1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59: #include <stdio.h>
60: #include <string.h>
61: #include <openssl/crypto.h>
62: #include <openssl/buffer.h>
63: #include <openssl/dso.h>
64: #include <openssl/engine.h>
65: #ifndef OPENSSL_NO_RSA
66: #include <openssl/rsa.h>
67: #endif
68: #ifndef OPENSSL_NO_DSA
69: #include <openssl/dsa.h>
70: #endif
71: #ifndef OPENSSL_NO_DH
72: #include <openssl/dh.h>
73: #endif
74: #include <openssl/bn.h>
75:
76: #ifndef OPENSSL_NO_HW
77: #ifndef OPENSSL_NO_HW_NURON
78:
79: #define NURON_LIB_NAME "nuron engine"
80: #include "e_nuron_err.c"
81:
82: static const char *NURON_LIBNAME = NULL;
83: static const char *get_NURON_LIBNAME(void)
84: {
85: if(NURON_LIBNAME)
86: return NURON_LIBNAME;
87: return "nuronssl";
88: }
89: static void free_NURON_LIBNAME(void)
90: {
91: if(NURON_LIBNAME)
92: OPENSSL_free((void*)NURON_LIBNAME);
93: NURON_LIBNAME = NULL;
94: }
95: static long set_NURON_LIBNAME(const char *name)
96: {
97: free_NURON_LIBNAME();
98: return (((NURON_LIBNAME = BUF_strdup(name)) != NULL) ? 1 : 0);
99: }
100: static const char *NURON_F1 = "nuron_mod_exp";
101:
102:
103: #define NURON_CMD_SO_PATH ENGINE_CMD_BASE
104: static const ENGINE_CMD_DEFN nuron_cmd_defns[] = {
105: {NURON_CMD_SO_PATH,
106: "SO_PATH",
107: "Specifies the path to the 'nuronssl' shared library",
108: ENGINE_CMD_FLAG_STRING},
109: {0, NULL, NULL, 0}
110: };
111:
112: typedef int tfnModExp(BIGNUM *r,const BIGNUM *a,const BIGNUM *p,const BIGNUM *m);
113: static tfnModExp *pfnModExp = NULL;
114:
115: static DSO *pvDSOHandle = NULL;
116:
117: static int nuron_destroy(ENGINE *e)
118: {
119: free_NURON_LIBNAME();
120: ERR_unload_NURON_strings();
121: return 1;
122: }
123:
124: static int nuron_init(ENGINE *e)
125: {
126: if(pvDSOHandle != NULL)
127: {
128: NURONerr(NURON_F_NURON_INIT,NURON_R_ALREADY_LOADED);
129: return 0;
130: }
131:
132: pvDSOHandle = DSO_load(NULL, get_NURON_LIBNAME(), NULL,
133: DSO_FLAG_NAME_TRANSLATION_EXT_ONLY);
134: if(!pvDSOHandle)
135: {
136: NURONerr(NURON_F_NURON_INIT,NURON_R_DSO_NOT_FOUND);
137: return 0;
138: }
139:
140: pfnModExp = (tfnModExp *)DSO_bind_func(pvDSOHandle, NURON_F1);
141: if(!pfnModExp)
142: {
143: NURONerr(NURON_F_NURON_INIT,NURON_R_DSO_FUNCTION_NOT_FOUND);
144: return 0;
145: }
146:
147: return 1;
148: }
149:
150: static int nuron_finish(ENGINE *e)
151: {
152: free_NURON_LIBNAME();
153: if(pvDSOHandle == NULL)
154: {
155: NURONerr(NURON_F_NURON_FINISH,NURON_R_NOT_LOADED);
156: return 0;
157: }
158: if(!DSO_free(pvDSOHandle))
159: {
160: NURONerr(NURON_F_NURON_FINISH,NURON_R_DSO_FAILURE);
161: return 0;
162: }
163: pvDSOHandle=NULL;
164: pfnModExp=NULL;
165: return 1;
166: }
167:
168: static int nuron_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void))
169: {
170: int initialised = ((pvDSOHandle == NULL) ? 0 : 1);
171: switch(cmd)
172: {
173: case NURON_CMD_SO_PATH:
174: if(p == NULL)
175: {
176: NURONerr(NURON_F_NURON_CTRL,ERR_R_PASSED_NULL_PARAMETER);
177: return 0;
178: }
179: if(initialised)
180: {
181: NURONerr(NURON_F_NURON_CTRL,NURON_R_ALREADY_LOADED);
182: return 0;
183: }
184: return set_NURON_LIBNAME((const char *)p);
185: default:
186: break;
187: }
188: NURONerr(NURON_F_NURON_CTRL,NURON_R_CTRL_COMMAND_NOT_IMPLEMENTED);
189: return 0;
190: }
191:
192: static int nuron_mod_exp(BIGNUM *r,const BIGNUM *a,const BIGNUM *p,
193: const BIGNUM *m,BN_CTX *ctx)
194: {
195: if(!pvDSOHandle)
196: {
197: NURONerr(NURON_F_NURON_MOD_EXP,NURON_R_NOT_LOADED);
198: return 0;
199: }
200: return pfnModExp(r,a,p,m);
201: }
202:
203: #ifndef OPENSSL_NO_RSA
204: static int nuron_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
205: {
206: return nuron_mod_exp(r0,I,rsa->d,rsa->n,ctx);
207: }
208: #endif
209:
210: #ifndef OPENSSL_NO_DSA
211:
212:
213:
214:
215:
216:
217:
218: static int nuron_dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1,
219: BIGNUM *p1, BIGNUM *a2, BIGNUM *p2, BIGNUM *m,
220: BN_CTX *ctx, BN_MONT_CTX *in_mont)
221: {
222: BIGNUM t;
223: int to_return = 0;
224:
225: BN_init(&t);
226:
227: if (!nuron_mod_exp(rr,a1,p1,m,ctx))
228: goto end;
229:
230: if (!nuron_mod_exp(&t,a2,p2,m,ctx))
231: goto end;
232:
233: if (!BN_mod_mul(rr,rr,&t,m,ctx))
234: goto end;
235: to_return = 1;
236: end:
237: BN_free(&t);
238: return to_return;
239: }
240:
241:
242: static int nuron_mod_exp_dsa(DSA *dsa, BIGNUM *r, BIGNUM *a,
243: const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
244: BN_MONT_CTX *m_ctx)
245: {
246: return nuron_mod_exp(r, a, p, m, ctx);
247: }
248: #endif
249:
250:
251: #ifndef OPENSSL_NO_RSA
252: static int nuron_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
253: const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
254: {
255: return nuron_mod_exp(r, a, p, m, ctx);
256: }
257: #endif
258:
259: #ifndef OPENSSL_NO_DH
260:
261: static int nuron_mod_exp_dh(const DH *dh, BIGNUM *r,
262: const BIGNUM *a, const BIGNUM *p,
263: const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
264: {
265: return nuron_mod_exp(r, a, p, m, ctx);
266: }
267: #endif
268:
269: #ifndef OPENSSL_NO_RSA
270: static RSA_METHOD nuron_rsa =
271: {
272: "Nuron RSA method",
273: NULL,
274: NULL,
275: NULL,
276: NULL,
277: nuron_rsa_mod_exp,
278: nuron_mod_exp_mont,
279: NULL,
280: NULL,
281: 0,
282: NULL,
283: NULL,
284: NULL,
285: NULL
286: };
287: #endif
288:
289: #ifndef OPENSSL_NO_DSA
290: static DSA_METHOD nuron_dsa =
291: {
292: "Nuron DSA method",
293: NULL,
294: NULL,
295: NULL,
296: nuron_dsa_mod_exp,
297: nuron_mod_exp_dsa,
298: NULL,
299: NULL,
300: 0,
301: NULL,
302: NULL,
303: NULL
304: };
305: #endif
306:
307: #ifndef OPENSSL_NO_DH
308: static DH_METHOD nuron_dh =
309: {
310: "Nuron DH method",
311: NULL,
312: NULL,
313: nuron_mod_exp_dh,
314: NULL,
315: NULL,
316: 0,
317: NULL,
318: NULL
319: };
320: #endif
321:
322:
323: static const char *engine_nuron_id = "nuron";
324: static const char *engine_nuron_name = "Nuron hardware engine support";
325:
326:
327:
328: static int bind_helper(ENGINE *e)
329: {
330: #ifndef OPENSSL_NO_RSA
331: const RSA_METHOD *meth1;
332: #endif
333: #ifndef OPENSSL_NO_DSA
334: const DSA_METHOD *meth2;
335: #endif
336: #ifndef OPENSSL_NO_DH
337: const DH_METHOD *meth3;
338: #endif
339: if(!ENGINE_set_id(e, engine_nuron_id) ||
340: !ENGINE_set_name(e, engine_nuron_name) ||
341: #ifndef OPENSSL_NO_RSA
342: !ENGINE_set_RSA(e, &nuron_rsa) ||
343: #endif
344: #ifndef OPENSSL_NO_DSA
345: !ENGINE_set_DSA(e, &nuron_dsa) ||
346: #endif
347: #ifndef OPENSSL_NO_DH
348: !ENGINE_set_DH(e, &nuron_dh) ||
349: #endif
350: !ENGINE_set_destroy_function(e, nuron_destroy) ||
351: !ENGINE_set_init_function(e, nuron_init) ||
352: !ENGINE_set_finish_function(e, nuron_finish) ||
353: !ENGINE_set_ctrl_function(e, nuron_ctrl) ||
354: !ENGINE_set_cmd_defns(e, nuron_cmd_defns))
355: return 0;
356:
357: #ifndef OPENSSL_NO_RSA
358:
359:
360:
361:
362:
363:
364:
365: meth1=RSA_PKCS1_SSLeay();
366: nuron_rsa.rsa_pub_enc=meth1->rsa_pub_enc;
367: nuron_rsa.rsa_pub_dec=meth1->rsa_pub_dec;
368: nuron_rsa.rsa_priv_enc=meth1->rsa_priv_enc;
369: nuron_rsa.rsa_priv_dec=meth1->rsa_priv_dec;
370: #endif
371:
372: #ifndef OPENSSL_NO_DSA
373:
374:
375: meth2=DSA_OpenSSL();
376: nuron_dsa.dsa_do_sign=meth2->dsa_do_sign;
377: nuron_dsa.dsa_sign_setup=meth2->dsa_sign_setup;
378: nuron_dsa.dsa_do_verify=meth2->dsa_do_verify;
379: #endif
380:
381: #ifndef OPENSSL_NO_DH
382:
383: meth3=DH_OpenSSL();
384: nuron_dh.generate_key=meth3->generate_key;
385: nuron_dh.compute_key=meth3->compute_key;
386: #endif
387:
388:
389: ERR_load_NURON_strings();
390: return 1;
391: }
392:
393: #ifdef OPENSSL_NO_DYNAMIC_ENGINE
394: static ENGINE *engine_nuron(void)
395: {
396: ENGINE *ret = ENGINE_new();
397: if(!ret)
398: return NULL;
399: if(!bind_helper(ret))
400: {
401: ENGINE_free(ret);
402: return NULL;
403: }
404: return ret;
405: }
406:
407: void ENGINE_load_nuron(void)
408: {
409:
410: ENGINE *toadd = engine_nuron();
411: if(!toadd) return;
412: ENGINE_add(toadd);
413: ENGINE_free(toadd);
414: ERR_clear_error();
415: }
416: #endif
417:
418:
419:
420: #ifndef OPENSSL_NO_DYNAMIC_ENGINE
421: static int bind_fn(ENGINE *e, const char *id)
422: {
423: if(id && (strcmp(id, engine_nuron_id) != 0))
424: return 0;
425: if(!bind_helper(e))
426: return 0;
427: return 1;
428: }
429: IMPLEMENT_DYNAMIC_CHECK_FN()
430: IMPLEMENT_DYNAMIC_BIND_FN(bind_fn)
431: #endif
432:
433: #endif
434: #endif