From 7cfcca8ba3925fe80e4902168373c1e50a6728a7 Mon Sep 17 00:00:00 2001 From: "Dr. Stephen Henson" Date: Fri, 28 Jan 2005 14:03:54 +0000 Subject: [PATCH] Further FIPS algorithm blocking. Fixes to cipher blocking and enabling code. Add option -non-fips-allow to 'enc' and update testenc. --- apps/dgst.c | 3 +- apps/enc.c | 42 +++++++++++++++++++++--- crypto/evp/e_rc4.c | 1 + crypto/evp/evp.h | 3 ++ crypto/evp/evp_enc.c | 75 ++++++++++++++++++++++++++++++++++--------- crypto/evp/evp_locl.h | 1 + test/testenc | 16 ++++----- 7 files changed, 113 insertions(+), 28 deletions(-) diff --git a/apps/dgst.c b/apps/dgst.c index b30bf4e009..17fb87b77c 100644 --- a/apps/dgst.c +++ b/apps/dgst.c @@ -355,7 +355,8 @@ int MAIN(int argc, char **argv) /* we use md as a filter, reading from 'in' */ if (!BIO_set_md(bmd,md)) { - BIO_printf(bio_err, "Error setting digest %s\n", pname); + BIO_printf(bio_err, "Error setting digest %s\n", + EVP_MD_name(md)); ERR_print_errors(bio_err); goto end; } diff --git a/apps/enc.c b/apps/enc.c index cf1d98cd65..6f3161395e 100644 --- a/apps/enc.c +++ b/apps/enc.c @@ -118,6 +118,7 @@ int MAIN(int argc, char **argv) int enc=1,printkey=0,i,base64=0; int debug=0,olb64=0,nosalt=0; const EVP_CIPHER *cipher=NULL,*c; + EVP_CIPHER_CTX *ctx = NULL; char *inf=NULL,*outf=NULL; BIO *in=NULL,*out=NULL,*b64=NULL,*benc=NULL,*rbio=NULL,*wbio=NULL; #define PROG_NAME_SIZE 39 @@ -126,6 +127,7 @@ int MAIN(int argc, char **argv) char *engine = NULL; #endif const EVP_MD *dgst=NULL; + int non_fips_allow = 0; apps_startup(); @@ -260,6 +262,8 @@ int MAIN(int argc, char **argv) if (--argc < 1) goto bad; md= *(++argv); } + else if (strcmp(*argv,"-non-fips-allow") == 0) + non_fips_allow = 1; else if ((argv[0][0] == '-') && ((c=EVP_get_cipherbyname(&(argv[0][1]))) != NULL)) { @@ -539,13 +543,43 @@ bad: if ((benc=BIO_new(BIO_f_cipher())) == NULL) goto end; - BIO_set_cipher(benc,cipher,key,iv,enc); - if (nopad) + + /* Since we may be changing parameters work on the encryption + * context rather than calling BIO_set_cipher(). + */ + + BIO_get_cipher_ctx(benc, &ctx); + if (!EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, enc)) + { + BIO_printf(bio_err, "Error setting cipher %s\n", + EVP_CIPHER_name(cipher)); + ERR_print_errors(bio_err); + goto end; + } + + if (non_fips_allow) + EVP_CIPHER_CTX_set_flags(ctx, + EVP_CIPH_FLAG_NON_FIPS_ALLOW); + + if (!EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, enc)) { - EVP_CIPHER_CTX *ctx; - BIO_get_cipher_ctx(benc, &ctx); + BIO_printf(bio_err, "Error setting cipher %s\n", + EVP_CIPHER_name(cipher)); + ERR_print_errors(bio_err); + goto end; + } + + if (nopad) EVP_CIPHER_CTX_set_padding(ctx, 0); + + if (!EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, enc)) + { + BIO_printf(bio_err, "Error setting cipher %s\n", + EVP_CIPHER_name(cipher)); + ERR_print_errors(bio_err); + goto end; } + if (debug) { BIO_set_callback(benc,BIO_debug_callback); diff --git a/crypto/evp/e_rc4.c b/crypto/evp/e_rc4.c index d58f507837..8aa70585b9 100644 --- a/crypto/evp/e_rc4.c +++ b/crypto/evp/e_rc4.c @@ -62,6 +62,7 @@ #include "cryptlib.h" #include #include +#include "evp_locl.h" #include /* FIXME: surely this is available elsewhere? */ diff --git a/crypto/evp/evp.h b/crypto/evp/evp.h index 8aab0a5cb4..5cde88ae76 100644 --- a/crypto/evp/evp.h +++ b/crypto/evp/evp.h @@ -490,6 +490,9 @@ typedef int (EVP_PBE_KEYGEN)(EVP_CIPHER_CTX *ctx, const char *pass, int passlen, #define EVP_CIPHER_CTX_set_app_data(e,d) ((e)->app_data=(char *)(d)) #define EVP_CIPHER_CTX_type(c) EVP_CIPHER_type(EVP_CIPHER_CTX_cipher(c)) #define EVP_CIPHER_CTX_flags(e) ((e)->cipher->flags) +#define EVP_CIPHER_CTX_set_flags(ctx,flgs) ((ctx)->flags|=(flgs)) +#define EVP_CIPHER_CTX_clear_flags(ctx,flgs) ((ctx)->flags&=~(flgs)) +#define EVP_CIPHER_CTX_test_flags(ctx,flgs) ((ctx)->flags&(flgs)) #define EVP_CIPHER_CTX_mode(e) ((e)->cipher->flags & EVP_CIPH_MODE) #define EVP_ENCODE_LENGTH(l) (((l+2)/3*4)+(l/48+1)*2+80) diff --git a/crypto/evp/evp_enc.c b/crypto/evp/evp_enc.c index d8ff552d3b..f549eeb437 100644 --- a/crypto/evp/evp_enc.c +++ b/crypto/evp/evp_enc.c @@ -82,6 +82,48 @@ int EVP_CipherInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, return EVP_CipherInit_ex(ctx,cipher,NULL,key,iv,enc); } +#ifdef OPENSSL_FIPS + +/* The purpose of these is to trap programs that attempt to use non FIPS + * algorithms in FIPS mode and ignore the errors. + */ + +int bad_init(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc) + { FIPS_ERROR_IGNORED("Cipher init"); return 0;} + +int bad_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, unsigned int inl) + { FIPS_ERROR_IGNORED("Cipher update"); return 0;} + +/* NB: no cleanup because it is allowed after failed init */ + +int bad_set_asn1(EVP_CIPHER_CTX *ctx, ASN1_TYPE *typ) + { FIPS_ERROR_IGNORED("Cipher set_asn1"); return 0;} +int bad_get_asn1(EVP_CIPHER_CTX *ctx, ASN1_TYPE *typ) + { FIPS_ERROR_IGNORED("Cipher get_asn1"); return 0;} +int bad_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr) + { FIPS_ERROR_IGNORED("Cipher ctrl"); return 0;} + +static const EVP_CIPHER bad_cipher = + { + 0, + 0, + 0, + 0, + 0, + bad_init, + bad_do_cipher, + NULL, + 0, + bad_set_asn1, + bad_get_asn1, + bad_ctrl, + NULL + }; + +#endif + int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, ENGINE *impl, const unsigned char *key, const unsigned char *iv, int enc) { @@ -145,18 +187,6 @@ int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, ENGINE *imp } else ctx->engine = NULL; -#endif -#ifdef OPENSSL_FIPS - if (FIPS_mode()) - { - if (!(cipher->flags & EVP_CIPH_FLAG_FIPS) - & !(ctx->flags & EVP_CIPH_FLAG_NON_FIPS_ALLOW)) - { - EVPerr(EVP_F_EVP_CIPHERINIT, EVP_R_DISABLED_FOR_FIPS); - ERR_add_error_data(2, "cipher=", EVP_CIPHER_name(cipher)); - return 0; - } - } #endif ctx->cipher=cipher; if (ctx->cipher->ctx_size) @@ -221,6 +251,24 @@ skip_to_init: } } +#ifdef OPENSSL_FIPS + /* After 'key' is set no further parameters changes are permissible. + * So only check for non FIPS enabling at this point. + */ + if (key && FIPS_mode()) + { + if (!(ctx->cipher->flags & EVP_CIPH_FLAG_FIPS) + & !(ctx->flags & EVP_CIPH_FLAG_NON_FIPS_ALLOW)) + { + EVPerr(EVP_F_EVP_CIPHERINIT, EVP_R_DISABLED_FOR_FIPS); + ERR_add_error_data(2, "cipher=", + EVP_CIPHER_name(ctx->cipher)); + ctx->cipher = &bad_cipher; + return 0; + } + } +#endif + if(key || (ctx->cipher->flags & EVP_CIPH_ALWAYS_CALL_INIT)) { if(!ctx->cipher->init(ctx,key,iv,enc)) return 0; } @@ -282,9 +330,6 @@ int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, int i,j,bl; OPENSSL_assert(inl > 0); -#ifdef OPENSSL_FIPS - OPENSSL_assert(!FIPS_mode() || ctx->cipher->flags & EVP_CIPH_FLAG_FIPS); -#endif if(ctx->buf_len == 0 && (inl&(ctx->block_mask)) == 0) { if(ctx->cipher->do_cipher(ctx,out,in,inl)) diff --git a/crypto/evp/evp_locl.h b/crypto/evp/evp_locl.h index 845f222eec..f8c5343620 100644 --- a/crypto/evp/evp_locl.h +++ b/crypto/evp/evp_locl.h @@ -241,6 +241,7 @@ const EVP_CIPHER *EVP_##cname##_ecb(void) { return &cname##_ecb; } #define CAST_set_key private_CAST_set_key #define RC5_32_set_key private_RC5_32_set_key #define BF_set_key private_BF_set_key +#define idea_set_encrypt_key private_idea_set_encrypt_key #define MD5_Init private_MD5_Init #define MD4_Init private_MD4_Init diff --git a/test/testenc b/test/testenc index 70505f0222..88c04cc325 100644 --- a/test/testenc +++ b/test/testenc @@ -7,8 +7,8 @@ cmd=../apps/openssl cat $testsrc >$test; echo cat -$cmd enc < $test > $test.cipher -$cmd enc < $test.cipher >$test.clear +$cmd enc -non-fips-allow < $test > $test.cipher +$cmd enc -non-fips-allow < $test.cipher >$test.clear cmp $test $test.clear if [ $? != 0 ] then @@ -17,8 +17,8 @@ else /bin/rm $test.cipher $test.clear fi echo base64 -$cmd enc -a -e < $test > $test.cipher -$cmd enc -a -d < $test.cipher >$test.clear +$cmd enc -non-fips-allow -a -e < $test > $test.cipher +$cmd enc -non-fips-allow -a -d < $test.cipher >$test.clear cmp $test $test.clear if [ $? != 0 ] then @@ -30,8 +30,8 @@ fi for i in `$cmd list-cipher-commands` do echo $i - $cmd $i -bufsize 113 -e -k test < $test > $test.$i.cipher - $cmd $i -bufsize 157 -d -k test < $test.$i.cipher >$test.$i.clear + $cmd $i -non-fips-allow -bufsize 113 -e -k test < $test > $test.$i.cipher + $cmd $i -non-fips-allow -bufsize 157 -d -k test < $test.$i.cipher >$test.$i.clear cmp $test $test.$i.clear if [ $? != 0 ] then @@ -41,8 +41,8 @@ do fi echo $i base64 - $cmd $i -bufsize 113 -a -e -k test < $test > $test.$i.cipher - $cmd $i -bufsize 157 -a -d -k test < $test.$i.cipher >$test.$i.clear + $cmd $i -non-fips-allow -bufsize 113 -a -e -k test < $test > $test.$i.cipher + $cmd $i -non-fips-allow -bufsize 157 -a -d -k test < $test.$i.cipher >$test.$i.clear cmp $test $test.$i.clear if [ $? != 0 ] then -- 2.25.1