X-Git-Url: https://asedeno.scripts.mit.edu/gitweb/?a=blobdiff_plain;f=sshsh512.c;h=bdfc1e9dc71298630dfb444d49f83114136896c8;hb=86b604dd65679d983c06012b377e41c927da3cd6;hp=a2dd0c0b2316f29663b00b35d12ede3ec2bcb2d3;hpb=c7139c343c722a338e299c3155b173f18842a964;p=PuTTY.git diff --git a/sshsh512.c b/sshsh512.c index a2dd0c0b..bdfc1e9d 100644 --- a/sshsh512.c +++ b/sshsh512.c @@ -2,6 +2,8 @@ * SHA-512 algorithm as described at * * http://csrc.nist.gov/cryptval/shs.html + * + * Modifications made for SHA-384 also */ #include "ssh.h" @@ -13,14 +15,14 @@ * overlap destination with one source, but the others can't. */ #define add(r,x,y) ( r.lo = y.lo + x.lo, \ - r.hi = y.hi + x.hi + (r.lo < y.lo) ) -#define rorB(r,x,y) ( r.lo = (x.hi >> ((y)-32)) | (x.lo << (64-(y))), \ - r.hi = (x.lo >> ((y)-32)) | (x.hi << (64-(y))) ) -#define rorL(r,x,y) ( r.lo = (x.lo >> (y)) | (x.hi << (32-(y))), \ - r.hi = (x.hi >> (y)) | (x.lo << (32-(y))) ) -#define shrB(r,x,y) ( r.lo = x.hi >> ((y)-32), r.hi = 0 ) -#define shrL(r,x,y) ( r.lo = (x.lo >> (y)) | (x.hi << (32-(y))), \ - r.hi = x.hi >> (y) ) + r.hi = y.hi + x.hi + ((uint32)r.lo < (uint32)y.lo) ) +#define rorB(r,x,y) ( r.lo = ((uint32)x.hi >> ((y)-32)) | ((uint32)x.lo << (64-(y))), \ + r.hi = ((uint32)x.lo >> ((y)-32)) | ((uint32)x.hi << (64-(y))) ) +#define rorL(r,x,y) ( r.lo = ((uint32)x.lo >> (y)) | ((uint32)x.hi << (32-(y))), \ + r.hi = ((uint32)x.hi >> (y)) | ((uint32)x.lo << (32-(y))) ) +#define shrB(r,x,y) ( r.lo = (uint32)x.hi >> ((y)-32), r.hi = 0 ) +#define shrL(r,x,y) ( r.lo = ((uint32)x.lo >> (y)) | ((uint32)x.hi << (32-(y))), \ + r.hi = (uint32)x.hi >> (y) ) #define and(r,x,y) ( r.lo = x.lo & y.lo, r.hi = x.hi & y.hi ) #define xor(r,x,y) ( r.lo = x.lo ^ y.lo, r.hi = x.hi ^ y.hi ) #define not(r,x) ( r.lo = ~x.lo, r.hi = ~x.hi ) @@ -45,7 +47,7 @@ #define smallsigma1(r,t,x) ( rorL(r,x,19), rorB(t,x,61), xor(r,r,t), \ shrL(t,x,6), xor(r,r,t) ) -void SHA512_Core_Init(SHA512_State *s) { +static void SHA512_Core_Init(SHA512_State *s) { static const uint64 iv[] = { INIT(0x6a09e667, 0xf3bcc908), INIT(0xbb67ae85, 0x84caa73b), @@ -61,7 +63,23 @@ void SHA512_Core_Init(SHA512_State *s) { s->h[i] = iv[i]; } -void SHA512_Block(SHA512_State *s, uint64 *block) { +static void SHA384_Core_Init(SHA512_State *s) { + static const uint64 iv[] = { + INIT(0xcbbb9d5d, 0xc1059ed8), + INIT(0x629a292a, 0x367cd507), + INIT(0x9159015a, 0x3070dd17), + INIT(0x152fecd8, 0xf70e5939), + INIT(0x67332667, 0xffc00b31), + INIT(0x8eb44a87, 0x68581511), + INIT(0xdb0c2e0d, 0x64f98fa7), + INIT(0x47b5481d, 0xbefa4fa4), + }; + int i; + for (i = 0; i < 8; i++) + s->h[i] = iv[i]; +} + +static void SHA512_Block(SHA512_State *s, uint64 *block) { uint64 w[80]; uint64 a,b,c,d,e,f,g,h; static const uint64 k[] = { @@ -175,6 +193,14 @@ void SHA512_Init(SHA512_State *s) { s->len[i] = 0; } +void SHA384_Init(SHA512_State *s) { + int i; + SHA384_Core_Init(s); + s->blkused = 0; + for (i = 0; i < 4; i++) + s->len[i] = 0; +} + void SHA512_Bytes(SHA512_State *s, const void *p, int len) { unsigned char *q = (unsigned char *)p; uint64 wordblock[16]; @@ -268,14 +294,104 @@ void SHA512_Final(SHA512_State *s, unsigned char *digest) { } } +void SHA384_Final(SHA512_State *s, unsigned char *digest) { + unsigned char biggerDigest[512 / 8]; + SHA512_Final(s, biggerDigest); + memcpy(digest, biggerDigest, 384 / 8); +} + void SHA512_Simple(const void *p, int len, unsigned char *output) { SHA512_State s; SHA512_Init(&s); SHA512_Bytes(&s, p, len); SHA512_Final(&s, output); + smemclr(&s, sizeof(s)); +} + +void SHA384_Simple(const void *p, int len, unsigned char *output) { + SHA512_State s; + + SHA384_Init(&s); + SHA512_Bytes(&s, p, len); + SHA384_Final(&s, output); + smemclr(&s, sizeof(s)); +} + +/* + * Thin abstraction for things where hashes are pluggable. + */ + +static void *sha512_init(void) +{ + SHA512_State *s; + + s = snew(SHA512_State); + SHA512_Init(s); + return s; +} + +static void *sha512_copy(const void *vold) +{ + const SHA512_State *old = (const SHA512_State *)vold; + SHA512_State *s; + + s = snew(SHA512_State); + *s = *old; + return s; +} + +static void sha512_free(void *handle) +{ + SHA512_State *s = handle; + + smemclr(s, sizeof(*s)); + sfree(s); +} + +static void sha512_bytes(void *handle, const void *p, int len) +{ + SHA512_State *s = handle; + + SHA512_Bytes(s, p, len); } +static void sha512_final(void *handle, unsigned char *output) +{ + SHA512_State *s = handle; + + SHA512_Final(s, output); + sha512_free(s); +} + +const struct ssh_hash ssh_sha512 = { + sha512_init, sha512_copy, sha512_bytes, sha512_final, sha512_free, + 64, "SHA-512" +}; + +static void *sha384_init(void) +{ + SHA512_State *s; + + s = snew(SHA512_State); + SHA384_Init(s); + return s; +} + +static void sha384_final(void *handle, unsigned char *output) +{ + SHA512_State *s = handle; + + SHA384_Final(s, output); + smemclr(s, sizeof(*s)); + sfree(s); +} + +const struct ssh_hash ssh_sha384 = { + sha384_init, sha512_copy, sha512_bytes, sha384_final, sha512_free, + 48, "SHA-384" +}; + #ifdef TEST #include