mirror of
https://github.com/openssl/openssl.git
synced 2025-03-19 19:50:42 +08:00
Add FIPS Self test for AES_ECB decrypt
Fixes #14807 Compliance with IG 9.4 requires that an inverse cipher function be tested if one is implemented. Just running AES_GCM encrypt/decrypt does not meet this requirement (Since only ECB, CBC, XTS, KW, KWP support the inverse function during decryption mode). Added a mode to the cipher test so that the AES_GCM only does an encrypt and AES_ECB only does a decrypt. TDES still does both. Reviewed-by: Paul Dale <pauli@openssl.org> (Merged from https://github.com/openssl/openssl/pull/14825)
This commit is contained in:
parent
28fd895305
commit
3fed27181a
@ -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<OSSL_SELF_TEST_DESC_CIPHER_AES_GCM>)
|
||||
=item "AES_GCM_Encrypt" (B<OSSL_SELF_TEST_DESC_CIPHER_AES_GCM>)
|
||||
|
||||
=item "AES_ECB_Decrypt" (B<OSSL_SELF_TEST_DESC_CIPHER_AES_ECB>)
|
||||
|
||||
=item "TDES" (B<OSSL_SELF_TEST_DESC_CIPHER_TDES>)
|
||||
|
||||
|
@ -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"
|
||||
|
@ -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)
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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',
|
||||
|
Loading…
x
Reference in New Issue
Block a user