]> granicus.if.org Git - openssl/commitdiff
Merge EVP changes in from FIPS branch.
authorDr. Stephen Henson <steve@openssl.org>
Mon, 15 Sep 2008 22:21:42 +0000 (22:21 +0000)
committerDr. Stephen Henson <steve@openssl.org>
Mon, 15 Sep 2008 22:21:42 +0000 (22:21 +0000)
27 files changed:
crypto/evp/Makefile
crypto/evp/bio_md.c
crypto/evp/dig_eng.c [new file with mode: 0644]
crypto/evp/digest.c
crypto/evp/e_aes.c
crypto/evp/e_des.c
crypto/evp/e_des3.c
crypto/evp/e_null.c
crypto/evp/e_rc4.c
crypto/evp/enc_min.c [new file with mode: 0644]
crypto/evp/evp.h
crypto/evp/evp_cnf.c [new file with mode: 0644]
crypto/evp/evp_enc.c
crypto/evp/evp_err.c
crypto/evp/evp_lib.c
crypto/evp/evp_locl.h
crypto/evp/m_dss.c
crypto/evp/m_dss1.c
crypto/evp/m_md2.c
crypto/evp/m_md4.c
crypto/evp/m_md5.c
crypto/evp/m_mdc2.c
crypto/evp/m_sha.c
crypto/evp/m_sha1.c
crypto/evp/names.c
crypto/evp/p_sign.c
crypto/evp/p_verify.c

index 9de56dc03d77df49a59bed4fa409f3650f266ce9..6c7e24582b8b251e06ac1af36ac0950ded475492 100644 (file)
@@ -18,10 +18,10 @@ TESTDATA=evptests.txt
 APPS=
 
 LIB=$(TOP)/libcrypto.a
-LIBSRC= encode.c digest.c evp_enc.c evp_key.c evp_acnf.c \
+LIBSRC= encode.c digest.c dig_eng.c evp_enc.c evp_key.c evp_acnf.c evp_cnf.c \
        e_des.c e_bf.c e_idea.c e_des3.c e_camellia.c\
        e_rc4.c e_aes.c names.c e_seed.c \
-       e_xcbc_d.c e_rc2.c e_cast.c e_rc5.c \
+       e_xcbc_d.c e_rc2.c e_cast.c e_rc5.c enc_min.c \
        m_null.c m_md2.c m_md4.c m_md5.c m_sha.c m_sha1.c \
        m_dss.c m_dss1.c m_mdc2.c m_ripemd.c m_ecdsa.c\
        p_open.c p_seal.c p_sign.c p_verify.c p_lib.c p_enc.c p_dec.c \
@@ -30,10 +30,10 @@ LIBSRC= encode.c digest.c evp_enc.c evp_key.c evp_acnf.c \
        evp_pkey.c evp_pbe.c p5_crpt.c p5_crpt2.c \
        e_old.c
 
-LIBOBJ=        encode.o digest.o evp_enc.o evp_key.o evp_acnf.o \
+LIBOBJ=        encode.o digest.o dig_eng.o evp_enc.o evp_key.o evp_acnf.o evp_cnf.o \
        e_des.o e_bf.o e_idea.o e_des3.o e_camellia.o\
        e_rc4.o e_aes.o names.o e_seed.o \
-       e_xcbc_d.o e_rc2.o e_cast.o e_rc5.o \
+       e_xcbc_d.o e_rc2.o e_cast.o e_rc5.o enc_min.o \
        m_null.o m_md2.o m_md4.o m_md5.o m_sha.o m_sha1.o \
        m_dss.o m_dss1.o m_mdc2.o m_ripemd.o m_ecdsa.o\
        p_open.o p_seal.o p_sign.o p_verify.o p_lib.o p_enc.o p_dec.o \
index d648ac6da6badc63adf71607e312a7ac27ffdc4c..ed5c1135fd456bf87f5580f542e29d014647b860 100644 (file)
@@ -192,13 +192,8 @@ static long md_ctrl(BIO *b, int cmd, long num, void *ptr)
                        ret=0;
                break;
        case BIO_C_GET_MD_CTX:
-               if (b->init)
-                       {
-                       pctx=ptr;
-                       *pctx=ctx;
-                       }
-               else
-                       ret=0;
+               pctx=ptr;
+               *pctx=ctx;
                break;
        case BIO_C_SET_MD_CTX:
                if (b->init)
diff --git a/crypto/evp/dig_eng.c b/crypto/evp/dig_eng.c
new file mode 100644 (file)
index 0000000..64cdf93
--- /dev/null
@@ -0,0 +1,180 @@
+/* crypto/evp/digest.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2001 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/objects.h>
+#include <openssl/evp.h>
+#ifndef OPENSSL_NO_ENGINE
+#include <openssl/engine.h>
+#endif
+#include "evp_locl.h"
+
+#ifndef OPENSSL_NO_ENGINE
+
+#ifdef OPENSSL_FIPS
+
+static int do_evp_md_engine_full(EVP_MD_CTX *ctx, const EVP_MD **ptype, ENGINE *impl)
+       {
+       if (*ptype)
+               {
+               /* Ensure an ENGINE left lying around from last time is cleared
+                * (the previous check attempted to avoid this if the same
+                * ENGINE and EVP_MD could be used). */
+               if(ctx->engine)
+                       ENGINE_finish(ctx->engine);
+               if(impl)
+                       {
+                       if (!ENGINE_init(impl))
+                               {
+                               EVPerr(EVP_F_DO_EVP_MD_ENGINE_FULL,EVP_R_INITIALIZATION_ERROR);
+                               return 0;
+                               }
+                       }
+               else
+                       /* Ask if an ENGINE is reserved for this job */
+                       impl = ENGINE_get_digest_engine((*ptype)->type);
+               if(impl)
+                       {
+                       /* There's an ENGINE for this job ... (apparently) */
+                       const EVP_MD *d = ENGINE_get_digest(impl, (*ptype)->type);
+                       if(!d)
+                               {
+                               /* Same comment from evp_enc.c */
+                               EVPerr(EVP_F_DO_EVP_MD_ENGINE_FULL,EVP_R_INITIALIZATION_ERROR);
+                               return 0;
+                               }
+                       /* We'll use the ENGINE's private digest definition */
+                       *ptype = d;
+                       /* Store the ENGINE functional reference so we know
+                        * 'type' came from an ENGINE and we need to release
+                        * it when done. */
+                       ctx->engine = impl;
+                       }
+               else
+                       ctx->engine = NULL;
+               }
+       else
+       if(!ctx->digest)
+               {
+               EVPerr(EVP_F_DO_EVP_MD_ENGINE_FULL,EVP_R_NO_DIGEST_SET);
+               return 0;
+               }
+       return 1;
+       }
+
+void int_EVP_MD_init_engine_callbacks(void)
+       {
+       int_EVP_MD_set_engine_callbacks(
+               ENGINE_init, ENGINE_finish, do_evp_md_engine_full);
+       }
+#endif
+#endif
index 762e6d3450d31d41d5ff042f030a11db20753bc6..3bc2d1295c604d936fd6a166a55f72affa9bee42 100644 (file)
 #ifndef OPENSSL_NO_ENGINE
 #include <openssl/engine.h>
 #endif
+#include "evp_locl.h"
 
 void EVP_MD_CTX_init(EVP_MD_CTX *ctx)
        {
@@ -137,18 +138,77 @@ int EVP_DigestInit(EVP_MD_CTX *ctx, const EVP_MD *type)
        return EVP_DigestInit_ex(ctx, type, NULL);
        }
 
-int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl)
+#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.
+ */
+
+static int bad_init(EVP_MD_CTX *ctx)
+       { FIPS_ERROR_IGNORED("Digest init"); return 0;}
+
+static int bad_update(EVP_MD_CTX *ctx,const void *data,size_t count)
+       { FIPS_ERROR_IGNORED("Digest update"); return 0;}
+
+static int bad_final(EVP_MD_CTX *ctx,unsigned char *md)
+       { FIPS_ERROR_IGNORED("Digest Final"); return 0;}
+
+static const EVP_MD bad_md =
        {
-       EVP_MD_CTX_clear_flags(ctx,EVP_MD_CTX_FLAG_CLEANED);
+       0,
+       0,
+       0,
+       0,
+       bad_init,
+       bad_update,
+       bad_final,
+       NULL,
+       NULL,
+       NULL,
+       0,
+       {0,0,0,0},
+       };
+
+#endif
+
 #ifndef OPENSSL_NO_ENGINE
