diff options
| author | beck <> | 2000-12-15 02:58:47 +0000 |
|---|---|---|
| committer | beck <> | 2000-12-15 02:58:47 +0000 |
| commit | 9200bb13d15da4b2a23e6bc92c20e95b74aa2113 (patch) | |
| tree | 5c52d628ec1e34be76e7ef2a4235d248b7c44d24 /src/lib/libcrypto/engine | |
| parent | e131d25072e3d4197ba4b9bcc0d1b27d34d6488d (diff) | |
| download | openbsd-9200bb13d15da4b2a23e6bc92c20e95b74aa2113.tar.gz openbsd-9200bb13d15da4b2a23e6bc92c20e95b74aa2113.tar.bz2 openbsd-9200bb13d15da4b2a23e6bc92c20e95b74aa2113.zip | |
openssl-engine-0.9.6 merge
Diffstat (limited to '')
| -rw-r--r-- | src/lib/libcrypto/engine/Makefile.ssl | 220 | ||||
| -rw-r--r-- | src/lib/libcrypto/engine/README | 278 | ||||
| -rw-r--r-- | src/lib/libcrypto/engine/engine.h | 398 | ||||
| -rw-r--r-- | src/lib/libcrypto/engine/engine_err.c | 183 | ||||
| -rw-r--r-- | src/lib/libcrypto/engine/engine_int.h | 160 | ||||
| -rw-r--r-- | src/lib/libcrypto/engine/engine_lib.c | 488 | ||||
| -rw-r--r-- | src/lib/libcrypto/engine/engine_list.c | 675 | ||||
| -rw-r--r-- | src/lib/libcrypto/engine/engine_openssl.c | 174 | ||||
| -rw-r--r-- | src/lib/libcrypto/engine/enginetest.c | 251 | ||||
| -rw-r--r-- | src/lib/libcrypto/engine/hw_atalla.c | 444 | ||||
| -rw-r--r-- | src/lib/libcrypto/engine/hw_cswift.c | 807 | ||||
| -rw-r--r-- | src/lib/libcrypto/engine/hw_ncipher.c | 1019 | ||||
| -rw-r--r-- | src/lib/libcrypto/engine/vendor_defns/atalla.h | 61 | ||||
| -rw-r--r-- | src/lib/libcrypto/engine/vendor_defns/cswift.h | 213 |
14 files changed, 5371 insertions, 0 deletions
diff --git a/src/lib/libcrypto/engine/Makefile.ssl b/src/lib/libcrypto/engine/Makefile.ssl new file mode 100644 index 0000000000..7a0ffe755d --- /dev/null +++ b/src/lib/libcrypto/engine/Makefile.ssl | |||
| @@ -0,0 +1,220 @@ | |||
| 1 | # | ||
| 2 | # OpenSSL/crypto/engine/Makefile | ||
| 3 | # | ||
| 4 | |||
| 5 | DIR= engine | ||
| 6 | TOP= ../.. | ||
| 7 | CC= cc | ||
| 8 | INCLUDES= -I.. -I../../include | ||
| 9 | CFLAG=-g | ||
| 10 | INSTALL_PREFIX= | ||
| 11 | OPENSSLDIR= /usr/local/ssl | ||
| 12 | INSTALLTOP=/usr/local/ssl | ||
| 13 | MAKE= make -f Makefile.ssl | ||
| 14 | MAKEDEPEND= $(TOP)/util/domd $(TOP) | ||
| 15 | MAKEFILE= Makefile.ssl | ||
| 16 | AR= ar r | ||
| 17 | |||
| 18 | CFLAGS= $(INCLUDES) $(CFLAG) | ||
| 19 | |||
| 20 | GENERAL=Makefile | ||
| 21 | TEST= enginetest.c | ||
| 22 | APPS= | ||
| 23 | |||
| 24 | LIB=$(TOP)/libcrypto.a | ||
| 25 | LIBSRC= engine_err.c engine_lib.c engine_list.c engine_openssl.c \ | ||
| 26 | hw_atalla.c hw_cswift.c hw_ncipher.c | ||
| 27 | LIBOBJ= engine_err.o engine_lib.o engine_list.o engine_openssl.o \ | ||
| 28 | hw_atalla.o hw_cswift.o hw_ncipher.o | ||
| 29 | |||
| 30 | SRC= $(LIBSRC) | ||
| 31 | |||
| 32 | EXHEADER= engine.h | ||
| 33 | HEADER= $(EXHEADER) | ||
| 34 | |||
| 35 | ALL= $(GENERAL) $(SRC) $(HEADER) | ||
| 36 | |||
| 37 | top: | ||
| 38 | (cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all) | ||
| 39 | |||
| 40 | all: lib | ||
| 41 | |||
| 42 | lib: $(LIBOBJ) | ||
| 43 | $(AR) $(LIB) $(LIBOBJ) | ||
| 44 | $(RANLIB) $(LIB) | ||
| 45 | @touch lib | ||
| 46 | |||
| 47 | files: | ||
| 48 | $(PERL) $(TOP)/util/files.pl Makefile.ssl >> $(TOP)/MINFO | ||
| 49 | |||
| 50 | links: | ||
| 51 | @$(TOP)/util/point.sh Makefile.ssl Makefile | ||
| 52 | @$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER) | ||
| 53 | @$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST) | ||
| 54 | @$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS) | ||
| 55 | |||
| 56 | install: | ||
| 57 | @for i in $(EXHEADER) ; \ | ||
| 58 | do \ | ||
| 59 | (cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \ | ||
| 60 | chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \ | ||
| 61 | done; | ||
| 62 | |||
| 63 | tags: | ||
| 64 | ctags $(SRC) | ||
| 65 | |||
| 66 | tests: | ||
| 67 | |||
| 68 | lint: | ||
| 69 | lint -DLINT $(INCLUDES) $(SRC)>fluff | ||
| 70 | |||
| 71 | depend: | ||
| 72 | $(MAKEDEPEND) $(INCLUDES) $(DEPFLAG) $(PROGS) $(LIBSRC) | ||
| 73 | |||
| 74 | dclean: | ||
| 75 | $(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new | ||
| 76 | mv -f Makefile.new $(MAKEFILE) | ||
| 77 | |||
| 78 | clean: | ||
| 79 | rm -f *.o */*.o *.obj lib tags core .pure .nfs* *.old *.bak fluff | ||
| 80 | |||
| 81 | # DO NOT DELETE THIS LINE -- make depend depends on it. | ||
| 82 | |||
| 83 | engine_err.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h | ||
| 84 | engine_err.o: ../../include/openssl/blowfish.h ../../include/openssl/bn.h | ||
| 85 | engine_err.o: ../../include/openssl/cast.h ../../include/openssl/crypto.h | ||
| 86 | engine_err.o: ../../include/openssl/des.h ../../include/openssl/dh.h | ||
| 87 | engine_err.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h | ||
| 88 | engine_err.o: ../../include/openssl/engine.h ../../include/openssl/err.h | ||
| 89 | engine_err.o: ../../include/openssl/evp.h ../../include/openssl/idea.h | ||
| 90 | engine_err.o: ../../include/openssl/lhash.h ../../include/openssl/md2.h | ||
| 91 | engine_err.o: ../../include/openssl/md4.h ../../include/openssl/md5.h | ||
| 92 | engine_err.o: ../../include/openssl/mdc2.h ../../include/openssl/obj_mac.h | ||
| 93 | engine_err.o: ../../include/openssl/objects.h | ||
| 94 | engine_err.o: ../../include/openssl/opensslconf.h | ||
| 95 | engine_err.o: ../../include/openssl/opensslv.h ../../include/openssl/rand.h | ||
| 96 | engine_err.o: ../../include/openssl/rc2.h ../../include/openssl/rc4.h | ||
| 97 | engine_err.o: ../../include/openssl/rc5.h ../../include/openssl/ripemd.h | ||
| 98 | engine_err.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h | ||
| 99 | engine_err.o: ../../include/openssl/sha.h ../../include/openssl/stack.h | ||
| 100 | engine_err.o: ../../include/openssl/symhacks.h | ||
| 101 | engine_lib.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h | ||
| 102 | engine_lib.o: ../../include/openssl/blowfish.h ../../include/openssl/bn.h | ||
| 103 | engine_lib.o: ../../include/openssl/buffer.h ../../include/openssl/cast.h | ||
| 104 | engine_lib.o: ../../include/openssl/crypto.h ../../include/openssl/des.h | ||
| 105 | engine_lib.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h | ||
| 106 | engine_lib.o: ../../include/openssl/e_os.h ../../include/openssl/e_os2.h | ||
| 107 | engine_lib.o: ../../include/openssl/engine.h ../../include/openssl/err.h | ||
| 108 | engine_lib.o: ../../include/openssl/evp.h ../../include/openssl/idea.h | ||
| 109 | engine_lib.o: ../../include/openssl/lhash.h ../../include/openssl/md2.h | ||
| 110 | engine_lib.o: ../../include/openssl/md4.h ../../include/openssl/md5.h | ||
| 111 | engine_lib.o: ../../include/openssl/mdc2.h ../../include/openssl/obj_mac.h | ||
| 112 | engine_lib.o: ../../include/openssl/objects.h | ||
| 113 | engine_lib.o: ../../include/openssl/opensslconf.h | ||
| 114 | engine_lib.o: ../../include/openssl/opensslv.h ../../include/openssl/rand.h | ||
| 115 | engine_lib.o: ../../include/openssl/rc2.h ../../include/openssl/rc4.h | ||
| 116 | engine_lib.o: ../../include/openssl/rc5.h ../../include/openssl/ripemd.h | ||
| 117 | engine_lib.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h | ||
| 118 | engine_lib.o: ../../include/openssl/sha.h ../../include/openssl/stack.h | ||
| 119 | engine_lib.o: ../../include/openssl/symhacks.h ../cryptlib.h engine_int.h | ||
| 120 | engine_list.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h | ||
| 121 | engine_list.o: ../../include/openssl/blowfish.h ../../include/openssl/bn.h | ||
| 122 | engine_list.o: ../../include/openssl/buffer.h ../../include/openssl/cast.h | ||
| 123 | engine_list.o: ../../include/openssl/crypto.h ../../include/openssl/des.h | ||
| 124 | engine_list.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h | ||
| 125 | engine_list.o: ../../include/openssl/e_os.h ../../include/openssl/e_os2.h | ||
| 126 | engine_list.o: ../../include/openssl/engine.h ../../include/openssl/err.h | ||
| 127 | engine_list.o: ../../include/openssl/evp.h ../../include/openssl/idea.h | ||
| 128 | engine_list.o: ../../include/openssl/lhash.h ../../include/openssl/md2.h | ||
| 129 | engine_list.o: ../../include/openssl/md4.h ../../include/openssl/md5.h | ||
| 130 | engine_list.o: ../../include/openssl/mdc2.h ../../include/openssl/obj_mac.h | ||
| 131 | engine_list.o: ../../include/openssl/objects.h | ||
| 132 | engine_list.o: ../../include/openssl/opensslconf.h | ||
| 133 | engine_list.o: ../../include/openssl/opensslv.h ../../include/openssl/rand.h | ||
| 134 | engine_list.o: ../../include/openssl/rc2.h ../../include/openssl/rc4.h | ||
| 135 | engine_list.o: ../../include/openssl/rc5.h ../../include/openssl/ripemd.h | ||
| 136 | engine_list.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h | ||
| 137 | engine_list.o: ../../include/openssl/sha.h ../../include/openssl/stack.h | ||
| 138 | engine_list.o: ../../include/openssl/symhacks.h ../cryptlib.h engine_int.h | ||
| 139 | engine_openssl.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h | ||
| 140 | engine_openssl.o: ../../include/openssl/blowfish.h ../../include/openssl/bn.h | ||
| 141 | engine_openssl.o: ../../include/openssl/buffer.h ../../include/openssl/cast.h | ||
| 142 | engine_openssl.o: ../../include/openssl/crypto.h ../../include/openssl/des.h | ||
| 143 | engine_openssl.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h | ||
| 144 | engine_openssl.o: ../../include/openssl/dso.h ../../include/openssl/e_os.h | ||
| 145 | engine_openssl.o: ../../include/openssl/e_os2.h ../../include/openssl/engine.h | ||
| 146 | engine_openssl.o: ../../include/openssl/err.h ../../include/openssl/evp.h | ||
| 147 | engine_openssl.o: ../../include/openssl/idea.h ../../include/openssl/lhash.h | ||
| 148 | engine_openssl.o: ../../include/openssl/md2.h ../../include/openssl/md4.h | ||
| 149 | engine_openssl.o: ../../include/openssl/md5.h ../../include/openssl/mdc2.h | ||
| 150 | engine_openssl.o: ../../include/openssl/obj_mac.h | ||
| 151 | engine_openssl.o: ../../include/openssl/objects.h | ||
| 152 | engine_openssl.o: ../../include/openssl/opensslconf.h | ||
| 153 | engine_openssl.o: ../../include/openssl/opensslv.h ../../include/openssl/rand.h | ||
| 154 | engine_openssl.o: ../../include/openssl/rc2.h ../../include/openssl/rc4.h | ||
| 155 | engine_openssl.o: ../../include/openssl/rc5.h ../../include/openssl/ripemd.h | ||
| 156 | engine_openssl.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h | ||
| 157 | engine_openssl.o: ../../include/openssl/sha.h ../../include/openssl/stack.h | ||
| 158 | engine_openssl.o: ../../include/openssl/symhacks.h ../cryptlib.h engine_int.h | ||
| 159 | hw_atalla.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h | ||
| 160 | hw_atalla.o: ../../include/openssl/blowfish.h ../../include/openssl/bn.h | ||
| 161 | hw_atalla.o: ../../include/openssl/buffer.h ../../include/openssl/cast.h | ||
| 162 | hw_atalla.o: ../../include/openssl/crypto.h ../../include/openssl/des.h | ||
| 163 | hw_atalla.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h | ||
| 164 | hw_atalla.o: ../../include/openssl/dso.h ../../include/openssl/e_os.h | ||
| 165 | hw_atalla.o: ../../include/openssl/e_os2.h ../../include/openssl/engine.h | ||
| 166 | hw_atalla.o: ../../include/openssl/err.h ../../include/openssl/evp.h | ||
| 167 | hw_atalla.o: ../../include/openssl/idea.h ../../include/openssl/lhash.h | ||
| 168 | hw_atalla.o: ../../include/openssl/md2.h ../../include/openssl/md4.h | ||
| 169 | hw_atalla.o: ../../include/openssl/md5.h ../../include/openssl/mdc2.h | ||
| 170 | hw_atalla.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h | ||
| 171 | hw_atalla.o: ../../include/openssl/opensslconf.h | ||
| 172 | hw_atalla.o: ../../include/openssl/opensslv.h ../../include/openssl/rand.h | ||
| 173 | hw_atalla.o: ../../include/openssl/rc2.h ../../include/openssl/rc4.h | ||
| 174 | hw_atalla.o: ../../include/openssl/rc5.h ../../include/openssl/ripemd.h | ||
| 175 | hw_atalla.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h | ||
| 176 | hw_atalla.o: ../../include/openssl/sha.h ../../include/openssl/stack.h | ||
| 177 | hw_atalla.o: ../../include/openssl/symhacks.h ../cryptlib.h engine_int.h | ||
| 178 | hw_atalla.o: vendor_defns/atalla.h | ||
| 179 | hw_cswift.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h | ||
| 180 | hw_cswift.o: ../../include/openssl/blowfish.h ../../include/openssl/bn.h | ||
| 181 | hw_cswift.o: ../../include/openssl/buffer.h ../../include/openssl/cast.h | ||
| 182 | hw_cswift.o: ../../include/openssl/crypto.h ../../include/openssl/des.h | ||
| 183 | hw_cswift.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h | ||
| 184 | hw_cswift.o: ../../include/openssl/dso.h ../../include/openssl/e_os.h | ||
| 185 | hw_cswift.o: ../../include/openssl/e_os2.h ../../include/openssl/engine.h | ||
| 186 | hw_cswift.o: ../../include/openssl/err.h ../../include/openssl/evp.h | ||
| 187 | hw_cswift.o: ../../include/openssl/idea.h ../../include/openssl/lhash.h | ||
| 188 | hw_cswift.o: ../../include/openssl/md2.h ../../include/openssl/md4.h | ||
| 189 | hw_cswift.o: ../../include/openssl/md5.h ../../include/openssl/mdc2.h | ||
| 190 | hw_cswift.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h | ||
| 191 | hw_cswift.o: ../../include/openssl/opensslconf.h | ||
| 192 | hw_cswift.o: ../../include/openssl/opensslv.h ../../include/openssl/rand.h | ||
| 193 | hw_cswift.o: ../../include/openssl/rc2.h ../../include/openssl/rc4.h | ||
| 194 | hw_cswift.o: ../../include/openssl/rc5.h ../../include/openssl/ripemd.h | ||
| 195 | hw_cswift.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h | ||
| 196 | hw_cswift.o: ../../include/openssl/sha.h ../../include/openssl/stack.h | ||
| 197 | hw_cswift.o: ../../include/openssl/symhacks.h ../cryptlib.h engine_int.h | ||
| 198 | hw_cswift.o: vendor_defns/cswift.h | ||
| 199 | hw_ncipher.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h | ||
| 200 | hw_ncipher.o: ../../include/openssl/blowfish.h ../../include/openssl/bn.h | ||
| 201 | hw_ncipher.o: ../../include/openssl/buffer.h ../../include/openssl/cast.h | ||
| 202 | hw_ncipher.o: ../../include/openssl/crypto.h ../../include/openssl/des.h | ||
| 203 | hw_ncipher.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h | ||
| 204 | hw_ncipher.o: ../../include/openssl/dso.h ../../include/openssl/e_os.h | ||
| 205 | hw_ncipher.o: ../../include/openssl/e_os2.h ../../include/openssl/engine.h | ||
| 206 | hw_ncipher.o: ../../include/openssl/err.h ../../include/openssl/evp.h | ||
| 207 | hw_ncipher.o: ../../include/openssl/idea.h ../../include/openssl/lhash.h | ||
| 208 | hw_ncipher.o: ../../include/openssl/md2.h ../../include/openssl/md4.h | ||
| 209 | hw_ncipher.o: ../../include/openssl/md5.h ../../include/openssl/mdc2.h | ||
| 210 | hw_ncipher.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h | ||
| 211 | hw_ncipher.o: ../../include/openssl/opensslconf.h | ||
| 212 | hw_ncipher.o: ../../include/openssl/opensslv.h ../../include/openssl/pem.h | ||
| 213 | hw_ncipher.o: ../../include/openssl/pem2.h ../../include/openssl/pkcs7.h | ||
| 214 | hw_ncipher.o: ../../include/openssl/rand.h ../../include/openssl/rc2.h | ||
| 215 | hw_ncipher.o: ../../include/openssl/rc4.h ../../include/openssl/rc5.h | ||
| 216 | hw_ncipher.o: ../../include/openssl/ripemd.h ../../include/openssl/rsa.h | ||
| 217 | hw_ncipher.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h | ||
| 218 | hw_ncipher.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h | ||
| 219 | hw_ncipher.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h | ||
| 220 | hw_ncipher.o: ../cryptlib.h engine_int.h vendor_defns/hwcryptohook.h | ||
diff --git a/src/lib/libcrypto/engine/README b/src/lib/libcrypto/engine/README new file mode 100644 index 0000000000..96595e6f35 --- /dev/null +++ b/src/lib/libcrypto/engine/README | |||
| @@ -0,0 +1,278 @@ | |||
| 1 | NOTES, THOUGHTS, and EVERYTHING | ||
| 2 | ------------------------------- | ||
| 3 | |||
| 4 | (1) Concurrency and locking ... I made a change to the ENGINE_free code | ||
| 5 | because I spotted a potential hold-up in proceedings (doing too | ||
| 6 | much inside a lock including calling a callback), there may be | ||
| 7 | other bits like this. What do the speed/optimisation freaks think | ||
| 8 | of this aspect of the code and design? There's lots of locking for | ||
| 9 | manipulation functions and I need that to keep things nice and | ||
| 10 | solid, but this manipulation is mostly (de)initialisation, I would | ||
| 11 | think that most run-time locking is purely in the ENGINE_init and | ||
| 12 | ENGINE_finish calls that might be made when getting handles for | ||
| 13 | RSA (and friends') structures. These would be mostly reference | ||
| 14 | count operations as the functional references should always be 1 | ||
| 15 | or greater at run-time to prevent init/deinit thrashing. | ||
| 16 | |||
| 17 | (2) nCipher support, via the HWCryptoHook API, is now in the code. | ||
| 18 | Apparently this hasn't been tested too much yet, but it looks | ||
| 19 | good. :-) Atalla support has been added too, but shares a lot in | ||
| 20 | common with Ben's original hooks in bn_exp.c (although it has been | ||
| 21 | ENGINE-ified, and error handling wrapped around it) and it's also | ||
| 22 | had some low-volume testing, so it should be usable. | ||
| 23 | |||
| 24 | (3) Of more concern, we need to work out (a) how to put together usable | ||
| 25 | RAND_METHODs for units that just have one "get n or less random | ||
| 26 | bytes" function, (b) we also need to determine how to hook the code | ||
| 27 | in crypto/rand/ to use the ENGINE defaults in a way similar to what | ||
| 28 | has been done in crypto/rsa/, crypto/dsa/, etc. | ||
| 29 | |||
| 30 | (4) ENGINE should really grow to encompass more than 3 public key | ||
| 31 | algorithms and randomness gathering. The structure/data level of | ||
| 32 | the engine code is hidden from code outside the crypto/engine/ | ||
| 33 | directory so change shouldn't be too viral. More important though | ||
| 34 | is how things should evolve ... this needs thought and discussion. | ||
| 35 | |||
| 36 | |||
| 37 | -----------------------------------==*==----------------------------------- | ||
| 38 | |||
| 39 | More notes 2000-08-01 | ||
| 40 | --------------------- | ||
| 41 | |||
| 42 | Geoff Thorpe, who designed the engine part, wrote a pretty good description | ||
| 43 | of the thoughts he had when he built it, good enough to include verbatim here | ||
| 44 | (with his permission) -- Richard Levitte | ||
| 45 | |||
| 46 | |||
| 47 | Date: Tue, 1 Aug 2000 16:54:08 +0100 (BST) | ||
| 48 | From: Geoff Thorpe | ||
| 49 | Subject: Re: The thoughts to merge BRANCH_engine into the main trunk are | ||
| 50 | emerging | ||
| 51 | |||
| 52 | Hi there, | ||
| 53 | |||
| 54 | I'm going to try and do some justice to this, but I'm a little short on | ||
| 55 | time and the there is an endless amount that could be discussed on this | ||
| 56 | subject. sigh ... please bear with me :-) | ||
| 57 | |||
| 58 | > The changes in BRANCH_engine dig deep into the core of OpenSSL, for example | ||
| 59 | > into the RSA and RAND routines, adding a level of indirection which is needed | ||
| 60 | > to keep the abstraction, as far as I understand. It would be a good thing if | ||
| 61 | > those who do play with those things took a look at the changes that have been | ||
| 62 | > done in the branch and say out loud how much (or hopefully little) we've made | ||
| 63 | > fools of ourselves. | ||
| 64 | |||
| 65 | The point here is that the code that has emerged in the BRANCH_engine | ||
| 66 | branch was based on some initial requirements of mine that I went in and | ||
| 67 | addressed, and Richard has picked up the ball and run with it too. It | ||
| 68 | would be really useful to get some review of the approach we've taken, but | ||
| 69 | first I think I need to describe as best I can the reasons behind what has | ||
| 70 | been done so far, in particular what issues we have tried to address when | ||
| 71 | doing this, and what issues we have intentionally (or necessarily) tried | ||
| 72 | to avoid. | ||
| 73 | |||
| 74 | methods, engines, and evps | ||
| 75 | -------------------------- | ||
| 76 | |||
| 77 | There has been some dicussion, particularly with Steve, about where this | ||
| 78 | ENGINE stuff might fit into the conceptual picture as/when we start to | ||
| 79 | abstract algorithms a little bit to make the library more extensible. In | ||
| 80 | particular, it would desirable to have algorithms (symmetric, hash, pkc, | ||
| 81 | etc) abstracted in some way that allows them to be just objects sitting in | ||
| 82 | a list (or database) ... it'll just happen that the "DSA" object doesn't | ||
| 83 | support encryption whereas the "RSA" object does. This requires a lot of | ||
| 84 | consideration to begin to know how to tackle it; in particular how | ||
| 85 | encapsulated should these things be? If the objects also understand their | ||
| 86 | own ASN1 encodings and what-not, then it would for example be possible to | ||
| 87 | add support for elliptic-curve DSA in as a new algorithm and automatically | ||
| 88 | have ECC-DSA certificates supported in SSL applications. Possible, but not | ||
| 89 | easy. :-) | ||
| 90 | |||
| 91 | Whatever, it seems that the way to go (if I've grok'd Steve's comments on | ||
| 92 | this in the past) is to amalgamate these things in EVP as is already done | ||
| 93 | (I think) for ciphers or hashes (Steve, please correct/elaborate). I | ||
| 94 | certainly think something should be done in this direction because right | ||
| 95 | now we have different source directories, types, functions, and methods | ||
| 96 | for each algorithm - even when conceptually they are very much different | ||
| 97 | feathers of the same bird. (This is certainly all true for the public-key | ||
| 98 | stuff, and may be partially true for the other parts.) | ||
| 99 | |||
| 100 | ENGINE was *not* conceived as a way of solving this, far from it. Nor was | ||
| 101 | it conceived as a way of replacing the various "***_METHOD"s. It was | ||
| 102 | conceived as an abstraction of a sort of "virtual crypto device". If we | ||
| 103 | lived in a world where "EVP_ALGO"s (or something like them) encapsulated | ||
| 104 | particular algorithms like RSA,DSA,MD5,RC4,etc, and "***_METHOD"s | ||
| 105 | encapsulated interfaces to algorithms (eg. some algo's might support a | ||
| 106 | PKC_METHOD, a HASH_METHOD, or a CIPHER_METHOD, who knows?), then I would | ||
| 107 | think that ENGINE would encapsulate an implementation of arbitrarily many | ||
| 108 | of those algorithms - perhaps as alternatives to existing algorithms | ||
| 109 | and/or perhaps as new previously unimplemented algorithms. An ENGINE could | ||
| 110 | be used to contain an alternative software implementation, a wrapper for a | ||
| 111 | hardware acceleration and/or key-management unit, a comms-wrapper for | ||
| 112 | distributing cryptographic operations to remote machines, or any other | ||
| 113 | "devices" your imagination can dream up. | ||
| 114 | |||
| 115 | However, what has been done in the ENGINE branch so far is nothing more | ||
| 116 | than starting to get our toes wet. I had a couple of self-imposed | ||
| 117 | requirements when putting the initial abstraction together, and I may have | ||
| 118 | already posed these in one form or another on the list, but briefly; | ||
| 119 | |||
| 120 | (i) only bother with public key algorithms for now, and maybe RAND too | ||
| 121 | (motivated by the need to get hardware support going and the fact | ||
| 122 | this was a comparitively easy subset to address to begin with). | ||
| 123 | |||
| 124 | (ii) don't change (if at all possible) the existing crypto code, ie. the | ||
| 125 | implementations, the way the ***_METHODs work, etc. | ||
| 126 | |||
| 127 | (iii) ensure that if no function from the ENGINE code is ever called then | ||
| 128 | things work the way they always did, and there is no memory | ||
| 129 | allocation (otherwise the failure to cleanup would be a problem - | ||
| 130 | this is part of the reason no STACKs were used, the other part of | ||
| 131 | the reason being I found them inappropriate). | ||
| 132 | |||
| 133 | (iv) ensure that all the built-in crypto was encapsulated by one of | ||
| 134 | these "ENGINE"s and that this engine was automatically selected as | ||
| 135 | the default. | ||
| 136 | |||
| 137 | (v) provide the minimum hooking possible in the existing crypto code | ||
| 138 | so that global functions (eg. RSA_public_encrypt) do not need any | ||
| 139 | extra parameter, yet will use whatever the current default ENGINE | ||
| 140 | for that RSA key is, and that the default can be set "per-key" | ||
| 141 | and globally (new keys will assume the global default, and keys | ||
| 142 | without their own default will be operated on using the global | ||
| 143 | default). NB: Try and make (v) conflict as little as possible with | ||
| 144 | (ii). :-) | ||
| 145 | |||
| 146 | (vi) wrap the ENGINE code up in duct tape so you can't even see the | ||
| 147 | corners. Ie. expose no structures at all, just black-box pointers. | ||
| 148 | |||
| 149 | (v) maintain internally a list of ENGINEs on which a calling | ||
| 150 | application can iterate, interrogate, etc. Allow a calling | ||
| 151 | application to hook in new ENGINEs, remove ENGINEs from the list, | ||
| 152 | and enforce uniqueness within the global list of each ENGINE's | ||
| 153 | "unique id". | ||
| 154 | |||
| 155 | (vi) keep reference counts for everything - eg. this includes storing a | ||
| 156 | reference inside each RSA structure to the ENGINE that it uses. | ||
| 157 | This is freed when the RSA structure is destroyed, or has its | ||
| 158 | ENGINE explicitly changed. The net effect needs to be that at any | ||
| 159 | time, it is deterministic to know whether an ENGINE is in use or | ||
| 160 | can be safely removed (or unloaded in the case of the other type | ||
| 161 | of reference) without invalidating function pointers that may or | ||
| 162 | may not be used indavertently in the future. This was actually | ||
| 163 | one of the biggest problems to overcome in the existing OpenSSL | ||
| 164 | code - implementations had always been assumed to be ever-present, | ||
| 165 | so there was no trivial way to get round this. | ||
| 166 | |||
| 167 | (vii) distinguish between structural references and functional | ||
| 168 | references. | ||
| 169 | |||
| 170 | A *little* detail | ||
| 171 | ----------------- | ||
| 172 | |||
| 173 | While my mind is on it; I'll illustrate the bit in item (vii). This idea | ||
| 174 | turned out to be very handy - the ENGINEs themselves need to be operated | ||
| 175 | on and manipulated simply as objects without necessarily trying to | ||
| 176 | "enable" them for use. Eg. most host machines will not have the necessary | ||
| 177 | hardware or software to support all the engines one might compile into | ||
| 178 | OpenSSL, yet it needs to be possible to iterate across the ENGINEs, | ||
| 179 | querying their names, properties, etc - all happening in a thread-safe | ||
| 180 | manner that uses reference counts (if you imagine two threads iterating | ||
| 181 | through a list and one thread removing the ENGINE the other is currently | ||
| 182 | looking at - you can see the gotcha waiting to happen). For all of this, | ||
| 183 | *structural references* are used and operate much like the other reference | ||
| 184 | counts in OpenSSL. | ||
| 185 | |||
| 186 | The other kind of reference count is for *functional* references - these | ||
| 187 | indicate a reference on which the caller can actually assume the | ||
| 188 | particular ENGINE to be initialised and usable to perform the operations | ||
| 189 | it implements. Any increment or decrement of the functional reference | ||
| 190 | count automatically invokes a corresponding change in the structural | ||
| 191 | reference count, as it is fairly obvious that a functional reference is a | ||
| 192 | restricted case of a structural reference. So struct_ref >= funct_ref at | ||
| 193 | all times. NB: functional references are usually obtained by a call to | ||
| 194 | ENGINE_init(), but can also be created implicitly by calls that require a | ||
| 195 | new functional reference to be created, eg. ENGINE_set_default(). Either | ||
| 196 | way the only time the underlying ENGINE's "init" function is really called | ||
| 197 | is when the (functional) reference count increases to 1, similarly the | ||
| 198 | underlying "finish" handler is only called as the count goes down to 0. | ||
| 199 | The effect of this, for example, is that if you set the default ENGINE for | ||
| 200 | RSA operations to be "cswift", then its functional reference count will | ||
| 201 | already be at least 1 so the CryptoSwift shared-library and the card will | ||
| 202 | stay loaded and initialised until such time as all RSA keys using the | ||
| 203 | cswift ENGINE are changed or destroyed and the default ENGINE for RSA | ||
| 204 | operations has been changed. This prevents repeated thrashing of init and | ||
| 205 | finish handling if the count keeps getting down as far as zero. | ||
| 206 | |||
| 207 | Otherwise, the way the ENGINE code has been put together I think pretty | ||
| 208 | much reflects the above points. The reason for the ENGINE structure having | ||
| 209 | individual RSA_METHOD, DSA_METHOD, etc pointers is simply that it was the | ||
| 210 | easiest way to go about things for now, to hook it all into the raw | ||
| 211 | RSA,DSA,etc code, and I was trying to the keep the structure invisible | ||
| 212 | anyway so that the way this is internally managed could be easily changed | ||
| 213 | later on when we start to work out what's to be done about these other | ||
| 214 | abstractions. | ||
| 215 | |||
| 216 | Down the line, if some EVP-based technique emerges for adequately | ||
| 217 | encapsulating algorithms and all their various bits and pieces, then I can | ||
| 218 | imagine that "ENGINE" would turn into a reference-counting database of | ||
| 219 | these EVP things, of which the default "openssl" ENGINE would be the | ||
| 220 | library's own object database of pre-built software implemented algorithms | ||
| 221 | (and such). It would also be cool to see the idea of "METHOD"s detached | ||
| 222 | from the algorithms themselves ... so RSA, DSA, ElGamal, etc can all | ||
| 223 | expose essentially the same METHOD (aka interface), which would include | ||
| 224 | any querying/flagging stuff to identify what the algorithm can/can't do, | ||
| 225 | its name, and other stuff like max/min block sizes, key sizes, etc. This | ||
| 226 | would result in ENGINE similarly detaching its internal database of | ||
| 227 | algorithm implementations from the function definitions that return | ||
| 228 | interfaces to them. I think ... | ||
| 229 | |||
| 230 | As for DSOs etc. Well the DSO code is pretty handy (but could be made much | ||
| 231 | more so) for loading vendor's driver-libraries and talking to them in some | ||
| 232 | generic way, but right now there's still big problems associated with | ||
| 233 | actually putting OpenSSL code (ie. new ENGINEs, or anything else for that | ||
| 234 | matter) in dynamically loadable libraries. These problems won't go away in | ||
| 235 | a hurry so I don't think we should expect to have any kind of | ||
| 236 | shared-library extensions any time soon - but solving the problems is a | ||
| 237 | good thing to aim for, and would as a side-effect probably help make | ||
| 238 | OpenSSL more usable as a shared-library itself (looking at the things | ||
| 239 | needed to do this will show you why). | ||
| 240 | |||
| 241 | One of the problems is that if you look at any of the ENGINE | ||
| 242 | implementations, eg. hw_cswift.c or hw_ncipher.c, you'll see how it needs | ||
| 243 | a variety of functionality and definitions from various areas of OpenSSL, | ||
| 244 | including crypto/bn/, crypto/err/, crypto/ itself (locking for example), | ||
| 245 | crypto/dso/, crypto/engine/, crypto/rsa, etc etc etc. So if similar code | ||
| 246 | were to be suctioned off into shared libraries, the shared libraries would | ||
| 247 | either have to duplicate all the definitions and code and avoid loader | ||
| 248 | conflicts, or OpenSSL would have to somehow expose all that functionality | ||
| 249 | to the shared-library. If this isn't a big enough problem, the issue of | ||
| 250 | binary compatibility will be - anyone writing Apache modules can tell you | ||
| 251 | that (Ralf? Ben? :-). However, I don't think OpenSSL would need to be | ||
| 252 | quite so forgiving as Apache should be, so OpenSSL could simply tell its | ||
| 253 | version to the DSO and leave the DSO with the problem of deciding whether | ||
| 254 | to proceed or bail out for fear of binary incompatibilities. | ||
| 255 | |||
| 256 | Certainly one thing that would go a long way to addressing this is to | ||
| 257 | embark on a bit of an opaqueness mission. I've set the ENGINE code up with | ||
| 258 | this in mind - it's so draconian that even to declare your own ENGINE, you | ||
| 259 | have to get the engine code to create the underlying ENGINE structure, and | ||
| 260 | then feed in the new ENGINE's function/method pointers through various | ||
| 261 | "set" functions. The more of the code that takes on such a black-box | ||
| 262 | approach, the more of the code that will be (a) easy to expose to shared | ||
| 263 | libraries that need it, and (b) easy to expose to applications wanting to | ||
| 264 | use OpenSSL itself as a shared-library. From my own explorations in | ||
| 265 | OpenSSL, the biggest leviathan I've seen that is a problem in this respect | ||
| 266 | is the BIGNUM code. Trying to "expose" the bignum code through any kind of | ||
| 267 | organised "METHODs", let alone do all the necessary bignum operations | ||
| 268 | solely through functions rather than direct access to the structures and | ||
| 269 | macros, will be a massive pain in the "r"s. | ||
| 270 | |||
| 271 | Anyway, I'm done for now - hope it was readable. Thoughts? | ||
| 272 | |||
| 273 | Cheers, | ||
| 274 | Geoff | ||
| 275 | |||
| 276 | |||
| 277 | -----------------------------------==*==----------------------------------- | ||
| 278 | |||
diff --git a/src/lib/libcrypto/engine/engine.h b/src/lib/libcrypto/engine/engine.h new file mode 100644 index 0000000000..2983f47034 --- /dev/null +++ b/src/lib/libcrypto/engine/engine.h | |||
| @@ -0,0 +1,398 @@ | |||
| 1 | /* openssl/engine.h */ | ||
| 2 | /* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL | ||
| 3 | * project 2000. | ||
| 4 | */ | ||
| 5 | /* ==================================================================== | ||
| 6 | * Copyright (c) 1999 The OpenSSL Project. All rights reserved. | ||
| 7 | * | ||
| 8 | * Redistribution and use in source and binary forms, with or without | ||
| 9 | * modification, are permitted provided that the following conditions | ||
| 10 | * are met: | ||
| 11 | * | ||
| 12 | * 1. Redistributions of source code must retain the above copyright | ||
| 13 | * notice, this list of conditions and the following disclaimer. | ||
| 14 | * | ||
| 15 | * 2. Redistributions in binary form must reproduce the above copyright | ||
| 16 | * notice, this list of conditions and the following disclaimer in | ||
| 17 | * the documentation and/or other materials provided with the | ||
| 18 | * distribution. | ||
| 19 | * | ||
| 20 | * 3. All advertising materials mentioning features or use of this | ||
| 21 | * software must display the following acknowledgment: | ||
| 22 | * "This product includes software developed by the OpenSSL Project | ||
| 23 | * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" | ||
| 24 | * | ||
| 25 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | ||
| 26 | * endorse or promote products derived from this software without | ||
| 27 | * prior written permission. For written permission, please contact | ||
| 28 | * licensing@OpenSSL.org. | ||
| 29 | * | ||
| 30 | * 5. Products derived from this software may not be called "OpenSSL" | ||
| 31 | * nor may "OpenSSL" appear in their names without prior written | ||
| 32 | * permission of the OpenSSL Project. | ||
| 33 | * | ||
| 34 | * 6. Redistributions of any form whatsoever must retain the following | ||
| 35 | * acknowledgment: | ||
| 36 | * "This product includes software developed by the OpenSSL Project | ||
| 37 | * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" | ||
| 38 | * | ||
| 39 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | ||
| 40 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
| 41 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
| 42 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | ||
| 43 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
| 44 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
| 45 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
| 46 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| 47 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
| 48 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
| 49 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | ||
| 50 | * OF THE POSSIBILITY OF SUCH DAMAGE. | ||
| 51 | * ==================================================================== | ||
| 52 | * | ||
| 53 | * This product includes cryptographic software written by Eric Young | ||
| 54 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
| 55 | * Hudson (tjh@cryptsoft.com). | ||
| 56 | * | ||
| 57 | */ | ||
| 58 | |||
| 59 | #ifndef HEADER_ENGINE_H | ||
| 60 | #define HEADER_ENGINE_H | ||
| 61 | |||
| 62 | #include <openssl/bn.h> | ||
| 63 | #include <openssl/rsa.h> | ||
| 64 | #include <openssl/dsa.h> | ||
| 65 | #include <openssl/dh.h> | ||
| 66 | #include <openssl/rand.h> | ||
| 67 | #include <openssl/evp.h> | ||
| 68 | #include <openssl/symhacks.h> | ||
| 69 | |||
| 70 | #ifdef __cplusplus | ||
| 71 | extern "C" { | ||
| 72 | #endif | ||
| 73 | |||
| 74 | /* These flags are used to control combinations of algorithm (methods) | ||
| 75 | * by bitwise "OR"ing. */ | ||
| 76 | #define ENGINE_METHOD_RSA (unsigned int)0x0001 | ||
| 77 | #define ENGINE_METHOD_DSA (unsigned int)0x0002 | ||
| 78 | #define ENGINE_METHOD_DH (unsigned int)0x0004 | ||
| 79 | #define ENGINE_METHOD_RAND (unsigned int)0x0008 | ||
| 80 | #define ENGINE_METHOD_BN_MOD_EXP (unsigned int)0x0010 | ||
| 81 | #define ENGINE_METHOD_BN_MOD_EXP_CRT (unsigned int)0x0020 | ||
| 82 | /* Obvious all-or-nothing cases. */ | ||
| 83 | #define ENGINE_METHOD_ALL (unsigned int)0xFFFF | ||
| 84 | #define ENGINE_METHOD_NONE (unsigned int)0x0000 | ||
| 85 | |||
| 86 | /* These flags are used to tell the ctrl function what should be done. | ||
| 87 | * All command numbers are shared between all engines, even if some don't | ||
| 88 | * make sense to some engines. In such a case, they do nothing but return | ||
| 89 | * the error ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED. */ | ||
| 90 | #define ENGINE_CTRL_SET_LOGSTREAM 1 | ||
| 91 | #define ENGINE_CTRL_SET_PASSWORD_CALLBACK 2 | ||
| 92 | /* Flags specific to the nCipher "chil" engine */ | ||
| 93 | #define ENGINE_CTRL_CHIL_SET_FORKCHECK 100 | ||
| 94 | /* Depending on the value of the (long)i argument, this sets or | ||
| 95 | * unsets the SimpleForkCheck flag in the CHIL API to enable or | ||
| 96 | * disable checking and workarounds for applications that fork(). | ||
| 97 | */ | ||
| 98 | #define ENGINE_CTRL_CHIL_NO_LOCKING 101 | ||
| 99 | /* This prevents the initialisation function from providing mutex | ||
| 100 | * callbacks to the nCipher library. */ | ||
| 101 | |||
| 102 | /* As we're missing a BIGNUM_METHOD, we need a couple of locally | ||
| 103 | * defined function types that engines can implement. */ | ||
| 104 | |||
| 105 | #ifndef HEADER_ENGINE_INT_H | ||
| 106 | /* mod_exp operation, calculates; r = a ^ p mod m | ||
| 107 | * NB: ctx can be NULL, but if supplied, the implementation may use | ||
| 108 | * it if it wishes. */ | ||
| 109 | typedef int (*BN_MOD_EXP)(BIGNUM *r, BIGNUM *a, const BIGNUM *p, | ||
| 110 | const BIGNUM *m, BN_CTX *ctx); | ||
| 111 | |||
| 112 | /* private key operation for RSA, provided seperately in case other | ||
| 113 | * RSA implementations wish to use it. */ | ||
| 114 | typedef int (*BN_MOD_EXP_CRT)(BIGNUM *r, BIGNUM *a, const BIGNUM *p, | ||
| 115 | const BIGNUM *q, const BIGNUM *dmp1, const BIGNUM *dmq1, | ||
| 116 | const BIGNUM *iqmp, BN_CTX *ctx); | ||
| 117 | |||
| 118 | /* Generic function pointer */ | ||
| 119 | typedef void (*ENGINE_GEN_FUNC_PTR)(); | ||
| 120 | /* Generic function pointer taking no arguments */ | ||
| 121 | typedef void (*ENGINE_GEN_INT_FUNC_PTR)(void); | ||
| 122 | /* Specific control function pointer */ | ||
| 123 | typedef int (*ENGINE_CTRL_FUNC_PTR)(int cmd, long i, void *p, void (*f)()); | ||
| 124 | |||
| 125 | /* The list of "engine" types is a static array of (const ENGINE*) | ||
| 126 | * pointers (not dynamic because static is fine for now and we otherwise | ||
| 127 | * have to hook an appropriate load/unload function in to initialise and | ||
| 128 | * cleanup). */ | ||
| 129 | typedef struct engine_st ENGINE; | ||
| 130 | #endif | ||
| 131 | |||
| 132 | /* STRUCTURE functions ... all of these functions deal with pointers to | ||
| 133 | * ENGINE structures where the pointers have a "structural reference". | ||
| 134 | * This means that their reference is to allow access to the structure | ||
| 135 | * but it does not imply that the structure is functional. To simply | ||
| 136 | * increment or decrement the structural reference count, use ENGINE_new | ||
| 137 | * and ENGINE_free. NB: This is not required when iterating using | ||
| 138 | * ENGINE_get_next as it will automatically decrement the structural | ||
| 139 | * reference count of the "current" ENGINE and increment the structural | ||
| 140 | * reference count of the ENGINE it returns (unless it is NULL). */ | ||
| 141 | |||
| 142 | /* Get the first/last "ENGINE" type available. */ | ||
| 143 | ENGINE *ENGINE_get_first(void); | ||
| 144 | ENGINE *ENGINE_get_last(void); | ||
| 145 | /* Iterate to the next/previous "ENGINE" type (NULL = end of the list). */ | ||
| 146 | ENGINE *ENGINE_get_next(ENGINE *e); | ||
| 147 | ENGINE *ENGINE_get_prev(ENGINE *e); | ||
| 148 | /* Add another "ENGINE" type into the array. */ | ||
| 149 | int ENGINE_add(ENGINE *e); | ||
| 150 | /* Remove an existing "ENGINE" type from the array. */ | ||
| 151 | int ENGINE_remove(ENGINE *e); | ||
| 152 | /* Retrieve an engine from the list by its unique "id" value. */ | ||
| 153 | ENGINE *ENGINE_by_id(const char *id); | ||
| 154 | |||
| 155 | /* These functions are useful for manufacturing new ENGINE | ||
| 156 | * structures. They don't address reference counting at all - | ||
| 157 | * one uses them to populate an ENGINE structure with personalised | ||
| 158 | * implementations of things prior to using it directly or adding | ||
| 159 | * it to the builtin ENGINE list in OpenSSL. These are also here | ||
| 160 | * so that the ENGINE structure doesn't have to be exposed and | ||
| 161 | * break binary compatibility! | ||
| 162 | * | ||
| 163 | * NB: I'm changing ENGINE_new to force the ENGINE structure to | ||
| 164 | * be allocated from within OpenSSL. See the comment for | ||
| 165 | * ENGINE_get_struct_size(). | ||
| 166 | */ | ||
| 167 | #if 0 | ||
| 168 | ENGINE *ENGINE_new(ENGINE *e); | ||
| 169 | #else | ||
| 170 | ENGINE *ENGINE_new(void); | ||
| 171 | #endif | ||
| 172 | int ENGINE_free(ENGINE *e); | ||
| 173 | int ENGINE_set_id(ENGINE *e, const char *id); | ||
| 174 | int ENGINE_set_name(ENGINE *e, const char *name); | ||
| 175 | int ENGINE_set_RSA(ENGINE *e, RSA_METHOD *rsa_meth); | ||
| 176 | int ENGINE_set_DSA(ENGINE *e, DSA_METHOD *dsa_meth); | ||
| 177 | int ENGINE_set_DH(ENGINE *e, DH_METHOD *dh_meth); | ||
| 178 | int ENGINE_set_RAND(ENGINE *e, RAND_METHOD *rand_meth); | ||
| 179 | int ENGINE_set_BN_mod_exp(ENGINE *e, BN_MOD_EXP bn_mod_exp); | ||
| 180 | int ENGINE_set_BN_mod_exp_crt(ENGINE *e, BN_MOD_EXP_CRT bn_mod_exp_crt); | ||
| 181 | int ENGINE_set_init_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR init_f); | ||
| 182 | int ENGINE_set_finish_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR finish_f); | ||
| 183 | int ENGINE_set_ctrl_function(ENGINE *e, ENGINE_CTRL_FUNC_PTR ctrl_f); | ||
| 184 | |||
| 185 | /* These return values from within the ENGINE structure. These can | ||
| 186 | * be useful with functional references as well as structural | ||
| 187 | * references - it depends which you obtained. Using the result | ||
| 188 | * for functional purposes if you only obtained a structural | ||
| 189 | * reference may be problematic! */ | ||
| 190 | const char *ENGINE_get_id(ENGINE *e); | ||
| 191 | const char *ENGINE_get_name(ENGINE *e); | ||
| 192 | RSA_METHOD *ENGINE_get_RSA(ENGINE *e); | ||
| 193 | DSA_METHOD *ENGINE_get_DSA(ENGINE *e); | ||
| 194 | DH_METHOD *ENGINE_get_DH(ENGINE *e); | ||
| 195 | RAND_METHOD *ENGINE_get_RAND(ENGINE *e); | ||
| 196 | BN_MOD_EXP ENGINE_get_BN_mod_exp(ENGINE *e); | ||
| 197 | BN_MOD_EXP_CRT ENGINE_get_BN_mod_exp_crt(ENGINE *e); | ||
| 198 | ENGINE_GEN_INT_FUNC_PTR ENGINE_get_init_function(ENGINE *e); | ||
| 199 | ENGINE_GEN_INT_FUNC_PTR ENGINE_get_finish_function(ENGINE *e); | ||
| 200 | ENGINE_CTRL_FUNC_PTR ENGINE_get_ctrl_function(ENGINE *e); | ||
| 201 | |||
| 202 | /* ENGINE_new is normally passed a NULL in the first parameter because | ||
| 203 | * the calling code doesn't have access to the definition of the ENGINE | ||
| 204 | * structure (for good reason). However, if the caller wishes to use | ||
| 205 | * its own memory allocation or use a static array, the following call | ||
| 206 | * should be used to check the amount of memory the ENGINE structure | ||
| 207 | * will occupy. This will make the code more future-proof. | ||
| 208 | * | ||
| 209 | * NB: I'm "#if 0"-ing this out because it's better to force the use of | ||
| 210 | * internally allocated memory. See similar change in ENGINE_new(). | ||
| 211 | */ | ||
| 212 | #if 0 | ||
| 213 | int ENGINE_get_struct_size(void); | ||
| 214 | #endif | ||
| 215 | |||
| 216 | /* FUNCTIONAL functions. These functions deal with ENGINE structures | ||
| 217 | * that have (or will) be initialised for use. Broadly speaking, the | ||
| 218 | * structural functions are useful for iterating the list of available | ||
| 219 | * engine types, creating new engine types, and other "list" operations. | ||
| 220 | * These functions actually deal with ENGINEs that are to be used. As | ||
| 221 | * such these functions can fail (if applicable) when particular | ||
| 222 | * engines are unavailable - eg. if a hardware accelerator is not | ||
| 223 | * attached or not functioning correctly. Each ENGINE has 2 reference | ||
| 224 | * counts; structural and functional. Every time a functional reference | ||
| 225 | * is obtained or released, a corresponding structural reference is | ||
| 226 | * automatically obtained or released too. */ | ||
| 227 | |||
| 228 | /* Initialise a engine type for use (or up its reference count if it's | ||
| 229 | * already in use). This will fail if the engine is not currently | ||
| 230 | * operational and cannot initialise. */ | ||
| 231 | int ENGINE_init(ENGINE *e); | ||
| 232 | /* Free a functional reference to a engine type. This does not require | ||
| 233 | * a corresponding call to ENGINE_free as it also releases a structural | ||
| 234 | * reference. */ | ||
| 235 | int ENGINE_finish(ENGINE *e); | ||
| 236 | /* Send control parametrised commands to the engine. The possibilities | ||
| 237 | * to send down an integer, a pointer to data or a function pointer are | ||
| 238 | * provided. Any of the parameters may or may not be NULL, depending | ||
| 239 | * on the command number */ | ||
| 240 | /* WARNING: This is currently experimental and may change radically! */ | ||
| 241 | int ENGINE_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)()); | ||
| 242 | |||
| 243 | /* The following functions handle keys that are stored in some secondary | ||
| 244 | * location, handled by the engine. The storage may be on a card or | ||
| 245 | * whatever. */ | ||
| 246 | EVP_PKEY *ENGINE_load_private_key(ENGINE *e, const char *key_id, | ||
| 247 | const char *passphrase); | ||
| 248 | EVP_PKEY *ENGINE_load_public_key(ENGINE *e, const char *key_id, | ||
| 249 | const char *passphrase); | ||
| 250 | |||
| 251 | /* This returns a pointer for the current ENGINE structure that | ||
| 252 | * is (by default) performing any RSA operations. The value returned | ||
| 253 | * is an incremented reference, so it should be free'd (ENGINE_finish) | ||
| 254 | * before it is discarded. */ | ||
| 255 | ENGINE *ENGINE_get_default_RSA(void); | ||
| 256 | /* Same for the other "methods" */ | ||
| 257 | ENGINE *ENGINE_get_default_DSA(void); | ||
| 258 | ENGINE *ENGINE_get_default_DH(void); | ||
| 259 | ENGINE *ENGINE_get_default_RAND(void); | ||
| 260 | ENGINE *ENGINE_get_default_BN_mod_exp(void); | ||
| 261 | ENGINE *ENGINE_get_default_BN_mod_exp_crt(void); | ||
| 262 | |||
| 263 | /* This sets a new default ENGINE structure for performing RSA | ||
| 264 | * operations. If the result is non-zero (success) then the ENGINE | ||
| 265 | * structure will have had its reference count up'd so the caller | ||
| 266 | * should still free their own reference 'e'. */ | ||
| 267 | int ENGINE_set_default_RSA(ENGINE *e); | ||
| 268 | /* Same for the other "methods" */ | ||
| 269 | int ENGINE_set_default_DSA(ENGINE *e); | ||
| 270 | int ENGINE_set_default_DH(ENGINE *e); | ||
| 271 | int ENGINE_set_default_RAND(ENGINE *e); | ||
| 272 | int ENGINE_set_default_BN_mod_exp(ENGINE *e); | ||
| 273 | int ENGINE_set_default_BN_mod_exp_crt(ENGINE *e); | ||
| 274 | |||
| 275 | /* The combination "set" - the flags are bitwise "OR"d from the | ||
| 276 | * ENGINE_METHOD_*** defines above. */ | ||
| 277 | int ENGINE_set_default(ENGINE *e, unsigned int flags); | ||
| 278 | |||
| 279 | /* Obligatory error function. */ | ||
| 280 | void ERR_load_ENGINE_strings(void); | ||
| 281 | |||
| 282 | /* | ||
| 283 | * Error codes for all engine functions. NB: We use "generic" | ||
| 284 | * function names instead of per-implementation ones because this | ||
| 285 | * levels the playing field for externally implemented bootstrapped | ||
| 286 | * support code. As the filename and line number is included, it's | ||
| 287 | * more important to indicate the type of function, so that | ||
| 288 | * bootstrapped code (that can't easily add its own errors in) can | ||
| 289 | * use the same error codes too. | ||
| 290 | */ | ||
| 291 | |||
| 292 | /* BEGIN ERROR CODES */ | ||
| 293 | /* The following lines are auto generated by the script mkerr.pl. Any changes | ||
| 294 | * made after this point may be overwritten when the script is next run. | ||
| 295 | */ | ||
| 296 | |||
| 297 | /* Error codes for the ENGINE functions. */ | ||
| 298 | |||
| 299 | /* Function codes. */ | ||
| 300 | #define ENGINE_F_ATALLA_FINISH 135 | ||
| 301 | #define ENGINE_F_ATALLA_INIT 136 | ||
| 302 | #define ENGINE_F_ATALLA_MOD_EXP 137 | ||
| 303 | #define ENGINE_F_ATALLA_RSA_MOD_EXP 138 | ||
| 304 | #define ENGINE_F_CSWIFT_DSA_SIGN 133 | ||
| 305 | #define ENGINE_F_CSWIFT_DSA_VERIFY 134 | ||
| 306 | #define ENGINE_F_CSWIFT_FINISH 100 | ||
| 307 | #define ENGINE_F_CSWIFT_INIT 101 | ||
| 308 | #define ENGINE_F_CSWIFT_MOD_EXP 102 | ||
| 309 | #define ENGINE_F_CSWIFT_MOD_EXP_CRT 103 | ||
| 310 | #define ENGINE_F_CSWIFT_RSA_MOD_EXP 104 | ||
| 311 | #define ENGINE_F_ENGINE_ADD 105 | ||
| 312 | #define ENGINE_F_ENGINE_BY_ID 106 | ||
| 313 | #define ENGINE_F_ENGINE_CTRL 142 | ||
| 314 | #define ENGINE_F_ENGINE_FINISH 107 | ||
| 315 | #define ENGINE_F_ENGINE_FREE 108 | ||
| 316 | #define ENGINE_F_ENGINE_GET_BN_MOD_EXP 109 | ||
| 317 | #define ENGINE_F_ENGINE_GET_BN_MOD_EXP_CRT 110 | ||
| 318 | #define ENGINE_F_ENGINE_GET_CTRL_FUNCTION 144 | ||
| 319 | #define ENGINE_F_ENGINE_GET_DH 111 | ||
| 320 | #define ENGINE_F_ENGINE_GET_DSA 112 | ||
| 321 | #define ENGINE_F_ENGINE_GET_FINISH_FUNCTION 145 | ||
| 322 | #define ENGINE_F_ENGINE_GET_ID 113 | ||
| 323 | #define ENGINE_F_ENGINE_GET_INIT_FUNCTION 146 | ||
| 324 | #define ENGINE_F_ENGINE_GET_NAME 114 | ||
| 325 | #define ENGINE_F_ENGINE_GET_NEXT 115 | ||
| 326 | #define ENGINE_F_ENGINE_GET_PREV 116 | ||
| 327 | #define ENGINE_F_ENGINE_GET_RAND 117 | ||
| 328 | #define ENGINE_F_ENGINE_GET_RSA 118 | ||
| 329 | #define ENGINE_F_ENGINE_INIT 119 | ||
| 330 | #define ENGINE_F_ENGINE_LIST_ADD 120 | ||
| 331 | #define ENGINE_F_ENGINE_LIST_REMOVE 121 | ||
| 332 | #define ENGINE_F_ENGINE_LOAD_PRIVATE_KEY 150 | ||
| 333 | #define ENGINE_F_ENGINE_LOAD_PUBLIC_KEY 151 | ||
| 334 | #define ENGINE_F_ENGINE_NEW 122 | ||
| 335 | #define ENGINE_F_ENGINE_REMOVE 123 | ||
| 336 | #define ENGINE_F_ENGINE_SET_BN_MOD_EXP 124 | ||
| 337 | #define ENGINE_F_ENGINE_SET_BN_MOD_EXP_CRT 125 | ||
| 338 | #define ENGINE_F_ENGINE_SET_CTRL_FUNCTION 147 | ||
| 339 | #define ENGINE_F_ENGINE_SET_DEFAULT_TYPE 126 | ||
| 340 | #define ENGINE_F_ENGINE_SET_DH 127 | ||
| 341 | #define ENGINE_F_ENGINE_SET_DSA 128 | ||
| 342 | #define ENGINE_F_ENGINE_SET_FINISH_FUNCTION 148 | ||
| 343 | #define ENGINE_F_ENGINE_SET_ID 129 | ||
| 344 | #define ENGINE_F_ENGINE_SET_INIT_FUNCTION 149 | ||
| 345 | #define ENGINE_F_ENGINE_SET_NAME 130 | ||
| 346 | #define ENGINE_F_ENGINE_SET_RAND 131 | ||
| 347 | #define ENGINE_F_ENGINE_SET_RSA 132 | ||
| 348 | #define ENGINE_F_ENGINE_UNLOAD_KEY 152 | ||
| 349 | #define ENGINE_F_HWCRHK_CTRL 143 | ||
| 350 | #define ENGINE_F_HWCRHK_FINISH 135 | ||
| 351 | #define ENGINE_F_HWCRHK_GET_PASS 155 | ||
| 352 | #define ENGINE_F_HWCRHK_INIT 136 | ||
| 353 | #define ENGINE_F_HWCRHK_LOAD_PRIVKEY 153 | ||
| 354 | #define ENGINE_F_HWCRHK_LOAD_PUBKEY 154 | ||
| 355 | #define ENGINE_F_HWCRHK_MOD_EXP 137 | ||
| 356 | #define ENGINE_F_HWCRHK_MOD_EXP_CRT 138 | ||
| 357 | #define ENGINE_F_HWCRHK_RAND_BYTES 139 | ||
| 358 | #define ENGINE_F_HWCRHK_RSA_MOD_EXP 140 | ||
| 359 | #define ENGINE_F_LOG_MESSAGE 141 | ||
| 360 | |||
| 361 | /* Reason codes. */ | ||
| 362 | #define ENGINE_R_ALREADY_LOADED 100 | ||
| 363 | #define ENGINE_R_BIO_WAS_FREED 121 | ||
| 364 | #define ENGINE_R_BN_CTX_FULL 101 | ||
| 365 | #define ENGINE_R_BN_EXPAND_FAIL 102 | ||
| 366 | #define ENGINE_R_CHIL_ERROR 123 | ||
| 367 | #define ENGINE_R_CONFLICTING_ENGINE_ID 103 | ||
| 368 | #define ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED 119 | ||
| 369 | #define ENGINE_R_DSO_FAILURE 104 | ||
| 370 | #define ENGINE_R_ENGINE_IS_NOT_IN_LIST 105 | ||
| 371 | #define ENGINE_R_FAILED_LOADING_PRIVATE_KEY 128 | ||
| 372 | #define ENGINE_R_FAILED_LOADING_PUBLIC_KEY 129 | ||
| 373 | #define ENGINE_R_FINISH_FAILED 106 | ||
| 374 | #define ENGINE_R_GET_HANDLE_FAILED 107 | ||
| 375 | #define ENGINE_R_ID_OR_NAME_MISSING 108 | ||
| 376 | #define ENGINE_R_INIT_FAILED 109 | ||
| 377 | #define ENGINE_R_INTERNAL_LIST_ERROR 110 | ||
| 378 | #define ENGINE_R_MISSING_KEY_COMPONENTS 111 | ||
| 379 | #define ENGINE_R_NOT_INITIALISED 117 | ||
| 380 | #define ENGINE_R_NOT_LOADED 112 | ||
| 381 | #define ENGINE_R_NO_CALLBACK 127 | ||
| 382 | #define ENGINE_R_NO_CONTROL_FUNCTION 120 | ||
| 383 | #define ENGINE_R_NO_KEY 124 | ||
| 384 | #define ENGINE_R_NO_LOAD_FUNCTION 125 | ||
| 385 | #define ENGINE_R_NO_REFERENCE 130 | ||
| 386 | #define ENGINE_R_NO_SUCH_ENGINE 116 | ||
| 387 | #define ENGINE_R_NO_UNLOAD_FUNCTION 126 | ||
| 388 | #define ENGINE_R_PROVIDE_PARAMETERS 113 | ||
| 389 | #define ENGINE_R_REQUEST_FAILED 114 | ||
| 390 | #define ENGINE_R_REQUEST_FALLBACK 118 | ||
| 391 | #define ENGINE_R_SIZE_TOO_LARGE_OR_TOO_SMALL 122 | ||
| 392 | #define ENGINE_R_UNIT_FAILURE 115 | ||
| 393 | |||
| 394 | #ifdef __cplusplus | ||
| 395 | } | ||
| 396 | #endif | ||
| 397 | #endif | ||
| 398 | |||
diff --git a/src/lib/libcrypto/engine/engine_err.c b/src/lib/libcrypto/engine/engine_err.c new file mode 100644 index 0000000000..0d7a31f6d5 --- /dev/null +++ b/src/lib/libcrypto/engine/engine_err.c | |||
| @@ -0,0 +1,183 @@ | |||
| 1 | /* crypto/engine/engine_err.c */ | ||
| 2 | /* ==================================================================== | ||
| 3 | * Copyright (c) 1999 The OpenSSL Project. All rights reserved. | ||
| 4 | * | ||
| 5 | * Redistribution and use in source and binary forms, with or without | ||
| 6 | * modification, are permitted provided that the following conditions | ||
| 7 | * are met: | ||
| 8 | * | ||
| 9 | * 1. Redistributions of source code must retain the above copyright | ||
| 10 | * notice, this list of conditions and the following disclaimer. | ||
| 11 | * | ||
| 12 | * 2. Redistributions in binary form must reproduce the above copyright | ||
| 13 | * notice, this list of conditions and the following disclaimer in | ||
| 14 | * the documentation and/or other materials provided with the | ||
| 15 | * distribution. | ||
| 16 | * | ||
| 17 | * 3. All advertising materials mentioning features or use of this | ||
| 18 | * software must display the following acknowledgment: | ||
| 19 | * "This product includes software developed by the OpenSSL Project | ||
| 20 | * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" | ||
| 21 | * | ||
| 22 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | ||
| 23 | * endorse or promote products derived from this software without | ||
| 24 | * prior written permission. For written permission, please contact | ||
| 25 | * openssl-core@OpenSSL.org. | ||
| 26 | * | ||
| 27 | * 5. Products derived from this software may not be called "OpenSSL" | ||
| 28 | * nor may "OpenSSL" appear in their names without prior written | ||
| 29 | * permission of the OpenSSL Project. | ||
| 30 | * | ||
| 31 | * 6. Redistributions of any form whatsoever must retain the following | ||
| 32 | * acknowledgment: | ||
| 33 | * "This product includes software developed by the OpenSSL Project | ||
| 34 | * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" | ||
| 35 | * | ||
| 36 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | ||
| 37 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
| 38 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
| 39 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | ||
| 40 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
| 41 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
| 42 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
| 43 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| 44 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
| 45 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
| 46 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | ||
| 47 | * OF THE POSSIBILITY OF SUCH DAMAGE. | ||
| 48 | * ==================================================================== | ||
| 49 | * | ||
| 50 | * This product includes cryptographic software written by Eric Young | ||
| 51 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
| 52 | * Hudson (tjh@cryptsoft.com). | ||
| 53 | * | ||
| 54 | */ | ||
| 55 | |||
| 56 | /* NOTE: this file was auto generated by the mkerr.pl script: any changes | ||
| 57 | * made to it will be overwritten when the script next updates this file, | ||
| 58 | * only reason strings will be preserved. | ||
| 59 | */ | ||
| 60 | |||
| 61 | #include <stdio.h> | ||
| 62 | #include <openssl/err.h> | ||
| 63 | #include <openssl/engine.h> | ||
| 64 | |||
| 65 | /* BEGIN ERROR CODES */ | ||
| 66 | #ifndef NO_ERR | ||
| 67 | static ERR_STRING_DATA ENGINE_str_functs[]= | ||
| 68 | { | ||
| 69 | {ERR_PACK(0,ENGINE_F_ATALLA_FINISH,0), "ATALLA_FINISH"}, | ||
| 70 | {ERR_PACK(0,ENGINE_F_ATALLA_INIT,0), "ATALLA_INIT"}, | ||
| 71 | {ERR_PACK(0,ENGINE_F_ATALLA_MOD_EXP,0), "ATALLA_MOD_EXP"}, | ||
| 72 | {ERR_PACK(0,ENGINE_F_ATALLA_RSA_MOD_EXP,0), "ATALLA_RSA_MOD_EXP"}, | ||
| 73 | {ERR_PACK(0,ENGINE_F_CSWIFT_DSA_SIGN,0), "CSWIFT_DSA_SIGN"}, | ||
| 74 | {ERR_PACK(0,ENGINE_F_CSWIFT_DSA_VERIFY,0), "CSWIFT_DSA_VERIFY"}, | ||
| 75 | {ERR_PACK(0,ENGINE_F_CSWIFT_FINISH,0), "CSWIFT_FINISH"}, | ||
| 76 | {ERR_PACK(0,ENGINE_F_CSWIFT_INIT,0), "CSWIFT_INIT"}, | ||
| 77 | {ERR_PACK(0,ENGINE_F_CSWIFT_MOD_EXP,0), "CSWIFT_MOD_EXP"}, | ||
| 78 | {ERR_PACK(0,ENGINE_F_CSWIFT_MOD_EXP_CRT,0), "CSWIFT_MOD_EXP_CRT"}, | ||
| 79 | {ERR_PACK(0,ENGINE_F_CSWIFT_RSA_MOD_EXP,0), "CSWIFT_RSA_MOD_EXP"}, | ||
| 80 | {ERR_PACK(0,ENGINE_F_ENGINE_ADD,0), "ENGINE_add"}, | ||
| 81 | {ERR_PACK(0,ENGINE_F_ENGINE_BY_ID,0), "ENGINE_by_id"}, | ||
| 82 | {ERR_PACK(0,ENGINE_F_ENGINE_CTRL,0), "ENGINE_ctrl"}, | ||
| 83 | {ERR_PACK(0,ENGINE_F_ENGINE_FINISH,0), "ENGINE_finish"}, | ||
| 84 | {ERR_PACK(0,ENGINE_F_ENGINE_FREE,0), "ENGINE_free"}, | ||
| 85 | {ERR_PACK(0,ENGINE_F_ENGINE_GET_BN_MOD_EXP,0), "ENGINE_get_BN_mod_exp"}, | ||
| 86 | {ERR_PACK(0,ENGINE_F_ENGINE_GET_BN_MOD_EXP_CRT,0), "ENGINE_get_BN_mod_exp_crt"}, | ||
| 87 | {ERR_PACK(0,ENGINE_F_ENGINE_GET_CTRL_FUNCTION,0), "ENGINE_get_ctrl_function"}, | ||
| 88 | {ERR_PACK(0,ENGINE_F_ENGINE_GET_DH,0), "ENGINE_get_DH"}, | ||
| 89 | {ERR_PACK(0,ENGINE_F_ENGINE_GET_DSA,0), "ENGINE_get_DSA"}, | ||
| 90 | {ERR_PACK(0,ENGINE_F_ENGINE_GET_FINISH_FUNCTION,0), "ENGINE_get_finish_function"}, | ||
| 91 | {ERR_PACK(0,ENGINE_F_ENGINE_GET_ID,0), "ENGINE_get_id"}, | ||
| 92 | {ERR_PACK(0,ENGINE_F_ENGINE_GET_INIT_FUNCTION,0), "ENGINE_get_init_function"}, | ||
| 93 | {ERR_PACK(0,ENGINE_F_ENGINE_GET_NAME,0), "ENGINE_get_name"}, | ||
| 94 | {ERR_PACK(0,ENGINE_F_ENGINE_GET_NEXT,0), "ENGINE_get_next"}, | ||
| 95 | {ERR_PACK(0,ENGINE_F_ENGINE_GET_PREV,0), "ENGINE_get_prev"}, | ||
| 96 | {ERR_PACK(0,ENGINE_F_ENGINE_GET_RAND,0), "ENGINE_get_RAND"}, | ||
| 97 | {ERR_PACK(0,ENGINE_F_ENGINE_GET_RSA,0), "ENGINE_get_RSA"}, | ||
| 98 | {ERR_PACK(0,ENGINE_F_ENGINE_INIT,0), "ENGINE_init"}, | ||
| 99 | {ERR_PACK(0,ENGINE_F_ENGINE_LIST_ADD,0), "ENGINE_LIST_ADD"}, | ||
| 100 | {ERR_PACK(0,ENGINE_F_ENGINE_LIST_REMOVE,0), "ENGINE_LIST_REMOVE"}, | ||
| 101 | {ERR_PACK(0,ENGINE_F_ENGINE_LOAD_PRIVATE_KEY,0), "ENGINE_load_private_key"}, | ||
| 102 | {ERR_PACK(0,ENGINE_F_ENGINE_LOAD_PUBLIC_KEY,0), "ENGINE_load_public_key"}, | ||
| 103 | {ERR_PACK(0,ENGINE_F_ENGINE_NEW,0), "ENGINE_new"}, | ||
| 104 | {ERR_PACK(0,ENGINE_F_ENGINE_REMOVE,0), "ENGINE_remove"}, | ||
| 105 | {ERR_PACK(0,ENGINE_F_ENGINE_SET_BN_MOD_EXP,0), "ENGINE_set_BN_mod_exp"}, | ||
| 106 | {ERR_PACK(0,ENGINE_F_ENGINE_SET_BN_MOD_EXP_CRT,0), "ENGINE_set_BN_mod_exp_crt"}, | ||
| 107 | {ERR_PACK(0,ENGINE_F_ENGINE_SET_CTRL_FUNCTION,0), "ENGINE_set_ctrl_function"}, | ||
| 108 | {ERR_PACK(0,ENGINE_F_ENGINE_SET_DEFAULT_TYPE,0), "ENGINE_SET_DEFAULT_TYPE"}, | ||
| 109 | {ERR_PACK(0,ENGINE_F_ENGINE_SET_DH,0), "ENGINE_set_DH"}, | ||
| 110 | {ERR_PACK(0,ENGINE_F_ENGINE_SET_DSA,0), "ENGINE_set_DSA"}, | ||
| 111 | {ERR_PACK(0,ENGINE_F_ENGINE_SET_FINISH_FUNCTION,0), "ENGINE_set_finish_function"}, | ||
| 112 | {ERR_PACK(0,ENGINE_F_ENGINE_SET_ID,0), "ENGINE_set_id"}, | ||
| 113 | {ERR_PACK(0,ENGINE_F_ENGINE_SET_INIT_FUNCTION,0), "ENGINE_set_init_function"}, | ||
| 114 | {ERR_PACK(0,ENGINE_F_ENGINE_SET_NAME,0), "ENGINE_set_name"}, | ||
| 115 | {ERR_PACK(0,ENGINE_F_ENGINE_SET_RAND,0), "ENGINE_set_RAND"}, | ||
| 116 | {ERR_PACK(0,ENGINE_F_ENGINE_SET_RSA,0), "ENGINE_set_RSA"}, | ||
| 117 | {ERR_PACK(0,ENGINE_F_ENGINE_UNLOAD_KEY,0), "ENGINE_UNLOAD_KEY"}, | ||
| 118 | {ERR_PACK(0,ENGINE_F_HWCRHK_CTRL,0), "HWCRHK_CTRL"}, | ||
| 119 | {ERR_PACK(0,ENGINE_F_HWCRHK_FINISH,0), "HWCRHK_FINISH"}, | ||
| 120 | {ERR_PACK(0,ENGINE_F_HWCRHK_GET_PASS,0), "HWCRHK_GET_PASS"}, | ||
| 121 | {ERR_PACK(0,ENGINE_F_HWCRHK_INIT,0), "HWCRHK_INIT"}, | ||
| 122 | {ERR_PACK(0,ENGINE_F_HWCRHK_LOAD_PRIVKEY,0), "HWCRHK_LOAD_PRIVKEY"}, | ||
| 123 | {ERR_PACK(0,ENGINE_F_HWCRHK_LOAD_PUBKEY,0), "HWCRHK_LOAD_PUBKEY"}, | ||
| 124 | {ERR_PACK(0,ENGINE_F_HWCRHK_MOD_EXP,0), "HWCRHK_MOD_EXP"}, | ||
| 125 | {ERR_PACK(0,ENGINE_F_HWCRHK_MOD_EXP_CRT,0), "HWCRHK_MOD_EXP_CRT"}, | ||
| 126 | {ERR_PACK(0,ENGINE_F_HWCRHK_RAND_BYTES,0), "HWCRHK_RAND_BYTES"}, | ||
| 127 | {ERR_PACK(0,ENGINE_F_HWCRHK_RSA_MOD_EXP,0), "HWCRHK_RSA_MOD_EXP"}, | ||
| 128 | {ERR_PACK(0,ENGINE_F_LOG_MESSAGE,0), "LOG_MESSAGE"}, | ||
| 129 | {0,NULL} | ||
| 130 | }; | ||
| 131 | |||
| 132 | static ERR_STRING_DATA ENGINE_str_reasons[]= | ||
| 133 | { | ||
| 134 | {ENGINE_R_ALREADY_LOADED ,"already loaded"}, | ||
| 135 | {ENGINE_R_BIO_WAS_FREED ,"bio was freed"}, | ||
| 136 | {ENGINE_R_BN_CTX_FULL ,"BN_CTX full"}, | ||
| 137 | {ENGINE_R_BN_EXPAND_FAIL ,"bn_expand fail"}, | ||
| 138 | {ENGINE_R_CHIL_ERROR ,"chil error"}, | ||
| 139 | {ENGINE_R_CONFLICTING_ENGINE_ID ,"conflicting engine id"}, | ||
| 140 | {ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED ,"ctrl command not implemented"}, | ||
| 141 | {ENGINE_R_DSO_FAILURE ,"DSO failure"}, | ||
| 142 | {ENGINE_R_ENGINE_IS_NOT_IN_LIST ,"engine is not in the list"}, | ||
| 143 | {ENGINE_R_FAILED_LOADING_PRIVATE_KEY ,"failed loading private key"}, | ||
| 144 | {ENGINE_R_FAILED_LOADING_PUBLIC_KEY ,"failed loading public key"}, | ||
| 145 | {ENGINE_R_FINISH_FAILED ,"finish failed"}, | ||
| 146 | {ENGINE_R_GET_HANDLE_FAILED ,"could not obtain hardware handle"}, | ||
| 147 | {ENGINE_R_ID_OR_NAME_MISSING ,"'id' or 'name' missing"}, | ||
| 148 | {ENGINE_R_INIT_FAILED ,"init failed"}, | ||
| 149 | {ENGINE_R_INTERNAL_LIST_ERROR ,"internal list error"}, | ||
| 150 | {ENGINE_R_MISSING_KEY_COMPONENTS ,"missing key components"}, | ||
| 151 | {ENGINE_R_NOT_INITIALISED ,"not initialised"}, | ||
| 152 | {ENGINE_R_NOT_LOADED ,"not loaded"}, | ||
| 153 | {ENGINE_R_NO_CALLBACK ,"no callback"}, | ||
| 154 | {ENGINE_R_NO_CONTROL_FUNCTION ,"no control function"}, | ||
| 155 | {ENGINE_R_NO_KEY ,"no key"}, | ||
| 156 | {ENGINE_R_NO_LOAD_FUNCTION ,"no load function"}, | ||
| 157 | {ENGINE_R_NO_REFERENCE ,"no reference"}, | ||
| 158 | {ENGINE_R_NO_SUCH_ENGINE ,"no such engine"}, | ||
| 159 | {ENGINE_R_NO_UNLOAD_FUNCTION ,"no unload function"}, | ||
| 160 | {ENGINE_R_PROVIDE_PARAMETERS ,"provide parameters"}, | ||
| 161 | {ENGINE_R_REQUEST_FAILED ,"request failed"}, | ||
| 162 | {ENGINE_R_REQUEST_FALLBACK ,"request fallback"}, | ||
| 163 | {ENGINE_R_SIZE_TOO_LARGE_OR_TOO_SMALL ,"size too large or too small"}, | ||
| 164 | {ENGINE_R_UNIT_FAILURE ,"unit failure"}, | ||
| 165 | {0,NULL} | ||
| 166 | }; | ||
| 167 | |||
| 168 | #endif | ||
| 169 | |||
| 170 | void ERR_load_ENGINE_strings(void) | ||
| 171 | { | ||
| 172 | static int init=1; | ||
| 173 | |||
| 174 | if (init) | ||
| 175 | { | ||
| 176 | init=0; | ||
| 177 | #ifndef NO_ERR | ||
| 178 | ERR_load_strings(ERR_LIB_ENGINE,ENGINE_str_functs); | ||
| 179 | ERR_load_strings(ERR_LIB_ENGINE,ENGINE_str_reasons); | ||
| 180 | #endif | ||
| 181 | |||
| 182 | } | ||
| 183 | } | ||
diff --git a/src/lib/libcrypto/engine/engine_int.h b/src/lib/libcrypto/engine/engine_int.h new file mode 100644 index 0000000000..447fa2a320 --- /dev/null +++ b/src/lib/libcrypto/engine/engine_int.h | |||
| @@ -0,0 +1,160 @@ | |||
| 1 | /* crypto/engine/engine_int.h */ | ||
| 2 | /* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL | ||
| 3 | * project 2000. | ||
| 4 | */ | ||
| 5 | /* ==================================================================== | ||
| 6 | * Copyright (c) 1999 The OpenSSL Project. All rights reserved. | ||
| 7 | * | ||
| 8 | * Redistribution and use in source and binary forms, with or without | ||
| 9 | * modification, are permitted provided that the following conditions | ||
| 10 | * are met: | ||
| 11 | * | ||
| 12 | * 1. Redistributions of source code must retain the above copyright | ||
| 13 | * notice, this list of conditions and the following disclaimer. | ||
| 14 | * | ||
| 15 | * 2. Redistributions in binary form must reproduce the above copyright | ||
| 16 | * notice, this list of conditions and the following disclaimer in | ||
| 17 | * the documentation and/or other materials provided with the | ||
| 18 | * distribution. | ||
| 19 | * | ||
| 20 | * 3. All advertising materials mentioning features or use of this | ||
| 21 | * software must display the following acknowledgment: | ||
| 22 | * "This product includes software developed by the OpenSSL Project | ||
| 23 | * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" | ||
| 24 | * | ||
| 25 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | ||
| 26 | * endorse or promote products derived from this software without | ||
| 27 | * prior written permission. For written permission, please contact | ||
| 28 | * licensing@OpenSSL.org. | ||
| 29 | * | ||
| 30 | * 5. Products derived from this software may not be called "OpenSSL" | ||
| 31 | * nor may "OpenSSL" appear in their names without prior written | ||
| 32 | * permission of the OpenSSL Project. | ||
| 33 | * | ||
| 34 | * 6. Redistributions of any form whatsoever must retain the following | ||
| 35 | * acknowledgment: | ||
| 36 | * "This product includes software developed by the OpenSSL Project | ||
| 37 | * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" | ||
| 38 | * | ||
| 39 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | ||
| 40 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
| 41 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
| 42 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | ||
| 43 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
| 44 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
| 45 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
| 46 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| 47 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
| 48 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
| 49 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | ||
| 50 | * OF THE POSSIBILITY OF SUCH DAMAGE. | ||
| 51 | * ==================================================================== | ||
| 52 | * | ||
| 53 | * This product includes cryptographic software written by Eric Young | ||
| 54 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
| 55 | * Hudson (tjh@cryptsoft.com). | ||
| 56 | * | ||
| 57 | */ | ||
| 58 | |||
| 59 | #ifndef HEADER_ENGINE_INT_H | ||
| 60 | #define HEADER_ENGINE_INT_H | ||
| 61 | |||
| 62 | #include <openssl/rsa.h> | ||
| 63 | #include <openssl/dsa.h> | ||
| 64 | #include <openssl/dh.h> | ||
| 65 | #include <openssl/rand.h> | ||
| 66 | #include <openssl/bn.h> | ||
| 67 | #include <openssl/evp.h> | ||
| 68 | |||
| 69 | #ifdef __cplusplus | ||
| 70 | extern "C" { | ||
| 71 | #endif | ||
| 72 | |||
| 73 | /* Bitwise OR-able values for the "flags" variable in ENGINE. */ | ||
| 74 | #define ENGINE_FLAGS_MALLOCED 0x0001 | ||
| 75 | |||
| 76 | #ifndef HEADER_ENGINE_H | ||
| 77 | /* Regrettably, we need to reproduce the "BN" function types here | ||
| 78 | * because there is no such "BIGNUM_METHOD" as there is with RSA, | ||
| 79 | * DSA, etc. We do this so that we don't have a case where engine.h | ||
| 80 | * and engine_int.h conflict with each other. */ | ||
| 81 | typedef int (*BN_MOD_EXP)(BIGNUM *r, BIGNUM *a, const BIGNUM *p, | ||
| 82 | const BIGNUM *m, BN_CTX *ctx); | ||
| 83 | |||
| 84 | /* private key operation for RSA, provided seperately in case other | ||
| 85 | * RSA implementations wish to use it. */ | ||
| 86 | typedef int (*BN_MOD_EXP_CRT)(BIGNUM *r, BIGNUM *a, const BIGNUM *p, | ||
| 87 | const BIGNUM *q, const BIGNUM *dmp1, const BIGNUM *dmq1, | ||
| 88 | const BIGNUM *iqmp, BN_CTX *ctx); | ||
| 89 | |||
| 90 | /* Generic function pointer */ | ||
| 91 | typedef int (*ENGINE_GEN_FUNC_PTR)(); | ||
| 92 | /* Generic function pointer taking no arguments */ | ||
| 93 | typedef int (*ENGINE_GEN_INT_FUNC_PTR)(void); | ||
| 94 | /* Specific control function pointer */ | ||
| 95 | typedef int (*ENGINE_CTRL_FUNC_PTR)(int cmd, long i, void *p, void (*f)()); | ||
| 96 | |||
| 97 | #endif | ||
| 98 | |||
| 99 | /* This is a structure for storing implementations of various crypto | ||
| 100 | * algorithms and functions. */ | ||
| 101 | typedef struct engine_st | ||
| 102 | { | ||
| 103 | const char *id; | ||
| 104 | const char *name; | ||
| 105 | RSA_METHOD *rsa_meth; | ||
| 106 | DSA_METHOD *dsa_meth; | ||
| 107 | DH_METHOD *dh_meth; | ||
| 108 | RAND_METHOD *rand_meth; | ||
| 109 | BN_MOD_EXP bn_mod_exp; | ||
| 110 | BN_MOD_EXP_CRT bn_mod_exp_crt; | ||
| 111 | int (*init)(void); | ||
| 112 | int (*finish)(void); | ||
| 113 | int (*ctrl)(int cmd, long i, void *p, void (*f)()); | ||
| 114 | EVP_PKEY *(*load_privkey)(const char *key_id, const char *passphrase); | ||
| 115 | EVP_PKEY *(*load_pubkey)(const char *key_id, const char *passphrase); | ||
| 116 | int flags; | ||
| 117 | /* reference count on the structure itself */ | ||
| 118 | int struct_ref; | ||
| 119 | /* reference count on usability of the engine type. NB: This | ||
| 120 | * controls the loading and initialisation of any functionlity | ||
| 121 | * required by this engine, whereas the previous count is | ||
| 122 | * simply to cope with (de)allocation of this structure. Hence, | ||
| 123 | * running_ref <= struct_ref at all times. */ | ||
| 124 | int funct_ref; | ||
| 125 | /* Used to maintain the linked-list of engines. */ | ||
| 126 | struct engine_st *prev; | ||
| 127 | struct engine_st *next; | ||
| 128 | } ENGINE; | ||
| 129 | |||
| 130 | /* BUILT-IN ENGINES. (these functions are only ever called once and | ||
| 131 | * do not return references - they are purely for bootstrapping). */ | ||
| 132 | |||
| 133 | /* Returns a structure of software only methods (the default). */ | ||
| 134 | ENGINE *ENGINE_openssl(); | ||
| 135 | |||
| 136 | #ifndef NO_HW | ||
| 137 | |||
| 138 | #ifndef NO_HW_CSWIFT | ||
| 139 | /* Returns a structure of cswift methods ... NB: This can exist and be | ||
| 140 | * "used" even on non-cswift systems because the "init" will fail if the | ||
| 141 | * card/library are not found. */ | ||
| 142 | ENGINE *ENGINE_cswift(); | ||
| 143 | #endif /* !NO_HW_CSWIFT */ | ||
| 144 | |||
| 145 | #ifndef NO_HW_NCIPHER | ||
| 146 | ENGINE *ENGINE_ncipher(); | ||
| 147 | #endif /* !NO_HW_NCIPHER */ | ||
| 148 | |||
| 149 | #ifndef NO_HW_ATALLA | ||
| 150 | /* Returns a structure of atalla methods. */ | ||
| 151 | ENGINE *ENGINE_atalla(); | ||
| 152 | #endif /* !NO_HW_ATALLA */ | ||
| 153 | |||
| 154 | #endif /* !NO_HW */ | ||
| 155 | |||
| 156 | #ifdef __cplusplus | ||
| 157 | } | ||
| 158 | #endif | ||
| 159 | |||
| 160 | #endif /* HEADER_ENGINE_INT_H */ | ||
diff --git a/src/lib/libcrypto/engine/engine_lib.c b/src/lib/libcrypto/engine/engine_lib.c new file mode 100644 index 0000000000..1df07af03a --- /dev/null +++ b/src/lib/libcrypto/engine/engine_lib.c | |||
| @@ -0,0 +1,488 @@ | |||
| 1 | /* crypto/engine/engine_lib.c */ | ||
| 2 | /* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL | ||
| 3 | * project 2000. | ||
| 4 | */ | ||
| 5 | /* ==================================================================== | ||
| 6 | * Copyright (c) 1999 The OpenSSL Project. All rights reserved. | ||
| 7 | * | ||
| 8 | * Redistribution and use in source and binary forms, with or without | ||
| 9 | * modification, are permitted provided that the following conditions | ||
| 10 | * are met: | ||
| 11 | * | ||
| 12 | * 1. Redistributions of source code must retain the above copyright | ||
| 13 | * notice, this list of conditions and the following disclaimer. | ||
| 14 | * | ||
| 15 | * 2. Redistributions in binary form must reproduce the above copyright | ||
| 16 | * notice, this list of conditions and the following disclaimer in | ||
| 17 | * the documentation and/or other materials provided with the | ||
| 18 | * distribution. | ||
| 19 | * | ||
| 20 | * 3. All advertising materials mentioning features or use of this | ||
| 21 | * software must display the following acknowledgment: | ||
| 22 | * "This product includes software developed by the OpenSSL Project | ||
| 23 | * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" | ||
| 24 | * | ||
| 25 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | ||
| 26 | * endorse or promote products derived from this software without | ||
| 27 | * prior written permission. For written permission, please contact | ||
| 28 | * licensing@OpenSSL.org. | ||
| 29 | * | ||
| 30 | * 5. Products derived from this software may not be called "OpenSSL" | ||
| 31 | * nor may "OpenSSL" appear in their names without prior written | ||
| 32 | * permission of the OpenSSL Project. | ||
| 33 | * | ||
| 34 | * 6. Redistributions of any form whatsoever must retain the following | ||
| 35 | * acknowledgment: | ||
| 36 | * "This product includes software developed by the OpenSSL Project | ||
| 37 | * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" | ||
| 38 | * | ||
| 39 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | ||
| 40 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
| 41 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
| 42 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | ||
| 43 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
| 44 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
| 45 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
| 46 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| 47 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
| 48 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
| 49 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | ||
| 50 | * OF THE POSSIBILITY OF SUCH DAMAGE. | ||
| 51 | * ==================================================================== | ||
| 52 | * | ||
| 53 | * This product includes cryptographic software written by Eric Young | ||
| 54 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
| 55 | * Hudson (tjh@cryptsoft.com). | ||
| 56 | * | ||
| 57 | */ | ||
| 58 | |||
| 59 | #include <openssl/crypto.h> | ||
| 60 | #include "cryptlib.h" | ||
| 61 | #include "engine_int.h" | ||
| 62 | #include <openssl/engine.h> | ||
| 63 | |||
| 64 | /* These pointers each have their own "functional reference" when they | ||
| 65 | * are non-NULL. Similarly, when they are retrieved by a call to | ||
| 66 | * ENGINE_get_default_[RSA|DSA|...] the returned pointer is also a | ||
| 67 | * reference and the caller is responsible for freeing that when they | ||
| 68 | * are finished with it (with a call to ENGINE_finish() *NOT* just | ||
| 69 | * ENGINE_free()!!!!!!). */ | ||
| 70 | static ENGINE *engine_def_rsa = NULL; | ||
| 71 | static ENGINE *engine_def_dsa = NULL; | ||
| 72 | static ENGINE *engine_def_dh = NULL; | ||
| 73 | static ENGINE *engine_def_rand = NULL; | ||
| 74 | static ENGINE *engine_def_bn_mod_exp = NULL; | ||
| 75 | static ENGINE *engine_def_bn_mod_exp_crt = NULL; | ||
| 76 | /* A static "once-only" flag used to control if/when the above were | ||
| 77 | * initialised to suitable start-up defaults. */ | ||
| 78 | static int engine_def_flag = 0; | ||
| 79 | |||
| 80 | /* This is used in certain static utility functions to save code | ||
| 81 | * repetition for per-algorithm functions. */ | ||
| 82 | typedef enum { | ||
| 83 | ENGINE_TYPE_RSA, | ||
| 84 | ENGINE_TYPE_DSA, | ||
| 85 | ENGINE_TYPE_DH, | ||
| 86 | ENGINE_TYPE_RAND, | ||
| 87 | ENGINE_TYPE_BN_MOD_EXP, | ||
| 88 | ENGINE_TYPE_BN_MOD_EXP_CRT | ||
| 89 | } ENGINE_TYPE; | ||
| 90 | |||
| 91 | static void engine_def_check_util(ENGINE **def, ENGINE *val) | ||
| 92 | { | ||
| 93 | *def = val; | ||
| 94 | val->struct_ref++; | ||
| 95 | val->funct_ref++; | ||
| 96 | } | ||
| 97 | |||
| 98 | /* In a slight break with convention - this static function must be | ||
| 99 | * called *outside* any locking of CRYPTO_LOCK_ENGINE. */ | ||
| 100 | static void engine_def_check(void) | ||
| 101 | { | ||
| 102 | ENGINE *e; | ||
| 103 | if(engine_def_flag) | ||
| 104 | return; | ||
| 105 | e = ENGINE_get_first(); | ||
| 106 | if(e == NULL) | ||
| 107 | /* The list is empty ... not much we can do! */ | ||
| 108 | return; | ||
| 109 | /* We have a structural reference, see if getting a functional | ||
| 110 | * reference is possible. This is done to cope with init errors | ||
| 111 | * in the engine - the following locked code does a bunch of | ||
| 112 | * manual "ENGINE_init"s which do *not* allow such an init | ||
| 113 | * error so this is worth doing. */ | ||
| 114 | if(ENGINE_init(e)) | ||
| 115 | { | ||
| 116 | CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); | ||
| 117 | /* Doing another check here prevents an obvious race | ||
| 118 | * condition because the whole function itself cannot | ||
| 119 | * be locked. */ | ||
| 120 | if(engine_def_flag) | ||
| 121 | goto skip_set_defaults; | ||
| 122 | /* OK, we got a functional reference, so we get one each | ||
| 123 | * for the defaults too. */ | ||
| 124 | engine_def_check_util(&engine_def_rsa, e); | ||
| 125 | engine_def_check_util(&engine_def_dsa, e); | ||
| 126 | engine_def_check_util(&engine_def_dh, e); | ||
| 127 | engine_def_check_util(&engine_def_rand, e); | ||
| 128 | engine_def_check_util(&engine_def_bn_mod_exp, e); | ||
| 129 | engine_def_check_util(&engine_def_bn_mod_exp_crt, e); | ||
| 130 | engine_def_flag = 1; | ||
| 131 | skip_set_defaults: | ||
| 132 | CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); | ||
| 133 | /* The "if" needs to be balanced out. */ | ||
| 134 | ENGINE_finish(e); | ||
| 135 | } | ||
| 136 | /* We need to balance out the fact we obtained a structural | ||
| 137 | * reference to begin with from ENGINE_get_first(). */ | ||
| 138 | ENGINE_free(e); | ||
| 139 | } | ||
| 140 | |||
| 141 | /* Initialise a engine type for use (or up its functional reference count | ||
| 142 | * if it's already in use). */ | ||
| 143 | int ENGINE_init(ENGINE *e) | ||
| 144 | { | ||
| 145 | int to_return = 1; | ||
| 146 | |||
| 147 | if(e == NULL) | ||
| 148 | { | ||
| 149 | ENGINEerr(ENGINE_F_ENGINE_INIT,ERR_R_PASSED_NULL_PARAMETER); | ||
| 150 | return 0; | ||
| 151 | } | ||
| 152 | CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); | ||
| 153 | if((e->funct_ref == 0) && e->init) | ||
| 154 | /* This is the first functional reference and the engine | ||
| 155 | * requires initialisation so we do it now. */ | ||
| 156 | to_return = e->init(); | ||
| 157 | if(to_return) | ||
| 158 | { | ||
| 159 | /* OK, we return a functional reference which is also a | ||
| 160 | * structural reference. */ | ||
| 161 | e->struct_ref++; | ||
| 162 | e->funct_ref++; | ||
| 163 | } | ||
| 164 | CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); | ||
| 165 | return to_return; | ||
| 166 | } | ||
| 167 | |||
| 168 | /* Free a functional reference to a engine type */ | ||
| 169 | int ENGINE_finish(ENGINE *e) | ||
| 170 | { | ||
| 171 | int to_return = 1; | ||
| 172 | |||
| 173 | if(e == NULL) | ||
| 174 | { | ||
| 175 | ENGINEerr(ENGINE_F_ENGINE_FINISH,ERR_R_PASSED_NULL_PARAMETER); | ||
| 176 | return 0; | ||
| 177 | } | ||
| 178 | CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); | ||
| 179 | if((e->funct_ref == 1) && e->finish) | ||
| 180 | #if 0 | ||
| 181 | /* This is the last functional reference and the engine | ||
| 182 | * requires cleanup so we do it now. */ | ||
| 183 | to_return = e->finish(); | ||
| 184 | if(to_return) | ||
| 185 | { | ||
| 186 | /* Cleanup the functional reference which is also a | ||
| 187 | * structural reference. */ | ||
| 188 | e->struct_ref--; | ||
| 189 | e->funct_ref--; | ||
| 190 | } | ||
| 191 | CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); | ||
| 192 | #else | ||
| 193 | /* I'm going to deliberately do a convoluted version of this | ||
| 194 | * piece of code because we don't want "finish" functions | ||
| 195 | * being called inside a locked block of code, if at all | ||
| 196 | * possible. I'd rather have this call take an extra couple | ||
| 197 | * of ticks than have throughput serialised on a externally- | ||
| 198 | * provided callback function that may conceivably never come | ||
| 199 | * back. :-( */ | ||
| 200 | { | ||
| 201 | CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); | ||
| 202 | /* CODE ALERT: This *IS* supposed to be "=" and NOT "==" :-) */ | ||
| 203 | if((to_return = e->finish())) | ||
| 204 | { | ||
| 205 | CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); | ||
| 206 | /* Cleanup the functional reference which is also a | ||
| 207 | * structural reference. */ | ||
| 208 | e->struct_ref--; | ||
| 209 | e->funct_ref--; | ||
| 210 | CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); | ||
| 211 | } | ||
| 212 | } | ||
| 213 | else | ||
| 214 | CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); | ||
| 215 | #endif | ||
| 216 | return to_return; | ||
| 217 | } | ||
| 218 | |||
| 219 | EVP_PKEY *ENGINE_load_private_key(ENGINE *e, const char *key_id, | ||
| 220 | const char *passphrase) | ||
| 221 | { | ||
| 222 | EVP_PKEY *pkey; | ||
| 223 | |||
| 224 | if(e == NULL) | ||
| 225 | { | ||
| 226 | ENGINEerr(ENGINE_F_ENGINE_LOAD_PRIVATE_KEY, | ||
| 227 | ERR_R_PASSED_NULL_PARAMETER); | ||
| 228 | return 0; | ||
| 229 | } | ||
| 230 | CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); | ||
| 231 | if(e->funct_ref == 0) | ||
| 232 | { | ||
| 233 | ENGINEerr(ENGINE_F_ENGINE_LOAD_PRIVATE_KEY, | ||
| 234 | ENGINE_R_NOT_INITIALISED); | ||
| 235 | return 0; | ||
| 236 | } | ||
| 237 | if (!e->load_privkey) | ||
| 238 | { | ||
| 239 | ENGINEerr(ENGINE_F_ENGINE_LOAD_PRIVATE_KEY, | ||
| 240 | ENGINE_R_NO_LOAD_FUNCTION); | ||
| 241 | return 0; | ||
| 242 | } | ||
| 243 | CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); | ||
| 244 | pkey = e->load_privkey(key_id, passphrase); | ||
| 245 | if (!pkey) | ||
| 246 | { | ||
| 247 | ENGINEerr(ENGINE_F_ENGINE_LOAD_PRIVATE_KEY, | ||
| 248 | ENGINE_R_FAILED_LOADING_PRIVATE_KEY); | ||
| 249 | return 0; | ||
| 250 | } | ||
| 251 | return pkey; | ||
| 252 | } | ||
| 253 | |||
| 254 | EVP_PKEY *ENGINE_load_public_key(ENGINE *e, const char *key_id, | ||
| 255 | const char *passphrase) | ||
| 256 | { | ||
| 257 | EVP_PKEY *pkey; | ||
| 258 | |||
| 259 | if(e == NULL) | ||
| 260 | { | ||
| 261 | ENGINEerr(ENGINE_F_ENGINE_LOAD_PUBLIC_KEY, | ||
| 262 | ERR_R_PASSED_NULL_PARAMETER); | ||
| 263 | return 0; | ||
| 264 | } | ||
| 265 | CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); | ||
| 266 | if(e->funct_ref == 0) | ||
| 267 | { | ||
| 268 | ENGINEerr(ENGINE_F_ENGINE_LOAD_PUBLIC_KEY, | ||
| 269 | ENGINE_R_NOT_INITIALISED); | ||
| 270 | return 0; | ||
| 271 | } | ||
| 272 | if (!e->load_pubkey) | ||
| 273 | { | ||
| 274 | ENGINEerr(ENGINE_F_ENGINE_LOAD_PUBLIC_KEY, | ||
| 275 | ENGINE_R_NO_LOAD_FUNCTION); | ||
| 276 | return 0; | ||
| 277 | } | ||
| 278 | CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); | ||
| 279 | pkey = e->load_pubkey(key_id, passphrase); | ||
| 280 | if (!pkey) | ||
| 281 | { | ||
| 282 | ENGINEerr(ENGINE_F_ENGINE_LOAD_PUBLIC_KEY, | ||
| 283 | ENGINE_R_FAILED_LOADING_PUBLIC_KEY); | ||
| 284 | return 0; | ||
| 285 | } | ||
| 286 | return pkey; | ||
| 287 | } | ||
| 288 | |||
| 289 | /* Initialise a engine type for use (or up its functional reference count | ||
| 290 | * if it's already in use). */ | ||
| 291 | int ENGINE_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)()) | ||
| 292 | { | ||
| 293 | if(e == NULL) | ||
| 294 | { | ||
| 295 | ENGINEerr(ENGINE_F_ENGINE_CTRL,ERR_R_PASSED_NULL_PARAMETER); | ||
| 296 | return 0; | ||
| 297 | } | ||
| 298 | CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); | ||
| 299 | if(e->struct_ref == 0) | ||
| 300 | { | ||
| 301 | ENGINEerr(ENGINE_F_ENGINE_CTRL,ENGINE_R_NO_REFERENCE); | ||
| 302 | return 0; | ||
| 303 | } | ||
| 304 | if (!e->ctrl) | ||
| 305 | { | ||
| 306 | ENGINEerr(ENGINE_F_ENGINE_CTRL,ENGINE_R_NO_CONTROL_FUNCTION); | ||
| 307 | return 0; | ||
| 308 | } | ||
| 309 | CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); | ||
| 310 | return e->ctrl(cmd, i, p, f); | ||
| 311 | } | ||
| 312 | |||
| 313 | static ENGINE *engine_get_default_type(ENGINE_TYPE t) | ||
| 314 | { | ||
| 315 | ENGINE *ret = NULL; | ||
| 316 | |||
| 317 | /* engine_def_check is lean and mean and won't replace any | ||
| 318 | * prior default engines ... so we must ensure that it is always | ||
| 319 | * the first function to get to touch the default values. */ | ||
| 320 | engine_def_check(); | ||
| 321 | CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); | ||
| 322 | switch(t) | ||
| 323 | { | ||
| 324 | case ENGINE_TYPE_RSA: | ||
| 325 | ret = engine_def_rsa; break; | ||
| 326 | case ENGINE_TYPE_DSA: | ||
| 327 | ret = engine_def_dsa; break; | ||
| 328 | case ENGINE_TYPE_DH: | ||
| 329 | ret = engine_def_dh; break; | ||
| 330 | case ENGINE_TYPE_RAND: | ||
| 331 | ret = engine_def_rand; break; | ||
| 332 | case ENGINE_TYPE_BN_MOD_EXP: | ||
| 333 | ret = engine_def_bn_mod_exp; break; | ||
| 334 | case ENGINE_TYPE_BN_MOD_EXP_CRT: | ||
| 335 | ret = engine_def_bn_mod_exp_crt; break; | ||
| 336 | } | ||
| 337 | /* Unforunately we can't do this work outside the lock with a | ||
| 338 | * call to ENGINE_init() because that would leave a race | ||
| 339 | * condition open. */ | ||
| 340 | if(ret) | ||
| 341 | { | ||
| 342 | ret->struct_ref++; | ||
| 343 | ret->funct_ref++; | ||
| 344 | } | ||
| 345 | CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); | ||
| 346 | return ret; | ||
| 347 | } | ||
| 348 | |||
| 349 | ENGINE *ENGINE_get_default_RSA(void) | ||
| 350 | { | ||
| 351 | return engine_get_default_type(ENGINE_TYPE_RSA); | ||
| 352 | } | ||
| 353 | |||
| 354 | ENGINE *ENGINE_get_default_DSA(void) | ||
| 355 | { | ||
| 356 | return engine_get_default_type(ENGINE_TYPE_DSA); | ||
| 357 | } | ||
| 358 | |||
| 359 | ENGINE *ENGINE_get_default_DH(void) | ||
| 360 | { | ||
| 361 | return engine_get_default_type(ENGINE_TYPE_DH); | ||
| 362 | } | ||
| 363 | |||
| 364 | ENGINE *ENGINE_get_default_RAND(void) | ||
| 365 | { | ||
| 366 | return engine_get_default_type(ENGINE_TYPE_RAND); | ||
| 367 | } | ||
| 368 | |||
| 369 | ENGINE *ENGINE_get_default_BN_mod_exp(void) | ||
| 370 | { | ||
| 371 | return engine_get_default_type(ENGINE_TYPE_BN_MOD_EXP); | ||
| 372 | } | ||
| 373 | |||
| 374 | ENGINE *ENGINE_get_default_BN_mod_exp_crt(void) | ||
| 375 | { | ||
| 376 | return engine_get_default_type(ENGINE_TYPE_BN_MOD_EXP_CRT); | ||
| 377 | } | ||
| 378 | |||
| 379 | static int engine_set_default_type(ENGINE_TYPE t, ENGINE *e) | ||
| 380 | { | ||
| 381 | ENGINE *old = NULL; | ||
| 382 | |||
| 383 | if(e == NULL) | ||
| 384 | { | ||
| 385 | ENGINEerr(ENGINE_F_ENGINE_SET_DEFAULT_TYPE, | ||
| 386 | ERR_R_PASSED_NULL_PARAMETER); | ||
| 387 | return 0; | ||
| 388 | } | ||
| 389 | /* engine_def_check is lean and mean and won't replace any | ||
| 390 | * prior default engines ... so we must ensure that it is always | ||
| 391 | * the first function to get to touch the default values. */ | ||
| 392 | engine_def_check(); | ||
| 393 | /* Attempt to get a functional reference (we need one anyway, but | ||
| 394 | * also, 'e' may be just a structural reference being passed in so | ||
| 395 | * this call may actually be the first). */ | ||
| 396 | if(!ENGINE_init(e)) | ||
| 397 | { | ||
| 398 | ENGINEerr(ENGINE_F_ENGINE_SET_DEFAULT_TYPE, | ||
| 399 | ENGINE_R_INIT_FAILED); | ||
| 400 | return 0; | ||
| 401 | } | ||
| 402 | CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); | ||
| 403 | switch(t) | ||
| 404 | { | ||
| 405 | case ENGINE_TYPE_RSA: | ||
| 406 | old = engine_def_rsa; | ||
| 407 | engine_def_rsa = e; break; | ||
| 408 | case ENGINE_TYPE_DSA: | ||
| 409 | old = engine_def_dsa; | ||
| 410 | engine_def_dsa = e; break; | ||
| 411 | case ENGINE_TYPE_DH: | ||
| 412 | old = engine_def_dh; | ||
| 413 | engine_def_dh = e; break; | ||
| 414 | case ENGINE_TYPE_RAND: | ||
| 415 | old = engine_def_rand; | ||
| 416 | engine_def_rand = e; break; | ||
| 417 | case ENGINE_TYPE_BN_MOD_EXP: | ||
| 418 | old = engine_def_bn_mod_exp; | ||
| 419 | engine_def_bn_mod_exp = e; break; | ||
| 420 | case ENGINE_TYPE_BN_MOD_EXP_CRT: | ||
| 421 | old = engine_def_bn_mod_exp_crt; | ||
| 422 | engine_def_bn_mod_exp_crt = e; break; | ||
| 423 | } | ||
| 424 | CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); | ||
| 425 | /* If we've replaced a previous value, then we need to remove the | ||
| 426 | * functional reference we had. */ | ||
| 427 | if(old && !ENGINE_finish(old)) | ||
| 428 | { | ||
| 429 | ENGINEerr(ENGINE_F_ENGINE_SET_DEFAULT_TYPE, | ||
| 430 | ENGINE_R_FINISH_FAILED); | ||
| 431 | return 0; | ||
| 432 | } | ||
| 433 | return 1; | ||
| 434 | } | ||
| 435 | |||
| 436 | int ENGINE_set_default_RSA(ENGINE *e) | ||
| 437 | { | ||
| 438 | return engine_set_default_type(ENGINE_TYPE_RSA, e); | ||
| 439 | } | ||
| 440 | |||
| 441 | int ENGINE_set_default_DSA(ENGINE *e) | ||
| 442 | { | ||
| 443 | return engine_set_default_type(ENGINE_TYPE_DSA, e); | ||
| 444 | } | ||
| 445 | |||
| 446 | int ENGINE_set_default_DH(ENGINE *e) | ||
| 447 | { | ||
| 448 | return engine_set_default_type(ENGINE_TYPE_DH, e); | ||
| 449 | } | ||
| 450 | |||
| 451 | int ENGINE_set_default_RAND(ENGINE *e) | ||
| 452 | { | ||
| 453 | return engine_set_default_type(ENGINE_TYPE_RAND, e); | ||
| 454 | } | ||
| 455 | |||
| 456 | int ENGINE_set_default_BN_mod_exp(ENGINE *e) | ||
| 457 | { | ||
| 458 | return engine_set_default_type(ENGINE_TYPE_BN_MOD_EXP, e); | ||
| 459 | } | ||
| 460 | |||
| 461 | int ENGINE_set_default_BN_mod_exp_crt(ENGINE *e) | ||
| 462 | { | ||
| 463 | return engine_set_default_type(ENGINE_TYPE_BN_MOD_EXP_CRT, e); | ||
| 464 | } | ||
| 465 | |||
| 466 | int ENGINE_set_default(ENGINE *e, unsigned int flags) | ||
| 467 | { | ||
| 468 | if((flags & ENGINE_METHOD_RSA) && e->rsa_meth && | ||
| 469 | !ENGINE_set_default_RSA(e)) | ||
| 470 | return 0; | ||
| 471 | if((flags & ENGINE_METHOD_DSA) && e->dsa_meth && | ||
| 472 | !ENGINE_set_default_DSA(e)) | ||
| 473 | return 0; | ||
| 474 | if((flags & ENGINE_METHOD_DH) && e->dh_meth && | ||
| 475 | !ENGINE_set_default_DH(e)) | ||
| 476 | return 0; | ||
| 477 | if((flags & ENGINE_METHOD_RAND) && e->rand_meth && | ||
| 478 | !ENGINE_set_default_RAND(e)) | ||
| 479 | return 0; | ||
| 480 | if((flags & ENGINE_METHOD_BN_MOD_EXP) && e->bn_mod_exp && | ||
| 481 | !ENGINE_set_default_BN_mod_exp(e)) | ||
| 482 | return 0; | ||
| 483 | if((flags & ENGINE_METHOD_BN_MOD_EXP_CRT) && e->bn_mod_exp_crt && | ||
| 484 | !ENGINE_set_default_BN_mod_exp_crt(e)) | ||
| 485 | return 0; | ||
| 486 | return 1; | ||
| 487 | } | ||
| 488 | |||
diff --git a/src/lib/libcrypto/engine/engine_list.c b/src/lib/libcrypto/engine/engine_list.c new file mode 100644 index 0000000000..d764c60661 --- /dev/null +++ b/src/lib/libcrypto/engine/engine_list.c | |||
| @@ -0,0 +1,675 @@ | |||
| 1 | /* crypto/engine/engine_list.c */ | ||
| 2 | /* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL | ||
| 3 | * project 2000. | ||
| 4 | */ | ||
| 5 | /* ==================================================================== | ||
| 6 | * Copyright (c) 1999 The OpenSSL Project. All rights reserved. | ||
| 7 | * | ||
| 8 | * Redistribution and use in source and binary forms, with or without | ||
| 9 | * modification, are permitted provided that the following conditions | ||
| 10 | * are met: | ||
| 11 | * | ||
| 12 | * 1. Redistributions of source code must retain the above copyright | ||
| 13 | * notice, this list of conditions and the following disclaimer. | ||
| 14 | * | ||
| 15 | * 2. Redistributions in binary form must reproduce the above copyright | ||
| 16 | * notice, this list of conditions and the following disclaimer in | ||
| 17 | * the documentation and/or other materials provided with the | ||
| 18 | * distribution. | ||
| 19 | * | ||
| 20 | * 3. All advertising materials mentioning features or use of this | ||
| 21 | * software must display the following acknowledgment: | ||
| 22 | * "This product includes software developed by the OpenSSL Project | ||
| 23 | * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" | ||
| 24 | * | ||
| 25 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | ||
| 26 | * endorse or promote products derived from this software without | ||
| 27 | * prior written permission. For written permission, please contact | ||
| 28 | * licensing@OpenSSL.org. | ||
| 29 | * | ||
| 30 | * 5. Products derived from this software may not be called "OpenSSL" | ||
| 31 | * nor may "OpenSSL" appear in their names without prior written | ||
| 32 | * permission of the OpenSSL Project. | ||
| 33 | * | ||
| 34 | * 6. Redistributions of any form whatsoever must retain the following | ||
| 35 | * acknowledgment: | ||
| 36 | * "This product includes software developed by the OpenSSL Project | ||
| 37 | * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" | ||
| 38 | * | ||
| 39 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | ||
| 40 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
| 41 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
| 42 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | ||
| 43 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
| 44 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
| 45 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
| 46 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| 47 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
| 48 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
| 49 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | ||
| 50 | * OF THE POSSIBILITY OF SUCH DAMAGE. | ||
| 51 | * ==================================================================== | ||
| 52 | * | ||
| 53 | * This product includes cryptographic software written by Eric Young | ||
| 54 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
| 55 | * Hudson (tjh@cryptsoft.com). | ||
| 56 | * | ||
| 57 | */ | ||
| 58 | |||
| 59 | #include <openssl/crypto.h> | ||
| 60 | #include "cryptlib.h" | ||
| 61 | #include "engine_int.h" | ||
| 62 | #include <openssl/engine.h> | ||
| 63 | |||
| 64 | /* The linked-list of pointers to engine types. engine_list_head | ||
| 65 | * incorporates an implicit structural reference but engine_list_tail | ||
| 66 | * does not - the latter is a computational niceity and only points | ||
| 67 | * to something that is already pointed to by its predecessor in the | ||
| 68 | * list (or engine_list_head itself). In the same way, the use of the | ||
| 69 | * "prev" pointer in each ENGINE is to save excessive list iteration, | ||
| 70 | * it doesn't correspond to an extra structural reference. Hence, | ||
| 71 | * engine_list_head, and each non-null "next" pointer account for | ||
| 72 | * the list itself assuming exactly 1 structural reference on each | ||
| 73 | * list member. */ | ||
| 74 | static ENGINE *engine_list_head = NULL; | ||
| 75 | static ENGINE *engine_list_tail = NULL; | ||
| 76 | /* A boolean switch, used to ensure we only initialise once. This | ||
| 77 | * is needed because the engine list may genuinely become empty during | ||
| 78 | * use (so we can't use engine_list_head as an indicator for example. */ | ||
| 79 | static int engine_list_flag = 0; | ||
| 80 | |||
| 81 | /* These static functions starting with a lower case "engine_" always | ||
| 82 | * take place when CRYPTO_LOCK_ENGINE has been locked up. */ | ||
| 83 | static int engine_list_add(ENGINE *e) | ||
| 84 | { | ||
| 85 | int conflict = 0; | ||
| 86 | ENGINE *iterator = NULL; | ||
| 87 | |||
| 88 | if(e == NULL) | ||
| 89 | { | ||
| 90 | ENGINEerr(ENGINE_F_ENGINE_LIST_ADD, | ||
| 91 | ERR_R_PASSED_NULL_PARAMETER); | ||
| 92 | return 0; | ||
| 93 | } | ||
| 94 | iterator = engine_list_head; | ||
| 95 | while(iterator && !conflict) | ||
| 96 | { | ||
| 97 | conflict = (strcmp(iterator->id, e->id) == 0); | ||
| 98 | iterator = iterator->next; | ||
| 99 | } | ||
| 100 | if(conflict) | ||
| 101 | { | ||
| 102 | ENGINEerr(ENGINE_F_ENGINE_LIST_ADD, | ||
| 103 | ENGINE_R_CONFLICTING_ENGINE_ID); | ||
| 104 | return 0; | ||
| 105 | } | ||
| 106 | if(engine_list_head == NULL) | ||
| 107 | { | ||
| 108 | /* We are adding to an empty list. */ | ||
| 109 | if(engine_list_tail) | ||
| 110 | { | ||
| 111 | ENGINEerr(ENGINE_F_ENGINE_LIST_ADD, | ||
| 112 | ENGINE_R_INTERNAL_LIST_ERROR); | ||
| 113 | return 0; | ||
| 114 | } | ||
| 115 | engine_list_head = e; | ||
| 116 | e->prev = NULL; | ||
| 117 | } | ||
| 118 | else | ||
| 119 | { | ||
| 120 | /* We are adding to the tail of an existing list. */ | ||
| 121 | if((engine_list_tail == NULL) || | ||
| 122 | (engine_list_tail->next != NULL)) | ||
| 123 | { | ||
| 124 | ENGINEerr(ENGINE_F_ENGINE_LIST_ADD, | ||
| 125 | ENGINE_R_INTERNAL_LIST_ERROR); | ||
| 126 | return 0; | ||
| 127 | } | ||
| 128 | engine_list_tail->next = e; | ||
| 129 | e->prev = engine_list_tail; | ||
| 130 | } | ||
| 131 | /* Having the engine in the list assumes a structural | ||
| 132 | * reference. */ | ||
| 133 | e->struct_ref++; | ||
| 134 | /* However it came to be, e is the last item in the list. */ | ||
| 135 | engine_list_tail = e; | ||
| 136 | e->next = NULL; | ||
| 137 | return 1; | ||
| 138 | } | ||
| 139 | |||
| 140 | static int engine_list_remove(ENGINE *e) | ||
| 141 | { | ||
| 142 | ENGINE *iterator; | ||
| 143 | |||
| 144 | if(e == NULL) | ||
| 145 | { | ||
| 146 | ENGINEerr(ENGINE_F_ENGINE_LIST_REMOVE, | ||
| 147 | ERR_R_PASSED_NULL_PARAMETER); | ||
| 148 | return 0; | ||
| 149 | } | ||
| 150 | /* We need to check that e is in our linked list! */ | ||
| 151 | iterator = engine_list_head; | ||
| 152 | while(iterator && (iterator != e)) | ||
| 153 | iterator = iterator->next; | ||
| 154 | if(iterator == NULL) | ||
| 155 | { | ||
| 156 | ENGINEerr(ENGINE_F_ENGINE_LIST_REMOVE, | ||
| 157 | ENGINE_R_ENGINE_IS_NOT_IN_LIST); | ||
| 158 | return 0; | ||
| 159 | } | ||
| 160 | /* un-link e from the chain. */ | ||
| 161 | if(e->next) | ||
| 162 | e->next->prev = e->prev; | ||
| 163 | if(e->prev) | ||
| 164 | e->prev->next = e->next; | ||
| 165 | /* Correct our head/tail if necessary. */ | ||
| 166 | if(engine_list_head == e) | ||
| 167 | engine_list_head = e->next; | ||
| 168 | if(engine_list_tail == e) | ||
| 169 | engine_list_tail = e->prev; | ||
| 170 | /* remove our structural reference. */ | ||
| 171 | e->struct_ref--; | ||
| 172 | return 1; | ||
| 173 | } | ||
| 174 | |||
| 175 | /* This check always takes place with CRYPTO_LOCK_ENGINE locked up | ||
| 176 | * so we're synchronised, but we can't call anything that tries to | ||
| 177 | * lock it again! :-) NB: For convenience (and code-clarity) we | ||
| 178 | * don't output errors for failures of the engine_list_add function | ||
| 179 | * as it will generate errors itself. */ | ||
| 180 | static int engine_internal_check(void) | ||
| 181 | { | ||
| 182 | if(engine_list_flag) | ||
| 183 | return 1; | ||
| 184 | /* This is our first time up, we need to populate the list | ||
| 185 | * with our statically compiled-in engines. */ | ||
| 186 | if(!engine_list_add(ENGINE_openssl())) | ||
| 187 | return 0; | ||
| 188 | #ifndef NO_HW | ||
| 189 | #ifndef NO_HW_CSWIFT | ||
| 190 | if(!engine_list_add(ENGINE_cswift())) | ||
| 191 | return 0; | ||
| 192 | #endif /* !NO_HW_CSWIFT */ | ||
| 193 | #ifndef NO_HW_NCIPHER | ||
| 194 | if(!engine_list_add(ENGINE_ncipher())) | ||
| 195 | return 0; | ||
| 196 | #endif /* !NO_HW_NCIPHER */ | ||
| 197 | #ifndef NO_HW_ATALLA | ||
| 198 | if(!engine_list_add(ENGINE_atalla())) | ||
| 199 | return 0; | ||
| 200 | #endif /* !NO_HW_ATALLA */ | ||
| 201 | #endif /* !NO_HW */ | ||
| 202 | engine_list_flag = 1; | ||
| 203 | return 1; | ||
| 204 | } | ||
| 205 | |||
| 206 | /* Get the first/last "ENGINE" type available. */ | ||
| 207 | ENGINE *ENGINE_get_first(void) | ||
| 208 | { | ||
| 209 | ENGINE *ret = NULL; | ||
| 210 | |||
| 211 | CRYPTO_r_lock(CRYPTO_LOCK_ENGINE); | ||
| 212 | if(engine_internal_check()) | ||
| 213 | { | ||
| 214 | ret = engine_list_head; | ||
| 215 | if(ret) | ||
| 216 | ret->struct_ref++; | ||
| 217 | } | ||
| 218 | CRYPTO_r_unlock(CRYPTO_LOCK_ENGINE); | ||
| 219 | return ret; | ||
| 220 | } | ||
| 221 | ENGINE *ENGINE_get_last(void) | ||
| 222 | { | ||
| 223 | ENGINE *ret = NULL; | ||
| 224 | |||
| 225 | CRYPTO_r_lock(CRYPTO_LOCK_ENGINE); | ||
| 226 | if(engine_internal_check()) | ||
| 227 | { | ||
| 228 | ret = engine_list_tail; | ||
| 229 | if(ret) | ||
| 230 | ret->struct_ref++; | ||
| 231 | } | ||
| 232 | CRYPTO_r_unlock(CRYPTO_LOCK_ENGINE); | ||
| 233 | return ret; | ||
| 234 | } | ||
| 235 | |||
| 236 | /* Iterate to the next/previous "ENGINE" type (NULL = end of the list). */ | ||
| 237 | ENGINE *ENGINE_get_next(ENGINE *e) | ||
| 238 | { | ||
| 239 | ENGINE *ret = NULL; | ||
| 240 | if(e == NULL) | ||
| 241 | { | ||
| 242 | ENGINEerr(ENGINE_F_ENGINE_GET_NEXT, | ||
| 243 | ERR_R_PASSED_NULL_PARAMETER); | ||
| 244 | return 0; | ||
| 245 | } | ||
| 246 | CRYPTO_r_lock(CRYPTO_LOCK_ENGINE); | ||
| 247 | ret = e->next; | ||
| 248 | e->struct_ref--; | ||
| 249 | if(ret) | ||
| 250 | ret->struct_ref++; | ||
| 251 | CRYPTO_r_unlock(CRYPTO_LOCK_ENGINE); | ||
| 252 | return ret; | ||
| 253 | } | ||
| 254 | ENGINE *ENGINE_get_prev(ENGINE *e) | ||
| 255 | { | ||
| 256 | ENGINE *ret = NULL; | ||
| 257 | if(e == NULL) | ||
| 258 | { | ||
| 259 | ENGINEerr(ENGINE_F_ENGINE_GET_PREV, | ||
| 260 | ERR_R_PASSED_NULL_PARAMETER); | ||
| 261 | return 0; | ||
| 262 | } | ||
| 263 | CRYPTO_r_lock(CRYPTO_LOCK_ENGINE); | ||
| 264 | ret = e->prev; | ||
| 265 | e->struct_ref--; | ||
| 266 | if(ret) | ||
| 267 | ret->struct_ref++; | ||
| 268 | CRYPTO_r_unlock(CRYPTO_LOCK_ENGINE); | ||
| 269 | return ret; | ||
| 270 | } | ||
| 271 | |||
| 272 | /* Add another "ENGINE" type into the list. */ | ||
| 273 | int ENGINE_add(ENGINE *e) | ||
| 274 | { | ||
| 275 | int to_return = 1; | ||
| 276 | if(e == NULL) | ||
| 277 | { | ||
| 278 | ENGINEerr(ENGINE_F_ENGINE_ADD, | ||
| 279 | ERR_R_PASSED_NULL_PARAMETER); | ||
| 280 | return 0; | ||
| 281 | } | ||
| 282 | if((e->id == NULL) || (e->name == NULL)) | ||
| 283 | { | ||
| 284 | ENGINEerr(ENGINE_F_ENGINE_ADD, | ||
| 285 | ENGINE_R_ID_OR_NAME_MISSING); | ||
| 286 | } | ||
| 287 | CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); | ||
| 288 | if(!engine_internal_check() || !engine_list_add(e)) | ||
| 289 | { | ||
| 290 | ENGINEerr(ENGINE_F_ENGINE_ADD, | ||
| 291 | ENGINE_R_INTERNAL_LIST_ERROR); | ||
| 292 | to_return = 0; | ||
| 293 | } | ||
| 294 | CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); | ||
| 295 | return to_return; | ||
| 296 | } | ||
| 297 | |||
| 298 | /* Remove an existing "ENGINE" type from the array. */ | ||
| 299 | int ENGINE_remove(ENGINE *e) | ||
| 300 | { | ||
| 301 | int to_return = 1; | ||
| 302 | if(e == NULL) | ||
| 303 | { | ||
| 304 | ENGINEerr(ENGINE_F_ENGINE_REMOVE, | ||
| 305 | ERR_R_PASSED_NULL_PARAMETER); | ||
| 306 | return 0; | ||
| 307 | } | ||
| 308 | CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); | ||
| 309 | if(!engine_internal_check() || !engine_list_remove(e)) | ||
| 310 | { | ||
| 311 | ENGINEerr(ENGINE_F_ENGINE_REMOVE, | ||
| 312 | ENGINE_R_INTERNAL_LIST_ERROR); | ||
| 313 | to_return = 0; | ||
| 314 | } | ||
| 315 | CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); | ||
| 316 | return to_return; | ||
| 317 | } | ||
| 318 | |||
| 319 | ENGINE *ENGINE_by_id(const char *id) | ||
| 320 | { | ||
| 321 | ENGINE *iterator = NULL; | ||
| 322 | if(id == NULL) | ||
| 323 | { | ||
| 324 | ENGINEerr(ENGINE_F_ENGINE_BY_ID, | ||
| 325 | ERR_R_PASSED_NULL_PARAMETER); | ||
| 326 | return NULL; | ||
| 327 | } | ||
| 328 | CRYPTO_r_lock(CRYPTO_LOCK_ENGINE); | ||
| 329 | if(!engine_internal_check()) | ||
| 330 | ENGINEerr(ENGINE_F_ENGINE_BY_ID, | ||
| 331 | ENGINE_R_INTERNAL_LIST_ERROR); | ||
| 332 | else | ||
| 333 | { | ||
| 334 | iterator = engine_list_head; | ||
| 335 | while(iterator && (strcmp(id, iterator->id) != 0)) | ||
| 336 | iterator = iterator->next; | ||
| 337 | if(iterator) | ||
| 338 | /* We need to return a structural reference */ | ||
| 339 | iterator->struct_ref++; | ||
| 340 | } | ||
| 341 | CRYPTO_r_unlock(CRYPTO_LOCK_ENGINE); | ||
| 342 | if(iterator == NULL) | ||
| 343 | ENGINEerr(ENGINE_F_ENGINE_BY_ID, | ||
| 344 | ENGINE_R_NO_SUCH_ENGINE); | ||
| 345 | return iterator; | ||
| 346 | } | ||
| 347 | |||
| 348 | /* As per the comments in engine.h, it is generally better all round | ||
| 349 | * if the ENGINE structure is allocated within this framework. */ | ||
| 350 | #if 0 | ||
| 351 | int ENGINE_get_struct_size(void) | ||
| 352 | { | ||
| 353 | return sizeof(ENGINE); | ||
| 354 | } | ||
| 355 | |||
| 356 | ENGINE *ENGINE_new(ENGINE *e) | ||
| 357 | { | ||
| 358 | ENGINE *ret; | ||
| 359 | |||
| 360 | if(e == NULL) | ||
| 361 | { | ||
| 362 | ret = (ENGINE *)(OPENSSL_malloc(sizeof(ENGINE)); | ||
| 363 | if(ret == NULL) | ||
| 364 | { | ||
| 365 | ENGINEerr(ENGINE_F_ENGINE_NEW, | ||
| 366 | ERR_R_MALLOC_FAILURE); | ||
| 367 | return NULL; | ||
| 368 | } | ||
| 369 | } | ||
| 370 | else | ||
| 371 | ret = e; | ||
| 372 | memset(ret, 0, sizeof(ENGINE)); | ||
| 373 | if(e) | ||
| 374 | ret->flags = ENGINE_FLAGS_MALLOCED; | ||
| 375 | ret->struct_ref = 1; | ||
| 376 | return ret; | ||
| 377 | } | ||
| 378 | #else | ||
| 379 | ENGINE *ENGINE_new(void) | ||
| 380 | { | ||
| 381 | ENGINE *ret; | ||
| 382 | |||
| 383 | ret = (ENGINE *)OPENSSL_malloc(sizeof(ENGINE)); | ||
| 384 | if(ret == NULL) | ||
| 385 | { | ||
| 386 | ENGINEerr(ENGINE_F_ENGINE_NEW, ERR_R_MALLOC_FAILURE); | ||
| 387 | return NULL; | ||
| 388 | } | ||
| 389 | memset(ret, 0, sizeof(ENGINE)); | ||
| 390 | ret->flags = ENGINE_FLAGS_MALLOCED; | ||
| 391 | ret->struct_ref = 1; | ||
| 392 | return ret; | ||
| 393 | } | ||
| 394 | #endif | ||
| 395 | |||
| 396 | int ENGINE_free(ENGINE *e) | ||
| 397 | { | ||
| 398 | int i; | ||
| 399 | |||
| 400 | if(e == NULL) | ||
| 401 | { | ||
| 402 | ENGINEerr(ENGINE_F_ENGINE_FREE, | ||
| 403 | ERR_R_PASSED_NULL_PARAMETER); | ||
| 404 | return 0; | ||
| 405 | } | ||
| 406 | i = CRYPTO_add(&e->struct_ref,-1,CRYPTO_LOCK_ENGINE); | ||
| 407 | #ifdef REF_PRINT | ||
| 408 | REF_PRINT("ENGINE",e); | ||
| 409 | #endif | ||
| 410 | if (i > 0) return 1; | ||
| 411 | #ifdef REF_CHECK | ||
| 412 | if (i < 0) | ||
| 413 | { | ||
| 414 | fprintf(stderr,"ENGINE_free, bad reference count\n"); | ||
| 415 | abort(); | ||
| 416 | } | ||
| 417 | #endif | ||
| 418 | if(e->flags & ENGINE_FLAGS_MALLOCED) | ||
| 419 | OPENSSL_free(e); | ||
| 420 | return 1; | ||
| 421 | } | ||
| 422 | |||
| 423 | int ENGINE_set_id(ENGINE *e, const char *id) | ||
| 424 | { | ||
| 425 | if((e == NULL) || (id == NULL)) | ||
| 426 | { | ||
| 427 | ENGINEerr(ENGINE_F_ENGINE_SET_ID, | ||
| 428 | ERR_R_PASSED_NULL_PARAMETER); | ||
| 429 | return 0; | ||
| 430 | } | ||
| 431 | e->id = id; | ||
| 432 | return 1; | ||
| 433 | } | ||
| 434 | |||
| 435 | int ENGINE_set_name(ENGINE *e, const char *name) | ||
| 436 | { | ||
| 437 | if((e == NULL) || (name == NULL)) | ||
| 438 | { | ||
| 439 | ENGINEerr(ENGINE_F_ENGINE_SET_NAME, | ||
| 440 | ERR_R_PASSED_NULL_PARAMETER); | ||
| 441 | return 0; | ||
| 442 | } | ||
| 443 | e->name = name; | ||
| 444 | return 1; | ||
| 445 | } | ||
| 446 | |||
| 447 | int ENGINE_set_RSA(ENGINE *e, RSA_METHOD *rsa_meth) | ||
| 448 | { | ||
| 449 | if((e == NULL) || (rsa_meth == NULL)) | ||
| 450 | { | ||
| 451 | ENGINEerr(ENGINE_F_ENGINE_SET_RSA, | ||
| 452 | ERR_R_PASSED_NULL_PARAMETER); | ||
| 453 | return 0; | ||
| 454 | } | ||
| 455 | e->rsa_meth = rsa_meth; | ||
| 456 | return 1; | ||
| 457 | } | ||
| 458 | |||
| 459 | int ENGINE_set_DSA(ENGINE *e, DSA_METHOD *dsa_meth) | ||
| 460 | { | ||
| 461 | if((e == NULL) || (dsa_meth == NULL)) | ||
| 462 | { | ||
| 463 | ENGINEerr(ENGINE_F_ENGINE_SET_DSA, | ||
| 464 | ERR_R_PASSED_NULL_PARAMETER); | ||
| 465 | return 0; | ||
| 466 | } | ||
| 467 | e->dsa_meth = dsa_meth; | ||
| 468 | return 1; | ||
| 469 | } | ||
| 470 | |||
| 471 | int ENGINE_set_DH(ENGINE *e, DH_METHOD *dh_meth) | ||
| 472 | { | ||
| 473 | if((e == NULL) || (dh_meth == NULL)) | ||
| 474 | { | ||
| 475 | ENGINEerr(ENGINE_F_ENGINE_SET_DH, | ||
| 476 | ERR_R_PASSED_NULL_PARAMETER); | ||
| 477 | return 0; | ||
| 478 | } | ||
| 479 | e->dh_meth = dh_meth; | ||
| 480 | return 1; | ||
| 481 | } | ||
| 482 | |||
| 483 | int ENGINE_set_RAND(ENGINE *e, RAND_METHOD *rand_meth) | ||
| 484 | { | ||
| 485 | if((e == NULL) || (rand_meth == NULL)) | ||
| 486 | { | ||
| 487 | ENGINEerr(ENGINE_F_ENGINE_SET_RAND, | ||
| 488 | ERR_R_PASSED_NULL_PARAMETER); | ||
| 489 | return 0; | ||
| 490 | } | ||
| 491 | e->rand_meth = rand_meth; | ||
| 492 | return 1; | ||
| 493 | } | ||
| 494 | |||
| 495 | int ENGINE_set_BN_mod_exp(ENGINE *e, BN_MOD_EXP bn_mod_exp) | ||
| 496 | { | ||
| 497 | if((e == NULL) || (bn_mod_exp == NULL)) | ||
| 498 | { | ||
| 499 | ENGINEerr(ENGINE_F_ENGINE_SET_BN_MOD_EXP, | ||
| 500 | ERR_R_PASSED_NULL_PARAMETER); | ||
| 501 | return 0; | ||
| 502 | } | ||
| 503 | e->bn_mod_exp = bn_mod_exp; | ||
| 504 | return 1; | ||
| 505 | } | ||
| 506 | |||
| 507 | int ENGINE_set_BN_mod_exp_crt(ENGINE *e, BN_MOD_EXP_CRT bn_mod_exp_crt) | ||
| 508 | { | ||
| 509 | if((e == NULL) || (bn_mod_exp_crt == NULL)) | ||
| 510 | { | ||
| 511 | ENGINEerr(ENGINE_F_ENGINE_SET_BN_MOD_EXP_CRT, | ||
| 512 | ERR_R_PASSED_NULL_PARAMETER); | ||
| 513 | return 0; | ||
| 514 | } | ||
| 515 | e->bn_mod_exp_crt = bn_mod_exp_crt; | ||
| 516 | return 1; | ||
| 517 | } | ||
| 518 | |||
| 519 | int ENGINE_set_init_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR init_f) | ||
| 520 | { | ||
| 521 | if((e == NULL) || (init_f == NULL)) | ||
| 522 | { | ||
| 523 | ENGINEerr(ENGINE_F_ENGINE_SET_INIT_FUNCTION, | ||
| 524 | ERR_R_PASSED_NULL_PARAMETER); | ||
| 525 | return 0; | ||
| 526 | } | ||
| 527 | e->init = init_f; | ||
| 528 | return 1; | ||
| 529 | } | ||
| 530 | |||
| 531 | int ENGINE_set_finish_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR finish_f) | ||
| 532 | { | ||
| 533 | if((e == NULL) || (finish_f == NULL)) | ||
| 534 | { | ||
| 535 | ENGINEerr(ENGINE_F_ENGINE_SET_FINISH_FUNCTION, | ||
| 536 | ERR_R_PASSED_NULL_PARAMETER); | ||
| 537 | return 0; | ||
| 538 | } | ||
| 539 | e->finish = finish_f; | ||
| 540 | return 1; | ||
| 541 | } | ||
| 542 | |||
| 543 | int ENGINE_set_ctrl_function(ENGINE *e, ENGINE_CTRL_FUNC_PTR ctrl_f) | ||
| 544 | { | ||
| 545 | if((e == NULL) || (ctrl_f == NULL)) | ||
| 546 | { | ||
| 547 | ENGINEerr(ENGINE_F_ENGINE_SET_CTRL_FUNCTION, | ||
| 548 | ERR_R_PASSED_NULL_PARAMETER); | ||
| 549 | return 0; | ||
| 550 | } | ||
| 551 | e->ctrl = ctrl_f; | ||
| 552 | return 1; | ||
| 553 | } | ||
| 554 | |||
| 555 | const char *ENGINE_get_id(ENGINE *e) | ||
| 556 | { | ||
| 557 | if(e == NULL) | ||
| 558 | { | ||
| 559 | ENGINEerr(ENGINE_F_ENGINE_GET_ID, | ||
| 560 | ERR_R_PASSED_NULL_PARAMETER); | ||
| 561 | return 0; | ||
| 562 | } | ||
| 563 | return e->id; | ||
| 564 | } | ||
| 565 | |||
| 566 | const char *ENGINE_get_name(ENGINE *e) | ||
| 567 | { | ||
| 568 | if(e == NULL) | ||
| 569 | { | ||
| 570 | ENGINEerr(ENGINE_F_ENGINE_GET_NAME, | ||
| 571 | ERR_R_PASSED_NULL_PARAMETER); | ||
| 572 | return 0; | ||
| 573 | } | ||
| 574 | return e->name; | ||
| 575 | } | ||
| 576 | |||
| 577 | RSA_METHOD *ENGINE_get_RSA(ENGINE *e) | ||
| 578 | { | ||
| 579 | if(e == NULL) | ||
| 580 | { | ||
| 581 | ENGINEerr(ENGINE_F_ENGINE_GET_RSA, | ||
| 582 | ERR_R_PASSED_NULL_PARAMETER); | ||
| 583 | return NULL; | ||
| 584 | } | ||
| 585 | return e->rsa_meth; | ||
| 586 | } | ||
| 587 | |||
| 588 | DSA_METHOD *ENGINE_get_DSA(ENGINE *e) | ||
| 589 | { | ||
| 590 | if(e == NULL) | ||
| 591 | { | ||
| 592 | ENGINEerr(ENGINE_F_ENGINE_GET_DSA, | ||
| 593 | ERR_R_PASSED_NULL_PARAMETER); | ||
| 594 | return NULL; | ||
| 595 | } | ||
| 596 | return e->dsa_meth; | ||
| 597 | } | ||
| 598 | |||
| 599 | DH_METHOD *ENGINE_get_DH(ENGINE *e) | ||
| 600 | { | ||
| 601 | if(e == NULL) | ||
| 602 | { | ||
| 603 | ENGINEerr(ENGINE_F_ENGINE_GET_DH, | ||
| 604 | ERR_R_PASSED_NULL_PARAMETER); | ||
| 605 | return NULL; | ||
| 606 | } | ||
| 607 | return e->dh_meth; | ||
| 608 | } | ||
| 609 | |||
| 610 | RAND_METHOD *ENGINE_get_RAND(ENGINE *e) | ||
| 611 | { | ||
| 612 | if(e == NULL) | ||
| 613 | { | ||
| 614 | ENGINEerr(ENGINE_F_ENGINE_GET_RAND, | ||
| 615 | ERR_R_PASSED_NULL_PARAMETER); | ||
| 616 | return NULL; | ||
| 617 | } | ||
| 618 | return e->rand_meth; | ||
| 619 | } | ||
| 620 | |||
| 621 | BN_MOD_EXP ENGINE_get_BN_mod_exp(ENGINE *e) | ||
| 622 | { | ||
| 623 | if(e == NULL) | ||
| 624 | { | ||
| 625 | ENGINEerr(ENGINE_F_ENGINE_GET_BN_MOD_EXP, | ||
| 626 | ERR_R_PASSED_NULL_PARAMETER); | ||
| 627 | return NULL; | ||
| 628 | } | ||
| 629 | return e->bn_mod_exp; | ||
| 630 | } | ||
| 631 | |||
| 632 | BN_MOD_EXP_CRT ENGINE_get_BN_mod_exp_crt(ENGINE *e) | ||
| 633 | { | ||
| 634 | if(e == NULL) | ||
| 635 | { | ||
| 636 | ENGINEerr(ENGINE_F_ENGINE_GET_BN_MOD_EXP_CRT, | ||
| 637 | ERR_R_PASSED_NULL_PARAMETER); | ||
| 638 | return NULL; | ||
| 639 | } | ||
| 640 | return e->bn_mod_exp_crt; | ||
| 641 | } | ||
| 642 | |||
| 643 | ENGINE_GEN_INT_FUNC_PTR ENGINE_get_init_function(ENGINE *e) | ||
| 644 | { | ||
| 645 | if(e == NULL) | ||
| 646 | { | ||
| 647 | ENGINEerr(ENGINE_F_ENGINE_GET_INIT_FUNCTION, | ||
| 648 | ERR_R_PASSED_NULL_PARAMETER); | ||
| 649 | return NULL; | ||
| 650 | } | ||
| 651 | return e->init; | ||
| 652 | } | ||
| 653 | |||
| 654 | ENGINE_GEN_INT_FUNC_PTR ENGINE_get_finish_function(ENGINE *e) | ||
| 655 | { | ||
| 656 | if(e == NULL) | ||
| 657 | { | ||
| 658 | ENGINEerr(ENGINE_F_ENGINE_GET_FINISH_FUNCTION, | ||
| 659 | ERR_R_PASSED_NULL_PARAMETER); | ||
| 660 | return NULL; | ||
| 661 | } | ||
| 662 | return e->finish; | ||
| 663 | } | ||
| 664 | |||
| 665 | ENGINE_CTRL_FUNC_PTR ENGINE_get_ctrl_function(ENGINE *e) | ||
| 666 | { | ||
| 667 | if(e == NULL) | ||
| 668 | { | ||
| 669 | ENGINEerr(ENGINE_F_ENGINE_GET_CTRL_FUNCTION, | ||
| 670 | ERR_R_PASSED_NULL_PARAMETER); | ||
| 671 | return NULL; | ||
| 672 | } | ||
| 673 | return e->ctrl; | ||
| 674 | } | ||
| 675 | |||
diff --git a/src/lib/libcrypto/engine/engine_openssl.c b/src/lib/libcrypto/engine/engine_openssl.c new file mode 100644 index 0000000000..9636f51168 --- /dev/null +++ b/src/lib/libcrypto/engine/engine_openssl.c | |||
| @@ -0,0 +1,174 @@ | |||
| 1 | /* crypto/engine/engine_openssl.c */ | ||
| 2 | /* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL | ||
| 3 | * project 2000. | ||
| 4 | */ | ||
| 5 | /* ==================================================================== | ||
| 6 | * Copyright (c) 1999 The OpenSSL Project. All rights reserved. | ||
| 7 | * | ||
| 8 | * Redistribution and use in source and binary forms, with or without | ||
| 9 | * modification, are permitted provided that the following conditions | ||
| 10 | * are met: | ||
| 11 | * | ||
| 12 | * 1. Redistributions of source code must retain the above copyright | ||
| 13 | * notice, this list of conditions and the following disclaimer. | ||
| 14 | * | ||
| 15 | * 2. Redistributions in binary form must reproduce the above copyright | ||
| 16 | * notice, this list of conditions and the following disclaimer in | ||
| 17 | * the documentation and/or other materials provided with the | ||
| 18 | * distribution. | ||
| 19 | * | ||
| 20 | * 3. All advertising materials mentioning features or use of this | ||
| 21 | * software must display the following acknowledgment: | ||
| 22 | * "This product includes software developed by the OpenSSL Project | ||
| 23 | * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" | ||
| 24 | * | ||
| 25 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | ||
| 26 | * endorse or promote products derived from this software without | ||
| 27 | * prior written permission. For written permission, please contact | ||
| 28 | * licensing@OpenSSL.org. | ||
| 29 | * | ||
| 30 | * 5. Products derived from this software may not be called "OpenSSL" | ||
| 31 | * nor may "OpenSSL" appear in their names without prior written | ||
| 32 | * permission of the OpenSSL Project. | ||
| 33 | * | ||
| 34 | * 6. Redistributions of any form whatsoever must retain the following | ||
| 35 | * acknowledgment: | ||
| 36 | * "This product includes software developed by the OpenSSL Project | ||
| 37 | * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" | ||
| 38 | * | ||
| 39 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | ||
| 40 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
| 41 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
| 42 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | ||
| 43 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
| 44 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
| 45 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
| 46 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| 47 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
| 48 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
| 49 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | ||
| 50 | * OF THE POSSIBILITY OF SUCH DAMAGE. | ||
| 51 | * ==================================================================== | ||
| 52 | * | ||
| 53 | * This product includes cryptographic software written by Eric Young | ||
| 54 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
| 55 | * Hudson (tjh@cryptsoft.com). | ||
| 56 | * | ||
| 57 | */ | ||
| 58 | |||
| 59 | |||
| 60 | #include <stdio.h> | ||
| 61 | #include <openssl/crypto.h> | ||
| 62 | #include "cryptlib.h" | ||
| 63 | #include "engine_int.h" | ||
| 64 | #include <openssl/engine.h> | ||
| 65 | #include <openssl/dso.h> | ||
| 66 | #include <openssl/rsa.h> | ||
| 67 | #include <openssl/dsa.h> | ||
| 68 | #include <openssl/dh.h> | ||
| 69 | #include <openssl/rand.h> | ||
| 70 | #include <openssl/bn.h> | ||
| 71 | |||
| 72 | /* This is the only function we need to implement as OpenSSL | ||
| 73 | * doesn't have a native CRT mod_exp. Perhaps this should be | ||
| 74 | * BN_mod_exp_crt and moved into crypto/bn/ ?? ... dunno. */ | ||
| 75 | static int openssl_mod_exp_crt(BIGNUM *r, BIGNUM *a, const BIGNUM *p, | ||
| 76 | const BIGNUM *q, const BIGNUM *dmp1, const BIGNUM *dmq1, | ||
| 77 | const BIGNUM *iqmp, BN_CTX *ctx); | ||
| 78 | |||
| 79 | /* The ENGINE structure that can be pointed to. */ | ||
| 80 | static ENGINE engine_openssl = | ||
| 81 | { | ||
| 82 | "openssl", | ||
| 83 | "Software default engine support", | ||
| 84 | NULL, | ||
| 85 | NULL, | ||
| 86 | NULL, /* these methods are "stolen" in ENGINE_openssl() */ | ||
| 87 | NULL, | ||
| 88 | NULL, | ||
| 89 | openssl_mod_exp_crt, | ||
| 90 | NULL, /* no init() */ | ||
| 91 | NULL, /* no finish() */ | ||
| 92 | NULL, /* no ctrl() */ | ||
| 93 | NULL, /* no load_privkey() */ | ||
| 94 | NULL, /* no load_pubkey() */ | ||
| 95 | 0, /* no flags */ | ||
| 96 | 0, 0, /* no references. */ | ||
| 97 | NULL, NULL /* unlinked */ | ||
| 98 | }; | ||
| 99 | |||
| 100 | /* As this is only ever called once, there's no need for locking | ||
| 101 | * (indeed - the lock will already be held by our caller!!!) */ | ||
| 102 | ENGINE *ENGINE_openssl() | ||
| 103 | { | ||
| 104 | /* We need to populate our structure with the software pointers | ||
| 105 | * that we want to steal. */ | ||
| 106 | engine_openssl.rsa_meth = RSA_get_default_openssl_method(); | ||
| 107 | engine_openssl.dsa_meth = DSA_get_default_openssl_method(); | ||
| 108 | engine_openssl.dh_meth = DH_get_default_openssl_method(); | ||
| 109 | engine_openssl.rand_meth = RAND_SSLeay(); | ||
| 110 | engine_openssl.bn_mod_exp = BN_mod_exp; | ||
| 111 | return &engine_openssl; | ||
| 112 | } | ||
| 113 | |||
| 114 | /* Chinese Remainder Theorem, taken and adapted from rsa_eay.c */ | ||
| 115 | static int openssl_mod_exp_crt(BIGNUM *r, BIGNUM *a, const BIGNUM *p, | ||
| 116 | const BIGNUM *q, const BIGNUM *dmp1, | ||
| 117 | const BIGNUM *dmq1, const BIGNUM *iqmp, BN_CTX *ctx) | ||
| 118 | { | ||
| 119 | BIGNUM r1,m1; | ||
| 120 | int ret=0; | ||
| 121 | BN_CTX *bn_ctx; | ||
| 122 | BIGNUM *temp_bn = NULL; | ||
| 123 | |||
| 124 | if (ctx) | ||
| 125 | bn_ctx = ctx; | ||
| 126 | else | ||
| 127 | if ((bn_ctx=BN_CTX_new()) == NULL) goto err; | ||
| 128 | BN_init(&m1); | ||
| 129 | BN_init(&r1); | ||
| 130 | /* BN_mul() cannot accept const BIGNUMs so I use the BN_CTX | ||
| 131 | * to duplicate what I need. <sigh> */ | ||
| 132 | if ((temp_bn = BN_CTX_get(bn_ctx)) == NULL) goto err; | ||
| 133 | if (!BN_copy(temp_bn, iqmp)) goto err; | ||
| 134 | |||
| 135 | if (!BN_mod(&r1, a, q, bn_ctx)) goto err; | ||
| 136 | if (!engine_openssl.bn_mod_exp(&m1, &r1, dmq1, q, bn_ctx)) | ||
| 137 | goto err; | ||
| 138 | |||
| 139 | if (!BN_mod(&r1, a, p, bn_ctx)) goto err; | ||
| 140 | if (!engine_openssl.bn_mod_exp(r, &r1, dmp1, p, bn_ctx)) | ||
| 141 | goto err; | ||
| 142 | |||
| 143 | if (!BN_sub(r, r, &m1)) goto err; | ||
| 144 | /* This will help stop the size of r0 increasing, which does | ||
| 145 | * affect the multiply if it optimised for a power of 2 size */ | ||
| 146 | if (r->neg) | ||
| 147 | if (!BN_add(r, r, p)) goto err; | ||
| 148 | |||
| 149 | if (!BN_mul(&r1, r, temp_bn, bn_ctx)) goto err; | ||
| 150 | if (!BN_mod(r, &r1, p, bn_ctx)) goto err; | ||
| 151 | /* If p < q it is occasionally possible for the correction of | ||
| 152 | * adding 'p' if r is negative above to leave the result still | ||
| 153 | * negative. This can break the private key operations: the following | ||
| 154 | * second correction should *always* correct this rare occurrence. | ||
| 155 | * This will *never* happen with OpenSSL generated keys because | ||
| 156 | * they ensure p > q [steve] | ||
| 157 | */ | ||
| 158 | if (r->neg) | ||
| 159 | if (!BN_add(r, r, p)) goto err; | ||
| 160 | /* Again, BN_mul() will need non-const values. */ | ||
| 161 | if (!BN_copy(temp_bn, q)) goto err; | ||
| 162 | if (!BN_mul(&r1, r, temp_bn, bn_ctx)) goto err; | ||
| 163 | if (!BN_add(r, &r1, &m1)) goto err; | ||
| 164 | |||
| 165 | ret=1; | ||
| 166 | err: | ||
| 167 | BN_clear_free(&m1); | ||
| 168 | BN_clear_free(&r1); | ||
| 169 | if (temp_bn) | ||
| 170 | bn_ctx->tos--; | ||
| 171 | if (!ctx) | ||
| 172 | BN_CTX_free(bn_ctx); | ||
| 173 | return(ret); | ||
| 174 | } | ||
diff --git a/src/lib/libcrypto/engine/enginetest.c b/src/lib/libcrypto/engine/enginetest.c new file mode 100644 index 0000000000..a5a3c47fcb --- /dev/null +++ b/src/lib/libcrypto/engine/enginetest.c | |||
| @@ -0,0 +1,251 @@ | |||
| 1 | /* crypto/engine/enginetest.c */ | ||
| 2 | /* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL | ||
| 3 | * project 2000. | ||
| 4 | */ | ||
| 5 | /* ==================================================================== | ||
| 6 | * Copyright (c) 1999 The OpenSSL Project. All rights reserved. | ||
| 7 | * | ||
| 8 | * Redistribution and use in source and binary forms, with or without | ||
| 9 | * modification, are permitted provided that the following conditions | ||
| 10 | * are met: | ||
| 11 | * | ||
| 12 | * 1. Redistributions of source code must retain the above copyright | ||
| 13 | * notice, this list of conditions and the following disclaimer. | ||
| 14 | * | ||
| 15 | * 2. Redistributions in binary form must reproduce the above copyright | ||
| 16 | * notice, this list of conditions and the following disclaimer in | ||
| 17 | * the documentation and/or other materials provided with the | ||
| 18 | * distribution. | ||
| 19 | * | ||
| 20 | * 3. All advertising materials mentioning features or use of this | ||
| 21 | * software must display the following acknowledgment: | ||
| 22 | * "This product includes software developed by the OpenSSL Project | ||
| 23 | * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" | ||
| 24 | * | ||
| 25 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | ||
| 26 | * endorse or promote products derived from this software without | ||
| 27 | * prior written permission. For written permission, please contact | ||
| 28 | * licensing@OpenSSL.org. | ||
| 29 | * | ||
| 30 | * 5. Products derived from this software may not be called "OpenSSL" | ||
| 31 | * nor may "OpenSSL" appear in their names without prior written | ||
| 32 | * permission of the OpenSSL Project. | ||
| 33 | * | ||
| 34 | * 6. Redistributions of any form whatsoever must retain the following | ||
| 35 | * acknowledgment: | ||
| 36 | * "This product includes software developed by the OpenSSL Project | ||
| 37 | * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" | ||
| 38 | * | ||
| 39 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | ||
| 40 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
| 41 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
| 42 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | ||
| 43 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
| 44 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
| 45 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
| 46 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| 47 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
| 48 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
| 49 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | ||
| 50 | * OF THE POSSIBILITY OF SUCH DAMAGE. | ||
| 51 | * ==================================================================== | ||
| 52 | * | ||
| 53 | * This product includes cryptographic software written by Eric Young | ||
| 54 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
| 55 | * Hudson (tjh@cryptsoft.com). | ||
| 56 | * | ||
| 57 | */ | ||
| 58 | |||
| 59 | #include <stdio.h> | ||
| 60 | #include <string.h> | ||
| 61 | #include <openssl/engine.h> | ||
| 62 | #include <openssl/err.h> | ||
| 63 | |||
| 64 | static void display_engine_list() | ||
| 65 | { | ||
| 66 | ENGINE *h; | ||
| 67 | int loop; | ||
| 68 | |||
| 69 | h = ENGINE_get_first(); | ||
| 70 | loop = 0; | ||
| 71 | printf("listing available engine types\n"); | ||
| 72 | while(h) | ||
| 73 | { | ||
| 74 | printf("engine %i, id = \"%s\", name = \"%s\"\n", | ||
| 75 | loop++, ENGINE_get_id(h), ENGINE_get_name(h)); | ||
| 76 | h = ENGINE_get_next(h); | ||
| 77 | } | ||
| 78 | printf("end of list\n"); | ||
| 79 | } | ||
| 80 | |||
| 81 | int main(int argc, char *argv[]) | ||
| 82 | { | ||
| 83 | ENGINE *block[512]; | ||
| 84 | char buf[256]; | ||
| 85 | const char *id, *name; | ||
| 86 | ENGINE *ptr; | ||
| 87 | int loop; | ||
| 88 | int to_return = 1; | ||
| 89 | ENGINE *new_h1 = NULL; | ||
| 90 | ENGINE *new_h2 = NULL; | ||
| 91 | ENGINE *new_h3 = NULL; | ||
| 92 | ENGINE *new_h4 = NULL; | ||
| 93 | |||
| 94 | ERR_load_crypto_strings(); | ||
| 95 | |||
| 96 | memset(block, 0, 512 * sizeof(ENGINE *)); | ||
| 97 | if(((new_h1 = ENGINE_new()) == NULL) || | ||
| 98 | !ENGINE_set_id(new_h1, "test_id0") || | ||
| 99 | !ENGINE_set_name(new_h1, "First test item") || | ||
| 100 | ((new_h2 = ENGINE_new()) == NULL) || | ||
| 101 | !ENGINE_set_id(new_h2, "test_id1") || | ||
| 102 | !ENGINE_set_name(new_h2, "Second test item") || | ||
| 103 | ((new_h3 = ENGINE_new()) == NULL) || | ||
| 104 | !ENGINE_set_id(new_h3, "test_id2") || | ||
| 105 | !ENGINE_set_name(new_h3, "Third test item") || | ||
| 106 | ((new_h4 = ENGINE_new()) == NULL) || | ||
| 107 | !ENGINE_set_id(new_h4, "test_id3") || | ||
| 108 | !ENGINE_set_name(new_h4, "Fourth test item")) | ||
| 109 | { | ||
| 110 | printf("Couldn't set up test ENGINE structures\n"); | ||
| 111 | goto end; | ||
| 112 | } | ||
| 113 | printf("\nenginetest beginning\n\n"); | ||
| 114 | display_engine_list(); | ||
| 115 | if(!ENGINE_add(new_h1)) | ||
| 116 | { | ||
| 117 | printf("Add failed!\n"); | ||
| 118 | goto end; | ||
| 119 | } | ||
| 120 | display_engine_list(); | ||
| 121 | ptr = ENGINE_get_first(); | ||
| 122 | if(!ENGINE_remove(ptr)) | ||
| 123 | { | ||
| 124 | printf("Remove failed!\n"); | ||
| 125 | goto end; | ||
| 126 | } | ||
| 127 | display_engine_list(); | ||
| 128 | if(!ENGINE_add(new_h3) || !ENGINE_add(new_h2)) | ||
| 129 | { | ||
| 130 | printf("Add failed!\n"); | ||
| 131 | goto end; | ||
| 132 | } | ||
| 133 | display_engine_list(); | ||
| 134 | if(!ENGINE_remove(new_h2)) | ||
| 135 | { | ||
| 136 | printf("Remove failed!\n"); | ||
| 137 | goto end; | ||
| 138 | } | ||
| 139 | display_engine_list(); | ||
| 140 | if(!ENGINE_add(new_h4)) | ||
| 141 | { | ||
| 142 | printf("Add failed!\n"); | ||
| 143 | goto end; | ||
| 144 | } | ||
| 145 | display_engine_list(); | ||
| 146 | if(ENGINE_add(new_h3)) | ||
| 147 | { | ||
| 148 | printf("Add *should* have failed but didn't!\n"); | ||
| 149 | goto end; | ||
| 150 | } | ||
| 151 | else | ||
| 152 | printf("Add that should fail did.\n"); | ||
| 153 | ERR_clear_error(); | ||
| 154 | if(ENGINE_remove(new_h2)) | ||
| 155 | { | ||
| 156 | printf("Remove *should* have failed but didn't!\n"); | ||
| 157 | goto end; | ||
| 158 | } | ||
| 159 | else | ||
| 160 | printf("Remove that should fail did.\n"); | ||
| 161 | if(!ENGINE_remove(new_h1)) | ||
| 162 | { | ||
| 163 | printf("Remove failed!\n"); | ||
| 164 | goto end; | ||
| 165 | } | ||
| 166 | display_engine_list(); | ||
| 167 | if(!ENGINE_remove(new_h3)) | ||
| 168 | { | ||
| 169 | printf("Remove failed!\n"); | ||
| 170 | goto end; | ||
| 171 | } | ||
| 172 | display_engine_list(); | ||
| 173 | if(!ENGINE_remove(new_h4)) | ||
| 174 | { | ||
| 175 | printf("Remove failed!\n"); | ||
| 176 | goto end; | ||
| 177 | } | ||
| 178 | display_engine_list(); | ||
| 179 | /* Depending on whether there's any hardware support compiled | ||
| 180 | * in, this remove may be destined to fail. */ | ||
| 181 | ptr = ENGINE_get_first(); | ||
| 182 | if(ptr) | ||
| 183 | if(!ENGINE_remove(ptr)) | ||
| 184 | printf("Remove failed!i - probably no hardware " | ||
| 185 | "support present.\n"); | ||
| 186 | display_engine_list(); | ||
| 187 | if(!ENGINE_add(new_h1) || !ENGINE_remove(new_h1)) | ||
| 188 | { | ||
| 189 | printf("Couldn't add and remove to an empty list!\n"); | ||
| 190 | goto end; | ||
| 191 | } | ||
| 192 | else | ||
| 193 | printf("Successfully added and removed to an empty list!\n"); | ||
| 194 | printf("About to beef up the engine-type list\n"); | ||
| 195 | for(loop = 0; loop < 512; loop++) | ||
| 196 | { | ||
| 197 | sprintf(buf, "id%i", loop); | ||
| 198 | id = strdup(buf); | ||
| 199 | sprintf(buf, "Fake engine type %i", loop); | ||
| 200 | name = strdup(buf); | ||
| 201 | if(((block[loop] = ENGINE_new()) == NULL) || | ||
| 202 | !ENGINE_set_id(block[loop], id) || | ||
| 203 | !ENGINE_set_name(block[loop], name)) | ||
| 204 | { | ||
| 205 | printf("Couldn't create block of ENGINE structures.\n" | ||
| 206 | "I'll probably also core-dump now, damn.\n"); | ||
| 207 | goto end; | ||
| 208 | } | ||
| 209 | } | ||
| 210 | for(loop = 0; loop < 512; loop++) | ||
| 211 | { | ||
| 212 | if(!ENGINE_add(block[loop])) | ||
| 213 | { | ||
| 214 | printf("\nAdding stopped at %i, (%s,%s)\n", | ||
| 215 | loop, ENGINE_get_id(block[loop]), | ||
| 216 | ENGINE_get_name(block[loop])); | ||
| 217 | goto cleanup_loop; | ||
| 218 | } | ||
| 219 | else | ||
| 220 | printf("."); fflush(stdout); | ||
| 221 | } | ||
| 222 | cleanup_loop: | ||
| 223 | printf("\nAbout to empty the engine-type list\n"); | ||
| 224 | while((ptr = ENGINE_get_first()) != NULL) | ||
| 225 | { | ||
| 226 | if(!ENGINE_remove(ptr)) | ||
| 227 | { | ||
| 228 | printf("\nRemove failed!\n"); | ||
| 229 | goto end; | ||
| 230 | } | ||
| 231 | printf("."); fflush(stdout); | ||
| 232 | } | ||
| 233 | for(loop = 0; loop < 512; loop++) | ||
| 234 | { | ||
| 235 | free((char *)(ENGINE_get_id(block[loop]))); | ||
| 236 | free((char *)(ENGINE_get_name(block[loop]))); | ||
| 237 | } | ||
| 238 | printf("\nTests completed happily\n"); | ||
| 239 | to_return = 0; | ||
| 240 | end: | ||
| 241 | if(to_return) | ||
| 242 | ERR_print_errors_fp(stderr); | ||
| 243 | if(new_h1) ENGINE_free(new_h1); | ||
| 244 | if(new_h2) ENGINE_free(new_h2); | ||
| 245 | if(new_h3) ENGINE_free(new_h3); | ||
| 246 | if(new_h4) ENGINE_free(new_h4); | ||
| 247 | for(loop = 0; loop < 512; loop++) | ||
| 248 | if(block[loop]) | ||
| 249 | ENGINE_free(block[loop]); | ||
| 250 | return to_return; | ||
| 251 | } | ||
diff --git a/src/lib/libcrypto/engine/hw_atalla.c b/src/lib/libcrypto/engine/hw_atalla.c new file mode 100644 index 0000000000..3bb992a193 --- /dev/null +++ b/src/lib/libcrypto/engine/hw_atalla.c | |||
| @@ -0,0 +1,444 @@ | |||
| 1 | /* crypto/engine/hw_atalla.c */ | ||
| 2 | /* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL | ||
| 3 | * project 2000. | ||
| 4 | */ | ||
| 5 | /* ==================================================================== | ||
| 6 | * Copyright (c) 1999 The OpenSSL Project. All rights reserved. | ||
| 7 | * | ||
| 8 | * Redistribution and use in source and binary forms, with or without | ||
| 9 | * modification, are permitted provided that the following conditions | ||
| 10 | * are met: | ||
| 11 | * | ||
| 12 | * 1. Redistributions of source code must retain the above copyright | ||
| 13 | * notice, this list of conditions and the following disclaimer. | ||
| 14 | * | ||
| 15 | * 2. Redistributions in binary form must reproduce the above copyright | ||
| 16 | * notice, this list of conditions and the following disclaimer in | ||
| 17 | * the documentation and/or other materials provided with the | ||
| 18 | * distribution. | ||
| 19 | * | ||
| 20 | * 3. All advertising materials mentioning features or use of this | ||
| 21 | * software must display the following acknowledgment: | ||
| 22 | * "This product includes software developed by the OpenSSL Project | ||
| 23 | * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" | ||
| 24 | * | ||
| 25 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | ||
| 26 | * endorse or promote products derived from this software without | ||
| 27 | * prior written permission. For written permission, please contact | ||
| 28 | * licensing@OpenSSL.org. | ||
| 29 | * | ||
| 30 | * 5. Products derived from this software may not be called "OpenSSL" | ||
| 31 | * nor may "OpenSSL" appear in their names without prior written | ||
| 32 | * permission of the OpenSSL Project. | ||
| 33 | * | ||
| 34 | * 6. Redistributions of any form whatsoever must retain the following | ||
| 35 | * acknowledgment: | ||
| 36 | * "This product includes software developed by the OpenSSL Project | ||
| 37 | * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" | ||
| 38 | * | ||
| 39 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | ||
| 40 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
| 41 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
| 42 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | ||
| 43 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
| 44 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
| 45 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
| 46 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| 47 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
| 48 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
| 49 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | ||
| 50 | * OF THE POSSIBILITY OF SUCH DAMAGE. | ||
| 51 | * ==================================================================== | ||
| 52 | * | ||
| 53 | * This product includes cryptographic software written by Eric Young | ||
| 54 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
| 55 | * Hudson (tjh@cryptsoft.com). | ||
| 56 | * | ||
| 57 | */ | ||
| 58 | |||
| 59 | #include <stdio.h> | ||
| 60 | #include <openssl/crypto.h> | ||
| 61 | #include "cryptlib.h" | ||
| 62 | #include <openssl/dso.h> | ||
| 63 | #include "engine_int.h" | ||
| 64 | #include <openssl/engine.h> | ||
| 65 | |||
| 66 | #ifndef NO_HW | ||
| 67 | #ifndef NO_HW_ATALLA | ||
| 68 | |||
| 69 | #ifdef FLAT_INC | ||
| 70 | #include "atalla.h" | ||
| 71 | #else | ||
| 72 | #include "vendor_defns/atalla.h" | ||
| 73 | #endif | ||
| 74 | |||
| 75 | static int atalla_init(void); | ||
| 76 | static int atalla_finish(void); | ||
| 77 | |||
| 78 | /* BIGNUM stuff */ | ||
| 79 | static int atalla_mod_exp(BIGNUM *r, BIGNUM *a, const BIGNUM *p, | ||
| 80 | const BIGNUM *m, BN_CTX *ctx); | ||
| 81 | |||
| 82 | /* RSA stuff */ | ||
| 83 | static int atalla_rsa_mod_exp(BIGNUM *r0, BIGNUM *I, RSA *rsa); | ||
| 84 | /* This function is aliased to mod_exp (with the mont stuff dropped). */ | ||
| 85 | static int atalla_mod_exp_mont(BIGNUM *r, BIGNUM *a, const BIGNUM *p, | ||
| 86 | const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); | ||
| 87 | |||
| 88 | /* DSA stuff */ | ||
| 89 | static int atalla_dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1, | ||
| 90 | BIGNUM *p1, BIGNUM *a2, BIGNUM *p2, BIGNUM *m, | ||
| 91 | BN_CTX *ctx, BN_MONT_CTX *in_mont); | ||
| 92 | static int atalla_mod_exp_dsa(DSA *dsa, BIGNUM *r, BIGNUM *a, | ||
| 93 | const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, | ||
| 94 | BN_MONT_CTX *m_ctx); | ||
| 95 | |||
| 96 | /* DH stuff */ | ||
| 97 | /* This function is alised to mod_exp (with the DH and mont dropped). */ | ||
| 98 | static int atalla_mod_exp_dh(DH *dh, BIGNUM *r, BIGNUM *a, const BIGNUM *p, | ||
| 99 | const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); | ||
| 100 | |||
| 101 | |||
| 102 | /* Our internal RSA_METHOD that we provide pointers to */ | ||
| 103 | static RSA_METHOD atalla_rsa = | ||
| 104 | { | ||
| 105 | "Atalla RSA method", | ||
| 106 | NULL, | ||
| 107 | NULL, | ||
| 108 | NULL, | ||
| 109 | NULL, | ||
| 110 | atalla_rsa_mod_exp, | ||
| 111 | atalla_mod_exp_mont, | ||
| 112 | NULL, | ||
| 113 | NULL, | ||
| 114 | 0, | ||
| 115 | NULL, | ||
| 116 | NULL, | ||
| 117 | NULL | ||
| 118 | }; | ||
| 119 | |||
| 120 | /* Our internal DSA_METHOD that we provide pointers to */ | ||
| 121 | static DSA_METHOD atalla_dsa = | ||
| 122 | { | ||
| 123 | "Atalla DSA method", | ||
| 124 | NULL, /* dsa_do_sign */ | ||
| 125 | NULL, /* dsa_sign_setup */ | ||
| 126 | NULL, /* dsa_do_verify */ | ||
| 127 | atalla_dsa_mod_exp, /* dsa_mod_exp */ | ||
| 128 | atalla_mod_exp_dsa, /* bn_mod_exp */ | ||
| 129 | NULL, /* init */ | ||
| 130 | NULL, /* finish */ | ||
| 131 | 0, /* flags */ | ||
| 132 | NULL /* app_data */ | ||
| 133 | }; | ||
| 134 | |||
| 135 | /* Our internal DH_METHOD that we provide pointers to */ | ||
| 136 | static DH_METHOD atalla_dh = | ||
| 137 | { | ||
| 138 | "Atalla DH method", | ||
| 139 | NULL, | ||
| 140 | NULL, | ||
| 141 | atalla_mod_exp_dh, | ||
| 142 | NULL, | ||
| 143 | NULL, | ||
| 144 | 0, | ||
| 145 | NULL | ||
| 146 | }; | ||
| 147 | |||
| 148 | /* Our ENGINE structure. */ | ||
| 149 | static ENGINE engine_atalla = | ||
| 150 | { | ||
| 151 | "atalla", | ||
| 152 | "Atalla hardware engine support", | ||
| 153 | &atalla_rsa, | ||
| 154 | &atalla_dsa, | ||
| 155 | &atalla_dh, | ||
| 156 | NULL, | ||
| 157 | atalla_mod_exp, | ||
| 158 | NULL, | ||
| 159 | atalla_init, | ||
| 160 | atalla_finish, | ||
| 161 | NULL, /* no ctrl() */ | ||
| 162 | NULL, /* no load_privkey() */ | ||
| 163 | NULL, /* no load_pubkey() */ | ||
| 164 | 0, /* no flags */ | ||
| 165 | 0, 0, /* no references */ | ||
| 166 | NULL, NULL /* unlinked */ | ||
| 167 | }; | ||
| 168 | |||
| 169 | /* As this is only ever called once, there's no need for locking | ||
| 170 | * (indeed - the lock will already be held by our caller!!!) */ | ||
| 171 | ENGINE *ENGINE_atalla() | ||
| 172 | { | ||
| 173 | RSA_METHOD *meth1; | ||
| 174 | DSA_METHOD *meth2; | ||
| 175 | DH_METHOD *meth3; | ||
| 176 | |||
| 177 | /* We know that the "PKCS1_SSLeay()" functions hook properly | ||
| 178 | * to the atalla-specific mod_exp and mod_exp_crt so we use | ||
| 179 | * those functions. NB: We don't use ENGINE_openssl() or | ||
| 180 | * anything "more generic" because something like the RSAref | ||
| 181 | * code may not hook properly, and if you own one of these | ||
| 182 | * cards then you have the right to do RSA operations on it | ||
| 183 | * anyway! */ | ||
| 184 | meth1 = RSA_PKCS1_SSLeay(); | ||
| 185 | atalla_rsa.rsa_pub_enc = meth1->rsa_pub_enc; | ||
| 186 | atalla_rsa.rsa_pub_dec = meth1->rsa_pub_dec; | ||
| 187 | atalla_rsa.rsa_priv_enc = meth1->rsa_priv_enc; | ||
| 188 | atalla_rsa.rsa_priv_dec = meth1->rsa_priv_dec; | ||
| 189 | |||
| 190 | /* Use the DSA_OpenSSL() method and just hook the mod_exp-ish | ||
| 191 | * bits. */ | ||
| 192 | meth2 = DSA_OpenSSL(); | ||
| 193 | atalla_dsa.dsa_do_sign = meth2->dsa_do_sign; | ||
| 194 | atalla_dsa.dsa_sign_setup = meth2->dsa_sign_setup; | ||
| 195 | atalla_dsa.dsa_do_verify = meth2->dsa_do_verify; | ||
| 196 | |||
| 197 | /* Much the same for Diffie-Hellman */ | ||
| 198 | meth3 = DH_OpenSSL(); | ||
| 199 | atalla_dh.generate_key = meth3->generate_key; | ||
| 200 | atalla_dh.compute_key = meth3->compute_key; | ||
| 201 | return &engine_atalla; | ||
| 202 | } | ||
| 203 | |||
| 204 | /* This is a process-global DSO handle used for loading and unloading | ||
| 205 | * the Atalla library. NB: This is only set (or unset) during an | ||
| 206 | * init() or finish() call (reference counts permitting) and they're | ||
| 207 | * operating with global locks, so this should be thread-safe | ||
| 208 | * implicitly. */ | ||
| 209 | static DSO *atalla_dso = NULL; | ||
| 210 | |||
| 211 | /* These are the function pointers that are (un)set when the library has | ||
| 212 | * successfully (un)loaded. */ | ||
| 213 | static tfnASI_GetHardwareConfig *p_Atalla_GetHardwareConfig = NULL; | ||
| 214 | static tfnASI_RSAPrivateKeyOpFn *p_Atalla_RSAPrivateKeyOpFn = NULL; | ||
| 215 | static tfnASI_GetPerformanceStatistics *p_Atalla_GetPerformanceStatistics = NULL; | ||
| 216 | |||
| 217 | /* (de)initialisation functions. */ | ||
| 218 | static int atalla_init() | ||
| 219 | { | ||
| 220 | tfnASI_GetHardwareConfig *p1; | ||
| 221 | tfnASI_RSAPrivateKeyOpFn *p2; | ||
| 222 | tfnASI_GetPerformanceStatistics *p3; | ||
| 223 | /* Not sure of the origin of this magic value, but Ben's code had it | ||
| 224 | * and it seemed to have been working for a few people. :-) */ | ||
| 225 | unsigned int config_buf[1024]; | ||
| 226 | |||
| 227 | if(atalla_dso != NULL) | ||
| 228 | { | ||
| 229 | ENGINEerr(ENGINE_F_ATALLA_INIT,ENGINE_R_ALREADY_LOADED); | ||
| 230 | goto err; | ||
| 231 | } | ||
| 232 | /* Attempt to load libatasi.so/atasi.dll/whatever. Needs to be | ||
| 233 | * changed unfortunately because the Atalla drivers don't have | ||
| 234 | * standard library names that can be platform-translated well. */ | ||
| 235 | /* TODO: Work out how to actually map to the names the Atalla | ||
| 236 | * drivers really use - for now a symbollic link needs to be | ||
| 237 | * created on the host system from libatasi.so to atasi.so on | ||
| 238 | * unix variants. */ | ||
| 239 | atalla_dso = DSO_load(NULL, ATALLA_LIBNAME, NULL, | ||
| 240 | DSO_FLAG_NAME_TRANSLATION); | ||
| 241 | if(atalla_dso == NULL) | ||
| 242 | { | ||
| 243 | ENGINEerr(ENGINE_F_ATALLA_INIT,ENGINE_R_DSO_FAILURE); | ||
| 244 | goto err; | ||
| 245 | } | ||
| 246 | if(!(p1 = (tfnASI_GetHardwareConfig *)DSO_bind_func( | ||
| 247 | atalla_dso, ATALLA_F1)) || | ||
| 248 | !(p2 = (tfnASI_RSAPrivateKeyOpFn *)DSO_bind_func( | ||
| 249 | atalla_dso, ATALLA_F2)) || | ||
| 250 | !(p3 = (tfnASI_GetPerformanceStatistics *)DSO_bind_func( | ||
| 251 | atalla_dso, ATALLA_F3))) | ||
| 252 | { | ||
| 253 | ENGINEerr(ENGINE_F_ATALLA_INIT,ENGINE_R_DSO_FAILURE); | ||
| 254 | goto err; | ||
| 255 | } | ||
| 256 | /* Copy the pointers */ | ||
| 257 | p_Atalla_GetHardwareConfig = p1; | ||
| 258 | p_Atalla_RSAPrivateKeyOpFn = p2; | ||
| 259 | p_Atalla_GetPerformanceStatistics = p3; | ||
| 260 | /* Perform a basic test to see if there's actually any unit | ||
| 261 | * running. */ | ||
| 262 | if(p1(0L, config_buf) != 0) | ||
| 263 | { | ||
| 264 | ENGINEerr(ENGINE_F_ATALLA_INIT,ENGINE_R_UNIT_FAILURE); | ||
| 265 | goto err; | ||
| 266 | } | ||
| 267 | /* Everything's fine. */ | ||
| 268 | return 1; | ||
| 269 | err: | ||
| 270 | if(atalla_dso) | ||
| 271 | DSO_free(atalla_dso); | ||
| 272 | p_Atalla_GetHardwareConfig = NULL; | ||
| 273 | p_Atalla_RSAPrivateKeyOpFn = NULL; | ||
| 274 | p_Atalla_GetPerformanceStatistics = NULL; | ||
| 275 | return 0; | ||
| 276 | } | ||
| 277 | |||
| 278 | static int atalla_finish() | ||
| 279 | { | ||
| 280 | if(atalla_dso == NULL) | ||
| 281 | { | ||
| 282 | ENGINEerr(ENGINE_F_ATALLA_FINISH,ENGINE_R_NOT_LOADED); | ||
| 283 | return 0; | ||
| 284 | } | ||
| 285 | if(!DSO_free(atalla_dso)) | ||
| 286 | { | ||
| 287 | ENGINEerr(ENGINE_F_ATALLA_FINISH,ENGINE_R_DSO_FAILURE); | ||
| 288 | return 0; | ||
| 289 | } | ||
| 290 | atalla_dso = NULL; | ||
| 291 | p_Atalla_GetHardwareConfig = NULL; | ||
| 292 | p_Atalla_RSAPrivateKeyOpFn = NULL; | ||
| 293 | p_Atalla_GetPerformanceStatistics = NULL; | ||
| 294 | return 1; | ||
| 295 | } | ||
| 296 | |||
| 297 | static int atalla_mod_exp(BIGNUM *r, BIGNUM *a, const BIGNUM *p, | ||
| 298 | const BIGNUM *m, BN_CTX *ctx) | ||
| 299 | { | ||
| 300 | /* I need somewhere to store temporary serialised values for | ||
| 301 | * use with the Atalla API calls. A neat cheat - I'll use | ||
| 302 | * BIGNUMs from the BN_CTX but access their arrays directly as | ||
| 303 | * byte arrays <grin>. This way I don't have to clean anything | ||
| 304 | * up. */ | ||
| 305 | BIGNUM *modulus; | ||
| 306 | BIGNUM *exponent; | ||
| 307 | BIGNUM *argument; | ||
| 308 | BIGNUM *result; | ||
| 309 | RSAPrivateKey keydata; | ||
| 310 | int to_return, numbytes; | ||
| 311 | |||
| 312 | modulus = exponent = argument = result = NULL; | ||
| 313 | to_return = 0; /* expect failure */ | ||
| 314 | |||
| 315 | if(!atalla_dso) | ||
| 316 | { | ||
| 317 | ENGINEerr(ENGINE_F_ATALLA_MOD_EXP,ENGINE_R_NOT_LOADED); | ||
| 318 | goto err; | ||
| 319 | } | ||
| 320 | /* Prepare the params */ | ||
| 321 | modulus = BN_CTX_get(ctx); | ||
| 322 | exponent = BN_CTX_get(ctx); | ||
| 323 | argument = BN_CTX_get(ctx); | ||
| 324 | result = BN_CTX_get(ctx); | ||
| 325 | if(!modulus || !exponent || !argument || !result) | ||
| 326 | { | ||
| 327 | ENGINEerr(ENGINE_F_ATALLA_MOD_EXP,ENGINE_R_BN_CTX_FULL); | ||
| 328 | goto err; | ||
| 329 | } | ||
| 330 | if(!bn_wexpand(modulus, m->top) || !bn_wexpand(exponent, m->top) || | ||
| 331 | !bn_wexpand(argument, m->top) || !bn_wexpand(result, m->top)) | ||
| 332 | { | ||
| 333 | ENGINEerr(ENGINE_F_ATALLA_MOD_EXP,ENGINE_R_BN_EXPAND_FAIL); | ||
| 334 | goto err; | ||
| 335 | } | ||
| 336 | /* Prepare the key-data */ | ||
| 337 | memset(&keydata, 0,sizeof keydata); | ||
| 338 | numbytes = BN_num_bytes(m); | ||
| 339 | memset(exponent->d, 0, numbytes); | ||
| 340 | memset(modulus->d, 0, numbytes); | ||
| 341 | BN_bn2bin(p, (unsigned char *)exponent->d + numbytes - BN_num_bytes(p)); | ||
| 342 | BN_bn2bin(m, (unsigned char *)modulus->d + numbytes - BN_num_bytes(m)); | ||
| 343 | keydata.privateExponent.data = (unsigned char *)exponent->d; | ||
| 344 | keydata.privateExponent.len = numbytes; | ||
| 345 | keydata.modulus.data = (unsigned char *)modulus->d; | ||
| 346 | keydata.modulus.len = numbytes; | ||
| 347 | /* Prepare the argument */ | ||
| 348 | memset(argument->d, 0, numbytes); | ||
| 349 | memset(result->d, 0, numbytes); | ||
| 350 | BN_bn2bin(a, (unsigned char *)argument->d + numbytes - BN_num_bytes(a)); | ||
| 351 | /* Perform the operation */ | ||
| 352 | if(p_Atalla_RSAPrivateKeyOpFn(&keydata, (unsigned char *)result->d, | ||
| 353 | (unsigned char *)argument->d, | ||
| 354 | keydata.modulus.len) != 0) | ||
| 355 | { | ||
| 356 | ENGINEerr(ENGINE_F_ATALLA_MOD_EXP,ENGINE_R_REQUEST_FAILED); | ||
| 357 | goto err; | ||
| 358 | } | ||
| 359 | /* Convert the response */ | ||
| 360 | BN_bin2bn((unsigned char *)result->d, numbytes, r); | ||
| 361 | to_return = 1; | ||
| 362 | err: | ||
| 363 | if(modulus) ctx->tos--; | ||
| 364 | if(exponent) ctx->tos--; | ||
| 365 | if(argument) ctx->tos--; | ||
| 366 | if(result) ctx->tos--; | ||
| 367 | return to_return; | ||
| 368 | } | ||
| 369 | |||
| 370 | static int atalla_rsa_mod_exp(BIGNUM *r0, BIGNUM *I, RSA *rsa) | ||
| 371 | { | ||
| 372 | BN_CTX *ctx = NULL; | ||
| 373 | int to_return = 0; | ||
| 374 | |||
| 375 | if(!atalla_dso) | ||
| 376 | { | ||
| 377 | ENGINEerr(ENGINE_F_ATALLA_RSA_MOD_EXP,ENGINE_R_NOT_LOADED); | ||
| 378 | goto err; | ||
| 379 | } | ||
| 380 | if((ctx = BN_CTX_new()) == NULL) | ||
| 381 | goto err; | ||
| 382 | if(!rsa->d || !rsa->n) | ||
| 383 | { | ||
| 384 | ENGINEerr(ENGINE_F_ATALLA_RSA_MOD_EXP,ENGINE_R_MISSING_KEY_COMPONENTS); | ||
| 385 | goto err; | ||
| 386 | } | ||
| 387 | to_return = atalla_mod_exp(r0, I, rsa->d, rsa->n, ctx); | ||
| 388 | err: | ||
| 389 | if(ctx) | ||
| 390 | BN_CTX_free(ctx); | ||
| 391 | return to_return; | ||
| 392 | } | ||
| 393 | |||
| 394 | /* This code was liberated and adapted from the commented-out code in | ||
| 395 | * dsa_ossl.c. Because of the unoptimised form of the Atalla acceleration | ||
| 396 | * (it doesn't have a CRT form for RSA), this function means that an | ||
| 397 | * Atalla system running with a DSA server certificate can handshake | ||
| 398 | * around 5 or 6 times faster/more than an equivalent system running with | ||
| 399 | * RSA. Just check out the "signs" statistics from the RSA and DSA parts | ||
| 400 | * of "openssl speed -engine atalla dsa1024 rsa1024". */ | ||
| 401 | static int atalla_dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1, | ||
| 402 | BIGNUM *p1, BIGNUM *a2, BIGNUM *p2, BIGNUM *m, | ||
| 403 | BN_CTX *ctx, BN_MONT_CTX *in_mont) | ||
| 404 | { | ||
| 405 | BIGNUM t; | ||
| 406 | int to_return = 0; | ||
| 407 | |||
| 408 | BN_init(&t); | ||
| 409 | /* let rr = a1 ^ p1 mod m */ | ||
| 410 | if (!atalla_mod_exp(rr,a1,p1,m,ctx)) goto end; | ||
| 411 | /* let t = a2 ^ p2 mod m */ | ||
| 412 | if (!atalla_mod_exp(&t,a2,p2,m,ctx)) goto end; | ||
| 413 | /* let rr = rr * t mod m */ | ||
| 414 | if (!BN_mod_mul(rr,rr,&t,m,ctx)) goto end; | ||
| 415 | to_return = 1; | ||
| 416 | end: | ||
| 417 | BN_free(&t); | ||
| 418 | return to_return; | ||
| 419 | } | ||
| 420 | |||
| 421 | |||
| 422 | static int atalla_mod_exp_dsa(DSA *dsa, BIGNUM *r, BIGNUM *a, | ||
| 423 | const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, | ||
| 424 | BN_MONT_CTX *m_ctx) | ||
| 425 | { | ||
| 426 | return atalla_mod_exp(r, a, p, m, ctx); | ||
| 427 | } | ||
| 428 | |||
| 429 | /* This function is aliased to mod_exp (with the mont stuff dropped). */ | ||
| 430 | static int atalla_mod_exp_mont(BIGNUM *r, BIGNUM *a, const BIGNUM *p, | ||
| 431 | const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx) | ||
| 432 | { | ||
| 433 | return atalla_mod_exp(r, a, p, m, ctx); | ||
| 434 | } | ||
| 435 | |||
| 436 | /* This function is aliased to mod_exp (with the dh and mont dropped). */ | ||
| 437 | static int atalla_mod_exp_dh(DH *dh, BIGNUM *r, BIGNUM *a, const BIGNUM *p, | ||
| 438 | const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx) | ||
| 439 | { | ||
| 440 | return atalla_mod_exp(r, a, p, m, ctx); | ||
| 441 | } | ||
| 442 | |||
| 443 | #endif /* !NO_HW_ATALLA */ | ||
| 444 | #endif /* !NO_HW */ | ||
diff --git a/src/lib/libcrypto/engine/hw_cswift.c b/src/lib/libcrypto/engine/hw_cswift.c new file mode 100644 index 0000000000..77608b8983 --- /dev/null +++ b/src/lib/libcrypto/engine/hw_cswift.c | |||
| @@ -0,0 +1,807 @@ | |||
| 1 | /* crypto/engine/hw_cswift.c */ | ||
| 2 | /* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL | ||
| 3 | * project 2000. | ||
| 4 | */ | ||
| 5 | /* ==================================================================== | ||
| 6 | * Copyright (c) 1999 The OpenSSL Project. All rights reserved. | ||
| 7 | * | ||
| 8 | * Redistribution and use in source and binary forms, with or without | ||
| 9 | * modification, are permitted provided that the following conditions | ||
| 10 | * are met: | ||
| 11 | * | ||
| 12 | * 1. Redistributions of source code must retain the above copyright | ||
| 13 | * notice, this list of conditions and the following disclaimer. | ||
| 14 | * | ||
| 15 | * 2. Redistributions in binary form must reproduce the above copyright | ||
| 16 | * notice, this list of conditions and the following disclaimer in | ||
| 17 | * the documentation and/or other materials provided with the | ||
| 18 | * distribution. | ||
| 19 | * | ||
| 20 | * 3. All advertising materials mentioning features or use of this | ||
| 21 | * software must display the following acknowledgment: | ||
| 22 | * "This product includes software developed by the OpenSSL Project | ||
| 23 | * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" | ||
| 24 | * | ||
| 25 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | ||
| 26 | * endorse or promote products derived from this software without | ||
| 27 | * prior written permission. For written permission, please contact | ||
| 28 | * licensing@OpenSSL.org. | ||
| 29 | * | ||
| 30 | * 5. Products derived from this software may not be called "OpenSSL" | ||
| 31 | * nor may "OpenSSL" appear in their names without prior written | ||
| 32 | * permission of the OpenSSL Project. | ||
| 33 | * | ||
| 34 | * 6. Redistributions of any form whatsoever must retain the following | ||
| 35 | * acknowledgment: | ||
| 36 | * "This product includes software developed by the OpenSSL Project | ||
| 37 | * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" | ||
| 38 | * | ||
| 39 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | ||
| 40 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
| 41 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
| 42 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | ||
| 43 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
| 44 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
| 45 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
| 46 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| 47 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
| 48 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
| 49 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | ||
| 50 | * OF THE POSSIBILITY OF SUCH DAMAGE. | ||
| 51 | * ==================================================================== | ||
| 52 | * | ||
| 53 | * This product includes cryptographic software written by Eric Young | ||
| 54 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
| 55 | * Hudson (tjh@cryptsoft.com). | ||
| 56 | * | ||
| 57 | */ | ||
| 58 | |||
| 59 | #include <stdio.h> | ||
| 60 | #include <openssl/crypto.h> | ||
| 61 | #include "cryptlib.h" | ||
| 62 | #include <openssl/dso.h> | ||
| 63 | #include "engine_int.h" | ||
| 64 | #include <openssl/engine.h> | ||
| 65 | |||
| 66 | #ifndef NO_HW | ||
| 67 | #ifndef NO_HW_CSWIFT | ||
| 68 | |||
| 69 | /* Attribution notice: Rainbow have generously allowed me to reproduce | ||
| 70 | * the necessary definitions here from their API. This means the support | ||
| 71 | * can build independently of whether application builders have the | ||
| 72 | * API or hardware. This will allow developers to easily produce software | ||
| 73 | * that has latent hardware support for any users that have accelerators | ||
| 74 | * installed, without the developers themselves needing anything extra. | ||
| 75 | * | ||
| 76 | * I have only clipped the parts from the CryptoSwift header files that | ||
| 77 | * are (or seem) relevant to the CryptoSwift support code. This is | ||
| 78 | * simply to keep the file sizes reasonable. | ||
| 79 | * [Geoff] | ||
| 80 | */ | ||
| 81 | #ifdef FLAT_INC | ||
| 82 | #include "cswift.h" | ||
| 83 | #else | ||
| 84 | #include "vendor_defns/cswift.h" | ||
| 85 | #endif | ||
| 86 | |||
| 87 | static int cswift_init(void); | ||
| 88 | static int cswift_finish(void); | ||
| 89 | |||
| 90 | /* BIGNUM stuff */ | ||
| 91 | static int cswift_mod_exp(BIGNUM *r, BIGNUM *a, const BIGNUM *p, | ||
| 92 | const BIGNUM *m, BN_CTX *ctx); | ||
| 93 | static int cswift_mod_exp_crt(BIGNUM *r, BIGNUM *a, const BIGNUM *p, | ||
| 94 | const BIGNUM *q, const BIGNUM *dmp1, const BIGNUM *dmq1, | ||
| 95 | const BIGNUM *iqmp, BN_CTX *ctx); | ||
| 96 | |||
| 97 | /* RSA stuff */ | ||
| 98 | static int cswift_rsa_mod_exp(BIGNUM *r0, BIGNUM *I, RSA *rsa); | ||
| 99 | /* This function is aliased to mod_exp (with the mont stuff dropped). */ | ||
| 100 | static int cswift_mod_exp_mont(BIGNUM *r, BIGNUM *a, const BIGNUM *p, | ||
| 101 | const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); | ||
| 102 | |||
| 103 | /* DSA stuff */ | ||
| 104 | static DSA_SIG *cswift_dsa_sign(const unsigned char *dgst, int dlen, DSA *dsa); | ||
| 105 | static int cswift_dsa_verify(const unsigned char *dgst, int dgst_len, | ||
| 106 | DSA_SIG *sig, DSA *dsa); | ||
| 107 | |||
| 108 | /* DH stuff */ | ||
| 109 | /* This function is alised to mod_exp (with the DH and mont dropped). */ | ||
| 110 | static int cswift_mod_exp_dh(DH *dh, BIGNUM *r, BIGNUM *a, const BIGNUM *p, | ||
| 111 | const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); | ||
| 112 | |||
| 113 | |||
| 114 | /* Our internal RSA_METHOD that we provide pointers to */ | ||
| 115 | static RSA_METHOD cswift_rsa = | ||
| 116 | { | ||
| 117 | "CryptoSwift RSA method", | ||
| 118 | NULL, | ||
| 119 | NULL, | ||
| 120 | NULL, | ||
| 121 | NULL, | ||
| 122 | cswift_rsa_mod_exp, | ||
| 123 | cswift_mod_exp_mont, | ||
| 124 | NULL, | ||
| 125 | NULL, | ||
| 126 | 0, | ||
| 127 | NULL, | ||
| 128 | NULL, | ||
| 129 | NULL | ||
| 130 | }; | ||
| 131 | |||
| 132 | /* Our internal DSA_METHOD that we provide pointers to */ | ||
| 133 | static DSA_METHOD cswift_dsa = | ||
| 134 | { | ||
| 135 | "CryptoSwift DSA method", | ||
| 136 | cswift_dsa_sign, | ||
| 137 | NULL, /* dsa_sign_setup */ | ||
| 138 | cswift_dsa_verify, | ||
| 139 | NULL, /* dsa_mod_exp */ | ||
| 140 | NULL, /* bn_mod_exp */ | ||
| 141 | NULL, /* init */ | ||
| 142 | NULL, /* finish */ | ||
| 143 | 0, /* flags */ | ||
| 144 | NULL /* app_data */ | ||
| 145 | }; | ||
| 146 | |||
| 147 | /* Our internal DH_METHOD that we provide pointers to */ | ||
| 148 | static DH_METHOD cswift_dh = | ||
| 149 | { | ||
| 150 | "CryptoSwift DH method", | ||
| 151 | NULL, | ||
| 152 | NULL, | ||
| 153 | cswift_mod_exp_dh, | ||
| 154 | NULL, | ||
| 155 | NULL, | ||
| 156 | 0, | ||
| 157 | NULL | ||
| 158 | }; | ||
| 159 | |||
| 160 | /* Our ENGINE structure. */ | ||
| 161 | static ENGINE engine_cswift = | ||
| 162 | { | ||
| 163 | "cswift", | ||
| 164 | "CryptoSwift hardware engine support", | ||
| 165 | &cswift_rsa, | ||
| 166 | &cswift_dsa, | ||
| 167 | &cswift_dh, | ||
| 168 | NULL, | ||
| 169 | cswift_mod_exp, | ||
| 170 | cswift_mod_exp_crt, | ||
| 171 | cswift_init, | ||
| 172 | cswift_finish, | ||
| 173 | NULL, /* no ctrl() */ | ||
| 174 | NULL, /* no load_privkey() */ | ||
| 175 | NULL, /* no load_pubkey() */ | ||
| 176 | 0, /* no flags */ | ||
| 177 | 0, 0, /* no references */ | ||
| 178 | NULL, NULL /* unlinked */ | ||
| 179 | }; | ||
| 180 | |||
| 181 | /* As this is only ever called once, there's no need for locking | ||
| 182 | * (indeed - the lock will already be held by our caller!!!) */ | ||
| 183 | ENGINE *ENGINE_cswift() | ||
| 184 | { | ||
| 185 | RSA_METHOD *meth1; | ||
| 186 | DH_METHOD *meth2; | ||
| 187 | |||
| 188 | /* We know that the "PKCS1_SSLeay()" functions hook properly | ||
| 189 | * to the cswift-specific mod_exp and mod_exp_crt so we use | ||
| 190 | * those functions. NB: We don't use ENGINE_openssl() or | ||
| 191 | * anything "more generic" because something like the RSAref | ||
| 192 | * code may not hook properly, and if you own one of these | ||
| 193 | * cards then you have the right to do RSA operations on it | ||
| 194 | * anyway! */ | ||
| 195 | meth1 = RSA_PKCS1_SSLeay(); | ||
| 196 | cswift_rsa.rsa_pub_enc = meth1->rsa_pub_enc; | ||
| 197 | cswift_rsa.rsa_pub_dec = meth1->rsa_pub_dec; | ||
| 198 | cswift_rsa.rsa_priv_enc = meth1->rsa_priv_enc; | ||
| 199 | cswift_rsa.rsa_priv_dec = meth1->rsa_priv_dec; | ||
| 200 | |||
| 201 | /* Much the same for Diffie-Hellman */ | ||
| 202 | meth2 = DH_OpenSSL(); | ||
| 203 | cswift_dh.generate_key = meth2->generate_key; | ||
| 204 | cswift_dh.compute_key = meth2->compute_key; | ||
| 205 | return &engine_cswift; | ||
| 206 | } | ||
| 207 | |||
| 208 | /* This is a process-global DSO handle used for loading and unloading | ||
| 209 | * the CryptoSwift library. NB: This is only set (or unset) during an | ||
| 210 | * init() or finish() call (reference counts permitting) and they're | ||
| 211 | * operating with global locks, so this should be thread-safe | ||
| 212 | * implicitly. */ | ||
| 213 | static DSO *cswift_dso = NULL; | ||
| 214 | |||
| 215 | /* These are the function pointers that are (un)set when the library has | ||
| 216 | * successfully (un)loaded. */ | ||
| 217 | t_swAcquireAccContext *p_CSwift_AcquireAccContext = NULL; | ||
| 218 | t_swAttachKeyParam *p_CSwift_AttachKeyParam = NULL; | ||
| 219 | t_swSimpleRequest *p_CSwift_SimpleRequest = NULL; | ||
| 220 | t_swReleaseAccContext *p_CSwift_ReleaseAccContext = NULL; | ||
| 221 | |||
| 222 | /* Used in the DSO operations. */ | ||
| 223 | static const char *CSWIFT_LIBNAME = "swift"; | ||
| 224 | static const char *CSWIFT_F1 = "swAcquireAccContext"; | ||
| 225 | static const char *CSWIFT_F2 = "swAttachKeyParam"; | ||
| 226 | static const char *CSWIFT_F3 = "swSimpleRequest"; | ||
| 227 | static const char *CSWIFT_F4 = "swReleaseAccContext"; | ||
| 228 | |||
| 229 | |||
| 230 | /* CryptoSwift library functions and mechanics - these are used by the | ||
| 231 | * higher-level functions further down. NB: As and where there's no | ||
| 232 | * error checking, take a look lower down where these functions are | ||
| 233 | * called, the checking and error handling is probably down there. */ | ||
| 234 | |||
| 235 | /* utility function to obtain a context */ | ||
| 236 | static int get_context(SW_CONTEXT_HANDLE *hac) | ||
| 237 | { | ||
| 238 | SW_STATUS status; | ||
| 239 | |||
| 240 | status = p_CSwift_AcquireAccContext(hac); | ||
| 241 | if(status != SW_OK) | ||
| 242 | return 0; | ||
| 243 | return 1; | ||
| 244 | } | ||
| 245 | |||
| 246 | /* similarly to release one. */ | ||
| 247 | static void release_context(SW_CONTEXT_HANDLE hac) | ||
| 248 | { | ||
| 249 | p_CSwift_ReleaseAccContext(hac); | ||
| 250 | } | ||
| 251 | |||
| 252 | /* (de)initialisation functions. */ | ||
| 253 | static int cswift_init() | ||
| 254 | { | ||
| 255 | SW_CONTEXT_HANDLE hac; | ||
| 256 | t_swAcquireAccContext *p1; | ||
| 257 | t_swAttachKeyParam *p2; | ||
| 258 | t_swSimpleRequest *p3; | ||
| 259 | t_swReleaseAccContext *p4; | ||
| 260 | |||
| 261 | if(cswift_dso != NULL) | ||
| 262 | { | ||
| 263 | ENGINEerr(ENGINE_F_CSWIFT_INIT,ENGINE_R_ALREADY_LOADED); | ||
| 264 | goto err; | ||
| 265 | } | ||
| 266 | /* Attempt to load libswift.so/swift.dll/whatever. */ | ||
| 267 | cswift_dso = DSO_load(NULL, CSWIFT_LIBNAME, NULL, | ||
| 268 | DSO_FLAG_NAME_TRANSLATION); | ||
| 269 | if(cswift_dso == NULL) | ||
| 270 | { | ||
| 271 | ENGINEerr(ENGINE_F_CSWIFT_INIT,ENGINE_R_DSO_FAILURE); | ||
| 272 | goto err; | ||
| 273 | } | ||
| 274 | if(!(p1 = (t_swAcquireAccContext *) | ||
| 275 | DSO_bind_func(cswift_dso, CSWIFT_F1)) || | ||
| 276 | !(p2 = (t_swAttachKeyParam *) | ||
| 277 | DSO_bind_func(cswift_dso, CSWIFT_F2)) || | ||
| 278 | !(p3 = (t_swSimpleRequest *) | ||
| 279 | DSO_bind_func(cswift_dso, CSWIFT_F3)) || | ||
| 280 | !(p4 = (t_swReleaseAccContext *) | ||
| 281 | DSO_bind_func(cswift_dso, CSWIFT_F4))) | ||
| 282 | { | ||
| 283 | ENGINEerr(ENGINE_F_CSWIFT_INIT,ENGINE_R_DSO_FAILURE); | ||
| 284 | goto err; | ||
| 285 | } | ||
| 286 | /* Copy the pointers */ | ||
| 287 | p_CSwift_AcquireAccContext = p1; | ||
| 288 | p_CSwift_AttachKeyParam = p2; | ||
| 289 | p_CSwift_SimpleRequest = p3; | ||
| 290 | p_CSwift_ReleaseAccContext = p4; | ||
| 291 | /* Try and get a context - if not, we may have a DSO but no | ||
| 292 | * accelerator! */ | ||
| 293 | if(!get_context(&hac)) | ||
| 294 | { | ||
| 295 | ENGINEerr(ENGINE_F_CSWIFT_INIT,ENGINE_R_UNIT_FAILURE); | ||
| 296 | goto err; | ||
| 297 | } | ||
| 298 | release_context(hac); | ||
| 299 | /* Everything's fine. */ | ||
| 300 | return 1; | ||
| 301 | err: | ||
| 302 | if(cswift_dso) | ||
| 303 | DSO_free(cswift_dso); | ||
| 304 | p_CSwift_AcquireAccContext = NULL; | ||
| 305 | p_CSwift_AttachKeyParam = NULL; | ||
| 306 | p_CSwift_SimpleRequest = NULL; | ||
| 307 | p_CSwift_ReleaseAccContext = NULL; | ||
| 308 | return 0; | ||
| 309 | } | ||
| 310 | |||
| 311 | static int cswift_finish() | ||
| 312 | { | ||
| 313 | if(cswift_dso == NULL) | ||
| 314 | { | ||
| 315 | ENGINEerr(ENGINE_F_CSWIFT_FINISH,ENGINE_R_NOT_LOADED); | ||
| 316 | return 0; | ||
| 317 | } | ||
| 318 | if(!DSO_free(cswift_dso)) | ||
| 319 | { | ||
| 320 | ENGINEerr(ENGINE_F_CSWIFT_FINISH,ENGINE_R_DSO_FAILURE); | ||
| 321 | return 0; | ||
| 322 | } | ||
| 323 | cswift_dso = NULL; | ||
| 324 | p_CSwift_AcquireAccContext = NULL; | ||
| 325 | p_CSwift_AttachKeyParam = NULL; | ||
| 326 | p_CSwift_SimpleRequest = NULL; | ||
| 327 | p_CSwift_ReleaseAccContext = NULL; | ||
| 328 | return 1; | ||
| 329 | } | ||
| 330 | |||
| 331 | /* Un petit mod_exp */ | ||
| 332 | static int cswift_mod_exp(BIGNUM *r, BIGNUM *a, const BIGNUM *p, | ||
| 333 | const BIGNUM *m, BN_CTX *ctx) | ||
| 334 | { | ||
| 335 | /* I need somewhere to store temporary serialised values for | ||
| 336 | * use with the CryptoSwift API calls. A neat cheat - I'll use | ||
| 337 | * BIGNUMs from the BN_CTX but access their arrays directly as | ||
| 338 | * byte arrays <grin>. This way I don't have to clean anything | ||
| 339 | * up. */ | ||
| 340 | BIGNUM *modulus; | ||
| 341 | BIGNUM *exponent; | ||
| 342 | BIGNUM *argument; | ||
| 343 | BIGNUM *result; | ||
| 344 | SW_STATUS sw_status; | ||
| 345 | SW_LARGENUMBER arg, res; | ||
| 346 | SW_PARAM sw_param; | ||
| 347 | SW_CONTEXT_HANDLE hac; | ||
| 348 | int to_return, acquired; | ||
| 349 | |||
| 350 | modulus = exponent = argument = result = NULL; | ||
| 351 | to_return = 0; /* expect failure */ | ||
| 352 | acquired = 0; | ||
| 353 | |||
| 354 | if(!get_context(&hac)) | ||
| 355 | { | ||
| 356 | ENGINEerr(ENGINE_F_CSWIFT_MOD_EXP,ENGINE_R_GET_HANDLE_FAILED); | ||
| 357 | goto err; | ||
| 358 | } | ||
| 359 | acquired = 1; | ||
| 360 | /* Prepare the params */ | ||
| 361 | modulus = BN_CTX_get(ctx); | ||
| 362 | exponent = BN_CTX_get(ctx); | ||
| 363 | argument = BN_CTX_get(ctx); | ||
| 364 | result = BN_CTX_get(ctx); | ||
| 365 | if(!modulus || !exponent || !argument || !result) | ||
| 366 | { | ||
| 367 | ENGINEerr(ENGINE_F_CSWIFT_MOD_EXP,ENGINE_R_BN_CTX_FULL); | ||
| 368 | goto err; | ||
| 369 | } | ||
| 370 | if(!bn_wexpand(modulus, m->top) || !bn_wexpand(exponent, p->top) || | ||
| 371 | !bn_wexpand(argument, a->top) || !bn_wexpand(result, m->top)) | ||
| 372 | { | ||
| 373 | ENGINEerr(ENGINE_F_CSWIFT_MOD_EXP,ENGINE_R_BN_EXPAND_FAIL); | ||
| 374 | goto err; | ||
| 375 | } | ||
| 376 | sw_param.type = SW_ALG_EXP; | ||
| 377 | sw_param.up.exp.modulus.nbytes = BN_bn2bin(m, | ||
| 378 | (unsigned char *)modulus->d); | ||
| 379 | sw_param.up.exp.modulus.value = (unsigned char *)modulus->d; | ||
| 380 | sw_param.up.exp.exponent.nbytes = BN_bn2bin(p, | ||
| 381 | (unsigned char *)exponent->d); | ||
| 382 | sw_param.up.exp.exponent.value = (unsigned char *)exponent->d; | ||
| 383 | /* Attach the key params */ | ||
| 384 | sw_status = p_CSwift_AttachKeyParam(hac, &sw_param); | ||
| 385 | switch(sw_status) | ||
| 386 | { | ||
| 387 | case SW_OK: | ||
| 388 | break; | ||
| 389 | case SW_ERR_INPUT_SIZE: | ||
| 390 | ENGINEerr(ENGINE_F_CSWIFT_MOD_EXP, | ||
| 391 | ENGINE_R_SIZE_TOO_LARGE_OR_TOO_SMALL); | ||
| 392 | goto err; | ||
| 393 | default: | ||
| 394 | { | ||
| 395 | char tmpbuf[20]; | ||
| 396 | ENGINEerr(ENGINE_F_CSWIFT_MOD_EXP,ENGINE_R_REQUEST_FAILED); | ||
| 397 | sprintf(tmpbuf, "%ld", sw_status); | ||
| 398 | ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf); | ||
| 399 | } | ||
| 400 | goto err; | ||
| 401 | } | ||
| 402 | /* Prepare the argument and response */ | ||
| 403 | arg.nbytes = BN_bn2bin(a, (unsigned char *)argument->d); | ||
| 404 | arg.value = (unsigned char *)argument->d; | ||
| 405 | res.nbytes = BN_num_bytes(m); | ||
| 406 | memset(result->d, 0, res.nbytes); | ||
| 407 | res.value = (unsigned char *)result->d; | ||
| 408 | /* Perform the operation */ | ||
| 409 | if((sw_status = p_CSwift_SimpleRequest(hac, SW_CMD_MODEXP, &arg, 1, | ||
| 410 | &res, 1)) != SW_OK) | ||
| 411 | { | ||
| 412 | char tmpbuf[20]; | ||
| 413 | ENGINEerr(ENGINE_F_CSWIFT_MOD_EXP,ENGINE_R_REQUEST_FAILED); | ||
| 414 | sprintf(tmpbuf, "%ld", sw_status); | ||
| 415 | ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf); | ||
| 416 | goto err; | ||
| 417 | } | ||
| 418 | /* Convert the response */ | ||
| 419 | BN_bin2bn((unsigned char *)result->d, res.nbytes, r); | ||
| 420 | to_return = 1; | ||
| 421 | err: | ||
| 422 | if(acquired) | ||
| 423 | release_context(hac); | ||
| 424 | if(modulus) ctx->tos--; | ||
| 425 | if(exponent) ctx->tos--; | ||
| 426 | if(argument) ctx->tos--; | ||
| 427 | if(result) ctx->tos--; | ||
| 428 | return to_return; | ||
| 429 | } | ||
| 430 | |||
| 431 | /* Un petit mod_exp chinois */ | ||
| 432 | static int cswift_mod_exp_crt(BIGNUM *r, BIGNUM *a, const BIGNUM *p, | ||
| 433 | const BIGNUM *q, const BIGNUM *dmp1, | ||
| 434 | const BIGNUM *dmq1, const BIGNUM *iqmp, BN_CTX *ctx) | ||
| 435 | { | ||
| 436 | SW_STATUS sw_status; | ||
| 437 | SW_LARGENUMBER arg, res; | ||
| 438 | SW_PARAM sw_param; | ||
| 439 | SW_CONTEXT_HANDLE hac; | ||
| 440 | BIGNUM *rsa_p = NULL; | ||
| 441 | BIGNUM *rsa_q = NULL; | ||
| 442 | BIGNUM *rsa_dmp1 = NULL; | ||
| 443 | BIGNUM *rsa_dmq1 = NULL; | ||
| 444 | BIGNUM *rsa_iqmp = NULL; | ||
| 445 | BIGNUM *argument = NULL; | ||
| 446 | BIGNUM *result = NULL; | ||
| 447 | int to_return = 0; /* expect failure */ | ||
| 448 | int acquired = 0; | ||
| 449 | |||
| 450 | if(!get_context(&hac)) | ||
| 451 | { | ||
| 452 | ENGINEerr(ENGINE_F_CSWIFT_MOD_EXP_CRT,ENGINE_R_GET_HANDLE_FAILED); | ||
| 453 | goto err; | ||
| 454 | } | ||
| 455 | acquired = 1; | ||
| 456 | /* Prepare the params */ | ||
| 457 | rsa_p = BN_CTX_get(ctx); | ||
| 458 | rsa_q = BN_CTX_get(ctx); | ||
| 459 | rsa_dmp1 = BN_CTX_get(ctx); | ||
| 460 | rsa_dmq1 = BN_CTX_get(ctx); | ||
| 461 | rsa_iqmp = BN_CTX_get(ctx); | ||
| 462 | argument = BN_CTX_get(ctx); | ||
| 463 | result = BN_CTX_get(ctx); | ||
| 464 | if(!rsa_p || !rsa_q || !rsa_dmp1 || !rsa_dmq1 || !rsa_iqmp || | ||
| 465 | !argument || !result) | ||
| 466 | { | ||
| 467 | ENGINEerr(ENGINE_F_CSWIFT_MOD_EXP_CRT,ENGINE_R_BN_CTX_FULL); | ||
| 468 | goto err; | ||
| 469 | } | ||
| 470 | if(!bn_wexpand(rsa_p, p->top) || !bn_wexpand(rsa_q, q->top) || | ||
| 471 | !bn_wexpand(rsa_dmp1, dmp1->top) || | ||
| 472 | !bn_wexpand(rsa_dmq1, dmq1->top) || | ||
| 473 | !bn_wexpand(rsa_iqmp, iqmp->top) || | ||
| 474 | !bn_wexpand(argument, a->top) || | ||
| 475 | !bn_wexpand(result, p->top + q->top)) | ||
| 476 | { | ||
| 477 | ENGINEerr(ENGINE_F_CSWIFT_MOD_EXP_CRT,ENGINE_R_BN_EXPAND_FAIL); | ||
| 478 | goto err; | ||
| 479 | } | ||
| 480 | sw_param.type = SW_ALG_CRT; | ||
| 481 | sw_param.up.crt.p.nbytes = BN_bn2bin(p, (unsigned char *)rsa_p->d); | ||
| 482 | sw_param.up.crt.p.value = (unsigned char *)rsa_p->d; | ||
| 483 | sw_param.up.crt.q.nbytes = BN_bn2bin(q, (unsigned char *)rsa_q->d); | ||
| 484 | sw_param.up.crt.q.value = (unsigned char *)rsa_q->d; | ||
| 485 | sw_param.up.crt.dmp1.nbytes = BN_bn2bin(dmp1, | ||
| 486 | (unsigned char *)rsa_dmp1->d); | ||
| 487 | sw_param.up.crt.dmp1.value = (unsigned char *)rsa_dmp1->d; | ||
| 488 | sw_param.up.crt.dmq1.nbytes = BN_bn2bin(dmq1, | ||
| 489 | (unsigned char *)rsa_dmq1->d); | ||
| 490 | sw_param.up.crt.dmq1.value = (unsigned char *)rsa_dmq1->d; | ||
| 491 | sw_param.up.crt.iqmp.nbytes = BN_bn2bin(iqmp, | ||
| 492 | (unsigned char *)rsa_iqmp->d); | ||
| 493 | sw_param.up.crt.iqmp.value = (unsigned char *)rsa_iqmp->d; | ||
| 494 | /* Attach the key params */ | ||
| 495 | sw_status = p_CSwift_AttachKeyParam(hac, &sw_param); | ||
| 496 | switch(sw_status) | ||
| 497 | { | ||
| 498 | case SW_OK: | ||
| 499 | break; | ||
| 500 | case SW_ERR_INPUT_SIZE: | ||
| 501 | ENGINEerr(ENGINE_F_CSWIFT_MOD_EXP_CRT, | ||
| 502 | ENGINE_R_SIZE_TOO_LARGE_OR_TOO_SMALL); | ||
| 503 | goto err; | ||
| 504 | default: | ||
| 505 | { | ||
| 506 | char tmpbuf[20]; | ||
| 507 | ENGINEerr(ENGINE_F_CSWIFT_MOD_EXP_CRT,ENGINE_R_REQUEST_FAILED); | ||
| 508 | sprintf(tmpbuf, "%ld", sw_status); | ||
| 509 | ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf); | ||
| 510 | } | ||
| 511 | goto err; | ||
| 512 | } | ||
| 513 | /* Prepare the argument and response */ | ||
| 514 | arg.nbytes = BN_bn2bin(a, (unsigned char *)argument->d); | ||
| 515 | arg.value = (unsigned char *)argument->d; | ||
| 516 | res.nbytes = 2 * BN_num_bytes(p); | ||
| 517 | memset(result->d, 0, res.nbytes); | ||
| 518 | res.value = (unsigned char *)result->d; | ||
| 519 | /* Perform the operation */ | ||
| 520 | if((sw_status = p_CSwift_SimpleRequest(hac, SW_CMD_MODEXP_CRT, &arg, 1, | ||
| 521 | &res, 1)) != SW_OK) | ||
| 522 | { | ||
| 523 | char tmpbuf[20]; | ||
| 524 | ENGINEerr(ENGINE_F_CSWIFT_MOD_EXP_CRT,ENGINE_R_REQUEST_FAILED); | ||
| 525 | sprintf(tmpbuf, "%ld", sw_status); | ||
| 526 | ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf); | ||
| 527 | goto err; | ||
| 528 | } | ||
| 529 | /* Convert the response */ | ||
| 530 | BN_bin2bn((unsigned char *)result->d, res.nbytes, r); | ||
| 531 | to_return = 1; | ||
| 532 | err: | ||
| 533 | if(acquired) | ||
| 534 | release_context(hac); | ||
| 535 | if(rsa_p) ctx->tos--; | ||
| 536 | if(rsa_q) ctx->tos--; | ||
| 537 | if(rsa_dmp1) ctx->tos--; | ||
| 538 | if(rsa_dmq1) ctx->tos--; | ||
| 539 | if(rsa_iqmp) ctx->tos--; | ||
| 540 | if(argument) ctx->tos--; | ||
| 541 | if(result) ctx->tos--; | ||
| 542 | return to_return; | ||
| 543 | } | ||
| 544 | |||
| 545 | static int cswift_rsa_mod_exp(BIGNUM *r0, BIGNUM *I, RSA *rsa) | ||
| 546 | { | ||
| 547 | BN_CTX *ctx; | ||
| 548 | int to_return = 0; | ||
| 549 | |||
| 550 | if((ctx = BN_CTX_new()) == NULL) | ||
| 551 | goto err; | ||
| 552 | if(!rsa->p || !rsa->q || !rsa->dmp1 || !rsa->dmq1 || !rsa->iqmp) | ||
| 553 | { | ||
| 554 | ENGINEerr(ENGINE_F_CSWIFT_RSA_MOD_EXP,ENGINE_R_MISSING_KEY_COMPONENTS); | ||
| 555 | goto err; | ||
| 556 | } | ||
| 557 | to_return = cswift_mod_exp_crt(r0, I, rsa->p, rsa->q, rsa->dmp1, | ||
| 558 | rsa->dmq1, rsa->iqmp, ctx); | ||
| 559 | err: | ||
| 560 | if(ctx) | ||
| 561 | BN_CTX_free(ctx); | ||
| 562 | return to_return; | ||
| 563 | } | ||
| 564 | |||
| 565 | /* This function is aliased to mod_exp (with the mont stuff dropped). */ | ||
| 566 | static int cswift_mod_exp_mont(BIGNUM *r, BIGNUM *a, const BIGNUM *p, | ||
| 567 | const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx) | ||
| 568 | { | ||
| 569 | return cswift_mod_exp(r, a, p, m, ctx); | ||
| 570 | } | ||
| 571 | |||
| 572 | static DSA_SIG *cswift_dsa_sign(const unsigned char *dgst, int dlen, DSA *dsa) | ||
| 573 | { | ||
| 574 | SW_CONTEXT_HANDLE hac; | ||
| 575 | SW_PARAM sw_param; | ||
| 576 | SW_STATUS sw_status; | ||
| 577 | SW_LARGENUMBER arg, res; | ||
| 578 | unsigned char *ptr; | ||
| 579 | BN_CTX *ctx; | ||
| 580 | BIGNUM *dsa_p = NULL; | ||
| 581 | BIGNUM *dsa_q = NULL; | ||
| 582 | BIGNUM *dsa_g = NULL; | ||
| 583 | BIGNUM *dsa_key = NULL; | ||
| 584 | BIGNUM *result = NULL; | ||
| 585 | DSA_SIG *to_return = NULL; | ||
| 586 | int acquired = 0; | ||
| 587 | |||
| 588 | if((ctx = BN_CTX_new()) == NULL) | ||
| 589 | goto err; | ||
| 590 | if(!get_context(&hac)) | ||
| 591 | { | ||
| 592 | ENGINEerr(ENGINE_F_CSWIFT_DSA_SIGN,ENGINE_R_GET_HANDLE_FAILED); | ||
| 593 | goto err; | ||
| 594 | } | ||
| 595 | acquired = 1; | ||
| 596 | /* Prepare the params */ | ||
| 597 | dsa_p = BN_CTX_get(ctx); | ||
| 598 | dsa_q = BN_CTX_get(ctx); | ||
| 599 | dsa_g = BN_CTX_get(ctx); | ||
| 600 | dsa_key = BN_CTX_get(ctx); | ||
| 601 | result = BN_CTX_get(ctx); | ||
| 602 | if(!dsa_p || !dsa_q || !dsa_g || !dsa_key || !result) | ||
| 603 | { | ||
| 604 | ENGINEerr(ENGINE_F_CSWIFT_DSA_SIGN,ENGINE_R_BN_CTX_FULL); | ||
| 605 | goto err; | ||
| 606 | } | ||
| 607 | if(!bn_wexpand(dsa_p, dsa->p->top) || | ||
| 608 | !bn_wexpand(dsa_q, dsa->q->top) || | ||
| 609 | !bn_wexpand(dsa_g, dsa->g->top) || | ||
| 610 | !bn_wexpand(dsa_key, dsa->priv_key->top) || | ||
| 611 | !bn_wexpand(result, dsa->p->top)) | ||
| 612 | { | ||
| 613 | ENGINEerr(ENGINE_F_CSWIFT_DSA_SIGN,ENGINE_R_BN_EXPAND_FAIL); | ||
| 614 | goto err; | ||
| 615 | } | ||
| 616 | sw_param.type = SW_ALG_DSA; | ||
| 617 | sw_param.up.dsa.p.nbytes = BN_bn2bin(dsa->p, | ||
| 618 | (unsigned char *)dsa_p->d); | ||
| 619 | sw_param.up.dsa.p.value = (unsigned char *)dsa_p->d; | ||
| 620 | sw_param.up.dsa.q.nbytes = BN_bn2bin(dsa->q, | ||
| 621 | (unsigned char *)dsa_q->d); | ||
| 622 | sw_param.up.dsa.q.value = (unsigned char *)dsa_q->d; | ||
| 623 | sw_param.up.dsa.g.nbytes = BN_bn2bin(dsa->g, | ||
| 624 | (unsigned char *)dsa_g->d); | ||
| 625 | sw_param.up.dsa.g.value = (unsigned char *)dsa_g->d; | ||
| 626 | sw_param.up.dsa.key.nbytes = BN_bn2bin(dsa->priv_key, | ||
| 627 | (unsigned char *)dsa_key->d); | ||
| 628 | sw_param.up.dsa.key.value = (unsigned char *)dsa_key->d; | ||
| 629 | /* Attach the key params */ | ||
| 630 | sw_status = p_CSwift_AttachKeyParam(hac, &sw_param); | ||
| 631 | switch(sw_status) | ||
| 632 | { | ||
| 633 | case SW_OK: | ||
| 634 | break; | ||
| 635 | case SW_ERR_INPUT_SIZE: | ||
| 636 | ENGINEerr(ENGINE_F_CSWIFT_DSA_SIGN, | ||
| 637 | ENGINE_R_SIZE_TOO_LARGE_OR_TOO_SMALL); | ||
| 638 | goto err; | ||
| 639 | default: | ||
| 640 | { | ||
| 641 | char tmpbuf[20]; | ||
| 642 | ENGINEerr(ENGINE_F_CSWIFT_DSA_SIGN,ENGINE_R_REQUEST_FAILED); | ||
| 643 | sprintf(tmpbuf, "%ld", sw_status); | ||
| 644 | ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf); | ||
| 645 | } | ||
| 646 | goto err; | ||
| 647 | } | ||
| 648 | /* Prepare the argument and response */ | ||
| 649 | arg.nbytes = dlen; | ||
| 650 | arg.value = (unsigned char *)dgst; | ||
| 651 | res.nbytes = BN_num_bytes(dsa->p); | ||
| 652 | memset(result->d, 0, res.nbytes); | ||
| 653 | res.value = (unsigned char *)result->d; | ||
| 654 | /* Perform the operation */ | ||
| 655 | sw_status = p_CSwift_SimpleRequest(hac, SW_CMD_DSS_SIGN, &arg, 1, | ||
| 656 | &res, 1); | ||
| 657 | if(sw_status != SW_OK) | ||
| 658 | { | ||
| 659 | char tmpbuf[20]; | ||
| 660 | ENGINEerr(ENGINE_F_CSWIFT_DSA_SIGN,ENGINE_R_REQUEST_FAILED); | ||
| 661 | sprintf(tmpbuf, "%ld", sw_status); | ||
| 662 | ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf); | ||
| 663 | goto err; | ||
| 664 | } | ||
| 665 | /* Convert the response */ | ||
| 666 | ptr = (unsigned char *)result->d; | ||
| 667 | if((to_return = DSA_SIG_new()) == NULL) | ||
| 668 | goto err; | ||
| 669 | to_return->r = BN_bin2bn((unsigned char *)result->d, 20, NULL); | ||
| 670 | to_return->s = BN_bin2bn((unsigned char *)result->d + 20, 20, NULL); | ||
| 671 | |||
| 672 | err: | ||
| 673 | if(acquired) | ||
| 674 | release_context(hac); | ||
| 675 | if(dsa_p) ctx->tos--; | ||
| 676 | if(dsa_q) ctx->tos--; | ||
| 677 | if(dsa_g) ctx->tos--; | ||
| 678 | if(dsa_key) ctx->tos--; | ||
| 679 | if(result) ctx->tos--; | ||
| 680 | if(ctx) | ||
| 681 | BN_CTX_free(ctx); | ||
| 682 | return to_return; | ||
| 683 | } | ||
| 684 | |||
| 685 | static int cswift_dsa_verify(const unsigned char *dgst, int dgst_len, | ||
| 686 | DSA_SIG *sig, DSA *dsa) | ||
| 687 | { | ||
| 688 | SW_CONTEXT_HANDLE hac; | ||
| 689 | SW_PARAM sw_param; | ||
| 690 | SW_STATUS sw_status; | ||
| 691 | SW_LARGENUMBER arg[2], res; | ||
| 692 | unsigned long sig_result; | ||
| 693 | BN_CTX *ctx; | ||
| 694 | BIGNUM *dsa_p = NULL; | ||
| 695 | BIGNUM *dsa_q = NULL; | ||
| 696 | BIGNUM *dsa_g = NULL; | ||
| 697 | BIGNUM *dsa_key = NULL; | ||
| 698 | BIGNUM *argument = NULL; | ||
| 699 | int to_return = -1; | ||
| 700 | int acquired = 0; | ||
| 701 | |||
| 702 | if((ctx = BN_CTX_new()) == NULL) | ||
| 703 | goto err; | ||
| 704 | if(!get_context(&hac)) | ||
| 705 | { | ||
| 706 | ENGINEerr(ENGINE_F_CSWIFT_DSA_VERIFY,ENGINE_R_GET_HANDLE_FAILED); | ||
| 707 | goto err; | ||
| 708 | } | ||
| 709 | acquired = 1; | ||
| 710 | /* Prepare the params */ | ||
| 711 | dsa_p = BN_CTX_get(ctx); | ||
| 712 | dsa_q = BN_CTX_get(ctx); | ||
| 713 | dsa_g = BN_CTX_get(ctx); | ||
| 714 | dsa_key = BN_CTX_get(ctx); | ||
| 715 | argument = BN_CTX_get(ctx); | ||
| 716 | if(!dsa_p || !dsa_q || !dsa_g || !dsa_key || !argument) | ||
| 717 | { | ||
| 718 | ENGINEerr(ENGINE_F_CSWIFT_DSA_VERIFY,ENGINE_R_BN_CTX_FULL); | ||
| 719 | goto err; | ||
| 720 | } | ||
| 721 | if(!bn_wexpand(dsa_p, dsa->p->top) || | ||
| 722 | !bn_wexpand(dsa_q, dsa->q->top) || | ||
| 723 | !bn_wexpand(dsa_g, dsa->g->top) || | ||
| 724 | !bn_wexpand(dsa_key, dsa->pub_key->top) || | ||
| 725 | !bn_wexpand(argument, 40)) | ||
| 726 | { | ||
| 727 | ENGINEerr(ENGINE_F_CSWIFT_DSA_VERIFY,ENGINE_R_BN_EXPAND_FAIL); | ||
| 728 | goto err; | ||
| 729 | } | ||
| 730 | sw_param.type = SW_ALG_DSA; | ||
| 731 | sw_param.up.dsa.p.nbytes = BN_bn2bin(dsa->p, | ||
| 732 | (unsigned char *)dsa_p->d); | ||
| 733 | sw_param.up.dsa.p.value = (unsigned char *)dsa_p->d; | ||
| 734 | sw_param.up.dsa.q.nbytes = BN_bn2bin(dsa->q, | ||
| 735 | (unsigned char *)dsa_q->d); | ||
| 736 | sw_param.up.dsa.q.value = (unsigned char *)dsa_q->d; | ||
| 737 | sw_param.up.dsa.g.nbytes = BN_bn2bin(dsa->g, | ||
| 738 | (unsigned char *)dsa_g->d); | ||
| 739 | sw_param.up.dsa.g.value = (unsigned char *)dsa_g->d; | ||
| 740 | sw_param.up.dsa.key.nbytes = BN_bn2bin(dsa->pub_key, | ||
| 741 | (unsigned char *)dsa_key->d); | ||
| 742 | sw_param.up.dsa.key.value = (unsigned char *)dsa_key->d; | ||
| 743 | /* Attach the key params */ | ||
| 744 | sw_status = p_CSwift_AttachKeyParam(hac, &sw_param); | ||
| 745 | switch(sw_status) | ||
| 746 | { | ||
| 747 | case SW_OK: | ||
| 748 | break; | ||
| 749 | case SW_ERR_INPUT_SIZE: | ||
| 750 | ENGINEerr(ENGINE_F_CSWIFT_DSA_VERIFY, | ||
| 751 | ENGINE_R_SIZE_TOO_LARGE_OR_TOO_SMALL); | ||
| 752 | goto err; | ||
| 753 | default: | ||
| 754 | { | ||
| 755 | char tmpbuf[20]; | ||
| 756 | ENGINEerr(ENGINE_F_CSWIFT_DSA_VERIFY,ENGINE_R_REQUEST_FAILED); | ||
| 757 | sprintf(tmpbuf, "%ld", sw_status); | ||
| 758 | ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf); | ||
| 759 | } | ||
| 760 | goto err; | ||
| 761 | } | ||
| 762 | /* Prepare the argument and response */ | ||
| 763 | arg[0].nbytes = dgst_len; | ||
| 764 | arg[0].value = (unsigned char *)dgst; | ||
| 765 | arg[1].nbytes = 40; | ||
| 766 | arg[1].value = (unsigned char *)argument->d; | ||
| 767 | memset(arg[1].value, 0, 40); | ||
| 768 | BN_bn2bin(sig->r, arg[1].value + 20 - BN_num_bytes(sig->r)); | ||
| 769 | BN_bn2bin(sig->s, arg[1].value + 40 - BN_num_bytes(sig->s)); | ||
| 770 | res.nbytes = 4; /* unsigned long */ | ||
| 771 | res.value = (unsigned char *)(&sig_result); | ||
| 772 | /* Perform the operation */ | ||
| 773 | sw_status = p_CSwift_SimpleRequest(hac, SW_CMD_DSS_VERIFY, arg, 2, | ||
| 774 | &res, 1); | ||
| 775 | if(sw_status != SW_OK) | ||
| 776 | { | ||
| 777 | char tmpbuf[20]; | ||
| 778 | ENGINEerr(ENGINE_F_CSWIFT_DSA_VERIFY,ENGINE_R_REQUEST_FAILED); | ||
| 779 | sprintf(tmpbuf, "%ld", sw_status); | ||
| 780 | ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf); | ||
| 781 | goto err; | ||
| 782 | } | ||
| 783 | /* Convert the response */ | ||
| 784 | to_return = ((sig_result == 0) ? 0 : 1); | ||
| 785 | |||
| 786 | err: | ||
| 787 | if(acquired) | ||
| 788 | release_context(hac); | ||
| 789 | if(dsa_p) ctx->tos--; | ||
| 790 | if(dsa_q) ctx->tos--; | ||
| 791 | if(dsa_g) ctx->tos--; | ||
| 792 | if(dsa_key) ctx->tos--; | ||
| 793 | if(argument) ctx->tos--; | ||
| 794 | if(ctx) | ||
| 795 | BN_CTX_free(ctx); | ||
| 796 | return to_return; | ||
| 797 | } | ||
| 798 | |||
| 799 | /* This function is aliased to mod_exp (with the dh and mont dropped). */ | ||
| 800 | static int cswift_mod_exp_dh(DH *dh, BIGNUM *r, BIGNUM *a, const BIGNUM *p, | ||
| 801 | const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx) | ||
| 802 | { | ||
| 803 | return cswift_mod_exp(r, a, p, m, ctx); | ||
| 804 | } | ||
| 805 | |||
| 806 | #endif /* !NO_HW_CSWIFT */ | ||
| 807 | #endif /* !NO_HW */ | ||
diff --git a/src/lib/libcrypto/engine/hw_ncipher.c b/src/lib/libcrypto/engine/hw_ncipher.c new file mode 100644 index 0000000000..41f5900676 --- /dev/null +++ b/src/lib/libcrypto/engine/hw_ncipher.c | |||
| @@ -0,0 +1,1019 @@ | |||
| 1 | /* crypto/engine/hw_ncipher.c -*- mode: C; c-file-style: "eay" -*- */ | ||
| 2 | /* Written by Richard Levitte (richard@levitte.org), Geoff Thorpe | ||
| 3 | * (geoff@geoffthorpe.net) and Dr Stephen N Henson (shenson@bigfoot.com) | ||
| 4 | * for the OpenSSL project 2000. | ||
| 5 | */ | ||
| 6 | /* ==================================================================== | ||
| 7 | * Copyright (c) 1999 The OpenSSL Project. All rights reserved. | ||
| 8 | * | ||
| 9 | * Redistribution and use in source and binary forms, with or without | ||
| 10 | * modification, are permitted provided that the following conditions | ||
| 11 | * are met: | ||
| 12 | * | ||
| 13 | * 1. Redistributions of source code must retain the above copyright | ||
| 14 | * notice, this list of conditions and the following disclaimer. | ||
| 15 | * | ||
| 16 | * 2. Redistributions in binary form must reproduce the above copyright | ||
| 17 | * notice, this list of conditions and the following disclaimer in | ||
| 18 | * the documentation and/or other materials provided with the | ||
| 19 | * distribution. | ||
| 20 | * | ||
| 21 | * 3. All advertising materials mentioning features or use of this | ||
| 22 | * software must display the following acknowledgment: | ||
| 23 | * "This product includes software developed by the OpenSSL Project | ||
| 24 | * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" | ||
| 25 | * | ||
| 26 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | ||
| 27 | * endorse or promote products derived from this software without | ||
| 28 | * prior written permission. For written permission, please contact | ||
| 29 | * licensing@OpenSSL.org. | ||
| 30 | * | ||
| 31 | * 5. Products derived from this software may not be called "OpenSSL" | ||
| 32 | * nor may "OpenSSL" appear in their names without prior written | ||
| 33 | * permission of the OpenSSL Project. | ||
| 34 | * | ||
| 35 | * 6. Redistributions of any form whatsoever must retain the following | ||
| 36 | * acknowledgment: | ||
| 37 | * "This product includes software developed by the OpenSSL Project | ||
| 38 | * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" | ||
| 39 | * | ||
| 40 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | ||
| 41 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
| 42 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
| 43 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | ||
| 44 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
| 45 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
| 46 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
| 47 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| 48 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
| 49 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
| 50 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | ||
| 51 | * OF THE POSSIBILITY OF SUCH DAMAGE. | ||
| 52 | * ==================================================================== | ||
| 53 | * | ||
| 54 | * This product includes cryptographic software written by Eric Young | ||
| 55 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
| 56 | * Hudson (tjh@cryptsoft.com). | ||
| 57 | * | ||
| 58 | */ | ||
| 59 | |||
| 60 | #include <stdio.h> | ||
| 61 | #include <openssl/crypto.h> | ||
| 62 | #include <openssl/pem.h> | ||
| 63 | #include "cryptlib.h" | ||
| 64 | #include <openssl/dso.h> | ||
| 65 | #include "engine_int.h" | ||
| 66 | #include <openssl/engine.h> | ||
| 67 | |||
| 68 | #ifndef NO_HW | ||
| 69 | #ifndef NO_HW_NCIPHER | ||
| 70 | |||
| 71 | /* Attribution notice: nCipher have said several times that it's OK for | ||
| 72 | * us to implement a general interface to their boxes, and recently declared | ||
| 73 | * their HWCryptoHook to be public, and therefore available for us to use. | ||
| 74 | * Thanks, nCipher. | ||
| 75 | * | ||
| 76 | * The hwcryptohook.h included here is from May 2000. | ||
| 77 | * [Richard Levitte] | ||
| 78 | */ | ||
| 79 | #ifdef FLAT_INC | ||
| 80 | #include "hwcryptohook.h" | ||
| 81 | #else | ||
| 82 | #include "vendor_defns/hwcryptohook.h" | ||
| 83 | #endif | ||
| 84 | |||
| 85 | static int hwcrhk_init(void); | ||
| 86 | static int hwcrhk_finish(void); | ||
| 87 | static int hwcrhk_ctrl(int cmd, long i, void *p, void (*f)()); | ||
| 88 | |||
| 89 | /* Functions to handle mutexes */ | ||
| 90 | static int hwcrhk_mutex_init(HWCryptoHook_Mutex*, HWCryptoHook_CallerContext*); | ||
| 91 | static int hwcrhk_mutex_lock(HWCryptoHook_Mutex*); | ||
| 92 | static void hwcrhk_mutex_unlock(HWCryptoHook_Mutex*); | ||
| 93 | static void hwcrhk_mutex_destroy(HWCryptoHook_Mutex*); | ||
| 94 | |||
| 95 | /* BIGNUM stuff */ | ||
| 96 | static int hwcrhk_mod_exp(BIGNUM *r, BIGNUM *a, const BIGNUM *p, | ||
| 97 | const BIGNUM *m, BN_CTX *ctx); | ||
| 98 | |||
| 99 | /* RSA stuff */ | ||
| 100 | static int hwcrhk_rsa_mod_exp(BIGNUM *r, BIGNUM *I, RSA *rsa); | ||
| 101 | /* This function is aliased to mod_exp (with the mont stuff dropped). */ | ||
| 102 | static int hwcrhk_mod_exp_mont(BIGNUM *r, BIGNUM *a, const BIGNUM *p, | ||
| 103 | const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); | ||
| 104 | |||
| 105 | /* DH stuff */ | ||
| 106 | /* This function is alised to mod_exp (with the DH and mont dropped). */ | ||
| 107 | static int hwcrhk_mod_exp_dh(DH *dh, BIGNUM *r, BIGNUM *a, const BIGNUM *p, | ||
| 108 | const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); | ||
| 109 | |||
| 110 | /* RAND stuff */ | ||
| 111 | static int hwcrhk_rand_bytes(unsigned char *buf, int num); | ||
| 112 | static int hwcrhk_rand_status(void); | ||
| 113 | |||
| 114 | /* KM stuff */ | ||
| 115 | static EVP_PKEY *hwcrhk_load_privkey(const char *key_id, | ||
| 116 | const char *passphrase); | ||
| 117 | static EVP_PKEY *hwcrhk_load_pubkey(const char *key_id, | ||
| 118 | const char *passphrase); | ||
| 119 | static void hwcrhk_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad, | ||
| 120 | int index,long argl, void *argp); | ||
| 121 | |||
| 122 | /* Interaction stuff */ | ||
| 123 | static int hwcrhk_get_pass(const char *prompt_info, | ||
| 124 | int *len_io, char *buf, | ||
| 125 | HWCryptoHook_PassphraseContext *ppctx, | ||
| 126 | HWCryptoHook_CallerContext *cactx); | ||
| 127 | static void hwcrhk_log_message(void *logstream, const char *message); | ||
| 128 | |||
| 129 | /* Our internal RSA_METHOD that we provide pointers to */ | ||
| 130 | static RSA_METHOD hwcrhk_rsa = | ||
| 131 | { | ||
| 132 | "nCipher RSA method", | ||
| 133 | NULL, | ||
| 134 | NULL, | ||
| 135 | NULL, | ||
| 136 | NULL, | ||
| 137 | hwcrhk_rsa_mod_exp, | ||
| 138 | hwcrhk_mod_exp_mont, | ||
| 139 | NULL, | ||
| 140 | NULL, | ||
| 141 | 0, | ||
| 142 | NULL, | ||
| 143 | NULL, | ||
| 144 | NULL | ||
| 145 | }; | ||
| 146 | |||
| 147 | /* Our internal DH_METHOD that we provide pointers to */ | ||
| 148 | static DH_METHOD hwcrhk_dh = | ||
| 149 | { | ||
| 150 | "nCipher DH method", | ||
| 151 | NULL, | ||
| 152 | NULL, | ||
| 153 | hwcrhk_mod_exp_dh, | ||
| 154 | NULL, | ||
| 155 | NULL, | ||
| 156 | 0, | ||
| 157 | NULL | ||
| 158 | }; | ||
| 159 | |||
| 160 | static RAND_METHOD hwcrhk_rand = | ||
| 161 | { | ||
| 162 | /* "nCipher RAND method", */ | ||
| 163 | NULL, | ||
| 164 | hwcrhk_rand_bytes, | ||
| 165 | NULL, | ||
| 166 | NULL, | ||
| 167 | hwcrhk_rand_bytes, | ||
| 168 | hwcrhk_rand_status, | ||
| 169 | }; | ||
| 170 | |||
| 171 | /* Our ENGINE structure. */ | ||
| 172 | static ENGINE engine_hwcrhk = | ||
| 173 | { | ||
| 174 | "chil", | ||
| 175 | "nCipher hardware engine support", | ||
| 176 | &hwcrhk_rsa, | ||
| 177 | NULL, | ||
| 178 | &hwcrhk_dh, | ||
| 179 | &hwcrhk_rand, | ||
| 180 | hwcrhk_mod_exp, | ||
| 181 | NULL, | ||
| 182 | hwcrhk_init, | ||
| 183 | hwcrhk_finish, | ||
| 184 | hwcrhk_ctrl, | ||
| 185 | hwcrhk_load_privkey, | ||
| 186 | hwcrhk_load_pubkey, | ||
| 187 | 0, /* no flags */ | ||
| 188 | 0, 0, /* no references */ | ||
| 189 | NULL, NULL /* unlinked */ | ||
| 190 | }; | ||
| 191 | |||
| 192 | /* Internal stuff for HWCryptoHook */ | ||
| 193 | |||
| 194 | /* Some structures needed for proper use of thread locks */ | ||
| 195 | /* hwcryptohook.h has some typedefs that turn struct HWCryptoHook_MutexValue | ||
| 196 | into HWCryptoHook_Mutex */ | ||
| 197 | struct HWCryptoHook_MutexValue | ||
| 198 | { | ||
| 199 | int lockid; | ||
| 200 | }; | ||
| 201 | |||
| 202 | /* hwcryptohook.h has some typedefs that turn | ||
| 203 | struct HWCryptoHook_PassphraseContextValue | ||
| 204 | into HWCryptoHook_PassphraseContext */ | ||
| 205 | struct HWCryptoHook_PassphraseContextValue | ||
| 206 | { | ||
| 207 | void *any; | ||
| 208 | }; | ||
| 209 | |||
| 210 | /* hwcryptohook.h has some typedefs that turn | ||
| 211 | struct HWCryptoHook_CallerContextValue | ||
| 212 | into HWCryptoHook_CallerContext */ | ||
| 213 | struct HWCryptoHook_CallerContextValue | ||
| 214 | { | ||
| 215 | void *any; | ||
| 216 | }; | ||
| 217 | |||
| 218 | /* The MPI structure in HWCryptoHook is pretty compatible with OpenSSL | ||
| 219 | BIGNUM's, so lets define a couple of conversion macros */ | ||
| 220 | #define BN2MPI(mp, bn) \ | ||
| 221 | {mp.size = bn->top * sizeof(BN_ULONG); mp.buf = (unsigned char *)bn->d;} | ||
| 222 | #define MPI2BN(bn, mp) \ | ||
| 223 | {mp.size = bn->dmax * sizeof(BN_ULONG); mp.buf = (unsigned char *)bn->d;} | ||
| 224 | |||
| 225 | #if 0 /* Card and password management is not yet supported */ | ||
| 226 | /* HWCryptoHook callbacks. insert_card() and get_pass() are not yet | ||
| 227 | defined, because we haven't quite decided on the proper form yet. | ||
| 228 | log_message() just adds an entry in the error stack. I don't know | ||
| 229 | if that's good or bad... */ | ||
| 230 | static int insert_card(const char *prompt_info, | ||
| 231 | const char *wrong_info, | ||
| 232 | HWCryptoHook_PassphraseContext *ppctx, | ||
| 233 | HWCryptoHook_CallerContext *cactx); | ||
| 234 | static int get_pass(const char *prompt_info, | ||
| 235 | int *len_io, char *buf, | ||
| 236 | HWCryptoHook_PassphraseContext *ppctx, | ||
| 237 | HWCryptoHook_CallerContext *cactx); | ||
| 238 | #endif | ||
| 239 | |||
| 240 | static BIO *logstream = NULL; | ||
| 241 | static pem_password_cb *password_callback = NULL; | ||
| 242 | #if 0 | ||
| 243 | static void *password_callback_userdata = NULL; | ||
| 244 | #endif | ||
| 245 | static int disable_mutex_callbacks = 0; | ||
| 246 | |||
| 247 | /* Stuff to pass to the HWCryptoHook library */ | ||
| 248 | static HWCryptoHook_InitInfo hwcrhk_globals = { | ||
| 249 | 0, /* Flags */ | ||
| 250 | &logstream, /* logstream */ | ||
| 251 | sizeof(BN_ULONG), /* limbsize */ | ||
| 252 | 0, /* mslimb first: false for BNs */ | ||
| 253 | -1, /* msbyte first: use native */ | ||
| 254 | 0, /* Max mutexes, 0 = no small limit */ | ||
| 255 | 0, /* Max simultaneous, 0 = default */ | ||
| 256 | |||
| 257 | /* The next few are mutex stuff: we write wrapper functions | ||
| 258 | around the OS mutex functions. We initialise them to 0 | ||
| 259 | here, and change that to actual function pointers in hwcrhk_init() | ||
| 260 | if dynamic locks are supported (that is, if the application | ||
| 261 | programmer has made sure of setting up callbacks bafore starting | ||
| 262 | this engine) *and* if disable_mutex_callbacks hasn't been set by | ||
| 263 | a call to ENGINE_ctrl(ENGINE_CTRL_CHIL_NO_LOCKING). */ | ||
| 264 | sizeof(HWCryptoHook_Mutex), | ||
| 265 | 0, | ||
| 266 | 0, | ||
| 267 | 0, | ||
| 268 | 0, | ||
| 269 | |||
| 270 | /* The next few are condvar stuff: we write wrapper functions | ||
| 271 | round the OS functions. Currently not implemented and not | ||
| 272 | and absolute necessity even in threaded programs, therefore | ||
| 273 | 0'ed. Will hopefully be implemented some day, since it | ||
| 274 | enhances the efficiency of HWCryptoHook. */ | ||
| 275 | 0, /* sizeof(HWCryptoHook_CondVar), */ | ||
| 276 | 0, /* hwcrhk_cv_init, */ | ||
| 277 | 0, /* hwcrhk_cv_wait, */ | ||
| 278 | 0, /* hwcrhk_cv_signal, */ | ||
| 279 | 0, /* hwcrhk_cv_broadcast, */ | ||
| 280 | 0, /* hwcrhk_cv_destroy, */ | ||
| 281 | |||
| 282 | hwcrhk_get_pass, /* pass phrase */ | ||
| 283 | 0, /* insert_card, */ /* insert a card */ | ||
| 284 | hwcrhk_log_message /* Log message */ | ||
| 285 | }; | ||
| 286 | |||
| 287 | |||
| 288 | /* Now, to our own code */ | ||
| 289 | |||
| 290 | /* As this is only ever called once, there's no need for locking | ||
| 291 | * (indeed - the lock will already be held by our caller!!!) */ | ||
| 292 | ENGINE *ENGINE_ncipher() | ||
| 293 | { | ||
| 294 | RSA_METHOD *meth1; | ||
| 295 | DH_METHOD *meth2; | ||
| 296 | |||
| 297 | /* We know that the "PKCS1_SSLeay()" functions hook properly | ||
| 298 | * to the cswift-specific mod_exp and mod_exp_crt so we use | ||
| 299 | * those functions. NB: We don't use ENGINE_openssl() or | ||
| 300 | * anything "more generic" because something like the RSAref | ||
| 301 | * code may not hook properly, and if you own one of these | ||
| 302 | * cards then you have the right to do RSA operations on it | ||
| 303 | * anyway! */ | ||
| 304 | meth1 = RSA_PKCS1_SSLeay(); | ||
| 305 | hwcrhk_rsa.rsa_pub_enc = meth1->rsa_pub_enc; | ||
| 306 | hwcrhk_rsa.rsa_pub_dec = meth1->rsa_pub_dec; | ||
| 307 | hwcrhk_rsa.rsa_priv_enc = meth1->rsa_priv_enc; | ||
| 308 | hwcrhk_rsa.rsa_priv_dec = meth1->rsa_priv_dec; | ||
| 309 | |||
| 310 | /* Much the same for Diffie-Hellman */ | ||
| 311 | meth2 = DH_OpenSSL(); | ||
| 312 | hwcrhk_dh.generate_key = meth2->generate_key; | ||
| 313 | hwcrhk_dh.compute_key = meth2->compute_key; | ||
| 314 | return &engine_hwcrhk; | ||
| 315 | } | ||
| 316 | |||
| 317 | /* This is a process-global DSO handle used for loading and unloading | ||
| 318 | * the HWCryptoHook library. NB: This is only set (or unset) during an | ||
| 319 | * init() or finish() call (reference counts permitting) and they're | ||
| 320 | * operating with global locks, so this should be thread-safe | ||
| 321 | * implicitly. */ | ||
| 322 | static DSO *hwcrhk_dso = NULL; | ||
| 323 | static HWCryptoHook_ContextHandle hwcrhk_context = 0; | ||
| 324 | static int hndidx = -1; /* Index for KM handle. Not really used yet. */ | ||
| 325 | |||
| 326 | /* These are the function pointers that are (un)set when the library has | ||
| 327 | * successfully (un)loaded. */ | ||
| 328 | static HWCryptoHook_Init_t *p_hwcrhk_Init = NULL; | ||
| 329 | static HWCryptoHook_Finish_t *p_hwcrhk_Finish = NULL; | ||
| 330 | static HWCryptoHook_ModExp_t *p_hwcrhk_ModExp = NULL; | ||
| 331 | static HWCryptoHook_RSA_t *p_hwcrhk_RSA = NULL; | ||
| 332 | static HWCryptoHook_RandomBytes_t *p_hwcrhk_RandomBytes = NULL; | ||
| 333 | static HWCryptoHook_RSALoadKey_t *p_hwcrhk_RSALoadKey = NULL; | ||
| 334 | static HWCryptoHook_RSAGetPublicKey_t *p_hwcrhk_RSAGetPublicKey = NULL; | ||
| 335 | static HWCryptoHook_RSAUnloadKey_t *p_hwcrhk_RSAUnloadKey = NULL; | ||
| 336 | static HWCryptoHook_ModExpCRT_t *p_hwcrhk_ModExpCRT = NULL; | ||
| 337 | |||
| 338 | /* Used in the DSO operations. */ | ||
| 339 | static const char *HWCRHK_LIBNAME = "nfhwcrhk"; | ||
| 340 | static const char *n_hwcrhk_Init = "HWCryptoHook_Init"; | ||
| 341 | static const char *n_hwcrhk_Finish = "HWCryptoHook_Finish"; | ||
| 342 | static const char *n_hwcrhk_ModExp = "HWCryptoHook_ModExp"; | ||
| 343 | static const char *n_hwcrhk_RSA = "HWCryptoHook_RSA"; | ||
| 344 | static const char *n_hwcrhk_RandomBytes = "HWCryptoHook_RandomBytes"; | ||
| 345 | static const char *n_hwcrhk_RSALoadKey = "HWCryptoHook_RSALoadKey"; | ||
| 346 | static const char *n_hwcrhk_RSAGetPublicKey = "HWCryptoHook_RSAGetPublicKey"; | ||
| 347 | static const char *n_hwcrhk_RSAUnloadKey = "HWCryptoHook_RSAUnloadKey"; | ||
| 348 | static const char *n_hwcrhk_ModExpCRT = "HWCryptoHook_ModExpCRT"; | ||
| 349 | |||
| 350 | /* HWCryptoHook library functions and mechanics - these are used by the | ||
| 351 | * higher-level functions further down. NB: As and where there's no | ||
| 352 | * error checking, take a look lower down where these functions are | ||
| 353 | * called, the checking and error handling is probably down there. */ | ||
| 354 | |||
| 355 | /* utility function to obtain a context */ | ||
| 356 | static int get_context(HWCryptoHook_ContextHandle *hac) | ||
| 357 | { | ||
| 358 | char tempbuf[1024]; | ||
| 359 | HWCryptoHook_ErrMsgBuf rmsg; | ||
| 360 | |||
| 361 | rmsg.buf = tempbuf; | ||
| 362 | rmsg.size = 1024; | ||
| 363 | |||
| 364 | *hac = p_hwcrhk_Init(&hwcrhk_globals, sizeof(hwcrhk_globals), &rmsg, | ||
| 365 | NULL); | ||
| 366 | if (!*hac) | ||
| 367 | return 0; | ||
| 368 | return 1; | ||
| 369 | } | ||
| 370 | |||
| 371 | /* similarly to release one. */ | ||
| 372 | static void release_context(HWCryptoHook_ContextHandle hac) | ||
| 373 | { | ||
| 374 | p_hwcrhk_Finish(hac); | ||
| 375 | } | ||
| 376 | |||
| 377 | /* (de)initialisation functions. */ | ||
| 378 | static int hwcrhk_init() | ||
| 379 | { | ||
| 380 | HWCryptoHook_Init_t *p1; | ||
| 381 | HWCryptoHook_Finish_t *p2; | ||
| 382 | HWCryptoHook_ModExp_t *p3; | ||
| 383 | HWCryptoHook_RSA_t *p4; | ||
| 384 | HWCryptoHook_RSALoadKey_t *p5; | ||
| 385 | HWCryptoHook_RSAGetPublicKey_t *p6; | ||
| 386 | HWCryptoHook_RSAUnloadKey_t *p7; | ||
| 387 | HWCryptoHook_RandomBytes_t *p8; | ||
| 388 | HWCryptoHook_ModExpCRT_t *p9; | ||
| 389 | |||
| 390 | if(hwcrhk_dso != NULL) | ||
| 391 | { | ||
| 392 | ENGINEerr(ENGINE_F_HWCRHK_INIT,ENGINE_R_ALREADY_LOADED); | ||
| 393 | goto err; | ||
| 394 | } | ||
| 395 | /* Attempt to load libnfhwcrhk.so/nfhwcrhk.dll/whatever. */ | ||
| 396 | hwcrhk_dso = DSO_load(NULL, HWCRHK_LIBNAME, NULL, | ||
| 397 | DSO_FLAG_NAME_TRANSLATION); | ||
| 398 | if(hwcrhk_dso == NULL) | ||
| 399 | { | ||
| 400 | ENGINEerr(ENGINE_F_HWCRHK_INIT,ENGINE_R_DSO_FAILURE); | ||
| 401 | goto err; | ||
| 402 | } | ||
| 403 | if(!(p1 = (HWCryptoHook_Init_t *) | ||
| 404 | DSO_bind_func(hwcrhk_dso, n_hwcrhk_Init)) || | ||
| 405 | !(p2 = (HWCryptoHook_Finish_t *) | ||
| 406 | DSO_bind_func(hwcrhk_dso, n_hwcrhk_Finish)) || | ||
| 407 | !(p3 = (HWCryptoHook_ModExp_t *) | ||
| 408 | DSO_bind_func(hwcrhk_dso, n_hwcrhk_ModExp)) || | ||
| 409 | !(p4 = (HWCryptoHook_RSA_t *) | ||
| 410 | DSO_bind_func(hwcrhk_dso, n_hwcrhk_RSA)) || | ||
| 411 | !(p5 = (HWCryptoHook_RSALoadKey_t *) | ||
| 412 | DSO_bind_func(hwcrhk_dso, n_hwcrhk_RSALoadKey)) || | ||
| 413 | !(p6 = (HWCryptoHook_RSAGetPublicKey_t *) | ||
| 414 | DSO_bind_func(hwcrhk_dso, n_hwcrhk_RSAGetPublicKey)) || | ||
| 415 | !(p7 = (HWCryptoHook_RSAUnloadKey_t *) | ||
| 416 | DSO_bind_func(hwcrhk_dso, n_hwcrhk_RSAUnloadKey)) || | ||
| 417 | !(p8 = (HWCryptoHook_RandomBytes_t *) | ||
| 418 | DSO_bind_func(hwcrhk_dso, n_hwcrhk_RandomBytes)) || | ||
| 419 | !(p9 = (HWCryptoHook_ModExpCRT_t *) | ||
| 420 | DSO_bind_func(hwcrhk_dso, n_hwcrhk_ModExpCRT))) | ||
| 421 | { | ||
| 422 | ENGINEerr(ENGINE_F_HWCRHK_INIT,ENGINE_R_DSO_FAILURE); | ||
| 423 | goto err; | ||
| 424 | } | ||
| 425 | /* Copy the pointers */ | ||
| 426 | p_hwcrhk_Init = p1; | ||
| 427 | p_hwcrhk_Finish = p2; | ||
| 428 | p_hwcrhk_ModExp = p3; | ||
| 429 | p_hwcrhk_RSA = p4; | ||
| 430 | p_hwcrhk_RSALoadKey = p5; | ||
| 431 | p_hwcrhk_RSAGetPublicKey = p6; | ||
| 432 | p_hwcrhk_RSAUnloadKey = p7; | ||
| 433 | p_hwcrhk_RandomBytes = p8; | ||
| 434 | p_hwcrhk_ModExpCRT = p9; | ||
| 435 | |||
| 436 | /* Check if the application decided to support dynamic locks, | ||
| 437 | and if it does, use them. */ | ||
| 438 | if (disable_mutex_callbacks == 0 && | ||
| 439 | CRYPTO_get_dynlock_create_callback() != NULL && | ||
| 440 | CRYPTO_get_dynlock_lock_callback() != NULL && | ||
| 441 | CRYPTO_get_dynlock_destroy_callback() != NULL) | ||
| 442 | { | ||
| 443 | hwcrhk_globals.mutex_init = hwcrhk_mutex_init; | ||
| 444 | hwcrhk_globals.mutex_acquire = hwcrhk_mutex_lock; | ||
| 445 | hwcrhk_globals.mutex_release = hwcrhk_mutex_unlock; | ||
| 446 | hwcrhk_globals.mutex_destroy = hwcrhk_mutex_destroy; | ||
| 447 | } | ||
| 448 | |||
| 449 | /* Try and get a context - if not, we may have a DSO but no | ||
| 450 | * accelerator! */ | ||
| 451 | if(!get_context(&hwcrhk_context)) | ||
| 452 | { | ||
| 453 | ENGINEerr(ENGINE_F_HWCRHK_INIT,ENGINE_R_UNIT_FAILURE); | ||
| 454 | goto err; | ||
| 455 | } | ||
| 456 | /* Everything's fine. */ | ||
| 457 | if (hndidx == -1) | ||
| 458 | hndidx = RSA_get_ex_new_index(0, | ||
| 459 | "nFast HWCryptoHook RSA key handle", | ||
| 460 | NULL, NULL, hwcrhk_ex_free); | ||
| 461 | return 1; | ||
| 462 | err: | ||
| 463 | if(hwcrhk_dso) | ||
| 464 | DSO_free(hwcrhk_dso); | ||
| 465 | hwcrhk_dso = NULL; | ||
| 466 | p_hwcrhk_Init = NULL; | ||
| 467 | p_hwcrhk_Finish = NULL; | ||
| 468 | p_hwcrhk_ModExp = NULL; | ||
| 469 | p_hwcrhk_RSA = NULL; | ||
| 470 | p_hwcrhk_RSALoadKey = NULL; | ||
| 471 | p_hwcrhk_RSAGetPublicKey = NULL; | ||
| 472 | p_hwcrhk_RSAUnloadKey = NULL; | ||
| 473 | p_hwcrhk_ModExpCRT = NULL; | ||
| 474 | p_hwcrhk_RandomBytes = NULL; | ||
| 475 | return 0; | ||
| 476 | } | ||
| 477 | |||
| 478 | static int hwcrhk_finish() | ||
| 479 | { | ||
| 480 | int to_return = 1; | ||
| 481 | if(hwcrhk_dso == NULL) | ||
| 482 | { | ||
| 483 | ENGINEerr(ENGINE_F_HWCRHK_FINISH,ENGINE_R_NOT_LOADED); | ||
| 484 | to_return = 0; | ||
| 485 | goto err; | ||
| 486 | } | ||
| 487 | release_context(hwcrhk_context); | ||
| 488 | if(!DSO_free(hwcrhk_dso)) | ||
| 489 | { | ||
| 490 | ENGINEerr(ENGINE_F_HWCRHK_FINISH,ENGINE_R_DSO_FAILURE); | ||
| 491 | to_return = 0; | ||
| 492 | goto err; | ||
| 493 | } | ||
| 494 | err: | ||
| 495 | if (logstream) | ||
| 496 | BIO_free(logstream); | ||
| 497 | hwcrhk_dso = NULL; | ||
| 498 | p_hwcrhk_Init = NULL; | ||
| 499 | p_hwcrhk_Finish = NULL; | ||
| 500 | p_hwcrhk_ModExp = NULL; | ||
| 501 | p_hwcrhk_RSA = NULL; | ||
| 502 | p_hwcrhk_RSALoadKey = NULL; | ||
| 503 | p_hwcrhk_RSAGetPublicKey = NULL; | ||
| 504 | p_hwcrhk_RSAUnloadKey = NULL; | ||
| 505 | p_hwcrhk_ModExpCRT = NULL; | ||
| 506 | p_hwcrhk_RandomBytes = NULL; | ||
| 507 | return to_return; | ||
| 508 | } | ||
| 509 | |||
| 510 | static int hwcrhk_ctrl(int cmd, long i, void *p, void (*f)()) | ||
| 511 | { | ||
| 512 | int to_return = 1; | ||
| 513 | |||
| 514 | switch(cmd) | ||
| 515 | { | ||
| 516 | case ENGINE_CTRL_SET_LOGSTREAM: | ||
| 517 | { | ||
| 518 | BIO *bio = (BIO *)p; | ||
| 519 | |||
| 520 | CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); | ||
| 521 | if (logstream) | ||
| 522 | { | ||
| 523 | BIO_free(logstream); | ||
| 524 | logstream = NULL; | ||
| 525 | } | ||
| 526 | if (CRYPTO_add(&bio->references,1,CRYPTO_LOCK_BIO) > 1) | ||
| 527 | logstream = bio; | ||
| 528 | else | ||
| 529 | ENGINEerr(ENGINE_F_HWCRHK_CTRL,ENGINE_R_BIO_WAS_FREED); | ||
| 530 | } | ||
| 531 | CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); | ||
| 532 | break; | ||
| 533 | case ENGINE_CTRL_SET_PASSWORD_CALLBACK: | ||
| 534 | CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); | ||
| 535 | password_callback = (pem_password_cb *)f; | ||
| 536 | CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); | ||
| 537 | break; | ||
| 538 | /* this enables or disables the "SimpleForkCheck" flag used in the | ||
| 539 | * initialisation structure. */ | ||
| 540 | case ENGINE_CTRL_CHIL_SET_FORKCHECK: | ||
| 541 | CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); | ||
| 542 | if(i) | ||
| 543 | hwcrhk_globals.flags |= | ||
| 544 | HWCryptoHook_InitFlags_SimpleForkCheck; | ||
| 545 | else | ||
| 546 | hwcrhk_globals.flags &= | ||
| 547 | ~HWCryptoHook_InitFlags_SimpleForkCheck; | ||
| 548 | CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); | ||
| 549 | break; | ||
| 550 | /* This will prevent the initialisation function from "installing" | ||
| 551 | * the mutex-handling callbacks, even if they are available from | ||
| 552 | * within the library (or were provided to the library from the | ||
| 553 | * calling application). This is to remove any baggage for | ||
| 554 | * applications not using multithreading. */ | ||
| 555 | case ENGINE_CTRL_CHIL_NO_LOCKING: | ||
| 556 | CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); | ||
| 557 | disable_mutex_callbacks = 1; | ||
| 558 | CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); | ||
| 559 | break; | ||
| 560 | |||
| 561 | /* The command isn't understood by this engine */ | ||
| 562 | default: | ||
| 563 | ENGINEerr(ENGINE_F_HWCRHK_CTRL, | ||
| 564 | ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED); | ||
| 565 | to_return = 0; | ||
| 566 | break; | ||
| 567 | } | ||
| 568 | |||
| 569 | return to_return; | ||
| 570 | } | ||
| 571 | |||
| 572 | static EVP_PKEY *hwcrhk_load_privkey(const char *key_id, | ||
| 573 | const char *passphrase) | ||
| 574 | { | ||
| 575 | RSA *rtmp = NULL; | ||
| 576 | EVP_PKEY *res = NULL; | ||
| 577 | HWCryptoHook_MPI e, n; | ||
| 578 | HWCryptoHook_RSAKeyHandle *hptr; | ||
| 579 | HWCryptoHook_ErrMsgBuf rmsg; | ||
| 580 | |||
| 581 | if(!hwcrhk_context) | ||
| 582 | { | ||
| 583 | ENGINEerr(ENGINE_F_HWCRHK_LOAD_PRIVKEY, | ||
| 584 | ENGINE_R_NOT_INITIALISED); | ||
| 585 | goto err; | ||
| 586 | } | ||
| 587 | hptr = OPENSSL_malloc(sizeof(HWCryptoHook_RSAKeyHandle)); | ||
| 588 | if (!hptr) | ||
| 589 | { | ||
| 590 | ENGINEerr(ENGINE_F_HWCRHK_LOAD_PRIVKEY, | ||
| 591 | ERR_R_MALLOC_FAILURE); | ||
| 592 | goto err; | ||
| 593 | } | ||
| 594 | if (p_hwcrhk_RSALoadKey(hwcrhk_context, key_id, hptr, | ||
| 595 | &rmsg, NULL)) | ||
| 596 | { | ||
| 597 | ENGINEerr(ENGINE_F_HWCRHK_LOAD_PRIVKEY, | ||
| 598 | ENGINE_R_CHIL_ERROR); | ||
| 599 | ERR_add_error_data(1,rmsg.buf); | ||
| 600 | goto err; | ||
| 601 | } | ||
| 602 | if (!*hptr) | ||
| 603 | { | ||
| 604 | ENGINEerr(ENGINE_F_HWCRHK_LOAD_PRIVKEY, | ||
| 605 | ENGINE_R_NO_KEY); | ||
| 606 | goto err; | ||
| 607 | } | ||
| 608 | rtmp = RSA_new_method(&engine_hwcrhk); | ||
| 609 | RSA_set_ex_data(rtmp, hndidx, (char *)hptr); | ||
| 610 | rtmp->e = BN_new(); | ||
| 611 | rtmp->n = BN_new(); | ||
| 612 | rtmp->flags |= RSA_FLAG_EXT_PKEY; | ||
| 613 | MPI2BN(rtmp->e, e); | ||
| 614 | MPI2BN(rtmp->n, n); | ||
| 615 | if (p_hwcrhk_RSAGetPublicKey(*hptr, &n, &e, &rmsg) | ||
| 616 | != HWCRYPTOHOOK_ERROR_MPISIZE) | ||
| 617 | { | ||
| 618 | ENGINEerr(ENGINE_F_HWCRHK_LOAD_PUBKEY,ENGINE_R_CHIL_ERROR); | ||
| 619 | ERR_add_error_data(1,rmsg.buf); | ||
| 620 | goto err; | ||
| 621 | } | ||
| 622 | |||
| 623 | bn_expand2(rtmp->e, e.size/sizeof(BN_ULONG)); | ||
| 624 | bn_expand2(rtmp->n, n.size/sizeof(BN_ULONG)); | ||
| 625 | MPI2BN(rtmp->e, e); | ||
| 626 | MPI2BN(rtmp->n, n); | ||
| 627 | |||
| 628 | if (p_hwcrhk_RSAGetPublicKey(*hptr, &n, &e, &rmsg)) | ||
| 629 | { | ||
| 630 | ENGINEerr(ENGINE_F_HWCRHK_LOAD_PUBKEY, | ||
| 631 | ENGINE_R_CHIL_ERROR); | ||
| 632 | ERR_add_error_data(1,rmsg.buf); | ||
| 633 | goto err; | ||
| 634 | } | ||
| 635 | rtmp->e->top = e.size / sizeof(BN_ULONG); | ||
| 636 | bn_fix_top(rtmp->e); | ||
| 637 | rtmp->n->top = n.size / sizeof(BN_ULONG); | ||
| 638 | bn_fix_top(rtmp->n); | ||
| 639 | |||
| 640 | res = EVP_PKEY_new(); | ||
| 641 | EVP_PKEY_assign_RSA(res, rtmp); | ||
| 642 | |||
| 643 | return res; | ||
| 644 | err: | ||
| 645 | if (res) | ||
| 646 | EVP_PKEY_free(res); | ||
| 647 | if (rtmp) | ||
| 648 | RSA_free(rtmp); | ||
| 649 | return NULL; | ||
| 650 | } | ||
| 651 | |||
| 652 | static EVP_PKEY *hwcrhk_load_pubkey(const char *key_id, const char *passphrase) | ||
| 653 | { | ||
| 654 | EVP_PKEY *res = hwcrhk_load_privkey(key_id, passphrase); | ||
| 655 | |||
| 656 | if (res) | ||
| 657 | switch(res->type) | ||
| 658 | { | ||
| 659 | case EVP_PKEY_RSA: | ||
| 660 | { | ||
| 661 | RSA *rsa = NULL; | ||
| 662 | |||
| 663 | CRYPTO_w_lock(CRYPTO_LOCK_EVP_PKEY); | ||
| 664 | rsa = res->pkey.rsa; | ||
| 665 | res->pkey.rsa = RSA_new(); | ||
| 666 | res->pkey.rsa->n = rsa->n; | ||
| 667 | res->pkey.rsa->e = rsa->e; | ||
| 668 | CRYPTO_w_unlock(CRYPTO_LOCK_EVP_PKEY); | ||
| 669 | RSA_free(rsa); | ||
| 670 | } | ||
| 671 | default: | ||
| 672 | ENGINEerr(ENGINE_F_HWCRHK_LOAD_PUBKEY, | ||
| 673 | ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED); | ||
| 674 | goto err; | ||
| 675 | } | ||
| 676 | |||
| 677 | return res; | ||
| 678 | err: | ||
| 679 | if (res) | ||
| 680 | EVP_PKEY_free(res); | ||
| 681 | return NULL; | ||
| 682 | } | ||
| 683 | |||
| 684 | /* A little mod_exp */ | ||
| 685 | static int hwcrhk_mod_exp(BIGNUM *r, BIGNUM *a, const BIGNUM *p, | ||
| 686 | const BIGNUM *m, BN_CTX *ctx) | ||
| 687 | { | ||
| 688 | char tempbuf[1024]; | ||
| 689 | HWCryptoHook_ErrMsgBuf rmsg; | ||
| 690 | /* Since HWCryptoHook_MPI is pretty compatible with BIGNUM's, | ||
| 691 | we use them directly, plus a little macro magic. We only | ||
| 692 | thing we need to make sure of is that enough space is allocated. */ | ||
| 693 | HWCryptoHook_MPI m_a, m_p, m_n, m_r; | ||
| 694 | int to_return, ret; | ||
| 695 | |||
| 696 | to_return = 0; /* expect failure */ | ||
| 697 | rmsg.buf = tempbuf; | ||
| 698 | rmsg.size = 1024; | ||
| 699 | |||
| 700 | if(!hwcrhk_context) | ||
| 701 | { | ||
| 702 | ENGINEerr(ENGINE_F_HWCRHK_MOD_EXP,ENGINE_R_NOT_INITIALISED); | ||
| 703 | goto err; | ||
| 704 | } | ||
| 705 | /* Prepare the params */ | ||
| 706 | bn_expand2(r, m->top); /* Check for error !! */ | ||
| 707 | BN2MPI(m_a, a); | ||
| 708 | BN2MPI(m_p, p); | ||
| 709 | BN2MPI(m_n, m); | ||
| 710 | MPI2BN(r, m_r); | ||
| 711 | |||
| 712 | /* Perform the operation */ | ||
| 713 | ret = p_hwcrhk_ModExp(hwcrhk_context, m_a, m_p, m_n, &m_r, &rmsg); | ||
| 714 | |||
| 715 | /* Convert the response */ | ||
| 716 | r->top = m_r.size / sizeof(BN_ULONG); | ||
| 717 | bn_fix_top(r); | ||
| 718 | |||
| 719 | if (ret < 0) | ||
| 720 | { | ||
| 721 | /* FIXME: When this error is returned, HWCryptoHook is | ||
| 722 | telling us that falling back to software computation | ||
| 723 | might be a good thing. */ | ||
| 724 | if(ret == HWCRYPTOHOOK_ERROR_FALLBACK) | ||
| 725 | { | ||
| 726 | ENGINEerr(ENGINE_F_HWCRHK_MOD_EXP,ENGINE_R_REQUEST_FALLBACK); | ||
| 727 | } | ||
| 728 | else | ||
| 729 | { | ||
| 730 | ENGINEerr(ENGINE_F_HWCRHK_MOD_EXP,ENGINE_R_REQUEST_FAILED); | ||
| 731 | } | ||
| 732 | ERR_add_error_data(1,rmsg.buf); | ||
| 733 | goto err; | ||
| 734 | } | ||
| 735 | |||
| 736 | to_return = 1; | ||
| 737 | err: | ||
| 738 | return to_return; | ||
| 739 | } | ||
| 740 | |||
| 741 | static int hwcrhk_rsa_mod_exp(BIGNUM *r, BIGNUM *I, RSA *rsa) | ||
| 742 | { | ||
| 743 | char tempbuf[1024]; | ||
| 744 | HWCryptoHook_ErrMsgBuf rmsg; | ||
| 745 | HWCryptoHook_RSAKeyHandle *hptr; | ||
| 746 | int to_return = 0, ret; | ||
| 747 | |||
| 748 | if(!hwcrhk_context) | ||
| 749 | { | ||
| 750 | ENGINEerr(ENGINE_F_HWCRHK_MOD_EXP,ENGINE_R_NOT_INITIALISED); | ||
| 751 | goto err; | ||
| 752 | } | ||
| 753 | |||
| 754 | /* This provides support for nForce keys. Since that's opaque data | ||
| 755 | all we do is provide a handle to the proper key and let HWCryptoHook | ||
| 756 | take care of the rest. */ | ||
| 757 | if ((hptr = (HWCryptoHook_RSAKeyHandle *) RSA_get_ex_data(rsa, hndidx)) | ||
| 758 | != NULL) | ||
| 759 | { | ||
| 760 | HWCryptoHook_MPI m_a, m_r; | ||
| 761 | |||
| 762 | if(!rsa->n) | ||
| 763 | { | ||
| 764 | ENGINEerr(ENGINE_F_HWCRHK_RSA_MOD_EXP, | ||
| 765 | ENGINE_R_MISSING_KEY_COMPONENTS); | ||
| 766 | goto err; | ||
| 767 | } | ||
| 768 | |||
| 769 | rmsg.buf = tempbuf; | ||
| 770 | rmsg.size = 1024; | ||
| 771 | |||
| 772 | /* Prepare the params */ | ||
| 773 | bn_expand2(r, rsa->n->top); /* Check for error !! */ | ||
| 774 | BN2MPI(m_a, I); | ||
| 775 | MPI2BN(r, m_r); | ||
| 776 | |||
| 777 | /* Perform the operation */ | ||
| 778 | ret = p_hwcrhk_RSA(m_a, *hptr, &m_r, &rmsg); | ||
| 779 | |||
| 780 | /* Convert the response */ | ||
| 781 | r->top = m_r.size / sizeof(BN_ULONG); | ||
| 782 | bn_fix_top(r); | ||
| 783 | |||
| 784 | if (ret < 0) | ||
| 785 | { | ||
| 786 | /* FIXME: When this error is returned, HWCryptoHook is | ||
| 787 | telling us that falling back to software computation | ||
| 788 | might be a good thing. */ | ||
| 789 | if(ret == HWCRYPTOHOOK_ERROR_FALLBACK) | ||
| 790 | { | ||
| 791 | ENGINEerr(ENGINE_F_HWCRHK_RSA_MOD_EXP,ENGINE_R_REQUEST_FALLBACK); | ||
| 792 | } | ||
| 793 | else | ||
| 794 | { | ||
| 795 | ENGINEerr(ENGINE_F_HWCRHK_RSA_MOD_EXP,ENGINE_R_REQUEST_FAILED); | ||
| 796 | } | ||
| 797 | ERR_add_error_data(1,rmsg.buf); | ||
| 798 | goto err; | ||
| 799 | } | ||
| 800 | } | ||
| 801 | else | ||
| 802 | { | ||
| 803 | HWCryptoHook_MPI m_a, m_p, m_q, m_dmp1, m_dmq1, m_iqmp, m_r; | ||
| 804 | |||
| 805 | if(!rsa->p || !rsa->q || !rsa->dmp1 || !rsa->dmq1 || !rsa->iqmp) | ||
| 806 | { | ||
| 807 | ENGINEerr(ENGINE_F_HWCRHK_RSA_MOD_EXP, | ||
| 808 | ENGINE_R_MISSING_KEY_COMPONENTS); | ||
| 809 | goto err; | ||
| 810 | } | ||
| 811 | |||
| 812 | rmsg.buf = tempbuf; | ||
| 813 | rmsg.size = 1024; | ||
| 814 | |||
| 815 | /* Prepare the params */ | ||
| 816 | bn_expand2(r, rsa->n->top); /* Check for error !! */ | ||
| 817 | BN2MPI(m_a, I); | ||
| 818 | BN2MPI(m_p, rsa->p); | ||
| 819 | BN2MPI(m_q, rsa->q); | ||
| 820 | BN2MPI(m_dmp1, rsa->dmp1); | ||
| 821 | BN2MPI(m_dmq1, rsa->dmq1); | ||
| 822 | BN2MPI(m_iqmp, rsa->iqmp); | ||
| 823 | MPI2BN(r, m_r); | ||
| 824 | |||
| 825 | /* Perform the operation */ | ||
| 826 | ret = p_hwcrhk_ModExpCRT(hwcrhk_context, m_a, m_p, m_q, | ||
| 827 | m_dmp1, m_dmq1, m_iqmp, &m_r, NULL); | ||
| 828 | |||
| 829 | /* Convert the response */ | ||
| 830 | r->top = m_r.size / sizeof(BN_ULONG); | ||
| 831 | bn_fix_top(r); | ||
| 832 | |||
| 833 | if (ret < 0) | ||
| 834 | { | ||
| 835 | /* FIXME: When this error is returned, HWCryptoHook is | ||
| 836 | telling us that falling back to software computation | ||
| 837 | might be a good thing. */ | ||
| 838 | if(ret == HWCRYPTOHOOK_ERROR_FALLBACK) | ||
| 839 | { | ||
| 840 | ENGINEerr(ENGINE_F_HWCRHK_RSA_MOD_EXP,ENGINE_R_REQUEST_FALLBACK); | ||
| 841 | } | ||
| 842 | else | ||
| 843 | { | ||
| 844 | ENGINEerr(ENGINE_F_HWCRHK_RSA_MOD_EXP,ENGINE_R_REQUEST_FAILED); | ||
| 845 | } | ||
| 846 | ERR_add_error_data(1,rmsg.buf); | ||
| 847 | goto err; | ||
| 848 | } | ||
| 849 | } | ||
| 850 | /* If we're here, we must be here with some semblance of success :-) */ | ||
| 851 | to_return = 1; | ||
| 852 | err: | ||
| 853 | return to_return; | ||
| 854 | } | ||
| 855 | |||
| 856 | /* This function is aliased to mod_exp (with the mont stuff dropped). */ | ||
| 857 | static int hwcrhk_mod_exp_mont(BIGNUM *r, BIGNUM *a, const BIGNUM *p, | ||
| 858 | const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx) | ||
| 859 | { | ||
| 860 | return hwcrhk_mod_exp(r, a, p, m, ctx); | ||
| 861 | } | ||
| 862 | |||
| 863 | /* This function is aliased to mod_exp (with the dh and mont dropped). */ | ||
| 864 | static int hwcrhk_mod_exp_dh(DH *dh, BIGNUM *r, BIGNUM *a, const BIGNUM *p, | ||
| 865 | const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx) | ||
| 866 | { | ||
| 867 | return hwcrhk_mod_exp(r, a, p, m, ctx); | ||
| 868 | } | ||
| 869 | |||
| 870 | /* Random bytes are good */ | ||
| 871 | static int hwcrhk_rand_bytes(unsigned char *buf, int num) | ||
| 872 | { | ||
| 873 | char tempbuf[1024]; | ||
| 874 | HWCryptoHook_ErrMsgBuf rmsg; | ||
| 875 | int to_return = 0; /* assume failure */ | ||
| 876 | int ret; | ||
| 877 | |||
| 878 | rmsg.buf = tempbuf; | ||
| 879 | rmsg.size = 1024; | ||
| 880 | |||
| 881 | if(!hwcrhk_context) | ||
| 882 | { | ||
| 883 | ENGINEerr(ENGINE_F_HWCRHK_RAND_BYTES,ENGINE_R_NOT_INITIALISED); | ||
| 884 | goto err; | ||
| 885 | } | ||
| 886 | |||
| 887 | ret = p_hwcrhk_RandomBytes(hwcrhk_context, buf, num, &rmsg); | ||
| 888 | if (ret < 0) | ||
| 889 | { | ||
| 890 | /* FIXME: When this error is returned, HWCryptoHook is | ||
| 891 | telling us that falling back to software computation | ||
| 892 | might be a good thing. */ | ||
| 893 | if(ret == HWCRYPTOHOOK_ERROR_FALLBACK) | ||
| 894 | { | ||
| 895 | ENGINEerr(ENGINE_F_HWCRHK_RAND_BYTES,ENGINE_R_REQUEST_FALLBACK); | ||
| 896 | } | ||
| 897 | else | ||
| 898 | { | ||
| 899 | ENGINEerr(ENGINE_F_HWCRHK_RAND_BYTES,ENGINE_R_REQUEST_FAILED); | ||
| 900 | } | ||
| 901 | ERR_add_error_data(1,rmsg.buf); | ||
| 902 | goto err; | ||
| 903 | } | ||
| 904 | to_return = 1; | ||
| 905 | err: | ||
| 906 | return to_return; | ||
| 907 | } | ||
| 908 | |||
| 909 | static int hwcrhk_rand_status(void) | ||
| 910 | { | ||
| 911 | return 1; | ||
| 912 | } | ||
| 913 | |||
| 914 | /* This cleans up an RSA KM key, called when ex_data is freed */ | ||
| 915 | |||
| 916 | static void hwcrhk_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad, | ||
| 917 | int index,long argl, void *argp) | ||
| 918 | { | ||
| 919 | char tempbuf[1024]; | ||
| 920 | HWCryptoHook_ErrMsgBuf rmsg; | ||
| 921 | HWCryptoHook_RSAKeyHandle *hptr; | ||
| 922 | int ret; | ||
| 923 | |||
| 924 | rmsg.buf = tempbuf; | ||
| 925 | rmsg.size = 1024; | ||
| 926 | |||
| 927 | hptr = (HWCryptoHook_RSAKeyHandle *) item; | ||
| 928 | if(!hptr) return; | ||
| 929 | ret = p_hwcrhk_RSAUnloadKey(*hptr, NULL); | ||
| 930 | OPENSSL_free(hptr); | ||
| 931 | } | ||
| 932 | |||
| 933 | /* Mutex calls: since the HWCryptoHook model closely follows the POSIX model | ||
| 934 | * these just wrap the POSIX functions and add some logging. | ||
| 935 | */ | ||
| 936 | |||
| 937 | static int hwcrhk_mutex_init(HWCryptoHook_Mutex* mt, | ||
| 938 | HWCryptoHook_CallerContext *cactx) | ||
| 939 | { | ||
| 940 | mt->lockid = CRYPTO_get_new_dynlockid(); | ||
| 941 | if (mt->lockid == 0) | ||
| 942 | return 0; | ||
| 943 | return 1; | ||
| 944 | } | ||
| 945 | |||
| 946 | static int hwcrhk_mutex_lock(HWCryptoHook_Mutex *mt) | ||
| 947 | { | ||
| 948 | CRYPTO_w_lock(mt->lockid); | ||
| 949 | return 1; | ||
| 950 | } | ||
| 951 | |||
| 952 | void hwcrhk_mutex_unlock(HWCryptoHook_Mutex * mt) | ||
| 953 | { | ||
| 954 | CRYPTO_w_unlock(mt->lockid); | ||
| 955 | } | ||
| 956 | |||
| 957 | static void hwcrhk_mutex_destroy(HWCryptoHook_Mutex *mt) | ||
| 958 | { | ||
| 959 | CRYPTO_destroy_dynlockid(mt->lockid); | ||
| 960 | } | ||
| 961 | |||
| 962 | static int hwcrhk_get_pass(const char *prompt_info, | ||
| 963 | int *len_io, char *buf, | ||
| 964 | HWCryptoHook_PassphraseContext *ppctx, | ||
| 965 | HWCryptoHook_CallerContext *cactx) | ||
| 966 | { | ||
| 967 | int l = 0; | ||
| 968 | char prompt[1024]; | ||
| 969 | |||
| 970 | if (password_callback == NULL) | ||
| 971 | { | ||
| 972 | ENGINEerr(ENGINE_F_HWCRHK_GET_PASS,ENGINE_R_NO_CALLBACK); | ||
| 973 | return -1; | ||
| 974 | } | ||
| 975 | if (prompt_info) | ||
| 976 | { | ||
| 977 | strncpy(prompt, "Card: \"", sizeof(prompt)); | ||
| 978 | l += 5; | ||
| 979 | strncpy(prompt + l, prompt_info, sizeof(prompt) - l); | ||
| 980 | l += strlen(prompt_info); | ||
| 981 | if (l + 2 < sizeof(prompt)) | ||
| 982 | { | ||
| 983 | strncpy(prompt + l, "\"\n", sizeof(prompt) - l); | ||
| 984 | l += 2; | ||
| 985 | } | ||
| 986 | } | ||
| 987 | if (l < sizeof(prompt) - 1) | ||
| 988 | { | ||
| 989 | strncpy(prompt, "Enter Passphrase <enter to cancel>:", | ||
| 990 | sizeof(prompt) - l); | ||
| 991 | l += 35; | ||
| 992 | } | ||
| 993 | prompt[l] = '\0'; | ||
| 994 | |||
| 995 | /* I know, passing on the prompt instead of the user data *is* | ||
| 996 | a bad thing. However, that's all we have right now. | ||
| 997 | -- Richard Levitte */ | ||
| 998 | *len_io = password_callback(buf, *len_io, 0, prompt); | ||
| 999 | if(!*len_io) | ||
| 1000 | return -1; | ||
| 1001 | return 0; | ||
| 1002 | } | ||
| 1003 | |||
| 1004 | static void hwcrhk_log_message(void *logstream, const char *message) | ||
| 1005 | { | ||
| 1006 | BIO *lstream = NULL; | ||
| 1007 | |||
| 1008 | CRYPTO_w_lock(CRYPTO_LOCK_BIO); | ||
| 1009 | if (logstream) | ||
| 1010 | lstream=*(BIO **)logstream; | ||
| 1011 | if (lstream) | ||
| 1012 | { | ||
| 1013 | BIO_write(lstream, message, strlen(message)); | ||
| 1014 | } | ||
| 1015 | CRYPTO_w_unlock(CRYPTO_LOCK_BIO); | ||
| 1016 | } | ||
| 1017 | |||
| 1018 | #endif /* !NO_HW_NCIPHER */ | ||
| 1019 | #endif /* !NO_HW */ | ||
diff --git a/src/lib/libcrypto/engine/vendor_defns/atalla.h b/src/lib/libcrypto/engine/vendor_defns/atalla.h new file mode 100644 index 0000000000..8111649c54 --- /dev/null +++ b/src/lib/libcrypto/engine/vendor_defns/atalla.h | |||
| @@ -0,0 +1,61 @@ | |||
| 1 | /* This header declares the necessary definitions for using the exponentiation | ||
| 2 | * acceleration capabilities of Atalla cards. The only cryptographic operation | ||
| 3 | * is performed by "ASI_RSAPrivateKeyOpFn" and this takes a structure that | ||
| 4 | * defines an "RSA private key". However, it is really only performing a | ||
| 5 | * regular mod_exp using the supplied modulus and exponent - no CRT form is | ||
| 6 | * being used. Hence, it is a generic mod_exp function in disguise, and we use | ||
| 7 | * it as such. | ||
| 8 | * | ||
| 9 | * Thanks to the people at Atalla for letting me know these definitions are | ||
| 10 | * fine and that they can be reproduced here. | ||
| 11 | * | ||
| 12 | * Geoff. | ||
| 13 | */ | ||
| 14 | |||
| 15 | typedef struct ItemStr | ||
| 16 | { | ||
| 17 | unsigned char *data; | ||
| 18 | int len; | ||
| 19 | } Item; | ||
| 20 | |||
| 21 | typedef struct RSAPrivateKeyStr | ||
| 22 | { | ||
| 23 | void *reserved; | ||
| 24 | Item version; | ||
| 25 | Item modulus; | ||
| 26 | Item publicExponent; | ||
| 27 | Item privateExponent; | ||
| 28 | Item prime[2]; | ||
| 29 | Item exponent[2]; | ||
| 30 | Item coefficient; | ||
| 31 | } RSAPrivateKey; | ||
| 32 | |||
| 33 | /* Predeclare the function pointer types that we dynamically load from the DSO. | ||
| 34 | * These use the same names and form that Ben's original support code had (in | ||
| 35 | * crypto/bn/bn_exp.c) unless of course I've inadvertently changed the style | ||
| 36 | * somewhere along the way! | ||
| 37 | */ | ||
| 38 | |||
| 39 | typedef int tfnASI_GetPerformanceStatistics(int reset_flag, | ||
| 40 | unsigned int *ret_buf); | ||
| 41 | |||
| 42 | typedef int tfnASI_GetHardwareConfig(long card_num, unsigned int *ret_buf); | ||
| 43 | |||
| 44 | typedef int tfnASI_RSAPrivateKeyOpFn(RSAPrivateKey * rsaKey, | ||
| 45 | unsigned char *output, | ||
| 46 | unsigned char *input, | ||
| 47 | unsigned int modulus_len); | ||
| 48 | |||
| 49 | /* These are the static string constants for the DSO file name and the function | ||
| 50 | * symbol names to bind to. Regrettably, the DSO name on *nix appears to be | ||
| 51 | * "atasi.so" rather than something more consistent like "libatasi.so". At the | ||
| 52 | * time of writing, I'm not sure what the file name on win32 is but clearly | ||
| 53 | * native name translation is not possible (eg libatasi.so on *nix, and | ||
| 54 | * atasi.dll on win32). For the purposes of testing, I have created a symbollic | ||
| 55 | * link called "libatasi.so" so that we can use native name-translation - a | ||
| 56 | * better solution will be needed. */ | ||
| 57 | static const char *ATALLA_LIBNAME = "atasi"; | ||
| 58 | static const char *ATALLA_F1 = "ASI_GetHardwareConfig"; | ||
| 59 | static const char *ATALLA_F2 = "ASI_RSAPrivateKeyOpFn"; | ||
| 60 | static const char *ATALLA_F3 = "ASI_GetPerformanceStatistics"; | ||
| 61 | |||
diff --git a/src/lib/libcrypto/engine/vendor_defns/cswift.h b/src/lib/libcrypto/engine/vendor_defns/cswift.h new file mode 100644 index 0000000000..0af14a1a92 --- /dev/null +++ b/src/lib/libcrypto/engine/vendor_defns/cswift.h | |||
| @@ -0,0 +1,213 @@ | |||
| 1 | /* Attribution notice: Rainbow have generously allowed me to reproduce | ||
| 2 | * the necessary definitions here from their API. This means the support | ||
| 3 | * can build independently of whether application builders have the | ||
| 4 | * API or hardware. This will allow developers to easily produce software | ||
| 5 | * that has latent hardware support for any users that have accelertors | ||
| 6 | * installed, without the developers themselves needing anything extra. | ||
| 7 | * | ||
| 8 | * I have only clipped the parts from the CryptoSwift header files that | ||
| 9 | * are (or seem) relevant to the CryptoSwift support code. This is | ||
| 10 | * simply to keep the file sizes reasonable. | ||
| 11 | * [Geoff] | ||
| 12 | */ | ||
| 13 | |||
| 14 | |||
| 15 | /* NB: These type widths do *not* seem right in general, in particular | ||
| 16 | * they're not terribly friendly to 64-bit architectures (unsigned long) | ||
| 17 | * will be 64-bit on IA-64 for a start. I'm leaving these alone as they | ||
| 18 | * agree with Rainbow's API and this will only be called into question | ||
| 19 | * on platforms with Rainbow support anyway! ;-) */ | ||
| 20 | |||
| 21 | #ifdef __cplusplus | ||
| 22 | extern "C" { | ||
| 23 | #endif /* __cplusplus */ | ||
| 24 | |||
| 25 | typedef long SW_STATUS; /* status */ | ||
| 26 | typedef unsigned char SW_BYTE; /* 8 bit byte */ | ||
| 27 | typedef unsigned short SW_U16; /* 16 bit number */ | ||
| 28 | #if defined(_IRIX) | ||
| 29 | #include <sgidefs.h> | ||
| 30 | typedef __uint32_t SW_U32; | ||
| 31 | #else | ||
| 32 | typedef unsigned long SW_U32; /* 32 bit integer */ | ||
| 33 | #endif | ||
| 34 | |||
| 35 | #if defined(WIN32) | ||
| 36 | typedef struct _SW_U64 { | ||
| 37 | SW_U32 low32; | ||
| 38 | SW_U32 high32; | ||
| 39 | } SW_U64; /* 64 bit integer */ | ||
| 40 | #elif defined(MAC) | ||
| 41 | typedef longlong SW_U64 | ||
| 42 | #else /* Unix variants */ | ||
| 43 | typedef struct _SW_U64 { | ||
| 44 | SW_U32 low32; | ||
| 45 | SW_U32 high32; | ||
| 46 | } SW_U64; /* 64 bit integer */ | ||
| 47 | #endif | ||
| 48 | |||
| 49 | /* status codes */ | ||
| 50 | #define SW_OK (0L) | ||
| 51 | #define SW_ERR_BASE (-10000L) | ||
| 52 | #define SW_ERR_NO_CARD (SW_ERR_BASE-1) /* The Card is not present */ | ||
| 53 | #define SW_ERR_CARD_NOT_READY (SW_ERR_BASE-2) /* The card has not powered */ | ||
| 54 | /* up yet */ | ||
| 55 | #define SW_ERR_TIME_OUT (SW_ERR_BASE-3) /* Execution of a command */ | ||
| 56 | /* time out */ | ||
| 57 | #define SW_ERR_NO_EXECUTE (SW_ERR_BASE-4) /* The Card failed to */ | ||
| 58 | /* execute the command */ | ||
| 59 | #define SW_ERR_INPUT_NULL_PTR (SW_ERR_BASE-5) /* a required pointer is */ | ||
| 60 | /* NULL */ | ||
| 61 | #define SW_ERR_INPUT_SIZE (SW_ERR_BASE-6) /* size is invalid, too */ | ||
| 62 | /* small, too large. */ | ||
| 63 | #define SW_ERR_INVALID_HANDLE (SW_ERR_BASE-7) /* Invalid SW_ACC_CONTEXT */ | ||
| 64 | /* handle */ | ||
| 65 | #define SW_ERR_PENDING (SW_ERR_BASE-8) /* A request is already out- */ | ||
| 66 | /* standing at this */ | ||
| 67 | /* context handle */ | ||
| 68 | #define SW_ERR_AVAILABLE (SW_ERR_BASE-9) /* A result is available. */ | ||
| 69 | #define SW_ERR_NO_PENDING (SW_ERR_BASE-10)/* No request is pending. */ | ||
| 70 | #define SW_ERR_NO_MEMORY (SW_ERR_BASE-11)/* Not enough memory */ | ||
| 71 | #define SW_ERR_BAD_ALGORITHM (SW_ERR_BASE-12)/* Invalid algorithm type */ | ||
| 72 | /* in SW_PARAM structure */ | ||
| 73 | #define SW_ERR_MISSING_KEY (SW_ERR_BASE-13)/* No key is associated with */ | ||
| 74 | /* context. */ | ||
| 75 | /* swAttachKeyParam() is */ | ||
| 76 | /* not called. */ | ||
| 77 | #define SW_ERR_KEY_CMD_MISMATCH \ | ||
| 78 | (SW_ERR_BASE-14)/* Cannot perform requested */ | ||
| 79 | /* SW_COMMAND_CODE since */ | ||
| 80 | /* key attached via */ | ||
| 81 | /* swAttachKeyParam() */ | ||
| 82 | /* cannot be used for this*/ | ||
| 83 | /* SW_COMMAND_CODE. */ | ||
| 84 | #define SW_ERR_NOT_IMPLEMENTED \ | ||
| 85 | (SW_ERR_BASE-15)/* Not implemented */ | ||
| 86 | #define SW_ERR_BAD_COMMAND (SW_ERR_BASE-16)/* Bad command code */ | ||
| 87 | #define SW_ERR_BAD_ITEM_SIZE (SW_ERR_BASE-17)/* too small or too large in */ | ||
| 88 | /* the "initems" or */ | ||
| 89 | /* "outitems". */ | ||
| 90 | #define SW_ERR_BAD_ACCNUM (SW_ERR_BASE-18)/* Bad accelerator number */ | ||
| 91 | #define SW_ERR_SELFTEST_FAIL (SW_ERR_BASE-19)/* At least one of the self */ | ||
| 92 | /* test fail, look at the */ | ||
| 93 | /* selfTestBitmap in */ | ||
| 94 | /* SW_ACCELERATOR_INFO for*/ | ||
| 95 | /* details. */ | ||
| 96 | #define SW_ERR_MISALIGN (SW_ERR_BASE-20)/* Certain alogrithms require*/ | ||
| 97 | /* key materials aligned */ | ||
| 98 | /* in certain order, e.g. */ | ||
| 99 | /* 128 bit for CRT */ | ||
| 100 | #define SW_ERR_OUTPUT_NULL_PTR \ | ||
| 101 | (SW_ERR_BASE-21)/* a required pointer is */ | ||
| 102 | /* NULL */ | ||
| 103 | #define SW_ERR_OUTPUT_SIZE \ | ||
| 104 | (SW_ERR_BASE-22)/* size is invalid, too */ | ||
| 105 | /* small, too large. */ | ||
| 106 | #define SW_ERR_FIRMWARE_CHECKSUM \ | ||
| 107 | (SW_ERR_BASE-23)/* firmware checksum mismatch*/ | ||
| 108 | /* download failed. */ | ||
| 109 | #define SW_ERR_UNKNOWN_FIRMWARE \ | ||
| 110 | (SW_ERR_BASE-24)/* unknown firmware error */ | ||
| 111 | #define SW_ERR_INTERRUPT (SW_ERR_BASE-25)/* request is abort when */ | ||
| 112 | /* it's waiting to be */ | ||
| 113 | /* completed. */ | ||
| 114 | #define SW_ERR_NVWRITE_FAIL (SW_ERR_BASE-26)/* error in writing to Non- */ | ||
| 115 | /* volatile memory */ | ||
| 116 | #define SW_ERR_NVWRITE_RANGE (SW_ERR_BASE-27)/* out of range error in */ | ||
| 117 | /* writing to NV memory */ | ||
| 118 | #define SW_ERR_RNG_ERROR (SW_ERR_BASE-28)/* Random Number Generation */ | ||
| 119 | /* failure */ | ||
| 120 | #define SW_ERR_DSS_FAILURE (SW_ERR_BASE-29)/* DSS Sign or Verify failure*/ | ||
| 121 | #define SW_ERR_MODEXP_FAILURE (SW_ERR_BASE-30)/* Failure in various math */ | ||
| 122 | /* calculations */ | ||
| 123 | #define SW_ERR_ONBOARD_MEMORY (SW_ERR_BASE-31)/* Error in accessing on - */ | ||
| 124 | /* board memory */ | ||
| 125 | #define SW_ERR_FIRMWARE_VERSION \ | ||
| 126 | (SW_ERR_BASE-32)/* Wrong version in firmware */ | ||
| 127 | /* update */ | ||
| 128 | #define SW_ERR_ZERO_WORKING_ACCELERATOR \ | ||
| 129 | (SW_ERR_BASE-44)/* All accelerators are bad */ | ||
| 130 | |||
| 131 | |||
| 132 | /* algorithm type */ | ||
| 133 | #define SW_ALG_CRT 1 | ||
| 134 | #define SW_ALG_EXP 2 | ||
| 135 | #define SW_ALG_DSA 3 | ||
| 136 | #define SW_ALG_NVDATA 4 | ||
| 137 | |||
| 138 | /* command code */ | ||
| 139 | #define SW_CMD_MODEXP_CRT 1 /* perform Modular Exponentiation using */ | ||
| 140 | /* Chinese Remainder Theorem (CRT) */ | ||
| 141 | #define SW_CMD_MODEXP 2 /* perform Modular Exponentiation */ | ||
| 142 | #define SW_CMD_DSS_SIGN 3 /* perform DSS sign */ | ||
| 143 | #define SW_CMD_DSS_VERIFY 4 /* perform DSS verify */ | ||
| 144 | #define SW_CMD_RAND 5 /* perform random number generation */ | ||
| 145 | #define SW_CMD_NVREAD 6 /* perform read to nonvolatile RAM */ | ||
| 146 | #define SW_CMD_NVWRITE 7 /* perform write to nonvolatile RAM */ | ||
| 147 | |||
| 148 | typedef SW_U32 SW_ALGTYPE; /* alogrithm type */ | ||
| 149 | typedef SW_U32 SW_STATE; /* state */ | ||
| 150 | typedef SW_U32 SW_COMMAND_CODE; /* command code */ | ||
| 151 | typedef SW_U32 SW_COMMAND_BITMAP[4]; /* bitmap */ | ||
| 152 | |||
| 153 | typedef struct _SW_LARGENUMBER { | ||
| 154 | SW_U32 nbytes; /* number of bytes in the buffer "value" */ | ||
| 155 | SW_BYTE* value; /* the large integer as a string of */ | ||
| 156 | /* bytes in network (big endian) order */ | ||
| 157 | } SW_LARGENUMBER; | ||
| 158 | |||
| 159 | typedef struct _SW_CRT { | ||
| 160 | SW_LARGENUMBER p; /* prime number p */ | ||
| 161 | SW_LARGENUMBER q; /* prime number q */ | ||
| 162 | SW_LARGENUMBER dmp1; /* exponent1 */ | ||
| 163 | SW_LARGENUMBER dmq1; /* exponent2 */ | ||
| 164 | SW_LARGENUMBER iqmp; /* CRT coefficient */ | ||
| 165 | } SW_CRT; | ||
| 166 | |||
| 167 | typedef struct _SW_EXP { | ||
| 168 | SW_LARGENUMBER modulus; /* modulus */ | ||
| 169 | SW_LARGENUMBER exponent;/* exponent */ | ||
| 170 | } SW_EXP; | ||
| 171 | |||
| 172 | typedef struct _SW_DSA { | ||
| 173 | SW_LARGENUMBER p; /* */ | ||
| 174 | SW_LARGENUMBER q; /* */ | ||
| 175 | SW_LARGENUMBER g; /* */ | ||
| 176 | SW_LARGENUMBER key; /* private/public key */ | ||
| 177 | } SW_DSA; | ||
| 178 | |||
| 179 | typedef struct _SW_NVDATA { | ||
| 180 | SW_U32 accnum; /* accelerator board number */ | ||
| 181 | SW_U32 offset; /* offset in byte */ | ||
| 182 | } SW_NVDATA; | ||
| 183 | |||
| 184 | typedef struct _SW_PARAM { | ||
| 185 | SW_ALGTYPE type; /* type of the alogrithm */ | ||
| 186 | union { | ||
| 187 | SW_CRT crt; | ||
| 188 | SW_EXP exp; | ||
| 189 | SW_DSA dsa; | ||
| 190 | SW_NVDATA nvdata; | ||
| 191 | } up; | ||
| 192 | } SW_PARAM; | ||
| 193 | |||
| 194 | typedef SW_U32 SW_CONTEXT_HANDLE; /* opaque context handle */ | ||
| 195 | |||
| 196 | |||
| 197 | /* Now the OpenSSL bits, these function types are the for the function | ||
| 198 | * pointers that will bound into the Rainbow shared libraries. */ | ||
| 199 | typedef SW_STATUS t_swAcquireAccContext(SW_CONTEXT_HANDLE *hac); | ||
| 200 | typedef SW_STATUS t_swAttachKeyParam(SW_CONTEXT_HANDLE hac, | ||
| 201 | SW_PARAM *key_params); | ||
| 202 | typedef SW_STATUS t_swSimpleRequest(SW_CONTEXT_HANDLE hac, | ||
| 203 | SW_COMMAND_CODE cmd, | ||
| 204 | SW_LARGENUMBER pin[], | ||
| 205 | SW_U32 pin_count, | ||
| 206 | SW_LARGENUMBER pout[], | ||
| 207 | SW_U32 pout_count); | ||
| 208 | typedef SW_STATUS t_swReleaseAccContext(SW_CONTEXT_HANDLE hac); | ||
| 209 | |||
| 210 | #ifdef __cplusplus | ||
| 211 | } | ||
| 212 | #endif /* __cplusplus */ | ||
| 213 | |||
