OLD | NEW |
1 /* | 1 /* |
2 * SHA-1 in C | 2 * SHA-1 in C |
3 * By Steve Reid <sreid@sea-to-sky.net> | 3 * By Steve Reid <sreid@sea-to-sky.net> |
4 * 100% Public Domain | 4 * 100% Public Domain |
5 * | 5 * |
6 * ----------------- | 6 * ----------------- |
7 * Modified 7/98 | 7 * Modified 7/98 |
8 * By James H. Brown <jbrown@burgoyne.com> | 8 * By James H. Brown <jbrown@burgoyne.com> |
9 * Still 100% Public Domain | 9 * Still 100% Public Domain |
10 * | 10 * |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
89 * A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D | 89 * A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D |
90 * "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" | 90 * "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" |
91 * 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1 | 91 * 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1 |
92 * A million repetitions of "a" | 92 * A million repetitions of "a" |
93 * 34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F | 93 * 34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F |
94 * | 94 * |
95 * ----------------- | 95 * ----------------- |
96 * Modified 05/2015 | 96 * Modified 05/2015 |
97 * By Sergey Ulanov <sergeyu@chromium.org> | 97 * By Sergey Ulanov <sergeyu@chromium.org> |
98 * Removed static buffer to make computation thread-safe. | 98 * Removed static buffer to make computation thread-safe. |
| 99 * |
| 100 * ----------------- |
| 101 * Modified 10/2015 |
| 102 * By Peter Boström <pbos@webrtc.org> |
| 103 * Change uint32(8) back to uint32(8)_t (undoes (03/2012) change). |
99 */ | 104 */ |
100 | 105 |
101 // Enabling SHA1HANDSOFF preserves the caller's data buffer. | 106 // Enabling SHA1HANDSOFF preserves the caller's data buffer. |
102 // Disabling SHA1HANDSOFF the buffer will be modified (end swapped). | 107 // Disabling SHA1HANDSOFF the buffer will be modified (end swapped). |
103 #define SHA1HANDSOFF | 108 #define SHA1HANDSOFF |
104 | 109 |
105 #include "webrtc/base/sha1.h" | 110 #include "webrtc/base/sha1.h" |
106 | 111 |
107 #include <stdio.h> | 112 #include <stdio.h> |
108 #include <string.h> | 113 #include <string.h> |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
149 context->count[0], context->count[1], | 154 context->count[0], context->count[1], |
150 context->state[0], | 155 context->state[0], |
151 context->state[1], | 156 context->state[1], |
152 context->state[2], | 157 context->state[2], |
153 context->state[3], | 158 context->state[3], |
154 context->state[4]); | 159 context->state[4]); |
155 } | 160 } |
156 #endif /* VERBOSE */ | 161 #endif /* VERBOSE */ |
157 | 162 |
158 // Hash a single 512-bit block. This is the core of the algorithm. | 163 // Hash a single 512-bit block. This is the core of the algorithm. |
159 void SHA1Transform(uint32 state[5], const uint8 buffer[64]) { | 164 void SHA1Transform(uint32_t state[5], const uint8_t buffer[64]) { |
160 union CHAR64LONG16 { | 165 union CHAR64LONG16 { |
161 uint8 c[64]; | 166 uint8_t c[64]; |
162 uint32 l[16]; | 167 uint32_t l[16]; |
163 }; | 168 }; |
164 #ifdef SHA1HANDSOFF | 169 #ifdef SHA1HANDSOFF |
165 uint8 workspace[64]; | 170 uint8_t workspace[64]; |
166 memcpy(workspace, buffer, 64); | 171 memcpy(workspace, buffer, 64); |
167 CHAR64LONG16* block = reinterpret_cast<CHAR64LONG16*>(workspace); | 172 CHAR64LONG16* block = reinterpret_cast<CHAR64LONG16*>(workspace); |
168 #else | 173 #else |
169 // Note(fbarchard): This option does modify the user's data buffer. | 174 // Note(fbarchard): This option does modify the user's data buffer. |
170 CHAR64LONG16* block = const_cast<CHAR64LONG16*>( | 175 CHAR64LONG16* block = const_cast<CHAR64LONG16*>( |
171 reinterpret_cast<const CHAR64LONG16*>(buffer)); | 176 reinterpret_cast<const CHAR64LONG16*>(buffer)); |
172 #endif | 177 #endif |
173 | 178 |
174 // Copy context->state[] to working vars. | 179 // Copy context->state[] to working vars. |
175 uint32 a = state[0]; | 180 uint32_t a = state[0]; |
176 uint32 b = state[1]; | 181 uint32_t b = state[1]; |
177 uint32 c = state[2]; | 182 uint32_t c = state[2]; |
178 uint32 d = state[3]; | 183 uint32_t d = state[3]; |
179 uint32 e = state[4]; | 184 uint32_t e = state[4]; |
180 | 185 |
181 // 4 rounds of 20 operations each. Loop unrolled. | 186 // 4 rounds of 20 operations each. Loop unrolled. |
182 // Note(fbarchard): The following has lint warnings for multiple ; on | 187 // Note(fbarchard): The following has lint warnings for multiple ; on |
183 // a line and no space after , but is left as-is to be similar to the | 188 // a line and no space after , but is left as-is to be similar to the |
184 // original code. | 189 // original code. |
185 R0(a,b,c,d,e,0); R0(e,a,b,c,d,1); R0(d,e,a,b,c,2); R0(c,d,e,a,b,3); | 190 R0(a,b,c,d,e,0); R0(e,a,b,c,d,1); R0(d,e,a,b,c,2); R0(c,d,e,a,b,3); |
186 R0(b,c,d,e,a,4); R0(a,b,c,d,e,5); R0(e,a,b,c,d,6); R0(d,e,a,b,c,7); | 191 R0(b,c,d,e,a,4); R0(a,b,c,d,e,5); R0(e,a,b,c,d,6); R0(d,e,a,b,c,7); |
187 R0(c,d,e,a,b,8); R0(b,c,d,e,a,9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11); | 192 R0(c,d,e,a,b,8); R0(b,c,d,e,a,9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11); |
188 R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15); | 193 R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15); |
189 R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19); | 194 R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19); |
(...skipping 28 matching lines...) Expand all Loading... |
218 // SHA1 initialization constants. | 223 // SHA1 initialization constants. |
219 context->state[0] = 0x67452301; | 224 context->state[0] = 0x67452301; |
220 context->state[1] = 0xEFCDAB89; | 225 context->state[1] = 0xEFCDAB89; |
221 context->state[2] = 0x98BADCFE; | 226 context->state[2] = 0x98BADCFE; |
222 context->state[3] = 0x10325476; | 227 context->state[3] = 0x10325476; |
223 context->state[4] = 0xC3D2E1F0; | 228 context->state[4] = 0xC3D2E1F0; |
224 context->count[0] = context->count[1] = 0; | 229 context->count[0] = context->count[1] = 0; |
225 } | 230 } |
226 | 231 |
227 // Run your data through this. | 232 // Run your data through this. |
228 void SHA1Update(SHA1_CTX* context, const uint8* data, size_t input_len) { | 233 void SHA1Update(SHA1_CTX* context, const uint8_t* data, size_t input_len) { |
229 size_t i = 0; | 234 size_t i = 0; |
230 | 235 |
231 #ifdef VERBOSE | 236 #ifdef VERBOSE |
232 SHAPrintContext(context, "before"); | 237 SHAPrintContext(context, "before"); |
233 #endif | 238 #endif |
234 | 239 |
235 // Compute number of bytes mod 64. | 240 // Compute number of bytes mod 64. |
236 size_t index = (context->count[0] >> 3) & 63; | 241 size_t index = (context->count[0] >> 3) & 63; |
237 | 242 |
238 // Update number of bits. | 243 // Update number of bits. |
239 // TODO: Use uint64 instead of 2 uint32 for count. | 244 // TODO: Use uint64_t instead of 2 uint32_t for count. |
240 // count[0] has low 29 bits for byte count + 3 pad 0's making 32 bits for | 245 // count[0] has low 29 bits for byte count + 3 pad 0's making 32 bits for |
241 // bit count. | 246 // bit count. |
242 // Add bit count to low uint32 | 247 // Add bit count to low uint32_t |
243 context->count[0] += static_cast<uint32>(input_len << 3); | 248 context->count[0] += static_cast<uint32_t>(input_len << 3); |
244 if (context->count[0] < static_cast<uint32>(input_len << 3)) { | 249 if (context->count[0] < static_cast<uint32_t>(input_len << 3)) { |
245 ++context->count[1]; // if overlow (carry), add one to high word | 250 ++context->count[1]; // if overlow (carry), add one to high word |
246 } | 251 } |
247 context->count[1] += static_cast<uint32>(input_len >> 29); | 252 context->count[1] += static_cast<uint32_t>(input_len >> 29); |
248 if ((index + input_len) > 63) { | 253 if ((index + input_len) > 63) { |
249 i = 64 - index; | 254 i = 64 - index; |
250 memcpy(&context->buffer[index], data, i); | 255 memcpy(&context->buffer[index], data, i); |
251 SHA1Transform(context->state, context->buffer); | 256 SHA1Transform(context->state, context->buffer); |
252 for (; i + 63 < input_len; i += 64) { | 257 for (; i + 63 < input_len; i += 64) { |
253 SHA1Transform(context->state, data + i); | 258 SHA1Transform(context->state, data + i); |
254 } | 259 } |
255 index = 0; | 260 index = 0; |
256 } | 261 } |
257 memcpy(&context->buffer[index], &data[i], input_len - i); | 262 memcpy(&context->buffer[index], &data[i], input_len - i); |
258 | 263 |
259 #ifdef VERBOSE | 264 #ifdef VERBOSE |
260 SHAPrintContext(context, "after "); | 265 SHAPrintContext(context, "after "); |
261 #endif | 266 #endif |
262 } | 267 } |
263 | 268 |
264 // Add padding and return the message digest. | 269 // Add padding and return the message digest. |
265 void SHA1Final(SHA1_CTX* context, uint8 digest[SHA1_DIGEST_SIZE]) { | 270 void SHA1Final(SHA1_CTX* context, uint8_t digest[SHA1_DIGEST_SIZE]) { |
266 uint8 finalcount[8]; | 271 uint8_t finalcount[8]; |
267 for (int i = 0; i < 8; ++i) { | 272 for (int i = 0; i < 8; ++i) { |
268 // Endian independent | 273 // Endian independent |
269 finalcount[i] = static_cast<uint8>( | 274 finalcount[i] = static_cast<uint8_t>( |
270 (context->count[(i >= 4 ? 0 : 1)] >> ((3 - (i & 3)) * 8) ) & 255); | 275 (context->count[(i >= 4 ? 0 : 1)] >> ((3 - (i & 3)) * 8)) & 255); |
271 } | 276 } |
272 SHA1Update(context, reinterpret_cast<const uint8*>("\200"), 1); | 277 SHA1Update(context, reinterpret_cast<const uint8_t*>("\200"), 1); |
273 while ((context->count[0] & 504) != 448) { | 278 while ((context->count[0] & 504) != 448) { |
274 SHA1Update(context, reinterpret_cast<const uint8*>("\0"), 1); | 279 SHA1Update(context, reinterpret_cast<const uint8_t*>("\0"), 1); |
275 } | 280 } |
276 SHA1Update(context, finalcount, 8); // Should cause a SHA1Transform(). | 281 SHA1Update(context, finalcount, 8); // Should cause a SHA1Transform(). |
277 for (int i = 0; i < SHA1_DIGEST_SIZE; ++i) { | 282 for (int i = 0; i < SHA1_DIGEST_SIZE; ++i) { |
278 digest[i] = static_cast<uint8>( | 283 digest[i] = static_cast<uint8_t>( |
279 (context->state[i >> 2] >> ((3 - (i & 3)) * 8) ) & 255); | 284 (context->state[i >> 2] >> ((3 - (i & 3)) * 8)) & 255); |
280 } | 285 } |
281 | 286 |
282 // Wipe variables. | 287 // Wipe variables. |
283 memset(context->buffer, 0, 64); | 288 memset(context->buffer, 0, 64); |
284 memset(context->state, 0, 20); | 289 memset(context->state, 0, 20); |
285 memset(context->count, 0, 8); | 290 memset(context->count, 0, 8); |
286 memset(finalcount, 0, 8); // SWR | 291 memset(finalcount, 0, 8); // SWR |
287 | 292 |
288 #ifdef SHA1HANDSOFF // Make SHA1Transform overwrite its own static vars. | 293 #ifdef SHA1HANDSOFF // Make SHA1Transform overwrite its own static vars. |
289 SHA1Transform(context->state, context->buffer); | 294 SHA1Transform(context->state, context->buffer); |
290 #endif | 295 #endif |
291 } | 296 } |
292 | 297 |
293 } // namespace rtc | 298 } // namespace rtc |
OLD | NEW |