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