Further FIPS algorithm blocking.
authorDr. Stephen Henson <steve@openssl.org>
Fri, 28 Jan 2005 14:03:54 +0000 (14:03 +0000)
committerDr. Stephen Henson <steve@openssl.org>
Fri, 28 Jan 2005 14:03:54 +0000 (14:03 +0000)
Fixes to cipher blocking and enabling code.

Add option -non-fips-allow to 'enc' and update testenc.

apps/dgst.c
apps/enc.c
crypto/evp/e_rc4.c
crypto/evp/evp.h
crypto/evp/evp_enc.c
crypto/evp/evp_locl.h
test/testenc

index b30bf4e009329d4063029adf63bea6849b47cb05..17fb87b77cb213784701b208c46cb11a4cb1d891 100644 (file)
@@ -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;
                }
index cf1d98cd65362fc5f44d129c5151c3a64088e399..6f3161395ecd863fbb8f0a9067cb708ddb55ef71 100644 (file)
@@ -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);
index d58f507837bd54d9b14d1f842941a7e231e2968b..8aa70585b9acb4510e13aa74fbcfc10cc14c0240 100644 (file)
@@ -62,6 +62,7 @@
 #include "cryptlib.h"
 #include <openssl/evp.h>
 #include <openssl/objects.h>
+#include "evp_locl.h"
 #include <openssl/rc4.h>
 
 /* FIXME: surely this is available elsewhere? */
index 8aab0a5cb410f799fb524bafa877360e738769a3..5cde88ae76ba31f9eb574e352e6feb9f6681c5b0 100644 (file)
@@ -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)
index d8ff552d3b7034bd72bfa6ad9bfb6a3dbfd0c939..f549eeb4377b000bd24b8296d9bf92f43bfa370b 100644 (file)
@@ -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))
index 845f222eec1cd6063105e2274ee6a904325f29a3..f8c534362084d74f9628931db6fe2631db26091f 100644 (file)
@@ -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
index 70505f02225c8f6c92027e206f81a620a79dd760..88c04cc3250d7f19779fc080295f6e2a0928c619 100644 (file)
@@ -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