1ebfedea0SLionel Sambuc /* Author: Maurice Gittens <maurice@gittens.nl> */
2ebfedea0SLionel Sambuc /* ====================================================================
3ebfedea0SLionel Sambuc * Copyright (c) 1999 The OpenSSL Project. All rights reserved.
4ebfedea0SLionel Sambuc *
5ebfedea0SLionel Sambuc * Redistribution and use in source and binary forms, with or without
6ebfedea0SLionel Sambuc * modification, are permitted provided that the following conditions
7ebfedea0SLionel Sambuc * are met:
8ebfedea0SLionel Sambuc *
9ebfedea0SLionel Sambuc * 1. Redistributions of source code must retain the above copyright
10ebfedea0SLionel Sambuc * notice, this list of conditions and the following disclaimer.
11ebfedea0SLionel Sambuc *
12ebfedea0SLionel Sambuc * 2. Redistributions in binary form must reproduce the above copyright
13ebfedea0SLionel Sambuc * notice, this list of conditions and the following disclaimer in
14ebfedea0SLionel Sambuc * the documentation and/or other materials provided with the
15ebfedea0SLionel Sambuc * distribution.
16ebfedea0SLionel Sambuc *
17ebfedea0SLionel Sambuc * 3. All advertising materials mentioning features or use of this
18ebfedea0SLionel Sambuc * software must display the following acknowledgment:
19ebfedea0SLionel Sambuc * "This product includes software developed by the OpenSSL Project
20ebfedea0SLionel Sambuc * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
21ebfedea0SLionel Sambuc *
22ebfedea0SLionel Sambuc * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
23ebfedea0SLionel Sambuc * endorse or promote products derived from this software without
24ebfedea0SLionel Sambuc * prior written permission. For written permission, please contact
25ebfedea0SLionel Sambuc * licensing@OpenSSL.org.
26ebfedea0SLionel Sambuc *
27ebfedea0SLionel Sambuc * 5. Products derived from this software may not be called "OpenSSL"
28ebfedea0SLionel Sambuc * nor may "OpenSSL" appear in their names without prior written
29ebfedea0SLionel Sambuc * permission of the OpenSSL Project.
30ebfedea0SLionel Sambuc *
31ebfedea0SLionel Sambuc * 6. Redistributions of any form whatsoever must retain the following
32ebfedea0SLionel Sambuc * acknowledgment:
33ebfedea0SLionel Sambuc * "This product includes software developed by the OpenSSL Project
34ebfedea0SLionel Sambuc * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
35ebfedea0SLionel Sambuc *
36ebfedea0SLionel Sambuc * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
37ebfedea0SLionel Sambuc * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
38ebfedea0SLionel Sambuc * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
39ebfedea0SLionel Sambuc * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
40ebfedea0SLionel Sambuc * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41ebfedea0SLionel Sambuc * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
42ebfedea0SLionel Sambuc * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
43ebfedea0SLionel Sambuc * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
44ebfedea0SLionel Sambuc * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
45ebfedea0SLionel Sambuc * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
46ebfedea0SLionel Sambuc * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
47ebfedea0SLionel Sambuc * OF THE POSSIBILITY OF SUCH DAMAGE.
48ebfedea0SLionel Sambuc * ====================================================================
49ebfedea0SLionel Sambuc *
50ebfedea0SLionel Sambuc * This product includes cryptographic software written by Eric Young
51ebfedea0SLionel Sambuc * (eay@cryptsoft.com). This product includes software written by Tim
52ebfedea0SLionel Sambuc * Hudson (tjh@cryptsoft.com).
53ebfedea0SLionel Sambuc *
54ebfedea0SLionel Sambuc */
55ebfedea0SLionel Sambuc
56ebfedea0SLionel Sambuc #include <stdio.h>
57ebfedea0SLionel Sambuc #include <string.h>
58ebfedea0SLionel Sambuc #include <openssl/crypto.h>
59ebfedea0SLionel Sambuc #include <openssl/dso.h>
60ebfedea0SLionel Sambuc #include <openssl/x509.h>
61ebfedea0SLionel Sambuc #include <openssl/objects.h>
62ebfedea0SLionel Sambuc #include <openssl/engine.h>
63ebfedea0SLionel Sambuc #include <openssl/rand.h>
64ebfedea0SLionel Sambuc #ifndef OPENSSL_NO_RSA
65ebfedea0SLionel Sambuc # include <openssl/rsa.h>
66ebfedea0SLionel Sambuc #endif
67ebfedea0SLionel Sambuc #include <openssl/bn.h>
68ebfedea0SLionel Sambuc
69ebfedea0SLionel Sambuc #ifndef OPENSSL_NO_HW
70ebfedea0SLionel Sambuc # ifndef OPENSSL_NO_HW_4758_CCA
71ebfedea0SLionel Sambuc
72ebfedea0SLionel Sambuc # ifdef FLAT_INC
73ebfedea0SLionel Sambuc # include "hw_4758_cca.h"
74ebfedea0SLionel Sambuc # else
75ebfedea0SLionel Sambuc # include "vendor_defns/hw_4758_cca.h"
76ebfedea0SLionel Sambuc # endif
77ebfedea0SLionel Sambuc
78ebfedea0SLionel Sambuc # include "e_4758cca_err.c"
79ebfedea0SLionel Sambuc
80ebfedea0SLionel Sambuc static int ibm_4758_cca_destroy(ENGINE *e);
81ebfedea0SLionel Sambuc static int ibm_4758_cca_init(ENGINE *e);
82ebfedea0SLionel Sambuc static int ibm_4758_cca_finish(ENGINE *e);
83*0a6a1f1dSLionel Sambuc static int ibm_4758_cca_ctrl(ENGINE *e, int cmd, long i, void *p,
84*0a6a1f1dSLionel Sambuc void (*f) (void));
85ebfedea0SLionel Sambuc
86ebfedea0SLionel Sambuc /* rsa functions */
87*0a6a1f1dSLionel Sambuc /* -------------*/
88ebfedea0SLionel Sambuc # ifndef OPENSSL_NO_RSA
89ebfedea0SLionel Sambuc static int cca_rsa_pub_enc(int flen, const unsigned char *from,
90ebfedea0SLionel Sambuc unsigned char *to, RSA *rsa, int padding);
91ebfedea0SLionel Sambuc static int cca_rsa_priv_dec(int flen, const unsigned char *from,
92ebfedea0SLionel Sambuc unsigned char *to, RSA *rsa, int padding);
93ebfedea0SLionel Sambuc static int cca_rsa_sign(int type, const unsigned char *m, unsigned int m_len,
94*0a6a1f1dSLionel Sambuc unsigned char *sigret, unsigned int *siglen,
95*0a6a1f1dSLionel Sambuc const RSA *rsa);
96*0a6a1f1dSLionel Sambuc static int cca_rsa_verify(int dtype, const unsigned char *m,
97*0a6a1f1dSLionel Sambuc unsigned int m_len, const unsigned char *sigbuf,
98*0a6a1f1dSLionel Sambuc unsigned int siglen, const RSA *rsa);
99ebfedea0SLionel Sambuc
100ebfedea0SLionel Sambuc /* utility functions */
101*0a6a1f1dSLionel Sambuc /* ---------------------*/
102ebfedea0SLionel Sambuc static EVP_PKEY *ibm_4758_load_privkey(ENGINE *, const char *,
103*0a6a1f1dSLionel Sambuc UI_METHOD *ui_method,
104*0a6a1f1dSLionel Sambuc void *callback_data);
105ebfedea0SLionel Sambuc static EVP_PKEY *ibm_4758_load_pubkey(ENGINE *, const char *,
106*0a6a1f1dSLionel Sambuc UI_METHOD *ui_method,
107*0a6a1f1dSLionel Sambuc void *callback_data);
108ebfedea0SLionel Sambuc
109*0a6a1f1dSLionel Sambuc static int getModulusAndExponent(const unsigned char *token,
110*0a6a1f1dSLionel Sambuc long *exponentLength,
111ebfedea0SLionel Sambuc unsigned char *exponent, long *modulusLength,
112*0a6a1f1dSLionel Sambuc long *modulusFieldLength,
113*0a6a1f1dSLionel Sambuc unsigned char *modulus);
114ebfedea0SLionel Sambuc # endif
115ebfedea0SLionel Sambuc
116ebfedea0SLionel Sambuc /* RAND number functions */
117*0a6a1f1dSLionel Sambuc /* ---------------------*/
118ebfedea0SLionel Sambuc static int cca_get_random_bytes(unsigned char *, int);
119ebfedea0SLionel Sambuc static int cca_random_status(void);
120ebfedea0SLionel Sambuc
121ebfedea0SLionel Sambuc # ifndef OPENSSL_NO_RSA
122ebfedea0SLionel Sambuc static void cca_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad,
123ebfedea0SLionel Sambuc int idx, long argl, void *argp);
124ebfedea0SLionel Sambuc # endif
125ebfedea0SLionel Sambuc
126ebfedea0SLionel Sambuc /* Function pointers for CCA verbs */
127*0a6a1f1dSLionel Sambuc /* -------------------------------*/
128ebfedea0SLionel Sambuc # ifndef OPENSSL_NO_RSA
129ebfedea0SLionel Sambuc static F_KEYRECORDREAD keyRecordRead;
130ebfedea0SLionel Sambuc static F_DIGITALSIGNATUREGENERATE digitalSignatureGenerate;
131ebfedea0SLionel Sambuc static F_DIGITALSIGNATUREVERIFY digitalSignatureVerify;
132ebfedea0SLionel Sambuc static F_PUBLICKEYEXTRACT publicKeyExtract;
133ebfedea0SLionel Sambuc static F_PKAENCRYPT pkaEncrypt;
134ebfedea0SLionel Sambuc static F_PKADECRYPT pkaDecrypt;
135ebfedea0SLionel Sambuc # endif
136ebfedea0SLionel Sambuc static F_RANDOMNUMBERGENERATE randomNumberGenerate;
137ebfedea0SLionel Sambuc
138ebfedea0SLionel Sambuc /* static variables */
139*0a6a1f1dSLionel Sambuc /* ----------------*/
140ebfedea0SLionel Sambuc static const char *CCA4758_LIB_NAME = NULL;
get_CCA4758_LIB_NAME(void)141ebfedea0SLionel Sambuc static const char *get_CCA4758_LIB_NAME(void)
142ebfedea0SLionel Sambuc {
143ebfedea0SLionel Sambuc if (CCA4758_LIB_NAME)
144ebfedea0SLionel Sambuc return CCA4758_LIB_NAME;
145ebfedea0SLionel Sambuc return CCA_LIB_NAME;
146ebfedea0SLionel Sambuc }
147*0a6a1f1dSLionel Sambuc
free_CCA4758_LIB_NAME(void)148ebfedea0SLionel Sambuc static void free_CCA4758_LIB_NAME(void)
149ebfedea0SLionel Sambuc {
150ebfedea0SLionel Sambuc if (CCA4758_LIB_NAME)
151ebfedea0SLionel Sambuc OPENSSL_free((void *)CCA4758_LIB_NAME);
152ebfedea0SLionel Sambuc CCA4758_LIB_NAME = NULL;
153ebfedea0SLionel Sambuc }
154*0a6a1f1dSLionel Sambuc
set_CCA4758_LIB_NAME(const char * name)155ebfedea0SLionel Sambuc static long set_CCA4758_LIB_NAME(const char *name)
156ebfedea0SLionel Sambuc {
157ebfedea0SLionel Sambuc free_CCA4758_LIB_NAME();
158ebfedea0SLionel Sambuc return (((CCA4758_LIB_NAME = BUF_strdup(name)) != NULL) ? 1 : 0);
159ebfedea0SLionel Sambuc }
160*0a6a1f1dSLionel Sambuc
161ebfedea0SLionel Sambuc # ifndef OPENSSL_NO_RSA
162ebfedea0SLionel Sambuc static const char *n_keyRecordRead = CSNDKRR;
163ebfedea0SLionel Sambuc static const char *n_digitalSignatureGenerate = CSNDDSG;
164ebfedea0SLionel Sambuc static const char *n_digitalSignatureVerify = CSNDDSV;
165ebfedea0SLionel Sambuc static const char *n_publicKeyExtract = CSNDPKX;
166ebfedea0SLionel Sambuc static const char *n_pkaEncrypt = CSNDPKE;
167ebfedea0SLionel Sambuc static const char *n_pkaDecrypt = CSNDPKD;
168ebfedea0SLionel Sambuc # endif
169ebfedea0SLionel Sambuc static const char *n_randomNumberGenerate = CSNBRNG;
170ebfedea0SLionel Sambuc
171ebfedea0SLionel Sambuc # ifndef OPENSSL_NO_RSA
172ebfedea0SLionel Sambuc static int hndidx = -1;
173ebfedea0SLionel Sambuc # endif
174ebfedea0SLionel Sambuc static DSO *dso = NULL;
175ebfedea0SLionel Sambuc
176ebfedea0SLionel Sambuc /* openssl engine initialization structures */
177*0a6a1f1dSLionel Sambuc /* ----------------------------------------*/
178ebfedea0SLionel Sambuc
179ebfedea0SLionel Sambuc # define CCA4758_CMD_SO_PATH ENGINE_CMD_BASE
180ebfedea0SLionel Sambuc static const ENGINE_CMD_DEFN cca4758_cmd_defns[] = {
181ebfedea0SLionel Sambuc {CCA4758_CMD_SO_PATH,
182ebfedea0SLionel Sambuc "SO_PATH",
183ebfedea0SLionel Sambuc "Specifies the path to the '4758cca' shared library",
184ebfedea0SLionel Sambuc ENGINE_CMD_FLAG_STRING},
185ebfedea0SLionel Sambuc {0, NULL, NULL, 0}
186ebfedea0SLionel Sambuc };
187ebfedea0SLionel Sambuc
188ebfedea0SLionel Sambuc # ifndef OPENSSL_NO_RSA
189*0a6a1f1dSLionel Sambuc static RSA_METHOD ibm_4758_cca_rsa = {
190ebfedea0SLionel Sambuc "IBM 4758 CCA RSA method",
191ebfedea0SLionel Sambuc cca_rsa_pub_enc,
192ebfedea0SLionel Sambuc NULL,
193ebfedea0SLionel Sambuc NULL,
194ebfedea0SLionel Sambuc cca_rsa_priv_dec,
195ebfedea0SLionel Sambuc NULL, /* rsa_mod_exp, */
196ebfedea0SLionel Sambuc NULL, /* mod_exp_mont, */
197ebfedea0SLionel Sambuc NULL, /* init */
198ebfedea0SLionel Sambuc NULL, /* finish */
199ebfedea0SLionel Sambuc RSA_FLAG_SIGN_VER, /* flags */
200ebfedea0SLionel Sambuc NULL, /* app_data */
201ebfedea0SLionel Sambuc cca_rsa_sign, /* rsa_sign */
202ebfedea0SLionel Sambuc cca_rsa_verify, /* rsa_verify */
203ebfedea0SLionel Sambuc NULL /* rsa_keygen */
204ebfedea0SLionel Sambuc };
205ebfedea0SLionel Sambuc # endif
206ebfedea0SLionel Sambuc
207*0a6a1f1dSLionel Sambuc static RAND_METHOD ibm_4758_cca_rand = {
208ebfedea0SLionel Sambuc /* "IBM 4758 RAND method", */
209ebfedea0SLionel Sambuc NULL, /* seed */
210ebfedea0SLionel Sambuc cca_get_random_bytes, /* get random bytes from the card */
211ebfedea0SLionel Sambuc NULL, /* cleanup */
212ebfedea0SLionel Sambuc NULL, /* add */
213ebfedea0SLionel Sambuc cca_get_random_bytes, /* pseudo rand */
214ebfedea0SLionel Sambuc cca_random_status, /* status */
215ebfedea0SLionel Sambuc };
216ebfedea0SLionel Sambuc
217ebfedea0SLionel Sambuc static const char *engine_4758_cca_id = "4758cca";
218*0a6a1f1dSLionel Sambuc static const char *engine_4758_cca_name =
219*0a6a1f1dSLionel Sambuc "IBM 4758 CCA hardware engine support";
220ebfedea0SLionel Sambuc # ifndef OPENSSL_NO_DYNAMIC_ENGINE
221ebfedea0SLionel Sambuc /* Compatibility hack, the dynamic library uses this form in the path */
222ebfedea0SLionel Sambuc static const char *engine_4758_cca_id_alt = "4758_cca";
223ebfedea0SLionel Sambuc # endif
224ebfedea0SLionel Sambuc
225ebfedea0SLionel Sambuc /* engine implementation */
226*0a6a1f1dSLionel Sambuc /* ---------------------*/
bind_helper(ENGINE * e)227ebfedea0SLionel Sambuc static int bind_helper(ENGINE *e)
228ebfedea0SLionel Sambuc {
229ebfedea0SLionel Sambuc if (!ENGINE_set_id(e, engine_4758_cca_id) ||
230ebfedea0SLionel Sambuc !ENGINE_set_name(e, engine_4758_cca_name) ||
231ebfedea0SLionel Sambuc # ifndef OPENSSL_NO_RSA
232ebfedea0SLionel Sambuc !ENGINE_set_RSA(e, &ibm_4758_cca_rsa) ||
233ebfedea0SLionel Sambuc # endif
234ebfedea0SLionel Sambuc !ENGINE_set_RAND(e, &ibm_4758_cca_rand) ||
235ebfedea0SLionel Sambuc !ENGINE_set_destroy_function(e, ibm_4758_cca_destroy) ||
236ebfedea0SLionel Sambuc !ENGINE_set_init_function(e, ibm_4758_cca_init) ||
237ebfedea0SLionel Sambuc !ENGINE_set_finish_function(e, ibm_4758_cca_finish) ||
238ebfedea0SLionel Sambuc !ENGINE_set_ctrl_function(e, ibm_4758_cca_ctrl) ||
239ebfedea0SLionel Sambuc # ifndef OPENSSL_NO_RSA
240ebfedea0SLionel Sambuc !ENGINE_set_load_privkey_function(e, ibm_4758_load_privkey) ||
241ebfedea0SLionel Sambuc !ENGINE_set_load_pubkey_function(e, ibm_4758_load_pubkey) ||
242ebfedea0SLionel Sambuc # endif
243ebfedea0SLionel Sambuc !ENGINE_set_cmd_defns(e, cca4758_cmd_defns))
244ebfedea0SLionel Sambuc return 0;
245ebfedea0SLionel Sambuc /* Ensure the error handling is set up */
246ebfedea0SLionel Sambuc ERR_load_CCA4758_strings();
247ebfedea0SLionel Sambuc return 1;
248ebfedea0SLionel Sambuc }
249ebfedea0SLionel Sambuc
250ebfedea0SLionel Sambuc # ifdef OPENSSL_NO_DYNAMIC_ENGINE
engine_4758_cca(void)251ebfedea0SLionel Sambuc static ENGINE *engine_4758_cca(void)
252ebfedea0SLionel Sambuc {
253ebfedea0SLionel Sambuc ENGINE *ret = ENGINE_new();
254ebfedea0SLionel Sambuc if (!ret)
255ebfedea0SLionel Sambuc return NULL;
256*0a6a1f1dSLionel Sambuc if (!bind_helper(ret)) {
257ebfedea0SLionel Sambuc ENGINE_free(ret);
258ebfedea0SLionel Sambuc return NULL;
259ebfedea0SLionel Sambuc }
260ebfedea0SLionel Sambuc return ret;
261ebfedea0SLionel Sambuc }
262ebfedea0SLionel Sambuc
ENGINE_load_4758cca(void)263ebfedea0SLionel Sambuc void ENGINE_load_4758cca(void)
264ebfedea0SLionel Sambuc {
265ebfedea0SLionel Sambuc ENGINE *e_4758 = engine_4758_cca();
266*0a6a1f1dSLionel Sambuc if (!e_4758)
267*0a6a1f1dSLionel Sambuc return;
268ebfedea0SLionel Sambuc ENGINE_add(e_4758);
269ebfedea0SLionel Sambuc ENGINE_free(e_4758);
270ebfedea0SLionel Sambuc ERR_clear_error();
271ebfedea0SLionel Sambuc }
272ebfedea0SLionel Sambuc # endif
273ebfedea0SLionel Sambuc
ibm_4758_cca_destroy(ENGINE * e)274ebfedea0SLionel Sambuc static int ibm_4758_cca_destroy(ENGINE *e)
275ebfedea0SLionel Sambuc {
276ebfedea0SLionel Sambuc ERR_unload_CCA4758_strings();
277ebfedea0SLionel Sambuc free_CCA4758_LIB_NAME();
278ebfedea0SLionel Sambuc return 1;
279ebfedea0SLionel Sambuc }
280ebfedea0SLionel Sambuc
ibm_4758_cca_init(ENGINE * e)281ebfedea0SLionel Sambuc static int ibm_4758_cca_init(ENGINE *e)
282ebfedea0SLionel Sambuc {
283*0a6a1f1dSLionel Sambuc if (dso) {
284ebfedea0SLionel Sambuc CCA4758err(CCA4758_F_IBM_4758_CCA_INIT, CCA4758_R_ALREADY_LOADED);
285ebfedea0SLionel Sambuc goto err;
286ebfedea0SLionel Sambuc }
287ebfedea0SLionel Sambuc
288ebfedea0SLionel Sambuc dso = DSO_load(NULL, get_CCA4758_LIB_NAME(), NULL, 0);
289*0a6a1f1dSLionel Sambuc if (!dso) {
290ebfedea0SLionel Sambuc CCA4758err(CCA4758_F_IBM_4758_CCA_INIT, CCA4758_R_DSO_FAILURE);
291ebfedea0SLionel Sambuc goto err;
292ebfedea0SLionel Sambuc }
293ebfedea0SLionel Sambuc # ifndef OPENSSL_NO_RSA
294ebfedea0SLionel Sambuc if (!(keyRecordRead = (F_KEYRECORDREAD)
295ebfedea0SLionel Sambuc DSO_bind_func(dso, n_keyRecordRead)) ||
296ebfedea0SLionel Sambuc !(randomNumberGenerate = (F_RANDOMNUMBERGENERATE)
297ebfedea0SLionel Sambuc DSO_bind_func(dso, n_randomNumberGenerate)) ||
298ebfedea0SLionel Sambuc !(digitalSignatureGenerate = (F_DIGITALSIGNATUREGENERATE)
299ebfedea0SLionel Sambuc DSO_bind_func(dso, n_digitalSignatureGenerate)) ||
300ebfedea0SLionel Sambuc !(digitalSignatureVerify = (F_DIGITALSIGNATUREVERIFY)
301ebfedea0SLionel Sambuc DSO_bind_func(dso, n_digitalSignatureVerify)) ||
302ebfedea0SLionel Sambuc !(publicKeyExtract = (F_PUBLICKEYEXTRACT)
303ebfedea0SLionel Sambuc DSO_bind_func(dso, n_publicKeyExtract)) ||
304ebfedea0SLionel Sambuc !(pkaEncrypt = (F_PKAENCRYPT)
305*0a6a1f1dSLionel Sambuc DSO_bind_func(dso, n_pkaEncrypt)) || !(pkaDecrypt = (F_PKADECRYPT)
306*0a6a1f1dSLionel Sambuc DSO_bind_func(dso,
307*0a6a1f1dSLionel Sambuc n_pkaDecrypt)))
308ebfedea0SLionel Sambuc {
309ebfedea0SLionel Sambuc CCA4758err(CCA4758_F_IBM_4758_CCA_INIT, CCA4758_R_DSO_FAILURE);
310ebfedea0SLionel Sambuc goto err;
311ebfedea0SLionel Sambuc }
312ebfedea0SLionel Sambuc # else
313ebfedea0SLionel Sambuc if (!(randomNumberGenerate = (F_RANDOMNUMBERGENERATE)
314*0a6a1f1dSLionel Sambuc DSO_bind_func(dso, n_randomNumberGenerate))) {
315ebfedea0SLionel Sambuc CCA4758err(CCA4758_F_IBM_4758_CCA_INIT, CCA4758_R_DSO_FAILURE);
316ebfedea0SLionel Sambuc goto err;
317ebfedea0SLionel Sambuc }
318ebfedea0SLionel Sambuc # endif
319ebfedea0SLionel Sambuc
320ebfedea0SLionel Sambuc # ifndef OPENSSL_NO_RSA
321ebfedea0SLionel Sambuc hndidx = RSA_get_ex_new_index(0, "IBM 4758 CCA RSA key handle",
322ebfedea0SLionel Sambuc NULL, NULL, cca_ex_free);
323ebfedea0SLionel Sambuc # endif
324ebfedea0SLionel Sambuc
325ebfedea0SLionel Sambuc return 1;
326ebfedea0SLionel Sambuc err:
327ebfedea0SLionel Sambuc if (dso)
328ebfedea0SLionel Sambuc DSO_free(dso);
329ebfedea0SLionel Sambuc dso = NULL;
330ebfedea0SLionel Sambuc
331ebfedea0SLionel Sambuc # ifndef OPENSSL_NO_RSA
332ebfedea0SLionel Sambuc keyRecordRead = (F_KEYRECORDREAD) 0;
333ebfedea0SLionel Sambuc digitalSignatureGenerate = (F_DIGITALSIGNATUREGENERATE) 0;
334ebfedea0SLionel Sambuc digitalSignatureVerify = (F_DIGITALSIGNATUREVERIFY)0;
335ebfedea0SLionel Sambuc publicKeyExtract = (F_PUBLICKEYEXTRACT)0;
336ebfedea0SLionel Sambuc pkaEncrypt = (F_PKAENCRYPT) 0;
337ebfedea0SLionel Sambuc pkaDecrypt = (F_PKADECRYPT) 0;
338ebfedea0SLionel Sambuc # endif
339ebfedea0SLionel Sambuc randomNumberGenerate = (F_RANDOMNUMBERGENERATE) 0;
340ebfedea0SLionel Sambuc return 0;
341ebfedea0SLionel Sambuc }
342ebfedea0SLionel Sambuc
ibm_4758_cca_finish(ENGINE * e)343ebfedea0SLionel Sambuc static int ibm_4758_cca_finish(ENGINE *e)
344ebfedea0SLionel Sambuc {
345ebfedea0SLionel Sambuc free_CCA4758_LIB_NAME();
346*0a6a1f1dSLionel Sambuc if (!dso) {
347*0a6a1f1dSLionel Sambuc CCA4758err(CCA4758_F_IBM_4758_CCA_FINISH, CCA4758_R_NOT_LOADED);
348ebfedea0SLionel Sambuc return 0;
349ebfedea0SLionel Sambuc }
350*0a6a1f1dSLionel Sambuc if (!DSO_free(dso)) {
351*0a6a1f1dSLionel Sambuc CCA4758err(CCA4758_F_IBM_4758_CCA_FINISH, CCA4758_R_UNIT_FAILURE);
352ebfedea0SLionel Sambuc return 0;
353ebfedea0SLionel Sambuc }
354ebfedea0SLionel Sambuc dso = NULL;
355ebfedea0SLionel Sambuc # ifndef OPENSSL_NO_RSA
356ebfedea0SLionel Sambuc keyRecordRead = (F_KEYRECORDREAD) 0;
357ebfedea0SLionel Sambuc randomNumberGenerate = (F_RANDOMNUMBERGENERATE) 0;
358ebfedea0SLionel Sambuc digitalSignatureGenerate = (F_DIGITALSIGNATUREGENERATE) 0;
359ebfedea0SLionel Sambuc digitalSignatureVerify = (F_DIGITALSIGNATUREVERIFY)0;
360ebfedea0SLionel Sambuc publicKeyExtract = (F_PUBLICKEYEXTRACT)0;
361ebfedea0SLionel Sambuc pkaEncrypt = (F_PKAENCRYPT) 0;
362ebfedea0SLionel Sambuc pkaDecrypt = (F_PKADECRYPT) 0;
363ebfedea0SLionel Sambuc # endif
364ebfedea0SLionel Sambuc randomNumberGenerate = (F_RANDOMNUMBERGENERATE) 0;
365ebfedea0SLionel Sambuc return 1;
366ebfedea0SLionel Sambuc }
367ebfedea0SLionel Sambuc
ibm_4758_cca_ctrl(ENGINE * e,int cmd,long i,void * p,void (* f)(void))368*0a6a1f1dSLionel Sambuc static int ibm_4758_cca_ctrl(ENGINE *e, int cmd, long i, void *p,
369*0a6a1f1dSLionel Sambuc void (*f) (void))
370ebfedea0SLionel Sambuc {
371ebfedea0SLionel Sambuc int initialised = ((dso == NULL) ? 0 : 1);
372*0a6a1f1dSLionel Sambuc switch (cmd) {
373ebfedea0SLionel Sambuc case CCA4758_CMD_SO_PATH:
374*0a6a1f1dSLionel Sambuc if (p == NULL) {
375ebfedea0SLionel Sambuc CCA4758err(CCA4758_F_IBM_4758_CCA_CTRL,
376ebfedea0SLionel Sambuc ERR_R_PASSED_NULL_PARAMETER);
377ebfedea0SLionel Sambuc return 0;
378ebfedea0SLionel Sambuc }
379*0a6a1f1dSLionel Sambuc if (initialised) {
380*0a6a1f1dSLionel Sambuc CCA4758err(CCA4758_F_IBM_4758_CCA_CTRL, CCA4758_R_ALREADY_LOADED);
381ebfedea0SLionel Sambuc return 0;
382ebfedea0SLionel Sambuc }
383ebfedea0SLionel Sambuc return set_CCA4758_LIB_NAME((const char *)p);
384ebfedea0SLionel Sambuc default:
385ebfedea0SLionel Sambuc break;
386ebfedea0SLionel Sambuc }
387ebfedea0SLionel Sambuc CCA4758err(CCA4758_F_IBM_4758_CCA_CTRL,
388ebfedea0SLionel Sambuc CCA4758_R_COMMAND_NOT_IMPLEMENTED);
389ebfedea0SLionel Sambuc return 0;
390ebfedea0SLionel Sambuc }
391ebfedea0SLionel Sambuc
392ebfedea0SLionel Sambuc # ifndef OPENSSL_NO_RSA
393ebfedea0SLionel Sambuc
394ebfedea0SLionel Sambuc # define MAX_CCA_PKA_TOKEN_SIZE 2500
395ebfedea0SLionel Sambuc
ibm_4758_load_privkey(ENGINE * e,const char * key_id,UI_METHOD * ui_method,void * callback_data)396ebfedea0SLionel Sambuc static EVP_PKEY *ibm_4758_load_privkey(ENGINE *e, const char *key_id,
397*0a6a1f1dSLionel Sambuc UI_METHOD *ui_method,
398*0a6a1f1dSLionel Sambuc void *callback_data)
399ebfedea0SLionel Sambuc {
400ebfedea0SLionel Sambuc RSA *rtmp = NULL;
401ebfedea0SLionel Sambuc EVP_PKEY *res = NULL;
402ebfedea0SLionel Sambuc unsigned char *keyToken = NULL;
403ebfedea0SLionel Sambuc unsigned char pubKeyToken[MAX_CCA_PKA_TOKEN_SIZE];
404ebfedea0SLionel Sambuc long pubKeyTokenLength = MAX_CCA_PKA_TOKEN_SIZE;
405ebfedea0SLionel Sambuc long keyTokenLength = MAX_CCA_PKA_TOKEN_SIZE;
406ebfedea0SLionel Sambuc long returnCode;
407ebfedea0SLionel Sambuc long reasonCode;
408ebfedea0SLionel Sambuc long exitDataLength = 0;
409ebfedea0SLionel Sambuc long ruleArrayLength = 0;
410ebfedea0SLionel Sambuc unsigned char exitData[8];
411ebfedea0SLionel Sambuc unsigned char ruleArray[8];
412ebfedea0SLionel Sambuc unsigned char keyLabel[64];
413ebfedea0SLionel Sambuc unsigned long keyLabelLength = strlen(key_id);
414ebfedea0SLionel Sambuc unsigned char modulus[256];
415ebfedea0SLionel Sambuc long modulusFieldLength = sizeof(modulus);
416ebfedea0SLionel Sambuc long modulusLength = 0;
417ebfedea0SLionel Sambuc unsigned char exponent[256];
418ebfedea0SLionel Sambuc long exponentLength = sizeof(exponent);
419ebfedea0SLionel Sambuc
420*0a6a1f1dSLionel Sambuc if (keyLabelLength > sizeof(keyLabel)) {
421ebfedea0SLionel Sambuc CCA4758err(CCA4758_F_IBM_4758_LOAD_PRIVKEY,
422ebfedea0SLionel Sambuc CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
423ebfedea0SLionel Sambuc return NULL;
424ebfedea0SLionel Sambuc }
425ebfedea0SLionel Sambuc
426ebfedea0SLionel Sambuc memset(keyLabel, ' ', sizeof(keyLabel));
427ebfedea0SLionel Sambuc memcpy(keyLabel, key_id, keyLabelLength);
428ebfedea0SLionel Sambuc
429ebfedea0SLionel Sambuc keyToken = OPENSSL_malloc(MAX_CCA_PKA_TOKEN_SIZE + sizeof(long));
430*0a6a1f1dSLionel Sambuc if (!keyToken) {
431*0a6a1f1dSLionel Sambuc CCA4758err(CCA4758_F_IBM_4758_LOAD_PRIVKEY, ERR_R_MALLOC_FAILURE);
432ebfedea0SLionel Sambuc goto err;
433ebfedea0SLionel Sambuc }
434ebfedea0SLionel Sambuc
435ebfedea0SLionel Sambuc keyRecordRead(&returnCode, &reasonCode, &exitDataLength,
436ebfedea0SLionel Sambuc exitData, &ruleArrayLength, ruleArray, keyLabel,
437ebfedea0SLionel Sambuc &keyTokenLength, keyToken + sizeof(long));
438ebfedea0SLionel Sambuc
439*0a6a1f1dSLionel Sambuc if (returnCode) {
440ebfedea0SLionel Sambuc CCA4758err(CCA4758_F_IBM_4758_LOAD_PRIVKEY,
441ebfedea0SLionel Sambuc CCA4758_R_FAILED_LOADING_PRIVATE_KEY);
442ebfedea0SLionel Sambuc goto err;
443ebfedea0SLionel Sambuc }
444ebfedea0SLionel Sambuc
445ebfedea0SLionel Sambuc publicKeyExtract(&returnCode, &reasonCode, &exitDataLength,
446ebfedea0SLionel Sambuc exitData, &ruleArrayLength, ruleArray, &keyTokenLength,
447*0a6a1f1dSLionel Sambuc keyToken + sizeof(long), &pubKeyTokenLength,
448*0a6a1f1dSLionel Sambuc pubKeyToken);
449ebfedea0SLionel Sambuc
450*0a6a1f1dSLionel Sambuc if (returnCode) {
451ebfedea0SLionel Sambuc CCA4758err(CCA4758_F_IBM_4758_LOAD_PRIVKEY,
452ebfedea0SLionel Sambuc CCA4758_R_FAILED_LOADING_PRIVATE_KEY);
453ebfedea0SLionel Sambuc goto err;
454ebfedea0SLionel Sambuc }
455ebfedea0SLionel Sambuc
456ebfedea0SLionel Sambuc if (!getModulusAndExponent(pubKeyToken, &exponentLength,
457ebfedea0SLionel Sambuc exponent, &modulusLength, &modulusFieldLength,
458*0a6a1f1dSLionel Sambuc modulus)) {
459ebfedea0SLionel Sambuc CCA4758err(CCA4758_F_IBM_4758_LOAD_PRIVKEY,
460ebfedea0SLionel Sambuc CCA4758_R_FAILED_LOADING_PRIVATE_KEY);
461ebfedea0SLionel Sambuc goto err;
462ebfedea0SLionel Sambuc }
463ebfedea0SLionel Sambuc
464ebfedea0SLionel Sambuc (*(long *)keyToken) = keyTokenLength;
465ebfedea0SLionel Sambuc rtmp = RSA_new_method(e);
466ebfedea0SLionel Sambuc RSA_set_ex_data(rtmp, hndidx, (char *)keyToken);
467ebfedea0SLionel Sambuc
468ebfedea0SLionel Sambuc rtmp->e = BN_bin2bn(exponent, exponentLength, NULL);
469ebfedea0SLionel Sambuc rtmp->n = BN_bin2bn(modulus, modulusFieldLength, NULL);
470ebfedea0SLionel Sambuc rtmp->flags |= RSA_FLAG_EXT_PKEY;
471ebfedea0SLionel Sambuc
472ebfedea0SLionel Sambuc res = EVP_PKEY_new();
473ebfedea0SLionel Sambuc EVP_PKEY_assign_RSA(res, rtmp);
474ebfedea0SLionel Sambuc
475ebfedea0SLionel Sambuc return res;
476ebfedea0SLionel Sambuc err:
477ebfedea0SLionel Sambuc if (keyToken)
478ebfedea0SLionel Sambuc OPENSSL_free(keyToken);
479ebfedea0SLionel Sambuc return NULL;
480ebfedea0SLionel Sambuc }
481ebfedea0SLionel Sambuc
ibm_4758_load_pubkey(ENGINE * e,const char * key_id,UI_METHOD * ui_method,void * callback_data)482ebfedea0SLionel Sambuc static EVP_PKEY *ibm_4758_load_pubkey(ENGINE *e, const char *key_id,
483*0a6a1f1dSLionel Sambuc UI_METHOD *ui_method,
484*0a6a1f1dSLionel Sambuc void *callback_data)
485ebfedea0SLionel Sambuc {
486ebfedea0SLionel Sambuc RSA *rtmp = NULL;
487ebfedea0SLionel Sambuc EVP_PKEY *res = NULL;
488ebfedea0SLionel Sambuc unsigned char *keyToken = NULL;
489ebfedea0SLionel Sambuc long keyTokenLength = MAX_CCA_PKA_TOKEN_SIZE;
490ebfedea0SLionel Sambuc long returnCode;
491ebfedea0SLionel Sambuc long reasonCode;
492ebfedea0SLionel Sambuc long exitDataLength = 0;
493ebfedea0SLionel Sambuc long ruleArrayLength = 0;
494ebfedea0SLionel Sambuc unsigned char exitData[8];
495ebfedea0SLionel Sambuc unsigned char ruleArray[8];
496ebfedea0SLionel Sambuc unsigned char keyLabel[64];
497ebfedea0SLionel Sambuc unsigned long keyLabelLength = strlen(key_id);
498ebfedea0SLionel Sambuc unsigned char modulus[512];
499ebfedea0SLionel Sambuc long modulusFieldLength = sizeof(modulus);
500ebfedea0SLionel Sambuc long modulusLength = 0;
501ebfedea0SLionel Sambuc unsigned char exponent[512];
502ebfedea0SLionel Sambuc long exponentLength = sizeof(exponent);
503ebfedea0SLionel Sambuc
504*0a6a1f1dSLionel Sambuc if (keyLabelLength > sizeof(keyLabel)) {
505ebfedea0SLionel Sambuc CCA4758err(CCA4758_F_IBM_4758_LOAD_PUBKEY,
506ebfedea0SLionel Sambuc CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
507ebfedea0SLionel Sambuc return NULL;
508ebfedea0SLionel Sambuc }
509ebfedea0SLionel Sambuc
510ebfedea0SLionel Sambuc memset(keyLabel, ' ', sizeof(keyLabel));
511ebfedea0SLionel Sambuc memcpy(keyLabel, key_id, keyLabelLength);
512ebfedea0SLionel Sambuc
513ebfedea0SLionel Sambuc keyToken = OPENSSL_malloc(MAX_CCA_PKA_TOKEN_SIZE + sizeof(long));
514*0a6a1f1dSLionel Sambuc if (!keyToken) {
515*0a6a1f1dSLionel Sambuc CCA4758err(CCA4758_F_IBM_4758_LOAD_PUBKEY, ERR_R_MALLOC_FAILURE);
516ebfedea0SLionel Sambuc goto err;
517ebfedea0SLionel Sambuc }
518ebfedea0SLionel Sambuc
519ebfedea0SLionel Sambuc keyRecordRead(&returnCode, &reasonCode, &exitDataLength, exitData,
520ebfedea0SLionel Sambuc &ruleArrayLength, ruleArray, keyLabel, &keyTokenLength,
521ebfedea0SLionel Sambuc keyToken + sizeof(long));
522ebfedea0SLionel Sambuc
523*0a6a1f1dSLionel Sambuc if (returnCode) {
524*0a6a1f1dSLionel Sambuc CCA4758err(CCA4758_F_IBM_4758_LOAD_PUBKEY, ERR_R_MALLOC_FAILURE);
525ebfedea0SLionel Sambuc goto err;
526ebfedea0SLionel Sambuc }
527ebfedea0SLionel Sambuc
528ebfedea0SLionel Sambuc if (!getModulusAndExponent(keyToken + sizeof(long), &exponentLength,
529*0a6a1f1dSLionel Sambuc exponent, &modulusLength, &modulusFieldLength,
530*0a6a1f1dSLionel Sambuc modulus)) {
531ebfedea0SLionel Sambuc CCA4758err(CCA4758_F_IBM_4758_LOAD_PUBKEY,
532ebfedea0SLionel Sambuc CCA4758_R_FAILED_LOADING_PUBLIC_KEY);
533ebfedea0SLionel Sambuc goto err;
534ebfedea0SLionel Sambuc }
535ebfedea0SLionel Sambuc
536ebfedea0SLionel Sambuc (*(long *)keyToken) = keyTokenLength;
537ebfedea0SLionel Sambuc rtmp = RSA_new_method(e);
538ebfedea0SLionel Sambuc RSA_set_ex_data(rtmp, hndidx, (char *)keyToken);
539ebfedea0SLionel Sambuc rtmp->e = BN_bin2bn(exponent, exponentLength, NULL);
540ebfedea0SLionel Sambuc rtmp->n = BN_bin2bn(modulus, modulusFieldLength, NULL);
541ebfedea0SLionel Sambuc rtmp->flags |= RSA_FLAG_EXT_PKEY;
542ebfedea0SLionel Sambuc res = EVP_PKEY_new();
543ebfedea0SLionel Sambuc EVP_PKEY_assign_RSA(res, rtmp);
544ebfedea0SLionel Sambuc
545ebfedea0SLionel Sambuc return res;
546ebfedea0SLionel Sambuc err:
547ebfedea0SLionel Sambuc if (keyToken)
548ebfedea0SLionel Sambuc OPENSSL_free(keyToken);
549ebfedea0SLionel Sambuc return NULL;
550ebfedea0SLionel Sambuc }
551ebfedea0SLionel Sambuc
cca_rsa_pub_enc(int flen,const unsigned char * from,unsigned char * to,RSA * rsa,int padding)552ebfedea0SLionel Sambuc static int cca_rsa_pub_enc(int flen, const unsigned char *from,
553ebfedea0SLionel Sambuc unsigned char *to, RSA *rsa, int padding)
554ebfedea0SLionel Sambuc {
555ebfedea0SLionel Sambuc long returnCode;
556ebfedea0SLionel Sambuc long reasonCode;
557ebfedea0SLionel Sambuc long lflen = flen;
558ebfedea0SLionel Sambuc long exitDataLength = 0;
559ebfedea0SLionel Sambuc unsigned char exitData[8];
560ebfedea0SLionel Sambuc long ruleArrayLength = 1;
561ebfedea0SLionel Sambuc unsigned char ruleArray[8] = "PKCS-1.2";
562ebfedea0SLionel Sambuc long dataStructureLength = 0;
563ebfedea0SLionel Sambuc unsigned char dataStructure[8];
564ebfedea0SLionel Sambuc long outputLength = RSA_size(rsa);
565ebfedea0SLionel Sambuc long keyTokenLength;
566ebfedea0SLionel Sambuc unsigned char *keyToken = (unsigned char *)RSA_get_ex_data(rsa, hndidx);
567ebfedea0SLionel Sambuc
568ebfedea0SLionel Sambuc keyTokenLength = *(long *)keyToken;
569ebfedea0SLionel Sambuc keyToken += sizeof(long);
570ebfedea0SLionel Sambuc
571ebfedea0SLionel Sambuc pkaEncrypt(&returnCode, &reasonCode, &exitDataLength, exitData,
572ebfedea0SLionel Sambuc &ruleArrayLength, ruleArray, &lflen, (unsigned char *)from,
573ebfedea0SLionel Sambuc &dataStructureLength, dataStructure, &keyTokenLength,
574ebfedea0SLionel Sambuc keyToken, &outputLength, to);
575ebfedea0SLionel Sambuc
576ebfedea0SLionel Sambuc if (returnCode || reasonCode)
577ebfedea0SLionel Sambuc return -(returnCode << 16 | reasonCode);
578ebfedea0SLionel Sambuc return outputLength;
579ebfedea0SLionel Sambuc }
580ebfedea0SLionel Sambuc
cca_rsa_priv_dec(int flen,const unsigned char * from,unsigned char * to,RSA * rsa,int padding)581ebfedea0SLionel Sambuc static int cca_rsa_priv_dec(int flen, const unsigned char *from,
582ebfedea0SLionel Sambuc unsigned char *to, RSA *rsa, int padding)
583ebfedea0SLionel Sambuc {
584ebfedea0SLionel Sambuc long returnCode;
585ebfedea0SLionel Sambuc long reasonCode;
586ebfedea0SLionel Sambuc long lflen = flen;
587ebfedea0SLionel Sambuc long exitDataLength = 0;
588ebfedea0SLionel Sambuc unsigned char exitData[8];
589ebfedea0SLionel Sambuc long ruleArrayLength = 1;
590ebfedea0SLionel Sambuc unsigned char ruleArray[8] = "PKCS-1.2";
591ebfedea0SLionel Sambuc long dataStructureLength = 0;
592ebfedea0SLionel Sambuc unsigned char dataStructure[8];
593ebfedea0SLionel Sambuc long outputLength = RSA_size(rsa);
594ebfedea0SLionel Sambuc long keyTokenLength;
595ebfedea0SLionel Sambuc unsigned char *keyToken = (unsigned char *)RSA_get_ex_data(rsa, hndidx);
596ebfedea0SLionel Sambuc
597ebfedea0SLionel Sambuc keyTokenLength = *(long *)keyToken;
598ebfedea0SLionel Sambuc keyToken += sizeof(long);
599ebfedea0SLionel Sambuc
600ebfedea0SLionel Sambuc pkaDecrypt(&returnCode, &reasonCode, &exitDataLength, exitData,
601ebfedea0SLionel Sambuc &ruleArrayLength, ruleArray, &lflen, (unsigned char *)from,
602ebfedea0SLionel Sambuc &dataStructureLength, dataStructure, &keyTokenLength,
603ebfedea0SLionel Sambuc keyToken, &outputLength, to);
604ebfedea0SLionel Sambuc
605ebfedea0SLionel Sambuc return (returnCode | reasonCode) ? 0 : 1;
606ebfedea0SLionel Sambuc }
607ebfedea0SLionel Sambuc
608ebfedea0SLionel Sambuc # define SSL_SIG_LEN 36
609ebfedea0SLionel Sambuc
cca_rsa_verify(int type,const unsigned char * m,unsigned int m_len,const unsigned char * sigbuf,unsigned int siglen,const RSA * rsa)610*0a6a1f1dSLionel Sambuc static int cca_rsa_verify(int type, const unsigned char *m,
611*0a6a1f1dSLionel Sambuc unsigned int m_len, const unsigned char *sigbuf,
612*0a6a1f1dSLionel Sambuc unsigned int siglen, const RSA *rsa)
613ebfedea0SLionel Sambuc {
614ebfedea0SLionel Sambuc long returnCode;
615ebfedea0SLionel Sambuc long reasonCode;
616ebfedea0SLionel Sambuc long lsiglen = siglen;
617ebfedea0SLionel Sambuc long exitDataLength = 0;
618ebfedea0SLionel Sambuc unsigned char exitData[8];
619ebfedea0SLionel Sambuc long ruleArrayLength = 1;
620ebfedea0SLionel Sambuc unsigned char ruleArray[8] = "PKCS-1.1";
621ebfedea0SLionel Sambuc long keyTokenLength;
622ebfedea0SLionel Sambuc unsigned char *keyToken = (unsigned char *)RSA_get_ex_data(rsa, hndidx);
623ebfedea0SLionel Sambuc long length = SSL_SIG_LEN;
624ebfedea0SLionel Sambuc long keyLength;
625ebfedea0SLionel Sambuc unsigned char *hashBuffer = NULL;
626ebfedea0SLionel Sambuc X509_SIG sig;
627ebfedea0SLionel Sambuc ASN1_TYPE parameter;
628ebfedea0SLionel Sambuc X509_ALGOR algorithm;
629ebfedea0SLionel Sambuc ASN1_OCTET_STRING digest;
630ebfedea0SLionel Sambuc
631ebfedea0SLionel Sambuc keyTokenLength = *(long *)keyToken;
632ebfedea0SLionel Sambuc keyToken += sizeof(long);
633ebfedea0SLionel Sambuc
634*0a6a1f1dSLionel Sambuc if (type == NID_md5 || type == NID_sha1) {
635ebfedea0SLionel Sambuc sig.algor = &algorithm;
636ebfedea0SLionel Sambuc algorithm.algorithm = OBJ_nid2obj(type);
637ebfedea0SLionel Sambuc
638*0a6a1f1dSLionel Sambuc if (!algorithm.algorithm) {
639ebfedea0SLionel Sambuc CCA4758err(CCA4758_F_CCA_RSA_VERIFY,
640ebfedea0SLionel Sambuc CCA4758_R_UNKNOWN_ALGORITHM_TYPE);
641ebfedea0SLionel Sambuc return 0;
642ebfedea0SLionel Sambuc }
643ebfedea0SLionel Sambuc
644*0a6a1f1dSLionel Sambuc if (!algorithm.algorithm->length) {
645ebfedea0SLionel Sambuc CCA4758err(CCA4758_F_CCA_RSA_VERIFY,
646ebfedea0SLionel Sambuc CCA4758_R_ASN1_OID_UNKNOWN_FOR_MD);
647ebfedea0SLionel Sambuc return 0;
648ebfedea0SLionel Sambuc }
649ebfedea0SLionel Sambuc
650ebfedea0SLionel Sambuc parameter.type = V_ASN1_NULL;
651ebfedea0SLionel Sambuc parameter.value.ptr = NULL;
652ebfedea0SLionel Sambuc algorithm.parameter = ¶meter;
653ebfedea0SLionel Sambuc
654ebfedea0SLionel Sambuc sig.digest = &digest;
655ebfedea0SLionel Sambuc sig.digest->data = (unsigned char *)m;
656ebfedea0SLionel Sambuc sig.digest->length = m_len;
657ebfedea0SLionel Sambuc
658ebfedea0SLionel Sambuc length = i2d_X509_SIG(&sig, NULL);
659ebfedea0SLionel Sambuc }
660ebfedea0SLionel Sambuc
661ebfedea0SLionel Sambuc keyLength = RSA_size(rsa);
662ebfedea0SLionel Sambuc
663*0a6a1f1dSLionel Sambuc if (length - RSA_PKCS1_PADDING > keyLength) {
664ebfedea0SLionel Sambuc CCA4758err(CCA4758_F_CCA_RSA_VERIFY,
665ebfedea0SLionel Sambuc CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
666ebfedea0SLionel Sambuc return 0;
667ebfedea0SLionel Sambuc }
668ebfedea0SLionel Sambuc
669*0a6a1f1dSLionel Sambuc switch (type) {
670ebfedea0SLionel Sambuc case NID_md5_sha1:
671*0a6a1f1dSLionel Sambuc if (m_len != SSL_SIG_LEN) {
672ebfedea0SLionel Sambuc CCA4758err(CCA4758_F_CCA_RSA_VERIFY,
673ebfedea0SLionel Sambuc CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
674ebfedea0SLionel Sambuc return 0;
675ebfedea0SLionel Sambuc }
676ebfedea0SLionel Sambuc
677ebfedea0SLionel Sambuc hashBuffer = (unsigned char *)m;
678ebfedea0SLionel Sambuc length = m_len;
679ebfedea0SLionel Sambuc break;
680ebfedea0SLionel Sambuc case NID_md5:
681ebfedea0SLionel Sambuc {
682ebfedea0SLionel Sambuc unsigned char *ptr;
683*0a6a1f1dSLionel Sambuc ptr = hashBuffer = OPENSSL_malloc((unsigned int)keyLength + 1);
684*0a6a1f1dSLionel Sambuc if (!hashBuffer) {
685*0a6a1f1dSLionel Sambuc CCA4758err(CCA4758_F_CCA_RSA_VERIFY, ERR_R_MALLOC_FAILURE);
686ebfedea0SLionel Sambuc return 0;
687ebfedea0SLionel Sambuc }
688ebfedea0SLionel Sambuc
689ebfedea0SLionel Sambuc i2d_X509_SIG(&sig, &ptr);
690ebfedea0SLionel Sambuc }
691ebfedea0SLionel Sambuc break;
692ebfedea0SLionel Sambuc case NID_sha1:
693ebfedea0SLionel Sambuc {
694ebfedea0SLionel Sambuc unsigned char *ptr;
695*0a6a1f1dSLionel Sambuc ptr = hashBuffer = OPENSSL_malloc((unsigned int)keyLength + 1);
696*0a6a1f1dSLionel Sambuc if (!hashBuffer) {
697*0a6a1f1dSLionel Sambuc CCA4758err(CCA4758_F_CCA_RSA_VERIFY, ERR_R_MALLOC_FAILURE);
698ebfedea0SLionel Sambuc return 0;
699ebfedea0SLionel Sambuc }
700ebfedea0SLionel Sambuc i2d_X509_SIG(&sig, &ptr);
701ebfedea0SLionel Sambuc }
702ebfedea0SLionel Sambuc break;
703ebfedea0SLionel Sambuc default:
704ebfedea0SLionel Sambuc return 0;
705ebfedea0SLionel Sambuc }
706ebfedea0SLionel Sambuc
707ebfedea0SLionel Sambuc digitalSignatureVerify(&returnCode, &reasonCode, &exitDataLength,
708*0a6a1f1dSLionel Sambuc exitData, &ruleArrayLength, ruleArray,
709*0a6a1f1dSLionel Sambuc &keyTokenLength, keyToken, &length, hashBuffer,
710*0a6a1f1dSLionel Sambuc &lsiglen, (unsigned char *)sigbuf);
711ebfedea0SLionel Sambuc
712*0a6a1f1dSLionel Sambuc if (type == NID_sha1 || type == NID_md5) {
713ebfedea0SLionel Sambuc OPENSSL_cleanse(hashBuffer, keyLength + 1);
714ebfedea0SLionel Sambuc OPENSSL_free(hashBuffer);
715ebfedea0SLionel Sambuc }
716ebfedea0SLionel Sambuc
717ebfedea0SLionel Sambuc return ((returnCode || reasonCode) ? 0 : 1);
718ebfedea0SLionel Sambuc }
719ebfedea0SLionel Sambuc
720ebfedea0SLionel Sambuc # define SSL_SIG_LEN 36
721ebfedea0SLionel Sambuc
cca_rsa_sign(int type,const unsigned char * m,unsigned int m_len,unsigned char * sigret,unsigned int * siglen,const RSA * rsa)722ebfedea0SLionel Sambuc static int cca_rsa_sign(int type, const unsigned char *m, unsigned int m_len,
723*0a6a1f1dSLionel Sambuc unsigned char *sigret, unsigned int *siglen,
724*0a6a1f1dSLionel Sambuc const RSA *rsa)
725ebfedea0SLionel Sambuc {
726ebfedea0SLionel Sambuc long returnCode;
727ebfedea0SLionel Sambuc long reasonCode;
728ebfedea0SLionel Sambuc long exitDataLength = 0;
729ebfedea0SLionel Sambuc unsigned char exitData[8];
730ebfedea0SLionel Sambuc long ruleArrayLength = 1;
731ebfedea0SLionel Sambuc unsigned char ruleArray[8] = "PKCS-1.1";
732ebfedea0SLionel Sambuc long outputLength = 256;
733ebfedea0SLionel Sambuc long outputBitLength;
734ebfedea0SLionel Sambuc long keyTokenLength;
735ebfedea0SLionel Sambuc unsigned char *hashBuffer = NULL;
736ebfedea0SLionel Sambuc unsigned char *keyToken = (unsigned char *)RSA_get_ex_data(rsa, hndidx);
737ebfedea0SLionel Sambuc long length = SSL_SIG_LEN;
738ebfedea0SLionel Sambuc long keyLength;
739ebfedea0SLionel Sambuc X509_SIG sig;
740ebfedea0SLionel Sambuc ASN1_TYPE parameter;
741ebfedea0SLionel Sambuc X509_ALGOR algorithm;
742ebfedea0SLionel Sambuc ASN1_OCTET_STRING digest;
743ebfedea0SLionel Sambuc
744ebfedea0SLionel Sambuc keyTokenLength = *(long *)keyToken;
745ebfedea0SLionel Sambuc keyToken += sizeof(long);
746ebfedea0SLionel Sambuc
747*0a6a1f1dSLionel Sambuc if (type == NID_md5 || type == NID_sha1) {
748ebfedea0SLionel Sambuc sig.algor = &algorithm;
749ebfedea0SLionel Sambuc algorithm.algorithm = OBJ_nid2obj(type);
750ebfedea0SLionel Sambuc
751*0a6a1f1dSLionel Sambuc if (!algorithm.algorithm) {
752ebfedea0SLionel Sambuc CCA4758err(CCA4758_F_CCA_RSA_SIGN,
753ebfedea0SLionel Sambuc CCA4758_R_UNKNOWN_ALGORITHM_TYPE);
754ebfedea0SLionel Sambuc return 0;
755ebfedea0SLionel Sambuc }
756ebfedea0SLionel Sambuc
757*0a6a1f1dSLionel Sambuc if (!algorithm.algorithm->length) {
758ebfedea0SLionel Sambuc CCA4758err(CCA4758_F_CCA_RSA_SIGN,
759ebfedea0SLionel Sambuc CCA4758_R_ASN1_OID_UNKNOWN_FOR_MD);
760ebfedea0SLionel Sambuc return 0;
761ebfedea0SLionel Sambuc }
762ebfedea0SLionel Sambuc
763ebfedea0SLionel Sambuc parameter.type = V_ASN1_NULL;
764ebfedea0SLionel Sambuc parameter.value.ptr = NULL;
765ebfedea0SLionel Sambuc algorithm.parameter = ¶meter;
766ebfedea0SLionel Sambuc
767ebfedea0SLionel Sambuc sig.digest = &digest;
768ebfedea0SLionel Sambuc sig.digest->data = (unsigned char *)m;
769ebfedea0SLionel Sambuc sig.digest->length = m_len;
770ebfedea0SLionel Sambuc
771ebfedea0SLionel Sambuc length = i2d_X509_SIG(&sig, NULL);
772ebfedea0SLionel Sambuc }
773ebfedea0SLionel Sambuc
774ebfedea0SLionel Sambuc keyLength = RSA_size(rsa);
775ebfedea0SLionel Sambuc
776*0a6a1f1dSLionel Sambuc if (length - RSA_PKCS1_PADDING > keyLength) {
777ebfedea0SLionel Sambuc CCA4758err(CCA4758_F_CCA_RSA_SIGN,
778ebfedea0SLionel Sambuc CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
779ebfedea0SLionel Sambuc return 0;
780ebfedea0SLionel Sambuc }
781ebfedea0SLionel Sambuc
782*0a6a1f1dSLionel Sambuc switch (type) {
783ebfedea0SLionel Sambuc case NID_md5_sha1:
784*0a6a1f1dSLionel Sambuc if (m_len != SSL_SIG_LEN) {
785ebfedea0SLionel Sambuc CCA4758err(CCA4758_F_CCA_RSA_SIGN,
786ebfedea0SLionel Sambuc CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
787ebfedea0SLionel Sambuc return 0;
788ebfedea0SLionel Sambuc }
789ebfedea0SLionel Sambuc hashBuffer = (unsigned char *)m;
790ebfedea0SLionel Sambuc length = m_len;
791ebfedea0SLionel Sambuc break;
792ebfedea0SLionel Sambuc case NID_md5:
793ebfedea0SLionel Sambuc {
794ebfedea0SLionel Sambuc unsigned char *ptr;
795*0a6a1f1dSLionel Sambuc ptr = hashBuffer = OPENSSL_malloc((unsigned int)keyLength + 1);
796*0a6a1f1dSLionel Sambuc if (!hashBuffer) {
797*0a6a1f1dSLionel Sambuc CCA4758err(CCA4758_F_CCA_RSA_SIGN, ERR_R_MALLOC_FAILURE);
798ebfedea0SLionel Sambuc return 0;
799ebfedea0SLionel Sambuc }
800ebfedea0SLionel Sambuc i2d_X509_SIG(&sig, &ptr);
801ebfedea0SLionel Sambuc }
802ebfedea0SLionel Sambuc break;
803ebfedea0SLionel Sambuc case NID_sha1:
804ebfedea0SLionel Sambuc {
805ebfedea0SLionel Sambuc unsigned char *ptr;
806*0a6a1f1dSLionel Sambuc ptr = hashBuffer = OPENSSL_malloc((unsigned int)keyLength + 1);
807*0a6a1f1dSLionel Sambuc if (!hashBuffer) {
808*0a6a1f1dSLionel Sambuc CCA4758err(CCA4758_F_CCA_RSA_SIGN, ERR_R_MALLOC_FAILURE);
809ebfedea0SLionel Sambuc return 0;
810ebfedea0SLionel Sambuc }
811ebfedea0SLionel Sambuc i2d_X509_SIG(&sig, &ptr);
812ebfedea0SLionel Sambuc }
813ebfedea0SLionel Sambuc break;
814ebfedea0SLionel Sambuc default:
815ebfedea0SLionel Sambuc return 0;
816ebfedea0SLionel Sambuc }
817ebfedea0SLionel Sambuc
818ebfedea0SLionel Sambuc digitalSignatureGenerate(&returnCode, &reasonCode, &exitDataLength,
819*0a6a1f1dSLionel Sambuc exitData, &ruleArrayLength, ruleArray,
820*0a6a1f1dSLionel Sambuc &keyTokenLength, keyToken, &length, hashBuffer,
821*0a6a1f1dSLionel Sambuc &outputLength, &outputBitLength, sigret);
822ebfedea0SLionel Sambuc
823*0a6a1f1dSLionel Sambuc if (type == NID_sha1 || type == NID_md5) {
824ebfedea0SLionel Sambuc OPENSSL_cleanse(hashBuffer, keyLength + 1);
825ebfedea0SLionel Sambuc OPENSSL_free(hashBuffer);
826ebfedea0SLionel Sambuc }
827ebfedea0SLionel Sambuc
828ebfedea0SLionel Sambuc *siglen = outputLength;
829ebfedea0SLionel Sambuc
830ebfedea0SLionel Sambuc return ((returnCode || reasonCode) ? 0 : 1);
831ebfedea0SLionel Sambuc }
832ebfedea0SLionel Sambuc
getModulusAndExponent(const unsigned char * token,long * exponentLength,unsigned char * exponent,long * modulusLength,long * modulusFieldLength,unsigned char * modulus)833*0a6a1f1dSLionel Sambuc static int getModulusAndExponent(const unsigned char *token,
834*0a6a1f1dSLionel Sambuc long *exponentLength,
835*0a6a1f1dSLionel Sambuc unsigned char *exponent, long *modulusLength,
836*0a6a1f1dSLionel Sambuc long *modulusFieldLength,
837ebfedea0SLionel Sambuc unsigned char *modulus)
838ebfedea0SLionel Sambuc {
839ebfedea0SLionel Sambuc unsigned long len;
840ebfedea0SLionel Sambuc
841ebfedea0SLionel Sambuc if (*token++ != (char)0x1E) /* internal PKA token? */
842ebfedea0SLionel Sambuc return 0;
843ebfedea0SLionel Sambuc
844ebfedea0SLionel Sambuc if (*token++) /* token version must be zero */
845ebfedea0SLionel Sambuc return 0;
846ebfedea0SLionel Sambuc
847ebfedea0SLionel Sambuc len = *token++;
848ebfedea0SLionel Sambuc len = len << 8;
849ebfedea0SLionel Sambuc len |= (unsigned char)*token++;
850ebfedea0SLionel Sambuc
851ebfedea0SLionel Sambuc token += 4; /* skip reserved bytes */
852ebfedea0SLionel Sambuc
853*0a6a1f1dSLionel Sambuc if (*token++ == (char)0x04) {
854ebfedea0SLionel Sambuc if (*token++) /* token version must be zero */
855ebfedea0SLionel Sambuc return 0;
856ebfedea0SLionel Sambuc
857ebfedea0SLionel Sambuc len = *token++;
858ebfedea0SLionel Sambuc len = len << 8;
859ebfedea0SLionel Sambuc len |= (unsigned char)*token++;
860ebfedea0SLionel Sambuc
861ebfedea0SLionel Sambuc token += 2; /* skip reserved section */
862ebfedea0SLionel Sambuc
863ebfedea0SLionel Sambuc len = *token++;
864ebfedea0SLionel Sambuc len = len << 8;
865ebfedea0SLionel Sambuc len |= (unsigned char)*token++;
866ebfedea0SLionel Sambuc
867ebfedea0SLionel Sambuc *exponentLength = len;
868ebfedea0SLionel Sambuc
869ebfedea0SLionel Sambuc len = *token++;
870ebfedea0SLionel Sambuc len = len << 8;
871ebfedea0SLionel Sambuc len |= (unsigned char)*token++;
872ebfedea0SLionel Sambuc
873ebfedea0SLionel Sambuc *modulusLength = len;
874ebfedea0SLionel Sambuc
875ebfedea0SLionel Sambuc len = *token++;
876ebfedea0SLionel Sambuc len = len << 8;
877ebfedea0SLionel Sambuc len |= (unsigned char)*token++;
878ebfedea0SLionel Sambuc
879ebfedea0SLionel Sambuc *modulusFieldLength = len;
880ebfedea0SLionel Sambuc
881ebfedea0SLionel Sambuc memcpy(exponent, token, *exponentLength);
882ebfedea0SLionel Sambuc token += *exponentLength;
883ebfedea0SLionel Sambuc
884ebfedea0SLionel Sambuc memcpy(modulus, token, *modulusFieldLength);
885ebfedea0SLionel Sambuc return 1;
886ebfedea0SLionel Sambuc }
887ebfedea0SLionel Sambuc return 0;
888ebfedea0SLionel Sambuc }
889ebfedea0SLionel Sambuc
890ebfedea0SLionel Sambuc # endif /* OPENSSL_NO_RSA */
891ebfedea0SLionel Sambuc
cca_random_status(void)892ebfedea0SLionel Sambuc static int cca_random_status(void)
893ebfedea0SLionel Sambuc {
894ebfedea0SLionel Sambuc return 1;
895ebfedea0SLionel Sambuc }
896ebfedea0SLionel Sambuc
cca_get_random_bytes(unsigned char * buf,int num)897ebfedea0SLionel Sambuc static int cca_get_random_bytes(unsigned char *buf, int num)
898ebfedea0SLionel Sambuc {
899ebfedea0SLionel Sambuc long ret_code;
900ebfedea0SLionel Sambuc long reason_code;
901ebfedea0SLionel Sambuc long exit_data_length;
902ebfedea0SLionel Sambuc unsigned char exit_data[4];
903ebfedea0SLionel Sambuc unsigned char form[] = "RANDOM ";
904ebfedea0SLionel Sambuc unsigned char rand_buf[8];
905ebfedea0SLionel Sambuc
906*0a6a1f1dSLionel Sambuc while (num >= (int)sizeof(rand_buf)) {
907ebfedea0SLionel Sambuc randomNumberGenerate(&ret_code, &reason_code, &exit_data_length,
908ebfedea0SLionel Sambuc exit_data, form, rand_buf);
909ebfedea0SLionel Sambuc if (ret_code)
910ebfedea0SLionel Sambuc return 0;
911ebfedea0SLionel Sambuc num -= sizeof(rand_buf);
912ebfedea0SLionel Sambuc memcpy(buf, rand_buf, sizeof(rand_buf));
913ebfedea0SLionel Sambuc buf += sizeof(rand_buf);
914ebfedea0SLionel Sambuc }
915ebfedea0SLionel Sambuc
916*0a6a1f1dSLionel Sambuc if (num) {
917ebfedea0SLionel Sambuc randomNumberGenerate(&ret_code, &reason_code, NULL, NULL,
918ebfedea0SLionel Sambuc form, rand_buf);
919ebfedea0SLionel Sambuc if (ret_code)
920ebfedea0SLionel Sambuc return 0;
921ebfedea0SLionel Sambuc memcpy(buf, rand_buf, num);
922ebfedea0SLionel Sambuc }
923ebfedea0SLionel Sambuc
924ebfedea0SLionel Sambuc return 1;
925ebfedea0SLionel Sambuc }
926ebfedea0SLionel Sambuc
927ebfedea0SLionel Sambuc # ifndef OPENSSL_NO_RSA
cca_ex_free(void * obj,void * item,CRYPTO_EX_DATA * ad,int idx,long argl,void * argp)928ebfedea0SLionel Sambuc static void cca_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad, int idx,
929ebfedea0SLionel Sambuc long argl, void *argp)
930ebfedea0SLionel Sambuc {
931ebfedea0SLionel Sambuc if (item)
932ebfedea0SLionel Sambuc OPENSSL_free(item);
933ebfedea0SLionel Sambuc }
934ebfedea0SLionel Sambuc # endif
935ebfedea0SLionel Sambuc
936ebfedea0SLionel Sambuc /* Goo to handle building as a dynamic engine */
937ebfedea0SLionel Sambuc # ifndef OPENSSL_NO_DYNAMIC_ENGINE
bind_fn(ENGINE * e,const char * id)938ebfedea0SLionel Sambuc static int bind_fn(ENGINE *e, const char *id)
939ebfedea0SLionel Sambuc {
940ebfedea0SLionel Sambuc if (id && (strcmp(id, engine_4758_cca_id) != 0) &&
941ebfedea0SLionel Sambuc (strcmp(id, engine_4758_cca_id_alt) != 0))
942ebfedea0SLionel Sambuc return 0;
943ebfedea0SLionel Sambuc if (!bind_helper(e))
944ebfedea0SLionel Sambuc return 0;
945ebfedea0SLionel Sambuc return 1;
946ebfedea0SLionel Sambuc }
947*0a6a1f1dSLionel Sambuc
948ebfedea0SLionel Sambuc IMPLEMENT_DYNAMIC_CHECK_FN()
949ebfedea0SLionel Sambuc IMPLEMENT_DYNAMIC_BIND_FN(bind_fn)
950ebfedea0SLionel Sambuc # endif /* OPENSSL_NO_DYNAMIC_ENGINE */
951ebfedea0SLionel Sambuc # endif /* !OPENSSL_NO_HW_4758_CCA */
952ebfedea0SLionel Sambuc #endif /* !OPENSSL_NO_HW */
953