From 20f12e63ff3fb9ed04f99039605a449b3137847b Mon Sep 17 00:00:00 2001 From: "Dr. Stephen Henson" Date: Mon, 8 Aug 2011 22:07:38 +0000 Subject: [PATCH] Add HMAC DRBG from SP800-90 --- CHANGES | 4 + fips/fips_test_suite.c | 5 + fips/rand/fips_drbg_ctr.c | 2 - fips/rand/fips_drbg_hash.c | 2 - fips/rand/fips_drbg_hmac.c | 216 ++++++++++++++++++++++++- fips/rand/fips_drbg_lib.c | 2 - fips/rand/fips_drbg_rand.c | 2 - fips/rand/fips_drbg_selftest.c | 281 ++++++++++++++++++++++++++++++++- fips/rand/fips_drbgvs.c | 44 ++++++ fips/rand/fips_rand.h | 4 + fips/rand/fips_rand_lcl.h | 10 ++ 11 files changed, 561 insertions(+), 11 deletions(-) diff --git a/CHANGES b/CHANGES index c4dc27a298..011df12db3 100644 --- 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 diff --git a/fips/fips_test_suite.c b/fips/fips_test_suite.c index bfd34c1924..6046ae0f86 100644 --- a/fips/fips_test_suite.c +++ b/fips/fips_test_suite.c @@ -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"}, diff --git a/fips/rand/fips_drbg_ctr.c b/fips/rand/fips_drbg_ctr.c index 4045e2d627..a7f5b46753 100644 --- a/fips/rand/fips_drbg_ctr.c +++ b/fips/rand/fips_drbg_ctr.c @@ -54,8 +54,6 @@ #include #include #include -#include -#include #include #include #include "fips_rand_lcl.h" diff --git a/fips/rand/fips_drbg_hash.c b/fips/rand/fips_drbg_hash.c index 2fdf0e8f38..51db7a41ee 100644 --- a/fips/rand/fips_drbg_hash.c +++ b/fips/rand/fips_drbg_hash.c @@ -56,8 +56,6 @@ #include #include #include -#include -#include #include #include #include "fips_rand_lcl.h" diff --git a/fips/rand/fips_drbg_hmac.c b/fips/rand/fips_drbg_hmac.c index 09ff330e2e..bf10609dee 100644 --- a/fips/rand/fips_drbg_hmac.c +++ b/fips/rand/fips_drbg_hmac.c @@ -61,7 +61,221 @@ #include #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; } diff --git a/fips/rand/fips_drbg_lib.c b/fips/rand/fips_drbg_lib.c index 4b2ac74b7a..3478864eec 100644 --- a/fips/rand/fips_drbg_lib.c +++ b/fips/rand/fips_drbg_lib.c @@ -55,8 +55,6 @@ #include #include -#include -#include #include #include #include "fips_rand_lcl.h" diff --git a/fips/rand/fips_drbg_rand.c b/fips/rand/fips_drbg_rand.c index 8872ba2992..22377573c0 100644 --- a/fips/rand/fips_drbg_rand.c +++ b/fips/rand/fips_drbg_rand.c @@ -55,8 +55,6 @@ #include #include -#include -#include #include #include #include diff --git a/fips/rand/fips_drbg_selftest.c b/fips/rand/fips_drbg_selftest.c index 881bce041d..be892d810e 100644 --- a/fips/rand/fips_drbg_selftest.c +++ b/fips/rand/fips_drbg_selftest.c @@ -55,8 +55,6 @@ #include #include -#include -#include #include #include #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} }; diff --git a/fips/rand/fips_drbgvs.c b/fips/rand/fips_drbgvs.c index ff552dfe6e..b0e431d38f 100644 --- a/fips/rand/fips_drbgvs.c +++ b/fips/rand/fips_drbgvs.c @@ -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)) { diff --git a/fips/rand/fips_rand.h b/fips/rand/fips_rand.h index c403e78f0d..2a2f996b65 100644 --- a/fips/rand/fips_rand.h +++ b/fips/rand/fips_rand.h @@ -50,6 +50,10 @@ #ifndef HEADER_FIPS_RAND_H #define HEADER_FIPS_RAND_H +#include +#include +#include + #ifdef OPENSSL_FIPS #ifdef __cplusplus diff --git a/fips/rand/fips_rand_lcl.h b/fips/rand/fips_rand_lcl.h index 98407e21ed..ce95633b37 100644 --- a/fips/rand/fips_rand_lcl.h +++ b/fips/rand/fips_rand_lcl.h @@ -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 */ -- 2.34.1