Commit 11a57c7b authored by Geoff Thorpe's avatar Geoff Thorpe
Browse files

This changes EVP's cipher and digest code to hook via the ENGINE support.

See crypto/engine/README for details.

- it also removes openbsd_hw.c from the build (that functionality is
  going to be available in the openbsd ENGINE in a upcoming commit)

- evp_test has had the extra initialisation added so it will use (if
  possible) any ENGINEs supporting the algorithms required.
parent b370230b
Loading
Loading
Loading
Loading
+21 −24
Original line number Diff line number Diff line
@@ -32,7 +32,7 @@ LIBSRC= encode.c digest.c evp_enc.c evp_key.c \
	p_open.c p_seal.c p_sign.c p_verify.c p_lib.c p_enc.c p_dec.c \
	bio_md.c bio_b64.c bio_enc.c evp_err.c e_null.c \
	c_all.c c_allc.c c_alld.c evp_lib.c bio_ok.c \
	evp_pkey.c evp_pbe.c p5_crpt.c p5_crpt2.c openbsd_hw.c
	evp_pkey.c evp_pbe.c p5_crpt.c p5_crpt2.c

LIBOBJ=	encode.o digest.o evp_enc.o evp_key.o \
	e_des.o e_bf.o e_idea.o e_des3.o \
@@ -43,7 +43,7 @@ LIBOBJ= encode.o digest.o evp_enc.o evp_key.o \
	p_open.o p_seal.o p_sign.o p_verify.o p_lib.o p_enc.o p_dec.o \
	bio_md.o bio_b64.o bio_enc.o evp_err.o e_null.o \
	c_all.o c_allc.o c_alld.o evp_lib.o bio_ok.o \
	evp_pkey.o evp_pbe.o p5_crpt.o p5_crpt2.o openbsd_hw.o
	evp_pkey.o evp_pbe.o p5_crpt.o p5_crpt2.o

SRC= $(LIBSRC)

@@ -174,13 +174,16 @@ c_alld.o: ../../include/openssl/types.h ../../include/openssl/x509.h
c_alld.o: ../../include/openssl/x509_vfy.h ../cryptlib.h c_alld.c
digest.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
digest.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
digest.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
digest.o: ../../include/openssl/err.h ../../include/openssl/evp.h
digest.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
digest.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
digest.o: ../../include/openssl/opensslv.h ../../include/openssl/safestack.h
digest.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
digest.o: ../../include/openssl/types.h ../cryptlib.h digest.c
digest.o: ../../include/openssl/crypto.h ../../include/openssl/dh.h
digest.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
digest.o: ../../include/openssl/engine.h ../../include/openssl/err.h
digest.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
digest.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
digest.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
digest.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h
digest.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
digest.o: ../../include/openssl/symhacks.h ../../include/openssl/types.h
digest.o: ../../include/openssl/ui.h ../cryptlib.h digest.c
e_aes.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
e_aes.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
e_aes.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
@@ -301,12 +304,15 @@ encode.o: ../../include/openssl/types.h ../cryptlib.h encode.c
evp_enc.o: ../../e_os.h ../../include/openssl/asn1.h
evp_enc.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
evp_enc.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
evp_enc.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
evp_enc.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
evp_enc.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
evp_enc.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
evp_enc.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
evp_enc.o: ../../include/openssl/symhacks.h ../../include/openssl/types.h
evp_enc.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h
evp_enc.o: ../../include/openssl/e_os2.h ../../include/openssl/engine.h
evp_enc.o: ../../include/openssl/err.h ../../include/openssl/evp.h
evp_enc.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
evp_enc.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
evp_enc.o: ../../include/openssl/opensslv.h ../../include/openssl/rand.h
evp_enc.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
evp_enc.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
evp_enc.o: ../../include/openssl/types.h ../../include/openssl/ui.h
evp_enc.o: ../cryptlib.h evp_enc.c evp_locl.h
evp_err.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
evp_err.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
@@ -513,15 +519,6 @@ names.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
names.o: ../../include/openssl/symhacks.h ../../include/openssl/types.h
names.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
names.o: ../cryptlib.h names.c
openbsd_hw.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
openbsd_hw.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
openbsd_hw.o: ../../include/openssl/e_os2.h ../../include/openssl/evp.h
openbsd_hw.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
openbsd_hw.o: ../../include/openssl/opensslconf.h
openbsd_hw.o: ../../include/openssl/opensslv.h ../../include/openssl/rsa.h
openbsd_hw.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
openbsd_hw.o: ../../include/openssl/symhacks.h ../../include/openssl/types.h
openbsd_hw.o: evp_locl.h openbsd_hw.c
p5_crpt.o: ../../e_os.h ../../include/openssl/asn1.h
p5_crpt.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
p5_crpt.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+58 −0
Original line number Diff line number Diff line
@@ -113,6 +113,7 @@
#include "cryptlib.h"
#include <openssl/objects.h>
#include <openssl/evp.h>
#include <openssl/engine.h>

