diff options
Diffstat (limited to 'lib/isc/sha2.c')
-rw-r--r-- | lib/isc/sha2.c | 457 |
1 files changed, 336 insertions, 121 deletions
diff --git a/lib/isc/sha2.c b/lib/isc/sha2.c index 70eea4f96700..db2e3496c454 100644 --- a/lib/isc/sha2.c +++ b/lib/isc/sha2.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005-2007, 2009 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2005-2007, 2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -14,9 +14,9 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: sha2.c,v 1.13.332.2 2009/01/18 23:47:41 tbox Exp $ */ +/* $Id$ */ -/* $FreeBSD$ */ +/* $FreeBSD: src/sys/crypto/sha2/sha2.c,v 1.2.2.2 2002/03/05 08:36:47 ume Exp $ */ /* $KAME: sha2.c,v 1.8 2001/11/08 01:07:52 itojun Exp $ */ /* @@ -58,10 +58,169 @@ #include <config.h> #include <isc/assertions.h> +#include <isc/platform.h> #include <isc/sha2.h> #include <isc/string.h> #include <isc/util.h> +#ifdef ISC_PLATFORM_OPENSSLHASH + +void +isc_sha224_init(isc_sha224_t *context) { + if (context == (isc_sha224_t *)0) { + return; + } + EVP_DigestInit(context, EVP_sha224()); +} + +void +isc_sha224_invalidate(isc_sha224_t *context) { + EVP_MD_CTX_cleanup(context); +} + +void +isc_sha224_update(isc_sha224_t *context, const isc_uint8_t* data, size_t len) { + if (len == 0U) { + /* Calling with no data is valid - we do nothing */ + return; + } + + /* Sanity check: */ + REQUIRE(context != (isc_sha224_t *)0 && data != (isc_uint8_t*)0); + + EVP_DigestUpdate(context, (const void *) data, len); +} + +void +isc_sha224_final(isc_uint8_t digest[], isc_sha224_t *context) { + /* Sanity check: */ + REQUIRE(context != (isc_sha224_t *)0); + + /* If no digest buffer is passed, we don't bother doing this: */ + if (digest != (isc_uint8_t*)0) { + EVP_DigestFinal(context, digest, NULL); + } else { + EVP_MD_CTX_cleanup(context); + } +} + +void +isc_sha256_init(isc_sha256_t *context) { + if (context == (isc_sha256_t *)0) { + return; + } + EVP_DigestInit(context, EVP_sha256()); +} + +void +isc_sha256_invalidate(isc_sha256_t *context) { + EVP_MD_CTX_cleanup(context); +} + +void +isc_sha256_update(isc_sha256_t *context, const isc_uint8_t *data, size_t len) { + if (len == 0U) { + /* Calling with no data is valid - we do nothing */ + return; + } + + /* Sanity check: */ + REQUIRE(context != (isc_sha256_t *)0 && data != (isc_uint8_t*)0); + + EVP_DigestUpdate(context, (const void *) data, len); +} + +void +isc_sha256_final(isc_uint8_t digest[], isc_sha256_t *context) { + /* Sanity check: */ + REQUIRE(context != (isc_sha256_t *)0); + + /* If no digest buffer is passed, we don't bother doing this: */ + if (digest != (isc_uint8_t*)0) { + EVP_DigestFinal(context, digest, NULL); + } else { + EVP_MD_CTX_cleanup(context); + } +} + +void +isc_sha512_init(isc_sha512_t *context) { + if (context == (isc_sha512_t *)0) { + return; + } + EVP_DigestInit(context, EVP_sha512()); +} + +void +isc_sha512_invalidate(isc_sha512_t *context) { + EVP_MD_CTX_cleanup(context); +} + +void isc_sha512_update(isc_sha512_t *context, const isc_uint8_t *data, size_t len) { + if (len == 0U) { + /* Calling with no data is valid - we do nothing */ + return; + } + + /* Sanity check: */ + REQUIRE(context != (isc_sha512_t *)0 && data != (isc_uint8_t*)0); + + EVP_DigestUpdate(context, (const void *) data, len); +} + +void isc_sha512_final(isc_uint8_t digest[], isc_sha512_t *context) { + /* Sanity check: */ + REQUIRE(context != (isc_sha512_t *)0); + + /* If no digest buffer is passed, we don't bother doing this: */ + if (digest != (isc_uint8_t*)0) { + EVP_DigestFinal(context, digest, NULL); + } else { + EVP_MD_CTX_cleanup(context); + } +} + +void +isc_sha384_init(isc_sha384_t *context) { + if (context == (isc_sha384_t *)0) { + return; + } + EVP_DigestInit(context, EVP_sha384()); +} + +void +isc_sha384_invalidate(isc_sha384_t *context) { + EVP_MD_CTX_cleanup(context); +} + +void +isc_sha384_update(isc_sha384_t *context, const isc_uint8_t* data, size_t len) { + if (len == 0U) { + /* Calling with no data is valid - we do nothing */ + return; + } + + /* Sanity check: */ + REQUIRE(context != (isc_sha512_t *)0 && data != (isc_uint8_t*)0); + + EVP_DigestUpdate(context, (const void *) data, len); +} + +void +isc_sha384_final(isc_uint8_t digest[], isc_sha384_t *context) { + /* Sanity check: */ + REQUIRE(context != (isc_sha384_t *)0); + + /* If no digest buffer is passed, we don't bother doing this: */ + if (digest != (isc_uint8_t*)0) { + EVP_DigestFinal(context, digest, NULL); + } else { + EVP_MD_CTX_cleanup(context); + } +} + +#else + /* * UNROLLED TRANSFORM LOOP NOTE: * You can define SHA2_UNROLL_TRANSFORM to use the unrolled transform @@ -394,13 +553,6 @@ static const isc_uint64_t sha512_initial_hash_value[8] = { }; #endif -/* - * Constant used by SHA256/384/512_End() functions for converting the - * digest to a readable hexadecimal character string: - */ -static const char *sha2_hex_digits = "0123456789abcdef"; - - /*** SHA-224: *********************************************************/ void @@ -415,6 +567,11 @@ isc_sha224_init(isc_sha224_t *context) { } void +isc_sha224_invalidate(isc_sha224_t *context) { + memset(context, 0, sizeof(isc_sha224_t)); +} + +void isc_sha224_update(isc_sha224_t *context, const isc_uint8_t* data, size_t len) { isc_sha256_update((isc_sha256_t *)context, data, len); } @@ -427,41 +584,6 @@ isc_sha224_final(isc_uint8_t digest[], isc_sha224_t *context) { memset(sha256_digest, 0, ISC_SHA256_DIGESTLENGTH); } -char * -isc_sha224_end(isc_sha224_t *context, char buffer[]) { - isc_uint8_t digest[ISC_SHA224_DIGESTLENGTH], *d = digest; - unsigned int i; - - /* Sanity check: */ - REQUIRE(context != (isc_sha224_t *)0); - - if (buffer != (char*)0) { - isc_sha224_final(digest, context); - - for (i = 0; i < ISC_SHA224_DIGESTLENGTH; i++) { - *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4]; - *buffer++ = sha2_hex_digits[*d & 0x0f]; - d++; - } - *buffer = (char)0; - } else { - memset(context, 0, sizeof(context)); - } - memset(digest, 0, ISC_SHA224_DIGESTLENGTH); - return buffer; -} - -char* -isc_sha224_data(const isc_uint8_t *data, size_t len, - char digest[ISC_SHA224_DIGESTSTRINGLENGTH]) -{ - isc_sha224_t context; - - isc_sha224_init(&context); - isc_sha224_update(&context, data, len); - return (isc_sha224_end(&context, digest)); -} - /*** SHA-256: *********************************************************/ void isc_sha256_init(isc_sha256_t *context) { @@ -474,6 +596,11 @@ isc_sha256_init(isc_sha256_t *context) { context->bitcount = 0; } +void +isc_sha256_invalidate(isc_sha256_t *context) { + memset(context, 0, sizeof(isc_sha256_t)); +} + #ifdef ISC_SHA2_UNROLL_TRANSFORM /* Unrolled SHA-256 round macros: */ @@ -565,6 +692,9 @@ void isc_sha256_transform(isc_sha256_t *context, const isc_uint32_t* data) { /* Clean up */ a = b = c = d = e = f = g = h = T1 = 0; + /* Avoid compiler warnings */ + POST(a); POST(b); POST(c); POST(d); POST(e); POST(f); + POST(g); POST(h); POST(T1); } #else /* ISC_SHA2_UNROLL_TRANSFORM */ @@ -646,6 +776,9 @@ isc_sha256_transform(isc_sha256_t *context, const isc_uint32_t* data) { /* Clean up */ a = b = c = d = e = f = g = h = T1 = T2 = 0; + /* Avoid compiler warnings */ + POST(a); POST(b); POST(c); POST(d); POST(e); POST(f); + POST(g); POST(h); POST(T1); POST(T2); } #endif /* ISC_SHA2_UNROLL_TRANSFORM */ @@ -682,6 +815,8 @@ isc_sha256_update(isc_sha256_t *context, const isc_uint8_t *data, size_t len) { context->bitcount += len << 3; /* Clean up: */ usedspace = freespace = 0; + /* Avoid compiler warnings: */ + POST(usedspace); POST(freespace); return; } } @@ -700,6 +835,8 @@ isc_sha256_update(isc_sha256_t *context, const isc_uint8_t *data, size_t len) { } /* Clean up: */ usedspace = freespace = 0; + /* Avoid compiler warnings: */ + POST(usedspace); POST(freespace); } void @@ -768,46 +905,11 @@ isc_sha256_final(isc_uint8_t digest[], isc_sha256_t *context) { } /* Clean up state data: */ - memset(context, 0, sizeof(context)); + memset(context, 0, sizeof(*context)); usedspace = 0; + POST(usedspace); } -char * -isc_sha256_end(isc_sha256_t *context, char buffer[]) { - isc_uint8_t digest[ISC_SHA256_DIGESTLENGTH], *d = digest; - unsigned int i; - - /* Sanity check: */ - REQUIRE(context != (isc_sha256_t *)0); - - if (buffer != (char*)0) { - isc_sha256_final(digest, context); - - for (i = 0; i < ISC_SHA256_DIGESTLENGTH; i++) { - *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4]; - *buffer++ = sha2_hex_digits[*d & 0x0f]; - d++; - } - *buffer = (char)0; - } else { - memset(context, 0, sizeof(context)); - } - memset(digest, 0, ISC_SHA256_DIGESTLENGTH); - return buffer; -} - -char * -isc_sha256_data(const isc_uint8_t* data, size_t len, - char digest[ISC_SHA256_DIGESTSTRINGLENGTH]) -{ - isc_sha256_t context; - - isc_sha256_init(&context); - isc_sha256_update(&context, data, len); - return (isc_sha256_end(&context, digest)); -} - - /*** SHA-512: *********************************************************/ void isc_sha512_init(isc_sha512_t *context) { @@ -820,6 +922,11 @@ isc_sha512_init(isc_sha512_t *context) { context->bitcount[0] = context->bitcount[1] = 0; } +void +isc_sha512_invalidate(isc_sha512_t *context) { + memset(context, 0, sizeof(isc_sha512_t)); +} + #ifdef ISC_SHA2_UNROLL_TRANSFORM /* Unrolled SHA-512 round macros: */ @@ -907,6 +1014,9 @@ void isc_sha512_transform(isc_sha512_t *context, const isc_uint64_t* data) { /* Clean up */ a = b = c = d = e = f = g = h = T1 = 0; + /* Avoid compiler warnings */ + POST(a); POST(b); POST(c); POST(d); POST(e); POST(f); + POST(g); POST(h); POST(T1); } #else /* ISC_SHA2_UNROLL_TRANSFORM */ @@ -986,6 +1096,9 @@ isc_sha512_transform(isc_sha512_t *context, const isc_uint64_t* data) { /* Clean up */ a = b = c = d = e = f = g = h = T1 = T2 = 0; + /* Avoid compiler warnings */ + POST(a); POST(b); POST(c); POST(d); POST(e); POST(f); + POST(g); POST(h); POST(T1); POST(T2); } #endif /* ISC_SHA2_UNROLL_TRANSFORM */ @@ -1021,6 +1134,8 @@ void isc_sha512_update(isc_sha512_t *context, const isc_uint8_t *data, size_t le ADDINC128(context->bitcount, len << 3); /* Clean up: */ usedspace = freespace = 0; + /* Avoid compiler warnings: */ + POST(usedspace); POST(freespace); return; } } @@ -1039,6 +1154,8 @@ void isc_sha512_update(isc_sha512_t *context, const isc_uint8_t *data, size_t le } /* Clean up: */ usedspace = freespace = 0; + /* Avoid compiler warnings: */ + POST(usedspace); POST(freespace); } void isc_sha512_last(isc_sha512_t *context) { @@ -1112,42 +1229,7 @@ void isc_sha512_final(isc_uint8_t digest[], isc_sha512_t *context) { } /* Zero out state data */ - memset(context, 0, sizeof(context)); -} - -char * -isc_sha512_end(isc_sha512_t *context, char buffer[]) { - isc_uint8_t digest[ISC_SHA512_DIGESTLENGTH], *d = digest; - unsigned int i; - - /* Sanity check: */ - REQUIRE(context != (isc_sha512_t *)0); - - if (buffer != (char*)0) { - isc_sha512_final(digest, context); - - for (i = 0; i < ISC_SHA512_DIGESTLENGTH; i++) { - *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4]; - *buffer++ = sha2_hex_digits[*d & 0x0f]; - d++; - } - *buffer = (char)0; - } else { - memset(context, 0, sizeof(context)); - } - memset(digest, 0, ISC_SHA512_DIGESTLENGTH); - return buffer; -} - -char * -isc_sha512_data(const isc_uint8_t *data, size_t len, - char digest[ISC_SHA512_DIGESTSTRINGLENGTH]) -{ - isc_sha512_t context; - - isc_sha512_init(&context); - isc_sha512_update(&context, data, len); - return (isc_sha512_end(&context, digest)); + memset(context, 0, sizeof(*context)); } @@ -1164,6 +1246,11 @@ isc_sha384_init(isc_sha384_t *context) { } void +isc_sha384_invalidate(isc_sha384_t *context) { + memset(context, 0, sizeof(isc_sha384_t)); +} + +void isc_sha384_update(isc_sha384_t *context, const isc_uint8_t* data, size_t len) { isc_sha512_update((isc_sha512_t *)context, data, len); } @@ -1195,7 +1282,131 @@ isc_sha384_final(isc_uint8_t digest[], isc_sha384_t *context) { } /* Zero out state data */ - memset(context, 0, sizeof(context)); + memset(context, 0, sizeof(*context)); +} +#endif /* !ISC_PLATFORM_OPENSSLHASH */ + +/* + * Constant used by SHA256/384/512_End() functions for converting the + * digest to a readable hexadecimal character string: + */ +static const char *sha2_hex_digits = "0123456789abcdef"; + +char * +isc_sha224_end(isc_sha224_t *context, char buffer[]) { + isc_uint8_t digest[ISC_SHA224_DIGESTLENGTH], *d = digest; + unsigned int i; + + /* Sanity check: */ + REQUIRE(context != (isc_sha224_t *)0); + + if (buffer != (char*)0) { + isc_sha224_final(digest, context); + + for (i = 0; i < ISC_SHA224_DIGESTLENGTH; i++) { + *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4]; + *buffer++ = sha2_hex_digits[*d & 0x0f]; + d++; + } + *buffer = (char)0; + } else { +#ifdef ISC_PLATFORM_OPENSSLHASH + EVP_MD_CTX_cleanup(context); +#else + memset(context, 0, sizeof(*context)); +#endif + } + memset(digest, 0, ISC_SHA224_DIGESTLENGTH); + return buffer; +} + +char * +isc_sha224_data(const isc_uint8_t *data, size_t len, + char digest[ISC_SHA224_DIGESTSTRINGLENGTH]) +{ + isc_sha224_t context; + + isc_sha224_init(&context); + isc_sha224_update(&context, data, len); + return (isc_sha224_end(&context, digest)); +} + +char * +isc_sha256_end(isc_sha256_t *context, char buffer[]) { + isc_uint8_t digest[ISC_SHA256_DIGESTLENGTH], *d = digest; + unsigned int i; + + /* Sanity check: */ + REQUIRE(context != (isc_sha256_t *)0); + + if (buffer != (char*)0) { + isc_sha256_final(digest, context); + + for (i = 0; i < ISC_SHA256_DIGESTLENGTH; i++) { + *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4]; + *buffer++ = sha2_hex_digits[*d & 0x0f]; + d++; + } + *buffer = (char)0; + } else { +#ifdef ISC_PLATFORM_OPENSSLHASH + EVP_MD_CTX_cleanup(context); +#else + memset(context, 0, sizeof(*context)); +#endif + } + memset(digest, 0, ISC_SHA256_DIGESTLENGTH); + return buffer; +} + +char * +isc_sha256_data(const isc_uint8_t* data, size_t len, + char digest[ISC_SHA256_DIGESTSTRINGLENGTH]) +{ + isc_sha256_t context; + + isc_sha256_init(&context); + isc_sha256_update(&context, data, len); + return (isc_sha256_end(&context, digest)); +} + +char * +isc_sha512_end(isc_sha512_t *context, char buffer[]) { + isc_uint8_t digest[ISC_SHA512_DIGESTLENGTH], *d = digest; + unsigned int i; + + /* Sanity check: */ + REQUIRE(context != (isc_sha512_t *)0); + + if (buffer != (char*)0) { + isc_sha512_final(digest, context); + + for (i = 0; i < ISC_SHA512_DIGESTLENGTH; i++) { + *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4]; + *buffer++ = sha2_hex_digits[*d & 0x0f]; + d++; + } + *buffer = (char)0; + } else { +#ifdef ISC_PLATFORM_OPENSSLHASH + EVP_MD_CTX_cleanup(context); +#else + memset(context, 0, sizeof(*context)); +#endif + } + memset(digest, 0, ISC_SHA512_DIGESTLENGTH); + return buffer; +} + +char * +isc_sha512_data(const isc_uint8_t *data, size_t len, + char digest[ISC_SHA512_DIGESTSTRINGLENGTH]) +{ + isc_sha512_t context; + + isc_sha512_init(&context); + isc_sha512_update(&context, data, len); + return (isc_sha512_end(&context, digest)); } char * @@ -1216,13 +1427,17 @@ isc_sha384_end(isc_sha384_t *context, char buffer[]) { } *buffer = (char)0; } else { - memset(context, 0, sizeof(context)); +#ifdef ISC_PLATFORM_OPENSSLHASH + EVP_MD_CTX_cleanup(context); +#else + memset(context, 0, sizeof(*context)); +#endif } memset(digest, 0, ISC_SHA384_DIGESTLENGTH); return buffer; } -char* +char * isc_sha384_data(const isc_uint8_t *data, size_t len, char digest[ISC_SHA384_DIGESTSTRINGLENGTH]) { |