From 7a4bd34a4f6d0c0745dd5710c0f4dba614e8dfac Mon Sep 17 00:00:00 2001 From: "Dr. Stephen Henson" Date: Wed, 26 Jan 2011 15:25:33 +0000 Subject: [PATCH] FIPS mode EVP changes: Set EVP_CIPH_FLAG_FIPS on approved ciphers. Support "default ASN1" flag which avoids need for ASN1 dependencies in FIPS code. Include some defines to redirect operations to a "tiny EVP" implementation in some FIPS source files. Change m_sha1.c to use EVP_PKEY_NULL_method: the EVP_MD sign/verify functions are not used in OpenSSL 1.0 and later for SHA1 and SHA2 ciphers: the EVP_PKEY API is used instead. --- crypto/evp/Makefile | 2 +- crypto/evp/e_aes.c | 20 ++++------- crypto/evp/e_camellia.c | 2 +- crypto/evp/e_des3.c | 26 ++++++-------- crypto/evp/evp.h | 80 ++++++++++++++++++++++++++++++++++++++--- crypto/evp/evp_lib.c | 2 ++ crypto/evp/evp_locl.h | 8 ++--- crypto/evp/m_sha1.c | 16 ++++++--- 8 files changed, 112 insertions(+), 44 deletions(-) diff --git a/crypto/evp/Makefile b/crypto/evp/Makefile index 4aa24fddfb..99eba94c67 100644 --- a/crypto/evp/Makefile +++ b/crypto/evp/Makefile @@ -55,7 +55,7 @@ top: all: lib lib: $(LIBOBJ) - $(AR) $(LIB) $(LIBOBJ) + $(ARX) $(LIB) $(LIBOBJ) $(RANLIB) $(LIB) || echo Never mind. @touch lib diff --git a/crypto/evp/e_aes.c b/crypto/evp/e_aes.c index a7fbba3689..32c903386b 100644 --- a/crypto/evp/e_aes.c +++ b/crypto/evp/e_aes.c @@ -70,24 +70,18 @@ typedef struct IMPLEMENT_BLOCK_CIPHER(aes_128, ks, AES, EVP_AES_KEY, NID_aes_128, 16, 16, 16, 128, - 0, 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, - 0, 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, - 0, 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) IMPLEMENT_CFBR(aes,AES,EVP_AES_KEY,ks,ksize,cbits,16) +#define IMPLEMENT_AES_CFBR(ksize,cbits) IMPLEMENT_CFBR(aes,AES,EVP_AES_KEY,ks,ksize,cbits,16,EVP_CIPH_FLAG_FIPS) IMPLEMENT_AES_CFBR(128,1) IMPLEMENT_AES_CFBR(192,1) diff --git a/crypto/evp/e_camellia.c b/crypto/evp/e_camellia.c index a7b40d1c60..365d397164 100644 --- a/crypto/evp/e_camellia.c +++ b/crypto/evp/e_camellia.c @@ -93,7 +93,7 @@ IMPLEMENT_BLOCK_CIPHER(camellia_256, ks, Camellia, EVP_CAMELLIA_KEY, EVP_CIPHER_get_asn1_iv, NULL) -#define IMPLEMENT_CAMELLIA_CFBR(ksize,cbits) IMPLEMENT_CFBR(camellia,Camellia,EVP_CAMELLIA_KEY,ks,ksize,cbits,16) +#define IMPLEMENT_CAMELLIA_CFBR(ksize,cbits) IMPLEMENT_CFBR(camellia,Camellia,EVP_CAMELLIA_KEY,ks,ksize,cbits,16,0) IMPLEMENT_CAMELLIA_CFBR(128,1) IMPLEMENT_CAMELLIA_CFBR(192,1) diff --git a/crypto/evp/e_des3.c b/crypto/evp/e_des3.c index 3232cfe024..785d76b5bd 100644 --- a/crypto/evp/e_des3.c +++ b/crypto/evp/e_des3.c @@ -206,9 +206,8 @@ static int des_ede3_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, } BLOCK_CIPHER_defs(des_ede, DES_EDE_KEY, NID_des_ede, 8, 16, 8, 64, - EVP_CIPH_RAND_KEY, des_ede_init_key, NULL, - EVP_CIPHER_set_asn1_iv, - EVP_CIPHER_get_asn1_iv, + EVP_CIPH_RAND_KEY|EVP_CIPH_FLAG_DEFAULT_ASN1, + des_ede_init_key, NULL, NULL, NULL, des3_ctrl) #define des_ede3_cfb64_cipher des_ede_cfb64_cipher @@ -217,22 +216,19 @@ BLOCK_CIPHER_defs(des_ede, DES_EDE_KEY, NID_des_ede, 8, 16, 8, 64, #define des_ede3_ecb_cipher des_ede_ecb_cipher BLOCK_CIPHER_defs(des_ede3, DES_EDE_KEY, NID_des_ede3, 8, 24, 8, 64, - EVP_CIPH_RAND_KEY, des_ede3_init_key, NULL, - EVP_CIPHER_set_asn1_iv, - EVP_CIPHER_get_asn1_iv, - des3_ctrl) + EVP_CIPH_RAND_KEY|EVP_CIPH_FLAG_FIPS|EVP_CIPH_FLAG_DEFAULT_ASN1, + des_ede3_init_key, NULL, NULL, NULL, + des3_ctrl) BLOCK_CIPHER_def_cfb(des_ede3,DES_EDE_KEY,NID_des_ede3,24,8,1, - EVP_CIPH_RAND_KEY, des_ede3_init_key,NULL, - EVP_CIPHER_set_asn1_iv, - EVP_CIPHER_get_asn1_iv, - des3_ctrl) + EVP_CIPH_RAND_KEY|EVP_CIPH_FLAG_FIPS|EVP_CIPH_FLAG_DEFAULT_ASN1, + des_ede3_init_key, NULL, NULL, NULL, + des3_ctrl) BLOCK_CIPHER_def_cfb(des_ede3,DES_EDE_KEY,NID_des_ede3,24,8,8, - EVP_CIPH_RAND_KEY, des_ede3_init_key,NULL, - EVP_CIPHER_set_asn1_iv, - EVP_CIPHER_get_asn1_iv, - des3_ctrl) + EVP_CIPH_RAND_KEY|EVP_CIPH_FLAG_FIPS|EVP_CIPH_FLAG_DEFAULT_ASN1, + des_ede3_init_key, NULL, NULL, NULL, + des3_ctrl) static int des_ede_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc) diff --git a/crypto/evp/evp.h b/crypto/evp/evp.h index 4548e6ddda..0db6f15ac9 100644 --- a/crypto/evp/evp.h +++ b/crypto/evp/evp.h @@ -217,6 +217,8 @@ typedef int evp_verify_method(int type,const unsigned char *m, #define EVP_MD_FLAG_DIGALGID_CUSTOM 0x0018 +#define EVP_MD_FLAG_FIPS 0x0400 /* Note if suitable for use in FIPS mode */ + /* Digest ctrls */ #define EVP_MD_CTRL_DIGALGID 0x1 @@ -348,6 +350,10 @@ struct evp_cipher_st #define EVP_CIPH_FLAG_DEFAULT_ASN1 0x1000 /* Buffer length in bits not bytes: CFB1 mode only */ #define EVP_CIPH_FLAG_LENGTH_BITS 0x2000 +/* Note if suitable for use in FIPS mode */ +#define EVP_CIPH_FLAG_FIPS 0x4000 +/* Allow non FIPS cipher in FIPS mode */ +#define EVP_CIPH_FLAG_NON_FIPS_ALLOW 0x8000 /* ctrl() values */ @@ -432,6 +438,22 @@ typedef int (EVP_PBE_KEYGEN)(EVP_CIPHER_CTX *ctx, const char *pass, int passlen, #define EVP_get_cipherbynid(a) EVP_get_cipherbyname(OBJ_nid2sn(a)) #define EVP_get_cipherbyobj(a) EVP_get_cipherbynid(OBJ_obj2nid(a)) +/* Macros to reduce FIPS dependencies: do NOT use in applications */ +#define M_EVP_MD_size(e) ((e)->md_size) +#define M_EVP_MD_block_size(e) ((e)->block_size) +#define M_EVP_MD_CTX_set_flags(ctx,flgs) ((ctx)->flags|=(flgs)) +#define M_EVP_MD_CTX_clear_flags(ctx,flgs) ((ctx)->flags&=~(flgs)) +#define M_EVP_MD_CTX_test_flags(ctx,flgs) ((ctx)->flags&(flgs)) +#define M_EVP_MD_type(e) ((e)->type) +#define M_EVP_MD_CTX_type(e) M_EVP_MD_type(M_EVP_MD_CTX_md(e)) +#define M_EVP_MD_CTX_md(e) ((e)->digest) + +#define M_EVP_CIPHER_CTX_iv_length(e) (e->cipher->iv_len) +#define M_EVP_CIPHER_CTX_flags(e) (e->cipher->flags) +#define M_EVP_CIPHER_CTX_mode(e) (M_EVP_CIPHER_CTX_flags(e) & EVP_CIPH_MODE) + +#define M_EVP_CIPHER_CTX_set_flags(ctx,flgs) ((ctx)->flags|=(flgs)) + int EVP_MD_type(const EVP_MD *md); #define EVP_MD_nid(e) EVP_MD_type(e) #define EVP_MD_name(e) OBJ_nid2sn(EVP_MD_nid(e)) @@ -504,20 +526,70 @@ __owur int EVP_Cipher(EVP_CIPHER_CTX *c, #define EVP_delete_digest_alias(alias) \ OBJ_NAME_remove(alias,OBJ_NAME_TYPE_MD_METH|OBJ_NAME_ALIAS); +#ifdef OPENSSL_FIPS +void FIPS_md_ctx_init(EVP_MD_CTX *ctx); +EVP_MD_CTX *FIPS_md_ctx_create(void); +void FIPS_md_ctx_destroy(EVP_MD_CTX *ctx); +int FIPS_digestinit(EVP_MD_CTX *ctx, const EVP_MD *type); +int FIPS_digestupdate(EVP_MD_CTX *ctx, const void *data, size_t count); +int FIPS_digestfinal(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size); +int FIPS_digest(const void *data, size_t count, + unsigned char *md, unsigned int *size, const EVP_MD *type); +int FIPS_md_ctx_cleanup(EVP_MD_CTX *ctx); +int FIPS_md_ctx_copy(EVP_MD_CTX *out,const EVP_MD_CTX *in); + + +void FIPS_cipher_ctx_init(EVP_CIPHER_CTX *ctx); +int FIPS_cipher_ctx_cleanup(EVP_CIPHER_CTX *c); +EVP_CIPHER_CTX *FIPS_cipher_ctx_new(void); +void FIPS_cipher_ctx_free(EVP_CIPHER_CTX *ctx); +int FIPS_cipherinit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, + const unsigned char *key, const unsigned char *iv, int enc); +int FIPS_cipher_ctx_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr); +int FIPS_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, unsigned int inl); + +#endif + +#if defined(OPENSSL_FIPSCANISTER) && defined(OPENSSL_FIPSEVP) + +#define EVP_MD_CTX_init FIPS_md_ctx_init +#define EVP_MD_CTX_cleanup FIPS_md_ctx_cleanup +#define EVP_MD_CTX_create FIPS_md_ctx_create +#define EVP_MD_CTX_destroy FIPS_md_ctx_destroy +#define EVP_DigestInit_ex(ctx, type, impl) FIPS_digestinit(ctx, type) +#define EVP_DigestUpdate FIPS_digestupdate +#define EVP_Digest(data, count, md, size, type, impl) \ + FIPS_digest(data, count, md, size, type) +#define EVP_DigestFinal_ex FIPS_digestfinal +#define EVP_MD_CTX_copy_ex FIPS_md_ctx_copy + +#define EVP_CipherInit_ex(ctx, cipher, impl, key, iv, enc) \ + FIPS_cipherinit(ctx, cipher, key, iv, enc) + +#define EVP_CIPHER_CTX_init FIPS_cipher_ctx_init +#define EVP_CIPHER_CTX_cleanup FIPS_cipher_ctx_cleanup +#define EVP_Cipher FIPS_cipher +#define EVP_CIPHER_CTX_ctrl FIPS_cipher_ctx_ctrl + +#else + void EVP_MD_CTX_init(EVP_MD_CTX *ctx); int EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx); EVP_MD_CTX *EVP_MD_CTX_create(void); void EVP_MD_CTX_destroy(EVP_MD_CTX *ctx); -__owur int EVP_MD_CTX_copy_ex(EVP_MD_CTX *out,const EVP_MD_CTX *in); -void EVP_MD_CTX_set_flags(EVP_MD_CTX *ctx, int flags); -void EVP_MD_CTX_clear_flags(EVP_MD_CTX *ctx, int flags); -int EVP_MD_CTX_test_flags(const EVP_MD_CTX *ctx,int flags); __owur int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl); __owur int EVP_DigestUpdate(EVP_MD_CTX *ctx,const void *d, size_t cnt); __owur int EVP_DigestFinal_ex(EVP_MD_CTX *ctx,unsigned char *md,unsigned int *s); __owur int EVP_Digest(const void *data, size_t count, unsigned char *md, unsigned int *size, const EVP_MD *type, ENGINE *impl); +#endif + +__owur int EVP_MD_CTX_copy_ex(EVP_MD_CTX *out,const EVP_MD_CTX *in); +void EVP_MD_CTX_set_flags(EVP_MD_CTX *ctx, int flags); +void EVP_MD_CTX_clear_flags(EVP_MD_CTX *ctx, int flags); +int EVP_MD_CTX_test_flags(const EVP_MD_CTX *ctx,int flags); __owur int EVP_MD_CTX_copy(EVP_MD_CTX *out,const EVP_MD_CTX *in); __owur int EVP_DigestInit(EVP_MD_CTX *ctx, const EVP_MD *type); diff --git a/crypto/evp/evp_lib.c b/crypto/evp/evp_lib.c index 40951a04f0..138dd47c3d 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); diff --git a/crypto/evp/evp_locl.h b/crypto/evp/evp_locl.h index 1b6c811fd6..94162d6419 100644 --- a/crypto/evp/evp_locl.h +++ b/crypto/evp/evp_locl.h @@ -254,14 +254,12 @@ const EVP_CIPHER *EVP_##cname##_ecb(void) { return &cname##_ecb; } #define EVP_C_DATA(kstruct, ctx) ((kstruct *)(ctx)->cipher_data) -#define IMPLEMENT_CFBR(cipher,cprefix,kstruct,ksched,keysize,cbits,iv_len) \ +#define IMPLEMENT_CFBR(cipher,cprefix,kstruct,ksched,keysize,cbits,iv_len,fl) \ 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, \ - 0, 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) struct evp_pkey_ctx_st { diff --git a/crypto/evp/m_sha1.c b/crypto/evp/m_sha1.c index 9a2790fdea..8c7e780a6d 100644 --- a/crypto/evp/m_sha1.c +++ b/crypto/evp/m_sha1.c @@ -68,6 +68,11 @@ #include #endif +#ifdef OPENSSL_FIPS +#include +#endif + + static int init(EVP_MD_CTX *ctx) { return SHA1_Init(ctx->md_data); } @@ -88,7 +93,7 @@ static const EVP_MD sha1_md= final, NULL, NULL, - EVP_PKEY_RSA_method, + EVP_PKEY_NULL_method, SHA_CBLOCK, sizeof(EVP_MD *)+sizeof(SHA_CTX), }; @@ -125,7 +130,7 @@ static const EVP_MD sha224_md= final256, NULL, NULL, - EVP_PKEY_RSA_method, + EVP_PKEY_NULL_method, SHA256_CBLOCK, sizeof(EVP_MD *)+sizeof(SHA256_CTX), }; @@ -144,7 +149,7 @@ static const EVP_MD sha256_md= final256, NULL, NULL, - EVP_PKEY_RSA_method, + EVP_PKEY_NULL_method, SHA256_CBLOCK, sizeof(EVP_MD *)+sizeof(SHA256_CTX), }; @@ -175,7 +180,7 @@ static const EVP_MD sha384_md= final512, NULL, NULL, - EVP_PKEY_RSA_method, + EVP_PKEY_NULL_method, SHA512_CBLOCK, sizeof(EVP_MD *)+sizeof(SHA512_CTX), }; @@ -194,7 +199,7 @@ static const EVP_MD sha512_md= final512, NULL, NULL, - EVP_PKEY_RSA_method, + EVP_PKEY_NULL_method, SHA512_CBLOCK, sizeof(EVP_MD *)+sizeof(SHA512_CTX), }; @@ -202,3 +207,4 @@ static const EVP_MD sha512_md= const EVP_MD *EVP_sha512(void) { return(&sha512_md); } #endif /* ifndef OPENSSL_NO_SHA512 */ + -- 2.25.1