xref: /aosp_15_r20/external/cronet/base/hash/sha1_nacl.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker // Copyright 2011 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker 
5*6777b538SAndroid Build Coastguard Worker #include <stddef.h>
6*6777b538SAndroid Build Coastguard Worker #include <stdint.h>
7*6777b538SAndroid Build Coastguard Worker #include <string.h>
8*6777b538SAndroid Build Coastguard Worker 
9*6777b538SAndroid Build Coastguard Worker #include <string_view>
10*6777b538SAndroid Build Coastguard Worker 
11*6777b538SAndroid Build Coastguard Worker #include "base/hash/sha1.h"
12*6777b538SAndroid Build Coastguard Worker #include "base/numerics/byte_conversions.h"
13*6777b538SAndroid Build Coastguard Worker 
14*6777b538SAndroid Build Coastguard Worker namespace base {
15*6777b538SAndroid Build Coastguard Worker // Implementation of SHA-1. Only handles data in byte-sized blocks,
16*6777b538SAndroid Build Coastguard Worker // which simplifies the code a fair bit.
17*6777b538SAndroid Build Coastguard Worker 
18*6777b538SAndroid Build Coastguard Worker // Identifier names follow notation in FIPS PUB 180-3, where you'll
19*6777b538SAndroid Build Coastguard Worker // also find a description of the algorithm:
20*6777b538SAndroid Build Coastguard Worker // http://csrc.nist.gov/publications/fips/fips180-3/fips180-3_final.pdf
21*6777b538SAndroid Build Coastguard Worker 
22*6777b538SAndroid Build Coastguard Worker // Usage example:
23*6777b538SAndroid Build Coastguard Worker //
24*6777b538SAndroid Build Coastguard Worker // SecureHashAlgorithm sha;
25*6777b538SAndroid Build Coastguard Worker // while(there is data to hash)
26*6777b538SAndroid Build Coastguard Worker //   sha.Update(moredata, size of data);
27*6777b538SAndroid Build Coastguard Worker // sha.Final();
28*6777b538SAndroid Build Coastguard Worker // memcpy(somewhere, sha.Digest(), 20);
29*6777b538SAndroid Build Coastguard Worker //
30*6777b538SAndroid Build Coastguard Worker // to reuse the instance of sha, call sha.Init();
31*6777b538SAndroid Build Coastguard Worker 
f(uint32_t t,uint32_t B,uint32_t C,uint32_t D)32*6777b538SAndroid Build Coastguard Worker static inline uint32_t f(uint32_t t, uint32_t B, uint32_t C, uint32_t D) {
33*6777b538SAndroid Build Coastguard Worker   if (t < 20)
34*6777b538SAndroid Build Coastguard Worker     return (B & C) | ((~B) & D);
35*6777b538SAndroid Build Coastguard Worker   if (t < 40)
36*6777b538SAndroid Build Coastguard Worker     return B ^ C ^ D;
37*6777b538SAndroid Build Coastguard Worker   if (t < 60)
38*6777b538SAndroid Build Coastguard Worker     return (B & C) | (B & D) | (C & D);
39*6777b538SAndroid Build Coastguard Worker   return B ^ C ^ D;
40*6777b538SAndroid Build Coastguard Worker }
41*6777b538SAndroid Build Coastguard Worker 
S(uint32_t n,uint32_t X)42*6777b538SAndroid Build Coastguard Worker static inline uint32_t S(uint32_t n, uint32_t X) {
43*6777b538SAndroid Build Coastguard Worker   return (X << n) | (X >> (32 - n));
44*6777b538SAndroid Build Coastguard Worker }
45*6777b538SAndroid Build Coastguard Worker 
K(uint32_t t)46*6777b538SAndroid Build Coastguard Worker static inline uint32_t K(uint32_t t) {
47*6777b538SAndroid Build Coastguard Worker   if (t < 20)
48*6777b538SAndroid Build Coastguard Worker     return 0x5a827999;
49*6777b538SAndroid Build Coastguard Worker   if (t < 40)
50*6777b538SAndroid Build Coastguard Worker     return 0x6ed9eba1;
51*6777b538SAndroid Build Coastguard Worker   if (t < 60)
52*6777b538SAndroid Build Coastguard Worker     return 0x8f1bbcdc;
53*6777b538SAndroid Build Coastguard Worker   return 0xca62c1d6;
54*6777b538SAndroid Build Coastguard Worker }
55*6777b538SAndroid Build Coastguard Worker 
Init()56*6777b538SAndroid Build Coastguard Worker void SHA1Context::Init() {
57*6777b538SAndroid Build Coastguard Worker   A = 0;
58*6777b538SAndroid Build Coastguard Worker   B = 0;
59*6777b538SAndroid Build Coastguard Worker   C = 0;
60*6777b538SAndroid Build Coastguard Worker   D = 0;
61*6777b538SAndroid Build Coastguard Worker   E = 0;
62*6777b538SAndroid Build Coastguard Worker   cursor = 0;
63*6777b538SAndroid Build Coastguard Worker   l = 0;
64*6777b538SAndroid Build Coastguard Worker   H[0] = 0x67452301;
65*6777b538SAndroid Build Coastguard Worker   H[1] = 0xefcdab89;
66*6777b538SAndroid Build Coastguard Worker   H[2] = 0x98badcfe;
67*6777b538SAndroid Build Coastguard Worker   H[3] = 0x10325476;
68*6777b538SAndroid Build Coastguard Worker   H[4] = 0xc3d2e1f0;
69*6777b538SAndroid Build Coastguard Worker }
70*6777b538SAndroid Build Coastguard Worker 
Update(const void * data,size_t nbytes)71*6777b538SAndroid Build Coastguard Worker void SHA1Context::Update(const void* data, size_t nbytes) {
72*6777b538SAndroid Build Coastguard Worker   const uint8_t* d = reinterpret_cast<const uint8_t*>(data);
73*6777b538SAndroid Build Coastguard Worker   while (nbytes--) {
74*6777b538SAndroid Build Coastguard Worker     M[cursor++] = *d++;
75*6777b538SAndroid Build Coastguard Worker     if (cursor >= 64) {
76*6777b538SAndroid Build Coastguard Worker       Process();
77*6777b538SAndroid Build Coastguard Worker     }
78*6777b538SAndroid Build Coastguard Worker     l += 8;
79*6777b538SAndroid Build Coastguard Worker   }
80*6777b538SAndroid Build Coastguard Worker }
81*6777b538SAndroid Build Coastguard Worker 
Final()82*6777b538SAndroid Build Coastguard Worker void SHA1Context::Final() {
83*6777b538SAndroid Build Coastguard Worker   Pad();
84*6777b538SAndroid Build Coastguard Worker   Process();
85*6777b538SAndroid Build Coastguard Worker 
86*6777b538SAndroid Build Coastguard Worker   for (auto& t : H) {
87*6777b538SAndroid Build Coastguard Worker     t = ByteSwap(t);
88*6777b538SAndroid Build Coastguard Worker   }
89*6777b538SAndroid Build Coastguard Worker }
90*6777b538SAndroid Build Coastguard Worker 
GetDigest() const91*6777b538SAndroid Build Coastguard Worker const unsigned char* SHA1Context::GetDigest() const {
92*6777b538SAndroid Build Coastguard Worker   return reinterpret_cast<const unsigned char*>(H);
93*6777b538SAndroid Build Coastguard Worker }
94*6777b538SAndroid Build Coastguard Worker 
Pad()95*6777b538SAndroid Build Coastguard Worker void SHA1Context::Pad() {
96*6777b538SAndroid Build Coastguard Worker   M[cursor++] = 0x80;
97*6777b538SAndroid Build Coastguard Worker 
98*6777b538SAndroid Build Coastguard Worker   if (cursor > 64 - 8) {
99*6777b538SAndroid Build Coastguard Worker     // pad out to next block
100*6777b538SAndroid Build Coastguard Worker     while (cursor < 64) {
101*6777b538SAndroid Build Coastguard Worker       M[cursor++] = 0;
102*6777b538SAndroid Build Coastguard Worker     }
103*6777b538SAndroid Build Coastguard Worker 
104*6777b538SAndroid Build Coastguard Worker     Process();
105*6777b538SAndroid Build Coastguard Worker   }
106*6777b538SAndroid Build Coastguard Worker 
107*6777b538SAndroid Build Coastguard Worker   while (cursor < 64 - 8) {
108*6777b538SAndroid Build Coastguard Worker     M[cursor++] = 0;
109*6777b538SAndroid Build Coastguard Worker   }
110*6777b538SAndroid Build Coastguard Worker 
111*6777b538SAndroid Build Coastguard Worker   M[cursor++] = (l >> 56) & 0xff;
112*6777b538SAndroid Build Coastguard Worker   M[cursor++] = (l >> 48) & 0xff;
113*6777b538SAndroid Build Coastguard Worker   M[cursor++] = (l >> 40) & 0xff;
114*6777b538SAndroid Build Coastguard Worker   M[cursor++] = (l >> 32) & 0xff;
115*6777b538SAndroid Build Coastguard Worker   M[cursor++] = (l >> 24) & 0xff;
116*6777b538SAndroid Build Coastguard Worker   M[cursor++] = (l >> 16) & 0xff;
117*6777b538SAndroid Build Coastguard Worker   M[cursor++] = (l >> 8) & 0xff;
118*6777b538SAndroid Build Coastguard Worker   M[cursor++] = l & 0xff;
119*6777b538SAndroid Build Coastguard Worker }
120*6777b538SAndroid Build Coastguard Worker 
Process()121*6777b538SAndroid Build Coastguard Worker void SHA1Context::Process() {
122*6777b538SAndroid Build Coastguard Worker   uint32_t t;
123*6777b538SAndroid Build Coastguard Worker 
124*6777b538SAndroid Build Coastguard Worker   // Each a...e corresponds to a section in the FIPS 180-3 algorithm.
125*6777b538SAndroid Build Coastguard Worker 
126*6777b538SAndroid Build Coastguard Worker   // a.
127*6777b538SAndroid Build Coastguard Worker   //
128*6777b538SAndroid Build Coastguard Worker   // W and M are in a union, so no need to memcpy.
129*6777b538SAndroid Build Coastguard Worker   // memcpy(W, M, sizeof(M));
130*6777b538SAndroid Build Coastguard Worker   for (t = 0; t < 16; ++t) {
131*6777b538SAndroid Build Coastguard Worker     W[t] = ByteSwap(W[t]);
132*6777b538SAndroid Build Coastguard Worker   }
133*6777b538SAndroid Build Coastguard Worker 
134*6777b538SAndroid Build Coastguard Worker   // b.
135*6777b538SAndroid Build Coastguard Worker   for (t = 16; t < 80; ++t) {
136*6777b538SAndroid Build Coastguard Worker     W[t] = S(1, W[t - 3] ^ W[t - 8] ^ W[t - 14] ^ W[t - 16]);
137*6777b538SAndroid Build Coastguard Worker   }
138*6777b538SAndroid Build Coastguard Worker 
139*6777b538SAndroid Build Coastguard Worker   // c.
140*6777b538SAndroid Build Coastguard Worker   A = H[0];
141*6777b538SAndroid Build Coastguard Worker   B = H[1];
142*6777b538SAndroid Build Coastguard Worker   C = H[2];
143*6777b538SAndroid Build Coastguard Worker   D = H[3];
144*6777b538SAndroid Build Coastguard Worker   E = H[4];
145*6777b538SAndroid Build Coastguard Worker 
146*6777b538SAndroid Build Coastguard Worker   // d.
147*6777b538SAndroid Build Coastguard Worker   for (t = 0; t < 80; ++t) {
148*6777b538SAndroid Build Coastguard Worker     uint32_t TEMP = S(5, A) + f(t, B, C, D) + E + W[t] + K(t);
149*6777b538SAndroid Build Coastguard Worker     E = D;
150*6777b538SAndroid Build Coastguard Worker     D = C;
151*6777b538SAndroid Build Coastguard Worker     C = S(30, B);
152*6777b538SAndroid Build Coastguard Worker     B = A;
153*6777b538SAndroid Build Coastguard Worker     A = TEMP;
154*6777b538SAndroid Build Coastguard Worker   }
155*6777b538SAndroid Build Coastguard Worker 
156*6777b538SAndroid Build Coastguard Worker   // e.
157*6777b538SAndroid Build Coastguard Worker   H[0] += A;
158*6777b538SAndroid Build Coastguard Worker   H[1] += B;
159*6777b538SAndroid Build Coastguard Worker   H[2] += C;
160*6777b538SAndroid Build Coastguard Worker   H[3] += D;
161*6777b538SAndroid Build Coastguard Worker   H[4] += E;
162*6777b538SAndroid Build Coastguard Worker 
163*6777b538SAndroid Build Coastguard Worker   cursor = 0;
164*6777b538SAndroid Build Coastguard Worker }
165*6777b538SAndroid Build Coastguard Worker 
166*6777b538SAndroid Build Coastguard Worker // These functions allow streaming SHA-1 operations.
SHA1Init(SHA1Context & context)167*6777b538SAndroid Build Coastguard Worker void SHA1Init(SHA1Context& context) {
168*6777b538SAndroid Build Coastguard Worker   context.Init();
169*6777b538SAndroid Build Coastguard Worker }
170*6777b538SAndroid Build Coastguard Worker 
SHA1Update(const std::string_view data,SHA1Context & context)171*6777b538SAndroid Build Coastguard Worker void SHA1Update(const std::string_view data, SHA1Context& context) {
172*6777b538SAndroid Build Coastguard Worker   context.Update(data.data(), data.size());
173*6777b538SAndroid Build Coastguard Worker }
174*6777b538SAndroid Build Coastguard Worker 
SHA1Final(SHA1Context & context,SHA1Digest & digest)175*6777b538SAndroid Build Coastguard Worker void SHA1Final(SHA1Context& context, SHA1Digest& digest) {
176*6777b538SAndroid Build Coastguard Worker   context.Final();
177*6777b538SAndroid Build Coastguard Worker   memcpy(digest.data(), context.GetDigest(), kSHA1Length);
178*6777b538SAndroid Build Coastguard Worker }
179*6777b538SAndroid Build Coastguard Worker 
SHA1HashSpan(span<const uint8_t> data)180*6777b538SAndroid Build Coastguard Worker SHA1Digest SHA1HashSpan(span<const uint8_t> data) {
181*6777b538SAndroid Build Coastguard Worker   SHA1Digest hash;
182*6777b538SAndroid Build Coastguard Worker   SHA1HashBytes(data.data(), data.size(), hash.data());
183*6777b538SAndroid Build Coastguard Worker   return hash;
184*6777b538SAndroid Build Coastguard Worker }
185*6777b538SAndroid Build Coastguard Worker 
SHA1HashString(std::string_view str)186*6777b538SAndroid Build Coastguard Worker std::string SHA1HashString(std::string_view str) {
187*6777b538SAndroid Build Coastguard Worker   char hash[kSHA1Length];
188*6777b538SAndroid Build Coastguard Worker   SHA1HashBytes(reinterpret_cast<const unsigned char*>(str.data()),
189*6777b538SAndroid Build Coastguard Worker                 str.length(), reinterpret_cast<unsigned char*>(hash));
190*6777b538SAndroid Build Coastguard Worker   return std::string(hash, kSHA1Length);
191*6777b538SAndroid Build Coastguard Worker }
192*6777b538SAndroid Build Coastguard Worker 
SHA1HashBytes(const unsigned char * data,size_t len,unsigned char * hash)193*6777b538SAndroid Build Coastguard Worker void SHA1HashBytes(const unsigned char* data, size_t len, unsigned char* hash) {
194*6777b538SAndroid Build Coastguard Worker   SHA1Context context;
195*6777b538SAndroid Build Coastguard Worker   context.Init();
196*6777b538SAndroid Build Coastguard Worker   context.Update(data, len);
197*6777b538SAndroid Build Coastguard Worker   context.Final();
198*6777b538SAndroid Build Coastguard Worker 
199*6777b538SAndroid Build Coastguard Worker   memcpy(hash, context.GetDigest(), kSHA1Length);
200*6777b538SAndroid Build Coastguard Worker }
201*6777b538SAndroid Build Coastguard Worker 
202*6777b538SAndroid Build Coastguard Worker }  // namespace base
203