1*0a6a1f1dSLionel Sambuc /*-
2*0a6a1f1dSLionel Sambuc * Written by Corinne Dive-Reclus(cdive@baltimore.com)
3ebfedea0SLionel Sambuc *
4ebfedea0SLionel Sambuc *
5ebfedea0SLionel Sambuc * Redistribution and use in source and binary forms, with or without
6ebfedea0SLionel Sambuc * modification, are permitted provided that the following conditions
7ebfedea0SLionel Sambuc * are met:
8ebfedea0SLionel Sambuc *
9ebfedea0SLionel Sambuc * 1. Redistributions of source code must retain the above copyright
10ebfedea0SLionel Sambuc * notice, this list of conditions and the following disclaimer.
11ebfedea0SLionel Sambuc *
12ebfedea0SLionel Sambuc * 2. Redistributions in binary form must reproduce the above copyright
13ebfedea0SLionel Sambuc * notice, this list of conditions and the following disclaimer in
14ebfedea0SLionel Sambuc * the documentation and/or other materials provided with the
15ebfedea0SLionel Sambuc * distribution.
16ebfedea0SLionel Sambuc *
17ebfedea0SLionel Sambuc * 3. All advertising materials mentioning features or use of this
18ebfedea0SLionel Sambuc * software must display the following acknowledgment:
19ebfedea0SLionel Sambuc * "This product includes software developed by the OpenSSL Project
20ebfedea0SLionel Sambuc * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
21ebfedea0SLionel Sambuc *
22ebfedea0SLionel Sambuc * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
23ebfedea0SLionel Sambuc * endorse or promote products derived from this software without
24ebfedea0SLionel Sambuc * prior written permission. For written permission, please contact
25ebfedea0SLionel Sambuc * licensing@OpenSSL.org.
26ebfedea0SLionel Sambuc *
27ebfedea0SLionel Sambuc * 5. Products derived from this software may not be called "OpenSSL"
28ebfedea0SLionel Sambuc * nor may "OpenSSL" appear in their names without prior written
29ebfedea0SLionel Sambuc * permission of the OpenSSL Project.
30ebfedea0SLionel Sambuc *
31ebfedea0SLionel Sambuc * 6. Redistributions of any form whatsoever must retain the following
32ebfedea0SLionel Sambuc * acknowledgment:
33ebfedea0SLionel Sambuc * "This product includes software developed by the OpenSSL Project
34ebfedea0SLionel Sambuc * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
35ebfedea0SLionel Sambuc *
36ebfedea0SLionel Sambuc * Written by Corinne Dive-Reclus(cdive@baltimore.com)
37ebfedea0SLionel Sambuc *
38ebfedea0SLionel Sambuc * Copyright@2001 Baltimore Technologies Ltd.
39ebfedea0SLionel Sambuc * All right Reserved.
40ebfedea0SLionel Sambuc * *
41ebfedea0SLionel Sambuc * THIS FILE IS PROVIDED BY BALTIMORE TECHNOLOGIES ``AS IS'' AND *
42ebfedea0SLionel Sambuc * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE *
43ebfedea0SLionel Sambuc * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE *
44ebfedea0SLionel Sambuc * ARE DISCLAIMED. IN NO EVENT SHALL BALTIMORE TECHNOLOGIES BE LIABLE *
45ebfedea0SLionel Sambuc * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL *
46ebfedea0SLionel Sambuc * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS *
47ebfedea0SLionel Sambuc * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) *
48ebfedea0SLionel Sambuc * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT *
49ebfedea0SLionel Sambuc * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY *
50ebfedea0SLionel Sambuc * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF *
51ebfedea0SLionel Sambuc * SUCH DAMAGE. *
52ebfedea0SLionel Sambuc ====================================================================*/
53ebfedea0SLionel Sambuc
54ebfedea0SLionel Sambuc #include <stdio.h>
55ebfedea0SLionel Sambuc #include <string.h>
56ebfedea0SLionel Sambuc #include <openssl/crypto.h>
57ebfedea0SLionel Sambuc #include <openssl/pem.h>
58ebfedea0SLionel Sambuc #include <openssl/dso.h>
59ebfedea0SLionel Sambuc #include <openssl/engine.h>
60ebfedea0SLionel Sambuc #include <openssl/rand.h>
61ebfedea0SLionel Sambuc #ifndef OPENSSL_NO_RSA
62ebfedea0SLionel Sambuc # include <openssl/rsa.h>
63ebfedea0SLionel Sambuc #endif
64ebfedea0SLionel Sambuc #ifndef OPENSSL_NO_DSA
65ebfedea0SLionel Sambuc # include <openssl/dsa.h>
66ebfedea0SLionel Sambuc #endif
67ebfedea0SLionel Sambuc #ifndef OPENSSL_NO_DH
68ebfedea0SLionel Sambuc # include <openssl/dh.h>
69ebfedea0SLionel Sambuc #endif
70ebfedea0SLionel Sambuc #include <openssl/bn.h>
71ebfedea0SLionel Sambuc
72ebfedea0SLionel Sambuc #ifndef OPENSSL_NO_HW
73ebfedea0SLionel Sambuc # ifndef OPENSSL_NO_HW_SUREWARE
74ebfedea0SLionel Sambuc
75ebfedea0SLionel Sambuc # ifdef FLAT_INC
76ebfedea0SLionel Sambuc # include "sureware.h"
77ebfedea0SLionel Sambuc # else
78ebfedea0SLionel Sambuc # include "vendor_defns/sureware.h"
79ebfedea0SLionel Sambuc # endif
80ebfedea0SLionel Sambuc
81ebfedea0SLionel Sambuc # define SUREWARE_LIB_NAME "sureware engine"
82ebfedea0SLionel Sambuc # include "e_sureware_err.c"
83ebfedea0SLionel Sambuc
84*0a6a1f1dSLionel Sambuc static int surewarehk_ctrl(ENGINE *e, int cmd, long i, void *p,
85*0a6a1f1dSLionel Sambuc void (*f) (void));
86ebfedea0SLionel Sambuc static int surewarehk_destroy(ENGINE *e);
87ebfedea0SLionel Sambuc static int surewarehk_init(ENGINE *e);
88ebfedea0SLionel Sambuc static int surewarehk_finish(ENGINE *e);
89ebfedea0SLionel Sambuc static int surewarehk_modexp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
90ebfedea0SLionel Sambuc const BIGNUM *m, BN_CTX *ctx);
91ebfedea0SLionel Sambuc
92ebfedea0SLionel Sambuc /* RSA stuff */
93ebfedea0SLionel Sambuc # ifndef OPENSSL_NO_RSA
94*0a6a1f1dSLionel Sambuc static int surewarehk_rsa_priv_dec(int flen, const unsigned char *from,
95*0a6a1f1dSLionel Sambuc unsigned char *to, RSA *rsa, int padding);
96*0a6a1f1dSLionel Sambuc static int surewarehk_rsa_sign(int flen, const unsigned char *from,
97*0a6a1f1dSLionel Sambuc unsigned char *to, RSA *rsa, int padding);
98ebfedea0SLionel Sambuc # endif
99ebfedea0SLionel Sambuc
100ebfedea0SLionel Sambuc /* RAND stuff */
101ebfedea0SLionel Sambuc static int surewarehk_rand_bytes(unsigned char *buf, int num);
102ebfedea0SLionel Sambuc static void surewarehk_rand_seed(const void *buf, int num);
103ebfedea0SLionel Sambuc static void surewarehk_rand_add(const void *buf, int num, double entropy);
104ebfedea0SLionel Sambuc
105ebfedea0SLionel Sambuc /* KM stuff */
106ebfedea0SLionel Sambuc static EVP_PKEY *surewarehk_load_privkey(ENGINE *e, const char *key_id,
107*0a6a1f1dSLionel Sambuc UI_METHOD *ui_method,
108*0a6a1f1dSLionel Sambuc void *callback_data);
109ebfedea0SLionel Sambuc static EVP_PKEY *surewarehk_load_pubkey(ENGINE *e, const char *key_id,
110*0a6a1f1dSLionel Sambuc UI_METHOD *ui_method,
111*0a6a1f1dSLionel Sambuc void *callback_data);
112ebfedea0SLionel Sambuc static void surewarehk_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad,
113ebfedea0SLionel Sambuc int idx, long argl, void *argp);
114ebfedea0SLionel Sambuc # if 0
115ebfedea0SLionel Sambuc static void surewarehk_dh_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad,
116ebfedea0SLionel Sambuc int idx, long argl, void *argp);
117ebfedea0SLionel Sambuc # endif
118ebfedea0SLionel Sambuc
119ebfedea0SLionel Sambuc # ifndef OPENSSL_NO_RSA
120ebfedea0SLionel Sambuc /* This function is aliased to mod_exp (with the mont stuff dropped). */
surewarehk_mod_exp_mont(BIGNUM * r,const BIGNUM * a,const BIGNUM * p,const BIGNUM * m,BN_CTX * ctx,BN_MONT_CTX * m_ctx)121*0a6a1f1dSLionel Sambuc static int surewarehk_mod_exp_mont(BIGNUM *r, const BIGNUM *a,
122*0a6a1f1dSLionel Sambuc const BIGNUM *p, const BIGNUM *m,
123*0a6a1f1dSLionel Sambuc BN_CTX *ctx, BN_MONT_CTX *m_ctx)
124ebfedea0SLionel Sambuc {
125ebfedea0SLionel Sambuc return surewarehk_modexp(r, a, p, m, ctx);
126ebfedea0SLionel Sambuc }
127ebfedea0SLionel Sambuc
128ebfedea0SLionel Sambuc /* Our internal RSA_METHOD that we provide pointers to */
129*0a6a1f1dSLionel Sambuc static RSA_METHOD surewarehk_rsa = {
130ebfedea0SLionel Sambuc "SureWare RSA method",
131ebfedea0SLionel Sambuc NULL, /* pub_enc */
132ebfedea0SLionel Sambuc NULL, /* pub_dec */
133ebfedea0SLionel Sambuc surewarehk_rsa_sign, /* our rsa_sign is OpenSSL priv_enc */
134ebfedea0SLionel Sambuc surewarehk_rsa_priv_dec, /* priv_dec */
135ebfedea0SLionel Sambuc NULL, /* mod_exp */
136ebfedea0SLionel Sambuc surewarehk_mod_exp_mont, /* mod_exp_mongomery */
137ebfedea0SLionel Sambuc NULL, /* init */
138ebfedea0SLionel Sambuc NULL, /* finish */
139ebfedea0SLionel Sambuc 0, /* RSA flag */
140ebfedea0SLionel Sambuc NULL,
141ebfedea0SLionel Sambuc NULL, /* OpenSSL sign */
142ebfedea0SLionel Sambuc NULL, /* OpenSSL verify */
143ebfedea0SLionel Sambuc NULL /* keygen */
144ebfedea0SLionel Sambuc };
145ebfedea0SLionel Sambuc # endif
146ebfedea0SLionel Sambuc
147ebfedea0SLionel Sambuc # ifndef OPENSSL_NO_DH
148ebfedea0SLionel Sambuc /* Our internal DH_METHOD that we provide pointers to */
149ebfedea0SLionel Sambuc /* This function is aliased to mod_exp (with the dh and mont dropped). */
surewarehk_modexp_dh(const DH * dh,BIGNUM * r,const BIGNUM * a,const BIGNUM * p,const BIGNUM * m,BN_CTX * ctx,BN_MONT_CTX * m_ctx)150ebfedea0SLionel Sambuc static int surewarehk_modexp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a,
151*0a6a1f1dSLionel Sambuc const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
152*0a6a1f1dSLionel Sambuc BN_MONT_CTX *m_ctx)
153ebfedea0SLionel Sambuc {
154ebfedea0SLionel Sambuc return surewarehk_modexp(r, a, p, m, ctx);
155ebfedea0SLionel Sambuc }
156ebfedea0SLionel Sambuc
157*0a6a1f1dSLionel Sambuc static DH_METHOD surewarehk_dh = {
158ebfedea0SLionel Sambuc "SureWare DH method",
159ebfedea0SLionel Sambuc NULL, /* gen_key */
160ebfedea0SLionel Sambuc NULL, /* agree, */
161ebfedea0SLionel Sambuc surewarehk_modexp_dh, /* dh mod exp */
162ebfedea0SLionel Sambuc NULL, /* init */
163ebfedea0SLionel Sambuc NULL, /* finish */
164ebfedea0SLionel Sambuc 0, /* flags */
165ebfedea0SLionel Sambuc NULL,
166ebfedea0SLionel Sambuc NULL
167ebfedea0SLionel Sambuc };
168ebfedea0SLionel Sambuc # endif
169ebfedea0SLionel Sambuc
170*0a6a1f1dSLionel Sambuc static RAND_METHOD surewarehk_rand = {
171ebfedea0SLionel Sambuc /* "SureWare RAND method", */
172ebfedea0SLionel Sambuc surewarehk_rand_seed,
173ebfedea0SLionel Sambuc surewarehk_rand_bytes,
174ebfedea0SLionel Sambuc NULL, /* cleanup */
175ebfedea0SLionel Sambuc surewarehk_rand_add,
176ebfedea0SLionel Sambuc surewarehk_rand_bytes,
177ebfedea0SLionel Sambuc NULL, /* rand_status */
178ebfedea0SLionel Sambuc };
179ebfedea0SLionel Sambuc
180ebfedea0SLionel Sambuc # ifndef OPENSSL_NO_DSA
181ebfedea0SLionel Sambuc /* DSA stuff */
182*0a6a1f1dSLionel Sambuc static DSA_SIG *surewarehk_dsa_do_sign(const unsigned char *dgst, int dlen,
183*0a6a1f1dSLionel Sambuc DSA *dsa);
surewarehk_dsa_mod_exp(DSA * dsa,BIGNUM * rr,BIGNUM * a1,BIGNUM * p1,BIGNUM * a2,BIGNUM * p2,BIGNUM * m,BN_CTX * ctx,BN_MONT_CTX * in_mont)184ebfedea0SLionel Sambuc static int surewarehk_dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1,
185*0a6a1f1dSLionel Sambuc BIGNUM *p1, BIGNUM *a2, BIGNUM *p2,
186*0a6a1f1dSLionel Sambuc BIGNUM *m, BN_CTX *ctx,
187*0a6a1f1dSLionel Sambuc BN_MONT_CTX *in_mont)
188ebfedea0SLionel Sambuc {
189ebfedea0SLionel Sambuc BIGNUM t;
190ebfedea0SLionel Sambuc int to_return = 0;
191ebfedea0SLionel Sambuc BN_init(&t);
192ebfedea0SLionel Sambuc /* let rr = a1 ^ p1 mod m */
193*0a6a1f1dSLionel Sambuc if (!surewarehk_modexp(rr, a1, p1, m, ctx))
194*0a6a1f1dSLionel Sambuc goto end;
195ebfedea0SLionel Sambuc /* let t = a2 ^ p2 mod m */
196*0a6a1f1dSLionel Sambuc if (!surewarehk_modexp(&t, a2, p2, m, ctx))
197*0a6a1f1dSLionel Sambuc goto end;
198ebfedea0SLionel Sambuc /* let rr = rr * t mod m */
199*0a6a1f1dSLionel Sambuc if (!BN_mod_mul(rr, rr, &t, m, ctx))
200*0a6a1f1dSLionel Sambuc goto end;
201ebfedea0SLionel Sambuc to_return = 1;
202ebfedea0SLionel Sambuc end:
203ebfedea0SLionel Sambuc BN_free(&t);
204ebfedea0SLionel Sambuc return to_return;
205ebfedea0SLionel Sambuc }
206ebfedea0SLionel Sambuc
207*0a6a1f1dSLionel Sambuc static DSA_METHOD surewarehk_dsa = {
208ebfedea0SLionel Sambuc "SureWare DSA method",
209ebfedea0SLionel Sambuc surewarehk_dsa_do_sign,
210ebfedea0SLionel Sambuc NULL, /* sign setup */
211ebfedea0SLionel Sambuc NULL, /* verify, */
212ebfedea0SLionel Sambuc surewarehk_dsa_mod_exp, /* mod exp */
213ebfedea0SLionel Sambuc NULL, /* bn mod exp */
214ebfedea0SLionel Sambuc NULL, /* init */
215ebfedea0SLionel Sambuc NULL, /* finish */
216ebfedea0SLionel Sambuc 0,
217ebfedea0SLionel Sambuc NULL,
218ebfedea0SLionel Sambuc NULL,
219ebfedea0SLionel Sambuc NULL
220ebfedea0SLionel Sambuc };
221ebfedea0SLionel Sambuc # endif
222ebfedea0SLionel Sambuc
223ebfedea0SLionel Sambuc static const char *engine_sureware_id = "sureware";
224ebfedea0SLionel Sambuc static const char *engine_sureware_name = "SureWare hardware engine support";
225ebfedea0SLionel Sambuc
226ebfedea0SLionel Sambuc /* Now, to our own code */
227ebfedea0SLionel Sambuc
228*0a6a1f1dSLionel Sambuc /*
229*0a6a1f1dSLionel Sambuc * As this is only ever called once, there's no need for locking (indeed -
230*0a6a1f1dSLionel Sambuc * the lock will already be held by our caller!!!)
231*0a6a1f1dSLionel Sambuc */
bind_sureware(ENGINE * e)232ebfedea0SLionel Sambuc static int bind_sureware(ENGINE *e)
233ebfedea0SLionel Sambuc {
234ebfedea0SLionel Sambuc # ifndef OPENSSL_NO_RSA
235ebfedea0SLionel Sambuc const RSA_METHOD *meth1;
236ebfedea0SLionel Sambuc # endif
237ebfedea0SLionel Sambuc # ifndef OPENSSL_NO_DSA
238ebfedea0SLionel Sambuc const DSA_METHOD *meth2;
239ebfedea0SLionel Sambuc # endif
240ebfedea0SLionel Sambuc # ifndef OPENSSL_NO_DH
241ebfedea0SLionel Sambuc const DH_METHOD *meth3;
242ebfedea0SLionel Sambuc # endif
243ebfedea0SLionel Sambuc
244ebfedea0SLionel Sambuc if (!ENGINE_set_id(e, engine_sureware_id) ||
245ebfedea0SLionel Sambuc !ENGINE_set_name(e, engine_sureware_name) ||
246ebfedea0SLionel Sambuc # ifndef OPENSSL_NO_RSA
247ebfedea0SLionel Sambuc !ENGINE_set_RSA(e, &surewarehk_rsa) ||
248ebfedea0SLionel Sambuc # endif
249ebfedea0SLionel Sambuc # ifndef OPENSSL_NO_DSA
250ebfedea0SLionel Sambuc !ENGINE_set_DSA(e, &surewarehk_dsa) ||
251ebfedea0SLionel Sambuc # endif
252ebfedea0SLionel Sambuc # ifndef OPENSSL_NO_DH
253ebfedea0SLionel Sambuc !ENGINE_set_DH(e, &surewarehk_dh) ||
254ebfedea0SLionel Sambuc # endif
255ebfedea0SLionel Sambuc !ENGINE_set_RAND(e, &surewarehk_rand) ||
256ebfedea0SLionel Sambuc !ENGINE_set_destroy_function(e, surewarehk_destroy) ||
257ebfedea0SLionel Sambuc !ENGINE_set_init_function(e, surewarehk_init) ||
258ebfedea0SLionel Sambuc !ENGINE_set_finish_function(e, surewarehk_finish) ||
259ebfedea0SLionel Sambuc !ENGINE_set_ctrl_function(e, surewarehk_ctrl) ||
260ebfedea0SLionel Sambuc !ENGINE_set_load_privkey_function(e, surewarehk_load_privkey) ||
261ebfedea0SLionel Sambuc !ENGINE_set_load_pubkey_function(e, surewarehk_load_pubkey))
262ebfedea0SLionel Sambuc return 0;
263ebfedea0SLionel Sambuc
264ebfedea0SLionel Sambuc # ifndef OPENSSL_NO_RSA
265*0a6a1f1dSLionel Sambuc /*
266*0a6a1f1dSLionel Sambuc * We know that the "PKCS1_SSLeay()" functions hook properly to the
267*0a6a1f1dSLionel Sambuc * cswift-specific mod_exp and mod_exp_crt so we use those functions. NB:
268*0a6a1f1dSLionel Sambuc * We don't use ENGINE_openssl() or anything "more generic" because
269*0a6a1f1dSLionel Sambuc * something like the RSAref code may not hook properly, and if you own
270*0a6a1f1dSLionel Sambuc * one of these cards then you have the right to do RSA operations on it
271*0a6a1f1dSLionel Sambuc * anyway!
272*0a6a1f1dSLionel Sambuc */
273ebfedea0SLionel Sambuc meth1 = RSA_PKCS1_SSLeay();
274*0a6a1f1dSLionel Sambuc if (meth1) {
275ebfedea0SLionel Sambuc surewarehk_rsa.rsa_pub_enc = meth1->rsa_pub_enc;
276ebfedea0SLionel Sambuc surewarehk_rsa.rsa_pub_dec = meth1->rsa_pub_dec;
277ebfedea0SLionel Sambuc }
278ebfedea0SLionel Sambuc # endif
279ebfedea0SLionel Sambuc
280ebfedea0SLionel Sambuc # ifndef OPENSSL_NO_DSA
281*0a6a1f1dSLionel Sambuc /*
282*0a6a1f1dSLionel Sambuc * Use the DSA_OpenSSL() method and just hook the mod_exp-ish bits.
283*0a6a1f1dSLionel Sambuc */
284ebfedea0SLionel Sambuc meth2 = DSA_OpenSSL();
285*0a6a1f1dSLionel Sambuc if (meth2) {
286ebfedea0SLionel Sambuc surewarehk_dsa.dsa_do_verify = meth2->dsa_do_verify;
287ebfedea0SLionel Sambuc }
288ebfedea0SLionel Sambuc # endif
289ebfedea0SLionel Sambuc
290ebfedea0SLionel Sambuc # ifndef OPENSSL_NO_DH
291ebfedea0SLionel Sambuc /* Much the same for Diffie-Hellman */
292ebfedea0SLionel Sambuc meth3 = DH_OpenSSL();
293*0a6a1f1dSLionel Sambuc if (meth3) {
294ebfedea0SLionel Sambuc surewarehk_dh.generate_key = meth3->generate_key;
295ebfedea0SLionel Sambuc surewarehk_dh.compute_key = meth3->compute_key;
296ebfedea0SLionel Sambuc }
297ebfedea0SLionel Sambuc # endif
298ebfedea0SLionel Sambuc
299ebfedea0SLionel Sambuc /* Ensure the sureware error handling is set up */
300ebfedea0SLionel Sambuc ERR_load_SUREWARE_strings();
301ebfedea0SLionel Sambuc return 1;
302ebfedea0SLionel Sambuc }
303ebfedea0SLionel Sambuc
304ebfedea0SLionel Sambuc # ifndef OPENSSL_NO_DYNAMIC_ENGINE
bind_helper(ENGINE * e,const char * id)305ebfedea0SLionel Sambuc static int bind_helper(ENGINE *e, const char *id)
306ebfedea0SLionel Sambuc {
307ebfedea0SLionel Sambuc if (id && (strcmp(id, engine_sureware_id) != 0))
308ebfedea0SLionel Sambuc return 0;
309ebfedea0SLionel Sambuc if (!bind_sureware(e))
310ebfedea0SLionel Sambuc return 0;
311ebfedea0SLionel Sambuc return 1;
312ebfedea0SLionel Sambuc }
313*0a6a1f1dSLionel Sambuc
314ebfedea0SLionel Sambuc IMPLEMENT_DYNAMIC_CHECK_FN()
315ebfedea0SLionel Sambuc IMPLEMENT_DYNAMIC_BIND_FN(bind_helper)
316ebfedea0SLionel Sambuc # else
317ebfedea0SLionel Sambuc static ENGINE *engine_sureware(void)
318ebfedea0SLionel Sambuc {
319ebfedea0SLionel Sambuc ENGINE *ret = ENGINE_new();
320ebfedea0SLionel Sambuc if (!ret)
321ebfedea0SLionel Sambuc return NULL;
322*0a6a1f1dSLionel Sambuc if (!bind_sureware(ret)) {
323ebfedea0SLionel Sambuc ENGINE_free(ret);
324ebfedea0SLionel Sambuc return NULL;
325ebfedea0SLionel Sambuc }
326ebfedea0SLionel Sambuc return ret;
327ebfedea0SLionel Sambuc }
328ebfedea0SLionel Sambuc
329ebfedea0SLionel Sambuc void ENGINE_load_sureware(void)
330ebfedea0SLionel Sambuc {
331ebfedea0SLionel Sambuc /* Copied from eng_[openssl|dyn].c */
332ebfedea0SLionel Sambuc ENGINE *toadd = engine_sureware();
333*0a6a1f1dSLionel Sambuc if (!toadd)
334*0a6a1f1dSLionel Sambuc return;
335ebfedea0SLionel Sambuc ENGINE_add(toadd);
336ebfedea0SLionel Sambuc ENGINE_free(toadd);
337ebfedea0SLionel Sambuc ERR_clear_error();
338ebfedea0SLionel Sambuc }
339ebfedea0SLionel Sambuc # endif
340ebfedea0SLionel Sambuc
341*0a6a1f1dSLionel Sambuc /*
342*0a6a1f1dSLionel Sambuc * This is a process-global DSO handle used for loading and unloading the
343*0a6a1f1dSLionel Sambuc * SureWareHook library. NB: This is only set (or unset) during an init() or
344*0a6a1f1dSLionel Sambuc * finish() call (reference counts permitting) and they're operating with
345*0a6a1f1dSLionel Sambuc * global locks, so this should be thread-safe implicitly.
346*0a6a1f1dSLionel Sambuc */
347ebfedea0SLionel Sambuc static DSO *surewarehk_dso = NULL;
348ebfedea0SLionel Sambuc # ifndef OPENSSL_NO_RSA
349*0a6a1f1dSLionel Sambuc /* Index for KM handle. Not really used yet. */
350*0a6a1f1dSLionel Sambuc static int rsaHndidx = -1;
351ebfedea0SLionel Sambuc # endif
352ebfedea0SLionel Sambuc # ifndef OPENSSL_NO_DSA
353*0a6a1f1dSLionel Sambuc /* Index for KM handle. Not really used yet. */
354*0a6a1f1dSLionel Sambuc static int dsaHndidx = -1;
355ebfedea0SLionel Sambuc # endif
356ebfedea0SLionel Sambuc
357*0a6a1f1dSLionel Sambuc /*
358*0a6a1f1dSLionel Sambuc * These are the function pointers that are (un)set when the library has
359*0a6a1f1dSLionel Sambuc * successfully (un)loaded.
360*0a6a1f1dSLionel Sambuc */
361ebfedea0SLionel Sambuc static SureWareHook_Init_t *p_surewarehk_Init = NULL;
362ebfedea0SLionel Sambuc static SureWareHook_Finish_t *p_surewarehk_Finish = NULL;
363ebfedea0SLionel Sambuc static SureWareHook_Rand_Bytes_t *p_surewarehk_Rand_Bytes = NULL;
364ebfedea0SLionel Sambuc static SureWareHook_Rand_Seed_t *p_surewarehk_Rand_Seed = NULL;
365ebfedea0SLionel Sambuc static SureWareHook_Load_Privkey_t *p_surewarehk_Load_Privkey = NULL;
366ebfedea0SLionel Sambuc static SureWareHook_Info_Pubkey_t *p_surewarehk_Info_Pubkey = NULL;
367ebfedea0SLionel Sambuc static SureWareHook_Load_Rsa_Pubkey_t *p_surewarehk_Load_Rsa_Pubkey = NULL;
368ebfedea0SLionel Sambuc static SureWareHook_Load_Dsa_Pubkey_t *p_surewarehk_Load_Dsa_Pubkey = NULL;
369ebfedea0SLionel Sambuc static SureWareHook_Free_t *p_surewarehk_Free = NULL;
370ebfedea0SLionel Sambuc static SureWareHook_Rsa_Priv_Dec_t *p_surewarehk_Rsa_Priv_Dec = NULL;
371ebfedea0SLionel Sambuc static SureWareHook_Rsa_Sign_t *p_surewarehk_Rsa_Sign = NULL;
372ebfedea0SLionel Sambuc static SureWareHook_Dsa_Sign_t *p_surewarehk_Dsa_Sign = NULL;
373ebfedea0SLionel Sambuc static SureWareHook_Mod_Exp_t *p_surewarehk_Mod_Exp = NULL;
374ebfedea0SLionel Sambuc
375ebfedea0SLionel Sambuc /* Used in the DSO operations. */
376ebfedea0SLionel Sambuc static const char *surewarehk_LIBNAME = "SureWareHook";
377ebfedea0SLionel Sambuc static const char *n_surewarehk_Init = "SureWareHook_Init";
378ebfedea0SLionel Sambuc static const char *n_surewarehk_Finish = "SureWareHook_Finish";
379ebfedea0SLionel Sambuc static const char *n_surewarehk_Rand_Bytes = "SureWareHook_Rand_Bytes";
380ebfedea0SLionel Sambuc static const char *n_surewarehk_Rand_Seed = "SureWareHook_Rand_Seed";
381ebfedea0SLionel Sambuc static const char *n_surewarehk_Load_Privkey = "SureWareHook_Load_Privkey";
382ebfedea0SLionel Sambuc static const char *n_surewarehk_Info_Pubkey = "SureWareHook_Info_Pubkey";
383*0a6a1f1dSLionel Sambuc static const char *n_surewarehk_Load_Rsa_Pubkey =
384*0a6a1f1dSLionel Sambuc "SureWareHook_Load_Rsa_Pubkey";
385*0a6a1f1dSLionel Sambuc static const char *n_surewarehk_Load_Dsa_Pubkey =
386*0a6a1f1dSLionel Sambuc "SureWareHook_Load_Dsa_Pubkey";
387ebfedea0SLionel Sambuc static const char *n_surewarehk_Free = "SureWareHook_Free";
388ebfedea0SLionel Sambuc static const char *n_surewarehk_Rsa_Priv_Dec = "SureWareHook_Rsa_Priv_Dec";
389ebfedea0SLionel Sambuc static const char *n_surewarehk_Rsa_Sign = "SureWareHook_Rsa_Sign";
390ebfedea0SLionel Sambuc static const char *n_surewarehk_Dsa_Sign = "SureWareHook_Dsa_Sign";
391ebfedea0SLionel Sambuc static const char *n_surewarehk_Mod_Exp = "SureWareHook_Mod_Exp";
392ebfedea0SLionel Sambuc static BIO *logstream = NULL;
393ebfedea0SLionel Sambuc
394*0a6a1f1dSLionel Sambuc /*
395*0a6a1f1dSLionel Sambuc * SureWareHook library functions and mechanics - these are used by the
396*0a6a1f1dSLionel Sambuc * higher-level functions further down. NB: As and where there's no error
397*0a6a1f1dSLionel Sambuc * checking, take a look lower down where these functions are called, the
398*0a6a1f1dSLionel Sambuc * checking and error handling is probably down there.
399ebfedea0SLionel Sambuc */
400ebfedea0SLionel Sambuc static int threadsafe = 1;
surewarehk_ctrl(ENGINE * e,int cmd,long i,void * p,void (* f)(void))401*0a6a1f1dSLionel Sambuc static int surewarehk_ctrl(ENGINE *e, int cmd, long i, void *p,
402*0a6a1f1dSLionel Sambuc void (*f) (void))
403ebfedea0SLionel Sambuc {
404ebfedea0SLionel Sambuc int to_return = 1;
405ebfedea0SLionel Sambuc
406*0a6a1f1dSLionel Sambuc switch (cmd) {
407ebfedea0SLionel Sambuc case ENGINE_CTRL_SET_LOGSTREAM:
408ebfedea0SLionel Sambuc {
409ebfedea0SLionel Sambuc BIO *bio = (BIO *)p;
410ebfedea0SLionel Sambuc CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
411*0a6a1f1dSLionel Sambuc if (logstream) {
412ebfedea0SLionel Sambuc BIO_free(logstream);
413ebfedea0SLionel Sambuc logstream = NULL;
414ebfedea0SLionel Sambuc }
415ebfedea0SLionel Sambuc if (CRYPTO_add(&bio->references, 1, CRYPTO_LOCK_BIO) > 1)
416ebfedea0SLionel Sambuc logstream = bio;
417ebfedea0SLionel Sambuc else
418*0a6a1f1dSLionel Sambuc SUREWAREerr(SUREWARE_F_SUREWAREHK_CTRL,
419*0a6a1f1dSLionel Sambuc SUREWARE_R_BIO_WAS_FREED);
420ebfedea0SLionel Sambuc }
421ebfedea0SLionel Sambuc CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
422ebfedea0SLionel Sambuc break;
423*0a6a1f1dSLionel Sambuc /*
424*0a6a1f1dSLionel Sambuc * This will prevent the initialisation function from "installing"
425ebfedea0SLionel Sambuc * the mutex-handling callbacks, even if they are available from
426ebfedea0SLionel Sambuc * within the library (or were provided to the library from the
427ebfedea0SLionel Sambuc * calling application). This is to remove any baggage for
428*0a6a1f1dSLionel Sambuc * applications not using multithreading.
429*0a6a1f1dSLionel Sambuc */
430ebfedea0SLionel Sambuc case ENGINE_CTRL_CHIL_NO_LOCKING:
431ebfedea0SLionel Sambuc CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
432ebfedea0SLionel Sambuc threadsafe = 0;
433ebfedea0SLionel Sambuc CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
434ebfedea0SLionel Sambuc break;
435ebfedea0SLionel Sambuc
436ebfedea0SLionel Sambuc /* The command isn't understood by this engine */
437ebfedea0SLionel Sambuc default:
438ebfedea0SLionel Sambuc SUREWAREerr(SUREWARE_F_SUREWAREHK_CTRL,
439ebfedea0SLionel Sambuc ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED);
440ebfedea0SLionel Sambuc to_return = 0;
441ebfedea0SLionel Sambuc break;
442ebfedea0SLionel Sambuc }
443ebfedea0SLionel Sambuc
444ebfedea0SLionel Sambuc return to_return;
445ebfedea0SLionel Sambuc }
446ebfedea0SLionel Sambuc
447ebfedea0SLionel Sambuc /* Destructor (complements the "ENGINE_surewarehk()" constructor) */
surewarehk_destroy(ENGINE * e)448ebfedea0SLionel Sambuc static int surewarehk_destroy(ENGINE *e)
449ebfedea0SLionel Sambuc {
450ebfedea0SLionel Sambuc ERR_unload_SUREWARE_strings();
451ebfedea0SLionel Sambuc return 1;
452ebfedea0SLionel Sambuc }
453ebfedea0SLionel Sambuc
454ebfedea0SLionel Sambuc /* (de)initialisation functions. */
surewarehk_init(ENGINE * e)455ebfedea0SLionel Sambuc static int surewarehk_init(ENGINE *e)
456ebfedea0SLionel Sambuc {
457ebfedea0SLionel Sambuc char msg[64] = "ENGINE_init";
458ebfedea0SLionel Sambuc SureWareHook_Init_t *p1 = NULL;
459ebfedea0SLionel Sambuc SureWareHook_Finish_t *p2 = NULL;
460ebfedea0SLionel Sambuc SureWareHook_Rand_Bytes_t *p3 = NULL;
461ebfedea0SLionel Sambuc SureWareHook_Rand_Seed_t *p4 = NULL;
462ebfedea0SLionel Sambuc SureWareHook_Load_Privkey_t *p5 = NULL;
463ebfedea0SLionel Sambuc SureWareHook_Load_Rsa_Pubkey_t *p6 = NULL;
464ebfedea0SLionel Sambuc SureWareHook_Free_t *p7 = NULL;
465ebfedea0SLionel Sambuc SureWareHook_Rsa_Priv_Dec_t *p8 = NULL;
466ebfedea0SLionel Sambuc SureWareHook_Rsa_Sign_t *p9 = NULL;
467ebfedea0SLionel Sambuc SureWareHook_Dsa_Sign_t *p12 = NULL;
468ebfedea0SLionel Sambuc SureWareHook_Info_Pubkey_t *p13 = NULL;
469ebfedea0SLionel Sambuc SureWareHook_Load_Dsa_Pubkey_t *p14 = NULL;
470ebfedea0SLionel Sambuc SureWareHook_Mod_Exp_t *p15 = NULL;
471ebfedea0SLionel Sambuc
472*0a6a1f1dSLionel Sambuc if (surewarehk_dso != NULL) {
473ebfedea0SLionel Sambuc SUREWAREerr(SUREWARE_F_SUREWAREHK_INIT, ENGINE_R_ALREADY_LOADED);
474ebfedea0SLionel Sambuc goto err;
475ebfedea0SLionel Sambuc }
476ebfedea0SLionel Sambuc /* Attempt to load libsurewarehk.so/surewarehk.dll/whatever. */
477ebfedea0SLionel Sambuc surewarehk_dso = DSO_load(NULL, surewarehk_LIBNAME, NULL, 0);
478*0a6a1f1dSLionel Sambuc if (surewarehk_dso == NULL) {
479ebfedea0SLionel Sambuc SUREWAREerr(SUREWARE_F_SUREWAREHK_INIT, ENGINE_R_DSO_FAILURE);
480ebfedea0SLionel Sambuc goto err;
481ebfedea0SLionel Sambuc }
482*0a6a1f1dSLionel Sambuc if (!
483*0a6a1f1dSLionel Sambuc (p1 =
484*0a6a1f1dSLionel Sambuc (SureWareHook_Init_t *) DSO_bind_func(surewarehk_dso,
485*0a6a1f1dSLionel Sambuc n_surewarehk_Init))
486*0a6a1f1dSLionel Sambuc || !(p2 =
487*0a6a1f1dSLionel Sambuc (SureWareHook_Finish_t *) DSO_bind_func(surewarehk_dso,
488*0a6a1f1dSLionel Sambuc n_surewarehk_Finish))
489*0a6a1f1dSLionel Sambuc || !(p3 =
490*0a6a1f1dSLionel Sambuc (SureWareHook_Rand_Bytes_t *) DSO_bind_func(surewarehk_dso,
491*0a6a1f1dSLionel Sambuc n_surewarehk_Rand_Bytes))
492*0a6a1f1dSLionel Sambuc || !(p4 =
493*0a6a1f1dSLionel Sambuc (SureWareHook_Rand_Seed_t *) DSO_bind_func(surewarehk_dso,
494*0a6a1f1dSLionel Sambuc n_surewarehk_Rand_Seed))
495*0a6a1f1dSLionel Sambuc || !(p5 =
496*0a6a1f1dSLionel Sambuc (SureWareHook_Load_Privkey_t *) DSO_bind_func(surewarehk_dso,
497*0a6a1f1dSLionel Sambuc n_surewarehk_Load_Privkey))
498*0a6a1f1dSLionel Sambuc || !(p6 =
499*0a6a1f1dSLionel Sambuc (SureWareHook_Load_Rsa_Pubkey_t *) DSO_bind_func(surewarehk_dso,
500*0a6a1f1dSLionel Sambuc n_surewarehk_Load_Rsa_Pubkey))
501*0a6a1f1dSLionel Sambuc || !(p7 =
502*0a6a1f1dSLionel Sambuc (SureWareHook_Free_t *) DSO_bind_func(surewarehk_dso, n_surewarehk_Free))
503*0a6a1f1dSLionel Sambuc || !(p8 =
504*0a6a1f1dSLionel Sambuc (SureWareHook_Rsa_Priv_Dec_t *) DSO_bind_func(surewarehk_dso,
505*0a6a1f1dSLionel Sambuc n_surewarehk_Rsa_Priv_Dec))
506*0a6a1f1dSLionel Sambuc || !(p9 =
507*0a6a1f1dSLionel Sambuc (SureWareHook_Rsa_Sign_t *) DSO_bind_func(surewarehk_dso,
508*0a6a1f1dSLionel Sambuc n_surewarehk_Rsa_Sign))
509*0a6a1f1dSLionel Sambuc || !(p12 =
510*0a6a1f1dSLionel Sambuc (SureWareHook_Dsa_Sign_t *) DSO_bind_func(surewarehk_dso,
511*0a6a1f1dSLionel Sambuc n_surewarehk_Dsa_Sign))
512*0a6a1f1dSLionel Sambuc || !(p13 =
513*0a6a1f1dSLionel Sambuc (SureWareHook_Info_Pubkey_t *) DSO_bind_func(surewarehk_dso,
514*0a6a1f1dSLionel Sambuc n_surewarehk_Info_Pubkey))
515*0a6a1f1dSLionel Sambuc || !(p14 =
516*0a6a1f1dSLionel Sambuc (SureWareHook_Load_Dsa_Pubkey_t *) DSO_bind_func(surewarehk_dso,
517*0a6a1f1dSLionel Sambuc n_surewarehk_Load_Dsa_Pubkey))
518*0a6a1f1dSLionel Sambuc || !(p15 =
519*0a6a1f1dSLionel Sambuc (SureWareHook_Mod_Exp_t *) DSO_bind_func(surewarehk_dso,
520*0a6a1f1dSLionel Sambuc n_surewarehk_Mod_Exp))) {
521ebfedea0SLionel Sambuc SUREWAREerr(SUREWARE_F_SUREWAREHK_INIT, ENGINE_R_DSO_FAILURE);
522ebfedea0SLionel Sambuc goto err;
523ebfedea0SLionel Sambuc }
524ebfedea0SLionel Sambuc /* Copy the pointers */
525ebfedea0SLionel Sambuc p_surewarehk_Init = p1;
526ebfedea0SLionel Sambuc p_surewarehk_Finish = p2;
527ebfedea0SLionel Sambuc p_surewarehk_Rand_Bytes = p3;
528ebfedea0SLionel Sambuc p_surewarehk_Rand_Seed = p4;
529ebfedea0SLionel Sambuc p_surewarehk_Load_Privkey = p5;
530ebfedea0SLionel Sambuc p_surewarehk_Load_Rsa_Pubkey = p6;
531ebfedea0SLionel Sambuc p_surewarehk_Free = p7;
532ebfedea0SLionel Sambuc p_surewarehk_Rsa_Priv_Dec = p8;
533ebfedea0SLionel Sambuc p_surewarehk_Rsa_Sign = p9;
534ebfedea0SLionel Sambuc p_surewarehk_Dsa_Sign = p12;
535ebfedea0SLionel Sambuc p_surewarehk_Info_Pubkey = p13;
536ebfedea0SLionel Sambuc p_surewarehk_Load_Dsa_Pubkey = p14;
537ebfedea0SLionel Sambuc p_surewarehk_Mod_Exp = p15;
538ebfedea0SLionel Sambuc /* Contact the hardware and initialises it. */
539*0a6a1f1dSLionel Sambuc if (p_surewarehk_Init(msg, threadsafe) == SUREWAREHOOK_ERROR_UNIT_FAILURE) {
540ebfedea0SLionel Sambuc SUREWAREerr(SUREWARE_F_SUREWAREHK_INIT, SUREWARE_R_UNIT_FAILURE);
541ebfedea0SLionel Sambuc goto err;
542ebfedea0SLionel Sambuc }
543*0a6a1f1dSLionel Sambuc if (p_surewarehk_Init(msg, threadsafe) == SUREWAREHOOK_ERROR_UNIT_FAILURE) {
544ebfedea0SLionel Sambuc SUREWAREerr(SUREWARE_F_SUREWAREHK_INIT, SUREWARE_R_UNIT_FAILURE);
545ebfedea0SLionel Sambuc goto err;
546ebfedea0SLionel Sambuc }
547*0a6a1f1dSLionel Sambuc /*
548*0a6a1f1dSLionel Sambuc * try to load the default private key, if failed does not return a
549*0a6a1f1dSLionel Sambuc * failure but wait for an explicit ENGINE_load_privakey
550*0a6a1f1dSLionel Sambuc */
551ebfedea0SLionel Sambuc surewarehk_load_privkey(e, NULL, NULL, NULL);
552ebfedea0SLionel Sambuc
553ebfedea0SLionel Sambuc /* Everything's fine. */
554ebfedea0SLionel Sambuc # ifndef OPENSSL_NO_RSA
555ebfedea0SLionel Sambuc if (rsaHndidx == -1)
556ebfedea0SLionel Sambuc rsaHndidx = RSA_get_ex_new_index(0,
557ebfedea0SLionel Sambuc "SureWareHook RSA key handle",
558ebfedea0SLionel Sambuc NULL, NULL, surewarehk_ex_free);
559ebfedea0SLionel Sambuc # endif
560ebfedea0SLionel Sambuc # ifndef OPENSSL_NO_DSA
561ebfedea0SLionel Sambuc if (dsaHndidx == -1)
562ebfedea0SLionel Sambuc dsaHndidx = DSA_get_ex_new_index(0,
563ebfedea0SLionel Sambuc "SureWareHook DSA key handle",
564ebfedea0SLionel Sambuc NULL, NULL, surewarehk_ex_free);
565ebfedea0SLionel Sambuc # endif
566ebfedea0SLionel Sambuc
567ebfedea0SLionel Sambuc return 1;
568ebfedea0SLionel Sambuc err:
569ebfedea0SLionel Sambuc if (surewarehk_dso)
570ebfedea0SLionel Sambuc DSO_free(surewarehk_dso);
571ebfedea0SLionel Sambuc surewarehk_dso = NULL;
572ebfedea0SLionel Sambuc p_surewarehk_Init = NULL;
573ebfedea0SLionel Sambuc p_surewarehk_Finish = NULL;
574ebfedea0SLionel Sambuc p_surewarehk_Rand_Bytes = NULL;
575ebfedea0SLionel Sambuc p_surewarehk_Rand_Seed = NULL;
576ebfedea0SLionel Sambuc p_surewarehk_Load_Privkey = NULL;
577ebfedea0SLionel Sambuc p_surewarehk_Load_Rsa_Pubkey = NULL;
578ebfedea0SLionel Sambuc p_surewarehk_Free = NULL;
579ebfedea0SLionel Sambuc p_surewarehk_Rsa_Priv_Dec = NULL;
580ebfedea0SLionel Sambuc p_surewarehk_Rsa_Sign = NULL;
581ebfedea0SLionel Sambuc p_surewarehk_Dsa_Sign = NULL;
582ebfedea0SLionel Sambuc p_surewarehk_Info_Pubkey = NULL;
583ebfedea0SLionel Sambuc p_surewarehk_Load_Dsa_Pubkey = NULL;
584ebfedea0SLionel Sambuc p_surewarehk_Mod_Exp = NULL;
585ebfedea0SLionel Sambuc return 0;
586ebfedea0SLionel Sambuc }
587ebfedea0SLionel Sambuc
surewarehk_finish(ENGINE * e)588ebfedea0SLionel Sambuc static int surewarehk_finish(ENGINE *e)
589ebfedea0SLionel Sambuc {
590ebfedea0SLionel Sambuc int to_return = 1;
591*0a6a1f1dSLionel Sambuc if (surewarehk_dso == NULL) {
592ebfedea0SLionel Sambuc SUREWAREerr(SUREWARE_F_SUREWAREHK_FINISH, ENGINE_R_NOT_LOADED);
593ebfedea0SLionel Sambuc to_return = 0;
594ebfedea0SLionel Sambuc goto err;
595ebfedea0SLionel Sambuc }
596ebfedea0SLionel Sambuc p_surewarehk_Finish();
597*0a6a1f1dSLionel Sambuc if (!DSO_free(surewarehk_dso)) {
598ebfedea0SLionel Sambuc SUREWAREerr(SUREWARE_F_SUREWAREHK_FINISH, ENGINE_R_DSO_FAILURE);
599ebfedea0SLionel Sambuc to_return = 0;
600ebfedea0SLionel Sambuc goto err;
601ebfedea0SLionel Sambuc }
602ebfedea0SLionel Sambuc err:
603ebfedea0SLionel Sambuc if (logstream)
604ebfedea0SLionel Sambuc BIO_free(logstream);
605ebfedea0SLionel Sambuc surewarehk_dso = NULL;
606ebfedea0SLionel Sambuc p_surewarehk_Init = NULL;
607ebfedea0SLionel Sambuc p_surewarehk_Finish = NULL;
608ebfedea0SLionel Sambuc p_surewarehk_Rand_Bytes = NULL;
609ebfedea0SLionel Sambuc p_surewarehk_Rand_Seed = NULL;
610ebfedea0SLionel Sambuc p_surewarehk_Load_Privkey = NULL;
611ebfedea0SLionel Sambuc p_surewarehk_Load_Rsa_Pubkey = NULL;
612ebfedea0SLionel Sambuc p_surewarehk_Free = NULL;
613ebfedea0SLionel Sambuc p_surewarehk_Rsa_Priv_Dec = NULL;
614ebfedea0SLionel Sambuc p_surewarehk_Rsa_Sign = NULL;
615ebfedea0SLionel Sambuc p_surewarehk_Dsa_Sign = NULL;
616ebfedea0SLionel Sambuc p_surewarehk_Info_Pubkey = NULL;
617ebfedea0SLionel Sambuc p_surewarehk_Load_Dsa_Pubkey = NULL;
618ebfedea0SLionel Sambuc p_surewarehk_Mod_Exp = NULL;
619ebfedea0SLionel Sambuc return to_return;
620ebfedea0SLionel Sambuc }
621ebfedea0SLionel Sambuc
surewarehk_error_handling(char * const msg,int func,int ret)622ebfedea0SLionel Sambuc static void surewarehk_error_handling(char *const msg, int func, int ret)
623ebfedea0SLionel Sambuc {
624*0a6a1f1dSLionel Sambuc switch (ret) {
625ebfedea0SLionel Sambuc case SUREWAREHOOK_ERROR_UNIT_FAILURE:
626ebfedea0SLionel Sambuc ENGINEerr(func, SUREWARE_R_UNIT_FAILURE);
627ebfedea0SLionel Sambuc break;
628ebfedea0SLionel Sambuc case SUREWAREHOOK_ERROR_FALLBACK:
629ebfedea0SLionel Sambuc ENGINEerr(func, SUREWARE_R_REQUEST_FALLBACK);
630ebfedea0SLionel Sambuc break;
631ebfedea0SLionel Sambuc case SUREWAREHOOK_ERROR_DATA_SIZE:
632ebfedea0SLionel Sambuc ENGINEerr(func, SUREWARE_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
633ebfedea0SLionel Sambuc break;
634ebfedea0SLionel Sambuc case SUREWAREHOOK_ERROR_INVALID_PAD:
635ebfedea0SLionel Sambuc ENGINEerr(func, SUREWARE_R_PADDING_CHECK_FAILED);
636ebfedea0SLionel Sambuc break;
637ebfedea0SLionel Sambuc default:
638ebfedea0SLionel Sambuc ENGINEerr(func, SUREWARE_R_REQUEST_FAILED);
639ebfedea0SLionel Sambuc break;
640ebfedea0SLionel Sambuc case 1: /* nothing */
641ebfedea0SLionel Sambuc msg[0] = '\0';
642ebfedea0SLionel Sambuc }
643*0a6a1f1dSLionel Sambuc if (*msg) {
644ebfedea0SLionel Sambuc ERR_add_error_data(1, msg);
645*0a6a1f1dSLionel Sambuc if (logstream) {
646ebfedea0SLionel Sambuc CRYPTO_w_lock(CRYPTO_LOCK_BIO);
647ebfedea0SLionel Sambuc BIO_write(logstream, msg, strlen(msg));
648ebfedea0SLionel Sambuc CRYPTO_w_unlock(CRYPTO_LOCK_BIO);
649ebfedea0SLionel Sambuc }
650ebfedea0SLionel Sambuc }
651ebfedea0SLionel Sambuc }
652ebfedea0SLionel Sambuc
surewarehk_rand_bytes(unsigned char * buf,int num)653ebfedea0SLionel Sambuc static int surewarehk_rand_bytes(unsigned char *buf, int num)
654ebfedea0SLionel Sambuc {
655ebfedea0SLionel Sambuc int ret = 0;
656ebfedea0SLionel Sambuc char msg[64] = "ENGINE_rand_bytes";
657*0a6a1f1dSLionel Sambuc if (!p_surewarehk_Rand_Bytes) {
658*0a6a1f1dSLionel Sambuc SUREWAREerr(SUREWARE_F_SUREWAREHK_RAND_BYTES,
659*0a6a1f1dSLionel Sambuc ENGINE_R_NOT_INITIALISED);
660*0a6a1f1dSLionel Sambuc } else {
661ebfedea0SLionel Sambuc ret = p_surewarehk_Rand_Bytes(msg, buf, num);
662ebfedea0SLionel Sambuc surewarehk_error_handling(msg, SUREWARE_F_SUREWAREHK_RAND_BYTES, ret);
663ebfedea0SLionel Sambuc }
664ebfedea0SLionel Sambuc return ret == 1 ? 1 : 0;
665ebfedea0SLionel Sambuc }
666ebfedea0SLionel Sambuc
surewarehk_rand_seed(const void * buf,int num)667ebfedea0SLionel Sambuc static void surewarehk_rand_seed(const void *buf, int num)
668ebfedea0SLionel Sambuc {
669ebfedea0SLionel Sambuc int ret = 0;
670ebfedea0SLionel Sambuc char msg[64] = "ENGINE_rand_seed";
671*0a6a1f1dSLionel Sambuc if (!p_surewarehk_Rand_Seed) {
672*0a6a1f1dSLionel Sambuc SUREWAREerr(SUREWARE_F_SUREWAREHK_RAND_SEED,
673*0a6a1f1dSLionel Sambuc ENGINE_R_NOT_INITIALISED);
674*0a6a1f1dSLionel Sambuc } else {
675ebfedea0SLionel Sambuc ret = p_surewarehk_Rand_Seed(msg, buf, num);
676ebfedea0SLionel Sambuc surewarehk_error_handling(msg, SUREWARE_F_SUREWAREHK_RAND_SEED, ret);
677ebfedea0SLionel Sambuc }
678ebfedea0SLionel Sambuc }
679ebfedea0SLionel Sambuc
surewarehk_rand_add(const void * buf,int num,double entropy)680ebfedea0SLionel Sambuc static void surewarehk_rand_add(const void *buf, int num, double entropy)
681ebfedea0SLionel Sambuc {
682ebfedea0SLionel Sambuc surewarehk_rand_seed(buf, num);
683ebfedea0SLionel Sambuc }
684ebfedea0SLionel Sambuc
sureware_load_public(ENGINE * e,const char * key_id,char * hptr,unsigned long el,char keytype)685*0a6a1f1dSLionel Sambuc static EVP_PKEY *sureware_load_public(ENGINE *e, const char *key_id,
686*0a6a1f1dSLionel Sambuc char *hptr, unsigned long el,
687*0a6a1f1dSLionel Sambuc char keytype)
688ebfedea0SLionel Sambuc {
689ebfedea0SLionel Sambuc EVP_PKEY *res = NULL;
690ebfedea0SLionel Sambuc # ifndef OPENSSL_NO_RSA
691ebfedea0SLionel Sambuc RSA *rsatmp = NULL;
692ebfedea0SLionel Sambuc # endif
693ebfedea0SLionel Sambuc # ifndef OPENSSL_NO_DSA
694ebfedea0SLionel Sambuc DSA *dsatmp = NULL;
695ebfedea0SLionel Sambuc # endif
696ebfedea0SLionel Sambuc char msg[64] = "sureware_load_public";
697ebfedea0SLionel Sambuc int ret = 0;
698*0a6a1f1dSLionel Sambuc if (!p_surewarehk_Load_Rsa_Pubkey || !p_surewarehk_Load_Dsa_Pubkey) {
699*0a6a1f1dSLionel Sambuc SUREWAREerr(SUREWARE_F_SUREWARE_LOAD_PUBLIC,
700*0a6a1f1dSLionel Sambuc ENGINE_R_NOT_INITIALISED);
701ebfedea0SLionel Sambuc goto err;
702ebfedea0SLionel Sambuc }
703*0a6a1f1dSLionel Sambuc switch (keytype) {
704ebfedea0SLionel Sambuc # ifndef OPENSSL_NO_RSA
705*0a6a1f1dSLionel Sambuc case 1:
706*0a6a1f1dSLionel Sambuc /*RSA*/
707ebfedea0SLionel Sambuc /* set private external reference */
708ebfedea0SLionel Sambuc rsatmp = RSA_new_method(e);
709ebfedea0SLionel Sambuc RSA_set_ex_data(rsatmp, rsaHndidx, hptr);
710ebfedea0SLionel Sambuc rsatmp->flags |= RSA_FLAG_EXT_PKEY;
711ebfedea0SLionel Sambuc
712ebfedea0SLionel Sambuc /* set public big nums */
713ebfedea0SLionel Sambuc rsatmp->e = BN_new();
714ebfedea0SLionel Sambuc rsatmp->n = BN_new();
715*0a6a1f1dSLionel Sambuc if(!rsatmp->e || !rsatmp->n)
716*0a6a1f1dSLionel Sambuc goto err;
717ebfedea0SLionel Sambuc bn_expand2(rsatmp->e, el / sizeof(BN_ULONG));
718ebfedea0SLionel Sambuc bn_expand2(rsatmp->n, el / sizeof(BN_ULONG));
719*0a6a1f1dSLionel Sambuc if (rsatmp->e->dmax != (int)(el / sizeof(BN_ULONG)) ||
720*0a6a1f1dSLionel Sambuc rsatmp->n->dmax != (int)(el / sizeof(BN_ULONG)))
721ebfedea0SLionel Sambuc goto err;
722ebfedea0SLionel Sambuc ret = p_surewarehk_Load_Rsa_Pubkey(msg, key_id, el,
723ebfedea0SLionel Sambuc (unsigned long *)rsatmp->n->d,
724ebfedea0SLionel Sambuc (unsigned long *)rsatmp->e->d);
725ebfedea0SLionel Sambuc surewarehk_error_handling(msg, SUREWARE_F_SUREWARE_LOAD_PUBLIC, ret);
726*0a6a1f1dSLionel Sambuc if (ret != 1) {
727*0a6a1f1dSLionel Sambuc SUREWAREerr(SUREWARE_F_SUREWARE_LOAD_PUBLIC,
728*0a6a1f1dSLionel Sambuc ENGINE_R_FAILED_LOADING_PUBLIC_KEY);
729ebfedea0SLionel Sambuc goto err;
730ebfedea0SLionel Sambuc }
731ebfedea0SLionel Sambuc /* normalise pub e and pub n */
732ebfedea0SLionel Sambuc rsatmp->e->top = el / sizeof(BN_ULONG);
733ebfedea0SLionel Sambuc bn_fix_top(rsatmp->e);
734ebfedea0SLionel Sambuc rsatmp->n->top = el / sizeof(BN_ULONG);
735ebfedea0SLionel Sambuc bn_fix_top(rsatmp->n);
736ebfedea0SLionel Sambuc /* create an EVP object: engine + rsa key */
737ebfedea0SLionel Sambuc res = EVP_PKEY_new();
738ebfedea0SLionel Sambuc EVP_PKEY_assign_RSA(res, rsatmp);
739ebfedea0SLionel Sambuc break;
740ebfedea0SLionel Sambuc # endif
741ebfedea0SLionel Sambuc
742ebfedea0SLionel Sambuc # ifndef OPENSSL_NO_DSA
743*0a6a1f1dSLionel Sambuc case 2:
744*0a6a1f1dSLionel Sambuc /*DSA*/
745ebfedea0SLionel Sambuc /* set private/public external reference */
746ebfedea0SLionel Sambuc dsatmp = DSA_new_method(e);
747ebfedea0SLionel Sambuc DSA_set_ex_data(dsatmp, dsaHndidx, hptr);
748*0a6a1f1dSLionel Sambuc /*
749*0a6a1f1dSLionel Sambuc * dsatmp->flags |= DSA_FLAG_EXT_PKEY;
750*0a6a1f1dSLionel Sambuc */
751ebfedea0SLionel Sambuc
752ebfedea0SLionel Sambuc /* set public key */
753ebfedea0SLionel Sambuc dsatmp->pub_key = BN_new();
754ebfedea0SLionel Sambuc dsatmp->p = BN_new();
755ebfedea0SLionel Sambuc dsatmp->q = BN_new();
756ebfedea0SLionel Sambuc dsatmp->g = BN_new();
757*0a6a1f1dSLionel Sambuc if(!dsatmp->pub_key || !dsatmp->p || !dsatmp->q || !dsatmp->g)
758*0a6a1f1dSLionel Sambuc goto err;
759ebfedea0SLionel Sambuc bn_expand2(dsatmp->pub_key, el / sizeof(BN_ULONG));
760ebfedea0SLionel Sambuc bn_expand2(dsatmp->p, el / sizeof(BN_ULONG));
761ebfedea0SLionel Sambuc bn_expand2(dsatmp->q, 20 / sizeof(BN_ULONG));
762ebfedea0SLionel Sambuc bn_expand2(dsatmp->g, el / sizeof(BN_ULONG));
763*0a6a1f1dSLionel Sambuc if (dsatmp->pub_key->dmax != (int)(el / sizeof(BN_ULONG))
764*0a6a1f1dSLionel Sambuc || dsatmp->p->dmax != (int)(el / sizeof(BN_ULONG))
765*0a6a1f1dSLionel Sambuc || dsatmp->q->dmax != 20 / sizeof(BN_ULONG)
766*0a6a1f1dSLionel Sambuc || dsatmp->g->dmax != (int)(el / sizeof(BN_ULONG)))
767ebfedea0SLionel Sambuc goto err;
768ebfedea0SLionel Sambuc
769ebfedea0SLionel Sambuc ret = p_surewarehk_Load_Dsa_Pubkey(msg, key_id, el,
770*0a6a1f1dSLionel Sambuc (unsigned long *)dsatmp->
771*0a6a1f1dSLionel Sambuc pub_key->d,
772ebfedea0SLionel Sambuc (unsigned long *)dsatmp->p->d,
773ebfedea0SLionel Sambuc (unsigned long *)dsatmp->q->d,
774ebfedea0SLionel Sambuc (unsigned long *)dsatmp->g->d);
775ebfedea0SLionel Sambuc surewarehk_error_handling(msg, SUREWARE_F_SUREWARE_LOAD_PUBLIC, ret);
776*0a6a1f1dSLionel Sambuc if (ret != 1) {
777*0a6a1f1dSLionel Sambuc SUREWAREerr(SUREWARE_F_SUREWARE_LOAD_PUBLIC,
778*0a6a1f1dSLionel Sambuc ENGINE_R_FAILED_LOADING_PUBLIC_KEY);
779ebfedea0SLionel Sambuc goto err;
780ebfedea0SLionel Sambuc }
781ebfedea0SLionel Sambuc /* set parameters */
782ebfedea0SLionel Sambuc /* normalise pubkey and parameters in case of */
783ebfedea0SLionel Sambuc dsatmp->pub_key->top = el / sizeof(BN_ULONG);
784ebfedea0SLionel Sambuc bn_fix_top(dsatmp->pub_key);
785ebfedea0SLionel Sambuc dsatmp->p->top = el / sizeof(BN_ULONG);
786ebfedea0SLionel Sambuc bn_fix_top(dsatmp->p);
787ebfedea0SLionel Sambuc dsatmp->q->top = 20 / sizeof(BN_ULONG);
788ebfedea0SLionel Sambuc bn_fix_top(dsatmp->q);
789ebfedea0SLionel Sambuc dsatmp->g->top = el / sizeof(BN_ULONG);
790ebfedea0SLionel Sambuc bn_fix_top(dsatmp->g);
791ebfedea0SLionel Sambuc
792ebfedea0SLionel Sambuc /* create an EVP object: engine + rsa key */
793ebfedea0SLionel Sambuc res = EVP_PKEY_new();
794ebfedea0SLionel Sambuc EVP_PKEY_assign_DSA(res, dsatmp);
795ebfedea0SLionel Sambuc break;
796ebfedea0SLionel Sambuc # endif
797ebfedea0SLionel Sambuc
798ebfedea0SLionel Sambuc default:
799*0a6a1f1dSLionel Sambuc SUREWAREerr(SUREWARE_F_SUREWARE_LOAD_PUBLIC,
800*0a6a1f1dSLionel Sambuc ENGINE_R_FAILED_LOADING_PRIVATE_KEY);
801ebfedea0SLionel Sambuc goto err;
802ebfedea0SLionel Sambuc }
803ebfedea0SLionel Sambuc return res;
804ebfedea0SLionel Sambuc err:
805ebfedea0SLionel Sambuc # ifndef OPENSSL_NO_RSA
806ebfedea0SLionel Sambuc if (rsatmp)
807ebfedea0SLionel Sambuc RSA_free(rsatmp);
808ebfedea0SLionel Sambuc # endif
809ebfedea0SLionel Sambuc # ifndef OPENSSL_NO_DSA
810ebfedea0SLionel Sambuc if (dsatmp)
811ebfedea0SLionel Sambuc DSA_free(dsatmp);
812ebfedea0SLionel Sambuc # endif
813ebfedea0SLionel Sambuc return NULL;
814ebfedea0SLionel Sambuc }
815ebfedea0SLionel Sambuc
surewarehk_load_privkey(ENGINE * e,const char * key_id,UI_METHOD * ui_method,void * callback_data)816ebfedea0SLionel Sambuc static EVP_PKEY *surewarehk_load_privkey(ENGINE *e, const char *key_id,
817*0a6a1f1dSLionel Sambuc UI_METHOD *ui_method,
818*0a6a1f1dSLionel Sambuc void *callback_data)
819ebfedea0SLionel Sambuc {
820ebfedea0SLionel Sambuc EVP_PKEY *res = NULL;
821ebfedea0SLionel Sambuc int ret = 0;
822ebfedea0SLionel Sambuc unsigned long el = 0;
823ebfedea0SLionel Sambuc char *hptr = NULL;
824ebfedea0SLionel Sambuc char keytype = 0;
825ebfedea0SLionel Sambuc char msg[64] = "ENGINE_load_privkey";
826ebfedea0SLionel Sambuc
827*0a6a1f1dSLionel Sambuc if (!p_surewarehk_Load_Privkey) {
828*0a6a1f1dSLionel Sambuc SUREWAREerr(SUREWARE_F_SUREWAREHK_LOAD_PRIVKEY,
829*0a6a1f1dSLionel Sambuc ENGINE_R_NOT_INITIALISED);
830*0a6a1f1dSLionel Sambuc } else {
831ebfedea0SLionel Sambuc ret = p_surewarehk_Load_Privkey(msg, key_id, &hptr, &el, &keytype);
832*0a6a1f1dSLionel Sambuc if (ret != 1) {
833*0a6a1f1dSLionel Sambuc SUREWAREerr(SUREWARE_F_SUREWAREHK_LOAD_PRIVKEY,
834*0a6a1f1dSLionel Sambuc ENGINE_R_FAILED_LOADING_PRIVATE_KEY);
835ebfedea0SLionel Sambuc ERR_add_error_data(1, msg);
836*0a6a1f1dSLionel Sambuc } else
837ebfedea0SLionel Sambuc res = sureware_load_public(e, key_id, hptr, el, keytype);
838ebfedea0SLionel Sambuc }
839ebfedea0SLionel Sambuc return res;
840ebfedea0SLionel Sambuc }
841ebfedea0SLionel Sambuc
surewarehk_load_pubkey(ENGINE * e,const char * key_id,UI_METHOD * ui_method,void * callback_data)842ebfedea0SLionel Sambuc static EVP_PKEY *surewarehk_load_pubkey(ENGINE *e, const char *key_id,
843*0a6a1f1dSLionel Sambuc UI_METHOD *ui_method,
844*0a6a1f1dSLionel Sambuc void *callback_data)
845ebfedea0SLionel Sambuc {
846ebfedea0SLionel Sambuc EVP_PKEY *res = NULL;
847ebfedea0SLionel Sambuc int ret = 0;
848ebfedea0SLionel Sambuc unsigned long el = 0;
849ebfedea0SLionel Sambuc char *hptr = NULL;
850ebfedea0SLionel Sambuc char keytype = 0;
851ebfedea0SLionel Sambuc char msg[64] = "ENGINE_load_pubkey";
852ebfedea0SLionel Sambuc
853*0a6a1f1dSLionel Sambuc if (!p_surewarehk_Info_Pubkey) {
854*0a6a1f1dSLionel Sambuc SUREWAREerr(SUREWARE_F_SUREWAREHK_LOAD_PUBKEY,
855*0a6a1f1dSLionel Sambuc ENGINE_R_NOT_INITIALISED);
856*0a6a1f1dSLionel Sambuc } else {
857ebfedea0SLionel Sambuc /* call once to identify if DSA or RSA */
858ebfedea0SLionel Sambuc ret = p_surewarehk_Info_Pubkey(msg, key_id, &el, &keytype);
859*0a6a1f1dSLionel Sambuc if (ret != 1) {
860*0a6a1f1dSLionel Sambuc SUREWAREerr(SUREWARE_F_SUREWAREHK_LOAD_PUBKEY,
861*0a6a1f1dSLionel Sambuc ENGINE_R_FAILED_LOADING_PUBLIC_KEY);
862ebfedea0SLionel Sambuc ERR_add_error_data(1, msg);
863*0a6a1f1dSLionel Sambuc } else
864ebfedea0SLionel Sambuc res = sureware_load_public(e, key_id, hptr, el, keytype);
865ebfedea0SLionel Sambuc }
866ebfedea0SLionel Sambuc return res;
867ebfedea0SLionel Sambuc }
868ebfedea0SLionel Sambuc
869*0a6a1f1dSLionel Sambuc /*
870*0a6a1f1dSLionel Sambuc * This cleans up an RSA/DSA KM key(do not destroy the key into the hardware)
871*0a6a1f1dSLionel Sambuc * , called when ex_data is freed
872*0a6a1f1dSLionel Sambuc */
surewarehk_ex_free(void * obj,void * item,CRYPTO_EX_DATA * ad,int idx,long argl,void * argp)873ebfedea0SLionel Sambuc static void surewarehk_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad,
874ebfedea0SLionel Sambuc int idx, long argl, void *argp)
875ebfedea0SLionel Sambuc {
876*0a6a1f1dSLionel Sambuc if (!p_surewarehk_Free) {
877ebfedea0SLionel Sambuc SUREWAREerr(SUREWARE_F_SUREWAREHK_EX_FREE, ENGINE_R_NOT_INITIALISED);
878*0a6a1f1dSLionel Sambuc } else
879ebfedea0SLionel Sambuc p_surewarehk_Free((char *)item, 0);
880ebfedea0SLionel Sambuc }
881ebfedea0SLionel Sambuc
882ebfedea0SLionel Sambuc # if 0
883ebfedea0SLionel Sambuc /* not currently used (bug?) */
884*0a6a1f1dSLionel Sambuc /*
885*0a6a1f1dSLionel Sambuc * This cleans up an DH KM key (destroys the key into hardware), called when
886*0a6a1f1dSLionel Sambuc * ex_data is freed
887*0a6a1f1dSLionel Sambuc */
888ebfedea0SLionel Sambuc static void surewarehk_dh_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad,
889ebfedea0SLionel Sambuc int idx, long argl, void *argp)
890ebfedea0SLionel Sambuc {
891*0a6a1f1dSLionel Sambuc if (!p_surewarehk_Free) {
892*0a6a1f1dSLionel Sambuc SUREWAREerr(SUREWARE_F_SUREWAREHK_DH_EX_FREE,
893*0a6a1f1dSLionel Sambuc ENGINE_R_NOT_INITIALISED);
894*0a6a1f1dSLionel Sambuc } else
895ebfedea0SLionel Sambuc p_surewarehk_Free((char *)item, 1);
896ebfedea0SLionel Sambuc }
897ebfedea0SLionel Sambuc # endif
898ebfedea0SLionel Sambuc
899ebfedea0SLionel Sambuc /*
900ebfedea0SLionel Sambuc * return number of decrypted bytes
901ebfedea0SLionel Sambuc */
902ebfedea0SLionel Sambuc # ifndef OPENSSL_NO_RSA
surewarehk_rsa_priv_dec(int flen,const unsigned char * from,unsigned char * to,RSA * rsa,int padding)903*0a6a1f1dSLionel Sambuc static int surewarehk_rsa_priv_dec(int flen, const unsigned char *from,
904*0a6a1f1dSLionel Sambuc unsigned char *to, RSA *rsa, int padding)
905ebfedea0SLionel Sambuc {
906ebfedea0SLionel Sambuc int ret = 0, tlen;
907ebfedea0SLionel Sambuc char *buf = NULL, *hptr = NULL;
908ebfedea0SLionel Sambuc char msg[64] = "ENGINE_rsa_priv_dec";
909*0a6a1f1dSLionel Sambuc if (!p_surewarehk_Rsa_Priv_Dec) {
910*0a6a1f1dSLionel Sambuc SUREWAREerr(SUREWARE_F_SUREWAREHK_RSA_PRIV_DEC,
911*0a6a1f1dSLionel Sambuc ENGINE_R_NOT_INITIALISED);
912ebfedea0SLionel Sambuc }
913ebfedea0SLionel Sambuc /* extract ref to private key */
914*0a6a1f1dSLionel Sambuc else if (!(hptr = RSA_get_ex_data(rsa, rsaHndidx))) {
915*0a6a1f1dSLionel Sambuc SUREWAREerr(SUREWARE_F_SUREWAREHK_RSA_PRIV_DEC,
916*0a6a1f1dSLionel Sambuc SUREWARE_R_MISSING_KEY_COMPONENTS);
917ebfedea0SLionel Sambuc goto err;
918ebfedea0SLionel Sambuc }
919ebfedea0SLionel Sambuc /* analyse what padding we can do into the hardware */
920*0a6a1f1dSLionel Sambuc if (padding == RSA_PKCS1_PADDING) {
921ebfedea0SLionel Sambuc /* do it one shot */
922*0a6a1f1dSLionel Sambuc ret =
923*0a6a1f1dSLionel Sambuc p_surewarehk_Rsa_Priv_Dec(msg, flen, (unsigned char *)from, &tlen,
924*0a6a1f1dSLionel Sambuc to, hptr, SUREWARE_PKCS1_PAD);
925*0a6a1f1dSLionel Sambuc surewarehk_error_handling(msg, SUREWARE_F_SUREWAREHK_RSA_PRIV_DEC,
926*0a6a1f1dSLionel Sambuc ret);
927ebfedea0SLionel Sambuc if (ret != 1)
928ebfedea0SLionel Sambuc goto err;
929ebfedea0SLionel Sambuc ret = tlen;
930*0a6a1f1dSLionel Sambuc } else { /* do with no padding into hardware */
931*0a6a1f1dSLionel Sambuc
932*0a6a1f1dSLionel Sambuc ret =
933*0a6a1f1dSLionel Sambuc p_surewarehk_Rsa_Priv_Dec(msg, flen, (unsigned char *)from, &tlen,
934*0a6a1f1dSLionel Sambuc to, hptr, SUREWARE_NO_PAD);
935*0a6a1f1dSLionel Sambuc surewarehk_error_handling(msg, SUREWARE_F_SUREWAREHK_RSA_PRIV_DEC,
936*0a6a1f1dSLionel Sambuc ret);
937ebfedea0SLionel Sambuc if (ret != 1)
938ebfedea0SLionel Sambuc goto err;
939ebfedea0SLionel Sambuc /* intermediate buffer for padding */
940*0a6a1f1dSLionel Sambuc if ((buf = OPENSSL_malloc(tlen)) == NULL) {
941*0a6a1f1dSLionel Sambuc SUREWAREerr(SUREWARE_F_SUREWAREHK_RSA_PRIV_DEC,
942*0a6a1f1dSLionel Sambuc ERR_R_MALLOC_FAILURE);
943ebfedea0SLionel Sambuc goto err;
944ebfedea0SLionel Sambuc }
945ebfedea0SLionel Sambuc memcpy(buf, to, tlen); /* transfert to into buf */
946*0a6a1f1dSLionel Sambuc switch (padding) { /* check padding in software */
947ebfedea0SLionel Sambuc # ifndef OPENSSL_NO_SHA
948ebfedea0SLionel Sambuc case RSA_PKCS1_OAEP_PADDING:
949*0a6a1f1dSLionel Sambuc ret =
950*0a6a1f1dSLionel Sambuc RSA_padding_check_PKCS1_OAEP(to, tlen, (unsigned char *)buf,
951*0a6a1f1dSLionel Sambuc tlen, tlen, NULL, 0);
952ebfedea0SLionel Sambuc break;
953ebfedea0SLionel Sambuc # endif
954ebfedea0SLionel Sambuc case RSA_SSLV23_PADDING:
955*0a6a1f1dSLionel Sambuc ret =
956*0a6a1f1dSLionel Sambuc RSA_padding_check_SSLv23(to, tlen, (unsigned char *)buf, flen,
957*0a6a1f1dSLionel Sambuc tlen);
958ebfedea0SLionel Sambuc break;
959ebfedea0SLionel Sambuc case RSA_NO_PADDING:
960*0a6a1f1dSLionel Sambuc ret =
961*0a6a1f1dSLionel Sambuc RSA_padding_check_none(to, tlen, (unsigned char *)buf, flen,
962*0a6a1f1dSLionel Sambuc tlen);
963ebfedea0SLionel Sambuc break;
964ebfedea0SLionel Sambuc default:
965*0a6a1f1dSLionel Sambuc SUREWAREerr(SUREWARE_F_SUREWAREHK_RSA_PRIV_DEC,
966*0a6a1f1dSLionel Sambuc SUREWARE_R_UNKNOWN_PADDING_TYPE);
967ebfedea0SLionel Sambuc goto err;
968ebfedea0SLionel Sambuc }
969ebfedea0SLionel Sambuc if (ret < 0)
970*0a6a1f1dSLionel Sambuc SUREWAREerr(SUREWARE_F_SUREWAREHK_RSA_PRIV_DEC,
971*0a6a1f1dSLionel Sambuc SUREWARE_R_PADDING_CHECK_FAILED);
972ebfedea0SLionel Sambuc }
973ebfedea0SLionel Sambuc err:
974*0a6a1f1dSLionel Sambuc if (buf) {
975ebfedea0SLionel Sambuc OPENSSL_cleanse(buf, tlen);
976ebfedea0SLionel Sambuc OPENSSL_free(buf);
977ebfedea0SLionel Sambuc }
978ebfedea0SLionel Sambuc return ret;
979ebfedea0SLionel Sambuc }
980ebfedea0SLionel Sambuc
981ebfedea0SLionel Sambuc /*
982ebfedea0SLionel Sambuc * Does what OpenSSL rsa_priv_enc does.
983ebfedea0SLionel Sambuc */
surewarehk_rsa_sign(int flen,const unsigned char * from,unsigned char * to,RSA * rsa,int padding)984*0a6a1f1dSLionel Sambuc static int surewarehk_rsa_sign(int flen, const unsigned char *from,
985*0a6a1f1dSLionel Sambuc unsigned char *to, RSA *rsa, int padding)
986ebfedea0SLionel Sambuc {
987ebfedea0SLionel Sambuc int ret = 0, tlen;
988ebfedea0SLionel Sambuc char *hptr = NULL;
989ebfedea0SLionel Sambuc char msg[64] = "ENGINE_rsa_sign";
990*0a6a1f1dSLionel Sambuc if (!p_surewarehk_Rsa_Sign) {
991ebfedea0SLionel Sambuc SUREWAREerr(SUREWARE_F_SUREWAREHK_RSA_SIGN, ENGINE_R_NOT_INITIALISED);
992ebfedea0SLionel Sambuc }
993ebfedea0SLionel Sambuc /* extract ref to private key */
994*0a6a1f1dSLionel Sambuc else if (!(hptr = RSA_get_ex_data(rsa, rsaHndidx))) {
995*0a6a1f1dSLionel Sambuc SUREWAREerr(SUREWARE_F_SUREWAREHK_RSA_SIGN,
996*0a6a1f1dSLionel Sambuc SUREWARE_R_MISSING_KEY_COMPONENTS);
997*0a6a1f1dSLionel Sambuc } else {
998*0a6a1f1dSLionel Sambuc switch (padding) {
999ebfedea0SLionel Sambuc case RSA_PKCS1_PADDING: /* do it in one shot */
1000*0a6a1f1dSLionel Sambuc ret =
1001*0a6a1f1dSLionel Sambuc p_surewarehk_Rsa_Sign(msg, flen, (unsigned char *)from, &tlen,
1002*0a6a1f1dSLionel Sambuc to, hptr, SUREWARE_PKCS1_PAD);
1003*0a6a1f1dSLionel Sambuc surewarehk_error_handling(msg, SUREWARE_F_SUREWAREHK_RSA_SIGN,
1004*0a6a1f1dSLionel Sambuc ret);
1005ebfedea0SLionel Sambuc break;
1006ebfedea0SLionel Sambuc case RSA_NO_PADDING:
1007ebfedea0SLionel Sambuc default:
1008*0a6a1f1dSLionel Sambuc SUREWAREerr(SUREWARE_F_SUREWAREHK_RSA_SIGN,
1009*0a6a1f1dSLionel Sambuc SUREWARE_R_UNKNOWN_PADDING_TYPE);
1010ebfedea0SLionel Sambuc }
1011ebfedea0SLionel Sambuc }
1012ebfedea0SLionel Sambuc return ret == 1 ? tlen : ret;
1013ebfedea0SLionel Sambuc }
1014ebfedea0SLionel Sambuc
1015ebfedea0SLionel Sambuc # endif
1016ebfedea0SLionel Sambuc
1017ebfedea0SLionel Sambuc # ifndef OPENSSL_NO_DSA
1018ebfedea0SLionel Sambuc /* DSA sign and verify */
surewarehk_dsa_do_sign(const unsigned char * from,int flen,DSA * dsa)1019*0a6a1f1dSLionel Sambuc static DSA_SIG *surewarehk_dsa_do_sign(const unsigned char *from, int flen,
1020*0a6a1f1dSLionel Sambuc DSA *dsa)
1021ebfedea0SLionel Sambuc {
1022ebfedea0SLionel Sambuc int ret = 0;
1023ebfedea0SLionel Sambuc char *hptr = NULL;
1024ebfedea0SLionel Sambuc DSA_SIG *psign = NULL;
1025ebfedea0SLionel Sambuc char msg[64] = "ENGINE_dsa_do_sign";
1026*0a6a1f1dSLionel Sambuc if (!p_surewarehk_Dsa_Sign) {
1027*0a6a1f1dSLionel Sambuc SUREWAREerr(SUREWARE_F_SUREWAREHK_DSA_DO_SIGN,
1028*0a6a1f1dSLionel Sambuc ENGINE_R_NOT_INITIALISED);
1029ebfedea0SLionel Sambuc goto err;
1030ebfedea0SLionel Sambuc }
1031ebfedea0SLionel Sambuc /* extract ref to private key */
1032*0a6a1f1dSLionel Sambuc else if (!(hptr = DSA_get_ex_data(dsa, dsaHndidx))) {
1033*0a6a1f1dSLionel Sambuc SUREWAREerr(SUREWARE_F_SUREWAREHK_DSA_DO_SIGN,
1034*0a6a1f1dSLionel Sambuc SUREWARE_R_MISSING_KEY_COMPONENTS);
1035ebfedea0SLionel Sambuc goto err;
1036*0a6a1f1dSLionel Sambuc } else {
1037*0a6a1f1dSLionel Sambuc if ((psign = DSA_SIG_new()) == NULL) {
1038*0a6a1f1dSLionel Sambuc SUREWAREerr(SUREWARE_F_SUREWAREHK_DSA_DO_SIGN,
1039*0a6a1f1dSLionel Sambuc ERR_R_MALLOC_FAILURE);
1040ebfedea0SLionel Sambuc goto err;
1041ebfedea0SLionel Sambuc }
1042ebfedea0SLionel Sambuc psign->r = BN_new();
1043ebfedea0SLionel Sambuc psign->s = BN_new();
1044*0a6a1f1dSLionel Sambuc if(!psign->r || !psign->s)
1045*0a6a1f1dSLionel Sambuc goto err;
1046ebfedea0SLionel Sambuc bn_expand2(psign->r, 20 / sizeof(BN_ULONG));
1047ebfedea0SLionel Sambuc bn_expand2(psign->s, 20 / sizeof(BN_ULONG));
1048*0a6a1f1dSLionel Sambuc if (psign->r->dmax != 20 / sizeof(BN_ULONG) ||
1049*0a6a1f1dSLionel Sambuc psign->s->dmax != 20 / sizeof(BN_ULONG))
1050ebfedea0SLionel Sambuc goto err;
1051ebfedea0SLionel Sambuc ret = p_surewarehk_Dsa_Sign(msg, flen, from,
1052ebfedea0SLionel Sambuc (unsigned long *)psign->r->d,
1053*0a6a1f1dSLionel Sambuc (unsigned long *)psign->s->d, hptr);
1054*0a6a1f1dSLionel Sambuc surewarehk_error_handling(msg, SUREWARE_F_SUREWAREHK_DSA_DO_SIGN,
1055*0a6a1f1dSLionel Sambuc ret);
1056ebfedea0SLionel Sambuc }
1057ebfedea0SLionel Sambuc psign->r->top = 20 / sizeof(BN_ULONG);
1058ebfedea0SLionel Sambuc bn_fix_top(psign->r);
1059ebfedea0SLionel Sambuc psign->s->top = 20 / sizeof(BN_ULONG);
1060ebfedea0SLionel Sambuc bn_fix_top(psign->s);
1061ebfedea0SLionel Sambuc
1062ebfedea0SLionel Sambuc err:
1063*0a6a1f1dSLionel Sambuc if (psign) {
1064ebfedea0SLionel Sambuc DSA_SIG_free(psign);
1065ebfedea0SLionel Sambuc psign = NULL;
1066ebfedea0SLionel Sambuc }
1067ebfedea0SLionel Sambuc return psign;
1068ebfedea0SLionel Sambuc }
1069ebfedea0SLionel Sambuc # endif
1070ebfedea0SLionel Sambuc
surewarehk_modexp(BIGNUM * r,const BIGNUM * a,const BIGNUM * p,const BIGNUM * m,BN_CTX * ctx)1071ebfedea0SLionel Sambuc static int surewarehk_modexp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
1072ebfedea0SLionel Sambuc const BIGNUM *m, BN_CTX *ctx)
1073ebfedea0SLionel Sambuc {
1074ebfedea0SLionel Sambuc int ret = 0;
1075ebfedea0SLionel Sambuc char msg[64] = "ENGINE_modexp";
1076*0a6a1f1dSLionel Sambuc if (!p_surewarehk_Mod_Exp) {
1077ebfedea0SLionel Sambuc SUREWAREerr(SUREWARE_F_SUREWAREHK_MODEXP, ENGINE_R_NOT_INITIALISED);
1078*0a6a1f1dSLionel Sambuc } else if (r) {
1079ebfedea0SLionel Sambuc bn_expand2(r, m->top);
1080*0a6a1f1dSLionel Sambuc if (r->dmax == m->top) {
1081ebfedea0SLionel Sambuc /* do it */
1082ebfedea0SLionel Sambuc ret = p_surewarehk_Mod_Exp(msg,
1083ebfedea0SLionel Sambuc m->top * sizeof(BN_ULONG),
1084ebfedea0SLionel Sambuc (unsigned long *)m->d,
1085ebfedea0SLionel Sambuc p->top * sizeof(BN_ULONG),
1086ebfedea0SLionel Sambuc (unsigned long *)p->d,
1087ebfedea0SLionel Sambuc a->top * sizeof(BN_ULONG),
1088ebfedea0SLionel Sambuc (unsigned long *)a->d,
1089ebfedea0SLionel Sambuc (unsigned long *)r->d);
1090ebfedea0SLionel Sambuc surewarehk_error_handling(msg, SUREWARE_F_SUREWAREHK_MODEXP, ret);
1091*0a6a1f1dSLionel Sambuc if (ret == 1) {
1092ebfedea0SLionel Sambuc /* normalise result */
1093ebfedea0SLionel Sambuc r->top = m->top;
1094ebfedea0SLionel Sambuc bn_fix_top(r);
1095ebfedea0SLionel Sambuc }
1096ebfedea0SLionel Sambuc }
1097ebfedea0SLionel Sambuc }
1098ebfedea0SLionel Sambuc return ret;
1099ebfedea0SLionel Sambuc }
1100ebfedea0SLionel Sambuc # endif /* !OPENSSL_NO_HW_SureWare */
1101ebfedea0SLionel Sambuc #endif /* !OPENSSL_NO_HW */
1102