Changes to make AES algorithm test work via EVP.

This commit is contained in:
Dr. Stephen Henson 2007-07-01 12:53:10 +00:00
parent df50ec372e
commit 5fd76ba57a
7 changed files with 143 additions and 122 deletions

View file

@ -4,6 +4,13 @@
Changes between 0.9.8e and 0.9.8f-fips [xx XXX xxxx] Changes between 0.9.8e and 0.9.8f-fips [xx XXX xxxx]
*) New flag in EVP_CIPHER: EVP_CIPH_FLAG_DEFAULT_ASN1. This will
automatically use EVP_CIPHER_{get,set}_asn1_iv and avoid the
need for any ASN1 dependencies in FIPS library. Move AES cipher
definitions to fips library and modify AES algorithm test to use
EVP.
[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
for use by FIPS applications. for use by FIPS applications.
[Steve Henson] [Steve Henson]

View file

@ -299,6 +299,7 @@ FIPS_EX_OBJ= ../crypto/aes/aes_cbc.o \
../crypto/err/err.o \ ../crypto/err/err.o \
../crypto/evp/digest.o \ ../crypto/evp/digest.o \
../crypto/evp/enc_min.o \ ../crypto/evp/enc_min.o \
../crypto/evp/e_aes.o \
../crypto/evp/p_sign.o \ ../crypto/evp/p_sign.o \
../crypto/evp/p_verify.o \ ../crypto/evp/p_verify.o \
../crypto/mem_clr.o \ ../crypto/mem_clr.o \

View file

@ -69,22 +69,19 @@ typedef struct
IMPLEMENT_BLOCK_CIPHER(aes_128, ks, AES, EVP_AES_KEY, IMPLEMENT_BLOCK_CIPHER(aes_128, ks, AES, EVP_AES_KEY,
NID_aes_128, 16, 16, 16, 128, NID_aes_128, 16, 16, 16, 128,
EVP_CIPH_FLAG_FIPS, aes_init_key, NULL, EVP_CIPH_FLAG_FIPS|EVP_CIPH_FLAG_DEFAULT_ASN1,
EVP_CIPHER_set_asn1_iv, aes_init_key,
EVP_CIPHER_get_asn1_iv, NULL, NULL, NULL, NULL)
NULL)
IMPLEMENT_BLOCK_CIPHER(aes_192, ks, AES, EVP_AES_KEY, IMPLEMENT_BLOCK_CIPHER(aes_192, ks, AES, EVP_AES_KEY,
NID_aes_192, 16, 24, 16, 128, NID_aes_192, 16, 24, 16, 128,
EVP_CIPH_FLAG_FIPS, aes_init_key, NULL, EVP_CIPH_FLAG_FIPS|EVP_CIPH_FLAG_DEFAULT_ASN1,
EVP_CIPHER_set_asn1_iv, aes_init_key,
EVP_CIPHER_get_asn1_iv, NULL, NULL, NULL, NULL)
NULL)
IMPLEMENT_BLOCK_CIPHER(aes_256, ks, AES, EVP_AES_KEY, IMPLEMENT_BLOCK_CIPHER(aes_256, ks, AES, EVP_AES_KEY,
NID_aes_256, 16, 32, 16, 128, NID_aes_256, 16, 32, 16, 128,
EVP_CIPH_FLAG_FIPS, aes_init_key, NULL, EVP_CIPH_FLAG_FIPS|EVP_CIPH_FLAG_DEFAULT_ASN1,
EVP_CIPHER_set_asn1_iv, aes_init_key,
EVP_CIPHER_get_asn1_iv, NULL, NULL, NULL, NULL)
NULL)
#define IMPLEMENT_AES_CFBR(ksize,cbits,flags) IMPLEMENT_CFBR(aes,AES,EVP_AES_KEY,ks,ksize,cbits,16,flags) #define IMPLEMENT_AES_CFBR(ksize,cbits,flags) IMPLEMENT_CFBR(aes,AES,EVP_AES_KEY,ks,ksize,cbits,16,flags)

View file

@ -376,6 +376,8 @@ struct evp_cipher_st
#define EVP_CIPH_FLAG_FIPS 0x400 #define EVP_CIPH_FLAG_FIPS 0x400
/* Allow non FIPS cipher in FIPS mode */ /* Allow non FIPS cipher in FIPS mode */
#define EVP_CIPH_FLAG_NON_FIPS_ALLOW 0x800 #define EVP_CIPH_FLAG_NON_FIPS_ALLOW 0x800
/* Allow use default ASN1 get/set iv */
#define EVP_CIPH_FLAG_DEFAULT_ASN1 0x1000
/* ctrl() values */ /* ctrl() values */

View file

@ -67,6 +67,8 @@ int EVP_CIPHER_param_to_asn1(EVP_CIPHER_CTX *c, ASN1_TYPE *type)
if (c->cipher->set_asn1_parameters != NULL) if (c->cipher->set_asn1_parameters != NULL)
ret=c->cipher->set_asn1_parameters(c,type); ret=c->cipher->set_asn1_parameters(c,type);
else if (c->cipher->flags & EVP_CIPH_FLAG_DEFAULT_ASN1)
ret=EVP_CIPHER_set_asn1_iv(c, type);
else else
ret=-1; ret=-1;
return(ret); return(ret);
@ -78,6 +80,8 @@ int EVP_CIPHER_asn1_to_param(EVP_CIPHER_CTX *c, ASN1_TYPE *type)
if (c->cipher->get_asn1_parameters != NULL) if (c->cipher->get_asn1_parameters != NULL)
ret=c->cipher->get_asn1_parameters(c,type); ret=c->cipher->get_asn1_parameters(c,type);
else if (c->cipher->flags & EVP_CIPH_FLAG_DEFAULT_ASN1)
ret=EVP_CIPHER_get_asn1_iv(c, type);
else else
ret=-1; ret=-1;
return(ret); return(ret);

View file

@ -230,10 +230,8 @@ const EVP_CIPHER *EVP_##cname##_ecb(void) { return &cname##_ecb; }
BLOCK_CIPHER_func_cfb(cipher##_##keysize,cprefix,cbits,kstruct,ksched) \ BLOCK_CIPHER_func_cfb(cipher##_##keysize,cprefix,cbits,kstruct,ksched) \
BLOCK_CIPHER_def_cfb(cipher##_##keysize,kstruct, \ BLOCK_CIPHER_def_cfb(cipher##_##keysize,kstruct, \
NID_##cipher##_##keysize, keysize/8, iv_len, cbits, \ NID_##cipher##_##keysize, keysize/8, iv_len, cbits, \
fl, cipher##_init_key, NULL, \ (fl)|EVP_CIPH_FLAG_DEFAULT_ASN1, \
EVP_CIPHER_set_asn1_iv, \ cipher##_init_key, NULL, NULL, NULL, NULL)
EVP_CIPHER_get_asn1_iv, \
NULL)
#ifdef OPENSSL_FIPS #ifdef OPENSSL_FIPS
#define RC2_set_key private_RC2_set_key #define RC2_set_key private_RC2_set_key

View file

@ -88,125 +88,135 @@ int main(int argc, char *argv[])
/*-----------------------------------------------*/ /*-----------------------------------------------*/
typedef struct int AESTest(EVP_CIPHER_CTX *ctx,
{
AES_KEY ks;
unsigned char tiv[AES_BLOCK_SIZE];
int dir, cmode, cbits, num;
} AES_CTX;
int AES_Cipher(AES_CTX *ctx,
unsigned char *out,
unsigned char *in,
int inl)
{
unsigned long len = inl;
switch(ctx->cmode)
{
case EVP_CIPH_ECB_MODE:
while (len > 0)
{
AES_ecb_encrypt(in, out, &ctx->ks, ctx->dir);
in += AES_BLOCK_SIZE;
out += AES_BLOCK_SIZE;
len -= AES_BLOCK_SIZE;
}
break;
case EVP_CIPH_CBC_MODE:
AES_cbc_encrypt(in, out, len, &ctx->ks, ctx->tiv, ctx->dir);
break;
case EVP_CIPH_CFB_MODE:
if (ctx->cbits == 1)
AES_cfb1_encrypt(in, out, len, &ctx->ks, ctx->tiv,
&ctx->num, ctx->dir);
else if (ctx->cbits == 8)
AES_cfb8_encrypt(in, out, len, &ctx->ks, ctx->tiv,
&ctx->num, ctx->dir);
else if (ctx->cbits == 128)
AES_cfb128_encrypt(in, out, len, &ctx->ks, ctx->tiv,
&ctx->num, ctx->dir);
break;
case EVP_CIPH_OFB_MODE:
AES_ofb128_encrypt(in, out, len, &ctx->ks, ctx->tiv,
&ctx->num);
break;
default:
return 0;
}
return 1;
}
int AESTest(AES_CTX *ctx,
char *amode, int akeysz, unsigned char *aKey, char *amode, int akeysz, unsigned char *aKey,
unsigned char *iVec, unsigned char *iVec,
int dir, /* 0 = decrypt, 1 = encrypt */ int dir, /* 0 = decrypt, 1 = encrypt */
unsigned char *plaintext, unsigned char *ciphertext, int len) unsigned char *plaintext, unsigned char *ciphertext, int len)
{ {
int ret = 1; const EVP_CIPHER *cipher = NULL;
ctx->cmode = -1;
ctx->cbits = -1;
ctx->dir = dir;
ctx->num = 0;
if (strcasecmp(amode, "CBC") == 0) if (strcasecmp(amode, "CBC") == 0)
ctx->cmode = EVP_CIPH_CBC_MODE; {
switch (akeysz)
{
case 128:
cipher = EVP_aes_128_cbc();
break;
case 192:
cipher = EVP_aes_192_cbc();
break;
case 256:
cipher = EVP_aes_256_cbc();
break;
}
}
else if (strcasecmp(amode, "ECB") == 0) else if (strcasecmp(amode, "ECB") == 0)
ctx->cmode = EVP_CIPH_ECB_MODE; {
switch (akeysz)
{
case 128:
cipher = EVP_aes_128_ecb();
break;
case 192:
cipher = EVP_aes_192_ecb();
break;
case 256:
cipher = EVP_aes_256_ecb();
break;
}
}
else if (strcasecmp(amode, "CFB128") == 0) else if (strcasecmp(amode, "CFB128") == 0)
{ {
ctx->cbits = 128; switch (akeysz)
ctx->cmode = EVP_CIPH_CFB_MODE; {
case 128:
cipher = EVP_aes_128_cfb128();
break;
case 192:
cipher = EVP_aes_192_cfb128();
break;
case 256:
cipher = EVP_aes_256_cfb128();
break;
}
} }
else if (strncasecmp(amode, "OFB", 3) == 0) else if (strncasecmp(amode, "OFB", 3) == 0)
ctx->cmode = EVP_CIPH_OFB_MODE; {
switch (akeysz)
{
case 128:
cipher = EVP_aes_128_ofb();
break;
case 192:
cipher = EVP_aes_192_ofb();
break;
case 256:
cipher = EVP_aes_256_ofb();
break;
}
}
else if(!strcasecmp(amode,"CFB1")) else if(!strcasecmp(amode,"CFB1"))
{ {
ctx->cbits = 1; switch (akeysz)
ctx->cmode = EVP_CIPH_CFB_MODE; {
case 128:
cipher = EVP_aes_128_cfb1();
break;
case 192:
cipher = EVP_aes_192_cfb1();
break;
case 256:
cipher = EVP_aes_256_cfb1();
break;
}
} }
else if(!strcasecmp(amode,"CFB8")) else if(!strcasecmp(amode,"CFB8"))
{ {
ctx->cbits = 8; switch (akeysz)
ctx->cmode = EVP_CIPH_CFB_MODE; {
case 128:
cipher = EVP_aes_128_cfb8();
break;
case 192:
cipher = EVP_aes_192_cfb8();
break;
case 256:
cipher = EVP_aes_256_cfb8();
break;
}
} }
else else
{ {
printf("Unknown mode: %s\n", amode); printf("Unknown mode: %s\n", amode);
EXIT(1); return 0;
} }
if (ret) if (!cipher)
{ {
if ((akeysz != 128) && (akeysz != 192) && (akeysz != 256)) printf("Invalid key size: %d\n", akeysz);
{ return 0;
printf("Invalid key size: %d\n", akeysz);
ret = 0;
}
if (ctx->dir
|| (ctx->cmode == EVP_CIPH_CFB_MODE)
|| (ctx->cmode == EVP_CIPH_OFB_MODE))
AES_set_encrypt_key(aKey, akeysz, &ctx->ks);
else
AES_set_decrypt_key(aKey, akeysz, &ctx->ks);
if (iVec)
memcpy(ctx->tiv, iVec, AES_BLOCK_SIZE);
if (ctx->dir)
AES_Cipher(ctx, ciphertext, plaintext, len);
else
AES_Cipher(ctx, plaintext, ciphertext, len);
} }
return ret; if (EVP_CipherInit_ex(ctx, cipher, NULL, aKey, iVec, dir) <= 0)
return 0;
if (dir)
EVP_Cipher(ctx, ciphertext, plaintext, len);
else
EVP_Cipher(ctx, plaintext, ciphertext, len);
return 1;
} }
/*-----------------------------------------------*/ /*-----------------------------------------------*/
@ -238,7 +248,8 @@ int do_mct(char *amode,
unsigned char ciphertext[64+4]; unsigned char ciphertext[64+4];
int i, j, n, n1, n2; int i, j, n, n1, n2;
int imode = 0, nkeysz = akeysz/8; int imode = 0, nkeysz = akeysz/8;
AES_CTX ctx; EVP_CIPHER_CTX ctx;
EVP_CIPHER_CTX_init(&ctx);
if (len > 32) if (len > 32)
{ {
@ -294,12 +305,12 @@ int do_mct(char *amode,
{ {
if (dir == XENCRYPT) if (dir == XENCRYPT)
{ {
AES_Cipher(&ctx, ctext[j], ptext[j], len); EVP_Cipher(&ctx, ctext[j], ptext[j], len);
memcpy(ptext[j+1], ctext[j], len); memcpy(ptext[j+1], ctext[j], len);
} }
else else
{ {
AES_Cipher(&ctx, ptext[j], ctext[j], len); EVP_Cipher(&ctx, ptext[j], ctext[j], len);
memcpy(ctext[j+1], ptext[j], len); memcpy(ctext[j+1], ptext[j], len);
} }
} }
@ -322,12 +333,12 @@ int do_mct(char *amode,
{ {
if (dir == XENCRYPT) if (dir == XENCRYPT)
{ {
AES_Cipher(&ctx, ctext[j], ptext[j], len); EVP_Cipher(&ctx, ctext[j], ptext[j], len);
memcpy(ptext[j+1], ctext[j-1], len); memcpy(ptext[j+1], ctext[j-1], len);
} }
else else
{ {
AES_Cipher(&ctx, ptext[j], ctext[j], len); EVP_Cipher(&ctx, ptext[j], ctext[j], len);
memcpy(ctext[j+1], ptext[j-1], len); memcpy(ctext[j+1], ptext[j-1], len);
} }
} }
@ -343,9 +354,9 @@ int do_mct(char *amode,
else else
{ {
if (dir == XENCRYPT) if (dir == XENCRYPT)
AES_Cipher(&ctx, ctext[j], ptext[j], len); EVP_Cipher(&ctx, ctext[j], ptext[j], len);
else else
AES_Cipher(&ctx, ptext[j], ctext[j], len); EVP_Cipher(&ctx, ptext[j], ctext[j], len);
} }
if (dir == XENCRYPT) if (dir == XENCRYPT)
{ {
@ -369,15 +380,15 @@ int do_mct(char *amode,
/* compensate for wrong endianness of input file */ /* compensate for wrong endianness of input file */
if(i == 0) if(i == 0)
ptext[0][0]<<=7; ptext[0][0]<<=7;
ret=AESTest(&ctx,amode,akeysz,key[i],iv[i],dir, ret = AESTest(&ctx,amode,akeysz,key[i],iv[i],dir,
ptext[j], ctext[j], len); ptext[j], ctext[j], len);
} }
else else
{ {
if (dir == XENCRYPT) if (dir == XENCRYPT)
AES_Cipher(&ctx, ctext[j], ptext[j], len); EVP_Cipher(&ctx, ctext[j], ptext[j], len);
else else
AES_Cipher(&ctx, ptext[j], ctext[j], len); EVP_Cipher(&ctx, ptext[j], ctext[j], len);
} }
if(dir == XENCRYPT) if(dir == XENCRYPT)
@ -546,7 +557,8 @@ int proc_file(char *rqfile)
unsigned char plaintext[2048]; unsigned char plaintext[2048];
unsigned char ciphertext[2048]; unsigned char ciphertext[2048];
char *rp; char *rp;
AES_CTX ctx; EVP_CIPHER_CTX ctx;
EVP_CIPHER_CTX_init(&ctx);
if (!rqfile || !(*rqfile)) if (!rqfile || !(*rqfile))
{ {