Add HMAC DRBG from SP800-90
authorDr. Stephen Henson <steve@openssl.org>
Mon, 8 Aug 2011 22:07:38 +0000 (22:07 +0000)
committerDr. Stephen Henson <steve@openssl.org>
Mon, 8 Aug 2011 22:07:38 +0000 (22:07 +0000)
CHANGES
fips/fips_test_suite.c
fips/rand/fips_drbg_ctr.c
fips/rand/fips_drbg_hash.c
fips/rand/fips_drbg_hmac.c
fips/rand/fips_drbg_lib.c
fips/rand/fips_drbg_rand.c
fips/rand/fips_drbg_selftest.c
fips/rand/fips_drbgvs.c
fips/rand/fips_rand.h
fips/rand/fips_rand_lcl.h

diff --git a/CHANGES b/CHANGES
index c4dc27a298c8e824e90e77b72a89f1bb4e83dc50..011df12db373725680e7382f1017fcbeaa87bfdc 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -4,6 +4,10 @@
 
  Changes between 1.0.1 and 1.1.0  [xx XXX xxxx]
 
+  *) Add support for HMAC DRBG from SP800-90. Update algorithm and POST
+     to handle HMAC cases.
+     [Steve Henson]
+
   *) Add GCM support to TLS library. Some custom code is needed to split
      the IV between the fixed (from PRF) and explicit (from TLS record)
      portions. This adds all GCM ciphersuites supported by RFC5288 and 
