Merge EVP changes in from FIPS branch.

This commit is contained in:
Dr. Stephen Henson
2008-09-15 22:21:42 +00:00
parent 16349eeceb
commit a2dc9b6be2
27 changed files with 1127 additions and 312 deletions

View 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 \

View 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;
break;
case BIO_C_SET_MD_CTX:
if (b->init)

180
crypto/evp/dig_eng.c Normal file
View File

@@ -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

View File

@@ -116,6 +116,7 @@
#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;
@@ -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);

View 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)

View 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)

View 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,

View 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,

View 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

390
crypto/evp/enc_min.c Normal file
View File

@@ -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;
}

View File

@@ -75,6 +75,10 @@
#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

125
crypto/evp/evp_cnf.c Normal file
View File

@@ -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);
}

View File

@@ -66,13 +66,15 @@
#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;
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

View 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
@@ -71,16 +71,23 @@
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"},

View 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);
}

View 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

View 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,

View 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

View File

@@ -58,6 +58,7 @@
#include <stdio.h>
#include "cryptlib.h"
#include "evp_locl.h"
#ifndef OPENSSL_NO_MD2

View File

@@ -58,6 +58,7 @@
#include <stdio.h>
#include "cryptlib.h"
#include "evp_locl.h"
#ifndef OPENSSL_NO_MD4

View 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>

View File

@@ -58,6 +58,7 @@
#include <stdio.h>
#include "cryptlib.h"
#include "evp_locl.h"
#ifndef OPENSSL_NO_MDC2

View File

@@ -58,6 +58,7 @@
#include <stdio.h>
#include "cryptlib.h"
#include "evp_locl.h"
#if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA0)

View 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

View 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);

View 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;
}

View 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)
{
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;
}