sha1_portable.cc revision 5821806d5e7f356e8fa4b058a389a808ea183019
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; 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32 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) { 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *t = ((*t & 0xff000000) >> 24) | 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ((*t & 0xff0000) >> 8) | 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ((*t & 0xff00) << 8) | 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ((*t & 0xff) << 24); 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int SecureHashAlgorithm::kDigestSizeBytes = 20; 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SecureHashAlgorithm::Init() { 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) A = 0; 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) B = 0; 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) C = 0; 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) D = 0; 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) E = 0; 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cursor = 0; 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) l = 0; 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) H[0] = 0x67452301; 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) H[1] = 0xefcdab89; 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) H[2] = 0x98badcfe; 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) H[3] = 0x10325476; 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) H[4] = 0xc3d2e1f0; 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SecureHashAlgorithm::Final() { 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Pad(); 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Process(); 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int t = 0; t < 5; ++t) 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) swapends(&H[t]); 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SecureHashAlgorithm::Update(const void* data, size_t nbytes) { 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const uint8* d = reinterpret_cast<const uint8*>(data); 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (nbytes--) { 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) M[cursor++] = *d++; 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cursor >= 64) 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Process(); 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) l += 8; 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SecureHashAlgorithm::Pad() { 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) M[cursor++] = 0x80; 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cursor > 64-8) { 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // pad out to next block 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (cursor < 64) 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) M[cursor++] = 0; 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Process(); 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (cursor < 64-4) 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) M[cursor++] = 0; 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) M[64-4] = (l & 0xff000000) >> 24; 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) M[64-3] = (l & 0xff0000) >> 16; 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) M[64-2] = (l & 0xff00) >> 8; 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) M[64-1] = (l & 0xff); 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SecureHashAlgorithm::Process() { 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32 t; 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Each a...e corresponds to a section in the FIPS 180-3 algorithm. 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // a. 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // W and M are in a union, so no need to memcpy. 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // memcpy(W, M, sizeof(M)); 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (t = 0; t < 16; ++t) 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) swapends(&W[t]); 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // b. 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (t = 16; t < 80; ++t) 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) W[t] = S(1, W[t - 3] ^ W[t - 8] ^ W[t - 14] ^ W[t - 16]); 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // c. 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) A = H[0]; 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) B = H[1]; 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) C = H[2]; 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) D = H[3]; 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) E = H[4]; 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // d. 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (t = 0; t < 80; ++t) { 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32 TEMP = S(5, A) + f(t, B, C, D) + E + W[t] + K(t); 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) E = D; 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) D = C; 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) C = S(30, B); 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) B = A; 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) A = TEMP; 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // e. 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) H[0] += A; 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) H[1] += B; 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) H[2] += C; 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) H[3] += D; 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) H[4] += E; 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cursor = 0; 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string SHA1HashString(const std::string& str) { 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char hash[SecureHashAlgorithm::kDigestSizeBytes]; 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SHA1HashBytes(reinterpret_cast<const unsigned char*>(str.c_str()), 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) str.length(), reinterpret_cast<unsigned char*>(hash)); 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return std::string(hash, SecureHashAlgorithm::kDigestSizeBytes); 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SHA1HashBytes(const unsigned char* data, size_t len, 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned char* hash) { 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SecureHashAlgorithm sha; 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sha.Update(data, len); 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sha.Final(); 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(hash, sha.Digest(), SecureHashAlgorithm::kDigestSizeBytes); 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace base 216