Fix emulator build error
[platform/framework/web/chromium-efl.git] / components / browsing_topics / util.cc
1 // Copyright 2022 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "components/browsing_topics/util.h"
6
7 #include "base/rand_util.h"
8 #include "base/ranges/algorithm.h"
9 #include "crypto/hmac.h"
10 #include "crypto/sha2.h"
11 #include "third_party/blink/public/common/features.h"
12
13 namespace browsing_topics {
14
15 namespace {
16
17 // Note that updating the use case prefixes below will change the pre-existing
18 // per-user stickiness. Some of the derived data may already have been persisted
19 // elsewhere. Be sure you are aware of the implications before updating those
20 // strings. Note also that the version here is just about the hash method, and
21 // is distinctive from the broader configuration version of the Topics API.
22 const char kRandomOrTopTopicDecisionPrefix[] =
23     "TopicsV1_RandomOrTopTopicDecision|";
24 const char kRandomTopicIndexDecisionPrefix[] =
25     "TopicsV1_RandomTopicIndexDecision|";
26 const char kTopTopicIndexDecisionPrefix[] = "TopicsV1_TopTopicIndexDecision|";
27 const char kEpochSwitchTimeDecisionPrefix[] =
28     "TopicsV1_EpochSwitchTimeDecision|";
29 const char kContextDomainStoragePrefix[] = "TopicsV1_ContextDomainStorage|";
30 const char kMainFrameHostStoragePrefix[] = "TopicsV1_MainFrameHostStorage|";
31
32 uint64_t HmacHash(ReadOnlyHmacKey hmac_key,
33                   const std::string& use_case_prefix,
34                   const std::string& data) {
35   crypto::HMAC hmac(crypto::HMAC::SHA256);
36   CHECK(hmac.Init(hmac_key));
37
38   uint64_t result;
39   CHECK(hmac.Sign(use_case_prefix + data,
40                   reinterpret_cast<unsigned char*>(&result), sizeof(result)));
41
42   return result;
43 }
44
45 bool g_hmac_key_overridden = false;
46   
47 browsing_topics::HmacKey& GetHmacKeyOverrideForTesting() {
48   static browsing_topics::HmacKey key;
49   return key;
50 }
51
52 }  // namespace
53
54 HmacKey GenerateRandomHmacKey() {
55   if (g_hmac_key_overridden)
56     return GetHmacKeyOverrideForTesting();
57
58   HmacKey result = {};
59   base::RandBytes(result.data(), result.size());
60
61   return result;
62 }
63
64 uint64_t HashTopDomainForRandomOrTopTopicDecision(
65     ReadOnlyHmacKey hmac_key,
66     base::Time epoch_calculation_time,
67     const std::string& top_domain) {
68   int64_t time_microseconds =
69       epoch_calculation_time.ToDeltaSinceWindowsEpoch().InMicroseconds();
70
71   std::string epoch_id(reinterpret_cast<const char*>(&time_microseconds),
72                        sizeof(time_microseconds));
73
74   return HmacHash(hmac_key, kRandomOrTopTopicDecisionPrefix,
75                   epoch_id + top_domain);
76 }
77
78 uint64_t HashTopDomainForRandomTopicIndexDecision(
79     ReadOnlyHmacKey hmac_key,
80     base::Time epoch_calculation_time,
81     const std::string& top_domain) {
82   int64_t time_microseconds =
83       epoch_calculation_time.ToDeltaSinceWindowsEpoch().InMicroseconds();
84
85   std::string epoch_id(reinterpret_cast<const char*>(&time_microseconds),
86                        sizeof(time_microseconds));
87
88   return HmacHash(hmac_key, kRandomTopicIndexDecisionPrefix,
89                   epoch_id + top_domain);
90 }
91
92 uint64_t HashTopDomainForTopTopicIndexDecision(
93     ReadOnlyHmacKey hmac_key,
94     base::Time epoch_calculation_time,
95     const std::string& top_domain) {
96   int64_t time_microseconds =
97       epoch_calculation_time.ToDeltaSinceWindowsEpoch().InMicroseconds();
98
99   std::string epoch_id(reinterpret_cast<const char*>(&time_microseconds),
100                        sizeof(time_microseconds));
101
102   return HmacHash(hmac_key, kTopTopicIndexDecisionPrefix,
103                   epoch_id + top_domain);
104 }
105
106 uint64_t HashTopDomainForEpochSwitchTimeDecision(
107     ReadOnlyHmacKey hmac_key,
108     const std::string& top_domain) {
109   return HmacHash(hmac_key, kEpochSwitchTimeDecisionPrefix, top_domain);
110 }
111
112 HashedDomain HashContextDomainForStorage(ReadOnlyHmacKey hmac_key,
113                                          const std::string& context_domain) {
114   return HashedDomain(
115       HmacHash(hmac_key, kContextDomainStoragePrefix, context_domain));
116 }
117
118 HashedHost HashMainFrameHostForStorage(const std::string& main_frame_host) {
119   int64_t result;
120   crypto::SHA256HashString(kMainFrameHostStoragePrefix + main_frame_host,
121                            &result, sizeof(result));
122   return HashedHost(result);
123 }
124
125 void OverrideHmacKeyForTesting(ReadOnlyHmacKey hmac_key) {
126   g_hmac_key_overridden = true;
127   base::ranges::copy(hmac_key, GetHmacKeyOverrideForTesting().begin());
128 }
129
130 }  // namespace browsing_topics