aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Levitte <levitte@openssl.org>2000-05-25 19:55:54 +0000
committerRichard Levitte <levitte@openssl.org>2000-05-25 19:55:54 +0000
commite759b095d447eab7d888065c5b69d986b516e183 (patch)
treeedfdd78881d8356377802e9a4e02da74d7fe7247
parentafa0598f066302b4b0679bec317aa3418143556f (diff)
downloadopenssl-e759b095d447eab7d888065c5b69d986b516e183.tar.gz
Add code and changes to implement the ENGINE mechanism. These are the
patches that Geoff had in a patch file in his play directory. NOTE for openssl-cvs: THIS IS A CVS BRANCH (BRANCH_engine). IT IS NOT FOR THE FAINTHEARTED TO PLAY WITH. The code works as it is, but it's not at all sure it ends up in the OpenSSL distributio in this form, so do not get dependent on it! Those rsyncing the repository are considered warned!
-rwxr-xr-xConfigure14
-rw-r--r--Makefile.org2
-rw-r--r--apps/Makefile.ssl24
-rw-r--r--apps/speed.c27
-rw-r--r--crypto/Makefile.ssl2
-rw-r--r--crypto/cryptlib.c3
-rw-r--r--crypto/crypto.h3
-rw-r--r--crypto/engine/Makefile.ssl126
-rw-r--r--crypto/engine/engine.h297
-rw-r--r--crypto/engine/engine_err.c142
-rw-r--r--crypto/engine/engine_int.h136
-rw-r--r--crypto/engine/engine_lib.c369
-rw-r--r--crypto/engine/engine_list.c575
-rw-r--r--crypto/engine/engine_openssl.c171
-rw-r--r--crypto/engine/enginetest.c251
-rw-r--r--crypto/engine/hw_cswift.c474
-rw-r--r--crypto/engine/vendor_defns/cswift.h132
-rw-r--r--crypto/err/Makefile.ssl26
-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/rsa/Makefile.ssl37
-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
-rw-r--r--test/Makefile.ssl16
-rwxr-xr-xutil/mkdef.pl2
-rwxr-xr-xutil/mkfiles.pl1
30 files changed, 2897 insertions, 81 deletions
diff --git a/Configure b/Configure
index 80b20efeef..af9833ef3e 100755
--- a/Configure
+++ b/Configure
@@ -10,7 +10,7 @@ use strict;
# see INSTALL for instructions.
-my $usage="Usage: Configure [no-<cipher> ...] [-Dxxx] [-lxxx] [-Lxxx] [-fxxx] [-Kxxx] [rsaref] [no-threads] [no-asm] [no-dso] [386] [--prefix=DIR] [--openssldir=OPENSSLDIR] os/compiler[:flags]\n";
+my $usage="Usage: Configure [no-<cipher> ...] [-Dxxx] [-lxxx] [-Lxxx] [-fxxx] [-Kxxx] [hw-xxx] [rsaref] [no-threads] [no-asm] [no-dso] [386] [--prefix=DIR] [--openssldir=OPENSSLDIR] os/compiler[:flags]\n";
# Options:
#
@@ -23,6 +23,11 @@ my $usage="Usage: Configure [no-<cipher> ...] [-Dxxx] [-lxxx] [-Lxxx] [-fxxx] [-
# default). This needn't be set in advance, you can
# just as well use "make INSTALL_PREFIX=/whatever install".
#
+# hw-xxx compile support for specific crypto hardware. Generic
+# OpenSSL-style methods relating to this support are
+# always compiled but return NULL if the hardware support
+# isn't compiled. Currently, hw-cswift is the only support
+# of this form.
# rsaref use RSAref
# [no-]threads [don't] try to create a library that is suitable for
# multithreaded applications (default is "threads" if we
@@ -459,6 +464,13 @@ foreach (@ARGV)
$openssl_algorithm_defines .= "#define NO_MDC2\n";
}
}
+ elsif (/^hw-(.+)$/)
+ {
+ my $hw=$1;
+ $hw =~ tr/[a-z]/[A-Z]/;
+ $flags .= "-DHW_$hw ";
+ $openssl_other_defines .= "#define HW_$hw\n";
+ }
elsif (/^386$/)
{ $processor=386; }
elsif (/^rsaref$/)
diff --git a/Makefile.org b/Makefile.org
index cf98fb515e..62a300ff5c 100644
--- a/Makefile.org
+++ b/Makefile.org
@@ -149,7 +149,7 @@ SHLIBDIRS= crypto ssl
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
diff --git a/apps/Makefile.ssl b/apps/Makefile.ssl
index 0d0cd888b4..a94bafab94 100644
--- a/apps/Makefile.ssl
+++ b/apps/Makefile.ssl
@@ -733,18 +733,18 @@ speed.o: ../include/openssl/buffer.h ../include/openssl/cast.h
speed.o: ../include/openssl/crypto.h ../include/openssl/des.h
speed.o: ../include/openssl/dh.h ../include/openssl/dsa.h
speed.o: ../include/openssl/e_os.h ../include/openssl/e_os2.h
-speed.o: ../include/openssl/err.h ../include/openssl/evp.h
-speed.o: ../include/openssl/hmac.h ../include/openssl/idea.h
-speed.o: ../include/openssl/md2.h ../include/openssl/md5.h
-speed.o: ../include/openssl/mdc2.h ../include/openssl/objects.h
-speed.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
-speed.o: ../include/openssl/pkcs7.h ../include/openssl/rand.h
-speed.o: ../include/openssl/rc2.h ../include/openssl/rc4.h
-speed.o: ../include/openssl/rc5.h ../include/openssl/ripemd.h
-speed.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
-speed.o: ../include/openssl/sha.h ../include/openssl/stack.h
-speed.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h ./testdsa.h
-speed.o: ./testrsa.h apps.h
+speed.o: ../include/openssl/engine.h ../include/openssl/err.h
+speed.o: ../include/openssl/evp.h ../include/openssl/hmac.h
+speed.o: ../include/openssl/idea.h ../include/openssl/md2.h
+speed.o: ../include/openssl/md5.h ../include/openssl/mdc2.h
+speed.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
+speed.o: ../include/openssl/opensslv.h ../include/openssl/pkcs7.h
+speed.o: ../include/openssl/rand.h ../include/openssl/rc2.h
+speed.o: ../include/openssl/rc4.h ../include/openssl/rc5.h
+speed.o: ../include/openssl/ripemd.h ../include/openssl/rsa.h
+speed.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+speed.o: ../include/openssl/stack.h ../include/openssl/x509.h
+speed.o: ../include/openssl/x509_vfy.h ./testdsa.h ./testrsa.h apps.h
spkac.o: ../include/openssl/asn1.h ../include/openssl/bio.h
spkac.o: ../include/openssl/blowfish.h ../include/openssl/bn.h
spkac.o: ../include/openssl/buffer.h ../include/openssl/cast.h
diff --git a/apps/speed.c b/apps/speed.c
index f7a8e00a8b..1a87aa1407 100644
--- a/apps/speed.c
+++ b/apps/speed.c
@@ -81,6 +81,7 @@
#include <openssl/crypto.h>
#include <openssl/rand.h>
#include <openssl/err.h>
+#include <openssl/engine.h>
#if !defined(MSDOS) && (!defined(VMS) || defined(__DECC))
#define TIMES
@@ -242,6 +243,7 @@ int MAIN(int, char **);
int MAIN(int argc, char **argv)
{
+ ENGINE *e;
unsigned char *buf=NULL,*buf2=NULL;
int mret=1;
#define ALGOR_NUM 14
@@ -391,6 +393,26 @@ int MAIN(int argc, char **argv)
argv++;
while (argc)
{
+ if ((strcmp(*argv,"-engine") == 0) && (argc > 0))
+ {
+ argc--;
+ argv++;
+ if((e = ENGINE_by_id(*argv)) == NULL)
+ {
+ BIO_printf(bio_err,"invalid engine \"%s\"\n",
+ *argv);
+ goto end;
+ }
+ if(!ENGINE_set_default(e, ENGINE_METHOD_ALL))
+ {
+ BIO_printf(bio_err,"can't use that engine\n");
+ goto end;
+ }
+ BIO_printf(bio_err,"engine \"%s\" set.\n", *argv);
+ /* Free our "structural" reference. */
+ ENGINE_free(e);
+ }
+ else
#ifndef NO_MD2
if (strcmp(*argv,"md2") == 0) doit[D_MD2]=1;
else
@@ -434,7 +456,7 @@ int MAIN(int argc, char **argv)
#ifdef RSAref
if (strcmp(*argv,"rsaref") == 0)
{
- RSA_set_default_method(RSA_PKCS1_RSAref());
+ RSA_set_default_openssl_method(RSA_PKCS1_RSAref());
j--;
}
else
@@ -442,7 +464,7 @@ int MAIN(int argc, char **argv)
#ifndef RSA_NULL
if (strcmp(*argv,"openssl") == 0)
{
- RSA_set_default_method(RSA_PKCS1_SSLeay());
+ RSA_set_default_openssl_method(RSA_PKCS1_SSLeay());
j--;
}
else
@@ -1173,6 +1195,7 @@ int MAIN(int argc, char **argv)
#endif
mret=0;
end:
+ ERR_print_errors(bio_err);
if (buf != NULL) Free(buf);
if (buf2 != NULL) Free(buf2);
#ifndef NO_RSA
diff --git a/crypto/Makefile.ssl b/crypto/Makefile.ssl
index b8e3072ee9..2fa2f0d2f9 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
diff --git a/crypto/cryptlib.c b/crypto/cryptlib.c
index 40a30a0939..0502a874a0 100644
--- a/crypto/cryptlib.c
+++ b/crypto/cryptlib.c
@@ -95,7 +95,8 @@ static const char* lock_names[CRYPTO_NUM_LOCKS] =
"dh",
"debug_malloc2",
"dso",
-#if CRYPTO_NUM_LOCKS != 27
+ "engine",
+#if CRYPTO_NUM_LOCKS != 28
# error "Inconsistency between crypto.h and cryptlib.c"
#endif
};
diff --git a/crypto/crypto.h b/crypto/crypto.h
index aee1899a25..71f2f6fdf2 100644
--- a/crypto/crypto.h
+++ b/crypto/crypto.h
@@ -122,7 +122,8 @@ extern "C" {
#define CRYPTO_LOCK_DH 24
#define CRYPTO_LOCK_MALLOC2 25
#define CRYPTO_LOCK_DSO 26
-#define CRYPTO_NUM_LOCKS 27
+#define CRYPTO_LOCK_ENGINE 27
+#define CRYPTO_NUM_LOCKS 28
#define CRYPTO_LOCK 1
#define CRYPTO_UNLOCK 2
diff --git a/crypto/engine/Makefile.ssl b/crypto/engine/Makefile.ssl
new file mode 100644
index 0000000000..86754a9c5d
--- /dev/null
+++ b/crypto/engine/Makefile.ssl
@@ -0,0 +1,126 @@
+#
+# 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_cswift.c
+LIBOBJ= engine_err.o engine_lib.o engine_list.o engine_openssl.o \
+ hw_cswift.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/bn.h ../../include/openssl/crypto.h
+engine_err.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h
+engine_err.o: ../../include/openssl/engine.h ../../include/openssl/err.h
+engine_err.o: ../../include/openssl/opensslconf.h
+engine_err.o: ../../include/openssl/opensslv.h ../../include/openssl/rand.h
+engine_err.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
+engine_err.o: ../../include/openssl/stack.h
+engine_lib.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
+engine_lib.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.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/opensslconf.h
+engine_lib.o: ../../include/openssl/opensslv.h ../../include/openssl/rand.h
+engine_lib.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
+engine_lib.o: ../../include/openssl/stack.h ../cryptlib.h engine_int.h
+engine_list.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
+engine_list.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.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/opensslconf.h
+engine_list.o: ../../include/openssl/opensslv.h ../../include/openssl/rand.h
+engine_list.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
+engine_list.o: ../../include/openssl/stack.h ../cryptlib.h engine_int.h
+engine_openssl.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
+engine_openssl.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.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
+engine_openssl.o: ../../include/openssl/opensslconf.h
+engine_openssl.o: ../../include/openssl/opensslv.h ../../include/openssl/rand.h
+engine_openssl.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
+engine_openssl.o: ../../include/openssl/stack.h ../cryptlib.h engine_int.h
+hw_cswift.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
+hw_cswift.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.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/opensslconf.h
+hw_cswift.o: ../../include/openssl/opensslv.h ../../include/openssl/rand.h
+hw_cswift.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
+hw_cswift.o: ../../include/openssl/stack.h ../cryptlib.h engine_int.h
diff --git a/crypto/engine/engine.h b/crypto/engine/engine.h
new file mode 100644
index 0000000000..ad4f3f539c
--- /dev/null
+++ b/crypto/engine/engine.h
@@ -0,0 +1,297 @@
+/* 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>
+
+#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
+
+/* 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);
+
+/* 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! */
+ENGINE *ENGINE_new(ENGINE *e);
+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);
+
+/* 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_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. */
+int ENGINE_get_struct_size(void);
+
+/* 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);
+
+/* 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_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_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_DH 111
+#define ENGINE_F_ENGINE_GET_DSA 112
+#define ENGINE_F_ENGINE_GET_ID 113
+#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_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_DEFAULT_TYPE 126
+#define ENGINE_F_ENGINE_SET_DH 127
+#define ENGINE_F_ENGINE_SET_DSA 128
+#define ENGINE_F_ENGINE_SET_ID 129
+#define ENGINE_F_ENGINE_SET_NAME 130
+#define ENGINE_F_ENGINE_SET_RAND 131
+#define ENGINE_F_ENGINE_SET_RSA 132
+
+/* Reason codes. */
+#define ENGINE_R_ALREADY_LOADED 100
+#define ENGINE_R_BN_CTX_FULL 101
+#define ENGINE_R_BN_EXPAND_FAIL 102
+#define ENGINE_R_CONFLICTING_ENGINE_ID 103
+#define ENGINE_R_DSO_FAILURE 104
+#define ENGINE_R_ENGINE_IS_NOT_IN_LIST 105
+#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_LOADED 112
+#define ENGINE_R_NO_SUCH_ENGINE 116
+#define ENGINE_R_PROVIDE_PARAMETERS 113
+#define ENGINE_R_REQUEST_FAILED 114
+#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..2ba0d301a6
--- /dev/null
+++ b/crypto/engine/engine_err.c
@@ -0,0 +1,142 @@
+/* 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_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_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_DH,0), "ENGINE_get_DH"},
+{ERR_PACK(0,ENGINE_F_ENGINE_GET_DSA,0), "ENGINE_get_DSA"},
+{ERR_PACK(0,ENGINE_F_ENGINE_GET_ID,0), "ENGINE_get_id"},
+{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_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_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_ID,0), "ENGINE_set_id"},
+{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"},
+{0,NULL}
+ };
+
+static ERR_STRING_DATA ENGINE_str_reasons[]=
+ {
+{ENGINE_R_ALREADY_LOADED ,"already loaded"},
+{ENGINE_R_BN_CTX_FULL ,"BN_CTX full"},
+{ENGINE_R_BN_EXPAND_FAIL ,"bn_expand fail"},
+{ENGINE_R_CONFLICTING_ENGINE_ID ,"conflicting engine id"},
+{ENGINE_R_DSO_FAILURE ,"DSO failure"},
+{ENGINE_R_ENGINE_IS_NOT_IN_LIST ,"engine is not in the list"},
+{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_LOADED ,"not loaded"},
+{ENGINE_R_NO_SUCH_ENGINE ,"no such engine"},
+{ENGINE_R_PROVIDE_PARAMETERS ,"provide parameters"},
+{ENGINE_R_REQUEST_FAILED ,"request failed"},
+{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..94f9d30d80
--- /dev/null
+++ b/crypto/engine/engine_int.h
@@ -0,0 +1,136 @@
+/* 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>
+
+#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);
+
+#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)();
+ int (*finish)();
+ 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();
+
+#ifdef 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 /* HW_CSWIFT */
+
+#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..787ebe9547
--- /dev/null
+++ b/crypto/engine/engine_lib.c
@@ -0,0 +1,369 @@
+/* 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)
+ /* 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);
+ return to_return;
+ }
+
+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..03d9a12616
--- /dev/null
+++ b/crypto/engine/engine_list.c
@@ -0,0 +1,575 @@
+/* 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;
+#ifdef HW_CSWIFT
+ if(!engine_list_add(ENGINE_cswift()))
+ return 0;
+#endif /* HW_CSWIFT */
+ 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;
+ }
+
+int ENGINE_get_struct_size(void)
+ {
+ return sizeof(ENGINE);
+ }
+
+ENGINE *ENGINE_new(ENGINE *e)
+ {
+ ENGINE *ret;
+
+ if(e == NULL)
+ {
+ ret = (ENGINE *)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;
+ }
+
+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)
+ 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;
+ }
+
+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;
+ }
diff --git a/crypto/engine/engine_openssl.c b/crypto/engine/engine_openssl.c
new file mode 100644
index 0000000000..4c760bde2d
--- /dev/null
+++ b/crypto/engine/engine_openssl.c
@@ -0,0 +1,171 @@
+/* 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 'hardware' support",
+ NULL,
+ NULL,
+ NULL, /* these methods are "stolen" in ENGINE_openssl() */
+ NULL,
+ NULL,
+ openssl_mod_exp_crt,
+ NULL, /* no "init()" */
+ NULL, /* no "finish()" */
+ 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_method();
+ engine_openssl.dh_meth = DH_get_default_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..7fdd395b42
--- /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)) == NULL) ||
+ !ENGINE_set_id(new_h1, "test_id0") ||
+ !ENGINE_set_name(new_h1, "First test item") ||
+ ((new_h2 = ENGINE_new(NULL)) == NULL) ||
+ !ENGINE_set_id(new_h2, "test_id1") ||
+ !ENGINE_set_name(new_h2, "Second test item") ||
+ ((new_h3 = ENGINE_new(NULL)) == NULL) ||
+ !ENGINE_set_id(new_h3, "test_id2") ||
+ !ENGINE_set_name(new_h3, "Third test item") ||
+ ((new_h4 = ENGINE_new(NULL)) == 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 fill up the engine type array\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)) == 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 array\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 complete\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_cswift.c b/crypto/engine/hw_cswift.c
new file mode 100644
index 0000000000..ca73599e73
--- /dev/null
+++ b/crypto/engine/hw_cswift.c
@@ -0,0 +1,474 @@
+/* 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>
+
+#ifdef HW_CSWIFT
+
+/* Attribution notice: Rainbow have generously allowed me to reproduce
+ * the necessary definitions here from their API. This means the support
+ * can build independantly 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]
+ */
+#include "vendor_defns/cswift.h"
+
+static int cswift_init();
+static int cswift_finish();
+
+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);
+
+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);
+
+/* Our internal RSA_METHOD that we provide const 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 ENGINE structure. */
+static ENGINE engine_cswift =
+ {
+ "cswift",
+ "CryptoSwift hardware support",
+ &cswift_rsa,
+ NULL,
+ NULL,
+ NULL,
+ cswift_mod_exp,
+ cswift_mod_exp_crt,
+ cswift_init,
+ cswift_finish,
+ 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 *meth;
+
+ /* 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! */
+ meth = RSA_PKCS1_SSLeay();
+ cswift_rsa.rsa_pub_enc = meth->rsa_pub_enc;
+ cswift_rsa.rsa_pub_dec = meth->rsa_pub_dec;
+ cswift_rsa.rsa_priv_enc = meth->rsa_priv_enc;
+ cswift_rsa.rsa_priv_dec = meth->rsa_priv_dec;
+ 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,
+ DSO_FLAG_NAME_TRANSLATION);
+ if(cswift_dso == NULL)
+ {
+ ENGINEerr(ENGINE_F_CSWIFT_INIT,ENGINE_R_DSO_FAILURE);
+ goto err;
+ }
+ if(!(p1 = DSO_bind(cswift_dso, CSWIFT_F1)) ||
+ !(p2 = DSO_bind(cswift_dso, CSWIFT_F2)) ||
+ !(p3 = DSO_bind(cswift_dso, CSWIFT_F3)) ||
+ !(p4 = DSO_bind(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);
+ 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_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, (char *)modulus->d);
+ sw_param.up.exp.modulus.value = (char *)modulus->d;
+ sw_param.up.exp.exponent.nbytes = BN_bn2bin(p, (char *)exponent->d);
+ sw_param.up.exp.exponent.value = (char *)exponent->d;
+ /* Attach the key params */
+ if(p_CSwift_AttachKeyParam(hac, &sw_param) != SW_OK)
+ {
+ ENGINEerr(ENGINE_F_CSWIFT_MOD_EXP,ENGINE_R_PROVIDE_PARAMETERS);
+ goto err;
+ }
+ /* Prepare the argument and response */
+ arg.nbytes = BN_bn2bin(a, (char *)argument->d);
+ arg.value = (char *)argument->d;
+ res.nbytes = BN_num_bytes(m);
+ memset(result->d, 0, res.nbytes);
+ res.value = (char *)result->d;
+ /* Perform the operation */
+ if(p_CSwift_SimpleRequest(hac, SW_CMD_MODEXP, &arg, 1, &res, 1) != SW_OK)
+ {
+ ENGINEerr(ENGINE_F_CSWIFT_MOD_EXP,ENGINE_R_REQUEST_FAILED);
+ goto err;
+ }
+ /* Convert the response */
+ BN_bin2bn((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)
+ {
+ BIGNUM *rsa_p;
+ BIGNUM *rsa_q;
+ BIGNUM *rsa_dmp1;
+ BIGNUM *rsa_dmq1;
+ BIGNUM *rsa_iqmp;
+ BIGNUM *argument;
+ BIGNUM *result;
+ SW_LARGENUMBER arg, res;
+ SW_PARAM sw_param;
+ SW_CONTEXT_HANDLE hac;
+ int to_return, acquired;
+
+ rsa_p = rsa_q = rsa_dmp1 = rsa_dmq1 = rsa_iqmp =
+ argument = result = NULL;
+ to_return = 0; /* expect failure */
+ 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, (char *)rsa_p->d);
+ sw_param.up.crt.p.value = (char *)rsa_p->d;
+ sw_param.up.crt.q.nbytes = BN_bn2bin(q, (char *)rsa_q->d);
+ sw_param.up.crt.q.value = (char *)rsa_q->d;
+ sw_param.up.crt.dmp1.nbytes = BN_bn2bin(dmp1, (char *)rsa_dmp1->d);
+ sw_param.up.crt.dmp1.value = (char *)rsa_dmp1->d;
+ sw_param.up.crt.dmq1.nbytes = BN_bn2bin(dmq1, (char *)rsa_dmq1->d);
+ sw_param.up.crt.dmq1.value = (char *)rsa_dmq1->d;
+ sw_param.up.crt.iqmp.nbytes = BN_bn2bin(iqmp, (char *)rsa_iqmp->d);
+ sw_param.up.crt.iqmp.value = (char *)rsa_iqmp->d;
+ /* Attach the key params */
+ if(p_CSwift_AttachKeyParam(hac, &sw_param) != SW_OK)
+ {
+ ENGINEerr(ENGINE_F_CSWIFT_MOD_EXP_CRT,ENGINE_R_PROVIDE_PARAMETERS);
+ goto err;
+ }
+ /* Prepare the argument and response */
+ arg.nbytes = BN_bn2bin(a, (char *)argument->d);
+ arg.value = (char *)argument->d;
+ res.nbytes = 2 * BN_num_bytes(p);
+ memset(result->d, 0, res.nbytes);
+ res.value = (char *)result->d;
+ /* Perform the operation */
+ if(p_CSwift_SimpleRequest(hac, SW_CMD_MODEXP_CRT, &arg, 1,
+ &res, 1) != SW_OK)
+ {
+ ENGINEerr(ENGINE_F_CSWIFT_MOD_EXP_CRT,ENGINE_R_REQUEST_FAILED);
+ goto err;
+ }
+ /* Convert the response */
+ BN_bin2bn((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);
+ }
+
+#endif /* HW_CSWIFT */
+
diff --git a/crypto/engine/vendor_defns/cswift.h b/crypto/engine/vendor_defns/cswift.h
new file mode 100644
index 0000000000..6048048c36
--- /dev/null
+++ b/crypto/engine/vendor_defns/cswift.h
@@ -0,0 +1,132 @@
+/* Attribution notice: Rainbow have generously allowed me to reproduce
+ * the necessary definitions here from their API. This means the support
+ * can build independantly 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
+
+#define SW_OK (0L)
+
+ /* 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/err/Makefile.ssl b/crypto/err/Makefile.ssl
index 640ed75678..d5be96f785 100644
--- a/crypto/err/Makefile.ssl
+++ b/crypto/err/Makefile.ssl
@@ -91,19 +91,19 @@ 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/md5.h
-err_all.o: ../../include/openssl/mdc2.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/ripemd.h
-err_all.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
-err_all.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
-err_all.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
-err_all.o: ../../include/openssl/x509v3.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/md5.h ../../include/openssl/mdc2.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/ripemd.h ../../include/openssl/rsa.h
+err_all.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+err_all.o: ../../include/openssl/stack.h ../../include/openssl/x509.h
+err_all.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
err_prn.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
err_prn.o: ../../include/openssl/crypto.h ../../include/openssl/e_os.h
err_prn.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
diff --git a/crypto/err/err.c b/crypto/err/err.c
index b0ee24c324..2e106a5dea 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 76a8ed1b38..e9eee99591 100644
--- a/crypto/err/err.h
+++ b/crypto/err/err.h
@@ -124,6 +124,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
@@ -153,6 +154,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 :-( */
@@ -202,6 +204,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/rsa/Makefile.ssl b/crypto/rsa/Makefile.ssl
index 6f56d928e0..aa6fdffa97 100644
--- a/crypto/rsa/Makefile.ssl
+++ b/crypto/rsa/Makefile.ssl
@@ -86,11 +86,13 @@ rsa_chk.o: ../../include/openssl/opensslv.h ../../include/openssl/rsa.h
rsa_chk.o: ../../include/openssl/safestack.h ../../include/openssl/stack.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/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/opensslconf.h
-rsa_eay.o: ../../include/openssl/opensslv.h ../../include/openssl/rand.h
-rsa_eay.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
-rsa_eay.o: ../../include/openssl/stack.h ../cryptlib.h
+rsa_eay.o: ../../include/openssl/engine.h ../../include/openssl/err.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: ../cryptlib.h
rsa_err.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
rsa_err.o: ../../include/openssl/err.h ../../include/openssl/opensslconf.h
rsa_err.o: ../../include/openssl/opensslv.h ../../include/openssl/rsa.h
@@ -104,9 +106,11 @@ rsa_gen.o: ../../include/openssl/safestack.h ../../include/openssl/stack.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/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/lhash.h ../../include/openssl/opensslconf.h
+rsa_lib.o: ../../include/openssl/opensslv.h ../../include/openssl/rand.h
rsa_lib.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
rsa_lib.o: ../../include/openssl/stack.h ../cryptlib.h
rsa_none.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
@@ -161,17 +165,18 @@ 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/md2.h
-rsa_sign.o: ../../include/openssl/md5.h ../../include/openssl/mdc2.h
-rsa_sign.o: ../../include/openssl/objects.h ../../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/md2.h ../../include/openssl/md5.h
+rsa_sign.o: ../../include/openssl/mdc2.h ../../include/openssl/objects.h
+rsa_sign.o: ../../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 ../../include/openssl/ripemd.h
-rsa_sign.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
-rsa_sign.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
-rsa_sign.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
-rsa_sign.o: ../cryptlib.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/ripemd.h ../../include/openssl/rsa.h
+rsa_sign.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+rsa_sign.o: ../../include/openssl/stack.h ../../include/openssl/x509.h
+rsa_sign.o: ../../include/openssl/x509_vfy.h ../cryptlib.h
rsa_ssl.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
rsa_ssl.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
rsa_ssl.o: ../../include/openssl/e_os.h ../../include/openssl/e_os2.h
diff --git a/crypto/rsa/rsa.h b/crypto/rsa/rsa.h
index 74033cf607..8bccf73c27 100644
--- a/crypto/rsa/rsa.h
+++ b/crypto/rsa/rsa.h
@@ -111,7 +111,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 *handle;
+#endif
BIGNUM *n;
BIGNUM *e;
BIGNUM *d;
@@ -165,7 +169,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 *handle);
+#endif
int RSA_size(RSA *);
RSA * RSA_generate_key(int bits, unsigned long e,void
(*callback)(int,int,void *),void *cb_arg);
@@ -183,10 +191,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
+RSA_METHOD *RSA_set_method(RSA *rsa, struct engine_st *h);
+#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 b7d2460754..a8992afb6d 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->handle);
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->handle);
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->handle);
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->handle);
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->handle);
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 88d93a46dd..885fb0227f 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->handle);
}
+#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
+RSA_METHOD *RSA_set_method(RSA *rsa, ENGINE *h)
+{
+ ENGINE *mtmp;
+ RSA_METHOD *meth, *old_meth;
+ mtmp = rsa->handle;
+ old_meth = ENGINE_get_RSA(mtmp);
+ if (!ENGINE_init(h))
+ return NULL;
+ if (old_meth->finish) old_meth->finish(rsa);
+ rsa->handle = h;
+ meth = ENGINE_get_RSA(h);
+ if (meth->init) meth->init(rsa);
+ /* SHOULD ERROR CHECK THIS!!! */
+ ENGINE_finish(mtmp);
+ return old_meth;
+}
+#endif
+#if 0
RSA *RSA_new_method(RSA_METHOD *meth)
+#else
+RSA *RSA_new_method(ENGINE *handle)
+#endif
{
+ RSA_METHOD *meth;
RSA *ret;
ret=(RSA *)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 (handle == NULL)
+ {
+ if((ret->handle=ENGINE_get_default_RSA()) == NULL)
+ {
+ Free(ret);
+ return NULL;
+ }
+ }
else
- ret->meth=meth;
+ ret->handle=handle;
+ meth = ENGINE_get_RSA(ret->handle);
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))
{
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->handle);
+ if (meth->finish != NULL)
+ meth->finish(r);
+ ENGINE_finish(r->handle);
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->handle)->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->handle)->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->handle)->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->handle)->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->handle)->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->handle)->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 05bb7fb74a..4a23df1946 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->handle)->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->handle)->rsa_verify(dtype,
+ m, m_len, sigbuf, siglen, rsa);
s=(unsigned char *)Malloc((unsigned int)siglen);
if (s == NULL)
diff --git a/test/Makefile.ssl b/test/Makefile.ssl
index a2db754bd0..480c697a88 100644
--- a/test/Makefile.ssl
+++ b/test/Makefile.ssl
@@ -52,11 +52,12 @@ DSATEST= dsatest
METHTEST= methtest
SSLTEST= ssltest
RSATEST= rsa_test
+ENGINETEST= enginetest
EXE= $(BNTEST) $(IDEATEST) $(MD2TEST) $(MD5TEST) $(HMACTEST) \
$(RC2TEST) $(RC4TEST) $(RC5TEST) \
$(DESTEST) $(SHATEST) $(SHA1TEST) $(MDC2TEST) $(RMDTEST) \
- $(RANDTEST) $(DHTEST) \
+ $(RANDTEST) $(DHTEST) $(ENGINETEST) \
$(BFTEST) $(CASTTEST) $(SSLTEST) $(EXPTEST) $(DSATEST) $(RSATEST)
# $(METHTEST)
@@ -64,12 +65,12 @@ EXE= $(BNTEST) $(IDEATEST) $(MD2TEST) $(MD5TEST) $(HMACTEST) \
OBJ= $(BNTEST).o $(IDEATEST).o $(MD2TEST).o $(MD5TEST).o $(HMACTEST).o \
$(RC2TEST).o $(RC4TEST).o $(RC5TEST).o \
$(DESTEST).o $(SHATEST).o $(SHA1TEST).o $(MDC2TEST).o $(RMDTEST).o \
- $(RANDTEST).o $(DHTEST).o $(CASTTEST).o \
+ $(RANDTEST).o $(DHTEST).o $(ENGINETEST).o $(CASTTEST).o \
$(BFTEST).o $(SSLTEST).o $(DSATEST).o $(EXPTEST).o $(RSATEST).o
SRC= $(BNTEST).c $(IDEATEST).c $(MD2TEST).c $(MD5TEST).c $(HMACTEST).c \
$(RC2TEST).c $(RC4TEST).c $(RC5TEST).c \
$(DESTEST).c $(SHATEST).c $(SHA1TEST).c $(MDC2TEST).c $(RMDTEST).c \
- $(RANDTEST).c $(DHTEST).c $(CASTTEST).c \
+ $(RANDTEST).c $(DHTEST).c $(ENGINETEST).c $(CASTTEST).c \
$(BFTEST).c $(SSLTEST).c $(DSATEST).c $(EXPTEST).c $(RSATEST).c
EXHEADER=
@@ -307,6 +308,9 @@ $(METHTEST): $(METHTEST).o $(DLIBCRYPTO)
$(SSLTEST): $(SSLTEST).o $(DLIBSSL) $(DLIBCRYPTO)
$(CC) -o $(SSLTEST) $(CFLAGS) $(SSLTEST).o $(PEX_LIBS) $(LIBSSL) $(LIBCRYPTO) $(EX_LIBS)
+$(ENGINETEST): $(ENGINETEST).o $(DLIBCRYPTO)
+ $(CC) -o $(ENGINETEST) $(CFLAGS) $(ENGINETEST).o $(PEX_LIBS) $(LIBCRYPTO) $(EX_LIBS)
+
# DO NOT DELETE THIS LINE -- make depend depends on it.
bftest.o: ../include/openssl/blowfish.h
@@ -340,6 +344,12 @@ dsatest.o: ../include/openssl/dsa.h ../include/openssl/err.h
dsatest.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
dsatest.o: ../include/openssl/rand.h ../include/openssl/safestack.h
dsatest.o: ../include/openssl/stack.h
+enginetest.o: ../include/openssl/bn.h ../include/openssl/crypto.h
+enginetest.o: ../include/openssl/dh.h ../include/openssl/dsa.h
+enginetest.o: ../include/openssl/engine.h ../include/openssl/err.h
+enginetest.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+enginetest.o: ../include/openssl/rand.h ../include/openssl/rsa.h
+enginetest.o: ../include/openssl/safestack.h ../include/openssl/stack.h
exptest.o: ../include/openssl/bio.h ../include/openssl/bn.h
exptest.o: ../include/openssl/crypto.h ../include/openssl/err.h
exptest.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
diff --git a/util/mkdef.pl b/util/mkdef.pl
index 9f5fba9146..91c194820a 100755
--- a/util/mkdef.pl
+++ b/util/mkdef.pl
@@ -102,6 +102,8 @@ $crypto.=" crypto/dsa/dsa.h" unless $no_dsa;
$crypto.=" crypto/dh/dh.h" unless $no_dh;
$crypto.=" crypto/hmac/hmac.h" unless $no_hmac;
+$crypto.=" crypto/dso/dso.h";
+$crypto.=" crypto/engine/engine.h";
$crypto.=" crypto/stack/stack.h";
$crypto.=" crypto/buffer/buffer.h";
$crypto.=" crypto/bio/bio.h";
diff --git a/util/mkfiles.pl b/util/mkfiles.pl
index 924a85f70e..fca47601bd 100755
--- a/util/mkfiles.pl
+++ b/util/mkfiles.pl
@@ -44,6 +44,7 @@ my @dirs = (
"crypto/pkcs7",
"crypto/pkcs12",
"crypto/comp",
+"crypto/engine",
"ssl",
"rsaref",
"apps",