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:
60: #include <stdio.h>
61: #include <string.h>
62: #include <openssl/crypto.h>
63: #include <openssl/pem.h>
64: #include <openssl/dso.h>
65: #include <openssl/engine.h>
66: #include <openssl/ui.h>
67: #include <openssl/rand.h>
68: #ifndef OPENSSL_NO_RSA
69: #include <openssl/rsa.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_CHIL
78:
79:
80:
81:
82:
83:
84:
85:
86:
87: #ifdef FLAT_INC
88: #include "hwcryptohook.h"
89: #else
90: #include "vendor_defns/hwcryptohook.h"
91: #endif
92:
93: #define HWCRHK_LIB_NAME "CHIL engine"
94: #include "e_chil_err.c"
95:
96: static int hwcrhk_destroy(ENGINE *e);
97: static int hwcrhk_init(ENGINE *e);
98: static int hwcrhk_finish(ENGINE *e);
99: static int hwcrhk_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void));
100:
101:
102: static int hwcrhk_mutex_init(HWCryptoHook_Mutex*, HWCryptoHook_CallerContext*);
103: static int hwcrhk_mutex_lock(HWCryptoHook_Mutex*);
104: static void hwcrhk_mutex_unlock(HWCryptoHook_Mutex*);
105: static void hwcrhk_mutex_destroy(HWCryptoHook_Mutex*);
106:
107:
108: static int hwcrhk_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
109: const BIGNUM *m, BN_CTX *ctx);
110:
111: #ifndef OPENSSL_NO_RSA
112:
113: static int hwcrhk_rsa_mod_exp(BIGNUM *r, const BIGNUM *I, RSA *rsa, BN_CTX *ctx);
114: #endif
115: #ifndef OPENSSL_NO_RSA
116:
117: static int hwcrhk_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
118: const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
119: #endif
120:
121: #ifndef OPENSSL_NO_DH
122:
123:
124: static int hwcrhk_mod_exp_dh(const DH *dh, BIGNUM *r,
125: const BIGNUM *a, const BIGNUM *p,
126: const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
127: #endif
128:
129:
130: static int hwcrhk_rand_bytes(unsigned char *buf, int num);
131: static int hwcrhk_rand_status(void);
132:
133:
134: static EVP_PKEY *hwcrhk_load_privkey(ENGINE *eng, const char *key_id,
135: UI_METHOD *ui_method, void *callback_data);
136: static EVP_PKEY *hwcrhk_load_pubkey(ENGINE *eng, const char *key_id,
137: UI_METHOD *ui_method, void *callback_data);
138: #ifndef OPENSSL_NO_RSA
139: static void hwcrhk_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad,
140: int ind,long argl, void *argp);
141: #endif
142:
143:
144: static int hwcrhk_insert_card(const char *prompt_info,
145: const char *wrong_info,
146: HWCryptoHook_PassphraseContext *ppctx,
147: HWCryptoHook_CallerContext *cactx);
148: static int hwcrhk_get_pass(const char *prompt_info,
149: int *len_io, char *buf,
150: HWCryptoHook_PassphraseContext *ppctx,
151: HWCryptoHook_CallerContext *cactx);
152: static void hwcrhk_log_message(void *logstr, const char *message);
153:
154:
155: #define HWCRHK_CMD_SO_PATH ENGINE_CMD_BASE
156: #define HWCRHK_CMD_FORK_CHECK (ENGINE_CMD_BASE + 1)
157: #define HWCRHK_CMD_THREAD_LOCKING (ENGINE_CMD_BASE + 2)
158: #define HWCRHK_CMD_SET_USER_INTERFACE (ENGINE_CMD_BASE + 3)
159: #define HWCRHK_CMD_SET_CALLBACK_DATA (ENGINE_CMD_BASE + 4)
160: static const ENGINE_CMD_DEFN hwcrhk_cmd_defns[] = {
161: {HWCRHK_CMD_SO_PATH,
162: "SO_PATH",
163: "Specifies the path to the 'hwcrhk' shared library",
164: ENGINE_CMD_FLAG_STRING},
165: {HWCRHK_CMD_FORK_CHECK,
166: "FORK_CHECK",
167: "Turns fork() checking on or off (boolean)",
168: ENGINE_CMD_FLAG_NUMERIC},
169: {HWCRHK_CMD_THREAD_LOCKING,
170: "THREAD_LOCKING",
171: "Turns thread-safe locking on or off (boolean)",
172: ENGINE_CMD_FLAG_NUMERIC},
173: {HWCRHK_CMD_SET_USER_INTERFACE,
174: "SET_USER_INTERFACE",
175: "Set the global user interface (internal)",
176: ENGINE_CMD_FLAG_INTERNAL},
177: {HWCRHK_CMD_SET_CALLBACK_DATA,
178: "SET_CALLBACK_DATA",
179: "Set the global user interface extra data (internal)",
180: ENGINE_CMD_FLAG_INTERNAL},
181: {0, NULL, NULL, 0}
182: };
183:
184: #ifndef OPENSSL_NO_RSA
185:
186: static RSA_METHOD hwcrhk_rsa =
187: {
188: "CHIL RSA method",
189: NULL,
190: NULL,
191: NULL,
192: NULL,
193: hwcrhk_rsa_mod_exp,
194: hwcrhk_mod_exp_mont,
195: NULL,
196: NULL,
197: 0,
198: NULL,
199: NULL,
200: NULL,
201: NULL
202: };
203: #endif
204:
205: #ifndef OPENSSL_NO_DH
206:
207: static DH_METHOD hwcrhk_dh =
208: {
209: "CHIL DH method",
210: NULL,
211: NULL,
212: hwcrhk_mod_exp_dh,
213: NULL,
214: NULL,
215: 0,
216: NULL,
217: NULL
218: };
219: #endif
220:
221: static RAND_METHOD hwcrhk_rand =
222: {
223:
224: NULL,
225: hwcrhk_rand_bytes,
226: NULL,
227: NULL,
228: hwcrhk_rand_bytes,
229: hwcrhk_rand_status,
230: };
231:
232:
233: static const char *engine_hwcrhk_id = "chil";
234: static const char *engine_hwcrhk_name = "CHIL hardware engine support";
235:
236: #ifndef OPENSSL_NO_DYNAMIC_ENGINE
237:
238: static const char *engine_hwcrhk_id_alt = "ncipher";
239: #endif
240:
241:
242:
243:
244:
245:
246: struct HWCryptoHook_MutexValue
247: {
248: int lockid;
249: };
250:
251:
252:
253:
254: struct HWCryptoHook_PassphraseContextValue
255: {
256: UI_METHOD *ui_method;
257: void *callback_data;
258: };
259:
260:
261:
262:
263: struct HWCryptoHook_CallerContextValue
264: {
265: pem_password_cb *password_callback;
266:
267: UI_METHOD *ui_method;
268: void *callback_data;
269: };
270:
271:
272:
273: #define BN2MPI(mp, bn) \
274: {mp.size = bn->top * sizeof(BN_ULONG); mp.buf = (unsigned char *)bn->d;}
275: #define MPI2BN(bn, mp) \
276: {mp.size = bn->dmax * sizeof(BN_ULONG); mp.buf = (unsigned char *)bn->d;}
277:
278: static BIO *logstream = NULL;
279: static int disable_mutex_callbacks = 0;
280:
281:
282:
283:
284:
285:
286:
287:
288:
289:
290:
291:
292:
293:
294: static HWCryptoHook_CallerContext password_context = { NULL, NULL, NULL };
295:
296:
297: static HWCryptoHook_InitInfo hwcrhk_globals = {
298: HWCryptoHook_InitFlags_SimpleForkCheck,
299: &logstream,
300: sizeof(BN_ULONG),
301: 0,
302: -1,
303: 0,
304: 0,
305:
306:
307:
308:
309:
310:
311:
312:
313: sizeof(HWCryptoHook_Mutex),
314: 0,
315: 0,
316: 0,
317: 0,
318:
319:
320:
321:
322:
323:
324: 0,
325: 0,
326: 0,
327: 0,
328: 0,
329: 0,
330:
331: hwcrhk_get_pass,
332: hwcrhk_insert_card,
333: hwcrhk_log_message
334: };
335:
336:
337:
338:
339:
340:
341: static int bind_helper(ENGINE *e)
342: {
343: #ifndef OPENSSL_NO_RSA
344: const RSA_METHOD *meth1;
345: #endif
346: #ifndef OPENSSL_NO_DH
347: const DH_METHOD *meth2;
348: #endif
349: if(!ENGINE_set_id(e, engine_hwcrhk_id) ||
350: !ENGINE_set_name(e, engine_hwcrhk_name) ||
351: #ifndef OPENSSL_NO_RSA
352: !ENGINE_set_RSA(e, &hwcrhk_rsa) ||
353: #endif
354: #ifndef OPENSSL_NO_DH
355: !ENGINE_set_DH(e, &hwcrhk_dh) ||
356: #endif
357: !ENGINE_set_RAND(e, &hwcrhk_rand) ||
358: !ENGINE_set_destroy_function(e, hwcrhk_destroy) ||
359: !ENGINE_set_init_function(e, hwcrhk_init) ||
360: !ENGINE_set_finish_function(e, hwcrhk_finish) ||
361: !ENGINE_set_ctrl_function(e, hwcrhk_ctrl) ||
362: !ENGINE_set_load_privkey_function(e, hwcrhk_load_privkey) ||
363: !ENGINE_set_load_pubkey_function(e, hwcrhk_load_pubkey) ||
364: !ENGINE_set_cmd_defns(e, hwcrhk_cmd_defns))
365: return 0;
366:
367: #ifndef OPENSSL_NO_RSA
368:
369:
370:
371:
372:
373:
374:
375: meth1 = RSA_PKCS1_SSLeay();
376: hwcrhk_rsa.rsa_pub_enc = meth1->rsa_pub_enc;
377: hwcrhk_rsa.rsa_pub_dec = meth1->rsa_pub_dec;
378: hwcrhk_rsa.rsa_priv_enc = meth1->rsa_priv_enc;
379: hwcrhk_rsa.rsa_priv_dec = meth1->rsa_priv_dec;
380: #endif
381:
382: #ifndef OPENSSL_NO_DH
383:
384: meth2 = DH_OpenSSL();
385: hwcrhk_dh.generate_key = meth2->generate_key;
386: hwcrhk_dh.compute_key = meth2->compute_key;
387: #endif
388:
389:
390: ERR_load_HWCRHK_strings();
391: return 1;
392: }
393:
394: #ifdef OPENSSL_NO_DYNAMIC_ENGINE
395: static ENGINE *engine_chil(void)
396: {
397: ENGINE *ret = ENGINE_new();
398: if(!ret)
399: return NULL;
400: if(!bind_helper(ret))
401: {
402: ENGINE_free(ret);
403: return NULL;
404: }
405: return ret;
406: }
407:
408: void ENGINE_load_chil(void)
409: {
410:
411: ENGINE *toadd = engine_chil();
412: if(!toadd) return;
413: ENGINE_add(toadd);
414: ENGINE_free(toadd);
415: ERR_clear_error();
416: }
417: #endif
418:
419:
420:
421:
422:
423:
424: static DSO *hwcrhk_dso = NULL;
425: static HWCryptoHook_ContextHandle hwcrhk_context = 0;
426: #ifndef OPENSSL_NO_RSA
427: static int hndidx_rsa = -1;
428: #endif
429:
430:
431:
432: static HWCryptoHook_Init_t *p_hwcrhk_Init = NULL;
433: static HWCryptoHook_Finish_t *p_hwcrhk_Finish = NULL;
434: static HWCryptoHook_ModExp_t *p_hwcrhk_ModExp = NULL;
435: #ifndef OPENSSL_NO_RSA
436: static HWCryptoHook_RSA_t *p_hwcrhk_RSA = NULL;
437: #endif
438: static HWCryptoHook_RandomBytes_t *p_hwcrhk_RandomBytes = NULL;
439: #ifndef OPENSSL_NO_RSA
440: static HWCryptoHook_RSALoadKey_t *p_hwcrhk_RSALoadKey = NULL;
441: static HWCryptoHook_RSAGetPublicKey_t *p_hwcrhk_RSAGetPublicKey = NULL;
442: static HWCryptoHook_RSAUnloadKey_t *p_hwcrhk_RSAUnloadKey = NULL;
443: #endif
444: static HWCryptoHook_ModExpCRT_t *p_hwcrhk_ModExpCRT = NULL;
445:
446:
447: static const char *HWCRHK_LIBNAME = NULL;
448: static void free_HWCRHK_LIBNAME(void)
449: {
450: if(HWCRHK_LIBNAME)
451: OPENSSL_free((void*)HWCRHK_LIBNAME);
452: HWCRHK_LIBNAME = NULL;
453: }
454: static const char *get_HWCRHK_LIBNAME(void)
455: {
456: if(HWCRHK_LIBNAME)
457: return HWCRHK_LIBNAME;
458: return "nfhwcrhk";
459: }
460: static long set_HWCRHK_LIBNAME(const char *name)
461: {
462: free_HWCRHK_LIBNAME();
463: return (((HWCRHK_LIBNAME = BUF_strdup(name)) != NULL) ? 1 : 0);
464: }
465: static const char *n_hwcrhk_Init = "HWCryptoHook_Init";
466: static const char *n_hwcrhk_Finish = "HWCryptoHook_Finish";
467: static const char *n_hwcrhk_ModExp = "HWCryptoHook_ModExp";
468: #ifndef OPENSSL_NO_RSA
469: static const char *n_hwcrhk_RSA = "HWCryptoHook_RSA";
470: #endif
471: static const char *n_hwcrhk_RandomBytes = "HWCryptoHook_RandomBytes";
472: #ifndef OPENSSL_NO_RSA
473: static const char *n_hwcrhk_RSALoadKey = "HWCryptoHook_RSALoadKey";
474: static const char *n_hwcrhk_RSAGetPublicKey = "HWCryptoHook_RSAGetPublicKey";
475: static const char *n_hwcrhk_RSAUnloadKey = "HWCryptoHook_RSAUnloadKey";
476: #endif
477: static const char *n_hwcrhk_ModExpCRT = "HWCryptoHook_ModExpCRT";
478:
479:
480:
481:
482:
483:
484:
485: static int get_context(HWCryptoHook_ContextHandle *hac,
486: HWCryptoHook_CallerContext *cac)
487: {
488: char tempbuf[1024];
489: HWCryptoHook_ErrMsgBuf rmsg;
490:
491: rmsg.buf = tempbuf;
492: rmsg.size = sizeof(tempbuf);
493:
494: *hac = p_hwcrhk_Init(&hwcrhk_globals, sizeof(hwcrhk_globals), &rmsg,
495: cac);
496: if (!*hac)
497: return 0;
498: return 1;
499: }
500:
501:
502: static void release_context(HWCryptoHook_ContextHandle hac)
503: {
504: p_hwcrhk_Finish(hac);
505: }
506:
507:
508: static int hwcrhk_destroy(ENGINE *e)
509: {
510: free_HWCRHK_LIBNAME();
511: ERR_unload_HWCRHK_strings();
512: return 1;
513: }
514:
515:
516: static int hwcrhk_init(ENGINE *e)
517: {
518: HWCryptoHook_Init_t *p1;
519: HWCryptoHook_Finish_t *p2;
520: HWCryptoHook_ModExp_t *p3;
521: #ifndef OPENSSL_NO_RSA
522: HWCryptoHook_RSA_t *p4;
523: HWCryptoHook_RSALoadKey_t *p5;
524: HWCryptoHook_RSAGetPublicKey_t *p6;
525: HWCryptoHook_RSAUnloadKey_t *p7;
526: #endif
527: HWCryptoHook_RandomBytes_t *p8;
528: HWCryptoHook_ModExpCRT_t *p9;
529:
530: if(hwcrhk_dso != NULL)
531: {
532: HWCRHKerr(HWCRHK_F_HWCRHK_INIT,HWCRHK_R_ALREADY_LOADED);
533: goto err;
534: }
535:
536: hwcrhk_dso = DSO_load(NULL, get_HWCRHK_LIBNAME(), NULL, 0);
537: if(hwcrhk_dso == NULL)
538: {
539: HWCRHKerr(HWCRHK_F_HWCRHK_INIT,HWCRHK_R_DSO_FAILURE);
540: goto err;
541: }
542: if(!(p1 = (HWCryptoHook_Init_t *)
543: DSO_bind_func(hwcrhk_dso, n_hwcrhk_Init)) ||
544: !(p2 = (HWCryptoHook_Finish_t *)
545: DSO_bind_func(hwcrhk_dso, n_hwcrhk_Finish)) ||
546: !(p3 = (HWCryptoHook_ModExp_t *)
547: DSO_bind_func(hwcrhk_dso, n_hwcrhk_ModExp)) ||
548: #ifndef OPENSSL_NO_RSA
549: !(p4 = (HWCryptoHook_RSA_t *)
550: DSO_bind_func(hwcrhk_dso, n_hwcrhk_RSA)) ||
551: