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 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
);
492 static EVP_PKEY
*ibm_4758_load_pubkey(ENGINE
* e
, const char* key_id
,
493 UI_METHOD
*ui_method
, void *callback_data
)
496 EVP_PKEY
*res
= NULL
;
497 unsigned char* keyToken
= NULL
;
498 long keyTokenLength
= MAX_CCA_PKA_TOKEN_SIZE
;
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
);
520 memset(keyLabel
,' ', sizeof(keyLabel
));
521 memcpy(keyLabel
, key_id
, keyLabelLength
);
523 keyToken
= OPENSSL_malloc(MAX_CCA_PKA_TOKEN_SIZE
+ sizeof(long));
526 CCA4758err(CCA4758_F_IBM_4758_LOAD_PUBKEY
,
527 ERR_R_MALLOC_FAILURE
);
531 keyRecordRead(&returnCode
, &reasonCode
, &exitDataLength
, exitData
,
532 &ruleArrayLength
, ruleArray
, keyLabel
, &keyTokenLength
,
533 keyToken
+sizeof(long));
537 CCA4758err(CCA4758_F_IBM_4758_LOAD_PUBKEY
,
538 ERR_R_MALLOC_FAILURE
);
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
);
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
);
562 OPENSSL_free(keyToken
);
570 static int cca_rsa_pub_enc(int flen
, const unsigned char *from
,
571 unsigned char *to
, RSA
*rsa
,int padding
)
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
);
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
);
599 static int cca_rsa_priv_dec(int flen
, const unsigned char *from
,
600 unsigned char *to
, RSA
*rsa
,int padding
)
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
);
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
)
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";
639 unsigned char* keyToken
= (unsigned char*)RSA_get_ex_data(rsa
, hndidx
);
640 long length
= SSL_SIG_LEN
;
642 unsigned char *hashBuffer
= NULL
;
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
);
663 if (!algorithm
.algorithm
->length
)
665 CCA4758err(CCA4758_F_CCA_RSA_VERIFY
,
666 CCA4758_R_ASN1_OID_UNKNOWN_FOR_MD
);
670 parameter
.type
= V_ASN1_NULL
;
671 parameter
.value
.ptr
= NULL
;
672 algorithm
.parameter
= ¶meter
;
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
);
693 if (m_len
!= SSL_SIG_LEN
)
695 CCA4758err(CCA4758_F_CCA_RSA_VERIFY
,
696 CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL
);
700 hashBuffer
= (unsigned char *)m
;
706 ptr
= hashBuffer
= OPENSSL_malloc(
707 (unsigned int)keyLength
+1);
710 CCA4758err(CCA4758_F_CCA_RSA_VERIFY
,
711 ERR_R_MALLOC_FAILURE
);
715 i2d_X509_SIG(&sig
, &ptr
);
721 ptr
= hashBuffer
= OPENSSL_malloc(
722 (unsigned int)keyLength
+1);
725 CCA4758err(CCA4758_F_CCA_RSA_VERIFY
,
726 ERR_R_MALLOC_FAILURE
);
729 i2d_X509_SIG(&sig
, &ptr
);
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
)
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
;
763 unsigned char *hashBuffer
= NULL
;
764 unsigned char* keyToken
= (unsigned char*)RSA_get_ex_data(rsa
, hndidx
);
765 long length
= SSL_SIG_LEN
;
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
);
787 if (!algorithm
.algorithm
->length
)
789 CCA4758err(CCA4758_F_CCA_RSA_SIGN
,
790 CCA4758_R_ASN1_OID_UNKNOWN_FOR_MD
);
794 parameter
.type
= V_ASN1_NULL
;
795 parameter
.value
.ptr
= NULL
;
796 algorithm
.parameter
= ¶meter
;
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
);
817 if (m_len
!= SSL_SIG_LEN
)
819 CCA4758err(CCA4758_F_CCA_RSA_SIGN
,
820 CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL
);
823 hashBuffer
= (unsigned char*)m
;
829 ptr
= hashBuffer
= OPENSSL_malloc(
830 (unsigned int)keyLength
+1);
833 CCA4758err(CCA4758_F_CCA_RSA_SIGN
,
834 ERR_R_MALLOC_FAILURE
);
837 i2d_X509_SIG(&sig
, &ptr
);
843 ptr
= hashBuffer
= OPENSSL_malloc(
844 (unsigned int)keyLength
+1);
847 CCA4758err(CCA4758_F_CCA_RSA_SIGN
,
848 ERR_R_MALLOC_FAILURE
);
851 i2d_X509_SIG(&sig
, &ptr
);
858 digitalSignatureGenerate(&returnCode
, &reasonCode
, &exitDataLength
,
859 exitData
, &ruleArrayLength
, ruleArray
, &keyTokenLength
,
860 keyToken
, &length
, hashBuffer
, &outputLength
, &outputBitLength
,
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
)
880 if (*token
++ != (char)0x1E) /* internal PKA token? */
883 if (*token
++) /* token version must be zero */
888 len
|= (unsigned char)*token
++;
890 token
+= 4; /* skip reserved bytes */
892 if (*token
++ == (char)0x04)
894 if (*token
++) /* token version must be zero */
899 len
|= (unsigned char)*token
++;
901 token
+=2; /* skip reserved section */
905 len
|= (unsigned char)*token
++;
907 *exponentLength
= len
;
911 len
|= (unsigned char)*token
++;
913 *modulusLength
= len
;
917 len
|= (unsigned char)*token
++;
919 *modulusFieldLength
= len
;
921 memcpy(exponent
, token
, *exponentLength
);
922 token
+= *exponentLength
;
924 memcpy(modulus
, token
, *modulusFieldLength
);
930 #endif /* OPENSSL_NO_RSA */
932 static int cca_random_status(void)
937 static int cca_get_random_bytes(unsigned char* buf
, int num
)
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
);
952 num
-= sizeof(rand_buf
);
953 memcpy(buf
, rand_buf
, sizeof(rand_buf
));
954 buf
+= sizeof(rand_buf
);
959 randomNumberGenerate(&ret_code
, &reason_code
, NULL
, NULL
,
963 memcpy(buf
, rand_buf
, num
);
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
)
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))
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 */