40 |
40 |
#include "sha2.h"
|
41 |
41 |
|
42 |
42 |
/*
|
|
43 |
* #if condition from regint.h - XXX there must exist a nicer way
|
|
44 |
*/
|
|
45 |
|
|
46 |
#if defined(__i386) || defined(__i386__) || defined(_M_IX86) || \
|
|
47 |
(defined(__ppc__) && defined(__APPLE__)) || \
|
|
48 |
defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD86) || \
|
|
49 |
defined(__mc68020__)
|
|
50 |
#define PLAT_NEED_ALIGNED_WORD_ACCESS 0
|
|
51 |
#else
|
|
52 |
#define PLAT_NEED_ALIGNED_WORD_ACCESS 1
|
|
53 |
#endif
|
|
54 |
|
|
55 |
/*
|
|
56 |
* from http://www.wambold.com/Martin/writings/alignof.html
|
|
57 |
*
|
|
58 |
* NOTE: This gives us the alignment the compiler would choose, not necessarily
|
|
59 |
* the minimal alignment requirement for the platform we live on
|
|
60 |
*/
|
|
61 |
|
|
62 |
#define ALIGNOF(type) offsetof (struct { char c; type member; }, member)
|
|
63 |
|
|
64 |
/*
|
43 |
65 |
* ASSERT NOTE:
|
44 |
66 |
* Some sanity checking code is included using assert(). On my FreeBSD
|
45 |
67 |
* system, this additional code can be removed by compiling with NDEBUG
|
... | ... | |
106 |
128 |
* Thank you, Jun-ichiro itojun Hagino, for suggesting using u_intXX_t
|
107 |
129 |
* types and pointing out recent ANSI C support for uintXX_t in inttypes.h.
|
108 |
130 |
*/
|
109 |
|
#ifdef SHA2_USE_INTTYPES_H
|
110 |
131 |
|
111 |
|
typedef uint8_t sha2_byte; /* Exactly 1 byte */
|
112 |
|
typedef uint32_t sha2_word32; /* Exactly 4 bytes */
|
113 |
|
typedef uint64_t sha2_word64; /* Exactly 8 bytes */
|
114 |
|
|
115 |
|
#else /* SHA2_USE_INTTYPES_H */
|
116 |
|
|
117 |
|
typedef u_int8_t sha2_byte; /* Exactly 1 byte */
|
118 |
|
typedef u_int32_t sha2_word32; /* Exactly 4 bytes */
|
119 |
|
typedef u_int64_t sha2_word64; /* Exactly 8 bytes */
|
120 |
|
|
121 |
|
#endif /* SHA2_USE_INTTYPES_H */
|
122 |
|
|
123 |
|
|
124 |
132 |
/*** SHA-256/384/512 Various Length Definitions ***********************/
|
125 |
133 |
/* NOTE: Most of these are in sha2.h */
|
126 |
134 |
#define SHA256_SHORT_BLOCK_LENGTH (SHA256_BLOCK_LENGTH - 8)
|
... | ... | |
392 |
400 |
sha2_word32 T1, *W256;
|
393 |
401 |
int j;
|
394 |
402 |
|
395 |
|
W256 = (sha2_word32*)context->buffer;
|
|
403 |
W256 = context->buffer;
|
396 |
404 |
|
397 |
405 |
/* Initialize registers with the prev. intermediate value */
|
398 |
406 |
a = context->state[0];
|
... | ... | |
450 |
458 |
sha2_word32 T1, T2, *W256;
|
451 |
459 |
int j;
|
452 |
460 |
|
453 |
|
W256 = (sha2_word32*)context->buffer;
|
|
461 |
W256 = context->buffer;
|
454 |
462 |
|
455 |
463 |
/* Initialize registers with the prev. intermediate value */
|
456 |
464 |
a = context->state[0];
|
... | ... | |
527 |
535 |
|
528 |
536 |
void SHA256_Update(SHA256_CTX* context, const sha2_byte *data, size_t len) {
|
529 |
537 |
unsigned int freespace, usedspace;
|
|
538 |
uint8_t *buffer = (uint8_t *)context->buffer;
|
530 |
539 |
|
531 |
540 |
if (len == 0) {
|
532 |
541 |
/* Calling with no data is valid - we do nothing */
|
... | ... | |
537 |
546 |
assert(context != (SHA256_CTX*)0 && data != (sha2_byte*)0);
|
538 |
547 |
|
539 |
548 |
usedspace = (unsigned int)((context->bitcount >> 3) % SHA256_BLOCK_LENGTH);
|
540 |
|
if (usedspace > 0) {
|
|
549 |
|
|
550 |
/* work on the buffer if it is filled or if we need to re-align data */
|
|
551 |
while (usedspace || (
|
|
552 |
PLAT_NEED_ALIGNED_WORD_ACCESS &&
|
|
553 |
(len > 0) &&
|
|
554 |
(((size_t)data % ALIGNOF(sha2_word32)) != 0))) {
|
541 |
555 |
/* Calculate how much free space is available in the buffer */
|
542 |
556 |
freespace = SHA256_BLOCK_LENGTH - usedspace;
|
543 |
557 |
|
544 |
558 |
if (len >= freespace) {
|
545 |
559 |
/* Fill the buffer completely and process it */
|
546 |
|
MEMCPY_BCOPY(&context->buffer[usedspace], data, freespace);
|
|
560 |
MEMCPY_BCOPY(&buffer[usedspace], data, freespace);
|
547 |
561 |
context->bitcount += freespace << 3;
|
548 |
562 |
len -= freespace;
|
549 |
563 |
data += freespace;
|
550 |
|
SHA256_Transform(context, (sha2_word32*)context->buffer);
|
|
564 |
SHA256_Transform(context, context->buffer);
|
|
565 |
usedspace = 0;
|
551 |
566 |
} else {
|
552 |
567 |
/* The buffer is not yet full */
|
553 |
|
MEMCPY_BCOPY(&context->buffer[usedspace], data, len);
|
|
568 |
MEMCPY_BCOPY(&buffer[usedspace], data, len);
|
554 |
569 |
context->bitcount += len << 3;
|
555 |
570 |
/* Clean up: */
|
556 |
571 |
usedspace = freespace = 0;
|
... | ... | |
576 |
591 |
void SHA256_Final(sha2_byte digest[], SHA256_CTX* context) {
|
577 |
592 |
sha2_word32 *d = (sha2_word32*)digest;
|
578 |
593 |
unsigned int usedspace;
|
|
594 |
uint8_t *buffer = (uint8_t *)context->buffer;
|
579 |
595 |
|
580 |
596 |
/* Sanity check: */
|
581 |
597 |
assert(context != (SHA256_CTX*)0);
|
... | ... | |
589 |
605 |
#endif
|
590 |
606 |
if (usedspace > 0) {
|
591 |
607 |
/* Begin padding with a 1 bit: */
|
592 |
|
context->buffer[usedspace++] = 0x80;
|
|
608 |
buffer[usedspace++] = 0x80;
|
593 |
609 |
|
594 |
610 |
if (usedspace <= SHA256_SHORT_BLOCK_LENGTH) {
|
595 |
611 |
/* Set-up for the last transform: */
|
596 |
|
MEMSET_BZERO(&context->buffer[usedspace], SHA256_SHORT_BLOCK_LENGTH - usedspace);
|
|
612 |
MEMSET_BZERO(&buffer[usedspace], SHA256_SHORT_BLOCK_LENGTH - usedspace);
|
597 |
613 |
} else {
|
598 |
614 |
if (usedspace < SHA256_BLOCK_LENGTH) {
|
599 |
|
MEMSET_BZERO(&context->buffer[usedspace], SHA256_BLOCK_LENGTH - usedspace);
|
|
615 |
MEMSET_BZERO(&buffer[usedspace], SHA256_BLOCK_LENGTH - usedspace);
|
600 |
616 |
}
|
601 |
617 |
/* Do second-to-last transform: */
|
602 |
|
SHA256_Transform(context, (sha2_word32*)context->buffer);
|
|
618 |
SHA256_Transform(context, context->buffer);
|
603 |
619 |
|
604 |
620 |
/* And set-up for the last transform: */
|
605 |
621 |
MEMSET_BZERO(context->buffer, SHA256_SHORT_BLOCK_LENGTH);
|
... | ... | |
609 |
625 |
MEMSET_BZERO(context->buffer, SHA256_SHORT_BLOCK_LENGTH);
|
610 |
626 |
|
611 |
627 |
/* Begin padding with a 1 bit: */
|
612 |
|
*context->buffer = 0x80;
|
|
628 |
*buffer = 0x80;
|
613 |
629 |
}
|
614 |
630 |
/* Set the bit count: */
|
615 |
|
*(sha2_word64*)&context->buffer[SHA256_SHORT_BLOCK_LENGTH] = context->bitcount;
|
|
631 |
*(sha2_word64*)&buffer[SHA256_SHORT_BLOCK_LENGTH] = context->bitcount;
|
616 |
632 |
|
617 |
633 |
/* Final transform: */
|
618 |
|
SHA256_Transform(context, (sha2_word32*)context->buffer);
|
|
634 |
SHA256_Transform(context, context->buffer);
|
619 |
635 |
|
620 |
636 |
#if BYTE_ORDER == LITTLE_ENDIAN
|
621 |
637 |
{
|
... | ... | |
715 |
731 |
|
716 |
732 |
void SHA512_Transform(SHA512_CTX* context, const sha2_word64* data) {
|
717 |
733 |
sha2_word64 a, b, c, d, e, f, g, h, s0, s1;
|
718 |
|
sha2_word64 T1, *W512 = (sha2_word64*)context->buffer;
|
|
734 |
sha2_word64 T1, *W512 = context->buffer;
|
719 |
735 |
int j;
|
720 |
736 |
|
721 |
737 |
/* Initialize registers with the prev. intermediate value */
|
... | ... | |
770 |
786 |
|
771 |
787 |
void SHA512_Transform(SHA512_CTX* context, const sha2_word64* data) {
|
772 |
788 |
sha2_word64 a, b, c, d, e, f, g, h, s0, s1;
|
773 |
|
sha2_word64 T1, T2, *W512 = (sha2_word64*)context->buffer;
|
|
789 |
sha2_word64 T1, T2, *W512 = context->buffer;
|
774 |
790 |
int j;
|
775 |
791 |
|
776 |
792 |
/* Initialize registers with the prev. intermediate value */
|
... | ... | |
848 |
864 |
|
849 |
865 |
void SHA512_Update(SHA512_CTX* context, const sha2_byte *data, size_t len) {
|
850 |
866 |
unsigned int freespace, usedspace;
|
|
867 |
uint8_t *buffer = (uint8_t *)context->buffer;
|
851 |
868 |
|
852 |
869 |
if (len == 0) {
|
853 |
870 |
/* Calling with no data is valid - we do nothing */
|
... | ... | |
855 |
872 |
}
|
856 |
873 |
|
857 |
874 |
/* Sanity check: */
|
858 |
|
assert(context != (SHA512_CTX*)0 && data != (sha2_byte*)0);
|
|
875 |
assert(context != (SHA512_CTX*)0);
|
|
876 |
assert(context->buffer != (sha2_word64*)0);
|
|
877 |
assert(data != (sha2_byte*)0);
|
859 |
878 |
|
860 |
879 |
usedspace = (unsigned int)((context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH);
|
861 |
|
if (usedspace > 0) {
|
|
880 |
/* work on the buffer if it is filled or if we need to re-align data */
|
|
881 |
while (usedspace || (
|
|
882 |
PLAT_NEED_ALIGNED_WORD_ACCESS &&
|
|
883 |
(len > 0) &&
|
|
884 |
(((size_t)data % ALIGNOF(sha2_word64)) != 0))) {
|
862 |
885 |
/* Calculate how much free space is available in the buffer */
|
863 |
886 |
freespace = SHA512_BLOCK_LENGTH - usedspace;
|
864 |
887 |
|
865 |
888 |
if (len >= freespace) {
|
866 |
889 |
/* Fill the buffer completely and process it */
|
867 |
|
MEMCPY_BCOPY(&context->buffer[usedspace], data, freespace);
|
|
890 |
MEMCPY_BCOPY(&buffer[usedspace], data, freespace);
|
868 |
891 |
ADDINC128(context->bitcount, freespace << 3);
|
869 |
892 |
len -= freespace;
|
870 |
893 |
data += freespace;
|
871 |
|
SHA512_Transform(context, (sha2_word64*)context->buffer);
|
|
894 |
SHA512_Transform(context, context->buffer);
|
|
895 |
usedspace = 0;
|
872 |
896 |
} else {
|
873 |
897 |
/* The buffer is not yet full */
|
874 |
|
MEMCPY_BCOPY(&context->buffer[usedspace], data, len);
|
|
898 |
MEMCPY_BCOPY(&buffer[usedspace], data, len);
|
875 |
899 |
ADDINC128(context->bitcount, len << 3);
|
876 |
900 |
/* Clean up: */
|
877 |
901 |
usedspace = freespace = 0;
|
... | ... | |
896 |
920 |
|
897 |
921 |
void SHA512_Last(SHA512_CTX* context) {
|
898 |
922 |
unsigned int usedspace;
|
|
923 |
uint8_t *buffer = (uint8_t *)context->buffer;
|
899 |
924 |
|
900 |
925 |
usedspace = (unsigned int)((context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH);
|
901 |
926 |
#if BYTE_ORDER == LITTLE_ENDIAN
|
... | ... | |
905 |
930 |
#endif
|
906 |
931 |
if (usedspace > 0) {
|
907 |
932 |
/* Begin padding with a 1 bit: */
|
908 |
|
context->buffer[usedspace++] = 0x80;
|
|
933 |
buffer[usedspace++] = 0x80;
|
909 |
934 |
|
910 |
935 |
if (usedspace <= SHA512_SHORT_BLOCK_LENGTH) {
|
911 |
936 |
/* Set-up for the last transform: */
|
912 |
|
MEMSET_BZERO(&context->buffer[usedspace], SHA512_SHORT_BLOCK_LENGTH - usedspace);
|
|
937 |
MEMSET_BZERO(&buffer[usedspace], SHA512_SHORT_BLOCK_LENGTH - usedspace);
|
913 |
938 |
} else {
|
914 |
939 |
if (usedspace < SHA512_BLOCK_LENGTH) {
|
915 |
|
MEMSET_BZERO(&context->buffer[usedspace], SHA512_BLOCK_LENGTH - usedspace);
|
|
940 |
MEMSET_BZERO(&buffer[usedspace], SHA512_BLOCK_LENGTH - usedspace);
|
916 |
941 |
}
|
917 |
942 |
/* Do second-to-last transform: */
|
918 |
|
SHA512_Transform(context, (sha2_word64*)context->buffer);
|
|
943 |
SHA512_Transform(context, context->buffer);
|
919 |
944 |
|
920 |
945 |
/* And set-up for the last transform: */
|
921 |
946 |
MEMSET_BZERO(context->buffer, SHA512_BLOCK_LENGTH - 2);
|
... | ... | |
925 |
950 |
MEMSET_BZERO(context->buffer, SHA512_SHORT_BLOCK_LENGTH);
|
926 |
951 |
|
927 |
952 |
/* Begin padding with a 1 bit: */
|
928 |
|
*context->buffer = 0x80;
|
|
953 |
*buffer = 0x80;
|
929 |
954 |
}
|
930 |
955 |
/* Store the length of input data (in bits): */
|
931 |
|
*(sha2_word64*)&context->buffer[SHA512_SHORT_BLOCK_LENGTH] = context->bitcount[1];
|
932 |
|
*(sha2_word64*)&context->buffer[SHA512_SHORT_BLOCK_LENGTH+8] = context->bitcount[0];
|
|
956 |
*(sha2_word64*)&buffer[SHA512_SHORT_BLOCK_LENGTH] = context->bitcount[1];
|
|
957 |
*(sha2_word64*)&buffer[SHA512_SHORT_BLOCK_LENGTH+8] = context->bitcount[0];
|
933 |
958 |
|
934 |
959 |
/* Final transform: */
|
935 |
|
SHA512_Transform(context, (sha2_word64*)context->buffer);
|
|
960 |
SHA512_Transform(context, context->buffer);
|
936 |
961 |
}
|
937 |
962 |
|
938 |
963 |
void SHA512_Final(sha2_byte digest[], SHA512_CTX* context) {
|