diff --git a/CHANGES b/CHANGES index c4dc27a29..011df12db 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 bfd34c192..6046ae0f8 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 4045e2d62..a7f5b4675 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 2fdf0e8f3..51db7a41e 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 09ff330e2..bf10609de 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 4b2ac74b7..3478864ee 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 8872ba299..22377573c 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 881bce041..be892d810 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 ff552dfe6..b0e431d38 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 c403e78f0..2a2f996b6 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 98407e21e..ce95633b3 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 */