From c4628983056da55c81063f65cfa9262eeb757d43 Mon Sep 17 00:00:00 2001 From: Stephan Mueller Date: Sun, 25 Nov 2018 13:46:44 +0100 Subject: DRBG: Remove all traces of FIPS 140-2 continuous self test The removal allows the CAVS / ACVP test required for a successful FIPS 140-2 validation to pass. Signed-off-by: Stephan Mueller --- lib/nettle/int/drbg-aes.c | 16 ---------------- lib/nettle/int/drbg-aes.h | 2 -- 2 files changed, 18 deletions(-) diff --git a/lib/nettle/int/drbg-aes.c b/lib/nettle/int/drbg-aes.c index a5a05b64a8..d8b0780cff 100644 --- a/lib/nettle/int/drbg-aes.c +++ b/lib/nettle/int/drbg-aes.c @@ -143,32 +143,16 @@ int drbg_aes_generate(struct drbg_aes_ctx *ctx, unsigned length, uint8_t * dst, memset(seed, 0, DRBG_AES_SEED_SIZE); } - /* Throw the first block generated. FIPS 140-2 requirement (see - * the continuous random number generator test in 4.9.2) - */ - if (ctx->prev_block_present == 0) { - INCREMENT(sizeof(ctx->v), ctx->v); - aes256_encrypt(&ctx->key, AES_BLOCK_SIZE, ctx->prev_block, ctx->v); - - ctx->prev_block_present = 1; - } - /* Perform the actual encryption */ for (left = length; left >= AES_BLOCK_SIZE; left -= AES_BLOCK_SIZE, dst += AES_BLOCK_SIZE) { - INCREMENT(sizeof(ctx->v), ctx->v); aes256_encrypt(&ctx->key, AES_BLOCK_SIZE, dst, ctx->v); - - memcpy(ctx->prev_block, dst, AES_BLOCK_SIZE); } if (left > 0) { /* partial fill */ - INCREMENT(sizeof(ctx->v), ctx->v); aes256_encrypt(&ctx->key, AES_BLOCK_SIZE, tmp, ctx->v); - - memcpy(ctx->prev_block, tmp, AES_BLOCK_SIZE); memcpy(dst, tmp, left); } diff --git a/lib/nettle/int/drbg-aes.h b/lib/nettle/int/drbg-aes.h index 1d421a69e9..5d03929662 100644 --- a/lib/nettle/int/drbg-aes.h +++ b/lib/nettle/int/drbg-aes.h @@ -50,8 +50,6 @@ struct drbg_aes_ctx { uint8_t v[AES_BLOCK_SIZE]; - unsigned prev_block_present; - uint8_t prev_block[AES_BLOCK_SIZE]; unsigned reseed_counter; }; -- cgit v1.2.1 From 3e8d160eebbbaf55123ac792e55ad8465b8a5202 Mon Sep 17 00:00:00 2001 From: Stephan Mueller Date: Tue, 27 Nov 2018 22:27:26 +0100 Subject: DRBG: Use ACVP validated test vector in self test Due to removing all of the FIPS 140-2 continuous self test leftovers, the DRBG test vector must be updated as the very first DRBG block is not dropped any more. The test complies with the CAVP test definition specified in "The NIST SP 800-90A Deterministic Random Bit Generator Validation System (DRBGVS)" section 6.2. The test vector is obtained during a successful trial run using the NIST ACVP server. The following registration was used to generate the test vector: { "algorithm":"ctrDRBG", "prereqVals":[ { "algorithm":"AES", "valValue":"same" } ], "predResistanceEnabled":[ false ], "reseedImplemented":true, "capabilities":[ { "mode":"AES-256", "derFuncEnabled":false, "entropyInputLen":[ 384 ], "nonceLen":[ 0 ], "persoStringLen":[ 0, 256 ], "additionalInputLen":[ 0, 256 ], "returnedBitsLen":512 } ] }, Signed-off-by: Stephan Mueller --- lib/nettle/int/drbg-aes-self-test.c | 147 ++++++++++++++++-------------------- 1 file changed, 66 insertions(+), 81 deletions(-) diff --git a/lib/nettle/int/drbg-aes-self-test.c b/lib/nettle/int/drbg-aes-self-test.c index d50ca19c3c..fe056c6a11 100644 --- a/lib/nettle/int/drbg-aes-self-test.c +++ b/lib/nettle/int/drbg-aes-self-test.c @@ -28,8 +28,10 @@ struct self_test_st { const uint8_t entropy[DRBG_AES_SEED_SIZE]; - const char *pstring; - const uint8_t res[4][16]; + const uint8_t pstring[32]; + const uint8_t reseed[DRBG_AES_SEED_SIZE]; + const uint8_t addtl[3][32]; + const uint8_t res[64]; }; struct priv_st { @@ -40,64 +42,49 @@ struct priv_st { int drbg_aes_self_test(void) { static const struct self_test_st tv[] = { + /* + * Test vector from NIST ACVP test framework that was + * successfully validated by ACVP server. + */ { - .entropy = {0xb9, 0xca, 0x7f, 0xd6, 0xa0, 0xf5, 0xd3, 0x42, - 0x19, 0x6d, 0x84, 0x91, 0x76, 0x1c, 0x3b, 0xbe, - 0x48, 0xb2, 0x82, 0x98, 0x68, 0xc2, 0x80, 0x00, - 0x19, 0x6d, 0x84, 0x91, 0x76, 0x1c, 0x3b, 0xbe, - 0x48, 0xb2, 0x82, 0x98, 0x68, 0xc2, 0x80, 0x00, - 0x00, 0x00, 0x28, 0x18, 0x00, 0x00, 0x25, 0x00}, - .pstring = "test test test", - .res = { - {0xa4, 0xae, 0xb4, 0x51, 0xd0, 0x0d, 0x97, 0xcc, 0x46, - 0xbb, 0xc0, 0xec, 0x5c, 0xa1, 0xf0, 0x34}, - {0x68, 0xc4, 0x04, 0x63, 0x3d, 0x9e, 0x2c, 0x05, 0x18, - 0xcf, 0xde, 0x2a, 0x4c, 0x49, 0xc8, 0x2b}, - {0x60, 0x5a, 0xd6, 0x71, 0x5e, 0xb3, 0x86, 0x22, 0xd5, - 0x21, 0x7f, 0xd7, 0x1d, 0xa3, 0xff, 0xa6}, - {0xe0, 0xf8, 0x77, 0x2c, 0xcb, 0xa4, 0x52, 0xa5, 0x35, - 0xf5, 0x21, 0xb9, 0x20, 0x4e, 0xff, 0x3e}, - } - }, - { - .entropy = { - 0xb9, 0xca, 0x7f, 0xd6, 0xa0, 0xf5, 0xd3, 0x42, - 0x19, 0x6d, 0x84, 0x91, 0x76, 0x1c, 0x3b, 0xbe, - 0x48, 0xb2, 0x82, 0x98, 0x68, 0xc2, 0x80, 0x00, - 0x19, 0x6d, 0x84, 0x91, 0x76, 0x1c, 0x3b, 0xbe, - 0x48, 0xb2, 0x82, 0x98, 0x68, 0xc2, 0x80, 0x00, - 0x00, 0x00, 0x28, 0x18, 0x00, 0x00, 0x25, 0x00}, - .pstring = "tost tost test", - .res = { - {0x47, 0x2d, 0x1e, 0xa9, 0xe9, 0xed, 0x02, 0xba, 0x0b, - 0x8f, 0xc7, 0x59, 0x84, 0xe0, 0x7d, 0x6e}, - {0x4c, 0x63, 0xfd, 0xc9, 0x17, 0x1e, 0x09, 0xca, 0x62, - 0x72, 0x45, 0x4f, 0xeb, 0x5b, 0xd0, 0x02}, - {0x3e, 0x29, 0x1c, 0xde, 0xd9, 0xdd, 0x65, 0x4f, 0xfe, - 0xcd, 0x17, 0xa3, 0xa0, 0x23, 0x3b, 0xd5}, - {0x2b, 0x45, 0xd2, 0x4a, 0xf9, 0xd4, 0x91, 0xa4, 0x2e, - 0xaf, 0xe6, 0xb5, 0x40, 0xb4, 0xf5, 0xd7}, - } - }, - { - .entropy = { - 0x42, 0x9c, 0x08, 0x3d, 0x82, 0xf4, 0x8a, 0x40, - 0x66, 0xb5, 0x49, 0x27, 0xab, 0x42, 0xc7, 0xc3, - 0x0e, 0xb7, 0x61, 0x3c, 0xfe, 0xb0, 0xbe, 0x73, - 0xf7, 0x6e, 0x6d, 0x6f, 0x1d, 0xa3, 0x14, 0xfa, - 0xbb, 0x4b, 0xc1, 0x0e, 0xc5, 0xfb, 0xcd, 0x46, - 0xbe, 0x28, 0x61, 0xe7, 0x03, 0x2b, 0x37, 0x7d}, - .pstring = "one two", - .res = { - {0x6c, 0x29, 0x75, 0xdc, 0xd3, 0xaf, 0xfa, 0xf0, 0xe9, - 0xa8, 0xa4, 0xd8, 0x60, 0x62, 0xc9, 0xaa}, - {0x2b, 0xac, 0x71, 0x36, 0x42, 0xbf, 0x2a, 0xff, 0xa7, - 0xc7, 0xf6, 0x08, 0xa4, 0x3b, 0xe6, 0x00}, - {0x1d, 0x2c, 0x18, 0xbc, 0xc4, 0xbe, 0x64, 0x4b, 0x9a, - 0x6c, 0x45, 0xcb, 0x6b, 0xf2, 0xed, 0xc3}, - {0xe3, 0x41, 0x58, 0x24, 0x57, 0xa0, 0x60, 0xad, 0xb6, - 0x45, 0x8d, 0x8f, 0x32, 0x81, 0x77, 0xa9}, - } + .entropy = { 0xBE, 0x36, 0xDA, 0x22, 0xC5, 0xEE, 0xC2, 0x46, + 0x88, 0xAF, 0xD5, 0xFB, 0xC7, 0x12, 0x98, 0x58, + 0x32, 0xD0, 0x35, 0x89, 0x33, 0xF0, 0xFA, 0x2B, + 0x1B, 0x0D, 0x02, 0xE9, 0x3A, 0x28, 0x5F, 0x06, + 0x04, 0x3B, 0x97, 0x5F, 0xED, 0xD6, 0x2D, 0xC5, + 0xD9, 0x76, 0x42, 0x06, 0xEC, 0x80, 0x55, 0xFB }, + .pstring = { 0x50, 0xF9, 0x47, 0x14, 0x27, 0xF4, 0xA0, 0xAF, + 0x30, 0x08, 0x74, 0x85, 0xC7, 0x94, 0xA3, 0x5D, + 0x8F, 0x4F, 0x43, 0x52, 0x0C, 0xC0, 0x64, 0x47, + 0xF8, 0xAD, 0xC7, 0xB2, 0x6C, 0x7F, 0x26, 0x6E }, + .reseed = { 0x64, 0xDB, 0x9E, 0xC3, 0x45, 0x88, 0xED, 0x33, + 0xC8, 0x4C, 0xE2, 0x87, 0x12, 0x9C, 0xCA, 0x02, + 0x16, 0x41, 0xB5, 0x3B, 0xCB, 0x5F, 0x01, 0xAE, + 0xA0, 0x01, 0xBB, 0x16, 0x44, 0x1B, 0x99, 0x82, + 0x97, 0x84, 0x5B, 0x16, 0x58, 0xF3, 0xBD, 0xBE, + 0x9A, 0xAB, 0x9F, 0xB7, 0xB2, 0x93, 0xBE, 0xA5 }, + .addtl = { + { 0x10, 0xDD, 0xBC, 0x33, 0x29, 0x10, 0x53, 0x4C, + 0xA0, 0x10, 0x72, 0xBF, 0x4C, 0x55, 0xDD, 0x7C, + 0x08, 0x5F, 0xDF, 0x40, 0xB6, 0x03, 0xF2, 0xBC, + 0xEA, 0xAE, 0x08, 0x46, 0x61, 0x68, 0x91, 0xC9 }, + { 0x00, 0xB6, 0x84, 0xF7, 0xF3, 0x14, 0xC7, 0x80, + 0x57, 0xA4, 0x8F, 0x48, 0xE5, 0xC9, 0x7F, 0x8D, + 0x54, 0x88, 0x96, 0xDF, 0x94, 0x55, 0xB1, 0x1C, + 0xFA, 0xCF, 0xE0, 0x4D, 0xAA, 0x01, 0xFA, 0x25 }, + { 0x97, 0x02, 0xDB, 0xCB, 0x85, 0x2A, 0xAA, 0x55, + 0x96, 0xC7, 0xF8, 0xF3, 0xB3, 0x9B, 0xBC, 0xCA, + 0xB5, 0xC1, 0x7C, 0x1C, 0x0D, 0x2F, 0x5B, 0x0E, + 0x9B, 0xBA, 0xB4, 0xDD, 0x45, 0x90, 0xF2, 0x14 }, + }, + .res = { 0xfe, 0x78, 0x3c, 0x64, 0x98, 0xb8, 0x69, 0x1d, + 0xb7, 0xd4, 0xfb, 0x71, 0xdb, 0x58, 0xd2, 0xee, + 0x32, 0x63, 0xfd, 0xed, 0x78, 0xe7, 0x93, 0x13, + 0x65, 0xd7, 0xf8, 0x6b, 0x71, 0x90, 0xfc, 0xf4, + 0xa3, 0x29, 0xae, 0x0b, 0xca, 0x40, 0x23, 0x61, + 0x6c, 0xa3, 0xf8, 0xc6, 0x75, 0x15, 0x38, 0x36, + 0x11, 0x5c, 0xc0, 0x87, 0x8a, 0x9b, 0x91, 0xdb, + 0x56, 0xb9, 0x06, 0x98, 0xc5, 0x78, 0x1a, 0x3a } }, }; unsigned i, j; @@ -106,7 +93,7 @@ int drbg_aes_self_test(void) struct priv_st priv; int ret, saved; uint8_t *tmp; - unsigned char result[16]; + unsigned char result[64]; memset(&priv, 0, sizeof(priv)); priv.ctx = &test_ctx; @@ -127,38 +114,36 @@ int drbg_aes_self_test(void) } for (i = 0; i < sizeof(tv) / sizeof(tv[0]); i++) { - /* Setup the key. */ - ret = - drbg_aes_init(&test_ctx, DRBG_AES_SEED_SIZE, tv[i].entropy, - strlen(tv[i].pstring), (void *)tv[i].pstring); + /* CAVP test step 1: initialization with perso string */ + ret = drbg_aes_init(&test_ctx, + sizeof(tv[i].entropy), tv[i].entropy, + sizeof(tv[i].pstring), tv[i].pstring); if (ret == 0) goto fail; if (drbg_aes_is_seeded(&test_ctx) == 0) goto fail; - /* Get and compare the first three results. */ - for (j = 0; j < 3; j++) { - /* Compute the next value. */ - if (drbg_aes_random(&test_ctx, 16, result) == 0) - goto fail; - - /* Compare it to the known value. */ - if (memcmp(result, tv[i].res[j], 16) != 0) { - goto fail; - } - } - - ret = - drbg_aes_reseed(&test_ctx, DRBG_AES_SEED_SIZE, - tv[i].entropy, 0, NULL); + /* CAVP test step 2: reseed with addtl information */ + ret = drbg_aes_reseed(&test_ctx, + sizeof(tv[i].reseed), tv[i].reseed, + sizeof(tv[i].addtl[0]), tv[i].addtl[0]); if (ret == 0) goto fail; - if (drbg_aes_random(&test_ctx, 16, result) == 0) + /* CAVP test step 3: generate with addtl info, discard result */ + if (drbg_aes_generate(&test_ctx, sizeof(result), result, + sizeof(tv[i].addtl[1]), + tv[i].addtl[1]) == 0) + goto fail; + + /* CAVP test step 4: generate with addtl info */ + if (drbg_aes_generate(&test_ctx, sizeof(result), result, + sizeof(tv[i].addtl[2]), + tv[i].addtl[2]) == 0) goto fail; - if (memcmp(result, tv[i].res[3], 16) != 0) { + if (memcmp(result, tv[i].res, sizeof(result)) != 0) { goto fail; } -- cgit v1.2.1