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