-       /* Whether it's nice or not, "Inits" can be used on "Final"'d contexts
-        * so this context may already have an ENGINE! Try to avoid releasing
-        * the previous handle, re-querying for an ENGINE, and having a
-        * reinitialisation, when it may all be unecessary. */
-       if (ctx->engine && ctx->digest && (!type ||
-                       (type && (type->type == ctx->digest->type))))
-               goto skip_to_init;
-       if (type)
+
+#ifdef OPENSSL_FIPS
+
+static int do_engine_null(ENGINE *impl) { return 0;}
+static int do_evp_md_engine_null(EVP_MD_CTX *ctx,
+                               const EVP_MD **ptype, ENGINE *impl)
+       { return 1; }
+
+static int (*do_engine_init)(ENGINE *impl)
+               = do_engine_null;
+
+static int (*do_engine_finish)(ENGINE *impl)
+               = do_engine_null;
+
+static int (*do_evp_md_engine)
+       (EVP_MD_CTX *ctx, const EVP_MD **ptype, ENGINE *impl)
+               = do_evp_md_engine_null;
+
+void int_EVP_MD_set_engine_callbacks(
+       int (*eng_md_init)(ENGINE *impl),
+       int (*eng_md_fin)(ENGINE *impl),
+       int (*eng_md_evp)
+               (EVP_MD_CTX *ctx, const EVP_MD **ptype, ENGINE *impl))
+       {
+       do_engine_init = eng_md_init;
+       do_engine_finish = eng_md_fin;
+       do_evp_md_engine = eng_md_evp;
+       }
+
+#else
+
+#define do_engine_init ENGINE_init
+#define do_engine_finish ENGINE_finish
+
+static int do_evp_md_engine(EVP_MD_CTX *ctx, const EVP_MD **ptype, ENGINE *impl)
+       {
+       if (*ptype)
                {
                /* Ensure an ENGINE left lying around from last time is cleared
                 * (the previous check attempted to avoid this if the same
@@ -159,25 +219,25 @@ int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl)
                        {
                        if (!ENGINE_init(impl))
                                {
-                               EVPerr(EVP_F_EVP_DIGESTINIT_EX,EVP_R_INITIALIZATION_ERROR);
+                               EVPerr(EVP_F_DO_EVP_MD_ENGINE,EVP_R_INITIALIZATION_ERROR);
                                return 0;
                                }
                        }
                else
                        /* Ask if an ENGINE is reserved for this job */
-                       impl = ENGINE_get_digest_engine(type->type);
+                       impl = ENGINE_get_digest_engine((*ptype)->type);
                if(impl)
                        {
                        /* There's an ENGINE for this job ... (apparently) */
-                       const EVP_MD *d = ENGINE_get_digest(impl, type->type);
+                       const EVP_MD *d = ENGINE_get_digest(impl, (*ptype)->type);
                        if(!d)
                                {
                                /* Same comment from evp_enc.c */
-                               EVPerr(EVP_F_EVP_DIGESTINIT_EX,EVP_R_INITIALIZATION_ERROR);
+                               EVPerr(EVP_F_DO_EVP_MD_ENGINE,EVP_R_INITIALIZATION_ERROR);
                                return 0;
                                }
                        /* We'll use the ENGINE's private digest definition */
-                       type = d;
+                       *ptype = d;
                        /* Store the ENGINE functional reference so we know
                         * 'type' came from an ENGINE and we need to release
                         * it when done. */
@@ -189,12 +249,52 @@ int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl)
        else
        if(!ctx->digest)
                {
-               EVPerr(EVP_F_EVP_DIGESTINIT_EX,EVP_R_NO_DIGEST_SET);
+               EVPerr(EVP_F_DO_EVP_MD_ENGINE,EVP_R_NO_DIGEST_SET);
                return 0;
                }
+       return 1;
+       }
+
+#endif
+
+#endif
+
+int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl)
+       {
+       M_EVP_MD_CTX_clear_flags(ctx,EVP_MD_CTX_FLAG_CLEANED);
+#ifdef OPENSSL_FIPS
+       if(FIPS_selftest_failed())
+               {
+               FIPSerr(FIPS_F_EVP_DIGESTINIT_EX,FIPS_R_FIPS_SELFTEST_FAILED);
+               ctx->digest = &bad_md;
+               return 0;
+               }
+#endif
+#ifndef OPENSSL_NO_ENGINE
+       /* Whether it's nice or not, "Inits" can be used on "Final"'d contexts
+        * so this context may already have an ENGINE! Try to avoid releasing
+        * the previous handle, re-querying for an ENGINE, and having a
+        * reinitialisation, when it may all be unecessary. */
+       if (ctx->engine && ctx->digest && (!type ||
+                       (type && (type->type == ctx->digest->type))))
+               goto skip_to_init;
+       if (!do_evp_md_engine(ctx, &type, impl))
+               return 0;
 #endif
        if (ctx->digest != type)
                {
+#ifdef OPENSSL_FIPS
+               if (FIPS_mode())
+                       {
+                       if (!(type->flags & EVP_MD_FLAG_FIPS) 
+                        && !(ctx->flags & EVP_MD_CTX_FLAG_NON_FIPS_ALLOW))
+                               {
+                               EVPerr(EVP_F_EVP_DIGESTINIT_EX, EVP_R_DISABLED_FOR_FIPS);
+                               ctx->digest = &bad_md;
+                               return 0;
+                               }
+                       }
+#endif
                if (ctx->digest && ctx->digest->ctx_size)
                        OPENSSL_free(ctx->md_data);
                ctx->digest=type;
@@ -202,7 +302,7 @@ int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl)
                        ctx->md_data=OPENSSL_malloc(type->ctx_size);
                }
 #ifndef OPENSSL_NO_ENGINE
-skip_to_init:
+       skip_to_init:
 #endif
        return ctx->digest->init(ctx);
        }
@@ -210,6 +310,9 @@ skip_to_init:
 int EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *data,
             size_t count)
        {
+#ifdef OPENSSL_FIPS
+       FIPS_selftest_check();
+#endif
        return ctx->digest->update(ctx,data,count);
        }
 
@@ -226,6 +329,9 @@ int EVP_DigestFinal(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size)
 int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size)
        {
        int ret;
+#ifdef OPENSSL_FIPS
+       FIPS_selftest_check();
+#endif
 
        OPENSSL_assert(ctx->digest->md_size <= EVP_MAX_MD_SIZE);
        ret=ctx->digest->final(ctx,md);
@@ -234,7 +340,7 @@ int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size)
        if (ctx->digest->cleanup)
                {
                ctx->digest->cleanup(ctx);
-               EVP_MD_CTX_set_flags(ctx,EVP_MD_CTX_FLAG_CLEANED);
+               M_EVP_MD_CTX_set_flags(ctx,EVP_MD_CTX_FLAG_CLEANED);
                }
        memset(ctx->md_data,0,ctx->digest->ctx_size);
        return ret;
@@ -256,7 +362,7 @@ int EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in)
                }
 #ifndef OPENSSL_NO_ENGINE
        /* Make sure it's safe to copy a digest context using an ENGINE */
-       if (in->engine && !ENGINE_init(in->engine))
+       if (in->engine && !do_engine_init(in->engine))
                {
                EVPerr(EVP_F_EVP_MD_CTX_COPY_EX,ERR_R_ENGINE_LIB);
                return 0;
@@ -266,7 +372,7 @@ int EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in)
        if (out->digest == in->digest)
                {
                tmp_buf = out->md_data;
-               EVP_MD_CTX_set_flags(out,EVP_MD_CTX_FLAG_REUSE);
+               M_EVP_MD_CTX_set_flags(out,EVP_MD_CTX_FLAG_REUSE);
                }
        else tmp_buf = NULL;
        EVP_MD_CTX_cleanup(out);
@@ -292,7 +398,7 @@ int EVP_Digest(const void *data, size_t count,
        int ret;
 
        EVP_MD_CTX_init(&ctx);
-       EVP_MD_CTX_set_flags(&ctx,EVP_MD_CTX_FLAG_ONESHOT);
+       M_EVP_MD_CTX_set_flags(&ctx,EVP_MD_CTX_FLAG_ONESHOT);
        ret=EVP_DigestInit_ex(&ctx, type, impl)
          && EVP_DigestUpdate(&ctx, data, count)
          && EVP_DigestFinal_ex(&ctx, md, size);
@@ -314,10 +420,10 @@ int EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx)
         * because sometimes only copies of the context are ever finalised.
         */
        if (ctx->digest && ctx->digest->cleanup
-           && !EVP_MD_CTX_test_flags(ctx,EVP_MD_CTX_FLAG_CLEANED))
+           && !M_EVP_MD_CTX_test_flags(ctx,EVP_MD_CTX_FLAG_CLEANED))
                ctx->digest->cleanup(ctx);
        if (ctx->digest && ctx->digest->ctx_size && ctx->md_data
-           && !EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_REUSE))
+           && !M_EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_REUSE))
                {
                OPENSSL_cleanse(ctx->md_data,ctx->digest->ctx_size);
                OPENSSL_free(ctx->md_data);
@@ -326,7 +432,7 @@ int EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx)
        if(ctx->engine)
                /* The EVP_MD we used belongs to an ENGINE, release the
                 * functional reference we held for this reason. */
-               ENGINE_finish(ctx->engine);
+               do_engine_finish(ctx->engine);
 #endif
        memset(ctx,'\0',sizeof *ctx);
 
index bd6c0a3a62a323a970a6d2d0bbc0ba9b869c595f..c9a5ee8d75a043d54d9bf1486d3b783cbdbbd36b 100644 (file)
@@ -69,32 +69,29 @@ 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,flags)  IMPLEMENT_CFBR(aes,AES,EVP_AES_KEY,ks,ksize,cbits,16,flags)
 
-IMPLEMENT_AES_CFBR(128,1)
-IMPLEMENT_AES_CFBR(192,1)
-IMPLEMENT_AES_CFBR(256,1)
+IMPLEMENT_AES_CFBR(128,1,EVP_CIPH_FLAG_FIPS)
+IMPLEMENT_AES_CFBR(192,1,EVP_CIPH_FLAG_FIPS)
+IMPLEMENT_AES_CFBR(256,1,EVP_CIPH_FLAG_FIPS)
 
