update to 9.7.1-P2
[tridge/bind9.git] / lib / isc / sha2.c
index 6cd900dd18dc5bbc657a40d69c516c33805bc835..d42ad584ba61b90d80f114867761683dc833fd0b 100644 (file)
@@ -14,7 +14,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: sha2.c,v 1.13.332.2 2009/01/18 23:47:41 tbox Exp $ */
+/* $Id: sha2.c,v 1.18 2009/10/22 02:21:31 each Exp $ */
 
 /*     $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 $    */
 #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
@@ -414,6 +566,11 @@ isc_sha224_init(isc_sha224_t *context) {
        context->bitcount = 0;
 }
 
+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: */
@@ -772,42 +899,6 @@ isc_sha256_final(isc_uint8_t digest[], isc_sha256_t *context) {
        usedspace = 0;
 }
 
-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 +911,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: */
@@ -1115,41 +1211,6 @@ void isc_sha512_final(isc_uint8_t digest[], isc_sha512_t *context) {
        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));
-}
-
 
 /*** SHA-384: *********************************************************/
 void
@@ -1163,6 +1224,11 @@ isc_sha384_init(isc_sha384_t *context) {
        context->bitcount[0] = context->bitcount[1] = 0;
 }
 
+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);
@@ -1197,6 +1263,130 @@ isc_sha384_final(isc_uint8_t digest[], isc_sha384_t *context) {
        /* Zero out state data */
        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 *
 isc_sha384_end(isc_sha384_t *context, char buffer[]) {
@@ -1216,13 +1406,17 @@ isc_sha384_end(isc_sha384_t *context, char buffer[]) {
                }
                *buffer = (char)0;
        } else {
+#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])
 {