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