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).
57 #include <openssl/crypto.h>
58 /* #include <openssl/pem.h> */
60 #include <openssl/dso.h>
61 #include <openssl/x509.h>
62 #include <openssl/objects.h>
63 #include <openssl/engine.h>
66 #ifndef NO_HW_4758_CCA
69 #include "hw_4758_cca.h"
71 #include "vendor_defns/hw_4758_cca.h"
74 #include "hw_4758_cca_err.c"
76 static int ibm_4758_cca_destroy(ENGINE *e);
77 static int ibm_4758_cca_init(ENGINE *e);
78 static int ibm_4758_cca_finish(ENGINE *e);
79 static int ibm_4758_cca_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)());
83 #ifndef OPENSSL_NO_RSA
84 static int cca_rsa_pub_enc(int flen, const unsigned char *from,
85 unsigned char *to, RSA *rsa,int padding);
86 static int cca_rsa_priv_dec(int flen, const unsigned char *from,
87 unsigned char *to, RSA *rsa,int padding);
88 static int cca_rsa_sign(int type, const unsigned char *m, unsigned int m_len,
89 unsigned char *sigret, unsigned int *siglen, const RSA *rsa);
90 static int cca_rsa_verify(int dtype, const unsigned char *m, unsigned int m_len,
91 unsigned char *sigbuf, unsigned int siglen, const RSA *rsa);
93 /* utility functions */
94 /*-----------------------*/
95 static EVP_PKEY *ibm_4758_load_privkey(ENGINE*, const char*,
96 UI_METHOD *ui_method, void *callback_data);
97 static EVP_PKEY *ibm_4758_load_pubkey(ENGINE*, const char*,
98 UI_METHOD *ui_method, void *callback_data);
100 static int getModulusAndExponent(const unsigned char *token, long *exponentLength,
101 unsigned char *exponent, long *modulusLength,
102 long *modulusFieldLength, unsigned char *modulus);
105 /* RAND number functions */
106 /*-----------------------*/
107 static int cca_get_random_bytes(unsigned char*, int );
108 static int cca_random_status(void);
110 static void cca_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad,
111 int idx,long argl, void *argp);
113 /* Function pointers for CCA verbs */
114 /*---------------------------------*/
115 #ifndef OPENSSL_NO_RSA
116 static F_KEYRECORDREAD keyRecordRead;
117 static F_DIGITALSIGNATUREGENERATE digitalSignatureGenerate;
118 static F_DIGITALSIGNATUREVERIFY digitalSignatureVerify;
119 static F_PUBLICKEYEXTRACT publicKeyExtract;
120 static F_PKAENCRYPT pkaEncrypt;
121 static F_PKADECRYPT pkaDecrypt;
123 static F_RANDOMNUMBERGENERATE randomNumberGenerate;
125 /* static variables */
126 /*------------------*/
127 static const char def_CCA4758_LIB_NAME[] = CCA_LIB_NAME;
128 static const char *CCA4758_LIB_NAME = def_CCA4758_LIB_NAME;
129 #ifndef OPENSSL_NO_RSA
130 static const char* n_keyRecordRead = CSNDKRR;
131 static const char* n_digitalSignatureGenerate = CSNDDSG;
132 static const char* n_digitalSignatureVerify = CSNDDSV;
133 static const char* n_publicKeyExtract = CSNDPKX;
134 static const char* n_pkaEncrypt = CSNDPKE;
135 static const char* n_pkaDecrypt = CSNDPKD;
137 static const char* n_randomNumberGenerate = CSNBRNG;
139 static int hndidx = -1;
140 static DSO *dso = NULL;
142 /* openssl engine initialization structures */
143 /*------------------------------------------*/
145 #define CCA4758_CMD_SO_PATH ENGINE_CMD_BASE
146 static const ENGINE_CMD_DEFN cca4758_cmd_defns[] = {
147 {CCA4758_CMD_SO_PATH,
149 "Specifies the path to the '4758cca' shared library",
150 ENGINE_CMD_FLAG_STRING},
154 #ifndef OPENSSL_NO_RSA
155 static RSA_METHOD ibm_4758_cca_rsa =
157 "IBM 4758 CCA RSA method",
162 NULL, /*rsa_mod_exp,*/
163 NULL, /*mod_exp_mont,*/
166 RSA_FLAG_SIGN_VER, /* flags */
168 cca_rsa_sign, /* rsa_sign */
169 cca_rsa_verify /* rsa_verify */
173 static RAND_METHOD ibm_4758_cca_rand =
175 /* "IBM 4758 RAND method", */
177 cca_get_random_bytes, /* get random bytes from the card */
180 cca_get_random_bytes, /* pseudo rand */
181 cca_random_status, /* status */
184 static const char *engine_4758_cca_id = "4758cca";
185 static const char *engine_4758_cca_name = "IBM 4758 CCA hardware engine support";
187 /* engine implementation */
188 /*-----------------------*/
189 static int bind_helper(ENGINE *e)
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) ||
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))
205 /* Ensure the error handling is set up */
206 ERR_load_CCA4758_strings();
210 static ENGINE *engine_4758_cca(void)
212 ENGINE *ret = ENGINE_new();
215 if(!bind_helper(ret))
223 void ENGINE_load_4758cca(void)
225 ENGINE *e_4758 = engine_4758_cca();
232 static int ibm_4758_cca_destroy(ENGINE *e)
234 ERR_unload_CCA4758_strings();
238 static int ibm_4758_cca_init(ENGINE *e)
242 CCA4758err(CCA4758_F_IBM_4758_CCA_INIT,CCA4758_R_ALREADY_LOADED);
246 dso = DSO_load(NULL, CCA4758_LIB_NAME , NULL, 0);
249 CCA4758err(CCA4758_F_IBM_4758_CCA_INIT,CCA4758_R_DSO_FAILURE);
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)))
269 CCA4758err(CCA4758_F_IBM_4758_CCA_INIT,CCA4758_R_DSO_FAILURE);
273 if(!(randomNumberGenerate = (F_RANDOMNUMBERGENERATE)
274 DSO_bind_func(dso, n_randomNumberGenerate)))
276 CCA4758err(CCA4758_F_IBM_4758_CCA_INIT,CCA4758_R_DSO_FAILURE);
281 hndidx = RSA_get_ex_new_index(0, "IBM 4758 CCA RSA key handle",
282 NULL, NULL, cca_ex_free);
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;
300 static int ibm_4758_cca_finish(ENGINE *e)
304 CCA4758err(CCA4758_F_IBM_4758_CCA_FINISH,
305 CCA4758_R_NOT_LOADED);
310 CCA4758err(CCA4758_F_IBM_4758_CCA_FINISH,
311 CCA4758_R_UNIT_FAILURE);
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;
325 static int ibm_4758_cca_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)())
327 int initialised = ((dso == NULL) ? 0 : 1);
330 case CCA4758_CMD_SO_PATH:
333 CCA4758err(CCA4758_F_IBM_4758_CCA_CTRL,
334 ERR_R_PASSED_NULL_PARAMETER);
339 CCA4758err(CCA4758_F_IBM_4758_CCA_CTRL,
340 CCA4758_R_ALREADY_LOADED);
343 CCA4758_LIB_NAME = (const char *)p;
348 CCA4758err(CCA4758_F_IBM_4758_CCA_CTRL,
349 CCA4758_R_COMMAND_NOT_IMPLEMENTED);
353 #ifndef OPENSSL_NO_RSA
355 #define MAX_CCA_PKA_TOKEN_SIZE 2500
357 static EVP_PKEY *ibm_4758_load_privkey(ENGINE* e, const char* key_id,
358 UI_METHOD *ui_method, void *callback_data)
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;
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);
380 if (keyLabelLength > sizeof(keyLabel))
382 CCA4758err(CCA4758_F_IBM_4758_CCA_LOAD_PRIVKEY,
383 CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
387 memset(keyLabel,' ', sizeof(keyLabel));
388 memcpy(keyLabel, key_id, keyLabelLength);
390 keyToken = OPENSSL_malloc(MAX_CCA_PKA_TOKEN_SIZE + sizeof(long));
393 CCA4758err(CCA4758_F_IBM_4758_CCA_LOAD_PRIVKEY,
394 ERR_R_MALLOC_FAILURE);
398 keyRecordRead(&returnCode, &reasonCode, &exitDataLength,
399 exitData, &ruleArrayLength, ruleArray, keyLabel,
400 &keyTokenLength, keyToken+sizeof(long));
404 CCA4758err(CCA4758_F_IBM_4758_CCA_LOAD_PRIVKEY,
405 CCA4758_R_FAILED_LOADING_PRIVATE_KEY);
409 publicKeyExtract(&returnCode, &reasonCode, &exitDataLength,
410 exitData, &ruleArrayLength, ruleArray, &keyTokenLength,
411 keyToken+sizeof(long), &pubKeyTokenLength, pubKeyToken);
415 CCA4758err(CCA4758_F_IBM_4758_CCA_LOAD_PRIVKEY,
416 CCA4758_R_FAILED_LOADING_PRIVATE_KEY);
420 if (!getModulusAndExponent(pubKeyToken, &exponentLength,
421 exponent, &modulusLength, &modulusFieldLength,
424 CCA4758err(CCA4758_F_IBM_4758_CCA_LOAD_PRIVKEY,
425 CCA4758_R_FAILED_LOADING_PRIVATE_KEY);
429 (*(long*)keyToken) = keyTokenLength;
430 rtmp = RSA_new_method(e);
431 RSA_set_ex_data(rtmp, hndidx, (char *)keyToken);
433 rtmp->e = BN_bin2bn(exponent, exponentLength, NULL);
434 rtmp->n = BN_bin2bn(modulus, modulusFieldLength, NULL);
435 rtmp->flags |= RSA_FLAG_EXT_PKEY;
437 res = EVP_PKEY_new();
438 EVP_PKEY_assign_RSA(res, rtmp);
443 OPENSSL_free(keyToken);
451 static EVP_PKEY *ibm_4758_load_pubkey(ENGINE* e, const char* key_id,
452 UI_METHOD *ui_method, void *callback_data)
455 EVP_PKEY *res = NULL;
456 unsigned char* keyToken = NULL;
457 long keyTokenLength = MAX_CCA_PKA_TOKEN_SIZE;
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);
472 if (keyLabelLength > sizeof(keyLabel))
474 CCA4758err(CCA4758_F_IBM_4758_CCA_LOAD_PRIVKEY,
475 CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
479 memset(keyLabel,' ', sizeof(keyLabel));
480 memcpy(keyLabel, key_id, keyLabelLength);
482 keyToken = OPENSSL_malloc(MAX_CCA_PKA_TOKEN_SIZE + sizeof(long));
485 CCA4758err(CCA4758_F_IBM_4758_CCA_LOAD_PUBKEY,
486 ERR_R_MALLOC_FAILURE);
490 keyRecordRead(&returnCode, &reasonCode, &exitDataLength, exitData,
491 &ruleArrayLength, ruleArray, keyLabel, &keyTokenLength,
492 keyToken+sizeof(long));
496 CCA4758err(CCA4758_F_IBM_4758_CCA_LOAD_PRIVKEY,
497 ERR_R_MALLOC_FAILURE);
501 if (!getModulusAndExponent(keyToken+sizeof(long), &exponentLength,
502 exponent, &modulusLength, &modulusFieldLength, modulus))
504 CCA4758err(CCA4758_F_IBM_4758_CCA_LOAD_PRIVKEY,
505 CCA4758_R_FAILED_LOADING_PUBLIC_KEY);
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);
521 OPENSSL_free(keyToken);
529 static int cca_rsa_pub_enc(int flen, const unsigned char *from,
530 unsigned char *to, RSA *rsa,int padding)
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);
543 unsigned char* keyToken = (unsigned char*)RSA_get_ex_data(rsa, hndidx);
545 keyTokenLength = *(long*)keyToken;
546 keyToken+=sizeof(long);
548 pkaEncrypt(&returnCode, &reasonCode, &exitDataLength, exitData,
549 &ruleArrayLength, ruleArray, &lflen, (unsigned char*)from,
550 &dataStructureLength, dataStructure, &keyTokenLength,
551 keyToken, &outputLength, to);
553 if (returnCode || reasonCode)
554 return -(returnCode << 16 | reasonCode);
558 static int cca_rsa_priv_dec(int flen, const unsigned char *from,
559 unsigned char *to, RSA *rsa,int padding)
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);
572 unsigned char* keyToken = (unsigned char*)RSA_get_ex_data(rsa, hndidx);
574 keyTokenLength = *(long*)keyToken;
575 keyToken+=sizeof(long);
577 pkaDecrypt(&returnCode, &reasonCode, &exitDataLength, exitData,
578 &ruleArrayLength, ruleArray, &lflen, (unsigned char*)from,
579 &dataStructureLength, dataStructure, &keyTokenLength,
580 keyToken, &outputLength, to);
582 return (returnCode | reasonCode) ? 0 : 1;
585 #define SSL_SIG_LEN 36
587 static int cca_rsa_verify(int type, const unsigned char *m, unsigned int m_len,
588 unsigned char *sigbuf, unsigned int siglen, const RSA *rsa)
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";
598 unsigned char* keyToken = (unsigned char*)RSA_get_ex_data(rsa, hndidx);
599 long length = SSL_SIG_LEN;
601 unsigned char *hashBuffer = NULL;
604 X509_ALGOR algorithm;
605 ASN1_OCTET_STRING digest;
607 keyTokenLength = *(long*)keyToken;
608 keyToken+=sizeof(long);
610 if (type == NID_md5 || type == NID_sha1)
612 sig.algor = &algorithm;
613 algorithm.algorithm = OBJ_nid2obj(type);
615 if (!algorithm.algorithm)
617 CCA4758err(CCA4758_F_IBM_4758_CCA_VERIFY,
618 CCA4758_R_UNKNOWN_ALGORITHM_TYPE);
622 if (!algorithm.algorithm->length)
624 CCA4758err(CCA4758_F_IBM_4758_CCA_VERIFY,
625 CCA4758_R_ASN1_OID_UNKNOWN_FOR_MD);
629 parameter.type = V_ASN1_NULL;
630 parameter.value.ptr = NULL;
631 algorithm.parameter = ¶meter;
633 sig.digest = &digest;
634 sig.digest->data = (unsigned char*)m;
635 sig.digest->length = m_len;
637 length = i2d_X509_SIG(&sig, NULL);
640 keyLength = RSA_size(rsa);
642 if (length - RSA_PKCS1_PADDING > keyLength)
644 CCA4758err(CCA4758_F_IBM_4758_CCA_VERIFY,
645 CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
652 if (m_len != SSL_SIG_LEN)
654 CCA4758err(CCA4758_F_IBM_4758_CCA_VERIFY,
655 CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
659 hashBuffer = (unsigned char *)m;
665 ptr = hashBuffer = OPENSSL_malloc(
666 (unsigned int)keyLength+1);
669 CCA4758err(CCA4758_F_IBM_4758_CCA_VERIFY,
670 ERR_R_MALLOC_FAILURE);
674 i2d_X509_SIG(&sig, &ptr);
680 ptr = hashBuffer = OPENSSL_malloc(
681 (unsigned int)keyLength+1);
684 CCA4758err(CCA4758_F_IBM_4758_CCA_VERIFY,
685 ERR_R_MALLOC_FAILURE);
688 i2d_X509_SIG(&sig, &ptr);
695 digitalSignatureVerify(&returnCode, &reasonCode, &exitDataLength,
696 exitData, &ruleArrayLength, ruleArray, &keyTokenLength,
697 keyToken, &length, hashBuffer, &lsiglen, sigbuf);
699 if (type == NID_sha1 || type == NID_md5)
701 memset(hashBuffer, keyLength+1, 0);
702 OPENSSL_free(hashBuffer);
705 return ((returnCode || reasonCode) ? 0 : 1);
708 #define SSL_SIG_LEN 36
710 static int cca_rsa_sign(int type, const unsigned char *m, unsigned int m_len,
711 unsigned char *sigret, unsigned int *siglen, const RSA *rsa)
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;
722 unsigned char *hashBuffer = NULL;
723 unsigned char* keyToken = (unsigned char*)RSA_get_ex_data(rsa, hndidx);
724 long length = SSL_SIG_LEN;
728 X509_ALGOR algorithm;
729 ASN1_OCTET_STRING digest;
731 keyTokenLength = *(long*)keyToken;
732 keyToken+=sizeof(long);
734 if (type == NID_md5 || type == NID_sha1)
736 sig.algor = &algorithm;
737 algorithm.algorithm = OBJ_nid2obj(type);
739 if (!algorithm.algorithm)
741 CCA4758err(CCA4758_F_IBM_4758_CCA_SIGN,
742 CCA4758_R_UNKNOWN_ALGORITHM_TYPE);
746 if (!algorithm.algorithm->length)
748 CCA4758err(CCA4758_F_IBM_4758_CCA_SIGN,
749 CCA4758_R_ASN1_OID_UNKNOWN_FOR_MD);
753 parameter.type = V_ASN1_NULL;
754 parameter.value.ptr = NULL;
755 algorithm.parameter = ¶meter;
757 sig.digest = &digest;
758 sig.digest->data = (unsigned char*)m;
759 sig.digest->length = m_len;
761 length = i2d_X509_SIG(&sig, NULL);
764 keyLength = RSA_size(rsa);
766 if (length - RSA_PKCS1_PADDING > keyLength)
768 CCA4758err(CCA4758_F_IBM_4758_CCA_SIGN,
769 CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
776 if (m_len != SSL_SIG_LEN)
778 CCA4758err(CCA4758_F_IBM_4758_CCA_SIGN,
779 CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
782 hashBuffer = (unsigned char*)m;
788 ptr = hashBuffer = OPENSSL_malloc(
789 (unsigned int)keyLength+1);
792 CCA4758err(CCA4758_F_IBM_4758_CCA_VERIFY,
793 ERR_R_MALLOC_FAILURE);
796 i2d_X509_SIG(&sig, &ptr);
802 ptr = hashBuffer = OPENSSL_malloc(
803 (unsigned int)keyLength+1);
806 CCA4758err(CCA4758_F_IBM_4758_CCA_VERIFY,
807 ERR_R_MALLOC_FAILURE);
810 i2d_X509_SIG(&sig, &ptr);
817 digitalSignatureGenerate(&returnCode, &reasonCode, &exitDataLength,
818 exitData, &ruleArrayLength, ruleArray, &keyTokenLength,
819 keyToken, &length, hashBuffer, &outputLength, &outputBitLength,
822 if (type == NID_sha1 || type == NID_md5)
824 memset(hashBuffer, keyLength+1, 0);
825 OPENSSL_free(hashBuffer);
828 *siglen = outputLength;
830 return ((returnCode || reasonCode) ? 0 : 1);
833 static int getModulusAndExponent(const unsigned char*token, long *exponentLength,
834 unsigned char *exponent, long *modulusLength, long *modulusFieldLength,
835 unsigned char *modulus)
839 if (*token++ != (char)0x1E) /* internal PKA token? */
842 if (*token++) /* token version must be zero */
847 len |= (unsigned char)*token++;
849 token += 4; /* skip reserved bytes */
851 if (*token++ == (char)0x04)
853 if (*token++) /* token version must be zero */
858 len |= (unsigned char)*token++;
860 token+=2; /* skip reserved section */
864 len |= (unsigned char)*token++;
866 *exponentLength = len;
870 len |= (unsigned char)*token++;
872 *modulusLength = len;
876 len |= (unsigned char)*token++;
878 *modulusFieldLength = len;
880 memcpy(exponent, token, *exponentLength);
881 token+= *exponentLength;
883 memcpy(modulus, token, *modulusFieldLength);
889 #endif /* OPENSSL_NO_RSA */
891 static int cca_random_status(void)
896 static int cca_get_random_bytes(unsigned char* buf, int num)
900 long exit_data_length;
901 unsigned char exit_data[4];
902 unsigned char form[] = "RANDOM ";
903 unsigned char rand_buf[8];
905 while(num >= sizeof(rand_buf))
907 randomNumberGenerate(&ret_code, &reason_code, &exit_data_length,
908 exit_data, form, rand_buf);
911 num -= sizeof(rand_buf);
912 memcpy(buf, rand_buf, sizeof(rand_buf));
913 buf += sizeof(rand_buf);
918 randomNumberGenerate(&ret_code, &reason_code, NULL, NULL,
922 memcpy(buf, rand_buf, num);
928 static void cca_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad, int idx,
929 long argl, void *argp)
935 /* Goo to handle building as a dynamic engine */
936 #ifdef ENGINE_DYNAMIC_SUPPORT
937 static int bind_fn(ENGINE *e, const char *id)
939 if(id && (strcmp(id, engine_cswift_id) != 0))
945 IMPLEMENT_DYNAMIC_CHECK_FN()
946 IMPLEMENT_DYNAMIC_BIND_FN(bind_fn)
947 #endif /* ENGINE_DYNAMIC_SUPPORT */
949 #endif /* !NO_HW_4758_CCA */