1 /*
2 * Copyright (C) 2021 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 #include "perfetto/ext/base/http/sha1.h"
17
18 #include <stddef.h>
19 #include <stdint.h>
20 #include <string.h>
21
22 // From chrome_elf/sha1/sha1.cc.
23
24 namespace perfetto {
25 namespace base {
26
27 namespace {
28
BSwap32(uint32_t x)29 inline uint32_t BSwap32(uint32_t x) {
30 #if defined(__GNUC__)
31 return __builtin_bswap32(x);
32 #elif defined(_MSC_VER)
33 return _byteswap_ulong(x);
34 #else
35 return (((x & 0xff000000u) >> 24) | ((x & 0x00ff0000u) >> 8) |
36 ((x & 0x0000ff00u) << 8) | ((x & 0x000000ffu) << 24));
37 #endif
38 }
39
40 // Usage example:
41 //
42 // SecureHashAlgorithm sha;
43 // while(there is data to hash)
44 // sha.Update(moredata, size of data);
45 // sha.Final();
46 // memcpy(somewhere, sha.Digest(), 20);
47 //
48 // to reuse the instance of sha, call sha.Init();
49 class SecureHashAlgorithm {
50 public:
SecureHashAlgorithm()51 SecureHashAlgorithm() { Init(); }
52
53 void Init();
54 void Update(const void* data, size_t nbytes);
55 void Final();
56
57 // 20 bytes of message digest.
Digest() const58 const unsigned char* Digest() const {
59 return reinterpret_cast<const unsigned char*>(H);
60 }
61
62 private:
63 void Pad();
64 void Process();
65
66 uint32_t A, B, C, D, E;
67
68 uint32_t H[5];
69
70 union {
71 uint32_t W[80];
72 uint8_t M[64];
73 };
74
75 uint32_t cursor;
76 uint64_t l;
77 };
78
79 //------------------------------------------------------------------------------
80 // Private functions
81 //------------------------------------------------------------------------------
82
83 // Identifier names follow notation in FIPS PUB 180-3, where you'll
84 // also find a description of the algorithm:
85 // http://csrc.nist.gov/publications/fips/fips180-3/fips180-3_final.pdf
86
f(uint32_t t,uint32_t B,uint32_t C,uint32_t D)87 inline uint32_t f(uint32_t t, uint32_t B, uint32_t C, uint32_t D) {
88 if (t < 20) {
89 return (B & C) | ((~B) & D);
90 } else if (t < 40) {
91 return B ^ C ^ D;
92 } else if (t < 60) {
93 return (B & C) | (B & D) | (C & D);
94 } else {
95 return B ^ C ^ D;
96 }
97 }
98
S(uint32_t n,uint32_t X)99 inline uint32_t S(uint32_t n, uint32_t X) {
100 return (X << n) | (X >> (32 - n));
101 }
102
K(uint32_t t)103 inline uint32_t K(uint32_t t) {
104 if (t < 20) {
105 return 0x5a827999;
106 } else if (t < 40) {
107 return 0x6ed9eba1;
108 } else if (t < 60) {
109 return 0x8f1bbcdc;
110 } else {
111 return 0xca62c1d6;
112 }
113 }
114
Init()115 void SecureHashAlgorithm::Init() {
116 A = 0;
117 B = 0;
118 C = 0;
119 D = 0;
120 E = 0;
121 cursor = 0;
122 l = 0;
123 H[0] = 0x67452301;
124 H[1] = 0xefcdab89;
125 H[2] = 0x98badcfe;
126 H[3] = 0x10325476;
127 H[4] = 0xc3d2e1f0;
128 }
129
Update(const void * data,size_t nbytes)130 void SecureHashAlgorithm::Update(const void* data, size_t nbytes) {
131 const uint8_t* d = reinterpret_cast<const uint8_t*>(data);
132 while (nbytes--) {
133 M[cursor++] = *d++;
134 if (cursor >= 64)
135 Process();
136 l += 8;
137 }
138 }
139
Final()140 void SecureHashAlgorithm::Final() {
141 Pad();
142 Process();
143
144 for (size_t t = 0; t < 5; ++t)
145 H[t] = BSwap32(H[t]);
146 }
147
Process()148 void SecureHashAlgorithm::Process() {
149 uint32_t t;
150
151 // Each a...e corresponds to a section in the FIPS 180-3 algorithm.
152
153 // a.
154 //
155 // W and M are in a union, so no need to memcpy.
156 // memcpy(W, M, sizeof(M));
157 for (t = 0; t < 16; ++t)
158 W[t] = BSwap32(W[t]);
159
160 // b.
161 for (t = 16; t < 80; ++t)
162 W[t] = S(1, W[t - 3] ^ W[t - 8] ^ W[t - 14] ^ W[t - 16]);
163
164 // c.
165 A = H[0];
166 B = H[1];
167 C = H[2];
168 D = H[3];
169 E = H[4];
170
171 // d.
172 for (t = 0; t < 80; ++t) {
173 uint32_t TEMP = S(5, A) + f(t, B, C, D) + E + W[t] + K(t);
174 E = D;
175 D = C;
176 C = S(30, B);
177 B = A;
178 A = TEMP;
179 }
180
181 // e.
182 H[0] += A;
183 H[1] += B;
184 H[2] += C;
185 H[3] += D;
186 H[4] += E;
187
188 cursor = 0;
189 }
190
Pad()191 void SecureHashAlgorithm::Pad() {
192 M[cursor++] = 0x80;
193
194 if (cursor > 64 - 8) {
195 // pad out to next block
196 while (cursor < 64)
197 M[cursor++] = 0;
198
199 Process();
200 }
201
202 while (cursor < 64 - 8)
203 M[cursor++] = 0;
204
205 M[cursor++] = (l >> 56) & 0xff;
206 M[cursor++] = (l >> 48) & 0xff;
207 M[cursor++] = (l >> 40) & 0xff;
208 M[cursor++] = (l >> 32) & 0xff;
209 M[cursor++] = (l >> 24) & 0xff;
210 M[cursor++] = (l >> 16) & 0xff;
211 M[cursor++] = (l >> 8) & 0xff;
212 M[cursor++] = l & 0xff;
213 }
214
215 // Computes the SHA-1 hash of the |len| bytes in |data| and puts the hash
216 // in |hash|. |hash| must be kSHA1Length bytes long.
SHA1HashBytes(const unsigned char * data,size_t len,unsigned char * hash)217 void SHA1HashBytes(const unsigned char* data, size_t len, unsigned char* hash) {
218 SecureHashAlgorithm sha;
219 sha.Update(data, len);
220 sha.Final();
221
222 ::memcpy(hash, sha.Digest(), kSHA1Length);
223 }
224
225 } // namespace
226
227 //------------------------------------------------------------------------------
228 // Public functions
229 //------------------------------------------------------------------------------
SHA1Hash(const void * data,size_t size)230 SHA1Digest SHA1Hash(const void* data, size_t size) {
231 SHA1Digest digest;
232 SHA1HashBytes(static_cast<const unsigned char*>(data), size,
233 reinterpret_cast<unsigned char*>(&digest[0]));
234 return digest;
235 }
236
SHA1Hash(const std::string & str)237 SHA1Digest SHA1Hash(const std::string& str) {
238 return SHA1Hash(str.data(), str.size());
239 }
240
241 } // namespace base
242 } // namespace perfetto
243