Modify AES and 3DES selftests to use EVP.

This commit is contained in:
Dr. Stephen Henson
2007-07-01 23:19:15 +00:00
parent 8944220221
commit a197212e0f
6 changed files with 95 additions and 105 deletions

View File

@@ -8,7 +8,7 @@
automatically use EVP_CIPHER_{get,set}_asn1_iv and avoid the automatically use EVP_CIPHER_{get,set}_asn1_iv and avoid the
need for any ASN1 dependencies in FIPS library. Move AES and 3DES need for any ASN1 dependencies in FIPS library. Move AES and 3DES
cipher definitions to fips library and modify AES and 3DES algorithm cipher definitions to fips library and modify AES and 3DES algorithm
tests to use EVP. tests and self tests to use EVP.
[Steve Henson] [Steve Henson]
*) Move EVP cipher code into enc_min.c to support a minimal implementation *) Move EVP cipher code into enc_min.c to support a minimal implementation

View File

@@ -50,7 +50,7 @@
#include <string.h> #include <string.h>
#include <openssl/err.h> #include <openssl/err.h>
#include <openssl/fips.h> #include <openssl/fips.h>
#include <openssl/aes.h> #include <openssl/evp.h>
#ifdef OPENSSL_FIPS #ifdef OPENSSL_FIPS
static struct static struct
@@ -78,35 +78,24 @@ void FIPS_corrupt_aes()
int FIPS_selftest_aes() int FIPS_selftest_aes()
{ {
int n; 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) for(n=0 ; n < 1 ; ++n)
{ {
AES_KEY key; if (fips_cipher_test(&ctx, EVP_aes_128_ecb(),
unsigned char buf[16]; tests[n].key, NULL,
tests[n].plaintext,
AES_set_encrypt_key(tests[n].key,128,&key); tests[n].ciphertext,
AES_encrypt(tests[n].plaintext,buf,&key); 16) <= 0)
if(memcmp(buf,tests[n].ciphertext,sizeof buf)) goto err;
{
FIPSerr(FIPS_F_FIPS_SELFTEST_AES,FIPS_R_SELFTEST_FAILED);
return 0;
}
} }
/* Decrypt and check against known plaintext */ ret = 1;
for(n=0 ; n < 1 ; ++n) err:
{ EVP_CIPHER_CTX_cleanup(&ctx);
AES_KEY key; if (ret == 0)
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))
{
FIPSerr(FIPS_F_FIPS_SELFTEST_AES,FIPS_R_SELFTEST_FAILED); FIPSerr(FIPS_F_FIPS_SELFTEST_AES,FIPS_R_SELFTEST_FAILED);
return 0; return ret;
}
}
return 1;
} }
#endif #endif

View File

