MFC: Make apps using '#define _POSIX_C_SOURCE' compile.
[dragonfly.git] / crypto / openssl-0.9 / engines / e_4758cca.c
blob0f1dae7567a5393b0563029a44e1891368fcdfce
1 /* Author: Maurice Gittens <maurice@gittens.nl> */
2 /* ====================================================================
3 * Copyright (c) 1999 The OpenSSL Project. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
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.
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/)"
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.
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.
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/)"
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 * ====================================================================
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).
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>
69 #ifndef OPENSSL_NO_HW
70 #ifndef OPENSSL_NO_HW_4758_CCA
72 #ifdef FLAT_INC
73 #include "hw_4758_cca.h"
74 #else
75 #include "vendor_defns/hw_4758_cca.h"
76 #endif
78 #include "e_4758cca_err.c"
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, void (*f)(void));
85 /* rsa functions */
86 /*---------------*/
87 #ifndef OPENSSL_NO_RSA
88 static int cca_rsa_pub_enc(int flen, const unsigned char *from,
89 unsigned char *to, RSA *rsa,int padding);
90 static int cca_rsa_priv_dec(int flen, const unsigned char *from,
91 unsigned char *to, RSA *rsa,int padding);
92 static int cca_rsa_sign(int type, const unsigned char *m, unsigned int m_len,
93 unsigned char *sigret, unsigned int *siglen, const RSA *rsa);
94 static int cca_rsa_verify(int dtype, const unsigned char *m, unsigned int m_len,
95 unsigned char *sigbuf, unsigned int siglen, const RSA *rsa);
97 /* utility functions */
98 /*-----------------------*/
99 static EVP_PKEY *ibm_4758_load_privkey(ENGINE*, const char*,
100 UI_METHOD *ui_method, void *callback_data);
101 static EVP_PKEY *ibm_4758_load_pubkey(ENGINE*, const char*,
102 UI_METHOD *ui_method, void *callback_data);
104 static int getModulusAndExponent(const unsigned char *token, long *exponentLength,
105 unsigned char *exponent, long *modulusLength,
106 long *modulusFieldLength, unsigned char *modulus);
107 #endif
109 /* RAND number functions */
110 /*-----------------------*/
111 static int cca_get_random_bytes(unsigned char*, int );
112 static int cca_random_status(void);
114 #ifndef OPENSSL_NO_RSA
115 static void cca_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad,
116 int idx,long argl, void *argp);
117 #endif
119 /* Function pointers for CCA verbs */
120 /*---------------------------------*/
121 #ifndef OPENSSL_NO_RSA
122 static F_KEYRECORDREAD keyRecordRead;
123 static F_DIGITALSIGNATUREGENERATE digitalSignatureGenerate;
124 static F_DIGITALSIGNATUREVERIFY digitalSignatureVerify;
125 static F_PUBLICKEYEXTRACT publicKeyExtract;
126 static F_PKAENCRYPT pkaEncrypt;
127 static F_PKADECRYPT pkaDecrypt;
128 #endif
129 static F_RANDOMNUMBERGENERATE randomNumberGenerate;
131 /* static variables */
132 /*------------------*/
133 static const char *CCA4758_LIB_NAME = NULL;
134 static const char *get_CCA4758_LIB_NAME(void)
136 if(CCA4758_LIB_NAME)
137 return CCA4758_LIB_NAME;
138 return CCA_LIB_NAME;
140 static void free_CCA4758_LIB_NAME(void)
142 if(CCA4758_LIB_NAME)
143 OPENSSL_free((void*)CCA4758_LIB_NAME);
144 CCA4758_LIB_NAME = NULL;
146 static long set_CCA4758_LIB_NAME(const char *name)
148 free_CCA4758_LIB_NAME();
149 return (((CCA4758_LIB_NAME = BUF_strdup(name)) != NULL) ? 1 : 0);
151 #ifndef OPENSSL_NO_RSA
152 static const char* n_keyRecordRead = CSNDKRR;
153 static const char* n_digitalSignatureGenerate = CSNDDSG;
154 static const char* n_digitalSignatureVerify = CSNDDSV;
155 static const char* n_publicKeyExtract = CSNDPKX;
156 static const char* n_pkaEncrypt = CSNDPKE;
157 static const char* n_pkaDecrypt = CSNDPKD;
158 #endif
159 static const char* n_randomNumberGenerate = CSNBRNG;
161 #ifndef OPENSSL_NO_RSA
162 static int hndidx = -1;
163 #endif
164 static DSO *dso = NULL;
166 /* openssl engine initialization structures */
167 /*------------------------------------------*/
169 #define CCA4758_CMD_SO_PATH ENGINE_CMD_BASE
170 static const ENGINE_CMD_DEFN cca4758_cmd_defns[] = {
171 {CCA4758_CMD_SO_PATH,
172 "SO_PATH",
173 "Specifies the path to the '4758cca' shared library",
174 ENGINE_CMD_FLAG_STRING},
175 {0, NULL, NULL, 0}
178 #ifndef OPENSSL_NO_RSA
179 static RSA_METHOD ibm_4758_cca_rsa =
181 "IBM 4758 CCA RSA method",
182 cca_rsa_pub_enc,
183 NULL,
184 NULL,
185 cca_rsa_priv_dec,
186 NULL, /*rsa_mod_exp,*/
187 NULL, /*mod_exp_mont,*/
188 NULL, /* init */
189 NULL, /* finish */
190 RSA_FLAG_SIGN_VER, /* flags */
191 NULL, /* app_data */
192 cca_rsa_sign, /* rsa_sign */
193 cca_rsa_verify, /* rsa_verify */
194 NULL /* rsa_keygen */
196 #endif
198 static RAND_METHOD ibm_4758_cca_rand =
200 /* "IBM 4758 RAND method", */
201 NULL, /* seed */
202 cca_get_random_bytes, /* get random bytes from the card */
203 NULL, /* cleanup */
204 NULL, /* add */
205 cca_get_random_bytes, /* pseudo rand */
206 cca_random_status, /* status */
209 static const char *engine_4758_cca_id = "4758cca";
210 static const char *engine_4758_cca_name = "IBM 4758 CCA hardware engine support";
211 #ifndef OPENSSL_NO_DYNAMIC_ENGINE
212 /* Compatibility hack, the dynamic library uses this form in the path */
213 static const char *engine_4758_cca_id_alt = "4758_cca";
214 #endif
216 /* engine implementation */
217 /*-----------------------*/
218 static int bind_helper(ENGINE *e)
220 if(!ENGINE_set_id(e, engine_4758_cca_id) ||
221 !ENGINE_set_name(e, engine_4758_cca_name) ||
222 #ifndef OPENSSL_NO_RSA
223 !ENGINE_set_RSA(e, &ibm_4758_cca_rsa) ||
224 #endif
225 !ENGINE_set_RAND(e, &ibm_4758_cca_rand) ||
226 !ENGINE_set_destroy_function(e, ibm_4758_cca_destroy) ||
227 !ENGINE_set_init_function(e, ibm_4758_cca_init) ||
228 !ENGINE_set_finish_function(e, ibm_4758_cca_finish) ||
229 !ENGINE_set_ctrl_function(e, ibm_4758_cca_ctrl) ||
230 #ifndef OPENSSL_NO_RSA
231 !ENGINE_set_load_privkey_function(e, ibm_4758_load_privkey) ||
232 !ENGINE_set_load_pubkey_function(e, ibm_4758_load_pubkey) ||
233 #endif
234 !ENGINE_set_cmd_defns(e, cca4758_cmd_defns))
235 return 0;
236 /* Ensure the error handling is set up */
237 ERR_load_CCA4758_strings();
238 return 1;
241 #ifdef OPENSSL_NO_DYNAMIC_ENGINE
242 static ENGINE *engine_4758_cca(void)
244 ENGINE *ret = ENGINE_new();
245 if(!ret)
246 return NULL;
247 if(!bind_helper(ret))
249 ENGINE_free(ret);
250 return NULL;
252 return ret;
255 void ENGINE_load_4758cca(void)
257 ENGINE *e_4758 = engine_4758_cca();
258 if (!e_4758) return;
259 ENGINE_add(e_4758);
260 ENGINE_free(e_4758);
261 ERR_clear_error();
263 #endif
265 static int ibm_4758_cca_destroy(ENGINE *e)
267 ERR_unload_CCA4758_strings();
268 free_CCA4758_LIB_NAME();
269 return 1;
272 static int ibm_4758_cca_init(ENGINE *e)
274 if(dso)
276 CCA4758err(CCA4758_F_IBM_4758_CCA_INIT,CCA4758_R_ALREADY_LOADED);
277 goto err;
280 dso = DSO_load(NULL, get_CCA4758_LIB_NAME(), NULL, 0);
281 if(!dso)
283 CCA4758err(CCA4758_F_IBM_4758_CCA_INIT,CCA4758_R_DSO_FAILURE);
284 goto err;
287 #ifndef OPENSSL_NO_RSA
288 if(!(keyRecordRead = (F_KEYRECORDREAD)
289 DSO_bind_func(dso, n_keyRecordRead)) ||
290 !(randomNumberGenerate = (F_RANDOMNUMBERGENERATE)
291 DSO_bind_func(dso, n_randomNumberGenerate)) ||
292 !(digitalSignatureGenerate = (F_DIGITALSIGNATUREGENERATE)
293 DSO_bind_func(dso, n_digitalSignatureGenerate)) ||
294 !(digitalSignatureVerify = (F_DIGITALSIGNATUREVERIFY)
295 DSO_bind_func(dso, n_digitalSignatureVerify)) ||
296 !(publicKeyExtract = (F_PUBLICKEYEXTRACT)
297 DSO_bind_func(dso, n_publicKeyExtract)) ||
298 !(pkaEncrypt = (F_PKAENCRYPT)
299 DSO_bind_func(dso, n_pkaEncrypt)) ||
300 !(pkaDecrypt = (F_PKADECRYPT)
301 DSO_bind_func(dso, n_pkaDecrypt)))
303 CCA4758err(CCA4758_F_IBM_4758_CCA_INIT,CCA4758_R_DSO_FAILURE);
304 goto err;
306 #else
307 if(!(randomNumberGenerate = (F_RANDOMNUMBERGENERATE)
308 DSO_bind_func(dso, n_randomNumberGenerate)))
310 CCA4758err(CCA4758_F_IBM_4758_CCA_INIT,CCA4758_R_DSO_FAILURE);
311 goto err;
313 #endif
315 #ifndef OPENSSL_NO_RSA
316 hndidx = RSA_get_ex_new_index(0, "IBM 4758 CCA RSA key handle",
317 NULL, NULL, cca_ex_free);
318 #endif
320 return 1;
321 err:
322 if(dso)
323 DSO_free(dso);
324 dso = NULL;
326 #ifndef OPENSSL_NO_RSA
327 keyRecordRead = (F_KEYRECORDREAD)0;
328 digitalSignatureGenerate = (F_DIGITALSIGNATUREGENERATE)0;
329 digitalSignatureVerify = (F_DIGITALSIGNATUREVERIFY)0;
330 publicKeyExtract = (F_PUBLICKEYEXTRACT)0;
331 pkaEncrypt = (F_PKAENCRYPT)0;
332 pkaDecrypt = (F_PKADECRYPT)0;
333 #endif
334 randomNumberGenerate = (F_RANDOMNUMBERGENERATE)0;
335 return 0;
338 static int ibm_4758_cca_finish(ENGINE *e)
340 free_CCA4758_LIB_NAME();
341 if(!dso)
343 CCA4758err(CCA4758_F_IBM_4758_CCA_FINISH,
344 CCA4758_R_NOT_LOADED);
345 return 0;
347 if(!DSO_free(dso))
349 CCA4758err(CCA4758_F_IBM_4758_CCA_FINISH,
350 CCA4758_R_UNIT_FAILURE);
351 return 0;
353 dso = NULL;
354 #ifndef OPENSSL_NO_RSA
355 keyRecordRead = (F_KEYRECORDREAD)0;
356 randomNumberGenerate = (F_RANDOMNUMBERGENERATE)0;
357 digitalSignatureGenerate = (F_DIGITALSIGNATUREGENERATE)0;
358 digitalSignatureVerify = (F_DIGITALSIGNATUREVERIFY)0;
359 publicKeyExtract = (F_PUBLICKEYEXTRACT)0;
360 pkaEncrypt = (F_PKAENCRYPT)0;
361 pkaDecrypt = (F_PKADECRYPT)0;
362 #endif
363 randomNumberGenerate = (F_RANDOMNUMBERGENERATE)0;
364 return 1;
367 static int ibm_4758_cca_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void))
369 int initialised = ((dso == NULL) ? 0 : 1);
370 switch(cmd)
372 case CCA4758_CMD_SO_PATH:
373 if(p == NULL)
375 CCA4758err(CCA4758_F_IBM_4758_CCA_CTRL,
376 ERR_R_PASSED_NULL_PARAMETER);
377 return 0;
379 if(initialised)
381 CCA4758err(CCA4758_F_IBM_4758_CCA_CTRL,
382 CCA4758_R_ALREADY_LOADED);
383 return 0;
385 return set_CCA4758_LIB_NAME((const char *)p);
386 default:
387 break;
389 CCA4758err(CCA4758_F_IBM_4758_CCA_CTRL,
390 CCA4758_R_COMMAND_NOT_IMPLEMENTED);
391 return 0;
394 #ifndef OPENSSL_NO_RSA
396 #define MAX_CCA_PKA_TOKEN_SIZE 2500
398 static EVP_PKEY *ibm_4758_load_privkey(ENGINE* e, const char* key_id,
399 UI_METHOD *ui_method, void *callback_data)
401 RSA *rtmp = NULL;
402 EVP_PKEY *res = NULL;
403 unsigned char* keyToken = NULL;
404 unsigned char pubKeyToken[MAX_CCA_PKA_TOKEN_SIZE];
405 long pubKeyTokenLength = MAX_CCA_PKA_TOKEN_SIZE;
406 long keyTokenLength = MAX_CCA_PKA_TOKEN_SIZE;
407 long returnCode;
408 long reasonCode;
409 long exitDataLength = 0;
410 long ruleArrayLength = 0;
411 unsigned char exitData[8];
412 unsigned char ruleArray[8];
413 unsigned char keyLabel[64];
414 unsigned long keyLabelLength = strlen(key_id);
415 unsigned char modulus[256];
416 long modulusFieldLength = sizeof(modulus);
417 long modulusLength = 0;
418 unsigned char exponent[256];
419 long exponentLength = sizeof(exponent);
421 if (keyLabelLength > sizeof(keyLabel))
423 CCA4758err(CCA4758_F_IBM_4758_LOAD_PRIVKEY,
424 CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
425 return NULL;
428 memset(keyLabel,' ', sizeof(keyLabel));
429 memcpy(keyLabel, key_id, keyLabelLength);
431 keyToken = OPENSSL_malloc(MAX_CCA_PKA_TOKEN_SIZE + sizeof(long));
432 if (!keyToken)
434 CCA4758err(CCA4758_F_IBM_4758_LOAD_PRIVKEY,
435 ERR_R_MALLOC_FAILURE);
436 goto err;
439 keyRecordRead(&returnCode, &reasonCode, &exitDataLength,
440 exitData, &ruleArrayLength, ruleArray, keyLabel,
441 &keyTokenLength, keyToken+sizeof(long));
443 if (returnCode)
445 CCA4758err(CCA4758_F_IBM_4758_LOAD_PRIVKEY,
446 CCA4758_R_FAILED_LOADING_PRIVATE_KEY);
447 goto err;
450 publicKeyExtract(&returnCode, &reasonCode, &exitDataLength,
451 exitData, &ruleArrayLength, ruleArray, &keyTokenLength,
452 keyToken+sizeof(long), &pubKeyTokenLength, pubKeyToken);
454 if (returnCode)
456 CCA4758err(CCA4758_F_IBM_4758_LOAD_PRIVKEY,
457 CCA4758_R_FAILED_LOADING_PRIVATE_KEY);
458 goto err;
461 if (!getModulusAndExponent(pubKeyToken, &exponentLength,
462 exponent, &modulusLength, &modulusFieldLength,
463 modulus))
465 CCA4758err(CCA4758_F_IBM_4758_LOAD_PRIVKEY,
466 CCA4758_R_FAILED_LOADING_PRIVATE_KEY);
467 goto err;
470 (*(long*)keyToken) = keyTokenLength;
471 rtmp = RSA_new_method(e);
472 RSA_set_ex_data(rtmp, hndidx, (char *)keyToken);
474 rtmp->e = BN_bin2bn(exponent, exponentLength, NULL);
475 rtmp->n = BN_bin2bn(modulus, modulusFieldLength, NULL);
476 rtmp->flags |= RSA_FLAG_EXT_PKEY;
478 res = EVP_PKEY_new();
479 EVP_PKEY_assign_RSA(res, rtmp);
481 return res;
482 err:
483 if (keyToken)
484 OPENSSL_free(keyToken);
485 if (res)
486 EVP_PKEY_free(res);
487 if (rtmp)
488 RSA_free(rtmp);
489 return NULL;
492 static EVP_PKEY *ibm_4758_load_pubkey(ENGINE* e, const char* key_id,
493 UI_METHOD *ui_method, void *callback_data)
495 RSA *rtmp = NULL;
496 EVP_PKEY *res = NULL;
497 unsigned char* keyToken = NULL;
498 long keyTokenLength = MAX_CCA_PKA_TOKEN_SIZE;
499 long returnCode;
500 long reasonCode;
501 long exitDataLength = 0;
502 long ruleArrayLength = 0;
503 unsigned char exitData[8];
504 unsigned char ruleArray[8];
505 unsigned char keyLabel[64];
506 unsigned long keyLabelLength = strlen(key_id);
507 unsigned char modulus[512];
508 long modulusFieldLength = sizeof(modulus);
509 long modulusLength = 0;
510 unsigned char exponent[512];
511 long exponentLength = sizeof(exponent);
513 if (keyLabelLength > sizeof(keyLabel))
515 CCA4758err(CCA4758_F_IBM_4758_LOAD_PUBKEY,
516 CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
517 return NULL;
520 memset(keyLabel,' ', sizeof(keyLabel));
521 memcpy(keyLabel, key_id, keyLabelLength);
523 keyToken = OPENSSL_malloc(MAX_CCA_PKA_TOKEN_SIZE + sizeof(long));
524 if (!keyToken)
526 CCA4758err(CCA4758_F_IBM_4758_LOAD_PUBKEY,
527 ERR_R_MALLOC_FAILURE);
528 goto err;
531 keyRecordRead(&returnCode, &reasonCode, &exitDataLength, exitData,
532 &ruleArrayLength, ruleArray, keyLabel, &keyTokenLength,
533 keyToken+sizeof(long));
535 if (returnCode)
537 CCA4758err(CCA4758_F_IBM_4758_LOAD_PUBKEY,
538 ERR_R_MALLOC_FAILURE);
539 goto err;
542 if (!getModulusAndExponent(keyToken+sizeof(long), &exponentLength,
543 exponent, &modulusLength, &modulusFieldLength, modulus))
545 CCA4758err(CCA4758_F_IBM_4758_LOAD_PUBKEY,
546 CCA4758_R_FAILED_LOADING_PUBLIC_KEY);
547 goto err;
550 (*(long*)keyToken) = keyTokenLength;
551 rtmp = RSA_new_method(e);
552 RSA_set_ex_data(rtmp, hndidx, (char *)keyToken);
553 rtmp->e = BN_bin2bn(exponent, exponentLength, NULL);
554 rtmp->n = BN_bin2bn(modulus, modulusFieldLength, NULL);
555 rtmp->flags |= RSA_FLAG_EXT_PKEY;
556 res = EVP_PKEY_new();
557 EVP_PKEY_assign_RSA(res, rtmp);
559 return res;
560 err:
561 if (keyToken)
562 OPENSSL_free(keyToken);
563 if (res)
564 EVP_PKEY_free(res);
565 if (rtmp)
566 RSA_free(rtmp);
567 return NULL;
570 static int cca_rsa_pub_enc(int flen, const unsigned char *from,
571 unsigned char *to, RSA *rsa,int padding)
573 long returnCode;
574 long reasonCode;
575 long lflen = flen;
576 long exitDataLength = 0;
577 unsigned char exitData[8];
578 long ruleArrayLength = 1;
579 unsigned char ruleArray[8] = "PKCS-1.2";
580 long dataStructureLength = 0;
581 unsigned char dataStructure[8];
582 long outputLength = RSA_size(rsa);
583 long keyTokenLength;
584 unsigned char* keyToken = (unsigned char*)RSA_get_ex_data(rsa, hndidx);
586 keyTokenLength = *(long*)keyToken;
587 keyToken+=sizeof(long);
589 pkaEncrypt(&returnCode, &reasonCode, &exitDataLength, exitData,
590 &ruleArrayLength, ruleArray, &lflen, (unsigned char*)from,
591 &dataStructureLength, dataStructure, &keyTokenLength,
592 keyToken, &outputLength, to);
594 if (returnCode || reasonCode)
595 return -(returnCode << 16 | reasonCode);
596 return outputLength;
599 static int cca_rsa_priv_dec(int flen, const unsigned char *from,
600 unsigned char *to, RSA *rsa,int padding)
602 long returnCode;
603 long reasonCode;
604 long lflen = flen;
605 long exitDataLength = 0;
606 unsigned char exitData[8];
607 long ruleArrayLength = 1;
608 unsigned char ruleArray[8] = "PKCS-1.2";
609 long dataStructureLength = 0;
610 unsigned char dataStructure[8];
611 long outputLength = RSA_size(rsa);
612 long keyTokenLength;
613 unsigned char* keyToken = (unsigned char*)RSA_get_ex_data(rsa, hndidx);
615 keyTokenLength = *(long*)keyToken;
616 keyToken+=sizeof(long);
618 pkaDecrypt(&returnCode, &reasonCode, &exitDataLength, exitData,
619 &ruleArrayLength, ruleArray, &lflen, (unsigned char*)from,
620 &dataStructureLength, dataStructure, &keyTokenLength,
621 keyToken, &outputLength, to);
623 return (returnCode | reasonCode) ? 0 : 1;
626 #define SSL_SIG_LEN 36
628 static int cca_rsa_verify(int type, const unsigned char *m, unsigned int m_len,
629 unsigned char *sigbuf, unsigned int siglen, const RSA *rsa)
631 long returnCode;
632 long reasonCode;
633 long lsiglen = siglen;
634 long exitDataLength = 0;
635 unsigned char exitData[8];
636 long ruleArrayLength = 1;
637 unsigned char ruleArray[8] = "PKCS-1.1";
638 long keyTokenLength;
639 unsigned char* keyToken = (unsigned char*)RSA_get_ex_data(rsa, hndidx);
640 long length = SSL_SIG_LEN;
641 long keyLength ;
642 unsigned char *hashBuffer = NULL;
643 X509_SIG sig;
644 ASN1_TYPE parameter;
645 X509_ALGOR algorithm;
646 ASN1_OCTET_STRING digest;
648 keyTokenLength = *(long*)keyToken;
649 keyToken+=sizeof(long);
651 if (type == NID_md5 || type == NID_sha1)
653 sig.algor = &algorithm;
654 algorithm.algorithm = OBJ_nid2obj(type);
656 if (!algorithm.algorithm)
658 CCA4758err(CCA4758_F_CCA_RSA_VERIFY,
659 CCA4758_R_UNKNOWN_ALGORITHM_TYPE);
660 return 0;
663 if (!algorithm.algorithm->length)
665 CCA4758err(CCA4758_F_CCA_RSA_VERIFY,
666 CCA4758_R_ASN1_OID_UNKNOWN_FOR_MD);
667 return 0;
670 parameter.type = V_ASN1_NULL;
671 parameter.value.ptr = NULL;
672 algorithm.parameter = &parameter;
674 sig.digest = &digest;
675 sig.digest->data = (unsigned char*)m;
676 sig.digest->length = m_len;
678 length = i2d_X509_SIG(&sig, NULL);
681 keyLength = RSA_size(rsa);
683 if (length - RSA_PKCS1_PADDING > keyLength)
685 CCA4758err(CCA4758_F_CCA_RSA_VERIFY,
686 CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
687 return 0;
690 switch (type)
692 case NID_md5_sha1 :
693 if (m_len != SSL_SIG_LEN)
695 CCA4758err(CCA4758_F_CCA_RSA_VERIFY,
696 CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
697 return 0;
700 hashBuffer = (unsigned char *)m;
701 length = m_len;
702 break;
703 case NID_md5 :
705 unsigned char *ptr;
706 ptr = hashBuffer = OPENSSL_malloc(
707 (unsigned int)keyLength+1);
708 if (!hashBuffer)
710 CCA4758err(CCA4758_F_CCA_RSA_VERIFY,
711 ERR_R_MALLOC_FAILURE);
712 return 0;
715 i2d_X509_SIG(&sig, &ptr);
717 break;
718 case NID_sha1 :
720 unsigned char *ptr;
721 ptr = hashBuffer = OPENSSL_malloc(
722 (unsigned int)keyLength+1);
723 if (!hashBuffer)
725 CCA4758err(CCA4758_F_CCA_RSA_VERIFY,
726 ERR_R_MALLOC_FAILURE);
727 return 0;
729 i2d_X509_SIG(&sig, &ptr);
731 break;
732 default:
733 return 0;
736 digitalSignatureVerify(&returnCode, &reasonCode, &exitDataLength,
737 exitData, &ruleArrayLength, ruleArray, &keyTokenLength,
738 keyToken, &length, hashBuffer, &lsiglen, sigbuf);
740 if (type == NID_sha1 || type == NID_md5)
742 OPENSSL_cleanse(hashBuffer, keyLength+1);
743 OPENSSL_free(hashBuffer);
746 return ((returnCode || reasonCode) ? 0 : 1);
749 #define SSL_SIG_LEN 36
751 static int cca_rsa_sign(int type, const unsigned char *m, unsigned int m_len,
752 unsigned char *sigret, unsigned int *siglen, const RSA *rsa)
754 long returnCode;
755 long reasonCode;
756 long exitDataLength = 0;
757 unsigned char exitData[8];
758 long ruleArrayLength = 1;
759 unsigned char ruleArray[8] = "PKCS-1.1";
760 long outputLength=256;
761 long outputBitLength;
762 long keyTokenLength;
763 unsigned char *hashBuffer = NULL;
764 unsigned char* keyToken = (unsigned char*)RSA_get_ex_data(rsa, hndidx);
765 long length = SSL_SIG_LEN;
766 long keyLength ;
767 X509_SIG sig;
768 ASN1_TYPE parameter;
769 X509_ALGOR algorithm;
770 ASN1_OCTET_STRING digest;
772 keyTokenLength = *(long*)keyToken;
773 keyToken+=sizeof(long);
775 if (type == NID_md5 || type == NID_sha1)
777 sig.algor = &algorithm;
778 algorithm.algorithm = OBJ_nid2obj(type);
780 if (!algorithm.algorithm)
782 CCA4758err(CCA4758_F_CCA_RSA_SIGN,
783 CCA4758_R_UNKNOWN_ALGORITHM_TYPE);
784 return 0;
787 if (!algorithm.algorithm->length)
789 CCA4758err(CCA4758_F_CCA_RSA_SIGN,
790 CCA4758_R_ASN1_OID_UNKNOWN_FOR_MD);
791 return 0;
794 parameter.type = V_ASN1_NULL;
795 parameter.value.ptr = NULL;
796 algorithm.parameter = &parameter;
798 sig.digest = &digest;
799 sig.digest->data = (unsigned char*)m;
800 sig.digest->length = m_len;
802 length = i2d_X509_SIG(&sig, NULL);
805 keyLength = RSA_size(rsa);
807 if (length - RSA_PKCS1_PADDING > keyLength)
809 CCA4758err(CCA4758_F_CCA_RSA_SIGN,
810 CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
811 return 0;
814 switch (type)
816 case NID_md5_sha1 :
817 if (m_len != SSL_SIG_LEN)
819 CCA4758err(CCA4758_F_CCA_RSA_SIGN,
820 CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
821 return 0;
823 hashBuffer = (unsigned char*)m;
824 length = m_len;
825 break;
826 case NID_md5 :
828 unsigned char *ptr;
829 ptr = hashBuffer = OPENSSL_malloc(
830 (unsigned int)keyLength+1);
831 if (!hashBuffer)
833 CCA4758err(CCA4758_F_CCA_RSA_SIGN,
834 ERR_R_MALLOC_FAILURE);
835 return 0;
837 i2d_X509_SIG(&sig, &ptr);
839 break;
840 case NID_sha1 :
842 unsigned char *ptr;
843 ptr = hashBuffer = OPENSSL_malloc(
844 (unsigned int)keyLength+1);
845 if (!hashBuffer)
847 CCA4758err(CCA4758_F_CCA_RSA_SIGN,
848 ERR_R_MALLOC_FAILURE);
849 return 0;
851 i2d_X509_SIG(&sig, &ptr);
853 break;
854 default:
855 return 0;
858 digitalSignatureGenerate(&returnCode, &reasonCode, &exitDataLength,
859 exitData, &ruleArrayLength, ruleArray, &keyTokenLength,
860 keyToken, &length, hashBuffer, &outputLength, &outputBitLength,
861 sigret);
863 if (type == NID_sha1 || type == NID_md5)
865 OPENSSL_cleanse(hashBuffer, keyLength+1);
866 OPENSSL_free(hashBuffer);
869 *siglen = outputLength;
871 return ((returnCode || reasonCode) ? 0 : 1);
874 static int getModulusAndExponent(const unsigned char*token, long *exponentLength,
875 unsigned char *exponent, long *modulusLength, long *modulusFieldLength,
876 unsigned char *modulus)
878 unsigned long len;
880 if (*token++ != (char)0x1E) /* internal PKA token? */
881 return 0;
883 if (*token++) /* token version must be zero */
884 return 0;
886 len = *token++;
887 len = len << 8;
888 len |= (unsigned char)*token++;
890 token += 4; /* skip reserved bytes */
892 if (*token++ == (char)0x04)
894 if (*token++) /* token version must be zero */
895 return 0;
897 len = *token++;
898 len = len << 8;
899 len |= (unsigned char)*token++;
901 token+=2; /* skip reserved section */
903 len = *token++;
904 len = len << 8;
905 len |= (unsigned char)*token++;
907 *exponentLength = len;
909 len = *token++;
910 len = len << 8;
911 len |= (unsigned char)*token++;
913 *modulusLength = len;
915 len = *token++;
916 len = len << 8;
917 len |= (unsigned char)*token++;
919 *modulusFieldLength = len;
921 memcpy(exponent, token, *exponentLength);
922 token+= *exponentLength;
924 memcpy(modulus, token, *modulusFieldLength);
925 return 1;
927 return 0;
930 #endif /* OPENSSL_NO_RSA */
932 static int cca_random_status(void)
934 return 1;
937 static int cca_get_random_bytes(unsigned char* buf, int num)
939 long ret_code;
940 long reason_code;
941 long exit_data_length;
942 unsigned char exit_data[4];
943 unsigned char form[] = "RANDOM ";
944 unsigned char rand_buf[8];
946 while(num >= (int)sizeof(rand_buf))
948 randomNumberGenerate(&ret_code, &reason_code, &exit_data_length,
949 exit_data, form, rand_buf);
950 if (ret_code)
951 return 0;
952 num -= sizeof(rand_buf);
953 memcpy(buf, rand_buf, sizeof(rand_buf));
954 buf += sizeof(rand_buf);
957 if (num)
959 randomNumberGenerate(&ret_code, &reason_code, NULL, NULL,
960 form, rand_buf);
961 if (ret_code)
962 return 0;
963 memcpy(buf, rand_buf, num);
966 return 1;
969 #ifndef OPENSSL_NO_RSA
970 static void cca_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad, int idx,
971 long argl, void *argp)
973 if (item)
974 OPENSSL_free(item);
976 #endif
978 /* Goo to handle building as a dynamic engine */
979 #ifndef OPENSSL_NO_DYNAMIC_ENGINE
980 static int bind_fn(ENGINE *e, const char *id)
982 if(id && (strcmp(id, engine_4758_cca_id) != 0) &&
983 (strcmp(id, engine_4758_cca_id_alt) != 0))
984 return 0;
985 if(!bind_helper(e))
986 return 0;
987 return 1;
989 IMPLEMENT_DYNAMIC_CHECK_FN()
990 IMPLEMENT_DYNAMIC_BIND_FN(bind_fn)
991 #endif /* OPENSSL_NO_DYNAMIC_ENGINE */
993 #endif /* !OPENSSL_NO_HW_4758_CCA */
994 #endif /* !OPENSSL_NO_HW */