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 c4dc27a..011df12 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 bfd34c1..6046ae0 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 4045e2d..a7f5b46 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 2fdf0e8..51db7a4 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 09ff330..bf10609 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 4b2ac74..3478864 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 8872ba2..2237757 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 881bce0..be892d8 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 ff552df..b0e431d 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 c403e78..2a2f996 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 98407e2..ce95633 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 */