xref: /aosp_15_r20/external/toybox/lib/hash.c (revision cf5a6c84e2b8763fc1a7db14496fd4742913b199)
1 /* hash.c - Calculate various cryptographic hashes.
2  *
3  * Copyright 2012, 2021 Rob Landley <[email protected]>
4  *
5  * See http://www.ietf.org/rfc/rfc1321.txt
6  * and http://www.ietf.org/rfc/rfc4634.txt
7  */
8 
9 #include "toys.h"
10 
11 // Use external library of hand-coded assembly implementations?
12 #if CFG_TOYBOX_LIBCRYPTO
13 #include <openssl/md5.h>
14 #include <openssl/sha.h>
15 
16 // Initialize array tersely
17 #define HASH_INIT(name, prefix) { name, (void *)prefix##_Init, \
18   (void *)prefix##_Update, (void *)prefix##_Final, \
19   prefix##_DIGEST_LENGTH, }
20 #define SHA1_DIGEST_LENGTH SHA_DIGEST_LENGTH
21 
hash_by_name(int fd,char * name,char * result)22 void hash_by_name(int fd, char *name, char *result)
23 {
24   // Largest context
25   SHA512_CTX ctx;
26   struct hash {
27     char *name;
28     int (*init)(void *);
29     int (*update)(void *, void *, size_t);
30     int (*final)(void *, void *);
31     int digest_length;
32   } algorithms[] = {
33     USE_MD5SUM(HASH_INIT("md5sum", MD5),)
34     USE_SHA1SUM(HASH_INIT("sha1sum", SHA1),)
35     USE_SHA224SUM(HASH_INIT("sha224sum", SHA224),)
36     USE_SHA256SUM(HASH_INIT("sha256sum", SHA256),)
37     USE_SHA384SUM(HASH_INIT("sha384sum", SHA384),)
38     USE_SHA512SUM(HASH_INIT("sha512sum", SHA512),)
39   }, * hash;
40   int i;
41 
42   // This should never NOT match, so no need to check
43   for (i = 0; i<ARRAY_LEN(algorithms); i++)
44     if (!strcmp(name, algorithms[i].name)) break;
45   hash = algorithms+i;
46 
47   hash->init(&ctx);
48   for (;;) {
49       i = read(fd, libbuf, sizeof(libbuf));
50       if (i<1) break;
51       hash->update(&ctx, libbuf, i);
52   }
53   hash->final(libbuf+128, &ctx);
54 
55   for (i = 0; i<hash->digest_length; i++)
56     result += sprintf(result, "%02x", libbuf[i+128]);
57 }
58 
59 // Builtin implementations
60 #else
61 
62 struct browns {
63   unsigned *rconsttable32;
64   unsigned long long *rconsttable64; // for sha384,sha512
65 
66   // Crypto variables blanked after summing
67   unsigned long long count, overflow;
68   union {
69     char c[128]; // bytes, 1024 bits
70     unsigned i32[16]; // 512 bits for md5,sha1,sha224,sha256
71     unsigned long long i64[16]; // 1024 bits for sha384,sha512
72   } state, buffer;
73 };
74 
75 // Round constants. Static table for when we haven't got floating point support
76 #if ! CFG_TOYBOX_FLOAT
77 static const unsigned md5nofloat[64] = {
78   0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, 0xf57c0faf, 0x4787c62a,
79   0xa8304613, 0xfd469501, 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
80   0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, 0xf61e2562, 0xc040b340,
81   0x265e5a51, 0xe9b6c7aa, 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8,
82   0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, 0xa9e3e905, 0xfcefa3f8,
83   0x676f02d9, 0x8d2a4c8a, 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c,
84   0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, 0x289b7ec6, 0xeaa127fa,
85   0xd4ef3085, 0x04881d05, 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
86   0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, 0x655b59c3, 0x8f0ccc92,
87   0xffeff47d, 0x85845dd1, 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
88   0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391
89 };
90 #else
91 #define md5nofloat 0
92 #endif
93 static unsigned long long sha512nofloat[80] = {
94   // we cannot calculate these 64-bit values using the readily
95   // available floating point data types and math functions,
96   // so we always use this lookup table (80 * 8 bytes)
97   0x428a2f98d728ae22, 0x7137449123ef65cd, 0xb5c0fbcfec4d3b2f,
98   0xe9b5dba58189dbbc, 0x3956c25bf348b538, 0x59f111f1b605d019,
99   0x923f82a4af194f9b, 0xab1c5ed5da6d8118, 0xd807aa98a3030242,
100   0x12835b0145706fbe, 0x243185be4ee4b28c, 0x550c7dc3d5ffb4e2,
101   0x72be5d74f27b896f, 0x80deb1fe3b1696b1, 0x9bdc06a725c71235,
102   0xc19bf174cf692694, 0xe49b69c19ef14ad2, 0xefbe4786384f25e3,
103   0x0fc19dc68b8cd5b5, 0x240ca1cc77ac9c65, 0x2de92c6f592b0275,
104   0x4a7484aa6ea6e483, 0x5cb0a9dcbd41fbd4, 0x76f988da831153b5,
105   0x983e5152ee66dfab, 0xa831c66d2db43210, 0xb00327c898fb213f,
106   0xbf597fc7beef0ee4, 0xc6e00bf33da88fc2, 0xd5a79147930aa725,
107   0x06ca6351e003826f, 0x142929670a0e6e70, 0x27b70a8546d22ffc,
108   0x2e1b21385c26c926, 0x4d2c6dfc5ac42aed, 0x53380d139d95b3df,
109   0x650a73548baf63de, 0x766a0abb3c77b2a8, 0x81c2c92e47edaee6,
110   0x92722c851482353b, 0xa2bfe8a14cf10364, 0xa81a664bbc423001,
111   0xc24b8b70d0f89791, 0xc76c51a30654be30, 0xd192e819d6ef5218,
112   0xd69906245565a910, 0xf40e35855771202a, 0x106aa07032bbd1b8,
113   0x19a4c116b8d2d0c8, 0x1e376c085141ab53, 0x2748774cdf8eeb99,
114   0x34b0bcb5e19b48a8, 0x391c0cb3c5c95a63, 0x4ed8aa4ae3418acb,
115   0x5b9cca4f7763e373, 0x682e6ff3d6b2b8a3, 0x748f82ee5defb2fc,
116   0x78a5636f43172f60, 0x84c87814a1f0ab72, 0x8cc702081a6439ec,
117   0x90befffa23631e28, 0xa4506cebde82bde9, 0xbef9a3f7b2c67915,
118   0xc67178f2e372532b, 0xca273eceea26619c, 0xd186b8c721c0c207,
119   0xeada7dd6cde0eb1e, 0xf57d4f7fee6ed178, 0x06f067aa72176fba,
120   0x0a637dc5a2c898a6, 0x113f9804bef90dae, 0x1b710b35131c471b,
121   0x28db77f523047d84, 0x32caab7b40c72493, 0x3c9ebe0a15c9bebc,
122   0x431d67c49c100d4c, 0x4cc5d4becb3e42b6, 0x597f299cfc657e2a,
123   0x5fcb6fab3ad6faec, 0x6c44198c4a475817
124 };
125 // sha1 needs only 4 round constant values, so prefer precomputed
126 static const unsigned sha1rconsts[] = {
127   0x5A827999, 0x6ED9EBA1, 0x8F1BBCDC, 0xCA62C1D6
128 };
129 
130 // bit rotations
131 #define rol(value, bits) (((value)<<(bits))|((value)>>(sizeof(value)*8-(bits))))
132 #define ror(value, bits) (((value)>>(bits))|((value)<<(sizeof(value)*8-(bits))))
133 
134 // Mix next 64 bytes of data into md5 hash
135 
md5_transform(struct browns * hash)136 static void md5_transform(struct browns *hash)
137 {
138   unsigned x[4], *b = hash->buffer.i32;
139   int i;
140 
141   for (i = 0; i<4; i++) x[i] = hash->state.i32[i];
142   for (i = 0; i<64; i++) {
143     unsigned in, a, rot, temp;
144 
145     a = (-i)&3;
146     if (i<16) {
147       in = i;
148       rot = 7+(5*(i&3));
149       temp = x[(a+1)&3];
150       temp = (temp & x[(a+2)&3]) | ((~temp) & x[(a+3)&3]);
151     } else if (i<32) {
152       in = (1+(5*i))&15;
153       temp = (i&3)+1;
154       rot = temp*5;
155       if (temp&2) rot--;
156       temp = x[(a+3)&3];
157       temp = (x[(a+1)&3] & temp) | (x[(a+2)&3] & ~temp);
158     } else if (i<48) {
159       in = (5+(3*(i&15)))&15;
160       rot = i&3;
161       rot = 4+(5*rot)+((rot+1)&6);
162       temp = x[(a+1)&3] ^ x[(a+2)&3] ^ x[(a+3)&3];
163     } else {
164       in = (7*(i&15))&15;
165       rot = (i&3)+1;
166       rot = (5*rot)+(((rot+2)&2)>>1);
167       temp = x[(a+2)&3] ^ (x[(a+1)&3] | ~x[(a+3)&3]);
168     }
169     temp += x[a] + SWAP_LE32(b[in]) + hash->rconsttable32[i];
170     x[a] = x[(a+1)&3] + ((temp<<rot) | (temp>>(32-rot)));
171   }
172   for (i = 0; i<4; i++) hash->state.i32[i] += x[i];
173 }
174 
175 // Mix next 64 bytes of data into sha1 hash.
176 
sha1_transform(struct browns * hash)177 static void sha1_transform(struct browns *hash)
178 {
179   int i, j, k, count;
180   unsigned *block = hash->buffer.i32, oldstate[5], *rot[5], *temp, work;
181 
182   // Copy context->state.i32[] to working vars
183   for (i = 0; i<5; i++) {
184     oldstate[i] = hash->state.i32[i];
185     rot[i] = hash->state.i32 + i;
186   }
187   if (IS_BIG_ENDIAN) for (i = 0; i<16; i++) block[i] = SWAP_LE32(block[i]);
188 
189   // 4 rounds of 20 operations each.
190   for (i = count = 0; i<4; i++) {
191     for (j = 0; j<20; j++) {
192       work = *rot[2] ^ *rot[3];
193       if (!i) work = (work & *rot[1]) ^ *rot[3];
194       else {
195         if (i==2) work = ((*rot[1]|*rot[2])&*rot[3])|(*rot[1]&*rot[2]);
196         else work ^= *rot[1];
197       }
198 
199       if (!i && j<16)
200         work += block[count] = (ror(block[count],8)&0xFF00FF00)
201                              | (rol(block[count],8)&0x00FF00FF);
202       else
203         work += block[count&15] = rol(block[(count+13)&15]
204               ^ block[(count+8)&15] ^ block[(count+2)&15] ^ block[count&15], 1);
205       *rot[4] += work + rol(*rot[0],5) + sha1rconsts[i];
206       *rot[1] = rol(*rot[1],30);
207 
208       // Rotate by one for next time.
209       temp = rot[4];
210       for (k = 4; k; k--) rot[k] = rot[k-1];
211       *rot = temp;
212       count++;
213     }
214   }
215   // Add the previous values of state.i32[]
216   for (i = 0; i<5; i++) hash->state.i32[i] += oldstate[i];
217 }
218 
sha2_32_transform(struct browns * hash)219 static void sha2_32_transform(struct browns *hash)
220 {
221   unsigned block[64], s0, s1, S0, S1, ch, maj, temp1, temp2, rot[8];
222   int i;
223 
224   for (i = 0; i<16; i++) block[i] = SWAP_BE32(hash->buffer.i32[i]);
225 
226   // Extend the message schedule array beyond first 16 words
227   for (i = 16; i<64; i++) {
228     s0 = ror(block[i-15], 7) ^ ror(block[i-15], 18) ^ (block[i-15] >> 3);
229     s1 = ror(block[i-2], 17) ^ ror(block[i-2], 19) ^ (block[i-2] >> 10);
230     block[i] = block[i-16] + s0 + block[i-7] + s1;
231   }
232   // Copy context->state.i32[] to working vars
233   for (i = 0; i<8; i++) rot[i] = hash->state.i32[i];
234   // 64 rounds
235   for (i = 0; i<64; i++) {
236     S1 = ror(rot[4],6) ^ ror(rot[4],11) ^ ror(rot[4], 25);
237     ch = (rot[4] & rot[5]) ^ ((~ rot[4]) & rot[6]);
238     temp1 = rot[7] + S1 + ch + hash->rconsttable32[i] + block[i];
239     S0 = ror(rot[0],2) ^ ror(rot[0],13) ^ ror(rot[0], 22);
240     maj = (rot[0] & rot[1]) ^ (rot[0] & rot[2]) ^ (rot[1] & rot[2]);
241     temp2 = S0 + maj;
242     memmove(rot+1, rot, 7*sizeof(*rot));
243     rot[4] += temp1;
244     rot[0] = temp1 + temp2;
245   }
246 
247   // Add the previous values of state.i32[]
248   for (i = 0; i<8; i++) hash->state.i32[i] += rot[i];
249 }
250 
sha2_64_transform(struct browns * hash)251 static void sha2_64_transform(struct browns *hash)
252 {
253   unsigned long long block[80], s0, s1, S0, S1, ch, maj, temp1, temp2, rot[8];
254   int i;
255 
256   for (i=0; i<16; i++) block[i] = SWAP_BE64(hash->buffer.i64[i]);
257 
258   // Extend the message schedule array beyond first 16 words
259   for (i = 16; i<80; i++) {
260     s0 = ror(block[i-15], 1) ^ ror(block[i-15], 8) ^ (block[i-15] >> 7);
261     s1 = ror(block[i-2], 19) ^ ror(block[i-2], 61) ^ (block[i-2] >> 6);
262     block[i] = block[i-16] + s0 + block[i-7] + s1;
263   }
264   // Copy context->state.i64[] to working vars
265   for (i = 0; i<8; i++) rot[i] = hash->state.i64[i];
266   // 80 rounds
267   for (i = 0; i<80; i++) {
268     S1 = ror(rot[4],14) ^ ror(rot[4],18) ^ ror(rot[4], 41);
269     ch = (rot[4] & rot[5]) ^ ((~ rot[4]) & rot[6]);
270     temp1 = rot[7] + S1 + ch + hash->rconsttable64[i] + block[i];
271     S0 = ror(rot[0],28) ^ ror(rot[0],34) ^ ror(rot[0], 39);
272     maj = (rot[0] & rot[1]) ^ (rot[0] & rot[2]) ^ (rot[1] & rot[2]);
273     temp2 = S0 + maj;
274     memmove(rot+1, rot, 7*sizeof(*rot));
275     rot[4] += temp1;
276     rot[0] = temp1 + temp2;
277   }
278 
279   // Add the previous values of state.i64[]
280   for (i=0; i<8; i++) hash->state.i64[i] += rot[i];
281 }
282 
283 // Fill 64/128-byte (512/1024-bit) working buffer, call transform() when full.
284 
hash_update(char * data,unsigned int len,void (* transform)(struct browns * hash),int chunksize,struct browns * hash)285 static void hash_update(char *data, unsigned int len,
286   void (*transform)(struct browns *hash), int chunksize, struct browns *hash)
287 {
288   unsigned int i, j;
289 
290   j = hash->count & (chunksize - 1);
291   if (hash->count+len<hash->count) hash->overflow++;
292   hash->count += len;
293 
294   for (;;) {
295     // Grab next chunk of data, return if it's not enough to process a frame
296     i = chunksize - j;
297     if (i>len) i = len;
298     memcpy(hash->buffer.c+j, data, i);
299     if (j+i != chunksize) break;
300 
301     // Process a frame
302     transform(hash);
303     j=0;
304     data += i;
305     len -= i;
306   }
307 }
308 
hash_by_name(int fd,char * name,char * result)309 void hash_by_name(int fd, char *name, char *result)
310 {
311   unsigned long long count[2];
312   int i, chunksize, digestlen, method;
313   volatile unsigned *pp;
314   void (*transform)(struct browns *hash);
315   struct browns *hash = xzalloc(sizeof(struct browns));
316   char buf;
317 
318   // md5sum, sha1sum, sha224sum, sha256sum, sha384sum, sha512sum
319   method = stridx("us2581", name[4]);
320 
321   // Calculate table if we have floating point. Static version should drop
322   // out at compile time when we don't need it.
323   if (!method) { // MD5
324     if (CFG_TOYBOX_FLOAT) {
325       hash->rconsttable32 = xmalloc(64*4);
326       for (i = 0; i<64; i++) hash->rconsttable32[i] = fabs(sin(i+1))*(1LL<<32);
327     } else hash->rconsttable32 = (void *)md5nofloat;
328   } else if (name[3] == '2') { // sha224, sha256
329     hash->rconsttable32 = xmalloc(64*4);
330     for (i=0; i<64; i++) hash->rconsttable32[i] = sha512nofloat[i] >> 32;
331   } else hash->rconsttable64 = sha512nofloat; // sha384, sha512
332 
333   // select hash type
334   transform = (void *[]){md5_transform, sha1_transform, sha2_32_transform,
335     sha2_32_transform, sha2_64_transform, sha2_64_transform}[method];
336   digestlen = (char []){16, 20, 28, 32, 48, 64}[method];
337   chunksize = 64<<(method>=4);
338   if (method<=1)
339     memcpy(hash->state.i32, (unsigned []){0x67452301, 0xEFCDAB89, 0x98BADCFE,
340       0x10325476, 0xC3D2E1F0}, 20);
341   else if (method==2)
342     memcpy(hash->state.i32, (unsigned []){0xc1059ed8, 0x367cd507, 0x3070dd17,
343       0xf70e5939, 0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4}, 32);
344   else if (method==3)
345     memcpy(hash->state.i32, (unsigned []){0x6a09e667, 0xbb67ae85, 0x3c6ef372,
346       0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19}, 32);
347   else if (method==4)
348     memcpy(hash->state.i64, (unsigned long long []){0xcbbb9d5dc1059ed8,
349       0x629a292a367cd507, 0x9159015a3070dd17, 0x152fecd8f70e5939,
350       0x67332667ffc00b31, 0x8eb44a8768581511, 0xdb0c2e0d64f98fa7,
351       0x47b5481dbefa4fa4}, 64);
352   else memcpy(hash->state.i64, (unsigned long long []){0x6a09e667f3bcc908,
353       0xbb67ae8584caa73b, 0x3c6ef372fe94f82b, 0xa54ff53a5f1d36f1,
354       0x510e527fade682d1, 0x9b05688c2b3e6c1f, 0x1f83d9abfb41bd6b,
355       0x5be0cd19137e2179}, 64);
356 
357   hash->count = 0;
358   for (;;) {
359     i = read(fd, libbuf, sizeof(libbuf));
360     if (i<1) break;
361     hash_update(libbuf, i, transform, chunksize, hash);
362   }
363 
364   // End the message by appending a "1" bit to the data, ending with the
365   // message size (in bits, big endian), and adding enough zero bits in
366   // between to pad to the end of the next frame.
367   //
368   // Since our input up to now has been in whole bytes, we can deal with
369   // bytes here too. sha384 and 512 use 128 bit counter, so track overflow.
370   buf = 0x80;
371   count[0] = (hash->overflow<<3)+(hash->count>>61);
372   count[1] = hash->count<<3; // convert to bits
373   for (i = 0; i<2; i++)
374     count[i] = !method ? SWAP_LE64(count[i]) : SWAP_BE64(count[i]);
375   i = 8<<(method>=4);
376   do {
377     hash_update(&buf, 1, transform, chunksize, hash);
378     buf = 0;
379   } while ((hash->count&(chunksize-1)) != chunksize-i);
380   hash_update((void *)(count+(method<4)), i, transform, chunksize, hash);
381 
382   // write digest to result
383   if (method>=4) for (i=0; i<digestlen/8; i++)
384     result += sprintf(result, "%016llx", hash->state.i64[i]);
385   else for (i=0; i<digestlen/4; i++)
386     result += sprintf(result, "%08x",
387             !method ? bswap_32(hash->state.i32[i]) : hash->state.i32[i]);
388   // Wipe variables. Cryptographer paranoia. Avoid "optimizing" out memset
389   // by looping on a volatile pointer.
390   for (pp = (void *)hash; pp-(unsigned *)hash<sizeof(*hash)/4; pp++) *pp = 0;
391   for (pp = (void *)libbuf; pp-(unsigned *)libbuf<sizeof(libbuf)/4; pp++)
392     *pp = 0;
393 }
394 #endif
395