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.
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 \
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)
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
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
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
#include "cryptlib.h"
#include <openssl/objects.h>
#include <openssl/evp.h>
+#include <openssl/engine.h>
void EVP_MD_CTX_init(EVP_MD_CTX *ctx)
{
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)
if (type->ctx_size)
ctx->md_data=OPENSSL_malloc(type->ctx_size);
}
+skip_to_init:
return type->init(ctx);
}
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);
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;
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 */;
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 */
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);
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);
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);
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);
/* 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. */
#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
#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
}
#endif
#endif
-
#include "cryptlib.h"
#include <openssl/evp.h>
#include <openssl/err.h>
+#include <openssl/engine.h>
#include "evp_locl.h"
#include <assert.h>
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
{
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,
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;
}
{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"},
{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"},
OpenSSL_add_all_digests();
/* Load all compiled-in ENGINEs */
ENGINE_load_builtin_engines();
+ /* Register all available ENGINE implementations of ciphers and digests.
+ * This could perhaps be changed to "ENGINE_register_all_complete()"? */
+ ENGINE_register_all_ciphers();
+ ENGINE_register_all_digests();
+ /* If we add command-line options, this statement should be switchable.
+ * It'll prevent ENGINEs being ENGINE_init()ialised for cipher/digest use if
+ * they weren't already initialised. */
+ /* ENGINE_set_cipher_flags(ENGINE_CIPHER_FLAG_NOINIT); */
for( ; ; )
{
#include <openssl/rsa.h>
#include "evp_locl.h"
+/* This stuff should now all be supported through
+ * crypto/engine/hw_openbsd_dev_crypto.c unless I botched it up */
+static void *dummy=&dummy;
+
+#if 0
+
/* check flag after OpenSSL headers to ensure make depend works */
#ifdef OPENSSL_OPENBSD_DEV_CRYPTO
{ return &md5_md; }
#endif
+#endif