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
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
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
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).
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>
67 #include <openssl/bn.h>
70 #ifndef OPENSSL_NO_HW_4758_CCA
73 #include "hw_4758_cca.h"
75 #include "vendor_defns/hw_4758_cca.h"
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));
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 const 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);
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);
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;
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)
137 return CCA4758_LIB_NAME;
140 static void free_CCA4758_LIB_NAME(void)
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;
159 static const char* n_randomNumberGenerate = CSNBRNG;
161 #ifndef OPENSSL_NO_RSA
162 static int hndidx = -1;
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,
173 "Specifies the path to the '4758cca' shared library",
174 ENGINE_CMD_FLAG_STRING},
178 #ifndef OPENSSL_NO_RSA
179 static RSA_METHOD ibm_4758_cca_rsa =
181 "IBM 4758 CCA RSA method",
186 NULL, /*rsa_mod_exp,*/
187 NULL, /*mod_exp_mont,*/
190 RSA_FLAG_SIGN_VER, /* flags */
192 cca_rsa_sign, /* rsa_sign */
193 cca_rsa_verify, /* rsa_verify */
194 NULL /* rsa_keygen */
198 static RAND_METHOD ibm_4758_cca_rand =
200 /* "IBM 4758 RAND method", */
202 cca_get_random_bytes, /* get random bytes from the card */
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";
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) ||
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) ||
234 !ENGINE_set_cmd_defns(e, cca4758_cmd_defns))
236 /* Ensure the error handling is set up */
237 ERR_load_CCA4758_strings();
241 #ifdef OPENSSL_NO_DYNAMIC_ENGINE
242 static ENGINE *engine_4758_cca(void)
244 ENGINE *ret = ENGINE_new();
247 if(!bind_helper(ret))
255 void ENGINE_load_4758cca(void)
257 ENGINE *e_4758 = engine_4758_cca();
265 static int ibm_4758_cca_destroy(ENGINE *e)
267 ERR_unload_CCA4758_strings();
268 free_CCA4758_LIB_NAME();
272 static int ibm_4758_cca_init(ENGINE *e)
276 CCA4758err(CCA4758_F_IBM_4758_CCA_INIT,CCA4758_R_ALREADY_LOADED);
280 dso = DSO_load(NULL, get_CCA4758_LIB_NAME(), NULL, 0);
283 CCA4758err(CCA4758_F_IBM_4758_CCA_INIT,CCA4758_R_DSO_FAILURE);
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);
307 if(!(randomNumberGenerate = (F_RANDOMNUMBERGENERATE)
308 DSO_bind_func(dso, n_randomNumberGenerate)))
310 CCA4758err(CCA4758_F_IBM_4758_CCA_INIT,CCA4758_R_DSO_FAILURE);
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);
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;
334 randomNumberGenerate = (F_RANDOMNUMBERGENERATE)0;
338 static int ibm_4758_cca_finish(ENGINE *e)
340 free_CCA4758_LIB_NAME();
343 CCA4758err(CCA4758_F_IBM_4758_CCA_FINISH,
344 CCA4758_R_NOT_LOADED);
349 CCA4758err(CCA4758_F_IBM_4758_CCA_FINISH,
350 CCA4758_R_UNIT_FAILURE);
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;
363 randomNumberGenerate = (F_RANDOMNUMBERGENERATE)0;
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);
372 case CCA4758_CMD_SO_PATH:
375 CCA4758err(CCA4758_F_IBM_4758_CCA_CTRL,
376 ERR_R_PASSED_NULL_PARAMETER);
381 CCA4758err(CCA4758_F_IBM_4758_CCA_CTRL,
382 CCA4758_R_ALREADY_LOADED);
385 return set_CCA4758_LIB_NAME((const char *)p);
389 CCA4758err(CCA4758_F_IBM_4758_CCA_CTRL,
390 CCA4758_R_COMMAND_NOT_IMPLEMENTED);
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)
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;
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);
428 memset(keyLabel,' ', sizeof(keyLabel));
429 memcpy(keyLabel, key_id, keyLabelLength);
431 keyToken = OPENSSL_malloc(MAX_CCA_PKA_TOKEN_SIZE + sizeof(long));
434 CCA4758err(CCA4758_F_IBM_4758_LOAD_PRIVKEY,
435 ERR_R_MALLOC_FAILURE);
439 keyRecordRead(&returnCode, &reasonCode, &exitDataLength,
440 exitData, &ruleArrayLength, ruleArray, keyLabel,
441 &keyTokenLength, keyToken+sizeof(long));
445 CCA4758err(CCA4758_F_IBM_4758_LOAD_PRIVKEY,
446 CCA4758_R_FAILED_LOADING_PRIVATE_KEY);
450 publicKeyExtract(&returnCode, &reasonCode, &exitDataLength,
451 exitData, &ruleArrayLength, ruleArray, &keyTokenLength,
452 keyToken+sizeof(long), &pubKeyTokenLength, pubKeyToken);
456 CCA4758err(CCA4758_F_IBM_4758_LOAD_PRIVKEY,
457 CCA4758_R_FAILED_LOADING_PRIVATE_KEY);
461 if (!getModulusAndExponent(pubKeyToken, &exponentLength,
462 exponent, &modulusLength, &modulusFieldLength,
465 CCA4758err(CCA4758_F_IBM_4758_LOAD_PRIVKEY,
466 CCA4758_R_FAILED_LOADING_PRIVATE_KEY);
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);
484 OPENSSL_free(keyToken);
488 static EVP_PKEY *ibm_4758_load_pubkey(ENGINE* e, const char* key_id,
489 UI_METHOD *ui_method, void *callback_data)
492 EVP_PKEY *res = NULL;
493 unsigned char* keyToken = NULL;
494 long keyTokenLength = MAX_CCA_PKA_TOKEN_SIZE;
497 long exitDataLength = 0;
498 long ruleArrayLength = 0;
499 unsigned char exitData[8];
500 unsigned char ruleArray[8];
501 unsigned char keyLabel[64];
502 unsigned long keyLabelLength = strlen(key_id);
503 unsigned char modulus[512];
504 long modulusFieldLength = sizeof(modulus);
505 long modulusLength = 0;
506 unsigned char exponent[512];
507 long exponentLength = sizeof(exponent);
509 if (keyLabelLength > sizeof(keyLabel))
511 CCA4758err(CCA4758_F_IBM_4758_LOAD_PUBKEY,
512 CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
516 memset(keyLabel,' ', sizeof(keyLabel));
517 memcpy(keyLabel, key_id, keyLabelLength);
519 keyToken = OPENSSL_malloc(MAX_CCA_PKA_TOKEN_SIZE + sizeof(long));
522 CCA4758err(CCA4758_F_IBM_4758_LOAD_PUBKEY,
523 ERR_R_MALLOC_FAILURE);
527 keyRecordRead(&returnCode, &reasonCode, &exitDataLength, exitData,
528 &ruleArrayLength, ruleArray, keyLabel, &keyTokenLength,
529 keyToken+sizeof(long));
533 CCA4758err(CCA4758_F_IBM_4758_LOAD_PUBKEY,
534 ERR_R_MALLOC_FAILURE);
538 if (!getModulusAndExponent(keyToken+sizeof(long), &exponentLength,
539 exponent, &modulusLength, &modulusFieldLength, modulus))
541 CCA4758err(CCA4758_F_IBM_4758_LOAD_PUBKEY,
542 CCA4758_R_FAILED_LOADING_PUBLIC_KEY);
546 (*(long*)keyToken) = keyTokenLength;
547 rtmp = RSA_new_method(e);
548 RSA_set_ex_data(rtmp, hndidx, (char *)keyToken);
549 rtmp->e = BN_bin2bn(exponent, exponentLength, NULL);
550 rtmp->n = BN_bin2bn(modulus, modulusFieldLength, NULL);
551 rtmp->flags |= RSA_FLAG_EXT_PKEY;
552 res = EVP_PKEY_new();
553 EVP_PKEY_assign_RSA(res, rtmp);
558 OPENSSL_free(keyToken);
562 static int cca_rsa_pub_enc(int flen, const unsigned char *from,
563 unsigned char *to, RSA *rsa,int padding)
568 long exitDataLength = 0;
569 unsigned char exitData[8];
570 long ruleArrayLength = 1;
571 unsigned char ruleArray[8] = "PKCS-1.2";
572 long dataStructureLength = 0;
573 unsigned char dataStructure[8];
574 long outputLength = RSA_size(rsa);
576 unsigned char* keyToken = (unsigned char*)RSA_get_ex_data(rsa, hndidx);
578 keyTokenLength = *(long*)keyToken;
579 keyToken+=sizeof(long);
581 pkaEncrypt(&returnCode, &reasonCode, &exitDataLength, exitData,
582 &ruleArrayLength, ruleArray, &lflen, (unsigned char*)from,
583 &dataStructureLength, dataStructure, &keyTokenLength,
584 keyToken, &outputLength, to);
586 if (returnCode || reasonCode)
587 return -(returnCode << 16 | reasonCode);
591 static int cca_rsa_priv_dec(int flen, const unsigned char *from,
592 unsigned char *to, RSA *rsa,int padding)
597 long exitDataLength = 0;
598 unsigned char exitData[8];
599 long ruleArrayLength = 1;
600 unsigned char ruleArray[8] = "PKCS-1.2";
601 long dataStructureLength = 0;
602 unsigned char dataStructure[8];
603 long outputLength = RSA_size(rsa);
605 unsigned char* keyToken = (unsigned char*)RSA_get_ex_data(rsa, hndidx);
607 keyTokenLength = *(long*)keyToken;
608 keyToken+=sizeof(long);
610 pkaDecrypt(&returnCode, &reasonCode, &exitDataLength, exitData,
611 &ruleArrayLength, ruleArray, &lflen, (unsigned char*)from,
612 &dataStructureLength, dataStructure, &keyTokenLength,
613 keyToken, &outputLength, to);
615 return (returnCode | reasonCode) ? 0 : 1;
618 #define SSL_SIG_LEN 36
620 static int cca_rsa_verify(int type, const unsigned char *m, unsigned int m_len,
621 const unsigned char *sigbuf, unsigned int siglen, const RSA *rsa)
625 long lsiglen = siglen;
626 long exitDataLength = 0;
627 unsigned char exitData[8];
628 long ruleArrayLength = 1;
629 unsigned char ruleArray[8] = "PKCS-1.1";
631 unsigned char* keyToken = (unsigned char*)RSA_get_ex_data(rsa, hndidx);
632 long length = SSL_SIG_LEN;
634 unsigned char *hashBuffer = NULL;
637 X509_ALGOR algorithm;
638 ASN1_OCTET_STRING digest;
640 keyTokenLength = *(long*)keyToken;
641 keyToken+=sizeof(long);
643 if (type == NID_md5 || type == NID_sha1)
645 sig.algor = &algorithm;
646 algorithm.algorithm = OBJ_nid2obj(type);
648 if (!algorithm.algorithm)
650 CCA4758err(CCA4758_F_CCA_RSA_VERIFY,
651 CCA4758_R_UNKNOWN_ALGORITHM_TYPE);
655 if (!algorithm.algorithm->length)
657 CCA4758err(CCA4758_F_CCA_RSA_VERIFY,
658 CCA4758_R_ASN1_OID_UNKNOWN_FOR_MD);
662 parameter.type = V_ASN1_NULL;
663 parameter.value.ptr = NULL;
664 algorithm.parameter = ¶meter;
666 sig.digest = &digest;
667 sig.digest->data = (unsigned char*)m;
668 sig.digest->length = m_len;
670 length = i2d_X509_SIG(&sig, NULL);
673 keyLength = RSA_size(rsa);
675 if (length - RSA_PKCS1_PADDING > keyLength)
677 CCA4758err(CCA4758_F_CCA_RSA_VERIFY,
678 CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
685 if (m_len != SSL_SIG_LEN)
687 CCA4758err(CCA4758_F_CCA_RSA_VERIFY,
688 CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
692 hashBuffer = (unsigned char *)m;
698 ptr = hashBuffer = OPENSSL_malloc(
699 (unsigned int)keyLength+1);
702 CCA4758err(CCA4758_F_CCA_RSA_VERIFY,
703 ERR_R_MALLOC_FAILURE);
707 i2d_X509_SIG(&sig, &ptr);
713 ptr = hashBuffer = OPENSSL_malloc(
714 (unsigned int)keyLength+1);
717 CCA4758err(CCA4758_F_CCA_RSA_VERIFY,
718 ERR_R_MALLOC_FAILURE);
721 i2d_X509_SIG(&sig, &ptr);
728 digitalSignatureVerify(&returnCode, &reasonCode, &exitDataLength,
729 exitData, &ruleArrayLength, ruleArray, &keyTokenLength,
730 keyToken, &length, hashBuffer, &lsiglen,
731 (unsigned char *)sigbuf);
733 if (type == NID_sha1 || type == NID_md5)
735 OPENSSL_cleanse(hashBuffer, keyLength+1);
736 OPENSSL_free(hashBuffer);
739 return ((returnCode || reasonCode) ? 0 : 1);
742 #define SSL_SIG_LEN 36
744 static int cca_rsa_sign(int type, const unsigned char *m, unsigned int m_len,
745 unsigned char *sigret, unsigned int *siglen, const RSA *rsa)
749 long exitDataLength = 0;
750 unsigned char exitData[8];
751 long ruleArrayLength = 1;
752 unsigned char ruleArray[8] = "PKCS-1.1";
753 long outputLength=256;
754 long outputBitLength;
756 unsigned char *hashBuffer = NULL;
757 unsigned char* keyToken = (unsigned char*)RSA_get_ex_data(rsa, hndidx);
758 long length = SSL_SIG_LEN;
762 X509_ALGOR algorithm;
763 ASN1_OCTET_STRING digest;
765 keyTokenLength = *(long*)keyToken;
766 keyToken+=sizeof(long);
768 if (type == NID_md5 || type == NID_sha1)
770 sig.algor = &algorithm;
771 algorithm.algorithm = OBJ_nid2obj(type);
773 if (!algorithm.algorithm)
775 CCA4758err(CCA4758_F_CCA_RSA_SIGN,
776 CCA4758_R_UNKNOWN_ALGORITHM_TYPE);
780 if (!algorithm.algorithm->length)
782 CCA4758err(CCA4758_F_CCA_RSA_SIGN,
783 CCA4758_R_ASN1_OID_UNKNOWN_FOR_MD);
787 parameter.type = V_ASN1_NULL;
788 parameter.value.ptr = NULL;
789 algorithm.parameter = ¶meter;
791 sig.digest = &digest;
792 sig.digest->data = (unsigned char*)m;
793 sig.digest->length = m_len;
795 length = i2d_X509_SIG(&sig, NULL);
798 keyLength = RSA_size(rsa);
800 if (length - RSA_PKCS1_PADDING > keyLength)
802 CCA4758err(CCA4758_F_CCA_RSA_SIGN,
803 CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
810 if (m_len != SSL_SIG_LEN)
812 CCA4758err(CCA4758_F_CCA_RSA_SIGN,
813 CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
816 hashBuffer = (unsigned char*)m;
822 ptr = hashBuffer = OPENSSL_malloc(
823 (unsigned int)keyLength+1);
826 CCA4758err(CCA4758_F_CCA_RSA_SIGN,
827 ERR_R_MALLOC_FAILURE);
830 i2d_X509_SIG(&sig, &ptr);
836 ptr = hashBuffer = OPENSSL_malloc(
837 (unsigned int)keyLength+1);
840 CCA4758err(CCA4758_F_CCA_RSA_SIGN,
841 ERR_R_MALLOC_FAILURE);
844 i2d_X509_SIG(&sig, &ptr);
851 digitalSignatureGenerate(&returnCode, &reasonCode, &exitDataLength,
852 exitData, &ruleArrayLength, ruleArray, &keyTokenLength,
853 keyToken, &length, hashBuffer, &outputLength, &outputBitLength,
856 if (type == NID_sha1 || type == NID_md5)
858 OPENSSL_cleanse(hashBuffer, keyLength+1);
859 OPENSSL_free(hashBuffer);
862 *siglen = outputLength;
864 return ((returnCode || reasonCode) ? 0 : 1);
867 static int getModulusAndExponent(const unsigned char*token, long *exponentLength,
868 unsigned char *exponent, long *modulusLength, long *modulusFieldLength,
869 unsigned char *modulus)
873 if (*token++ != (char)0x1E) /* internal PKA token? */
876 if (*token++) /* token version must be zero */
881 len |= (unsigned char)*token++;
883 token += 4; /* skip reserved bytes */
885 if (*token++ == (char)0x04)
887 if (*token++) /* token version must be zero */
892 len |= (unsigned char)*token++;
894 token+=2; /* skip reserved section */
898 len |= (unsigned char)*token++;
900 *exponentLength = len;
904 len |= (unsigned char)*token++;
906 *modulusLength = len;
910 len |= (unsigned char)*token++;
912 *modulusFieldLength = len;
914 memcpy(exponent, token, *exponentLength);
915 token+= *exponentLength;
917 memcpy(modulus, token, *modulusFieldLength);
923 #endif /* OPENSSL_NO_RSA */
925 static int cca_random_status(void)
930 static int cca_get_random_bytes(unsigned char* buf, int num)
934 long exit_data_length;
935 unsigned char exit_data[4];
936 unsigned char form[] = "RANDOM ";
937 unsigned char rand_buf[8];
939 while(num >= (int)sizeof(rand_buf))
941 randomNumberGenerate(&ret_code, &reason_code, &exit_data_length,
942 exit_data, form, rand_buf);
945 num -= sizeof(rand_buf);
946 memcpy(buf, rand_buf, sizeof(rand_buf));
947 buf += sizeof(rand_buf);
952 randomNumberGenerate(&ret_code, &reason_code, NULL, NULL,
956 memcpy(buf, rand_buf, num);
962 #ifndef OPENSSL_NO_RSA
963 static void cca_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad, int idx,
964 long argl, void *argp)
971 /* Goo to handle building as a dynamic engine */
972 #ifndef OPENSSL_NO_DYNAMIC_ENGINE
973 static int bind_fn(ENGINE *e, const char *id)
975 if(id && (strcmp(id, engine_4758_cca_id) != 0) &&
976 (strcmp(id, engine_4758_cca_id_alt) != 0))
982 IMPLEMENT_DYNAMIC_CHECK_FN()
983 IMPLEMENT_DYNAMIC_BIND_FN(bind_fn)
984 #endif /* OPENSSL_NO_DYNAMIC_ENGINE */
986 #endif /* !OPENSSL_NO_HW_4758_CCA */
987 #endif /* !OPENSSL_NO_HW */