-IMPLEMENT_AES_CFBR(128,8)
-IMPLEMENT_AES_CFBR(192,8)
-IMPLEMENT_AES_CFBR(256,8)
+IMPLEMENT_AES_CFBR(128,8,EVP_CIPH_FLAG_FIPS)
+IMPLEMENT_AES_CFBR(192,8,EVP_CIPH_FLAG_FIPS)
+IMPLEMENT_AES_CFBR(256,8,EVP_CIPH_FLAG_FIPS)
 
 static int aes_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
                   const unsigned char *iv, int enc)
index 856323648cd4c69ab3a9cfe66c87db824a7d8827..04376df23245834f1b020df4906aff81433b1f25 100644 (file)
@@ -129,18 +129,21 @@ static int des_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
     }
 
 BLOCK_CIPHER_defs(des, DES_key_schedule, NID_des, 8, 8, 8, 64,
-                       EVP_CIPH_RAND_KEY, des_init_key, NULL,
+                       EVP_CIPH_RAND_KEY,
+                       des_init_key, NULL,
                        EVP_CIPHER_set_asn1_iv,
                        EVP_CIPHER_get_asn1_iv,
                        des_ctrl)
 
 BLOCK_CIPHER_def_cfb(des,DES_key_schedule,NID_des,8,8,1,
-                    EVP_CIPH_RAND_KEY, des_init_key,NULL,
+                    EVP_CIPH_RAND_KEY,
+                    des_init_key, NULL,
                     EVP_CIPHER_set_asn1_iv,
                     EVP_CIPHER_get_asn1_iv,des_ctrl)
 
 BLOCK_CIPHER_def_cfb(des,DES_key_schedule,NID_des,8,8,8,
-                    EVP_CIPH_RAND_KEY,des_init_key,NULL,
+                    EVP_CIPH_RAND_KEY,
+                    des_init_key,NULL,
                     EVP_CIPHER_set_asn1_iv,
                     EVP_CIPHER_get_asn1_iv,des_ctrl)
 
index ac148efab237f4363261f1795cc24b8c72c9667f..b7d1adec6764f3597e0316b8a00af5a2fca67fc8 100644 (file)
@@ -164,9 +164,9 @@ 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_FIPS|EVP_CIPH_FLAG_DEFAULT_ASN1,
+                       des_ede_init_key,
+                       NULL, NULL, NULL,
                        des3_ctrl)
 
 #define des_ede3_cfb64_cipher des_ede_cfb64_cipher
@@ -175,21 +175,21 @@ 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,
+               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,
+               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,
+               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,
index 5205259f18ca2249a5cfaaef1140b6df8b4d2c4b..0872d733e475f04668efbc30df2ef7bcd469a07b 100644 (file)
@@ -69,7 +69,7 @@ static const EVP_CIPHER n_cipher=
        {
        NID_undef,
        1,0,0,
-       0,
+       EVP_CIPH_FLAG_FIPS,
        null_init_key,
        null_cipher,
        NULL,
index 67af850bea1ab955cdc3159bd57bb9f8a55c3b73..55baad7446dcef1925232574092a32e54b55cf59 100644 (file)
@@ -64,6 +64,7 @@
 #include <openssl/evp.h>
 #include <openssl/objects.h>
 #include <openssl/rc4.h>
+#include "evp_locl.h"
 
 /* FIXME: surely this is available elsewhere? */
 #define EVP_RC4_KEY_SIZE               16
diff --git a/crypto/evp/enc_min.c b/crypto/evp/enc_min.c
new file mode 100644 (file)
index 0000000..0368e53
--- /dev/null
@@ -0,0 +1,390 @@
+/* crypto/evp/enc_min.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/evp.h>
+#include <openssl/err.h>
+#include <openssl/rand.h>
+#ifndef OPENSSL_NO_ENGINE
+#include <openssl/engine.h>
+#endif
+#include "evp_locl.h"
+
+void EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *ctx)
+       {
+#ifdef OPENSSL_FIPS
+       FIPS_selftest_check();
+#endif
+       memset(ctx,0,sizeof(EVP_CIPHER_CTX));
+       /* ctx->cipher=NULL; */
+       }
+
+#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
+
+#ifndef OPENSSL_NO_ENGINE
+
+#ifdef OPENSSL_FIPS
+
+static int do_engine_null(ENGINE *impl) { return 0;}
+static int do_evp_enc_engine_null(EVP_CIPHER_CTX *ctx,
+                               const EVP_CIPHER **pciph, ENGINE *impl)
+       { return 1; }
+
+static int (*do_engine_finish)(ENGINE *impl)
+               = do_engine_null;
+
+static int (*do_evp_enc_engine)
+       (EVP_CIPHER_CTX *ctx, const EVP_CIPHER **pciph, ENGINE *impl)
+               = do_evp_enc_engine_null;
+
+void int_EVP_CIPHER_set_engine_callbacks(
+       int (*eng_ciph_fin)(ENGINE *impl),
+       int (*eng_ciph_evp)
+               (EVP_CIPHER_CTX *ctx, const EVP_CIPHER **pciph, ENGINE *impl))
+       {
+       do_engine_finish = eng_ciph_fin;
+       do_evp_enc_engine = eng_ciph_evp;
+       }
+
+#else
+
+#define do_engine_finish ENGINE_finish
+
+static int do_evp_enc_engine(EVP_CIPHER_CTX *ctx, const EVP_CIPHER **pcipher, ENGINE *impl)
+       {
+       if(impl)
+               {
+               if (!ENGINE_init(impl))
+                       {
+                       EVPerr(EVP_F_DO_EVP_ENC_ENGINE, EVP_R_INITIALIZATION_ERROR);
+                       return 0;
+                       }
+               }
+       else
+               /* Ask if an ENGINE is reserved for this job */
+               impl = ENGINE_get_cipher_engine((*pcipher)->nid);
+       if(impl)
+               {
+               /* There's an ENGINE for this job ... (apparently) */
+               const EVP_CIPHER *c = ENGINE_get_cipher(impl, (*pcipher)->nid);
+               if(!c)
+                       {
+                       /* One positive side-effect of US's export
+                        * control history, is that we should at least
+                        * be able to avoid using US mispellings of
+                        * "initialisation"? */
+                       EVPerr(EVP_F_DO_EVP_ENC_ENGINE, EVP_R_INITIALIZATION_ERROR);
+                       return 0;
+                       }
+               /* We'll use the ENGINE's private cipher definition */
+               *pcipher = c;
+               /* Store the ENGINE functional reference so we know
+                * 'cipher' came from an ENGINE and we need to release
+                * it when done. */
+               ctx->engine = impl;
+               }
+       else
+               ctx->engine = NULL;
+       return 1;
+       }
+
+#endif
+
+#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)
+       {
+       if (enc == -1)
+               enc = ctx->encrypt;
+       else
+               {
+               if (enc)
+                       enc = 1;
+               ctx->encrypt = enc;
+               }
+#ifdef OPENSSL_NO_FIPS
+       if(FIPS_selftest_failed())
+               {
+               FIPSerr(FIPS_F_EVP_CIPHERINIT_EX,FIPS_R_FIPS_SELFTEST_FAILED);
+               ctx->cipher = &bad_cipher;
+               return 0;
+               }
+#endif
+#ifndef OPENSSL_NO_ENGINE
+       /* Whether it's nice or not, "Inits" can be used on "Final"'d contexts
+        * so this context may already have an ENGINE! Try to avoid releasing
+        * the previous handle, re-querying for an ENGINE, and having a
+        * reinitialisation, when it may all be unecessary. */
+       if (ctx->engine && ctx->cipher && (!cipher ||
+                       (cipher && (cipher->nid == ctx->cipher->nid))))
+               goto skip_to_init;
+#endif
+       if (cipher)
+               {
+               /* Ensure a context left lying around from last time is cleared
+                * (the previous check attempted to avoid this if the same
+                * ENGINE and EVP_CIPHER could be used). */
+               EVP_CIPHER_CTX_cleanup(ctx);
+
+               /* Restore encrypt field: it is zeroed by cleanup */
+               ctx->encrypt = enc;
+#ifndef OPENSSL_NO_ENGINE
+               if (!do_evp_enc_engine(ctx, &cipher, impl))
+                       return 0;
+#endif
+
+               ctx->cipher=cipher;
+               if (ctx->cipher->ctx_size)
+                       {
+                       ctx->cipher_data=OPENSSL_malloc(ctx->cipher->ctx_size);
+                       if (!ctx->cipher_data)
+                               {
+                               EVPerr(EVP_F_EVP_CIPHERINIT_EX, ERR_R_MALLOC_FAILURE);
+                               return 0;
+                               }
+                       }
+               else
+                       {
+                       ctx->cipher_data = NULL;
+                       }
+               ctx->key_len = cipher->key_len;
+               ctx->flags = 0;
+               if(ctx->cipher->flags & EVP_CIPH_CTRL_INIT)
+                       {
+                       if(!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_INIT, 0, NULL))
+                               {
+                               EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_INITIALIZATION_ERROR);
+                               return 0;
+                               }
+                       }
+               }
+       else if(!ctx->cipher)
+               {
+               EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_NO_CIPHER_SET);
+               return 0;
+               }
+#ifndef OPENSSL_NO_ENGINE
+skip_to_init:
+#endif
+       /* we assume block size is a power of 2 in *cryptUpdate */
+       OPENSSL_assert(ctx->cipher->block_size == 1
+           || ctx->cipher->block_size == 8
+           || ctx->cipher->block_size == 16);
+
+       if(!(EVP_CIPHER_CTX_flags(ctx) & EVP_CIPH_CUSTOM_IV)) {
+               switch(EVP_CIPHER_CTX_mode(ctx)) {
+
+                       case EVP_CIPH_STREAM_CIPHER:
+                       case EVP_CIPH_ECB_MODE:
+                       break;
+
+                       case EVP_CIPH_CFB_MODE:
+                       case EVP_CIPH_OFB_MODE:
+
+                       ctx->num = 0;
+
+                       case EVP_CIPH_CBC_MODE:
+
+                       OPENSSL_assert(EVP_CIPHER_CTX_iv_length(ctx) <=
+                                       (int)sizeof(ctx->iv));
+                       if(iv) memcpy(ctx->oiv, iv, EVP_CIPHER_CTX_iv_length(ctx));
+                       memcpy(ctx->iv, ctx->oiv, EVP_CIPHER_CTX_iv_length(ctx));
+                       break;
+
+                       default:
+                       return 0;
+                       break;
+               }
+       }
+
+#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_EX, EVP_R_DISABLED_FOR_FIPS);
+#if 0
+                       ERR_add_error_data(2, "cipher=",
+                                               EVP_CIPHER_name(ctx->cipher));
+#endif
+                       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;
+       }
+       ctx->buf_len=0;
+       ctx->final_used=0;
+       ctx->block_mask=ctx->cipher->block_size-1;
+       return 1;
+       }
+
+int EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *c)
+       {
+       if (c->cipher != NULL)
+               {
+               if(c->cipher->cleanup && !c->cipher->cleanup(c))
+                       return 0;
+               /* Cleanse cipher context data */
+               if (c->cipher_data)
+                       OPENSSL_cleanse(c->cipher_data, c->cipher->ctx_size);
+               }
+       if (c->cipher_data)
+               OPENSSL_free(c->cipher_data);
+#ifndef OPENSSL_NO_ENGINE
+       if (c->engine)
+               /* The EVP_CIPHER we used belongs to an ENGINE, release the
+                * functional reference we held for this reason. */
+               do_engine_finish(c->engine);
+#endif
+       memset(c,0,sizeof(EVP_CIPHER_CTX));
+       return 1;
+       }
+
+int EVP_Cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, unsigned int inl)
+       {
+#ifdef OPENSSL_FIPS
+       FIPS_selftest_check();
+#endif
+       return ctx->cipher->do_cipher(ctx,out,in,inl);
+       }
+
+int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr)
+{
+       int ret;
+       if(!ctx->cipher) {
+               EVPerr(EVP_F_EVP_CIPHER_CTX_CTRL, EVP_R_NO_CIPHER_SET);
+               return 0;
+       }
+
+       if(!ctx->cipher->ctrl) {
+               EVPerr(EVP_F_EVP_CIPHER_CTX_CTRL, EVP_R_CTRL_NOT_IMPLEMENTED);
+               return 0;
+       }
+
+       ret = ctx->cipher->ctrl(ctx, type, arg, ptr);
+       if(ret == -1) {
+               EVPerr(EVP_F_EVP_CIPHER_CTX_CTRL, EVP_R_CTRL_OPERATION_NOT_IMPLEMENTED);
+               return 0;
+       }
+       return ret;
+}
+
+unsigned long EVP_CIPHER_CTX_flags(const EVP_CIPHER_CTX *ctx)
+       {
+       return ctx->cipher->flags;
+       }
+
+int EVP_CIPHER_CTX_iv_length(const EVP_CIPHER_CTX *ctx)
+       {
+       return ctx->cipher->iv_len;
+       }
+
+int EVP_CIPHER_nid(const EVP_CIPHER *cipher)
+       {
+       return cipher->nid;
+       }
index 09e621bebeb83f8c0f9540671d997e31ca7cefd0..8bf05de1ad442d125eb96e280d5e8177b60083b4 100644 (file)
 #include <openssl/bio.h>
 #endif
 
