Home | History | Annotate | Download | only in base
      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