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 */