diff --git a/ssh.h b/ssh.h index db694c58..139ea33f 100644 --- a/ssh.h +++ b/ssh.h @@ -353,8 +353,10 @@ struct ssh_mac { struct ssh_hash { void *(*init)(void); /* also allocates context */ + void *(*copy)(const void *); void (*bytes)(void *, const void *, int); void (*final)(void *, unsigned char *); /* also frees context */ + void (*free)(void *); int hlen; /* output length in bytes */ const char *text_name; }; diff --git a/sshsh256.c b/sshsh256.c index 8e3d4fc1..b2bd862e 100644 --- a/sshsh256.c +++ b/sshsh256.c @@ -200,6 +200,24 @@ static void *sha256_init(void) return s; } +static void *sha256_copy(const void *vold) +{ + const SHA256_State *old = (const SHA256_State *)vold; + SHA256_State *s; + + s = snew(SHA256_State); + *s = *old; + return s; +} + +static void sha256_free(void *handle) +{ + SHA256_State *s = handle; + + smemclr(s, sizeof(*s)); + sfree(s); +} + static void sha256_bytes(void *handle, const void *p, int len) { SHA256_State *s = handle; @@ -212,12 +230,12 @@ static void sha256_final(void *handle, unsigned char *output) SHA256_State *s = handle; SHA256_Final(s, output); - smemclr(s, sizeof(*s)); - sfree(s); + sha256_free(s); } const struct ssh_hash ssh_sha256 = { - sha256_init, sha256_bytes, sha256_final, 32, "SHA-256" + sha256_init, sha256_copy, sha256_bytes, sha256_final, sha256_free, + 32, "SHA-256" }; /* ---------------------------------------------------------------------- diff --git a/sshsh512.c b/sshsh512.c index f0f13510..bdfc1e9d 100644 --- a/sshsh512.c +++ b/sshsh512.c @@ -331,6 +331,24 @@ static void *sha512_init(void) 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; @@ -343,12 +361,12 @@ static void sha512_final(void *handle, unsigned char *output) SHA512_State *s = handle; SHA512_Final(s, output); - smemclr(s, sizeof(*s)); - sfree(s); + sha512_free(s); } const struct ssh_hash ssh_sha512 = { - sha512_init, sha512_bytes, sha512_final, 64, "SHA-512" + sha512_init, sha512_copy, sha512_bytes, sha512_final, sha512_free, + 64, "SHA-512" }; static void *sha384_init(void) @@ -370,7 +388,8 @@ static void sha384_final(void *handle, unsigned char *output) } const struct ssh_hash ssh_sha384 = { - sha384_init, sha512_bytes, sha384_final, 48, "SHA-384" + sha384_init, sha512_copy, sha512_bytes, sha384_final, sha512_free, + 48, "SHA-384" }; #ifdef TEST diff --git a/sshsha.c b/sshsha.c index 2b2eead1..07a71ca2 100644 --- a/sshsha.c +++ b/sshsha.c @@ -230,6 +230,24 @@ static void *sha1_init(void) return s; } +static void *sha1_copy(const void *vold) +{ + const SHA_State *old = (const SHA_State *)vold; + SHA_State *s; + + s = snew(SHA_State); + *s = *old; + return s; +} + +static void sha1_free(void *handle) +{ + SHA_State *s = handle; + + smemclr(s, sizeof(*s)); + sfree(s); +} + static void sha1_bytes(void *handle, const void *p, int len) { SHA_State *s = handle; @@ -242,12 +260,11 @@ static void sha1_final(void *handle, unsigned char *output) SHA_State *s = handle; SHA_Final(s, output); - smemclr(s, sizeof(*s)); - sfree(s); + sha1_free(s); } const struct ssh_hash ssh_sha1 = { - sha1_init, sha1_bytes, sha1_final, 20, "SHA-1" + sha1_init, sha1_copy, sha1_bytes, sha1_final, sha1_free, 20, "SHA-1" }; /* ----------------------------------------------------------------------