15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2011 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/sha1.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string.h> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace base { 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Implementation of SHA-1. Only handles data in byte-sized blocks, 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// which simplifies the code a fair bit. 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Identifier names follow notation in FIPS PUB 180-3, where you'll 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// also find a description of the algorithm: 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// http://csrc.nist.gov/publications/fips/fips180-3/fips180-3_final.pdf 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Usage example: 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// SecureHashAlgorithm sha; 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// while(there is data to hash) 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// sha.Update(moredata, size of data); 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// sha.Final(); 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// memcpy(somewhere, sha.Digest(), 20); 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// to reuse the instance of sha, call sha.Init(); 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TODO(jhawkins): Replace this implementation with a per-platform 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// implementation using each platform's crypto library. See 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// http://crbug.com/47218 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SecureHashAlgorithm { 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SecureHashAlgorithm() { Init(); } 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const int kDigestSizeBytes; 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void Init(); 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void Update(const void* data, size_t nbytes); 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void Final(); 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 20 bytes of message digest. 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const unsigned char* Digest() const { 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return reinterpret_cast<const unsigned char*>(H); 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void Pad(); 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void Process(); 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32 A, B, C, D, E; 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32 H[5]; 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) union { 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32 W[80]; 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint8 M[64]; 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32 cursor; 63116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch uint64 l; 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static inline uint32 f(uint32 t, uint32 B, uint32 C, uint32 D) { 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (t < 20) { 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (B & C) | ((~B) & D); 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (t < 40) { 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return B ^ C ^ D; 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (t < 60) { 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (B & C) | (B & D) | (C & D); 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return B ^ C ^ D; 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static inline uint32 S(uint32 n, uint32 X) { 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (X << n) | (X >> (32-n)); 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static inline uint32 K(uint32 t) { 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (t < 20) { 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0x5a827999; 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (t < 40) { 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0x6ed9eba1; 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (t < 60) { 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0x8f1bbcdc; 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0xca62c1d6; 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static inline void swapends(uint32* t) { 95116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch *t = (*t >> 24) | ((*t >> 8) & 0xff00) | ((*t & 0xff00) << 8) | (*t << 24); 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int SecureHashAlgorithm::kDigestSizeBytes = 20; 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SecureHashAlgorithm::Init() { 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) A = 0; 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) B = 0; 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) C = 0; 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) D = 0; 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) E = 0; 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cursor = 0; 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) l = 0; 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) H[0] = 0x67452301; 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) H[1] = 0xefcdab89; 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) H[2] = 0x98badcfe; 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) H[3] = 0x10325476; 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) H[4] = 0xc3d2e1f0; 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SecureHashAlgorithm::Final() { 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Pad(); 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Process(); 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int t = 0; t < 5; ++t) 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) swapends(&H[t]); 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SecureHashAlgorithm::Update(const void* data, size_t nbytes) { 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const uint8* d = reinterpret_cast<const uint8*>(data); 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (nbytes--) { 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) M[cursor++] = *d++; 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cursor >= 64) 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Process(); 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) l += 8; 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SecureHashAlgorithm::Pad() { 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) M[cursor++] = 0x80; 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cursor > 64-8) { 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // pad out to next block 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (cursor < 64) 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) M[cursor++] = 0; 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Process(); 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 144116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch while (cursor < 64-8) 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) M[cursor++] = 0; 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 147116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch M[cursor++] = (l >> 56) & 0xff; 148116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch M[cursor++] = (l >> 48) & 0xff; 149116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch M[cursor++] = (l >> 40) & 0xff; 150116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch M[cursor++] = (l >> 32) & 0xff; 151116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch M[cursor++] = (l >> 24) & 0xff; 152116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch M[cursor++] = (l >> 16) & 0xff; 153116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch M[cursor++] = (l >> 8) & 0xff; 154116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch M[cursor++] = l & 0xff; 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SecureHashAlgorithm::Process() { 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32 t; 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Each a...e corresponds to a section in the FIPS 180-3 algorithm. 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // a. 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // W and M are in a union, so no need to memcpy. 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // memcpy(W, M, sizeof(M)); 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (t = 0; t < 16; ++t) 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) swapends(&W[t]); 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // b. 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (t = 16; t < 80; ++t) 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) W[t] = S(1, W[t - 3] ^ W[t - 8] ^ W[t - 14] ^ W[t - 16]); 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // c. 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) A = H[0]; 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) B = H[1]; 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) C = H[2]; 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) D = H[3]; 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) E = H[4]; 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // d. 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (t = 0; t < 80; ++t) { 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32 TEMP = S(5, A) + f(t, B, C, D) + E + W[t] + K(t); 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) E = D; 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) D = C; 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) C = S(30, B); 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) B = A; 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) A = TEMP; 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // e. 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) H[0] += A; 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) H[1] += B; 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) H[2] += C; 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) H[3] += D; 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) H[4] += E; 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cursor = 0; 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string SHA1HashString(const std::string& str) { 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char hash[SecureHashAlgorithm::kDigestSizeBytes]; 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SHA1HashBytes(reinterpret_cast<const unsigned char*>(str.c_str()), 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) str.length(), reinterpret_cast<unsigned char*>(hash)); 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return std::string(hash, SecureHashAlgorithm::kDigestSizeBytes); 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SHA1HashBytes(const unsigned char* data, size_t len, 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned char* hash) { 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SecureHashAlgorithm sha; 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sha.Update(data, len); 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sha.Final(); 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(hash, sha.Digest(), SecureHashAlgorithm::kDigestSizeBytes); 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace base 217