| 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 |