+#ifdef OPENSSL_FIPS
+#include <openssl/fips.h>
+#endif
+
 /*
 #define EVP_RC2_KEY_SIZE               16
 #define EVP_RC4_KEY_SIZE               16
@@ -250,9 +254,19 @@ typedef int evp_verify_method(int type,const unsigned char *m,
                            unsigned int m_length,const unsigned char *sigbuf,
                            unsigned int siglen, void *key);
 
+typedef struct
+       {
+       EVP_MD_CTX *mctx;
+       void *key;
+       } EVP_MD_SVCTX;
+
 #define EVP_MD_FLAG_ONESHOT    0x0001 /* digest can only handle a single
                                        * block */
 
+#define EVP_MD_FLAG_FIPS       0x0400 /* Note if suitable for use in FIPS mode */
+
+#define EVP_MD_FLAG_SVCTX      0x0800 /* pass EVP_MD_SVCTX to sign/verify */
+
 #define EVP_PKEY_NULL_method   NULL,NULL,{0,0,0,0}
 
 #ifndef OPENSSL_NO_DSA
@@ -306,6 +320,15 @@ struct env_md_ctx_st
 #define EVP_MD_CTX_FLAG_NON_FIPS_ALLOW 0x0008  /* Allow use of non FIPS digest
                                                 * in FIPS mode */
 
+#define EVP_MD_CTX_FLAG_PAD_MASK       0xF0    /* RSA mode to use */
+#define EVP_MD_CTX_FLAG_PAD_PKCS1      0x00    /* PKCS#1 v1.5 mode */
+#define EVP_MD_CTX_FLAG_PAD_X931       0x10    /* X9.31 mode */
+#define EVP_MD_CTX_FLAG_PAD_PSS                0x20    /* PSS mode */
+#define M_EVP_MD_CTX_FLAG_PSS_SALT(ctx) \
+               ((ctx->flags>>16) &0xFFFF) /* seed length */
+#define EVP_MD_CTX_FLAG_PSS_MDLEN      0xFFFF  /* salt len same as digest */
+#define EVP_MD_CTX_FLAG_PSS_MREC       0xFFFE  /* salt max or auto recovered */
+
 struct evp_cipher_st
        {
        int nid;
@@ -349,6 +372,14 @@ struct evp_cipher_st
 #define        EVP_CIPH_NO_PADDING             0x100
 /* cipher handles random key generation */
 #define        EVP_CIPH_RAND_KEY               0x200
+/* Note if suitable for use in FIPS mode */
+#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
+/* Buffer length in bits not bytes: CFB1 mode only */
+#define                EVP_CIPH_FLAG_LENGTH_BITS       0x2000
 
 /* ctrl() values */
 
@@ -431,6 +462,18 @@ 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_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))
@@ -526,6 +569,10 @@ int        EVP_BytesToKey(const EVP_CIPHER *type,const EVP_MD *md,
                const unsigned char *salt, const unsigned char *data,
                int datal, int count, unsigned char *key,unsigned char *iv);
 
