From 5fd76ba57a7219657e3eaa43b0e08df2d54a28a2 Mon Sep 17 00:00:00 2001 From: "Dr. Stephen Henson" Date: Sun, 1 Jul 2007 12:53:10 +0000 Subject: [PATCH] Changes to make AES algorithm test work via EVP. --- CHANGES | 7 ++ Makefile.org | 1 + crypto/evp/e_aes.c | 21 ++-- crypto/evp/evp.h | 2 + crypto/evp/evp_lib.c | 4 + crypto/evp/evp_locl.h | 6 +- fips-1.0/aes/fips_aesavs.c | 212 ++++++++++++++++++++----------------- 7 files changed, 137 insertions(+), 116 deletions(-) diff --git a/CHANGES b/CHANGES index 0130bfcdb5..f14f78f6e2 100644 --- a/CHANGES +++ b/CHANGES @@ -4,6 +4,13 @@ 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 for use by FIPS applications. [Steve Henson] diff --git a/Makefile.org b/Makefile.org index 3751c1d897..96ebd119c1 100644 --- a/Makefile.org +++ b/Makefile.org @@ -299,6 +299,7 @@ FIPS_EX_OBJ= ../crypto/aes/aes_cbc.o \ ../crypto/err/err.o \ ../crypto/evp/digest.o \ ../crypto/evp/enc_min.o \ + ../crypto/evp/e_aes.o \ ../crypto/evp/p_sign.o \ ../crypto/evp/p_verify.o \ ../crypto/mem_clr.o \ diff --git a/crypto/evp/e_aes.c b/crypto/evp/e_aes.c index 3e08d39bb5..c9a5ee8d75 100644 --- a/crypto/evp/e_aes.c +++ b/crypto/evp/e_aes.c @@ -69,22 +69,19 @@ typedef struct IMPLEMENT_BLOCK_CIPHER(aes_128, ks, AES, EVP_AES_KEY, NID_aes_128, 16, 16, 16, 128, - EVP_CIPH_FLAG_FIPS, aes_init_key, NULL, - EVP_CIPHER_set_asn1_iv, - EVP_CIPHER_get_asn1_iv, - NULL) + EVP_CIPH_FLAG_FIPS|EVP_CIPH_FLAG_DEFAULT_ASN1, + aes_init_key, + NULL, NULL, NULL, NULL) IMPLEMENT_BLOCK_CIPHER(aes_192, ks, AES, EVP_AES_KEY, NID_aes_192, 16, 24, 16, 128, - EVP_CIPH_FLAG_FIPS, aes_init_key, NULL, - EVP_CIPHER_set_asn1_iv, - EVP_CIPHER_get_asn1_iv, - NULL) + EVP_CIPH_FLAG_FIPS|EVP_CIPH_FLAG_DEFAULT_ASN1, + aes_init_key, + NULL, NULL, NULL, NULL) IMPLEMENT_BLOCK_CIPHER(aes_256, ks, AES, EVP_AES_KEY, NID_aes_256, 16, 32, 16, 128, - EVP_CIPH_FLAG_FIPS, aes_init_key, NULL, - EVP_CIPHER_set_asn1_iv, - EVP_CIPHER_get_asn1_iv, - NULL) + EVP_CIPH_FLAG_FIPS|EVP_CIPH_FLAG_DEFAULT_ASN1, + aes_init_key, + NULL, NULL, NULL, NULL) #define IMPLEMENT_AES_CFBR(ksize,cbits,flags) IMPLEMENT_CFBR(aes,AES,EVP_AES_KEY,ks,ksize,cbits,16,flags) diff --git a/crypto/evp/evp.h b/crypto/evp/evp.h index 7c5184d536..b8efccae23 100644 --- a/crypto/evp/evp.h +++ b/crypto/evp/evp.h @@ -376,6 +376,8 @@ struct evp_cipher_st #define EVP_CIPH_FLAG_FIPS 0x400 /* Allow non FIPS cipher in FIPS mode */ #define EVP_CIPH_FLAG_NON_FIPS_ALLOW 0x800 +/* Allow use default ASN1 get/set iv */ +#define EVP_CIPH_FLAG_DEFAULT_ASN1 0x1000 /* ctrl() values */ diff --git a/crypto/evp/evp_lib.c b/crypto/evp/evp_lib.c index a5f6eee352..174cf6c594 100644 --- a/crypto/evp/evp_lib.c +++ b/crypto/evp/evp_lib.c @@ -67,6 +67,8 @@ int EVP_CIPHER_param_to_asn1(EVP_CIPHER_CTX *c, ASN1_TYPE *type) if (c->cipher->set_asn1_parameters != NULL) 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 ret=-1; 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) 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 ret=-1; return(ret); diff --git a/crypto/evp/evp_locl.h b/crypto/evp/evp_locl.h index 1ec70f0af5..f5b71eed79 100644 --- a/crypto/evp/evp_locl.h +++ b/crypto/evp/evp_locl.h @@ -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_def_cfb(cipher##_##keysize,kstruct, \ NID_##cipher##_##keysize, keysize/8, iv_len, cbits, \ - fl, cipher##_init_key, NULL, \ - EVP_CIPHER_set_asn1_iv, \ - EVP_CIPHER_get_asn1_iv, \ - NULL) + (fl)|EVP_CIPH_FLAG_DEFAULT_ASN1, \ + cipher##_init_key, NULL, NULL, NULL, NULL) #ifdef OPENSSL_FIPS #define RC2_set_key private_RC2_set_key diff --git a/fips-1.0/aes/fips_aesavs.c b/fips-1.0/aes/fips_aesavs.c index acd349d384..cc1d18182e 100644 --- a/fips-1.0/aes/fips_aesavs.c +++ b/fips-1.0/aes/fips_aesavs.c @@ -88,125 +88,135 @@ int main(int argc, char *argv[]) /*-----------------------------------------------*/ -typedef struct - { - 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; +int AESTest(EVP_CIPHER_CTX *ctx, + char *amode, int akeysz, unsigned char *aKey, + unsigned char *iVec, + int dir, /* 0 = decrypt, 1 = encrypt */ + unsigned char *plaintext, unsigned char *ciphertext, int len) + { + const EVP_CIPHER *cipher = NULL; - switch(ctx->cmode) + if (strcasecmp(amode, "CBC") == 0) + { + switch (akeysz) { - 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; - } + case 128: + cipher = EVP_aes_128_cbc(); break; - case EVP_CIPH_CBC_MODE: - AES_cbc_encrypt(in, out, len, &ctx->ks, ctx->tiv, ctx->dir); + case 192: + cipher = EVP_aes_192_cbc(); 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); + case 256: + cipher = EVP_aes_256_cbc(); break; + } - case EVP_CIPH_OFB_MODE: - AES_ofb128_encrypt(in, out, len, &ctx->ks, ctx->tiv, - &ctx->num); - + } + else if (strcasecmp(amode, "ECB") == 0) + { + switch (akeysz) + { + case 128: + cipher = EVP_aes_128_ecb(); break; - default: - return 0; + case 192: + cipher = EVP_aes_192_ecb(); + break; + case 256: + cipher = EVP_aes_256_ecb(); + break; } - - return 1; - } + else if (strcasecmp(amode, "CFB128") == 0) + { + switch (akeysz) + { + case 128: + cipher = EVP_aes_128_cfb128(); + break; + case 192: + cipher = EVP_aes_192_cfb128(); + break; + case 256: + cipher = EVP_aes_256_cfb128(); + break; + } -int AESTest(AES_CTX *ctx, - char *amode, int akeysz, unsigned char *aKey, - unsigned char *iVec, - int dir, /* 0 = decrypt, 1 = encrypt */ - unsigned char *plaintext, unsigned char *ciphertext, int len) - { - int ret = 1; - - ctx->cmode = -1; - ctx->cbits = -1; - ctx->dir = dir; - ctx->num = 0; - if (strcasecmp(amode, "CBC") == 0) - ctx->cmode = EVP_CIPH_CBC_MODE; - else if (strcasecmp(amode, "ECB") == 0) - ctx->cmode = EVP_CIPH_ECB_MODE; - else if (strcasecmp(amode, "CFB128") == 0) - { - ctx->cbits = 128; - ctx->cmode = EVP_CIPH_CFB_MODE; } 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")) { - ctx->cbits = 1; - ctx->cmode = EVP_CIPH_CFB_MODE; + switch (akeysz) + { + 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")) { - ctx->cbits = 8; - ctx->cmode = EVP_CIPH_CFB_MODE; + switch (akeysz) + { + 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 { 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); - 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); + printf("Invalid key size: %d\n", akeysz); + return 0; } - 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]; int i, j, n, n1, n2; int imode = 0, nkeysz = akeysz/8; - AES_CTX ctx; + EVP_CIPHER_CTX ctx; + EVP_CIPHER_CTX_init(&ctx); if (len > 32) { @@ -294,12 +305,12 @@ int do_mct(char *amode, { 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); } else { - AES_Cipher(&ctx, ptext[j], ctext[j], len); + EVP_Cipher(&ctx, ptext[j], ctext[j], len); memcpy(ctext[j+1], ptext[j], len); } } @@ -322,12 +333,12 @@ int do_mct(char *amode, { 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); } 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); } } @@ -343,9 +354,9 @@ int do_mct(char *amode, else { if (dir == XENCRYPT) - AES_Cipher(&ctx, ctext[j], ptext[j], len); + EVP_Cipher(&ctx, ctext[j], ptext[j], len); else - AES_Cipher(&ctx, ptext[j], ctext[j], len); + EVP_Cipher(&ctx, ptext[j], ctext[j], len); } if (dir == XENCRYPT) { @@ -369,15 +380,15 @@ int do_mct(char *amode, /* compensate for wrong endianness of input file */ if(i == 0) 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); } else { if (dir == XENCRYPT) - AES_Cipher(&ctx, ctext[j], ptext[j], len); + EVP_Cipher(&ctx, ctext[j], ptext[j], len); else - AES_Cipher(&ctx, ptext[j], ctext[j], len); + EVP_Cipher(&ctx, ptext[j], ctext[j], len); } if(dir == XENCRYPT) @@ -546,7 +557,8 @@ int proc_file(char *rqfile) unsigned char plaintext[2048]; unsigned char ciphertext[2048]; char *rp; - AES_CTX ctx; + EVP_CIPHER_CTX ctx; + EVP_CIPHER_CTX_init(&ctx); if (!rqfile || !(*rqfile)) { -- 2.25.1