diff --git a/doc/man7/OSSL_PROVIDER-FIPS.pod b/doc/man7/OSSL_PROVIDER-FIPS.pod index ad7c4a6244..fbb2443f3c 100644 --- a/doc/man7/OSSL_PROVIDER-FIPS.pod +++ b/doc/man7/OSSL_PROVIDER-FIPS.pod @@ -267,7 +267,9 @@ Key generation tests used with the "Pairwise_Consistency_Test" type. "KAT_AsymmetricCipher" uses this to indicate an encrypt or decrypt KAT. -=item "AES_GCM" (B) +=item "AES_GCM_Encrypt" (B) + +=item "AES_ECB_Decrypt" (B) =item "TDES" (B) diff --git a/include/openssl/self_test.h b/include/openssl/self_test.h index 3b324b2bbe..cc5278243b 100644 --- a/include/openssl/self_test.h +++ b/include/openssl/self_test.h @@ -44,7 +44,8 @@ extern "C" { # define OSSL_SELF_TEST_DESC_PCT_RSA_PKCS1 "RSA" # define OSSL_SELF_TEST_DESC_PCT_ECDSA "ECDSA" # define OSSL_SELF_TEST_DESC_PCT_DSA "DSA" -# define OSSL_SELF_TEST_DESC_CIPHER_AES_GCM "AES_GCM" +# define OSSL_SELF_TEST_DESC_CIPHER_AES_GCM "AES_GCM_Encrypt" +# define OSSL_SELF_TEST_DESC_CIPHER_AES_ECB "AES_ECB_Decrypt" # define OSSL_SELF_TEST_DESC_CIPHER_TDES "TDES" # define OSSL_SELF_TEST_DESC_ASYM_RSA_ENC "RSA_Encrypt" # define OSSL_SELF_TEST_DESC_ASYM_RSA_DEC "RSA_Decrypt" diff --git a/providers/fips/self_test_data.inc b/providers/fips/self_test_data.inc index 49ffb7aab6..21ad526418 100644 --- a/providers/fips/self_test_data.inc +++ b/providers/fips/self_test_data.inc @@ -40,9 +40,14 @@ typedef struct st_kat_st { size_t expected_len; } ST_KAT; +#define CIPHER_MODE_ENCRYPT 1 +#define CIPHER_MODE_DECRYPT 2 +#define CIPHER_MODE_ALL (CIPHER_MODE_ENCRYPT | CIPHER_MODE_DECRYPT) + typedef ST_KAT ST_KAT_DIGEST; typedef struct st_kat_cipher_st { ST_KAT base; + int mode; const unsigned char *key; size_t key_len; const unsigned char *iv; @@ -215,6 +220,20 @@ static const unsigned char aes_256_gcm_tag[] = { 0x14, 0xd9, 0xc5, 0x1e, 0x1d, 0xa4, 0x74, 0xab }; +/* AES-ECB test data */ +static const unsigned char aes_128_ecb_key[] = { + 0x10, 0xa5, 0x88, 0x69, 0xd7, 0x4b, 0xe5, 0xa3, + 0x74, 0xcf, 0x86, 0x7c, 0xfb, 0x47, 0x38, 0x59 +}; +static const unsigned char aes_128_ecb_pt[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; +static const unsigned char aes_128_ecb_ct[] = { + 0x6d, 0x25, 0x1e, 0x69, 0x44, 0xb0, 0x51, 0xe0, + 0x4e, 0xaa, 0x6f, 0xb4, 0xdb, 0xf7, 0x84, 0x65 +}; + static const ST_KAT_CIPHER st_kat_cipher_tests[] = { #ifndef OPENSSL_NO_DES { @@ -224,6 +243,7 @@ static const ST_KAT_CIPHER st_kat_cipher_tests[] = { ITM(des_ede3_cbc_pt), ITM(des_ede3_cbc_ct) }, + CIPHER_MODE_ENCRYPT | CIPHER_MODE_DECRYPT, ITM(des_ede3_cbc_key), ITM(des_ede3_cbc_iv), }, @@ -233,12 +253,23 @@ static const ST_KAT_CIPHER st_kat_cipher_tests[] = { OSSL_SELF_TEST_DESC_CIPHER_AES_GCM, "AES-256-GCM", ITM(aes_256_gcm_pt), - ITM(aes_256_gcm_ct), + ITM(aes_256_gcm_ct) }, + CIPHER_MODE_ENCRYPT, ITM(aes_256_gcm_key), ITM(aes_256_gcm_iv), ITM(aes_256_gcm_aad), ITM(aes_256_gcm_tag) + }, + { + { + OSSL_SELF_TEST_DESC_CIPHER_AES_ECB, + "AES-128-ECB", + ITM(aes_128_ecb_pt), + ITM(aes_128_ecb_ct) + }, + CIPHER_MODE_DECRYPT, + ITM(aes_128_ecb_key) } }; diff --git a/providers/fips/self_test_kats.c b/providers/fips/self_test_kats.c index ba8e835bd7..0041a88842 100644 --- a/providers/fips/self_test_kats.c +++ b/providers/fips/self_test_kats.c @@ -85,7 +85,7 @@ static int cipher_init(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, static int self_test_cipher(const ST_KAT_CIPHER *t, OSSL_SELF_TEST *st, OSSL_LIB_CTX *libctx) { - int ret = 0, encrypt = 1, len, ct_len = 0, pt_len = 0; + int ret = 0, encrypt = 1, len = 0, ct_len = 0, pt_len = 0; EVP_CIPHER_CTX *ctx = NULL; EVP_CIPHER *cipher = NULL; unsigned char ct_buf[256] = { 0 }; @@ -96,39 +96,47 @@ static int self_test_cipher(const ST_KAT_CIPHER *t, OSSL_SELF_TEST *st, ctx = EVP_CIPHER_CTX_new(); if (ctx == NULL) goto err; - cipher = EVP_CIPHER_fetch(libctx, t->base.algorithm, ""); + cipher = EVP_CIPHER_fetch(libctx, t->base.algorithm, NULL); if (cipher == NULL) goto err; /* Encrypt plain text message */ - if (!cipher_init(ctx, cipher, t, encrypt) - || !EVP_CipherUpdate(ctx, ct_buf, &len, t->base.pt, t->base.pt_len) - || !EVP_CipherFinal_ex(ctx, ct_buf + len, &ct_len)) - goto err; - - OSSL_SELF_TEST_oncorrupt_byte(st, ct_buf); - ct_len += len; - if (ct_len != (int)t->base.expected_len - || memcmp(t->base.expected, ct_buf, ct_len) != 0) - goto err; - - if (t->tag != NULL) { - unsigned char tag[16] = { 0 }; - - if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, t->tag_len, tag) - || memcmp(tag, t->tag, t->tag_len) != 0) + if ((t->mode & CIPHER_MODE_ENCRYPT) != 0) { + if (!cipher_init(ctx, cipher, t, encrypt) + || !EVP_CipherUpdate(ctx, ct_buf, &len, t->base.pt, + t->base.pt_len) + || !EVP_CipherFinal_ex(ctx, ct_buf + len, &ct_len)) goto err; + + OSSL_SELF_TEST_oncorrupt_byte(st, ct_buf); + ct_len += len; + if (ct_len != (int)t->base.expected_len + || memcmp(t->base.expected, ct_buf, ct_len) != 0) + goto err; + + if (t->tag != NULL) { + unsigned char tag[16] = { 0 }; + + if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, t->tag_len, + tag) + || memcmp(tag, t->tag, t->tag_len) != 0) + goto err; + } } - if (!(cipher_init(ctx, cipher, t, !encrypt) - && EVP_CipherUpdate(ctx, pt_buf, &len, ct_buf, ct_len) - && EVP_CipherFinal_ex(ctx, pt_buf + len, &pt_len))) - goto err; - pt_len += len; - - if (pt_len != (int)t->base.pt_len - || memcmp(pt_buf, t->base.pt, pt_len) != 0) - goto err; + /* Decrypt cipher text */ + if ((t->mode & CIPHER_MODE_DECRYPT) != 0) { + if (!(cipher_init(ctx, cipher, t, !encrypt) + && EVP_CipherUpdate(ctx, pt_buf, &len, + t->base.expected, t->base.expected_len) + && EVP_CipherFinal_ex(ctx, pt_buf + len, &pt_len))) + goto err; + OSSL_SELF_TEST_oncorrupt_byte(st, pt_buf); + pt_len += len; + if (pt_len != (int)t->base.pt_len + || memcmp(pt_buf, t->base.pt, pt_len) != 0) + goto err; + } ret = 1; err: diff --git a/test/recipes/03-test_fipsinstall.t b/test/recipes/03-test_fipsinstall.t index 9ba6d2eb85..bc0c94cc97 100644 --- a/test/recipes/03-test_fipsinstall.t +++ b/test/recipes/03-test_fipsinstall.t @@ -24,7 +24,7 @@ use platform; plan skip_all => "Test only supported in a fips build" if disabled("fips"); -plan tests => 24; +plan tests => 26; my $infile = bldtop_file('providers', platform->dso('fips')); my $fipskey = $ENV{FIPSKEY} // '00'; @@ -191,6 +191,20 @@ ok(!run(app(['openssl', 'fipsinstall', '-out', 'fips_fail.cnf', '-module', $infi '-section_name', 'fips_sect', '-corrupt_desc', 'SHA3'])), "fipsinstall fails when the digest result is corrupted"); +# corrupt cipher encrypt test +ok(!run(app(['openssl', 'fipsinstall', '-out', 'fips_fail.cnf', '-module', $infile, + '-provider_name', 'fips', '-mac_name', 'HMAC', + '-macopt', 'digest:SHA256', '-macopt', "hexkey:$fipskey", + '-section_name', 'fips_sect', '-corrupt_desc', 'AES_GCM_Encrypt'])), + "fipsinstall fails when the AES_GCM result is corrupted"); + +# corrupt cipher decrypt test +ok(!run(app(['openssl', 'fipsinstall', '-out', 'fips_fail.cnf', '-module', $infile, + '-provider_name', 'fips', '-mac_name', 'HMAC', + '-macopt', 'digest:SHA256', '-macopt', "hexkey:$fipskey", + '-section_name', 'fips_sect', '-corrupt_desc', 'AES_ECB_Decrypt'])), + "fipsinstall fails when the AES_ECB result is corrupted"); + # corrupt DRBG ok(!run(app(['openssl', 'fipsinstall', '-out', 'fips_fail.cnf', '-module', $infile, '-provider_name', 'fips', '-mac_name', 'HMAC',