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/Makefile34
-rw-r--r--src/lib/libcrypto/engine/README211
-rw-r--r--src/lib/libcrypto/engine/eng_aesni.c570
-rw-r--r--src/lib/libcrypto/engine/eng_all.c (renamed from src/lib/libcrypto/engine/hw_cswift_err.h)112
-rw-r--r--src/lib/libcrypto/engine/eng_cnf.c259
-rw-r--r--src/lib/libcrypto/engine/eng_cryptodev.c74
-rw-r--r--src/lib/libcrypto/engine/eng_ctrl.c389
-rw-r--r--src/lib/libcrypto/engine/eng_dyn.c548
-rw-r--r--src/lib/libcrypto/engine/eng_err.c173
-rw-r--r--src/lib/libcrypto/engine/eng_fat.c181
-rw-r--r--src/lib/libcrypto/engine/eng_init.c154
-rw-r--r--src/lib/libcrypto/engine/eng_int.h206
-rw-r--r--src/lib/libcrypto/engine/eng_lib.c332
-rw-r--r--src/lib/libcrypto/engine/eng_list.c433
-rw-r--r--src/lib/libcrypto/engine/eng_openssl.c384
-rw-r--r--src/lib/libcrypto/engine/eng_padlock.c1219
-rw-r--r--src/lib/libcrypto/engine/eng_pkey.c196
-rw-r--r--src/lib/libcrypto/engine/eng_rdrand.c142
-rw-r--r--src/lib/libcrypto/engine/eng_rsax.c668
-rw-r--r--src/lib/libcrypto/engine/eng_table.c351
-rw-r--r--src/lib/libcrypto/engine/engine.h834
-rw-r--r--src/lib/libcrypto/engine/hw.ec8
-rw-r--r--src/lib/libcrypto/engine/hw_4758_cca.c969
-rw-r--r--src/lib/libcrypto/engine/hw_4758_cca_err.c149
-rw-r--r--src/lib/libcrypto/engine/hw_aep.c1120
-rw-r--r--src/lib/libcrypto/engine/hw_aep_err.c157
-rw-r--r--src/lib/libcrypto/engine/hw_atalla.c595
-rw-r--r--src/lib/libcrypto/engine/hw_atalla_err.c145
-rw-r--r--src/lib/libcrypto/engine/hw_cryptodev.c396
-rw-r--r--src/lib/libcrypto/engine/hw_cswift.c1109
-rw-r--r--src/lib/libcrypto/engine/hw_cswift_err.c149
-rw-r--r--src/lib/libcrypto/engine/hw_ncipher.c1388
-rw-r--r--src/lib/libcrypto/engine/hw_ncipher_err.c157
-rw-r--r--src/lib/libcrypto/engine/hw_ncipher_err.h101
-rw-r--r--src/lib/libcrypto/engine/hw_nuron.c418
-rw-r--r--src/lib/libcrypto/engine/hw_sureware.c1039
-rw-r--r--src/lib/libcrypto/engine/hw_sureware_err.c150
-rw-r--r--src/lib/libcrypto/engine/hw_sureware_err.h94
-rw-r--r--src/lib/libcrypto/engine/hw_ubsec.c1061
-rw-r--r--src/lib/libcrypto/engine/hw_ubsec_err.c151
-rw-r--r--src/lib/libcrypto/engine/tb_asnmth.c246
-rw-r--r--src/lib/libcrypto/engine/tb_cipher.c (renamed from src/lib/libcrypto/engine/hw_nuron_err.c)139
-rw-r--r--src/lib/libcrypto/engine/tb_dh.c (renamed from src/lib/libcrypto/engine/hw_ubsec_err.h)103
-rw-r--r--src/lib/libcrypto/engine/tb_digest.c143
-rw-r--r--src/lib/libcrypto/engine/tb_dsa.c (renamed from src/lib/libcrypto/engine/hw_nuron_err.h)94
-rw-r--r--src/lib/libcrypto/engine/tb_ecdh.c133
-rw-r--r--src/lib/libcrypto/engine/tb_ecdsa.c (renamed from src/lib/libcrypto/engine/hw_4758_cca_err.h)101
-rw-r--r--src/lib/libcrypto/engine/tb_pkmeth.c167
-rw-r--r--src/lib/libcrypto/engine/tb_rand.c (renamed from src/lib/libcrypto/engine/hw_aep_err.h)109
-rw-r--r--src/lib/libcrypto/engine/tb_rsa.c (renamed from src/lib/libcrypto/engine/hw_atalla_err.h)97
-rw-r--r--src/lib/libcrypto/engine/tb_store.c123
-rw-r--r--src/lib/libcrypto/engine/vendor_defns/aep.h178
-rw-r--r--src/lib/libcrypto/engine/vendor_defns/atalla.h48
-rw-r--r--src/lib/libcrypto/engine/vendor_defns/cswift.h234
-rw-r--r--src/lib/libcrypto/engine/vendor_defns/hw_4758_cca.h149
-rw-r--r--src/lib/libcrypto/engine/vendor_defns/hw_ubsec.h100
-rw-r--r--src/lib/libcrypto/engine/vendor_defns/hwcryptohook.h486
-rw-r--r--src/lib/libcrypto/engine/vendor_defns/sureware.h239
58 files changed, 8859 insertions, 10856 deletions
diff --git a/src/lib/libcrypto/engine/Makefile b/src/lib/libcrypto/engine/Makefile
index d29bdd09a0..9c214824eb 100644
--- a/src/lib/libcrypto/engine/Makefile
+++ b/src/lib/libcrypto/engine/Makefile
@@ -21,14 +21,12 @@ LIBSRC= eng_err.c eng_lib.c eng_list.c eng_init.c eng_ctrl.c \
21 eng_table.c eng_pkey.c eng_fat.c eng_all.c \ 21 eng_table.c eng_pkey.c eng_fat.c eng_all.c \
22 tb_rsa.c tb_dsa.c tb_ecdsa.c tb_dh.c tb_ecdh.c tb_rand.c tb_store.c \ 22 tb_rsa.c tb_dsa.c tb_ecdsa.c tb_dh.c tb_ecdh.c tb_rand.c tb_store.c \
23 tb_cipher.c tb_digest.c tb_pkmeth.c tb_asnmth.c \ 23 tb_cipher.c tb_digest.c tb_pkmeth.c tb_asnmth.c \
24 eng_openssl.c eng_cnf.c eng_dyn.c eng_cryptodev.c \ 24 eng_openssl.c eng_cnf.c eng_dyn.c eng_cryptodev.c
25 eng_rsax.c eng_rdrand.c
26LIBOBJ= eng_err.o eng_lib.o eng_list.o eng_init.o eng_ctrl.o \ 25LIBOBJ= eng_err.o eng_lib.o eng_list.o eng_init.o eng_ctrl.o \
27 eng_table.o eng_pkey.o eng_fat.o eng_all.o \ 26 eng_table.o eng_pkey.o eng_fat.o eng_all.o \
28 tb_rsa.o tb_dsa.o tb_ecdsa.o tb_dh.o tb_ecdh.o tb_rand.o tb_store.o \ 27 tb_rsa.o tb_dsa.o tb_ecdsa.o tb_dh.o tb_ecdh.o tb_rand.o tb_store.o \
29 tb_cipher.o tb_digest.o tb_pkmeth.o tb_asnmth.o \ 28 tb_cipher.o tb_digest.o tb_pkmeth.o tb_asnmth.o \
30 eng_openssl.o eng_cnf.o eng_dyn.o eng_cryptodev.o \ 29 eng_openssl.o eng_cnf.o eng_dyn.o eng_cryptodev.o
31 eng_rsax.o eng_rdrand.o
32 30
33SRC= $(LIBSRC) 31SRC= $(LIBSRC)
34 32
@@ -251,34 +249,6 @@ eng_pkey.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
251eng_pkey.o: ../../include/openssl/sha.h ../../include/openssl/stack.h 249eng_pkey.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
252eng_pkey.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h 250eng_pkey.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
253eng_pkey.o: ../../include/openssl/x509_vfy.h ../cryptlib.h eng_int.h eng_pkey.c 251eng_pkey.o: ../../include/openssl/x509_vfy.h ../cryptlib.h eng_int.h eng_pkey.c
254eng_rdrand.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
255eng_rdrand.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
256eng_rdrand.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
257eng_rdrand.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
258eng_rdrand.o: ../../include/openssl/engine.h ../../include/openssl/err.h
259eng_rdrand.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
260eng_rdrand.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
261eng_rdrand.o: ../../include/openssl/opensslconf.h
262eng_rdrand.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
263eng_rdrand.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
264eng_rdrand.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
265eng_rdrand.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
266eng_rdrand.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
267eng_rdrand.o: eng_rdrand.c
268eng_rsax.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
269eng_rsax.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
270eng_rsax.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
271eng_rsax.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
272eng_rsax.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
273eng_rsax.o: ../../include/openssl/err.h ../../include/openssl/evp.h
274eng_rsax.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
275eng_rsax.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
276eng_rsax.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
277eng_rsax.o: ../../include/openssl/pkcs7.h ../../include/openssl/rsa.h
278eng_rsax.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
279eng_rsax.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
280eng_rsax.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
281eng_rsax.o: eng_rsax.c
282eng_table.o: ../../e_os.h ../../include/openssl/asn1.h 252eng_table.o: ../../e_os.h ../../include/openssl/asn1.h
283eng_table.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h 253eng_table.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
284eng_table.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h 254eng_table.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
diff --git a/src/lib/libcrypto/engine/README b/src/lib/libcrypto/engine/README
new file mode 100644
index 0000000000..6b69b70f57
--- /dev/null
+++ b/src/lib/libcrypto/engine/README
@@ -0,0 +1,211 @@
1Notes: 2001-09-24
2-----------------
3
4This "description" (if one chooses to call it that) needed some major updating
5so here goes. This update addresses a change being made at the same time to
6OpenSSL, and it pretty much completely restructures the underlying mechanics of
7the "ENGINE" code. So it serves a double purpose of being a "ENGINE internals
8for masochists" document *and* a rather extensive commit log message. (I'd get
9lynched for sticking all this in CHANGES or the commit mails :-).
10
11ENGINE_TABLE underlies this restructuring, as described in the internal header
12"eng_int.h", implemented in eng_table.c, and used in each of the "class" files;
13tb_rsa.c, tb_dsa.c, etc.
14
15However, "EVP_CIPHER" underlies the motivation and design of ENGINE_TABLE so
16I'll mention a bit about that first. EVP_CIPHER (and most of this applies
17equally to EVP_MD for digests) is both a "method" and a algorithm/mode
18identifier that, in the current API, "lingers". These cipher description +
19implementation structures can be defined or obtained directly by applications,
20or can be loaded "en masse" into EVP storage so that they can be catalogued and
21searched in various ways, ie. two ways of encrypting with the "des_cbc"
22algorithm/mode pair are;
23
24(i) directly;
25 const EVP_CIPHER *cipher = EVP_des_cbc();
26 EVP_EncryptInit(&ctx, cipher, key, iv);
27 [ ... use EVP_EncryptUpdate() and EVP_EncryptFinal() ...]
28
29(ii) indirectly;
30 OpenSSL_add_all_ciphers();
31 cipher = EVP_get_cipherbyname("des_cbc");
32 EVP_EncryptInit(&ctx, cipher, key, iv);
33 [ ... etc ... ]
34
35The latter is more generally used because it also allows ciphers/digests to be
36looked up based on other identifiers which can be useful for automatic cipher
37selection, eg. in SSL/TLS, or by user-controllable configuration.
38
39The important point about this is that EVP_CIPHER definitions and structures are
40passed around with impunity and there is no safe way, without requiring massive
41rewrites of many applications, to assume that EVP_CIPHERs can be reference
42counted. One an EVP_CIPHER is exposed to the caller, neither it nor anything it
43comes from can "safely" be destroyed. Unless of course the way of getting to
44such ciphers is via entirely distinct API calls that didn't exist before.
45However existing API usage cannot be made to understand when an EVP_CIPHER
46pointer, that has been passed to the caller, is no longer being used.
47
48The other problem with the existing API w.r.t. to hooking EVP_CIPHER support
49into ENGINE is storage - the OBJ_NAME-based storage used by EVP to register
50ciphers simultaneously registers cipher *types* and cipher *implementations* -
51they are effectively the same thing, an "EVP_CIPHER" pointer. The problem with
52hooking in ENGINEs is that multiple ENGINEs may implement the same ciphers. The
53solution is necessarily that ENGINE-provided ciphers simply are not registered,
54stored, or exposed to the caller in the same manner as existing ciphers. This is
55especially necessary considering the fact ENGINE uses reference counts to allow
56for cleanup, modularity, and DSO support - yet EVP_CIPHERs, as exposed to
57callers in the current API, support no such controls.
58
59Another sticking point for integrating cipher support into ENGINE is linkage.
60Already there is a problem with the way ENGINE supports RSA, DSA, etc whereby
61they are available *because* they're part of a giant ENGINE called "openssl".
62Ie. all implementations *have* to come from an ENGINE, but we get round that by
63having a giant ENGINE with all the software support encapsulated. This creates
64linker hassles if nothing else - linking a 1-line application that calls 2 basic
65RSA functions (eg. "RSA_free(RSA_new());") will result in large quantities of
66ENGINE code being linked in *and* because of that DSA, DH, and RAND also. If we
67continue with this approach for EVP_CIPHER support (even if it *was* possible)
68we would lose our ability to link selectively by selectively loading certain
69implementations of certain functionality. Touching any part of any kind of
70crypto would result in massive static linkage of everything else. So the
71solution is to change the way ENGINE feeds existing "classes", ie. how the
72hooking to ENGINE works from RSA, DSA, DH, RAND, as well as adding new hooking
73for EVP_CIPHER, and EVP_MD.
74
75The way this is now being done is by mostly reverting back to how things used to
76work prior to ENGINE :-). Ie. RSA now has a "RSA_METHOD" pointer again - this
77was previously replaced by an "ENGINE" pointer and all RSA code that required
78the RSA_METHOD would call ENGINE_get_RSA() each time on its ENGINE handle to
79temporarily get and use the ENGINE's RSA implementation. Apart from being more
80efficient, switching back to each RSA having an RSA_METHOD pointer also allows
81us to conceivably operate with *no* ENGINE. As we'll see, this removes any need
82for a fallback ENGINE that encapsulates default implementations - we can simply
83have our RSA structure pointing its RSA_METHOD pointer to the software
84implementation and have its ENGINE pointer set to NULL.
85
86A look at the EVP_CIPHER hooking is most explanatory, the RSA, DSA (etc) cases
87turn out to be degenerate forms of the same thing. The EVP storage of ciphers,
88and the existing EVP API functions that return "software" implementations and
89descriptions remain untouched. However, the storage takes more meaning in terms
90of "cipher description" and less meaning in terms of "implementation". When an
91EVP_CIPHER_CTX is actually initialised with an EVP_CIPHER method and is about to
92begin en/decryption, the hooking to ENGINE comes into play. What happens is that
93cipher-specific ENGINE code is asked for an ENGINE pointer (a functional
94reference) for any ENGINE that is registered to perform the algo/mode that the
95provided EVP_CIPHER structure represents. Under normal circumstances, that
96ENGINE code will return NULL because no ENGINEs will have had any cipher
97implementations *registered*. As such, a NULL ENGINE pointer is stored in the
98EVP_CIPHER_CTX context, and the EVP_CIPHER structure is left hooked into the
99context and so is used as the implementation. Pretty much how things work now
100except we'd have a redundant ENGINE pointer set to NULL and doing nothing.
101
102Conversely, if an ENGINE *has* been registered to perform the algorithm/mode
103combination represented by the provided EVP_CIPHER, then a functional reference
104to that ENGINE will be returned to the EVP_CIPHER_CTX during initialisation.
105That functional reference will be stored in the context (and released on
106cleanup) - and having that reference provides a *safe* way to use an EVP_CIPHER
107definition that is private to the ENGINE. Ie. the EVP_CIPHER provided by the
108application will actually be replaced by an EVP_CIPHER from the registered
109ENGINE - it will support the same algorithm/mode as the original but will be a
110completely different implementation. Because this EVP_CIPHER isn't stored in the
111EVP storage, nor is it returned to applications from traditional API functions,
112there is no associated problem with it not having reference counts. And of
113course, when one of these "private" cipher implementations is hooked into
114EVP_CIPHER_CTX, it is done whilst the EVP_CIPHER_CTX holds a functional
115reference to the ENGINE that owns it, thus the use of the ENGINE's EVP_CIPHER is
116safe.
117
118The "cipher-specific ENGINE code" I mentioned is implemented in tb_cipher.c but
119in essence it is simply an instantiation of "ENGINE_TABLE" code for use by
120EVP_CIPHER code. tb_digest.c is virtually identical but, of course, it is for
121use by EVP_MD code. Ditto for tb_rsa.c, tb_dsa.c, etc. These instantiations of
122ENGINE_TABLE essentially provide linker-separation of the classes so that even
123if ENGINEs implement *all* possible algorithms, an application using only
124EVP_CIPHER code will link at most code relating to EVP_CIPHER, tb_cipher.c, core
125ENGINE code that is independant of class, and of course the ENGINE
126implementation that the application loaded. It will *not* however link any
127class-specific ENGINE code for digests, RSA, etc nor will it bleed over into
128other APIs, such as the RSA/DSA/etc library code.
129
130ENGINE_TABLE is a little more complicated than may seem necessary but this is
131mostly to avoid a lot of "init()"-thrashing on ENGINEs (that may have to load
132DSOs, and other expensive setup that shouldn't be thrashed unnecessarily) *and*
133to duplicate "default" behaviour. Basically an ENGINE_TABLE instantiation, for
134example tb_cipher.c, implements a hash-table keyed by integer "nid" values.
135These nids provide the uniquenness of an algorithm/mode - and each nid will hash
136to a potentially NULL "ENGINE_PILE". An ENGINE_PILE is essentially a list of
137pointers to ENGINEs that implement that particular 'nid'. Each "pile" uses some
138caching tricks such that requests on that 'nid' will be cached and all future
139requests will return immediately (well, at least with minimal operation) unless
140a change is made to the pile, eg. perhaps an ENGINE was unloaded. The reason is
141that an application could have support for 10 ENGINEs statically linked
142in, and the machine in question may not have any of the hardware those 10
143ENGINEs support. If each of those ENGINEs has a "des_cbc" implementation, we
144want to avoid every EVP_CIPHER_CTX setup from trying (and failing) to initialise
145each of those 10 ENGINEs. Instead, the first such request will try to do that
146and will either return (and cache) a NULL ENGINE pointer or will return a
147functional reference to the first that successfully initialised. In the latter
148case it will also cache an extra functional reference to the ENGINE as a
149"default" for that 'nid'. The caching is acknowledged by a 'uptodate' variable
150that is unset only if un/registration takes place on that pile. Ie. if
151implementations of "des_cbc" are added or removed. This behaviour can be
152tweaked; the ENGINE_TABLE_FLAG_NOINIT value can be passed to
153ENGINE_set_table_flags(), in which case the only ENGINEs that tb_cipher.c will
154try to initialise from the "pile" will be those that are already initialised
155(ie. it's simply an increment of the functional reference count, and no real
156"initialisation" will take place).
157
158RSA, DSA, DH, and RAND all have their own ENGINE_TABLE code as well, and the
159difference is that they all use an implicit 'nid' of 1. Whereas EVP_CIPHERs are
160actually qualitatively different depending on 'nid' (the "des_cbc" EVP_CIPHER is
161not an interoperable implementation of "aes_256_cbc"), RSA_METHODs are
162necessarily interoperable and don't have different flavours, only different
163implementations. In other words, the ENGINE_TABLE for RSA will either be empty,
164or will have a single ENGING_PILE hashed to by the 'nid' 1 and that pile
165represents ENGINEs that implement the single "type" of RSA there is.
166
167Cleanup - the registration and unregistration may pose questions about how
168cleanup works with the ENGINE_PILE doing all this caching nonsense (ie. when the
169application or EVP_CIPHER code releases its last reference to an ENGINE, the
170ENGINE_PILE code may still have references and thus those ENGINEs will stay
171hooked in forever). The way this is handled is via "unregistration". With these
172new ENGINE changes, an abstract ENGINE can be loaded and initialised, but that
173is an algorithm-agnostic process. Even if initialised, it will not have
174registered any of its implementations (to do so would link all class "table"
175code despite the fact the application may use only ciphers, for example). This
176is deliberately a distinct step. Moreover, registration and unregistration has
177nothing to do with whether an ENGINE is *functional* or not (ie. you can even
178register an ENGINE and its implementations without it being operational, you may
179not even have the drivers to make it operate). What actually happens with
180respect to cleanup is managed inside eng_lib.c with the "engine_cleanup_***"
181functions. These functions are internal-only and each part of ENGINE code that
182could require cleanup will, upon performing its first allocation, register a
183callback with the "engine_cleanup" code. The other part of this that makes it
184tick is that the ENGINE_TABLE instantiations (tb_***.c) use NULL as their
185initialised state. So if RSA code asks for an ENGINE and no ENGINE has
186registered an implementation, the code will simply return NULL and the tb_rsa.c
187state will be unchanged. Thus, no cleanup is required unless registration takes
188place. ENGINE_cleanup() will simply iterate across a list of registered cleanup
189callbacks calling each in turn, and will then internally delete its own storage
190(a STACK). When a cleanup callback is next registered (eg. if the cleanup() is
191part of a gracefull restart and the application wants to cleanup all state then
192start again), the internal STACK storage will be freshly allocated. This is much
193the same as the situation in the ENGINE_TABLE instantiations ... NULL is the
194initialised state, so only modification operations (not queries) will cause that
195code to have to register a cleanup.
196
197What else? The bignum callbacks and associated ENGINE functions have been
198removed for two obvious reasons; (i) there was no way to generalise them to the
199mechanism now used by RSA/DSA/..., because there's no such thing as a BIGNUM
200method, and (ii) because of (i), there was no meaningful way for library or
201application code to automatically hook and use ENGINE supplied bignum functions
202anyway. Also, ENGINE_cpy() has been removed (although an internal-only version
203exists) - the idea of providing an ENGINE_cpy() function probably wasn't a good
204one and now certainly doesn't make sense in any generalised way. Some of the
205RSA, DSA, DH, and RAND functions that were fiddled during the original ENGINE
206changes have now, as a consequence, been reverted back. This is because the
207hooking of ENGINE is now automatic (and passive, it can interally use a NULL
208ENGINE pointer to simply ignore ENGINE from then on).
209
210Hell, that should be enough for now ... comments welcome: geoff@openssl.org
211
diff --git a/src/lib/libcrypto/engine/eng_aesni.c b/src/lib/libcrypto/engine/eng_aesni.c
new file mode 100644
index 0000000000..5fdb33bfde
--- /dev/null
+++ b/src/lib/libcrypto/engine/eng_aesni.c
@@ -0,0 +1,570 @@
1/*
2 * Support for Intel AES-NI intruction set
3 * Author: Huang Ying <ying.huang@intel.com>
4 *
5 * Intel AES-NI is a new set of Single Instruction Multiple Data
6 * (SIMD) instructions that are going to be introduced in the next
7 * generation of Intel processor, as of 2009. These instructions
8 * enable fast and secure data encryption and decryption, using the
9 * Advanced Encryption Standard (AES), defined by FIPS Publication
10 * number 197. The architecture introduces six instructions that
11 * offer full hardware support for AES. Four of them support high
12 * performance data encryption and decryption, and the other two
13 * instructions support the AES key expansion procedure.
14 *
15 * The white paper can be downloaded from:
16 * http://softwarecommunity.intel.com/isn/downloads/intelavx/AES-Instructions-Set_WP.pdf
17 *
18 * This file is based on engines/e_padlock.c
19 */
20
21/* ====================================================================
22 * Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved.
23 *
24 * Redistribution and use in source and binary forms, with or without
25 * modification, are permitted provided that the following conditions
26 * are met:
27 *
28 * 1. Redistributions of source code must retain the above copyright
29 * notice, this list of conditions and the following disclaimer.
30 *
31 * 2. Redistributions in binary form must reproduce the above copyright
32 * notice, this list of conditions and the following disclaimer in
33 * the documentation and/or other materials provided with the
34 * distribution.
35 *
36 * 3. All advertising materials mentioning features or use of this
37 * software must display the following acknowledgment:
38 * "This product includes software developed by the OpenSSL Project
39 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
40 *
41 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
42 * endorse or promote products derived from this software without
43 * prior written permission. For written permission, please contact
44 * licensing@OpenSSL.org.
45 *
46 * 5. Products derived from this software may not be called "OpenSSL"
47 * nor may "OpenSSL" appear in their names without prior written
48 * permission of the OpenSSL Project.
49 *
50 * 6. Redistributions of any form whatsoever must retain the following
51 * acknowledgment:
52 * "This product includes software developed by the OpenSSL Project
53 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
54 *
55 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
56 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
57 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
58 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
59 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
60 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
61 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
62 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
63 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
64 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
65 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
66 * OF THE POSSIBILITY OF SUCH DAMAGE.
67 * ====================================================================
68 *
69 * This product includes cryptographic software written by Eric Young
70 * (eay@cryptsoft.com). This product includes software written by Tim
71 * Hudson (tjh@cryptsoft.com).
72 *
73 */
74
75
76#include <openssl/opensslconf.h>
77
78#if !defined(OPENSSL_NO_HW) && !defined(OPENSSL_NO_HW_AES_NI) && !defined(OPENSSL_NO_AES)
79
80#include <stdio.h>
81#include <assert.h>
82#include "cryptlib.h"
83#include <openssl/dso.h>
84#include <openssl/engine.h>
85#include <openssl/evp.h>
86#include <openssl/aes.h>
87#include <openssl/err.h>
88
89/* AES-NI is available *ONLY* on some x86 CPUs. Not only that it
90 doesn't exist elsewhere, but it even can't be compiled on other
91 platforms! */
92#undef COMPILE_HW_AESNI
93#if (defined(__x86_64) || defined(__x86_64__) || \
94 defined(_M_AMD64) || defined(_M_X64) || \
95 defined(OPENSSL_IA32_SSE2)) && !defined(OPENSSL_NO_ASM) && !defined(__i386__)
96#define COMPILE_HW_AESNI
97#endif
98static ENGINE *ENGINE_aesni (void);
99
100void ENGINE_load_aesni (void)
101{
102/* On non-x86 CPUs it just returns. */
103#ifdef COMPILE_HW_AESNI
104 ENGINE *toadd = ENGINE_aesni();
105 if (!toadd) return;
106 ENGINE_add (toadd);
107 ENGINE_register_complete (toadd);
108 ENGINE_free (toadd);
109 ERR_clear_error ();
110#endif
111}
112
113#ifdef COMPILE_HW_AESNI
114int aesni_set_encrypt_key(const unsigned char *userKey, int bits,
115 AES_KEY *key);
116int aesni_set_decrypt_key(const unsigned char *userKey, int bits,
117 AES_KEY *key);
118
119void aesni_encrypt(const unsigned char *in, unsigned char *out,
120 const AES_KEY *key);
121void aesni_decrypt(const unsigned char *in, unsigned char *out,
122 const AES_KEY *key);
123
124void aesni_ecb_encrypt(const unsigned char *in,
125 unsigned char *out,
126 size_t length,
127 const AES_KEY *key,
128 int enc);
129void aesni_cbc_encrypt(const unsigned char *in,
130 unsigned char *out,
131 size_t length,
132 const AES_KEY *key,
133 unsigned char *ivec, int enc);
134
135/* Function for ENGINE detection and control */
136static int aesni_init(ENGINE *e);
137
138/* Cipher Stuff */
139static int aesni_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
140 const int **nids, int nid);
141
142#define AESNI_MIN_ALIGN 16
143#define AESNI_ALIGN(x) \
144 ((void *)(((unsigned long)(x)+AESNI_MIN_ALIGN-1)&~(AESNI_MIN_ALIGN-1)))
145
146/* Engine names */
147static const char aesni_id[] = "aesni",
148 aesni_name[] = "Intel AES-NI engine",
149 no_aesni_name[] = "Intel AES-NI engine (no-aesni)";
150
151
152/* The input and output encrypted as though 128bit cfb mode is being
153 * used. The extra state information to record how much of the
154 * 128bit block we have used is contained in *num;
155 */
156static void aesni_cfb128_encrypt(const unsigned char *in, unsigned char *out,
157 unsigned int len, const void *key,
158 unsigned char ivec[16], int *num,
159 int enc)
160{
161 unsigned int n;
162 size_t l = 0;
163
164 assert(in && out && key && ivec && num);
165
166 n = *num;
167
168 if (enc) {
169#if !defined(OPENSSL_SMALL_FOOTPRINT)
170 if (16%sizeof(size_t) == 0) do { /* always true actually */
171 while (n && len) {
172 *(out++) = ivec[n] ^= *(in++);
173 --len;
174 n = (n+1) % 16;
175 }
176 while (len>=16) {
177 aesni_encrypt(ivec, ivec, key);
178 for (n=0; n<16; n+=sizeof(size_t)) {
179 *(size_t*)(out+n) =
180 *(size_t*)(ivec+n) ^= *(size_t*)(in+n);
181 }
182 len -= 16;
183 out += 16;
184 in += 16;
185 }
186 n = 0;
187 if (len) {
188 aesni_encrypt(ivec, ivec, key);
189 while (len--) {
190 out[n] = ivec[n] ^= in[n];
191 ++n;
192 }
193 }
194 *num = n;
195 return;
196 } while (0);
197 /* the rest would be commonly eliminated by x86* compiler */
198#endif
199 while (l<len) {
200 if (n == 0) {
201 aesni_encrypt(ivec, ivec, key);
202 }
203 out[l] = ivec[n] ^= in[l];
204 ++l;
205 n = (n+1) % 16;
206 }
207 *num = n;
208 } else {
209#if !defined(OPENSSL_SMALL_FOOTPRINT)
210 if (16%sizeof(size_t) == 0) do { /* always true actually */
211 while (n && len) {
212 unsigned char c;
213 *(out++) = ivec[n] ^ (c = *(in++)); ivec[n] = c;
214 --len;
215 n = (n+1) % 16;
216 }
217 while (len>=16) {
218 aesni_encrypt(ivec, ivec, key);
219 for (n=0; n<16; n+=sizeof(size_t)) {
220 size_t t = *(size_t*)(in+n);
221 *(size_t*)(out+n) = *(size_t*)(ivec+n) ^ t;
222 *(size_t*)(ivec+n) = t;
223 }
224 len -= 16;
225 out += 16;
226 in += 16;
227 }
228 n = 0;
229 if (len) {
230 aesni_encrypt(ivec, ivec, key);
231 while (len--) {
232 unsigned char c;
233 out[n] = ivec[n] ^ (c = in[n]); ivec[n] = c;
234 ++n;
235 }
236 }
237 *num = n;
238 return;
239 } while (0);
240 /* the rest would be commonly eliminated by x86* compiler */
241#endif
242 while (l<len) {
243 unsigned char c;
244 if (n == 0) {
245 aesni_encrypt(ivec, ivec, key);
246 }
247 out[l] = ivec[n] ^ (c = in[l]); ivec[n] = c;
248 ++l;
249 n = (n+1) % 16;
250 }
251 *num=n;
252 }
253}
254
255/* The input and output encrypted as though 128bit ofb mode is being
256 * used. The extra state information to record how much of the
257 * 128bit block we have used is contained in *num;
258 */
259static void aesni_ofb128_encrypt(const unsigned char *in, unsigned char *out,
260 unsigned int len, const void *key,
261 unsigned char ivec[16], int *num)
262{
263 unsigned int n;
264 size_t l=0;
265
266 assert(in && out && key && ivec && num);
267
268 n = *num;
269
270#if !defined(OPENSSL_SMALL_FOOTPRINT)
271 if (16%sizeof(size_t) == 0) do { /* always true actually */
272 while (n && len) {
273 *(out++) = *(in++) ^ ivec[n];
274 --len;
275 n = (n+1) % 16;
276 }
277 while (len>=16) {
278 aesni_encrypt(ivec, ivec, key);
279 for (n=0; n<16; n+=sizeof(size_t))
280 *(size_t*)(out+n) =
281 *(size_t*)(in+n) ^ *(size_t*)(ivec+n);
282 len -= 16;
283 out += 16;
284 in += 16;
285 }
286 n = 0;
287 if (len) {
288 aesni_encrypt(ivec, ivec, key);
289 while (len--) {
290 out[n] = in[n] ^ ivec[n];
291 ++n;
292 }
293 }
294 *num = n;
295 return;
296 } while(0);
297 /* the rest would be commonly eliminated by x86* compiler */
298#endif
299 while (l<len) {
300 if (n==0) {
301 aesni_encrypt(ivec, ivec, key);
302 }
303 out[l] = in[l] ^ ivec[n];
304 ++l;
305 n = (n+1) % 16;
306 }
307
308 *num=n;
309}
310/* ===== Engine "management" functions ===== */
311
312#if defined(_WIN32)
313typedef unsigned __int64 IA32CAP;
314#else
315typedef unsigned long long IA32CAP;
316#endif
317
318/* Prepare the ENGINE structure for registration */
319static int
320aesni_bind_helper(ENGINE *e)
321{
322 int engage;
323 if (sizeof(OPENSSL_ia32cap_P) > 4) {
324 engage = ((IA32CAP)OPENSSL_ia32cap_P >> 57) & 1;
325 } else {
326 IA32CAP OPENSSL_ia32_cpuid(void);
327 engage = (OPENSSL_ia32_cpuid() >> 57) & 1;
328 }
329
330 /* Register everything or return with an error */
331 if (!ENGINE_set_id(e, aesni_id) ||
332 !ENGINE_set_name(e, engage ? aesni_name : no_aesni_name) ||
333
334 !ENGINE_set_init_function(e, aesni_init) ||
335 (engage && !ENGINE_set_ciphers (e, aesni_ciphers))
336 )
337 return 0;
338
339 /* Everything looks good */
340 return 1;
341}
342
343/* Constructor */
344static ENGINE *
345ENGINE_aesni(void)
346{
347 ENGINE *eng = ENGINE_new();
348
349 if (!eng) {
350 return NULL;
351 }
352
353 if (!aesni_bind_helper(eng)) {
354 ENGINE_free(eng);
355 return NULL;
356 }
357
358 return eng;
359}
360
361/* Check availability of the engine */
362static int
363aesni_init(ENGINE *e)
364{
365 return 1;
366}
367
368#if defined(NID_aes_128_cfb128) && ! defined (NID_aes_128_cfb)
369#define NID_aes_128_cfb NID_aes_128_cfb128
370#endif
371
372#if defined(NID_aes_128_ofb128) && ! defined (NID_aes_128_ofb)
373#define NID_aes_128_ofb NID_aes_128_ofb128
374#endif
375
376#if defined(NID_aes_192_cfb128) && ! defined (NID_aes_192_cfb)
377#define NID_aes_192_cfb NID_aes_192_cfb128
378#endif
379
380#if defined(NID_aes_192_ofb128) && ! defined (NID_aes_192_ofb)
381#define NID_aes_192_ofb NID_aes_192_ofb128
382#endif
383
384#if defined(NID_aes_256_cfb128) && ! defined (NID_aes_256_cfb)
385#define NID_aes_256_cfb NID_aes_256_cfb128
386#endif
387
388#if defined(NID_aes_256_ofb128) && ! defined (NID_aes_256_ofb)
389#define NID_aes_256_ofb NID_aes_256_ofb128
390#endif
391
392/* List of supported ciphers. */
393static int aesni_cipher_nids[] = {
394 NID_aes_128_ecb,
395 NID_aes_128_cbc,
396 NID_aes_128_cfb,
397 NID_aes_128_ofb,
398
399 NID_aes_192_ecb,
400 NID_aes_192_cbc,
401 NID_aes_192_cfb,
402 NID_aes_192_ofb,
403
404 NID_aes_256_ecb,
405 NID_aes_256_cbc,
406 NID_aes_256_cfb,
407 NID_aes_256_ofb,
408};
409static int aesni_cipher_nids_num =
410 (sizeof(aesni_cipher_nids)/sizeof(aesni_cipher_nids[0]));
411
412typedef struct
413{
414 AES_KEY ks;
415 unsigned int _pad1[3];
416} AESNI_KEY;
417
418static int
419aesni_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *user_key,
420 const unsigned char *iv, int enc)
421{
422 int ret;
423 AES_KEY *key = AESNI_ALIGN(ctx->cipher_data);
424
425 if ((ctx->cipher->flags & EVP_CIPH_MODE) == EVP_CIPH_CFB_MODE
426 || (ctx->cipher->flags & EVP_CIPH_MODE) == EVP_CIPH_OFB_MODE
427 || enc)
428 ret=aesni_set_encrypt_key(user_key, ctx->key_len * 8, key);
429 else
430 ret=aesni_set_decrypt_key(user_key, ctx->key_len * 8, key);
431
432 if(ret < 0) {
433 EVPerr(EVP_F_AESNI_INIT_KEY,EVP_R_AES_KEY_SETUP_FAILED);
434 return 0;
435 }
436
437 return 1;
438}
439
440static int aesni_cipher_ecb(EVP_CIPHER_CTX *ctx, unsigned char *out,
441 const unsigned char *in, size_t inl)
442{ AES_KEY *key = AESNI_ALIGN(ctx->cipher_data);
443 aesni_ecb_encrypt(in, out, inl, key, ctx->encrypt);
444 return 1;
445}
446static int aesni_cipher_cbc(EVP_CIPHER_CTX *ctx, unsigned char *out,
447 const unsigned char *in, size_t inl)
448{ AES_KEY *key = AESNI_ALIGN(ctx->cipher_data);
449 aesni_cbc_encrypt(in, out, inl, key,
450 ctx->iv, ctx->encrypt);
451 return 1;
452}
453static int aesni_cipher_cfb(EVP_CIPHER_CTX *ctx, unsigned char *out,
454 const unsigned char *in, size_t inl)
455{ AES_KEY *key = AESNI_ALIGN(ctx->cipher_data);
456
457 aesni_cfb128_encrypt(in, out, inl, key, ctx->iv,
458 &ctx->num, ctx->encrypt);
459 return 1;
460}
461static int aesni_cipher_ofb(EVP_CIPHER_CTX *ctx, unsigned char *out,
462 const unsigned char *in, size_t inl)
463{ AES_KEY *key = AESNI_ALIGN(ctx->cipher_data);
464 aesni_ofb128_encrypt(in, out, inl, key, ctx->iv, &ctx->num);
465 return 1;
466}
467
468#define AES_BLOCK_SIZE 16
469
470#define EVP_CIPHER_block_size_ECB AES_BLOCK_SIZE
471#define EVP_CIPHER_block_size_CBC AES_BLOCK_SIZE
472#define EVP_CIPHER_block_size_OFB 1
473#define EVP_CIPHER_block_size_CFB 1
474
475/* Declaring so many ciphers by hand would be a pain.
476 Instead introduce a bit of preprocessor magic :-) */
477#define DECLARE_AES_EVP(ksize,lmode,umode) \
478static const EVP_CIPHER aesni_##ksize##_##lmode = { \
479 NID_aes_##ksize##_##lmode, \
480 EVP_CIPHER_block_size_##umode, \
481 ksize / 8, \
482 AES_BLOCK_SIZE, \
483 0 | EVP_CIPH_##umode##_MODE, \
484 aesni_init_key, \
485 aesni_cipher_##lmode, \
486 NULL, \
487 sizeof(AESNI_KEY), \
488 EVP_CIPHER_set_asn1_iv, \
489 EVP_CIPHER_get_asn1_iv, \
490 NULL, \
491 NULL \
492}
493
494DECLARE_AES_EVP(128,ecb,ECB);
495DECLARE_AES_EVP(128,cbc,CBC);
496DECLARE_AES_EVP(128,cfb,CFB);
497DECLARE_AES_EVP(128,ofb,OFB);
498
499DECLARE_AES_EVP(192,ecb,ECB);
500DECLARE_AES_EVP(192,cbc,CBC);
501DECLARE_AES_EVP(192,cfb,CFB);
502DECLARE_AES_EVP(192,ofb,OFB);
503
504DECLARE_AES_EVP(256,ecb,ECB);
505DECLARE_AES_EVP(256,cbc,CBC);
506DECLARE_AES_EVP(256,cfb,CFB);
507DECLARE_AES_EVP(256,ofb,OFB);
508
509static int
510aesni_ciphers (ENGINE *e, const EVP_CIPHER **cipher,
511 const int **nids, int nid)
512{
513 /* No specific cipher => return a list of supported nids ... */
514 if (!cipher) {
515 *nids = aesni_cipher_nids;
516 return aesni_cipher_nids_num;
517 }
518
519 /* ... or the requested "cipher" otherwise */
520 switch (nid) {
521 case NID_aes_128_ecb:
522 *cipher = &aesni_128_ecb;
523 break;
524 case NID_aes_128_cbc:
525 *cipher = &aesni_128_cbc;
526 break;
527 case NID_aes_128_cfb:
528 *cipher = &aesni_128_cfb;
529 break;
530 case NID_aes_128_ofb:
531 *cipher = &aesni_128_ofb;
532 break;
533
534 case NID_aes_192_ecb:
535 *cipher = &aesni_192_ecb;
536 break;
537 case NID_aes_192_cbc:
538 *cipher = &aesni_192_cbc;
539 break;
540 case NID_aes_192_cfb:
541 *cipher = &aesni_192_cfb;
542 break;
543 case NID_aes_192_ofb:
544 *cipher = &aesni_192_ofb;
545 break;
546
547 case NID_aes_256_ecb:
548 *cipher = &aesni_256_ecb;
549 break;
550 case NID_aes_256_cbc:
551 *cipher = &aesni_256_cbc;
552 break;
553 case NID_aes_256_cfb:
554 *cipher = &aesni_256_cfb;
555 break;
556 case NID_aes_256_ofb:
557 *cipher = &aesni_256_ofb;
558 break;
559
560 default:
561 /* Sorry, we don't support this NID */
562 *cipher = NULL;
563 return 0;
564 }
565 return 1;
566}
567
568#endif /* COMPILE_HW_AESNI */
569#endif /* !defined(OPENSSL_NO_HW) && !defined(OPENSSL_NO_HW_AESNI) && !defined(OPENSSL_NO_AES) */
570
diff --git a/src/lib/libcrypto/engine/hw_cswift_err.h b/src/lib/libcrypto/engine/eng_all.c
index 7120c3216f..79d1f2beff 100644
--- a/src/lib/libcrypto/engine/hw_cswift_err.h
+++ b/src/lib/libcrypto/engine/eng_all.c
@@ -1,5 +1,9 @@
1/* crypto/engine/eng_all.c -*- mode: C; c-file-style: "eay" -*- */
2/* Written by Richard Levitte <richard@levitte.org> for the OpenSSL
3 * project 2000.
4 */
1/* ==================================================================== 5/* ====================================================================
2 * Copyright (c) 2001 The OpenSSL Project. All rights reserved. 6 * Copyright (c) 2000-2001 The OpenSSL Project. All rights reserved.
3 * 7 *
4 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions 9 * modification, are permitted provided that the following conditions
@@ -16,12 +20,12 @@
16 * 3. All advertising materials mentioning features or use of this 20 * 3. All advertising materials mentioning features or use of this
17 * software must display the following acknowledgment: 21 * software must display the following acknowledgment:
18 * "This product includes software developed by the OpenSSL Project 22 * "This product includes software developed by the OpenSSL Project
19 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
20 * 24 *
21 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
22 * endorse or promote products derived from this software without 26 * endorse or promote products derived from this software without
23 * prior written permission. For written permission, please contact 27 * prior written permission. For written permission, please contact
24 * openssl-core@openssl.org. 28 * licensing@OpenSSL.org.
25 * 29 *
26 * 5. Products derived from this software may not be called "OpenSSL" 30 * 5. Products derived from this software may not be called "OpenSSL"
27 * nor may "OpenSSL" appear in their names without prior written 31 * nor may "OpenSSL" appear in their names without prior written
@@ -30,7 +34,7 @@
30 * 6. Redistributions of any form whatsoever must retain the following 34 * 6. Redistributions of any form whatsoever must retain the following
31 * acknowledgment: 35 * acknowledgment:
32 * "This product includes software developed by the OpenSSL Project 36 * "This product includes software developed by the OpenSSL Project
33 * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
34 * 38 *
35 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
36 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
@@ -52,42 +56,76 @@
52 * 56 *
53 */ 57 */
54 58
55#ifndef HEADER_CSWIFT_ERR_H 59#include "cryptlib.h"
56#define HEADER_CSWIFT_ERR_H 60#include "eng_int.h"
57
58/* BEGIN ERROR CODES */
59/* The following lines are auto generated by the script mkerr.pl. Any changes
60 * made after this point may be overwritten when the script is next run.
61 */
62static void ERR_load_CSWIFT_strings(void);
63static void ERR_unload_CSWIFT_strings(void);
64static void ERR_CSWIFT_error(int function, int reason, char *file, int line);
65#define CSWIFTerr(f,r) ERR_CSWIFT_error((f),(r),__FILE__,__LINE__)
66 61
67/* Error codes for the CSWIFT functions. */ 62void ENGINE_load_builtin_engines(void)
63 {
64#if 0
65 /* There's no longer any need for an "openssl" ENGINE unless, one day,
66 * it is the *only* way for standard builtin implementations to be be
67 * accessed (ie. it would be possible to statically link binaries with
68 * *no* builtin implementations). */
69 ENGINE_load_openssl();
70#endif
71#if !defined(OPENSSL_NO_HW) && (defined(__OpenBSD__) || defined(__FreeBSD__) || defined(HAVE_CRYPTODEV))
72 ENGINE_load_cryptodev();
73#endif
68 74
69/* Function codes. */ 75#if !defined(OPENSSL_NO_HW) && !defined(OPENSSL_NO_HW_AESNI)
70#define CSWIFT_F_CSWIFT_CTRL 100 76 ENGINE_load_aesni();
71#define CSWIFT_F_CSWIFT_DSA_SIGN 101 77#endif
72#define CSWIFT_F_CSWIFT_DSA_VERIFY 102
73#define CSWIFT_F_CSWIFT_FINISH 103
74#define CSWIFT_F_CSWIFT_INIT 104
75#define CSWIFT_F_CSWIFT_MOD_EXP 105
76#define CSWIFT_F_CSWIFT_MOD_EXP_CRT 106
77#define CSWIFT_F_CSWIFT_RSA_MOD_EXP 107
78 78
79/* Reason codes. */ 79 ENGINE_load_dynamic();
80#define CSWIFT_R_ALREADY_LOADED 100 80#ifndef OPENSSL_NO_STATIC_ENGINE
81#define CSWIFT_R_BAD_KEY_SIZE 101 81#ifndef OPENSSL_NO_HW
82#define CSWIFT_R_BN_CTX_FULL 102 82#ifndef OPENSSL_NO_HW_4758_CCA
83#define CSWIFT_R_BN_EXPAND_FAIL 103 83 ENGINE_load_4758cca();
84#define CSWIFT_R_CTRL_COMMAND_NOT_IMPLEMENTED 104 84#endif
85#define CSWIFT_R_MISSING_KEY_COMPONENTS 105 85#ifndef OPENSSL_NO_HW_AEP
86#define CSWIFT_R_NOT_LOADED 106 86 ENGINE_load_aep();
87#define CSWIFT_R_REQUEST_FAILED 107 87#endif
88#define CSWIFT_R_UNIT_FAILURE 108 88#ifndef OPENSSL_NO_HW_ATALLA
89 ENGINE_load_atalla();
90#endif
91#ifndef OPENSSL_NO_HW_CSWIFT
92 ENGINE_load_cswift();
93#endif
94#ifndef OPENSSL_NO_HW_NCIPHER
95 ENGINE_load_chil();
96#endif
97#ifndef OPENSSL_NO_HW_NURON
98 ENGINE_load_nuron();
99#endif
100#ifndef OPENSSL_NO_HW_SUREWARE
101 ENGINE_load_sureware();
102#endif
103#ifndef OPENSSL_NO_HW_UBSEC
104 ENGINE_load_ubsec();
105#endif
106#ifndef OPENSSL_NO_HW_PADLOCK
107 ENGINE_load_padlock();
108#endif
109#endif
110#ifndef OPENSSL_NO_GOST
111 ENGINE_load_gost();
112#endif
113#ifndef OPENSSL_NO_GMP
114 ENGINE_load_gmp();
115#endif
116#if defined(OPENSSL_SYS_WIN32) && !defined(OPENSSL_NO_CAPIENG)
117 ENGINE_load_capi();
118#endif
119#endif
120 }
89 121
90#ifdef __cplusplus 122#if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(HAVE_CRYPTODEV)
123void ENGINE_setup_bsd_cryptodev(void) {
124 static int bsd_cryptodev_default_loaded = 0;
125 if (!bsd_cryptodev_default_loaded) {
126 ENGINE_load_cryptodev();
127 ENGINE_register_all_complete();
128 }
129 bsd_cryptodev_default_loaded=1;
91} 130}
92#endif 131#endif
93#endif
diff --git a/src/lib/libcrypto/engine/eng_cnf.c b/src/lib/libcrypto/engine/eng_cnf.c
new file mode 100644
index 0000000000..95c4070015
--- /dev/null
+++ b/src/lib/libcrypto/engine/eng_cnf.c
@@ -0,0 +1,259 @@
1/* eng_cnf.c */
2/* Written by Stephen Henson (steve@openssl.org) for the OpenSSL
3 * project 2001.
4 */
5/* ====================================================================
6 * Copyright (c) 2001 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 "eng_int.h"
60#include <openssl/conf.h>
61
62/* #define ENGINE_CONF_DEBUG */
63
64/* ENGINE config module */
65
66static char *skip_dot(char *name)
67 {
68 char *p;
69 p = strchr(name, '.');
70 if (p)
71 return p + 1;
72 return name;
73 }
74
75static STACK_OF(ENGINE) *initialized_engines = NULL;
76
77static int int_engine_init(ENGINE *e)
78 {
79 if (!ENGINE_init(e))
80 return 0;
81 if (!initialized_engines)
82 initialized_engines = sk_ENGINE_new_null();
83 if (!initialized_engines || !sk_ENGINE_push(initialized_engines, e))
84 {
85 ENGINE_finish(e);
86 return 0;
87 }
88 return 1;
89 }
90
91
92static int int_engine_configure(char *name, char *value, const CONF *cnf)
93 {
94 int i;
95 int ret = 0;
96 long do_init = -1;
97 STACK_OF(CONF_VALUE) *ecmds;
98 CONF_VALUE *ecmd = NULL;
99 char *ctrlname, *ctrlvalue;
100 ENGINE *e = NULL;
101 int soft = 0;
102
103 name = skip_dot(name);
104#ifdef ENGINE_CONF_DEBUG
105 fprintf(stderr, "Configuring engine %s\n", name);
106#endif
107 /* Value is a section containing ENGINE commands */
108 ecmds = NCONF_get_section(cnf, value);
109
110 if (!ecmds)
111 {
112 ENGINEerr(ENGINE_F_INT_ENGINE_CONFIGURE, ENGINE_R_ENGINE_SECTION_ERROR);
113 return 0;
114 }
115
116 for (i = 0; i < sk_CONF_VALUE_num(ecmds); i++)
117 {
118 ecmd = sk_CONF_VALUE_value(ecmds, i);
119 ctrlname = skip_dot(ecmd->name);
120 ctrlvalue = ecmd->value;
121#ifdef ENGINE_CONF_DEBUG
122 fprintf(stderr, "ENGINE conf: doing ctrl(%s,%s)\n", ctrlname, ctrlvalue);
123#endif
124
125 /* First handle some special pseudo ctrls */
126
127 /* Override engine name to use */
128 if (!strcmp(ctrlname, "engine_id"))
129 name = ctrlvalue;
130 else if (!strcmp(ctrlname, "soft_load"))
131 soft = 1;
132 /* Load a dynamic ENGINE */
133 else if (!strcmp(ctrlname, "dynamic_path"))
134 {
135 e = ENGINE_by_id("dynamic");
136 if (!e)
137 goto err;
138 if (!ENGINE_ctrl_cmd_string(e, "SO_PATH", ctrlvalue, 0))
139 goto err;
140 if (!ENGINE_ctrl_cmd_string(e, "LIST_ADD", "2", 0))
141 goto err;
142 if (!ENGINE_ctrl_cmd_string(e, "LOAD", NULL, 0))
143 goto err;
144 }
145 /* ... add other pseudos here ... */
146 else
147 {
148 /* At this point we need an ENGINE structural reference
149 * if we don't already have one.
150 */
151 if (!e)
152 {
153 e = ENGINE_by_id(name);
154 if (!e && soft)
155 {
156 ERR_clear_error();
157 return 1;
158 }
159 if (!e)
160 goto err;
161 }
162 /* Allow "EMPTY" to mean no value: this allows a valid
163 * "value" to be passed to ctrls of type NO_INPUT
164 */
165 if (!strcmp(ctrlvalue, "EMPTY"))
166 ctrlvalue = NULL;
167 if (!strcmp(ctrlname, "init"))
168 {
169 if (!NCONF_get_number_e(cnf, value, "init", &do_init))
170 goto err;
171 if (do_init == 1)
172 {
173 if (!int_engine_init(e))
174 goto err;
175 }
176 else if (do_init != 0)
177 {
178 ENGINEerr(ENGINE_F_INT_ENGINE_CONFIGURE, ENGINE_R_INVALID_INIT_VALUE);
179 goto err;
180 }
181 }
182 else if (!strcmp(ctrlname, "default_algorithms"))
183 {
184 if (!ENGINE_set_default_string(e, ctrlvalue))
185 goto err;
186 }
187 else if (!ENGINE_ctrl_cmd_string(e,
188 ctrlname, ctrlvalue, 0))
189 goto err;
190 }
191
192
193
194 }
195 if (e && (do_init == -1) && !int_engine_init(e))
196 {
197 ecmd = NULL;
198 goto err;
199 }
200 ret = 1;
201 err:
202 if (ret != 1)
203 {
204 ENGINEerr(ENGINE_F_INT_ENGINE_CONFIGURE, ENGINE_R_ENGINE_CONFIGURATION_ERROR);
205 if (ecmd)
206 ERR_add_error_data(6, "section=", ecmd->section,
207 ", name=", ecmd->name,
208 ", value=", ecmd->value);
209 }
210 if (e)
211 ENGINE_free(e);
212 return ret;
213 }
214
215
216static int int_engine_module_init(CONF_IMODULE *md, const CONF *cnf)
217 {
218 STACK_OF(CONF_VALUE) *elist;
219 CONF_VALUE *cval;
220 int i;
221#ifdef ENGINE_CONF_DEBUG
222 fprintf(stderr, "Called engine module: name %s, value %s\n",
223 CONF_imodule_get_name(md), CONF_imodule_get_value(md));
224#endif
225 /* Value is a section containing ENGINEs to configure */
226 elist = NCONF_get_section(cnf, CONF_imodule_get_value(md));
227
228 if (!elist)
229 {
230 ENGINEerr(ENGINE_F_INT_ENGINE_MODULE_INIT, ENGINE_R_ENGINES_SECTION_ERROR);
231 return 0;
232 }
233
234 for (i = 0; i < sk_CONF_VALUE_num(elist); i++)
235 {
236 cval = sk_CONF_VALUE_value(elist, i);
237 if (!int_engine_configure(cval->name, cval->value, cnf))
238 return 0;
239 }
240
241 return 1;
242 }
243
244static void int_engine_module_finish(CONF_IMODULE *md)
245 {
246 ENGINE *e;
247 while ((e = sk_ENGINE_pop(initialized_engines)))
248 ENGINE_finish(e);
249 sk_ENGINE_free(initialized_engines);
250 initialized_engines = NULL;
251 }
252
253
254void ENGINE_add_conf_module(void)
255 {
256 CONF_module_add("engines",
257 int_engine_module_init,
258 int_engine_module_finish);
259 }
diff --git a/src/lib/libcrypto/engine/eng_cryptodev.c b/src/lib/libcrypto/engine/eng_cryptodev.c
index 5a715aca4f..10b3856b4e 100644
--- a/src/lib/libcrypto/engine/eng_cryptodev.c
+++ b/src/lib/libcrypto/engine/eng_cryptodev.c
@@ -32,7 +32,7 @@
32#include <openssl/bn.h> 32#include <openssl/bn.h>
33 33
34#if (defined(__unix__) || defined(unix)) && !defined(USG) && \ 34#if (defined(__unix__) || defined(unix)) && !defined(USG) && \
35 (defined(OpenBSD) || defined(__FreeBSD__)) 35 (defined(__OpenBSD__) || defined(__FreeBSD__))
36#include <sys/param.h> 36#include <sys/param.h>
37# if (OpenBSD >= 200112) || ((__FreeBSD_version >= 470101 && __FreeBSD_version < 500000) || __FreeBSD_version >= 500041) 37# if (OpenBSD >= 200112) || ((__FreeBSD_version >= 470101 && __FreeBSD_version < 500000) || __FreeBSD_version >= 500041)
38# define HAVE_CRYPTODEV 38# define HAVE_CRYPTODEV
@@ -79,6 +79,8 @@ struct dev_crypto_state {
79 unsigned char digest_res[HASH_MAX_LEN]; 79 unsigned char digest_res[HASH_MAX_LEN];
80 char *mac_data; 80 char *mac_data;
81 int mac_len; 81 int mac_len;
82
83 int copy;
82#endif 84#endif
83}; 85};
84 86
@@ -149,7 +151,6 @@ static struct {
149 { CRYPTO_AES_CBC, NID_aes_256_cbc, 16, 32, }, 151 { CRYPTO_AES_CBC, NID_aes_256_cbc, 16, 32, },
150 { CRYPTO_BLF_CBC, NID_bf_cbc, 8, 16, }, 152 { CRYPTO_BLF_CBC, NID_bf_cbc, 8, 16, },
151 { CRYPTO_CAST_CBC, NID_cast5_cbc, 8, 16, }, 153 { CRYPTO_CAST_CBC, NID_cast5_cbc, 8, 16, },
152 { CRYPTO_SKIPJACK_CBC, NID_undef, 0, 0, },
153 { 0, NID_undef, 0, 0, }, 154 { 0, NID_undef, 0, 0, },
154}; 155};
155 156
@@ -198,7 +199,6 @@ get_dev_crypto(void)
198 199
199 if ((fd = open_dev_crypto()) == -1) 200 if ((fd = open_dev_crypto()) == -1)
200 return (-1); 201 return (-1);
201#ifndef CRIOGET_NOT_NEEDED
202 if (ioctl(fd, CRIOGET, &retfd) == -1) 202 if (ioctl(fd, CRIOGET, &retfd) == -1)
203 return (-1); 203 return (-1);
204 204
@@ -207,19 +207,9 @@ get_dev_crypto(void)
207 close(retfd); 207 close(retfd);
208 return (-1); 208 return (-1);
209 } 209 }
210#else
211 retfd = fd;
212#endif
213 return (retfd); 210 return (retfd);
214} 211}
215 212
216static void put_dev_crypto(int fd)
217{
218#ifndef CRIOGET_NOT_NEEDED
219 close(fd);
220#endif
221}
222
223/* Caching version for asym operations */ 213/* Caching version for asym operations */
224static int 214static int
225get_asym_dev_crypto(void) 215get_asym_dev_crypto(void)
@@ -261,7 +251,7 @@ get_cryptodev_ciphers(const int **cnids)
261 ioctl(fd, CIOCFSESSION, &sess.ses) != -1) 251 ioctl(fd, CIOCFSESSION, &sess.ses) != -1)
262 nids[count++] = ciphers[i].nid; 252 nids[count++] = ciphers[i].nid;
263 } 253 }
264 put_dev_crypto(fd); 254 close(fd);
265 255
266 if (count > 0) 256 if (count > 0)
267 *cnids = nids; 257 *cnids = nids;
@@ -300,7 +290,7 @@ get_cryptodev_digests(const int **cnids)
300 ioctl(fd, CIOCFSESSION, &sess.ses) != -1) 290 ioctl(fd, CIOCFSESSION, &sess.ses) != -1)
301 nids[count++] = digests[i].nid; 291 nids[count++] = digests[i].nid;
302 } 292 }
303 put_dev_crypto(fd); 293 close(fd);
304 294
305 if (count > 0) 295 if (count > 0)
306 *cnids = nids; 296 *cnids = nids;
@@ -445,7 +435,7 @@ cryptodev_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
445 sess->cipher = cipher; 435 sess->cipher = cipher;
446 436
447 if (ioctl(state->d_fd, CIOCGSESSION, sess) == -1) { 437 if (ioctl(state->d_fd, CIOCGSESSION, sess) == -1) {
448 put_dev_crypto(state->d_fd); 438 close(state->d_fd);
449 state->d_fd = -1; 439 state->d_fd = -1;
450 return (0); 440 return (0);
451 } 441 }
@@ -482,7 +472,7 @@ cryptodev_cleanup(EVP_CIPHER_CTX *ctx)
482 } else { 472 } else {
483 ret = 1; 473 ret = 1;
484 } 474 }
485 put_dev_crypto(state->d_fd); 475 close(state->d_fd);
486 state->d_fd = -1; 476 state->d_fd = -1;
487 477
488 return (ret); 478 return (ret);
@@ -695,7 +685,7 @@ static int cryptodev_digest_init(EVP_MD_CTX *ctx)
695 sess->mac = digest; 685 sess->mac = digest;
696 686
697 if (ioctl(state->d_fd, CIOCGSESSION, sess) < 0) { 687 if (ioctl(state->d_fd, CIOCGSESSION, sess) < 0) {
698 put_dev_crypto(state->d_fd); 688 close(state->d_fd);
699 state->d_fd = -1; 689 state->d_fd = -1;
700 printf("cryptodev_digest_init: Open session failed\n"); 690 printf("cryptodev_digest_init: Open session failed\n");
701 return (0); 691 return (0);
@@ -767,12 +757,14 @@ static int cryptodev_digest_final(EVP_MD_CTX *ctx, unsigned char *md)
767 if (! (ctx->flags & EVP_MD_CTX_FLAG_ONESHOT) ) { 757 if (! (ctx->flags & EVP_MD_CTX_FLAG_ONESHOT) ) {
768 /* if application doesn't support one buffer */ 758 /* if application doesn't support one buffer */
769 memset(&cryp, 0, sizeof(cryp)); 759 memset(&cryp, 0, sizeof(cryp));
760
770 cryp.ses = sess->ses; 761 cryp.ses = sess->ses;
771 cryp.flags = 0; 762 cryp.flags = 0;
772 cryp.len = state->mac_len; 763 cryp.len = state->mac_len;
773 cryp.src = state->mac_data; 764 cryp.src = state->mac_data;
774 cryp.dst = NULL; 765 cryp.dst = NULL;
775 cryp.mac = (caddr_t)md; 766 cryp.mac = (caddr_t)md;
767
776 if (ioctl(state->d_fd, CIOCCRYPT, &cryp) < 0) { 768 if (ioctl(state->d_fd, CIOCCRYPT, &cryp) < 0) {
777 printf("cryptodev_digest_final: digest failed\n"); 769 printf("cryptodev_digest_final: digest failed\n");
778 return (0); 770 return (0);
@@ -793,9 +785,6 @@ static int cryptodev_digest_cleanup(EVP_MD_CTX *ctx)
793 struct dev_crypto_state *state = ctx->md_data; 785 struct dev_crypto_state *state = ctx->md_data;
794 struct session_op *sess = &state->d_sess; 786 struct session_op *sess = &state->d_sess;
795 787
796 if (state == NULL)
797 return 0;
798
799 if (state->d_fd < 0) { 788 if (state->d_fd < 0) {
800 printf("cryptodev_digest_cleanup: illegal input\n"); 789 printf("cryptodev_digest_cleanup: illegal input\n");
801 return (0); 790 return (0);
@@ -807,13 +796,16 @@ static int cryptodev_digest_cleanup(EVP_MD_CTX *ctx)
807 state->mac_len = 0; 796 state->mac_len = 0;
808 } 797 }
809 798
799 if (state->copy)
800 return 1;
801
810 if (ioctl(state->d_fd, CIOCFSESSION, &sess->ses) < 0) { 802 if (ioctl(state->d_fd, CIOCFSESSION, &sess->ses) < 0) {
811 printf("cryptodev_digest_cleanup: failed to close session\n"); 803 printf("cryptodev_digest_cleanup: failed to close session\n");
812 ret = 0; 804 ret = 0;
813 } else { 805 } else {
814 ret = 1; 806 ret = 1;
815 } 807 }
816 put_dev_crypto(state->d_fd); 808 close(state->d_fd);
817 state->d_fd = -1; 809 state->d_fd = -1;
818 810
819 return (ret); 811 return (ret);
@@ -823,40 +815,16 @@ static int cryptodev_digest_copy(EVP_MD_CTX *to,const EVP_MD_CTX *from)
823{ 815{
824 struct dev_crypto_state *fstate = from->md_data; 816 struct dev_crypto_state *fstate = from->md_data;
825 struct dev_crypto_state *dstate = to->md_data; 817 struct dev_crypto_state *dstate = to->md_data;
826 struct session_op *sess;
827 int digest;
828
829 if (dstate == NULL || fstate == NULL)
830 return 1;
831
832 memcpy(dstate, fstate, sizeof(struct dev_crypto_state));
833
834 sess = &dstate->d_sess;
835
836 digest = digest_nid_to_cryptodev(to->digest->type);
837
838 sess->mackey = dstate->dummy_mac_key;
839 sess->mackeylen = digest_key_length(to->digest->type);
840 sess->mac = digest;
841 818
842 dstate->d_fd = get_dev_crypto(); 819 memcpy(dstate, fstate, sizeof(struct dev_crypto_state));
843
844 if (ioctl(dstate->d_fd, CIOCGSESSION, sess) < 0) {
845 put_dev_crypto(dstate->d_fd);
846 dstate->d_fd = -1;
847 printf("cryptodev_digest_init: Open session failed\n");
848 return (0);
849 }
850 820
851 if (fstate->mac_len != 0) { 821 if (fstate->mac_len != 0) {
852 if (fstate->mac_data != NULL) 822 dstate->mac_data = OPENSSL_malloc(fstate->mac_len);
853 { 823 memcpy(dstate->mac_data, fstate->mac_data, fstate->mac_len);
854 dstate->mac_data = OPENSSL_malloc(fstate->mac_len);
855 memcpy(dstate->mac_data, fstate->mac_data, fstate->mac_len);
856 dstate->mac_len = fstate->mac_len;
857 }
858 } 824 }
859 825
826 dstate->copy = 1;
827
860 return 1; 828 return 1;
861} 829}
862 830
@@ -1378,11 +1346,11 @@ ENGINE_load_cryptodev(void)
1378 * find out what asymmetric crypto algorithms we support 1346 * find out what asymmetric crypto algorithms we support
1379 */ 1347 */
1380 if (ioctl(fd, CIOCASYMFEAT, &cryptodev_asymfeat) == -1) { 1348 if (ioctl(fd, CIOCASYMFEAT, &cryptodev_asymfeat) == -1) {
1381 put_dev_crypto(fd); 1349 close(fd);
1382 ENGINE_free(engine); 1350 ENGINE_free(engine);
1383 return; 1351 return;
1384 } 1352 }
1385 put_dev_crypto(fd); 1353 close(fd);
1386 1354
1387 if (!ENGINE_set_id(engine, "cryptodev") || 1355 if (!ENGINE_set_id(engine, "cryptodev") ||
1388 !ENGINE_set_name(engine, "BSD cryptodev engine") || 1356 !ENGINE_set_name(engine, "BSD cryptodev engine") ||
diff --git a/src/lib/libcrypto/engine/eng_ctrl.c b/src/lib/libcrypto/engine/eng_ctrl.c
new file mode 100644
index 0000000000..5ce25d92ec
--- /dev/null
+++ b/src/lib/libcrypto/engine/eng_ctrl.c
@@ -0,0 +1,389 @@
1/* crypto/engine/eng_ctrl.c */
2/* ====================================================================
3 * Copyright (c) 1999-2001 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 * licensing@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#include "eng_int.h"
57
58/* When querying a ENGINE-specific control command's 'description', this string
59 * is used if the ENGINE_CMD_DEFN has cmd_desc set to NULL. */
60static const char *int_no_description = "";
61
62/* These internal functions handle 'CMD'-related control commands when the
63 * ENGINE in question has asked us to take care of it (ie. the ENGINE did not
64 * set the ENGINE_FLAGS_MANUAL_CMD_CTRL flag. */
65
66static int int_ctrl_cmd_is_null(const ENGINE_CMD_DEFN *defn)
67 {
68 if((defn->cmd_num == 0) || (defn->cmd_name == NULL))
69 return 1;
70 return 0;
71 }
72
73static int int_ctrl_cmd_by_name(const ENGINE_CMD_DEFN *defn, const char *s)
74 {
75 int idx = 0;
76 while(!int_ctrl_cmd_is_null(defn) && (strcmp(defn->cmd_name, s) != 0))
77 {
78 idx++;
79 defn++;
80 }
81 if(int_ctrl_cmd_is_null(defn))
82 /* The given name wasn't found */
83 return -1;
84 return idx;
85 }
86
87static int int_ctrl_cmd_by_num(const ENGINE_CMD_DEFN *defn, unsigned int num)
88 {
89 int idx = 0;
90 /* NB: It is stipulated that 'cmd_defn' lists are ordered by cmd_num. So
91 * our searches don't need to take any longer than necessary. */
92 while(!int_ctrl_cmd_is_null(defn) && (defn->cmd_num < num))
93 {
94 idx++;
95 defn++;
96 }
97 if(defn->cmd_num == num)
98 return idx;
99 /* The given cmd_num wasn't found */
100 return -1;
101 }
102
103static int int_ctrl_helper(ENGINE *e, int cmd, long i, void *p,
104 void (*f)(void))
105 {
106 int idx;
107 char *s = (char *)p;
108 /* Take care of the easy one first (eg. it requires no searches) */
109 if(cmd == ENGINE_CTRL_GET_FIRST_CMD_TYPE)
110 {
111 if((e->cmd_defns == NULL) || int_ctrl_cmd_is_null(e->cmd_defns))
112 return 0;
113 return e->cmd_defns->cmd_num;
114 }
115 /* One or two commands require that "p" be a valid string buffer */
116 if((cmd == ENGINE_CTRL_GET_CMD_FROM_NAME) ||
117 (cmd == ENGINE_CTRL_GET_NAME_FROM_CMD) ||
118 (cmd == ENGINE_CTRL_GET_DESC_FROM_CMD))
119 {
120 if(s == NULL)
121 {
122 ENGINEerr(ENGINE_F_INT_CTRL_HELPER,
123 ERR_R_PASSED_NULL_PARAMETER);
124 return -1;
125 }
126 }
127 /* Now handle cmd_name -> cmd_num conversion */
128 if(cmd == ENGINE_CTRL_GET_CMD_FROM_NAME)
129 {
130 if((e->cmd_defns == NULL) || ((idx = int_ctrl_cmd_by_name(
131 e->cmd_defns, s)) < 0))
132 {
133 ENGINEerr(ENGINE_F_INT_CTRL_HELPER,
134 ENGINE_R_INVALID_CMD_NAME);
135 return -1;
136 }
137 return e->cmd_defns[idx].cmd_num;
138 }
139 /* For the rest of the commands, the 'long' argument must specify a
140 * valie command number - so we need to conduct a search. */
141 if((e->cmd_defns == NULL) || ((idx = int_ctrl_cmd_by_num(e->cmd_defns,
142 (unsigned int)i)) < 0))
143 {
144 ENGINEerr(ENGINE_F_INT_CTRL_HELPER,
145 ENGINE_R_INVALID_CMD_NUMBER);
146 return -1;
147 }
148 /* Now the logic splits depending on command type */
149 switch(cmd)
150 {
151 case ENGINE_CTRL_GET_NEXT_CMD_TYPE:
152 idx++;
153 if(int_ctrl_cmd_is_null(e->cmd_defns + idx))
154 /* end-of-list */
155 return 0;
156 else
157 return e->cmd_defns[idx].cmd_num;
158 case ENGINE_CTRL_GET_NAME_LEN_FROM_CMD:
159 return strlen(e->cmd_defns[idx].cmd_name);
160 case ENGINE_CTRL_GET_NAME_FROM_CMD:
161 return BIO_snprintf(s,strlen(e->cmd_defns[idx].cmd_name) + 1,
162 "%s", e->cmd_defns[idx].cmd_name);
163 case ENGINE_CTRL_GET_DESC_LEN_FROM_CMD:
164 if(e->cmd_defns[idx].cmd_desc)
165 return strlen(e->cmd_defns[idx].cmd_desc);
166 return strlen(int_no_description);
167 case ENGINE_CTRL_GET_DESC_FROM_CMD:
168 if(e->cmd_defns[idx].cmd_desc)
169 return BIO_snprintf(s,
170 strlen(e->cmd_defns[idx].cmd_desc) + 1,
171 "%s", e->cmd_defns[idx].cmd_desc);
172 return BIO_snprintf(s, strlen(int_no_description) + 1,"%s",
173 int_no_description);
174 case ENGINE_CTRL_GET_CMD_FLAGS:
175 return e->cmd_defns[idx].cmd_flags;
176 }
177 /* Shouldn't really be here ... */
178 ENGINEerr(ENGINE_F_INT_CTRL_HELPER,ENGINE_R_INTERNAL_LIST_ERROR);
179 return -1;
180 }
181
182int ENGINE_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void))
183 {
184 int ctrl_exists, ref_exists;
185 if(e == NULL)
186 {
187 ENGINEerr(ENGINE_F_ENGINE_CTRL,ERR_R_PASSED_NULL_PARAMETER);
188 return 0;
189 }
190 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
191 ref_exists = ((e->struct_ref > 0) ? 1 : 0);
192 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
193 ctrl_exists = ((e->ctrl == NULL) ? 0 : 1);
194 if(!ref_exists)
195 {
196 ENGINEerr(ENGINE_F_ENGINE_CTRL,ENGINE_R_NO_REFERENCE);
197 return 0;
198 }
199 /* Intercept any "root-level" commands before trying to hand them on to
200 * ctrl() handlers. */
201 switch(cmd)
202 {
203 case ENGINE_CTRL_HAS_CTRL_FUNCTION:
204 return ctrl_exists;
205 case ENGINE_CTRL_GET_FIRST_CMD_TYPE:
206 case ENGINE_CTRL_GET_NEXT_CMD_TYPE:
207 case ENGINE_CTRL_GET_CMD_FROM_NAME:
208 case ENGINE_CTRL_GET_NAME_LEN_FROM_CMD:
209 case ENGINE_CTRL_GET_NAME_FROM_CMD:
210 case ENGINE_CTRL_GET_DESC_LEN_FROM_CMD:
211 case ENGINE_CTRL_GET_DESC_FROM_CMD:
212 case ENGINE_CTRL_GET_CMD_FLAGS:
213 if(ctrl_exists && !(e->flags & ENGINE_FLAGS_MANUAL_CMD_CTRL))
214 return int_ctrl_helper(e,cmd,i,p,f);
215 if(!ctrl_exists)
216 {
217 ENGINEerr(ENGINE_F_ENGINE_CTRL,ENGINE_R_NO_CONTROL_FUNCTION);
218 /* For these cmd-related functions, failure is indicated
219 * by a -1 return value (because 0 is used as a valid
220 * return in some places). */
221 return -1;
222 }
223 default:
224 break;
225 }
226 /* Anything else requires a ctrl() handler to exist. */
227 if(!ctrl_exists)
228 {
229 ENGINEerr(ENGINE_F_ENGINE_CTRL,ENGINE_R_NO_CONTROL_FUNCTION);
230 return 0;
231 }
232 return e->ctrl(e, cmd, i, p, f);
233 }
234
235int ENGINE_cmd_is_executable(ENGINE *e, int cmd)
236 {
237 int flags;
238 if((flags = ENGINE_ctrl(e, ENGINE_CTRL_GET_CMD_FLAGS, cmd, NULL, NULL)) < 0)
239 {
240 ENGINEerr(ENGINE_F_ENGINE_CMD_IS_EXECUTABLE,
241 ENGINE_R_INVALID_CMD_NUMBER);
242 return 0;
243 }
244 if(!(flags & ENGINE_CMD_FLAG_NO_INPUT) &&
245 !(flags & ENGINE_CMD_FLAG_NUMERIC) &&
246 !(flags & ENGINE_CMD_FLAG_STRING))
247 return 0;
248 return 1;
249 }
250
251int ENGINE_ctrl_cmd(ENGINE *e, const char *cmd_name,
252 long i, void *p, void (*f)(void), int cmd_optional)
253 {
254 int num;
255
256 if((e == NULL) || (cmd_name == NULL))
257 {
258 ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD,
259 ERR_R_PASSED_NULL_PARAMETER);
260 return 0;
261 }
262 if((e->ctrl == NULL) || ((num = ENGINE_ctrl(e,
263 ENGINE_CTRL_GET_CMD_FROM_NAME,
264 0, (void *)cmd_name, NULL)) <= 0))
265 {
266 /* If the command didn't *have* to be supported, we fake
267 * success. This allows certain settings to be specified for
268 * multiple ENGINEs and only require a change of ENGINE id
269 * (without having to selectively apply settings). Eg. changing
270 * from a hardware device back to the regular software ENGINE
271 * without editing the config file, etc. */
272 if(cmd_optional)
273 {
274 ERR_clear_error();
275 return 1;
276 }
277 ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD,
278 ENGINE_R_INVALID_CMD_NAME);
279 return 0;
280 }
281 /* Force the result of the control command to 0 or 1, for the reasons
282 * mentioned before. */
283 if (ENGINE_ctrl(e, num, i, p, f) > 0)
284 return 1;
285 return 0;
286 }
287
288int ENGINE_ctrl_cmd_string(ENGINE *e, const char *cmd_name, const char *arg,
289 int cmd_optional)
290 {
291 int num, flags;
292 long l;
293 char *ptr;
294 if((e == NULL) || (cmd_name == NULL))
295 {
296 ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING,
297 ERR_R_PASSED_NULL_PARAMETER);
298 return 0;
299 }
300 if((e->ctrl == NULL) || ((num = ENGINE_ctrl(e,
301 ENGINE_CTRL_GET_CMD_FROM_NAME,
302 0, (void *)cmd_name, NULL)) <= 0))
303 {
304 /* If the command didn't *have* to be supported, we fake
305 * success. This allows certain settings to be specified for
306 * multiple ENGINEs and only require a change of ENGINE id
307 * (without having to selectively apply settings). Eg. changing
308 * from a hardware device back to the regular software ENGINE
309 * without editing the config file, etc. */
310 if(cmd_optional)
311 {
312 ERR_clear_error();
313 return 1;
314 }
315 ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING,
316 ENGINE_R_INVALID_CMD_NAME);
317 return 0;
318 }
319 if(!ENGINE_cmd_is_executable(e, num))
320 {
321 ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING,
322 ENGINE_R_CMD_NOT_EXECUTABLE);
323 return 0;
324 }
325 if((flags = ENGINE_ctrl(e, ENGINE_CTRL_GET_CMD_FLAGS, num, NULL, NULL)) < 0)
326 {
327 /* Shouldn't happen, given that ENGINE_cmd_is_executable()
328 * returned success. */
329 ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING,
330 ENGINE_R_INTERNAL_LIST_ERROR);
331 return 0;
332 }
333 /* If the command takes no input, there must be no input. And vice
334 * versa. */
335 if(flags & ENGINE_CMD_FLAG_NO_INPUT)
336 {
337 if(arg != NULL)
338 {
339 ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING,
340 ENGINE_R_COMMAND_TAKES_NO_INPUT);
341 return 0;
342 }
343 /* We deliberately force the result of ENGINE_ctrl() to 0 or 1
344 * rather than returning it as "return data". This is to ensure
345 * usage of these commands is consistent across applications and
346 * that certain applications don't understand it one way, and
347 * others another. */
348 if(ENGINE_ctrl(e, num, 0, (void *)arg, NULL) > 0)
349 return 1;
350 return 0;
351 }
352 /* So, we require input */
353 if(arg == NULL)
354 {
355 ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING,
356 ENGINE_R_COMMAND_TAKES_INPUT);
357 return 0;
358 }
359 /* If it takes string input, that's easy */
360 if(flags & ENGINE_CMD_FLAG_STRING)
361 {
362 /* Same explanation as above */
363 if(ENGINE_ctrl(e, num, 0, (void *)arg, NULL) > 0)
364 return 1;
365 return 0;
366 }
367 /* If it doesn't take numeric either, then it is unsupported for use in
368 * a config-setting situation, which is what this function is for. This
369 * should never happen though, because ENGINE_cmd_is_executable() was
370 * used. */
371 if(!(flags & ENGINE_CMD_FLAG_NUMERIC))
372 {
373 ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING,
374 ENGINE_R_INTERNAL_LIST_ERROR);
375 return 0;
376 }
377 l = strtol(arg, &ptr, 10);
378 if((arg == ptr) || (*ptr != '\0'))
379 {
380 ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING,
381 ENGINE_R_ARGUMENT_IS_NOT_A_NUMBER);
382 return 0;
383 }
384 /* Force the result of the control command to 0 or 1, for the reasons
385 * mentioned before. */
386 if(ENGINE_ctrl(e, num, l, NULL, NULL) > 0)
387 return 1;
388 return 0;
389 }
diff --git a/src/lib/libcrypto/engine/eng_dyn.c b/src/lib/libcrypto/engine/eng_dyn.c
new file mode 100644
index 0000000000..807da7a5eb
--- /dev/null
+++ b/src/lib/libcrypto/engine/eng_dyn.c
@@ -0,0 +1,548 @@
1/* crypto/engine/eng_dyn.c */
2/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
3 * project 2001.
4 */
5/* ====================================================================
6 * Copyright (c) 1999-2001 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 "eng_int.h"
61#include <openssl/dso.h>
62
63/* Shared libraries implementing ENGINEs for use by the "dynamic" ENGINE loader
64 * should implement the hook-up functions with the following prototypes. */
65
66/* Our ENGINE handlers */
67static int dynamic_init(ENGINE *e);
68static int dynamic_finish(ENGINE *e);
69static int dynamic_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void));
70/* Predeclare our context type */
71typedef struct st_dynamic_data_ctx dynamic_data_ctx;
72/* The implementation for the important control command */
73static int dynamic_load(ENGINE *e, dynamic_data_ctx *ctx);
74
75#define DYNAMIC_CMD_SO_PATH ENGINE_CMD_BASE
76#define DYNAMIC_CMD_NO_VCHECK (ENGINE_CMD_BASE + 1)
77#define DYNAMIC_CMD_ID (ENGINE_CMD_BASE + 2)
78#define DYNAMIC_CMD_LIST_ADD (ENGINE_CMD_BASE + 3)
79#define DYNAMIC_CMD_DIR_LOAD (ENGINE_CMD_BASE + 4)
80#define DYNAMIC_CMD_DIR_ADD (ENGINE_CMD_BASE + 5)
81#define DYNAMIC_CMD_LOAD (ENGINE_CMD_BASE + 6)
82
83/* The constants used when creating the ENGINE */
84static const char *engine_dynamic_id = "dynamic";
85static const char *engine_dynamic_name = "Dynamic engine loading support";
86static const ENGINE_CMD_DEFN dynamic_cmd_defns[] = {
87 {DYNAMIC_CMD_SO_PATH,
88 "SO_PATH",
89 "Specifies the path to the new ENGINE shared library",
90 ENGINE_CMD_FLAG_STRING},
91 {DYNAMIC_CMD_NO_VCHECK,
92 "NO_VCHECK",
93 "Specifies to continue even if version checking fails (boolean)",
94 ENGINE_CMD_FLAG_NUMERIC},
95 {DYNAMIC_CMD_ID,
96 "ID",
97 "Specifies an ENGINE id name for loading",
98 ENGINE_CMD_FLAG_STRING},
99 {DYNAMIC_CMD_LIST_ADD,
100 "LIST_ADD",
101 "Whether to add a loaded ENGINE to the internal list (0=no,1=yes,2=mandatory)",
102 ENGINE_CMD_FLAG_NUMERIC},
103 {DYNAMIC_CMD_DIR_LOAD,
104 "DIR_LOAD",
105 "Specifies whether to load from 'DIR_ADD' directories (0=no,1=yes,2=mandatory)",
106 ENGINE_CMD_FLAG_NUMERIC},
107 {DYNAMIC_CMD_DIR_ADD,
108 "DIR_ADD",
109 "Adds a directory from which ENGINEs can be loaded",
110 ENGINE_CMD_FLAG_STRING},
111 {DYNAMIC_CMD_LOAD,
112 "LOAD",
113 "Load up the ENGINE specified by other settings",
114 ENGINE_CMD_FLAG_NO_INPUT},
115 {0, NULL, NULL, 0}
116 };
117static const ENGINE_CMD_DEFN dynamic_cmd_defns_empty[] = {
118 {0, NULL, NULL, 0}
119 };
120
121/* Loading code stores state inside the ENGINE structure via the "ex_data"
122 * element. We load all our state into a single structure and use that as a
123 * single context in the "ex_data" stack. */
124struct st_dynamic_data_ctx
125 {
126 /* The DSO object we load that supplies the ENGINE code */
127 DSO *dynamic_dso;
128 /* The function pointer to the version checking shared library function */
129 dynamic_v_check_fn v_check;
130 /* The function pointer to the engine-binding shared library function */
131 dynamic_bind_engine bind_engine;
132 /* The default name/path for loading the shared library */
133 const char *DYNAMIC_LIBNAME;
134 /* Whether to continue loading on a version check failure */
135 int no_vcheck;
136 /* If non-NULL, stipulates the 'id' of the ENGINE to be loaded */
137 const char *engine_id;
138 /* If non-zero, a successfully loaded ENGINE should be added to the internal
139 * ENGINE list. If 2, the add must succeed or the entire load should fail. */
140 int list_add_value;
141 /* The symbol name for the version checking function */
142 const char *DYNAMIC_F1;
143 /* The symbol name for the "initialise ENGINE structure" function */
144 const char *DYNAMIC_F2;
145 /* Whether to never use 'dirs', use 'dirs' as a fallback, or only use
146 * 'dirs' for loading. Default is to use 'dirs' as a fallback. */
147 int dir_load;
148 /* A stack of directories from which ENGINEs could be loaded */
149 STACK_OF(OPENSSL_STRING) *dirs;
150 };
151
152/* This is the "ex_data" index we obtain and reserve for use with our context
153 * structure. */
154static int dynamic_ex_data_idx = -1;
155
156static void int_free_str(char *s) { OPENSSL_free(s); }
157/* Because our ex_data element may or may not get allocated depending on whether
158 * a "first-use" occurs before the ENGINE is freed, we have a memory leak
159 * problem to solve. We can't declare a "new" handler for the ex_data as we
160 * don't want a dynamic_data_ctx in *all* ENGINE structures of all types (this
161 * is a bug in the design of CRYPTO_EX_DATA). As such, we just declare a "free"
162 * handler and that will get called if an ENGINE is being destroyed and there
163 * was an ex_data element corresponding to our context type. */
164static void dynamic_data_ctx_free_func(void *parent, void *ptr,
165 CRYPTO_EX_DATA *ad, int idx, long argl, void *argp)
166 {
167 if(ptr)
168 {
169 dynamic_data_ctx *ctx = (dynamic_data_ctx *)ptr;
170 if(ctx->dynamic_dso)
171 DSO_free(ctx->dynamic_dso);
172 if(ctx->DYNAMIC_LIBNAME)
173 OPENSSL_free((void*)ctx->DYNAMIC_LIBNAME);
174 if(ctx->engine_id)
175 OPENSSL_free((void*)ctx->engine_id);
176 if(ctx->dirs)
177 sk_OPENSSL_STRING_pop_free(ctx->dirs, int_free_str);
178 OPENSSL_free(ctx);
179 }
180 }
181
182/* Construct the per-ENGINE context. We create it blindly and then use a lock to
183 * check for a race - if so, all but one of the threads "racing" will have
184 * wasted their time. The alternative involves creating everything inside the
185 * lock which is far worse. */
186static int dynamic_set_data_ctx(ENGINE *e, dynamic_data_ctx **ctx)
187 {
188 dynamic_data_ctx *c;
189 c = OPENSSL_malloc(sizeof(dynamic_data_ctx));
190 if(!c)
191 {
192 ENGINEerr(ENGINE_F_DYNAMIC_SET_DATA_CTX,ERR_R_MALLOC_FAILURE);
193 return 0;
194 }
195 memset(c, 0, sizeof(dynamic_data_ctx));
196 c->dynamic_dso = NULL;
197 c->v_check = NULL;
198 c->bind_engine = NULL;
199 c->DYNAMIC_LIBNAME = NULL;
200 c->no_vcheck = 0;
201 c->engine_id = NULL;
202 c->list_add_value = 0;
203 c->DYNAMIC_F1 = "v_check";
204 c->DYNAMIC_F2 = "bind_engine";
205 c->dir_load = 1;
206 c->dirs = sk_OPENSSL_STRING_new_null();
207 if(!c->dirs)
208 {
209 ENGINEerr(ENGINE_F_DYNAMIC_SET_DATA_CTX,ERR_R_MALLOC_FAILURE);
210 OPENSSL_free(c);
211 return 0;
212 }
213 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
214 if((*ctx = (dynamic_data_ctx *)ENGINE_get_ex_data(e,
215 dynamic_ex_data_idx)) == NULL)
216 {
217 /* Good, we're the first */
218 ENGINE_set_ex_data(e, dynamic_ex_data_idx, c);
219 *ctx = c;
220 c = NULL;
221 }
222 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
223 /* If we lost the race to set the context, c is non-NULL and *ctx is the
224 * context of the thread that won. */
225 if(c)
226 OPENSSL_free(c);
227 return 1;
228 }
229
230/* This function retrieves the context structure from an ENGINE's "ex_data", or
231 * if it doesn't exist yet, sets it up. */
232static dynamic_data_ctx *dynamic_get_data_ctx(ENGINE *e)
233 {
234 dynamic_data_ctx *ctx;
235 if(dynamic_ex_data_idx < 0)
236 {
237 /* Create and register the ENGINE ex_data, and associate our
238 * "free" function with it to ensure any allocated contexts get
239 * freed when an ENGINE goes underground. */
240 int new_idx = ENGINE_get_ex_new_index(0, NULL, NULL, NULL,
241 dynamic_data_ctx_free_func);
242 if(new_idx == -1)
243 {
244 ENGINEerr(ENGINE_F_DYNAMIC_GET_DATA_CTX,ENGINE_R_NO_INDEX);
245 return NULL;
246 }
247 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
248 /* Avoid a race by checking again inside this lock */
249 if(dynamic_ex_data_idx < 0)
250 {
251 /* Good, someone didn't beat us to it */
252 dynamic_ex_data_idx = new_idx;
253 new_idx = -1;
254 }
255 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
256 /* In theory we could "give back" the index here if
257 * (new_idx>-1), but it's not possible and wouldn't gain us much
258 * if it were. */
259 }
260 ctx = (dynamic_data_ctx *)ENGINE_get_ex_data(e, dynamic_ex_data_idx);
261 /* Check if the context needs to be created */
262 if((ctx == NULL) && !dynamic_set_data_ctx(e, &ctx))
263 /* "set_data" will set errors if necessary */
264 return NULL;
265 return ctx;
266 }
267
268static ENGINE *engine_dynamic(void)
269 {
270 ENGINE *ret = ENGINE_new();
271 if(!ret)
272 return NULL;
273 if(!ENGINE_set_id(ret, engine_dynamic_id) ||
274 !ENGINE_set_name(ret, engine_dynamic_name) ||
275 !ENGINE_set_init_function(ret, dynamic_init) ||
276 !ENGINE_set_finish_function(ret, dynamic_finish) ||
277 !ENGINE_set_ctrl_function(ret, dynamic_ctrl) ||
278 !ENGINE_set_flags(ret, ENGINE_FLAGS_BY_ID_COPY) ||
279 !ENGINE_set_cmd_defns(ret, dynamic_cmd_defns))
280 {
281 ENGINE_free(ret);
282 return NULL;
283 }
284 return ret;
285 }
286
287void ENGINE_load_dynamic(void)
288 {
289 ENGINE *toadd = engine_dynamic();
290 if(!toadd) return;
291 ENGINE_add(toadd);
292 /* If the "add" worked, it gets a structural reference. So either way,
293 * we release our just-created reference. */
294 ENGINE_free(toadd);
295 /* If the "add" didn't work, it was probably a conflict because it was
296 * already added (eg. someone calling ENGINE_load_blah then calling
297 * ENGINE_load_builtin_engines() perhaps). */
298 ERR_clear_error();
299 }
300
301static int dynamic_init(ENGINE *e)
302 {
303 /* We always return failure - the "dyanamic" engine itself can't be used
304 * for anything. */
305 return 0;
306 }
307
308static int dynamic_finish(ENGINE *e)
309 {
310 /* This should never be called on account of "dynamic_init" always
311 * failing. */
312 return 0;
313 }
314
315static int dynamic_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void))
316 {
317 dynamic_data_ctx *ctx = dynamic_get_data_ctx(e);
318 int initialised;
319
320 if(!ctx)
321 {
322 ENGINEerr(ENGINE_F_DYNAMIC_CTRL,ENGINE_R_NOT_LOADED);
323 return 0;
324 }
325 initialised = ((ctx->dynamic_dso == NULL) ? 0 : 1);
326 /* All our control commands require the ENGINE to be uninitialised */
327 if(initialised)
328 {
329 ENGINEerr(ENGINE_F_DYNAMIC_CTRL,
330 ENGINE_R_ALREADY_LOADED);
331 return 0;
332 }
333 switch(cmd)
334 {
335 case DYNAMIC_CMD_SO_PATH:
336 /* a NULL 'p' or a string of zero-length is the same thing */
337 if(p && (strlen((const char *)p) < 1))
338 p = NULL;
339 if(ctx->DYNAMIC_LIBNAME)
340 OPENSSL_free((void*)ctx->DYNAMIC_LIBNAME);
341 if(p)
342 ctx->DYNAMIC_LIBNAME = BUF_strdup(p);
343 else
344 ctx->DYNAMIC_LIBNAME = NULL;
345 return (ctx->DYNAMIC_LIBNAME ? 1 : 0);
346 case DYNAMIC_CMD_NO_VCHECK:
347 ctx->no_vcheck = ((i == 0) ? 0 : 1);
348 return 1;
349 case DYNAMIC_CMD_ID:
350 /* a NULL 'p' or a string of zero-length is the same thing */
351 if(p && (strlen((const char *)p) < 1))
352 p = NULL;
353 if(ctx->engine_id)
354 OPENSSL_free((void*)ctx->engine_id);
355 if(p)
356 ctx->engine_id = BUF_strdup(p);
357 else
358 ctx->engine_id = NULL;
359 return (ctx->engine_id ? 1 : 0);
360 case DYNAMIC_CMD_LIST_ADD:
361 if((i < 0) || (i > 2))
362 {
363 ENGINEerr(ENGINE_F_DYNAMIC_CTRL,
364 ENGINE_R_INVALID_ARGUMENT);
365 return 0;
366 }
367 ctx->list_add_value = (int)i;
368 return 1;
369 case DYNAMIC_CMD_LOAD:
370 return dynamic_load(e, ctx);
371 case DYNAMIC_CMD_DIR_LOAD:
372 if((i < 0) || (i > 2))
373 {
374 ENGINEerr(ENGINE_F_DYNAMIC_CTRL,
375 ENGINE_R_INVALID_ARGUMENT);
376 return 0;
377 }
378 ctx->dir_load = (int)i;
379 return 1;
380 case DYNAMIC_CMD_DIR_ADD:
381 /* a NULL 'p' or a string of zero-length is the same thing */
382 if(!p || (strlen((const char *)p) < 1))
383 {
384 ENGINEerr(ENGINE_F_DYNAMIC_CTRL,
385 ENGINE_R_INVALID_ARGUMENT);
386 return 0;
387 }
388 {
389 char *tmp_str = BUF_strdup(p);
390 if(!tmp_str)
391 {
392 ENGINEerr(ENGINE_F_DYNAMIC_CTRL,
393 ERR_R_MALLOC_FAILURE);
394 return 0;
395 }
396 sk_OPENSSL_STRING_insert(ctx->dirs, tmp_str, -1);
397 }
398 return 1;
399 default:
400 break;
401 }
402 ENGINEerr(ENGINE_F_DYNAMIC_CTRL,ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED);
403 return 0;
404 }
405
406static int int_load(dynamic_data_ctx *ctx)
407 {
408 int num, loop;
409 /* Unless told not to, try a direct load */
410 if((ctx->dir_load != 2) && (DSO_load(ctx->dynamic_dso,
411 ctx->DYNAMIC_LIBNAME, NULL, 0)) != NULL)
412 return 1;
413 /* If we're not allowed to use 'dirs' or we have none, fail */
414 if(!ctx->dir_load || (num = sk_OPENSSL_STRING_num(ctx->dirs)) < 1)
415 return 0;
416 for(loop = 0; loop < num; loop++)
417 {
418 const char *s = sk_OPENSSL_STRING_value(ctx->dirs, loop);
419 char *merge = DSO_merge(ctx->dynamic_dso, ctx->DYNAMIC_LIBNAME, s);
420 if(!merge)
421 return 0;
422 if(DSO_load(ctx->dynamic_dso, merge, NULL, 0))
423 {
424 /* Found what we're looking for */
425 OPENSSL_free(merge);
426 return 1;
427 }
428 OPENSSL_free(merge);
429 }
430 return 0;
431 }
432
433static int dynamic_load(ENGINE *e, dynamic_data_ctx *ctx)
434 {
435 ENGINE cpy;
436 dynamic_fns fns;
437
438 if(!ctx->dynamic_dso)
439 ctx->dynamic_dso = DSO_new();
440 if(!ctx->DYNAMIC_LIBNAME)
441 {
442 if(!ctx->engine_id)
443 return 0;
444 ctx->DYNAMIC_LIBNAME =
445 DSO_convert_filename(ctx->dynamic_dso, ctx->engine_id);
446 }
447 if(!int_load(ctx))
448 {
449 ENGINEerr(ENGINE_F_DYNAMIC_LOAD,
450 ENGINE_R_DSO_NOT_FOUND);
451 DSO_free(ctx->dynamic_dso);
452 ctx->dynamic_dso = NULL;
453 return 0;
454 }
455 /* We have to find a bind function otherwise it'll always end badly */
456 if(!(ctx->bind_engine = (dynamic_bind_engine)DSO_bind_func(
457 ctx->dynamic_dso, ctx->DYNAMIC_F2)))
458 {
459 ctx->bind_engine = NULL;
460 DSO_free(ctx->dynamic_dso);
461 ctx->dynamic_dso = NULL;
462 ENGINEerr(ENGINE_F_DYNAMIC_LOAD,
463 ENGINE_R_DSO_FAILURE);
464 return 0;
465 }
466 /* Do we perform version checking? */
467 if(!ctx->no_vcheck)
468 {
469 unsigned long vcheck_res = 0;
470 /* Now we try to find a version checking function and decide how
471 * to cope with failure if/when it fails. */
472 ctx->v_check = (dynamic_v_check_fn)DSO_bind_func(
473 ctx->dynamic_dso, ctx->DYNAMIC_F1);
474 if(ctx->v_check)
475 vcheck_res = ctx->v_check(OSSL_DYNAMIC_VERSION);
476 /* We fail if the version checker veto'd the load *or* if it is
477 * deferring to us (by returning its version) and we think it is
478 * too old. */
479 if(vcheck_res < OSSL_DYNAMIC_OLDEST)
480 {
481 /* Fail */
482 ctx->bind_engine = NULL;
483 ctx->v_check = NULL;
484 DSO_free(ctx->dynamic_dso);
485 ctx->dynamic_dso = NULL;
486 ENGINEerr(ENGINE_F_DYNAMIC_LOAD,
487 ENGINE_R_VERSION_INCOMPATIBILITY);
488 return 0;
489 }
490 }
491 /* First binary copy the ENGINE structure so that we can roll back if
492 * the hand-over fails */
493 memcpy(&cpy, e, sizeof(ENGINE));
494 /* Provide the ERR, "ex_data", memory, and locking callbacks so the
495 * loaded library uses our state rather than its own. FIXME: As noted in
496 * engine.h, much of this would be simplified if each area of code
497 * provided its own "summary" structure of all related callbacks. It
498 * would also increase opaqueness. */
499 fns.static_state = ENGINE_get_static_state();
500 fns.err_fns = ERR_get_implementation();
501 fns.ex_data_fns = CRYPTO_get_ex_data_implementation();
502 CRYPTO_get_mem_functions(&fns.mem_fns.malloc_cb,
503 &fns.mem_fns.realloc_cb,
504 &fns.mem_fns.free_cb);
505 fns.lock_fns.lock_locking_cb = CRYPTO_get_locking_callback();
506 fns.lock_fns.lock_add_lock_cb = CRYPTO_get_add_lock_callback();
507 fns.lock_fns.dynlock_create_cb = CRYPTO_get_dynlock_create_callback();
508 fns.lock_fns.dynlock_lock_cb = CRYPTO_get_dynlock_lock_callback();
509 fns.lock_fns.dynlock_destroy_cb = CRYPTO_get_dynlock_destroy_callback();
510 /* Now that we've loaded the dynamic engine, make sure no "dynamic"
511 * ENGINE elements will show through. */
512 engine_set_all_null(e);
513
514 /* Try to bind the ENGINE onto our own ENGINE structure */
515 if(!ctx->bind_engine(e, ctx->engine_id, &fns))
516 {
517 ctx->bind_engine = NULL;
518 ctx->v_check = NULL;
519 DSO_free(ctx->dynamic_dso);
520 ctx->dynamic_dso = NULL;
521 ENGINEerr(ENGINE_F_DYNAMIC_LOAD,ENGINE_R_INIT_FAILED);
522 /* Copy the original ENGINE structure back */
523 memcpy(e, &cpy, sizeof(ENGINE));
524 return 0;
525 }
526 /* Do we try to add this ENGINE to the internal list too? */
527 if(ctx->list_add_value > 0)
528 {
529 if(!ENGINE_add(e))
530 {
531 /* Do we tolerate this or fail? */
532 if(ctx->list_add_value > 1)
533 {
534 /* Fail - NB: By this time, it's too late to
535 * rollback, and trying to do so allows the
536 * bind_engine() code to have created leaks. We
537 * just have to fail where we are, after the
538 * ENGINE has changed. */
539 ENGINEerr(ENGINE_F_DYNAMIC_LOAD,
540 ENGINE_R_CONFLICTING_ENGINE_ID);
541 return 0;
542 }
543 /* Tolerate */
544 ERR_clear_error();
545 }
546 }
547 return 1;
548 }
diff --git a/src/lib/libcrypto/engine/eng_err.c b/src/lib/libcrypto/engine/eng_err.c
new file mode 100644
index 0000000000..81c70acfa8
--- /dev/null
+++ b/src/lib/libcrypto/engine/eng_err.c
@@ -0,0 +1,173 @@
1/* crypto/engine/eng_err.c */
2/* ====================================================================
3 * Copyright (c) 1999-2010 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 OPENSSL_NO_ERR
67
68#define ERR_FUNC(func) ERR_PACK(ERR_LIB_ENGINE,func,0)
69#define ERR_REASON(reason) ERR_PACK(ERR_LIB_ENGINE,0,reason)
70
71static ERR_STRING_DATA ENGINE_str_functs[]=
72 {
73{ERR_FUNC(ENGINE_F_DYNAMIC_CTRL), "DYNAMIC_CTRL"},
74{ERR_FUNC(ENGINE_F_DYNAMIC_GET_DATA_CTX), "DYNAMIC_GET_DATA_CTX"},
75{ERR_FUNC(ENGINE_F_DYNAMIC_LOAD), "DYNAMIC_LOAD"},
76{ERR_FUNC(ENGINE_F_DYNAMIC_SET_DATA_CTX), "DYNAMIC_SET_DATA_CTX"},
77{ERR_FUNC(ENGINE_F_ENGINE_ADD), "ENGINE_add"},
78{ERR_FUNC(ENGINE_F_ENGINE_BY_ID), "ENGINE_by_id"},
79{ERR_FUNC(ENGINE_F_ENGINE_CMD_IS_EXECUTABLE), "ENGINE_cmd_is_executable"},
80{ERR_FUNC(ENGINE_F_ENGINE_CTRL), "ENGINE_ctrl"},
81{ERR_FUNC(ENGINE_F_ENGINE_CTRL_CMD), "ENGINE_ctrl_cmd"},
82{ERR_FUNC(ENGINE_F_ENGINE_CTRL_CMD_STRING), "ENGINE_ctrl_cmd_string"},
83{ERR_FUNC(ENGINE_F_ENGINE_FINISH), "ENGINE_finish"},
84{ERR_FUNC(ENGINE_F_ENGINE_FREE_UTIL), "ENGINE_FREE_UTIL"},
85{ERR_FUNC(ENGINE_F_ENGINE_GET_CIPHER), "ENGINE_get_cipher"},
86{ERR_FUNC(ENGINE_F_ENGINE_GET_DEFAULT_TYPE), "ENGINE_GET_DEFAULT_TYPE"},
87{ERR_FUNC(ENGINE_F_ENGINE_GET_DIGEST), "ENGINE_get_digest"},
88{ERR_FUNC(ENGINE_F_ENGINE_GET_NEXT), "ENGINE_get_next"},
89{ERR_FUNC(ENGINE_F_ENGINE_GET_PKEY_ASN1_METH), "ENGINE_get_pkey_asn1_meth"},
90{ERR_FUNC(ENGINE_F_ENGINE_GET_PKEY_METH), "ENGINE_get_pkey_meth"},
91{ERR_FUNC(ENGINE_F_ENGINE_GET_PREV), "ENGINE_get_prev"},
92{ERR_FUNC(ENGINE_F_ENGINE_INIT), "ENGINE_init"},
93{ERR_FUNC(ENGINE_F_ENGINE_LIST_ADD), "ENGINE_LIST_ADD"},
94{ERR_FUNC(ENGINE_F_ENGINE_LIST_REMOVE), "ENGINE_LIST_REMOVE"},
95{ERR_FUNC(ENGINE_F_ENGINE_LOAD_PRIVATE_KEY), "ENGINE_load_private_key"},
96{ERR_FUNC(ENGINE_F_ENGINE_LOAD_PUBLIC_KEY), "ENGINE_load_public_key"},
97{ERR_FUNC(ENGINE_F_ENGINE_LOAD_SSL_CLIENT_CERT), "ENGINE_load_ssl_client_cert"},
98{ERR_FUNC(ENGINE_F_ENGINE_NEW), "ENGINE_new"},
99{ERR_FUNC(ENGINE_F_ENGINE_REMOVE), "ENGINE_remove"},
100{ERR_FUNC(ENGINE_F_ENGINE_SET_DEFAULT_STRING), "ENGINE_set_default_string"},
101{ERR_FUNC(ENGINE_F_ENGINE_SET_DEFAULT_TYPE), "ENGINE_SET_DEFAULT_TYPE"},
102{ERR_FUNC(ENGINE_F_ENGINE_SET_ID), "ENGINE_set_id"},
103{ERR_FUNC(ENGINE_F_ENGINE_SET_NAME), "ENGINE_set_name"},
104{ERR_FUNC(ENGINE_F_ENGINE_TABLE_REGISTER), "ENGINE_TABLE_REGISTER"},
105{ERR_FUNC(ENGINE_F_ENGINE_UNLOAD_KEY), "ENGINE_UNLOAD_KEY"},
106{ERR_FUNC(ENGINE_F_ENGINE_UNLOCKED_FINISH), "ENGINE_UNLOCKED_FINISH"},
107{ERR_FUNC(ENGINE_F_ENGINE_UP_REF), "ENGINE_up_ref"},
108{ERR_FUNC(ENGINE_F_INT_CTRL_HELPER), "INT_CTRL_HELPER"},
109{ERR_FUNC(ENGINE_F_INT_ENGINE_CONFIGURE), "INT_ENGINE_CONFIGURE"},
110{ERR_FUNC(ENGINE_F_INT_ENGINE_MODULE_INIT), "INT_ENGINE_MODULE_INIT"},
111{ERR_FUNC(ENGINE_F_LOG_MESSAGE), "LOG_MESSAGE"},
112{0,NULL}
113 };
114
115static ERR_STRING_DATA ENGINE_str_reasons[]=
116 {
117{ERR_REASON(ENGINE_R_ALREADY_LOADED) ,"already loaded"},
118{ERR_REASON(ENGINE_R_ARGUMENT_IS_NOT_A_NUMBER),"argument is not a number"},
119{ERR_REASON(ENGINE_R_CMD_NOT_EXECUTABLE) ,"cmd not executable"},
120{ERR_REASON(ENGINE_R_COMMAND_TAKES_INPUT),"command takes input"},
121{ERR_REASON(ENGINE_R_COMMAND_TAKES_NO_INPUT),"command takes no input"},
122{ERR_REASON(ENGINE_R_CONFLICTING_ENGINE_ID),"conflicting engine id"},
123{ERR_REASON(ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED),"ctrl command not implemented"},
124{ERR_REASON(ENGINE_R_DH_NOT_IMPLEMENTED) ,"dh not implemented"},
125{ERR_REASON(ENGINE_R_DSA_NOT_IMPLEMENTED),"dsa not implemented"},
126{ERR_REASON(ENGINE_R_DSO_FAILURE) ,"DSO failure"},
127{ERR_REASON(ENGINE_R_DSO_NOT_FOUND) ,"dso not found"},
128{ERR_REASON(ENGINE_R_ENGINES_SECTION_ERROR),"engines section error"},
129{ERR_REASON(ENGINE_R_ENGINE_CONFIGURATION_ERROR),"engine configuration error"},
130{ERR_REASON(ENGINE_R_ENGINE_IS_NOT_IN_LIST),"engine is not in the list"},
131{ERR_REASON(ENGINE_R_ENGINE_SECTION_ERROR),"engine section error"},
132{ERR_REASON(ENGINE_R_FAILED_LOADING_PRIVATE_KEY),"failed loading private key"},
133{ERR_REASON(ENGINE_R_FAILED_LOADING_PUBLIC_KEY),"failed loading public key"},
134{ERR_REASON(ENGINE_R_FINISH_FAILED) ,"finish failed"},
135{ERR_REASON(ENGINE_R_GET_HANDLE_FAILED) ,"could not obtain hardware handle"},
136{ERR_REASON(ENGINE_R_ID_OR_NAME_MISSING) ,"'id' or 'name' missing"},
137{ERR_REASON(ENGINE_R_INIT_FAILED) ,"init failed"},
138{ERR_REASON(ENGINE_R_INTERNAL_LIST_ERROR),"internal list error"},
139{ERR_REASON(ENGINE_R_INVALID_ARGUMENT) ,"invalid argument"},
140{ERR_REASON(ENGINE_R_INVALID_CMD_NAME) ,"invalid cmd name"},
141{ERR_REASON(ENGINE_R_INVALID_CMD_NUMBER) ,"invalid cmd number"},
142{ERR_REASON(ENGINE_R_INVALID_INIT_VALUE) ,"invalid init value"},
143{ERR_REASON(ENGINE_R_INVALID_STRING) ,"invalid string"},
144{ERR_REASON(ENGINE_R_NOT_INITIALISED) ,"not initialised"},
145{ERR_REASON(ENGINE_R_NOT_LOADED) ,"not loaded"},
146{ERR_REASON(ENGINE_R_NO_CONTROL_FUNCTION),"no control function"},
147{ERR_REASON(ENGINE_R_NO_INDEX) ,"no index"},
148{ERR_REASON(ENGINE_R_NO_LOAD_FUNCTION) ,"no load function"},
149{ERR_REASON(ENGINE_R_NO_REFERENCE) ,"no reference"},
150{ERR_REASON(ENGINE_R_NO_SUCH_ENGINE) ,"no such engine"},
151{ERR_REASON(ENGINE_R_NO_UNLOAD_FUNCTION) ,"no unload function"},
152{ERR_REASON(ENGINE_R_PROVIDE_PARAMETERS) ,"provide parameters"},
153{ERR_REASON(ENGINE_R_RSA_NOT_IMPLEMENTED),"rsa not implemented"},
154{ERR_REASON(ENGINE_R_UNIMPLEMENTED_CIPHER),"unimplemented cipher"},
155{ERR_REASON(ENGINE_R_UNIMPLEMENTED_DIGEST),"unimplemented digest"},
156{ERR_REASON(ENGINE_R_UNIMPLEMENTED_PUBLIC_KEY_METHOD),"unimplemented public key method"},
157{ERR_REASON(ENGINE_R_VERSION_INCOMPATIBILITY),"version incompatibility"},
158{0,NULL}
159 };
160
161#endif
162
163void ERR_load_ENGINE_strings(void)
164 {
165#ifndef OPENSSL_NO_ERR
166
167 if (ERR_func_error_string(ENGINE_str_functs[0].error) == NULL)
168 {
169 ERR_load_strings(0,ENGINE_str_functs);
170 ERR_load_strings(0,ENGINE_str_reasons);
171 }
172#endif
173 }
diff --git a/src/lib/libcrypto/engine/eng_fat.c b/src/lib/libcrypto/engine/eng_fat.c
new file mode 100644
index 0000000000..db66e62350
--- /dev/null
+++ b/src/lib/libcrypto/engine/eng_fat.c
@@ -0,0 +1,181 @@
1/* crypto/engine/eng_fat.c */
2/* ====================================================================
3 * Copyright (c) 1999-2001 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 * licensing@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 * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
57 * ECDH support in OpenSSL originally developed by
58 * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
59 */
60
61#include "eng_int.h"
62#include <openssl/conf.h>
63
64int ENGINE_set_default(ENGINE *e, unsigned int flags)
65 {
66 if((flags & ENGINE_METHOD_CIPHERS) && !ENGINE_set_default_ciphers(e))
67 return 0;
68 if((flags & ENGINE_METHOD_DIGESTS) && !ENGINE_set_default_digests(e))
69 return 0;
70#ifndef OPENSSL_NO_RSA
71 if((flags & ENGINE_METHOD_RSA) && !ENGINE_set_default_RSA(e))
72 return 0;
73#endif
74#ifndef OPENSSL_NO_DSA
75 if((flags & ENGINE_METHOD_DSA) && !ENGINE_set_default_DSA(e))
76 return 0;
77#endif
78#ifndef OPENSSL_NO_DH
79 if((flags & ENGINE_METHOD_DH) && !ENGINE_set_default_DH(e))
80 return 0;
81#endif
82#ifndef OPENSSL_NO_ECDH
83 if((flags & ENGINE_METHOD_ECDH) && !ENGINE_set_default_ECDH(e))
84 return 0;
85#endif
86#ifndef OPENSSL_NO_ECDSA
87 if((flags & ENGINE_METHOD_ECDSA) && !ENGINE_set_default_ECDSA(e))
88 return 0;
89#endif
90 if((flags & ENGINE_METHOD_RAND) && !ENGINE_set_default_RAND(e))
91 return 0;
92 if((flags & ENGINE_METHOD_PKEY_METHS)
93 && !ENGINE_set_default_pkey_meths(e))
94 return 0;
95 if((flags & ENGINE_METHOD_PKEY_ASN1_METHS)
96 && !ENGINE_set_default_pkey_asn1_meths(e))
97 return 0;
98 return 1;
99 }
100
101/* Set default algorithms using a string */
102
103static int int_def_cb(const char *alg, int len, void *arg)
104 {
105 unsigned int *pflags = arg;
106 if (!strncmp(alg, "ALL", len))
107 *pflags |= ENGINE_METHOD_ALL;
108 else if (!strncmp(alg, "RSA", len))
109 *pflags |= ENGINE_METHOD_RSA;
110 else if (!strncmp(alg, "DSA", len))
111 *pflags |= ENGINE_METHOD_DSA;
112 else if (!strncmp(alg, "ECDH", len))
113 *pflags |= ENGINE_METHOD_ECDH;
114 else if (!strncmp(alg, "ECDSA", len))
115 *pflags |= ENGINE_METHOD_ECDSA;
116 else if (!strncmp(alg, "DH", len))
117 *pflags |= ENGINE_METHOD_DH;
118 else if (!strncmp(alg, "RAND", len))
119 *pflags |= ENGINE_METHOD_RAND;
120 else if (!strncmp(alg, "CIPHERS", len))
121 *pflags |= ENGINE_METHOD_CIPHERS;
122 else if (!strncmp(alg, "DIGESTS", len))
123 *pflags |= ENGINE_METHOD_DIGESTS;
124 else if (!strncmp(alg, "PKEY", len))
125 *pflags |=
126 ENGINE_METHOD_PKEY_METHS|ENGINE_METHOD_PKEY_ASN1_METHS;
127 else if (!strncmp(alg, "PKEY_CRYPTO", len))
128 *pflags |= ENGINE_METHOD_PKEY_METHS;
129 else if (!strncmp(alg, "PKEY_ASN1", len))
130 *pflags |= ENGINE_METHOD_PKEY_ASN1_METHS;
131 else
132 return 0;
133 return 1;
134 }
135
136
137int ENGINE_set_default_string(ENGINE *e, const char *def_list)
138 {
139 unsigned int flags = 0;
140 if (!CONF_parse_list(def_list, ',', 1, int_def_cb, &flags))
141 {
142 ENGINEerr(ENGINE_F_ENGINE_SET_DEFAULT_STRING,
143 ENGINE_R_INVALID_STRING);
144 ERR_add_error_data(2, "str=",def_list);
145 return 0;
146 }
147 return ENGINE_set_default(e, flags);
148 }
149
150int ENGINE_register_complete(ENGINE *e)
151 {
152 ENGINE_register_ciphers(e);
153 ENGINE_register_digests(e);
154#ifndef OPENSSL_NO_RSA
155 ENGINE_register_RSA(e);
156#endif
157#ifndef OPENSSL_NO_DSA
158 ENGINE_register_DSA(e);
159#endif
160#ifndef OPENSSL_NO_DH
161 ENGINE_register_DH(e);
162#endif
163#ifndef OPENSSL_NO_ECDH
164 ENGINE_register_ECDH(e);
165#endif
166#ifndef OPENSSL_NO_ECDSA
167 ENGINE_register_ECDSA(e);
168#endif
169 ENGINE_register_RAND(e);
170 ENGINE_register_pkey_meths(e);
171 return 1;
172 }
173
174int ENGINE_register_all_complete(void)
175 {
176 ENGINE *e;
177
178 for(e=ENGINE_get_first() ; e ; e=ENGINE_get_next(e))
179 ENGINE_register_complete(e);
180 return 1;
181 }
diff --git a/src/lib/libcrypto/engine/eng_init.c b/src/lib/libcrypto/engine/eng_init.c
new file mode 100644
index 0000000000..7633cf5f1d
--- /dev/null
+++ b/src/lib/libcrypto/engine/eng_init.c
@@ -0,0 +1,154 @@
1/* crypto/engine/eng_init.c */
2/* ====================================================================
3 * Copyright (c) 1999-2001 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 * licensing@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#include "eng_int.h"
57
58/* Initialise a engine type for use (or up its functional reference count
59 * if it's already in use). This version is only used internally. */
60int engine_unlocked_init(ENGINE *e)
61 {
62 int to_return = 1;
63
64 if((e->funct_ref == 0) && e->init)
65 /* This is the first functional reference and the engine
66 * requires initialisation so we do it now. */
67 to_return = e->init(e);
68 if(to_return)
69 {
70 /* OK, we return a functional reference which is also a
71 * structural reference. */
72 e->struct_ref++;
73 e->funct_ref++;
74 engine_ref_debug(e, 0, 1)
75 engine_ref_debug(e, 1, 1)
76 }
77 return to_return;
78 }
79
80/* Free a functional reference to a engine type. This version is only used
81 * internally. */
82int engine_unlocked_finish(ENGINE *e, int unlock_for_handlers)
83 {
84 int to_return = 1;
85
86 /* Reduce the functional reference count here so if it's the terminating
87 * case, we can release the lock safely and call the finish() handler
88 * without risk of a race. We get a race if we leave the count until
89 * after and something else is calling "finish" at the same time -
90 * there's a chance that both threads will together take the count from
91 * 2 to 0 without either calling finish(). */
92 e->funct_ref--;
93 engine_ref_debug(e, 1, -1);
94 if((e->funct_ref == 0) && e->finish)
95 {
96 if(unlock_for_handlers)
97 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
98 to_return = e->finish(e);
99 if(unlock_for_handlers)
100 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
101 if(!to_return)
102 return 0;
103 }
104#ifdef REF_CHECK
105 if(e->funct_ref < 0)
106 {
107 fprintf(stderr,"ENGINE_finish, bad functional reference count\n");
108 abort();
109 }
110#endif
111 /* Release the structural reference too */
112 if(!engine_free_util(e, 0))
113 {
114 ENGINEerr(ENGINE_F_ENGINE_UNLOCKED_FINISH,ENGINE_R_FINISH_FAILED);
115 return 0;
116 }
117 return to_return;
118 }
119
120/* The API (locked) version of "init" */
121int ENGINE_init(ENGINE *e)
122 {
123 int ret;
124 if(e == NULL)
125 {
126 ENGINEerr(ENGINE_F_ENGINE_INIT,ERR_R_PASSED_NULL_PARAMETER);
127 return 0;
128 }
129 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
130 ret = engine_unlocked_init(e);
131 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
132 return ret;
133 }
134
135/* The API (locked) version of "finish" */
136int ENGINE_finish(ENGINE *e)
137 {
138 int to_return = 1;
139
140 if(e == NULL)
141 {
142 ENGINEerr(ENGINE_F_ENGINE_FINISH,ERR_R_PASSED_NULL_PARAMETER);
143 return 0;
144 }
145 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
146 to_return = engine_unlocked_finish(e, 1);
147 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
148 if(!to_return)
149 {
150 ENGINEerr(ENGINE_F_ENGINE_FINISH,ENGINE_R_FINISH_FAILED);
151 return 0;
152 }
153 return to_return;
154 }
diff --git a/src/lib/libcrypto/engine/eng_int.h b/src/lib/libcrypto/engine/eng_int.h
new file mode 100644
index 0000000000..451ef8feb8
--- /dev/null
+++ b/src/lib/libcrypto/engine/eng_int.h
@@ -0,0 +1,206 @@
1/* crypto/engine/eng_int.h */
2/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
3 * project 2000.
4 */
5/* ====================================================================
6 * Copyright (c) 1999-2001 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 * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
60 * ECDH support in OpenSSL originally developed by
61 * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
62 */
63
64#ifndef HEADER_ENGINE_INT_H
65#define HEADER_ENGINE_INT_H
66
67#include "cryptlib.h"
68/* Take public definitions from engine.h */
69#include <openssl/engine.h>
70
71#ifdef __cplusplus
72extern "C" {
73#endif
74
75/* If we compile with this symbol defined, then both reference counts in the
76 * ENGINE structure will be monitored with a line of output on stderr for each
77 * change. This prints the engine's pointer address (truncated to unsigned int),
78 * "struct" or "funct" to indicate the reference type, the before and after
79 * reference count, and the file:line-number pair. The "engine_ref_debug"
80 * statements must come *after* the change. */
81#ifdef ENGINE_REF_COUNT_DEBUG
82
83#define engine_ref_debug(e, isfunct, diff) \
84 fprintf(stderr, "engine: %08x %s from %d to %d (%s:%d)\n", \
85 (unsigned int)(e), (isfunct ? "funct" : "struct"), \
86 ((isfunct) ? ((e)->funct_ref - (diff)) : ((e)->struct_ref - (diff))), \
87 ((isfunct) ? (e)->funct_ref : (e)->struct_ref), \
88 (__FILE__), (__LINE__));
89
90#else
91
92#define engine_ref_debug(e, isfunct, diff)
93
94#endif
95
96/* Any code that will need cleanup operations should use these functions to
97 * register callbacks. ENGINE_cleanup() will call all registered callbacks in
98 * order. NB: both the "add" functions assume CRYPTO_LOCK_ENGINE to already be
99 * held (in "write" mode). */
100typedef void (ENGINE_CLEANUP_CB)(void);
101typedef struct st_engine_cleanup_item
102 {
103 ENGINE_CLEANUP_CB *cb;
104 } ENGINE_CLEANUP_ITEM;
105DECLARE_STACK_OF(ENGINE_CLEANUP_ITEM)
106void engine_cleanup_add_first(ENGINE_CLEANUP_CB *cb);
107void engine_cleanup_add_last(ENGINE_CLEANUP_CB *cb);
108
109/* We need stacks of ENGINEs for use in eng_table.c */
110DECLARE_STACK_OF(ENGINE)
111
112/* If this symbol is defined then engine_table_select(), the function that is
113 * used by RSA, DSA (etc) code to select registered ENGINEs, cache defaults and
114 * functional references (etc), will display debugging summaries to stderr. */
115/* #define ENGINE_TABLE_DEBUG */
116
117/* This represents an implementation table. Dependent code should instantiate it
118 * as a (ENGINE_TABLE *) pointer value set initially to NULL. */
119typedef struct st_engine_table ENGINE_TABLE;
120int engine_table_register(ENGINE_TABLE **table, ENGINE_CLEANUP_CB *cleanup,
121 ENGINE *e, const int *nids, int num_nids, int setdefault);
122void engine_table_unregister(ENGINE_TABLE **table, ENGINE *e);
123void engine_table_cleanup(ENGINE_TABLE **table);
124#ifndef ENGINE_TABLE_DEBUG
125ENGINE *engine_table_select(ENGINE_TABLE **table, int nid);
126#else
127ENGINE *engine_table_select_tmp(ENGINE_TABLE **table, int nid, const char *f, int l);
128#define engine_table_select(t,n) engine_table_select_tmp(t,n,__FILE__,__LINE__)
129#endif
130typedef void (engine_table_doall_cb)(int nid, STACK_OF(ENGINE) *sk, ENGINE *def, void *arg);
131void engine_table_doall(ENGINE_TABLE *table, engine_table_doall_cb *cb, void *arg);
132
133/* Internal versions of API functions that have control over locking. These are
134 * used between C files when functionality needs to be shared but the caller may
135 * already be controlling of the CRYPTO_LOCK_ENGINE lock. */
136int engine_unlocked_init(ENGINE *e);
137int engine_unlocked_finish(ENGINE *e, int unlock_for_handlers);
138int engine_free_util(ENGINE *e, int locked);
139
140/* This function will reset all "set"able values in an ENGINE to NULL. This
141 * won't touch reference counts or ex_data, but is equivalent to calling all the
142 * ENGINE_set_***() functions with a NULL value. */
143void engine_set_all_null(ENGINE *e);
144
145/* NB: Bitwise OR-able values for the "flags" variable in ENGINE are now exposed
146 * in engine.h. */
147
148/* Free up dynamically allocated public key methods associated with ENGINE */
149
150void engine_pkey_meths_free(ENGINE *e);
151void engine_pkey_asn1_meths_free(ENGINE *e);
152
153/* This is a structure for storing implementations of various crypto
154 * algorithms and functions. */
155struct engine_st
156 {
157 const char *id;
158 const char *name;
159 const RSA_METHOD *rsa_meth;
160 const DSA_METHOD *dsa_meth;
161 const DH_METHOD *dh_meth;
162 const ECDH_METHOD *ecdh_meth;
163 const ECDSA_METHOD *ecdsa_meth;
164 const RAND_METHOD *rand_meth;
165 const STORE_METHOD *store_meth;
166 /* Cipher handling is via this callback */
167 ENGINE_CIPHERS_PTR ciphers;
168 /* Digest handling is via this callback */
169 ENGINE_DIGESTS_PTR digests;
170 /* Public key handling via this callback */
171 ENGINE_PKEY_METHS_PTR pkey_meths;
172 /* ASN1 public key handling via this callback */
173 ENGINE_PKEY_ASN1_METHS_PTR pkey_asn1_meths;
174
175 ENGINE_GEN_INT_FUNC_PTR destroy;
176
177 ENGINE_GEN_INT_FUNC_PTR init;
178 ENGINE_GEN_INT_FUNC_PTR finish;
179 ENGINE_CTRL_FUNC_PTR ctrl;
180 ENGINE_LOAD_KEY_PTR load_privkey;
181 ENGINE_LOAD_KEY_PTR load_pubkey;
182
183 ENGINE_SSL_CLIENT_CERT_PTR load_ssl_client_cert;
184
185 const ENGINE_CMD_DEFN *cmd_defns;
186 int flags;
187 /* reference count on the structure itself */
188 int struct_ref;
189 /* reference count on usability of the engine type. NB: This
190 * controls the loading and initialisation of any functionlity
191 * required by this engine, whereas the previous count is
192 * simply to cope with (de)allocation of this structure. Hence,
193 * running_ref <= struct_ref at all times. */
194 int funct_ref;
195 /* A place to store per-ENGINE data */
196 CRYPTO_EX_DATA ex_data;
197 /* Used to maintain the linked-list of engines. */
198 struct engine_st *prev;
199 struct engine_st *next;
200 };
201
202#ifdef __cplusplus
203}
204#endif
205
206#endif /* HEADER_ENGINE_INT_H */
diff --git a/src/lib/libcrypto/engine/eng_lib.c b/src/lib/libcrypto/engine/eng_lib.c
new file mode 100644
index 0000000000..18a6664645
--- /dev/null
+++ b/src/lib/libcrypto/engine/eng_lib.c
@@ -0,0 +1,332 @@
1/* crypto/engine/eng_lib.c */
2/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
3 * project 2000.
4 */
5/* ====================================================================
6 * Copyright (c) 1999-2001 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 "eng_int.h"
60#include <openssl/rand.h>
61
62/* The "new"/"free" stuff first */
63
64ENGINE *ENGINE_new(void)
65 {
66 ENGINE *ret;
67
68 ret = (ENGINE *)OPENSSL_malloc(sizeof(ENGINE));
69 if(ret == NULL)
70 {
71 ENGINEerr(ENGINE_F_ENGINE_NEW, ERR_R_MALLOC_FAILURE);
72 return NULL;
73 }
74 memset(ret, 0, sizeof(ENGINE));
75 ret->struct_ref = 1;
76 engine_ref_debug(ret, 0, 1)
77 CRYPTO_new_ex_data(CRYPTO_EX_INDEX_ENGINE, ret, &ret->ex_data);
78 return ret;
79 }
80
81/* Placed here (close proximity to ENGINE_new) so that modifications to the
82 * elements of the ENGINE structure are more likely to be caught and changed
83 * here. */
84void engine_set_all_null(ENGINE *e)
85 {
86 e->id = NULL;
87 e->name = NULL;
88 e->rsa_meth = NULL;
89 e->dsa_meth = NULL;
90 e->dh_meth = NULL;
91 e->rand_meth = NULL;
92 e->store_meth = NULL;
93 e->ciphers = NULL;
94 e->digests = NULL;
95 e->destroy = NULL;
96 e->init = NULL;
97 e->finish = NULL;
98 e->ctrl = NULL;
99 e->load_privkey = NULL;
100 e->load_pubkey = NULL;
101 e->cmd_defns = NULL;
102 e->flags = 0;
103 }
104
105int engine_free_util(ENGINE *e, int locked)
106 {
107 int i;
108
109 if(e == NULL)
110 {
111 ENGINEerr(ENGINE_F_ENGINE_FREE_UTIL,
112 ERR_R_PASSED_NULL_PARAMETER);
113 return 0;
114 }
115 if(locked)
116 i = CRYPTO_add(&e->struct_ref,-1,CRYPTO_LOCK_ENGINE);
117 else
118 i = --e->struct_ref;
119 engine_ref_debug(e, 0, -1)
120 if (i > 0) return 1;
121#ifdef REF_CHECK
122 if (i < 0)
123 {
124 fprintf(stderr,"ENGINE_free, bad structural reference count\n");
125 abort();
126 }
127#endif
128 /* Free up any dynamically allocated public key methods */
129 engine_pkey_meths_free(e);
130 engine_pkey_asn1_meths_free(e);
131 /* Give the ENGINE a chance to do any structural cleanup corresponding
132 * to allocation it did in its constructor (eg. unload error strings) */
133 if(e->destroy)
134 e->destroy(e);
135 CRYPTO_free_ex_data(CRYPTO_EX_INDEX_ENGINE, e, &e->ex_data);
136 OPENSSL_free(e);
137 return 1;
138 }
139
140int ENGINE_free(ENGINE *e)
141 {
142 return engine_free_util(e, 1);
143 }
144
145/* Cleanup stuff */
146
147/* ENGINE_cleanup() is coded such that anything that does work that will need
148 * cleanup can register a "cleanup" callback here. That way we don't get linker
149 * bloat by referring to all *possible* cleanups, but any linker bloat into code
150 * "X" will cause X's cleanup function to end up here. */
151static STACK_OF(ENGINE_CLEANUP_ITEM) *cleanup_stack = NULL;
152static int int_cleanup_check(int create)
153 {
154 if(cleanup_stack) return 1;
155 if(!create) return 0;
156 cleanup_stack = sk_ENGINE_CLEANUP_ITEM_new_null();
157 return (cleanup_stack ? 1 : 0);
158 }
159static ENGINE_CLEANUP_ITEM *int_cleanup_item(ENGINE_CLEANUP_CB *cb)
160 {
161 ENGINE_CLEANUP_ITEM *item = OPENSSL_malloc(sizeof(
162 ENGINE_CLEANUP_ITEM));
163 if(!item) return NULL;
164 item->cb = cb;
165 return item;
166 }
167void engine_cleanup_add_first(ENGINE_CLEANUP_CB *cb)
168 {
169 ENGINE_CLEANUP_ITEM *item;
170 if(!int_cleanup_check(1)) return;
171 item = int_cleanup_item(cb);
172 if(item)
173 sk_ENGINE_CLEANUP_ITEM_insert(cleanup_stack, item, 0);
174 }
175void engine_cleanup_add_last(ENGINE_CLEANUP_CB *cb)
176 {
177 ENGINE_CLEANUP_ITEM *item;
178 if(!int_cleanup_check(1)) return;
179 item = int_cleanup_item(cb);
180 if(item)
181 sk_ENGINE_CLEANUP_ITEM_push(cleanup_stack, item);
182 }
183/* The API function that performs all cleanup */
184static void engine_cleanup_cb_free(ENGINE_CLEANUP_ITEM *item)
185 {
186 (*(item->cb))();
187 OPENSSL_free(item);
188 }
189void ENGINE_cleanup(void)
190 {
191 if(int_cleanup_check(0))
192 {
193 sk_ENGINE_CLEANUP_ITEM_pop_free(cleanup_stack,
194 engine_cleanup_cb_free);
195 cleanup_stack = NULL;
196 }
197 /* FIXME: This should be handled (somehow) through RAND, eg. by it
198 * registering a cleanup callback. */
199 RAND_set_rand_method(NULL);
200 }
201
202/* Now the "ex_data" support */
203
204int ENGINE_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
205 CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func)
206 {
207 return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_ENGINE, argl, argp,
208 new_func, dup_func, free_func);
209 }
210
211int ENGINE_set_ex_data(ENGINE *e, int idx, void *arg)
212 {
213 return(CRYPTO_set_ex_data(&e->ex_data, idx, arg));
214 }
215
216void *ENGINE_get_ex_data(const ENGINE *e, int idx)
217 {
218 return(CRYPTO_get_ex_data(&e->ex_data, idx));
219 }
220
221/* Functions to get/set an ENGINE's elements - mainly to avoid exposing the
222 * ENGINE structure itself. */
223
224int ENGINE_set_id(ENGINE *e, const char *id)
225 {
226 if(id == NULL)
227 {
228 ENGINEerr(ENGINE_F_ENGINE_SET_ID,
229 ERR_R_PASSED_NULL_PARAMETER);
230 return 0;
231 }
232 e->id = id;
233 return 1;
234 }
235
236int ENGINE_set_name(ENGINE *e, const char *name)
237 {
238 if(name == NULL)
239 {
240 ENGINEerr(ENGINE_F_ENGINE_SET_NAME,
241 ERR_R_PASSED_NULL_PARAMETER);
242 return 0;
243 }
244 e->name = name;
245 return 1;
246 }
247
248int ENGINE_set_destroy_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR destroy_f)
249 {
250 e->destroy = destroy_f;
251 return 1;
252 }
253
254int ENGINE_set_init_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR init_f)
255 {
256 e->init = init_f;
257 return 1;
258 }
259
260int ENGINE_set_finish_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR finish_f)
261 {
262 e->finish = finish_f;
263 return 1;
264 }
265
266int ENGINE_set_ctrl_function(ENGINE *e, ENGINE_CTRL_FUNC_PTR ctrl_f)
267 {
268 e->ctrl = ctrl_f;
269 return 1;
270 }
271
272int ENGINE_set_flags(ENGINE *e, int flags)
273 {
274 e->flags = flags;
275 return 1;
276 }
277
278int ENGINE_set_cmd_defns(ENGINE *e, const ENGINE_CMD_DEFN *defns)
279 {
280 e->cmd_defns = defns;
281 return 1;
282 }
283
284const char *ENGINE_get_id(const ENGINE *e)
285 {
286 return e->id;
287 }
288
289const char *ENGINE_get_name(const ENGINE *e)
290 {
291 return e->name;
292 }
293
294ENGINE_GEN_INT_FUNC_PTR ENGINE_get_destroy_function(const ENGINE *e)
295 {
296 return e->destroy;
297 }
298
299ENGINE_GEN_INT_FUNC_PTR ENGINE_get_init_function(const ENGINE *e)
300 {
301 return e->init;
302 }
303
304ENGINE_GEN_INT_FUNC_PTR ENGINE_get_finish_function(const ENGINE *e)
305 {
306 return e->finish;
307 }
308
309ENGINE_CTRL_FUNC_PTR ENGINE_get_ctrl_function(const ENGINE *e)
310 {
311 return e->ctrl;
312 }
313
314int ENGINE_get_flags(const ENGINE *e)
315 {
316 return e->flags;
317 }
318
319const ENGINE_CMD_DEFN *ENGINE_get_cmd_defns(const ENGINE *e)
320 {
321 return e->cmd_defns;
322 }
323
324/* eng_lib.o is pretty much linked into anything that touches ENGINE already, so
325 * put the "static_state" hack here. */
326
327static int internal_static_hack = 0;
328
329void *ENGINE_get_static_state(void)
330 {
331 return &internal_static_hack;
332 }
diff --git a/src/lib/libcrypto/engine/eng_list.c b/src/lib/libcrypto/engine/eng_list.c
new file mode 100644
index 0000000000..27846edb1e
--- /dev/null
+++ b/src/lib/libcrypto/engine/eng_list.c
@@ -0,0 +1,433 @@
1/* crypto/engine/eng_list.c */
2/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
3 * project 2000.
4 */
5/* ====================================================================
6 * Copyright (c) 1999-2001 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 * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
60 * ECDH support in OpenSSL originally developed by
61 * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
62 */
63
64#include "eng_int.h"
65
66/* The linked-list of pointers to engine types. engine_list_head
67 * incorporates an implicit structural reference but engine_list_tail
68 * does not - the latter is a computational niceity and only points
69 * to something that is already pointed to by its predecessor in the
70 * list (or engine_list_head itself). In the same way, the use of the
71 * "prev" pointer in each ENGINE is to save excessive list iteration,
72 * it doesn't correspond to an extra structural reference. Hence,
73 * engine_list_head, and each non-null "next" pointer account for
74 * the list itself assuming exactly 1 structural reference on each
75 * list member. */
76static ENGINE *engine_list_head = NULL;
77static ENGINE *engine_list_tail = NULL;
78
79/* This cleanup function is only needed internally. If it should be called, we
80 * register it with the "ENGINE_cleanup()" stack to be called during cleanup. */
81
82static void engine_list_cleanup(void)
83 {
84 ENGINE *iterator = engine_list_head;
85
86 while(iterator != NULL)
87 {
88 ENGINE_remove(iterator);
89 iterator = engine_list_head;
90 }
91 return;
92 }
93
94/* These static functions starting with a lower case "engine_" always
95 * take place when CRYPTO_LOCK_ENGINE has been locked up. */
96static int engine_list_add(ENGINE *e)
97 {
98 int conflict = 0;
99 ENGINE *iterator = NULL;
100
101 if(e == NULL)
102 {
103 ENGINEerr(ENGINE_F_ENGINE_LIST_ADD,
104 ERR_R_PASSED_NULL_PARAMETER);
105 return 0;
106 }
107 iterator = engine_list_head;
108 while(iterator && !conflict)
109 {
110 conflict = (strcmp(iterator->id, e->id) == 0);
111 iterator = iterator->next;
112 }
113 if(conflict)
114 {
115 ENGINEerr(ENGINE_F_ENGINE_LIST_ADD,
116 ENGINE_R_CONFLICTING_ENGINE_ID);
117 return 0;
118 }
119 if(engine_list_head == NULL)
120 {
121 /* We are adding to an empty list. */
122 if(engine_list_tail)
123 {
124 ENGINEerr(ENGINE_F_ENGINE_LIST_ADD,
125 ENGINE_R_INTERNAL_LIST_ERROR);
126 return 0;
127 }
128 engine_list_head = e;
129 e->prev = NULL;
130 /* The first time the list allocates, we should register the
131 * cleanup. */
132 engine_cleanup_add_last(engine_list_cleanup);
133 }
134 else
135 {
136 /* We are adding to the tail of an existing list. */
137 if((engine_list_tail == NULL) ||
138 (engine_list_tail->next != NULL))
139 {
140 ENGINEerr(ENGINE_F_ENGINE_LIST_ADD,
141 ENGINE_R_INTERNAL_LIST_ERROR);
142 return 0;
143 }
144 engine_list_tail->next = e;
145 e->prev = engine_list_tail;
146 }
147 /* Having the engine in the list assumes a structural
148 * reference. */
149 e->struct_ref++;
150 engine_ref_debug(e, 0, 1)
151 /* However it came to be, e is the last item in the list. */
152 engine_list_tail = e;
153 e->next = NULL;
154 return 1;
155 }
156
157static int engine_list_remove(ENGINE *e)
158 {
159 ENGINE *iterator;
160
161 if(e == NULL)
162 {
163 ENGINEerr(ENGINE_F_ENGINE_LIST_REMOVE,
164 ERR_R_PASSED_NULL_PARAMETER);
165 return 0;
166 }
167 /* We need to check that e is in our linked list! */
168 iterator = engine_list_head;
169 while(iterator && (iterator != e))
170 iterator = iterator->next;
171 if(iterator == NULL)
172 {
173 ENGINEerr(ENGINE_F_ENGINE_LIST_REMOVE,
174 ENGINE_R_ENGINE_IS_NOT_IN_LIST);
175 return 0;
176 }
177 /* un-link e from the chain. */
178 if(e->next)
179 e->next->prev = e->prev;
180 if(e->prev)
181 e->prev->next = e->next;
182 /* Correct our head/tail if necessary. */
183 if(engine_list_head == e)
184 engine_list_head = e->next;
185 if(engine_list_tail == e)
186 engine_list_tail = e->prev;
187 engine_free_util(e, 0);
188 return 1;
189 }
190
191/* Get the first/last "ENGINE" type available. */
192ENGINE *ENGINE_get_first(void)
193 {
194 ENGINE *ret;
195
196 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
197 ret = engine_list_head;
198 if(ret)
199 {
200 ret->struct_ref++;
201 engine_ref_debug(ret, 0, 1)
202 }
203 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
204 return ret;
205 }
206
207ENGINE *ENGINE_get_last(void)
208 {
209 ENGINE *ret;
210
211 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
212 ret = engine_list_tail;
213 if(ret)
214 {
215 ret->struct_ref++;
216 engine_ref_debug(ret, 0, 1)
217 }
218 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
219 return ret;
220 }
221
222/* Iterate to the next/previous "ENGINE" type (NULL = end of the list). */
223ENGINE *ENGINE_get_next(ENGINE *e)
224 {
225 ENGINE *ret = NULL;
226 if(e == NULL)
227 {
228 ENGINEerr(ENGINE_F_ENGINE_GET_NEXT,
229 ERR_R_PASSED_NULL_PARAMETER);
230 return 0;
231 }
232 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
233 ret = e->next;
234 if(ret)
235 {
236 /* Return a valid structural refernce to the next ENGINE */
237 ret->struct_ref++;
238 engine_ref_debug(ret, 0, 1)
239 }
240 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
241 /* Release the structural reference to the previous ENGINE */
242 ENGINE_free(e);
243 return ret;
244 }
245
246ENGINE *ENGINE_get_prev(ENGINE *e)
247 {
248 ENGINE *ret = NULL;
249 if(e == NULL)
250 {
251 ENGINEerr(ENGINE_F_ENGINE_GET_PREV,
252 ERR_R_PASSED_NULL_PARAMETER);
253 return 0;
254 }
255 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
256 ret = e->prev;
257 if(ret)
258 {
259 /* Return a valid structural reference to the next ENGINE */
260 ret->struct_ref++;
261 engine_ref_debug(ret, 0, 1)
262 }
263 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
264 /* Release the structural reference to the previous ENGINE */
265 ENGINE_free(e);
266 return ret;
267 }
268
269/* Add another "ENGINE" type into the list. */
270int ENGINE_add(ENGINE *e)
271 {
272 int to_return = 1;
273 if(e == NULL)
274 {
275 ENGINEerr(ENGINE_F_ENGINE_ADD,
276 ERR_R_PASSED_NULL_PARAMETER);
277 return 0;
278 }
279 if((e->id == NULL) || (e->name == NULL))
280 {
281 ENGINEerr(ENGINE_F_ENGINE_ADD,
282 ENGINE_R_ID_OR_NAME_MISSING);
283 }
284 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
285 if(!engine_list_add(e))
286 {
287 ENGINEerr(ENGINE_F_ENGINE_ADD,
288 ENGINE_R_INTERNAL_LIST_ERROR);
289 to_return = 0;
290 }
291 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
292 return to_return;
293 }
294
295/* Remove an existing "ENGINE" type from the array. */
296int ENGINE_remove(ENGINE *e)
297 {
298 int to_return = 1;
299 if(e == NULL)
300 {
301 ENGINEerr(ENGINE_F_ENGINE_REMOVE,
302 ERR_R_PASSED_NULL_PARAMETER);
303 return 0;
304 }
305 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
306 if(!engine_list_remove(e))
307 {
308 ENGINEerr(ENGINE_F_ENGINE_REMOVE,
309 ENGINE_R_INTERNAL_LIST_ERROR);
310 to_return = 0;
311 }
312 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
313 return to_return;
314 }
315
316static void engine_cpy(ENGINE *dest, const ENGINE *src)
317 {
318 dest->id = src->id;
319 dest->name = src->name;
320#ifndef OPENSSL_NO_RSA
321 dest->rsa_meth = src->rsa_meth;
322#endif
323#ifndef OPENSSL_NO_DSA
324 dest->dsa_meth = src->dsa_meth;
325#endif
326#ifndef OPENSSL_NO_DH
327 dest->dh_meth = src->dh_meth;
328#endif
329#ifndef OPENSSL_NO_ECDH
330 dest->ecdh_meth = src->ecdh_meth;
331#endif
332#ifndef OPENSSL_NO_ECDSA
333 dest->ecdsa_meth = src->ecdsa_meth;
334#endif
335 dest->rand_meth = src->rand_meth;
336 dest->store_meth = src->store_meth;
337 dest->ciphers = src->ciphers;
338 dest->digests = src->digests;
339 dest->pkey_meths = src->pkey_meths;
340 dest->destroy = src->destroy;
341 dest->init = src->init;
342 dest->finish = src->finish;
343 dest->ctrl = src->ctrl;
344 dest->load_privkey = src->load_privkey;
345 dest->load_pubkey = src->load_pubkey;
346 dest->cmd_defns = src->cmd_defns;
347 dest->flags = src->flags;
348 }
349
350ENGINE *ENGINE_by_id(const char *id)
351 {
352 ENGINE *iterator;
353 char *load_dir = NULL;
354 if(id == NULL)
355 {
356 ENGINEerr(ENGINE_F_ENGINE_BY_ID,
357 ERR_R_PASSED_NULL_PARAMETER);
358 return NULL;
359 }
360 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
361 iterator = engine_list_head;
362 while(iterator && (strcmp(id, iterator->id) != 0))
363 iterator = iterator->next;
364 if(iterator)
365 {
366 /* We need to return a structural reference. If this is an
367 * ENGINE type that returns copies, make a duplicate - otherwise
368 * increment the existing ENGINE's reference count. */
369 if(iterator->flags & ENGINE_FLAGS_BY_ID_COPY)
370 {
371 ENGINE *cp = ENGINE_new();
372 if(!cp)
373 iterator = NULL;
374 else
375 {
376 engine_cpy(cp, iterator);
377 iterator = cp;
378 }
379 }
380 else
381 {
382 iterator->struct_ref++;
383 engine_ref_debug(iterator, 0, 1)
384 }
385 }
386 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
387#if 0
388 if(iterator == NULL)
389 {
390 ENGINEerr(ENGINE_F_ENGINE_BY_ID,
391 ENGINE_R_NO_SUCH_ENGINE);
392 ERR_add_error_data(2, "id=", id);
393 }
394 return iterator;
395#else
396 /* EEK! Experimental code starts */
397 if(iterator) return iterator;
398 /* Prevent infinite recusrion if we're looking for the dynamic engine. */
399 if (strcmp(id, "dynamic"))
400 {
401#ifdef OPENSSL_SYS_VMS
402 if((load_dir = getenv("OPENSSL_ENGINES")) == 0) load_dir = "SSLROOT:[ENGINES]";
403#else
404 if((load_dir = getenv("OPENSSL_ENGINES")) == 0) load_dir = ENGINESDIR;
405#endif
406 iterator = ENGINE_by_id("dynamic");
407 if(!iterator || !ENGINE_ctrl_cmd_string(iterator, "ID", id, 0) ||
408 !ENGINE_ctrl_cmd_string(iterator, "DIR_LOAD", "2", 0) ||
409 !ENGINE_ctrl_cmd_string(iterator, "DIR_ADD",
410 load_dir, 0) ||
411 !ENGINE_ctrl_cmd_string(iterator, "LOAD", NULL, 0))
412 goto notfound;
413 return iterator;
414 }
415notfound:
416 ENGINE_free(iterator);
417 ENGINEerr(ENGINE_F_ENGINE_BY_ID,ENGINE_R_NO_SUCH_ENGINE);
418 ERR_add_error_data(2, "id=", id);
419 return NULL;
420 /* EEK! Experimental code ends */
421#endif
422 }
423
424int ENGINE_up_ref(ENGINE *e)
425 {
426 if (e == NULL)
427 {
428 ENGINEerr(ENGINE_F_ENGINE_UP_REF,ERR_R_PASSED_NULL_PARAMETER);
429 return 0;
430 }
431 CRYPTO_add(&e->struct_ref,1,CRYPTO_LOCK_ENGINE);
432 return 1;
433 }
diff --git a/src/lib/libcrypto/engine/eng_openssl.c b/src/lib/libcrypto/engine/eng_openssl.c
new file mode 100644
index 0000000000..9abb95cc22
--- /dev/null
+++ b/src/lib/libcrypto/engine/eng_openssl.c
@@ -0,0 +1,384 @@
1/* crypto/engine/eng_openssl.c */
2/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
3 * project 2000.
4 */
5/* ====================================================================
6 * Copyright (c) 1999-2001 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 * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
60 * ECDH support in OpenSSL originally developed by
61 * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
62 */
63
64
65#include <stdio.h>
66#include <openssl/crypto.h>
67#include "cryptlib.h"
68#include <openssl/engine.h>
69#include <openssl/dso.h>
70#include <openssl/pem.h>
71#include <openssl/evp.h>
72#include <openssl/rand.h>
73#ifndef OPENSSL_NO_RSA
74#include <openssl/rsa.h>
75#endif
76#ifndef OPENSSL_NO_DSA
77#include <openssl/dsa.h>
78#endif
79#ifndef OPENSSL_NO_DH
80#include <openssl/dh.h>
81#endif
82
83/* This testing gunk is implemented (and explained) lower down. It also assumes
84 * the application explicitly calls "ENGINE_load_openssl()" because this is no
85 * longer automatic in ENGINE_load_builtin_engines(). */
86#define TEST_ENG_OPENSSL_RC4
87#define TEST_ENG_OPENSSL_PKEY
88/* #define TEST_ENG_OPENSSL_RC4_OTHERS */
89#define TEST_ENG_OPENSSL_RC4_P_INIT
90/* #define TEST_ENG_OPENSSL_RC4_P_CIPHER */
91#define TEST_ENG_OPENSSL_SHA
92/* #define TEST_ENG_OPENSSL_SHA_OTHERS */
93/* #define TEST_ENG_OPENSSL_SHA_P_INIT */
94/* #define TEST_ENG_OPENSSL_SHA_P_UPDATE */
95/* #define TEST_ENG_OPENSSL_SHA_P_FINAL */
96
97/* Now check what of those algorithms are actually enabled */
98#ifdef OPENSSL_NO_RC4
99#undef TEST_ENG_OPENSSL_RC4
100#undef TEST_ENG_OPENSSL_RC4_OTHERS
101#undef TEST_ENG_OPENSSL_RC4_P_INIT
102#undef TEST_ENG_OPENSSL_RC4_P_CIPHER
103#endif
104#if defined(OPENSSL_NO_SHA) || defined(OPENSSL_NO_SHA0) || defined(OPENSSL_NO_SHA1)
105#undef TEST_ENG_OPENSSL_SHA
106#undef TEST_ENG_OPENSSL_SHA_OTHERS
107#undef TEST_ENG_OPENSSL_SHA_P_INIT
108#undef TEST_ENG_OPENSSL_SHA_P_UPDATE
109#undef TEST_ENG_OPENSSL_SHA_P_FINAL
110#endif
111
112#ifdef TEST_ENG_OPENSSL_RC4
113static int openssl_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
114 const int **nids, int nid);
115#endif
116#ifdef TEST_ENG_OPENSSL_SHA
117static int openssl_digests(ENGINE *e, const EVP_MD **digest,
118 const int **nids, int nid);
119#endif
120
121#ifdef TEST_ENG_OPENSSL_PKEY
122static EVP_PKEY *openssl_load_privkey(ENGINE *eng, const char *key_id,
123 UI_METHOD *ui_method, void *callback_data);
124#endif
125
126/* The constants used when creating the ENGINE */
127static const char *engine_openssl_id = "openssl";
128static const char *engine_openssl_name = "Software engine support";
129
130/* This internal function is used by ENGINE_openssl() and possibly by the
131 * "dynamic" ENGINE support too */
132static int bind_helper(ENGINE *e)
133 {
134 if(!ENGINE_set_id(e, engine_openssl_id)
135 || !ENGINE_set_name(e, engine_openssl_name)
136#ifndef TEST_ENG_OPENSSL_NO_ALGORITHMS
137#ifndef OPENSSL_NO_RSA
138 || !ENGINE_set_RSA(e, RSA_get_default_method())
139#endif
140#ifndef OPENSSL_NO_DSA
141 || !ENGINE_set_DSA(e, DSA_get_default_method())
142#endif
143#ifndef OPENSSL_NO_ECDH
144 || !ENGINE_set_ECDH(e, ECDH_OpenSSL())
145#endif
146#ifndef OPENSSL_NO_ECDSA
147 || !ENGINE_set_ECDSA(e, ECDSA_OpenSSL())
148#endif
149#ifndef OPENSSL_NO_DH
150 || !ENGINE_set_DH(e, DH_get_default_method())
151#endif
152 || !ENGINE_set_RAND(e, RAND_SSLeay())
153#ifdef TEST_ENG_OPENSSL_RC4
154 || !ENGINE_set_ciphers(e, openssl_ciphers)
155#endif
156#ifdef TEST_ENG_OPENSSL_SHA
157 || !ENGINE_set_digests(e, openssl_digests)
158#endif
159#endif
160#ifdef TEST_ENG_OPENSSL_PKEY
161 || !ENGINE_set_load_privkey_function(e, openssl_load_privkey)
162#endif
163 )
164 return 0;
165 /* If we add errors to this ENGINE, ensure the error handling is setup here */
166 /* openssl_load_error_strings(); */
167 return 1;
168 }
169
170static ENGINE *engine_openssl(void)
171 {
172 ENGINE *ret = ENGINE_new();
173 if(!ret)
174 return NULL;
175 if(!bind_helper(ret))
176 {
177 ENGINE_free(ret);
178 return NULL;
179 }
180 return ret;
181 }
182
183void ENGINE_load_openssl(void)
184 {
185 ENGINE *toadd = engine_openssl();
186 if(!toadd) return;
187 ENGINE_add(toadd);
188 /* If the "add" worked, it gets a structural reference. So either way,
189 * we release our just-created reference. */
190 ENGINE_free(toadd);
191 ERR_clear_error();
192 }
193
194/* This stuff is needed if this ENGINE is being compiled into a self-contained
195 * shared-library. */
196#ifdef ENGINE_DYNAMIC_SUPPORT
197static int bind_fn(ENGINE *e, const char *id)
198 {
199 if(id && (strcmp(id, engine_openssl_id) != 0))
200 return 0;
201 if(!bind_helper(e))
202 return 0;
203 return 1;
204 }
205IMPLEMENT_DYNAMIC_CHECK_FN()
206IMPLEMENT_DYNAMIC_BIND_FN(bind_fn)
207#endif /* ENGINE_DYNAMIC_SUPPORT */
208
209#ifdef TEST_ENG_OPENSSL_RC4
210/* This section of code compiles an "alternative implementation" of two modes of
211 * RC4 into this ENGINE. The result is that EVP_CIPHER operation for "rc4"
212 * should under normal circumstances go via this support rather than the default
213 * EVP support. There are other symbols to tweak the testing;
214 * TEST_ENC_OPENSSL_RC4_OTHERS - print a one line message to stderr each time
215 * we're asked for a cipher we don't support (should not happen).
216 * TEST_ENG_OPENSSL_RC4_P_INIT - print a one line message to stderr each time
217 * the "init_key" handler is called.
218 * TEST_ENG_OPENSSL_RC4_P_CIPHER - ditto for the "cipher" handler.
219 */
220#include <openssl/rc4.h>
221#define TEST_RC4_KEY_SIZE 16
222static int test_cipher_nids[] = {NID_rc4,NID_rc4_40};
223static int test_cipher_nids_number = 2;
224typedef struct {
225 unsigned char key[TEST_RC4_KEY_SIZE];
226 RC4_KEY ks;
227 } TEST_RC4_KEY;
228#define test(ctx) ((TEST_RC4_KEY *)(ctx)->cipher_data)
229static int test_rc4_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
230 const unsigned char *iv, int enc)
231 {
232#ifdef TEST_ENG_OPENSSL_RC4_P_INIT
233 fprintf(stderr, "(TEST_ENG_OPENSSL_RC4) test_init_key() called\n");
234#endif
235 memcpy(&test(ctx)->key[0],key,EVP_CIPHER_CTX_key_length(ctx));
236 RC4_set_key(&test(ctx)->ks,EVP_CIPHER_CTX_key_length(ctx),
237 test(ctx)->key);
238 return 1;
239 }
240static int test_rc4_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
241 const unsigned char *in, size_t inl)
242 {
243#ifdef TEST_ENG_OPENSSL_RC4_P_CIPHER
244 fprintf(stderr, "(TEST_ENG_OPENSSL_RC4) test_cipher() called\n");
245#endif
246 RC4(&test(ctx)->ks,inl,in,out);
247 return 1;
248 }
249static const EVP_CIPHER test_r4_cipher=
250 {
251 NID_rc4,
252 1,TEST_RC4_KEY_SIZE,0,
253 EVP_CIPH_VARIABLE_LENGTH,
254 test_rc4_init_key,
255 test_rc4_cipher,
256 NULL,
257 sizeof(TEST_RC4_KEY),
258 NULL,
259 NULL,
260 NULL,
261 NULL
262 };
263static const EVP_CIPHER test_r4_40_cipher=
264 {
265 NID_rc4_40,
266 1,5 /* 40 bit */,0,
267 EVP_CIPH_VARIABLE_LENGTH,
268 test_rc4_init_key,
269 test_rc4_cipher,
270 NULL,
271 sizeof(TEST_RC4_KEY),
272 NULL,
273 NULL,
274 NULL,
275 NULL
276 };
277static int openssl_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
278 const int **nids, int nid)
279 {
280 if(!cipher)
281 {
282 /* We are returning a list of supported nids */
283 *nids = test_cipher_nids;
284 return test_cipher_nids_number;
285 }
286 /* We are being asked for a specific cipher */
287 if(nid == NID_rc4)
288 *cipher = &test_r4_cipher;
289 else if(nid == NID_rc4_40)
290 *cipher = &test_r4_40_cipher;
291 else
292 {
293#ifdef TEST_ENG_OPENSSL_RC4_OTHERS
294 fprintf(stderr, "(TEST_ENG_OPENSSL_RC4) returning NULL for "
295 "nid %d\n", nid);
296#endif
297 *cipher = NULL;
298 return 0;
299 }
300 return 1;
301 }
302#endif
303
304#ifdef TEST_ENG_OPENSSL_SHA
305/* Much the same sort of comment as for TEST_ENG_OPENSSL_RC4 */
306#include <openssl/sha.h>
307static int test_digest_nids[] = {NID_sha1};
308static int test_digest_nids_number = 1;
309static int test_sha1_init(EVP_MD_CTX *ctx)
310 {
311#ifdef TEST_ENG_OPENSSL_SHA_P_INIT
312 fprintf(stderr, "(TEST_ENG_OPENSSL_SHA) test_sha1_init() called\n");
313#endif
314 return SHA1_Init(ctx->md_data);
315 }
316static int test_sha1_update(EVP_MD_CTX *ctx,const void *data,size_t count)
317 {
318#ifdef TEST_ENG_OPENSSL_SHA_P_UPDATE
319 fprintf(stderr, "(TEST_ENG_OPENSSL_SHA) test_sha1_update() called\n");
320#endif
321 return SHA1_Update(ctx->md_data,data,count);
322 }
323static int test_sha1_final(EVP_MD_CTX *ctx,unsigned char *md)
324 {
325#ifdef TEST_ENG_OPENSSL_SHA_P_FINAL
326 fprintf(stderr, "(TEST_ENG_OPENSSL_SHA) test_sha1_final() called\n");
327#endif
328 return SHA1_Final(md,ctx->md_data);
329 }
330static const EVP_MD test_sha_md=
331 {
332 NID_sha1,
333 NID_sha1WithRSAEncryption,
334 SHA_DIGEST_LENGTH,
335 0,
336 test_sha1_init,
337 test_sha1_update,
338 test_sha1_final,
339 NULL,
340 NULL,
341 EVP_PKEY_RSA_method,
342 SHA_CBLOCK,
343 sizeof(EVP_MD *)+sizeof(SHA_CTX),
344 };
345static int openssl_digests(ENGINE *e, const EVP_MD **digest,
346 const int **nids, int nid)
347 {
348 if(!digest)
349 {
350 /* We are returning a list of supported nids */
351 *nids = test_digest_nids;
352 return test_digest_nids_number;
353 }
354 /* We are being asked for a specific digest */
355 if(nid == NID_sha1)
356 *digest = &test_sha_md;
357 else
358 {
359#ifdef TEST_ENG_OPENSSL_SHA_OTHERS
360 fprintf(stderr, "(TEST_ENG_OPENSSL_SHA) returning NULL for "
361 "nid %d\n", nid);
362#endif
363 *digest = NULL;
364 return 0;
365 }
366 return 1;
367 }
368#endif
369
370#ifdef TEST_ENG_OPENSSL_PKEY
371static EVP_PKEY *openssl_load_privkey(ENGINE *eng, const char *key_id,
372 UI_METHOD *ui_method, void *callback_data)
373 {
374 BIO *in;
375 EVP_PKEY *key;
376 fprintf(stderr, "(TEST_ENG_OPENSSL_PKEY)Loading Private key %s\n", key_id);
377 in = BIO_new_file(key_id, "r");
378 if (!in)
379 return NULL;
380 key = PEM_read_bio_PrivateKey(in, NULL, 0, NULL);
381 BIO_free(in);
382 return key;
383 }
384#endif
diff --git a/src/lib/libcrypto/engine/eng_padlock.c b/src/lib/libcrypto/engine/eng_padlock.c
new file mode 100644
index 0000000000..743558ab33
--- /dev/null
+++ b/src/lib/libcrypto/engine/eng_padlock.c
@@ -0,0 +1,1219 @@
1/*
2 * Support for VIA PadLock Advanced Cryptography Engine (ACE)
3 * Written by Michal Ludvig <michal@logix.cz>
4 * http://www.logix.cz/michal
5 *
6 * Big thanks to Andy Polyakov for a help with optimization,
7 * assembler fixes, port to MS Windows and a lot of other
8 * valuable work on this engine!
9 */
10
11/* ====================================================================
12 * Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved.
13 *
14 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions
16 * are met:
17 *
18 * 1. Redistributions of source code must retain the above copyright
19 * notice, this list of conditions and the following disclaimer.
20 *
21 * 2. Redistributions in binary form must reproduce the above copyright
22 * notice, this list of conditions and the following disclaimer in
23 * the documentation and/or other materials provided with the
24 * distribution.
25 *
26 * 3. All advertising materials mentioning features or use of this
27 * software must display the following acknowledgment:
28 * "This product includes software developed by the OpenSSL Project
29 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
30 *
31 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
32 * endorse or promote products derived from this software without
33 * prior written permission. For written permission, please contact
34 * licensing@OpenSSL.org.
35 *
36 * 5. Products derived from this software may not be called "OpenSSL"
37 * nor may "OpenSSL" appear in their names without prior written
38 * permission of the OpenSSL Project.
39 *
40 * 6. Redistributions of any form whatsoever must retain the following
41 * acknowledgment:
42 * "This product includes software developed by the OpenSSL Project
43 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
44 *
45 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
46 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
47 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
48 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
49 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
50 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
51 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
52 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
53 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
54 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
55 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
56 * OF THE POSSIBILITY OF SUCH DAMAGE.
57 * ====================================================================
58 *
59 * This product includes cryptographic software written by Eric Young
60 * (eay@cryptsoft.com). This product includes software written by Tim
61 * Hudson (tjh@cryptsoft.com).
62 *
63 */
64
65
66#include <stdio.h>
67#include <string.h>
68
69#include <openssl/opensslconf.h>
70#include <openssl/crypto.h>
71#include <openssl/dso.h>
72#include <openssl/engine.h>
73#include <openssl/evp.h>
74#ifndef OPENSSL_NO_AES
75#include <openssl/aes.h>
76#endif
77#include <openssl/rand.h>
78#include <openssl/err.h>
79
80#ifndef OPENSSL_NO_HW
81#ifndef OPENSSL_NO_HW_PADLOCK
82
83/* Attempt to have a single source for both 0.9.7 and 0.9.8 :-) */
84#if (OPENSSL_VERSION_NUMBER >= 0x00908000L)
85# ifndef OPENSSL_NO_DYNAMIC_ENGINE
86# define DYNAMIC_ENGINE
87# endif
88#elif (OPENSSL_VERSION_NUMBER >= 0x00907000L)
89# ifdef ENGINE_DYNAMIC_SUPPORT
90# define DYNAMIC_ENGINE
91# endif
92#else
93# error "Only OpenSSL >= 0.9.7 is supported"
94#endif
95
96/* VIA PadLock AES is available *ONLY* on some x86 CPUs.
97 Not only that it doesn't exist elsewhere, but it
98 even can't be compiled on other platforms!
99
100 In addition, because of the heavy use of inline assembler,
101 compiler choice is limited to GCC and Microsoft C. */
102#undef COMPILE_HW_PADLOCK
103#if !defined(I386_ONLY) && !defined(OPENSSL_NO_INLINE_ASM)
104# if (defined(__GNUC__) && (defined(__i386__) || defined(__i386))) || \
105 (defined(_MSC_VER) && defined(_M_IX86))
106# define COMPILE_HW_PADLOCK
107static ENGINE *ENGINE_padlock (void);
108# endif
109#endif
110
111void ENGINE_load_padlock (void)
112{
113/* On non-x86 CPUs it just returns. */
114#ifdef COMPILE_HW_PADLOCK
115 ENGINE *toadd = ENGINE_padlock ();
116 if (!toadd) return;
117 ENGINE_add (toadd);
118 ENGINE_free (toadd);
119 ERR_clear_error ();
120#endif
121}
122
123#ifdef COMPILE_HW_PADLOCK
124/* We do these includes here to avoid header problems on platforms that
125 do not have the VIA padlock anyway... */
126#ifdef _MSC_VER
127# include <malloc.h>
128# define alloca _alloca
129#elif defined(NETWARE_CLIB) && defined(__GNUC__)
130 void *alloca(size_t);
131# define alloca(s) __builtin_alloca(s)
132#else
133# include <stdlib.h>
134#endif
135
136/* Function for ENGINE detection and control */
137static int padlock_available(void);
138static int padlock_init(ENGINE *e);
139
140/* RNG Stuff */
141static RAND_METHOD padlock_rand;
142
143/* Cipher Stuff */
144#ifndef OPENSSL_NO_AES
145static int padlock_ciphers(ENGINE *e, const EVP_CIPHER **cipher, const int **nids, int nid);
146#endif
147
148/* Engine names */
149static const char *padlock_id = "padlock";
150static char padlock_name[100];
151
152/* Available features */
153static int padlock_use_ace = 0; /* Advanced Cryptography Engine */
154static int padlock_use_rng = 0; /* Random Number Generator */
155#ifndef OPENSSL_NO_AES
156static int padlock_aes_align_required = 1;
157#endif
158
159/* ===== Engine "management" functions ===== */
160
161/* Prepare the ENGINE structure for registration */
162static int
163padlock_bind_helper(ENGINE *e)
164{
165 /* Check available features */
166 padlock_available();
167
168#if 1 /* disable RNG for now, see commentary in vicinity of RNG code */
169 padlock_use_rng=0;
170#endif
171
172 /* Generate a nice engine name with available features */
173 BIO_snprintf(padlock_name, sizeof(padlock_name),
174 "VIA PadLock (%s, %s)",
175 padlock_use_rng ? "RNG" : "no-RNG",
176 padlock_use_ace ? "ACE" : "no-ACE");
177
178 /* Register everything or return with an error */
179 if (!ENGINE_set_id(e, padlock_id) ||
180 !ENGINE_set_name(e, padlock_name) ||
181
182 !ENGINE_set_init_function(e, padlock_init) ||
183#ifndef OPENSSL_NO_AES
184 (padlock_use_ace && !ENGINE_set_ciphers (e, padlock_ciphers)) ||
185#endif
186 (padlock_use_rng && !ENGINE_set_RAND (e, &padlock_rand))) {
187 return 0;
188 }
189
190 /* Everything looks good */
191 return 1;
192}
193
194/* Constructor */
195static ENGINE *
196ENGINE_padlock(void)
197{
198 ENGINE *eng = ENGINE_new();
199
200 if (!eng) {
201 return NULL;
202 }
203
204 if (!padlock_bind_helper(eng)) {
205 ENGINE_free(eng);
206 return NULL;
207 }
208
209 return eng;
210}
211
212/* Check availability of the engine */
213static int
214padlock_init(ENGINE *e)
215{
216 return (padlock_use_rng || padlock_use_ace);
217}
218
219/* This stuff is needed if this ENGINE is being compiled into a self-contained
220 * shared-library.
221 */
222#ifdef DYNAMIC_ENGINE
223static int
224padlock_bind_fn(ENGINE *e, const char *id)
225{
226 if (id && (strcmp(id, padlock_id) != 0)) {
227 return 0;
228 }
229
230 if (!padlock_bind_helper(e)) {
231 return 0;
232 }
233
234 return 1;
235}
236
237IMPLEMENT_DYNAMIC_CHECK_FN ()
238IMPLEMENT_DYNAMIC_BIND_FN (padlock_bind_fn)
239#endif /* DYNAMIC_ENGINE */
240
241/* ===== Here comes the "real" engine ===== */
242
243#ifndef OPENSSL_NO_AES
244/* Some AES-related constants */
245#define AES_BLOCK_SIZE 16
246#define AES_KEY_SIZE_128 16
247#define AES_KEY_SIZE_192 24
248#define AES_KEY_SIZE_256 32
249
250/* Here we store the status information relevant to the
251 current context. */
252/* BIG FAT WARNING:
253 * Inline assembler in PADLOCK_XCRYPT_ASM()
254 * depends on the order of items in this structure.
255 * Don't blindly modify, reorder, etc!
256 */
257struct padlock_cipher_data
258{
259 unsigned char iv[AES_BLOCK_SIZE]; /* Initialization vector */
260 union { unsigned int pad[4];
261 struct {
262 int rounds:4;
263 int dgst:1; /* n/a in C3 */
264 int align:1; /* n/a in C3 */
265 int ciphr:1; /* n/a in C3 */
266 unsigned int keygen:1;
267 int interm:1;
268 unsigned int encdec:1;
269 int ksize:2;
270 } b;
271 } cword; /* Control word */
272 AES_KEY ks; /* Encryption key */
273};
274
275/*
276 * Essentially this variable belongs in thread local storage.
277 * Having this variable global on the other hand can only cause
278 * few bogus key reloads [if any at all on single-CPU system],
279 * so we accept the penatly...
280 */
281static volatile struct padlock_cipher_data *padlock_saved_context;
282#endif
283
284/*
285 * =======================================================
286 * Inline assembler section(s).
287 * =======================================================
288 * Order of arguments is chosen to facilitate Windows port
289 * using __fastcall calling convention. If you wish to add
290 * more routines, keep in mind that first __fastcall
291 * argument is passed in %ecx and second - in %edx.
292 * =======================================================
293 */
294#if defined(__GNUC__) && __GNUC__>=2
295/*
296 * As for excessive "push %ebx"/"pop %ebx" found all over.
297 * When generating position-independent code GCC won't let
298 * us use "b" in assembler templates nor even respect "ebx"
299 * in "clobber description." Therefore the trouble...
300 */
301
302/* Helper function - check if a CPUID instruction
303 is available on this CPU */
304static int
305padlock_insn_cpuid_available(void)
306{
307 int result = -1;
308
309 /* We're checking if the bit #21 of EFLAGS
310 can be toggled. If yes = CPUID is available. */
311 asm volatile (
312 "pushf\n"
313 "popl %%eax\n"
314 "xorl $0x200000, %%eax\n"
315 "movl %%eax, %%ecx\n"
316 "andl $0x200000, %%ecx\n"
317 "pushl %%eax\n"
318 "popf\n"
319 "pushf\n"
320 "popl %%eax\n"
321 "andl $0x200000, %%eax\n"
322 "xorl %%eax, %%ecx\n"
323 "movl %%ecx, %0\n"
324 : "=r" (result) : : "eax", "ecx");
325
326 return (result == 0);
327}
328
329/* Load supported features of the CPU to see if
330 the PadLock is available. */
331static int
332padlock_available(void)
333{
334 char vendor_string[16];
335 unsigned int eax, edx;
336
337 /* First check if the CPUID instruction is available at all... */
338 if (! padlock_insn_cpuid_available())
339 return 0;
340
341 /* Are we running on the Centaur (VIA) CPU? */
342 eax = 0x00000000;
343 vendor_string[12] = 0;
344 asm volatile (
345 "pushl %%ebx\n"
346 "cpuid\n"
347 "movl %%ebx,(%%edi)\n"
348 "movl %%edx,4(%%edi)\n"
349 "movl %%ecx,8(%%edi)\n"
350 "popl %%ebx"
351 : "+a"(eax) : "D"(vendor_string) : "ecx", "edx");
352 if (strcmp(vendor_string, "CentaurHauls") != 0)
353 return 0;
354
355 /* Check for Centaur Extended Feature Flags presence */
356 eax = 0xC0000000;
357 asm volatile ("pushl %%ebx; cpuid; popl %%ebx"
358 : "+a"(eax) : : "ecx", "edx");
359 if (eax < 0xC0000001)
360 return 0;
361
362 /* Read the Centaur Extended Feature Flags */
363 eax = 0xC0000001;
364 asm volatile ("pushl %%ebx; cpuid; popl %%ebx"
365 : "+a"(eax), "=d"(edx) : : "ecx");
366
367 /* Fill up some flags */
368 padlock_use_ace = ((edx & (0x3<<6)) == (0x3<<6));
369 padlock_use_rng = ((edx & (0x3<<2)) == (0x3<<2));
370
371 return padlock_use_ace + padlock_use_rng;
372}
373
374#ifndef OPENSSL_NO_AES
375/* Our own htonl()/ntohl() */
376static inline void
377padlock_bswapl(AES_KEY *ks)
378{
379 size_t i = sizeof(ks->rd_key)/sizeof(ks->rd_key[0]);
380 unsigned int *key = ks->rd_key;
381
382 while (i--) {
383 asm volatile ("bswapl %0" : "+r"(*key));
384 key++;
385 }
386}
387#endif
388
389/* Force key reload from memory to the CPU microcode.
390 Loading EFLAGS from the stack clears EFLAGS[30]
391 which does the trick. */
392static inline void
393padlock_reload_key(void)
394{
395 asm volatile ("pushfl; popfl");
396}
397
398#ifndef OPENSSL_NO_AES
399/*
400 * This is heuristic key context tracing. At first one
401 * believes that one should use atomic swap instructions,
402 * but it's not actually necessary. Point is that if
403 * padlock_saved_context was changed by another thread
404 * after we've read it and before we compare it with cdata,
405 * our key *shall* be reloaded upon thread context switch
406 * and we are therefore set in either case...
407 */
408static inline void
409padlock_verify_context(struct padlock_cipher_data *cdata)
410{
411 asm volatile (
412 "pushfl\n"
413" btl $30,(%%esp)\n"
414" jnc 1f\n"
415" cmpl %2,%1\n"
416" je 1f\n"
417" popfl\n"
418" subl $4,%%esp\n"
419"1: addl $4,%%esp\n"
420" movl %2,%0"
421 :"+m"(padlock_saved_context)
422 : "r"(padlock_saved_context), "r"(cdata) : "cc");
423}
424
425/* Template for padlock_xcrypt_* modes */
426/* BIG FAT WARNING:
427 * The offsets used with 'leal' instructions
428 * describe items of the 'padlock_cipher_data'
429 * structure.
430 */
431#define PADLOCK_XCRYPT_ASM(name,rep_xcrypt) \
432static inline void *name(size_t cnt, \
433 struct padlock_cipher_data *cdata, \
434 void *out, const void *inp) \
435{ void *iv; \
436 asm volatile ( "pushl %%ebx\n" \
437 " leal 16(%0),%%edx\n" \
438 " leal 32(%0),%%ebx\n" \
439 rep_xcrypt "\n" \
440 " popl %%ebx" \
441 : "=a"(iv), "=c"(cnt), "=D"(out), "=S"(inp) \
442 : "0"(cdata), "1"(cnt), "2"(out), "3"(inp) \
443 : "edx", "cc", "memory"); \
444 return iv; \
445}
446
447/* Generate all functions with appropriate opcodes */
448PADLOCK_XCRYPT_ASM(padlock_xcrypt_ecb, ".byte 0xf3,0x0f,0xa7,0xc8") /* rep xcryptecb */
449PADLOCK_XCRYPT_ASM(padlock_xcrypt_cbc, ".byte 0xf3,0x0f,0xa7,0xd0") /* rep xcryptcbc */
450PADLOCK_XCRYPT_ASM(padlock_xcrypt_cfb, ".byte 0xf3,0x0f,0xa7,0xe0") /* rep xcryptcfb */
451PADLOCK_XCRYPT_ASM(padlock_xcrypt_ofb, ".byte 0xf3,0x0f,0xa7,0xe8") /* rep xcryptofb */
452#endif
453
454/* The RNG call itself */
455static inline unsigned int
456padlock_xstore(void *addr, unsigned int edx_in)
457{
458 unsigned int eax_out;
459
460 asm volatile (".byte 0x0f,0xa7,0xc0" /* xstore */
461 : "=a"(eax_out),"=m"(*(unsigned *)addr)
462 : "D"(addr), "d" (edx_in)
463 );
464
465 return eax_out;
466}
467
468/* Why not inline 'rep movsd'? I failed to find information on what
469 * value in Direction Flag one can expect and consequently have to
470 * apply "better-safe-than-sorry" approach and assume "undefined."
471 * I could explicitly clear it and restore the original value upon
472 * return from padlock_aes_cipher, but it's presumably too much
473 * trouble for too little gain...
474 *
475 * In case you wonder 'rep xcrypt*' instructions above are *not*
476 * affected by the Direction Flag and pointers advance toward
477 * larger addresses unconditionally.
478 */
479static inline unsigned char *
480padlock_memcpy(void *dst,const void *src,size_t n)
481{
482 long *d=dst;
483 const long *s=src;
484
485 n /= sizeof(*d);
486 do { *d++ = *s++; } while (--n);
487
488 return dst;
489}
490
491#elif defined(_MSC_VER)
492/*
493 * Unlike GCC these are real functions. In order to minimize impact
494 * on performance we adhere to __fastcall calling convention in
495 * order to get two first arguments passed through %ecx and %edx.
496 * Which kind of suits very well, as instructions in question use
497 * both %ecx and %edx as input:-)
498 */
499#define REP_XCRYPT(code) \
500 _asm _emit 0xf3 \
501 _asm _emit 0x0f _asm _emit 0xa7 \
502 _asm _emit code
503
504/* BIG FAT WARNING:
505 * The offsets used with 'lea' instructions
506 * describe items of the 'padlock_cipher_data'
507 * structure.
508 */
509#define PADLOCK_XCRYPT_ASM(name,code) \
510static void * __fastcall \
511 name (size_t cnt, void *cdata, \
512 void *outp, const void *inp) \
513{ _asm mov eax,edx \
514 _asm lea edx,[eax+16] \
515 _asm lea ebx,[eax+32] \
516 _asm mov edi,outp \
517 _asm mov esi,inp \
518 REP_XCRYPT(code) \
519}
520
521PADLOCK_XCRYPT_ASM(padlock_xcrypt_ecb,0xc8)
522PADLOCK_XCRYPT_ASM(padlock_xcrypt_cbc,0xd0)
523PADLOCK_XCRYPT_ASM(padlock_xcrypt_cfb,0xe0)
524PADLOCK_XCRYPT_ASM(padlock_xcrypt_ofb,0xe8)
525
526static int __fastcall
527padlock_xstore(void *outp,unsigned int code)
528{ _asm mov edi,ecx
529 _asm _emit 0x0f _asm _emit 0xa7 _asm _emit 0xc0
530}
531
532static void __fastcall
533padlock_reload_key(void)
534{ _asm pushfd _asm popfd }
535
536static void __fastcall
537padlock_verify_context(void *cdata)
538{ _asm {
539 pushfd
540 bt DWORD PTR[esp],30
541 jnc skip
542 cmp ecx,padlock_saved_context
543 je skip
544 popfd
545 sub esp,4
546 skip: add esp,4
547 mov padlock_saved_context,ecx
548 }
549}
550
551static int
552padlock_available(void)
553{ _asm {
554 pushfd
555 pop eax
556 mov ecx,eax
557 xor eax,1<<21
558 push eax
559 popfd
560 pushfd
561 pop eax
562 xor eax,ecx
563 bt eax,21
564 jnc noluck
565 mov eax,0
566 cpuid
567 xor eax,eax
568 cmp ebx,'tneC'
569 jne noluck
570 cmp edx,'Hrua'
571 jne noluck
572 cmp ecx,'slua'
573 jne noluck
574 mov eax,0xC0000000
575 cpuid
576 mov edx,eax
577 xor eax,eax
578 cmp edx,0xC0000001
579 jb noluck
580 mov eax,0xC0000001
581 cpuid
582 xor eax,eax
583 bt edx,6
584 jnc skip_a
585 bt edx,7
586 jnc skip_a
587 mov padlock_use_ace,1
588 inc eax
589 skip_a: bt edx,2
590 jnc skip_r
591 bt edx,3
592 jnc skip_r
593 mov padlock_use_rng,1
594 inc eax
595 skip_r:
596 noluck:
597 }
598}
599
600static void __fastcall
601padlock_bswapl(void *key)
602{ _asm {
603 pushfd
604 cld
605 mov esi,ecx
606 mov edi,ecx
607 mov ecx,60
608 up: lodsd
609 bswap eax
610 stosd
611 loop up
612 popfd
613 }
614}
615
616/* MS actually specifies status of Direction Flag and compiler even
617 * manages to compile following as 'rep movsd' all by itself...
618 */
619#define padlock_memcpy(o,i,n) ((unsigned char *)memcpy((o),(i),(n)&~3U))
620#endif
621
622/* ===== AES encryption/decryption ===== */
623#ifndef OPENSSL_NO_AES
624
625#if defined(NID_aes_128_cfb128) && ! defined (NID_aes_128_cfb)
626#define NID_aes_128_cfb NID_aes_128_cfb128
627#endif
628
629#if defined(NID_aes_128_ofb128) && ! defined (NID_aes_128_ofb)
630#define NID_aes_128_ofb NID_aes_128_ofb128
631#endif
632
633#if defined(NID_aes_192_cfb128) && ! defined (NID_aes_192_cfb)
634#define NID_aes_192_cfb NID_aes_192_cfb128
635#endif
636
637#if defined(NID_aes_192_ofb128) && ! defined (NID_aes_192_ofb)
638#define NID_aes_192_ofb NID_aes_192_ofb128
639#endif
640
641#if defined(NID_aes_256_cfb128) && ! defined (NID_aes_256_cfb)
642#define NID_aes_256_cfb NID_aes_256_cfb128
643#endif
644
645#if defined(NID_aes_256_ofb128) && ! defined (NID_aes_256_ofb)
646#define NID_aes_256_ofb NID_aes_256_ofb128
647#endif
648
649/* List of supported ciphers. */
650static int padlock_cipher_nids[] = {
651 NID_aes_128_ecb,
652 NID_aes_128_cbc,
653 NID_aes_128_cfb,
654 NID_aes_128_ofb,
655
656 NID_aes_192_ecb,
657 NID_aes_192_cbc,
658 NID_aes_192_cfb,
659 NID_aes_192_ofb,
660
661 NID_aes_256_ecb,
662 NID_aes_256_cbc,
663 NID_aes_256_cfb,
664 NID_aes_256_ofb,
665};
666static int padlock_cipher_nids_num = (sizeof(padlock_cipher_nids)/
667 sizeof(padlock_cipher_nids[0]));
668
669/* Function prototypes ... */
670static int padlock_aes_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
671 const unsigned char *iv, int enc);
672static int padlock_aes_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
673 const unsigned char *in, size_t nbytes);
674
675#define NEAREST_ALIGNED(ptr) ( (unsigned char *)(ptr) + \
676 ( (0x10 - ((size_t)(ptr) & 0x0F)) & 0x0F ) )
677#define ALIGNED_CIPHER_DATA(ctx) ((struct padlock_cipher_data *)\
678 NEAREST_ALIGNED(ctx->cipher_data))
679
680#define EVP_CIPHER_block_size_ECB AES_BLOCK_SIZE
681#define EVP_CIPHER_block_size_CBC AES_BLOCK_SIZE
682#define EVP_CIPHER_block_size_OFB 1
683#define EVP_CIPHER_block_size_CFB 1
684
685/* Declaring so many ciphers by hand would be a pain.
686 Instead introduce a bit of preprocessor magic :-) */
687#define DECLARE_AES_EVP(ksize,lmode,umode) \
688static const EVP_CIPHER padlock_aes_##ksize##_##lmode = { \
689 NID_aes_##ksize##_##lmode, \
690 EVP_CIPHER_block_size_##umode, \
691 AES_KEY_SIZE_##ksize, \
692 AES_BLOCK_SIZE, \
693 0 | EVP_CIPH_##umode##_MODE, \
694 padlock_aes_init_key, \
695 padlock_aes_cipher, \
696 NULL, \
697 sizeof(struct padlock_cipher_data) + 16, \
698 EVP_CIPHER_set_asn1_iv, \
699 EVP_CIPHER_get_asn1_iv, \
700 NULL, \
701 NULL \
702}
703
704DECLARE_AES_EVP(128,ecb,ECB);
705DECLARE_AES_EVP(128,cbc,CBC);
706DECLARE_AES_EVP(128,cfb,CFB);
707DECLARE_AES_EVP(128,ofb,OFB);
708
709DECLARE_AES_EVP(192,ecb,ECB);
710DECLARE_AES_EVP(192,cbc,CBC);
711DECLARE_AES_EVP(192,cfb,CFB);
712DECLARE_AES_EVP(192,ofb,OFB);
713
714DECLARE_AES_EVP(256,ecb,ECB);
715DECLARE_AES_EVP(256,cbc,CBC);
716DECLARE_AES_EVP(256,cfb,CFB);
717DECLARE_AES_EVP(256,ofb,OFB);
718
719static int
720padlock_ciphers (ENGINE *e, const EVP_CIPHER **cipher, const int **nids, int nid)
721{
722 /* No specific cipher => return a list of supported nids ... */
723 if (!cipher) {
724 *nids = padlock_cipher_nids;
725 return padlock_cipher_nids_num;
726 }
727
728 /* ... or the requested "cipher" otherwise */
729 switch (nid) {
730 case NID_aes_128_ecb:
731 *cipher = &padlock_aes_128_ecb;
732 break;
733 case NID_aes_128_cbc:
734 *cipher = &padlock_aes_128_cbc;
735 break;
736 case NID_aes_128_cfb:
737 *cipher = &padlock_aes_128_cfb;
738 break;
739 case NID_aes_128_ofb:
740 *cipher = &padlock_aes_128_ofb;
741 break;
742
743 case NID_aes_192_ecb:
744 *cipher = &padlock_aes_192_ecb;
745 break;
746 case NID_aes_192_cbc:
747 *cipher = &padlock_aes_192_cbc;
748 break;
749 case NID_aes_192_cfb:
750 *cipher = &padlock_aes_192_cfb;
751 break;
752 case NID_aes_192_ofb:
753 *cipher = &padlock_aes_192_ofb;
754 break;
755
756 case NID_aes_256_ecb:
757 *cipher = &padlock_aes_256_ecb;
758 break;
759 case NID_aes_256_cbc:
760 *cipher = &padlock_aes_256_cbc;
761 break;
762 case NID_aes_256_cfb:
763 *cipher = &padlock_aes_256_cfb;
764 break;
765 case NID_aes_256_ofb:
766 *cipher = &padlock_aes_256_ofb;
767 break;
768
769 default:
770 /* Sorry, we don't support this NID */
771 *cipher = NULL;
772 return 0;
773 }
774
775 return 1;
776}
777
778/* Prepare the encryption key for PadLock usage */
779static int
780padlock_aes_init_key (EVP_CIPHER_CTX *ctx, const unsigned char *key,
781 const unsigned char *iv, int enc)
782{
783 struct padlock_cipher_data *cdata;
784 int key_len = EVP_CIPHER_CTX_key_length(ctx) * 8;
785
786 if (key==NULL) return 0; /* ERROR */
787
788 cdata = ALIGNED_CIPHER_DATA(ctx);
789 memset(cdata, 0, sizeof(struct padlock_cipher_data));
790
791 /* Prepare Control word. */
792 if (EVP_CIPHER_CTX_mode(ctx) == EVP_CIPH_OFB_MODE)
793 cdata->cword.b.encdec = 0;
794 else
795 cdata->cword.b.encdec = (ctx->encrypt == 0);
796 cdata->cword.b.rounds = 10 + (key_len - 128) / 32;
797 cdata->cword.b.ksize = (key_len - 128) / 64;
798
799 switch(key_len) {
800 case 128:
801 /* PadLock can generate an extended key for
802 AES128 in hardware */
803 memcpy(cdata->ks.rd_key, key, AES_KEY_SIZE_128);
804 cdata->cword.b.keygen = 0;
805 break;
806
807 case 192:
808 case 256:
809 /* Generate an extended AES key in software.
810 Needed for AES192/AES256 */
811 /* Well, the above applies to Stepping 8 CPUs
812 and is listed as hardware errata. They most
813 likely will fix it at some point and then
814 a check for stepping would be due here. */
815 if (EVP_CIPHER_CTX_mode(ctx) == EVP_CIPH_CFB_MODE ||
816 EVP_CIPHER_CTX_mode(ctx) == EVP_CIPH_OFB_MODE ||
817 enc)
818 AES_set_encrypt_key(key, key_len, &cdata->ks);
819 else
820 AES_set_decrypt_key(key, key_len, &cdata->ks);
821#ifndef AES_ASM
822 /* OpenSSL C functions use byte-swapped extended key. */
823 padlock_bswapl(&cdata->ks);
824#endif
825 cdata->cword.b.keygen = 1;
826 break;
827
828 default:
829 /* ERROR */
830 return 0;
831 }
832
833 /*
834 * This is done to cover for cases when user reuses the
835 * context for new key. The catch is that if we don't do
836 * this, padlock_eas_cipher might proceed with old key...
837 */
838 padlock_reload_key ();
839
840 return 1;
841}
842
843/*
844 * Simplified version of padlock_aes_cipher() used when
845 * 1) both input and output buffers are at aligned addresses.
846 * or when
847 * 2) running on a newer CPU that doesn't require aligned buffers.
848 */
849static int
850padlock_aes_cipher_omnivorous(EVP_CIPHER_CTX *ctx, unsigned char *out_arg,
851 const unsigned char *in_arg, size_t nbytes)
852{
853 struct padlock_cipher_data *cdata;
854 void *iv;
855
856 cdata = ALIGNED_CIPHER_DATA(ctx);
857 padlock_verify_context(cdata);
858
859 switch (EVP_CIPHER_CTX_mode(ctx)) {
860 case EVP_CIPH_ECB_MODE:
861 padlock_xcrypt_ecb(nbytes/AES_BLOCK_SIZE, cdata, out_arg, in_arg);
862 break;
863
864 case EVP_CIPH_CBC_MODE:
865 memcpy(cdata->iv, ctx->iv, AES_BLOCK_SIZE);
866 iv = padlock_xcrypt_cbc(nbytes/AES_BLOCK_SIZE, cdata, out_arg, in_arg);
867 memcpy(ctx->iv, iv, AES_BLOCK_SIZE);
868 break;
869
870 case EVP_CIPH_CFB_MODE:
871 memcpy(cdata->iv, ctx->iv, AES_BLOCK_SIZE);
872 iv = padlock_xcrypt_cfb(nbytes/AES_BLOCK_SIZE, cdata, out_arg, in_arg);
873 memcpy(ctx->iv, iv, AES_BLOCK_SIZE);
874 break;
875
876 case EVP_CIPH_OFB_MODE:
877 memcpy(cdata->iv, ctx->iv, AES_BLOCK_SIZE);
878 padlock_xcrypt_ofb(nbytes/AES_BLOCK_SIZE, cdata, out_arg, in_arg);
879 memcpy(ctx->iv, cdata->iv, AES_BLOCK_SIZE);
880 break;
881
882 default:
883 return 0;
884 }
885
886 memset(cdata->iv, 0, AES_BLOCK_SIZE);
887
888 return 1;
889}
890
891#ifndef PADLOCK_CHUNK
892# define PADLOCK_CHUNK 512 /* Must be a power of 2 larger than 16 */
893#endif
894#if PADLOCK_CHUNK<16 || PADLOCK_CHUNK&(PADLOCK_CHUNK-1)
895# error "insane PADLOCK_CHUNK..."
896#endif
897
898/* Re-align the arguments to 16-Bytes boundaries and run the
899 encryption function itself. This function is not AES-specific. */
900static int
901padlock_aes_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out_arg,
902 const unsigned char *in_arg, size_t nbytes)
903{
904 struct padlock_cipher_data *cdata;
905 const void *inp;
906 unsigned char *out;
907 void *iv;
908 int inp_misaligned, out_misaligned, realign_in_loop;
909 size_t chunk, allocated=0;
910
911 /* ctx->num is maintained in byte-oriented modes,
912 such as CFB and OFB... */
913 if ((chunk = ctx->num)) { /* borrow chunk variable */
914 unsigned char *ivp=ctx->iv;
915
916 switch (EVP_CIPHER_CTX_mode(ctx)) {
917 case EVP_CIPH_CFB_MODE:
918 if (chunk >= AES_BLOCK_SIZE)
919 return 0; /* bogus value */
920
921 if (ctx->encrypt)
922 while (chunk<AES_BLOCK_SIZE && nbytes!=0) {
923 ivp[chunk] = *(out_arg++) = *(in_arg++) ^ ivp[chunk];
924 chunk++, nbytes--;
925 }
926 else while (chunk<AES_BLOCK_SIZE && nbytes!=0) {
927 unsigned char c = *(in_arg++);
928 *(out_arg++) = c ^ ivp[chunk];
929 ivp[chunk++] = c, nbytes--;
930 }
931
932 ctx->num = chunk%AES_BLOCK_SIZE;
933 break;
934 case EVP_CIPH_OFB_MODE:
935 if (chunk >= AES_BLOCK_SIZE)
936 return 0; /* bogus value */
937
938 while (chunk<AES_BLOCK_SIZE && nbytes!=0) {
939 *(out_arg++) = *(in_arg++) ^ ivp[chunk];
940 chunk++, nbytes--;
941 }
942
943 ctx->num = chunk%AES_BLOCK_SIZE;
944 break;
945 }
946 }
947
948 if (nbytes == 0)
949 return 1;
950#if 0
951 if (nbytes % AES_BLOCK_SIZE)
952 return 0; /* are we expected to do tail processing? */
953#else
954 /* nbytes is always multiple of AES_BLOCK_SIZE in ECB and CBC
955 modes and arbitrary value in byte-oriented modes, such as
956 CFB and OFB... */
957#endif
958
959 /* VIA promises CPUs that won't require alignment in the future.
960 For now padlock_aes_align_required is initialized to 1 and
961 the condition is never met... */
962 /* C7 core is capable to manage unaligned input in non-ECB[!]
963 mode, but performance penalties appear to be approximately
964 same as for software alignment below or ~3x. They promise to
965 improve it in the future, but for now we can just as well
966 pretend that it can only handle aligned input... */
967 if (!padlock_aes_align_required && (nbytes%AES_BLOCK_SIZE)==0)
968 return padlock_aes_cipher_omnivorous(ctx, out_arg, in_arg, nbytes);
969
970 inp_misaligned = (((size_t)in_arg) & 0x0F);
971 out_misaligned = (((size_t)out_arg) & 0x0F);
972
973 /* Note that even if output is aligned and input not,
974 * I still prefer to loop instead of copy the whole
975 * input and then encrypt in one stroke. This is done
976 * in order to improve L1 cache utilization... */
977 realign_in_loop = out_misaligned|inp_misaligned;
978
979 if (!realign_in_loop && (nbytes%AES_BLOCK_SIZE)==0)
980 return padlock_aes_cipher_omnivorous(ctx, out_arg, in_arg, nbytes);
981
982 /* this takes one "if" out of the loops */
983 chunk = nbytes;
984 chunk %= PADLOCK_CHUNK;
985 if (chunk==0) chunk = PADLOCK_CHUNK;
986
987 if (out_misaligned) {
988 /* optmize for small input */
989 allocated = (chunk<nbytes?PADLOCK_CHUNK:nbytes);
990 out = alloca(0x10 + allocated);
991 out = NEAREST_ALIGNED(out);
992 }
993 else
994 out = out_arg;
995
996 cdata = ALIGNED_CIPHER_DATA(ctx);
997 padlock_verify_context(cdata);
998
999 switch (EVP_CIPHER_CTX_mode(ctx)) {
1000 case EVP_CIPH_ECB_MODE:
1001 do {
1002 if (inp_misaligned)
1003 inp = padlock_memcpy(out, in_arg, chunk);
1004 else
1005 inp = in_arg;
1006 in_arg += chunk;
1007
1008 padlock_xcrypt_ecb(chunk/AES_BLOCK_SIZE, cdata, out, inp);
1009
1010 if (out_misaligned)
1011 out_arg = padlock_memcpy(out_arg, out, chunk) + chunk;
1012 else
1013 out = out_arg+=chunk;
1014
1015 nbytes -= chunk;
1016 chunk = PADLOCK_CHUNK;
1017 } while (nbytes);
1018 break;
1019
1020 case EVP_CIPH_CBC_MODE:
1021 memcpy(cdata->iv, ctx->iv, AES_BLOCK_SIZE);
1022 goto cbc_shortcut;
1023 do {
1024 if (iv != cdata->iv)
1025 memcpy(cdata->iv, iv, AES_BLOCK_SIZE);
1026 chunk = PADLOCK_CHUNK;
1027 cbc_shortcut: /* optimize for small input */
1028 if (inp_misaligned)
1029 inp = padlock_memcpy(out, in_arg, chunk);
1030 else
1031 inp = in_arg;
1032 in_arg += chunk;
1033
1034 iv = padlock_xcrypt_cbc(chunk/AES_BLOCK_SIZE, cdata, out, inp);
1035
1036 if (out_misaligned)
1037 out_arg = padlock_memcpy(out_arg, out, chunk) + chunk;
1038 else
1039 out = out_arg+=chunk;
1040
1041 } while (nbytes -= chunk);
1042 memcpy(ctx->iv, iv, AES_BLOCK_SIZE);
1043 break;
1044
1045 case EVP_CIPH_CFB_MODE:
1046 memcpy (iv = cdata->iv, ctx->iv, AES_BLOCK_SIZE);
1047 chunk &= ~(AES_BLOCK_SIZE-1);
1048 if (chunk) goto cfb_shortcut;
1049 else goto cfb_skiploop;
1050 do {
1051 if (iv != cdata->iv)
1052 memcpy(cdata->iv, iv, AES_BLOCK_SIZE);
1053 chunk = PADLOCK_CHUNK;
1054 cfb_shortcut: /* optimize for small input */
1055 if (inp_misaligned)
1056 inp = padlock_memcpy(out, in_arg, chunk);
1057 else
1058 inp = in_arg;
1059 in_arg += chunk;
1060
1061 iv = padlock_xcrypt_cfb(chunk/AES_BLOCK_SIZE, cdata, out, inp);
1062
1063 if (out_misaligned)
1064 out_arg = padlock_memcpy(out_arg, out, chunk) + chunk;
1065 else
1066 out = out_arg+=chunk;
1067
1068 nbytes -= chunk;
1069 } while (nbytes >= AES_BLOCK_SIZE);
1070
1071 cfb_skiploop:
1072 if (nbytes) {
1073 unsigned char *ivp = cdata->iv;
1074
1075 if (iv != ivp) {
1076 memcpy(ivp, iv, AES_BLOCK_SIZE);
1077 iv = ivp;
1078 }
1079 ctx->num = nbytes;
1080 if (cdata->cword.b.encdec) {
1081 cdata->cword.b.encdec=0;
1082 padlock_reload_key();
1083 padlock_xcrypt_ecb(1,cdata,ivp,ivp);
1084 cdata->cword.b.encdec=1;
1085 padlock_reload_key();
1086 while(nbytes) {
1087 unsigned char c = *(in_arg++);
1088 *(out_arg++) = c ^ *ivp;
1089 *(ivp++) = c, nbytes--;
1090 }
1091 }
1092 else { padlock_reload_key();
1093 padlock_xcrypt_ecb(1,cdata,ivp,ivp);
1094 padlock_reload_key();
1095 while (nbytes) {
1096 *ivp = *(out_arg++) = *(in_arg++) ^ *ivp;
1097 ivp++, nbytes--;
1098 }
1099 }
1100 }
1101
1102 memcpy(ctx->iv, iv, AES_BLOCK_SIZE);
1103 break;
1104
1105 case EVP_CIPH_OFB_MODE:
1106 memcpy(cdata->iv, ctx->iv, AES_BLOCK_SIZE);
1107 chunk &= ~(AES_BLOCK_SIZE-1);
1108 if (chunk) do {
1109 if (inp_misaligned)
1110 inp = padlock_memcpy(out, in_arg, chunk);
1111 else
1112 inp = in_arg;
1113 in_arg += chunk;
1114
1115 padlock_xcrypt_ofb(chunk/AES_BLOCK_SIZE, cdata, out, inp);
1116
1117 if (out_misaligned)
1118 out_arg = padlock_memcpy(out_arg, out, chunk) + chunk;
1119 else
1120 out = out_arg+=chunk;
1121
1122 nbytes -= chunk;
1123 chunk = PADLOCK_CHUNK;
1124 } while (nbytes >= AES_BLOCK_SIZE);
1125
1126 if (nbytes) {
1127 unsigned char *ivp = cdata->iv;
1128
1129 ctx->num = nbytes;
1130 padlock_reload_key(); /* empirically found */
1131 padlock_xcrypt_ecb(1,cdata,ivp,ivp);
1132 padlock_reload_key(); /* empirically found */
1133 while (nbytes) {
1134 *(out_arg++) = *(in_arg++) ^ *ivp;
1135 ivp++, nbytes--;
1136 }
1137 }
1138
1139 memcpy(ctx->iv, cdata->iv, AES_BLOCK_SIZE);
1140 break;
1141
1142 default:
1143 return 0;
1144 }
1145
1146 /* Clean the realign buffer if it was used */
1147 if (out_misaligned) {
1148 volatile unsigned long *p=(void *)out;
1149 size_t n = allocated/sizeof(*p);
1150 while (n--) *p++=0;
1151 }
1152
1153 memset(cdata->iv, 0, AES_BLOCK_SIZE);
1154
1155 return 1;
1156}
1157
1158#endif /* OPENSSL_NO_AES */
1159
1160/* ===== Random Number Generator ===== */
1161/*
1162 * This code is not engaged. The reason is that it does not comply
1163 * with recommendations for VIA RNG usage for secure applications
1164 * (posted at http://www.via.com.tw/en/viac3/c3.jsp) nor does it
1165 * provide meaningful error control...
1166 */
1167/* Wrapper that provides an interface between the API and
1168 the raw PadLock RNG */
1169static int
1170padlock_rand_bytes(unsigned char *output, int count)
1171{
1172 unsigned int eax, buf;
1173
1174 while (count >= 8) {
1175 eax = padlock_xstore(output, 0);
1176 if (!(eax&(1<<6))) return 0; /* RNG disabled */
1177 /* this ---vv--- covers DC bias, Raw Bits and String Filter */
1178 if (eax&(0x1F<<10)) return 0;
1179 if ((eax&0x1F)==0) continue; /* no data, retry... */
1180 if ((eax&0x1F)!=8) return 0; /* fatal failure... */
1181 output += 8;
1182 count -= 8;
1183 }
1184 while (count > 0) {
1185 eax = padlock_xstore(&buf, 3);
1186 if (!(eax&(1<<6))) return 0; /* RNG disabled */
1187 /* this ---vv--- covers DC bias, Raw Bits and String Filter */
1188 if (eax&(0x1F<<10)) return 0;
1189 if ((eax&0x1F)==0) continue; /* no data, retry... */
1190 if ((eax&0x1F)!=1) return 0; /* fatal failure... */
1191 *output++ = (unsigned char)buf;
1192 count--;
1193 }
1194 *(volatile unsigned int *)&buf=0;
1195
1196 return 1;
1197}
1198
1199/* Dummy but necessary function */
1200static int
1201padlock_rand_status(void)
1202{
1203 return 1;
1204}
1205
1206/* Prepare structure for registration */
1207static RAND_METHOD padlock_rand = {
1208 NULL, /* seed */
1209 padlock_rand_bytes, /* bytes */
1210 NULL, /* cleanup */
1211 NULL, /* add */
1212 padlock_rand_bytes, /* pseudorand */
1213 padlock_rand_status, /* rand status */
1214};
1215
1216#endif /* COMPILE_HW_PADLOCK */
1217
1218#endif /* !OPENSSL_NO_HW_PADLOCK */
1219#endif /* !OPENSSL_NO_HW */
diff --git a/src/lib/libcrypto/engine/eng_pkey.c b/src/lib/libcrypto/engine/eng_pkey.c
new file mode 100644
index 0000000000..1dfa2e3664
--- /dev/null
+++ b/src/lib/libcrypto/engine/eng_pkey.c
@@ -0,0 +1,196 @@
1/* crypto/engine/eng_pkey.c */
2/* ====================================================================
3 * Copyright (c) 1999-2001 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 * licensing@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#include "eng_int.h"
57
58/* Basic get/set stuff */
59
60int ENGINE_set_load_privkey_function(ENGINE *e, ENGINE_LOAD_KEY_PTR loadpriv_f)
61 {
62 e->load_privkey = loadpriv_f;
63 return 1;
64 }
65
66int ENGINE_set_load_pubkey_function(ENGINE *e, ENGINE_LOAD_KEY_PTR loadpub_f)
67 {
68 e->load_pubkey = loadpub_f;
69 return 1;
70 }
71
72int ENGINE_set_load_ssl_client_cert_function(ENGINE *e,
73 ENGINE_SSL_CLIENT_CERT_PTR loadssl_f)
74 {
75 e->load_ssl_client_cert = loadssl_f;
76 return 1;
77 }
78
79ENGINE_LOAD_KEY_PTR ENGINE_get_load_privkey_function(const ENGINE *e)
80 {
81 return e->load_privkey;
82 }
83
84ENGINE_LOAD_KEY_PTR ENGINE_get_load_pubkey_function(const ENGINE *e)
85 {
86 return e->load_pubkey;
87 }
88
89ENGINE_SSL_CLIENT_CERT_PTR ENGINE_get_ssl_client_cert_function(const ENGINE *e)
90 {
91 return e->load_ssl_client_cert;
92 }
93
94/* API functions to load public/private keys */
95
96EVP_PKEY *ENGINE_load_private_key(ENGINE *e, const char *key_id,
97 UI_METHOD *ui_method, void *callback_data)
98 {
99 EVP_PKEY *pkey;
100
101 if(e == NULL)
102 {
103 ENGINEerr(ENGINE_F_ENGINE_LOAD_PRIVATE_KEY,
104 ERR_R_PASSED_NULL_PARAMETER);
105 return 0;
106 }
107 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
108 if(e->funct_ref == 0)
109 {
110 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
111 ENGINEerr(ENGINE_F_ENGINE_LOAD_PRIVATE_KEY,
112 ENGINE_R_NOT_INITIALISED);
113 return 0;
114 }
115 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
116 if (!e->load_privkey)
117 {
118 ENGINEerr(ENGINE_F_ENGINE_LOAD_PRIVATE_KEY,
119 ENGINE_R_NO_LOAD_FUNCTION);
120 return 0;
121 }
122 pkey = e->load_privkey(e, key_id, ui_method, callback_data);
123 if (!pkey)
124 {
125 ENGINEerr(ENGINE_F_ENGINE_LOAD_PRIVATE_KEY,
126 ENGINE_R_FAILED_LOADING_PRIVATE_KEY);
127 return 0;
128 }
129 return pkey;
130 }
131
132EVP_PKEY *ENGINE_load_public_key(ENGINE *e, const char *key_id,
133 UI_METHOD *ui_method, void *callback_data)
134 {
135 EVP_PKEY *pkey;
136
137 if(e == NULL)
138 {
139 ENGINEerr(ENGINE_F_ENGINE_LOAD_PUBLIC_KEY,
140 ERR_R_PASSED_NULL_PARAMETER);
141 return 0;
142 }
143 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
144 if(e->funct_ref == 0)
145 {
146 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
147 ENGINEerr(ENGINE_F_ENGINE_LOAD_PUBLIC_KEY,
148 ENGINE_R_NOT_INITIALISED);
149 return 0;
150 }
151 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
152 if (!e->load_pubkey)
153 {
154 ENGINEerr(ENGINE_F_ENGINE_LOAD_PUBLIC_KEY,
155 ENGINE_R_NO_LOAD_FUNCTION);
156 return 0;
157 }
158 pkey = e->load_pubkey(e, key_id, ui_method, callback_data);
159 if (!pkey)
160 {
161 ENGINEerr(ENGINE_F_ENGINE_LOAD_PUBLIC_KEY,
162 ENGINE_R_FAILED_LOADING_PUBLIC_KEY);
163 return 0;
164 }
165 return pkey;
166 }
167
168int ENGINE_load_ssl_client_cert(ENGINE *e, SSL *s,
169 STACK_OF(X509_NAME) *ca_dn, X509 **pcert, EVP_PKEY **ppkey,
170 STACK_OF(X509) **pother, UI_METHOD *ui_method, void *callback_data)
171 {
172
173 if(e == NULL)
174 {
175 ENGINEerr(ENGINE_F_ENGINE_LOAD_SSL_CLIENT_CERT,
176 ERR_R_PASSED_NULL_PARAMETER);
177 return 0;
178 }
179 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
180 if(e->funct_ref == 0)
181 {
182 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
183 ENGINEerr(ENGINE_F_ENGINE_LOAD_SSL_CLIENT_CERT,
184 ENGINE_R_NOT_INITIALISED);
185 return 0;
186 }
187 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
188 if (!e->load_ssl_client_cert)
189 {
190 ENGINEerr(ENGINE_F_ENGINE_LOAD_SSL_CLIENT_CERT,
191 ENGINE_R_NO_LOAD_FUNCTION);
192 return 0;
193 }
194 return e->load_ssl_client_cert(e, s, ca_dn, pcert, ppkey, pother,
195 ui_method, callback_data);
196 }
diff --git a/src/lib/libcrypto/engine/eng_rdrand.c b/src/lib/libcrypto/engine/eng_rdrand.c
new file mode 100644
index 0000000000..a9ba5ae6f9
--- /dev/null
+++ b/src/lib/libcrypto/engine/eng_rdrand.c
@@ -0,0 +1,142 @@
1/* ====================================================================
2 * Copyright (c) 2011 The OpenSSL Project. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in
13 * the documentation and/or other materials provided with the
14 * distribution.
15 *
16 * 3. All advertising materials mentioning features or use of this
17 * software must display the following acknowledgment:
18 * "This product includes software developed by the OpenSSL Project
19 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
20 *
21 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
22 * endorse or promote products derived from this software without
23 * prior written permission. For written permission, please contact
24 * licensing@OpenSSL.org.
25 *
26 * 5. Products derived from this software may not be called "OpenSSL"
27 * nor may "OpenSSL" appear in their names without prior written
28 * permission of the OpenSSL Project.
29 *
30 * 6. Redistributions of any form whatsoever must retain the following
31 * acknowledgment:
32 * "This product includes software developed by the OpenSSL Project
33 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
34 *
35 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
36 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
37 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
38 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
39 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
41 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
42 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
43 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
44 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
45 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
46 * OF THE POSSIBILITY OF SUCH DAMAGE.
47 * ====================================================================
48 */
49
50#include <openssl/opensslconf.h>
51
52#include <stdio.h>
53#include <string.h>
54#include <openssl/engine.h>
55#include <openssl/rand.h>
56#include <openssl/err.h>
57
58#if (defined(__i386) || defined(__i386__) || defined(_M_IX86) || \
59 defined(__x86_64) || defined(__x86_64__) || \
60 defined(_M_AMD64) || defined (_M_X64)) && defined(OPENSSL_CPUID_OBJ)
61
62size_t OPENSSL_ia32_rdrand(void);
63
64static int get_random_bytes (unsigned char *buf, int num)
65 {
66 size_t rnd;
67
68 while (num>=(int)sizeof(size_t)) {
69 if ((rnd = OPENSSL_ia32_rdrand()) == 0) return 0;
70
71 *((size_t *)buf) = rnd;
72 buf += sizeof(size_t);
73 num -= sizeof(size_t);
74 }
75 if (num) {
76 if ((rnd = OPENSSL_ia32_rdrand()) == 0) return 0;
77
78 memcpy (buf,&rnd,num);
79 }
80
81 return 1;
82 }
83
84static int random_status (void)
85{ return 1; }
86
87static RAND_METHOD rdrand_meth =
88 {
89 NULL, /* seed */
90 get_random_bytes,
91 NULL, /* cleanup */
92 NULL, /* add */
93 get_random_bytes,
94 random_status,
95 };
96
97static int rdrand_init(ENGINE *e)
98{ return 1; }
99
100static const char *engine_e_rdrand_id = "rdrand";
101static const char *engine_e_rdrand_name = "Intel RDRAND engine";
102
103static int bind_helper(ENGINE *e)
104 {
105 if (!ENGINE_set_id(e, engine_e_rdrand_id) ||
106 !ENGINE_set_name(e, engine_e_rdrand_name) ||
107 !ENGINE_set_init_function(e, rdrand_init) ||
108 !ENGINE_set_RAND(e, &rdrand_meth) )
109 return 0;
110
111 return 1;
112 }
113
114static ENGINE *ENGINE_rdrand(void)
115 {
116 ENGINE *ret = ENGINE_new();
117 if(!ret)
118 return NULL;
119 if(!bind_helper(ret))
120 {
121 ENGINE_free(ret);
122 return NULL;
123 }
124 return ret;
125 }
126
127void ENGINE_load_rdrand (void)
128 {
129 extern unsigned int OPENSSL_ia32cap_P[];
130
131 if (OPENSSL_ia32cap_P[1] & (1<<(62-32)))
132 {
133 ENGINE *toadd = ENGINE_rdrand();
134 if(!toadd) return;
135 ENGINE_add(toadd);
136 ENGINE_free(toadd);
137 ERR_clear_error();
138 }
139 }
140#else
141void ENGINE_load_rdrand (void) {}
142#endif
diff --git a/src/lib/libcrypto/engine/eng_rsax.c b/src/lib/libcrypto/engine/eng_rsax.c
new file mode 100644
index 0000000000..96e63477ee
--- /dev/null
+++ b/src/lib/libcrypto/engine/eng_rsax.c
@@ -0,0 +1,668 @@
1/* crypto/engine/eng_rsax.c */
2/* Copyright (c) 2010-2010 Intel Corp.
3 * Author: Vinodh.Gopal@intel.com
4 * Jim Guilford
5 * Erdinc.Ozturk@intel.com
6 * Maxim.Perminov@intel.com
7 * Ying.Huang@intel.com
8 *
9 * More information about algorithm used can be found at:
10 * http://www.cse.buffalo.edu/srds2009/escs2009_submission_Gopal.pdf
11 */
12/* ====================================================================
13 * Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved.
14 *
15 * Redistribution and use in source and binary forms, with or without
16 * modification, are permitted provided that the following conditions
17 * are met:
18 *
19 * 1. Redistributions of source code must retain the above copyright
20 * notice, this list of conditions and the following disclaimer.
21 *
22 * 2. Redistributions in binary form must reproduce the above copyright
23 * notice, this list of conditions and the following disclaimer in
24 * the documentation and/or other materials provided with the
25 * distribution.
26 *
27 * 3. All advertising materials mentioning features or use of this
28 * software must display the following acknowledgment:
29 * "This product includes software developed by the OpenSSL Project
30 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
31 *
32 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
33 * endorse or promote products derived from this software without
34 * prior written permission. For written permission, please contact
35 * licensing@OpenSSL.org.
36 *
37 * 5. Products derived from this software may not be called "OpenSSL"
38 * nor may "OpenSSL" appear in their names without prior written
39 * permission of the OpenSSL Project.
40 *
41 * 6. Redistributions of any form whatsoever must retain the following
42 * acknowledgment:
43 * "This product includes software developed by the OpenSSL Project
44 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
45 *
46 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
47 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
48 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
49 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
50 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
51 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
52 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
53 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
54 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
55 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
56 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
57 * OF THE POSSIBILITY OF SUCH DAMAGE.
58 * ====================================================================
59 *
60 * This product includes cryptographic software written by Eric Young
61 * (eay@cryptsoft.com). This product includes software written by Tim
62 * Hudson (tjh@cryptsoft.com).
63 */
64
65#include <openssl/opensslconf.h>
66
67#include <stdio.h>
68#include <string.h>
69#include <openssl/crypto.h>
70#include <openssl/buffer.h>
71#include <openssl/engine.h>
72#ifndef OPENSSL_NO_RSA
73#include <openssl/rsa.h>
74#endif
75#include <openssl/bn.h>
76#include <openssl/err.h>
77
78/* RSAX is available **ONLY* on x86_64 CPUs */
79#undef COMPILE_RSAX
80
81#if (defined(__x86_64) || defined(__x86_64__) || \
82 defined(_M_AMD64) || defined (_M_X64)) && !defined(OPENSSL_NO_ASM)
83#define COMPILE_RSAX
84static ENGINE *ENGINE_rsax (void);
85#endif
86
87void ENGINE_load_rsax (void)
88 {
89/* On non-x86 CPUs it just returns. */
90#ifdef COMPILE_RSAX
91 ENGINE *toadd = ENGINE_rsax();
92 if(!toadd) return;
93 ENGINE_add(toadd);
94 ENGINE_free(toadd);
95 ERR_clear_error();
96#endif
97 }
98
99#ifdef COMPILE_RSAX
100#define E_RSAX_LIB_NAME "rsax engine"
101
102static int e_rsax_destroy(ENGINE *e);
103static int e_rsax_init(ENGINE *e);
104static int e_rsax_finish(ENGINE *e);
105static int e_rsax_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void));
106
107#ifndef OPENSSL_NO_RSA
108/* RSA stuff */
109static int e_rsax_rsa_mod_exp(BIGNUM *r, const BIGNUM *I, RSA *rsa, BN_CTX *ctx);
110static int e_rsax_rsa_finish(RSA *r);
111#endif
112
113static const ENGINE_CMD_DEFN e_rsax_cmd_defns[] = {
114 {0, NULL, NULL, 0}
115 };
116
117#ifndef OPENSSL_NO_RSA
118/* Our internal RSA_METHOD that we provide pointers to */
119static RSA_METHOD e_rsax_rsa =
120 {
121 "Intel RSA-X method",
122 NULL,
123 NULL,
124 NULL,
125 NULL,
126 e_rsax_rsa_mod_exp,
127 NULL,
128 NULL,
129 e_rsax_rsa_finish,
130 RSA_FLAG_CACHE_PUBLIC|RSA_FLAG_CACHE_PRIVATE,
131 NULL,
132 NULL,
133 NULL
134 };
135#endif
136
137/* Constants used when creating the ENGINE */
138static const char *engine_e_rsax_id = "rsax";
139static const char *engine_e_rsax_name = "RSAX engine support";
140
141/* This internal function is used by ENGINE_rsax() */
142static int bind_helper(ENGINE *e)
143 {
144#ifndef OPENSSL_NO_RSA
145 const RSA_METHOD *meth1;
146#endif
147 if(!ENGINE_set_id(e, engine_e_rsax_id) ||
148 !ENGINE_set_name(e, engine_e_rsax_name) ||
149#ifndef OPENSSL_NO_RSA
150 !ENGINE_set_RSA(e, &e_rsax_rsa) ||
151#endif
152 !ENGINE_set_destroy_function(e, e_rsax_destroy) ||
153 !ENGINE_set_init_function(e, e_rsax_init) ||
154 !ENGINE_set_finish_function(e, e_rsax_finish) ||
155 !ENGINE_set_ctrl_function(e, e_rsax_ctrl) ||
156 !ENGINE_set_cmd_defns(e, e_rsax_cmd_defns))
157 return 0;
158
159#ifndef OPENSSL_NO_RSA
160 meth1 = RSA_PKCS1_SSLeay();
161 e_rsax_rsa.rsa_pub_enc = meth1->rsa_pub_enc;
162 e_rsax_rsa.rsa_pub_dec = meth1->rsa_pub_dec;
163 e_rsax_rsa.rsa_priv_enc = meth1->rsa_priv_enc;
164 e_rsax_rsa.rsa_priv_dec = meth1->rsa_priv_dec;
165 e_rsax_rsa.bn_mod_exp = meth1->bn_mod_exp;
166#endif
167 return 1;
168 }
169
170static ENGINE *ENGINE_rsax(void)
171 {
172 ENGINE *ret = ENGINE_new();
173 if(!ret)
174 return NULL;
175 if(!bind_helper(ret))
176 {
177 ENGINE_free(ret);
178 return NULL;
179 }
180 return ret;
181 }
182
183#ifndef OPENSSL_NO_RSA
184/* Used to attach our own key-data to an RSA structure */
185static int rsax_ex_data_idx = -1;
186#endif
187
188static int e_rsax_destroy(ENGINE *e)
189 {
190 return 1;
191 }
192
193/* (de)initialisation functions. */
194static int e_rsax_init(ENGINE *e)
195 {
196#ifndef OPENSSL_NO_RSA
197 if (rsax_ex_data_idx == -1)
198 rsax_ex_data_idx = RSA_get_ex_new_index(0,
199 NULL,
200 NULL, NULL, NULL);
201#endif
202 if (rsax_ex_data_idx == -1)
203 return 0;
204 return 1;
205 }
206
207static int e_rsax_finish(ENGINE *e)
208 {
209 return 1;
210 }
211
212static int e_rsax_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void))
213 {
214 int to_return = 1;
215
216 switch(cmd)
217 {
218 /* The command isn't understood by this engine */
219 default:
220 to_return = 0;
221 break;
222 }
223
224 return to_return;
225 }
226
227
228#ifndef OPENSSL_NO_RSA
229
230#ifdef _WIN32
231typedef unsigned __int64 UINT64;
232#else
233typedef unsigned long long UINT64;
234#endif
235typedef unsigned short UINT16;
236
237/* Table t is interleaved in the following manner:
238 * The order in memory is t[0][0], t[0][1], ..., t[0][7], t[1][0], ...
239 * A particular 512-bit value is stored in t[][index] rather than the more
240 * normal t[index][]; i.e. the qwords of a particular entry in t are not
241 * adjacent in memory
242 */
243
244/* Init BIGNUM b from the interleaved UINT64 array */
245static int interleaved_array_to_bn_512(BIGNUM* b, UINT64 *array);
246
247/* Extract array elements from BIGNUM b
248 * To set the whole array from b, call with n=8
249 */
250static int bn_extract_to_array_512(const BIGNUM* b, unsigned int n, UINT64 *array);
251
252struct mod_ctx_512 {
253 UINT64 t[8][8];
254 UINT64 m[8];
255 UINT64 m1[8]; /* 2^278 % m */
256 UINT64 m2[8]; /* 2^640 % m */
257 UINT64 k1[2]; /* (- 1/m) % 2^128 */
258};
259
260static int mod_exp_pre_compute_data_512(UINT64 *m, struct mod_ctx_512 *data);
261
262void mod_exp_512(UINT64 *result, /* 512 bits, 8 qwords */
263 UINT64 *g, /* 512 bits, 8 qwords */
264 UINT64 *exp, /* 512 bits, 8 qwords */
265 struct mod_ctx_512 *data);
266
267typedef struct st_e_rsax_mod_ctx
268{
269 UINT64 type;
270 union {
271 struct mod_ctx_512 b512;
272 } ctx;
273
274} E_RSAX_MOD_CTX;
275
276static E_RSAX_MOD_CTX *e_rsax_get_ctx(RSA *rsa, int idx, BIGNUM* m)
277{
278 E_RSAX_MOD_CTX *hptr;
279
280 if (idx < 0 || idx > 2)
281 return NULL;
282
283 hptr = RSA_get_ex_data(rsa, rsax_ex_data_idx);
284 if (!hptr) {
285 hptr = OPENSSL_malloc(3*sizeof(E_RSAX_MOD_CTX));
286 if (!hptr) return NULL;
287 hptr[2].type = hptr[1].type= hptr[0].type = 0;
288 RSA_set_ex_data(rsa, rsax_ex_data_idx, hptr);
289 }
290
291 if (hptr[idx].type == (UINT64)BN_num_bits(m))
292 return hptr+idx;
293
294 if (BN_num_bits(m) == 512) {
295 UINT64 _m[8];
296 bn_extract_to_array_512(m, 8, _m);
297 memset( &hptr[idx].ctx.b512, 0, sizeof(struct mod_ctx_512));
298 mod_exp_pre_compute_data_512(_m, &hptr[idx].ctx.b512);
299 }
300
301 hptr[idx].type = BN_num_bits(m);
302 return hptr+idx;
303}
304
305static int e_rsax_rsa_finish(RSA *rsa)
306 {
307 E_RSAX_MOD_CTX *hptr = RSA_get_ex_data(rsa, rsax_ex_data_idx);
308 if(hptr)
309 {
310 OPENSSL_free(hptr);
311 RSA_set_ex_data(rsa, rsax_ex_data_idx, NULL);
312 }
313 if (rsa->_method_mod_n)
314 BN_MONT_CTX_free(rsa->_method_mod_n);
315 if (rsa->_method_mod_p)
316 BN_MONT_CTX_free(rsa->_method_mod_p);
317 if (rsa->_method_mod_q)
318 BN_MONT_CTX_free(rsa->_method_mod_q);
319 return 1;
320 }
321
322
323static int e_rsax_bn_mod_exp(BIGNUM *r, const BIGNUM *g, const BIGNUM *e,
324 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont, E_RSAX_MOD_CTX* rsax_mod_ctx )
325{
326 if (rsax_mod_ctx && BN_get_flags(e, BN_FLG_CONSTTIME) != 0) {
327 if (BN_num_bits(m) == 512) {
328 UINT64 _r[8];
329 UINT64 _g[8];
330 UINT64 _e[8];
331
332 /* Init the arrays from the BIGNUMs */
333 bn_extract_to_array_512(g, 8, _g);
334 bn_extract_to_array_512(e, 8, _e);
335
336 mod_exp_512(_r, _g, _e, &rsax_mod_ctx->ctx.b512);
337 /* Return the result in the BIGNUM */
338 interleaved_array_to_bn_512(r, _r);
339 return 1;
340 }
341 }
342
343 return BN_mod_exp_mont(r, g, e, m, ctx, in_mont);
344}
345
346/* Declares for the Intel CIAP 512-bit / CRT / 1024 bit RSA modular
347 * exponentiation routine precalculations and a structure to hold the
348 * necessary values. These files are meant to live in crypto/rsa/ in
349 * the target openssl.
350 */
351
352/*
353 * Local method: extracts a piece from a BIGNUM, to fit it into
354 * an array. Call with n=8 to extract an entire 512-bit BIGNUM
355 */
356static int bn_extract_to_array_512(const BIGNUM* b, unsigned int n, UINT64 *array)
357{
358 int i;
359 UINT64 tmp;
360 unsigned char bn_buff[64];
361 memset(bn_buff, 0, 64);
362 if (BN_num_bytes(b) > 64) {
363 printf ("Can't support this byte size\n");
364 return 0; }
365 if (BN_num_bytes(b)!=0) {
366 if (!BN_bn2bin(b, bn_buff+(64-BN_num_bytes(b)))) {
367 printf ("Error's in bn2bin\n");
368 /* We have to error, here */
369 return 0; } }
370 while (n-- > 0) {
371 array[n] = 0;
372 for (i=7; i>=0; i--) {
373 tmp = bn_buff[63-(n*8+i)];
374 array[n] |= tmp << (8*i); } }
375 return 1;
376}
377
378/* Init a 512-bit BIGNUM from the UINT64*_ (8 * 64) interleaved array */
379static int interleaved_array_to_bn_512(BIGNUM* b, UINT64 *array)
380{
381 unsigned char tmp[64];
382 int n=8;
383 int i;
384 while (n-- > 0) {
385 for (i = 7; i>=0; i--) {
386 tmp[63-(n*8+i)] = (unsigned char)(array[n]>>(8*i)); } }
387 BN_bin2bn(tmp, 64, b);
388 return 0;
389}
390
391
392/* The main 512bit precompute call */
393static int mod_exp_pre_compute_data_512(UINT64 *m, struct mod_ctx_512 *data)
394 {
395 BIGNUM two_768, two_640, two_128, two_512, tmp, _m, tmp2;
396
397 /* We need a BN_CTX for the modulo functions */
398 BN_CTX* ctx;
399 /* Some tmps */
400 UINT64 _t[8];
401 int i, j, ret = 0;
402
403 /* Init _m with m */
404 BN_init(&_m);
405 interleaved_array_to_bn_512(&_m, m);
406 memset(_t, 0, 64);
407
408 /* Inits */
409 BN_init(&two_768);
410 BN_init(&two_640);
411 BN_init(&two_128);
412 BN_init(&two_512);
413 BN_init(&tmp);
414 BN_init(&tmp2);
415
416 /* Create our context */
417 if ((ctx=BN_CTX_new()) == NULL) { goto err; }
418 BN_CTX_start(ctx);
419
420 /*
421 * For production, if you care, these only need to be set once,
422 * and may be made constants.
423 */
424 BN_lshift(&two_768, BN_value_one(), 768);
425 BN_lshift(&two_640, BN_value_one(), 640);
426 BN_lshift(&two_128, BN_value_one(), 128);
427 BN_lshift(&two_512, BN_value_one(), 512);
428
429 if (0 == (m[7] & 0x8000000000000000)) {
430 exit(1);
431 }
432 if (0 == (m[0] & 0x1)) { /* Odd modulus required for Mont */
433 exit(1);
434 }
435
436 /* Precompute m1 */
437 BN_mod(&tmp, &two_768, &_m, ctx);
438 if (!bn_extract_to_array_512(&tmp, 8, &data->m1[0])) {
439 goto err; }
440
441 /* Precompute m2 */
442 BN_mod(&tmp, &two_640, &_m, ctx);
443 if (!bn_extract_to_array_512(&tmp, 8, &data->m2[0])) {
444 goto err;
445 }
446
447 /*
448 * Precompute k1, a 128b number = ((-1)* m-1 ) mod 2128; k1 should
449 * be non-negative.
450 */
451 BN_mod_inverse(&tmp, &_m, &two_128, ctx);
452 if (!BN_is_zero(&tmp)) { BN_sub(&tmp, &two_128, &tmp); }
453 if (!bn_extract_to_array_512(&tmp, 2, &data->k1[0])) {
454 goto err; }
455
456 /* Precompute t */
457 for (i=0; i<8; i++) {
458 BN_zero(&tmp);
459 if (i & 1) { BN_add(&tmp, &two_512, &tmp); }
460 if (i & 2) { BN_add(&tmp, &two_512, &tmp); }
461 if (i & 4) { BN_add(&tmp, &two_640, &tmp); }
462
463 BN_nnmod(&tmp2, &tmp, &_m, ctx);
464 if (!bn_extract_to_array_512(&tmp2, 8, _t)) {
465 goto err; }
466 for (j=0; j<8; j++) data->t[j][i] = _t[j]; }
467
468 /* Precompute m */
469 for (i=0; i<8; i++) {
470 data->m[i] = m[i]; }
471
472 ret = 1;
473
474err:
475 /* Cleanup */
476 if (ctx != NULL) {
477 BN_CTX_end(ctx); BN_CTX_free(ctx); }
478 BN_free(&two_768);
479 BN_free(&two_640);
480 BN_free(&two_128);
481 BN_free(&two_512);
482 BN_free(&tmp);
483 BN_free(&tmp2);
484 BN_free(&_m);
485
486 return ret;
487}
488
489
490static int e_rsax_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
491 {
492 BIGNUM *r1,*m1,*vrfy;
493 BIGNUM local_dmp1,local_dmq1,local_c,local_r1;
494 BIGNUM *dmp1,*dmq1,*c,*pr1;
495 int ret=0;
496
497 BN_CTX_start(ctx);
498 r1 = BN_CTX_get(ctx);
499 m1 = BN_CTX_get(ctx);
500 vrfy = BN_CTX_get(ctx);
501
502 {
503 BIGNUM local_p, local_q;
504 BIGNUM *p = NULL, *q = NULL;
505 int error = 0;
506
507 /* Make sure BN_mod_inverse in Montgomery
508 * intialization uses the BN_FLG_CONSTTIME flag
509 * (unless RSA_FLAG_NO_CONSTTIME is set)
510 */
511 if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
512 {
513 BN_init(&local_p);
514 p = &local_p;
515 BN_with_flags(p, rsa->p, BN_FLG_CONSTTIME);
516
517 BN_init(&local_q);
518 q = &local_q;
519 BN_with_flags(q, rsa->q, BN_FLG_CONSTTIME);
520 }
521 else
522 {
523 p = rsa->p;
524 q = rsa->q;
525 }
526
527 if (rsa->flags & RSA_FLAG_CACHE_PRIVATE)
528 {
529 if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_p, CRYPTO_LOCK_RSA, p, ctx))
530 error = 1;
531 if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_q, CRYPTO_LOCK_RSA, q, ctx))
532 error = 1;
533 }
534
535 /* clean up */
536 if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
537 {
538 BN_free(&local_p);
539 BN_free(&local_q);
540 }
541 if ( error )
542 goto err;
543 }
544
545 if (rsa->flags & RSA_FLAG_CACHE_PUBLIC)
546 if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_n, CRYPTO_LOCK_RSA, rsa->n, ctx))
547 goto err;
548
549 /* compute I mod q */
550 if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
551 {
552 c = &local_c;
553 BN_with_flags(c, I, BN_FLG_CONSTTIME);
554 if (!BN_mod(r1,c,rsa->q,ctx)) goto err;
555 }
556 else
557 {
558 if (!BN_mod(r1,I,rsa->q,ctx)) goto err;
559 }
560
561 /* compute r1^dmq1 mod q */
562 if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
563 {
564 dmq1 = &local_dmq1;
565 BN_with_flags(dmq1, rsa->dmq1, BN_FLG_CONSTTIME);
566 }
567 else
568 dmq1 = rsa->dmq1;
569
570 if (!e_rsax_bn_mod_exp(m1,r1,dmq1,rsa->q,ctx,
571 rsa->_method_mod_q, e_rsax_get_ctx(rsa, 0, rsa->q) )) goto err;
572
573 /* compute I mod p */
574 if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
575 {
576 c = &local_c;
577 BN_with_flags(c, I, BN_FLG_CONSTTIME);
578 if (!BN_mod(r1,c,rsa->p,ctx)) goto err;
579 }
580 else
581 {
582 if (!BN_mod(r1,I,rsa->p,ctx)) goto err;
583 }
584
585 /* compute r1^dmp1 mod p */
586 if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
587 {
588 dmp1 = &local_dmp1;
589 BN_with_flags(dmp1, rsa->dmp1, BN_FLG_CONSTTIME);
590 }
591 else
592 dmp1 = rsa->dmp1;
593
594 if (!e_rsax_bn_mod_exp(r0,r1,dmp1,rsa->p,ctx,
595 rsa->_method_mod_p, e_rsax_get_ctx(rsa, 1, rsa->p) )) goto err;
596
597 if (!BN_sub(r0,r0,m1)) goto err;
598 /* This will help stop the size of r0 increasing, which does
599 * affect the multiply if it optimised for a power of 2 size */
600 if (BN_is_negative(r0))
601 if (!BN_add(r0,r0,rsa->p)) goto err;
602
603 if (!BN_mul(r1,r0,rsa->iqmp,ctx)) goto err;
604
605 /* Turn BN_FLG_CONSTTIME flag on before division operation */
606 if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
607 {
608 pr1 = &local_r1;
609 BN_with_flags(pr1, r1, BN_FLG_CONSTTIME);
610 }
611 else
612 pr1 = r1;
613 if (!BN_mod(r0,pr1,rsa->p,ctx)) goto err;
614
615 /* If p < q it is occasionally possible for the correction of
616 * adding 'p' if r0 is negative above to leave the result still
617 * negative. This can break the private key operations: the following
618 * second correction should *always* correct this rare occurrence.
619 * This will *never* happen with OpenSSL generated keys because
620 * they ensure p > q [steve]
621 */
622 if (BN_is_negative(r0))
623 if (!BN_add(r0,r0,rsa->p)) goto err;
624 if (!BN_mul(r1,r0,rsa->q,ctx)) goto err;
625 if (!BN_add(r0,r1,m1)) goto err;
626
627 if (rsa->e && rsa->n)
628 {
629 if (!e_rsax_bn_mod_exp(vrfy,r0,rsa->e,rsa->n,ctx,rsa->_method_mod_n, e_rsax_get_ctx(rsa, 2, rsa->n) ))
630 goto err;
631
632 /* If 'I' was greater than (or equal to) rsa->n, the operation
633 * will be equivalent to using 'I mod n'. However, the result of
634 * the verify will *always* be less than 'n' so we don't check
635 * for absolute equality, just congruency. */
636 if (!BN_sub(vrfy, vrfy, I)) goto err;
637 if (!BN_mod(vrfy, vrfy, rsa->n, ctx)) goto err;
638 if (BN_is_negative(vrfy))
639 if (!BN_add(vrfy, vrfy, rsa->n)) goto err;
640 if (!BN_is_zero(vrfy))
641 {
642 /* 'I' and 'vrfy' aren't congruent mod n. Don't leak
643 * miscalculated CRT output, just do a raw (slower)
644 * mod_exp and return that instead. */
645
646 BIGNUM local_d;
647 BIGNUM *d = NULL;
648
649 if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
650 {
651 d = &local_d;
652 BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME);
653 }
654 else
655 d = rsa->d;
656 if (!e_rsax_bn_mod_exp(r0,I,d,rsa->n,ctx,
657 rsa->_method_mod_n, e_rsax_get_ctx(rsa, 2, rsa->n) )) goto err;
658 }
659 }
660 ret=1;
661
662err:
663 BN_CTX_end(ctx);
664
665 return ret;
666 }
667#endif /* !OPENSSL_NO_RSA */
668#endif /* !COMPILE_RSAX */
diff --git a/src/lib/libcrypto/engine/eng_table.c b/src/lib/libcrypto/engine/eng_table.c
new file mode 100644
index 0000000000..4fde948185
--- /dev/null
+++ b/src/lib/libcrypto/engine/eng_table.c
@@ -0,0 +1,351 @@
1/* ====================================================================
2 * Copyright (c) 2001 The OpenSSL Project. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in
13 * the documentation and/or other materials provided with the
14 * distribution.
15 *
16 * 3. All advertising materials mentioning features or use of this
17 * software must display the following acknowledgment:
18 * "This product includes software developed by the OpenSSL Project
19 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
20 *
21 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
22 * endorse or promote products derived from this software without
23 * prior written permission. For written permission, please contact
24 * licensing@OpenSSL.org.
25 *
26 * 5. Products derived from this software may not be called "OpenSSL"
27 * nor may "OpenSSL" appear in their names without prior written
28 * permission of the OpenSSL Project.
29 *
30 * 6. Redistributions of any form whatsoever must retain the following
31 * acknowledgment:
32 * "This product includes software developed by the OpenSSL Project
33 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
34 *
35 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
36 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
37 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
38 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
39 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
41 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
42 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
43 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
44 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
45 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
46 * OF THE POSSIBILITY OF SUCH DAMAGE.
47 * ====================================================================
48 *
49 * This product includes cryptographic software written by Eric Young
50 * (eay@cryptsoft.com). This product includes software written by Tim
51 * Hudson (tjh@cryptsoft.com).
52 *
53 */
54
55#include "cryptlib.h"
56#include <openssl/evp.h>
57#include <openssl/lhash.h>
58#include "eng_int.h"
59
60/* The type of the items in the table */
61typedef struct st_engine_pile
62 {
63 /* The 'nid' of this algorithm/mode */
64 int nid;
65 /* ENGINEs that implement this algorithm/mode. */
66 STACK_OF(ENGINE) *sk;
67 /* The default ENGINE to perform this algorithm/mode. */
68 ENGINE *funct;
69 /* Zero if 'sk' is newer than the cached 'funct', non-zero otherwise */
70 int uptodate;
71 } ENGINE_PILE;
72
73DECLARE_LHASH_OF(ENGINE_PILE);
74
75/* The type exposed in eng_int.h */
76struct st_engine_table
77 {
78 LHASH_OF(ENGINE_PILE) piles;
79 }; /* ENGINE_TABLE */
80
81
82typedef struct st_engine_pile_doall
83 {
84 engine_table_doall_cb *cb;
85 void *arg;
86 } ENGINE_PILE_DOALL;
87
88
89/* Global flags (ENGINE_TABLE_FLAG_***). */
90static unsigned int table_flags = 0;
91
92/* API function manipulating 'table_flags' */
93unsigned int ENGINE_get_table_flags(void)
94 {
95 return table_flags;
96 }
97
98void ENGINE_set_table_flags(unsigned int flags)
99 {
100 table_flags = flags;
101 }
102
103/* Internal functions for the "piles" hash table */
104static unsigned long engine_pile_hash(const ENGINE_PILE *c)
105 {
106 return c->nid;
107 }
108
109static int engine_pile_cmp(const ENGINE_PILE *a, const ENGINE_PILE *b)
110 {
111 return a->nid - b->nid;
112 }
113static IMPLEMENT_LHASH_HASH_FN(engine_pile, ENGINE_PILE)
114static IMPLEMENT_LHASH_COMP_FN(engine_pile, ENGINE_PILE)
115
116static int int_table_check(ENGINE_TABLE **t, int create)
117 {
118 LHASH_OF(ENGINE_PILE) *lh;
119
120 if(*t) return 1;
121 if(!create) return 0;
122 if((lh = lh_ENGINE_PILE_new()) == NULL)
123 return 0;
124 *t = (ENGINE_TABLE *)lh;
125 return 1;
126 }
127
128/* Privately exposed (via eng_int.h) functions for adding and/or removing
129 * ENGINEs from the implementation table */
130int engine_table_register(ENGINE_TABLE **table, ENGINE_CLEANUP_CB *cleanup,
131 ENGINE *e, const int *nids, int num_nids, int setdefault)
132 {
133 int ret = 0, added = 0;
134 ENGINE_PILE tmplate, *fnd;
135 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
136 if(!(*table))
137 added = 1;
138 if(!int_table_check(table, 1))
139 goto end;
140 if(added)
141 /* The cleanup callback needs to be added */
142 engine_cleanup_add_first(cleanup);
143 while(num_nids--)
144 {
145 tmplate.nid = *nids;
146 fnd = lh_ENGINE_PILE_retrieve(&(*table)->piles, &tmplate);
147 if(!fnd)
148 {
149 fnd = OPENSSL_malloc(sizeof(ENGINE_PILE));
150 if(!fnd) goto end;
151 fnd->uptodate = 1;
152 fnd->nid = *nids;
153 fnd->sk = sk_ENGINE_new_null();
154 if(!fnd->sk)
155 {
156 OPENSSL_free(fnd);
157 goto end;
158 }
159 fnd->funct = NULL;
160 (void)lh_ENGINE_PILE_insert(&(*table)->piles, fnd);
161 }
162 /* A registration shouldn't add duplciate entries */
163 (void)sk_ENGINE_delete_ptr(fnd->sk, e);
164 /* if 'setdefault', this ENGINE goes to the head of the list */
165 if(!sk_ENGINE_push(fnd->sk, e))
166 goto end;
167 /* "touch" this ENGINE_PILE */
168 fnd->uptodate = 0;
169 if(setdefault)
170 {
171 if(!engine_unlocked_init(e))
172 {
173 ENGINEerr(ENGINE_F_ENGINE_TABLE_REGISTER,
174 ENGINE_R_INIT_FAILED);
175 goto end;
176 }
177 if(fnd->funct)
178 engine_unlocked_finish(fnd->funct, 0);
179 fnd->funct = e;
180 fnd->uptodate = 1;
181 }
182 nids++;
183 }
184 ret = 1;
185end:
186 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
187 return ret;
188 }
189static void int_unregister_cb_doall_arg(ENGINE_PILE *pile, ENGINE *e)
190 {
191 int n;
192 /* Iterate the 'c->sk' stack removing any occurance of 'e' */
193 while((n = sk_ENGINE_find(pile->sk, e)) >= 0)
194 {
195 (void)sk_ENGINE_delete(pile->sk, n);
196 pile->uptodate = 0;
197 }
198 if(pile->funct == e)
199 {
200 engine_unlocked_finish(e, 0);
201 pile->funct = NULL;
202 }
203 }
204static IMPLEMENT_LHASH_DOALL_ARG_FN(int_unregister_cb, ENGINE_PILE, ENGINE)
205
206void engine_table_unregister(ENGINE_TABLE **table, ENGINE *e)
207 {
208 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
209 if(int_table_check(table, 0))
210 lh_ENGINE_PILE_doall_arg(&(*table)->piles,
211 LHASH_DOALL_ARG_FN(int_unregister_cb),
212 ENGINE, e);
213 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
214 }
215
216static void int_cleanup_cb_doall(ENGINE_PILE *p)
217 {
218 sk_ENGINE_free(p->sk);
219 if(p->funct)
220 engine_unlocked_finish(p->funct, 0);
221 OPENSSL_free(p);
222 }
223static IMPLEMENT_LHASH_DOALL_FN(int_cleanup_cb, ENGINE_PILE)
224
225void engine_table_cleanup(ENGINE_TABLE **table)
226 {
227 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
228 if(*table)
229 {
230 lh_ENGINE_PILE_doall(&(*table)->piles,
231 LHASH_DOALL_FN(int_cleanup_cb));
232 lh_ENGINE_PILE_free(&(*table)->piles);
233 *table = NULL;
234 }
235 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
236 }
237
238/* return a functional reference for a given 'nid' */
239#ifndef ENGINE_TABLE_DEBUG
240ENGINE *engine_table_select(ENGINE_TABLE **table, int nid)
241#else
242ENGINE *engine_table_select_tmp(ENGINE_TABLE **table, int nid, const char *f, int l)
243#endif
244 {
245 ENGINE *ret = NULL;
246 ENGINE_PILE tmplate, *fnd=NULL;
247 int initres, loop = 0;
248
249 if(!(*table))
250 {
251#ifdef ENGINE_TABLE_DEBUG
252 fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, nothing "
253 "registered!\n", f, l, nid);
254#endif
255 return NULL;
256 }
257 ERR_set_mark();
258 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
259 /* Check again inside the lock otherwise we could race against cleanup
260 * operations. But don't worry about a fprintf(stderr). */
261 if(!int_table_check(table, 0)) goto end;
262 tmplate.nid = nid;
263 fnd = lh_ENGINE_PILE_retrieve(&(*table)->piles, &tmplate);
264 if(!fnd) goto end;
265 if(fnd->funct && engine_unlocked_init(fnd->funct))
266 {
267#ifdef ENGINE_TABLE_DEBUG
268 fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, using "
269 "ENGINE '%s' cached\n", f, l, nid, fnd->funct->id);
270#endif
271 ret = fnd->funct;
272 goto end;
273 }
274 if(fnd->uptodate)
275 {
276 ret = fnd->funct;
277 goto end;
278 }
279trynext:
280 ret = sk_ENGINE_value(fnd->sk, loop++);
281 if(!ret)
282 {
283#ifdef ENGINE_TABLE_DEBUG
284 fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, no "
285 "registered implementations would initialise\n",
286 f, l, nid);
287#endif
288 goto end;
289 }
290 /* Try to initialise the ENGINE? */
291 if((ret->funct_ref > 0) || !(table_flags & ENGINE_TABLE_FLAG_NOINIT))
292 initres = engine_unlocked_init(ret);
293 else
294 initres = 0;
295 if(initres)
296 {
297 /* Update 'funct' */
298 if((fnd->funct != ret) && engine_unlocked_init(ret))
299 {
300 /* If there was a previous default we release it. */
301 if(fnd->funct)
302 engine_unlocked_finish(fnd->funct, 0);
303 fnd->funct = ret;
304#ifdef ENGINE_TABLE_DEBUG
305 fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, "
306 "setting default to '%s'\n", f, l, nid, ret->id);
307#endif
308 }
309#ifdef ENGINE_TABLE_DEBUG
310 fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, using "
311 "newly initialised '%s'\n", f, l, nid, ret->id);
312#endif
313 goto end;
314 }
315 goto trynext;
316end:
317 /* If it failed, it is unlikely to succeed again until some future
318 * registrations have taken place. In all cases, we cache. */
319 if(fnd) fnd->uptodate = 1;
320#ifdef ENGINE_TABLE_DEBUG
321 if(ret)
322 fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, caching "
323 "ENGINE '%s'\n", f, l, nid, ret->id);
324 else
325 fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, caching "
326 "'no matching ENGINE'\n", f, l, nid);
327#endif
328 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
329 /* Whatever happened, any failed init()s are not failures in this
330 * context, so clear our error state. */
331 ERR_pop_to_mark();
332 return ret;
333 }
334
335/* Table enumeration */
336
337static void int_cb_doall_arg(ENGINE_PILE *pile, ENGINE_PILE_DOALL *dall)
338 {
339 dall->cb(pile->nid, pile->sk, pile->funct, dall->arg);
340 }
341static IMPLEMENT_LHASH_DOALL_ARG_FN(int_cb, ENGINE_PILE,ENGINE_PILE_DOALL)
342
343void engine_table_doall(ENGINE_TABLE *table, engine_table_doall_cb *cb,
344 void *arg)
345 {
346 ENGINE_PILE_DOALL dall;
347 dall.cb = cb;
348 dall.arg = arg;
349 lh_ENGINE_PILE_doall_arg(&table->piles, LHASH_DOALL_ARG_FN(int_cb),
350 ENGINE_PILE_DOALL, &dall);
351 }
diff --git a/src/lib/libcrypto/engine/engine.h b/src/lib/libcrypto/engine/engine.h
new file mode 100644
index 0000000000..9d73abac8e
--- /dev/null
+++ b/src/lib/libcrypto/engine/engine.h
@@ -0,0 +1,834 @@
1/* openssl/engine.h */
2/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
3 * project 2000.
4 */
5/* ====================================================================
6 * Copyright (c) 1999-2004 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 * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
60 * ECDH support in OpenSSL originally developed by
61 * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
62 */
63
64#ifndef HEADER_ENGINE_H
65#define HEADER_ENGINE_H
66
67#include <openssl/opensslconf.h>
68
69#ifdef OPENSSL_NO_ENGINE
70#error ENGINE is disabled.
71#endif
72
73#ifndef OPENSSL_NO_DEPRECATED
74#include <openssl/bn.h>
75#ifndef OPENSSL_NO_RSA
76#include <openssl/rsa.h>
77#endif
78#ifndef OPENSSL_NO_DSA
79#include <openssl/dsa.h>
80#endif
81#ifndef OPENSSL_NO_DH
82#include <openssl/dh.h>
83#endif
84#ifndef OPENSSL_NO_ECDH
85#include <openssl/ecdh.h>
86#endif
87#ifndef OPENSSL_NO_ECDSA
88#include <openssl/ecdsa.h>
89#endif
90#include <openssl/rand.h>
91#include <openssl/ui.h>
92#include <openssl/err.h>
93#endif
94
95#include <openssl/ossl_typ.h>
96#include <openssl/symhacks.h>
97
98#include <openssl/x509.h>
99
100#ifdef __cplusplus
101extern "C" {
102#endif
103
104/* These flags are used to control combinations of algorithm (methods)
105 * by bitwise "OR"ing. */
106#define ENGINE_METHOD_RSA (unsigned int)0x0001
107#define ENGINE_METHOD_DSA (unsigned int)0x0002
108#define ENGINE_METHOD_DH (unsigned int)0x0004
109#define ENGINE_METHOD_RAND (unsigned int)0x0008
110#define ENGINE_METHOD_ECDH (unsigned int)0x0010
111#define ENGINE_METHOD_ECDSA (unsigned int)0x0020
112#define ENGINE_METHOD_CIPHERS (unsigned int)0x0040
113#define ENGINE_METHOD_DIGESTS (unsigned int)0x0080
114#define ENGINE_METHOD_STORE (unsigned int)0x0100
115#define ENGINE_METHOD_PKEY_METHS (unsigned int)0x0200
116#define ENGINE_METHOD_PKEY_ASN1_METHS (unsigned int)0x0400
117/* Obvious all-or-nothing cases. */
118#define ENGINE_METHOD_ALL (unsigned int)0xFFFF
119#define ENGINE_METHOD_NONE (unsigned int)0x0000
120
121/* This(ese) flag(s) controls behaviour of the ENGINE_TABLE mechanism used
122 * internally to control registration of ENGINE implementations, and can be set
123 * by ENGINE_set_table_flags(). The "NOINIT" flag prevents attempts to
124 * initialise registered ENGINEs if they are not already initialised. */
125#define ENGINE_TABLE_FLAG_NOINIT (unsigned int)0x0001
126
127/* ENGINE flags that can be set by ENGINE_set_flags(). */
128/* #define ENGINE_FLAGS_MALLOCED 0x0001 */ /* Not used */
129
130/* This flag is for ENGINEs that wish to handle the various 'CMD'-related
131 * control commands on their own. Without this flag, ENGINE_ctrl() handles these
132 * control commands on behalf of the ENGINE using their "cmd_defns" data. */
133#define ENGINE_FLAGS_MANUAL_CMD_CTRL (int)0x0002
134
135/* This flag is for ENGINEs who return new duplicate structures when found via
136 * "ENGINE_by_id()". When an ENGINE must store state (eg. if ENGINE_ctrl()
137 * commands are called in sequence as part of some stateful process like
138 * key-generation setup and execution), it can set this flag - then each attempt
139 * to obtain the ENGINE will result in it being copied into a new structure.
140 * Normally, ENGINEs don't declare this flag so ENGINE_by_id() just increments
141 * the existing ENGINE's structural reference count. */
142#define ENGINE_FLAGS_BY_ID_COPY (int)0x0004
143
144/* ENGINEs can support their own command types, and these flags are used in
145 * ENGINE_CTRL_GET_CMD_FLAGS to indicate to the caller what kind of input each
146 * command expects. Currently only numeric and string input is supported. If a
147 * control command supports none of the _NUMERIC, _STRING, or _NO_INPUT options,
148 * then it is regarded as an "internal" control command - and not for use in
149 * config setting situations. As such, they're not available to the
150 * ENGINE_ctrl_cmd_string() function, only raw ENGINE_ctrl() access. Changes to
151 * this list of 'command types' should be reflected carefully in
152 * ENGINE_cmd_is_executable() and ENGINE_ctrl_cmd_string(). */
153
154/* accepts a 'long' input value (3rd parameter to ENGINE_ctrl) */
155#define ENGINE_CMD_FLAG_NUMERIC (unsigned int)0x0001
156/* accepts string input (cast from 'void*' to 'const char *', 4th parameter to
157 * ENGINE_ctrl) */
158#define ENGINE_CMD_FLAG_STRING (unsigned int)0x0002
159/* Indicates that the control command takes *no* input. Ie. the control command
160 * is unparameterised. */
161#define ENGINE_CMD_FLAG_NO_INPUT (unsigned int)0x0004
162/* Indicates that the control command is internal. This control command won't
163 * be shown in any output, and is only usable through the ENGINE_ctrl_cmd()
164 * function. */
165#define ENGINE_CMD_FLAG_INTERNAL (unsigned int)0x0008
166
167/* NB: These 3 control commands are deprecated and should not be used. ENGINEs
168 * relying on these commands should compile conditional support for
169 * compatibility (eg. if these symbols are defined) but should also migrate the
170 * same functionality to their own ENGINE-specific control functions that can be
171 * "discovered" by calling applications. The fact these control commands
172 * wouldn't be "executable" (ie. usable by text-based config) doesn't change the
173 * fact that application code can find and use them without requiring per-ENGINE
174 * hacking. */
175
176/* These flags are used to tell the ctrl function what should be done.
177 * All command numbers are shared between all engines, even if some don't
178 * make sense to some engines. In such a case, they do nothing but return
179 * the error ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED. */
180#define ENGINE_CTRL_SET_LOGSTREAM 1
181#define ENGINE_CTRL_SET_PASSWORD_CALLBACK 2
182#define ENGINE_CTRL_HUP 3 /* Close and reinitialise any
183 handles/connections etc. */
184#define ENGINE_CTRL_SET_USER_INTERFACE 4 /* Alternative to callback */
185#define ENGINE_CTRL_SET_CALLBACK_DATA 5 /* User-specific data, used
186 when calling the password
187 callback and the user
188 interface */
189#define ENGINE_CTRL_LOAD_CONFIGURATION 6 /* Load a configuration, given
190 a string that represents a
191 file name or so */
192#define ENGINE_CTRL_LOAD_SECTION 7 /* Load data from a given
193 section in the already loaded
194 configuration */
195
196/* These control commands allow an application to deal with an arbitrary engine
197 * in a dynamic way. Warn: Negative return values indicate errors FOR THESE
198 * COMMANDS because zero is used to indicate 'end-of-list'. Other commands,
199 * including ENGINE-specific command types, return zero for an error.
200 *
201 * An ENGINE can choose to implement these ctrl functions, and can internally
202 * manage things however it chooses - it does so by setting the
203 * ENGINE_FLAGS_MANUAL_CMD_CTRL flag (using ENGINE_set_flags()). Otherwise the
204 * ENGINE_ctrl() code handles this on the ENGINE's behalf using the cmd_defns
205 * data (set using ENGINE_set_cmd_defns()). This means an ENGINE's ctrl()
206 * handler need only implement its own commands - the above "meta" commands will
207 * be taken care of. */
208
209/* Returns non-zero if the supplied ENGINE has a ctrl() handler. If "not", then
210 * all the remaining control commands will return failure, so it is worth
211 * checking this first if the caller is trying to "discover" the engine's
212 * capabilities and doesn't want errors generated unnecessarily. */
213#define ENGINE_CTRL_HAS_CTRL_FUNCTION 10
214/* Returns a positive command number for the first command supported by the
215 * engine. Returns zero if no ctrl commands are supported. */
216#define ENGINE_CTRL_GET_FIRST_CMD_TYPE 11
217/* The 'long' argument specifies a command implemented by the engine, and the
218 * return value is the next command supported, or zero if there are no more. */
219#define ENGINE_CTRL_GET_NEXT_CMD_TYPE 12
220/* The 'void*' argument is a command name (cast from 'const char *'), and the
221 * return value is the command that corresponds to it. */
222#define ENGINE_CTRL_GET_CMD_FROM_NAME 13
223/* The next two allow a command to be converted into its corresponding string
224 * form. In each case, the 'long' argument supplies the command. In the NAME_LEN
225 * case, the return value is the length of the command name (not counting a
226 * trailing EOL). In the NAME case, the 'void*' argument must be a string buffer
227 * large enough, and it will be populated with the name of the command (WITH a
228 * trailing EOL). */
229#define ENGINE_CTRL_GET_NAME_LEN_FROM_CMD 14
230#define ENGINE_CTRL_GET_NAME_FROM_CMD 15
231/* The next two are similar but give a "short description" of a command. */
232#define ENGINE_CTRL_GET_DESC_LEN_FROM_CMD 16
233#define ENGINE_CTRL_GET_DESC_FROM_CMD 17
234/* With this command, the return value is the OR'd combination of
235 * ENGINE_CMD_FLAG_*** values that indicate what kind of input a given
236 * engine-specific ctrl command expects. */
237#define ENGINE_CTRL_GET_CMD_FLAGS 18
238
239/* ENGINE implementations should start the numbering of their own control
240 * commands from this value. (ie. ENGINE_CMD_BASE, ENGINE_CMD_BASE + 1, etc). */
241#define ENGINE_CMD_BASE 200
242
243/* NB: These 2 nCipher "chil" control commands are deprecated, and their
244 * functionality is now available through ENGINE-specific control commands
245 * (exposed through the above-mentioned 'CMD'-handling). Code using these 2
246 * commands should be migrated to the more general command handling before these
247 * are removed. */
248
249/* Flags specific to the nCipher "chil" engine */
250#define ENGINE_CTRL_CHIL_SET_FORKCHECK 100
251 /* Depending on the value of the (long)i argument, this sets or
252 * unsets the SimpleForkCheck flag in the CHIL API to enable or
253 * disable checking and workarounds for applications that fork().
254 */
255#define ENGINE_CTRL_CHIL_NO_LOCKING 101
256 /* This prevents the initialisation function from providing mutex
257 * callbacks to the nCipher library. */
258
259/* If an ENGINE supports its own specific control commands and wishes the
260 * framework to handle the above 'ENGINE_CMD_***'-manipulation commands on its
261 * behalf, it should supply a null-terminated array of ENGINE_CMD_DEFN entries
262 * to ENGINE_set_cmd_defns(). It should also implement a ctrl() handler that
263 * supports the stated commands (ie. the "cmd_num" entries as described by the
264 * array). NB: The array must be ordered in increasing order of cmd_num.
265 * "null-terminated" means that the last ENGINE_CMD_DEFN element has cmd_num set
266 * to zero and/or cmd_name set to NULL. */
267typedef struct ENGINE_CMD_DEFN_st
268 {
269 unsigned int cmd_num; /* The command number */
270 const char *cmd_name; /* The command name itself */
271 const char *cmd_desc; /* A short description of the command */
272 unsigned int cmd_flags; /* The input the command expects */
273 } ENGINE_CMD_DEFN;
274
275/* Generic function pointer */
276typedef int (*ENGINE_GEN_FUNC_PTR)(void);
277/* Generic function pointer taking no arguments */
278typedef int (*ENGINE_GEN_INT_FUNC_PTR)(ENGINE *);
279/* Specific control function pointer */
280typedef int (*ENGINE_CTRL_FUNC_PTR)(ENGINE *, int, long, void *, void (*f)(void));
281/* Generic load_key function pointer */
282typedef EVP_PKEY * (*ENGINE_LOAD_KEY_PTR)(ENGINE *, const char *,
283 UI_METHOD *ui_method, void *callback_data);
284typedef int (*ENGINE_SSL_CLIENT_CERT_PTR)(ENGINE *, SSL *ssl,
285 STACK_OF(X509_NAME) *ca_dn, X509 **pcert, EVP_PKEY **pkey,
286 STACK_OF(X509) **pother, UI_METHOD *ui_method, void *callback_data);
287/* These callback types are for an ENGINE's handler for cipher and digest logic.
288 * These handlers have these prototypes;
289 * int foo(ENGINE *e, const EVP_CIPHER **cipher, const int **nids, int nid);
290 * int foo(ENGINE *e, const EVP_MD **digest, const int **nids, int nid);
291 * Looking at how to implement these handlers in the case of cipher support, if
292 * the framework wants the EVP_CIPHER for 'nid', it will call;
293 * foo(e, &p_evp_cipher, NULL, nid); (return zero for failure)
294 * If the framework wants a list of supported 'nid's, it will call;
295 * foo(e, NULL, &p_nids, 0); (returns number of 'nids' or -1 for error)
296 */
297/* Returns to a pointer to the array of supported cipher 'nid's. If the second
298 * parameter is non-NULL it is set to the size of the returned array. */
299typedef int (*ENGINE_CIPHERS_PTR)(ENGINE *, const EVP_CIPHER **, const int **, int);
300typedef int (*ENGINE_DIGESTS_PTR)(ENGINE *, const EVP_MD **, const int **, int);
301typedef int (*ENGINE_PKEY_METHS_PTR)(ENGINE *, EVP_PKEY_METHOD **, const int **, int);
302typedef int (*ENGINE_PKEY_ASN1_METHS_PTR)(ENGINE *, EVP_PKEY_ASN1_METHOD **, const int **, int);
303/* STRUCTURE functions ... all of these functions deal with pointers to ENGINE
304 * structures where the pointers have a "structural reference". This means that
305 * their reference is to allowed access to the structure but it does not imply
306 * that the structure is functional. To simply increment or decrement the
307 * structural reference count, use ENGINE_by_id and ENGINE_free. NB: This is not
308 * required when iterating using ENGINE_get_next as it will automatically
309 * decrement the structural reference count of the "current" ENGINE and
310 * increment the structural reference count of the ENGINE it returns (unless it
311 * is NULL). */
312
313/* Get the first/last "ENGINE" type available. */
314ENGINE *ENGINE_get_first(void);
315ENGINE *ENGINE_get_last(void);
316/* Iterate to the next/previous "ENGINE" type (NULL = end of the list). */
317ENGINE *ENGINE_get_next(ENGINE *e);
318ENGINE *ENGINE_get_prev(ENGINE *e);
319/* Add another "ENGINE" type into the array. */
320int ENGINE_add(ENGINE *e);
321/* Remove an existing "ENGINE" type from the array. */
322int ENGINE_remove(ENGINE *e);
323/* Retrieve an engine from the list by its unique "id" value. */
324ENGINE *ENGINE_by_id(const char *id);
325/* Add all the built-in engines. */
326void ENGINE_load_openssl(void);
327void ENGINE_load_dynamic(void);
328#ifndef OPENSSL_NO_STATIC_ENGINE
329void ENGINE_load_4758cca(void);
330void ENGINE_load_aep(void);
331void ENGINE_load_atalla(void);
332void ENGINE_load_chil(void);
333void ENGINE_load_cswift(void);
334void ENGINE_load_nuron(void);
335void ENGINE_load_sureware(void);
336void ENGINE_load_ubsec(void);
337void ENGINE_load_padlock(void);
338void ENGINE_load_capi(void);
339#ifndef OPENSSL_NO_GMP
340void ENGINE_load_gmp(void);
341#endif
342#ifndef OPENSSL_NO_GOST
343void ENGINE_load_gost(void);
344#endif
345#endif
346void ENGINE_load_cryptodev(void);
347void ENGINE_load_aesni(void);
348void ENGINE_load_builtin_engines(void);
349
350/* Get and set global flags (ENGINE_TABLE_FLAG_***) for the implementation
351 * "registry" handling. */
352unsigned int ENGINE_get_table_flags(void);
353void ENGINE_set_table_flags(unsigned int flags);
354
355/* Manage registration of ENGINEs per "table". For each type, there are 3
356 * functions;
357 * ENGINE_register_***(e) - registers the implementation from 'e' (if it has one)
358 * ENGINE_unregister_***(e) - unregister the implementation from 'e'
359 * ENGINE_register_all_***() - call ENGINE_register_***() for each 'e' in the list
360 * Cleanup is automatically registered from each table when required, so
361 * ENGINE_cleanup() will reverse any "register" operations. */
362
363int ENGINE_register_RSA(ENGINE *e);
364void ENGINE_unregister_RSA(ENGINE *e);
365void ENGINE_register_all_RSA(void);
366
367int ENGINE_register_DSA(ENGINE *e);
368void ENGINE_unregister_DSA(ENGINE *e);
369void ENGINE_register_all_DSA(void);
370
371int ENGINE_register_ECDH(ENGINE *e);
372void ENGINE_unregister_ECDH(ENGINE *e);
373void ENGINE_register_all_ECDH(void);
374
375int ENGINE_register_ECDSA(ENGINE *e);
376void ENGINE_unregister_ECDSA(ENGINE *e);
377void ENGINE_register_all_ECDSA(void);
378
379int ENGINE_register_DH(ENGINE *e);
380void ENGINE_unregister_DH(ENGINE *e);
381void ENGINE_register_all_DH(void);
382
383int ENGINE_register_RAND(ENGINE *e);
384void ENGINE_unregister_RAND(ENGINE *e);
385void ENGINE_register_all_RAND(void);
386
387int ENGINE_register_STORE(ENGINE *e);
388void ENGINE_unregister_STORE(ENGINE *e);
389void ENGINE_register_all_STORE(void);
390
391int ENGINE_register_ciphers(ENGINE *e);
392void ENGINE_unregister_ciphers(ENGINE *e);
393void ENGINE_register_all_ciphers(void);
394
395int ENGINE_register_digests(ENGINE *e);
396void ENGINE_unregister_digests(ENGINE *e);
397void ENGINE_register_all_digests(void);
398
399int ENGINE_register_pkey_meths(ENGINE *e);
400void ENGINE_unregister_pkey_meths(ENGINE *e);
401void ENGINE_register_all_pkey_meths(void);
402
403int ENGINE_register_pkey_asn1_meths(ENGINE *e);
404void ENGINE_unregister_pkey_asn1_meths(ENGINE *e);
405void ENGINE_register_all_pkey_asn1_meths(void);
406
407/* These functions register all support from the above categories. Note, use of
408 * these functions can result in static linkage of code your application may not
409 * need. If you only need a subset of functionality, consider using more
410 * selective initialisation. */
411int ENGINE_register_complete(ENGINE *e);
412int ENGINE_register_all_complete(void);
413
414/* Send parametrised control commands to the engine. The possibilities to send
415 * down an integer, a pointer to data or a function pointer are provided. Any of
416 * the parameters may or may not be NULL, depending on the command number. In
417 * actuality, this function only requires a structural (rather than functional)
418 * reference to an engine, but many control commands may require the engine be
419 * functional. The caller should be aware of trying commands that require an
420 * operational ENGINE, and only use functional references in such situations. */
421int ENGINE_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void));
422
423/* This function tests if an ENGINE-specific command is usable as a "setting".
424 * Eg. in an application's config file that gets processed through
425 * ENGINE_ctrl_cmd_string(). If this returns zero, it is not available to
426 * ENGINE_ctrl_cmd_string(), only ENGINE_ctrl(). */
427int ENGINE_cmd_is_executable(ENGINE *e, int cmd);
428
429/* This function works like ENGINE_ctrl() with the exception of taking a
430 * command name instead of a command number, and can handle optional commands.
431 * See the comment on ENGINE_ctrl_cmd_string() for an explanation on how to
432 * use the cmd_name and cmd_optional. */
433int ENGINE_ctrl_cmd(ENGINE *e, const char *cmd_name,
434 long i, void *p, void (*f)(void), int cmd_optional);
435
436/* This function passes a command-name and argument to an ENGINE. The cmd_name
437 * is converted to a command number and the control command is called using
438 * 'arg' as an argument (unless the ENGINE doesn't support such a command, in
439 * which case no control command is called). The command is checked for input
440 * flags, and if necessary the argument will be converted to a numeric value. If
441 * cmd_optional is non-zero, then if the ENGINE doesn't support the given
442 * cmd_name the return value will be success anyway. This function is intended
443 * for applications to use so that users (or config files) can supply
444 * engine-specific config data to the ENGINE at run-time to control behaviour of
445 * specific engines. As such, it shouldn't be used for calling ENGINE_ctrl()
446 * functions that return data, deal with binary data, or that are otherwise
447 * supposed to be used directly through ENGINE_ctrl() in application code. Any
448 * "return" data from an ENGINE_ctrl() operation in this function will be lost -
449 * the return value is interpreted as failure if the return value is zero,
450 * success otherwise, and this function returns a boolean value as a result. In
451 * other words, vendors of 'ENGINE'-enabled devices should write ENGINE
452 * implementations with parameterisations that work in this scheme, so that
453 * compliant ENGINE-based applications can work consistently with the same
454 * configuration for the same ENGINE-enabled devices, across applications. */
455int ENGINE_ctrl_cmd_string(ENGINE *e, const char *cmd_name, const char *arg,
456 int cmd_optional);
457
458/* These functions are useful for manufacturing new ENGINE structures. They
459 * don't address reference counting at all - one uses them to populate an ENGINE
460 * structure with personalised implementations of things prior to using it
461 * directly or adding it to the builtin ENGINE list in OpenSSL. These are also
462 * here so that the ENGINE structure doesn't have to be exposed and break binary
463 * compatibility! */
464ENGINE *ENGINE_new(void);
465int ENGINE_free(ENGINE *e);
466int ENGINE_up_ref(ENGINE *e);
467int ENGINE_set_id(ENGINE *e, const char *id);
468int ENGINE_set_name(ENGINE *e, const char *name);
469int ENGINE_set_RSA(ENGINE *e, const RSA_METHOD *rsa_meth);
470int ENGINE_set_DSA(ENGINE *e, const DSA_METHOD *dsa_meth);
471int ENGINE_set_ECDH(ENGINE *e, const ECDH_METHOD *ecdh_meth);
472int ENGINE_set_ECDSA(ENGINE *e, const ECDSA_METHOD *ecdsa_meth);
473int ENGINE_set_DH(ENGINE *e, const DH_METHOD *dh_meth);
474int ENGINE_set_RAND(ENGINE *e, const RAND_METHOD *rand_meth);
475int ENGINE_set_STORE(ENGINE *e, const STORE_METHOD *store_meth);
476int ENGINE_set_destroy_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR destroy_f);
477int ENGINE_set_init_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR init_f);
478int ENGINE_set_finish_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR finish_f);
479int ENGINE_set_ctrl_function(ENGINE *e, ENGINE_CTRL_FUNC_PTR ctrl_f);
480int ENGINE_set_load_privkey_function(ENGINE *e, ENGINE_LOAD_KEY_PTR loadpriv_f);
481int ENGINE_set_load_pubkey_function(ENGINE *e, ENGINE_LOAD_KEY_PTR loadpub_f);
482int ENGINE_set_load_ssl_client_cert_function(ENGINE *e,
483 ENGINE_SSL_CLIENT_CERT_PTR loadssl_f);
484int ENGINE_set_ciphers(ENGINE *e, ENGINE_CIPHERS_PTR f);
485int ENGINE_set_digests(ENGINE *e, ENGINE_DIGESTS_PTR f);
486int ENGINE_set_pkey_meths(ENGINE *e, ENGINE_PKEY_METHS_PTR f);
487int ENGINE_set_pkey_asn1_meths(ENGINE *e, ENGINE_PKEY_ASN1_METHS_PTR f);
488int ENGINE_set_flags(ENGINE *e, int flags);
489int ENGINE_set_cmd_defns(ENGINE *e, const ENGINE_CMD_DEFN *defns);
490/* These functions allow control over any per-structure ENGINE data. */
491int ENGINE_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
492 CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
493int ENGINE_set_ex_data(ENGINE *e, int idx, void *arg);
494void *ENGINE_get_ex_data(const ENGINE *e, int idx);
495
496/* This function cleans up anything that needs it. Eg. the ENGINE_add() function
497 * automatically ensures the list cleanup function is registered to be called
498 * from ENGINE_cleanup(). Similarly, all ENGINE_register_*** functions ensure
499 * ENGINE_cleanup() will clean up after them. */
500void ENGINE_cleanup(void);
501
502/* These return values from within the ENGINE structure. These can be useful
503 * with functional references as well as structural references - it depends
504 * which you obtained. Using the result for functional purposes if you only
505 * obtained a structural reference may be problematic! */
506const char *ENGINE_get_id(const ENGINE *e);
507const char *ENGINE_get_name(const ENGINE *e);
508const RSA_METHOD *ENGINE_get_RSA(const ENGINE *e);
509const DSA_METHOD *ENGINE_get_DSA(const ENGINE *e);
510const ECDH_METHOD *ENGINE_get_ECDH(const ENGINE *e);
511const ECDSA_METHOD *ENGINE_get_ECDSA(const ENGINE *e);
512const DH_METHOD *ENGINE_get_DH(const ENGINE *e);
513const RAND_METHOD *ENGINE_get_RAND(const ENGINE *e);
514const STORE_METHOD *ENGINE_get_STORE(const ENGINE *e);
515ENGINE_GEN_INT_FUNC_PTR ENGINE_get_destroy_function(const ENGINE *e);
516ENGINE_GEN_INT_FUNC_PTR ENGINE_get_init_function(const ENGINE *e);
517ENGINE_GEN_INT_FUNC_PTR ENGINE_get_finish_function(const ENGINE *e);
518ENGINE_CTRL_FUNC_PTR ENGINE_get_ctrl_function(const ENGINE *e);
519ENGINE_LOAD_KEY_PTR ENGINE_get_load_privkey_function(const ENGINE *e);
520ENGINE_LOAD_KEY_PTR ENGINE_get_load_pubkey_function(const ENGINE *e);
521ENGINE_SSL_CLIENT_CERT_PTR ENGINE_get_ssl_client_cert_function(const ENGINE *e);
522ENGINE_CIPHERS_PTR ENGINE_get_ciphers(const ENGINE *e);
523ENGINE_DIGESTS_PTR ENGINE_get_digests(const ENGINE *e);
524ENGINE_PKEY_METHS_PTR ENGINE_get_pkey_meths(const ENGINE *e);
525ENGINE_PKEY_ASN1_METHS_PTR ENGINE_get_pkey_asn1_meths(const ENGINE *e);
526const EVP_CIPHER *ENGINE_get_cipher(ENGINE *e, int nid);
527const EVP_MD *ENGINE_get_digest(ENGINE *e, int nid);
528const EVP_PKEY_METHOD *ENGINE_get_pkey_meth(ENGINE *e, int nid);
529const EVP_PKEY_ASN1_METHOD *ENGINE_get_pkey_asn1_meth(ENGINE *e, int nid);
530const EVP_PKEY_ASN1_METHOD *ENGINE_get_pkey_asn1_meth_str(ENGINE *e,
531 const char *str, int len);
532const EVP_PKEY_ASN1_METHOD *ENGINE_pkey_asn1_find_str(ENGINE **pe,
533 const char *str, int len);
534const ENGINE_CMD_DEFN *ENGINE_get_cmd_defns(const ENGINE *e);
535int ENGINE_get_flags(const ENGINE *e);
536
537/* FUNCTIONAL functions. These functions deal with ENGINE structures
538 * that have (or will) be initialised for use. Broadly speaking, the
539 * structural functions are useful for iterating the list of available
540 * engine types, creating new engine types, and other "list" operations.
541 * These functions actually deal with ENGINEs that are to be used. As
542 * such these functions can fail (if applicable) when particular
543 * engines are unavailable - eg. if a hardware accelerator is not
544 * attached or not functioning correctly. Each ENGINE has 2 reference
545 * counts; structural and functional. Every time a functional reference
546 * is obtained or released, a corresponding structural reference is
547 * automatically obtained or released too. */
548
549/* Initialise a engine type for use (or up its reference count if it's
550 * already in use). This will fail if the engine is not currently
551 * operational and cannot initialise. */
552int ENGINE_init(ENGINE *e);
553/* Free a functional reference to a engine type. This does not require
554 * a corresponding call to ENGINE_free as it also releases a structural
555 * reference. */
556int ENGINE_finish(ENGINE *e);
557
558/* The following functions handle keys that are stored in some secondary
559 * location, handled by the engine. The storage may be on a card or
560 * whatever. */
561EVP_PKEY *ENGINE_load_private_key(ENGINE *e, const char *key_id,
562 UI_METHOD *ui_method, void *callback_data);
563EVP_PKEY *ENGINE_load_public_key(ENGINE *e, const char *key_id,
564 UI_METHOD *ui_method, void *callback_data);
565int ENGINE_load_ssl_client_cert(ENGINE *e, SSL *s,
566 STACK_OF(X509_NAME) *ca_dn, X509 **pcert, EVP_PKEY **ppkey,
567 STACK_OF(X509) **pother,
568 UI_METHOD *ui_method, void *callback_data);
569
570/* This returns a pointer for the current ENGINE structure that
571 * is (by default) performing any RSA operations. The value returned
572 * is an incremented reference, so it should be free'd (ENGINE_finish)
573 * before it is discarded. */
574ENGINE *ENGINE_get_default_RSA(void);
575/* Same for the other "methods" */
576ENGINE *ENGINE_get_default_DSA(void);
577ENGINE *ENGINE_get_default_ECDH(void);
578ENGINE *ENGINE_get_default_ECDSA(void);
579ENGINE *ENGINE_get_default_DH(void);
580ENGINE *ENGINE_get_default_RAND(void);
581/* These functions can be used to get a functional reference to perform
582 * ciphering or digesting corresponding to "nid". */
583ENGINE *ENGINE_get_cipher_engine(int nid);
584ENGINE *ENGINE_get_digest_engine(int nid);
585ENGINE *ENGINE_get_pkey_meth_engine(int nid);
586ENGINE *ENGINE_get_pkey_asn1_meth_engine(int nid);
587
588/* This sets a new default ENGINE structure for performing RSA
589 * operations. If the result is non-zero (success) then the ENGINE
590 * structure will have had its reference count up'd so the caller
591 * should still free their own reference 'e'. */
592int ENGINE_set_default_RSA(ENGINE *e);
593int ENGINE_set_default_string(ENGINE *e, const char *def_list);
594/* Same for the other "methods" */
595int ENGINE_set_default_DSA(ENGINE *e);
596int ENGINE_set_default_ECDH(ENGINE *e);
597int ENGINE_set_default_ECDSA(ENGINE *e);
598int ENGINE_set_default_DH(ENGINE *e);
599int ENGINE_set_default_RAND(ENGINE *e);
600int ENGINE_set_default_ciphers(ENGINE *e);
601int ENGINE_set_default_digests(ENGINE *e);
602int ENGINE_set_default_pkey_meths(ENGINE *e);
603int ENGINE_set_default_pkey_asn1_meths(ENGINE *e);
604
605/* The combination "set" - the flags are bitwise "OR"d from the
606 * ENGINE_METHOD_*** defines above. As with the "ENGINE_register_complete()"
607 * function, this function can result in unnecessary static linkage. If your
608 * application requires only specific functionality, consider using more
609 * selective functions. */
610int ENGINE_set_default(ENGINE *e, unsigned int flags);
611
612void ENGINE_add_conf_module(void);
613
614/* Deprecated functions ... */
615/* int ENGINE_clear_defaults(void); */
616
617/**************************/
618/* DYNAMIC ENGINE SUPPORT */
619/**************************/
620
621/* Binary/behaviour compatibility levels */
622#define OSSL_DYNAMIC_VERSION (unsigned long)0x00020000
623/* Binary versions older than this are too old for us (whether we're a loader or
624 * a loadee) */
625#define OSSL_DYNAMIC_OLDEST (unsigned long)0x00020000
626
627/* When compiling an ENGINE entirely as an external shared library, loadable by
628 * the "dynamic" ENGINE, these types are needed. The 'dynamic_fns' structure
629 * type provides the calling application's (or library's) error functionality
630 * and memory management function pointers to the loaded library. These should
631 * be used/set in the loaded library code so that the loading application's
632 * 'state' will be used/changed in all operations. The 'static_state' pointer
633 * allows the loaded library to know if it shares the same static data as the
634 * calling application (or library), and thus whether these callbacks need to be
635 * set or not. */
636typedef void *(*dyn_MEM_malloc_cb)(size_t);
637typedef void *(*dyn_MEM_realloc_cb)(void *, size_t);
638typedef void (*dyn_MEM_free_cb)(void *);
639typedef struct st_dynamic_MEM_fns {
640 dyn_MEM_malloc_cb malloc_cb;
641 dyn_MEM_realloc_cb realloc_cb;
642 dyn_MEM_free_cb free_cb;
643 } dynamic_MEM_fns;
644/* FIXME: Perhaps the memory and locking code (crypto.h) should declare and use
645 * these types so we (and any other dependant code) can simplify a bit?? */
646typedef void (*dyn_lock_locking_cb)(int,int,const char *,int);
647typedef int (*dyn_lock_add_lock_cb)(int*,int,int,const char *,int);
648typedef struct CRYPTO_dynlock_value *(*dyn_dynlock_create_cb)(
649 const char *,int);
650typedef void (*dyn_dynlock_lock_cb)(int,struct CRYPTO_dynlock_value *,
651 const char *,int);
652typedef void (*dyn_dynlock_destroy_cb)(struct CRYPTO_dynlock_value *,
653 const char *,int);
654typedef struct st_dynamic_LOCK_fns {
655 dyn_lock_locking_cb lock_locking_cb;
656 dyn_lock_add_lock_cb lock_add_lock_cb;
657 dyn_dynlock_create_cb dynlock_create_cb;
658 dyn_dynlock_lock_cb dynlock_lock_cb;
659 dyn_dynlock_destroy_cb dynlock_destroy_cb;
660 } dynamic_LOCK_fns;
661/* The top-level structure */
662typedef struct st_dynamic_fns {
663 void *static_state;
664 const ERR_FNS *err_fns;
665 const CRYPTO_EX_DATA_IMPL *ex_data_fns;
666 dynamic_MEM_fns mem_fns;
667 dynamic_LOCK_fns lock_fns;
668 } dynamic_fns;
669
670/* The version checking function should be of this prototype. NB: The
671 * ossl_version value passed in is the OSSL_DYNAMIC_VERSION of the loading code.
672 * If this function returns zero, it indicates a (potential) version
673 * incompatibility and the loaded library doesn't believe it can proceed.
674 * Otherwise, the returned value is the (latest) version supported by the
675 * loading library. The loader may still decide that the loaded code's version
676 * is unsatisfactory and could veto the load. The function is expected to
677 * be implemented with the symbol name "v_check", and a default implementation
678 * can be fully instantiated with IMPLEMENT_DYNAMIC_CHECK_FN(). */
679typedef unsigned long (*dynamic_v_check_fn)(unsigned long ossl_version);
680#define IMPLEMENT_DYNAMIC_CHECK_FN() \
681 OPENSSL_EXPORT unsigned long v_check(unsigned long v); \
682 OPENSSL_EXPORT unsigned long v_check(unsigned long v) { \
683 if(v >= OSSL_DYNAMIC_OLDEST) return OSSL_DYNAMIC_VERSION; \
684 return 0; }
685
686/* This function is passed the ENGINE structure to initialise with its own
687 * function and command settings. It should not adjust the structural or
688 * functional reference counts. If this function returns zero, (a) the load will
689 * be aborted, (b) the previous ENGINE state will be memcpy'd back onto the
690 * structure, and (c) the shared library will be unloaded. So implementations
691 * should do their own internal cleanup in failure circumstances otherwise they
692 * could leak. The 'id' parameter, if non-NULL, represents the ENGINE id that
693 * the loader is looking for. If this is NULL, the shared library can choose to
694 * return failure or to initialise a 'default' ENGINE. If non-NULL, the shared
695 * library must initialise only an ENGINE matching the passed 'id'. The function
696 * is expected to be implemented with the symbol name "bind_engine". A standard
697 * implementation can be instantiated with IMPLEMENT_DYNAMIC_BIND_FN(fn) where
698 * the parameter 'fn' is a callback function that populates the ENGINE structure
699 * and returns an int value (zero for failure). 'fn' should have prototype;
700 * [static] int fn(ENGINE *e, const char *id); */
701typedef int (*dynamic_bind_engine)(ENGINE *e, const char *id,
702 const dynamic_fns *fns);
703#define IMPLEMENT_DYNAMIC_BIND_FN(fn) \
704 OPENSSL_EXPORT \
705 int bind_engine(ENGINE *e, const char *id, const dynamic_fns *fns); \
706 OPENSSL_EXPORT \
707 int bind_engine(ENGINE *e, const char *id, const dynamic_fns *fns) { \
708 if(ENGINE_get_static_state() == fns->static_state) goto skip_cbs; \
709 if(!CRYPTO_set_mem_functions(fns->mem_fns.malloc_cb, \
710 fns->mem_fns.realloc_cb, fns->mem_fns.free_cb)) \
711 return 0; \
712 CRYPTO_set_locking_callback(fns->lock_fns.lock_locking_cb); \
713 CRYPTO_set_add_lock_callback(fns->lock_fns.lock_add_lock_cb); \
714 CRYPTO_set_dynlock_create_callback(fns->lock_fns.dynlock_create_cb); \
715 CRYPTO_set_dynlock_lock_callback(fns->lock_fns.dynlock_lock_cb); \
716 CRYPTO_set_dynlock_destroy_callback(fns->lock_fns.dynlock_destroy_cb); \
717 if(!CRYPTO_set_ex_data_implementation(fns->ex_data_fns)) \
718 return 0; \
719 if(!ERR_set_implementation(fns->err_fns)) return 0; \
720 skip_cbs: \
721 if(!fn(e,id)) return 0; \
722 return 1; }
723
724/* If the loading application (or library) and the loaded ENGINE library share
725 * the same static data (eg. they're both dynamically linked to the same
726 * libcrypto.so) we need a way to avoid trying to set system callbacks - this
727 * would fail, and for the same reason that it's unnecessary to try. If the
728 * loaded ENGINE has (or gets from through the loader) its own copy of the
729 * libcrypto static data, we will need to set the callbacks. The easiest way to
730 * detect this is to have a function that returns a pointer to some static data
731 * and let the loading application and loaded ENGINE compare their respective
732 * values. */
733void *ENGINE_get_static_state(void);
734
735#if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(HAVE_CRYPTODEV)
736void ENGINE_setup_bsd_cryptodev(void);
737#endif
738
739/* BEGIN ERROR CODES */
740/* The following lines are auto generated by the script mkerr.pl. Any changes
741 * made after this point may be overwritten when the script is next run.
742 */
743void ERR_load_ENGINE_strings(void);
744
745/* Error codes for the ENGINE functions. */
746
747/* Function codes. */
748#define ENGINE_F_DYNAMIC_CTRL 180
749#define ENGINE_F_DYNAMIC_GET_DATA_CTX 181
750#define ENGINE_F_DYNAMIC_LOAD 182
751#define ENGINE_F_DYNAMIC_SET_DATA_CTX 183
752#define ENGINE_F_ENGINE_ADD 105
753#define ENGINE_F_ENGINE_BY_ID 106
754#define ENGINE_F_ENGINE_CMD_IS_EXECUTABLE 170
755#define ENGINE_F_ENGINE_CTRL 142
756#define ENGINE_F_ENGINE_CTRL_CMD 178
757#define ENGINE_F_ENGINE_CTRL_CMD_STRING 171
758#define ENGINE_F_ENGINE_FINISH 107
759#define ENGINE_F_ENGINE_FREE_UTIL 108
760#define ENGINE_F_ENGINE_GET_CIPHER 185
761#define ENGINE_F_ENGINE_GET_DEFAULT_TYPE 177
762#define ENGINE_F_ENGINE_GET_DIGEST 186
763#define ENGINE_F_ENGINE_GET_NEXT 115
764#define ENGINE_F_ENGINE_GET_PKEY_ASN1_METH 193
765#define ENGINE_F_ENGINE_GET_PKEY_METH 192
766#define ENGINE_F_ENGINE_GET_PREV 116
767#define ENGINE_F_ENGINE_INIT 119
768#define ENGINE_F_ENGINE_LIST_ADD 120
769#define ENGINE_F_ENGINE_LIST_REMOVE 121
770#define ENGINE_F_ENGINE_LOAD_PRIVATE_KEY 150
771#define ENGINE_F_ENGINE_LOAD_PUBLIC_KEY 151
772#define ENGINE_F_ENGINE_LOAD_SSL_CLIENT_CERT 194
773#define ENGINE_F_ENGINE_NEW 122
774#define ENGINE_F_ENGINE_REMOVE 123
775#define ENGINE_F_ENGINE_SET_DEFAULT_STRING 189
776#define ENGINE_F_ENGINE_SET_DEFAULT_TYPE 126
777#define ENGINE_F_ENGINE_SET_ID 129
778#define ENGINE_F_ENGINE_SET_NAME 130
779#define ENGINE_F_ENGINE_TABLE_REGISTER 184
780#define ENGINE_F_ENGINE_UNLOAD_KEY 152
781#define ENGINE_F_ENGINE_UNLOCKED_FINISH 191
782#define ENGINE_F_ENGINE_UP_REF 190
783#define ENGINE_F_INT_CTRL_HELPER 172
784#define ENGINE_F_INT_ENGINE_CONFIGURE 188
785#define ENGINE_F_INT_ENGINE_MODULE_INIT 187
786#define ENGINE_F_LOG_MESSAGE 141
787
788/* Reason codes. */
789#define ENGINE_R_ALREADY_LOADED 100
790#define ENGINE_R_ARGUMENT_IS_NOT_A_NUMBER 133
791#define ENGINE_R_CMD_NOT_EXECUTABLE 134
792#define ENGINE_R_COMMAND_TAKES_INPUT 135
793#define ENGINE_R_COMMAND_TAKES_NO_INPUT 136
794#define ENGINE_R_CONFLICTING_ENGINE_ID 103
795#define ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED 119
796#define ENGINE_R_DH_NOT_IMPLEMENTED 139
797#define ENGINE_R_DSA_NOT_IMPLEMENTED 140
798#define ENGINE_R_DSO_FAILURE 104
799#define ENGINE_R_DSO_NOT_FOUND 132
800#define ENGINE_R_ENGINES_SECTION_ERROR 148
801#define ENGINE_R_ENGINE_CONFIGURATION_ERROR 102
802#define ENGINE_R_ENGINE_IS_NOT_IN_LIST 105
803#define ENGINE_R_ENGINE_SECTION_ERROR 149
804#define ENGINE_R_FAILED_LOADING_PRIVATE_KEY 128
805#define ENGINE_R_FAILED_LOADING_PUBLIC_KEY 129
806#define ENGINE_R_FINISH_FAILED 106
807#define ENGINE_R_GET_HANDLE_FAILED 107
808#define ENGINE_R_ID_OR_NAME_MISSING 108
809#define ENGINE_R_INIT_FAILED 109
810#define ENGINE_R_INTERNAL_LIST_ERROR 110
811#define ENGINE_R_INVALID_ARGUMENT 143
812#define ENGINE_R_INVALID_CMD_NAME 137
813#define ENGINE_R_INVALID_CMD_NUMBER 138
814#define ENGINE_R_INVALID_INIT_VALUE 151
815#define ENGINE_R_INVALID_STRING 150
816#define ENGINE_R_NOT_INITIALISED 117
817#define ENGINE_R_NOT_LOADED 112
818#define ENGINE_R_NO_CONTROL_FUNCTION 120
819#define ENGINE_R_NO_INDEX 144
820#define ENGINE_R_NO_LOAD_FUNCTION 125
821#define ENGINE_R_NO_REFERENCE 130
822#define ENGINE_R_NO_SUCH_ENGINE 116
823#define ENGINE_R_NO_UNLOAD_FUNCTION 126
824#define ENGINE_R_PROVIDE_PARAMETERS 113
825#define ENGINE_R_RSA_NOT_IMPLEMENTED 141
826#define ENGINE_R_UNIMPLEMENTED_CIPHER 146
827#define ENGINE_R_UNIMPLEMENTED_DIGEST 147
828#define ENGINE_R_UNIMPLEMENTED_PUBLIC_KEY_METHOD 101
829#define ENGINE_R_VERSION_INCOMPATIBILITY 145
830
831#ifdef __cplusplus
832}
833#endif
834#endif
diff --git a/src/lib/libcrypto/engine/hw.ec b/src/lib/libcrypto/engine/hw.ec
deleted file mode 100644
index 5481a43918..0000000000
--- a/src/lib/libcrypto/engine/hw.ec
+++ /dev/null
@@ -1,8 +0,0 @@
1L AEPHK hw_aep_err.h hw_aep_err.c
2L ATALLA hw_atalla_err.h hw_atalla_err.c
3L CSWIFT hw_cswift_err.h hw_cswift_err.c
4L HWCRHK hw_ncipher_err.h hw_ncipher_err.c
5L NURON hw_nuron_err.h hw_nuron_err.c
6L SUREWARE hw_sureware_err.h hw_sureware_err.c
7L UBSEC hw_ubsec_err.h hw_ubsec_err.c
8L CCA4758 hw_4758_cca_err.h hw_4758_cca_err.c
diff --git a/src/lib/libcrypto/engine/hw_4758_cca.c b/src/lib/libcrypto/engine/hw_4758_cca.c
deleted file mode 100644
index 4f5ae8a46d..0000000000
--- a/src/lib/libcrypto/engine/hw_4758_cca.c
+++ /dev/null
@@ -1,969 +0,0 @@
1/* Author: Maurice Gittens <maurice@gittens.nl> */
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 * licensing@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#include <stdio.h>
57#include <openssl/crypto.h>
58/* #include <openssl/pem.h> */
59#include "cryptlib.h"
60#include <openssl/dso.h>
61#include <openssl/x509.h>
62#include <openssl/objects.h>
63#include <openssl/engine.h>
64
65#ifndef OPENSSL_NO_HW
66#ifndef OPENSSL_NO_HW_4758_CCA
67
68#ifdef FLAT_INC
69#include "hw_4758_cca.h"
70#else
71#include "vendor_defns/hw_4758_cca.h"
72#endif
73
74#include "hw_4758_cca_err.c"
75
76static int ibm_4758_cca_destroy(ENGINE *e);
77static int ibm_4758_cca_init(ENGINE *e);
78static int ibm_4758_cca_finish(ENGINE *e);
79static int ibm_4758_cca_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)());
80
81/* rsa functions */
82/*---------------*/
83#ifndef OPENSSL_NO_RSA
84static int cca_rsa_pub_enc(int flen, const unsigned char *from,
85 unsigned char *to, RSA *rsa,int padding);
86static int cca_rsa_priv_dec(int flen, const unsigned char *from,
87 unsigned char *to, RSA *rsa,int padding);
88static int cca_rsa_sign(int type, const unsigned char *m, unsigned int m_len,
89 unsigned char *sigret, unsigned int *siglen, const RSA *rsa);
90static int cca_rsa_verify(int dtype, const unsigned char *m, unsigned int m_len,
91 unsigned char *sigbuf, unsigned int siglen, const RSA *rsa);
92
93/* utility functions */
94/*-----------------------*/
95static EVP_PKEY *ibm_4758_load_privkey(ENGINE*, const char*,
96 UI_METHOD *ui_method, void *callback_data);
97static EVP_PKEY *ibm_4758_load_pubkey(ENGINE*, const char*,
98 UI_METHOD *ui_method, void *callback_data);
99
100static int getModulusAndExponent(const unsigned char *token, long *exponentLength,
101 unsigned char *exponent, long *modulusLength,
102 long *modulusFieldLength, unsigned char *modulus);
103#endif
104
105/* RAND number functions */
106/*-----------------------*/
107static int cca_get_random_bytes(unsigned char*, int );
108static int cca_random_status(void);
109
110static void cca_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad,
111 int idx,long argl, void *argp);
112
113/* Function pointers for CCA verbs */
114/*---------------------------------*/
115#ifndef OPENSSL_NO_RSA
116static F_KEYRECORDREAD keyRecordRead;
117static F_DIGITALSIGNATUREGENERATE digitalSignatureGenerate;
118static F_DIGITALSIGNATUREVERIFY digitalSignatureVerify;
119static F_PUBLICKEYEXTRACT publicKeyExtract;
120static F_PKAENCRYPT pkaEncrypt;
121static F_PKADECRYPT pkaDecrypt;
122#endif
123static F_RANDOMNUMBERGENERATE randomNumberGenerate;
124
125/* static variables */
126/*------------------*/
127static const char *CCA4758_LIB_NAME = NULL;
128static const char *get_CCA4758_LIB_NAME(void)
129 {
130 if(CCA4758_LIB_NAME)
131 return CCA4758_LIB_NAME;
132 return CCA_LIB_NAME;
133 }
134static void free_CCA4758_LIB_NAME(void)
135 {
136 if(CCA4758_LIB_NAME)
137 OPENSSL_free((void*)CCA4758_LIB_NAME);
138 CCA4758_LIB_NAME = NULL;
139 }
140static long set_CCA4758_LIB_NAME(const char *name)
141 {
142 free_CCA4758_LIB_NAME();
143 return (((CCA4758_LIB_NAME = BUF_strdup(name)) != NULL) ? 1 : 0);
144 }
145#ifndef OPENSSL_NO_RSA
146static const char* n_keyRecordRead = CSNDKRR;
147static const char* n_digitalSignatureGenerate = CSNDDSG;
148static const char* n_digitalSignatureVerify = CSNDDSV;
149static const char* n_publicKeyExtract = CSNDPKX;
150static const char* n_pkaEncrypt = CSNDPKE;
151static const char* n_pkaDecrypt = CSNDPKD;
152#endif
153static const char* n_randomNumberGenerate = CSNBRNG;
154
155static int hndidx = -1;
156static DSO *dso = NULL;
157
158/* openssl engine initialization structures */
159/*------------------------------------------*/
160
161#define CCA4758_CMD_SO_PATH ENGINE_CMD_BASE
162static const ENGINE_CMD_DEFN cca4758_cmd_defns[] = {
163 {CCA4758_CMD_SO_PATH,
164 "SO_PATH",
165 "Specifies the path to the '4758cca' shared library",
166 ENGINE_CMD_FLAG_STRING},
167 {0, NULL, NULL, 0}
168 };
169
170#ifndef OPENSSL_NO_RSA
171static RSA_METHOD ibm_4758_cca_rsa =
172 {
173 "IBM 4758 CCA RSA method",
174 cca_rsa_pub_enc,
175 NULL,
176 NULL,
177 cca_rsa_priv_dec,
178 NULL, /*rsa_mod_exp,*/
179 NULL, /*mod_exp_mont,*/
180 NULL, /* init */
181 NULL, /* finish */
182 RSA_FLAG_SIGN_VER, /* flags */
183 NULL, /* app_data */
184 cca_rsa_sign, /* rsa_sign */
185 cca_rsa_verify /* rsa_verify */
186 };
187#endif
188
189static RAND_METHOD ibm_4758_cca_rand =
190 {
191 /* "IBM 4758 RAND method", */
192 NULL, /* seed */
193 cca_get_random_bytes, /* get random bytes from the card */
194 NULL, /* cleanup */
195 NULL, /* add */
196 cca_get_random_bytes, /* pseudo rand */
197 cca_random_status, /* status */
198 };
199
200static const char *engine_4758_cca_id = "4758cca";
201static const char *engine_4758_cca_name = "IBM 4758 CCA hardware engine support";
202
203/* engine implementation */
204/*-----------------------*/
205static int bind_helper(ENGINE *e)
206 {
207 if(!ENGINE_set_id(e, engine_4758_cca_id) ||
208 !ENGINE_set_name(e, engine_4758_cca_name) ||
209#ifndef OPENSSL_NO_RSA
210 !ENGINE_set_RSA(e, &ibm_4758_cca_rsa) ||
211#endif
212 !ENGINE_set_RAND(e, &ibm_4758_cca_rand) ||
213 !ENGINE_set_destroy_function(e, ibm_4758_cca_destroy) ||
214 !ENGINE_set_init_function(e, ibm_4758_cca_init) ||
215 !ENGINE_set_finish_function(e, ibm_4758_cca_finish) ||
216 !ENGINE_set_ctrl_function(e, ibm_4758_cca_ctrl) ||
217 !ENGINE_set_load_privkey_function(e, ibm_4758_load_privkey) ||
218 !ENGINE_set_load_pubkey_function(e, ibm_4758_load_pubkey) ||
219 !ENGINE_set_cmd_defns(e, cca4758_cmd_defns))
220 return 0;
221 /* Ensure the error handling is set up */
222 ERR_load_CCA4758_strings();
223 return 1;
224 }
225
226#ifndef ENGINE_DYNAMIC_SUPPORT
227static ENGINE *engine_4758_cca(void)
228 {
229 ENGINE *ret = ENGINE_new();
230 if(!ret)
231 return NULL;
232 if(!bind_helper(ret))
233 {
234 ENGINE_free(ret);
235 return NULL;
236 }
237 return ret;
238 }
239
240void ENGINE_load_4758cca(void)
241 {
242 ENGINE *e_4758 = engine_4758_cca();
243 if (!e_4758) return;
244 ENGINE_add(e_4758);
245 ENGINE_free(e_4758);
246 ERR_clear_error();
247 }
248#endif
249
250static int ibm_4758_cca_destroy(ENGINE *e)
251 {
252 ERR_unload_CCA4758_strings();
253 free_CCA4758_LIB_NAME();
254 return 1;
255 }
256
257static int ibm_4758_cca_init(ENGINE *e)
258 {
259 if(dso)
260 {
261 CCA4758err(CCA4758_F_IBM_4758_CCA_INIT,CCA4758_R_ALREADY_LOADED);
262 goto err;
263 }
264
265 dso = DSO_load(NULL, get_CCA4758_LIB_NAME(), NULL, 0);
266 if(!dso)
267 {
268 CCA4758err(CCA4758_F_IBM_4758_CCA_INIT,CCA4758_R_DSO_FAILURE);
269 goto err;
270 }
271
272#ifndef OPENSSL_NO_RSA
273 if(!(keyRecordRead = (F_KEYRECORDREAD)
274 DSO_bind_func(dso, n_keyRecordRead)) ||
275 !(randomNumberGenerate = (F_RANDOMNUMBERGENERATE)
276 DSO_bind_func(dso, n_randomNumberGenerate)) ||
277 !(digitalSignatureGenerate = (F_DIGITALSIGNATUREGENERATE)
278 DSO_bind_func(dso, n_digitalSignatureGenerate)) ||
279 !(digitalSignatureVerify = (F_DIGITALSIGNATUREVERIFY)
280 DSO_bind_func(dso, n_digitalSignatureVerify)) ||
281 !(publicKeyExtract = (F_PUBLICKEYEXTRACT)
282 DSO_bind_func(dso, n_publicKeyExtract)) ||
283 !(pkaEncrypt = (F_PKAENCRYPT)
284 DSO_bind_func(dso, n_pkaEncrypt)) ||
285 !(pkaDecrypt = (F_PKADECRYPT)
286 DSO_bind_func(dso, n_pkaDecrypt)))
287 {
288 CCA4758err(CCA4758_F_IBM_4758_CCA_INIT,CCA4758_R_DSO_FAILURE);
289 goto err;
290 }
291#else
292 if(!(randomNumberGenerate = (F_RANDOMNUMBERGENERATE)
293 DSO_bind_func(dso, n_randomNumberGenerate)))
294 {
295 CCA4758err(CCA4758_F_IBM_4758_CCA_INIT,CCA4758_R_DSO_FAILURE);
296 goto err;
297 }
298#endif
299
300 hndidx = RSA_get_ex_new_index(0, "IBM 4758 CCA RSA key handle",
301 NULL, NULL, cca_ex_free);
302
303 return 1;
304err:
305 if(dso)
306 DSO_free(dso);
307 dso = NULL;
308
309 keyRecordRead = (F_KEYRECORDREAD)0;
310 randomNumberGenerate = (F_RANDOMNUMBERGENERATE)0;
311 digitalSignatureGenerate = (F_DIGITALSIGNATUREGENERATE)0;
312 digitalSignatureVerify = (F_DIGITALSIGNATUREVERIFY)0;
313 publicKeyExtract = (F_PUBLICKEYEXTRACT)0;
314 pkaEncrypt = (F_PKAENCRYPT)0;
315 pkaDecrypt = (F_PKADECRYPT)0;
316 return 0;
317 }
318
319static int ibm_4758_cca_finish(ENGINE *e)
320 {
321 free_CCA4758_LIB_NAME();
322 if(!dso)
323 {
324 CCA4758err(CCA4758_F_IBM_4758_CCA_FINISH,
325 CCA4758_R_NOT_LOADED);
326 return 0;
327 }
328 if(!DSO_free(dso))
329 {
330 CCA4758err(CCA4758_F_IBM_4758_CCA_FINISH,
331 CCA4758_R_UNIT_FAILURE);
332 return 0;
333 }
334 dso = NULL;
335 keyRecordRead = (F_KEYRECORDREAD)0;
336 randomNumberGenerate = (F_RANDOMNUMBERGENERATE)0;
337 digitalSignatureGenerate = (F_DIGITALSIGNATUREGENERATE)0;
338 digitalSignatureVerify = (F_DIGITALSIGNATUREVERIFY)0;
339 publicKeyExtract = (F_PUBLICKEYEXTRACT)0;
340 pkaEncrypt = (F_PKAENCRYPT)0;
341 pkaDecrypt = (F_PKADECRYPT)0;
342 return 1;
343 }
344
345static int ibm_4758_cca_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)())
346 {
347 int initialised = ((dso == NULL) ? 0 : 1);
348 switch(cmd)
349 {
350 case CCA4758_CMD_SO_PATH:
351 if(p == NULL)
352 {
353 CCA4758err(CCA4758_F_IBM_4758_CCA_CTRL,
354 ERR_R_PASSED_NULL_PARAMETER);
355 return 0;
356 }
357 if(initialised)
358 {
359 CCA4758err(CCA4758_F_IBM_4758_CCA_CTRL,
360 CCA4758_R_ALREADY_LOADED);
361 return 0;
362 }
363 return set_CCA4758_LIB_NAME((const char *)p);
364 default:
365 break;
366 }
367 CCA4758err(CCA4758_F_IBM_4758_CCA_CTRL,
368 CCA4758_R_COMMAND_NOT_IMPLEMENTED);
369 return 0;
370 }
371
372#ifndef OPENSSL_NO_RSA
373
374#define MAX_CCA_PKA_TOKEN_SIZE 2500
375
376static EVP_PKEY *ibm_4758_load_privkey(ENGINE* e, const char* key_id,
377 UI_METHOD *ui_method, void *callback_data)
378 {
379 RSA *rtmp = NULL;
380 EVP_PKEY *res = NULL;
381 unsigned char* keyToken = NULL;
382 unsigned char pubKeyToken[MAX_CCA_PKA_TOKEN_SIZE];
383 long pubKeyTokenLength = MAX_CCA_PKA_TOKEN_SIZE;
384 long keyTokenLength = MAX_CCA_PKA_TOKEN_SIZE;
385 long returnCode;
386 long reasonCode;
387 long exitDataLength = 0;
388 long ruleArrayLength = 0;
389 unsigned char exitData[8];
390 unsigned char ruleArray[8];
391 unsigned char keyLabel[64];
392 long keyLabelLength = strlen(key_id);
393 unsigned char modulus[256];
394 long modulusFieldLength = sizeof(modulus);
395 long modulusLength = 0;
396 unsigned char exponent[256];
397 long exponentLength = sizeof(exponent);
398
399 if (keyLabelLength > sizeof(keyLabel))
400 {
401 CCA4758err(CCA4758_F_IBM_4758_CCA_LOAD_PRIVKEY,
402 CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
403 return NULL;
404 }
405
406 memset(keyLabel,' ', sizeof(keyLabel));
407 memcpy(keyLabel, key_id, keyLabelLength);
408
409 keyToken = OPENSSL_malloc(MAX_CCA_PKA_TOKEN_SIZE + sizeof(long));
410 if (!keyToken)
411 {
412 CCA4758err(CCA4758_F_IBM_4758_CCA_LOAD_PRIVKEY,
413 ERR_R_MALLOC_FAILURE);
414 goto err;
415 }
416
417 keyRecordRead(&returnCode, &reasonCode, &exitDataLength,
418 exitData, &ruleArrayLength, ruleArray, keyLabel,
419 &keyTokenLength, keyToken+sizeof(long));
420
421 if (returnCode)
422 {
423 CCA4758err(CCA4758_F_IBM_4758_CCA_LOAD_PRIVKEY,
424 CCA4758_R_FAILED_LOADING_PRIVATE_KEY);
425 goto err;
426 }
427
428 publicKeyExtract(&returnCode, &reasonCode, &exitDataLength,
429 exitData, &ruleArrayLength, ruleArray, &keyTokenLength,
430 keyToken+sizeof(long), &pubKeyTokenLength, pubKeyToken);
431
432 if (returnCode)
433 {
434 CCA4758err(CCA4758_F_IBM_4758_CCA_LOAD_PRIVKEY,
435 CCA4758_R_FAILED_LOADING_PRIVATE_KEY);
436 goto err;
437 }
438
439 if (!getModulusAndExponent(pubKeyToken, &exponentLength,
440 exponent, &modulusLength, &modulusFieldLength,
441 modulus))
442 {
443 CCA4758err(CCA4758_F_IBM_4758_CCA_LOAD_PRIVKEY,
444 CCA4758_R_FAILED_LOADING_PRIVATE_KEY);
445 goto err;
446 }
447
448 (*(long*)keyToken) = keyTokenLength;
449 rtmp = RSA_new_method(e);
450 RSA_set_ex_data(rtmp, hndidx, (char *)keyToken);
451
452 rtmp->e = BN_bin2bn(exponent, exponentLength, NULL);
453 rtmp->n = BN_bin2bn(modulus, modulusFieldLength, NULL);
454 rtmp->flags |= RSA_FLAG_EXT_PKEY;
455
456 res = EVP_PKEY_new();
457 EVP_PKEY_assign_RSA(res, rtmp);
458
459 return res;
460err:
461 if (keyToken)
462 OPENSSL_free(keyToken);
463 if (res)
464 EVP_PKEY_free(res);
465 if (rtmp)
466 RSA_free(rtmp);
467 return NULL;
468 }
469
470static EVP_PKEY *ibm_4758_load_pubkey(ENGINE* e, const char* key_id,
471 UI_METHOD *ui_method, void *callback_data)
472 {
473 RSA *rtmp = NULL;
474 EVP_PKEY *res = NULL;
475 unsigned char* keyToken = NULL;
476 long keyTokenLength = MAX_CCA_PKA_TOKEN_SIZE;
477 long returnCode;
478 long reasonCode;
479 long exitDataLength = 0;
480 long ruleArrayLength = 0;
481 unsigned char exitData[8];
482 unsigned char ruleArray[8];
483 unsigned char keyLabel[64];
484 long keyLabelLength = strlen(key_id);
485 unsigned char modulus[512];
486 long modulusFieldLength = sizeof(modulus);
487 long modulusLength = 0;
488 unsigned char exponent[512];
489 long exponentLength = sizeof(exponent);
490
491 if (keyLabelLength > sizeof(keyLabel))
492 {
493 CCA4758err(CCA4758_F_IBM_4758_CCA_LOAD_PRIVKEY,
494 CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
495 return NULL;
496 }
497
498 memset(keyLabel,' ', sizeof(keyLabel));
499 memcpy(keyLabel, key_id, keyLabelLength);
500
501 keyToken = OPENSSL_malloc(MAX_CCA_PKA_TOKEN_SIZE + sizeof(long));
502 if (!keyToken)
503 {
504 CCA4758err(CCA4758_F_IBM_4758_CCA_LOAD_PUBKEY,
505 ERR_R_MALLOC_FAILURE);
506 goto err;
507 }
508
509 keyRecordRead(&returnCode, &reasonCode, &exitDataLength, exitData,
510 &ruleArrayLength, ruleArray, keyLabel, &keyTokenLength,
511 keyToken+sizeof(long));
512
513 if (returnCode)
514 {
515 CCA4758err(CCA4758_F_IBM_4758_CCA_LOAD_PRIVKEY,
516 ERR_R_MALLOC_FAILURE);
517 goto err;
518 }
519
520 if (!getModulusAndExponent(keyToken+sizeof(long), &exponentLength,
521 exponent, &modulusLength, &modulusFieldLength, modulus))
522 {
523 CCA4758err(CCA4758_F_IBM_4758_CCA_LOAD_PRIVKEY,
524 CCA4758_R_FAILED_LOADING_PUBLIC_KEY);
525 goto err;
526 }
527
528 (*(long*)keyToken) = keyTokenLength;
529 rtmp = RSA_new_method(e);
530 RSA_set_ex_data(rtmp, hndidx, (char *)keyToken);
531 rtmp->e = BN_bin2bn(exponent, exponentLength, NULL);
532 rtmp->n = BN_bin2bn(modulus, modulusFieldLength, NULL);
533 rtmp->flags |= RSA_FLAG_EXT_PKEY;
534 res = EVP_PKEY_new();
535 EVP_PKEY_assign_RSA(res, rtmp);
536
537 return res;
538err:
539 if (keyToken)
540 OPENSSL_free(keyToken);
541 if (res)
542 EVP_PKEY_free(res);
543 if (rtmp)
544 RSA_free(rtmp);
545 return NULL;
546 }
547
548static int cca_rsa_pub_enc(int flen, const unsigned char *from,
549 unsigned char *to, RSA *rsa,int padding)
550 {
551 long returnCode;
552 long reasonCode;
553 long lflen = flen;
554 long exitDataLength = 0;
555 unsigned char exitData[8];
556 long ruleArrayLength = 1;
557 unsigned char ruleArray[8] = "PKCS-1.2";
558 long dataStructureLength = 0;
559 unsigned char dataStructure[8];
560 long outputLength = RSA_size(rsa);
561 long keyTokenLength;
562 unsigned char* keyToken = (unsigned char*)RSA_get_ex_data(rsa, hndidx);
563
564 keyTokenLength = *(long*)keyToken;
565 keyToken+=sizeof(long);
566
567 pkaEncrypt(&returnCode, &reasonCode, &exitDataLength, exitData,
568 &ruleArrayLength, ruleArray, &lflen, (unsigned char*)from,
569 &dataStructureLength, dataStructure, &keyTokenLength,
570 keyToken, &outputLength, to);
571
572 if (returnCode || reasonCode)
573 return -(returnCode << 16 | reasonCode);
574 return outputLength;
575 }
576
577static int cca_rsa_priv_dec(int flen, const unsigned char *from,
578 unsigned char *to, RSA *rsa,int padding)
579 {
580 long returnCode;
581 long reasonCode;
582 long lflen = flen;
583 long exitDataLength = 0;
584 unsigned char exitData[8];
585 long ruleArrayLength = 1;
586 unsigned char ruleArray[8] = "PKCS-1.2";
587 long dataStructureLength = 0;
588 unsigned char dataStructure[8];
589 long outputLength = RSA_size(rsa);
590 long keyTokenLength;
591 unsigned char* keyToken = (unsigned char*)RSA_get_ex_data(rsa, hndidx);
592
593 keyTokenLength = *(long*)keyToken;
594 keyToken+=sizeof(long);
595
596 pkaDecrypt(&returnCode, &reasonCode, &exitDataLength, exitData,
597 &ruleArrayLength, ruleArray, &lflen, (unsigned char*)from,
598 &dataStructureLength, dataStructure, &keyTokenLength,
599 keyToken, &outputLength, to);
600
601 return (returnCode | reasonCode) ? 0 : 1;
602 }
603
604#define SSL_SIG_LEN 36
605
606static int cca_rsa_verify(int type, const unsigned char *m, unsigned int m_len,
607 unsigned char *sigbuf, unsigned int siglen, const RSA *rsa)
608 {
609 long returnCode;
610 long reasonCode;
611 long lsiglen = siglen;
612 long exitDataLength = 0;
613 unsigned char exitData[8];
614 long ruleArrayLength = 1;
615 unsigned char ruleArray[8] = "PKCS-1.1";
616 long keyTokenLength;
617 unsigned char* keyToken = (unsigned char*)RSA_get_ex_data(rsa, hndidx);
618 long length = SSL_SIG_LEN;
619 long keyLength ;
620 unsigned char *hashBuffer = NULL;
621 X509_SIG sig;
622 ASN1_TYPE parameter;
623 X509_ALGOR algorithm;
624 ASN1_OCTET_STRING digest;
625
626 keyTokenLength = *(long*)keyToken;
627 keyToken+=sizeof(long);
628
629 if (type == NID_md5 || type == NID_sha1)
630 {
631 sig.algor = &algorithm;
632 algorithm.algorithm = OBJ_nid2obj(type);
633
634 if (!algorithm.algorithm)
635 {
636 CCA4758err(CCA4758_F_IBM_4758_CCA_VERIFY,
637 CCA4758_R_UNKNOWN_ALGORITHM_TYPE);
638 return 0;
639 }
640
641 if (!algorithm.algorithm->length)
642 {
643 CCA4758err(CCA4758_F_IBM_4758_CCA_VERIFY,
644 CCA4758_R_ASN1_OID_UNKNOWN_FOR_MD);
645 return 0;
646 }
647
648 parameter.type = V_ASN1_NULL;
649 parameter.value.ptr = NULL;
650 algorithm.parameter = &parameter;
651
652 sig.digest = &digest;
653 sig.digest->data = (unsigned char*)m;
654 sig.digest->length = m_len;
655
656 length = i2d_X509_SIG(&sig, NULL);
657 }
658
659 keyLength = RSA_size(rsa);
660
661 if (length - RSA_PKCS1_PADDING > keyLength)
662 {
663 CCA4758err(CCA4758_F_IBM_4758_CCA_VERIFY,
664 CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
665 return 0;
666 }
667
668 switch (type)
669 {
670 case NID_md5_sha1 :
671 if (m_len != SSL_SIG_LEN)
672 {
673 CCA4758err(CCA4758_F_IBM_4758_CCA_VERIFY,
674 CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
675 return 0;
676 }
677
678 hashBuffer = (unsigned char *)m;
679 length = m_len;
680 break;
681 case NID_md5 :
682 {
683 unsigned char *ptr;
684 ptr = hashBuffer = OPENSSL_malloc(
685 (unsigned int)keyLength+1);
686 if (!hashBuffer)
687 {
688 CCA4758err(CCA4758_F_IBM_4758_CCA_VERIFY,
689 ERR_R_MALLOC_FAILURE);
690 return 0;
691 }
692
693 i2d_X509_SIG(&sig, &ptr);
694 }
695 break;
696 case NID_sha1 :
697 {
698 unsigned char *ptr;
699 ptr = hashBuffer = OPENSSL_malloc(
700 (unsigned int)keyLength+1);
701 if (!hashBuffer)
702 {
703 CCA4758err(CCA4758_F_IBM_4758_CCA_VERIFY,
704 ERR_R_MALLOC_FAILURE);
705 return 0;
706 }
707 i2d_X509_SIG(&sig, &ptr);
708 }
709 break;
710 default:
711 return 0;
712 }
713
714 digitalSignatureVerify(&returnCode, &reasonCode, &exitDataLength,
715 exitData, &ruleArrayLength, ruleArray, &keyTokenLength,
716 keyToken, &length, hashBuffer, &lsiglen, sigbuf);
717
718 if (type == NID_sha1 || type == NID_md5)
719 {
720 OPENSSL_cleanse(hashBuffer, keyLength+1);
721 OPENSSL_free(hashBuffer);
722 }
723
724 return ((returnCode || reasonCode) ? 0 : 1);
725 }
726
727#define SSL_SIG_LEN 36
728
729static int cca_rsa_sign(int type, const unsigned char *m, unsigned int m_len,
730 unsigned char *sigret, unsigned int *siglen, const RSA *rsa)
731 {
732 long returnCode;
733 long reasonCode;
734 long exitDataLength = 0;
735 unsigned char exitData[8];
736 long ruleArrayLength = 1;
737 unsigned char ruleArray[8] = "PKCS-1.1";
738 long outputLength=256;
739 long outputBitLength;
740 long keyTokenLength;
741 unsigned char *hashBuffer = NULL;
742 unsigned char* keyToken = (unsigned char*)RSA_get_ex_data(rsa, hndidx);
743 long length = SSL_SIG_LEN;
744 long keyLength ;
745 X509_SIG sig;
746 ASN1_TYPE parameter;
747 X509_ALGOR algorithm;
748 ASN1_OCTET_STRING digest;
749
750 keyTokenLength = *(long*)keyToken;
751 keyToken+=sizeof(long);
752
753 if (type == NID_md5 || type == NID_sha1)
754 {
755 sig.algor = &algorithm;
756 algorithm.algorithm = OBJ_nid2obj(type);
757
758 if (!algorithm.algorithm)
759 {
760 CCA4758err(CCA4758_F_IBM_4758_CCA_SIGN,
761 CCA4758_R_UNKNOWN_ALGORITHM_TYPE);
762 return 0;
763 }
764
765 if (!algorithm.algorithm->length)
766 {
767 CCA4758err(CCA4758_F_IBM_4758_CCA_SIGN,
768 CCA4758_R_ASN1_OID_UNKNOWN_FOR_MD);
769 return 0;
770 }
771
772 parameter.type = V_ASN1_NULL;
773 parameter.value.ptr = NULL;
774 algorithm.parameter = &parameter;
775
776 sig.digest = &digest;
777 sig.digest->data = (unsigned char*)m;
778 sig.digest->length = m_len;
779
780 length = i2d_X509_SIG(&sig, NULL);
781 }
782
783 keyLength = RSA_size(rsa);
784
785 if (length - RSA_PKCS1_PADDING > keyLength)
786 {
787 CCA4758err(CCA4758_F_IBM_4758_CCA_SIGN,
788 CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
789 return 0;
790 }
791
792 switch (type)
793 {
794 case NID_md5_sha1 :
795 if (m_len != SSL_SIG_LEN)
796 {
797 CCA4758err(CCA4758_F_IBM_4758_CCA_SIGN,
798 CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
799 return 0;
800 }
801 hashBuffer = (unsigned char*)m;
802 length = m_len;
803 break;
804 case NID_md5 :
805 {
806 unsigned char *ptr;
807 ptr = hashBuffer = OPENSSL_malloc(
808 (unsigned int)keyLength+1);
809 if (!hashBuffer)
810 {
811 CCA4758err(CCA4758_F_IBM_4758_CCA_VERIFY,
812 ERR_R_MALLOC_FAILURE);
813 return 0;
814 }
815 i2d_X509_SIG(&sig, &ptr);
816 }
817 break;
818 case NID_sha1 :
819 {
820 unsigned char *ptr;
821 ptr = hashBuffer = OPENSSL_malloc(
822 (unsigned int)keyLength+1);
823 if (!hashBuffer)
824 {
825 CCA4758err(CCA4758_F_IBM_4758_CCA_VERIFY,
826 ERR_R_MALLOC_FAILURE);
827 return 0;
828 }
829 i2d_X509_SIG(&sig, &ptr);
830 }
831 break;
832 default:
833 return 0;
834 }
835
836 digitalSignatureGenerate(&returnCode, &reasonCode, &exitDataLength,
837 exitData, &ruleArrayLength, ruleArray, &keyTokenLength,
838 keyToken, &length, hashBuffer, &outputLength, &outputBitLength,
839 sigret);
840
841 if (type == NID_sha1 || type == NID_md5)
842 {
843 OPENSSL_cleanse(hashBuffer, keyLength+1);
844 OPENSSL_free(hashBuffer);
845 }
846
847 *siglen = outputLength;
848
849 return ((returnCode || reasonCode) ? 0 : 1);
850 }
851
852static int getModulusAndExponent(const unsigned char*token, long *exponentLength,
853 unsigned char *exponent, long *modulusLength, long *modulusFieldLength,
854 unsigned char *modulus)
855 {
856 unsigned long len;
857
858 if (*token++ != (char)0x1E) /* internal PKA token? */
859 return 0;
860
861 if (*token++) /* token version must be zero */
862 return 0;
863
864 len = *token++;
865 len = len << 8;
866 len |= (unsigned char)*token++;
867
868 token += 4; /* skip reserved bytes */
869
870 if (*token++ == (char)0x04)
871 {
872 if (*token++) /* token version must be zero */
873 return 0;
874
875 len = *token++;
876 len = len << 8;
877 len |= (unsigned char)*token++;
878
879 token+=2; /* skip reserved section */
880
881 len = *token++;
882 len = len << 8;
883 len |= (unsigned char)*token++;
884
885 *exponentLength = len;
886
887 len = *token++;
888 len = len << 8;
889 len |= (unsigned char)*token++;
890
891 *modulusLength = len;
892
893 len = *token++;
894 len = len << 8;
895 len |= (unsigned char)*token++;
896
897 *modulusFieldLength = len;
898
899 memcpy(exponent, token, *exponentLength);
900 token+= *exponentLength;
901
902 memcpy(modulus, token, *modulusFieldLength);
903 return 1;
904 }
905 return 0;
906 }
907
908#endif /* OPENSSL_NO_RSA */
909
910static int cca_random_status(void)
911 {
912 return 1;
913 }
914
915static int cca_get_random_bytes(unsigned char* buf, int num)
916 {
917 long ret_code;
918 long reason_code;
919 long exit_data_length;
920 unsigned char exit_data[4];
921 unsigned char form[] = "RANDOM ";
922 unsigned char rand_buf[8];
923
924 while(num >= sizeof(rand_buf))
925 {
926 randomNumberGenerate(&ret_code, &reason_code, &exit_data_length,
927 exit_data, form, rand_buf);
928 if (ret_code)
929 return 0;
930 num -= sizeof(rand_buf);
931 memcpy(buf, rand_buf, sizeof(rand_buf));
932 buf += sizeof(rand_buf);
933 }
934
935 if (num)
936 {
937 randomNumberGenerate(&ret_code, &reason_code, NULL, NULL,
938 form, rand_buf);
939 if (ret_code)
940 return 0;
941 memcpy(buf, rand_buf, num);
942 }
943
944 return 1;
945 }
946
947static void cca_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad, int idx,
948 long argl, void *argp)
949 {
950 if (item)
951 OPENSSL_free(item);
952 }
953
954/* Goo to handle building as a dynamic engine */
955#ifdef ENGINE_DYNAMIC_SUPPORT
956static int bind_fn(ENGINE *e, const char *id)
957 {
958 if(id && (strcmp(id, engine_4758_cca_id) != 0))
959 return 0;
960 if(!bind_helper(e))
961 return 0;
962 return 1;
963 }
964IMPLEMENT_DYNAMIC_CHECK_FN()
965IMPLEMENT_DYNAMIC_BIND_FN(bind_fn)
966#endif /* ENGINE_DYNAMIC_SUPPORT */
967
968#endif /* !OPENSSL_NO_HW_4758_CCA */
969#endif /* !OPENSSL_NO_HW */
diff --git a/src/lib/libcrypto/engine/hw_4758_cca_err.c b/src/lib/libcrypto/engine/hw_4758_cca_err.c
deleted file mode 100644
index 7ea5c63707..0000000000
--- a/src/lib/libcrypto/engine/hw_4758_cca_err.c
+++ /dev/null
@@ -1,149 +0,0 @@
1/* hw_4758_cca_err.c */
2/* ====================================================================
3 * Copyright (c) 1999-2002 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 "hw_4758_cca_err.h"
64
65/* BEGIN ERROR CODES */
66#ifndef OPENSSL_NO_ERR
67static ERR_STRING_DATA CCA4758_str_functs[]=
68 {
69{ERR_PACK(0,CCA4758_F_IBM_4758_CCA_CTRL,0), "IBM_4758_CCA_CTRL"},
70{ERR_PACK(0,CCA4758_F_IBM_4758_CCA_FINISH,0), "IBM_4758_CCA_FINISH"},
71{ERR_PACK(0,CCA4758_F_IBM_4758_CCA_INIT,0), "IBM_4758_CCA_INIT"},
72{ERR_PACK(0,CCA4758_F_IBM_4758_CCA_LOAD_PRIVKEY,0), "IBM_4758_CCA_LOAD_PRIVKEY"},
73{ERR_PACK(0,CCA4758_F_IBM_4758_CCA_LOAD_PUBKEY,0), "IBM_4758_CCA_LOAD_PUBKEY"},
74{ERR_PACK(0,CCA4758_F_IBM_4758_CCA_SIGN,0), "IBM_4758_CCA_SIGN"},
75{ERR_PACK(0,CCA4758_F_IBM_4758_CCA_VERIFY,0), "IBM_4758_CCA_VERIFY"},
76{0,NULL}
77 };
78
79static ERR_STRING_DATA CCA4758_str_reasons[]=
80 {
81{CCA4758_R_ALREADY_LOADED ,"already loaded"},
82{CCA4758_R_ASN1_OID_UNKNOWN_FOR_MD ,"asn1 oid unknown for md"},
83{CCA4758_R_COMMAND_NOT_IMPLEMENTED ,"command not implemented"},
84{CCA4758_R_DSO_FAILURE ,"dso failure"},
85{CCA4758_R_FAILED_LOADING_PRIVATE_KEY ,"failed loading private key"},
86{CCA4758_R_FAILED_LOADING_PUBLIC_KEY ,"failed loading public key"},
87{CCA4758_R_NOT_LOADED ,"not loaded"},
88{CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL ,"size too large or too small"},
89{CCA4758_R_UNIT_FAILURE ,"unit failure"},
90{CCA4758_R_UNKNOWN_ALGORITHM_TYPE ,"unknown algorithm type"},
91{0,NULL}
92 };
93
94#endif
95
96#ifdef CCA4758_LIB_NAME
97static ERR_STRING_DATA CCA4758_lib_name[]=
98 {
99{0 ,CCA4758_LIB_NAME},
100{0,NULL}
101 };
102#endif
103
104
105static int CCA4758_lib_error_code=0;
106static int CCA4758_error_init=1;
107
108static void ERR_load_CCA4758_strings(void)
109 {
110 if (CCA4758_lib_error_code == 0)
111 CCA4758_lib_error_code=ERR_get_next_error_library();
112
113 if (CCA4758_error_init)
114 {
115 CCA4758_error_init=0;
116#ifndef OPENSSL_NO_ERR
117 ERR_load_strings(CCA4758_lib_error_code,CCA4758_str_functs);
118 ERR_load_strings(CCA4758_lib_error_code,CCA4758_str_reasons);
119#endif
120
121#ifdef CCA4758_LIB_NAME
122 CCA4758_lib_name->error = ERR_PACK(CCA4758_lib_error_code,0,0);
123 ERR_load_strings(0,CCA4758_lib_name);
124#endif
125 }
126 }
127
128static void ERR_unload_CCA4758_strings(void)
129 {
130 if (CCA4758_error_init == 0)
131 {
132#ifndef OPENSSL_NO_ERR
133 ERR_unload_strings(CCA4758_lib_error_code,CCA4758_str_functs);
134 ERR_unload_strings(CCA4758_lib_error_code,CCA4758_str_reasons);
135#endif
136
137#ifdef CCA4758_LIB_NAME
138 ERR_unload_strings(0,CCA4758_lib_name);
139#endif
140 CCA4758_error_init=1;
141 }
142 }
143
144static void ERR_CCA4758_error(int function, int reason, char *file, int line)
145 {
146 if (CCA4758_lib_error_code == 0)
147 CCA4758_lib_error_code=ERR_get_next_error_library();
148 ERR_PUT_error(CCA4758_lib_error_code,function,reason,file,line);
149 }
diff --git a/src/lib/libcrypto/engine/hw_aep.c b/src/lib/libcrypto/engine/hw_aep.c
deleted file mode 100644
index 5f1772ea99..0000000000
--- a/src/lib/libcrypto/engine/hw_aep.c
+++ /dev/null
@@ -1,1120 +0,0 @@
1/* crypto/engine/hw_aep.c */
2/*
3 */
4/* ====================================================================
5 * Copyright (c) 1999 The OpenSSL Project. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 *
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in
16 * the documentation and/or other materials provided with the
17 * distribution.
18 *
19 * 3. All advertising materials mentioning features or use of this
20 * software must display the following acknowledgment:
21 * "This product includes software developed by the OpenSSL Project
22 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
23 *
24 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
25 * endorse or promote products derived from this software without
26 * prior written permission. For written permission, please contact
27 * licensing@OpenSSL.org.
28 *
29 * 5. Products derived from this software may not be called "OpenSSL"
30 * nor may "OpenSSL" appear in their names without prior written
31 * permission of the OpenSSL Project.
32 *
33 * 6. Redistributions of any form whatsoever must retain the following
34 * acknowledgment:
35 * "This product includes software developed by the OpenSSL Project
36 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
37 *
38 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
39 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
40 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
41 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
42 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
43 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
44 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
45 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
46 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
47 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
48 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
49 * OF THE POSSIBILITY OF SUCH DAMAGE.
50 * ====================================================================
51 *
52 * This product includes cryptographic software written by Eric Young
53 * (eay@cryptsoft.com). This product includes software written by Tim
54 * Hudson (tjh@cryptsoft.com).
55 *
56 */
57
58#include <stdio.h>
59#include <openssl/bn.h>
60#include <string.h>
61
62#include <openssl/e_os2.h>
63#if !defined(OPENSSL_SYS_MSDOS) || defined(__DJGPP__)
64#include <sys/types.h>
65#include <unistd.h>
66#else
67#include <process.h>
68typedef int pid_t;
69#endif
70
71#include <openssl/crypto.h>
72#include <openssl/dso.h>
73#include <openssl/engine.h>
74#include <openssl/buffer.h>
75
76#ifndef OPENSSL_NO_HW
77#ifndef OPENSSL_NO_HW_AEP
78#ifdef FLAT_INC
79#include "aep.h"
80#else
81#include "vendor_defns/aep.h"
82#endif
83
84#define AEP_LIB_NAME "aep engine"
85#define FAIL_TO_SW 0x10101010
86
87#include "hw_aep_err.c"
88
89static int aep_init(ENGINE *e);
90static int aep_finish(ENGINE *e);
91static int aep_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)());
92static int aep_destroy(ENGINE *e);
93
94static AEP_RV aep_get_connection(AEP_CONNECTION_HNDL_PTR hConnection);
95static AEP_RV aep_return_connection(AEP_CONNECTION_HNDL hConnection);
96static AEP_RV aep_close_connection(AEP_CONNECTION_HNDL hConnection);
97static AEP_RV aep_close_all_connections(int use_engine_lock, int *in_use);
98
99/* BIGNUM stuff */
100static int aep_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
101 const BIGNUM *m, BN_CTX *ctx);
102
103static AEP_RV aep_mod_exp_crt(BIGNUM *r,const BIGNUM *a, const BIGNUM *p,
104 const BIGNUM *q, const BIGNUM *dmp1,const BIGNUM *dmq1,
105 const BIGNUM *iqmp, BN_CTX *ctx);
106
107/* RSA stuff */
108#ifndef OPENSSL_NO_RSA
109static int aep_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa);
110#endif
111
112/* This function is aliased to mod_exp (with the mont stuff dropped). */
113static int aep_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
114 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
115
116/* DSA stuff */
117#ifndef OPENSSL_NO_DSA
118static int aep_dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1,
119 BIGNUM *p1, BIGNUM *a2, BIGNUM *p2, BIGNUM *m,
120 BN_CTX *ctx, BN_MONT_CTX *in_mont);
121
122static int aep_mod_exp_dsa(DSA *dsa, BIGNUM *r, BIGNUM *a,
123 const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
124 BN_MONT_CTX *m_ctx);
125#endif
126
127/* DH stuff */
128/* This function is aliased to mod_exp (with the DH and mont dropped). */
129#ifndef OPENSSL_NO_DH
130static int aep_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a,
131 const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
132#endif
133
134/* rand stuff */
135#ifdef AEPRAND
136static int aep_rand(unsigned char *buf, int num);
137static int aep_rand_status(void);
138#endif
139
140/* Bignum conversion stuff */
141static AEP_RV GetBigNumSize(AEP_VOID_PTR ArbBigNum, AEP_U32* BigNumSize);
142static AEP_RV MakeAEPBigNum(AEP_VOID_PTR ArbBigNum, AEP_U32 BigNumSize,
143 unsigned char* AEP_BigNum);
144static AEP_RV ConvertAEPBigNum(void* ArbBigNum, AEP_U32 BigNumSize,
145 unsigned char* AEP_BigNum);
146
147/* The definitions for control commands specific to this engine */
148#define AEP_CMD_SO_PATH ENGINE_CMD_BASE
149static const ENGINE_CMD_DEFN aep_cmd_defns[] =
150 {
151 { AEP_CMD_SO_PATH,
152 "SO_PATH",
153 "Specifies the path to the 'aep' shared library",
154 ENGINE_CMD_FLAG_STRING
155 },
156 {0, NULL, NULL, 0}
157 };
158
159#ifndef OPENSSL_NO_RSA
160/* Our internal RSA_METHOD that we provide pointers to */
161static RSA_METHOD aep_rsa =
162 {
163 "Aep RSA method",
164 NULL, /*rsa_pub_encrypt*/
165 NULL, /*rsa_pub_decrypt*/
166 NULL, /*rsa_priv_encrypt*/
167 NULL, /*rsa_priv_encrypt*/
168 aep_rsa_mod_exp, /*rsa_mod_exp*/
169 aep_mod_exp_mont, /*bn_mod_exp*/
170 NULL, /*init*/
171 NULL, /*finish*/
172 0, /*flags*/
173 NULL, /*app_data*/
174 NULL, /*rsa_sign*/
175 NULL /*rsa_verify*/
176 };
177#endif
178
179#ifndef OPENSSL_NO_DSA
180/* Our internal DSA_METHOD that we provide pointers to */
181static DSA_METHOD aep_dsa =
182 {
183 "Aep DSA method",
184 NULL, /* dsa_do_sign */
185 NULL, /* dsa_sign_setup */
186 NULL, /* dsa_do_verify */
187 aep_dsa_mod_exp, /* dsa_mod_exp */
188 aep_mod_exp_dsa, /* bn_mod_exp */
189 NULL, /* init */
190 NULL, /* finish */
191 0, /* flags */
192 NULL /* app_data */
193 };
194#endif
195
196#ifndef OPENSSL_NO_DH
197/* Our internal DH_METHOD that we provide pointers to */
198static DH_METHOD aep_dh =
199 {
200 "Aep DH method",
201 NULL,
202 NULL,
203 aep_mod_exp_dh,
204 NULL,
205 NULL,
206 0,
207 NULL
208 };
209#endif
210
211#ifdef AEPRAND
212/* our internal RAND_method that we provide pointers to */
213static RAND_METHOD aep_random =
214 {
215 /*"AEP RAND method", */
216 NULL,
217 aep_rand,
218 NULL,
219 NULL,
220 aep_rand,
221 aep_rand_status,
222 };
223#endif
224
225/*Define an array of structures to hold connections*/
226static AEP_CONNECTION_ENTRY aep_app_conn_table[MAX_PROCESS_CONNECTIONS];
227
228/*Used to determine if this is a new process*/
229static pid_t recorded_pid = 0;
230
231#ifdef AEPRAND
232static AEP_U8 rand_block[RAND_BLK_SIZE];
233static AEP_U32 rand_block_bytes = 0;
234#endif
235
236/* Constants used when creating the ENGINE */
237static const char *engine_aep_id = "aep";
238static const char *engine_aep_name = "Aep hardware engine support";
239
240static int max_key_len = 2176;
241
242
243/* This internal function is used by ENGINE_aep() and possibly by the
244 * "dynamic" ENGINE support too */
245static int bind_aep(ENGINE *e)
246 {
247#ifndef OPENSSL_NO_RSA
248 const RSA_METHOD *meth1;
249#endif
250#ifndef OPENSSL_NO_DSA
251 const DSA_METHOD *meth2;
252#endif
253#ifndef OPENSSL_NO_DH
254 const DH_METHOD *meth3;
255#endif
256
257 if(!ENGINE_set_id(e, engine_aep_id) ||
258 !ENGINE_set_name(e, engine_aep_name) ||
259#ifndef OPENSSL_NO_RSA
260 !ENGINE_set_RSA(e, &aep_rsa) ||
261#endif
262#ifndef OPENSSL_NO_DSA
263 !ENGINE_set_DSA(e, &aep_dsa) ||
264#endif
265#ifndef OPENSSL_NO_DH
266 !ENGINE_set_DH(e, &aep_dh) ||
267#endif
268#ifdef AEPRAND
269 !ENGINE_set_RAND(e, &aep_random) ||
270#endif
271 !ENGINE_set_init_function(e, aep_init) ||
272 !ENGINE_set_destroy_function(e, aep_destroy) ||
273 !ENGINE_set_finish_function(e, aep_finish) ||
274 !ENGINE_set_ctrl_function(e, aep_ctrl) ||
275 !ENGINE_set_cmd_defns(e, aep_cmd_defns))
276 return 0;
277
278#ifndef OPENSSL_NO_RSA
279 /* We know that the "PKCS1_SSLeay()" functions hook properly
280 * to the aep-specific mod_exp and mod_exp_crt so we use
281 * those functions. NB: We don't use ENGINE_openssl() or
282 * anything "more generic" because something like the RSAref
283 * code may not hook properly, and if you own one of these
284 * cards then you have the right to do RSA operations on it
285 * anyway! */
286 meth1 = RSA_PKCS1_SSLeay();
287 aep_rsa.rsa_pub_enc = meth1->rsa_pub_enc;
288 aep_rsa.rsa_pub_dec = meth1->rsa_pub_dec;
289 aep_rsa.rsa_priv_enc = meth1->rsa_priv_enc;
290 aep_rsa.rsa_priv_dec = meth1->rsa_priv_dec;
291#endif
292
293
294#ifndef OPENSSL_NO_DSA
295 /* Use the DSA_OpenSSL() method and just hook the mod_exp-ish
296 * bits. */
297 meth2 = DSA_OpenSSL();
298 aep_dsa.dsa_do_sign = meth2->dsa_do_sign;
299 aep_dsa.dsa_sign_setup = meth2->dsa_sign_setup;
300 aep_dsa.dsa_do_verify = meth2->dsa_do_verify;
301
302 aep_dsa = *DSA_get_default_method();
303 aep_dsa.dsa_mod_exp = aep_dsa_mod_exp;
304 aep_dsa.bn_mod_exp = aep_mod_exp_dsa;
305#endif
306
307#ifndef OPENSSL_NO_DH
308 /* Much the same for Diffie-Hellman */
309 meth3 = DH_OpenSSL();
310 aep_dh.generate_key = meth3->generate_key;
311 aep_dh.compute_key = meth3->compute_key;
312 aep_dh.bn_mod_exp = meth3->bn_mod_exp;
313#endif
314
315 /* Ensure the aep error handling is set up */
316 ERR_load_AEPHK_strings();
317
318 return 1;
319}
320
321#ifdef ENGINE_DYNAMIC_SUPPORT
322static int bind_helper(ENGINE *e, const char *id)
323 {
324 if(id && (strcmp(id, engine_aep_id) != 0))
325 return 0;
326 if(!bind_aep(e))
327 return 0;
328 return 1;
329 }
330IMPLEMENT_DYNAMIC_CHECK_FN()
331IMPLEMENT_DYNAMIC_BIND_FN(bind_helper)
332#else
333static ENGINE *engine_aep(void)
334 {
335 ENGINE *ret = ENGINE_new();
336 if(!ret)
337 return NULL;
338 if(!bind_aep(ret))
339 {
340 ENGINE_free(ret);
341 return NULL;
342 }
343 return ret;
344 }
345
346void ENGINE_load_aep(void)
347 {
348 /* Copied from eng_[openssl|dyn].c */
349 ENGINE *toadd = engine_aep();
350 if(!toadd) return;
351 ENGINE_add(toadd);
352 ENGINE_free(toadd);
353 ERR_clear_error();
354 }
355#endif
356
357/* This is a process-global DSO handle used for loading and unloading
358 * the Aep library. NB: This is only set (or unset) during an
359 * init() or finish() call (reference counts permitting) and they're
360 * operating with global locks, so this should be thread-safe
361 * implicitly. */
362static DSO *aep_dso = NULL;
363
364/* These are the static string constants for the DSO file name and the function
365 * symbol names to bind to.
366*/
367static const char *AEP_LIBNAME = NULL;
368static const char *get_AEP_LIBNAME(void)
369 {
370 if(AEP_LIBNAME)
371 return AEP_LIBNAME;
372 return "aep";
373 }
374static void free_AEP_LIBNAME(void)
375 {
376 if(AEP_LIBNAME)
377 OPENSSL_free((void*)AEP_LIBNAME);
378 AEP_LIBNAME = NULL;
379 }
380static long set_AEP_LIBNAME(const char *name)
381 {
382 free_AEP_LIBNAME();
383 return ((AEP_LIBNAME = BUF_strdup(name)) != NULL ? 1 : 0);
384 }
385
386static const char *AEP_F1 = "AEP_ModExp";
387static const char *AEP_F2 = "AEP_ModExpCrt";
388#ifdef AEPRAND
389static const char *AEP_F3 = "AEP_GenRandom";
390#endif
391static const char *AEP_F4 = "AEP_Finalize";
392static const char *AEP_F5 = "AEP_Initialize";
393static const char *AEP_F6 = "AEP_OpenConnection";
394static const char *AEP_F7 = "AEP_SetBNCallBacks";
395static const char *AEP_F8 = "AEP_CloseConnection";
396
397/* These are the function pointers that are (un)set when the library has
398 * successfully (un)loaded. */
399static t_AEP_OpenConnection *p_AEP_OpenConnection = NULL;
400static t_AEP_CloseConnection *p_AEP_CloseConnection = NULL;
401static t_AEP_ModExp *p_AEP_ModExp = NULL;
402static t_AEP_ModExpCrt *p_AEP_ModExpCrt = NULL;
403#ifdef AEPRAND
404static t_AEP_GenRandom *p_AEP_GenRandom = NULL;
405#endif
406static t_AEP_Initialize *p_AEP_Initialize = NULL;
407static t_AEP_Finalize *p_AEP_Finalize = NULL;
408static t_AEP_SetBNCallBacks *p_AEP_SetBNCallBacks = NULL;
409
410/* (de)initialisation functions. */
411static int aep_init(ENGINE *e)
412 {
413 t_AEP_ModExp *p1;
414 t_AEP_ModExpCrt *p2;
415#ifdef AEPRAND
416 t_AEP_GenRandom *p3;
417#endif
418 t_AEP_Finalize *p4;
419 t_AEP_Initialize *p5;
420 t_AEP_OpenConnection *p6;
421 t_AEP_SetBNCallBacks *p7;
422 t_AEP_CloseConnection *p8;
423
424 int to_return = 0;
425
426 if(aep_dso != NULL)
427 {
428 AEPHKerr(AEPHK_F_AEP_INIT,AEPHK_R_ALREADY_LOADED);
429 goto err;
430 }
431 /* Attempt to load libaep.so. */
432
433 aep_dso = DSO_load(NULL, get_AEP_LIBNAME(), NULL, 0);
434
435 if(aep_dso == NULL)
436 {
437 AEPHKerr(AEPHK_F_AEP_INIT,AEPHK_R_NOT_LOADED);
438 goto err;
439 }
440
441 if( !(p1 = (t_AEP_ModExp *) DSO_bind_func( aep_dso,AEP_F1)) ||
442 !(p2 = (t_AEP_ModExpCrt*) DSO_bind_func( aep_dso,AEP_F2)) ||
443#ifdef AEPRAND
444 !(p3 = (t_AEP_GenRandom*) DSO_bind_func( aep_dso,AEP_F3)) ||
445#endif
446 !(p4 = (t_AEP_Finalize*) DSO_bind_func( aep_dso,AEP_F4)) ||
447 !(p5 = (t_AEP_Initialize*) DSO_bind_func( aep_dso,AEP_F5)) ||
448 !(p6 = (t_AEP_OpenConnection*) DSO_bind_func( aep_dso,AEP_F6)) ||
449 !(p7 = (t_AEP_SetBNCallBacks*) DSO_bind_func( aep_dso,AEP_F7)) ||
450 !(p8 = (t_AEP_CloseConnection*) DSO_bind_func( aep_dso,AEP_F8)))
451 {
452 AEPHKerr(AEPHK_F_AEP_INIT,AEPHK_R_NOT_LOADED);
453 goto err;
454 }
455
456 /* Copy the pointers */
457
458 p_AEP_ModExp = p1;
459 p_AEP_ModExpCrt = p2;
460#ifdef AEPRAND
461 p_AEP_GenRandom = p3;
462#endif
463 p_AEP_Finalize = p4;
464 p_AEP_Initialize = p5;
465 p_AEP_OpenConnection = p6;
466 p_AEP_SetBNCallBacks = p7;
467 p_AEP_CloseConnection = p8;
468
469 to_return = 1;
470
471 return to_return;
472
473 err:
474
475 if(aep_dso)
476 DSO_free(aep_dso);
477 aep_dso = NULL;
478
479 p_AEP_OpenConnection = NULL;
480 p_AEP_ModExp = NULL;
481 p_AEP_ModExpCrt = NULL;
482#ifdef AEPRAND
483 p_AEP_GenRandom = NULL;
484#endif
485 p_AEP_Initialize = NULL;
486 p_AEP_Finalize = NULL;
487 p_AEP_SetBNCallBacks = NULL;
488 p_AEP_CloseConnection = NULL;
489
490 return to_return;
491 }
492
493/* Destructor (complements the "ENGINE_aep()" constructor) */
494static int aep_destroy(ENGINE *e)
495 {
496 free_AEP_LIBNAME();
497 ERR_unload_AEPHK_strings();
498 return 1;
499 }
500
501static int aep_finish(ENGINE *e)
502 {
503 int to_return = 0, in_use;
504 AEP_RV rv;
505
506 if(aep_dso == NULL)
507 {
508 AEPHKerr(AEPHK_F_AEP_FINISH,AEPHK_R_NOT_LOADED);
509 goto err;
510 }
511
512 rv = aep_close_all_connections(0, &in_use);
513 if (rv != AEP_R_OK)
514 {
515 AEPHKerr(AEPHK_F_AEP_FINISH,AEPHK_R_CLOSE_HANDLES_FAILED);
516 goto err;
517 }
518 if (in_use)
519 {
520 AEPHKerr(AEPHK_F_AEP_FINISH,AEPHK_R_CONNECTIONS_IN_USE);
521 goto err;
522 }
523
524 rv = p_AEP_Finalize();
525 if (rv != AEP_R_OK)
526 {
527 AEPHKerr(AEPHK_F_AEP_FINISH,AEPHK_R_FINALIZE_FAILED);
528 goto err;
529 }
530
531 if(!DSO_free(aep_dso))
532 {
533 AEPHKerr(AEPHK_F_AEP_FINISH,AEPHK_R_UNIT_FAILURE);
534 goto err;
535 }
536
537 aep_dso = NULL;
538 p_AEP_CloseConnection = NULL;
539 p_AEP_OpenConnection = NULL;
540 p_AEP_ModExp = NULL;
541 p_AEP_ModExpCrt = NULL;
542#ifdef AEPRAND
543 p_AEP_GenRandom = NULL;
544#endif
545 p_AEP_Initialize = NULL;
546 p_AEP_Finalize = NULL;
547 p_AEP_SetBNCallBacks = NULL;
548
549 to_return = 1;
550 err:
551 return to_return;
552 }
553
554static int aep_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)())
555 {
556 int initialised = ((aep_dso == NULL) ? 0 : 1);
557 switch(cmd)
558 {
559 case AEP_CMD_SO_PATH:
560 if(p == NULL)
561 {
562 AEPHKerr(AEPHK_F_AEP_CTRL,
563 ERR_R_PASSED_NULL_PARAMETER);
564 return 0;
565 }
566 if(initialised)
567 {
568 AEPHKerr(AEPHK_F_AEP_CTRL,
569 AEPHK_R_ALREADY_LOADED);
570 return 0;
571 }
572 return set_AEP_LIBNAME((const char*)p);
573 default:
574 break;
575 }
576 AEPHKerr(AEPHK_F_AEP_CTRL,AEPHK_R_CTRL_COMMAND_NOT_IMPLEMENTED);
577 return 0;
578 }
579
580static int aep_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
581 const BIGNUM *m, BN_CTX *ctx)
582 {
583 int to_return = 0;
584 int r_len = 0;
585 AEP_CONNECTION_HNDL hConnection;
586 AEP_RV rv;
587
588 r_len = BN_num_bits(m);
589
590 /* Perform in software if modulus is too large for hardware. */
591
592 if (r_len > max_key_len){
593 AEPHKerr(AEPHK_F_AEP_MOD_EXP, AEPHK_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
594 return BN_mod_exp(r, a, p, m, ctx);
595 }
596
597 /*Grab a connection from the pool*/
598 rv = aep_get_connection(&hConnection);
599 if (rv != AEP_R_OK)
600 {
601 AEPHKerr(AEPHK_F_AEP_MOD_EXP,AEPHK_R_GET_HANDLE_FAILED);
602 return BN_mod_exp(r, a, p, m, ctx);
603 }
604
605 /*To the card with the mod exp*/
606 rv = p_AEP_ModExp(hConnection,(void*)a, (void*)p,(void*)m, (void*)r,NULL);
607
608 if (rv != AEP_R_OK)
609 {
610 AEPHKerr(AEPHK_F_AEP_MOD_EXP,AEPHK_R_MOD_EXP_FAILED);
611 rv = aep_close_connection(hConnection);
612 return BN_mod_exp(r, a, p, m, ctx);
613 }
614
615 /*Return the connection to the pool*/
616 rv = aep_return_connection(hConnection);
617 if (rv != AEP_R_OK)
618 {
619 AEPHKerr(AEPHK_F_AEP_RAND,AEPHK_R_RETURN_CONNECTION_FAILED);
620 goto err;
621 }
622
623 to_return = 1;
624 err:
625 return to_return;
626 }
627
628static AEP_RV aep_mod_exp_crt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
629 const BIGNUM *q, const BIGNUM *dmp1,
630 const BIGNUM *dmq1,const BIGNUM *iqmp, BN_CTX *ctx)
631 {
632 AEP_RV rv = AEP_R_OK;
633 AEP_CONNECTION_HNDL hConnection;
634
635 /*Grab a connection from the pool*/
636 rv = aep_get_connection(&hConnection);
637 if (rv != AEP_R_OK)
638 {
639 AEPHKerr(AEPHK_F_AEP_MOD_EXP_CRT,AEPHK_R_GET_HANDLE_FAILED);
640 return FAIL_TO_SW;
641 }
642
643 /*To the card with the mod exp*/
644 rv = p_AEP_ModExpCrt(hConnection,(void*)a, (void*)p, (void*)q, (void*)dmp1,(void*)dmq1,
645 (void*)iqmp,(void*)r,NULL);
646 if (rv != AEP_R_OK)
647 {
648 AEPHKerr(AEPHK_F_AEP_MOD_EXP_CRT,AEPHK_R_MOD_EXP_CRT_FAILED);
649 rv = aep_close_connection(hConnection);
650 return FAIL_TO_SW;
651 }
652
653 /*Return the connection to the pool*/
654 rv = aep_return_connection(hConnection);
655 if (rv != AEP_R_OK)
656 {
657 AEPHKerr(AEPHK_F_AEP_RAND,AEPHK_R_RETURN_CONNECTION_FAILED);
658 goto err;
659 }
660
661 err:
662 return rv;
663 }
664
665
666#ifdef AEPRAND
667static int aep_rand(unsigned char *buf,int len )
668 {
669 AEP_RV rv = AEP_R_OK;
670 AEP_CONNECTION_HNDL hConnection;
671
672 CRYPTO_w_lock(CRYPTO_LOCK_RAND);
673
674 /*Can the request be serviced with what's already in the buffer?*/
675 if (len <= rand_block_bytes)
676 {
677 memcpy(buf, &rand_block[RAND_BLK_SIZE - rand_block_bytes], len);
678 rand_block_bytes -= len;
679 CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
680 }
681 else
682 /*If not the get another block of random bytes*/
683 {
684 CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
685
686 rv = aep_get_connection(&hConnection);
687 if (rv != AEP_R_OK)
688 {
689 AEPHKerr(AEPHK_F_AEP_RAND,AEPHK_R_GET_HANDLE_FAILED);
690 goto err_nounlock;
691 }
692
693 if (len > RAND_BLK_SIZE)
694 {
695 rv = p_AEP_GenRandom(hConnection, len, 2, buf, NULL);
696 if (rv != AEP_R_OK)
697 {
698 AEPHKerr(AEPHK_F_AEP_RAND,AEPHK_R_GET_RANDOM_FAILED);
699 goto err_nounlock;
700 }
701 }
702 else
703 {
704 CRYPTO_w_lock(CRYPTO_LOCK_RAND);
705
706 rv = p_AEP_GenRandom(hConnection, RAND_BLK_SIZE, 2, &rand_block[0], NULL);
707 if (rv != AEP_R_OK)
708 {
709 AEPHKerr(AEPHK_F_AEP_RAND,AEPHK_R_GET_RANDOM_FAILED);
710
711 goto err;
712 }
713
714 rand_block_bytes = RAND_BLK_SIZE;
715
716 memcpy(buf, &rand_block[RAND_BLK_SIZE - rand_block_bytes], len);
717 rand_block_bytes -= len;
718
719 CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
720 }
721
722 rv = aep_return_connection(hConnection);
723 if (rv != AEP_R_OK)
724 {
725 AEPHKerr(AEPHK_F_AEP_RAND,AEPHK_R_RETURN_CONNECTION_FAILED);
726
727 goto err_nounlock;
728 }
729 }
730
731 return 1;
732 err:
733 CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
734 err_nounlock:
735 return 0;
736 }
737
738static int aep_rand_status(void)
739{
740 return 1;
741}
742#endif
743
744#ifndef OPENSSL_NO_RSA
745static int aep_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa)
746 {
747 BN_CTX *ctx = NULL;
748 int to_return = 0;
749 AEP_RV rv = AEP_R_OK;
750
751 if ((ctx = BN_CTX_new()) == NULL)
752 goto err;
753
754 if (!aep_dso)
755 {
756 AEPHKerr(AEPHK_F_AEP_RSA_MOD_EXP,AEPHK_R_NOT_LOADED);
757 goto err;
758 }
759
760 /*See if we have all the necessary bits for a crt*/
761 if (rsa->q && rsa->dmp1 && rsa->dmq1 && rsa->iqmp)
762 {
763 rv = aep_mod_exp_crt(r0,I,rsa->p,rsa->q, rsa->dmp1,rsa->dmq1,rsa->iqmp,ctx);
764
765 if (rv == FAIL_TO_SW){
766 const RSA_METHOD *meth = RSA_PKCS1_SSLeay();
767 to_return = (*meth->rsa_mod_exp)(r0, I, rsa);
768 goto err;
769 }
770 else if (rv != AEP_R_OK)
771 goto err;
772 }
773 else
774 {
775 if (!rsa->d || !rsa->n)
776 {
777 AEPHKerr(AEPHK_F_AEP_RSA_MOD_EXP,AEPHK_R_MISSING_KEY_COMPONENTS);
778 goto err;
779 }
780
781 rv = aep_mod_exp(r0,I,rsa->d,rsa->n,ctx);
782 if (rv != AEP_R_OK)
783 goto err;
784
785 }
786
787 to_return = 1;
788
789 err:
790 if(ctx)
791 BN_CTX_free(ctx);
792 return to_return;
793}
794#endif
795
796#ifndef OPENSSL_NO_DSA
797static int aep_dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1,
798 BIGNUM *p1, BIGNUM *a2, BIGNUM *p2, BIGNUM *m,
799 BN_CTX *ctx, BN_MONT_CTX *in_mont)
800 {
801 BIGNUM t;
802 int to_return = 0;
803 BN_init(&t);
804
805 /* let rr = a1 ^ p1 mod m */
806 if (!aep_mod_exp(rr,a1,p1,m,ctx)) goto end;
807 /* let t = a2 ^ p2 mod m */
808 if (!aep_mod_exp(&t,a2,p2,m,ctx)) goto end;
809 /* let rr = rr * t mod m */
810 if (!BN_mod_mul(rr,rr,&t,m,ctx)) goto end;
811 to_return = 1;
812 end:
813 BN_free(&t);
814 return to_return;
815 }
816
817static int aep_mod_exp_dsa(DSA *dsa, BIGNUM *r, BIGNUM *a,
818 const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
819 BN_MONT_CTX *m_ctx)
820 {
821 return aep_mod_exp(r, a, p, m, ctx);
822 }
823#endif
824
825/* This function is aliased to mod_exp (with the mont stuff dropped). */
826static int aep_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
827 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
828 {
829 return aep_mod_exp(r, a, p, m, ctx);
830 }
831
832#ifndef OPENSSL_NO_DH
833/* This function is aliased to mod_exp (with the dh and mont dropped). */
834static int aep_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a,
835 const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
836 BN_MONT_CTX *m_ctx)
837 {
838 return aep_mod_exp(r, a, p, m, ctx);
839 }
840#endif
841
842static AEP_RV aep_get_connection(AEP_CONNECTION_HNDL_PTR phConnection)
843 {
844 int count;
845 AEP_RV rv = AEP_R_OK;
846
847 /*Get the current process id*/
848 pid_t curr_pid;
849
850 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
851
852 curr_pid = getpid();
853
854 /*Check if this is the first time this is being called from the current
855 process*/
856 if (recorded_pid != curr_pid)
857 {
858 /*Remember our pid so we can check if we're in a new process*/
859 recorded_pid = curr_pid;
860
861 /*Call Finalize to make sure we have not inherited some data
862 from a parent process*/
863 p_AEP_Finalize();
864
865 /*Initialise the AEP API*/
866 rv = p_AEP_Initialize(NULL);
867
868 if (rv != AEP_R_OK)
869 {
870 AEPHKerr(AEPHK_F_AEP_GET_CONNECTION,AEPHK_R_INIT_FAILURE);
871 recorded_pid = 0;
872 goto end;
873 }
874
875 /*Set the AEP big num call back functions*/
876 rv = p_AEP_SetBNCallBacks(&GetBigNumSize, &MakeAEPBigNum,
877 &ConvertAEPBigNum);
878
879 if (rv != AEP_R_OK)
880 {
881 AEPHKerr(AEPHK_F_AEP_GET_CONNECTION,AEPHK_R_SETBNCALLBACK_FAILURE);
882 recorded_pid = 0;
883 goto end;
884 }
885
886#ifdef AEPRAND
887 /*Reset the rand byte count*/
888 rand_block_bytes = 0;
889#endif
890
891 /*Init the structures*/
892 for (count = 0;count < MAX_PROCESS_CONNECTIONS;count ++)
893 {
894 aep_app_conn_table[count].conn_state = NotConnected;
895 aep_app_conn_table[count].conn_hndl = 0;
896 }
897
898 /*Open a connection*/
899 rv = p_AEP_OpenConnection(phConnection);
900
901 if (rv != AEP_R_OK)
902 {
903 AEPHKerr(AEPHK_F_AEP_GET_CONNECTION,AEPHK_R_UNIT_FAILURE);
904 recorded_pid = 0;
905 goto end;
906 }
907
908 aep_app_conn_table[0].conn_state = InUse;
909 aep_app_conn_table[0].conn_hndl = *phConnection;
910 goto end;
911 }
912 /*Check the existing connections to see if we can find a free one*/
913 for (count = 0;count < MAX_PROCESS_CONNECTIONS;count ++)
914 {
915 if (aep_app_conn_table[count].conn_state == Connected)
916 {
917 aep_app_conn_table[count].conn_state = InUse;
918 *phConnection = aep_app_conn_table[count].conn_hndl;
919 goto end;
920 }
921 }
922 /*If no connections available, we're going to have to try
923 to open a new one*/
924 for (count = 0;count < MAX_PROCESS_CONNECTIONS;count ++)
925 {
926 if (aep_app_conn_table[count].conn_state == NotConnected)
927 {
928 /*Open a connection*/
929 rv = p_AEP_OpenConnection(phConnection);
930
931 if (rv != AEP_R_OK)
932 {
933 AEPHKerr(AEPHK_F_AEP_GET_CONNECTION,AEPHK_R_UNIT_FAILURE);
934 goto end;
935 }
936
937 aep_app_conn_table[count].conn_state = InUse;
938 aep_app_conn_table[count].conn_hndl = *phConnection;
939 goto end;
940 }
941 }
942 rv = AEP_R_GENERAL_ERROR;
943 end:
944 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
945 return rv;
946 }
947
948
949static AEP_RV aep_return_connection(AEP_CONNECTION_HNDL hConnection)
950 {
951 int count;
952
953 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
954
955 /*Find the connection item that matches this connection handle*/
956 for(count = 0;count < MAX_PROCESS_CONNECTIONS;count ++)
957 {
958 if (aep_app_conn_table[count].conn_hndl == hConnection)
959 {
960 aep_app_conn_table[count].conn_state = Connected;
961 break;
962 }
963 }
964
965 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
966
967 return AEP_R_OK;
968 }
969
970static AEP_RV aep_close_connection(AEP_CONNECTION_HNDL hConnection)
971 {
972 int count;
973 AEP_RV rv = AEP_R_OK;
974
975 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
976
977 /*Find the connection item that matches this connection handle*/
978 for(count = 0;count < MAX_PROCESS_CONNECTIONS;count ++)
979 {
980 if (aep_app_conn_table[count].conn_hndl == hConnection)
981 {
982 rv = p_AEP_CloseConnection(aep_app_conn_table[count].conn_hndl);
983 if (rv != AEP_R_OK)
984 goto end;
985 aep_app_conn_table[count].conn_state = NotConnected;
986 aep_app_conn_table[count].conn_hndl = 0;
987 break;
988 }
989 }
990
991 end:
992 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
993 return rv;
994 }
995
996static AEP_RV aep_close_all_connections(int use_engine_lock, int *in_use)
997 {
998 int count;
999 AEP_RV rv = AEP_R_OK;
1000
1001 *in_use = 0;
1002 if (use_engine_lock) CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
1003 for (count = 0;count < MAX_PROCESS_CONNECTIONS;count ++)
1004 {
1005 switch (aep_app_conn_table[count].conn_state)
1006 {
1007 case Connected:
1008 rv = p_AEP_CloseConnection(aep_app_conn_table[count].conn_hndl);
1009 if (rv != AEP_R_OK)
1010 goto end;
1011 aep_app_conn_table[count].conn_state = NotConnected;
1012 aep_app_conn_table[count].conn_hndl = 0;
1013 break;
1014 case InUse:
1015 (*in_use)++;
1016 break;
1017 case NotConnected:
1018 break;
1019 }
1020 }
1021 end:
1022 if (use_engine_lock) CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
1023 return rv;
1024 }
1025
1026/*BigNum call back functions, used to convert OpenSSL bignums into AEP bignums.
1027 Note only 32bit Openssl build support*/
1028
1029static AEP_RV GetBigNumSize(AEP_VOID_PTR ArbBigNum, AEP_U32* BigNumSize)
1030 {
1031 BIGNUM* bn;
1032
1033 /*Cast the ArbBigNum pointer to our BIGNUM struct*/
1034 bn = (BIGNUM*) ArbBigNum;
1035
1036#ifdef SIXTY_FOUR_BIT_LONG
1037 *BigNumSize = bn->top << 3;
1038#else
1039 /*Size of the bignum in bytes is equal to the bn->top (no of 32 bit
1040 words) multiplies by 4*/
1041 *BigNumSize = bn->top << 2;
1042#endif
1043
1044 return AEP_R_OK;
1045 }
1046
1047static AEP_RV MakeAEPBigNum(AEP_VOID_PTR ArbBigNum, AEP_U32 BigNumSize,
1048 unsigned char* AEP_BigNum)
1049 {
1050 BIGNUM* bn;
1051
1052#ifndef SIXTY_FOUR_BIT_LONG
1053 unsigned char* buf;
1054 int i;
1055#endif
1056
1057 /*Cast the ArbBigNum pointer to our BIGNUM struct*/
1058 bn = (BIGNUM*) ArbBigNum;
1059
1060#ifdef SIXTY_FOUR_BIT_LONG
1061 memcpy(AEP_BigNum, bn->d, BigNumSize);
1062#else
1063 /*Must copy data into a (monotone) least significant byte first format
1064 performing endian conversion if necessary*/
1065 for(i=0;i<bn->top;i++)
1066 {
1067 buf = (unsigned char*)&bn->d[i];
1068
1069 *((AEP_U32*)AEP_BigNum) = (AEP_U32)
1070 ((unsigned) buf[1] << 8 | buf[0]) |
1071 ((unsigned) buf[3] << 8 | buf[2]) << 16;
1072
1073 AEP_BigNum += 4;
1074 }
1075#endif
1076
1077 return AEP_R_OK;
1078 }
1079
1080/*Turn an AEP Big Num back to a user big num*/
1081static AEP_RV ConvertAEPBigNum(void* ArbBigNum, AEP_U32 BigNumSize,
1082 unsigned char* AEP_BigNum)
1083 {
1084 BIGNUM* bn;
1085#ifndef SIXTY_FOUR_BIT_LONG
1086 int i;
1087#endif
1088
1089 bn = (BIGNUM*)ArbBigNum;
1090
1091 /*Expand the result bn so that it can hold our big num.
1092 Size is in bits*/
1093 bn_expand(bn, (int)(BigNumSize << 3));
1094
1095#ifdef SIXTY_FOUR_BIT_LONG
1096 bn->top = BigNumSize >> 3;
1097
1098 if((BigNumSize & 7) != 0)
1099 bn->top++;
1100
1101 memset(bn->d, 0, bn->top << 3);
1102
1103 memcpy(bn->d, AEP_BigNum, BigNumSize);
1104#else
1105 bn->top = BigNumSize >> 2;
1106
1107 for(i=0;i<bn->top;i++)
1108 {
1109 bn->d[i] = (AEP_U32)
1110 ((unsigned) AEP_BigNum[3] << 8 | AEP_BigNum[2]) << 16 |
1111 ((unsigned) AEP_BigNum[1] << 8 | AEP_BigNum[0]);
1112 AEP_BigNum += 4;
1113 }
1114#endif
1115
1116 return AEP_R_OK;
1117}
1118
1119#endif /* !OPENSSL_NO_HW_AEP */
1120#endif /* !OPENSSL_NO_HW */
diff --git a/src/lib/libcrypto/engine/hw_aep_err.c b/src/lib/libcrypto/engine/hw_aep_err.c
deleted file mode 100644
index 092f532946..0000000000
--- a/src/lib/libcrypto/engine/hw_aep_err.c
+++ /dev/null
@@ -1,157 +0,0 @@
1/* hw_aep_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 "hw_aep_err.h"
64
65/* BEGIN ERROR CODES */
66#ifndef OPENSSL_NO_ERR
67static ERR_STRING_DATA AEPHK_str_functs[]=
68 {
69{ERR_PACK(0,AEPHK_F_AEP_CTRL,0), "AEP_CTRL"},
70{ERR_PACK(0,AEPHK_F_AEP_FINISH,0), "AEP_FINISH"},
71{ERR_PACK(0,AEPHK_F_AEP_GET_CONNECTION,0), "AEP_GET_CONNECTION"},
72{ERR_PACK(0,AEPHK_F_AEP_INIT,0), "AEP_INIT"},
73{ERR_PACK(0,AEPHK_F_AEP_MOD_EXP,0), "AEP_MOD_EXP"},
74{ERR_PACK(0,AEPHK_F_AEP_MOD_EXP_CRT,0), "AEP_MOD_EXP_CRT"},
75{ERR_PACK(0,AEPHK_F_AEP_RAND,0), "AEP_RAND"},
76{ERR_PACK(0,AEPHK_F_AEP_RSA_MOD_EXP,0), "AEP_RSA_MOD_EXP"},
77{0,NULL}
78 };
79
80static ERR_STRING_DATA AEPHK_str_reasons[]=
81 {
82{AEPHK_R_ALREADY_LOADED ,"already loaded"},
83{AEPHK_R_CLOSE_HANDLES_FAILED ,"close handles failed"},
84{AEPHK_R_CONNECTIONS_IN_USE ,"connections in use"},
85{AEPHK_R_CTRL_COMMAND_NOT_IMPLEMENTED ,"ctrl command not implemented"},
86{AEPHK_R_FINALIZE_FAILED ,"finalize failed"},
87{AEPHK_R_GET_HANDLE_FAILED ,"get handle failed"},
88{AEPHK_R_GET_RANDOM_FAILED ,"get random failed"},
89{AEPHK_R_INIT_FAILURE ,"init failure"},
90{AEPHK_R_MISSING_KEY_COMPONENTS ,"missing key components"},
91{AEPHK_R_MOD_EXP_CRT_FAILED ,"mod exp crt failed"},
92{AEPHK_R_MOD_EXP_FAILED ,"mod exp failed"},
93{AEPHK_R_NOT_LOADED ,"not loaded"},
94{AEPHK_R_OK ,"ok"},
95{AEPHK_R_RETURN_CONNECTION_FAILED ,"return connection failed"},
96{AEPHK_R_SETBNCALLBACK_FAILURE ,"setbncallback failure"},
97{AEPHK_R_SIZE_TOO_LARGE_OR_TOO_SMALL ,"size too large or too small"},
98{AEPHK_R_UNIT_FAILURE ,"unit failure"},
99{0,NULL}
100 };
101
102#endif
103
104#ifdef AEPHK_LIB_NAME
105static ERR_STRING_DATA AEPHK_lib_name[]=
106 {
107{0 ,AEPHK_LIB_NAME},
108{0,NULL}
109 };
110#endif
111
112
113static int AEPHK_lib_error_code=0;
114static int AEPHK_error_init=1;
115
116static void ERR_load_AEPHK_strings(void)
117 {
118 if (AEPHK_lib_error_code == 0)
119 AEPHK_lib_error_code=ERR_get_next_error_library();
120
121 if (AEPHK_error_init)
122 {
123 AEPHK_error_init=0;
124#ifndef OPENSSL_NO_ERR
125 ERR_load_strings(AEPHK_lib_error_code,AEPHK_str_functs);
126 ERR_load_strings(AEPHK_lib_error_code,AEPHK_str_reasons);
127#endif
128
129#ifdef AEPHK_LIB_NAME
130 AEPHK_lib_name->error = ERR_PACK(AEPHK_lib_error_code,0,0);
131 ERR_load_strings(0,AEPHK_lib_name);
132#endif
133 }
134 }
135
136static void ERR_unload_AEPHK_strings(void)
137 {
138 if (AEPHK_error_init == 0)
139 {
140#ifndef OPENSSL_NO_ERR
141 ERR_unload_strings(AEPHK_lib_error_code,AEPHK_str_functs);
142 ERR_unload_strings(AEPHK_lib_error_code,AEPHK_str_reasons);
143#endif
144
145#ifdef AEPHK_LIB_NAME
146 ERR_unload_strings(0,AEPHK_lib_name);
147#endif
148 AEPHK_error_init=1;
149 }
150 }
151
152static void ERR_AEPHK_error(int function, int reason, char *file, int line)
153 {
154 if (AEPHK_lib_error_code == 0)
155 AEPHK_lib_error_code=ERR_get_next_error_library();
156 ERR_PUT_error(AEPHK_lib_error_code,function,reason,file,line);
157 }
diff --git a/src/lib/libcrypto/engine/hw_atalla.c b/src/lib/libcrypto/engine/hw_atalla.c
deleted file mode 100644
index 2b8342bbdd..0000000000
--- a/src/lib/libcrypto/engine/hw_atalla.c
+++ /dev/null
@@ -1,595 +0,0 @@
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-2001 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 <openssl/engine.h>
64
65#ifndef OPENSSL_NO_HW
66#ifndef OPENSSL_NO_HW_ATALLA
67
68#ifdef FLAT_INC
69#include "atalla.h"
70#else
71#include "vendor_defns/atalla.h"
72#endif
73
74#define ATALLA_LIB_NAME "atalla engine"
75#include "hw_atalla_err.c"
76
77static int atalla_destroy(ENGINE *e);
78static int atalla_init(ENGINE *e);
79static int atalla_finish(ENGINE *e);
80static int atalla_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)());
81
82/* BIGNUM stuff */
83static int atalla_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
84 const BIGNUM *m, BN_CTX *ctx);
85
86#ifndef OPENSSL_NO_RSA
87/* RSA stuff */
88static int atalla_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa);
89#endif
90/* This function is aliased to mod_exp (with the mont stuff dropped). */
91static int atalla_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
92 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
93
94#ifndef OPENSSL_NO_DSA
95/* DSA stuff */
96static int atalla_dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1,
97 BIGNUM *p1, BIGNUM *a2, BIGNUM *p2, BIGNUM *m,
98 BN_CTX *ctx, BN_MONT_CTX *in_mont);
99static int atalla_mod_exp_dsa(DSA *dsa, BIGNUM *r, BIGNUM *a,
100 const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
101 BN_MONT_CTX *m_ctx);
102#endif
103
104#ifndef OPENSSL_NO_DH
105/* DH stuff */
106/* This function is alised to mod_exp (with the DH and mont dropped). */
107static int atalla_mod_exp_dh(const DH *dh, BIGNUM *r,
108 const BIGNUM *a, const BIGNUM *p,
109 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
110#endif
111
112/* The definitions for control commands specific to this engine */
113#define ATALLA_CMD_SO_PATH ENGINE_CMD_BASE
114static const ENGINE_CMD_DEFN atalla_cmd_defns[] = {
115 {ATALLA_CMD_SO_PATH,
116 "SO_PATH",
117 "Specifies the path to the 'atasi' shared library",
118 ENGINE_CMD_FLAG_STRING},
119 {0, NULL, NULL, 0}
120 };
121
122#ifndef OPENSSL_NO_RSA
123/* Our internal RSA_METHOD that we provide pointers to */
124static RSA_METHOD atalla_rsa =
125 {
126 "Atalla RSA method",
127 NULL,
128 NULL,
129 NULL,
130 NULL,
131 atalla_rsa_mod_exp,
132 atalla_mod_exp_mont,
133 NULL,
134 NULL,
135 0,
136 NULL,
137 NULL,
138 NULL
139 };
140#endif
141
142#ifndef OPENSSL_NO_DSA
143/* Our internal DSA_METHOD that we provide pointers to */
144static DSA_METHOD atalla_dsa =
145 {
146 "Atalla DSA method",
147 NULL, /* dsa_do_sign */
148 NULL, /* dsa_sign_setup */
149 NULL, /* dsa_do_verify */
150 atalla_dsa_mod_exp, /* dsa_mod_exp */
151 atalla_mod_exp_dsa, /* bn_mod_exp */
152 NULL, /* init */
153 NULL, /* finish */
154 0, /* flags */
155 NULL /* app_data */
156 };
157#endif
158
159#ifndef OPENSSL_NO_DH
160/* Our internal DH_METHOD that we provide pointers to */
161static DH_METHOD atalla_dh =
162 {
163 "Atalla DH method",
164 NULL,
165 NULL,
166 atalla_mod_exp_dh,
167 NULL,
168 NULL,
169 0,
170 NULL
171 };
172#endif
173
174/* Constants used when creating the ENGINE */
175static const char *engine_atalla_id = "atalla";
176static const char *engine_atalla_name = "Atalla hardware engine support";
177
178/* This internal function is used by ENGINE_atalla() and possibly by the
179 * "dynamic" ENGINE support too */
180static int bind_helper(ENGINE *e)
181 {
182#ifndef OPENSSL_NO_RSA
183 const RSA_METHOD *meth1;
184#endif
185#ifndef OPENSSL_NO_DSA
186 const DSA_METHOD *meth2;
187#endif
188#ifndef OPENSSL_NO_DH
189 const DH_METHOD *meth3;
190#endif
191 if(!ENGINE_set_id(e, engine_atalla_id) ||
192 !ENGINE_set_name(e, engine_atalla_name) ||
193#ifndef OPENSSL_NO_RSA
194 !ENGINE_set_RSA(e, &atalla_rsa) ||
195#endif
196#ifndef OPENSSL_NO_DSA
197 !ENGINE_set_DSA(e, &atalla_dsa) ||
198#endif
199#ifndef OPENSSL_NO_DH
200 !ENGINE_set_DH(e, &atalla_dh) ||
201#endif
202 !ENGINE_set_destroy_function(e, atalla_destroy) ||
203 !ENGINE_set_init_function(e, atalla_init) ||
204 !ENGINE_set_finish_function(e, atalla_finish) ||
205 !ENGINE_set_ctrl_function(e, atalla_ctrl) ||
206 !ENGINE_set_cmd_defns(e, atalla_cmd_defns))
207 return 0;
208
209#ifndef OPENSSL_NO_RSA
210 /* We know that the "PKCS1_SSLeay()" functions hook properly
211 * to the atalla-specific mod_exp and mod_exp_crt so we use
212 * those functions. NB: We don't use ENGINE_openssl() or
213 * anything "more generic" because something like the RSAref
214 * code may not hook properly, and if you own one of these
215 * cards then you have the right to do RSA operations on it
216 * anyway! */
217 meth1 = RSA_PKCS1_SSLeay();
218 atalla_rsa.rsa_pub_enc = meth1->rsa_pub_enc;
219 atalla_rsa.rsa_pub_dec = meth1->rsa_pub_dec;
220 atalla_rsa.rsa_priv_enc = meth1->rsa_priv_enc;
221 atalla_rsa.rsa_priv_dec = meth1->rsa_priv_dec;
222#endif
223
224#ifndef OPENSSL_NO_DSA
225 /* Use the DSA_OpenSSL() method and just hook the mod_exp-ish
226 * bits. */
227 meth2 = DSA_OpenSSL();
228 atalla_dsa.dsa_do_sign = meth2->dsa_do_sign;
229 atalla_dsa.dsa_sign_setup = meth2->dsa_sign_setup;
230 atalla_dsa.dsa_do_verify = meth2->dsa_do_verify;
231#endif
232
233#ifndef OPENSSL_NO_DH
234 /* Much the same for Diffie-Hellman */
235 meth3 = DH_OpenSSL();
236 atalla_dh.generate_key = meth3->generate_key;
237 atalla_dh.compute_key = meth3->compute_key;
238#endif
239
240 /* Ensure the atalla error handling is set up */
241 ERR_load_ATALLA_strings();
242 return 1;
243 }
244
245#ifndef ENGINE_DYNAMIC_SUPPORT
246static ENGINE *engine_atalla(void)
247 {
248 ENGINE *ret = ENGINE_new();
249 if(!ret)
250 return NULL;
251 if(!bind_helper(ret))
252 {
253 ENGINE_free(ret);
254 return NULL;
255 }
256 return ret;
257 }
258
259void ENGINE_load_atalla(void)
260 {
261 /* Copied from eng_[openssl|dyn].c */
262 ENGINE *toadd = engine_atalla();
263 if(!toadd) return;
264 ENGINE_add(toadd);
265 ENGINE_free(toadd);
266 ERR_clear_error();
267 }
268#endif
269
270/* This is a process-global DSO handle used for loading and unloading
271 * the Atalla library. NB: This is only set (or unset) during an
272 * init() or finish() call (reference counts permitting) and they're
273 * operating with global locks, so this should be thread-safe
274 * implicitly. */
275static DSO *atalla_dso = NULL;
276
277/* These are the function pointers that are (un)set when the library has
278 * successfully (un)loaded. */
279static tfnASI_GetHardwareConfig *p_Atalla_GetHardwareConfig = NULL;
280static tfnASI_RSAPrivateKeyOpFn *p_Atalla_RSAPrivateKeyOpFn = NULL;
281static tfnASI_GetPerformanceStatistics *p_Atalla_GetPerformanceStatistics = NULL;
282
283/* These are the static string constants for the DSO file name and the function
284 * symbol names to bind to. Regrettably, the DSO name on *nix appears to be
285 * "atasi.so" rather than something more consistent like "libatasi.so". At the
286 * time of writing, I'm not sure what the file name on win32 is but clearly
287 * native name translation is not possible (eg libatasi.so on *nix, and
288 * atasi.dll on win32). For the purposes of testing, I have created a symbollic
289 * link called "libatasi.so" so that we can use native name-translation - a
290 * better solution will be needed. */
291static const char *ATALLA_LIBNAME = NULL;
292static const char *get_ATALLA_LIBNAME(void)
293 {
294 if(ATALLA_LIBNAME)
295 return ATALLA_LIBNAME;
296 return "atasi";
297 }
298static void free_ATALLA_LIBNAME(void)
299 {
300 if(ATALLA_LIBNAME)
301 OPENSSL_free((void*)ATALLA_LIBNAME);
302 ATALLA_LIBNAME = NULL;
303 }
304static long set_ATALLA_LIBNAME(const char *name)
305 {
306 free_ATALLA_LIBNAME();
307 return (((ATALLA_LIBNAME = BUF_strdup(name)) != NULL) ? 1 : 0);
308 }
309static const char *ATALLA_F1 = "ASI_GetHardwareConfig";
310static const char *ATALLA_F2 = "ASI_RSAPrivateKeyOpFn";
311static const char *ATALLA_F3 = "ASI_GetPerformanceStatistics";
312
313/* Destructor (complements the "ENGINE_atalla()" constructor) */
314static int atalla_destroy(ENGINE *e)
315 {
316 free_ATALLA_LIBNAME();
317 /* Unload the atalla error strings so any error state including our
318 * functs or reasons won't lead to a segfault (they simply get displayed
319 * without corresponding string data because none will be found). */
320 ERR_unload_ATALLA_strings();
321 return 1;
322 }
323
324/* (de)initialisation functions. */
325static int atalla_init(ENGINE *e)
326 {
327 tfnASI_GetHardwareConfig *p1;
328 tfnASI_RSAPrivateKeyOpFn *p2;
329 tfnASI_GetPerformanceStatistics *p3;
330 /* Not sure of the origin of this magic value, but Ben's code had it
331 * and it seemed to have been working for a few people. :-) */
332 unsigned int config_buf[1024];
333
334 if(atalla_dso != NULL)
335 {
336 ATALLAerr(ATALLA_F_ATALLA_INIT,ATALLA_R_ALREADY_LOADED);
337 goto err;
338 }
339 /* Attempt to load libatasi.so/atasi.dll/whatever. Needs to be
340 * changed unfortunately because the Atalla drivers don't have
341 * standard library names that can be platform-translated well. */
342 /* TODO: Work out how to actually map to the names the Atalla
343 * drivers really use - for now a symbollic link needs to be
344 * created on the host system from libatasi.so to atasi.so on
345 * unix variants. */
346 atalla_dso = DSO_load(NULL, get_ATALLA_LIBNAME(), NULL, 0);
347 if(atalla_dso == NULL)
348 {
349 ATALLAerr(ATALLA_F_ATALLA_INIT,ATALLA_R_NOT_LOADED);
350 goto err;
351 }
352 if(!(p1 = (tfnASI_GetHardwareConfig *)DSO_bind_func(
353 atalla_dso, ATALLA_F1)) ||
354 !(p2 = (tfnASI_RSAPrivateKeyOpFn *)DSO_bind_func(
355 atalla_dso, ATALLA_F2)) ||
356 !(p3 = (tfnASI_GetPerformanceStatistics *)DSO_bind_func(
357 atalla_dso, ATALLA_F3)))
358 {
359 ATALLAerr(ATALLA_F_ATALLA_INIT,ATALLA_R_NOT_LOADED);
360 goto err;
361 }
362 /* Copy the pointers */
363 p_Atalla_GetHardwareConfig = p1;
364 p_Atalla_RSAPrivateKeyOpFn = p2;
365 p_Atalla_GetPerformanceStatistics = p3;
366 /* Perform a basic test to see if there's actually any unit
367 * running. */
368 if(p1(0L, config_buf) != 0)
369 {
370 ATALLAerr(ATALLA_F_ATALLA_INIT,ATALLA_R_UNIT_FAILURE);
371 goto err;
372 }
373 /* Everything's fine. */
374 return 1;
375err:
376 if(atalla_dso)
377 DSO_free(atalla_dso);
378 atalla_dso = NULL;
379 p_Atalla_GetHardwareConfig = NULL;
380 p_Atalla_RSAPrivateKeyOpFn = NULL;
381 p_Atalla_GetPerformanceStatistics = NULL;
382 return 0;
383 }
384
385static int atalla_finish(ENGINE *e)
386 {
387 free_ATALLA_LIBNAME();
388 if(atalla_dso == NULL)
389 {
390 ATALLAerr(ATALLA_F_ATALLA_FINISH,ATALLA_R_NOT_LOADED);
391 return 0;
392 }
393 if(!DSO_free(atalla_dso))
394 {
395 ATALLAerr(ATALLA_F_ATALLA_FINISH,ATALLA_R_UNIT_FAILURE);
396 return 0;
397 }
398 atalla_dso = NULL;
399 p_Atalla_GetHardwareConfig = NULL;
400 p_Atalla_RSAPrivateKeyOpFn = NULL;
401 p_Atalla_GetPerformanceStatistics = NULL;
402 return 1;
403 }
404
405static int atalla_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)())
406 {
407 int initialised = ((atalla_dso == NULL) ? 0 : 1);
408 switch(cmd)
409 {
410 case ATALLA_CMD_SO_PATH:
411 if(p == NULL)
412 {
413 ATALLAerr(ATALLA_F_ATALLA_CTRL,ERR_R_PASSED_NULL_PARAMETER);
414 return 0;
415 }
416 if(initialised)
417 {
418 ATALLAerr(ATALLA_F_ATALLA_CTRL,ATALLA_R_ALREADY_LOADED);
419 return 0;
420 }
421 return set_ATALLA_LIBNAME((const char *)p);
422 default:
423 break;
424 }
425 ATALLAerr(ATALLA_F_ATALLA_CTRL,ATALLA_R_CTRL_COMMAND_NOT_IMPLEMENTED);
426 return 0;
427 }
428
429static int atalla_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
430 const BIGNUM *m, BN_CTX *ctx)
431 {
432 /* I need somewhere to store temporary serialised values for
433 * use with the Atalla API calls. A neat cheat - I'll use
434 * BIGNUMs from the BN_CTX but access their arrays directly as
435 * byte arrays <grin>. This way I don't have to clean anything
436 * up. */
437 BIGNUM *modulus;
438 BIGNUM *exponent;
439 BIGNUM *argument;
440 BIGNUM *result;
441 RSAPrivateKey keydata;
442 int to_return, numbytes;
443
444 modulus = exponent = argument = result = NULL;
445 to_return = 0; /* expect failure */
446
447 if(!atalla_dso)
448 {
449 ATALLAerr(ATALLA_F_ATALLA_MOD_EXP,ATALLA_R_NOT_LOADED);
450 goto err;
451 }
452 /* Prepare the params */
453 BN_CTX_start(ctx);
454 modulus = BN_CTX_get(ctx);
455 exponent = BN_CTX_get(ctx);
456 argument = BN_CTX_get(ctx);
457 result = BN_CTX_get(ctx);
458 if (!result)
459 {
460 ATALLAerr(ATALLA_F_ATALLA_MOD_EXP,ATALLA_R_BN_CTX_FULL);
461 goto err;
462 }
463 if(!bn_wexpand(modulus, m->top) || !bn_wexpand(exponent, m->top) ||
464 !bn_wexpand(argument, m->top) || !bn_wexpand(result, m->top))
465 {
466 ATALLAerr(ATALLA_F_ATALLA_MOD_EXP,ATALLA_R_BN_EXPAND_FAIL);
467 goto err;
468 }
469 /* Prepare the key-data */
470 memset(&keydata, 0,sizeof keydata);
471 numbytes = BN_num_bytes(m);
472 memset(exponent->d, 0, numbytes);
473 memset(modulus->d, 0, numbytes);
474 BN_bn2bin(p, (unsigned char *)exponent->d + numbytes - BN_num_bytes(p));
475 BN_bn2bin(m, (unsigned char *)modulus->d + numbytes - BN_num_bytes(m));
476 keydata.privateExponent.data = (unsigned char *)exponent->d;
477 keydata.privateExponent.len = numbytes;
478 keydata.modulus.data = (unsigned char *)modulus->d;
479 keydata.modulus.len = numbytes;
480 /* Prepare the argument */
481 memset(argument->d, 0, numbytes);
482 memset(result->d, 0, numbytes);
483 BN_bn2bin(a, (unsigned char *)argument->d + numbytes - BN_num_bytes(a));
484 /* Perform the operation */
485 if(p_Atalla_RSAPrivateKeyOpFn(&keydata, (unsigned char *)result->d,
486 (unsigned char *)argument->d,
487 keydata.modulus.len) != 0)
488 {
489 ATALLAerr(ATALLA_F_ATALLA_MOD_EXP,ATALLA_R_REQUEST_FAILED);
490 goto err;
491 }
492 /* Convert the response */
493 BN_bin2bn((unsigned char *)result->d, numbytes, r);
494 to_return = 1;
495err:
496 BN_CTX_end(ctx);
497 return to_return;
498 }
499
500#ifndef OPENSSL_NO_RSA
501static int atalla_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa)
502 {
503 BN_CTX *ctx = NULL;
504 int to_return = 0;
505
506 if(!atalla_dso)
507 {
508 ATALLAerr(ATALLA_F_ATALLA_RSA_MOD_EXP,ATALLA_R_NOT_LOADED);
509 goto err;
510 }
511 if((ctx = BN_CTX_new()) == NULL)
512 goto err;
513 if(!rsa->d || !rsa->n)
514 {
515 ATALLAerr(ATALLA_F_ATALLA_RSA_MOD_EXP,ATALLA_R_MISSING_KEY_COMPONENTS);
516 goto err;
517 }
518 to_return = atalla_mod_exp(r0, I, rsa->d, rsa->n, ctx);
519err:
520 if(ctx)
521 BN_CTX_free(ctx);
522 return to_return;
523 }
524#endif
525
526#ifndef OPENSSL_NO_DSA
527/* This code was liberated and adapted from the commented-out code in
528 * dsa_ossl.c. Because of the unoptimised form of the Atalla acceleration
529 * (it doesn't have a CRT form for RSA), this function means that an
530 * Atalla system running with a DSA server certificate can handshake
531 * around 5 or 6 times faster/more than an equivalent system running with
532 * RSA. Just check out the "signs" statistics from the RSA and DSA parts
533 * of "openssl speed -engine atalla dsa1024 rsa1024". */
534static int atalla_dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1,
535 BIGNUM *p1, BIGNUM *a2, BIGNUM *p2, BIGNUM *m,
536 BN_CTX *ctx, BN_MONT_CTX *in_mont)
537 {
538 BIGNUM t;
539 int to_return = 0;
540
541 BN_init(&t);
542 /* let rr = a1 ^ p1 mod m */
543 if (!atalla_mod_exp(rr,a1,p1,m,ctx)) goto end;
544 /* let t = a2 ^ p2 mod m */
545 if (!atalla_mod_exp(&t,a2,p2,m,ctx)) goto end;
546 /* let rr = rr * t mod m */
547 if (!BN_mod_mul(rr,rr,&t,m,ctx)) goto end;
548 to_return = 1;
549end:
550 BN_free(&t);
551 return to_return;
552 }
553
554static int atalla_mod_exp_dsa(DSA *dsa, BIGNUM *r, BIGNUM *a,
555 const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
556 BN_MONT_CTX *m_ctx)
557 {
558 return atalla_mod_exp(r, a, p, m, ctx);
559 }
560#endif
561
562/* This function is aliased to mod_exp (with the mont stuff dropped). */
563static int atalla_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
564 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
565 {
566 return atalla_mod_exp(r, a, p, m, ctx);
567 }
568
569#ifndef OPENSSL_NO_DH
570/* This function is aliased to mod_exp (with the dh and mont dropped). */
571static int atalla_mod_exp_dh(const DH *dh, BIGNUM *r,
572 const BIGNUM *a, const BIGNUM *p,
573 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
574 {
575 return atalla_mod_exp(r, a, p, m, ctx);
576 }
577#endif
578
579/* This stuff is needed if this ENGINE is being compiled into a self-contained
580 * shared-library. */
581#ifdef ENGINE_DYNAMIC_SUPPORT
582static int bind_fn(ENGINE *e, const char *id)
583 {
584 if(id && (strcmp(id, engine_atalla_id) != 0))
585 return 0;
586 if(!bind_helper(e))
587 return 0;
588 return 1;
589 }
590IMPLEMENT_DYNAMIC_CHECK_FN()
591IMPLEMENT_DYNAMIC_BIND_FN(bind_fn)
592#endif /* ENGINE_DYNAMIC_SUPPORT */
593
594#endif /* !OPENSSL_NO_HW_ATALLA */
595#endif /* !OPENSSL_NO_HW */
diff --git a/src/lib/libcrypto/engine/hw_atalla_err.c b/src/lib/libcrypto/engine/hw_atalla_err.c
deleted file mode 100644
index 1df9c4570c..0000000000
--- a/src/lib/libcrypto/engine/hw_atalla_err.c
+++ /dev/null
@@ -1,145 +0,0 @@
1/* hw_atalla_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 "hw_atalla_err.h"
64
65/* BEGIN ERROR CODES */
66#ifndef OPENSSL_NO_ERR
67static ERR_STRING_DATA ATALLA_str_functs[]=
68 {
69{ERR_PACK(0,ATALLA_F_ATALLA_CTRL,0), "ATALLA_CTRL"},
70{ERR_PACK(0,ATALLA_F_ATALLA_FINISH,0), "ATALLA_FINISH"},
71{ERR_PACK(0,ATALLA_F_ATALLA_INIT,0), "ATALLA_INIT"},
72{ERR_PACK(0,ATALLA_F_ATALLA_MOD_EXP,0), "ATALLA_MOD_EXP"},
73{ERR_PACK(0,ATALLA_F_ATALLA_RSA_MOD_EXP,0), "ATALLA_RSA_MOD_EXP"},
74{0,NULL}
75 };
76
77static ERR_STRING_DATA ATALLA_str_reasons[]=
78 {
79{ATALLA_R_ALREADY_LOADED ,"already loaded"},
80{ATALLA_R_BN_CTX_FULL ,"bn ctx full"},
81{ATALLA_R_BN_EXPAND_FAIL ,"bn expand fail"},
82{ATALLA_R_CTRL_COMMAND_NOT_IMPLEMENTED ,"ctrl command not implemented"},
83{ATALLA_R_MISSING_KEY_COMPONENTS ,"missing key components"},
84{ATALLA_R_NOT_LOADED ,"not loaded"},
85{ATALLA_R_REQUEST_FAILED ,"request failed"},
86{ATALLA_R_UNIT_FAILURE ,"unit failure"},
87{0,NULL}
88 };
89
90#endif
91
92#ifdef ATALLA_LIB_NAME
93static ERR_STRING_DATA ATALLA_lib_name[]=
94 {
95{0 ,ATALLA_LIB_NAME},
96{0,NULL}
97 };
98#endif
99
100
101static int ATALLA_lib_error_code=0;
102static int ATALLA_error_init=1;
103
104static void ERR_load_ATALLA_strings(void)
105 {
106 if (ATALLA_lib_error_code == 0)
107 ATALLA_lib_error_code=ERR_get_next_error_library();
108
109 if (ATALLA_error_init)
110 {
111 ATALLA_error_init=0;
112#ifndef OPENSSL_NO_ERR
113 ERR_load_strings(ATALLA_lib_error_code,ATALLA_str_functs);
114 ERR_load_strings(ATALLA_lib_error_code,ATALLA_str_reasons);
115#endif
116
117#ifdef ATALLA_LIB_NAME
118 ATALLA_lib_name->error = ERR_PACK(ATALLA_lib_error_code,0,0);
119 ERR_load_strings(0,ATALLA_lib_name);
120#endif
121 }
122 }
123
124static void ERR_unload_ATALLA_strings(void)
125 {
126 if (ATALLA_error_init == 0)
127 {
128#ifndef OPENSSL_NO_ERR
129 ERR_unload_strings(ATALLA_lib_error_code,ATALLA_str_functs);
130 ERR_unload_strings(ATALLA_lib_error_code,ATALLA_str_reasons);
131#endif
132
133#ifdef ATALLA_LIB_NAME
134 ERR_unload_strings(0,ATALLA_lib_name);
135#endif
136 ATALLA_error_init=1;
137 }
138 }
139
140static void ERR_ATALLA_error(int function, int reason, char *file, int line)
141 {
142 if (ATALLA_lib_error_code == 0)
143 ATALLA_lib_error_code=ERR_get_next_error_library();
144 ERR_PUT_error(ATALLA_lib_error_code,function,reason,file,line);
145 }
diff --git a/src/lib/libcrypto/engine/hw_cryptodev.c b/src/lib/libcrypto/engine/hw_cryptodev.c
index 3e7fff1c1e..0e80ca051a 100644
--- a/src/lib/libcrypto/engine/hw_cryptodev.c
+++ b/src/lib/libcrypto/engine/hw_cryptodev.c
@@ -1,6 +1,6 @@
1/* 1/*
2 * Copyright (c) 2002-2004 Theo de Raadt
2 * Copyright (c) 2002 Bob Beck <beck@openbsd.org> 3 * Copyright (c) 2002 Bob Beck <beck@openbsd.org>
3 * Copyright (c) 2002 Theo de Raadt
4 * Copyright (c) 2002 Markus Friedl 4 * Copyright (c) 2002 Markus Friedl
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
@@ -49,39 +49,57 @@ ENGINE_load_cryptodev(void)
49 return; 49 return;
50} 50}
51 51
52#else 52#else
53 53
54#include <sys/types.h> 54#include <sys/types.h>
55#include <crypto/cryptodev.h> 55#include <crypto/cryptodev.h>
56#include <sys/ioctl.h> 56#include <sys/ioctl.h>
57
57#include <errno.h> 58#include <errno.h>
58#include <stdio.h>
59#include <unistd.h>
60#include <fcntl.h> 59#include <fcntl.h>
60#include <limits.h>
61#include <stdarg.h> 61#include <stdarg.h>
62#include <syslog.h> 62#include <stdio.h>
63#include <errno.h>
64#include <string.h> 63#include <string.h>
64#include <syslog.h>
65#include <unistd.h>
66
67#if defined(__i386__) || defined(__amd64__)
68#include <sys/sysctl.h>
69#include <machine/cpu.h>
70#include <machine/specialreg.h>
71
72#include <ssl/aes.h>
73
74static int check_viac3aes(void);
75#endif
76
77#define CRYPTO_VIAC3_MAX 3
65 78
66struct dev_crypto_state { 79struct dev_crypto_state {
67 struct session_op d_sess; 80 struct session_op d_sess;
68 int d_fd; 81 int d_fd;
69}; 82};
70 83
84struct dev_crypto_cipher {
85 int c_id;
86 int c_nid;
87 int c_ivmax;
88 int c_keylen;
89};
90
71static u_int32_t cryptodev_asymfeat = 0; 91static u_int32_t cryptodev_asymfeat = 0;
72 92
73static int get_asym_dev_crypto(void); 93static int get_asym_dev_crypto(void);
74static int open_dev_crypto(void); 94static int open_dev_crypto(void);
75static int get_dev_crypto(void); 95static int get_dev_crypto(void);
76static int cryptodev_max_iv(int cipher); 96static struct dev_crypto_cipher *cipher_nid_to_cryptodev(int nid);
77static int cryptodev_key_length_valid(int cipher, int len);
78static int cipher_nid_to_cryptodev(int nid);
79static int get_cryptodev_ciphers(const int **cnids); 97static int get_cryptodev_ciphers(const int **cnids);
80/*static int get_cryptodev_digests(const int **cnids);*/ 98/*static int get_cryptodev_digests(const int **cnids);*/
81static int cryptodev_usable_ciphers(const int **nids); 99static int cryptodev_usable_ciphers(const int **nids);
82static int cryptodev_usable_digests(const int **nids); 100static int cryptodev_usable_digests(const int **nids);
83static int cryptodev_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, 101static int cryptodev_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
84 const unsigned char *in, unsigned int inl); 102 const unsigned char *in, size_t inl);
85static int cryptodev_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, 103static int cryptodev_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
86 const unsigned char *iv, int enc); 104 const unsigned char *iv, int enc);
87static int cryptodev_cleanup(EVP_CIPHER_CTX *ctx); 105static int cryptodev_cleanup(EVP_CIPHER_CTX *ctx);
@@ -98,8 +116,9 @@ static int cryptodev_asym(struct crypt_kop *kop, int rlen, BIGNUM *r,
98static int cryptodev_bn_mod_exp(BIGNUM *r, const BIGNUM *a, 116static int cryptodev_bn_mod_exp(BIGNUM *r, const BIGNUM *a,
99 const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); 117 const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
100static int cryptodev_rsa_nocrt_mod_exp(BIGNUM *r0, const BIGNUM *I, 118static int cryptodev_rsa_nocrt_mod_exp(BIGNUM *r0, const BIGNUM *I,
101 RSA *rsa); 119 RSA *rsa, BN_CTX *ctx);
102static int cryptodev_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa); 120static int cryptodev_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa,
121 BN_CTX *ctx);
103static int cryptodev_dsa_bn_mod_exp(DSA *dsa, BIGNUM *r, BIGNUM *a, 122static int cryptodev_dsa_bn_mod_exp(DSA *dsa, BIGNUM *r, BIGNUM *a,
104 const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); 123 const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
105static int cryptodev_dsa_dsa_mod_exp(DSA *dsa, BIGNUM *t1, BIGNUM *g, 124static int cryptodev_dsa_dsa_mod_exp(DSA *dsa, BIGNUM *t1, BIGNUM *g,
@@ -122,18 +141,14 @@ static const ENGINE_CMD_DEFN cryptodev_defns[] = {
122 { 0, NULL, NULL, 0 } 141 { 0, NULL, NULL, 0 }
123}; 142};
124 143
125static struct { 144static struct dev_crypto_cipher ciphers[] = {
126 int id;
127 int nid;
128 int ivmax;
129 int keylen;
130} ciphers[] = {
131 { CRYPTO_DES_CBC, NID_des_cbc, 8, 8, }, 145 { CRYPTO_DES_CBC, NID_des_cbc, 8, 8, },
132 { CRYPTO_3DES_CBC, NID_des_ede3_cbc, 8, 24, }, 146 { CRYPTO_3DES_CBC, NID_des_ede3_cbc, 8, 24, },
133 { CRYPTO_AES_CBC, NID_aes_128_cbc, 16, 16, }, 147 { CRYPTO_AES_CBC, NID_aes_128_cbc, 16, 16, },
148 { CRYPTO_AES_CBC, NID_aes_192_cbc, 16, 24, },
149 { CRYPTO_AES_CBC, NID_aes_256_cbc, 16, 32, },
134 { CRYPTO_BLF_CBC, NID_bf_cbc, 8, 16, }, 150 { CRYPTO_BLF_CBC, NID_bf_cbc, 8, 16, },
135 { CRYPTO_CAST_CBC, NID_cast5_cbc, 8, 16, }, 151 { CRYPTO_CAST_CBC, NID_cast5_cbc, 8, 16, },
136 { CRYPTO_SKIPJACK_CBC, NID_undef, 0, 0, },
137 { 0, NID_undef, 0, 0, }, 152 { 0, NID_undef, 0, 0, },
138}; 153};
139 154
@@ -153,7 +168,7 @@ static struct {
153#endif 168#endif
154 169
155/* 170/*
156 * Return a fd if /dev/crypto seems usable, 0 otherwise. 171 * Return a fd if /dev/crypto seems usable, -1 otherwise.
157 */ 172 */
158static int 173static int
159open_dev_crypto(void) 174open_dev_crypto(void)
@@ -180,8 +195,10 @@ get_dev_crypto(void)
180 195
181 if ((fd = open_dev_crypto()) == -1) 196 if ((fd = open_dev_crypto()) == -1)
182 return (-1); 197 return (-1);
183 if (ioctl(fd, CRIOGET, &retfd) == -1) 198 if (ioctl(fd, CRIOGET, &retfd) == -1) {
199 close(fd);
184 return (-1); 200 return (-1);
201 }
185 202
186 /* close on exec */ 203 /* close on exec */
187 if (fcntl(retfd, F_SETFD, 1) == -1) { 204 if (fcntl(retfd, F_SETFD, 1) == -1) {
@@ -202,48 +219,16 @@ get_asym_dev_crypto(void)
202 return fd; 219 return fd;
203} 220}
204 221
205/*
206 * XXXX this needs to be set for each alg - and determined from
207 * a running card.
208 */
209static int
210cryptodev_max_iv(int cipher)
211{
212 int i;
213
214 for (i = 0; ciphers[i].id; i++)
215 if (ciphers[i].id == cipher)
216 return (ciphers[i].ivmax);
217 return (0);
218}
219
220/*
221 * XXXX this needs to be set for each alg - and determined from
222 * a running card. For now, fake it out - but most of these
223 * for real devices should return 1 for the supported key
224 * sizes the device can handle.
225 */
226static int
227cryptodev_key_length_valid(int cipher, int len)
228{
229 int i;
230
231 for (i = 0; ciphers[i].id; i++)
232 if (ciphers[i].id == cipher)
233 return (ciphers[i].keylen == len);
234 return (0);
235}
236
237/* convert libcrypto nids to cryptodev */ 222/* convert libcrypto nids to cryptodev */
238static int 223static struct dev_crypto_cipher *
239cipher_nid_to_cryptodev(int nid) 224cipher_nid_to_cryptodev(int nid)
240{ 225{
241 int i; 226 int i;
242 227
243 for (i = 0; ciphers[i].id; i++) 228 for (i = 0; ciphers[i].c_id; i++)
244 if (ciphers[i].nid == nid) 229 if (ciphers[i].c_nid == nid)
245 return (ciphers[i].id); 230 return (&ciphers[i]);
246 return (0); 231 return (NULL);
247} 232}
248 233
249/* 234/*
@@ -255,7 +240,7 @@ cipher_nid_to_cryptodev(int nid)
255static int 240static int
256get_cryptodev_ciphers(const int **cnids) 241get_cryptodev_ciphers(const int **cnids)
257{ 242{
258 static int nids[CRYPTO_ALGORITHM_MAX]; 243 static int nids[CRYPTO_ALGORITHM_MAX + CRYPTO_VIAC3_MAX + 1];
259 struct session_op sess; 244 struct session_op sess;
260 int fd, i, count = 0; 245 int fd, i, count = 0;
261 246
@@ -266,18 +251,45 @@ get_cryptodev_ciphers(const int **cnids)
266 memset(&sess, 0, sizeof(sess)); 251 memset(&sess, 0, sizeof(sess));
267 sess.key = (caddr_t)"123456781234567812345678"; 252 sess.key = (caddr_t)"123456781234567812345678";
268 253
269 for (i = 0; ciphers[i].id && count < CRYPTO_ALGORITHM_MAX; i++) { 254 for (i = 0; ciphers[i].c_id && count <= CRYPTO_ALGORITHM_MAX; i++) {
270 if (ciphers[i].nid == NID_undef) 255 if (ciphers[i].c_nid == NID_undef)
271 continue; 256 continue;
272 sess.cipher = ciphers[i].id; 257 sess.cipher = ciphers[i].c_id;
273 sess.keylen = ciphers[i].keylen; 258 sess.keylen = ciphers[i].c_keylen;
274 sess.mac = 0; 259 sess.mac = 0;
275 if (ioctl(fd, CIOCGSESSION, &sess) != -1 && 260 if (ioctl(fd, CIOCGSESSION, &sess) != -1 &&
276 ioctl(fd, CIOCFSESSION, &sess.ses) != -1) 261 ioctl(fd, CIOCFSESSION, &sess.ses) != -1)
277 nids[count++] = ciphers[i].nid; 262 nids[count++] = ciphers[i].c_nid;
278 } 263 }
279 close(fd); 264 close(fd);
280 265
266#if defined(__i386__) || defined(__amd64__)
267 /*
268 * Always check for the VIA C3 AES instructions;
269 * even if /dev/crypto is disabled.
270 */
271 if (check_viac3aes() >= 1) {
272 int have_NID_aes_128_cbc = 0;
273 int have_NID_aes_192_cbc = 0;
274 int have_NID_aes_256_cbc = 0;
275
276 for (i = 0; i < count; i++) {
277 if (nids[i] == NID_aes_128_cbc)
278 have_NID_aes_128_cbc = 1;
279 if (nids[i] == NID_aes_192_cbc)
280 have_NID_aes_192_cbc = 1;
281 if (nids[i] == NID_aes_256_cbc)
282 have_NID_aes_256_cbc = 1;
283 }
284 if (!have_NID_aes_128_cbc)
285 nids[count++] = NID_aes_128_cbc;
286 if (!have_NID_aes_192_cbc)
287 nids[count++] = NID_aes_192_cbc;
288 if (!have_NID_aes_256_cbc)
289 nids[count++] = NID_aes_256_cbc;
290 }
291#endif
292
281 if (count > 0) 293 if (count > 0)
282 *cnids = nids; 294 *cnids = nids;
283 else 295 else
@@ -371,7 +383,7 @@ cryptodev_usable_digests(const int **nids)
371 383
372static int 384static int
373cryptodev_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, 385cryptodev_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
374 const unsigned char *in, unsigned int inl) 386 const unsigned char *in, size_t inl)
375{ 387{
376 struct crypt_op cryp; 388 struct crypt_op cryp;
377 struct dev_crypto_state *state = ctx->cipher_data; 389 struct dev_crypto_state *state = ctx->cipher_data;
@@ -429,15 +441,15 @@ cryptodev_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
429{ 441{
430 struct dev_crypto_state *state = ctx->cipher_data; 442 struct dev_crypto_state *state = ctx->cipher_data;
431 struct session_op *sess = &state->d_sess; 443 struct session_op *sess = &state->d_sess;
432 int cipher; 444 struct dev_crypto_cipher *cipher;
433 445
434 if ((cipher = cipher_nid_to_cryptodev(ctx->cipher->nid)) == NID_undef) 446 if ((cipher = cipher_nid_to_cryptodev(ctx->cipher->nid)) == NULL)
435 return (0); 447 return (0);
436 448
437 if (ctx->cipher->iv_len > cryptodev_max_iv(cipher)) 449 if (ctx->cipher->iv_len > cipher->c_ivmax)
438 return (0); 450 return (0);
439 451
440 if (!cryptodev_key_length_valid(cipher, ctx->key_len)) 452 if (ctx->key_len != cipher->c_keylen)
441 return (0); 453 return (0);
442 454
443 memset(sess, 0, sizeof(struct session_op)); 455 memset(sess, 0, sizeof(struct session_op));
@@ -447,7 +459,7 @@ cryptodev_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
447 459
448 sess->key = (unsigned char *)key; 460 sess->key = (unsigned char *)key;
449 sess->keylen = ctx->key_len; 461 sess->keylen = ctx->key_len;
450 sess->cipher = cipher; 462 sess->cipher = cipher->c_id;
451 463
452 if (ioctl(state->d_fd, CIOCGSESSION, sess) == -1) { 464 if (ioctl(state->d_fd, CIOCGSESSION, sess) == -1) {
453 close(state->d_fd); 465 close(state->d_fd);
@@ -552,7 +564,7 @@ const EVP_CIPHER cryptodev_cast_cbc = {
552 NULL 564 NULL
553}; 565};
554 566
555const EVP_CIPHER cryptodev_aes_cbc = { 567EVP_CIPHER cryptodev_aes_128_cbc = {
556 NID_aes_128_cbc, 568 NID_aes_128_cbc,
557 16, 16, 16, 569 16, 16, 16,
558 EVP_CIPH_CBC_MODE, 570 EVP_CIPH_CBC_MODE,
@@ -565,6 +577,225 @@ const EVP_CIPHER cryptodev_aes_cbc = {
565 NULL 577 NULL
566}; 578};
567 579
580EVP_CIPHER cryptodev_aes_192_cbc = {
581 NID_aes_192_cbc,
582 16, 24, 16,
583 EVP_CIPH_CBC_MODE,
584 cryptodev_init_key,
585 cryptodev_cipher,
586 cryptodev_cleanup,
587 sizeof(struct dev_crypto_state),
588 EVP_CIPHER_set_asn1_iv,
589 EVP_CIPHER_get_asn1_iv,
590 NULL
591};
592
593EVP_CIPHER cryptodev_aes_256_cbc = {
594 NID_aes_256_cbc,
595 16, 32, 16,
596 EVP_CIPH_CBC_MODE,
597 cryptodev_init_key,
598 cryptodev_cipher,
599 cryptodev_cleanup,
600 sizeof(struct dev_crypto_state),
601 EVP_CIPHER_set_asn1_iv,
602 EVP_CIPHER_get_asn1_iv,
603 NULL
604};
605
606#if defined(__i386__) || defined(__amd64__)
607
608static inline void
609viac3_xcrypt_cbc(int *cw, const void *src, void *dst, void *key, int rep,
610 void *iv)
611{
612#ifdef notdef
613 printf("cw %p[%x %x %x %x] src %p dst %p key %p rep %x iv %p\n",
614 cw, cw[0], cw[1], cw[2], cw[3],
615 src, dst, key, rep, iv);
616#endif
617#if defined(__i386__)
618
619 /*
620 * Clear bit 30 of EFLAGS.
621 */
622 __asm __volatile("pushfl; popfl");
623
624 /*
625 * Cannot simply place key into "b" register, since the compiler
626 * -pic mode uses that register; so instead we must dance a little.
627 */
628 __asm __volatile("pushl %%ebx; movl %0, %%ebx; rep xcrypt-cbc; popl %%ebx" :
629 : "m" (key), "a" (iv), "c" (rep), "d" (cw), "S" (src), "D" (dst)
630 : "memory", "cc");
631#else
632
633 /*
634 * Clear bit 30 of EFLAGS.
635 */
636 __asm __volatile("pushfq; popfq");
637 __asm __volatile("rep xcrypt-cbc" :
638 : "b" (key), "a" (iv), "c" (rep), "d" (cw), "S" (src), "D" (dst)
639 : "memory", "cc");
640#endif
641
642}
643
644#define ISUNALIGNED(x) ((long)(x)) & 15
645#define DOALIGN(v) ((void *)(((long)(v) + 15) & ~15))
646
647static int
648xcrypt_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
649 const unsigned char *in, size_t inl)
650{
651 unsigned char *save_iv_store[EVP_MAX_IV_LENGTH + 15];
652 unsigned char *save_iv = DOALIGN(save_iv_store);
653 unsigned char *ivs_store[EVP_MAX_IV_LENGTH + 15];
654 unsigned char *ivs = DOALIGN(ivs_store);
655 void *iiv, *iv = NULL, *ivp = NULL;
656 const void *usein = in;
657 void *useout = out, *spare;
658 int cws[4 + 3], *cw = DOALIGN(cws);
659
660 if (!inl)
661 return (1);
662 if ((inl % ctx->cipher->block_size) != 0)
663 return (0);
664 if (inl > UINT_MAX)
665 return (0);
666
667 if (ISUNALIGNED(in) || ISUNALIGNED(out)) {
668 spare = malloc(inl);
669 if (spare == NULL)
670 return (0);
671
672 if (ISUNALIGNED(in)) {
673 bcopy(in, spare, inl);
674 usein = spare;
675 }
676 if (ISUNALIGNED(out))
677 useout = spare;
678 }
679
680 cw[0] = C3_CRYPT_CWLO_ALG_AES | C3_CRYPT_CWLO_KEYGEN_SW |
681 C3_CRYPT_CWLO_NORMAL;
682 cw[0] |= ctx->encrypt ? C3_CRYPT_CWLO_ENCRYPT : C3_CRYPT_CWLO_DECRYPT;
683 cw[1] = cw[2] = cw[3] = 0;
684
685 switch (ctx->key_len * 8) {
686 case 128:
687 cw[0] |= C3_CRYPT_CWLO_KEY128;
688 break;
689 case 192:
690 cw[0] |= C3_CRYPT_CWLO_KEY192;
691 break;
692 case 256:
693 cw[0] |= C3_CRYPT_CWLO_KEY256;
694 break;
695 }
696
697 if (ctx->cipher->iv_len) {
698 iv = (caddr_t) ctx->iv;
699 if (!ctx->encrypt) {
700 iiv = (void *) in + inl - ctx->cipher->iv_len;
701 memcpy(save_iv, iiv, ctx->cipher->iv_len);
702 }
703 }
704
705 ivp = iv;
706 if (ISUNALIGNED(iv)) {
707 bcopy(iv, ivs, ctx->cipher->iv_len);
708 ivp = ivs;
709 }
710
711 viac3_xcrypt_cbc(cw, usein, useout, ctx->cipher_data, inl / 16, ivp);
712
713 if (ISUNALIGNED(in) || ISUNALIGNED(out)) {
714 if (ISUNALIGNED(out))
715 bcopy(spare, out, inl);
716 free(spare);
717 }
718
719 if (ivp == ivs)
720 bcopy(ivp, iv, ctx->cipher->iv_len);
721
722 if (ctx->cipher->iv_len) {
723 if (ctx->encrypt)
724 iiv = (void *) out + inl - ctx->cipher->iv_len;
725 else
726 iiv = save_iv;
727 memcpy(ctx->iv, iiv, ctx->cipher->iv_len);
728 }
729 return (1);
730}
731
732static int
733xcrypt_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
734 const unsigned char *iv, int enc)
735{
736 AES_KEY *k = ctx->cipher_data;
737#ifndef AES_ASM
738 int i;
739#endif
740
741 bzero(k, sizeof *k);
742 if (enc)
743 AES_set_encrypt_key(key, ctx->key_len * 8, k);
744 else
745 AES_set_decrypt_key(key, ctx->key_len * 8, k);
746
747#ifndef AES_ASM
748 /*
749 * XXX Damn OpenSSL byte swaps the expanded key!!
750 *
751 * XXX But only if we're using the C implementation of AES
752 */
753 for (i = 0; i < 4 * (AES_MAXNR + 1); i++)
754 k->rd_key[i] = htonl(k->rd_key[i]);
755#endif
756
757 return (1);
758}
759
760static int
761xcrypt_cleanup(EVP_CIPHER_CTX *ctx)
762{
763 bzero(ctx->cipher_data, ctx->cipher->ctx_size);
764 return (1);
765}
766
767static int
768check_viac3aes(void)
769{
770 int mib[2] = { CTL_MACHDEP, CPU_XCRYPT }, value;
771 size_t size = sizeof(value);
772
773 if (sysctl(mib, sizeof(mib)/sizeof(mib[0]), &value, &size,
774 NULL, 0) < 0)
775 return (0);
776 if (value == 0)
777 return (0);
778
779 if (value & C3_HAS_AES) {
780 cryptodev_aes_128_cbc.init = xcrypt_init_key;
781 cryptodev_aes_128_cbc.do_cipher = xcrypt_cipher;
782 cryptodev_aes_128_cbc.cleanup = xcrypt_cleanup;
783 cryptodev_aes_128_cbc.ctx_size = sizeof(AES_KEY);
784
785 cryptodev_aes_192_cbc.init = xcrypt_init_key;
786 cryptodev_aes_192_cbc.do_cipher = xcrypt_cipher;
787 cryptodev_aes_192_cbc.cleanup = xcrypt_cleanup;
788 cryptodev_aes_192_cbc.ctx_size = sizeof(AES_KEY);
789
790 cryptodev_aes_256_cbc.init = xcrypt_init_key;
791 cryptodev_aes_256_cbc.do_cipher = xcrypt_cipher;
792 cryptodev_aes_256_cbc.cleanup = xcrypt_cleanup;
793 cryptodev_aes_256_cbc.ctx_size = sizeof(AES_KEY);
794 }
795 return (value);
796}
797#endif /* __i386__ || __amd64__ */
798
568/* 799/*
569 * Registered by the ENGINE when used to find out how to deal with 800 * Registered by the ENGINE when used to find out how to deal with
570 * a particular NID in the ENGINE. this says what we'll do at the 801 * a particular NID in the ENGINE. this says what we'll do at the
@@ -591,7 +822,13 @@ cryptodev_engine_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
591 *cipher = &cryptodev_cast_cbc; 822 *cipher = &cryptodev_cast_cbc;
592 break; 823 break;
593 case NID_aes_128_cbc: 824 case NID_aes_128_cbc:
594 *cipher = &cryptodev_aes_cbc; 825 *cipher = &cryptodev_aes_128_cbc;
826 break;
827 case NID_aes_192_cbc:
828 *cipher = &cryptodev_aes_192_cbc;
829 break;
830 case NID_aes_256_cbc:
831 *cipher = &cryptodev_aes_256_cbc;
595 break; 832 break;
596 default: 833 default:
597 *cipher = NULL; 834 *cipher = NULL;
@@ -758,19 +995,14 @@ err:
758} 995}
759 996
760static int 997static int
761cryptodev_rsa_nocrt_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa) 998cryptodev_rsa_nocrt_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa,
999 BN_CTX *ctx)
762{ 1000{
763 int r; 1001 return (RSA_PKCS1_SSLeay()->rsa_mod_exp)(r0, I, rsa, ctx);
764 BN_CTX *ctx;
765
766 ctx = BN_CTX_new();
767 r = cryptodev_bn_mod_exp(r0, I, rsa->d, rsa->n, ctx, NULL);
768 BN_CTX_free(ctx);
769 return (r);
770} 1002}
771 1003
772static int 1004static int
773cryptodev_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa) 1005cryptodev_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
774{ 1006{
775 struct crypt_kop kop; 1007 struct crypt_kop kop;
776 int ret = 1; 1008 int ret = 1;
@@ -799,7 +1031,7 @@ cryptodev_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa)
799 1031
800 if (cryptodev_asym(&kop, BN_num_bytes(rsa->n), r0, 0, NULL) == -1) { 1032 if (cryptodev_asym(&kop, BN_num_bytes(rsa->n), r0, 0, NULL) == -1) {
801 const RSA_METHOD *meth = RSA_PKCS1_SSLeay(); 1033 const RSA_METHOD *meth = RSA_PKCS1_SSLeay();
802 ret = (*meth->rsa_mod_exp)(r0, I, rsa); 1034 ret = (*meth->rsa_mod_exp)(r0, I, rsa, ctx);
803 } 1035 }
804err: 1036err:
805 zapparams(&kop); 1037 zapparams(&kop);
diff --git a/src/lib/libcrypto/engine/hw_cswift.c b/src/lib/libcrypto/engine/hw_cswift.c
deleted file mode 100644
index 1411fd8333..0000000000
--- a/src/lib/libcrypto/engine/hw_cswift.c
+++ /dev/null
@@ -1,1109 +0,0 @@
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-2001 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 <openssl/engine.h>
64
65#ifndef OPENSSL_NO_HW
66#ifndef OPENSSL_NO_HW_CSWIFT
67
68/* Attribution notice: Rainbow have generously allowed me to reproduce
69 * the necessary definitions here from their API. This means the support
70 * can build independently of whether application builders have the
71 * API or hardware. This will allow developers to easily produce software
72 * that has latent hardware support for any users that have accelerators
73 * installed, without the developers themselves needing anything extra.
74 *
75 * I have only clipped the parts from the CryptoSwift header files that
76 * are (or seem) relevant to the CryptoSwift support code. This is
77 * simply to keep the file sizes reasonable.
78 * [Geoff]
79 */
80#ifdef FLAT_INC
81#include "cswift.h"
82#else
83#include "vendor_defns/cswift.h"
84#endif
85
86#define CSWIFT_LIB_NAME "cswift engine"
87#include "hw_cswift_err.c"
88
89static int cswift_destroy(ENGINE *e);
90static int cswift_init(ENGINE *e);
91static int cswift_finish(ENGINE *e);
92static int cswift_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)());
93static int cswift_bn_32copy(SW_LARGENUMBER * out, const BIGNUM * in);
94
95/* BIGNUM stuff */
96static int cswift_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
97 const BIGNUM *m, BN_CTX *ctx);
98static int cswift_mod_exp_crt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
99 const BIGNUM *q, const BIGNUM *dmp1, const BIGNUM *dmq1,
100 const BIGNUM *iqmp, BN_CTX *ctx);
101
102#ifndef OPENSSL_NO_RSA
103/* RSA stuff */
104static int cswift_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa);
105#endif
106/* This function is aliased to mod_exp (with the mont stuff dropped). */
107static int cswift_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
108 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
109
110#ifndef OPENSSL_NO_DSA
111/* DSA stuff */
112static DSA_SIG *cswift_dsa_sign(const unsigned char *dgst, int dlen, DSA *dsa);
113static int cswift_dsa_verify(const unsigned char *dgst, int dgst_len,
114 DSA_SIG *sig, DSA *dsa);
115#endif
116
117#ifndef OPENSSL_NO_DH
118/* DH stuff */
119/* This function is alised to mod_exp (with the DH and mont dropped). */
120static int cswift_mod_exp_dh(const DH *dh, BIGNUM *r,
121 const BIGNUM *a, const BIGNUM *p,
122 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
123#endif
124
125/* RAND stuff */
126static int cswift_rand_bytes(unsigned char *buf, int num);
127static int cswift_rand_status(void);
128
129/* The definitions for control commands specific to this engine */
130#define CSWIFT_CMD_SO_PATH ENGINE_CMD_BASE
131static const ENGINE_CMD_DEFN cswift_cmd_defns[] = {
132 {CSWIFT_CMD_SO_PATH,
133 "SO_PATH",
134 "Specifies the path to the 'cswift' shared library",
135 ENGINE_CMD_FLAG_STRING},
136 {0, NULL, NULL, 0}
137 };
138
139#ifndef OPENSSL_NO_RSA
140/* Our internal RSA_METHOD that we provide pointers to */
141static RSA_METHOD cswift_rsa =
142 {
143 "CryptoSwift RSA method",
144 NULL,
145 NULL,
146 NULL,
147 NULL,
148 cswift_rsa_mod_exp,
149 cswift_mod_exp_mont,
150 NULL,
151 NULL,
152 0,
153 NULL,
154 NULL,
155 NULL
156 };
157#endif
158
159#ifndef OPENSSL_NO_DSA
160/* Our internal DSA_METHOD that we provide pointers to */
161static DSA_METHOD cswift_dsa =
162 {
163 "CryptoSwift DSA method",
164 cswift_dsa_sign,
165 NULL, /* dsa_sign_setup */
166 cswift_dsa_verify,
167 NULL, /* dsa_mod_exp */
168 NULL, /* bn_mod_exp */
169 NULL, /* init */
170 NULL, /* finish */
171 0, /* flags */
172 NULL /* app_data */
173 };
174#endif
175
176#ifndef OPENSSL_NO_DH
177/* Our internal DH_METHOD that we provide pointers to */
178static DH_METHOD cswift_dh =
179 {
180 "CryptoSwift DH method",
181 NULL,
182 NULL,
183 cswift_mod_exp_dh,
184 NULL,
185 NULL,
186 0,
187 NULL
188 };
189#endif
190
191static RAND_METHOD cswift_random =
192 {
193 /* "CryptoSwift RAND method", */
194 NULL,
195 cswift_rand_bytes,
196 NULL,
197 NULL,
198 cswift_rand_bytes,
199 cswift_rand_status,
200 };
201
202
203/* Constants used when creating the ENGINE */
204static const char *engine_cswift_id = "cswift";
205static const char *engine_cswift_name = "CryptoSwift hardware engine support";
206
207/* This internal function is used by ENGINE_cswift() and possibly by the
208 * "dynamic" ENGINE support too */
209static int bind_helper(ENGINE *e)
210 {
211#ifndef OPENSSL_NO_RSA
212 const RSA_METHOD *meth1;
213#endif
214#ifndef OPENSSL_NO_DH
215 const DH_METHOD *meth2;
216#endif
217 if(!ENGINE_set_id(e, engine_cswift_id) ||
218 !ENGINE_set_name(e, engine_cswift_name) ||
219#ifndef OPENSSL_NO_RSA
220 !ENGINE_set_RSA(e, &cswift_rsa) ||
221#endif
222#ifndef OPENSSL_NO_DSA
223 !ENGINE_set_DSA(e, &cswift_dsa) ||
224#endif
225#ifndef OPENSSL_NO_DH
226 !ENGINE_set_DH(e, &cswift_dh) ||
227#endif
228 !ENGINE_set_RAND(e, &cswift_random) ||
229 !ENGINE_set_destroy_function(e, cswift_destroy) ||
230 !ENGINE_set_init_function(e, cswift_init) ||
231 !ENGINE_set_finish_function(e, cswift_finish) ||
232 !ENGINE_set_ctrl_function(e, cswift_ctrl) ||
233 !ENGINE_set_cmd_defns(e, cswift_cmd_defns))
234 return 0;
235
236#ifndef OPENSSL_NO_RSA
237 /* We know that the "PKCS1_SSLeay()" functions hook properly
238 * to the cswift-specific mod_exp and mod_exp_crt so we use
239 * those functions. NB: We don't use ENGINE_openssl() or
240 * anything "more generic" because something like the RSAref
241 * code may not hook properly, and if you own one of these
242 * cards then you have the right to do RSA operations on it
243 * anyway! */
244 meth1 = RSA_PKCS1_SSLeay();
245 cswift_rsa.rsa_pub_enc = meth1->rsa_pub_enc;
246 cswift_rsa.rsa_pub_dec = meth1->rsa_pub_dec;
247 cswift_rsa.rsa_priv_enc = meth1->rsa_priv_enc;
248 cswift_rsa.rsa_priv_dec = meth1->rsa_priv_dec;
249#endif
250
251#ifndef OPENSSL_NO_DH
252 /* Much the same for Diffie-Hellman */
253 meth2 = DH_OpenSSL();
254 cswift_dh.generate_key = meth2->generate_key;
255 cswift_dh.compute_key = meth2->compute_key;
256#endif
257
258 /* Ensure the cswift error handling is set up */
259 ERR_load_CSWIFT_strings();
260 return 1;
261 }
262
263#ifndef ENGINE_DYNAMIC_SUPPORT
264static ENGINE *engine_cswift(void)
265 {
266 ENGINE *ret = ENGINE_new();
267 if(!ret)
268 return NULL;
269 if(!bind_helper(ret))
270 {
271 ENGINE_free(ret);
272 return NULL;
273 }
274 return ret;
275 }
276
277void ENGINE_load_cswift(void)
278 {
279 /* Copied from eng_[openssl|dyn].c */
280 ENGINE *toadd = engine_cswift();
281 if(!toadd) return;
282 ENGINE_add(toadd);
283 ENGINE_free(toadd);
284 ERR_clear_error();
285 }
286#endif
287
288/* This is a process-global DSO handle used for loading and unloading
289 * the CryptoSwift library. NB: This is only set (or unset) during an
290 * init() or finish() call (reference counts permitting) and they're
291 * operating with global locks, so this should be thread-safe
292 * implicitly. */
293static DSO *cswift_dso = NULL;
294
295/* These are the function pointers that are (un)set when the library has
296 * successfully (un)loaded. */
297t_swAcquireAccContext *p_CSwift_AcquireAccContext = NULL;
298t_swAttachKeyParam *p_CSwift_AttachKeyParam = NULL;
299t_swSimpleRequest *p_CSwift_SimpleRequest = NULL;
300t_swReleaseAccContext *p_CSwift_ReleaseAccContext = NULL;
301
302/* Used in the DSO operations. */
303static const char *CSWIFT_LIBNAME = NULL;
304static const char *get_CSWIFT_LIBNAME(void)
305 {
306 if(CSWIFT_LIBNAME)
307 return CSWIFT_LIBNAME;
308 return "swift";
309 }
310static void free_CSWIFT_LIBNAME(void)
311 {
312 if(CSWIFT_LIBNAME)
313 OPENSSL_free((void*)CSWIFT_LIBNAME);
314 CSWIFT_LIBNAME = NULL;
315 }
316static long set_CSWIFT_LIBNAME(const char *name)
317 {
318 free_CSWIFT_LIBNAME();
319 return (((CSWIFT_LIBNAME = BUF_strdup(name)) != NULL) ? 1 : 0);
320 }
321static const char *CSWIFT_F1 = "swAcquireAccContext";
322static const char *CSWIFT_F2 = "swAttachKeyParam";
323static const char *CSWIFT_F3 = "swSimpleRequest";
324static const char *CSWIFT_F4 = "swReleaseAccContext";
325
326
327/* CryptoSwift library functions and mechanics - these are used by the
328 * higher-level functions further down. NB: As and where there's no
329 * error checking, take a look lower down where these functions are
330 * called, the checking and error handling is probably down there. */
331
332/* utility function to obtain a context */
333static int get_context(SW_CONTEXT_HANDLE *hac)
334 {
335 SW_STATUS status;
336
337 status = p_CSwift_AcquireAccContext(hac);
338 if(status != SW_OK)
339 return 0;
340 return 1;
341 }
342
343/* similarly to release one. */
344static void release_context(SW_CONTEXT_HANDLE hac)
345 {
346 p_CSwift_ReleaseAccContext(hac);
347 }
348
349/* Destructor (complements the "ENGINE_cswift()" constructor) */
350static int cswift_destroy(ENGINE *e)
351 {
352 free_CSWIFT_LIBNAME();
353 ERR_unload_CSWIFT_strings();
354 return 1;
355 }
356
357/* (de)initialisation functions. */
358static int cswift_init(ENGINE *e)
359 {
360 SW_CONTEXT_HANDLE hac;
361 t_swAcquireAccContext *p1;
362 t_swAttachKeyParam *p2;
363 t_swSimpleRequest *p3;
364 t_swReleaseAccContext *p4;
365
366 if(cswift_dso != NULL)
367 {
368 CSWIFTerr(CSWIFT_F_CSWIFT_INIT,CSWIFT_R_ALREADY_LOADED);
369 goto err;
370 }
371 /* Attempt to load libswift.so/swift.dll/whatever. */
372 cswift_dso = DSO_load(NULL, get_CSWIFT_LIBNAME(), NULL, 0);
373 if(cswift_dso == NULL)
374 {
375 CSWIFTerr(CSWIFT_F_CSWIFT_INIT,CSWIFT_R_NOT_LOADED);
376 goto err;
377 }
378 if(!(p1 = (t_swAcquireAccContext *)
379 DSO_bind_func(cswift_dso, CSWIFT_F1)) ||
380 !(p2 = (t_swAttachKeyParam *)
381 DSO_bind_func(cswift_dso, CSWIFT_F2)) ||
382 !(p3 = (t_swSimpleRequest *)
383 DSO_bind_func(cswift_dso, CSWIFT_F3)) ||
384 !(p4 = (t_swReleaseAccContext *)
385 DSO_bind_func(cswift_dso, CSWIFT_F4)))
386 {
387 CSWIFTerr(CSWIFT_F_CSWIFT_INIT,CSWIFT_R_NOT_LOADED);
388 goto err;
389 }
390 /* Copy the pointers */
391 p_CSwift_AcquireAccContext = p1;
392 p_CSwift_AttachKeyParam = p2;
393 p_CSwift_SimpleRequest = p3;
394 p_CSwift_ReleaseAccContext = p4;
395 /* Try and get a context - if not, we may have a DSO but no
396 * accelerator! */
397 if(!get_context(&hac))
398 {
399 CSWIFTerr(CSWIFT_F_CSWIFT_INIT,CSWIFT_R_UNIT_FAILURE);
400 goto err;
401 }
402 release_context(hac);
403 /* Everything's fine. */
404 return 1;
405err:
406 if(cswift_dso)
407 {
408 DSO_free(cswift_dso);
409 cswift_dso = NULL;
410 }
411 p_CSwift_AcquireAccContext = NULL;
412 p_CSwift_AttachKeyParam = NULL;
413 p_CSwift_SimpleRequest = NULL;
414 p_CSwift_ReleaseAccContext = NULL;
415 return 0;
416 }
417
418static int cswift_finish(ENGINE *e)
419 {
420 free_CSWIFT_LIBNAME();
421 if(cswift_dso == NULL)
422 {
423 CSWIFTerr(CSWIFT_F_CSWIFT_FINISH,CSWIFT_R_NOT_LOADED);
424 return 0;
425 }
426 if(!DSO_free(cswift_dso))
427 {
428 CSWIFTerr(CSWIFT_F_CSWIFT_FINISH,CSWIFT_R_UNIT_FAILURE);
429 return 0;
430 }
431 cswift_dso = NULL;
432 p_CSwift_AcquireAccContext = NULL;
433 p_CSwift_AttachKeyParam = NULL;
434 p_CSwift_SimpleRequest = NULL;
435 p_CSwift_ReleaseAccContext = NULL;
436 return 1;
437 }
438
439static int cswift_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)())
440 {
441 int initialised = ((cswift_dso == NULL) ? 0 : 1);
442 switch(cmd)
443 {
444 case CSWIFT_CMD_SO_PATH:
445 if(p == NULL)
446 {
447 CSWIFTerr(CSWIFT_F_CSWIFT_CTRL,ERR_R_PASSED_NULL_PARAMETER);
448 return 0;
449 }
450 if(initialised)
451 {
452 CSWIFTerr(CSWIFT_F_CSWIFT_CTRL,CSWIFT_R_ALREADY_LOADED);
453 return 0;
454 }
455 return set_CSWIFT_LIBNAME((const char *)p);
456 default:
457 break;
458 }
459 CSWIFTerr(CSWIFT_F_CSWIFT_CTRL,CSWIFT_R_CTRL_COMMAND_NOT_IMPLEMENTED);
460 return 0;
461 }
462
463/* Un petit mod_exp */
464static int cswift_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
465 const BIGNUM *m, BN_CTX *ctx)
466 {
467 /* I need somewhere to store temporary serialised values for
468 * use with the CryptoSwift API calls. A neat cheat - I'll use
469 * BIGNUMs from the BN_CTX but access their arrays directly as
470 * byte arrays <grin>. This way I don't have to clean anything
471 * up. */
472 BIGNUM *modulus;
473 BIGNUM *exponent;
474 BIGNUM *argument;
475 BIGNUM *result;
476 SW_STATUS sw_status;
477 SW_LARGENUMBER arg, res;
478 SW_PARAM sw_param;
479 SW_CONTEXT_HANDLE hac;
480 int to_return, acquired;
481
482 modulus = exponent = argument = result = NULL;
483 to_return = 0; /* expect failure */
484 acquired = 0;
485
486 if(!get_context(&hac))
487 {
488 CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP,CSWIFT_R_UNIT_FAILURE);
489 goto err;
490 }
491 acquired = 1;
492 /* Prepare the params */
493 BN_CTX_start(ctx);
494 modulus = BN_CTX_get(ctx);
495 exponent = BN_CTX_get(ctx);
496 argument = BN_CTX_get(ctx);
497 result = BN_CTX_get(ctx);
498 if(!result)
499 {
500 CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP,CSWIFT_R_BN_CTX_FULL);
501 goto err;
502 }
503 if(!bn_wexpand(modulus, m->top) || !bn_wexpand(exponent, p->top) ||
504 !bn_wexpand(argument, a->top) || !bn_wexpand(result, m->top))
505 {
506 CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP,CSWIFT_R_BN_EXPAND_FAIL);
507 goto err;
508 }
509 sw_param.type = SW_ALG_EXP;
510 sw_param.up.exp.modulus.nbytes = BN_bn2bin(m,
511 (unsigned char *)modulus->d);
512 sw_param.up.exp.modulus.value = (unsigned char *)modulus->d;
513 sw_param.up.exp.exponent.nbytes = BN_bn2bin(p,
514 (unsigned char *)exponent->d);
515 sw_param.up.exp.exponent.value = (unsigned char *)exponent->d;
516 /* Attach the key params */
517 sw_status = p_CSwift_AttachKeyParam(hac, &sw_param);
518 switch(sw_status)
519 {
520 case SW_OK:
521 break;
522 case SW_ERR_INPUT_SIZE:
523 CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP,CSWIFT_R_BAD_KEY_SIZE);
524 goto err;
525 default:
526 {
527 char tmpbuf[DECIMAL_SIZE(sw_status)+1];
528 CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP,CSWIFT_R_REQUEST_FAILED);
529 sprintf(tmpbuf, "%ld", sw_status);
530 ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf);
531 }
532 goto err;
533 }
534 /* Prepare the argument and response */
535 arg.nbytes = BN_bn2bin(a, (unsigned char *)argument->d);
536 arg.value = (unsigned char *)argument->d;
537 res.nbytes = BN_num_bytes(m);
538 memset(result->d, 0, res.nbytes);
539 res.value = (unsigned char *)result->d;
540 /* Perform the operation */
541 if((sw_status = p_CSwift_SimpleRequest(hac, SW_CMD_MODEXP, &arg, 1,
542 &res, 1)) != SW_OK)
543 {
544 char tmpbuf[DECIMAL_SIZE(sw_status)+1];
545 CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP,CSWIFT_R_REQUEST_FAILED);
546 sprintf(tmpbuf, "%ld", sw_status);
547 ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf);
548 goto err;
549 }
550 /* Convert the response */
551 BN_bin2bn((unsigned char *)result->d, res.nbytes, r);
552 to_return = 1;
553err:
554 if(acquired)
555 release_context(hac);
556 BN_CTX_end(ctx);
557 return to_return;
558 }
559
560
561int cswift_bn_32copy(SW_LARGENUMBER * out, const BIGNUM * in)
562{
563 int mod;
564 int numbytes = BN_num_bytes(in);
565
566 mod = 0;
567 while( ((out->nbytes = (numbytes+mod)) % 32) )
568 {
569 mod++;
570 }
571 out->value = (unsigned char*)OPENSSL_malloc(out->nbytes);
572 if(!out->value)
573 {
574 return 0;
575 }
576 BN_bn2bin(in, &out->value[mod]);
577 if(mod)
578 memset(out->value, 0, mod);
579
580 return 1;
581}
582
583/* Un petit mod_exp chinois */
584static int cswift_mod_exp_crt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
585 const BIGNUM *q, const BIGNUM *dmp1,
586 const BIGNUM *dmq1, const BIGNUM *iqmp, BN_CTX *ctx)
587 {
588 SW_STATUS sw_status;
589 SW_LARGENUMBER arg, res;
590 SW_PARAM sw_param;
591 SW_CONTEXT_HANDLE hac;
592 BIGNUM *result = NULL;
593 BIGNUM *argument = NULL;
594 int to_return = 0; /* expect failure */
595 int acquired = 0;
596
597 sw_param.up.crt.p.value = NULL;
598 sw_param.up.crt.q.value = NULL;
599 sw_param.up.crt.dmp1.value = NULL;
600 sw_param.up.crt.dmq1.value = NULL;
601 sw_param.up.crt.iqmp.value = NULL;
602
603 if(!get_context(&hac))
604 {
605 CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT,CSWIFT_R_UNIT_FAILURE);
606 goto err;
607 }
608 acquired = 1;
609
610 /* Prepare the params */
611 argument = BN_new();
612 result = BN_new();
613 if(!result || !argument)
614 {
615 CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT,CSWIFT_R_BN_CTX_FULL);
616 goto err;
617 }
618
619
620 sw_param.type = SW_ALG_CRT;
621 /************************************************************************/
622 /* 04/02/2003 */
623 /* Modified by Frederic Giudicelli (deny-all.com) to overcome the */
624 /* limitation of cswift with values not a multiple of 32 */
625 /************************************************************************/
626 if(!cswift_bn_32copy(&sw_param.up.crt.p, p))
627 {
628 CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT,CSWIFT_R_BN_EXPAND_FAIL);
629 goto err;
630 }
631 if(!cswift_bn_32copy(&sw_param.up.crt.q, q))
632 {
633 CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT,CSWIFT_R_BN_EXPAND_FAIL);
634 goto err;
635 }
636 if(!cswift_bn_32copy(&sw_param.up.crt.dmp1, dmp1))
637 {
638 CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT,CSWIFT_R_BN_EXPAND_FAIL);
639 goto err;
640 }
641 if(!cswift_bn_32copy(&sw_param.up.crt.dmq1, dmq1))
642 {
643 CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT,CSWIFT_R_BN_EXPAND_FAIL);
644 goto err;
645 }
646 if(!cswift_bn_32copy(&sw_param.up.crt.iqmp, iqmp))
647 {
648 CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT,CSWIFT_R_BN_EXPAND_FAIL);
649 goto err;
650 }
651 if( !bn_wexpand(argument, a->top) ||
652 !bn_wexpand(result, p->top + q->top))
653 {
654 CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT,CSWIFT_R_BN_EXPAND_FAIL);
655 goto err;
656 }
657
658 /* Attach the key params */
659 sw_status = p_CSwift_AttachKeyParam(hac, &sw_param);
660 switch(sw_status)
661 {
662 case SW_OK:
663 break;
664 case SW_ERR_INPUT_SIZE:
665 CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT,CSWIFT_R_BAD_KEY_SIZE);
666 goto err;
667 default:
668 {
669 char tmpbuf[DECIMAL_SIZE(sw_status)+1];
670 CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT,CSWIFT_R_REQUEST_FAILED);
671 sprintf(tmpbuf, "%ld", sw_status);
672 ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf);
673 }
674 goto err;
675 }
676 /* Prepare the argument and response */
677 arg.nbytes = BN_bn2bin(a, (unsigned char *)argument->d);
678 arg.value = (unsigned char *)argument->d;
679 res.nbytes = 2 * BN_num_bytes(p);
680 memset(result->d, 0, res.nbytes);
681 res.value = (unsigned char *)result->d;
682 /* Perform the operation */
683 if((sw_status = p_CSwift_SimpleRequest(hac, SW_CMD_MODEXP_CRT, &arg, 1,
684 &res, 1)) != SW_OK)
685 {
686 char tmpbuf[DECIMAL_SIZE(sw_status)+1];
687 CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT,CSWIFT_R_REQUEST_FAILED);
688 sprintf(tmpbuf, "%ld", sw_status);
689 ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf);
690 goto err;
691 }
692 /* Convert the response */
693 BN_bin2bn((unsigned char *)result->d, res.nbytes, r);
694 to_return = 1;
695err:
696 if(sw_param.up.crt.p.value)
697 OPENSSL_free(sw_param.up.crt.p.value);
698 if(sw_param.up.crt.q.value)
699 OPENSSL_free(sw_param.up.crt.q.value);
700 if(sw_param.up.crt.dmp1.value)
701 OPENSSL_free(sw_param.up.crt.dmp1.value);
702 if(sw_param.up.crt.dmq1.value)
703 OPENSSL_free(sw_param.up.crt.dmq1.value);
704 if(sw_param.up.crt.iqmp.value)
705 OPENSSL_free(sw_param.up.crt.iqmp.value);
706 if(result)
707 BN_free(result);
708 if(argument)
709 BN_free(argument);
710 if(acquired)
711 release_context(hac);
712 return to_return;
713 }
714
715#ifndef OPENSSL_NO_RSA
716static int cswift_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa)
717 {
718 BN_CTX *ctx;
719 int to_return = 0;
720 const RSA_METHOD * def_rsa_method;
721
722 /* Try the limits of RSA (2048 bits) */
723 if(BN_num_bytes(rsa->p) > 128 ||
724 BN_num_bytes(rsa->q) > 128 ||
725 BN_num_bytes(rsa->dmp1) > 128 ||
726 BN_num_bytes(rsa->dmq1) > 128 ||
727 BN_num_bytes(rsa->iqmp) > 128)
728 {
729#ifdef RSA_NULL
730 def_rsa_method=RSA_null_method();
731#else
732#if 0
733 def_rsa_method=RSA_PKCS1_RSAref();
734#else
735 def_rsa_method=RSA_PKCS1_SSLeay();
736#endif
737#endif
738 if(def_rsa_method)
739 return def_rsa_method->rsa_mod_exp(r0, I, rsa);
740 }
741
742 if((ctx = BN_CTX_new()) == NULL)
743 goto err;
744 if(!rsa->p || !rsa->q || !rsa->dmp1 || !rsa->dmq1 || !rsa->iqmp)
745 {
746 CSWIFTerr(CSWIFT_F_CSWIFT_RSA_MOD_EXP,CSWIFT_R_MISSING_KEY_COMPONENTS);
747 goto err;
748 }
749 to_return = cswift_mod_exp_crt(r0, I, rsa->p, rsa->q, rsa->dmp1,
750 rsa->dmq1, rsa->iqmp, ctx);
751err:
752 if(ctx)
753 BN_CTX_free(ctx);
754 return to_return;
755 }
756#endif
757
758/* This function is aliased to mod_exp (with the mont stuff dropped). */
759static int cswift_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
760 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
761 {
762 const RSA_METHOD * def_rsa_method;
763
764 /* Try the limits of RSA (2048 bits) */
765 if(BN_num_bytes(r) > 256 ||
766 BN_num_bytes(a) > 256 ||
767 BN_num_bytes(m) > 256)
768 {
769#ifdef RSA_NULL
770 def_rsa_method=RSA_null_method();
771#else
772#if 0
773 def_rsa_method=RSA_PKCS1_RSAref();
774#else
775 def_rsa_method=RSA_PKCS1_SSLeay();
776#endif
777#endif
778 if(def_rsa_method)
779 return def_rsa_method->bn_mod_exp(r, a, p, m, ctx, m_ctx);
780 }
781
782 return cswift_mod_exp(r, a, p, m, ctx);
783 }
784
785#ifndef OPENSSL_NO_DSA
786static DSA_SIG *cswift_dsa_sign(const unsigned char *dgst, int dlen, DSA *dsa)
787 {
788 SW_CONTEXT_HANDLE hac;
789 SW_PARAM sw_param;
790 SW_STATUS sw_status;
791 SW_LARGENUMBER arg, res;
792 unsigned char *ptr;
793 BN_CTX *ctx;
794 BIGNUM *dsa_p = NULL;
795 BIGNUM *dsa_q = NULL;
796 BIGNUM *dsa_g = NULL;
797 BIGNUM *dsa_key = NULL;
798 BIGNUM *result = NULL;
799 DSA_SIG *to_return = NULL;
800 int acquired = 0;
801
802 if((ctx = BN_CTX_new()) == NULL)
803 goto err;
804 if(!get_context(&hac))
805 {
806 CSWIFTerr(CSWIFT_F_CSWIFT_DSA_SIGN,CSWIFT_R_UNIT_FAILURE);
807 goto err;
808 }
809 acquired = 1;
810 /* Prepare the params */
811 BN_CTX_start(ctx);
812 dsa_p = BN_CTX_get(ctx);
813 dsa_q = BN_CTX_get(ctx);
814 dsa_g = BN_CTX_get(ctx);
815 dsa_key = BN_CTX_get(ctx);
816 result = BN_CTX_get(ctx);
817 if(!result)
818 {
819 CSWIFTerr(CSWIFT_F_CSWIFT_DSA_SIGN,CSWIFT_R_BN_CTX_FULL);
820 goto err;
821 }
822 if(!bn_wexpand(dsa_p, dsa->p->top) ||
823 !bn_wexpand(dsa_q, dsa->q->top) ||
824 !bn_wexpand(dsa_g, dsa->g->top) ||
825 !bn_wexpand(dsa_key, dsa->priv_key->top) ||
826 !bn_wexpand(result, dsa->p->top))
827 {
828 CSWIFTerr(CSWIFT_F_CSWIFT_DSA_SIGN,CSWIFT_R_BN_EXPAND_FAIL);
829 goto err;
830 }
831 sw_param.type = SW_ALG_DSA;
832 sw_param.up.dsa.p.nbytes = BN_bn2bin(dsa->p,
833 (unsigned char *)dsa_p->d);
834 sw_param.up.dsa.p.value = (unsigned char *)dsa_p->d;
835 sw_param.up.dsa.q.nbytes = BN_bn2bin(dsa->q,
836 (unsigned char *)dsa_q->d);
837 sw_param.up.dsa.q.value = (unsigned char *)dsa_q->d;
838 sw_param.up.dsa.g.nbytes = BN_bn2bin(dsa->g,
839 (unsigned char *)dsa_g->d);
840 sw_param.up.dsa.g.value = (unsigned char *)dsa_g->d;
841 sw_param.up.dsa.key.nbytes = BN_bn2bin(dsa->priv_key,
842 (unsigned char *)dsa_key->d);
843 sw_param.up.dsa.key.value = (unsigned char *)dsa_key->d;
844 /* Attach the key params */
845 sw_status = p_CSwift_AttachKeyParam(hac, &sw_param);
846 switch(sw_status)
847 {
848 case SW_OK:
849 break;
850 case SW_ERR_INPUT_SIZE:
851 CSWIFTerr(CSWIFT_F_CSWIFT_DSA_SIGN,CSWIFT_R_BAD_KEY_SIZE);
852 goto err;
853 default:
854 {
855 char tmpbuf[DECIMAL_SIZE(sw_status)+1];
856 CSWIFTerr(CSWIFT_F_CSWIFT_DSA_SIGN,CSWIFT_R_REQUEST_FAILED);
857 sprintf(tmpbuf, "%ld", sw_status);
858 ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf);
859 }
860 goto err;
861 }
862 /* Prepare the argument and response */
863 arg.nbytes = dlen;
864 arg.value = (unsigned char *)dgst;
865 res.nbytes = BN_num_bytes(dsa->p);
866 memset(result->d, 0, res.nbytes);
867 res.value = (unsigned char *)result->d;
868 /* Perform the operation */
869 sw_status = p_CSwift_SimpleRequest(hac, SW_CMD_DSS_SIGN, &arg, 1,
870 &res, 1);
871 if(sw_status != SW_OK)
872 {
873 char tmpbuf[DECIMAL_SIZE(sw_status)+1];
874 CSWIFTerr(CSWIFT_F_CSWIFT_DSA_SIGN,CSWIFT_R_REQUEST_FAILED);
875 sprintf(tmpbuf, "%ld", sw_status);
876 ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf);
877 goto err;
878 }
879 /* Convert the response */
880 ptr = (unsigned char *)result->d;
881 if((to_return = DSA_SIG_new()) == NULL)
882 goto err;
883 to_return->r = BN_bin2bn((unsigned char *)result->d, 20, NULL);
884 to_return->s = BN_bin2bn((unsigned char *)result->d + 20, 20, NULL);
885
886err:
887 if(acquired)
888 release_context(hac);
889 if(ctx)
890 {
891 BN_CTX_end(ctx);
892 BN_CTX_free(ctx);
893 }
894 return to_return;
895 }
896
897static int cswift_dsa_verify(const unsigned char *dgst, int dgst_len,
898 DSA_SIG *sig, DSA *dsa)
899 {
900 SW_CONTEXT_HANDLE hac;
901 SW_PARAM sw_param;
902 SW_STATUS sw_status;
903 SW_LARGENUMBER arg[2], res;
904 unsigned long sig_result;
905 BN_CTX *ctx;
906 BIGNUM *dsa_p = NULL;
907 BIGNUM *dsa_q = NULL;
908 BIGNUM *dsa_g = NULL;
909 BIGNUM *dsa_key = NULL;
910 BIGNUM *argument = NULL;
911 int to_return = -1;
912 int acquired = 0;
913
914 if((ctx = BN_CTX_new()) == NULL)
915 goto err;
916 if(!get_context(&hac))
917 {
918 CSWIFTerr(CSWIFT_F_CSWIFT_DSA_VERIFY,CSWIFT_R_UNIT_FAILURE);
919 goto err;
920 }
921 acquired = 1;
922 /* Prepare the params */
923 BN_CTX_start(ctx);
924 dsa_p = BN_CTX_get(ctx);
925 dsa_q = BN_CTX_get(ctx);
926 dsa_g = BN_CTX_get(ctx);
927 dsa_key = BN_CTX_get(ctx);
928 argument = BN_CTX_get(ctx);
929 if(!argument)
930 {
931 CSWIFTerr(CSWIFT_F_CSWIFT_DSA_VERIFY,CSWIFT_R_BN_CTX_FULL);
932 goto err;
933 }
934 if(!bn_wexpand(dsa_p, dsa->p->top) ||
935 !bn_wexpand(dsa_q, dsa->q->top) ||
936 !bn_wexpand(dsa_g, dsa->g->top) ||
937 !bn_wexpand(dsa_key, dsa->pub_key->top) ||
938 !bn_wexpand(argument, 40))
939 {
940 CSWIFTerr(CSWIFT_F_CSWIFT_DSA_VERIFY,CSWIFT_R_BN_EXPAND_FAIL);
941 goto err;
942 }
943 sw_param.type = SW_ALG_DSA;
944 sw_param.up.dsa.p.nbytes = BN_bn2bin(dsa->p,
945 (unsigned char *)dsa_p->d);
946 sw_param.up.dsa.p.value = (unsigned char *)dsa_p->d;
947 sw_param.up.dsa.q.nbytes = BN_bn2bin(dsa->q,
948 (unsigned char *)dsa_q->d);
949 sw_param.up.dsa.q.value = (unsigned char *)dsa_q->d;
950 sw_param.up.dsa.g.nbytes = BN_bn2bin(dsa->g,
951 (unsigned char *)dsa_g->d);
952 sw_param.up.dsa.g.value = (unsigned char *)dsa_g->d;
953 sw_param.up.dsa.key.nbytes = BN_bn2bin(dsa->pub_key,
954 (unsigned char *)dsa_key->d);
955 sw_param.up.dsa.key.value = (unsigned char *)dsa_key->d;
956 /* Attach the key params */
957 sw_status = p_CSwift_AttachKeyParam(hac, &sw_param);
958 switch(sw_status)
959 {
960 case SW_OK:
961 break;
962 case SW_ERR_INPUT_SIZE:
963 CSWIFTerr(CSWIFT_F_CSWIFT_DSA_VERIFY,CSWIFT_R_BAD_KEY_SIZE);
964 goto err;
965 default:
966 {
967 char tmpbuf[DECIMAL_SIZE(sw_status)+1];
968 CSWIFTerr(CSWIFT_F_CSWIFT_DSA_VERIFY,CSWIFT_R_REQUEST_FAILED);
969 sprintf(tmpbuf, "%ld", sw_status);
970 ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf);
971 }
972 goto err;
973 }
974 /* Prepare the argument and response */
975 arg[0].nbytes = dgst_len;
976 arg[0].value = (unsigned char *)dgst;
977 arg[1].nbytes = 40;
978 arg[1].value = (unsigned char *)argument->d;
979 memset(arg[1].value, 0, 40);
980 BN_bn2bin(sig->r, arg[1].value + 20 - BN_num_bytes(sig->r));
981 BN_bn2bin(sig->s, arg[1].value + 40 - BN_num_bytes(sig->s));
982 res.nbytes = 4; /* unsigned long */
983 res.value = (unsigned char *)(&sig_result);
984 /* Perform the operation */
985 sw_status = p_CSwift_SimpleRequest(hac, SW_CMD_DSS_VERIFY, arg, 2,
986 &res, 1);
987 if(sw_status != SW_OK)
988 {
989 char tmpbuf[DECIMAL_SIZE(sw_status)+1];
990 CSWIFTerr(CSWIFT_F_CSWIFT_DSA_VERIFY,CSWIFT_R_REQUEST_FAILED);
991 sprintf(tmpbuf, "%ld", sw_status);
992 ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf);
993 goto err;
994 }
995 /* Convert the response */
996 to_return = ((sig_result == 0) ? 0 : 1);
997
998err:
999 if(acquired)
1000 release_context(hac);
1001 if(ctx)
1002 {
1003 BN_CTX_end(ctx);
1004 BN_CTX_free(ctx);
1005 }
1006 return to_return;
1007 }
1008#endif
1009
1010#ifndef OPENSSL_NO_DH
1011/* This function is aliased to mod_exp (with the dh and mont dropped). */
1012static int cswift_mod_exp_dh(const DH *dh, BIGNUM *r,
1013 const BIGNUM *a, const BIGNUM *p,
1014 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
1015 {
1016 return cswift_mod_exp(r, a, p, m, ctx);
1017 }
1018#endif
1019
1020/* Random bytes are good */
1021static int cswift_rand_bytes(unsigned char *buf, int num)
1022{
1023 SW_CONTEXT_HANDLE hac;
1024 SW_STATUS swrc;
1025 SW_LARGENUMBER largenum;
1026 int acquired = 0;
1027 int to_return = 0; /* assume failure */
1028 unsigned char buf32[1024];
1029
1030
1031 if (!get_context(&hac))
1032 {
1033 CSWIFTerr(CSWIFT_F_CSWIFT_CTRL, CSWIFT_R_UNIT_FAILURE);
1034 goto err;
1035 }
1036 acquired = 1;
1037
1038 /************************************************************************/
1039 /* 04/02/2003 */
1040 /* Modified by Frederic Giudicelli (deny-all.com) to overcome the */
1041 /* limitation of cswift with values not a multiple of 32 */
1042 /************************************************************************/
1043
1044 while(num >= sizeof(buf32))
1045 {
1046 largenum.value = buf;
1047 largenum.nbytes = sizeof(buf32);
1048 /* tell CryptoSwift how many bytes we want and where we want it.
1049 * Note: - CryptoSwift cannot do more than 4096 bytes at a time.
1050 * - CryptoSwift can only do multiple of 32-bits. */
1051 swrc = p_CSwift_SimpleRequest(hac, SW_CMD_RAND, NULL, 0, &largenum, 1);
1052 if (swrc != SW_OK)
1053 {
1054 char tmpbuf[20];
1055 CSWIFTerr(CSWIFT_F_CSWIFT_CTRL, CSWIFT_R_REQUEST_FAILED);
1056 sprintf(tmpbuf, "%ld", swrc);
1057 ERR_add_error_data(2, "CryptoSwift error number is ", tmpbuf);
1058 goto err;
1059 }
1060 buf += sizeof(buf32);
1061 num -= sizeof(buf32);
1062 }
1063 if(num)
1064 {
1065 largenum.nbytes = sizeof(buf32);
1066 largenum.value = buf32;
1067 swrc = p_CSwift_SimpleRequest(hac, SW_CMD_RAND, NULL, 0, &largenum, 1);
1068 if (swrc != SW_OK)
1069 {
1070 char tmpbuf[20];
1071 CSWIFTerr(CSWIFT_F_CSWIFT_CTRL, CSWIFT_R_REQUEST_FAILED);
1072 sprintf(tmpbuf, "%ld", swrc);
1073 ERR_add_error_data(2, "CryptoSwift error number is ", tmpbuf);
1074 goto err;
1075 }
1076 memcpy(buf, largenum.value, num);
1077 }
1078
1079 to_return = 1; /* success */
1080err:
1081 if (acquired)
1082 release_context(hac);
1083
1084 return to_return;
1085}
1086
1087static int cswift_rand_status(void)
1088{
1089 return 1;
1090}
1091
1092
1093/* This stuff is needed if this ENGINE is being compiled into a self-contained
1094 * shared-library. */
1095#ifdef ENGINE_DYNAMIC_SUPPORT
1096static int bind_fn(ENGINE *e, const char *id)
1097 {
1098 if(id && (strcmp(id, engine_cswift_id) != 0))
1099 return 0;
1100 if(!bind_helper(e))
1101 return 0;
1102 return 1;
1103 }
1104IMPLEMENT_DYNAMIC_CHECK_FN()
1105IMPLEMENT_DYNAMIC_BIND_FN(bind_fn)
1106#endif /* ENGINE_DYNAMIC_SUPPORT */
1107
1108#endif /* !OPENSSL_NO_HW_CSWIFT */
1109#endif /* !OPENSSL_NO_HW */
diff --git a/src/lib/libcrypto/engine/hw_cswift_err.c b/src/lib/libcrypto/engine/hw_cswift_err.c
deleted file mode 100644
index 684f53bf27..0000000000
--- a/src/lib/libcrypto/engine/hw_cswift_err.c
+++ /dev/null
@@ -1,149 +0,0 @@
1/* hw_cswift_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 "hw_cswift_err.h"
64
65/* BEGIN ERROR CODES */
66#ifndef OPENSSL_NO_ERR
67static ERR_STRING_DATA CSWIFT_str_functs[]=
68 {
69{ERR_PACK(0,CSWIFT_F_CSWIFT_CTRL,0), "CSWIFT_CTRL"},
70{ERR_PACK(0,CSWIFT_F_CSWIFT_DSA_SIGN,0), "CSWIFT_DSA_SIGN"},
71{ERR_PACK(0,CSWIFT_F_CSWIFT_DSA_VERIFY,0), "CSWIFT_DSA_VERIFY"},
72{ERR_PACK(0,CSWIFT_F_CSWIFT_FINISH,0), "CSWIFT_FINISH"},
73{ERR_PACK(0,CSWIFT_F_CSWIFT_INIT,0), "CSWIFT_INIT"},
74{ERR_PACK(0,CSWIFT_F_CSWIFT_MOD_EXP,0), "CSWIFT_MOD_EXP"},
75{ERR_PACK(0,CSWIFT_F_CSWIFT_MOD_EXP_CRT,0), "CSWIFT_MOD_EXP_CRT"},
76{ERR_PACK(0,CSWIFT_F_CSWIFT_RSA_MOD_EXP,0), "CSWIFT_RSA_MOD_EXP"},
77{0,NULL}
78 };
79
80static ERR_STRING_DATA CSWIFT_str_reasons[]=
81 {
82{CSWIFT_R_ALREADY_LOADED ,"already loaded"},
83{CSWIFT_R_BAD_KEY_SIZE ,"bad key size"},
84{CSWIFT_R_BN_CTX_FULL ,"bn ctx full"},
85{CSWIFT_R_BN_EXPAND_FAIL ,"bn expand fail"},
86{CSWIFT_R_CTRL_COMMAND_NOT_IMPLEMENTED ,"ctrl command not implemented"},
87{CSWIFT_R_MISSING_KEY_COMPONENTS ,"missing key components"},
88{CSWIFT_R_NOT_LOADED ,"not loaded"},
89{CSWIFT_R_REQUEST_FAILED ,"request failed"},
90{CSWIFT_R_UNIT_FAILURE ,"unit failure"},
91{0,NULL}
92 };
93
94#endif
95
96#ifdef CSWIFT_LIB_NAME
97static ERR_STRING_DATA CSWIFT_lib_name[]=
98 {
99{0 ,CSWIFT_LIB_NAME},
100{0,NULL}
101 };
102#endif
103
104
105static int CSWIFT_lib_error_code=0;
106static int CSWIFT_error_init=1;
107
108static void ERR_load_CSWIFT_strings(void)
109 {
110 if (CSWIFT_lib_error_code == 0)
111 CSWIFT_lib_error_code=ERR_get_next_error_library();
112
113 if (CSWIFT_error_init)
114 {
115 CSWIFT_error_init=0;
116#ifndef OPENSSL_NO_ERR
117 ERR_load_strings(CSWIFT_lib_error_code,CSWIFT_str_functs);
118 ERR_load_strings(CSWIFT_lib_error_code,CSWIFT_str_reasons);
119#endif
120
121#ifdef CSWIFT_LIB_NAME
122 CSWIFT_lib_name->error = ERR_PACK(CSWIFT_lib_error_code,0,0);
123 ERR_load_strings(0,CSWIFT_lib_name);
124#endif
125 }
126 }
127
128static void ERR_unload_CSWIFT_strings(void)
129 {
130 if (CSWIFT_error_init == 0)
131 {
132#ifndef OPENSSL_NO_ERR
133 ERR_unload_strings(CSWIFT_lib_error_code,CSWIFT_str_functs);
134 ERR_unload_strings(CSWIFT_lib_error_code,CSWIFT_str_reasons);
135#endif
136
137#ifdef CSWIFT_LIB_NAME
138 ERR_unload_strings(0,CSWIFT_lib_name);
139#endif
140 CSWIFT_error_init=1;
141 }
142 }
143
144static void ERR_CSWIFT_error(int function, int reason, char *file, int line)
145 {
146 if (CSWIFT_lib_error_code == 0)
147 CSWIFT_lib_error_code=ERR_get_next_error_library();
148 ERR_PUT_error(CSWIFT_lib_error_code,function,reason,file,line);
149 }
diff --git a/src/lib/libcrypto/engine/hw_ncipher.c b/src/lib/libcrypto/engine/hw_ncipher.c
deleted file mode 100644
index 0d1c6b8df0..0000000000
--- a/src/lib/libcrypto/engine/hw_ncipher.c
+++ /dev/null
@@ -1,1388 +0,0 @@
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-2001 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 <string.h>
62#include "cryptlib.h"
63#include <openssl/crypto.h>
64#include <openssl/pem.h>
65#include <openssl/dso.h>
66#include <openssl/engine.h>
67#include <openssl/ui.h>
68
69#ifndef OPENSSL_NO_HW
70#ifndef OPENSSL_NO_HW_NCIPHER
71
72/* Attribution notice: nCipher have said several times that it's OK for
73 * us to implement a general interface to their boxes, and recently declared
74 * their HWCryptoHook to be public, and therefore available for us to use.
75 * Thanks, nCipher.
76 *
77 * The hwcryptohook.h included here is from May 2000.
78 * [Richard Levitte]
79 */
80#ifdef FLAT_INC
81#include "hwcryptohook.h"
82#else
83#include "vendor_defns/hwcryptohook.h"
84#endif
85
86#define HWCRHK_LIB_NAME "hwcrhk engine"
87#include "hw_ncipher_err.c"
88
89static int hwcrhk_destroy(ENGINE *e);
90static int hwcrhk_init(ENGINE *e);
91static int hwcrhk_finish(ENGINE *e);
92static int hwcrhk_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)());
93
94/* Functions to handle mutexes if have dynamic locks */
95static int hwcrhk_mutex_init(HWCryptoHook_Mutex*, HWCryptoHook_CallerContext*);
96static int hwcrhk_mutex_lock(HWCryptoHook_Mutex*);
97static void hwcrhk_mutex_unlock(HWCryptoHook_Mutex*);
98static void hwcrhk_mutex_destroy(HWCryptoHook_Mutex*);
99#if 1 /* This is a HACK which will disappear in 0.9.8 */
100/* Functions to handle mutexes if only have static locks */
101static int hwcrhk_static_mutex_init(HWCryptoHook_Mutex *m,
102 HWCryptoHook_CallerContext *c);
103static int hwcrhk_static_mutex_lock(HWCryptoHook_Mutex *m);
104static void hwcrhk_static_mutex_unlock(HWCryptoHook_Mutex *m);
105static void hwcrhk_static_mutex_destroy(HWCryptoHook_Mutex *m);
106#endif
107
108/* BIGNUM stuff */
109static int hwcrhk_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
110 const BIGNUM *m, BN_CTX *ctx);
111
112#ifndef OPENSSL_NO_RSA
113/* RSA stuff */
114static int hwcrhk_rsa_mod_exp(BIGNUM *r, const BIGNUM *I, RSA *rsa);
115#endif
116/* This function is aliased to mod_exp (with the mont stuff dropped). */
117static int hwcrhk_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
118 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
119
120#ifndef OPENSSL_NO_DH
121/* DH stuff */
122/* This function is alised to mod_exp (with the DH and mont dropped). */
123static int hwcrhk_mod_exp_dh(const DH *dh, BIGNUM *r,
124 const BIGNUM *a, const BIGNUM *p,
125 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
126#endif
127
128/* RAND stuff */
129static int hwcrhk_rand_bytes(unsigned char *buf, int num);
130static int hwcrhk_rand_status(void);
131
132/* KM stuff */
133static EVP_PKEY *hwcrhk_load_privkey(ENGINE *eng, const char *key_id,
134 UI_METHOD *ui_method, void *callback_data);
135static EVP_PKEY *hwcrhk_load_pubkey(ENGINE *eng, const char *key_id,
136 UI_METHOD *ui_method, void *callback_data);
137static void hwcrhk_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad,
138 int ind,long argl, void *argp);
139
140/* Interaction stuff */
141static int hwcrhk_insert_card(const char *prompt_info,
142 const char *wrong_info,
143 HWCryptoHook_PassphraseContext *ppctx,
144 HWCryptoHook_CallerContext *cactx);
145static int hwcrhk_get_pass(const char *prompt_info,
146 int *len_io, char *buf,
147 HWCryptoHook_PassphraseContext *ppctx,
148 HWCryptoHook_CallerContext *cactx);
149static void hwcrhk_log_message(void *logstr, const char *message);
150
151/* The definitions for control commands specific to this engine */
152#define HWCRHK_CMD_SO_PATH ENGINE_CMD_BASE
153#define HWCRHK_CMD_FORK_CHECK (ENGINE_CMD_BASE + 1)
154#define HWCRHK_CMD_THREAD_LOCKING (ENGINE_CMD_BASE + 2)
155#define HWCRHK_CMD_SET_USER_INTERFACE (ENGINE_CMD_BASE + 3)
156#define HWCRHK_CMD_SET_CALLBACK_DATA (ENGINE_CMD_BASE + 4)
157static const ENGINE_CMD_DEFN hwcrhk_cmd_defns[] = {
158 {HWCRHK_CMD_SO_PATH,
159 "SO_PATH",
160 "Specifies the path to the 'hwcrhk' shared library",
161 ENGINE_CMD_FLAG_STRING},
162 {HWCRHK_CMD_FORK_CHECK,
163 "FORK_CHECK",
164 "Turns fork() checking on or off (boolean)",
165 ENGINE_CMD_FLAG_NUMERIC},
166 {HWCRHK_CMD_THREAD_LOCKING,
167 "THREAD_LOCKING",
168 "Turns thread-safe locking on or off (boolean)",
169 ENGINE_CMD_FLAG_NUMERIC},
170 {HWCRHK_CMD_SET_USER_INTERFACE,
171 "SET_USER_INTERFACE",
172 "Set the global user interface (internal)",
173 ENGINE_CMD_FLAG_INTERNAL},
174 {HWCRHK_CMD_SET_CALLBACK_DATA,
175 "SET_CALLBACK_DATA",
176 "Set the global user interface extra data (internal)",
177 ENGINE_CMD_FLAG_INTERNAL},
178 {0, NULL, NULL, 0}
179 };
180
181#ifndef OPENSSL_NO_RSA
182/* Our internal RSA_METHOD that we provide pointers to */
183static RSA_METHOD hwcrhk_rsa =
184 {
185 "nCipher RSA method",
186 NULL,
187 NULL,
188 NULL,
189 NULL,
190 hwcrhk_rsa_mod_exp,
191 hwcrhk_mod_exp_mont,
192 NULL,
193 NULL,
194 0,
195 NULL,
196 NULL,
197 NULL
198 };
199#endif
200
201#ifndef OPENSSL_NO_DH
202/* Our internal DH_METHOD that we provide pointers to */
203static DH_METHOD hwcrhk_dh =
204 {
205 "nCipher DH method",
206 NULL,
207 NULL,
208 hwcrhk_mod_exp_dh,
209 NULL,
210 NULL,
211 0,
212 NULL
213 };
214#endif
215
216static RAND_METHOD hwcrhk_rand =
217 {
218 /* "nCipher RAND method", */
219 NULL,
220 hwcrhk_rand_bytes,
221 NULL,
222 NULL,
223 hwcrhk_rand_bytes,
224 hwcrhk_rand_status,
225 };
226
227/* Constants used when creating the ENGINE */
228static const char *engine_hwcrhk_id = "chil";
229static const char *engine_hwcrhk_name = "nCipher hardware engine support";
230
231/* Internal stuff for HWCryptoHook */
232
233/* Some structures needed for proper use of thread locks */
234/* hwcryptohook.h has some typedefs that turn struct HWCryptoHook_MutexValue
235 into HWCryptoHook_Mutex */
236struct HWCryptoHook_MutexValue
237 {
238 int lockid;
239 };
240
241/* hwcryptohook.h has some typedefs that turn
242 struct HWCryptoHook_PassphraseContextValue
243 into HWCryptoHook_PassphraseContext */
244struct HWCryptoHook_PassphraseContextValue
245 {
246 UI_METHOD *ui_method;
247 void *callback_data;
248 };
249
250/* hwcryptohook.h has some typedefs that turn
251 struct HWCryptoHook_CallerContextValue
252 into HWCryptoHook_CallerContext */
253struct HWCryptoHook_CallerContextValue
254 {
255 pem_password_cb *password_callback; /* Deprecated! Only present for
256 backward compatibility! */
257 UI_METHOD *ui_method;
258 void *callback_data;
259 };
260
261/* The MPI structure in HWCryptoHook is pretty compatible with OpenSSL
262 BIGNUM's, so lets define a couple of conversion macros */
263#define BN2MPI(mp, bn) \
264 {mp.size = bn->top * sizeof(BN_ULONG); mp.buf = (unsigned char *)bn->d;}
265#define MPI2BN(bn, mp) \
266 {mp.size = bn->dmax * sizeof(BN_ULONG); mp.buf = (unsigned char *)bn->d;}
267
268static BIO *logstream = NULL;
269static int disable_mutex_callbacks = 0;
270
271/* One might wonder why these are needed, since one can pass down at least
272 a UI_METHOD and a pointer to callback data to the key-loading functions.
273 The thing is that the ModExp and RSAImmed functions can load keys as well,
274 if the data they get is in a special, nCipher-defined format (hint: if you
275 look at the private exponent of the RSA data as a string, you'll see this
276 string: "nCipher KM tool key id", followed by some bytes, followed a key
277 identity string, followed by more bytes. This happens when you use "embed"
278 keys instead of "hwcrhk" keys). Unfortunately, those functions do not take
279 any passphrase or caller context, and our functions can't really take any
280 callback data either. Still, the "insert_card" and "get_passphrase"
281 callbacks may be called down the line, and will need to know what user
282 interface callbacks to call, and having callback data from the application
283 may be a nice thing as well, so we need to keep track of that globally. */
284static HWCryptoHook_CallerContext password_context = { NULL, NULL, NULL };
285
286/* Stuff to pass to the HWCryptoHook library */
287static HWCryptoHook_InitInfo hwcrhk_globals = {
288 HWCryptoHook_InitFlags_SimpleForkCheck, /* Flags */
289 &logstream, /* logstream */
290 sizeof(BN_ULONG), /* limbsize */
291 0, /* mslimb first: false for BNs */
292 -1, /* msbyte first: use native */
293 0, /* Max mutexes, 0 = no small limit */
294 0, /* Max simultaneous, 0 = default */
295
296 /* The next few are mutex stuff: we write wrapper functions
297 around the OS mutex functions. We initialise them to 0
298 here, and change that to actual function pointers in hwcrhk_init()
299 if dynamic locks are supported (that is, if the application
300 programmer has made sure of setting up callbacks bafore starting
301 this engine) *and* if disable_mutex_callbacks hasn't been set by
302 a call to ENGINE_ctrl(ENGINE_CTRL_CHIL_NO_LOCKING). */
303 sizeof(HWCryptoHook_Mutex),
304 0,
305 0,
306 0,
307 0,
308
309 /* The next few are condvar stuff: we write wrapper functions
310 round the OS functions. Currently not implemented and not
311 and absolute necessity even in threaded programs, therefore
312 0'ed. Will hopefully be implemented some day, since it
313 enhances the efficiency of HWCryptoHook. */
314 0, /* sizeof(HWCryptoHook_CondVar), */
315 0, /* hwcrhk_cv_init, */
316 0, /* hwcrhk_cv_wait, */
317 0, /* hwcrhk_cv_signal, */
318 0, /* hwcrhk_cv_broadcast, */
319 0, /* hwcrhk_cv_destroy, */
320
321 hwcrhk_get_pass, /* pass phrase */
322 hwcrhk_insert_card, /* insert a card */
323 hwcrhk_log_message /* Log message */
324};
325
326
327/* Now, to our own code */
328
329/* This internal function is used by ENGINE_ncipher() and possibly by the
330 * "dynamic" ENGINE support too */
331static int bind_helper(ENGINE *e)
332 {
333#ifndef OPENSSL_NO_RSA
334 const RSA_METHOD *meth1;
335#endif
336#ifndef OPENSSL_NO_DH
337 const DH_METHOD *meth2;
338#endif
339 if(!ENGINE_set_id(e, engine_hwcrhk_id) ||
340 !ENGINE_set_name(e, engine_hwcrhk_name) ||
341#ifndef OPENSSL_NO_RSA
342 !ENGINE_set_RSA(e, &hwcrhk_rsa) ||
343#endif
344#ifndef OPENSSL_NO_DH
345 !ENGINE_set_DH(e, &hwcrhk_dh) ||
346#endif
347 !ENGINE_set_RAND(e, &hwcrhk_rand) ||
348 !ENGINE_set_destroy_function(e, hwcrhk_destroy) ||
349 !ENGINE_set_init_function(e, hwcrhk_init) ||
350 !ENGINE_set_finish_function(e, hwcrhk_finish) ||
351 !ENGINE_set_ctrl_function(e, hwcrhk_ctrl) ||
352 !ENGINE_set_load_privkey_function(e, hwcrhk_load_privkey) ||
353 !ENGINE_set_load_pubkey_function(e, hwcrhk_load_pubkey) ||
354 !ENGINE_set_cmd_defns(e, hwcrhk_cmd_defns))
355 return 0;
356
357#ifndef OPENSSL_NO_RSA
358 /* We know that the "PKCS1_SSLeay()" functions hook properly
359 * to the cswift-specific mod_exp and mod_exp_crt so we use
360 * those functions. NB: We don't use ENGINE_openssl() or
361 * anything "more generic" because something like the RSAref
362 * code may not hook properly, and if you own one of these
363 * cards then you have the right to do RSA operations on it
364 * anyway! */
365 meth1 = RSA_PKCS1_SSLeay();
366 hwcrhk_rsa.rsa_pub_enc = meth1->rsa_pub_enc;
367 hwcrhk_rsa.rsa_pub_dec = meth1->rsa_pub_dec;
368 hwcrhk_rsa.rsa_priv_enc = meth1->rsa_priv_enc;
369 hwcrhk_rsa.rsa_priv_dec = meth1->rsa_priv_dec;
370#endif
371
372#ifndef OPENSSL_NO_DH
373 /* Much the same for Diffie-Hellman */
374 meth2 = DH_OpenSSL();
375 hwcrhk_dh.generate_key = meth2->generate_key;
376 hwcrhk_dh.compute_key = meth2->compute_key;
377#endif
378
379 /* Ensure the hwcrhk error handling is set up */
380 ERR_load_HWCRHK_strings();
381 return 1;
382 }
383
384#ifndef ENGINE_DYNAMIC_SUPPORT
385static ENGINE *engine_ncipher(void)
386 {
387 ENGINE *ret = ENGINE_new();
388 if(!ret)
389 return NULL;
390 if(!bind_helper(ret))
391 {
392 ENGINE_free(ret);
393 return NULL;
394 }
395 return ret;
396 }
397
398void ENGINE_load_chil(void)
399 {
400 /* Copied from eng_[openssl|dyn].c */
401 ENGINE *toadd = engine_ncipher();
402 if(!toadd) return;
403 ENGINE_add(toadd);
404 ENGINE_free(toadd);
405 ERR_clear_error();
406 }
407#endif
408
409/* This is a process-global DSO handle used for loading and unloading
410 * the HWCryptoHook library. NB: This is only set (or unset) during an
411 * init() or finish() call (reference counts permitting) and they're
412 * operating with global locks, so this should be thread-safe
413 * implicitly. */
414static DSO *hwcrhk_dso = NULL;
415static HWCryptoHook_ContextHandle hwcrhk_context = 0;
416#ifndef OPENSSL_NO_RSA
417static int hndidx_rsa = -1; /* Index for KM handle. Not really used yet. */
418#endif
419
420/* These are the function pointers that are (un)set when the library has
421 * successfully (un)loaded. */
422static HWCryptoHook_Init_t *p_hwcrhk_Init = NULL;
423static HWCryptoHook_Finish_t *p_hwcrhk_Finish = NULL;
424static HWCryptoHook_ModExp_t *p_hwcrhk_ModExp = NULL;
425#ifndef OPENSSL_NO_RSA
426static HWCryptoHook_RSA_t *p_hwcrhk_RSA = NULL;
427#endif
428static HWCryptoHook_RandomBytes_t *p_hwcrhk_RandomBytes = NULL;
429#ifndef OPENSSL_NO_RSA
430static HWCryptoHook_RSALoadKey_t *p_hwcrhk_RSALoadKey = NULL;
431static HWCryptoHook_RSAGetPublicKey_t *p_hwcrhk_RSAGetPublicKey = NULL;
432static HWCryptoHook_RSAUnloadKey_t *p_hwcrhk_RSAUnloadKey = NULL;
433#endif
434static HWCryptoHook_ModExpCRT_t *p_hwcrhk_ModExpCRT = NULL;
435
436/* Used in the DSO operations. */
437static const char *HWCRHK_LIBNAME = NULL;
438static void free_HWCRHK_LIBNAME(void)
439 {
440 if(HWCRHK_LIBNAME)
441 OPENSSL_free((void*)HWCRHK_LIBNAME);
442 HWCRHK_LIBNAME = NULL;
443 }
444static const char *get_HWCRHK_LIBNAME(void)
445 {
446 if(HWCRHK_LIBNAME)
447 return HWCRHK_LIBNAME;
448 return "nfhwcrhk";
449 }
450static long set_HWCRHK_LIBNAME(const char *name)
451 {
452 free_HWCRHK_LIBNAME();
453 return (((HWCRHK_LIBNAME = BUF_strdup(name)) != NULL) ? 1 : 0);
454 }
455static const char *n_hwcrhk_Init = "HWCryptoHook_Init";
456static const char *n_hwcrhk_Finish = "HWCryptoHook_Finish";
457static const char *n_hwcrhk_ModExp = "HWCryptoHook_ModExp";
458#ifndef OPENSSL_NO_RSA
459static const char *n_hwcrhk_RSA = "HWCryptoHook_RSA";
460#endif
461static const char *n_hwcrhk_RandomBytes = "HWCryptoHook_RandomBytes";
462#ifndef OPENSSL_NO_RSA
463static const char *n_hwcrhk_RSALoadKey = "HWCryptoHook_RSALoadKey";
464static const char *n_hwcrhk_RSAGetPublicKey = "HWCryptoHook_RSAGetPublicKey";
465static const char *n_hwcrhk_RSAUnloadKey = "HWCryptoHook_RSAUnloadKey";
466#endif
467static const char *n_hwcrhk_ModExpCRT = "HWCryptoHook_ModExpCRT";
468
469/* HWCryptoHook library functions and mechanics - these are used by the
470 * higher-level functions further down. NB: As and where there's no
471 * error checking, take a look lower down where these functions are
472 * called, the checking and error handling is probably down there. */
473
474/* utility function to obtain a context */
475static int get_context(HWCryptoHook_ContextHandle *hac,
476 HWCryptoHook_CallerContext *cac)
477 {
478 char tempbuf[1024];
479 HWCryptoHook_ErrMsgBuf rmsg;
480
481 rmsg.buf = tempbuf;
482 rmsg.size = sizeof(tempbuf);
483
484 *hac = p_hwcrhk_Init(&hwcrhk_globals, sizeof(hwcrhk_globals), &rmsg,
485 cac);
486 if (!*hac)
487 return 0;
488 return 1;
489 }
490
491/* similarly to release one. */
492static void release_context(HWCryptoHook_ContextHandle hac)
493 {
494 p_hwcrhk_Finish(hac);
495 }
496
497/* Destructor (complements the "ENGINE_ncipher()" constructor) */
498static int hwcrhk_destroy(ENGINE *e)
499 {
500 free_HWCRHK_LIBNAME();
501 ERR_unload_HWCRHK_strings();
502 return 1;
503 }
504
505/* (de)initialisation functions. */
506static int hwcrhk_init(ENGINE *e)
507 {
508 HWCryptoHook_Init_t *p1;
509 HWCryptoHook_Finish_t *p2;
510 HWCryptoHook_ModExp_t *p3;
511#ifndef OPENSSL_NO_RSA
512 HWCryptoHook_RSA_t *p4;
513 HWCryptoHook_RSALoadKey_t *p5;
514 HWCryptoHook_RSAGetPublicKey_t *p6;
515 HWCryptoHook_RSAUnloadKey_t *p7;
516#endif
517 HWCryptoHook_RandomBytes_t *p8;
518 HWCryptoHook_ModExpCRT_t *p9;
519
520 if(hwcrhk_dso != NULL)
521 {
522 HWCRHKerr(HWCRHK_F_HWCRHK_INIT,HWCRHK_R_ALREADY_LOADED);
523 goto err;
524 }
525 /* Attempt to load libnfhwcrhk.so/nfhwcrhk.dll/whatever. */
526 hwcrhk_dso = DSO_load(NULL, get_HWCRHK_LIBNAME(), NULL, 0);
527 if(hwcrhk_dso == NULL)
528 {
529 HWCRHKerr(HWCRHK_F_HWCRHK_INIT,HWCRHK_R_DSO_FAILURE);
530 goto err;
531 }
532 if(!(p1 = (HWCryptoHook_Init_t *)
533 DSO_bind_func(hwcrhk_dso, n_hwcrhk_Init)) ||
534 !(p2 = (HWCryptoHook_Finish_t *)
535 DSO_bind_func(hwcrhk_dso, n_hwcrhk_Finish)) ||
536 !(p3 = (HWCryptoHook_ModExp_t *)
537 DSO_bind_func(hwcrhk_dso, n_hwcrhk_ModExp)) ||
538#ifndef OPENSSL_NO_RSA
539 !(p4 = (HWCryptoHook_RSA_t *)
540 DSO_bind_func(hwcrhk_dso, n_hwcrhk_RSA)) ||
541 !(p5 = (HWCryptoHook_RSALoadKey_t *)
542 DSO_bind_func(hwcrhk_dso, n_hwcrhk_RSALoadKey)) ||
543 !(p6 = (HWCryptoHook_RSAGetPublicKey_t *)
544 DSO_bind_func(hwcrhk_dso, n_hwcrhk_RSAGetPublicKey)) ||
545 !(p7 = (HWCryptoHook_RSAUnloadKey_t *)
546 DSO_bind_func(hwcrhk_dso, n_hwcrhk_RSAUnloadKey)) ||
547#endif
548 !(p8 = (HWCryptoHook_RandomBytes_t *)
549 DSO_bind_func(hwcrhk_dso, n_hwcrhk_RandomBytes)) ||
550 !(p9 = (HWCryptoHook_ModExpCRT_t *)
551 DSO_bind_func(hwcrhk_dso, n_hwcrhk_ModExpCRT)))
552 {
553 HWCRHKerr(HWCRHK_F_HWCRHK_INIT,HWCRHK_R_DSO_FAILURE);
554 goto err;
555 }
556 /* Copy the pointers */
557 p_hwcrhk_Init = p1;
558 p_hwcrhk_Finish = p2;
559 p_hwcrhk_ModExp = p3;
560#ifndef OPENSSL_NO_RSA
561 p_hwcrhk_RSA = p4;
562 p_hwcrhk_RSALoadKey = p5;
563 p_hwcrhk_RSAGetPublicKey = p6;
564 p_hwcrhk_RSAUnloadKey = p7;
565#endif
566 p_hwcrhk_RandomBytes = p8;
567 p_hwcrhk_ModExpCRT = p9;
568
569 /* Check if the application decided to support dynamic locks,
570 and if it does, use them. */
571 if (disable_mutex_callbacks == 0)
572 {
573 if (CRYPTO_get_dynlock_create_callback() != NULL &&
574 CRYPTO_get_dynlock_lock_callback() != NULL &&
575 CRYPTO_get_dynlock_destroy_callback() != NULL)
576 {
577 hwcrhk_globals.mutex_init = hwcrhk_mutex_init;
578 hwcrhk_globals.mutex_acquire = hwcrhk_mutex_lock;
579 hwcrhk_globals.mutex_release = hwcrhk_mutex_unlock;
580 hwcrhk_globals.mutex_destroy = hwcrhk_mutex_destroy;
581 }
582 else if (CRYPTO_get_locking_callback() != NULL)
583 {
584 HWCRHKerr(HWCRHK_F_HWCRHK_INIT,HWCRHK_R_DYNAMIC_LOCKING_MISSING);
585 ERR_add_error_data(1,"You HAVE to add dynamic locking callbacks via CRYPTO_set_dynlock_{create,lock,destroy}_callback()");
586#if 1 /* This is a HACK which will disappear in 0.9.8 */
587 hwcrhk_globals.maxmutexes = 1; /* Only have one lock */
588 hwcrhk_globals.mutex_init = hwcrhk_static_mutex_init;
589 hwcrhk_globals.mutex_acquire = hwcrhk_static_mutex_lock;
590 hwcrhk_globals.mutex_release = hwcrhk_static_mutex_unlock;
591 hwcrhk_globals.mutex_destroy = hwcrhk_static_mutex_destroy;
592#else
593 goto err;
594#endif
595 }
596 }
597
598 /* Try and get a context - if not, we may have a DSO but no
599 * accelerator! */
600 if(!get_context(&hwcrhk_context, &password_context))
601 {
602 HWCRHKerr(HWCRHK_F_HWCRHK_INIT,HWCRHK_R_UNIT_FAILURE);
603 goto err;
604 }
605 /* Everything's fine. */
606#ifndef OPENSSL_NO_RSA
607 if (hndidx_rsa == -1)
608 hndidx_rsa = RSA_get_ex_new_index(0,
609 "nFast HWCryptoHook RSA key handle",
610 NULL, NULL, hwcrhk_ex_free);
611#endif
612 return 1;
613err:
614 if(hwcrhk_dso)
615 DSO_free(hwcrhk_dso);
616 hwcrhk_dso = NULL;
617 p_hwcrhk_Init = NULL;
618 p_hwcrhk_Finish = NULL;
619 p_hwcrhk_ModExp = NULL;
620#ifndef OPENSSL_NO_RSA
621 p_hwcrhk_RSA = NULL;
622 p_hwcrhk_RSALoadKey = NULL;
623 p_hwcrhk_RSAGetPublicKey = NULL;
624 p_hwcrhk_RSAUnloadKey = NULL;
625#endif
626 p_hwcrhk_ModExpCRT = NULL;
627 p_hwcrhk_RandomBytes = NULL;
628 return 0;
629 }
630
631static int hwcrhk_finish(ENGINE *e)
632 {
633 int to_return = 1;
634 free_HWCRHK_LIBNAME();
635 if(hwcrhk_dso == NULL)
636 {
637 HWCRHKerr(HWCRHK_F_HWCRHK_FINISH,HWCRHK_R_NOT_LOADED);
638 to_return = 0;
639 goto err;
640 }
641 release_context(hwcrhk_context);
642 if(!DSO_free(hwcrhk_dso))
643 {
644 HWCRHKerr(HWCRHK_F_HWCRHK_FINISH,HWCRHK_R_DSO_FAILURE);
645 to_return = 0;
646 goto err;
647 }
648 err:
649 if (logstream)
650 BIO_free(logstream);
651 hwcrhk_dso = NULL;
652 p_hwcrhk_Init = NULL;
653 p_hwcrhk_Finish = NULL;
654 p_hwcrhk_ModExp = NULL;
655#ifndef OPENSSL_NO_RSA
656 p_hwcrhk_RSA = NULL;
657 p_hwcrhk_RSALoadKey = NULL;
658 p_hwcrhk_RSAGetPublicKey = NULL;
659 p_hwcrhk_RSAUnloadKey = NULL;
660#endif
661 p_hwcrhk_ModExpCRT = NULL;
662 p_hwcrhk_RandomBytes = NULL;
663 return to_return;
664 }
665
666static int hwcrhk_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)())
667 {
668 int to_return = 1;
669
670 switch(cmd)
671 {
672 case HWCRHK_CMD_SO_PATH:
673 if(hwcrhk_dso)
674 {
675 HWCRHKerr(HWCRHK_F_HWCRHK_CTRL,HWCRHK_R_ALREADY_LOADED);
676 return 0;
677 }
678 if(p == NULL)
679 {
680 HWCRHKerr(HWCRHK_F_HWCRHK_CTRL,ERR_R_PASSED_NULL_PARAMETER);
681 return 0;
682 }
683 return set_HWCRHK_LIBNAME((const char *)p);
684 case ENGINE_CTRL_SET_LOGSTREAM:
685 {
686 BIO *bio = (BIO *)p;
687
688 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
689 if (logstream)
690 {
691 BIO_free(logstream);
692 logstream = NULL;
693 }
694 if (CRYPTO_add(&bio->references,1,CRYPTO_LOCK_BIO) > 1)
695 logstream = bio;
696 else
697 HWCRHKerr(HWCRHK_F_HWCRHK_CTRL,HWCRHK_R_BIO_WAS_FREED);
698 }
699 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
700 break;
701 case ENGINE_CTRL_SET_PASSWORD_CALLBACK:
702 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
703 password_context.password_callback = (pem_password_cb *)f;
704 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
705 break;
706 case ENGINE_CTRL_SET_USER_INTERFACE:
707 case HWCRHK_CMD_SET_USER_INTERFACE:
708 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
709 password_context.ui_method = (UI_METHOD *)p;
710 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
711 break;
712 case ENGINE_CTRL_SET_CALLBACK_DATA:
713 case HWCRHK_CMD_SET_CALLBACK_DATA:
714 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
715 password_context.callback_data = p;
716 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
717 break;
718 /* this enables or disables the "SimpleForkCheck" flag used in the
719 * initialisation structure. */
720 case ENGINE_CTRL_CHIL_SET_FORKCHECK:
721 case HWCRHK_CMD_FORK_CHECK:
722 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
723 if(i)
724 hwcrhk_globals.flags |=
725 HWCryptoHook_InitFlags_SimpleForkCheck;
726 else
727 hwcrhk_globals.flags &=
728 ~HWCryptoHook_InitFlags_SimpleForkCheck;
729 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
730 break;
731 /* This will prevent the initialisation function from "installing"
732 * the mutex-handling callbacks, even if they are available from
733 * within the library (or were provided to the library from the
734 * calling application). This is to remove any baggage for
735 * applications not using multithreading. */
736 case ENGINE_CTRL_CHIL_NO_LOCKING:
737 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
738 disable_mutex_callbacks = 1;
739 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
740 break;
741 case HWCRHK_CMD_THREAD_LOCKING:
742 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
743 disable_mutex_callbacks = ((i == 0) ? 0 : 1);
744 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
745 break;
746
747 /* The command isn't understood by this engine */
748 default:
749 HWCRHKerr(HWCRHK_F_HWCRHK_CTRL,
750 HWCRHK_R_CTRL_COMMAND_NOT_IMPLEMENTED);
751 to_return = 0;
752 break;
753 }
754
755 return to_return;
756 }
757
758static EVP_PKEY *hwcrhk_load_privkey(ENGINE *eng, const char *key_id,
759 UI_METHOD *ui_method, void *callback_data)
760 {
761#ifndef OPENSSL_NO_RSA
762 RSA *rtmp = NULL;
763#endif
764 EVP_PKEY *res = NULL;
765#ifndef OPENSSL_NO_RSA
766 HWCryptoHook_MPI e, n;
767 HWCryptoHook_RSAKeyHandle *hptr;
768#endif
769#if !defined(OPENSSL_NO_RSA)
770 char tempbuf[1024];
771 HWCryptoHook_ErrMsgBuf rmsg;
772#endif
773 HWCryptoHook_PassphraseContext ppctx;
774
775#if !defined(OPENSSL_NO_RSA)
776 rmsg.buf = tempbuf;
777 rmsg.size = sizeof(tempbuf);
778#endif
779
780 if(!hwcrhk_context)
781 {
782 HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY,
783 HWCRHK_R_NOT_INITIALISED);
784 goto err;
785 }
786#ifndef OPENSSL_NO_RSA
787 hptr = OPENSSL_malloc(sizeof(HWCryptoHook_RSAKeyHandle));
788 if (!hptr)
789 {
790 HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY,
791 ERR_R_MALLOC_FAILURE);
792 goto err;
793 }
794 ppctx.ui_method = ui_method;
795 ppctx.callback_data = callback_data;
796 if (p_hwcrhk_RSALoadKey(hwcrhk_context, key_id, hptr,
797 &rmsg, &ppctx))
798 {
799 HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY,
800 HWCRHK_R_CHIL_ERROR);
801 ERR_add_error_data(1,rmsg.buf);
802 goto err;
803 }
804 if (!*hptr)
805 {
806 HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY,
807 HWCRHK_R_NO_KEY);
808 goto err;
809 }
810#endif
811#ifndef OPENSSL_NO_RSA
812 rtmp = RSA_new_method(eng);
813 RSA_set_ex_data(rtmp, hndidx_rsa, (char *)hptr);
814 rtmp->e = BN_new();
815 rtmp->n = BN_new();
816 rtmp->flags |= RSA_FLAG_EXT_PKEY;
817 MPI2BN(rtmp->e, e);
818 MPI2BN(rtmp->n, n);
819 if (p_hwcrhk_RSAGetPublicKey(*hptr, &n, &e, &rmsg)
820 != HWCRYPTOHOOK_ERROR_MPISIZE)
821 {
822 HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PUBKEY,HWCRHK_R_CHIL_ERROR);
823 ERR_add_error_data(1,rmsg.buf);
824 goto err;
825 }
826
827 bn_expand2(rtmp->e, e.size/sizeof(BN_ULONG));
828 bn_expand2(rtmp->n, n.size/sizeof(BN_ULONG));
829 MPI2BN(rtmp->e, e);
830 MPI2BN(rtmp->n, n);
831
832 if (p_hwcrhk_RSAGetPublicKey(*hptr, &n, &e, &rmsg))
833 {
834 HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PUBKEY,
835 HWCRHK_R_CHIL_ERROR);
836 ERR_add_error_data(1,rmsg.buf);
837 goto err;
838 }
839 rtmp->e->top = e.size / sizeof(BN_ULONG);
840 bn_fix_top(rtmp->e);
841 rtmp->n->top = n.size / sizeof(BN_ULONG);
842 bn_fix_top(rtmp->n);
843
844 res = EVP_PKEY_new();
845 EVP_PKEY_assign_RSA(res, rtmp);
846#endif
847
848 if (!res)
849 HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PUBKEY,
850 HWCRHK_R_PRIVATE_KEY_ALGORITHMS_DISABLED);
851
852 return res;
853 err:
854 if (res)
855 EVP_PKEY_free(res);
856#ifndef OPENSSL_NO_RSA
857 if (rtmp)
858 RSA_free(rtmp);
859#endif
860 return NULL;
861 }
862
863static EVP_PKEY *hwcrhk_load_pubkey(ENGINE *eng, const char *key_id,
864 UI_METHOD *ui_method, void *callback_data)
865 {
866 EVP_PKEY *res = NULL;
867
868#ifndef OPENSSL_NO_RSA
869 res = hwcrhk_load_privkey(eng, key_id,
870 ui_method, callback_data);
871#endif
872
873 if (res)
874 switch(res->type)
875 {
876#ifndef OPENSSL_NO_RSA
877 case EVP_PKEY_RSA:
878 {
879 RSA *rsa = NULL;
880
881 CRYPTO_w_lock(CRYPTO_LOCK_EVP_PKEY);
882 rsa = res->pkey.rsa;
883 res->pkey.rsa = RSA_new();
884 res->pkey.rsa->n = rsa->n;
885 res->pkey.rsa->e = rsa->e;
886 rsa->n = NULL;
887 rsa->e = NULL;
888 CRYPTO_w_unlock(CRYPTO_LOCK_EVP_PKEY);
889 RSA_free(rsa);
890 }
891 break;
892#endif
893 default:
894 HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PUBKEY,
895 HWCRHK_R_CTRL_COMMAND_NOT_IMPLEMENTED);
896 goto err;
897 }
898
899 return res;
900 err:
901 if (res)
902 EVP_PKEY_free(res);
903 return NULL;
904 }
905
906/* A little mod_exp */
907static int hwcrhk_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
908 const BIGNUM *m, BN_CTX *ctx)
909 {
910 char tempbuf[1024];
911 HWCryptoHook_ErrMsgBuf rmsg;
912 /* Since HWCryptoHook_MPI is pretty compatible with BIGNUM's,
913 we use them directly, plus a little macro magic. We only
914 thing we need to make sure of is that enough space is allocated. */
915 HWCryptoHook_MPI m_a, m_p, m_n, m_r;
916 int to_return, ret;
917
918 to_return = 0; /* expect failure */
919 rmsg.buf = tempbuf;
920 rmsg.size = sizeof(tempbuf);
921
922 if(!hwcrhk_context)
923 {
924 HWCRHKerr(HWCRHK_F_HWCRHK_MOD_EXP,HWCRHK_R_NOT_INITIALISED);
925 goto err;
926 }
927 /* Prepare the params */
928 bn_expand2(r, m->top); /* Check for error !! */
929 BN2MPI(m_a, a);
930 BN2MPI(m_p, p);
931 BN2MPI(m_n, m);
932 MPI2BN(r, m_r);
933
934 /* Perform the operation */
935 ret = p_hwcrhk_ModExp(hwcrhk_context, m_a, m_p, m_n, &m_r, &rmsg);
936
937 /* Convert the response */
938 r->top = m_r.size / sizeof(BN_ULONG);
939 bn_fix_top(r);
940
941 if (ret < 0)
942 {
943 /* FIXME: When this error is returned, HWCryptoHook is
944 telling us that falling back to software computation
945 might be a good thing. */
946 if(ret == HWCRYPTOHOOK_ERROR_FALLBACK)
947 {
948 HWCRHKerr(HWCRHK_F_HWCRHK_MOD_EXP,HWCRHK_R_REQUEST_FALLBACK);
949 }
950 else
951 {
952 HWCRHKerr(HWCRHK_F_HWCRHK_MOD_EXP,HWCRHK_R_REQUEST_FAILED);
953 }
954 ERR_add_error_data(1,rmsg.buf);
955 goto err;
956 }
957
958 to_return = 1;
959err:
960 return to_return;
961 }
962
963#ifndef OPENSSL_NO_RSA
964static int hwcrhk_rsa_mod_exp(BIGNUM *r, const BIGNUM *I, RSA *rsa)
965 {
966 char tempbuf[1024];
967 HWCryptoHook_ErrMsgBuf rmsg;
968 HWCryptoHook_RSAKeyHandle *hptr;
969 int to_return = 0, ret;
970
971 rmsg.buf = tempbuf;
972 rmsg.size = sizeof(tempbuf);
973
974 if(!hwcrhk_context)
975 {
976 HWCRHKerr(HWCRHK_F_HWCRHK_MOD_EXP,HWCRHK_R_NOT_INITIALISED);
977 goto err;
978 }
979
980 /* This provides support for nForce keys. Since that's opaque data
981 all we do is provide a handle to the proper key and let HWCryptoHook
982 take care of the rest. */
983 if ((hptr = (HWCryptoHook_RSAKeyHandle *) RSA_get_ex_data(rsa, hndidx_rsa))
984 != NULL)
985 {
986 HWCryptoHook_MPI m_a, m_r;
987
988 if(!rsa->n)
989 {
990 HWCRHKerr(HWCRHK_F_HWCRHK_RSA_MOD_EXP,
991 HWCRHK_R_MISSING_KEY_COMPONENTS);
992 goto err;
993 }
994
995 /* Prepare the params */
996 bn_expand2(r, rsa->n->top); /* Check for error !! */
997 BN2MPI(m_a, I);
998 MPI2BN(r, m_r);
999
1000 /* Perform the operation */
1001 ret = p_hwcrhk_RSA(m_a, *hptr, &m_r, &rmsg);
1002
1003 /* Convert the response */
1004 r->top = m_r.size / sizeof(BN_ULONG);
1005 bn_fix_top(r);
1006
1007 if (ret < 0)
1008 {
1009 /* FIXME: When this error is returned, HWCryptoHook is
1010 telling us that falling back to software computation
1011 might be a good thing. */
1012 if(ret == HWCRYPTOHOOK_ERROR_FALLBACK)
1013 {
1014 HWCRHKerr(HWCRHK_F_HWCRHK_RSA_MOD_EXP,
1015 HWCRHK_R_REQUEST_FALLBACK);
1016 }
1017 else
1018 {
1019 HWCRHKerr(HWCRHK_F_HWCRHK_RSA_MOD_EXP,
1020 HWCRHK_R_REQUEST_FAILED);
1021 }
1022 ERR_add_error_data(1,rmsg.buf);
1023 goto err;
1024 }
1025 }
1026 else
1027 {
1028 HWCryptoHook_MPI m_a, m_p, m_q, m_dmp1, m_dmq1, m_iqmp, m_r;
1029
1030 if(!rsa->p || !rsa->q || !rsa->dmp1 || !rsa->dmq1 || !rsa->iqmp)
1031 {
1032 HWCRHKerr(HWCRHK_F_HWCRHK_RSA_MOD_EXP,
1033 HWCRHK_R_MISSING_KEY_COMPONENTS);
1034 goto err;
1035 }
1036
1037 /* Prepare the params */
1038 bn_expand2(r, rsa->n->top); /* Check for error !! */
1039 BN2MPI(m_a, I);
1040 BN2MPI(m_p, rsa->p);
1041 BN2MPI(m_q, rsa->q);
1042 BN2MPI(m_dmp1, rsa->dmp1);
1043 BN2MPI(m_dmq1, rsa->dmq1);
1044 BN2MPI(m_iqmp, rsa->iqmp);
1045 MPI2BN(r, m_r);
1046
1047 /* Perform the operation */
1048 ret = p_hwcrhk_ModExpCRT(hwcrhk_context, m_a, m_p, m_q,
1049 m_dmp1, m_dmq1, m_iqmp, &m_r, &rmsg);
1050
1051 /* Convert the response */
1052 r->top = m_r.size / sizeof(BN_ULONG);
1053 bn_fix_top(r);
1054
1055 if (ret < 0)
1056 {
1057 /* FIXME: When this error is returned, HWCryptoHook is
1058 telling us that falling back to software computation
1059 might be a good thing. */
1060 if(ret == HWCRYPTOHOOK_ERROR_FALLBACK)
1061 {
1062 HWCRHKerr(HWCRHK_F_HWCRHK_RSA_MOD_EXP,
1063 HWCRHK_R_REQUEST_FALLBACK);
1064 }
1065 else
1066 {
1067 HWCRHKerr(HWCRHK_F_HWCRHK_RSA_MOD_EXP,
1068 HWCRHK_R_REQUEST_FAILED);
1069 }
1070 ERR_add_error_data(1,rmsg.buf);
1071 goto err;
1072 }
1073 }
1074 /* If we're here, we must be here with some semblance of success :-) */
1075 to_return = 1;
1076err:
1077 return to_return;
1078 }
1079#endif
1080
1081/* This function is aliased to mod_exp (with the mont stuff dropped). */
1082static int hwcrhk_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
1083 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
1084 {
1085 return hwcrhk_mod_exp(r, a, p, m, ctx);
1086 }
1087
1088#ifndef OPENSSL_NO_DH
1089/* This function is aliased to mod_exp (with the dh and mont dropped). */
1090static int hwcrhk_mod_exp_dh(const DH *dh, BIGNUM *r,
1091 const BIGNUM *a, const BIGNUM *p,
1092 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
1093 {
1094 return hwcrhk_mod_exp(r, a, p, m, ctx);
1095 }
1096#endif
1097
1098/* Random bytes are good */
1099static int hwcrhk_rand_bytes(unsigned char *buf, int num)
1100 {
1101 char tempbuf[1024];
1102 HWCryptoHook_ErrMsgBuf rmsg;
1103 int to_return = 0; /* assume failure */
1104 int ret;
1105
1106 rmsg.buf = tempbuf;
1107 rmsg.size = sizeof(tempbuf);
1108
1109 if(!hwcrhk_context)
1110 {
1111 HWCRHKerr(HWCRHK_F_HWCRHK_RAND_BYTES,HWCRHK_R_NOT_INITIALISED);
1112 goto err;
1113 }
1114
1115 ret = p_hwcrhk_RandomBytes(hwcrhk_context, buf, num, &rmsg);
1116 if (ret < 0)
1117 {
1118 /* FIXME: When this error is returned, HWCryptoHook is
1119 telling us that falling back to software computation
1120 might be a good thing. */
1121 if(ret == HWCRYPTOHOOK_ERROR_FALLBACK)
1122 {
1123 HWCRHKerr(HWCRHK_F_HWCRHK_RAND_BYTES,
1124 HWCRHK_R_REQUEST_FALLBACK);
1125 }
1126 else
1127 {
1128 HWCRHKerr(HWCRHK_F_HWCRHK_RAND_BYTES,
1129 HWCRHK_R_REQUEST_FAILED);
1130 }
1131 ERR_add_error_data(1,rmsg.buf);
1132 goto err;
1133 }
1134 to_return = 1;
1135 err:
1136 return to_return;
1137 }
1138
1139static int hwcrhk_rand_status(void)
1140 {
1141 return 1;
1142 }
1143
1144/* This cleans up an RSA KM key, called when ex_data is freed */
1145
1146static void hwcrhk_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad,
1147 int ind,long argl, void *argp)
1148{
1149 char tempbuf[1024];
1150 HWCryptoHook_ErrMsgBuf rmsg;
1151#ifndef OPENSSL_NO_RSA
1152 HWCryptoHook_RSAKeyHandle *hptr;
1153#endif
1154#if !defined(OPENSSL_NO_RSA)
1155 int ret;
1156#endif
1157
1158 rmsg.buf = tempbuf;
1159 rmsg.size = sizeof(tempbuf);
1160
1161#ifndef OPENSSL_NO_RSA
1162 hptr = (HWCryptoHook_RSAKeyHandle *) item;
1163 if(hptr)
1164 {
1165 ret = p_hwcrhk_RSAUnloadKey(*hptr, NULL);
1166 OPENSSL_free(hptr);
1167 }
1168#endif
1169}
1170
1171/* Mutex calls: since the HWCryptoHook model closely follows the POSIX model
1172 * these just wrap the POSIX functions and add some logging.
1173 */
1174
1175static int hwcrhk_mutex_init(HWCryptoHook_Mutex* mt,
1176 HWCryptoHook_CallerContext *cactx)
1177 {
1178 mt->lockid = CRYPTO_get_new_dynlockid();
1179 if (mt->lockid == 0)
1180 return 1; /* failure */
1181 return 0; /* success */
1182 }
1183
1184static int hwcrhk_mutex_lock(HWCryptoHook_Mutex *mt)
1185 {
1186 CRYPTO_w_lock(mt->lockid);
1187 return 0;
1188 }
1189
1190static void hwcrhk_mutex_unlock(HWCryptoHook_Mutex * mt)
1191 {
1192 CRYPTO_w_unlock(mt->lockid);
1193 }
1194
1195static void hwcrhk_mutex_destroy(HWCryptoHook_Mutex *mt)
1196 {
1197 CRYPTO_destroy_dynlockid(mt->lockid);
1198 }
1199
1200/* Mutex upcalls to use if the application does not support dynamic locks */
1201
1202static int hwcrhk_static_mutex_init(HWCryptoHook_Mutex *m,
1203 HWCryptoHook_CallerContext *c)
1204 {
1205 return 0;
1206 }
1207static int hwcrhk_static_mutex_lock(HWCryptoHook_Mutex *m)
1208 {
1209 CRYPTO_w_lock(CRYPTO_LOCK_HWCRHK);
1210 return 0;
1211 }
1212static void hwcrhk_static_mutex_unlock(HWCryptoHook_Mutex *m)
1213 {
1214 CRYPTO_w_unlock(CRYPTO_LOCK_HWCRHK);
1215 }
1216static void hwcrhk_static_mutex_destroy(HWCryptoHook_Mutex *m)
1217 {
1218 }
1219
1220static int hwcrhk_get_pass(const char *prompt_info,
1221 int *len_io, char *buf,
1222 HWCryptoHook_PassphraseContext *ppctx,
1223 HWCryptoHook_CallerContext *cactx)
1224 {
1225 pem_password_cb *callback = NULL;
1226 void *callback_data = NULL;
1227 UI_METHOD *ui_method = NULL;
1228
1229 if (cactx)
1230 {
1231 if (cactx->ui_method)
1232 ui_method = cactx->ui_method;
1233 if (cactx->password_callback)
1234 callback = cactx->password_callback;
1235 if (cactx->callback_data)
1236 callback_data = cactx->callback_data;
1237 }
1238 if (ppctx)
1239 {
1240 if (ppctx->ui_method)
1241 {
1242 ui_method = ppctx->ui_method;
1243 callback = NULL;
1244 }
1245 if (ppctx->callback_data)
1246 callback_data = ppctx->callback_data;
1247 }
1248 if (callback == NULL && ui_method == NULL)
1249 {
1250 HWCRHKerr(HWCRHK_F_HWCRHK_GET_PASS,HWCRHK_R_NO_CALLBACK);
1251 return -1;
1252 }
1253
1254 if (ui_method)
1255 {
1256 UI *ui = UI_new_method(ui_method);
1257 if (ui)
1258 {
1259 int ok;
1260 char *prompt = UI_construct_prompt(ui,
1261 "pass phrase", prompt_info);
1262
1263 ok = UI_add_input_string(ui,prompt,
1264 UI_INPUT_FLAG_DEFAULT_PWD,
1265 buf,0,(*len_io) - 1);
1266 UI_add_user_data(ui, callback_data);
1267 UI_ctrl(ui, UI_CTRL_PRINT_ERRORS, 1, 0, 0);
1268
1269 if (ok >= 0)
1270 do
1271 {
1272 ok=UI_process(ui);
1273 }
1274 while (ok < 0 && UI_ctrl(ui, UI_CTRL_IS_REDOABLE, 0, 0, 0));
1275
1276 if (ok >= 0)
1277 *len_io = strlen(buf);
1278
1279 UI_free(ui);
1280 OPENSSL_free(prompt);
1281 }
1282 }
1283 else
1284 {
1285 *len_io = callback(buf, *len_io, 0, callback_data);
1286 }
1287 if(!*len_io)
1288 return -1;
1289 return 0;
1290 }
1291
1292static int hwcrhk_insert_card(const char *prompt_info,
1293 const char *wrong_info,
1294 HWCryptoHook_PassphraseContext *ppctx,
1295 HWCryptoHook_CallerContext *cactx)
1296 {
1297 int ok = -1;
1298 UI *ui;
1299 void *callback_data = NULL;
1300 UI_METHOD *ui_method = NULL;
1301
1302 if (cactx)
1303 {
1304 if (cactx->ui_method)
1305 ui_method = cactx->ui_method;
1306 if (cactx->callback_data)
1307 callback_data = cactx->callback_data;
1308 }
1309 if (ppctx)
1310 {
1311 if (ppctx->ui_method)
1312 ui_method = ppctx->ui_method;
1313 if (ppctx->callback_data)
1314 callback_data = ppctx->callback_data;
1315 }
1316 if (ui_method == NULL)
1317 {
1318 HWCRHKerr(HWCRHK_F_HWCRHK_INSERT_CARD,
1319 HWCRHK_R_NO_CALLBACK);
1320 return -1;
1321 }
1322
1323 ui = UI_new_method(ui_method);
1324
1325 if (ui)
1326 {
1327 char answer;
1328 char buf[BUFSIZ];
1329
1330 if (wrong_info)
1331 BIO_snprintf(buf, sizeof(buf)-1,
1332 "Current card: \"%s\"\n", wrong_info);
1333 ok = UI_dup_info_string(ui, buf);
1334 if (ok >= 0 && prompt_info)
1335 {
1336 BIO_snprintf(buf, sizeof(buf)-1,
1337 "Insert card \"%s\"", prompt_info);
1338 ok = UI_dup_input_boolean(ui, buf,
1339 "\n then hit <enter> or C<enter> to cancel\n",
1340 "\r\n", "Cc", UI_INPUT_FLAG_ECHO, &answer);
1341 }
1342 UI_add_user_data(ui, callback_data);
1343
1344 if (ok >= 0)
1345 ok = UI_process(ui);
1346 UI_free(ui);
1347
1348 if (ok == -2 || (ok >= 0 && answer == 'C'))
1349 ok = 1;
1350 else if (ok < 0)
1351 ok = -1;
1352 else
1353 ok = 0;
1354 }
1355 return ok;
1356 }
1357
1358static void hwcrhk_log_message(void *logstr, const char *message)
1359 {
1360 BIO *lstream = NULL;
1361
1362 CRYPTO_w_lock(CRYPTO_LOCK_BIO);
1363 if (logstr)
1364 lstream=*(BIO **)logstr;
1365 if (lstream)
1366 {
1367 BIO_printf(lstream, "%s\n", message);
1368 }
1369 CRYPTO_w_unlock(CRYPTO_LOCK_BIO);
1370 }
1371
1372/* This stuff is needed if this ENGINE is being compiled into a self-contained
1373 * shared-library. */
1374#ifdef ENGINE_DYNAMIC_SUPPORT
1375static int bind_fn(ENGINE *e, const char *id)
1376 {
1377 if(id && (strcmp(id, engine_hwcrhk_id) != 0))
1378 return 0;
1379 if(!bind_helper(e))
1380 return 0;
1381 return 1;
1382 }
1383IMPLEMENT_DYNAMIC_CHECK_FN()
1384IMPLEMENT_DYNAMIC_BIND_FN(bind_fn)
1385#endif /* ENGINE_DYNAMIC_SUPPORT */
1386
1387#endif /* !OPENSSL_NO_HW_NCIPHER */
1388#endif /* !OPENSSL_NO_HW */
diff --git a/src/lib/libcrypto/engine/hw_ncipher_err.c b/src/lib/libcrypto/engine/hw_ncipher_err.c
deleted file mode 100644
index 5bc94581b7..0000000000
--- a/src/lib/libcrypto/engine/hw_ncipher_err.c
+++ /dev/null
@@ -1,157 +0,0 @@
1/* hw_ncipher_err.c */
2/* ====================================================================
3 * Copyright (c) 1999-2002 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 "hw_ncipher_err.h"
64
65/* BEGIN ERROR CODES */
66#ifndef OPENSSL_NO_ERR
67static ERR_STRING_DATA HWCRHK_str_functs[]=
68 {
69{ERR_PACK(0,HWCRHK_F_HWCRHK_CTRL,0), "HWCRHK_CTRL"},
70{ERR_PACK(0,HWCRHK_F_HWCRHK_FINISH,0), "HWCRHK_FINISH"},
71{ERR_PACK(0,HWCRHK_F_HWCRHK_GET_PASS,0), "HWCRHK_GET_PASS"},
72{ERR_PACK(0,HWCRHK_F_HWCRHK_INIT,0), "HWCRHK_INIT"},
73{ERR_PACK(0,HWCRHK_F_HWCRHK_INSERT_CARD,0), "HWCRHK_INSERT_CARD"},
74{ERR_PACK(0,HWCRHK_F_HWCRHK_LOAD_PRIVKEY,0), "HWCRHK_LOAD_PRIVKEY"},
75{ERR_PACK(0,HWCRHK_F_HWCRHK_LOAD_PUBKEY,0), "HWCRHK_LOAD_PUBKEY"},
76{ERR_PACK(0,HWCRHK_F_HWCRHK_MOD_EXP,0), "HWCRHK_MOD_EXP"},
77{ERR_PACK(0,HWCRHK_F_HWCRHK_RAND_BYTES,0), "HWCRHK_RAND_BYTES"},
78{ERR_PACK(0,HWCRHK_F_HWCRHK_RSA_MOD_EXP,0), "HWCRHK_RSA_MOD_EXP"},
79{0,NULL}
80 };
81
82static ERR_STRING_DATA HWCRHK_str_reasons[]=
83 {
84{HWCRHK_R_ALREADY_LOADED ,"already loaded"},
85{HWCRHK_R_BIO_WAS_FREED ,"bio was freed"},
86{HWCRHK_R_CHIL_ERROR ,"chil error"},
87{HWCRHK_R_CTRL_COMMAND_NOT_IMPLEMENTED ,"ctrl command not implemented"},
88{HWCRHK_R_DSO_FAILURE ,"dso failure"},
89{HWCRHK_R_DYNAMIC_LOCKING_MISSING ,"dynamic locking missing"},
90{HWCRHK_R_MISSING_KEY_COMPONENTS ,"missing key components"},
91{HWCRHK_R_NOT_INITIALISED ,"not initialised"},
92{HWCRHK_R_NOT_LOADED ,"not loaded"},
93{HWCRHK_R_NO_CALLBACK ,"no callback"},
94{HWCRHK_R_NO_KEY ,"no key"},
95{HWCRHK_R_PRIVATE_KEY_ALGORITHMS_DISABLED,"private key algorithms disabled"},
96{HWCRHK_R_REQUEST_FAILED ,"request failed"},
97{HWCRHK_R_REQUEST_FALLBACK ,"request fallback"},
98{HWCRHK_R_UNIT_FAILURE ,"unit failure"},
99{0,NULL}
100 };
101
102#endif
103
104#ifdef HWCRHK_LIB_NAME
105static ERR_STRING_DATA HWCRHK_lib_name[]=
106 {
107{0 ,HWCRHK_LIB_NAME},
108{0,NULL}
109 };
110#endif
111
112
113static int HWCRHK_lib_error_code=0;
114static int HWCRHK_error_init=1;
115
116static void ERR_load_HWCRHK_strings(void)
117 {
118 if (HWCRHK_lib_error_code == 0)
119 HWCRHK_lib_error_code=ERR_get_next_error_library();
120
121 if (HWCRHK_error_init)
122 {
123 HWCRHK_error_init=0;
124#ifndef OPENSSL_NO_ERR
125 ERR_load_strings(HWCRHK_lib_error_code,HWCRHK_str_functs);
126 ERR_load_strings(HWCRHK_lib_error_code,HWCRHK_str_reasons);
127#endif
128
129#ifdef HWCRHK_LIB_NAME
130 HWCRHK_lib_name->error = ERR_PACK(HWCRHK_lib_error_code,0,0);
131 ERR_load_strings(0,HWCRHK_lib_name);
132#endif
133 }
134 }
135
136static void ERR_unload_HWCRHK_strings(void)
137 {
138 if (HWCRHK_error_init == 0)
139 {
140#ifndef OPENSSL_NO_ERR
141 ERR_unload_strings(HWCRHK_lib_error_code,HWCRHK_str_functs);
142 ERR_unload_strings(HWCRHK_lib_error_code,HWCRHK_str_reasons);
143#endif
144
145#ifdef HWCRHK_LIB_NAME
146 ERR_unload_strings(0,HWCRHK_lib_name);
147#endif
148 HWCRHK_error_init=1;
149 }
150 }
151
152static void ERR_HWCRHK_error(int function, int reason, char *file, int line)
153 {
154 if (HWCRHK_lib_error_code == 0)
155 HWCRHK_lib_error_code=ERR_get_next_error_library();
156 ERR_PUT_error(HWCRHK_lib_error_code,function,reason,file,line);
157 }
diff --git a/src/lib/libcrypto/engine/hw_ncipher_err.h b/src/lib/libcrypto/engine/hw_ncipher_err.h
deleted file mode 100644
index d232d02319..0000000000
--- a/src/lib/libcrypto/engine/hw_ncipher_err.h
+++ /dev/null
@@ -1,101 +0,0 @@
1/* ====================================================================
2 * Copyright (c) 2001 The OpenSSL Project. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in
13 * the documentation and/or other materials provided with the
14 * distribution.
15 *
16 * 3. All advertising materials mentioning features or use of this
17 * software must display the following acknowledgment:
18 * "This product includes software developed by the OpenSSL Project
19 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
20 *
21 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
22 * endorse or promote products derived from this software without
23 * prior written permission. For written permission, please contact
24 * openssl-core@openssl.org.
25 *
26 * 5. Products derived from this software may not be called "OpenSSL"
27 * nor may "OpenSSL" appear in their names without prior written
28 * permission of the OpenSSL Project.
29 *
30 * 6. Redistributions of any form whatsoever must retain the following
31 * acknowledgment:
32 * "This product includes software developed by the OpenSSL Project
33 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
34 *
35 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
36 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
37 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
38 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
39 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
41 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
42 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
43 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
44 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
45 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
46 * OF THE POSSIBILITY OF SUCH DAMAGE.
47 * ====================================================================
48 *
49 * This product includes cryptographic software written by Eric Young
50 * (eay@cryptsoft.com). This product includes software written by Tim
51 * Hudson (tjh@cryptsoft.com).
52 *
53 */
54
55#ifndef HEADER_HWCRHK_ERR_H
56#define HEADER_HWCRHK_ERR_H
57
58/* BEGIN ERROR CODES */
59/* The following lines are auto generated by the script mkerr.pl. Any changes
60 * made after this point may be overwritten when the script is next run.
61 */
62static void ERR_load_HWCRHK_strings(void);
63static void ERR_unload_HWCRHK_strings(void);
64static void ERR_HWCRHK_error(int function, int reason, char *file, int line);
65#define HWCRHKerr(f,r) ERR_HWCRHK_error((f),(r),__FILE__,__LINE__)
66
67/* Error codes for the HWCRHK functions. */
68
69/* Function codes. */
70#define HWCRHK_F_HWCRHK_CTRL 100
71#define HWCRHK_F_HWCRHK_FINISH 101
72#define HWCRHK_F_HWCRHK_GET_PASS 102
73#define HWCRHK_F_HWCRHK_INIT 103
74#define HWCRHK_F_HWCRHK_INSERT_CARD 104
75#define HWCRHK_F_HWCRHK_LOAD_PRIVKEY 105
76#define HWCRHK_F_HWCRHK_LOAD_PUBKEY 106
77#define HWCRHK_F_HWCRHK_MOD_EXP 107
78#define HWCRHK_F_HWCRHK_RAND_BYTES 108
79#define HWCRHK_F_HWCRHK_RSA_MOD_EXP 109
80
81/* Reason codes. */
82#define HWCRHK_R_ALREADY_LOADED 100
83#define HWCRHK_R_BIO_WAS_FREED 101
84#define HWCRHK_R_CHIL_ERROR 102
85#define HWCRHK_R_CTRL_COMMAND_NOT_IMPLEMENTED 103
86#define HWCRHK_R_DSO_FAILURE 104
87#define HWCRHK_R_DYNAMIC_LOCKING_MISSING 114
88#define HWCRHK_R_MISSING_KEY_COMPONENTS 105
89#define HWCRHK_R_NOT_INITIALISED 106
90#define HWCRHK_R_NOT_LOADED 107
91#define HWCRHK_R_NO_CALLBACK 108
92#define HWCRHK_R_NO_KEY 109
93#define HWCRHK_R_PRIVATE_KEY_ALGORITHMS_DISABLED 110
94#define HWCRHK_R_REQUEST_FAILED 111
95#define HWCRHK_R_REQUEST_FALLBACK 112
96#define HWCRHK_R_UNIT_FAILURE 113
97
98#ifdef __cplusplus
99}
100#endif
101#endif
diff --git a/src/lib/libcrypto/engine/hw_nuron.c b/src/lib/libcrypto/engine/hw_nuron.c
deleted file mode 100644
index fb9188bfe5..0000000000
--- a/src/lib/libcrypto/engine/hw_nuron.c
+++ /dev/null
@@ -1,418 +0,0 @@
1/* crypto/engine/hw_nuron.c */
2/* Written by Ben Laurie for the OpenSSL Project, leaning heavily on Geoff
3 * Thorpe's Atalla implementation.
4 */
5/* ====================================================================
6 * Copyright (c) 2000-2001 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 <openssl/engine.h>
64
65
66#ifndef OPENSSL_NO_HW
67#ifndef OPENSSL_NO_HW_NURON
68
69#define NURON_LIB_NAME "nuron engine"
70#include "hw_nuron_err.c"
71
72static const char *NURON_LIBNAME = NULL;
73static const char *get_NURON_LIBNAME(void)
74 {
75 if(NURON_LIBNAME)
76 return NURON_LIBNAME;
77 return "nuronssl";
78 }
79static void free_NURON_LIBNAME(void)
80 {
81 if(NURON_LIBNAME)
82 OPENSSL_free((void*)NURON_LIBNAME);
83 NURON_LIBNAME = NULL;
84 }
85static long set_NURON_LIBNAME(const char *name)
86 {
87 free_NURON_LIBNAME();
88 return (((NURON_LIBNAME = BUF_strdup(name)) != NULL) ? 1 : 0);
89 }
90static const char *NURON_F1 = "nuron_mod_exp";
91
92/* The definitions for control commands specific to this engine */
93#define NURON_CMD_SO_PATH ENGINE_CMD_BASE
94static const ENGINE_CMD_DEFN nuron_cmd_defns[] = {
95 {NURON_CMD_SO_PATH,
96 "SO_PATH",
97 "Specifies the path to the 'nuronssl' shared library",
98 ENGINE_CMD_FLAG_STRING},
99 {0, NULL, NULL, 0}
100 };
101
102typedef int tfnModExp(BIGNUM *r,const BIGNUM *a,const BIGNUM *p,const BIGNUM *m);
103static tfnModExp *pfnModExp = NULL;
104
105static DSO *pvDSOHandle = NULL;
106
107static int nuron_destroy(ENGINE *e)
108 {
109 free_NURON_LIBNAME();
110 ERR_unload_NURON_strings();
111 return 1;
112 }
113
114static int nuron_init(ENGINE *e)
115 {
116 if(pvDSOHandle != NULL)
117 {
118 NURONerr(NURON_F_NURON_INIT,NURON_R_ALREADY_LOADED);
119 return 0;
120 }
121
122 pvDSOHandle = DSO_load(NULL, get_NURON_LIBNAME(), NULL,
123 DSO_FLAG_NAME_TRANSLATION_EXT_ONLY);
124 if(!pvDSOHandle)
125 {
126 NURONerr(NURON_F_NURON_INIT,NURON_R_DSO_NOT_FOUND);
127 return 0;
128 }
129
130 pfnModExp = (tfnModExp *)DSO_bind_func(pvDSOHandle, NURON_F1);
131 if(!pfnModExp)
132 {
133 NURONerr(NURON_F_NURON_INIT,NURON_R_DSO_FUNCTION_NOT_FOUND);
134 return 0;
135 }
136
137 return 1;
138 }
139
140static int nuron_finish(ENGINE *e)
141 {
142 free_NURON_LIBNAME();
143 if(pvDSOHandle == NULL)
144 {
145 NURONerr(NURON_F_NURON_FINISH,NURON_R_NOT_LOADED);
146 return 0;
147 }
148 if(!DSO_free(pvDSOHandle))
149 {
150 NURONerr(NURON_F_NURON_FINISH,NURON_R_DSO_FAILURE);
151 return 0;
152 }
153 pvDSOHandle=NULL;
154 pfnModExp=NULL;
155 return 1;
156 }
157
158static int nuron_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)())
159 {
160 int initialised = ((pvDSOHandle == NULL) ? 0 : 1);
161 switch(cmd)
162 {
163 case NURON_CMD_SO_PATH:
164 if(p == NULL)
165 {
166 NURONerr(NURON_F_NURON_CTRL,ERR_R_PASSED_NULL_PARAMETER);
167 return 0;
168 }
169 if(initialised)
170 {
171 NURONerr(NURON_F_NURON_CTRL,NURON_R_ALREADY_LOADED);
172 return 0;
173 }
174 return set_NURON_LIBNAME((const char *)p);
175 default:
176 break;
177 }
178 NURONerr(NURON_F_NURON_CTRL,NURON_R_CTRL_COMMAND_NOT_IMPLEMENTED);
179 return 0;
180}
181
182static int nuron_mod_exp(BIGNUM *r,const BIGNUM *a,const BIGNUM *p,
183 const BIGNUM *m,BN_CTX *ctx)
184 {
185 if(!pvDSOHandle)
186 {
187 NURONerr(NURON_F_NURON_MOD_EXP,NURON_R_NOT_LOADED);
188 return 0;
189 }
190 return pfnModExp(r,a,p,m);
191 }
192
193#ifndef OPENSSL_NO_RSA
194static int nuron_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa)
195 {
196 return nuron_mod_exp(r0,I,rsa->d,rsa->n,NULL);
197 }
198#endif
199
200#ifndef OPENSSL_NO_DSA
201/* This code was liberated and adapted from the commented-out code in
202 * dsa_ossl.c. Because of the unoptimised form of the Atalla acceleration
203 * (it doesn't have a CRT form for RSA), this function means that an
204 * Atalla system running with a DSA server certificate can handshake
205 * around 5 or 6 times faster/more than an equivalent system running with
206 * RSA. Just check out the "signs" statistics from the RSA and DSA parts
207 * of "openssl speed -engine atalla dsa1024 rsa1024". */
208static int nuron_dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1,
209 BIGNUM *p1, BIGNUM *a2, BIGNUM *p2, BIGNUM *m,
210 BN_CTX *ctx, BN_MONT_CTX *in_mont)
211 {
212 BIGNUM t;
213 int to_return = 0;
214
215 BN_init(&t);
216 /* let rr = a1 ^ p1 mod m */
217 if (!nuron_mod_exp(rr,a1,p1,m,ctx))
218 goto end;
219 /* let t = a2 ^ p2 mod m */
220 if (!nuron_mod_exp(&t,a2,p2,m,ctx))
221 goto end;
222 /* let rr = rr * t mod m */
223 if (!BN_mod_mul(rr,rr,&t,m,ctx))
224 goto end;
225 to_return = 1;
226end:
227 BN_free(&t);
228 return to_return;
229 }
230
231
232static int nuron_mod_exp_dsa(DSA *dsa, BIGNUM *r, BIGNUM *a,
233 const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
234 BN_MONT_CTX *m_ctx)
235 {
236 return nuron_mod_exp(r, a, p, m, ctx);
237 }
238#endif
239
240/* This function is aliased to mod_exp (with the mont stuff dropped). */
241static int nuron_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
242 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
243 {
244 return nuron_mod_exp(r, a, p, m, ctx);
245 }
246
247#ifndef OPENSSL_NO_DH
248/* This function is aliased to mod_exp (with the dh and mont dropped). */
249static int nuron_mod_exp_dh(const DH *dh, BIGNUM *r,
250 const BIGNUM *a, const BIGNUM *p,
251 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
252 {
253 return nuron_mod_exp(r, a, p, m, ctx);
254 }
255#endif
256
257#ifndef OPENSSL_NO_RSA
258static RSA_METHOD nuron_rsa =
259 {
260 "Nuron RSA method",
261 NULL,
262 NULL,
263 NULL,
264 NULL,
265 nuron_rsa_mod_exp,
266 nuron_mod_exp_mont,
267 NULL,
268 NULL,
269 0,
270 NULL,
271 NULL,
272 NULL
273 };
274#endif
275
276#ifndef OPENSSL_NO_DSA
277static DSA_METHOD nuron_dsa =
278 {
279 "Nuron DSA method",
280 NULL, /* dsa_do_sign */
281 NULL, /* dsa_sign_setup */
282 NULL, /* dsa_do_verify */
283 nuron_dsa_mod_exp, /* dsa_mod_exp */
284 nuron_mod_exp_dsa, /* bn_mod_exp */
285 NULL, /* init */
286 NULL, /* finish */
287 0, /* flags */
288 NULL /* app_data */
289 };
290#endif
291
292#ifndef OPENSSL_NO_DH
293static DH_METHOD nuron_dh =
294 {
295 "Nuron DH method",
296 NULL,
297 NULL,
298 nuron_mod_exp_dh,
299 NULL,
300 NULL,
301 0,
302 NULL
303 };
304#endif
305
306/* Constants used when creating the ENGINE */
307static const char *engine_nuron_id = "nuron";
308static const char *engine_nuron_name = "Nuron hardware engine support";
309
310/* This internal function is used by ENGINE_nuron() and possibly by the
311 * "dynamic" ENGINE support too */
312static int bind_helper(ENGINE *e)
313 {
314#ifndef OPENSSL_NO_RSA
315 const RSA_METHOD *meth1;
316#endif
317#ifndef OPENSSL_NO_DSA
318 const DSA_METHOD *meth2;
319#endif
320#ifndef OPENSSL_NO_DH
321 const DH_METHOD *meth3;
322#endif
323 if(!ENGINE_set_id(e, engine_nuron_id) ||
324 !ENGINE_set_name(e, engine_nuron_name) ||
325#ifndef OPENSSL_NO_RSA
326 !ENGINE_set_RSA(e, &nuron_rsa) ||
327#endif
328#ifndef OPENSSL_NO_DSA
329 !ENGINE_set_DSA(e, &nuron_dsa) ||
330#endif
331#ifndef OPENSSL_NO_DH
332 !ENGINE_set_DH(e, &nuron_dh) ||
333#endif
334 !ENGINE_set_destroy_function(e, nuron_destroy) ||
335 !ENGINE_set_init_function(e, nuron_init) ||
336 !ENGINE_set_finish_function(e, nuron_finish) ||
337 !ENGINE_set_ctrl_function(e, nuron_ctrl) ||
338 !ENGINE_set_cmd_defns(e, nuron_cmd_defns))
339 return 0;
340
341#ifndef OPENSSL_NO_RSA
342 /* We know that the "PKCS1_SSLeay()" functions hook properly
343 * to the nuron-specific mod_exp and mod_exp_crt so we use
344 * those functions. NB: We don't use ENGINE_openssl() or
345 * anything "more generic" because something like the RSAref
346 * code may not hook properly, and if you own one of these
347 * cards then you have the right to do RSA operations on it
348 * anyway! */
349 meth1=RSA_PKCS1_SSLeay();
350 nuron_rsa.rsa_pub_enc=meth1->rsa_pub_enc;
351 nuron_rsa.rsa_pub_dec=meth1->rsa_pub_dec;
352 nuron_rsa.rsa_priv_enc=meth1->rsa_priv_enc;
353 nuron_rsa.rsa_priv_dec=meth1->rsa_priv_dec;
354#endif
355
356#ifndef OPENSSL_NO_DSA
357 /* Use the DSA_OpenSSL() method and just hook the mod_exp-ish
358 * bits. */
359 meth2=DSA_OpenSSL();
360 nuron_dsa.dsa_do_sign=meth2->dsa_do_sign;
361 nuron_dsa.dsa_sign_setup=meth2->dsa_sign_setup;
362 nuron_dsa.dsa_do_verify=meth2->dsa_do_verify;
363#endif
364
365#ifndef OPENSSL_NO_DH
366 /* Much the same for Diffie-Hellman */
367 meth3=DH_OpenSSL();
368 nuron_dh.generate_key=meth3->generate_key;
369 nuron_dh.compute_key=meth3->compute_key;
370#endif
371
372 /* Ensure the nuron error handling is set up */
373 ERR_load_NURON_strings();
374 return 1;
375 }
376
377#ifndef ENGINE_DYNAMIC_SUPPORT
378static ENGINE *engine_nuron(void)
379 {
380 ENGINE *ret = ENGINE_new();
381 if(!ret)
382 return NULL;
383 if(!bind_helper(ret))
384 {
385 ENGINE_free(ret);
386 return NULL;
387 }
388 return ret;
389 }
390
391void ENGINE_load_nuron(void)
392 {
393 /* Copied from eng_[openssl|dyn].c */
394 ENGINE *toadd = engine_nuron();
395 if(!toadd) return;
396 ENGINE_add(toadd);
397 ENGINE_free(toadd);
398 ERR_clear_error();
399 }
400#endif
401
402/* This stuff is needed if this ENGINE is being compiled into a self-contained
403 * shared-library. */
404#ifdef ENGINE_DYNAMIC_SUPPORT
405static int bind_fn(ENGINE *e, const char *id)
406 {
407 if(id && (strcmp(id, engine_nuron_id) != 0))
408 return 0;
409 if(!bind_helper(e))
410 return 0;
411 return 1;
412 }
413IMPLEMENT_DYNAMIC_CHECK_FN()
414IMPLEMENT_DYNAMIC_BIND_FN(bind_fn)
415#endif /* ENGINE_DYNAMIC_SUPPORT */
416
417#endif /* !OPENSSL_NO_HW_NURON */
418#endif /* !OPENSSL_NO_HW */
diff --git a/src/lib/libcrypto/engine/hw_sureware.c b/src/lib/libcrypto/engine/hw_sureware.c
deleted file mode 100644
index fca467e690..0000000000
--- a/src/lib/libcrypto/engine/hw_sureware.c
+++ /dev/null
@@ -1,1039 +0,0 @@
1/* Written by Corinne Dive-Reclus(cdive@baltimore.com)
2*
3*
4* Redistribution and use in source and binary forms, with or without
5* modification, are permitted provided that the following conditions
6* are met:
7*
8* 1. Redistributions of source code must retain the above copyright
9* notice, this list of conditions and the following disclaimer.
10*
11* 2. Redistributions in binary form must reproduce the above copyright
12* notice, this list of conditions and the following disclaimer in
13* the documentation and/or other materials provided with the
14* distribution.
15*
16* 3. All advertising materials mentioning features or use of this
17* software must display the following acknowledgment:
18* "This product includes software developed by the OpenSSL Project
19* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
20*
21* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
22* endorse or promote products derived from this software without
23* prior written permission. For written permission, please contact
24* licensing@OpenSSL.org.
25*
26* 5. Products derived from this software may not be called "OpenSSL"
27* nor may "OpenSSL" appear in their names without prior written
28* permission of the OpenSSL Project.
29*
30* 6. Redistributions of any form whatsoever must retain the following
31* acknowledgment:
32* "This product includes software developed by the OpenSSL Project
33* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
34*
35* Written by Corinne Dive-Reclus(cdive@baltimore.com)
36*
37* Copyright@2001 Baltimore Technologies Ltd.
38* All right Reserved.
39* *
40* THIS FILE IS PROVIDED BY BALTIMORE TECHNOLOGIES ``AS IS'' AND *
41* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE *
42* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE *
43* ARE DISCLAIMED. IN NO EVENT SHALL BALTIMORE TECHNOLOGIES BE LIABLE *
44* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL *
45* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS *
46* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) *
47* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT *
48* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY *
49* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF *
50* SUCH DAMAGE. *
51====================================================================*/
52
53#include <stdio.h>
54#include "cryptlib.h"
55#include <openssl/crypto.h>
56#include <openssl/pem.h>
57#include <openssl/dso.h>
58#include "eng_int.h"
59#include "engine.h"
60#include <openssl/engine.h>
61
62#ifndef OPENSSL_NO_HW
63#ifndef OPENSSL_NO_HW_SUREWARE
64
65#ifdef FLAT_INC
66#include "sureware.h"
67#else
68#include "vendor_defns/sureware.h"
69#endif
70
71#define SUREWARE_LIB_NAME "sureware engine"
72#include "hw_sureware_err.c"
73
74static int surewarehk_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)());
75static int surewarehk_destroy(ENGINE *e);
76static int surewarehk_init(ENGINE *e);
77static int surewarehk_finish(ENGINE *e);
78static int surewarehk_modexp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
79 const BIGNUM *m, BN_CTX *ctx);
80
81/* RSA stuff */
82static int surewarehk_rsa_priv_dec(int flen,const unsigned char *from,unsigned char *to,
83 RSA *rsa,int padding);
84static int surewarehk_rsa_sign(int flen,const unsigned char *from,unsigned char *to,
85 RSA *rsa,int padding);
86
87/* RAND stuff */
88static int surewarehk_rand_bytes(unsigned char *buf, int num);
89static void surewarehk_rand_seed(const void *buf, int num);
90static void surewarehk_rand_add(const void *buf, int num, double entropy);
91
92/* KM stuff */
93static EVP_PKEY *surewarehk_load_privkey(ENGINE *e, const char *key_id,
94 UI_METHOD *ui_method, void *callback_data);
95static EVP_PKEY *surewarehk_load_pubkey(ENGINE *e, const char *key_id,
96 UI_METHOD *ui_method, void *callback_data);
97static void surewarehk_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad,
98 int idx,long argl, void *argp);
99#if 0
100static void surewarehk_dh_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad,
101 int idx,long argl, void *argp);
102#endif
103
104#ifndef OPENSSL_NO_RSA
105/* This function is aliased to mod_exp (with the mont stuff dropped). */
106static int surewarehk_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
107 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
108{
109 return surewarehk_modexp(r, a, p, m, ctx);
110}
111
112/* Our internal RSA_METHOD that we provide pointers to */
113static RSA_METHOD surewarehk_rsa =
114 {
115 "SureWare RSA method",
116 NULL, /* pub_enc*/
117 NULL, /* pub_dec*/
118 surewarehk_rsa_sign, /* our rsa_sign is OpenSSL priv_enc*/
119 surewarehk_rsa_priv_dec, /* priv_dec*/
120 NULL, /*mod_exp*/
121 surewarehk_mod_exp_mont, /*mod_exp_mongomery*/
122 NULL, /* init*/
123 NULL, /* finish*/
124 0, /* RSA flag*/
125 NULL,
126 NULL, /* OpenSSL sign*/
127 NULL /* OpenSSL verify*/
128 };
129#endif
130
131#ifndef OPENSSL_NO_DH
132/* Our internal DH_METHOD that we provide pointers to */
133/* This function is aliased to mod_exp (with the dh and mont dropped). */
134static int surewarehk_modexp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a,
135 const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
136{
137 return surewarehk_modexp(r, a, p, m, ctx);
138}
139
140static DH_METHOD surewarehk_dh =
141 {
142 "SureWare DH method",
143 NULL,/*gen_key*/
144 NULL,/*agree,*/
145 surewarehk_modexp_dh, /*dh mod exp*/
146 NULL, /* init*/
147 NULL, /* finish*/
148 0, /* flags*/
149 NULL
150 };
151#endif
152
153static RAND_METHOD surewarehk_rand =
154 {
155 /* "SureWare RAND method", */
156 surewarehk_rand_seed,
157 surewarehk_rand_bytes,
158 NULL,/*cleanup*/
159 surewarehk_rand_add,
160 surewarehk_rand_bytes,
161 NULL,/*rand_status*/
162 };
163
164#ifndef OPENSSL_NO_DSA
165/* DSA stuff */
166static DSA_SIG * surewarehk_dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa);
167static int surewarehk_dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1,
168 BIGNUM *p1, BIGNUM *a2, BIGNUM *p2, BIGNUM *m,
169 BN_CTX *ctx, BN_MONT_CTX *in_mont)
170{
171 BIGNUM t;
172 int to_return = 0;
173 BN_init(&t);
174 /* let rr = a1 ^ p1 mod m */
175 if (!surewarehk_modexp(rr,a1,p1,m,ctx)) goto end;
176 /* let t = a2 ^ p2 mod m */
177 if (!surewarehk_modexp(&t,a2,p2,m,ctx)) goto end;
178 /* let rr = rr * t mod m */
179 if (!BN_mod_mul(rr,rr,&t,m,ctx)) goto end;
180 to_return = 1;
181end:
182 BN_free(&t);
183 return to_return;
184}
185
186static DSA_METHOD surewarehk_dsa =
187 {
188 "SureWare DSA method",
189 surewarehk_dsa_do_sign,
190 NULL,/*sign setup*/
191 NULL,/*verify,*/
192 surewarehk_dsa_mod_exp,/*mod exp*/
193 NULL,/*bn mod exp*/
194 NULL, /*init*/
195 NULL,/*finish*/
196 0,
197 NULL,
198 };
199#endif
200
201static const char *engine_sureware_id = "sureware";
202static const char *engine_sureware_name = "SureWare hardware engine support";
203
204/* Now, to our own code */
205
206/* As this is only ever called once, there's no need for locking
207 * (indeed - the lock will already be held by our caller!!!) */
208static int bind_sureware(ENGINE *e)
209{
210#ifndef OPENSSL_NO_RSA
211 const RSA_METHOD *meth1;
212#endif
213#ifndef OPENSSL_NO_DSA
214 const DSA_METHOD *meth2;
215#endif
216#ifndef OPENSSL_NO_DH
217 const DH_METHOD *meth3;
218#endif
219
220 if(!ENGINE_set_id(e, engine_sureware_id) ||
221 !ENGINE_set_name(e, engine_sureware_name) ||
222#ifndef OPENSSL_NO_RSA
223 !ENGINE_set_RSA(e, &surewarehk_rsa) ||
224#endif
225#ifndef OPENSSL_NO_DSA
226 !ENGINE_set_DSA(e, &surewarehk_dsa) ||
227#endif
228#ifndef OPENSSL_NO_DH
229 !ENGINE_set_DH(e, &surewarehk_dh) ||
230#endif
231 !ENGINE_set_RAND(e, &surewarehk_rand) ||
232 !ENGINE_set_destroy_function(e, surewarehk_destroy) ||
233 !ENGINE_set_init_function(e, surewarehk_init) ||
234 !ENGINE_set_finish_function(e, surewarehk_finish) ||
235 !ENGINE_set_ctrl_function(e, surewarehk_ctrl) ||
236 !ENGINE_set_load_privkey_function(e, surewarehk_load_privkey) ||
237 !ENGINE_set_load_pubkey_function(e, surewarehk_load_pubkey))
238 return 0;
239
240#ifndef OPENSSL_NO_RSA
241 /* We know that the "PKCS1_SSLeay()" functions hook properly
242 * to the cswift-specific mod_exp and mod_exp_crt so we use
243 * those functions. NB: We don't use ENGINE_openssl() or
244 * anything "more generic" because something like the RSAref
245 * code may not hook properly, and if you own one of these
246 * cards then you have the right to do RSA operations on it
247 * anyway! */
248 meth1 = RSA_PKCS1_SSLeay();
249 if (meth1)
250 {
251 surewarehk_rsa.rsa_pub_enc = meth1->rsa_pub_enc;
252 surewarehk_rsa.rsa_pub_dec = meth1->rsa_pub_dec;
253 }
254#endif
255
256#ifndef OPENSSL_NO_DSA
257 /* Use the DSA_OpenSSL() method and just hook the mod_exp-ish
258 * bits. */
259 meth2 = DSA_OpenSSL();
260 if (meth2)
261 {
262 surewarehk_dsa.dsa_do_verify = meth2->dsa_do_verify;
263 }
264#endif
265
266#ifndef OPENSSL_NO_DH
267 /* Much the same for Diffie-Hellman */
268 meth3 = DH_OpenSSL();
269 if (meth3)
270 {
271 surewarehk_dh.generate_key = meth3->generate_key;
272 surewarehk_dh.compute_key = meth3->compute_key;
273 }
274#endif
275
276 /* Ensure the sureware error handling is set up */
277 ERR_load_SUREWARE_strings();
278 return 1;
279}
280
281#ifdef ENGINE_DYNAMIC_SUPPORT
282static int bind_helper(ENGINE *e, const char *id)
283 {
284 if(id && (strcmp(id, engine_sureware_id) != 0))
285 return 0;
286 if(!bind_sureware(e))
287 return 0;
288 return 1;
289 }
290IMPLEMENT_DYNAMIC_CHECK_FN()
291IMPLEMENT_DYNAMIC_BIND_FN(bind_helper)
292#else
293static ENGINE *engine_sureware(void)
294 {
295 ENGINE *ret = ENGINE_new();
296 if(!ret)
297 return NULL;
298 if(!bind_sureware(ret))
299 {
300 ENGINE_free(ret);
301 return NULL;
302 }
303 return ret;
304 }
305
306void ENGINE_load_sureware(void)
307 {
308 /* Copied from eng_[openssl|dyn].c */
309 ENGINE *toadd = engine_sureware();
310 if(!toadd) return;
311 ENGINE_add(toadd);
312 ENGINE_free(toadd);
313 ERR_clear_error();
314 }
315#endif
316
317/* This is a process-global DSO handle used for loading and unloading
318 * the SureWareHook 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 *surewarehk_dso = NULL;
323#ifndef OPENSSL_NO_RSA
324static int rsaHndidx = -1; /* Index for KM handle. Not really used yet. */
325#endif
326#ifndef OPENSSL_NO_DSA
327static int dsaHndidx = -1; /* Index for KM handle. Not really used yet. */
328#endif
329
330/* These are the function pointers that are (un)set when the library has
331 * successfully (un)loaded. */
332static SureWareHook_Init_t *p_surewarehk_Init = NULL;
333static SureWareHook_Finish_t *p_surewarehk_Finish = NULL;
334static SureWareHook_Rand_Bytes_t *p_surewarehk_Rand_Bytes = NULL;
335static SureWareHook_Rand_Seed_t *p_surewarehk_Rand_Seed = NULL;
336static SureWareHook_Load_Privkey_t *p_surewarehk_Load_Privkey = NULL;
337static SureWareHook_Info_Pubkey_t *p_surewarehk_Info_Pubkey = NULL;
338static SureWareHook_Load_Rsa_Pubkey_t *p_surewarehk_Load_Rsa_Pubkey = NULL;
339static SureWareHook_Load_Dsa_Pubkey_t *p_surewarehk_Load_Dsa_Pubkey = NULL;
340static SureWareHook_Free_t *p_surewarehk_Free=NULL;
341static SureWareHook_Rsa_Priv_Dec_t *p_surewarehk_Rsa_Priv_Dec=NULL;
342static SureWareHook_Rsa_Sign_t *p_surewarehk_Rsa_Sign=NULL;
343static SureWareHook_Dsa_Sign_t *p_surewarehk_Dsa_Sign=NULL;
344static SureWareHook_Mod_Exp_t *p_surewarehk_Mod_Exp=NULL;
345
346/* Used in the DSO operations. */
347static const char *surewarehk_LIBNAME = "SureWareHook";
348static const char *n_surewarehk_Init = "SureWareHook_Init";
349static const char *n_surewarehk_Finish = "SureWareHook_Finish";
350static const char *n_surewarehk_Rand_Bytes="SureWareHook_Rand_Bytes";
351static const char *n_surewarehk_Rand_Seed="SureWareHook_Rand_Seed";
352static const char *n_surewarehk_Load_Privkey="SureWareHook_Load_Privkey";
353static const char *n_surewarehk_Info_Pubkey="SureWareHook_Info_Pubkey";
354static const char *n_surewarehk_Load_Rsa_Pubkey="SureWareHook_Load_Rsa_Pubkey";
355static const char *n_surewarehk_Load_Dsa_Pubkey="SureWareHook_Load_Dsa_Pubkey";
356static const char *n_surewarehk_Free="SureWareHook_Free";
357static const char *n_surewarehk_Rsa_Priv_Dec="SureWareHook_Rsa_Priv_Dec";
358static const char *n_surewarehk_Rsa_Sign="SureWareHook_Rsa_Sign";
359static const char *n_surewarehk_Dsa_Sign="SureWareHook_Dsa_Sign";
360static const char *n_surewarehk_Mod_Exp="SureWareHook_Mod_Exp";
361static BIO *logstream = NULL;
362
363/* SureWareHook library functions and mechanics - these are used by the
364 * higher-level functions further down. NB: As and where there's no
365 * error checking, take a look lower down where these functions are
366 * called, the checking and error handling is probably down there.
367*/
368static int threadsafe=1;
369static int surewarehk_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)())
370{
371 int to_return = 1;
372
373 switch(cmd)
374 {
375 case ENGINE_CTRL_SET_LOGSTREAM:
376 {
377 BIO *bio = (BIO *)p;
378 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
379 if (logstream)
380 {
381 BIO_free(logstream);
382 logstream = NULL;
383 }
384 if (CRYPTO_add(&bio->references,1,CRYPTO_LOCK_BIO) > 1)
385 logstream = bio;
386 else
387 SUREWAREerr(SUREWARE_F_SUREWAREHK_CTRL,SUREWARE_R_BIO_WAS_FREED);
388 }
389 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
390 break;
391 /* This will prevent the initialisation function from "installing"
392 * the mutex-handling callbacks, even if they are available from
393 * within the library (or were provided to the library from the
394 * calling application). This is to remove any baggage for
395 * applications not using multithreading. */
396 case ENGINE_CTRL_CHIL_NO_LOCKING:
397 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
398 threadsafe = 0;
399 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
400 break;
401
402 /* The command isn't understood by this engine */
403 default:
404 SUREWAREerr(SUREWARE_F_SUREWAREHK_CTRL,
405 ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED);
406 to_return = 0;
407 break;
408 }
409
410 return to_return;
411}
412
413/* Destructor (complements the "ENGINE_surewarehk()" constructor) */
414static int surewarehk_destroy(ENGINE *e)
415{
416 ERR_unload_SUREWARE_strings();
417 return 1;
418}
419
420/* (de)initialisation functions. */
421static int surewarehk_init(ENGINE *e)
422{
423 char msg[64]="ENGINE_init";
424 SureWareHook_Init_t *p1=NULL;
425 SureWareHook_Finish_t *p2=NULL;
426 SureWareHook_Rand_Bytes_t *p3=NULL;
427 SureWareHook_Rand_Seed_t *p4=NULL;
428 SureWareHook_Load_Privkey_t *p5=NULL;
429 SureWareHook_Load_Rsa_Pubkey_t *p6=NULL;
430 SureWareHook_Free_t *p7=NULL;
431 SureWareHook_Rsa_Priv_Dec_t *p8=NULL;
432 SureWareHook_Rsa_Sign_t *p9=NULL;
433 SureWareHook_Dsa_Sign_t *p12=NULL;
434 SureWareHook_Info_Pubkey_t *p13=NULL;
435 SureWareHook_Load_Dsa_Pubkey_t *p14=NULL;
436 SureWareHook_Mod_Exp_t *p15=NULL;
437
438 if(surewarehk_dso != NULL)
439 {
440 SUREWAREerr(SUREWARE_F_SUREWAREHK_INIT,ENGINE_R_ALREADY_LOADED);
441 goto err;
442 }
443 /* Attempt to load libsurewarehk.so/surewarehk.dll/whatever. */
444 surewarehk_dso = DSO_load(NULL, surewarehk_LIBNAME, NULL, 0);
445 if(surewarehk_dso == NULL)
446 {
447 SUREWAREerr(SUREWARE_F_SUREWAREHK_INIT,ENGINE_R_DSO_FAILURE);
448 goto err;
449 }
450 if(!(p1=(SureWareHook_Init_t*)DSO_bind_func(surewarehk_dso, n_surewarehk_Init)) ||
451 !(p2=(SureWareHook_Finish_t*)DSO_bind_func(surewarehk_dso, n_surewarehk_Finish)) ||
452 !(p3=(SureWareHook_Rand_Bytes_t*)DSO_bind_func(surewarehk_dso, n_surewarehk_Rand_Bytes)) ||
453 !(p4=(SureWareHook_Rand_Seed_t*)DSO_bind_func(surewarehk_dso, n_surewarehk_Rand_Seed)) ||
454 !(p5=(SureWareHook_Load_Privkey_t*)DSO_bind_func(surewarehk_dso, n_surewarehk_Load_Privkey)) ||
455 !(p6=(SureWareHook_Load_Rsa_Pubkey_t*)DSO_bind_func(surewarehk_dso, n_surewarehk_Load_Rsa_Pubkey)) ||
456 !(p7=(SureWareHook_Free_t*)DSO_bind_func(surewarehk_dso, n_surewarehk_Free)) ||
457 !(p8=(SureWareHook_Rsa_Priv_Dec_t*)DSO_bind_func(surewarehk_dso, n_surewarehk_Rsa_Priv_Dec)) ||
458 !(p9=(SureWareHook_Rsa_Sign_t*)DSO_bind_func(surewarehk_dso, n_surewarehk_Rsa_Sign)) ||
459 !(p12=(SureWareHook_Dsa_Sign_t*)DSO_bind_func(surewarehk_dso, n_surewarehk_Dsa_Sign)) ||
460 !(p13=(SureWareHook_Info_Pubkey_t*)DSO_bind_func(surewarehk_dso, n_surewarehk_Info_Pubkey)) ||
461 !(p14=(SureWareHook_Load_Dsa_Pubkey_t*)DSO_bind_func(surewarehk_dso, n_surewarehk_Load_Dsa_Pubkey)) ||
462 !(p15=(SureWareHook_Mod_Exp_t*)DSO_bind_func(surewarehk_dso, n_surewarehk_Mod_Exp)))
463 {
464 SUREWAREerr(SUREWARE_F_SUREWAREHK_INIT,ENGINE_R_DSO_FAILURE);
465 goto err;
466 }
467 /* Copy the pointers */
468 p_surewarehk_Init = p1;
469 p_surewarehk_Finish = p2;
470 p_surewarehk_Rand_Bytes = p3;
471 p_surewarehk_Rand_Seed = p4;
472 p_surewarehk_Load_Privkey = p5;
473 p_surewarehk_Load_Rsa_Pubkey = p6;
474 p_surewarehk_Free = p7;
475 p_surewarehk_Rsa_Priv_Dec = p8;
476 p_surewarehk_Rsa_Sign = p9;
477 p_surewarehk_Dsa_Sign = p12;
478 p_surewarehk_Info_Pubkey = p13;
479 p_surewarehk_Load_Dsa_Pubkey = p14;
480 p_surewarehk_Mod_Exp = p15;
481 /* Contact the hardware and initialises it. */
482 if(p_surewarehk_Init(msg,threadsafe)==SUREWAREHOOK_ERROR_UNIT_FAILURE)
483 {
484 SUREWAREerr(SUREWARE_F_SUREWAREHK_INIT,SUREWARE_R_UNIT_FAILURE);
485 goto err;
486 }
487 if(p_surewarehk_Init(msg,threadsafe)==SUREWAREHOOK_ERROR_UNIT_FAILURE)
488 {
489 SUREWAREerr(SUREWARE_F_SUREWAREHK_INIT,SUREWARE_R_UNIT_FAILURE);
490 goto err;
491 }
492 /* try to load the default private key, if failed does not return a failure but
493 wait for an explicit ENGINE_load_privakey */
494 surewarehk_load_privkey(e,NULL,NULL,NULL);
495
496 /* Everything's fine. */
497#ifndef OPENSSL_NO_RSA
498 if (rsaHndidx == -1)
499 rsaHndidx = RSA_get_ex_new_index(0,
500 "SureWareHook RSA key handle",
501 NULL, NULL, surewarehk_ex_free);
502#endif
503#ifndef OPENSSL_NO_DSA
504 if (dsaHndidx == -1)
505 dsaHndidx = DSA_get_ex_new_index(0,
506 "SureWareHook DSA key handle",
507 NULL, NULL, surewarehk_ex_free);
508#endif
509
510 return 1;
511err:
512 if(surewarehk_dso)
513 DSO_free(surewarehk_dso);
514 surewarehk_dso = NULL;
515 p_surewarehk_Init = NULL;
516 p_surewarehk_Finish = NULL;
517 p_surewarehk_Rand_Bytes = NULL;
518 p_surewarehk_Rand_Seed = NULL;
519 p_surewarehk_Load_Privkey = NULL;
520 p_surewarehk_Load_Rsa_Pubkey = NULL;
521 p_surewarehk_Free = NULL;
522 p_surewarehk_Rsa_Priv_Dec = NULL;
523 p_surewarehk_Rsa_Sign = NULL;
524 p_surewarehk_Dsa_Sign = NULL;
525 p_surewarehk_Info_Pubkey = NULL;
526 p_surewarehk_Load_Dsa_Pubkey = NULL;
527 p_surewarehk_Mod_Exp = NULL;
528 return 0;
529}
530
531static int surewarehk_finish(ENGINE *e)
532{
533 int to_return = 1;
534 if(surewarehk_dso == NULL)
535 {
536 SUREWAREerr(SUREWARE_F_SUREWAREHK_FINISH,ENGINE_R_NOT_LOADED);
537 to_return = 0;
538 goto err;
539 }
540 p_surewarehk_Finish();
541 if(!DSO_free(surewarehk_dso))
542 {
543 SUREWAREerr(SUREWARE_F_SUREWAREHK_FINISH,ENGINE_R_DSO_FAILURE);
544 to_return = 0;
545 goto err;
546 }
547 err:
548 if (logstream)
549 BIO_free(logstream);
550 surewarehk_dso = NULL;
551 p_surewarehk_Init = NULL;
552 p_surewarehk_Finish = NULL;
553 p_surewarehk_Rand_Bytes = NULL;
554 p_surewarehk_Rand_Seed = NULL;
555 p_surewarehk_Load_Privkey = NULL;
556 p_surewarehk_Load_Rsa_Pubkey = NULL;
557 p_surewarehk_Free = NULL;
558 p_surewarehk_Rsa_Priv_Dec = NULL;
559 p_surewarehk_Rsa_Sign = NULL;
560 p_surewarehk_Dsa_Sign = NULL;
561 p_surewarehk_Info_Pubkey = NULL;
562 p_surewarehk_Load_Dsa_Pubkey = NULL;
563 p_surewarehk_Mod_Exp = NULL;
564 return to_return;
565}
566
567static void surewarehk_error_handling(char *const msg,int func,int ret)
568{
569 switch (ret)
570 {
571 case SUREWAREHOOK_ERROR_UNIT_FAILURE:
572 ENGINEerr(func,SUREWARE_R_UNIT_FAILURE);
573 break;
574 case SUREWAREHOOK_ERROR_FALLBACK:
575 ENGINEerr(func,SUREWARE_R_REQUEST_FALLBACK);
576 break;
577 case SUREWAREHOOK_ERROR_DATA_SIZE:
578 ENGINEerr(func,SUREWARE_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
579 break;
580 case SUREWAREHOOK_ERROR_INVALID_PAD:
581 ENGINEerr(func,RSA_R_PADDING_CHECK_FAILED);
582 break;
583 default:
584 ENGINEerr(func,SUREWARE_R_REQUEST_FAILED);
585 break;
586 case 1:/*nothing*/
587 msg[0]='\0';
588 }
589 if (*msg)
590 {
591 ERR_add_error_data(1,msg);
592 if (logstream)
593 {
594 CRYPTO_w_lock(CRYPTO_LOCK_BIO);
595 BIO_write(logstream, msg, strlen(msg));
596 CRYPTO_w_unlock(CRYPTO_LOCK_BIO);
597 }
598 }
599}
600
601static int surewarehk_rand_bytes(unsigned char *buf, int num)
602{
603 int ret=0;
604 char msg[64]="ENGINE_rand_bytes";
605 if(!p_surewarehk_Rand_Bytes)
606 {
607 SUREWAREerr(SUREWARE_F_SUREWAREHK_RAND_BYTES,ENGINE_R_NOT_INITIALISED);
608 }
609 else
610 {
611 ret = p_surewarehk_Rand_Bytes(msg,buf, num);
612 surewarehk_error_handling(msg,SUREWARE_F_SUREWAREHK_RAND_BYTES,ret);
613 }
614 return ret==1 ? 1 : 0;
615}
616
617static void surewarehk_rand_seed(const void *buf, int num)
618{
619 int ret=0;
620 char msg[64]="ENGINE_rand_seed";
621 if(!p_surewarehk_Rand_Seed)
622 {
623 SUREWAREerr(SUREWARE_F_SUREWAREHK_RAND_SEED,ENGINE_R_NOT_INITIALISED);
624 }
625 else
626 {
627 ret = p_surewarehk_Rand_Seed(msg,buf, num);
628 surewarehk_error_handling(msg,SUREWARE_F_SUREWAREHK_RAND_SEED,ret);
629 }
630}
631
632static void surewarehk_rand_add(const void *buf, int num, double entropy)
633{
634 surewarehk_rand_seed(buf,num);
635}
636
637static EVP_PKEY* sureware_load_public(ENGINE *e,const char *key_id,char *hptr,unsigned long el,char keytype)
638{
639 EVP_PKEY *res = NULL;
640#ifndef OPENSSL_NO_RSA
641 RSA *rsatmp = NULL;
642#endif
643#ifndef OPENSSL_NO_DSA
644 DSA *dsatmp=NULL;
645#endif
646 char msg[64]="sureware_load_public";
647 int ret=0;
648 if(!p_surewarehk_Load_Rsa_Pubkey || !p_surewarehk_Load_Dsa_Pubkey)
649 {
650 SUREWAREerr(SUREWARE_F_SUREWAREHK_LOAD_PUBLIC_KEY,ENGINE_R_NOT_INITIALISED);
651 goto err;
652 }
653 switch (keytype)
654 {
655#ifndef OPENSSL_NO_RSA
656 case 1: /*RSA*/
657 /* set private external reference */
658 rsatmp = RSA_new_method(e);
659 RSA_set_ex_data(rsatmp,rsaHndidx,hptr);
660 rsatmp->flags |= RSA_FLAG_EXT_PKEY;
661
662 /* set public big nums*/
663 rsatmp->e = BN_new();
664 rsatmp->n = BN_new();
665 bn_expand2(rsatmp->e, el/sizeof(BN_ULONG));
666 bn_expand2(rsatmp->n, el/sizeof(BN_ULONG));
667 if (!rsatmp->e || rsatmp->e->dmax!=(int)(el/sizeof(BN_ULONG))||
668 !rsatmp->n || rsatmp->n->dmax!=(int)(el/sizeof(BN_ULONG)))
669 goto err;
670 ret=p_surewarehk_Load_Rsa_Pubkey(msg,key_id,el,
671 (unsigned long *)rsatmp->n->d,
672 (unsigned long *)rsatmp->e->d);
673 surewarehk_error_handling(msg,SUREWARE_F_SUREWAREHK_LOAD_PUBLIC_KEY,ret);
674 if (ret!=1)
675 {
676 SUREWAREerr(SUREWARE_F_SUREWAREHK_LOAD_PRIVATE_KEY,ENGINE_R_FAILED_LOADING_PUBLIC_KEY);
677 goto err;
678 }
679 /* normalise pub e and pub n */
680 rsatmp->e->top=el/sizeof(BN_ULONG);
681 bn_fix_top(rsatmp->e);
682 rsatmp->n->top=el/sizeof(BN_ULONG);
683 bn_fix_top(rsatmp->n);
684 /* create an EVP object: engine + rsa key */
685 res = EVP_PKEY_new();
686 EVP_PKEY_assign_RSA(res, rsatmp);
687 break;
688#endif
689
690#ifndef OPENSSL_NO_DSA
691 case 2:/*DSA*/
692 /* set private/public external reference */
693 dsatmp = DSA_new_method(e);
694 DSA_set_ex_data(dsatmp,dsaHndidx,hptr);
695 /*dsatmp->flags |= DSA_FLAG_EXT_PKEY;*/
696
697 /* set public key*/
698 dsatmp->pub_key = BN_new();
699 dsatmp->p = BN_new();
700 dsatmp->q = BN_new();
701 dsatmp->g = BN_new();
702 bn_expand2(dsatmp->pub_key, el/sizeof(BN_ULONG));
703 bn_expand2(dsatmp->p, el/sizeof(BN_ULONG));
704 bn_expand2(dsatmp->q, 20/sizeof(BN_ULONG));
705 bn_expand2(dsatmp->g, el/sizeof(BN_ULONG));
706 if (!dsatmp->pub_key || dsatmp->pub_key->dmax!=(int)(el/sizeof(BN_ULONG))||
707 !dsatmp->p || dsatmp->p->dmax!=(int)(el/sizeof(BN_ULONG)) ||
708 !dsatmp->q || dsatmp->q->dmax!=20/sizeof(BN_ULONG) ||
709 !dsatmp->g || dsatmp->g->dmax!=(int)(el/sizeof(BN_ULONG)))
710 goto err;
711
712 ret=p_surewarehk_Load_Dsa_Pubkey(msg,key_id,el,
713 (unsigned long *)dsatmp->pub_key->d,
714 (unsigned long *)dsatmp->p->d,
715 (unsigned long *)dsatmp->q->d,
716 (unsigned long *)dsatmp->g->d);
717 surewarehk_error_handling(msg,SUREWARE_F_SUREWAREHK_LOAD_PUBLIC_KEY,ret);
718 if (ret!=1)
719 {
720 SUREWAREerr(SUREWARE_F_SUREWAREHK_LOAD_PRIVATE_KEY,ENGINE_R_FAILED_LOADING_PUBLIC_KEY);
721 goto err;
722 }
723 /* set parameters */
724 /* normalise pubkey and parameters in case of */
725 dsatmp->pub_key->top=el/sizeof(BN_ULONG);
726 bn_fix_top(dsatmp->pub_key);
727 dsatmp->p->top=el/sizeof(BN_ULONG);
728 bn_fix_top(dsatmp->p);
729 dsatmp->q->top=20/sizeof(BN_ULONG);
730 bn_fix_top(dsatmp->q);
731 dsatmp->g->top=el/sizeof(BN_ULONG);
732 bn_fix_top(dsatmp->g);
733
734 /* create an EVP object: engine + rsa key */
735 res = EVP_PKEY_new();
736 EVP_PKEY_assign_DSA(res, dsatmp);
737 break;
738#endif
739
740 default:
741 SUREWAREerr(SUREWARE_F_SUREWAREHK_LOAD_PRIVATE_KEY,ENGINE_R_FAILED_LOADING_PRIVATE_KEY);
742 goto err;
743 }
744 return res;
745 err:
746 if (res)
747 EVP_PKEY_free(res);
748#ifndef OPENSSL_NO_RSA
749 if (rsatmp)
750 RSA_free(rsatmp);
751#endif
752#ifndef OPENSSL_NO_DSA
753 if (dsatmp)
754 DSA_free(dsatmp);
755#endif
756 return NULL;
757}
758
759static EVP_PKEY *surewarehk_load_privkey(ENGINE *e, const char *key_id,
760 UI_METHOD *ui_method, void *callback_data)
761{
762 EVP_PKEY *res = NULL;
763 int ret=0;
764 unsigned long el=0;
765 char *hptr=NULL;
766 char keytype=0;
767 char msg[64]="ENGINE_load_privkey";
768
769 if(!p_surewarehk_Load_Privkey)
770 {
771 SUREWAREerr(SUREWARE_F_SUREWAREHK_LOAD_PRIVATE_KEY,ENGINE_R_NOT_INITIALISED);
772 }
773 else
774 {
775 ret=p_surewarehk_Load_Privkey(msg,key_id,&hptr,&el,&keytype);
776 if (ret!=1)
777 {
778 SUREWAREerr(SUREWARE_F_SUREWAREHK_LOAD_PRIVATE_KEY,ENGINE_R_FAILED_LOADING_PRIVATE_KEY);
779 ERR_add_error_data(1,msg);
780 }
781 else
782 res=sureware_load_public(e,key_id,hptr,el,keytype);
783 }
784 return res;
785}
786
787static EVP_PKEY *surewarehk_load_pubkey(ENGINE *e, const char *key_id,
788 UI_METHOD *ui_method, void *callback_data)
789{
790 EVP_PKEY *res = NULL;
791 int ret=0;
792 unsigned long el=0;
793 char *hptr=NULL;
794 char keytype=0;
795 char msg[64]="ENGINE_load_pubkey";
796
797 if(!p_surewarehk_Info_Pubkey)
798 {
799 SUREWAREerr(SUREWARE_F_SUREWAREHK_LOAD_PUBLIC_KEY,ENGINE_R_NOT_INITIALISED);
800 }
801 else
802 {
803 /* call once to identify if DSA or RSA */
804 ret=p_surewarehk_Info_Pubkey(msg,key_id,&el,&keytype);
805 if (ret!=1)
806 {
807 SUREWAREerr(SUREWARE_F_SUREWAREHK_LOAD_PUBLIC_KEY,ENGINE_R_FAILED_LOADING_PUBLIC_KEY);
808 ERR_add_error_data(1,msg);
809 }
810 else
811 res=sureware_load_public(e,key_id,hptr,el,keytype);
812 }
813 return res;
814}
815
816/* This cleans up an RSA/DSA KM key(do not destroy the key into the hardware)
817, called when ex_data is freed */
818static void surewarehk_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad,
819 int idx,long argl, void *argp)
820{
821 if(!p_surewarehk_Free)
822 {
823 SUREWAREerr(SUREWARE_F_SUREWAREHK_EX_FREE,ENGINE_R_NOT_INITIALISED);
824 }
825 else
826 p_surewarehk_Free((char *)item,0);
827}
828
829#if 0
830/* This cleans up an DH KM key (destroys the key into hardware),
831called when ex_data is freed */
832static void surewarehk_dh_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad,
833 int idx,long argl, void *argp)
834{
835 if(!p_surewarehk_Free)
836 {
837 SUREWAREerr(SUREWARE_F_SUREWAREHK_EX_FREE,ENGINE_R_NOT_INITIALISED);
838 }
839 else
840 p_surewarehk_Free((char *)item,1);
841}
842#endif
843
844/*
845* return number of decrypted bytes
846*/
847#ifndef OPENSSL_NO_RSA
848static int surewarehk_rsa_priv_dec(int flen,const unsigned char *from,unsigned char *to,
849 RSA *rsa,int padding)
850{
851 int ret=0,tlen;
852 char *buf=NULL,*hptr=NULL;
853 char msg[64]="ENGINE_rsa_priv_dec";
854 if (!p_surewarehk_Rsa_Priv_Dec)
855 {
856 SUREWAREerr(SUREWARE_F_SUREWAREHK_RSA_PRIV_DEC,ENGINE_R_NOT_INITIALISED);
857 }
858 /* extract ref to private key */
859 else if (!(hptr=RSA_get_ex_data(rsa, rsaHndidx)))
860 {
861 SUREWAREerr(SUREWARE_F_SUREWAREHK_RSA_PRIV_DEC,SUREWARE_R_MISSING_KEY_COMPONENTS);
862 goto err;
863 }
864 /* analyse what padding we can do into the hardware */
865 if (padding==RSA_PKCS1_PADDING)
866 {
867 /* do it one shot */
868 ret=p_surewarehk_Rsa_Priv_Dec(msg,flen,(unsigned char *)from,&tlen,to,hptr,SUREWARE_PKCS1_PAD);
869 surewarehk_error_handling(msg,SUREWARE_F_SUREWAREHK_RSA_PRIV_DEC,ret);
870 if (ret!=1)
871 goto err;
872 ret=tlen;
873 }
874 else /* do with no padding into hardware */
875 {
876 ret=p_surewarehk_Rsa_Priv_Dec(msg,flen,(unsigned char *)from,&tlen,to,hptr,SUREWARE_NO_PAD);
877 surewarehk_error_handling(msg,SUREWARE_F_SUREWAREHK_RSA_PRIV_DEC,ret);
878 if (ret!=1)
879 goto err;
880 /* intermediate buffer for padding */
881 if ((buf=OPENSSL_malloc(tlen)) == NULL)
882 {
883 RSAerr(SUREWARE_F_SUREWAREHK_RSA_PRIV_DEC,ERR_R_MALLOC_FAILURE);
884 goto err;
885 }
886 memcpy(buf,to,tlen);/* transfert to into buf */
887 switch (padding) /* check padding in software */
888 {
889#ifndef OPENSSL_NO_SHA
890 case RSA_PKCS1_OAEP_PADDING:
891 ret=RSA_padding_check_PKCS1_OAEP(to,tlen,(unsigned char *)buf,tlen,tlen,NULL,0);
892 break;
893#endif
894 case RSA_SSLV23_PADDING:
895 ret=RSA_padding_check_SSLv23(to,tlen,(unsigned char *)buf,flen,tlen);
896 break;
897 case RSA_NO_PADDING:
898 ret=RSA_padding_check_none(to,tlen,(unsigned char *)buf,flen,tlen);
899 break;
900 default:
901 RSAerr(SUREWARE_F_SUREWAREHK_RSA_PRIV_DEC,RSA_R_UNKNOWN_PADDING_TYPE);
902 goto err;
903 }
904 if (ret < 0)
905 RSAerr(SUREWARE_F_SUREWAREHK_RSA_PRIV_DEC,RSA_R_PADDING_CHECK_FAILED);
906 }
907err:
908 if (buf)
909 {
910 OPENSSL_cleanse(buf,tlen);
911 OPENSSL_free(buf);
912 }
913 return ret;
914}
915
916/*
917* Does what OpenSSL rsa_priv_enc does.
918*/
919static int surewarehk_rsa_sign(int flen,const unsigned char *from,unsigned char *to,
920 RSA *rsa,int padding)
921{
922 int ret=0,tlen;
923 char *hptr=NULL;
924 char msg[64]="ENGINE_rsa_sign";
925 if (!p_surewarehk_Rsa_Sign)
926 {
927 SUREWAREerr(SUREWARE_F_SUREWAREHK_RSA_PRIV_ENC,ENGINE_R_NOT_INITIALISED);
928 }
929 /* extract ref to private key */
930 else if (!(hptr=RSA_get_ex_data(rsa, rsaHndidx)))
931 {
932 SUREWAREerr(SUREWARE_F_SUREWAREHK_RSA_PRIV_ENC,SUREWARE_R_MISSING_KEY_COMPONENTS);
933 }
934 else
935 {
936 switch (padding)
937 {
938 case RSA_PKCS1_PADDING: /* do it in one shot */
939 ret=p_surewarehk_Rsa_Sign(msg,flen,(unsigned char *)from,&tlen,to,hptr,SUREWARE_PKCS1_PAD);
940 surewarehk_error_handling(msg,SUREWARE_F_SUREWAREHK_RSA_PRIV_ENC,ret);
941 break;
942 case RSA_NO_PADDING:
943 default:
944 RSAerr(SUREWARE_F_SUREWAREHK_RSA_PRIV_ENC,RSA_R_UNKNOWN_PADDING_TYPE);
945 }
946 }
947 return ret==1 ? tlen : ret;
948}
949
950#endif
951
952#ifndef OPENSSL_NO_DSA
953/* DSA sign and verify */
954static DSA_SIG * surewarehk_dsa_do_sign(const unsigned char *from, int flen, DSA *dsa)
955{
956 int ret=0;
957 char *hptr=NULL;
958 DSA_SIG *psign=NULL;
959 char msg[64]="ENGINE_dsa_do_sign";
960 if (!p_surewarehk_Dsa_Sign)
961 {
962 SUREWAREerr(SUREWARE_F_SUREWAREHK_DSA_DO_SIGN,ENGINE_R_NOT_INITIALISED);
963 }
964 /* extract ref to private key */
965 else if (!(hptr=DSA_get_ex_data(dsa, dsaHndidx)))
966 {
967 SUREWAREerr(SUREWARE_F_SUREWAREHK_DSA_DO_SIGN,SUREWARE_R_MISSING_KEY_COMPONENTS);
968 }
969 else
970 {
971 if((psign = DSA_SIG_new()) == NULL)
972 {
973 SUREWAREerr(SUREWARE_F_SUREWAREHK_DSA_DO_SIGN,ERR_R_MALLOC_FAILURE);
974 goto err;
975 }
976 psign->r=BN_new();
977 psign->s=BN_new();
978 bn_expand2(psign->r, 20/sizeof(BN_ULONG));
979 bn_expand2(psign->s, 20/sizeof(BN_ULONG));
980 if (!psign->r || psign->r->dmax!=20/sizeof(BN_ULONG) ||
981 !psign->s || psign->s->dmax!=20/sizeof(BN_ULONG))
982 goto err;
983 ret=p_surewarehk_Dsa_Sign(msg,flen,from,
984 (unsigned long *)psign->r->d,
985 (unsigned long *)psign->s->d,
986 hptr);
987 surewarehk_error_handling(msg,SUREWARE_F_SUREWAREHK_DSA_DO_SIGN,ret);
988 }
989 psign->r->top=20/sizeof(BN_ULONG);
990 bn_fix_top(psign->r);
991 psign->s->top=20/sizeof(BN_ULONG);
992 bn_fix_top(psign->s);
993
994err:
995 if (psign)
996 {
997 DSA_SIG_free(psign);
998 psign=NULL;
999 }
1000 return psign;
1001}
1002#endif
1003
1004static int surewarehk_modexp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
1005 const BIGNUM *m, BN_CTX *ctx)
1006{
1007 int ret=0;
1008 char msg[64]="ENGINE_modexp";
1009 if (!p_surewarehk_Mod_Exp)
1010 {
1011 SUREWAREerr(SUREWARE_F_SUREWAREHK_MOD_EXP,ENGINE_R_NOT_INITIALISED);
1012 }
1013 else
1014 {
1015 bn_expand2(r,m->top);
1016 if (r && r->dmax==m->top)
1017 {
1018 /* do it*/
1019 ret=p_surewarehk_Mod_Exp(msg,
1020 m->top*sizeof(BN_ULONG),
1021 (unsigned long *)m->d,
1022 p->top*sizeof(BN_ULONG),
1023 (unsigned long *)p->d,
1024 a->top*sizeof(BN_ULONG),
1025 (unsigned long *)a->d,
1026 (unsigned long *)r->d);
1027 surewarehk_error_handling(msg,SUREWARE_F_SUREWAREHK_MOD_EXP,ret);
1028 if (ret==1)
1029 {
1030 /* normalise result */
1031 r->top=m->top;
1032 bn_fix_top(r);
1033 }
1034 }
1035 }
1036 return ret;
1037}
1038#endif /* !OPENSSL_NO_HW_SureWare */
1039#endif /* !OPENSSL_NO_HW */
diff --git a/src/lib/libcrypto/engine/hw_sureware_err.c b/src/lib/libcrypto/engine/hw_sureware_err.c
deleted file mode 100644
index 69955dadbb..0000000000
--- a/src/lib/libcrypto/engine/hw_sureware_err.c
+++ /dev/null
@@ -1,150 +0,0 @@
1/* hw_sureware_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 "hw_sureware_err.h"
64
65/* BEGIN ERROR CODES */
66#ifndef OPENSSL_NO_ERR
67static ERR_STRING_DATA SUREWARE_str_functs[]=
68 {
69{ERR_PACK(0,SUREWARE_F_SUREWAREHK_CTRL,0), "SUREWAREHK_CTRL"},
70{ERR_PACK(0,SUREWARE_F_SUREWAREHK_DSA_DO_SIGN,0), "SUREWAREHK_DSA_DO_SIGN"},
71{ERR_PACK(0,SUREWARE_F_SUREWAREHK_EX_FREE,0), "SUREWAREHK_EX_FREE"},
72{ERR_PACK(0,SUREWARE_F_SUREWAREHK_FINISH,0), "SUREWAREHK_FINISH"},
73{ERR_PACK(0,SUREWARE_F_SUREWAREHK_INIT,0), "SUREWAREHK_INIT"},
74{ERR_PACK(0,SUREWARE_F_SUREWAREHK_LOAD_PRIVATE_KEY,0), "SUREWAREHK_LOAD_PRIVATE_KEY"},
75{ERR_PACK(0,SUREWARE_F_SUREWAREHK_LOAD_PUBLIC_KEY,0), "SUREWAREHK_LOAD_PUBLIC_KEY"},
76{ERR_PACK(0,SUREWARE_F_SUREWAREHK_MOD_EXP,0), "SUREWAREHK_MOD_EXP"},
77{ERR_PACK(0,SUREWARE_F_SUREWAREHK_RAND_BYTES,0), "SUREWAREHK_RAND_BYTES"},
78{ERR_PACK(0,SUREWARE_F_SUREWAREHK_RAND_SEED,0), "SUREWAREHK_RAND_SEED"},
79{ERR_PACK(0,SUREWARE_F_SUREWAREHK_RSA_PRIV_DEC,0), "SUREWAREHK_RSA_PRIV_DEC"},
80{ERR_PACK(0,SUREWARE_F_SUREWAREHK_RSA_PRIV_ENC,0), "SUREWAREHK_RSA_PRIV_ENC"},
81{0,NULL}
82 };
83
84static ERR_STRING_DATA SUREWARE_str_reasons[]=
85 {
86{SUREWARE_R_BIO_WAS_FREED ,"bio was freed"},
87{SUREWARE_R_MISSING_KEY_COMPONENTS ,"missing key components"},
88{SUREWARE_R_REQUEST_FAILED ,"request failed"},
89{SUREWARE_R_REQUEST_FALLBACK ,"request fallback"},
90{SUREWARE_R_SIZE_TOO_LARGE_OR_TOO_SMALL ,"size too large or too small"},
91{SUREWARE_R_UNIT_FAILURE ,"unit failure"},
92{0,NULL}
93 };
94
95#endif
96
97#ifdef SUREWARE_LIB_NAME
98static ERR_STRING_DATA SUREWARE_lib_name[]=
99 {
100{0 ,SUREWARE_LIB_NAME},
101{0,NULL}
102 };
103#endif
104
105
106static int SUREWARE_lib_error_code=0;
107static int SUREWARE_error_init=1;
108
109static void ERR_load_SUREWARE_strings(void)
110 {
111 if (SUREWARE_lib_error_code == 0)
112 SUREWARE_lib_error_code=ERR_get_next_error_library();
113
114 if (SUREWARE_error_init)
115 {
116 SUREWARE_error_init=0;
117#ifndef OPENSSL_NO_ERR
118 ERR_load_strings(SUREWARE_lib_error_code,SUREWARE_str_functs);
119 ERR_load_strings(SUREWARE_lib_error_code,SUREWARE_str_reasons);
120#endif
121
122#ifdef SUREWARE_LIB_NAME
123 SUREWARE_lib_name->error = ERR_PACK(SUREWARE_lib_error_code,0,0);
124 ERR_load_strings(0,SUREWARE_lib_name);
125#endif
126 }
127 }
128
129static void ERR_unload_SUREWARE_strings(void)
130 {
131 if (SUREWARE_error_init == 0)
132 {
133#ifndef OPENSSL_NO_ERR
134 ERR_unload_strings(SUREWARE_lib_error_code,SUREWARE_str_functs);
135 ERR_unload_strings(SUREWARE_lib_error_code,SUREWARE_str_reasons);
136#endif
137
138#ifdef SUREWARE_LIB_NAME
139 ERR_unload_strings(0,SUREWARE_lib_name);
140#endif
141 SUREWARE_error_init=1;
142 }
143 }
144
145static void ERR_SUREWARE_error(int function, int reason, char *file, int line)
146 {
147 if (SUREWARE_lib_error_code == 0)
148 SUREWARE_lib_error_code=ERR_get_next_error_library();
149 ERR_PUT_error(SUREWARE_lib_error_code,function,reason,file,line);
150 }
diff --git a/src/lib/libcrypto/engine/hw_sureware_err.h b/src/lib/libcrypto/engine/hw_sureware_err.h
deleted file mode 100644
index bc52af5e05..0000000000
--- a/src/lib/libcrypto/engine/hw_sureware_err.h
+++ /dev/null
@@ -1,94 +0,0 @@
1/* ====================================================================
2 * Copyright (c) 2001 The OpenSSL Project. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in
13 * the documentation and/or other materials provided with the
14 * distribution.
15 *
16 * 3. All advertising materials mentioning features or use of this
17 * software must display the following acknowledgment:
18 * "This product includes software developed by the OpenSSL Project
19 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
20 *
21 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
22 * endorse or promote products derived from this software without
23 * prior written permission. For written permission, please contact
24 * openssl-core@openssl.org.
25 *
26 * 5. Products derived from this software may not be called "OpenSSL"
27 * nor may "OpenSSL" appear in their names without prior written
28 * permission of the OpenSSL Project.
29 *
30 * 6. Redistributions of any form whatsoever must retain the following
31 * acknowledgment:
32 * "This product includes software developed by the OpenSSL Project
33 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
34 *
35 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
36 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
37 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
38 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
39 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
41 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
42 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
43 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
44 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
45 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
46 * OF THE POSSIBILITY OF SUCH DAMAGE.
47 * ====================================================================
48 *
49 * This product includes cryptographic software written by Eric Young
50 * (eay@cryptsoft.com). This product includes software written by Tim
51 * Hudson (tjh@cryptsoft.com).
52 *
53 */
54
55#ifndef HEADER_SUREWARE_ERR_H
56#define HEADER_SUREWARE_ERR_H
57
58/* BEGIN ERROR CODES */
59/* The following lines are auto generated by the script mkerr.pl. Any changes
60 * made after this point may be overwritten when the script is next run.
61 */
62static void ERR_load_SUREWARE_strings(void);
63static void ERR_unload_SUREWARE_strings(void);
64static void ERR_SUREWARE_error(int function, int reason, char *file, int line);
65#define SUREWAREerr(f,r) ERR_SUREWARE_error((f),(r),__FILE__,__LINE__)
66
67/* Error codes for the SUREWARE functions. */
68
69/* Function codes. */
70#define SUREWARE_F_SUREWAREHK_CTRL 100
71#define SUREWARE_F_SUREWAREHK_DSA_DO_SIGN 101
72#define SUREWARE_F_SUREWAREHK_EX_FREE 102
73#define SUREWARE_F_SUREWAREHK_FINISH 103
74#define SUREWARE_F_SUREWAREHK_INIT 104
75#define SUREWARE_F_SUREWAREHK_LOAD_PRIVATE_KEY 105
76#define SUREWARE_F_SUREWAREHK_LOAD_PUBLIC_KEY 106
77#define SUREWARE_F_SUREWAREHK_MOD_EXP 107
78#define SUREWARE_F_SUREWAREHK_RAND_BYTES 108
79#define SUREWARE_F_SUREWAREHK_RAND_SEED 109
80#define SUREWARE_F_SUREWAREHK_RSA_PRIV_DEC 110
81#define SUREWARE_F_SUREWAREHK_RSA_PRIV_ENC 111
82
83/* Reason codes. */
84#define SUREWARE_R_BIO_WAS_FREED 100
85#define SUREWARE_R_MISSING_KEY_COMPONENTS 105
86#define SUREWARE_R_REQUEST_FAILED 101
87#define SUREWARE_R_REQUEST_FALLBACK 102
88#define SUREWARE_R_SIZE_TOO_LARGE_OR_TOO_SMALL 103
89#define SUREWARE_R_UNIT_FAILURE 104
90
91#ifdef __cplusplus
92}
93#endif
94#endif
diff --git a/src/lib/libcrypto/engine/hw_ubsec.c b/src/lib/libcrypto/engine/hw_ubsec.c
deleted file mode 100644
index 8fb834af31..0000000000
--- a/src/lib/libcrypto/engine/hw_ubsec.c
+++ /dev/null
@@ -1,1061 +0,0 @@
1/* crypto/engine/hw_ubsec.c */
2/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
3 * project 2000.
4 *
5 * Cloned shamelessly by Joe Tardo.
6 */
7/* ====================================================================
8 * Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 *
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 *
17 * 2. Redistributions in binary form must reproduce the above copyright
18 * notice, this list of conditions and the following disclaimer in
19 * the documentation and/or other materials provided with the
20 * distribution.
21 *
22 * 3. All advertising materials mentioning features or use of this
23 * software must display the following acknowledgment:
24 * "This product includes software developed by the OpenSSL Project
25 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
26 *
27 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
28 * endorse or promote products derived from this software without
29 * prior written permission. For written permission, please contact
30 * licensing@OpenSSL.org.
31 *
32 * 5. Products derived from this software may not be called "OpenSSL"
33 * nor may "OpenSSL" appear in their names without prior written
34 * permission of the OpenSSL Project.
35 *
36 * 6. Redistributions of any form whatsoever must retain the following
37 * acknowledgment:
38 * "This product includes software developed by the OpenSSL Project
39 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
40 *
41 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
42 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
44 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
45 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
46 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
47 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
48 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
49 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
50 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
51 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
52 * OF THE POSSIBILITY OF SUCH DAMAGE.
53 * ====================================================================
54 *
55 * This product includes cryptographic software written by Eric Young
56 * (eay@cryptsoft.com). This product includes software written by Tim
57 * Hudson (tjh@cryptsoft.com).
58 *
59 */
60
61#include <stdio.h>
62#include <openssl/crypto.h>
63#include "cryptlib.h"
64#include <openssl/dso.h>
65#include <openssl/engine.h>
66
67#ifndef OPENSSL_NO_HW
68#ifndef OPENSSL_NO_HW_UBSEC
69
70#ifdef FLAT_INC
71#include "hw_ubsec.h"
72#else
73#include "vendor_defns/hw_ubsec.h"
74#endif
75
76#define UBSEC_LIB_NAME "ubsec engine"
77#include "hw_ubsec_err.c"
78
79#define FAIL_TO_SOFTWARE -15
80
81static int ubsec_destroy(ENGINE *e);
82static int ubsec_init(ENGINE *e);
83static int ubsec_finish(ENGINE *e);
84static int ubsec_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)());
85static int ubsec_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
86 const BIGNUM *m, BN_CTX *ctx);
87static int ubsec_mod_exp_crt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
88 const BIGNUM *q, const BIGNUM *dp,
89 const BIGNUM *dq, const BIGNUM *qinv, BN_CTX *ctx);
90#ifndef OPENSSL_NO_RSA
91static int ubsec_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa);
92#endif
93static int ubsec_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
94 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
95#ifndef OPENSSL_NO_DSA
96#ifdef NOT_USED
97static int ubsec_dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1,
98 BIGNUM *p1, BIGNUM *a2, BIGNUM *p2, BIGNUM *m,
99 BN_CTX *ctx, BN_MONT_CTX *in_mont);
100static int ubsec_mod_exp_dsa(DSA *dsa, BIGNUM *r, BIGNUM *a,
101 const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
102 BN_MONT_CTX *m_ctx);
103#endif
104static DSA_SIG *ubsec_dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa);
105static int ubsec_dsa_verify(const unsigned char *dgst, int dgst_len,
106 DSA_SIG *sig, DSA *dsa);
107#endif
108#ifndef OPENSSL_NO_DH
109static int ubsec_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a,
110 const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
111 BN_MONT_CTX *m_ctx);
112static int ubsec_dh_compute_key(unsigned char *key,const BIGNUM *pub_key,DH *dh);
113static int ubsec_dh_generate_key(DH *dh);
114#endif
115
116#ifdef NOT_USED
117static int ubsec_rand_bytes(unsigned char *buf, int num);
118static int ubsec_rand_status(void);
119#endif
120
121#define UBSEC_CMD_SO_PATH ENGINE_CMD_BASE
122static const ENGINE_CMD_DEFN ubsec_cmd_defns[] = {
123 {UBSEC_CMD_SO_PATH,
124 "SO_PATH",
125 "Specifies the path to the 'ubsec' shared library",
126 ENGINE_CMD_FLAG_STRING},
127 {0, NULL, NULL, 0}
128 };
129
130#ifndef OPENSSL_NO_RSA
131/* Our internal RSA_METHOD that we provide pointers to */
132static RSA_METHOD ubsec_rsa =
133 {
134 "UBSEC RSA method",
135 NULL,
136 NULL,
137 NULL,
138 NULL,
139 ubsec_rsa_mod_exp,
140 ubsec_mod_exp_mont,
141 NULL,
142 NULL,
143 0,
144 NULL,
145 NULL,
146 NULL
147 };
148#endif
149
150#ifndef OPENSSL_NO_DSA
151/* Our internal DSA_METHOD that we provide pointers to */
152static DSA_METHOD ubsec_dsa =
153 {
154 "UBSEC DSA method",
155 ubsec_dsa_do_sign, /* dsa_do_sign */
156 NULL, /* dsa_sign_setup */
157 ubsec_dsa_verify, /* dsa_do_verify */
158 NULL, /* ubsec_dsa_mod_exp */ /* dsa_mod_exp */
159 NULL, /* ubsec_mod_exp_dsa */ /* bn_mod_exp */
160 NULL, /* init */
161 NULL, /* finish */
162 0, /* flags */
163 NULL /* app_data */
164 };
165#endif
166
167#ifndef OPENSSL_NO_DH
168/* Our internal DH_METHOD that we provide pointers to */
169static DH_METHOD ubsec_dh =
170 {
171 "UBSEC DH method",
172 ubsec_dh_generate_key,
173 ubsec_dh_compute_key,
174 ubsec_mod_exp_dh,
175 NULL,
176 NULL,
177 0,
178 NULL
179 };
180#endif
181
182/* Constants used when creating the ENGINE */
183static const char *engine_ubsec_id = "ubsec";
184static const char *engine_ubsec_name = "UBSEC hardware engine support";
185
186/* This internal function is used by ENGINE_ubsec() and possibly by the
187 * "dynamic" ENGINE support too */
188static int bind_helper(ENGINE *e)
189 {
190#ifndef OPENSSL_NO_RSA
191 const RSA_METHOD *meth1;
192#endif
193#ifndef OPENSSL_NO_DH
194#ifndef HAVE_UBSEC_DH
195 const DH_METHOD *meth3;
196#endif /* HAVE_UBSEC_DH */
197#endif
198 if(!ENGINE_set_id(e, engine_ubsec_id) ||
199 !ENGINE_set_name(e, engine_ubsec_name) ||
200#ifndef OPENSSL_NO_RSA
201 !ENGINE_set_RSA(e, &ubsec_rsa) ||
202#endif
203#ifndef OPENSSL_NO_DSA
204 !ENGINE_set_DSA(e, &ubsec_dsa) ||
205#endif
206#ifndef OPENSSL_NO_DH
207 !ENGINE_set_DH(e, &ubsec_dh) ||
208#endif
209 !ENGINE_set_destroy_function(e, ubsec_destroy) ||
210 !ENGINE_set_init_function(e, ubsec_init) ||
211 !ENGINE_set_finish_function(e, ubsec_finish) ||
212 !ENGINE_set_ctrl_function(e, ubsec_ctrl) ||
213 !ENGINE_set_cmd_defns(e, ubsec_cmd_defns))
214 return 0;
215
216#ifndef OPENSSL_NO_RSA
217 /* We know that the "PKCS1_SSLeay()" functions hook properly
218 * to the Broadcom-specific mod_exp and mod_exp_crt so we use
219 * those functions. NB: We don't use ENGINE_openssl() or
220 * anything "more generic" because something like the RSAref
221 * code may not hook properly, and if you own one of these
222 * cards then you have the right to do RSA operations on it
223 * anyway! */
224 meth1 = RSA_PKCS1_SSLeay();
225 ubsec_rsa.rsa_pub_enc = meth1->rsa_pub_enc;
226 ubsec_rsa.rsa_pub_dec = meth1->rsa_pub_dec;
227 ubsec_rsa.rsa_priv_enc = meth1->rsa_priv_enc;
228 ubsec_rsa.rsa_priv_dec = meth1->rsa_priv_dec;
229#endif
230
231#ifndef OPENSSL_NO_DH
232#ifndef HAVE_UBSEC_DH
233 /* Much the same for Diffie-Hellman */
234 meth3 = DH_OpenSSL();
235 ubsec_dh.generate_key = meth3->generate_key;
236 ubsec_dh.compute_key = meth3->compute_key;
237#endif /* HAVE_UBSEC_DH */
238#endif
239
240 /* Ensure the ubsec error handling is set up */
241 ERR_load_UBSEC_strings();
242 return 1;
243 }
244
245#ifndef ENGINE_DYNAMIC_SUPPORT
246static ENGINE *engine_ubsec(void)
247 {
248 ENGINE *ret = ENGINE_new();
249 if(!ret)
250 return NULL;
251 if(!bind_helper(ret))
252 {
253 ENGINE_free(ret);
254 return NULL;
255 }
256 return ret;
257 }
258
259void ENGINE_load_ubsec(void)
260 {
261 /* Copied from eng_[openssl|dyn].c */
262 ENGINE *toadd = engine_ubsec();
263 if(!toadd) return;
264 ENGINE_add(toadd);
265 ENGINE_free(toadd);
266 ERR_clear_error();
267 }
268#endif
269
270/* This is a process-global DSO handle used for loading and unloading
271 * the UBSEC library. NB: This is only set (or unset) during an
272 * init() or finish() call (reference counts permitting) and they're
273 * operating with global locks, so this should be thread-safe
274 * implicitly. */
275
276static DSO *ubsec_dso = NULL;
277
278/* These are the function pointers that are (un)set when the library has
279 * successfully (un)loaded. */
280
281static t_UBSEC_ubsec_bytes_to_bits *p_UBSEC_ubsec_bytes_to_bits = NULL;
282static t_UBSEC_ubsec_bits_to_bytes *p_UBSEC_ubsec_bits_to_bytes = NULL;
283static t_UBSEC_ubsec_open *p_UBSEC_ubsec_open = NULL;
284static t_UBSEC_ubsec_close *p_UBSEC_ubsec_close = NULL;
285#ifndef OPENSSL_NO_DH
286static t_UBSEC_diffie_hellman_generate_ioctl
287 *p_UBSEC_diffie_hellman_generate_ioctl = NULL;
288static t_UBSEC_diffie_hellman_agree_ioctl *p_UBSEC_diffie_hellman_agree_ioctl = NULL;
289#endif
290/* #ifndef OPENSSL_NO_RSA */
291static t_UBSEC_rsa_mod_exp_ioctl *p_UBSEC_rsa_mod_exp_ioctl = NULL;
292static t_UBSEC_rsa_mod_exp_crt_ioctl *p_UBSEC_rsa_mod_exp_crt_ioctl = NULL;
293/* #endif */
294#ifndef OPENSSL_NO_DSA
295static t_UBSEC_dsa_sign_ioctl *p_UBSEC_dsa_sign_ioctl = NULL;
296static t_UBSEC_dsa_verify_ioctl *p_UBSEC_dsa_verify_ioctl = NULL;
297#endif
298static t_UBSEC_math_accelerate_ioctl *p_UBSEC_math_accelerate_ioctl = NULL;
299static t_UBSEC_rng_ioctl *p_UBSEC_rng_ioctl = NULL;
300static t_UBSEC_max_key_len_ioctl *p_UBSEC_max_key_len_ioctl = NULL;
301
302static int max_key_len = 1024; /* ??? */
303
304/*
305 * These are the static string constants for the DSO file name and the function
306 * symbol names to bind to.
307 */
308
309static const char *UBSEC_LIBNAME = NULL;
310static const char *get_UBSEC_LIBNAME(void)
311 {
312 if(UBSEC_LIBNAME)
313 return UBSEC_LIBNAME;
314 return "ubsec";
315 }
316static void free_UBSEC_LIBNAME(void)
317 {
318 if(UBSEC_LIBNAME)
319 OPENSSL_free((void*)UBSEC_LIBNAME);
320 UBSEC_LIBNAME = NULL;
321 }
322static long set_UBSEC_LIBNAME(const char *name)
323 {
324 free_UBSEC_LIBNAME();
325 return (((UBSEC_LIBNAME = BUF_strdup(name)) != NULL) ? 1 : 0);
326 }
327static const char *UBSEC_F1 = "ubsec_bytes_to_bits";
328static const char *UBSEC_F2 = "ubsec_bits_to_bytes";
329static const char *UBSEC_F3 = "ubsec_open";
330static const char *UBSEC_F4 = "ubsec_close";
331#ifndef OPENSSL_NO_DH
332static const char *UBSEC_F5 = "diffie_hellman_generate_ioctl";
333static const char *UBSEC_F6 = "diffie_hellman_agree_ioctl";
334#endif
335/* #ifndef OPENSSL_NO_RSA */
336static const char *UBSEC_F7 = "rsa_mod_exp_ioctl";
337static const char *UBSEC_F8 = "rsa_mod_exp_crt_ioctl";
338/* #endif */
339#ifndef OPENSSL_NO_DSA
340static const char *UBSEC_F9 = "dsa_sign_ioctl";
341static const char *UBSEC_F10 = "dsa_verify_ioctl";
342#endif
343static const char *UBSEC_F11 = "math_accelerate_ioctl";
344static const char *UBSEC_F12 = "rng_ioctl";
345static const char *UBSEC_F13 = "ubsec_max_key_len_ioctl";
346
347/* Destructor (complements the "ENGINE_ubsec()" constructor) */
348static int ubsec_destroy(ENGINE *e)
349 {
350 free_UBSEC_LIBNAME();
351 ERR_unload_UBSEC_strings();
352 return 1;
353 }
354
355/* (de)initialisation functions. */
356static int ubsec_init(ENGINE *e)
357 {
358 t_UBSEC_ubsec_bytes_to_bits *p1;
359 t_UBSEC_ubsec_bits_to_bytes *p2;
360 t_UBSEC_ubsec_open *p3;
361 t_UBSEC_ubsec_close *p4;
362#ifndef OPENSSL_NO_DH
363 t_UBSEC_diffie_hellman_generate_ioctl *p5;
364 t_UBSEC_diffie_hellman_agree_ioctl *p6;
365#endif
366/* #ifndef OPENSSL_NO_RSA */
367 t_UBSEC_rsa_mod_exp_ioctl *p7;
368 t_UBSEC_rsa_mod_exp_crt_ioctl *p8;
369/* #endif */
370#ifndef OPENSSL_NO_DSA
371 t_UBSEC_dsa_sign_ioctl *p9;
372 t_UBSEC_dsa_verify_ioctl *p10;
373#endif
374 t_UBSEC_math_accelerate_ioctl *p11;
375 t_UBSEC_rng_ioctl *p12;
376 t_UBSEC_max_key_len_ioctl *p13;
377 int fd = 0;
378
379 if(ubsec_dso != NULL)
380 {
381 UBSECerr(UBSEC_F_UBSEC_INIT, UBSEC_R_ALREADY_LOADED);
382 goto err;
383 }
384 /*
385 * Attempt to load libubsec.so/ubsec.dll/whatever.
386 */
387 ubsec_dso = DSO_load(NULL, get_UBSEC_LIBNAME(), NULL, 0);
388 if(ubsec_dso == NULL)
389 {
390 UBSECerr(UBSEC_F_UBSEC_INIT, UBSEC_R_DSO_FAILURE);
391 goto err;
392 }
393
394 if (
395 !(p1 = (t_UBSEC_ubsec_bytes_to_bits *) DSO_bind_func(ubsec_dso, UBSEC_F1)) ||
396 !(p2 = (t_UBSEC_ubsec_bits_to_bytes *) DSO_bind_func(ubsec_dso, UBSEC_F2)) ||
397 !(p3 = (t_UBSEC_ubsec_open *) DSO_bind_func(ubsec_dso, UBSEC_F3)) ||
398 !(p4 = (t_UBSEC_ubsec_close *) DSO_bind_func(ubsec_dso, UBSEC_F4)) ||
399#ifndef OPENSSL_NO_DH
400 !(p5 = (t_UBSEC_diffie_hellman_generate_ioctl *)
401 DSO_bind_func(ubsec_dso, UBSEC_F5)) ||
402 !(p6 = (t_UBSEC_diffie_hellman_agree_ioctl *)
403 DSO_bind_func(ubsec_dso, UBSEC_F6)) ||
404#endif
405/* #ifndef OPENSSL_NO_RSA */
406 !(p7 = (t_UBSEC_rsa_mod_exp_ioctl *) DSO_bind_func(ubsec_dso, UBSEC_F7)) ||
407 !(p8 = (t_UBSEC_rsa_mod_exp_crt_ioctl *) DSO_bind_func(ubsec_dso, UBSEC_F8)) ||
408/* #endif */
409#ifndef OPENSSL_NO_DSA
410 !(p9 = (t_UBSEC_dsa_sign_ioctl *) DSO_bind_func(ubsec_dso, UBSEC_F9)) ||
411 !(p10 = (t_UBSEC_dsa_verify_ioctl *) DSO_bind_func(ubsec_dso, UBSEC_F10)) ||
412#endif
413 !(p11 = (t_UBSEC_math_accelerate_ioctl *)
414 DSO_bind_func(ubsec_dso, UBSEC_F11)) ||
415 !(p12 = (t_UBSEC_rng_ioctl *) DSO_bind_func(ubsec_dso, UBSEC_F12)) ||
416 !(p13 = (t_UBSEC_max_key_len_ioctl *) DSO_bind_func(ubsec_dso, UBSEC_F13)))
417 {
418 UBSECerr(UBSEC_F_UBSEC_INIT, UBSEC_R_DSO_FAILURE);
419 goto err;
420 }
421
422 /* Copy the pointers */
423 p_UBSEC_ubsec_bytes_to_bits = p1;
424 p_UBSEC_ubsec_bits_to_bytes = p2;
425 p_UBSEC_ubsec_open = p3;
426 p_UBSEC_ubsec_close = p4;
427#ifndef OPENSSL_NO_DH
428 p_UBSEC_diffie_hellman_generate_ioctl = p5;
429 p_UBSEC_diffie_hellman_agree_ioctl = p6;
430#endif
431#ifndef OPENSSL_NO_RSA
432 p_UBSEC_rsa_mod_exp_ioctl = p7;
433 p_UBSEC_rsa_mod_exp_crt_ioctl = p8;
434#endif
435#ifndef OPENSSL_NO_DSA
436 p_UBSEC_dsa_sign_ioctl = p9;
437 p_UBSEC_dsa_verify_ioctl = p10;
438#endif
439 p_UBSEC_math_accelerate_ioctl = p11;
440 p_UBSEC_rng_ioctl = p12;
441 p_UBSEC_max_key_len_ioctl = p13;
442
443 /* Perform an open to see if there's actually any unit running. */
444 if (((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) > 0) && (p_UBSEC_max_key_len_ioctl(fd, &max_key_len) == 0))
445 {
446 p_UBSEC_ubsec_close(fd);
447 return 1;
448 }
449 else
450 {
451 UBSECerr(UBSEC_F_UBSEC_INIT, UBSEC_R_UNIT_FAILURE);
452 }
453
454err:
455 if(ubsec_dso)
456 DSO_free(ubsec_dso);
457 ubsec_dso = NULL;
458 p_UBSEC_ubsec_bytes_to_bits = NULL;
459 p_UBSEC_ubsec_bits_to_bytes = NULL;
460 p_UBSEC_ubsec_open = NULL;
461 p_UBSEC_ubsec_close = NULL;
462#ifndef OPENSSL_NO_DH
463 p_UBSEC_diffie_hellman_generate_ioctl = NULL;
464 p_UBSEC_diffie_hellman_agree_ioctl = NULL;
465#endif
466#ifndef OPENSSL_NO_RSA
467 p_UBSEC_rsa_mod_exp_ioctl = NULL;
468 p_UBSEC_rsa_mod_exp_crt_ioctl = NULL;
469#endif
470#ifndef OPENSSL_NO_DSA
471 p_UBSEC_dsa_sign_ioctl = NULL;
472 p_UBSEC_dsa_verify_ioctl = NULL;
473#endif
474 p_UBSEC_math_accelerate_ioctl = NULL;
475 p_UBSEC_rng_ioctl = NULL;
476 p_UBSEC_max_key_len_ioctl = NULL;
477
478 return 0;
479 }
480
481static int ubsec_finish(ENGINE *e)
482 {
483 free_UBSEC_LIBNAME();
484 if(ubsec_dso == NULL)
485 {
486 UBSECerr(UBSEC_F_UBSEC_FINISH, UBSEC_R_NOT_LOADED);
487 return 0;
488 }
489 if(!DSO_free(ubsec_dso))
490 {
491 UBSECerr(UBSEC_F_UBSEC_FINISH, UBSEC_R_DSO_FAILURE);
492 return 0;
493 }
494 ubsec_dso = NULL;
495 p_UBSEC_ubsec_bytes_to_bits = NULL;
496 p_UBSEC_ubsec_bits_to_bytes = NULL;
497 p_UBSEC_ubsec_open = NULL;
498 p_UBSEC_ubsec_close = NULL;
499#ifndef OPENSSL_NO_DH
500 p_UBSEC_diffie_hellman_generate_ioctl = NULL;
501 p_UBSEC_diffie_hellman_agree_ioctl = NULL;
502#endif
503#ifndef OPENSSL_NO_RSA
504 p_UBSEC_rsa_mod_exp_ioctl = NULL;
505 p_UBSEC_rsa_mod_exp_crt_ioctl = NULL;
506#endif
507#ifndef OPENSSL_NO_DSA
508 p_UBSEC_dsa_sign_ioctl = NULL;
509 p_UBSEC_dsa_verify_ioctl = NULL;
510#endif
511 p_UBSEC_math_accelerate_ioctl = NULL;
512 p_UBSEC_rng_ioctl = NULL;
513 p_UBSEC_max_key_len_ioctl = NULL;
514 return 1;
515 }
516
517static int ubsec_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)())
518 {
519 int initialised = ((ubsec_dso == NULL) ? 0 : 1);
520 switch(cmd)
521 {
522 case UBSEC_CMD_SO_PATH:
523 if(p == NULL)
524 {
525 UBSECerr(UBSEC_F_UBSEC_CTRL,ERR_R_PASSED_NULL_PARAMETER);
526 return 0;
527 }
528 if(initialised)
529 {
530 UBSECerr(UBSEC_F_UBSEC_CTRL,UBSEC_R_ALREADY_LOADED);
531 return 0;
532 }
533 return set_UBSEC_LIBNAME((const char *)p);
534 default:
535 break;
536 }
537 UBSECerr(UBSEC_F_UBSEC_CTRL,UBSEC_R_CTRL_COMMAND_NOT_IMPLEMENTED);
538 return 0;
539 }
540
541static int ubsec_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
542 const BIGNUM *m, BN_CTX *ctx)
543 {
544 int y_len = 0;
545 int fd;
546
547 if(ubsec_dso == NULL)
548 {
549 UBSECerr(UBSEC_F_UBSEC_MOD_EXP, UBSEC_R_NOT_LOADED);
550 return 0;
551 }
552
553 /* Check if hardware can't handle this argument. */
554 y_len = BN_num_bits(m);
555 if (y_len > max_key_len) {
556 UBSECerr(UBSEC_F_UBSEC_MOD_EXP, UBSEC_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
557 return BN_mod_exp(r, a, p, m, ctx);
558 }
559
560 if(!bn_wexpand(r, m->top))
561 {
562 UBSECerr(UBSEC_F_UBSEC_MOD_EXP, UBSEC_R_BN_EXPAND_FAIL);
563 return 0;
564 }
565
566 if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0) {
567 fd = 0;
568 UBSECerr(UBSEC_F_UBSEC_INIT, UBSEC_R_UNIT_FAILURE);
569 return BN_mod_exp(r, a, p, m, ctx);
570 }
571
572 if (p_UBSEC_rsa_mod_exp_ioctl(fd, (unsigned char *)a->d, BN_num_bits(a),
573 (unsigned char *)m->d, BN_num_bits(m), (unsigned char *)p->d,
574 BN_num_bits(p), (unsigned char *)r->d, &y_len) != 0)
575 {
576 UBSECerr(UBSEC_F_UBSEC_MOD_EXP, UBSEC_R_REQUEST_FAILED);
577 p_UBSEC_ubsec_close(fd);
578
579 return BN_mod_exp(r, a, p, m, ctx);
580 }
581
582 p_UBSEC_ubsec_close(fd);
583
584 r->top = (BN_num_bits(m)+BN_BITS2-1)/BN_BITS2;
585 return 1;
586 }
587
588#ifndef OPENSSL_NO_RSA
589static int ubsec_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa)
590 {
591 BN_CTX *ctx;
592 int to_return = 0;
593
594 if((ctx = BN_CTX_new()) == NULL)
595 goto err;
596
597 if(!rsa->p || !rsa->q || !rsa->dmp1 || !rsa->dmq1 || !rsa->iqmp)
598 {
599 UBSECerr(UBSEC_F_UBSEC_RSA_MOD_EXP, UBSEC_R_MISSING_KEY_COMPONENTS);
600 goto err;
601 }
602
603 to_return = ubsec_mod_exp_crt(r0, I, rsa->p, rsa->q, rsa->dmp1,
604 rsa->dmq1, rsa->iqmp, ctx);
605 if (to_return == FAIL_TO_SOFTWARE)
606 {
607 /*
608 * Do in software as hardware failed.
609 */
610 const RSA_METHOD *meth = RSA_PKCS1_SSLeay();
611 to_return = (*meth->rsa_mod_exp)(r0, I, rsa);
612 }
613err:
614 if(ctx)
615 BN_CTX_free(ctx);
616 return to_return;
617 }
618#endif
619
620static int ubsec_mod_exp_crt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
621 const BIGNUM *q, const BIGNUM *dp,
622 const BIGNUM *dq, const BIGNUM *qinv, BN_CTX *ctx)
623 {
624 int y_len,
625 m_len,
626 fd;
627
628 m_len = BN_num_bytes(p) + BN_num_bytes(q) + 1;
629 y_len = BN_num_bits(p) + BN_num_bits(q);
630
631 /* Check if hardware can't handle this argument. */
632 if (y_len > max_key_len) {
633 UBSECerr(UBSEC_F_UBSEC_MOD_EXP, UBSEC_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
634 return FAIL_TO_SOFTWARE;
635 }
636
637 if (!bn_wexpand(r, p->top + q->top + 1)) {
638 UBSECerr(UBSEC_F_UBSEC_RSA_MOD_EXP_CRT, UBSEC_R_BN_EXPAND_FAIL);
639 return 0;
640 }
641
642 if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0) {
643 fd = 0;
644 UBSECerr(UBSEC_F_UBSEC_INIT, UBSEC_R_UNIT_FAILURE);
645 return FAIL_TO_SOFTWARE;
646 }
647
648 if (p_UBSEC_rsa_mod_exp_crt_ioctl(fd,
649 (unsigned char *)a->d, BN_num_bits(a),
650 (unsigned char *)qinv->d, BN_num_bits(qinv),
651 (unsigned char *)dp->d, BN_num_bits(dp),
652 (unsigned char *)p->d, BN_num_bits(p),
653 (unsigned char *)dq->d, BN_num_bits(dq),
654 (unsigned char *)q->d, BN_num_bits(q),
655 (unsigned char *)r->d, &y_len) != 0) {
656 UBSECerr(UBSEC_F_UBSEC_MOD_EXP, UBSEC_R_REQUEST_FAILED);
657 p_UBSEC_ubsec_close(fd);
658 return FAIL_TO_SOFTWARE;
659 }
660
661 p_UBSEC_ubsec_close(fd);
662
663 r->top = (BN_num_bits(p) + BN_num_bits(q) + BN_BITS2 - 1)/BN_BITS2;
664 return 1;
665}
666
667#ifndef OPENSSL_NO_DSA
668#ifdef NOT_USED
669static int ubsec_dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1,
670 BIGNUM *p1, BIGNUM *a2, BIGNUM *p2, BIGNUM *m,
671 BN_CTX *ctx, BN_MONT_CTX *in_mont)
672 {
673 BIGNUM t;
674 int to_return = 0;
675
676 BN_init(&t);
677 /* let rr = a1 ^ p1 mod m */
678 if (!ubsec_mod_exp(rr,a1,p1,m,ctx)) goto end;
679 /* let t = a2 ^ p2 mod m */
680 if (!ubsec_mod_exp(&t,a2,p2,m,ctx)) goto end;
681 /* let rr = rr * t mod m */
682 if (!BN_mod_mul(rr,rr,&t,m,ctx)) goto end;
683 to_return = 1;
684end:
685 BN_free(&t);
686 return to_return;
687 }
688
689static int ubsec_mod_exp_dsa(DSA *dsa, BIGNUM *r, BIGNUM *a,
690 const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
691 BN_MONT_CTX *m_ctx)
692 {
693 return ubsec_mod_exp(r, a, p, m, ctx);
694 }
695#endif
696#endif
697
698/*
699 * This function is aliased to mod_exp (with the mont stuff dropped).
700 */
701static int ubsec_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
702 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
703 {
704 int ret = 0;
705
706#ifndef OPENSSL_NO_RSA
707 /* Do in software if the key is too large for the hardware. */
708 if (BN_num_bits(m) > max_key_len)
709 {
710 const RSA_METHOD *meth = RSA_PKCS1_SSLeay();
711 ret = (*meth->bn_mod_exp)(r, a, p, m, ctx, m_ctx);
712 }
713 else
714#endif
715 {
716 ret = ubsec_mod_exp(r, a, p, m, ctx);
717 }
718
719 return ret;
720 }
721
722#ifndef OPENSSL_NO_DH
723/* This function is aliased to mod_exp (with the dh and mont dropped). */
724static int ubsec_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a,
725 const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
726 BN_MONT_CTX *m_ctx)
727 {
728 return ubsec_mod_exp(r, a, p, m, ctx);
729 }
730#endif
731
732#ifndef OPENSSL_NO_DSA
733static DSA_SIG *ubsec_dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
734 {
735 DSA_SIG *to_return = NULL;
736 int s_len = 160, r_len = 160, d_len, fd;
737 BIGNUM m, *r=NULL, *s=NULL;
738
739 BN_init(&m);
740
741 s = BN_new();
742 r = BN_new();
743 if ((s == NULL) || (r==NULL))
744 goto err;
745
746 d_len = p_UBSEC_ubsec_bytes_to_bits((unsigned char *)dgst, dlen);
747
748 if(!bn_wexpand(r, (160+BN_BITS2-1)/BN_BITS2) ||
749 (!bn_wexpand(s, (160+BN_BITS2-1)/BN_BITS2))) {
750 UBSECerr(UBSEC_F_UBSEC_DSA_SIGN, UBSEC_R_BN_EXPAND_FAIL);
751 goto err;
752 }
753
754 if (BN_bin2bn(dgst,dlen,&m) == NULL) {
755 UBSECerr(UBSEC_F_UBSEC_DSA_SIGN, UBSEC_R_BN_EXPAND_FAIL);
756 goto err;
757 }
758
759 if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0) {
760 const DSA_METHOD *meth;
761 fd = 0;
762 UBSECerr(UBSEC_F_UBSEC_INIT, UBSEC_R_UNIT_FAILURE);
763 meth = DSA_OpenSSL();
764 to_return = meth->dsa_do_sign(dgst, dlen, dsa);
765 goto err;
766 }
767
768 if (p_UBSEC_dsa_sign_ioctl(fd, 0, /* compute hash before signing */
769 (unsigned char *)dgst, d_len,
770 NULL, 0, /* compute random value */
771 (unsigned char *)dsa->p->d, BN_num_bits(dsa->p),
772 (unsigned char *)dsa->q->d, BN_num_bits(dsa->q),
773 (unsigned char *)dsa->g->d, BN_num_bits(dsa->g),
774 (unsigned char *)dsa->priv_key->d, BN_num_bits(dsa->priv_key),
775 (unsigned char *)r->d, &r_len,
776 (unsigned char *)s->d, &s_len ) != 0) {
777 const DSA_METHOD *meth;
778
779 UBSECerr(UBSEC_F_UBSEC_DSA_SIGN, UBSEC_R_REQUEST_FAILED);
780 p_UBSEC_ubsec_close(fd);
781 meth = DSA_OpenSSL();
782 to_return = meth->dsa_do_sign(dgst, dlen, dsa);
783
784 goto err;
785 }
786
787 p_UBSEC_ubsec_close(fd);
788
789 r->top = (160+BN_BITS2-1)/BN_BITS2;
790 s->top = (160+BN_BITS2-1)/BN_BITS2;
791
792 to_return = DSA_SIG_new();
793 if(to_return == NULL) {
794 UBSECerr(UBSEC_F_UBSEC_DSA_SIGN, UBSEC_R_BN_EXPAND_FAIL);
795 goto err;
796 }
797
798 to_return->r = r;
799 to_return->s = s;
800
801err:
802 if (!to_return) {
803 if (r) BN_free(r);
804 if (s) BN_free(s);
805 }
806 BN_clear_free(&m);
807 return to_return;
808}
809
810static int ubsec_dsa_verify(const unsigned char *dgst, int dgst_len,
811 DSA_SIG *sig, DSA *dsa)
812 {
813 int v_len, d_len;
814 int to_return = 0;
815 int fd;
816 BIGNUM v;
817
818 BN_init(&v);
819
820 if(!bn_wexpand(&v, dsa->p->top)) {
821 UBSECerr(UBSEC_F_UBSEC_DSA_VERIFY ,UBSEC_R_BN_EXPAND_FAIL);
822 goto err;
823 }
824
825 v_len = BN_num_bits(dsa->p);
826
827 d_len = p_UBSEC_ubsec_bytes_to_bits((unsigned char *)dgst, dgst_len);
828
829 if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0) {
830 const DSA_METHOD *meth;
831 fd = 0;
832 UBSECerr(UBSEC_F_UBSEC_INIT, UBSEC_R_UNIT_FAILURE);
833 meth = DSA_OpenSSL();
834 to_return = meth->dsa_do_verify(dgst, dgst_len, sig, dsa);
835 goto err;
836 }
837
838 if (p_UBSEC_dsa_verify_ioctl(fd, 0, /* compute hash before signing */
839 (unsigned char *)dgst, d_len,
840 (unsigned char *)dsa->p->d, BN_num_bits(dsa->p),
841 (unsigned char *)dsa->q->d, BN_num_bits(dsa->q),
842 (unsigned char *)dsa->g->d, BN_num_bits(dsa->g),
843 (unsigned char *)dsa->pub_key->d, BN_num_bits(dsa->pub_key),
844 (unsigned char *)sig->r->d, BN_num_bits(sig->r),
845 (unsigned char *)sig->s->d, BN_num_bits(sig->s),
846 (unsigned char *)v.d, &v_len) != 0) {
847 const DSA_METHOD *meth;
848 UBSECerr(UBSEC_F_UBSEC_DSA_VERIFY , UBSEC_R_REQUEST_FAILED);
849 p_UBSEC_ubsec_close(fd);
850
851 meth = DSA_OpenSSL();
852 to_return = meth->dsa_do_verify(dgst, dgst_len, sig, dsa);
853
854 goto err;
855 }
856
857 p_UBSEC_ubsec_close(fd);
858
859 to_return = 1;
860err:
861 BN_clear_free(&v);
862 return to_return;
863 }
864#endif
865
866#ifndef OPENSSL_NO_DH
867static int ubsec_dh_compute_key (unsigned char *key,const BIGNUM *pub_key,DH *dh)
868 {
869 int ret = -1,
870 k_len,
871 fd;
872
873 k_len = BN_num_bits(dh->p);
874
875 if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0)
876 {
877 const DH_METHOD *meth;
878 ENGINEerr(UBSEC_F_UBSEC_INIT, UBSEC_R_UNIT_FAILURE);
879 meth = DH_OpenSSL();
880 ret = meth->compute_key(key, pub_key, dh);
881 goto err;
882 }
883
884 if (p_UBSEC_diffie_hellman_agree_ioctl(fd,
885 (unsigned char *)dh->priv_key->d, BN_num_bits(dh->priv_key),
886 (unsigned char *)pub_key->d, BN_num_bits(pub_key),
887 (unsigned char *)dh->p->d, BN_num_bits(dh->p),
888 key, &k_len) != 0)
889 {
890 /* Hardware's a no go, failover to software */
891 const DH_METHOD *meth;
892 ENGINEerr(UBSEC_F_UBSEC_DH_COMPUTE_KEY, UBSEC_R_REQUEST_FAILED);
893 p_UBSEC_ubsec_close(fd);
894
895 meth = DH_OpenSSL();
896 ret = meth->compute_key(key, pub_key, dh);
897
898 goto err;
899 }
900
901 p_UBSEC_ubsec_close(fd);
902
903 ret = p_UBSEC_ubsec_bits_to_bytes(k_len);
904err:
905 return ret;
906 }
907
908static int ubsec_dh_generate_key (DH *dh)
909 {
910 int ret = 0,
911 random_bits = 0,
912 pub_key_len = 0,
913 priv_key_len = 0,
914 fd;
915 BIGNUM *pub_key = NULL;
916 BIGNUM *priv_key = NULL;
917
918 /*
919 * How many bits should Random x be? dh_key.c
920 * sets the range from 0 to num_bits(modulus) ???
921 */
922
923 if (dh->priv_key == NULL)
924 {
925 priv_key = BN_new();
926 if (priv_key == NULL) goto err;
927 priv_key_len = BN_num_bits(dh->p);
928 bn_wexpand(priv_key, dh->p->top);
929 do
930 if (!BN_rand_range(priv_key, dh->p)) goto err;
931 while (BN_is_zero(priv_key));
932 random_bits = BN_num_bits(priv_key);
933 }
934 else
935 {
936 priv_key = dh->priv_key;
937 }
938
939 if (dh->pub_key == NULL)
940 {
941 pub_key = BN_new();
942 pub_key_len = BN_num_bits(dh->p);
943 bn_wexpand(pub_key, dh->p->top);
944 if(pub_key == NULL) goto err;
945 }
946 else
947 {
948 pub_key = dh->pub_key;
949 }
950
951 if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0)
952 {
953 const DH_METHOD *meth;
954 ENGINEerr(UBSEC_F_UBSEC_INIT, UBSEC_R_UNIT_FAILURE);
955 meth = DH_OpenSSL();
956 ret = meth->generate_key(dh);
957 goto err;
958 }
959
960 if (p_UBSEC_diffie_hellman_generate_ioctl(fd,
961 (unsigned char *)priv_key->d, &priv_key_len,
962 (unsigned char *)pub_key->d, &pub_key_len,
963 (unsigned char *)dh->g->d, BN_num_bits(dh->g),
964 (unsigned char *)dh->p->d, BN_num_bits(dh->p),
965 0, 0, random_bits) != 0)
966 {
967 /* Hardware's a no go, failover to software */
968 const DH_METHOD *meth;
969
970 ENGINEerr(UBSEC_F_UBSEC_DH_COMPUTE_KEY, UBSEC_R_REQUEST_FAILED);
971 p_UBSEC_ubsec_close(fd);
972
973 meth = DH_OpenSSL();
974 ret = meth->generate_key(dh);
975
976 goto err;
977 }
978
979 p_UBSEC_ubsec_close(fd);
980
981 dh->pub_key = pub_key;
982 dh->pub_key->top = (pub_key_len + BN_BITS2-1) / BN_BITS2;
983 dh->priv_key = priv_key;
984 dh->priv_key->top = (priv_key_len + BN_BITS2-1) / BN_BITS2;
985
986 ret = 1;
987err:
988 return ret;
989 }
990#endif
991
992#ifdef NOT_USED
993static int ubsec_rand_bytes(unsigned char * buf,
994 int num)
995 {
996 int ret = 0,
997 fd;
998
999 if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0)
1000 {
1001 const RAND_METHOD *meth;
1002 ENGINEerr(UBSEC_F_UBSEC_INIT, UBSEC_R_UNIT_FAILURE);
1003 num = p_UBSEC_ubsec_bits_to_bytes(num);
1004 meth = RAND_SSLeay();
1005 meth->seed(buf, num);
1006 ret = meth->bytes(buf, num);
1007 goto err;
1008 }
1009
1010 num *= 8; /* bytes to bits */
1011
1012 if (p_UBSEC_rng_ioctl(fd,
1013 UBSEC_RNG_DIRECT,
1014 buf,
1015 &num) != 0)
1016 {
1017 /* Hardware's a no go, failover to software */
1018 const RAND_METHOD *meth;
1019
1020 ENGINEerr(UBSEC_F_UBSEC_RNG_BYTES, UBSEC_R_REQUEST_FAILED);
1021 p_UBSEC_ubsec_close(fd);
1022
1023 num = p_UBSEC_ubsec_bits_to_bytes(num);
1024 meth = RAND_SSLeay();
1025 meth->seed(buf, num);
1026 ret = meth->bytes(buf, num);
1027
1028 goto err;
1029 }
1030
1031 p_UBSEC_ubsec_close(fd);
1032
1033 ret = 1;
1034err:
1035 return(ret);
1036 }
1037
1038
1039static int ubsec_rand_status(void)
1040 {
1041 return 0;
1042 }
1043#endif
1044
1045/* This stuff is needed if this ENGINE is being compiled into a self-contained
1046 * shared-library. */
1047#ifdef ENGINE_DYNAMIC_SUPPORT
1048static int bind_fn(ENGINE *e, const char *id)
1049 {
1050 if(id && (strcmp(id, engine_ubsec_id) != 0))
1051 return 0;
1052 if(!bind_helper(e))
1053 return 0;
1054 return 1;
1055 }
1056IMPLEMENT_DYNAMIC_CHECK_FN()
1057IMPLEMENT_DYNAMIC_BIND_FN(bind_fn)
1058#endif /* ENGINE_DYNAMIC_SUPPORT */
1059
1060#endif /* !OPENSSL_NO_HW_UBSEC */
1061#endif /* !OPENSSL_NO_HW */
diff --git a/src/lib/libcrypto/engine/hw_ubsec_err.c b/src/lib/libcrypto/engine/hw_ubsec_err.c
deleted file mode 100644
index d707331fc2..0000000000
--- a/src/lib/libcrypto/engine/hw_ubsec_err.c
+++ /dev/null
@@ -1,151 +0,0 @@
1/* hw_ubsec_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 "hw_ubsec_err.h"
64
65/* BEGIN ERROR CODES */
66#ifndef OPENSSL_NO_ERR
67static ERR_STRING_DATA UBSEC_str_functs[]=
68 {
69{ERR_PACK(0,UBSEC_F_UBSEC_CTRL,0), "UBSEC_CTRL"},
70{ERR_PACK(0,UBSEC_F_UBSEC_DH_COMPUTE_KEY,0), "UBSEC_DH_COMPUTE_KEY"},
71{ERR_PACK(0,UBSEC_F_UBSEC_DSA_SIGN,0), "UBSEC_DSA_SIGN"},
72{ERR_PACK(0,UBSEC_F_UBSEC_DSA_VERIFY,0), "UBSEC_DSA_VERIFY"},
73{ERR_PACK(0,UBSEC_F_UBSEC_FINISH,0), "UBSEC_FINISH"},
74{ERR_PACK(0,UBSEC_F_UBSEC_INIT,0), "UBSEC_INIT"},
75{ERR_PACK(0,UBSEC_F_UBSEC_MOD_EXP,0), "UBSEC_MOD_EXP"},
76{ERR_PACK(0,UBSEC_F_UBSEC_RNG_BYTES,0), "UBSEC_RNG_BYTES"},
77{ERR_PACK(0,UBSEC_F_UBSEC_RSA_MOD_EXP,0), "UBSEC_RSA_MOD_EXP"},
78{ERR_PACK(0,UBSEC_F_UBSEC_RSA_MOD_EXP_CRT,0), "UBSEC_RSA_MOD_EXP_CRT"},
79{0,NULL}
80 };
81
82static ERR_STRING_DATA UBSEC_str_reasons[]=
83 {
84{UBSEC_R_ALREADY_LOADED ,"already loaded"},
85{UBSEC_R_BN_EXPAND_FAIL ,"bn expand fail"},
86{UBSEC_R_CTRL_COMMAND_NOT_IMPLEMENTED ,"ctrl command not implemented"},
87{UBSEC_R_DSO_FAILURE ,"dso failure"},
88{UBSEC_R_MISSING_KEY_COMPONENTS ,"missing key components"},
89{UBSEC_R_NOT_LOADED ,"not loaded"},
90{UBSEC_R_REQUEST_FAILED ,"request failed"},
91{UBSEC_R_SIZE_TOO_LARGE_OR_TOO_SMALL ,"size too large or too small"},
92{UBSEC_R_UNIT_FAILURE ,"unit failure"},
93{0,NULL}
94 };
95
96#endif
97
98#ifdef UBSEC_LIB_NAME
99static ERR_STRING_DATA UBSEC_lib_name[]=
100 {
101{0 ,UBSEC_LIB_NAME},
102{0,NULL}
103 };
104#endif
105
106
107static int UBSEC_lib_error_code=0;
108static int UBSEC_error_init=1;
109
110static void ERR_load_UBSEC_strings(void)
111 {
112 if (UBSEC_lib_error_code == 0)
113 UBSEC_lib_error_code=ERR_get_next_error_library();
114
115 if (UBSEC_error_init)
116 {
117 UBSEC_error_init=0;
118#ifndef OPENSSL_NO_ERR
119 ERR_load_strings(UBSEC_lib_error_code,UBSEC_str_functs);
120 ERR_load_strings(UBSEC_lib_error_code,UBSEC_str_reasons);
121#endif
122
123#ifdef UBSEC_LIB_NAME
124 UBSEC_lib_name->error = ERR_PACK(UBSEC_lib_error_code,0,0);
125 ERR_load_strings(0,UBSEC_lib_name);
126#endif
127 }
128 }
129
130static void ERR_unload_UBSEC_strings(void)
131 {
132 if (UBSEC_error_init == 0)
133 {
134#ifndef OPENSSL_NO_ERR
135 ERR_unload_strings(UBSEC_lib_error_code,UBSEC_str_functs);
136 ERR_unload_strings(UBSEC_lib_error_code,UBSEC_str_reasons);
137#endif
138
139#ifdef UBSEC_LIB_NAME
140 ERR_unload_strings(0,UBSEC_lib_name);
141#endif
142 UBSEC_error_init=1;
143 }
144 }
145
146static void ERR_UBSEC_error(int function, int reason, char *file, int line)
147 {
148 if (UBSEC_lib_error_code == 0)
149 UBSEC_lib_error_code=ERR_get_next_error_library();
150 ERR_PUT_error(UBSEC_lib_error_code,function,reason,file,line);
151 }
diff --git a/src/lib/libcrypto/engine/tb_asnmth.c b/src/lib/libcrypto/engine/tb_asnmth.c
new file mode 100644
index 0000000000..75090339f7
--- /dev/null
+++ b/src/lib/libcrypto/engine/tb_asnmth.c
@@ -0,0 +1,246 @@
1/* ====================================================================
2 * Copyright (c) 2006 The OpenSSL Project. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in
13 * the documentation and/or other materials provided with the
14 * distribution.
15 *
16 * 3. All advertising materials mentioning features or use of this
17 * software must display the following acknowledgment:
18 * "This product includes software developed by the OpenSSL Project
19 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
20 *
21 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
22 * endorse or promote products derived from this software without
23 * prior written permission. For written permission, please contact
24 * licensing@OpenSSL.org.
25 *
26 * 5. Products derived from this software may not be called "OpenSSL"
27 * nor may "OpenSSL" appear in their names without prior written
28 * permission of the OpenSSL Project.
29 *
30 * 6. Redistributions of any form whatsoever must retain the following
31 * acknowledgment:
32 * "This product includes software developed by the OpenSSL Project
33 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
34 *
35 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
36 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
37 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
38 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
39 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
41 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
42 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
43 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
44 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
45 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
46 * OF THE POSSIBILITY OF SUCH DAMAGE.
47 * ====================================================================
48 *
49 * This product includes cryptographic software written by Eric Young
50 * (eay@cryptsoft.com). This product includes software written by Tim
51 * Hudson (tjh@cryptsoft.com).
52 *
53 */
54
55#include "eng_int.h"
56#include "asn1_locl.h"
57#include <openssl/evp.h>
58
59/* If this symbol is defined then ENGINE_get_pkey_asn1_meth_engine(), the
60 * function that is used by EVP to hook in pkey_asn1_meth code and cache
61 * defaults (etc), will display brief debugging summaries to stderr with the
62 * 'nid'. */
63/* #define ENGINE_PKEY_ASN1_METH_DEBUG */
64
65static ENGINE_TABLE *pkey_asn1_meth_table = NULL;
66
67void ENGINE_unregister_pkey_asn1_meths(ENGINE *e)
68 {
69 engine_table_unregister(&pkey_asn1_meth_table, e);
70 }
71
72static void engine_unregister_all_pkey_asn1_meths(void)
73 {
74 engine_table_cleanup(&pkey_asn1_meth_table);
75 }
76
77int ENGINE_register_pkey_asn1_meths(ENGINE *e)
78 {
79 if(e->pkey_asn1_meths)
80 {
81 const int *nids;
82 int num_nids = e->pkey_asn1_meths(e, NULL, &nids, 0);
83 if(num_nids > 0)
84 return engine_table_register(&pkey_asn1_meth_table,
85 engine_unregister_all_pkey_asn1_meths, e, nids,
86 num_nids, 0);
87 }
88 return 1;
89 }
90
91void ENGINE_register_all_pkey_asn1_meths(void)
92 {
93 ENGINE *e;
94
95 for(e=ENGINE_get_first() ; e ; e=ENGINE_get_next(e))
96 ENGINE_register_pkey_asn1_meths(e);
97 }
98
99int ENGINE_set_default_pkey_asn1_meths(ENGINE *e)
100 {
101 if(e->pkey_asn1_meths)
102 {
103 const int *nids;
104 int num_nids = e->pkey_asn1_meths(e, NULL, &nids, 0);
105 if(num_nids > 0)
106 return engine_table_register(&pkey_asn1_meth_table,
107 engine_unregister_all_pkey_asn1_meths, e, nids,
108 num_nids, 1);
109 }
110 return 1;
111 }
112
113/* Exposed API function to get a functional reference from the implementation
114 * table (ie. try to get a functional reference from the tabled structural
115 * references) for a given pkey_asn1_meth 'nid' */
116ENGINE *ENGINE_get_pkey_asn1_meth_engine(int nid)
117 {
118 return engine_table_select(&pkey_asn1_meth_table, nid);
119 }
120
121/* Obtains a pkey_asn1_meth implementation from an ENGINE functional reference */
122const EVP_PKEY_ASN1_METHOD *ENGINE_get_pkey_asn1_meth(ENGINE *e, int nid)
123 {
124 EVP_PKEY_ASN1_METHOD *ret;
125 ENGINE_PKEY_ASN1_METHS_PTR fn = ENGINE_get_pkey_asn1_meths(e);
126 if(!fn || !fn(e, &ret, NULL, nid))
127 {
128 ENGINEerr(ENGINE_F_ENGINE_GET_PKEY_ASN1_METH,
129 ENGINE_R_UNIMPLEMENTED_PUBLIC_KEY_METHOD);
130 return NULL;
131 }
132 return ret;
133 }
134
135/* Gets the pkey_asn1_meth callback from an ENGINE structure */
136ENGINE_PKEY_ASN1_METHS_PTR ENGINE_get_pkey_asn1_meths(const ENGINE *e)
137 {
138 return e->pkey_asn1_meths;
139 }
140
141/* Sets the pkey_asn1_meth callback in an ENGINE structure */
142int ENGINE_set_pkey_asn1_meths(ENGINE *e, ENGINE_PKEY_ASN1_METHS_PTR f)
143 {
144 e->pkey_asn1_meths = f;
145 return 1;
146 }
147
148/* Internal function to free up EVP_PKEY_ASN1_METHOD structures before an
149 * ENGINE is destroyed
150 */
151
152void engine_pkey_asn1_meths_free(ENGINE *e)
153 {
154 int i;
155 EVP_PKEY_ASN1_METHOD *pkm;
156 if (e->pkey_asn1_meths)
157 {
158 const int *pknids;
159 int npknids;
160 npknids = e->pkey_asn1_meths(e, NULL, &pknids, 0);
161 for (i = 0; i < npknids; i++)
162 {
163 if (e->pkey_asn1_meths(e, &pkm, NULL, pknids[i]))
164 {
165 EVP_PKEY_asn1_free(pkm);
166 }
167 }
168 }
169 }
170
171/* Find a method based on a string. This does a linear search through
172 * all implemented algorithms. This is OK in practice because only
173 * a small number of algorithms are likely to be implemented in an engine
174 * and it is not used for speed critical operations.
175 */
176
177const EVP_PKEY_ASN1_METHOD *ENGINE_get_pkey_asn1_meth_str(ENGINE *e,
178 const char *str, int len)
179 {
180 int i, nidcount;
181 const int *nids;
182 EVP_PKEY_ASN1_METHOD *ameth;
183 if (!e->pkey_asn1_meths)
184 return NULL;
185 if (len == -1)
186 len = strlen(str);
187 nidcount = e->pkey_asn1_meths(e, NULL, &nids, 0);
188 for (i = 0; i < nidcount; i++)
189 {
190 e->pkey_asn1_meths(e, &ameth, NULL, nids[i]);
191 if (((int)strlen(ameth->pem_str) == len) &&
192 !strncasecmp(ameth->pem_str, str, len))
193 return ameth;
194 }
195 return NULL;
196 }
197
198typedef struct
199 {
200 ENGINE *e;
201 const EVP_PKEY_ASN1_METHOD *ameth;
202 const char *str;
203 int len;
204 } ENGINE_FIND_STR;
205
206static void look_str_cb(int nid, STACK_OF(ENGINE) *sk, ENGINE *def, void *arg)
207 {
208 ENGINE_FIND_STR *lk = arg;
209 int i;
210 if (lk->ameth)
211 return;
212 for (i = 0; i < sk_ENGINE_num(sk); i++)
213 {
214 ENGINE *e = sk_ENGINE_value(sk, i);
215 EVP_PKEY_ASN1_METHOD *ameth;
216 e->pkey_asn1_meths(e, &ameth, NULL, nid);
217 if (((int)strlen(ameth->pem_str) == lk->len) &&
218 !strncasecmp(ameth->pem_str, lk->str, lk->len))
219 {
220 lk->e = e;
221 lk->ameth = ameth;
222 return;
223 }
224 }
225 }
226
227const EVP_PKEY_ASN1_METHOD *ENGINE_pkey_asn1_find_str(ENGINE **pe,
228 const char *str, int len)
229 {
230 ENGINE_FIND_STR fstr;
231 fstr.e = NULL;
232 fstr.ameth = NULL;
233 fstr.str = str;
234 fstr.len = len;
235 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
236 engine_table_doall(pkey_asn1_meth_table, look_str_cb, &fstr);
237 /* If found obtain a structural reference to engine */
238 if (fstr.e)
239 {
240 fstr.e->struct_ref++;
241 engine_ref_debug(fstr.e, 0, 1)
242 }
243 *pe = fstr.e;
244 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
245 return fstr.ameth;
246 }
diff --git a/src/lib/libcrypto/engine/hw_nuron_err.c b/src/lib/libcrypto/engine/tb_cipher.c
index df9d7bde76..177fc1fb73 100644
--- a/src/lib/libcrypto/engine/hw_nuron_err.c
+++ b/src/lib/libcrypto/engine/tb_cipher.c
@@ -1,6 +1,5 @@
1/* hw_nuron_err.c */
2/* ==================================================================== 1/* ====================================================================
3 * Copyright (c) 1999 The OpenSSL Project. All rights reserved. 2 * Copyright (c) 2000 The OpenSSL Project. All rights reserved.
4 * 3 *
5 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 5 * modification, are permitted provided that the following conditions
@@ -22,7 +21,7 @@
22 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 21 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
23 * endorse or promote products derived from this software without 22 * endorse or promote products derived from this software without
24 * prior written permission. For written permission, please contact 23 * prior written permission. For written permission, please contact
25 * openssl-core@OpenSSL.org. 24 * licensing@OpenSSL.org.
26 * 25 *
27 * 5. Products derived from this software may not be called "OpenSSL" 26 * 5. Products derived from this software may not be called "OpenSSL"
28 * nor may "OpenSSL" appear in their names without prior written 27 * nor may "OpenSSL" appear in their names without prior written
@@ -53,90 +52,92 @@
53 * 52 *
54 */ 53 */
55 54
56/* NOTE: this file was auto generated by the mkerr.pl script: any changes 55#include "eng_int.h"
57 * made to it will be overwritten when the script next updates this file,
58 * only reason strings will be preserved.
59 */
60 56
61#include <stdio.h> 57/* If this symbol is defined then ENGINE_get_cipher_engine(), the function that
62#include <openssl/err.h> 58 * is used by EVP to hook in cipher code and cache defaults (etc), will display
63#include "hw_nuron_err.h" 59 * brief debugging summaries to stderr with the 'nid'. */
60/* #define ENGINE_CIPHER_DEBUG */
64 61
65/* BEGIN ERROR CODES */ 62static ENGINE_TABLE *cipher_table = NULL;
66#ifndef OPENSSL_NO_ERR
67static ERR_STRING_DATA NURON_str_functs[]=
68 {
69{ERR_PACK(0,NURON_F_NURON_CTRL,0), "NURON_CTRL"},
70{ERR_PACK(0,NURON_F_NURON_FINISH,0), "NURON_FINISH"},
71{ERR_PACK(0,NURON_F_NURON_INIT,0), "NURON_INIT"},
72{ERR_PACK(0,NURON_F_NURON_MOD_EXP,0), "NURON_MOD_EXP"},
73{0,NULL}
74 };
75 63
76static ERR_STRING_DATA NURON_str_reasons[]= 64void ENGINE_unregister_ciphers(ENGINE *e)
77 { 65 {
78{NURON_R_ALREADY_LOADED ,"already loaded"}, 66 engine_table_unregister(&cipher_table, e);
79{NURON_R_CTRL_COMMAND_NOT_IMPLEMENTED ,"ctrl command not implemented"}, 67 }
80{NURON_R_DSO_FAILURE ,"dso failure"},
81{NURON_R_DSO_FUNCTION_NOT_FOUND ,"dso function not found"},
82{NURON_R_DSO_NOT_FOUND ,"dso not found"},
83{NURON_R_NOT_LOADED ,"not loaded"},
84{0,NULL}
85 };
86 68
87#endif 69static void engine_unregister_all_ciphers(void)
70 {
71 engine_table_cleanup(&cipher_table);
72 }
88 73
89#ifdef NURON_LIB_NAME 74int ENGINE_register_ciphers(ENGINE *e)
90static ERR_STRING_DATA NURON_lib_name[]= 75 {
91 { 76 if(e->ciphers)
92{0 ,NURON_LIB_NAME}, 77 {
93{0,NULL} 78 const int *nids;
94 }; 79 int num_nids = e->ciphers(e, NULL, &nids, 0);
95#endif 80 if(num_nids > 0)
81 return engine_table_register(&cipher_table,
82 engine_unregister_all_ciphers, e, nids,
83 num_nids, 0);
84 }
85 return 1;
86 }
96 87
88void ENGINE_register_all_ciphers()
89 {
90 ENGINE *e;
97 91
98static int NURON_lib_error_code=0; 92 for(e=ENGINE_get_first() ; e ; e=ENGINE_get_next(e))
99static int NURON_error_init=1; 93 ENGINE_register_ciphers(e);
94 }
100 95
101static void ERR_load_NURON_strings(void) 96int ENGINE_set_default_ciphers(ENGINE *e)
102 { 97 {
103 if (NURON_lib_error_code == 0) 98 if(e->ciphers)
104 NURON_lib_error_code=ERR_get_next_error_library();
105
106 if (NURON_error_init)
107 { 99 {
108 NURON_error_init=0; 100 const int *nids;
109#ifndef OPENSSL_NO_ERR 101 int num_nids = e->ciphers(e, NULL, &nids, 0);
110 ERR_load_strings(NURON_lib_error_code,NURON_str_functs); 102 if(num_nids > 0)
111 ERR_load_strings(NURON_lib_error_code,NURON_str_reasons); 103 return engine_table_register(&cipher_table,
112#endif 104 engine_unregister_all_ciphers, e, nids,
113 105 num_nids, 1);
114#ifdef NURON_LIB_NAME
115 NURON_lib_name->error = ERR_PACK(NURON_lib_error_code,0,0);
116 ERR_load_strings(0,NURON_lib_name);
117#endif
118 } 106 }
107 return 1;
119 } 108 }
120 109
121static void ERR_unload_NURON_strings(void) 110/* Exposed API function to get a functional reference from the implementation
111 * table (ie. try to get a functional reference from the tabled structural
112 * references) for a given cipher 'nid' */
113ENGINE *ENGINE_get_cipher_engine(int nid)
122 { 114 {
123 if (NURON_error_init == 0) 115 return engine_table_select(&cipher_table, nid);
124 { 116 }
125#ifndef OPENSSL_NO_ERR
126 ERR_unload_strings(NURON_lib_error_code,NURON_str_functs);
127 ERR_unload_strings(NURON_lib_error_code,NURON_str_reasons);
128#endif
129 117
130#ifdef NURON_LIB_NAME 118/* Obtains a cipher implementation from an ENGINE functional reference */
131 ERR_unload_strings(0,NURON_lib_name); 119const EVP_CIPHER *ENGINE_get_cipher(ENGINE *e, int nid)
132#endif 120 {
133 NURON_error_init=1; 121 const EVP_CIPHER *ret;
122 ENGINE_CIPHERS_PTR fn = ENGINE_get_ciphers(e);
123 if(!fn || !fn(e, &ret, NULL, nid))
124 {
125 ENGINEerr(ENGINE_F_ENGINE_GET_CIPHER,
126 ENGINE_R_UNIMPLEMENTED_CIPHER);
127 return NULL;
134 } 128 }
129 return ret;
130 }
131
132/* Gets the cipher callback from an ENGINE structure */
133ENGINE_CIPHERS_PTR ENGINE_get_ciphers(const ENGINE *e)
134 {
135 return e->ciphers;
135 } 136 }
136 137
137static void ERR_NURON_error(int function, int reason, char *file, int line) 138/* Sets the cipher callback in an ENGINE structure */
139int ENGINE_set_ciphers(ENGINE *e, ENGINE_CIPHERS_PTR f)
138 { 140 {
139 if (NURON_lib_error_code == 0) 141 e->ciphers = f;
140 NURON_lib_error_code=ERR_get_next_error_library(); 142 return 1;
141 ERR_PUT_error(NURON_lib_error_code,function,reason,file,line);
142 } 143 }
diff --git a/src/lib/libcrypto/engine/hw_ubsec_err.h b/src/lib/libcrypto/engine/tb_dh.c
index 023d3be771..6e9d428761 100644
--- a/src/lib/libcrypto/engine/hw_ubsec_err.h
+++ b/src/lib/libcrypto/engine/tb_dh.c
@@ -1,5 +1,5 @@
1/* ==================================================================== 1/* ====================================================================
2 * Copyright (c) 2001 The OpenSSL Project. All rights reserved. 2 * Copyright (c) 2000 The OpenSSL Project. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions 5 * modification, are permitted provided that the following conditions
@@ -16,12 +16,12 @@
16 * 3. All advertising materials mentioning features or use of this 16 * 3. All advertising materials mentioning features or use of this
17 * software must display the following acknowledgment: 17 * software must display the following acknowledgment:
18 * "This product includes software developed by the OpenSSL Project 18 * "This product includes software developed by the OpenSSL Project
19 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 19 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
20 * 20 *
21 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 21 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
22 * endorse or promote products derived from this software without 22 * endorse or promote products derived from this software without
23 * prior written permission. For written permission, please contact 23 * prior written permission. For written permission, please contact
24 * openssl-core@openssl.org. 24 * licensing@OpenSSL.org.
25 * 25 *
26 * 5. Products derived from this software may not be called "OpenSSL" 26 * 5. Products derived from this software may not be called "OpenSSL"
27 * nor may "OpenSSL" appear in their names without prior written 27 * nor may "OpenSSL" appear in their names without prior written
@@ -30,7 +30,7 @@
30 * 6. Redistributions of any form whatsoever must retain the following 30 * 6. Redistributions of any form whatsoever must retain the following
31 * acknowledgment: 31 * acknowledgment:
32 * "This product includes software developed by the OpenSSL Project 32 * "This product includes software developed by the OpenSSL Project
33 * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 33 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
34 * 34 *
35 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 35 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
36 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 36 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
@@ -52,44 +52,67 @@
52 * 52 *
53 */ 53 */
54 54
55#ifndef HEADER_UBSEC_ERR_H 55#include "eng_int.h"
56#define HEADER_UBSEC_ERR_H
57 56
58/* BEGIN ERROR CODES */ 57/* If this symbol is defined then ENGINE_get_default_DH(), the function that is
59/* The following lines are auto generated by the script mkerr.pl. Any changes 58 * used by DH to hook in implementation code and cache defaults (etc), will
60 * made after this point may be overwritten when the script is next run. 59 * display brief debugging summaries to stderr with the 'nid'. */
61 */ 60/* #define ENGINE_DH_DEBUG */
62static void ERR_load_UBSEC_strings(void); 61
63static void ERR_unload_UBSEC_strings(void); 62static ENGINE_TABLE *dh_table = NULL;
64static void ERR_UBSEC_error(int function, int reason, char *file, int line); 63static const int dummy_nid = 1;
65#define UBSECerr(f,r) ERR_UBSEC_error((f),(r),__FILE__,__LINE__) 64
65void ENGINE_unregister_DH(ENGINE *e)
66 {
67 engine_table_unregister(&dh_table, e);
68 }
69
70static void engine_unregister_all_DH(void)
71 {
72 engine_table_cleanup(&dh_table);
73 }
74
75int ENGINE_register_DH(ENGINE *e)
76 {
77 if(e->dh_meth)
78 return engine_table_register(&dh_table,
79 engine_unregister_all_DH, e, &dummy_nid, 1, 0);
80 return 1;
81 }
82
83void ENGINE_register_all_DH()
84 {
85 ENGINE *e;
86
87 for(e=ENGINE_get_first() ; e ; e=ENGINE_get_next(e))
88 ENGINE_register_DH(e);
89 }
66 90
67/* Error codes for the UBSEC functions. */ 91int ENGINE_set_default_DH(ENGINE *e)
92 {
93 if(e->dh_meth)
94 return engine_table_register(&dh_table,
95 engine_unregister_all_DH, e, &dummy_nid, 1, 1);
96 return 1;
97 }
68 98
69/* Function codes. */ 99/* Exposed API function to get a functional reference from the implementation
70#define UBSEC_F_UBSEC_CTRL 100 100 * table (ie. try to get a functional reference from the tabled structural
71#define UBSEC_F_UBSEC_DH_COMPUTE_KEY 101 101 * references). */
72#define UBSEC_F_UBSEC_DSA_SIGN 102 102ENGINE *ENGINE_get_default_DH(void)
73#define UBSEC_F_UBSEC_DSA_VERIFY 103 103 {
74#define UBSEC_F_UBSEC_FINISH 104 104 return engine_table_select(&dh_table, dummy_nid);
75#define UBSEC_F_UBSEC_INIT 105 105 }
76#define UBSEC_F_UBSEC_MOD_EXP 106
77#define UBSEC_F_UBSEC_RNG_BYTES 107
78#define UBSEC_F_UBSEC_RSA_MOD_EXP 108
79#define UBSEC_F_UBSEC_RSA_MOD_EXP_CRT 109
80 106
81/* Reason codes. */ 107/* Obtains an DH implementation from an ENGINE functional reference */
82#define UBSEC_R_ALREADY_LOADED 100 108const DH_METHOD *ENGINE_get_DH(const ENGINE *e)
83#define UBSEC_R_BN_EXPAND_FAIL 101 109 {
84#define UBSEC_R_CTRL_COMMAND_NOT_IMPLEMENTED 102 110 return e->dh_meth;
85#define UBSEC_R_DSO_FAILURE 103 111 }
86#define UBSEC_R_MISSING_KEY_COMPONENTS 104
87#define UBSEC_R_NOT_LOADED 105
88#define UBSEC_R_REQUEST_FAILED 106
89#define UBSEC_R_SIZE_TOO_LARGE_OR_TOO_SMALL 107
90#define UBSEC_R_UNIT_FAILURE 108
91 112
92#ifdef __cplusplus 113/* Sets an DH implementation in an ENGINE structure */
93} 114int ENGINE_set_DH(ENGINE *e, const DH_METHOD *dh_meth)
94#endif 115 {
95#endif 116 e->dh_meth = dh_meth;
117 return 1;
118 }
diff --git a/src/lib/libcrypto/engine/tb_digest.c b/src/lib/libcrypto/engine/tb_digest.c
new file mode 100644
index 0000000000..d3f4bb2747
--- /dev/null
+++ b/src/lib/libcrypto/engine/tb_digest.c
@@ -0,0 +1,143 @@
1/* ====================================================================
2 * Copyright (c) 2000 The OpenSSL Project. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in
13 * the documentation and/or other materials provided with the
14 * distribution.
15 *
16 * 3. All advertising materials mentioning features or use of this
17 * software must display the following acknowledgment:
18 * "This product includes software developed by the OpenSSL Project
19 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
20 *
21 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
22 * endorse or promote products derived from this software without
23 * prior written permission. For written permission, please contact
24 * licensing@OpenSSL.org.
25 *
26 * 5. Products derived from this software may not be called "OpenSSL"
27 * nor may "OpenSSL" appear in their names without prior written
28 * permission of the OpenSSL Project.
29 *
30 * 6. Redistributions of any form whatsoever must retain the following
31 * acknowledgment:
32 * "This product includes software developed by the OpenSSL Project
33 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
34 *
35 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
36 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
37 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
38 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
39 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
41 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
42 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
43 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
44 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
45 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
46 * OF THE POSSIBILITY OF SUCH DAMAGE.
47 * ====================================================================
48 *
49 * This product includes cryptographic software written by Eric Young
50 * (eay@cryptsoft.com). This product includes software written by Tim
51 * Hudson (tjh@cryptsoft.com).
52 *
53 */
54
55#include "eng_int.h"
56
57/* If this symbol is defined then ENGINE_get_digest_engine(), the function that
58 * is used by EVP to hook in digest code and cache defaults (etc), will display
59 * brief debugging summaries to stderr with the 'nid'. */
60/* #define ENGINE_DIGEST_DEBUG */
61
62static ENGINE_TABLE *digest_table = NULL;
63
64void ENGINE_unregister_digests(ENGINE *e)
65 {
66 engine_table_unregister(&digest_table, e);
67 }
68
69static void engine_unregister_all_digests(void)
70 {
71 engine_table_cleanup(&digest_table);
72 }
73
74int ENGINE_register_digests(ENGINE *e)
75 {
76 if(e->digests)
77 {
78 const int *nids;
79 int num_nids = e->digests(e, NULL, &nids, 0);
80 if(num_nids > 0)
81 return engine_table_register(&digest_table,
82 engine_unregister_all_digests, e, nids,
83 num_nids, 0);
84 }
85 return 1;
86 }
87
88void ENGINE_register_all_digests()
89 {
90 ENGINE *e;
91
92 for(e=ENGINE_get_first() ; e ; e=ENGINE_get_next(e))
93 ENGINE_register_digests(e);
94 }
95
96int ENGINE_set_default_digests(ENGINE *e)
97 {
98 if(e->digests)
99 {
100 const int *nids;
101 int num_nids = e->digests(e, NULL, &nids, 0);
102 if(num_nids > 0)
103 return engine_table_register(&digest_table,
104 engine_unregister_all_digests, e, nids,
105 num_nids, 1);
106 }
107 return 1;
108 }
109
110/* Exposed API function to get a functional reference from the implementation
111 * table (ie. try to get a functional reference from the tabled structural
112 * references) for a given digest 'nid' */
113ENGINE *ENGINE_get_digest_engine(int nid)
114 {
115 return engine_table_select(&digest_table, nid);
116 }
117
118/* Obtains a digest implementation from an ENGINE functional reference */
119const EVP_MD *ENGINE_get_digest(ENGINE *e, int nid)
120 {
121 const EVP_MD *ret;
122 ENGINE_DIGESTS_PTR fn = ENGINE_get_digests(e);
123 if(!fn || !fn(e, &ret, NULL, nid))
124 {
125 ENGINEerr(ENGINE_F_ENGINE_GET_DIGEST,
126 ENGINE_R_UNIMPLEMENTED_DIGEST);
127 return NULL;
128 }
129 return ret;
130 }
131
132/* Gets the digest callback from an ENGINE structure */
133ENGINE_DIGESTS_PTR ENGINE_get_digests(const ENGINE *e)
134 {
135 return e->digests;
136 }
137
138/* Sets the digest callback in an ENGINE structure */
139int ENGINE_set_digests(ENGINE *e, ENGINE_DIGESTS_PTR f)
140 {
141 e->digests = f;
142 return 1;
143 }
diff --git a/src/lib/libcrypto/engine/hw_nuron_err.h b/src/lib/libcrypto/engine/tb_dsa.c
index a56bfdf303..e4674f5f07 100644
--- a/src/lib/libcrypto/engine/hw_nuron_err.h
+++ b/src/lib/libcrypto/engine/tb_dsa.c
@@ -1,5 +1,5 @@
1/* ==================================================================== 1/* ====================================================================
2 * Copyright (c) 2001 The OpenSSL Project. All rights reserved. 2 * Copyright (c) 2000 The OpenSSL Project. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions 5 * modification, are permitted provided that the following conditions
@@ -16,12 +16,12 @@
16 * 3. All advertising materials mentioning features or use of this 16 * 3. All advertising materials mentioning features or use of this
17 * software must display the following acknowledgment: 17 * software must display the following acknowledgment:
18 * "This product includes software developed by the OpenSSL Project 18 * "This product includes software developed by the OpenSSL Project
19 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 19 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
20 * 20 *
21 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 21 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
22 * endorse or promote products derived from this software without 22 * endorse or promote products derived from this software without
23 * prior written permission. For written permission, please contact 23 * prior written permission. For written permission, please contact
24 * openssl-core@openssl.org. 24 * licensing@OpenSSL.org.
25 * 25 *
26 * 5. Products derived from this software may not be called "OpenSSL" 26 * 5. Products derived from this software may not be called "OpenSSL"
27 * nor may "OpenSSL" appear in their names without prior written 27 * nor may "OpenSSL" appear in their names without prior written
@@ -30,7 +30,7 @@
30 * 6. Redistributions of any form whatsoever must retain the following 30 * 6. Redistributions of any form whatsoever must retain the following
31 * acknowledgment: 31 * acknowledgment:
32 * "This product includes software developed by the OpenSSL Project 32 * "This product includes software developed by the OpenSSL Project
33 * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 33 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
34 * 34 *
35 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 35 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
36 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 36 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
@@ -52,35 +52,67 @@
52 * 52 *
53 */ 53 */
54 54
55#ifndef HEADER_NURON_ERR_H 55#include "eng_int.h"
56#define HEADER_NURON_ERR_H
57 56
58/* BEGIN ERROR CODES */ 57/* If this symbol is defined then ENGINE_get_default_DSA(), the function that is
59/* The following lines are auto generated by the script mkerr.pl. Any changes 58 * used by DSA to hook in implementation code and cache defaults (etc), will
60 * made after this point may be overwritten when the script is next run. 59 * display brief debugging summaries to stderr with the 'nid'. */
61 */ 60/* #define ENGINE_DSA_DEBUG */
62static void ERR_load_NURON_strings(void); 61
63static void ERR_unload_NURON_strings(void); 62static ENGINE_TABLE *dsa_table = NULL;
64static void ERR_NURON_error(int function, int reason, char *file, int line); 63static const int dummy_nid = 1;
65#define NURONerr(f,r) ERR_NURON_error((f),(r),__FILE__,__LINE__) 64
65void ENGINE_unregister_DSA(ENGINE *e)
66 {
67 engine_table_unregister(&dsa_table, e);
68 }
69
70static void engine_unregister_all_DSA(void)
71 {
72 engine_table_cleanup(&dsa_table);
73 }
74
75int ENGINE_register_DSA(ENGINE *e)
76 {
77 if(e->dsa_meth)
78 return engine_table_register(&dsa_table,
79 engine_unregister_all_DSA, e, &dummy_nid, 1, 0);
80 return 1;
81 }
82
83void ENGINE_register_all_DSA()
84 {
85 ENGINE *e;
86
87 for(e=ENGINE_get_first() ; e ; e=ENGINE_get_next(e))
88 ENGINE_register_DSA(e);
89 }
66 90
67/* Error codes for the NURON functions. */ 91int ENGINE_set_default_DSA(ENGINE *e)
92 {
93 if(e->dsa_meth)
94 return engine_table_register(&dsa_table,
95 engine_unregister_all_DSA, e, &dummy_nid, 1, 1);
96 return 1;
97 }
68 98
69/* Function codes. */ 99/* Exposed API function to get a functional reference from the implementation
70#define NURON_F_NURON_CTRL 100 100 * table (ie. try to get a functional reference from the tabled structural
71#define NURON_F_NURON_FINISH 101 101 * references). */
72#define NURON_F_NURON_INIT 102 102ENGINE *ENGINE_get_default_DSA(void)
73#define NURON_F_NURON_MOD_EXP 103 103 {
104 return engine_table_select(&dsa_table, dummy_nid);
105 }
74 106
75/* Reason codes. */ 107/* Obtains an DSA implementation from an ENGINE functional reference */
76#define NURON_R_ALREADY_LOADED 100 108const DSA_METHOD *ENGINE_get_DSA(const ENGINE *e)
77#define NURON_R_CTRL_COMMAND_NOT_IMPLEMENTED 101 109 {
78#define NURON_R_DSO_FAILURE 102 110 return e->dsa_meth;
79#define NURON_R_DSO_FUNCTION_NOT_FOUND 103 111 }
80#define NURON_R_DSO_NOT_FOUND 104
81#define NURON_R_NOT_LOADED 105
82 112
83#ifdef __cplusplus 113/* Sets an DSA implementation in an ENGINE structure */
84} 114int ENGINE_set_DSA(ENGINE *e, const DSA_METHOD *dsa_meth)
85#endif 115 {
86#endif 116 e->dsa_meth = dsa_meth;
117 return 1;
118 }
diff --git a/src/lib/libcrypto/engine/tb_ecdh.c b/src/lib/libcrypto/engine/tb_ecdh.c
new file mode 100644
index 0000000000..c8ec7812c5
--- /dev/null
+++ b/src/lib/libcrypto/engine/tb_ecdh.c
@@ -0,0 +1,133 @@
1/* crypto/engine/tb_ecdh.c */
2/* ====================================================================
3 * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
4 *
5 * The Elliptic Curve Public-Key Crypto Library (ECC Code) included
6 * herein is developed by SUN MICROSYSTEMS, INC., and is contributed
7 * to the OpenSSL project.
8 *
9 * The ECC Code is licensed pursuant to the OpenSSL open source
10 * license provided below.
11 *
12 * The ECDH engine software is originally written by Nils Gura and
13 * Douglas Stebila of Sun Microsystems Laboratories.
14 *
15 */
16/* ====================================================================
17 * Copyright (c) 2000-2002 The OpenSSL Project. All rights reserved.
18 *
19 * Redistribution and use in source and binary forms, with or without
20 * modification, are permitted provided that the following conditions
21 * are met:
22 *
23 * 1. Redistributions of source code must retain the above copyright
24 * notice, this list of conditions and the following disclaimer.
25 *
26 * 2. Redistributions in binary form must reproduce the above copyright
27 * notice, this list of conditions and the following disclaimer in
28 * the documentation and/or other materials provided with the
29 * distribution.
30 *
31 * 3. All advertising materials mentioning features or use of this
32 * software must display the following acknowledgment:
33 * "This product includes software developed by the OpenSSL Project
34 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
35 *
36 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
37 * endorse or promote products derived from this software without
38 * prior written permission. For written permission, please contact
39 * licensing@OpenSSL.org.
40 *
41 * 5. Products derived from this software may not be called "OpenSSL"
42 * nor may "OpenSSL" appear in their names without prior written
43 * permission of the OpenSSL Project.
44 *
45 * 6. Redistributions of any form whatsoever must retain the following
46 * acknowledgment:
47 * "This product includes software developed by the OpenSSL Project
48 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
49 *
50 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
51 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
52 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
53 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
54 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
55 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
56 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
57 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
58 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
59 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
60 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
61 * OF THE POSSIBILITY OF SUCH DAMAGE.
62 * ====================================================================
63 *
64 * This product includes cryptographic software written by Eric Young
65 * (eay@cryptsoft.com). This product includes software written by Tim
66 * Hudson (tjh@cryptsoft.com).
67 *
68 */
69
70#include "eng_int.h"
71
72/* If this symbol is defined then ENGINE_get_default_ECDH(), the function that is
73 * used by ECDH to hook in implementation code and cache defaults (etc), will
74 * display brief debugging summaries to stderr with the 'nid'. */
75/* #define ENGINE_ECDH_DEBUG */
76
77static ENGINE_TABLE *ecdh_table = NULL;
78static const int dummy_nid = 1;
79
80void ENGINE_unregister_ECDH(ENGINE *e)
81 {
82 engine_table_unregister(&ecdh_table, e);
83 }
84
85static void engine_unregister_all_ECDH(void)
86 {
87 engine_table_cleanup(&ecdh_table);
88 }
89
90int ENGINE_register_ECDH(ENGINE *e)
91 {
92 if(e->ecdh_meth)
93 return engine_table_register(&ecdh_table,
94 engine_unregister_all_ECDH, e, &dummy_nid, 1, 0);
95 return 1;
96 }
97
98void ENGINE_register_all_ECDH()
99 {
100 ENGINE *e;
101
102 for(e=ENGINE_get_first() ; e ; e=ENGINE_get_next(e))
103 ENGINE_register_ECDH(e);
104 }
105
106int ENGINE_set_default_ECDH(ENGINE *e)
107 {
108 if(e->ecdh_meth)
109 return engine_table_register(&ecdh_table,
110 engine_unregister_all_ECDH, e, &dummy_nid, 1, 1);
111 return 1;
112 }
113
114/* Exposed API function to get a functional reference from the implementation
115 * table (ie. try to get a functional reference from the tabled structural
116 * references). */
117ENGINE *ENGINE_get_default_ECDH(void)
118 {
119 return engine_table_select(&ecdh_table, dummy_nid);
120 }
121
122/* Obtains an ECDH implementation from an ENGINE functional reference */
123const ECDH_METHOD *ENGINE_get_ECDH(const ENGINE *e)
124 {
125 return e->ecdh_meth;
126 }
127
128/* Sets an ECDH implementation in an ENGINE structure */
129int ENGINE_set_ECDH(ENGINE *e, const ECDH_METHOD *ecdh_meth)
130 {
131 e->ecdh_meth = ecdh_meth;
132 return 1;
133 }
diff --git a/src/lib/libcrypto/engine/hw_4758_cca_err.h b/src/lib/libcrypto/engine/tb_ecdsa.c
index 2fc563ab11..005ecb622c 100644
--- a/src/lib/libcrypto/engine/hw_4758_cca_err.h
+++ b/src/lib/libcrypto/engine/tb_ecdsa.c
@@ -1,5 +1,5 @@
1/* ==================================================================== 1/* ====================================================================
2 * Copyright (c) 2001 The OpenSSL Project. All rights reserved. 2 * Copyright (c) 2000-2002 The OpenSSL Project. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions 5 * modification, are permitted provided that the following conditions
@@ -16,12 +16,12 @@
16 * 3. All advertising materials mentioning features or use of this 16 * 3. All advertising materials mentioning features or use of this
17 * software must display the following acknowledgment: 17 * software must display the following acknowledgment:
18 * "This product includes software developed by the OpenSSL Project 18 * "This product includes software developed by the OpenSSL Project
19 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 19 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
20 * 20 *
21 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 21 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
22 * endorse or promote products derived from this software without 22 * endorse or promote products derived from this software without
23 * prior written permission. For written permission, please contact 23 * prior written permission. For written permission, please contact
24 * openssl-core@openssl.org. 24 * licensing@OpenSSL.org.
25 * 25 *
26 * 5. Products derived from this software may not be called "OpenSSL" 26 * 5. Products derived from this software may not be called "OpenSSL"
27 * nor may "OpenSSL" appear in their names without prior written 27 * nor may "OpenSSL" appear in their names without prior written
@@ -30,7 +30,7 @@
30 * 6. Redistributions of any form whatsoever must retain the following 30 * 6. Redistributions of any form whatsoever must retain the following
31 * acknowledgment: 31 * acknowledgment:
32 * "This product includes software developed by the OpenSSL Project 32 * "This product includes software developed by the OpenSSL Project
33 * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 33 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
34 * 34 *
35 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 35 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
36 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 36 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
@@ -52,42 +52,67 @@
52 * 52 *
53 */ 53 */
54 54
55#ifndef HEADER_CCA4758_ERR_H 55#include "eng_int.h"
56#define HEADER_CCA4758_ERR_H
57 56
58/* BEGIN ERROR CODES */ 57/* If this symbol is defined then ENGINE_get_default_ECDSA(), the function that is
59/* The following lines are auto generated by the script mkerr.pl. Any changes 58 * used by ECDSA to hook in implementation code and cache defaults (etc), will
60 * made after this point may be overwritten when the script is next run. 59 * display brief debugging summaries to stderr with the 'nid'. */
61 */ 60/* #define ENGINE_ECDSA_DEBUG */
62static void ERR_load_CCA4758_strings(void); 61
63static void ERR_unload_CCA4758_strings(void); 62static ENGINE_TABLE *ecdsa_table = NULL;
64static void ERR_CCA4758_error(int function, int reason, char *file, int line); 63static const int dummy_nid = 1;
65#define CCA4758err(f,r) ERR_CCA4758_error((f),(r),__FILE__,__LINE__) 64
65void ENGINE_unregister_ECDSA(ENGINE *e)
66 {
67 engine_table_unregister(&ecdsa_table, e);
68 }
69
70static void engine_unregister_all_ECDSA(void)
71 {
72 engine_table_cleanup(&ecdsa_table);
73 }
74
75int ENGINE_register_ECDSA(ENGINE *e)
76 {
77 if(e->ecdsa_meth)
78 return engine_table_register(&ecdsa_table,
79 engine_unregister_all_ECDSA, e, &dummy_nid, 1, 0);
80 return 1;
81 }
82
83void ENGINE_register_all_ECDSA()
84 {
85 ENGINE *e;
86
87 for(e=ENGINE_get_first() ; e ; e=ENGINE_get_next(e))
88 ENGINE_register_ECDSA(e);
89 }
66 90
67/* Error codes for the CCA4758 functions. */ 91int ENGINE_set_default_ECDSA(ENGINE *e)
92 {
93 if(e->ecdsa_meth)
94 return engine_table_register(&ecdsa_table,
95 engine_unregister_all_ECDSA, e, &dummy_nid, 1, 1);
96 return 1;
97 }
68 98
69/* Function codes. */ 99/* Exposed API function to get a functional reference from the implementation
70#define CCA4758_F_IBM_4758_CCA_CTRL 100 100 * table (ie. try to get a functional reference from the tabled structural
71#define CCA4758_F_IBM_4758_CCA_FINISH 101 101 * references). */
72#define CCA4758_F_IBM_4758_CCA_INIT 102 102ENGINE *ENGINE_get_default_ECDSA(void)
73#define CCA4758_F_IBM_4758_CCA_LOAD_PRIVKEY 103 103 {
74#define CCA4758_F_IBM_4758_CCA_LOAD_PUBKEY 104 104 return engine_table_select(&ecdsa_table, dummy_nid);
75#define CCA4758_F_IBM_4758_CCA_SIGN 105 105 }
76#define CCA4758_F_IBM_4758_CCA_VERIFY 106
77 106
78/* Reason codes. */ 107/* Obtains an ECDSA implementation from an ENGINE functional reference */
79#define CCA4758_R_ALREADY_LOADED 100 108const ECDSA_METHOD *ENGINE_get_ECDSA(const ENGINE *e)
80#define CCA4758_R_ASN1_OID_UNKNOWN_FOR_MD 101 109 {
81#define CCA4758_R_COMMAND_NOT_IMPLEMENTED 102 110 return e->ecdsa_meth;
82#define CCA4758_R_DSO_FAILURE 103 111 }
83#define CCA4758_R_FAILED_LOADING_PRIVATE_KEY 104
84#define CCA4758_R_FAILED_LOADING_PUBLIC_KEY 105
85#define CCA4758_R_NOT_LOADED 106
86#define CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL 107
87#define CCA4758_R_UNIT_FAILURE 108
88#define CCA4758_R_UNKNOWN_ALGORITHM_TYPE 109
89 112
90#ifdef __cplusplus 113/* Sets an ECDSA implementation in an ENGINE structure */
91} 114int ENGINE_set_ECDSA(ENGINE *e, const ECDSA_METHOD *ecdsa_meth)
92#endif 115 {
93#endif 116 e->ecdsa_meth = ecdsa_meth;
117 return 1;
118 }
diff --git a/src/lib/libcrypto/engine/tb_pkmeth.c b/src/lib/libcrypto/engine/tb_pkmeth.c
new file mode 100644
index 0000000000..1cdb967f25
--- /dev/null
+++ b/src/lib/libcrypto/engine/tb_pkmeth.c
@@ -0,0 +1,167 @@
1/* ====================================================================
2 * Copyright (c) 2006 The OpenSSL Project. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in
13 * the documentation and/or other materials provided with the
14 * distribution.
15 *
16 * 3. All advertising materials mentioning features or use of this
17 * software must display the following acknowledgment:
18 * "This product includes software developed by the OpenSSL Project
19 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
20 *
21 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
22 * endorse or promote products derived from this software without
23 * prior written permission. For written permission, please contact
24 * licensing@OpenSSL.org.
25 *
26 * 5. Products derived from this software may not be called "OpenSSL"
27 * nor may "OpenSSL" appear in their names without prior written
28 * permission of the OpenSSL Project.
29 *
30 * 6. Redistributions of any form whatsoever must retain the following
31 * acknowledgment:
32 * "This product includes software developed by the OpenSSL Project
33 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
34 *
35 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
36 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
37 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
38 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
39 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
41 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
42 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
43 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
44 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
45 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
46 * OF THE POSSIBILITY OF SUCH DAMAGE.
47 * ====================================================================
48 *
49 * This product includes cryptographic software written by Eric Young
50 * (eay@cryptsoft.com). This product includes software written by Tim
51 * Hudson (tjh@cryptsoft.com).
52 *
53 */
54
55#include "eng_int.h"
56#include <openssl/evp.h>
57
58/* If this symbol is defined then ENGINE_get_pkey_meth_engine(), the function
59 * that is used by EVP to hook in pkey_meth code and cache defaults (etc), will
60 * display brief debugging summaries to stderr with the 'nid'. */
61/* #define ENGINE_PKEY_METH_DEBUG */
62
63static ENGINE_TABLE *pkey_meth_table = NULL;
64
65void ENGINE_unregister_pkey_meths(ENGINE *e)
66 {
67 engine_table_unregister(&pkey_meth_table, e);
68 }
69
70static void engine_unregister_all_pkey_meths(void)
71 {
72 engine_table_cleanup(&pkey_meth_table);
73 }
74
75int ENGINE_register_pkey_meths(ENGINE *e)
76 {
77 if(e->pkey_meths)
78 {
79 const int *nids;
80 int num_nids = e->pkey_meths(e, NULL, &nids, 0);
81 if(num_nids > 0)
82 return engine_table_register(&pkey_meth_table,
83 engine_unregister_all_pkey_meths, e, nids,
84 num_nids, 0);
85 }
86 return 1;
87 }
88
89void ENGINE_register_all_pkey_meths()
90 {
91 ENGINE *e;
92
93 for(e=ENGINE_get_first() ; e ; e=ENGINE_get_next(e))
94 ENGINE_register_pkey_meths(e);
95 }
96
97int ENGINE_set_default_pkey_meths(ENGINE *e)
98 {
99 if(e->pkey_meths)
100 {
101 const int *nids;
102 int num_nids = e->pkey_meths(e, NULL, &nids, 0);
103 if(num_nids > 0)
104 return engine_table_register(&pkey_meth_table,
105 engine_unregister_all_pkey_meths, e, nids,
106 num_nids, 1);
107 }
108 return 1;
109 }
110
111/* Exposed API function to get a functional reference from the implementation
112 * table (ie. try to get a functional reference from the tabled structural
113 * references) for a given pkey_meth 'nid' */
114ENGINE *ENGINE_get_pkey_meth_engine(int nid)
115 {
116 return engine_table_select(&pkey_meth_table, nid);
117 }
118
119/* Obtains a pkey_meth implementation from an ENGINE functional reference */
120const EVP_PKEY_METHOD *ENGINE_get_pkey_meth(ENGINE *e, int nid)
121 {
122 EVP_PKEY_METHOD *ret;
123 ENGINE_PKEY_METHS_PTR fn = ENGINE_get_pkey_meths(e);
124 if(!fn || !fn(e, &ret, NULL, nid))
125 {
126 ENGINEerr(ENGINE_F_ENGINE_GET_PKEY_METH,
127 ENGINE_R_UNIMPLEMENTED_PUBLIC_KEY_METHOD);
128 return NULL;
129 }
130 return ret;
131 }
132
133/* Gets the pkey_meth callback from an ENGINE structure */
134ENGINE_PKEY_METHS_PTR ENGINE_get_pkey_meths(const ENGINE *e)
135 {
136 return e->pkey_meths;
137 }
138
139/* Sets the pkey_meth callback in an ENGINE structure */
140int ENGINE_set_pkey_meths(ENGINE *e, ENGINE_PKEY_METHS_PTR f)
141 {
142 e->pkey_meths = f;
143 return 1;
144 }
145
146/* Internal function to free up EVP_PKEY_METHOD structures before an
147 * ENGINE is destroyed
148 */
149
150void engine_pkey_meths_free(ENGINE *e)
151 {
152 int i;
153 EVP_PKEY_METHOD *pkm;
154 if (e->pkey_meths)
155 {
156 const int *pknids;
157 int npknids;
158 npknids = e->pkey_meths(e, NULL, &pknids, 0);
159 for (i = 0; i < npknids; i++)
160 {
161 if (e->pkey_meths(e, &pkm, NULL, pknids[i]))
162 {
163 EVP_PKEY_meth_free(pkm);
164 }
165 }
166 }
167 }
diff --git a/src/lib/libcrypto/engine/hw_aep_err.h b/src/lib/libcrypto/engine/tb_rand.c
index 8fe4cf921f..f36f67c0f6 100644
--- a/src/lib/libcrypto/engine/hw_aep_err.h
+++ b/src/lib/libcrypto/engine/tb_rand.c
@@ -1,5 +1,5 @@
1/* ==================================================================== 1/* ====================================================================
2 * Copyright (c) 2001 The OpenSSL Project. All rights reserved. 2 * Copyright (c) 2000 The OpenSSL Project. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions 5 * modification, are permitted provided that the following conditions
@@ -16,12 +16,12 @@
16 * 3. All advertising materials mentioning features or use of this 16 * 3. All advertising materials mentioning features or use of this
17 * software must display the following acknowledgment: 17 * software must display the following acknowledgment:
18 * "This product includes software developed by the OpenSSL Project 18 * "This product includes software developed by the OpenSSL Project
19 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 19 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
20 * 20 *
21 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 21 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
22 * endorse or promote products derived from this software without 22 * endorse or promote products derived from this software without
23 * prior written permission. For written permission, please contact 23 * prior written permission. For written permission, please contact
24 * openssl-core@openssl.org. 24 * licensing@OpenSSL.org.
25 * 25 *
26 * 5. Products derived from this software may not be called "OpenSSL" 26 * 5. Products derived from this software may not be called "OpenSSL"
27 * nor may "OpenSSL" appear in their names without prior written 27 * nor may "OpenSSL" appear in their names without prior written
@@ -30,7 +30,7 @@
30 * 6. Redistributions of any form whatsoever must retain the following 30 * 6. Redistributions of any form whatsoever must retain the following
31 * acknowledgment: 31 * acknowledgment:
32 * "This product includes software developed by the OpenSSL Project 32 * "This product includes software developed by the OpenSSL Project
33 * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 33 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
34 * 34 *
35 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 35 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
36 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 36 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
@@ -52,50 +52,67 @@
52 * 52 *
53 */ 53 */
54 54
55#ifndef HEADER_AEPHK_ERR_H 55#include "eng_int.h"
56#define HEADER_AEPHK_ERR_H
57 56
58/* BEGIN ERROR CODES */ 57/* If this symbol is defined then ENGINE_get_default_RAND(), the function that is
59/* The following lines are auto generated by the script mkerr.pl. Any changes 58 * used by RAND to hook in implementation code and cache defaults (etc), will
60 * made after this point may be overwritten when the script is next run. 59 * display brief debugging summaries to stderr with the 'nid'. */
61 */ 60/* #define ENGINE_RAND_DEBUG */
62static void ERR_load_AEPHK_strings(void); 61
63static void ERR_unload_AEPHK_strings(void); 62static ENGINE_TABLE *rand_table = NULL;
64static void ERR_AEPHK_error(int function, int reason, char *file, int line); 63static const int dummy_nid = 1;
65#define AEPHKerr(f,r) ERR_AEPHK_error((f),(r),__FILE__,__LINE__) 64
65void ENGINE_unregister_RAND(ENGINE *e)
66 {
67 engine_table_unregister(&rand_table, e);
68 }
69
70static void engine_unregister_all_RAND(void)
71 {
72 engine_table_cleanup(&rand_table);
73 }
74
75int ENGINE_register_RAND(ENGINE *e)
76 {
77 if(e->rand_meth)
78 return engine_table_register(&rand_table,
79 engine_unregister_all_RAND, e, &dummy_nid, 1, 0);
80 return 1;
81 }
82
83void ENGINE_register_all_RAND()
84 {
85 ENGINE *e;
86
87 for(e=ENGINE_get_first() ; e ; e=ENGINE_get_next(e))
88 ENGINE_register_RAND(e);
89 }
66 90
67/* Error codes for the AEPHK functions. */ 91int ENGINE_set_default_RAND(ENGINE *e)
92 {
93 if(e->rand_meth)
94 return engine_table_register(&rand_table,
95 engine_unregister_all_RAND, e, &dummy_nid, 1, 1);
96 return 1;
97 }
68 98
69/* Function codes. */ 99/* Exposed API function to get a functional reference from the implementation
70#define AEPHK_F_AEP_CTRL 100 100 * table (ie. try to get a functional reference from the tabled structural
71#define AEPHK_F_AEP_FINISH 101 101 * references). */
72#define AEPHK_F_AEP_GET_CONNECTION 102 102ENGINE *ENGINE_get_default_RAND(void)
73#define AEPHK_F_AEP_INIT 103 103 {
74#define AEPHK_F_AEP_MOD_EXP 104 104 return engine_table_select(&rand_table, dummy_nid);
75#define AEPHK_F_AEP_MOD_EXP_CRT 105 105 }
76#define AEPHK_F_AEP_RAND 106
77#define AEPHK_F_AEP_RSA_MOD_EXP 107
78 106
79/* Reason codes. */ 107/* Obtains an RAND implementation from an ENGINE functional reference */
80#define AEPHK_R_ALREADY_LOADED 100 108const RAND_METHOD *ENGINE_get_RAND(const ENGINE *e)
81#define AEPHK_R_CLOSE_HANDLES_FAILED 101 109 {
82#define AEPHK_R_CONNECTIONS_IN_USE 102 110 return e->rand_meth;
83#define AEPHK_R_CTRL_COMMAND_NOT_IMPLEMENTED 103 111 }
84#define AEPHK_R_FINALIZE_FAILED 104
85#define AEPHK_R_GET_HANDLE_FAILED 105
86#define AEPHK_R_GET_RANDOM_FAILED 106
87#define AEPHK_R_INIT_FAILURE 107
88#define AEPHK_R_MISSING_KEY_COMPONENTS 108
89#define AEPHK_R_MOD_EXP_CRT_FAILED 109
90#define AEPHK_R_MOD_EXP_FAILED 110
91#define AEPHK_R_NOT_LOADED 111
92#define AEPHK_R_OK 112
93#define AEPHK_R_RETURN_CONNECTION_FAILED 113
94#define AEPHK_R_SETBNCALLBACK_FAILURE 114
95#define AEPHK_R_SIZE_TOO_LARGE_OR_TOO_SMALL 116
96#define AEPHK_R_UNIT_FAILURE 115
97 112
98#ifdef __cplusplus 113/* Sets an RAND implementation in an ENGINE structure */
99} 114int ENGINE_set_RAND(ENGINE *e, const RAND_METHOD *rand_meth)
100#endif 115 {
101#endif 116 e->rand_meth = rand_meth;
117 return 1;
118 }
diff --git a/src/lib/libcrypto/engine/hw_atalla_err.h b/src/lib/libcrypto/engine/tb_rsa.c
index cdac052d8c..fbc707fd26 100644
--- a/src/lib/libcrypto/engine/hw_atalla_err.h
+++ b/src/lib/libcrypto/engine/tb_rsa.c
@@ -1,5 +1,5 @@
1/* ==================================================================== 1/* ====================================================================
2 * Copyright (c) 2001 The OpenSSL Project. All rights reserved. 2 * Copyright (c) 2000 The OpenSSL Project. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions 5 * modification, are permitted provided that the following conditions
@@ -16,12 +16,12 @@
16 * 3. All advertising materials mentioning features or use of this 16 * 3. All advertising materials mentioning features or use of this
17 * software must display the following acknowledgment: 17 * software must display the following acknowledgment:
18 * "This product includes software developed by the OpenSSL Project 18 * "This product includes software developed by the OpenSSL Project
19 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 19 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
20 * 20 *
21 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 21 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
22 * endorse or promote products derived from this software without 22 * endorse or promote products derived from this software without
23 * prior written permission. For written permission, please contact 23 * prior written permission. For written permission, please contact
24 * openssl-core@openssl.org. 24 * licensing@OpenSSL.org.
25 * 25 *
26 * 5. Products derived from this software may not be called "OpenSSL" 26 * 5. Products derived from this software may not be called "OpenSSL"
27 * nor may "OpenSSL" appear in their names without prior written 27 * nor may "OpenSSL" appear in their names without prior written
@@ -30,7 +30,7 @@
30 * 6. Redistributions of any form whatsoever must retain the following 30 * 6. Redistributions of any form whatsoever must retain the following
31 * acknowledgment: 31 * acknowledgment:
32 * "This product includes software developed by the OpenSSL Project 32 * "This product includes software developed by the OpenSSL Project
33 * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 33 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
34 * 34 *
35 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 35 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
36 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 36 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
@@ -52,38 +52,67 @@
52 * 52 *
53 */ 53 */
54 54
55#ifndef HEADER_ATALLA_ERR_H 55#include "eng_int.h"
56#define HEADER_ATALLA_ERR_H
57 56
58/* BEGIN ERROR CODES */ 57/* If this symbol is defined then ENGINE_get_default_RSA(), the function that is
59/* The following lines are auto generated by the script mkerr.pl. Any changes 58 * used by RSA to hook in implementation code and cache defaults (etc), will
60 * made after this point may be overwritten when the script is next run. 59 * display brief debugging summaries to stderr with the 'nid'. */
61 */ 60/* #define ENGINE_RSA_DEBUG */
62static void ERR_load_ATALLA_strings(void); 61
63static void ERR_unload_ATALLA_strings(void); 62static ENGINE_TABLE *rsa_table = NULL;
64static void ERR_ATALLA_error(int function, int reason, char *file, int line); 63static const int dummy_nid = 1;
65#define ATALLAerr(f,r) ERR_ATALLA_error((f),(r),__FILE__,__LINE__) 64
65void ENGINE_unregister_RSA(ENGINE *e)
66 {
67 engine_table_unregister(&rsa_table, e);
68 }
69
70static void engine_unregister_all_RSA(void)
71 {
72 engine_table_cleanup(&rsa_table);
73 }
74
75int ENGINE_register_RSA(ENGINE *e)
76 {
77 if(e->rsa_meth)
78 return engine_table_register(&rsa_table,
79 engine_unregister_all_RSA, e, &dummy_nid, 1, 0);
80 return 1;
81 }
82
83void ENGINE_register_all_RSA()
84 {
85 ENGINE *e;
86
87 for(e=ENGINE_get_first() ; e ; e=ENGINE_get_next(e))
88 ENGINE_register_RSA(e);
89 }
66 90
67/* Error codes for the ATALLA functions. */ 91int ENGINE_set_default_RSA(ENGINE *e)
92 {
93 if(e->rsa_meth)
94 return engine_table_register(&rsa_table,
95 engine_unregister_all_RSA, e, &dummy_nid, 1, 1);
96 return 1;
97 }
68 98
69/* Function codes. */ 99/* Exposed API function to get a functional reference from the implementation
70#define ATALLA_F_ATALLA_CTRL 100 100 * table (ie. try to get a functional reference from the tabled structural
71#define ATALLA_F_ATALLA_FINISH 101 101 * references). */
72#define ATALLA_F_ATALLA_INIT 102 102ENGINE *ENGINE_get_default_RSA(void)
73#define ATALLA_F_ATALLA_MOD_EXP 103 103 {
74#define ATALLA_F_ATALLA_RSA_MOD_EXP 104 104 return engine_table_select(&rsa_table, dummy_nid);
105 }
75 106
76/* Reason codes. */ 107/* Obtains an RSA implementation from an ENGINE functional reference */
77#define ATALLA_R_ALREADY_LOADED 100 108const RSA_METHOD *ENGINE_get_RSA(const ENGINE *e)
78#define ATALLA_R_BN_CTX_FULL 101 109 {
79#define ATALLA_R_BN_EXPAND_FAIL 102 110 return e->rsa_meth;
80#define ATALLA_R_CTRL_COMMAND_NOT_IMPLEMENTED 103 111 }
81#define ATALLA_R_MISSING_KEY_COMPONENTS 104
82#define ATALLA_R_NOT_LOADED 105
83#define ATALLA_R_REQUEST_FAILED 106
84#define ATALLA_R_UNIT_FAILURE 107
85 112
86#ifdef __cplusplus 113/* Sets an RSA implementation in an ENGINE structure */
87} 114int ENGINE_set_RSA(ENGINE *e, const RSA_METHOD *rsa_meth)
88#endif 115 {
89#endif 116 e->rsa_meth = rsa_meth;
117 return 1;
118 }
diff --git a/src/lib/libcrypto/engine/tb_store.c b/src/lib/libcrypto/engine/tb_store.c
new file mode 100644
index 0000000000..8cc435c935
--- /dev/null
+++ b/src/lib/libcrypto/engine/tb_store.c
@@ -0,0 +1,123 @@
1/* ====================================================================
2 * Copyright (c) 2003 The OpenSSL Project. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in
13 * the documentation and/or other materials provided with the
14 * distribution.
15 *
16 * 3. All advertising materials mentioning features or use of this
17 * software must display the following acknowledgment:
18 * "This product includes software developed by the OpenSSL Project
19 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
20 *
21 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
22 * endorse or promote products derived from this software without
23 * prior written permission. For written permission, please contact
24 * licensing@OpenSSL.org.
25 *
26 * 5. Products derived from this software may not be called "OpenSSL"
27 * nor may "OpenSSL" appear in their names without prior written
28 * permission of the OpenSSL Project.
29 *
30 * 6. Redistributions of any form whatsoever must retain the following
31 * acknowledgment:
32 * "This product includes software developed by the OpenSSL Project
33 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
34 *
35 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
36 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
37 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
38 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
39 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
41 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
42 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
43 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
44 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
45 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
46 * OF THE POSSIBILITY OF SUCH DAMAGE.
47 * ====================================================================
48 *
49 * This product includes cryptographic software written by Eric Young
50 * (eay@cryptsoft.com). This product includes software written by Tim
51 * Hudson (tjh@cryptsoft.com).
52 *
53 */
54
55#include "eng_int.h"
56
57/* If this symbol is defined then ENGINE_get_default_STORE(), the function that is
58 * used by STORE to hook in implementation code and cache defaults (etc), will
59 * display brief debugging summaries to stderr with the 'nid'. */
60/* #define ENGINE_STORE_DEBUG */
61
62static ENGINE_TABLE *store_table = NULL;
63static const int dummy_nid = 1;
64
65void ENGINE_unregister_STORE(ENGINE *e)
66 {
67 engine_table_unregister(&store_table, e);
68 }
69
70static void engine_unregister_all_STORE(void)
71 {
72 engine_table_cleanup(&store_table);
73 }
74
75int ENGINE_register_STORE(ENGINE *e)
76 {
77 if(e->store_meth)
78 return engine_table_register(&store_table,
79 engine_unregister_all_STORE, e, &dummy_nid, 1, 0);
80 return 1;
81 }
82
83void ENGINE_register_all_STORE()
84 {
85 ENGINE *e;
86
87 for(e=ENGINE_get_first() ; e ; e=ENGINE_get_next(e))
88 ENGINE_register_STORE(e);
89 }
90
91/* The following two functions are removed because they're useless. */
92#if 0
93int ENGINE_set_default_STORE(ENGINE *e)
94 {
95 if(e->store_meth)
96 return engine_table_register(&store_table,
97 engine_unregister_all_STORE, e, &dummy_nid, 1, 1);
98 return 1;
99 }
100#endif
101
102#if 0
103/* Exposed API function to get a functional reference from the implementation
104 * table (ie. try to get a functional reference from the tabled structural
105 * references). */
106ENGINE *ENGINE_get_default_STORE(void)
107 {
108 return engine_table_select(&store_table, dummy_nid);
109 }
110#endif
111
112/* Obtains an STORE implementation from an ENGINE functional reference */
113const STORE_METHOD *ENGINE_get_STORE(const ENGINE *e)
114 {
115 return e->store_meth;
116 }
117
118/* Sets an STORE implementation in an ENGINE structure */
119int ENGINE_set_STORE(ENGINE *e, const STORE_METHOD *store_meth)
120 {
121 e->store_meth = store_meth;
122 return 1;
123 }
diff --git a/src/lib/libcrypto/engine/vendor_defns/aep.h b/src/lib/libcrypto/engine/vendor_defns/aep.h
deleted file mode 100644
index 2b2792d2d6..0000000000
--- a/src/lib/libcrypto/engine/vendor_defns/aep.h
+++ /dev/null
@@ -1,178 +0,0 @@
1/* This header declares the necessary definitions for using the exponentiation
2 * acceleration capabilities, and rnd number generation of the AEP card.
3 *
4 */
5
6/*
7 *
8 * Some AEP defines
9 *
10 */
11
12/*Successful return value*/
13#define AEP_R_OK 0x00000000
14
15/*Miscelleanous unsuccessful return value*/
16#define AEP_R_GENERAL_ERROR 0x10000001
17
18/*Insufficient host memory*/
19#define AEP_R_HOST_MEMORY 0x10000002
20
21#define AEP_R_FUNCTION_FAILED 0x10000006
22
23/*Invalid arguments in function call*/
24#define AEP_R_ARGUMENTS_BAD 0x10020000
25
26#define AEP_R_NO_TARGET_RESOURCES 0x10030000
27
28/*Error occuring on socket operation*/
29#define AEP_R_SOCKERROR 0x10000010
30
31/*Socket has been closed from the other end*/
32#define AEP_R_SOCKEOF 0x10000011
33
34/*Invalid handles*/
35#define AEP_R_CONNECTION_HANDLE_INVALID 0x100000B3
36
37#define AEP_R_TRANSACTION_HANDLE_INVALID 0x10040000
38
39/*Transaction has not yet returned from accelerator*/
40#define AEP_R_TRANSACTION_NOT_READY 0x00010000
41
42/*There is already a thread waiting on this transaction*/
43#define AEP_R_TRANSACTION_CLAIMED 0x10050000
44
45/*The transaction timed out*/
46#define AEP_R_TIMED_OUT 0x10060000
47
48#define AEP_R_FXN_NOT_IMPLEMENTED 0x10070000
49
50#define AEP_R_TARGET_ERROR 0x10080000
51
52/*Error in the AEP daemon process*/
53#define AEP_R_DAEMON_ERROR 0x10090000
54
55/*Invalid ctx id*/
56#define AEP_R_INVALID_CTX_ID 0x10009000
57
58#define AEP_R_NO_KEY_MANAGER 0x1000a000
59
60/*Error obtaining a mutex*/
61#define AEP_R_MUTEX_BAD 0x000001A0
62
63/*Fxn call before AEP_Initialise ot after AEP_Finialise*/
64#define AEP_R_AEPAPI_NOT_INITIALIZED 0x10000190
65
66/*AEP_Initialise has already been called*/
67#define AEP_R_AEPAPI_ALREADY_INITIALIZED 0x10000191
68
69/*Maximum number of connections to daemon reached*/
70#define AEP_R_NO_MORE_CONNECTION_HNDLS 0x10000200
71
72/*
73 *
74 * Some AEP Type definitions
75 *
76 */
77
78/* an unsigned 8-bit value */
79typedef unsigned char AEP_U8;
80
81/* an unsigned 8-bit character */
82typedef char AEP_CHAR;
83
84/* a BYTE-sized Boolean flag */
85typedef AEP_U8 AEP_BBOOL;
86
87/*Unsigned value, at least 16 bits long*/
88typedef unsigned short AEP_U16;
89
90/* an unsigned value, at least 32 bits long */
91#ifdef SIXTY_FOUR_BIT_LONG
92typedef unsigned int AEP_U32;
93#else
94typedef unsigned long AEP_U32;
95#endif
96
97#ifdef SIXTY_FOUR_BIT_LONG
98typedef unsigned long AEP_U64;
99#else
100typedef struct { unsigned long l1, l2; } AEP_U64;
101#endif
102
103/* at least 32 bits; each bit is a Boolean flag */
104typedef AEP_U32 AEP_FLAGS;
105
106typedef AEP_U8 *AEP_U8_PTR;
107typedef AEP_CHAR *AEP_CHAR_PTR;
108typedef AEP_U32 *AEP_U32_PTR;
109typedef AEP_U64 *AEP_U64_PTR;
110typedef void *AEP_VOID_PTR;
111
112/* Pointer to a AEP_VOID_PTR-- i.e., pointer to pointer to void */
113typedef AEP_VOID_PTR *AEP_VOID_PTR_PTR;
114
115/*Used to identify an AEP connection handle*/
116typedef AEP_U32 AEP_CONNECTION_HNDL;
117
118/*Pointer to an AEP connection handle*/
119typedef AEP_CONNECTION_HNDL *AEP_CONNECTION_HNDL_PTR;
120
121/*Used by an application (in conjunction with the apps process id) to
122identify an individual transaction*/
123typedef AEP_U32 AEP_TRANSACTION_ID;
124
125/*Pointer to an applications transaction identifier*/
126typedef AEP_TRANSACTION_ID *AEP_TRANSACTION_ID_PTR;
127
128/*Return value type*/
129typedef AEP_U32 AEP_RV;
130
131#define MAX_PROCESS_CONNECTIONS 256
132
133#define RAND_BLK_SIZE 1024
134
135typedef enum{
136 NotConnected= 0,
137 Connected= 1,
138 InUse= 2
139} AEP_CONNECTION_STATE;
140
141
142typedef struct AEP_CONNECTION_ENTRY{
143 AEP_CONNECTION_STATE conn_state;
144 AEP_CONNECTION_HNDL conn_hndl;
145} AEP_CONNECTION_ENTRY;
146
147
148typedef AEP_RV t_AEP_OpenConnection(AEP_CONNECTION_HNDL_PTR phConnection);
149typedef AEP_RV t_AEP_CloseConnection(AEP_CONNECTION_HNDL hConnection);
150
151typedef AEP_RV t_AEP_ModExp(AEP_CONNECTION_HNDL hConnection,
152 AEP_VOID_PTR pA, AEP_VOID_PTR pP,
153 AEP_VOID_PTR pN,
154 AEP_VOID_PTR pResult,
155 AEP_TRANSACTION_ID* pidTransID);
156
157typedef AEP_RV t_AEP_ModExpCrt(AEP_CONNECTION_HNDL hConnection,
158 AEP_VOID_PTR pA, AEP_VOID_PTR pP,
159 AEP_VOID_PTR pQ,
160 AEP_VOID_PTR pDmp1, AEP_VOID_PTR pDmq1,
161 AEP_VOID_PTR pIqmp,
162 AEP_VOID_PTR pResult,
163 AEP_TRANSACTION_ID* pidTransID);
164
165#ifdef AEPRAND
166typedef AEP_RV t_AEP_GenRandom(AEP_CONNECTION_HNDL hConnection,
167 AEP_U32 Len,
168 AEP_U32 Type,
169 AEP_VOID_PTR pResult,
170 AEP_TRANSACTION_ID* pidTransID);
171#endif
172
173typedef AEP_RV t_AEP_Initialize(AEP_VOID_PTR pInitArgs);
174typedef AEP_RV t_AEP_Finalize();
175typedef AEP_RV t_AEP_SetBNCallBacks(AEP_RV (*GetBigNumSizeFunc)(),
176 AEP_RV (*MakeAEPBigNumFunc)(),
177 AEP_RV (*ConverAEPBigNumFunc)());
178
diff --git a/src/lib/libcrypto/engine/vendor_defns/atalla.h b/src/lib/libcrypto/engine/vendor_defns/atalla.h
deleted file mode 100644
index 149970d441..0000000000
--- a/src/lib/libcrypto/engine/vendor_defns/atalla.h
+++ /dev/null
@@ -1,48 +0,0 @@
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
diff --git a/src/lib/libcrypto/engine/vendor_defns/cswift.h b/src/lib/libcrypto/engine/vendor_defns/cswift.h
deleted file mode 100644
index 60079326bb..0000000000
--- a/src/lib/libcrypto/engine/vendor_defns/cswift.h
+++ /dev/null
@@ -1,234 +0,0 @@
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(OPENSSL_SYS_WIN32)
36 typedef struct _SW_U64 {
37 SW_U32 low32;
38 SW_U32 high32;
39 } SW_U64; /* 64 bit integer */
40#elif defined(OPENSSL_SYS_MACINTOSH_CLASSIC)
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
159#if defined(OPENSSL_SYS_WIN32)
160 #include <windows.h>
161 typedef HANDLE SW_OSHANDLE; /* handle to kernel object */
162 #define SW_OS_INVALID_HANDLE INVALID_HANDLE_VALUE
163 #define SW_CALLCONV _stdcall
164#elif defined(OPENSSL_SYS_MACINTOSH_CLASSIC)
165 /* async callback mechanisms */
166 /* swiftCallbackLevel */
167 #define SW_MAC_CALLBACK_LEVEL_NO 0
168 #define SW_MAC_CALLBACK_LEVEL_HARDWARE 1 /* from the hardware ISR */
169 #define SW_MAC_CALLBACK_LEVEL_SECONDARY 2 /* as secondary ISR */
170 typedef int SW_MAC_CALLBACK_LEVEL;
171 typedef int SW_OSHANDLE;
172 #define SW_OS_INVALID_HANDLE (-1)
173 #define SW_CALLCONV
174#else /* Unix variants */
175 typedef int SW_OSHANDLE; /* handle to driver */
176 #define SW_OS_INVALID_HANDLE (-1)
177 #define SW_CALLCONV
178#endif
179
180typedef struct _SW_CRT {
181 SW_LARGENUMBER p; /* prime number p */
182 SW_LARGENUMBER q; /* prime number q */
183 SW_LARGENUMBER dmp1; /* exponent1 */
184 SW_LARGENUMBER dmq1; /* exponent2 */
185 SW_LARGENUMBER iqmp; /* CRT coefficient */
186} SW_CRT;
187
188typedef struct _SW_EXP {
189 SW_LARGENUMBER modulus; /* modulus */
190 SW_LARGENUMBER exponent;/* exponent */
191} SW_EXP;
192
193typedef struct _SW_DSA {
194 SW_LARGENUMBER p; /* */
195 SW_LARGENUMBER q; /* */
196 SW_LARGENUMBER g; /* */
197 SW_LARGENUMBER key; /* private/public key */
198} SW_DSA;
199
200typedef struct _SW_NVDATA {
201 SW_U32 accnum; /* accelerator board number */
202 SW_U32 offset; /* offset in byte */
203} SW_NVDATA;
204
205typedef struct _SW_PARAM {
206 SW_ALGTYPE type; /* type of the alogrithm */
207 union {
208 SW_CRT crt;
209 SW_EXP exp;
210 SW_DSA dsa;
211 SW_NVDATA nvdata;
212 } up;
213} SW_PARAM;
214
215typedef SW_U32 SW_CONTEXT_HANDLE; /* opaque context handle */
216
217
218/* Now the OpenSSL bits, these function types are the for the function
219 * pointers that will bound into the Rainbow shared libraries. */
220typedef SW_STATUS SW_CALLCONV t_swAcquireAccContext(SW_CONTEXT_HANDLE *hac);
221typedef SW_STATUS SW_CALLCONV t_swAttachKeyParam(SW_CONTEXT_HANDLE hac,
222 SW_PARAM *key_params);
223typedef SW_STATUS SW_CALLCONV t_swSimpleRequest(SW_CONTEXT_HANDLE hac,
224 SW_COMMAND_CODE cmd,
225 SW_LARGENUMBER pin[],
226 SW_U32 pin_count,
227 SW_LARGENUMBER pout[],
228 SW_U32 pout_count);
229typedef SW_STATUS SW_CALLCONV t_swReleaseAccContext(SW_CONTEXT_HANDLE hac);
230
231#ifdef __cplusplus
232}
233#endif /* __cplusplus */
234
diff --git a/src/lib/libcrypto/engine/vendor_defns/hw_4758_cca.h b/src/lib/libcrypto/engine/vendor_defns/hw_4758_cca.h
deleted file mode 100644
index 296636e81a..0000000000
--- a/src/lib/libcrypto/engine/vendor_defns/hw_4758_cca.h
+++ /dev/null
@@ -1,149 +0,0 @@
1/**********************************************************************/
2/* */
3/* Prototypes of the CCA verbs used by the 4758 CCA openssl driver */
4/* */
5/* Maurice Gittens <maurice@gittens.nl> */
6/* */
7/**********************************************************************/
8
9#ifndef __HW_4758_CCA__
10#define __HW_4758_CCA__
11
12/*
13 * Only WIN32 support for now
14 */
15#if defined(WIN32)
16
17 #define CCA_LIB_NAME "CSUNSAPI"
18
19 #define CSNDPKX "CSNDPKX_32"
20 #define CSNDKRR "CSNDKRR_32"
21 #define CSNDPKE "CSNDPKE_32"
22 #define CSNDPKD "CSNDPKD_32"
23 #define CSNDDSV "CSNDDSV_32"
24 #define CSNDDSG "CSNDDSG_32"
25 #define CSNBRNG "CSNBRNG_32"
26
27 #define SECURITYAPI __stdcall
28#else
29 /* Fixme!!
30 Find out the values of these constants for other platforms.
31 */
32 #define CCA_LIB_NAME "CSUNSAPI"
33
34 #define CSNDPKX "CSNDPKX"
35 #define CSNDKRR "CSNDKRR"
36 #define CSNDPKE "CSNDPKE"
37 #define CSNDPKD "CSNDPKD"
38 #define CSNDDSV "CSNDDSV"
39 #define CSNDDSG "CSNDDSG"
40 #define CSNBRNG "CSNBRNG"
41
42 #define SECURITYAPI
43#endif
44
45/*
46 * security API prototypes
47 */
48
49/* PKA Key Record Read */
50typedef void (SECURITYAPI *F_KEYRECORDREAD)
51 (long * return_code,
52 long * reason_code,
53 long * exit_data_length,
54 unsigned char * exit_data,
55 long * rule_array_count,
56 unsigned char * rule_array,
57 unsigned char * key_label,
58 long * key_token_length,
59 unsigned char * key_token);
60
61/* Random Number Generate */
62typedef void (SECURITYAPI *F_RANDOMNUMBERGENERATE)
63 (long * return_code,
64 long * reason_code,
65 long * exit_data_length,
66 unsigned char * exit_data,
67 unsigned char * form,
68 unsigned char * random_number);
69
70/* Digital Signature Generate */
71typedef void (SECURITYAPI *F_DIGITALSIGNATUREGENERATE)
72 (long * return_code,
73 long * reason_code,
74 long * exit_data_length,
75 unsigned char * exit_data,
76 long * rule_array_count,
77 unsigned char * rule_array,
78 long * PKA_private_key_id_length,
79 unsigned char * PKA_private_key_id,
80 long * hash_length,
81 unsigned char * hash,
82 long * signature_field_length,
83 long * signature_bit_length,
84 unsigned char * signature_field);
85
86/* Digital Signature Verify */
87typedef void (SECURITYAPI *F_DIGITALSIGNATUREVERIFY)(
88 long * return_code,
89 long * reason_code,
90 long * exit_data_length,
91 unsigned char * exit_data,
92 long * rule_array_count,
93 unsigned char * rule_array,
94 long * PKA_public_key_id_length,
95 unsigned char * PKA_public_key_id,
96 long * hash_length,
97 unsigned char * hash,
98 long * signature_field_length,
99 unsigned char * signature_field);
100
101/* PKA Public Key Extract */
102typedef void (SECURITYAPI *F_PUBLICKEYEXTRACT)(
103 long * return_code,
104 long * reason_code,
105 long * exit_data_length,
106 unsigned char * exit_data,
107 long * rule_array_count,
108 unsigned char * rule_array,
109 long * source_key_identifier_length,
110 unsigned char * source_key_identifier,
111 long * target_key_token_length,
112 unsigned char * target_key_token);
113
114/* PKA Encrypt */
115typedef void (SECURITYAPI *F_PKAENCRYPT)
116 (long * return_code,
117 long * reason_code,
118 long * exit_data_length,
119 unsigned char * exit_data,
120 long * rule_array_count,
121 unsigned char * rule_array,
122 long * key_value_length,
123 unsigned char * key_value,
124 long * data_struct_length,
125 unsigned char * data_struct,
126 long * RSA_public_key_length,
127 unsigned char * RSA_public_key,
128 long * RSA_encipher_length,
129 unsigned char * RSA_encipher );
130
131/* PKA Decrypt */
132typedef void (SECURITYAPI *F_PKADECRYPT)
133 (long * return_code,
134 long * reason_code,
135 long * exit_data_length,
136 unsigned char * exit_data,
137 long * rule_array_count,
138 unsigned char * rule_array,
139 long * enciphered_key_length,
140 unsigned char * enciphered_key,
141 long * data_struct_length,
142 unsigned char * data_struct,
143 long * RSA_private_key_length,
144 unsigned char * RSA_private_key,
145 long * key_value_length,
146 unsigned char * key_value );
147
148
149#endif
diff --git a/src/lib/libcrypto/engine/vendor_defns/hw_ubsec.h b/src/lib/libcrypto/engine/vendor_defns/hw_ubsec.h
deleted file mode 100644
index b6619d40f2..0000000000
--- a/src/lib/libcrypto/engine/vendor_defns/hw_ubsec.h
+++ /dev/null
@@ -1,100 +0,0 @@
1/******************************************************************************
2 *
3 * Copyright 2000
4 * Broadcom Corporation
5 * 16215 Alton Parkway
6 * PO Box 57013
7 * Irvine CA 92619-7013
8 *
9 *****************************************************************************/
10/*
11 * Broadcom Corporation uBSec SDK
12 */
13/*
14 * Character device header file.
15 */
16/*
17 * Revision History:
18 *
19 * October 2000 JTT Created.
20 */
21
22#define MAX_PUBLIC_KEY_BITS (1024)
23#define MAX_PUBLIC_KEY_BYTES (1024/8)
24#define SHA_BIT_SIZE (160)
25#define MAX_CRYPTO_KEY_LENGTH 24
26#define MAX_MAC_KEY_LENGTH 64
27#define UBSEC_CRYPTO_DEVICE_NAME ((unsigned char *)"/dev/ubscrypt")
28#define UBSEC_KEY_DEVICE_NAME ((unsigned char *)"/dev/ubskey")
29
30/* Math command types. */
31#define UBSEC_MATH_MODADD 0x0001
32#define UBSEC_MATH_MODSUB 0x0002
33#define UBSEC_MATH_MODMUL 0x0004
34#define UBSEC_MATH_MODEXP 0x0008
35#define UBSEC_MATH_MODREM 0x0010
36#define UBSEC_MATH_MODINV 0x0020
37
38typedef long ubsec_MathCommand_t;
39typedef long ubsec_RNGCommand_t;
40
41typedef struct ubsec_crypto_context_s {
42 unsigned int flags;
43 unsigned char crypto[MAX_CRYPTO_KEY_LENGTH];
44 unsigned char auth[MAX_MAC_KEY_LENGTH];
45} ubsec_crypto_context_t, *ubsec_crypto_context_p;
46
47/*
48 * Predeclare the function pointer types that we dynamically load from the DSO.
49 */
50
51typedef int t_UBSEC_ubsec_bytes_to_bits(unsigned char *n, int bytes);
52
53typedef int t_UBSEC_ubsec_bits_to_bytes(int bits);
54
55typedef int t_UBSEC_ubsec_open(unsigned char *device);
56
57typedef int t_UBSEC_ubsec_close(int fd);
58
59typedef int t_UBSEC_diffie_hellman_generate_ioctl (int fd,
60 unsigned char *x, int *x_len, unsigned char *y, int *y_len,
61 unsigned char *g, int g_len, unsigned char *m, int m_len,
62 unsigned char *userX, int userX_len, int random_bits);
63
64typedef int t_UBSEC_diffie_hellman_agree_ioctl (int fd,
65 unsigned char *x, int x_len, unsigned char *y, int y_len,
66 unsigned char *m, int m_len, unsigned char *k, int *k_len);
67
68typedef int t_UBSEC_rsa_mod_exp_ioctl (int fd,
69 unsigned char *x, int x_len, unsigned char *m, int m_len,
70 unsigned char *e, int e_len, unsigned char *y, int *y_len);
71
72typedef int t_UBSEC_rsa_mod_exp_crt_ioctl (int fd,
73 unsigned char *x, int x_len, unsigned char *qinv, int qinv_len,
74 unsigned char *edq, int edq_len, unsigned char *q, int q_len,
75 unsigned char *edp, int edp_len, unsigned char *p, int p_len,
76 unsigned char *y, int *y_len);
77
78typedef int t_UBSEC_dsa_sign_ioctl (int fd,
79 int hash, unsigned char *data, int data_len,
80 unsigned char *rndom, int random_len,
81 unsigned char *p, int p_len, unsigned char *q, int q_len,
82 unsigned char *g, int g_len, unsigned char *key, int key_len,
83 unsigned char *r, int *r_len, unsigned char *s, int *s_len);
84
85typedef int t_UBSEC_dsa_verify_ioctl (int fd,
86 int hash, unsigned char *data, int data_len,
87 unsigned char *p, int p_len, unsigned char *q, int q_len,
88 unsigned char *g, int g_len, unsigned char *key, int key_len,
89 unsigned char *r, int r_len, unsigned char *s, int s_len,
90 unsigned char *v, int *v_len);
91
92typedef int t_UBSEC_math_accelerate_ioctl(int fd, ubsec_MathCommand_t command,
93 unsigned char *ModN, int *ModN_len, unsigned char *ExpE, int *ExpE_len,
94 unsigned char *ParamA, int *ParamA_len, unsigned char *ParamB, int *ParamB_len,
95 unsigned char *Result, int *Result_len);
96
97typedef int t_UBSEC_rng_ioctl(int fd, ubsec_RNGCommand_t command,
98 unsigned char *Result, int *Result_len);
99
100typedef int t_UBSEC_max_key_len_ioctl(int fd, int *max_key_len);
diff --git a/src/lib/libcrypto/engine/vendor_defns/hwcryptohook.h b/src/lib/libcrypto/engine/vendor_defns/hwcryptohook.h
deleted file mode 100644
index aaa4d4575e..0000000000
--- a/src/lib/libcrypto/engine/vendor_defns/hwcryptohook.h
+++ /dev/null
@@ -1,486 +0,0 @@
1/*
2 * ModExp / RSA (with/without KM) plugin API
3 *
4 * The application will load a dynamic library which
5 * exports entrypoint(s) defined in this file.
6 *
7 * This set of entrypoints provides only a multithreaded,
8 * synchronous-within-each-thread, facility.
9 *
10 *
11 * This file is Copyright 1998-2000 nCipher Corporation Limited.
12 *
13 * Redistribution and use in source and binary forms, with opr without
14 * modification, are permitted provided that the following conditions
15 * are met:
16 *
17 * 1. Redistributions of source code must retain the copyright notice,
18 * this list of conditions, and the following disclaimer.
19 *
20 * 2. Redistributions in binary form must reproduce the above
21 * copyright notice, this list of conditions, and the following
22 * disclaimer, in the documentation and/or other materials provided
23 * with the distribution
24 *
25 * IN NO EVENT SHALL NCIPHER CORPORATION LIMITED (`NCIPHER') AND/OR
26 * ANY OTHER AUTHORS OR DISTRIBUTORS OF THIS FILE BE LIABLE for any
27 * damages arising directly or indirectly from this file, its use or
28 * this licence. Without prejudice to the generality of the
29 * foregoing: all liability shall be excluded for direct, indirect,
30 * special, incidental, consequential or other damages or any loss of
31 * profits, business, revenue goodwill or anticipated savings;
32 * liability shall be excluded even if nCipher or anyone else has been
33 * advised of the possibility of damage. In any event, if the
34 * exclusion of liability is not effective, the liability of nCipher
35 * or any author or distributor shall be limited to the lesser of the
36 * price paid and 1,000 pounds sterling. This licence only fails to
37 * exclude or limit liability for death or personal injury arising out
38 * of negligence, and only to the extent that such an exclusion or
39 * limitation is not effective.
40 *
41 * NCIPHER AND THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ALL
42 * AND ANY WARRANTIES (WHETHER EXPRESS OR IMPLIED), including, but not
43 * limited to, any implied warranties of merchantability, fitness for
44 * a particular purpose, satisfactory quality, and/or non-infringement
45 * of any third party rights.
46 *
47 * US Government use: This software and documentation is Commercial
48 * Computer Software and Computer Software Documentation, as defined in
49 * sub-paragraphs (a)(1) and (a)(5) of DFAR 252.227-7014, "Rights in
50 * Noncommercial Computer Software and Noncommercial Computer Software
51 * Documentation." Use, duplication or disclosure by the Government is
52 * subject to the terms and conditions specified here.
53 *
54 * By using or distributing this file you will be accepting these
55 * terms and conditions, including the limitation of liability and
56 * lack of warranty. If you do not wish to accept these terms and
57 * conditions, DO NOT USE THE FILE.
58 *
59 *
60 * The actual dynamically loadable plugin, and the library files for
61 * static linking, which are also provided in some distributions, are
62 * not covered by the licence described above. You should have
63 * received a separate licence with terms and conditions for these
64 * library files; if you received the library files without a licence,
65 * please contact nCipher.
66 *
67 *
68 * $Id: hwcryptohook.h,v 1.1.1.1 2003/05/11 21:35:16 markus Exp $
69 */
70
71#ifndef HWCRYPTOHOOK_H
72#define HWCRYPTOHOOK_H
73
74#include <sys/types.h>
75#include <stdio.h>
76
77#ifndef HWCRYPTOHOOK_DECLARE_APPTYPES
78#define HWCRYPTOHOOK_DECLARE_APPTYPES 1
79#endif
80
81#define HWCRYPTOHOOK_ERROR_FAILED -1
82#define HWCRYPTOHOOK_ERROR_FALLBACK -2
83#define HWCRYPTOHOOK_ERROR_MPISIZE -3
84
85#if HWCRYPTOHOOK_DECLARE_APPTYPES
86
87/* These structs are defined by the application and opaque to the
88 * crypto plugin. The application may define these as it sees fit.
89 * Default declarations are provided here, but the application may
90 * #define HWCRYPTOHOOK_DECLARE_APPTYPES 0
91 * to prevent these declarations, and instead provide its own
92 * declarations of these types. (Pointers to them must still be
93 * ordinary pointers to structs or unions, or the resulting combined
94 * program will have a type inconsistency.)
95 */
96typedef struct HWCryptoHook_MutexValue HWCryptoHook_Mutex;
97typedef struct HWCryptoHook_CondVarValue HWCryptoHook_CondVar;
98typedef struct HWCryptoHook_PassphraseContextValue HWCryptoHook_PassphraseContext;
99typedef struct HWCryptoHook_CallerContextValue HWCryptoHook_CallerContext;
100
101#endif /* HWCRYPTOHOOK_DECLARE_APPTYPES */
102
103/* These next two structs are opaque to the application. The crypto
104 * plugin will return pointers to them; the caller simply manipulates
105 * the pointers.
106 */
107typedef struct HWCryptoHook_Context *HWCryptoHook_ContextHandle;
108typedef struct HWCryptoHook_RSAKey *HWCryptoHook_RSAKeyHandle;
109
110typedef struct {
111 char *buf;
112 size_t size;
113} HWCryptoHook_ErrMsgBuf;
114/* Used for error reporting. When a HWCryptoHook function fails it
115 * will return a sentinel value (0 for pointer-valued functions, or a
116 * negative number, usually HWCRYPTOHOOK_ERROR_FAILED, for
117 * integer-valued ones). It will, if an ErrMsgBuf is passed, also put
118 * an error message there.
119 *
120 * size is the size of the buffer, and will not be modified. If you
121 * pass 0 for size you must pass 0 for buf, and nothing will be
122 * recorded (just as if you passed 0 for the struct pointer).
123 * Messages written to the buffer will always be null-terminated, even
124 * when truncated to fit within size bytes.
125 *
126 * The contents of the buffer are not defined if there is no error.
127 */
128
129typedef struct HWCryptoHook_MPIStruct {
130 unsigned char *buf;
131 size_t size;
132} HWCryptoHook_MPI;
133/* When one of these is returned, a pointer is passed to the function.
134 * At call, size is the space available. Afterwards it is updated to
135 * be set to the actual length (which may be more than the space available,
136 * if there was not enough room and the result was truncated).
137 * buf (the pointer) is not updated.
138 *
139 * size is in bytes and may be zero at call or return, but must be a
140 * multiple of the limb size. Zero limbs at the MS end are not
141 * permitted.
142 */
143
144#define HWCryptoHook_InitFlags_FallbackModExp 0x0002UL
145#define HWCryptoHook_InitFlags_FallbackRSAImmed 0x0004UL
146/* Enable requesting fallback to software in case of problems with the
147 * hardware support. This indicates to the crypto provider that the
148 * application is prepared to fall back to software operation if the
149 * ModExp* or RSAImmed* functions return HWCRYPTOHOOK_ERROR_FALLBACK.
150 * Without this flag those calls will never return
151 * HWCRYPTOHOOK_ERROR_FALLBACK. The flag will also cause the crypto
152 * provider to avoid repeatedly attempting to contact dead hardware
153 * within a short interval, if appropriate.
154 */
155
156#define HWCryptoHook_InitFlags_SimpleForkCheck 0x0010UL
157/* Without _SimpleForkCheck the library is allowed to assume that the
158 * application will not fork and call the library in the child(ren).
159 *
160 * When it is specified, this is allowed. However, after a fork
161 * neither parent nor child may unload any loaded keys or call
162 * _Finish. Instead, they should call exit (or die with a signal)
163 * without calling _Finish. After all the children have died the
164 * parent may unload keys or call _Finish.
165 *
166 * This flag only has any effect on UN*X platforms.
167 */
168
169typedef struct {
170 unsigned long flags;
171 void *logstream; /* usually a FILE*. See below. */
172
173 size_t limbsize; /* bignum format - size of radix type, must be power of 2 */
174 int mslimbfirst; /* 0 or 1 */
175 int msbytefirst; /* 0 or 1; -1 = native */
176
177 /* All the callback functions should return 0 on success, or a
178 * nonzero integer (whose value will be visible in the error message
179 * put in the buffer passed to the call).
180 *
181 * If a callback is not available pass a null function pointer.
182 *
183 * The callbacks may not call down again into the crypto plugin.
184 */
185
186 /* For thread-safety. Set everything to 0 if you promise only to be
187 * singlethreaded. maxsimultaneous is the number of calls to
188 * ModExp[Crt]/RSAImmed{Priv,Pub}/RSA. If you don't know what to
189 * put there then say 0 and the hook library will use a default.
190 *
191 * maxmutexes is a small limit on the number of simultaneous mutexes
192 * which will be requested by the library. If there is no small
193 * limit, set it to 0. If the crypto plugin cannot create the
194 * advertised number of mutexes the calls to its functions may fail.
195 * If a low number of mutexes is advertised the plugin will try to
196 * do the best it can. Making larger numbers of mutexes available
197 * may improve performance and parallelism by reducing contention
198 * over critical sections. Unavailability of any mutexes, implying
199 * single-threaded operation, should be indicated by the setting
200 * mutex_init et al to 0.
201 */
202 int maxmutexes;
203 int maxsimultaneous;
204 size_t mutexsize;
205 int (*mutex_init)(HWCryptoHook_Mutex*, HWCryptoHook_CallerContext *cactx);
206 int (*mutex_acquire)(HWCryptoHook_Mutex*);
207 void (*mutex_release)(HWCryptoHook_Mutex*);
208 void (*mutex_destroy)(HWCryptoHook_Mutex*);
209
210 /* For greater efficiency, can use condition vars internally for
211 * synchronisation. In this case maxsimultaneous is ignored, but
212 * the other mutex stuff must be available. In singlethreaded
213 * programs, set everything to 0.
214 */
215 size_t condvarsize;
216 int (*condvar_init)(HWCryptoHook_CondVar*, HWCryptoHook_CallerContext *cactx);
217 int (*condvar_wait)(HWCryptoHook_CondVar*, HWCryptoHook_Mutex*);
218 void (*condvar_signal)(HWCryptoHook_CondVar*);
219 void (*condvar_broadcast)(HWCryptoHook_CondVar*);
220 void (*condvar_destroy)(HWCryptoHook_CondVar*);
221
222 /* The semantics of acquiring and releasing mutexes and broadcasting
223 * and waiting on condition variables are expected to be those from
224 * POSIX threads (pthreads). The mutexes may be (in pthread-speak)
225 * fast mutexes, recursive mutexes, or nonrecursive ones.
226 *
227 * The _release/_signal/_broadcast and _destroy functions must
228 * always succeed when given a valid argument; if they are given an
229 * invalid argument then the program (crypto plugin + application)
230 * has an internal error, and they should abort the program.
231 */
232
233 int (*getpassphrase)(const char *prompt_info,
234 int *len_io, char *buf,
235 HWCryptoHook_PassphraseContext *ppctx,
236 HWCryptoHook_CallerContext *cactx);
237 /* Passphrases and the prompt_info, if they contain high-bit-set
238 * characters, are UTF-8. The prompt_info may be a null pointer if
239 * no prompt information is available (it should not be an empty
240 * string). It will not contain text like `enter passphrase';
241 * instead it might say something like `Operator Card for John
242 * Smith' or `SmartCard in nFast Module #1, Slot #1'.
243 *
244 * buf points to a buffer in which to return the passphrase; on
245 * entry *len_io is the length of the buffer. It should be updated
246 * by the callback. The returned passphrase should not be
247 * null-terminated by the callback.
248 */
249
250 int (*getphystoken)(const char *prompt_info,
251 const char *wrong_info,
252 HWCryptoHook_PassphraseContext *ppctx,
253 HWCryptoHook_CallerContext *cactx);
254 /* Requests that the human user physically insert a different
255 * smartcard, DataKey, etc. The plugin should check whether the
256 * currently inserted token(s) are appropriate, and if they are it
257 * should not make this call.
258 *
259 * prompt_info is as before. wrong_info is a description of the
260 * currently inserted token(s) so that the user is told what
261 * something is. wrong_info, like prompt_info, may be null, but
262 * should not be an empty string. Its contents should be
263 * syntactically similar to that of prompt_info.
264 */
265
266 /* Note that a single LoadKey operation might cause several calls to
267 * getpassphrase and/or requestphystoken. If requestphystoken is
268 * not provided (ie, a null pointer is passed) then the plugin may
269 * not support loading keys for which authorisation by several cards
270 * is required. If getpassphrase is not provided then cards with
271 * passphrases may not be supported.
272 *
273 * getpassphrase and getphystoken do not need to check that the
274 * passphrase has been entered correctly or the correct token
275 * inserted; the crypto plugin will do that. If this is not the
276 * case then the crypto plugin is responsible for calling these
277 * routines again as appropriate until the correct token(s) and
278 * passphrase(s) are supplied as required, or until any retry limits
279 * implemented by the crypto plugin are reached.
280 *
281 * In either case, the application must allow the user to say `no'
282 * or `cancel' to indicate that they do not know the passphrase or
283 * have the appropriate token; this should cause the callback to
284 * return nonzero indicating error.
285 */
286
287 void (*logmessage)(void *logstream, const char *message);
288 /* A log message will be generated at least every time something goes
289 * wrong and an ErrMsgBuf is filled in (or would be if one was
290 * provided). Other diagnostic information may be written there too,
291 * including more detailed reasons for errors which are reported in an
292 * ErrMsgBuf.
293 *
294 * When a log message is generated, this callback is called. It
295 * should write a message to the relevant logging arrangements.
296 *
297 * The message string passed will be null-terminated and may be of arbitrary
298 * length. It will not be prefixed by the time and date, nor by the
299 * name of the library that is generating it - if this is required,
300 * the logmessage callback must do it. The message will not have a
301 * trailing newline (though it may contain internal newlines).
302 *
303 * If a null pointer is passed for logmessage a default function is
304 * used. The default function treats logstream as a FILE* which has
305 * been converted to a void*. If logstream is 0 it does nothing.
306 * Otherwise it prepends the date and time and library name and
307 * writes the message to logstream. Each line will be prefixed by a
308 * descriptive string containing the date, time and identity of the
309 * crypto plugin. Errors on the logstream are not reported
310 * anywhere, and the default function doesn't flush the stream, so
311 * the application must set the buffering how it wants it.
312 *
313 * The crypto plugin may also provide a facility to have copies of
314 * log messages sent elsewhere, and or for adjusting the verbosity
315 * of the log messages; any such facilities will be configured by
316 * external means.
317 */
318
319} HWCryptoHook_InitInfo;
320
321typedef
322HWCryptoHook_ContextHandle HWCryptoHook_Init_t(const HWCryptoHook_InitInfo *initinfo,
323 size_t initinfosize,
324 const HWCryptoHook_ErrMsgBuf *errors,
325 HWCryptoHook_CallerContext *cactx);
326extern HWCryptoHook_Init_t HWCryptoHook_Init;
327
328/* Caller should set initinfosize to the size of the HWCryptoHook struct,
329 * so it can be extended later.
330 *
331 * On success, a message for display or logging by the server,
332 * including the name and version number of the plugin, will be filled
333 * in into *errors; on failure *errors is used for error handling, as
334 * usual.
335 */
336
337/* All these functions return 0 on success, HWCRYPTOHOOK_ERROR_FAILED
338 * on most failures. HWCRYPTOHOOK_ERROR_MPISIZE means at least one of
339 * the output MPI buffer(s) was too small; the sizes of all have been
340 * set to the desired size (and for those where the buffer was large
341 * enough, the value may have been copied in), and no error message
342 * has been recorded.
343 *
344 * You may pass 0 for the errors struct. In any case, unless you set
345 * _NoStderr at init time then messages may be reported to stderr.
346 */
347
348/* The RSAImmed* functions (and key managed RSA) only work with
349 * modules which have an RSA patent licence - currently that means KM
350 * units; the ModExp* ones work with all modules, so you need a patent
351 * licence in the software in the US. They are otherwise identical.
352 */
353
354typedef
355void HWCryptoHook_Finish_t(HWCryptoHook_ContextHandle hwctx);
356extern HWCryptoHook_Finish_t HWCryptoHook_Finish;
357/* You must not have any calls going or keys loaded when you call this. */
358
359typedef
360int HWCryptoHook_RandomBytes_t(HWCryptoHook_ContextHandle hwctx,
361 unsigned char *buf, size_t len,
362 const HWCryptoHook_ErrMsgBuf *errors);
363extern HWCryptoHook_RandomBytes_t HWCryptoHook_RandomBytes;
364
365typedef
366int HWCryptoHook_ModExp_t(HWCryptoHook_ContextHandle hwctx,
367 HWCryptoHook_MPI a,
368 HWCryptoHook_MPI p,
369 HWCryptoHook_MPI n,
370 HWCryptoHook_MPI *r,
371 const HWCryptoHook_ErrMsgBuf *errors);
372extern HWCryptoHook_ModExp_t HWCryptoHook_ModExp;
373
374typedef
375int HWCryptoHook_RSAImmedPub_t(HWCryptoHook_ContextHandle hwctx,
376 HWCryptoHook_MPI m,
377 HWCryptoHook_MPI e,
378 HWCryptoHook_MPI n,
379 HWCryptoHook_MPI *r,
380 const HWCryptoHook_ErrMsgBuf *errors);
381extern HWCryptoHook_RSAImmedPub_t HWCryptoHook_RSAImmedPub;
382
383typedef
384int HWCryptoHook_ModExpCRT_t(HWCryptoHook_ContextHandle hwctx,
385 HWCryptoHook_MPI a,
386 HWCryptoHook_MPI p,
387 HWCryptoHook_MPI q,
388 HWCryptoHook_MPI dmp1,
389 HWCryptoHook_MPI dmq1,
390 HWCryptoHook_MPI iqmp,
391 HWCryptoHook_MPI *r,
392 const HWCryptoHook_ErrMsgBuf *errors);
393extern HWCryptoHook_ModExpCRT_t HWCryptoHook_ModExpCRT;
394
395typedef
396int HWCryptoHook_RSAImmedPriv_t(HWCryptoHook_ContextHandle hwctx,
397 HWCryptoHook_MPI m,
398 HWCryptoHook_MPI p,
399 HWCryptoHook_MPI q,
400 HWCryptoHook_MPI dmp1,
401 HWCryptoHook_MPI dmq1,
402 HWCryptoHook_MPI iqmp,
403 HWCryptoHook_MPI *r,
404 const HWCryptoHook_ErrMsgBuf *errors);
405extern HWCryptoHook_RSAImmedPriv_t HWCryptoHook_RSAImmedPriv;
406
407/* The RSAImmed* and ModExp* functions may return E_FAILED or
408 * E_FALLBACK for failure.
409 *
410 * E_FAILED means the failure is permanent and definite and there
411 * should be no attempt to fall back to software. (Eg, for some
412 * applications, which support only the acceleration-only
413 * functions, the `key material' may actually be an encoded key
414 * identifier, and doing the operation in software would give wrong
415 * answers.)
416 *
417 * E_FALLBACK means that doing the computation in software would seem
418 * reasonable. If an application pays attention to this and is
419 * able to fall back, it should also set the Fallback init flags.
420 */
421
422typedef
423int HWCryptoHook_RSALoadKey_t(HWCryptoHook_ContextHandle hwctx,
424 const char *key_ident,
425 HWCryptoHook_RSAKeyHandle *keyhandle_r,
426 const HWCryptoHook_ErrMsgBuf *errors,
427 HWCryptoHook_PassphraseContext *ppctx);
428extern HWCryptoHook_RSALoadKey_t HWCryptoHook_RSALoadKey;
429/* The key_ident is a null-terminated string configured by the
430 * user via the application's usual configuration mechanisms.
431 * It is provided to the user by the crypto provider's key management
432 * system. The user must be able to enter at least any string of between
433 * 1 and 1023 characters inclusive, consisting of printable 7-bit
434 * ASCII characters. The provider should avoid using
435 * any characters except alphanumerics and the punctuation
436 * characters _ - + . / @ ~ (the user is expected to be able
437 * to enter these without quoting). The string may be case-sensitive.
438 * The application may allow the user to enter other NULL-terminated strings,
439 * and the provider must cope (returning an error if the string is not
440 * valid).
441 *
442 * If the key does not exist, no error is recorded and 0 is returned;
443 * keyhandle_r will be set to 0 instead of to a key handle.
444 */
445
446typedef
447int HWCryptoHook_RSAGetPublicKey_t(HWCryptoHook_RSAKeyHandle k,
448 HWCryptoHook_MPI *n,
449 HWCryptoHook_MPI *e,
450 const HWCryptoHook_ErrMsgBuf *errors);
451extern HWCryptoHook_RSAGetPublicKey_t HWCryptoHook_RSAGetPublicKey;
452/* The crypto plugin will not store certificates.
453 *
454 * Although this function for acquiring the public key value is
455 * provided, it is not the purpose of this API to deal fully with the
456 * handling of the public key.
457 *
458 * It is expected that the crypto supplier's key generation program
459 * will provide general facilities for producing X.509
460 * self-certificates and certificate requests in PEM format. These
461 * will be given to the user so that they can configure them in the
462 * application, send them to CAs, or whatever.
463 *
464 * In case this kind of certificate handling is not appropriate, the
465 * crypto supplier's key generation program should be able to be
466 * configured not to generate such a self-certificate or certificate
467 * request. Then the application will need to do all of this, and
468 * will need to store and handle the public key and certificates
469 * itself.
470 */
471
472typedef
473int HWCryptoHook_RSAUnloadKey_t(HWCryptoHook_RSAKeyHandle k,
474 const HWCryptoHook_ErrMsgBuf *errors);
475extern HWCryptoHook_RSAUnloadKey_t HWCryptoHook_RSAUnloadKey;
476/* Might fail due to locking problems, or other serious internal problems. */
477
478typedef
479int HWCryptoHook_RSA_t(HWCryptoHook_MPI m,
480 HWCryptoHook_RSAKeyHandle k,
481 HWCryptoHook_MPI *r,
482 const HWCryptoHook_ErrMsgBuf *errors);
483extern HWCryptoHook_RSA_t HWCryptoHook_RSA;
484/* RSA private key operation (sign or decrypt) - raw, unpadded. */
485
486#endif /*HWCRYPTOHOOK_H*/
diff --git a/src/lib/libcrypto/engine/vendor_defns/sureware.h b/src/lib/libcrypto/engine/vendor_defns/sureware.h
deleted file mode 100644
index 4bc22027f9..0000000000
--- a/src/lib/libcrypto/engine/vendor_defns/sureware.h
+++ /dev/null
@@ -1,239 +0,0 @@
1/*
2* Written by Corinne Dive-Reclus(cdive@baltimore.com)
3*
4* Copyright@2001 Baltimore Technologies Ltd.
5* *
6* THIS FILE IS PROVIDED BY BALTIMORE TECHNOLOGIES ``AS IS'' AND *
7* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE *
8* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE *
9* ARE DISCLAIMED. IN NO EVENT SHALL BALTIMORE TECHNOLOGIES BE LIABLE *
10* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL *
11* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS *
12* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) *
13* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT *
14* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY *
15* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF *
16* SUCH DAMAGE. *
17*
18*
19*/
20#ifdef WIN32
21#define SW_EXPORT __declspec ( dllexport )
22#else
23#define SW_EXPORT
24#endif
25
26/*
27* List of exposed SureWare errors
28*/
29#define SUREWAREHOOK_ERROR_FAILED -1
30#define SUREWAREHOOK_ERROR_FALLBACK -2
31#define SUREWAREHOOK_ERROR_UNIT_FAILURE -3
32#define SUREWAREHOOK_ERROR_DATA_SIZE -4
33#define SUREWAREHOOK_ERROR_INVALID_PAD -5
34/*
35* -----------------WARNING-----------------------------------
36* In all the following functions:
37* msg is a string with at least 24 bytes free.
38* A 24 bytes string will be concatenated to the existing content of msg.
39*/
40/*
41* SureWare Initialisation function
42* in param threadsafe, if !=0, thread safe enabled
43* return SureWareHOOK_ERROR_UNIT_FAILURE if failure, 1 if success
44*/
45typedef int SureWareHook_Init_t(char*const msg,int threadsafe);
46extern SW_EXPORT SureWareHook_Init_t SureWareHook_Init;
47/*
48* SureWare Finish function
49*/
50typedef void SureWareHook_Finish_t();
51extern SW_EXPORT SureWareHook_Finish_t SureWareHook_Finish;
52/*
53* PRE_CONDITION:
54* DO NOT CALL ANY OF THE FOLLOWING FUNCTIONS IN CASE OF INIT FAILURE
55*/
56/*
57* SureWare RAND Bytes function
58* In case of failure, the content of buf is unpredictable.
59* return 1 if success
60* SureWareHOOK_ERROR_FALLBACK if function not available in hardware
61* SureWareHOOK_ERROR_FAILED if error while processing
62* SureWareHOOK_ERROR_UNIT_FAILURE if hardware failure
63* SUREWAREHOOK_ERROR_DATA_SIZE wrong size for buf
64*
65* in/out param buf : a num bytes long buffer where random bytes will be put
66* in param num : the number of bytes into buf
67*/
68typedef int SureWareHook_Rand_Bytes_t(char*const msg,unsigned char *buf, int num);
69extern SW_EXPORT SureWareHook_Rand_Bytes_t SureWareHook_Rand_Bytes;
70
71/*
72* SureWare RAND Seed function
73* Adds some seed to the Hardware Random Number Generator
74* return 1 if success
75* SureWareHOOK_ERROR_FALLBACK if function not available in hardware
76* SureWareHOOK_ERROR_FAILED if error while processing
77* SureWareHOOK_ERROR_UNIT_FAILURE if hardware failure
78* SUREWAREHOOK_ERROR_DATA_SIZE wrong size for buf
79*
80* in param buf : the seed to add into the HRNG
81* in param num : the number of bytes into buf
82*/
83typedef int SureWareHook_Rand_Seed_t(char*const msg,const void *buf, int num);
84extern SW_EXPORT SureWareHook_Rand_Seed_t SureWareHook_Rand_Seed;
85
86/*
87* SureWare Load Private Key function
88* return 1 if success
89* SureWareHOOK_ERROR_FAILED if error while processing
90* No hardware is contact for this function.
91*
92* in param key_id :the name of the private protected key file without the extension
93 ".sws"
94* out param hptr : a pointer to a buffer allocated by SureWare_Hook
95* out param num: the effective key length in bytes
96* out param keytype: 1 if RSA 2 if DSA
97*/
98typedef int SureWareHook_Load_Privkey_t(char*const msg,const char *key_id,char **hptr,unsigned long *num,char *keytype);
99extern SW_EXPORT SureWareHook_Load_Privkey_t SureWareHook_Load_Privkey;
100
101/*
102* SureWare Info Public Key function
103* return 1 if success
104* SureWareHOOK_ERROR_FAILED if error while processing
105* No hardware is contact for this function.
106*
107* in param key_id :the name of the private protected key file without the extension
108 ".swp"
109* out param hptr : a pointer to a buffer allocated by SureWare_Hook
110* out param num: the effective key length in bytes
111* out param keytype: 1 if RSA 2 if DSA
112*/
113typedef int SureWareHook_Info_Pubkey_t(char*const msg,const char *key_id,unsigned long *num,
114 char *keytype);
115extern SW_EXPORT SureWareHook_Info_Pubkey_t SureWareHook_Info_Pubkey;
116
117/*
118* SureWare Load Public Key function
119* return 1 if success
120* SureWareHOOK_ERROR_FAILED if error while processing
121* No hardware is contact for this function.
122*
123* in param key_id :the name of the public protected key file without the extension
124 ".swp"
125* in param num : the bytes size of n and e
126* out param n: where to write modulus in bn format
127* out param e: where to write exponent in bn format
128*/
129typedef int SureWareHook_Load_Rsa_Pubkey_t(char*const msg,const char *key_id,unsigned long num,
130 unsigned long *n, unsigned long *e);
131extern SW_EXPORT SureWareHook_Load_Rsa_Pubkey_t SureWareHook_Load_Rsa_Pubkey;
132
133/*
134* SureWare Load DSA Public Key function
135* return 1 if success
136* SureWareHOOK_ERROR_FAILED if error while processing
137* No hardware is contact for this function.
138*
139* in param key_id :the name of the public protected key file without the extension
140 ".swp"
141* in param num : the bytes size of n and e
142* out param pub: where to write pub key in bn format
143* out param p: where to write prime in bn format
144* out param q: where to write sunprime (length 20 bytes) in bn format
145* out param g: where to write base in bn format
146*/
147typedef int SureWareHook_Load_Dsa_Pubkey_t(char*const msg,const char *key_id,unsigned long num,
148 unsigned long *pub, unsigned long *p,unsigned long*q,
149 unsigned long *g);
150extern SW_EXPORT SureWareHook_Load_Dsa_Pubkey_t SureWareHook_Load_Dsa_Pubkey;
151
152/*
153* SureWare Free function
154* Destroy the key into the hardware if destroy==1
155*/
156typedef void SureWareHook_Free_t(char *p,int destroy);
157extern SW_EXPORT SureWareHook_Free_t SureWareHook_Free;
158
159#define SUREWARE_PKCS1_PAD 1
160#define SUREWARE_ISO9796_PAD 2
161#define SUREWARE_NO_PAD 0
162/*
163* SureWare RSA Private Decryption
164* return 1 if success
165* SureWareHOOK_ERROR_FAILED if error while processing
166* SureWareHOOK_ERROR_UNIT_FAILURE if hardware failure
167* SUREWAREHOOK_ERROR_DATA_SIZE wrong size for buf
168*
169* in param flen : byte size of from and to
170* in param from : encrypted data buffer, should be a not-null valid pointer
171* out param tlen: byte size of decrypted data, if error, unexpected value
172* out param to : decrypted data buffer, should be a not-null valid pointer
173* in param prsa: a protected key pointer, should be a not-null valid pointer
174* int padding: padding id as follow
175* SUREWARE_PKCS1_PAD
176* SUREWARE_NO_PAD
177*
178*/
179typedef int SureWareHook_Rsa_Priv_Dec_t(char*const msg,int flen,unsigned char *from,
180 int *tlen,unsigned char *to,
181 char *prsa,int padding);
182extern SW_EXPORT SureWareHook_Rsa_Priv_Dec_t SureWareHook_Rsa_Priv_Dec;
183/*
184* SureWare RSA Signature
185* return 1 if success
186* SureWareHOOK_ERROR_FAILED if error while processing
187* SureWareHOOK_ERROR_UNIT_FAILURE if hardware failure
188* SUREWAREHOOK_ERROR_DATA_SIZE wrong size for buf
189*
190* in param flen : byte size of from and to
191* in param from : encrypted data buffer, should be a not-null valid pointer
192* out param tlen: byte size of decrypted data, if error, unexpected value
193* out param to : decrypted data buffer, should be a not-null valid pointer
194* in param prsa: a protected key pointer, should be a not-null valid pointer
195* int padding: padding id as follow
196* SUREWARE_PKCS1_PAD
197* SUREWARE_ISO9796_PAD
198*
199*/
200typedef int SureWareHook_Rsa_Sign_t(char*const msg,int flen,unsigned char *from,
201 int *tlen,unsigned char *to,
202 char *prsa,int padding);
203extern SW_EXPORT SureWareHook_Rsa_Sign_t SureWareHook_Rsa_Sign;
204/*
205* SureWare DSA Signature
206* return 1 if success
207* SureWareHOOK_ERROR_FAILED if error while processing
208* SureWareHOOK_ERROR_UNIT_FAILURE if hardware failure
209* SUREWAREHOOK_ERROR_DATA_SIZE wrong size for buf
210*
211* in param flen : byte size of from and to
212* in param from : encrypted data buffer, should be a not-null valid pointer
213* out param to : decrypted data buffer, should be a 40bytes valid pointer
214* in param pdsa: a protected key pointer, should be a not-null valid pointer
215*
216*/
217typedef int SureWareHook_Dsa_Sign_t(char*const msg,int flen,const unsigned char *from,
218 unsigned long *r,unsigned long *s,char *pdsa);
219extern SW_EXPORT SureWareHook_Dsa_Sign_t SureWareHook_Dsa_Sign;
220
221
222/*
223* SureWare Mod Exp
224* return 1 if success
225* SureWareHOOK_ERROR_FAILED if error while processing
226* SureWareHOOK_ERROR_UNIT_FAILURE if hardware failure
227* SUREWAREHOOK_ERROR_DATA_SIZE wrong size for buf
228*
229* mod and res are mlen bytes long.
230* exp is elen bytes long
231* data is dlen bytes long
232* mlen,elen and dlen are all multiple of sizeof(unsigned long)
233*/
234typedef int SureWareHook_Mod_Exp_t(char*const msg,int mlen,const unsigned long *mod,
235 int elen,const unsigned long *exponent,
236 int dlen,unsigned long *data,
237 unsigned long *res);
238extern SW_EXPORT SureWareHook_Mod_Exp_t SureWareHook_Mod_Exp;
239