void EVP_MD_CTX_init(EVP_MD_CTX *ctx)
	{
@@ -130,6 +131,52 @@ EVP_MD_CTX *EVP_MD_CTX_create(void)

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)
	{
	/* 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)
		{
		/* 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)
			/* Ask if an ENGINE is reserved for this job */
			impl = ENGINE_get_digest_engine(type->type);
		if(impl)
			{
			/* There's an ENGINE for this job ... (apparently) */
			const EVP_MD *d = ENGINE_get_digest(impl, type->type);
			if(!d)
				{
				/* Same comment from evp_enc.c */
				EVPerr(EVP_F_EVP_DIGESTINIT, EVP_R_INITIALIZATION_ERROR);
				return 0;
				}
			/* We'll use the ENGINE's private digest definition */
			type = 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_EVP_DIGESTINIT, EVP_R_NO_DIGEST_SET);
		return 0;
		}
	if (ctx->digest != type)
		{
		if (ctx->digest && ctx->digest->ctx_size)
@@ -138,6 +185,7 @@ int EVP_DigestInit(EVP_MD_CTX *ctx, const EVP_MD *type)
		if (type->ctx_size)
			ctx->md_data=OPENSSL_malloc(type->ctx_size);
		}
skip_to_init:
	return type->init(ctx);
	}

@@ -166,6 +214,12 @@ int EVP_MD_CTX_copy(EVP_MD_CTX *out, const EVP_MD_CTX *in)
		EVPerr(EVP_F_EVP_MD_CTX_COPY,EVP_R_INPUT_NOT_INITIALIZED);
		return 0;
		}
	/* Make sure it's safe to copy a digest context using an ENGINE */
	if (in->engine && !ENGINE_init(in->engine))
		{
		EVPerr(EVP_F_EVP_MD_CTX_COPY,ERR_R_ENGINE_LIB);
		return 0;
		}

	EVP_MD_CTX_cleanup(out);
	memcpy(out,in,sizeof *out);
@@ -217,6 +271,10 @@ int EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx)
		memset(ctx->md_data,0,ctx->digest->ctx_size);
		OPENSSL_free(ctx->md_data);
		}
	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);
	memset(ctx,'\0',sizeof *ctx);

	return 1;
+17 −1
Original line number Diff line number Diff line
@@ -262,6 +262,7 @@ struct env_md_st
struct env_md_ctx_st
	{
	const EVP_MD *digest;
	ENGINE *engine; /* functional reference if 'digest' is ENGINE-provided */
	unsigned long flags;
	void *md_data;
	} /* EVP_MD_CTX */;
@@ -331,6 +332,7 @@ typedef struct evp_cipher_info_st
struct evp_cipher_ctx_st
	{
	const EVP_CIPHER *cipher;
	ENGINE *engine;	/* functional reference if 'cipher' is ENGINE-provided */
	int encrypt;		/* encrypt or decrypt */
	int buf_len;		/* number we have left */

@@ -456,6 +458,7 @@ void EVP_MD_CTX_destroy(EVP_MD_CTX *ctx);
int     EVP_MD_CTX_copy(EVP_MD_CTX *out,const EVP_MD_CTX *in);  
#define EVP_MD_CTX_set_flags(ctx,flgs) ((ctx)->flags|=(flgs))
int	EVP_DigestInit(EVP_MD_CTX *ctx, const EVP_MD *type);
int	EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl);
int	EVP_DigestUpdate(EVP_MD_CTX *ctx,const void *d,
			 unsigned int cnt);
