OLD | NEW |
1 /* SHA-256 and SHA-512 implementation based on code by Oliver Gay | 1 /* SHA-256 and SHA-512 implementation based on code by Oliver Gay |
2 * <olivier.gay@a3.epfl.ch> under a BSD-style license. See below. | 2 * <olivier.gay@a3.epfl.ch> under a BSD-style license. See below. |
3 */ | 3 */ |
4 | 4 |
5 /* | 5 /* |
6 * FIPS 180-2 SHA-224/256/384/512 implementation | 6 * FIPS 180-2 SHA-224/256/384/512 implementation |
7 * Last update: 02/02/2007 | 7 * Last update: 02/02/2007 |
8 * Issue date: 04/30/2005 | 8 * Issue date: 04/30/2005 |
9 * | 9 * |
10 * Copyright (C) 2005, 2007 Olivier Gay <olivier.gay@a3.epfl.ch> | 10 * Copyright (C) 2005, 2007 Olivier Gay <olivier.gay@a3.epfl.ch> |
(...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
325 ctx->h[0] += wv[0]; ctx->h[1] += wv[1]; | 325 ctx->h[0] += wv[0]; ctx->h[1] += wv[1]; |
326 ctx->h[2] += wv[2]; ctx->h[3] += wv[3]; | 326 ctx->h[2] += wv[2]; ctx->h[3] += wv[3]; |
327 ctx->h[4] += wv[4]; ctx->h[5] += wv[5]; | 327 ctx->h[4] += wv[4]; ctx->h[5] += wv[5]; |
328 ctx->h[6] += wv[6]; ctx->h[7] += wv[7]; | 328 ctx->h[6] += wv[6]; ctx->h[7] += wv[7]; |
329 #endif /* !UNROLL_LOOPS */ | 329 #endif /* !UNROLL_LOOPS */ |
330 } | 330 } |
331 } | 331 } |
332 | 332 |
333 | 333 |
334 | 334 |
335 void SHA256_update(SHA256_CTX* ctx, const uint8_t* data, uint32_t len) { | 335 void SHA256_update(SHA256_CTX* ctx, const uint8_t* data, uint64_t len) { |
336 unsigned int block_nb; | 336 unsigned int block_nb; |
337 unsigned int new_len, rem_len, tmp_len; | 337 unsigned int new_len, rem_len, tmp_len; |
338 const uint8_t *shifted_data; | 338 const uint8_t *shifted_data; |
339 | 339 |
340 tmp_len = SHA256_BLOCK_SIZE - ctx->len; | 340 tmp_len = SHA256_BLOCK_SIZE - ctx->len; |
341 rem_len = len < tmp_len ? len : tmp_len; | 341 rem_len = len < tmp_len ? (unsigned int)len : tmp_len; |
342 | 342 |
343 Memcpy(&ctx->block[ctx->len], data, rem_len); | 343 Memcpy(&ctx->block[ctx->len], data, rem_len); |
344 | 344 |
345 if (ctx->len + len < SHA256_BLOCK_SIZE) { | 345 if (ctx->len + len < SHA256_BLOCK_SIZE) { |
346 ctx->len += len; | 346 ctx->len += (uint32_t)len; |
347 return; | 347 return; |
348 } | 348 } |
349 | 349 |
350 new_len = len - rem_len; | 350 new_len = (unsigned int)len - rem_len; |
351 block_nb = new_len / SHA256_BLOCK_SIZE; | 351 block_nb = new_len / SHA256_BLOCK_SIZE; |
352 | 352 |
353 shifted_data = data + rem_len; | 353 shifted_data = data + rem_len; |
354 | 354 |
355 SHA256_transform(ctx, ctx->block, 1); | 355 SHA256_transform(ctx, ctx->block, 1); |
356 SHA256_transform(ctx, shifted_data, block_nb); | 356 SHA256_transform(ctx, shifted_data, block_nb); |
357 | 357 |
358 rem_len = new_len % SHA256_BLOCK_SIZE; | 358 rem_len = new_len % SHA256_BLOCK_SIZE; |
359 | 359 |
360 Memcpy(ctx->block, &shifted_data[block_nb << 6], | 360 Memcpy(ctx->block, &shifted_data[block_nb << 6], |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
417 ctx->h[4] = sha512_h0[4]; ctx->h[5] = sha512_h0[5]; | 417 ctx->h[4] = sha512_h0[4]; ctx->h[5] = sha512_h0[5]; |
418 ctx->h[6] = sha512_h0[6]; ctx->h[7] = sha512_h0[7]; | 418 ctx->h[6] = sha512_h0[6]; ctx->h[7] = sha512_h0[7]; |
419 #endif /* !UNROLL_LOOPS */ | 419 #endif /* !UNROLL_LOOPS */ |
420 | 420 |
421 ctx->len = 0; | 421 ctx->len = 0; |
422 ctx->tot_len = 0; | 422 ctx->tot_len = 0; |
423 } | 423 } |
424 | 424 |
425 | 425 |
426 static void SHA512_transform(SHA512_CTX* ctx, const uint8_t* message, | 426 static void SHA512_transform(SHA512_CTX* ctx, const uint8_t* message, |
427 unsigned int block_nb) { | 427 unsigned int block_nb) |
| 428 { |
428 uint64_t w[80]; | 429 uint64_t w[80]; |
429 uint64_t wv[8]; | 430 uint64_t wv[8]; |
430 uint64_t t1, t2; | 431 uint64_t t1, t2; |
431 const uint8_t *sub_block; | 432 const uint8_t *sub_block; |
432 int i, j; | 433 int i, j; |
433 | 434 |
434 for (i = 0; i < (int) block_nb; i++) { | 435 for (i = 0; i < (int) block_nb; i++) { |
435 sub_block = message + (i << 7); | 436 sub_block = message + (i << 7); |
436 | 437 |
437 #ifndef UNROLL_LOOPS | 438 #ifndef UNROLL_LOOPS |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
512 ctx->h[0] += wv[0]; ctx->h[1] += wv[1]; | 513 ctx->h[0] += wv[0]; ctx->h[1] += wv[1]; |
513 ctx->h[2] += wv[2]; ctx->h[3] += wv[3]; | 514 ctx->h[2] += wv[2]; ctx->h[3] += wv[3]; |
514 ctx->h[4] += wv[4]; ctx->h[5] += wv[5]; | 515 ctx->h[4] += wv[4]; ctx->h[5] += wv[5]; |
515 ctx->h[6] += wv[6]; ctx->h[7] += wv[7]; | 516 ctx->h[6] += wv[6]; ctx->h[7] += wv[7]; |
516 #endif /* !UNROLL_LOOPS */ | 517 #endif /* !UNROLL_LOOPS */ |
517 } | 518 } |
518 } | 519 } |
519 | 520 |
520 | 521 |
521 void SHA512_update(SHA512_CTX* ctx, const uint8_t* data, | 522 void SHA512_update(SHA512_CTX* ctx, const uint8_t* data, |
522 uint32_t len) { | 523 uint64_t len) { |
523 unsigned int block_nb; | 524 unsigned int block_nb; |
524 unsigned int new_len, rem_len, tmp_len; | 525 unsigned int new_len, rem_len, tmp_len; |
525 const uint8_t* shifted_data; | 526 const uint8_t* shifted_data; |
526 | 527 |
527 tmp_len = SHA512_BLOCK_SIZE - ctx->len; | 528 tmp_len = SHA512_BLOCK_SIZE - ctx->len; |
528 rem_len = len < tmp_len ? len : tmp_len; | 529 rem_len = len < tmp_len ? (unsigned int)len : tmp_len; |
529 | 530 |
530 Memcpy(&ctx->block[ctx->len], data, rem_len); | 531 Memcpy(&ctx->block[ctx->len], data, rem_len); |
531 | 532 |
532 if (ctx->len + len < SHA512_BLOCK_SIZE) { | 533 if (ctx->len + len < SHA512_BLOCK_SIZE) { |
533 ctx->len += len; | 534 ctx->len += (uint32_t)len; |
534 return; | 535 return; |
535 } | 536 } |
536 | 537 |
537 new_len = len - rem_len; | 538 new_len = (unsigned int)len - rem_len; |
538 block_nb = new_len / SHA512_BLOCK_SIZE; | 539 block_nb = new_len / SHA512_BLOCK_SIZE; |
539 | 540 |
540 shifted_data = data + rem_len; | 541 shifted_data = data + rem_len; |
541 | 542 |
542 SHA512_transform(ctx, ctx->block, 1); | 543 SHA512_transform(ctx, ctx->block, 1); |
543 SHA512_transform(ctx, shifted_data, block_nb); | 544 SHA512_transform(ctx, shifted_data, block_nb); |
544 | 545 |
545 rem_len = new_len % SHA512_BLOCK_SIZE; | 546 rem_len = new_len % SHA512_BLOCK_SIZE; |
546 | 547 |
547 Memcpy(ctx->block, &shifted_data[block_nb << 7], | 548 Memcpy(ctx->block, &shifted_data[block_nb << 7], |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
585 UNPACK64(ctx->h[4], &ctx->buf[32]); | 586 UNPACK64(ctx->h[4], &ctx->buf[32]); |
586 UNPACK64(ctx->h[5], &ctx->buf[40]); | 587 UNPACK64(ctx->h[5], &ctx->buf[40]); |
587 UNPACK64(ctx->h[6], &ctx->buf[48]); | 588 UNPACK64(ctx->h[6], &ctx->buf[48]); |
588 UNPACK64(ctx->h[7], &ctx->buf[56]); | 589 UNPACK64(ctx->h[7], &ctx->buf[56]); |
589 #endif /* !UNROLL_LOOPS */ | 590 #endif /* !UNROLL_LOOPS */ |
590 | 591 |
591 return ctx->buf; | 592 return ctx->buf; |
592 } | 593 } |
593 | 594 |
594 | 595 |
| 596 |
| 597 /* Convenient functions. */ |
595 uint8_t* SHA256(const uint8_t* data, uint64_t len, uint8_t* digest) { | 598 uint8_t* SHA256(const uint8_t* data, uint64_t len, uint8_t* digest) { |
596 const uint8_t* input_ptr; | 599 const uint8_t* p; |
597 const uint8_t* result; | |
598 uint64_t remaining_len; | |
599 int i; | 600 int i; |
600 SHA256_CTX ctx; | 601 SHA256_CTX ctx; |
601 | |
602 SHA256_init(&ctx); | 602 SHA256_init(&ctx); |
603 | 603 SHA256_update(&ctx, data, len); |
604 input_ptr = data; | 604 p = SHA256_final(&ctx); |
605 remaining_len = len; | |
606 | |
607 /* Process data in at most UINT32_MAX byte chunks at a time. */ | |
608 while (remaining_len) { | |
609 uint32_t block_size; | |
610 block_size = (uint32_t) ((remaining_len >= UINT32_MAX) ? | |
611 UINT32_MAX : remaining_len); | |
612 SHA256_update(&ctx, input_ptr, block_size); | |
613 remaining_len -= block_size; | |
614 input_ptr += block_size; | |
615 } | |
616 | |
617 result = SHA256_final(&ctx); | |
618 for (i = 0; i < SHA256_DIGEST_SIZE; ++i) { | 605 for (i = 0; i < SHA256_DIGEST_SIZE; ++i) { |
619 digest[i] = *result++; | 606 digest[i] = *p++; |
620 } | 607 } |
621 return digest; | 608 return digest; |
622 } | 609 } |
623 | 610 |
624 | 611 |
625 uint8_t* SHA512(const uint8_t* data, uint64_t len, uint8_t* digest) { | 612 uint8_t* SHA512(const uint8_t* data, uint64_t len, uint8_t* digest) { |
626 const uint8_t* input_ptr; | 613 const uint8_t* p; |
627 const uint8_t* result; | |
628 uint64_t remaining_len; | |
629 int i; | 614 int i; |
630 SHA512_CTX ctx; | 615 SHA512_CTX ctx; |
631 SHA512_init(&ctx); | 616 SHA512_init(&ctx); |
632 | 617 SHA512_update(&ctx, data, len); |
633 input_ptr = data; | 618 p = SHA512_final(&ctx); |
634 remaining_len = len; | |
635 | |
636 /* Process data in at most UINT32_MAX byte chunks at a time. */ | |
637 while (remaining_len) { | |
638 uint32_t block_size; | |
639 block_size = (uint32_t) ((remaining_len >= UINT32_MAX) ? | |
640 UINT32_MAX : remaining_len); | |
641 SHA512_update(&ctx, input_ptr, block_size); | |
642 remaining_len -= block_size; | |
643 input_ptr += block_size; | |
644 } | |
645 | |
646 result = SHA512_final(&ctx); | |
647 for (i = 0; i < SHA512_DIGEST_SIZE; ++i) { | 619 for (i = 0; i < SHA512_DIGEST_SIZE; ++i) { |
648 digest[i] = *result++; | 620 digest[i] = *p++; |
649 } | 621 } |
650 return digest; | 622 return digest; |
651 } | 623 } |
OLD | NEW |