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