summaryrefslogtreecommitdiff
path: root/crypto
diff options
context:
space:
mode:
authorRichard Levitte <levitte@openssl.org>2000-10-26 21:07:28 +0000
committerRichard Levitte <levitte@openssl.org>2000-10-26 21:07:28 +0000
commit5270e7025e11b2fd1a5bdf8d81feded1167b1c87 (patch)
tree3bb44c37f4bb6469f738a10127050b023e0d7fb5 /crypto
parent1df586bec20de86c3086181c565aaee7629bb0a2 (diff)
downloadopenssl-new-5270e7025e11b2fd1a5bdf8d81feded1167b1c87.tar.gz
Merge the engine branch into the main trunk. All conflicts resolved.
At the same time, add VMS support for Rijndael.
Diffstat (limited to 'crypto')
-rw-r--r--crypto/Makefile.ssl2
-rw-r--r--crypto/bn/bn_exp.c205
-rw-r--r--crypto/cryptlib.c3
-rw-r--r--crypto/crypto-lib.com15
-rw-r--r--crypto/crypto.h3
-rw-r--r--crypto/dh/Makefile.ssl50
-rw-r--r--crypto/dh/dh.h13
-rw-r--r--crypto/dh/dh_key.c13
-rw-r--r--crypto/dh/dh_lib.c67
-rw-r--r--crypto/dsa/Makefile.ssl98
-rw-r--r--crypto/dsa/dsa.h16
-rw-r--r--crypto/dsa/dsa_lib.c67
-rw-r--r--crypto/dsa/dsa_ossl.c5
-rw-r--r--crypto/dsa/dsa_sign.c5
-rw-r--r--crypto/dsa/dsa_vrf.c3
-rw-r--r--crypto/engine/.cvsignore2
-rw-r--r--crypto/engine/Makefile.ssl256
-rw-r--r--crypto/engine/README278
-rw-r--r--crypto/engine/engine.h403
-rw-r--r--crypto/engine/engine_err.c188
-rw-r--r--crypto/engine/engine_int.h164
-rw-r--r--crypto/engine/engine_lib.c488
-rw-r--r--crypto/engine/engine_list.c679
-rw-r--r--crypto/engine/engine_openssl.c174
-rw-r--r--crypto/engine/enginetest.c251
-rw-r--r--crypto/engine/hw_atalla.c443
-rw-r--r--crypto/engine/hw_cswift.c806
-rw-r--r--crypto/engine/hw_ncipher.c1018
-rw-r--r--crypto/engine/hw_nuron.c286
-rw-r--r--crypto/engine/vendor_defns/atalla.h61
-rw-r--r--crypto/engine/vendor_defns/cswift.h213
-rw-r--r--crypto/engine/vendor_defns/hwcryptohook.h476
-rw-r--r--crypto/err/Makefile.ssl21
-rw-r--r--crypto/err/err.c2
-rw-r--r--crypto/err/err.h3
-rw-r--r--crypto/err/err_all.c4
-rw-r--r--crypto/err/openssl.ec1
-rw-r--r--crypto/install.com4
-rw-r--r--crypto/rand/Makefile.ssl19
-rw-r--r--crypto/rand/rand.h4
-rw-r--r--crypto/rand/rand_lib.c57
-rw-r--r--crypto/rsa/Makefile.ssl62
-rw-r--r--crypto/rsa/rsa.h16
-rw-r--r--crypto/rsa/rsa_eay.c27
-rw-r--r--crypto/rsa/rsa_lib.c88
-rw-r--r--crypto/rsa/rsa_sign.c7
46 files changed, 6700 insertions, 366 deletions
diff --git a/crypto/Makefile.ssl b/crypto/Makefile.ssl
index 72e3fe7fde..7bb2a5ca99 100644
--- a/crypto/Makefile.ssl
+++ b/crypto/Makefile.ssl
@@ -27,7 +27,7 @@ LIBS=
SDIRS= md2 md5 sha mdc2 hmac ripemd \
des rc2 rc4 rc5 idea bf cast \
- bn rsa dsa dh dso \
+ bn rsa dsa dh dso engine \
buffer bio stack lhash rand err objects \
evp asn1 pem x509 x509v3 conf txt_db pkcs7 pkcs12 comp rijndael
diff --git a/crypto/bn/bn_exp.c b/crypto/bn/bn_exp.c
index 8117323766..d2c91628ac 100644
--- a/crypto/bn/bn_exp.c
+++ b/crypto/bn/bn_exp.c
@@ -113,13 +113,6 @@
#include <stdio.h>
#include "cryptlib.h"
#include "bn_lcl.h"
-#ifdef ATALLA
-# include <alloca.h>
-# include <atasi.h>
-# include <assert.h>
-# include <dlfcn.h>
-#endif
-
#define TABLE_SIZE 32
@@ -183,174 +176,6 @@ err:
}
-#ifdef ATALLA
-
-/*
- * This routine will dynamically check for the existance of an Atalla AXL-200
- * SSL accelerator module. If one is found, the variable
- * asi_accelerator_present is set to 1 and the function pointers
- * ptr_ASI_xxxxxx above will be initialized to corresponding ASI API calls.
- */
-typedef int tfnASI_GetPerformanceStatistics(int reset_flag,
- unsigned int *ret_buf);
-typedef int tfnASI_GetHardwareConfig(long card_num, unsigned int *ret_buf);
-typedef int tfnASI_RSAPrivateKeyOpFn(RSAPrivateKey * rsaKey,
- unsigned char *output,
- unsigned char *input,
- unsigned int modulus_len);
-
-static tfnASI_GetHardwareConfig *ptr_ASI_GetHardwareConfig;
-static tfnASI_RSAPrivateKeyOpFn *ptr_ASI_RSAPrivateKeyOpFn;
-static tfnASI_GetPerformanceStatistics *ptr_ASI_GetPerformanceStatistics;
-static int asi_accelerator_present;
-static int tried_atalla;
-
-void atalla_initialize_accelerator_handle(void)
- {
- void *dl_handle;
- int status;
- unsigned int config_buf[1024];
- static int tested;
-
- if(tested)
- return;
-
- tested=1;
-
- bzero((void *)config_buf, 1024);
-
- /*
- * Check to see if the library is present on the system
- */
- dl_handle = dlopen("atasi.so", RTLD_NOW);
- if (dl_handle == (void *) NULL)
- {
-/* printf("atasi.so library is not present on the system\n");
- printf("No HW acceleration available\n");*/
- return;
- }
-
- /*
- * The library is present. Now we'll check to insure that the
- * LDM is up and running. First we'll get the address of the
- * function in the atasi library that we need to see if the
- * LDM is operating.
- */
-
- ptr_ASI_GetHardwareConfig =
- (tfnASI_GetHardwareConfig *)dlsym(dl_handle,"ASI_GetHardwareConfig");
-
- if (ptr_ASI_GetHardwareConfig)
- {
- /*
- * We found the call, now we'll get our config
- * status. If we get a non 0 result, the LDM is not
- * running and we cannot use the Atalla ASI *
- * library.
- */
- status = (*ptr_ASI_GetHardwareConfig)(0L, config_buf);
- if (status != 0)
- {
- printf("atasi.so library is present but not initialized\n");
- printf("No HW acceleration available\n");
- return;
- }
- }
- else
- {
-/* printf("We found the library, but not the function. Very Strange!\n");*/
- return ;
- }
-
- /*
- * It looks like we have acceleration capabilities. Load up the
- * pointers to our ASI API calls.
- */
- ptr_ASI_RSAPrivateKeyOpFn=
- (tfnASI_RSAPrivateKeyOpFn *)dlsym(dl_handle, "ASI_RSAPrivateKeyOpFn");
- if (ptr_ASI_RSAPrivateKeyOpFn == NULL)
- {
-/* printf("We found the library, but no RSA function. Very Strange!\n");*/
- return;
- }
-
- ptr_ASI_GetPerformanceStatistics =
- (tfnASI_GetPerformanceStatistics *)dlsym(dl_handle, "ASI_GetPerformanceStatistics");
- if (ptr_ASI_GetPerformanceStatistics == NULL)
- {
-/* printf("We found the library, but no stat function. Very Strange!\n");*/
- return;
- }
-
- /*
- * Indicate that acceleration is available
- */
- asi_accelerator_present = 1;
-
-/* printf("This system has acceleration!\n");*/
-
- return;
- }
-
-/* make sure this only gets called once when bn_mod_exp calls bn_mod_exp_mont */
-int BN_mod_exp_atalla(BIGNUM *r, BIGNUM *a, const BIGNUM *p, const BIGNUM *m)
- {
- unsigned char *abin;
- unsigned char *pbin;
- unsigned char *mbin;
- unsigned char *rbin;
- int an,pn,mn,ret;
- RSAPrivateKey keydata;
-
- atalla_initialize_accelerator_handle();
- if(!asi_accelerator_present)
- return 0;
-
-
-/* We should be able to run without size testing */
-# define ASIZE 128
- an=BN_num_bytes(a);
- pn=BN_num_bytes(p);
- mn=BN_num_bytes(m);
-
- if(an <= ASIZE && pn <= ASIZE && mn <= ASIZE)
- {
- int size=mn;
-
- assert(an <= mn);
- abin=alloca(size);
- memset(abin,'\0',mn);
- BN_bn2bin(a,abin+size-an);
-
- pbin=alloca(pn);
- BN_bn2bin(p,pbin);
-
- mbin=alloca(size);
- memset(mbin,'\0',mn);
- BN_bn2bin(m,mbin+size-mn);
-
- rbin=alloca(size);
-
- memset(&keydata,'\0',sizeof keydata);
- keydata.privateExponent.data=pbin;
- keydata.privateExponent.len=pn;
- keydata.modulus.data=mbin;
- keydata.modulus.len=size;
-
- ret=(*ptr_ASI_RSAPrivateKeyOpFn)(&keydata,rbin,abin,keydata.modulus.len);
-/*fprintf(stderr,"!%s\n",BN_bn2hex(a));*/
- if(!ret)
- {
- BN_bin2bn(rbin,keydata.modulus.len,r);
-/*fprintf(stderr,"?%s\n",BN_bn2hex(r));*/
- return 1;
- }
- }
- return 0;
- }
-#endif /* def ATALLA */
-
-
int BN_mod_exp(BIGNUM *r, BIGNUM *a, const BIGNUM *p, const BIGNUM *m,
BN_CTX *ctx)
{
@@ -360,13 +185,6 @@ int BN_mod_exp(BIGNUM *r, BIGNUM *a, const BIGNUM *p, const BIGNUM *m,
bn_check_top(p);
bn_check_top(m);
-#ifdef ATALLA
- if(BN_mod_exp_atalla(r,a,p,m))
- return 1;
-/* If it fails, try the other methods (but don't try atalla again) */
- tried_atalla=1;
-#endif
-
#ifdef MONT_MUL_MOD
/* I have finally been able to take out this pre-condition of
* the top bit being set. It was caused by an error in BN_div
@@ -392,10 +210,6 @@ int BN_mod_exp(BIGNUM *r, BIGNUM *a, const BIGNUM *p, const BIGNUM *m,
{ ret=BN_mod_exp_simple(r,a,p,m,ctx); }
#endif
-#ifdef ATALLA
- tried_atalla=0;
-#endif
-
return(ret);
}
@@ -525,12 +339,6 @@ int BN_mod_exp_mont(BIGNUM *rr, BIGNUM *a, const BIGNUM *p,
bn_check_top(p);
bn_check_top(m);
-#ifdef ATALLA
- if(!tried_atalla && BN_mod_exp_atalla(rr,a,p,m))
- return 1;
-/* If it fails, try the other methods */
-#endif
-
if (!(m->d[0] & 1))
{
BNerr(BN_F_BN_MOD_EXP_MONT,BN_R_CALLED_WITH_EVEN_MODULUS);
@@ -693,19 +501,6 @@ int BN_mod_exp_mont_word(BIGNUM *rr, BN_ULONG a, const BIGNUM *p,
t = BN_CTX_get(ctx);
if (d == NULL || r == NULL || t == NULL) goto err;
-#ifdef ATALLA
- if (!tried_atalla)
- {
- BN_set_word(t, a);
- if (BN_mod_exp_atalla(rr, t, p, m))
- {
- BN_CTX_end(ctx);
- return 1;
- }
- }
-/* If it fails, try the other methods */
-#endif
-
if (in_mont != NULL)
mont=in_mont;
else
diff --git a/crypto/cryptlib.c b/crypto/cryptlib.c
index 070cf59690..9de60fd528 100644
--- a/crypto/cryptlib.c
+++ b/crypto/cryptlib.c
@@ -100,7 +100,8 @@ static const char* lock_names[CRYPTO_NUM_LOCKS] =
"debug_malloc2",
"dso",
"dynlock",
-#if CRYPTO_NUM_LOCKS != 28
+ "engine",
+#if CRYPTO_NUM_LOCKS != 29
# error "Inconsistency between crypto.h and cryptlib.c"
#endif
};
diff --git a/crypto/crypto-lib.com b/crypto/crypto-lib.com
index edffeffde1..70e3c91b34 100644
--- a/crypto/crypto-lib.com
+++ b/crypto/crypto-lib.com
@@ -88,7 +88,7 @@ $! Define The Different Encryption Types.
$!
$ ENCRYPT_TYPES = "Basic,MD2,MD4,MD5,SHA,MDC2,HMAC,RIPEMD,"+ -
"DES,RC2,RC4,RC5,IDEA,BF,CAST,"+ -
- "BN,RSA,DSA,DH,DSO,"+ -
+ "BN,RSA,DSA,DH,DSO,ENGINE,RIJNDAEL,"+ -
"BUFFER,BIO,STACK,LHASH,RAND,ERR,OBJECTS,"+ -
"EVP,EVP_2,ASN1,ASN1_2,PEM,X509,X509V3,"+ -
"CONF,TXT_DB,PKCS7,PKCS12,COMP"
@@ -206,6 +206,9 @@ $ LIB_DSA = "dsa_gen,dsa_key,dsa_lib,dsa_asn1,dsa_vrf,dsa_sign,dsa_err,dsa_ossl"
$ LIB_DH = "dh_gen,dh_key,dh_lib,dh_check,dh_err"
$ LIB_DSO = "dso_dl,dso_dlfcn,dso_err,dso_lib,dso_null,"+ -
"dso_openssl,dso_win32,dso_vms"
+$ LIB_ENGINE = "engine_err,engine_lib,engine_list,engine_openssl,"+ -
+ "hw_atalla,hw_cswift,hw_ncipher"
+$ LIB_RIJNDAEL = "rijndael-alg-fst"
$ LIB_BUFFER = "buffer,buf_err"
$ LIB_BIO = "bio_lib,bio_cb,bio_err,"+ -
"bss_mem,bss_null,bss_fd,"+ -
@@ -1194,7 +1197,9 @@ $ CC = "CC"
$ IF ARCH.EQS."VAX" .AND. F$TRNLNM("DECC$CC_DEFAULT").NES."/DECC" -
THEN CC = "CC/DECC"
$ CC = CC + "/''CC_OPTIMIZE'/''DEBUGGER'/STANDARD=ANSI89" + -
- "/NOLIST/PREFIX=ALL/INCLUDE=SYS$DISK:[]" + CCEXTRAFLAGS
+ "/NOLIST/PREFIX=ALL" + -
+ "/INCLUDE=(SYS$DISK:[],SYS$DISK:[.ENGINE.VENDOR_DEFNS])" + -
+ CCEXTRAFLAGS
$!
$! Define The Linker Options File Name.
$!
@@ -1226,7 +1231,8 @@ $ WRITE SYS$OUTPUT "There is no VAX C on Alpha!"
$ EXIT
$ ENDIF
$ IF F$TRNLNM("DECC$CC_DEFAULT").EQS."/DECC" THEN CC = "CC/VAXC"
-$ CC = CC + "/''CC_OPTIMIZE'/''DEBUGGER'/NOLIST/INCLUDE=SYS$DISK:[]" + -
+$ CC = CC + "/''CC_OPTIMIZE'/''DEBUGGER'/NOLIST" + -
+ "/INCLUDE=(SYS$DISK:[],SYS$DISK:[.ENGINE.VENDOR_DEFNS])" + -
CCEXTRAFLAGS
$ CCDEFS = """VAXC""," + CCDEFS
$!
@@ -1258,7 +1264,8 @@ $!
$! Use GNU C...
$!
$ CC = "GCC/NOCASE_HACK/''GCC_OPTIMIZE'/''DEBUGGER'/NOLIST" + -
- "/INCLUDE=SYS$DISK:[]" + CCEXTRAFLAGS
+ "/INCLUDE=(SYS$DISK:[],SYS$DISK:[.ENGINE.VENDOR_DEFNS])" + -
+ CCEXTRAFLAGS
$!
$! Define The Linker Options File Name.
$!
diff --git a/crypto/crypto.h b/crypto/crypto.h
index df6ccaff6d..52ee97b71a 100644
--- a/crypto/crypto.h
+++ b/crypto/crypto.h
@@ -122,7 +122,8 @@ extern "C" {
#define CRYPTO_LOCK_MALLOC2 25
#define CRYPTO_LOCK_DSO 26
#define CRYPTO_LOCK_DYNLOCK 27
-#define CRYPTO_NUM_LOCKS 28
+#define CRYPTO_LOCK_ENGINE 28
+#define CRYPTO_NUM_LOCKS 29
#define CRYPTO_LOCK 1
#define CRYPTO_UNLOCK 2
diff --git a/crypto/dh/Makefile.ssl b/crypto/dh/Makefile.ssl
index ccee00eeca..b9fed3a65e 100644
--- a/crypto/dh/Makefile.ssl
+++ b/crypto/dh/Makefile.ssl
@@ -101,19 +101,41 @@ dh_gen.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
dh_gen.o: ../../include/openssl/opensslv.h ../../include/openssl/safestack.h
dh_gen.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
dh_gen.o: ../cryptlib.h
-dh_key.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
-dh_key.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-dh_key.o: ../../include/openssl/dh.h ../../include/openssl/e_os.h
-dh_key.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-dh_key.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+dh_key.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+dh_key.o: ../../include/openssl/blowfish.h ../../include/openssl/bn.h
+dh_key.o: ../../include/openssl/buffer.h ../../include/openssl/cast.h
+dh_key.o: ../../include/openssl/crypto.h ../../include/openssl/des.h
+dh_key.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h
+dh_key.o: ../../include/openssl/e_os.h ../../include/openssl/e_os2.h
+dh_key.o: ../../include/openssl/engine.h ../../include/openssl/err.h
+dh_key.o: ../../include/openssl/evp.h ../../include/openssl/idea.h
+dh_key.o: ../../include/openssl/lhash.h ../../include/openssl/md2.h
+dh_key.o: ../../include/openssl/md4.h ../../include/openssl/md5.h
+dh_key.o: ../../include/openssl/mdc2.h ../../include/openssl/obj_mac.h
+dh_key.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
dh_key.o: ../../include/openssl/opensslv.h ../../include/openssl/rand.h
-dh_key.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+dh_key.o: ../../include/openssl/rc2.h ../../include/openssl/rc4.h
+dh_key.o: ../../include/openssl/rc5.h ../../include/openssl/rijndael-alg-fst.h
+dh_key.o: ../../include/openssl/rijndael.h ../../include/openssl/ripemd.h
+dh_key.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
+dh_key.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
dh_key.o: ../../include/openssl/symhacks.h ../cryptlib.h
-dh_lib.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
-dh_lib.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-dh_lib.o: ../../include/openssl/dh.h ../../include/openssl/e_os.h
-dh_lib.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-dh_lib.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
-dh_lib.o: ../../include/openssl/opensslv.h ../../include/openssl/safestack.h
-dh_lib.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-dh_lib.o: ../cryptlib.h
+dh_lib.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+dh_lib.o: ../../include/openssl/blowfish.h ../../include/openssl/bn.h
+dh_lib.o: ../../include/openssl/buffer.h ../../include/openssl/cast.h
+dh_lib.o: ../../include/openssl/crypto.h ../../include/openssl/des.h
+dh_lib.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h
+dh_lib.o: ../../include/openssl/e_os.h ../../include/openssl/e_os2.h
+dh_lib.o: ../../include/openssl/engine.h ../../include/openssl/err.h
+dh_lib.o: ../../include/openssl/evp.h ../../include/openssl/idea.h
+dh_lib.o: ../../include/openssl/lhash.h ../../include/openssl/md2.h
+dh_lib.o: ../../include/openssl/md4.h ../../include/openssl/md5.h
+dh_lib.o: ../../include/openssl/mdc2.h ../../include/openssl/obj_mac.h
+dh_lib.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+dh_lib.o: ../../include/openssl/opensslv.h ../../include/openssl/rand.h
+dh_lib.o: ../../include/openssl/rc2.h ../../include/openssl/rc4.h
+dh_lib.o: ../../include/openssl/rc5.h ../../include/openssl/rijndael-alg-fst.h
+dh_lib.o: ../../include/openssl/rijndael.h ../../include/openssl/ripemd.h
+dh_lib.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
+dh_lib.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+dh_lib.o: ../../include/openssl/symhacks.h ../cryptlib.h
diff --git a/crypto/dh/dh.h b/crypto/dh/dh.h
index a15fc1c65f..7a8d9f88c2 100644
--- a/crypto/dh/dh.h
+++ b/crypto/dh/dh.h
@@ -115,7 +115,11 @@ struct dh_st
int references;
CRYPTO_EX_DATA ex_data;
+#if 0
DH_METHOD *meth;
+#else
+ struct engine_st *engine;
+#endif
};
#define DH_GENERATOR_2 2
@@ -150,10 +154,15 @@ struct dh_st
DH_METHOD *DH_OpenSSL(void);
-void DH_set_default_method(DH_METHOD *meth);
-DH_METHOD *DH_get_default_method(void);
+void DH_set_default_openssl_method(DH_METHOD *meth);
+DH_METHOD *DH_get_default_openssl_method(void);
+#if 0
DH_METHOD *DH_set_method(DH *dh, DH_METHOD *meth);
DH *DH_new_method(DH_METHOD *meth);
+#else
+int DH_set_method(DH *dh, struct engine_st *engine);
+DH *DH_new_method(struct engine_st *engine);
+#endif
DH * DH_new(void);
void DH_free(DH *dh);
diff --git a/crypto/dh/dh_key.c b/crypto/dh/dh_key.c
index 6f9426dd6f..6915d79dcc 100644
--- a/crypto/dh/dh_key.c
+++ b/crypto/dh/dh_key.c
@@ -61,6 +61,7 @@
#include <openssl/bn.h>
#include <openssl/rand.h>
#include <openssl/dh.h>
+#include <openssl/engine.h>
static int generate_key(DH *dh);
static int compute_key(unsigned char *key, BIGNUM *pub_key, DH *dh);
@@ -72,12 +73,12 @@ static int dh_finish(DH *dh);
int DH_generate_key(DH *dh)
{
- return dh->meth->generate_key(dh);
+ return ENGINE_get_DH(dh->engine)->generate_key(dh);
}
int DH_compute_key(unsigned char *key, BIGNUM *pub_key, DH *dh)
{
- return dh->meth->compute_key(key, pub_key, dh);
+ return ENGINE_get_DH(dh->engine)->compute_key(key, pub_key, dh);
}
static DH_METHOD dh_ossl = {
@@ -137,8 +138,9 @@ static int generate_key(DH *dh)
}
mont=(BN_MONT_CTX *)dh->method_mont_p;
- if (!dh->meth->bn_mod_exp(dh, pub_key,dh->g,priv_key,dh->p,&ctx,mont))
- goto err;
+ if (!ENGINE_get_DH(dh->engine)->bn_mod_exp(dh, pub_key, dh->g,
+ priv_key,dh->p,&ctx,mont))
+ goto err;
dh->pub_key=pub_key;
dh->priv_key=priv_key;
@@ -177,7 +179,8 @@ static int compute_key(unsigned char *key, BIGNUM *pub_key, DH *dh)
}
mont=(BN_MONT_CTX *)dh->method_mont_p;
- if (!dh->meth->bn_mod_exp(dh, tmp,pub_key,dh->priv_key,dh->p,&ctx,mont))
+ if (!ENGINE_get_DH(dh->engine)->bn_mod_exp(dh, tmp, pub_key,
+ dh->priv_key,dh->p,&ctx,mont))
{
DHerr(DH_F_DH_COMPUTE_KEY,ERR_R_BN_LIB);
goto err;
diff --git a/crypto/dh/dh_lib.c b/crypto/dh/dh_lib.c
index a8d5340bf4..66803b5565 100644
--- a/crypto/dh/dh_lib.c
+++ b/crypto/dh/dh_lib.c
@@ -60,6 +60,7 @@
#include "cryptlib.h"
#include <openssl/bn.h>
#include <openssl/dh.h>
+#include <openssl/engine.h>
const char *DH_version="Diffie-Hellman" OPENSSL_VERSION_PTEXT;
@@ -67,17 +68,32 @@ static DH_METHOD *default_DH_method;
static int dh_meth_num = 0;
static STACK_OF(CRYPTO_EX_DATA_FUNCS) *dh_meth = NULL;
-void DH_set_default_method(DH_METHOD *meth)
+void DH_set_default_openssl_method(DH_METHOD *meth)
{
- default_DH_method = meth;
+ ENGINE *e;
+ /* We'll need to notify the "openssl" ENGINE of this
+ * change too. We won't bother locking things down at
+ * our end as there was never any locking in these
+ * functions! */
+ if(default_DH_method != meth)
+ {
+ default_DH_method = meth;
+ e = ENGINE_by_id("openssl");
+ if(e)
+ {
+ ENGINE_set_DH(e, meth);
+ ENGINE_free(e);
+ }
+ }
}
-DH_METHOD *DH_get_default_method(void)
+DH_METHOD *DH_get_default_openssl_method(void)
{
if(!default_DH_method) default_DH_method = DH_OpenSSL();
return default_DH_method;
}
+#if 0
DH_METHOD *DH_set_method(DH *dh, DH_METHOD *meth)
{
DH_METHOD *mtmp;
@@ -87,14 +103,37 @@ DH_METHOD *DH_set_method(DH *dh, DH_METHOD *meth)
if (meth->init) meth->init(dh);
return mtmp;
}
+#else
+int DH_set_method(DH *dh, ENGINE *engine)
+{
+ ENGINE *mtmp;
+ DH_METHOD *meth;
+ mtmp = dh->engine;
+ meth = ENGINE_get_DH(mtmp);
+ if (!ENGINE_init(engine))
+ return 0;
+ if (meth->finish) meth->finish(dh);
+ dh->engine= engine;
+ meth = ENGINE_get_DH(engine);
+ if (meth->init) meth->init(dh);
+ /* SHOULD ERROR CHECK THIS!!! */
+ ENGINE_finish(mtmp);
+ return 1;
+}
+#endif
DH *DH_new(void)
{
return DH_new_method(NULL);
}
+#if 0
DH *DH_new_method(DH_METHOD *meth)
+#else
+DH *DH_new_method(ENGINE *engine)
+#endif
{
+ DH_METHOD *meth;
DH *ret;
ret=(DH *)OPENSSL_malloc(sizeof(DH));
@@ -103,8 +142,17 @@ DH *DH_new_method(DH_METHOD *meth)
DHerr(DH_F_DH_NEW,ERR_R_MALLOC_FAILURE);
return(NULL);
}
- if(meth) ret->meth = meth;
- else ret->meth = DH_get_default_method();
+ if(engine)
+ ret->engine = engine;
+ else
+ {
+ if((ret->engine=ENGINE_get_default_DH()) == NULL)
+ {
+ OPENSSL_free(ret);
+ return NULL;
+ }
+ }
+ meth = ENGINE_get_DH(ret->engine);
ret->pad=0;
ret->version=0;
ret->p=NULL;
@@ -119,8 +167,8 @@ DH *DH_new_method(DH_METHOD *meth)
ret->counter = NULL;
ret->method_mont_p=NULL;
ret->references = 1;
- ret->flags=ret->meth->flags;
- if ((ret->meth->init != NULL) && !ret->meth->init(ret))
+ ret->flags=meth->flags;
+ if ((meth->init != NULL) && !meth->init(ret))
{
OPENSSL_free(ret);
ret=NULL;
@@ -132,6 +180,7 @@ DH *DH_new_method(DH_METHOD *meth)
void DH_free(DH *r)
{
+ DH_METHOD *meth;
int i;
if(r == NULL) return;
i = CRYPTO_add(&r->references, -1, CRYPTO_LOCK_DH);
@@ -149,7 +198,9 @@ void DH_free(DH *r)
CRYPTO_free_ex_data(dh_meth, r, &r->ex_data);
- if(r->meth->finish) r->meth->finish(r);
+ meth = ENGINE_get_DH(r->engine);
+ if(meth->finish) meth->finish(r);
+ ENGINE_finish(r->engine);
if (r->p != NULL) BN_clear_free(r->p);
if (r->g != NULL) BN_clear_free(r->g);
diff --git a/crypto/dsa/Makefile.ssl b/crypto/dsa/Makefile.ssl
index 1dfdb2d769..f9a6dbbd45 100644
--- a/crypto/dsa/Makefile.ssl
+++ b/crypto/dsa/Makefile.ssl
@@ -116,39 +116,81 @@ dsa_key.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
dsa_key.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
dsa_key.o: ../../include/openssl/symhacks.h ../cryptlib.h
dsa_lib.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
-dsa_lib.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
-dsa_lib.o: ../../include/openssl/crypto.h ../../include/openssl/dh.h
-dsa_lib.o: ../../include/openssl/dsa.h ../../include/openssl/e_os.h
-dsa_lib.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-dsa_lib.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
-dsa_lib.o: ../../include/openssl/opensslv.h ../../include/openssl/safestack.h
-dsa_lib.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-dsa_lib.o: ../cryptlib.h
+dsa_lib.o: ../../include/openssl/blowfish.h ../../include/openssl/bn.h
+dsa_lib.o: ../../include/openssl/buffer.h ../../include/openssl/cast.h
+dsa_lib.o: ../../include/openssl/crypto.h ../../include/openssl/des.h
+dsa_lib.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h
+dsa_lib.o: ../../include/openssl/e_os.h ../../include/openssl/e_os2.h
+dsa_lib.o: ../../include/openssl/engine.h ../../include/openssl/err.h
+dsa_lib.o: ../../include/openssl/evp.h ../../include/openssl/idea.h
+dsa_lib.o: ../../include/openssl/lhash.h ../../include/openssl/md2.h
+dsa_lib.o: ../../include/openssl/md4.h ../../include/openssl/md5.h
+dsa_lib.o: ../../include/openssl/mdc2.h ../../include/openssl/obj_mac.h
+dsa_lib.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+dsa_lib.o: ../../include/openssl/opensslv.h ../../include/openssl/rand.h
+dsa_lib.o: ../../include/openssl/rc2.h ../../include/openssl/rc4.h
+dsa_lib.o: ../../include/openssl/rc5.h ../../include/openssl/rijndael-alg-fst.h
+dsa_lib.o: ../../include/openssl/rijndael.h ../../include/openssl/ripemd.h
+dsa_lib.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
+dsa_lib.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+dsa_lib.o: ../../include/openssl/symhacks.h ../cryptlib.h
dsa_ossl.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
-dsa_ossl.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
-dsa_ossl.o: ../../include/openssl/crypto.h ../../include/openssl/dh.h
-dsa_ossl.o: ../../include/openssl/dsa.h ../../include/openssl/e_os.h
-dsa_ossl.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-dsa_ossl.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+dsa_ossl.o: ../../include/openssl/blowfish.h ../../include/openssl/bn.h
+dsa_ossl.o: ../../include/openssl/buffer.h ../../include/openssl/cast.h
+dsa_ossl.o: ../../include/openssl/crypto.h ../../include/openssl/des.h
+dsa_ossl.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h
+dsa_ossl.o: ../../include/openssl/e_os.h ../../include/openssl/e_os2.h
+dsa_ossl.o: ../../include/openssl/engine.h ../../include/openssl/err.h
+dsa_ossl.o: ../../include/openssl/evp.h ../../include/openssl/idea.h
+dsa_ossl.o: ../../include/openssl/lhash.h ../../include/openssl/md2.h
+dsa_ossl.o: ../../include/openssl/md4.h ../../include/openssl/md5.h
+dsa_ossl.o: ../../include/openssl/mdc2.h ../../include/openssl/obj_mac.h
+dsa_ossl.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
dsa_ossl.o: ../../include/openssl/opensslv.h ../../include/openssl/rand.h
-dsa_ossl.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+dsa_ossl.o: ../../include/openssl/rc2.h ../../include/openssl/rc4.h
+dsa_ossl.o: ../../include/openssl/rc5.h
+dsa_ossl.o: ../../include/openssl/rijndael-alg-fst.h
+dsa_ossl.o: ../../include/openssl/rijndael.h ../../include/openssl/ripemd.h
+dsa_ossl.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
+dsa_ossl.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
dsa_ossl.o: ../../include/openssl/symhacks.h ../cryptlib.h
dsa_sign.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
-dsa_sign.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
-dsa_sign.o: ../../include/openssl/crypto.h ../../include/openssl/dh.h
-dsa_sign.o: ../../include/openssl/dsa.h ../../include/openssl/e_os.h
-dsa_sign.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-dsa_sign.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+dsa_sign.o: ../../include/openssl/blowfish.h ../../include/openssl/bn.h
+dsa_sign.o: ../../include/openssl/buffer.h ../../include/openssl/cast.h
+dsa_sign.o: ../../include/openssl/crypto.h ../../include/openssl/des.h
+dsa_sign.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h
+dsa_sign.o: ../../include/openssl/e_os.h ../../include/openssl/e_os2.h
+dsa_sign.o: ../../include/openssl/engine.h ../../include/openssl/err.h
+dsa_sign.o: ../../include/openssl/evp.h ../../include/openssl/idea.h
+dsa_sign.o: ../../include/openssl/lhash.h ../../include/openssl/md2.h
+dsa_sign.o: ../../include/openssl/md4.h ../../include/openssl/md5.h
+dsa_sign.o: ../../include/openssl/mdc2.h ../../include/openssl/obj_mac.h
+dsa_sign.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
dsa_sign.o: ../../include/openssl/opensslv.h ../../include/openssl/rand.h
-dsa_sign.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+dsa_sign.o: ../../include/openssl/rc2.h ../../include/openssl/rc4.h
+dsa_sign.o: ../../include/openssl/rc5.h
+dsa_sign.o: ../../include/openssl/rijndael-alg-fst.h
+dsa_sign.o: ../../include/openssl/rijndael.h ../../include/openssl/ripemd.h
+dsa_sign.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
+dsa_sign.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
dsa_sign.o: ../../include/openssl/symhacks.h ../cryptlib.h
dsa_vrf.o: ../../include/openssl/asn1.h ../../include/openssl/asn1_mac.h
-dsa_vrf.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
-dsa_vrf.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-dsa_vrf.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h
-dsa_vrf.o: ../../include/openssl/e_os.h ../../include/openssl/e_os2.h
-dsa_vrf.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
+dsa_vrf.o: ../../include/openssl/bio.h ../../include/openssl/blowfish.h
+dsa_vrf.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
+dsa_vrf.o: ../../include/openssl/cast.h ../../include/openssl/crypto.h
+dsa_vrf.o: ../../include/openssl/des.h ../../include/openssl/dh.h
+dsa_vrf.o: ../../include/openssl/dsa.h ../../include/openssl/e_os.h
+dsa_vrf.o: ../../include/openssl/e_os2.h ../../include/openssl/engine.h
+dsa_vrf.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+dsa_vrf.o: ../../include/openssl/idea.h ../../include/openssl/lhash.h
+dsa_vrf.o: ../../include/openssl/md2.h ../../include/openssl/md4.h
+dsa_vrf.o: ../../include/openssl/md5.h ../../include/openssl/mdc2.h
+dsa_vrf.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
dsa_vrf.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-dsa_vrf.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
-dsa_vrf.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-dsa_vrf.o: ../cryptlib.h
+dsa_vrf.o: ../../include/openssl/rand.h ../../include/openssl/rc2.h
+dsa_vrf.o: ../../include/openssl/rc4.h ../../include/openssl/rc5.h
+dsa_vrf.o: ../../include/openssl/rijndael-alg-fst.h
+dsa_vrf.o: ../../include/openssl/rijndael.h ../../include/openssl/ripemd.h
+dsa_vrf.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
+dsa_vrf.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+dsa_vrf.o: ../../include/openssl/symhacks.h ../cryptlib.h
diff --git a/crypto/dsa/dsa.h b/crypto/dsa/dsa.h
index 3ebcc4ae0a..65689a3426 100644
--- a/crypto/dsa/dsa.h
+++ b/crypto/dsa/dsa.h
@@ -133,7 +133,11 @@ struct dsa_st
char *method_mont_p;
int references;
CRYPTO_EX_DATA ex_data;
+#if 0
DSA_METHOD *meth;
+#else
+ struct engine_st *engine;
+#endif
};
#define DSAparams_dup(x) (DSA *)ASN1_dup((int (*)())i2d_DSAparams, \
@@ -159,12 +163,20 @@ int DSA_do_verify(const unsigned char *dgst,int dgst_len,
DSA_METHOD *DSA_OpenSSL(void);
-void DSA_set_default_method(DSA_METHOD *);
-DSA_METHOD *DSA_get_default_method(void);
+void DSA_set_default_openssl_method(DSA_METHOD *);
+DSA_METHOD *DSA_get_default_openssl_method(void);
+#if 0
DSA_METHOD *DSA_set_method(DSA *dsa, DSA_METHOD *);
+#else
+int DSA_set_method(DSA *dsa, struct engine_st *engine);
+#endif
DSA * DSA_new(void);
+#if 0
DSA * DSA_new_method(DSA_METHOD *meth);
+#else
+DSA * DSA_new_method(struct engine_st *engine);
+#endif
int DSA_size(DSA *);
/* next 4 return -1 on error */
int DSA_sign_setup( DSA *dsa,BN_CTX *ctx_in,BIGNUM **kinvp,BIGNUM **rp);
diff --git a/crypto/dsa/dsa_lib.c b/crypto/dsa/dsa_lib.c
index be30d18b8a..b31b946ad3 100644
--- a/crypto/dsa/dsa_lib.c
+++ b/crypto/dsa/dsa_lib.c
@@ -63,6 +63,7 @@
#include <openssl/bn.h>
#include <openssl/dsa.h>
#include <openssl/asn1.h>
+#include <openssl/engine.h>
const char *DSA_version="DSA" OPENSSL_VERSION_PTEXT;
@@ -70,12 +71,26 @@ static DSA_METHOD *default_DSA_method;
static int dsa_meth_num = 0;
static STACK_OF(CRYPTO_EX_DATA_FUNCS) *dsa_meth = NULL;
-void DSA_set_default_method(DSA_METHOD *meth)
+void DSA_set_default_openssl_method(DSA_METHOD *meth)
{
- default_DSA_method = meth;
+ ENGINE *e;
+ /* We'll need to notify the "openssl" ENGINE of this
+ * change too. We won't bother locking things down at
+ * our end as there was never any locking in these
+ * functions! */
+ if(default_DSA_method != meth)
+ {
+ default_DSA_method = meth;
+ e = ENGINE_by_id("openssl");
+ if(e)
+ {
+ ENGINE_set_DSA(e, meth);
+ ENGINE_free(e);
+ }
+ }
}
-DSA_METHOD *DSA_get_default_method(void)
+DSA_METHOD *DSA_get_default_openssl_method(void)
{
if(!default_DSA_method) default_DSA_method = DSA_OpenSSL();
return default_DSA_method;
@@ -86,6 +101,7 @@ DSA *DSA_new(void)
return DSA_new_method(NULL);
}
+#if 0
DSA_METHOD *DSA_set_method(DSA *dsa, DSA_METHOD *meth)
{
DSA_METHOD *mtmp;
@@ -95,10 +111,33 @@ DSA_METHOD *DSA_set_method(DSA *dsa, DSA_METHOD *meth)
if (meth->init) meth->init(dsa);
return mtmp;
}
+#else
+int DSA_set_method(DSA *dsa, ENGINE *engine)
+ {
+ ENGINE *mtmp;
+ DSA_METHOD *meth;
+ mtmp = dsa->engine;
+ meth = ENGINE_get_DSA(mtmp);
+ if (!ENGINE_init(engine))
+ return 0;
+ if (meth->finish) meth->finish(dsa);
+ dsa->engine = engine;
+ meth = ENGINE_get_DSA(engine);
+ if (meth->init) meth->init(dsa);
+ /* SHOULD ERROR CHECK THIS!!! */
+ ENGINE_finish(mtmp);
+ return 1;
+ }
+#endif
+#if 0
DSA *DSA_new_method(DSA_METHOD *meth)
+#else
+DSA *DSA_new_method(ENGINE *engine)
+#endif
{
+ DSA_METHOD *meth;
DSA *ret;
ret=(DSA *)OPENSSL_malloc(sizeof(DSA));
@@ -107,8 +146,17 @@ DSA *DSA_new_method(DSA_METHOD *meth)
DSAerr(DSA_F_DSA_NEW,ERR_R_MALLOC_FAILURE);
return(NULL);
}
- if(meth) ret->meth = meth;
- else ret->meth = DSA_get_default_method();
+ if(engine)
+ ret->engine = engine;
+ else
+ {
+ if((ret->engine=ENGINE_get_default_DSA()) == NULL)
+ {
+ OPENSSL_free(ret);
+ return NULL;
+ }
+ }
+ meth = ENGINE_get_DSA(ret->engine);
ret->pad=0;
ret->version=0;
ret->write_params=1;
@@ -124,8 +172,8 @@ DSA *DSA_new_method(DSA_METHOD *meth)
ret->method_mont_p=NULL;
ret->references=1;
- ret->flags=ret->meth->flags;
- if ((ret->meth->init != NULL) && !ret->meth->init(ret))
+ ret->flags=meth->flags;
+ if ((meth->init != NULL) && !meth->init(ret))
{
OPENSSL_free(ret);
ret=NULL;
@@ -138,6 +186,7 @@ DSA *DSA_new_method(DSA_METHOD *meth)
void DSA_free(DSA *r)
{
+ DSA_METHOD *meth;
int i;
if (r == NULL) return;
@@ -157,7 +206,9 @@ void DSA_free(DSA *r)
CRYPTO_free_ex_data(dsa_meth, r, &r->ex_data);
- if(r->meth->finish) r->meth->finish(r);
+ meth = ENGINE_get_DSA(r->engine);
+ if(meth->finish) meth->finish(r);
+ ENGINE_finish(r->engine);
if (r->p != NULL) BN_clear_free(r->p);
if (r->q != NULL) BN_clear_free(r->q);
diff --git a/crypto/dsa/dsa_ossl.c b/crypto/dsa/dsa_ossl.c
index 094356518f..96295dc24f 100644
--- a/crypto/dsa/dsa_ossl.c
+++ b/crypto/dsa/dsa_ossl.c
@@ -64,6 +64,7 @@
#include <openssl/dsa.h>
#include <openssl/rand.h>
#include <openssl/asn1.h>
+#include <openssl/engine.h>
static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa);
static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp);
@@ -195,7 +196,7 @@ static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp)
}
/* Compute r = (g^k mod p) mod q */
- if (!dsa->meth->bn_mod_exp(dsa, r,dsa->g,&k,dsa->p,ctx,
+ if (!ENGINE_get_DSA(dsa->engine)->bn_mod_exp(dsa, r,dsa->g,&k,dsa->p,ctx,
(BN_MONT_CTX *)dsa->method_mont_p)) goto err;
if (!BN_mod(r,r,dsa->q,ctx)) goto err;
@@ -273,7 +274,7 @@ static int dsa_do_verify(const unsigned char *dgst, int dgst_len, DSA_SIG *sig,
if (!BN_mod(&u1,&u1,dsa->q,ctx)) goto err;
#else
{
- if (!dsa->meth->dsa_mod_exp(dsa, &t1,dsa->g,&u1,dsa->pub_key,&u2,
+ if (!ENGINE_get_DSA(dsa->engine)->dsa_mod_exp(dsa, &t1,dsa->g,&u1,dsa->pub_key,&u2,
dsa->p,ctx,mont)) goto err;
/* BN_copy(&u1,&t1); */
/* let u1 = u1 mod q */
diff --git a/crypto/dsa/dsa_sign.c b/crypto/dsa/dsa_sign.c
index 89205026f0..dfe27bae47 100644
--- a/crypto/dsa/dsa_sign.c
+++ b/crypto/dsa/dsa_sign.c
@@ -64,10 +64,11 @@
#include <openssl/dsa.h>
#include <openssl/rand.h>
#include <openssl/asn1.h>
+#include <openssl/engine.h>
DSA_SIG * DSA_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
{
- return dsa->meth->dsa_do_sign(dgst, dlen, dsa);
+ return ENGINE_get_DSA(dsa->engine)->dsa_do_sign(dgst, dlen, dsa);
}
int DSA_sign(int type, const unsigned char *dgst, int dlen, unsigned char *sig,
@@ -87,6 +88,6 @@ int DSA_sign(int type, const unsigned char *dgst, int dlen, unsigned char *sig,
int DSA_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp)
{
- return dsa->meth->dsa_sign_setup(dsa, ctx_in, kinvp, rp);
+ return ENGINE_get_DSA(dsa->engine)->dsa_sign_setup(dsa, ctx_in, kinvp, rp);
}
diff --git a/crypto/dsa/dsa_vrf.c b/crypto/dsa/dsa_vrf.c
index 03277f80fd..2e891ae491 100644
--- a/crypto/dsa/dsa_vrf.c
+++ b/crypto/dsa/dsa_vrf.c
@@ -65,11 +65,12 @@
#include <openssl/rand.h>
#include <openssl/asn1.h>
#include <openssl/asn1_mac.h>
+#include <openssl/engine.h>
int DSA_do_verify(const unsigned char *dgst, int dgst_len, DSA_SIG *sig,
DSA *dsa)
{
- return dsa->meth->dsa_do_verify(dgst, dgst_len, sig, dsa);
+ return ENGINE_get_DSA(dsa->engine)->dsa_do_verify(dgst, dgst_len, sig, dsa);
}
/* data has already been hashed (probably with SHA or SHA-1). */
diff --git a/crypto/engine/.cvsignore b/crypto/engine/.cvsignore
new file mode 100644
index 0000000000..c6d03a9dbc
--- /dev/null
+++ b/crypto/engine/.cvsignore
@@ -0,0 +1,2 @@
+lib
+Makefile.save
diff --git a/crypto/engine/Makefile.ssl b/crypto/engine/Makefile.ssl
new file mode 100644
index 0000000000..8974ecd9c5
--- /dev/null
+++ b/crypto/engine/Makefile.ssl
@@ -0,0 +1,256 @@
+#
+# OpenSSL/crypto/engine/Makefile
+#
+
+DIR= engine
+TOP= ../..
+CC= cc
+INCLUDES= -I.. -I../../include
+CFLAG=-g
+INSTALL_PREFIX=
+OPENSSLDIR= /usr/local/ssl
+INSTALLTOP=/usr/local/ssl
+MAKE= make -f Makefile.ssl
+MAKEDEPEND= $(TOP)/util/domd $(TOP)
+MAKEFILE= Makefile.ssl
+AR= ar r
+
+CFLAGS= $(INCLUDES) $(CFLAG)
+
+GENERAL=Makefile
+TEST= enginetest.c
+APPS=
+
+LIB=$(TOP)/libcrypto.a
+LIBSRC= engine_err.c engine_lib.c engine_list.c engine_openssl.c \
+ hw_atalla.c hw_cswift.c hw_ncipher.c hw_nuron.c
+LIBOBJ= engine_err.o engine_lib.o engine_list.o engine_openssl.o \
+ hw_atalla.o hw_cswift.o hw_ncipher.o hw_nuron.o
+
+SRC= $(LIBSRC)
+
+EXHEADER= engine.h
+HEADER= $(EXHEADER)
+
+ALL= $(GENERAL) $(SRC) $(HEADER)
+
+top:
+ (cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
+
+all: lib
+
+lib: $(LIBOBJ)
+ $(AR) $(LIB) $(LIBOBJ)
+ $(RANLIB) $(LIB)
+ @touch lib
+
+files:
+ $(PERL) $(TOP)/util/files.pl Makefile.ssl >> $(TOP)/MINFO
+
+links:
+ @$(TOP)/util/point.sh Makefile.ssl Makefile
+ @$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
+ @$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
+ @$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
+
+install:
+ @for i in $(EXHEADER) ; \
+ do \
+ (cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
+ chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
+ done;
+
+tags:
+ ctags $(SRC)
+
+tests:
+
+lint:
+ lint -DLINT $(INCLUDES) $(SRC)>fluff
+
+depend:
+ $(MAKEDEPEND) $(INCLUDES) $(DEPFLAG) $(PROGS) $(LIBSRC)
+
+dclean:
+ $(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
+ mv -f Makefile.new $(MAKEFILE)
+
+clean:
+ rm -f *.o */*.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+engine_err.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+engine_err.o: ../../include/openssl/blowfish.h ../../include/openssl/bn.h
+engine_err.o: ../../include/openssl/cast.h ../../include/openssl/crypto.h
+engine_err.o: ../../include/openssl/des.h ../../include/openssl/dh.h
+engine_err.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
+engine_err.o: ../../include/openssl/engine.h ../../include/openssl/err.h
+engine_err.o: ../../include/openssl/evp.h ../../include/openssl/idea.h
+engine_err.o: ../../include/openssl/lhash.h ../../include/openssl/md2.h
+engine_err.o: ../../include/openssl/md4.h ../../include/openssl/md5.h
+engine_err.o: ../../include/openssl/mdc2.h ../../include/openssl/obj_mac.h
+engine_err.o: ../../include/openssl/objects.h
+engine_err.o: ../../include/openssl/opensslconf.h
+engine_err.o: ../../include/openssl/opensslv.h ../../include/openssl/rand.h
+engine_err.o: ../../include/openssl/rc2.h ../../include/openssl/rc4.h
+engine_err.o: ../../include/openssl/rc5.h
+engine_err.o: ../../include/openssl/rijndael-alg-fst.h
+engine_err.o: ../../include/openssl/rijndael.h ../../include/openssl/ripemd.h
+engine_err.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
+engine_err.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+engine_err.o: ../../include/openssl/symhacks.h
+engine_lib.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+engine_lib.o: ../../include/openssl/blowfish.h ../../include/openssl/bn.h
+engine_lib.o: ../../include/openssl/buffer.h ../../include/openssl/cast.h
+engine_lib.o: ../../include/openssl/crypto.h ../../include/openssl/des.h
+engine_lib.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h
+engine_lib.o: ../../include/openssl/e_os.h ../../include/openssl/e_os2.h
+engine_lib.o: ../../include/openssl/engine.h ../../include/openssl/err.h
+engine_lib.o: ../../include/openssl/evp.h ../../include/openssl/idea.h
+engine_lib.o: ../../include/openssl/lhash.h ../../include/openssl/md2.h
+engine_lib.o: ../../include/openssl/md4.h ../../include/openssl/md5.h
+engine_lib.o: ../../include/openssl/mdc2.h ../../include/openssl/obj_mac.h
+engine_lib.o: ../../include/openssl/objects.h
+engine_lib.o: ../../include/openssl/opensslconf.h
+engine_lib.o: ../../include/openssl/opensslv.h ../../include/openssl/rand.h
+engine_lib.o: ../../include/openssl/rc2.h ../../include/openssl/rc4.h
+engine_lib.o: ../../include/openssl/rc5.h
+engine_lib.o: ../../include/openssl/rijndael-alg-fst.h
+engine_lib.o: ../../include/openssl/rijndael.h ../../include/openssl/ripemd.h
+engine_lib.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
+engine_lib.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+engine_lib.o: ../../include/openssl/symhacks.h ../cryptlib.h engine_int.h
+engine_list.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+engine_list.o: ../../include/openssl/blowfish.h ../../include/openssl/bn.h
+engine_list.o: ../../include/openssl/buffer.h ../../include/openssl/cast.h
+engine_list.o: ../../include/openssl/crypto.h ../../include/openssl/des.h
+engine_list.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h
+engine_list.o: ../../include/openssl/e_os.h ../../include/openssl/e_os2.h
+engine_list.o: ../../include/openssl/engine.h ../../include/openssl/err.h
+engine_list.o: ../../include/openssl/evp.h ../../include/openssl/idea.h
+engine_list.o: ../../include/openssl/lhash.h ../../include/openssl/md2.h
+engine_list.o: ../../include/openssl/md4.h ../../include/openssl/md5.h
+engine_list.o: ../../include/openssl/mdc2.h ../../include/openssl/obj_mac.h
+engine_list.o: ../../include/openssl/objects.h
+engine_list.o: ../../include/openssl/opensslconf.h
+engine_list.o: ../../include/openssl/opensslv.h ../../include/openssl/rand.h
+engine_list.o: ../../include/openssl/rc2.h ../../include/openssl/rc4.h
+engine_list.o: ../../include/openssl/rc5.h
+engine_list.o: ../../include/openssl/rijndael-alg-fst.h
+engine_list.o: ../../include/openssl/rijndael.h ../../include/openssl/ripemd.h
+engine_list.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
+engine_list.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+engine_list.o: ../../include/openssl/symhacks.h ../cryptlib.h engine_int.h
+engine_openssl.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+engine_openssl.o: ../../include/openssl/blowfish.h ../../include/openssl/bn.h
+engine_openssl.o: ../../include/openssl/buffer.h ../../include/openssl/cast.h
+engine_openssl.o: ../../include/openssl/crypto.h ../../include/openssl/des.h
+engine_openssl.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h
+engine_openssl.o: ../../include/openssl/dso.h ../../include/openssl/e_os.h
+engine_openssl.o: ../../include/openssl/e_os2.h ../../include/openssl/engine.h
+engine_openssl.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+engine_openssl.o: ../../include/openssl/idea.h ../../include/openssl/lhash.h
+engine_openssl.o: ../../include/openssl/md2.h ../../include/openssl/md4.h
+engine_openssl.o: ../../include/openssl/md5.h ../../include/openssl/mdc2.h
+engine_openssl.o: ../../include/openssl/obj_mac.h
+engine_openssl.o: ../../include/openssl/objects.h
+engine_openssl.o: ../../include/openssl/opensslconf.h
+engine_openssl.o: ../../include/openssl/opensslv.h ../../include/openssl/rand.h
+engine_openssl.o: ../../include/openssl/rc2.h ../../include/openssl/rc4.h
+engine_openssl.o: ../../include/openssl/rc5.h
+engine_openssl.o: ../../include/openssl/rijndael-alg-fst.h
+engine_openssl.o: ../../include/openssl/rijndael.h
+engine_openssl.o: ../../include/openssl/ripemd.h ../../include/openssl/rsa.h
+engine_openssl.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+engine_openssl.o: ../../include/openssl/stack.h
+engine_openssl.o: ../../include/openssl/symhacks.h ../cryptlib.h engine_int.h
+hw_atalla.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+hw_atalla.o: ../../include/openssl/blowfish.h ../../include/openssl/bn.h
+hw_atalla.o: ../../include/openssl/buffer.h ../../include/openssl/cast.h
+hw_atalla.o: ../../include/openssl/crypto.h ../../include/openssl/des.h
+hw_atalla.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h
+hw_atalla.o: ../../include/openssl/dso.h ../../include/openssl/e_os.h
+hw_atalla.o: ../../include/openssl/e_os2.h ../../include/openssl/engine.h
+hw_atalla.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+hw_atalla.o: ../../include/openssl/idea.h ../../include/openssl/lhash.h
+hw_atalla.o: ../../include/openssl/md2.h ../../include/openssl/md4.h
+hw_atalla.o: ../../include/openssl/md5.h ../../include/openssl/mdc2.h
+hw_atalla.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+hw_atalla.o: ../../include/openssl/opensslconf.h
+hw_atalla.o: ../../include/openssl/opensslv.h ../../include/openssl/rand.h
+hw_atalla.o: ../../include/openssl/rc2.h ../../include/openssl/rc4.h
+hw_atalla.o: ../../include/openssl/rc5.h
+hw_atalla.o: ../../include/openssl/rijndael-alg-fst.h
+hw_atalla.o: ../../include/openssl/rijndael.h ../../include/openssl/ripemd.h
+hw_atalla.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
+hw_atalla.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+hw_atalla.o: ../../include/openssl/symhacks.h ../cryptlib.h engine_int.h
+hw_atalla.o: vendor_defns/atalla.h
+hw_cswift.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+hw_cswift.o: ../../include/openssl/blowfish.h ../../include/openssl/bn.h
+hw_cswift.o: ../../include/openssl/buffer.h ../../include/openssl/cast.h
+hw_cswift.o: ../../include/openssl/crypto.h ../../include/openssl/des.h
+hw_cswift.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h
+hw_cswift.o: ../../include/openssl/dso.h ../../include/openssl/e_os.h
+hw_cswift.o: ../../include/openssl/e_os2.h ../../include/openssl/engine.h
+hw_cswift.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+hw_cswift.o: ../../include/openssl/idea.h ../../include/openssl/lhash.h
+hw_cswift.o: ../../include/openssl/md2.h ../../include/openssl/md4.h
+hw_cswift.o: ../../include/openssl/md5.h ../../include/openssl/mdc2.h
+hw_cswift.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+hw_cswift.o: ../../include/openssl/opensslconf.h
+hw_cswift.o: ../../include/openssl/opensslv.h ../../include/openssl/rand.h
+hw_cswift.o: ../../include/openssl/rc2.h ../../include/openssl/rc4.h
+hw_cswift.o: ../../include/openssl/rc5.h
+hw_cswift.o: ../../include/openssl/rijndael-alg-fst.h
+hw_cswift.o: ../../include/openssl/rijndael.h ../../include/openssl/ripemd.h
+hw_cswift.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
+hw_cswift.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+hw_cswift.o: ../../include/openssl/symhacks.h ../cryptlib.h engine_int.h
+hw_cswift.o: vendor_defns/cswift.h
+hw_ncipher.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+hw_ncipher.o: ../../include/openssl/blowfish.h ../../include/openssl/bn.h
+hw_ncipher.o: ../../include/openssl/buffer.h ../../include/openssl/cast.h
+hw_ncipher.o: ../../include/openssl/crypto.h ../../include/openssl/des.h
+hw_ncipher.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h
+hw_ncipher.o: ../../include/openssl/dso.h ../../include/openssl/e_os.h
+hw_ncipher.o: ../../include/openssl/e_os2.h ../../include/openssl/engine.h
+hw_ncipher.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+hw_ncipher.o: ../../include/openssl/idea.h ../../include/openssl/lhash.h
+hw_ncipher.o: ../../include/openssl/md2.h ../../include/openssl/md4.h
+hw_ncipher.o: ../../include/openssl/md5.h ../../include/openssl/mdc2.h
+hw_ncipher.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+hw_ncipher.o: ../../include/openssl/opensslconf.h
+hw_ncipher.o: ../../include/openssl/opensslv.h ../../include/openssl/pem.h
+hw_ncipher.o: ../../include/openssl/pem2.h ../../include/openssl/pkcs7.h
+hw_ncipher.o: ../../include/openssl/rand.h ../../include/openssl/rc2.h
+hw_ncipher.o: ../../include/openssl/rc4.h ../../include/openssl/rc5.h
+hw_ncipher.o: ../../include/openssl/rijndael-alg-fst.h
+hw_ncipher.o: ../../include/openssl/rijndael.h ../../include/openssl/ripemd.h
+hw_ncipher.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
+hw_ncipher.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+hw_ncipher.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+hw_ncipher.o: ../../include/openssl/x509_vfy.h ../cryptlib.h engine_int.h
+hw_ncipher.o: vendor_defns/hwcryptohook.h
+hw_nuron.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+hw_nuron.o: ../../include/openssl/blowfish.h ../../include/openssl/bn.h
+hw_nuron.o: ../../include/openssl/buffer.h ../../include/openssl/cast.h
+hw_nuron.o: ../../include/openssl/crypto.h ../../include/openssl/des.h
+hw_nuron.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h
+hw_nuron.o: ../../include/openssl/dso.h ../../include/openssl/e_os.h
+hw_nuron.o: ../../include/openssl/e_os2.h ../../include/openssl/engine.h
+hw_nuron.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+hw_nuron.o: ../../include/openssl/idea.h ../../include/openssl/lhash.h
+hw_nuron.o: ../../include/openssl/md2.h ../../include/openssl/md4.h
+hw_nuron.o: ../../include/openssl/md5.h ../../include/openssl/mdc2.h
+hw_nuron.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+hw_nuron.o: ../../include/openssl/opensslconf.h
+hw_nuron.o: ../../include/openssl/opensslv.h ../../include/openssl/rand.h
+hw_nuron.o: ../../include/openssl/rc2.h ../../include/openssl/rc4.h
+hw_nuron.o: ../../include/openssl/rc5.h
+hw_nuron.o: ../../include/openssl/rijndael-alg-fst.h
+hw_nuron.o: ../../include/openssl/rijndael.h ../../include/openssl/ripemd.h
+hw_nuron.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
+hw_nuron.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+hw_nuron.o: ../../include/openssl/symhacks.h ../cryptlib.h engine_int.h
diff --git a/crypto/engine/README b/crypto/engine/README
new file mode 100644
index 0000000000..96595e6f35
--- /dev/null
+++ b/crypto/engine/README
@@ -0,0 +1,278 @@
+NOTES, THOUGHTS, and EVERYTHING
+-------------------------------
+
+(1) Concurrency and locking ... I made a change to the ENGINE_free code
+ because I spotted a potential hold-up in proceedings (doing too
+ much inside a lock including calling a callback), there may be
+ other bits like this. What do the speed/optimisation freaks think
+ of this aspect of the code and design? There's lots of locking for
+ manipulation functions and I need that to keep things nice and
+ solid, but this manipulation is mostly (de)initialisation, I would
+ think that most run-time locking is purely in the ENGINE_init and
+ ENGINE_finish calls that might be made when getting handles for
+ RSA (and friends') structures. These would be mostly reference
+ count operations as the functional references should always be 1
+ or greater at run-time to prevent init/deinit thrashing.
+
+(2) nCipher support, via the HWCryptoHook API, is now in the code.
+ Apparently this hasn't been tested too much yet, but it looks
+ good. :-) Atalla support has been added too, but shares a lot in
+ common with Ben's original hooks in bn_exp.c (although it has been
+ ENGINE-ified, and error handling wrapped around it) and it's also
+ had some low-volume testing, so it should be usable.
+
+(3) Of more concern, we need to work out (a) how to put together usable
+ RAND_METHODs for units that just have one "get n or less random
+ bytes" function, (b) we also need to determine how to hook the code
+ in crypto/rand/ to use the ENGINE defaults in a way similar to what
+ has been done in crypto/rsa/, crypto/dsa/, etc.
+
+(4) ENGINE should really grow to encompass more than 3 public key
+ algorithms and randomness gathering. The structure/data level of
+ the engine code is hidden from code outside the crypto/engine/
+ directory so change shouldn't be too viral. More important though
+ is how things should evolve ... this needs thought and discussion.
+
+
+-----------------------------------==*==-----------------------------------
+
+More notes 2000-08-01
+---------------------
+
+Geoff Thorpe, who designed the engine part, wrote a pretty good description
+of the thoughts he had when he built it, good enough to include verbatim here
+(with his permission) -- Richard Levitte
+
+
+Date: Tue, 1 Aug 2000 16:54:08 +0100 (BST)
+From: Geoff Thorpe
+Subject: Re: The thoughts to merge BRANCH_engine into the main trunk are
+ emerging
+
+Hi there,
+
+I'm going to try and do some justice to this, but I'm a little short on
+time and the there is an endless amount that could be discussed on this
+subject. sigh ... please bear with me :-)
+
+> The changes in BRANCH_engine dig deep into the core of OpenSSL, for example
+> into the RSA and RAND routines, adding a level of indirection which is needed
+> to keep the abstraction, as far as I understand. It would be a good thing if
+> those who do play with those things took a look at the changes that have been
+> done in the branch and say out loud how much (or hopefully little) we've made
+> fools of ourselves.
+
+The point here is that the code that has emerged in the BRANCH_engine
+branch was based on some initial requirements of mine that I went in and
+addressed, and Richard has picked up the ball and run with it too. It
+would be really useful to get some review of the approach we've taken, but
+first I think I need to describe as best I can the reasons behind what has
+been done so far, in particular what issues we have tried to address when
+doing this, and what issues we have intentionally (or necessarily) tried
+to avoid.
+
+methods, engines, and evps
+--------------------------
+
+There has been some dicussion, particularly with Steve, about where this
+ENGINE stuff might fit into the conceptual picture as/when we start to
+abstract algorithms a little bit to make the library more extensible. In
+particular, it would desirable to have algorithms (symmetric, hash, pkc,
+etc) abstracted in some way that allows them to be just objects sitting in
+a list (or database) ... it'll just happen that the "DSA" object doesn't
+support encryption whereas the "RSA" object does. This requires a lot of
+consideration to begin to know how to tackle it; in particular how
+encapsulated should these things be? If the objects also understand their
+own ASN1 encodings and what-not, then it would for example be possible to
+add support for elliptic-curve DSA in as a new algorithm and automatically
+have ECC-DSA certificates supported in SSL applications. Possible, but not
+easy. :-)
+
+Whatever, it seems that the way to go (if I've grok'd Steve's comments on
+this in the past) is to amalgamate these things in EVP as is already done
+(I think) for ciphers or hashes (Steve, please correct/elaborate). I
+certainly think something should be done in this direction because right
+now we have different source directories, types, functions, and methods
+for each algorithm - even when conceptually they are very much different
+feathers of the same bird. (This is certainly all true for the public-key
+stuff, and may be partially true for the other parts.)
+
+ENGINE was *not* conceived as a way of solving this, far from it. Nor was
+it conceived as a way of replacing the various "***_METHOD"s. It was
+conceived as an abstraction of a sort of "virtual crypto device". If we
+lived in a world where "EVP_ALGO"s (or something like them) encapsulated
+particular algorithms like RSA,DSA,MD5,RC4,etc, and "***_METHOD"s
+encapsulated interfaces to algorithms (eg. some algo's might support a
+PKC_METHOD, a HASH_METHOD, or a CIPHER_METHOD, who knows?), then I would
+think that ENGINE would encapsulate an implementation of arbitrarily many
+of those algorithms - perhaps as alternatives to existing algorithms
+and/or perhaps as new previously unimplemented algorithms. An ENGINE could
+be used to contain an alternative software implementation, a wrapper for a
+hardware acceleration and/or key-management unit, a comms-wrapper for
+distributing cryptographic operations to remote machines, or any other
+"devices" your imagination can dream up.
+
+However, what has been done in the ENGINE branch so far is nothing more
+than starting to get our toes wet. I had a couple of self-imposed
+requirements when putting the initial abstraction together, and I may have
+already posed these in one form or another on the list, but briefly;
+
+ (i) only bother with public key algorithms for now, and maybe RAND too
+ (motivated by the need to get hardware support going and the fact
+ this was a comparitively easy subset to address to begin with).
+
+ (ii) don't change (if at all possible) the existing crypto code, ie. the
+ implementations, the way the ***_METHODs work, etc.
+
+ (iii) ensure that if no function from the ENGINE code is ever called then
+ things work the way they always did, and there is no memory
+ allocation (otherwise the failure to cleanup would be a problem -
+ this is part of the reason no STACKs were used, the other part of
+ the reason being I found them inappropriate).
+
+ (iv) ensure that all the built-in crypto was encapsulated by one of
+ these "ENGINE"s and that this engine was automatically selected as
+ the default.
+
+ (v) provide the minimum hooking possible in the existing crypto code
+ so that global functions (eg. RSA_public_encrypt) do not need any
+ extra parameter, yet will use whatever the current default ENGINE
+ for that RSA key is, and that the default can be set "per-key"
+ and globally (new keys will assume the global default, and keys
+ without their own default will be operated on using the global
+ default). NB: Try and make (v) conflict as little as possible with
+ (ii). :-)
+
+ (vi) wrap the ENGINE code up in duct tape so you can't even see the
+ corners. Ie. expose no structures at all, just black-box pointers.
+
+ (v) maintain internally a list of ENGINEs on which a calling
+ application can iterate, interrogate, etc. Allow a calling
+ application to hook in new ENGINEs, remove ENGINEs from the list,
+ and enforce uniqueness within the global list of each ENGINE's
+ "unique id".
+
+ (vi) keep reference counts for everything - eg. this includes storing a
+ reference inside each RSA structure to the ENGINE that it uses.
+ This is freed when the RSA structure is destroyed, or has its
+ ENGINE explicitly changed. The net effect needs to be that at any
+ time, it is deterministic to know whether an ENGINE is in use or
+ can be safely removed (or unloaded in the case of the other type
+ of reference) without invalidating function pointers that may or
+ may not be used indavertently in the future. This was actually
+ one of the biggest problems to overcome in the existing OpenSSL
+ code - implementations had always been assumed to be ever-present,
+ so there was no trivial way to get round this.
+
+ (vii) distinguish between structural references and functional
+ references.
+
+A *little* detail
+-----------------
+
+While my mind is on it; I'll illustrate the bit in item (vii). This idea
+turned out to be very handy - the ENGINEs themselves need to be operated
+on and manipulated simply as objects without necessarily trying to
+"enable" them for use. Eg. most host machines will not have the necessary
+hardware or software to support all the engines one might compile into
+OpenSSL, yet it needs to be possible to iterate across the ENGINEs,
+querying their names, properties, etc - all happening in a thread-safe
+manner that uses reference counts (if you imagine two threads iterating
+through a list and one thread removing the ENGINE the other is currently
+looking at - you can see the gotcha waiting to happen). For all of this,
+*structural references* are used and operate much like the other reference
+counts in OpenSSL.
+
+The other kind of reference count is for *functional* references - these
+indicate a reference on which the caller can actually assume the
+particular ENGINE to be initialised and usable to perform the operations
+it implements. Any increment or decrement of the functional reference
+count automatically invokes a corresponding change in the structural
+reference count, as it is fairly obvious that a functional reference is a
+restricted case of a structural reference. So struct_ref >= funct_ref at
+all times. NB: functional references are usually obtained by a call to
+ENGINE_init(), but can also be created implicitly by calls that require a
+new functional reference to be created, eg. ENGINE_set_default(). Either
+way the only time the underlying ENGINE's "init" function is really called
+is when the (functional) reference count increases to 1, similarly the
+underlying "finish" handler is only called as the count goes down to 0.
+The effect of this, for example, is that if you set the default ENGINE for
+RSA operations to be "cswift", then its functional reference count will
+already be at least 1 so the CryptoSwift shared-library and the card will
+stay loaded and initialised until such time as all RSA keys using the
+cswift ENGINE are changed or destroyed and the default ENGINE for RSA
+operations has been changed. This prevents repeated thrashing of init and
+finish handling if the count keeps getting down as far as zero.
+
+Otherwise, the way the ENGINE code has been put together I think pretty
+much reflects the above points. The reason for the ENGINE structure having
+individual RSA_METHOD, DSA_METHOD, etc pointers is simply that it was the
+easiest way to go about things for now, to hook it all into the raw
+RSA,DSA,etc code, and I was trying to the keep the structure invisible
+anyway so that the way this is internally managed could be easily changed
+later on when we start to work out what's to be done about these other
+abstractions.
+
+Down the line, if some EVP-based technique emerges for adequately
+encapsulating algorithms and all their various bits and pieces, then I can
+imagine that "ENGINE" would turn into a reference-counting database of
+these EVP things, of which the default "openssl" ENGINE would be the
+library's own object database of pre-built software implemented algorithms
+(and such). It would also be cool to see the idea of "METHOD"s detached
+from the algorithms themselves ... so RSA, DSA, ElGamal, etc can all
+expose essentially the same METHOD (aka interface), which would include
+any querying/flagging stuff to identify what the algorithm can/can't do,
+its name, and other stuff like max/min block sizes, key sizes, etc. This
+would result in ENGINE similarly detaching its internal database of
+algorithm implementations from the function definitions that return
+interfaces to them. I think ...
+
+As for DSOs etc. Well the DSO code is pretty handy (but could be made much
+more so) for loading vendor's driver-libraries and talking to them in some
+generic way, but right now there's still big problems associated with
+actually putting OpenSSL code (ie. new ENGINEs, or anything else for that
+matter) in dynamically loadable libraries. These problems won't go away in
+a hurry so I don't think we should expect to have any kind of
+shared-library extensions any time soon - but solving the problems is a
+good thing to aim for, and would as a side-effect probably help make
+OpenSSL more usable as a shared-library itself (looking at the things
+needed to do this will show you why).
+
+One of the problems is that if you look at any of the ENGINE
+implementations, eg. hw_cswift.c or hw_ncipher.c, you'll see how it needs
+a variety of functionality and definitions from various areas of OpenSSL,
+including crypto/bn/, crypto/err/, crypto/ itself (locking for example),
+crypto/dso/, crypto/engine/, crypto/rsa, etc etc etc. So if similar code
+were to be suctioned off into shared libraries, the shared libraries would
+either have to duplicate all the definitions and code and avoid loader
+conflicts, or OpenSSL would have to somehow expose all that functionality
+to the shared-library. If this isn't a big enough problem, the issue of
+binary compatibility will be - anyone writing Apache modules can tell you
+that (Ralf? Ben? :-). However, I don't think OpenSSL would need to be
+quite so forgiving as Apache should be, so OpenSSL could simply tell its
+version to the DSO and leave the DSO with the problem of deciding whether
+to proceed or bail out for fear of binary incompatibilities.
+
+Certainly one thing that would go a long way to addressing this is to
+embark on a bit of an opaqueness mission. I've set the ENGINE code up with
+this in mind - it's so draconian that even to declare your own ENGINE, you
+have to get the engine code to create the underlying ENGINE structure, and
+then feed in the new ENGINE's function/method pointers through various
+"set" functions. The more of the code that takes on such a black-box
+approach, the more of the code that will be (a) easy to expose to shared
+libraries that need it, and (b) easy to expose to applications wanting to
+use OpenSSL itself as a shared-library. From my own explorations in
+OpenSSL, the biggest leviathan I've seen that is a problem in this respect
+is the BIGNUM code. Trying to "expose" the bignum code through any kind of
+organised "METHODs", let alone do all the necessary bignum operations
+solely through functions rather than direct access to the structures and
+macros, will be a massive pain in the "r"s.
+
+Anyway, I'm done for now - hope it was readable. Thoughts?
+
+Cheers,
+Geoff
+
+
+-----------------------------------==*==-----------------------------------
+
diff --git a/crypto/engine/engine.h b/crypto/engine/engine.h
new file mode 100644
index 0000000000..78cf41c378
--- /dev/null
+++ b/crypto/engine/engine.h
@@ -0,0 +1,403 @@
+/* openssl/engine.h */
+/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
+ * project 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 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).
+ *
+ */
+
+#ifndef HEADER_ENGINE_H
+#define HEADER_ENGINE_H
+
+#include <openssl/bn.h>
+#include <openssl/rsa.h>
+#include <openssl/dsa.h>
+#include <openssl/dh.h>
+#include <openssl/rand.h>
+#include <openssl/evp.h>
+#include <openssl/symhacks.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* These flags are used to control combinations of algorithm (methods)
+ * by bitwise "OR"ing. */
+#define ENGINE_METHOD_RSA (unsigned int)0x0001
+#define ENGINE_METHOD_DSA (unsigned int)0x0002
+#define ENGINE_METHOD_DH (unsigned int)0x0004
+#define ENGINE_METHOD_RAND (unsigned int)0x0008
+#define ENGINE_METHOD_BN_MOD_EXP (unsigned int)0x0010
+#define ENGINE_METHOD_BN_MOD_EXP_CRT (unsigned int)0x0020
+/* Obvious all-or-nothing cases. */
+#define ENGINE_METHOD_ALL (unsigned int)0xFFFF
+#define ENGINE_METHOD_NONE (unsigned int)0x0000
+
+/* These flags are used to tell the ctrl function what should be done.
+ * All command numbers are shared between all engines, even if some don't
+ * make sense to some engines. In such a case, they do nothing but return
+ * the error ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED. */
+#define ENGINE_CTRL_SET_LOGSTREAM 1
+#define ENGINE_CTRL_SET_PASSWORD_CALLBACK 2
+/* Flags specific to the nCipher "chil" engine */
+#define ENGINE_CTRL_CHIL_SET_FORKCHECK 100
+ /* Depending on the value of the (long)i argument, this sets or
+ * unsets the SimpleForkCheck flag in the CHIL API to enable or
+ * disable checking and workarounds for applications that fork().
+ */
+#define ENGINE_CTRL_CHIL_NO_LOCKING 101
+ /* This prevents the initialisation function from providing mutex
+ * callbacks to the nCipher library. */
+
+/* As we're missing a BIGNUM_METHOD, we need a couple of locally
+ * defined function types that engines can implement. */
+
+#ifndef HEADER_ENGINE_INT_H
+/* mod_exp operation, calculates; r = a ^ p mod m
+ * NB: ctx can be NULL, but if supplied, the implementation may use
+ * it if it wishes. */
+typedef int (*BN_MOD_EXP)(BIGNUM *r, BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *m, BN_CTX *ctx);
+
+/* private key operation for RSA, provided seperately in case other
+ * RSA implementations wish to use it. */
+typedef int (*BN_MOD_EXP_CRT)(BIGNUM *r, BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *q, const BIGNUM *dmp1, const BIGNUM *dmq1,
+ const BIGNUM *iqmp, BN_CTX *ctx);
+
+/* Generic function pointer */
+typedef void (*ENGINE_GEN_FUNC_PTR)();
+/* Generic function pointer taking no arguments */
+typedef void (*ENGINE_GEN_INT_FUNC_PTR)(void);
+/* Specific control function pointer */
+typedef int (*ENGINE_CTRL_FUNC_PTR)(int cmd, long i, void *p, void (*f)());
+
+/* The list of "engine" types is a static array of (const ENGINE*)
+ * pointers (not dynamic because static is fine for now and we otherwise
+ * have to hook an appropriate load/unload function in to initialise and
+ * cleanup). */
+typedef struct engine_st ENGINE;
+#endif
+
+/* STRUCTURE functions ... all of these functions deal with pointers to
+ * ENGINE structures where the pointers have a "structural reference".
+ * This means that their reference is to allow access to the structure
+ * but it does not imply that the structure is functional. To simply
+ * increment or decrement the structural reference count, use ENGINE_new
+ * and ENGINE_free. NB: This is not required when iterating using
+ * ENGINE_get_next as it will automatically decrement the structural
+ * reference count of the "current" ENGINE and increment the structural
+ * reference count of the ENGINE it returns (unless it is NULL). */
+
+/* Get the first/last "ENGINE" type available. */
+ENGINE *ENGINE_get_first(void);
+ENGINE *ENGINE_get_last(void);
+/* Iterate to the next/previous "ENGINE" type (NULL = end of the list). */
+ENGINE *ENGINE_get_next(ENGINE *e);
+ENGINE *ENGINE_get_prev(ENGINE *e);
+/* Add another "ENGINE" type into the array. */
+int ENGINE_add(ENGINE *e);
+/* Remove an existing "ENGINE" type from the array. */
+int ENGINE_remove(ENGINE *e);
+/* Retrieve an engine from the list by its unique "id" value. */
+ENGINE *ENGINE_by_id(const char *id);
+
+/* These functions are useful for manufacturing new ENGINE
+ * structures. They don't address reference counting at all -
+ * one uses them to populate an ENGINE structure with personalised
+ * implementations of things prior to using it directly or adding
+ * it to the builtin ENGINE list in OpenSSL. These are also here
+ * so that the ENGINE structure doesn't have to be exposed and
+ * break binary compatibility!
+ *
+ * NB: I'm changing ENGINE_new to force the ENGINE structure to
+ * be allocated from within OpenSSL. See the comment for
+ * ENGINE_get_struct_size().
+ */
+#if 0
+ENGINE *ENGINE_new(ENGINE *e);
+#else
+ENGINE *ENGINE_new(void);
+#endif
+int ENGINE_free(ENGINE *e);
+int ENGINE_set_id(ENGINE *e, const char *id);
+int ENGINE_set_name(ENGINE *e, const char *name);
+int ENGINE_set_RSA(ENGINE *e, RSA_METHOD *rsa_meth);
+int ENGINE_set_DSA(ENGINE *e, DSA_METHOD *dsa_meth);
+int ENGINE_set_DH(ENGINE *e, DH_METHOD *dh_meth);
+int ENGINE_set_RAND(ENGINE *e, RAND_METHOD *rand_meth);
+int ENGINE_set_BN_mod_exp(ENGINE *e, BN_MOD_EXP bn_mod_exp);
+int ENGINE_set_BN_mod_exp_crt(ENGINE *e, BN_MOD_EXP_CRT bn_mod_exp_crt);
+int ENGINE_set_init_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR init_f);
+int ENGINE_set_finish_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR finish_f);
+int ENGINE_set_ctrl_function(ENGINE *e, ENGINE_CTRL_FUNC_PTR ctrl_f);
+
+/* These return values from within the ENGINE structure. These can
+ * be useful with functional references as well as structural
+ * references - it depends which you obtained. Using the result
+ * for functional purposes if you only obtained a structural
+ * reference may be problematic! */
+const char *ENGINE_get_id(ENGINE *e);
+const char *ENGINE_get_name(ENGINE *e);
+RSA_METHOD *ENGINE_get_RSA(ENGINE *e);
+DSA_METHOD *ENGINE_get_DSA(ENGINE *e);
+DH_METHOD *ENGINE_get_DH(ENGINE *e);
+RAND_METHOD *ENGINE_get_RAND(ENGINE *e);
+BN_MOD_EXP ENGINE_get_BN_mod_exp(ENGINE *e);
+BN_MOD_EXP_CRT ENGINE_get_BN_mod_exp_crt(ENGINE *e);
+ENGINE_GEN_INT_FUNC_PTR ENGINE_get_init_function(ENGINE *e);
+ENGINE_GEN_INT_FUNC_PTR ENGINE_get_finish_function(ENGINE *e);
+ENGINE_CTRL_FUNC_PTR ENGINE_get_ctrl_function(ENGINE *e);
+
+/* ENGINE_new is normally passed a NULL in the first parameter because
+ * the calling code doesn't have access to the definition of the ENGINE
+ * structure (for good reason). However, if the caller wishes to use
+ * its own memory allocation or use a static array, the following call
+ * should be used to check the amount of memory the ENGINE structure
+ * will occupy. This will make the code more future-proof.
+ *
+ * NB: I'm "#if 0"-ing this out because it's better to force the use of
+ * internally allocated memory. See similar change in ENGINE_new().
+ */
+#if 0
+int ENGINE_get_struct_size(void);
+#endif
+
+/* FUNCTIONAL functions. These functions deal with ENGINE structures
+ * that have (or will) be initialised for use. Broadly speaking, the
+ * structural functions are useful for iterating the list of available
+ * engine types, creating new engine types, and other "list" operations.
+ * These functions actually deal with ENGINEs that are to be used. As
+ * such these functions can fail (if applicable) when particular
+ * engines are unavailable - eg. if a hardware accelerator is not
+ * attached or not functioning correctly. Each ENGINE has 2 reference
+ * counts; structural and functional. Every time a functional reference
+ * is obtained or released, a corresponding structural reference is
+ * automatically obtained or released too. */
+
+/* Initialise a engine type for use (or up its reference count if it's
+ * already in use). This will fail if the engine is not currently
+ * operational and cannot initialise. */
+int ENGINE_init(ENGINE *e);
+/* Free a functional reference to a engine type. This does not require
+ * a corresponding call to ENGINE_free as it also releases a structural
+ * reference. */
+int ENGINE_finish(ENGINE *e);
+/* Send control parametrised commands to the engine. The possibilities
+ * to send down an integer, a pointer to data or a function pointer are
+ * provided. Any of the parameters may or may not be NULL, depending
+ * on the command number */
+/* WARNING: This is currently experimental and may change radically! */
+int ENGINE_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)());
+
+/* The following functions handle keys that are stored in some secondary
+ * location, handled by the engine. The storage may be on a card or
+ * whatever. */
+EVP_PKEY *ENGINE_load_private_key(ENGINE *e, const char *key_id,
+ const char *passphrase);
+EVP_PKEY *ENGINE_load_public_key(ENGINE *e, const char *key_id,
+ const char *passphrase);
+
+/* This returns a pointer for the current ENGINE structure that
+ * is (by default) performing any RSA operations. The value returned
+ * is an incremented reference, so it should be free'd (ENGINE_finish)
+ * before it is discarded. */
+ENGINE *ENGINE_get_default_RSA(void);
+/* Same for the other "methods" */
+ENGINE *ENGINE_get_default_DSA(void);
+ENGINE *ENGINE_get_default_DH(void);
+ENGINE *ENGINE_get_default_RAND(void);
+ENGINE *ENGINE_get_default_BN_mod_exp(void);
+ENGINE *ENGINE_get_default_BN_mod_exp_crt(void);
+
+/* This sets a new default ENGINE structure for performing RSA
+ * operations. If the result is non-zero (success) then the ENGINE
+ * structure will have had its reference count up'd so the caller
+ * should still free their own reference 'e'. */
+int ENGINE_set_default_RSA(ENGINE *e);
+/* Same for the other "methods" */
+int ENGINE_set_default_DSA(ENGINE *e);
+int ENGINE_set_default_DH(ENGINE *e);
+int ENGINE_set_default_RAND(ENGINE *e);
+int ENGINE_set_default_BN_mod_exp(ENGINE *e);
+int ENGINE_set_default_BN_mod_exp_crt(ENGINE *e);
+
+/* The combination "set" - the flags are bitwise "OR"d from the
+ * ENGINE_METHOD_*** defines above. */
+int ENGINE_set_default(ENGINE *e, unsigned int flags);
+
+/* Obligatory error function. */
+void ERR_load_ENGINE_strings(void);
+
+/*
+ * Error codes for all engine functions. NB: We use "generic"
+ * function names instead of per-implementation ones because this
+ * levels the playing field for externally implemented bootstrapped
+ * support code. As the filename and line number is included, it's
+ * more important to indicate the type of function, so that
+ * bootstrapped code (that can't easily add its own errors in) can
+ * use the same error codes too.
+ */
+
+/* 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.
+ */
+
+/* Error codes for the ENGINE functions. */
+
+/* Function codes. */
+#define ENGINE_F_ATALLA_FINISH 135
+#define ENGINE_F_ATALLA_INIT 136
+#define ENGINE_F_ATALLA_MOD_EXP 137
+#define ENGINE_F_ATALLA_RSA_MOD_EXP 138
+#define ENGINE_F_CSWIFT_DSA_SIGN 133
+#define ENGINE_F_CSWIFT_DSA_VERIFY 134
+#define ENGINE_F_CSWIFT_FINISH 100
+#define ENGINE_F_CSWIFT_INIT 101
+#define ENGINE_F_CSWIFT_MOD_EXP 102
+#define ENGINE_F_CSWIFT_MOD_EXP_CRT 103
+#define ENGINE_F_CSWIFT_RSA_MOD_EXP 104
+#define ENGINE_F_ENGINE_ADD 105
+#define ENGINE_F_ENGINE_BY_ID 106
+#define ENGINE_F_ENGINE_CTRL 142
+#define ENGINE_F_ENGINE_FINISH 107
+#define ENGINE_F_ENGINE_FREE 108
+#define ENGINE_F_ENGINE_GET_BN_MOD_EXP 109
+#define ENGINE_F_ENGINE_GET_BN_MOD_EXP_CRT 110
+#define ENGINE_F_ENGINE_GET_CTRL_FUNCTION 144
+#define ENGINE_F_ENGINE_GET_DH 111
+#define ENGINE_F_ENGINE_GET_DSA 112
+#define ENGINE_F_ENGINE_GET_FINISH_FUNCTION 145
+#define ENGINE_F_ENGINE_GET_ID 113
+#define ENGINE_F_ENGINE_GET_INIT_FUNCTION 146
+#define ENGINE_F_ENGINE_GET_NAME 114
+#define ENGINE_F_ENGINE_GET_NEXT 115
+#define ENGINE_F_ENGINE_GET_PREV 116
+#define ENGINE_F_ENGINE_GET_RAND 117
+#define ENGINE_F_ENGINE_GET_RSA 118
+#define ENGINE_F_ENGINE_INIT 119
+#define ENGINE_F_ENGINE_LIST_ADD 120
+#define ENGINE_F_ENGINE_LIST_REMOVE 121
+#define ENGINE_F_ENGINE_LOAD_PRIVATE_KEY 150
+#define ENGINE_F_ENGINE_LOAD_PUBLIC_KEY 151
+#define ENGINE_F_ENGINE_NEW 122
+#define ENGINE_F_ENGINE_REMOVE 123
+#define ENGINE_F_ENGINE_SET_BN_MOD_EXP 124
+#define ENGINE_F_ENGINE_SET_BN_MOD_EXP_CRT 125
+#define ENGINE_F_ENGINE_SET_CTRL_FUNCTION 147
+#define ENGINE_F_ENGINE_SET_DEFAULT_TYPE 126
+#define ENGINE_F_ENGINE_SET_DH 127
+#define ENGINE_F_ENGINE_SET_DSA 128
+#define ENGINE_F_ENGINE_SET_FINISH_FUNCTION 148
+#define ENGINE_F_ENGINE_SET_ID 129
+#define ENGINE_F_ENGINE_SET_INIT_FUNCTION 149
+#define ENGINE_F_ENGINE_SET_NAME 130
+#define ENGINE_F_ENGINE_SET_RAND 131
+#define ENGINE_F_ENGINE_SET_RSA 132
+#define ENGINE_F_ENGINE_UNLOAD_KEY 152
+#define ENGINE_F_HWCRHK_CTRL 143
+#define ENGINE_F_HWCRHK_FINISH 135
+#define ENGINE_F_HWCRHK_GET_PASS 155
+#define ENGINE_F_HWCRHK_INIT 136
+#define ENGINE_F_HWCRHK_LOAD_PRIVKEY 153
+#define ENGINE_F_HWCRHK_LOAD_PUBKEY 154
+#define ENGINE_F_HWCRHK_MOD_EXP 137
+#define ENGINE_F_HWCRHK_MOD_EXP_CRT 138
+#define ENGINE_F_HWCRHK_RAND_BYTES 139
+#define ENGINE_F_HWCRHK_RSA_MOD_EXP 140
+#define ENGINE_F_LOG_MESSAGE 141
+#define ENGINE_F_NURON_FINISH 157
+#define ENGINE_F_NURON_INIT 156
+#define ENGINE_F_NURON_MOD_EXP 158
+
+/* Reason codes. */
+#define ENGINE_R_ALREADY_LOADED 100
+#define ENGINE_R_BIO_WAS_FREED 121
+#define ENGINE_R_BN_CTX_FULL 101
+#define ENGINE_R_BN_EXPAND_FAIL 102
+#define ENGINE_R_CHIL_ERROR 123
+#define ENGINE_R_CONFLICTING_ENGINE_ID 103
+#define ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED 119
+#define ENGINE_R_DSO_FAILURE 104
+#define ENGINE_R_DSO_FUNCTION_NOT_FOUND 131
+#define ENGINE_R_DSO_NOT_FOUND 132
+#define ENGINE_R_ENGINE_IS_NOT_IN_LIST 105
+#define ENGINE_R_FAILED_LOADING_PRIVATE_KEY 128
+#define ENGINE_R_FAILED_LOADING_PUBLIC_KEY 129
+#define ENGINE_R_FINISH_FAILED 106
+#define ENGINE_R_GET_HANDLE_FAILED 107
+#define ENGINE_R_ID_OR_NAME_MISSING 108
+#define ENGINE_R_INIT_FAILED 109
+#define ENGINE_R_INTERNAL_LIST_ERROR 110
+#define ENGINE_R_MISSING_KEY_COMPONENTS 111
+#define ENGINE_R_NOT_INITIALISED 117
+#define ENGINE_R_NOT_LOADED 112
+#define ENGINE_R_NO_CALLBACK 127
+#define ENGINE_R_NO_CONTROL_FUNCTION 120
+#define ENGINE_R_NO_KEY 124
+#define ENGINE_R_NO_LOAD_FUNCTION 125
+#define ENGINE_R_NO_REFERENCE 130
+#define ENGINE_R_NO_SUCH_ENGINE 116
+#define ENGINE_R_NO_UNLOAD_FUNCTION 126
+#define ENGINE_R_PROVIDE_PARAMETERS 113
+#define ENGINE_R_REQUEST_FAILED 114
+#define ENGINE_R_REQUEST_FALLBACK 118
+#define ENGINE_R_SIZE_TOO_LARGE_OR_TOO_SMALL 122
+#define ENGINE_R_UNIT_FAILURE 115
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+
diff --git a/crypto/engine/engine_err.c b/crypto/engine/engine_err.c
new file mode 100644
index 0000000000..44c4fb9dde
--- /dev/null
+++ b/crypto/engine/engine_err.c
@@ -0,0 +1,188 @@
+/* crypto/engine/engine_err.c */
+/* ====================================================================
+ * Copyright (c) 1999 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).
+ *
+ */
+
+/* NOTE: this file was auto generated by the mkerr.pl script: any changes
+ * made to it will be overwritten when the script next updates this file,
+ * only reason strings will be preserved.
+ */
+
+#include <stdio.h>
+#include <openssl/err.h>
+#include <openssl/engine.h>
+
+/* BEGIN ERROR CODES */
+#ifndef NO_ERR
+static ERR_STRING_DATA ENGINE_str_functs[]=
+ {
+{ERR_PACK(0,ENGINE_F_ATALLA_FINISH,0), "ATALLA_FINISH"},
+{ERR_PACK(0,ENGINE_F_ATALLA_INIT,0), "ATALLA_INIT"},
+{ERR_PACK(0,ENGINE_F_ATALLA_MOD_EXP,0), "ATALLA_MOD_EXP"},
+{ERR_PACK(0,ENGINE_F_ATALLA_RSA_MOD_EXP,0), "ATALLA_RSA_MOD_EXP"},
+{ERR_PACK(0,ENGINE_F_CSWIFT_DSA_SIGN,0), "CSWIFT_DSA_SIGN"},
+{ERR_PACK(0,ENGINE_F_CSWIFT_DSA_VERIFY,0), "CSWIFT_DSA_VERIFY"},
+{ERR_PACK(0,ENGINE_F_CSWIFT_FINISH,0), "CSWIFT_FINISH"},
+{ERR_PACK(0,ENGINE_F_CSWIFT_INIT,0), "CSWIFT_INIT"},
+{ERR_PACK(0,ENGINE_F_CSWIFT_MOD_EXP,0), "CSWIFT_MOD_EXP"},
+{ERR_PACK(0,ENGINE_F_CSWIFT_MOD_EXP_CRT,0), "CSWIFT_MOD_EXP_CRT"},
+{ERR_PACK(0,ENGINE_F_CSWIFT_RSA_MOD_EXP,0), "CSWIFT_RSA_MOD_EXP"},
+{ERR_PACK(0,ENGINE_F_ENGINE_ADD,0), "ENGINE_add"},
+{ERR_PACK(0,ENGINE_F_ENGINE_BY_ID,0), "ENGINE_by_id"},
+{ERR_PACK(0,ENGINE_F_ENGINE_CTRL,0), "ENGINE_ctrl"},
+{ERR_PACK(0,ENGINE_F_ENGINE_FINISH,0), "ENGINE_finish"},
+{ERR_PACK(0,ENGINE_F_ENGINE_FREE,0), "ENGINE_free"},
+{ERR_PACK(0,ENGINE_F_ENGINE_GET_BN_MOD_EXP,0), "ENGINE_get_BN_mod_exp"},
+{ERR_PACK(0,ENGINE_F_ENGINE_GET_BN_MOD_EXP_CRT,0), "ENGINE_get_BN_mod_exp_crt"},
+{ERR_PACK(0,ENGINE_F_ENGINE_GET_CTRL_FUNCTION,0), "ENGINE_get_ctrl_function"},
+{ERR_PACK(0,ENGINE_F_ENGINE_GET_DH,0), "ENGINE_get_DH"},
+{ERR_PACK(0,ENGINE_F_ENGINE_GET_DSA,0), "ENGINE_get_DSA"},
+{ERR_PACK(0,ENGINE_F_ENGINE_GET_FINISH_FUNCTION,0), "ENGINE_get_finish_function"},
+{ERR_PACK(0,ENGINE_F_ENGINE_GET_ID,0), "ENGINE_get_id"},
+{ERR_PACK(0,ENGINE_F_ENGINE_GET_INIT_FUNCTION,0), "ENGINE_get_init_function"},
+{ERR_PACK(0,ENGINE_F_ENGINE_GET_NAME,0), "ENGINE_get_name"},
+{ERR_PACK(0,ENGINE_F_ENGINE_GET_NEXT,0), "ENGINE_get_next"},
+{ERR_PACK(0,ENGINE_F_ENGINE_GET_PREV,0), "ENGINE_get_prev"},
+{ERR_PACK(0,ENGINE_F_ENGINE_GET_RAND,0), "ENGINE_get_RAND"},
+{ERR_PACK(0,ENGINE_F_ENGINE_GET_RSA,0), "ENGINE_get_RSA"},
+{ERR_PACK(0,ENGINE_F_ENGINE_INIT,0), "ENGINE_init"},
+{ERR_PACK(0,ENGINE_F_ENGINE_LIST_ADD,0), "ENGINE_LIST_ADD"},
+{ERR_PACK(0,ENGINE_F_ENGINE_LIST_REMOVE,0), "ENGINE_LIST_REMOVE"},
+{ERR_PACK(0,ENGINE_F_ENGINE_LOAD_PRIVATE_KEY,0), "ENGINE_load_private_key"},
+{ERR_PACK(0,ENGINE_F_ENGINE_LOAD_PUBLIC_KEY,0), "ENGINE_load_public_key"},
+{ERR_PACK(0,ENGINE_F_ENGINE_NEW,0), "ENGINE_new"},
+{ERR_PACK(0,ENGINE_F_ENGINE_REMOVE,0), "ENGINE_remove"},
+{ERR_PACK(0,ENGINE_F_ENGINE_SET_BN_MOD_EXP,0), "ENGINE_set_BN_mod_exp"},
+{ERR_PACK(0,ENGINE_F_ENGINE_SET_BN_MOD_EXP_CRT,0), "ENGINE_set_BN_mod_exp_crt"},
+{ERR_PACK(0,ENGINE_F_ENGINE_SET_CTRL_FUNCTION,0), "ENGINE_set_ctrl_function"},
+{ERR_PACK(0,ENGINE_F_ENGINE_SET_DEFAULT_TYPE,0), "ENGINE_SET_DEFAULT_TYPE"},
+{ERR_PACK(0,ENGINE_F_ENGINE_SET_DH,0), "ENGINE_set_DH"},
+{ERR_PACK(0,ENGINE_F_ENGINE_SET_DSA,0), "ENGINE_set_DSA"},
+{ERR_PACK(0,ENGINE_F_ENGINE_SET_FINISH_FUNCTION,0), "ENGINE_set_finish_function"},
+{ERR_PACK(0,ENGINE_F_ENGINE_SET_ID,0), "ENGINE_set_id"},
+{ERR_PACK(0,ENGINE_F_ENGINE_SET_INIT_FUNCTION,0), "ENGINE_set_init_function"},
+{ERR_PACK(0,ENGINE_F_ENGINE_SET_NAME,0), "ENGINE_set_name"},
+{ERR_PACK(0,ENGINE_F_ENGINE_SET_RAND,0), "ENGINE_set_RAND"},
+{ERR_PACK(0,ENGINE_F_ENGINE_SET_RSA,0), "ENGINE_set_RSA"},
+{ERR_PACK(0,ENGINE_F_ENGINE_UNLOAD_KEY,0), "ENGINE_UNLOAD_KEY"},
+{ERR_PACK(0,ENGINE_F_HWCRHK_CTRL,0), "HWCRHK_CTRL"},
+{ERR_PACK(0,ENGINE_F_HWCRHK_FINISH,0), "HWCRHK_FINISH"},
+{ERR_PACK(0,ENGINE_F_HWCRHK_GET_PASS,0), "HWCRHK_GET_PASS"},
+{ERR_PACK(0,ENGINE_F_HWCRHK_INIT,0), "HWCRHK_INIT"},
+{ERR_PACK(0,ENGINE_F_HWCRHK_LOAD_PRIVKEY,0), "HWCRHK_LOAD_PRIVKEY"},
+{ERR_PACK(0,ENGINE_F_HWCRHK_LOAD_PUBKEY,0), "HWCRHK_LOAD_PUBKEY"},
+{ERR_PACK(0,ENGINE_F_HWCRHK_MOD_EXP,0), "HWCRHK_MOD_EXP"},
+{ERR_PACK(0,ENGINE_F_HWCRHK_MOD_EXP_CRT,0), "HWCRHK_MOD_EXP_CRT"},
+{ERR_PACK(0,ENGINE_F_HWCRHK_RAND_BYTES,0), "HWCRHK_RAND_BYTES"},
+{ERR_PACK(0,ENGINE_F_HWCRHK_RSA_MOD_EXP,0), "HWCRHK_RSA_MOD_EXP"},
+{ERR_PACK(0,ENGINE_F_LOG_MESSAGE,0), "LOG_MESSAGE"},
+{ERR_PACK(0,ENGINE_F_NURON_FINISH,0), "NURON_FINISH"},
+{ERR_PACK(0,ENGINE_F_NURON_INIT,0), "NURON_INIT"},
+{ERR_PACK(0,ENGINE_F_NURON_MOD_EXP,0), "NURON_MOD_EXP"},
+{0,NULL}
+ };
+
+static ERR_STRING_DATA ENGINE_str_reasons[]=
+ {
+{ENGINE_R_ALREADY_LOADED ,"already loaded"},
+{ENGINE_R_BIO_WAS_FREED ,"bio was freed"},
+{ENGINE_R_BN_CTX_FULL ,"BN_CTX full"},
+{ENGINE_R_BN_EXPAND_FAIL ,"bn_expand fail"},
+{ENGINE_R_CHIL_ERROR ,"chil error"},
+{ENGINE_R_CONFLICTING_ENGINE_ID ,"conflicting engine id"},
+{ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED ,"ctrl command not implemented"},
+{ENGINE_R_DSO_FAILURE ,"DSO failure"},
+{ENGINE_R_DSO_FUNCTION_NOT_FOUND ,"dso function not found"},
+{ENGINE_R_DSO_NOT_FOUND ,"dso not found"},
+{ENGINE_R_ENGINE_IS_NOT_IN_LIST ,"engine is not in the list"},
+{ENGINE_R_FAILED_LOADING_PRIVATE_KEY ,"failed loading private key"},
+{ENGINE_R_FAILED_LOADING_PUBLIC_KEY ,"failed loading public key"},
+{ENGINE_R_FINISH_FAILED ,"finish failed"},
+{ENGINE_R_GET_HANDLE_FAILED ,"could not obtain hardware handle"},
+{ENGINE_R_ID_OR_NAME_MISSING ,"'id' or 'name' missing"},
+{ENGINE_R_INIT_FAILED ,"init failed"},
+{ENGINE_R_INTERNAL_LIST_ERROR ,"internal list error"},
+{ENGINE_R_MISSING_KEY_COMPONENTS ,"missing key components"},
+{ENGINE_R_NOT_INITIALISED ,"not initialised"},
+{ENGINE_R_NOT_LOADED ,"not loaded"},
+{ENGINE_R_NO_CALLBACK ,"no callback"},
+{ENGINE_R_NO_CONTROL_FUNCTION ,"no control function"},
+{ENGINE_R_NO_KEY ,"no key"},
+{ENGINE_R_NO_LOAD_FUNCTION ,"no load function"},
+{ENGINE_R_NO_REFERENCE ,"no reference"},
+{ENGINE_R_NO_SUCH_ENGINE ,"no such engine"},
+{ENGINE_R_NO_UNLOAD_FUNCTION ,"no unload function"},
+{ENGINE_R_PROVIDE_PARAMETERS ,"provide parameters"},
+{ENGINE_R_REQUEST_FAILED ,"request failed"},
+{ENGINE_R_REQUEST_FALLBACK ,"request fallback"},
+{ENGINE_R_SIZE_TOO_LARGE_OR_TOO_SMALL ,"size too large or too small"},
+{ENGINE_R_UNIT_FAILURE ,"unit failure"},
+{0,NULL}
+ };
+
+#endif
+
+void ERR_load_ENGINE_strings(void)
+ {
+ static int init=1;
+
+ if (init)
+ {
+ init=0;
+#ifndef NO_ERR
+ ERR_load_strings(ERR_LIB_ENGINE,ENGINE_str_functs);
+ ERR_load_strings(ERR_LIB_ENGINE,ENGINE_str_reasons);
+#endif
+
+ }
+ }
diff --git a/crypto/engine/engine_int.h b/crypto/engine/engine_int.h
new file mode 100644
index 0000000000..d4aa8faca2
--- /dev/null
+++ b/crypto/engine/engine_int.h
@@ -0,0 +1,164 @@
+/* crypto/engine/engine_int.h */
+/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
+ * project 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 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).
+ *
+ */
+
+#ifndef HEADER_ENGINE_INT_H
+#define HEADER_ENGINE_INT_H
+
+#include <openssl/rsa.h>
+#include <openssl/dsa.h>
+#include <openssl/dh.h>
+#include <openssl/rand.h>
+#include <openssl/bn.h>
+#include <openssl/evp.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Bitwise OR-able values for the "flags" variable in ENGINE. */
+#define ENGINE_FLAGS_MALLOCED 0x0001
+
+#ifndef HEADER_ENGINE_H
+/* Regrettably, we need to reproduce the "BN" function types here
+ * because there is no such "BIGNUM_METHOD" as there is with RSA,
+ * DSA, etc. We do this so that we don't have a case where engine.h
+ * and engine_int.h conflict with each other. */
+typedef int (*BN_MOD_EXP)(BIGNUM *r, BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *m, BN_CTX *ctx);
+
+/* private key operation for RSA, provided seperately in case other
+ * RSA implementations wish to use it. */
+typedef int (*BN_MOD_EXP_CRT)(BIGNUM *r, BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *q, const BIGNUM *dmp1, const BIGNUM *dmq1,
+ const BIGNUM *iqmp, BN_CTX *ctx);
+
+/* Generic function pointer */
+typedef int (*ENGINE_GEN_FUNC_PTR)();
+/* Generic function pointer taking no arguments */
+typedef int (*ENGINE_GEN_INT_FUNC_PTR)(void);
+/* Specific control function pointer */
+typedef int (*ENGINE_CTRL_FUNC_PTR)(int cmd, long i, void *p, void (*f)());
+
+#endif
+
+/* This is a structure for storing implementations of various crypto
+ * algorithms and functions. */
+typedef struct engine_st
+ {
+ const char *id;
+ const char *name;
+ RSA_METHOD *rsa_meth;
+ DSA_METHOD *dsa_meth;
+ DH_METHOD *dh_meth;
+ RAND_METHOD *rand_meth;
+ BN_MOD_EXP bn_mod_exp;
+ BN_MOD_EXP_CRT bn_mod_exp_crt;
+ int (*init)(void);
+ int (*finish)(void);
+ int (*ctrl)(int cmd, long i, void *p, void (*f)());
+ EVP_PKEY *(*load_privkey)(const char *key_id, const char *passphrase);
+ EVP_PKEY *(*load_pubkey)(const char *key_id, const char *passphrase);
+ int flags;
+ /* reference count on the structure itself */
+ int struct_ref;
+ /* reference count on usability of the engine type. NB: This
+ * controls the loading and initialisation of any functionlity
+ * required by this engine, whereas the previous count is
+ * simply to cope with (de)allocation of this structure. Hence,
+ * running_ref <= struct_ref at all times. */
+ int funct_ref;
+ /* Used to maintain the linked-list of engines. */
+ struct engine_st *prev;
+ struct engine_st *next;
+ } ENGINE;
+
+/* BUILT-IN ENGINES. (these functions are only ever called once and
+ * do not return references - they are purely for bootstrapping). */
+
+/* Returns a structure of software only methods (the default). */
+ENGINE *ENGINE_openssl();
+
+#ifndef NO_HW
+
+#ifndef NO_HW_CSWIFT
+/* Returns a structure of cswift methods ... NB: This can exist and be
+ * "used" even on non-cswift systems because the "init" will fail if the
+ * card/library are not found. */
+ENGINE *ENGINE_cswift();
+#endif /* !NO_HW_CSWIFT */
+
+#ifndef NO_HW_NCIPHER
+ENGINE *ENGINE_ncipher();
+#endif /* !NO_HW_NCIPHER */
+
+#ifndef NO_HW_ATALLA
+/* Returns a structure of atalla methods. */
+ENGINE *ENGINE_atalla();
+#endif /* !NO_HW_ATALLA */
+
+#ifndef NO_HW_NURON
+ENGINE *ENGINE_nuron();
+#endif /* !NO_HW_NURON */
+
+#endif /* !NO_HW */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HEADER_ENGINE_INT_H */
diff --git a/crypto/engine/engine_lib.c b/crypto/engine/engine_lib.c
new file mode 100644
index 0000000000..1df07af03a
--- /dev/null
+++ b/crypto/engine/engine_lib.c
@@ -0,0 +1,488 @@
+/* crypto/engine/engine_lib.c */
+/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
+ * project 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 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 <openssl/crypto.h>
+#include "cryptlib.h"
+#include "engine_int.h"
+#include <openssl/engine.h>
+
+/* These pointers each have their own "functional reference" when they
+ * are non-NULL. Similarly, when they are retrieved by a call to
+ * ENGINE_get_default_[RSA|DSA|...] the returned pointer is also a
+ * reference and the caller is responsible for freeing that when they
+ * are finished with it (with a call to ENGINE_finish() *NOT* just
+ * ENGINE_free()!!!!!!). */
+static ENGINE *engine_def_rsa = NULL;
+static ENGINE *engine_def_dsa = NULL;
+static ENGINE *engine_def_dh = NULL;
+static ENGINE *engine_def_rand = NULL;
+static ENGINE *engine_def_bn_mod_exp = NULL;
+static ENGINE *engine_def_bn_mod_exp_crt = NULL;
+/* A static "once-only" flag used to control if/when the above were
+ * initialised to suitable start-up defaults. */
+static int engine_def_flag = 0;
+
+/* This is used in certain static utility functions to save code
+ * repetition for per-algorithm functions. */
+typedef enum {
+ ENGINE_TYPE_RSA,
+ ENGINE_TYPE_DSA,
+ ENGINE_TYPE_DH,
+ ENGINE_TYPE_RAND,
+ ENGINE_TYPE_BN_MOD_EXP,
+ ENGINE_TYPE_BN_MOD_EXP_CRT
+ } ENGINE_TYPE;
+
+static void engine_def_check_util(ENGINE **def, ENGINE *val)
+ {
+ *def = val;
+ val->struct_ref++;
+ val->funct_ref++;
+ }
+
+/* In a slight break with convention - this static function must be
+ * called *outside* any locking of CRYPTO_LOCK_ENGINE. */
+static void engine_def_check(void)
+ {
+ ENGINE *e;
+ if(engine_def_flag)
+ return;
+ e = ENGINE_get_first();
+ if(e == NULL)
+ /* The list is empty ... not much we can do! */
+ return;
+ /* We have a structural reference, see if getting a functional
+ * reference is possible. This is done to cope with init errors
+ * in the engine - the following locked code does a bunch of
+ * manual "ENGINE_init"s which do *not* allow such an init
+ * error so this is worth doing. */
+ if(ENGINE_init(e))
+ {
+ CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
+ /* Doing another check here prevents an obvious race
+ * condition because the whole function itself cannot
+ * be locked. */
+ if(engine_def_flag)
+ goto skip_set_defaults;
+ /* OK, we got a functional reference, so we get one each
+ * for the defaults too. */
+ engine_def_check_util(&engine_def_rsa, e);
+ engine_def_check_util(&engine_def_dsa, e);
+ engine_def_check_util(&engine_def_dh, e);
+ engine_def_check_util(&engine_def_rand, e);
+ engine_def_check_util(&engine_def_bn_mod_exp, e);
+ engine_def_check_util(&engine_def_bn_mod_exp_crt, e);
+ engine_def_flag = 1;
+skip_set_defaults:
+ CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
+ /* The "if" needs to be balanced out. */
+ ENGINE_finish(e);
+ }
+ /* We need to balance out the fact we obtained a structural
+ * reference to begin with from ENGINE_get_first(). */
+ ENGINE_free(e);
+ }
+
+/* Initialise a engine type for use (or up its functional reference count
+ * if it's already in use). */
+int ENGINE_init(ENGINE *e)
+ {
+ int to_return = 1;
+
+ if(e == NULL)
+ {
+ ENGINEerr(ENGINE_F_ENGINE_INIT,ERR_R_PASSED_NULL_PARAMETER);
+ return 0;
+ }
+ CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
+ if((e->funct_ref == 0) && e->init)
+ /* This is the first functional reference and the engine
+ * requires initialisation so we do it now. */
+ to_return = e->init();
+ if(to_return)
+ {
+ /* OK, we return a functional reference which is also a
+ * structural reference. */
+ e->struct_ref++;
+ e->funct_ref++;
+ }
+ CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
+ return to_return;
+ }
+
+/* Free a functional reference to a engine type */
+int ENGINE_finish(ENGINE *e)
+ {
+ int to_return = 1;
+
+ if(e == NULL)
+ {
+ ENGINEerr(ENGINE_F_ENGINE_FINISH,ERR_R_PASSED_NULL_PARAMETER);
+ return 0;
+ }
+ CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
+ if((e->funct_ref == 1) && e->finish)
+#if 0
+ /* This is the last functional reference and the engine
+ * requires cleanup so we do it now. */
+ to_return = e->finish();
+ if(to_return)
+ {
+ /* Cleanup the functional reference which is also a
+ * structural reference. */
+ e->struct_ref--;
+ e->funct_ref--;
+ }
+ CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
+#else
+ /* I'm going to deliberately do a convoluted version of this
+ * piece of code because we don't want "finish" functions
+ * being called inside a locked block of code, if at all
+ * possible. I'd rather have this call take an extra couple
+ * of ticks than have throughput serialised on a externally-
+ * provided callback function that may conceivably never come
+ * back. :-( */
+ {
+ CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
+ /* CODE ALERT: This *IS* supposed to be "=" and NOT "==" :-) */
+ if((to_return = e->finish()))
+ {
+ CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
+ /* Cleanup the functional reference which is also a
+ * structural reference. */
+ e->struct_ref--;
+ e->funct_ref--;
+ CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
+ }
+ }
+ else
+ CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
+#endif
+ return to_return;
+ }
+
+EVP_PKEY *ENGINE_load_private_key(ENGINE *e, const char *key_id,
+ const char *passphrase)
+ {
+ EVP_PKEY *pkey;
+
+ if(e == NULL)
+ {
+ ENGINEerr(ENGINE_F_ENGINE_LOAD_PRIVATE_KEY,
+ ERR_R_PASSED_NULL_PARAMETER);
+ return 0;
+ }
+ CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
+ if(e->funct_ref == 0)
+ {
+ ENGINEerr(ENGINE_F_ENGINE_LOAD_PRIVATE_KEY,
+ ENGINE_R_NOT_INITIALISED);
+ return 0;
+ }
+ if (!e->load_privkey)
+ {
+ ENGINEerr(ENGINE_F_ENGINE_LOAD_PRIVATE_KEY,
+ ENGINE_R_NO_LOAD_FUNCTION);
+ return 0;
+ }
+ CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
+ pkey = e->load_privkey(key_id, passphrase);
+ if (!pkey)
+ {
+ ENGINEerr(ENGINE_F_ENGINE_LOAD_PRIVATE_KEY,
+ ENGINE_R_FAILED_LOADING_PRIVATE_KEY);
+ return 0;
+ }
+ return pkey;
+ }
+
+EVP_PKEY *ENGINE_load_public_key(ENGINE *e, const char *key_id,
+ const char *passphrase)
+ {
+ EVP_PKEY *pkey;
+
+ if(e == NULL)
+ {
+ ENGINEerr(ENGINE_F_ENGINE_LOAD_PUBLIC_KEY,
+ ERR_R_PASSED_NULL_PARAMETER);
+ return 0;
+ }
+ CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
+ if(e->funct_ref == 0)
+ {
+ ENGINEerr(ENGINE_F_ENGINE_LOAD_PUBLIC_KEY,
+ ENGINE_R_NOT_INITIALISED);
+ return 0;
+ }
+ if (!e->load_pubkey)
+ {
+ ENGINEerr(ENGINE_F_ENGINE_LOAD_PUBLIC_KEY,
+ ENGINE_R_NO_LOAD_FUNCTION);
+ return 0;
+ }
+ CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
+ pkey = e->load_pubkey(key_id, passphrase);
+ if (!pkey)
+ {
+ ENGINEerr(ENGINE_F_ENGINE_LOAD_PUBLIC_KEY,
+ ENGINE_R_FAILED_LOADING_PUBLIC_KEY);
+ return 0;
+ }
+ return pkey;
+ }
+
+/* Initialise a engine type for use (or up its functional reference count
+ * if it's already in use). */
+int ENGINE_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)())
+ {
+ if(e == NULL)
+ {
+ ENGINEerr(ENGINE_F_ENGINE_CTRL,ERR_R_PASSED_NULL_PARAMETER);
+ return 0;
+ }
+ CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
+ if(e->struct_ref == 0)
+ {
+ ENGINEerr(ENGINE_F_ENGINE_CTRL,ENGINE_R_NO_REFERENCE);
+ return 0;
+ }
+ if (!e->ctrl)
+ {
+ ENGINEerr(ENGINE_F_ENGINE_CTRL,ENGINE_R_NO_CONTROL_FUNCTION);
+ return 0;
+ }
+ CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
+ return e->ctrl(cmd, i, p, f);
+ }
+
+static ENGINE *engine_get_default_type(ENGINE_TYPE t)
+ {
+ ENGINE *ret = NULL;
+
+ /* engine_def_check is lean and mean and won't replace any
+ * prior default engines ... so we must ensure that it is always
+ * the first function to get to touch the default values. */
+ engine_def_check();
+ CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
+ switch(t)
+ {
+ case ENGINE_TYPE_RSA:
+ ret = engine_def_rsa; break;
+ case ENGINE_TYPE_DSA:
+ ret = engine_def_dsa; break;
+ case ENGINE_TYPE_DH:
+ ret = engine_def_dh; break;
+ case ENGINE_TYPE_RAND:
+ ret = engine_def_rand; break;
+ case ENGINE_TYPE_BN_MOD_EXP:
+ ret = engine_def_bn_mod_exp; break;
+ case ENGINE_TYPE_BN_MOD_EXP_CRT:
+ ret = engine_def_bn_mod_exp_crt; break;
+ }
+ /* Unforunately we can't do this work outside the lock with a
+ * call to ENGINE_init() because that would leave a race
+ * condition open. */
+ if(ret)
+ {
+ ret->struct_ref++;
+ ret->funct_ref++;
+ }
+ CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
+ return ret;
+ }
+
+ENGINE *ENGINE_get_default_RSA(void)
+ {
+ return engine_get_default_type(ENGINE_TYPE_RSA);
+ }
+
+ENGINE *ENGINE_get_default_DSA(void)
+ {
+ return engine_get_default_type(ENGINE_TYPE_DSA);
+ }
+
+ENGINE *ENGINE_get_default_DH(void)
+ {
+ return engine_get_default_type(ENGINE_TYPE_DH);
+ }
+
+ENGINE *ENGINE_get_default_RAND(void)
+ {
+ return engine_get_default_type(ENGINE_TYPE_RAND);
+ }
+
+ENGINE *ENGINE_get_default_BN_mod_exp(void)
+ {
+ return engine_get_default_type(ENGINE_TYPE_BN_MOD_EXP);
+ }
+
+ENGINE *ENGINE_get_default_BN_mod_exp_crt(void)
+ {
+ return engine_get_default_type(ENGINE_TYPE_BN_MOD_EXP_CRT);
+ }
+
+static int engine_set_default_type(ENGINE_TYPE t, ENGINE *e)
+ {
+ ENGINE *old = NULL;
+
+ if(e == NULL)
+ {
+ ENGINEerr(ENGINE_F_ENGINE_SET_DEFAULT_TYPE,
+ ERR_R_PASSED_NULL_PARAMETER);
+ return 0;
+ }
+ /* engine_def_check is lean and mean and won't replace any
+ * prior default engines ... so we must ensure that it is always
+ * the first function to get to touch the default values. */
+ engine_def_check();
+ /* Attempt to get a functional reference (we need one anyway, but
+ * also, 'e' may be just a structural reference being passed in so
+ * this call may actually be the first). */
+ if(!ENGINE_init(e))
+ {
+ ENGINEerr(ENGINE_F_ENGINE_SET_DEFAULT_TYPE,
+ ENGINE_R_INIT_FAILED);
+ return 0;
+ }
+ CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
+ switch(t)
+ {
+ case ENGINE_TYPE_RSA:
+ old = engine_def_rsa;
+ engine_def_rsa = e; break;
+ case ENGINE_TYPE_DSA:
+ old = engine_def_dsa;
+ engine_def_dsa = e; break;
+ case ENGINE_TYPE_DH:
+ old = engine_def_dh;
+ engine_def_dh = e; break;
+ case ENGINE_TYPE_RAND:
+ old = engine_def_rand;
+ engine_def_rand = e; break;
+ case ENGINE_TYPE_BN_MOD_EXP:
+ old = engine_def_bn_mod_exp;
+ engine_def_bn_mod_exp = e; break;
+ case ENGINE_TYPE_BN_MOD_EXP_CRT:
+ old = engine_def_bn_mod_exp_crt;
+ engine_def_bn_mod_exp_crt = e; break;
+ }
+ CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
+ /* If we've replaced a previous value, then we need to remove the
+ * functional reference we had. */
+ if(old && !ENGINE_finish(old))
+ {
+ ENGINEerr(ENGINE_F_ENGINE_SET_DEFAULT_TYPE,
+ ENGINE_R_FINISH_FAILED);
+ return 0;
+ }
+ return 1;
+ }
+
+int ENGINE_set_default_RSA(ENGINE *e)
+ {
+ return engine_set_default_type(ENGINE_TYPE_RSA, e);
+ }
+
+int ENGINE_set_default_DSA(ENGINE *e)
+ {
+ return engine_set_default_type(ENGINE_TYPE_DSA, e);
+ }
+
+int ENGINE_set_default_DH(ENGINE *e)
+ {
+ return engine_set_default_type(ENGINE_TYPE_DH, e);
+ }
+
+int ENGINE_set_default_RAND(ENGINE *e)
+ {
+ return engine_set_default_type(ENGINE_TYPE_RAND, e);
+ }
+
+int ENGINE_set_default_BN_mod_exp(ENGINE *e)
+ {
+ return engine_set_default_type(ENGINE_TYPE_BN_MOD_EXP, e);
+ }
+
+int ENGINE_set_default_BN_mod_exp_crt(ENGINE *e)
+ {
+ return engine_set_default_type(ENGINE_TYPE_BN_MOD_EXP_CRT, e);
+ }
+
+int ENGINE_set_default(ENGINE *e, unsigned int flags)
+ {
+ if((flags & ENGINE_METHOD_RSA) && e->rsa_meth &&
+ !ENGINE_set_default_RSA(e))
+ return 0;
+ if((flags & ENGINE_METHOD_DSA) && e->dsa_meth &&
+ !ENGINE_set_default_DSA(e))
+ return 0;
+ if((flags & ENGINE_METHOD_DH) && e->dh_meth &&
+ !ENGINE_set_default_DH(e))
+ return 0;
+ if((flags & ENGINE_METHOD_RAND) && e->rand_meth &&
+ !ENGINE_set_default_RAND(e))
+ return 0;
+ if((flags & ENGINE_METHOD_BN_MOD_EXP) && e->bn_mod_exp &&
+ !ENGINE_set_default_BN_mod_exp(e))
+ return 0;
+ if((flags & ENGINE_METHOD_BN_MOD_EXP_CRT) && e->bn_mod_exp_crt &&
+ !ENGINE_set_default_BN_mod_exp_crt(e))
+ return 0;
+ return 1;
+ }
+
diff --git a/crypto/engine/engine_list.c b/crypto/engine/engine_list.c
new file mode 100644
index 0000000000..8fe4f305b4
--- /dev/null
+++ b/crypto/engine/engine_list.c
@@ -0,0 +1,679 @@
+/* crypto/engine/engine_list.c */
+/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
+ * project 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 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 <openssl/crypto.h>
+#include "cryptlib.h"
+#include "engine_int.h"
+#include <openssl/engine.h>
+
+/* The linked-list of pointers to engine types. engine_list_head
+ * incorporates an implicit structural reference but engine_list_tail
+ * does not - the latter is a computational niceity and only points
+ * to something that is already pointed to by its predecessor in the
+ * list (or engine_list_head itself). In the same way, the use of the
+ * "prev" pointer in each ENGINE is to save excessive list iteration,
+ * it doesn't correspond to an extra structural reference. Hence,
+ * engine_list_head, and each non-null "next" pointer account for
+ * the list itself assuming exactly 1 structural reference on each
+ * list member. */
+static ENGINE *engine_list_head = NULL;
+static ENGINE *engine_list_tail = NULL;
+/* A boolean switch, used to ensure we only initialise once. This
+ * is needed because the engine list may genuinely become empty during
+ * use (so we can't use engine_list_head as an indicator for example. */
+static int engine_list_flag = 0;
+
+/* These static functions starting with a lower case "engine_" always
+ * take place when CRYPTO_LOCK_ENGINE has been locked up. */
+static int engine_list_add(ENGINE *e)
+ {
+ int conflict = 0;
+ ENGINE *iterator = NULL;
+
+ if(e == NULL)
+ {
+ ENGINEerr(ENGINE_F_ENGINE_LIST_ADD,
+ ERR_R_PASSED_NULL_PARAMETER);
+ return 0;
+ }
+ iterator = engine_list_head;
+ while(iterator && !conflict)
+ {
+ conflict = (strcmp(iterator->id, e->id) == 0);
+ iterator = iterator->next;
+ }
+ if(conflict)
+ {
+ ENGINEerr(ENGINE_F_ENGINE_LIST_ADD,
+ ENGINE_R_CONFLICTING_ENGINE_ID);
+ return 0;
+ }
+ if(engine_list_head == NULL)
+ {
+ /* We are adding to an empty list. */
+ if(engine_list_tail)
+ {
+ ENGINEerr(ENGINE_F_ENGINE_LIST_ADD,
+ ENGINE_R_INTERNAL_LIST_ERROR);
+ return 0;
+ }
+ engine_list_head = e;
+ e->prev = NULL;
+ }
+ else
+ {
+ /* We are adding to the tail of an existing list. */
+ if((engine_list_tail == NULL) ||
+ (engine_list_tail->next != NULL))
+ {
+ ENGINEerr(ENGINE_F_ENGINE_LIST_ADD,
+ ENGINE_R_INTERNAL_LIST_ERROR);
+ return 0;
+ }
+ engine_list_tail->next = e;
+ e->prev = engine_list_tail;
+ }
+ /* Having the engine in the list assumes a structural
+ * reference. */
+ e->struct_ref++;
+ /* However it came to be, e is the last item in the list. */
+ engine_list_tail = e;
+ e->next = NULL;
+ return 1;
+ }
+
+static int engine_list_remove(ENGINE *e)
+ {
+ ENGINE *iterator;
+
+ if(e == NULL)
+ {
+ ENGINEerr(ENGINE_F_ENGINE_LIST_REMOVE,
+ ERR_R_PASSED_NULL_PARAMETER);
+ return 0;
+ }
+ /* We need to check that e is in our linked list! */
+ iterator = engine_list_head;
+ while(iterator && (iterator != e))
+ iterator = iterator->next;
+ if(iterator == NULL)
+ {
+ ENGINEerr(ENGINE_F_ENGINE_LIST_REMOVE,
+ ENGINE_R_ENGINE_IS_NOT_IN_LIST);
+ return 0;
+ }
+ /* un-link e from the chain. */
+ if(e->next)
+ e->next->prev = e->prev;
+ if(e->prev)
+ e->prev->next = e->next;
+ /* Correct our head/tail if necessary. */
+ if(engine_list_head == e)
+ engine_list_head = e->next;
+ if(engine_list_tail == e)
+ engine_list_tail = e->prev;
+ /* remove our structural reference. */
+ e->struct_ref--;
+ return 1;
+ }
+
+/* This check always takes place with CRYPTO_LOCK_ENGINE locked up
+ * so we're synchronised, but we can't call anything that tries to
+ * lock it again! :-) NB: For convenience (and code-clarity) we
+ * don't output errors for failures of the engine_list_add function
+ * as it will generate errors itself. */
+static int engine_internal_check(void)
+ {
+ if(engine_list_flag)
+ return 1;
+ /* This is our first time up, we need to populate the list
+ * with our statically compiled-in engines. */
+ if(!engine_list_add(ENGINE_openssl()))
+ return 0;
+#ifndef NO_HW
+#ifndef NO_HW_CSWIFT
+ if(!engine_list_add(ENGINE_cswift()))
+ return 0;
+#endif /* !NO_HW_CSWIFT */
+#ifndef NO_HW_NCIPHER
+ if(!engine_list_add(ENGINE_ncipher()))
+ return 0;
+#endif /* !NO_HW_NCIPHER */
+#ifndef NO_HW_ATALLA
+ if(!engine_list_add(ENGINE_atalla()))
+ return 0;
+#endif /* !NO_HW_ATALLA */
+#ifndef NO_HW_NURON
+ if(!engine_list_add(ENGINE_nuron()))
+ return 0;
+#endif /* !NO_HW_NURON */
+#endif /* !NO_HW */
+ engine_list_flag = 1;
+ return 1;
+ }
+
+/* Get the first/last "ENGINE" type available. */
+ENGINE *ENGINE_get_first(void)
+ {
+ ENGINE *ret = NULL;
+
+ CRYPTO_r_lock(CRYPTO_LOCK_ENGINE);
+ if(engine_internal_check())
+ {
+ ret = engine_list_head;
+ if(ret)
+ ret->struct_ref++;
+ }
+ CRYPTO_r_unlock(CRYPTO_LOCK_ENGINE);
+ return ret;
+ }
+ENGINE *ENGINE_get_last(void)
+ {
+ ENGINE *ret = NULL;
+
+ CRYPTO_r_lock(CRYPTO_LOCK_ENGINE);
+ if(engine_internal_check())
+ {
+ ret = engine_list_tail;
+ if(ret)
+ ret->struct_ref++;
+ }
+ CRYPTO_r_unlock(CRYPTO_LOCK_ENGINE);
+ return ret;
+ }
+
+/* Iterate to the next/previous "ENGINE" type (NULL = end of the list). */
+ENGINE *ENGINE_get_next(ENGINE *e)
+ {
+ ENGINE *ret = NULL;
+ if(e == NULL)
+ {
+ ENGINEerr(ENGINE_F_ENGINE_GET_NEXT,
+ ERR_R_PASSED_NULL_PARAMETER);
+ return 0;
+ }
+ CRYPTO_r_lock(CRYPTO_LOCK_ENGINE);
+ ret = e->next;
+ e->struct_ref--;
+ if(ret)
+ ret->struct_ref++;
+ CRYPTO_r_unlock(CRYPTO_LOCK_ENGINE);
+ return ret;
+ }
+ENGINE *ENGINE_get_prev(ENGINE *e)
+ {
+ ENGINE *ret = NULL;
+ if(e == NULL)
+ {
+ ENGINEerr(ENGINE_F_ENGINE_GET_PREV,
+ ERR_R_PASSED_NULL_PARAMETER);
+ return 0;
+ }
+ CRYPTO_r_lock(CRYPTO_LOCK_ENGINE);
+ ret = e->prev;
+ e->struct_ref--;
+ if(ret)
+ ret->struct_ref++;
+ CRYPTO_r_unlock(CRYPTO_LOCK_ENGINE);
+ return ret;
+ }
+
+/* Add another "ENGINE" type into the list. */
+int ENGINE_add(ENGINE *e)
+ {
+ int to_return = 1;
+ if(e == NULL)
+ {
+ ENGINEerr(ENGINE_F_ENGINE_ADD,
+ ERR_R_PASSED_NULL_PARAMETER);
+ return 0;
+ }
+ if((e->id == NULL) || (e->name == NULL))
+ {
+ ENGINEerr(ENGINE_F_ENGINE_ADD,
+ ENGINE_R_ID_OR_NAME_MISSING);
+ }
+ CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
+ if(!engine_internal_check() || !engine_list_add(e))
+ {
+ ENGINEerr(ENGINE_F_ENGINE_ADD,
+ ENGINE_R_INTERNAL_LIST_ERROR);
+ to_return = 0;
+ }
+ CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
+ return to_return;
+ }
+
+/* Remove an existing "ENGINE" type from the array. */
+int ENGINE_remove(ENGINE *e)
+ {
+ int to_return = 1;
+ if(e == NULL)
+ {
+ ENGINEerr(ENGINE_F_ENGINE_REMOVE,
+ ERR_R_PASSED_NULL_PARAMETER);
+ return 0;
+ }
+ CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
+ if(!engine_internal_check() || !engine_list_remove(e))
+ {
+ ENGINEerr(ENGINE_F_ENGINE_REMOVE,
+ ENGINE_R_INTERNAL_LIST_ERROR);
+ to_return = 0;
+ }
+ CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
+ return to_return;
+ }
+
+ENGINE *ENGINE_by_id(const char *id)
+ {
+ ENGINE *iterator = NULL;
+ if(id == NULL)
+ {
+ ENGINEerr(ENGINE_F_ENGINE_BY_ID,
+ ERR_R_PASSED_NULL_PARAMETER);
+ return NULL;
+ }
+ CRYPTO_r_lock(CRYPTO_LOCK_ENGINE);
+ if(!engine_internal_check())
+ ENGINEerr(ENGINE_F_ENGINE_BY_ID,
+ ENGINE_R_INTERNAL_LIST_ERROR);
+ else
+ {
+ iterator = engine_list_head;
+ while(iterator && (strcmp(id, iterator->id) != 0))
+ iterator = iterator->next;
+ if(iterator)
+ /* We need to return a structural reference */
+ iterator->struct_ref++;
+ }
+ CRYPTO_r_unlock(CRYPTO_LOCK_ENGINE);
+ if(iterator == NULL)
+ ENGINEerr(ENGINE_F_ENGINE_BY_ID,
+ ENGINE_R_NO_SUCH_ENGINE);
+ return iterator;
+ }
+
+/* As per the comments in engine.h, it is generally better all round
+ * if the ENGINE structure is allocated within this framework. */
+#if 0
+int ENGINE_get_struct_size(void)
+ {
+ return sizeof(ENGINE);
+ }
+
+ENGINE *ENGINE_new(ENGINE *e)
+ {
+ ENGINE *ret;
+
+ if(e == NULL)
+ {
+ ret = (ENGINE *)(OPENSSL_malloc(sizeof(ENGINE));
+ if(ret == NULL)
+ {
+ ENGINEerr(ENGINE_F_ENGINE_NEW,
+ ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+ }
+ else
+ ret = e;
+ memset(ret, 0, sizeof(ENGINE));
+ if(e)
+ ret->flags = ENGINE_FLAGS_MALLOCED;
+ ret->struct_ref = 1;
+ return ret;
+ }
+#else
+ENGINE *ENGINE_new(void)
+ {
+ ENGINE *ret;
+
+ ret = (ENGINE *)OPENSSL_malloc(sizeof(ENGINE));
+ if(ret == NULL)
+ {
+ ENGINEerr(ENGINE_F_ENGINE_NEW, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+ memset(ret, 0, sizeof(ENGINE));
+ ret->flags = ENGINE_FLAGS_MALLOCED;
+ ret->struct_ref = 1;
+ return ret;
+ }
+#endif
+
+int ENGINE_free(ENGINE *e)
+ {
+ int i;
+
+ if(e == NULL)
+ {
+ ENGINEerr(ENGINE_F_ENGINE_FREE,
+ ERR_R_PASSED_NULL_PARAMETER);
+ return 0;
+ }
+ i = CRYPTO_add(&e->struct_ref,-1,CRYPTO_LOCK_ENGINE);
+#ifdef REF_PRINT
+ REF_PRINT("ENGINE",e);
+#endif
+ if (i > 0) return 1;
+#ifdef REF_CHECK
+ if (i < 0)
+ {
+ fprintf(stderr,"ENGINE_free, bad reference count\n");
+ abort();
+ }
+#endif
+ if(e->flags & ENGINE_FLAGS_MALLOCED)
+ OPENSSL_free(e);
+ return 1;
+ }
+
+int ENGINE_set_id(ENGINE *e, const char *id)
+ {
+ if((e == NULL) || (id == NULL))
+ {
+ ENGINEerr(ENGINE_F_ENGINE_SET_ID,
+ ERR_R_PASSED_NULL_PARAMETER);
+ return 0;
+ }
+ e->id = id;
+ return 1;
+ }
+
+int ENGINE_set_name(ENGINE *e, const char *name)
+ {
+ if((e == NULL) || (name == NULL))
+ {
+ ENGINEerr(ENGINE_F_ENGINE_SET_NAME,
+ ERR_R_PASSED_NULL_PARAMETER);
+ return 0;
+ }
+ e->name = name;
+ return 1;
+ }
+
+int ENGINE_set_RSA(ENGINE *e, RSA_METHOD *rsa_meth)
+ {
+ if((e == NULL) || (rsa_meth == NULL))
+ {
+ ENGINEerr(ENGINE_F_ENGINE_SET_RSA,
+ ERR_R_PASSED_NULL_PARAMETER);
+ return 0;
+ }
+ e->rsa_meth = rsa_meth;
+ return 1;
+ }
+
+int ENGINE_set_DSA(ENGINE *e, DSA_METHOD *dsa_meth)
+ {
+ if((e == NULL) || (dsa_meth == NULL))
+ {
+ ENGINEerr(ENGINE_F_ENGINE_SET_DSA,
+ ERR_R_PASSED_NULL_PARAMETER);
+ return 0;
+ }
+ e->dsa_meth = dsa_meth;
+ return 1;
+ }
+
+int ENGINE_set_DH(ENGINE *e, DH_METHOD *dh_meth)
+ {
+ if((e == NULL) || (dh_meth == NULL))
+ {
+ ENGINEerr(ENGINE_F_ENGINE_SET_DH,
+ ERR_R_PASSED_NULL_PARAMETER);
+ return 0;
+ }
+ e->dh_meth = dh_meth;
+ return 1;
+ }
+
+int ENGINE_set_RAND(ENGINE *e, RAND_METHOD *rand_meth)
+ {
+ if((e == NULL) || (rand_meth == NULL))
+ {
+ ENGINEerr(ENGINE_F_ENGINE_SET_RAND,
+ ERR_R_PASSED_NULL_PARAMETER);
+ return 0;
+ }
+ e->rand_meth = rand_meth;
+ return 1;
+ }
+
+int ENGINE_set_BN_mod_exp(ENGINE *e, BN_MOD_EXP bn_mod_exp)
+ {
+ if((e == NULL) || (bn_mod_exp == NULL))
+ {
+ ENGINEerr(ENGINE_F_ENGINE_SET_BN_MOD_EXP,
+ ERR_R_PASSED_NULL_PARAMETER);
+ return 0;
+ }
+ e->bn_mod_exp = bn_mod_exp;
+ return 1;
+ }
+
+int ENGINE_set_BN_mod_exp_crt(ENGINE *e, BN_MOD_EXP_CRT bn_mod_exp_crt)
+ {
+ if((e == NULL) || (bn_mod_exp_crt == NULL))
+ {
+ ENGINEerr(ENGINE_F_ENGINE_SET_BN_MOD_EXP_CRT,
+ ERR_R_PASSED_NULL_PARAMETER);
+ return 0;
+ }
+ e->bn_mod_exp_crt = bn_mod_exp_crt;
+ return 1;
+ }
+
+int ENGINE_set_init_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR init_f)
+ {
+ if((e == NULL) || (init_f == NULL))
+ {
+ ENGINEerr(ENGINE_F_ENGINE_SET_INIT_FUNCTION,
+ ERR_R_PASSED_NULL_PARAMETER);
+ return 0;
+ }
+ e->init = init_f;
+ return 1;
+ }
+
+int ENGINE_set_finish_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR finish_f)
+ {
+ if((e == NULL) || (finish_f == NULL))
+ {
+ ENGINEerr(ENGINE_F_ENGINE_SET_FINISH_FUNCTION,
+ ERR_R_PASSED_NULL_PARAMETER);
+ return 0;
+ }
+ e->finish = finish_f;
+ return 1;
+ }
+
+int ENGINE_set_ctrl_function(ENGINE *e, ENGINE_CTRL_FUNC_PTR ctrl_f)
+ {
+ if((e == NULL) || (ctrl_f == NULL))
+ {
+ ENGINEerr(ENGINE_F_ENGINE_SET_CTRL_FUNCTION,
+ ERR_R_PASSED_NULL_PARAMETER);
+ return 0;
+ }
+ e->ctrl = ctrl_f;
+ return 1;
+ }
+
+const char *ENGINE_get_id(ENGINE *e)
+ {
+ if(e == NULL)
+ {
+ ENGINEerr(ENGINE_F_ENGINE_GET_ID,
+ ERR_R_PASSED_NULL_PARAMETER);
+ return 0;
+ }
+ return e->id;
+ }
+
+const char *ENGINE_get_name(ENGINE *e)
+ {
+ if(e == NULL)
+ {
+ ENGINEerr(ENGINE_F_ENGINE_GET_NAME,
+ ERR_R_PASSED_NULL_PARAMETER);
+ return 0;
+ }
+ return e->name;
+ }
+
+RSA_METHOD *ENGINE_get_RSA(ENGINE *e)
+ {
+ if(e == NULL)
+ {
+ ENGINEerr(ENGINE_F_ENGINE_GET_RSA,
+ ERR_R_PASSED_NULL_PARAMETER);
+ return NULL;
+ }
+ return e->rsa_meth;
+ }
+
+DSA_METHOD *ENGINE_get_DSA(ENGINE *e)
+ {
+ if(e == NULL)
+ {
+ ENGINEerr(ENGINE_F_ENGINE_GET_DSA,
+ ERR_R_PASSED_NULL_PARAMETER);
+ return NULL;
+ }
+ return e->dsa_meth;
+ }
+
+DH_METHOD *ENGINE_get_DH(ENGINE *e)
+ {
+ if(e == NULL)
+ {
+ ENGINEerr(ENGINE_F_ENGINE_GET_DH,
+ ERR_R_PASSED_NULL_PARAMETER);
+ return NULL;
+ }
+ return e->dh_meth;
+ }
+
+RAND_METHOD *ENGINE_get_RAND(ENGINE *e)
+ {
+ if(e == NULL)
+ {
+ ENGINEerr(ENGINE_F_ENGINE_GET_RAND,
+ ERR_R_PASSED_NULL_PARAMETER);
+ return NULL;
+ }
+ return e->rand_meth;
+ }
+
+BN_MOD_EXP ENGINE_get_BN_mod_exp(ENGINE *e)
+ {
+ if(e == NULL)
+ {
+ ENGINEerr(ENGINE_F_ENGINE_GET_BN_MOD_EXP,
+ ERR_R_PASSED_NULL_PARAMETER);
+ return NULL;
+ }
+ return e->bn_mod_exp;
+ }
+
+BN_MOD_EXP_CRT ENGINE_get_BN_mod_exp_crt(ENGINE *e)
+ {
+ if(e == NULL)
+ {
+ ENGINEerr(ENGINE_F_ENGINE_GET_BN_MOD_EXP_CRT,
+ ERR_R_PASSED_NULL_PARAMETER);
+ return NULL;
+ }
+ return e->bn_mod_exp_crt;
+ }
+
+ENGINE_GEN_INT_FUNC_PTR ENGINE_get_init_function(ENGINE *e)
+ {
+ if(e == NULL)
+ {
+ ENGINEerr(ENGINE_F_ENGINE_GET_INIT_FUNCTION,
+ ERR_R_PASSED_NULL_PARAMETER);
+ return NULL;
+ }
+ return e->init;
+ }
+
+ENGINE_GEN_INT_FUNC_PTR ENGINE_get_finish_function(ENGINE *e)
+ {
+ if(e == NULL)
+ {
+ ENGINEerr(ENGINE_F_ENGINE_GET_FINISH_FUNCTION,
+ ERR_R_PASSED_NULL_PARAMETER);
+ return NULL;
+ }
+ return e->finish;
+ }
+
+ENGINE_CTRL_FUNC_PTR ENGINE_get_ctrl_function(ENGINE *e)
+ {
+ if(e == NULL)
+ {
+ ENGINEerr(ENGINE_F_ENGINE_GET_CTRL_FUNCTION,
+ ERR_R_PASSED_NULL_PARAMETER);
+ return NULL;
+ }
+ return e->ctrl;
+ }
+
diff --git a/crypto/engine/engine_openssl.c b/crypto/engine/engine_openssl.c
new file mode 100644
index 0000000000..9636f51168
--- /dev/null
+++ b/crypto/engine/engine_openssl.c
@@ -0,0 +1,174 @@
+/* crypto/engine/engine_openssl.c */
+/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
+ * project 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 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 <openssl/crypto.h>
+#include "cryptlib.h"
+#include "engine_int.h"
+#include <openssl/engine.h>
+#include <openssl/dso.h>
+#include <openssl/rsa.h>
+#include <openssl/dsa.h>
+#include <openssl/dh.h>
+#include <openssl/rand.h>
+#include <openssl/bn.h>
+
+/* This is the only function we need to implement as OpenSSL
+ * doesn't have a native CRT mod_exp. Perhaps this should be
+ * BN_mod_exp_crt and moved into crypto/bn/ ?? ... dunno. */
+static int openssl_mod_exp_crt(BIGNUM *r, BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *q, const BIGNUM *dmp1, const BIGNUM *dmq1,
+ const BIGNUM *iqmp, BN_CTX *ctx);
+
+/* The ENGINE structure that can be pointed to. */
+static ENGINE engine_openssl =
+ {
+ "openssl",
+ "Software default engine support",
+ NULL,
+ NULL,
+ NULL, /* these methods are "stolen" in ENGINE_openssl() */
+ NULL,
+ NULL,
+ openssl_mod_exp_crt,
+ NULL, /* no init() */
+ NULL, /* no finish() */
+ NULL, /* no ctrl() */
+ NULL, /* no load_privkey() */
+ NULL, /* no load_pubkey() */
+ 0, /* no flags */
+ 0, 0, /* no references. */
+ NULL, NULL /* unlinked */
+ };
+
+/* As this is only ever called once, there's no need for locking
+ * (indeed - the lock will already be held by our caller!!!) */
+ENGINE *ENGINE_openssl()
+ {
+ /* We need to populate our structure with the software pointers
+ * that we want to steal. */
+ engine_openssl.rsa_meth = RSA_get_default_openssl_method();
+ engine_openssl.dsa_meth = DSA_get_default_openssl_method();
+ engine_openssl.dh_meth = DH_get_default_openssl_method();
+ engine_openssl.rand_meth = RAND_SSLeay();
+ engine_openssl.bn_mod_exp = BN_mod_exp;
+ return &engine_openssl;
+ }
+
+/* Chinese Remainder Theorem, taken and adapted from rsa_eay.c */
+static int openssl_mod_exp_crt(BIGNUM *r, BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *q, const BIGNUM *dmp1,
+ const BIGNUM *dmq1, const BIGNUM *iqmp, BN_CTX *ctx)
+ {
+ BIGNUM r1,m1;
+ int ret=0;
+ BN_CTX *bn_ctx;
+ BIGNUM *temp_bn = NULL;
+
+ if (ctx)
+ bn_ctx = ctx;
+ else
+ if ((bn_ctx=BN_CTX_new()) == NULL) goto err;
+ BN_init(&m1);
+ BN_init(&r1);
+ /* BN_mul() cannot accept const BIGNUMs so I use the BN_CTX
+ * to duplicate what I need. <sigh> */
+ if ((temp_bn = BN_CTX_get(bn_ctx)) == NULL) goto err;
+ if (!BN_copy(temp_bn, iqmp)) goto err;
+
+ if (!BN_mod(&r1, a, q, bn_ctx)) goto err;
+ if (!engine_openssl.bn_mod_exp(&m1, &r1, dmq1, q, bn_ctx))
+ goto err;
+
+ if (!BN_mod(&r1, a, p, bn_ctx)) goto err;
+ if (!engine_openssl.bn_mod_exp(r, &r1, dmp1, p, bn_ctx))
+ goto err;
+
+ if (!BN_sub(r, r, &m1)) goto err;
+ /* This will help stop the size of r0 increasing, which does
+ * affect the multiply if it optimised for a power of 2 size */
+ if (r->neg)
+ if (!BN_add(r, r, p)) goto err;
+
+ if (!BN_mul(&r1, r, temp_bn, bn_ctx)) goto err;
+ if (!BN_mod(r, &r1, p, bn_ctx)) goto err;
+ /* If p < q it is occasionally possible for the correction of
+ * adding 'p' if r is negative above to leave the result still
+ * negative. This can break the private key operations: the following
+ * second correction should *always* correct this rare occurrence.
+ * This will *never* happen with OpenSSL generated keys because
+ * they ensure p > q [steve]
+ */
+ if (r->neg)
+ if (!BN_add(r, r, p)) goto err;
+ /* Again, BN_mul() will need non-const values. */
+ if (!BN_copy(temp_bn, q)) goto err;
+ if (!BN_mul(&r1, r, temp_bn, bn_ctx)) goto err;
+ if (!BN_add(r, &r1, &m1)) goto err;
+
+ ret=1;
+err:
+ BN_clear_free(&m1);
+ BN_clear_free(&r1);
+ if (temp_bn)
+ bn_ctx->tos--;
+ if (!ctx)
+ BN_CTX_free(bn_ctx);
+ return(ret);
+ }
diff --git a/crypto/engine/enginetest.c b/crypto/engine/enginetest.c
new file mode 100644
index 0000000000..a5a3c47fcb
--- /dev/null
+++ b/crypto/engine/enginetest.c
@@ -0,0 +1,251 @@
+/* crypto/engine/enginetest.c */
+/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
+ * project 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 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 <string.h>
+#include <openssl/engine.h>
+#include <openssl/err.h>
+
+static void display_engine_list()
+ {
+ ENGINE *h;
+ int loop;
+
+ h = ENGINE_get_first();
+ loop = 0;
+ printf("listing available engine types\n");
+ while(h)
+ {
+ printf("engine %i, id = \"%s\", name = \"%s\"\n",
+ loop++, ENGINE_get_id(h), ENGINE_get_name(h));
+ h = ENGINE_get_next(h);
+ }
+ printf("end of list\n");
+ }
+
+int main(int argc, char *argv[])
+ {
+ ENGINE *block[512];
+ char buf[256];
+ const char *id, *name;
+ ENGINE *ptr;
+ int loop;
+ int to_return = 1;
+ ENGINE *new_h1 = NULL;
+ ENGINE *new_h2 = NULL;
+ ENGINE *new_h3 = NULL;
+ ENGINE *new_h4 = NULL;
+
+ ERR_load_crypto_strings();
+
+ memset(block, 0, 512 * sizeof(ENGINE *));
+ if(((new_h1 = ENGINE_new()) == NULL) ||
+ !ENGINE_set_id(new_h1, "test_id0") ||
+ !ENGINE_set_name(new_h1, "First test item") ||
+ ((new_h2 = ENGINE_new()) == NULL) ||
+ !ENGINE_set_id(new_h2, "test_id1") ||
+ !ENGINE_set_name(new_h2, "Second test item") ||
+ ((new_h3 = ENGINE_new()) == NULL) ||
+ !ENGINE_set_id(new_h3, "test_id2") ||
+ !ENGINE_set_name(new_h3, "Third test item") ||
+ ((new_h4 = ENGINE_new()) == NULL) ||
+ !ENGINE_set_id(new_h4, "test_id3") ||
+ !ENGINE_set_name(new_h4, "Fourth test item"))
+ {
+ printf("Couldn't set up test ENGINE structures\n");
+ goto end;
+ }
+ printf("\nenginetest beginning\n\n");
+ display_engine_list();
+ if(!ENGINE_add(new_h1))
+ {
+ printf("Add failed!\n");
+ goto end;
+ }
+ display_engine_list();
+ ptr = ENGINE_get_first();
+ if(!ENGINE_remove(ptr))
+ {
+ printf("Remove failed!\n");
+ goto end;
+ }
+ display_engine_list();
+ if(!ENGINE_add(new_h3) || !ENGINE_add(new_h2))
+ {
+ printf("Add failed!\n");
+ goto end;
+ }
+ display_engine_list();
+ if(!ENGINE_remove(new_h2))
+ {
+ printf("Remove failed!\n");
+ goto end;
+ }
+ display_engine_list();
+ if(!ENGINE_add(new_h4))
+ {
+ printf("Add failed!\n");
+ goto end;
+ }
+ display_engine_list();
+ if(ENGINE_add(new_h3))
+ {
+ printf("Add *should* have failed but didn't!\n");
+ goto end;
+ }
+ else
+ printf("Add that should fail did.\n");
+ ERR_clear_error();
+ if(ENGINE_remove(new_h2))
+ {
+ printf("Remove *should* have failed but didn't!\n");
+ goto end;
+ }
+ else
+ printf("Remove that should fail did.\n");
+ if(!ENGINE_remove(new_h1))
+ {
+ printf("Remove failed!\n");
+ goto end;
+ }
+ display_engine_list();
+ if(!ENGINE_remove(new_h3))
+ {
+ printf("Remove failed!\n");
+ goto end;
+ }
+ display_engine_list();
+ if(!ENGINE_remove(new_h4))
+ {
+ printf("Remove failed!\n");
+ goto end;
+ }
+ display_engine_list();
+ /* Depending on whether there's any hardware support compiled
+ * in, this remove may be destined to fail. */
+ ptr = ENGINE_get_first();
+ if(ptr)
+ if(!ENGINE_remove(ptr))
+ printf("Remove failed!i - probably no hardware "
+ "support present.\n");
+ display_engine_list();
+ if(!ENGINE_add(new_h1) || !ENGINE_remove(new_h1))
+ {
+ printf("Couldn't add and remove to an empty list!\n");
+ goto end;
+ }
+ else
+ printf("Successfully added and removed to an empty list!\n");
+ printf("About to beef up the engine-type list\n");
+ for(loop = 0; loop < 512; loop++)
+ {
+ sprintf(buf, "id%i", loop);
+ id = strdup(buf);
+ sprintf(buf, "Fake engine type %i", loop);
+ name = strdup(buf);
+ if(((block[loop] = ENGINE_new()) == NULL) ||
+ !ENGINE_set_id(block[loop], id) ||
+ !ENGINE_set_name(block[loop], name))
+ {
+ printf("Couldn't create block of ENGINE structures.\n"
+ "I'll probably also core-dump now, damn.\n");
+ goto end;
+ }
+ }
+ for(loop = 0; loop < 512; loop++)
+ {
+ if(!ENGINE_add(block[loop]))
+ {
+ printf("\nAdding stopped at %i, (%s,%s)\n",
+ loop, ENGINE_get_id(block[loop]),
+ ENGINE_get_name(block[loop]));
+ goto cleanup_loop;
+ }
+ else
+ printf("."); fflush(stdout);
+ }
+cleanup_loop:
+ printf("\nAbout to empty the engine-type list\n");
+ while((ptr = ENGINE_get_first()) != NULL)
+ {
+ if(!ENGINE_remove(ptr))
+ {
+ printf("\nRemove failed!\n");
+ goto end;
+ }
+ printf("."); fflush(stdout);
+ }
+ for(loop = 0; loop < 512; loop++)
+ {
+ free((char *)(ENGINE_get_id(block[loop])));
+ free((char *)(ENGINE_get_name(block[loop])));
+ }
+ printf("\nTests completed happily\n");
+ to_return = 0;
+end:
+ if(to_return)
+ ERR_print_errors_fp(stderr);
+ if(new_h1) ENGINE_free(new_h1);
+ if(new_h2) ENGINE_free(new_h2);
+ if(new_h3) ENGINE_free(new_h3);
+ if(new_h4) ENGINE_free(new_h4);
+ for(loop = 0; loop < 512; loop++)
+ if(block[loop])
+ ENGINE_free(block[loop]);
+ return to_return;
+ }
diff --git a/crypto/engine/hw_atalla.c b/crypto/engine/hw_atalla.c
new file mode 100644
index 0000000000..e536420480
--- /dev/null
+++ b/crypto/engine/hw_atalla.c
@@ -0,0 +1,443 @@
+/* crypto/engine/hw_atalla.c */
+/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
+ * project 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 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 <openssl/crypto.h>
+#include "cryptlib.h"
+#include <openssl/dso.h>
+#include "engine_int.h"
+#include <openssl/engine.h>
+
+#ifndef NO_HW
+#ifndef NO_HW_ATALLA
+
+#ifdef FLAT_INC
+#include "atalla.h"
+#else
+#include "vendor_defns/atalla.h"
+#endif
+
+static int atalla_init(void);
+static int atalla_finish(void);
+
+/* BIGNUM stuff */
+static int atalla_mod_exp(BIGNUM *r, BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *m, BN_CTX *ctx);
+
+/* RSA stuff */
+static int atalla_rsa_mod_exp(BIGNUM *r0, BIGNUM *I, RSA *rsa);
+/* This function is aliased to mod_exp (with the mont stuff dropped). */
+static int atalla_mod_exp_mont(BIGNUM *r, BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
+
+/* DSA stuff */
+static int atalla_dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1,
+ BIGNUM *p1, BIGNUM *a2, BIGNUM *p2, BIGNUM *m,
+ BN_CTX *ctx, BN_MONT_CTX *in_mont);
+static int atalla_mod_exp_dsa(DSA *dsa, BIGNUM *r, BIGNUM *a,
+ const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
+ BN_MONT_CTX *m_ctx);
+
+/* DH stuff */
+/* This function is alised to mod_exp (with the DH and mont dropped). */
+static int atalla_mod_exp_dh(DH *dh, BIGNUM *r, BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
+
+
+/* Our internal RSA_METHOD that we provide pointers to */
+static RSA_METHOD atalla_rsa =
+ {
+ "Atalla RSA method",
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ atalla_rsa_mod_exp,
+ atalla_mod_exp_mont,
+ NULL,
+ NULL,
+ 0,
+ NULL,
+ NULL,
+ NULL
+ };
+
+/* Our internal DSA_METHOD that we provide pointers to */
+static DSA_METHOD atalla_dsa =
+ {
+ "Atalla DSA method",
+ NULL, /* dsa_do_sign */
+ NULL, /* dsa_sign_setup */
+ NULL, /* dsa_do_verify */
+ atalla_dsa_mod_exp, /* dsa_mod_exp */
+ atalla_mod_exp_dsa, /* bn_mod_exp */
+ NULL, /* init */
+ NULL, /* finish */
+ 0, /* flags */
+ NULL /* app_data */
+ };
+
+/* Our internal DH_METHOD that we provide pointers to */
+static DH_METHOD atalla_dh =
+ {
+ "Atalla DH method",
+ NULL,
+ NULL,
+ atalla_mod_exp_dh,
+ NULL,
+ NULL,
+ 0,
+ NULL
+ };
+
+/* Our ENGINE structure. */
+static ENGINE engine_atalla =
+ {
+ "atalla",
+ "Atalla hardware engine support",
+ &atalla_rsa,
+ &atalla_dsa,
+ &atalla_dh,
+ NULL,
+ atalla_mod_exp,
+ NULL,
+ atalla_init,
+ atalla_finish,
+ NULL, /* no ctrl() */
+ NULL, /* no load_privkey() */
+ NULL, /* no load_pubkey() */
+ 0, /* no flags */
+ 0, 0, /* no references */
+ NULL, NULL /* unlinked */
+ };
+
+/* As this is only ever called once, there's no need for locking
+ * (indeed - the lock will already be held by our caller!!!) */
+ENGINE *ENGINE_atalla()
+ {
+ RSA_METHOD *meth1;
+ DSA_METHOD *meth2;
+ DH_METHOD *meth3;
+
+ /* We know that the "PKCS1_SSLeay()" functions hook properly
+ * to the atalla-specific mod_exp and mod_exp_crt so we use
+ * those functions. NB: We don't use ENGINE_openssl() or
+ * anything "more generic" because something like the RSAref
+ * code may not hook properly, and if you own one of these
+ * cards then you have the right to do RSA operations on it
+ * anyway! */
+ meth1 = RSA_PKCS1_SSLeay();
+ atalla_rsa.rsa_pub_enc = meth1->rsa_pub_enc;
+ atalla_rsa.rsa_pub_dec = meth1->rsa_pub_dec;
+ atalla_rsa.rsa_priv_enc = meth1->rsa_priv_enc;
+ atalla_rsa.rsa_priv_dec = meth1->rsa_priv_dec;
+
+ /* Use the DSA_OpenSSL() method and just hook the mod_exp-ish
+ * bits. */
+ meth2 = DSA_OpenSSL();
+ atalla_dsa.dsa_do_sign = meth2->dsa_do_sign;
+ atalla_dsa.dsa_sign_setup = meth2->dsa_sign_setup;
+ atalla_dsa.dsa_do_verify = meth2->dsa_do_verify;
+
+ /* Much the same for Diffie-Hellman */
+ meth3 = DH_OpenSSL();
+ atalla_dh.generate_key = meth3->generate_key;
+ atalla_dh.compute_key = meth3->compute_key;
+ return &engine_atalla;
+ }
+
+/* This is a process-global DSO handle used for loading and unloading
+ * the Atalla library. NB: This is only set (or unset) during an
+ * init() or finish() call (reference counts permitting) and they're
+ * operating with global locks, so this should be thread-safe
+ * implicitly. */
+static DSO *atalla_dso = NULL;
+
+/* These are the function pointers that are (un)set when the library has
+ * successfully (un)loaded. */
+static tfnASI_GetHardwareConfig *p_Atalla_GetHardwareConfig = NULL;
+static tfnASI_RSAPrivateKeyOpFn *p_Atalla_RSAPrivateKeyOpFn = NULL;
+static tfnASI_GetPerformanceStatistics *p_Atalla_GetPerformanceStatistics = NULL;
+
+/* (de)initialisation functions. */
+static int atalla_init()
+ {
+ tfnASI_GetHardwareConfig *p1;
+ tfnASI_RSAPrivateKeyOpFn *p2;
+ tfnASI_GetPerformanceStatistics *p3;
+ /* Not sure of the origin of this magic value, but Ben's code had it
+ * and it seemed to have been working for a few people. :-) */
+ unsigned int config_buf[1024];
+
+ if(atalla_dso != NULL)
+ {
+ ENGINEerr(ENGINE_F_ATALLA_INIT,ENGINE_R_ALREADY_LOADED);
+ goto err;
+ }
+ /* Attempt to load libatasi.so/atasi.dll/whatever. Needs to be
+ * changed unfortunately because the Atalla drivers don't have
+ * standard library names that can be platform-translated well. */
+ /* TODO: Work out how to actually map to the names the Atalla
+ * drivers really use - for now a symbollic link needs to be
+ * created on the host system from libatasi.so to atasi.so on
+ * unix variants. */
+ atalla_dso = DSO_load(NULL, ATALLA_LIBNAME, NULL, 0);
+ if(atalla_dso == NULL)
+ {
+ ENGINEerr(ENGINE_F_ATALLA_INIT,ENGINE_R_DSO_FAILURE);
+ goto err;
+ }
+ if(!(p1 = (tfnASI_GetHardwareConfig *)DSO_bind_func(
+ atalla_dso, ATALLA_F1)) ||
+ !(p2 = (tfnASI_RSAPrivateKeyOpFn *)DSO_bind_func(
+ atalla_dso, ATALLA_F2)) ||
+ !(p3 = (tfnASI_GetPerformanceStatistics *)DSO_bind_func(
+ atalla_dso, ATALLA_F3)))
+ {
+ ENGINEerr(ENGINE_F_ATALLA_INIT,ENGINE_R_DSO_FAILURE);
+ goto err;
+ }
+ /* Copy the pointers */
+ p_Atalla_GetHardwareConfig = p1;
+ p_Atalla_RSAPrivateKeyOpFn = p2;
+ p_Atalla_GetPerformanceStatistics = p3;
+ /* Perform a basic test to see if there's actually any unit
+ * running. */
+ if(p1(0L, config_buf) != 0)
+ {
+ ENGINEerr(ENGINE_F_ATALLA_INIT,ENGINE_R_UNIT_FAILURE);
+ goto err;
+ }
+ /* Everything's fine. */
+ return 1;
+err:
+ if(atalla_dso)
+ DSO_free(atalla_dso);
+ p_Atalla_GetHardwareConfig = NULL;
+ p_Atalla_RSAPrivateKeyOpFn = NULL;
+ p_Atalla_GetPerformanceStatistics = NULL;
+ return 0;
+ }
+
+static int atalla_finish()
+ {
+ if(atalla_dso == NULL)
+ {
+ ENGINEerr(ENGINE_F_ATALLA_FINISH,ENGINE_R_NOT_LOADED);
+ return 0;
+ }
+ if(!DSO_free(atalla_dso))
+ {
+ ENGINEerr(ENGINE_F_ATALLA_FINISH,ENGINE_R_DSO_FAILURE);
+ return 0;
+ }
+ atalla_dso = NULL;
+ p_Atalla_GetHardwareConfig = NULL;
+ p_Atalla_RSAPrivateKeyOpFn = NULL;
+ p_Atalla_GetPerformanceStatistics = NULL;
+ return 1;
+ }
+
+static int atalla_mod_exp(BIGNUM *r, BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *m, BN_CTX *ctx)
+ {
+ /* I need somewhere to store temporary serialised values for
+ * use with the Atalla API calls. A neat cheat - I'll use
+ * BIGNUMs from the BN_CTX but access their arrays directly as
+ * byte arrays <grin>. This way I don't have to clean anything
+ * up. */
+ BIGNUM *modulus;
+ BIGNUM *exponent;
+ BIGNUM *argument;
+ BIGNUM *result;
+ RSAPrivateKey keydata;
+ int to_return, numbytes;
+
+ modulus = exponent = argument = result = NULL;
+ to_return = 0; /* expect failure */
+
+ if(!atalla_dso)
+ {
+ ENGINEerr(ENGINE_F_ATALLA_MOD_EXP,ENGINE_R_NOT_LOADED);
+ goto err;
+ }
+ /* Prepare the params */
+ modulus = BN_CTX_get(ctx);
+ exponent = BN_CTX_get(ctx);
+ argument = BN_CTX_get(ctx);
+ result = BN_CTX_get(ctx);
+ if(!modulus || !exponent || !argument || !result)
+ {
+ ENGINEerr(ENGINE_F_ATALLA_MOD_EXP,ENGINE_R_BN_CTX_FULL);
+ goto err;
+ }
+ if(!bn_wexpand(modulus, m->top) || !bn_wexpand(exponent, m->top) ||
+ !bn_wexpand(argument, m->top) || !bn_wexpand(result, m->top))
+ {
+ ENGINEerr(ENGINE_F_ATALLA_MOD_EXP,ENGINE_R_BN_EXPAND_FAIL);
+ goto err;
+ }
+ /* Prepare the key-data */
+ memset(&keydata, 0,sizeof keydata);
+ numbytes = BN_num_bytes(m);
+ memset(exponent->d, 0, numbytes);
+ memset(modulus->d, 0, numbytes);
+ BN_bn2bin(p, (unsigned char *)exponent->d + numbytes - BN_num_bytes(p));
+ BN_bn2bin(m, (unsigned char *)modulus->d + numbytes - BN_num_bytes(m));
+ keydata.privateExponent.data = (unsigned char *)exponent->d;
+ keydata.privateExponent.len = numbytes;
+ keydata.modulus.data = (unsigned char *)modulus->d;
+ keydata.modulus.len = numbytes;
+ /* Prepare the argument */
+ memset(argument->d, 0, numbytes);
+ memset(result->d, 0, numbytes);
+ BN_bn2bin(a, (unsigned char *)argument->d + numbytes - BN_num_bytes(a));
+ /* Perform the operation */
+ if(p_Atalla_RSAPrivateKeyOpFn(&keydata, (unsigned char *)result->d,
+ (unsigned char *)argument->d,
+ keydata.modulus.len) != 0)
+ {
+ ENGINEerr(ENGINE_F_ATALLA_MOD_EXP,ENGINE_R_REQUEST_FAILED);
+ goto err;
+ }
+ /* Convert the response */
+ BN_bin2bn((unsigned char *)result->d, numbytes, r);
+ to_return = 1;
+err:
+ if(modulus) ctx->tos--;
+ if(exponent) ctx->tos--;
+ if(argument) ctx->tos--;
+ if(result) ctx->tos--;
+ return to_return;
+ }
+
+static int atalla_rsa_mod_exp(BIGNUM *r0, BIGNUM *I, RSA *rsa)
+ {
+ BN_CTX *ctx = NULL;
+ int to_return = 0;
+
+ if(!atalla_dso)
+ {
+ ENGINEerr(ENGINE_F_ATALLA_RSA_MOD_EXP,ENGINE_R_NOT_LOADED);
+ goto err;
+ }
+ if((ctx = BN_CTX_new()) == NULL)
+ goto err;
+ if(!rsa->d || !rsa->n)
+ {
+ ENGINEerr(ENGINE_F_ATALLA_RSA_MOD_EXP,ENGINE_R_MISSING_KEY_COMPONENTS);
+ goto err;
+ }
+ to_return = atalla_mod_exp(r0, I, rsa->d, rsa->n, ctx);
+err:
+ if(ctx)
+ BN_CTX_free(ctx);
+ return to_return;
+ }
+
+/* This code was liberated and adapted from the commented-out code in
+ * dsa_ossl.c. Because of the unoptimised form of the Atalla acceleration
+ * (it doesn't have a CRT form for RSA), this function means that an
+ * Atalla system running with a DSA server certificate can handshake
+ * around 5 or 6 times faster/more than an equivalent system running with
+ * RSA. Just check out the "signs" statistics from the RSA and DSA parts
+ * of "openssl speed -engine atalla dsa1024 rsa1024". */
+static int atalla_dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1,
+ BIGNUM *p1, BIGNUM *a2, BIGNUM *p2, BIGNUM *m,
+ BN_CTX *ctx, BN_MONT_CTX *in_mont)
+ {
+ BIGNUM t;
+ int to_return = 0;
+
+ BN_init(&t);
+ /* let rr = a1 ^ p1 mod m */
+ if (!atalla_mod_exp(rr,a1,p1,m,ctx)) goto end;
+ /* let t = a2 ^ p2 mod m */
+ if (!atalla_mod_exp(&t,a2,p2,m,ctx)) goto end;
+ /* let rr = rr * t mod m */
+ if (!BN_mod_mul(rr,rr,&t,m,ctx)) goto end;
+ to_return = 1;
+end:
+ BN_free(&t);
+ return to_return;
+ }
+
+
+static int atalla_mod_exp_dsa(DSA *dsa, BIGNUM *r, BIGNUM *a,
+ const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
+ BN_MONT_CTX *m_ctx)
+ {
+ return atalla_mod_exp(r, a, p, m, ctx);
+ }
+
+/* This function is aliased to mod_exp (with the mont stuff dropped). */
+static int atalla_mod_exp_mont(BIGNUM *r, BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
+ {
+ return atalla_mod_exp(r, a, p, m, ctx);
+ }
+
+/* This function is aliased to mod_exp (with the dh and mont dropped). */
+static int atalla_mod_exp_dh(DH *dh, BIGNUM *r, BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
+ {
+ return atalla_mod_exp(r, a, p, m, ctx);
+ }
+
+#endif /* !NO_HW_ATALLA */
+#endif /* !NO_HW */
diff --git a/crypto/engine/hw_cswift.c b/crypto/engine/hw_cswift.c
new file mode 100644
index 0000000000..5747973c74
--- /dev/null
+++ b/crypto/engine/hw_cswift.c
@@ -0,0 +1,806 @@
+/* crypto/engine/hw_cswift.c */
+/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
+ * project 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 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 <openssl/crypto.h>
+#include "cryptlib.h"
+#include <openssl/dso.h>
+#include "engine_int.h"
+#include <openssl/engine.h>
+
+#ifndef NO_HW
+#ifndef NO_HW_CSWIFT
+
+/* Attribution notice: Rainbow have generously allowed me to reproduce
+ * the necessary definitions here from their API. This means the support
+ * can build independently of whether application builders have the
+ * API or hardware. This will allow developers to easily produce software
+ * that has latent hardware support for any users that have accelerators
+ * installed, without the developers themselves needing anything extra.
+ *
+ * I have only clipped the parts from the CryptoSwift header files that
+ * are (or seem) relevant to the CryptoSwift support code. This is
+ * simply to keep the file sizes reasonable.
+ * [Geoff]
+ */
+#ifdef FLAT_INC
+#include "cswift.h"
+#else
+#include "vendor_defns/cswift.h"
+#endif
+
+static int cswift_init(void);
+static int cswift_finish(void);
+
+/* BIGNUM stuff */
+static int cswift_mod_exp(BIGNUM *r, BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *m, BN_CTX *ctx);
+static int cswift_mod_exp_crt(BIGNUM *r, BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *q, const BIGNUM *dmp1, const BIGNUM *dmq1,
+ const BIGNUM *iqmp, BN_CTX *ctx);
+
+/* RSA stuff */
+static int cswift_rsa_mod_exp(BIGNUM *r0, BIGNUM *I, RSA *rsa);
+/* This function is aliased to mod_exp (with the mont stuff dropped). */
+static int cswift_mod_exp_mont(BIGNUM *r, BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
+
+/* DSA stuff */
+static DSA_SIG *cswift_dsa_sign(const unsigned char *dgst, int dlen, DSA *dsa);
+static int cswift_dsa_verify(const unsigned char *dgst, int dgst_len,
+ DSA_SIG *sig, DSA *dsa);
+
+/* DH stuff */
+/* This function is alised to mod_exp (with the DH and mont dropped). */
+static int cswift_mod_exp_dh(DH *dh, BIGNUM *r, BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
+
+
+/* Our internal RSA_METHOD that we provide pointers to */
+static RSA_METHOD cswift_rsa =
+ {
+ "CryptoSwift RSA method",
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ cswift_rsa_mod_exp,
+ cswift_mod_exp_mont,
+ NULL,
+ NULL,
+ 0,
+ NULL,
+ NULL,
+ NULL
+ };
+
+/* Our internal DSA_METHOD that we provide pointers to */
+static DSA_METHOD cswift_dsa =
+ {
+ "CryptoSwift DSA method",
+ cswift_dsa_sign,
+ NULL, /* dsa_sign_setup */
+ cswift_dsa_verify,
+ NULL, /* dsa_mod_exp */
+ NULL, /* bn_mod_exp */
+ NULL, /* init */
+ NULL, /* finish */
+ 0, /* flags */
+ NULL /* app_data */
+ };
+
+/* Our internal DH_METHOD that we provide pointers to */
+static DH_METHOD cswift_dh =
+ {
+ "CryptoSwift DH method",
+ NULL,
+ NULL,
+ cswift_mod_exp_dh,
+ NULL,
+ NULL,
+ 0,
+ NULL
+ };
+
+/* Our ENGINE structure. */
+static ENGINE engine_cswift =
+ {
+ "cswift",
+ "CryptoSwift hardware engine support",
+ &cswift_rsa,
+ &cswift_dsa,
+ &cswift_dh,
+ NULL,
+ cswift_mod_exp,
+ cswift_mod_exp_crt,
+ cswift_init,
+ cswift_finish,
+ NULL, /* no ctrl() */
+ NULL, /* no load_privkey() */
+ NULL, /* no load_pubkey() */
+ 0, /* no flags */
+ 0, 0, /* no references */
+ NULL, NULL /* unlinked */
+ };
+
+/* As this is only ever called once, there's no need for locking
+ * (indeed - the lock will already be held by our caller!!!) */
+ENGINE *ENGINE_cswift()
+ {
+ RSA_METHOD *meth1;
+ DH_METHOD *meth2;
+
+ /* We know that the "PKCS1_SSLeay()" functions hook properly
+ * to the cswift-specific mod_exp and mod_exp_crt so we use
+ * those functions. NB: We don't use ENGINE_openssl() or
+ * anything "more generic" because something like the RSAref
+ * code may not hook properly, and if you own one of these
+ * cards then you have the right to do RSA operations on it
+ * anyway! */
+ meth1 = RSA_PKCS1_SSLeay();
+ cswift_rsa.rsa_pub_enc = meth1->rsa_pub_enc;
+ cswift_rsa.rsa_pub_dec = meth1->rsa_pub_dec;
+ cswift_rsa.rsa_priv_enc = meth1->rsa_priv_enc;
+ cswift_rsa.rsa_priv_dec = meth1->rsa_priv_dec;
+
+ /* Much the same for Diffie-Hellman */
+ meth2 = DH_OpenSSL();
+ cswift_dh.generate_key = meth2->generate_key;
+ cswift_dh.compute_key = meth2->compute_key;
+ return &engine_cswift;
+ }
+
+/* This is a process-global DSO handle used for loading and unloading
+ * the CryptoSwift library. NB: This is only set (or unset) during an
+ * init() or finish() call (reference counts permitting) and they're
+ * operating with global locks, so this should be thread-safe
+ * implicitly. */
+static DSO *cswift_dso = NULL;
+
+/* These are the function pointers that are (un)set when the library has
+ * successfully (un)loaded. */
+t_swAcquireAccContext *p_CSwift_AcquireAccContext = NULL;
+t_swAttachKeyParam *p_CSwift_AttachKeyParam = NULL;
+t_swSimpleRequest *p_CSwift_SimpleRequest = NULL;
+t_swReleaseAccContext *p_CSwift_ReleaseAccContext = NULL;
+
+/* Used in the DSO operations. */
+static const char *CSWIFT_LIBNAME = "swift";
+static const char *CSWIFT_F1 = "swAcquireAccContext";
+static const char *CSWIFT_F2 = "swAttachKeyParam";
+static const char *CSWIFT_F3 = "swSimpleRequest";
+static const char *CSWIFT_F4 = "swReleaseAccContext";
+
+
+/* CryptoSwift library functions and mechanics - these are used by the
+ * higher-level functions further down. NB: As and where there's no
+ * error checking, take a look lower down where these functions are
+ * called, the checking and error handling is probably down there. */
+
+/* utility function to obtain a context */
+static int get_context(SW_CONTEXT_HANDLE *hac)
+ {
+ SW_STATUS status;
+
+ status = p_CSwift_AcquireAccContext(hac);
+ if(status != SW_OK)
+ return 0;
+ return 1;
+ }
+
+/* similarly to release one. */
+static void release_context(SW_CONTEXT_HANDLE hac)
+ {
+ p_CSwift_ReleaseAccContext(hac);
+ }
+
+/* (de)initialisation functions. */
+static int cswift_init()
+ {
+ SW_CONTEXT_HANDLE hac;
+ t_swAcquireAccContext *p1;
+ t_swAttachKeyParam *p2;
+ t_swSimpleRequest *p3;
+ t_swReleaseAccContext *p4;
+
+ if(cswift_dso != NULL)
+ {
+ ENGINEerr(ENGINE_F_CSWIFT_INIT,ENGINE_R_ALREADY_LOADED);
+ goto err;
+ }
+ /* Attempt to load libswift.so/swift.dll/whatever. */
+ cswift_dso = DSO_load(NULL, CSWIFT_LIBNAME, NULL, 0);
+ if(cswift_dso == NULL)
+ {
+ ENGINEerr(ENGINE_F_CSWIFT_INIT,ENGINE_R_DSO_FAILURE);
+ goto err;
+ }
+ if(!(p1 = (t_swAcquireAccContext *)
+ DSO_bind_func(cswift_dso, CSWIFT_F1)) ||
+ !(p2 = (t_swAttachKeyParam *)
+ DSO_bind_func(cswift_dso, CSWIFT_F2)) ||
+ !(p3 = (t_swSimpleRequest *)
+ DSO_bind_func(cswift_dso, CSWIFT_F3)) ||
+ !(p4 = (t_swReleaseAccContext *)
+ DSO_bind_func(cswift_dso, CSWIFT_F4)))
+ {
+ ENGINEerr(ENGINE_F_CSWIFT_INIT,ENGINE_R_DSO_FAILURE);
+ goto err;
+ }
+ /* Copy the pointers */
+ p_CSwift_AcquireAccContext = p1;
+ p_CSwift_AttachKeyParam = p2;
+ p_CSwift_SimpleRequest = p3;
+ p_CSwift_ReleaseAccContext = p4;
+ /* Try and get a context - if not, we may have a DSO but no
+ * accelerator! */
+ if(!get_context(&hac))
+ {
+ ENGINEerr(ENGINE_F_CSWIFT_INIT,ENGINE_R_UNIT_FAILURE);
+ goto err;
+ }
+ release_context(hac);
+ /* Everything's fine. */
+ return 1;
+err:
+ if(cswift_dso)
+ DSO_free(cswift_dso);
+ p_CSwift_AcquireAccContext = NULL;
+ p_CSwift_AttachKeyParam = NULL;
+ p_CSwift_SimpleRequest = NULL;
+ p_CSwift_ReleaseAccContext = NULL;
+ return 0;
+ }
+
+static int cswift_finish()
+ {
+ if(cswift_dso == NULL)
+ {
+ ENGINEerr(ENGINE_F_CSWIFT_FINISH,ENGINE_R_NOT_LOADED);
+ return 0;
+ }
+ if(!DSO_free(cswift_dso))
+ {
+ ENGINEerr(ENGINE_F_CSWIFT_FINISH,ENGINE_R_DSO_FAILURE);
+ return 0;
+ }
+ cswift_dso = NULL;
+ p_CSwift_AcquireAccContext = NULL;
+ p_CSwift_AttachKeyParam = NULL;
+ p_CSwift_SimpleRequest = NULL;
+ p_CSwift_ReleaseAccContext = NULL;
+ return 1;
+ }
+
+/* Un petit mod_exp */
+static int cswift_mod_exp(BIGNUM *r, BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *m, BN_CTX *ctx)
+ {
+ /* I need somewhere to store temporary serialised values for
+ * use with the CryptoSwift API calls. A neat cheat - I'll use
+ * BIGNUMs from the BN_CTX but access their arrays directly as
+ * byte arrays <grin>. This way I don't have to clean anything
+ * up. */
+ BIGNUM *modulus;
+ BIGNUM *exponent;
+ BIGNUM *argument;
+ BIGNUM *result;
+ SW_STATUS sw_status;
+ SW_LARGENUMBER arg, res;
+ SW_PARAM sw_param;
+ SW_CONTEXT_HANDLE hac;
+ int to_return, acquired;
+
+ modulus = exponent = argument = result = NULL;
+ to_return = 0; /* expect failure */
+ acquired = 0;
+
+ if(!get_context(&hac))
+ {
+ ENGINEerr(ENGINE_F_CSWIFT_MOD_EXP,ENGINE_R_GET_HANDLE_FAILED);
+ goto err;
+ }
+ acquired = 1;
+ /* Prepare the params */
+ modulus = BN_CTX_get(ctx);
+ exponent = BN_CTX_get(ctx);
+ argument = BN_CTX_get(ctx);
+ result = BN_CTX_get(ctx);
+ if(!modulus || !exponent || !argument || !result)
+ {
+ ENGINEerr(ENGINE_F_CSWIFT_MOD_EXP,ENGINE_R_BN_CTX_FULL);
+ goto err;
+ }
+ if(!bn_wexpand(modulus, m->top) || !bn_wexpand(exponent, p->top) ||
+ !bn_wexpand(argument, a->top) || !bn_wexpand(result, m->top))
+ {
+ ENGINEerr(ENGINE_F_CSWIFT_MOD_EXP,ENGINE_R_BN_EXPAND_FAIL);
+ goto err;
+ }
+ sw_param.type = SW_ALG_EXP;
+ sw_param.up.exp.modulus.nbytes = BN_bn2bin(m,
+ (unsigned char *)modulus->d);
+ sw_param.up.exp.modulus.value = (unsigned char *)modulus->d;
+ sw_param.up.exp.exponent.nbytes = BN_bn2bin(p,
+ (unsigned char *)exponent->d);
+ sw_param.up.exp.exponent.value = (unsigned char *)exponent->d;
+ /* Attach the key params */
+ sw_status = p_CSwift_AttachKeyParam(hac, &sw_param);
+ switch(sw_status)
+ {
+ case SW_OK:
+ break;
+ case SW_ERR_INPUT_SIZE:
+ ENGINEerr(ENGINE_F_CSWIFT_MOD_EXP,
+ ENGINE_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
+ goto err;
+ default:
+ {
+ char tmpbuf[20];
+ ENGINEerr(ENGINE_F_CSWIFT_MOD_EXP,ENGINE_R_REQUEST_FAILED);
+ sprintf(tmpbuf, "%ld", sw_status);
+ ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf);
+ }
+ goto err;
+ }
+ /* Prepare the argument and response */
+ arg.nbytes = BN_bn2bin(a, (unsigned char *)argument->d);
+ arg.value = (unsigned char *)argument->d;
+ res.nbytes = BN_num_bytes(m);
+ memset(result->d, 0, res.nbytes);
+ res.value = (unsigned char *)result->d;
+ /* Perform the operation */
+ if((sw_status = p_CSwift_SimpleRequest(hac, SW_CMD_MODEXP, &arg, 1,
+ &res, 1)) != SW_OK)
+ {
+ char tmpbuf[20];
+ ENGINEerr(ENGINE_F_CSWIFT_MOD_EXP,ENGINE_R_REQUEST_FAILED);
+ sprintf(tmpbuf, "%ld", sw_status);
+ ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf);
+ goto err;
+ }
+ /* Convert the response */
+ BN_bin2bn((unsigned char *)result->d, res.nbytes, r);
+ to_return = 1;
+err:
+ if(acquired)
+ release_context(hac);
+ if(modulus) ctx->tos--;
+ if(exponent) ctx->tos--;
+ if(argument) ctx->tos--;
+ if(result) ctx->tos--;
+ return to_return;
+ }
+
+/* Un petit mod_exp chinois */
+static int cswift_mod_exp_crt(BIGNUM *r, BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *q, const BIGNUM *dmp1,
+ const BIGNUM *dmq1, const BIGNUM *iqmp, BN_CTX *ctx)
+ {
+ SW_STATUS sw_status;
+ SW_LARGENUMBER arg, res;
+ SW_PARAM sw_param;
+ SW_CONTEXT_HANDLE hac;
+ BIGNUM *rsa_p = NULL;
+ BIGNUM *rsa_q = NULL;
+ BIGNUM *rsa_dmp1 = NULL;
+ BIGNUM *rsa_dmq1 = NULL;
+ BIGNUM *rsa_iqmp = NULL;
+ BIGNUM *argument = NULL;
+ BIGNUM *result = NULL;
+ int to_return = 0; /* expect failure */
+ int acquired = 0;
+
+ if(!get_context(&hac))
+ {
+ ENGINEerr(ENGINE_F_CSWIFT_MOD_EXP_CRT,ENGINE_R_GET_HANDLE_FAILED);
+ goto err;
+ }
+ acquired = 1;
+ /* Prepare the params */
+ rsa_p = BN_CTX_get(ctx);
+ rsa_q = BN_CTX_get(ctx);
+ rsa_dmp1 = BN_CTX_get(ctx);
+ rsa_dmq1 = BN_CTX_get(ctx);
+ rsa_iqmp = BN_CTX_get(ctx);
+ argument = BN_CTX_get(ctx);
+ result = BN_CTX_get(ctx);
+ if(!rsa_p || !rsa_q || !rsa_dmp1 || !rsa_dmq1 || !rsa_iqmp ||
+ !argument || !result)
+ {
+ ENGINEerr(ENGINE_F_CSWIFT_MOD_EXP_CRT,ENGINE_R_BN_CTX_FULL);
+ goto err;
+ }
+ if(!bn_wexpand(rsa_p, p->top) || !bn_wexpand(rsa_q, q->top) ||
+ !bn_wexpand(rsa_dmp1, dmp1->top) ||
+ !bn_wexpand(rsa_dmq1, dmq1->top) ||
+ !bn_wexpand(rsa_iqmp, iqmp->top) ||
+ !bn_wexpand(argument, a->top) ||
+ !bn_wexpand(result, p->top + q->top))
+ {
+ ENGINEerr(ENGINE_F_CSWIFT_MOD_EXP_CRT,ENGINE_R_BN_EXPAND_FAIL);
+ goto err;
+ }
+ sw_param.type = SW_ALG_CRT;
+ sw_param.up.crt.p.nbytes = BN_bn2bin(p, (unsigned char *)rsa_p->d);
+ sw_param.up.crt.p.value = (unsigned char *)rsa_p->d;
+ sw_param.up.crt.q.nbytes = BN_bn2bin(q, (unsigned char *)rsa_q->d);
+ sw_param.up.crt.q.value = (unsigned char *)rsa_q->d;
+ sw_param.up.crt.dmp1.nbytes = BN_bn2bin(dmp1,
+ (unsigned char *)rsa_dmp1->d);
+ sw_param.up.crt.dmp1.value = (unsigned char *)rsa_dmp1->d;
+ sw_param.up.crt.dmq1.nbytes = BN_bn2bin(dmq1,
+ (unsigned char *)rsa_dmq1->d);
+ sw_param.up.crt.dmq1.value = (unsigned char *)rsa_dmq1->d;
+ sw_param.up.crt.iqmp.nbytes = BN_bn2bin(iqmp,
+ (unsigned char *)rsa_iqmp->d);
+ sw_param.up.crt.iqmp.value = (unsigned char *)rsa_iqmp->d;
+ /* Attach the key params */
+ sw_status = p_CSwift_AttachKeyParam(hac, &sw_param);
+ switch(sw_status)
+ {
+ case SW_OK:
+ break;
+ case SW_ERR_INPUT_SIZE:
+ ENGINEerr(ENGINE_F_CSWIFT_MOD_EXP_CRT,
+ ENGINE_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
+ goto err;
+ default:
+ {
+ char tmpbuf[20];
+ ENGINEerr(ENGINE_F_CSWIFT_MOD_EXP_CRT,ENGINE_R_REQUEST_FAILED);
+ sprintf(tmpbuf, "%ld", sw_status);
+ ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf);
+ }
+ goto err;
+ }
+ /* Prepare the argument and response */
+ arg.nbytes = BN_bn2bin(a, (unsigned char *)argument->d);
+ arg.value = (unsigned char *)argument->d;
+ res.nbytes = 2 * BN_num_bytes(p);
+ memset(result->d, 0, res.nbytes);
+ res.value = (unsigned char *)result->d;
+ /* Perform the operation */
+ if((sw_status = p_CSwift_SimpleRequest(hac, SW_CMD_MODEXP_CRT, &arg, 1,
+ &res, 1)) != SW_OK)
+ {
+ char tmpbuf[20];
+ ENGINEerr(ENGINE_F_CSWIFT_MOD_EXP_CRT,ENGINE_R_REQUEST_FAILED);
+ sprintf(tmpbuf, "%ld", sw_status);
+ ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf);
+ goto err;
+ }
+ /* Convert the response */
+ BN_bin2bn((unsigned char *)result->d, res.nbytes, r);
+ to_return = 1;
+err:
+ if(acquired)
+ release_context(hac);
+ if(rsa_p) ctx->tos--;
+ if(rsa_q) ctx->tos--;
+ if(rsa_dmp1) ctx->tos--;
+ if(rsa_dmq1) ctx->tos--;
+ if(rsa_iqmp) ctx->tos--;
+ if(argument) ctx->tos--;
+ if(result) ctx->tos--;
+ return to_return;
+ }
+
+static int cswift_rsa_mod_exp(BIGNUM *r0, BIGNUM *I, RSA *rsa)
+ {
+ BN_CTX *ctx;
+ int to_return = 0;
+
+ if((ctx = BN_CTX_new()) == NULL)
+ goto err;
+ if(!rsa->p || !rsa->q || !rsa->dmp1 || !rsa->dmq1 || !rsa->iqmp)
+ {
+ ENGINEerr(ENGINE_F_CSWIFT_RSA_MOD_EXP,ENGINE_R_MISSING_KEY_COMPONENTS);
+ goto err;
+ }
+ to_return = cswift_mod_exp_crt(r0, I, rsa->p, rsa->q, rsa->dmp1,
+ rsa->dmq1, rsa->iqmp, ctx);
+err:
+ if(ctx)
+ BN_CTX_free(ctx);
+ return to_return;
+ }
+
+/* This function is aliased to mod_exp (with the mont stuff dropped). */
+static int cswift_mod_exp_mont(BIGNUM *r, BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
+ {
+ return cswift_mod_exp(r, a, p, m, ctx);
+ }
+
+static DSA_SIG *cswift_dsa_sign(const unsigned char *dgst, int dlen, DSA *dsa)
+ {
+ SW_CONTEXT_HANDLE hac;
+ SW_PARAM sw_param;
+ SW_STATUS sw_status;
+ SW_LARGENUMBER arg, res;
+ unsigned char *ptr;
+ BN_CTX *ctx;
+ BIGNUM *dsa_p = NULL;
+ BIGNUM *dsa_q = NULL;
+ BIGNUM *dsa_g = NULL;
+ BIGNUM *dsa_key = NULL;
+ BIGNUM *result = NULL;
+ DSA_SIG *to_return = NULL;
+ int acquired = 0;
+
+ if((ctx = BN_CTX_new()) == NULL)
+ goto err;
+ if(!get_context(&hac))
+ {
+ ENGINEerr(ENGINE_F_CSWIFT_DSA_SIGN,ENGINE_R_GET_HANDLE_FAILED);
+ goto err;
+ }
+ acquired = 1;
+ /* Prepare the params */
+ dsa_p = BN_CTX_get(ctx);
+ dsa_q = BN_CTX_get(ctx);
+ dsa_g = BN_CTX_get(ctx);
+ dsa_key = BN_CTX_get(ctx);
+ result = BN_CTX_get(ctx);
+ if(!dsa_p || !dsa_q || !dsa_g || !dsa_key || !result)
+ {
+ ENGINEerr(ENGINE_F_CSWIFT_DSA_SIGN,ENGINE_R_BN_CTX_FULL);
+ goto err;
+ }
+ if(!bn_wexpand(dsa_p, dsa->p->top) ||
+ !bn_wexpand(dsa_q, dsa->q->top) ||
+ !bn_wexpand(dsa_g, dsa->g->top) ||
+ !bn_wexpand(dsa_key, dsa->priv_key->top) ||
+ !bn_wexpand(result, dsa->p->top))
+ {
+ ENGINEerr(ENGINE_F_CSWIFT_DSA_SIGN,ENGINE_R_BN_EXPAND_FAIL);
+ goto err;
+ }
+ sw_param.type = SW_ALG_DSA;
+ sw_param.up.dsa.p.nbytes = BN_bn2bin(dsa->p,
+ (unsigned char *)dsa_p->d);
+ sw_param.up.dsa.p.value = (unsigned char *)dsa_p->d;
+ sw_param.up.dsa.q.nbytes = BN_bn2bin(dsa->q,
+ (unsigned char *)dsa_q->d);
+ sw_param.up.dsa.q.value = (unsigned char *)dsa_q->d;
+ sw_param.up.dsa.g.nbytes = BN_bn2bin(dsa->g,
+ (unsigned char *)dsa_g->d);
+ sw_param.up.dsa.g.value = (unsigned char *)dsa_g->d;
+ sw_param.up.dsa.key.nbytes = BN_bn2bin(dsa->priv_key,
+ (unsigned char *)dsa_key->d);
+ sw_param.up.dsa.key.value = (unsigned char *)dsa_key->d;
+ /* Attach the key params */
+ sw_status = p_CSwift_AttachKeyParam(hac, &sw_param);
+ switch(sw_status)
+ {
+ case SW_OK:
+ break;
+ case SW_ERR_INPUT_SIZE:
+ ENGINEerr(ENGINE_F_CSWIFT_DSA_SIGN,
+ ENGINE_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
+ goto err;
+ default:
+ {
+ char tmpbuf[20];
+ ENGINEerr(ENGINE_F_CSWIFT_DSA_SIGN,ENGINE_R_REQUEST_FAILED);
+ sprintf(tmpbuf, "%ld", sw_status);
+ ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf);
+ }
+ goto err;
+ }
+ /* Prepare the argument and response */
+ arg.nbytes = dlen;
+ arg.value = (unsigned char *)dgst;
+ res.nbytes = BN_num_bytes(dsa->p);
+ memset(result->d, 0, res.nbytes);
+ res.value = (unsigned char *)result->d;
+ /* Perform the operation */
+ sw_status = p_CSwift_SimpleRequest(hac, SW_CMD_DSS_SIGN, &arg, 1,
+ &res, 1);
+ if(sw_status != SW_OK)
+ {
+ char tmpbuf[20];
+ ENGINEerr(ENGINE_F_CSWIFT_DSA_SIGN,ENGINE_R_REQUEST_FAILED);
+ sprintf(tmpbuf, "%ld", sw_status);
+ ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf);
+ goto err;
+ }
+ /* Convert the response */
+ ptr = (unsigned char *)result->d;
+ if((to_return = DSA_SIG_new()) == NULL)
+ goto err;
+ to_return->r = BN_bin2bn((unsigned char *)result->d, 20, NULL);
+ to_return->s = BN_bin2bn((unsigned char *)result->d + 20, 20, NULL);
+
+err:
+ if(acquired)
+ release_context(hac);
+ if(dsa_p) ctx->tos--;
+ if(dsa_q) ctx->tos--;
+ if(dsa_g) ctx->tos--;
+ if(dsa_key) ctx->tos--;
+ if(result) ctx->tos--;
+ if(ctx)
+ BN_CTX_free(ctx);
+ return to_return;
+ }
+
+static int cswift_dsa_verify(const unsigned char *dgst, int dgst_len,
+ DSA_SIG *sig, DSA *dsa)
+ {
+ SW_CONTEXT_HANDLE hac;
+ SW_PARAM sw_param;
+ SW_STATUS sw_status;
+ SW_LARGENUMBER arg[2], res;
+ unsigned long sig_result;
+ BN_CTX *ctx;
+ BIGNUM *dsa_p = NULL;
+ BIGNUM *dsa_q = NULL;
+ BIGNUM *dsa_g = NULL;
+ BIGNUM *dsa_key = NULL;
+ BIGNUM *argument = NULL;
+ int to_return = -1;
+ int acquired = 0;
+
+ if((ctx = BN_CTX_new()) == NULL)
+ goto err;
+ if(!get_context(&hac))
+ {
+ ENGINEerr(ENGINE_F_CSWIFT_DSA_VERIFY,ENGINE_R_GET_HANDLE_FAILED);
+ goto err;
+ }
+ acquired = 1;
+ /* Prepare the params */
+ dsa_p = BN_CTX_get(ctx);
+ dsa_q = BN_CTX_get(ctx);
+ dsa_g = BN_CTX_get(ctx);
+ dsa_key = BN_CTX_get(ctx);
+ argument = BN_CTX_get(ctx);
+ if(!dsa_p || !dsa_q || !dsa_g || !dsa_key || !argument)
+ {
+ ENGINEerr(ENGINE_F_CSWIFT_DSA_VERIFY,ENGINE_R_BN_CTX_FULL);
+ goto err;
+ }
+ if(!bn_wexpand(dsa_p, dsa->p->top) ||
+ !bn_wexpand(dsa_q, dsa->q->top) ||
+ !bn_wexpand(dsa_g, dsa->g->top) ||
+ !bn_wexpand(dsa_key, dsa->pub_key->top) ||
+ !bn_wexpand(argument, 40))
+ {
+ ENGINEerr(ENGINE_F_CSWIFT_DSA_VERIFY,ENGINE_R_BN_EXPAND_FAIL);
+ goto err;
+ }
+ sw_param.type = SW_ALG_DSA;
+ sw_param.up.dsa.p.nbytes = BN_bn2bin(dsa->p,
+ (unsigned char *)dsa_p->d);
+ sw_param.up.dsa.p.value = (unsigned char *)dsa_p->d;
+ sw_param.up.dsa.q.nbytes = BN_bn2bin(dsa->q,
+ (unsigned char *)dsa_q->d);
+ sw_param.up.dsa.q.value = (unsigned char *)dsa_q->d;
+ sw_param.up.dsa.g.nbytes = BN_bn2bin(dsa->g,
+ (unsigned char *)dsa_g->d);
+ sw_param.up.dsa.g.value = (unsigned char *)dsa_g->d;
+ sw_param.up.dsa.key.nbytes = BN_bn2bin(dsa->pub_key,
+ (unsigned char *)dsa_key->d);
+ sw_param.up.dsa.key.value = (unsigned char *)dsa_key->d;
+ /* Attach the key params */
+ sw_status = p_CSwift_AttachKeyParam(hac, &sw_param);
+ switch(sw_status)
+ {
+ case SW_OK:
+ break;
+ case SW_ERR_INPUT_SIZE:
+ ENGINEerr(ENGINE_F_CSWIFT_DSA_VERIFY,
+ ENGINE_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
+ goto err;
+ default:
+ {
+ char tmpbuf[20];
+ ENGINEerr(ENGINE_F_CSWIFT_DSA_VERIFY,ENGINE_R_REQUEST_FAILED);
+ sprintf(tmpbuf, "%ld", sw_status);
+ ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf);
+ }
+ goto err;
+ }
+ /* Prepare the argument and response */
+ arg[0].nbytes = dgst_len;
+ arg[0].value = (unsigned char *)dgst;
+ arg[1].nbytes = 40;
+ arg[1].value = (unsigned char *)argument->d;
+ memset(arg[1].value, 0, 40);
+ BN_bn2bin(sig->r, arg[1].value + 20 - BN_num_bytes(sig->r));
+ BN_bn2bin(sig->s, arg[1].value + 40 - BN_num_bytes(sig->s));
+ res.nbytes = 4; /* unsigned long */
+ res.value = (unsigned char *)(&sig_result);
+ /* Perform the operation */
+ sw_status = p_CSwift_SimpleRequest(hac, SW_CMD_DSS_VERIFY, arg, 2,
+ &res, 1);
+ if(sw_status != SW_OK)
+ {
+ char tmpbuf[20];
+ ENGINEerr(ENGINE_F_CSWIFT_DSA_VERIFY,ENGINE_R_REQUEST_FAILED);
+ sprintf(tmpbuf, "%ld", sw_status);
+ ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf);
+ goto err;
+ }
+ /* Convert the response */
+ to_return = ((sig_result == 0) ? 0 : 1);
+
+err:
+ if(acquired)
+ release_context(hac);
+ if(dsa_p) ctx->tos--;
+ if(dsa_q) ctx->tos--;
+ if(dsa_g) ctx->tos--;
+ if(dsa_key) ctx->tos--;
+ if(argument) ctx->tos--;
+ if(ctx)
+ BN_CTX_free(ctx);
+ return to_return;
+ }
+
+/* This function is aliased to mod_exp (with the dh and mont dropped). */
+static int cswift_mod_exp_dh(DH *dh, BIGNUM *r, BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
+ {
+ return cswift_mod_exp(r, a, p, m, ctx);
+ }
+
+#endif /* !NO_HW_CSWIFT */
+#endif /* !NO_HW */
diff --git a/crypto/engine/hw_ncipher.c b/crypto/engine/hw_ncipher.c
new file mode 100644
index 0000000000..f6b06e468f
--- /dev/null
+++ b/crypto/engine/hw_ncipher.c
@@ -0,0 +1,1018 @@
+/* crypto/engine/hw_ncipher.c -*- mode: C; c-file-style: "eay" -*- */
+/* Written by Richard Levitte (richard@levitte.org), Geoff Thorpe
+ * (geoff@geoffthorpe.net) and Dr Stephen N Henson (shenson@bigfoot.com)
+ * for the OpenSSL project 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 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 <openssl/crypto.h>
+#include <openssl/pem.h>
+#include "cryptlib.h"
+#include <openssl/dso.h>
+#include "engine_int.h"
+#include <openssl/engine.h>
+
+#ifndef NO_HW
+#ifndef NO_HW_NCIPHER
+
+/* Attribution notice: nCipher have said several times that it's OK for
+ * us to implement a general interface to their boxes, and recently declared
+ * their HWCryptoHook to be public, and therefore available for us to use.
+ * Thanks, nCipher.
+ *
+ * The hwcryptohook.h included here is from May 2000.
+ * [Richard Levitte]
+ */
+#ifdef FLAT_INC
+#include "hwcryptohook.h"
+#else
+#include "vendor_defns/hwcryptohook.h"
+#endif
+
+static int hwcrhk_init(void);
+static int hwcrhk_finish(void);
+static int hwcrhk_ctrl(int cmd, long i, void *p, void (*f)());
+
+/* Functions to handle mutexes */
+static int hwcrhk_mutex_init(HWCryptoHook_Mutex*, HWCryptoHook_CallerContext*);
+static int hwcrhk_mutex_lock(HWCryptoHook_Mutex*);
+static void hwcrhk_mutex_unlock(HWCryptoHook_Mutex*);
+static void hwcrhk_mutex_destroy(HWCryptoHook_Mutex*);
+
+/* BIGNUM stuff */
+static int hwcrhk_mod_exp(BIGNUM *r, BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *m, BN_CTX *ctx);
+
+/* RSA stuff */
+static int hwcrhk_rsa_mod_exp(BIGNUM *r, BIGNUM *I, RSA *rsa);
+/* This function is aliased to mod_exp (with the mont stuff dropped). */
+static int hwcrhk_mod_exp_mont(BIGNUM *r, BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
+
+/* DH stuff */
+/* This function is alised to mod_exp (with the DH and mont dropped). */
+static int hwcrhk_mod_exp_dh(DH *dh, BIGNUM *r, BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
+
+/* RAND stuff */
+static int hwcrhk_rand_bytes(unsigned char *buf, int num);
+static int hwcrhk_rand_status(void);
+
+/* KM stuff */
+static EVP_PKEY *hwcrhk_load_privkey(const char *key_id,
+ const char *passphrase);
+static EVP_PKEY *hwcrhk_load_pubkey(const char *key_id,
+ const char *passphrase);
+static void hwcrhk_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad,
+ int ind,long argl, void *argp);
+
+/* Interaction stuff */
+static int hwcrhk_get_pass(const char *prompt_info,
+ int *len_io, char *buf,
+ HWCryptoHook_PassphraseContext *ppctx,
+ HWCryptoHook_CallerContext *cactx);
+static void hwcrhk_log_message(void *logstr, const char *message);
+
+/* Our internal RSA_METHOD that we provide pointers to */
+static RSA_METHOD hwcrhk_rsa =
+ {
+ "nCipher RSA method",
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ hwcrhk_rsa_mod_exp,
+ hwcrhk_mod_exp_mont,
+ NULL,
+ NULL,
+ 0,
+ NULL,
+ NULL,
+ NULL
+ };
+
+/* Our internal DH_METHOD that we provide pointers to */
+static DH_METHOD hwcrhk_dh =
+ {
+ "nCipher DH method",
+ NULL,
+ NULL,
+ hwcrhk_mod_exp_dh,
+ NULL,
+ NULL,
+ 0,
+ NULL
+ };
+
+static RAND_METHOD hwcrhk_rand =
+ {
+ /* "nCipher RAND method", */
+ NULL,
+ hwcrhk_rand_bytes,
+ NULL,
+ NULL,
+ hwcrhk_rand_bytes,
+ hwcrhk_rand_status,
+ };
+
+/* Our ENGINE structure. */
+static ENGINE engine_hwcrhk =
+ {
+ "chil",
+ "nCipher hardware engine support",
+ &hwcrhk_rsa,
+ NULL,
+ &hwcrhk_dh,
+ &hwcrhk_rand,
+ hwcrhk_mod_exp,
+ NULL,
+ hwcrhk_init,
+ hwcrhk_finish,
+ hwcrhk_ctrl,
+ hwcrhk_load_privkey,
+ hwcrhk_load_pubkey,
+ 0, /* no flags */
+ 0, 0, /* no references */
+ NULL, NULL /* unlinked */
+ };
+
+/* Internal stuff for HWCryptoHook */
+
+/* Some structures needed for proper use of thread locks */
+/* hwcryptohook.h has some typedefs that turn struct HWCryptoHook_MutexValue
+ into HWCryptoHook_Mutex */
+struct HWCryptoHook_MutexValue
+ {
+ int lockid;
+ };
+
+/* hwcryptohook.h has some typedefs that turn
+ struct HWCryptoHook_PassphraseContextValue
+ into HWCryptoHook_PassphraseContext */
+struct HWCryptoHook_PassphraseContextValue
+ {
+ void *any;
+ };
+
+/* hwcryptohook.h has some typedefs that turn
+ struct HWCryptoHook_CallerContextValue
+ into HWCryptoHook_CallerContext */
+struct HWCryptoHook_CallerContextValue
+ {
+ void *any;
+ };
+
+/* The MPI structure in HWCryptoHook is pretty compatible with OpenSSL
+ BIGNUM's, so lets define a couple of conversion macros */
+#define BN2MPI(mp, bn) \
+ {mp.size = bn->top * sizeof(BN_ULONG); mp.buf = (unsigned char *)bn->d;}
+#define MPI2BN(bn, mp) \
+ {mp.size = bn->dmax * sizeof(BN_ULONG); mp.buf = (unsigned char *)bn->d;}
+
+#if 0 /* Card and password management is not yet supported */
+/* HWCryptoHook callbacks. insert_card() and get_pass() are not yet
+ defined, because we haven't quite decided on the proper form yet.
+ log_message() just adds an entry in the error stack. I don't know
+ if that's good or bad... */
+static int insert_card(const char *prompt_info,
+ const char *wrong_info,
+ HWCryptoHook_PassphraseContext *ppctx,
+ HWCryptoHook_CallerContext *cactx);
+static int get_pass(const char *prompt_info,
+ int *len_io, char *buf,
+ HWCryptoHook_PassphraseContext *ppctx,
+ HWCryptoHook_CallerContext *cactx);
+#endif
+
+static BIO *logstream = NULL;
+static pem_password_cb *password_callback = NULL;
+#if 0
+static void *password_callback_userdata = NULL;
+#endif
+static int disable_mutex_callbacks = 0;
+
+/* Stuff to pass to the HWCryptoHook library */
+static HWCryptoHook_InitInfo hwcrhk_globals = {
+ 0, /* Flags */
+ &logstream, /* logstream */
+ sizeof(BN_ULONG), /* limbsize */
+ 0, /* mslimb first: false for BNs */
+ -1, /* msbyte first: use native */
+ 0, /* Max mutexes, 0 = no small limit */
+ 0, /* Max simultaneous, 0 = default */
+
+ /* The next few are mutex stuff: we write wrapper functions
+ around the OS mutex functions. We initialise them to 0
+ here, and change that to actual function pointers in hwcrhk_init()
+ if dynamic locks are supported (that is, if the application
+ programmer has made sure of setting up callbacks bafore starting
+ this engine) *and* if disable_mutex_callbacks hasn't been set by
+ a call to ENGINE_ctrl(ENGINE_CTRL_CHIL_NO_LOCKING). */
+ sizeof(HWCryptoHook_Mutex),
+ 0,
+ 0,
+ 0,
+ 0,
+
+ /* The next few are condvar stuff: we write wrapper functions
+ round the OS functions. Currently not implemented and not
+ and absolute necessity even in threaded programs, therefore
+ 0'ed. Will hopefully be implemented some day, since it
+ enhances the efficiency of HWCryptoHook. */
+ 0, /* sizeof(HWCryptoHook_CondVar), */
+ 0, /* hwcrhk_cv_init, */
+ 0, /* hwcrhk_cv_wait, */
+ 0, /* hwcrhk_cv_signal, */
+ 0, /* hwcrhk_cv_broadcast, */
+ 0, /* hwcrhk_cv_destroy, */
+
+ hwcrhk_get_pass, /* pass phrase */
+ 0, /* insert_card, */ /* insert a card */
+ hwcrhk_log_message /* Log message */
+};
+
+
+/* Now, to our own code */
+
+/* As this is only ever called once, there's no need for locking
+ * (indeed - the lock will already be held by our caller!!!) */
+ENGINE *ENGINE_ncipher()
+ {
+ RSA_METHOD *meth1;
+ DH_METHOD *meth2;
+
+ /* We know that the "PKCS1_SSLeay()" functions hook properly
+ * to the cswift-specific mod_exp and mod_exp_crt so we use
+ * those functions. NB: We don't use ENGINE_openssl() or
+ * anything "more generic" because something like the RSAref
+ * code may not hook properly, and if you own one of these
+ * cards then you have the right to do RSA operations on it
+ * anyway! */
+ meth1 = RSA_PKCS1_SSLeay();
+ hwcrhk_rsa.rsa_pub_enc = meth1->rsa_pub_enc;
+ hwcrhk_rsa.rsa_pub_dec = meth1->rsa_pub_dec;
+ hwcrhk_rsa.rsa_priv_enc = meth1->rsa_priv_enc;
+ hwcrhk_rsa.rsa_priv_dec = meth1->rsa_priv_dec;
+
+ /* Much the same for Diffie-Hellman */
+ meth2 = DH_OpenSSL();
+ hwcrhk_dh.generate_key = meth2->generate_key;
+ hwcrhk_dh.compute_key = meth2->compute_key;
+ return &engine_hwcrhk;
+ }
+
+/* This is a process-global DSO handle used for loading and unloading
+ * the HWCryptoHook library. NB: This is only set (or unset) during an
+ * init() or finish() call (reference counts permitting) and they're
+ * operating with global locks, so this should be thread-safe
+ * implicitly. */
+static DSO *hwcrhk_dso = NULL;
+static HWCryptoHook_ContextHandle hwcrhk_context = 0;
+static int hndidx = -1; /* Index for KM handle. Not really used yet. */
+
+/* These are the function pointers that are (un)set when the library has
+ * successfully (un)loaded. */
+static HWCryptoHook_Init_t *p_hwcrhk_Init = NULL;
+static HWCryptoHook_Finish_t *p_hwcrhk_Finish = NULL;
+static HWCryptoHook_ModExp_t *p_hwcrhk_ModExp = NULL;
+static HWCryptoHook_RSA_t *p_hwcrhk_RSA = NULL;
+static HWCryptoHook_RandomBytes_t *p_hwcrhk_RandomBytes = NULL;
+static HWCryptoHook_RSALoadKey_t *p_hwcrhk_RSALoadKey = NULL;
+static HWCryptoHook_RSAGetPublicKey_t *p_hwcrhk_RSAGetPublicKey = NULL;
+static HWCryptoHook_RSAUnloadKey_t *p_hwcrhk_RSAUnloadKey = NULL;
+static HWCryptoHook_ModExpCRT_t *p_hwcrhk_ModExpCRT = NULL;
+
+/* Used in the DSO operations. */
+static const char *HWCRHK_LIBNAME = "nfhwcrhk";
+static const char *n_hwcrhk_Init = "HWCryptoHook_Init";
+static const char *n_hwcrhk_Finish = "HWCryptoHook_Finish";
+static const char *n_hwcrhk_ModExp = "HWCryptoHook_ModExp";
+static const char *n_hwcrhk_RSA = "HWCryptoHook_RSA";
+static const char *n_hwcrhk_RandomBytes = "HWCryptoHook_RandomBytes";
+static const char *n_hwcrhk_RSALoadKey = "HWCryptoHook_RSALoadKey";
+static const char *n_hwcrhk_RSAGetPublicKey = "HWCryptoHook_RSAGetPublicKey";
+static const char *n_hwcrhk_RSAUnloadKey = "HWCryptoHook_RSAUnloadKey";
+static const char *n_hwcrhk_ModExpCRT = "HWCryptoHook_ModExpCRT";
+
+/* HWCryptoHook library functions and mechanics - these are used by the
+ * higher-level functions further down. NB: As and where there's no
+ * error checking, take a look lower down where these functions are
+ * called, the checking and error handling is probably down there. */
+
+/* utility function to obtain a context */
+static int get_context(HWCryptoHook_ContextHandle *hac)
+ {
+ char tempbuf[1024];
+ HWCryptoHook_ErrMsgBuf rmsg;
+
+ rmsg.buf = tempbuf;
+ rmsg.size = 1024;
+
+ *hac = p_hwcrhk_Init(&hwcrhk_globals, sizeof(hwcrhk_globals), &rmsg,
+ NULL);
+ if (!*hac)
+ return 0;
+ return 1;
+ }
+
+/* similarly to release one. */
+static void release_context(HWCryptoHook_ContextHandle hac)
+ {
+ p_hwcrhk_Finish(hac);
+ }
+
+/* (de)initialisation functions. */
+static int hwcrhk_init()
+ {
+ HWCryptoHook_Init_t *p1;
+ HWCryptoHook_Finish_t *p2;
+ HWCryptoHook_ModExp_t *p3;
+ HWCryptoHook_RSA_t *p4;
+ HWCryptoHook_RSALoadKey_t *p5;
+ HWCryptoHook_RSAGetPublicKey_t *p6;
+ HWCryptoHook_RSAUnloadKey_t *p7;
+ HWCryptoHook_RandomBytes_t *p8;
+ HWCryptoHook_ModExpCRT_t *p9;
+
+ if(hwcrhk_dso != NULL)
+ {
+ ENGINEerr(ENGINE_F_HWCRHK_INIT,ENGINE_R_ALREADY_LOADED);
+ goto err;
+ }
+ /* Attempt to load libnfhwcrhk.so/nfhwcrhk.dll/whatever. */
+ hwcrhk_dso = DSO_load(NULL, HWCRHK_LIBNAME, NULL, 0);
+ if(hwcrhk_dso == NULL)
+ {
+ ENGINEerr(ENGINE_F_HWCRHK_INIT,ENGINE_R_DSO_FAILURE);
+ goto err;
+ }
+ if(!(p1 = (HWCryptoHook_Init_t *)
+ DSO_bind_func(hwcrhk_dso, n_hwcrhk_Init)) ||
+ !(p2 = (HWCryptoHook_Finish_t *)
+ DSO_bind_func(hwcrhk_dso, n_hwcrhk_Finish)) ||
+ !(p3 = (HWCryptoHook_ModExp_t *)
+ DSO_bind_func(hwcrhk_dso, n_hwcrhk_ModExp)) ||
+ !(p4 = (HWCryptoHook_RSA_t *)
+ DSO_bind_func(hwcrhk_dso, n_hwcrhk_RSA)) ||
+ !(p5 = (HWCryptoHook_RSALoadKey_t *)
+ DSO_bind_func(hwcrhk_dso, n_hwcrhk_RSALoadKey)) ||
+ !(p6 = (HWCryptoHook_RSAGetPublicKey_t *)
+ DSO_bind_func(hwcrhk_dso, n_hwcrhk_RSAGetPublicKey)) ||
+ !(p7 = (HWCryptoHook_RSAUnloadKey_t *)
+ DSO_bind_func(hwcrhk_dso, n_hwcrhk_RSAUnloadKey)) ||
+ !(p8 = (HWCryptoHook_RandomBytes_t *)
+ DSO_bind_func(hwcrhk_dso, n_hwcrhk_RandomBytes)) ||
+ !(p9 = (HWCryptoHook_ModExpCRT_t *)
+ DSO_bind_func(hwcrhk_dso, n_hwcrhk_ModExpCRT)))
+ {
+ ENGINEerr(ENGINE_F_HWCRHK_INIT,ENGINE_R_DSO_FAILURE);
+ goto err;
+ }
+ /* Copy the pointers */
+ p_hwcrhk_Init = p1;
+ p_hwcrhk_Finish = p2;
+ p_hwcrhk_ModExp = p3;
+ p_hwcrhk_RSA = p4;
+ p_hwcrhk_RSALoadKey = p5;
+ p_hwcrhk_RSAGetPublicKey = p6;
+ p_hwcrhk_RSAUnloadKey = p7;
+ p_hwcrhk_RandomBytes = p8;
+ p_hwcrhk_ModExpCRT = p9;
+
+ /* Check if the application decided to support dynamic locks,
+ and if it does, use them. */
+ if (disable_mutex_callbacks == 0 &&
+ CRYPTO_get_dynlock_create_callback() != NULL &&
+ CRYPTO_get_dynlock_lock_callback() != NULL &&
+ CRYPTO_get_dynlock_destroy_callback() != NULL)
+ {
+ hwcrhk_globals.mutex_init = hwcrhk_mutex_init;
+ hwcrhk_globals.mutex_acquire = hwcrhk_mutex_lock;
+ hwcrhk_globals.mutex_release = hwcrhk_mutex_unlock;
+ hwcrhk_globals.mutex_destroy = hwcrhk_mutex_destroy;
+ }
+
+ /* Try and get a context - if not, we may have a DSO but no
+ * accelerator! */
+ if(!get_context(&hwcrhk_context))
+ {
+ ENGINEerr(ENGINE_F_HWCRHK_INIT,ENGINE_R_UNIT_FAILURE);
+ goto err;
+ }
+ /* Everything's fine. */
+ if (hndidx == -1)
+ hndidx = RSA_get_ex_new_index(0,
+ "nFast HWCryptoHook RSA key handle",
+ NULL, NULL, hwcrhk_ex_free);
+ return 1;
+err:
+ if(hwcrhk_dso)
+ DSO_free(hwcrhk_dso);
+ hwcrhk_dso = NULL;
+ p_hwcrhk_Init = NULL;
+ p_hwcrhk_Finish = NULL;
+ p_hwcrhk_ModExp = NULL;
+ p_hwcrhk_RSA = NULL;
+ p_hwcrhk_RSALoadKey = NULL;
+ p_hwcrhk_RSAGetPublicKey = NULL;
+ p_hwcrhk_RSAUnloadKey = NULL;
+ p_hwcrhk_ModExpCRT = NULL;
+ p_hwcrhk_RandomBytes = NULL;
+ return 0;
+ }
+
+static int hwcrhk_finish()
+ {
+ int to_return = 1;
+ if(hwcrhk_dso == NULL)
+ {
+ ENGINEerr(ENGINE_F_HWCRHK_FINISH,ENGINE_R_NOT_LOADED);
+ to_return = 0;
+ goto err;
+ }
+ release_context(hwcrhk_context);
+ if(!DSO_free(hwcrhk_dso))
+ {
+ ENGINEerr(ENGINE_F_HWCRHK_FINISH,ENGINE_R_DSO_FAILURE);
+ to_return = 0;
+ goto err;
+ }
+ err:
+ if (logstream)
+ BIO_free(logstream);
+ hwcrhk_dso = NULL;
+ p_hwcrhk_Init = NULL;
+ p_hwcrhk_Finish = NULL;
+ p_hwcrhk_ModExp = NULL;
+ p_hwcrhk_RSA = NULL;
+ p_hwcrhk_RSALoadKey = NULL;
+ p_hwcrhk_RSAGetPublicKey = NULL;
+ p_hwcrhk_RSAUnloadKey = NULL;
+ p_hwcrhk_ModExpCRT = NULL;
+ p_hwcrhk_RandomBytes = NULL;
+ return to_return;
+ }
+
+static int hwcrhk_ctrl(int cmd, long i, void *p, void (*f)())
+ {
+ int to_return = 1;
+
+ switch(cmd)
+ {
+ case ENGINE_CTRL_SET_LOGSTREAM:
+ {
+ BIO *bio = (BIO *)p;
+
+ CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
+ if (logstream)
+ {
+ BIO_free(logstream);
+ logstream = NULL;
+ }
+ if (CRYPTO_add(&bio->references,1,CRYPTO_LOCK_BIO) > 1)
+ logstream = bio;
+ else
+ ENGINEerr(ENGINE_F_HWCRHK_CTRL,ENGINE_R_BIO_WAS_FREED);
+ }
+ CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
+ break;
+ case ENGINE_CTRL_SET_PASSWORD_CALLBACK:
+ CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
+ password_callback = (pem_password_cb *)f;
+ CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
+ break;
+ /* this enables or disables the "SimpleForkCheck" flag used in the
+ * initialisation structure. */
+ case ENGINE_CTRL_CHIL_SET_FORKCHECK:
+ CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
+ if(i)
+ hwcrhk_globals.flags |=
+ HWCryptoHook_InitFlags_SimpleForkCheck;
+ else
+ hwcrhk_globals.flags &=
+ ~HWCryptoHook_InitFlags_SimpleForkCheck;
+ CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
+ break;
+ /* This will prevent the initialisation function from "installing"
+ * the mutex-handling callbacks, even if they are available from
+ * within the library (or were provided to the library from the
+ * calling application). This is to remove any baggage for
+ * applications not using multithreading. */
+ case ENGINE_CTRL_CHIL_NO_LOCKING:
+ CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
+ disable_mutex_callbacks = 1;
+ CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
+ break;
+
+ /* The command isn't understood by this engine */
+ default:
+ ENGINEerr(ENGINE_F_HWCRHK_CTRL,
+ ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED);
+ to_return = 0;
+ break;
+ }
+
+ return to_return;
+ }
+
+static EVP_PKEY *hwcrhk_load_privkey(const char *key_id,
+ const char *passphrase)
+ {
+ RSA *rtmp = NULL;
+ EVP_PKEY *res = NULL;
+ HWCryptoHook_MPI e, n;
+ HWCryptoHook_RSAKeyHandle *hptr;
+ HWCryptoHook_ErrMsgBuf rmsg;
+
+ if(!hwcrhk_context)
+ {
+ ENGINEerr(ENGINE_F_HWCRHK_LOAD_PRIVKEY,
+ ENGINE_R_NOT_INITIALISED);
+ goto err;
+ }
+ hptr = OPENSSL_malloc(sizeof(HWCryptoHook_RSAKeyHandle));
+ if (!hptr)
+ {
+ ENGINEerr(ENGINE_F_HWCRHK_LOAD_PRIVKEY,
+ ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ if (p_hwcrhk_RSALoadKey(hwcrhk_context, key_id, hptr,
+ &rmsg, NULL))
+ {
+ ENGINEerr(ENGINE_F_HWCRHK_LOAD_PRIVKEY,
+ ENGINE_R_CHIL_ERROR);
+ ERR_add_error_data(1,rmsg.buf);
+ goto err;
+ }
+ if (!*hptr)
+ {
+ ENGINEerr(ENGINE_F_HWCRHK_LOAD_PRIVKEY,
+ ENGINE_R_NO_KEY);
+ goto err;
+ }
+ rtmp = RSA_new_method(&engine_hwcrhk);
+ RSA_set_ex_data(rtmp, hndidx, (char *)hptr);
+ rtmp->e = BN_new();
+ rtmp->n = BN_new();
+ rtmp->flags |= RSA_FLAG_EXT_PKEY;
+ MPI2BN(rtmp->e, e);
+ MPI2BN(rtmp->n, n);
+ if (p_hwcrhk_RSAGetPublicKey(*hptr, &n, &e, &rmsg)
+ != HWCRYPTOHOOK_ERROR_MPISIZE)
+ {
+ ENGINEerr(ENGINE_F_HWCRHK_LOAD_PUBKEY,ENGINE_R_CHIL_ERROR);
+ ERR_add_error_data(1,rmsg.buf);
+ goto err;
+ }
+
+ bn_expand2(rtmp->e, e.size/sizeof(BN_ULONG));
+ bn_expand2(rtmp->n, n.size/sizeof(BN_ULONG));
+ MPI2BN(rtmp->e, e);
+ MPI2BN(rtmp->n, n);
+
+ if (p_hwcrhk_RSAGetPublicKey(*hptr, &n, &e, &rmsg))
+ {
+ ENGINEerr(ENGINE_F_HWCRHK_LOAD_PUBKEY,
+ ENGINE_R_CHIL_ERROR);
+ ERR_add_error_data(1,rmsg.buf);
+ goto err;
+ }
+ rtmp->e->top = e.size / sizeof(BN_ULONG);
+ bn_fix_top(rtmp->e);
+ rtmp->n->top = n.size / sizeof(BN_ULONG);
+ bn_fix_top(rtmp->n);
+
+ res = EVP_PKEY_new();
+ EVP_PKEY_assign_RSA(res, rtmp);
+
+ return res;
+ err:
+ if (res)
+ EVP_PKEY_free(res);
+ if (rtmp)
+ RSA_free(rtmp);
+ return NULL;
+ }
+
+static EVP_PKEY *hwcrhk_load_pubkey(const char *key_id, const char *passphrase)
+ {
+ EVP_PKEY *res = hwcrhk_load_privkey(key_id, passphrase);
+
+ if (res)
+ switch(res->type)
+ {
+ case EVP_PKEY_RSA:
+ {
+ RSA *rsa = NULL;
+
+ CRYPTO_w_lock(CRYPTO_LOCK_EVP_PKEY);
+ rsa = res->pkey.rsa;
+ res->pkey.rsa = RSA_new();
+ res->pkey.rsa->n = rsa->n;
+ res->pkey.rsa->e = rsa->e;
+ CRYPTO_w_unlock(CRYPTO_LOCK_EVP_PKEY);
+ RSA_free(rsa);
+ }
+ default:
+ ENGINEerr(ENGINE_F_HWCRHK_LOAD_PUBKEY,
+ ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED);
+ goto err;
+ }
+
+ return res;
+ err:
+ if (res)
+ EVP_PKEY_free(res);
+ return NULL;
+ }
+
+/* A little mod_exp */
+static int hwcrhk_mod_exp(BIGNUM *r, BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *m, BN_CTX *ctx)
+ {
+ char tempbuf[1024];
+ HWCryptoHook_ErrMsgBuf rmsg;
+ /* Since HWCryptoHook_MPI is pretty compatible with BIGNUM's,
+ we use them directly, plus a little macro magic. We only
+ thing we need to make sure of is that enough space is allocated. */
+ HWCryptoHook_MPI m_a, m_p, m_n, m_r;
+ int to_return, ret;
+
+ to_return = 0; /* expect failure */
+ rmsg.buf = tempbuf;
+ rmsg.size = 1024;
+
+ if(!hwcrhk_context)
+ {
+ ENGINEerr(ENGINE_F_HWCRHK_MOD_EXP,ENGINE_R_NOT_INITIALISED);
+ goto err;
+ }
+ /* Prepare the params */
+ bn_expand2(r, m->top); /* Check for error !! */
+ BN2MPI(m_a, a);
+ BN2MPI(m_p, p);
+ BN2MPI(m_n, m);
+ MPI2BN(r, m_r);
+
+ /* Perform the operation */
+ ret = p_hwcrhk_ModExp(hwcrhk_context, m_a, m_p, m_n, &m_r, &rmsg);
+
+ /* Convert the response */
+ r->top = m_r.size / sizeof(BN_ULONG);
+ bn_fix_top(r);
+
+ if (ret < 0)
+ {
+ /* FIXME: When this error is returned, HWCryptoHook is
+ telling us that falling back to software computation
+ might be a good thing. */
+ if(ret == HWCRYPTOHOOK_ERROR_FALLBACK)
+ {
+ ENGINEerr(ENGINE_F_HWCRHK_MOD_EXP,ENGINE_R_REQUEST_FALLBACK);
+ }
+ else
+ {
+ ENGINEerr(ENGINE_F_HWCRHK_MOD_EXP,ENGINE_R_REQUEST_FAILED);
+ }
+ ERR_add_error_data(1,rmsg.buf);
+ goto err;
+ }
+
+ to_return = 1;
+err:
+ return to_return;
+ }
+
+static int hwcrhk_rsa_mod_exp(BIGNUM *r, BIGNUM *I, RSA *rsa)
+ {
+ char tempbuf[1024];
+ HWCryptoHook_ErrMsgBuf rmsg;
+ HWCryptoHook_RSAKeyHandle *hptr;
+ int to_return = 0, ret;
+
+ if(!hwcrhk_context)
+ {
+ ENGINEerr(ENGINE_F_HWCRHK_MOD_EXP,ENGINE_R_NOT_INITIALISED);
+ goto err;
+ }
+
+ /* This provides support for nForce keys. Since that's opaque data
+ all we do is provide a handle to the proper key and let HWCryptoHook
+ take care of the rest. */
+ if ((hptr = (HWCryptoHook_RSAKeyHandle *) RSA_get_ex_data(rsa, hndidx))
+ != NULL)
+ {
+ HWCryptoHook_MPI m_a, m_r;
+
+ if(!rsa->n)
+ {
+ ENGINEerr(ENGINE_F_HWCRHK_RSA_MOD_EXP,
+ ENGINE_R_MISSING_KEY_COMPONENTS);
+ goto err;
+ }
+
+ rmsg.buf = tempbuf;
+ rmsg.size = 1024;
+
+ /* Prepare the params */
+ bn_expand2(r, rsa->n->top); /* Check for error !! */
+ BN2MPI(m_a, I);
+ MPI2BN(r, m_r);
+
+ /* Perform the operation */
+ ret = p_hwcrhk_RSA(m_a, *hptr, &m_r, &rmsg);
+
+ /* Convert the response */
+ r->top = m_r.size / sizeof(BN_ULONG);
+ bn_fix_top(r);
+
+ if (ret < 0)
+ {
+ /* FIXME: When this error is returned, HWCryptoHook is
+ telling us that falling back to software computation
+ might be a good thing. */
+ if(ret == HWCRYPTOHOOK_ERROR_FALLBACK)
+ {
+ ENGINEerr(ENGINE_F_HWCRHK_RSA_MOD_EXP,ENGINE_R_REQUEST_FALLBACK);
+ }
+ else
+ {
+ ENGINEerr(ENGINE_F_HWCRHK_RSA_MOD_EXP,ENGINE_R_REQUEST_FAILED);
+ }
+ ERR_add_error_data(1,rmsg.buf);
+ goto err;
+ }
+ }
+ else
+ {
+ HWCryptoHook_MPI m_a, m_p, m_q, m_dmp1, m_dmq1, m_iqmp, m_r;
+
+ if(!rsa->p || !rsa->q || !rsa->dmp1 || !rsa->dmq1 || !rsa->iqmp)
+ {
+ ENGINEerr(ENGINE_F_HWCRHK_RSA_MOD_EXP,
+ ENGINE_R_MISSING_KEY_COMPONENTS);
+ goto err;
+ }
+
+ rmsg.buf = tempbuf;
+ rmsg.size = 1024;
+
+ /* Prepare the params */
+ bn_expand2(r, rsa->n->top); /* Check for error !! */
+ BN2MPI(m_a, I);
+ BN2MPI(m_p, rsa->p);
+ BN2MPI(m_q, rsa->q);
+ BN2MPI(m_dmp1, rsa->dmp1);
+ BN2MPI(m_dmq1, rsa->dmq1);
+ BN2MPI(m_iqmp, rsa->iqmp);
+ MPI2BN(r, m_r);
+
+ /* Perform the operation */
+ ret = p_hwcrhk_ModExpCRT(hwcrhk_context, m_a, m_p, m_q,
+ m_dmp1, m_dmq1, m_iqmp, &m_r, NULL);
+
+ /* Convert the response */
+ r->top = m_r.size / sizeof(BN_ULONG);
+ bn_fix_top(r);
+
+ if (ret < 0)
+ {
+ /* FIXME: When this error is returned, HWCryptoHook is
+ telling us that falling back to software computation
+ might be a good thing. */
+ if(ret == HWCRYPTOHOOK_ERROR_FALLBACK)
+ {
+ ENGINEerr(ENGINE_F_HWCRHK_RSA_MOD_EXP,ENGINE_R_REQUEST_FALLBACK);
+ }
+ else
+ {
+ ENGINEerr(ENGINE_F_HWCRHK_RSA_MOD_EXP,ENGINE_R_REQUEST_FAILED);
+ }
+ ERR_add_error_data(1,rmsg.buf);
+ goto err;
+ }
+ }
+ /* If we're here, we must be here with some semblance of success :-) */
+ to_return = 1;
+err:
+ return to_return;
+ }
+
+/* This function is aliased to mod_exp (with the mont stuff dropped). */
+static int hwcrhk_mod_exp_mont(BIGNUM *r, BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
+ {
+ return hwcrhk_mod_exp(r, a, p, m, ctx);
+ }
+
+/* This function is aliased to mod_exp (with the dh and mont dropped). */
+static int hwcrhk_mod_exp_dh(DH *dh, BIGNUM *r, BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
+ {
+ return hwcrhk_mod_exp(r, a, p, m, ctx);
+ }
+
+/* Random bytes are good */
+static int hwcrhk_rand_bytes(unsigned char *buf, int num)
+ {
+ char tempbuf[1024];
+ HWCryptoHook_ErrMsgBuf rmsg;
+ int to_return = 0; /* assume failure */
+ int ret;
+
+ rmsg.buf = tempbuf;
+ rmsg.size = 1024;
+
+ if(!hwcrhk_context)
+ {
+ ENGINEerr(ENGINE_F_HWCRHK_RAND_BYTES,ENGINE_R_NOT_INITIALISED);
+ goto err;
+ }
+
+ ret = p_hwcrhk_RandomBytes(hwcrhk_context, buf, num, &rmsg);
+ if (ret < 0)
+ {
+ /* FIXME: When this error is returned, HWCryptoHook is
+ telling us that falling back to software computation
+ might be a good thing. */
+ if(ret == HWCRYPTOHOOK_ERROR_FALLBACK)
+ {
+ ENGINEerr(ENGINE_F_HWCRHK_RAND_BYTES,ENGINE_R_REQUEST_FALLBACK);
+ }
+ else
+ {
+ ENGINEerr(ENGINE_F_HWCRHK_RAND_BYTES,ENGINE_R_REQUEST_FAILED);
+ }
+ ERR_add_error_data(1,rmsg.buf);
+ goto err;
+ }
+ to_return = 1;
+ err:
+ return to_return;
+ }
+
+static int hwcrhk_rand_status(void)
+ {
+ return 1;
+ }
+
+/* This cleans up an RSA KM key, called when ex_data is freed */
+
+static void hwcrhk_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad,
+ int ind,long argl, void *argp)
+{
+ char tempbuf[1024];
+ HWCryptoHook_ErrMsgBuf rmsg;
+ HWCryptoHook_RSAKeyHandle *hptr;
+ int ret;
+
+ rmsg.buf = tempbuf;
+ rmsg.size = 1024;
+
+ hptr = (HWCryptoHook_RSAKeyHandle *) item;
+ if(!hptr) return;
+ ret = p_hwcrhk_RSAUnloadKey(*hptr, NULL);
+ OPENSSL_free(hptr);
+}
+
+/* Mutex calls: since the HWCryptoHook model closely follows the POSIX model
+ * these just wrap the POSIX functions and add some logging.
+ */
+
+static int hwcrhk_mutex_init(HWCryptoHook_Mutex* mt,
+ HWCryptoHook_CallerContext *cactx)
+ {
+ mt->lockid = CRYPTO_get_new_dynlockid();
+ if (mt->lockid == 0)
+ return 0;
+ return 1;
+ }
+
+static int hwcrhk_mutex_lock(HWCryptoHook_Mutex *mt)
+ {
+ CRYPTO_w_lock(mt->lockid);
+ return 1;
+ }
+
+void hwcrhk_mutex_unlock(HWCryptoHook_Mutex * mt)
+ {
+ CRYPTO_w_unlock(mt->lockid);
+ }
+
+static void hwcrhk_mutex_destroy(HWCryptoHook_Mutex *mt)
+ {
+ CRYPTO_destroy_dynlockid(mt->lockid);
+ }
+
+static int hwcrhk_get_pass(const char *prompt_info,
+ int *len_io, char *buf,
+ HWCryptoHook_PassphraseContext *ppctx,
+ HWCryptoHook_CallerContext *cactx)
+ {
+ int l = 0;
+ char prompt[1024];
+
+ if (password_callback == NULL)
+ {
+ ENGINEerr(ENGINE_F_HWCRHK_GET_PASS,ENGINE_R_NO_CALLBACK);
+ return -1;
+ }
+ if (prompt_info)
+ {
+ strncpy(prompt, "Card: \"", sizeof(prompt));
+ l += 5;
+ strncpy(prompt + l, prompt_info, sizeof(prompt) - l);
+ l += strlen(prompt_info);
+ if (l + 2 < sizeof(prompt))
+ {
+ strncpy(prompt + l, "\"\n", sizeof(prompt) - l);
+ l += 2;
+ }
+ }
+ if (l < sizeof(prompt) - 1)
+ {
+ strncpy(prompt, "Enter Passphrase <enter to cancel>:",
+ sizeof(prompt) - l);
+ l += 35;
+ }
+ prompt[l] = '\0';
+
+ /* I know, passing on the prompt instead of the user data *is*
+ a bad thing. However, that's all we have right now.
+ -- Richard Levitte */
+ *len_io = password_callback(buf, *len_io, 0, prompt);
+ if(!*len_io)
+ return -1;
+ return 0;
+ }
+
+static void hwcrhk_log_message(void *logstr, const char *message)
+ {
+ BIO *lstream = NULL;
+
+ CRYPTO_w_lock(CRYPTO_LOCK_BIO);
+ if (logstr)
+ lstream=*(BIO **)logstr;
+ if (lstream)
+ {
+ BIO_write(lstream, message, strlen(message));
+ }
+ CRYPTO_w_unlock(CRYPTO_LOCK_BIO);
+ }
+
+#endif /* !NO_HW_NCIPHER */
+#endif /* !NO_HW */
diff --git a/crypto/engine/hw_nuron.c b/crypto/engine/hw_nuron.c
new file mode 100644
index 0000000000..d8a3e3f1fa
--- /dev/null
+++ b/crypto/engine/hw_nuron.c
@@ -0,0 +1,286 @@
+/* crypto/engine/hw_nuron.c */
+/* Written by Ben Laurie for the OpenSSL Project, leaning heavily on Geoff
+ * Thorpe's Atalla implementation.
+ */
+/* ====================================================================
+ * Copyright (c) 2000 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 <openssl/crypto.h>
+#include "cryptlib.h"
+#include <openssl/dso.h>
+#include "engine_int.h"
+#include <openssl/engine.h>
+#include <dlfcn.h>
+
+
+#ifndef NO_HW
+#ifndef NO_HW_NURON
+
+typedef int tfnModExp(BIGNUM *r,BIGNUM *a,const BIGNUM *p,const BIGNUM *m);
+static tfnModExp *pfnModExp = NULL;
+
+static DSO *pvDSOHandle = NULL;
+
+static int nuron_init()
+ {
+ if(pvDSOHandle != NULL)
+ {
+ ENGINEerr(ENGINE_F_NURON_INIT,ENGINE_R_ALREADY_LOADED);
+ return 0;
+ }
+
+ pvDSOHandle=DSO_load(NULL,"nuronssl",NULL,
+ DSO_FLAG_NAME_TRANSLATION_EXT_ONLY);
+ if(!pvDSOHandle)
+ {
+ ENGINEerr(ENGINE_F_NURON_INIT,ENGINE_R_DSO_NOT_FOUND);
+ return 0;
+ }
+
+ pfnModExp=(tfnModExp *)DSO_bind_func(pvDSOHandle,"nuron_mod_exp");
+ if(!pfnModExp)
+ {
+ ENGINEerr(ENGINE_F_NURON_INIT,ENGINE_R_DSO_FUNCTION_NOT_FOUND);
+ return 0;
+ }
+
+ return 1;
+ }
+
+static int nuron_finish()
+ {
+ if(pvDSOHandle == NULL)
+ {
+ ENGINEerr(ENGINE_F_NURON_FINISH,ENGINE_R_NOT_LOADED);
+ return 0;
+ }
+ if(!DSO_free(pvDSOHandle))
+ {
+ ENGINEerr(ENGINE_F_NURON_FINISH,ENGINE_R_DSO_FAILURE);
+ return 0;
+ }
+ pvDSOHandle=NULL;
+ pfnModExp=NULL;
+ return 1;
+ }
+
+static int nuron_mod_exp(BIGNUM *r,BIGNUM *a,const BIGNUM *p,
+ const BIGNUM *m,BN_CTX *ctx)
+ {
+ if(!pvDSOHandle)
+ {
+ ENGINEerr(ENGINE_F_NURON_MOD_EXP,ENGINE_R_NOT_LOADED);
+ return 0;
+ }
+ return pfnModExp(r,a,p,m);
+ }
+
+static int nuron_rsa_mod_exp(BIGNUM *r0, BIGNUM *I, RSA *rsa)
+ {
+ return nuron_mod_exp(r0,I,rsa->d,rsa->n,NULL);
+ }
+
+/* This code was liberated and adapted from the commented-out code in
+ * dsa_ossl.c. Because of the unoptimised form of the Atalla acceleration
+ * (it doesn't have a CRT form for RSA), this function means that an
+ * Atalla system running with a DSA server certificate can handshake
+ * around 5 or 6 times faster/more than an equivalent system running with
+ * RSA. Just check out the "signs" statistics from the RSA and DSA parts
+ * of "openssl speed -engine atalla dsa1024 rsa1024". */
+static int nuron_dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1,
+ BIGNUM *p1, BIGNUM *a2, BIGNUM *p2, BIGNUM *m,
+ BN_CTX *ctx, BN_MONT_CTX *in_mont)
+ {
+ BIGNUM t;
+ int to_return = 0;
+
+ BN_init(&t);
+ /* let rr = a1 ^ p1 mod m */
+ if (!nuron_mod_exp(rr,a1,p1,m,ctx))
+ goto end;
+ /* let t = a2 ^ p2 mod m */
+ if (!nuron_mod_exp(&t,a2,p2,m,ctx))
+ goto end;
+ /* let rr = rr * t mod m */
+ if (!BN_mod_mul(rr,rr,&t,m,ctx))
+ goto end;
+ to_return = 1;
+end:
+ BN_free(&t);
+ return to_return;
+ }
+
+
+static int nuron_mod_exp_dsa(DSA *dsa, BIGNUM *r, BIGNUM *a,
+ const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
+ BN_MONT_CTX *m_ctx)
+ {
+ return nuron_mod_exp(r, a, p, m, ctx);
+ }
+
+/* This function is aliased to mod_exp (with the mont stuff dropped). */
+static int nuron_mod_exp_mont(BIGNUM *r, BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
+ {
+ return nuron_mod_exp(r, a, p, m, ctx);
+ }
+
+/* This function is aliased to mod_exp (with the dh and mont dropped). */
+static int nuron_mod_exp_dh(DH *dh, BIGNUM *r, BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
+ {
+ return nuron_mod_exp(r, a, p, m, ctx);
+ }
+
+static RSA_METHOD nuron_rsa =
+ {
+ "Nuron RSA method",
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ nuron_rsa_mod_exp,
+ nuron_mod_exp_mont,
+ NULL,
+ NULL,
+ 0,
+ NULL,
+ NULL,
+ NULL
+ };
+
+static DSA_METHOD nuron_dsa =
+ {
+ "Nuron DSA method",
+ NULL, /* dsa_do_sign */
+ NULL, /* dsa_sign_setup */
+ NULL, /* dsa_do_verify */
+ nuron_dsa_mod_exp, /* dsa_mod_exp */
+ nuron_mod_exp_dsa, /* bn_mod_exp */
+ NULL, /* init */
+ NULL, /* finish */
+ 0, /* flags */
+ NULL /* app_data */
+ };
+
+static DH_METHOD nuron_dh =
+ {
+ "Nuron DH method",
+ NULL,
+ NULL,
+ nuron_mod_exp_dh,
+ NULL,
+ NULL,
+ 0,
+ NULL
+ };
+
+static ENGINE engine_nuron =
+ {
+ "nuron",
+ "Nuron hardware engine support",
+ &nuron_rsa,
+ &nuron_dsa,
+ &nuron_dh,
+ NULL,
+ nuron_mod_exp,
+ NULL,
+ nuron_init,
+ nuron_finish,
+ NULL, /* no ctrl() */
+ NULL, /* no load_privkey() */
+ NULL, /* no load_pubkey() */
+ 0, /* no flags */
+ 0, 0, /* no references */
+ NULL, NULL /* unlinked */
+ };
+
+/* As this is only ever called once, there's no need for locking
+ * (indeed - the lock will already be held by our caller!!!) */
+ENGINE *ENGINE_nuron()
+ {
+ RSA_METHOD *meth1;
+ DSA_METHOD *meth2;
+ DH_METHOD *meth3;
+
+ /* We know that the "PKCS1_SSLeay()" functions hook properly
+ * to the nuron-specific mod_exp and mod_exp_crt so we use
+ * those functions. NB: We don't use ENGINE_openssl() or
+ * anything "more generic" because something like the RSAref
+ * code may not hook properly, and if you own one of these
+ * cards then you have the right to do RSA operations on it
+ * anyway! */
+ meth1=RSA_PKCS1_SSLeay();
+ nuron_rsa.rsa_pub_enc=meth1->rsa_pub_enc;
+ nuron_rsa.rsa_pub_dec=meth1->rsa_pub_dec;
+ nuron_rsa.rsa_priv_enc=meth1->rsa_priv_enc;
+ nuron_rsa.rsa_priv_dec=meth1->rsa_priv_dec;
+
+ /* Use the DSA_OpenSSL() method and just hook the mod_exp-ish
+ * bits. */
+ meth2=DSA_OpenSSL();
+ nuron_dsa.dsa_do_sign=meth2->dsa_do_sign;
+ nuron_dsa.dsa_sign_setup=meth2->dsa_sign_setup;
+ nuron_dsa.dsa_do_verify=meth2->dsa_do_verify;
+
+ /* Much the same for Diffie-Hellman */
+ meth3=DH_OpenSSL();
+ nuron_dh.generate_key=meth3->generate_key;
+ nuron_dh.compute_key=meth3->compute_key;
+ return &engine_nuron;
+ }
+
+#endif /* !NO_HW_NURON */
+#endif /* !NO_HW */
diff --git a/crypto/engine/vendor_defns/atalla.h b/crypto/engine/vendor_defns/atalla.h
new file mode 100644
index 0000000000..8111649c54
--- /dev/null
+++ b/crypto/engine/vendor_defns/atalla.h
@@ -0,0 +1,61 @@
+/* This header declares the necessary definitions for using the exponentiation
+ * acceleration capabilities of Atalla cards. The only cryptographic operation
+ * is performed by "ASI_RSAPrivateKeyOpFn" and this takes a structure that
+ * defines an "RSA private key". However, it is really only performing a
+ * regular mod_exp using the supplied modulus and exponent - no CRT form is
+ * being used. Hence, it is a generic mod_exp function in disguise, and we use
+ * it as such.
+ *
+ * Thanks to the people at Atalla for letting me know these definitions are
+ * fine and that they can be reproduced here.
+ *
+ * Geoff.
+ */
+
+typedef struct ItemStr
+ {
+ unsigned char *data;
+ int len;
+ } Item;
+
+typedef struct RSAPrivateKeyStr
+ {
+ void *reserved;
+ Item version;
+ Item modulus;
+ Item publicExponent;
+ Item privateExponent;
+ Item prime[2];
+ Item exponent[2];
+ Item coefficient;
+ } RSAPrivateKey;
+
+/* Predeclare the function pointer types that we dynamically load from the DSO.
+ * These use the same names and form that Ben's original support code had (in
+ * crypto/bn/bn_exp.c) unless of course I've inadvertently changed the style
+ * somewhere along the way!
+ */
+
+typedef int tfnASI_GetPerformanceStatistics(int reset_flag,
+ unsigned int *ret_buf);
+
+typedef int tfnASI_GetHardwareConfig(long card_num, unsigned int *ret_buf);
+
+typedef int tfnASI_RSAPrivateKeyOpFn(RSAPrivateKey * rsaKey,
+ unsigned char *output,
+ unsigned char *input,
+ unsigned int modulus_len);
+
+/* These are the static string constants for the DSO file name and the function
+ * symbol names to bind to. Regrettably, the DSO name on *nix appears to be
+ * "atasi.so" rather than something more consistent like "libatasi.so". At the
+ * time of writing, I'm not sure what the file name on win32 is but clearly
+ * native name translation is not possible (eg libatasi.so on *nix, and
+ * atasi.dll on win32). For the purposes of testing, I have created a symbollic
+ * link called "libatasi.so" so that we can use native name-translation - a
+ * better solution will be needed. */
+static const char *ATALLA_LIBNAME = "atasi";
+static const char *ATALLA_F1 = "ASI_GetHardwareConfig";
+static const char *ATALLA_F2 = "ASI_RSAPrivateKeyOpFn";
+static const char *ATALLA_F3 = "ASI_GetPerformanceStatistics";
+
diff --git a/crypto/engine/vendor_defns/cswift.h b/crypto/engine/vendor_defns/cswift.h
new file mode 100644
index 0000000000..0af14a1a92
--- /dev/null
+++ b/crypto/engine/vendor_defns/cswift.h
@@ -0,0 +1,213 @@
+/* Attribution notice: Rainbow have generously allowed me to reproduce
+ * the necessary definitions here from their API. This means the support
+ * can build independently of whether application builders have the
+ * API or hardware. This will allow developers to easily produce software
+ * that has latent hardware support for any users that have accelertors
+ * installed, without the developers themselves needing anything extra.
+ *
+ * I have only clipped the parts from the CryptoSwift header files that
+ * are (or seem) relevant to the CryptoSwift support code. This is
+ * simply to keep the file sizes reasonable.
+ * [Geoff]
+ */
+
+
+/* NB: These type widths do *not* seem right in general, in particular
+ * they're not terribly friendly to 64-bit architectures (unsigned long)
+ * will be 64-bit on IA-64 for a start. I'm leaving these alone as they
+ * agree with Rainbow's API and this will only be called into question
+ * on platforms with Rainbow support anyway! ;-) */
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+typedef long SW_STATUS; /* status */
+typedef unsigned char SW_BYTE; /* 8 bit byte */
+typedef unsigned short SW_U16; /* 16 bit number */
+#if defined(_IRIX)
+#include <sgidefs.h>
+typedef __uint32_t SW_U32;
+#else
+typedef unsigned long SW_U32; /* 32 bit integer */
+#endif
+
+#if defined(WIN32)
+ typedef struct _SW_U64 {
+ SW_U32 low32;
+ SW_U32 high32;
+ } SW_U64; /* 64 bit integer */
+#elif defined(MAC)
+ typedef longlong SW_U64
+#else /* Unix variants */
+ typedef struct _SW_U64 {
+ SW_U32 low32;
+ SW_U32 high32;
+ } SW_U64; /* 64 bit integer */
+#endif
+
+/* status codes */
+#define SW_OK (0L)
+#define SW_ERR_BASE (-10000L)
+#define SW_ERR_NO_CARD (SW_ERR_BASE-1) /* The Card is not present */
+#define SW_ERR_CARD_NOT_READY (SW_ERR_BASE-2) /* The card has not powered */
+ /* up yet */
+#define SW_ERR_TIME_OUT (SW_ERR_BASE-3) /* Execution of a command */
+ /* time out */
+#define SW_ERR_NO_EXECUTE (SW_ERR_BASE-4) /* The Card failed to */
+ /* execute the command */
+#define SW_ERR_INPUT_NULL_PTR (SW_ERR_BASE-5) /* a required pointer is */
+ /* NULL */
+#define SW_ERR_INPUT_SIZE (SW_ERR_BASE-6) /* size is invalid, too */
+ /* small, too large. */
+#define SW_ERR_INVALID_HANDLE (SW_ERR_BASE-7) /* Invalid SW_ACC_CONTEXT */
+ /* handle */
+#define SW_ERR_PENDING (SW_ERR_BASE-8) /* A request is already out- */
+ /* standing at this */
+ /* context handle */
+#define SW_ERR_AVAILABLE (SW_ERR_BASE-9) /* A result is available. */
+#define SW_ERR_NO_PENDING (SW_ERR_BASE-10)/* No request is pending. */
+#define SW_ERR_NO_MEMORY (SW_ERR_BASE-11)/* Not enough memory */
+#define SW_ERR_BAD_ALGORITHM (SW_ERR_BASE-12)/* Invalid algorithm type */
+ /* in SW_PARAM structure */
+#define SW_ERR_MISSING_KEY (SW_ERR_BASE-13)/* No key is associated with */
+ /* context. */
+ /* swAttachKeyParam() is */
+ /* not called. */
+#define SW_ERR_KEY_CMD_MISMATCH \
+ (SW_ERR_BASE-14)/* Cannot perform requested */
+ /* SW_COMMAND_CODE since */
+ /* key attached via */
+ /* swAttachKeyParam() */
+ /* cannot be used for this*/
+ /* SW_COMMAND_CODE. */
+#define SW_ERR_NOT_IMPLEMENTED \
+ (SW_ERR_BASE-15)/* Not implemented */
+#define SW_ERR_BAD_COMMAND (SW_ERR_BASE-16)/* Bad command code */
+#define SW_ERR_BAD_ITEM_SIZE (SW_ERR_BASE-17)/* too small or too large in */
+ /* the "initems" or */
+ /* "outitems". */
+#define SW_ERR_BAD_ACCNUM (SW_ERR_BASE-18)/* Bad accelerator number */
+#define SW_ERR_SELFTEST_FAIL (SW_ERR_BASE-19)/* At least one of the self */
+ /* test fail, look at the */
+ /* selfTestBitmap in */
+ /* SW_ACCELERATOR_INFO for*/
+ /* details. */
+#define SW_ERR_MISALIGN (SW_ERR_BASE-20)/* Certain alogrithms require*/
+ /* key materials aligned */
+ /* in certain order, e.g. */
+ /* 128 bit for CRT */
+#define SW_ERR_OUTPUT_NULL_PTR \
+ (SW_ERR_BASE-21)/* a required pointer is */
+ /* NULL */
+#define SW_ERR_OUTPUT_SIZE \
+ (SW_ERR_BASE-22)/* size is invalid, too */
+ /* small, too large. */
+#define SW_ERR_FIRMWARE_CHECKSUM \
+ (SW_ERR_BASE-23)/* firmware checksum mismatch*/
+ /* download failed. */
+#define SW_ERR_UNKNOWN_FIRMWARE \
+ (SW_ERR_BASE-24)/* unknown firmware error */
+#define SW_ERR_INTERRUPT (SW_ERR_BASE-25)/* request is abort when */
+ /* it's waiting to be */
+ /* completed. */
+#define SW_ERR_NVWRITE_FAIL (SW_ERR_BASE-26)/* error in writing to Non- */
+ /* volatile memory */
+#define SW_ERR_NVWRITE_RANGE (SW_ERR_BASE-27)/* out of range error in */
+ /* writing to NV memory */
+#define SW_ERR_RNG_ERROR (SW_ERR_BASE-28)/* Random Number Generation */
+ /* failure */
+#define SW_ERR_DSS_FAILURE (SW_ERR_BASE-29)/* DSS Sign or Verify failure*/
+#define SW_ERR_MODEXP_FAILURE (SW_ERR_BASE-30)/* Failure in various math */
+ /* calculations */
+#define SW_ERR_ONBOARD_MEMORY (SW_ERR_BASE-31)/* Error in accessing on - */
+ /* board memory */
+#define SW_ERR_FIRMWARE_VERSION \
+ (SW_ERR_BASE-32)/* Wrong version in firmware */
+ /* update */
+#define SW_ERR_ZERO_WORKING_ACCELERATOR \
+ (SW_ERR_BASE-44)/* All accelerators are bad */
+
+
+ /* algorithm type */
+#define SW_ALG_CRT 1
+#define SW_ALG_EXP 2
+#define SW_ALG_DSA 3
+#define SW_ALG_NVDATA 4
+
+ /* command code */
+#define SW_CMD_MODEXP_CRT 1 /* perform Modular Exponentiation using */
+ /* Chinese Remainder Theorem (CRT) */
+#define SW_CMD_MODEXP 2 /* perform Modular Exponentiation */
+#define SW_CMD_DSS_SIGN 3 /* perform DSS sign */
+#define SW_CMD_DSS_VERIFY 4 /* perform DSS verify */
+#define SW_CMD_RAND 5 /* perform random number generation */
+#define SW_CMD_NVREAD 6 /* perform read to nonvolatile RAM */
+#define SW_CMD_NVWRITE 7 /* perform write to nonvolatile RAM */
+
+typedef SW_U32 SW_ALGTYPE; /* alogrithm type */
+typedef SW_U32 SW_STATE; /* state */
+typedef SW_U32 SW_COMMAND_CODE; /* command code */
+typedef SW_U32 SW_COMMAND_BITMAP[4]; /* bitmap */
+
+typedef struct _SW_LARGENUMBER {
+ SW_U32 nbytes; /* number of bytes in the buffer "value" */
+ SW_BYTE* value; /* the large integer as a string of */
+ /* bytes in network (big endian) order */
+} SW_LARGENUMBER;
+
+typedef struct _SW_CRT {
+ SW_LARGENUMBER p; /* prime number p */
+ SW_LARGENUMBER q; /* prime number q */
+ SW_LARGENUMBER dmp1; /* exponent1 */
+ SW_LARGENUMBER dmq1; /* exponent2 */
+ SW_LARGENUMBER iqmp; /* CRT coefficient */
+} SW_CRT;
+
+typedef struct _SW_EXP {
+ SW_LARGENUMBER modulus; /* modulus */
+ SW_LARGENUMBER exponent;/* exponent */
+} SW_EXP;
+
+typedef struct _SW_DSA {
+ SW_LARGENUMBER p; /* */
+ SW_LARGENUMBER q; /* */
+ SW_LARGENUMBER g; /* */
+ SW_LARGENUMBER key; /* private/public key */
+} SW_DSA;
+
+typedef struct _SW_NVDATA {
+ SW_U32 accnum; /* accelerator board number */
+ SW_U32 offset; /* offset in byte */
+} SW_NVDATA;
+
+typedef struct _SW_PARAM {
+ SW_ALGTYPE type; /* type of the alogrithm */
+ union {
+ SW_CRT crt;
+ SW_EXP exp;
+ SW_DSA dsa;
+ SW_NVDATA nvdata;
+ } up;
+} SW_PARAM;
+
+typedef SW_U32 SW_CONTEXT_HANDLE; /* opaque context handle */
+
+
+/* Now the OpenSSL bits, these function types are the for the function
+ * pointers that will bound into the Rainbow shared libraries. */
+typedef SW_STATUS t_swAcquireAccContext(SW_CONTEXT_HANDLE *hac);
+typedef SW_STATUS t_swAttachKeyParam(SW_CONTEXT_HANDLE hac,
+ SW_PARAM *key_params);
+typedef SW_STATUS t_swSimpleRequest(SW_CONTEXT_HANDLE hac,
+ SW_COMMAND_CODE cmd,
+ SW_LARGENUMBER pin[],
+ SW_U32 pin_count,
+ SW_LARGENUMBER pout[],
+ SW_U32 pout_count);
+typedef SW_STATUS t_swReleaseAccContext(SW_CONTEXT_HANDLE hac);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
diff --git a/crypto/engine/vendor_defns/hwcryptohook.h b/crypto/engine/vendor_defns/hwcryptohook.h
new file mode 100644
index 0000000000..ed880515bc
--- /dev/null
+++ b/crypto/engine/vendor_defns/hwcryptohook.h
@@ -0,0 +1,476 @@
+/*
+ * ModExp / RSA (with/without KM) plugin API
+ *
+ * The application will load a dynamic library which
+ * exports entrypoint(s) defined in this file.
+ *
+ * This set of entrypoints provides only a multithreaded,
+ * synchronous-within-each-thread, facility.
+ *
+ *
+ * This file is Copyright 1998-1999 nCipher Corporation Limited.
+ *
+ * This file is provided for your information and assistance. You are
+ * permitted to copy it verbatim, to use it to create compatible
+ * software, and for review and comment. However, you may not
+ * distribute changed versions or other derivative works. All other
+ * rights are reserved.
+ *
+ * IN NO EVENT SHALL NCIPHER CORPORATION LIMITED (`NCIPHER') AND/OR
+ * ANY OTHER AUTHORS OR DISTRIBUTORS OF THIS FILE BE LIABLE for any
+ * damages arising directly or indirectly from this file, its use or
+ * this licence. Without prejudice to the generality of the
+ * foregoing: all liability shall be excluded for direct, indirect,
+ * special, incidental, consequential or other damages or any loss of
+ * profits, business, revenue goodwill or anticipated savings;
+ * liability shall be excluded even if nCipher or anyone else has been
+ * advised of the possibility of damage. In any event, if the
+ * exclusion of liability is not effective, the liability of nCipher
+ * or any author or distributor shall be limited to the lesser of the
+ * price paid and 1,000 pounds sterling. This licence only fails to
+ * exclude or limit liability for death or personal injury arising out
+ * of negligence, and only to the extent that such an exclusion or
+ * limitation is not effective.
+ *
+ * NCIPHER AND THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ALL
+ * AND ANY WARRANTIES (WHETHER EXPRESS OR IMPLIED), including, but not
+ * limited to, any implied warranties of merchantability, fitness for
+ * a particular purpose, satisfactory quality, and/or non-infringement
+ * of any third party rights.
+ *
+ * US Government use: This software and documentation is Commercial
+ * Computer Software and Computer Software Documentation, as defined in
+ * sub-paragraphs (a)(1) and (a)(5) of DFAR 252.227-7014, "Rights in
+ * Noncommercial Computer Software and Noncommercial Computer Software
+ * Documentation." Use, duplication or disclosure by the Government is
+ * subject to the terms and conditions specified here.
+ *
+ * By using or distributing this file you will be accepting these
+ * terms and conditions, including the limitation of liability and
+ * lack of warranty. If you do not wish to accept these terms and
+ * conditions, DO NOT USE THE FILE.
+ *
+ *
+ * The actual dynamically loadable plugin, and the library files for
+ * static linking, which are also provided in this distribution, are
+ * not covered by the licence described above. You should have
+ * received a separate licence with terms and conditions for these
+ * library files; if you received the library files without a licence,
+ * please contact nCipher.
+ *
+ *
+ * $Id: hwcryptohook.h,v 1.2 2000/10/26 21:06:30 levitte Exp $
+ */
+
+#ifndef HWCRYPTOHOOK_H
+#define HWCRYPTOHOOK_H
+
+#include <sys/types.h>
+#include <stdio.h>
+
+#ifndef HWCRYPTOHOOK_DECLARE_APPTYPES
+#define HWCRYPTOHOOK_DECLARE_APPTYPES 1
+#endif
+
+#define HWCRYPTOHOOK_ERROR_FAILED -1
+#define HWCRYPTOHOOK_ERROR_FALLBACK -2
+#define HWCRYPTOHOOK_ERROR_MPISIZE -3
+
+#if HWCRYPTOHOOK_DECLARE_APPTYPES
+
+/* These structs are defined by the application and opaque to the
+ * crypto plugin. The application may define these as it sees fit.
+ * Default declarations are provided here, but the application may
+ * #define HWCRYPTOHOOK_DECLARE_APPTYPES 0
+ * to prevent these declarations, and instead provide its own
+ * declarations of these types. (Pointers to them must still be
+ * ordinary pointers to structs or unions, or the resulting combined
+ * program will have a type inconsistency.)
+ */
+typedef struct HWCryptoHook_MutexValue HWCryptoHook_Mutex;
+typedef struct HWCryptoHook_CondVarValue HWCryptoHook_CondVar;
+typedef struct HWCryptoHook_PassphraseContextValue HWCryptoHook_PassphraseContext;
+typedef struct HWCryptoHook_CallerContextValue HWCryptoHook_CallerContext;
+
+#endif /* HWCRYPTOHOOK_DECLARE_APPTYPES */
+
+/* These next two structs are opaque to the application. The crypto
+ * plugin will return pointers to them; the caller simply manipulates
+ * the pointers.
+ */
+typedef struct HWCryptoHook_Context *HWCryptoHook_ContextHandle;
+typedef struct HWCryptoHook_RSAKey *HWCryptoHook_RSAKeyHandle;
+
+typedef struct {
+ char *buf;
+ size_t size;
+} HWCryptoHook_ErrMsgBuf;
+/* Used for error reporting. When a HWCryptoHook function fails it
+ * will return a sentinel value (0 for pointer-valued functions, or a
+ * negative number, usually HWCRYPTOHOOK_ERROR_FAILED, for
+ * integer-valued ones). It will, if an ErrMsgBuf is passed, also put
+ * an error message there.
+ *
+ * size is the size of the buffer. When the buffer is filled, it will
+ * always be null-terminated. If you pass 0 buf buf you must pass 0
+ * for size, and nothing will be recorded (just as if you passed 0 for
+ * the struct pointer). Size will not be modified when an error is
+ * recorded. The buffer is always null-terminated even if there is an
+ * overrun.
+ *
+ * The contents of the buffer are not defined if there is no error.
+ */
+
+typedef struct HWCryptoHook_MPIStruct {
+ unsigned char *buf;
+ size_t size;
+} HWCryptoHook_MPI;
+/* When one of these is returned, a pointer is passed to the function.
+ * At call, size is the space available. Afterwards it is updated.
+ * buf (the pointer) is not updated. size is in bytes and may be
+ * zero, but must be a multiple of the limb size. Zero limbs at the
+ * MS end are not permitted.
+ */
+
+#define HWCryptoHook_InitFlags_FallbackModExp 0x0002UL
+#define HWCryptoHook_InitFlags_FallbackRSAImmed 0x0004UL
+/* Enable requesting fallback to software in case of problems with the
+ * hardware support. This indicates to the crypto provider that the
+ * application is prepared to fall back to software operation if the
+ * ModExp* or RSAImmed* functions return HWCRYPTOHOOK_ERROR_FALLBACK.
+ * Without this flag those calls will never return
+ * HWCRYPTOHOOK_ERROR_FALLBACK. The flag will also cause the crypto
+ * provider to avoid repeatedly attempting to contact dead hardware
+ * within a short interval, if appropriate.
+ */
+
+#define HWCryptoHook_InitFlags_SimpleForkCheck 0x0010UL
+/* Without _SimpleForkCheck the library is allowed to assume that the
+ * application will not fork and call the library in the child(ren).
+ *
+ * When it is specified, this is allowed. However, after a fork
+ * neither parent nor child may unload any loaded keys or call
+ * _Finish. Instead, they should call exit (or die with a signal)
+ * without calling _Finish. After all the children have died the
+ * parent may unload keys or call _Finish.
+ *
+ * This flag only has any effect on UN*X platforms.
+ */
+
+typedef struct {
+ unsigned long flags;
+ void *logstream; /* usually a FILE*. See below. */
+
+ size_t limbsize; /* bignum format - size of radix type, must be power of 2 */
+ int mslimbfirst; /* 0 or 1 */
+ int msbytefirst; /* 0 or 1; -1 = native */
+
+ /* All the callback functions should return 0 on success, or a
+ * nonzero integer (whose value will be visible in the error message
+ * put in the buffer passed to the call).
+ *
+ * If a callback is not available pass a null function pointer.
+ *
+ * The callbacks may not call down again into the crypto plugin.
+ */
+
+ /* For thread-safety. Set everything to 0 if you promise only to be
+ * singlethreaded. maxsimultaneous is the number of calls to
+ * ModExp[Crt]/RSAImmed{Priv,Pub}/RSA. If you don't know what to
+ * put there then say 0 and the hook library will use a default.
+ *
+ * maxmutexes is a small limit on the number of simultaneous mutexes
+ * which will be requested by the library. If there is no small
+ * limit, set it to 0. If the crypto plugin cannot create the
+ * advertised number of mutexes the calls to its functions may fail.
+ * If a low number of mutexes is advertised the plugin will try to
+ * do the best it can. Making larger numbers of mutexes available
+ * may improve performance and parallelism by reducing contention
+ * over critical sections. Unavailability of any mutexes, implying
+ * single-threaded operation, should be indicated by the setting
+ * mutex_init et al to 0.
+ */
+ int maxmutexes;
+ int maxsimultaneous;
+ size_t mutexsize;
+ int (*mutex_init)(HWCryptoHook_Mutex*, HWCryptoHook_CallerContext *cactx);
+ int (*mutex_acquire)(HWCryptoHook_Mutex*);
+ void (*mutex_release)(HWCryptoHook_Mutex*);
+ void (*mutex_destroy)(HWCryptoHook_Mutex*);
+
+ /* For greater efficiency, can use condition vars internally for
+ * synchronisation. In this case maxsimultaneous is ignored, but
+ * the other mutex stuff must be available. In singlethreaded
+ * programs, set everything to 0.
+ */
+ size_t condvarsize;
+ int (*condvar_init)(HWCryptoHook_CondVar*, HWCryptoHook_CallerContext *cactx);
+ int (*condvar_wait)(HWCryptoHook_CondVar*, HWCryptoHook_Mutex*);
+ void (*condvar_signal)(HWCryptoHook_CondVar*);
+ void (*condvar_broadcast)(HWCryptoHook_CondVar*);
+ void (*condvar_destroy)(HWCryptoHook_CondVar*);
+
+ /* The semantics of acquiring and releasing mutexes and broadcasting
+ * and waiting on condition variables are expected to be those from
+ * POSIX threads (pthreads). The mutexes may be (in pthread-speak)
+ * fast mutexes, recursive mutexes, or nonrecursive ones.
+ *
+ * The _release/_signal/_broadcast and _destroy functions must
+ * always succeed when given a valid argument; if they are given an
+ * invalid argument then the program (crypto plugin + application)
+ * has an internal error, and they should abort the program.
+ */
+
+ int (*getpassphrase)(const char *prompt_info,
+ int *len_io, char *buf,
+ HWCryptoHook_PassphraseContext *ppctx,
+ HWCryptoHook_CallerContext *cactx);
+ /* Passphrases and the prompt_info, if they contain high-bit-set
+ * characters, are UTF-8. The prompt_info may be a null pointer if
+ * no prompt information is available (it should not be an empty
+ * string). It will not contain text like `enter passphrase';
+ * instead it might say something like `Operator Card for John
+ * Smith' or `SmartCard in nFast Module #1, Slot #1'.
+ *
+ * buf points to a buffer in which to return the passphrase; on
+ * entry *len_io is the length of the buffer. It should be updated
+ * by the callback. The returned passphrase should not be
+ * null-terminated by the callback.
+ */
+
+ int (*getphystoken)(const char *prompt_info,
+ const char *wrong_info,
+ HWCryptoHook_PassphraseContext *ppctx,
+ HWCryptoHook_CallerContext *cactx);
+ /* Requests that the human user physically insert a different
+ * smartcard, DataKey, etc. The plugin should check whether the
+ * currently inserted token(s) are appropriate, and if they are it
+ * should not make this call.
+ *
+ * prompt_info is as before. wrong_info is a description of the
+ * currently inserted token(s) so that the user is told what
+ * something is. wrong_info, like prompt_info, may be null, but
+ * should not be an empty string. Its contents should be
+ * syntactically similar to that of prompt_info.
+ */
+
+ /* Note that a single LoadKey operation might cause several calls to
+ * getpassphrase and/or requestphystoken. If requestphystoken is
+ * not provided (ie, a null pointer is passed) then the plugin may
+ * not support loading keys for which authorisation by several cards
+ * is required. If getpassphrase is not provided then cards with
+ * passphrases may not be supported.
+ *
+ * getpassphrase and getphystoken do not need to check that the
+ * passphrase has been entered correctly or the correct token
+ * inserted; the crypto plugin will do that. If this is not the
+ * case then the crypto plugin is responsible for calling these
+ * routines again as appropriate until the correct token(s) and
+ * passphrase(s) are supplied as required, or until any retry limits
+ * implemented by the crypto plugin are reached.
+ *
+ * In either case, the application must allow the user to say `no'
+ * or `cancel' to indicate that they do not know the passphrase or
+ * have the appropriate token; this should cause the callback to
+ * return nonzero indicating error.
+ */
+
+ void (*logmessage)(void *logstream, const char *message);
+ /* A log message will be generated at least every time something goes
+ * wrong and an ErrMsgBuf is filled in (or would be if one was
+ * provided). Other diagnostic information may be written there too,
+ * including more detailed reasons for errors which are reported in an
+ * ErrMsgBuf.
+ *
+ * When a log message is generated, this callback is called. It
+ * should write a message to the relevant logging arrangements.
+ *
+ * The message string passed will be null-terminated and may be of arbitrary
+ * length. It will not be prefixed by the time and date, nor by the
+ * name of the library that is generating it - if this is required,
+ * the logmessage callback must do it. The message will not have a
+ * trailing newline (though it may contain internal newlines).
+ *
+ * If a null pointer is passed for logmessage a default function is
+ * used. The default function treats logstream as a FILE* which has
+ * been converted to a void*. If logstream is 0 it does nothing.
+ * Otherwise it prepends the date and time and library name and
+ * writes the message to logstream. Each line will be prefixed by a
+ * descriptive string containing the date, time and identity of the
+ * crypto plugin. Errors on the logstream are not reported
+ * anywhere, and the default function doesn't flush the stream, so
+ * the application must set the buffering how it wants it.
+ *
+ * The crypto plugin may also provide a facility to have copies of
+ * log messages sent elsewhere, and or for adjusting the verbosity
+ * of the log messages; any such facilities will be configured by
+ * external means.
+ */
+
+} HWCryptoHook_InitInfo;
+
+typedef
+HWCryptoHook_ContextHandle HWCryptoHook_Init_t(const HWCryptoHook_InitInfo *initinfo,
+ size_t initinfosize,
+ HWCryptoHook_ErrMsgBuf *errors,
+ HWCryptoHook_CallerContext *cactx);
+extern HWCryptoHook_Init_t HWCryptoHook_Init;
+
+/* Caller should set initinfosize to the size of the HWCryptoHook struct,
+ * so it can be extended later.
+ *
+ * On success, a message for display or logging by the server,
+ * including the name and version number of the plugin, will be filled
+ * in into *errors; on failure *errors is used for error handling, as
+ * usual.
+ */
+
+/* All these functions return 0 on success, HWCRYPTOHOOK_ERROR_FAILED
+ * on most failures. HWCRYPTOHOOK_ERROR_MPISIZE means at least one of
+ * the output MPI buffer(s) was too small; the sizes of all have been
+ * set to the desired size (and for those where the buffer was large
+ * enough, the value may have been copied in), and no error message
+ * has been recorded.
+ *
+ * You may pass 0 for the errors struct. In any case, unless you set
+ * _NoStderr at init time then messages may be reported to stderr.
+ */
+
+/* The RSAImmed* functions (and key managed RSA) only work with
+ * modules which have an RSA patent licence - currently that means KM
+ * units; the ModExp* ones work with all modules, so you need a patent
+ * licence in the software in the US.
+ */
+
+typedef
+void HWCryptoHook_Finish_t(HWCryptoHook_ContextHandle hwctx);
+extern HWCryptoHook_Finish_t HWCryptoHook_Finish;
+/* You must not have any calls going or keys loaded when you call this. */
+
+typedef
+int HWCryptoHook_RandomBytes_t(HWCryptoHook_ContextHandle hwctx,
+ unsigned char *buf, size_t len,
+ const HWCryptoHook_ErrMsgBuf *errors);
+extern HWCryptoHook_RandomBytes_t HWCryptoHook_RandomBytes;
+
+typedef
+int HWCryptoHook_ModExp_t(HWCryptoHook_ContextHandle hwctx,
+ HWCryptoHook_MPI a,
+ HWCryptoHook_MPI p,
+ HWCryptoHook_MPI n,
+ HWCryptoHook_MPI *r,
+ const HWCryptoHook_ErrMsgBuf *errors);
+extern HWCryptoHook_ModExp_t HWCryptoHook_ModExp;
+
+typedef
+int HWCryptoHook_RSAImmedPub_t(HWCryptoHook_ContextHandle hwctx,
+ HWCryptoHook_MPI m,
+ HWCryptoHook_MPI e,
+ HWCryptoHook_MPI n,
+ HWCryptoHook_MPI *r,
+ const HWCryptoHook_ErrMsgBuf *errors);
+extern HWCryptoHook_RSAImmedPub_t HWCryptoHook_RSAImmedPub;
+
+typedef
+int HWCryptoHook_ModExpCRT_t(HWCryptoHook_ContextHandle hwctx,
+ HWCryptoHook_MPI a,
+ HWCryptoHook_MPI p,
+ HWCryptoHook_MPI q,
+ HWCryptoHook_MPI dmp1,
+ HWCryptoHook_MPI dmq1,
+ HWCryptoHook_MPI iqmp,
+ HWCryptoHook_MPI *r,
+ const HWCryptoHook_ErrMsgBuf *errors);
+extern HWCryptoHook_ModExpCRT_t HWCryptoHook_ModExpCRT;
+
+typedef
+int HWCryptoHook_RSAImmedPriv_t(HWCryptoHook_ContextHandle hwctx,
+ HWCryptoHook_MPI m,
+ HWCryptoHook_MPI p,
+ HWCryptoHook_MPI q,
+ HWCryptoHook_MPI dmp1,
+ HWCryptoHook_MPI dmq1,
+ HWCryptoHook_MPI iqmp,
+ HWCryptoHook_MPI *r,
+ const HWCryptoHook_ErrMsgBuf *errors);
+extern HWCryptoHook_RSAImmedPriv_t HWCryptoHook_RSAImmedPriv;
+
+/* The RSAImmed* and ModExp* functions may return E_FAILED or
+ * E_FALLBACK for failure.
+ *
+ * E_FAILED means the failure is permanent and definite and there
+ * should be no attempt to fall back to software. (Eg, for some
+ * applications, which support only the acceleration-only
+ * functions, the `key material' may actually be an encoded key
+ * identifier, and doing the operation in software would give wrong
+ * answers.)
+ *
+ * E_FALLBACK means that doing the computation in software would seem
+ * reasonable. If an application pays attention to this and is
+ * able to fall back, it should also set the Fallback init flags.
+ */
+
+typedef
+int HWCryptoHook_RSALoadKey_t(HWCryptoHook_ContextHandle hwctx,
+ const char *key_ident,
+ HWCryptoHook_RSAKeyHandle *keyhandle_r,
+ const HWCryptoHook_ErrMsgBuf *errors,
+ HWCryptoHook_PassphraseContext *ppctx);
+extern HWCryptoHook_RSALoadKey_t HWCryptoHook_RSALoadKey;
+/* The key_ident is a null-terminated string configured by the
+ * user via the application's usual configuration mechanisms.
+ * It is provided to the user by the crypto provider's key management
+ * system. The user must be able to enter at least any string of between
+ * 1 and 1023 characters inclusive, consisting of printable 7-bit
+ * ASCII characters. The provider should avoid using
+ * any characters except alphanumerics and the punctuation
+ * characters _ - + . / @ ~ (the user is expected to be able
+ * to enter these without quoting). The string may be case-sensitive.
+ * The application may allow the user to enter other NULL-terminated strings,
+ * and the provider must cope (returning an error if the string is not
+ * valid).
+ *
+ * If the key does not exist, it is _not_ an error - in that case,
+ * keyhandle_r will be set to 0 instead of to a key handle.
+ */
+
+typedef
+int HWCryptoHook_RSAGetPublicKey_t(HWCryptoHook_RSAKeyHandle k,
+ HWCryptoHook_MPI *n,
+ HWCryptoHook_MPI *e,
+ const HWCryptoHook_ErrMsgBuf *errors);
+extern HWCryptoHook_RSAGetPublicKey_t HWCryptoHook_RSAGetPublicKey;
+/* The crypto plugin will not store certificates.
+ *
+ * Although this function for acquiring the public key value is
+ * provided, it is not the purpose of this API to deal fully with the
+ * handling of the public key.
+ *
+ * It is expected that the crypto supplier's key generation program
+ * will provide general facilities for producing X.509
+ * self-certificates and certificate requests in PEM format. These
+ * will be given to the user so that they can configure them in the
+ * application, send them to CAs, or whatever.
+ *
+ * In case this kind of certificate handling is not appropriate, the
+ * crypto supplier's key generation program should be able to be
+ * configured not to generate such a self-certificate or certificate
+ * request. Then the application will need to do all of this, and
+ * will need to store and handle the public key and certificates
+ * itself.
+ */
+
+typedef
+int HWCryptoHook_RSAUnloadKey_t(HWCryptoHook_RSAKeyHandle k,
+ const HWCryptoHook_ErrMsgBuf *errors);
+extern HWCryptoHook_RSAUnloadKey_t HWCryptoHook_RSAUnloadKey;
+/* Might fail due to locking problems, or other serious internal problems. */
+
+typedef
+int HWCryptoHook_RSA_t(HWCryptoHook_MPI m,
+ HWCryptoHook_RSAKeyHandle k,
+ HWCryptoHook_MPI *r,
+ const HWCryptoHook_ErrMsgBuf *errors);
+extern HWCryptoHook_RSA_t HWCryptoHook_RSA;
+
+#endif /*HWCRYPTOHOOK_H*/
diff --git a/crypto/err/Makefile.ssl b/crypto/err/Makefile.ssl
index a31bc78914..00ee86f3c4 100644
--- a/crypto/err/Makefile.ssl
+++ b/crypto/err/Makefile.ssl
@@ -93,16 +93,17 @@ err_all.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
err_all.o: ../../include/openssl/des.h ../../include/openssl/dh.h
err_all.o: ../../include/openssl/dsa.h ../../include/openssl/dso.h
err_all.o: ../../include/openssl/e_os.h ../../include/openssl/e_os2.h
-err_all.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-err_all.o: ../../include/openssl/idea.h ../../include/openssl/lhash.h
-err_all.o: ../../include/openssl/md2.h ../../include/openssl/md4.h
-err_all.o: ../../include/openssl/md5.h ../../include/openssl/mdc2.h
-err_all.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-err_all.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-err_all.o: ../../include/openssl/pem2.h ../../include/openssl/pkcs12.h
-err_all.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
-err_all.o: ../../include/openssl/rc2.h ../../include/openssl/rc4.h
-err_all.o: ../../include/openssl/rc5.h ../../include/openssl/rijndael-alg-fst.h
+err_all.o: ../../include/openssl/engine.h ../../include/openssl/err.h
+err_all.o: ../../include/openssl/evp.h ../../include/openssl/idea.h
+err_all.o: ../../include/openssl/lhash.h ../../include/openssl/md2.h
+err_all.o: ../../include/openssl/md4.h ../../include/openssl/md5.h
+err_all.o: ../../include/openssl/mdc2.h ../../include/openssl/obj_mac.h
+err_all.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+err_all.o: ../../include/openssl/opensslv.h ../../include/openssl/pem2.h
+err_all.o: ../../include/openssl/pkcs12.h ../../include/openssl/pkcs7.h
+err_all.o: ../../include/openssl/rand.h ../../include/openssl/rc2.h
+err_all.o: ../../include/openssl/rc4.h ../../include/openssl/rc5.h
+err_all.o: ../../include/openssl/rijndael-alg-fst.h
err_all.o: ../../include/openssl/rijndael.h ../../include/openssl/ripemd.h
err_all.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
err_all.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
diff --git a/crypto/err/err.c b/crypto/err/err.c
index bfecb86c75..99272e437c 100644
--- a/crypto/err/err.c
+++ b/crypto/err/err.c
@@ -157,6 +157,7 @@ static ERR_STRING_DATA ERR_str_libraries[]=
{ERR_PACK(ERR_LIB_PKCS12,0,0) ,"PKCS12 routines"},
{ERR_PACK(ERR_LIB_RAND,0,0) ,"random number generator"},
{ERR_PACK(ERR_LIB_DSO,0,0) ,"DSO support routines"},
+{ERR_PACK(ERR_LIB_ENGINE,0,0) ,"engine routines"},
{0,NULL},
};
@@ -208,6 +209,7 @@ static ERR_STRING_DATA ERR_str_reasons[]=
{ERR_R_ASN1_LENGTH_MISMATCH ,"asn1 length mismatch"},
{ERR_R_MISSING_ASN1_EOS ,"missing asn1 eos"},
{ERR_R_DSO_LIB ,"DSO lib"},
+{ERR_R_ENGINE_LIB ,"ENGINE lib"},
{0,NULL},
};
diff --git a/crypto/err/err.h b/crypto/err/err.h
index 2c3d39c68c..7388a4a937 100644
--- a/crypto/err/err.h
+++ b/crypto/err/err.h
@@ -132,6 +132,7 @@ typedef struct err_state_st
#define ERR_LIB_PKCS12 35
#define ERR_LIB_RAND 36
#define ERR_LIB_DSO 37
+#define ERR_LIB_ENGINE 38
#define ERR_LIB_USER 128
@@ -161,6 +162,7 @@ typedef struct err_state_st
#define PKCS12err(f,r) ERR_PUT_error(ERR_LIB_PKCS12,(f),(r),ERR_file_name,__LINE__)
#define RANDerr(f,r) ERR_PUT_error(ERR_LIB_RAND,(f),(r),ERR_file_name,__LINE__)
#define DSOerr(f,r) ERR_PUT_error(ERR_LIB_DSO,(f),(r),ERR_file_name,__LINE__)
+#define ENGINEerr(f,r) ERR_PUT_error(ERR_LIB_ENGINE,(f),(r),ERR_file_name,__LINE__)
/* Borland C seems too stupid to be able to shift and do longs in
* the pre-processor :-( */
@@ -210,6 +212,7 @@ typedef struct err_state_st
#define ERR_R_PKCS7_LIB ERR_LIB_PKCS7
#define ERR_R_PKCS12_LIB ERR_LIB_PKCS12
#define ERR_R_DSO_LIB ERR_LIB_DSO
+#define ERR_R_ENGINE_LIB ERR_LIB_ENGINE
/* fatal error */
#define ERR_R_MALLOC_FAILURE (1|ERR_R_FATAL)
diff --git a/crypto/err/err_all.c b/crypto/err/err_all.c
index 638ed3fe71..b8315d8272 100644
--- a/crypto/err/err_all.c
+++ b/crypto/err/err_all.c
@@ -81,8 +81,9 @@
#include <openssl/conf.h>
#include <openssl/pkcs12.h>
#include <openssl/rand.h>
-#include <openssl/err.h>
#include <openssl/dso.h>
+#include <openssl/engine.h>
+#include <openssl/err.h>
void ERR_load_crypto_strings(void)
{
@@ -120,5 +121,6 @@ void ERR_load_crypto_strings(void)
ERR_load_PKCS12_strings();
ERR_load_RAND_strings();
ERR_load_DSO_strings();
+ ERR_load_ENGINE_strings();
#endif
}
diff --git a/crypto/err/openssl.ec b/crypto/err/openssl.ec
index 02deaa6fc9..861d680e07 100644
--- a/crypto/err/openssl.ec
+++ b/crypto/err/openssl.ec
@@ -23,6 +23,7 @@ L RSAREF rsaref/rsaref.h rsaref/rsar_err.c
L SSL ssl/ssl.h ssl/ssl_err.c
L COMP crypto/comp/comp.h crypto/comp/comp_err.c
L RAND crypto/rand/rand.h crypto/rand/rand_err.c
+L ENGINE crypto/engine/engine.h crypto/engine/engine_err.c
F RSAREF_F_RSA_BN2BIN
diff --git a/crypto/install.com b/crypto/install.com
index 8c283c4ceb..4780118ab9 100644
--- a/crypto/install.com
+++ b/crypto/install.com
@@ -34,7 +34,7 @@ $ IF F$PARSE("WRK_SSLINCLUDE:") .EQS. "" THEN -
$
$ SDIRS := ,MD2,MD4,MD5,SHA,MDC2,HMAC,RIPEMD,-
DES,RC2,RC4,RC5,IDEA,BF,CAST,-
- BN,RSA,DSA,DH,DSO,-
+ BN,RSA,DSA,DH,DSO,ENGINE,RIJNDAEL,-
BUFFER,BIO,STACK,LHASH,RAND,ERR,OBJECTS,-
EVP,ASN1,PEM,X509,X509V3,CONF,TXT_DB,PKCS7,PKCS12,COMP
$ EXHEADER_ := crypto.h,tmdiff.h,opensslv.h,opensslconf.h,ebcdic.h,symhacks.h
@@ -57,6 +57,8 @@ $ EXHEADER_RSA := rsa.h
$ EXHEADER_DSA := dsa.h
$ EXHEADER_DH := dh.h
$ EXHEADER_DSO := dso.h
+$ EXHEADER_ENGINE := engine.h
+$ EXHEADER_RIJNDAEL := rijndael-alg-fst.h,rijndael.h
$ EXHEADER_BUFFER := buffer.h
$ EXHEADER_BIO := bio.h
$ EXHEADER_STACK := stack.h,safestack.h
diff --git a/crypto/rand/Makefile.ssl b/crypto/rand/Makefile.ssl
index e9a6876b5a..a005df2019 100644
--- a/crypto/rand/Makefile.ssl
+++ b/crypto/rand/Makefile.ssl
@@ -92,7 +92,24 @@ rand_err.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
rand_err.o: ../../include/openssl/opensslv.h ../../include/openssl/rand.h
rand_err.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
rand_err.o: ../../include/openssl/symhacks.h
-rand_lib.o: ../../include/openssl/rand.h
+rand_lib.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+rand_lib.o: ../../include/openssl/blowfish.h ../../include/openssl/bn.h
+rand_lib.o: ../../include/openssl/cast.h ../../include/openssl/crypto.h
+rand_lib.o: ../../include/openssl/des.h ../../include/openssl/dh.h
+rand_lib.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
+rand_lib.o: ../../include/openssl/engine.h ../../include/openssl/evp.h
+rand_lib.o: ../../include/openssl/idea.h ../../include/openssl/md2.h
+rand_lib.o: ../../include/openssl/md4.h ../../include/openssl/md5.h
+rand_lib.o: ../../include/openssl/mdc2.h ../../include/openssl/obj_mac.h
+rand_lib.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+rand_lib.o: ../../include/openssl/opensslv.h ../../include/openssl/rand.h
+rand_lib.o: ../../include/openssl/rc2.h ../../include/openssl/rc4.h
+rand_lib.o: ../../include/openssl/rc5.h
+rand_lib.o: ../../include/openssl/rijndael-alg-fst.h
+rand_lib.o: ../../include/openssl/rijndael.h ../../include/openssl/ripemd.h
+rand_lib.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
+rand_lib.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+rand_lib.o: ../../include/openssl/symhacks.h
rand_win.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
rand_win.o: ../../include/openssl/crypto.h ../../include/openssl/e_os.h
rand_win.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
diff --git a/crypto/rand/rand.h b/crypto/rand/rand.h
index 971880edaa..eb9c8c034d 100644
--- a/crypto/rand/rand.h
+++ b/crypto/rand/rand.h
@@ -77,7 +77,9 @@ typedef struct rand_meth_st
extern int rand_predictable;
#endif
-void RAND_set_rand_method(RAND_METHOD *meth);
+struct engine_st;
+
+int RAND_set_rand_method(struct engine_st *meth);
RAND_METHOD *RAND_get_rand_method(void );
RAND_METHOD *RAND_SSLeay(void);
void RAND_cleanup(void );
diff --git a/crypto/rand/rand_lib.c b/crypto/rand/rand_lib.c
index 7da74aab0e..57eff0f132 100644
--- a/crypto/rand/rand_lib.c
+++ b/crypto/rand/rand_lib.c
@@ -59,59 +59,78 @@
#include <stdio.h>
#include <time.h>
#include <openssl/rand.h>
+#include <openssl/engine.h>
-#ifdef NO_RAND
-static RAND_METHOD *rand_meth=NULL;
-#else
-extern RAND_METHOD rand_ssleay_meth;
-static RAND_METHOD *rand_meth= &rand_ssleay_meth;
-#endif
+static ENGINE *rand_engine=NULL;
+#if 0
void RAND_set_rand_method(RAND_METHOD *meth)
{
rand_meth=meth;
}
+#else
+int RAND_set_rand_method(ENGINE *engine)
+ {
+ ENGINE *mtmp;
+ mtmp = rand_engine;
+ if (!ENGINE_init(engine))
+ return 0;
+ rand_engine = engine;
+ /* SHOULD ERROR CHECK THIS!!! */
+ ENGINE_finish(mtmp);
+ return 1;
+ }
+#endif
RAND_METHOD *RAND_get_rand_method(void)
{
- return(rand_meth);
+ if (rand_engine == NULL
+ && (rand_engine = ENGINE_get_default_RAND()) == NULL)
+ return NULL;
+ return ENGINE_get_RAND(rand_engine);
}
void RAND_cleanup(void)
{
- if (rand_meth != NULL)
- rand_meth->cleanup();
+ RAND_METHOD *meth = RAND_get_rand_method();
+ if (meth && meth->cleanup)
+ meth->cleanup();
}
void RAND_seed(const void *buf, int num)
{
- if (rand_meth != NULL)
- rand_meth->seed(buf,num);
+ RAND_METHOD *meth = RAND_get_rand_method();
+ if (meth && meth->seed)
+ meth->seed(buf,num);
}
void RAND_add(const void *buf, int num, double entropy)
{
- if (rand_meth != NULL)
- rand_meth->add(buf,num,entropy);
+ RAND_METHOD *meth = RAND_get_rand_method();
+ if (meth && meth->add)
+ meth->add(buf,num,entropy);
}
int RAND_bytes(unsigned char *buf, int num)
{
- if (rand_meth != NULL)
- return rand_meth->bytes(buf,num);
+ RAND_METHOD *meth = RAND_get_rand_method();
+ if (meth && meth->bytes)
+ return meth->bytes(buf,num);
return(-1);
}
int RAND_pseudo_bytes(unsigned char *buf, int num)
{
- if (rand_meth != NULL)
- return rand_meth->pseudorand(buf,num);
+ RAND_METHOD *meth = RAND_get_rand_method();
+ if (meth && meth->pseudorand)
+ return meth->pseudorand(buf,num);
return(-1);
}
int RAND_status(void)
{
- if (rand_meth != NULL)
- return rand_meth->status();
+ RAND_METHOD *meth = RAND_get_rand_method();
+ if (meth && meth->status)
+ return meth->status();
return 0;
}
diff --git a/crypto/rsa/Makefile.ssl b/crypto/rsa/Makefile.ssl
index 8fd68a688c..5e01a503cc 100644
--- a/crypto/rsa/Makefile.ssl
+++ b/crypto/rsa/Makefile.ssl
@@ -87,13 +87,24 @@ rsa_chk.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
rsa_chk.o: ../../include/openssl/opensslv.h ../../include/openssl/rsa.h
rsa_chk.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
rsa_chk.o: ../../include/openssl/symhacks.h
-rsa_eay.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
-rsa_eay.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+rsa_eay.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+rsa_eay.o: ../../include/openssl/blowfish.h ../../include/openssl/bn.h
+rsa_eay.o: ../../include/openssl/buffer.h ../../include/openssl/cast.h
+rsa_eay.o: ../../include/openssl/crypto.h ../../include/openssl/des.h
+rsa_eay.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h
rsa_eay.o: ../../include/openssl/e_os.h ../../include/openssl/e_os2.h
-rsa_eay.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
-rsa_eay.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-rsa_eay.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h
-rsa_eay.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+rsa_eay.o: ../../include/openssl/engine.h ../../include/openssl/err.h
+rsa_eay.o: ../../include/openssl/evp.h ../../include/openssl/idea.h
+rsa_eay.o: ../../include/openssl/lhash.h ../../include/openssl/md2.h
+rsa_eay.o: ../../include/openssl/md4.h ../../include/openssl/md5.h
+rsa_eay.o: ../../include/openssl/mdc2.h ../../include/openssl/obj_mac.h
+rsa_eay.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+rsa_eay.o: ../../include/openssl/opensslv.h ../../include/openssl/rand.h
+rsa_eay.o: ../../include/openssl/rc2.h ../../include/openssl/rc4.h
+rsa_eay.o: ../../include/openssl/rc5.h ../../include/openssl/rijndael-alg-fst.h
+rsa_eay.o: ../../include/openssl/rijndael.h ../../include/openssl/ripemd.h
+rsa_eay.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
+rsa_eay.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
rsa_eay.o: ../../include/openssl/symhacks.h ../cryptlib.h
rsa_err.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
rsa_err.o: ../../include/openssl/crypto.h ../../include/openssl/err.h
@@ -109,14 +120,25 @@ rsa_gen.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
rsa_gen.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
rsa_gen.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
rsa_gen.o: ../cryptlib.h
-rsa_lib.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
-rsa_lib.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+rsa_lib.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+rsa_lib.o: ../../include/openssl/blowfish.h ../../include/openssl/bn.h
+rsa_lib.o: ../../include/openssl/buffer.h ../../include/openssl/cast.h
+rsa_lib.o: ../../include/openssl/crypto.h ../../include/openssl/des.h
+rsa_lib.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h
rsa_lib.o: ../../include/openssl/e_os.h ../../include/openssl/e_os2.h
-rsa_lib.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
-rsa_lib.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+rsa_lib.o: ../../include/openssl/engine.h ../../include/openssl/err.h
+rsa_lib.o: ../../include/openssl/evp.h ../../include/openssl/idea.h
+rsa_lib.o: ../../include/openssl/lhash.h ../../include/openssl/md2.h
+rsa_lib.o: ../../include/openssl/md4.h ../../include/openssl/md5.h
+rsa_lib.o: ../../include/openssl/mdc2.h ../../include/openssl/obj_mac.h
+rsa_lib.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+rsa_lib.o: ../../include/openssl/opensslv.h ../../include/openssl/rand.h
+rsa_lib.o: ../../include/openssl/rc2.h ../../include/openssl/rc4.h
+rsa_lib.o: ../../include/openssl/rc5.h ../../include/openssl/rijndael-alg-fst.h
+rsa_lib.o: ../../include/openssl/rijndael.h ../../include/openssl/ripemd.h
rsa_lib.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
-rsa_lib.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-rsa_lib.o: ../cryptlib.h
+rsa_lib.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+rsa_lib.o: ../../include/openssl/symhacks.h ../cryptlib.h
rsa_none.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
rsa_none.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
rsa_none.o: ../../include/openssl/e_os.h ../../include/openssl/e_os2.h
@@ -179,15 +201,15 @@ rsa_sign.o: ../../include/openssl/buffer.h ../../include/openssl/cast.h
rsa_sign.o: ../../include/openssl/crypto.h ../../include/openssl/des.h
rsa_sign.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h
rsa_sign.o: ../../include/openssl/e_os.h ../../include/openssl/e_os2.h
-rsa_sign.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-rsa_sign.o: ../../include/openssl/idea.h ../../include/openssl/lhash.h
-rsa_sign.o: ../../include/openssl/md2.h ../../include/openssl/md4.h
-rsa_sign.o: ../../include/openssl/md5.h ../../include/openssl/mdc2.h
-rsa_sign.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-rsa_sign.o: ../../include/openssl/opensslconf.h
+rsa_sign.o: ../../include/openssl/engine.h ../../include/openssl/err.h
+rsa_sign.o: ../../include/openssl/evp.h ../../include/openssl/idea.h
+rsa_sign.o: ../../include/openssl/lhash.h ../../include/openssl/md2.h
+rsa_sign.o: ../../include/openssl/md4.h ../../include/openssl/md5.h
+rsa_sign.o: ../../include/openssl/mdc2.h ../../include/openssl/obj_mac.h
+rsa_sign.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
rsa_sign.o: ../../include/openssl/opensslv.h ../../include/openssl/pkcs7.h
-rsa_sign.o: ../../include/openssl/rc2.h ../../include/openssl/rc4.h
-rsa_sign.o: ../../include/openssl/rc5.h
+rsa_sign.o: ../../include/openssl/rand.h ../../include/openssl/rc2.h
+rsa_sign.o: ../../include/openssl/rc4.h ../../include/openssl/rc5.h
rsa_sign.o: ../../include/openssl/rijndael-alg-fst.h
rsa_sign.o: ../../include/openssl/rijndael.h ../../include/openssl/ripemd.h
rsa_sign.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
diff --git a/crypto/rsa/rsa.h b/crypto/rsa/rsa.h
index fef4ef5a2d..bda636a365 100644
--- a/crypto/rsa/rsa.h
+++ b/crypto/rsa/rsa.h
@@ -114,7 +114,11 @@ struct rsa_st
* this is passed instead of aEVP_PKEY, it is set to 0 */
int pad;
int version;
+#if 0
RSA_METHOD *meth;
+#else
+ struct engine_st *engine;
+#endif
BIGNUM *n;
BIGNUM *e;
BIGNUM *d;
@@ -168,7 +172,11 @@ struct rsa_st
#define RSA_get_app_data(s) RSA_get_ex_data(s,0)
RSA * RSA_new(void);
+#if 0
RSA * RSA_new_method(RSA_METHOD *method);
+#else
+RSA * RSA_new_method(struct engine_st *engine);
+#endif
int RSA_size(RSA *);
RSA * RSA_generate_key(int bits, unsigned long e,void
(*callback)(int,int,void *),void *cb_arg);
@@ -186,10 +194,14 @@ void RSA_free (RSA *r);
int RSA_flags(RSA *r);
-void RSA_set_default_method(RSA_METHOD *meth);
-RSA_METHOD *RSA_get_default_method(void);
+void RSA_set_default_openssl_method(RSA_METHOD *meth);
+RSA_METHOD *RSA_get_default_openssl_method(void);
RSA_METHOD *RSA_get_method(RSA *rsa);
+#if 0
RSA_METHOD *RSA_set_method(RSA *rsa, RSA_METHOD *meth);
+#else
+int RSA_set_method(RSA *rsa, struct engine_st *engine);
+#endif
/* This function needs the memory locking malloc callbacks to be installed */
int RSA_memory_lock(RSA *r);
diff --git a/crypto/rsa/rsa_eay.c b/crypto/rsa/rsa_eay.c
index 618b5bd595..8b8a1e279a 100644
--- a/crypto/rsa/rsa_eay.c
+++ b/crypto/rsa/rsa_eay.c
@@ -61,6 +61,7 @@
#include <openssl/bn.h>
#include <openssl/rsa.h>
#include <openssl/rand.h>
+#include <openssl/engine.h>
#ifndef RSA_NULL
@@ -97,11 +98,13 @@ RSA_METHOD *RSA_PKCS1_SSLeay(void)
static int RSA_eay_public_encrypt(int flen, unsigned char *from,
unsigned char *to, RSA *rsa, int padding)
{
+ const RSA_METHOD *meth;
BIGNUM f,ret;
int i,j,k,num=0,r= -1;
unsigned char *buf=NULL;
BN_CTX *ctx=NULL;
+ meth = ENGINE_get_RSA(rsa->engine);
BN_init(&f);
BN_init(&ret);
if ((ctx=BN_CTX_new()) == NULL) goto err;
@@ -143,7 +146,7 @@ static int RSA_eay_public_encrypt(int flen, unsigned char *from,
goto err;
}
- if (!rsa->meth->bn_mod_exp(&ret,&f,rsa->e,rsa->n,ctx,
+ if (!meth->bn_mod_exp(&ret,&f,rsa->e,rsa->n,ctx,
rsa->_method_mod_n)) goto err;
/* put in leading 0 bytes if the number is less than the
@@ -169,11 +172,13 @@ err:
static int RSA_eay_private_encrypt(int flen, unsigned char *from,
unsigned char *to, RSA *rsa, int padding)
{
+ const RSA_METHOD *meth;
BIGNUM f,ret;
int i,j,k,num=0,r= -1;
unsigned char *buf=NULL;
BN_CTX *ctx=NULL;
+ meth = ENGINE_get_RSA(rsa->engine);
BN_init(&f);
BN_init(&ret);
@@ -213,10 +218,10 @@ static int RSA_eay_private_encrypt(int flen, unsigned char *from,
(rsa->dmp1 != NULL) &&
(rsa->dmq1 != NULL) &&
(rsa->iqmp != NULL)) )
- { if (!rsa->meth->rsa_mod_exp(&ret,&f,rsa)) goto err; }
+ { if (!meth->rsa_mod_exp(&ret,&f,rsa)) goto err; }
else
{
- if (!rsa->meth->bn_mod_exp(&ret,&f,rsa->d,rsa->n,ctx,NULL)) goto err;
+ if (!meth->bn_mod_exp(&ret,&f,rsa->d,rsa->n,ctx,NULL)) goto err;
}
if (rsa->flags & RSA_FLAG_BLINDING)
@@ -245,12 +250,14 @@ err:
static int RSA_eay_private_decrypt(int flen, unsigned char *from,
unsigned char *to, RSA *rsa, int padding)
{
+ const RSA_METHOD *meth;
BIGNUM f,ret;
int j,num=0,r= -1;
unsigned char *p;
unsigned char *buf=NULL;
BN_CTX *ctx=NULL;
+ meth = ENGINE_get_RSA(rsa->engine);
BN_init(&f);
BN_init(&ret);
ctx=BN_CTX_new();
@@ -287,10 +294,10 @@ static int RSA_eay_private_decrypt(int flen, unsigned char *from,
(rsa->dmp1 != NULL) &&
(rsa->dmq1 != NULL) &&
(rsa->iqmp != NULL)) )
- { if (!rsa->meth->rsa_mod_exp(&ret,&f,rsa)) goto err; }
+ { if (!meth->rsa_mod_exp(&ret,&f,rsa)) goto err; }
else
{
- if (!rsa->meth->bn_mod_exp(&ret,&f,rsa->d,rsa->n,ctx,NULL))
+ if (!meth->bn_mod_exp(&ret,&f,rsa->d,rsa->n,ctx,NULL))
goto err;
}
@@ -338,12 +345,14 @@ err:
static int RSA_eay_public_decrypt(int flen, unsigned char *from,
unsigned char *to, RSA *rsa, int padding)
{
+ const RSA_METHOD *meth;
BIGNUM f,ret;
int i,num=0,r= -1;
unsigned char *p;
unsigned char *buf=NULL;
BN_CTX *ctx=NULL;
+ meth = ENGINE_get_RSA(rsa->engine);
BN_init(&f);
BN_init(&ret);
ctx=BN_CTX_new();
@@ -374,7 +383,7 @@ static int RSA_eay_public_decrypt(int flen, unsigned char *from,
goto err;
}
- if (!rsa->meth->bn_mod_exp(&ret,&f,rsa->e,rsa->n,ctx,
+ if (!meth->bn_mod_exp(&ret,&f,rsa->e,rsa->n,ctx,
rsa->_method_mod_n)) goto err;
p=buf;
@@ -409,10 +418,12 @@ err:
static int RSA_eay_mod_exp(BIGNUM *r0, BIGNUM *I, RSA *rsa)
{
+ const RSA_METHOD *meth;
BIGNUM r1,m1;
int ret=0;
BN_CTX *ctx;
+ meth = ENGINE_get_RSA(rsa->engine);
if ((ctx=BN_CTX_new()) == NULL) goto err;
BN_init(&m1);
BN_init(&r1);
@@ -436,11 +447,11 @@ static int RSA_eay_mod_exp(BIGNUM *r0, BIGNUM *I, RSA *rsa)
}
if (!BN_mod(&r1,I,rsa->q,ctx)) goto err;
- if (!rsa->meth->bn_mod_exp(&m1,&r1,rsa->dmq1,rsa->q,ctx,
+ if (!meth->bn_mod_exp(&m1,&r1,rsa->dmq1,rsa->q,ctx,
rsa->_method_mod_q)) goto err;
if (!BN_mod(&r1,I,rsa->p,ctx)) goto err;
- if (!rsa->meth->bn_mod_exp(r0,&r1,rsa->dmp1,rsa->p,ctx,
+ if (!meth->bn_mod_exp(r0,&r1,rsa->dmp1,rsa->p,ctx,
rsa->_method_mod_p)) goto err;
if (!BN_sub(r0,r0,&m1)) goto err;
diff --git a/crypto/rsa/rsa_lib.c b/crypto/rsa/rsa_lib.c
index bbddd3f0f0..5e1e8fcdf3 100644
--- a/crypto/rsa/rsa_lib.c
+++ b/crypto/rsa/rsa_lib.c
@@ -62,6 +62,7 @@
#include <openssl/lhash.h>
#include <openssl/bn.h>
#include <openssl/rsa.h>
+#include <openssl/engine.h>
const char *RSA_version="RSA" OPENSSL_VERSION_PTEXT;
@@ -74,12 +75,26 @@ RSA *RSA_new(void)
return(RSA_new_method(NULL));
}
-void RSA_set_default_method(RSA_METHOD *meth)
+void RSA_set_default_openssl_method(RSA_METHOD *meth)
{
- default_RSA_meth=meth;
+ ENGINE *e;
+ /* We'll need to notify the "openssl" ENGINE of this
+ * change too. We won't bother locking things down at
+ * our end as there was never any locking in these
+ * functions! */
+ if(default_RSA_meth != meth)
+ {
+ default_RSA_meth = meth;
+ e = ENGINE_by_id("openssl");
+ if(e)
+ {
+ ENGINE_set_RSA(e, meth);
+ ENGINE_free(e);
+ }
+ }
}
-RSA_METHOD *RSA_get_default_method(void)
+RSA_METHOD *RSA_get_default_openssl_method(void)
{
if (default_RSA_meth == NULL)
{
@@ -99,9 +114,10 @@ RSA_METHOD *RSA_get_default_method(void)
RSA_METHOD *RSA_get_method(RSA *rsa)
{
- return rsa->meth;
+ return ENGINE_get_RSA(rsa->engine);
}
+#if 0
RSA_METHOD *RSA_set_method(RSA *rsa, RSA_METHOD *meth)
{
RSA_METHOD *mtmp;
@@ -111,9 +127,32 @@ RSA_METHOD *RSA_set_method(RSA *rsa, RSA_METHOD *meth)
if (meth->init) meth->init(rsa);
return mtmp;
}
+#else
+int RSA_set_method(RSA *rsa, ENGINE *engine)
+{
+ ENGINE *mtmp;
+ RSA_METHOD *meth;
+ mtmp = rsa->engine;
+ meth = ENGINE_get_RSA(mtmp);
+ if (!ENGINE_init(engine))
+ return 0;
+ if (meth->finish) meth->finish(rsa);
+ rsa->engine = engine;
+ meth = ENGINE_get_RSA(engine);
+ if (meth->init) meth->init(rsa);
+ /* SHOULD ERROR CHECK THIS!!! */
+ ENGINE_finish(mtmp);
+ return 1;
+}
+#endif
+#if 0
RSA *RSA_new_method(RSA_METHOD *meth)
+#else
+RSA *RSA_new_method(ENGINE *engine)
+#endif
{
+ RSA_METHOD *meth;
RSA *ret;
ret=(RSA *)OPENSSL_malloc(sizeof(RSA));
@@ -123,10 +162,17 @@ RSA *RSA_new_method(RSA_METHOD *meth)
return(NULL);
}
- if (meth == NULL)
- ret->meth=RSA_get_default_method();
+ if (engine == NULL)
+ {
+ if((ret->engine=ENGINE_get_default_RSA()) == NULL)
+ {
+ OPENSSL_free(ret);
+ return NULL;
+ }
+ }
else
- ret->meth=meth;
+ ret->engine=engine;
+ meth = ENGINE_get_RSA(ret->engine);
ret->pad=0;
ret->version=0;
@@ -144,8 +190,8 @@ RSA *RSA_new_method(RSA_METHOD *meth)
ret->_method_mod_q=NULL;
ret->blinding=NULL;
ret->bignum_data=NULL;
- ret->flags=ret->meth->flags;
- if ((ret->meth->init != NULL) && !ret->meth->init(ret))
+ ret->flags=meth->flags;
+ if ((meth->init != NULL) && !meth->init(ret))
{
OPENSSL_free(ret);
ret=NULL;
@@ -157,6 +203,7 @@ RSA *RSA_new_method(RSA_METHOD *meth)
void RSA_free(RSA *r)
{
+ RSA_METHOD *meth;
int i;
if (r == NULL) return;
@@ -176,8 +223,10 @@ void RSA_free(RSA *r)
CRYPTO_free_ex_data(rsa_meth,r,&r->ex_data);
- if (r->meth->finish != NULL)
- r->meth->finish(r);
+ meth = ENGINE_get_RSA(r->engine);
+ if (meth->finish != NULL)
+ meth->finish(r);
+ ENGINE_finish(r->engine);
if (r->n != NULL) BN_clear_free(r->n);
if (r->e != NULL) BN_clear_free(r->e);
@@ -218,30 +267,34 @@ int RSA_size(RSA *r)
int RSA_public_encrypt(int flen, unsigned char *from, unsigned char *to,
RSA *rsa, int padding)
{
- return(rsa->meth->rsa_pub_enc(flen, from, to, rsa, padding));
+ return(ENGINE_get_RSA(rsa->engine)->rsa_pub_enc(flen,
+ from, to, rsa, padding));
}
int RSA_private_encrypt(int flen, unsigned char *from, unsigned char *to,
RSA *rsa, int padding)
{
- return(rsa->meth->rsa_priv_enc(flen, from, to, rsa, padding));
+ return(ENGINE_get_RSA(rsa->engine)->rsa_priv_enc(flen,
+ from, to, rsa, padding));
}
int RSA_private_decrypt(int flen, unsigned char *from, unsigned char *to,
RSA *rsa, int padding)
{
- return(rsa->meth->rsa_priv_dec(flen, from, to, rsa, padding));
+ return(ENGINE_get_RSA(rsa->engine)->rsa_priv_dec(flen,
+ from, to, rsa, padding));
}
int RSA_public_decrypt(int flen, unsigned char *from, unsigned char *to,
RSA *rsa, int padding)
{
- return(rsa->meth->rsa_pub_dec(flen, from, to, rsa, padding));
+ return(ENGINE_get_RSA(rsa->engine)->rsa_pub_dec(flen,
+ from, to, rsa, padding));
}
int RSA_flags(RSA *r)
{
- return((r == NULL)?0:r->meth->flags);
+ return((r == NULL)?0:ENGINE_get_RSA(r->engine)->flags);
}
void RSA_blinding_off(RSA *rsa)
@@ -275,7 +328,8 @@ int RSA_blinding_on(RSA *rsa, BN_CTX *p_ctx)
if (!BN_rand(A,BN_num_bits(rsa->n)-1,1,0)) goto err;
if ((Ai=BN_mod_inverse(NULL,A,rsa->n,ctx)) == NULL) goto err;
- if (!rsa->meth->bn_mod_exp(A,A,rsa->e,rsa->n,ctx,rsa->_method_mod_n))
+ if (!ENGINE_get_RSA(rsa->engine)->bn_mod_exp(A,A,
+ rsa->e,rsa->n,ctx,rsa->_method_mod_n))
goto err;
rsa->blinding=BN_BLINDING_new(A,Ai,rsa->n);
rsa->flags|=RSA_FLAG_BLINDING;
diff --git a/crypto/rsa/rsa_sign.c b/crypto/rsa/rsa_sign.c
index 31049b9791..cf00876292 100644
--- a/crypto/rsa/rsa_sign.c
+++ b/crypto/rsa/rsa_sign.c
@@ -62,6 +62,7 @@
#include <openssl/rsa.h>
#include <openssl/objects.h>
#include <openssl/x509.h>
+#include <openssl/engine.h>
/* Size of an SSL signature: MD5+SHA1 */
#define SSL_SIG_LENGTH 36
@@ -76,7 +77,8 @@ int RSA_sign(int type, unsigned char *m, unsigned int m_len,
X509_ALGOR algor;
ASN1_OCTET_STRING digest;
if(rsa->flags & RSA_FLAG_SIGN_VER)
- return rsa->meth->rsa_sign(type, m, m_len, sigret, siglen, rsa);
+ return ENGINE_get_RSA(rsa->engine)->rsa_sign(type,
+ m, m_len, sigret, siglen, rsa);
/* Special case: SSL signature, just check the length */
if(type == NID_md5_sha1) {
if(m_len != SSL_SIG_LENGTH) {
@@ -151,7 +153,8 @@ int RSA_verify(int dtype, unsigned char *m, unsigned int m_len,
}
if(rsa->flags & RSA_FLAG_SIGN_VER)
- return rsa->meth->rsa_verify(dtype, m, m_len, sigbuf, siglen, rsa);
+ return ENGINE_get_RSA(rsa->engine)->rsa_verify(dtype,
+ m, m_len, sigbuf, siglen, rsa);
s=(unsigned char *)OPENSSL_malloc((unsigned int)siglen);
if (s == NULL)