+void   EVP_CIPHER_CTX_set_flags(EVP_CIPHER_CTX *ctx, int flags);
+void   EVP_CIPHER_CTX_clear_flags(EVP_CIPHER_CTX *ctx, int flags);
+int    EVP_CIPHER_CTX_test_flags(const EVP_CIPHER_CTX *ctx,int flags);
+
 int    EVP_EncryptInit(EVP_CIPHER_CTX *ctx,const EVP_CIPHER *cipher,
                const unsigned char *key, const unsigned char *iv);
 int    EVP_EncryptInit_ex(EVP_CIPHER_CTX *ctx,const EVP_CIPHER *cipher, ENGINE *impl,
@@ -881,6 +928,24 @@ int EVP_PBE_alg_add(int nid, const EVP_CIPHER *cipher, const EVP_MD *md,
                    EVP_PBE_KEYGEN *keygen);
 void EVP_PBE_cleanup(void);
 
+#ifdef OPENSSL_FIPS
+#ifndef OPENSSL_NO_ENGINE
+void int_EVP_MD_set_engine_callbacks(
+       int (*eng_md_init)(ENGINE *impl),
+       int (*eng_md_fin)(ENGINE *impl),
+       int (*eng_md_evp)
+               (EVP_MD_CTX *ctx, const EVP_MD **ptype, ENGINE *impl));
+void int_EVP_MD_init_engine_callbacks(void);
+void int_EVP_CIPHER_set_engine_callbacks(
+       int (*eng_ciph_fin)(ENGINE *impl),
+       int (*eng_ciph_evp)
+               (EVP_CIPHER_CTX *ctx, const EVP_CIPHER **pciph, ENGINE *impl));
+void int_EVP_CIPHER_init_engine_callbacks(void);
+#endif
+#endif
+
+void EVP_add_alg_module(void);
+
 /* BEGIN ERROR CODES */
 /* The following lines are auto generated by the script mkerr.pl. Any changes
  * made after this point may be overwritten when the script is next run.
@@ -891,16 +956,23 @@ void ERR_load_EVP_strings(void);
 
 /* Function codes. */
 #define EVP_F_AES_INIT_KEY                              133
+#define EVP_F_ALG_MODULE_INIT                           138
 #define EVP_F_CAMELLIA_INIT_KEY                                 159
 #define EVP_F_D2I_PKEY                                  100
+#define EVP_F_DO_EVP_ENC_ENGINE                                 140
+#define EVP_F_DO_EVP_ENC_ENGINE_FULL                    141
+#define EVP_F_DO_EVP_MD_ENGINE                          139
+#define EVP_F_DO_EVP_MD_ENGINE_FULL                     142
 #define EVP_F_DSAPKEY2PKCS8                             134
 #define EVP_F_DSA_PKEY2PKCS8                            135
 #define EVP_F_ECDSA_PKEY2PKCS8                          129
 #define EVP_F_ECKEY_PKEY2PKCS8                          132
+#define EVP_F_EVP_CIPHERINIT                            137
 #define EVP_F_EVP_CIPHERINIT_EX                                 123
 #define EVP_F_EVP_CIPHER_CTX_CTRL                       124
 #define EVP_F_EVP_CIPHER_CTX_SET_KEY_LENGTH             122
 #define EVP_F_EVP_DECRYPTFINAL_EX                       101
+#define EVP_F_EVP_DIGESTINIT                            136
 #define EVP_F_EVP_DIGESTINIT_EX                                 128
 #define EVP_F_EVP_ENCRYPTFINAL_EX                       127
 #define EVP_F_EVP_MD_CTX_COPY_EX                        110
@@ -942,15 +1014,20 @@ void ERR_load_EVP_strings(void);
 #define EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH                 138
 #define EVP_R_DECODE_ERROR                              114
 #define EVP_R_DIFFERENT_KEY_TYPES                       101
+#define EVP_R_DISABLED_FOR_FIPS                                 144
 #define EVP_R_ENCODE_ERROR                              115
+#define EVP_R_ERROR_LOADING_SECTION                     145
+#define EVP_R_ERROR_SETTING_FIPS_MODE                   146
 #define EVP_R_EVP_PBE_CIPHERINIT_ERROR                  119
 #define EVP_R_EXPECTING_AN_RSA_KEY                      127
 #define EVP_R_EXPECTING_A_DH_KEY                        128
 #define EVP_R_EXPECTING_A_DSA_KEY                       129
 #define EVP_R_EXPECTING_A_ECDSA_KEY                     141
 #define EVP_R_EXPECTING_A_EC_KEY                        142
+#define EVP_R_FIPS_MODE_NOT_SUPPORTED                   147
 #define EVP_R_INITIALIZATION_ERROR                      134
 #define EVP_R_INPUT_NOT_INITIALIZED                     111
+#define EVP_R_INVALID_FIPS_MODE                                 148
 #define EVP_R_INVALID_KEY_LENGTH                        130
 #define EVP_R_IV_TOO_LARGE                              102
 #define EVP_R_KEYGEN_FAILURE                            120
@@ -962,6 +1039,8 @@ void ERR_load_EVP_strings(void);
 #define EVP_R_NO_VERIFY_FUNCTION_CONFIGURED             105
 #define EVP_R_PKCS8_UNKNOWN_BROKEN_TYPE                         117
 #define EVP_R_PUBLIC_KEY_NOT_RSA                        106
+#define EVP_R_SEED_KEY_SETUP_FAILED                     162
+#define EVP_R_UNKNOWN_OPTION                            149
 #define EVP_R_UNKNOWN_PBE_ALGORITHM                     121
 #define EVP_R_UNSUPORTED_NUMBER_OF_ROUNDS               135
 #define EVP_R_UNSUPPORTED_CIPHER                        107
diff --git a/crypto/evp/evp_cnf.c b/crypto/evp/evp_cnf.c
new file mode 100644 (file)
index 0000000..5bdd57b
--- /dev/null
@@ -0,0 +1,125 @@
+/* evp_cnf.c */
+/* Written by Stephen Henson (shenson@bigfoot.com) for the OpenSSL
+ * project 2007.
+ */
+/* ====================================================================
+ * Copyright (c) 2007 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include <ctype.h>
+#include <openssl/crypto.h>
+#include "cryptlib.h"
+#include <openssl/conf.h>
+#include <openssl/dso.h>
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+#ifdef OPENSSL_FIPS
+#include <openssl/fips.h>
+#endif
+
+
+/* Algorithm configuration module. */
+
+static int alg_module_init(CONF_IMODULE *md, const CONF *cnf)
+       {
+       int i;
+       const char *oid_section;
+       STACK_OF(CONF_VALUE) *sktmp;
+       CONF_VALUE *oval;
+       oid_section = CONF_imodule_get_value(md);
+       if(!(sktmp = NCONF_get_section(cnf, oid_section)))
+               {
+               EVPerr(EVP_F_ALG_MODULE_INIT, EVP_R_ERROR_LOADING_SECTION);
+               return 0;
+               }
+       for(i = 0; i < sk_CONF_VALUE_num(sktmp); i++)
+               {
+               oval = sk_CONF_VALUE_value(sktmp, i);
+               if (!strcmp(oval->name, "fips_mode"))
+                       {
+                       int m;
+                       if (!X509V3_get_value_bool(oval, &m))
+                               {
+                               EVPerr(EVP_F_ALG_MODULE_INIT, EVP_R_INVALID_FIPS_MODE);
+                               return 0;
+                               }
+                       if (m > 0)
+                               {
+#ifdef OPENSSL_FIPS
+                               if (!FIPS_mode_set(1))
+                                       {
+                                       EVPerr(EVP_F_ALG_MODULE_INIT, EVP_R_ERROR_SETTING_FIPS_MODE);
+                                       return 0;
+                                       }
+#else
+                               EVPerr(EVP_F_ALG_MODULE_INIT, EVP_R_FIPS_MODE_NOT_SUPPORTED);
+                               return 0;
+#endif
+                               }
+                       }
+               else
+                       {
+                       EVPerr(EVP_F_ALG_MODULE_INIT, EVP_R_UNKNOWN_OPTION);
+                       ERR_add_error_data(4, "name=", oval->name,
+                                               ", value=", oval->value);
+                       }
+                               
+               }
+       return 1;
+       }
+
+void EVP_add_alg_module(void)
+       {
+       CONF_module_add("alg_section", alg_module_init, 0);
+       }
index 6e582c458de55b5fc7b230d3d3c546fc42cbbb43..304ce7ea6871bb37a419a00b4f22ab882f33fbb1 100644 (file)
 #endif
 #include "evp_locl.h"
 
-const char EVP_version[]="EVP" OPENSSL_VERSION_PTEXT;
+#ifdef OPENSSL_FIPS
+       #define M_do_cipher(ctx, out, in, inl) \
+               EVP_Cipher(ctx,out,in,inl)
+#else
+       #define M_do_cipher(ctx, out, in, inl) \
+               ctx->cipher->do_cipher(ctx,out,in,inl)
+#endif
 
-void EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *ctx)
-       {
-       memset(ctx,0,sizeof(EVP_CIPHER_CTX));
-       /* ctx->cipher=NULL; */
-       }
+const char EVP_version[]="EVP" OPENSSL_VERSION_PTEXT;
 
 EVP_CIPHER_CTX *EVP_CIPHER_CTX_new(void)
        {
@@ -90,144 +92,6 @@ int EVP_CipherInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
        return EVP_CipherInit_ex(ctx,cipher,NULL,key,iv,enc);
        }
 
