From a197212e0f416767536a645079b559a601f87e6d Mon Sep 17 00:00:00 2001 From: "Dr. Stephen Henson" Date: Sun, 1 Jul 2007 23:19:15 +0000 Subject: [PATCH] Modify AES and 3DES selftests to use EVP. --- CHANGES | 2 +- fips-1.0/aes/fips_aes_selftest.c | 41 ++++------- fips-1.0/des/fips_des_selftest.c | 117 +++++++++++-------------------- fips-1.0/fips.c | 28 ++++++++ fips-1.0/fips.h | 10 +++ fips-1.0/fips_locl.h | 2 + 6 files changed, 95 insertions(+), 105 deletions(-) diff --git a/CHANGES b/CHANGES index 5f4ea05d0a..5cb29ca5fd 100644 --- a/CHANGES +++ b/CHANGES @@ -8,7 +8,7 @@ automatically use EVP_CIPHER_{get,set}_asn1_iv and avoid the need for any ASN1 dependencies in FIPS library. Move AES and 3DES cipher definitions to fips library and modify AES and 3DES algorithm - tests to use EVP. + tests and self tests to use EVP. [Steve Henson] *) Move EVP cipher code into enc_min.c to support a minimal implementation diff --git a/fips-1.0/aes/fips_aes_selftest.c b/fips-1.0/aes/fips_aes_selftest.c index 0e53d21bd0..441bbc18e7 100644 --- a/fips-1.0/aes/fips_aes_selftest.c +++ b/fips-1.0/aes/fips_aes_selftest.c @@ -50,7 +50,7 @@ #include #include #include -#include +#include #ifdef OPENSSL_FIPS static struct @@ -78,35 +78,24 @@ void FIPS_corrupt_aes() int FIPS_selftest_aes() { int n; + int ret = 0; + EVP_CIPHER_CTX ctx; + EVP_CIPHER_CTX_init(&ctx); - /* Encrypt and check against known ciphertext */ for(n=0 ; n < 1 ; ++n) { - AES_KEY key; - unsigned char buf[16]; - - AES_set_encrypt_key(tests[n].key,128,&key); - AES_encrypt(tests[n].plaintext,buf,&key); - if(memcmp(buf,tests[n].ciphertext,sizeof buf)) - { - FIPSerr(FIPS_F_FIPS_SELFTEST_AES,FIPS_R_SELFTEST_FAILED); - return 0; - } + if (fips_cipher_test(&ctx, EVP_aes_128_ecb(), + tests[n].key, NULL, + tests[n].plaintext, + tests[n].ciphertext, + 16) <= 0) + goto err; } - /* Decrypt and check against known plaintext */ - for(n=0 ; n < 1 ; ++n) - { - AES_KEY key; - unsigned char buf[16]; - - AES_set_decrypt_key(tests[n].key,128,&key); - AES_decrypt(tests[n].ciphertext,buf,&key); - if(memcmp(buf,tests[n].plaintext,sizeof buf)) - { + ret = 1; + err: + EVP_CIPHER_CTX_cleanup(&ctx); + if (ret == 0) FIPSerr(FIPS_F_FIPS_SELFTEST_AES,FIPS_R_SELFTEST_FAILED); - return 0; - } - } - return 1; + return ret; } #endif diff --git a/fips-1.0/des/fips_des_selftest.c b/fips-1.0/des/fips_des_selftest.c index 7dd01465a1..8ae215f131 100644 --- a/fips-1.0/des/fips_des_selftest.c +++ b/fips-1.0/des/fips_des_selftest.c @@ -50,13 +50,13 @@ #include #include #include -#include +#include #include #ifdef OPENSSL_FIPS static struct { - DES_cblock key; + unsigned char key[8]; unsigned char plaintext[8]; unsigned char ciphertext[8]; } tests[]= @@ -75,21 +75,20 @@ static struct static struct { - DES_cblock key1; - DES_cblock key2; + unsigned char key[16]; unsigned char plaintext[8]; unsigned char ciphertext[8]; } tests2[]= { { - { 0x7c,0x4f,0x6e,0xf7,0xa2,0x04,0x16,0xec }, - { 0x0b,0x6b,0x7c,0x9e,0x5e,0x19,0xa7,0xc4 }, + { 0x7c,0x4f,0x6e,0xf7,0xa2,0x04,0x16,0xec, + 0x0b,0x6b,0x7c,0x9e,0x5e,0x19,0xa7,0xc4 }, { 0x06,0xa7,0xd8,0x79,0xaa,0xce,0x69,0xef }, { 0x4c,0x11,0x17,0x55,0xbf,0xc4,0x4e,0xfd } }, { - { 0x5d,0x9e,0x01,0xd3,0x25,0xc7,0x3e,0x34 }, - { 0x01,0x16,0x7c,0x85,0x23,0xdf,0xe0,0x68 }, + { 0x5d,0x9e,0x01,0xd3,0x25,0xc7,0x3e,0x34, + 0x01,0x16,0x7c,0x85,0x23,0xdf,0xe0,0x68 }, { 0x9c,0x50,0x09,0x0f,0x5e,0x7d,0x69,0x7e }, { 0xd2,0x0b,0x18,0xdf,0xd9,0x0d,0x9e,0xff }, } @@ -97,24 +96,22 @@ static struct static struct { - DES_cblock key1; - DES_cblock key2; - DES_cblock key3; + unsigned char key[24]; unsigned char plaintext[8]; unsigned char ciphertext[8]; } tests3[]= { { - { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - { 0xFE,0xDC,0xBA,0x98,0x76,0x54,0x32,0x10 }, - { 0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0 }, - { 0x8f,0x8f,0xbf,0x9b,0x5d,0x48,0xb4,0x1c}, - { 0x59,0x8c,0xe5,0xd3,0x6c,0xa2,0xea,0x1b}, + { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xFE,0xDC,0xBA,0x98,0x76,0x54,0x32,0x10, + 0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0 }, + { 0x8f,0x8f,0xbf,0x9b,0x5d,0x48,0xb4,0x1c }, + { 0x59,0x8c,0xe5,0xd3,0x6c,0xa2,0xea,0x1b }, }, { - { 0xDC,0xBA,0x98,0x76,0x54,0x32,0x10,0xFE }, - { 0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF }, - { 0xED,0x39,0xD9,0x50,0xFA,0x74,0xBC,0xC4 }, + { 0xDC,0xBA,0x98,0x76,0x54,0x32,0x10,0xFE, + 0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF, + 0xED,0x39,0xD9,0x50,0xFA,0x74,0xBC,0xC4 }, { 0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF }, { 0x11,0x25,0xb0,0x35,0xbe,0xa0,0x82,0x86 }, }, @@ -127,78 +124,42 @@ void FIPS_corrupt_des() int FIPS_selftest_des() { - int n; - + int n, ret = 0; + EVP_CIPHER_CTX ctx; + EVP_CIPHER_CTX_init(&ctx); +#if 0 /* Encrypt/decrypt with DES and compare to known answers */ for(n=0 ; n < 2 ; ++n) { - DES_key_schedule key; - DES_cblock buf; - - DES_set_key(&tests[n].key,&key); - DES_ecb_encrypt(&tests[n].plaintext,&buf,&key,1); - if(memcmp(buf,tests[n].ciphertext,sizeof buf)) - { - FIPSerr(FIPS_F_FIPS_SELFTEST_DES,FIPS_R_SELFTEST_FAILED); - return 0; - } - DES_ecb_encrypt(&tests[n].ciphertext,&buf,&key,0); - if(memcmp(buf,tests[n].plaintext,sizeof buf)) - { - FIPSerr(FIPS_F_FIPS_SELFTEST_DES,FIPS_R_SELFTEST_FAILED); - return 0; - } + if (!fips_cipher_test(&ctx, EVP_des_ecb(), + tests[n].key, NULL, + tests[n].plaintext, tests[n].ciphertext, 8)) + goto err; } - +#endif /* Encrypt/decrypt with 2-key 3DES and compare to known answers */ for(n=0 ; n < 2 ; ++n) { - DES_key_schedule key1, key2; - unsigned char buf[8]; - - DES_set_key(&tests2[n].key1,&key1); - DES_set_key(&tests2[n].key2,&key2); - DES_ecb2_encrypt((const_DES_cblock *)tests2[n].plaintext, - (DES_cblock *)buf,&key1,&key2,1); - if(memcmp(buf,tests2[n].ciphertext,sizeof buf)) - { - FIPSerr(FIPS_F_FIPS_SELFTEST_DES,FIPS_R_SELFTEST_FAILED); - return 0; - } - DES_ecb2_encrypt((const_DES_cblock *)tests2[n].ciphertext, - (DES_cblock *)buf,&key1,&key2,0); - if(memcmp(buf,tests2[n].plaintext,sizeof buf)) - { - FIPSerr(FIPS_F_FIPS_SELFTEST_DES,FIPS_R_SELFTEST_FAILED); - return 0; - } + if (!fips_cipher_test(&ctx, EVP_des_ede_ecb(), + tests2[n].key, NULL, + tests2[n].plaintext, tests2[n].ciphertext, 8)) + goto err; } /* Encrypt/decrypt with 3DES and compare to known answers */ for(n=0 ; n < 2 ; ++n) { - DES_key_schedule key1, key2, key3; - unsigned char buf[8]; - - DES_set_key(&tests3[n].key1,&key1); - DES_set_key(&tests3[n].key2,&key2); - DES_set_key(&tests3[n].key3,&key3); - DES_ecb3_encrypt((const_DES_cblock *)tests3[n].plaintext, - (DES_cblock *)buf,&key1,&key2,&key3,1); - if(memcmp(buf,tests3[n].ciphertext,sizeof buf)) - { - FIPSerr(FIPS_F_FIPS_SELFTEST_DES,FIPS_R_SELFTEST_FAILED); - return 0; - } - DES_ecb3_encrypt((const_DES_cblock *)tests3[n].ciphertext, - (DES_cblock *)buf,&key1,&key2,&key3,0); - if(memcmp(buf,tests3[n].plaintext,sizeof buf)) - { - FIPSerr(FIPS_F_FIPS_SELFTEST_DES,FIPS_R_SELFTEST_FAILED); - return 0; - } + if (!fips_cipher_test(&ctx, EVP_des_ede3_ecb(), + tests3[n].key, NULL, + tests3[n].plaintext, tests3[n].ciphertext, 8)) + goto err; } + ret = 1; + err: + EVP_CIPHER_CTX_cleanup(&ctx); + if (ret == 0) + FIPSerr(FIPS_F_FIPS_SELFTEST_DES,FIPS_R_SELFTEST_FAILED); - return 1; + return ret; } #endif diff --git a/fips-1.0/fips.c b/fips-1.0/fips.c index f524bf1eb8..372aa59377 100644 --- a/fips-1.0/fips.c +++ b/fips-1.0/fips.c @@ -462,4 +462,32 @@ int fips_pkey_signature_test(EVP_PKEY *pkey, return 1; } +/* Generalized symmetric cipher test routine. Encrypt data, verify result + * against known answer, decrypt and compare with original plaintext. + */ + +int fips_cipher_test(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, + const unsigned char *key, + const unsigned char *iv, + const unsigned char *plaintext, + const unsigned char *ciphertext, + int len) + { + unsigned char pltmp[FIPS_MAX_CIPHER_TEST_SIZE]; + unsigned char citmp[FIPS_MAX_CIPHER_TEST_SIZE]; + OPENSSL_assert(len <= FIPS_MAX_CIPHER_TEST_SIZE); + if (EVP_CipherInit_ex(ctx, cipher, NULL, key, iv, 1) <= 0) + return 0; + EVP_Cipher(ctx, citmp, plaintext, len); + if (memcmp(citmp, ciphertext, len)) + return 0; + if (EVP_CipherInit_ex(ctx, cipher, NULL, key, iv, 0) <= 0) + return 0; + EVP_Cipher(ctx, pltmp, citmp, len); + if (memcmp(pltmp, plaintext, len)) + return 0; + return 1; + } + + #endif diff --git a/fips-1.0/fips.h b/fips-1.0/fips.h index d77ff3a32d..1ae60e39c1 100644 --- a/fips-1.0/fips.h +++ b/fips-1.0/fips.h @@ -58,6 +58,8 @@ extern "C" { struct dsa_st; struct evp_pkey_st; struct env_md_st; +struct evp_cipher_st; +struct evp_cipher_ctx_st; int FIPS_mode_set(int onoff); int FIPS_mode(void); @@ -84,6 +86,14 @@ int fips_pkey_signature_test(struct evp_pkey_st *pkey, const struct env_md_st *digest, unsigned int md_flags, const char *fail_str); +int fips_cipher_test(struct evp_cipher_ctx_st *ctx, + const struct evp_cipher_st *cipher, + const unsigned char *key, + const unsigned char *iv, + const unsigned char *plaintext, + const unsigned char *ciphertext, + int len); + /* BEGIN ERROR CODES */ /* The following lines are auto generated by the script mkerr.pl. Any changes * made after this point may be overwritten when the script is next run. diff --git a/fips-1.0/fips_locl.h b/fips-1.0/fips_locl.h index cc91341bee..06cb64d832 100644 --- a/fips-1.0/fips_locl.h +++ b/fips-1.0/fips_locl.h @@ -64,6 +64,8 @@ int fips_set_owning_thread(void); int fips_clear_owning_thread(void); unsigned char *fips_signature_witness(void); +#define FIPS_MAX_CIPHER_TEST_SIZE 16 + #ifdef __cplusplus } #endif -- 2.25.1