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