summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/engine
diff options
context:
space:
mode:
authorcvs2svn <admin@example.com>2002-05-15 02:29:23 +0000
committercvs2svn <admin@example.com>2002-05-15 02:29:23 +0000
commitfd9566423b542798f5c8b06e68101a9ea5bb9885 (patch)
treef2cc037857a260afc5aaaaaa6cf62d06923c6273 /src/lib/libcrypto/engine
parent536c76cbb863bab152f19842ab88772c01e922c7 (diff)
downloadopenbsd-fd9566423b542798f5c8b06e68101a9ea5bb9885.tar.gz
openbsd-fd9566423b542798f5c8b06e68101a9ea5bb9885.tar.bz2
openbsd-fd9566423b542798f5c8b06e68101a9ea5bb9885.zip
This commit was manufactured by cvs2git to create branch 'openssl'.
Diffstat (limited to 'src/lib/libcrypto/engine')
-rw-r--r--src/lib/libcrypto/engine/enginetest.c251
-rw-r--r--src/lib/libcrypto/engine/hw.ec8
-rw-r--r--src/lib/libcrypto/engine/hw_4758_cca.c950
-rw-r--r--src/lib/libcrypto/engine/hw_4758_cca_err.c149
-rw-r--r--src/lib/libcrypto/engine/hw_4758_cca_err.h93
-rw-r--r--src/lib/libcrypto/engine/hw_aep.c1101
-rw-r--r--src/lib/libcrypto/engine/hw_aep_err.c157
-rw-r--r--src/lib/libcrypto/engine/hw_aep_err.h101
-rw-r--r--src/lib/libcrypto/engine/hw_atalla.c444
-rw-r--r--src/lib/libcrypto/engine/hw_atalla_err.c145
-rw-r--r--src/lib/libcrypto/engine/hw_atalla_err.h89
-rw-r--r--src/lib/libcrypto/engine/hw_cryptodev.c926
-rw-r--r--src/lib/libcrypto/engine/hw_cswift.c807
-rw-r--r--src/lib/libcrypto/engine/hw_cswift_err.c149
-rw-r--r--src/lib/libcrypto/engine/hw_cswift_err.h93
-rw-r--r--src/lib/libcrypto/engine/hw_ncipher.c1019
-rw-r--r--src/lib/libcrypto/engine/hw_ncipher_err.c156
-rw-r--r--src/lib/libcrypto/engine/hw_ncipher_err.h100
-rw-r--r--src/lib/libcrypto/engine/hw_nuron.c399
-rw-r--r--src/lib/libcrypto/engine/hw_nuron_err.c142
-rw-r--r--src/lib/libcrypto/engine/hw_nuron_err.h86
-rw-r--r--src/lib/libcrypto/engine/hw_sureware_err.c150
-rw-r--r--src/lib/libcrypto/engine/hw_sureware_err.h94
-rw-r--r--src/lib/libcrypto/engine/hw_ubsec.c1041
-rw-r--r--src/lib/libcrypto/engine/hw_ubsec_err.c151
-rw-r--r--src/lib/libcrypto/engine/hw_ubsec_err.h95
-rw-r--r--src/lib/libcrypto/engine/vendor_defns/aep.h178
-rw-r--r--src/lib/libcrypto/engine/vendor_defns/atalla.h61
-rw-r--r--src/lib/libcrypto/engine/vendor_defns/cswift.h213
-rw-r--r--src/lib/libcrypto/engine/vendor_defns/hw_4758_cca.h149
30 files changed, 9497 insertions, 0 deletions
diff --git a/src/lib/libcrypto/engine/enginetest.c b/src/lib/libcrypto/engine/enginetest.c
new file mode 100644
index 0000000000..a5a3c47fcb
--- /dev/null
+++ b/src/lib/libcrypto/engine/enginetest.c
@@ -0,0 +1,251 @@
1/* crypto/engine/enginetest.c */
2/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
3 * project 2000.
4 */
5/* ====================================================================
6 * Copyright (c) 1999 The OpenSSL Project. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * 3. All advertising materials mentioning features or use of this
21 * software must display the following acknowledgment:
22 * "This product includes software developed by the OpenSSL Project
23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24 *
25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26 * endorse or promote products derived from this software without
27 * prior written permission. For written permission, please contact
28 * licensing@OpenSSL.org.
29 *
30 * 5. Products derived from this software may not be called "OpenSSL"
31 * nor may "OpenSSL" appear in their names without prior written
32 * permission of the OpenSSL Project.
33 *
34 * 6. Redistributions of any form whatsoever must retain the following
35 * acknowledgment:
36 * "This product includes software developed by the OpenSSL Project
37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38 *
39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50 * OF THE POSSIBILITY OF SUCH DAMAGE.
51 * ====================================================================
52 *
53 * This product includes cryptographic software written by Eric Young
54 * (eay@cryptsoft.com). This product includes software written by Tim
55 * Hudson (tjh@cryptsoft.com).
56 *
57 */
58
59#include <stdio.h>
60#include <string.h>
61#include <openssl/engine.h>
62#include <openssl/err.h>
63
64static void display_engine_list()
65 {
66 ENGINE *h;
67 int loop;
68
69 h = ENGINE_get_first();
70 loop = 0;
71 printf("listing available engine types\n");
72 while(h)
73 {
74 printf("engine %i, id = \"%s\", name = \"%s\"\n",
75 loop++, ENGINE_get_id(h), ENGINE_get_name(h));
76 h = ENGINE_get_next(h);
77 }
78 printf("end of list\n");
79 }
80
81int main(int argc, char *argv[])
82 {
83 ENGINE *block[512];
84 char buf[256];
85 const char *id, *name;
86 ENGINE *ptr;
87 int loop;
88 int to_return = 1;
89 ENGINE *new_h1 = NULL;
90 ENGINE *new_h2 = NULL;
91 ENGINE *new_h3 = NULL;
92 ENGINE *new_h4 = NULL;
93
94 ERR_load_crypto_strings();
95
96 memset(block, 0, 512 * sizeof(ENGINE *));
97 if(((new_h1 = ENGINE_new()) == NULL) ||
98 !ENGINE_set_id(new_h1, "test_id0") ||
99 !ENGINE_set_name(new_h1, "First test item") ||
100 ((new_h2 = ENGINE_new()) == NULL) ||
101 !ENGINE_set_id(new_h2, "test_id1") ||
102 !ENGINE_set_name(new_h2, "Second test item") ||
103 ((new_h3 = ENGINE_new()) == NULL) ||
104 !ENGINE_set_id(new_h3, "test_id2") ||
105 !ENGINE_set_name(new_h3, "Third test item") ||
106 ((new_h4 = ENGINE_new()) == NULL) ||
107 !ENGINE_set_id(new_h4, "test_id3") ||
108 !ENGINE_set_name(new_h4, "Fourth test item"))
109 {
110 printf("Couldn't set up test ENGINE structures\n");
111 goto end;
112 }
113 printf("\nenginetest beginning\n\n");
114 display_engine_list();
115 if(!ENGINE_add(new_h1))
116 {
117 printf("Add failed!\n");
118 goto end;
119 }
120 display_engine_list();
121 ptr = ENGINE_get_first();
122 if(!ENGINE_remove(ptr))
123 {
124 printf("Remove failed!\n");
125 goto end;
126 }
127 display_engine_list();
128 if(!ENGINE_add(new_h3) || !ENGINE_add(new_h2))
129 {
130 printf("Add failed!\n");
131 goto end;
132 }
133 display_engine_list();
134 if(!ENGINE_remove(new_h2))
135 {
136 printf("Remove failed!\n");
137 goto end;
138 }
139 display_engine_list();
140 if(!ENGINE_add(new_h4))
141 {
142 printf("Add failed!\n");
143 goto end;
144 }
145 display_engine_list();
146 if(ENGINE_add(new_h3))
147 {
148 printf("Add *should* have failed but didn't!\n");
149 goto end;
150 }
151 else
152 printf("Add that should fail did.\n");
153 ERR_clear_error();
154 if(ENGINE_remove(new_h2))
155 {
156 printf("Remove *should* have failed but didn't!\n");
157 goto end;
158 }
159 else
160 printf("Remove that should fail did.\n");
161 if(!ENGINE_remove(new_h1))
162 {
163 printf("Remove failed!\n");
164 goto end;
165 }
166 display_engine_list();
167 if(!ENGINE_remove(new_h3))
168 {
169 printf("Remove failed!\n");
170 goto end;
171 }
172 display_engine_list();
173 if(!ENGINE_remove(new_h4))
174 {
175 printf("Remove failed!\n");
176 goto end;
177 }
178 display_engine_list();
179 /* Depending on whether there's any hardware support compiled
180 * in, this remove may be destined to fail. */
181 ptr = ENGINE_get_first();
182 if(ptr)
183 if(!ENGINE_remove(ptr))
184 printf("Remove failed!i - probably no hardware "
185 "support present.\n");
186 display_engine_list();
187 if(!ENGINE_add(new_h1) || !ENGINE_remove(new_h1))
188 {
189 printf("Couldn't add and remove to an empty list!\n");
190 goto end;
191 }
192 else
193 printf("Successfully added and removed to an empty list!\n");
194 printf("About to beef up the engine-type list\n");
195 for(loop = 0; loop < 512; loop++)
196 {
197 sprintf(buf, "id%i", loop);
198 id = strdup(buf);
199 sprintf(buf, "Fake engine type %i", loop);
200 name = strdup(buf);
201 if(((block[loop] = ENGINE_new()) == NULL) ||
202 !ENGINE_set_id(block[loop], id) ||
203 !ENGINE_set_name(block[loop], name))
204 {
205 printf("Couldn't create block of ENGINE structures.\n"
206 "I'll probably also core-dump now, damn.\n");
207 goto end;
208 }
209 }
210 for(loop = 0; loop < 512; loop++)
211 {
212 if(!ENGINE_add(block[loop]))
213 {
214 printf("\nAdding stopped at %i, (%s,%s)\n",
215 loop, ENGINE_get_id(block[loop]),
216 ENGINE_get_name(block[loop]));
217 goto cleanup_loop;
218 }
219 else
220 printf("."); fflush(stdout);
221 }
222cleanup_loop:
223 printf("\nAbout to empty the engine-type list\n");
224 while((ptr = ENGINE_get_first()) != NULL)
225 {
226 if(!ENGINE_remove(ptr))
227 {
228 printf("\nRemove failed!\n");
229 goto end;
230 }
231 printf("."); fflush(stdout);
232 }
233 for(loop = 0; loop < 512; loop++)
234 {
235 free((char *)(ENGINE_get_id(block[loop])));
236 free((char *)(ENGINE_get_name(block[loop])));
237 }
238 printf("\nTests completed happily\n");
239 to_return = 0;
240end:
241 if(to_return)
242 ERR_print_errors_fp(stderr);
243 if(new_h1) ENGINE_free(new_h1);
244 if(new_h2) ENGINE_free(new_h2);
245 if(new_h3) ENGINE_free(new_h3);
246 if(new_h4) ENGINE_free(new_h4);
247 for(loop = 0; loop < 512; loop++)
248 if(block[loop])
249 ENGINE_free(block[loop]);
250 return to_return;
251 }
diff --git a/src/lib/libcrypto/engine/hw.ec b/src/lib/libcrypto/engine/hw.ec
new file mode 100644
index 0000000000..5481a43918
--- /dev/null
+++ b/src/lib/libcrypto/engine/hw.ec
@@ -0,0 +1,8 @@
1L AEPHK hw_aep_err.h hw_aep_err.c
2L ATALLA hw_atalla_err.h hw_atalla_err.c
3L CSWIFT hw_cswift_err.h hw_cswift_err.c
4L HWCRHK hw_ncipher_err.h hw_ncipher_err.c
5L NURON hw_nuron_err.h hw_nuron_err.c
6L SUREWARE hw_sureware_err.h hw_sureware_err.c
7L UBSEC hw_ubsec_err.h hw_ubsec_err.c
8L CCA4758 hw_4758_cca_err.h hw_4758_cca_err.c
diff --git a/src/lib/libcrypto/engine/hw_4758_cca.c b/src/lib/libcrypto/engine/hw_4758_cca.c
new file mode 100644
index 0000000000..959d8f1a61
--- /dev/null
+++ b/src/lib/libcrypto/engine/hw_4758_cca.c
@@ -0,0 +1,950 @@
1/* Author: Maurice Gittens <maurice@gittens.nl> */
2/* ====================================================================
3 * Copyright (c) 1999 The OpenSSL Project. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
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
15 * distribution.
16 *
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/)"
21 *
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.
26 *
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.
30 *
31 * 6. Redistributions of any form whatsoever must retain the following
32 * acknowledgment:
33 * "This product includes software developed by the OpenSSL Project
34 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
35 *
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 * ====================================================================
49 *
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).
53 *
54 */
55
56#include <stdio.h>
57#include <openssl/crypto.h>
58/* #include <openssl/pem.h> */
59#include "cryptlib.h"
60#include <openssl/dso.h>
61#include <openssl/x509.h>
62#include <openssl/objects.h>
63#include <openssl/engine.h>
64
65#ifndef OPENSSL_NO_HW
66#ifndef OPENSSL_NO_HW_4758_CCA
67
68#ifdef FLAT_INC
69#include "hw_4758_cca.h"
70#else
71#include "vendor_defns/hw_4758_cca.h"
72#endif
73
74#include "hw_4758_cca_err.c"
75
76static int ibm_4758_cca_destroy(ENGINE *e);
77static int ibm_4758_cca_init(ENGINE *e);
78static int ibm_4758_cca_finish(ENGINE *e);
79static int ibm_4758_cca_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)());
80
81/* rsa functions */
82/*---------------*/
83#ifndef OPENSSL_NO_RSA
84static int cca_rsa_pub_enc(int flen, const unsigned char *from,
85 unsigned char *to, RSA *rsa,int padding);
86static int cca_rsa_priv_dec(int flen, const unsigned char *from,
87 unsigned char *to, RSA *rsa,int padding);
88static int cca_rsa_sign(int type, const unsigned char *m, unsigned int m_len,
89 unsigned char *sigret, unsigned int *siglen, const RSA *rsa);
90static int cca_rsa_verify(int dtype, const unsigned char *m, unsigned int m_len,
91 unsigned char *sigbuf, unsigned int siglen, const RSA *rsa);
92
93/* utility functions */
94/*-----------------------*/
95static EVP_PKEY *ibm_4758_load_privkey(ENGINE*, const char*,
96 UI_METHOD *ui_method, void *callback_data);
97static EVP_PKEY *ibm_4758_load_pubkey(ENGINE*, const char*,
98 UI_METHOD *ui_method, void *callback_data);
99
100static int getModulusAndExponent(const unsigned char *token, long *exponentLength,
101 unsigned char *exponent, long *modulusLength,
102 long *modulusFieldLength, unsigned char *modulus);
103#endif
104
105/* RAND number functions */
106/*-----------------------*/
107static int cca_get_random_bytes(unsigned char*, int );
108static int cca_random_status(void);
109
110static void cca_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad,
111 int idx,long argl, void *argp);
112
113/* Function pointers for CCA verbs */
114/*---------------------------------*/
115#ifndef OPENSSL_NO_RSA
116static F_KEYRECORDREAD keyRecordRead;
117static F_DIGITALSIGNATUREGENERATE digitalSignatureGenerate;
118static F_DIGITALSIGNATUREVERIFY digitalSignatureVerify;
119static F_PUBLICKEYEXTRACT publicKeyExtract;
120static F_PKAENCRYPT pkaEncrypt;
121static F_PKADECRYPT pkaDecrypt;
122#endif
123static F_RANDOMNUMBERGENERATE randomNumberGenerate;
124
125/* static variables */
126/*------------------*/
127static const char def_CCA4758_LIB_NAME[] = CCA_LIB_NAME;
128static const char *CCA4758_LIB_NAME = def_CCA4758_LIB_NAME;
129#ifndef OPENSSL_NO_RSA
130static const char* n_keyRecordRead = CSNDKRR;
131static const char* n_digitalSignatureGenerate = CSNDDSG;
132static const char* n_digitalSignatureVerify = CSNDDSV;
133static const char* n_publicKeyExtract = CSNDPKX;
134static const char* n_pkaEncrypt = CSNDPKE;
135static const char* n_pkaDecrypt = CSNDPKD;
136#endif
137static const char* n_randomNumberGenerate = CSNBRNG;
138
139static int hndidx = -1;
140static DSO *dso = NULL;
141
142/* openssl engine initialization structures */
143/*------------------------------------------*/
144
145#define CCA4758_CMD_SO_PATH ENGINE_CMD_BASE
146static const ENGINE_CMD_DEFN cca4758_cmd_defns[] = {
147 {CCA4758_CMD_SO_PATH,
148 "SO_PATH",
149 "Specifies the path to the '4758cca' shared library",
150 ENGINE_CMD_FLAG_STRING},
151 {0, NULL, NULL, 0}
152 };
153
154#ifndef OPENSSL_NO_RSA
155static RSA_METHOD ibm_4758_cca_rsa =
156 {
157 "IBM 4758 CCA RSA method",
158 cca_rsa_pub_enc,
159 NULL,
160 NULL,
161 cca_rsa_priv_dec,
162 NULL, /*rsa_mod_exp,*/
163 NULL, /*mod_exp_mont,*/
164 NULL, /* init */
165 NULL, /* finish */
166 RSA_FLAG_SIGN_VER, /* flags */
167 NULL, /* app_data */
168 cca_rsa_sign, /* rsa_sign */
169 cca_rsa_verify /* rsa_verify */
170 };
171#endif
172
173static RAND_METHOD ibm_4758_cca_rand =
174 {
175 /* "IBM 4758 RAND method", */
176 NULL, /* seed */
177 cca_get_random_bytes, /* get random bytes from the card */
178 NULL, /* cleanup */
179 NULL, /* add */
180 cca_get_random_bytes, /* pseudo rand */
181 cca_random_status, /* status */
182 };
183
184static const char *engine_4758_cca_id = "4758cca";
185static const char *engine_4758_cca_name = "IBM 4758 CCA hardware engine support";
186
187/* engine implementation */
188/*-----------------------*/
189static int bind_helper(ENGINE *e)
190 {
191 if(!ENGINE_set_id(e, engine_4758_cca_id) ||
192 !ENGINE_set_name(e, engine_4758_cca_name) ||
193#ifndef OPENSSL_NO_RSA
194 !ENGINE_set_RSA(e, &ibm_4758_cca_rsa) ||
195#endif
196 !ENGINE_set_RAND(e, &ibm_4758_cca_rand) ||
197 !ENGINE_set_destroy_function(e, ibm_4758_cca_destroy) ||
198 !ENGINE_set_init_function(e, ibm_4758_cca_init) ||
199 !ENGINE_set_finish_function(e, ibm_4758_cca_finish) ||
200 !ENGINE_set_ctrl_function(e, ibm_4758_cca_ctrl) ||
201 !ENGINE_set_load_privkey_function(e, ibm_4758_load_privkey) ||
202 !ENGINE_set_load_pubkey_function(e, ibm_4758_load_pubkey) ||
203 !ENGINE_set_cmd_defns(e, cca4758_cmd_defns))
204 return 0;
205 /* Ensure the error handling is set up */
206 ERR_load_CCA4758_strings();
207 return 1;
208 }
209
210static ENGINE *engine_4758_cca(void)
211 {
212 ENGINE *ret = ENGINE_new();
213 if(!ret)
214 return NULL;
215 if(!bind_helper(ret))
216 {
217 ENGINE_free(ret);
218 return NULL;
219 }
220 return ret;
221 }
222
223void ENGINE_load_4758cca(void)
224 {
225 ENGINE *e_4758 = engine_4758_cca();
226 if (!e_4758) return;
227 ENGINE_add(e_4758);
228 ENGINE_free(e_4758);
229 ERR_clear_error();
230 }
231
232static int ibm_4758_cca_destroy(ENGINE *e)
233 {
234 ERR_unload_CCA4758_strings();
235 return 1;
236 }
237
238static int ibm_4758_cca_init(ENGINE *e)
239 {
240 if(dso)
241 {
242 CCA4758err(CCA4758_F_IBM_4758_CCA_INIT,CCA4758_R_ALREADY_LOADED);
243 goto err;
244 }
245
246 dso = DSO_load(NULL, CCA4758_LIB_NAME , NULL, 0);
247 if(!dso)
248 {
249 CCA4758err(CCA4758_F_IBM_4758_CCA_INIT,CCA4758_R_DSO_FAILURE);
250 goto err;
251 }
252
253#ifndef OPENSSL_NO_RSA
254 if(!(keyRecordRead = (F_KEYRECORDREAD)
255 DSO_bind_func(dso, n_keyRecordRead)) ||
256 !(randomNumberGenerate = (F_RANDOMNUMBERGENERATE)
257 DSO_bind_func(dso, n_randomNumberGenerate)) ||
258 !(digitalSignatureGenerate = (F_DIGITALSIGNATUREGENERATE)
259 DSO_bind_func(dso, n_digitalSignatureGenerate)) ||
260 !(digitalSignatureVerify = (F_DIGITALSIGNATUREVERIFY)
261 DSO_bind_func(dso, n_digitalSignatureVerify)) ||
262 !(publicKeyExtract = (F_PUBLICKEYEXTRACT)
263 DSO_bind_func(dso, n_publicKeyExtract)) ||
264 !(pkaEncrypt = (F_PKAENCRYPT)
265 DSO_bind_func(dso, n_pkaEncrypt)) ||
266 !(pkaDecrypt = (F_PKADECRYPT)
267 DSO_bind_func(dso, n_pkaDecrypt)))
268 {
269 CCA4758err(CCA4758_F_IBM_4758_CCA_INIT,CCA4758_R_DSO_FAILURE);
270 goto err;
271 }
272#else
273 if(!(randomNumberGenerate = (F_RANDOMNUMBERGENERATE)
274 DSO_bind_func(dso, n_randomNumberGenerate)))
275 {
276 CCA4758err(CCA4758_F_IBM_4758_CCA_INIT,CCA4758_R_DSO_FAILURE);
277 goto err;
278 }
279#endif
280
281 hndidx = RSA_get_ex_new_index(0, "IBM 4758 CCA RSA key handle",
282 NULL, NULL, cca_ex_free);
283
284 return 1;
285err:
286 if(dso)
287 DSO_free(dso);
288 dso = NULL;
289
290 keyRecordRead = (F_KEYRECORDREAD)NULL;
291 randomNumberGenerate = (F_RANDOMNUMBERGENERATE)NULL;
292 digitalSignatureGenerate = (F_DIGITALSIGNATUREGENERATE)NULL;
293 digitalSignatureVerify = (F_DIGITALSIGNATUREVERIFY)NULL;
294 publicKeyExtract = (F_PUBLICKEYEXTRACT)NULL;
295 pkaEncrypt = (F_PKAENCRYPT)NULL;
296 pkaDecrypt = (F_PKADECRYPT)NULL;
297 return 0;
298 }
299
300static int ibm_4758_cca_finish(ENGINE *e)
301 {
302 if(dso)
303 {
304 CCA4758err(CCA4758_F_IBM_4758_CCA_FINISH,
305 CCA4758_R_NOT_LOADED);
306 return 0;
307 }
308 if(!DSO_free(dso))
309 {
310 CCA4758err(CCA4758_F_IBM_4758_CCA_FINISH,
311 CCA4758_R_UNIT_FAILURE);
312 return 0;
313 }
314 dso = NULL;
315 keyRecordRead = (F_KEYRECORDREAD)NULL;
316 randomNumberGenerate = (F_RANDOMNUMBERGENERATE)NULL;
317 digitalSignatureGenerate = (F_DIGITALSIGNATUREGENERATE)NULL;
318 digitalSignatureVerify = (F_DIGITALSIGNATUREVERIFY)NULL;
319 publicKeyExtract = (F_PUBLICKEYEXTRACT)NULL;
320 pkaEncrypt = (F_PKAENCRYPT)NULL;
321 pkaDecrypt = (F_PKADECRYPT)NULL;
322 return 1;
323 }
324
325static int ibm_4758_cca_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)())
326 {
327 int initialised = ((dso == NULL) ? 0 : 1);
328 switch(cmd)
329 {
330 case CCA4758_CMD_SO_PATH:
331 if(p == NULL)
332 {
333 CCA4758err(CCA4758_F_IBM_4758_CCA_CTRL,
334 ERR_R_PASSED_NULL_PARAMETER);
335 return 0;
336 }
337 if(initialised)
338 {
339 CCA4758err(CCA4758_F_IBM_4758_CCA_CTRL,
340 CCA4758_R_ALREADY_LOADED);
341 return 0;
342 }
343 CCA4758_LIB_NAME = (const char *)p;
344 return 1;
345 default:
346 break;
347 }
348 CCA4758err(CCA4758_F_IBM_4758_CCA_CTRL,
349 CCA4758_R_COMMAND_NOT_IMPLEMENTED);
350 return 0;
351 }
352
353#ifndef OPENSSL_NO_RSA
354
355#define MAX_CCA_PKA_TOKEN_SIZE 2500
356
357static EVP_PKEY *ibm_4758_load_privkey(ENGINE* e, const char* key_id,
358 UI_METHOD *ui_method, void *callback_data)
359 {
360 RSA *rtmp = NULL;
361 EVP_PKEY *res = NULL;
362 unsigned char* keyToken = NULL;
363 unsigned char pubKeyToken[MAX_CCA_PKA_TOKEN_SIZE];
364 long pubKeyTokenLength = MAX_CCA_PKA_TOKEN_SIZE;
365 long keyTokenLength = MAX_CCA_PKA_TOKEN_SIZE;
366 long returnCode;
367 long reasonCode;
368 long exitDataLength = 0;
369 long ruleArrayLength = 0;
370 unsigned char exitData[8];
371 unsigned char ruleArray[8];
372 unsigned char keyLabel[64];
373 long keyLabelLength = strlen(key_id);
374 unsigned char modulus[256];
375 long modulusFieldLength = sizeof(modulus);
376 long modulusLength = 0;
377 unsigned char exponent[256];
378 long exponentLength = sizeof(exponent);
379
380 if (keyLabelLength > sizeof(keyLabel))
381 {
382 CCA4758err(CCA4758_F_IBM_4758_CCA_LOAD_PRIVKEY,
383 CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
384 return NULL;
385 }
386
387 memset(keyLabel,' ', sizeof(keyLabel));
388 memcpy(keyLabel, key_id, keyLabelLength);
389
390 keyToken = OPENSSL_malloc(MAX_CCA_PKA_TOKEN_SIZE + sizeof(long));
391 if (!keyToken)
392 {
393 CCA4758err(CCA4758_F_IBM_4758_CCA_LOAD_PRIVKEY,
394 ERR_R_MALLOC_FAILURE);
395 goto err;
396 }
397
398 keyRecordRead(&returnCode, &reasonCode, &exitDataLength,
399 exitData, &ruleArrayLength, ruleArray, keyLabel,
400 &keyTokenLength, keyToken+sizeof(long));
401
402 if (returnCode)
403 {
404 CCA4758err(CCA4758_F_IBM_4758_CCA_LOAD_PRIVKEY,
405 CCA4758_R_FAILED_LOADING_PRIVATE_KEY);
406 goto err;
407 }
408
409 publicKeyExtract(&returnCode, &reasonCode, &exitDataLength,
410 exitData, &ruleArrayLength, ruleArray, &keyTokenLength,
411 keyToken+sizeof(long), &pubKeyTokenLength, pubKeyToken);
412
413 if (returnCode)
414 {
415 CCA4758err(CCA4758_F_IBM_4758_CCA_LOAD_PRIVKEY,
416 CCA4758_R_FAILED_LOADING_PRIVATE_KEY);
417 goto err;
418 }
419
420 if (!getModulusAndExponent(pubKeyToken, &exponentLength,
421 exponent, &modulusLength, &modulusFieldLength,
422 modulus))
423 {
424 CCA4758err(CCA4758_F_IBM_4758_CCA_LOAD_PRIVKEY,
425 CCA4758_R_FAILED_LOADING_PRIVATE_KEY);
426 goto err;
427 }
428
429 (*(long*)keyToken) = keyTokenLength;
430 rtmp = RSA_new_method(e);
431 RSA_set_ex_data(rtmp, hndidx, (char *)keyToken);
432
433 rtmp->e = BN_bin2bn(exponent, exponentLength, NULL);
434 rtmp->n = BN_bin2bn(modulus, modulusFieldLength, NULL);
435 rtmp->flags |= RSA_FLAG_EXT_PKEY;
436
437 res = EVP_PKEY_new();
438 EVP_PKEY_assign_RSA(res, rtmp);
439
440 return res;
441err:
442 if (keyToken)
443 OPENSSL_free(keyToken);
444 if (res)
445 EVP_PKEY_free(res);
446 if (rtmp)
447 RSA_free(rtmp);
448 return NULL;
449 }
450
451static EVP_PKEY *ibm_4758_load_pubkey(ENGINE* e, const char* key_id,
452 UI_METHOD *ui_method, void *callback_data)
453 {
454 RSA *rtmp = NULL;
455 EVP_PKEY *res = NULL;
456 unsigned char* keyToken = NULL;
457 long keyTokenLength = MAX_CCA_PKA_TOKEN_SIZE;
458 long returnCode;
459 long reasonCode;
460 long exitDataLength = 0;
461 long ruleArrayLength = 0;
462 unsigned char exitData[8];
463 unsigned char ruleArray[8];
464 unsigned char keyLabel[64];
465 long keyLabelLength = strlen(key_id);
466 unsigned char modulus[512];
467 long modulusFieldLength = sizeof(modulus);
468 long modulusLength = 0;
469 unsigned char exponent[512];
470 long exponentLength = sizeof(exponent);
471
472 if (keyLabelLength > sizeof(keyLabel))
473 {
474 CCA4758err(CCA4758_F_IBM_4758_CCA_LOAD_PRIVKEY,
475 CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
476 return NULL;
477 }
478
479 memset(keyLabel,' ', sizeof(keyLabel));
480 memcpy(keyLabel, key_id, keyLabelLength);
481
482 keyToken = OPENSSL_malloc(MAX_CCA_PKA_TOKEN_SIZE + sizeof(long));
483 if (!keyToken)
484 {
485 CCA4758err(CCA4758_F_IBM_4758_CCA_LOAD_PUBKEY,
486 ERR_R_MALLOC_FAILURE);
487 goto err;
488 }
489
490 keyRecordRead(&returnCode, &reasonCode, &exitDataLength, exitData,
491 &ruleArrayLength, ruleArray, keyLabel, &keyTokenLength,
492 keyToken+sizeof(long));
493
494 if (returnCode)
495 {
496 CCA4758err(CCA4758_F_IBM_4758_CCA_LOAD_PRIVKEY,
497 ERR_R_MALLOC_FAILURE);
498 goto err;
499 }
500
501 if (!getModulusAndExponent(keyToken+sizeof(long), &exponentLength,
502 exponent, &modulusLength, &modulusFieldLength, modulus))
503 {
504 CCA4758err(CCA4758_F_IBM_4758_CCA_LOAD_PRIVKEY,
505 CCA4758_R_FAILED_LOADING_PUBLIC_KEY);
506 goto err;
507 }
508
509 (*(long*)keyToken) = keyTokenLength;
510 rtmp = RSA_new_method(e);
511 RSA_set_ex_data(rtmp, hndidx, (char *)keyToken);
512 rtmp->e = BN_bin2bn(exponent, exponentLength, NULL);
513 rtmp->n = BN_bin2bn(modulus, modulusFieldLength, NULL);
514 rtmp->flags |= RSA_FLAG_EXT_PKEY;
515 res = EVP_PKEY_new();
516 EVP_PKEY_assign_RSA(res, rtmp);
517
518 return res;
519err:
520 if (keyToken)
521 OPENSSL_free(keyToken);
522 if (res)
523 EVP_PKEY_free(res);
524 if (rtmp)
525 RSA_free(rtmp);
526 return NULL;
527 }
528
529static int cca_rsa_pub_enc(int flen, const unsigned char *from,
530 unsigned char *to, RSA *rsa,int padding)
531 {
532 long returnCode;
533 long reasonCode;
534 long lflen = flen;
535 long exitDataLength = 0;
536 unsigned char exitData[8];
537 long ruleArrayLength = 1;
538 unsigned char ruleArray[8] = "PKCS-1.2";
539 long dataStructureLength = 0;
540 unsigned char dataStructure[8];
541 long outputLength = RSA_size(rsa);
542 long keyTokenLength;
543 unsigned char* keyToken = (unsigned char*)RSA_get_ex_data(rsa, hndidx);
544
545 keyTokenLength = *(long*)keyToken;
546 keyToken+=sizeof(long);
547
548 pkaEncrypt(&returnCode, &reasonCode, &exitDataLength, exitData,
549 &ruleArrayLength, ruleArray, &lflen, (unsigned char*)from,
550 &dataStructureLength, dataStructure, &keyTokenLength,
551 keyToken, &outputLength, to);
552
553 if (returnCode || reasonCode)
554 return -(returnCode << 16 | reasonCode);
555 return outputLength;
556 }
557
558static int cca_rsa_priv_dec(int flen, const unsigned char *from,
559 unsigned char *to, RSA *rsa,int padding)
560 {
561 long returnCode;
562 long reasonCode;
563 long lflen = flen;
564 long exitDataLength = 0;
565 unsigned char exitData[8];
566 long ruleArrayLength = 1;
567 unsigned char ruleArray[8] = "PKCS-1.2";
568 long dataStructureLength = 0;
569 unsigned char dataStructure[8];
570 long outputLength = RSA_size(rsa);
571 long keyTokenLength;
572 unsigned char* keyToken = (unsigned char*)RSA_get_ex_data(rsa, hndidx);
573
574 keyTokenLength = *(long*)keyToken;
575 keyToken+=sizeof(long);
576
577 pkaDecrypt(&returnCode, &reasonCode, &exitDataLength, exitData,
578 &ruleArrayLength, ruleArray, &lflen, (unsigned char*)from,
579 &dataStructureLength, dataStructure, &keyTokenLength,
580 keyToken, &outputLength, to);
581
582 return (returnCode | reasonCode) ? 0 : 1;
583 }
584
585#define SSL_SIG_LEN 36
586
587static int cca_rsa_verify(int type, const unsigned char *m, unsigned int m_len,
588 unsigned char *sigbuf, unsigned int siglen, const RSA *rsa)
589 {
590 long returnCode;
591 long reasonCode;
592 long lsiglen = siglen;
593 long exitDataLength = 0;
594 unsigned char exitData[8];
595 long ruleArrayLength = 1;
596 unsigned char ruleArray[8] = "PKCS-1.1";
597 long keyTokenLength;
598 unsigned char* keyToken = (unsigned char*)RSA_get_ex_data(rsa, hndidx);
599 long length = SSL_SIG_LEN;
600 long keyLength ;
601 unsigned char *hashBuffer = NULL;
602 X509_SIG sig;
603 ASN1_TYPE parameter;
604 X509_ALGOR algorithm;
605 ASN1_OCTET_STRING digest;
606
607 keyTokenLength = *(long*)keyToken;
608 keyToken+=sizeof(long);
609
610 if (type == NID_md5 || type == NID_sha1)
611 {
612 sig.algor = &algorithm;
613 algorithm.algorithm = OBJ_nid2obj(type);
614
615 if (!algorithm.algorithm)
616 {
617 CCA4758err(CCA4758_F_IBM_4758_CCA_VERIFY,
618 CCA4758_R_UNKNOWN_ALGORITHM_TYPE);
619 return 0;
620 }
621
622 if (!algorithm.algorithm->length)
623 {
624 CCA4758err(CCA4758_F_IBM_4758_CCA_VERIFY,
625 CCA4758_R_ASN1_OID_UNKNOWN_FOR_MD);
626 return 0;
627 }
628
629 parameter.type = V_ASN1_NULL;
630 parameter.value.ptr = NULL;
631 algorithm.parameter = &parameter;
632
633 sig.digest = &digest;
634 sig.digest->data = (unsigned char*)m;
635 sig.digest->length = m_len;
636
637 length = i2d_X509_SIG(&sig, NULL);
638 }
639
640 keyLength = RSA_size(rsa);
641
642 if (length - RSA_PKCS1_PADDING > keyLength)
643 {
644 CCA4758err(CCA4758_F_IBM_4758_CCA_VERIFY,
645 CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
646 return 0;
647 }
648
649 switch (type)
650 {
651 case NID_md5_sha1 :
652 if (m_len != SSL_SIG_LEN)
653 {
654 CCA4758err(CCA4758_F_IBM_4758_CCA_VERIFY,
655 CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
656 return 0;
657 }
658
659 hashBuffer = (unsigned char *)m;
660 length = m_len;
661 break;
662 case NID_md5 :
663 {
664 unsigned char *ptr;
665 ptr = hashBuffer = OPENSSL_malloc(
666 (unsigned int)keyLength+1);
667 if (!hashBuffer)
668 {
669 CCA4758err(CCA4758_F_IBM_4758_CCA_VERIFY,
670 ERR_R_MALLOC_FAILURE);
671 return 0;
672 }
673
674 i2d_X509_SIG(&sig, &ptr);
675 }
676 break;
677 case NID_sha1 :
678 {
679 unsigned char *ptr;
680 ptr = hashBuffer = OPENSSL_malloc(
681 (unsigned int)keyLength+1);
682 if (!hashBuffer)
683 {
684 CCA4758err(CCA4758_F_IBM_4758_CCA_VERIFY,
685 ERR_R_MALLOC_FAILURE);
686 return 0;
687 }
688 i2d_X509_SIG(&sig, &ptr);
689 }
690 break;
691 default:
692 return 0;
693 }
694
695 digitalSignatureVerify(&returnCode, &reasonCode, &exitDataLength,
696 exitData, &ruleArrayLength, ruleArray, &keyTokenLength,
697 keyToken, &length, hashBuffer, &lsiglen, sigbuf);
698
699 if (type == NID_sha1 || type == NID_md5)
700 {
701 memset(hashBuffer, keyLength+1, 0);
702 OPENSSL_free(hashBuffer);
703 }
704
705 return ((returnCode || reasonCode) ? 0 : 1);
706 }
707
708#define SSL_SIG_LEN 36
709
710static int cca_rsa_sign(int type, const unsigned char *m, unsigned int m_len,
711 unsigned char *sigret, unsigned int *siglen, const RSA *rsa)
712 {
713 long returnCode;
714 long reasonCode;
715 long exitDataLength = 0;
716 unsigned char exitData[8];
717 long ruleArrayLength = 1;
718 unsigned char ruleArray[8] = "PKCS-1.1";
719 long outputLength=256;
720 long outputBitLength;
721 long keyTokenLength;
722 unsigned char *hashBuffer = NULL;
723 unsigned char* keyToken = (unsigned char*)RSA_get_ex_data(rsa, hndidx);
724 long length = SSL_SIG_LEN;
725 long keyLength ;
726 X509_SIG sig;
727 ASN1_TYPE parameter;
728 X509_ALGOR algorithm;
729 ASN1_OCTET_STRING digest;
730
731 keyTokenLength = *(long*)keyToken;
732 keyToken+=sizeof(long);
733
734 if (type == NID_md5 || type == NID_sha1)
735 {
736 sig.algor = &algorithm;
737 algorithm.algorithm = OBJ_nid2obj(type);
738
739 if (!algorithm.algorithm)
740 {
741 CCA4758err(CCA4758_F_IBM_4758_CCA_SIGN,
742 CCA4758_R_UNKNOWN_ALGORITHM_TYPE);
743 return 0;
744 }
745
746 if (!algorithm.algorithm->length)
747 {
748 CCA4758err(CCA4758_F_IBM_4758_CCA_SIGN,
749 CCA4758_R_ASN1_OID_UNKNOWN_FOR_MD);
750 return 0;
751 }
752
753 parameter.type = V_ASN1_NULL;
754 parameter.value.ptr = NULL;
755 algorithm.parameter = &parameter;
756
757 sig.digest = &digest;
758 sig.digest->data = (unsigned char*)m;
759 sig.digest->length = m_len;
760
761 length = i2d_X509_SIG(&sig, NULL);
762 }
763
764 keyLength = RSA_size(rsa);
765
766 if (length - RSA_PKCS1_PADDING > keyLength)
767 {
768 CCA4758err(CCA4758_F_IBM_4758_CCA_SIGN,
769 CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
770 return 0;
771 }
772
773 switch (type)
774 {
775 case NID_md5_sha1 :
776 if (m_len != SSL_SIG_LEN)
777 {
778 CCA4758err(CCA4758_F_IBM_4758_CCA_SIGN,
779 CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
780 return 0;
781 }
782 hashBuffer = (unsigned char*)m;
783 length = m_len;
784 break;
785 case NID_md5 :
786 {
787 unsigned char *ptr;
788 ptr = hashBuffer = OPENSSL_malloc(
789 (unsigned int)keyLength+1);
790 if (!hashBuffer)
791 {
792 CCA4758err(CCA4758_F_IBM_4758_CCA_VERIFY,
793 ERR_R_MALLOC_FAILURE);
794 return 0;
795 }
796 i2d_X509_SIG(&sig, &ptr);
797 }
798 break;
799 case NID_sha1 :
800 {
801 unsigned char *ptr;
802 ptr = hashBuffer = OPENSSL_malloc(
803 (unsigned int)keyLength+1);
804 if (!hashBuffer)
805 {
806 CCA4758err(CCA4758_F_IBM_4758_CCA_VERIFY,
807 ERR_R_MALLOC_FAILURE);
808 return 0;
809 }
810 i2d_X509_SIG(&sig, &ptr);
811 }
812 break;
813 default:
814 return 0;
815 }
816
817 digitalSignatureGenerate(&returnCode, &reasonCode, &exitDataLength,
818 exitData, &ruleArrayLength, ruleArray, &keyTokenLength,
819 keyToken, &length, hashBuffer, &outputLength, &outputBitLength,
820 sigret);
821
822 if (type == NID_sha1 || type == NID_md5)
823 {
824 memset(hashBuffer, keyLength+1, 0);
825 OPENSSL_free(hashBuffer);
826 }
827
828 *siglen = outputLength;
829
830 return ((returnCode || reasonCode) ? 0 : 1);
831 }
832
833static int getModulusAndExponent(const unsigned char*token, long *exponentLength,
834 unsigned char *exponent, long *modulusLength, long *modulusFieldLength,
835 unsigned char *modulus)
836 {
837 unsigned long len;
838
839 if (*token++ != (char)0x1E) /* internal PKA token? */
840 return 0;
841
842 if (*token++) /* token version must be zero */
843 return 0;
844
845 len = *token++;
846 len = len << 8;
847 len |= (unsigned char)*token++;
848
849 token += 4; /* skip reserved bytes */
850
851 if (*token++ == (char)0x04)
852 {
853 if (*token++) /* token version must be zero */
854 return 0;
855
856 len = *token++;
857 len = len << 8;
858 len |= (unsigned char)*token++;
859
860 token+=2; /* skip reserved section */
861
862 len = *token++;
863 len = len << 8;
864 len |= (unsigned char)*token++;
865
866 *exponentLength = len;
867
868 len = *token++;
869 len = len << 8;
870 len |= (unsigned char)*token++;
871
872 *modulusLength = len;
873
874 len = *token++;
875 len = len << 8;
876 len |= (unsigned char)*token++;
877
878 *modulusFieldLength = len;
879
880 memcpy(exponent, token, *exponentLength);
881 token+= *exponentLength;
882
883 memcpy(modulus, token, *modulusFieldLength);
884 return 1;
885 }
886 return 0;
887 }
888
889#endif /* OPENSSL_NO_RSA */
890
891static int cca_random_status(void)
892 {
893 return 1;
894 }
895
896static int cca_get_random_bytes(unsigned char* buf, int num)
897 {
898 long ret_code;
899 long reason_code;
900 long exit_data_length;
901 unsigned char exit_data[4];
902 unsigned char form[] = "RANDOM ";
903 unsigned char rand_buf[8];
904
905 while(num >= sizeof(rand_buf))
906 {
907 randomNumberGenerate(&ret_code, &reason_code, &exit_data_length,
908 exit_data, form, rand_buf);
909 if (ret_code)
910 return 0;
911 num -= sizeof(rand_buf);
912 memcpy(buf, rand_buf, sizeof(rand_buf));
913 buf += sizeof(rand_buf);
914 }
915
916 if (num)
917 {
918 randomNumberGenerate(&ret_code, &reason_code, NULL, NULL,
919 form, rand_buf);
920 if (ret_code)
921 return 0;
922 memcpy(buf, rand_buf, num);
923 }
924
925 return 1;
926 }
927
928static void cca_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad, int idx,
929 long argl, void *argp)
930 {
931 if (item)
932 OPENSSL_free(item);
933 }
934
935/* Goo to handle building as a dynamic engine */
936#ifdef ENGINE_DYNAMIC_SUPPORT
937static int bind_fn(ENGINE *e, const char *id)
938 {
939 if(id && (strcmp(id, engine_cswift_id) != 0))
940 return 0;
941 if(!bind_helper(e))
942 return 0;
943 return 1;
944 }
945IMPLEMENT_DYNAMIC_CHECK_FN()
946IMPLEMENT_DYNAMIC_BIND_FN(bind_fn)
947#endif /* ENGINE_DYNAMIC_SUPPORT */
948
949#endif /* !OPENSSL_NO_HW_4758_CCA */
950#endif /* !OPENSSL_NO_HW */
diff --git a/src/lib/libcrypto/engine/hw_4758_cca_err.c b/src/lib/libcrypto/engine/hw_4758_cca_err.c
new file mode 100644
index 0000000000..7ea5c63707
--- /dev/null
+++ b/src/lib/libcrypto/engine/hw_4758_cca_err.c
@@ -0,0 +1,149 @@
1/* hw_4758_cca_err.c */
2/* ====================================================================
3 * Copyright (c) 1999-2002 The OpenSSL Project. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
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
15 * distribution.
16 *
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/)"
21 *
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 * openssl-core@OpenSSL.org.
26 *
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.
30 *
31 * 6. Redistributions of any form whatsoever must retain the following
32 * acknowledgment:
33 * "This product includes software developed by the OpenSSL Project
34 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
35 *
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 * ====================================================================
49 *
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).
53 *
54 */
55
56/* NOTE: this file was auto generated by the mkerr.pl script: any changes
57 * made to it will be overwritten when the script next updates this file,
58 * only reason strings will be preserved.
59 */
60
61#include <stdio.h>
62#include <openssl/err.h>
63#include "hw_4758_cca_err.h"
64
65/* BEGIN ERROR CODES */
66#ifndef OPENSSL_NO_ERR
67static ERR_STRING_DATA CCA4758_str_functs[]=
68 {
69{ERR_PACK(0,CCA4758_F_IBM_4758_CCA_CTRL,0), "IBM_4758_CCA_CTRL"},
70{ERR_PACK(0,CCA4758_F_IBM_4758_CCA_FINISH,0), "IBM_4758_CCA_FINISH"},
71{ERR_PACK(0,CCA4758_F_IBM_4758_CCA_INIT,0), "IBM_4758_CCA_INIT"},
72{ERR_PACK(0,CCA4758_F_IBM_4758_CCA_LOAD_PRIVKEY,0), "IBM_4758_CCA_LOAD_PRIVKEY"},
73{ERR_PACK(0,CCA4758_F_IBM_4758_CCA_LOAD_PUBKEY,0), "IBM_4758_CCA_LOAD_PUBKEY"},
74{ERR_PACK(0,CCA4758_F_IBM_4758_CCA_SIGN,0), "IBM_4758_CCA_SIGN"},
75{ERR_PACK(0,CCA4758_F_IBM_4758_CCA_VERIFY,0), "IBM_4758_CCA_VERIFY"},
76{0,NULL}
77 };
78
79static ERR_STRING_DATA CCA4758_str_reasons[]=
80 {
81{CCA4758_R_ALREADY_LOADED ,"already loaded"},
82{CCA4758_R_ASN1_OID_UNKNOWN_FOR_MD ,"asn1 oid unknown for md"},
83{CCA4758_R_COMMAND_NOT_IMPLEMENTED ,"command not implemented"},
84{CCA4758_R_DSO_FAILURE ,"dso failure"},
85{CCA4758_R_FAILED_LOADING_PRIVATE_KEY ,"failed loading private key"},
86{CCA4758_R_FAILED_LOADING_PUBLIC_KEY ,"failed loading public key"},
87{CCA4758_R_NOT_LOADED ,"not loaded"},
88{CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL ,"size too large or too small"},
89{CCA4758_R_UNIT_FAILURE ,"unit failure"},
90{CCA4758_R_UNKNOWN_ALGORITHM_TYPE ,"unknown algorithm type"},
91{0,NULL}
92 };
93
94#endif
95
96#ifdef CCA4758_LIB_NAME
97static ERR_STRING_DATA CCA4758_lib_name[]=
98 {
99{0 ,CCA4758_LIB_NAME},
100{0,NULL}
101 };
102#endif
103
104
105static int CCA4758_lib_error_code=0;
106static int CCA4758_error_init=1;
107
108static void ERR_load_CCA4758_strings(void)
109 {
110 if (CCA4758_lib_error_code == 0)
111 CCA4758_lib_error_code=ERR_get_next_error_library();
112
113 if (CCA4758_error_init)
114 {
115 CCA4758_error_init=0;
116#ifndef OPENSSL_NO_ERR
117 ERR_load_strings(CCA4758_lib_error_code,CCA4758_str_functs);
118 ERR_load_strings(CCA4758_lib_error_code,CCA4758_str_reasons);
119#endif
120
121#ifdef CCA4758_LIB_NAME
122 CCA4758_lib_name->error = ERR_PACK(CCA4758_lib_error_code,0,0);
123 ERR_load_strings(0,CCA4758_lib_name);
124#endif
125 }
126 }
127
128static void ERR_unload_CCA4758_strings(void)
129 {
130 if (CCA4758_error_init == 0)
131 {
132#ifndef OPENSSL_NO_ERR
133 ERR_unload_strings(CCA4758_lib_error_code,CCA4758_str_functs);
134 ERR_unload_strings(CCA4758_lib_error_code,CCA4758_str_reasons);
135#endif
136
137#ifdef CCA4758_LIB_NAME
138 ERR_unload_strings(0,CCA4758_lib_name);
139#endif
140 CCA4758_error_init=1;
141 }
142 }
143
144static void ERR_CCA4758_error(int function, int reason, char *file, int line)
145 {
146 if (CCA4758_lib_error_code == 0)
147 CCA4758_lib_error_code=ERR_get_next_error_library();
148 ERR_PUT_error(CCA4758_lib_error_code,function,reason,file,line);
149 }
diff --git a/src/lib/libcrypto/engine/hw_4758_cca_err.h b/src/lib/libcrypto/engine/hw_4758_cca_err.h
new file mode 100644
index 0000000000..2fc563ab11
--- /dev/null
+++ b/src/lib/libcrypto/engine/hw_4758_cca_err.h
@@ -0,0 +1,93 @@
1/* ====================================================================
2 * Copyright (c) 2001 The OpenSSL Project. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in
13 * the documentation and/or other materials provided with the
14 * distribution.
15 *
16 * 3. All advertising materials mentioning features or use of this
17 * software must display the following acknowledgment:
18 * "This product includes software developed by the OpenSSL Project
19 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
20 *
21 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
22 * endorse or promote products derived from this software without
23 * prior written permission. For written permission, please contact
24 * openssl-core@openssl.org.
25 *
26 * 5. Products derived from this software may not be called "OpenSSL"
27 * nor may "OpenSSL" appear in their names without prior written
28 * permission of the OpenSSL Project.
29 *
30 * 6. Redistributions of any form whatsoever must retain the following
31 * acknowledgment:
32 * "This product includes software developed by the OpenSSL Project
33 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
34 *
35 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
36 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
37 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
38 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
39 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
41 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
42 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
43 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
44 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
45 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
46 * OF THE POSSIBILITY OF SUCH DAMAGE.
47 * ====================================================================
48 *
49 * This product includes cryptographic software written by Eric Young
50 * (eay@cryptsoft.com). This product includes software written by Tim
51 * Hudson (tjh@cryptsoft.com).
52 *
53 */
54
55#ifndef HEADER_CCA4758_ERR_H
56#define HEADER_CCA4758_ERR_H
57
58/* BEGIN ERROR CODES */
59/* The following lines are auto generated by the script mkerr.pl. Any changes
60 * made after this point may be overwritten when the script is next run.
61 */
62static void ERR_load_CCA4758_strings(void);
63static void ERR_unload_CCA4758_strings(void);
64static void ERR_CCA4758_error(int function, int reason, char *file, int line);
65#define CCA4758err(f,r) ERR_CCA4758_error((f),(r),__FILE__,__LINE__)
66
67/* Error codes for the CCA4758 functions. */
68
69/* Function codes. */
70#define CCA4758_F_IBM_4758_CCA_CTRL 100
71#define CCA4758_F_IBM_4758_CCA_FINISH 101
72#define CCA4758_F_IBM_4758_CCA_INIT 102
73#define CCA4758_F_IBM_4758_CCA_LOAD_PRIVKEY 103
74#define CCA4758_F_IBM_4758_CCA_LOAD_PUBKEY 104
75#define CCA4758_F_IBM_4758_CCA_SIGN 105
76#define CCA4758_F_IBM_4758_CCA_VERIFY 106
77
78/* Reason codes. */
79#define CCA4758_R_ALREADY_LOADED 100
80#define CCA4758_R_ASN1_OID_UNKNOWN_FOR_MD 101
81#define CCA4758_R_COMMAND_NOT_IMPLEMENTED 102
82#define CCA4758_R_DSO_FAILURE 103
83#define CCA4758_R_FAILED_LOADING_PRIVATE_KEY 104
84#define CCA4758_R_FAILED_LOADING_PUBLIC_KEY 105
85#define CCA4758_R_NOT_LOADED 106
86#define CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL 107
87#define CCA4758_R_UNIT_FAILURE 108
88#define CCA4758_R_UNKNOWN_ALGORITHM_TYPE 109
89
90#ifdef __cplusplus
91}
92#endif
93#endif
diff --git a/src/lib/libcrypto/engine/hw_aep.c b/src/lib/libcrypto/engine/hw_aep.c
new file mode 100644
index 0000000000..cf4507cff1
--- /dev/null
+++ b/src/lib/libcrypto/engine/hw_aep.c
@@ -0,0 +1,1101 @@
1/* crypto/engine/hw_aep.c */
2/*
3 */
4/* ====================================================================
5 * Copyright (c) 1999 The OpenSSL Project. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 *
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in
16 * the documentation and/or other materials provided with the
17 * distribution.
18 *
19 * 3. All advertising materials mentioning features or use of this
20 * software must display the following acknowledgment:
21 * "This product includes software developed by the OpenSSL Project
22 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
23 *
24 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
25 * endorse or promote products derived from this software without
26 * prior written permission. For written permission, please contact
27 * licensing@OpenSSL.org.
28 *
29 * 5. Products derived from this software may not be called "OpenSSL"
30 * nor may "OpenSSL" appear in their names without prior written
31 * permission of the OpenSSL Project.
32 *
33 * 6. Redistributions of any form whatsoever must retain the following
34 * acknowledgment:
35 * "This product includes software developed by the OpenSSL Project
36 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
37 *
38 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
39 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
40 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
41 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
42 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
43 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
44 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
45 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
46 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
47 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
48 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
49 * OF THE POSSIBILITY OF SUCH DAMAGE.
50 * ====================================================================
51 *
52 * This product includes cryptographic software written by Eric Young
53 * (eay@cryptsoft.com). This product includes software written by Tim
54 * Hudson (tjh@cryptsoft.com).
55 *
56 */
57
58#include <stdio.h>
59#include <openssl/bn.h>
60#include <string.h>
61
62#include <openssl/e_os2.h>
63#ifndef OPENSSL_SYS_MSDOS
64#include <sys/types.h>
65#include <unistd.h>
66#else
67#include <process.h>
68typedef int pid_t;
69#endif
70
71#include <openssl/crypto.h>
72#include <openssl/dso.h>
73#include <openssl/engine.h>
74
75#ifndef OPENSSL_NO_HW
76#ifndef OPENSSL_NO_HW_AEP
77#ifdef FLAT_INC
78#include "aep.h"
79#else
80#include "vendor_defns/aep.h"
81#endif
82
83#define AEP_LIB_NAME "aep engine"
84#define FAIL_TO_SW 0x10101010
85
86#include "hw_aep_err.c"
87
88static int aep_init(ENGINE *e);
89static int aep_finish(ENGINE *e);
90static int aep_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)());
91static int aep_destroy(ENGINE *e);
92
93static AEP_RV aep_get_connection(AEP_CONNECTION_HNDL_PTR hConnection);
94static AEP_RV aep_return_connection(AEP_CONNECTION_HNDL hConnection);
95static AEP_RV aep_close_connection(AEP_CONNECTION_HNDL hConnection);
96static AEP_RV aep_close_all_connections(int use_engine_lock, int *in_use);
97
98/* BIGNUM stuff */
99static int aep_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
100 const BIGNUM *m, BN_CTX *ctx);
101
102static AEP_RV aep_mod_exp_crt(BIGNUM *r,const BIGNUM *a, const BIGNUM *p,
103 const BIGNUM *q, const BIGNUM *dmp1,const BIGNUM *dmq1,
104 const BIGNUM *iqmp, BN_CTX *ctx);
105
106/* RSA stuff */
107#ifndef OPENSSL_NO_RSA
108static int aep_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa);
109#endif
110
111/* This function is aliased to mod_exp (with the mont stuff dropped). */
112static int aep_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
113 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
114
115/* DSA stuff */
116#ifndef OPENSSL_NO_DSA
117static int aep_dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1,
118 BIGNUM *p1, BIGNUM *a2, BIGNUM *p2, BIGNUM *m,
119 BN_CTX *ctx, BN_MONT_CTX *in_mont);
120
121static int aep_mod_exp_dsa(DSA *dsa, BIGNUM *r, BIGNUM *a,
122 const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
123 BN_MONT_CTX *m_ctx);
124#endif
125
126/* DH stuff */
127/* This function is aliased to mod_exp (with the DH and mont dropped). */
128#ifndef OPENSSL_NO_DH
129static int aep_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a,
130 const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
131#endif
132
133/* rand stuff */
134#ifdef AEPRAND
135static int aep_rand(unsigned char *buf, int num);
136static int aep_rand_status(void);
137#endif
138
139/* Bignum conversion stuff */
140static AEP_RV GetBigNumSize(AEP_VOID_PTR ArbBigNum, AEP_U32* BigNumSize);
141static AEP_RV MakeAEPBigNum(AEP_VOID_PTR ArbBigNum, AEP_U32 BigNumSize,
142 unsigned char* AEP_BigNum);
143static AEP_RV ConvertAEPBigNum(void* ArbBigNum, AEP_U32 BigNumSize,
144 unsigned char* AEP_BigNum);
145
146/* The definitions for control commands specific to this engine */
147#define AEP_CMD_SO_PATH ENGINE_CMD_BASE
148static const ENGINE_CMD_DEFN aep_cmd_defns[] =
149 {
150 { AEP_CMD_SO_PATH,
151 "SO_PATH",
152 "Specifies the path to the 'aep' shared library",
153 ENGINE_CMD_FLAG_STRING
154 },
155 {0, NULL, NULL, 0}
156 };
157
158#ifndef OPENSSL_NO_RSA
159/* Our internal RSA_METHOD that we provide pointers to */
160static RSA_METHOD aep_rsa =
161 {
162 "Aep RSA method",
163 NULL, /*rsa_pub_encrypt*/
164 NULL, /*rsa_pub_decrypt*/
165 NULL, /*rsa_priv_encrypt*/
166 NULL, /*rsa_priv_encrypt*/
167 aep_rsa_mod_exp, /*rsa_mod_exp*/
168 aep_mod_exp_mont, /*bn_mod_exp*/
169 NULL, /*init*/
170 NULL, /*finish*/
171 0, /*flags*/
172 NULL, /*app_data*/
173 NULL, /*rsa_sign*/
174 NULL /*rsa_verify*/
175 };
176#endif
177
178#ifndef OPENSSL_NO_DSA
179/* Our internal DSA_METHOD that we provide pointers to */
180static DSA_METHOD aep_dsa =
181 {
182 "Aep DSA method",
183 NULL, /* dsa_do_sign */
184 NULL, /* dsa_sign_setup */
185 NULL, /* dsa_do_verify */
186 aep_dsa_mod_exp, /* dsa_mod_exp */
187 aep_mod_exp_dsa, /* bn_mod_exp */
188 NULL, /* init */
189 NULL, /* finish */
190 0, /* flags */
191 NULL /* app_data */
192 };
193#endif
194
195#ifndef OPENSSL_NO_DH
196/* Our internal DH_METHOD that we provide pointers to */
197static DH_METHOD aep_dh =
198 {
199 "Aep DH method",
200 NULL,
201 NULL,
202 aep_mod_exp_dh,
203 NULL,
204 NULL,
205 0,
206 NULL
207 };
208#endif
209
210#ifdef AEPRAND
211/* our internal RAND_method that we provide pointers to */
212static RAND_METHOD aep_random =
213 {
214 /*"AEP RAND method", */
215 NULL,
216 aep_rand,
217 NULL,
218 NULL,
219 aep_rand,
220 aep_rand_status,
221 };
222#endif
223
224/*Define an array of structures to hold connections*/
225static AEP_CONNECTION_ENTRY aep_app_conn_table[MAX_PROCESS_CONNECTIONS];
226
227/*Used to determine if this is a new process*/
228static pid_t recorded_pid = 0;
229
230#ifdef AEPRAND
231static AEP_U8 rand_block[RAND_BLK_SIZE];
232static AEP_U32 rand_block_bytes = 0;
233#endif
234
235/* Constants used when creating the ENGINE */
236static const char *engine_aep_id = "aep";
237static const char *engine_aep_name = "Aep hardware engine support";
238
239static int max_key_len = 2176;
240
241
242/* This internal function is used by ENGINE_aep() and possibly by the
243 * "dynamic" ENGINE support too */
244static int bind_aep(ENGINE *e)
245 {
246#ifndef OPENSSL_NO_RSA
247 const RSA_METHOD *meth1;
248#endif
249#ifndef OPENSSL_NO_DSA
250 const DSA_METHOD *meth2;
251#endif
252#ifndef OPENSSL_NO_DH
253 const DH_METHOD *meth3;
254#endif
255
256 if(!ENGINE_set_id(e, engine_aep_id) ||
257 !ENGINE_set_name(e, engine_aep_name) ||
258#ifndef OPENSSL_NO_RSA
259 !ENGINE_set_RSA(e, &aep_rsa) ||
260#endif
261#ifndef OPENSSL_NO_DSA
262 !ENGINE_set_DSA(e, &aep_dsa) ||
263#endif
264#ifndef OPENSSL_NO_DH
265 !ENGINE_set_DH(e, &aep_dh) ||
266#endif
267#ifdef AEPRAND
268 !ENGINE_set_RAND(e, &aep_random) ||
269#endif
270 !ENGINE_set_init_function(e, aep_init) ||
271 !ENGINE_set_destroy_function(e, aep_destroy) ||
272 !ENGINE_set_finish_function(e, aep_finish) ||
273 !ENGINE_set_ctrl_function(e, aep_ctrl) ||
274 !ENGINE_set_cmd_defns(e, aep_cmd_defns))
275 return 0;
276
277#ifndef OPENSSL_NO_RSA
278 /* We know that the "PKCS1_SSLeay()" functions hook properly
279 * to the aep-specific mod_exp and mod_exp_crt so we use
280 * those functions. NB: We don't use ENGINE_openssl() or
281 * anything "more generic" because something like the RSAref
282 * code may not hook properly, and if you own one of these
283 * cards then you have the right to do RSA operations on it
284 * anyway! */
285 meth1 = RSA_PKCS1_SSLeay();
286 aep_rsa.rsa_pub_enc = meth1->rsa_pub_enc;
287 aep_rsa.rsa_pub_dec = meth1->rsa_pub_dec;
288 aep_rsa.rsa_priv_enc = meth1->rsa_priv_enc;
289 aep_rsa.rsa_priv_dec = meth1->rsa_priv_dec;
290#endif
291
292
293#ifndef OPENSSL_NO_DSA
294 /* Use the DSA_OpenSSL() method and just hook the mod_exp-ish
295 * bits. */
296 meth2 = DSA_OpenSSL();
297 aep_dsa.dsa_do_sign = meth2->dsa_do_sign;
298 aep_dsa.dsa_sign_setup = meth2->dsa_sign_setup;
299 aep_dsa.dsa_do_verify = meth2->dsa_do_verify;
300
301 aep_dsa = *DSA_get_default_method();
302 aep_dsa.dsa_mod_exp = aep_dsa_mod_exp;
303 aep_dsa.bn_mod_exp = aep_mod_exp_dsa;
304#endif
305
306#ifndef OPENSSL_NO_DH
307 /* Much the same for Diffie-Hellman */
308 meth3 = DH_OpenSSL();
309 aep_dh.generate_key = meth3->generate_key;
310 aep_dh.compute_key = meth3->compute_key;
311 aep_dh.bn_mod_exp = meth3->bn_mod_exp;
312#endif
313
314 /* Ensure the aep error handling is set up */
315 ERR_load_AEPHK_strings();
316
317 return 1;
318}
319
320#ifdef ENGINE_DYNAMIC_SUPPORT
321static int bind_helper(ENGINE *e, const char *id)
322 {
323 if(id && (strcmp(id, engine_aep_id) != 0))
324 return 0;
325 if(!bind_aep(e))
326 return 0;
327 return 1;
328 }
329IMPLEMENT_DYNAMIC_CHECK_FN()
330IMPLEMENT_DYNAMIC_BIND_FN(bind_helper)
331#else
332static ENGINE *engine_aep(void)
333 {
334 ENGINE *ret = ENGINE_new();
335 if(!ret)
336 return NULL;
337 if(!bind_aep(ret))
338 {
339 ENGINE_free(ret);
340 return NULL;
341 }
342 return ret;
343 }
344
345void ENGINE_load_aep(void)
346 {
347 /* Copied from eng_[openssl|dyn].c */
348 ENGINE *toadd = engine_aep();
349 if(!toadd) return;
350 ENGINE_add(toadd);
351 ENGINE_free(toadd);
352 ERR_clear_error();
353 }
354#endif
355
356/* This is a process-global DSO handle used for loading and unloading
357 * the Aep library. NB: This is only set (or unset) during an
358 * init() or finish() call (reference counts permitting) and they're
359 * operating with global locks, so this should be thread-safe
360 * implicitly. */
361static DSO *aep_dso = NULL;
362
363/* These are the static string constants for the DSO file name and the function
364 * symbol names to bind to.
365*/
366static const char *AEP_LIBNAME = "aep";
367
368static const char *AEP_F1 = "AEP_ModExp";
369static const char *AEP_F2 = "AEP_ModExpCrt";
370#ifdef AEPRAND
371static const char *AEP_F3 = "AEP_GenRandom";
372#endif
373static const char *AEP_F4 = "AEP_Finalize";
374static const char *AEP_F5 = "AEP_Initialize";
375static const char *AEP_F6 = "AEP_OpenConnection";
376static const char *AEP_F7 = "AEP_SetBNCallBacks";
377static const char *AEP_F8 = "AEP_CloseConnection";
378
379/* These are the function pointers that are (un)set when the library has
380 * successfully (un)loaded. */
381static t_AEP_OpenConnection *p_AEP_OpenConnection = NULL;
382static t_AEP_CloseConnection *p_AEP_CloseConnection = NULL;
383static t_AEP_ModExp *p_AEP_ModExp = NULL;
384static t_AEP_ModExpCrt *p_AEP_ModExpCrt = NULL;
385#ifdef AEPRAND
386static t_AEP_GenRandom *p_AEP_GenRandom = NULL;
387#endif
388static t_AEP_Initialize *p_AEP_Initialize = NULL;
389static t_AEP_Finalize *p_AEP_Finalize = NULL;
390static t_AEP_SetBNCallBacks *p_AEP_SetBNCallBacks = NULL;
391
392/* (de)initialisation functions. */
393static int aep_init(ENGINE *e)
394 {
395 t_AEP_ModExp *p1;
396 t_AEP_ModExpCrt *p2;
397#ifdef AEPRAND
398 t_AEP_GenRandom *p3;
399#endif
400 t_AEP_Finalize *p4;
401 t_AEP_Initialize *p5;
402 t_AEP_OpenConnection *p6;
403 t_AEP_SetBNCallBacks *p7;
404 t_AEP_CloseConnection *p8;
405
406 int to_return = 0;
407
408 if(aep_dso != NULL)
409 {
410 AEPHKerr(AEPHK_F_AEP_INIT,AEPHK_R_ALREADY_LOADED);
411 goto err;
412 }
413 /* Attempt to load libaep.so. */
414
415 aep_dso = DSO_load(NULL, AEP_LIBNAME, NULL, 0);
416
417 if(aep_dso == NULL)
418 {
419 AEPHKerr(AEPHK_F_AEP_INIT,AEPHK_R_NOT_LOADED);
420 goto err;
421 }
422
423 if( !(p1 = (t_AEP_ModExp *) DSO_bind_func( aep_dso,AEP_F1)) ||
424 !(p2 = (t_AEP_ModExpCrt*) DSO_bind_func( aep_dso,AEP_F2)) ||
425#ifdef AEPRAND
426 !(p3 = (t_AEP_GenRandom*) DSO_bind_func( aep_dso,AEP_F3)) ||
427#endif
428 !(p4 = (t_AEP_Finalize*) DSO_bind_func( aep_dso,AEP_F4)) ||
429 !(p5 = (t_AEP_Initialize*) DSO_bind_func( aep_dso,AEP_F5)) ||
430 !(p6 = (t_AEP_OpenConnection*) DSO_bind_func( aep_dso,AEP_F6)) ||
431 !(p7 = (t_AEP_SetBNCallBacks*) DSO_bind_func( aep_dso,AEP_F7)) ||
432 !(p8 = (t_AEP_CloseConnection*) DSO_bind_func( aep_dso,AEP_F8)))
433 {
434 AEPHKerr(AEPHK_F_AEP_INIT,AEPHK_R_NOT_LOADED);
435 goto err;
436 }
437
438 /* Copy the pointers */
439
440 p_AEP_ModExp = p1;
441 p_AEP_ModExpCrt = p2;
442#ifdef AEPRAND
443 p_AEP_GenRandom = p3;
444#endif
445 p_AEP_Finalize = p4;
446 p_AEP_Initialize = p5;
447 p_AEP_OpenConnection = p6;
448 p_AEP_SetBNCallBacks = p7;
449 p_AEP_CloseConnection = p8;
450
451 to_return = 1;
452
453 return to_return;
454
455 err:
456
457 if(aep_dso)
458 DSO_free(aep_dso);
459
460 p_AEP_OpenConnection = NULL;
461 p_AEP_ModExp = NULL;
462 p_AEP_ModExpCrt = NULL;
463#ifdef AEPRAND
464 p_AEP_GenRandom = NULL;
465#endif
466 p_AEP_Initialize = NULL;
467 p_AEP_Finalize = NULL;
468 p_AEP_SetBNCallBacks = NULL;
469 p_AEP_CloseConnection = NULL;
470
471 return to_return;
472 }
473
474/* Destructor (complements the "ENGINE_aep()" constructor) */
475static int aep_destroy(ENGINE *e)
476 {
477 ERR_unload_AEPHK_strings();
478 return 1;
479 }
480
481static int aep_finish(ENGINE *e)
482 {
483 int to_return = 0, in_use;
484 AEP_RV rv;
485
486 if(aep_dso == NULL)
487 {
488 AEPHKerr(AEPHK_F_AEP_FINISH,AEPHK_R_NOT_LOADED);
489 goto err;
490 }
491
492 rv = aep_close_all_connections(0, &in_use);
493 if (rv != AEP_R_OK)
494 {
495 AEPHKerr(AEPHK_F_AEP_FINISH,AEPHK_R_CLOSE_HANDLES_FAILED);
496 goto err;
497 }
498 if (in_use)
499 {
500 AEPHKerr(AEPHK_F_AEP_FINISH,AEPHK_R_CONNECTIONS_IN_USE);
501 goto err;
502 }
503
504 rv = p_AEP_Finalize();
505 if (rv != AEP_R_OK)
506 {
507 AEPHKerr(AEPHK_F_AEP_FINISH,AEPHK_R_FINALIZE_FAILED);
508 goto err;
509 }
510
511 if(!DSO_free(aep_dso))
512 {
513 AEPHKerr(AEPHK_F_AEP_FINISH,AEPHK_R_UNIT_FAILURE);
514 goto err;
515 }
516
517 aep_dso = NULL;
518 p_AEP_CloseConnection = NULL;
519 p_AEP_OpenConnection = NULL;
520 p_AEP_ModExp = NULL;
521 p_AEP_ModExpCrt = NULL;
522#ifdef AEPRAND
523 p_AEP_GenRandom = NULL;
524#endif
525 p_AEP_Initialize = NULL;
526 p_AEP_Finalize = NULL;
527 p_AEP_SetBNCallBacks = NULL;
528
529 to_return = 1;
530 err:
531 return to_return;
532 }
533
534static int aep_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)())
535 {
536 int initialised = ((aep_dso == NULL) ? 0 : 1);
537 switch(cmd)
538 {
539 case AEP_CMD_SO_PATH:
540 if(p == NULL)
541 {
542 AEPHKerr(AEPHK_F_AEP_CTRL,
543 ERR_R_PASSED_NULL_PARAMETER);
544 return 0;
545 }
546 if(initialised)
547 {
548 AEPHKerr(AEPHK_F_AEP_CTRL,
549 AEPHK_R_ALREADY_LOADED);
550 return 0;
551 }
552 AEP_LIBNAME = (const char *)p;
553 return 1;
554 default:
555 break;
556 }
557 AEPHKerr(AEPHK_F_AEP_CTRL,AEPHK_R_CTRL_COMMAND_NOT_IMPLEMENTED);
558 return 0;
559 }
560
561static int aep_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
562 const BIGNUM *m, BN_CTX *ctx)
563 {
564 int to_return = 0;
565 int r_len = 0;
566 AEP_CONNECTION_HNDL hConnection;
567 AEP_RV rv;
568
569 r_len = BN_num_bits(m);
570
571 /* Perform in software if modulus is too large for hardware. */
572
573 if (r_len > max_key_len){
574 AEPHKerr(AEPHK_F_AEP_MOD_EXP, AEPHK_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
575 return BN_mod_exp(r, a, p, m, ctx);
576 }
577
578 /*Grab a connection from the pool*/
579 rv = aep_get_connection(&hConnection);
580 if (rv != AEP_R_OK)
581 {
582 AEPHKerr(AEPHK_F_AEP_MOD_EXP,AEPHK_R_GET_HANDLE_FAILED);
583 return BN_mod_exp(r, a, p, m, ctx);
584 }
585
586 /*To the card with the mod exp*/
587 rv = p_AEP_ModExp(hConnection,(void*)a, (void*)p,(void*)m, (void*)r,NULL);
588
589 if (rv != AEP_R_OK)
590 {
591 AEPHKerr(AEPHK_F_AEP_MOD_EXP,AEPHK_R_MOD_EXP_FAILED);
592 rv = aep_close_connection(hConnection);
593 return BN_mod_exp(r, a, p, m, ctx);
594 }
595
596 /*Return the connection to the pool*/
597 rv = aep_return_connection(hConnection);
598 if (rv != AEP_R_OK)
599 {
600 AEPHKerr(AEPHK_F_AEP_RAND,AEPHK_R_RETURN_CONNECTION_FAILED);
601 goto err;
602 }
603
604 to_return = 1;
605 err:
606 return to_return;
607 }
608
609static AEP_RV aep_mod_exp_crt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
610 const BIGNUM *q, const BIGNUM *dmp1,
611 const BIGNUM *dmq1,const BIGNUM *iqmp, BN_CTX *ctx)
612 {
613 AEP_RV rv = AEP_R_OK;
614 AEP_CONNECTION_HNDL hConnection;
615
616 /*Grab a connection from the pool*/
617 rv = aep_get_connection(&hConnection);
618 if (rv != AEP_R_OK)
619 {
620 AEPHKerr(AEPHK_F_AEP_MOD_EXP_CRT,AEPHK_R_GET_HANDLE_FAILED);
621 return FAIL_TO_SW;
622 }
623
624 /*To the card with the mod exp*/
625 rv = p_AEP_ModExpCrt(hConnection,(void*)a, (void*)p, (void*)q, (void*)dmp1,(void*)dmq1,
626 (void*)iqmp,(void*)r,NULL);
627 if (rv != AEP_R_OK)
628 {
629 AEPHKerr(AEPHK_F_AEP_MOD_EXP_CRT,AEPHK_R_MOD_EXP_CRT_FAILED);
630 rv = aep_close_connection(hConnection);
631 return FAIL_TO_SW;
632 }
633
634 /*Return the connection to the pool*/
635 rv = aep_return_connection(hConnection);
636 if (rv != AEP_R_OK)
637 {
638 AEPHKerr(AEPHK_F_AEP_RAND,AEPHK_R_RETURN_CONNECTION_FAILED);
639 goto err;
640 }
641
642 err:
643 return rv;
644 }
645
646
647#ifdef AEPRAND
648static int aep_rand(unsigned char *buf,int len )
649 {
650 AEP_RV rv = AEP_R_OK;
651 AEP_CONNECTION_HNDL hConnection;
652
653 CRYPTO_w_lock(CRYPTO_LOCK_RAND);
654
655 /*Can the request be serviced with what's already in the buffer?*/
656 if (len <= rand_block_bytes)
657 {
658 memcpy(buf, &rand_block[RAND_BLK_SIZE - rand_block_bytes], len);
659 rand_block_bytes -= len;
660 CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
661 }
662 else
663 /*If not the get another block of random bytes*/
664 {
665 CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
666
667 rv = aep_get_connection(&hConnection);
668 if (rv != AEP_R_OK)
669 {
670 AEPHKerr(AEPHK_F_AEP_RAND,AEPHK_R_GET_HANDLE_FAILED);
671 goto err_nounlock;
672 }
673
674 if (len > RAND_BLK_SIZE)
675 {
676 rv = p_AEP_GenRandom(hConnection, len, 2, buf, NULL);
677 if (rv != AEP_R_OK)
678 {
679 AEPHKerr(AEPHK_F_AEP_RAND,AEPHK_R_GET_RANDOM_FAILED);
680 goto err_nounlock;
681 }
682 }
683 else
684 {
685 CRYPTO_w_lock(CRYPTO_LOCK_RAND);
686
687 rv = p_AEP_GenRandom(hConnection, RAND_BLK_SIZE, 2, &rand_block[0], NULL);
688 if (rv != AEP_R_OK)
689 {
690 AEPHKerr(AEPHK_F_AEP_RAND,AEPHK_R_GET_RANDOM_FAILED);
691
692 goto err;
693 }
694
695 rand_block_bytes = RAND_BLK_SIZE;
696
697 memcpy(buf, &rand_block[RAND_BLK_SIZE - rand_block_bytes], len);
698 rand_block_bytes -= len;
699
700 CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
701 }
702
703 rv = aep_return_connection(hConnection);
704 if (rv != AEP_R_OK)
705 {
706 AEPHKerr(AEPHK_F_AEP_RAND,AEPHK_R_RETURN_CONNECTION_FAILED);
707
708 goto err_nounlock;
709 }
710 }
711
712 return 1;
713 err:
714 CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
715 err_nounlock:
716 return 0;
717 }
718
719static int aep_rand_status(void)
720{
721 return 1;
722}
723#endif
724
725#ifndef OPENSSL_NO_RSA
726static int aep_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa)
727 {
728 BN_CTX *ctx = NULL;
729 int to_return = 0;
730 AEP_RV rv = AEP_R_OK;
731
732 if ((ctx = BN_CTX_new()) == NULL)
733 goto err;
734
735 if (!aep_dso)
736 {
737 AEPHKerr(AEPHK_F_AEP_RSA_MOD_EXP,AEPHK_R_NOT_LOADED);
738 goto err;
739 }
740
741 /*See if we have all the necessary bits for a crt*/
742 if (rsa->q && rsa->dmp1 && rsa->dmq1 && rsa->iqmp)
743 {
744 rv = aep_mod_exp_crt(r0,I,rsa->p,rsa->q, rsa->dmp1,rsa->dmq1,rsa->iqmp,ctx);
745
746 if (rv == FAIL_TO_SW){
747 const RSA_METHOD *meth = RSA_PKCS1_SSLeay();
748 to_return = (*meth->rsa_mod_exp)(r0, I, rsa);
749 goto err;
750 }
751 else if (rv != AEP_R_OK)
752 goto err;
753 }
754 else
755 {
756 if (!rsa->d || !rsa->n)
757 {
758 AEPHKerr(AEPHK_F_AEP_RSA_MOD_EXP,AEPHK_R_MISSING_KEY_COMPONENTS);
759 goto err;
760 }
761
762 rv = aep_mod_exp(r0,I,rsa->d,rsa->n,ctx);
763 if (rv != AEP_R_OK)
764 goto err;
765
766 }
767
768 to_return = 1;
769
770 err:
771 if(ctx)
772 BN_CTX_free(ctx);
773 return to_return;
774}
775#endif
776
777#ifndef OPENSSL_NO_DSA
778static int aep_dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1,
779 BIGNUM *p1, BIGNUM *a2, BIGNUM *p2, BIGNUM *m,
780 BN_CTX *ctx, BN_MONT_CTX *in_mont)
781 {
782 BIGNUM t;
783 int to_return = 0;
784 BN_init(&t);
785
786 /* let rr = a1 ^ p1 mod m */
787 if (!aep_mod_exp(rr,a1,p1,m,ctx)) goto end;
788 /* let t = a2 ^ p2 mod m */
789 if (!aep_mod_exp(&t,a2,p2,m,ctx)) goto end;
790 /* let rr = rr * t mod m */
791 if (!BN_mod_mul(rr,rr,&t,m,ctx)) goto end;
792 to_return = 1;
793 end:
794 BN_free(&t);
795 return to_return;
796 }
797
798static int aep_mod_exp_dsa(DSA *dsa, BIGNUM *r, BIGNUM *a,
799 const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
800 BN_MONT_CTX *m_ctx)
801 {
802 return aep_mod_exp(r, a, p, m, ctx);
803 }
804#endif
805
806/* This function is aliased to mod_exp (with the mont stuff dropped). */
807static int aep_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
808 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
809 {
810 return aep_mod_exp(r, a, p, m, ctx);
811 }
812
813#ifndef OPENSSL_NO_DH
814/* This function is aliased to mod_exp (with the dh and mont dropped). */
815static int aep_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a,
816 const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
817 BN_MONT_CTX *m_ctx)
818 {
819 return aep_mod_exp(r, a, p, m, ctx);
820 }
821#endif
822
823static AEP_RV aep_get_connection(AEP_CONNECTION_HNDL_PTR phConnection)
824 {
825 int count;
826 AEP_RV rv = AEP_R_OK;
827
828 /*Get the current process id*/
829 pid_t curr_pid;
830
831 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
832
833 curr_pid = getpid();
834
835 /*Check if this is the first time this is being called from the current
836 process*/
837 if (recorded_pid != curr_pid)
838 {
839 /*Remember our pid so we can check if we're in a new process*/
840 recorded_pid = curr_pid;
841
842 /*Call Finalize to make sure we have not inherited some data
843 from a parent process*/
844 p_AEP_Finalize();
845
846 /*Initialise the AEP API*/
847 rv = p_AEP_Initialize(NULL);
848
849 if (rv != AEP_R_OK)
850 {
851 AEPHKerr(AEPHK_F_AEP_GET_CONNECTION,AEPHK_R_INIT_FAILURE);
852 recorded_pid = 0;
853 goto end;
854 }
855
856 /*Set the AEP big num call back functions*/
857 rv = p_AEP_SetBNCallBacks(&GetBigNumSize, &MakeAEPBigNum,
858 &ConvertAEPBigNum);
859
860 if (rv != AEP_R_OK)
861 {
862 AEPHKerr(AEPHK_F_AEP_GET_CONNECTION,AEPHK_R_SETBNCALLBACK_FAILURE);
863 recorded_pid = 0;
864 goto end;
865 }
866
867#ifdef AEPRAND
868 /*Reset the rand byte count*/
869 rand_block_bytes = 0;
870#endif
871
872 /*Init the structures*/
873 for (count = 0;count < MAX_PROCESS_CONNECTIONS;count ++)
874 {
875 aep_app_conn_table[count].conn_state = NotConnected;
876 aep_app_conn_table[count].conn_hndl = 0;
877 }
878
879 /*Open a connection*/
880 rv = p_AEP_OpenConnection(phConnection);
881
882 if (rv != AEP_R_OK)
883 {
884 AEPHKerr(AEPHK_F_AEP_GET_CONNECTION,AEPHK_R_UNIT_FAILURE);
885 recorded_pid = 0;
886 goto end;
887 }
888
889 aep_app_conn_table[0].conn_state = InUse;
890 aep_app_conn_table[0].conn_hndl = *phConnection;
891 goto end;
892 }
893 /*Check the existing connections to see if we can find a free one*/
894 for (count = 0;count < MAX_PROCESS_CONNECTIONS;count ++)
895 {
896 if (aep_app_conn_table[count].conn_state == Connected)
897 {
898 aep_app_conn_table[count].conn_state = InUse;
899 *phConnection = aep_app_conn_table[count].conn_hndl;
900 goto end;
901 }
902 }
903 /*If no connections available, we're going to have to try
904 to open a new one*/
905 for (count = 0;count < MAX_PROCESS_CONNECTIONS;count ++)
906 {
907 if (aep_app_conn_table[count].conn_state == NotConnected)
908 {
909 /*Open a connection*/
910 rv = p_AEP_OpenConnection(phConnection);
911
912 if (rv != AEP_R_OK)
913 {
914 AEPHKerr(AEPHK_F_AEP_GET_CONNECTION,AEPHK_R_UNIT_FAILURE);
915 goto end;
916 }
917
918 aep_app_conn_table[count].conn_state = InUse;
919 aep_app_conn_table[count].conn_hndl = *phConnection;
920 goto end;
921 }
922 }
923 rv = AEP_R_GENERAL_ERROR;
924 end:
925 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
926 return rv;
927 }
928
929
930static AEP_RV aep_return_connection(AEP_CONNECTION_HNDL hConnection)
931 {
932 int count;
933
934 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
935
936 /*Find the connection item that matches this connection handle*/
937 for(count = 0;count < MAX_PROCESS_CONNECTIONS;count ++)
938 {
939 if (aep_app_conn_table[count].conn_hndl == hConnection)
940 {
941 aep_app_conn_table[count].conn_state = Connected;
942 break;
943 }
944 }
945
946 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
947
948 return AEP_R_OK;
949 }
950
951static AEP_RV aep_close_connection(AEP_CONNECTION_HNDL hConnection)
952 {
953 int count;
954 AEP_RV rv = AEP_R_OK;
955
956 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
957
958 /*Find the connection item that matches this connection handle*/
959 for(count = 0;count < MAX_PROCESS_CONNECTIONS;count ++)
960 {
961 if (aep_app_conn_table[count].conn_hndl == hConnection)
962 {
963 rv = p_AEP_CloseConnection(aep_app_conn_table[count].conn_hndl);
964 if (rv != AEP_R_OK)
965 goto end;
966 aep_app_conn_table[count].conn_state = NotConnected;
967 aep_app_conn_table[count].conn_hndl = 0;
968 break;
969 }
970 }
971
972 end:
973 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
974 return rv;
975 }
976
977static AEP_RV aep_close_all_connections(int use_engine_lock, int *in_use)
978 {
979 int count;
980 AEP_RV rv = AEP_R_OK;
981
982 *in_use = 0;
983 if (use_engine_lock) CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
984 for (count = 0;count < MAX_PROCESS_CONNECTIONS;count ++)
985 {
986 switch (aep_app_conn_table[count].conn_state)
987 {
988 case Connected:
989 rv = p_AEP_CloseConnection(aep_app_conn_table[count].conn_hndl);
990 if (rv != AEP_R_OK)
991 goto end;
992 aep_app_conn_table[count].conn_state = NotConnected;
993 aep_app_conn_table[count].conn_hndl = 0;
994 break;
995 case InUse:
996 (*in_use)++;
997 break;
998 case NotConnected:
999 break;
1000 }
1001 }
1002 end:
1003 if (use_engine_lock) CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
1004 return rv;
1005 }
1006
1007/*BigNum call back functions, used to convert OpenSSL bignums into AEP bignums.
1008 Note only 32bit Openssl build support*/
1009
1010static AEP_RV GetBigNumSize(AEP_VOID_PTR ArbBigNum, AEP_U32* BigNumSize)
1011 {
1012 BIGNUM* bn;
1013
1014 /*Cast the ArbBigNum pointer to our BIGNUM struct*/
1015 bn = (BIGNUM*) ArbBigNum;
1016
1017#ifdef SIXTY_FOUR_BIT_LONG
1018 *BigNumSize = bn->top << 3;
1019#else
1020 /*Size of the bignum in bytes is equal to the bn->top (no of 32 bit
1021 words) multiplies by 4*/
1022 *BigNumSize = bn->top << 2;
1023#endif
1024
1025 return AEP_R_OK;
1026 }
1027
1028static AEP_RV MakeAEPBigNum(AEP_VOID_PTR ArbBigNum, AEP_U32 BigNumSize,
1029 unsigned char* AEP_BigNum)
1030 {
1031 BIGNUM* bn;
1032
1033#ifndef SIXTY_FOUR_BIT_LONG
1034 unsigned char* buf;
1035 int i;
1036#endif
1037
1038 /*Cast the ArbBigNum pointer to our BIGNUM struct*/
1039 bn = (BIGNUM*) ArbBigNum;
1040
1041#ifdef SIXTY_FOUR_BIT_LONG
1042 memcpy(AEP_BigNum, bn->d, BigNumSize);
1043#else
1044 /*Must copy data into a (monotone) least significant byte first format
1045 performing endian conversion if necessary*/
1046 for(i=0;i<bn->top;i++)
1047 {
1048 buf = (unsigned char*)&bn->d[i];
1049
1050 *((AEP_U32*)AEP_BigNum) = (AEP_U32)
1051 ((unsigned) buf[1] << 8 | buf[0]) |
1052 ((unsigned) buf[3] << 8 | buf[2]) << 16;
1053
1054 AEP_BigNum += 4;
1055 }
1056#endif
1057
1058 return AEP_R_OK;
1059 }
1060
1061/*Turn an AEP Big Num back to a user big num*/
1062static AEP_RV ConvertAEPBigNum(void* ArbBigNum, AEP_U32 BigNumSize,
1063 unsigned char* AEP_BigNum)
1064 {
1065 BIGNUM* bn;
1066#ifndef SIXTY_FOUR_BIT_LONG
1067 int i;
1068#endif
1069
1070 bn = (BIGNUM*)ArbBigNum;
1071
1072 /*Expand the result bn so that it can hold our big num.
1073 Size is in bits*/
1074 bn_expand(bn, (int)(BigNumSize << 3));
1075
1076#ifdef SIXTY_FOUR_BIT_LONG
1077 bn->top = BigNumSize >> 3;
1078
1079 if((BigNumSize & 7) != 0)
1080 bn->top++;
1081
1082 memset(bn->d, 0, bn->top << 3);
1083
1084 memcpy(bn->d, AEP_BigNum, BigNumSize);
1085#else
1086 bn->top = BigNumSize >> 2;
1087
1088 for(i=0;i<bn->top;i++)
1089 {
1090 bn->d[i] = (AEP_U32)
1091 ((unsigned) AEP_BigNum[3] << 8 | AEP_BigNum[2]) << 16 |
1092 ((unsigned) AEP_BigNum[1] << 8 | AEP_BigNum[0]);
1093 AEP_BigNum += 4;
1094 }
1095#endif
1096
1097 return AEP_R_OK;
1098}
1099
1100#endif /* !OPENSSL_NO_HW_AEP */
1101#endif /* !OPENSSL_NO_HW */
diff --git a/src/lib/libcrypto/engine/hw_aep_err.c b/src/lib/libcrypto/engine/hw_aep_err.c
new file mode 100644
index 0000000000..092f532946
--- /dev/null
+++ b/src/lib/libcrypto/engine/hw_aep_err.c
@@ -0,0 +1,157 @@
1/* hw_aep_err.c */
2/* ====================================================================
3 * Copyright (c) 1999 The OpenSSL Project. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
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
15 * distribution.
16 *
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/)"
21 *
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 * openssl-core@OpenSSL.org.
26 *
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.
30 *
31 * 6. Redistributions of any form whatsoever must retain the following
32 * acknowledgment:
33 * "This product includes software developed by the OpenSSL Project
34 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
35 *
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 * ====================================================================
49 *
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).
53 *
54 */
55
56/* NOTE: this file was auto generated by the mkerr.pl script: any changes
57 * made to it will be overwritten when the script next updates this file,
58 * only reason strings will be preserved.
59 */
60
61#include <stdio.h>
62#include <openssl/err.h>
63#include "hw_aep_err.h"
64
65/* BEGIN ERROR CODES */
66#ifndef OPENSSL_NO_ERR
67static ERR_STRING_DATA AEPHK_str_functs[]=
68 {
69{ERR_PACK(0,AEPHK_F_AEP_CTRL,0), "AEP_CTRL"},
70{ERR_PACK(0,AEPHK_F_AEP_FINISH,0), "AEP_FINISH"},
71{ERR_PACK(0,AEPHK_F_AEP_GET_CONNECTION,0), "AEP_GET_CONNECTION"},
72{ERR_PACK(0,AEPHK_F_AEP_INIT,0), "AEP_INIT"},
73{ERR_PACK(0,AEPHK_F_AEP_MOD_EXP,0), "AEP_MOD_EXP"},
74{ERR_PACK(0,AEPHK_F_AEP_MOD_EXP_CRT,0), "AEP_MOD_EXP_CRT"},
75{ERR_PACK(0,AEPHK_F_AEP_RAND,0), "AEP_RAND"},
76{ERR_PACK(0,AEPHK_F_AEP_RSA_MOD_EXP,0), "AEP_RSA_MOD_EXP"},
77{0,NULL}
78 };
79
80static ERR_STRING_DATA AEPHK_str_reasons[]=
81 {
82{AEPHK_R_ALREADY_LOADED ,"already loaded"},
83{AEPHK_R_CLOSE_HANDLES_FAILED ,"close handles failed"},
84{AEPHK_R_CONNECTIONS_IN_USE ,"connections in use"},
85{AEPHK_R_CTRL_COMMAND_NOT_IMPLEMENTED ,"ctrl command not implemented"},
86{AEPHK_R_FINALIZE_FAILED ,"finalize failed"},
87{AEPHK_R_GET_HANDLE_FAILED ,"get handle failed"},
88{AEPHK_R_GET_RANDOM_FAILED ,"get random failed"},
89{AEPHK_R_INIT_FAILURE ,"init failure"},
90{AEPHK_R_MISSING_KEY_COMPONENTS ,"missing key components"},
91{AEPHK_R_MOD_EXP_CRT_FAILED ,"mod exp crt failed"},
92{AEPHK_R_MOD_EXP_FAILED ,"mod exp failed"},
93{AEPHK_R_NOT_LOADED ,"not loaded"},
94{AEPHK_R_OK ,"ok"},
95{AEPHK_R_RETURN_CONNECTION_FAILED ,"return connection failed"},
96{AEPHK_R_SETBNCALLBACK_FAILURE ,"setbncallback failure"},
97{AEPHK_R_SIZE_TOO_LARGE_OR_TOO_SMALL ,"size too large or too small"},
98{AEPHK_R_UNIT_FAILURE ,"unit failure"},
99{0,NULL}
100 };
101
102#endif
103
104#ifdef AEPHK_LIB_NAME
105static ERR_STRING_DATA AEPHK_lib_name[]=
106 {
107{0 ,AEPHK_LIB_NAME},
108{0,NULL}
109 };
110#endif
111
112
113static int AEPHK_lib_error_code=0;
114static int AEPHK_error_init=1;
115
116static void ERR_load_AEPHK_strings(void)
117 {
118 if (AEPHK_lib_error_code == 0)
119 AEPHK_lib_error_code=ERR_get_next_error_library();
120
121 if (AEPHK_error_init)
122 {
123 AEPHK_error_init=0;
124#ifndef OPENSSL_NO_ERR
125 ERR_load_strings(AEPHK_lib_error_code,AEPHK_str_functs);
126 ERR_load_strings(AEPHK_lib_error_code,AEPHK_str_reasons);
127#endif
128
129#ifdef AEPHK_LIB_NAME
130 AEPHK_lib_name->error = ERR_PACK(AEPHK_lib_error_code,0,0);
131 ERR_load_strings(0,AEPHK_lib_name);
132#endif
133 }
134 }
135
136static void ERR_unload_AEPHK_strings(void)
137 {
138 if (AEPHK_error_init == 0)
139 {
140#ifndef OPENSSL_NO_ERR
141 ERR_unload_strings(AEPHK_lib_error_code,AEPHK_str_functs);
142 ERR_unload_strings(AEPHK_lib_error_code,AEPHK_str_reasons);
143#endif
144
145#ifdef AEPHK_LIB_NAME
146 ERR_unload_strings(0,AEPHK_lib_name);
147#endif
148 AEPHK_error_init=1;
149 }
150 }
151
152static void ERR_AEPHK_error(int function, int reason, char *file, int line)
153 {
154 if (AEPHK_lib_error_code == 0)
155 AEPHK_lib_error_code=ERR_get_next_error_library();
156 ERR_PUT_error(AEPHK_lib_error_code,function,reason,file,line);
157 }
diff --git a/src/lib/libcrypto/engine/hw_aep_err.h b/src/lib/libcrypto/engine/hw_aep_err.h
new file mode 100644
index 0000000000..8fe4cf921f
--- /dev/null
+++ b/src/lib/libcrypto/engine/hw_aep_err.h
@@ -0,0 +1,101 @@
1/* ====================================================================
2 * Copyright (c) 2001 The OpenSSL Project. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in
13 * the documentation and/or other materials provided with the
14 * distribution.
15 *
16 * 3. All advertising materials mentioning features or use of this
17 * software must display the following acknowledgment:
18 * "This product includes software developed by the OpenSSL Project
19 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
20 *
21 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
22 * endorse or promote products derived from this software without
23 * prior written permission. For written permission, please contact
24 * openssl-core@openssl.org.
25 *
26 * 5. Products derived from this software may not be called "OpenSSL"
27 * nor may "OpenSSL" appear in their names without prior written
28 * permission of the OpenSSL Project.
29 *
30 * 6. Redistributions of any form whatsoever must retain the following
31 * acknowledgment:
32 * "This product includes software developed by the OpenSSL Project
33 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
34 *
35 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
36 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
37 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
38 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
39 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
41 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
42 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
43 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
44 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
45 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
46 * OF THE POSSIBILITY OF SUCH DAMAGE.
47 * ====================================================================
48 *
49 * This product includes cryptographic software written by Eric Young
50 * (eay@cryptsoft.com). This product includes software written by Tim
51 * Hudson (tjh@cryptsoft.com).
52 *
53 */
54
55#ifndef HEADER_AEPHK_ERR_H
56#define HEADER_AEPHK_ERR_H
57
58/* BEGIN ERROR CODES */
59/* The following lines are auto generated by the script mkerr.pl. Any changes
60 * made after this point may be overwritten when the script is next run.
61 */
62static void ERR_load_AEPHK_strings(void);
63static void ERR_unload_AEPHK_strings(void);
64static void ERR_AEPHK_error(int function, int reason, char *file, int line);
65#define AEPHKerr(f,r) ERR_AEPHK_error((f),(r),__FILE__,__LINE__)
66
67/* Error codes for the AEPHK functions. */
68
69/* Function codes. */
70#define AEPHK_F_AEP_CTRL 100
71#define AEPHK_F_AEP_FINISH 101
72#define AEPHK_F_AEP_GET_CONNECTION 102
73#define AEPHK_F_AEP_INIT 103
74#define AEPHK_F_AEP_MOD_EXP 104
75#define AEPHK_F_AEP_MOD_EXP_CRT 105
76#define AEPHK_F_AEP_RAND 106
77#define AEPHK_F_AEP_RSA_MOD_EXP 107
78
79/* Reason codes. */
80#define AEPHK_R_ALREADY_LOADED 100
81#define AEPHK_R_CLOSE_HANDLES_FAILED 101
82#define AEPHK_R_CONNECTIONS_IN_USE 102
83#define AEPHK_R_CTRL_COMMAND_NOT_IMPLEMENTED 103
84#define AEPHK_R_FINALIZE_FAILED 104
85#define AEPHK_R_GET_HANDLE_FAILED 105
86#define AEPHK_R_GET_RANDOM_FAILED 106
87#define AEPHK_R_INIT_FAILURE 107
88#define AEPHK_R_MISSING_KEY_COMPONENTS 108
89#define AEPHK_R_MOD_EXP_CRT_FAILED 109
90#define AEPHK_R_MOD_EXP_FAILED 110
91#define AEPHK_R_NOT_LOADED 111
92#define AEPHK_R_OK 112
93#define AEPHK_R_RETURN_CONNECTION_FAILED 113
94#define AEPHK_R_SETBNCALLBACK_FAILURE 114
95#define AEPHK_R_SIZE_TOO_LARGE_OR_TOO_SMALL 116
96#define AEPHK_R_UNIT_FAILURE 115
97
98#ifdef __cplusplus
99}
100#endif
101#endif
diff --git a/src/lib/libcrypto/engine/hw_atalla.c b/src/lib/libcrypto/engine/hw_atalla.c
new file mode 100644
index 0000000000..3bb992a193
--- /dev/null
+++ b/src/lib/libcrypto/engine/hw_atalla.c
@@ -0,0 +1,444 @@
1/* crypto/engine/hw_atalla.c */
2/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
3 * project 2000.
4 */
5/* ====================================================================
6 * Copyright (c) 1999 The OpenSSL Project. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * 3. All advertising materials mentioning features or use of this
21 * software must display the following acknowledgment:
22 * "This product includes software developed by the OpenSSL Project
23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24 *
25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26 * endorse or promote products derived from this software without
27 * prior written permission. For written permission, please contact
28 * licensing@OpenSSL.org.
29 *
30 * 5. Products derived from this software may not be called "OpenSSL"
31 * nor may "OpenSSL" appear in their names without prior written
32 * permission of the OpenSSL Project.
33 *
34 * 6. Redistributions of any form whatsoever must retain the following
35 * acknowledgment:
36 * "This product includes software developed by the OpenSSL Project
37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38 *
39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50 * OF THE POSSIBILITY OF SUCH DAMAGE.
51 * ====================================================================
52 *
53 * This product includes cryptographic software written by Eric Young
54 * (eay@cryptsoft.com). This product includes software written by Tim
55 * Hudson (tjh@cryptsoft.com).
56 *
57 */
58
59#include <stdio.h>
60#include <openssl/crypto.h>
61#include "cryptlib.h"
62#include <openssl/dso.h>
63#include "engine_int.h"
64#include <openssl/engine.h>
65
66#ifndef NO_HW
67#ifndef NO_HW_ATALLA
68
69#ifdef FLAT_INC
70#include "atalla.h"
71#else
72#include "vendor_defns/atalla.h"
73#endif
74
75static int atalla_init(void);
76static int atalla_finish(void);
77
78/* BIGNUM stuff */
79static int atalla_mod_exp(BIGNUM *r, BIGNUM *a, const BIGNUM *p,
80 const BIGNUM *m, BN_CTX *ctx);
81
82/* RSA stuff */
83static int atalla_rsa_mod_exp(BIGNUM *r0, BIGNUM *I, RSA *rsa);
84/* This function is aliased to mod_exp (with the mont stuff dropped). */
85static int atalla_mod_exp_mont(BIGNUM *r, BIGNUM *a, const BIGNUM *p,
86 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
87
88/* DSA stuff */
89static int atalla_dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1,
90 BIGNUM *p1, BIGNUM *a2, BIGNUM *p2, BIGNUM *m,
91 BN_CTX *ctx, BN_MONT_CTX *in_mont);
92static int atalla_mod_exp_dsa(DSA *dsa, BIGNUM *r, BIGNUM *a,
93 const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
94 BN_MONT_CTX *m_ctx);
95
96/* DH stuff */
97/* This function is alised to mod_exp (with the DH and mont dropped). */
98static int atalla_mod_exp_dh(DH *dh, BIGNUM *r, BIGNUM *a, const BIGNUM *p,
99 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
100
101
102/* Our internal RSA_METHOD that we provide pointers to */
103static RSA_METHOD atalla_rsa =
104 {
105 "Atalla RSA method",
106 NULL,
107 NULL,
108 NULL,
109 NULL,
110 atalla_rsa_mod_exp,
111 atalla_mod_exp_mont,
112 NULL,
113 NULL,
114 0,
115 NULL,
116 NULL,
117 NULL
118 };
119
120/* Our internal DSA_METHOD that we provide pointers to */
121static DSA_METHOD atalla_dsa =
122 {
123 "Atalla DSA method",
124 NULL, /* dsa_do_sign */
125 NULL, /* dsa_sign_setup */
126 NULL, /* dsa_do_verify */
127 atalla_dsa_mod_exp, /* dsa_mod_exp */
128 atalla_mod_exp_dsa, /* bn_mod_exp */
129 NULL, /* init */
130 NULL, /* finish */
131 0, /* flags */
132 NULL /* app_data */
133 };
134
135/* Our internal DH_METHOD that we provide pointers to */
136static DH_METHOD atalla_dh =
137 {
138 "Atalla DH method",
139 NULL,
140 NULL,
141 atalla_mod_exp_dh,
142 NULL,
143 NULL,
144 0,
145 NULL
146 };
147
148/* Our ENGINE structure. */
149static ENGINE engine_atalla =
150 {
151 "atalla",
152 "Atalla hardware engine support",
153 &atalla_rsa,
154 &atalla_dsa,
155 &atalla_dh,
156 NULL,
157 atalla_mod_exp,
158 NULL,
159 atalla_init,
160 atalla_finish,
161 NULL, /* no ctrl() */
162 NULL, /* no load_privkey() */
163 NULL, /* no load_pubkey() */
164 0, /* no flags */
165 0, 0, /* no references */
166 NULL, NULL /* unlinked */
167 };
168
169/* As this is only ever called once, there's no need for locking
170 * (indeed - the lock will already be held by our caller!!!) */
171ENGINE *ENGINE_atalla()
172 {
173 RSA_METHOD *meth1;
174 DSA_METHOD *meth2;
175 DH_METHOD *meth3;
176
177 /* We know that the "PKCS1_SSLeay()" functions hook properly
178 * to the atalla-specific mod_exp and mod_exp_crt so we use
179 * those functions. NB: We don't use ENGINE_openssl() or
180 * anything "more generic" because something like the RSAref
181 * code may not hook properly, and if you own one of these
182 * cards then you have the right to do RSA operations on it
183 * anyway! */
184 meth1 = RSA_PKCS1_SSLeay();
185 atalla_rsa.rsa_pub_enc = meth1->rsa_pub_enc;
186 atalla_rsa.rsa_pub_dec = meth1->rsa_pub_dec;
187 atalla_rsa.rsa_priv_enc = meth1->rsa_priv_enc;
188 atalla_rsa.rsa_priv_dec = meth1->rsa_priv_dec;
189
190 /* Use the DSA_OpenSSL() method and just hook the mod_exp-ish
191 * bits. */
192 meth2 = DSA_OpenSSL();
193 atalla_dsa.dsa_do_sign = meth2->dsa_do_sign;
194 atalla_dsa.dsa_sign_setup = meth2->dsa_sign_setup;
195 atalla_dsa.dsa_do_verify = meth2->dsa_do_verify;
196
197 /* Much the same for Diffie-Hellman */
198 meth3 = DH_OpenSSL();
199 atalla_dh.generate_key = meth3->generate_key;
200 atalla_dh.compute_key = meth3->compute_key;
201 return &engine_atalla;
202 }
203
204/* This is a process-global DSO handle used for loading and unloading
205 * the Atalla library. NB: This is only set (or unset) during an
206 * init() or finish() call (reference counts permitting) and they're
207 * operating with global locks, so this should be thread-safe
208 * implicitly. */
209static DSO *atalla_dso = NULL;
210
211/* These are the function pointers that are (un)set when the library has
212 * successfully (un)loaded. */
213static tfnASI_GetHardwareConfig *p_Atalla_GetHardwareConfig = NULL;
214static tfnASI_RSAPrivateKeyOpFn *p_Atalla_RSAPrivateKeyOpFn = NULL;
215static tfnASI_GetPerformanceStatistics *p_Atalla_GetPerformanceStatistics = NULL;
216
217/* (de)initialisation functions. */
218static int atalla_init()
219 {
220 tfnASI_GetHardwareConfig *p1;
221 tfnASI_RSAPrivateKeyOpFn *p2;
222 tfnASI_GetPerformanceStatistics *p3;
223 /* Not sure of the origin of this magic value, but Ben's code had it
224 * and it seemed to have been working for a few people. :-) */
225 unsigned int config_buf[1024];
226
227 if(atalla_dso != NULL)
228 {
229 ENGINEerr(ENGINE_F_ATALLA_INIT,ENGINE_R_ALREADY_LOADED);
230 goto err;
231 }
232 /* Attempt to load libatasi.so/atasi.dll/whatever. Needs to be
233 * changed unfortunately because the Atalla drivers don't have
234 * standard library names that can be platform-translated well. */
235 /* TODO: Work out how to actually map to the names the Atalla
236 * drivers really use - for now a symbollic link needs to be
237 * created on the host system from libatasi.so to atasi.so on
238 * unix variants. */
239 atalla_dso = DSO_load(NULL, ATALLA_LIBNAME, NULL,
240 DSO_FLAG_NAME_TRANSLATION);
241 if(atalla_dso == NULL)
242 {
243 ENGINEerr(ENGINE_F_ATALLA_INIT,ENGINE_R_DSO_FAILURE);
244 goto err;
245 }
246 if(!(p1 = (tfnASI_GetHardwareConfig *)DSO_bind_func(
247 atalla_dso, ATALLA_F1)) ||
248 !(p2 = (tfnASI_RSAPrivateKeyOpFn *)DSO_bind_func(
249 atalla_dso, ATALLA_F2)) ||
250 !(p3 = (tfnASI_GetPerformanceStatistics *)DSO_bind_func(
251 atalla_dso, ATALLA_F3)))
252 {
253 ENGINEerr(ENGINE_F_ATALLA_INIT,ENGINE_R_DSO_FAILURE);
254 goto err;
255 }
256 /* Copy the pointers */
257 p_Atalla_GetHardwareConfig = p1;
258 p_Atalla_RSAPrivateKeyOpFn = p2;
259 p_Atalla_GetPerformanceStatistics = p3;
260 /* Perform a basic test to see if there's actually any unit
261 * running. */
262 if(p1(0L, config_buf) != 0)
263 {
264 ENGINEerr(ENGINE_F_ATALLA_INIT,ENGINE_R_UNIT_FAILURE);
265 goto err;
266 }
267 /* Everything's fine. */
268 return 1;
269err:
270 if(atalla_dso)
271 DSO_free(atalla_dso);
272 p_Atalla_GetHardwareConfig = NULL;
273 p_Atalla_RSAPrivateKeyOpFn = NULL;
274 p_Atalla_GetPerformanceStatistics = NULL;
275 return 0;
276 }
277
278static int atalla_finish()
279 {
280 if(atalla_dso == NULL)
281 {
282 ENGINEerr(ENGINE_F_ATALLA_FINISH,ENGINE_R_NOT_LOADED);
283 return 0;
284 }
285 if(!DSO_free(atalla_dso))
286 {
287 ENGINEerr(ENGINE_F_ATALLA_FINISH,ENGINE_R_DSO_FAILURE);
288 return 0;
289 }
290 atalla_dso = NULL;
291 p_Atalla_GetHardwareConfig = NULL;
292 p_Atalla_RSAPrivateKeyOpFn = NULL;
293 p_Atalla_GetPerformanceStatistics = NULL;
294 return 1;
295 }
296
297static int atalla_mod_exp(BIGNUM *r, BIGNUM *a, const BIGNUM *p,
298 const BIGNUM *m, BN_CTX *ctx)
299 {
300 /* I need somewhere to store temporary serialised values for
301 * use with the Atalla API calls. A neat cheat - I'll use
302 * BIGNUMs from the BN_CTX but access their arrays directly as
303 * byte arrays <grin>. This way I don't have to clean anything
304 * up. */
305 BIGNUM *modulus;
306 BIGNUM *exponent;
307 BIGNUM *argument;
308 BIGNUM *result;
309 RSAPrivateKey keydata;
310 int to_return, numbytes;
311
312 modulus = exponent = argument = result = NULL;
313 to_return = 0; /* expect failure */
314
315 if(!atalla_dso)
316 {
317 ENGINEerr(ENGINE_F_ATALLA_MOD_EXP,ENGINE_R_NOT_LOADED);
318 goto err;
319 }
320 /* Prepare the params */
321 modulus = BN_CTX_get(ctx);
322 exponent = BN_CTX_get(ctx);
323 argument = BN_CTX_get(ctx);
324 result = BN_CTX_get(ctx);
325 if(!modulus || !exponent || !argument || !result)
326 {
327 ENGINEerr(ENGINE_F_ATALLA_MOD_EXP,ENGINE_R_BN_CTX_FULL);
328 goto err;
329 }
330 if(!bn_wexpand(modulus, m->top) || !bn_wexpand(exponent, m->top) ||
331 !bn_wexpand(argument, m->top) || !bn_wexpand(result, m->top))
332 {
333 ENGINEerr(ENGINE_F_ATALLA_MOD_EXP,ENGINE_R_BN_EXPAND_FAIL);
334 goto err;
335 }
336 /* Prepare the key-data */
337 memset(&keydata, 0,sizeof keydata);
338 numbytes = BN_num_bytes(m);
339 memset(exponent->d, 0, numbytes);
340 memset(modulus->d, 0, numbytes);
341 BN_bn2bin(p, (unsigned char *)exponent->d + numbytes - BN_num_bytes(p));
342 BN_bn2bin(m, (unsigned char *)modulus->d + numbytes - BN_num_bytes(m));
343 keydata.privateExponent.data = (unsigned char *)exponent->d;
344 keydata.privateExponent.len = numbytes;
345 keydata.modulus.data = (unsigned char *)modulus->d;
346 keydata.modulus.len = numbytes;
347 /* Prepare the argument */
348 memset(argument->d, 0, numbytes);
349 memset(result->d, 0, numbytes);
350 BN_bn2bin(a, (unsigned char *)argument->d + numbytes - BN_num_bytes(a));
351 /* Perform the operation */
352 if(p_Atalla_RSAPrivateKeyOpFn(&keydata, (unsigned char *)result->d,
353 (unsigned char *)argument->d,
354 keydata.modulus.len) != 0)
355 {
356 ENGINEerr(ENGINE_F_ATALLA_MOD_EXP,ENGINE_R_REQUEST_FAILED);
357 goto err;
358 }
359 /* Convert the response */
360 BN_bin2bn((unsigned char *)result->d, numbytes, r);
361 to_return = 1;
362err:
363 if(modulus) ctx->tos--;
364 if(exponent) ctx->tos--;
365 if(argument) ctx->tos--;
366 if(result) ctx->tos--;
367 return to_return;
368 }
369
370static int atalla_rsa_mod_exp(BIGNUM *r0, BIGNUM *I, RSA *rsa)
371 {
372 BN_CTX *ctx = NULL;
373 int to_return = 0;
374
375 if(!atalla_dso)
376 {
377 ENGINEerr(ENGINE_F_ATALLA_RSA_MOD_EXP,ENGINE_R_NOT_LOADED);
378 goto err;
379 }
380 if((ctx = BN_CTX_new()) == NULL)
381 goto err;
382 if(!rsa->d || !rsa->n)
383 {
384 ENGINEerr(ENGINE_F_ATALLA_RSA_MOD_EXP,ENGINE_R_MISSING_KEY_COMPONENTS);
385 goto err;
386 }
387 to_return = atalla_mod_exp(r0, I, rsa->d, rsa->n, ctx);
388err:
389 if(ctx)
390 BN_CTX_free(ctx);
391 return to_return;
392 }
393
394/* This code was liberated and adapted from the commented-out code in
395 * dsa_ossl.c. Because of the unoptimised form of the Atalla acceleration
396 * (it doesn't have a CRT form for RSA), this function means that an
397 * Atalla system running with a DSA server certificate can handshake
398 * around 5 or 6 times faster/more than an equivalent system running with
399 * RSA. Just check out the "signs" statistics from the RSA and DSA parts
400 * of "openssl speed -engine atalla dsa1024 rsa1024". */
401static int atalla_dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1,
402 BIGNUM *p1, BIGNUM *a2, BIGNUM *p2, BIGNUM *m,
403 BN_CTX *ctx, BN_MONT_CTX *in_mont)
404 {
405 BIGNUM t;
406 int to_return = 0;
407
408 BN_init(&t);
409 /* let rr = a1 ^ p1 mod m */
410 if (!atalla_mod_exp(rr,a1,p1,m,ctx)) goto end;
411 /* let t = a2 ^ p2 mod m */
412 if (!atalla_mod_exp(&t,a2,p2,m,ctx)) goto end;
413 /* let rr = rr * t mod m */
414 if (!BN_mod_mul(rr,rr,&t,m,ctx)) goto end;
415 to_return = 1;
416end:
417 BN_free(&t);
418 return to_return;
419 }
420
421
422static int atalla_mod_exp_dsa(DSA *dsa, BIGNUM *r, BIGNUM *a,
423 const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
424 BN_MONT_CTX *m_ctx)
425 {
426 return atalla_mod_exp(r, a, p, m, ctx);
427 }
428
429/* This function is aliased to mod_exp (with the mont stuff dropped). */
430static int atalla_mod_exp_mont(BIGNUM *r, BIGNUM *a, const BIGNUM *p,
431 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
432 {
433 return atalla_mod_exp(r, a, p, m, ctx);
434 }
435
436/* This function is aliased to mod_exp (with the dh and mont dropped). */
437static int atalla_mod_exp_dh(DH *dh, BIGNUM *r, BIGNUM *a, const BIGNUM *p,
438 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
439 {
440 return atalla_mod_exp(r, a, p, m, ctx);
441 }
442
443#endif /* !NO_HW_ATALLA */
444#endif /* !NO_HW */
diff --git a/src/lib/libcrypto/engine/hw_atalla_err.c b/src/lib/libcrypto/engine/hw_atalla_err.c
new file mode 100644
index 0000000000..1df9c4570c
--- /dev/null
+++ b/src/lib/libcrypto/engine/hw_atalla_err.c
@@ -0,0 +1,145 @@
1/* hw_atalla_err.c */
2/* ====================================================================
3 * Copyright (c) 1999 The OpenSSL Project. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
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
15 * distribution.
16 *
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/)"
21 *
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 * openssl-core@OpenSSL.org.
26 *
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.
30 *
31 * 6. Redistributions of any form whatsoever must retain the following
32 * acknowledgment:
33 * "This product includes software developed by the OpenSSL Project
34 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
35 *
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 * ====================================================================
49 *
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).
53 *
54 */
55
56/* NOTE: this file was auto generated by the mkerr.pl script: any changes
57 * made to it will be overwritten when the script next updates this file,
58 * only reason strings will be preserved.
59 */
60
61#include <stdio.h>
62#include <openssl/err.h>
63#include "hw_atalla_err.h"
64
65/* BEGIN ERROR CODES */
66#ifndef OPENSSL_NO_ERR
67static ERR_STRING_DATA ATALLA_str_functs[]=
68 {
69{ERR_PACK(0,ATALLA_F_ATALLA_CTRL,0), "ATALLA_CTRL"},
70{ERR_PACK(0,ATALLA_F_ATALLA_FINISH,0), "ATALLA_FINISH"},
71{ERR_PACK(0,ATALLA_F_ATALLA_INIT,0), "ATALLA_INIT"},
72{ERR_PACK(0,ATALLA_F_ATALLA_MOD_EXP,0), "ATALLA_MOD_EXP"},
73{ERR_PACK(0,ATALLA_F_ATALLA_RSA_MOD_EXP,0), "ATALLA_RSA_MOD_EXP"},
74{0,NULL}
75 };
76
77static ERR_STRING_DATA ATALLA_str_reasons[]=
78 {
79{ATALLA_R_ALREADY_LOADED ,"already loaded"},
80{ATALLA_R_BN_CTX_FULL ,"bn ctx full"},
81{ATALLA_R_BN_EXPAND_FAIL ,"bn expand fail"},
82{ATALLA_R_CTRL_COMMAND_NOT_IMPLEMENTED ,"ctrl command not implemented"},
83{ATALLA_R_MISSING_KEY_COMPONENTS ,"missing key components"},
84{ATALLA_R_NOT_LOADED ,"not loaded"},
85{ATALLA_R_REQUEST_FAILED ,"request failed"},
86{ATALLA_R_UNIT_FAILURE ,"unit failure"},
87{0,NULL}
88 };
89
90#endif
91
92#ifdef ATALLA_LIB_NAME
93static ERR_STRING_DATA ATALLA_lib_name[]=
94 {
95{0 ,ATALLA_LIB_NAME},
96{0,NULL}
97 };
98#endif
99
100
101static int ATALLA_lib_error_code=0;
102static int ATALLA_error_init=1;
103
104static void ERR_load_ATALLA_strings(void)
105 {
106 if (ATALLA_lib_error_code == 0)
107 ATALLA_lib_error_code=ERR_get_next_error_library();
108
109 if (ATALLA_error_init)
110 {
111 ATALLA_error_init=0;
112#ifndef OPENSSL_NO_ERR
113 ERR_load_strings(ATALLA_lib_error_code,ATALLA_str_functs);
114 ERR_load_strings(ATALLA_lib_error_code,ATALLA_str_reasons);
115#endif
116
117#ifdef ATALLA_LIB_NAME
118 ATALLA_lib_name->error = ERR_PACK(ATALLA_lib_error_code,0,0);
119 ERR_load_strings(0,ATALLA_lib_name);
120#endif
121 }
122 }
123
124static void ERR_unload_ATALLA_strings(void)
125 {
126 if (ATALLA_error_init == 0)
127 {
128#ifndef OPENSSL_NO_ERR
129 ERR_unload_strings(ATALLA_lib_error_code,ATALLA_str_functs);
130 ERR_unload_strings(ATALLA_lib_error_code,ATALLA_str_reasons);
131#endif
132
133#ifdef ATALLA_LIB_NAME
134 ERR_unload_strings(0,ATALLA_lib_name);
135#endif
136 ATALLA_error_init=1;
137 }
138 }
139
140static void ERR_ATALLA_error(int function, int reason, char *file, int line)
141 {
142 if (ATALLA_lib_error_code == 0)
143 ATALLA_lib_error_code=ERR_get_next_error_library();
144 ERR_PUT_error(ATALLA_lib_error_code,function,reason,file,line);
145 }
diff --git a/src/lib/libcrypto/engine/hw_atalla_err.h b/src/lib/libcrypto/engine/hw_atalla_err.h
new file mode 100644
index 0000000000..cdac052d8c
--- /dev/null
+++ b/src/lib/libcrypto/engine/hw_atalla_err.h
@@ -0,0 +1,89 @@
1/* ====================================================================
2 * Copyright (c) 2001 The OpenSSL Project. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in
13 * the documentation and/or other materials provided with the
14 * distribution.
15 *
16 * 3. All advertising materials mentioning features or use of this
17 * software must display the following acknowledgment:
18 * "This product includes software developed by the OpenSSL Project
19 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
20 *
21 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
22 * endorse or promote products derived from this software without
23 * prior written permission. For written permission, please contact
24 * openssl-core@openssl.org.
25 *
26 * 5. Products derived from this software may not be called "OpenSSL"
27 * nor may "OpenSSL" appear in their names without prior written
28 * permission of the OpenSSL Project.
29 *
30 * 6. Redistributions of any form whatsoever must retain the following
31 * acknowledgment:
32 * "This product includes software developed by the OpenSSL Project
33 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
34 *
35 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
36 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
37 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
38 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
39 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
41 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
42 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
43 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
44 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
45 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
46 * OF THE POSSIBILITY OF SUCH DAMAGE.
47 * ====================================================================
48 *
49 * This product includes cryptographic software written by Eric Young
50 * (eay@cryptsoft.com). This product includes software written by Tim
51 * Hudson (tjh@cryptsoft.com).
52 *
53 */
54
55#ifndef HEADER_ATALLA_ERR_H
56#define HEADER_ATALLA_ERR_H
57
58/* BEGIN ERROR CODES */
59/* The following lines are auto generated by the script mkerr.pl. Any changes
60 * made after this point may be overwritten when the script is next run.
61 */
62static void ERR_load_ATALLA_strings(void);
63static void ERR_unload_ATALLA_strings(void);
64static void ERR_ATALLA_error(int function, int reason, char *file, int line);
65#define ATALLAerr(f,r) ERR_ATALLA_error((f),(r),__FILE__,__LINE__)
66
67/* Error codes for the ATALLA functions. */
68
69/* Function codes. */
70#define ATALLA_F_ATALLA_CTRL 100
71#define ATALLA_F_ATALLA_FINISH 101
72#define ATALLA_F_ATALLA_INIT 102
73#define ATALLA_F_ATALLA_MOD_EXP 103
74#define ATALLA_F_ATALLA_RSA_MOD_EXP 104
75
76/* Reason codes. */
77#define ATALLA_R_ALREADY_LOADED 100
78#define ATALLA_R_BN_CTX_FULL 101
79#define ATALLA_R_BN_EXPAND_FAIL 102
80#define ATALLA_R_CTRL_COMMAND_NOT_IMPLEMENTED 103
81#define ATALLA_R_MISSING_KEY_COMPONENTS 104
82#define ATALLA_R_NOT_LOADED 105
83#define ATALLA_R_REQUEST_FAILED 106
84#define ATALLA_R_UNIT_FAILURE 107
85
86#ifdef __cplusplus
87}
88#endif
89#endif
diff --git a/src/lib/libcrypto/engine/hw_cryptodev.c b/src/lib/libcrypto/engine/hw_cryptodev.c
new file mode 100644
index 0000000000..7c3728f395
--- /dev/null
+++ b/src/lib/libcrypto/engine/hw_cryptodev.c
@@ -0,0 +1,926 @@
1/*
2 * Copyright (c) 2002 Bob Beck <beck@openbsd.org>
3 * Copyright (c) 2002 Theo de Raadt
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. Neither the name of the author nor the names of contributors
15 * may be used to endorse or promote products derived from this software
16 * without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
19 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY
22 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 *
29 */
30
31#include <sys/types.h>
32#include <sys/param.h>
33#include <crypto/cryptodev.h>
34#include <sys/ioctl.h>
35#include <errno.h>
36#include <stdio.h>
37#include <unistd.h>
38#include <fcntl.h>
39#include <syslog.h>
40#include <stdarg.h>
41#include <ssl/objects.h>
42#include <ssl/engine.h>
43#include <ssl/evp.h>
44
45static int cryptodev_fd = -1;
46static int cryptodev_sessions = 0;
47static u_int32_t cryptodev_symfeat = 0;
48
49static int bn2crparam(const BIGNUM *a, struct crparam *crp);
50static int crparam2bn(struct crparam *crp, BIGNUM *a);
51static void zapparams(struct crypt_kop *kop);
52
53static int cryptodev_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa);
54static int cryptodev_bn_mod_exp(BIGNUM *r, const BIGNUM *a,
55 const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
56static int cryptodev_dsa_bn_mod_exp(DSA *dsa, BIGNUM *r, BIGNUM *a,
57 const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
58static DSA_SIG *cryptodev_dsa_do_sign(const unsigned char *dgst,
59 int dlen, DSA *dsa);
60static int cryptodev_dsa_verify(const unsigned char *dgst, int dgst_len,
61 DSA_SIG *sig, DSA *dsa);
62static int cryptodev_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a,
63 const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
64 BN_MONT_CTX *m_ctx);
65static int cryptodev_dh_compute_key(unsigned char *key,
66 const BIGNUM *pub_key, DH *dh);
67
68static const ENGINE_CMD_DEFN cryptodev_defns[] = {
69 { 0, NULL, NULL, 0 }
70};
71
72static struct {
73 int id;
74 int nid;
75 int ivmax;
76 int keylen;
77} ciphers[] = {
78 { CRYPTO_DES_CBC, NID_des_cbc, 8, 8, },
79 { CRYPTO_3DES_CBC, NID_des_ede3_cbc, 8, 24, },
80 { CRYPTO_AES_CBC, NID_undef, 8, 24, },
81 { CRYPTO_BLF_CBC, NID_bf_cbc, 8, 16, },
82 { CRYPTO_CAST_CBC, NID_cast5_cbc, 8, 8, },
83 { CRYPTO_SKIPJACK_CBC, NID_undef, 0, 0, },
84 { CRYPTO_ARC4, NID_rc4, 8, 16, },
85 { 0, NID_undef, 0, 0, },
86};
87
88static struct {
89 int id;
90 int nid;
91} digests[] = {
92 { CRYPTO_SHA1_HMAC, NID_hmacWithSHA1, },
93 { CRYPTO_RIPEMD160_HMAC, NID_ripemd160, },
94 { CRYPTO_MD5_KPDK, NID_undef, },
95 { CRYPTO_SHA1_KPDK, NID_undef, },
96 { CRYPTO_MD5, NID_md5, },
97 { CRYPTO_SHA1, NID_undef, },
98 { 0, NID_undef, },
99};
100
101/*
102 * Return 1 if /dev/crypto seems usable, 0 otherwise , also
103 * does most of the work of initting the device, if not already
104 * done.. This should leave is with global fd initialized with CRIOGET.
105 */
106static int
107check_dev_crypto()
108{
109 int fd;
110
111 if (cryptodev_fd == -1) {
112 if ((fd = open("/dev/crypto", O_RDWR, 0)) == -1)
113 return (0);
114 if (ioctl(fd, CRIOGET, &cryptodev_fd) == -1) {
115 close(fd);
116 return (0);
117 }
118 close(fd);
119 /* close on exec */
120 if (fcntl(cryptodev_fd, F_SETFD, 1) == -1) {
121 close(cryptodev_fd);
122 cryptodev_fd = -1;
123 return (0);
124 }
125 }
126 ioctl(cryptodev_fd, CIOCSYMFEAT, &cryptodev_symfeat);
127
128 return (1);
129}
130
131/*
132 * XXXX this needs to be set for each alg - and determined from
133 * a running card.
134 */
135static int
136cryptodev_max_iv(int cipher)
137{
138 int i;
139
140 for (i = 0; ciphers[i].id; i++)
141 if (ciphers[i].id == cipher)
142 return (ciphers[i].ivmax);
143 return (0);
144}
145
146/*
147 * XXXX this needs to be set for each alg - and determined from
148 * a running card. For now, fake it out - but most of these
149 * for real devices should return 1 for the supported key
150 * sizes the device can handle.
151 */
152static int
153cryptodev_key_length_valid(int cipher, int len)
154{
155 int i;
156
157 for (i = 0; ciphers[i].id; i++)
158 if (ciphers[i].id == cipher)
159 return (ciphers[i].keylen == len);
160 return (0);
161}
162
163/* convert libcrypto nids to cryptodev */
164static int
165cipher_nid_to_cryptodev(int nid)
166{
167 int i;
168
169 for (i = 0; ciphers[i].id; i++)
170 if (ciphers[i].nid == nid)
171 return (ciphers[i].id);
172 return (0);
173}
174
175/*
176 * Find out what ciphers /dev/crypto will let us have a session for.
177 * XXX note, that some of these openssl doesn't deal with yet!
178 * returning them here is harmless, as long as we return NULL
179 * when asked for a handler in the cryptodev_engine_ciphers routine
180 */
181static int
182get_cryptodev_ciphers(const int **cnids)
183{
184 static int nids[CRYPTO_ALGORITHM_MAX];
185 struct session_op sess;
186 int i, count = 0;
187
188 memset(&sess, 0, sizeof(sess));
189 sess.key = (caddr_t)"123456781234567812345678";
190
191 for (i = 0; ciphers[i].id && count < CRYPTO_ALGORITHM_MAX; i++) {
192 if (ciphers[i].nid == NID_undef)
193 continue;
194 sess.cipher = ciphers[i].id;
195 sess.keylen = ciphers[i].keylen;
196 sess.mac = 0;
197 if (ioctl(cryptodev_fd, CIOCGSESSION, &sess) != -1 &&
198 ioctl(cryptodev_fd, CIOCFSESSION, &sess.ses) != -1)
199 nids[count++] = ciphers[i].nid;
200 }
201 if (count > 0)
202 *cnids = nids;
203 else
204 *cnids = NULL;
205 return (count);
206}
207
208/*
209 * Find out what digests /dev/crypto will let us have a session for.
210 * XXX note, that some of these openssl doesn't deal with yet!
211 * returning them here is harmless, as long as we return NULL
212 * when asked for a handler in the cryptodev_engine_digests routine
213 */
214static int
215get_cryptodev_digests(const int **cnids)
216{
217 static int nids[CRYPTO_ALGORITHM_MAX];
218 struct session_op sess;
219 int i, count = 0;
220
221 memset(&sess, 0, sizeof(sess));
222 for (i = 0; digests[i].id && count < CRYPTO_ALGORITHM_MAX; i++) {
223 if (digests[i].nid == NID_undef)
224 continue;
225 sess.mac = digests[i].id;
226 sess.cipher = 0;
227 if (ioctl(cryptodev_fd, CIOCGSESSION, &sess) != -1 &&
228 ioctl(cryptodev_fd, CIOCFSESSION, &sess.ses) != -1)
229 nids[count++] = digests[i].nid;
230 }
231 if (count > 0)
232 *cnids = nids;
233 else
234 *cnids = NULL;
235 return (count);
236}
237
238/*
239 * Find the useable ciphers|digests from dev/crypto - this is the first
240 * thing called by the engine init crud which determines what it
241 * can use for ciphers from this engine. We want to return
242 * only what we can do, anythine else is handled by software.
243 *
244 * If we can't initialize the device to do anything useful for
245 * any reason, we want to return a NULL array, and 0 length,
246 * which forces everything to be done is software. By putting
247 * the initalization of the device in here, we ensure we can
248 * use this engine as the default, and if for whatever reason
249 * /dev/crypto won't do what we want it will just be done in
250 * software
251 *
252 * This can (should) be greatly expanded to perhaps take into
253 * account speed of the device, and what we want to do.
254 * (although the disabling of particular alg's could be controlled
255 * by the device driver with sysctl's.) - this is where we
256 * want most of the decisions made about what we actually want
257 * to use from /dev/crypto.
258 */
259int
260cryptodev_usable_ciphers(const int **nids)
261{
262 if (!check_dev_crypto()) {
263 *nids = NULL;
264 return (0);
265 }
266
267 /* find what the device can do. Unfortunately, we don't
268 * necessarily want all of these yet, because we aren't
269 * yet set up to do them
270 */
271 return (get_cryptodev_ciphers(nids));
272}
273
274int
275cryptodev_usable_digests(const int **nids)
276{
277#if 1
278 /*
279 * XXXX just disable all digests for now, because it sucks.
280 * we need a better way to decide this - i.e. I may not
281 * want digests on slow cards like hifn on fast machines,
282 * but might want them on slow or loaded machines, etc.
283 * will also want them when using crypto cards that don't
284 * suck moose gonads - would be nice to be able to decide something
285 * as reasonable default without having hackery that's card dependent.
286 * of course, the default should probably be just do everything,
287 * with perhaps a sysctl to turn algoritms off (or have them off
288 * by default) on cards that generally suck like the hifn.
289 */
290 *nids = NULL;
291 return (0);
292#endif
293
294 if (!check_dev_crypto()) {
295 *nids = NULL;
296 return (0);
297 }
298 return (get_cryptodev_digests(nids));
299}
300
301
302int
303cryptodev_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
304 const unsigned char *in, unsigned int inl)
305{
306 struct crypt_op cryp;
307 struct session_op *sess = ctx->cipher_data;
308 void *iiv;
309 unsigned char save_iv[EVP_MAX_IV_LENGTH];
310 struct syslog_data sd = SYSLOG_DATA_INIT;
311
312 if (cryptodev_fd == -1)
313 return (0);
314 if (sess == NULL)
315 return (0);
316 if (!inl)
317 return (1);
318 if ((inl % ctx->cipher->block_size) != 0)
319 return (0);
320
321 memset(&cryp, 0, sizeof(cryp));
322
323 cryp.ses = sess->ses;
324 cryp.flags = 0;
325 cryp.len = inl;
326 cryp.src = (caddr_t) in;
327 cryp.dst = (caddr_t) out;
328 cryp.mac = 0;
329
330 cryp.op = ctx->encrypt ? COP_ENCRYPT : COP_DECRYPT;
331
332 if (ctx->cipher->iv_len) {
333 cryp.iv = (caddr_t) ctx->iv;
334 if (!ctx->encrypt) {
335 iiv = (void *) in + inl - ctx->cipher->iv_len;
336 memcpy(save_iv, iiv, ctx->cipher->iv_len);
337 }
338 } else
339 cryp.iv = NULL;
340
341 if (ioctl(cryptodev_fd, CIOCCRYPT, &cryp) == -1) {
342 /* XXX need better errror handling
343 * this can fail for a number of different reasons.
344 */
345 syslog_r(LOG_ERR, &sd, "CIOCCRYPT failed (%m)");
346 return (0);
347 }
348
349 if (ctx->cipher->iv_len) {
350 if (ctx->encrypt)
351 iiv = (void *) out + inl - ctx->cipher->iv_len;
352 else
353 iiv = save_iv;
354 memcpy(ctx->iv, iiv, ctx->cipher->iv_len);
355 }
356 return (1);
357}
358
359int
360cryptodev_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
361 const unsigned char *iv, int enc)
362{
363 struct session_op *sess = ctx->cipher_data;
364 struct syslog_data sd = SYSLOG_DATA_INIT;
365 int cipher;
366
367 if ((cipher = cipher_nid_to_cryptodev(ctx->cipher->nid)) == NID_undef)
368 return (0);
369
370 if (!check_dev_crypto())
371 return (0);
372
373 if (ctx->cipher->iv_len > cryptodev_max_iv(cipher))
374 return (0);
375
376 if (!cryptodev_key_length_valid(cipher, ctx->key_len))
377 return (0);
378
379 memset(sess, 0, sizeof(struct session_op));
380
381 sess->key = (unsigned char *)key;
382 sess->keylen = ctx->key_len;
383 sess->cipher = cipher;
384
385 if (ioctl(cryptodev_fd, CIOCGSESSION, sess) == -1) {
386 syslog_r(LOG_ERR, &sd, "CIOCGSESSION failed (%m)");
387 return (0);
388 }
389 cryptodev_sessions++;
390 return (1);
391}
392
393/*
394 * free anything we allocated earlier when initting a
395 * session, and close the session.
396 */
397int
398cryptodev_cleanup(EVP_CIPHER_CTX *ctx)
399{
400 int ret = 0;
401 struct session_op *sess = ctx->cipher_data;
402 struct syslog_data sd = SYSLOG_DATA_INIT;
403
404 if (sess == NULL)
405 return (0);
406
407 /* XXX if this ioctl fails, someting's wrong. the invoker
408 * may have called us with a bogus ctx, or we could
409 * have a device that for whatever reason just doesn't
410 * want to play ball - it's not clear what's right
411 * here - should this be an error? should it just
412 * increase a counter, hmm. For right now, we return
413 * 0 - I don't believe that to be "right". we could
414 * call the gorpy openssl lib error handlers that
415 * print messages to users of the library. hmm..
416 */
417
418 if (ioctl(cryptodev_fd, CIOCFSESSION, &sess->ses) == -1) {
419 syslog_r(LOG_ERR, &sd, "CIOCFSESSION failed (%m)");
420 ret = 0;
421 } else {
422 cryptodev_sessions--;
423 ret = 1;
424 }
425 if (cryptodev_sessions == 0 && cryptodev_fd != -1 ) {
426 close(cryptodev_fd); /* XXX should this be closed? */
427 cryptodev_fd = -1;
428 }
429 return (ret);
430}
431
432/*
433 * libcrypto EVP stuff - this is how we get wired to EVP so the engine
434 * gets called when libcrypto requests a cipher NID.
435 */
436
437/* ARC4 (16 byte key) */
438const EVP_CIPHER cryptodev_arc4_cipher = {
439 NID_rc4,
440 1, 16, 0,
441 EVP_CIPH_VARIABLE_LENGTH,
442 cryptodev_init_key,
443 cryptodev_cipher,
444 cryptodev_cleanup,
445 sizeof(struct session_op),
446 NULL,
447 NULL,
448 NULL
449};
450
451/* DES CBC EVP */
452const EVP_CIPHER cryptodev_des_cbc = {
453 NID_des_cbc,
454 8, 8, 8,
455 EVP_CIPH_CBC_MODE,
456 cryptodev_init_key,
457 cryptodev_cipher,
458 cryptodev_cleanup,
459 sizeof(struct session_op),
460 EVP_CIPHER_set_asn1_iv,
461 EVP_CIPHER_get_asn1_iv,
462 NULL
463};
464
465/* 3DES CBC EVP */
466const EVP_CIPHER cryptodev_3des_cbc = {
467 NID_des_ede3_cbc,
468 8, 24, 8,
469 EVP_CIPH_CBC_MODE,
470 cryptodev_init_key,
471 cryptodev_cipher,
472 cryptodev_cleanup,
473 sizeof(struct session_op),
474 EVP_CIPHER_set_asn1_iv,
475 EVP_CIPHER_get_asn1_iv,
476 NULL
477};
478
479
480/*
481 * Registered by the ENGINE when used to find out how to deal with
482 * a particular NID in the ENGINE. this says what we'll do at the
483 * top level - note, that list is restricted by what we answer with
484 */
485int
486cryptodev_engine_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
487 const int **nids, int nid)
488{
489 if (!cipher)
490 return (cryptodev_usable_ciphers(nids));
491
492 switch (nid) {
493 case NID_rc4:
494 *cipher = &cryptodev_arc4_cipher;
495 break;
496 case NID_des_ede3_cbc:
497 *cipher = &cryptodev_3des_cbc;
498 break;
499 case NID_des_cbc:
500 *cipher = &cryptodev_des_cbc;
501 break;
502 default:
503 *cipher = NULL;
504 break;
505 }
506 return (*cipher != NULL);
507}
508
509int
510cryptodev_engine_digests(ENGINE *e, const EVP_MD **digest,
511 const int **nids, int nid)
512{
513 if (!digest)
514 return (cryptodev_usable_digests(nids));
515
516 switch (nid) {
517 case NID_md5:
518 *digest = NULL; /* need to make a clean md5 critter */
519 break;
520 default:
521 *digest = NULL;
522 break;
523 }
524 return (*digest != NULL);
525}
526
527
528/*
529 * Convert a BIGNUM to the representation that /dev/crypto needs.
530 * Upon completion of use, the caller is responsible for freeing
531 * crp->crp_p.
532 */
533static int
534bn2crparam(const BIGNUM *a, struct crparam *crp)
535{
536 int i, j, n;
537 ssize_t words, bytes, bits;
538 u_char *b;
539
540 crp->crp_p = NULL;
541 crp->crp_nbits = 0;
542
543 bits = BN_num_bits(a);
544 bytes = (bits + 7) / 8;
545
546 b = malloc(bytes);
547 if (b == NULL)
548 return (1);
549
550 crp->crp_p = b;
551 crp->crp_nbits = bits;
552
553 words = (bits + BN_BITS2 - 1) / BN_BITS2;
554
555 n = 0;
556 for (i = 0; i < words && n < bytes; i++) {
557 BN_ULONG word;
558
559 word = a->d[i];
560 for (j = 0 ; j < BN_BYTES && n < bytes; j++, n++) {
561 *b++ = (word & 0xff);
562 word >>= 8;
563 }
564 }
565 return (0);
566}
567
568/* Convert a /dev/crypto parameter to a BIGNUM */
569static int
570crparam2bn(struct crparam *crp, BIGNUM *a)
571{
572 int i, bytes;
573
574 bytes = (crp->crp_nbits + 7)/8;
575
576 BN_zero(a);
577 for (i = bytes - 1; i >= 0; i--) {
578 BN_lshift(a, a, 8);
579 BN_add_word(a, (u_char)crp->crp_p[i]);
580 }
581
582 return (0);
583}
584
585static void
586zapparams(struct crypt_kop *kop)
587{
588 int i;
589
590 for (i = 0; i <= kop->crk_iparams + kop->crk_oparams; i++) {
591 if (kop->crk_param[i].crp_p)
592 free(kop->crk_param[i].crp_p);
593 kop->crk_param[i].crp_p = NULL;
594 kop->crk_param[i].crp_nbits = 0;
595 }
596}
597
598static int
599cryptodev_sym(struct crypt_kop *kop, BIGNUM *r, BIGNUM *s)
600{
601 int ret = -1;
602
603 if (r) {
604 kop->crk_param[kop->crk_iparams].crp_p = malloc(256);
605 kop->crk_param[kop->crk_iparams].crp_nbits = 256 * 8;
606 kop->crk_oparams++;
607 }
608 if (s) {
609 kop->crk_param[kop->crk_iparams+1].crp_p = malloc(256);
610 kop->crk_param[kop->crk_iparams+1].crp_nbits = 256 * 8;
611 kop->crk_oparams++;
612 }
613
614 if (ioctl(cryptodev_fd, CIOCKEY, &kop) == 0) {
615 crparam2bn(&kop->crk_param[3], r);
616 ret = 0;
617 }
618 return (ret);
619}
620
621static int
622cryptodev_bn_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
623 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont)
624{
625 struct crypt_kop kop;
626 int ret = 0;
627
628 memset(&kop, 0, sizeof kop);
629 kop.crk_op = CRK_MOD_EXP;
630
631 /* inputs: a m p */
632 if (bn2crparam(a, &kop.crk_param[0]))
633 goto err;
634 if (bn2crparam(m, &kop.crk_param[1]))
635 goto err;
636 if (bn2crparam(p, &kop.crk_param[2]))
637 goto err;
638 kop.crk_iparams = 3;
639
640 if (cryptodev_sym(&kop, r, NULL) == -1) {
641 ret = BN_mod_exp(r, a, p, m, ctx);
642 }
643err:
644 zapparams(&kop);
645 return (ret);
646}
647
648
649static int
650cryptodev_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa)
651{
652 struct crypt_kop kop;
653 int ret = 0;
654
655 if (!rsa->p || !rsa->q || !rsa->dmp1 || !rsa->dmq1 || !rsa->iqmp) {
656 /* XXX 0 means failure?? */
657 goto err;
658 }
659
660 memset(&kop, 0, sizeof kop);
661 kop.crk_op = CRK_MOD_EXP_CRT;
662 /* inputs: rsa->p rsa->q I rsa->dmp1 rsa->dmq1 rsa->iqmp */
663 if (bn2crparam(rsa->p, &kop.crk_param[0]))
664 goto err;
665 if (bn2crparam(rsa->q, &kop.crk_param[1]))
666 goto err;
667 if (bn2crparam(I, &kop.crk_param[2]))
668 goto err;
669 if (bn2crparam(rsa->dmp1, &kop.crk_param[3]))
670 goto err;
671 if (bn2crparam(rsa->dmq1, &kop.crk_param[4]))
672 goto err;
673 if (bn2crparam(rsa->iqmp, &kop.crk_param[5]))
674 goto err;
675 kop.crk_iparams = 6;
676
677 if (cryptodev_sym(&kop, r0, NULL) == -1) {
678 const RSA_METHOD *meth = RSA_PKCS1_SSLeay();
679
680 ret = (*meth->rsa_mod_exp)(r0, I, rsa);
681 }
682err:
683 zapparams(&kop);
684 return (ret);
685}
686
687static RSA_METHOD cryptodev_rsa = {
688 "cryptodev RSA method",
689 NULL, /* rsa_pub_enc */
690 NULL, /* rsa_pub_dec */
691 NULL, /* rsa_priv_enc */
692 NULL, /* rsa_priv_dec */
693 cryptodev_rsa_mod_exp, /* rsa_mod_exp */
694 cryptodev_bn_mod_exp, /* bn_mod_exp */
695 NULL, /* init */
696 NULL, /* finish */
697 0, /* flags */
698 NULL, /* app_data */
699 NULL, /* rsa_sign */
700 NULL /* rsa_verify */
701};
702
703static int
704cryptodev_dsa_bn_mod_exp(DSA *dsa, BIGNUM *r, BIGNUM *a, const BIGNUM *p,
705 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
706{
707 return (cryptodev_bn_mod_exp(r, a, p, m, ctx, m_ctx));
708}
709
710static DSA_SIG *
711cryptodev_dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
712{
713 struct crypt_kop kop;
714 BIGNUM *r = NULL, *s = NULL;
715 DSA_SIG *dsaret = NULL;
716
717 if ((r = BN_new()) == NULL)
718 goto err;
719 if ((s = BN_new()) == NULL) {
720 BN_free(r);
721 goto err;
722 }
723
724 memset(&kop, 0, sizeof kop);
725 kop.crk_op = CRK_DSA_SIGN;
726
727 /* inputs: dgst dsa->p dsa->q dsa->g dsa->priv_key */
728 kop.crk_param[0].crp_p = (caddr_t)dgst;
729 kop.crk_param[0].crp_nbits = dlen * 8;
730 if (bn2crparam(dsa->p, &kop.crk_param[1]))
731 goto err;
732 if (bn2crparam(dsa->q, &kop.crk_param[2]))
733 goto err;
734 if (bn2crparam(dsa->g, &kop.crk_param[3]))
735 goto err;
736 if (bn2crparam(dsa->priv_key, &kop.crk_param[4]))
737 goto err;
738 kop.crk_iparams = 5;
739
740 if (cryptodev_sym(&kop, r, s) == 0) {
741 dsaret = DSA_SIG_new();
742 dsaret->r = r;
743 dsaret->s = s;
744 } else {
745 const DSA_METHOD *meth = DSA_OpenSSL();
746
747 BN_free(r);
748 BN_free(s);
749 dsaret = (meth->dsa_do_sign)(dgst, dlen, dsa);
750 }
751err:
752 kop.crk_param[0].crp_p = NULL;
753 zapparams(&kop);
754 return (dsaret);
755}
756
757static int
758cryptodev_dsa_verify(const unsigned char *dgst, int dlen,
759 DSA_SIG *sig, DSA *dsa)
760{
761 struct crypt_kop kop;
762 int dsaret = 0;
763
764 memset(&kop, 0, sizeof kop);
765 kop.crk_op = CRK_DSA_VERIFY;
766
767 /* inputs: dgst dsa->p dsa->q dsa->g dsa->pub_key sig->r sig->s */
768 kop.crk_param[0].crp_p = (caddr_t)dgst;
769 kop.crk_param[0].crp_nbits = dlen * 8;
770 if (bn2crparam(dsa->p, &kop.crk_param[1]))
771 goto err;
772 if (bn2crparam(dsa->q, &kop.crk_param[2]))
773 goto err;
774 if (bn2crparam(dsa->g, &kop.crk_param[3]))
775 goto err;
776 if (bn2crparam(dsa->pub_key, &kop.crk_param[4]))
777 goto err;
778 if (bn2crparam(sig->r, &kop.crk_param[5]))
779 goto err;
780 if (bn2crparam(sig->s, &kop.crk_param[6]))
781 goto err;
782 kop.crk_iparams = 7;
783
784 if (cryptodev_sym(&kop, NULL, NULL) == 0) {
785 dsaret = kop.crk_status;
786 } else {
787 const DSA_METHOD *meth = DSA_OpenSSL();
788
789 dsaret = (meth->dsa_do_verify)(dgst, dlen, sig, dsa);
790 }
791err:
792 kop.crk_param[0].crp_p = NULL;
793 zapparams(&kop);
794 return (dsaret);
795}
796
797static DSA_METHOD cryptodev_dsa = {
798 "cryptodev DSA method",
799 cryptodev_dsa_do_sign,
800 NULL, /* dsa_sign_setup */
801 cryptodev_dsa_verify,
802 NULL, /* dsa_mod_exp */
803 cryptodev_dsa_bn_mod_exp, /* bn_mod_exp */
804 NULL, /* init */
805 NULL, /* finish */
806 0, /* flags */
807 NULL /* app_data */
808};
809
810static int
811cryptodev_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a,
812 const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
813 BN_MONT_CTX *m_ctx)
814{
815 return (cryptodev_bn_mod_exp(r, a, p, m, ctx, m_ctx));
816}
817
818static int
819cryptodev_dh_compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh)
820{
821 struct crypt_kop kop;
822 int dhret = 0;
823 int keylen;
824
825 keylen = BN_num_bits(dh->p);
826
827 memset(&kop, 0, sizeof kop);
828 kop.crk_op = CRK_DH_COMPUTE_KEY;
829
830 /* inputs: dh->priv_key pub_key dh->p key */
831 if (bn2crparam(dh->priv_key, &kop.crk_param[0]))
832 goto err;
833 if (bn2crparam(pub_key, &kop.crk_param[1]))
834 goto err;
835 if (bn2crparam(dh->p, &kop.crk_param[2]))
836 goto err;
837 kop.crk_iparams = 3;
838
839 kop.crk_param[3].crp_p = key;
840 kop.crk_param[3].crp_nbits = keylen * 8;
841 kop.crk_oparams = 1;
842
843 if (ioctl(cryptodev_fd, CIOCKEY, &kop) == -1) {
844 const DH_METHOD *meth = DH_OpenSSL();
845
846 dhret = (meth->compute_key)(key, pub_key, dh);
847 }
848err:
849 kop.crk_param[3].crp_p = NULL;
850 zapparams(&kop);
851 return (dhret);
852}
853
854static DH_METHOD cryptodev_dh = {
855 "cryptodev DH method",
856 NULL, /* cryptodev_dh_generate_key */
857 cryptodev_dh_compute_key,
858 cryptodev_mod_exp_dh,
859 NULL,
860 NULL,
861 0, /* flags */
862 NULL /* app_data */
863};
864
865/*
866 * ctrl right now is just a wrapper that doesn't do much
867 * but I expect we'll want some options soon.
868 */
869static int
870cryptodev_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)())
871{
872 struct syslog_data sd = SYSLOG_DATA_INIT;
873
874 switch (cmd) {
875 default:
876 syslog_r(LOG_ERR, &sd,
877 "cryptodev_ctrl: unknown command %d", cmd);
878 break;
879 }
880 return (1);
881}
882
883void
884ENGINE_load_cryptodev(void)
885{
886 ENGINE *engine = ENGINE_new();
887 const RSA_METHOD *rsa_meth;
888 const DH_METHOD *dh_meth;
889
890 if (engine == NULL)
891 return;
892
893 if (!ENGINE_set_id(engine, "cryptodev") ||
894 !ENGINE_set_name(engine, "OpenBSD cryptodev engine") ||
895 !ENGINE_set_ciphers(engine, cryptodev_engine_ciphers) ||
896 !ENGINE_set_digests(engine, cryptodev_engine_digests) ||
897 !ENGINE_set_ctrl_function(engine, cryptodev_ctrl) ||
898 !ENGINE_set_cmd_defns(engine, cryptodev_defns)) {
899 ENGINE_free(engine);
900 return;
901 }
902
903 if ((cryptodev_symfeat & CRSFEAT_RSA) &&
904 ENGINE_set_RSA(engine, &cryptodev_rsa)) {
905 rsa_meth = RSA_PKCS1_SSLeay();
906 cryptodev_rsa.rsa_pub_enc = rsa_meth->rsa_pub_enc;
907 cryptodev_rsa.rsa_pub_dec = rsa_meth->rsa_pub_dec;
908 cryptodev_rsa.rsa_priv_enc = rsa_meth->rsa_priv_dec;
909 cryptodev_rsa.rsa_priv_dec = rsa_meth->rsa_priv_dec;
910 }
911
912 if ((cryptodev_symfeat & CRSFEAT_DSA) &&
913 ENGINE_set_DSA(engine, &cryptodev_dsa)) {
914 }
915
916 if ((cryptodev_symfeat & CRSFEAT_DH) &&
917 ENGINE_set_DH(engine, &cryptodev_dh)) {
918 dh_meth = DH_OpenSSL();
919 cryptodev_dh.generate_key = dh_meth->generate_key;
920 cryptodev_dh.compute_key = dh_meth->compute_key;
921 }
922
923 ENGINE_add(engine);
924 ENGINE_free(engine);
925 ERR_clear_error();
926}
diff --git a/src/lib/libcrypto/engine/hw_cswift.c b/src/lib/libcrypto/engine/hw_cswift.c
new file mode 100644
index 0000000000..77608b8983
--- /dev/null
+++ b/src/lib/libcrypto/engine/hw_cswift.c
@@ -0,0 +1,807 @@
1/* crypto/engine/hw_cswift.c */
2/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
3 * project 2000.
4 */
5/* ====================================================================
6 * Copyright (c) 1999 The OpenSSL Project. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * 3. All advertising materials mentioning features or use of this
21 * software must display the following acknowledgment:
22 * "This product includes software developed by the OpenSSL Project
23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24 *
25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26 * endorse or promote products derived from this software without
27 * prior written permission. For written permission, please contact
28 * licensing@OpenSSL.org.
29 *
30 * 5. Products derived from this software may not be called "OpenSSL"
31 * nor may "OpenSSL" appear in their names without prior written
32 * permission of the OpenSSL Project.
33 *
34 * 6. Redistributions of any form whatsoever must retain the following
35 * acknowledgment:
36 * "This product includes software developed by the OpenSSL Project
37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38 *
39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50 * OF THE POSSIBILITY OF SUCH DAMAGE.
51 * ====================================================================
52 *
53 * This product includes cryptographic software written by Eric Young
54 * (eay@cryptsoft.com). This product includes software written by Tim
55 * Hudson (tjh@cryptsoft.com).
56 *
57 */
58
59#include <stdio.h>
60#include <openssl/crypto.h>
61#include "cryptlib.h"
62#include <openssl/dso.h>
63#include "engine_int.h"
64#include <openssl/engine.h>
65
66#ifndef NO_HW
67#ifndef NO_HW_CSWIFT
68
69/* Attribution notice: Rainbow have generously allowed me to reproduce
70 * the necessary definitions here from their API. This means the support
71 * can build independently of whether application builders have the
72 * API or hardware. This will allow developers to easily produce software
73 * that has latent hardware support for any users that have accelerators
74 * installed, without the developers themselves needing anything extra.
75 *
76 * I have only clipped the parts from the CryptoSwift header files that
77 * are (or seem) relevant to the CryptoSwift support code. This is
78 * simply to keep the file sizes reasonable.
79 * [Geoff]
80 */
81#ifdef FLAT_INC
82#include "cswift.h"
83#else
84#include "vendor_defns/cswift.h"
85#endif
86
87static int cswift_init(void);
88static int cswift_finish(void);
89
90/* BIGNUM stuff */
91static int cswift_mod_exp(BIGNUM *r, BIGNUM *a, const BIGNUM *p,
92 const BIGNUM *m, BN_CTX *ctx);
93static int cswift_mod_exp_crt(BIGNUM *r, BIGNUM *a, const BIGNUM *p,
94 const BIGNUM *q, const BIGNUM *dmp1, const BIGNUM *dmq1,
95 const BIGNUM *iqmp, BN_CTX *ctx);
96
97/* RSA stuff */
98static int cswift_rsa_mod_exp(BIGNUM *r0, BIGNUM *I, RSA *rsa);
99/* This function is aliased to mod_exp (with the mont stuff dropped). */
100static int cswift_mod_exp_mont(BIGNUM *r, BIGNUM *a, const BIGNUM *p,
101 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
102
103/* DSA stuff */
104static DSA_SIG *cswift_dsa_sign(const unsigned char *dgst, int dlen, DSA *dsa);
105static int cswift_dsa_verify(const unsigned char *dgst, int dgst_len,
106 DSA_SIG *sig, DSA *dsa);
107
108/* DH stuff */
109/* This function is alised to mod_exp (with the DH and mont dropped). */
110static int cswift_mod_exp_dh(DH *dh, BIGNUM *r, BIGNUM *a, const BIGNUM *p,
111 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
112
113
114/* Our internal RSA_METHOD that we provide pointers to */
115static RSA_METHOD cswift_rsa =
116 {
117 "CryptoSwift RSA method",
118 NULL,
119 NULL,
120 NULL,
121 NULL,
122 cswift_rsa_mod_exp,
123 cswift_mod_exp_mont,
124 NULL,
125 NULL,
126 0,
127 NULL,
128 NULL,
129 NULL
130 };
131
132/* Our internal DSA_METHOD that we provide pointers to */
133static DSA_METHOD cswift_dsa =
134 {
135 "CryptoSwift DSA method",
136 cswift_dsa_sign,
137 NULL, /* dsa_sign_setup */
138 cswift_dsa_verify,
139 NULL, /* dsa_mod_exp */
140 NULL, /* bn_mod_exp */
141 NULL, /* init */
142 NULL, /* finish */
143 0, /* flags */
144 NULL /* app_data */
145 };
146
147/* Our internal DH_METHOD that we provide pointers to */
148static DH_METHOD cswift_dh =
149 {
150 "CryptoSwift DH method",
151 NULL,
152 NULL,
153 cswift_mod_exp_dh,
154 NULL,
155 NULL,
156 0,
157 NULL
158 };
159
160/* Our ENGINE structure. */
161static ENGINE engine_cswift =
162 {
163 "cswift",
164 "CryptoSwift hardware engine support",
165 &cswift_rsa,
166 &cswift_dsa,
167 &cswift_dh,
168 NULL,
169 cswift_mod_exp,
170 cswift_mod_exp_crt,
171 cswift_init,
172 cswift_finish,
173 NULL, /* no ctrl() */
174 NULL, /* no load_privkey() */
175 NULL, /* no load_pubkey() */
176 0, /* no flags */
177 0, 0, /* no references */
178 NULL, NULL /* unlinked */
179 };
180
181/* As this is only ever called once, there's no need for locking
182 * (indeed - the lock will already be held by our caller!!!) */
183ENGINE *ENGINE_cswift()
184 {
185 RSA_METHOD *meth1;
186 DH_METHOD *meth2;
187
188 /* We know that the "PKCS1_SSLeay()" functions hook properly
189 * to the cswift-specific mod_exp and mod_exp_crt so we use
190 * those functions. NB: We don't use ENGINE_openssl() or
191 * anything "more generic" because something like the RSAref
192 * code may not hook properly, and if you own one of these
193 * cards then you have the right to do RSA operations on it
194 * anyway! */
195 meth1 = RSA_PKCS1_SSLeay();
196 cswift_rsa.rsa_pub_enc = meth1->rsa_pub_enc;
197 cswift_rsa.rsa_pub_dec = meth1->rsa_pub_dec;
198 cswift_rsa.rsa_priv_enc = meth1->rsa_priv_enc;
199 cswift_rsa.rsa_priv_dec = meth1->rsa_priv_dec;
200
201 /* Much the same for Diffie-Hellman */
202 meth2 = DH_OpenSSL();
203 cswift_dh.generate_key = meth2->generate_key;
204 cswift_dh.compute_key = meth2->compute_key;
205 return &engine_cswift;
206 }
207
208/* This is a process-global DSO handle used for loading and unloading
209 * the CryptoSwift library. NB: This is only set (or unset) during an
210 * init() or finish() call (reference counts permitting) and they're
211 * operating with global locks, so this should be thread-safe
212 * implicitly. */
213static DSO *cswift_dso = NULL;
214
215/* These are the function pointers that are (un)set when the library has
216 * successfully (un)loaded. */
217t_swAcquireAccContext *p_CSwift_AcquireAccContext = NULL;
218t_swAttachKeyParam *p_CSwift_AttachKeyParam = NULL;
219t_swSimpleRequest *p_CSwift_SimpleRequest = NULL;
220t_swReleaseAccContext *p_CSwift_ReleaseAccContext = NULL;
221
222/* Used in the DSO operations. */
223static const char *CSWIFT_LIBNAME = "swift";
224static const char *CSWIFT_F1 = "swAcquireAccContext";
225static const char *CSWIFT_F2 = "swAttachKeyParam";
226static const char *CSWIFT_F3 = "swSimpleRequest";
227static const char *CSWIFT_F4 = "swReleaseAccContext";
228
229
230/* CryptoSwift library functions and mechanics - these are used by the
231 * higher-level functions further down. NB: As and where there's no
232 * error checking, take a look lower down where these functions are
233 * called, the checking and error handling is probably down there. */
234
235/* utility function to obtain a context */
236static int get_context(SW_CONTEXT_HANDLE *hac)
237 {
238 SW_STATUS status;
239
240 status = p_CSwift_AcquireAccContext(hac);
241 if(status != SW_OK)
242 return 0;
243 return 1;
244 }
245
246/* similarly to release one. */
247static void release_context(SW_CONTEXT_HANDLE hac)
248 {
249 p_CSwift_ReleaseAccContext(hac);
250 }
251
252/* (de)initialisation functions. */
253static int cswift_init()
254 {
255 SW_CONTEXT_HANDLE hac;
256 t_swAcquireAccContext *p1;
257 t_swAttachKeyParam *p2;
258 t_swSimpleRequest *p3;
259 t_swReleaseAccContext *p4;
260
261 if(cswift_dso != NULL)
262 {
263 ENGINEerr(ENGINE_F_CSWIFT_INIT,ENGINE_R_ALREADY_LOADED);
264 goto err;
265 }
266 /* Attempt to load libswift.so/swift.dll/whatever. */
267 cswift_dso = DSO_load(NULL, CSWIFT_LIBNAME, NULL,
268 DSO_FLAG_NAME_TRANSLATION);
269 if(cswift_dso == NULL)
270 {
271 ENGINEerr(ENGINE_F_CSWIFT_INIT,ENGINE_R_DSO_FAILURE);
272 goto err;
273 }
274 if(!(p1 = (t_swAcquireAccContext *)
275 DSO_bind_func(cswift_dso, CSWIFT_F1)) ||
276 !(p2 = (t_swAttachKeyParam *)
277 DSO_bind_func(cswift_dso, CSWIFT_F2)) ||
278 !(p3 = (t_swSimpleRequest *)
279 DSO_bind_func(cswift_dso, CSWIFT_F3)) ||
280 !(p4 = (t_swReleaseAccContext *)
281 DSO_bind_func(cswift_dso, CSWIFT_F4)))
282 {
283 ENGINEerr(ENGINE_F_CSWIFT_INIT,ENGINE_R_DSO_FAILURE);
284 goto err;
285 }
286 /* Copy the pointers */
287 p_CSwift_AcquireAccContext = p1;
288 p_CSwift_AttachKeyParam = p2;
289 p_CSwift_SimpleRequest = p3;
290 p_CSwift_ReleaseAccContext = p4;
291 /* Try and get a context - if not, we may have a DSO but no
292 * accelerator! */
293 if(!get_context(&hac))
294 {
295 ENGINEerr(ENGINE_F_CSWIFT_INIT,ENGINE_R_UNIT_FAILURE);
296 goto err;
297 }
298 release_context(hac);
299 /* Everything's fine. */
300 return 1;
301err:
302 if(cswift_dso)
303 DSO_free(cswift_dso);
304 p_CSwift_AcquireAccContext = NULL;
305 p_CSwift_AttachKeyParam = NULL;
306 p_CSwift_SimpleRequest = NULL;
307 p_CSwift_ReleaseAccContext = NULL;
308 return 0;
309 }
310
311static int cswift_finish()
312 {
313 if(cswift_dso == NULL)
314 {
315 ENGINEerr(ENGINE_F_CSWIFT_FINISH,ENGINE_R_NOT_LOADED);
316 return 0;
317 }
318 if(!DSO_free(cswift_dso))
319 {
320 ENGINEerr(ENGINE_F_CSWIFT_FINISH,ENGINE_R_DSO_FAILURE);
321 return 0;
322 }
323 cswift_dso = NULL;
324 p_CSwift_AcquireAccContext = NULL;
325 p_CSwift_AttachKeyParam = NULL;
326 p_CSwift_SimpleRequest = NULL;
327 p_CSwift_ReleaseAccContext = NULL;
328 return 1;
329 }
330
331/* Un petit mod_exp */
332static int cswift_mod_exp(BIGNUM *r, BIGNUM *a, const BIGNUM *p,
333 const BIGNUM *m, BN_CTX *ctx)
334 {
335 /* I need somewhere to store temporary serialised values for
336 * use with the CryptoSwift API calls. A neat cheat - I'll use
337 * BIGNUMs from the BN_CTX but access their arrays directly as
338 * byte arrays <grin>. This way I don't have to clean anything
339 * up. */
340 BIGNUM *modulus;
341 BIGNUM *exponent;
342 BIGNUM *argument;
343 BIGNUM *result;
344 SW_STATUS sw_status;
345 SW_LARGENUMBER arg, res;
346 SW_PARAM sw_param;
347 SW_CONTEXT_HANDLE hac;
348 int to_return, acquired;
349
350 modulus = exponent = argument = result = NULL;
351 to_return = 0; /* expect failure */
352 acquired = 0;
353
354 if(!get_context(&hac))
355 {
356 ENGINEerr(ENGINE_F_CSWIFT_MOD_EXP,ENGINE_R_GET_HANDLE_FAILED);
357 goto err;
358 }
359 acquired = 1;
360 /* Prepare the params */
361 modulus = BN_CTX_get(ctx);
362 exponent = BN_CTX_get(ctx);
363 argument = BN_CTX_get(ctx);
364 result = BN_CTX_get(ctx);
365 if(!modulus || !exponent || !argument || !result)
366 {
367 ENGINEerr(ENGINE_F_CSWIFT_MOD_EXP,ENGINE_R_BN_CTX_FULL);
368 goto err;
369 }
370 if(!bn_wexpand(modulus, m->top) || !bn_wexpand(exponent, p->top) ||
371 !bn_wexpand(argument, a->top) || !bn_wexpand(result, m->top))
372 {
373 ENGINEerr(ENGINE_F_CSWIFT_MOD_EXP,ENGINE_R_BN_EXPAND_FAIL);
374 goto err;
375 }
376 sw_param.type = SW_ALG_EXP;
377 sw_param.up.exp.modulus.nbytes = BN_bn2bin(m,
378 (unsigned char *)modulus->d);
379 sw_param.up.exp.modulus.value = (unsigned char *)modulus->d;
380 sw_param.up.exp.exponent.nbytes = BN_bn2bin(p,
381 (unsigned char *)exponent->d);
382 sw_param.up.exp.exponent.value = (unsigned char *)exponent->d;
383 /* Attach the key params */
384 sw_status = p_CSwift_AttachKeyParam(hac, &sw_param);
385 switch(sw_status)
386 {
387 case SW_OK:
388 break;
389 case SW_ERR_INPUT_SIZE:
390 ENGINEerr(ENGINE_F_CSWIFT_MOD_EXP,
391 ENGINE_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
392 goto err;
393 default:
394 {
395 char tmpbuf[20];
396 ENGINEerr(ENGINE_F_CSWIFT_MOD_EXP,ENGINE_R_REQUEST_FAILED);
397 sprintf(tmpbuf, "%ld", sw_status);
398 ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf);
399 }
400 goto err;
401 }
402 /* Prepare the argument and response */
403 arg.nbytes = BN_bn2bin(a, (unsigned char *)argument->d);
404 arg.value = (unsigned char *)argument->d;
405 res.nbytes = BN_num_bytes(m);
406 memset(result->d, 0, res.nbytes);
407 res.value = (unsigned char *)result->d;
408 /* Perform the operation */
409 if((sw_status = p_CSwift_SimpleRequest(hac, SW_CMD_MODEXP, &arg, 1,
410 &res, 1)) != SW_OK)
411 {
412 char tmpbuf[20];
413 ENGINEerr(ENGINE_F_CSWIFT_MOD_EXP,ENGINE_R_REQUEST_FAILED);
414 sprintf(tmpbuf, "%ld", sw_status);
415 ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf);
416 goto err;
417 }
418 /* Convert the response */
419 BN_bin2bn((unsigned char *)result->d, res.nbytes, r);
420 to_return = 1;
421err:
422 if(acquired)
423 release_context(hac);
424 if(modulus) ctx->tos--;
425 if(exponent) ctx->tos--;
426 if(argument) ctx->tos--;
427 if(result) ctx->tos--;
428 return to_return;
429 }
430
431/* Un petit mod_exp chinois */
432static int cswift_mod_exp_crt(BIGNUM *r, BIGNUM *a, const BIGNUM *p,
433 const BIGNUM *q, const BIGNUM *dmp1,
434 const BIGNUM *dmq1, const BIGNUM *iqmp, BN_CTX *ctx)
435 {
436 SW_STATUS sw_status;
437 SW_LARGENUMBER arg, res;
438 SW_PARAM sw_param;
439 SW_CONTEXT_HANDLE hac;
440 BIGNUM *rsa_p = NULL;
441 BIGNUM *rsa_q = NULL;
442 BIGNUM *rsa_dmp1 = NULL;
443 BIGNUM *rsa_dmq1 = NULL;
444 BIGNUM *rsa_iqmp = NULL;
445 BIGNUM *argument = NULL;
446 BIGNUM *result = NULL;
447 int to_return = 0; /* expect failure */
448 int acquired = 0;
449
450 if(!get_context(&hac))
451 {
452 ENGINEerr(ENGINE_F_CSWIFT_MOD_EXP_CRT,ENGINE_R_GET_HANDLE_FAILED);
453 goto err;
454 }
455 acquired = 1;
456 /* Prepare the params */
457 rsa_p = BN_CTX_get(ctx);
458 rsa_q = BN_CTX_get(ctx);
459 rsa_dmp1 = BN_CTX_get(ctx);
460 rsa_dmq1 = BN_CTX_get(ctx);
461 rsa_iqmp = BN_CTX_get(ctx);
462 argument = BN_CTX_get(ctx);
463 result = BN_CTX_get(ctx);
464 if(!rsa_p || !rsa_q || !rsa_dmp1 || !rsa_dmq1 || !rsa_iqmp ||
465 !argument || !result)
466 {
467 ENGINEerr(ENGINE_F_CSWIFT_MOD_EXP_CRT,ENGINE_R_BN_CTX_FULL);
468 goto err;
469 }
470 if(!bn_wexpand(rsa_p, p->top) || !bn_wexpand(rsa_q, q->top) ||
471 !bn_wexpand(rsa_dmp1, dmp1->top) ||
472 !bn_wexpand(rsa_dmq1, dmq1->top) ||
473 !bn_wexpand(rsa_iqmp, iqmp->top) ||
474 !bn_wexpand(argument, a->top) ||
475 !bn_wexpand(result, p->top + q->top))
476 {
477 ENGINEerr(ENGINE_F_CSWIFT_MOD_EXP_CRT,ENGINE_R_BN_EXPAND_FAIL);
478 goto err;
479 }
480 sw_param.type = SW_ALG_CRT;
481 sw_param.up.crt.p.nbytes = BN_bn2bin(p, (unsigned char *)rsa_p->d);
482 sw_param.up.crt.p.value = (unsigned char *)rsa_p->d;
483 sw_param.up.crt.q.nbytes = BN_bn2bin(q, (unsigned char *)rsa_q->d);
484 sw_param.up.crt.q.value = (unsigned char *)rsa_q->d;
485 sw_param.up.crt.dmp1.nbytes = BN_bn2bin(dmp1,
486 (unsigned char *)rsa_dmp1->d);
487 sw_param.up.crt.dmp1.value = (unsigned char *)rsa_dmp1->d;
488 sw_param.up.crt.dmq1.nbytes = BN_bn2bin(dmq1,
489 (unsigned char *)rsa_dmq1->d);
490 sw_param.up.crt.dmq1.value = (unsigned char *)rsa_dmq1->d;
491 sw_param.up.crt.iqmp.nbytes = BN_bn2bin(iqmp,
492 (unsigned char *)rsa_iqmp->d);
493 sw_param.up.crt.iqmp.value = (unsigned char *)rsa_iqmp->d;
494 /* Attach the key params */
495 sw_status = p_CSwift_AttachKeyParam(hac, &sw_param);
496 switch(sw_status)
497 {
498 case SW_OK:
499 break;
500 case SW_ERR_INPUT_SIZE:
501 ENGINEerr(ENGINE_F_CSWIFT_MOD_EXP_CRT,
502 ENGINE_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
503 goto err;
504 default:
505 {
506 char tmpbuf[20];
507 ENGINEerr(ENGINE_F_CSWIFT_MOD_EXP_CRT,ENGINE_R_REQUEST_FAILED);
508 sprintf(tmpbuf, "%ld", sw_status);
509 ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf);
510 }
511 goto err;
512 }
513 /* Prepare the argument and response */
514 arg.nbytes = BN_bn2bin(a, (unsigned char *)argument->d);
515 arg.value = (unsigned char *)argument->d;
516 res.nbytes = 2 * BN_num_bytes(p);
517 memset(result->d, 0, res.nbytes);
518 res.value = (unsigned char *)result->d;
519 /* Perform the operation */
520 if((sw_status = p_CSwift_SimpleRequest(hac, SW_CMD_MODEXP_CRT, &arg, 1,
521 &res, 1)) != SW_OK)
522 {
523 char tmpbuf[20];
524 ENGINEerr(ENGINE_F_CSWIFT_MOD_EXP_CRT,ENGINE_R_REQUEST_FAILED);
525 sprintf(tmpbuf, "%ld", sw_status);
526 ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf);
527 goto err;
528 }
529 /* Convert the response */
530 BN_bin2bn((unsigned char *)result->d, res.nbytes, r);
531 to_return = 1;
532err:
533 if(acquired)
534 release_context(hac);
535 if(rsa_p) ctx->tos--;
536 if(rsa_q) ctx->tos--;
537 if(rsa_dmp1) ctx->tos--;
538 if(rsa_dmq1) ctx->tos--;
539 if(rsa_iqmp) ctx->tos--;
540 if(argument) ctx->tos--;
541 if(result) ctx->tos--;
542 return to_return;
543 }
544
545static int cswift_rsa_mod_exp(BIGNUM *r0, BIGNUM *I, RSA *rsa)
546 {
547 BN_CTX *ctx;
548 int to_return = 0;
549
550 if((ctx = BN_CTX_new()) == NULL)
551 goto err;
552 if(!rsa->p || !rsa->q || !rsa->dmp1 || !rsa->dmq1 || !rsa->iqmp)
553 {
554 ENGINEerr(ENGINE_F_CSWIFT_RSA_MOD_EXP,ENGINE_R_MISSING_KEY_COMPONENTS);
555 goto err;
556 }
557 to_return = cswift_mod_exp_crt(r0, I, rsa->p, rsa->q, rsa->dmp1,
558 rsa->dmq1, rsa->iqmp, ctx);
559err:
560 if(ctx)
561 BN_CTX_free(ctx);
562 return to_return;
563 }
564
565/* This function is aliased to mod_exp (with the mont stuff dropped). */
566static int cswift_mod_exp_mont(BIGNUM *r, BIGNUM *a, const BIGNUM *p,
567 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
568 {
569 return cswift_mod_exp(r, a, p, m, ctx);
570 }
571
572static DSA_SIG *cswift_dsa_sign(const unsigned char *dgst, int dlen, DSA *dsa)
573 {
574 SW_CONTEXT_HANDLE hac;
575 SW_PARAM sw_param;
576 SW_STATUS sw_status;
577 SW_LARGENUMBER arg, res;
578 unsigned char *ptr;
579 BN_CTX *ctx;
580 BIGNUM *dsa_p = NULL;
581 BIGNUM *dsa_q = NULL;
582 BIGNUM *dsa_g = NULL;
583 BIGNUM *dsa_key = NULL;
584 BIGNUM *result = NULL;
585 DSA_SIG *to_return = NULL;
586 int acquired = 0;
587
588 if((ctx = BN_CTX_new()) == NULL)
589 goto err;
590 if(!get_context(&hac))
591 {
592 ENGINEerr(ENGINE_F_CSWIFT_DSA_SIGN,ENGINE_R_GET_HANDLE_FAILED);
593 goto err;
594 }
595 acquired = 1;
596 /* Prepare the params */
597 dsa_p = BN_CTX_get(ctx);
598 dsa_q = BN_CTX_get(ctx);
599 dsa_g = BN_CTX_get(ctx);
600 dsa_key = BN_CTX_get(ctx);
601 result = BN_CTX_get(ctx);
602 if(!dsa_p || !dsa_q || !dsa_g || !dsa_key || !result)
603 {
604 ENGINEerr(ENGINE_F_CSWIFT_DSA_SIGN,ENGINE_R_BN_CTX_FULL);
605 goto err;
606 }
607 if(!bn_wexpand(dsa_p, dsa->p->top) ||
608 !bn_wexpand(dsa_q, dsa->q->top) ||
609 !bn_wexpand(dsa_g, dsa->g->top) ||
610 !bn_wexpand(dsa_key, dsa->priv_key->top) ||
611 !bn_wexpand(result, dsa->p->top))
612 {
613 ENGINEerr(ENGINE_F_CSWIFT_DSA_SIGN,ENGINE_R_BN_EXPAND_FAIL);
614 goto err;
615 }
616 sw_param.type = SW_ALG_DSA;
617 sw_param.up.dsa.p.nbytes = BN_bn2bin(dsa->p,
618 (unsigned char *)dsa_p->d);
619 sw_param.up.dsa.p.value = (unsigned char *)dsa_p->d;
620 sw_param.up.dsa.q.nbytes = BN_bn2bin(dsa->q,
621 (unsigned char *)dsa_q->d);
622 sw_param.up.dsa.q.value = (unsigned char *)dsa_q->d;
623 sw_param.up.dsa.g.nbytes = BN_bn2bin(dsa->g,
624 (unsigned char *)dsa_g->d);
625 sw_param.up.dsa.g.value = (unsigned char *)dsa_g->d;
626 sw_param.up.dsa.key.nbytes = BN_bn2bin(dsa->priv_key,
627 (unsigned char *)dsa_key->d);
628 sw_param.up.dsa.key.value = (unsigned char *)dsa_key->d;
629 /* Attach the key params */
630 sw_status = p_CSwift_AttachKeyParam(hac, &sw_param);
631 switch(sw_status)
632 {
633 case SW_OK:
634 break;
635 case SW_ERR_INPUT_SIZE:
636 ENGINEerr(ENGINE_F_CSWIFT_DSA_SIGN,
637 ENGINE_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
638 goto err;
639 default:
640 {
641 char tmpbuf[20];
642 ENGINEerr(ENGINE_F_CSWIFT_DSA_SIGN,ENGINE_R_REQUEST_FAILED);
643 sprintf(tmpbuf, "%ld", sw_status);
644 ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf);
645 }
646 goto err;
647 }
648 /* Prepare the argument and response */
649 arg.nbytes = dlen;
650 arg.value = (unsigned char *)dgst;
651 res.nbytes = BN_num_bytes(dsa->p);
652 memset(result->d, 0, res.nbytes);
653 res.value = (unsigned char *)result->d;
654 /* Perform the operation */
655 sw_status = p_CSwift_SimpleRequest(hac, SW_CMD_DSS_SIGN, &arg, 1,
656 &res, 1);
657 if(sw_status != SW_OK)
658 {
659 char tmpbuf[20];
660 ENGINEerr(ENGINE_F_CSWIFT_DSA_SIGN,ENGINE_R_REQUEST_FAILED);
661 sprintf(tmpbuf, "%ld", sw_status);
662 ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf);
663 goto err;
664 }
665 /* Convert the response */
666 ptr = (unsigned char *)result->d;
667 if((to_return = DSA_SIG_new()) == NULL)
668 goto err;
669 to_return->r = BN_bin2bn((unsigned char *)result->d, 20, NULL);
670 to_return->s = BN_bin2bn((unsigned char *)result->d + 20, 20, NULL);
671
672err:
673 if(acquired)
674 release_context(hac);
675 if(dsa_p) ctx->tos--;
676 if(dsa_q) ctx->tos--;
677 if(dsa_g) ctx->tos--;
678 if(dsa_key) ctx->tos--;
679 if(result) ctx->tos--;
680 if(ctx)
681 BN_CTX_free(ctx);
682 return to_return;
683 }
684
685static int cswift_dsa_verify(const unsigned char *dgst, int dgst_len,
686 DSA_SIG *sig, DSA *dsa)
687 {
688 SW_CONTEXT_HANDLE hac;
689 SW_PARAM sw_param;
690 SW_STATUS sw_status;
691 SW_LARGENUMBER arg[2], res;
692 unsigned long sig_result;
693 BN_CTX *ctx;
694 BIGNUM *dsa_p = NULL;
695 BIGNUM *dsa_q = NULL;
696 BIGNUM *dsa_g = NULL;
697 BIGNUM *dsa_key = NULL;
698 BIGNUM *argument = NULL;
699 int to_return = -1;
700 int acquired = 0;
701
702 if((ctx = BN_CTX_new()) == NULL)
703 goto err;
704 if(!get_context(&hac))
705 {
706 ENGINEerr(ENGINE_F_CSWIFT_DSA_VERIFY,ENGINE_R_GET_HANDLE_FAILED);
707 goto err;
708 }
709 acquired = 1;
710 /* Prepare the params */
711 dsa_p = BN_CTX_get(ctx);
712 dsa_q = BN_CTX_get(ctx);
713 dsa_g = BN_CTX_get(ctx);
714 dsa_key = BN_CTX_get(ctx);
715 argument = BN_CTX_get(ctx);
716 if(!dsa_p || !dsa_q || !dsa_g || !dsa_key || !argument)
717 {
718 ENGINEerr(ENGINE_F_CSWIFT_DSA_VERIFY,ENGINE_R_BN_CTX_FULL);
719 goto err;
720 }
721 if(!bn_wexpand(dsa_p, dsa->p->top) ||
722 !bn_wexpand(dsa_q, dsa->q->top) ||
723 !bn_wexpand(dsa_g, dsa->g->top) ||
724 !bn_wexpand(dsa_key, dsa->pub_key->top) ||
725 !bn_wexpand(argument, 40))
726 {
727 ENGINEerr(ENGINE_F_CSWIFT_DSA_VERIFY,ENGINE_R_BN_EXPAND_FAIL);
728 goto err;
729 }
730 sw_param.type = SW_ALG_DSA;
731 sw_param.up.dsa.p.nbytes = BN_bn2bin(dsa->p,
732 (unsigned char *)dsa_p->d);
733 sw_param.up.dsa.p.value = (unsigned char *)dsa_p->d;
734 sw_param.up.dsa.q.nbytes = BN_bn2bin(dsa->q,
735 (unsigned char *)dsa_q->d);
736 sw_param.up.dsa.q.value = (unsigned char *)dsa_q->d;
737 sw_param.up.dsa.g.nbytes = BN_bn2bin(dsa->g,
738 (unsigned char *)dsa_g->d);
739 sw_param.up.dsa.g.value = (unsigned char *)dsa_g->d;
740 sw_param.up.dsa.key.nbytes = BN_bn2bin(dsa->pub_key,
741 (unsigned char *)dsa_key->d);
742 sw_param.up.dsa.key.value = (unsigned char *)dsa_key->d;
743 /* Attach the key params */
744 sw_status = p_CSwift_AttachKeyParam(hac, &sw_param);
745 switch(sw_status)
746 {
747 case SW_OK:
748 break;
749 case SW_ERR_INPUT_SIZE:
750 ENGINEerr(ENGINE_F_CSWIFT_DSA_VERIFY,
751 ENGINE_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
752 goto err;
753 default:
754 {
755 char tmpbuf[20];
756 ENGINEerr(ENGINE_F_CSWIFT_DSA_VERIFY,ENGINE_R_REQUEST_FAILED);
757 sprintf(tmpbuf, "%ld", sw_status);
758 ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf);
759 }
760 goto err;
761 }
762 /* Prepare the argument and response */
763 arg[0].nbytes = dgst_len;
764 arg[0].value = (unsigned char *)dgst;
765 arg[1].nbytes = 40;
766 arg[1].value = (unsigned char *)argument->d;
767 memset(arg[1].value, 0, 40);
768 BN_bn2bin(sig->r, arg[1].value + 20 - BN_num_bytes(sig->r));
769 BN_bn2bin(sig->s, arg[1].value + 40 - BN_num_bytes(sig->s));
770 res.nbytes = 4; /* unsigned long */
771 res.value = (unsigned char *)(&sig_result);
772 /* Perform the operation */
773 sw_status = p_CSwift_SimpleRequest(hac, SW_CMD_DSS_VERIFY, arg, 2,
774 &res, 1);
775 if(sw_status != SW_OK)
776 {
777 char tmpbuf[20];
778 ENGINEerr(ENGINE_F_CSWIFT_DSA_VERIFY,ENGINE_R_REQUEST_FAILED);
779 sprintf(tmpbuf, "%ld", sw_status);
780 ERR_add_error_data(2, "CryptoSwift error number is ",tmpbuf);
781 goto err;
782 }
783 /* Convert the response */
784 to_return = ((sig_result == 0) ? 0 : 1);
785
786err:
787 if(acquired)
788 release_context(hac);
789 if(dsa_p) ctx->tos--;
790 if(dsa_q) ctx->tos--;
791 if(dsa_g) ctx->tos--;
792 if(dsa_key) ctx->tos--;
793 if(argument) ctx->tos--;
794 if(ctx)
795 BN_CTX_free(ctx);
796 return to_return;
797 }
798
799/* This function is aliased to mod_exp (with the dh and mont dropped). */
800static int cswift_mod_exp_dh(DH *dh, BIGNUM *r, BIGNUM *a, const BIGNUM *p,
801 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
802 {
803 return cswift_mod_exp(r, a, p, m, ctx);
804 }
805
806#endif /* !NO_HW_CSWIFT */
807#endif /* !NO_HW */
diff --git a/src/lib/libcrypto/engine/hw_cswift_err.c b/src/lib/libcrypto/engine/hw_cswift_err.c
new file mode 100644
index 0000000000..684f53bf27
--- /dev/null
+++ b/src/lib/libcrypto/engine/hw_cswift_err.c
@@ -0,0 +1,149 @@
1/* hw_cswift_err.c */
2/* ====================================================================
3 * Copyright (c) 1999 The OpenSSL Project. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
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
15 * distribution.
16 *
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/)"
21 *
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 * openssl-core@OpenSSL.org.
26 *
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.
30 *
31 * 6. Redistributions of any form whatsoever must retain the following
32 * acknowledgment:
33 * "This product includes software developed by the OpenSSL Project
34 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
35 *
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 * ====================================================================
49 *
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).
53 *
54 */
55
56/* NOTE: this file was auto generated by the mkerr.pl script: any changes
57 * made to it will be overwritten when the script next updates this file,
58 * only reason strings will be preserved.
59 */
60
61#include <stdio.h>
62#include <openssl/err.h>
63#include "hw_cswift_err.h"
64
65/* BEGIN ERROR CODES */
66#ifndef OPENSSL_NO_ERR
67static ERR_STRING_DATA CSWIFT_str_functs[]=
68 {
69{ERR_PACK(0,CSWIFT_F_CSWIFT_CTRL,0), "CSWIFT_CTRL"},
70{ERR_PACK(0,CSWIFT_F_CSWIFT_DSA_SIGN,0), "CSWIFT_DSA_SIGN"},
71{ERR_PACK(0,CSWIFT_F_CSWIFT_DSA_VERIFY,0), "CSWIFT_DSA_VERIFY"},
72{ERR_PACK(0,CSWIFT_F_CSWIFT_FINISH,0), "CSWIFT_FINISH"},
73{ERR_PACK(0,CSWIFT_F_CSWIFT_INIT,0), "CSWIFT_INIT"},
74{ERR_PACK(0,CSWIFT_F_CSWIFT_MOD_EXP,0), "CSWIFT_MOD_EXP"},
75{ERR_PACK(0,CSWIFT_F_CSWIFT_MOD_EXP_CRT,0), "CSWIFT_MOD_EXP_CRT"},
76{ERR_PACK(0,CSWIFT_F_CSWIFT_RSA_MOD_EXP,0), "CSWIFT_RSA_MOD_EXP"},
77{0,NULL}
78 };
79
80static ERR_STRING_DATA CSWIFT_str_reasons[]=
81 {
82{CSWIFT_R_ALREADY_LOADED ,"already loaded"},
83{CSWIFT_R_BAD_KEY_SIZE ,"bad key size"},
84{CSWIFT_R_BN_CTX_FULL ,"bn ctx full"},
85{CSWIFT_R_BN_EXPAND_FAIL ,"bn expand fail"},
86{CSWIFT_R_CTRL_COMMAND_NOT_IMPLEMENTED ,"ctrl command not implemented"},
87{CSWIFT_R_MISSING_KEY_COMPONENTS ,"missing key components"},
88{CSWIFT_R_NOT_LOADED ,"not loaded"},
89{CSWIFT_R_REQUEST_FAILED ,"request failed"},
90{CSWIFT_R_UNIT_FAILURE ,"unit failure"},
91{0,NULL}
92 };
93
94#endif
95
96#ifdef CSWIFT_LIB_NAME
97static ERR_STRING_DATA CSWIFT_lib_name[]=
98 {
99{0 ,CSWIFT_LIB_NAME},
100{0,NULL}
101 };
102#endif
103
104
105static int CSWIFT_lib_error_code=0;
106static int CSWIFT_error_init=1;
107
108static void ERR_load_CSWIFT_strings(void)
109 {
110 if (CSWIFT_lib_error_code == 0)
111 CSWIFT_lib_error_code=ERR_get_next_error_library();
112
113 if (CSWIFT_error_init)
114 {
115 CSWIFT_error_init=0;
116#ifndef OPENSSL_NO_ERR
117 ERR_load_strings(CSWIFT_lib_error_code,CSWIFT_str_functs);
118 ERR_load_strings(CSWIFT_lib_error_code,CSWIFT_str_reasons);
119#endif
120
121#ifdef CSWIFT_LIB_NAME
122 CSWIFT_lib_name->error = ERR_PACK(CSWIFT_lib_error_code,0,0);
123 ERR_load_strings(0,CSWIFT_lib_name);
124#endif
125 }
126 }
127
128static void ERR_unload_CSWIFT_strings(void)
129 {
130 if (CSWIFT_error_init == 0)
131 {
132#ifndef OPENSSL_NO_ERR
133 ERR_unload_strings(CSWIFT_lib_error_code,CSWIFT_str_functs);
134 ERR_unload_strings(CSWIFT_lib_error_code,CSWIFT_str_reasons);
135#endif
136
137#ifdef CSWIFT_LIB_NAME
138 ERR_unload_strings(0,CSWIFT_lib_name);
139#endif
140 CSWIFT_error_init=1;
141 }
142 }
143
144static void ERR_CSWIFT_error(int function, int reason, char *file, int line)
145 {
146 if (CSWIFT_lib_error_code == 0)
147 CSWIFT_lib_error_code=ERR_get_next_error_library();
148 ERR_PUT_error(CSWIFT_lib_error_code,function,reason,file,line);
149 }
diff --git a/src/lib/libcrypto/engine/hw_cswift_err.h b/src/lib/libcrypto/engine/hw_cswift_err.h
new file mode 100644
index 0000000000..7120c3216f
--- /dev/null
+++ b/src/lib/libcrypto/engine/hw_cswift_err.h
@@ -0,0 +1,93 @@
1/* ====================================================================
2 * Copyright (c) 2001 The OpenSSL Project. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in
13 * the documentation and/or other materials provided with the
14 * distribution.
15 *
16 * 3. All advertising materials mentioning features or use of this
17 * software must display the following acknowledgment:
18 * "This product includes software developed by the OpenSSL Project
19 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
20 *
21 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
22 * endorse or promote products derived from this software without
23 * prior written permission. For written permission, please contact
24 * openssl-core@openssl.org.
25 *
26 * 5. Products derived from this software may not be called "OpenSSL"
27 * nor may "OpenSSL" appear in their names without prior written
28 * permission of the OpenSSL Project.
29 *
30 * 6. Redistributions of any form whatsoever must retain the following
31 * acknowledgment:
32 * "This product includes software developed by the OpenSSL Project
33 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
34 *
35 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
36 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
37 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
38 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
39 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
41 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
42 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
43 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
44 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
45 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
46 * OF THE POSSIBILITY OF SUCH DAMAGE.
47 * ====================================================================
48 *
49 * This product includes cryptographic software written by Eric Young
50 * (eay@cryptsoft.com). This product includes software written by Tim
51 * Hudson (tjh@cryptsoft.com).
52 *
53 */
54
55#ifndef HEADER_CSWIFT_ERR_H
56#define HEADER_CSWIFT_ERR_H
57
58/* BEGIN ERROR CODES */
59/* The following lines are auto generated by the script mkerr.pl. Any changes
60 * made after this point may be overwritten when the script is next run.
61 */
62static void ERR_load_CSWIFT_strings(void);
63static void ERR_unload_CSWIFT_strings(void);
64static void ERR_CSWIFT_error(int function, int reason, char *file, int line);
65#define CSWIFTerr(f,r) ERR_CSWIFT_error((f),(r),__FILE__,__LINE__)
66
67/* Error codes for the CSWIFT functions. */
68
69/* Function codes. */
70#define CSWIFT_F_CSWIFT_CTRL 100
71#define CSWIFT_F_CSWIFT_DSA_SIGN 101
72#define CSWIFT_F_CSWIFT_DSA_VERIFY 102
73#define CSWIFT_F_CSWIFT_FINISH 103
74#define CSWIFT_F_CSWIFT_INIT 104
75#define CSWIFT_F_CSWIFT_MOD_EXP 105
76#define CSWIFT_F_CSWIFT_MOD_EXP_CRT 106
77#define CSWIFT_F_CSWIFT_RSA_MOD_EXP 107
78
79/* Reason codes. */
80#define CSWIFT_R_ALREADY_LOADED 100
81#define CSWIFT_R_BAD_KEY_SIZE 101
82#define CSWIFT_R_BN_CTX_FULL 102
83#define CSWIFT_R_BN_EXPAND_FAIL 103
84#define CSWIFT_R_CTRL_COMMAND_NOT_IMPLEMENTED 104
85#define CSWIFT_R_MISSING_KEY_COMPONENTS 105
86#define CSWIFT_R_NOT_LOADED 106
87#define CSWIFT_R_REQUEST_FAILED 107
88#define CSWIFT_R_UNIT_FAILURE 108
89
90#ifdef __cplusplus
91}
92#endif
93#endif
diff --git a/src/lib/libcrypto/engine/hw_ncipher.c b/src/lib/libcrypto/engine/hw_ncipher.c
new file mode 100644
index 0000000000..41f5900676
--- /dev/null
+++ b/src/lib/libcrypto/engine/hw_ncipher.c
@@ -0,0 +1,1019 @@
1/* crypto/engine/hw_ncipher.c -*- mode: C; c-file-style: "eay" -*- */
2/* Written by Richard Levitte (richard@levitte.org), Geoff Thorpe
3 * (geoff@geoffthorpe.net) and Dr Stephen N Henson (shenson@bigfoot.com)
4 * for the OpenSSL project 2000.
5 */
6/* ====================================================================
7 * Copyright (c) 1999 The OpenSSL Project. All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 *
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 *
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in
18 * the documentation and/or other materials provided with the
19 * distribution.
20 *
21 * 3. All advertising materials mentioning features or use of this
22 * software must display the following acknowledgment:
23 * "This product includes software developed by the OpenSSL Project
24 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
25 *
26 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
27 * endorse or promote products derived from this software without
28 * prior written permission. For written permission, please contact
29 * licensing@OpenSSL.org.
30 *
31 * 5. Products derived from this software may not be called "OpenSSL"
32 * nor may "OpenSSL" appear in their names without prior written
33 * permission of the OpenSSL Project.
34 *
35 * 6. Redistributions of any form whatsoever must retain the following
36 * acknowledgment:
37 * "This product includes software developed by the OpenSSL Project
38 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
39 *
40 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
41 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
43 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
44 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
45 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
46 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
47 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
49 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
50 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
51 * OF THE POSSIBILITY OF SUCH DAMAGE.
52 * ====================================================================
53 *
54 * This product includes cryptographic software written by Eric Young
55 * (eay@cryptsoft.com). This product includes software written by Tim
56 * Hudson (tjh@cryptsoft.com).
57 *
58 */
59
60#include <stdio.h>
61#include <openssl/crypto.h>
62#include <openssl/pem.h>
63#include "cryptlib.h"
64#include <openssl/dso.h>
65#include "engine_int.h"
66#include <openssl/engine.h>
67
68#ifndef NO_HW
69#ifndef NO_HW_NCIPHER
70
71/* Attribution notice: nCipher have said several times that it's OK for
72 * us to implement a general interface to their boxes, and recently declared
73 * their HWCryptoHook to be public, and therefore available for us to use.
74 * Thanks, nCipher.
75 *
76 * The hwcryptohook.h included here is from May 2000.
77 * [Richard Levitte]
78 */
79#ifdef FLAT_INC
80#include "hwcryptohook.h"
81#else
82#include "vendor_defns/hwcryptohook.h"
83#endif
84
85static int hwcrhk_init(void);
86static int hwcrhk_finish(void);
87static int hwcrhk_ctrl(int cmd, long i, void *p, void (*f)());
88
89/* Functions to handle mutexes */
90static int hwcrhk_mutex_init(HWCryptoHook_Mutex*, HWCryptoHook_CallerContext*);
91static int hwcrhk_mutex_lock(HWCryptoHook_Mutex*);
92static void hwcrhk_mutex_unlock(HWCryptoHook_Mutex*);
93static void hwcrhk_mutex_destroy(HWCryptoHook_Mutex*);
94
95/* BIGNUM stuff */
96static int hwcrhk_mod_exp(BIGNUM *r, BIGNUM *a, const BIGNUM *p,
97 const BIGNUM *m, BN_CTX *ctx);
98
99/* RSA stuff */
100static int hwcrhk_rsa_mod_exp(BIGNUM *r, BIGNUM *I, RSA *rsa);
101/* This function is aliased to mod_exp (with the mont stuff dropped). */
102static int hwcrhk_mod_exp_mont(BIGNUM *r, BIGNUM *a, const BIGNUM *p,
103 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
104
105/* DH stuff */
106/* This function is alised to mod_exp (with the DH and mont dropped). */
107static int hwcrhk_mod_exp_dh(DH *dh, BIGNUM *r, BIGNUM *a, const BIGNUM *p,
108 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
109
110/* RAND stuff */
111static int hwcrhk_rand_bytes(unsigned char *buf, int num);
112static int hwcrhk_rand_status(void);
113
114/* KM stuff */
115static EVP_PKEY *hwcrhk_load_privkey(const char *key_id,
116 const char *passphrase);
117static EVP_PKEY *hwcrhk_load_pubkey(const char *key_id,
118 const char *passphrase);
119static void hwcrhk_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad,
120 int index,long argl, void *argp);
121
122/* Interaction stuff */
123static int hwcrhk_get_pass(const char *prompt_info,
124 int *len_io, char *buf,
125 HWCryptoHook_PassphraseContext *ppctx,
126 HWCryptoHook_CallerContext *cactx);
127static void hwcrhk_log_message(void *logstream, const char *message);
128
129/* Our internal RSA_METHOD that we provide pointers to */
130static RSA_METHOD hwcrhk_rsa =
131 {
132 "nCipher RSA method",
133 NULL,
134 NULL,
135 NULL,
136 NULL,
137 hwcrhk_rsa_mod_exp,
138 hwcrhk_mod_exp_mont,
139 NULL,
140 NULL,
141 0,
142 NULL,
143 NULL,
144 NULL
145 };
146
147/* Our internal DH_METHOD that we provide pointers to */
148static DH_METHOD hwcrhk_dh =
149 {
150 "nCipher DH method",
151 NULL,
152 NULL,
153 hwcrhk_mod_exp_dh,
154 NULL,
155 NULL,
156 0,
157 NULL
158 };
159
160static RAND_METHOD hwcrhk_rand =
161 {
162 /* "nCipher RAND method", */
163 NULL,
164 hwcrhk_rand_bytes,
165 NULL,
166 NULL,
167 hwcrhk_rand_bytes,
168 hwcrhk_rand_status,
169 };
170
171/* Our ENGINE structure. */
172static ENGINE engine_hwcrhk =
173 {
174 "chil",
175 "nCipher hardware engine support",
176 &hwcrhk_rsa,
177 NULL,
178 &hwcrhk_dh,
179 &hwcrhk_rand,
180 hwcrhk_mod_exp,
181 NULL,
182 hwcrhk_init,
183 hwcrhk_finish,
184 hwcrhk_ctrl,
185 hwcrhk_load_privkey,
186 hwcrhk_load_pubkey,
187 0, /* no flags */
188 0, 0, /* no references */
189 NULL, NULL /* unlinked */
190 };
191
192/* Internal stuff for HWCryptoHook */
193
194/* Some structures needed for proper use of thread locks */
195/* hwcryptohook.h has some typedefs that turn struct HWCryptoHook_MutexValue
196 into HWCryptoHook_Mutex */
197struct HWCryptoHook_MutexValue
198 {
199 int lockid;
200 };
201
202/* hwcryptohook.h has some typedefs that turn
203 struct HWCryptoHook_PassphraseContextValue
204 into HWCryptoHook_PassphraseContext */
205struct HWCryptoHook_PassphraseContextValue
206 {
207 void *any;
208 };
209
210/* hwcryptohook.h has some typedefs that turn
211 struct HWCryptoHook_CallerContextValue
212 into HWCryptoHook_CallerContext */
213struct HWCryptoHook_CallerContextValue
214 {
215 void *any;
216 };
217
218/* The MPI structure in HWCryptoHook is pretty compatible with OpenSSL
219 BIGNUM's, so lets define a couple of conversion macros */
220#define BN2MPI(mp, bn) \
221 {mp.size = bn->top * sizeof(BN_ULONG); mp.buf = (unsigned char *)bn->d;}
222#define MPI2BN(bn, mp) \
223 {mp.size = bn->dmax * sizeof(BN_ULONG); mp.buf = (unsigned char *)bn->d;}
224
225#if 0 /* Card and password management is not yet supported */
226/* HWCryptoHook callbacks. insert_card() and get_pass() are not yet
227 defined, because we haven't quite decided on the proper form yet.
228 log_message() just adds an entry in the error stack. I don't know
229 if that's good or bad... */
230static int insert_card(const char *prompt_info,
231 const char *wrong_info,
232 HWCryptoHook_PassphraseContext *ppctx,
233 HWCryptoHook_CallerContext *cactx);
234static int get_pass(const char *prompt_info,
235 int *len_io, char *buf,
236 HWCryptoHook_PassphraseContext *ppctx,
237 HWCryptoHook_CallerContext *cactx);
238#endif
239
240static BIO *logstream = NULL;
241static pem_password_cb *password_callback = NULL;
242#if 0
243static void *password_callback_userdata = NULL;
244#endif
245static int disable_mutex_callbacks = 0;
246
247/* Stuff to pass to the HWCryptoHook library */
248static HWCryptoHook_InitInfo hwcrhk_globals = {
249 0, /* Flags */
250 &logstream, /* logstream */
251 sizeof(BN_ULONG), /* limbsize */
252 0, /* mslimb first: false for BNs */
253 -1, /* msbyte first: use native */
254 0, /* Max mutexes, 0 = no small limit */
255 0, /* Max simultaneous, 0 = default */
256
257 /* The next few are mutex stuff: we write wrapper functions
258 around the OS mutex functions. We initialise them to 0
259 here, and change that to actual function pointers in hwcrhk_init()
260 if dynamic locks are supported (that is, if the application
261 programmer has made sure of setting up callbacks bafore starting
262 this engine) *and* if disable_mutex_callbacks hasn't been set by
263 a call to ENGINE_ctrl(ENGINE_CTRL_CHIL_NO_LOCKING). */
264 sizeof(HWCryptoHook_Mutex),
265 0,
266 0,
267 0,
268 0,
269
270 /* The next few are condvar stuff: we write wrapper functions
271 round the OS functions. Currently not implemented and not
272 and absolute necessity even in threaded programs, therefore
273 0'ed. Will hopefully be implemented some day, since it
274 enhances the efficiency of HWCryptoHook. */
275 0, /* sizeof(HWCryptoHook_CondVar), */
276 0, /* hwcrhk_cv_init, */
277 0, /* hwcrhk_cv_wait, */
278 0, /* hwcrhk_cv_signal, */
279 0, /* hwcrhk_cv_broadcast, */
280 0, /* hwcrhk_cv_destroy, */
281
282 hwcrhk_get_pass, /* pass phrase */
283 0, /* insert_card, */ /* insert a card */
284 hwcrhk_log_message /* Log message */
285};
286
287
288/* Now, to our own code */
289
290/* As this is only ever called once, there's no need for locking
291 * (indeed - the lock will already be held by our caller!!!) */
292ENGINE *ENGINE_ncipher()
293 {
294 RSA_METHOD *meth1;
295 DH_METHOD *meth2;
296
297 /* We know that the "PKCS1_SSLeay()" functions hook properly
298 * to the cswift-specific mod_exp and mod_exp_crt so we use
299 * those functions. NB: We don't use ENGINE_openssl() or
300 * anything "more generic" because something like the RSAref
301 * code may not hook properly, and if you own one of these
302 * cards then you have the right to do RSA operations on it
303 * anyway! */
304 meth1 = RSA_PKCS1_SSLeay();
305 hwcrhk_rsa.rsa_pub_enc = meth1->rsa_pub_enc;
306 hwcrhk_rsa.rsa_pub_dec = meth1->rsa_pub_dec;
307 hwcrhk_rsa.rsa_priv_enc = meth1->rsa_priv_enc;
308 hwcrhk_rsa.rsa_priv_dec = meth1->rsa_priv_dec;
309
310 /* Much the same for Diffie-Hellman */
311 meth2 = DH_OpenSSL();
312 hwcrhk_dh.generate_key = meth2->generate_key;
313 hwcrhk_dh.compute_key = meth2->compute_key;
314 return &engine_hwcrhk;
315 }
316
317/* This is a process-global DSO handle used for loading and unloading
318 * the HWCryptoHook library. NB: This is only set (or unset) during an
319 * init() or finish() call (reference counts permitting) and they're
320 * operating with global locks, so this should be thread-safe
321 * implicitly. */
322static DSO *hwcrhk_dso = NULL;
323static HWCryptoHook_ContextHandle hwcrhk_context = 0;
324static int hndidx = -1; /* Index for KM handle. Not really used yet. */
325
326/* These are the function pointers that are (un)set when the library has
327 * successfully (un)loaded. */
328static HWCryptoHook_Init_t *p_hwcrhk_Init = NULL;
329static HWCryptoHook_Finish_t *p_hwcrhk_Finish = NULL;
330static HWCryptoHook_ModExp_t *p_hwcrhk_ModExp = NULL;
331static HWCryptoHook_RSA_t *p_hwcrhk_RSA = NULL;
332static HWCryptoHook_RandomBytes_t *p_hwcrhk_RandomBytes = NULL;
333static HWCryptoHook_RSALoadKey_t *p_hwcrhk_RSALoadKey = NULL;
334static HWCryptoHook_RSAGetPublicKey_t *p_hwcrhk_RSAGetPublicKey = NULL;
335static HWCryptoHook_RSAUnloadKey_t *p_hwcrhk_RSAUnloadKey = NULL;
336static HWCryptoHook_ModExpCRT_t *p_hwcrhk_ModExpCRT = NULL;
337
338/* Used in the DSO operations. */
339static const char *HWCRHK_LIBNAME = "nfhwcrhk";
340static const char *n_hwcrhk_Init = "HWCryptoHook_Init";
341static const char *n_hwcrhk_Finish = "HWCryptoHook_Finish";
342static const char *n_hwcrhk_ModExp = "HWCryptoHook_ModExp";
343static const char *n_hwcrhk_RSA = "HWCryptoHook_RSA";
344static const char *n_hwcrhk_RandomBytes = "HWCryptoHook_RandomBytes";
345static const char *n_hwcrhk_RSALoadKey = "HWCryptoHook_RSALoadKey";
346static const char *n_hwcrhk_RSAGetPublicKey = "HWCryptoHook_RSAGetPublicKey";
347static const char *n_hwcrhk_RSAUnloadKey = "HWCryptoHook_RSAUnloadKey";
348static const char *n_hwcrhk_ModExpCRT = "HWCryptoHook_ModExpCRT";
349
350/* HWCryptoHook library functions and mechanics - these are used by the
351 * higher-level functions further down. NB: As and where there's no
352 * error checking, take a look lower down where these functions are
353 * called, the checking and error handling is probably down there. */
354
355/* utility function to obtain a context */
356static int get_context(HWCryptoHook_ContextHandle *hac)
357 {
358 char tempbuf[1024];
359 HWCryptoHook_ErrMsgBuf rmsg;
360
361 rmsg.buf = tempbuf;
362 rmsg.size = 1024;
363
364 *hac = p_hwcrhk_Init(&hwcrhk_globals, sizeof(hwcrhk_globals), &rmsg,
365 NULL);
366 if (!*hac)
367 return 0;
368 return 1;
369 }
370
371/* similarly to release one. */
372static void release_context(HWCryptoHook_ContextHandle hac)
373 {
374 p_hwcrhk_Finish(hac);
375 }
376
377/* (de)initialisation functions. */
378static int hwcrhk_init()
379 {
380 HWCryptoHook_Init_t *p1;
381 HWCryptoHook_Finish_t *p2;
382 HWCryptoHook_ModExp_t *p3;
383 HWCryptoHook_RSA_t *p4;
384 HWCryptoHook_RSALoadKey_t *p5;
385 HWCryptoHook_RSAGetPublicKey_t *p6;
386 HWCryptoHook_RSAUnloadKey_t *p7;
387 HWCryptoHook_RandomBytes_t *p8;
388 HWCryptoHook_ModExpCRT_t *p9;
389
390 if(hwcrhk_dso != NULL)
391 {
392 ENGINEerr(ENGINE_F_HWCRHK_INIT,ENGINE_R_ALREADY_LOADED);
393 goto err;
394 }
395 /* Attempt to load libnfhwcrhk.so/nfhwcrhk.dll/whatever. */
396 hwcrhk_dso = DSO_load(NULL, HWCRHK_LIBNAME, NULL,
397 DSO_FLAG_NAME_TRANSLATION);
398 if(hwcrhk_dso == NULL)
399 {
400 ENGINEerr(ENGINE_F_HWCRHK_INIT,ENGINE_R_DSO_FAILURE);
401 goto err;
402 }
403 if(!(p1 = (HWCryptoHook_Init_t *)
404 DSO_bind_func(hwcrhk_dso, n_hwcrhk_Init)) ||
405 !(p2 = (HWCryptoHook_Finish_t *)
406 DSO_bind_func(hwcrhk_dso, n_hwcrhk_Finish)) ||
407 !(p3 = (HWCryptoHook_ModExp_t *)
408 DSO_bind_func(hwcrhk_dso, n_hwcrhk_ModExp)) ||
409 !(p4 = (HWCryptoHook_RSA_t *)
410 DSO_bind_func(hwcrhk_dso, n_hwcrhk_RSA)) ||
411 !(p5 = (HWCryptoHook_RSALoadKey_t *)
412 DSO_bind_func(hwcrhk_dso, n_hwcrhk_RSALoadKey)) ||
413 !(p6 = (HWCryptoHook_RSAGetPublicKey_t *)
414 DSO_bind_func(hwcrhk_dso, n_hwcrhk_RSAGetPublicKey)) ||
415 !(p7 = (HWCryptoHook_RSAUnloadKey_t *)
416 DSO_bind_func(hwcrhk_dso, n_hwcrhk_RSAUnloadKey)) ||
417 !(p8 = (HWCryptoHook_RandomBytes_t *)
418 DSO_bind_func(hwcrhk_dso, n_hwcrhk_RandomBytes)) ||
419 !(p9 = (HWCryptoHook_ModExpCRT_t *)
420 DSO_bind_func(hwcrhk_dso, n_hwcrhk_ModExpCRT)))
421 {
422 ENGINEerr(ENGINE_F_HWCRHK_INIT,ENGINE_R_DSO_FAILURE);
423 goto err;
424 }
425 /* Copy the pointers */
426 p_hwcrhk_Init = p1;
427 p_hwcrhk_Finish = p2;
428 p_hwcrhk_ModExp = p3;
429 p_hwcrhk_RSA = p4;
430 p_hwcrhk_RSALoadKey = p5;
431 p_hwcrhk_RSAGetPublicKey = p6;
432 p_hwcrhk_RSAUnloadKey = p7;
433 p_hwcrhk_RandomBytes = p8;
434 p_hwcrhk_ModExpCRT = p9;
435
436 /* Check if the application decided to support dynamic locks,
437 and if it does, use them. */
438 if (disable_mutex_callbacks == 0 &&
439 CRYPTO_get_dynlock_create_callback() != NULL &&
440 CRYPTO_get_dynlock_lock_callback() != NULL &&
441 CRYPTO_get_dynlock_destroy_callback() != NULL)
442 {
443 hwcrhk_globals.mutex_init = hwcrhk_mutex_init;
444 hwcrhk_globals.mutex_acquire = hwcrhk_mutex_lock;
445 hwcrhk_globals.mutex_release = hwcrhk_mutex_unlock;
446 hwcrhk_globals.mutex_destroy = hwcrhk_mutex_destroy;
447 }
448
449 /* Try and get a context - if not, we may have a DSO but no
450 * accelerator! */
451 if(!get_context(&hwcrhk_context))
452 {
453 ENGINEerr(ENGINE_F_HWCRHK_INIT,ENGINE_R_UNIT_FAILURE);
454 goto err;
455 }
456 /* Everything's fine. */
457 if (hndidx == -1)
458 hndidx = RSA_get_ex_new_index(0,
459 "nFast HWCryptoHook RSA key handle",
460 NULL, NULL, hwcrhk_ex_free);
461 return 1;
462err:
463 if(hwcrhk_dso)
464 DSO_free(hwcrhk_dso);
465 hwcrhk_dso = NULL;
466 p_hwcrhk_Init = NULL;
467 p_hwcrhk_Finish = NULL;
468 p_hwcrhk_ModExp = NULL;
469 p_hwcrhk_RSA = NULL;
470 p_hwcrhk_RSALoadKey = NULL;
471 p_hwcrhk_RSAGetPublicKey = NULL;
472 p_hwcrhk_RSAUnloadKey = NULL;
473 p_hwcrhk_ModExpCRT = NULL;
474 p_hwcrhk_RandomBytes = NULL;
475 return 0;
476 }
477
478static int hwcrhk_finish()
479 {
480 int to_return = 1;
481 if(hwcrhk_dso == NULL)
482 {
483 ENGINEerr(ENGINE_F_HWCRHK_FINISH,ENGINE_R_NOT_LOADED);
484 to_return = 0;
485 goto err;
486 }
487 release_context(hwcrhk_context);
488 if(!DSO_free(hwcrhk_dso))
489 {
490 ENGINEerr(ENGINE_F_HWCRHK_FINISH,ENGINE_R_DSO_FAILURE);
491 to_return = 0;
492 goto err;
493 }
494 err:
495 if (logstream)
496 BIO_free(logstream);
497 hwcrhk_dso = NULL;
498 p_hwcrhk_Init = NULL;
499 p_hwcrhk_Finish = NULL;
500 p_hwcrhk_ModExp = NULL;
501 p_hwcrhk_RSA = NULL;
502 p_hwcrhk_RSALoadKey = NULL;
503 p_hwcrhk_RSAGetPublicKey = NULL;
504 p_hwcrhk_RSAUnloadKey = NULL;
505 p_hwcrhk_ModExpCRT = NULL;
506 p_hwcrhk_RandomBytes = NULL;
507 return to_return;
508 }
509
510static int hwcrhk_ctrl(int cmd, long i, void *p, void (*f)())
511 {
512 int to_return = 1;
513
514 switch(cmd)
515 {
516 case ENGINE_CTRL_SET_LOGSTREAM:
517 {
518 BIO *bio = (BIO *)p;
519
520 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
521 if (logstream)
522 {
523 BIO_free(logstream);
524 logstream = NULL;
525 }
526 if (CRYPTO_add(&bio->references,1,CRYPTO_LOCK_BIO) > 1)
527 logstream = bio;
528 else
529 ENGINEerr(ENGINE_F_HWCRHK_CTRL,ENGINE_R_BIO_WAS_FREED);
530 }
531 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
532 break;
533 case ENGINE_CTRL_SET_PASSWORD_CALLBACK:
534 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
535 password_callback = (pem_password_cb *)f;
536 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
537 break;
538 /* this enables or disables the "SimpleForkCheck" flag used in the
539 * initialisation structure. */
540 case ENGINE_CTRL_CHIL_SET_FORKCHECK:
541 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
542 if(i)
543 hwcrhk_globals.flags |=
544 HWCryptoHook_InitFlags_SimpleForkCheck;
545 else
546 hwcrhk_globals.flags &=
547 ~HWCryptoHook_InitFlags_SimpleForkCheck;
548 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
549 break;
550 /* This will prevent the initialisation function from "installing"
551 * the mutex-handling callbacks, even if they are available from
552 * within the library (or were provided to the library from the
553 * calling application). This is to remove any baggage for
554 * applications not using multithreading. */
555 case ENGINE_CTRL_CHIL_NO_LOCKING:
556 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
557 disable_mutex_callbacks = 1;
558 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
559 break;
560
561 /* The command isn't understood by this engine */
562 default:
563 ENGINEerr(ENGINE_F_HWCRHK_CTRL,
564 ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED);
565 to_return = 0;
566 break;
567 }
568
569 return to_return;
570 }
571
572static EVP_PKEY *hwcrhk_load_privkey(const char *key_id,
573 const char *passphrase)
574 {
575 RSA *rtmp = NULL;
576 EVP_PKEY *res = NULL;
577 HWCryptoHook_MPI e, n;
578 HWCryptoHook_RSAKeyHandle *hptr;
579 HWCryptoHook_ErrMsgBuf rmsg;
580
581 if(!hwcrhk_context)
582 {
583 ENGINEerr(ENGINE_F_HWCRHK_LOAD_PRIVKEY,
584 ENGINE_R_NOT_INITIALISED);
585 goto err;
586 }
587 hptr = OPENSSL_malloc(sizeof(HWCryptoHook_RSAKeyHandle));
588 if (!hptr)
589 {
590 ENGINEerr(ENGINE_F_HWCRHK_LOAD_PRIVKEY,
591 ERR_R_MALLOC_FAILURE);
592 goto err;
593 }
594 if (p_hwcrhk_RSALoadKey(hwcrhk_context, key_id, hptr,
595 &rmsg, NULL))
596 {
597 ENGINEerr(ENGINE_F_HWCRHK_LOAD_PRIVKEY,
598 ENGINE_R_CHIL_ERROR);
599 ERR_add_error_data(1,rmsg.buf);
600 goto err;
601 }
602 if (!*hptr)
603 {
604 ENGINEerr(ENGINE_F_HWCRHK_LOAD_PRIVKEY,
605 ENGINE_R_NO_KEY);
606 goto err;
607 }
608 rtmp = RSA_new_method(&engine_hwcrhk);
609 RSA_set_ex_data(rtmp, hndidx, (char *)hptr);
610 rtmp->e = BN_new();
611 rtmp->n = BN_new();
612 rtmp->flags |= RSA_FLAG_EXT_PKEY;
613 MPI2BN(rtmp->e, e);
614 MPI2BN(rtmp->n, n);
615 if (p_hwcrhk_RSAGetPublicKey(*hptr, &n, &e, &rmsg)
616 != HWCRYPTOHOOK_ERROR_MPISIZE)
617 {
618 ENGINEerr(ENGINE_F_HWCRHK_LOAD_PUBKEY,ENGINE_R_CHIL_ERROR);
619 ERR_add_error_data(1,rmsg.buf);
620 goto err;
621 }
622
623 bn_expand2(rtmp->e, e.size/sizeof(BN_ULONG));
624 bn_expand2(rtmp->n, n.size/sizeof(BN_ULONG));
625 MPI2BN(rtmp->e, e);
626 MPI2BN(rtmp->n, n);
627
628 if (p_hwcrhk_RSAGetPublicKey(*hptr, &n, &e, &rmsg))
629 {
630 ENGINEerr(ENGINE_F_HWCRHK_LOAD_PUBKEY,
631 ENGINE_R_CHIL_ERROR);
632 ERR_add_error_data(1,rmsg.buf);
633 goto err;
634 }
635 rtmp->e->top = e.size / sizeof(BN_ULONG);
636 bn_fix_top(rtmp->e);
637 rtmp->n->top = n.size / sizeof(BN_ULONG);
638 bn_fix_top(rtmp->n);
639
640 res = EVP_PKEY_new();
641 EVP_PKEY_assign_RSA(res, rtmp);
642
643 return res;
644 err:
645 if (res)
646 EVP_PKEY_free(res);
647 if (rtmp)
648 RSA_free(rtmp);
649 return NULL;
650 }
651
652static EVP_PKEY *hwcrhk_load_pubkey(const char *key_id, const char *passphrase)
653 {
654 EVP_PKEY *res = hwcrhk_load_privkey(key_id, passphrase);
655
656 if (res)
657 switch(res->type)
658 {
659 case EVP_PKEY_RSA:
660 {
661 RSA *rsa = NULL;
662
663 CRYPTO_w_lock(CRYPTO_LOCK_EVP_PKEY);
664 rsa = res->pkey.rsa;
665 res->pkey.rsa = RSA_new();
666 res->pkey.rsa->n = rsa->n;
667 res->pkey.rsa->e = rsa->e;
668 CRYPTO_w_unlock(CRYPTO_LOCK_EVP_PKEY);
669 RSA_free(rsa);
670 }
671 default:
672 ENGINEerr(ENGINE_F_HWCRHK_LOAD_PUBKEY,
673 ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED);
674 goto err;
675 }
676
677 return res;
678 err:
679 if (res)
680 EVP_PKEY_free(res);
681 return NULL;
682 }
683
684/* A little mod_exp */
685static int hwcrhk_mod_exp(BIGNUM *r, BIGNUM *a, const BIGNUM *p,
686 const BIGNUM *m, BN_CTX *ctx)
687 {
688 char tempbuf[1024];
689 HWCryptoHook_ErrMsgBuf rmsg;
690 /* Since HWCryptoHook_MPI is pretty compatible with BIGNUM's,
691 we use them directly, plus a little macro magic. We only
692 thing we need to make sure of is that enough space is allocated. */
693 HWCryptoHook_MPI m_a, m_p, m_n, m_r;
694 int to_return, ret;
695
696 to_return = 0; /* expect failure */
697 rmsg.buf = tempbuf;
698 rmsg.size = 1024;
699
700 if(!hwcrhk_context)
701 {
702 ENGINEerr(ENGINE_F_HWCRHK_MOD_EXP,ENGINE_R_NOT_INITIALISED);
703 goto err;
704 }
705 /* Prepare the params */
706 bn_expand2(r, m->top); /* Check for error !! */
707 BN2MPI(m_a, a);
708 BN2MPI(m_p, p);
709 BN2MPI(m_n, m);
710 MPI2BN(r, m_r);
711
712 /* Perform the operation */
713 ret = p_hwcrhk_ModExp(hwcrhk_context, m_a, m_p, m_n, &m_r, &rmsg);
714
715 /* Convert the response */
716 r->top = m_r.size / sizeof(BN_ULONG);
717 bn_fix_top(r);
718
719 if (ret < 0)
720 {
721 /* FIXME: When this error is returned, HWCryptoHook is
722 telling us that falling back to software computation
723 might be a good thing. */
724 if(ret == HWCRYPTOHOOK_ERROR_FALLBACK)
725 {
726 ENGINEerr(ENGINE_F_HWCRHK_MOD_EXP,ENGINE_R_REQUEST_FALLBACK);
727 }
728 else
729 {
730 ENGINEerr(ENGINE_F_HWCRHK_MOD_EXP,ENGINE_R_REQUEST_FAILED);
731 }
732 ERR_add_error_data(1,rmsg.buf);
733 goto err;
734 }
735
736 to_return = 1;
737err:
738 return to_return;
739 }
740
741static int hwcrhk_rsa_mod_exp(BIGNUM *r, BIGNUM *I, RSA *rsa)
742 {
743 char tempbuf[1024];
744 HWCryptoHook_ErrMsgBuf rmsg;
745 HWCryptoHook_RSAKeyHandle *hptr;
746 int to_return = 0, ret;
747
748 if(!hwcrhk_context)
749 {
750 ENGINEerr(ENGINE_F_HWCRHK_MOD_EXP,ENGINE_R_NOT_INITIALISED);
751 goto err;
752 }
753
754 /* This provides support for nForce keys. Since that's opaque data
755 all we do is provide a handle to the proper key and let HWCryptoHook
756 take care of the rest. */
757 if ((hptr = (HWCryptoHook_RSAKeyHandle *) RSA_get_ex_data(rsa, hndidx))
758 != NULL)
759 {
760 HWCryptoHook_MPI m_a, m_r;
761
762 if(!rsa->n)
763 {
764 ENGINEerr(ENGINE_F_HWCRHK_RSA_MOD_EXP,
765 ENGINE_R_MISSING_KEY_COMPONENTS);
766 goto err;
767 }
768
769 rmsg.buf = tempbuf;
770 rmsg.size = 1024;
771
772 /* Prepare the params */
773 bn_expand2(r, rsa->n->top); /* Check for error !! */
774 BN2MPI(m_a, I);
775 MPI2BN(r, m_r);
776
777 /* Perform the operation */
778 ret = p_hwcrhk_RSA(m_a, *hptr, &m_r, &rmsg);
779
780 /* Convert the response */
781 r->top = m_r.size / sizeof(BN_ULONG);
782 bn_fix_top(r);
783
784 if (ret < 0)
785 {
786 /* FIXME: When this error is returned, HWCryptoHook is
787 telling us that falling back to software computation
788 might be a good thing. */
789 if(ret == HWCRYPTOHOOK_ERROR_FALLBACK)
790 {
791 ENGINEerr(ENGINE_F_HWCRHK_RSA_MOD_EXP,ENGINE_R_REQUEST_FALLBACK);
792 }
793 else
794 {
795 ENGINEerr(ENGINE_F_HWCRHK_RSA_MOD_EXP,ENGINE_R_REQUEST_FAILED);
796 }
797 ERR_add_error_data(1,rmsg.buf);
798 goto err;
799 }
800 }
801 else
802 {
803 HWCryptoHook_MPI m_a, m_p, m_q, m_dmp1, m_dmq1, m_iqmp, m_r;
804
805 if(!rsa->p || !rsa->q || !rsa->dmp1 || !rsa->dmq1 || !rsa->iqmp)
806 {
807 ENGINEerr(ENGINE_F_HWCRHK_RSA_MOD_EXP,
808 ENGINE_R_MISSING_KEY_COMPONENTS);
809 goto err;
810 }
811
812 rmsg.buf = tempbuf;
813 rmsg.size = 1024;
814
815 /* Prepare the params */
816 bn_expand2(r, rsa->n->top); /* Check for error !! */
817 BN2MPI(m_a, I);
818 BN2MPI(m_p, rsa->p);
819 BN2MPI(m_q, rsa->q);
820 BN2MPI(m_dmp1, rsa->dmp1);
821 BN2MPI(m_dmq1, rsa->dmq1);
822 BN2MPI(m_iqmp, rsa->iqmp);
823 MPI2BN(r, m_r);
824
825 /* Perform the operation */
826 ret = p_hwcrhk_ModExpCRT(hwcrhk_context, m_a, m_p, m_q,
827 m_dmp1, m_dmq1, m_iqmp, &m_r, NULL);
828
829 /* Convert the response */
830 r->top = m_r.size / sizeof(BN_ULONG);
831 bn_fix_top(r);
832
833 if (ret < 0)
834 {
835 /* FIXME: When this error is returned, HWCryptoHook is
836 telling us that falling back to software computation
837 might be a good thing. */
838 if(ret == HWCRYPTOHOOK_ERROR_FALLBACK)
839 {
840 ENGINEerr(ENGINE_F_HWCRHK_RSA_MOD_EXP,ENGINE_R_REQUEST_FALLBACK);
841 }
842 else
843 {
844 ENGINEerr(ENGINE_F_HWCRHK_RSA_MOD_EXP,ENGINE_R_REQUEST_FAILED);
845 }
846 ERR_add_error_data(1,rmsg.buf);
847 goto err;
848 }
849 }
850 /* If we're here, we must be here with some semblance of success :-) */
851 to_return = 1;
852err:
853 return to_return;
854 }
855
856/* This function is aliased to mod_exp (with the mont stuff dropped). */
857static int hwcrhk_mod_exp_mont(BIGNUM *r, BIGNUM *a, const BIGNUM *p,
858 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
859 {
860 return hwcrhk_mod_exp(r, a, p, m, ctx);
861 }
862
863/* This function is aliased to mod_exp (with the dh and mont dropped). */
864static int hwcrhk_mod_exp_dh(DH *dh, BIGNUM *r, BIGNUM *a, const BIGNUM *p,
865 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
866 {
867 return hwcrhk_mod_exp(r, a, p, m, ctx);
868 }
869
870/* Random bytes are good */
871static int hwcrhk_rand_bytes(unsigned char *buf, int num)
872 {
873 char tempbuf[1024];
874 HWCryptoHook_ErrMsgBuf rmsg;
875 int to_return = 0; /* assume failure */
876 int ret;
877
878 rmsg.buf = tempbuf;
879 rmsg.size = 1024;
880
881 if(!hwcrhk_context)
882 {
883 ENGINEerr(ENGINE_F_HWCRHK_RAND_BYTES,ENGINE_R_NOT_INITIALISED);
884 goto err;
885 }
886
887 ret = p_hwcrhk_RandomBytes(hwcrhk_context, buf, num, &rmsg);
888 if (ret < 0)
889 {
890 /* FIXME: When this error is returned, HWCryptoHook is
891 telling us that falling back to software computation
892 might be a good thing. */
893 if(ret == HWCRYPTOHOOK_ERROR_FALLBACK)
894 {
895 ENGINEerr(ENGINE_F_HWCRHK_RAND_BYTES,ENGINE_R_REQUEST_FALLBACK);
896 }
897 else
898 {
899 ENGINEerr(ENGINE_F_HWCRHK_RAND_BYTES,ENGINE_R_REQUEST_FAILED);
900 }
901 ERR_add_error_data(1,rmsg.buf);
902 goto err;
903 }
904 to_return = 1;
905 err:
906 return to_return;
907 }
908
909static int hwcrhk_rand_status(void)
910 {
911 return 1;
912 }
913
914/* This cleans up an RSA KM key, called when ex_data is freed */
915
916static void hwcrhk_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad,
917 int index,long argl, void *argp)
918{
919 char tempbuf[1024];
920 HWCryptoHook_ErrMsgBuf rmsg;
921 HWCryptoHook_RSAKeyHandle *hptr;
922 int ret;
923
924 rmsg.buf = tempbuf;
925 rmsg.size = 1024;
926
927 hptr = (HWCryptoHook_RSAKeyHandle *) item;
928 if(!hptr) return;
929 ret = p_hwcrhk_RSAUnloadKey(*hptr, NULL);
930 OPENSSL_free(hptr);
931}
932
933/* Mutex calls: since the HWCryptoHook model closely follows the POSIX model
934 * these just wrap the POSIX functions and add some logging.
935 */
936
937static int hwcrhk_mutex_init(HWCryptoHook_Mutex* mt,
938 HWCryptoHook_CallerContext *cactx)
939 {
940 mt->lockid = CRYPTO_get_new_dynlockid();
941 if (mt->lockid == 0)
942 return 0;
943 return 1;
944 }
945
946static int hwcrhk_mutex_lock(HWCryptoHook_Mutex *mt)
947 {
948 CRYPTO_w_lock(mt->lockid);
949 return 1;
950 }
951
952void hwcrhk_mutex_unlock(HWCryptoHook_Mutex * mt)
953 {
954 CRYPTO_w_unlock(mt->lockid);
955 }
956
957static void hwcrhk_mutex_destroy(HWCryptoHook_Mutex *mt)
958 {
959 CRYPTO_destroy_dynlockid(mt->lockid);
960 }
961
962static int hwcrhk_get_pass(const char *prompt_info,
963 int *len_io, char *buf,
964 HWCryptoHook_PassphraseContext *ppctx,
965 HWCryptoHook_CallerContext *cactx)
966 {
967 int l = 0;
968 char prompt[1024];
969
970 if (password_callback == NULL)
971 {
972 ENGINEerr(ENGINE_F_HWCRHK_GET_PASS,ENGINE_R_NO_CALLBACK);
973 return -1;
974 }
975 if (prompt_info)
976 {
977 strncpy(prompt, "Card: \"", sizeof(prompt));
978 l += 5;
979 strncpy(prompt + l, prompt_info, sizeof(prompt) - l);
980 l += strlen(prompt_info);
981 if (l + 2 < sizeof(prompt))
982 {
983 strncpy(prompt + l, "\"\n", sizeof(prompt) - l);
984 l += 2;
985 }
986 }
987 if (l < sizeof(prompt) - 1)
988 {
989 strncpy(prompt, "Enter Passphrase <enter to cancel>:",
990 sizeof(prompt) - l);
991 l += 35;
992 }
993 prompt[l] = '\0';
994
995 /* I know, passing on the prompt instead of the user data *is*
996 a bad thing. However, that's all we have right now.
997 -- Richard Levitte */
998 *len_io = password_callback(buf, *len_io, 0, prompt);
999 if(!*len_io)
1000 return -1;
1001 return 0;
1002 }
1003
1004static void hwcrhk_log_message(void *logstream, const char *message)
1005 {
1006 BIO *lstream = NULL;
1007
1008 CRYPTO_w_lock(CRYPTO_LOCK_BIO);
1009 if (logstream)
1010 lstream=*(BIO **)logstream;
1011 if (lstream)
1012 {
1013 BIO_write(lstream, message, strlen(message));
1014 }
1015 CRYPTO_w_unlock(CRYPTO_LOCK_BIO);
1016 }
1017
1018#endif /* !NO_HW_NCIPHER */
1019#endif /* !NO_HW */
diff --git a/src/lib/libcrypto/engine/hw_ncipher_err.c b/src/lib/libcrypto/engine/hw_ncipher_err.c
new file mode 100644
index 0000000000..24024cfc6f
--- /dev/null
+++ b/src/lib/libcrypto/engine/hw_ncipher_err.c
@@ -0,0 +1,156 @@
1/* hw_ncipher_err.c */
2/* ====================================================================
3 * Copyright (c) 1999 The OpenSSL Project. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
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
15 * distribution.
16 *
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/)"
21 *
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 * openssl-core@OpenSSL.org.
26 *
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.
30 *
31 * 6. Redistributions of any form whatsoever must retain the following
32 * acknowledgment:
33 * "This product includes software developed by the OpenSSL Project
34 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
35 *
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 * ====================================================================
49 *
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).
53 *
54 */
55
56/* NOTE: this file was auto generated by the mkerr.pl script: any changes
57 * made to it will be overwritten when the script next updates this file,
58 * only reason strings will be preserved.
59 */
60
61#include <stdio.h>
62#include <openssl/err.h>
63#include "hw_ncipher_err.h"
64
65/* BEGIN ERROR CODES */
66#ifndef OPENSSL_NO_ERR
67static ERR_STRING_DATA HWCRHK_str_functs[]=
68 {
69{ERR_PACK(0,HWCRHK_F_HWCRHK_CTRL,0), "HWCRHK_CTRL"},
70{ERR_PACK(0,HWCRHK_F_HWCRHK_FINISH,0), "HWCRHK_FINISH"},
71{ERR_PACK(0,HWCRHK_F_HWCRHK_GET_PASS,0), "HWCRHK_GET_PASS"},
72{ERR_PACK(0,HWCRHK_F_HWCRHK_INIT,0), "HWCRHK_INIT"},
73{ERR_PACK(0,HWCRHK_F_HWCRHK_INSERT_CARD,0), "HWCRHK_INSERT_CARD"},
74{ERR_PACK(0,HWCRHK_F_HWCRHK_LOAD_PRIVKEY,0), "HWCRHK_LOAD_PRIVKEY"},
75{ERR_PACK(0,HWCRHK_F_HWCRHK_LOAD_PUBKEY,0), "HWCRHK_LOAD_PUBKEY"},
76{ERR_PACK(0,HWCRHK_F_HWCRHK_MOD_EXP,0), "HWCRHK_MOD_EXP"},
77{ERR_PACK(0,HWCRHK_F_HWCRHK_RAND_BYTES,0), "HWCRHK_RAND_BYTES"},
78{ERR_PACK(0,HWCRHK_F_HWCRHK_RSA_MOD_EXP,0), "HWCRHK_RSA_MOD_EXP"},
79{0,NULL}
80 };
81
82static ERR_STRING_DATA HWCRHK_str_reasons[]=
83 {
84{HWCRHK_R_ALREADY_LOADED ,"already loaded"},
85{HWCRHK_R_BIO_WAS_FREED ,"bio was freed"},
86{HWCRHK_R_CHIL_ERROR ,"chil error"},
87{HWCRHK_R_CTRL_COMMAND_NOT_IMPLEMENTED ,"ctrl command not implemented"},
88{HWCRHK_R_DSO_FAILURE ,"dso failure"},
89{HWCRHK_R_MISSING_KEY_COMPONENTS ,"missing key components"},
90{HWCRHK_R_NOT_INITIALISED ,"not initialised"},
91{HWCRHK_R_NOT_LOADED ,"not loaded"},
92{HWCRHK_R_NO_CALLBACK ,"no callback"},
93{HWCRHK_R_NO_KEY ,"no key"},
94{HWCRHK_R_PRIVATE_KEY_ALGORITHMS_DISABLED,"private key algorithms disabled"},
95{HWCRHK_R_REQUEST_FAILED ,"request failed"},
96{HWCRHK_R_REQUEST_FALLBACK ,"request fallback"},
97{HWCRHK_R_UNIT_FAILURE ,"unit failure"},
98{0,NULL}
99 };
100
101#endif
102
103#ifdef HWCRHK_LIB_NAME
104static ERR_STRING_DATA HWCRHK_lib_name[]=
105 {
106{0 ,HWCRHK_LIB_NAME},
107{0,NULL}
108 };
109#endif
110
111
112static int HWCRHK_lib_error_code=0;
113static int HWCRHK_error_init=1;
114
115static void ERR_load_HWCRHK_strings(void)
116 {
117 if (HWCRHK_lib_error_code == 0)
118 HWCRHK_lib_error_code=ERR_get_next_error_library();
119
120 if (HWCRHK_error_init)
121 {
122 HWCRHK_error_init=0;
123#ifndef OPENSSL_NO_ERR
124 ERR_load_strings(HWCRHK_lib_error_code,HWCRHK_str_functs);
125 ERR_load_strings(HWCRHK_lib_error_code,HWCRHK_str_reasons);
126#endif
127
128#ifdef HWCRHK_LIB_NAME
129 HWCRHK_lib_name->error = ERR_PACK(HWCRHK_lib_error_code,0,0);
130 ERR_load_strings(0,HWCRHK_lib_name);
131#endif
132 }
133 }
134
135static void ERR_unload_HWCRHK_strings(void)
136 {
137 if (HWCRHK_error_init == 0)
138 {
139#ifndef OPENSSL_NO_ERR
140 ERR_unload_strings(HWCRHK_lib_error_code,HWCRHK_str_functs);
141 ERR_unload_strings(HWCRHK_lib_error_code,HWCRHK_str_reasons);
142#endif
143
144#ifdef HWCRHK_LIB_NAME
145 ERR_unload_strings(0,HWCRHK_lib_name);
146#endif
147 HWCRHK_error_init=1;
148 }
149 }
150
151static void ERR_HWCRHK_error(int function, int reason, char *file, int line)
152 {
153 if (HWCRHK_lib_error_code == 0)
154 HWCRHK_lib_error_code=ERR_get_next_error_library();
155 ERR_PUT_error(HWCRHK_lib_error_code,function,reason,file,line);
156 }
diff --git a/src/lib/libcrypto/engine/hw_ncipher_err.h b/src/lib/libcrypto/engine/hw_ncipher_err.h
new file mode 100644
index 0000000000..4d65b1d470
--- /dev/null
+++ b/src/lib/libcrypto/engine/hw_ncipher_err.h
@@ -0,0 +1,100 @@
1/* ====================================================================
2 * Copyright (c) 2001 The OpenSSL Project. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in
13 * the documentation and/or other materials provided with the
14 * distribution.
15 *
16 * 3. All advertising materials mentioning features or use of this
17 * software must display the following acknowledgment:
18 * "This product includes software developed by the OpenSSL Project
19 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
20 *
21 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
22 * endorse or promote products derived from this software without
23 * prior written permission. For written permission, please contact
24 * openssl-core@openssl.org.
25 *
26 * 5. Products derived from this software may not be called "OpenSSL"
27 * nor may "OpenSSL" appear in their names without prior written
28 * permission of the OpenSSL Project.
29 *
30 * 6. Redistributions of any form whatsoever must retain the following
31 * acknowledgment:
32 * "This product includes software developed by the OpenSSL Project
33 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
34 *
35 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
36 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
37 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
38 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
39 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
41 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
42 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
43 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
44 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
45 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
46 * OF THE POSSIBILITY OF SUCH DAMAGE.
47 * ====================================================================
48 *
49 * This product includes cryptographic software written by Eric Young
50 * (eay@cryptsoft.com). This product includes software written by Tim
51 * Hudson (tjh@cryptsoft.com).
52 *
53 */
54
55#ifndef HEADER_HWCRHK_ERR_H
56#define HEADER_HWCRHK_ERR_H
57
58/* BEGIN ERROR CODES */
59/* The following lines are auto generated by the script mkerr.pl. Any changes
60 * made after this point may be overwritten when the script is next run.
61 */
62static void ERR_load_HWCRHK_strings(void);
63static void ERR_unload_HWCRHK_strings(void);
64static void ERR_HWCRHK_error(int function, int reason, char *file, int line);
65#define HWCRHKerr(f,r) ERR_HWCRHK_error((f),(r),__FILE__,__LINE__)
66
67/* Error codes for the HWCRHK functions. */
68
69/* Function codes. */
70#define HWCRHK_F_HWCRHK_CTRL 100
71#define HWCRHK_F_HWCRHK_FINISH 101
72#define HWCRHK_F_HWCRHK_GET_PASS 102
73#define HWCRHK_F_HWCRHK_INIT 103
74#define HWCRHK_F_HWCRHK_INSERT_CARD 104
75#define HWCRHK_F_HWCRHK_LOAD_PRIVKEY 105
76#define HWCRHK_F_HWCRHK_LOAD_PUBKEY 106
77#define HWCRHK_F_HWCRHK_MOD_EXP 107
78#define HWCRHK_F_HWCRHK_RAND_BYTES 108
79#define HWCRHK_F_HWCRHK_RSA_MOD_EXP 109
80
81/* Reason codes. */
82#define HWCRHK_R_ALREADY_LOADED 100
83#define HWCRHK_R_BIO_WAS_FREED 101
84#define HWCRHK_R_CHIL_ERROR 102
85#define HWCRHK_R_CTRL_COMMAND_NOT_IMPLEMENTED 103
86#define HWCRHK_R_DSO_FAILURE 104
87#define HWCRHK_R_MISSING_KEY_COMPONENTS 105
88#define HWCRHK_R_NOT_INITIALISED 106
89#define HWCRHK_R_NOT_LOADED 107
90#define HWCRHK_R_NO_CALLBACK 108
91#define HWCRHK_R_NO_KEY 109
92#define HWCRHK_R_PRIVATE_KEY_ALGORITHMS_DISABLED 110
93#define HWCRHK_R_REQUEST_FAILED 111
94#define HWCRHK_R_REQUEST_FALLBACK 112
95#define HWCRHK_R_UNIT_FAILURE 113
96
97#ifdef __cplusplus
98}
99#endif
100#endif
diff --git a/src/lib/libcrypto/engine/hw_nuron.c b/src/lib/libcrypto/engine/hw_nuron.c
new file mode 100644
index 0000000000..2672012154
--- /dev/null
+++ b/src/lib/libcrypto/engine/hw_nuron.c
@@ -0,0 +1,399 @@
1/* crypto/engine/hw_nuron.c */
2/* Written by Ben Laurie for the OpenSSL Project, leaning heavily on Geoff
3 * Thorpe's Atalla implementation.
4 */
5/* ====================================================================
6 * Copyright (c) 2000-2001 The OpenSSL Project. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * 3. All advertising materials mentioning features or use of this
21 * software must display the following acknowledgment:
22 * "This product includes software developed by the OpenSSL Project
23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24 *
25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26 * endorse or promote products derived from this software without
27 * prior written permission. For written permission, please contact
28 * licensing@OpenSSL.org.
29 *
30 * 5. Products derived from this software may not be called "OpenSSL"
31 * nor may "OpenSSL" appear in their names without prior written
32 * permission of the OpenSSL Project.
33 *
34 * 6. Redistributions of any form whatsoever must retain the following
35 * acknowledgment:
36 * "This product includes software developed by the OpenSSL Project
37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38 *
39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50 * OF THE POSSIBILITY OF SUCH DAMAGE.
51 * ====================================================================
52 *
53 * This product includes cryptographic software written by Eric Young
54 * (eay@cryptsoft.com). This product includes software written by Tim
55 * Hudson (tjh@cryptsoft.com).
56 *
57 */
58
59#include <stdio.h>
60#include <openssl/crypto.h>
61#include "cryptlib.h"
62#include <openssl/dso.h>
63#include <openssl/engine.h>
64
65
66#ifndef OPENSSL_NO_HW
67#ifndef OPENSSL_NO_HW_NURON
68
69#define NURON_LIB_NAME "nuron engine"
70#include "hw_nuron_err.c"
71
72static const char def_NURON_LIBNAME[] = "nuronssl";
73static const char *NURON_LIBNAME = def_NURON_LIBNAME;
74static const char *NURON_F1 = "nuron_mod_exp";
75
76/* The definitions for control commands specific to this engine */
77#define NURON_CMD_SO_PATH ENGINE_CMD_BASE
78static const ENGINE_CMD_DEFN nuron_cmd_defns[] = {
79 {NURON_CMD_SO_PATH,
80 "SO_PATH",
81 "Specifies the path to the 'nuronssl' shared library",
82 ENGINE_CMD_FLAG_STRING},
83 {0, NULL, NULL, 0}
84 };
85
86typedef int tfnModExp(BIGNUM *r,const BIGNUM *a,const BIGNUM *p,const BIGNUM *m);
87static tfnModExp *pfnModExp = NULL;
88
89static DSO *pvDSOHandle = NULL;
90
91static int nuron_destroy(ENGINE *e)
92 {
93 ERR_unload_NURON_strings();
94 return 1;
95 }
96
97static int nuron_init(ENGINE *e)
98 {
99 if(pvDSOHandle != NULL)
100 {
101 NURONerr(NURON_F_NURON_INIT,NURON_R_ALREADY_LOADED);
102 return 0;
103 }
104
105 pvDSOHandle = DSO_load(NULL, NURON_LIBNAME, NULL,
106 DSO_FLAG_NAME_TRANSLATION_EXT_ONLY);
107 if(!pvDSOHandle)
108 {
109 NURONerr(NURON_F_NURON_INIT,NURON_R_DSO_NOT_FOUND);
110 return 0;
111 }
112
113 pfnModExp = (tfnModExp *)DSO_bind_func(pvDSOHandle, NURON_F1);
114 if(!pfnModExp)
115 {
116 NURONerr(NURON_F_NURON_INIT,NURON_R_DSO_FUNCTION_NOT_FOUND);
117 return 0;
118 }
119
120 return 1;
121 }
122
123static int nuron_finish(ENGINE *e)
124 {
125 if(pvDSOHandle == NULL)
126 {
127 NURONerr(NURON_F_NURON_FINISH,NURON_R_NOT_LOADED);
128 return 0;
129 }
130 if(!DSO_free(pvDSOHandle))
131 {
132 NURONerr(NURON_F_NURON_FINISH,NURON_R_DSO_FAILURE);
133 return 0;
134 }
135 pvDSOHandle=NULL;
136 pfnModExp=NULL;
137 return 1;
138 }
139
140static int nuron_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)())
141 {
142 int initialised = ((pvDSOHandle == NULL) ? 0 : 1);
143 switch(cmd)
144 {
145 case NURON_CMD_SO_PATH:
146 if(p == NULL)
147 {
148 NURONerr(NURON_F_NURON_CTRL,ERR_R_PASSED_NULL_PARAMETER);
149 return 0;
150 }
151 if(initialised)
152 {
153 NURONerr(NURON_F_NURON_CTRL,NURON_R_ALREADY_LOADED);
154 return 0;
155 }
156 NURON_LIBNAME = (const char *)p;
157 return 1;
158 default:
159 break;
160 }
161 NURONerr(NURON_F_NURON_CTRL,NURON_R_CTRL_COMMAND_NOT_IMPLEMENTED);
162 return 0;
163}
164
165static int nuron_mod_exp(BIGNUM *r,const BIGNUM *a,const BIGNUM *p,
166 const BIGNUM *m,BN_CTX *ctx)
167 {
168 if(!pvDSOHandle)
169 {
170 NURONerr(NURON_F_NURON_MOD_EXP,NURON_R_NOT_LOADED);
171 return 0;
172 }
173 return pfnModExp(r,a,p,m);
174 }
175
176#ifndef OPENSSL_NO_RSA
177static int nuron_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa)
178 {
179 return nuron_mod_exp(r0,I,rsa->d,rsa->n,NULL);
180 }
181#endif
182
183#ifndef OPENSSL_NO_DSA
184/* This code was liberated and adapted from the commented-out code in
185 * dsa_ossl.c. Because of the unoptimised form of the Atalla acceleration
186 * (it doesn't have a CRT form for RSA), this function means that an
187 * Atalla system running with a DSA server certificate can handshake
188 * around 5 or 6 times faster/more than an equivalent system running with
189 * RSA. Just check out the "signs" statistics from the RSA and DSA parts
190 * of "openssl speed -engine atalla dsa1024 rsa1024". */
191static int nuron_dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1,
192 BIGNUM *p1, BIGNUM *a2, BIGNUM *p2, BIGNUM *m,
193 BN_CTX *ctx, BN_MONT_CTX *in_mont)
194 {
195 BIGNUM t;
196 int to_return = 0;
197
198 BN_init(&t);
199 /* let rr = a1 ^ p1 mod m */
200 if (!nuron_mod_exp(rr,a1,p1,m,ctx))
201 goto end;
202 /* let t = a2 ^ p2 mod m */
203 if (!nuron_mod_exp(&t,a2,p2,m,ctx))
204 goto end;
205 /* let rr = rr * t mod m */
206 if (!BN_mod_mul(rr,rr,&t,m,ctx))
207 goto end;
208 to_return = 1;
209end:
210 BN_free(&t);
211 return to_return;
212 }
213
214
215static int nuron_mod_exp_dsa(DSA *dsa, BIGNUM *r, BIGNUM *a,
216 const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
217 BN_MONT_CTX *m_ctx)
218 {
219 return nuron_mod_exp(r, a, p, m, ctx);
220 }
221#endif
222
223/* This function is aliased to mod_exp (with the mont stuff dropped). */
224static int nuron_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
225 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
226 {
227 return nuron_mod_exp(r, a, p, m, ctx);
228 }
229
230#ifndef OPENSSL_NO_DH
231/* This function is aliased to mod_exp (with the dh and mont dropped). */
232static int nuron_mod_exp_dh(const DH *dh, BIGNUM *r,
233 const BIGNUM *a, const BIGNUM *p,
234 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
235 {
236 return nuron_mod_exp(r, a, p, m, ctx);
237 }
238#endif
239
240#ifndef OPENSSL_NO_RSA
241static RSA_METHOD nuron_rsa =
242 {
243 "Nuron RSA method",
244 NULL,
245 NULL,
246 NULL,
247 NULL,
248 nuron_rsa_mod_exp,
249 nuron_mod_exp_mont,
250 NULL,
251 NULL,
252 0,
253 NULL,
254 NULL,
255 NULL
256 };
257#endif
258
259#ifndef OPENSSL_NO_DSA
260static DSA_METHOD nuron_dsa =
261 {
262 "Nuron DSA method",
263 NULL, /* dsa_do_sign */
264 NULL, /* dsa_sign_setup */
265 NULL, /* dsa_do_verify */
266 nuron_dsa_mod_exp, /* dsa_mod_exp */
267 nuron_mod_exp_dsa, /* bn_mod_exp */
268 NULL, /* init */
269 NULL, /* finish */
270 0, /* flags */
271 NULL /* app_data */
272 };
273#endif
274
275#ifndef OPENSSL_NO_DH
276static DH_METHOD nuron_dh =
277 {
278 "Nuron DH method",
279 NULL,
280 NULL,
281 nuron_mod_exp_dh,
282 NULL,
283 NULL,
284 0,
285 NULL
286 };
287#endif
288
289/* Constants used when creating the ENGINE */
290static const char *engine_nuron_id = "nuron";
291static const char *engine_nuron_name = "Nuron hardware engine support";
292
293/* This internal function is used by ENGINE_nuron() and possibly by the
294 * "dynamic" ENGINE support too */
295static int bind_helper(ENGINE *e)
296 {
297#ifndef OPENSSL_NO_RSA
298 const RSA_METHOD *meth1;
299#endif
300#ifndef OPENSSL_NO_DSA
301 const DSA_METHOD *meth2;
302#endif
303#ifndef OPENSSL_NO_DH
304 const DH_METHOD *meth3;
305#endif
306 if(!ENGINE_set_id(e, engine_nuron_id) ||
307 !ENGINE_set_name(e, engine_nuron_name) ||
308#ifndef OPENSSL_NO_RSA
309 !ENGINE_set_RSA(e, &nuron_rsa) ||
310#endif
311#ifndef OPENSSL_NO_DSA
312 !ENGINE_set_DSA(e, &nuron_dsa) ||
313#endif
314#ifndef OPENSSL_NO_DH
315 !ENGINE_set_DH(e, &nuron_dh) ||
316#endif
317 !ENGINE_set_destroy_function(e, nuron_destroy) ||
318 !ENGINE_set_init_function(e, nuron_init) ||
319 !ENGINE_set_finish_function(e, nuron_finish) ||
320 !ENGINE_set_ctrl_function(e, nuron_ctrl) ||
321 !ENGINE_set_cmd_defns(e, nuron_cmd_defns))
322 return 0;
323
324#ifndef OPENSSL_NO_RSA
325 /* We know that the "PKCS1_SSLeay()" functions hook properly
326 * to the nuron-specific mod_exp and mod_exp_crt so we use
327 * those functions. NB: We don't use ENGINE_openssl() or
328 * anything "more generic" because something like the RSAref
329 * code may not hook properly, and if you own one of these
330 * cards then you have the right to do RSA operations on it
331 * anyway! */
332 meth1=RSA_PKCS1_SSLeay();
333 nuron_rsa.rsa_pub_enc=meth1->rsa_pub_enc;
334 nuron_rsa.rsa_pub_dec=meth1->rsa_pub_dec;
335 nuron_rsa.rsa_priv_enc=meth1->rsa_priv_enc;
336 nuron_rsa.rsa_priv_dec=meth1->rsa_priv_dec;
337#endif
338
339#ifndef OPENSSL_NO_DSA
340 /* Use the DSA_OpenSSL() method and just hook the mod_exp-ish
341 * bits. */
342 meth2=DSA_OpenSSL();
343 nuron_dsa.dsa_do_sign=meth2->dsa_do_sign;
344 nuron_dsa.dsa_sign_setup=meth2->dsa_sign_setup;
345 nuron_dsa.dsa_do_verify=meth2->dsa_do_verify;
346#endif
347
348#ifndef OPENSSL_NO_DH
349 /* Much the same for Diffie-Hellman */
350 meth3=DH_OpenSSL();
351 nuron_dh.generate_key=meth3->generate_key;
352 nuron_dh.compute_key=meth3->compute_key;
353#endif
354
355 /* Ensure the nuron error handling is set up */
356 ERR_load_NURON_strings();
357 return 1;
358 }
359
360static ENGINE *engine_nuron(void)
361 {
362 ENGINE *ret = ENGINE_new();
363 if(!ret)
364 return NULL;
365 if(!bind_helper(ret))
366 {
367 ENGINE_free(ret);
368 return NULL;
369 }
370 return ret;
371 }
372
373void ENGINE_load_nuron(void)
374 {
375 /* Copied from eng_[openssl|dyn].c */
376 ENGINE *toadd = engine_nuron();
377 if(!toadd) return;
378 ENGINE_add(toadd);
379 ENGINE_free(toadd);
380 ERR_clear_error();
381 }
382
383/* This stuff is needed if this ENGINE is being compiled into a self-contained
384 * shared-library. */
385#ifdef ENGINE_DYNAMIC_SUPPORT
386static int bind_fn(ENGINE *e, const char *id)
387 {
388 if(id && (strcmp(id, engine_nuron_id) != 0))
389 return 0;
390 if(!bind_helper(e))
391 return 0;
392 return 1;
393 }
394IMPLEMENT_DYNAMIC_CHECK_FN()
395IMPLEMENT_DYNAMIC_BIND_FN(bind_fn)
396#endif /* ENGINE_DYNAMIC_SUPPORT */
397
398#endif /* !OPENSSL_NO_HW_NURON */
399#endif /* !OPENSSL_NO_HW */
diff --git a/src/lib/libcrypto/engine/hw_nuron_err.c b/src/lib/libcrypto/engine/hw_nuron_err.c
new file mode 100644
index 0000000000..df9d7bde76
--- /dev/null
+++ b/src/lib/libcrypto/engine/hw_nuron_err.c
@@ -0,0 +1,142 @@
1/* hw_nuron_err.c */
2/* ====================================================================
3 * Copyright (c) 1999 The OpenSSL Project. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
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
15 * distribution.
16 *
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/)"
21 *
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 * openssl-core@OpenSSL.org.
26 *
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.
30 *
31 * 6. Redistributions of any form whatsoever must retain the following
32 * acknowledgment:
33 * "This product includes software developed by the OpenSSL Project
34 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
35 *
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 * ====================================================================
49 *
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).
53 *
54 */
55
56/* NOTE: this file was auto generated by the mkerr.pl script: any changes
57 * made to it will be overwritten when the script next updates this file,
58 * only reason strings will be preserved.
59 */
60
61#include <stdio.h>
62#include <openssl/err.h>
63#include "hw_nuron_err.h"
64
65/* BEGIN ERROR CODES */
66#ifndef OPENSSL_NO_ERR
67static ERR_STRING_DATA NURON_str_functs[]=
68 {
69{ERR_PACK(0,NURON_F_NURON_CTRL,0), "NURON_CTRL"},
70{ERR_PACK(0,NURON_F_NURON_FINISH,0), "NURON_FINISH"},
71{ERR_PACK(0,NURON_F_NURON_INIT,0), "NURON_INIT"},
72{ERR_PACK(0,NURON_F_NURON_MOD_EXP,0), "NURON_MOD_EXP"},
73{0,NULL}
74 };
75
76static ERR_STRING_DATA NURON_str_reasons[]=
77 {
78{NURON_R_ALREADY_LOADED ,"already loaded"},
79{NURON_R_CTRL_COMMAND_NOT_IMPLEMENTED ,"ctrl command not implemented"},
80{NURON_R_DSO_FAILURE ,"dso failure"},
81{NURON_R_DSO_FUNCTION_NOT_FOUND ,"dso function not found"},
82{NURON_R_DSO_NOT_FOUND ,"dso not found"},
83{NURON_R_NOT_LOADED ,"not loaded"},
84{0,NULL}
85 };
86
87#endif
88
89#ifdef NURON_LIB_NAME
90static ERR_STRING_DATA NURON_lib_name[]=
91 {
92{0 ,NURON_LIB_NAME},
93{0,NULL}
94 };
95#endif
96
97
98static int NURON_lib_error_code=0;
99static int NURON_error_init=1;
100
101static void ERR_load_NURON_strings(void)
102 {
103 if (NURON_lib_error_code == 0)
104 NURON_lib_error_code=ERR_get_next_error_library();
105
106 if (NURON_error_init)
107 {
108 NURON_error_init=0;
109#ifndef OPENSSL_NO_ERR
110 ERR_load_strings(NURON_lib_error_code,NURON_str_functs);
111 ERR_load_strings(NURON_lib_error_code,NURON_str_reasons);
112#endif
113
114#ifdef NURON_LIB_NAME
115 NURON_lib_name->error = ERR_PACK(NURON_lib_error_code,0,0);
116 ERR_load_strings(0,NURON_lib_name);
117#endif
118 }
119 }
120
121static void ERR_unload_NURON_strings(void)
122 {
123 if (NURON_error_init == 0)
124 {
125#ifndef OPENSSL_NO_ERR
126 ERR_unload_strings(NURON_lib_error_code,NURON_str_functs);
127 ERR_unload_strings(NURON_lib_error_code,NURON_str_reasons);
128#endif
129
130#ifdef NURON_LIB_NAME
131 ERR_unload_strings(0,NURON_lib_name);
132#endif
133 NURON_error_init=1;
134 }
135 }
136
137static void ERR_NURON_error(int function, int reason, char *file, int line)
138 {
139 if (NURON_lib_error_code == 0)
140 NURON_lib_error_code=ERR_get_next_error_library();
141 ERR_PUT_error(NURON_lib_error_code,function,reason,file,line);
142 }
diff --git a/src/lib/libcrypto/engine/hw_nuron_err.h b/src/lib/libcrypto/engine/hw_nuron_err.h
new file mode 100644
index 0000000000..a56bfdf303
--- /dev/null
+++ b/src/lib/libcrypto/engine/hw_nuron_err.h
@@ -0,0 +1,86 @@
1/* ====================================================================
2 * Copyright (c) 2001 The OpenSSL Project. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in
13 * the documentation and/or other materials provided with the
14 * distribution.
15 *
16 * 3. All advertising materials mentioning features or use of this
17 * software must display the following acknowledgment:
18 * "This product includes software developed by the OpenSSL Project
19 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
20 *
21 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
22 * endorse or promote products derived from this software without
23 * prior written permission. For written permission, please contact
24 * openssl-core@openssl.org.
25 *
26 * 5. Products derived from this software may not be called "OpenSSL"
27 * nor may "OpenSSL" appear in their names without prior written
28 * permission of the OpenSSL Project.
29 *
30 * 6. Redistributions of any form whatsoever must retain the following
31 * acknowledgment:
32 * "This product includes software developed by the OpenSSL Project
33 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
34 *
35 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
36 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
37 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
38 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
39 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
41 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
42 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
43 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
44 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
45 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
46 * OF THE POSSIBILITY OF SUCH DAMAGE.
47 * ====================================================================
48 *
49 * This product includes cryptographic software written by Eric Young
50 * (eay@cryptsoft.com). This product includes software written by Tim
51 * Hudson (tjh@cryptsoft.com).
52 *
53 */
54
55#ifndef HEADER_NURON_ERR_H
56#define HEADER_NURON_ERR_H
57
58/* BEGIN ERROR CODES */
59/* The following lines are auto generated by the script mkerr.pl. Any changes
60 * made after this point may be overwritten when the script is next run.
61 */
62static void ERR_load_NURON_strings(void);
63static void ERR_unload_NURON_strings(void);
64static void ERR_NURON_error(int function, int reason, char *file, int line);
65#define NURONerr(f,r) ERR_NURON_error((f),(r),__FILE__,__LINE__)
66
67/* Error codes for the NURON functions. */
68
69/* Function codes. */
70#define NURON_F_NURON_CTRL 100
71#define NURON_F_NURON_FINISH 101
72#define NURON_F_NURON_INIT 102
73#define NURON_F_NURON_MOD_EXP 103
74
75/* Reason codes. */
76#define NURON_R_ALREADY_LOADED 100
77#define NURON_R_CTRL_COMMAND_NOT_IMPLEMENTED 101
78#define NURON_R_DSO_FAILURE 102
79#define NURON_R_DSO_FUNCTION_NOT_FOUND 103
80#define NURON_R_DSO_NOT_FOUND 104
81#define NURON_R_NOT_LOADED 105
82
83#ifdef __cplusplus
84}
85#endif
86#endif
diff --git a/src/lib/libcrypto/engine/hw_sureware_err.c b/src/lib/libcrypto/engine/hw_sureware_err.c
new file mode 100644
index 0000000000..69955dadbb
--- /dev/null
+++ b/src/lib/libcrypto/engine/hw_sureware_err.c
@@ -0,0 +1,150 @@
1/* hw_sureware_err.c */
2/* ====================================================================
3 * Copyright (c) 1999 The OpenSSL Project. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
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
15 * distribution.
16 *
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/)"
21 *
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 * openssl-core@OpenSSL.org.
26 *
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.
30 *
31 * 6. Redistributions of any form whatsoever must retain the following
32 * acknowledgment:
33 * "This product includes software developed by the OpenSSL Project
34 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
35 *
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 * ====================================================================
49 *
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).
53 *
54 */
55
56/* NOTE: this file was auto generated by the mkerr.pl script: any changes
57 * made to it will be overwritten when the script next updates this file,
58 * only reason strings will be preserved.
59 */
60
61#include <stdio.h>
62#include <openssl/err.h>
63#include "hw_sureware_err.h"
64
65/* BEGIN ERROR CODES */
66#ifndef OPENSSL_NO_ERR
67static ERR_STRING_DATA SUREWARE_str_functs[]=
68 {
69{ERR_PACK(0,SUREWARE_F_SUREWAREHK_CTRL,0), "SUREWAREHK_CTRL"},
70{ERR_PACK(0,SUREWARE_F_SUREWAREHK_DSA_DO_SIGN,0), "SUREWAREHK_DSA_DO_SIGN"},
71{ERR_PACK(0,SUREWARE_F_SUREWAREHK_EX_FREE,0), "SUREWAREHK_EX_FREE"},
72{ERR_PACK(0,SUREWARE_F_SUREWAREHK_FINISH,0), "SUREWAREHK_FINISH"},
73{ERR_PACK(0,SUREWARE_F_SUREWAREHK_INIT,0), "SUREWAREHK_INIT"},
74{ERR_PACK(0,SUREWARE_F_SUREWAREHK_LOAD_PRIVATE_KEY,0), "SUREWAREHK_LOAD_PRIVATE_KEY"},
75{ERR_PACK(0,SUREWARE_F_SUREWAREHK_LOAD_PUBLIC_KEY,0), "SUREWAREHK_LOAD_PUBLIC_KEY"},
76{ERR_PACK(0,SUREWARE_F_SUREWAREHK_MOD_EXP,0), "SUREWAREHK_MOD_EXP"},
77{ERR_PACK(0,SUREWARE_F_SUREWAREHK_RAND_BYTES,0), "SUREWAREHK_RAND_BYTES"},
78{ERR_PACK(0,SUREWARE_F_SUREWAREHK_RAND_SEED,0), "SUREWAREHK_RAND_SEED"},
79{ERR_PACK(0,SUREWARE_F_SUREWAREHK_RSA_PRIV_DEC,0), "SUREWAREHK_RSA_PRIV_DEC"},
80{ERR_PACK(0,SUREWARE_F_SUREWAREHK_RSA_PRIV_ENC,0), "SUREWAREHK_RSA_PRIV_ENC"},
81{0,NULL}
82 };
83
84static ERR_STRING_DATA SUREWARE_str_reasons[]=
85 {
86{SUREWARE_R_BIO_WAS_FREED ,"bio was freed"},
87{SUREWARE_R_MISSING_KEY_COMPONENTS ,"missing key components"},
88{SUREWARE_R_REQUEST_FAILED ,"request failed"},
89{SUREWARE_R_REQUEST_FALLBACK ,"request fallback"},
90{SUREWARE_R_SIZE_TOO_LARGE_OR_TOO_SMALL ,"size too large or too small"},
91{SUREWARE_R_UNIT_FAILURE ,"unit failure"},
92{0,NULL}
93 };
94
95#endif
96
97#ifdef SUREWARE_LIB_NAME
98static ERR_STRING_DATA SUREWARE_lib_name[]=
99 {
100{0 ,SUREWARE_LIB_NAME},
101{0,NULL}
102 };
103#endif
104
105
106static int SUREWARE_lib_error_code=0;
107static int SUREWARE_error_init=1;
108
109static void ERR_load_SUREWARE_strings(void)
110 {
111 if (SUREWARE_lib_error_code == 0)
112 SUREWARE_lib_error_code=ERR_get_next_error_library();
113
114 if (SUREWARE_error_init)
115 {
116 SUREWARE_error_init=0;
117#ifndef OPENSSL_NO_ERR
118 ERR_load_strings(SUREWARE_lib_error_code,SUREWARE_str_functs);
119 ERR_load_strings(SUREWARE_lib_error_code,SUREWARE_str_reasons);
120#endif
121
122#ifdef SUREWARE_LIB_NAME
123 SUREWARE_lib_name->error = ERR_PACK(SUREWARE_lib_error_code,0,0);
124 ERR_load_strings(0,SUREWARE_lib_name);
125#endif
126 }
127 }
128
129static void ERR_unload_SUREWARE_strings(void)
130 {
131 if (SUREWARE_error_init == 0)
132 {
133#ifndef OPENSSL_NO_ERR
134 ERR_unload_strings(SUREWARE_lib_error_code,SUREWARE_str_functs);
135 ERR_unload_strings(SUREWARE_lib_error_code,SUREWARE_str_reasons);
136#endif
137
138#ifdef SUREWARE_LIB_NAME
139 ERR_unload_strings(0,SUREWARE_lib_name);
140#endif
141 SUREWARE_error_init=1;
142 }
143 }
144
145static void ERR_SUREWARE_error(int function, int reason, char *file, int line)
146 {
147 if (SUREWARE_lib_error_code == 0)
148 SUREWARE_lib_error_code=ERR_get_next_error_library();
149 ERR_PUT_error(SUREWARE_lib_error_code,function,reason,file,line);
150 }
diff --git a/src/lib/libcrypto/engine/hw_sureware_err.h b/src/lib/libcrypto/engine/hw_sureware_err.h
new file mode 100644
index 0000000000..bc52af5e05
--- /dev/null
+++ b/src/lib/libcrypto/engine/hw_sureware_err.h
@@ -0,0 +1,94 @@
1/* ====================================================================
2 * Copyright (c) 2001 The OpenSSL Project. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in
13 * the documentation and/or other materials provided with the
14 * distribution.
15 *
16 * 3. All advertising materials mentioning features or use of this
17 * software must display the following acknowledgment:
18 * "This product includes software developed by the OpenSSL Project
19 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
20 *
21 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
22 * endorse or promote products derived from this software without
23 * prior written permission. For written permission, please contact
24 * openssl-core@openssl.org.
25 *
26 * 5. Products derived from this software may not be called "OpenSSL"
27 * nor may "OpenSSL" appear in their names without prior written
28 * permission of the OpenSSL Project.
29 *
30 * 6. Redistributions of any form whatsoever must retain the following
31 * acknowledgment:
32 * "This product includes software developed by the OpenSSL Project
33 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
34 *
35 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
36 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
37 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
38 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
39 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
41 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
42 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
43 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
44 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
45 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
46 * OF THE POSSIBILITY OF SUCH DAMAGE.
47 * ====================================================================
48 *
49 * This product includes cryptographic software written by Eric Young
50 * (eay@cryptsoft.com). This product includes software written by Tim
51 * Hudson (tjh@cryptsoft.com).
52 *
53 */
54
55#ifndef HEADER_SUREWARE_ERR_H
56#define HEADER_SUREWARE_ERR_H
57
58/* BEGIN ERROR CODES */
59/* The following lines are auto generated by the script mkerr.pl. Any changes
60 * made after this point may be overwritten when the script is next run.
61 */
62static void ERR_load_SUREWARE_strings(void);
63static void ERR_unload_SUREWARE_strings(void);
64static void ERR_SUREWARE_error(int function, int reason, char *file, int line);
65#define SUREWAREerr(f,r) ERR_SUREWARE_error((f),(r),__FILE__,__LINE__)
66
67/* Error codes for the SUREWARE functions. */
68
69/* Function codes. */
70#define SUREWARE_F_SUREWAREHK_CTRL 100
71#define SUREWARE_F_SUREWAREHK_DSA_DO_SIGN 101
72#define SUREWARE_F_SUREWAREHK_EX_FREE 102
73#define SUREWARE_F_SUREWAREHK_FINISH 103
74#define SUREWARE_F_SUREWAREHK_INIT 104
75#define SUREWARE_F_SUREWAREHK_LOAD_PRIVATE_KEY 105
76#define SUREWARE_F_SUREWAREHK_LOAD_PUBLIC_KEY 106
77#define SUREWARE_F_SUREWAREHK_MOD_EXP 107
78#define SUREWARE_F_SUREWAREHK_RAND_BYTES 108
79#define SUREWARE_F_SUREWAREHK_RAND_SEED 109
80#define SUREWARE_F_SUREWAREHK_RSA_PRIV_DEC 110
81#define SUREWARE_F_SUREWAREHK_RSA_PRIV_ENC 111
82
83/* Reason codes. */
84#define SUREWARE_R_BIO_WAS_FREED 100
85#define SUREWARE_R_MISSING_KEY_COMPONENTS 105
86#define SUREWARE_R_REQUEST_FAILED 101
87#define SUREWARE_R_REQUEST_FALLBACK 102
88#define SUREWARE_R_SIZE_TOO_LARGE_OR_TOO_SMALL 103
89#define SUREWARE_R_UNIT_FAILURE 104
90
91#ifdef __cplusplus
92}
93#endif
94#endif
diff --git a/src/lib/libcrypto/engine/hw_ubsec.c b/src/lib/libcrypto/engine/hw_ubsec.c
new file mode 100644
index 0000000000..743c06043c
--- /dev/null
+++ b/src/lib/libcrypto/engine/hw_ubsec.c
@@ -0,0 +1,1041 @@
1/* crypto/engine/hw_ubsec.c */
2/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
3 * project 2000.
4 *
5 * Cloned shamelessly by Joe Tardo.
6 */
7/* ====================================================================
8 * Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 *
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 *
17 * 2. Redistributions in binary form must reproduce the above copyright
18 * notice, this list of conditions and the following disclaimer in
19 * the documentation and/or other materials provided with the
20 * distribution.
21 *
22 * 3. All advertising materials mentioning features or use of this
23 * software must display the following acknowledgment:
24 * "This product includes software developed by the OpenSSL Project
25 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
26 *
27 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
28 * endorse or promote products derived from this software without
29 * prior written permission. For written permission, please contact
30 * licensing@OpenSSL.org.
31 *
32 * 5. Products derived from this software may not be called "OpenSSL"
33 * nor may "OpenSSL" appear in their names without prior written
34 * permission of the OpenSSL Project.
35 *
36 * 6. Redistributions of any form whatsoever must retain the following
37 * acknowledgment:
38 * "This product includes software developed by the OpenSSL Project
39 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
40 *
41 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
42 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
44 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
45 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
46 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
47 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
48 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
49 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
50 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
51 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
52 * OF THE POSSIBILITY OF SUCH DAMAGE.
53 * ====================================================================
54 *
55 * This product includes cryptographic software written by Eric Young
56 * (eay@cryptsoft.com). This product includes software written by Tim
57 * Hudson (tjh@cryptsoft.com).
58 *
59 */
60
61#include <stdio.h>
62#include <openssl/crypto.h>
63#include "cryptlib.h"
64#include <openssl/dso.h>
65#include <openssl/engine.h>
66
67#ifndef OPENSSL_NO_HW
68#ifndef OPENSSL_NO_HW_UBSEC
69
70#ifdef FLAT_INC
71#include "hw_ubsec.h"
72#else
73#include "vendor_defns/hw_ubsec.h"
74#endif
75
76#define UBSEC_LIB_NAME "ubsec engine"
77#include "hw_ubsec_err.c"
78
79#define FAIL_TO_SOFTWARE -15
80
81static int ubsec_destroy(ENGINE *e);
82static int ubsec_init(ENGINE *e);
83static int ubsec_finish(ENGINE *e);
84static int ubsec_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)());
85static int ubsec_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
86 const BIGNUM *m, BN_CTX *ctx);
87static int ubsec_mod_exp_crt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
88 const BIGNUM *q, const BIGNUM *dp,
89 const BIGNUM *dq, const BIGNUM *qinv, BN_CTX *ctx);
90#ifndef OPENSSL_NO_RSA
91static int ubsec_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa);
92#endif
93static int ubsec_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
94 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
95#ifndef OPENSSL_NO_DSA
96#if NOT_USED
97static int ubsec_dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1,
98 BIGNUM *p1, BIGNUM *a2, BIGNUM *p2, BIGNUM *m,
99 BN_CTX *ctx, BN_MONT_CTX *in_mont);
100static int ubsec_mod_exp_dsa(DSA *dsa, BIGNUM *r, BIGNUM *a,
101 const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
102 BN_MONT_CTX *m_ctx);
103#endif
104static DSA_SIG *ubsec_dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa);
105static int ubsec_dsa_verify(const unsigned char *dgst, int dgst_len,
106 DSA_SIG *sig, DSA *dsa);
107#endif
108#ifndef OPENSSL_NO_DH
109static int ubsec_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a,
110 const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
111 BN_MONT_CTX *m_ctx);
112static int ubsec_dh_compute_key(unsigned char *key,const BIGNUM *pub_key,DH *dh);
113static int ubsec_dh_generate_key(DH *dh);
114#endif
115
116#if NOT_USED
117static int ubsec_rand_bytes(unsigned char *buf, int num);
118static int ubsec_rand_status(void);
119#endif
120
121#define UBSEC_CMD_SO_PATH ENGINE_CMD_BASE
122static const ENGINE_CMD_DEFN ubsec_cmd_defns[] = {
123 {UBSEC_CMD_SO_PATH,
124 "SO_PATH",
125 "Specifies the path to the 'ubsec' shared library",
126 ENGINE_CMD_FLAG_STRING},
127 {0, NULL, NULL, 0}
128 };
129
130#ifndef OPENSSL_NO_RSA
131/* Our internal RSA_METHOD that we provide pointers to */
132static RSA_METHOD ubsec_rsa =
133 {
134 "UBSEC RSA method",
135 NULL,
136 NULL,
137 NULL,
138 NULL,
139 ubsec_rsa_mod_exp,
140 ubsec_mod_exp_mont,
141 NULL,
142 NULL,
143 0,
144 NULL,
145 NULL,
146 NULL
147 };
148#endif
149
150#ifndef OPENSSL_NO_DSA
151/* Our internal DSA_METHOD that we provide pointers to */
152static DSA_METHOD ubsec_dsa =
153 {
154 "UBSEC DSA method",
155 ubsec_dsa_do_sign, /* dsa_do_sign */
156 NULL, /* dsa_sign_setup */
157 ubsec_dsa_verify, /* dsa_do_verify */
158 NULL, /* ubsec_dsa_mod_exp */ /* dsa_mod_exp */
159 NULL, /* ubsec_mod_exp_dsa */ /* bn_mod_exp */
160 NULL, /* init */
161 NULL, /* finish */
162 0, /* flags */
163 NULL /* app_data */
164 };
165#endif
166
167#ifndef OPENSSL_NO_DH
168/* Our internal DH_METHOD that we provide pointers to */
169static DH_METHOD ubsec_dh =
170 {
171 "UBSEC DH method",
172 ubsec_dh_generate_key,
173 ubsec_dh_compute_key,
174 ubsec_mod_exp_dh,
175 NULL,
176 NULL,
177 0,
178 NULL
179 };
180#endif
181
182/* Constants used when creating the ENGINE */
183static const char *engine_ubsec_id = "ubsec";
184static const char *engine_ubsec_name = "UBSEC hardware engine support";
185
186/* This internal function is used by ENGINE_ubsec() and possibly by the
187 * "dynamic" ENGINE support too */
188static int bind_helper(ENGINE *e)
189 {
190#ifndef OPENSSL_NO_RSA
191 const RSA_METHOD *meth1;
192#endif
193#ifndef OPENSSL_NO_DH
194#ifndef HAVE_UBSEC_DH
195 const DH_METHOD *meth3;
196#endif /* HAVE_UBSEC_DH */
197#endif
198 if(!ENGINE_set_id(e, engine_ubsec_id) ||
199 !ENGINE_set_name(e, engine_ubsec_name) ||
200#ifndef OPENSSL_NO_RSA
201 !ENGINE_set_RSA(e, &ubsec_rsa) ||
202#endif
203#ifndef OPENSSL_NO_DSA
204 !ENGINE_set_DSA(e, &ubsec_dsa) ||
205#endif
206#ifndef OPENSSL_NO_DH
207 !ENGINE_set_DH(e, &ubsec_dh) ||
208#endif
209 !ENGINE_set_destroy_function(e, ubsec_destroy) ||
210 !ENGINE_set_init_function(e, ubsec_init) ||
211 !ENGINE_set_finish_function(e, ubsec_finish) ||
212 !ENGINE_set_ctrl_function(e, ubsec_ctrl) ||
213 !ENGINE_set_cmd_defns(e, ubsec_cmd_defns))
214 return 0;
215
216#ifndef OPENSSL_NO_RSA
217 /* We know that the "PKCS1_SSLeay()" functions hook properly
218 * to the Broadcom-specific mod_exp and mod_exp_crt so we use
219 * those functions. NB: We don't use ENGINE_openssl() or
220 * anything "more generic" because something like the RSAref
221 * code may not hook properly, and if you own one of these
222 * cards then you have the right to do RSA operations on it
223 * anyway! */
224 meth1 = RSA_PKCS1_SSLeay();
225 ubsec_rsa.rsa_pub_enc = meth1->rsa_pub_enc;
226 ubsec_rsa.rsa_pub_dec = meth1->rsa_pub_dec;
227 ubsec_rsa.rsa_priv_enc = meth1->rsa_priv_enc;
228 ubsec_rsa.rsa_priv_dec = meth1->rsa_priv_dec;
229#endif
230
231#ifndef OPENSSL_NO_DH
232#ifndef HAVE_UBSEC_DH
233 /* Much the same for Diffie-Hellman */
234 meth3 = DH_OpenSSL();
235 ubsec_dh.generate_key = meth3->generate_key;
236 ubsec_dh.compute_key = meth3->compute_key;
237#endif /* HAVE_UBSEC_DH */
238#endif
239
240 /* Ensure the ubsec error handling is set up */
241 ERR_load_UBSEC_strings();
242 return 1;
243 }
244
245static ENGINE *engine_ubsec(void)
246 {
247 ENGINE *ret = ENGINE_new();
248 if(!ret)
249 return NULL;
250 if(!bind_helper(ret))
251 {
252 ENGINE_free(ret);
253 return NULL;
254 }
255 return ret;
256 }
257
258void ENGINE_load_ubsec(void)
259 {
260 /* Copied from eng_[openssl|dyn].c */
261 ENGINE *toadd = engine_ubsec();
262 if(!toadd) return;
263 ENGINE_add(toadd);
264 ENGINE_free(toadd);
265 ERR_clear_error();
266 }
267
268/* This is a process-global DSO handle used for loading and unloading
269 * the UBSEC library. NB: This is only set (or unset) during an
270 * init() or finish() call (reference counts permitting) and they're
271 * operating with global locks, so this should be thread-safe
272 * implicitly. */
273
274static DSO *ubsec_dso = NULL;
275
276/* These are the function pointers that are (un)set when the library has
277 * successfully (un)loaded. */
278
279static t_UBSEC_ubsec_bytes_to_bits *p_UBSEC_ubsec_bytes_to_bits = NULL;
280static t_UBSEC_ubsec_bits_to_bytes *p_UBSEC_ubsec_bits_to_bytes = NULL;
281static t_UBSEC_ubsec_open *p_UBSEC_ubsec_open = NULL;
282static t_UBSEC_ubsec_close *p_UBSEC_ubsec_close = NULL;
283#ifndef OPENSSL_NO_DH
284static t_UBSEC_diffie_hellman_generate_ioctl
285 *p_UBSEC_diffie_hellman_generate_ioctl = NULL;
286static t_UBSEC_diffie_hellman_agree_ioctl *p_UBSEC_diffie_hellman_agree_ioctl = NULL;
287#endif
288/* #ifndef OPENSSL_NO_RSA */
289static t_UBSEC_rsa_mod_exp_ioctl *p_UBSEC_rsa_mod_exp_ioctl = NULL;
290static t_UBSEC_rsa_mod_exp_crt_ioctl *p_UBSEC_rsa_mod_exp_crt_ioctl = NULL;
291/* #endif */
292#ifndef OPENSSL_NO_DSA
293static t_UBSEC_dsa_sign_ioctl *p_UBSEC_dsa_sign_ioctl = NULL;
294static t_UBSEC_dsa_verify_ioctl *p_UBSEC_dsa_verify_ioctl = NULL;
295#endif
296static t_UBSEC_math_accelerate_ioctl *p_UBSEC_math_accelerate_ioctl = NULL;
297static t_UBSEC_rng_ioctl *p_UBSEC_rng_ioctl = NULL;
298static t_UBSEC_max_key_len_ioctl *p_UBSEC_max_key_len_ioctl = NULL;
299
300static int max_key_len = 1024; /* ??? */
301
302/*
303 * These are the static string constants for the DSO file name and the function
304 * symbol names to bind to.
305 */
306
307static const char *UBSEC_LIBNAME = "ubsec";
308static const char *UBSEC_F1 = "ubsec_bytes_to_bits";
309static const char *UBSEC_F2 = "ubsec_bits_to_bytes";
310static const char *UBSEC_F3 = "ubsec_open";
311static const char *UBSEC_F4 = "ubsec_close";
312#ifndef OPENSSL_NO_DH
313static const char *UBSEC_F5 = "diffie_hellman_generate_ioctl";
314static const char *UBSEC_F6 = "diffie_hellman_agree_ioctl";
315#endif
316/* #ifndef OPENSSL_NO_RSA */
317static const char *UBSEC_F7 = "rsa_mod_exp_ioctl";
318static const char *UBSEC_F8 = "rsa_mod_exp_crt_ioctl";
319/* #endif */
320#ifndef OPENSSL_NO_DSA
321static const char *UBSEC_F9 = "dsa_sign_ioctl";
322static const char *UBSEC_F10 = "dsa_verify_ioctl";
323#endif
324static const char *UBSEC_F11 = "math_accelerate_ioctl";
325static const char *UBSEC_F12 = "rng_ioctl";
326static const char *UBSEC_F13 = "ubsec_max_key_len_ioctl";
327
328/* Destructor (complements the "ENGINE_ubsec()" constructor) */
329static int ubsec_destroy(ENGINE *e)
330 {
331 ERR_unload_UBSEC_strings();
332 return 1;
333 }
334
335/* (de)initialisation functions. */
336static int ubsec_init(ENGINE *e)
337 {
338 t_UBSEC_ubsec_bytes_to_bits *p1;
339 t_UBSEC_ubsec_bits_to_bytes *p2;
340 t_UBSEC_ubsec_open *p3;
341 t_UBSEC_ubsec_close *p4;
342#ifndef OPENSSL_NO_DH
343 t_UBSEC_diffie_hellman_generate_ioctl *p5;
344 t_UBSEC_diffie_hellman_agree_ioctl *p6;
345#endif
346/* #ifndef OPENSSL_NO_RSA */
347 t_UBSEC_rsa_mod_exp_ioctl *p7;
348 t_UBSEC_rsa_mod_exp_crt_ioctl *p8;
349/* #endif */
350#ifndef OPENSSL_NO_DSA
351 t_UBSEC_dsa_sign_ioctl *p9;
352 t_UBSEC_dsa_verify_ioctl *p10;
353#endif
354 t_UBSEC_math_accelerate_ioctl *p11;
355 t_UBSEC_rng_ioctl *p12;
356 t_UBSEC_max_key_len_ioctl *p13;
357 int fd = 0;
358
359 if(ubsec_dso != NULL)
360 {
361 UBSECerr(UBSEC_F_UBSEC_INIT, UBSEC_R_ALREADY_LOADED);
362 goto err;
363 }
364 /*
365 * Attempt to load libubsec.so/ubsec.dll/whatever.
366 */
367 ubsec_dso = DSO_load(NULL, UBSEC_LIBNAME, NULL, 0);
368 if(ubsec_dso == NULL)
369 {
370 UBSECerr(UBSEC_F_UBSEC_INIT, UBSEC_R_DSO_FAILURE);
371 goto err;
372 }
373
374 if (
375 !(p1 = (t_UBSEC_ubsec_bytes_to_bits *) DSO_bind_func(ubsec_dso, UBSEC_F1)) ||
376 !(p2 = (t_UBSEC_ubsec_bits_to_bytes *) DSO_bind_func(ubsec_dso, UBSEC_F2)) ||
377 !(p3 = (t_UBSEC_ubsec_open *) DSO_bind_func(ubsec_dso, UBSEC_F3)) ||
378 !(p4 = (t_UBSEC_ubsec_close *) DSO_bind_func(ubsec_dso, UBSEC_F4)) ||
379#ifndef OPENSSL_NO_DH
380 !(p5 = (t_UBSEC_diffie_hellman_generate_ioctl *)
381 DSO_bind_func(ubsec_dso, UBSEC_F5)) ||
382 !(p6 = (t_UBSEC_diffie_hellman_agree_ioctl *)
383 DSO_bind_func(ubsec_dso, UBSEC_F6)) ||
384#endif
385/* #ifndef OPENSSL_NO_RSA */
386 !(p7 = (t_UBSEC_rsa_mod_exp_ioctl *) DSO_bind_func(ubsec_dso, UBSEC_F7)) ||
387 !(p8 = (t_UBSEC_rsa_mod_exp_crt_ioctl *) DSO_bind_func(ubsec_dso, UBSEC_F8)) ||
388/* #endif */
389#ifndef OPENSSL_NO_DSA
390 !(p9 = (t_UBSEC_dsa_sign_ioctl *) DSO_bind_func(ubsec_dso, UBSEC_F9)) ||
391 !(p10 = (t_UBSEC_dsa_verify_ioctl *) DSO_bind_func(ubsec_dso, UBSEC_F10)) ||
392#endif
393 !(p11 = (t_UBSEC_math_accelerate_ioctl *)
394 DSO_bind_func(ubsec_dso, UBSEC_F11)) ||
395 !(p12 = (t_UBSEC_rng_ioctl *) DSO_bind_func(ubsec_dso, UBSEC_F12)) ||
396 !(p13 = (t_UBSEC_max_key_len_ioctl *) DSO_bind_func(ubsec_dso, UBSEC_F13)))
397 {
398 UBSECerr(UBSEC_F_UBSEC_INIT, UBSEC_R_DSO_FAILURE);
399 goto err;
400 }
401
402 /* Copy the pointers */
403 p_UBSEC_ubsec_bytes_to_bits = p1;
404 p_UBSEC_ubsec_bits_to_bytes = p2;
405 p_UBSEC_ubsec_open = p3;
406 p_UBSEC_ubsec_close = p4;
407#ifndef OPENSSL_NO_DH
408 p_UBSEC_diffie_hellman_generate_ioctl = p5;
409 p_UBSEC_diffie_hellman_agree_ioctl = p6;
410#endif
411#ifndef OPENSSL_NO_RSA
412 p_UBSEC_rsa_mod_exp_ioctl = p7;
413 p_UBSEC_rsa_mod_exp_crt_ioctl = p8;
414#endif
415#ifndef OPENSSL_NO_DSA
416 p_UBSEC_dsa_sign_ioctl = p9;
417 p_UBSEC_dsa_verify_ioctl = p10;
418#endif
419 p_UBSEC_math_accelerate_ioctl = p11;
420 p_UBSEC_rng_ioctl = p12;
421 p_UBSEC_max_key_len_ioctl = p13;
422
423 /* Perform an open to see if there's actually any unit running. */
424 if (((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) > 0) && (p_UBSEC_max_key_len_ioctl(fd, &max_key_len) == 0))
425 {
426 p_UBSEC_ubsec_close(fd);
427 return 1;
428 }
429 else
430 {
431 UBSECerr(UBSEC_F_UBSEC_INIT, UBSEC_R_UNIT_FAILURE);
432 }
433
434err:
435 if(ubsec_dso)
436 DSO_free(ubsec_dso);
437 p_UBSEC_ubsec_bytes_to_bits = NULL;
438 p_UBSEC_ubsec_bits_to_bytes = NULL;
439 p_UBSEC_ubsec_open = NULL;
440 p_UBSEC_ubsec_close = NULL;
441#ifndef OPENSSL_NO_DH
442 p_UBSEC_diffie_hellman_generate_ioctl = NULL;
443 p_UBSEC_diffie_hellman_agree_ioctl = NULL;
444#endif
445#ifndef OPENSSL_NO_RSA
446 p_UBSEC_rsa_mod_exp_ioctl = NULL;
447 p_UBSEC_rsa_mod_exp_crt_ioctl = NULL;
448#endif
449#ifndef OPENSSL_NO_DSA
450 p_UBSEC_dsa_sign_ioctl = NULL;
451 p_UBSEC_dsa_verify_ioctl = NULL;
452#endif
453 p_UBSEC_math_accelerate_ioctl = NULL;
454 p_UBSEC_rng_ioctl = NULL;
455 p_UBSEC_max_key_len_ioctl = NULL;
456
457 return 0;
458 }
459
460static int ubsec_finish(ENGINE *e)
461 {
462 if(ubsec_dso == NULL)
463 {
464 UBSECerr(UBSEC_F_UBSEC_FINISH, UBSEC_R_NOT_LOADED);
465 return 0;
466 }
467 if(!DSO_free(ubsec_dso))
468 {
469 UBSECerr(UBSEC_F_UBSEC_FINISH, UBSEC_R_DSO_FAILURE);
470 return 0;
471 }
472 ubsec_dso = NULL;
473 p_UBSEC_ubsec_bytes_to_bits = NULL;
474 p_UBSEC_ubsec_bits_to_bytes = NULL;
475 p_UBSEC_ubsec_open = NULL;
476 p_UBSEC_ubsec_close = NULL;
477#ifndef OPENSSL_NO_DH
478 p_UBSEC_diffie_hellman_generate_ioctl = NULL;
479 p_UBSEC_diffie_hellman_agree_ioctl = NULL;
480#endif
481#ifndef OPENSSL_NO_RSA
482 p_UBSEC_rsa_mod_exp_ioctl = NULL;
483 p_UBSEC_rsa_mod_exp_crt_ioctl = NULL;
484#endif
485#ifndef OPENSSL_NO_DSA
486 p_UBSEC_dsa_sign_ioctl = NULL;
487 p_UBSEC_dsa_verify_ioctl = NULL;
488#endif
489 p_UBSEC_math_accelerate_ioctl = NULL;
490 p_UBSEC_rng_ioctl = NULL;
491 p_UBSEC_max_key_len_ioctl = NULL;
492 return 1;
493 }
494
495static int ubsec_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)())
496 {
497 int initialised = ((ubsec_dso == NULL) ? 0 : 1);
498 switch(cmd)
499 {
500 case UBSEC_CMD_SO_PATH:
501 if(p == NULL)
502 {
503 UBSECerr(UBSEC_F_UBSEC_CTRL,ERR_R_PASSED_NULL_PARAMETER);
504 return 0;
505 }
506 if(initialised)
507 {
508 UBSECerr(UBSEC_F_UBSEC_CTRL,UBSEC_R_ALREADY_LOADED);
509 return 0;
510 }
511 UBSEC_LIBNAME = (const char *)p;
512 return 1;
513 default:
514 break;
515 }
516 UBSECerr(UBSEC_F_UBSEC_CTRL,UBSEC_R_CTRL_COMMAND_NOT_IMPLEMENTED);
517 return 0;
518 }
519
520static int ubsec_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
521 const BIGNUM *m, BN_CTX *ctx)
522 {
523 int y_len = 0;
524 int fd;
525
526 if(ubsec_dso == NULL)
527 {
528 UBSECerr(UBSEC_F_UBSEC_MOD_EXP, UBSEC_R_NOT_LOADED);
529 return 0;
530 }
531
532 /* Check if hardware can't handle this argument. */
533 y_len = BN_num_bits(m);
534 if (y_len > max_key_len) {
535 UBSECerr(UBSEC_F_UBSEC_MOD_EXP, UBSEC_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
536 return BN_mod_exp(r, a, p, m, ctx);
537 }
538
539 if(!bn_wexpand(r, m->top))
540 {
541 UBSECerr(UBSEC_F_UBSEC_MOD_EXP, UBSEC_R_BN_EXPAND_FAIL);
542 return 0;
543 }
544 memset(r->d, 0, BN_num_bytes(m));
545
546 if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0) {
547 fd = 0;
548 UBSECerr(UBSEC_F_UBSEC_INIT, UBSEC_R_UNIT_FAILURE);
549 return BN_mod_exp(r, a, p, m, ctx);
550 }
551
552 if (p_UBSEC_rsa_mod_exp_ioctl(fd, (unsigned char *)a->d, BN_num_bits(a),
553 (unsigned char *)m->d, BN_num_bits(m), (unsigned char *)p->d,
554 BN_num_bits(p), (unsigned char *)r->d, &y_len) != 0)
555 {
556 UBSECerr(UBSEC_F_UBSEC_MOD_EXP, UBSEC_R_REQUEST_FAILED);
557 p_UBSEC_ubsec_close(fd);
558
559 return BN_mod_exp(r, a, p, m, ctx);
560 }
561
562 p_UBSEC_ubsec_close(fd);
563
564 r->top = (BN_num_bits(m)+BN_BITS2-1)/BN_BITS2;
565 return 1;
566 }
567
568#ifndef OPENSSL_NO_RSA
569static int ubsec_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa)
570 {
571 BN_CTX *ctx;
572 int to_return = 0;
573
574 if((ctx = BN_CTX_new()) == NULL)
575 goto err;
576
577 if(!rsa->p || !rsa->q || !rsa->dmp1 || !rsa->dmq1 || !rsa->iqmp)
578 {
579 UBSECerr(UBSEC_F_UBSEC_RSA_MOD_EXP, UBSEC_R_MISSING_KEY_COMPONENTS);
580 goto err;
581 }
582
583 to_return = ubsec_mod_exp_crt(r0, I, rsa->p, rsa->q, rsa->dmp1,
584 rsa->dmq1, rsa->iqmp, ctx);
585 if (to_return == FAIL_TO_SOFTWARE)
586 {
587 /*
588 * Do in software as hardware failed.
589 */
590 const RSA_METHOD *meth = RSA_PKCS1_SSLeay();
591 to_return = (*meth->rsa_mod_exp)(r0, I, rsa);
592 }
593err:
594 if(ctx)
595 BN_CTX_free(ctx);
596 return to_return;
597 }
598#endif
599
600static int ubsec_mod_exp_crt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
601 const BIGNUM *q, const BIGNUM *dp,
602 const BIGNUM *dq, const BIGNUM *qinv, BN_CTX *ctx)
603 {
604 int y_len,
605 m_len,
606 fd;
607
608 m_len = BN_num_bytes(p) + BN_num_bytes(q) + 1;
609 y_len = BN_num_bits(p) + BN_num_bits(q);
610
611 /* Check if hardware can't handle this argument. */
612 if (y_len > max_key_len) {
613 UBSECerr(UBSEC_F_UBSEC_MOD_EXP, UBSEC_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
614 return FAIL_TO_SOFTWARE;
615 }
616
617 if (!bn_wexpand(r, p->top + q->top + 1)) {
618 UBSECerr(UBSEC_F_UBSEC_RSA_MOD_EXP_CRT, UBSEC_R_BN_EXPAND_FAIL);
619 return 0;
620 }
621
622 if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0) {
623 fd = 0;
624 UBSECerr(UBSEC_F_UBSEC_INIT, UBSEC_R_UNIT_FAILURE);
625 return FAIL_TO_SOFTWARE;
626 }
627
628 if (p_UBSEC_rsa_mod_exp_crt_ioctl(fd,
629 (unsigned char *)a->d, BN_num_bits(a),
630 (unsigned char *)qinv->d, BN_num_bits(qinv),
631 (unsigned char *)dp->d, BN_num_bits(dp),
632 (unsigned char *)p->d, BN_num_bits(p),
633 (unsigned char *)dq->d, BN_num_bits(dq),
634 (unsigned char *)q->d, BN_num_bits(q),
635 (unsigned char *)r->d, &y_len) != 0) {
636 UBSECerr(UBSEC_F_UBSEC_MOD_EXP, UBSEC_R_REQUEST_FAILED);
637 p_UBSEC_ubsec_close(fd);
638 return FAIL_TO_SOFTWARE;
639 }
640
641 p_UBSEC_ubsec_close(fd);
642
643 r->top = (BN_num_bits(p) + BN_num_bits(q) + BN_BITS2 - 1)/BN_BITS2;
644 return 1;
645}
646
647#ifndef OPENSSL_NO_DSA
648#if NOT_USED
649static int ubsec_dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1,
650 BIGNUM *p1, BIGNUM *a2, BIGNUM *p2, BIGNUM *m,
651 BN_CTX *ctx, BN_MONT_CTX *in_mont)
652 {
653 BIGNUM t;
654 int to_return = 0;
655
656 BN_init(&t);
657 /* let rr = a1 ^ p1 mod m */
658 if (!ubsec_mod_exp(rr,a1,p1,m,ctx)) goto end;
659 /* let t = a2 ^ p2 mod m */
660 if (!ubsec_mod_exp(&t,a2,p2,m,ctx)) goto end;
661 /* let rr = rr * t mod m */
662 if (!BN_mod_mul(rr,rr,&t,m,ctx)) goto end;
663 to_return = 1;
664end:
665 BN_free(&t);
666 return to_return;
667 }
668
669static int ubsec_mod_exp_dsa(DSA *dsa, BIGNUM *r, BIGNUM *a,
670 const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
671 BN_MONT_CTX *m_ctx)
672 {
673 return ubsec_mod_exp(r, a, p, m, ctx);
674 }
675#endif
676#endif
677
678/*
679 * This function is aliased to mod_exp (with the mont stuff dropped).
680 */
681static int ubsec_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
682 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
683 {
684 int ret = 0;
685
686#ifndef OPENSSL_NO_RSA
687 /* Do in software if the key is too large for the hardware. */
688 if (BN_num_bits(m) > max_key_len)
689 {
690 const RSA_METHOD *meth = RSA_PKCS1_SSLeay();
691 ret = (*meth->bn_mod_exp)(r, a, p, m, ctx, m_ctx);
692 }
693 else
694#endif
695 {
696 ret = ubsec_mod_exp(r, a, p, m, ctx);
697 }
698
699 return ret;
700 }
701
702#ifndef OPENSSL_NO_DH
703/* This function is aliased to mod_exp (with the dh and mont dropped). */
704static int ubsec_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a,
705 const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
706 BN_MONT_CTX *m_ctx)
707 {
708 return ubsec_mod_exp(r, a, p, m, ctx);
709 }
710#endif
711
712#ifndef OPENSSL_NO_DSA
713static DSA_SIG *ubsec_dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
714 {
715 DSA_SIG *to_return = NULL;
716 int s_len = 160, r_len = 160, d_len, fd;
717 BIGNUM m, *r=NULL, *s=NULL;
718
719 BN_init(&m);
720
721 s = BN_new();
722 r = BN_new();
723 if ((s == NULL) || (r==NULL))
724 goto err;
725
726 d_len = p_UBSEC_ubsec_bytes_to_bits((unsigned char *)dgst, dlen);
727
728 if(!bn_wexpand(r, (160+BN_BITS2-1)/BN_BITS2) ||
729 (!bn_wexpand(s, (160+BN_BITS2-1)/BN_BITS2))) {
730 UBSECerr(UBSEC_F_UBSEC_DSA_SIGN, UBSEC_R_BN_EXPAND_FAIL);
731 goto err;
732 }
733
734 if (BN_bin2bn(dgst,dlen,&m) == NULL) {
735 UBSECerr(UBSEC_F_UBSEC_DSA_SIGN, UBSEC_R_BN_EXPAND_FAIL);
736 goto err;
737 }
738
739 if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0) {
740 const DSA_METHOD *meth;
741 fd = 0;
742 UBSECerr(UBSEC_F_UBSEC_INIT, UBSEC_R_UNIT_FAILURE);
743 meth = DSA_OpenSSL();
744 to_return = meth->dsa_do_sign(dgst, dlen, dsa);
745 goto err;
746 }
747
748 if (p_UBSEC_dsa_sign_ioctl(fd, 0, /* compute hash before signing */
749 (unsigned char *)dgst, d_len,
750 NULL, 0, /* compute random value */
751 (unsigned char *)dsa->p->d, BN_num_bits(dsa->p),
752 (unsigned char *)dsa->q->d, BN_num_bits(dsa->q),
753 (unsigned char *)dsa->g->d, BN_num_bits(dsa->g),
754 (unsigned char *)dsa->priv_key->d, BN_num_bits(dsa->priv_key),
755 (unsigned char *)r->d, &r_len,
756 (unsigned char *)s->d, &s_len ) != 0) {
757 const DSA_METHOD *meth;
758
759 UBSECerr(UBSEC_F_UBSEC_DSA_SIGN, UBSEC_R_REQUEST_FAILED);
760 p_UBSEC_ubsec_close(fd);
761 meth = DSA_OpenSSL();
762 to_return = meth->dsa_do_sign(dgst, dlen, dsa);
763
764 goto err;
765 }
766
767 p_UBSEC_ubsec_close(fd);
768
769 r->top = (160+BN_BITS2-1)/BN_BITS2;
770 s->top = (160+BN_BITS2-1)/BN_BITS2;
771
772 to_return = DSA_SIG_new();
773 if(to_return == NULL) {
774 UBSECerr(UBSEC_F_UBSEC_DSA_SIGN, UBSEC_R_BN_EXPAND_FAIL);
775 goto err;
776 }
777
778 to_return->r = r;
779 to_return->s = s;
780
781err:
782 if (!to_return) {
783 if (r) BN_free(r);
784 if (s) BN_free(s);
785 }
786 BN_clear_free(&m);
787 return to_return;
788}
789
790static int ubsec_dsa_verify(const unsigned char *dgst, int dgst_len,
791 DSA_SIG *sig, DSA *dsa)
792 {
793 int v_len, d_len;
794 int to_return = 0;
795 int fd;
796 BIGNUM v;
797
798 BN_init(&v);
799
800 if(!bn_wexpand(&v, dsa->p->top)) {
801 UBSECerr(UBSEC_F_UBSEC_DSA_VERIFY ,UBSEC_R_BN_EXPAND_FAIL);
802 goto err;
803 }
804
805 v_len = BN_num_bits(dsa->p);
806
807 d_len = p_UBSEC_ubsec_bytes_to_bits((unsigned char *)dgst, dgst_len);
808
809 if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0) {
810 const DSA_METHOD *meth;
811 fd = 0;
812 UBSECerr(UBSEC_F_UBSEC_INIT, UBSEC_R_UNIT_FAILURE);
813 meth = DSA_OpenSSL();
814 to_return = meth->dsa_do_verify(dgst, dgst_len, sig, dsa);
815 goto err;
816 }
817
818 if (p_UBSEC_dsa_verify_ioctl(fd, 0, /* compute hash before signing */
819 (unsigned char *)dgst, d_len,
820 (unsigned char *)dsa->p->d, BN_num_bits(dsa->p),
821 (unsigned char *)dsa->q->d, BN_num_bits(dsa->q),
822 (unsigned char *)dsa->g->d, BN_num_bits(dsa->g),
823 (unsigned char *)dsa->pub_key->d, BN_num_bits(dsa->pub_key),
824 (unsigned char *)sig->r->d, BN_num_bits(sig->r),
825 (unsigned char *)sig->s->d, BN_num_bits(sig->s),
826 (unsigned char *)v.d, &v_len) != 0) {
827 const DSA_METHOD *meth;
828 UBSECerr(UBSEC_F_UBSEC_DSA_VERIFY , UBSEC_R_REQUEST_FAILED);
829 p_UBSEC_ubsec_close(fd);
830
831 meth = DSA_OpenSSL();
832 to_return = meth->dsa_do_verify(dgst, dgst_len, sig, dsa);
833
834 goto err;
835 }
836
837 p_UBSEC_ubsec_close(fd);
838
839 to_return = 1;
840err:
841 BN_clear_free(&v);
842 return to_return;
843 }
844#endif
845
846#ifndef OPENSSL_NO_DH
847static int ubsec_dh_compute_key (unsigned char *key,const BIGNUM *pub_key,DH *dh)
848 {
849 int ret = -1,
850 k_len,
851 fd;
852
853 k_len = BN_num_bits(dh->p);
854
855 if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0)
856 {
857 const DH_METHOD *meth;
858 ENGINEerr(UBSEC_F_UBSEC_INIT, UBSEC_R_UNIT_FAILURE);
859 meth = DH_OpenSSL();
860 ret = meth->compute_key(key, pub_key, dh);
861 goto err;
862 }
863
864 if (p_UBSEC_diffie_hellman_agree_ioctl(fd,
865 (unsigned char *)dh->priv_key->d, BN_num_bits(dh->priv_key),
866 (unsigned char *)pub_key->d, BN_num_bits(pub_key),
867 (unsigned char *)dh->p->d, BN_num_bits(dh->p),
868 key, &k_len) != 0)
869 {
870 /* Hardware's a no go, failover to software */
871 const DH_METHOD *meth;
872 ENGINEerr(UBSEC_F_UBSEC_DH_COMPUTE_KEY, UBSEC_R_REQUEST_FAILED);
873 p_UBSEC_ubsec_close(fd);
874
875 meth = DH_OpenSSL();
876 ret = meth->compute_key(key, pub_key, dh);
877
878 goto err;
879 }
880
881 p_UBSEC_ubsec_close(fd);
882
883 ret = p_UBSEC_ubsec_bits_to_bytes(k_len);
884err:
885 return ret;
886 }
887
888static int ubsec_dh_generate_key (DH *dh)
889 {
890 int ret = 0,
891 random_bits = 0,
892 pub_key_len = 0,
893 priv_key_len = 0,
894 fd;
895 BIGNUM *pub_key = NULL;
896 BIGNUM *priv_key = NULL;
897
898 /*
899 * How many bits should Random x be? dh_key.c
900 * sets the range from 0 to num_bits(modulus) ???
901 */
902
903 if (dh->priv_key == NULL)
904 {
905 priv_key = BN_new();
906 if (priv_key == NULL) goto err;
907 priv_key_len = BN_num_bits(dh->p);
908 bn_wexpand(priv_key, dh->p->top);
909 do
910 if (!BN_rand_range(priv_key, dh->p)) goto err;
911 while (BN_is_zero(priv_key));
912 random_bits = BN_num_bits(priv_key);
913 }
914 else
915 {
916 priv_key = dh->priv_key;
917 }
918
919 if (dh->pub_key == NULL)
920 {
921 pub_key = BN_new();
922 pub_key_len = BN_num_bits(dh->p);
923 bn_wexpand(pub_key, dh->p->top);
924 if(pub_key == NULL) goto err;
925 }
926 else
927 {
928 pub_key = dh->pub_key;
929 }
930
931 if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0)
932 {
933 const DH_METHOD *meth;
934 ENGINEerr(UBSEC_F_UBSEC_INIT, UBSEC_R_UNIT_FAILURE);
935 meth = DH_OpenSSL();
936 ret = meth->generate_key(dh);
937 goto err;
938 }
939
940 if (p_UBSEC_diffie_hellman_generate_ioctl(fd,
941 (unsigned char *)priv_key->d, &priv_key_len,
942 (unsigned char *)pub_key->d, &pub_key_len,
943 (unsigned char *)dh->g->d, BN_num_bits(dh->g),
944 (unsigned char *)dh->p->d, BN_num_bits(dh->p),
945 0, 0, random_bits) != 0)
946 {
947 /* Hardware's a no go, failover to software */
948 const DH_METHOD *meth;
949
950 ENGINEerr(UBSEC_F_UBSEC_DH_COMPUTE_KEY, UBSEC_R_REQUEST_FAILED);
951 p_UBSEC_ubsec_close(fd);
952
953 meth = DH_OpenSSL();
954 ret = meth->generate_key(dh);
955
956 goto err;
957 }
958
959 p_UBSEC_ubsec_close(fd);
960
961 dh->pub_key = pub_key;
962 dh->pub_key->top = (pub_key_len + BN_BITS2-1) / BN_BITS2;
963 dh->priv_key = priv_key;
964 dh->priv_key->top = (priv_key_len + BN_BITS2-1) / BN_BITS2;
965
966 ret = 1;
967err:
968 return ret;
969 }
970#endif
971
972#if NOT_USED
973static int ubsec_rand_bytes(unsigned char * buf,
974 int num)
975 {
976 int ret = 0,
977 fd;
978
979 if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0)
980 {
981 const RAND_METHOD *meth;
982 ENGINEerr(UBSEC_F_UBSEC_INIT, UBSEC_R_UNIT_FAILURE);
983 num = p_UBSEC_ubsec_bits_to_bytes(num);
984 meth = RAND_SSLeay();
985 meth->seed(buf, num);
986 ret = meth->bytes(buf, num);
987 goto err;
988 }
989
990 num *= 8; /* bytes to bits */
991
992 if (p_UBSEC_rng_ioctl(fd,
993 UBSEC_RNG_DIRECT,
994 buf,
995 &num) != 0)
996 {
997 /* Hardware's a no go, failover to software */
998 const RAND_METHOD *meth;
999
1000 ENGINEerr(UBSEC_F_UBSEC_RNG_BYTES, UBSEC_R_REQUEST_FAILED);
1001 p_UBSEC_ubsec_close(fd);
1002
1003 num = p_UBSEC_ubsec_bits_to_bytes(num);
1004 meth = RAND_SSLeay();
1005 meth->seed(buf, num);
1006 ret = meth->bytes(buf, num);
1007
1008 goto err;
1009 }
1010
1011 p_UBSEC_ubsec_close(fd);
1012
1013 ret = 1;
1014err:
1015 return(ret);
1016 }
1017
1018
1019static int ubsec_rand_status(void)
1020 {
1021 return 0;
1022 }
1023#endif
1024
1025/* This stuff is needed if this ENGINE is being compiled into a self-contained
1026 * shared-library. */
1027#ifdef ENGINE_DYNAMIC_SUPPORT
1028static int bind_fn(ENGINE *e, const char *id)
1029 {
1030 if(id && (strcmp(id, engine_ubsec_id) != 0))
1031 return 0;
1032 if(!bind_helper(e))
1033 return 0;
1034 return 1;
1035 }
1036IMPLEMENT_DYNAMIC_CHECK_FN()
1037IMPLEMENT_DYNAMIC_BIND_FN(bind_fn)
1038#endif /* ENGINE_DYNAMIC_SUPPORT */
1039
1040#endif /* !OPENSSL_NO_HW_UBSEC */
1041#endif /* !OPENSSL_NO_HW */
diff --git a/src/lib/libcrypto/engine/hw_ubsec_err.c b/src/lib/libcrypto/engine/hw_ubsec_err.c
new file mode 100644
index 0000000000..d707331fc2
--- /dev/null
+++ b/src/lib/libcrypto/engine/hw_ubsec_err.c
@@ -0,0 +1,151 @@
1/* hw_ubsec_err.c */
2/* ====================================================================
3 * Copyright (c) 1999 The OpenSSL Project. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
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
15 * distribution.
16 *
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/)"
21 *
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 * openssl-core@OpenSSL.org.
26 *
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.
30 *
31 * 6. Redistributions of any form whatsoever must retain the following
32 * acknowledgment:
33 * "This product includes software developed by the OpenSSL Project
34 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
35 *
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 * ====================================================================
49 *
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).
53 *
54 */
55
56/* NOTE: this file was auto generated by the mkerr.pl script: any changes
57 * made to it will be overwritten when the script next updates this file,
58 * only reason strings will be preserved.
59 */
60
61#include <stdio.h>
62#include <openssl/err.h>
63#include "hw_ubsec_err.h"
64
65/* BEGIN ERROR CODES */
66#ifndef OPENSSL_NO_ERR
67static ERR_STRING_DATA UBSEC_str_functs[]=
68 {
69{ERR_PACK(0,UBSEC_F_UBSEC_CTRL,0), "UBSEC_CTRL"},
70{ERR_PACK(0,UBSEC_F_UBSEC_DH_COMPUTE_KEY,0), "UBSEC_DH_COMPUTE_KEY"},
71{ERR_PACK(0,UBSEC_F_UBSEC_DSA_SIGN,0), "UBSEC_DSA_SIGN"},
72{ERR_PACK(0,UBSEC_F_UBSEC_DSA_VERIFY,0), "UBSEC_DSA_VERIFY"},
73{ERR_PACK(0,UBSEC_F_UBSEC_FINISH,0), "UBSEC_FINISH"},
74{ERR_PACK(0,UBSEC_F_UBSEC_INIT,0), "UBSEC_INIT"},
75{ERR_PACK(0,UBSEC_F_UBSEC_MOD_EXP,0), "UBSEC_MOD_EXP"},
76{ERR_PACK(0,UBSEC_F_UBSEC_RNG_BYTES,0), "UBSEC_RNG_BYTES"},
77{ERR_PACK(0,UBSEC_F_UBSEC_RSA_MOD_EXP,0), "UBSEC_RSA_MOD_EXP"},
78{ERR_PACK(0,UBSEC_F_UBSEC_RSA_MOD_EXP_CRT,0), "UBSEC_RSA_MOD_EXP_CRT"},
79{0,NULL}
80 };
81
82static ERR_STRING_DATA UBSEC_str_reasons[]=
83 {
84{UBSEC_R_ALREADY_LOADED ,"already loaded"},
85{UBSEC_R_BN_EXPAND_FAIL ,"bn expand fail"},
86{UBSEC_R_CTRL_COMMAND_NOT_IMPLEMENTED ,"ctrl command not implemented"},
87{UBSEC_R_DSO_FAILURE ,"dso failure"},
88{UBSEC_R_MISSING_KEY_COMPONENTS ,"missing key components"},
89{UBSEC_R_NOT_LOADED ,"not loaded"},
90{UBSEC_R_REQUEST_FAILED ,"request failed"},
91{UBSEC_R_SIZE_TOO_LARGE_OR_TOO_SMALL ,"size too large or too small"},
92{UBSEC_R_UNIT_FAILURE ,"unit failure"},
93{0,NULL}
94 };
95
96#endif
97
98#ifdef UBSEC_LIB_NAME
99static ERR_STRING_DATA UBSEC_lib_name[]=
100 {
101{0 ,UBSEC_LIB_NAME},
102{0,NULL}
103 };
104#endif
105
106
107static int UBSEC_lib_error_code=0;
108static int UBSEC_error_init=1;
109
110static void ERR_load_UBSEC_strings(void)
111 {
112 if (UBSEC_lib_error_code == 0)
113 UBSEC_lib_error_code=ERR_get_next_error_library();
114
115 if (UBSEC_error_init)
116 {
117 UBSEC_error_init=0;
118#ifndef OPENSSL_NO_ERR
119 ERR_load_strings(UBSEC_lib_error_code,UBSEC_str_functs);
120 ERR_load_strings(UBSEC_lib_error_code,UBSEC_str_reasons);
121#endif
122
123#ifdef UBSEC_LIB_NAME
124 UBSEC_lib_name->error = ERR_PACK(UBSEC_lib_error_code,0,0);
125 ERR_load_strings(0,UBSEC_lib_name);
126#endif
127 }
128 }
129
130static void ERR_unload_UBSEC_strings(void)
131 {
132 if (UBSEC_error_init == 0)
133 {
134#ifndef OPENSSL_NO_ERR
135 ERR_unload_strings(UBSEC_lib_error_code,UBSEC_str_functs);
136 ERR_unload_strings(UBSEC_lib_error_code,UBSEC_str_reasons);
137#endif
138
139#ifdef UBSEC_LIB_NAME
140 ERR_unload_strings(0,UBSEC_lib_name);
141#endif
142 UBSEC_error_init=1;
143 }
144 }
145
146static void ERR_UBSEC_error(int function, int reason, char *file, int line)
147 {
148 if (UBSEC_lib_error_code == 0)
149 UBSEC_lib_error_code=ERR_get_next_error_library();
150 ERR_PUT_error(UBSEC_lib_error_code,function,reason,file,line);
151 }
diff --git a/src/lib/libcrypto/engine/hw_ubsec_err.h b/src/lib/libcrypto/engine/hw_ubsec_err.h
new file mode 100644
index 0000000000..023d3be771
--- /dev/null
+++ b/src/lib/libcrypto/engine/hw_ubsec_err.h
@@ -0,0 +1,95 @@
1/* ====================================================================
2 * Copyright (c) 2001 The OpenSSL Project. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in
13 * the documentation and/or other materials provided with the
14 * distribution.
15 *
16 * 3. All advertising materials mentioning features or use of this
17 * software must display the following acknowledgment:
18 * "This product includes software developed by the OpenSSL Project
19 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
20 *
21 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
22 * endorse or promote products derived from this software without
23 * prior written permission. For written permission, please contact
24 * openssl-core@openssl.org.
25 *
26 * 5. Products derived from this software may not be called "OpenSSL"
27 * nor may "OpenSSL" appear in their names without prior written
28 * permission of the OpenSSL Project.
29 *
30 * 6. Redistributions of any form whatsoever must retain the following
31 * acknowledgment:
32 * "This product includes software developed by the OpenSSL Project
33 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
34 *
35 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
36 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
37 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
38 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
39 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
41 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
42 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
43 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
44 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
45 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
46 * OF THE POSSIBILITY OF SUCH DAMAGE.
47 * ====================================================================
48 *
49 * This product includes cryptographic software written by Eric Young
50 * (eay@cryptsoft.com). This product includes software written by Tim
51 * Hudson (tjh@cryptsoft.com).
52 *
53 */
54
55#ifndef HEADER_UBSEC_ERR_H
56#define HEADER_UBSEC_ERR_H
57
58/* BEGIN ERROR CODES */
59/* The following lines are auto generated by the script mkerr.pl. Any changes
60 * made after this point may be overwritten when the script is next run.
61 */
62static void ERR_load_UBSEC_strings(void);
63static void ERR_unload_UBSEC_strings(void);
64static void ERR_UBSEC_error(int function, int reason, char *file, int line);
65#define UBSECerr(f,r) ERR_UBSEC_error((f),(r),__FILE__,__LINE__)
66
67/* Error codes for the UBSEC functions. */
68
69/* Function codes. */
70#define UBSEC_F_UBSEC_CTRL 100
71#define UBSEC_F_UBSEC_DH_COMPUTE_KEY 101
72#define UBSEC_F_UBSEC_DSA_SIGN 102
73#define UBSEC_F_UBSEC_DSA_VERIFY 103
74#define UBSEC_F_UBSEC_FINISH 104
75#define UBSEC_F_UBSEC_INIT 105
76#define UBSEC_F_UBSEC_MOD_EXP 106
77#define UBSEC_F_UBSEC_RNG_BYTES 107
78#define UBSEC_F_UBSEC_RSA_MOD_EXP 108
79#define UBSEC_F_UBSEC_RSA_MOD_EXP_CRT 109
80
81/* Reason codes. */
82#define UBSEC_R_ALREADY_LOADED 100
83#define UBSEC_R_BN_EXPAND_FAIL 101
84#define UBSEC_R_CTRL_COMMAND_NOT_IMPLEMENTED 102
85#define UBSEC_R_DSO_FAILURE 103
86#define UBSEC_R_MISSING_KEY_COMPONENTS 104
87#define UBSEC_R_NOT_LOADED 105
88#define UBSEC_R_REQUEST_FAILED 106
89#define UBSEC_R_SIZE_TOO_LARGE_OR_TOO_SMALL 107
90#define UBSEC_R_UNIT_FAILURE 108
91
92#ifdef __cplusplus
93}
94#endif
95#endif
diff --git a/src/lib/libcrypto/engine/vendor_defns/aep.h b/src/lib/libcrypto/engine/vendor_defns/aep.h
new file mode 100644
index 0000000000..2b2792d2d6
--- /dev/null
+++ b/src/lib/libcrypto/engine/vendor_defns/aep.h
@@ -0,0 +1,178 @@
1/* This header declares the necessary definitions for using the exponentiation
2 * acceleration capabilities, and rnd number generation of the AEP card.
3 *
4 */
5
6/*
7 *
8 * Some AEP defines
9 *
10 */
11
12/*Successful return value*/
13#define AEP_R_OK 0x00000000
14
15/*Miscelleanous unsuccessful return value*/
16#define AEP_R_GENERAL_ERROR 0x10000001
17
18/*Insufficient host memory*/
19#define AEP_R_HOST_MEMORY 0x10000002
20
21#define AEP_R_FUNCTION_FAILED 0x10000006
22
23/*Invalid arguments in function call*/
24#define AEP_R_ARGUMENTS_BAD 0x10020000
25
26#define AEP_R_NO_TARGET_RESOURCES 0x10030000
27
28/*Error occuring on socket operation*/
29#define AEP_R_SOCKERROR 0x10000010
30
31/*Socket has been closed from the other end*/
32#define AEP_R_SOCKEOF 0x10000011
33
34/*Invalid handles*/
35#define AEP_R_CONNECTION_HANDLE_INVALID 0x100000B3
36
37#define AEP_R_TRANSACTION_HANDLE_INVALID 0x10040000
38
39/*Transaction has not yet returned from accelerator*/
40#define AEP_R_TRANSACTION_NOT_READY 0x00010000
41
42/*There is already a thread waiting on this transaction*/
43#define AEP_R_TRANSACTION_CLAIMED 0x10050000
44
45/*The transaction timed out*/
46#define AEP_R_TIMED_OUT 0x10060000
47
48#define AEP_R_FXN_NOT_IMPLEMENTED 0x10070000
49
50#define AEP_R_TARGET_ERROR 0x10080000
51
52/*Error in the AEP daemon process*/
53#define AEP_R_DAEMON_ERROR 0x10090000
54
55/*Invalid ctx id*/
56#define AEP_R_INVALID_CTX_ID 0x10009000
57
58#define AEP_R_NO_KEY_MANAGER 0x1000a000
59
60/*Error obtaining a mutex*/
61#define AEP_R_MUTEX_BAD 0x000001A0
62
63/*Fxn call before AEP_Initialise ot after AEP_Finialise*/
64#define AEP_R_AEPAPI_NOT_INITIALIZED 0x10000190
65
66/*AEP_Initialise has already been called*/
67#define AEP_R_AEPAPI_ALREADY_INITIALIZED 0x10000191
68
69/*Maximum number of connections to daemon reached*/
70#define AEP_R_NO_MORE_CONNECTION_HNDLS 0x10000200
71
72/*
73 *
74 * Some AEP Type definitions
75 *
76 */
77
78/* an unsigned 8-bit value */
79typedef unsigned char AEP_U8;
80
81/* an unsigned 8-bit character */
82typedef char AEP_CHAR;
83
84/* a BYTE-sized Boolean flag */
85typedef AEP_U8 AEP_BBOOL;
86
87/*Unsigned value, at least 16 bits long*/
88typedef unsigned short AEP_U16;
89
90/* an unsigned value, at least 32 bits long */
91#ifdef SIXTY_FOUR_BIT_LONG
92typedef unsigned int AEP_U32;
93#else
94typedef unsigned long AEP_U32;
95#endif
96
97#ifdef SIXTY_FOUR_BIT_LONG
98typedef unsigned long AEP_U64;
99#else
100typedef struct { unsigned long l1, l2; } AEP_U64;
101#endif
102
103/* at least 32 bits; each bit is a Boolean flag */
104typedef AEP_U32 AEP_FLAGS;
105
106typedef AEP_U8 *AEP_U8_PTR;
107typedef AEP_CHAR *AEP_CHAR_PTR;
108typedef AEP_U32 *AEP_U32_PTR;
109typedef AEP_U64 *AEP_U64_PTR;
110typedef void *AEP_VOID_PTR;
111
112/* Pointer to a AEP_VOID_PTR-- i.e., pointer to pointer to void */
113typedef AEP_VOID_PTR *AEP_VOID_PTR_PTR;
114
115/*Used to identify an AEP connection handle*/
116typedef AEP_U32 AEP_CONNECTION_HNDL;
117
118/*Pointer to an AEP connection handle*/
119typedef AEP_CONNECTION_HNDL *AEP_CONNECTION_HNDL_PTR;
120
121/*Used by an application (in conjunction with the apps process id) to
122identify an individual transaction*/
123typedef AEP_U32 AEP_TRANSACTION_ID;
124
125/*Pointer to an applications transaction identifier*/
126typedef AEP_TRANSACTION_ID *AEP_TRANSACTION_ID_PTR;
127
128/*Return value type*/
129typedef AEP_U32 AEP_RV;
130
131#define MAX_PROCESS_CONNECTIONS 256
132
133#define RAND_BLK_SIZE 1024
134
135typedef enum{
136 NotConnected= 0,
137 Connected= 1,
138 InUse= 2
139} AEP_CONNECTION_STATE;
140
141
142typedef struct AEP_CONNECTION_ENTRY{
143 AEP_CONNECTION_STATE conn_state;
144 AEP_CONNECTION_HNDL conn_hndl;
145} AEP_CONNECTION_ENTRY;
146
147
148typedef AEP_RV t_AEP_OpenConnection(AEP_CONNECTION_HNDL_PTR phConnection);
149typedef AEP_RV t_AEP_CloseConnection(AEP_CONNECTION_HNDL hConnection);
150
151typedef AEP_RV t_AEP_ModExp(AEP_CONNECTION_HNDL hConnection,
152 AEP_VOID_PTR pA, AEP_VOID_PTR pP,
153 AEP_VOID_PTR pN,
154 AEP_VOID_PTR pResult,
155 AEP_TRANSACTION_ID* pidTransID);
156
157typedef AEP_RV t_AEP_ModExpCrt(AEP_CONNECTION_HNDL hConnection,
158 AEP_VOID_PTR pA, AEP_VOID_PTR pP,
159 AEP_VOID_PTR pQ,
160 AEP_VOID_PTR pDmp1, AEP_VOID_PTR pDmq1,
161 AEP_VOID_PTR pIqmp,
162 AEP_VOID_PTR pResult,
163 AEP_TRANSACTION_ID* pidTransID);
164
165#ifdef AEPRAND
166typedef AEP_RV t_AEP_GenRandom(AEP_CONNECTION_HNDL hConnection,
167 AEP_U32 Len,
168 AEP_U32 Type,
169 AEP_VOID_PTR pResult,
170 AEP_TRANSACTION_ID* pidTransID);
171#endif
172
173typedef AEP_RV t_AEP_Initialize(AEP_VOID_PTR pInitArgs);
174typedef AEP_RV t_AEP_Finalize();
175typedef AEP_RV t_AEP_SetBNCallBacks(AEP_RV (*GetBigNumSizeFunc)(),
176 AEP_RV (*MakeAEPBigNumFunc)(),
177 AEP_RV (*ConverAEPBigNumFunc)());
178
diff --git a/src/lib/libcrypto/engine/vendor_defns/atalla.h b/src/lib/libcrypto/engine/vendor_defns/atalla.h
new file mode 100644
index 0000000000..8111649c54
--- /dev/null
+++ b/src/lib/libcrypto/engine/vendor_defns/atalla.h
@@ -0,0 +1,61 @@
1/* This header declares the necessary definitions for using the exponentiation
2 * acceleration capabilities of Atalla cards. The only cryptographic operation
3 * is performed by "ASI_RSAPrivateKeyOpFn" and this takes a structure that
4 * defines an "RSA private key". However, it is really only performing a
5 * regular mod_exp using the supplied modulus and exponent - no CRT form is
6 * being used. Hence, it is a generic mod_exp function in disguise, and we use
7 * it as such.
8 *
9 * Thanks to the people at Atalla for letting me know these definitions are
10 * fine and that they can be reproduced here.
11 *
12 * Geoff.
13 */
14
15typedef struct ItemStr
16 {
17 unsigned char *data;
18 int len;
19 } Item;
20
21typedef struct RSAPrivateKeyStr
22 {
23 void *reserved;
24 Item version;
25 Item modulus;
26 Item publicExponent;
27 Item privateExponent;
28 Item prime[2];
29 Item exponent[2];
30 Item coefficient;
31 } RSAPrivateKey;
32
33/* Predeclare the function pointer types that we dynamically load from the DSO.
34 * These use the same names and form that Ben's original support code had (in
35 * crypto/bn/bn_exp.c) unless of course I've inadvertently changed the style
36 * somewhere along the way!
37 */
38
39typedef int tfnASI_GetPerformanceStatistics(int reset_flag,
40 unsigned int *ret_buf);
41
42typedef int tfnASI_GetHardwareConfig(long card_num, unsigned int *ret_buf);
43
44typedef int tfnASI_RSAPrivateKeyOpFn(RSAPrivateKey * rsaKey,
45 unsigned char *output,
46 unsigned char *input,
47 unsigned int modulus_len);
48
49/* These are the static string constants for the DSO file name and the function
50 * symbol names to bind to. Regrettably, the DSO name on *nix appears to be
51 * "atasi.so" rather than something more consistent like "libatasi.so". At the
52 * time of writing, I'm not sure what the file name on win32 is but clearly
53 * native name translation is not possible (eg libatasi.so on *nix, and
54 * atasi.dll on win32). For the purposes of testing, I have created a symbollic
55 * link called "libatasi.so" so that we can use native name-translation - a
56 * better solution will be needed. */
57static const char *ATALLA_LIBNAME = "atasi";
58static const char *ATALLA_F1 = "ASI_GetHardwareConfig";
59static const char *ATALLA_F2 = "ASI_RSAPrivateKeyOpFn";
60static const char *ATALLA_F3 = "ASI_GetPerformanceStatistics";
61
diff --git a/src/lib/libcrypto/engine/vendor_defns/cswift.h b/src/lib/libcrypto/engine/vendor_defns/cswift.h
new file mode 100644
index 0000000000..0af14a1a92
--- /dev/null
+++ b/src/lib/libcrypto/engine/vendor_defns/cswift.h
@@ -0,0 +1,213 @@
1/* Attribution notice: Rainbow have generously allowed me to reproduce
2 * the necessary definitions here from their API. This means the support
3 * can build independently of whether application builders have the
4 * API or hardware. This will allow developers to easily produce software
5 * that has latent hardware support for any users that have accelertors
6 * installed, without the developers themselves needing anything extra.
7 *
8 * I have only clipped the parts from the CryptoSwift header files that
9 * are (or seem) relevant to the CryptoSwift support code. This is
10 * simply to keep the file sizes reasonable.
11 * [Geoff]
12 */
13
14
15/* NB: These type widths do *not* seem right in general, in particular
16 * they're not terribly friendly to 64-bit architectures (unsigned long)
17 * will be 64-bit on IA-64 for a start. I'm leaving these alone as they
18 * agree with Rainbow's API and this will only be called into question
19 * on platforms with Rainbow support anyway! ;-) */
20
21#ifdef __cplusplus
22extern "C" {
23#endif /* __cplusplus */
24
25typedef long SW_STATUS; /* status */
26typedef unsigned char SW_BYTE; /* 8 bit byte */
27typedef unsigned short SW_U16; /* 16 bit number */
28#if defined(_IRIX)
29#include <sgidefs.h>
30typedef __uint32_t SW_U32;
31#else
32typedef unsigned long SW_U32; /* 32 bit integer */
33#endif
34
35#if defined(WIN32)
36 typedef struct _SW_U64 {
37 SW_U32 low32;
38 SW_U32 high32;
39 } SW_U64; /* 64 bit integer */
40#elif defined(MAC)
41 typedef longlong SW_U64
42#else /* Unix variants */
43 typedef struct _SW_U64 {
44 SW_U32 low32;
45 SW_U32 high32;
46 } SW_U64; /* 64 bit integer */
47#endif
48
49/* status codes */
50#define SW_OK (0L)
51#define SW_ERR_BASE (-10000L)
52#define SW_ERR_NO_CARD (SW_ERR_BASE-1) /* The Card is not present */
53#define SW_ERR_CARD_NOT_READY (SW_ERR_BASE-2) /* The card has not powered */
54 /* up yet */
55#define SW_ERR_TIME_OUT (SW_ERR_BASE-3) /* Execution of a command */
56 /* time out */
57#define SW_ERR_NO_EXECUTE (SW_ERR_BASE-4) /* The Card failed to */
58 /* execute the command */
59#define SW_ERR_INPUT_NULL_PTR (SW_ERR_BASE-5) /* a required pointer is */
60 /* NULL */
61#define SW_ERR_INPUT_SIZE (SW_ERR_BASE-6) /* size is invalid, too */
62 /* small, too large. */
63#define SW_ERR_INVALID_HANDLE (SW_ERR_BASE-7) /* Invalid SW_ACC_CONTEXT */
64 /* handle */
65#define SW_ERR_PENDING (SW_ERR_BASE-8) /* A request is already out- */
66 /* standing at this */
67 /* context handle */
68#define SW_ERR_AVAILABLE (SW_ERR_BASE-9) /* A result is available. */
69#define SW_ERR_NO_PENDING (SW_ERR_BASE-10)/* No request is pending. */
70#define SW_ERR_NO_MEMORY (SW_ERR_BASE-11)/* Not enough memory */
71#define SW_ERR_BAD_ALGORITHM (SW_ERR_BASE-12)/* Invalid algorithm type */
72 /* in SW_PARAM structure */
73#define SW_ERR_MISSING_KEY (SW_ERR_BASE-13)/* No key is associated with */
74 /* context. */
75 /* swAttachKeyParam() is */
76 /* not called. */
77#define SW_ERR_KEY_CMD_MISMATCH \
78 (SW_ERR_BASE-14)/* Cannot perform requested */
79 /* SW_COMMAND_CODE since */
80 /* key attached via */
81 /* swAttachKeyParam() */
82 /* cannot be used for this*/
83 /* SW_COMMAND_CODE. */
84#define SW_ERR_NOT_IMPLEMENTED \
85 (SW_ERR_BASE-15)/* Not implemented */
86#define SW_ERR_BAD_COMMAND (SW_ERR_BASE-16)/* Bad command code */
87#define SW_ERR_BAD_ITEM_SIZE (SW_ERR_BASE-17)/* too small or too large in */
88 /* the "initems" or */
89 /* "outitems". */
90#define SW_ERR_BAD_ACCNUM (SW_ERR_BASE-18)/* Bad accelerator number */
91#define SW_ERR_SELFTEST_FAIL (SW_ERR_BASE-19)/* At least one of the self */
92 /* test fail, look at the */
93 /* selfTestBitmap in */
94 /* SW_ACCELERATOR_INFO for*/
95 /* details. */
96#define SW_ERR_MISALIGN (SW_ERR_BASE-20)/* Certain alogrithms require*/
97 /* key materials aligned */
98 /* in certain order, e.g. */
99 /* 128 bit for CRT */
100#define SW_ERR_OUTPUT_NULL_PTR \
101 (SW_ERR_BASE-21)/* a required pointer is */
102 /* NULL */
103#define SW_ERR_OUTPUT_SIZE \
104 (SW_ERR_BASE-22)/* size is invalid, too */
105 /* small, too large. */
106#define SW_ERR_FIRMWARE_CHECKSUM \
107 (SW_ERR_BASE-23)/* firmware checksum mismatch*/
108 /* download failed. */
109#define SW_ERR_UNKNOWN_FIRMWARE \
110 (SW_ERR_BASE-24)/* unknown firmware error */
111#define SW_ERR_INTERRUPT (SW_ERR_BASE-25)/* request is abort when */
112 /* it's waiting to be */
113 /* completed. */
114#define SW_ERR_NVWRITE_FAIL (SW_ERR_BASE-26)/* error in writing to Non- */
115 /* volatile memory */
116#define SW_ERR_NVWRITE_RANGE (SW_ERR_BASE-27)/* out of range error in */
117 /* writing to NV memory */
118#define SW_ERR_RNG_ERROR (SW_ERR_BASE-28)/* Random Number Generation */
119 /* failure */
120#define SW_ERR_DSS_FAILURE (SW_ERR_BASE-29)/* DSS Sign or Verify failure*/
121#define SW_ERR_MODEXP_FAILURE (SW_ERR_BASE-30)/* Failure in various math */
122 /* calculations */
123#define SW_ERR_ONBOARD_MEMORY (SW_ERR_BASE-31)/* Error in accessing on - */
124 /* board memory */
125#define SW_ERR_FIRMWARE_VERSION \
126 (SW_ERR_BASE-32)/* Wrong version in firmware */
127 /* update */
128#define SW_ERR_ZERO_WORKING_ACCELERATOR \
129 (SW_ERR_BASE-44)/* All accelerators are bad */
130
131
132 /* algorithm type */
133#define SW_ALG_CRT 1
134#define SW_ALG_EXP 2
135#define SW_ALG_DSA 3
136#define SW_ALG_NVDATA 4
137
138 /* command code */
139#define SW_CMD_MODEXP_CRT 1 /* perform Modular Exponentiation using */
140 /* Chinese Remainder Theorem (CRT) */
141#define SW_CMD_MODEXP 2 /* perform Modular Exponentiation */
142#define SW_CMD_DSS_SIGN 3 /* perform DSS sign */
143#define SW_CMD_DSS_VERIFY 4 /* perform DSS verify */
144#define SW_CMD_RAND 5 /* perform random number generation */
145#define SW_CMD_NVREAD 6 /* perform read to nonvolatile RAM */
146#define SW_CMD_NVWRITE 7 /* perform write to nonvolatile RAM */
147
148typedef SW_U32 SW_ALGTYPE; /* alogrithm type */
149typedef SW_U32 SW_STATE; /* state */
150typedef SW_U32 SW_COMMAND_CODE; /* command code */
151typedef SW_U32 SW_COMMAND_BITMAP[4]; /* bitmap */
152
153typedef struct _SW_LARGENUMBER {
154 SW_U32 nbytes; /* number of bytes in the buffer "value" */
155 SW_BYTE* value; /* the large integer as a string of */
156 /* bytes in network (big endian) order */
157} SW_LARGENUMBER;
158
159typedef struct _SW_CRT {
160 SW_LARGENUMBER p; /* prime number p */
161 SW_LARGENUMBER q; /* prime number q */
162 SW_LARGENUMBER dmp1; /* exponent1 */
163 SW_LARGENUMBER dmq1; /* exponent2 */
164 SW_LARGENUMBER iqmp; /* CRT coefficient */
165} SW_CRT;
166
167typedef struct _SW_EXP {
168 SW_LARGENUMBER modulus; /* modulus */
169 SW_LARGENUMBER exponent;/* exponent */
170} SW_EXP;
171
172typedef struct _SW_DSA {
173 SW_LARGENUMBER p; /* */
174 SW_LARGENUMBER q; /* */
175 SW_LARGENUMBER g; /* */
176 SW_LARGENUMBER key; /* private/public key */
177} SW_DSA;
178
179typedef struct _SW_NVDATA {
180 SW_U32 accnum; /* accelerator board number */
181 SW_U32 offset; /* offset in byte */
182} SW_NVDATA;
183
184typedef struct _SW_PARAM {
185 SW_ALGTYPE type; /* type of the alogrithm */
186 union {
187 SW_CRT crt;
188 SW_EXP exp;
189 SW_DSA dsa;
190 SW_NVDATA nvdata;
191 } up;
192} SW_PARAM;
193
194typedef SW_U32 SW_CONTEXT_HANDLE; /* opaque context handle */
195
196
197/* Now the OpenSSL bits, these function types are the for the function
198 * pointers that will bound into the Rainbow shared libraries. */
199typedef SW_STATUS t_swAcquireAccContext(SW_CONTEXT_HANDLE *hac);
200typedef SW_STATUS t_swAttachKeyParam(SW_CONTEXT_HANDLE hac,
201 SW_PARAM *key_params);
202typedef SW_STATUS t_swSimpleRequest(SW_CONTEXT_HANDLE hac,
203 SW_COMMAND_CODE cmd,
204 SW_LARGENUMBER pin[],
205 SW_U32 pin_count,
206 SW_LARGENUMBER pout[],
207 SW_U32 pout_count);
208typedef SW_STATUS t_swReleaseAccContext(SW_CONTEXT_HANDLE hac);
209
210#ifdef __cplusplus
211}
212#endif /* __cplusplus */
213
diff --git a/src/lib/libcrypto/engine/vendor_defns/hw_4758_cca.h b/src/lib/libcrypto/engine/vendor_defns/hw_4758_cca.h
new file mode 100644
index 0000000000..296636e81a
--- /dev/null
+++ b/src/lib/libcrypto/engine/vendor_defns/hw_4758_cca.h
@@ -0,0 +1,149 @@
1/**********************************************************************/
2/* */
3/* Prototypes of the CCA verbs used by the 4758 CCA openssl driver */
4/* */
5/* Maurice Gittens <maurice@gittens.nl> */
6/* */
7/**********************************************************************/
8
9#ifndef __HW_4758_CCA__
10#define __HW_4758_CCA__
11
12/*
13 * Only WIN32 support for now
14 */
15#if defined(WIN32)
16
17 #define CCA_LIB_NAME "CSUNSAPI"
18
19 #define CSNDPKX "CSNDPKX_32"
20 #define CSNDKRR "CSNDKRR_32"
21 #define CSNDPKE "CSNDPKE_32"
22 #define CSNDPKD "CSNDPKD_32"
23 #define CSNDDSV "CSNDDSV_32"
24 #define CSNDDSG "CSNDDSG_32"
25 #define CSNBRNG "CSNBRNG_32"
26
27 #define SECURITYAPI __stdcall
28#else
29 /* Fixme!!
30 Find out the values of these constants for other platforms.
31 */
32 #define CCA_LIB_NAME "CSUNSAPI"
33
34 #define CSNDPKX "CSNDPKX"
35 #define CSNDKRR "CSNDKRR"
36 #define CSNDPKE "CSNDPKE"
37 #define CSNDPKD "CSNDPKD"
38 #define CSNDDSV "CSNDDSV"
39 #define CSNDDSG "CSNDDSG"
40 #define CSNBRNG "CSNBRNG"
41
42 #define SECURITYAPI
43#endif
44
45/*
46 * security API prototypes
47 */
48
49/* PKA Key Record Read */
50typedef void (SECURITYAPI *F_KEYRECORDREAD)
51 (long * return_code,
52 long * reason_code,
53 long * exit_data_length,
54 unsigned char * exit_data,
55 long * rule_array_count,
56 unsigned char * rule_array,
57 unsigned char * key_label,
58 long * key_token_length,
59 unsigned char * key_token);
60
61/* Random Number Generate */
62typedef void (SECURITYAPI *F_RANDOMNUMBERGENERATE)
63 (long * return_code,
64 long * reason_code,
65 long * exit_data_length,
66 unsigned char * exit_data,
67 unsigned char * form,
68 unsigned char * random_number);
69
70/* Digital Signature Generate */
71typedef void (SECURITYAPI *F_DIGITALSIGNATUREGENERATE)
72 (long * return_code,
73 long * reason_code,
74 long * exit_data_length,
75 unsigned char * exit_data,
76 long * rule_array_count,
77 unsigned char * rule_array,
78 long * PKA_private_key_id_length,
79 unsigned char * PKA_private_key_id,
80 long * hash_length,
81 unsigned char * hash,
82 long * signature_field_length,
83 long * signature_bit_length,
84 unsigned char * signature_field);
85
86/* Digital Signature Verify */
87typedef void (SECURITYAPI *F_DIGITALSIGNATUREVERIFY)(
88 long * return_code,
89 long * reason_code,
90 long * exit_data_length,
91 unsigned char * exit_data,
92 long * rule_array_count,
93 unsigned char * rule_array,
94 long * PKA_public_key_id_length,
95 unsigned char * PKA_public_key_id,
96 long * hash_length,
97 unsigned char * hash,
98 long * signature_field_length,
99 unsigned char * signature_field);
100
101/* PKA Public Key Extract */
102typedef void (SECURITYAPI *F_PUBLICKEYEXTRACT)(
103 long * return_code,
104 long * reason_code,
105 long * exit_data_length,
106 unsigned char * exit_data,
107 long * rule_array_count,
108 unsigned char * rule_array,
109 long * source_key_identifier_length,
110 unsigned char * source_key_identifier,
111 long * target_key_token_length,
112 unsigned char * target_key_token);
113
114/* PKA Encrypt */
115typedef void (SECURITYAPI *F_PKAENCRYPT)
116 (long * return_code,
117 long * reason_code,
118 long * exit_data_length,
119 unsigned char * exit_data,
120 long * rule_array_count,
121 unsigned char * rule_array,
122 long * key_value_length,
123 unsigned char * key_value,
124 long * data_struct_length,
125 unsigned char * data_struct,
126 long * RSA_public_key_length,
127 unsigned char * RSA_public_key,
128 long * RSA_encipher_length,
129 unsigned char * RSA_encipher );
130
131/* PKA Decrypt */
132typedef void (SECURITYAPI *F_PKADECRYPT)
133 (long * return_code,
134 long * reason_code,
135 long * exit_data_length,
136 unsigned char * exit_data,
137 long * rule_array_count,
138 unsigned char * rule_array,
139 long * enciphered_key_length,
140 unsigned char * enciphered_key,
141 long * data_struct_length,
142 unsigned char * data_struct,
143 long * RSA_private_key_length,
144 unsigned char * RSA_private_key,
145 long * key_value_length,
146 unsigned char * key_value );
147
148
149#endif