aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/libbb.h15
-rw-r--r--libbb/sha1.c290
2 files changed, 94 insertions, 211 deletions
diff --git a/include/libbb.h b/include/libbb.h
index b04488a54..b6eab6f24 100644
--- a/include/libbb.h
+++ b/include/libbb.h
@@ -1321,24 +1321,21 @@ extern const char bb_uuenc_tbl_std[];
1321void bb_uuencode(char *store, const void *s, int length, const char *tbl) FAST_FUNC; 1321void bb_uuencode(char *store, const void *s, int length, const char *tbl) FAST_FUNC;
1322 1322
1323typedef struct sha1_ctx_t { 1323typedef struct sha1_ctx_t {
1324 uint32_t hash[8]; /* 5, +3 elements for sha256 */
1324 uint64_t total64; 1325 uint64_t total64;
1325 uint8_t wbuffer[64]; /* NB: always correctly aligned for uint64_t */ 1326 uint8_t wbuffer[64]; /* NB: always correctly aligned for uint64_t */
1326 uint32_t hash[5]; 1327 void (*process_block)(struct sha1_ctx_t*);
1327} sha1_ctx_t; 1328} sha1_ctx_t;
1328void sha1_begin(sha1_ctx_t *ctx) FAST_FUNC; 1329void sha1_begin(sha1_ctx_t *ctx) FAST_FUNC;
1329void sha1_hash(const void *data, size_t length, sha1_ctx_t *ctx) FAST_FUNC; 1330void sha1_hash(const void *data, size_t length, sha1_ctx_t *ctx) FAST_FUNC;
1330void sha1_end(void *resbuf, sha1_ctx_t *ctx) FAST_FUNC; 1331void sha1_end(void *resbuf, sha1_ctx_t *ctx) FAST_FUNC;
1331typedef struct sha256_ctx_t { 1332typedef struct sha1_ctx_t sha256_ctx_t;
1332 uint64_t total64;
1333 uint32_t hash[8];
1334 uint8_t wbuffer[64]; /* NB: always correctly aligned for uint64_t */
1335} sha256_ctx_t;
1336void sha256_begin(sha256_ctx_t *ctx) FAST_FUNC; 1333void sha256_begin(sha256_ctx_t *ctx) FAST_FUNC;
1337void sha256_hash(const void *buffer, size_t len, sha256_ctx_t *ctx) FAST_FUNC; 1334#define sha256_hash sha1_hash
1338void sha256_end(void *resbuf, sha256_ctx_t *ctx) FAST_FUNC; 1335#define sha256_end sha1_end
1339typedef struct sha512_ctx_t { 1336typedef struct sha512_ctx_t {
1340 uint64_t total64[2];
1341 uint64_t hash[8]; 1337 uint64_t hash[8];
1338 uint64_t total64[2];
1342 uint8_t wbuffer[128]; /* NB: always correctly aligned for uint64_t */ 1339 uint8_t wbuffer[128]; /* NB: always correctly aligned for uint64_t */
1343} sha512_ctx_t; 1340} sha512_ctx_t;
1344void sha512_begin(sha512_ctx_t *ctx) FAST_FUNC; 1341void sha512_begin(sha512_ctx_t *ctx) FAST_FUNC;
diff --git a/libbb/sha1.c b/libbb/sha1.c
index efdb0f58e..8ecf71a9d 100644
--- a/libbb/sha1.c
+++ b/libbb/sha1.c
@@ -203,9 +203,10 @@ static const uint32_t K512_lo[80] = {
203 203
204/* Process LEN bytes of BUFFER, accumulating context into CTX. 204/* Process LEN bytes of BUFFER, accumulating context into CTX.
205 LEN is rounded _down_ to 64. */ 205 LEN is rounded _down_ to 64. */
206static void sha256_process_block64(const void *buffer, size_t len, sha256_ctx_t *ctx) 206static void sha256_process_block64(sha256_ctx_t *ctx)
207{ 207{
208 const uint32_t *words = buffer; 208 unsigned t;
209 uint32_t W[64];
209 uint32_t a = ctx->hash[0]; 210 uint32_t a = ctx->hash[0];
210 uint32_t b = ctx->hash[1]; 211 uint32_t b = ctx->hash[1];
211 uint32_t c = ctx->hash[2]; 212 uint32_t c = ctx->hash[2];
@@ -214,15 +215,9 @@ static void sha256_process_block64(const void *buffer, size_t len, sha256_ctx_t
214 uint32_t f = ctx->hash[5]; 215 uint32_t f = ctx->hash[5];
215 uint32_t g = ctx->hash[6]; 216 uint32_t g = ctx->hash[6];
216 uint32_t h = ctx->hash[7]; 217 uint32_t h = ctx->hash[7];
218 const uint32_t *words = (uint32_t*) ctx->wbuffer;
217 219
218 /* Process all bytes in the buffer with 64 bytes in each round of 220 /* Operators defined in FIPS 180-2:4.1.2. */
219 the loop. */
220 len /= (sizeof(uint32_t) * 16);
221 while (len) {
222 unsigned t;
223 uint32_t W[64];
224
225 /* Operators defined in FIPS 180-2:4.1.2. */
226#define Ch(x, y, z) ((x & y) ^ (~x & z)) 221#define Ch(x, y, z) ((x & y) ^ (~x & z))
227#define Maj(x, y, z) ((x & y) ^ (x & z) ^ (y & z)) 222#define Maj(x, y, z) ((x & y) ^ (x & z) ^ (y & z))
228#define S0(x) (rotr32(x, 2) ^ rotr32(x, 13) ^ rotr32(x, 22)) 223#define S0(x) (rotr32(x, 2) ^ rotr32(x, 13) ^ rotr32(x, 22))
@@ -230,54 +225,51 @@ static void sha256_process_block64(const void *buffer, size_t len, sha256_ctx_t
230#define R0(x) (rotr32(x, 7) ^ rotr32(x, 18) ^ (x >> 3)) 225#define R0(x) (rotr32(x, 7) ^ rotr32(x, 18) ^ (x >> 3))
231#define R1(x) (rotr32(x, 17) ^ rotr32(x, 19) ^ (x >> 10)) 226#define R1(x) (rotr32(x, 17) ^ rotr32(x, 19) ^ (x >> 10))
232 227
233 /* Compute the message schedule according to FIPS 180-2:6.2.2 step 2. */ 228 /* Compute the message schedule according to FIPS 180-2:6.2.2 step 2. */
234 for (t = 0; t < 16; ++t) { 229 for (t = 0; t < 16; ++t) {
235 W[t] = ntohl(*words); 230 W[t] = ntohl(*words);
236 words++; 231 words++;
237 } 232 }
238 233
239 for (/*t = 16*/; t < 64; ++t) 234 for (/*t = 16*/; t < 64; ++t)
240 W[t] = R1(W[t - 2]) + W[t - 7] + R0(W[t - 15]) + W[t - 16]; 235 W[t] = R1(W[t - 2]) + W[t - 7] + R0(W[t - 15]) + W[t - 16];
241 236
242 /* The actual computation according to FIPS 180-2:6.2.2 step 3. */ 237 /* The actual computation according to FIPS 180-2:6.2.2 step 3. */
243 for (t = 0; t < 64; ++t) { 238 for (t = 0; t < 64; ++t) {
244 uint32_t T1 = h + S1(e) + Ch(e, f, g) + K256[t] + W[t]; 239 uint32_t T1 = h + S1(e) + Ch(e, f, g) + K256[t] + W[t];
245 uint32_t T2 = S0(a) + Maj(a, b, c); 240 uint32_t T2 = S0(a) + Maj(a, b, c);
246 h = g; 241 h = g;
247 g = f; 242 g = f;
248 f = e; 243 f = e;
249 e = d + T1; 244 e = d + T1;
250 d = c; 245 d = c;
251 c = b; 246 c = b;
252 b = a; 247 b = a;
253 a = T1 + T2; 248 a = T1 + T2;
254 } 249 }
255#undef Ch 250#undef Ch
256#undef Maj 251#undef Maj
257#undef S0 252#undef S0
258#undef S1 253#undef S1
259#undef R0 254#undef R0
260#undef R1 255#undef R1
261 /* Add the starting values of the context according to FIPS 180-2:6.2.2 256 /* Add the starting values of the context according to FIPS 180-2:6.2.2
262 step 4. */ 257 step 4. */
263 ctx->hash[0] = a += ctx->hash[0]; 258 ctx->hash[0] += a;
264 ctx->hash[1] = b += ctx->hash[1]; 259 ctx->hash[1] += b;
265 ctx->hash[2] = c += ctx->hash[2]; 260 ctx->hash[2] += c;
266 ctx->hash[3] = d += ctx->hash[3]; 261 ctx->hash[3] += d;
267 ctx->hash[4] = e += ctx->hash[4]; 262 ctx->hash[4] += e;
268 ctx->hash[5] = f += ctx->hash[5]; 263 ctx->hash[5] += f;
269 ctx->hash[6] = g += ctx->hash[6]; 264 ctx->hash[6] += g;
270 ctx->hash[7] = h += ctx->hash[7]; 265 ctx->hash[7] += h;
271
272 /* Prepare for the next round. */
273 len--;
274 }
275} 266}
276/* Process LEN bytes of BUFFER, accumulating context into CTX. 267/* Process LEN bytes of BUFFER, accumulating context into CTX.
277 LEN is rounded _down_ to 128. */ 268 LEN is rounded _down_ to 128. */
278static void sha512_process_block128(const void *buffer, size_t len, sha512_ctx_t *ctx) 269static void sha512_process_block128(sha512_ctx_t *ctx)
279{ 270{
280 const uint64_t *words = buffer; 271 unsigned t;
272 uint64_t W[80];
281 uint64_t a = ctx->hash[0]; 273 uint64_t a = ctx->hash[0];
282 uint64_t b = ctx->hash[1]; 274 uint64_t b = ctx->hash[1];
283 uint64_t c = ctx->hash[2]; 275 uint64_t c = ctx->hash[2];
@@ -286,13 +278,9 @@ static void sha512_process_block128(const void *buffer, size_t len, sha512_ctx_t
286 uint64_t f = ctx->hash[5]; 278 uint64_t f = ctx->hash[5];
287 uint64_t g = ctx->hash[6]; 279 uint64_t g = ctx->hash[6];
288 uint64_t h = ctx->hash[7]; 280 uint64_t h = ctx->hash[7];
281 const uint32_t *words = (uint32_t*) ctx->wbuffer;
289 282
290 len /= (sizeof(uint64_t) * 16); 283 /* Operators defined in FIPS 180-2:4.1.2. */
291 while (len) {
292 unsigned t;
293 uint64_t W[80];
294
295 /* Operators defined in FIPS 180-2:4.1.2. */
296#define Ch(x, y, z) ((x & y) ^ (~x & z)) 284#define Ch(x, y, z) ((x & y) ^ (~x & z))
297#define Maj(x, y, z) ((x & y) ^ (x & z) ^ (y & z)) 285#define Maj(x, y, z) ((x & y) ^ (x & z) ^ (y & z))
298#define S0(x) (rotr64(x, 28) ^ rotr64(x, 34) ^ rotr64(x, 39)) 286#define S0(x) (rotr64(x, 28) ^ rotr64(x, 34) ^ rotr64(x, 39))
@@ -300,58 +288,56 @@ static void sha512_process_block128(const void *buffer, size_t len, sha512_ctx_t
300#define R0(x) (rotr64(x, 1) ^ rotr64(x, 8) ^ (x >> 7)) 288#define R0(x) (rotr64(x, 1) ^ rotr64(x, 8) ^ (x >> 7))
301#define R1(x) (rotr64(x, 19) ^ rotr64(x, 61) ^ (x >> 6)) 289#define R1(x) (rotr64(x, 19) ^ rotr64(x, 61) ^ (x >> 6))
302 290
303 /* Compute the message schedule according to FIPS 180-2:6.3.2 step 2. */ 291 /* Compute the message schedule according to FIPS 180-2:6.3.2 step 2. */
304 for (t = 0; t < 16; ++t) { 292 for (t = 0; t < 16; ++t) {
305 W[t] = ntoh64(*words); 293 W[t] = ntoh64(*words);
306 words++; 294 words++;
307 } 295 }
308 for (/*t = 16*/; t < 80; ++t) 296 for (/*t = 16*/; t < 80; ++t)
309 W[t] = R1(W[t - 2]) + W[t - 7] + R0(W[t - 15]) + W[t - 16]; 297 W[t] = R1(W[t - 2]) + W[t - 7] + R0(W[t - 15]) + W[t - 16];
310 298
311 /* The actual computation according to FIPS 180-2:6.3.2 step 3. */ 299 /* The actual computation according to FIPS 180-2:6.3.2 step 3. */
312 for (t = 0; t < 80; ++t) { 300 for (t = 0; t < 80; ++t) {
313 uint64_t K512_t = ((uint64_t)(K256[t]) << 32) + K512_lo[t]; 301 uint64_t K512_t = ((uint64_t)(K256[t]) << 32) + K512_lo[t];
314 uint64_t T1 = h + S1(e) + Ch(e, f, g) + K512_t + W[t]; 302 uint64_t T1 = h + S1(e) + Ch(e, f, g) + K512_t + W[t];
315 uint64_t T2 = S0(a) + Maj(a, b, c); 303 uint64_t T2 = S0(a) + Maj(a, b, c);
316 h = g; 304 h = g;
317 g = f; 305 g = f;
318 f = e; 306 f = e;
319 e = d + T1; 307 e = d + T1;
320 d = c; 308 d = c;
321 c = b; 309 c = b;
322 b = a; 310 b = a;
323 a = T1 + T2; 311 a = T1 + T2;
324 } 312 }
325#undef Ch 313#undef Ch
326#undef Maj 314#undef Maj
327#undef S0 315#undef S0
328#undef S1 316#undef S1
329#undef R0 317#undef R0
330#undef R1 318#undef R1
331 /* Add the starting values of the context according to FIPS 180-2:6.3.2 319 /* Add the starting values of the context according to FIPS 180-2:6.3.2
332 step 4. */ 320 step 4. */
333 ctx->hash[0] = a += ctx->hash[0]; 321 ctx->hash[0] += a;
334 ctx->hash[1] = b += ctx->hash[1]; 322 ctx->hash[1] += b;
335 ctx->hash[2] = c += ctx->hash[2]; 323 ctx->hash[2] += c;
336 ctx->hash[3] = d += ctx->hash[3]; 324 ctx->hash[3] += d;
337 ctx->hash[4] = e += ctx->hash[4]; 325 ctx->hash[4] += e;
338 ctx->hash[5] = f += ctx->hash[5]; 326 ctx->hash[5] += f;
339 ctx->hash[6] = g += ctx->hash[6]; 327 ctx->hash[6] += g;
340 ctx->hash[7] = h += ctx->hash[7]; 328 ctx->hash[7] += h;
341
342 len--;
343 }
344} 329}
345 330
346 331
347void FAST_FUNC sha1_begin(sha1_ctx_t *ctx) 332void FAST_FUNC sha1_begin(sha1_ctx_t *ctx)
348{ 333{
349 ctx->total64 = 0;
350 ctx->hash[0] = 0x67452301; 334 ctx->hash[0] = 0x67452301;
351 ctx->hash[1] = 0xefcdab89; 335 ctx->hash[1] = 0xefcdab89;
352 ctx->hash[2] = 0x98badcfe; 336 ctx->hash[2] = 0x98badcfe;
353 ctx->hash[3] = 0x10325476; 337 ctx->hash[3] = 0x10325476;
354 ctx->hash[4] = 0xc3d2e1f0; 338 ctx->hash[4] = 0xc3d2e1f0;
339 ctx->total64 = 0;
340 ctx->process_block = sha1_process_block64;
355} 341}
356 342
357static const uint32_t init256[] = { 343static const uint32_t init256[] = {
@@ -380,6 +366,7 @@ void FAST_FUNC sha256_begin(sha256_ctx_t *ctx)
380{ 366{
381 memcpy(ctx->hash, init256, sizeof(init256)); 367 memcpy(ctx->hash, init256, sizeof(init256));
382 ctx->total64 = 0; 368 ctx->total64 = 0;
369 ctx->process_block = sha256_process_block64;
383} 370}
384/* Initialize structure containing state of computation. 371/* Initialize structure containing state of computation.
385 (FIPS 180-2:5.3.3) */ 372 (FIPS 180-2:5.3.3) */
@@ -405,64 +392,16 @@ void FAST_FUNC sha1_hash(const void *buffer, size_t len, sha1_ctx_t *ctx)
405 len -= add; 392 len -= add;
406 add = SHA1_BLOCK_SIZE; 393 add = SHA1_BLOCK_SIZE;
407 in_buf = 0; 394 in_buf = 0;
408 sha1_process_block64(ctx); 395 ctx->process_block(ctx);
409 } 396 }
410 397
411 memcpy(ctx->wbuffer + in_buf, buffer, len); 398 memcpy(ctx->wbuffer + in_buf, buffer, len);
412} 399}
413 400
414void FAST_FUNC sha256_hash(const void *buffer, size_t len, sha256_ctx_t *ctx)
415{
416 unsigned in_buf = ctx->total64 & 63;
417
418 /* First increment the byte count. FIPS 180-2 specifies the possible
419 length of the file up to 2^64 _bits_.
420 We compute the number of _bytes_ and convert to bits later. */
421 ctx->total64 += len;
422
423 /* When we already have some bits in our internal buffer concatenate
424 both inputs first. */
425 if (in_buf != 0) {
426 unsigned add;
427
428 add = sizeof(ctx->wbuffer) - in_buf;
429 if (add > len)
430 add = len;
431 memcpy(ctx->wbuffer + in_buf, buffer, add);
432 in_buf += add;
433
434 /* If we still didn't collect full wbuffer, bail out */
435 if (in_buf < sizeof(ctx->wbuffer))
436 return;
437
438 sha256_process_block64(ctx->wbuffer, 64, ctx);
439 buffer = (const char *)buffer + add;
440 len -= add;
441 }
442
443 /* Process available complete blocks. */
444 if (len >= 64) {
445 if (UNALIGNED_P(buffer, uint32_t)) {
446 while (len >= 64) {
447 sha256_process_block64(memcpy(ctx->wbuffer, buffer, 64), 64, ctx);
448 buffer = (const char *)buffer + 64;
449 len -= 64;
450 }
451 } else {
452 sha256_process_block64(buffer, len /*& ~63*/, ctx);
453 buffer = (const char *)buffer + (len & ~63);
454 len &= 63;
455 }
456 }
457
458 /* Move remaining bytes into internal buffer. */
459 if (len > 0)
460 memcpy(ctx->wbuffer, buffer, len);
461}
462
463void FAST_FUNC sha512_hash(const void *buffer, size_t len, sha512_ctx_t *ctx) 401void FAST_FUNC sha512_hash(const void *buffer, size_t len, sha512_ctx_t *ctx)
464{ 402{
465 unsigned in_buf = ctx->total64[0] & 127; 403 unsigned in_buf = ctx->total64[0] & 127;
404 unsigned add = 128 - in_buf;
466 405
467 /* First increment the byte count. FIPS 180-2 specifies the possible 406 /* First increment the byte count. FIPS 180-2 specifies the possible
468 length of the file up to 2^128 _bits_. 407 length of the file up to 2^128 _bits_.
@@ -471,39 +410,16 @@ void FAST_FUNC sha512_hash(const void *buffer, size_t len, sha512_ctx_t *ctx)
471 if (ctx->total64[0] < len) 410 if (ctx->total64[0] < len)
472 ctx->total64[1]++; 411 ctx->total64[1]++;
473 412
474 if (in_buf != 0) { 413 while (len >= add) { /* transfer whole blocks while possible */
475 unsigned add;
476
477 add = sizeof(ctx->wbuffer) - in_buf;
478 if (add > len)
479 add = len;
480 memcpy(ctx->wbuffer + in_buf, buffer, add); 414 memcpy(ctx->wbuffer + in_buf, buffer, add);
481 in_buf += add;
482
483 if (in_buf < sizeof(ctx->wbuffer))
484 return;
485
486 sha512_process_block128(ctx->wbuffer, 128, ctx);
487 buffer = (const char *)buffer + add; 415 buffer = (const char *)buffer + add;
488 len -= add; 416 len -= add;
417 add = 128;
418 in_buf = 0;
419 sha512_process_block128(ctx);
489 } 420 }
490 421
491 if (len >= 128) { 422 memcpy(ctx->wbuffer + in_buf, buffer, len);
492 if (UNALIGNED_P(buffer, uint64_t)) {
493 while (len >= 128) {
494 sha512_process_block128(memcpy(ctx->wbuffer, buffer, 128), 128, ctx);
495 buffer = (const char *)buffer + 128;
496 len -= 128;
497 }
498 } else {
499 sha512_process_block128(buffer, len /*& ~127*/, ctx);
500 buffer = (const char *)buffer + (len & ~127);
501 len &= 127;
502 }
503 }
504
505 if (len > 0)
506 memcpy(ctx->wbuffer, buffer, len);
507} 423}
508 424
509 425
@@ -528,48 +444,18 @@ void FAST_FUNC sha1_end(void *resbuf, sha1_ctx_t *ctx)
528 /* wbuffer is suitably aligned for this */ 444 /* wbuffer is suitably aligned for this */
529 *(uint64_t *) (&ctx->wbuffer[SHA1_BLOCK_SIZE - 8]) = t; 445 *(uint64_t *) (&ctx->wbuffer[SHA1_BLOCK_SIZE - 8]) = t;
530 } 446 }
531 sha1_process_block64(ctx); 447 ctx->process_block(ctx);
532 if (pad >= 8) 448 if (pad >= 8)
533 break; 449 break;
534 } 450 }
535 451
452 in_buf = (ctx->process_block == sha1_process_block64) ? 5 : 8;
536 /* This way we do not impose alignment constraints on resbuf: */ 453 /* This way we do not impose alignment constraints on resbuf: */
537#if BB_LITTLE_ENDIAN 454#if BB_LITTLE_ENDIAN
538 for (i = 0; i < ARRAY_SIZE(ctx->hash); ++i) 455 for (i = 0; i < in_buf; ++i)
539 ctx->hash[i] = htonl(ctx->hash[i]);
540#endif
541 memcpy(resbuf, ctx->hash, sizeof(ctx->hash));
542}
543
544void FAST_FUNC sha256_end(void *resbuf, sha256_ctx_t *ctx)
545{
546 unsigned i, pad, in_buf;
547
548 in_buf = ctx->total64 & 63;
549 /* Pad the buffer to the next 64-byte boundary with 0x80,0,0,0...
550 * (FIPS 180-2:5.1.1)
551 */
552 ctx->wbuffer[in_buf++] = 0x80;
553
554 while (1) {
555 pad = 64 - in_buf;
556 memset(ctx->wbuffer + in_buf, 0, pad);
557 in_buf = 0;
558 if (pad >= 8) {
559 uint64_t t = ctx->total64 << 3;
560 t = hton64(t);
561 *(uint64_t *) (&ctx->wbuffer[64 - 8]) = t;
562 }
563 sha256_process_block64(ctx->wbuffer, 64, ctx);
564 if (pad >= 8)
565 break;
566 }
567
568#if BB_LITTLE_ENDIAN
569 for (i = 0; i < ARRAY_SIZE(ctx->hash); ++i)
570 ctx->hash[i] = htonl(ctx->hash[i]); 456 ctx->hash[i] = htonl(ctx->hash[i]);
571#endif 457#endif
572 memcpy(resbuf, ctx->hash, sizeof(ctx->hash)); 458 memcpy(resbuf, ctx->hash, sizeof(ctx->hash[0]) * in_buf);
573} 459}
574 460
575void FAST_FUNC sha512_end(void *resbuf, sha512_ctx_t *ctx) 461void FAST_FUNC sha512_end(void *resbuf, sha512_ctx_t *ctx)
@@ -596,7 +482,7 @@ void FAST_FUNC sha512_end(void *resbuf, sha512_ctx_t *ctx)
596 t = hton64(t); 482 t = hton64(t);
597 *(uint64_t *) (&ctx->wbuffer[128 - 16]) = t; 483 *(uint64_t *) (&ctx->wbuffer[128 - 16]) = t;
598 } 484 }
599 sha512_process_block128(ctx->wbuffer, 128, ctx); 485 sha512_process_block128(ctx);
600 if (pad >= 16) 486 if (pad >= 16)
601 break; 487 break;
602 } 488 }