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