-int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, ENGINE *impl,
-            const unsigned char *key, const unsigned char *iv, int enc)
-       {
-       if (enc == -1)
-               enc = ctx->encrypt;
-       else
-               {
-               if (enc)
-                       enc = 1;
-               ctx->encrypt = enc;
-               }
-#ifndef OPENSSL_NO_ENGINE
-       /* Whether it's nice or not, "Inits" can be used on "Final"'d contexts
-        * so this context may already have an ENGINE! Try to avoid releasing
-        * the previous handle, re-querying for an ENGINE, and having a
-        * reinitialisation, when it may all be unecessary. */
-       if (ctx->engine && ctx->cipher && (!cipher ||
-                       (cipher && (cipher->nid == ctx->cipher->nid))))
-               goto skip_to_init;
-#endif
-       if (cipher)
-               {
-               /* Ensure a context left lying around from last time is cleared
-                * (the previous check attempted to avoid this if the same
-                * ENGINE and EVP_CIPHER could be used). */
-               EVP_CIPHER_CTX_cleanup(ctx);
-
-               /* Restore encrypt field: it is zeroed by cleanup */
-               ctx->encrypt = enc;
-#ifndef OPENSSL_NO_ENGINE
-               if(impl)
-                       {
-                       if (!ENGINE_init(impl))
-                               {
-                               EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_INITIALIZATION_ERROR);
-                               return 0;
-                               }
-                       }
-               else
-                       /* Ask if an ENGINE is reserved for this job */
-                       impl = ENGINE_get_cipher_engine(cipher->nid);
-               if(impl)
-                       {
-                       /* There's an ENGINE for this job ... (apparently) */
-                       const EVP_CIPHER *c = ENGINE_get_cipher(impl, cipher->nid);
-                       if(!c)
-                               {
-                               /* One positive side-effect of US's export
-                                * control history, is that we should at least
-                                * be able to avoid using US mispellings of
-                                * "initialisation"? */
-                               EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_INITIALIZATION_ERROR);
-                               return 0;
-                               }
-                       /* We'll use the ENGINE's private cipher definition */
-                       cipher = c;
-                       /* Store the ENGINE functional reference so we know
-                        * 'cipher' came from an ENGINE and we need to release
-                        * it when done. */
-                       ctx->engine = impl;
-                       }
-               else
-                       ctx->engine = NULL;
-#endif
-
-               ctx->cipher=cipher;
-               if (ctx->cipher->ctx_size)
-                       {
-                       ctx->cipher_data=OPENSSL_malloc(ctx->cipher->ctx_size);
-                       if (!ctx->cipher_data)
-                               {
-                               EVPerr(EVP_F_EVP_CIPHERINIT_EX, ERR_R_MALLOC_FAILURE);
-                               return 0;
-                               }
-                       }
-               else
-                       {
-                       ctx->cipher_data = NULL;
-                       }
-               ctx->key_len = cipher->key_len;
-               ctx->flags = 0;
-               if(ctx->cipher->flags & EVP_CIPH_CTRL_INIT)
-                       {
-                       if(!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_INIT, 0, NULL))
-                               {
-                               EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_INITIALIZATION_ERROR);
-                               return 0;
-                               }
-                       }
-               }
-       else if(!ctx->cipher)
-               {
-               EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_NO_CIPHER_SET);
-               return 0;
-               }
-#ifndef OPENSSL_NO_ENGINE
-skip_to_init:
-#endif
-       /* we assume block size is a power of 2 in *cryptUpdate */
-       OPENSSL_assert(ctx->cipher->block_size == 1
-           || ctx->cipher->block_size == 8
-           || ctx->cipher->block_size == 16);
-
-       if(!(EVP_CIPHER_CTX_flags(ctx) & EVP_CIPH_CUSTOM_IV)) {
-               switch(EVP_CIPHER_CTX_mode(ctx)) {
-
-                       case EVP_CIPH_STREAM_CIPHER:
-                       case EVP_CIPH_ECB_MODE:
-                       break;
-
-                       case EVP_CIPH_CFB_MODE:
-                       case EVP_CIPH_OFB_MODE:
-
-                       ctx->num = 0;
-
-                       case EVP_CIPH_CBC_MODE:
-
-                       OPENSSL_assert(EVP_CIPHER_CTX_iv_length(ctx) <=
-                                       (int)sizeof(ctx->iv));
-                       if(iv) memcpy(ctx->oiv, iv, EVP_CIPHER_CTX_iv_length(ctx));
-                       memcpy(ctx->iv, ctx->oiv, EVP_CIPHER_CTX_iv_length(ctx));
-                       break;
-
-                       default:
-                       return 0;
-                       break;
-               }
-       }
-
-       if(key || (ctx->cipher->flags & EVP_CIPH_ALWAYS_CALL_INIT)) {
-               if(!ctx->cipher->init(ctx,key,iv,enc)) return 0;
-       }
-       ctx->buf_len=0;
-       ctx->final_used=0;
-       ctx->block_mask=ctx->cipher->block_size-1;
-       return 1;
-       }
-
 int EVP_CipherUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
             const unsigned char *in, int inl)
        {
@@ -279,15 +143,10 @@ int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
        {
        int i,j,bl;
 
-       if (inl <= 0)
-               {
-               *outl = 0;
-               return inl == 0;
-               }
-
+       OPENSSL_assert(inl > 0);
        if(ctx->buf_len == 0 && (inl&(ctx->block_mask)) == 0)
                {
-               if(ctx->cipher->do_cipher(ctx,out,in,inl))
+               if(M_do_cipher(ctx,out,in,inl))
                        {
                        *outl=inl;
                        return 1;
@@ -314,7 +173,7 @@ int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
                        {
                        j=bl-i;
                        memcpy(&(ctx->buf[i]),in,j);
-                       if(!ctx->cipher->do_cipher(ctx,out,ctx->buf,bl)) return 0;
+                       if(!M_do_cipher(ctx,out,ctx->buf,bl)) return 0;
                        inl-=j;
                        in+=j;
                        out+=bl;
@@ -327,7 +186,7 @@ int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
        inl-=i;
        if (inl > 0)
                {
-               if(!ctx->cipher->do_cipher(ctx,out,in,inl)) return 0;
+               if(!M_do_cipher(ctx,out,in,inl)) return 0;
                *outl+=inl;
                }
 
@@ -371,7 +230,7 @@ int EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
        n=b-bl;
        for (i=bl; i<b; i++)
                ctx->buf[i]=n;
-       ret=ctx->cipher->do_cipher(ctx,out,ctx->buf,b);
+       ret=M_do_cipher(ctx,out,ctx->buf,b);
 
 
        if(ret)
@@ -386,10 +245,10 @@ int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
        int fix_len;
        unsigned int b;
 
-       if (inl <= 0)
+       if (inl == 0)
                {
-               *outl = 0;
-               return inl == 0;
+               *outl=0;
+               return 1;
                }
 
        if (ctx->flags & EVP_CIPH_NO_PADDING)
@@ -493,28 +352,6 @@ void EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *ctx)
                }
        }
 
-int EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *c)
-       {
-       if (c->cipher != NULL)
-               {
-               if(c->cipher->cleanup && !c->cipher->cleanup(c))
-                       return 0;
-               /* Cleanse cipher context data */
-               if (c->cipher_data)
-                       OPENSSL_cleanse(c->cipher_data, c->cipher->ctx_size);
-               }
-       if (c->cipher_data)
-               OPENSSL_free(c->cipher_data);
-#ifndef OPENSSL_NO_ENGINE
-       if (c->engine)
-               /* The EVP_CIPHER we used belongs to an ENGINE, release the
-                * functional reference we held for this reason. */
-               ENGINE_finish(c->engine);
-#endif
-       memset(c,0,sizeof(EVP_CIPHER_CTX));
-       return 1;
-       }
-
 int EVP_CIPHER_CTX_set_key_length(EVP_CIPHER_CTX *c, int keylen)
        {
        if(c->cipher->flags & EVP_CIPH_CUSTOM_KEY_LENGTH) 
@@ -536,27 +373,6 @@ int EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX *ctx, int pad)
        return 1;
        }
 
-int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr)
-{
-       int ret;
-       if(!ctx->cipher) {
-               EVPerr(EVP_F_EVP_CIPHER_CTX_CTRL, EVP_R_NO_CIPHER_SET);
-               return 0;
-       }
-
-       if(!ctx->cipher->ctrl) {
-               EVPerr(EVP_F_EVP_CIPHER_CTX_CTRL, EVP_R_CTRL_NOT_IMPLEMENTED);
-               return 0;
-       }
-
-       ret = ctx->cipher->ctrl(ctx, type, arg, ptr);
-       if(ret == -1) {
-               EVPerr(EVP_F_EVP_CIPHER_CTX_CTRL, EVP_R_CTRL_OPERATION_NOT_IMPLEMENTED);
-               return 0;
-       }
-       return ret;
-}
-
 int EVP_CIPHER_CTX_rand_key(EVP_CIPHER_CTX *ctx, unsigned char *key)
        {
        if (ctx->cipher->flags & EVP_CIPH_RAND_KEY)
@@ -566,3 +382,54 @@ int EVP_CIPHER_CTX_rand_key(EVP_CIPHER_CTX *ctx, unsigned char *key)
        return 1;
        }
 
