summaryrefslogtreecommitdiff
path: root/crypto/engine
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/engine')
-rw-r--r--crypto/engine/.cvsignore2
-rw-r--r--crypto/engine/Makefile.ssl292
-rw-r--r--crypto/engine/eng_aesni.c400
-rw-r--r--crypto/engine/eng_all.c17
-rw-r--r--crypto/engine/eng_cnf.c15
-rw-r--r--crypto/engine/eng_cryptodev.c425
-rw-r--r--crypto/engine/eng_ctrl.c13
-rw-r--r--crypto/engine/eng_dyn.c18
-rw-r--r--crypto/engine/eng_err.c172
-rw-r--r--crypto/engine/eng_fat.c14
-rw-r--r--crypto/engine/eng_init.c2
-rw-r--r--crypto/engine/eng_int.h14
-rw-r--r--crypto/engine/eng_lib.c5
-rw-r--r--crypto/engine/eng_list.c25
-rw-r--r--crypto/engine/eng_openssl.c10
-rw-r--r--crypto/engine/eng_padlock.c1091
-rw-r--r--crypto/engine/eng_pkey.c42
-rw-r--r--crypto/engine/eng_table.c81
-rw-r--r--crypto/engine/engine.h82
-rw-r--r--crypto/engine/enginetest.c6
-rw-r--r--crypto/engine/tb_asnmth.c246
-rw-r--r--crypto/engine/tb_dsa.c2
-rw-r--r--crypto/engine/tb_ecdh.c2
-rw-r--r--crypto/engine/tb_ecdsa.c2
-rw-r--r--crypto/engine/tb_pkmeth.c167
25 files changed, 1508 insertions, 1637 deletions
diff --git a/crypto/engine/.cvsignore b/crypto/engine/.cvsignore
index c6d03a9dbc..439e6d3eb6 100644
--- a/crypto/engine/.cvsignore
+++ b/crypto/engine/.cvsignore
@@ -1,2 +1,4 @@
lib
Makefile.save
+*.flc
+semantic.cache
diff --git a/crypto/engine/Makefile.ssl b/crypto/engine/Makefile.ssl
deleted file mode 100644
index f75297fd0c..0000000000
--- a/crypto/engine/Makefile.ssl
+++ /dev/null
@@ -1,292 +0,0 @@
-#
-# OpenSSL/crypto/engine/Makefile
-#
-
-DIR= engine
-TOP= ../..
-CC= cc
-INCLUDES= -I.. -I$(TOP) -I../../include
-CFLAG=-g
-INSTALL_PREFIX=
-OPENSSLDIR= /usr/local/ssl
-INSTALLTOP=/usr/local/ssl
-MAKE= make -f Makefile.ssl
-MAKEDEPPROG= makedepend
-MAKEDEPEND= $(TOP)/util/domd $(TOP) -MD $(MAKEDEPPROG)
-MAKEFILE= Makefile.ssl
-AR= ar r
-
-CFLAGS= $(INCLUDES) $(CFLAG)
-
-GENERAL=Makefile
-TEST= enginetest.c
-APPS=
-
-LIB=$(TOP)/libcrypto.a
-LIBSRC= eng_err.c eng_lib.c eng_list.c eng_init.c eng_ctrl.c \
- eng_table.c eng_pkey.c eng_fat.c eng_all.c \
- tb_rsa.c tb_dsa.c tb_ecdsa.c tb_dh.c tb_ecdh.c tb_rand.c tb_store.c \
- tb_cipher.c tb_digest.c \
- eng_openssl.c eng_cnf.c eng_dyn.c eng_cryptodev.c eng_padlock.c
-LIBOBJ= eng_err.o eng_lib.o eng_list.o eng_init.o eng_ctrl.o \
- eng_table.o eng_pkey.o eng_fat.o eng_all.o \
- tb_rsa.o tb_dsa.o tb_ecdsa.o tb_dh.o tb_ecdh.o tb_rand.o tb_store.o \
- tb_cipher.o tb_digest.o \
- eng_openssl.o eng_cnf.o eng_dyn.o eng_cryptodev.o eng_padlock.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) || echo Never mind.
- @touch lib
-
-files:
- $(PERL) $(TOP)/util/files.pl Makefile.ssl >> $(TOP)/MINFO
-
-links:
- @sh $(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:
- @headerlist="$(EXHEADER)"; for i in $$headerlist ; \
- 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) -- $(CFLAG) $(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.
-
-eng_all.o: ../../e_os.h ../../include/openssl/bio.h
-eng_all.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-eng_all.o: ../../include/openssl/e_os2.h ../../include/openssl/engine.h
-eng_all.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
-eng_all.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-eng_all.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
-eng_all.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-eng_all.o: ../cryptlib.h eng_all.c eng_int.h
-eng_cnf.o: ../../e_os.h ../../include/openssl/bio.h
-eng_cnf.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h
-eng_cnf.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
-eng_cnf.o: ../../include/openssl/engine.h ../../include/openssl/err.h
-eng_cnf.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
-eng_cnf.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-eng_cnf.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-eng_cnf.o: ../../include/openssl/symhacks.h ../cryptlib.h eng_cnf.c eng_int.h
-eng_cryptodev.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
-eng_cryptodev.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
-eng_cryptodev.o: ../../include/openssl/e_os2.h ../../include/openssl/engine.h
-eng_cryptodev.o: ../../include/openssl/evp.h ../../include/openssl/obj_mac.h
-eng_cryptodev.o: ../../include/openssl/objects.h
-eng_cryptodev.o: ../../include/openssl/opensslconf.h
-eng_cryptodev.o: ../../include/openssl/opensslv.h
-eng_cryptodev.o: ../../include/openssl/ossl_typ.h
-eng_cryptodev.o: ../../include/openssl/safestack.h
-eng_cryptodev.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-eng_cryptodev.o: eng_cryptodev.c
-eng_ctrl.o: ../../e_os.h ../../include/openssl/bio.h
-eng_ctrl.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-eng_ctrl.o: ../../include/openssl/e_os2.h ../../include/openssl/engine.h
-eng_ctrl.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
-eng_ctrl.o: ../../include/openssl/opensslconf.h
-eng_ctrl.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-eng_ctrl.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-eng_ctrl.o: ../../include/openssl/symhacks.h ../cryptlib.h eng_ctrl.c eng_int.h
-eng_dyn.o: ../../e_os.h ../../include/openssl/bio.h
-eng_dyn.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-eng_dyn.o: ../../include/openssl/dso.h ../../include/openssl/e_os2.h
-eng_dyn.o: ../../include/openssl/engine.h ../../include/openssl/err.h
-eng_dyn.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
-eng_dyn.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-eng_dyn.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-eng_dyn.o: ../../include/openssl/symhacks.h ../cryptlib.h eng_dyn.c eng_int.h
-eng_err.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h
-eng_err.o: ../../include/openssl/e_os2.h ../../include/openssl/engine.h
-eng_err.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
-eng_err.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-eng_err.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
-eng_err.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-eng_err.o: eng_err.c
-eng_fat.o: ../../e_os.h ../../include/openssl/bio.h
-eng_fat.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h
-eng_fat.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
-eng_fat.o: ../../include/openssl/engine.h ../../include/openssl/err.h
-eng_fat.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
-eng_fat.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-eng_fat.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-eng_fat.o: ../../include/openssl/symhacks.h ../cryptlib.h eng_fat.c eng_int.h
-eng_init.o: ../../e_os.h ../../include/openssl/bio.h
-eng_init.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-eng_init.o: ../../include/openssl/e_os2.h ../../include/openssl/engine.h
-eng_init.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
-eng_init.o: ../../include/openssl/opensslconf.h
-eng_init.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-eng_init.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-eng_init.o: ../../include/openssl/symhacks.h ../cryptlib.h eng_init.c eng_int.h
-eng_lib.o: ../../e_os.h ../../include/openssl/bio.h
-eng_lib.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-eng_lib.o: ../../include/openssl/e_os2.h ../../include/openssl/engine.h
-eng_lib.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
-eng_lib.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-eng_lib.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h
-eng_lib.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-eng_lib.o: ../../include/openssl/symhacks.h ../cryptlib.h eng_int.h eng_lib.c
-eng_list.o: ../../e_os.h ../../include/openssl/bio.h
-eng_list.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-eng_list.o: ../../include/openssl/e_os2.h ../../include/openssl/engine.h
-eng_list.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
-eng_list.o: ../../include/openssl/opensslconf.h
-eng_list.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-eng_list.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-eng_list.o: ../../include/openssl/symhacks.h ../cryptlib.h eng_int.h eng_list.c
-eng_openssl.o: ../../e_os.h ../../include/openssl/asn1.h
-eng_openssl.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
-eng_openssl.o: ../../include/openssl/crypto.h ../../include/openssl/dh.h
-eng_openssl.o: ../../include/openssl/dsa.h ../../include/openssl/dso.h
-eng_openssl.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
-eng_openssl.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
-eng_openssl.o: ../../include/openssl/engine.h ../../include/openssl/err.h
-eng_openssl.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
-eng_openssl.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-eng_openssl.o: ../../include/openssl/opensslconf.h
-eng_openssl.o: ../../include/openssl/opensslv.h
-eng_openssl.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pem.h
-eng_openssl.o: ../../include/openssl/pem2.h ../../include/openssl/pkcs7.h
-eng_openssl.o: ../../include/openssl/rand.h ../../include/openssl/rc4.h
-eng_openssl.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
-eng_openssl.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
-eng_openssl.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-eng_openssl.o: ../../include/openssl/x509_vfy.h ../cryptlib.h eng_openssl.c
-eng_padlock.o: ../../include/openssl/aes.h ../../include/openssl/asn1.h
-eng_padlock.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h
-eng_padlock.o: ../../include/openssl/dso.h ../../include/openssl/e_os2.h
-eng_padlock.o: ../../include/openssl/engine.h ../../include/openssl/evp.h
-eng_padlock.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-eng_padlock.o: ../../include/openssl/opensslconf.h
-eng_padlock.o: ../../include/openssl/opensslv.h
-eng_padlock.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h
-eng_padlock.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-eng_padlock.o: ../../include/openssl/symhacks.h eng_padlock.c
-eng_pkey.o: ../../e_os.h ../../include/openssl/bio.h
-eng_pkey.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-eng_pkey.o: ../../include/openssl/e_os2.h ../../include/openssl/engine.h
-eng_pkey.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
-eng_pkey.o: ../../include/openssl/opensslconf.h
-eng_pkey.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-eng_pkey.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-eng_pkey.o: ../../include/openssl/symhacks.h ../cryptlib.h eng_int.h eng_pkey.c
-eng_table.o: ../../e_os.h ../../include/openssl/asn1.h
-eng_table.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
-eng_table.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
-eng_table.o: ../../include/openssl/engine.h ../../include/openssl/err.h
-eng_table.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
-eng_table.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-eng_table.o: ../../include/openssl/opensslconf.h
-eng_table.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-eng_table.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-eng_table.o: ../../include/openssl/symhacks.h ../cryptlib.h eng_int.h
-eng_table.o: eng_table.c
-tb_cipher.o: ../../e_os.h ../../include/openssl/bio.h
-tb_cipher.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-tb_cipher.o: ../../include/openssl/e_os2.h ../../include/openssl/engine.h
-tb_cipher.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
-tb_cipher.o: ../../include/openssl/opensslconf.h
-tb_cipher.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-tb_cipher.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-tb_cipher.o: ../../include/openssl/symhacks.h ../cryptlib.h eng_int.h
-tb_cipher.o: tb_cipher.c
-tb_dh.o: ../../e_os.h ../../include/openssl/bio.h
-tb_dh.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-tb_dh.o: ../../include/openssl/e_os2.h ../../include/openssl/engine.h
-tb_dh.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
-tb_dh.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-tb_dh.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
-tb_dh.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-tb_dh.o: ../cryptlib.h eng_int.h tb_dh.c
-tb_digest.o: ../../e_os.h ../../include/openssl/bio.h
-tb_digest.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-tb_digest.o: ../../include/openssl/e_os2.h ../../include/openssl/engine.h
-tb_digest.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
-tb_digest.o: ../../include/openssl/opensslconf.h
-tb_digest.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-tb_digest.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-tb_digest.o: ../../include/openssl/symhacks.h ../cryptlib.h eng_int.h
-tb_digest.o: tb_digest.c
-tb_dsa.o: ../../e_os.h ../../include/openssl/bio.h
-tb_dsa.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-tb_dsa.o: ../../include/openssl/e_os2.h ../../include/openssl/engine.h
-tb_dsa.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
-tb_dsa.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-tb_dsa.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
-tb_dsa.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-tb_dsa.o: ../cryptlib.h eng_int.h tb_dsa.c
-tb_ecdh.o: ../../e_os.h ../../include/openssl/bio.h
-tb_ecdh.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-tb_ecdh.o: ../../include/openssl/e_os2.h ../../include/openssl/engine.h
-tb_ecdh.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
-tb_ecdh.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-tb_ecdh.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
-tb_ecdh.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-tb_ecdh.o: ../cryptlib.h eng_int.h tb_ecdh.c
-tb_ecdsa.o: ../../e_os.h ../../include/openssl/bio.h
-tb_ecdsa.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-tb_ecdsa.o: ../../include/openssl/e_os2.h ../../include/openssl/engine.h
-tb_ecdsa.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
-tb_ecdsa.o: ../../include/openssl/opensslconf.h
-tb_ecdsa.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-tb_ecdsa.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-tb_ecdsa.o: ../../include/openssl/symhacks.h ../cryptlib.h eng_int.h tb_ecdsa.c
-tb_rand.o: ../../e_os.h ../../include/openssl/bio.h
-tb_rand.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-tb_rand.o: ../../include/openssl/e_os2.h ../../include/openssl/engine.h
-tb_rand.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
-tb_rand.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-tb_rand.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
-tb_rand.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-tb_rand.o: ../cryptlib.h eng_int.h tb_rand.c
-tb_rsa.o: ../../e_os.h ../../include/openssl/bio.h
-tb_rsa.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-tb_rsa.o: ../../include/openssl/e_os2.h ../../include/openssl/engine.h
-tb_rsa.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
-tb_rsa.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-tb_rsa.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
-tb_rsa.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-tb_rsa.o: ../cryptlib.h eng_int.h tb_rsa.c
-tb_store.o: ../../e_os.h ../../include/openssl/bio.h
-tb_store.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-tb_store.o: ../../include/openssl/e_os2.h ../../include/openssl/engine.h
-tb_store.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
-tb_store.o: ../../include/openssl/opensslconf.h
-tb_store.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-tb_store.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-tb_store.o: ../../include/openssl/symhacks.h ../cryptlib.h eng_int.h tb_store.c
diff --git a/crypto/engine/eng_aesni.c b/crypto/engine/eng_aesni.c
new file mode 100644
index 0000000000..2a997cae36
--- /dev/null
+++ b/crypto/engine/eng_aesni.c
@@ -0,0 +1,400 @@
+/*
+ * Support for Intel AES-NI intruction set
+ * Author: Huang Ying <ying.huang@intel.com>
+ *
+ * Intel AES-NI is a new set of Single Instruction Multiple Data
+ * (SIMD) instructions that are going to be introduced in the next
+ * generation of Intel processor, as of 2009. These instructions
+ * enable fast and secure data encryption and decryption, using the
+ * Advanced Encryption Standard (AES), defined by FIPS Publication
+ * number 197. The architecture introduces six instructions that
+ * offer full hardware support for AES. Four of them support high
+ * performance data encryption and decryption, and the other two
+ * instructions support the AES key expansion procedure.
+ *
+ * The white paper can be downloaded from:
+ * http://softwarecommunity.intel.com/isn/downloads/intelavx/AES-Instructions-Set_WP.pdf
+ *
+ * This file is based on engines/e_padlock.c
+ */
+
+/* ====================================================================
+ * Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * 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/opensslconf.h>
+
+#if !defined(OPENSSL_NO_HW) && !defined(OPENSSL_NO_HW_AES_NI) && !defined(OPENSSL_NO_AES)
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/dso.h>
+#include <openssl/engine.h>
+#include <openssl/evp.h>
+#include <openssl/aes.h>
+#include <openssl/err.h>
+#include <openssl/modes.h>
+
+/* AES-NI is available *ONLY* on some x86 CPUs. Not only that it
+ doesn't exist elsewhere, but it even can't be compiled on other
+ platforms! */
+#undef COMPILE_HW_AESNI
+#if (defined(__x86_64) || defined(__x86_64__) || \
+ defined(_M_AMD64) || defined(_M_X64) || \
+ defined(OPENSSL_IA32_SSE2)) && !defined(OPENSSL_NO_ASM)
+#define COMPILE_HW_AESNI
+static ENGINE *ENGINE_aesni (void);
+#endif
+
+void ENGINE_load_aesni (void)
+{
+/* On non-x86 CPUs it just returns. */
+#ifdef COMPILE_HW_AESNI
+ ENGINE *toadd = ENGINE_aesni();
+ if (!toadd)
+ return;
+ ENGINE_add (toadd);
+ ENGINE_free (toadd);
+ ERR_clear_error ();
+#endif
+}
+
+#ifdef COMPILE_HW_AESNI
+int aesni_set_encrypt_key(const unsigned char *userKey, int bits,
+ AES_KEY *key);
+int aesni_set_decrypt_key(const unsigned char *userKey, int bits,
+ AES_KEY *key);
+
+void aesni_encrypt(const unsigned char *in, unsigned char *out,
+ const AES_KEY *key);
+void aesni_decrypt(const unsigned char *in, unsigned char *out,
+ const AES_KEY *key);
+
+void aesni_ecb_encrypt(const unsigned char *in,
+ unsigned char *out,
+ size_t length,
+ const AES_KEY *key,
+ int enc);
+void aesni_cbc_encrypt(const unsigned char *in,
+ unsigned char *out,
+ size_t length,
+ const AES_KEY *key,
+ unsigned char *ivec, int enc);
+
+/* Function for ENGINE detection and control */
+static int aesni_init(ENGINE *e);
+
+/* Cipher Stuff */
+static int aesni_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
+ const int **nids, int nid);
+
+#define AESNI_MIN_ALIGN 16
+#define AESNI_ALIGN(x) \
+ ((void *)(((unsigned long)(x)+AESNI_MIN_ALIGN-1)&~(AESNI_MIN_ALIGN-1)))
+
+/* Engine names */
+static const char aesni_id[] = "aesni",
+ aesni_name[] = "Intel AES-NI engine",
+ no_aesni_name[] = "Intel AES-NI engine (no-aesni)";
+
+/* ===== Engine "management" functions ===== */
+
+/* Prepare the ENGINE structure for registration */
+static int
+aesni_bind_helper(ENGINE *e)
+{
+ int engage = (OPENSSL_ia32cap_P[1] & (1 << (57-32))) != 0;
+
+ /* Register everything or return with an error */
+ if (!ENGINE_set_id(e, aesni_id) ||
+ !ENGINE_set_name(e, engage ? aesni_name : no_aesni_name) ||
+
+ !ENGINE_set_init_function(e, aesni_init) ||
+ (engage && !ENGINE_set_ciphers (e, aesni_ciphers))
+ )
+ return 0;
+
+ /* Everything looks good */
+ return 1;
+}
+
+/* Constructor */
+static ENGINE *
+ENGINE_aesni(void)
+{
+ ENGINE *eng = ENGINE_new();
+
+ if (!eng) {
+ return NULL;
+ }
+
+ if (!aesni_bind_helper(eng)) {
+ ENGINE_free(eng);
+ return NULL;
+ }
+
+ return eng;
+}
+
+/* Check availability of the engine */
+static int
+aesni_init(ENGINE *e)
+{
+ return 1;
+}
+
+#if defined(NID_aes_128_cfb128) && ! defined (NID_aes_128_cfb)
+#define NID_aes_128_cfb NID_aes_128_cfb128
+#endif
+
+#if defined(NID_aes_128_ofb128) && ! defined (NID_aes_128_ofb)
+#define NID_aes_128_ofb NID_aes_128_ofb128
+#endif
+
+#if defined(NID_aes_192_cfb128) && ! defined (NID_aes_192_cfb)
+#define NID_aes_192_cfb NID_aes_192_cfb128
+#endif
+
+#if defined(NID_aes_192_ofb128) && ! defined (NID_aes_192_ofb)
+#define NID_aes_192_ofb NID_aes_192_ofb128
+#endif
+
+#if defined(NID_aes_256_cfb128) && ! defined (NID_aes_256_cfb)
+#define NID_aes_256_cfb NID_aes_256_cfb128
+#endif
+
+#if defined(NID_aes_256_ofb128) && ! defined (NID_aes_256_ofb)
+#define NID_aes_256_ofb NID_aes_256_ofb128
+#endif
+
+/* List of supported ciphers. */
+static int aesni_cipher_nids[] = {
+ NID_aes_128_ecb,
+ NID_aes_128_cbc,
+ NID_aes_128_cfb,
+ NID_aes_128_ofb,
+
+ NID_aes_192_ecb,
+ NID_aes_192_cbc,
+ NID_aes_192_cfb,
+ NID_aes_192_ofb,
+
+ NID_aes_256_ecb,
+ NID_aes_256_cbc,
+ NID_aes_256_cfb,
+ NID_aes_256_ofb,
+};
+static int aesni_cipher_nids_num =
+ (sizeof(aesni_cipher_nids)/sizeof(aesni_cipher_nids[0]));
+
+typedef struct
+{
+ AES_KEY ks;
+ unsigned int _pad1[3];
+} AESNI_KEY;
+
+static int
+aesni_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *user_key,
+ const unsigned char *iv, int enc)
+{
+ int ret;
+ AES_KEY *key = AESNI_ALIGN(ctx->cipher_data);
+
+ if ((ctx->cipher->flags & EVP_CIPH_MODE) == EVP_CIPH_CFB_MODE
+ || (ctx->cipher->flags & EVP_CIPH_MODE) == EVP_CIPH_OFB_MODE
+ || enc)
+ ret=aesni_set_encrypt_key(user_key, ctx->key_len * 8, key);
+ else
+ ret=aesni_set_decrypt_key(user_key, ctx->key_len * 8, key);
+
+ if(ret < 0) {
+ EVPerr(EVP_F_AESNI_INIT_KEY,EVP_R_AES_KEY_SETUP_FAILED);
+ return 0;
+ }
+
+ return 1;
+}
+
+static int aesni_cipher_ecb(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t inl)
+{ AES_KEY *key = AESNI_ALIGN(ctx->cipher_data);
+ aesni_ecb_encrypt(in, out, inl, key, ctx->encrypt);
+ return 1;
+}
+static int aesni_cipher_cbc(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t inl)
+{ AES_KEY *key = AESNI_ALIGN(ctx->cipher_data);
+ aesni_cbc_encrypt(in, out, inl, key,
+ ctx->iv, ctx->encrypt);
+ return 1;
+}
+static int aesni_cipher_cfb(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t inl)
+{ AES_KEY *key = AESNI_ALIGN(ctx->cipher_data);
+ CRYPTO_cfb128_encrypt(in, out, inl, key, ctx->iv,
+ &ctx->num, ctx->encrypt,
+ (block128_f)aesni_encrypt);
+ return 1;
+}
+static int aesni_cipher_ofb(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t inl)
+{ AES_KEY *key = AESNI_ALIGN(ctx->cipher_data);
+ CRYPTO_ofb128_encrypt(in, out, inl, key, ctx->iv,
+ &ctx->num, (block128_f)aesni_encrypt);
+ return 1;
+}
+
+#define AES_BLOCK_SIZE 16
+
+#define EVP_CIPHER_block_size_ECB AES_BLOCK_SIZE
+#define EVP_CIPHER_block_size_CBC AES_BLOCK_SIZE
+#define EVP_CIPHER_block_size_OFB 1
+#define EVP_CIPHER_block_size_CFB 1
+
+/* Declaring so many ciphers by hand would be a pain.
+ Instead introduce a bit of preprocessor magic :-) */
+#define DECLARE_AES_EVP(ksize,lmode,umode) \
+static const EVP_CIPHER aesni_##ksize##_##lmode = { \
+ NID_aes_##ksize##_##lmode, \
+ EVP_CIPHER_block_size_##umode, \
+ ksize / 8, \
+ AES_BLOCK_SIZE, \
+ 0 | EVP_CIPH_##umode##_MODE, \
+ aesni_init_key, \
+ aesni_cipher_##lmode, \
+ NULL, \
+ sizeof(AESNI_KEY), \
+ EVP_CIPHER_set_asn1_iv, \
+ EVP_CIPHER_get_asn1_iv, \
+ NULL, \
+ NULL \
+}
+
+DECLARE_AES_EVP(128,ecb,ECB);
+DECLARE_AES_EVP(128,cbc,CBC);
+DECLARE_AES_EVP(128,cfb,CFB);
+DECLARE_AES_EVP(128,ofb,OFB);
+
+DECLARE_AES_EVP(192,ecb,ECB);
+DECLARE_AES_EVP(192,cbc,CBC);
+DECLARE_AES_EVP(192,cfb,CFB);
+DECLARE_AES_EVP(192,ofb,OFB);
+
+DECLARE_AES_EVP(256,ecb,ECB);
+DECLARE_AES_EVP(256,cbc,CBC);
+DECLARE_AES_EVP(256,cfb,CFB);
+DECLARE_AES_EVP(256,ofb,OFB);
+
+static int
+aesni_ciphers (ENGINE *e, const EVP_CIPHER **cipher,
+ const int **nids, int nid)
+{
+ /* No specific cipher => return a list of supported nids ... */
+ if (!cipher) {
+ *nids = aesni_cipher_nids;
+ return aesni_cipher_nids_num;
+ }
+
+ /* ... or the requested "cipher" otherwise */
+ switch (nid) {
+ case NID_aes_128_ecb:
+ *cipher = &aesni_128_ecb;
+ break;
+ case NID_aes_128_cbc:
+ *cipher = &aesni_128_cbc;
+ break;
+ case NID_aes_128_cfb:
+ *cipher = &aesni_128_cfb;
+ break;
+ case NID_aes_128_ofb:
+ *cipher = &aesni_128_ofb;
+ break;
+
+ case NID_aes_192_ecb:
+ *cipher = &aesni_192_ecb;
+ break;
+ case NID_aes_192_cbc:
+ *cipher = &aesni_192_cbc;
+ break;
+ case NID_aes_192_cfb:
+ *cipher = &aesni_192_cfb;
+ break;
+ case NID_aes_192_ofb:
+ *cipher = &aesni_192_ofb;
+ break;
+
+ case NID_aes_256_ecb:
+ *cipher = &aesni_256_ecb;
+ break;
+ case NID_aes_256_cbc:
+ *cipher = &aesni_256_cbc;
+ break;
+ case NID_aes_256_cfb:
+ *cipher = &aesni_256_cfb;
+ break;
+ case NID_aes_256_ofb:
+ *cipher = &aesni_256_ofb;
+ break;
+
+ default:
+ /* Sorry, we don't support this NID */
+ *cipher = NULL;
+ return 0;
+ }
+
+ return 1;
+}
+
+#endif /* COMPILE_HW_AESNI */
+#endif /* !defined(OPENSSL_NO_HW) && !defined(OPENSSL_NO_HW_AESNI) && !defined(OPENSSL_NO_AES) */
diff --git a/crypto/engine/eng_all.c b/crypto/engine/eng_all.c
index 93c54d0f6f..623485d3d2 100644
--- a/crypto/engine/eng_all.c
+++ b/crypto/engine/eng_all.c
@@ -61,13 +61,19 @@
void ENGINE_load_builtin_engines(void)
{
+#if 0
/* There's no longer any need for an "openssl" ENGINE unless, one day,
* it is the *only* way for standard builtin implementations to be be
* accessed (ie. it would be possible to statically link binaries with
* *no* builtin implementations). */
-#if 0
ENGINE_load_openssl();
#endif
+#if defined(__OpenBSD__) || defined(__FreeBSD__)
+ ENGINE_load_cryptodev();
+#endif
+#if !defined(OPENSSL_NO_HW) && !defined(OPENSSL_NO_HW_AESNI)
+ ENGINE_load_aesni();
+#endif
ENGINE_load_dynamic();
#ifndef OPENSSL_NO_STATIC_ENGINE
#ifndef OPENSSL_NO_HW
@@ -99,12 +105,15 @@ void ENGINE_load_builtin_engines(void)
ENGINE_load_padlock();
#endif
#endif
-#if defined(__OpenBSD__) || defined(__FreeBSD__)
- ENGINE_load_cryptodev();
+#ifndef OPENSSL_NO_GOST
+ ENGINE_load_gost();
#endif
-#if defined(OPENSSL_USE_GMP) && !defined(OPENSSL_NO_HW_GMP)
+#ifndef OPENSSL_NO_GMP
ENGINE_load_gmp();
#endif
+#if defined(OPENSSL_SYS_WIN32) && !defined(OPENSSL_NO_CAPIENG)
+ ENGINE_load_capi();
+#endif
#endif
}
diff --git a/crypto/engine/eng_cnf.c b/crypto/engine/eng_cnf.c
index 8567f26675..08066cea59 100644
--- a/crypto/engine/eng_cnf.c
+++ b/crypto/engine/eng_cnf.c
@@ -1,5 +1,5 @@
/* eng_cnf.c */
-/* Written by Stephen Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Stephen Henson (steve@openssl.org) for the OpenSSL
* project 2001.
*/
/* ====================================================================
@@ -98,6 +98,8 @@ static int int_engine_configure(char *name, char *value, const CONF *cnf)
CONF_VALUE *ecmd;
char *ctrlname, *ctrlvalue;
ENGINE *e = NULL;
+ int soft = 0;
+
name = skip_dot(name);
#ifdef ENGINE_CONF_DEBUG
fprintf(stderr, "Configuring engine %s\n", name);
@@ -125,6 +127,8 @@ static int int_engine_configure(char *name, char *value, const CONF *cnf)
/* Override engine name to use */
if (!strcmp(ctrlname, "engine_id"))
name = ctrlvalue;
+ else if (!strcmp(ctrlname, "soft_load"))
+ soft = 1;
/* Load a dynamic ENGINE */
else if (!strcmp(ctrlname, "dynamic_path"))
{
@@ -147,6 +151,11 @@ static int int_engine_configure(char *name, char *value, const CONF *cnf)
if (!e)
{
e = ENGINE_by_id(name);
+ if (!e && soft)
+ {
+ ERR_clear_error();
+ return 1;
+ }
if (!e)
return 0;
}
@@ -155,7 +164,7 @@ static int int_engine_configure(char *name, char *value, const CONF *cnf)
*/
if (!strcmp(ctrlvalue, "EMPTY"))
ctrlvalue = NULL;
- else if (!strcmp(ctrlname, "init"))
+ if (!strcmp(ctrlname, "init"))
{
if (!NCONF_get_number_e(cnf, value, "init", &do_init))
goto err;
@@ -207,7 +216,7 @@ static int int_engine_module_init(CONF_IMODULE *md, const CONF *cnf)
if (!elist)
{
- ENGINEerr(ENGINE_F_ENGINE_MODULE_INIT, ENGINE_R_ENGINES_SECTION_ERROR);
+ ENGINEerr(ENGINE_F_INT_ENGINE_MODULE_INIT, ENGINE_R_ENGINES_SECTION_ERROR);
return 0;
}
diff --git a/crypto/engine/eng_cryptodev.c b/crypto/engine/eng_cryptodev.c
index ab38cd52f0..d07068f13f 100644
--- a/crypto/engine/eng_cryptodev.c
+++ b/crypto/engine/eng_cryptodev.c
@@ -32,7 +32,7 @@
#include <openssl/bn.h>
#if (defined(__unix__) || defined(unix)) && !defined(USG) && \
- (defined(OpenBSD) || defined(__FreeBSD_version))
+ (defined(OpenBSD) || defined(__FreeBSD__))
#include <sys/param.h>
# if (OpenBSD >= 200112) || ((__FreeBSD_version >= 470101 && __FreeBSD_version < 500000) || __FreeBSD_version >= 500041)
# define HAVE_CRYPTODEV
@@ -68,6 +68,16 @@ ENGINE_load_cryptodev(void)
struct dev_crypto_state {
struct session_op d_sess;
int d_fd;
+
+#ifdef USE_CRYPTODEV_DIGESTS
+ char dummy_mac_key[HASH_MAX_LEN];
+
+ unsigned char digest_res[HASH_MAX_LEN];
+ char *mac_data;
+ int mac_len;
+
+ int copy;
+#endif
};
static u_int32_t cryptodev_asymfeat = 0;
@@ -75,15 +85,12 @@ static u_int32_t cryptodev_asymfeat = 0;
static int get_asym_dev_crypto(void);
static int open_dev_crypto(void);
static int get_dev_crypto(void);
-static int cryptodev_max_iv(int cipher);
-static int cryptodev_key_length_valid(int cipher, int len);
-static int cipher_nid_to_cryptodev(int nid);
static int get_cryptodev_ciphers(const int **cnids);
-static int get_cryptodev_digests(const int **cnids);
+/*static int get_cryptodev_digests(const int **cnids);*/
static int cryptodev_usable_ciphers(const int **nids);
static int cryptodev_usable_digests(const int **nids);
static int cryptodev_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
- const unsigned char *in, unsigned int inl);
+ const unsigned char *in, size_t inl);
static int cryptodev_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
const unsigned char *iv, int enc);
static int cryptodev_cleanup(EVP_CIPHER_CTX *ctx);
@@ -100,7 +107,7 @@ static int cryptodev_asym(struct crypt_kop *kop, int rlen, BIGNUM *r,
static int cryptodev_bn_mod_exp(BIGNUM *r, const BIGNUM *a,
const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
static int cryptodev_rsa_nocrt_mod_exp(BIGNUM *r0, const BIGNUM *I,
- RSA *rsa);
+ RSA *rsa, BN_CTX *ctx);
static int cryptodev_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx);
static int cryptodev_dsa_bn_mod_exp(DSA *dsa, BIGNUM *r, BIGNUM *a,
const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
@@ -117,7 +124,7 @@ static int cryptodev_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a,
static int cryptodev_dh_compute_key(unsigned char *key,
const BIGNUM *pub_key, DH *dh);
static int cryptodev_ctrl(ENGINE *e, int cmd, long i, void *p,
- void (*f)());
+ void (*f)(void));
void ENGINE_load_cryptodev(void);
static const ENGINE_CMD_DEFN cryptodev_defns[] = {
@@ -130,27 +137,34 @@ static struct {
int ivmax;
int keylen;
} ciphers[] = {
+ { CRYPTO_ARC4, NID_rc4, 0, 16, },
{ CRYPTO_DES_CBC, NID_des_cbc, 8, 8, },
{ CRYPTO_3DES_CBC, NID_des_ede3_cbc, 8, 24, },
{ CRYPTO_AES_CBC, NID_aes_128_cbc, 16, 16, },
+ { CRYPTO_AES_CBC, NID_aes_192_cbc, 16, 24, },
+ { CRYPTO_AES_CBC, NID_aes_256_cbc, 16, 32, },
{ CRYPTO_BLF_CBC, NID_bf_cbc, 8, 16, },
{ CRYPTO_CAST_CBC, NID_cast5_cbc, 8, 16, },
{ CRYPTO_SKIPJACK_CBC, NID_undef, 0, 0, },
{ 0, NID_undef, 0, 0, },
};
+#if 0 /* not (yet?) used */
static struct {
int id;
int nid;
+ int keylen;
} digests[] = {
- { CRYPTO_SHA1_HMAC, NID_hmacWithSHA1, },
- { CRYPTO_RIPEMD160_HMAC, NID_ripemd160, },
- { CRYPTO_MD5_KPDK, NID_undef, },
- { CRYPTO_SHA1_KPDK, NID_undef, },
- { CRYPTO_MD5, NID_md5, },
- { CRYPTO_SHA1, NID_undef, },
- { 0, NID_undef, },
+ { CRYPTO_MD5_HMAC, NID_hmacWithMD5, 16},
+ { CRYPTO_SHA1_HMAC, NID_hmacWithSHA1, 20},
+ { CRYPTO_RIPEMD160_HMAC, NID_ripemd160, 16/*?*/},
+ { CRYPTO_MD5_KPDK, NID_undef, 0},
+ { CRYPTO_SHA1_KPDK, NID_undef, 0},
+ { CRYPTO_MD5, NID_md5, 16},
+ { CRYPTO_SHA1, NID_sha1, 20},
+ { 0, NID_undef, 0},
};
+#endif /* 0 */
/*
* Return a fd if /dev/crypto seems usable, 0 otherwise.
@@ -203,50 +217,6 @@ get_asym_dev_crypto(void)
}
/*
- * XXXX this needs to be set for each alg - and determined from
- * a running card.
- */
-static int
-cryptodev_max_iv(int cipher)
-{
- int i;
-
- for (i = 0; ciphers[i].id; i++)
- if (ciphers[i].id == cipher)
- return (ciphers[i].ivmax);
- return (0);
-}
-
-/*
- * XXXX this needs to be set for each alg - and determined from
- * a running card. For now, fake it out - but most of these
- * for real devices should return 1 for the supported key
- * sizes the device can handle.
- */
-static int
-cryptodev_key_length_valid(int cipher, int len)
-{
- int i;
-
- for (i = 0; ciphers[i].id; i++)
- if (ciphers[i].id == cipher)
- return (ciphers[i].keylen == len);
- return (0);
-}
-
-/* convert libcrypto nids to cryptodev */
-static int
-cipher_nid_to_cryptodev(int nid)
-{
- int i;
-
- for (i = 0; ciphers[i].id; i++)
- if (ciphers[i].nid == nid)
- return (ciphers[i].id);
- return (0);
-}
-
-/*
* Find out what ciphers /dev/crypto will let us have a session for.
* XXX note, that some of these openssl doesn't deal with yet!
* returning them here is harmless, as long as we return NULL
@@ -264,7 +234,7 @@ get_cryptodev_ciphers(const int **cnids)
return (0);
}
memset(&sess, 0, sizeof(sess));
- sess.key = (caddr_t)"123456781234567812345678";
+ sess.key = (caddr_t)"123456789abcdefghijklmno";
for (i = 0; ciphers[i].id && count < CRYPTO_ALGORITHM_MAX; i++) {
if (ciphers[i].nid == NID_undef)
@@ -291,6 +261,7 @@ get_cryptodev_ciphers(const int **cnids)
* returning them here is harmless, as long as we return NULL
* when asked for a handler in the cryptodev_engine_digests routine
*/
+#if 0 /* not (yet?) used */
static int
get_cryptodev_digests(const int **cnids)
{
@@ -303,10 +274,12 @@ get_cryptodev_digests(const int **cnids)
return (0);
}
memset(&sess, 0, sizeof(sess));
+ sess.mackey = (caddr_t)"123456789abcdefghijklmno";
for (i = 0; digests[i].id && count < CRYPTO_ALGORITHM_MAX; i++) {
if (digests[i].nid == NID_undef)
continue;
sess.mac = digests[i].id;
+ sess.mackeylen = digests[i].keylen;
sess.cipher = 0;
if (ioctl(fd, CIOCGSESSION, &sess) != -1 &&
ioctl(fd, CIOCFSESSION, &sess.ses) != -1)
@@ -320,6 +293,7 @@ get_cryptodev_digests(const int **cnids)
*cnids = NULL;
return (count);
}
+#endif /* 0 */
/*
* Find the useable ciphers|digests from dev/crypto - this is the first
@@ -351,6 +325,9 @@ cryptodev_usable_ciphers(const int **nids)
static int
cryptodev_usable_digests(const int **nids)
{
+#ifdef USE_CRYPTODEV_DIGESTS
+ return (get_cryptodev_digests(nids));
+#else
/*
* XXXX just disable all digests for now, because it sucks.
* we need a better way to decide this - i.e. I may not
@@ -365,16 +342,17 @@ cryptodev_usable_digests(const int **nids)
*/
*nids = NULL;
return (0);
+#endif
}
static int
cryptodev_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
- const unsigned char *in, unsigned int inl)
+ const unsigned char *in, size_t inl)
{
struct crypt_op cryp;
struct dev_crypto_state *state = ctx->cipher_data;
struct session_op *sess = &state->d_sess;
- void *iiv;
+ const void *iiv;
unsigned char save_iv[EVP_MAX_IV_LENGTH];
if (state->d_fd < 0)
@@ -398,7 +376,7 @@ cryptodev_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
if (ctx->cipher->iv_len) {
cryp.iv = (caddr_t) ctx->iv;
if (!ctx->encrypt) {
- iiv = (void *) in + inl - ctx->cipher->iv_len;
+ iiv = in + inl - ctx->cipher->iv_len;
memcpy(save_iv, iiv, ctx->cipher->iv_len);
}
} else
@@ -413,7 +391,7 @@ cryptodev_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
if (ctx->cipher->iv_len) {
if (ctx->encrypt)
- iiv = (void *) out + inl - ctx->cipher->iv_len;
+ iiv = out + inl - ctx->cipher->iv_len;
else
iiv = save_iv;
memcpy(ctx->iv, iiv, ctx->cipher->iv_len);
@@ -427,23 +405,27 @@ cryptodev_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
{
struct dev_crypto_state *state = ctx->cipher_data;
struct session_op *sess = &state->d_sess;
- int cipher;
-
- if ((cipher = cipher_nid_to_cryptodev(ctx->cipher->nid)) == NID_undef)
- return (0);
+ int cipher = -1, i;
- if (ctx->cipher->iv_len > cryptodev_max_iv(cipher))
- return (0);
+ for (i = 0; ciphers[i].id; i++)
+ if (ctx->cipher->nid == ciphers[i].nid &&
+ ctx->cipher->iv_len <= ciphers[i].ivmax &&
+ ctx->key_len == ciphers[i].keylen) {
+ cipher = ciphers[i].id;
+ break;
+ }
- if (!cryptodev_key_length_valid(cipher, ctx->key_len))
+ if (!ciphers[i].id) {
+ state->d_fd = -1;
return (0);
+ }
memset(sess, 0, sizeof(struct session_op));
if ((state->d_fd = get_dev_crypto()) < 0)
return (0);
- sess->key = (unsigned char *)key;
+ sess->key = (caddr_t)key;
sess->keylen = ctx->key_len;
sess->cipher = cipher;
@@ -496,6 +478,20 @@ cryptodev_cleanup(EVP_CIPHER_CTX *ctx)
* gets called when libcrypto requests a cipher NID.
*/
+/* RC4 */
+const EVP_CIPHER cryptodev_rc4 = {
+ NID_rc4,
+ 1, 16, 0,
+ EVP_CIPH_VARIABLE_LENGTH,
+ cryptodev_init_key,
+ cryptodev_cipher,
+ cryptodev_cleanup,
+ sizeof(struct dev_crypto_state),
+ NULL,
+ NULL,
+ NULL
+};
+
/* DES CBC EVP */
const EVP_CIPHER cryptodev_des_cbc = {
NID_des_cbc,
@@ -563,6 +559,32 @@ const EVP_CIPHER cryptodev_aes_cbc = {
NULL
};
+const EVP_CIPHER cryptodev_aes_192_cbc = {
+ NID_aes_192_cbc,
+ 16, 24, 16,
+ EVP_CIPH_CBC_MODE,
+ cryptodev_init_key,
+ cryptodev_cipher,
+ cryptodev_cleanup,
+ sizeof(struct dev_crypto_state),
+ EVP_CIPHER_set_asn1_iv,
+ EVP_CIPHER_get_asn1_iv,
+ NULL
+};
+
+const EVP_CIPHER cryptodev_aes_256_cbc = {
+ NID_aes_256_cbc,
+ 16, 32, 16,
+ EVP_CIPH_CBC_MODE,
+ cryptodev_init_key,
+ cryptodev_cipher,
+ cryptodev_cleanup,
+ sizeof(struct dev_crypto_state),
+ EVP_CIPHER_set_asn1_iv,
+ EVP_CIPHER_get_asn1_iv,
+ NULL
+};
+
/*
* Registered by the ENGINE when used to find out how to deal with
* a particular NID in the ENGINE. this says what we'll do at the
@@ -576,6 +598,9 @@ cryptodev_engine_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
return (cryptodev_usable_ciphers(nids));
switch (nid) {
+ case NID_rc4:
+ *cipher = &cryptodev_rc4;
+ break;
case NID_des_ede3_cbc:
*cipher = &cryptodev_3des_cbc;
break;
@@ -591,6 +616,12 @@ cryptodev_engine_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
case NID_aes_128_cbc:
*cipher = &cryptodev_aes_cbc;
break;
+ case NID_aes_192_cbc:
+ *cipher = &cryptodev_aes_192_cbc;
+ break;
+ case NID_aes_256_cbc:
+ *cipher = &cryptodev_aes_256_cbc;
+ break;
default:
*cipher = NULL;
break;
@@ -598,6 +629,234 @@ cryptodev_engine_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
return (*cipher != NULL);
}
+
+#ifdef USE_CRYPTODEV_DIGESTS
+
+/* convert digest type to cryptodev */
+static int
+digest_nid_to_cryptodev(int nid)
+{
+ int i;
+
+ for (i = 0; digests[i].id; i++)
+ if (digests[i].nid == nid)
+ return (digests[i].id);
+ return (0);
+}
+
+
+static int
+digest_key_length(int nid)
+{
+ int i;
+
+ for (i = 0; digests[i].id; i++)
+ if (digests[i].nid == nid)
+ return digests[i].keylen;
+ return (0);
+}
+
+
+static int cryptodev_digest_init(EVP_MD_CTX *ctx)
+{
+ struct dev_crypto_state *state = ctx->md_data;
+ struct session_op *sess = &state->d_sess;
+ int digest;
+
+ if ((digest = digest_nid_to_cryptodev(ctx->digest->type)) == NID_undef){
+ printf("cryptodev_digest_init: Can't get digest \n");
+ return (0);
+ }
+
+ memset(state, 0, sizeof(struct dev_crypto_state));
+
+ if ((state->d_fd = get_dev_crypto()) < 0) {
+ printf("cryptodev_digest_init: Can't get Dev \n");
+ return (0);
+ }
+
+ sess->mackey = state->dummy_mac_key;
+ sess->mackeylen = digest_key_length(ctx->digest->type);
+ sess->mac = digest;
+
+ if (ioctl(state->d_fd, CIOCGSESSION, sess) < 0) {
+ close(state->d_fd);
+ state->d_fd = -1;
+ printf("cryptodev_digest_init: Open session failed\n");
+ return (0);
+ }
+
+ return (1);
+}
+
+static int cryptodev_digest_update(EVP_MD_CTX *ctx, const void *data,
+ size_t count)
+{
+ struct crypt_op cryp;
+ struct dev_crypto_state *state = ctx->md_data;
+ struct session_op *sess = &state->d_sess;
+
+ if (!data || state->d_fd < 0) {
+ printf("cryptodev_digest_update: illegal inputs \n");
+ return (0);
+ }
+
+ if (!count) {
+ return (0);
+ }
+
+ if (!(ctx->flags & EVP_MD_CTX_FLAG_ONESHOT)) {
+ /* if application doesn't support one buffer */
+ state->mac_data = OPENSSL_realloc(state->mac_data, state->mac_len + count);
+
+ if (!state->mac_data) {
+ printf("cryptodev_digest_update: realloc failed\n");
+ return (0);
+ }
+
+ memcpy(state->mac_data + state->mac_len, data, count);
+ state->mac_len += count;
+
+ return (1);
+ }
+
+ memset(&cryp, 0, sizeof(cryp));
+
+ cryp.ses = sess->ses;
+ cryp.flags = 0;
+ cryp.len = count;
+ cryp.src = (caddr_t) data;
+ cryp.dst = NULL;
+ cryp.mac = (caddr_t) state->digest_res;
+ if (ioctl(state->d_fd, CIOCCRYPT, &cryp) < 0) {
+ printf("cryptodev_digest_update: digest failed\n");
+ return (0);
+ }
+ return (1);
+}
+
+
+static int cryptodev_digest_final(EVP_MD_CTX *ctx, unsigned char *md)
+{
+ struct crypt_op cryp;
+ struct dev_crypto_state *state = ctx->md_data;
+ struct session_op *sess = &state->d_sess;
+
+ int ret = 1;
+
+ if (!md || state->d_fd < 0) {
+ printf("cryptodev_digest_final: illegal input\n");
+ return(0);
+ }
+
+ if (! (ctx->flags & EVP_MD_CTX_FLAG_ONESHOT) ) {
+ /* if application doesn't support one buffer */
+ memset(&cryp, 0, sizeof(cryp));
+
+ cryp.ses = sess->ses;
+ cryp.flags = 0;
+ cryp.len = state->mac_len;
+ cryp.src = state->mac_data;
+ cryp.dst = NULL;
+ cryp.mac = (caddr_t)md;
+
+ if (ioctl(state->d_fd, CIOCCRYPT, &cryp) < 0) {
+ printf("cryptodev_digest_final: digest failed\n");
+ return (0);
+ }
+
+ return 1;
+ }
+
+ memcpy(md, state->digest_res, ctx->digest->md_size);
+
+ return (ret);
+}
+
+
+static int cryptodev_digest_cleanup(EVP_MD_CTX *ctx)
+{
+ int ret = 1;
+ struct dev_crypto_state *state = ctx->md_data;
+ struct session_op *sess = &state->d_sess;
+
+ if (state->d_fd < 0) {
+ printf("cryptodev_digest_cleanup: illegal input\n");
+ return (0);
+ }
+
+ if (state->mac_data) {
+ OPENSSL_free(state->mac_data);
+ state->mac_data = NULL;
+ state->mac_len = 0;
+ }
+
+ if (state->copy)
+ return 1;
+
+ if (ioctl(state->d_fd, CIOCFSESSION, &sess->ses) < 0) {
+ printf("cryptodev_digest_cleanup: failed to close session\n");
+ ret = 0;
+ } else {
+ ret = 1;
+ }
+ close(state->d_fd);
+ state->d_fd = -1;
+
+ return (ret);
+}
+
+static int cryptodev_digest_copy(EVP_MD_CTX *to,const EVP_MD_CTX *from)
+{
+ struct dev_crypto_state *fstate = from->md_data;
+ struct dev_crypto_state *dstate = to->md_data;
+
+ memcpy(dstate, fstate, sizeof(struct dev_crypto_state));
+
+ if (fstate->mac_len != 0) {
+ dstate->mac_data = OPENSSL_malloc(fstate->mac_len);
+ memcpy(dstate->mac_data, fstate->mac_data, fstate->mac_len);
+ }
+
+ dstate->copy = 1;
+
+ return 1;
+}
+
+
+const EVP_MD cryptodev_sha1 = {
+ NID_sha1,
+ NID_undef,
+ SHA_DIGEST_LENGTH,
+ EVP_MD_FLAG_ONESHOT,
+ cryptodev_digest_init,
+ cryptodev_digest_update,
+ cryptodev_digest_final,
+ cryptodev_digest_copy,
+ cryptodev_digest_cleanup,
+ EVP_PKEY_NULL_method,
+ SHA_CBLOCK,
+ sizeof(struct dev_crypto_state),
+};
+
+const EVP_MD cryptodev_md5 = {
+ NID_md5,
+ NID_undef,
+ 16 /* MD5_DIGEST_LENGTH */,
+ EVP_MD_FLAG_ONESHOT,
+ cryptodev_digest_init,
+ cryptodev_digest_update,
+ cryptodev_digest_final,
+ cryptodev_digest_copy,
+ cryptodev_digest_cleanup,
+ EVP_PKEY_NULL_method,
+ 64 /* MD5_CBLOCK */,
+ sizeof(struct dev_crypto_state),
+};
+
+#endif /* USE_CRYPTODEV_DIGESTS */
+
+
static int
cryptodev_engine_digests(ENGINE *e, const EVP_MD **digest,
const int **nids, int nid)
@@ -606,10 +865,15 @@ cryptodev_engine_digests(ENGINE *e, const EVP_MD **digest,
return (cryptodev_usable_digests(nids));
switch (nid) {
+#ifdef USE_CRYPTODEV_DIGESTS
case NID_md5:
- *digest = NULL; /* need to make a clean md5 critter */
+ *digest = &cryptodev_md5;
break;
+ case NID_sha1:
+ *digest = &cryptodev_sha1;
+ break;
default:
+#endif /* USE_CRYPTODEV_DIGESTS */
*digest = NULL;
break;
}
@@ -625,7 +889,7 @@ static int
bn2crparam(const BIGNUM *a, struct crparam *crp)
{
int i, j, k;
- ssize_t words, bytes, bits;
+ ssize_t bytes, bits;
u_char *b;
crp->crp_p = NULL;
@@ -637,8 +901,9 @@ bn2crparam(const BIGNUM *a, struct crparam *crp)
b = malloc(bytes);
if (b == NULL)
return (1);
+ memset(b, 0, bytes);
- crp->crp_p = b;
+ crp->crp_p = (caddr_t) b;
crp->crp_nbits = bits;
for (i = 0, j = 0; i < a->top; i++) {
@@ -681,7 +946,7 @@ zapparams(struct crypt_kop *kop)
{
int i;
- for (i = 0; i <= kop->crk_iparams + kop->crk_oparams; i++) {
+ for (i = 0; i < kop->crk_iparams + kop->crk_oparams; i++) {
if (kop->crk_param[i].crp_p)
free(kop->crk_param[i].crp_p);
kop->crk_param[i].crp_p = NULL;
@@ -756,11 +1021,9 @@ err:
}
static int
-cryptodev_rsa_nocrt_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa)
+cryptodev_rsa_nocrt_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
{
int r;
- BN_CTX *ctx;
-
ctx = BN_CTX_new();
r = cryptodev_bn_mod_exp(r0, I, rsa->d, rsa->n, ctx, NULL);
BN_CTX_free(ctx);
@@ -994,7 +1257,7 @@ cryptodev_dh_compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh)
goto err;
kop.crk_iparams = 3;
- kop.crk_param[3].crp_p = key;
+ kop.crk_param[3].crp_p = (caddr_t) key;
kop.crk_param[3].crp_nbits = keylen * 8;
kop.crk_oparams = 1;
@@ -1025,7 +1288,7 @@ static DH_METHOD cryptodev_dh = {
* but I expect we'll want some options soon.
*/
static int
-cryptodev_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)())
+cryptodev_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void))
{
#ifdef HAVE_SYSLOG_R
struct syslog_data sd = SYSLOG_DATA_INIT;
diff --git a/crypto/engine/eng_ctrl.c b/crypto/engine/eng_ctrl.c
index 18527484ce..5ce25d92ec 100644
--- a/crypto/engine/eng_ctrl.c
+++ b/crypto/engine/eng_ctrl.c
@@ -100,7 +100,8 @@ static int int_ctrl_cmd_by_num(const ENGINE_CMD_DEFN *defn, unsigned int num)
return -1;
}
-static int int_ctrl_helper(ENGINE *e, int cmd, long i, void *p, void (*f)())
+static int int_ctrl_helper(ENGINE *e, int cmd, long i, void *p,
+ void (*f)(void))
{
int idx;
char *s = (char *)p;
@@ -254,7 +255,7 @@ int ENGINE_ctrl_cmd(ENGINE *e, const char *cmd_name,
if((e == NULL) || (cmd_name == NULL))
{
- ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING,
+ ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD,
ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
@@ -279,7 +280,7 @@ int ENGINE_ctrl_cmd(ENGINE *e, const char *cmd_name,
}
/* Force the result of the control command to 0 or 1, for the reasons
* mentioned before. */
- if (ENGINE_ctrl(e, num, i, p, f))
+ if (ENGINE_ctrl(e, num, i, p, f) > 0)
return 1;
return 0;
}
@@ -344,7 +345,7 @@ int ENGINE_ctrl_cmd_string(ENGINE *e, const char *cmd_name, const char *arg,
* usage of these commands is consistent across applications and
* that certain applications don't understand it one way, and
* others another. */
- if(ENGINE_ctrl(e, num, 0, (void *)arg, NULL))
+ if(ENGINE_ctrl(e, num, 0, (void *)arg, NULL) > 0)
return 1;
return 0;
}
@@ -359,7 +360,7 @@ int ENGINE_ctrl_cmd_string(ENGINE *e, const char *cmd_name, const char *arg,
if(flags & ENGINE_CMD_FLAG_STRING)
{
/* Same explanation as above */
- if(ENGINE_ctrl(e, num, 0, (void *)arg, NULL))
+ if(ENGINE_ctrl(e, num, 0, (void *)arg, NULL) > 0)
return 1;
return 0;
}
@@ -382,7 +383,7 @@ int ENGINE_ctrl_cmd_string(ENGINE *e, const char *cmd_name, const char *arg,
}
/* Force the result of the control command to 0 or 1, for the reasons
* mentioned before. */
- if(ENGINE_ctrl(e, num, l, NULL, NULL))
+ if(ENGINE_ctrl(e, num, l, NULL, NULL) > 0)
return 1;
return 0;
}
diff --git a/crypto/engine/eng_dyn.c b/crypto/engine/eng_dyn.c
index 290b8bd395..807da7a5eb 100644
--- a/crypto/engine/eng_dyn.c
+++ b/crypto/engine/eng_dyn.c
@@ -146,14 +146,14 @@ struct st_dynamic_data_ctx
* 'dirs' for loading. Default is to use 'dirs' as a fallback. */
int dir_load;
/* A stack of directories from which ENGINEs could be loaded */
- STACK *dirs;
+ STACK_OF(OPENSSL_STRING) *dirs;
};
/* This is the "ex_data" index we obtain and reserve for use with our context
* structure. */
static int dynamic_ex_data_idx = -1;
-static void int_free_str(void *s) { OPENSSL_free(s); }
+static void int_free_str(char *s) { OPENSSL_free(s); }
/* Because our ex_data element may or may not get allocated depending on whether
* a "first-use" occurs before the ENGINE is freed, we have a memory leak
* problem to solve. We can't declare a "new" handler for the ex_data as we
@@ -174,7 +174,7 @@ static void dynamic_data_ctx_free_func(void *parent, void *ptr,
if(ctx->engine_id)
OPENSSL_free((void*)ctx->engine_id);
if(ctx->dirs)
- sk_pop_free(ctx->dirs, int_free_str);
+ sk_OPENSSL_STRING_pop_free(ctx->dirs, int_free_str);
OPENSSL_free(ctx);
}
}
@@ -189,7 +189,7 @@ static int dynamic_set_data_ctx(ENGINE *e, dynamic_data_ctx **ctx)
c = OPENSSL_malloc(sizeof(dynamic_data_ctx));
if(!c)
{
- ENGINEerr(ENGINE_F_SET_DATA_CTX,ERR_R_MALLOC_FAILURE);
+ ENGINEerr(ENGINE_F_DYNAMIC_SET_DATA_CTX,ERR_R_MALLOC_FAILURE);
return 0;
}
memset(c, 0, sizeof(dynamic_data_ctx));
@@ -203,10 +203,10 @@ static int dynamic_set_data_ctx(ENGINE *e, dynamic_data_ctx **ctx)
c->DYNAMIC_F1 = "v_check";
c->DYNAMIC_F2 = "bind_engine";
c->dir_load = 1;
- c->dirs = sk_new_null();
+ c->dirs = sk_OPENSSL_STRING_new_null();
if(!c->dirs)
{
- ENGINEerr(ENGINE_F_SET_DATA_CTX,ERR_R_MALLOC_FAILURE);
+ ENGINEerr(ENGINE_F_DYNAMIC_SET_DATA_CTX,ERR_R_MALLOC_FAILURE);
OPENSSL_free(c);
return 0;
}
@@ -393,7 +393,7 @@ static int dynamic_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void))
ERR_R_MALLOC_FAILURE);
return 0;
}
- sk_insert(ctx->dirs, tmp_str, -1);
+ sk_OPENSSL_STRING_insert(ctx->dirs, tmp_str, -1);
}
return 1;
default:
@@ -411,11 +411,11 @@ static int int_load(dynamic_data_ctx *ctx)
ctx->DYNAMIC_LIBNAME, NULL, 0)) != NULL)
return 1;
/* If we're not allowed to use 'dirs' or we have none, fail */
- if(!ctx->dir_load || ((num = sk_num(ctx->dirs)) < 1))
+ if(!ctx->dir_load || (num = sk_OPENSSL_STRING_num(ctx->dirs)) < 1)
return 0;
for(loop = 0; loop < num; loop++)
{
- const char *s = sk_value(ctx->dirs, loop);
+ const char *s = sk_OPENSSL_STRING_value(ctx->dirs, loop);
char *merge = DSO_merge(ctx->dynamic_dso, ctx->DYNAMIC_LIBNAME, s);
if(!merge)
return 0;
diff --git a/crypto/engine/eng_err.c b/crypto/engine/eng_err.c
index 814d95ee32..466b8af190 100644
--- a/crypto/engine/eng_err.c
+++ b/crypto/engine/eng_err.c
@@ -1,6 +1,6 @@
/* crypto/engine/eng_err.c */
/* ====================================================================
- * Copyright (c) 1999-2002 The OpenSSL Project. All rights reserved.
+ * Copyright (c) 1999-2007 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -64,87 +64,96 @@
/* BEGIN ERROR CODES */
#ifndef OPENSSL_NO_ERR
+
+#define ERR_FUNC(func) ERR_PACK(ERR_LIB_ENGINE,func,0)
+#define ERR_REASON(reason) ERR_PACK(ERR_LIB_ENGINE,0,reason)
+
static ERR_STRING_DATA ENGINE_str_functs[]=
{
-{ERR_PACK(0,ENGINE_F_DYNAMIC_CTRL,0), "DYNAMIC_CTRL"},
-{ERR_PACK(0,ENGINE_F_DYNAMIC_GET_DATA_CTX,0), "DYNAMIC_GET_DATA_CTX"},
-{ERR_PACK(0,ENGINE_F_DYNAMIC_LOAD,0), "DYNAMIC_LOAD"},
-{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_CMD_IS_EXECUTABLE,0), "ENGINE_cmd_is_executable"},
-{ERR_PACK(0,ENGINE_F_ENGINE_CTRL,0), "ENGINE_ctrl"},
-{ERR_PACK(0,ENGINE_F_ENGINE_CTRL_CMD,0), "ENGINE_ctrl_cmd"},
-{ERR_PACK(0,ENGINE_F_ENGINE_CTRL_CMD_STRING,0), "ENGINE_ctrl_cmd_string"},
-{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_CIPHER,0), "ENGINE_get_cipher"},
-{ERR_PACK(0,ENGINE_F_ENGINE_GET_DEFAULT_TYPE,0), "ENGINE_GET_DEFAULT_TYPE"},
-{ERR_PACK(0,ENGINE_F_ENGINE_GET_DIGEST,0), "ENGINE_get_digest"},
-{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_INIT,0), "ENGINE_init"},
-{ERR_PACK(0,ENGINE_F_ENGINE_LIST_ADD,0), "ENGINE_LIST_ADD"},
-{ERR_PACK(0,ENGINE_F_ENGINE_LIST_REMOVE,0), "ENGINE_LIST_REMOVE"},
-{ERR_PACK(0,ENGINE_F_ENGINE_LOAD_PRIVATE_KEY,0), "ENGINE_load_private_key"},
-{ERR_PACK(0,ENGINE_F_ENGINE_LOAD_PUBLIC_KEY,0), "ENGINE_load_public_key"},
-{ERR_PACK(0,ENGINE_F_ENGINE_MODULE_INIT,0), "ENGINE_MODULE_INIT"},
-{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_DEFAULT_STRING,0), "ENGINE_set_default_string"},
-{ERR_PACK(0,ENGINE_F_ENGINE_SET_DEFAULT_TYPE,0), "ENGINE_SET_DEFAULT_TYPE"},
-{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_TABLE_REGISTER,0), "ENGINE_TABLE_REGISTER"},
-{ERR_PACK(0,ENGINE_F_ENGINE_UNLOAD_KEY,0), "ENGINE_UNLOAD_KEY"},
-{ERR_PACK(0,ENGINE_F_ENGINE_UP_REF,0), "ENGINE_up_ref"},
-{ERR_PACK(0,ENGINE_F_INT_CTRL_HELPER,0), "INT_CTRL_HELPER"},
-{ERR_PACK(0,ENGINE_F_INT_ENGINE_CONFIGURE,0), "INT_ENGINE_CONFIGURE"},
-{ERR_PACK(0,ENGINE_F_LOG_MESSAGE,0), "LOG_MESSAGE"},
-{ERR_PACK(0,ENGINE_F_SET_DATA_CTX,0), "SET_DATA_CTX"},
+{ERR_FUNC(ENGINE_F_DYNAMIC_CTRL), "DYNAMIC_CTRL"},
+{ERR_FUNC(ENGINE_F_DYNAMIC_GET_DATA_CTX), "DYNAMIC_GET_DATA_CTX"},
+{ERR_FUNC(ENGINE_F_DYNAMIC_LOAD), "DYNAMIC_LOAD"},
+{ERR_FUNC(ENGINE_F_DYNAMIC_SET_DATA_CTX), "DYNAMIC_SET_DATA_CTX"},
+{ERR_FUNC(ENGINE_F_ENGINE_ADD), "ENGINE_add"},
+{ERR_FUNC(ENGINE_F_ENGINE_BY_ID), "ENGINE_by_id"},
+{ERR_FUNC(ENGINE_F_ENGINE_CMD_IS_EXECUTABLE), "ENGINE_cmd_is_executable"},
+{ERR_FUNC(ENGINE_F_ENGINE_CTRL), "ENGINE_ctrl"},
+{ERR_FUNC(ENGINE_F_ENGINE_CTRL_CMD), "ENGINE_ctrl_cmd"},
+{ERR_FUNC(ENGINE_F_ENGINE_CTRL_CMD_STRING), "ENGINE_ctrl_cmd_string"},
+{ERR_FUNC(ENGINE_F_ENGINE_FINISH), "ENGINE_finish"},
+{ERR_FUNC(ENGINE_F_ENGINE_FREE_UTIL), "ENGINE_FREE_UTIL"},
+{ERR_FUNC(ENGINE_F_ENGINE_GET_CIPHER), "ENGINE_get_cipher"},
+{ERR_FUNC(ENGINE_F_ENGINE_GET_DEFAULT_TYPE), "ENGINE_GET_DEFAULT_TYPE"},
+{ERR_FUNC(ENGINE_F_ENGINE_GET_DIGEST), "ENGINE_get_digest"},
+{ERR_FUNC(ENGINE_F_ENGINE_GET_NEXT), "ENGINE_get_next"},
+{ERR_FUNC(ENGINE_F_ENGINE_GET_PKEY_ASN1_METH), "ENGINE_get_pkey_asn1_meth"},
+{ERR_FUNC(ENGINE_F_ENGINE_GET_PKEY_METH), "ENGINE_get_pkey_meth"},
+{ERR_FUNC(ENGINE_F_ENGINE_GET_PREV), "ENGINE_get_prev"},
+{ERR_FUNC(ENGINE_F_ENGINE_INIT), "ENGINE_init"},
+{ERR_FUNC(ENGINE_F_ENGINE_LIST_ADD), "ENGINE_LIST_ADD"},
+{ERR_FUNC(ENGINE_F_ENGINE_LIST_REMOVE), "ENGINE_LIST_REMOVE"},
+{ERR_FUNC(ENGINE_F_ENGINE_LOAD_PRIVATE_KEY), "ENGINE_load_private_key"},
+{ERR_FUNC(ENGINE_F_ENGINE_LOAD_PUBLIC_KEY), "ENGINE_load_public_key"},
+{ERR_FUNC(ENGINE_F_ENGINE_LOAD_SSL_CLIENT_CERT), "ENGINE_load_ssl_client_cert"},
+{ERR_FUNC(ENGINE_F_ENGINE_NEW), "ENGINE_new"},
+{ERR_FUNC(ENGINE_F_ENGINE_REMOVE), "ENGINE_remove"},
+{ERR_FUNC(ENGINE_F_ENGINE_SET_DEFAULT_STRING), "ENGINE_set_default_string"},
+{ERR_FUNC(ENGINE_F_ENGINE_SET_DEFAULT_TYPE), "ENGINE_SET_DEFAULT_TYPE"},
+{ERR_FUNC(ENGINE_F_ENGINE_SET_ID), "ENGINE_set_id"},
+{ERR_FUNC(ENGINE_F_ENGINE_SET_NAME), "ENGINE_set_name"},
+{ERR_FUNC(ENGINE_F_ENGINE_TABLE_REGISTER), "ENGINE_TABLE_REGISTER"},
+{ERR_FUNC(ENGINE_F_ENGINE_UNLOAD_KEY), "ENGINE_UNLOAD_KEY"},
+{ERR_FUNC(ENGINE_F_ENGINE_UNLOCKED_FINISH), "ENGINE_UNLOCKED_FINISH"},
+{ERR_FUNC(ENGINE_F_ENGINE_UP_REF), "ENGINE_up_ref"},
+{ERR_FUNC(ENGINE_F_INT_CTRL_HELPER), "INT_CTRL_HELPER"},
+{ERR_FUNC(ENGINE_F_INT_ENGINE_CONFIGURE), "INT_ENGINE_CONFIGURE"},
+{ERR_FUNC(ENGINE_F_INT_ENGINE_MODULE_INIT), "INT_ENGINE_MODULE_INIT"},
+{ERR_FUNC(ENGINE_F_LOG_MESSAGE), "LOG_MESSAGE"},
{0,NULL}
};
static ERR_STRING_DATA ENGINE_str_reasons[]=
{
-{ENGINE_R_ALREADY_LOADED ,"already loaded"},
-{ENGINE_R_ARGUMENT_IS_NOT_A_NUMBER ,"argument is not a number"},
-{ENGINE_R_CMD_NOT_EXECUTABLE ,"cmd not executable"},
-{ENGINE_R_COMMAND_TAKES_INPUT ,"command takes input"},
-{ENGINE_R_COMMAND_TAKES_NO_INPUT ,"command takes no input"},
-{ENGINE_R_CONFLICTING_ENGINE_ID ,"conflicting engine id"},
-{ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED ,"ctrl command not implemented"},
-{ENGINE_R_DH_NOT_IMPLEMENTED ,"dh not implemented"},
-{ENGINE_R_DSA_NOT_IMPLEMENTED ,"dsa not implemented"},
-{ENGINE_R_DSO_FAILURE ,"DSO failure"},
-{ENGINE_R_DSO_NOT_FOUND ,"dso not found"},
-{ENGINE_R_ENGINES_SECTION_ERROR ,"engines section error"},
-{ENGINE_R_ENGINE_IS_NOT_IN_LIST ,"engine is not in the list"},
-{ENGINE_R_ENGINE_SECTION_ERROR ,"engine section error"},
-{ENGINE_R_FAILED_LOADING_PRIVATE_KEY ,"failed loading private key"},
-{ENGINE_R_FAILED_LOADING_PUBLIC_KEY ,"failed loading public key"},
-{ENGINE_R_FINISH_FAILED ,"finish failed"},
-{ENGINE_R_GET_HANDLE_FAILED ,"could not obtain hardware handle"},
-{ENGINE_R_ID_OR_NAME_MISSING ,"'id' or 'name' missing"},
-{ENGINE_R_INIT_FAILED ,"init failed"},
-{ENGINE_R_INTERNAL_LIST_ERROR ,"internal list error"},
-{ENGINE_R_INVALID_ARGUMENT ,"invalid argument"},
-{ENGINE_R_INVALID_CMD_NAME ,"invalid cmd name"},
-{ENGINE_R_INVALID_CMD_NUMBER ,"invalid cmd number"},
-{ENGINE_R_INVALID_INIT_VALUE ,"invalid init value"},
-{ENGINE_R_INVALID_STRING ,"invalid string"},
-{ENGINE_R_NOT_INITIALISED ,"not initialised"},
-{ENGINE_R_NOT_LOADED ,"not loaded"},
-{ENGINE_R_NO_CONTROL_FUNCTION ,"no control function"},
-{ENGINE_R_NO_INDEX ,"no index"},
-{ENGINE_R_NO_LOAD_FUNCTION ,"no load function"},
-{ENGINE_R_NO_REFERENCE ,"no reference"},
-{ENGINE_R_NO_SUCH_ENGINE ,"no such engine"},
-{ENGINE_R_NO_UNLOAD_FUNCTION ,"no unload function"},
-{ENGINE_R_PROVIDE_PARAMETERS ,"provide parameters"},
-{ENGINE_R_RSA_NOT_IMPLEMENTED ,"rsa not implemented"},
-{ENGINE_R_UNIMPLEMENTED_CIPHER ,"unimplemented cipher"},
-{ENGINE_R_UNIMPLEMENTED_DIGEST ,"unimplemented digest"},
-{ENGINE_R_VERSION_INCOMPATIBILITY ,"version incompatibility"},
+{ERR_REASON(ENGINE_R_ALREADY_LOADED) ,"already loaded"},
+{ERR_REASON(ENGINE_R_ARGUMENT_IS_NOT_A_NUMBER),"argument is not a number"},
+{ERR_REASON(ENGINE_R_CMD_NOT_EXECUTABLE) ,"cmd not executable"},
+{ERR_REASON(ENGINE_R_COMMAND_TAKES_INPUT),"command takes input"},
+{ERR_REASON(ENGINE_R_COMMAND_TAKES_NO_INPUT),"command takes no input"},
+{ERR_REASON(ENGINE_R_CONFLICTING_ENGINE_ID),"conflicting engine id"},
+{ERR_REASON(ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED),"ctrl command not implemented"},
+{ERR_REASON(ENGINE_R_DH_NOT_IMPLEMENTED) ,"dh not implemented"},
+{ERR_REASON(ENGINE_R_DSA_NOT_IMPLEMENTED),"dsa not implemented"},
+{ERR_REASON(ENGINE_R_DSO_FAILURE) ,"DSO failure"},
+{ERR_REASON(ENGINE_R_DSO_NOT_FOUND) ,"dso not found"},
+{ERR_REASON(ENGINE_R_ENGINES_SECTION_ERROR),"engines section error"},
+{ERR_REASON(ENGINE_R_ENGINE_IS_NOT_IN_LIST),"engine is not in the list"},
+{ERR_REASON(ENGINE_R_ENGINE_SECTION_ERROR),"engine section error"},
+{ERR_REASON(ENGINE_R_FAILED_LOADING_PRIVATE_KEY),"failed loading private key"},
+{ERR_REASON(ENGINE_R_FAILED_LOADING_PUBLIC_KEY),"failed loading public key"},
+{ERR_REASON(ENGINE_R_FINISH_FAILED) ,"finish failed"},
+{ERR_REASON(ENGINE_R_GET_HANDLE_FAILED) ,"could not obtain hardware handle"},
+{ERR_REASON(ENGINE_R_ID_OR_NAME_MISSING) ,"'id' or 'name' missing"},
+{ERR_REASON(ENGINE_R_INIT_FAILED) ,"init failed"},
+{ERR_REASON(ENGINE_R_INTERNAL_LIST_ERROR),"internal list error"},
+{ERR_REASON(ENGINE_R_INVALID_ARGUMENT) ,"invalid argument"},
+{ERR_REASON(ENGINE_R_INVALID_CMD_NAME) ,"invalid cmd name"},
+{ERR_REASON(ENGINE_R_INVALID_CMD_NUMBER) ,"invalid cmd number"},
+{ERR_REASON(ENGINE_R_INVALID_INIT_VALUE) ,"invalid init value"},
+{ERR_REASON(ENGINE_R_INVALID_STRING) ,"invalid string"},
+{ERR_REASON(ENGINE_R_NOT_INITIALISED) ,"not initialised"},
+{ERR_REASON(ENGINE_R_NOT_LOADED) ,"not loaded"},
+{ERR_REASON(ENGINE_R_NO_CONTROL_FUNCTION),"no control function"},
+{ERR_REASON(ENGINE_R_NO_INDEX) ,"no index"},
+{ERR_REASON(ENGINE_R_NO_LOAD_FUNCTION) ,"no load function"},
+{ERR_REASON(ENGINE_R_NO_REFERENCE) ,"no reference"},
+{ERR_REASON(ENGINE_R_NO_SUCH_ENGINE) ,"no such engine"},
+{ERR_REASON(ENGINE_R_NO_UNLOAD_FUNCTION) ,"no unload function"},
+{ERR_REASON(ENGINE_R_PROVIDE_PARAMETERS) ,"provide parameters"},
+{ERR_REASON(ENGINE_R_RSA_NOT_IMPLEMENTED),"rsa not implemented"},
+{ERR_REASON(ENGINE_R_UNIMPLEMENTED_CIPHER),"unimplemented cipher"},
+{ERR_REASON(ENGINE_R_UNIMPLEMENTED_DIGEST),"unimplemented digest"},
+{ERR_REASON(ENGINE_R_UNIMPLEMENTED_PUBLIC_KEY_METHOD),"unimplemented public key method"},
+{ERR_REASON(ENGINE_R_VERSION_INCOMPATIBILITY),"version incompatibility"},
{0,NULL}
};
@@ -152,15 +161,12 @@ static ERR_STRING_DATA ENGINE_str_reasons[]=
void ERR_load_ENGINE_strings(void)
{
- static int init=1;
-
- if (init)
- {
- init=0;
#ifndef OPENSSL_NO_ERR
- ERR_load_strings(ERR_LIB_ENGINE,ENGINE_str_functs);
- ERR_load_strings(ERR_LIB_ENGINE,ENGINE_str_reasons);
-#endif
+ if (ERR_func_error_string(ENGINE_str_functs[0].error) == NULL)
+ {
+ ERR_load_strings(0,ENGINE_str_functs);
+ ERR_load_strings(0,ENGINE_str_reasons);
}
+#endif
}
diff --git a/crypto/engine/eng_fat.c b/crypto/engine/eng_fat.c
index 27c1662f62..db66e62350 100644
--- a/crypto/engine/eng_fat.c
+++ b/crypto/engine/eng_fat.c
@@ -89,6 +89,12 @@ int ENGINE_set_default(ENGINE *e, unsigned int flags)
#endif
if((flags & ENGINE_METHOD_RAND) && !ENGINE_set_default_RAND(e))
return 0;
+ if((flags & ENGINE_METHOD_PKEY_METHS)
+ && !ENGINE_set_default_pkey_meths(e))
+ return 0;
+ if((flags & ENGINE_METHOD_PKEY_ASN1_METHS)
+ && !ENGINE_set_default_pkey_asn1_meths(e))
+ return 0;
return 1;
}
@@ -115,6 +121,13 @@ static int int_def_cb(const char *alg, int len, void *arg)
*pflags |= ENGINE_METHOD_CIPHERS;
else if (!strncmp(alg, "DIGESTS", len))
*pflags |= ENGINE_METHOD_DIGESTS;
+ else if (!strncmp(alg, "PKEY", len))
+ *pflags |=
+ ENGINE_METHOD_PKEY_METHS|ENGINE_METHOD_PKEY_ASN1_METHS;
+ else if (!strncmp(alg, "PKEY_CRYPTO", len))
+ *pflags |= ENGINE_METHOD_PKEY_METHS;
+ else if (!strncmp(alg, "PKEY_ASN1", len))
+ *pflags |= ENGINE_METHOD_PKEY_ASN1_METHS;
else
return 0;
return 1;
@@ -154,6 +167,7 @@ int ENGINE_register_complete(ENGINE *e)
ENGINE_register_ECDSA(e);
#endif
ENGINE_register_RAND(e);
+ ENGINE_register_pkey_meths(e);
return 1;
}
diff --git a/crypto/engine/eng_init.c b/crypto/engine/eng_init.c
index 2843e4f0e4..7633cf5f1d 100644
--- a/crypto/engine/eng_init.c
+++ b/crypto/engine/eng_init.c
@@ -111,7 +111,7 @@ int engine_unlocked_finish(ENGINE *e, int unlock_for_handlers)
/* Release the structural reference too */
if(!engine_free_util(e, 0))
{
- ENGINEerr(ENGINE_F_ENGINE_FINISH,ENGINE_R_FINISH_FAILED);
+ ENGINEerr(ENGINE_F_ENGINE_UNLOCKED_FINISH,ENGINE_R_FINISH_FAILED);
return 0;
}
return to_return;
diff --git a/crypto/engine/eng_int.h b/crypto/engine/eng_int.h
index a5b1edebf4..451ef8feb8 100644
--- a/crypto/engine/eng_int.h
+++ b/crypto/engine/eng_int.h
@@ -127,6 +127,8 @@ ENGINE *engine_table_select(ENGINE_TABLE **table, int nid);
ENGINE *engine_table_select_tmp(ENGINE_TABLE **table, int nid, const char *f, int l);
#define engine_table_select(t,n) engine_table_select_tmp(t,n,__FILE__,__LINE__)
#endif
+typedef void (engine_table_doall_cb)(int nid, STACK_OF(ENGINE) *sk, ENGINE *def, void *arg);
+void engine_table_doall(ENGINE_TABLE *table, engine_table_doall_cb *cb, void *arg);
/* Internal versions of API functions that have control over locking. These are
* used between C files when functionality needs to be shared but the caller may
@@ -143,6 +145,11 @@ void engine_set_all_null(ENGINE *e);
/* NB: Bitwise OR-able values for the "flags" variable in ENGINE are now exposed
* in engine.h. */
+/* Free up dynamically allocated public key methods associated with ENGINE */
+
+void engine_pkey_meths_free(ENGINE *e);
+void engine_pkey_asn1_meths_free(ENGINE *e);
+
/* This is a structure for storing implementations of various crypto
* algorithms and functions. */
struct engine_st
@@ -160,7 +167,10 @@ struct engine_st
ENGINE_CIPHERS_PTR ciphers;
/* Digest handling is via this callback */
ENGINE_DIGESTS_PTR digests;
-
+ /* Public key handling via this callback */
+ ENGINE_PKEY_METHS_PTR pkey_meths;
+ /* ASN1 public key handling via this callback */
+ ENGINE_PKEY_ASN1_METHS_PTR pkey_asn1_meths;
ENGINE_GEN_INT_FUNC_PTR destroy;
@@ -170,6 +180,8 @@ struct engine_st
ENGINE_LOAD_KEY_PTR load_privkey;
ENGINE_LOAD_KEY_PTR load_pubkey;
+ ENGINE_SSL_CLIENT_CERT_PTR load_ssl_client_cert;
+
const ENGINE_CMD_DEFN *cmd_defns;
int flags;
/* reference count on the structure itself */
diff --git a/crypto/engine/eng_lib.c b/crypto/engine/eng_lib.c
index 7b3686ddc0..18a6664645 100644
--- a/crypto/engine/eng_lib.c
+++ b/crypto/engine/eng_lib.c
@@ -108,7 +108,7 @@ int engine_free_util(ENGINE *e, int locked)
if(e == NULL)
{
- ENGINEerr(ENGINE_F_ENGINE_FREE,
+ ENGINEerr(ENGINE_F_ENGINE_FREE_UTIL,
ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
@@ -125,6 +125,9 @@ int engine_free_util(ENGINE *e, int locked)
abort();
}
#endif
+ /* Free up any dynamically allocated public key methods */
+ engine_pkey_meths_free(e);
+ engine_pkey_asn1_meths_free(e);
/* Give the ENGINE a chance to do any structural cleanup corresponding
* to allocation it did in its constructor (eg. unload error strings) */
if(e->destroy)
diff --git a/crypto/engine/eng_list.c b/crypto/engine/eng_list.c
index f337e0f3bc..66a52b89e0 100644
--- a/crypto/engine/eng_list.c
+++ b/crypto/engine/eng_list.c
@@ -336,6 +336,7 @@ static void engine_cpy(ENGINE *dest, const ENGINE *src)
dest->store_meth = src->store_meth;
dest->ciphers = src->ciphers;
dest->digests = src->digests;
+ dest->pkey_meths = src->pkey_meths;
dest->destroy = src->destroy;
dest->init = src->init;
dest->finish = src->finish;
@@ -394,19 +395,23 @@ ENGINE *ENGINE_by_id(const char *id)
#else
/* EEK! Experimental code starts */
if(iterator) return iterator;
+ /* Prevent infinite recusrion if we're looking for the dynamic engine. */
+ if (strcmp(id, "dynamic"))
+ {
#ifdef OPENSSL_SYS_VMS
- if((load_dir = getenv("OPENSSL_ENGINES")) == 0) load_dir = "SSLROOT:[ENGINES]";
+ if((load_dir = getenv("OPENSSL_ENGINES")) == 0) load_dir = "SSLROOT:[ENGINES]";
#else
- if((load_dir = getenv("OPENSSL_ENGINES")) == 0) load_dir = ENGINESDIR;
+ if((load_dir = getenv("OPENSSL_ENGINES")) == 0) load_dir = ENGINESDIR;
#endif
- iterator = ENGINE_by_id("dynamic");
- if(!iterator || !ENGINE_ctrl_cmd_string(iterator, "ID", id, 0) ||
- !ENGINE_ctrl_cmd_string(iterator, "DIR_LOAD", "2", 0) ||
- !ENGINE_ctrl_cmd_string(iterator, "DIR_ADD",
- load_dir, 0) ||
- !ENGINE_ctrl_cmd_string(iterator, "LOAD", NULL, 0))
- goto notfound;
- return iterator;
+ iterator = ENGINE_by_id("dynamic");
+ if(!iterator || !ENGINE_ctrl_cmd_string(iterator, "ID", id, 0) ||
+ !ENGINE_ctrl_cmd_string(iterator, "DIR_LOAD", "2", 0) ||
+ !ENGINE_ctrl_cmd_string(iterator, "DIR_ADD",
+ load_dir, 0) ||
+ !ENGINE_ctrl_cmd_string(iterator, "LOAD", NULL, 0))
+ goto notfound;
+ return iterator;
+ }
notfound:
ENGINEerr(ENGINE_F_ENGINE_BY_ID,ENGINE_R_NO_SUCH_ENGINE);
ERR_add_error_data(2, "id=", id);
diff --git a/crypto/engine/eng_openssl.c b/crypto/engine/eng_openssl.c
index dd16d3bc6a..9abb95cc22 100644
--- a/crypto/engine/eng_openssl.c
+++ b/crypto/engine/eng_openssl.c
@@ -70,9 +70,15 @@
#include <openssl/pem.h>
#include <openssl/evp.h>
#include <openssl/rand.h>
+#ifndef OPENSSL_NO_RSA
#include <openssl/rsa.h>
+#endif
+#ifndef OPENSSL_NO_DSA
#include <openssl/dsa.h>
+#endif
+#ifndef OPENSSL_NO_DH
#include <openssl/dh.h>
+#endif
/* This testing gunk is implemented (and explained) lower down. It also assumes
* the application explicitly calls "ENGINE_load_openssl()" because this is no
@@ -232,7 +238,7 @@ static int test_rc4_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
return 1;
}
static int test_rc4_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
- const unsigned char *in, unsigned int inl)
+ const unsigned char *in, size_t inl)
{
#ifdef TEST_ENG_OPENSSL_RC4_P_CIPHER
fprintf(stderr, "(TEST_ENG_OPENSSL_RC4) test_cipher() called\n");
@@ -251,6 +257,7 @@ static const EVP_CIPHER test_r4_cipher=
sizeof(TEST_RC4_KEY),
NULL,
NULL,
+ NULL,
NULL
};
static const EVP_CIPHER test_r4_40_cipher=
@@ -264,6 +271,7 @@ static const EVP_CIPHER test_r4_40_cipher=
sizeof(TEST_RC4_KEY),
NULL,
NULL,
+ NULL,
NULL
};
static int openssl_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
diff --git a/crypto/engine/eng_padlock.c b/crypto/engine/eng_padlock.c
deleted file mode 100644
index 4f64a06fb0..0000000000
--- a/crypto/engine/eng_padlock.c
+++ /dev/null
@@ -1,1091 +0,0 @@
-/*
- * Support for VIA PadLock Advanced Cryptography Engine (ACE)
- * Written by Michal Ludvig <michal@logix.cz>
- * http://www.logix.cz/michal
- *
- * Big thanks to Andy Polyakov for a help with optimization,
- * assembler fixes, port to MS Windows and a lot of other
- * valuable work on this engine!
- */
-
-/* ====================================================================
- * Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * 3. All advertising materials mentioning features or use of this
- * software must display the following acknowledgment:
- * "This product includes software developed by the OpenSSL Project
- * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
- *
- * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
- * endorse or promote products derived from this software without
- * prior written permission. For written permission, please contact
- * 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/crypto.h>
-#include <openssl/dso.h>
-#include <openssl/engine.h>
-#include <openssl/evp.h>
-#include <openssl/aes.h>
-#include <openssl/rand.h>
-
-#ifndef OPENSSL_NO_HW
-#ifndef OPENSSL_NO_HW_PADLOCK
-
-/* Attempt to have a single source for both 0.9.7 and 0.9.8 :-) */
-#if (OPENSSL_VERSION_NUMBER >= 0x00908000L)
-# ifndef OPENSSL_NO_DYNAMIC_ENGINE
-# define DYNAMIC_ENGINE
-# endif
-#elif (OPENSSL_VERSION_NUMBER >= 0x00907000L)
-# ifdef ENGINE_DYNAMIC_SUPPORT
-# define DYNAMIC_ENGINE
-# endif
-#else
-# error "Only OpenSSL >= 0.9.7 is supported"
-#endif
-
-/* VIA PadLock AES is available *ONLY* on some x86 CPUs.
- Not only that it doesn't exist elsewhere, but it
- even can't be compiled on other platforms!
-
- In addition, because of the heavy use of inline assembler,
- compiler choice is limited to GCC and Microsoft C. */
-#undef COMPILE_HW_PADLOCK
-#if !defined(I386_ONLY) && !defined(OPENSSL_NO_INLINE_ASM)
-# if defined(__i386__) || defined(__i386) || defined(_M_IX86)
-# define COMPILE_HW_PADLOCK
-static ENGINE *ENGINE_padlock (void);
-# endif
-#endif
-
-void ENGINE_load_padlock (void)
-{
-/* On non-x86 CPUs it just returns. */
-#ifdef COMPILE_HW_PADLOCK
- ENGINE *toadd = ENGINE_padlock ();
- if (!toadd) return;
- ENGINE_add (toadd);
- ENGINE_free (toadd);
- ERR_clear_error ();
-#endif
-}
-
-#ifdef COMPILE_HW_PADLOCK
-/* We do these includes here to avoid header problems on platforms that
- do not have the VIA padlock anyway... */
-#ifdef _MSC_VER
-# include <malloc.h>
-# define alloca _alloca
-#else
-# include <stdlib.h>
-#endif
-
-/* Function for ENGINE detection and control */
-static int padlock_available(void);
-static int padlock_init(ENGINE *e);
-
-/* RNG Stuff */
-static RAND_METHOD padlock_rand;
-
-/* Cipher Stuff */
-static int padlock_ciphers(ENGINE *e, const EVP_CIPHER **cipher, const int **nids, int nid);
-
-/* Engine names */
-static const char *padlock_id = "padlock";
-static char padlock_name[100];
-
-/* Available features */
-static int padlock_use_ace = 0; /* Advanced Cryptography Engine */
-static int padlock_use_rng = 0; /* Random Number Generator */
-static int padlock_aes_align_required = 1;
-
-/* ===== Engine "management" functions ===== */
-
-/* Prepare the ENGINE structure for registration */
-static int
-padlock_bind_helper(ENGINE *e)
-{
- /* Check available features */
- padlock_available();
-
-#if 1 /* disable RNG for now, see commentary in vicinity of RNG code */
- padlock_use_rng=0;
-#endif
-
- /* Generate a nice engine name with available features */
- BIO_snprintf(padlock_name, sizeof(padlock_name),
- "VIA PadLock (%s, %s)",
- padlock_use_rng ? "RNG" : "no-RNG",
- padlock_use_ace ? "ACE" : "no-ACE");
-
- /* Register everything or return with an error */
- if (!ENGINE_set_id(e, padlock_id) ||
- !ENGINE_set_name(e, padlock_name) ||
-
- !ENGINE_set_init_function(e, padlock_init) ||
-
- (padlock_use_ace && !ENGINE_set_ciphers (e, padlock_ciphers)) ||
- (padlock_use_rng && !ENGINE_set_RAND (e, &padlock_rand))) {
- return 0;
- }
-
- /* Everything looks good */
- return 1;
-}
-
-/* Constructor */
-static ENGINE *
-ENGINE_padlock(void)
-{
- ENGINE *eng = ENGINE_new();
-
- if (!eng) {
- return NULL;
- }
-
- if (!padlock_bind_helper(eng)) {
- ENGINE_free(eng);
- return NULL;
- }
-
- return eng;
-}
-
-/* Check availability of the engine */
-static int
-padlock_init(ENGINE *e)
-{
- return (padlock_use_rng || padlock_use_ace);
-}
-
-/* This stuff is needed if this ENGINE is being compiled into a self-contained
- * shared-library.
- */
-#ifdef DYNAMIC_ENGINE
-static int
-padlock_bind_fn(ENGINE *e, const char *id)
-{
- if (id && (strcmp(id, padlock_id) != 0)) {
- return 0;
- }
-
- if (!padlock_bind_helper(e)) {
- return 0;
- }
-
- return 1;
-}
-
-IMPLEMENT_DYNAMIC_CHECK_FN ();
-IMPLEMENT_DYNAMIC_BIND_FN (padlock_bind_fn);
-#endif /* DYNAMIC_ENGINE */
-
-/* ===== Here comes the "real" engine ===== */
-
-/* Some AES-related constants */
-#define AES_BLOCK_SIZE 16
-#define AES_KEY_SIZE_128 16
-#define AES_KEY_SIZE_192 24
-#define AES_KEY_SIZE_256 32
-
-/* Here we store the status information relevant to the
- current context. */
-/* BIG FAT WARNING:
- * Inline assembler in PADLOCK_XCRYPT_ASM()
- * depends on the order of items in this structure.
- * Don't blindly modify, reorder, etc!
- */
-struct padlock_cipher_data
-{
- unsigned char iv[AES_BLOCK_SIZE]; /* Initialization vector */
- union { unsigned int pad[4];
- struct {
- int rounds:4;
- int algo:3;
- int keygen:1;
- int interm:1;
- int encdec:1;
- int ksize:2;
- } b;
- } cword; /* Control word */
- AES_KEY ks; /* Encryption key */
-};
-
-/*
- * Essentially this variable belongs in thread local storage.
- * Having this variable global on the other hand can only cause
- * few bogus key reloads [if any at all on single-CPU system],
- * so we accept the penatly...
- */
-static volatile struct padlock_cipher_data *padlock_saved_context;
-
-/*
- * =======================================================
- * Inline assembler section(s).
- * =======================================================
- * Order of arguments is chosen to facilitate Windows port
- * using __fastcall calling convention. If you wish to add
- * more routines, keep in mind that first __fastcall
- * argument is passed in %ecx and second - in %edx.
- * =======================================================
- */
-#if defined(__GNUC__) && __GNUC__>=2
-/*
- * As for excessive "push %ebx"/"pop %ebx" found all over.
- * When generating position-independent code GCC won't let
- * us use "b" in assembler templates nor even respect "ebx"
- * in "clobber description." Therefore the trouble...
- */
-
-/* Helper function - check if a CPUID instruction
- is available on this CPU */
-static int
-padlock_insn_cpuid_available(void)
-{
- int result = -1;
-
- /* We're checking if the bit #21 of EFLAGS
- can be toggled. If yes = CPUID is available. */
- asm volatile (
- "pushf\n"
- "popl %%eax\n"
- "xorl $0x200000, %%eax\n"
- "movl %%eax, %%ecx\n"
- "andl $0x200000, %%ecx\n"
- "pushl %%eax\n"
- "popf\n"
- "pushf\n"
- "popl %%eax\n"
- "andl $0x200000, %%eax\n"
- "xorl %%eax, %%ecx\n"
- "movl %%ecx, %0\n"
- : "=r" (result) : : "eax", "ecx");
-
- return (result == 0);
-}
-
-/* Load supported features of the CPU to see if
- the PadLock is available. */
-static int
-padlock_available(void)
-{
- char vendor_string[16];
- unsigned int eax, edx;
-
- /* First check if the CPUID instruction is available at all... */
- if (! padlock_insn_cpuid_available())
- return 0;
-
- /* Are we running on the Centaur (VIA) CPU? */
- eax = 0x00000000;
- vendor_string[12] = 0;
- asm volatile (
- "pushl %%ebx\n"
- "cpuid\n"
- "movl %%ebx,(%%edi)\n"
- "movl %%edx,4(%%edi)\n"
- "movl %%ecx,8(%%edi)\n"
- "popl %%ebx"
- : "+a"(eax) : "D"(vendor_string) : "ecx", "edx");
- if (strcmp(vendor_string, "CentaurHauls") != 0)
- return 0;
-
- /* Check for Centaur Extended Feature Flags presence */
- eax = 0xC0000000;
- asm volatile ("pushl %%ebx; cpuid; popl %%ebx"
- : "+a"(eax) : : "ecx", "edx");
- if (eax < 0xC0000001)
- return 0;
-
- /* Read the Centaur Extended Feature Flags */
- eax = 0xC0000001;
- asm volatile ("pushl %%ebx; cpuid; popl %%ebx"
- : "+a"(eax), "=d"(edx) : : "ecx");
-
- /* Fill up some flags */
- padlock_use_ace = ((edx & (0x3<<6)) == (0x3<<6));
- padlock_use_rng = ((edx & (0x3<<2)) == (0x3<<2));
-
- return padlock_use_ace + padlock_use_rng;
-}
-
-/* Our own htonl()/ntohl() */
-static inline void
-padlock_bswapl(AES_KEY *ks)
-{
- size_t i = sizeof(ks->rd_key)/sizeof(ks->rd_key[0]);
- unsigned int *key = ks->rd_key;
-
- while (i--) {
- asm volatile ("bswapl %0" : "+r"(*key));
- key++;
- }
-}
-
-/* Force key reload from memory to the CPU microcode.
- Loading EFLAGS from the stack clears EFLAGS[30]
- which does the trick. */
-static inline void
-padlock_reload_key(void)
-{
- asm volatile ("pushfl; popfl");
-}
-
-/*
- * This is heuristic key context tracing. At first one
- * believes that one should use atomic swap instructions,
- * but it's not actually necessary. Point is that if
- * padlock_saved_context was changed by another thread
- * after we've read it and before we compare it with cdata,
- * our key *shall* be reloaded upon thread context switch
- * and we are therefore set in either case...
- */
-static inline void
-padlock_verify_context(struct padlock_cipher_data *cdata)
-{
- asm volatile (
- "pushfl\n"
-" bt $30,(%%esp)\n"
-" jnc 1f\n"
-" cmp %2,%1\n"
-" je 1f\n"
-" mov %2,%0\n"
-" popfl\n"
-" sub $4,%%esp\n"
-"1: add $4,%%esp"
- :"+m"(padlock_saved_context)
- : "r"(padlock_saved_context), "r"(cdata) : "cc");
-}
-
-/* Template for padlock_xcrypt_* modes */
-/* BIG FAT WARNING:
- * The offsets used with 'leal' instructions
- * describe items of the 'padlock_cipher_data'
- * structure.
- */
-#define PADLOCK_XCRYPT_ASM(name,rep_xcrypt) \
-static inline void *name(size_t cnt, \
- struct padlock_cipher_data *cdata, \
- void *out, const void *inp) \
-{ void *iv; \
- asm volatile ( "pushl %%ebx\n" \
- " leal 16(%0),%%edx\n" \
- " leal 32(%0),%%ebx\n" \
- rep_xcrypt "\n" \
- " popl %%ebx" \
- : "=a"(iv), "=c"(cnt), "=D"(out), "=S"(inp) \
- : "0"(cdata), "1"(cnt), "2"(out), "3"(inp) \
- : "edx", "cc"); \
- return iv; \
-}
-
-/* Generate all functions with appropriate opcodes */
-PADLOCK_XCRYPT_ASM(padlock_xcrypt_ecb, ".byte 0xf3,0x0f,0xa7,0xc8") /* rep xcryptecb */
-PADLOCK_XCRYPT_ASM(padlock_xcrypt_cbc, ".byte 0xf3,0x0f,0xa7,0xd0") /* rep xcryptcbc */
-PADLOCK_XCRYPT_ASM(padlock_xcrypt_cfb, ".byte 0xf3,0x0f,0xa7,0xe0") /* rep xcryptcfb */
-PADLOCK_XCRYPT_ASM(padlock_xcrypt_ofb, ".byte 0xf3,0x0f,0xa7,0xe8") /* rep xcryptofb */
-
-/* The RNG call itself */
-static inline unsigned int
-padlock_xstore(void *addr, unsigned int edx_in)
-{
- unsigned int eax_out;
-
- asm volatile (".byte 0x0f,0xa7,0xc0" /* xstore */
- : "=a"(eax_out),"=m"(*(unsigned *)addr)
- : "D"(addr), "d" (edx_in)
- );
-
- return eax_out;
-}
-
-/* Why not inline 'rep movsd'? I failed to find information on what
- * value in Direction Flag one can expect and consequently have to
- * apply "better-safe-than-sorry" approach and assume "undefined."
- * I could explicitly clear it and restore the original value upon
- * return from padlock_aes_cipher, but it's presumably too much
- * trouble for too little gain...
- *
- * In case you wonder 'rep xcrypt*' instructions above are *not*
- * affected by the Direction Flag and pointers advance toward
- * larger addresses unconditionally.
- */
-static inline unsigned char *
-padlock_memcpy(void *dst,const void *src,size_t n)
-{
- long *d=dst;
- const long *s=src;
-
- n /= sizeof(*d);
- do { *d++ = *s++; } while (--n);
-
- return dst;
-}
-
-#elif defined(_MSC_VER)
-/*
- * Unlike GCC these are real functions. In order to minimize impact
- * on performance we adhere to __fastcall calling convention in
- * order to get two first arguments passed through %ecx and %edx.
- * Which kind of suits very well, as instructions in question use
- * both %ecx and %edx as input:-)
- */
-#define REP_XCRYPT(code) \
- _asm _emit 0xf3 \
- _asm _emit 0x0f _asm _emit 0xa7 \
- _asm _emit code
-
-/* BIG FAT WARNING:
- * The offsets used with 'lea' instructions
- * describe items of the 'padlock_cipher_data'
- * structure.
- */
-#define PADLOCK_XCRYPT_ASM(name,code) \
-static void * __fastcall \
- name (size_t cnt, void *cdata, \
- void *outp, const void *inp) \
-{ _asm mov eax,edx \
- _asm lea edx,[eax+16] \
- _asm lea ebx,[eax+32] \
- _asm mov edi,outp \
- _asm mov esi,inp \
- REP_XCRYPT(code) \
-}
-
-PADLOCK_XCRYPT_ASM(padlock_xcrypt_ecb,0xc8)
-PADLOCK_XCRYPT_ASM(padlock_xcrypt_cbc,0xd0)
-PADLOCK_XCRYPT_ASM(padlock_xcrypt_cfb,0xe0)
-PADLOCK_XCRYPT_ASM(padlock_xcrypt_ofb,0xe8)
-
-static int __fastcall
-padlock_xstore(void *outp,unsigned int code)
-{ _asm mov edi,ecx
- _asm _emit 0x0f _asm _emit 0xa7 _asm _emit 0xc0
-}
-
-static void __fastcall
-padlock_reload_key(void)
-{ _asm pushfd _asm popfd }
-
-static void __fastcall
-padlock_verify_context(void *cdata)
-{ _asm {
- pushfd
- bt DWORD PTR[esp],30
- jnc skip
- cmp ecx,padlock_saved_context
- je skip
- mov padlock_saved_context,ecx
- popfd
- sub esp,4
- skip: add esp,4
- }
-}
-
-static int
-padlock_available(void)
-{ _asm {
- pushfd
- pop eax
- mov ecx,eax
- xor eax,1<<21
- push eax
- popfd
- pushfd
- pop eax
- xor eax,ecx
- bt eax,21
- jnc noluck
- mov eax,0
- cpuid
- xor eax,eax
- cmp ebx,'tneC'
- jne noluck
- cmp edx,'Hrua'
- jne noluck
- cmp ecx,'slua'
- jne noluck
- mov eax,0xC0000000
- cpuid
- mov edx,eax
- xor eax,eax
- cmp edx,0xC0000001
- jb noluck
- mov eax,0xC0000001
- cpuid
- xor eax,eax
- bt edx,6
- jnc skip_a
- bt edx,7
- jnc skip_a
- mov padlock_use_ace,1
- inc eax
- skip_a: bt edx,2
- jnc skip_r
- bt edx,3
- jnc skip_r
- mov padlock_use_rng,1
- inc eax
- skip_r:
- noluck:
- }
-}
-
-static void __fastcall
-padlock_bswapl(void *key)
-{ _asm {
- pushfd
- cld
- mov esi,ecx
- mov edi,ecx
- mov ecx,60
- up: lodsd
- bswap eax
- stosd
- loop up
- popfd
- }
-}
-
-/* MS actually specifies status of Direction Flag and compiler even
- * manages to compile following as 'rep movsd' all by itself...
- */
-#define padlock_memcpy(o,i,n) ((unsigned char *)memcpy((o),(i),(n)&~3U))
-#endif
-
-/* ===== AES encryption/decryption ===== */
-
-#if defined(NID_aes_128_cfb128) && ! defined (NID_aes_128_cfb)
-#define NID_aes_128_cfb NID_aes_128_cfb128
-#endif
-
-#if defined(NID_aes_128_ofb128) && ! defined (NID_aes_128_ofb)
-#define NID_aes_128_ofb NID_aes_128_ofb128
-#endif
-
-#if defined(NID_aes_192_cfb128) && ! defined (NID_aes_192_cfb)
-#define NID_aes_192_cfb NID_aes_192_cfb128
-#endif
-
-#if defined(NID_aes_192_ofb128) && ! defined (NID_aes_192_ofb)
-#define NID_aes_192_ofb NID_aes_192_ofb128
-#endif
-
-#if defined(NID_aes_256_cfb128) && ! defined (NID_aes_256_cfb)
-#define NID_aes_256_cfb NID_aes_256_cfb128
-#endif
-
-#if defined(NID_aes_256_ofb128) && ! defined (NID_aes_256_ofb)
-#define NID_aes_256_ofb NID_aes_256_ofb128
-#endif
-
-/* List of supported ciphers. */
-static int padlock_cipher_nids[] = {
- NID_aes_128_ecb,
- NID_aes_128_cbc,
- NID_aes_128_cfb,
- NID_aes_128_ofb,
-
- NID_aes_192_ecb,
- NID_aes_192_cbc,
-#if 0
- NID_aes_192_cfb, /* FIXME: AES192/256 CFB/OFB don't work. */
- NID_aes_192_ofb,
-#endif
-
- NID_aes_256_ecb,
- NID_aes_256_cbc,
-#if 0
- NID_aes_256_cfb,
- NID_aes_256_ofb,
-#endif
-};
-static int padlock_cipher_nids_num = (sizeof(padlock_cipher_nids)/
- sizeof(padlock_cipher_nids[0]));
-
-/* Function prototypes ... */
-static int padlock_aes_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
- const unsigned char *iv, int enc);
-static int padlock_aes_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
- const unsigned char *in, size_t nbytes);
-
-#define NEAREST_ALIGNED(ptr) ( (unsigned char *)(ptr) + \
- ( (0x10 - ((size_t)(ptr) & 0x0F)) & 0x0F ) )
-#define ALIGNED_CIPHER_DATA(ctx) ((struct padlock_cipher_data *)\
- NEAREST_ALIGNED(ctx->cipher_data))
-
-/* Declaring so many ciphers by hand would be a pain.
- Instead introduce a bit of preprocessor magic :-) */
-#define DECLARE_AES_EVP(ksize,lmode,umode) \
-static const EVP_CIPHER padlock_aes_##ksize##_##lmode = { \
- NID_aes_##ksize##_##lmode, \
- AES_BLOCK_SIZE, \
- AES_KEY_SIZE_##ksize, \
- AES_BLOCK_SIZE, \
- 0 | EVP_CIPH_##umode##_MODE, \
- padlock_aes_init_key, \
- padlock_aes_cipher, \
- NULL, \
- sizeof(struct padlock_cipher_data) + 16, \
- EVP_CIPHER_set_asn1_iv, \
- EVP_CIPHER_get_asn1_iv, \
- NULL, \
- NULL \
-}
-
-DECLARE_AES_EVP(128,ecb,ECB);
-DECLARE_AES_EVP(128,cbc,CBC);
-DECLARE_AES_EVP(128,cfb,CFB);
-DECLARE_AES_EVP(128,ofb,OFB);
-
-DECLARE_AES_EVP(192,ecb,ECB);
-DECLARE_AES_EVP(192,cbc,CBC);
-DECLARE_AES_EVP(192,cfb,CFB);
-DECLARE_AES_EVP(192,ofb,OFB);
-
-DECLARE_AES_EVP(256,ecb,ECB);
-DECLARE_AES_EVP(256,cbc,CBC);
-DECLARE_AES_EVP(256,cfb,CFB);
-DECLARE_AES_EVP(256,ofb,OFB);
-
-static int
-padlock_ciphers (ENGINE *e, const EVP_CIPHER **cipher, const int **nids, int nid)
-{
- /* No specific cipher => return a list of supported nids ... */
- if (!cipher) {
- *nids = padlock_cipher_nids;
- return padlock_cipher_nids_num;
- }
-
- /* ... or the requested "cipher" otherwise */
- switch (nid) {
- case NID_aes_128_ecb:
- *cipher = &padlock_aes_128_ecb;
- break;
- case NID_aes_128_cbc:
- *cipher = &padlock_aes_128_cbc;
- break;
- case NID_aes_128_cfb:
- *cipher = &padlock_aes_128_cfb;
- break;
- case NID_aes_128_ofb:
- *cipher = &padlock_aes_128_ofb;
- break;
-
- case NID_aes_192_ecb:
- *cipher = &padlock_aes_192_ecb;
- break;
- case NID_aes_192_cbc:
- *cipher = &padlock_aes_192_cbc;
- break;
- case NID_aes_192_cfb:
- *cipher = &padlock_aes_192_cfb;
- break;
- case NID_aes_192_ofb:
- *cipher = &padlock_aes_192_ofb;
- break;
-
- case NID_aes_256_ecb:
- *cipher = &padlock_aes_256_ecb;
- break;
- case NID_aes_256_cbc:
- *cipher = &padlock_aes_256_cbc;
- break;
- case NID_aes_256_cfb:
- *cipher = &padlock_aes_256_cfb;
- break;
- case NID_aes_256_ofb:
- *cipher = &padlock_aes_256_ofb;
- break;
-
- default:
- /* Sorry, we don't support this NID */
- *cipher = NULL;
- return 0;
- }
-
- return 1;
-}
-
-/* Prepare the encryption key for PadLock usage */
-static int
-padlock_aes_init_key (EVP_CIPHER_CTX *ctx, const unsigned char *key,
- const unsigned char *iv, int enc)
-{
- struct padlock_cipher_data *cdata;
- int key_len = EVP_CIPHER_CTX_key_length(ctx) * 8;
-
- if (key==NULL) return 0; /* ERROR */
-
- cdata = ALIGNED_CIPHER_DATA(ctx);
- memset(cdata, 0, sizeof(struct padlock_cipher_data));
-
- /* Prepare Control word. */
- cdata->cword.b.encdec = (ctx->encrypt == 0);
- cdata->cword.b.rounds = 10 + (key_len - 128) / 32;
- cdata->cword.b.ksize = (key_len - 128) / 64;
-
- switch(key_len) {
- case 128:
- /* PadLock can generate an extended key for
- AES128 in hardware */
- memcpy(cdata->ks.rd_key, key, AES_KEY_SIZE_128);
- cdata->cword.b.keygen = 0;
- break;
-
- case 192:
- case 256:
- /* Generate an extended AES key in software.
- Needed for AES192/AES256 */
- /* Well, the above applies to Stepping 8 CPUs
- and is listed as hardware errata. They most
- likely will fix it at some point and then
- a check for stepping would be due here. */
- if (enc)
- AES_set_encrypt_key(key, key_len, &cdata->ks);
- else
- AES_set_decrypt_key(key, key_len, &cdata->ks);
-#ifndef AES_ASM
- /* OpenSSL C functions use byte-swapped extended key. */
- padlock_bswapl(&cdata->ks);
-#endif
- cdata->cword.b.keygen = 1;
- break;
-
- default:
- /* ERROR */
- return 0;
- }
-
- /*
- * This is done to cover for cases when user reuses the
- * context for new key. The catch is that if we don't do
- * this, padlock_eas_cipher might proceed with old key...
- */
- padlock_reload_key ();
-
- return 1;
-}
-
-/*
- * Simplified version of padlock_aes_cipher() used when
- * 1) both input and output buffers are at aligned addresses.
- * or when
- * 2) running on a newer CPU that doesn't require aligned buffers.
- */
-static int
-padlock_aes_cipher_omnivorous(EVP_CIPHER_CTX *ctx, unsigned char *out_arg,
- const unsigned char *in_arg, size_t nbytes)
-{
- struct padlock_cipher_data *cdata;
- void *iv;
-
- cdata = ALIGNED_CIPHER_DATA(ctx);
- padlock_verify_context(cdata);
-
- switch (EVP_CIPHER_CTX_mode(ctx)) {
- case EVP_CIPH_ECB_MODE:
- padlock_xcrypt_ecb(nbytes/AES_BLOCK_SIZE, cdata, out_arg, in_arg);
- break;
-
- case EVP_CIPH_CBC_MODE:
- memcpy(cdata->iv, ctx->iv, AES_BLOCK_SIZE);
- iv = padlock_xcrypt_cbc(nbytes/AES_BLOCK_SIZE, cdata, out_arg, in_arg);
- memcpy(ctx->iv, iv, AES_BLOCK_SIZE);
- break;
-
- case EVP_CIPH_CFB_MODE:
- memcpy(cdata->iv, ctx->iv, AES_BLOCK_SIZE);
- iv = padlock_xcrypt_cfb(nbytes/AES_BLOCK_SIZE, cdata, out_arg, in_arg);
- memcpy(ctx->iv, iv, AES_BLOCK_SIZE);
- break;
-
- case EVP_CIPH_OFB_MODE:
- memcpy(cdata->iv, ctx->iv, AES_BLOCK_SIZE);
- padlock_xcrypt_ofb(nbytes/AES_BLOCK_SIZE, cdata, out_arg, in_arg);
- memcpy(ctx->iv, cdata->iv, AES_BLOCK_SIZE);
- break;
-
- default:
- return 0;
- }
-
- memset(cdata->iv, 0, AES_BLOCK_SIZE);
-
- return 1;
-}
-
-#ifndef PADLOCK_CHUNK
-# define PADLOCK_CHUNK 4096 /* Must be a power of 2 larger than 16 */
-#endif
-#if PADLOCK_CHUNK<16 || PADLOCK_CHUNK&(PADLOCK_CHUNK-1)
-# error "insane PADLOCK_CHUNK..."
-#endif
-
-/* Re-align the arguments to 16-Bytes boundaries and run the
- encryption function itself. This function is not AES-specific. */
-static int
-padlock_aes_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out_arg,
- const unsigned char *in_arg, size_t nbytes)
-{
- struct padlock_cipher_data *cdata;
- const void *inp;
- unsigned char *out;
- void *iv;
- int inp_misaligned, out_misaligned, realign_in_loop;
- size_t chunk, allocated=0;
-
- if (nbytes == 0)
- return 1;
- if (nbytes % AES_BLOCK_SIZE)
- return 0; /* are we expected to do tail processing? */
-
- /* VIA promises CPUs that won't require alignment in the future.
- For now padlock_aes_align_required is initialized to 1 and
- the condition is never met... */
- if (!padlock_aes_align_required)
- return padlock_aes_cipher_omnivorous(ctx, out_arg, in_arg, nbytes);
-
- inp_misaligned = (((size_t)in_arg) & 0x0F);
- out_misaligned = (((size_t)out_arg) & 0x0F);
-
- /* Note that even if output is aligned and input not,
- * I still prefer to loop instead of copy the whole
- * input and then encrypt in one stroke. This is done
- * in order to improve L1 cache utilization... */
- realign_in_loop = out_misaligned|inp_misaligned;
-
- if (!realign_in_loop)
- return padlock_aes_cipher_omnivorous(ctx, out_arg, in_arg, nbytes);
-
- /* this takes one "if" out of the loops */
- chunk = nbytes;
- chunk %= PADLOCK_CHUNK;
- if (chunk==0) chunk = PADLOCK_CHUNK;
-
- if (out_misaligned) {
- /* optmize for small input */
- allocated = (chunk<nbytes?PADLOCK_CHUNK:nbytes);
- out = alloca(0x10 + allocated);
- out = NEAREST_ALIGNED(out);
- }
- else
- out = out_arg;
-
- cdata = ALIGNED_CIPHER_DATA(ctx);
- padlock_verify_context(cdata);
-
- switch (EVP_CIPHER_CTX_mode(ctx)) {
- case EVP_CIPH_ECB_MODE:
- do {
- if (inp_misaligned)
- inp = padlock_memcpy(out, in_arg, chunk);
- else
- inp = in_arg;
- in_arg += chunk;
-
- padlock_xcrypt_ecb(chunk/AES_BLOCK_SIZE, cdata, out, inp);
-
- if (out_misaligned)
- out_arg = padlock_memcpy(out_arg, out, chunk) + chunk;
- else
- out = out_arg+=chunk;
-
- nbytes -= chunk;
- chunk = PADLOCK_CHUNK;
- } while (nbytes);
- break;
-
- case EVP_CIPH_CBC_MODE:
- memcpy(cdata->iv, ctx->iv, AES_BLOCK_SIZE);
- goto cbc_shortcut;
- do {
- if (iv != cdata->iv)
- memcpy(cdata->iv, iv, AES_BLOCK_SIZE);
- chunk = PADLOCK_CHUNK;
- cbc_shortcut: /* optimize for small input */
- if (inp_misaligned)
- inp = padlock_memcpy(out, in_arg, chunk);
- else
- inp = in_arg;
- in_arg += chunk;
-
- iv = padlock_xcrypt_cbc(chunk/AES_BLOCK_SIZE, cdata, out, inp);
-
- if (out_misaligned)
- out_arg = padlock_memcpy(out_arg, out, chunk) + chunk;
- else
- out = out_arg+=chunk;
-
- } while (nbytes -= chunk);
- memcpy(ctx->iv, iv, AES_BLOCK_SIZE);
- break;
-
- case EVP_CIPH_CFB_MODE:
- memcpy (cdata->iv, ctx->iv, AES_BLOCK_SIZE);
- goto cfb_shortcut;
- do {
- if (iv != cdata->iv)
- memcpy(cdata->iv, iv, AES_BLOCK_SIZE);
- chunk = PADLOCK_CHUNK;
- cfb_shortcut: /* optimize for small input */
- if (inp_misaligned)
- inp = padlock_memcpy(out, in_arg, chunk);
- else
- inp = in_arg;
- in_arg += chunk;
-
- iv = padlock_xcrypt_cfb(chunk/AES_BLOCK_SIZE, cdata, out, inp);
-
- if (out_misaligned)
- out_arg = padlock_memcpy(out_arg, out, chunk) + chunk;
- else
- out = out_arg+=chunk;
-
- } while (nbytes -= chunk);
- memcpy(ctx->iv, iv, AES_BLOCK_SIZE);
- break;
-
- case EVP_CIPH_OFB_MODE:
- memcpy(cdata->iv, ctx->iv, AES_BLOCK_SIZE);
- do {
- if (inp_misaligned)
- inp = padlock_memcpy(out, in_arg, chunk);
- else
- inp = in_arg;
- in_arg += chunk;
-
- padlock_xcrypt_ofb(chunk/AES_BLOCK_SIZE, cdata, out, inp);
-
- if (out_misaligned)
- out_arg = padlock_memcpy(out_arg, out, chunk) + chunk;
- else
- out = out_arg+=chunk;
-
- nbytes -= chunk;
- chunk = PADLOCK_CHUNK;
- } while (nbytes);
- memcpy(ctx->iv, cdata->iv, AES_BLOCK_SIZE);
- break;
-
- default:
- return 0;
- }
-
- /* Clean the realign buffer if it was used */
- if (out_misaligned) {
- volatile unsigned long *p=(void *)out;
- size_t n = allocated/sizeof(*p);
- while (n--) *p++=0;
- }
-
- memset(cdata->iv, 0, AES_BLOCK_SIZE);
-
- return 1;
-}
-
-/* ===== Random Number Generator ===== */
-/*
- * This code is not engaged. The reason is that it does not comply
- * with recommendations for VIA RNG usage for secure applications
- * (posted at http://www.via.com.tw/en/viac3/c3.jsp) nor does it
- * provide meaningful error control...
- */
-/* Wrapper that provides an interface between the API and
- the raw PadLock RNG */
-static int
-padlock_rand_bytes(unsigned char *output, int count)
-{
- unsigned int eax, buf;
-
- while (count >= 8) {
- eax = padlock_xstore(output, 0);
- if (!(eax&(1<<6))) return 0; /* RNG disabled */
- /* this ---vv--- covers DC bias, Raw Bits and String Filter */
- if (eax&(0x1F<<10)) return 0;
- if ((eax&0x1F)==0) continue; /* no data, retry... */
- if ((eax&0x1F)!=8) return 0; /* fatal failure... */
- output += 8;
- count -= 8;
- }
- while (count > 0) {
- eax = padlock_xstore(&buf, 3);
- if (!(eax&(1<<6))) return 0; /* RNG disabled */
- /* this ---vv--- covers DC bias, Raw Bits and String Filter */
- if (eax&(0x1F<<10)) return 0;
- if ((eax&0x1F)==0) continue; /* no data, retry... */
- if ((eax&0x1F)!=1) return 0; /* fatal failure... */
- *output++ = (unsigned char)buf;
- count--;
- }
- *(volatile unsigned int *)&buf=0;
-
- return 1;
-}
-
-/* Dummy but necessary function */
-static int
-padlock_rand_status(void)
-{
- return 1;
-}
-
-/* Prepare structure for registration */
-static RAND_METHOD padlock_rand = {
- NULL, /* seed */
- padlock_rand_bytes, /* bytes */
- NULL, /* cleanup */
- NULL, /* add */
- padlock_rand_bytes, /* pseudorand */
- padlock_rand_status, /* rand status */
-};
-
-#endif /* COMPILE_HW_PADLOCK */
-
-#endif /* !OPENSSL_NO_HW_PADLOCK */
-#endif /* !OPENSSL_NO_HW */
diff --git a/crypto/engine/eng_pkey.c b/crypto/engine/eng_pkey.c
index bc8b21abec..1dfa2e3664 100644
--- a/crypto/engine/eng_pkey.c
+++ b/crypto/engine/eng_pkey.c
@@ -69,6 +69,13 @@ int ENGINE_set_load_pubkey_function(ENGINE *e, ENGINE_LOAD_KEY_PTR loadpub_f)
return 1;
}
+int ENGINE_set_load_ssl_client_cert_function(ENGINE *e,
+ ENGINE_SSL_CLIENT_CERT_PTR loadssl_f)
+ {
+ e->load_ssl_client_cert = loadssl_f;
+ return 1;
+ }
+
ENGINE_LOAD_KEY_PTR ENGINE_get_load_privkey_function(const ENGINE *e)
{
return e->load_privkey;
@@ -79,6 +86,11 @@ ENGINE_LOAD_KEY_PTR ENGINE_get_load_pubkey_function(const ENGINE *e)
return e->load_pubkey;
}
+ENGINE_SSL_CLIENT_CERT_PTR ENGINE_get_ssl_client_cert_function(const ENGINE *e)
+ {
+ return e->load_ssl_client_cert;
+ }
+
/* API functions to load public/private keys */
EVP_PKEY *ENGINE_load_private_key(ENGINE *e, const char *key_id,
@@ -152,3 +164,33 @@ EVP_PKEY *ENGINE_load_public_key(ENGINE *e, const char *key_id,
}
return pkey;
}
+
+int ENGINE_load_ssl_client_cert(ENGINE *e, SSL *s,
+ STACK_OF(X509_NAME) *ca_dn, X509 **pcert, EVP_PKEY **ppkey,
+ STACK_OF(X509) **pother, UI_METHOD *ui_method, void *callback_data)
+ {
+
+ if(e == NULL)
+ {
+ ENGINEerr(ENGINE_F_ENGINE_LOAD_SSL_CLIENT_CERT,
+ ERR_R_PASSED_NULL_PARAMETER);
+ return 0;
+ }
+ CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
+ if(e->funct_ref == 0)
+ {
+ CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
+ ENGINEerr(ENGINE_F_ENGINE_LOAD_SSL_CLIENT_CERT,
+ ENGINE_R_NOT_INITIALISED);
+ return 0;
+ }
+ CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
+ if (!e->load_ssl_client_cert)
+ {
+ ENGINEerr(ENGINE_F_ENGINE_LOAD_SSL_CLIENT_CERT,
+ ENGINE_R_NO_LOAD_FUNCTION);
+ return 0;
+ }
+ return e->load_ssl_client_cert(e, s, ca_dn, pcert, ppkey, pother,
+ ui_method, callback_data);
+ }
diff --git a/crypto/engine/eng_table.c b/crypto/engine/eng_table.c
index a83c3899ee..954b4d7970 100644
--- a/crypto/engine/eng_table.c
+++ b/crypto/engine/eng_table.c
@@ -70,12 +70,22 @@ typedef struct st_engine_pile
int uptodate;
} ENGINE_PILE;
+DECLARE_LHASH_OF(ENGINE_PILE);
+
/* The type exposed in eng_int.h */
struct st_engine_table
{
- LHASH piles;
+ LHASH_OF(ENGINE_PILE) piles;
}; /* ENGINE_TABLE */
+
+typedef struct st_engine_pile_doall
+ {
+ engine_table_doall_cb *cb;
+ void *arg;
+ } ENGINE_PILE_DOALL;
+
+
/* Global flags (ENGINE_TABLE_FLAG_***). */
static unsigned int table_flags = 0;
@@ -84,6 +94,7 @@ unsigned int ENGINE_get_table_flags(void)
{
return table_flags;
}
+
void ENGINE_set_table_flags(unsigned int flags)
{
table_flags = flags;
@@ -94,19 +105,21 @@ static unsigned long engine_pile_hash(const ENGINE_PILE *c)
{
return c->nid;
}
+
static int engine_pile_cmp(const ENGINE_PILE *a, const ENGINE_PILE *b)
{
return a->nid - b->nid;
}
-static IMPLEMENT_LHASH_HASH_FN(engine_pile_hash, const ENGINE_PILE *)
-static IMPLEMENT_LHASH_COMP_FN(engine_pile_cmp, const ENGINE_PILE *)
+static IMPLEMENT_LHASH_HASH_FN(engine_pile, ENGINE_PILE)
+static IMPLEMENT_LHASH_COMP_FN(engine_pile, ENGINE_PILE)
+
static int int_table_check(ENGINE_TABLE **t, int create)
{
- LHASH *lh;
+ LHASH_OF(ENGINE_PILE) *lh;
+
if(*t) return 1;
if(!create) return 0;
- if((lh = lh_new(LHASH_HASH_FN(engine_pile_hash),
- LHASH_COMP_FN(engine_pile_cmp))) == NULL)
+ if((lh = lh_ENGINE_PILE_new()) == NULL)
return 0;
*t = (ENGINE_TABLE *)lh;
return 1;
@@ -130,12 +143,12 @@ int engine_table_register(ENGINE_TABLE **table, ENGINE_CLEANUP_CB *cleanup,
while(num_nids--)
{
tmplate.nid = *nids;
- fnd = lh_retrieve(&(*table)->piles, &tmplate);
+ fnd = lh_ENGINE_PILE_retrieve(&(*table)->piles, &tmplate);
if(!fnd)
{
fnd = OPENSSL_malloc(sizeof(ENGINE_PILE));
if(!fnd) goto end;
- fnd->uptodate = 0;
+ fnd->uptodate = 1;
fnd->nid = *nids;
fnd->sk = sk_ENGINE_new_null();
if(!fnd->sk)
@@ -144,15 +157,15 @@ int engine_table_register(ENGINE_TABLE **table, ENGINE_CLEANUP_CB *cleanup,
goto end;
}
fnd->funct = NULL;
- lh_insert(&(*table)->piles, fnd);
+ (void)lh_ENGINE_PILE_insert(&(*table)->piles, fnd);
}
/* A registration shouldn't add duplciate entries */
- sk_ENGINE_delete_ptr(fnd->sk, e);
+ (void)sk_ENGINE_delete_ptr(fnd->sk, e);
/* if 'setdefault', this ENGINE goes to the head of the list */
if(!sk_ENGINE_push(fnd->sk, e))
goto end;
/* "touch" this ENGINE_PILE */
- fnd->uptodate = 1;
+ fnd->uptodate = 0;
if(setdefault)
{
if(!engine_unlocked_init(e))
@@ -164,6 +177,7 @@ int engine_table_register(ENGINE_TABLE **table, ENGINE_CLEANUP_CB *cleanup,
if(fnd->funct)
engine_unlocked_finish(fnd->funct, 0);
fnd->funct = e;
+ fnd->uptodate = 1;
}
nids++;
}
@@ -172,15 +186,14 @@ end:
CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
return ret;
}
-static void int_unregister_cb(ENGINE_PILE *pile, ENGINE *e)
+static void int_unregister_cb_doall_arg(ENGINE_PILE *pile, ENGINE *e)
{
int n;
/* Iterate the 'c->sk' stack removing any occurance of 'e' */
while((n = sk_ENGINE_find(pile->sk, e)) >= 0)
{
- sk_ENGINE_delete(pile->sk, n);
- /* "touch" this ENGINE_CIPHER */
- pile->uptodate = 1;
+ (void)sk_ENGINE_delete(pile->sk, n);
+ pile->uptodate = 0;
}
if(pile->funct == e)
{
@@ -188,31 +201,35 @@ static void int_unregister_cb(ENGINE_PILE *pile, ENGINE *e)
pile->funct = NULL;
}
}
-static IMPLEMENT_LHASH_DOALL_ARG_FN(int_unregister_cb,ENGINE_PILE *,ENGINE *)
+static IMPLEMENT_LHASH_DOALL_ARG_FN(int_unregister_cb, ENGINE_PILE, ENGINE)
+
void engine_table_unregister(ENGINE_TABLE **table, ENGINE *e)
{
CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
if(int_table_check(table, 0))
- lh_doall_arg(&(*table)->piles,
- LHASH_DOALL_ARG_FN(int_unregister_cb), e);
+ lh_ENGINE_PILE_doall_arg(&(*table)->piles,
+ LHASH_DOALL_ARG_FN(int_unregister_cb),
+ ENGINE, e);
CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
}
-static void int_cleanup_cb(ENGINE_PILE *p)
+static void int_cleanup_cb_doall(ENGINE_PILE *p)
{
sk_ENGINE_free(p->sk);
if(p->funct)
engine_unlocked_finish(p->funct, 0);
OPENSSL_free(p);
}
-static IMPLEMENT_LHASH_DOALL_FN(int_cleanup_cb,ENGINE_PILE *)
+static IMPLEMENT_LHASH_DOALL_FN(int_cleanup_cb, ENGINE_PILE)
+
void engine_table_cleanup(ENGINE_TABLE **table)
{
CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
if(*table)
{
- lh_doall(&(*table)->piles, LHASH_DOALL_FN(int_cleanup_cb));
- lh_free(&(*table)->piles);
+ lh_ENGINE_PILE_doall(&(*table)->piles,
+ LHASH_DOALL_FN(int_cleanup_cb));
+ lh_ENGINE_PILE_free(&(*table)->piles);
*table = NULL;
}
CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
@@ -242,7 +259,7 @@ ENGINE *engine_table_select_tmp(ENGINE_TABLE **table, int nid, const char *f, in
* operations. But don't worry about a fprintf(stderr). */
if(!int_table_check(table, 0)) goto end;
tmplate.nid = nid;
- fnd = lh_retrieve(&(*table)->piles, &tmplate);
+ fnd = lh_ENGINE_PILE_retrieve(&(*table)->piles, &tmplate);
if(!fnd) goto end;
if(fnd->funct && engine_unlocked_init(fnd->funct))
{
@@ -313,3 +330,21 @@ end:
ERR_clear_error();
return ret;
}
+
+/* Table enumeration */
+
+static void int_cb_doall_arg(ENGINE_PILE *pile, ENGINE_PILE_DOALL *dall)
+ {
+ dall->cb(pile->nid, pile->sk, pile->funct, dall->arg);
+ }
+static IMPLEMENT_LHASH_DOALL_ARG_FN(int_cb, ENGINE_PILE,ENGINE_PILE_DOALL)
+
+void engine_table_doall(ENGINE_TABLE *table, engine_table_doall_cb *cb,
+ void *arg)
+ {
+ ENGINE_PILE_DOALL dall;
+ dall.cb = cb;
+ dall.arg = arg;
+ lh_ENGINE_PILE_doall_arg(&table->piles, LHASH_DOALL_ARG_FN(int_cb),
+ ENGINE_PILE_DOALL, &dall);
+ }
diff --git a/crypto/engine/engine.h b/crypto/engine/engine.h
index 14fefea474..f288a38685 100644
--- a/crypto/engine/engine.h
+++ b/crypto/engine/engine.h
@@ -88,7 +88,6 @@
#include <openssl/ecdsa.h>
#endif
#include <openssl/rand.h>
-#include <openssl/store.h>
#include <openssl/ui.h>
#include <openssl/err.h>
#endif
@@ -96,27 +95,12 @@
#include <openssl/ossl_typ.h>
#include <openssl/symhacks.h>
+#include <openssl/x509.h>
+
#ifdef __cplusplus
extern "C" {
#endif
-/* Fixups for missing algorithms */
-#ifdef OPENSSL_NO_RSA
-typedef void RSA_METHOD;
-#endif
-#ifdef OPENSSL_NO_DSA
-typedef void DSA_METHOD;
-#endif
-#ifdef OPENSSL_NO_DH
-typedef void DH_METHOD;
-#endif
-#ifdef OPENSSL_NO_ECDH
-typedef void ECDH_METHOD;
-#endif
-#ifdef OPENSSL_NO_ECDSA
-typedef void ECDSA_METHOD;
-#endif
-
/* These flags are used to control combinations of algorithm (methods)
* by bitwise "OR"ing. */
#define ENGINE_METHOD_RSA (unsigned int)0x0001
@@ -128,6 +112,8 @@ typedef void ECDSA_METHOD;
#define ENGINE_METHOD_CIPHERS (unsigned int)0x0040
#define ENGINE_METHOD_DIGESTS (unsigned int)0x0080
#define ENGINE_METHOD_STORE (unsigned int)0x0100
+#define ENGINE_METHOD_PKEY_METHS (unsigned int)0x0200
+#define ENGINE_METHOD_PKEY_ASN1_METHS (unsigned int)0x0400
/* Obvious all-or-nothing cases. */
#define ENGINE_METHOD_ALL (unsigned int)0xFFFF
#define ENGINE_METHOD_NONE (unsigned int)0x0000
@@ -295,6 +281,9 @@ typedef int (*ENGINE_CTRL_FUNC_PTR)(ENGINE *, int, long, void *, void (*f)(void)
/* Generic load_key function pointer */
typedef EVP_PKEY * (*ENGINE_LOAD_KEY_PTR)(ENGINE *, const char *,
UI_METHOD *ui_method, void *callback_data);
+typedef int (*ENGINE_SSL_CLIENT_CERT_PTR)(ENGINE *, SSL *ssl,
+ STACK_OF(X509_NAME) *ca_dn, X509 **pcert, EVP_PKEY **pkey,
+ STACK_OF(X509) **pother, UI_METHOD *ui_method, void *callback_data);
/* These callback types are for an ENGINE's handler for cipher and digest logic.
* These handlers have these prototypes;
* int foo(ENGINE *e, const EVP_CIPHER **cipher, const int **nids, int nid);
@@ -309,7 +298,8 @@ typedef EVP_PKEY * (*ENGINE_LOAD_KEY_PTR)(ENGINE *, const char *,
* parameter is non-NULL it is set to the size of the returned array. */
typedef int (*ENGINE_CIPHERS_PTR)(ENGINE *, const EVP_CIPHER **, const int **, int);
typedef int (*ENGINE_DIGESTS_PTR)(ENGINE *, const EVP_MD **, const int **, int);
-
+typedef int (*ENGINE_PKEY_METHS_PTR)(ENGINE *, EVP_PKEY_METHOD **, const int **, int);
+typedef int (*ENGINE_PKEY_ASN1_METHS_PTR)(ENGINE *, EVP_PKEY_ASN1_METHOD **, const int **, int);
/* 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 allowed access to the structure but it does not imply
@@ -341,13 +331,20 @@ void ENGINE_load_aep(void);
void ENGINE_load_atalla(void);
void ENGINE_load_chil(void);
void ENGINE_load_cswift(void);
-void ENGINE_load_gmp(void);
void ENGINE_load_nuron(void);
void ENGINE_load_sureware(void);
void ENGINE_load_ubsec(void);
+void ENGINE_load_padlock(void);
+void ENGINE_load_capi(void);
+#ifndef OPENSSL_NO_GMP
+void ENGINE_load_gmp(void);
+#endif
+#ifndef OPENSSL_NO_GOST
+void ENGINE_load_gost(void);
+#endif
#endif
void ENGINE_load_cryptodev(void);
-void ENGINE_load_padlock(void);
+void ENGINE_load_aesni(void);
void ENGINE_load_builtin_engines(void);
/* Get and set global flags (ENGINE_TABLE_FLAG_***) for the implementation
@@ -399,6 +396,14 @@ int ENGINE_register_digests(ENGINE *e);
void ENGINE_unregister_digests(ENGINE *e);
void ENGINE_register_all_digests(void);
+int ENGINE_register_pkey_meths(ENGINE *e);
+void ENGINE_unregister_pkey_meths(ENGINE *e);
+void ENGINE_register_all_pkey_meths(void);
+
+int ENGINE_register_pkey_asn1_meths(ENGINE *e);
+void ENGINE_unregister_pkey_asn1_meths(ENGINE *e);
+void ENGINE_register_all_pkey_asn1_meths(void);
+
/* These functions register all support from the above categories. Note, use of
* these functions can result in static linkage of code your application may not
* need. If you only need a subset of functionality, consider using more
@@ -474,8 +479,12 @@ int ENGINE_set_finish_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR finish_f);
int ENGINE_set_ctrl_function(ENGINE *e, ENGINE_CTRL_FUNC_PTR ctrl_f);
int ENGINE_set_load_privkey_function(ENGINE *e, ENGINE_LOAD_KEY_PTR loadpriv_f);
int ENGINE_set_load_pubkey_function(ENGINE *e, ENGINE_LOAD_KEY_PTR loadpub_f);
+int ENGINE_set_load_ssl_client_cert_function(ENGINE *e,
+ ENGINE_SSL_CLIENT_CERT_PTR loadssl_f);
int ENGINE_set_ciphers(ENGINE *e, ENGINE_CIPHERS_PTR f);
int ENGINE_set_digests(ENGINE *e, ENGINE_DIGESTS_PTR f);
+int ENGINE_set_pkey_meths(ENGINE *e, ENGINE_PKEY_METHS_PTR f);
+int ENGINE_set_pkey_asn1_meths(ENGINE *e, ENGINE_PKEY_ASN1_METHS_PTR f);
int ENGINE_set_flags(ENGINE *e, int flags);
int ENGINE_set_cmd_defns(ENGINE *e, const ENGINE_CMD_DEFN *defns);
/* These functions allow control over any per-structure ENGINE data. */
@@ -509,10 +518,19 @@ ENGINE_GEN_INT_FUNC_PTR ENGINE_get_finish_function(const ENGINE *e);
ENGINE_CTRL_FUNC_PTR ENGINE_get_ctrl_function(const ENGINE *e);
ENGINE_LOAD_KEY_PTR ENGINE_get_load_privkey_function(const ENGINE *e);
ENGINE_LOAD_KEY_PTR ENGINE_get_load_pubkey_function(const ENGINE *e);
+ENGINE_SSL_CLIENT_CERT_PTR ENGINE_get_ssl_client_cert_function(const ENGINE *e);
ENGINE_CIPHERS_PTR ENGINE_get_ciphers(const ENGINE *e);
ENGINE_DIGESTS_PTR ENGINE_get_digests(const ENGINE *e);
+ENGINE_PKEY_METHS_PTR ENGINE_get_pkey_meths(const ENGINE *e);
+ENGINE_PKEY_ASN1_METHS_PTR ENGINE_get_pkey_asn1_meths(const ENGINE *e);
const EVP_CIPHER *ENGINE_get_cipher(ENGINE *e, int nid);
const EVP_MD *ENGINE_get_digest(ENGINE *e, int nid);
+const EVP_PKEY_METHOD *ENGINE_get_pkey_meth(ENGINE *e, int nid);
+const EVP_PKEY_ASN1_METHOD *ENGINE_get_pkey_asn1_meth(ENGINE *e, int nid);
+const EVP_PKEY_ASN1_METHOD *ENGINE_get_pkey_asn1_meth_str(ENGINE *e,
+ const char *str, int len);
+const EVP_PKEY_ASN1_METHOD *ENGINE_pkey_asn1_find_str(ENGINE **pe,
+ const char *str, int len);
const ENGINE_CMD_DEFN *ENGINE_get_cmd_defns(const ENGINE *e);
int ENGINE_get_flags(const ENGINE *e);
@@ -544,6 +562,10 @@ EVP_PKEY *ENGINE_load_private_key(ENGINE *e, const char *key_id,
UI_METHOD *ui_method, void *callback_data);
EVP_PKEY *ENGINE_load_public_key(ENGINE *e, const char *key_id,
UI_METHOD *ui_method, void *callback_data);
+int ENGINE_load_ssl_client_cert(ENGINE *e, SSL *s,
+ STACK_OF(X509_NAME) *ca_dn, X509 **pcert, EVP_PKEY **ppkey,
+ STACK_OF(X509) **pother,
+ UI_METHOD *ui_method, void *callback_data);
/* This returns a pointer for the current ENGINE structure that
* is (by default) performing any RSA operations. The value returned
@@ -560,6 +582,8 @@ ENGINE *ENGINE_get_default_RAND(void);
* ciphering or digesting corresponding to "nid". */
ENGINE *ENGINE_get_cipher_engine(int nid);
ENGINE *ENGINE_get_digest_engine(int nid);
+ENGINE *ENGINE_get_pkey_meth_engine(int nid);
+ENGINE *ENGINE_get_pkey_asn1_meth_engine(int nid);
/* This sets a new default ENGINE structure for performing RSA
* operations. If the result is non-zero (success) then the ENGINE
@@ -575,6 +599,8 @@ int ENGINE_set_default_DH(ENGINE *e);
int ENGINE_set_default_RAND(ENGINE *e);
int ENGINE_set_default_ciphers(ENGINE *e);
int ENGINE_set_default_digests(ENGINE *e);
+int ENGINE_set_default_pkey_meths(ENGINE *e);
+int ENGINE_set_default_pkey_asn1_meths(ENGINE *e);
/* The combination "set" - the flags are bitwise "OR"d from the
* ENGINE_METHOD_*** defines above. As with the "ENGINE_register_complete()"
@@ -652,7 +678,7 @@ typedef struct st_dynamic_fns {
* can be fully instantiated with IMPLEMENT_DYNAMIC_CHECK_FN(). */
typedef unsigned long (*dynamic_v_check_fn)(unsigned long ossl_version);
#define IMPLEMENT_DYNAMIC_CHECK_FN() \
- unsigned long v_check(unsigned long v) { \
+ OPENSSL_EXPORT unsigned long v_check(unsigned long v) { \
if(v >= OSSL_DYNAMIC_OLDEST) return OSSL_DYNAMIC_VERSION; \
return 0; }
@@ -674,6 +700,7 @@ typedef unsigned long (*dynamic_v_check_fn)(unsigned long ossl_version);
typedef int (*dynamic_bind_engine)(ENGINE *e, const char *id,
const dynamic_fns *fns);
#define IMPLEMENT_DYNAMIC_BIND_FN(fn) \
+ OPENSSL_EXPORT \
int bind_engine(ENGINE *e, const char *id, const dynamic_fns *fns) { \
if(ENGINE_get_static_state() == fns->static_state) goto skip_cbs; \
if(!CRYPTO_set_mem_functions(fns->mem_fns.malloc_cb, \
@@ -718,6 +745,7 @@ void ERR_load_ENGINE_strings(void);
#define ENGINE_F_DYNAMIC_CTRL 180
#define ENGINE_F_DYNAMIC_GET_DATA_CTX 181
#define ENGINE_F_DYNAMIC_LOAD 182
+#define ENGINE_F_DYNAMIC_SET_DATA_CTX 183
#define ENGINE_F_ENGINE_ADD 105
#define ENGINE_F_ENGINE_BY_ID 106
#define ENGINE_F_ENGINE_CMD_IS_EXECUTABLE 170
@@ -725,18 +753,20 @@ void ERR_load_ENGINE_strings(void);
#define ENGINE_F_ENGINE_CTRL_CMD 178
#define ENGINE_F_ENGINE_CTRL_CMD_STRING 171
#define ENGINE_F_ENGINE_FINISH 107
-#define ENGINE_F_ENGINE_FREE 108
+#define ENGINE_F_ENGINE_FREE_UTIL 108
#define ENGINE_F_ENGINE_GET_CIPHER 185
#define ENGINE_F_ENGINE_GET_DEFAULT_TYPE 177
#define ENGINE_F_ENGINE_GET_DIGEST 186
#define ENGINE_F_ENGINE_GET_NEXT 115
+#define ENGINE_F_ENGINE_GET_PKEY_ASN1_METH 193
+#define ENGINE_F_ENGINE_GET_PKEY_METH 192
#define ENGINE_F_ENGINE_GET_PREV 116
#define ENGINE_F_ENGINE_INIT 119
#define ENGINE_F_ENGINE_LIST_ADD 120
#define ENGINE_F_ENGINE_LIST_REMOVE 121
#define ENGINE_F_ENGINE_LOAD_PRIVATE_KEY 150
#define ENGINE_F_ENGINE_LOAD_PUBLIC_KEY 151
-#define ENGINE_F_ENGINE_MODULE_INIT 187
+#define ENGINE_F_ENGINE_LOAD_SSL_CLIENT_CERT 194
#define ENGINE_F_ENGINE_NEW 122
#define ENGINE_F_ENGINE_REMOVE 123
#define ENGINE_F_ENGINE_SET_DEFAULT_STRING 189
@@ -745,11 +775,12 @@ void ERR_load_ENGINE_strings(void);
#define ENGINE_F_ENGINE_SET_NAME 130
#define ENGINE_F_ENGINE_TABLE_REGISTER 184
#define ENGINE_F_ENGINE_UNLOAD_KEY 152
+#define ENGINE_F_ENGINE_UNLOCKED_FINISH 191
#define ENGINE_F_ENGINE_UP_REF 190
#define ENGINE_F_INT_CTRL_HELPER 172
#define ENGINE_F_INT_ENGINE_CONFIGURE 188
+#define ENGINE_F_INT_ENGINE_MODULE_INIT 187
#define ENGINE_F_LOG_MESSAGE 141
-#define ENGINE_F_SET_DATA_CTX 183
/* Reason codes. */
#define ENGINE_R_ALREADY_LOADED 100
@@ -790,6 +821,7 @@ void ERR_load_ENGINE_strings(void);
#define ENGINE_R_RSA_NOT_IMPLEMENTED 141
#define ENGINE_R_UNIMPLEMENTED_CIPHER 146
#define ENGINE_R_UNIMPLEMENTED_DIGEST 147
+#define ENGINE_R_UNIMPLEMENTED_PUBLIC_KEY_METHOD 101
#define ENGINE_R_VERSION_INCOMPATIBILITY 145
#ifdef __cplusplus
diff --git a/crypto/engine/enginetest.c b/crypto/engine/enginetest.c
index c2d0297392..f4d70e7e0a 100644
--- a/crypto/engine/enginetest.c
+++ b/crypto/engine/enginetest.c
@@ -58,6 +58,7 @@
#include <stdio.h>
#include <string.h>
+#include <openssl/e_os2.h>
#ifdef OPENSSL_NO_ENGINE
int main(int argc, char *argv[])
@@ -66,13 +67,12 @@ int main(int argc, char *argv[])
return(0);
}
#else
-#include <openssl/e_os2.h>
#include <openssl/buffer.h>
#include <openssl/crypto.h>
#include <openssl/engine.h>
#include <openssl/err.h>
-static void display_engine_list()
+static void display_engine_list(void)
{
ENGINE *h;
int loop;
@@ -276,7 +276,7 @@ end:
ENGINE_cleanup();
CRYPTO_cleanup_all_ex_data();
ERR_free_strings();
- ERR_remove_state(0);
+ ERR_remove_thread_state(NULL);
CRYPTO_mem_leaks_fp(stderr);
return to_return;
}
diff --git a/crypto/engine/tb_asnmth.c b/crypto/engine/tb_asnmth.c
new file mode 100644
index 0000000000..75090339f7
--- /dev/null
+++ b/crypto/engine/tb_asnmth.c
@@ -0,0 +1,246 @@
+/* ====================================================================
+ * Copyright (c) 2006 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 "eng_int.h"
+#include "asn1_locl.h"
+#include <openssl/evp.h>
+
+/* If this symbol is defined then ENGINE_get_pkey_asn1_meth_engine(), the
+ * function that is used by EVP to hook in pkey_asn1_meth code and cache
+ * defaults (etc), will display brief debugging summaries to stderr with the
+ * 'nid'. */
+/* #define ENGINE_PKEY_ASN1_METH_DEBUG */
+
+static ENGINE_TABLE *pkey_asn1_meth_table = NULL;
+
+void ENGINE_unregister_pkey_asn1_meths(ENGINE *e)
+ {
+ engine_table_unregister(&pkey_asn1_meth_table, e);
+ }
+
+static void engine_unregister_all_pkey_asn1_meths(void)
+ {
+ engine_table_cleanup(&pkey_asn1_meth_table);
+ }
+
+int ENGINE_register_pkey_asn1_meths(ENGINE *e)
+ {
+ if(e->pkey_asn1_meths)
+ {
+ const int *nids;
+ int num_nids = e->pkey_asn1_meths(e, NULL, &nids, 0);
+ if(num_nids > 0)
+ return engine_table_register(&pkey_asn1_meth_table,
+ engine_unregister_all_pkey_asn1_meths, e, nids,
+ num_nids, 0);
+ }
+ return 1;
+ }
+
+void ENGINE_register_all_pkey_asn1_meths(void)
+ {
+ ENGINE *e;
+
+ for(e=ENGINE_get_first() ; e ; e=ENGINE_get_next(e))
+ ENGINE_register_pkey_asn1_meths(e);
+ }
+
+int ENGINE_set_default_pkey_asn1_meths(ENGINE *e)
+ {
+ if(e->pkey_asn1_meths)
+ {
+ const int *nids;
+ int num_nids = e->pkey_asn1_meths(e, NULL, &nids, 0);
+ if(num_nids > 0)
+ return engine_table_register(&pkey_asn1_meth_table,
+ engine_unregister_all_pkey_asn1_meths, e, nids,
+ num_nids, 1);
+ }
+ return 1;
+ }
+
+/* Exposed API function to get a functional reference from the implementation
+ * table (ie. try to get a functional reference from the tabled structural
+ * references) for a given pkey_asn1_meth 'nid' */
+ENGINE *ENGINE_get_pkey_asn1_meth_engine(int nid)
+ {
+ return engine_table_select(&pkey_asn1_meth_table, nid);
+ }
+
+/* Obtains a pkey_asn1_meth implementation from an ENGINE functional reference */
+const EVP_PKEY_ASN1_METHOD *ENGINE_get_pkey_asn1_meth(ENGINE *e, int nid)
+ {
+ EVP_PKEY_ASN1_METHOD *ret;
+ ENGINE_PKEY_ASN1_METHS_PTR fn = ENGINE_get_pkey_asn1_meths(e);
+ if(!fn || !fn(e, &ret, NULL, nid))
+ {
+ ENGINEerr(ENGINE_F_ENGINE_GET_PKEY_ASN1_METH,
+ ENGINE_R_UNIMPLEMENTED_PUBLIC_KEY_METHOD);
+ return NULL;
+ }
+ return ret;
+ }
+
+/* Gets the pkey_asn1_meth callback from an ENGINE structure */
+ENGINE_PKEY_ASN1_METHS_PTR ENGINE_get_pkey_asn1_meths(const ENGINE *e)
+ {
+ return e->pkey_asn1_meths;
+ }
+
+/* Sets the pkey_asn1_meth callback in an ENGINE structure */
+int ENGINE_set_pkey_asn1_meths(ENGINE *e, ENGINE_PKEY_ASN1_METHS_PTR f)
+ {
+ e->pkey_asn1_meths = f;
+ return 1;
+ }
+
+/* Internal function to free up EVP_PKEY_ASN1_METHOD structures before an
+ * ENGINE is destroyed
+ */
+
+void engine_pkey_asn1_meths_free(ENGINE *e)
+ {
+ int i;
+ EVP_PKEY_ASN1_METHOD *pkm;
+ if (e->pkey_asn1_meths)
+ {
+ const int *pknids;
+ int npknids;
+ npknids = e->pkey_asn1_meths(e, NULL, &pknids, 0);
+ for (i = 0; i < npknids; i++)
+ {
+ if (e->pkey_asn1_meths(e, &pkm, NULL, pknids[i]))
+ {
+ EVP_PKEY_asn1_free(pkm);
+ }
+ }
+ }
+ }
+
+/* Find a method based on a string. This does a linear search through
+ * all implemented algorithms. This is OK in practice because only
+ * a small number of algorithms are likely to be implemented in an engine
+ * and it is not used for speed critical operations.
+ */
+
+const EVP_PKEY_ASN1_METHOD *ENGINE_get_pkey_asn1_meth_str(ENGINE *e,
+ const char *str, int len)
+ {
+ int i, nidcount;
+ const int *nids;
+ EVP_PKEY_ASN1_METHOD *ameth;
+ if (!e->pkey_asn1_meths)
+ return NULL;
+ if (len == -1)
+ len = strlen(str);
+ nidcount = e->pkey_asn1_meths(e, NULL, &nids, 0);
+ for (i = 0; i < nidcount; i++)
+ {
+ e->pkey_asn1_meths(e, &ameth, NULL, nids[i]);
+ if (((int)strlen(ameth->pem_str) == len) &&
+ !strncasecmp(ameth->pem_str, str, len))
+ return ameth;
+ }
+ return NULL;
+ }
+
+typedef struct
+ {
+ ENGINE *e;
+ const EVP_PKEY_ASN1_METHOD *ameth;
+ const char *str;
+ int len;
+ } ENGINE_FIND_STR;
+
+static void look_str_cb(int nid, STACK_OF(ENGINE) *sk, ENGINE *def, void *arg)
+ {
+ ENGINE_FIND_STR *lk = arg;
+ int i;
+ if (lk->ameth)
+ return;
+ for (i = 0; i < sk_ENGINE_num(sk); i++)
+ {
+ ENGINE *e = sk_ENGINE_value(sk, i);
+ EVP_PKEY_ASN1_METHOD *ameth;
+ e->pkey_asn1_meths(e, &ameth, NULL, nid);
+ if (((int)strlen(ameth->pem_str) == lk->len) &&
+ !strncasecmp(ameth->pem_str, lk->str, lk->len))
+ {
+ lk->e = e;
+ lk->ameth = ameth;
+ return;
+ }
+ }
+ }
+
+const EVP_PKEY_ASN1_METHOD *ENGINE_pkey_asn1_find_str(ENGINE **pe,
+ const char *str, int len)
+ {
+ ENGINE_FIND_STR fstr;
+ fstr.e = NULL;
+ fstr.ameth = NULL;
+ fstr.str = str;
+ fstr.len = len;
+ CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
+ engine_table_doall(pkey_asn1_meth_table, look_str_cb, &fstr);
+ /* If found obtain a structural reference to engine */
+ if (fstr.e)
+ {
+ fstr.e->struct_ref++;
+ engine_ref_debug(fstr.e, 0, 1)
+ }
+ *pe = fstr.e;
+ CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
+ return fstr.ameth;
+ }
diff --git a/crypto/engine/tb_dsa.c b/crypto/engine/tb_dsa.c
index d326a5f6da..e4674f5f07 100644
--- a/crypto/engine/tb_dsa.c
+++ b/crypto/engine/tb_dsa.c
@@ -92,7 +92,7 @@ int ENGINE_set_default_DSA(ENGINE *e)
{
if(e->dsa_meth)
return engine_table_register(&dsa_table,
- engine_unregister_all_DSA, e, &dummy_nid, 1, 0);
+ engine_unregister_all_DSA, e, &dummy_nid, 1, 1);
return 1;
}
diff --git a/crypto/engine/tb_ecdh.c b/crypto/engine/tb_ecdh.c
index 59977f7dd0..c8ec7812c5 100644
--- a/crypto/engine/tb_ecdh.c
+++ b/crypto/engine/tb_ecdh.c
@@ -107,7 +107,7 @@ int ENGINE_set_default_ECDH(ENGINE *e)
{
if(e->ecdh_meth)
return engine_table_register(&ecdh_table,
- engine_unregister_all_ECDH, e, &dummy_nid, 1, 0);
+ engine_unregister_all_ECDH, e, &dummy_nid, 1, 1);
return 1;
}
diff --git a/crypto/engine/tb_ecdsa.c b/crypto/engine/tb_ecdsa.c
index e30b02e8c5..005ecb622c 100644
--- a/crypto/engine/tb_ecdsa.c
+++ b/crypto/engine/tb_ecdsa.c
@@ -92,7 +92,7 @@ int ENGINE_set_default_ECDSA(ENGINE *e)
{
if(e->ecdsa_meth)
return engine_table_register(&ecdsa_table,
- engine_unregister_all_ECDSA, e, &dummy_nid, 1, 0);
+ engine_unregister_all_ECDSA, e, &dummy_nid, 1, 1);
return 1;
}
diff --git a/crypto/engine/tb_pkmeth.c b/crypto/engine/tb_pkmeth.c
new file mode 100644
index 0000000000..1cdb967f25
--- /dev/null
+++ b/crypto/engine/tb_pkmeth.c
@@ -0,0 +1,167 @@
+/* ====================================================================
+ * Copyright (c) 2006 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 "eng_int.h"
+#include <openssl/evp.h>
+
+/* If this symbol is defined then ENGINE_get_pkey_meth_engine(), the function
+ * that is used by EVP to hook in pkey_meth code and cache defaults (etc), will
+ * display brief debugging summaries to stderr with the 'nid'. */
+/* #define ENGINE_PKEY_METH_DEBUG */
+
+static ENGINE_TABLE *pkey_meth_table = NULL;
+
+void ENGINE_unregister_pkey_meths(ENGINE *e)
+ {
+ engine_table_unregister(&pkey_meth_table, e);
+ }
+
+static void engine_unregister_all_pkey_meths(void)
+ {
+ engine_table_cleanup(&pkey_meth_table);
+ }
+
+int ENGINE_register_pkey_meths(ENGINE *e)
+ {
+ if(e->pkey_meths)
+ {
+ const int *nids;
+ int num_nids = e->pkey_meths(e, NULL, &nids, 0);
+ if(num_nids > 0)
+ return engine_table_register(&pkey_meth_table,
+ engine_unregister_all_pkey_meths, e, nids,
+ num_nids, 0);
+ }
+ return 1;
+ }
+
+void ENGINE_register_all_pkey_meths()
+ {
+ ENGINE *e;
+
+ for(e=ENGINE_get_first() ; e ; e=ENGINE_get_next(e))
+ ENGINE_register_pkey_meths(e);
+ }
+
+int ENGINE_set_default_pkey_meths(ENGINE *e)
+ {
+ if(e->pkey_meths)
+ {
+ const int *nids;
+ int num_nids = e->pkey_meths(e, NULL, &nids, 0);
+ if(num_nids > 0)
+ return engine_table_register(&pkey_meth_table,
+ engine_unregister_all_pkey_meths, e, nids,
+ num_nids, 1);
+ }
+ return 1;
+ }
+
+/* Exposed API function to get a functional reference from the implementation
+ * table (ie. try to get a functional reference from the tabled structural
+ * references) for a given pkey_meth 'nid' */
+ENGINE *ENGINE_get_pkey_meth_engine(int nid)
+ {
+ return engine_table_select(&pkey_meth_table, nid);
+ }
+
+/* Obtains a pkey_meth implementation from an ENGINE functional reference */
+const EVP_PKEY_METHOD *ENGINE_get_pkey_meth(ENGINE *e, int nid)
+ {
+ EVP_PKEY_METHOD *ret;
+ ENGINE_PKEY_METHS_PTR fn = ENGINE_get_pkey_meths(e);
+ if(!fn || !fn(e, &ret, NULL, nid))
+ {
+ ENGINEerr(ENGINE_F_ENGINE_GET_PKEY_METH,
+ ENGINE_R_UNIMPLEMENTED_PUBLIC_KEY_METHOD);
+ return NULL;
+ }
+ return ret;
+ }
+
+/* Gets the pkey_meth callback from an ENGINE structure */
+ENGINE_PKEY_METHS_PTR ENGINE_get_pkey_meths(const ENGINE *e)
+ {
+ return e->pkey_meths;
+ }
+
+/* Sets the pkey_meth callback in an ENGINE structure */
+int ENGINE_set_pkey_meths(ENGINE *e, ENGINE_PKEY_METHS_PTR f)
+ {
+ e->pkey_meths = f;
+ return 1;
+ }
+
+/* Internal function to free up EVP_PKEY_METHOD structures before an
+ * ENGINE is destroyed
+ */
+
+void engine_pkey_meths_free(ENGINE *e)
+ {
+ int i;
+ EVP_PKEY_METHOD *pkm;
+ if (e->pkey_meths)
+ {
+ const int *pknids;
+ int npknids;
+ npknids = e->pkey_meths(e, NULL, &pknids, 0);
+ for (i = 0; i < npknids; i++)
+ {
+ if (e->pkey_meths(e, &pkm, NULL, pknids[i]))
+ {
+ EVP_PKEY_meth_free(pkm);
+ }
+ }
+ }
+ }