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