int	EVP_DigestFinal(EVP_MD_CTX *ctx,unsigned char *md,unsigned int *s);
@@ -472,12 +475,16 @@ int EVP_BytesToKey(const EVP_CIPHER *type,const EVP_MD *md,

int	EVP_EncryptInit(EVP_CIPHER_CTX *ctx,const EVP_CIPHER *type,
		const unsigned char *key, const unsigned char *iv);
int	EVP_EncryptInit_ex(EVP_CIPHER_CTX *ctx,const EVP_CIPHER *type, ENGINE *impl,
		const unsigned char *key, const unsigned char *iv);
int	EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out,
		int *outl, const unsigned char *in, int inl);
int	EVP_EncryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl);

int	EVP_DecryptInit(EVP_CIPHER_CTX *ctx,const EVP_CIPHER *type,
		const unsigned char *key, const unsigned char *iv);
int	EVP_DecryptInit_ex(EVP_CIPHER_CTX *ctx,const EVP_CIPHER *type, ENGINE *impl,
		const unsigned char *key, const unsigned char *iv);
int	EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out,
		int *outl, const unsigned char *in, int inl);
int	EVP_DecryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *outm, int *outl);
@@ -485,6 +492,9 @@ int EVP_DecryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *outm, int *outl);
int	EVP_CipherInit(EVP_CIPHER_CTX *ctx,const EVP_CIPHER *type,
		       const unsigned char *key,const unsigned char *iv,
		       int enc);
int	EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx,const EVP_CIPHER *type, ENGINE *impl,
		       const unsigned char *key,const unsigned char *iv,
		       int enc);
int	EVP_CipherUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out,
		int *outl, const unsigned char *in, int inl);
int	EVP_CipherFinal(EVP_CIPHER_CTX *ctx, unsigned char *outm, int *outl);
@@ -570,12 +580,16 @@ const EVP_CIPHER *EVP_des_cbc(void);
const EVP_CIPHER *EVP_des_ede_cbc(void);
const EVP_CIPHER *EVP_des_ede3_cbc(void);
const EVP_CIPHER *EVP_desx_cbc(void);
/* This should now be supported through the dev_crypto ENGINE. But also, why are
 * rc4 and md5 declarations made here inside a "NO_DES" precompiler branch? */
#if 0
# ifdef OPENSSL_OPENBSD_DEV_CRYPTO
const EVP_CIPHER *EVP_dev_crypto_des_ede3_cbc(void);
const EVP_CIPHER *EVP_dev_crypto_rc4(void);
const EVP_MD *EVP_dev_crypto_md5(void);
# endif
#endif
#endif
#ifndef OPENSSL_NO_RC4
const EVP_CIPHER *EVP_rc4(void);
const EVP_CIPHER *EVP_rc4_40(void);
@@ -711,6 +725,7 @@ void EVP_PBE_cleanup(void);
/* 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.
 */
void ERR_load_EVP_strings(void);

/* Error codes for the EVP functions. */

@@ -720,6 +735,7 @@ void EVP_PBE_cleanup(void);
#define EVP_F_EVP_CIPHER_CTX_CTRL			 124
#define EVP_F_EVP_CIPHER_CTX_SET_KEY_LENGTH		 122
#define EVP_F_EVP_DECRYPTFINAL				 101
#define EVP_F_EVP_DIGESTINIT				 128
#define EVP_F_EVP_ENCRYPTFINAL				 127
#define EVP_F_EVP_MD_CTX_COPY				 110
#define EVP_F_EVP_OPENINIT				 102
@@ -767,6 +783,7 @@ void EVP_PBE_cleanup(void);
#define EVP_R_KEYGEN_FAILURE				 120
#define EVP_R_MISSING_PARAMETERS			 103
#define EVP_R_NO_CIPHER_SET				 131
#define EVP_R_NO_DIGEST_SET				 139
#define EVP_R_NO_DSA_PARAMETERS				 116
#define EVP_R_NO_SIGN_FUNCTION_CONFIGURED		 104
#define EVP_R_NO_VERIFY_FUNCTION_CONFIGURED		 105
@@ -788,4 +805,3 @@ void EVP_PBE_cleanup(void);
}
#endif
#endif
+57 −6
Original line number Diff line number Diff line
@@ -60,6 +60,7 @@
#include "cryptlib.h"
#include <openssl/evp.h>
#include <openssl/err.h>
#include <openssl/engine.h>
#include "evp_locl.h"

