From: Nicholas Clark Date: Sun, 8 Jan 2006 08:28:29 +0000 (+0000) Subject: Add missing files in ext/Digest/SHA/src that somehow escaped the net. X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=0512892892c4fd0ef65b4790f3fe0b366846424d;p=p5sagit%2Fp5-mst-13.2.git Add missing files in ext/Digest/SHA/src that somehow escaped the net. p4raw-id: //depot/perl@26705 --- diff --git a/ext/Digest/SHA/src/hmac.c b/ext/Digest/SHA/src/hmac.c new file mode 100644 index 0000000..19d999b --- /dev/null +++ b/ext/Digest/SHA/src/hmac.c @@ -0,0 +1,114 @@ +/* + * hmac.c: routines to compute HMAC-SHA-1/224/256/384/512 digests + * + * Ref: FIPS PUB 198 The Keyed-Hash Message Authentication Code + * + * Copyright (C) 2003-2005 Mark Shelor, All Rights Reserved + * + * Version: 5.32 + * Fri Dec 2 02:32:20 MST 2005 + * + */ + +#include +#include +#include +#include "hmac.h" +#include "sha.h" + +/* hmacopen: creates a new HMAC-SHA digest object */ +HMAC *hmacopen(alg, key, keylen) +int alg; +unsigned char *key; +unsigned int keylen; +{ + unsigned int i; + HMAC *h; + + SHA_newz(0, h, 1, HMAC); + if (h == NULL) + return(NULL); + if ((h->isha = shaopen(alg)) == NULL) { + SHA_free(h); + return(NULL); + } + if ((h->osha = shaopen(alg)) == NULL) { + shaclose(h->isha); + SHA_free(h); + return(NULL); + } + if (keylen <= h->osha->blocksize / 8) + memcpy(h->key, key, keylen); + else { + if ((h->ksha = shaopen(alg)) == NULL) { + shaclose(h->isha); + shaclose(h->osha); + SHA_free(h); + return(NULL); + } + shawrite(key, keylen * 8, h->ksha); + shafinish(h->ksha); + memcpy(h->key, shadigest(h->ksha), h->ksha->digestlen); + shaclose(h->ksha); + } + for (i = 0; i < h->osha->blocksize / 8; i++) + h->key[i] ^= 0x5c; + shawrite(h->key, h->osha->blocksize, h->osha); + for (i = 0; i < h->isha->blocksize / 8; i++) + h->key[i] ^= (0x5c ^ 0x36); + shawrite(h->key, h->isha->blocksize, h->isha); + memset(h->key, 0, sizeof(h->key)); + return(h); +} + +/* hmacwrite: triggers a state update using data in bitstr/bitcnt */ +unsigned long hmacwrite(bitstr, bitcnt, h) +unsigned char *bitstr; +unsigned long bitcnt; +HMAC *h; +{ + return(shawrite(bitstr, bitcnt, h->isha)); +} + +/* hmacfinish: computes final digest state */ +void hmacfinish(h) +HMAC *h; +{ + shafinish(h->isha); + shawrite(shadigest(h->isha), h->isha->digestlen * 8, h->osha); + shaclose(h->isha); + shafinish(h->osha); +} + +/* hmacdigest: returns pointer to digest (binary) */ +unsigned char *hmacdigest(h) +HMAC *h; +{ + return(shadigest(h->osha)); +} + +/* hmachex: returns pointer to digest (hexadecimal) */ +char *hmachex(h) +HMAC *h; +{ + return(shahex(h->osha)); +} + +/* hmacbase64: returns pointer to digest (Base 64) */ +char *hmacbase64(h) +HMAC *h; +{ + return(shabase64(h->osha)); +} + +/* hmacclose: de-allocates digest object */ +int hmacclose(h) +HMAC *h; +{ + shaclose(h->osha); + if (h != NULL) { + memset(h, 0, sizeof(HMAC)); + SHA_free(h); + } + return(0); +} diff --git a/ext/Digest/SHA/src/hmac.h b/ext/Digest/SHA/src/hmac.h new file mode 100644 index 0000000..639c46f --- /dev/null +++ b/ext/Digest/SHA/src/hmac.h @@ -0,0 +1,60 @@ +/* + * hmac.h: header file for HMAC-SHA-1/224/256/384/512 routines + * + * Ref: FIPS PUB 198 The Keyed-Hash Message Authentication Code + * + * Copyright (C) 2003-2005 Mark Shelor, All Rights Reserved + * + * Version: 5.32 + * Fri Dec 2 02:32:20 MST 2005 + * + */ + +#ifndef _INCLUDE_HMAC_H_ +#define _INCLUDE_HMAC_H_ + +#include "sha.h" + +typedef struct { + SHA *ksha; + SHA *isha; + SHA *osha; + unsigned char key[SHA_MAX_BLOCK_BITS/8]; +} HMAC; + +#if defined(__STDC__) && __STDC__ != 0 + #define _HMAC_P(protos) protos +#else + #define _HMAC_P(protos) () +#endif + +#define _HMAC_STATE HMAC *h +#define _HMAC_ALG int alg +#define _HMAC_DATA unsigned char *bitstr, unsigned long bitcnt +#define _HMAC_KEY unsigned char *key, unsigned int keylen + +HMAC *hmacopen _HMAC_P((_HMAC_ALG, _HMAC_KEY)); +unsigned long hmacwrite _HMAC_P((_HMAC_DATA, _HMAC_STATE)); +void hmacfinish _HMAC_P((_HMAC_STATE)); +unsigned char *hmacdigest _HMAC_P((_HMAC_STATE)); +char *hmachex _HMAC_P((_HMAC_STATE)); +char *hmacbase64 _HMAC_P((_HMAC_STATE)); +int hmacclose _HMAC_P((_HMAC_STATE)); + +unsigned char *hmac1digest _HMAC_P((_HMAC_DATA, _HMAC_KEY)); +char *hmac1hex _HMAC_P((_HMAC_DATA, _HMAC_KEY)); +char *hmac1base64 _HMAC_P((_HMAC_DATA, _HMAC_KEY)); +unsigned char *hmac224digest _HMAC_P((_HMAC_DATA, _HMAC_KEY)); +char *hmac224hex _HMAC_P((_HMAC_DATA, _HMAC_KEY)); +char *hmac224base64 _HMAC_P((_HMAC_DATA, _HMAC_KEY)); +unsigned char *hmac256digest _HMAC_P((_HMAC_DATA, _HMAC_KEY)); +char *hmac256hex _HMAC_P((_HMAC_DATA, _HMAC_KEY)); +char *hmac256base64 _HMAC_P((_HMAC_DATA, _HMAC_KEY)); +unsigned char *hmac384digest _HMAC_P((_HMAC_DATA, _HMAC_KEY)); +char *hmac384hex _HMAC_P((_HMAC_DATA, _HMAC_KEY)); +char *hmac384base64 _HMAC_P((_HMAC_DATA, _HMAC_KEY)); +unsigned char *hmac512digest _HMAC_P((_HMAC_DATA, _HMAC_KEY)); +char *hmac512hex _HMAC_P((_HMAC_DATA, _HMAC_KEY)); +char *hmac512base64 _HMAC_P((_HMAC_DATA, _HMAC_KEY)); + +#endif /* _INCLUDE_HMAC_H_ */ diff --git a/ext/Digest/SHA/src/hmacxtra.c b/ext/Digest/SHA/src/hmacxtra.c new file mode 100644 index 0000000..35a36ed --- /dev/null +++ b/ext/Digest/SHA/src/hmacxtra.c @@ -0,0 +1,62 @@ +#include +#include +#include "hmac.h" + +static unsigned char *hmaccomp(alg, fmt, bitstr, bitcnt, key, keylen) +int alg; +int fmt; +unsigned char *bitstr; +unsigned long bitcnt; +unsigned char *key; +unsigned int keylen; +{ + HMAC *h; + static unsigned char digest[SHA_MAX_HEX_LEN+1]; + unsigned char *ret = digest; + + if ((h = hmacopen(alg, key, keylen)) == NULL) + return(NULL); + hmacwrite(bitstr, bitcnt, h); + hmacfinish(h); + if (fmt == SHA_FMT_RAW) + memcpy(digest, hmacdigest(h), h->osha->digestlen); + else if (fmt == SHA_FMT_HEX) + strcpy((char *) digest, hmachex(h)); + else if (fmt == SHA_FMT_BASE64) + strcpy((char *) digest, hmacbase64(h)); + else + ret = NULL; + hmacclose(h); + return(ret); +} + +#define HMAC_DIRECT(type, name, alg, fmt) \ +type name(bitstr, bitcnt, key, keylen) \ +unsigned char *bitstr; \ +unsigned long bitcnt; \ +unsigned char *key; \ +unsigned int keylen; \ +{ \ + return((type) hmaccomp(alg, fmt, bitstr, bitcnt, \ + key, keylen)); \ +} + +HMAC_DIRECT(unsigned char *, hmac1digest, SHA1, SHA_FMT_RAW) +HMAC_DIRECT(char *, hmac1hex, SHA1, SHA_FMT_HEX) +HMAC_DIRECT(char *, hmac1base64, SHA1, SHA_FMT_BASE64) + +HMAC_DIRECT(unsigned char *, hmac224digest, SHA224, SHA_FMT_RAW) +HMAC_DIRECT(char *, hmac224hex, SHA224, SHA_FMT_HEX) +HMAC_DIRECT(char *, hmac224base64, SHA224, SHA_FMT_BASE64) + +HMAC_DIRECT(unsigned char *, hmac256digest, SHA256, SHA_FMT_RAW) +HMAC_DIRECT(char *, hmac256hex, SHA256, SHA_FMT_HEX) +HMAC_DIRECT(char *, hmac256base64, SHA256, SHA_FMT_BASE64) + +HMAC_DIRECT(unsigned char *, hmac384digest, SHA384, SHA_FMT_RAW) +HMAC_DIRECT(char *, hmac384hex, SHA384, SHA_FMT_HEX) +HMAC_DIRECT(char *, hmac384base64, SHA384, SHA_FMT_BASE64) + +HMAC_DIRECT(unsigned char *, hmac512digest, SHA512, SHA_FMT_RAW) +HMAC_DIRECT(char *, hmac512hex, SHA512, SHA_FMT_HEX) +HMAC_DIRECT(char *, hmac512base64, SHA512, SHA_FMT_BASE64) diff --git a/ext/Digest/SHA/src/sha.c b/ext/Digest/SHA/src/sha.c new file mode 100644 index 0000000..9fb7775 --- /dev/null +++ b/ext/Digest/SHA/src/sha.c @@ -0,0 +1,682 @@ +/* + * sha.c: routines to compute SHA-1/224/256/384/512 digests + * + * Ref: NIST FIPS PUB 180-2 Secure Hash Standard + * + * Copyright (C) 2003-2005 Mark Shelor, All Rights Reserved + * + * Version: 5.32 + * Fri Dec 2 02:32:20 MST 2005 + * + */ + +#include +#include +#include +#include +#include +#include "sha.h" +#include "sha64bit.h" + +#define W32 SHA32 /* useful abbreviations */ +#define C32 SHA32_CONST +#define SR32 SHA32_SHR +#define SL32 SHA32_SHL +#define LO32 SHA_LO32 +#define UCHR unsigned char +#define UINT unsigned int +#define ULNG unsigned long +#define VP void * + +#define ROTR(x, n) (SR32(x, n) | SL32(x, 32-(n))) +#define ROTL(x, n) (SL32(x, n) | SR32(x, 32-(n))) + +#define Ch(x, y, z) ((z) ^ ((x) & ((y) ^ (z)))) +#define Pa(x, y, z) ((x) ^ (y) ^ (z)) +#define Ma(x, y, z) (((x) & (y)) | ((z) & ((x) | (y)))) + +#define SIGMA0(x) (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22)) +#define SIGMA1(x) (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25)) +#define sigma0(x) (ROTR(x, 7) ^ ROTR(x, 18) ^ SR32(x, 3)) +#define sigma1(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ SR32(x, 10)) + +#define K1 C32(0x5a827999) /* SHA-1 constants */ +#define K2 C32(0x6ed9eba1) +#define K3 C32(0x8f1bbcdc) +#define K4 C32(0xca62c1d6) + +static W32 K256[64] = /* SHA-224/256 constants */ +{ + C32(0x428a2f98), C32(0x71374491), C32(0xb5c0fbcf), C32(0xe9b5dba5), + C32(0x3956c25b), C32(0x59f111f1), C32(0x923f82a4), C32(0xab1c5ed5), + C32(0xd807aa98), C32(0x12835b01), C32(0x243185be), C32(0x550c7dc3), + C32(0x72be5d74), C32(0x80deb1fe), C32(0x9bdc06a7), C32(0xc19bf174), + C32(0xe49b69c1), C32(0xefbe4786), C32(0x0fc19dc6), C32(0x240ca1cc), + C32(0x2de92c6f), C32(0x4a7484aa), C32(0x5cb0a9dc), C32(0x76f988da), + C32(0x983e5152), C32(0xa831c66d), C32(0xb00327c8), C32(0xbf597fc7), + C32(0xc6e00bf3), C32(0xd5a79147), C32(0x06ca6351), C32(0x14292967), + C32(0x27b70a85), C32(0x2e1b2138), C32(0x4d2c6dfc), C32(0x53380d13), + C32(0x650a7354), C32(0x766a0abb), C32(0x81c2c92e), C32(0x92722c85), + C32(0xa2bfe8a1), C32(0xa81a664b), C32(0xc24b8b70), C32(0xc76c51a3), + C32(0xd192e819), C32(0xd6990624), C32(0xf40e3585), C32(0x106aa070), + C32(0x19a4c116), C32(0x1e376c08), C32(0x2748774c), C32(0x34b0bcb5), + C32(0x391c0cb3), C32(0x4ed8aa4a), C32(0x5b9cca4f), C32(0x682e6ff3), + C32(0x748f82ee), C32(0x78a5636f), C32(0x84c87814), C32(0x8cc70208), + C32(0x90befffa), C32(0xa4506ceb), C32(0xbef9a3f7), C32(0xc67178f2) +}; + +static W32 H01[5] = /* SHA-1 initial hash value */ +{ + C32(0x67452301), C32(0xefcdab89), C32(0x98badcfe), + C32(0x10325476), C32(0xc3d2e1f0) +}; + +static W32 H0224[8] = /* SHA-224 initial hash value */ +{ + C32(0xc1059ed8), C32(0x367cd507), C32(0x3070dd17), C32(0xf70e5939), + C32(0xffc00b31), C32(0x68581511), C32(0x64f98fa7), C32(0xbefa4fa4) +}; + +static W32 H0256[8] = /* SHA-256 initial hash value */ +{ + C32(0x6a09e667), C32(0xbb67ae85), C32(0x3c6ef372), C32(0xa54ff53a), + C32(0x510e527f), C32(0x9b05688c), C32(0x1f83d9ab), C32(0x5be0cd19) +}; + +static void sha1(s, block) /* SHA-1 transform */ +SHA *s; +UCHR *block; +{ + W32 a, b, c, d, e; + SHA_STO_CLASS W32 W[16]; + W32 *wp = W; + W32 *H = (W32 *) s->H; + + SHA32_SCHED(W, block); + +/* + * Use SHA-1 alternate method from FIPS PUB 180-2 (ref. 6.1.3) + * + * To improve performance, unroll the loop and consolidate assignments + * by changing the roles of variables "a" through "e" at each step. + * Note that the variable "T" is no longer needed. + */ + +#define M1(a, b, c, d, e, f, k, w) \ + e += ROTL(a, 5) + f(b, c, d) + k + w; \ + b = ROTL(b, 30) + +#define M11(f, k, w) M1(a, b, c, d, e, f, k, w); +#define M12(f, k, w) M1(e, a, b, c, d, f, k, w); +#define M13(f, k, w) M1(d, e, a, b, c, f, k, w); +#define M14(f, k, w) M1(c, d, e, a, b, f, k, w); +#define M15(f, k, w) M1(b, c, d, e, a, f, k, w); + +#define W11(s) W[(s+ 0) & 0xf] +#define W12(s) W[(s+13) & 0xf] +#define W13(s) W[(s+ 8) & 0xf] +#define W14(s) W[(s+ 2) & 0xf] + +#define A1(s) (W11(s) = ROTL(W11(s) ^ W12(s) ^ W13(s) ^ W14(s), 1)) + + a = H[0]; b = H[1]; c = H[2]; d = H[3]; e = H[4]; + + M11(Ch, K1, *wp++); M12(Ch, K1, *wp++); M13(Ch, K1, *wp++); + M14(Ch, K1, *wp++); M15(Ch, K1, *wp++); M11(Ch, K1, *wp++); + M12(Ch, K1, *wp++); M13(Ch, K1, *wp++); M14(Ch, K1, *wp++); + M15(Ch, K1, *wp++); M11(Ch, K1, *wp++); M12(Ch, K1, *wp++); + M13(Ch, K1, *wp++); M14(Ch, K1, *wp++); M15(Ch, K1, *wp++); + M11(Ch, K1, *wp ); M12(Ch, K1, A1( 0)); M13(Ch, K1, A1( 1)); + M14(Ch, K1, A1( 2)); M15(Ch, K1, A1( 3)); M11(Pa, K2, A1( 4)); + M12(Pa, K2, A1( 5)); M13(Pa, K2, A1( 6)); M14(Pa, K2, A1( 7)); + M15(Pa, K2, A1( 8)); M11(Pa, K2, A1( 9)); M12(Pa, K2, A1(10)); + M13(Pa, K2, A1(11)); M14(Pa, K2, A1(12)); M15(Pa, K2, A1(13)); + M11(Pa, K2, A1(14)); M12(Pa, K2, A1(15)); M13(Pa, K2, A1( 0)); + M14(Pa, K2, A1( 1)); M15(Pa, K2, A1( 2)); M11(Pa, K2, A1( 3)); + M12(Pa, K2, A1( 4)); M13(Pa, K2, A1( 5)); M14(Pa, K2, A1( 6)); + M15(Pa, K2, A1( 7)); M11(Ma, K3, A1( 8)); M12(Ma, K3, A1( 9)); + M13(Ma, K3, A1(10)); M14(Ma, K3, A1(11)); M15(Ma, K3, A1(12)); + M11(Ma, K3, A1(13)); M12(Ma, K3, A1(14)); M13(Ma, K3, A1(15)); + M14(Ma, K3, A1( 0)); M15(Ma, K3, A1( 1)); M11(Ma, K3, A1( 2)); + M12(Ma, K3, A1( 3)); M13(Ma, K3, A1( 4)); M14(Ma, K3, A1( 5)); + M15(Ma, K3, A1( 6)); M11(Ma, K3, A1( 7)); M12(Ma, K3, A1( 8)); + M13(Ma, K3, A1( 9)); M14(Ma, K3, A1(10)); M15(Ma, K3, A1(11)); + M11(Pa, K4, A1(12)); M12(Pa, K4, A1(13)); M13(Pa, K4, A1(14)); + M14(Pa, K4, A1(15)); M15(Pa, K4, A1( 0)); M11(Pa, K4, A1( 1)); + M12(Pa, K4, A1( 2)); M13(Pa, K4, A1( 3)); M14(Pa, K4, A1( 4)); + M15(Pa, K4, A1( 5)); M11(Pa, K4, A1( 6)); M12(Pa, K4, A1( 7)); + M13(Pa, K4, A1( 8)); M14(Pa, K4, A1( 9)); M15(Pa, K4, A1(10)); + M11(Pa, K4, A1(11)); M12(Pa, K4, A1(12)); M13(Pa, K4, A1(13)); + M14(Pa, K4, A1(14)); M15(Pa, K4, A1(15)); + + H[0] += a; H[1] += b; H[2] += c; H[3] += d; H[4] += e; +} + +static void sha256(s, block) /* SHA-224/256 transform */ +SHA *s; +UCHR *block; +{ + W32 a, b, c, d, e, f, g, h, T1; + SHA_STO_CLASS W32 W[16]; + W32 *kp = K256; + W32 *wp = W; + W32 *H = (W32 *) s->H; + + SHA32_SCHED(W, block); + +/* + * Use same technique as in sha1() + * + * To improve performance, unroll the loop and consolidate assignments + * by changing the roles of variables "a" through "h" at each step. + * Note that the variable "T2" is no longer needed. + */ + +#define M2(a, b, c, d, e, f, g, h, w) \ + T1 = h + SIGMA1(e) + Ch(e, f, g) + (*kp++) + w; \ + h = T1 + SIGMA0(a) + Ma(a, b, c); d += T1; + +#define W21(s) W[(s+ 0) & 0xf] +#define W22(s) W[(s+14) & 0xf] +#define W23(s) W[(s+ 9) & 0xf] +#define W24(s) W[(s+ 1) & 0xf] + +#define A2(s) (W21(s) += sigma1(W22(s)) + W23(s) + sigma0(W24(s))) + +#define M21(w) M2(a, b, c, d, e, f, g, h, w) +#define M22(w) M2(h, a, b, c, d, e, f, g, w) +#define M23(w) M2(g, h, a, b, c, d, e, f, w) +#define M24(w) M2(f, g, h, a, b, c, d, e, w) +#define M25(w) M2(e, f, g, h, a, b, c, d, w) +#define M26(w) M2(d, e, f, g, h, a, b, c, w) +#define M27(w) M2(c, d, e, f, g, h, a, b, w) +#define M28(w) M2(b, c, d, e, f, g, h, a, w) + + a = H[0]; b = H[1]; c = H[2]; d = H[3]; + e = H[4]; f = H[5]; g = H[6]; h = H[7]; + + M21( *wp++); M22( *wp++); M23( *wp++); M24( *wp++); + M25( *wp++); M26( *wp++); M27( *wp++); M28( *wp++); + M21( *wp++); M22( *wp++); M23( *wp++); M24( *wp++); + M25( *wp++); M26( *wp++); M27( *wp++); M28( *wp ); + M21(A2( 0)); M22(A2( 1)); M23(A2( 2)); M24(A2( 3)); + M25(A2( 4)); M26(A2( 5)); M27(A2( 6)); M28(A2( 7)); + M21(A2( 8)); M22(A2( 9)); M23(A2(10)); M24(A2(11)); + M25(A2(12)); M26(A2(13)); M27(A2(14)); M28(A2(15)); + M21(A2( 0)); M22(A2( 1)); M23(A2( 2)); M24(A2( 3)); + M25(A2( 4)); M26(A2( 5)); M27(A2( 6)); M28(A2( 7)); + M21(A2( 8)); M22(A2( 9)); M23(A2(10)); M24(A2(11)); + M25(A2(12)); M26(A2(13)); M27(A2(14)); M28(A2(15)); + M21(A2( 0)); M22(A2( 1)); M23(A2( 2)); M24(A2( 3)); + M25(A2( 4)); M26(A2( 5)); M27(A2( 6)); M28(A2( 7)); + M21(A2( 8)); M22(A2( 9)); M23(A2(10)); M24(A2(11)); + M25(A2(12)); M26(A2(13)); M27(A2(14)); M28(A2(15)); + + H[0] += a; H[1] += b; H[2] += c; H[3] += d; + H[4] += e; H[5] += f; H[6] += g; H[7] += h; +} + +#include "sha64bit.c" + +#define SETBIT(s, pos) s[(pos) >> 3] |= (0x01 << (7 - (pos) % 8)) +#define CLRBIT(s, pos) s[(pos) >> 3] &= ~(0x01 << (7 - (pos) % 8)) +#define NBYTES(nbits) ((nbits) > 0 ? 1 + (((nbits) - 1) >> 3) : 0) +#define HEXLEN(nbytes) ((nbytes) << 1) +#define B64LEN(nbytes) (((nbytes) % 3 == 0) ? ((nbytes) / 3) * 4 \ + : ((nbytes) / 3) * 4 + ((nbytes) % 3) + 1) + +/* w32mem: writes 32-bit word to memory in big-endian order */ +static void w32mem(mem, w32) +UCHR *mem; +W32 w32; +{ + int i; + + for (i = 0; i < 4; i++) + *mem++ = (UCHR) (SR32(w32, 24-i*8) & 0xff); +} + +/* digcpy: writes current state to digest buffer */ +static void digcpy(s) +SHA *s; +{ + UINT i; + UCHR *d = s->digest; + W32 *p32 = (W32 *) s->H; + W64 *p64 = (W64 *) s->H; + + if (s->alg <= SHA256) + for (i = 0; i < 8; i++, d += 4) + w32mem(d, *p32++); + else + for (i = 0; i < 8; i++, d += 8) { + w32mem(d, (W32) ((*p64 >> 16) >> 16)); + w32mem(d+4, (W32) (*p64++ & SHA32_MAX)); + } +} + +#define SHA_INIT(algo, transform) \ + do { \ + memset(s, 0, sizeof(SHA)); \ + s->alg = algo; s->sha = sha ## transform; \ + memcpy(s->H, H0 ## algo, sizeof(H0 ## algo)); \ + s->blocksize = SHA ## algo ## _BLOCK_BITS; \ + s->digestlen = SHA ## algo ## _DIGEST_BITS >> 3; \ + } while (0) + +/* sharewind: re-initializes the digest object */ +void sharewind(s) +SHA *s; +{ + if (s->alg == SHA1) SHA_INIT(1, 1); + else if (s->alg == SHA224) SHA_INIT(224, 256); + else if (s->alg == SHA256) SHA_INIT(256, 256); + else if (s->alg == SHA384) SHA_INIT(384, 512); + else if (s->alg == SHA512) SHA_INIT(512, 512); +} + +/* shaopen: creates a new digest object */ +SHA *shaopen(alg) +int alg; +{ + SHA *s; + + if (alg != SHA1 && alg != SHA224 && alg != SHA256 && + alg != SHA384 && alg != SHA512) + return(NULL); + if (alg >= SHA384 && !sha_384_512) + return(NULL); + SHA_newz(0, s, 1, SHA); + if (s == NULL) + return(NULL); + s->alg = alg; + sharewind(s); + return(s); +} + +/* shadirect: updates state directly (w/o going through s->block) */ +static ULNG shadirect(bitstr, bitcnt, s) +UCHR *bitstr; +ULNG bitcnt; +SHA *s; +{ + ULNG savecnt = bitcnt; + + while (bitcnt >= s->blocksize) { + s->sha(s, bitstr); + bitstr += (s->blocksize >> 3); + bitcnt -= s->blocksize; + } + if (bitcnt > 0) { + memcpy(s->block, bitstr, NBYTES(bitcnt)); + s->blockcnt = bitcnt; + } + return(savecnt); +} + +/* shabytes: updates state for byte-aligned input data */ +static ULNG shabytes(bitstr, bitcnt, s) +UCHR *bitstr; +ULNG bitcnt; +SHA *s; +{ + UINT offset; + UINT nbits; + ULNG savecnt = bitcnt; + + offset = s->blockcnt >> 3; + if (s->blockcnt + bitcnt >= s->blocksize) { + nbits = s->blocksize - s->blockcnt; + memcpy(s->block+offset, bitstr, nbits>>3); + bitcnt -= nbits; + bitstr += (nbits >> 3); + s->sha(s, s->block), s->blockcnt = 0; + shadirect(bitstr, bitcnt, s); + } + else { + memcpy(s->block+offset, bitstr, NBYTES(bitcnt)); + s->blockcnt += bitcnt; + } + return(savecnt); +} + +/* shabits: updates state for bit-aligned input data */ +static ULNG shabits(bitstr, bitcnt, s) +UCHR *bitstr; +ULNG bitcnt; +SHA *s; +{ + UINT i; + UINT gap; + ULNG nbits; + UCHR buf[1<<9]; + UINT bufsize = sizeof(buf); + ULNG bufbits = (ULNG) bufsize << 3; + UINT nbytes = NBYTES(bitcnt); + ULNG savecnt = bitcnt; + + gap = 8 - s->blockcnt % 8; + s->block[s->blockcnt>>3] &= ~0 << gap; + s->block[s->blockcnt>>3] |= *bitstr >> (8 - gap); + s->blockcnt += bitcnt < gap ? bitcnt : gap; + if (bitcnt < gap) + return(savecnt); + if (s->blockcnt == s->blocksize) + s->sha(s, s->block), s->blockcnt = 0; + if ((bitcnt -= gap) == 0) + return(savecnt); + while (nbytes > bufsize) { + for (i = 0; i < bufsize; i++) + buf[i] = bitstr[i] << gap | bitstr[i+1] >> (8-gap); + nbits = bitcnt < bufbits ? bitcnt : bufbits; + shabytes(buf, nbits, s); + bitcnt -= nbits, bitstr += bufsize, nbytes -= bufsize; + } + for (i = 0; i < nbytes - 1; i++) + buf[i] = bitstr[i] << gap | bitstr[i+1] >> (8-gap); + buf[nbytes-1] = bitstr[nbytes-1] << gap; + shabytes(buf, bitcnt, s); + return(savecnt); +} + +/* shawrite: triggers a state update using data in bitstr/bitcnt */ +ULNG shawrite(bitstr, bitcnt, s) +UCHR *bitstr; +ULNG bitcnt; +SHA *s; +{ + if (bitcnt < 1) + return(0); + if (SHA_LO32(s->lenll += bitcnt) < bitcnt) + if (SHA_LO32(++s->lenlh) == 0) + if (SHA_LO32(++s->lenhl) == 0) + s->lenhh++; + if (s->blockcnt == 0) + return(shadirect(bitstr, bitcnt, s)); + else if (s->blockcnt % 8 == 0) + return(shabytes(bitstr, bitcnt, s)); + else + return(shabits(bitstr, bitcnt, s)); +} + +/* shafinish: pads remaining block(s) and computes final digest state */ +void shafinish(s) +SHA *s; +{ + UINT lenpos, lhpos, llpos; + + lenpos = s->blocksize == SHA1_BLOCK_BITS ? 448 : 896; + lhpos = s->blocksize == SHA1_BLOCK_BITS ? 56 : 120; + llpos = s->blocksize == SHA1_BLOCK_BITS ? 60 : 124; + SETBIT(s->block, s->blockcnt), s->blockcnt++; + while (s->blockcnt > lenpos) + if (s->blockcnt < s->blocksize) + CLRBIT(s->block, s->blockcnt), s->blockcnt++; + else + s->sha(s, s->block), s->blockcnt = 0; + while (s->blockcnt < lenpos) + CLRBIT(s->block, s->blockcnt), s->blockcnt++; + if (s->blocksize > SHA1_BLOCK_BITS) { + w32mem(s->block + 112, s->lenhh); + w32mem(s->block + 116, s->lenhl); + } + w32mem(s->block + lhpos, s->lenlh); + w32mem(s->block + llpos, s->lenll); + s->sha(s, s->block); +} + +/* shadigest: returns pointer to current digest (binary) */ +UCHR *shadigest(s) +SHA *s; +{ + digcpy(s); + return(s->digest); +} + +/* shahex: returns pointer to current digest (hexadecimal) */ +char *shahex(s) +SHA *s; +{ + int i; + + digcpy(s); + s->hex[0] = '\0'; + if (HEXLEN((size_t) s->digestlen) >= sizeof(s->hex)) + return(s->hex); + for (i = 0; i < s->digestlen; i++) + sprintf(s->hex+i*2, "%02x", s->digest[i]); + return(s->hex); +} + +/* map: translation map for Base 64 encoding */ +static char map[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + +/* encbase64: encodes input (0 to 3 bytes) into Base 64 */ +static void encbase64(in, n, out) +UCHR *in; +int n; +char *out; +{ + UCHR byte[3] = {0, 0, 0}; + + out[0] = '\0'; + if (n < 1 || n > 3) + return; + memcpy(byte, in, n); + out[0] = map[byte[0] >> 2]; + out[1] = map[((byte[0] & 0x03) << 4) | (byte[1] >> 4)]; + out[2] = map[((byte[1] & 0x0f) << 2) | (byte[2] >> 6)]; + out[3] = map[byte[2] & 0x3f]; + out[n+1] = '\0'; +} + +/* shabase64: returns pointer to current digest (Base 64) */ +char *shabase64(s) +SHA *s; +{ + int n; + UCHR *q; + char out[5]; + + digcpy(s); + s->base64[0] = '\0'; + if (B64LEN(s->digestlen) >= sizeof(s->base64)) + return(s->base64); + for (n = s->digestlen, q = s->digest; n > 3; n -= 3, q += 3) { + encbase64(q, 3, out); + strcat(s->base64, out); + } + encbase64(q, n, out); + strcat(s->base64, out); + return(s->base64); +} + +/* shadsize: returns length of digest in bytes */ +int shadsize(s) +SHA *s; +{ + return(s->digestlen); +} + +/* shadup: duplicates current digest object */ +SHA *shadup(s) +SHA *s; +{ + SHA *p; + + SHA_new(0, p, 1, SHA); + if (p == NULL) + return(NULL); + memcpy(p, s, sizeof(SHA)); + return(p); +} + +/* shadump: dumps digest object to a human-readable ASCII file */ +int shadump(file, s) +char *file; +SHA *s; +{ + unsigned int i, j; + SHA_FILE *f; + UCHR *p = shadigest(s); + + if (file == NULL || strlen(file) == 0) + f = SHA_stdout(); + else if ((f = SHA_open(file, "w")) == NULL) + return(0); + SHA_fprintf(f, "alg:%d\nH", s->alg); + for (i = 0; i < 8; i++) + for (j = 0; j < (s->alg <= 256 ? 4 : 8); j++) + SHA_fprintf(f, "%s%02x", j==0 ? ":" : "", *p++); + SHA_fprintf(f, "\nblock"); + for (i = 0; i < s->blocksize>>3; i++) + SHA_fprintf(f, ":%02x", s->block[i]); + SHA_fprintf(f, "\nblockcnt:%u\n", s->blockcnt); + SHA_fprintf(f, "lenhh:%lu\nlenhl:%lu\nlenlh:%lu\nlenll:%lu\n", + (ULNG) LO32(s->lenhh), (ULNG) LO32(s->lenhl), + (ULNG) LO32(s->lenlh), (ULNG) LO32(s->lenll)); + if (f != SHA_stdout()) + SHA_close(f); + return(1); +} + +/* fgetstr: reads (and returns pointer to) next line of file */ +static char *fgetstr(line, maxsize, f) +char *line; +UINT maxsize; +SHA_FILE *f; +{ + char *p; + + if (SHA_feof(f) || maxsize == 0) + return(NULL); + for (p = line; !SHA_feof(f) && maxsize > 1; maxsize--) + if ((*p++ = SHA_getc(f)) == '\n') + break; + *p = '\0'; + return(line); +} + +/* empty: returns true if line contains only whitespace characters */ +static int empty(line) +char *line; +{ + char *p; + + for (p = line; *p; p++) + if (!isspace(*p)) + return(0); + return(1); +} + +/* getval: null-terminates field value, and sets pointer to rest of line */ +static char *getval(line, pprest) +char *line; +char **pprest; +{ + char *p, *v; + + for (v = line; *v == ':' || isspace(*v); v++) + ; + for (p = v; *p; p++) { + if (*p == ':' || isspace(*p)) { + *p++ = '\0'; + break; + } + } + *pprest = p; + return(p == v ? NULL : v); +} + +/* types of values present in dump file */ +#define T_C 1 /* character */ +#define T_I 2 /* normal integer */ +#define T_L 3 /* 32-bit value */ +#define T_Q 4 /* 64-bit value */ + +/* ldvals: checks next line in dump file against tag, and loads values */ +static int ldvals(f, tag, type, pval, reps, base) +SHA_FILE *f; +char *tag; +int type; +void *pval; +int reps; +int base; +{ + char *p, *pr, line[512]; + UCHR *pc = (UCHR *) pval; UINT *pi = (UINT *) pval; + W32 *pl = (W32 *) pval; W64 *pq = (W64 *) pval; + + while ((p = fgetstr(line, sizeof(line), f)) != NULL) + if (line[0] != '#' && !empty(line)) + break; + if (p == NULL || strcmp(getval(line, &pr), tag) != 0) + return(0); + while (reps-- > 0) { + if ((p = getval(pr, &pr)) == NULL) + return(1); + switch (type) { + case T_C: *pc++ = (UCHR) strtoul(p, NULL, base); break; + case T_I: *pi++ = (UINT) strtoul(p, NULL, base); break; + case T_L: *pl++ = (W32 ) strtoul(p, NULL, base); break; + case T_Q: *pq++ = (W64 ) strto64(p ); break; + } + } + return(1); +} + +/* closeall: closes dump file and de-allocates digest object */ +static SHA *closeall(f, s) +SHA_FILE *f; +SHA *s; +{ + if (f != NULL && f != SHA_stdin()) + SHA_close(f); + if (s != NULL) + shaclose(s); + return(NULL); +} + +/* shaload: creates digest object corresponding to contents of dump file */ +SHA *shaload(file) +char *file; +{ + int alg; + SHA *s = NULL; + SHA_FILE *f; + + if (file == NULL || strlen(file) == 0) + f = SHA_stdin(); + else if ((f = SHA_open(file, "r")) == NULL) + return(NULL); + if ( + /* avoid parens by exploiting precedence of (type)&-> */ + !ldvals(f,"alg",T_I,(VP)&alg,1,10) || + ((s = shaopen(alg)) == NULL) || + !ldvals(f,"H",alg<=SHA256?T_L:T_Q,(VP)s->H,8,16) || + !ldvals(f,"block",T_C,(VP)s->block,s->blocksize/8,16) || + !ldvals(f,"blockcnt",T_I,(VP)&s->blockcnt,1,10) || + (alg <= SHA256 && s->blockcnt >= SHA1_BLOCK_BITS) || + (alg >= SHA384 && s->blockcnt >= SHA384_BLOCK_BITS) || + !ldvals(f,"lenhh",T_L,(VP)&s->lenhh,1,10) || + !ldvals(f,"lenhl",T_L,(VP)&s->lenhl,1,10) || + !ldvals(f,"lenlh",T_L,(VP)&s->lenlh,1,10) || + !ldvals(f,"lenll",T_L,(VP)&s->lenll,1,10) + ) + return(closeall(f, s)); + if (f != SHA_stdin()) + SHA_close(f); + return(s); +} + +/* shaclose: de-allocates digest object */ +int shaclose(s) +SHA *s; +{ + if (s != NULL) { + memset(s, 0, sizeof(SHA)); + SHA_free(s); + } + return(0); +} diff --git a/ext/Digest/SHA/src/sha.h b/ext/Digest/SHA/src/sha.h new file mode 100644 index 0000000..0cbc9c3 --- /dev/null +++ b/ext/Digest/SHA/src/sha.h @@ -0,0 +1,235 @@ +/* + * sha.h: header file for SHA-1/224/256/384/512 routines + * + * Ref: NIST FIPS PUB 180-2 Secure Hash Standard + * + * Copyright (C) 2003-2005 Mark Shelor, All Rights Reserved + * + * Version: 5.32 + * Fri Dec 2 02:32:20 MST 2005 + * + */ + +#ifndef _INCLUDE_SHA_H_ +#define _INCLUDE_SHA_H_ + +#include + +#define SHA32_MAX 4294967295U +#define SHA64_MAX 18446744073709551615U + +#define SHA32_SHR(x, n) ((x) >> (n)) +#define SHA32_SHL(x, n) ((x) << (n)) + +#define SHA64_SHR(x, n) ((x) >> (n)) +#define SHA64_SHL(x, n) ((x) << (n)) + +#define SHA32_ALIGNED +#define SHA64_ALIGNED + +#define SHA_LO32(x) (x) + +#if USHRT_MAX == SHA32_MAX + #define SHA32 unsigned short + #define SHA32_CONST(c) c ## U +#elif UINT_MAX == SHA32_MAX + #define SHA32 unsigned int + #define SHA32_CONST(c) c ## U +#elif ULONG_MAX == SHA32_MAX + #define SHA32 unsigned long + #define SHA32_CONST(c) c ## UL +#else + #undef SHA32_ALIGNED + #undef SHA_LO32 + #define SHA_LO32(x) ((x) & SHA32_MAX) + #undef SHA32_SHR + #define SHA32_SHR(x, n) (SHA_LO32(x) >> (n)) + #define SHA32 unsigned long + #define SHA32_CONST(c) c ## UL +#endif + +#if defined(ULONG_LONG_MAX) || defined(ULLONG_MAX) || defined(HAS_LONG_LONG) + #define SHA_ULL_EXISTS +#endif + +#if (((ULONG_MAX >> 16) >> 16) >> 16) >> 15 == 1UL + #define SHA64 unsigned long + #define SHA64_CONST(c) c ## UL +#elif defined(SHA_ULL_EXISTS) && defined(LONGLONGSIZE) && LONGLONGSIZE == 8 + #define SHA64 unsigned long long + #define SHA64_CONST(c) c ## ULL +#elif defined(SHA_ULL_EXISTS) + #undef SHA64_ALIGNED + #undef SHA64_SHR + #define SHA64_SHR(x, n) (((x) & SHA64_MAX) >> (n)) + #define SHA64 unsigned long long + #define SHA64_CONST(c) c ## ULL + + /* The following cases detect compilers that + * support 64-bit types in a non-standard way */ + +#elif defined(_MSC_VER) /* Microsoft C */ + #define SHA64 unsigned __int64 + #define SHA64_CONST(c) (SHA64) c +#endif + +#if defined(SHA64) && !defined(NO_SHA_384_512) + #define SHA_384_512 +#endif + +#if defined(BYTEORDER) && (BYTEORDER & 0xffff) == 0x4321 + #if defined(SHA32_ALIGNED) + #define SHA32_SCHED(W, b) memcpy(W, b, 64) + #endif + #if defined(SHA64) && defined(SHA64_ALIGNED) + #define SHA64_SCHED(W, b) memcpy(W, b, 128) + #endif +#endif + +#if !defined(SHA32_SCHED) + #define SHA32_SCHED(W, b) { int t; SHA32 *q = W; \ + for (t = 0; t < 16; t++, b += 4) *q++ = \ + (SHA32) b[0] << 24 | (SHA32) b[1] << 16 | \ + (SHA32) b[2] << 8 | (SHA32) b[3]; } +#endif + +#if defined(SHA64) && !defined(SHA64_SCHED) + #define SHA64_SCHED(W, b) { int t; SHA64 *q = W; \ + for (t = 0; t < 16; t++, b += 8) *q++ = \ + (SHA64) b[0] << 56 | (SHA64) b[1] << 48 | \ + (SHA64) b[2] << 40 | (SHA64) b[3] << 32 | \ + (SHA64) b[4] << 24 | (SHA64) b[5] << 16 | \ + (SHA64) b[6] << 8 | (SHA64) b[7]; } +#endif + +/* + * SHA_STO_CLASS: default to auto storage class for message schedule + * arrays inside transform routines. Note that redefining this to + * static might improve performance on some platforms (e.g. Intel). + */ + +#if !defined(SHA_STO_CLASS) + #define SHA_STO_CLASS auto +#endif + +/* Override use of static arrays if compiling for thread-safety */ +#ifdef SHA_THREAD_SAFE + #undef SHA_STO_CLASS + #define SHA_STO_CLASS auto +#endif + +/* Configure memory management and I/O for Perl or standalone C */ +#ifdef SHA_PERL_MODULE + #define SHA_new New + #define SHA_newz Newz + #define SHA_free Safefree + #define SHA_FILE PerlIO + #define SHA_stdin() PerlIO_stdin() + #define SHA_stdout() PerlIO_stdout() + #define SHA_open PerlIO_open + #define SHA_close PerlIO_close + #define SHA_fprintf PerlIO_printf + #define SHA_feof PerlIO_eof + #define SHA_getc PerlIO_getc +#else + #define SHA_new(id, p, n, t) p = (t *) malloc(sizeof(t)) + #define SHA_newz(id, p, n, t) p = (t *) calloc(n, sizeof(t)) + #define SHA_free free + #define SHA_FILE FILE + #define SHA_stdin() stdin + #define SHA_stdout() stdout + #define SHA_open fopen + #define SHA_close fclose + #define SHA_fprintf fprintf + #define SHA_feof feof + #define SHA_getc fgetc +#endif + +#define SHA1 1 +#define SHA224 224 +#define SHA256 256 +#define SHA384 384 +#define SHA512 512 + +#define SHA1_BLOCK_BITS 512 +#define SHA224_BLOCK_BITS SHA1_BLOCK_BITS +#define SHA256_BLOCK_BITS SHA1_BLOCK_BITS +#define SHA384_BLOCK_BITS 1024 +#define SHA512_BLOCK_BITS SHA384_BLOCK_BITS + +#define SHA1_DIGEST_BITS 160 +#define SHA224_DIGEST_BITS 224 +#define SHA256_DIGEST_BITS 256 +#define SHA384_DIGEST_BITS 384 +#define SHA512_DIGEST_BITS 512 + +#define SHA_MAX_BLOCK_BITS SHA512_BLOCK_BITS +#define SHA_MAX_DIGEST_BITS SHA512_DIGEST_BITS +#define SHA_MAX_HEX_LEN (SHA_MAX_DIGEST_BITS / 4) +#define SHA_MAX_BASE64_LEN (1 + (SHA_MAX_DIGEST_BITS / 6)) + +#if defined(SHA64) + #define SHA_H_SIZE sizeof(SHA64) * 8 +#else + #define SHA_H_SIZE sizeof(SHA32) * 8 +#endif + +typedef struct { + int alg; + void (*sha)(); + unsigned char H[SHA_H_SIZE]; + unsigned char block[SHA_MAX_BLOCK_BITS/8]; + unsigned int blockcnt; + unsigned int blocksize; + SHA32 lenhh, lenhl, lenlh, lenll; + unsigned char digest[SHA_MAX_DIGEST_BITS/8]; + int digestlen; + char hex[SHA_MAX_HEX_LEN+1]; + char base64[SHA_MAX_BASE64_LEN+1]; +} SHA; + +#define SHA_FMT_RAW 1 +#define SHA_FMT_HEX 2 +#define SHA_FMT_BASE64 3 + +#if defined(__STDC__) && __STDC__ != 0 + #define _SHA_P(protos) protos +#else + #define _SHA_P(protos) () +#endif + +#define _SHA_STATE SHA *s +#define _SHA_ALG int alg +#define _SHA_DATA unsigned char *bitstr, unsigned long bitcnt +#define _SHA_FNAME char *filename + +SHA *shaopen _SHA_P((_SHA_ALG)); +unsigned long shawrite _SHA_P((_SHA_DATA, _SHA_STATE)); +void shafinish _SHA_P((_SHA_STATE)); +void sharewind _SHA_P((_SHA_STATE)); +unsigned char *shadigest _SHA_P((_SHA_STATE)); +char *shahex _SHA_P((_SHA_STATE)); +char *shabase64 _SHA_P((_SHA_STATE)); +int shadsize _SHA_P((_SHA_STATE)); +SHA *shadup _SHA_P((_SHA_STATE)); +int shadump _SHA_P((_SHA_FNAME, _SHA_STATE)); +SHA *shaload _SHA_P((_SHA_FNAME)); +int shaclose _SHA_P((_SHA_STATE)); + +unsigned char *sha1digest _SHA_P((_SHA_DATA)); +char *sha1hex _SHA_P((_SHA_DATA)); +char *sha1base64 _SHA_P((_SHA_DATA)); +unsigned char *sha224digest _SHA_P((_SHA_DATA)); +char *sha224hex _SHA_P((_SHA_DATA)); +char *sha224base64 _SHA_P((_SHA_DATA)); +unsigned char *sha256digest _SHA_P((_SHA_DATA)); +char *sha256hex _SHA_P((_SHA_DATA)); +char *sha256base64 _SHA_P((_SHA_DATA)); +unsigned char *sha384digest _SHA_P((_SHA_DATA)); +char *sha384hex _SHA_P((_SHA_DATA)); +char *sha384base64 _SHA_P((_SHA_DATA)); +unsigned char *sha512digest _SHA_P((_SHA_DATA)); +char *sha512hex _SHA_P((_SHA_DATA)); +char *sha512base64 _SHA_P((_SHA_DATA)); + +#endif /* _INCLUDE_SHA_H_ */ diff --git a/ext/Digest/SHA/src/sha64bit.c b/ext/Digest/SHA/src/sha64bit.c new file mode 100644 index 0000000..0e499a6 --- /dev/null +++ b/ext/Digest/SHA/src/sha64bit.c @@ -0,0 +1,104 @@ +#ifdef SHA_384_512 + +#undef sha_384_512 +#undef W64 +#undef strto64 +#undef sha512 +#undef H0384 +#undef H0512 + +#define sha_384_512 1 + +#define W64 SHA64 /* useful abbreviations */ +#define C64 SHA64_CONST +#define SR64 SHA64_SHR +#define SL64 SHA64_SHL + +#define ROTRQ(x, n) (SR64(x, n) | SL64(x, 64-(n))) +#define SIGMAQ0(x) (ROTRQ(x, 28) ^ ROTRQ(x, 34) ^ ROTRQ(x, 39)) +#define SIGMAQ1(x) (ROTRQ(x, 14) ^ ROTRQ(x, 18) ^ ROTRQ(x, 41)) +#define sigmaQ0(x) (ROTRQ(x, 1) ^ ROTRQ(x, 8) ^ SR64(x, 7)) +#define sigmaQ1(x) (ROTRQ(x, 19) ^ ROTRQ(x, 61) ^ SR64(x, 6)) + +static W64 K512[80] = /* SHA-384/512 constants */ +{ +C64(0x428a2f98d728ae22), C64(0x7137449123ef65cd), C64(0xb5c0fbcfec4d3b2f), +C64(0xe9b5dba58189dbbc), C64(0x3956c25bf348b538), C64(0x59f111f1b605d019), +C64(0x923f82a4af194f9b), C64(0xab1c5ed5da6d8118), C64(0xd807aa98a3030242), +C64(0x12835b0145706fbe), C64(0x243185be4ee4b28c), C64(0x550c7dc3d5ffb4e2), +C64(0x72be5d74f27b896f), C64(0x80deb1fe3b1696b1), C64(0x9bdc06a725c71235), +C64(0xc19bf174cf692694), C64(0xe49b69c19ef14ad2), C64(0xefbe4786384f25e3), +C64(0x0fc19dc68b8cd5b5), C64(0x240ca1cc77ac9c65), C64(0x2de92c6f592b0275), +C64(0x4a7484aa6ea6e483), C64(0x5cb0a9dcbd41fbd4), C64(0x76f988da831153b5), +C64(0x983e5152ee66dfab), C64(0xa831c66d2db43210), C64(0xb00327c898fb213f), +C64(0xbf597fc7beef0ee4), C64(0xc6e00bf33da88fc2), C64(0xd5a79147930aa725), +C64(0x06ca6351e003826f), C64(0x142929670a0e6e70), C64(0x27b70a8546d22ffc), +C64(0x2e1b21385c26c926), C64(0x4d2c6dfc5ac42aed), C64(0x53380d139d95b3df), +C64(0x650a73548baf63de), C64(0x766a0abb3c77b2a8), C64(0x81c2c92e47edaee6), +C64(0x92722c851482353b), C64(0xa2bfe8a14cf10364), C64(0xa81a664bbc423001), +C64(0xc24b8b70d0f89791), C64(0xc76c51a30654be30), C64(0xd192e819d6ef5218), +C64(0xd69906245565a910), C64(0xf40e35855771202a), C64(0x106aa07032bbd1b8), +C64(0x19a4c116b8d2d0c8), C64(0x1e376c085141ab53), C64(0x2748774cdf8eeb99), +C64(0x34b0bcb5e19b48a8), C64(0x391c0cb3c5c95a63), C64(0x4ed8aa4ae3418acb), +C64(0x5b9cca4f7763e373), C64(0x682e6ff3d6b2b8a3), C64(0x748f82ee5defb2fc), +C64(0x78a5636f43172f60), C64(0x84c87814a1f0ab72), C64(0x8cc702081a6439ec), +C64(0x90befffa23631e28), C64(0xa4506cebde82bde9), C64(0xbef9a3f7b2c67915), +C64(0xc67178f2e372532b), C64(0xca273eceea26619c), C64(0xd186b8c721c0c207), +C64(0xeada7dd6cde0eb1e), C64(0xf57d4f7fee6ed178), C64(0x06f067aa72176fba), +C64(0x0a637dc5a2c898a6), C64(0x113f9804bef90dae), C64(0x1b710b35131c471b), +C64(0x28db77f523047d84), C64(0x32caab7b40c72493), C64(0x3c9ebe0a15c9bebc), +C64(0x431d67c49c100d4c), C64(0x4cc5d4becb3e42b6), C64(0x597f299cfc657e2a), +C64(0x5fcb6fab3ad6faec), C64(0x6c44198c4a475817) +}; + +static W64 H0384[8] = /* SHA-384 initial hash value */ +{ +C64(0xcbbb9d5dc1059ed8), C64(0x629a292a367cd507), C64(0x9159015a3070dd17), +C64(0x152fecd8f70e5939), C64(0x67332667ffc00b31), C64(0x8eb44a8768581511), +C64(0xdb0c2e0d64f98fa7), C64(0x47b5481dbefa4fa4) +}; + +static W64 H0512[8] = /* SHA-512 initial hash value */ +{ +C64(0x6a09e667f3bcc908), C64(0xbb67ae8584caa73b), C64(0x3c6ef372fe94f82b), +C64(0xa54ff53a5f1d36f1), C64(0x510e527fade682d1), C64(0x9b05688c2b3e6c1f), +C64(0x1f83d9abfb41bd6b), C64(0x5be0cd19137e2179) +}; + +/* strto64: converts hex string to a 64-bit word */ +static W64 strto64(s) +char *s; +{ + char str[2] = {0, 0}; + W64 u = C64(0); + + while (isxdigit(str[0] = *s++)) + u = (u << 4) + strtoul(str, NULL, 16); + return(u); +} + +static void sha512(s, block) /* SHA-384/512 transform */ +SHA *s; +unsigned char *block; +{ + W64 a, b, c, d, e, f, g, h, T1, T2; + SHA_STO_CLASS W64 W[80]; + W64 *H = (W64 *) s->H; + int t; + + SHA64_SCHED(W, block); + for (t = 16; t < 80; t++) + W[t] = sigmaQ1(W[t-2]) + W[t-7] + sigmaQ0(W[t-15]) + W[t-16]; + a = H[0]; b = H[1]; c = H[2]; d = H[3]; + e = H[4]; f = H[5]; g = H[6]; h = H[7]; + for (t = 0; t < 80; t++) { + T1 = h + SIGMAQ1(e) + Ch(e, f, g) + K512[t] + W[t]; + T2 = SIGMAQ0(a) + Ma(a, b, c); + h = g; g = f; f = e; e = d + T1; + d = c; c = b; b = a; a = T1 + T2; + } + H[0] += a; H[1] += b; H[2] += c; H[3] += d; + H[4] += e; H[5] += f; H[6] += g; H[7] += h; +} + +#endif /* #ifdef SHA_384_512 */ diff --git a/ext/Digest/SHA/src/sha64bit.h b/ext/Digest/SHA/src/sha64bit.h new file mode 100644 index 0000000..5a02c92 --- /dev/null +++ b/ext/Digest/SHA/src/sha64bit.h @@ -0,0 +1,15 @@ +/* + * The following macros supply placeholder values that enable the + * `sha.c' module to successfully compile when 64-bit integer types + * aren't present. + * + * They are appropriately redefined in `sha64bit.c` if the compiler + * provides a 64-bit type (i.e. when SHA_384_512 is defined). + */ + +#define sha_384_512 0 +#define W64 unsigned long +#define strto64(p) 0 +#define sha512 NULL +#define H0384 H01 +#define H0512 H01 diff --git a/ext/Digest/SHA/src/shaxtra.c b/ext/Digest/SHA/src/shaxtra.c new file mode 100644 index 0000000..7301fc7 --- /dev/null +++ b/ext/Digest/SHA/src/shaxtra.c @@ -0,0 +1,57 @@ +#include +#include +#include "sha.h" + +static unsigned char *shacomp(alg, fmt, bitstr, bitcnt) +int alg; +int fmt; +unsigned char *bitstr; +unsigned long bitcnt; +{ + SHA *s; + static unsigned char digest[SHA_MAX_HEX_LEN+1]; + unsigned char *ret = digest; + + if ((s = shaopen(alg)) == NULL) + return(NULL); + shawrite(bitstr, bitcnt, s); + shafinish(s); + if (fmt == SHA_FMT_RAW) + memcpy(digest, shadigest(s), s->digestlen); + else if (fmt == SHA_FMT_HEX) + strcpy((char *) digest, shahex(s)); + else if (fmt == SHA_FMT_BASE64) + strcpy((char *) digest, shabase64(s)); + else + ret = NULL; + shaclose(s); + return(ret); +} + +#define SHA_DIRECT(type, name, alg, fmt) \ +type name(bitstr, bitcnt) \ +unsigned char *bitstr; \ +unsigned long bitcnt; \ +{ \ + return((type) shacomp(alg, fmt, bitstr, bitcnt)); \ +} + +SHA_DIRECT(unsigned char *, sha1digest, SHA1, SHA_FMT_RAW) +SHA_DIRECT(char *, sha1hex, SHA1, SHA_FMT_HEX) +SHA_DIRECT(char *, sha1base64, SHA1, SHA_FMT_BASE64) + +SHA_DIRECT(unsigned char *, sha224digest, SHA224, SHA_FMT_RAW) +SHA_DIRECT(char *, sha224hex, SHA224, SHA_FMT_HEX) +SHA_DIRECT(char *, sha224base64, SHA224, SHA_FMT_BASE64) + +SHA_DIRECT(unsigned char *, sha256digest, SHA256, SHA_FMT_RAW) +SHA_DIRECT(char *, sha256hex, SHA256, SHA_FMT_HEX) +SHA_DIRECT(char *, sha256base64, SHA256, SHA_FMT_BASE64) + +SHA_DIRECT(unsigned char *, sha384digest, SHA384, SHA_FMT_RAW) +SHA_DIRECT(char *, sha384hex, SHA384, SHA_FMT_HEX) +SHA_DIRECT(char *, sha384base64, SHA384, SHA_FMT_BASE64) + +SHA_DIRECT(unsigned char *, sha512digest, SHA512, SHA_FMT_RAW) +SHA_DIRECT(char *, sha512hex, SHA512, SHA_FMT_HEX) +SHA_DIRECT(char *, sha512base64, SHA512, SHA_FMT_BASE64)