+#ifndef OPENSSL_NO_ENGINE
+
+#ifdef OPENSSL_FIPS
+
+static int do_evp_enc_engine_full(EVP_CIPHER_CTX *ctx, const EVP_CIPHER **pcipher, ENGINE *impl)
+       {
+       if(impl)
+               {
+               if (!ENGINE_init(impl))
+                       {
+                       EVPerr(EVP_F_DO_EVP_ENC_ENGINE_FULL, EVP_R_INITIALIZATION_ERROR);
+                       return 0;
+                       }
+               }
+       else
+               /* Ask if an ENGINE is reserved for this job */
+               impl = ENGINE_get_cipher_engine((*pcipher)->nid);
+       if(impl)
+               {
+               /* There's an ENGINE for this job ... (apparently) */
+               const EVP_CIPHER *c = ENGINE_get_cipher(impl, (*pcipher)->nid);
+               if(!c)
+                       {
+                       /* One positive side-effect of US's export
+                        * control history, is that we should at least
+                        * be able to avoid using US mispellings of
+                        * "initialisation"? */
+                       EVPerr(EVP_F_DO_EVP_ENC_ENGINE_FULL, EVP_R_INITIALIZATION_ERROR);
+                       return 0;
+                       }
+               /* We'll use the ENGINE's private cipher definition */
+               *pcipher = c;
+               /* Store the ENGINE functional reference so we know
+                * 'cipher' came from an ENGINE and we need to release
+                * it when done. */
+               ctx->engine = impl;
+               }
+       else
+               ctx->engine = NULL;
+       return 1;
+       }
+
+void int_EVP_CIPHER_init_engine_callbacks(void)
+       {
+       int_EVP_CIPHER_set_engine_callbacks(
+               ENGINE_finish, do_evp_enc_engine_full);
+       }
+
+#endif
+
+#endif
index e8c9e8de9ca761b631f7c8f67c4e5f5dea817dd6..b5b900d4fe4f9d6399591bd476d97aeaf455cf66 100644 (file)
@@ -1,6 +1,6 @@
 /* crypto/evp/evp_err.c */
 /* ====================================================================
- * Copyright (c) 1999-2005 The OpenSSL Project.  All rights reserved.
+ * Copyright (c) 1999-2007 The OpenSSL Project.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 static ERR_STRING_DATA EVP_str_functs[]=
        {
 {ERR_FUNC(EVP_F_AES_INIT_KEY), "AES_INIT_KEY"},
+{ERR_FUNC(EVP_F_ALG_MODULE_INIT),      "ALG_MODULE_INIT"},
 {ERR_FUNC(EVP_F_CAMELLIA_INIT_KEY),    "CAMELLIA_INIT_KEY"},
 {ERR_FUNC(EVP_F_D2I_PKEY),     "D2I_PKEY"},
+{ERR_FUNC(EVP_F_DO_EVP_ENC_ENGINE),    "DO_EVP_ENC_ENGINE"},
+{ERR_FUNC(EVP_F_DO_EVP_ENC_ENGINE_FULL),       "DO_EVP_ENC_ENGINE_FULL"},
+{ERR_FUNC(EVP_F_DO_EVP_MD_ENGINE),     "DO_EVP_MD_ENGINE"},
+{ERR_FUNC(EVP_F_DO_EVP_MD_ENGINE_FULL),        "DO_EVP_MD_ENGINE_FULL"},
 {ERR_FUNC(EVP_F_DSAPKEY2PKCS8),        "DSAPKEY2PKCS8"},
 {ERR_FUNC(EVP_F_DSA_PKEY2PKCS8),       "DSA_PKEY2PKCS8"},
 {ERR_FUNC(EVP_F_ECDSA_PKEY2PKCS8),     "ECDSA_PKEY2PKCS8"},
 {ERR_FUNC(EVP_F_ECKEY_PKEY2PKCS8),     "ECKEY_PKEY2PKCS8"},
+{ERR_FUNC(EVP_F_EVP_CIPHERINIT),       "EVP_CipherInit"},
 {ERR_FUNC(EVP_F_EVP_CIPHERINIT_EX),    "EVP_CipherInit_ex"},
 {ERR_FUNC(EVP_F_EVP_CIPHER_CTX_CTRL),  "EVP_CIPHER_CTX_ctrl"},
 {ERR_FUNC(EVP_F_EVP_CIPHER_CTX_SET_KEY_LENGTH),        "EVP_CIPHER_CTX_set_key_length"},
 {ERR_FUNC(EVP_F_EVP_DECRYPTFINAL_EX),  "EVP_DecryptFinal_ex"},
+{ERR_FUNC(EVP_F_EVP_DIGESTINIT),       "EVP_DigestInit"},
 {ERR_FUNC(EVP_F_EVP_DIGESTINIT_EX),    "EVP_DigestInit_ex"},
 {ERR_FUNC(EVP_F_EVP_ENCRYPTFINAL_EX),  "EVP_EncryptFinal_ex"},
 {ERR_FUNC(EVP_F_EVP_MD_CTX_COPY_EX),   "EVP_MD_CTX_copy_ex"},
@@ -125,15 +132,20 @@ static ERR_STRING_DATA EVP_str_reasons[]=
 {ERR_REASON(EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH),"data not multiple of block length"},
 {ERR_REASON(EVP_R_DECODE_ERROR)          ,"decode error"},
 {ERR_REASON(EVP_R_DIFFERENT_KEY_TYPES)   ,"different key types"},
+{ERR_REASON(EVP_R_DISABLED_FOR_FIPS)     ,"disabled for fips"},
 {ERR_REASON(EVP_R_ENCODE_ERROR)          ,"encode error"},
+{ERR_REASON(EVP_R_ERROR_LOADING_SECTION) ,"error loading section"},
+{ERR_REASON(EVP_R_ERROR_SETTING_FIPS_MODE),"error setting fips mode"},
 {ERR_REASON(EVP_R_EVP_PBE_CIPHERINIT_ERROR),"evp pbe cipherinit error"},
 {ERR_REASON(EVP_R_EXPECTING_AN_RSA_KEY)  ,"expecting an rsa key"},
 {ERR_REASON(EVP_R_EXPECTING_A_DH_KEY)    ,"expecting a dh key"},
 {ERR_REASON(EVP_R_EXPECTING_A_DSA_KEY)   ,"expecting a dsa key"},
 {ERR_REASON(EVP_R_EXPECTING_A_ECDSA_KEY) ,"expecting a ecdsa key"},
 {ERR_REASON(EVP_R_EXPECTING_A_EC_KEY)    ,"expecting a ec key"},
+{ERR_REASON(EVP_R_FIPS_MODE_NOT_SUPPORTED),"fips mode not supported"},
 {ERR_REASON(EVP_R_INITIALIZATION_ERROR)  ,"initialization error"},
 {ERR_REASON(EVP_R_INPUT_NOT_INITIALIZED) ,"input not initialized"},
+{ERR_REASON(EVP_R_INVALID_FIPS_MODE)     ,"invalid fips mode"},
 {ERR_REASON(EVP_R_INVALID_KEY_LENGTH)    ,"invalid key length"},
 {ERR_REASON(EVP_R_IV_TOO_LARGE)          ,"iv too large"},
 {ERR_REASON(EVP_R_KEYGEN_FAILURE)        ,"keygen failure"},
@@ -145,6 +157,8 @@ static ERR_STRING_DATA EVP_str_reasons[]=
 {ERR_REASON(EVP_R_NO_VERIFY_FUNCTION_CONFIGURED),"no verify function configured"},
 {ERR_REASON(EVP_R_PKCS8_UNKNOWN_BROKEN_TYPE),"pkcs8 unknown broken type"},
 {ERR_REASON(EVP_R_PUBLIC_KEY_NOT_RSA)    ,"public key not rsa"},
+{ERR_REASON(EVP_R_SEED_KEY_SETUP_FAILED) ,"seed key setup failed"},
+{ERR_REASON(EVP_R_UNKNOWN_OPTION)        ,"unknown option"},
 {ERR_REASON(EVP_R_UNKNOWN_PBE_ALGORITHM) ,"unknown pbe algorithm"},
 {ERR_REASON(EVP_R_UNSUPORTED_NUMBER_OF_ROUNDS),"unsuported number of rounds"},
 {ERR_REASON(EVP_R_UNSUPPORTED_CIPHER)    ,"unsupported cipher"},
index edb28ef38ed7b44ae6cb9c26f1b7aa3c3aa989ff..174cf6c5942f5e5f9d7a3aaebe8405a10daf3a9e 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);
@@ -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);
@@ -178,11 +182,6 @@ int EVP_CIPHER_CTX_block_size(const EVP_CIPHER_CTX *ctx)
        return ctx->cipher->block_size;
        }
 
-int EVP_Cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, unsigned int inl)
-       {
-       return ctx->cipher->do_cipher(ctx,out,in,inl);
-       }
-
 const EVP_CIPHER *EVP_CIPHER_CTX_cipher(const EVP_CIPHER_CTX *ctx)
        {
        return ctx->cipher;
@@ -193,11 +192,6 @@ unsigned long EVP_CIPHER_flags(const EVP_CIPHER *cipher)
        return cipher->flags;
        }
 
-unsigned long EVP_CIPHER_CTX_flags(const EVP_CIPHER_CTX *ctx)
-       {
-       return ctx->cipher->flags;
-       }
-
 void *EVP_CIPHER_CTX_get_app_data(const EVP_CIPHER_CTX *ctx)
        {
        return ctx->app_data;
@@ -213,11 +207,6 @@ int EVP_CIPHER_iv_length(const EVP_CIPHER *cipher)
        return cipher->iv_len;
        }
 
-int EVP_CIPHER_CTX_iv_length(const EVP_CIPHER_CTX *ctx)
-       {
-       return ctx->cipher->iv_len;
-       }
-
 int EVP_CIPHER_key_length(const EVP_CIPHER *cipher)
        {
        return cipher->key_len;
@@ -228,11 +217,6 @@ int EVP_CIPHER_CTX_key_length(const EVP_CIPHER_CTX *ctx)
        return ctx->key_len;
        }
 
-int EVP_CIPHER_nid(const EVP_CIPHER *cipher)
-       {
-       return cipher->nid;
-       }
-
 int EVP_CIPHER_CTX_nid(const EVP_CIPHER_CTX *ctx)
        {
        return ctx->cipher->nid;
@@ -277,3 +261,18 @@ int EVP_MD_CTX_test_flags(const EVP_MD_CTX *ctx, int flags)
        {
        return (ctx->flags & flags);
        }
+
+void EVP_CIPHER_CTX_set_flags(EVP_CIPHER_CTX *ctx, int flags)
+       {
+       ctx->flags |= flags;
+       }
+
+void EVP_CIPHER_CTX_clear_flags(EVP_CIPHER_CTX *ctx, int flags)
+       {
+       ctx->flags &= ~flags;
+       }
+
+int EVP_CIPHER_CTX_test_flags(const EVP_CIPHER_CTX *ctx, int flags)
+       {
+       return (ctx->flags & flags);
+       }
index 073b0adcffea4e230c9f8fdf021a387f6a54cdff..a59c4c1a612396ed62cb66e00379c67313e31319 100644 (file)
@@ -92,7 +92,7 @@ static int cname##_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const uns
 #define BLOCK_CIPHER_func_cfb(cname, cprefix, cbits, kstruct, ksched) \
 static int cname##_cfb##cbits##_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, unsigned int inl) \
 {\
-       cprefix##_cfb##cbits##_encrypt(in, out, (long)(cbits==1?inl*8:inl), &((kstruct *)ctx->cipher_data)->ksched, ctx->iv, &ctx->num, ctx->encrypt);\
+       cprefix##_cfb##cbits##_encrypt(in, out, (long)((cbits==1) && !(ctx->flags & EVP_CIPH_FLAG_LENGTH_BITS) ?inl*8:inl), &((kstruct *)ctx->cipher_data)->ksched, ctx->iv, &ctx->num, ctx->encrypt);\
        return 1;\
 }
 
@@ -226,11 +226,26 @@ 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)
+
+#ifdef OPENSSL_FIPS
+#define RC2_set_key    private_RC2_set_key
+#define RC4_set_key    private_RC4_set_key
+#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
+#define MD2_Init       private_MD2_Init
+#define MDC2_Init      private_MDC2_Init
+#define SHA_Init       private_SHA_Init
+
+#endif
+
index a948c77fa497a2bf8fc35f574ea333c1fbd0cd9f..6b0c0aa7a3f5dee6c210823b73ceec7567fc36e9 100644 (file)
@@ -81,7 +81,7 @@ static const EVP_MD dsa_md=
        NID_dsaWithSHA,
        NID_dsaWithSHA,
        SHA_DIGEST_LENGTH,
-       0,
+       EVP_MD_FLAG_FIPS,
        init,
        update,
        final,
index c12e13972b501d98cd35456733ce3915ad000e3a..da8babc147dd6010b9c6daaf6bc29c86713e6804 100644 (file)
@@ -68,6 +68,8 @@
 #include <openssl/dsa.h>
 #endif
 
+#ifndef OPENSSL_FIPS
+
 static int init(EVP_MD_CTX *ctx)
        { return SHA1_Init(ctx->md_data); }
 
@@ -98,3 +100,4 @@ const EVP_MD *EVP_dss1(void)
        return(&dss1_md);
        }
 #endif
+#endif
index 5ce849f161dde283fa899d4a4a02f3538e486d94..8eee6236ba25cad34e57aa0f6c6a8bcb2f6a7a48 100644 (file)
@@ -58,6 +58,7 @@
 
 #include <stdio.h>
 #include "cryptlib.h"
+#include "evp_locl.h"
 
 #ifndef OPENSSL_NO_MD2
 
index 1e0b7c5b424ef615516110bae37ee89d4c654cab..5cd2ab5adeef5ba420f892ad8f89f5d993ae7114 100644 (file)
@@ -58,6 +58,7 @@
 
 #include <stdio.h>
 #include "cryptlib.h"
+#include "evp_locl.h"
 
 #ifndef OPENSSL_NO_MD4
 
index 63c142119ebd76f6b06f0416f62e4b3efabc902e..6455829671ef6c632d351858619f264635730c5a 100644 (file)
@@ -62,6 +62,7 @@
 #ifndef OPENSSL_NO_MD5
 
 #include <openssl/evp.h>
+#include "evp_locl.h"
 #include <openssl/objects.h>
 #include <openssl/x509.h>
 #include <openssl/md5.h>
index 36c4e9b1343688d7f5b10b3ee50e90d37b0bc8ae..9f9bcf06ed2d126cfbc03bad5c5dff45bc0a3437 100644 (file)
@@ -58,6 +58,7 @@
 
 #include <stdio.h>
 #include "cryptlib.h"
+#include "evp_locl.h"
 
 #ifndef OPENSSL_NO_MDC2
 
index acccc8f92d8e13b9cd5d50f45780f64ccc145470..3f30dfc579ca4d0f4406465165354045e4e2f624 100644 (file)
@@ -58,6 +58,7 @@
 
 #include <stdio.h>
 #include "cryptlib.h"
+#include "evp_locl.h"
 
 #if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA0)
 
index 4679b1c4638c18d1e0d8c6edc8c1d86f14fff28d..471ec30be0139dd846c9ab2888002b4eb1efc371 100644 (file)
@@ -68,6 +68,8 @@
 #include <openssl/rsa.h>
 #endif
 
+#ifndef OPENSSL_FIPS
+
 static int init(EVP_MD_CTX *ctx)
        { return SHA1_Init(ctx->md_data); }
 
@@ -97,7 +99,6 @@ const EVP_MD *EVP_sha1(void)
        {
        return(&sha1_md);
        }
-#endif
 
 #ifndef OPENSSL_NO_SHA256
 static int init224(EVP_MD_CTX *ctx)
@@ -202,3 +203,7 @@ static const EVP_MD sha512_md=
 const EVP_MD *EVP_sha512(void)
        { return(&sha512_md); }
 #endif /* ifndef OPENSSL_NO_SHA512 */
