aboutsummaryrefslogtreecommitdiff
path: root/lib/isc/sha2.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/isc/sha2.c')
-rw-r--r--lib/isc/sha2.c457
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])
{