#include <assert.h>
@@ -75,24 +76,70 @@ void EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *ctx)
int EVP_CipherInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
	     const unsigned char *key, const unsigned char *iv, int enc)
	{
	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 && (enc != -1)) enc = 1;
	/* 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;
	if (cipher)
		{
		/* Ensure an ENGINE 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). */
		if(ctx->engine)
			ENGINE_finish(ctx->engine);
		if(!impl)
			/* 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, 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;
		ctx->cipher=cipher;
		ctx->cipher_data=OPENSSL_malloc(ctx->cipher->ctx_size);
		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)) {
		if(ctx->cipher->flags & EVP_CIPH_CTRL_INIT)
			{
			if(!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_INIT, 0, NULL))
				{
				EVPerr(EVP_F_EVP_CIPHERINIT, EVP_R_INITIALIZATION_ERROR);
				return 0;
				}
			}
	} else if(!ctx->cipher) {
		}
	else if(!ctx->cipher)
		{
		EVPerr(EVP_F_EVP_CIPHERINIT, EVP_R_NO_CIPHER_SET);
		return 0;
		}

skip_to_init:
	/* we assume block size is a power of 2 in *cryptUpdate */
	assert(ctx->cipher->block_size == 1
	       || ctx->cipher->block_size == 8
@@ -144,7 +191,7 @@ int EVP_CipherFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
	{
	if (ctx->encrypt)
		return EVP_EncryptFinal(ctx,out,outl);
	else	return(EVP_DecryptFinal(ctx,out,outl));
	else	return EVP_DecryptFinal(ctx,out,outl);
	}

int EVP_EncryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
@@ -355,6 +402,10 @@ int EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *c)
		if(!c->cipher->cleanup(c)) return 0;
		}
	OPENSSL_free(c->cipher_data);
	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);
	memset(c,0,sizeof(EVP_CIPHER_CTX));
	return 1;
	}
+2 −0
Original line number Diff line number Diff line
@@ -71,6 +71,7 @@ static ERR_STRING_DATA EVP_str_functs[]=
{ERR_PACK(0,EVP_F_EVP_CIPHER_CTX_CTRL,0),	"EVP_CIPHER_CTX_ctrl"},
{ERR_PACK(0,EVP_F_EVP_CIPHER_CTX_SET_KEY_LENGTH,0),	"EVP_CIPHER_CTX_set_key_length"},
{ERR_PACK(0,EVP_F_EVP_DECRYPTFINAL,0),	"EVP_DecryptFinal"},
{ERR_PACK(0,EVP_F_EVP_DIGESTINIT,0),	"EVP_DigestInit"},
{ERR_PACK(0,EVP_F_EVP_ENCRYPTFINAL,0),	"EVP_EncryptFinal"},
{ERR_PACK(0,EVP_F_EVP_MD_CTX_COPY,0),	"EVP_MD_CTX_copy"},
{ERR_PACK(0,EVP_F_EVP_OPENINIT,0),	"EVP_OpenInit"},
@@ -121,6 +122,7 @@ static ERR_STRING_DATA EVP_str_reasons[]=
{EVP_R_KEYGEN_FAILURE                    ,"keygen failure"},
{EVP_R_MISSING_PARAMETERS                ,"missing parameters"},
{EVP_R_NO_CIPHER_SET                     ,"no cipher set"},
{EVP_R_NO_DIGEST_SET                     ,"no digest set"},
{EVP_R_NO_DSA_PARAMETERS                 ,"no dsa parameters"},
{EVP_R_NO_SIGN_FUNCTION_CONFIGURED       ,"no sign function configured"},
{EVP_R_NO_VERIFY_FUNCTION_CONFIGURED     ,"no verify function configured"},
Loading