index bfd34c19247a4e6c81fb1f28b3f35b2972b303f5..6046ae0f86c1b68558258f849418c16ff3716383 100644 (file)
@@ -679,6 +679,11 @@ POST_ID id_list[] = {
        {NID_sha256, "SHA256"},
        {NID_sha384, "SHA384"},
        {NID_sha512, "SHA512"},
+       {NID_hmacWithSHA1, "HMAC-SHA1"},
+       {NID_hmacWithSHA224, "HMAC-SHA224"},
+       {NID_hmacWithSHA256, "HMAC-SHA256"},
+       {NID_hmacWithSHA384, "HMAC-SHA384"},
+       {NID_hmacWithSHA512, "HMAC-SHA512"},
        {EVP_PKEY_RSA, "RSA"},
        {EVP_PKEY_DSA, "DSA"},
        {EVP_PKEY_EC, "ECDSA"},
index 4045e2d627f2966f5c4cd8bbba37657f1ec94735..a7f5b467537de0cae51ba5cf02ab0f46cf9430f6 100644 (file)
@@ -54,8 +54,6 @@
 #include <stdlib.h>
 #include <string.h>
 #include <openssl/crypto.h>
-#include <openssl/evp.h>
-#include <openssl/aes.h>
 #include <openssl/fips.h>
 #include <openssl/fips_rand.h>
 #include "fips_rand_lcl.h"
index 2fdf0e8f3820d64adc99b5a534f78900eaa90450..51db7a41ee667a658d853f75346c4c964a830be3 100644 (file)
@@ -56,8 +56,6 @@
 #include <stdlib.h>
 #include <string.h>
 #include <openssl/crypto.h>
-#include <openssl/evp.h>
-#include <openssl/aes.h>
 #include <openssl/fips.h>
 #include <openssl/fips_rand.h>
 #include "fips_rand_lcl.h"
index 09ff330e2e08b1adc108b296b6279c14c6dfae91..bf10609deea4ac19aa8e11a324141f75be3dd498 100644 (file)
 #include <openssl/fips_rand.h>
 #include "fips_rand_lcl.h"
 
+static int drbg_hmac_update(DRBG_CTX *dctx,
+                               const unsigned char *in1, size_t in1len,
+                               const unsigned char *in2, size_t in2len,
+                               const unsigned char *in3, size_t in3len
+                       )
+       {
+       static unsigned char c0 = 0, c1 = 1;
+       DRBG_HMAC_CTX *hmac = &dctx->d.hmac;
+       HMAC_CTX *hctx = &hmac->hctx;
+
+       if (!HMAC_Init_ex(hctx, hmac->K, dctx->blocklength, hmac->md, NULL))
+               return 0;
+       if (!HMAC_Update(hctx, hmac->V, dctx->blocklength))
+               return 0;
+       if (!HMAC_Update(hctx, &c0, 1))
+               return 0;
+       if (in1len && !HMAC_Update(hctx, in1, in1len))
+               return 0;
+       if (in2len && !HMAC_Update(hctx, in2, in2len))
+               return 0;
+       if (in3len && !HMAC_Update(hctx, in3, in3len))
+               return 0;
+
+       if (!HMAC_Final(hctx, hmac->K, NULL))
+               return 0;
+
+       if (!HMAC_Init_ex(hctx, hmac->K, dctx->blocklength, hmac->md, NULL))
+               return 0;
+       if (!HMAC_Update(hctx, hmac->V, dctx->blocklength))
+               return 0;
+
+       if (!HMAC_Final(hctx, hmac->V, NULL))
+               return 0;
+
+       if (!in1len && !in2len && !in3len)
+               return 1;
+
+       if (!HMAC_Init_ex(hctx, hmac->K, dctx->blocklength, hmac->md, NULL))
+               return 0;
+       if (!HMAC_Update(hctx, hmac->V, dctx->blocklength))
+               return 0;
+       if (!HMAC_Update(hctx, &c1, 1))
+               return 0;
+       if (in1len && !HMAC_Update(hctx, in1, in1len))
+               return 0;
+       if (in2len && !HMAC_Update(hctx, in2, in2len))
+               return 0;
+       if (in3len && !HMAC_Update(hctx, in3, in3len))
+               return 0;
+
+       if (!HMAC_Final(hctx, hmac->K, NULL))
+               return 0;
+
+       if (!HMAC_Init_ex(hctx, hmac->K, dctx->blocklength, hmac->md, NULL))
+               return 0;
+       if (!HMAC_Update(hctx, hmac->V, dctx->blocklength))
+               return 0;
+
+       if (!HMAC_Final(hctx, hmac->V, NULL))
+               return 0;
+
+       return 1;
+
+       }
+
+static int drbg_hmac_instantiate(DRBG_CTX *dctx,
+                               const unsigned char *ent, size_t ent_len,
+                               const unsigned char *nonce, size_t nonce_len,
+                               const unsigned char *pstr, size_t pstr_len)
+       {
+       DRBG_HMAC_CTX *hmac = &dctx->d.hmac;
+       memset(hmac->K, 0, dctx->blocklength);
+       memset(hmac->V, 1, dctx->blocklength);
+       if (!drbg_hmac_update(dctx,
+                       ent, ent_len, nonce, nonce_len, pstr, pstr_len))
+               return 0;
+
+#ifdef HMAC_DRBG_TRACE
+       fprintf(stderr, "K+V after instantiate:\n");
+       hexprint(stderr, hmac->K, hmac->blocklength);
+       hexprint(stderr, hmac->V, hmac->blocklength);
+#endif
+       return 1;
+       }
+
+static int drbg_hmac_reseed(DRBG_CTX *dctx,
+                               const unsigned char *ent, size_t ent_len,
+                               const unsigned char *adin, size_t adin_len)
+       {
+       if (!drbg_hmac_update(dctx,
+                       ent, ent_len, adin, adin_len, NULL, 0))
+               return 0;
+
+#ifdef HMAC_DRBG_TRACE
+       {
+               DRBG_HMAC_CTX *hmac = &dctx->d.hmac;
+               fprintf(stderr, "K+V after reseed:\n");
+               hexprint(stderr, hmac->K, hmac->blocklength);
+               hexprint(stderr, hmac->V, hmac->blocklength);
+       }
+#endif
+       return 1;
+       }
+
+static int drbg_hmac_generate(DRBG_CTX *dctx,
+                               unsigned char *out, size_t outlen,
+                               const unsigned char *adin, size_t adin_len)
+       {
+       DRBG_HMAC_CTX *hmac = &dctx->d.hmac;
+       HMAC_CTX *hctx = &hmac->hctx;
+       const unsigned char *Vtmp = hmac->V;
+       if (adin_len && !drbg_hmac_update(dctx, adin, adin_len,
+                                               NULL, 0, NULL, 0))
+               return 0;
+       for (;;)
+               {
+               if (!HMAC_Init_ex(hctx, hmac->K, dctx->blocklength,
+                                                       hmac->md, NULL))
+                       return 0;
+               if (!HMAC_Update(hctx, Vtmp, dctx->blocklength))
+                       return 0;
+               if (!(dctx->flags & DRBG_FLAG_TEST) && !dctx->lb_valid)
+                       {
+                       if (!HMAC_Final(hctx, dctx->lb, NULL))
+                               return 0;
+                       dctx->lb_valid = 1;
+                       Vtmp = dctx->lb;
+                       continue;
+                       }
+               else if (outlen > dctx->blocklength)
+                       {
+                       if (!HMAC_Final(hctx, out, NULL))
+                               return 0;
+                       if (!fips_drbg_cprng_test(dctx, out))
+                               return 0;
+                       Vtmp = out;
+                       }
+               else
+                       {
+                       if (!HMAC_Final(hctx, hmac->V, NULL))
+                               return 0;
+                       if (!fips_drbg_cprng_test(dctx, hmac->V))
+                               return 0;
+                       memcpy(out, hmac->V, outlen);
+                       break;
+                       }
+               out += dctx->blocklength;
+               outlen -= dctx->blocklength;
+               }
+       if (!drbg_hmac_update(dctx, adin, adin_len, NULL, 0, NULL, 0))
+               return 0;
+
+       return 1;
+       }
+
+static int drbg_hmac_uninstantiate(DRBG_CTX *dctx)
+       {
+       HMAC_CTX_cleanup(&dctx->d.hmac.hctx);
+       OPENSSL_cleanse(&dctx->d.hmac, sizeof(DRBG_HMAC_CTX));
+       return 1;
+       }
+
 int fips_drbg_hmac_init(DRBG_CTX *dctx)
        {
-       return -2;
+       const EVP_MD *md = NULL;
+       DRBG_HMAC_CTX *hctx = &dctx->d.hmac;
+       dctx->strength = 256;
+       switch (dctx->type)
+               {
+               case NID_hmacWithSHA1:
+               md = EVP_sha1();
+               dctx->strength = 128;
+               break;
+
+               case NID_hmacWithSHA224:
+               md = EVP_sha224();
+               dctx->strength = 192;
+               break;
+
+               case NID_hmacWithSHA256:
+               md = EVP_sha256();
+               break;
+
+               case NID_hmacWithSHA384:
+               md = EVP_sha384();
+               break;
+
+               case NID_hmacWithSHA512:
+               md = EVP_sha512();
+               break;
+
+               default:
+               dctx->strength = 0;
+               return -2;
+               }
+        dctx->instantiate = drbg_hmac_instantiate;
+        dctx->reseed = drbg_hmac_reseed;
+        dctx->generate = drbg_hmac_generate;
+        dctx->uninstantiate = drbg_hmac_uninstantiate;
+       HMAC_CTX_init(&hctx->hctx);
+       hctx->md = md;
+       dctx->blocklength = M_EVP_MD_size(md);
+       dctx->seedlen = M_EVP_MD_size(md);
+
+        dctx->min_entropy = dctx->strength / 8;
+        dctx->max_entropy = DRBG_MAX_LENGTH;
+
+        dctx->min_nonce = dctx->min_entropy / 2;
+        dctx->max_nonce = DRBG_MAX_LENGTH;
+
+        dctx->max_pers = DRBG_MAX_LENGTH;
+        dctx->max_adin = DRBG_MAX_LENGTH;
+
+        dctx->max_request = 1<<19;
+        dctx->reseed_interval = 1<<24;
+
+       return 1;
        }
index 4b2ac74b7a5d0298d5d887fabf69de68836adcad..3478864eec8e794bf05becfb75be7bb815ca7fcf 100644 (file)
@@ -55,8 +55,6 @@
 
 #include <string.h>
 #include <openssl/crypto.h>
-#include <openssl/evp.h>
-#include <openssl/aes.h>
 #include <openssl/err.h>
 #include <openssl/fips_rand.h>
 #include "fips_rand_lcl.h"
index 8872ba2992de669ebd6357f3752f07ae995e7f2b..22377573c022a6c52880aef5efce1bd9247a3095 100644 (file)
@@ -55,8 +55,6 @@
 
 #include <string.h>
 #include <openssl/crypto.h>
-#include <openssl/evp.h>
-#include <openssl/aes.h>
 #include <openssl/err.h>
 #include <openssl/rand.h>
 #include <openssl/fips_rand.h>
index 881bce041d5002f82af79f66a88e11e248d21ec1..be892d810eae828dc40d044caaa3f0a99bd44e9c 100644 (file)
@@ -55,8 +55,6 @@
 
 #include <string.h>
 #include <openssl/crypto.h>
-#include <openssl/evp.h>
-#include <openssl/aes.h>
 #include <openssl/err.h>
 #include <openssl/fips_rand.h>
 #include "fips_rand_lcl.h"
@@ -706,6 +704,280 @@ static const unsigned char sha512_returnedbits[] =
        0x14,0x0b,0x50,0x11
        };
 
