summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/engine
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libcrypto/engine')
-rw-r--r--src/lib/libcrypto/engine/Makefile.ssl220
-rw-r--r--src/lib/libcrypto/engine/README278
-rw-r--r--src/lib/libcrypto/engine/engine.h398
-rw-r--r--src/lib/libcrypto/engine/engine_err.c183
-rw-r--r--src/lib/libcrypto/engine/engine_int.h160
-rw-r--r--src/lib/libcrypto/engine/engine_lib.c488
-rw-r--r--src/lib/libcrypto/engine/engine_list.c675
-rw-r--r--src/lib/libcrypto/engine/engine_openssl.c174
-rw-r--r--src/lib/libcrypto/engine/enginetest.c251
-rw-r--r--src/lib/libcrypto/engine/hw_atalla.c444
-rw-r--r--src/lib/libcrypto/engine/hw_cswift.c807
-rw-r--r--src/lib/libcrypto/engine/hw_ncipher.c1019
-rw-r--r--src/lib/libcrypto/engine/vendor_defns/atalla.h61
-rw-r--r--src/lib/libcrypto/engine/vendor_defns/cswift.h213
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
5DIR= engine
6TOP= ../..
7CC= cc
8INCLUDES= -I.. -I../../include
9CFLAG=-g
10INSTALL_PREFIX=
11OPENSSLDIR= /usr/local/ssl
12INSTALLTOP=/usr/local/ssl
13MAKE= make -f Makefile.ssl
14MAKEDEPEND= $(TOP)/util/domd $(TOP)
15MAKEFILE= Makefile.ssl
16AR= ar r
17
18CFLAGS= $(INCLUDES) $(CFLAG)
19
20GENERAL=Makefile
21TEST= enginetest.c
22APPS=
23
24LIB=$(TOP)/libcrypto.a
25LIBSRC= engine_err.c engine_lib.c engine_list.c engine_openssl.c \
26 hw_atalla.c hw_cswift.c hw_ncipher.c
27LIBOBJ= engine_err.o engine_lib.o engine_list.o engine_openssl.o \
28 hw_atalla.o hw_cswift.o hw_ncipher.o
29
30SRC= $(LIBSRC)
31
32EXHEADER= engine.h
33HEADER= $(EXHEADER)
34
35ALL= $(GENERAL) $(SRC) $(HEADER)
36
37top:
38 (cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
39
40all: lib
41
42lib: $(LIBOBJ)
43 $(AR) $(LIB) $(LIBOBJ)
44 $(RANLIB) $(LIB)
45 @touch lib
46
47files:
48 $(PERL) $(TOP)/util/files.pl Makefile.ssl >> $(TOP)/MINFO
49
50links:
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
56install:
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
63tags:
64 ctags $(SRC)
65
66tests:
67
68lint:
69 lint -DLINT $(INCLUDES) $(SRC)>fluff
70
71depend:
72 $(MAKEDEPEND) $(INCLUDES) $(DEPFLAG) $(PROGS) $(LIBSRC)
73
74dclean:
75 $(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
76 mv -f Makefile.new $(MAKEFILE)
77
78clean:
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
83engine_err.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
84engine_err.o: ../../include/openssl/blowfish.h ../../include/openssl/bn.h
85engine_err.o: ../../include/openssl/cast.h ../../include/openssl/crypto.h
86engine_err.o: ../../include/openssl/des.h ../../include/openssl/dh.h
87engine_err.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
88engine_err.o: ../../include/openssl/engine.h ../../include/openssl/err.h
89engine_err.o: ../../include/openssl/evp.h ../../include/openssl/idea.h
90engine_err.o: ../../include/openssl/lhash.h ../../include/openssl/md2.h
91engine_err.o: ../../include/openssl/md4.h ../../include/openssl/md5.h
92engine_err.o: ../../include/openssl/mdc2.h ../../include/openssl/obj_mac.h
93engine_err.o: ../../include/openssl/objects.h
94engine_err.o: ../../include/openssl/opensslconf.h
95engine_err.o: ../../include/openssl/opensslv.h ../../include/openssl/rand.h
96engine_err.o: ../../include/openssl/rc2.h ../../include/openssl/rc4.h
97engine_err.o: ../../include/openssl/rc5.h ../../include/openssl/ripemd.h
98engine_err.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
99engine_err.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
100engine_err.o: ../../include/openssl/symhacks.h
101engine_lib.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
102engine_lib.o: ../../include/openssl/blowfish.h ../../include/openssl/bn.h
103engine_lib.o: ../../include/openssl/buffer.h ../../include/openssl/cast.h
104engine_lib.o: ../../include/openssl/crypto.h ../../include/openssl/des.h
105engine_lib.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h
106engine_lib.o: ../../include/openssl/e_os.h ../../include/openssl/e_os2.h
107engine_lib.o: ../../include/openssl/engine.h ../../include/openssl/err.h
108engine_lib.o: ../../include/openssl/evp.h ../../include/openssl/idea.h
109engine_lib.o: ../../include/openssl/lhash.h ../../include/openssl/md2.h
110engine_lib.o: ../../include/openssl/md4.h ../../include/openssl/md5.h
111engine_lib.o: ../../include/openssl/mdc2.h ../../include/openssl/obj_mac.h
112engine_lib.o: ../../include/openssl/objects.h
113engine_lib.o: ../../include/openssl/opensslconf.h
114engine_lib.o: ../../include/openssl/opensslv.h ../../include/openssl/rand.h
115engine_lib.o: ../../include/openssl/rc2.h ../../include/openssl/rc4.h
116engine_lib.o: ../../include/openssl/rc5.h ../../include/openssl/ripemd.h
117engine_lib.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
118engine_lib.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
119engine_lib.o: ../../include/openssl/symhacks.h ../cryptlib.h engine_int.h
120engine_list.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
121engine_list.o: ../../include/openssl/blowfish.h ../../include/openssl/bn.h
122engine_list.o: ../../include/openssl/buffer.h ../../include/openssl/cast.h
123engine_list.o: ../../include/openssl/crypto.h ../../include/openssl/des.h
124engine_list.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h
125engine_list.o: ../../include/openssl/e_os.h ../../include/openssl/e_os2.h
126engine_list.o: ../../include/openssl/engine.h ../../include/openssl/err.h
127engine_list.o: ../../include/openssl/evp.h ../../include/openssl/idea.h
128engine_list.o: ../../include/openssl/lhash.h ../../include/openssl/md2.h
129engine_list.o: ../../include/openssl/md4.h ../../include/openssl/md5.h
130engine_list.o: ../../include/openssl/mdc2.h ../../include/openssl/obj_mac.h
131engine_list.o: ../../include/openssl/objects.h
132engine_list.o: ../../include/openssl/opensslconf.h
133engine_list.o: ../../include/openssl/opensslv.h ../../include/openssl/rand.h
134engine_list.o: ../../include/openssl/rc2.h ../../include/openssl/rc4.h
135engine_list.o: ../../include/openssl/rc5.h ../../include/openssl/ripemd.h
136engine_list.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
137engine_list.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
138engine_list.o: ../../include/openssl/symhacks.h ../cryptlib.h engine_int.h
139engine_openssl.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
140engine_openssl.o: ../../include/openssl/blowfish.h ../../include/openssl/bn.h
141engine_openssl.o: ../../include/openssl/buffer.h ../../include/openssl/cast.h
142engine_openssl.o: ../../include/openssl/crypto.h ../../include/openssl/des.h
143engine_openssl.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h
144engine_openssl.o: ../../include/openssl/dso.h ../../include/openssl/e_os.h
145engine_openssl.o: ../../include/openssl/e_os2.h ../../include/openssl/engine.h
146engine_openssl.o: ../../include/openssl/err.h ../../include/openssl/evp.h
147engine_openssl.o: ../../include/openssl/idea.h ../../include/openssl/lhash.h
148engine_openssl.o: ../../include/openssl/md2.h ../../include/openssl/md4.h
149engine_openssl.o: ../../include/openssl/md5.h ../../include/openssl/mdc2.h
150engine_openssl.o: ../../include/openssl/obj_mac.h
151engine_openssl.o: ../../include/openssl/objects.h
152engine_openssl.o: ../../include/openssl/opensslconf.h
153engine_openssl.o: ../../include/openssl/opensslv.h ../../include/openssl/rand.h
154engine_openssl.o: ../../include/openssl/rc2.h ../../include/openssl/rc4.h
155engine_openssl.o: ../../include/openssl/rc5.h ../../include/openssl/ripemd.h
156engine_openssl.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
157engine_openssl.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
158engine_openssl.o: ../../include/openssl/symhacks.h ../cryptlib.h engine_int.h
159hw_atalla.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
160hw_atalla.o: ../../include/openssl/blowfish.h ../../include/openssl/bn.h
161hw_atalla.o: ../../include/openssl/buffer.h ../../include/openssl/cast.h
162hw_atalla.o: ../../include/openssl/crypto.h ../../include/openssl/des.h
163hw_atalla.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h
164hw_atalla.o: ../../include/openssl/dso.h ../../include/openssl/e_os.h
165hw_atalla.o: ../../include/openssl/e_os2.h ../../include/openssl/engine.h
166hw_atalla.o: ../../include/openssl/err.h ../../include/openssl/evp.h
167hw_atalla.o: ../../include/openssl/idea.h ../../include/openssl/lhash.h
168hw_atalla.o: ../../include/openssl/md2.h ../../include/openssl/md4.h
169hw_atalla.o: ../../include/openssl/md5.h ../../include/openssl/mdc2.h
170hw_atalla.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
171hw_atalla.o: ../../include/openssl/opensslconf.h
172hw_atalla.o: ../../include/openssl/opensslv.h ../../include/openssl/rand.h
173hw_atalla.o: ../../include/openssl/rc2.h ../../include/openssl/rc4.h
174hw_atalla.o: ../../include/openssl/rc5.h ../../include/openssl/ripemd.h
175hw_atalla.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
176hw_atalla.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
177hw_atalla.o: ../../include/openssl/symhacks.h ../cryptlib.h engine_int.h
178hw_atalla.o: vendor_defns/atalla.h
179hw_cswift.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
180hw_cswift.o: ../../include/openssl/blowfish.h ../../include/openssl/bn.h
181hw_cswift.o: ../../include/openssl/buffer.h ../../include/openssl/cast.h
182hw_cswift.o: ../../include/openssl/crypto.h ../../include/openssl/des.h
183hw_cswift.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h
184hw_cswift.o: ../../include/openssl/dso.h ../../include/openssl/e_os.h
185hw_cswift.o: ../../include/openssl/e_os2.h ../../include/openssl/engine.h
186hw_cswift.o: ../../include/openssl/err.h ../../include/openssl/evp.h
187hw_cswift.o: ../../include/openssl/idea.h ../../include/openssl/lhash.h
188hw_cswift.o: ../../include/openssl/md2.h ../../include/openssl/md4.h
189hw_cswift.o: ../../include/openssl/md5.h ../../include/openssl/mdc2.h
190hw_cswift.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
191hw_cswift.o: ../../include/openssl/opensslconf.h
192hw_cswift.o: ../../include/openssl/opensslv.h ../../include/openssl/rand.h
193hw_cswift.o: ../../include/openssl/rc2.h ../../include/openssl/rc4.h
194hw_cswift.o: ../../include/openssl/rc5.h ../../include/openssl/ripemd.h
195hw_cswift.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
196hw_cswift.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
197hw_cswift.o: ../../include/openssl/symhacks.h ../cryptlib.h engine_int.h
198hw_cswift.o: vendor_defns/cswift.h
199hw_ncipher.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
200hw_ncipher.o: ../../include/openssl/blowfish.h ../../include/openssl/bn.h
201hw_ncipher.o: ../../include/openssl/buffer.h ../../include/openssl/cast.h
202hw_ncipher.o: ../../include/openssl/crypto.h ../../include/openssl/des.h
203hw_ncipher.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h
204hw_ncipher.o: ../../include/openssl/dso.h ../../include/openssl/e_os.h
205hw_ncipher.o: ../../include/openssl/e_os2.h ../../include/openssl/engine.h
206hw_ncipher.o: ../../include/openssl/err.h ../../include/openssl/evp.h
207hw_ncipher.o: ../../include/openssl/idea.h ../../include/openssl/lhash.h
208hw_ncipher.o: ../../include/openssl/md2.h ../../include/openssl/md4.h
209hw_ncipher.o: ../../include/openssl/md5.h ../../include/openssl/mdc2.h
210hw_ncipher.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
211hw_ncipher.o: ../../include/openssl/opensslconf.h
212hw_ncipher.o: ../../include/openssl/opensslv.h ../../include/openssl/pem.h
213hw_ncipher.o: ../../include/openssl/pem2.h ../../include/openssl/pkcs7.h
214hw_ncipher.o: ../../include/openssl/rand.h ../../include/openssl/rc2.h
215hw_ncipher.o: ../../include/openssl/rc4.h ../../include/openssl/rc5.h
216hw_ncipher.o: ../../include/openssl/ripemd.h ../../include/openssl/rsa.h
217hw_ncipher.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
218hw_ncipher.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
219hw_ncipher.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
220hw_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 @@
1NOTES, 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
39More notes 2000-08-01
40---------------------
41
42Geoff Thorpe, who designed the engine part, wrote a pretty good description
43of the thoughts he had when he built it, good enough to include verbatim here
44(with his permission) -- Richard Levitte
45
46
47Date: Tue, 1 Aug 2000 16:54:08 +0100 (BST)
48From: Geoff Thorpe
49Subject: Re: The thoughts to merge BRANCH_engine into the main trunk are
50 emerging
51
52Hi there,
53
54I'm going to try and do some justice to this, but I'm a little short on
55time and the there is an endless amount that could be discussed on this
56subject. 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
65The point here is that the code that has emerged in the BRANCH_engine
66branch was based on some initial requirements of mine that I went in and
67addressed, and Richard has picked up the ball and run with it too. It
68would be really useful to get some review of the approach we've taken, but
69first I think I need to describe as best I can the reasons behind what has
70been done so far, in particular what issues we have tried to address when
71doing this, and what issues we have intentionally (or necessarily) tried
72to avoid.
73
74methods, engines, and evps
75--------------------------
76
77There has been some dicussion, particularly with Steve, about where this
78ENGINE stuff might fit into the conceptual picture as/when we start to
79abstract algorithms a little bit to make the library more extensible. In
80particular, it would desirable to have algorithms (symmetric, hash, pkc,
81etc) abstracted in some way that allows them to be just objects sitting in
82a list (or database) ... it'll just happen that the "DSA" object doesn't
83support encryption whereas the "RSA" object does. This requires a lot of
84consideration to begin to know how to tackle it; in particular how
85encapsulated should these things be? If the objects also understand their
86own ASN1 encodings and what-not, then it would for example be possible to
87add support for elliptic-curve DSA in as a new algorithm and automatically
88have ECC-DSA certificates supported in SSL applications. Possible, but not
89easy. :-)
90
91Whatever, it seems that the way to go (if I've grok'd Steve's comments on
92this 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
94certainly think something should be done in this direction because right
95now we have different source directories, types, functions, and methods
96for each algorithm - even when conceptually they are very much different
97feathers of the same bird. (This is certainly all true for the public-key
98stuff, and may be partially true for the other parts.)
99
100ENGINE was *not* conceived as a way of solving this, far from it. Nor was
101it conceived as a way of replacing the various "***_METHOD"s. It was
102conceived as an abstraction of a sort of "virtual crypto device". If we
103lived in a world where "EVP_ALGO"s (or something like them) encapsulated
104particular algorithms like RSA,DSA,MD5,RC4,etc, and "***_METHOD"s
105encapsulated interfaces to algorithms (eg. some algo's might support a
106PKC_METHOD, a HASH_METHOD, or a CIPHER_METHOD, who knows?), then I would
107think that ENGINE would encapsulate an implementation of arbitrarily many
108of those algorithms - perhaps as alternatives to existing algorithms
109and/or perhaps as new previously unimplemented algorithms. An ENGINE could
110be used to contain an alternative software implementation, a wrapper for a
111hardware acceleration and/or key-management unit, a comms-wrapper for
112distributing cryptographic operations to remote machines, or any other
113"devices" your imagination can dream up.
114
115However, what has been done in the ENGINE branch so far is nothing more
116than starting to get our toes wet. I had a couple of self-imposed
117requirements when putting the initial abstraction together, and I may have
118already 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
170A *little* detail
171-----------------
172
173While my mind is on it; I'll illustrate the bit in item (vii). This idea
174turned out to be very handy - the ENGINEs themselves need to be operated
175on and manipulated simply as objects without necessarily trying to
176"enable" them for use. Eg. most host machines will not have the necessary
177hardware or software to support all the engines one might compile into
178OpenSSL, yet it needs to be possible to iterate across the ENGINEs,
179querying their names, properties, etc - all happening in a thread-safe
180manner that uses reference counts (if you imagine two threads iterating
181through a list and one thread removing the ENGINE the other is currently
182looking 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
184counts in OpenSSL.
185
186The other kind of reference count is for *functional* references - these
187indicate a reference on which the caller can actually assume the
188particular ENGINE to be initialised and usable to perform the operations
189it implements. Any increment or decrement of the functional reference
190count automatically invokes a corresponding change in the structural
191reference count, as it is fairly obvious that a functional reference is a
192restricted case of a structural reference. So struct_ref >= funct_ref at
193all times. NB: functional references are usually obtained by a call to
194ENGINE_init(), but can also be created implicitly by calls that require a
195new functional reference to be created, eg. ENGINE_set_default(). Either
196way the only time the underlying ENGINE's "init" function is really called
197is when the (functional) reference count increases to 1, similarly the
198underlying "finish" handler is only called as the count goes down to 0.
199The effect of this, for example, is that if you set the default ENGINE for
200RSA operations to be "cswift", then its functional reference count will
201already be at least 1 so the CryptoSwift shared-library and the card will
202stay loaded and initialised until such time as all RSA keys using the
203cswift ENGINE are changed or destroyed and the default ENGINE for RSA
204operations has been changed. This prevents repeated thrashing of init and
205finish handling if the count keeps getting down as far as zero.
206
207Otherwise, the way the ENGINE code has been put together I think pretty
208much reflects the above points. The reason for the ENGINE structure having
209individual RSA_METHOD, DSA_METHOD, etc pointers is simply that it was the
210easiest way to go about things for now, to hook it all into the raw
211RSA,DSA,etc code, and I was trying to the keep the structure invisible
212anyway so that the way this is internally managed could be easily changed
213later on when we start to work out what's to be done about these other
214abstractions.
215
216Down the line, if some EVP-based technique emerges for adequately
217encapsulating algorithms and all their various bits and pieces, then I can
218imagine that "ENGINE" would turn into a reference-counting database of
219these EVP things, of which the default "openssl" ENGINE would be the
220library'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
222from the algorithms themselves ... so RSA, DSA, ElGamal, etc can all
223expose essentially the same METHOD (aka interface), which would include
224any querying/flagging stuff to identify what the algorithm can/can't do,
225its name, and other stuff like max/min block sizes, key sizes, etc. This
226would result in ENGINE similarly detaching its internal database of
227algorithm implementations from the function definitions that return
228interfaces to them. I think ...
229
230As for DSOs etc. Well the DSO code is pretty handy (but could be made much
231more so) for loading vendor's driver-libraries and talking to them in some
232generic way, but right now there's still big problems associated with
233actually putting OpenSSL code (ie. new ENGINEs, or anything else for that
234matter) in dynamically loadable libraries. These problems won't go away in
235a hurry so I don't think we should expect to have any kind of
236shared-library extensions any time soon - but solving the problems is a
237good thing to aim for, and would as a side-effect probably help make
238OpenSSL more usable as a shared-library itself (looking at the things
239needed to do this will show you why).
240
241One of the problems is that if you look at any of the ENGINE
242implementations, eg. hw_cswift.c or hw_ncipher.c, you'll see how it needs
243a variety of functionality and definitions from various areas of OpenSSL,
244including crypto/bn/, crypto/err/, crypto/ itself (locking for example),
245crypto/dso/, crypto/engine/, crypto/rsa, etc etc etc. So if similar code
246were to be suctioned off into shared libraries, the shared libraries would
247either have to duplicate all the definitions and code and avoid loader
248conflicts, or OpenSSL would have to somehow expose all that functionality
249to the shared-library. If this isn't a big enough problem, the issue of
250binary compatibility will be - anyone writing Apache modules can tell you
251that (Ralf? Ben? :-). However, I don't think OpenSSL would need to be
252quite so forgiving as Apache should be, so OpenSSL could simply tell its
253version to the DSO and leave the DSO with the problem of deciding whether
254to proceed or bail out for fear of binary incompatibilities.
255
256Certainly one thing that would go a long way to addressing this is to
257embark on a bit of an opaqueness mission. I've set the ENGINE code up with
258this in mind - it's so draconian that even to declare your own ENGINE, you
259have to get the engine code to create the underlying ENGINE structure, and
260then 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
262approach, the more of the code that will be (a) easy to expose to shared
263libraries that need it, and (b) easy to expose to applications wanting to
264use OpenSSL itself as a shared-library. From my own explorations in
265OpenSSL, the biggest leviathan I've seen that is a problem in this respect
266is the BIGNUM code. Trying to "expose" the bignum code through any kind of
267organised "METHODs", let alone do all the necessary bignum operations
268solely through functions rather than direct access to the structures and
269macros, will be a massive pain in the "r"s.
270
271Anyway, I'm done for now - hope it was readable. Thoughts?
272
273Cheers,
274Geoff
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
71extern "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. */
109typedef 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. */
114typedef 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 */
119typedef void (*ENGINE_GEN_FUNC_PTR)();
120/* Generic function pointer taking no arguments */
121typedef void (*ENGINE_GEN_INT_FUNC_PTR)(void);
122/* Specific control function pointer */
123typedef 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). */
129typedef 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. */
143ENGINE *ENGINE_get_first(void);
144ENGINE *ENGINE_get_last(void);
145/* Iterate to the next/previous "ENGINE" type (NULL = end of the list). */
146ENGINE *ENGINE_get_next(ENGINE *e);
147ENGINE *ENGINE_get_prev(ENGINE *e);
148/* Add another "ENGINE" type into the array. */
149int ENGINE_add(ENGINE *e);
150/* Remove an existing "ENGINE" type from the array. */
151int ENGINE_remove(ENGINE *e);
152/* Retrieve an engine from the list by its unique "id" value. */
153ENGINE *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
168ENGINE *ENGINE_new(ENGINE *e);
169#else
170ENGINE *ENGINE_new(void);
171#endif
172int ENGINE_free(ENGINE *e);
173int ENGINE_set_id(ENGINE *e, const char *id);
174int ENGINE_set_name(ENGINE *e, const char *name);
175int ENGINE_set_RSA(ENGINE *e, RSA_METHOD *rsa_meth);
176int ENGINE_set_DSA(ENGINE *e, DSA_METHOD *dsa_meth);
177int ENGINE_set_DH(ENGINE *e, DH_METHOD *dh_meth);
178int ENGINE_set_RAND(ENGINE *e, RAND_METHOD *rand_meth);
179int ENGINE_set_BN_mod_exp(ENGINE *e, BN_MOD_EXP bn_mod_exp);
180int ENGINE_set_BN_mod_exp_crt(ENGINE *e, BN_MOD_EXP_CRT bn_mod_exp_crt);
181int ENGINE_set_init_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR init_f);
182int ENGINE_set_finish_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR finish_f);
183int 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! */
190const char *ENGINE_get_id(ENGINE *e);
191const char *ENGINE_get_name(ENGINE *e);
192RSA_METHOD *ENGINE_get_RSA(ENGINE *e);
193DSA_METHOD *ENGINE_get_DSA(ENGINE *e);
194DH_METHOD *ENGINE_get_DH(ENGINE *e);
195RAND_METHOD *ENGINE_get_RAND(ENGINE *e);
196BN_MOD_EXP ENGINE_get_BN_mod_exp(ENGINE *e);
197BN_MOD_EXP_CRT ENGINE_get_BN_mod_exp_crt(ENGINE *e);
198ENGINE_GEN_INT_FUNC_PTR ENGINE_get_init_function(ENGINE *e);
199ENGINE_GEN_INT_FUNC_PTR ENGINE_get_finish_function(ENGINE *e);
200ENGINE_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
213int 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. */
231int 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. */
235int 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! */
241int 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. */
246EVP_PKEY *ENGINE_load_private_key(ENGINE *e, const char *key_id,
247 const char *passphrase);
248EVP_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. */
255ENGINE *ENGINE_get_default_RSA(void);
256/* Same for the other "methods" */
257ENGINE *ENGINE_get_default_DSA(void);
258ENGINE *ENGINE_get_default_DH(void);
259ENGINE *ENGINE_get_default_RAND(void);
260ENGINE *ENGINE_get_default_BN_mod_exp(void);
261ENGINE *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'. */
267int ENGINE_set_default_RSA(ENGINE *e);
268/* Same for the other "methods" */
269int ENGINE_set_default_DSA(ENGINE *e);
270int ENGINE_set_default_DH(ENGINE *e);
271int ENGINE_set_default_RAND(ENGINE *e);
272int ENGINE_set_default_BN_mod_exp(ENGINE *e);
273int 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. */
277int ENGINE_set_default(ENGINE *e, unsigned int flags);
278
279/* Obligatory error function. */
280void 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
67static 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
132static 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
170void 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
70extern "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. */
81typedef 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. */
86typedef 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 */
91typedef int (*ENGINE_GEN_FUNC_PTR)();
92/* Generic function pointer taking no arguments */
93typedef int (*ENGINE_GEN_INT_FUNC_PTR)(void);
94/* Specific control function pointer */
95typedef 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. */
101typedef 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). */
134ENGINE *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. */
142ENGINE *ENGINE_cswift();
143#endif /* !NO_HW_CSWIFT */
144
145#ifndef NO_HW_NCIPHER
146ENGINE *ENGINE_ncipher();
147#endif /* !NO_HW_NCIPHER */
148
149#ifndef NO_HW_ATALLA
150/* Returns a structure of atalla methods. */
151ENGINE *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()!!!!!!). */
70static ENGINE *engine_def_rsa = NULL;
71static ENGINE *engine_def_dsa = NULL;
72static ENGINE *engine_def_dh = NULL;
73static ENGINE *engine_def_rand = NULL;
74static ENGINE *engine_def_bn_mod_exp = NULL;
75static 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. */
78static int engine_def_flag = 0;
79
80/* This is used in certain static utility functions to save code
81 * repetition for per-algorithm functions. */
82typedef 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
91static 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. */
100static 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;
131skip_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). */
143int 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 */
169int 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
219EVP_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
254EVP_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). */
291int 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
313static 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
349ENGINE *ENGINE_get_default_RSA(void)
350 {
351 return engine_get_default_type(ENGINE_TYPE_RSA);
352 }
353
354ENGINE *ENGINE_get_default_DSA(void)
355 {
356 return engine_get_default_type(ENGINE_TYPE_DSA);
357 }
358
359ENGINE *ENGINE_get_default_DH(void)
360 {
361 return engine_get_default_type(ENGINE_TYPE_DH);
362 }
363
364ENGINE *ENGINE_get_default_RAND(void)
365 {
366 return engine_get_default_type(ENGINE_TYPE_RAND);
367 }
368
369ENGINE *ENGINE_get_default_BN_mod_exp(void)
370 {
371 return engine_get_default_type(ENGINE_TYPE_BN_MOD_EXP);
372 }
373
374ENGINE *ENGINE_get_default_BN_mod_exp_crt(void)
375 {
376 return engine_get_default_type(ENGINE_TYPE_BN_MOD_EXP_CRT);
377 }
378
379static 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
436int ENGINE_set_default_RSA(ENGINE *e)
437 {
438 return engine_set_default_type(ENGINE_TYPE_RSA, e);
439 }
440
441int ENGINE_set_default_DSA(ENGINE *e)
442 {
443 return engine_set_default_type(ENGINE_TYPE_DSA, e);
444 }
445
446int ENGINE_set_default_DH(ENGINE *e)
447 {
448 return engine_set_default_type(ENGINE_TYPE_DH, e);
449 }
450
451int ENGINE_set_default_RAND(ENGINE *e)
452 {
453 return engine_set_default_type(ENGINE_TYPE_RAND, e);
454 }
455
456int ENGINE_set_default_BN_mod_exp(ENGINE *e)
457 {
458 return engine_set_default_type(ENGINE_TYPE_BN_MOD_EXP, e);
459 }
460
461int 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
466int 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. */
74static ENGINE *engine_list_head = NULL;
75static 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. */
79static 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. */
83static 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
140static 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. */
180static 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. */
207ENGINE *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 }
221ENGINE *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). */
237ENGINE *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 }
254ENGINE *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. */
273int 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. */
299int 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
319ENGINE *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
351int ENGINE_get_struct_size(void)
352 {
353 return sizeof(ENGINE);
354 }
355
356ENGINE *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
379ENGINE *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
396int 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
423int 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
435int 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
447int 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
459int 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
471int 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
483int 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
495int 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
507int 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
519int 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
531int 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
543int 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
555const 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
566const 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
577RSA_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
588DSA_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
599DH_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
610RAND_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
621BN_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
632BN_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
643ENGINE_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
654ENGINE_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
665ENGINE_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. */
75static 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. */
80static 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!!!) */
102ENGINE *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 */
115static 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;
166err:
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
64static 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
81int 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 }
222cleanup_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;
240end:
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
75static int atalla_init(void);
76static int atalla_finish(void);
77
78/* BIGNUM stuff */
79static int atalla_mod_exp(BIGNUM *r, BIGNUM *a, const BIGNUM *p,
80 const BIGNUM *m, BN_CTX *ctx);
81
82/* RSA stuff */
83static int atalla_rsa_mod_exp(BIGNUM *r0, BIGNUM *I, RSA *rsa);
84/* This function is aliased to mod_exp (with the mont stuff dropped). */
85static 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 */
89static 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);
92static 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). */
98static 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 */
103static 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 */
121static 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 */
136static 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. */
149static 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!!!) */
171ENGINE *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. */
209static DSO *atalla_dso = NULL;
210
211/* These are the function pointers that are (un)set when the library has
212 * successfully (un)loaded. */
213static tfnASI_GetHardwareConfig *p_Atalla_GetHardwareConfig = NULL;
214static tfnASI_RSAPrivateKeyOpFn *p_Atalla_RSAPrivateKeyOpFn = NULL;
215static tfnASI_GetPerformanceStatistics *p_Atalla_GetPerformanceStatistics = NULL;
216
217/* (de)initialisation functions. */
218static 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;
269err:
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
278static 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
297static 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;
362err:
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
370static 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);
388err:
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". */
401static 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;
416end:
417 BN_free(&t);
418 return to_return;
419 }
420
421
422static 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). */
430static 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). */
437static 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
87static int cswift_init(void);
88static int cswift_finish(void);
89
90/* BIGNUM stuff */
91static int cswift_mod_exp(BIGNUM *r, BIGNUM *a, const BIGNUM *p,
92 const BIGNUM *m, BN_CTX *ctx);
93static 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 */
98static int cswift_rsa_mod_exp(BIGNUM *r0, BIGNUM *I, RSA *rsa);
99/* This function is aliased to mod_exp (with the mont stuff dropped). */
100static 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 */
104static DSA_SIG *cswift_dsa_sign(const unsigned char *dgst, int dlen, DSA *dsa);
105static 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). */
110static 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 */
115static 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 */
133static 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 */
148static 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. */
161static 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!!!) */
183ENGINE *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. */
213static DSO *cswift_dso = NULL;
214
215/* These are the function pointers that are (un)set when the library has
216 * successfully (un)loaded. */
217t_swAcquireAccContext *p_CSwift_AcquireAccContext = NULL;
218t_swAttachKeyParam *p_CSwift_AttachKeyParam = NULL;
219t_swSimpleRequest *p_CSwift_SimpleRequest = NULL;
220t_swReleaseAccContext *p_CSwift_ReleaseAccContext = NULL;
221
222/* Used in the DSO operations. */
223static const char *CSWIFT_LIBNAME = "swift";
224static const char *CSWIFT_F1 = "swAcquireAccContext";
225static const char *CSWIFT_F2 = "swAttachKeyParam";
226static const char *CSWIFT_F3 = "swSimpleRequest";
227static 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 */
236static 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. */
247static void release_context(SW_CONTEXT_HANDLE hac)
248 {
249 p_CSwift_ReleaseAccContext(hac);
250 }
251
252/* (de)initialisation functions. */
253static 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;
301err:
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
311static 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 */
332static 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;
421err:
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 */
432static 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;
532err:
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
545static 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);
559err:
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). */
566static 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
572static 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
672err:
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
685static 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
786err:
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). */
800static 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
85static int hwcrhk_init(void);
86static int hwcrhk_finish(void);
87static int hwcrhk_ctrl(int cmd, long i, void *p, void (*f)());
88
89/* Functions to handle mutexes */
90static int hwcrhk_mutex_init(HWCryptoHook_Mutex*, HWCryptoHook_CallerContext*);
91static int hwcrhk_mutex_lock(HWCryptoHook_Mutex*);
92static void hwcrhk_mutex_unlock(HWCryptoHook_Mutex*);
93static void hwcrhk_mutex_destroy(HWCryptoHook_Mutex*);
94
95/* BIGNUM stuff */
96static int hwcrhk_mod_exp(BIGNUM *r, BIGNUM *a, const BIGNUM *p,
97 const BIGNUM *m, BN_CTX *ctx);
98
99/* RSA stuff */
100static int hwcrhk_rsa_mod_exp(BIGNUM *r, BIGNUM *I, RSA *rsa);
101/* This function is aliased to mod_exp (with the mont stuff dropped). */
102static 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). */
107static 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 */
111static int hwcrhk_rand_bytes(unsigned char *buf, int num);
112static int hwcrhk_rand_status(void);
113
114/* KM stuff */
115static EVP_PKEY *hwcrhk_load_privkey(const char *key_id,
116 const char *passphrase);
117static EVP_PKEY *hwcrhk_load_pubkey(const char *key_id,
118 const char *passphrase);
119static void hwcrhk_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad,
120 int index,long argl, void *argp);
121
122/* Interaction stuff */
123static int hwcrhk_get_pass(const char *prompt_info,
124 int *len_io, char *buf,
125 HWCryptoHook_PassphraseContext *ppctx,
126 HWCryptoHook_CallerContext *cactx);
127static void hwcrhk_log_message(void *logstream, const char *message);
128
129/* Our internal RSA_METHOD that we provide pointers to */
130static 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 */
148static 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
160static 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. */
172static 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 */
197struct HWCryptoHook_MutexValue
198 {
199 int lockid;
200 };
201
202/* hwcryptohook.h has some typedefs that turn
203 struct HWCryptoHook_PassphraseContextValue
204 into HWCryptoHook_PassphraseContext */
205struct HWCryptoHook_PassphraseContextValue
206 {
207 void *any;
208 };
209
210/* hwcryptohook.h has some typedefs that turn
211 struct HWCryptoHook_CallerContextValue
212 into HWCryptoHook_CallerContext */
213struct 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... */
230static int insert_card(const char *prompt_info,
231 const char *wrong_info,
232 HWCryptoHook_PassphraseContext *ppctx,
233 HWCryptoHook_CallerContext *cactx);
234static int get_pass(const char *prompt_info,
235 int *len_io, char *buf,
236 HWCryptoHook_PassphraseContext *ppctx,
237 HWCryptoHook_CallerContext *cactx);
238#endif
239
240static BIO *logstream = NULL;
241static pem_password_cb *password_callback = NULL;
242#if 0
243static void *password_callback_userdata = NULL;
244#endif
245static int disable_mutex_callbacks = 0;
246
247/* Stuff to pass to the HWCryptoHook library */
248static 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!!!) */
292ENGINE *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. */
322static DSO *hwcrhk_dso = NULL;
323static HWCryptoHook_ContextHandle hwcrhk_context = 0;
324static 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. */
328static HWCryptoHook_Init_t *p_hwcrhk_Init = NULL;
329static HWCryptoHook_Finish_t *p_hwcrhk_Finish = NULL;
330static HWCryptoHook_ModExp_t *p_hwcrhk_ModExp = NULL;
331static HWCryptoHook_RSA_t *p_hwcrhk_RSA = NULL;
332static HWCryptoHook_RandomBytes_t *p_hwcrhk_RandomBytes = NULL;
333static HWCryptoHook_RSALoadKey_t *p_hwcrhk_RSALoadKey = NULL;
334static HWCryptoHook_RSAGetPublicKey_t *p_hwcrhk_RSAGetPublicKey = NULL;
335static HWCryptoHook_RSAUnloadKey_t *p_hwcrhk_RSAUnloadKey = NULL;
336static HWCryptoHook_ModExpCRT_t *p_hwcrhk_ModExpCRT = NULL;
337
338/* Used in the DSO operations. */
339static const char *HWCRHK_LIBNAME = "nfhwcrhk";
340static const char *n_hwcrhk_Init = "HWCryptoHook_Init";
341static const char *n_hwcrhk_Finish = "HWCryptoHook_Finish";
342static const char *n_hwcrhk_ModExp = "HWCryptoHook_ModExp";
343static const char *n_hwcrhk_RSA = "HWCryptoHook_RSA";
344static const char *n_hwcrhk_RandomBytes = "HWCryptoHook_RandomBytes";
345static const char *n_hwcrhk_RSALoadKey = "HWCryptoHook_RSALoadKey";
346static const char *n_hwcrhk_RSAGetPublicKey = "HWCryptoHook_RSAGetPublicKey";
347static const char *n_hwcrhk_RSAUnloadKey = "HWCryptoHook_RSAUnloadKey";
348static 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 */
356static 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. */
372static void release_context(HWCryptoHook_ContextHandle hac)
373 {
374 p_hwcrhk_Finish(hac);
375 }
376
377/* (de)initialisation functions. */
378static 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;
462err:
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
478static 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
510static 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
572static 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
652static 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 */
685static 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;
737err:
738 return to_return;
739 }
740
741static 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;
852err:
853 return to_return;
854 }
855
856/* This function is aliased to mod_exp (with the mont stuff dropped). */
857static 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). */
864static 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 */
871static 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
909static 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
916static 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
937static 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
946static int hwcrhk_mutex_lock(HWCryptoHook_Mutex *mt)
947 {
948 CRYPTO_w_lock(mt->lockid);
949 return 1;
950 }
951
952void hwcrhk_mutex_unlock(HWCryptoHook_Mutex * mt)
953 {
954 CRYPTO_w_unlock(mt->lockid);
955 }
956
957static void hwcrhk_mutex_destroy(HWCryptoHook_Mutex *mt)
958 {
959 CRYPTO_destroy_dynlockid(mt->lockid);
960 }
961
962static 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
1004static 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
15typedef struct ItemStr
16 {
17 unsigned char *data;
18 int len;
19 } Item;
20
21typedef 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
39typedef int tfnASI_GetPerformanceStatistics(int reset_flag,
40 unsigned int *ret_buf);
41
42typedef int tfnASI_GetHardwareConfig(long card_num, unsigned int *ret_buf);
43
44typedef 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. */
57static const char *ATALLA_LIBNAME = "atasi";
58static const char *ATALLA_F1 = "ASI_GetHardwareConfig";
59static const char *ATALLA_F2 = "ASI_RSAPrivateKeyOpFn";
60static 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
22extern "C" {
23#endif /* __cplusplus */
24
25typedef long SW_STATUS; /* status */
26typedef unsigned char SW_BYTE; /* 8 bit byte */
27typedef unsigned short SW_U16; /* 16 bit number */
28#if defined(_IRIX)
29#include <sgidefs.h>
30typedef __uint32_t SW_U32;
31#else
32typedef 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
148typedef SW_U32 SW_ALGTYPE; /* alogrithm type */
149typedef SW_U32 SW_STATE; /* state */
150typedef SW_U32 SW_COMMAND_CODE; /* command code */
151typedef SW_U32 SW_COMMAND_BITMAP[4]; /* bitmap */
152
153typedef 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
159typedef 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
167typedef struct _SW_EXP {
168 SW_LARGENUMBER modulus; /* modulus */
169 SW_LARGENUMBER exponent;/* exponent */
170} SW_EXP;
171
172typedef 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
179typedef struct _SW_NVDATA {
180 SW_U32 accnum; /* accelerator board number */
181 SW_U32 offset; /* offset in byte */
182} SW_NVDATA;
183
184typedef 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
194typedef 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. */
199typedef SW_STATUS t_swAcquireAccContext(SW_CONTEXT_HANDLE *hac);
200typedef SW_STATUS t_swAttachKeyParam(SW_CONTEXT_HANDLE hac,
201 SW_PARAM *key_params);
202typedef 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);
208typedef SW_STATUS t_swReleaseAccContext(SW_CONTEXT_HANDLE hac);
209
210#ifdef __cplusplus
211}
212#endif /* __cplusplus */
213