FIPS mode EVP changes:
authorDr. Stephen Henson <steve@openssl.org>
Wed, 26 Jan 2011 15:25:33 +0000 (15:25 +0000)
committerDr. Stephen Henson <steve@openssl.org>
Wed, 26 Jan 2011 15:25:33 +0000 (15:25 +0000)
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
crypto/evp/e_aes.c
crypto/evp/e_camellia.c
crypto/evp/e_des3.c
crypto/evp/evp.h
crypto/evp/evp_lib.c
crypto/evp/evp_locl.h
crypto/evp/m_sha1.c

index 4aa24fddfb7c67fc872f6d305670a660386489bf..99eba94c67a86a7fdc958069a06c57d0d140053e 100644 (file)
@@ -55,7 +55,7 @@ top:
 all:   lib
 
 lib:   $(LIBOBJ)
-       $(AR) $(LIB) $(LIBOBJ)
+       $(ARX) $(LIB) $(LIBOBJ)
        $(RANLIB) $(LIB) || echo Never mind.
        @touch lib
 
index a7fbba3689ff33ebacf98dc13c16f60fc4e289fc..32c903386b42b18652eed0d1e7a38ea9c06d41e0 100644 (file)
@@ -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)
index a7b40d1c6001065a34ca1a745c3678046a505689..365d39716455d4a8222ac26619412c425bc0cb1d 100644 (file)
@@ -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)
index 3232cfe024b2b3d671c431537bf669fe78cf4c17..785d76b5bdefe82f35fdc5671a03c3c6a03ca357 100644 (file)
@@ -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)
index 4548e6dddada28d60e8d9d2c1d02102eea0ac6af..0db6f15ac9d909f01687f84ed3152a55dd67f288 100644 (file)
@@ -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);
index 40951a04f0c9344c1f45b3780d86b28990aefcd0..138dd47c3dc25f0e9bfa0ac2bde85e249abaca57 100644 (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)
                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);
index 1b6c811fd64d270edbf9219a1b9e09674c85e6ef..94162d6419020372eb49d0aee4bc5fe8ececa6ae 100644 (file)
@@ -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
        {
index 9a2790fdea5400ec1e1762240ba8437d5e1f7624..8c7e780a6d0de27af3079b07170a73103755f591 100644 (file)
 #include <openssl/rsa.h>
 #endif
 
+#ifdef OPENSSL_FIPS
+#include <openssl/fips.h>
+#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 */
+