+/* HMAC SHA-1 PR */
+static const unsigned char hmac_sha1_entropyinput[] =
+       {
+       0x0a,0xbe,0x45,0x75,0x79,0x56,0x5a,0xc1,0x93,0x1a,0xea,0xee,
+       0x08,0x86,0xc6,0x9e
+       };
+
+static const unsigned char hmac_sha1_nonce[] =
+       {
+       0x15,0x63,0x19,0xd2,0x2f,0xec,0x42,0x84
+       };
+
+static const unsigned char hmac_sha1_personalizationstring[] =
+       {
+       0xb4,0xfe,0x99,0x80,0xde,0xcf,0x1e,0x5e,0x50,0x0d,0x36,0x24,
+       0x8a,0x74,0x72,0x06
+       };
+
+static const unsigned char hmac_sha1_additionalinput[] =
+       {
+       0x5d,0xcb,0x61,0x0f,0x21,0x12,0xbf,0xdd,0x6a,0xa7,0x86,0x97,
+       0xed,0x89,0xd9,0x3f
+       };
+
+static const unsigned char hmac_sha1_entropyinputpr[] =
+       {
+       0x9e,0xb3,0x11,0xa7,0xfa,0x5f,0xaa,0x99,0xec,0xf1,0xb4,0x7a,
+       0x14,0xef,0x55,0x25
+       };
+
+static const unsigned char hmac_sha1_additionalinput2[] =
+       {
+       0x82,0x6e,0x85,0x25,0xa4,0xdc,0xdc,0xf4,0x09,0xb3,0x57,0x4a,
+       0x10,0x65,0xf5,0x38
+       };
+
+static const unsigned char hmac_sha1_entropyinputpr2[] =
+       {
+       0x8d,0x0b,0xdc,0x9a,0x62,0x49,0xb0,0xfe,0x56,0x23,0xfd,0x1d,
+       0x15,0x43,0xae,0xb9
+       };
+
+static const unsigned char hmac_sha1_returnedbits[] =
+       {
+       0x09,0xe3,0xcc,0x21,0x7e,0x78,0x83,0x7d,0x3c,0x1b,0x15,0xc7,
+       0x0c,0xe5,0xd6,0x9d,0x11,0xd7,0xe6,0xf8
+       };
+
+
+/* HMAC SHA-224 PR */
+static const unsigned char hmac_sha224_entropyinput[] =
+       {
+       0x98,0x49,0x8d,0x87,0x54,0xdc,0xf3,0x0f,0xe6,0x9d,0x5b,0x1f,
+       0x3b,0x23,0x0e,0x59,0x16,0x67,0x33,0xc0,0x71,0x50,0x4d,0xe3
+       };
+
+static const unsigned char hmac_sha224_nonce[] =
+       {
+       0x96,0x73,0xae,0x62,0xfb,0xf4,0xb7,0x9b,0xcc,0xe9,0x84,0x7f
+       };
+
+static const unsigned char hmac_sha224_personalizationstring[] =
+       {
+       0xa9,0x43,0x09,0xae,0xdd,0x11,0xc8,0x4a,0x04,0x89,0xa5,0x69,
+       0x5e,0x7c,0x80,0xd1,0xf9,0x1e,0x6d,0x8c,0xcd,0x59,0xef,0xd2
+       };
+
+static const unsigned char hmac_sha224_additionalinput[] =
+       {
+       0xef,0x8f,0xfc,0x23,0x6a,0x71,0xdf,0xfa,0xf3,0xa1,0x37,0xd0,
+       0xfe,0x5e,0x3f,0x76,0x16,0xe0,0xdf,0x84,0xd7,0x01,0xc8,0xa4
+       };
+
+static const unsigned char hmac_sha224_entropyinputpr[] =
+       {
+       0x5a,0xc1,0x2f,0xa3,0x52,0x1a,0x27,0xed,0x1b,0x13,0x2a,0xab,
+       0xb1,0x3d,0x2f,0x9c,0xd0,0x40,0xce,0xf2,0x0c,0x23,0x7d,0x40
+       };
+
+static const unsigned char hmac_sha224_additionalinput2[] =
+       {
+       0xfe,0x48,0x55,0x54,0x87,0x83,0x50,0x11,0xc9,0x73,0x68,0x89,
+       0x1a,0x62,0xd5,0xe6,0x3b,0xc9,0x14,0x8d,0xd9,0x7e,0x83,0xef
+       };
+
+static const unsigned char hmac_sha224_entropyinputpr2[] =
+       {
+       0x75,0x50,0xa6,0x64,0x0f,0xdf,0x11,0x05,0x02,0x79,0x89,0xf3,
+       0x33,0x37,0xa8,0x89,0xfe,0x0a,0x1a,0xc9,0x31,0x68,0xb2,0xa7
+       };
+
+static const unsigned char hmac_sha224_returnedbits[] =
+       {
+       0xd0,0x38,0xa8,0xdf,0xfe,0xcd,0x4a,0x16,0xd6,0xec,0x20,0xac,
+       0x42,0x97,0x8c,0x5d,0x7b,0xec,0x23,0x62,0x21,0xc8,0x8e,0x76,
+       0xdd,0x4d,0xca,0x4f
+       };
+
+
+/* HMAC SHA-256 PR */
+static const unsigned char hmac_sha256_entropyinput[] =
+       {
+       0xf8,0x48,0xab,0xfe,0x9a,0xf2,0x3d,0x9f,0x17,0xda,0xfe,0xe1,
+       0x41,0xcd,0xfc,0xa4,0x46,0x74,0xf7,0x38,0x32,0x86,0x02,0x28,
+       0xa6,0x33,0x5e,0x42,0xd9,0xce,0x95,0xe9
+       };
+
+static const unsigned char hmac_sha256_nonce[] =
+       {
+       0x7a,0x26,0x5a,0xed,0x72,0xe0,0x2d,0xef,0xc3,0xa2,0x7f,0x7f,
+       0x1a,0x6e,0xca,0x85
+       };
+
+static const unsigned char hmac_sha256_personalizationstring[] =
+       {
+       0xc8,0x79,0xe5,0xb6,0x19,0xc1,0xc1,0x4d,0x78,0xf8,0xfc,0xdf,
+       0x26,0xc3,0x5b,0x10,0x0f,0x37,0x25,0x04,0x50,0x06,0xc6,0x25,
+       0xe7,0xeb,0xa3,0x38,0xbb,0x55,0x3e,0xa2
+       };
+
+static const unsigned char hmac_sha256_additionalinput[] =
+       {
+       0x37,0xf0,0x25,0xe1,0x03,0x4b,0xae,0x74,0xfc,0xff,0xbe,0x6b,
+       0xc1,0x93,0x23,0x66,0x95,0x54,0x67,0x1c,0x63,0x05,0xef,0xa6,
+       0xf0,0xc9,0x56,0x0c,0x61,0x4f,0x05,0x0f
+       };
+
+static const unsigned char hmac_sha256_entropyinputpr[] =
+       {
+       0x91,0x62,0x41,0xa5,0x9a,0x5f,0x90,0x4d,0x53,0x75,0x11,0x0a,
+       0x86,0x1a,0x96,0x26,0x97,0x3e,0x20,0x31,0x79,0xf4,0xf8,0x4d,
+       0xf2,0x60,0x0d,0xba,0x12,0xe2,0x8f,0xa3
+       };
+
+static const unsigned char hmac_sha256_additionalinput2[] =
+       {
+       0xd4,0xf8,0x6f,0x3a,0xae,0x93,0x93,0x42,0x0f,0x11,0xd7,0xe3,
+       0x07,0xfe,0x33,0x84,0xc3,0xd9,0xa2,0xe2,0xaa,0x66,0x5b,0xfa,
+       0xb7,0x37,0x56,0x35,0x17,0x78,0xfd,0xd4
+       };
+
+static const unsigned char hmac_sha256_entropyinputpr2[] =
+       {
+       0xdd,0x21,0x60,0x30,0xfd,0x6d,0xea,0x1a,0x2e,0x0f,0xe3,0xcd,
+       0xb1,0x2b,0x10,0x16,0x3b,0x15,0xd0,0x92,0x93,0x1b,0xd7,0x14,
+       0x6e,0x90,0x31,0x52,0x88,0x1b,0x75,0xd5
+       };
+
+static const unsigned char hmac_sha256_returnedbits[] =
+       {
+       0x8a,0x66,0x8a,0xe2,0x0d,0xe7,0xcc,0xae,0xec,0x9b,0x22,0x8e,
+       0xd1,0x0c,0xa4,0x13,0xcd,0xd9,0x4b,0xb9,0x72,0xf2,0xc2,0x12,
+       0x88,0x52,0x5d,0x90,0x67,0x69,0x38,0x22
+       };
+
+
+/* HMAC SHA-384 PR */
+static const unsigned char hmac_sha384_entropyinput[] =
+       {
+       0x81,0x6f,0xcc,0xe7,0x9b,0x85,0x5e,0x99,0x0d,0x74,0x39,0xe5,
+       0x65,0x9b,0xb9,0x68,0x6b,0x9e,0x76,0xff,0x78,0xef,0xc6,0xf2,
+       0x1b,0x99,0x74,0x64,0xee,0x4e,0xc0,0xfa
+       };
+
+static const unsigned char hmac_sha384_nonce[] =
+       {
+       0xf8,0xce,0xb1,0xe7,0x96,0x9d,0x47,0x10,0x80,0xda,0x70,0x75,
+       0xbf,0xba,0xe9,0xe8
+       };
+
+static const unsigned char hmac_sha384_personalizationstring[] =
+       {
+       0x3c,0xbd,0xd5,0x1c,0x1e,0xa5,0xa9,0xe0,0x0b,0xb1,0xd4,0x2c,
+       0xcc,0xaf,0xb9,0x70,0x61,0x03,0x86,0x82,0xff,0x58,0x51,0xea,
+       0x46,0x88,0x77,0x6f,0xc6,0xc7,0x38,0xe0
+       };
+
+static const unsigned char hmac_sha384_additionalinput[] =
+       {
+       0xaf,0x16,0x5f,0xcf,0x85,0xba,0xd2,0x85,0x14,0x5c,0x33,0x64,
+       0x8a,0x7b,0x26,0x9b,0xd1,0xb0,0xf4,0xcc,0xaf,0xf3,0xc4,0xfa,
+       0x1d,0x2c,0x19,0xb4,0xe6,0xfc,0x8d,0x81
+       };
+
+static const unsigned char hmac_sha384_entropyinputpr[] =
+       {
+       0xff,0x63,0xb4,0x83,0x95,0xe6,0x7e,0x3c,0x35,0xee,0xb5,0x2c,
+       0x50,0x65,0x06,0x53,0xb3,0x17,0xd3,0x22,0x0c,0xdb,0xce,0x41,
+       0x9b,0xff,0xd8,0xa1,0x36,0xf7,0x1a,0xc4
+       };
+
+static const unsigned char hmac_sha384_additionalinput2[] =
+       {
+       0xaa,0x2a,0xd6,0x81,0xda,0x55,0x3b,0xdd,0xa7,0x9e,0x25,0x31,
+       0xf8,0xc9,0xa3,0xb5,0x8b,0x52,0x30,0x24,0xf2,0x16,0xd3,0x0c,
+       0xcc,0x47,0x77,0x5a,0x46,0x91,0x87,0x23
+       };
+
+static const unsigned char hmac_sha384_entropyinputpr2[] =
+       {
+       0xaa,0xe9,0xf6,0xcc,0xd3,0x38,0x0b,0x20,0x75,0x4a,0x3b,0x13,
+       0xc7,0xf1,0x66,0xc0,0x0e,0xfd,0xc1,0x7b,0x81,0x3f,0xd7,0x7b,
+       0x5b,0xe0,0xbe,0xc7,0x40,0xe2,0x9c,0x65
+       };
+
+static const unsigned char hmac_sha384_returnedbits[] =
+       {
+       0x57,0x49,0xc1,0x59,0x99,0x5d,0xe2,0xc6,0x25,0xc5,0xdb,0xe2,
+       0xd4,0x1b,0xee,0x4c,0xd3,0x36,0xe5,0xa5,0xc8,0x93,0xcb,0xbc,
+       0xc8,0x2e,0xd6,0x45,0x3f,0x66,0xa4,0x71,0xc8,0x98,0xb9,0x97,
+       0x28,0x56,0xad,0xdb,0xfe,0x09,0x8d,0xe2,0xb3,0x04,0xae,0xf4
+       };
+
+
+/* HMAC SHA-512 PR */
+static const unsigned char hmac_sha512_entropyinput[] =
+       {
+       0xab,0xb5,0xbc,0x7f,0x94,0xd6,0xbe,0xc8,0x94,0xa9,0x46,0xdd,
+       0xc5,0x63,0x14,0x8e,0xdc,0xab,0x68,0x7f,0x47,0xec,0x46,0x16,
+       0x8a,0xe0,0xea,0xa3,0xda,0x5b,0x88,0xd0
+       };
+
+static const unsigned char hmac_sha512_nonce[] =
+       {
+       0x6a,0xda,0xa4,0x68,0x66,0x9a,0xc8,0x34,0xef,0x21,0xe6,0xb4,
+       0xac,0xc7,0xb0,0xbe
+       };
+
+static const unsigned char hmac_sha512_personalizationstring[] =
+       {
+       0x69,0xa4,0x13,0xd2,0xeb,0x39,0xb6,0xdc,0x3e,0x6c,0x84,0xb8,
+       0x1b,0x0e,0x86,0x47,0xb4,0x74,0xf1,0x60,0xe6,0x66,0x7c,0x53,
+       0xbc,0x43,0x03,0xbd,0x26,0x78,0x5b,0x92
+       };
+
+static const unsigned char hmac_sha512_additionalinput[] =
+       {
+       0xaf,0x33,0x2b,0x15,0x3c,0xd1,0x01,0x8b,0x24,0xe9,0x97,0x01,
+       0x13,0x52,0x4b,0x92,0xd0,0x2f,0x0e,0xd4,0xf9,0x5a,0x3b,0xe3,
+       0xff,0x14,0xb7,0xae,0x63,0xed,0x4d,0x80
+       };
+
+static const unsigned char hmac_sha512_entropyinputpr[] =
+       {
+       0x0e,0xe7,0xe1,0x16,0x7d,0x6d,0x3c,0xfd,0xd2,0x69,0x2e,0xc6,
+       0xb7,0x08,0xa4,0xb5,0x93,0xe2,0xba,0xa3,0x40,0x6a,0x9a,0x13,
+       0x0d,0x94,0x99,0x7a,0xfb,0xc7,0x8f,0xca
+       };
+
+static const unsigned char hmac_sha512_additionalinput2[] =
+       {
+       0xc0,0xfd,0xea,0x00,0xee,0xdd,0xf3,0x4c,0x5e,0x4a,0x97,0x04,
+       0x3c,0xf0,0x97,0xce,0x75,0x90,0xad,0x51,0xf8,0xea,0xe9,0xc2,
+       0x2c,0xec,0x4d,0xb2,0xb4,0x1b,0xa6,0x15
+       };
+
+static const unsigned char hmac_sha512_entropyinputpr2[] =
+       {
+       0x63,0xfb,0x80,0xa7,0xf9,0xce,0x87,0xbd,0xe2,0xf0,0xfa,0x82,
+       0x4b,0xe2,0x7e,0xce,0x90,0xc1,0x30,0x54,0x1c,0x4e,0x9f,0x49,
+       0x82,0x3d,0x0a,0x52,0xdb,0xc0,0xda,0xb1
+       };
+
+static const unsigned char hmac_sha512_returnedbits[] =
+       {
+       0x6a,0x33,0x60,0x3d,0xe4,0x83,0x39,0x46,0xb3,0x3d,0x7d,0x16,
+       0x25,0xc8,0x69,0xb3,0x94,0x17,0x6b,0x23,0xec,0x4d,0xcb,0x23,
+       0xbd,0x92,0x1c,0xfa,0xa7,0xba,0x97,0x35,0xb9,0x54,0x47,0x88,
+       0x26,0x6d,0x6d,0x3f,0xc2,0xe3,0x5c,0x56,0x2c,0x50,0x5d,0x60,
+       0x11,0x3a,0x19,0x66,0xd9,0x0e,0x7c,0x08,0xfb,0xf9,0xf2,0xb4,
+       0xfb,0xcb,0xfc,0x49
+       };
+
+
 
 
 static DRBG_SELFTEST_DATA drbg_test[] = {
@@ -720,6 +992,11 @@ static DRBG_SELFTEST_DATA drbg_test[] = {
        make_drbg_test_data(NID_sha256, 0, sha256),
        make_drbg_test_data(NID_sha384, 0, sha384),
        make_drbg_test_data(NID_sha512, 0, sha512),
+       make_drbg_test_data(NID_hmacWithSHA1, 0, hmac_sha1),
+       make_drbg_test_data(NID_hmacWithSHA224, 0, hmac_sha224),
+       make_drbg_test_data(NID_hmacWithSHA256, 0, hmac_sha256),
+       make_drbg_test_data(NID_hmacWithSHA384, 0, hmac_sha384),
+       make_drbg_test_data(NID_hmacWithSHA512, 0, hmac_sha512),
        {0,0,0}
        };
 
index ff552dfe6ead7d2148050b6be444d5bb28ba55ce..b0e431d38f283706151fb2200858c5a30eb925b7 100644 (file)
@@ -166,6 +166,9 @@ int main(int argc,char **argv)
        long entlen, noncelen, perslen, adinlen;
        int df = 0;
 
+       enum dtype { DRBG_NONE, DRBG_CTR, DRBG_HASH, DRBG_HMAC, DRBG_DUAL_EC }
+               drbg_type = DRBG_NONE;
+
        int randoutlen = 0;
 
        int gen = 0;
@@ -201,11 +204,52 @@ int main(int argc,char **argv)
        while (fgets(buf, sizeof(buf), in) != NULL)
                {
                fputs(buf, out);
+               if (drbg_type == DRBG_NONE)
+                       {
+                       if (strstr(buf, "CTR_DRBG"))
+                               drbg_type = DRBG_CTR;
+                       else if (strstr(buf, "Hash_DRBG"))
+                               drbg_type = DRBG_HASH;
+                       else if (strstr(buf, "HMAC_DRBG"))
+                               drbg_type = DRBG_HMAC;
+                       else if (strstr(buf, "Dual_EC_DRBG"))
+                               drbg_type = DRBG_DUAL_EC;
+                       else
+                               continue;
+                       }
                if (strlen(buf) > 4 && !strncmp(buf, "[SHA-", 5))
                        {
                        nid = parse_md(buf);
                        if (nid == NID_undef)
                                exit(1);
+                       if (drbg_type == DRBG_HMAC)
+                               {
+                               switch (nid)
+                                       {
+                                       case NID_sha1:
+                                       nid = NID_hmacWithSHA1;
+                                       break;
+
+                                       case NID_sha224:
+                                       nid = NID_hmacWithSHA224;
+                                       break;
+
+                                       case NID_sha256:
+                                       nid = NID_hmacWithSHA256;
+                                       break;
+
+                                       case NID_sha384:
+                                       nid = NID_hmacWithSHA384;
+                                       break;
+
+                                       case NID_sha512:
+                                       nid = NID_hmacWithSHA512;
+                                       break;
+
+                                       default:
+                                       exit(1);
+                                       }
+                               }
                        }
                if (strlen(buf) > 12 && !strncmp(buf, "[AES-", 5))
                        {
index c403e78f0d772956c42f54741f24a01b433c0d0b..2a2f996b651d1d949833b4d38960ec3c65980ec5 100644 (file)
 #ifndef HEADER_FIPS_RAND_H
 #define HEADER_FIPS_RAND_H
 
+#include <openssl/aes.h>
+#include <openssl/evp.h>
+#include <openssl/hmac.h>
+
 #ifdef OPENSSL_FIPS
 
 #ifdef  __cplusplus
index 98407e21ed752393868efda43723cce78bd27768..ce95633b37b926d8666d45c4d8c9ce7d04f5da2e 100644 (file)
@@ -52,6 +52,7 @@
  */
 
 typedef struct drbg_hash_ctx_st DRBG_HASH_CTX;
+typedef struct drbg_hmac_ctx_st DRBG_HMAC_CTX;
 typedef struct drbg_ctr_ctx_st DRBG_CTR_CTX;
 
 /* 888 bits from 10.1 table 2 */
@@ -67,6 +68,14 @@ struct drbg_hash_ctx_st
        unsigned char vtmp[HASH_PRNG_MAX_SEEDLEN];
        };
 
+struct drbg_hmac_ctx_st
+       {
+       const EVP_MD *md;
+       HMAC_CTX hctx;
+       unsigned char K[EVP_MAX_MD_SIZE];
+       unsigned char V[EVP_MAX_MD_SIZE];
+       };
+
 struct drbg_ctr_ctx_st
        {
        AES_KEY ks;
@@ -137,6 +146,7 @@ struct drbg_ctx_st
        union 
                {
                DRBG_HASH_CTX hash;
+               DRBG_HMAC_CTX hmac;
                DRBG_CTR_CTX  ctr;
                } d;
        /* Initialiase PRNG and setup callbacks below */