+
+#endif
+
+#endif
index 88c1e780dd7694c325730ef76720868beff338c1..e2e04c3570f461ae5e941db3de4db91a702310dd 100644 (file)
@@ -66,6 +66,10 @@ int EVP_add_cipher(const EVP_CIPHER *c)
        {
        int r;
 
+#ifdef OPENSSL_FIPS
+       OPENSSL_init();
+#endif
+
        r=OBJ_NAME_add(OBJ_nid2sn(c->nid),OBJ_NAME_TYPE_CIPHER_METH,(const char *)c);
        if (r == 0) return(0);
        r=OBJ_NAME_add(OBJ_nid2ln(c->nid),OBJ_NAME_TYPE_CIPHER_METH,(const char *)c);
@@ -77,6 +81,9 @@ int EVP_add_digest(const EVP_MD *md)
        int r;
        const char *name;
 
+#ifdef OPENSSL_FIPS
+       OPENSSL_init();
+#endif
        name=OBJ_nid2sn(md->type);
        r=OBJ_NAME_add(name,OBJ_NAME_TYPE_MD_METH,(const char *)md);
        if (r == 0) return(0);
index e4ae5906f5578238654dcdf940d150da994f1411..bf41a0db68ad1af405fcfd332b837b05a9130c6a 100644 (file)
@@ -84,10 +84,6 @@ int EVP_SignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, unsigned int *siglen,
        MS_STATIC EVP_MD_CTX tmp_ctx;
 
        *siglen=0;
-       EVP_MD_CTX_init(&tmp_ctx);
-       EVP_MD_CTX_copy_ex(&tmp_ctx,ctx);   
-       EVP_DigestFinal_ex(&tmp_ctx,&(m[0]),&m_len);
-       EVP_MD_CTX_cleanup(&tmp_ctx);
        for (i=0; i<4; i++)
                {
                v=ctx->digest->required_pkey_type[i];
@@ -108,7 +104,23 @@ int EVP_SignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, unsigned int *siglen,
                EVPerr(EVP_F_EVP_SIGNFINAL,EVP_R_NO_SIGN_FUNCTION_CONFIGURED);
                return(0);
                }
-       return(ctx->digest->sign(ctx->digest->type,m,m_len,sigret,siglen,
-               pkey->pkey.ptr));
+       EVP_MD_CTX_init(&tmp_ctx);
+       EVP_MD_CTX_copy_ex(&tmp_ctx,ctx);
+       if (ctx->digest->flags & EVP_MD_FLAG_SVCTX)
+               {
+               EVP_MD_SVCTX sctmp;
+               sctmp.mctx = &tmp_ctx;
+               sctmp.key = pkey->pkey.ptr;
+               i = ctx->digest->sign(ctx->digest->type,
+                       NULL, -1, sigret, siglen, &sctmp);
+               }
+       else
+               {
+               EVP_DigestFinal_ex(&tmp_ctx,&(m[0]),&m_len);
+               i = ctx->digest->sign(ctx->digest->type,m,m_len,sigret,siglen,
+                                       pkey->pkey.ptr);
+               }
+       EVP_MD_CTX_cleanup(&tmp_ctx);
+       return i;
        }
 
index 21a40a375e1b71b6e3a2c17bd0a8ee840cde1ec2..2d46dffe7e1a4d6905620a570fb333f896be85f6 100644 (file)
@@ -85,17 +85,29 @@ int EVP_VerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sigbuf,
                EVPerr(EVP_F_EVP_VERIFYFINAL,EVP_R_WRONG_PUBLIC_KEY_TYPE);
                return(-1);
                }
-       EVP_MD_CTX_init(&tmp_ctx);
-       EVP_MD_CTX_copy_ex(&tmp_ctx,ctx);     
-       EVP_DigestFinal_ex(&tmp_ctx,&(m[0]),&m_len);
-       EVP_MD_CTX_cleanup(&tmp_ctx);
-        if (ctx->digest->verify == NULL)
+       if (ctx->digest->verify == NULL)
                 {
                EVPerr(EVP_F_EVP_VERIFYFINAL,EVP_R_NO_VERIFY_FUNCTION_CONFIGURED);
                return(0);
                }
 
-       return(ctx->digest->verify(ctx->digest->type,m,m_len,
-               sigbuf,siglen,pkey->pkey.ptr));
+       EVP_MD_CTX_init(&tmp_ctx);
+       EVP_MD_CTX_copy_ex(&tmp_ctx,ctx);     
+       if (ctx->digest->flags & EVP_MD_FLAG_SVCTX)
+               {
+               EVP_MD_SVCTX sctmp;
+               sctmp.mctx = &tmp_ctx;
+               sctmp.key = pkey->pkey.ptr;
+               i = ctx->digest->verify(ctx->digest->type,
+                       NULL, -1, sigbuf, siglen, &sctmp);
+               }
+       else
+               {
+               EVP_DigestFinal_ex(&tmp_ctx,&(m[0]),&m_len);
+               i = ctx->digest->verify(ctx->digest->type,m,m_len,
+                                       sigbuf,siglen,pkey->pkey.ptr);
+               }
+       EVP_MD_CTX_cleanup(&tmp_ctx);
+       return i;
        }