xref: /aosp_15_r20/external/libchrome/base/sha1.cc (revision 635a864187cb8b6c713ff48b7e790a6b21769273)
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