1*8975f5c5SAndroid Build Coastguard Worker // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2*8975f5c5SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*8975f5c5SAndroid Build Coastguard Worker // found in the LICENSE file.
4*8975f5c5SAndroid Build Coastguard Worker
5*8975f5c5SAndroid Build Coastguard Worker #include "anglebase/sha1.h"
6*8975f5c5SAndroid Build Coastguard Worker
7*8975f5c5SAndroid Build Coastguard Worker #include <stddef.h>
8*8975f5c5SAndroid Build Coastguard Worker #include <stdint.h>
9*8975f5c5SAndroid Build Coastguard Worker #include <string.h>
10*8975f5c5SAndroid Build Coastguard Worker
11*8975f5c5SAndroid Build Coastguard Worker #include "anglebase/sys_byteorder.h"
12*8975f5c5SAndroid Build Coastguard Worker
13*8975f5c5SAndroid Build Coastguard Worker namespace angle
14*8975f5c5SAndroid Build Coastguard Worker {
15*8975f5c5SAndroid Build Coastguard Worker
16*8975f5c5SAndroid Build Coastguard Worker namespace base
17*8975f5c5SAndroid Build Coastguard Worker {
18*8975f5c5SAndroid Build Coastguard Worker
f(uint32_t t,uint32_t B,uint32_t C,uint32_t D)19*8975f5c5SAndroid Build Coastguard Worker static inline uint32_t f(uint32_t t, uint32_t B, uint32_t C, uint32_t D)
20*8975f5c5SAndroid Build Coastguard Worker {
21*8975f5c5SAndroid Build Coastguard Worker if (t < 20)
22*8975f5c5SAndroid Build Coastguard Worker {
23*8975f5c5SAndroid Build Coastguard Worker return (B & C) | ((~B) & D);
24*8975f5c5SAndroid Build Coastguard Worker }
25*8975f5c5SAndroid Build Coastguard Worker else if (t < 40)
26*8975f5c5SAndroid Build Coastguard Worker {
27*8975f5c5SAndroid Build Coastguard Worker return B ^ C ^ D;
28*8975f5c5SAndroid Build Coastguard Worker }
29*8975f5c5SAndroid Build Coastguard Worker else if (t < 60)
30*8975f5c5SAndroid Build Coastguard Worker {
31*8975f5c5SAndroid Build Coastguard Worker return (B & C) | (B & D) | (C & D);
32*8975f5c5SAndroid Build Coastguard Worker }
33*8975f5c5SAndroid Build Coastguard Worker else
34*8975f5c5SAndroid Build Coastguard Worker {
35*8975f5c5SAndroid Build Coastguard Worker return B ^ C ^ D;
36*8975f5c5SAndroid Build Coastguard Worker }
37*8975f5c5SAndroid Build Coastguard Worker }
38*8975f5c5SAndroid Build Coastguard Worker
S(uint32_t n,uint32_t X)39*8975f5c5SAndroid Build Coastguard Worker static inline uint32_t S(uint32_t n, uint32_t X)
40*8975f5c5SAndroid Build Coastguard Worker {
41*8975f5c5SAndroid Build Coastguard Worker return (X << n) | (X >> (32 - n));
42*8975f5c5SAndroid Build Coastguard Worker }
43*8975f5c5SAndroid Build Coastguard Worker
K(uint32_t t)44*8975f5c5SAndroid Build Coastguard Worker static inline uint32_t K(uint32_t t)
45*8975f5c5SAndroid Build Coastguard Worker {
46*8975f5c5SAndroid Build Coastguard Worker if (t < 20)
47*8975f5c5SAndroid Build Coastguard Worker {
48*8975f5c5SAndroid Build Coastguard Worker return 0x5a827999;
49*8975f5c5SAndroid Build Coastguard Worker }
50*8975f5c5SAndroid Build Coastguard Worker else if (t < 40)
51*8975f5c5SAndroid Build Coastguard Worker {
52*8975f5c5SAndroid Build Coastguard Worker return 0x6ed9eba1;
53*8975f5c5SAndroid Build Coastguard Worker }
54*8975f5c5SAndroid Build Coastguard Worker else if (t < 60)
55*8975f5c5SAndroid Build Coastguard Worker {
56*8975f5c5SAndroid Build Coastguard Worker return 0x8f1bbcdc;
57*8975f5c5SAndroid Build Coastguard Worker }
58*8975f5c5SAndroid Build Coastguard Worker else
59*8975f5c5SAndroid Build Coastguard Worker {
60*8975f5c5SAndroid Build Coastguard Worker return 0xca62c1d6;
61*8975f5c5SAndroid Build Coastguard Worker }
62*8975f5c5SAndroid Build Coastguard Worker }
63*8975f5c5SAndroid Build Coastguard Worker
64*8975f5c5SAndroid Build Coastguard Worker const int SecureHashAlgorithm::kDigestSizeBytes = 20;
65*8975f5c5SAndroid Build Coastguard Worker
Init()66*8975f5c5SAndroid Build Coastguard Worker void SecureHashAlgorithm::Init()
67*8975f5c5SAndroid Build Coastguard Worker {
68*8975f5c5SAndroid Build Coastguard Worker A = 0;
69*8975f5c5SAndroid Build Coastguard Worker B = 0;
70*8975f5c5SAndroid Build Coastguard Worker C = 0;
71*8975f5c5SAndroid Build Coastguard Worker D = 0;
72*8975f5c5SAndroid Build Coastguard Worker E = 0;
73*8975f5c5SAndroid Build Coastguard Worker cursor = 0;
74*8975f5c5SAndroid Build Coastguard Worker l = 0;
75*8975f5c5SAndroid Build Coastguard Worker H[0] = 0x67452301;
76*8975f5c5SAndroid Build Coastguard Worker H[1] = 0xefcdab89;
77*8975f5c5SAndroid Build Coastguard Worker H[2] = 0x98badcfe;
78*8975f5c5SAndroid Build Coastguard Worker H[3] = 0x10325476;
79*8975f5c5SAndroid Build Coastguard Worker H[4] = 0xc3d2e1f0;
80*8975f5c5SAndroid Build Coastguard Worker }
81*8975f5c5SAndroid Build Coastguard Worker
Final()82*8975f5c5SAndroid Build Coastguard Worker void SecureHashAlgorithm::Final()
83*8975f5c5SAndroid Build Coastguard Worker {
84*8975f5c5SAndroid Build Coastguard Worker Pad();
85*8975f5c5SAndroid Build Coastguard Worker Process();
86*8975f5c5SAndroid Build Coastguard Worker
87*8975f5c5SAndroid Build Coastguard Worker for (int t = 0; t < 5; ++t)
88*8975f5c5SAndroid Build Coastguard Worker H[t] = ByteSwap(H[t]);
89*8975f5c5SAndroid Build Coastguard Worker }
90*8975f5c5SAndroid Build Coastguard Worker
Update(const void * data,size_t nbytes)91*8975f5c5SAndroid Build Coastguard Worker void SecureHashAlgorithm::Update(const void *data, size_t nbytes)
92*8975f5c5SAndroid Build Coastguard Worker {
93*8975f5c5SAndroid Build Coastguard Worker const uint8_t *d = reinterpret_cast<const uint8_t *>(data);
94*8975f5c5SAndroid Build Coastguard Worker while (nbytes--)
95*8975f5c5SAndroid Build Coastguard Worker {
96*8975f5c5SAndroid Build Coastguard Worker M[cursor++] = *d++;
97*8975f5c5SAndroid Build Coastguard Worker if (cursor >= 64)
98*8975f5c5SAndroid Build Coastguard Worker Process();
99*8975f5c5SAndroid Build Coastguard Worker l += 8;
100*8975f5c5SAndroid Build Coastguard Worker }
101*8975f5c5SAndroid Build Coastguard Worker }
102*8975f5c5SAndroid Build Coastguard Worker
Pad()103*8975f5c5SAndroid Build Coastguard Worker void SecureHashAlgorithm::Pad()
104*8975f5c5SAndroid Build Coastguard Worker {
105*8975f5c5SAndroid Build Coastguard Worker M[cursor++] = 0x80;
106*8975f5c5SAndroid Build Coastguard Worker
107*8975f5c5SAndroid Build Coastguard Worker if (cursor > 64 - 8)
108*8975f5c5SAndroid Build Coastguard Worker {
109*8975f5c5SAndroid Build Coastguard Worker // pad out to next block
110*8975f5c5SAndroid Build Coastguard Worker while (cursor < 64)
111*8975f5c5SAndroid Build Coastguard Worker M[cursor++] = 0;
112*8975f5c5SAndroid Build Coastguard Worker
113*8975f5c5SAndroid Build Coastguard Worker Process();
114*8975f5c5SAndroid Build Coastguard Worker }
115*8975f5c5SAndroid Build Coastguard Worker
116*8975f5c5SAndroid Build Coastguard Worker while (cursor < 64 - 8)
117*8975f5c5SAndroid Build Coastguard Worker M[cursor++] = 0;
118*8975f5c5SAndroid Build Coastguard Worker
119*8975f5c5SAndroid Build Coastguard Worker M[cursor++] = (l >> 56) & 0xff;
120*8975f5c5SAndroid Build Coastguard Worker M[cursor++] = (l >> 48) & 0xff;
121*8975f5c5SAndroid Build Coastguard Worker M[cursor++] = (l >> 40) & 0xff;
122*8975f5c5SAndroid Build Coastguard Worker M[cursor++] = (l >> 32) & 0xff;
123*8975f5c5SAndroid Build Coastguard Worker M[cursor++] = (l >> 24) & 0xff;
124*8975f5c5SAndroid Build Coastguard Worker M[cursor++] = (l >> 16) & 0xff;
125*8975f5c5SAndroid Build Coastguard Worker M[cursor++] = (l >> 8) & 0xff;
126*8975f5c5SAndroid Build Coastguard Worker M[cursor++] = l & 0xff;
127*8975f5c5SAndroid Build Coastguard Worker }
128*8975f5c5SAndroid Build Coastguard Worker
Process()129*8975f5c5SAndroid Build Coastguard Worker void SecureHashAlgorithm::Process()
130*8975f5c5SAndroid Build Coastguard Worker {
131*8975f5c5SAndroid Build Coastguard Worker uint32_t t;
132*8975f5c5SAndroid Build Coastguard Worker
133*8975f5c5SAndroid Build Coastguard Worker // Each a...e corresponds to a section in the FIPS 180-3 algorithm.
134*8975f5c5SAndroid Build Coastguard Worker
135*8975f5c5SAndroid Build Coastguard Worker // a.
136*8975f5c5SAndroid Build Coastguard Worker //
137*8975f5c5SAndroid Build Coastguard Worker // W and M are in a union, so no need to memcpy.
138*8975f5c5SAndroid Build Coastguard Worker // memcpy(W, M, sizeof(M));
139*8975f5c5SAndroid Build Coastguard Worker for (t = 0; t < 16; ++t)
140*8975f5c5SAndroid Build Coastguard Worker W[t] = ByteSwap(W[t]);
141*8975f5c5SAndroid Build Coastguard Worker
142*8975f5c5SAndroid Build Coastguard Worker // b.
143*8975f5c5SAndroid Build Coastguard Worker for (t = 16; t < 80; ++t)
144*8975f5c5SAndroid Build Coastguard Worker W[t] = S(1, W[t - 3] ^ W[t - 8] ^ W[t - 14] ^ W[t - 16]);
145*8975f5c5SAndroid Build Coastguard Worker
146*8975f5c5SAndroid Build Coastguard Worker // c.
147*8975f5c5SAndroid Build Coastguard Worker A = H[0];
148*8975f5c5SAndroid Build Coastguard Worker B = H[1];
149*8975f5c5SAndroid Build Coastguard Worker C = H[2];
150*8975f5c5SAndroid Build Coastguard Worker D = H[3];
151*8975f5c5SAndroid Build Coastguard Worker E = H[4];
152*8975f5c5SAndroid Build Coastguard Worker
153*8975f5c5SAndroid Build Coastguard Worker // d.
154*8975f5c5SAndroid Build Coastguard Worker for (t = 0; t < 80; ++t)
155*8975f5c5SAndroid Build Coastguard Worker {
156*8975f5c5SAndroid Build Coastguard Worker uint32_t TEMP = S(5, A) + f(t, B, C, D) + E + W[t] + K(t);
157*8975f5c5SAndroid Build Coastguard Worker E = D;
158*8975f5c5SAndroid Build Coastguard Worker D = C;
159*8975f5c5SAndroid Build Coastguard Worker C = S(30, B);
160*8975f5c5SAndroid Build Coastguard Worker B = A;
161*8975f5c5SAndroid Build Coastguard Worker A = TEMP;
162*8975f5c5SAndroid Build Coastguard Worker }
163*8975f5c5SAndroid Build Coastguard Worker
164*8975f5c5SAndroid Build Coastguard Worker // e.
165*8975f5c5SAndroid Build Coastguard Worker H[0] += A;
166*8975f5c5SAndroid Build Coastguard Worker H[1] += B;
167*8975f5c5SAndroid Build Coastguard Worker H[2] += C;
168*8975f5c5SAndroid Build Coastguard Worker H[3] += D;
169*8975f5c5SAndroid Build Coastguard Worker H[4] += E;
170*8975f5c5SAndroid Build Coastguard Worker
171*8975f5c5SAndroid Build Coastguard Worker cursor = 0;
172*8975f5c5SAndroid Build Coastguard Worker }
173*8975f5c5SAndroid Build Coastguard Worker
DigestAsArray() const174*8975f5c5SAndroid Build Coastguard Worker std::array<uint8_t, kSHA1Length> SecureHashAlgorithm::DigestAsArray() const
175*8975f5c5SAndroid Build Coastguard Worker {
176*8975f5c5SAndroid Build Coastguard Worker std::array<uint8_t, kSHA1Length> digest;
177*8975f5c5SAndroid Build Coastguard Worker memcpy(digest.data(), Digest(), SecureHashAlgorithm::kDigestSizeBytes);
178*8975f5c5SAndroid Build Coastguard Worker return digest;
179*8975f5c5SAndroid Build Coastguard Worker }
180*8975f5c5SAndroid Build Coastguard Worker
SHA1HashString(const std::string & str)181*8975f5c5SAndroid Build Coastguard Worker std::string SHA1HashString(const std::string &str)
182*8975f5c5SAndroid Build Coastguard Worker {
183*8975f5c5SAndroid Build Coastguard Worker char hash[SecureHashAlgorithm::kDigestSizeBytes];
184*8975f5c5SAndroid Build Coastguard Worker SHA1HashBytes(reinterpret_cast<const unsigned char *>(str.c_str()), str.length(),
185*8975f5c5SAndroid Build Coastguard Worker reinterpret_cast<unsigned char *>(hash));
186*8975f5c5SAndroid Build Coastguard Worker return std::string(hash, SecureHashAlgorithm::kDigestSizeBytes);
187*8975f5c5SAndroid Build Coastguard Worker }
188*8975f5c5SAndroid Build Coastguard Worker
SHA1HashBytes(const unsigned char * data,size_t len,unsigned char * hash)189*8975f5c5SAndroid Build Coastguard Worker void SHA1HashBytes(const unsigned char *data, size_t len, unsigned char *hash)
190*8975f5c5SAndroid Build Coastguard Worker {
191*8975f5c5SAndroid Build Coastguard Worker SecureHashAlgorithm sha;
192*8975f5c5SAndroid Build Coastguard Worker sha.Update(data, len);
193*8975f5c5SAndroid Build Coastguard Worker sha.Final();
194*8975f5c5SAndroid Build Coastguard Worker
195*8975f5c5SAndroid Build Coastguard Worker memcpy(hash, sha.Digest(), SecureHashAlgorithm::kDigestSizeBytes);
196*8975f5c5SAndroid Build Coastguard Worker }
197*8975f5c5SAndroid Build Coastguard Worker
198*8975f5c5SAndroid Build Coastguard Worker } // namespace base
199*8975f5c5SAndroid Build Coastguard Worker
200*8975f5c5SAndroid Build Coastguard Worker } // namespace angle
201