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