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