Loading CHANGES +4 −0 Original line number Diff line number Diff line Loading @@ -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 Loading fips/fips_test_suite.c +5 −0 Original line number Diff line number Diff line Loading @@ -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"}, Loading fips/rand/fips_drbg_ctr.c +0 −2 Original line number Diff line number Diff line Loading @@ -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" Loading fips/rand/fips_drbg_hash.c +0 −2 Original line number Diff line number Diff line Loading @@ -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" Loading fips/rand/fips_drbg_hmac.c +215 −1 Original line number Diff line number Diff line Loading @@ -61,7 +61,221 @@ #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) { 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; } Loading
CHANGES +4 −0 Original line number Diff line number Diff line Loading @@ -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 Loading
fips/fips_test_suite.c +5 −0 Original line number Diff line number Diff line Loading @@ -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"}, Loading
fips/rand/fips_drbg_ctr.c +0 −2 Original line number Diff line number Diff line Loading @@ -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" Loading
fips/rand/fips_drbg_hash.c +0 −2 Original line number Diff line number Diff line Loading @@ -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" Loading
fips/rand/fips_drbg_hmac.c +215 −1 Original line number Diff line number Diff line Loading @@ -61,7 +61,221 @@ #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) { 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; }