/src/openssl/engines/e_4758cca.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* Author: Maurice Gittens <maurice@gittens.nl> */ |
2 | | /* ==================================================================== |
3 | | * Copyright (c) 1999 The OpenSSL Project. All rights reserved. |
4 | | * |
5 | | * Redistribution and use in source and binary forms, with or without |
6 | | * modification, are permitted provided that the following conditions |
7 | | * are met: |
8 | | * |
9 | | * 1. Redistributions of source code must retain the above copyright |
10 | | * notice, this list of conditions and the following disclaimer. |
11 | | * |
12 | | * 2. Redistributions in binary form must reproduce the above copyright |
13 | | * notice, this list of conditions and the following disclaimer in |
14 | | * the documentation and/or other materials provided with the |
15 | | * distribution. |
16 | | * |
17 | | * 3. All advertising materials mentioning features or use of this |
18 | | * software must display the following acknowledgment: |
19 | | * "This product includes software developed by the OpenSSL Project |
20 | | * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" |
21 | | * |
22 | | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to |
23 | | * endorse or promote products derived from this software without |
24 | | * prior written permission. For written permission, please contact |
25 | | * licensing@OpenSSL.org. |
26 | | * |
27 | | * 5. Products derived from this software may not be called "OpenSSL" |
28 | | * nor may "OpenSSL" appear in their names without prior written |
29 | | * permission of the OpenSSL Project. |
30 | | * |
31 | | * 6. Redistributions of any form whatsoever must retain the following |
32 | | * acknowledgment: |
33 | | * "This product includes software developed by the OpenSSL Project |
34 | | * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" |
35 | | * |
36 | | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY |
37 | | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
38 | | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
39 | | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR |
40 | | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
41 | | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
42 | | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
43 | | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
44 | | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, |
45 | | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
46 | | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED |
47 | | * OF THE POSSIBILITY OF SUCH DAMAGE. |
48 | | * ==================================================================== |
49 | | * |
50 | | * This product includes cryptographic software written by Eric Young |
51 | | * (eay@cryptsoft.com). This product includes software written by Tim |
52 | | * Hudson (tjh@cryptsoft.com). |
53 | | * |
54 | | */ |
55 | | |
56 | | #include <stdio.h> |
57 | | #include <string.h> |
58 | | #include <openssl/crypto.h> |
59 | | #include <openssl/dso.h> |
60 | | #include <openssl/x509.h> |
61 | | #include <openssl/objects.h> |
62 | | #include <openssl/engine.h> |
63 | | #include <openssl/rand.h> |
64 | | #ifndef OPENSSL_NO_RSA |
65 | | # include <openssl/rsa.h> |
66 | | #endif |
67 | | #include <openssl/bn.h> |
68 | | |
69 | | #ifndef OPENSSL_NO_HW |
70 | | # ifndef OPENSSL_NO_HW_4758_CCA |
71 | | |
72 | | # ifdef FLAT_INC |
73 | | # include "hw_4758_cca.h" |
74 | | # else |
75 | | # include "vendor_defns/hw_4758_cca.h" |
76 | | # endif |
77 | | |
78 | | # include "e_4758cca_err.c" |
79 | | |
80 | | static int ibm_4758_cca_destroy(ENGINE *e); |
81 | | static int ibm_4758_cca_init(ENGINE *e); |
82 | | static int ibm_4758_cca_finish(ENGINE *e); |
83 | | static int ibm_4758_cca_ctrl(ENGINE *e, int cmd, long i, void *p, |
84 | | void (*f) (void)); |
85 | | |
86 | | /* rsa functions */ |
87 | | /* -------------*/ |
88 | | # ifndef OPENSSL_NO_RSA |
89 | | static int cca_rsa_pub_enc(int flen, const unsigned char *from, |
90 | | unsigned char *to, RSA *rsa, int padding); |
91 | | static int cca_rsa_priv_dec(int flen, const unsigned char *from, |
92 | | unsigned char *to, RSA *rsa, int padding); |
93 | | static int cca_rsa_sign(int type, const unsigned char *m, unsigned int m_len, |
94 | | unsigned char *sigret, unsigned int *siglen, |
95 | | const RSA *rsa); |
96 | | static int cca_rsa_verify(int dtype, const unsigned char *m, |
97 | | unsigned int m_len, const unsigned char *sigbuf, |
98 | | unsigned int siglen, const RSA *rsa); |
99 | | |
100 | | /* utility functions */ |
101 | | /* ---------------------*/ |
102 | | static EVP_PKEY *ibm_4758_load_privkey(ENGINE *, const char *, |
103 | | UI_METHOD *ui_method, |
104 | | void *callback_data); |
105 | | static EVP_PKEY *ibm_4758_load_pubkey(ENGINE *, const char *, |
106 | | UI_METHOD *ui_method, |
107 | | void *callback_data); |
108 | | |
109 | | static int getModulusAndExponent(const unsigned char *token, |
110 | | long *exponentLength, |
111 | | unsigned char *exponent, long *modulusLength, |
112 | | long *modulusFieldLength, |
113 | | unsigned char *modulus); |
114 | | # endif |
115 | | |
116 | | /* RAND number functions */ |
117 | | /* ---------------------*/ |
118 | | static int cca_get_random_bytes(unsigned char *, int); |
119 | | static int cca_random_status(void); |
120 | | |
121 | | # ifndef OPENSSL_NO_RSA |
122 | | static void cca_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad, |
123 | | int idx, long argl, void *argp); |
124 | | # endif |
125 | | |
126 | | /* Function pointers for CCA verbs */ |
127 | | /* -------------------------------*/ |
128 | | # ifndef OPENSSL_NO_RSA |
129 | | static F_KEYRECORDREAD keyRecordRead; |
130 | | static F_DIGITALSIGNATUREGENERATE digitalSignatureGenerate; |
131 | | static F_DIGITALSIGNATUREVERIFY digitalSignatureVerify; |
132 | | static F_PUBLICKEYEXTRACT publicKeyExtract; |
133 | | static F_PKAENCRYPT pkaEncrypt; |
134 | | static F_PKADECRYPT pkaDecrypt; |
135 | | # endif |
136 | | static F_RANDOMNUMBERGENERATE randomNumberGenerate; |
137 | | |
138 | | /* static variables */ |
139 | | /* ----------------*/ |
140 | | static const char *CCA4758_LIB_NAME = NULL; |
141 | | static const char *get_CCA4758_LIB_NAME(void) |
142 | 18 | { |
143 | 18 | if (CCA4758_LIB_NAME) |
144 | 0 | return CCA4758_LIB_NAME; |
145 | 18 | return CCA_LIB_NAME; |
146 | 18 | } |
147 | | |
148 | | static void free_CCA4758_LIB_NAME(void) |
149 | 0 | { |
150 | 0 | if (CCA4758_LIB_NAME) |
151 | 0 | OPENSSL_free((void *)CCA4758_LIB_NAME); |
152 | 0 | CCA4758_LIB_NAME = NULL; |
153 | 0 | } |
154 | | |
155 | | static long set_CCA4758_LIB_NAME(const char *name) |
156 | 0 | { |
157 | 0 | free_CCA4758_LIB_NAME(); |
158 | 0 | return (((CCA4758_LIB_NAME = BUF_strdup(name)) != NULL) ? 1 : 0); |
159 | 0 | } |
160 | | |
161 | | # ifndef OPENSSL_NO_RSA |
162 | | static const char *n_keyRecordRead = CSNDKRR; |
163 | | static const char *n_digitalSignatureGenerate = CSNDDSG; |
164 | | static const char *n_digitalSignatureVerify = CSNDDSV; |
165 | | static const char *n_publicKeyExtract = CSNDPKX; |
166 | | static const char *n_pkaEncrypt = CSNDPKE; |
167 | | static const char *n_pkaDecrypt = CSNDPKD; |
168 | | # endif |
169 | | static const char *n_randomNumberGenerate = CSNBRNG; |
170 | | |
171 | | # ifndef OPENSSL_NO_RSA |
172 | | static int hndidx = -1; |
173 | | # endif |
174 | | static DSO *dso = NULL; |
175 | | |
176 | | /* openssl engine initialization structures */ |
177 | | /* ----------------------------------------*/ |
178 | | |
179 | 0 | # define CCA4758_CMD_SO_PATH ENGINE_CMD_BASE |
180 | | static const ENGINE_CMD_DEFN cca4758_cmd_defns[] = { |
181 | | {CCA4758_CMD_SO_PATH, |
182 | | "SO_PATH", |
183 | | "Specifies the path to the '4758cca' shared library", |
184 | | ENGINE_CMD_FLAG_STRING}, |
185 | | {0, NULL, NULL, 0} |
186 | | }; |
187 | | |
188 | | # ifndef OPENSSL_NO_RSA |
189 | | static RSA_METHOD ibm_4758_cca_rsa = { |
190 | | "IBM 4758 CCA RSA method", |
191 | | cca_rsa_pub_enc, |
192 | | NULL, |
193 | | NULL, |
194 | | cca_rsa_priv_dec, |
195 | | NULL, /* rsa_mod_exp, */ |
196 | | NULL, /* mod_exp_mont, */ |
197 | | NULL, /* init */ |
198 | | NULL, /* finish */ |
199 | | RSA_FLAG_SIGN_VER, /* flags */ |
200 | | NULL, /* app_data */ |
201 | | cca_rsa_sign, /* rsa_sign */ |
202 | | cca_rsa_verify, /* rsa_verify */ |
203 | | NULL /* rsa_keygen */ |
204 | | }; |
205 | | # endif |
206 | | |
207 | | static RAND_METHOD ibm_4758_cca_rand = { |
208 | | /* "IBM 4758 RAND method", */ |
209 | | NULL, /* seed */ |
210 | | cca_get_random_bytes, /* get random bytes from the card */ |
211 | | NULL, /* cleanup */ |
212 | | NULL, /* add */ |
213 | | cca_get_random_bytes, /* pseudo rand */ |
214 | | cca_random_status, /* status */ |
215 | | }; |
216 | | |
217 | | static const char *engine_4758_cca_id = "4758cca"; |
218 | | static const char *engine_4758_cca_name = |
219 | | "IBM 4758 CCA hardware engine support"; |
220 | | # ifndef OPENSSL_NO_DYNAMIC_ENGINE |
221 | | /* Compatibility hack, the dynamic library uses this form in the path */ |
222 | | static const char *engine_4758_cca_id_alt = "4758_cca"; |
223 | | # endif |
224 | | |
225 | | /* engine implementation */ |
226 | | /* ---------------------*/ |
227 | | static int bind_helper(ENGINE *e) |
228 | 19 | { |
229 | 19 | if (!ENGINE_set_id(e, engine_4758_cca_id) || |
230 | 19 | !ENGINE_set_name(e, engine_4758_cca_name) || |
231 | 19 | # ifndef OPENSSL_NO_RSA |
232 | 19 | !ENGINE_set_RSA(e, &ibm_4758_cca_rsa) || |
233 | 19 | # endif |
234 | 19 | !ENGINE_set_RAND(e, &ibm_4758_cca_rand) || |
235 | 19 | !ENGINE_set_destroy_function(e, ibm_4758_cca_destroy) || |
236 | 19 | !ENGINE_set_init_function(e, ibm_4758_cca_init) || |
237 | 19 | !ENGINE_set_finish_function(e, ibm_4758_cca_finish) || |
238 | 19 | !ENGINE_set_ctrl_function(e, ibm_4758_cca_ctrl) || |
239 | 19 | # ifndef OPENSSL_NO_RSA |
240 | 19 | !ENGINE_set_load_privkey_function(e, ibm_4758_load_privkey) || |
241 | 19 | !ENGINE_set_load_pubkey_function(e, ibm_4758_load_pubkey) || |
242 | 19 | # endif |
243 | 19 | !ENGINE_set_cmd_defns(e, cca4758_cmd_defns)) |
244 | 0 | return 0; |
245 | | /* Ensure the error handling is set up */ |
246 | 19 | ERR_load_CCA4758_strings(); |
247 | 19 | return 1; |
248 | 19 | } |
249 | | |
250 | | # ifdef OPENSSL_NO_DYNAMIC_ENGINE |
251 | | static ENGINE *engine_4758_cca(void) |
252 | 19 | { |
253 | 19 | ENGINE *ret = ENGINE_new(); |
254 | 19 | if (!ret) |
255 | 0 | return NULL; |
256 | 19 | if (!bind_helper(ret)) { |
257 | 0 | ENGINE_free(ret); |
258 | 0 | return NULL; |
259 | 0 | } |
260 | 19 | return ret; |
261 | 19 | } |
262 | | |
263 | | void ENGINE_load_4758cca(void) |
264 | 19 | { |
265 | 19 | ENGINE *e_4758 = engine_4758_cca(); |
266 | 19 | if (!e_4758) |
267 | 0 | return; |
268 | 19 | ENGINE_add(e_4758); |
269 | 19 | ENGINE_free(e_4758); |
270 | 19 | ERR_clear_error(); |
271 | 19 | } |
272 | | # endif |
273 | | |
274 | | static int ibm_4758_cca_destroy(ENGINE *e) |
275 | 0 | { |
276 | 0 | ERR_unload_CCA4758_strings(); |
277 | 0 | free_CCA4758_LIB_NAME(); |
278 | 0 | return 1; |
279 | 0 | } |
280 | | |
281 | | static int ibm_4758_cca_init(ENGINE *e) |
282 | 18 | { |
283 | 18 | if (dso) { |
284 | 0 | CCA4758err(CCA4758_F_IBM_4758_CCA_INIT, CCA4758_R_ALREADY_LOADED); |
285 | 0 | goto err; |
286 | 0 | } |
287 | | |
288 | 18 | dso = DSO_load(NULL, get_CCA4758_LIB_NAME(), NULL, 0); |
289 | 18 | if (!dso) { |
290 | 18 | CCA4758err(CCA4758_F_IBM_4758_CCA_INIT, CCA4758_R_DSO_FAILURE); |
291 | 18 | goto err; |
292 | 18 | } |
293 | 0 | # ifndef OPENSSL_NO_RSA |
294 | 0 | if (!(keyRecordRead = (F_KEYRECORDREAD) |
295 | 0 | DSO_bind_func(dso, n_keyRecordRead)) || |
296 | 0 | !(randomNumberGenerate = (F_RANDOMNUMBERGENERATE) |
297 | 0 | DSO_bind_func(dso, n_randomNumberGenerate)) || |
298 | 0 | !(digitalSignatureGenerate = (F_DIGITALSIGNATUREGENERATE) |
299 | 0 | DSO_bind_func(dso, n_digitalSignatureGenerate)) || |
300 | 0 | !(digitalSignatureVerify = (F_DIGITALSIGNATUREVERIFY) |
301 | 0 | DSO_bind_func(dso, n_digitalSignatureVerify)) || |
302 | 0 | !(publicKeyExtract = (F_PUBLICKEYEXTRACT) |
303 | 0 | DSO_bind_func(dso, n_publicKeyExtract)) || |
304 | 0 | !(pkaEncrypt = (F_PKAENCRYPT) |
305 | 0 | DSO_bind_func(dso, n_pkaEncrypt)) || !(pkaDecrypt = (F_PKADECRYPT) |
306 | 0 | DSO_bind_func(dso, |
307 | 0 | n_pkaDecrypt))) |
308 | 0 | { |
309 | 0 | CCA4758err(CCA4758_F_IBM_4758_CCA_INIT, CCA4758_R_DSO_FAILURE); |
310 | 0 | goto err; |
311 | 0 | } |
312 | | # else |
313 | | if (!(randomNumberGenerate = (F_RANDOMNUMBERGENERATE) |
314 | | DSO_bind_func(dso, n_randomNumberGenerate))) { |
315 | | CCA4758err(CCA4758_F_IBM_4758_CCA_INIT, CCA4758_R_DSO_FAILURE); |
316 | | goto err; |
317 | | } |
318 | | # endif |
319 | | |
320 | 0 | # ifndef OPENSSL_NO_RSA |
321 | 0 | hndidx = RSA_get_ex_new_index(0, "IBM 4758 CCA RSA key handle", |
322 | 0 | NULL, NULL, cca_ex_free); |
323 | 0 | # endif |
324 | |
|
325 | 0 | return 1; |
326 | 18 | err: |
327 | 18 | if (dso) |
328 | 0 | DSO_free(dso); |
329 | 18 | dso = NULL; |
330 | | |
331 | 18 | # ifndef OPENSSL_NO_RSA |
332 | 18 | keyRecordRead = (F_KEYRECORDREAD) 0; |
333 | 18 | digitalSignatureGenerate = (F_DIGITALSIGNATUREGENERATE) 0; |
334 | 18 | digitalSignatureVerify = (F_DIGITALSIGNATUREVERIFY)0; |
335 | 18 | publicKeyExtract = (F_PUBLICKEYEXTRACT)0; |
336 | 18 | pkaEncrypt = (F_PKAENCRYPT) 0; |
337 | 18 | pkaDecrypt = (F_PKADECRYPT) 0; |
338 | 18 | # endif |
339 | 18 | randomNumberGenerate = (F_RANDOMNUMBERGENERATE) 0; |
340 | 18 | return 0; |
341 | 0 | } |
342 | | |
343 | | static int ibm_4758_cca_finish(ENGINE *e) |
344 | 0 | { |
345 | 0 | free_CCA4758_LIB_NAME(); |
346 | 0 | if (!dso) { |
347 | 0 | CCA4758err(CCA4758_F_IBM_4758_CCA_FINISH, CCA4758_R_NOT_LOADED); |
348 | 0 | return 0; |
349 | 0 | } |
350 | 0 | if (!DSO_free(dso)) { |
351 | 0 | CCA4758err(CCA4758_F_IBM_4758_CCA_FINISH, CCA4758_R_UNIT_FAILURE); |
352 | 0 | return 0; |
353 | 0 | } |
354 | 0 | dso = NULL; |
355 | 0 | # ifndef OPENSSL_NO_RSA |
356 | 0 | keyRecordRead = (F_KEYRECORDREAD) 0; |
357 | 0 | randomNumberGenerate = (F_RANDOMNUMBERGENERATE) 0; |
358 | 0 | digitalSignatureGenerate = (F_DIGITALSIGNATUREGENERATE) 0; |
359 | 0 | digitalSignatureVerify = (F_DIGITALSIGNATUREVERIFY)0; |
360 | 0 | publicKeyExtract = (F_PUBLICKEYEXTRACT)0; |
361 | 0 | pkaEncrypt = (F_PKAENCRYPT) 0; |
362 | 0 | pkaDecrypt = (F_PKADECRYPT) 0; |
363 | 0 | # endif |
364 | 0 | randomNumberGenerate = (F_RANDOMNUMBERGENERATE) 0; |
365 | 0 | return 1; |
366 | 0 | } |
367 | | |
368 | | static int ibm_4758_cca_ctrl(ENGINE *e, int cmd, long i, void *p, |
369 | | void (*f) (void)) |
370 | 0 | { |
371 | 0 | int initialised = ((dso == NULL) ? 0 : 1); |
372 | 0 | switch (cmd) { |
373 | 0 | case CCA4758_CMD_SO_PATH: |
374 | 0 | if (p == NULL) { |
375 | 0 | CCA4758err(CCA4758_F_IBM_4758_CCA_CTRL, |
376 | 0 | ERR_R_PASSED_NULL_PARAMETER); |
377 | 0 | return 0; |
378 | 0 | } |
379 | 0 | if (initialised) { |
380 | 0 | CCA4758err(CCA4758_F_IBM_4758_CCA_CTRL, CCA4758_R_ALREADY_LOADED); |
381 | 0 | return 0; |
382 | 0 | } |
383 | 0 | return set_CCA4758_LIB_NAME((const char *)p); |
384 | 0 | default: |
385 | 0 | break; |
386 | 0 | } |
387 | 0 | CCA4758err(CCA4758_F_IBM_4758_CCA_CTRL, |
388 | 0 | CCA4758_R_COMMAND_NOT_IMPLEMENTED); |
389 | 0 | return 0; |
390 | 0 | } |
391 | | |
392 | | # ifndef OPENSSL_NO_RSA |
393 | | |
394 | 0 | # define MAX_CCA_PKA_TOKEN_SIZE 2500 |
395 | | |
396 | | static EVP_PKEY *ibm_4758_load_privkey(ENGINE *e, const char *key_id, |
397 | | UI_METHOD *ui_method, |
398 | | void *callback_data) |
399 | 0 | { |
400 | 0 | RSA *rtmp = NULL; |
401 | 0 | EVP_PKEY *res = NULL; |
402 | 0 | unsigned char *keyToken = NULL; |
403 | 0 | unsigned char pubKeyToken[MAX_CCA_PKA_TOKEN_SIZE]; |
404 | 0 | long pubKeyTokenLength = MAX_CCA_PKA_TOKEN_SIZE; |
405 | 0 | long keyTokenLength = MAX_CCA_PKA_TOKEN_SIZE; |
406 | 0 | long returnCode; |
407 | 0 | long reasonCode; |
408 | 0 | long exitDataLength = 0; |
409 | 0 | long ruleArrayLength = 0; |
410 | 0 | unsigned char exitData[8]; |
411 | 0 | unsigned char ruleArray[8]; |
412 | 0 | unsigned char keyLabel[64]; |
413 | 0 | unsigned long keyLabelLength = strlen(key_id); |
414 | 0 | unsigned char modulus[256]; |
415 | 0 | long modulusFieldLength = sizeof(modulus); |
416 | 0 | long modulusLength = 0; |
417 | 0 | unsigned char exponent[256]; |
418 | 0 | long exponentLength = sizeof(exponent); |
419 | |
|
420 | 0 | if (keyLabelLength > sizeof(keyLabel)) { |
421 | 0 | CCA4758err(CCA4758_F_IBM_4758_LOAD_PRIVKEY, |
422 | 0 | CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL); |
423 | 0 | return NULL; |
424 | 0 | } |
425 | | |
426 | 0 | memset(keyLabel, ' ', sizeof(keyLabel)); |
427 | 0 | memcpy(keyLabel, key_id, keyLabelLength); |
428 | |
|
429 | 0 | keyToken = OPENSSL_malloc(MAX_CCA_PKA_TOKEN_SIZE + sizeof(long)); |
430 | 0 | if (!keyToken) { |
431 | 0 | CCA4758err(CCA4758_F_IBM_4758_LOAD_PRIVKEY, ERR_R_MALLOC_FAILURE); |
432 | 0 | goto err; |
433 | 0 | } |
434 | | |
435 | 0 | keyRecordRead(&returnCode, &reasonCode, &exitDataLength, |
436 | 0 | exitData, &ruleArrayLength, ruleArray, keyLabel, |
437 | 0 | &keyTokenLength, keyToken + sizeof(long)); |
438 | |
|
439 | 0 | if (returnCode) { |
440 | 0 | CCA4758err(CCA4758_F_IBM_4758_LOAD_PRIVKEY, |
441 | 0 | CCA4758_R_FAILED_LOADING_PRIVATE_KEY); |
442 | 0 | goto err; |
443 | 0 | } |
444 | | |
445 | 0 | publicKeyExtract(&returnCode, &reasonCode, &exitDataLength, |
446 | 0 | exitData, &ruleArrayLength, ruleArray, &keyTokenLength, |
447 | 0 | keyToken + sizeof(long), &pubKeyTokenLength, |
448 | 0 | pubKeyToken); |
449 | |
|
450 | 0 | if (returnCode) { |
451 | 0 | CCA4758err(CCA4758_F_IBM_4758_LOAD_PRIVKEY, |
452 | 0 | CCA4758_R_FAILED_LOADING_PRIVATE_KEY); |
453 | 0 | goto err; |
454 | 0 | } |
455 | | |
456 | 0 | if (!getModulusAndExponent(pubKeyToken, &exponentLength, |
457 | 0 | exponent, &modulusLength, &modulusFieldLength, |
458 | 0 | modulus)) { |
459 | 0 | CCA4758err(CCA4758_F_IBM_4758_LOAD_PRIVKEY, |
460 | 0 | CCA4758_R_FAILED_LOADING_PRIVATE_KEY); |
461 | 0 | goto err; |
462 | 0 | } |
463 | | |
464 | 0 | (*(long *)keyToken) = keyTokenLength; |
465 | 0 | rtmp = RSA_new_method(e); |
466 | 0 | if (rtmp == NULL) { |
467 | 0 | CCA4758err(CCA4758_F_IBM_4758_LOAD_PRIVKEY, ERR_R_MALLOC_FAILURE); |
468 | 0 | goto err; |
469 | 0 | } |
470 | 0 | RSA_set_ex_data(rtmp, hndidx, (char *)keyToken); |
471 | |
|
472 | 0 | rtmp->e = BN_bin2bn(exponent, exponentLength, NULL); |
473 | 0 | rtmp->n = BN_bin2bn(modulus, modulusFieldLength, NULL); |
474 | 0 | rtmp->flags |= RSA_FLAG_EXT_PKEY; |
475 | |
|
476 | 0 | res = EVP_PKEY_new(); |
477 | 0 | EVP_PKEY_assign_RSA(res, rtmp); |
478 | |
|
479 | 0 | return res; |
480 | 0 | err: |
481 | 0 | if (keyToken) |
482 | 0 | OPENSSL_free(keyToken); |
483 | 0 | return NULL; |
484 | 0 | } |
485 | | |
486 | | static EVP_PKEY *ibm_4758_load_pubkey(ENGINE *e, const char *key_id, |
487 | | UI_METHOD *ui_method, |
488 | | void *callback_data) |
489 | 0 | { |
490 | 0 | RSA *rtmp = NULL; |
491 | 0 | EVP_PKEY *res = NULL; |
492 | 0 | unsigned char *keyToken = NULL; |
493 | 0 | long keyTokenLength = MAX_CCA_PKA_TOKEN_SIZE; |
494 | 0 | long returnCode; |
495 | 0 | long reasonCode; |
496 | 0 | long exitDataLength = 0; |
497 | 0 | long ruleArrayLength = 0; |
498 | 0 | unsigned char exitData[8]; |
499 | 0 | unsigned char ruleArray[8]; |
500 | 0 | unsigned char keyLabel[64]; |
501 | 0 | unsigned long keyLabelLength = strlen(key_id); |
502 | 0 | unsigned char modulus[512]; |
503 | 0 | long modulusFieldLength = sizeof(modulus); |
504 | 0 | long modulusLength = 0; |
505 | 0 | unsigned char exponent[512]; |
506 | 0 | long exponentLength = sizeof(exponent); |
507 | |
|
508 | 0 | if (keyLabelLength > sizeof(keyLabel)) { |
509 | 0 | CCA4758err(CCA4758_F_IBM_4758_LOAD_PUBKEY, |
510 | 0 | CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL); |
511 | 0 | return NULL; |
512 | 0 | } |
513 | | |
514 | 0 | memset(keyLabel, ' ', sizeof(keyLabel)); |
515 | 0 | memcpy(keyLabel, key_id, keyLabelLength); |
516 | |
|
517 | 0 | keyToken = OPENSSL_malloc(MAX_CCA_PKA_TOKEN_SIZE + sizeof(long)); |
518 | 0 | if (!keyToken) { |
519 | 0 | CCA4758err(CCA4758_F_IBM_4758_LOAD_PUBKEY, ERR_R_MALLOC_FAILURE); |
520 | 0 | goto err; |
521 | 0 | } |
522 | | |
523 | 0 | keyRecordRead(&returnCode, &reasonCode, &exitDataLength, exitData, |
524 | 0 | &ruleArrayLength, ruleArray, keyLabel, &keyTokenLength, |
525 | 0 | keyToken + sizeof(long)); |
526 | |
|
527 | 0 | if (returnCode) { |
528 | 0 | CCA4758err(CCA4758_F_IBM_4758_LOAD_PUBKEY, ERR_R_MALLOC_FAILURE); |
529 | 0 | goto err; |
530 | 0 | } |
531 | | |
532 | 0 | if (!getModulusAndExponent(keyToken + sizeof(long), &exponentLength, |
533 | 0 | exponent, &modulusLength, &modulusFieldLength, |
534 | 0 | modulus)) { |
535 | 0 | CCA4758err(CCA4758_F_IBM_4758_LOAD_PUBKEY, |
536 | 0 | CCA4758_R_FAILED_LOADING_PUBLIC_KEY); |
537 | 0 | goto err; |
538 | 0 | } |
539 | | |
540 | 0 | (*(long *)keyToken) = keyTokenLength; |
541 | 0 | rtmp = RSA_new_method(e); |
542 | 0 | if (rtmp == NULL) { |
543 | 0 | CCA4758err(CCA4758_F_IBM_4758_LOAD_PUBKEY, ERR_R_MALLOC_FAILURE); |
544 | 0 | goto err; |
545 | 0 | } |
546 | 0 | RSA_set_ex_data(rtmp, hndidx, (char *)keyToken); |
547 | 0 | rtmp->e = BN_bin2bn(exponent, exponentLength, NULL); |
548 | 0 | rtmp->n = BN_bin2bn(modulus, modulusFieldLength, NULL); |
549 | 0 | rtmp->flags |= RSA_FLAG_EXT_PKEY; |
550 | 0 | res = EVP_PKEY_new(); |
551 | 0 | EVP_PKEY_assign_RSA(res, rtmp); |
552 | |
|
553 | 0 | return res; |
554 | 0 | err: |
555 | 0 | if (keyToken) |
556 | 0 | OPENSSL_free(keyToken); |
557 | 0 | return NULL; |
558 | 0 | } |
559 | | |
560 | | static int cca_rsa_pub_enc(int flen, const unsigned char *from, |
561 | | unsigned char *to, RSA *rsa, int padding) |
562 | 0 | { |
563 | 0 | long returnCode; |
564 | 0 | long reasonCode; |
565 | 0 | long lflen = flen; |
566 | 0 | long exitDataLength = 0; |
567 | 0 | unsigned char exitData[8]; |
568 | 0 | long ruleArrayLength = 1; |
569 | 0 | unsigned char ruleArray[8] = "PKCS-1.2"; |
570 | 0 | long dataStructureLength = 0; |
571 | 0 | unsigned char dataStructure[8]; |
572 | 0 | long outputLength = RSA_size(rsa); |
573 | 0 | long keyTokenLength; |
574 | 0 | unsigned char *keyToken = (unsigned char *)RSA_get_ex_data(rsa, hndidx); |
575 | |
|
576 | 0 | keyTokenLength = *(long *)keyToken; |
577 | 0 | keyToken += sizeof(long); |
578 | |
|
579 | 0 | pkaEncrypt(&returnCode, &reasonCode, &exitDataLength, exitData, |
580 | 0 | &ruleArrayLength, ruleArray, &lflen, (unsigned char *)from, |
581 | 0 | &dataStructureLength, dataStructure, &keyTokenLength, |
582 | 0 | keyToken, &outputLength, to); |
583 | |
|
584 | 0 | if (returnCode || reasonCode) |
585 | 0 | return -(returnCode << 16 | reasonCode); |
586 | 0 | return outputLength; |
587 | 0 | } |
588 | | |
589 | | static int cca_rsa_priv_dec(int flen, const unsigned char *from, |
590 | | unsigned char *to, RSA *rsa, int padding) |
591 | 0 | { |
592 | 0 | long returnCode; |
593 | 0 | long reasonCode; |
594 | 0 | long lflen = flen; |
595 | 0 | long exitDataLength = 0; |
596 | 0 | unsigned char exitData[8]; |
597 | 0 | long ruleArrayLength = 1; |
598 | 0 | unsigned char ruleArray[8] = "PKCS-1.2"; |
599 | 0 | long dataStructureLength = 0; |
600 | 0 | unsigned char dataStructure[8]; |
601 | 0 | long outputLength = RSA_size(rsa); |
602 | 0 | long keyTokenLength; |
603 | 0 | unsigned char *keyToken = (unsigned char *)RSA_get_ex_data(rsa, hndidx); |
604 | |
|
605 | 0 | keyTokenLength = *(long *)keyToken; |
606 | 0 | keyToken += sizeof(long); |
607 | |
|
608 | 0 | pkaDecrypt(&returnCode, &reasonCode, &exitDataLength, exitData, |
609 | 0 | &ruleArrayLength, ruleArray, &lflen, (unsigned char *)from, |
610 | 0 | &dataStructureLength, dataStructure, &keyTokenLength, |
611 | 0 | keyToken, &outputLength, to); |
612 | |
|
613 | 0 | return (returnCode | reasonCode) ? 0 : 1; |
614 | 0 | } |
615 | | |
616 | 0 | # define SSL_SIG_LEN 36 |
617 | | |
618 | | static int cca_rsa_verify(int type, const unsigned char *m, |
619 | | unsigned int m_len, const unsigned char *sigbuf, |
620 | | unsigned int siglen, const RSA *rsa) |
621 | 0 | { |
622 | 0 | long returnCode; |
623 | 0 | long reasonCode; |
624 | 0 | long lsiglen = siglen; |
625 | 0 | long exitDataLength = 0; |
626 | 0 | unsigned char exitData[8]; |
627 | 0 | long ruleArrayLength = 1; |
628 | 0 | unsigned char ruleArray[8] = "PKCS-1.1"; |
629 | 0 | long keyTokenLength; |
630 | 0 | unsigned char *keyToken = (unsigned char *)RSA_get_ex_data(rsa, hndidx); |
631 | 0 | long length = SSL_SIG_LEN; |
632 | 0 | long keyLength; |
633 | 0 | unsigned char *hashBuffer = NULL; |
634 | 0 | X509_SIG sig; |
635 | 0 | ASN1_TYPE parameter; |
636 | 0 | X509_ALGOR algorithm; |
637 | 0 | ASN1_OCTET_STRING digest; |
638 | |
|
639 | 0 | keyTokenLength = *(long *)keyToken; |
640 | 0 | keyToken += sizeof(long); |
641 | |
|
642 | 0 | if (type == NID_md5 || type == NID_sha1) { |
643 | 0 | sig.algor = &algorithm; |
644 | 0 | algorithm.algorithm = OBJ_nid2obj(type); |
645 | |
|
646 | 0 | if (!algorithm.algorithm) { |
647 | 0 | CCA4758err(CCA4758_F_CCA_RSA_VERIFY, |
648 | 0 | CCA4758_R_UNKNOWN_ALGORITHM_TYPE); |
649 | 0 | return 0; |
650 | 0 | } |
651 | | |
652 | 0 | if (!algorithm.algorithm->length) { |
653 | 0 | CCA4758err(CCA4758_F_CCA_RSA_VERIFY, |
654 | 0 | CCA4758_R_ASN1_OID_UNKNOWN_FOR_MD); |
655 | 0 | return 0; |
656 | 0 | } |
657 | | |
658 | 0 | parameter.type = V_ASN1_NULL; |
659 | 0 | parameter.value.ptr = NULL; |
660 | 0 | algorithm.parameter = ¶meter; |
661 | |
|
662 | 0 | sig.digest = &digest; |
663 | 0 | sig.digest->data = (unsigned char *)m; |
664 | 0 | sig.digest->length = m_len; |
665 | |
|
666 | 0 | length = i2d_X509_SIG(&sig, NULL); |
667 | 0 | } |
668 | | |
669 | 0 | keyLength = RSA_size(rsa); |
670 | |
|
671 | 0 | if (length - RSA_PKCS1_PADDING > keyLength) { |
672 | 0 | CCA4758err(CCA4758_F_CCA_RSA_VERIFY, |
673 | 0 | CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL); |
674 | 0 | return 0; |
675 | 0 | } |
676 | | |
677 | 0 | switch (type) { |
678 | 0 | case NID_md5_sha1: |
679 | 0 | if (m_len != SSL_SIG_LEN) { |
680 | 0 | CCA4758err(CCA4758_F_CCA_RSA_VERIFY, |
681 | 0 | CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL); |
682 | 0 | return 0; |
683 | 0 | } |
684 | | |
685 | 0 | hashBuffer = (unsigned char *)m; |
686 | 0 | length = m_len; |
687 | 0 | break; |
688 | 0 | case NID_md5: |
689 | 0 | { |
690 | 0 | unsigned char *ptr; |
691 | 0 | ptr = hashBuffer = OPENSSL_malloc((unsigned int)keyLength + 1); |
692 | 0 | if (!hashBuffer) { |
693 | 0 | CCA4758err(CCA4758_F_CCA_RSA_VERIFY, ERR_R_MALLOC_FAILURE); |
694 | 0 | return 0; |
695 | 0 | } |
696 | | |
697 | 0 | i2d_X509_SIG(&sig, &ptr); |
698 | 0 | } |
699 | 0 | break; |
700 | 0 | case NID_sha1: |
701 | 0 | { |
702 | 0 | unsigned char *ptr; |
703 | 0 | ptr = hashBuffer = OPENSSL_malloc((unsigned int)keyLength + 1); |
704 | 0 | if (!hashBuffer) { |
705 | 0 | CCA4758err(CCA4758_F_CCA_RSA_VERIFY, ERR_R_MALLOC_FAILURE); |
706 | 0 | return 0; |
707 | 0 | } |
708 | 0 | i2d_X509_SIG(&sig, &ptr); |
709 | 0 | } |
710 | 0 | break; |
711 | 0 | default: |
712 | 0 | return 0; |
713 | 0 | } |
714 | | |
715 | 0 | digitalSignatureVerify(&returnCode, &reasonCode, &exitDataLength, |
716 | 0 | exitData, &ruleArrayLength, ruleArray, |
717 | 0 | &keyTokenLength, keyToken, &length, hashBuffer, |
718 | 0 | &lsiglen, (unsigned char *)sigbuf); |
719 | |
|
720 | 0 | if (type == NID_sha1 || type == NID_md5) { |
721 | 0 | OPENSSL_cleanse(hashBuffer, keyLength + 1); |
722 | 0 | OPENSSL_free(hashBuffer); |
723 | 0 | } |
724 | |
|
725 | 0 | return ((returnCode || reasonCode) ? 0 : 1); |
726 | 0 | } |
727 | | |
728 | 0 | # define SSL_SIG_LEN 36 |
729 | | |
730 | | static int cca_rsa_sign(int type, const unsigned char *m, unsigned int m_len, |
731 | | unsigned char *sigret, unsigned int *siglen, |
732 | | const RSA *rsa) |
733 | 0 | { |
734 | 0 | long returnCode; |
735 | 0 | long reasonCode; |
736 | 0 | long exitDataLength = 0; |
737 | 0 | unsigned char exitData[8]; |
738 | 0 | long ruleArrayLength = 1; |
739 | 0 | unsigned char ruleArray[8] = "PKCS-1.1"; |
740 | 0 | long outputLength = 256; |
741 | 0 | long outputBitLength; |
742 | 0 | long keyTokenLength; |
743 | 0 | unsigned char *hashBuffer = NULL; |
744 | 0 | unsigned char *keyToken = (unsigned char *)RSA_get_ex_data(rsa, hndidx); |
745 | 0 | long length = SSL_SIG_LEN; |
746 | 0 | long keyLength; |
747 | 0 | X509_SIG sig; |
748 | 0 | ASN1_TYPE parameter; |
749 | 0 | X509_ALGOR algorithm; |
750 | 0 | ASN1_OCTET_STRING digest; |
751 | |
|
752 | 0 | keyTokenLength = *(long *)keyToken; |
753 | 0 | keyToken += sizeof(long); |
754 | |
|
755 | 0 | if (type == NID_md5 || type == NID_sha1) { |
756 | 0 | sig.algor = &algorithm; |
757 | 0 | algorithm.algorithm = OBJ_nid2obj(type); |
758 | |
|
759 | 0 | if (!algorithm.algorithm) { |
760 | 0 | CCA4758err(CCA4758_F_CCA_RSA_SIGN, |
761 | 0 | CCA4758_R_UNKNOWN_ALGORITHM_TYPE); |
762 | 0 | return 0; |
763 | 0 | } |
764 | | |
765 | 0 | if (!algorithm.algorithm->length) { |
766 | 0 | CCA4758err(CCA4758_F_CCA_RSA_SIGN, |
767 | 0 | CCA4758_R_ASN1_OID_UNKNOWN_FOR_MD); |
768 | 0 | return 0; |
769 | 0 | } |
770 | | |
771 | 0 | parameter.type = V_ASN1_NULL; |
772 | 0 | parameter.value.ptr = NULL; |
773 | 0 | algorithm.parameter = ¶meter; |
774 | |
|
775 | 0 | sig.digest = &digest; |
776 | 0 | sig.digest->data = (unsigned char *)m; |
777 | 0 | sig.digest->length = m_len; |
778 | |
|
779 | 0 | length = i2d_X509_SIG(&sig, NULL); |
780 | 0 | } |
781 | | |
782 | 0 | keyLength = RSA_size(rsa); |
783 | |
|
784 | 0 | if (length - RSA_PKCS1_PADDING > keyLength) { |
785 | 0 | CCA4758err(CCA4758_F_CCA_RSA_SIGN, |
786 | 0 | CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL); |
787 | 0 | return 0; |
788 | 0 | } |
789 | | |
790 | 0 | switch (type) { |
791 | 0 | case NID_md5_sha1: |
792 | 0 | if (m_len != SSL_SIG_LEN) { |
793 | 0 | CCA4758err(CCA4758_F_CCA_RSA_SIGN, |
794 | 0 | CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL); |
795 | 0 | return 0; |
796 | 0 | } |
797 | 0 | hashBuffer = (unsigned char *)m; |
798 | 0 | length = m_len; |
799 | 0 | break; |
800 | 0 | case NID_md5: |
801 | 0 | { |
802 | 0 | unsigned char *ptr; |
803 | 0 | ptr = hashBuffer = OPENSSL_malloc((unsigned int)keyLength + 1); |
804 | 0 | if (!hashBuffer) { |
805 | 0 | CCA4758err(CCA4758_F_CCA_RSA_SIGN, ERR_R_MALLOC_FAILURE); |
806 | 0 | return 0; |
807 | 0 | } |
808 | 0 | i2d_X509_SIG(&sig, &ptr); |
809 | 0 | } |
810 | 0 | break; |
811 | 0 | case NID_sha1: |
812 | 0 | { |
813 | 0 | unsigned char *ptr; |
814 | 0 | ptr = hashBuffer = OPENSSL_malloc((unsigned int)keyLength + 1); |
815 | 0 | if (!hashBuffer) { |
816 | 0 | CCA4758err(CCA4758_F_CCA_RSA_SIGN, ERR_R_MALLOC_FAILURE); |
817 | 0 | return 0; |
818 | 0 | } |
819 | 0 | i2d_X509_SIG(&sig, &ptr); |
820 | 0 | } |
821 | 0 | break; |
822 | 0 | default: |
823 | 0 | return 0; |
824 | 0 | } |
825 | | |
826 | 0 | digitalSignatureGenerate(&returnCode, &reasonCode, &exitDataLength, |
827 | 0 | exitData, &ruleArrayLength, ruleArray, |
828 | 0 | &keyTokenLength, keyToken, &length, hashBuffer, |
829 | 0 | &outputLength, &outputBitLength, sigret); |
830 | |
|
831 | 0 | if (type == NID_sha1 || type == NID_md5) { |
832 | 0 | OPENSSL_cleanse(hashBuffer, keyLength + 1); |
833 | 0 | OPENSSL_free(hashBuffer); |
834 | 0 | } |
835 | |
|
836 | 0 | *siglen = outputLength; |
837 | |
|
838 | 0 | return ((returnCode || reasonCode) ? 0 : 1); |
839 | 0 | } |
840 | | |
841 | | static int getModulusAndExponent(const unsigned char *token, |
842 | | long *exponentLength, |
843 | | unsigned char *exponent, long *modulusLength, |
844 | | long *modulusFieldLength, |
845 | | unsigned char *modulus) |
846 | 0 | { |
847 | 0 | unsigned long len; |
848 | |
|
849 | 0 | if (*token++ != (char)0x1E) /* internal PKA token? */ |
850 | 0 | return 0; |
851 | | |
852 | 0 | if (*token++) /* token version must be zero */ |
853 | 0 | return 0; |
854 | | |
855 | 0 | len = *token++; |
856 | 0 | len = len << 8; |
857 | 0 | len |= (unsigned char)*token++; |
858 | |
|
859 | 0 | token += 4; /* skip reserved bytes */ |
860 | |
|
861 | 0 | if (*token++ == (char)0x04) { |
862 | 0 | if (*token++) /* token version must be zero */ |
863 | 0 | return 0; |
864 | | |
865 | 0 | len = *token++; |
866 | 0 | len = len << 8; |
867 | 0 | len |= (unsigned char)*token++; |
868 | |
|
869 | 0 | token += 2; /* skip reserved section */ |
870 | |
|
871 | 0 | len = *token++; |
872 | 0 | len = len << 8; |
873 | 0 | len |= (unsigned char)*token++; |
874 | |
|
875 | 0 | *exponentLength = len; |
876 | |
|
877 | 0 | len = *token++; |
878 | 0 | len = len << 8; |
879 | 0 | len |= (unsigned char)*token++; |
880 | |
|
881 | 0 | *modulusLength = len; |
882 | |
|
883 | 0 | len = *token++; |
884 | 0 | len = len << 8; |
885 | 0 | len |= (unsigned char)*token++; |
886 | |
|
887 | 0 | *modulusFieldLength = len; |
888 | |
|
889 | 0 | memcpy(exponent, token, *exponentLength); |
890 | 0 | token += *exponentLength; |
891 | |
|
892 | 0 | memcpy(modulus, token, *modulusFieldLength); |
893 | 0 | return 1; |
894 | 0 | } |
895 | 0 | return 0; |
896 | 0 | } |
897 | | |
898 | | # endif /* OPENSSL_NO_RSA */ |
899 | | |
900 | | static int cca_random_status(void) |
901 | 0 | { |
902 | 0 | return 1; |
903 | 0 | } |
904 | | |
905 | | static int cca_get_random_bytes(unsigned char *buf, int num) |
906 | 0 | { |
907 | 0 | long ret_code; |
908 | 0 | long reason_code; |
909 | 0 | long exit_data_length; |
910 | 0 | unsigned char exit_data[4]; |
911 | 0 | unsigned char form[] = "RANDOM "; |
912 | 0 | unsigned char rand_buf[8]; |
913 | |
|
914 | 0 | while (num >= (int)sizeof(rand_buf)) { |
915 | 0 | randomNumberGenerate(&ret_code, &reason_code, &exit_data_length, |
916 | 0 | exit_data, form, rand_buf); |
917 | 0 | if (ret_code) |
918 | 0 | return 0; |
919 | 0 | num -= sizeof(rand_buf); |
920 | 0 | memcpy(buf, rand_buf, sizeof(rand_buf)); |
921 | 0 | buf += sizeof(rand_buf); |
922 | 0 | } |
923 | | |
924 | 0 | if (num) { |
925 | 0 | randomNumberGenerate(&ret_code, &reason_code, NULL, NULL, |
926 | 0 | form, rand_buf); |
927 | 0 | if (ret_code) |
928 | 0 | return 0; |
929 | 0 | memcpy(buf, rand_buf, num); |
930 | 0 | } |
931 | | |
932 | 0 | return 1; |
933 | 0 | } |
934 | | |
935 | | # ifndef OPENSSL_NO_RSA |
936 | | static void cca_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad, int idx, |
937 | | long argl, void *argp) |
938 | 0 | { |
939 | 0 | if (item) |
940 | 0 | OPENSSL_free(item); |
941 | 0 | } |
942 | | # endif |
943 | | |
944 | | /* Goo to handle building as a dynamic engine */ |
945 | | # ifndef OPENSSL_NO_DYNAMIC_ENGINE |
946 | | static int bind_fn(ENGINE *e, const char *id) |
947 | | { |
948 | | if (id && (strcmp(id, engine_4758_cca_id) != 0) && |
949 | | (strcmp(id, engine_4758_cca_id_alt) != 0)) |
950 | | return 0; |
951 | | if (!bind_helper(e)) |
952 | | return 0; |
953 | | return 1; |
954 | | } |
955 | | |
956 | | IMPLEMENT_DYNAMIC_CHECK_FN() |
957 | | IMPLEMENT_DYNAMIC_BIND_FN(bind_fn) |
958 | | # endif /* OPENSSL_NO_DYNAMIC_ENGINE */ |
959 | | # endif /* !OPENSSL_NO_HW_4758_CCA */ |
960 | | #endif /* !OPENSSL_NO_HW */ |