Chromium Code Reviews| 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 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 68 * ----------------- | 68 * ----------------- |
| 69 * Modified 02/2012 | 69 * Modified 02/2012 |
| 70 * By Justin Uberti <juberti@google.com> | 70 * By Justin Uberti <juberti@google.com> |
| 71 * Remove underscore from SHA1 prefix to avoid conflict with OpenSSL | 71 * Remove underscore from SHA1 prefix to avoid conflict with OpenSSL |
| 72 * Remove test code | 72 * Remove test code |
| 73 * Untabify | 73 * Untabify |
| 74 * | 74 * |
| 75 * ----------------- | 75 * ----------------- |
| 76 * Modified 03/2012 | 76 * Modified 03/2012 |
| 77 * By Ronghua Wu <ronghuawu@google.com> | 77 * By Ronghua Wu <ronghuawu@google.com> |
| 78 * Change the typedef of uint32(8)_t to uint32(8). We need this because in the | 78 * Change the typedef of uint32_t(8)_t to uint32_t(8). We need this because in |
|
Henrik Grunell WebRTC
2015/10/05 12:00:19
Don't change the change log. :)
pbos-webrtc
2015/10/05 12:23:23
Oops, thanks!
| |
| 79 *the | |
| 79 * chromium android build, the stdio.h will include stdint.h which already | 80 * chromium android build, the stdio.h will include stdint.h which already |
| 80 * defined uint32(8)_t. | 81 * defined uint32_t(8)_t. |
| 81 * | 82 * |
| 82 * ----------------- | 83 * ----------------- |
| 83 * Modified 04/2012 | 84 * Modified 04/2012 |
| 84 * By Frank Barchard <fbarchard@google.com> | 85 * By Frank Barchard <fbarchard@google.com> |
| 85 * Ported to C++, Google style, change len to size_t, enable SHA1HANDSOFF | 86 * Ported to C++, Google style, change len to size_t, enable SHA1HANDSOFF |
| 86 * | 87 * |
| 87 * Test Vectors (from FIPS PUB 180-1) | 88 * Test Vectors (from FIPS PUB 180-1) |
| 88 * "abc" | 89 * "abc" |
| 89 * A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D | 90 * A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D |
| 90 * "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" | 91 * "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" |
| 91 * 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1 | 92 * 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1 |
| 92 * A million repetitions of "a" | 93 * A million repetitions of "a" |
| 93 * 34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F | 94 * 34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F |
| 94 * | 95 * |
| 95 * ----------------- | 96 * ----------------- |
| 96 * Modified 05/2015 | 97 * Modified 05/2015 |
| 97 * By Sergey Ulanov <sergeyu@chromium.org> | 98 * By Sergey Ulanov <sergeyu@chromium.org> |
| 98 * Removed static buffer to make computation thread-safe. | 99 * Removed static buffer to make computation thread-safe. |
| 99 */ | 100 */ |
|
Henrik Grunell WebRTC
2015/10/05 12:00:20
Add an entry here with your modification.
pbos-webrtc
2015/10/05 12:23:23
Done.
| |
| 100 | 101 |
| 101 // Enabling SHA1HANDSOFF preserves the caller's data buffer. | 102 // Enabling SHA1HANDSOFF preserves the caller's data buffer. |
| 102 // Disabling SHA1HANDSOFF the buffer will be modified (end swapped). | 103 // Disabling SHA1HANDSOFF the buffer will be modified (end swapped). |
| 103 #define SHA1HANDSOFF | 104 #define SHA1HANDSOFF |
| 104 | 105 |
| 105 #include "webrtc/base/sha1.h" | 106 #include "webrtc/base/sha1.h" |
| 106 | 107 |
| 107 #include <stdio.h> | 108 #include <stdio.h> |
| 108 #include <string.h> | 109 #include <string.h> |
| 109 | 110 |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 149 context->count[0], context->count[1], | 150 context->count[0], context->count[1], |
| 150 context->state[0], | 151 context->state[0], |
| 151 context->state[1], | 152 context->state[1], |
| 152 context->state[2], | 153 context->state[2], |
| 153 context->state[3], | 154 context->state[3], |
| 154 context->state[4]); | 155 context->state[4]); |
| 155 } | 156 } |
| 156 #endif /* VERBOSE */ | 157 #endif /* VERBOSE */ |
| 157 | 158 |
| 158 // Hash a single 512-bit block. This is the core of the algorithm. | 159 // Hash a single 512-bit block. This is the core of the algorithm. |
| 159 void SHA1Transform(uint32 state[5], const uint8 buffer[64]) { | 160 void SHA1Transform(uint32_t state[5], const uint8_t buffer[64]) { |
| 160 union CHAR64LONG16 { | 161 union CHAR64LONG16 { |
| 161 uint8 c[64]; | 162 uint8_t c[64]; |
| 162 uint32 l[16]; | 163 uint32_t l[16]; |
| 163 }; | 164 }; |
| 164 #ifdef SHA1HANDSOFF | 165 #ifdef SHA1HANDSOFF |
| 165 uint8 workspace[64]; | 166 uint8_t workspace[64]; |
| 166 memcpy(workspace, buffer, 64); | 167 memcpy(workspace, buffer, 64); |
| 167 CHAR64LONG16* block = reinterpret_cast<CHAR64LONG16*>(workspace); | 168 CHAR64LONG16* block = reinterpret_cast<CHAR64LONG16*>(workspace); |
| 168 #else | 169 #else |
| 169 // Note(fbarchard): This option does modify the user's data buffer. | 170 // Note(fbarchard): This option does modify the user's data buffer. |
| 170 CHAR64LONG16* block = const_cast<CHAR64LONG16*>( | 171 CHAR64LONG16* block = const_cast<CHAR64LONG16*>( |
| 171 reinterpret_cast<const CHAR64LONG16*>(buffer)); | 172 reinterpret_cast<const CHAR64LONG16*>(buffer)); |
| 172 #endif | 173 #endif |
| 173 | 174 |
| 174 // Copy context->state[] to working vars. | 175 // Copy context->state[] to working vars. |
| 175 uint32 a = state[0]; | 176 uint32_t a = state[0]; |
| 176 uint32 b = state[1]; | 177 uint32_t b = state[1]; |
| 177 uint32 c = state[2]; | 178 uint32_t c = state[2]; |
| 178 uint32 d = state[3]; | 179 uint32_t d = state[3]; |
| 179 uint32 e = state[4]; | 180 uint32_t e = state[4]; |
| 180 | 181 |
| 181 // 4 rounds of 20 operations each. Loop unrolled. | 182 // 4 rounds of 20 operations each. Loop unrolled. |
| 182 // Note(fbarchard): The following has lint warnings for multiple ; on | 183 // 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 | 184 // a line and no space after , but is left as-is to be similar to the |
| 184 // original code. | 185 // 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); | 186 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); | 187 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); | 188 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); | 189 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); | 190 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. | 219 // SHA1 initialization constants. |
| 219 context->state[0] = 0x67452301; | 220 context->state[0] = 0x67452301; |
| 220 context->state[1] = 0xEFCDAB89; | 221 context->state[1] = 0xEFCDAB89; |
| 221 context->state[2] = 0x98BADCFE; | 222 context->state[2] = 0x98BADCFE; |
| 222 context->state[3] = 0x10325476; | 223 context->state[3] = 0x10325476; |
| 223 context->state[4] = 0xC3D2E1F0; | 224 context->state[4] = 0xC3D2E1F0; |
| 224 context->count[0] = context->count[1] = 0; | 225 context->count[0] = context->count[1] = 0; |
| 225 } | 226 } |
| 226 | 227 |
| 227 // Run your data through this. | 228 // Run your data through this. |
| 228 void SHA1Update(SHA1_CTX* context, const uint8* data, size_t input_len) { | 229 void SHA1Update(SHA1_CTX* context, const uint8_t* data, size_t input_len) { |
| 229 size_t i = 0; | 230 size_t i = 0; |
| 230 | 231 |
| 231 #ifdef VERBOSE | 232 #ifdef VERBOSE |
| 232 SHAPrintContext(context, "before"); | 233 SHAPrintContext(context, "before"); |
| 233 #endif | 234 #endif |
| 234 | 235 |
| 235 // Compute number of bytes mod 64. | 236 // Compute number of bytes mod 64. |
| 236 size_t index = (context->count[0] >> 3) & 63; | 237 size_t index = (context->count[0] >> 3) & 63; |
| 237 | 238 |
| 238 // Update number of bits. | 239 // Update number of bits. |
| 239 // TODO: Use uint64 instead of 2 uint32 for count. | 240 // 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 | 241 // count[0] has low 29 bits for byte count + 3 pad 0's making 32 bits for |
| 241 // bit count. | 242 // bit count. |
| 242 // Add bit count to low uint32 | 243 // Add bit count to low uint32_t |
| 243 context->count[0] += static_cast<uint32>(input_len << 3); | 244 context->count[0] += static_cast<uint32_t>(input_len << 3); |
| 244 if (context->count[0] < static_cast<uint32>(input_len << 3)) { | 245 if (context->count[0] < static_cast<uint32_t>(input_len << 3)) { |
| 245 ++context->count[1]; // if overlow (carry), add one to high word | 246 ++context->count[1]; // if overlow (carry), add one to high word |
| 246 } | 247 } |
| 247 context->count[1] += static_cast<uint32>(input_len >> 29); | 248 context->count[1] += static_cast<uint32_t>(input_len >> 29); |
| 248 if ((index + input_len) > 63) { | 249 if ((index + input_len) > 63) { |
| 249 i = 64 - index; | 250 i = 64 - index; |
| 250 memcpy(&context->buffer[index], data, i); | 251 memcpy(&context->buffer[index], data, i); |
| 251 SHA1Transform(context->state, context->buffer); | 252 SHA1Transform(context->state, context->buffer); |
| 252 for (; i + 63 < input_len; i += 64) { | 253 for (; i + 63 < input_len; i += 64) { |
| 253 SHA1Transform(context->state, data + i); | 254 SHA1Transform(context->state, data + i); |
| 254 } | 255 } |
| 255 index = 0; | 256 index = 0; |
| 256 } | 257 } |
| 257 memcpy(&context->buffer[index], &data[i], input_len - i); | 258 memcpy(&context->buffer[index], &data[i], input_len - i); |
| 258 | 259 |
| 259 #ifdef VERBOSE | 260 #ifdef VERBOSE |
| 260 SHAPrintContext(context, "after "); | 261 SHAPrintContext(context, "after "); |
| 261 #endif | 262 #endif |
| 262 } | 263 } |
| 263 | 264 |
| 264 // Add padding and return the message digest. | 265 // Add padding and return the message digest. |
| 265 void SHA1Final(SHA1_CTX* context, uint8 digest[SHA1_DIGEST_SIZE]) { | 266 void SHA1Final(SHA1_CTX* context, uint8_t digest[SHA1_DIGEST_SIZE]) { |
| 266 uint8 finalcount[8]; | 267 uint8_t finalcount[8]; |
| 267 for (int i = 0; i < 8; ++i) { | 268 for (int i = 0; i < 8; ++i) { |
| 268 // Endian independent | 269 // Endian independent |
| 269 finalcount[i] = static_cast<uint8>( | 270 finalcount[i] = static_cast<uint8_t>( |
| 270 (context->count[(i >= 4 ? 0 : 1)] >> ((3 - (i & 3)) * 8) ) & 255); | 271 (context->count[(i >= 4 ? 0 : 1)] >> ((3 - (i & 3)) * 8)) & 255); |
| 271 } | 272 } |
| 272 SHA1Update(context, reinterpret_cast<const uint8*>("\200"), 1); | 273 SHA1Update(context, reinterpret_cast<const uint8_t*>("\200"), 1); |
| 273 while ((context->count[0] & 504) != 448) { | 274 while ((context->count[0] & 504) != 448) { |
| 274 SHA1Update(context, reinterpret_cast<const uint8*>("\0"), 1); | 275 SHA1Update(context, reinterpret_cast<const uint8_t*>("\0"), 1); |
| 275 } | 276 } |
| 276 SHA1Update(context, finalcount, 8); // Should cause a SHA1Transform(). | 277 SHA1Update(context, finalcount, 8); // Should cause a SHA1Transform(). |
| 277 for (int i = 0; i < SHA1_DIGEST_SIZE; ++i) { | 278 for (int i = 0; i < SHA1_DIGEST_SIZE; ++i) { |
| 278 digest[i] = static_cast<uint8>( | 279 digest[i] = static_cast<uint8_t>( |
| 279 (context->state[i >> 2] >> ((3 - (i & 3)) * 8) ) & 255); | 280 (context->state[i >> 2] >> ((3 - (i & 3)) * 8)) & 255); |
| 280 } | 281 } |
| 281 | 282 |
| 282 // Wipe variables. | 283 // Wipe variables. |
| 283 memset(context->buffer, 0, 64); | 284 memset(context->buffer, 0, 64); |
| 284 memset(context->state, 0, 20); | 285 memset(context->state, 0, 20); |
| 285 memset(context->count, 0, 8); | 286 memset(context->count, 0, 8); |
| 286 memset(finalcount, 0, 8); // SWR | 287 memset(finalcount, 0, 8); // SWR |
| 287 | 288 |
| 288 #ifdef SHA1HANDSOFF // Make SHA1Transform overwrite its own static vars. | 289 #ifdef SHA1HANDSOFF // Make SHA1Transform overwrite its own static vars. |
| 289 SHA1Transform(context->state, context->buffer); | 290 SHA1Transform(context->state, context->buffer); |
| 290 #endif | 291 #endif |
| 291 } | 292 } |
| 292 | 293 |
| 293 } // namespace rtc | 294 } // namespace rtc |
| OLD | NEW |