Loading CHANGES +7 −0 Original line number Diff line number Diff line Loading @@ -4,6 +4,13 @@ Changes between 1.0.1 and 1.1.0 [xx XXX xxxx] *) Use separate DRBG fields for internal and external flags. New function FIPS_drbg_test() to perform on demand health checking. Add generation tests to fips_test_suite with reduced health check interval to demonstrate periodic health checking. Add "nodh" option to fips_test_suite to skip very slow DH test. [Steve Henson] *) New function FIPS_get_cipherbynid() to lookup FIPS supported ciphers based on NID. [Steve Henson] Loading fips/fips_test_suite.c +113 −4 Original line number Diff line number Diff line Loading @@ -43,6 +43,7 @@ int main(int argc, char *argv[]) #include <openssl/dh.h> #include <openssl/fips.h> #include <openssl/fips_rand.h> #include "fips_utl.h" /* AES: encrypt and decrypt known plaintext, verify result matches original plaintext Loading Loading @@ -653,6 +654,103 @@ static int Zeroize() return 1; } /* Dummy Entropy for DRBG tests. WARNING: THIS IS TOTALLY BOGUS * HAS ZERO SECURITY AND MUST NOT BE USED IN REAL APPLICATIONS. */ static unsigned char dummy_drbg_entropy[1024]; static size_t drbg_test_cb(DRBG_CTX *ctx, unsigned char **pout, int entropy, size_t min_len, size_t max_len) { *pout = dummy_drbg_entropy; /* Round up to multiple of block size */ return (min_len + 0xf) & ~0xf; } /* DRBG test: just generate lots of data and trigger health checks */ static int do_drbg_test(int type, int flags) { DRBG_CTX *dctx; int rv = 0; size_t i; unsigned char randout[1024]; dctx = FIPS_drbg_new(type, flags); if (!dctx) return 0; FIPS_drbg_set_callbacks(dctx, drbg_test_cb, 0, 0x10, drbg_test_cb, 0); for (i = 0; i < sizeof(dummy_drbg_entropy); i++) { dummy_drbg_entropy[i] = i & 0xff; } if (!FIPS_drbg_instantiate(dctx, dummy_drbg_entropy, 10)) goto err; FIPS_drbg_set_check_interval(dctx, 10); for (i = 0; i < 32; i++) { if (!FIPS_drbg_generate(dctx, randout, sizeof(randout), 0, NULL, 0)) goto err; if (!FIPS_drbg_generate(dctx, randout, sizeof(randout), 0, dummy_drbg_entropy, 1)) goto err; } rv = 1; err: FIPS_drbg_uninstantiate(dctx); return rv; } typedef struct { int type, flags; } DRBG_LIST; static int do_drbg_all(void) { static DRBG_LIST drbg_types[] = { {NID_sha1, 0}, {NID_sha224, 0}, {NID_sha256, 0}, {NID_sha384, 0}, {NID_sha512, 0}, {NID_hmacWithSHA1, 0}, {NID_hmacWithSHA224, 0}, {NID_hmacWithSHA256, 0}, {NID_hmacWithSHA384, 0}, {NID_hmacWithSHA512, 0}, {NID_aes_128_ctr, 0}, {NID_aes_192_ctr, 0}, {NID_aes_256_ctr, 0}, {NID_aes_128_ctr, DRBG_FLAG_CTR_USE_DF}, {NID_aes_192_ctr, DRBG_FLAG_CTR_USE_DF}, {NID_aes_256_ctr, DRBG_FLAG_CTR_USE_DF}, {(NID_X9_62_prime256v1 << 16)|NID_sha1, 0}, {(NID_X9_62_prime256v1 << 16)|NID_sha224, 0}, {(NID_X9_62_prime256v1 << 16)|NID_sha256, 0}, {(NID_X9_62_prime256v1 << 16)|NID_sha384, 0}, {(NID_X9_62_prime256v1 << 16)|NID_sha512, 0}, {(NID_secp384r1 << 16)|NID_sha224, 0}, {(NID_secp384r1 << 16)|NID_sha256, 0}, {(NID_secp384r1 << 16)|NID_sha384, 0}, {(NID_secp384r1 << 16)|NID_sha512, 0}, {(NID_secp521r1 << 16)|NID_sha256, 0}, {(NID_secp521r1 << 16)|NID_sha384, 0}, {(NID_secp521r1 << 16)|NID_sha512, 0}, {0, 0} }; DRBG_LIST *lst; int rv = 1; for (lst = drbg_types;; lst++) { if (lst->type == 0) break; if (!do_drbg_test(lst->type, lst->flags)) rv = 0; } return rv; } static int Error; static const char * Fail(const char *msg) { Loading Loading @@ -885,7 +983,7 @@ int main(int argc,char **argv) int do_rng_stick = 0; int do_drbg_stick = 0; int no_exit = 0; int no_dh = 0; FIPS_post_set_callback(post_cb); Loading Loading @@ -944,6 +1042,9 @@ int main(int argc,char **argv) fail_id = FIPS_TEST_DRBG; } else if (!strcmp(argv[1], "rng")) { fail_id = FIPS_TEST_X931; } else if (!strcmp(argv[1], "nodh")) { no_dh = 1; no_exit = 1; } else if (!strcmp(argv[1], "post")) { fail_id = -1; } else if (!strcmp(argv[1], "rngstick")) { Loading Loading @@ -976,6 +1077,9 @@ int main(int argc,char **argv) /* Non-Approved cryptographic operation */ printf("1. Non-Approved cryptographic operation test...\n"); if (no_dh) printf("\t D-H test skipped\n"); else test_msg("\ta. Included algorithm (D-H)...", dh_test()); /* Power-up self test Loading Loading @@ -1068,6 +1172,7 @@ int main(int argc,char **argv) */ printf("9. Non-Approved cryptographic operation test...\n"); printf("\ta. Included algorithm (D-H)...%s\n", no_dh ? "skipped" : dh_test() ? "successful as expected" : Fail("failed INCORRECTLY!") ); Loading @@ -1077,8 +1182,12 @@ int main(int argc,char **argv) Zeroize() ? "successful as expected" : Fail("failed INCORRECTLY!") ); printf("11. Complete DRBG health check...\n\t%s\n", FIPS_selftest_drbg_all() ? "successful as expected" printf("11. Complete DRBG health check...\n"); printf("\t%s\n", FIPS_selftest_drbg_all() ? "successful as expected" : Fail("failed INCORRECTLY!") ); printf("12. DRBG generation check...\n"); printf("\t%s\n", do_drbg_all() ? "successful as expected" : Fail("failed INCORRECTLY!") ); printf("\nAll tests completed with %d errors\n", Error); Loading fips/rand/fips_drbg_ctr.c +4 −4 Original line number Diff line number Diff line Loading @@ -263,7 +263,7 @@ static void ctr_Update(DRBG_CTX *dctx, memcpy(cctx->V, cctx->K + 24, 8); } if (dctx->flags & DRBG_FLAG_CTR_USE_DF) if (dctx->xflags & DRBG_FLAG_CTR_USE_DF) { /* If no input reuse existing derived value */ if (in1 || nonce || in2) Loading Loading @@ -316,7 +316,7 @@ static int drbg_ctr_generate(DRBG_CTX *dctx, { ctr_Update(dctx, adin, adinlen, NULL, 0, NULL, 0); /* This means we reuse derived value */ if (dctx->flags & DRBG_FLAG_CTR_USE_DF) if (dctx->xflags & DRBG_FLAG_CTR_USE_DF) { adin = NULL; adinlen = 1; Loading @@ -328,7 +328,7 @@ static int drbg_ctr_generate(DRBG_CTX *dctx, for (;;) { inc_128(cctx); if (!(dctx->flags & DRBG_FLAG_TEST) && !dctx->lb_valid) if (!(dctx->xflags & DRBG_FLAG_TEST) && !dctx->lb_valid) { AES_encrypt(cctx->V, dctx->lb, &cctx->ks); dctx->lb_valid = 1; Loading Loading @@ -398,7 +398,7 @@ int fips_drbg_ctr_init(DRBG_CTX *dctx) dctx->blocklength = 16; dctx->seedlen = keylen + 16; if (dctx->flags & DRBG_FLAG_CTR_USE_DF) if (dctx->xflags & DRBG_FLAG_CTR_USE_DF) { /* df initialisation */ static unsigned char df_key[32] = Loading fips/rand/fips_drbg_ec.c +2 −2 Original line number Diff line number Diff line Loading @@ -337,7 +337,7 @@ static int drbg_ec_generate(DRBG_CTX *dctx, dctx->reseed_counter++; /* Get rightmost bits of r to output buffer */ if (!(dctx->flags & DRBG_FLAG_TEST) && !dctx->lb_valid) if (!(dctx->xflags & DRBG_FLAG_TEST) && !dctx->lb_valid) { if (!bn2binpad(dctx->lb, dctx->blocklength, r)) goto err; Loading Loading @@ -499,7 +499,7 @@ int fips_drbg_ec_init(DRBG_CTX *dctx) return -2; } dctx->flags |= DRBG_CUSTOM_RESEED; dctx->iflags |= DRBG_CUSTOM_RESEED; dctx->reseed_counter = 0; dctx->instantiate = drbg_ec_instantiate; dctx->reseed = drbg_ec_reseed; Loading fips/rand/fips_drbg_hash.c +1 −1 Original line number Diff line number Diff line Loading @@ -193,7 +193,7 @@ static int hash_gen(DRBG_CTX *dctx, unsigned char *out, size_t outlen) { FIPS_digestinit(&hctx->mctx, hctx->md); FIPS_digestupdate(&hctx->mctx, hctx->vtmp, dctx->seedlen); if (!(dctx->flags & DRBG_FLAG_TEST) && !dctx->lb_valid) if (!(dctx->xflags & DRBG_FLAG_TEST) && !dctx->lb_valid) { FIPS_digestfinal(&hctx->mctx, dctx->lb, NULL); dctx->lb_valid = 1; Loading Loading
CHANGES +7 −0 Original line number Diff line number Diff line Loading @@ -4,6 +4,13 @@ Changes between 1.0.1 and 1.1.0 [xx XXX xxxx] *) Use separate DRBG fields for internal and external flags. New function FIPS_drbg_test() to perform on demand health checking. Add generation tests to fips_test_suite with reduced health check interval to demonstrate periodic health checking. Add "nodh" option to fips_test_suite to skip very slow DH test. [Steve Henson] *) New function FIPS_get_cipherbynid() to lookup FIPS supported ciphers based on NID. [Steve Henson] Loading
fips/fips_test_suite.c +113 −4 Original line number Diff line number Diff line Loading @@ -43,6 +43,7 @@ int main(int argc, char *argv[]) #include <openssl/dh.h> #include <openssl/fips.h> #include <openssl/fips_rand.h> #include "fips_utl.h" /* AES: encrypt and decrypt known plaintext, verify result matches original plaintext Loading Loading @@ -653,6 +654,103 @@ static int Zeroize() return 1; } /* Dummy Entropy for DRBG tests. WARNING: THIS IS TOTALLY BOGUS * HAS ZERO SECURITY AND MUST NOT BE USED IN REAL APPLICATIONS. */ static unsigned char dummy_drbg_entropy[1024]; static size_t drbg_test_cb(DRBG_CTX *ctx, unsigned char **pout, int entropy, size_t min_len, size_t max_len) { *pout = dummy_drbg_entropy; /* Round up to multiple of block size */ return (min_len + 0xf) & ~0xf; } /* DRBG test: just generate lots of data and trigger health checks */ static int do_drbg_test(int type, int flags) { DRBG_CTX *dctx; int rv = 0; size_t i; unsigned char randout[1024]; dctx = FIPS_drbg_new(type, flags); if (!dctx) return 0; FIPS_drbg_set_callbacks(dctx, drbg_test_cb, 0, 0x10, drbg_test_cb, 0); for (i = 0; i < sizeof(dummy_drbg_entropy); i++) { dummy_drbg_entropy[i] = i & 0xff; } if (!FIPS_drbg_instantiate(dctx, dummy_drbg_entropy, 10)) goto err; FIPS_drbg_set_check_interval(dctx, 10); for (i = 0; i < 32; i++) { if (!FIPS_drbg_generate(dctx, randout, sizeof(randout), 0, NULL, 0)) goto err; if (!FIPS_drbg_generate(dctx, randout, sizeof(randout), 0, dummy_drbg_entropy, 1)) goto err; } rv = 1; err: FIPS_drbg_uninstantiate(dctx); return rv; } typedef struct { int type, flags; } DRBG_LIST; static int do_drbg_all(void) { static DRBG_LIST drbg_types[] = { {NID_sha1, 0}, {NID_sha224, 0}, {NID_sha256, 0}, {NID_sha384, 0}, {NID_sha512, 0}, {NID_hmacWithSHA1, 0}, {NID_hmacWithSHA224, 0}, {NID_hmacWithSHA256, 0}, {NID_hmacWithSHA384, 0}, {NID_hmacWithSHA512, 0}, {NID_aes_128_ctr, 0}, {NID_aes_192_ctr, 0}, {NID_aes_256_ctr, 0}, {NID_aes_128_ctr, DRBG_FLAG_CTR_USE_DF}, {NID_aes_192_ctr, DRBG_FLAG_CTR_USE_DF}, {NID_aes_256_ctr, DRBG_FLAG_CTR_USE_DF}, {(NID_X9_62_prime256v1 << 16)|NID_sha1, 0}, {(NID_X9_62_prime256v1 << 16)|NID_sha224, 0}, {(NID_X9_62_prime256v1 << 16)|NID_sha256, 0}, {(NID_X9_62_prime256v1 << 16)|NID_sha384, 0}, {(NID_X9_62_prime256v1 << 16)|NID_sha512, 0}, {(NID_secp384r1 << 16)|NID_sha224, 0}, {(NID_secp384r1 << 16)|NID_sha256, 0}, {(NID_secp384r1 << 16)|NID_sha384, 0}, {(NID_secp384r1 << 16)|NID_sha512, 0}, {(NID_secp521r1 << 16)|NID_sha256, 0}, {(NID_secp521r1 << 16)|NID_sha384, 0}, {(NID_secp521r1 << 16)|NID_sha512, 0}, {0, 0} }; DRBG_LIST *lst; int rv = 1; for (lst = drbg_types;; lst++) { if (lst->type == 0) break; if (!do_drbg_test(lst->type, lst->flags)) rv = 0; } return rv; } static int Error; static const char * Fail(const char *msg) { Loading Loading @@ -885,7 +983,7 @@ int main(int argc,char **argv) int do_rng_stick = 0; int do_drbg_stick = 0; int no_exit = 0; int no_dh = 0; FIPS_post_set_callback(post_cb); Loading Loading @@ -944,6 +1042,9 @@ int main(int argc,char **argv) fail_id = FIPS_TEST_DRBG; } else if (!strcmp(argv[1], "rng")) { fail_id = FIPS_TEST_X931; } else if (!strcmp(argv[1], "nodh")) { no_dh = 1; no_exit = 1; } else if (!strcmp(argv[1], "post")) { fail_id = -1; } else if (!strcmp(argv[1], "rngstick")) { Loading Loading @@ -976,6 +1077,9 @@ int main(int argc,char **argv) /* Non-Approved cryptographic operation */ printf("1. Non-Approved cryptographic operation test...\n"); if (no_dh) printf("\t D-H test skipped\n"); else test_msg("\ta. Included algorithm (D-H)...", dh_test()); /* Power-up self test Loading Loading @@ -1068,6 +1172,7 @@ int main(int argc,char **argv) */ printf("9. Non-Approved cryptographic operation test...\n"); printf("\ta. Included algorithm (D-H)...%s\n", no_dh ? "skipped" : dh_test() ? "successful as expected" : Fail("failed INCORRECTLY!") ); Loading @@ -1077,8 +1182,12 @@ int main(int argc,char **argv) Zeroize() ? "successful as expected" : Fail("failed INCORRECTLY!") ); printf("11. Complete DRBG health check...\n\t%s\n", FIPS_selftest_drbg_all() ? "successful as expected" printf("11. Complete DRBG health check...\n"); printf("\t%s\n", FIPS_selftest_drbg_all() ? "successful as expected" : Fail("failed INCORRECTLY!") ); printf("12. DRBG generation check...\n"); printf("\t%s\n", do_drbg_all() ? "successful as expected" : Fail("failed INCORRECTLY!") ); printf("\nAll tests completed with %d errors\n", Error); Loading
fips/rand/fips_drbg_ctr.c +4 −4 Original line number Diff line number Diff line Loading @@ -263,7 +263,7 @@ static void ctr_Update(DRBG_CTX *dctx, memcpy(cctx->V, cctx->K + 24, 8); } if (dctx->flags & DRBG_FLAG_CTR_USE_DF) if (dctx->xflags & DRBG_FLAG_CTR_USE_DF) { /* If no input reuse existing derived value */ if (in1 || nonce || in2) Loading Loading @@ -316,7 +316,7 @@ static int drbg_ctr_generate(DRBG_CTX *dctx, { ctr_Update(dctx, adin, adinlen, NULL, 0, NULL, 0); /* This means we reuse derived value */ if (dctx->flags & DRBG_FLAG_CTR_USE_DF) if (dctx->xflags & DRBG_FLAG_CTR_USE_DF) { adin = NULL; adinlen = 1; Loading @@ -328,7 +328,7 @@ static int drbg_ctr_generate(DRBG_CTX *dctx, for (;;) { inc_128(cctx); if (!(dctx->flags & DRBG_FLAG_TEST) && !dctx->lb_valid) if (!(dctx->xflags & DRBG_FLAG_TEST) && !dctx->lb_valid) { AES_encrypt(cctx->V, dctx->lb, &cctx->ks); dctx->lb_valid = 1; Loading Loading @@ -398,7 +398,7 @@ int fips_drbg_ctr_init(DRBG_CTX *dctx) dctx->blocklength = 16; dctx->seedlen = keylen + 16; if (dctx->flags & DRBG_FLAG_CTR_USE_DF) if (dctx->xflags & DRBG_FLAG_CTR_USE_DF) { /* df initialisation */ static unsigned char df_key[32] = Loading
fips/rand/fips_drbg_ec.c +2 −2 Original line number Diff line number Diff line Loading @@ -337,7 +337,7 @@ static int drbg_ec_generate(DRBG_CTX *dctx, dctx->reseed_counter++; /* Get rightmost bits of r to output buffer */ if (!(dctx->flags & DRBG_FLAG_TEST) && !dctx->lb_valid) if (!(dctx->xflags & DRBG_FLAG_TEST) && !dctx->lb_valid) { if (!bn2binpad(dctx->lb, dctx->blocklength, r)) goto err; Loading Loading @@ -499,7 +499,7 @@ int fips_drbg_ec_init(DRBG_CTX *dctx) return -2; } dctx->flags |= DRBG_CUSTOM_RESEED; dctx->iflags |= DRBG_CUSTOM_RESEED; dctx->reseed_counter = 0; dctx->instantiate = drbg_ec_instantiate; dctx->reseed = drbg_ec_reseed; Loading
fips/rand/fips_drbg_hash.c +1 −1 Original line number Diff line number Diff line Loading @@ -193,7 +193,7 @@ static int hash_gen(DRBG_CTX *dctx, unsigned char *out, size_t outlen) { FIPS_digestinit(&hctx->mctx, hctx->md); FIPS_digestupdate(&hctx->mctx, hctx->vtmp, dctx->seedlen); if (!(dctx->flags & DRBG_FLAG_TEST) && !dctx->lb_valid) if (!(dctx->xflags & DRBG_FLAG_TEST) && !dctx->lb_valid) { FIPS_digestfinal(&hctx->mctx, dctx->lb, NULL); dctx->lb_valid = 1; Loading