/* This file is in the public domain. */ #include #include #ifdef TRACE #include #endif typedef unsigned long int U32; typedef unsigned long long int U64; typedef struct state STATE; /* SHA-384 shares much of its code with SHA-512; this is why a number of things that would normally exist in sha512 and sha384 versions are collapsed, eg the sha_384_512 alg-specific struct below. */ struct state { int num; /* These values must be distinct and each fit in an unsigned char. */ #define NUM_SHA 2 #define NUM_SHA1 3 #define NUM_SHA256 4 #define NUM_SHA384 5 #define NUM_SHA512 6 union { struct { U32 H[5]; U32 M[16]; unsigned int mfill; U64 bitlen; } sha; struct { U32 H[5]; U32 M[16]; unsigned int mfill; U64 bitlen; } sha1; struct { U32 H[8]; U32 M[16]; unsigned int mfill; U64 bitlen; } sha256; struct { U64 H[8]; U64 M[16]; unsigned int mfill; U64 bitlen_l; U64 bitlen_h; } sha_384_512; } u; } ; #define LIMIT32(x) (((U32)(x))&(U32)0xffffffff) #define LIMIT64(x) (((U64)(x))&(U64)0xffffffffffffffffULL) __inline__ static U32 ROTL32(U32 v, unsigned int nbits) { return(LIMIT32(v<>(32-nbits))); } __inline__ static U32 ROTR32(U32 v, unsigned int nbits) { return((LIMIT32(v)>>nbits)|LIMIT32(v<<(32-nbits))); } __inline__ static U64 ROTL64(U64 v, unsigned int nbits) { return(LIMIT64(v<>(64-nbits))); } __inline__ static U64 ROTR64(U64 v, unsigned int nbits) { return((LIMIT64(v)>>nbits)|LIMIT64(v<<(64-nbits))); } static void fill_u32s(const unsigned char *buf, U32 *u32s, unsigned int n) { for (;n>0;n--) { *u32s++ = buf[3] | (((U32)buf[2]) << 8) | (((U32)buf[1]) << 16) | (((U32)buf[0]) << 24); buf += 4; } } static void fill_u64s(const unsigned char *buf, U64 *u64s, unsigned int n) { for (;n>0;n--) { *u64s++ = buf[7] | (((U64)buf[6]) << 8) | (((U64)buf[5]) << 16) | (((U64)buf[4]) << 24) | (((U64)buf[3]) << 32) | (((U64)buf[2]) << 40) | (((U64)buf[1]) << 48) | (((U64)buf[0]) << 56); buf += 8; } } /***************** BEGIN SHA *****************/ #define SHA_F_1(B,C,D) ((B&C)|((~(B))&D)) #define SHA_F_2(B,C,D) (B^C^D) #define SHA_F_3(B,C,D) ((B&C)|(B&D)|(C&D)) #define SHA_F_4(B,C,D) (B^C^D) #define SHA_K_1 0x5a827999 #define SHA_K_2 0x6ed9eba1 #define SHA_K_3 0x8f1bbcdc #define SHA_K_4 0xca62c1d6 static void sha_crunch_block(STATE *state) { U32 A; U32 B; U32 C; U32 D; U32 E; U32 *M; U32 TMP; int i; A = LIMIT32(state->u.sha.H[0]); B = LIMIT32(state->u.sha.H[1]); C = LIMIT32(state->u.sha.H[2]); D = LIMIT32(state->u.sha.H[3]); E = LIMIT32(state->u.sha.H[4]); M = &state->u.sha.M[0]; #ifdef TRACE printf("SHA block:\n"); for (i=0;i<16;i++) printf("M[%2d] = %08x\n",i,(unsigned int)M[i]); for (i=0;i<5;i++) printf("H[%d] = %08x\n",i,(unsigned int)LIMIT32(state->u.sha.H[i])); #define MAYBE_TRACE() do {\ printf("t=%2d: %08x %08x %08x %08x %08x\n",i,(unsigned int)A, \ (unsigned int)B,(unsigned int)C,(unsigned int)D,(unsigned int)E);\ } while (0) #else #define MAYBE_TRACE() /* nothing */ #endif #define BODY(fn,k) do {\ TMP = ROTL32(A,5) + fn(B,C,D) + E + M[i&15] + (k); \ E = D; \ D = C; \ C = ROTL32(B,30); \ B = A; \ A = LIMIT32(TMP); \ MAYBE_TRACE(); \ } while (0) for (i=0;i<16;i++) BODY(SHA_F_1,SHA_K_1); for (i=16;i<20;i++) { M[i&15] ^= M[(i+13)&15] ^ M[(i+8)&15] ^ M[(i+2)&15]; BODY(SHA_F_1,SHA_K_1); } for (i=20;i<40;i++) { M[i&15] ^= M[(i+13)&15] ^ M[(i+8)&15] ^ M[(i+2)&15]; BODY(SHA_F_2,SHA_K_2); } for (i=40;i<60;i++) { M[i&15] ^= M[(i+13)&15] ^ M[(i+8)&15] ^ M[(i+2)&15]; BODY(SHA_F_3,SHA_K_3); } for (i=60;i<80;i++) { M[i&15] ^= M[(i+13)&15] ^ M[(i+8)&15] ^ M[(i+2)&15]; BODY(SHA_F_4,SHA_K_4); } #undef BODY #undef MAYBE_TRACE state->u.sha.H[0] += A; state->u.sha.H[1] += B; state->u.sha.H[2] += C; state->u.sha.H[3] += D; state->u.sha.H[4] += E; } static void sha_crunch_bytes(STATE *state, const unsigned char *buf, unsigned int nbytes) { unsigned int mfill; U32 *M; mfill = state->u.sha.mfill; M = &state->u.sha.M[0]; while (nbytes > 0) { if ((mfill == 0) && (nbytes >= 64)) { fill_u32s(buf,M,64/4); sha_crunch_block(state); buf += 64; nbytes -= 64; } else { if (((mfill % 4) == 0) && (nbytes >= 4)) { unsigned int n; n = 64 - mfill; if (n > nbytes) n = nbytes; n &= ~3; fill_u32s(buf,&M[mfill/4],n/4); buf += n; nbytes -= n; mfill += n; } else { switch (mfill % 4) { case 0: M[mfill/4] = ((U32)*buf) << 24; break; case 1: M[mfill/4] |= ((U32)*buf) << 16; break; case 2: M[mfill/4] |= ((U32)*buf) << 8; break; case 3: M[mfill/4] |= *buf; break; } buf ++; nbytes --; mfill ++; } if (mfill >= 64) { sha_crunch_block(state); mfill = 0; } } } state->u.sha.mfill = mfill; } void *sha_init(void) { STATE *s; s = malloc(sizeof(STATE)); if (s == 0) return(0); s->num = NUM_SHA; s->u.sha.H[0] = 0x67452301; s->u.sha.H[1] = 0xefcdab89; s->u.sha.H[2] = 0x98badcfe; s->u.sha.H[3] = 0x10325476; s->u.sha.H[4] = 0xc3d2e1f0; s->u.sha.mfill = 0; s->u.sha.bitlen = 0; return(s); } void sha_process_bytes(void *state, const void *vbuf, unsigned int nbytes) #define s ((STATE *)state) { if (s->num != NUM_SHA) { abort(); return; } sha_crunch_bytes(s,vbuf,nbytes); s->u.sha.bitlen += nbytes * (U64)8; } #undef s void sha_result(void *state, unsigned char *result) #define s ((STATE *)state) { unsigned char lenbytes[8]; if (s->num != NUM_SHA) { abort(); return; } sha_crunch_bytes(s,(const void *)"\200",1); while (s->u.sha.mfill != 56) sha_crunch_bytes(s,(const void *)"\0",1); lenbytes[0] = (s->u.sha.bitlen >> 56) & 0xff; lenbytes[1] = (s->u.sha.bitlen >> 48) & 0xff; lenbytes[2] = (s->u.sha.bitlen >> 40) & 0xff; lenbytes[3] = (s->u.sha.bitlen >> 32) & 0xff; lenbytes[4] = (s->u.sha.bitlen >> 24) & 0xff; lenbytes[5] = (s->u.sha.bitlen >> 16) & 0xff; lenbytes[6] = (s->u.sha.bitlen >> 8) & 0xff; lenbytes[7] = s->u.sha.bitlen & 0xff; sha_crunch_bytes(s,&lenbytes[0],8); result[ 0] = (s->u.sha.H[0] >> 24) & 0xff; result[ 1] = (s->u.sha.H[0] >> 16) & 0xff; result[ 2] = (s->u.sha.H[0] >> 8) & 0xff; result[ 3] = s->u.sha.H[0] & 0xff; result[ 4] = (s->u.sha.H[1] >> 24) & 0xff; result[ 5] = (s->u.sha.H[1] >> 16) & 0xff; result[ 6] = (s->u.sha.H[1] >> 8) & 0xff; result[ 7] = s->u.sha.H[1] & 0xff; result[ 8] = (s->u.sha.H[2] >> 24) & 0xff; result[ 9] = (s->u.sha.H[2] >> 16) & 0xff; result[10] = (s->u.sha.H[2] >> 8) & 0xff; result[11] = s->u.sha.H[2] & 0xff; result[12] = (s->u.sha.H[3] >> 24) & 0xff; result[13] = (s->u.sha.H[3] >> 16) & 0xff; result[14] = (s->u.sha.H[3] >> 8) & 0xff; result[15] = s->u.sha.H[3] & 0xff; result[16] = (s->u.sha.H[4] >> 24) & 0xff; result[17] = (s->u.sha.H[4] >> 16) & 0xff; result[18] = (s->u.sha.H[4] >> 8) & 0xff; result[19] = s->u.sha.H[4] & 0xff; free(s); } #undef s void *sha_clone(const void *old) #define o ((const STATE *)old) { STATE *n; if (o->num != NUM_SHA) { abort(); return(0); } n = malloc(sizeof(STATE)); n->num = NUM_SHA; n->u.sha = o->u.sha; return(n); } #undef o int sha_state(const void *state, void *buf, int buflen) #define s ((const STATE *)state) { int want; int blen; int i; unsigned char *bp; unsigned char ck_xor; unsigned char ck_sum; static void sb(unsigned char b) { *bp++ = b; ck_xor ^= b; ck_sum += b; } static void sb32(U32 v) { sb( v &0xff); sb((v>> 8)&0xff); sb((v>>16)&0xff); sb((v>>24)&0xff); } if (s->num != NUM_SHA) { abort(); return(0); } want = 1 + 1 + 1 + 1 + 1 + ((5 + ((s->u.sha.mfill+3)/4)) * 4); if (s->u.sha.bitlen >> 56) blen = 8; else if (s->u.sha.bitlen >> 48) blen = 7; else if (s->u.sha.bitlen >> 40) blen = 6; else if (s->u.sha.bitlen >> 32) blen = 5; else if (s->u.sha.bitlen >> 24) blen = 4; else if (s->u.sha.bitlen >> 16) blen = 3; else if (s->u.sha.bitlen >> 8) blen = 2; else if (s->u.sha.bitlen ) blen = 1; else blen = 0; want += blen + 1 + 1; if (want > buflen) return(want); bp = buf; ck_xor = 0xff; ck_sum = 0; sb(2); sb(NUM_SHA); sb(want); sb(s->u.sha.mfill); sb(blen); sb32(s->u.sha.H[0]); sb32(s->u.sha.H[1]); sb32(s->u.sha.H[2]); sb32(s->u.sha.H[3]); sb32(s->u.sha.H[4]); for (i=0;iu.sha.mfill;i+=4) sb32(s->u.sha.M[i>>2]); if (blen > 0) sb( s->u.sha.bitlen &0xff); if (blen > 1) sb((s->u.sha.bitlen>> 8)&0xff); if (blen > 2) sb((s->u.sha.bitlen>>16)&0xff); if (blen > 3) sb((s->u.sha.bitlen>>24)&0xff); if (blen > 4) sb((s->u.sha.bitlen>>32)&0xff); if (blen > 5) sb((s->u.sha.bitlen>>40)&0xff); if (blen > 6) sb((s->u.sha.bitlen>>48)&0xff); if (blen > 7) sb((s->u.sha.bitlen>>56)&0xff); i = ck_sum; sb(0xff&ck_xor); sb(0xff&i); return(want); } #undef s int sha_set_state(void *state, const void *buf, int buflen) #define s ((STATE *)state) { const unsigned char *bp; int l; int mfill; int blen; int i; unsigned char ck_xor; unsigned char ck_sum; static U32 get32(void) { bp += 4; return( (((U32)bp[-1]) << 24) | (((U32)bp[-2]) << 16) | (((U32)bp[-3]) << 8) | ((U32)bp[-4]) ); } if (s->num != NUM_SHA) { abort(); return(SHA_CORRUPT); } if (buflen < 1) return(SHA_CORRUPT); bp = buf; if (*bp++ != 2) return(SHA_BADVERS); if (buflen < 1+1+1+1+1+((5+((0+3)/4))*4) + 0+1+1) return(SHA_CORRUPT); if (*bp++ != NUM_SHA) return(SHA_CORRUPT); l = *bp++; if (l > buflen) return(SHA_CORRUPT); mfill = *bp++; if ((mfill < 0) || (mfill > 63)) return(SHA_CORRUPT); blen = *bp++; if ((blen < 0) || (blen > 8)) return(SHA_CORRUPT); if (l != 1+1+1+1+1+((5+((mfill+3)/4))*4) + blen+1+1) return(SHA_CORRUPT); ck_xor = 0xff; ck_sum = 0; for (i=l-3;i>=0;i--) { ck_xor ^= ((const unsigned char *)buf)[i]; ck_sum += ((const unsigned char *)buf)[i]; } if (((const unsigned char *)buf)[l-2] != (0xff&ck_xor)) return(SHA_CORRUPT); if (((const unsigned char *)buf)[l-1] != (0xff&ck_sum)) return(SHA_CORRUPT); s->u.sha.mfill = mfill; s->u.sha.H[0] = get32(); s->u.sha.H[1] = get32(); s->u.sha.H[2] = get32(); s->u.sha.H[3] = get32(); s->u.sha.H[4] = get32(); for (i=0;iu.sha.M[i>>2] = get32(); s->u.sha.bitlen = 0; for (i=blen-1;i>=0;i--) s->u.sha.bitlen = (s->u.sha.bitlen << 8) | bp[i]; /* bp += blen; - don't bother; it's not used hereafter */ return(0); } #undef s void sha_drop(void *state) { if (((STATE *)state)->num != NUM_SHA) { abort(); return; } free(state); } /***************** END SHA *****************/ /***************** BEGIN SHA1 *****************/ #define SHA1_F_1(B,C,D) ((B&C)|((~(B))&D)) #define SHA1_F_2(B,C,D) (B^C^D) #define SHA1_F_3(B,C,D) ((B&C)|(B&D)|(C&D)) #define SHA1_F_4(B,C,D) (B^C^D) #define SHA1_K_1 0x5a827999 #define SHA1_K_2 0x6ed9eba1 #define SHA1_K_3 0x8f1bbcdc #define SHA1_K_4 0xca62c1d6 static void sha1_crunch_block(STATE *state) { U32 A; U32 B; U32 C; U32 D; U32 E; U32 *M; U32 TMP; int i; A = LIMIT32(state->u.sha1.H[0]); B = LIMIT32(state->u.sha1.H[1]); C = LIMIT32(state->u.sha1.H[2]); D = LIMIT32(state->u.sha1.H[3]); E = LIMIT32(state->u.sha1.H[4]); M = &state->u.sha1.M[0]; #ifdef TRACE printf("SHA-1 block:\n"); for (i=0;i<16;i++) printf("M[%2d] = %08x\n",i,(unsigned int)M[i]); for (i=0;i<5;i++) printf("H[%d] = %08x\n",i,(unsigned int)LIMIT32(state->u.sha1.H[i])); #define MAYBE_TRACE() do {\ printf("t=%2d: %08x %08x %08x %08x %08x\n",i,(unsigned int)A, \ (unsigned int)B,(unsigned int)C,(unsigned int)D,(unsigned int)E);\ } while (0) #else #define MAYBE_TRACE() /* nothing */ #endif #define BODY(fn,k) do {\ TMP = ROTL32(A,5) + fn(B,C,D) + E + M[i&15] + (k); \ E = D; \ D = C; \ C = ROTL32(B,30); \ B = A; \ A = LIMIT32(TMP); \ MAYBE_TRACE(); \ } while (0) for (i=0;i<16;i++) BODY(SHA1_F_1,SHA1_K_1); for (i=16;i<20;i++) { M[i&15] = ROTL32(M[(i+13)&15] ^ M[(i+8)&15] ^ M[(i+2)&15] ^ M[i&15], 1); BODY(SHA1_F_1,SHA1_K_1); } for (i=20;i<40;i++) { M[i&15] = ROTL32(M[(i+13)&15] ^ M[(i+8)&15] ^ M[(i+2)&15] ^ M[i&15], 1); BODY(SHA1_F_2,SHA1_K_2); } for (i=40;i<60;i++) { M[i&15] = ROTL32(M[(i+13)&15] ^ M[(i+8)&15] ^ M[(i+2)&15] ^ M[i&15], 1); BODY(SHA1_F_3,SHA1_K_3); } for (i=60;i<80;i++) { M[i&15] = ROTL32(M[(i+13)&15] ^ M[(i+8)&15] ^ M[(i+2)&15] ^ M[i&15], 1); BODY(SHA1_F_4,SHA1_K_4); } #undef BODY #undef MAYBE_TRACE state->u.sha1.H[0] += A; state->u.sha1.H[1] += B; state->u.sha1.H[2] += C; state->u.sha1.H[3] += D; state->u.sha1.H[4] += E; } static void sha1_crunch_bytes(STATE *state, const unsigned char *buf, unsigned int nbytes) { unsigned int mfill; U32 *M; mfill = state->u.sha1.mfill; M = &state->u.sha1.M[0]; while (nbytes > 0) { if ((mfill == 0) && (nbytes >= 64)) { fill_u32s(buf,M,64/4); sha1_crunch_block(state); buf += 64; nbytes -= 64; } else { if (((mfill % 4) == 0) && (nbytes >= 4)) { unsigned int n; n = 64 - mfill; if (n > nbytes) n = nbytes; n &= ~3; fill_u32s(buf,&M[mfill/4],n/4); buf += n; nbytes -= n; mfill += n; } else { switch (mfill % 4) { case 0: M[mfill/4] = ((U32)*buf) << 24; break; case 1: M[mfill/4] |= ((U32)*buf) << 16; break; case 2: M[mfill/4] |= ((U32)*buf) << 8; break; case 3: M[mfill/4] |= *buf; break; } buf ++; nbytes --; mfill ++; } if (mfill >= 64) { sha1_crunch_block(state); mfill = 0; } } } state->u.sha1.mfill = mfill; } void *sha1_init(void) { STATE *s; s = malloc(sizeof(STATE)); if (s == 0) return(0); s->num = NUM_SHA1; s->u.sha1.H[0] = 0x67452301; s->u.sha1.H[1] = 0xefcdab89; s->u.sha1.H[2] = 0x98badcfe; s->u.sha1.H[3] = 0x10325476; s->u.sha1.H[4] = 0xc3d2e1f0; s->u.sha1.mfill = 0; s->u.sha1.bitlen = 0; return(s); } void sha1_process_bytes(void *state, const void *vbuf, unsigned int nbytes) #define s ((STATE *)state) { if (s->num != NUM_SHA1) { abort(); return; } sha1_crunch_bytes(s,vbuf,nbytes); s->u.sha1.bitlen += nbytes * (U64)8; } #undef s void sha1_result(void *state, unsigned char *result) #define s ((STATE *)state) { unsigned char lenbytes[8]; if (s->num != NUM_SHA1) { abort(); return; } sha1_crunch_bytes(s,(const void *)"\200",1); while (s->u.sha1.mfill != 56) sha1_crunch_bytes(s,(const void *)"\0",1); lenbytes[0] = (s->u.sha1.bitlen >> 56) & 0xff; lenbytes[1] = (s->u.sha1.bitlen >> 48) & 0xff; lenbytes[2] = (s->u.sha1.bitlen >> 40) & 0xff; lenbytes[3] = (s->u.sha1.bitlen >> 32) & 0xff; lenbytes[4] = (s->u.sha1.bitlen >> 24) & 0xff; lenbytes[5] = (s->u.sha1.bitlen >> 16) & 0xff; lenbytes[6] = (s->u.sha1.bitlen >> 8) & 0xff; lenbytes[7] = s->u.sha1.bitlen & 0xff; sha1_crunch_bytes(s,&lenbytes[0],8); result[ 0] = (s->u.sha1.H[0] >> 24) & 0xff; result[ 1] = (s->u.sha1.H[0] >> 16) & 0xff; result[ 2] = (s->u.sha1.H[0] >> 8) & 0xff; result[ 3] = s->u.sha1.H[0] & 0xff; result[ 4] = (s->u.sha1.H[1] >> 24) & 0xff; result[ 5] = (s->u.sha1.H[1] >> 16) & 0xff; result[ 6] = (s->u.sha1.H[1] >> 8) & 0xff; result[ 7] = s->u.sha1.H[1] & 0xff; result[ 8] = (s->u.sha1.H[2] >> 24) & 0xff; result[ 9] = (s->u.sha1.H[2] >> 16) & 0xff; result[10] = (s->u.sha1.H[2] >> 8) & 0xff; result[11] = s->u.sha1.H[2] & 0xff; result[12] = (s->u.sha1.H[3] >> 24) & 0xff; result[13] = (s->u.sha1.H[3] >> 16) & 0xff; result[14] = (s->u.sha1.H[3] >> 8) & 0xff; result[15] = s->u.sha1.H[3] & 0xff; result[16] = (s->u.sha1.H[4] >> 24) & 0xff; result[17] = (s->u.sha1.H[4] >> 16) & 0xff; result[18] = (s->u.sha1.H[4] >> 8) & 0xff; result[19] = s->u.sha1.H[4] & 0xff; free(s); } #undef s void *sha1_clone(const void *old) #define o ((const STATE *)old) { STATE *n; if (o->num != NUM_SHA1) { abort(); return(0); } n = malloc(sizeof(STATE)); n->num = NUM_SHA1; n->u.sha1 = o->u.sha1; return(n); } #undef o int sha1_state(const void *state, void *buf, int buflen) #define s ((const STATE *)state) { int want; int blen; int i; unsigned char *bp; unsigned char ck_xor; unsigned char ck_sum; static void sb(unsigned char b) { *bp++ = b; ck_xor ^= b; ck_sum += b; } static void sb32(U32 v) { sb( v &0xff); sb((v>> 8)&0xff); sb((v>>16)&0xff); sb((v>>24)&0xff); } if (s->num != NUM_SHA1) { abort(); return(0); } want = 1 + 1 + 1 + 1 + 1 + ((5 + ((s->u.sha1.mfill+3)/4)) * 4); if (s->u.sha1.bitlen >> 56) blen = 8; else if (s->u.sha1.bitlen >> 48) blen = 7; else if (s->u.sha1.bitlen >> 40) blen = 6; else if (s->u.sha1.bitlen >> 32) blen = 5; else if (s->u.sha1.bitlen >> 24) blen = 4; else if (s->u.sha1.bitlen >> 16) blen = 3; else if (s->u.sha1.bitlen >> 8) blen = 2; else if (s->u.sha1.bitlen ) blen = 1; else blen = 0; want += blen + 1 + 1; if (want > buflen) return(want); bp = buf; ck_xor = 0xff; ck_sum = 0; sb(2); sb(NUM_SHA1); sb(want); sb(s->u.sha1.mfill); sb(blen); sb32(s->u.sha1.H[0]); sb32(s->u.sha1.H[1]); sb32(s->u.sha1.H[2]); sb32(s->u.sha1.H[3]); sb32(s->u.sha1.H[4]); for (i=0;iu.sha1.mfill;i+=4) sb32(s->u.sha1.M[i>>2]); if (blen > 0) sb( s->u.sha1.bitlen &0xff); if (blen > 1) sb((s->u.sha1.bitlen>> 8)&0xff); if (blen > 2) sb((s->u.sha1.bitlen>>16)&0xff); if (blen > 3) sb((s->u.sha1.bitlen>>24)&0xff); if (blen > 4) sb((s->u.sha1.bitlen>>32)&0xff); if (blen > 5) sb((s->u.sha1.bitlen>>40)&0xff); if (blen > 6) sb((s->u.sha1.bitlen>>48)&0xff); if (blen > 7) sb((s->u.sha1.bitlen>>56)&0xff); i = ck_sum; sb(0xff&ck_xor); sb(0xff&i); return(want); } #undef s int sha1_set_state(void *state, const void *buf, int buflen) #define s ((STATE *)state) { const unsigned char *bp; int l; int mfill; int blen; int i; unsigned char ck_xor; unsigned char ck_sum; static U32 get32(void) { bp += 4; return( (((U32)bp[-1]) << 24) | (((U32)bp[-2]) << 16) | (((U32)bp[-3]) << 8) | ((U32)bp[-4]) ); } if (s->num != NUM_SHA1) { abort(); return(SHA_CORRUPT); } if (buflen < 1) return(SHA_CORRUPT); bp = buf; if (*bp++ != 2) return(SHA_BADVERS); if (buflen < 1+1+1+1+1+((5+((0+3)/4))*4) + 0+1+1) return(SHA_CORRUPT); if (*bp++ != NUM_SHA1) return(SHA_CORRUPT); l = *bp++; if (l > buflen) return(SHA_CORRUPT); mfill = *bp++; if ((mfill < 0) || (mfill > 63)) return(SHA_CORRUPT); blen = *bp++; if ((blen < 0) || (blen > 8)) return(SHA_CORRUPT); if (l != 1+1+1+1+1+((5+((mfill+3)/4))*4) + blen+1+1) return(SHA_CORRUPT); ck_xor = 0xff; ck_sum = 0; for (i=l-3;i>=0;i--) { ck_xor ^= ((const unsigned char *)buf)[i]; ck_sum += ((const unsigned char *)buf)[i]; } if (((const unsigned char *)buf)[l-2] != (0xff&ck_xor)) return(SHA_CORRUPT); if (((const unsigned char *)buf)[l-1] != (0xff&ck_sum)) return(SHA_CORRUPT); s->u.sha1.mfill = mfill; s->u.sha1.H[0] = get32(); s->u.sha1.H[1] = get32(); s->u.sha1.H[2] = get32(); s->u.sha1.H[3] = get32(); s->u.sha1.H[4] = get32(); for (i=0;iu.sha1.M[i>>2] = get32(); s->u.sha1.bitlen = 0; for (i=blen-1;i>=0;i--) s->u.sha1.bitlen = (s->u.sha1.bitlen << 8) | bp[i]; /* bp += blen; - don't bother; it's not used hereafter */ return(0); } #undef s void sha1_drop(void *state) { if (((STATE *)state)->num != NUM_SHA1) { abort(); return; } free(state); } /***************** END SHA1 *****************/ /***************** BEGIN SHA256 *****************/ /* The spec defines MAJ with ^ where we use |, but the truth tables of the two versions are identical. */ #define SHA256_CH(B,C,D) ((B&C)|((~B)&D)) #define SHA256_MAJ(B,C,D) ((B&C)|(B&D)|(C&D)) /* sha256_K[i] = floor(pow(2,32)*frac(cbrt(primes[i]))), the high-order 32 bits of the fractional parts of the cube roots of the first 64 primes. */ static const U32 sha256_K[64] = { 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 }; __inline__ static U32 sha256_s0(U32 x) { return(ROTR32(x,7)^ROTR32(x,18)^(LIMIT32(x)>>3)); } __inline__ static U32 sha256_s1(U32 x) { return(ROTR32(x,17)^ROTR32(x,19)^(LIMIT32(x)>>10)); } __inline__ static U32 sha256_S0(U32 x) { return(ROTR32(x,2)^ROTR32(x,13)^ROTR32(x,22)); } __inline__ static U32 sha256_S1(U32 x) { return(ROTR32(x,6)^ROTR32(x,11)^ROTR32(x,25)); } static void sha256_crunch_block(STATE *state) { U32 A; U32 B; U32 C; U32 D; U32 E; U32 F; U32 G; U32 H; U32 *M; U32 T1; U32 T2; int i; A = LIMIT32(state->u.sha256.H[0]); B = LIMIT32(state->u.sha256.H[1]); C = LIMIT32(state->u.sha256.H[2]); D = LIMIT32(state->u.sha256.H[3]); E = LIMIT32(state->u.sha256.H[4]); F = LIMIT32(state->u.sha256.H[5]); G = LIMIT32(state->u.sha256.H[6]); H = LIMIT32(state->u.sha256.H[7]); M = &state->u.sha256.M[0]; #ifdef TRACE printf("SHA-256 block:\n"); for (i=0;i<16;i++) printf("M[%2d] = %08x\n",i,(unsigned int)M[i]); for (i=0;i<8;i++) printf("H[%2d] = %08x\n",i,(unsigned int)LIMIT32(state->u.sha256.H[i])); #define MAYBE_TRACE() do {\ printf("t=%2d: %08x %08x %08x %08x %08x %08x %08x %08x\n",i, \ (unsigned int)A,(unsigned int)B,(unsigned int)C,(unsigned int)D,\ (unsigned int)E,(unsigned int)F,(unsigned int)G,(unsigned int)H);\ } while (0) #else #define MAYBE_TRACE() /* nothing */ #endif #define BODY() do {\ T1 = H + sha256_S1(E) + SHA256_CH(E,F,G) + sha256_K[i] + M[i&15];\ T2 = sha256_S0(A) + SHA256_MAJ(A,B,C); \ H = G; \ G = F; \ F = E; \ E = LIMIT32(D+T1); \ D = C; \ C = B; \ B = A; \ A = LIMIT32(T1+T2); \ MAYBE_TRACE(); \ } while (0) for (i=0;i<16;i++) BODY(); for (i=16;i<64;i++) { M[i&15] = LIMIT32( sha256_s1(M[(i+14)&15]) + M[(i+9)&15] + sha256_s0(M[(i+1)&15]) + M[i&15] ); BODY(); } #undef BODY #undef MAYBE_TRACE state->u.sha256.H[0] += A; state->u.sha256.H[1] += B; state->u.sha256.H[2] += C; state->u.sha256.H[3] += D; state->u.sha256.H[4] += E; state->u.sha256.H[5] += F; state->u.sha256.H[6] += G; state->u.sha256.H[7] += H; } static void sha256_crunch_bytes(STATE *state, const unsigned char *buf, unsigned int nbytes) { unsigned int mfill; U32 *M; mfill = state->u.sha256.mfill; M = &state->u.sha256.M[0]; while (nbytes > 0) { if ((mfill == 0) && (nbytes >= 64)) { fill_u32s(buf,M,64/4); sha256_crunch_block(state); buf += 64; nbytes -= 64; } else { if (((mfill % 4) == 0) && (nbytes >= 4)) { unsigned int n; n = 64 - mfill; if (n > nbytes) n = nbytes; n &= ~3; fill_u32s(buf,&M[mfill/4],n/4); buf += n; nbytes -= n; mfill += n; } else { switch (mfill % 4) { case 0: M[mfill/4] = ((U32)*buf) << 24; break; case 1: M[mfill/4] |= ((U32)*buf) << 16; break; case 2: M[mfill/4] |= ((U32)*buf) << 8; break; case 3: M[mfill/4] |= *buf; break; } buf ++; nbytes --; mfill ++; } if (mfill >= 64) { sha256_crunch_block(state); mfill = 0; } } } state->u.sha256.mfill = mfill; } void *sha256_init(void) { STATE *s; s = malloc(sizeof(STATE)); if (s == 0) return(0); s->num = NUM_SHA256; s->u.sha256.H[0] = 0x6a09e667; s->u.sha256.H[1] = 0xbb67ae85; s->u.sha256.H[2] = 0x3c6ef372; s->u.sha256.H[3] = 0xa54ff53a; s->u.sha256.H[4] = 0x510e527f; s->u.sha256.H[5] = 0x9b05688c; s->u.sha256.H[6] = 0x1f83d9ab; s->u.sha256.H[7] = 0x5be0cd19; s->u.sha256.mfill = 0; s->u.sha256.bitlen = 0; return(s); } void sha256_process_bytes(void *state, const void *vbuf, unsigned int nbytes) #define s ((STATE *)state) { if (s->num != NUM_SHA256) { abort(); return; } sha256_crunch_bytes(s,vbuf,nbytes); s->u.sha256.bitlen += nbytes * (U64)8; } #undef s void sha256_result(void *state, unsigned char *result) #define s ((STATE *)state) { unsigned char lenbytes[8]; if (s->num != NUM_SHA256) { abort(); return; } sha256_crunch_bytes(s,(const void *)"\200",1); while (s->u.sha256.mfill != 56) sha256_crunch_bytes(s,(const void *)"\0",1); lenbytes[0] = (s->u.sha256.bitlen >> 56) & 0xff; lenbytes[1] = (s->u.sha256.bitlen >> 48) & 0xff; lenbytes[2] = (s->u.sha256.bitlen >> 40) & 0xff; lenbytes[3] = (s->u.sha256.bitlen >> 32) & 0xff; lenbytes[4] = (s->u.sha256.bitlen >> 24) & 0xff; lenbytes[5] = (s->u.sha256.bitlen >> 16) & 0xff; lenbytes[6] = (s->u.sha256.bitlen >> 8) & 0xff; lenbytes[7] = s->u.sha256.bitlen & 0xff; sha256_crunch_bytes(s,&lenbytes[0],8); result[ 0] = (s->u.sha256.H[0] >> 24) & 0xff; result[ 1] = (s->u.sha256.H[0] >> 16) & 0xff; result[ 2] = (s->u.sha256.H[0] >> 8) & 0xff; result[ 3] = s->u.sha256.H[0] & 0xff; result[ 4] = (s->u.sha256.H[1] >> 24) & 0xff; result[ 5] = (s->u.sha256.H[1] >> 16) & 0xff; result[ 6] = (s->u.sha256.H[1] >> 8) & 0xff; result[ 7] = s->u.sha256.H[1] & 0xff; result[ 8] = (s->u.sha256.H[2] >> 24) & 0xff; result[ 9] = (s->u.sha256.H[2] >> 16) & 0xff; result[10] = (s->u.sha256.H[2] >> 8) & 0xff; result[11] = s->u.sha256.H[2] & 0xff; result[12] = (s->u.sha256.H[3] >> 24) & 0xff; result[13] = (s->u.sha256.H[3] >> 16) & 0xff; result[14] = (s->u.sha256.H[3] >> 8) & 0xff; result[15] = s->u.sha256.H[3] & 0xff; result[16] = (s->u.sha256.H[4] >> 24) & 0xff; result[17] = (s->u.sha256.H[4] >> 16) & 0xff; result[18] = (s->u.sha256.H[4] >> 8) & 0xff; result[19] = s->u.sha256.H[4] & 0xff; result[20] = (s->u.sha256.H[5] >> 24) & 0xff; result[21] = (s->u.sha256.H[5] >> 16) & 0xff; result[22] = (s->u.sha256.H[5] >> 8) & 0xff; result[23] = s->u.sha256.H[5] & 0xff; result[24] = (s->u.sha256.H[6] >> 24) & 0xff; result[25] = (s->u.sha256.H[6] >> 16) & 0xff; result[26] = (s->u.sha256.H[6] >> 8) & 0xff; result[27] = s->u.sha256.H[6] & 0xff; result[28] = (s->u.sha256.H[7] >> 24) & 0xff; result[29] = (s->u.sha256.H[7] >> 16) & 0xff; result[30] = (s->u.sha256.H[7] >> 8) & 0xff; result[31] = s->u.sha256.H[7] & 0xff; free(s); } #undef s void *sha256_clone(const void *old) #define o ((const STATE *)old) { STATE *n; if (o->num != NUM_SHA256) { abort(); return(0); } n = malloc(sizeof(STATE)); n->num = NUM_SHA256; n->u.sha256 = o->u.sha256; return(n); } #undef o int sha256_state(const void *state, void *buf, int buflen) #define s ((const STATE *)state) { int want; int blen; int i; unsigned char *bp; unsigned char ck_xor; unsigned char ck_sum; static void sb(unsigned char b) { *bp++ = b; ck_xor ^= b; ck_sum += b; } static void sb32(U32 v) { sb( v &0xff); sb((v>> 8)&0xff); sb((v>>16)&0xff); sb((v>>24)&0xff); } if (s->num != NUM_SHA256) { abort(); return(0); } want = 1 + 1 + 1 + 1 + 1 + ((8 + ((s->u.sha256.mfill+3)/4)) * 4); if (s->u.sha256.bitlen >> 56) blen = 8; else if (s->u.sha256.bitlen >> 48) blen = 7; else if (s->u.sha256.bitlen >> 40) blen = 6; else if (s->u.sha256.bitlen >> 32) blen = 5; else if (s->u.sha256.bitlen >> 24) blen = 4; else if (s->u.sha256.bitlen >> 16) blen = 3; else if (s->u.sha256.bitlen >> 8) blen = 2; else if (s->u.sha256.bitlen ) blen = 1; else blen = 0; want += blen + 1 + 1; if (want > buflen) return(want); bp = buf; ck_xor = 0xff; ck_sum = 0; sb(2); sb(NUM_SHA256); sb(want); sb(s->u.sha256.mfill); sb(blen); sb32(s->u.sha256.H[0]); sb32(s->u.sha256.H[1]); sb32(s->u.sha256.H[2]); sb32(s->u.sha256.H[3]); sb32(s->u.sha256.H[4]); sb32(s->u.sha256.H[5]); sb32(s->u.sha256.H[6]); sb32(s->u.sha256.H[7]); for (i=0;iu.sha256.mfill;i+=4) sb32(s->u.sha256.M[i>>2]); if (blen > 0) sb( s->u.sha256.bitlen &0xff); if (blen > 1) sb((s->u.sha256.bitlen>> 8)&0xff); if (blen > 2) sb((s->u.sha256.bitlen>>16)&0xff); if (blen > 3) sb((s->u.sha256.bitlen>>24)&0xff); if (blen > 4) sb((s->u.sha256.bitlen>>32)&0xff); if (blen > 5) sb((s->u.sha256.bitlen>>40)&0xff); if (blen > 6) sb((s->u.sha256.bitlen>>48)&0xff); if (blen > 7) sb((s->u.sha256.bitlen>>56)&0xff); i = ck_sum; sb(0xff&ck_xor); sb(0xff&i); return(want); } #undef s int sha256_set_state(void *state, const void *buf, int buflen) #define s ((STATE *)state) { const unsigned char *bp; int l; int mfill; int blen; int i; unsigned char ck_xor; unsigned char ck_sum; static U32 get32(void) { bp += 4; return( (((U32)bp[-1]) << 24) | (((U32)bp[-2]) << 16) | (((U32)bp[-3]) << 8) | ((U32)bp[-4]) ); } if (s->num != NUM_SHA256) { abort(); return(SHA_CORRUPT); } if (buflen < 1) return(SHA_CORRUPT); bp = buf; if (*bp++ != 2) return(SHA_BADVERS); if (buflen < 1+1+1+1+1+((8+((0+3)/4))*4) + 0+1+1) return(SHA_CORRUPT); if (*bp++ != NUM_SHA256) return(SHA_CORRUPT); l = *bp++; if (l > buflen) return(SHA_CORRUPT); mfill = *bp++; if ((mfill < 0) || (mfill > 63)) return(SHA_CORRUPT); blen = *bp++; if ((blen < 0) || (blen > 8)) return(SHA_CORRUPT); if (l != 1+1+1+1+1+((8+((mfill+3)/4))*4) + blen+1+1) return(SHA_CORRUPT); ck_xor = 0xff; ck_sum = 0; for (i=l-3;i>=0;i--) { ck_xor ^= ((const unsigned char *)buf)[i]; ck_sum += ((const unsigned char *)buf)[i]; } if (((const unsigned char *)buf)[l-2] != (0xff&ck_xor)) return(SHA_CORRUPT); if (((const unsigned char *)buf)[l-1] != (0xff&ck_sum)) return(SHA_CORRUPT); s->u.sha256.mfill = mfill; s->u.sha256.H[0] = get32(); s->u.sha256.H[1] = get32(); s->u.sha256.H[2] = get32(); s->u.sha256.H[3] = get32(); s->u.sha256.H[4] = get32(); s->u.sha256.H[5] = get32(); s->u.sha256.H[6] = get32(); s->u.sha256.H[7] = get32(); for (i=0;iu.sha256.M[i>>2] = get32(); s->u.sha256.bitlen = 0; for (i=blen-1;i>=0;i--) s->u.sha256.bitlen = (s->u.sha256.bitlen << 8) | bp[i]; /* bp += blen; - don't bother; it's not used hereafter */ return(0); } #undef s void sha256_drop(void *state) { if (((STATE *)state)->num != NUM_SHA256) { abort(); return; } free(state); } /***************** END SHA256 *****************/ /***************** BEGIN SHA512 *****************/ /* The spec defines MAJ with ^ where we use |, but the truth tables of the two versions are identical. */ #define SHA384512_CH(B,C,D) ((B&C)|((~B)&D)) #define SHA384512_MAJ(B,C,D) ((B&C)|(B&D)|(C&D)) /* sha_384_512_K[i] = floor(pow(2,64)*frac(cbrt(primes[i]))), the high-order 64 bits of the fractional parts of the cube roots of the first 80 primes. */ static const U64 sha_384_512_K[80] = { 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL, 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL, 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL, 0xd807aa98a3030242ULL, 0x12835b0145706fbeULL, 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL, 0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL, 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL, 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL, 0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL, 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL, 0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, 0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL, 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL, 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL, 0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL, 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL, 0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 0x81c2c92e47edaee6ULL, 0x92722c851482353bULL, 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL, 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL, 0xd192e819d6ef5218ULL, 0xd69906245565a910ULL, 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL, 0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, 0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL, 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL, 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL, 0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL, 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL, 0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL, 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL, 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL, 0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL, 0x113f9804bef90daeULL, 0x1b710b35131c471bULL, 0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL, 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL, 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL }; __inline__ static U64 sha_384_512_s0(U64 x) { return(ROTR64(x,1)^ROTR64(x,8)^(LIMIT64(x)>>7)); } __inline__ static U64 sha_384_512_s1(U64 x) { return(ROTR64(x,19)^ROTR64(x,61)^(LIMIT64(x)>>6)); } __inline__ static U64 sha_384_512_S0(U64 x) { return(ROTR64(x,28)^ROTR64(x,34)^ROTR64(x,39)); } __inline__ static U64 sha_384_512_S1(U64 x) { return(ROTR64(x,14)^ROTR64(x,18)^ROTR64(x,41)); } static void sha_384_512_crunch_block(STATE *state) { U64 A; U64 B; U64 C; U64 D; U64 E; U64 F; U64 G; U64 H; U64 *M; U64 T1; U64 T2; int i; A = LIMIT64(state->u.sha_384_512.H[0]); B = LIMIT64(state->u.sha_384_512.H[1]); C = LIMIT64(state->u.sha_384_512.H[2]); D = LIMIT64(state->u.sha_384_512.H[3]); E = LIMIT64(state->u.sha_384_512.H[4]); F = LIMIT64(state->u.sha_384_512.H[5]); G = LIMIT64(state->u.sha_384_512.H[6]); H = LIMIT64(state->u.sha_384_512.H[7]); M = &state->u.sha_384_512.M[0]; #ifdef TRACE printf("SHA-384/SHA-512 block:\n"); for (i=0;i<16;i++) printf("M[%2d] = %016llx\n",i,(unsigned long long int)M[i]); for (i=0;i<8;i++) printf("H[%2d] = %016llx\n",i,(unsigned long long int)LIMIT64(state->u.sha_384_512.H[i])); #define MAYBE_TRACE() do {\ printf("t=%2d: %016llx %016llx %016llx %016llx\n" \ " %016llx %016llx %016llx %016llx\n",i, \ (unsigned long long int)A, (unsigned long long int)B, \ (unsigned long long int)C, (unsigned long long int)D, \ (unsigned long long int)E, (unsigned long long int)F, \ (unsigned long long int)G, (unsigned long long int)H); \ } while (0) #else #define MAYBE_TRACE() /* nothing */ #endif #define BODY() do {\ T1 = H + sha_384_512_S1(E) + SHA384512_CH(E,F,G) + \ sha_384_512_K[i] + M[i&15]; \ T2 = sha_384_512_S0(A) + SHA384512_MAJ(A,B,C); \ H = G; \ G = F; \ F = E; \ E = LIMIT64(D+T1); \ D = C; \ C = B; \ B = A; \ A = LIMIT64(T1+T2); \ MAYBE_TRACE(); \ } while (0) for (i=0;i<16;i++) BODY(); for (i=16;i<80;i++) { M[i&15] = LIMIT64( sha_384_512_s1(M[(i+14)&15]) + M[(i+9)&15] + sha_384_512_s0(M[(i+1)&15]) + M[i&15] ); BODY(); } #undef BODY #undef MAYBE_TRACE state->u.sha_384_512.H[0] += A; state->u.sha_384_512.H[1] += B; state->u.sha_384_512.H[2] += C; state->u.sha_384_512.H[3] += D; state->u.sha_384_512.H[4] += E; state->u.sha_384_512.H[5] += F; state->u.sha_384_512.H[6] += G; state->u.sha_384_512.H[7] += H; } static void sha_384_512_crunch_bytes(STATE *state, const unsigned char *buf, unsigned int nbytes) { unsigned int mfill; U64 *M; mfill = state->u.sha_384_512.mfill; M = &state->u.sha_384_512.M[0]; while (nbytes > 0) { if ((mfill == 0) && (nbytes >= 128)) { fill_u64s(buf,M,128/8); sha_384_512_crunch_block(state); buf += 128; nbytes -= 128; } else { if (((mfill % 8) == 0) && (nbytes >= 8)) { unsigned int n; n = 128 - mfill; if (n > nbytes) n = nbytes; n &= ~7; fill_u64s(buf,&M[mfill/8],n/8); buf += n; nbytes -= n; mfill += n; } else { switch (mfill % 8) { case 0: M[mfill/8] = ((U64)*buf) << 56; break; case 1: M[mfill/8] |= ((U64)*buf) << 48; break; case 2: M[mfill/8] |= ((U64)*buf) << 40; break; case 3: M[mfill/8] |= ((U64)*buf) << 32; break; case 4: M[mfill/8] |= ((U64)*buf) << 24; break; case 5: M[mfill/8] |= ((U64)*buf) << 16; break; case 6: M[mfill/8] |= ((U64)*buf) << 8; break; case 7: M[mfill/8] |= (U64)*buf ; break; } buf ++; nbytes --; mfill ++; } if (mfill >= 128) { sha_384_512_crunch_block(state); mfill = 0; } } } state->u.sha_384_512.mfill = mfill; } static int sha_384_512_state(const STATE *s, void *buf, int buflen, int destype) { int want; int blen; int i; unsigned char *bp; unsigned char ck_xor; unsigned char ck_sum; static void sb(unsigned char b) { *bp++ = b; ck_xor ^= b; ck_sum += b; } static void sb64(U64 v) { sb( v &0xff); sb((v>> 8)&0xff); sb((v>>16)&0xff); sb((v>>24)&0xff); sb((v>>32)&0xff); sb((v>>40)&0xff); sb((v>>48)&0xff); sb((v>>56)&0xff); } if (s->num != destype) { abort(); return(0); } want = 1 + 1 + 1 + 1 + 1 + ((8 + ((s->u.sha_384_512.mfill+7)/8)) * 8); if (s->u.sha_384_512.bitlen_h >> 56) blen = 16; else if (s->u.sha_384_512.bitlen_h >> 48) blen = 15; else if (s->u.sha_384_512.bitlen_h >> 40) blen = 14; else if (s->u.sha_384_512.bitlen_h >> 32) blen = 13; else if (s->u.sha_384_512.bitlen_h >> 24) blen = 12; else if (s->u.sha_384_512.bitlen_h >> 16) blen = 11; else if (s->u.sha_384_512.bitlen_h >> 8) blen = 10; else if (s->u.sha_384_512.bitlen_h ) blen = 9; else if (s->u.sha_384_512.bitlen_l >> 56) blen = 8; else if (s->u.sha_384_512.bitlen_l >> 48) blen = 7; else if (s->u.sha_384_512.bitlen_l >> 40) blen = 6; else if (s->u.sha_384_512.bitlen_l >> 32) blen = 5; else if (s->u.sha_384_512.bitlen_l >> 24) blen = 4; else if (s->u.sha_384_512.bitlen_l >> 16) blen = 3; else if (s->u.sha_384_512.bitlen_l >> 8) blen = 2; else if (s->u.sha_384_512.bitlen_l ) blen = 1; else blen = 0; want += blen + 1 + 1; if (want > buflen) return(want); bp = buf; ck_xor = 0xff; ck_sum = 0; sb(2); sb(destype); sb(want); sb(s->u.sha_384_512.mfill); sb(blen); sb64(s->u.sha_384_512.H[0]); sb64(s->u.sha_384_512.H[1]); sb64(s->u.sha_384_512.H[2]); sb64(s->u.sha_384_512.H[3]); sb64(s->u.sha_384_512.H[4]); sb64(s->u.sha_384_512.H[5]); sb64(s->u.sha_384_512.H[6]); sb64(s->u.sha_384_512.H[7]); for (i=0;iu.sha_384_512.mfill;i+=8) sb64(s->u.sha_384_512.M[i>>3]); if (blen > 0) sb( s->u.sha_384_512.bitlen_l &0xff); if (blen > 1) sb((s->u.sha_384_512.bitlen_l>> 8)&0xff); if (blen > 2) sb((s->u.sha_384_512.bitlen_l>>16)&0xff); if (blen > 3) sb((s->u.sha_384_512.bitlen_l>>24)&0xff); if (blen > 4) sb((s->u.sha_384_512.bitlen_l>>32)&0xff); if (blen > 5) sb((s->u.sha_384_512.bitlen_l>>40)&0xff); if (blen > 6) sb((s->u.sha_384_512.bitlen_l>>48)&0xff); if (blen > 7) sb((s->u.sha_384_512.bitlen_l>>56)&0xff); if (blen > 8) sb( s->u.sha_384_512.bitlen_h &0xff); if (blen > 9) sb((s->u.sha_384_512.bitlen_h>> 8)&0xff); if (blen > 10) sb((s->u.sha_384_512.bitlen_h>>16)&0xff); if (blen > 11) sb((s->u.sha_384_512.bitlen_h>>24)&0xff); if (blen > 12) sb((s->u.sha_384_512.bitlen_h>>32)&0xff); if (blen > 13) sb((s->u.sha_384_512.bitlen_h>>40)&0xff); if (blen > 14) sb((s->u.sha_384_512.bitlen_h>>48)&0xff); if (blen > 15) sb((s->u.sha_384_512.bitlen_h>>56)&0xff); i = ck_sum; sb(0xff&ck_xor); sb(0xff&i); return(want); } static int sha_384_512_set_state(STATE *s, const void *buf, int buflen, int destype) { const unsigned char *bp; int l; int mfill; int blen; int i; unsigned char ck_xor; unsigned char ck_sum; U64 bl_l; U64 bl_h; static U64 get64(void) { bp += 4; return( (((U64)bp[-1]) << 56) | (((U64)bp[-2]) << 48) | (((U64)bp[-3]) << 40) | (((U64)bp[-4]) << 32) | (((U64)bp[-5]) << 24) | (((U64)bp[-6]) << 16) | (((U64)bp[-7]) << 8) | ((U64)bp[-8]) ); } if (s->num != destype) { abort(); return(SHA_CORRUPT); } if (buflen < 1) return(SHA_CORRUPT); bp = buf; if (*bp++ != 2) return(SHA_BADVERS); if (buflen < 1+1+1+1+1+((8+((0+7)/8))*8) + 0+1+1) return(SHA_CORRUPT); if (*bp++ != destype) return(SHA_CORRUPT); l = *bp++; if (l > buflen) return(SHA_CORRUPT); mfill = *bp++; if ((mfill < 0) || (mfill > 128)) return(SHA_CORRUPT); blen = *bp++; if ((blen < 0) || (blen > 16)) return(SHA_CORRUPT); if (l != 1+1+1+1+1+((8+((mfill+7)/8))*8) + blen+1+1) return(SHA_CORRUPT); ck_xor = 0xff; ck_sum = 0; for (i=l-3;i>=0;i--) { ck_xor ^= ((const unsigned char *)buf)[i]; ck_sum += ((const unsigned char *)buf)[i]; } if (((const unsigned char *)buf)[l-2] != (0xff&ck_xor)) return(SHA_CORRUPT); if (((const unsigned char *)buf)[l-1] != (0xff&ck_sum)) return(SHA_CORRUPT); s->u.sha_384_512.mfill = mfill; s->u.sha_384_512.H[0] = get64(); s->u.sha_384_512.H[1] = get64(); s->u.sha_384_512.H[2] = get64(); s->u.sha_384_512.H[3] = get64(); s->u.sha_384_512.H[4] = get64(); s->u.sha_384_512.H[5] = get64(); s->u.sha_384_512.H[6] = get64(); s->u.sha_384_512.H[7] = get64(); for (i=0;iu.sha_384_512.M[i>>3] = get64(); bl_l = 0; bl_h = 0; for (i=blen-1;i>=0;i--) { bl_h = (bl_h << 8) | (LIMIT64(bl_l) >> 56); bl_l = (bl_l << 8) | bp[i]; } s->u.sha_384_512.bitlen_l = LIMIT64(bl_l); s->u.sha_384_512.bitlen_h = LIMIT64(bl_h); /* bp += blen; - don't bother; it's not used hereafter */ return(0); } static void sha_384_512_pad_and_length(STATE *s) { unsigned char lenbytes[16]; sha_384_512_crunch_bytes(s,(const void *)"\200",1); while (s->u.sha_384_512.mfill != 112) sha_384_512_crunch_bytes(s,(const void *)"\0",1); lenbytes[ 0] = (s->u.sha_384_512.bitlen_h >> 56) & 0xff; lenbytes[ 1] = (s->u.sha_384_512.bitlen_h >> 48) & 0xff; lenbytes[ 2] = (s->u.sha_384_512.bitlen_h >> 40) & 0xff; lenbytes[ 3] = (s->u.sha_384_512.bitlen_h >> 32) & 0xff; lenbytes[ 4] = (s->u.sha_384_512.bitlen_h >> 24) & 0xff; lenbytes[ 5] = (s->u.sha_384_512.bitlen_h >> 16) & 0xff; lenbytes[ 6] = (s->u.sha_384_512.bitlen_h >> 8) & 0xff; lenbytes[ 7] = s->u.sha_384_512.bitlen_h & 0xff; lenbytes[ 8] = (s->u.sha_384_512.bitlen_l >> 56) & 0xff; lenbytes[ 9] = (s->u.sha_384_512.bitlen_l >> 48) & 0xff; lenbytes[10] = (s->u.sha_384_512.bitlen_l >> 40) & 0xff; lenbytes[11] = (s->u.sha_384_512.bitlen_l >> 32) & 0xff; lenbytes[12] = (s->u.sha_384_512.bitlen_l >> 24) & 0xff; lenbytes[13] = (s->u.sha_384_512.bitlen_l >> 16) & 0xff; lenbytes[14] = (s->u.sha_384_512.bitlen_l >> 8) & 0xff; lenbytes[15] = s->u.sha_384_512.bitlen_l & 0xff; sha_384_512_crunch_bytes(s,&lenbytes[0],16); } void *sha512_init(void) { STATE *s; s = malloc(sizeof(STATE)); if (s == 0) return(0); s->num = NUM_SHA512; s->u.sha_384_512.H[0] = 0x6a09e667f3bcc908ULL; s->u.sha_384_512.H[1] = 0xbb67ae8584caa73bULL; s->u.sha_384_512.H[2] = 0x3c6ef372fe94f82bULL; s->u.sha_384_512.H[3] = 0xa54ff53a5f1d36f1ULL; s->u.sha_384_512.H[4] = 0x510e527fade682d1ULL; s->u.sha_384_512.H[5] = 0x9b05688c2b3e6c1fULL; s->u.sha_384_512.H[6] = 0x1f83d9abfb41bd6bULL; s->u.sha_384_512.H[7] = 0x5be0cd19137e2179ULL; s->u.sha_384_512.mfill = 0; s->u.sha_384_512.bitlen_l = 0; s->u.sha_384_512.bitlen_h = 0; return(s); } void sha512_process_bytes(void *state, const void *vbuf, unsigned int nbytes) #define s ((STATE *)state) { U64 ltmp; U64 lsum; if (s->num != NUM_SHA512) { abort(); return; } sha_384_512_crunch_bytes(s,vbuf,nbytes); s->u.sha_384_512.bitlen_h += ((U64)nbytes) >> 61; ltmp = ((U64)nbytes) << 3; lsum = ltmp + s->u.sha_384_512.bitlen_l; if ( (ltmp & s->u.sha_384_512.bitlen_l & 0x8000000000000000ULL) || ( ((ltmp|s->u.sha_384_512.bitlen_l) & 0x8000000000000000ULL) && !(lsum & 0x8000000000000000ULL) ) ) { s->u.sha_384_512.bitlen_h ++; } s->u.sha_384_512.bitlen_l = lsum; } #undef s void sha512_result(void *state, unsigned char *result) #define s ((STATE *)state) { if (s->num != NUM_SHA512) { abort(); return; } sha_384_512_pad_and_length(s); result[ 0] = (s->u.sha_384_512.H[0] >> 56) & 0xff; result[ 1] = (s->u.sha_384_512.H[0] >> 48) & 0xff; result[ 2] = (s->u.sha_384_512.H[0] >> 40) & 0xff; result[ 3] = (s->u.sha_384_512.H[0] >> 32) & 0xff; result[ 4] = (s->u.sha_384_512.H[0] >> 24) & 0xff; result[ 5] = (s->u.sha_384_512.H[0] >> 16) & 0xff; result[ 6] = (s->u.sha_384_512.H[0] >> 8) & 0xff; result[ 7] = s->u.sha_384_512.H[0] & 0xff; result[ 8] = (s->u.sha_384_512.H[1] >> 56) & 0xff; result[ 9] = (s->u.sha_384_512.H[1] >> 48) & 0xff; result[10] = (s->u.sha_384_512.H[1] >> 40) & 0xff; result[11] = (s->u.sha_384_512.H[1] >> 32) & 0xff; result[12] = (s->u.sha_384_512.H[1] >> 24) & 0xff; result[13] = (s->u.sha_384_512.H[1] >> 16) & 0xff; result[14] = (s->u.sha_384_512.H[1] >> 8) & 0xff; result[15] = s->u.sha_384_512.H[1] & 0xff; result[16] = (s->u.sha_384_512.H[2] >> 56) & 0xff; result[17] = (s->u.sha_384_512.H[2] >> 48) & 0xff; result[18] = (s->u.sha_384_512.H[2] >> 40) & 0xff; result[19] = (s->u.sha_384_512.H[2] >> 32) & 0xff; result[20] = (s->u.sha_384_512.H[2] >> 24) & 0xff; result[21] = (s->u.sha_384_512.H[2] >> 16) & 0xff; result[22] = (s->u.sha_384_512.H[2] >> 8) & 0xff; result[23] = s->u.sha_384_512.H[2] & 0xff; result[24] = (s->u.sha_384_512.H[3] >> 56) & 0xff; result[25] = (s->u.sha_384_512.H[3] >> 48) & 0xff; result[26] = (s->u.sha_384_512.H[3] >> 40) & 0xff; result[27] = (s->u.sha_384_512.H[3] >> 32) & 0xff; result[28] = (s->u.sha_384_512.H[3] >> 24) & 0xff; result[29] = (s->u.sha_384_512.H[3] >> 16) & 0xff; result[30] = (s->u.sha_384_512.H[3] >> 8) & 0xff; result[31] = s->u.sha_384_512.H[3] & 0xff; result[32] = (s->u.sha_384_512.H[4] >> 56) & 0xff; result[33] = (s->u.sha_384_512.H[4] >> 48) & 0xff; result[34] = (s->u.sha_384_512.H[4] >> 40) & 0xff; result[35] = (s->u.sha_384_512.H[4] >> 32) & 0xff; result[36] = (s->u.sha_384_512.H[4] >> 24) & 0xff; result[37] = (s->u.sha_384_512.H[4] >> 16) & 0xff; result[38] = (s->u.sha_384_512.H[4] >> 8) & 0xff; result[39] = s->u.sha_384_512.H[4] & 0xff; result[40] = (s->u.sha_384_512.H[5] >> 56) & 0xff; result[41] = (s->u.sha_384_512.H[5] >> 48) & 0xff; result[42] = (s->u.sha_384_512.H[5] >> 40) & 0xff; result[43] = (s->u.sha_384_512.H[5] >> 32) & 0xff; result[44] = (s->u.sha_384_512.H[5] >> 24) & 0xff; result[45] = (s->u.sha_384_512.H[5] >> 16) & 0xff; result[46] = (s->u.sha_384_512.H[5] >> 8) & 0xff; result[47] = s->u.sha_384_512.H[5] & 0xff; result[48] = (s->u.sha_384_512.H[6] >> 56) & 0xff; result[49] = (s->u.sha_384_512.H[6] >> 48) & 0xff; result[50] = (s->u.sha_384_512.H[6] >> 40) & 0xff; result[51] = (s->u.sha_384_512.H[6] >> 32) & 0xff; result[52] = (s->u.sha_384_512.H[6] >> 24) & 0xff; result[53] = (s->u.sha_384_512.H[6] >> 16) & 0xff; result[54] = (s->u.sha_384_512.H[6] >> 8) & 0xff; result[55] = s->u.sha_384_512.H[6] & 0xff; result[56] = (s->u.sha_384_512.H[7] >> 56) & 0xff; result[57] = (s->u.sha_384_512.H[7] >> 48) & 0xff; result[58] = (s->u.sha_384_512.H[7] >> 40) & 0xff; result[59] = (s->u.sha_384_512.H[7] >> 32) & 0xff; result[60] = (s->u.sha_384_512.H[7] >> 24) & 0xff; result[61] = (s->u.sha_384_512.H[7] >> 16) & 0xff; result[62] = (s->u.sha_384_512.H[7] >> 8) & 0xff; result[63] = s->u.sha_384_512.H[7] & 0xff; free(s); } #undef s void *sha512_clone(const void *old) #define o ((const STATE *)old) { STATE *n; if (o->num != NUM_SHA512) { abort(); return(0); } n = malloc(sizeof(STATE)); n->num = NUM_SHA512; n->u.sha_384_512 = o->u.sha_384_512; return(n); } #undef o int sha512_state(const void *state, void *buf, int buflen) { return(sha_384_512_state(state,buf,buflen,NUM_SHA512)); } int sha512_set_state(void *state, const void *buf, int buflen) { return(sha_384_512_set_state(state,buf,buflen,NUM_SHA512)); } void sha512_drop(void *state) { if (((STATE *)state)->num != NUM_SHA512) { abort(); return; } free(state); } /***************** END SHA512 *****************/ /***************** BEGIN SHA384 *****************/ void *sha384_init(void) { STATE *s; s = malloc(sizeof(STATE)); if (s == 0) return(0); s->num = NUM_SHA384; s->u.sha_384_512.H[0] = 0xcbbb9d5dc1059ed8ULL; s->u.sha_384_512.H[1] = 0x629a292a367cd507ULL; s->u.sha_384_512.H[2] = 0x9159015a3070dd17ULL; s->u.sha_384_512.H[3] = 0x152fecd8f70e5939ULL; s->u.sha_384_512.H[4] = 0x67332667ffc00b31ULL; s->u.sha_384_512.H[5] = 0x8eb44a8768581511ULL; s->u.sha_384_512.H[6] = 0xdb0c2e0d64f98fa7ULL; s->u.sha_384_512.H[7] = 0x47b5481dbefa4fa4ULL; s->u.sha_384_512.mfill = 0; s->u.sha_384_512.bitlen_l = 0; s->u.sha_384_512.bitlen_h = 0; return(s); } void sha384_process_bytes(void *state, const void *vbuf, unsigned int nbytes) #define s ((STATE *)state) { U64 ltmp; U64 lsum; if (s->num != NUM_SHA384) { abort(); return; } sha_384_512_crunch_bytes(s,vbuf,nbytes); s->u.sha_384_512.bitlen_h += ((U64)nbytes) >> 61; ltmp = ((U64)nbytes) << 3; lsum = ltmp + s->u.sha_384_512.bitlen_l; if ( (ltmp & s->u.sha_384_512.bitlen_l & 0x8000000000000000ULL) || ( ((ltmp|s->u.sha_384_512.bitlen_l) & 0x8000000000000000ULL) && !(lsum & 0x8000000000000000ULL) ) ) { s->u.sha_384_512.bitlen_h ++; } s->u.sha_384_512.bitlen_l = lsum; } #undef s void sha384_result(void *state, unsigned char *result) #define s ((STATE *)state) { if (s->num != NUM_SHA384) { abort(); return; } sha_384_512_pad_and_length(s); result[ 0] = (s->u.sha_384_512.H[0] >> 56) & 0xff; result[ 1] = (s->u.sha_384_512.H[0] >> 48) & 0xff; result[ 2] = (s->u.sha_384_512.H[0] >> 40) & 0xff; result[ 3] = (s->u.sha_384_512.H[0] >> 32) & 0xff; result[ 4] = (s->u.sha_384_512.H[0] >> 24) & 0xff; result[ 5] = (s->u.sha_384_512.H[0] >> 16) & 0xff; result[ 6] = (s->u.sha_384_512.H[0] >> 8) & 0xff; result[ 7] = s->u.sha_384_512.H[0] & 0xff; result[ 8] = (s->u.sha_384_512.H[1] >> 56) & 0xff; result[ 9] = (s->u.sha_384_512.H[1] >> 48) & 0xff; result[10] = (s->u.sha_384_512.H[1] >> 40) & 0xff; result[11] = (s->u.sha_384_512.H[1] >> 32) & 0xff; result[12] = (s->u.sha_384_512.H[1] >> 24) & 0xff; result[13] = (s->u.sha_384_512.H[1] >> 16) & 0xff; result[14] = (s->u.sha_384_512.H[1] >> 8) & 0xff; result[15] = s->u.sha_384_512.H[1] & 0xff; result[16] = (s->u.sha_384_512.H[2] >> 56) & 0xff; result[17] = (s->u.sha_384_512.H[2] >> 48) & 0xff; result[18] = (s->u.sha_384_512.H[2] >> 40) & 0xff; result[19] = (s->u.sha_384_512.H[2] >> 32) & 0xff; result[20] = (s->u.sha_384_512.H[2] >> 24) & 0xff; result[21] = (s->u.sha_384_512.H[2] >> 16) & 0xff; result[22] = (s->u.sha_384_512.H[2] >> 8) & 0xff; result[23] = s->u.sha_384_512.H[2] & 0xff; result[24] = (s->u.sha_384_512.H[3] >> 56) & 0xff; result[25] = (s->u.sha_384_512.H[3] >> 48) & 0xff; result[26] = (s->u.sha_384_512.H[3] >> 40) & 0xff; result[27] = (s->u.sha_384_512.H[3] >> 32) & 0xff; result[28] = (s->u.sha_384_512.H[3] >> 24) & 0xff; result[29] = (s->u.sha_384_512.H[3] >> 16) & 0xff; result[30] = (s->u.sha_384_512.H[3] >> 8) & 0xff; result[31] = s->u.sha_384_512.H[3] & 0xff; result[32] = (s->u.sha_384_512.H[4] >> 56) & 0xff; result[33] = (s->u.sha_384_512.H[4] >> 48) & 0xff; result[34] = (s->u.sha_384_512.H[4] >> 40) & 0xff; result[35] = (s->u.sha_384_512.H[4] >> 32) & 0xff; result[36] = (s->u.sha_384_512.H[4] >> 24) & 0xff; result[37] = (s->u.sha_384_512.H[4] >> 16) & 0xff; result[38] = (s->u.sha_384_512.H[4] >> 8) & 0xff; result[39] = s->u.sha_384_512.H[4] & 0xff; result[40] = (s->u.sha_384_512.H[5] >> 56) & 0xff; result[41] = (s->u.sha_384_512.H[5] >> 48) & 0xff; result[42] = (s->u.sha_384_512.H[5] >> 40) & 0xff; result[43] = (s->u.sha_384_512.H[5] >> 32) & 0xff; result[44] = (s->u.sha_384_512.H[5] >> 24) & 0xff; result[45] = (s->u.sha_384_512.H[5] >> 16) & 0xff; result[46] = (s->u.sha_384_512.H[5] >> 8) & 0xff; result[47] = s->u.sha_384_512.H[5] & 0xff; free(s); } #undef s void *sha384_clone(const void *old) #define o ((const STATE *)old) { STATE *n; if (o->num != NUM_SHA384) { abort(); return(0); } n = malloc(sizeof(STATE)); n->num = NUM_SHA384; n->u.sha_384_512 = o->u.sha_384_512; return(n); } #undef o int sha384_state(const void *state, void *buf, int buflen) { return(sha_384_512_state(state,buf,buflen,NUM_SHA384)); } int sha384_set_state(void *state, const void *buf, int buflen) { return(sha_384_512_set_state(state,buf,buflen,NUM_SHA384)); } void sha384_drop(void *state) { if (((STATE *)state)->num != NUM_SHA384) { abort(); return; } free(state); } /***************** END SHA384 *****************/ /***************** BEGIN generics *****************/ void *shaX_init(int num) { switch (num) { case 0: return(sha_init()); break; case 1: return(sha1_init()); break; case 256: return(sha256_init()); break; case 384: return(sha384_init()); break; case 512: return(sha512_init()); break; } return(0); } int shaX_number(const void *state) { switch (((const STATE *)state)->num) { case NUM_SHA: return(0); break; case NUM_SHA1: return(1); break; case NUM_SHA256: return(256); break; case NUM_SHA384: return(384); break; case NUM_SHA512: return(512); break; } abort(); } int shaX_hashsize(const void *state) { switch (((const STATE *)state)->num) { case NUM_SHA: return(20); break; case NUM_SHA1: return(20); break; case NUM_SHA256: return(32); break; case NUM_SHA384: return(48); break; case NUM_SHA512: return(64); break; } abort(); } int shaX_max_hashsize(void) { return(64); } void shaX_process_bytes(void *state, const void *buf, unsigned int buflen) { switch (((STATE *)state)->num) { case NUM_SHA: sha_process_bytes(state,buf,buflen); return; break; case NUM_SHA1: sha1_process_bytes(state,buf,buflen); return; break; case NUM_SHA256: sha256_process_bytes(state,buf,buflen); return; break; case NUM_SHA384: sha384_process_bytes(state,buf,buflen); return; break; case NUM_SHA512: sha512_process_bytes(state,buf,buflen); return; break; } abort(); } void shaX_result(void *state, unsigned char *buf) { switch (((STATE *)state)->num) { case NUM_SHA: sha_result(state,buf); return; break; case NUM_SHA1: sha1_result(state,buf); return; break; case NUM_SHA256: sha256_result(state,buf); return; break; case NUM_SHA384: sha384_result(state,buf); return; break; case NUM_SHA512: sha512_result(state,buf); return; break; } abort(); } void *shaX_clone(const void *state) { switch (((const STATE *)state)->num) { case NUM_SHA: return(sha_clone(state)); break; case NUM_SHA1: return(sha1_clone(state)); break; case NUM_SHA256: return(sha256_clone(state)); break; case NUM_SHA384: return(sha384_clone(state)); break; case NUM_SHA512: return(sha512_clone(state)); break; } abort(); } int shaX_state(const void *state, void *buf, int buflen) { switch (((const STATE *)state)->num) { case NUM_SHA: return(sha_state(state,buf,buflen)); break; case NUM_SHA1: return(sha1_state(state,buf,buflen)); break; case NUM_SHA256: return(sha256_state(state,buf,buflen)); break; case NUM_SHA384: return(sha384_state(state,buf,buflen)); break; case NUM_SHA512: return(sha512_state(state,buf,buflen)); break; } abort(); } int shaX_set_state(void *state, const void *buf, int buflen) { const unsigned char *bp; int t; if (buflen < 1) return(SHA_CORRUPT); bp = buf; if (*bp++ != 2) return(SHA_BADVERS); if (buflen < 2) return(SHA_CORRUPT); t = *bp++; switch (t) { case NUM_SHA: ((STATE *)state)->num = NUM_SHA; return(sha_set_state(state,buf,buflen)); break; case NUM_SHA1: ((STATE *)state)->num = NUM_SHA1; return(sha1_set_state(state,buf,buflen)); break; case NUM_SHA256: ((STATE *)state)->num = NUM_SHA256; return(sha256_set_state(state,buf,buflen)); break; case NUM_SHA384: ((STATE *)state)->num = NUM_SHA384; return(sha384_set_state(state,buf,buflen)); break; case NUM_SHA512: ((STATE *)state)->num = NUM_SHA512; return(sha512_set_state(state,buf,buflen)); break; } return(SHA_CORRUPT); } void shaX_drop(void *state) { switch (((STATE *)state)->num) { case NUM_SHA: case NUM_SHA1: case NUM_SHA256: case NUM_SHA384: case NUM_SHA512: free(state); return; } abort(); } /***************** END generics *****************/