@@ -50,13 +50,13 @@
#include <string.h> #include <string.h>
#include <openssl/err.h> #include <openssl/err.h>
#include <openssl/fips.h> #include <openssl/fips.h>
#include <openssl/des.h> #include <openssl/evp.h>
#include <openssl/opensslconf.h> #include <openssl/opensslconf.h>
#ifdef OPENSSL_FIPS #ifdef OPENSSL_FIPS
static struct static struct
{ {
DES_cblock key; unsigned char key[8];
unsigned char plaintext[8]; unsigned char plaintext[8];
unsigned char ciphertext[8]; unsigned char ciphertext[8];
} tests[]= } tests[]=
@@ -75,21 +75,20 @@ static struct
static struct static struct
{ {
DES_cblock key1; unsigned char key[16];
DES_cblock key2;
unsigned char plaintext[8]; unsigned char plaintext[8];
unsigned char ciphertext[8]; unsigned char ciphertext[8];
} tests2[]= } tests2[]=
{ {
{ {
{ 0x7c,0x4f,0x6e,0xf7,0xa2,0x04,0x16,0xec }, { 0x7c,0x4f,0x6e,0xf7,0xa2,0x04,0x16,0xec,
{ 0x0b,0x6b,0x7c,0x9e,0x5e,0x19,0xa7,0xc4 }, 0x0b,0x6b,0x7c,0x9e,0x5e,0x19,0xa7,0xc4 },
{ 0x06,0xa7,0xd8,0x79,0xaa,0xce,0x69,0xef }, { 0x06,0xa7,0xd8,0x79,0xaa,0xce,0x69,0xef },
{ 0x4c,0x11,0x17,0x55,0xbf,0xc4,0x4e,0xfd } { 0x4c,0x11,0x17,0x55,0xbf,0xc4,0x4e,0xfd }
}, },
{ {
{ 0x5d,0x9e,0x01,0xd3,0x25,0xc7,0x3e,0x34 }, { 0x5d,0x9e,0x01,0xd3,0x25,0xc7,0x3e,0x34,
{ 0x01,0x16,0x7c,0x85,0x23,0xdf,0xe0,0x68 }, 0x01,0x16,0x7c,0x85,0x23,0xdf,0xe0,0x68 },
{ 0x9c,0x50,0x09,0x0f,0x5e,0x7d,0x69,0x7e }, { 0x9c,0x50,0x09,0x0f,0x5e,0x7d,0x69,0x7e },
{ 0xd2,0x0b,0x18,0xdf,0xd9,0x0d,0x9e,0xff }, { 0xd2,0x0b,0x18,0xdf,0xd9,0x0d,0x9e,0xff },
} }
@@ -97,24 +96,22 @@ static struct
static struct static struct
{ {
DES_cblock key1; unsigned char key[24];
DES_cblock key2;
DES_cblock key3;
unsigned char plaintext[8]; unsigned char plaintext[8];
unsigned char ciphertext[8]; unsigned char ciphertext[8];
} tests3[]= } tests3[]=
{ {
{ {
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
{ 0xFE,0xDC,0xBA,0x98,0x76,0x54,0x32,0x10 }, 0xFE,0xDC,0xBA,0x98,0x76,0x54,0x32,0x10,
{ 0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0 }, 0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0 },
{ 0x8f,0x8f,0xbf,0x9b,0x5d,0x48,0xb4,0x1c}, { 0x8f,0x8f,0xbf,0x9b,0x5d,0x48,0xb4,0x1c },
{ 0x59,0x8c,0xe5,0xd3,0x6c,0xa2,0xea,0x1b}, { 0x59,0x8c,0xe5,0xd3,0x6c,0xa2,0xea,0x1b },
}, },
{ {
{ 0xDC,0xBA,0x98,0x76,0x54,0x32,0x10,0xFE }, { 0xDC,0xBA,0x98,0x76,0x54,0x32,0x10,0xFE,
{ 0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF }, 0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF,
{ 0xED,0x39,0xD9,0x50,0xFA,0x74,0xBC,0xC4 }, 0xED,0x39,0xD9,0x50,0xFA,0x74,0xBC,0xC4 },
{ 0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF }, { 0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF },
{ 0x11,0x25,0xb0,0x35,0xbe,0xa0,0x82,0x86 }, { 0x11,0x25,0xb0,0x35,0xbe,0xa0,0x82,0x86 },
}, },
@@ -127,78 +124,42 @@ void FIPS_corrupt_des()
int FIPS_selftest_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 */ /* Encrypt/decrypt with DES and compare to known answers */
for(n=0 ; n < 2 ; ++n) for(n=0 ; n < 2 ; ++n)
{ {
DES_key_schedule key; if (!fips_cipher_test(&ctx, EVP_des_ecb(),
DES_cblock buf; tests[n].key, NULL,
tests[n].plaintext, tests[n].ciphertext, 8))
DES_set_key(&tests[n].key,&key); goto err;
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;
}
} }
#endif
/* Encrypt/decrypt with 2-key 3DES and compare to known answers */ /* Encrypt/decrypt with 2-key 3DES and compare to known answers */
for(n=0 ; n < 2 ; ++n) for(n=0 ; n < 2 ; ++n)
{ {
DES_key_schedule key1, key2; if (!fips_cipher_test(&ctx, EVP_des_ede_ecb(),
unsigned char buf[8]; tests2[n].key, NULL,
tests2[n].plaintext, tests2[n].ciphertext, 8))
DES_set_key(&tests2[n].key1,&key1); goto err;
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;
}
} }
/* Encrypt/decrypt with 3DES and compare to known answers */ /* Encrypt/decrypt with 3DES and compare to known answers */
for(n=0 ; n < 2 ; ++n) for(n=0 ; n < 2 ; ++n)
{ {
DES_key_schedule key1, key2, key3; if (!fips_cipher_test(&ctx, EVP_des_ede3_ecb(),
unsigned char buf[8]; tests3[n].key, NULL,
tests3[n].plaintext, tests3[n].ciphertext, 8))
DES_set_key(&tests3[n].key1,&key1); goto err;
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;
}
} }
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 #endif

View File

@@ -462,4 +462,32 @@ int fips_pkey_signature_test(EVP_PKEY *pkey,
return 1; 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 #endif

View File

@@ -58,6 +58,8 @@ extern "C" {
struct dsa_st; struct dsa_st;
struct evp_pkey_st; struct evp_pkey_st;
struct env_md_st; struct env_md_st;
struct evp_cipher_st;
struct evp_cipher_ctx_st;
int FIPS_mode_set(int onoff); int FIPS_mode_set(int onoff);
int FIPS_mode(void); 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 struct env_md_st *digest, unsigned int md_flags,
const char *fail_str); 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 */ /* BEGIN ERROR CODES */
/* The following lines are auto generated by the script mkerr.pl. Any changes /* 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. * made after this point may be overwritten when the script is next run.

View File

@@ -64,6 +64,8 @@ int fips_set_owning_thread(void);
int fips_clear_owning_thread(void); int fips_clear_owning_thread(void);
unsigned char *fips_signature_witness(void); unsigned char *fips_signature_witness(void);
#define FIPS_MAX_CIPHER_TEST_SIZE 16
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif