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 "base/sha1.h" 6 7 #include <stddef.h> 8 #include <stdint.h> 9 #include <string.h> 10 11 12 namespace base { 13 14 // Implementation of SHA-1. Only handles data in byte-sized blocks, 15 // which simplifies the code a fair bit. 16 17 // Identifier names follow notation in FIPS PUB 180-3, where you'll 18 // also find a description of the algorithm: 19 // http://csrc.nist.gov/publications/fips/fips180-3/fips180-3_final.pdf 20 21 // Usage example: 22 // 23 // SecureHashAlgorithm sha; 24 // while(there is data to hash) 25 // sha.Update(moredata, size of data); 26 // sha.Final(); 27 // memcpy(somewhere, sha.Digest(), 20); 28 // 29 // to reuse the instance of sha, call sha.Init(); 30 31 // TODO(jhawkins): Replace this implementation with a per-platform 32 // implementation using each platform's crypto library. See 33 // http://crbug.com/47218 34 35 class SecureHashAlgorithm { 36 public: 37 SecureHashAlgorithm() { Init(); } 38 39 static const int kDigestSizeBytes; 40 41 void Init(); 42 void Update(const void* data, size_t nbytes); 43 void Final(); 44 45 // 20 bytes of message digest. 46 const unsigned char* Digest() const { 47 return reinterpret_cast<const unsigned char*>(H); 48 } 49 50 private: 51 void Pad(); 52 void Process(); 53 54 uint32_t A, B, C, D, E; 55 56 uint32_t H[5]; 57 58 union { 59 uint32_t W[80]; 60 uint8_t M[64]; 61 }; 62 63 uint32_t cursor; 64 uint64_t l; 65 }; 66 67 static inline uint32_t f(uint32_t t, uint32_t B, uint32_t C, uint32_t D) { 68 if (t < 20) { 69 return (B & C) | ((~B) & D); 70 } else if (t < 40) { 71 return B ^ C ^ D; 72 } else if (t < 60) { 73 return (B & C) | (B & D) | (C & D); 74 } else { 75 return B ^ C ^ D; 76 } 77 } 78 79 static inline uint32_t S(uint32_t n, uint32_t X) { 80 return (X << n) | (X >> (32-n)); 81 } 82 83 static inline uint32_t K(uint32_t t) { 84 if (t < 20) { 85 return 0x5a827999; 86 } else if (t < 40) { 87 return 0x6ed9eba1; 88 } else if (t < 60) { 89 return 0x8f1bbcdc; 90 } else { 91 return 0xca62c1d6; 92 } 93 } 94 95 static inline void swapends(uint32_t* t) { 96 *t = (*t >> 24) | ((*t >> 8) & 0xff00) | ((*t & 0xff00) << 8) | (*t << 24); 97 } 98 99 const int SecureHashAlgorithm::kDigestSizeBytes = 20; 100 101 void SecureHashAlgorithm::Init() { 102 A = 0; 103 B = 0; 104 C = 0; 105 D = 0; 106 E = 0; 107 cursor = 0; 108 l = 0; 109 H[0] = 0x67452301; 110 H[1] = 0xefcdab89; 111 H[2] = 0x98badcfe; 112 H[3] = 0x10325476; 113 H[4] = 0xc3d2e1f0; 114 } 115 116 void SecureHashAlgorithm::Final() { 117 Pad(); 118 Process(); 119 120 for (int t = 0; t < 5; ++t) 121 swapends(&H[t]); 122 } 123 124 void SecureHashAlgorithm::Update(const void* data, size_t nbytes) { 125 const uint8_t* d = reinterpret_cast<const uint8_t*>(data); 126 while (nbytes--) { 127 M[cursor++] = *d++; 128 if (cursor >= 64) 129 Process(); 130 l += 8; 131 } 132 } 133 134 void SecureHashAlgorithm::Pad() { 135 M[cursor++] = 0x80; 136 137 if (cursor > 64-8) { 138 // pad out to next block 139 while (cursor < 64) 140 M[cursor++] = 0; 141 142 Process(); 143 } 144 145 while (cursor < 64-8) 146 M[cursor++] = 0; 147 148 M[cursor++] = (l >> 56) & 0xff; 149 M[cursor++] = (l >> 48) & 0xff; 150 M[cursor++] = (l >> 40) & 0xff; 151 M[cursor++] = (l >> 32) & 0xff; 152 M[cursor++] = (l >> 24) & 0xff; 153 M[cursor++] = (l >> 16) & 0xff; 154 M[cursor++] = (l >> 8) & 0xff; 155 M[cursor++] = l & 0xff; 156 } 157 158 void SecureHashAlgorithm::Process() { 159 uint32_t t; 160 161 // Each a...e corresponds to a section in the FIPS 180-3 algorithm. 162 163 // a. 164 // 165 // W and M are in a union, so no need to memcpy. 166 // memcpy(W, M, sizeof(M)); 167 for (t = 0; t < 16; ++t) 168 swapends(&W[t]); 169 170 // b. 171 for (t = 16; t < 80; ++t) 172 W[t] = S(1, W[t - 3] ^ W[t - 8] ^ W[t - 14] ^ W[t - 16]); 173 174 // c. 175 A = H[0]; 176 B = H[1]; 177 C = H[2]; 178 D = H[3]; 179 E = H[4]; 180 181 // d. 182 for (t = 0; t < 80; ++t) { 183 uint32_t TEMP = S(5, A) + f(t, B, C, D) + E + W[t] + K(t); 184 E = D; 185 D = C; 186 C = S(30, B); 187 B = A; 188 A = TEMP; 189 } 190 191 // e. 192 H[0] += A; 193 H[1] += B; 194 H[2] += C; 195 H[3] += D; 196 H[4] += E; 197 198 cursor = 0; 199 } 200 201 std::string SHA1HashString(const std::string& str) { 202 char hash[SecureHashAlgorithm::kDigestSizeBytes]; 203 SHA1HashBytes(reinterpret_cast<const unsigned char*>(str.c_str()), 204 str.length(), reinterpret_cast<unsigned char*>(hash)); 205 return std::string(hash, SecureHashAlgorithm::kDigestSizeBytes); 206 } 207 208 void SHA1HashBytes(const unsigned char* data, size_t len, 209 unsigned char* hash) { 210 SecureHashAlgorithm sha; 211 sha.Update(data, len); 212 sha.Final(); 213 214 memcpy(hash, sha.Digest(), SecureHashAlgorithm::kDigestSizeBytes); 215 } 216 217 } // namespace base 218