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