aboutsummaryrefslogtreecommitdiff
path: root/libbb/hash_sha.c
diff options
context:
space:
mode:
Diffstat (limited to 'libbb/hash_sha.c')
-rw-r--r--libbb/hash_sha.c460
1 files changed, 451 insertions, 9 deletions
diff --git a/libbb/hash_sha.c b/libbb/hash_sha.c
index 72d50928b..3e708ef7e 100644
--- a/libbb/hash_sha.c
+++ b/libbb/hash_sha.c
@@ -53,12 +53,6 @@ static ALWAYS_INLINE uint64_t rotr64(uint64_t x, unsigned n)
53} 53}
54 54
55 55
56/* Some arch headers have conflicting defines */
57#undef ch
58#undef parity
59#undef maj
60#undef rnd
61
62static void FAST_FUNC sha1_process_block64(sha1_ctx_t *ctx) 56static void FAST_FUNC sha1_process_block64(sha1_ctx_t *ctx)
63{ 57{
64 unsigned t; 58 unsigned t;
@@ -78,12 +72,14 @@ static void FAST_FUNC sha1_process_block64(sha1_ctx_t *ctx)
78 d = ctx->hash[3]; 72 d = ctx->hash[3];
79 e = ctx->hash[4]; 73 e = ctx->hash[4];
80 74
81/* Reverse byte order in 32-bit words */ 75#undef ch
76#undef parity
77#undef maj
78#undef rnd
82#define ch(x,y,z) ((z) ^ ((x) & ((y) ^ (z)))) 79#define ch(x,y,z) ((z) ^ ((x) & ((y) ^ (z))))
83#define parity(x,y,z) ((x) ^ (y) ^ (z)) 80#define parity(x,y,z) ((x) ^ (y) ^ (z))
84#define maj(x,y,z) (((x) & (y)) | ((z) & ((x) | (y)))) 81#define maj(x,y,z) (((x) & (y)) | ((z) & ((x) | (y))))
85/* A normal version as set out in the FIPS. This version uses */ 82/* A normal version as set out in the FIPS. */
86/* partial loop unrolling and is optimised for the Pentium 4 */
87#define rnd(f,k) \ 83#define rnd(f,k) \
88 do { \ 84 do { \
89 uint32_t T = a; \ 85 uint32_t T = a; \
@@ -518,3 +514,449 @@ void FAST_FUNC sha512_end(sha512_ctx_t *ctx, void *resbuf)
518 } 514 }
519 memcpy(resbuf, ctx->hash, sizeof(ctx->hash)); 515 memcpy(resbuf, ctx->hash, sizeof(ctx->hash));
520} 516}
517
518
519/*
520 * Compute MD5 checksum of strings according to the
521 * definition of MD5 in RFC 1321 from April 1992.
522 *
523 * Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
524 *
525 * Copyright (C) 1995-1999 Free Software Foundation, Inc.
526 * Copyright (C) 2001 Manuel Novoa III
527 * Copyright (C) 2003 Glenn L. McGrath
528 * Copyright (C) 2003 Erik Andersen
529 *
530 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
531 */
532
533/* 0: fastest, 3: smallest */
534#if CONFIG_MD5_SIZE_VS_SPEED < 0
535# define MD5_SIZE_VS_SPEED 0
536#elif CONFIG_MD5_SIZE_VS_SPEED > 3
537# define MD5_SIZE_VS_SPEED 3
538#else
539# define MD5_SIZE_VS_SPEED CONFIG_MD5_SIZE_VS_SPEED
540#endif
541
542/* Initialize structure containing state of computation.
543 * (RFC 1321, 3.3: Step 3)
544 */
545void FAST_FUNC md5_begin(md5_ctx_t *ctx)
546{
547 ctx->A = 0x67452301;
548 ctx->B = 0xefcdab89;
549 ctx->C = 0x98badcfe;
550 ctx->D = 0x10325476;
551 ctx->total64 = 0;
552}
553
554/* These are the four functions used in the four steps of the MD5 algorithm
555 * and defined in the RFC 1321. The first function is a little bit optimized
556 * (as found in Colin Plumbs public domain implementation).
557 * #define FF(b, c, d) ((b & c) | (~b & d))
558 */
559#undef FF
560#undef FG
561#undef FH
562#undef FI
563#define FF(b, c, d) (d ^ (b & (c ^ d)))
564#define FG(b, c, d) FF(d, b, c)
565#define FH(b, c, d) (b ^ c ^ d)
566#define FI(b, c, d) (c ^ (b | ~d))
567
568/* Hash a single block, 64 bytes long and 4-byte aligned */
569static void md5_process_block64(md5_ctx_t *ctx)
570{
571#if MD5_SIZE_VS_SPEED > 0
572 /* Before we start, one word to the strange constants.
573 They are defined in RFC 1321 as
574 T[i] = (int)(4294967296.0 * fabs(sin(i))), i=1..64
575 */
576 static const uint32_t C_array[] = {
577 /* round 1 */
578 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,
579 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
580 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
581 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,
582 /* round 2 */
583 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa,
584 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8,
585 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed,
586 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,
587 /* round 3 */
588 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c,
589 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
590 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x4881d05,
591 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
592 /* round 4 */
593 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039,
594 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
595 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
596 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391
597 };
598 static const char P_array[] ALIGN1 = {
599# if MD5_SIZE_VS_SPEED > 1
600 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, /* 1 */
601# endif
602 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, /* 2 */
603 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2, /* 3 */
604 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 /* 4 */
605 };
606#endif
607 uint32_t *words = (void*) ctx->wbuffer;
608 uint32_t A = ctx->A;
609 uint32_t B = ctx->B;
610 uint32_t C = ctx->C;
611 uint32_t D = ctx->D;
612
613#if MD5_SIZE_VS_SPEED >= 2 /* 2 or 3 */
614
615 static const char S_array[] ALIGN1 = {
616 7, 12, 17, 22,
617 5, 9, 14, 20,
618 4, 11, 16, 23,
619 6, 10, 15, 21
620 };
621 const uint32_t *pc;
622 const char *pp;
623 const char *ps;
624 int i;
625 uint32_t temp;
626
627# if BB_BIG_ENDIAN
628 for (i = 0; i < 16; i++)
629 words[i] = SWAP_LE32(words[i]);
630# endif
631
632# if MD5_SIZE_VS_SPEED == 3
633 pc = C_array;
634 pp = P_array;
635 ps = S_array - 4;
636
637 for (i = 0; i < 64; i++) {
638 if ((i & 0x0f) == 0)
639 ps += 4;
640 temp = A;
641 switch (i >> 4) {
642 case 0:
643 temp += FF(B, C, D);
644 break;
645 case 1:
646 temp += FG(B, C, D);
647 break;
648 case 2:
649 temp += FH(B, C, D);
650 break;
651 case 3:
652 temp += FI(B, C, D);
653 }
654 temp += words[(int) (*pp++)] + *pc++;
655 temp = rotl32(temp, ps[i & 3]);
656 temp += B;
657 A = D;
658 D = C;
659 C = B;
660 B = temp;
661 }
662# else /* MD5_SIZE_VS_SPEED == 2 */
663 pc = C_array;
664 pp = P_array;
665 ps = S_array;
666
667 for (i = 0; i < 16; i++) {
668 temp = A + FF(B, C, D) + words[(int) (*pp++)] + *pc++;
669 temp = rotl32(temp, ps[i & 3]);
670 temp += B;
671 A = D;
672 D = C;
673 C = B;
674 B = temp;
675 }
676 ps += 4;
677 for (i = 0; i < 16; i++) {
678 temp = A + FG(B, C, D) + words[(int) (*pp++)] + *pc++;
679 temp = rotl32(temp, ps[i & 3]);
680 temp += B;
681 A = D;
682 D = C;
683 C = B;
684 B = temp;
685 }
686 ps += 4;
687 for (i = 0; i < 16; i++) {
688 temp = A + FH(B, C, D) + words[(int) (*pp++)] + *pc++;
689 temp = rotl32(temp, ps[i & 3]);
690 temp += B;
691 A = D;
692 D = C;
693 C = B;
694 B = temp;
695 }
696 ps += 4;
697 for (i = 0; i < 16; i++) {
698 temp = A + FI(B, C, D) + words[(int) (*pp++)] + *pc++;
699 temp = rotl32(temp, ps[i & 3]);
700 temp += B;
701 A = D;
702 D = C;
703 C = B;
704 B = temp;
705 }
706# endif
707 /* Add checksum to the starting values */
708 ctx->A += A;
709 ctx->B += B;
710 ctx->C += C;
711 ctx->D += D;
712
713#else /* MD5_SIZE_VS_SPEED == 0 or 1 */
714
715 uint32_t A_save = A;
716 uint32_t B_save = B;
717 uint32_t C_save = C;
718 uint32_t D_save = D;
719# if MD5_SIZE_VS_SPEED == 1
720 const uint32_t *pc;
721 const char *pp;
722 int i;
723# endif
724
725 /* First round: using the given function, the context and a constant
726 the next context is computed. Because the algorithm's processing
727 unit is a 32-bit word and it is determined to work on words in
728 little endian byte order we perhaps have to change the byte order
729 before the computation. To reduce the work for the next steps
730 we save swapped words in WORDS array. */
731# undef OP
732# define OP(a, b, c, d, s, T) \
733 do { \
734 a += FF(b, c, d) + (*words IF_BIG_ENDIAN(= SWAP_LE32(*words))) + T; \
735 words++; \
736 a = rotl32(a, s); \
737 a += b; \
738 } while (0)
739
740 /* Round 1 */
741# if MD5_SIZE_VS_SPEED == 1
742 pc = C_array;
743 for (i = 0; i < 4; i++) {
744 OP(A, B, C, D, 7, *pc++);
745 OP(D, A, B, C, 12, *pc++);
746 OP(C, D, A, B, 17, *pc++);
747 OP(B, C, D, A, 22, *pc++);
748 }
749# else
750 OP(A, B, C, D, 7, 0xd76aa478);
751 OP(D, A, B, C, 12, 0xe8c7b756);
752 OP(C, D, A, B, 17, 0x242070db);
753 OP(B, C, D, A, 22, 0xc1bdceee);
754 OP(A, B, C, D, 7, 0xf57c0faf);
755 OP(D, A, B, C, 12, 0x4787c62a);
756 OP(C, D, A, B, 17, 0xa8304613);
757 OP(B, C, D, A, 22, 0xfd469501);
758 OP(A, B, C, D, 7, 0x698098d8);
759 OP(D, A, B, C, 12, 0x8b44f7af);
760 OP(C, D, A, B, 17, 0xffff5bb1);
761 OP(B, C, D, A, 22, 0x895cd7be);
762 OP(A, B, C, D, 7, 0x6b901122);
763 OP(D, A, B, C, 12, 0xfd987193);
764 OP(C, D, A, B, 17, 0xa679438e);
765 OP(B, C, D, A, 22, 0x49b40821);
766# endif
767 words -= 16;
768
769 /* For the second to fourth round we have the possibly swapped words
770 in WORDS. Redefine the macro to take an additional first
771 argument specifying the function to use. */
772# undef OP
773# define OP(f, a, b, c, d, k, s, T) \
774 do { \
775 a += f(b, c, d) + words[k] + T; \
776 a = rotl32(a, s); \
777 a += b; \
778 } while (0)
779
780 /* Round 2 */
781# if MD5_SIZE_VS_SPEED == 1
782 pp = P_array;
783 for (i = 0; i < 4; i++) {
784 OP(FG, A, B, C, D, (int) (*pp++), 5, *pc++);
785 OP(FG, D, A, B, C, (int) (*pp++), 9, *pc++);
786 OP(FG, C, D, A, B, (int) (*pp++), 14, *pc++);
787 OP(FG, B, C, D, A, (int) (*pp++), 20, *pc++);
788 }
789# else
790 OP(FG, A, B, C, D, 1, 5, 0xf61e2562);
791 OP(FG, D, A, B, C, 6, 9, 0xc040b340);
792 OP(FG, C, D, A, B, 11, 14, 0x265e5a51);
793 OP(FG, B, C, D, A, 0, 20, 0xe9b6c7aa);
794 OP(FG, A, B, C, D, 5, 5, 0xd62f105d);
795 OP(FG, D, A, B, C, 10, 9, 0x02441453);
796 OP(FG, C, D, A, B, 15, 14, 0xd8a1e681);
797 OP(FG, B, C, D, A, 4, 20, 0xe7d3fbc8);
798 OP(FG, A, B, C, D, 9, 5, 0x21e1cde6);
799 OP(FG, D, A, B, C, 14, 9, 0xc33707d6);
800 OP(FG, C, D, A, B, 3, 14, 0xf4d50d87);
801 OP(FG, B, C, D, A, 8, 20, 0x455a14ed);
802 OP(FG, A, B, C, D, 13, 5, 0xa9e3e905);
803 OP(FG, D, A, B, C, 2, 9, 0xfcefa3f8);
804 OP(FG, C, D, A, B, 7, 14, 0x676f02d9);
805 OP(FG, B, C, D, A, 12, 20, 0x8d2a4c8a);
806# endif
807
808 /* Round 3 */
809# if MD5_SIZE_VS_SPEED == 1
810 for (i = 0; i < 4; i++) {
811 OP(FH, A, B, C, D, (int) (*pp++), 4, *pc++);
812 OP(FH, D, A, B, C, (int) (*pp++), 11, *pc++);
813 OP(FH, C, D, A, B, (int) (*pp++), 16, *pc++);
814 OP(FH, B, C, D, A, (int) (*pp++), 23, *pc++);
815 }
816# else
817 OP(FH, A, B, C, D, 5, 4, 0xfffa3942);
818 OP(FH, D, A, B, C, 8, 11, 0x8771f681);
819 OP(FH, C, D, A, B, 11, 16, 0x6d9d6122);
820 OP(FH, B, C, D, A, 14, 23, 0xfde5380c);
821 OP(FH, A, B, C, D, 1, 4, 0xa4beea44);
822 OP(FH, D, A, B, C, 4, 11, 0x4bdecfa9);
823 OP(FH, C, D, A, B, 7, 16, 0xf6bb4b60);
824 OP(FH, B, C, D, A, 10, 23, 0xbebfbc70);
825 OP(FH, A, B, C, D, 13, 4, 0x289b7ec6);
826 OP(FH, D, A, B, C, 0, 11, 0xeaa127fa);
827 OP(FH, C, D, A, B, 3, 16, 0xd4ef3085);
828 OP(FH, B, C, D, A, 6, 23, 0x04881d05);
829 OP(FH, A, B, C, D, 9, 4, 0xd9d4d039);
830 OP(FH, D, A, B, C, 12, 11, 0xe6db99e5);
831 OP(FH, C, D, A, B, 15, 16, 0x1fa27cf8);
832 OP(FH, B, C, D, A, 2, 23, 0xc4ac5665);
833# endif
834
835 /* Round 4 */
836# if MD5_SIZE_VS_SPEED == 1
837 for (i = 0; i < 4; i++) {
838 OP(FI, A, B, C, D, (int) (*pp++), 6, *pc++);
839 OP(FI, D, A, B, C, (int) (*pp++), 10, *pc++);
840 OP(FI, C, D, A, B, (int) (*pp++), 15, *pc++);
841 OP(FI, B, C, D, A, (int) (*pp++), 21, *pc++);
842 }
843# else
844 OP(FI, A, B, C, D, 0, 6, 0xf4292244);
845 OP(FI, D, A, B, C, 7, 10, 0x432aff97);
846 OP(FI, C, D, A, B, 14, 15, 0xab9423a7);
847 OP(FI, B, C, D, A, 5, 21, 0xfc93a039);
848 OP(FI, A, B, C, D, 12, 6, 0x655b59c3);
849 OP(FI, D, A, B, C, 3, 10, 0x8f0ccc92);
850 OP(FI, C, D, A, B, 10, 15, 0xffeff47d);
851 OP(FI, B, C, D, A, 1, 21, 0x85845dd1);
852 OP(FI, A, B, C, D, 8, 6, 0x6fa87e4f);
853 OP(FI, D, A, B, C, 15, 10, 0xfe2ce6e0);
854 OP(FI, C, D, A, B, 6, 15, 0xa3014314);
855 OP(FI, B, C, D, A, 13, 21, 0x4e0811a1);
856 OP(FI, A, B, C, D, 4, 6, 0xf7537e82);
857 OP(FI, D, A, B, C, 11, 10, 0xbd3af235);
858 OP(FI, C, D, A, B, 2, 15, 0x2ad7d2bb);
859 OP(FI, B, C, D, A, 9, 21, 0xeb86d391);
860# undef OP
861# endif
862 /* Add checksum to the starting values */
863 ctx->A = A_save + A;
864 ctx->B = B_save + B;
865 ctx->C = C_save + C;
866 ctx->D = D_save + D;
867#endif
868}
869#undef FF
870#undef FG
871#undef FH
872#undef FI
873
874/* Feed data through a temporary buffer to call md5_hash_aligned_block()
875 * with chunks of data that are 4-byte aligned and a multiple of 64 bytes.
876 * This function's internal buffer remembers previous data until it has 64
877 * bytes worth to pass on. Call md5_end() to flush this buffer. */
878void FAST_FUNC md5_hash(md5_ctx_t *ctx, const void *buffer, size_t len)
879{
880 unsigned bufpos = ctx->total64 & 63;
881 unsigned remaining;
882
883 /* RFC 1321 specifies the possible length of the file up to 2^64 bits.
884 * Here we only track the number of bytes. */
885 ctx->total64 += len;
886#if 0
887 remaining = 64 - bufpos;
888
889 /* Hash whole blocks */
890 while (len >= remaining) {
891 memcpy(ctx->wbuffer + bufpos, buffer, remaining);
892 buffer = (const char *)buffer + remaining;
893 len -= remaining;
894 remaining = 64;
895 bufpos = 0;
896 md5_process_block64(ctx);
897 }
898
899 /* Save last, partial blosk */
900 memcpy(ctx->wbuffer + bufpos, buffer, len);
901#else
902 /* Tiny bit smaller code */
903 while (1) {
904 remaining = 64 - bufpos;
905 if (remaining > len)
906 remaining = len;
907 /* Copy data into aligned buffer */
908 memcpy(ctx->wbuffer + bufpos, buffer, remaining);
909 len -= remaining;
910 buffer = (const char *)buffer + remaining;
911 bufpos += remaining;
912 /* clever way to do "if (bufpos != 64) break; ... ; bufpos = 0;" */
913 bufpos -= 64;
914 if (bufpos != 0)
915 break;
916 /* Buffer is filled up, process it */
917 md5_process_block64(ctx);
918 /*bufpos = 0; - already is */
919 }
920#endif
921}
922
923/* Process the remaining bytes in the buffer and put result from CTX
924 * in first 16 bytes following RESBUF. The result is always in little
925 * endian byte order, so that a byte-wise output yields to the wanted
926 * ASCII representation of the message digest.
927 */
928void FAST_FUNC md5_end(md5_ctx_t *ctx, void *resbuf)
929{
930 unsigned bufpos = ctx->total64 & 63;
931 /* Pad the buffer to the next 64-byte boundary with 0x80,0,0,0... */
932 ctx->wbuffer[bufpos++] = 0x80;
933
934 /* This loop iterates either once or twice, no more, no less */
935 while (1) {
936 unsigned remaining = 64 - bufpos;
937 memset(ctx->wbuffer + bufpos, 0, remaining);
938 /* Do we have enough space for the length count? */
939 if (remaining >= 8) {
940 /* Store the 64-bit counter of bits in the buffer in LE format */
941 uint64_t t = ctx->total64 << 3;
942 t = SWAP_LE64(t);
943 /* wbuffer is suitably aligned for this */
944 *(uint64_t *) (&ctx->wbuffer[64 - 8]) = t;
945 }
946 md5_process_block64(ctx);
947 if (remaining >= 8)
948 break;
949 bufpos = 0;
950 }
951
952 /* The MD5 result is in little endian byte order.
953 * We (ab)use the fact that A-D are consecutive in memory.
954 */
955#if BB_BIG_ENDIAN
956 ctx->A = SWAP_LE32(ctx->A);
957 ctx->B = SWAP_LE32(ctx->B);
958 ctx->C = SWAP_LE32(ctx->C);
959 ctx->D = SWAP_LE32(ctx->D);
960#endif
961 memcpy(resbuf, &ctx->A, sizeof(ctx->A) * 4);
962}