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