xref: /minix3/crypto/external/bsd/openssl/dist/engines/e_sureware.c (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
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