OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/sha1.h" | 5 #include "base/sha1.h" |
6 | 6 |
| 7 #include <stddef.h> |
| 8 #include <stdint.h> |
7 #include <string.h> | 9 #include <string.h> |
8 | 10 |
9 #include "base/basictypes.h" | |
10 | 11 |
11 namespace base { | 12 namespace base { |
12 | 13 |
13 // Implementation of SHA-1. Only handles data in byte-sized blocks, | 14 // Implementation of SHA-1. Only handles data in byte-sized blocks, |
14 // which simplifies the code a fair bit. | 15 // which simplifies the code a fair bit. |
15 | 16 |
16 // Identifier names follow notation in FIPS PUB 180-3, where you'll | 17 // Identifier names follow notation in FIPS PUB 180-3, where you'll |
17 // also find a description of the algorithm: | 18 // also find a description of the algorithm: |
18 // http://csrc.nist.gov/publications/fips/fips180-3/fips180-3_final.pdf | 19 // http://csrc.nist.gov/publications/fips/fips180-3/fips180-3_final.pdf |
19 | 20 |
(...skipping 23 matching lines...) Expand all Loading... |
43 | 44 |
44 // 20 bytes of message digest. | 45 // 20 bytes of message digest. |
45 const unsigned char* Digest() const { | 46 const unsigned char* Digest() const { |
46 return reinterpret_cast<const unsigned char*>(H); | 47 return reinterpret_cast<const unsigned char*>(H); |
47 } | 48 } |
48 | 49 |
49 private: | 50 private: |
50 void Pad(); | 51 void Pad(); |
51 void Process(); | 52 void Process(); |
52 | 53 |
53 uint32 A, B, C, D, E; | 54 uint32_t A, B, C, D, E; |
54 | 55 |
55 uint32 H[5]; | 56 uint32_t H[5]; |
56 | 57 |
57 union { | 58 union { |
58 uint32 W[80]; | 59 uint32_t W[80]; |
59 uint8 M[64]; | 60 uint8_t M[64]; |
60 }; | 61 }; |
61 | 62 |
62 uint32 cursor; | 63 uint32_t cursor; |
63 uint64 l; | 64 uint64_t l; |
64 }; | 65 }; |
65 | 66 |
66 static inline uint32 f(uint32 t, uint32 B, uint32 C, uint32 D) { | 67 static inline uint32_t f(uint32_t t, uint32_t B, uint32_t C, uint32_t D) { |
67 if (t < 20) { | 68 if (t < 20) { |
68 return (B & C) | ((~B) & D); | 69 return (B & C) | ((~B) & D); |
69 } else if (t < 40) { | 70 } else if (t < 40) { |
70 return B ^ C ^ D; | 71 return B ^ C ^ D; |
71 } else if (t < 60) { | 72 } else if (t < 60) { |
72 return (B & C) | (B & D) | (C & D); | 73 return (B & C) | (B & D) | (C & D); |
73 } else { | 74 } else { |
74 return B ^ C ^ D; | 75 return B ^ C ^ D; |
75 } | 76 } |
76 } | 77 } |
77 | 78 |
78 static inline uint32 S(uint32 n, uint32 X) { | 79 static inline uint32_t S(uint32_t n, uint32_t X) { |
79 return (X << n) | (X >> (32-n)); | 80 return (X << n) | (X >> (32-n)); |
80 } | 81 } |
81 | 82 |
82 static inline uint32 K(uint32 t) { | 83 static inline uint32_t K(uint32_t t) { |
83 if (t < 20) { | 84 if (t < 20) { |
84 return 0x5a827999; | 85 return 0x5a827999; |
85 } else if (t < 40) { | 86 } else if (t < 40) { |
86 return 0x6ed9eba1; | 87 return 0x6ed9eba1; |
87 } else if (t < 60) { | 88 } else if (t < 60) { |
88 return 0x8f1bbcdc; | 89 return 0x8f1bbcdc; |
89 } else { | 90 } else { |
90 return 0xca62c1d6; | 91 return 0xca62c1d6; |
91 } | 92 } |
92 } | 93 } |
93 | 94 |
94 static inline void swapends(uint32* t) { | 95 static inline void swapends(uint32_t* t) { |
95 *t = (*t >> 24) | ((*t >> 8) & 0xff00) | ((*t & 0xff00) << 8) | (*t << 24); | 96 *t = (*t >> 24) | ((*t >> 8) & 0xff00) | ((*t & 0xff00) << 8) | (*t << 24); |
96 } | 97 } |
97 | 98 |
98 const int SecureHashAlgorithm::kDigestSizeBytes = 20; | 99 const int SecureHashAlgorithm::kDigestSizeBytes = 20; |
99 | 100 |
100 void SecureHashAlgorithm::Init() { | 101 void SecureHashAlgorithm::Init() { |
101 A = 0; | 102 A = 0; |
102 B = 0; | 103 B = 0; |
103 C = 0; | 104 C = 0; |
104 D = 0; | 105 D = 0; |
105 E = 0; | 106 E = 0; |
106 cursor = 0; | 107 cursor = 0; |
107 l = 0; | 108 l = 0; |
108 H[0] = 0x67452301; | 109 H[0] = 0x67452301; |
109 H[1] = 0xefcdab89; | 110 H[1] = 0xefcdab89; |
110 H[2] = 0x98badcfe; | 111 H[2] = 0x98badcfe; |
111 H[3] = 0x10325476; | 112 H[3] = 0x10325476; |
112 H[4] = 0xc3d2e1f0; | 113 H[4] = 0xc3d2e1f0; |
113 } | 114 } |
114 | 115 |
115 void SecureHashAlgorithm::Final() { | 116 void SecureHashAlgorithm::Final() { |
116 Pad(); | 117 Pad(); |
117 Process(); | 118 Process(); |
118 | 119 |
119 for (int t = 0; t < 5; ++t) | 120 for (int t = 0; t < 5; ++t) |
120 swapends(&H[t]); | 121 swapends(&H[t]); |
121 } | 122 } |
122 | 123 |
123 void SecureHashAlgorithm::Update(const void* data, size_t nbytes) { | 124 void SecureHashAlgorithm::Update(const void* data, size_t nbytes) { |
124 const uint8* d = reinterpret_cast<const uint8*>(data); | 125 const uint8_t* d = reinterpret_cast<const uint8_t*>(data); |
125 while (nbytes--) { | 126 while (nbytes--) { |
126 M[cursor++] = *d++; | 127 M[cursor++] = *d++; |
127 if (cursor >= 64) | 128 if (cursor >= 64) |
128 Process(); | 129 Process(); |
129 l += 8; | 130 l += 8; |
130 } | 131 } |
131 } | 132 } |
132 | 133 |
133 void SecureHashAlgorithm::Pad() { | 134 void SecureHashAlgorithm::Pad() { |
134 M[cursor++] = 0x80; | 135 M[cursor++] = 0x80; |
(...skipping 13 matching lines...) Expand all Loading... |
148 M[cursor++] = (l >> 48) & 0xff; | 149 M[cursor++] = (l >> 48) & 0xff; |
149 M[cursor++] = (l >> 40) & 0xff; | 150 M[cursor++] = (l >> 40) & 0xff; |
150 M[cursor++] = (l >> 32) & 0xff; | 151 M[cursor++] = (l >> 32) & 0xff; |
151 M[cursor++] = (l >> 24) & 0xff; | 152 M[cursor++] = (l >> 24) & 0xff; |
152 M[cursor++] = (l >> 16) & 0xff; | 153 M[cursor++] = (l >> 16) & 0xff; |
153 M[cursor++] = (l >> 8) & 0xff; | 154 M[cursor++] = (l >> 8) & 0xff; |
154 M[cursor++] = l & 0xff; | 155 M[cursor++] = l & 0xff; |
155 } | 156 } |
156 | 157 |
157 void SecureHashAlgorithm::Process() { | 158 void SecureHashAlgorithm::Process() { |
158 uint32 t; | 159 uint32_t t; |
159 | 160 |
160 // Each a...e corresponds to a section in the FIPS 180-3 algorithm. | 161 // Each a...e corresponds to a section in the FIPS 180-3 algorithm. |
161 | 162 |
162 // a. | 163 // a. |
163 // | 164 // |
164 // W and M are in a union, so no need to memcpy. | 165 // W and M are in a union, so no need to memcpy. |
165 // memcpy(W, M, sizeof(M)); | 166 // memcpy(W, M, sizeof(M)); |
166 for (t = 0; t < 16; ++t) | 167 for (t = 0; t < 16; ++t) |
167 swapends(&W[t]); | 168 swapends(&W[t]); |
168 | 169 |
169 // b. | 170 // b. |
170 for (t = 16; t < 80; ++t) | 171 for (t = 16; t < 80; ++t) |
171 W[t] = S(1, W[t - 3] ^ W[t - 8] ^ W[t - 14] ^ W[t - 16]); | 172 W[t] = S(1, W[t - 3] ^ W[t - 8] ^ W[t - 14] ^ W[t - 16]); |
172 | 173 |
173 // c. | 174 // c. |
174 A = H[0]; | 175 A = H[0]; |
175 B = H[1]; | 176 B = H[1]; |
176 C = H[2]; | 177 C = H[2]; |
177 D = H[3]; | 178 D = H[3]; |
178 E = H[4]; | 179 E = H[4]; |
179 | 180 |
180 // d. | 181 // d. |
181 for (t = 0; t < 80; ++t) { | 182 for (t = 0; t < 80; ++t) { |
182 uint32 TEMP = S(5, A) + f(t, B, C, D) + E + W[t] + K(t); | 183 uint32_t TEMP = S(5, A) + f(t, B, C, D) + E + W[t] + K(t); |
183 E = D; | 184 E = D; |
184 D = C; | 185 D = C; |
185 C = S(30, B); | 186 C = S(30, B); |
186 B = A; | 187 B = A; |
187 A = TEMP; | 188 A = TEMP; |
188 } | 189 } |
189 | 190 |
190 // e. | 191 // e. |
191 H[0] += A; | 192 H[0] += A; |
192 H[1] += B; | 193 H[1] += B; |
(...skipping 14 matching lines...) Expand all Loading... |
207 void SHA1HashBytes(const unsigned char* data, size_t len, | 208 void SHA1HashBytes(const unsigned char* data, size_t len, |
208 unsigned char* hash) { | 209 unsigned char* hash) { |
209 SecureHashAlgorithm sha; | 210 SecureHashAlgorithm sha; |
210 sha.Update(data, len); | 211 sha.Update(data, len); |
211 sha.Final(); | 212 sha.Final(); |
212 | 213 |
213 memcpy(hash, sha.Digest(), SecureHashAlgorithm::kDigestSizeBytes); | 214 memcpy(hash, sha.Digest(), SecureHashAlgorithm::kDigestSizeBytes); |
214 } | 215 } |
215 | 216 |
216 } // namespace base | 217 } // namespace base |
OLD | NEW |