e_chil.c 42 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342
  1. /* crypto/engine/e_chil.c -*- mode: C; c-file-style: "eay" -*- */
  2. /*
  3. * Written by Richard Levitte (richard@levitte.org), Geoff Thorpe
  4. * (geoff@geoffthorpe.net) and Dr Stephen N Henson (steve@openssl.org) for
  5. * the OpenSSL project 2000.
  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. #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. #ifndef OPENSSL_NO_HW
  76. # ifndef OPENSSL_NO_HW_CHIL
  77. /*-
  78. * Attribution notice: nCipher have said several times that it's OK for
  79. * us to implement a general interface to their boxes, and recently declared
  80. * their HWCryptoHook to be public, and therefore available for us to use.
  81. * Thanks, nCipher.
  82. *
  83. * The hwcryptohook.h included here is from May 2000.
  84. * [Richard Levitte]
  85. */
  86. # ifdef FLAT_INC
  87. # include "hwcryptohook.h"
  88. # else
  89. # include "vendor_defns/hwcryptohook.h"
  90. # endif
  91. # define HWCRHK_LIB_NAME "CHIL engine"
  92. # include "e_chil_err.c"
  93. static int hwcrhk_destroy(ENGINE *e);
  94. static int hwcrhk_init(ENGINE *e);
  95. static int hwcrhk_finish(ENGINE *e);
  96. static int hwcrhk_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void));
  97. /* Functions to handle mutexes */
  98. static int hwcrhk_mutex_init(HWCryptoHook_Mutex *,
  99. HWCryptoHook_CallerContext *);
  100. static int hwcrhk_mutex_lock(HWCryptoHook_Mutex *);
  101. static void hwcrhk_mutex_unlock(HWCryptoHook_Mutex *);
  102. static void hwcrhk_mutex_destroy(HWCryptoHook_Mutex *);
  103. /* BIGNUM stuff */
  104. static int hwcrhk_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
  105. const BIGNUM *m, BN_CTX *ctx);
  106. # ifndef OPENSSL_NO_RSA
  107. /* RSA stuff */
  108. static int hwcrhk_rsa_mod_exp(BIGNUM *r, const BIGNUM *I, RSA *rsa,
  109. BN_CTX *ctx);
  110. /* This function is aliased to mod_exp (with the mont stuff dropped). */
  111. static int hwcrhk_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
  112. const BIGNUM *m, BN_CTX *ctx,
  113. BN_MONT_CTX *m_ctx);
  114. static int hwcrhk_rsa_finish(RSA *rsa);
  115. # endif
  116. # ifndef OPENSSL_NO_DH
  117. /* DH stuff */
  118. /* This function is alised to mod_exp (with the DH and mont dropped). */
  119. static int hwcrhk_mod_exp_dh(const DH *dh, BIGNUM *r,
  120. const BIGNUM *a, const BIGNUM *p,
  121. const BIGNUM *m, BN_CTX *ctx,
  122. BN_MONT_CTX *m_ctx);
  123. # endif
  124. /* RAND stuff */
  125. static int hwcrhk_rand_bytes(unsigned char *buf, int num);
  126. static int hwcrhk_rand_status(void);
  127. /* KM stuff */
  128. static EVP_PKEY *hwcrhk_load_privkey(ENGINE *eng, const char *key_id,
  129. UI_METHOD *ui_method,
  130. void *callback_data);
  131. static EVP_PKEY *hwcrhk_load_pubkey(ENGINE *eng, const char *key_id,
  132. UI_METHOD *ui_method,
  133. void *callback_data);
  134. /* Interaction stuff */
  135. static int hwcrhk_insert_card(const char *prompt_info,
  136. const char *wrong_info,
  137. HWCryptoHook_PassphraseContext * ppctx,
  138. HWCryptoHook_CallerContext * cactx);
  139. static int hwcrhk_get_pass(const char *prompt_info,
  140. int *len_io, char *buf,
  141. HWCryptoHook_PassphraseContext * ppctx,
  142. HWCryptoHook_CallerContext * cactx);
  143. static void hwcrhk_log_message(void *logstr, const char *message);
  144. /* The definitions for control commands specific to this engine */
  145. # define HWCRHK_CMD_SO_PATH ENGINE_CMD_BASE
  146. # define HWCRHK_CMD_FORK_CHECK (ENGINE_CMD_BASE + 1)
  147. # define HWCRHK_CMD_THREAD_LOCKING (ENGINE_CMD_BASE + 2)
  148. # define HWCRHK_CMD_SET_USER_INTERFACE (ENGINE_CMD_BASE + 3)
  149. # define HWCRHK_CMD_SET_CALLBACK_DATA (ENGINE_CMD_BASE + 4)
  150. static const ENGINE_CMD_DEFN hwcrhk_cmd_defns[] = {
  151. {HWCRHK_CMD_SO_PATH,
  152. "SO_PATH",
  153. "Specifies the path to the 'hwcrhk' shared library",
  154. ENGINE_CMD_FLAG_STRING},
  155. {HWCRHK_CMD_FORK_CHECK,
  156. "FORK_CHECK",
  157. "Turns fork() checking on (non-zero) or off (zero)",
  158. ENGINE_CMD_FLAG_NUMERIC},
  159. {HWCRHK_CMD_THREAD_LOCKING,
  160. "THREAD_LOCKING",
  161. "Turns thread-safe locking on (zero) or off (non-zero)",
  162. ENGINE_CMD_FLAG_NUMERIC},
  163. {HWCRHK_CMD_SET_USER_INTERFACE,
  164. "SET_USER_INTERFACE",
  165. "Set the global user interface (internal)",
  166. ENGINE_CMD_FLAG_INTERNAL},
  167. {HWCRHK_CMD_SET_CALLBACK_DATA,
  168. "SET_CALLBACK_DATA",
  169. "Set the global user interface extra data (internal)",
  170. ENGINE_CMD_FLAG_INTERNAL},
  171. {0, NULL, NULL, 0}
  172. };
  173. # ifndef OPENSSL_NO_RSA
  174. /* Our internal RSA_METHOD that we provide pointers to */
  175. static RSA_METHOD hwcrhk_rsa = {
  176. "CHIL RSA method",
  177. NULL,
  178. NULL,
  179. NULL,
  180. NULL,
  181. hwcrhk_rsa_mod_exp,
  182. hwcrhk_mod_exp_mont,
  183. NULL,
  184. hwcrhk_rsa_finish,
  185. 0,
  186. NULL,
  187. NULL,
  188. NULL,
  189. NULL
  190. };
  191. # endif
  192. # ifndef OPENSSL_NO_DH
  193. /* Our internal DH_METHOD that we provide pointers to */
  194. static DH_METHOD hwcrhk_dh = {
  195. "CHIL DH method",
  196. NULL,
  197. NULL,
  198. hwcrhk_mod_exp_dh,
  199. NULL,
  200. NULL,
  201. 0,
  202. NULL,
  203. NULL
  204. };
  205. # endif
  206. static RAND_METHOD hwcrhk_rand = {
  207. /* "CHIL RAND method", */
  208. NULL,
  209. hwcrhk_rand_bytes,
  210. NULL,
  211. NULL,
  212. hwcrhk_rand_bytes,
  213. hwcrhk_rand_status,
  214. };
  215. /* Constants used when creating the ENGINE */
  216. static const char *engine_hwcrhk_id = "chil";
  217. static const char *engine_hwcrhk_name = "CHIL hardware engine support";
  218. # ifndef OPENSSL_NO_DYNAMIC_ENGINE
  219. /* Compatibility hack, the dynamic library uses this form in the path */
  220. static const char *engine_hwcrhk_id_alt = "ncipher";
  221. # endif
  222. /* Internal stuff for HWCryptoHook */
  223. /* Some structures needed for proper use of thread locks */
  224. /*
  225. * hwcryptohook.h has some typedefs that turn struct HWCryptoHook_MutexValue
  226. * into HWCryptoHook_Mutex
  227. */
  228. struct HWCryptoHook_MutexValue {
  229. int lockid;
  230. };
  231. /*
  232. * hwcryptohook.h has some typedefs that turn struct
  233. * HWCryptoHook_PassphraseContextValue into HWCryptoHook_PassphraseContext
  234. */
  235. struct HWCryptoHook_PassphraseContextValue {
  236. UI_METHOD *ui_method;
  237. void *callback_data;
  238. };
  239. /*
  240. * hwcryptohook.h has some typedefs that turn struct
  241. * HWCryptoHook_CallerContextValue into HWCryptoHook_CallerContext
  242. */
  243. struct HWCryptoHook_CallerContextValue {
  244. pem_password_cb *password_callback; /* Deprecated! Only present for
  245. * backward compatibility! */
  246. UI_METHOD *ui_method;
  247. void *callback_data;
  248. };
  249. /*
  250. * The MPI structure in HWCryptoHook is pretty compatible with OpenSSL
  251. * BIGNUM's, so lets define a couple of conversion macros
  252. */
  253. # define BN2MPI(mp, bn) \
  254. {mp.size = bn->top * sizeof(BN_ULONG); mp.buf = (unsigned char *)bn->d;}
  255. # define MPI2BN(bn, mp) \
  256. {mp.size = bn->dmax * sizeof(BN_ULONG); mp.buf = (unsigned char *)bn->d;}
  257. static BIO *logstream = NULL;
  258. static int disable_mutex_callbacks = 0;
  259. /*
  260. * One might wonder why these are needed, since one can pass down at least a
  261. * UI_METHOD and a pointer to callback data to the key-loading functions. The
  262. * thing is that the ModExp and RSAImmed functions can load keys as well, if
  263. * the data they get is in a special, nCipher-defined format (hint: if you
  264. * look at the private exponent of the RSA data as a string, you'll see this
  265. * string: "nCipher KM tool key id", followed by some bytes, followed a key
  266. * identity string, followed by more bytes. This happens when you use
  267. * "embed" keys instead of "hwcrhk" keys). Unfortunately, those functions do
  268. * not take any passphrase or caller context, and our functions can't really
  269. * take any callback data either. Still, the "insert_card" and
  270. * "get_passphrase" callbacks may be called down the line, and will need to
  271. * know what user interface callbacks to call, and having callback data from
  272. * the application may be a nice thing as well, so we need to keep track of
  273. * that globally.
  274. */
  275. static HWCryptoHook_CallerContext password_context = { NULL, NULL, NULL };
  276. /* Stuff to pass to the HWCryptoHook library */
  277. static HWCryptoHook_InitInfo hwcrhk_globals = {
  278. HWCryptoHook_InitFlags_SimpleForkCheck, /* Flags */
  279. &logstream, /* logstream */
  280. sizeof(BN_ULONG), /* limbsize */
  281. 0, /* mslimb first: false for BNs */
  282. -1, /* msbyte first: use native */
  283. 0, /* Max mutexes, 0 = no small limit */
  284. 0, /* Max simultaneous, 0 = default */
  285. /*
  286. * The next few are mutex stuff: we write wrapper functions around the OS
  287. * mutex functions. We initialise them to 0 here, and change that to
  288. * actual function pointers in hwcrhk_init() if dynamic locks are
  289. * supported (that is, if the application programmer has made sure of
  290. * setting up callbacks bafore starting this engine) *and* if
  291. * disable_mutex_callbacks hasn't been set by a call to
  292. * ENGINE_ctrl(ENGINE_CTRL_CHIL_NO_LOCKING).
  293. */
  294. sizeof(HWCryptoHook_Mutex),
  295. 0,
  296. 0,
  297. 0,
  298. 0,
  299. /*
  300. * The next few are condvar stuff: we write wrapper functions round the
  301. * OS functions. Currently not implemented and not and absolute
  302. * necessity even in threaded programs, therefore 0'ed. Will hopefully
  303. * be implemented some day, since it enhances the efficiency of
  304. * HWCryptoHook.
  305. */
  306. 0, /* sizeof(HWCryptoHook_CondVar), */
  307. 0, /* hwcrhk_cv_init, */
  308. 0, /* hwcrhk_cv_wait, */
  309. 0, /* hwcrhk_cv_signal, */
  310. 0, /* hwcrhk_cv_broadcast, */
  311. 0, /* hwcrhk_cv_destroy, */
  312. hwcrhk_get_pass, /* pass phrase */
  313. hwcrhk_insert_card, /* insert a card */
  314. hwcrhk_log_message /* Log message */
  315. };
  316. /* Now, to our own code */
  317. /*
  318. * This internal function is used by ENGINE_chil() and possibly by the
  319. * "dynamic" ENGINE support too
  320. */
  321. static int bind_helper(ENGINE *e)
  322. {
  323. # ifndef OPENSSL_NO_RSA
  324. const RSA_METHOD *meth1;
  325. # endif
  326. # ifndef OPENSSL_NO_DH
  327. const DH_METHOD *meth2;
  328. # endif
  329. if (!ENGINE_set_id(e, engine_hwcrhk_id) ||
  330. !ENGINE_set_name(e, engine_hwcrhk_name) ||
  331. # ifndef OPENSSL_NO_RSA
  332. !ENGINE_set_RSA(e, &hwcrhk_rsa) ||
  333. # endif
  334. # ifndef OPENSSL_NO_DH
  335. !ENGINE_set_DH(e, &hwcrhk_dh) ||
  336. # endif
  337. !ENGINE_set_RAND(e, &hwcrhk_rand) ||
  338. !ENGINE_set_destroy_function(e, hwcrhk_destroy) ||
  339. !ENGINE_set_init_function(e, hwcrhk_init) ||
  340. !ENGINE_set_finish_function(e, hwcrhk_finish) ||
  341. !ENGINE_set_ctrl_function(e, hwcrhk_ctrl) ||
  342. !ENGINE_set_load_privkey_function(e, hwcrhk_load_privkey) ||
  343. !ENGINE_set_load_pubkey_function(e, hwcrhk_load_pubkey) ||
  344. !ENGINE_set_cmd_defns(e, hwcrhk_cmd_defns))
  345. return 0;
  346. # ifndef OPENSSL_NO_RSA
  347. /*
  348. * We know that the "PKCS1_SSLeay()" functions hook properly to the
  349. * cswift-specific mod_exp and mod_exp_crt so we use those functions. NB:
  350. * We don't use ENGINE_openssl() or anything "more generic" because
  351. * something like the RSAref code may not hook properly, and if you own
  352. * one of these cards then you have the right to do RSA operations on it
  353. * anyway!
  354. */
  355. meth1 = RSA_PKCS1_SSLeay();
  356. hwcrhk_rsa.rsa_pub_enc = meth1->rsa_pub_enc;
  357. hwcrhk_rsa.rsa_pub_dec = meth1->rsa_pub_dec;
  358. hwcrhk_rsa.rsa_priv_enc = meth1->rsa_priv_enc;
  359. hwcrhk_rsa.rsa_priv_dec = meth1->rsa_priv_dec;
  360. # endif
  361. # ifndef OPENSSL_NO_DH
  362. /* Much the same for Diffie-Hellman */
  363. meth2 = DH_OpenSSL();
  364. hwcrhk_dh.generate_key = meth2->generate_key;
  365. hwcrhk_dh.compute_key = meth2->compute_key;
  366. # endif
  367. /* Ensure the hwcrhk error handling is set up */
  368. ERR_load_HWCRHK_strings();
  369. return 1;
  370. }
  371. # ifdef OPENSSL_NO_DYNAMIC_ENGINE
  372. static ENGINE *engine_chil(void)
  373. {
  374. ENGINE *ret = ENGINE_new();
  375. if (!ret)
  376. return NULL;
  377. if (!bind_helper(ret)) {
  378. ENGINE_free(ret);
  379. return NULL;
  380. }
  381. return ret;
  382. }
  383. void ENGINE_load_chil(void)
  384. {
  385. /* Copied from eng_[openssl|dyn].c */
  386. ENGINE *toadd = engine_chil();
  387. if (!toadd)
  388. return;
  389. ENGINE_add(toadd);
  390. ENGINE_free(toadd);
  391. ERR_clear_error();
  392. }
  393. # endif
  394. /*
  395. * This is a process-global DSO handle used for loading and unloading the
  396. * HWCryptoHook library. NB: This is only set (or unset) during an init() or
  397. * finish() call (reference counts permitting) and they're operating with
  398. * global locks, so this should be thread-safe implicitly.
  399. */
  400. static DSO *hwcrhk_dso = NULL;
  401. static HWCryptoHook_ContextHandle hwcrhk_context = 0;
  402. # ifndef OPENSSL_NO_RSA
  403. /* Index for KM handle. Not really used yet. */
  404. static int hndidx_rsa = -1;
  405. # endif
  406. /*
  407. * These are the function pointers that are (un)set when the library has
  408. * successfully (un)loaded.
  409. */
  410. static HWCryptoHook_Init_t *p_hwcrhk_Init = NULL;
  411. static HWCryptoHook_Finish_t *p_hwcrhk_Finish = NULL;
  412. static HWCryptoHook_ModExp_t *p_hwcrhk_ModExp = NULL;
  413. # ifndef OPENSSL_NO_RSA
  414. static HWCryptoHook_RSA_t *p_hwcrhk_RSA = NULL;
  415. # endif
  416. static HWCryptoHook_RandomBytes_t *p_hwcrhk_RandomBytes = NULL;
  417. # ifndef OPENSSL_NO_RSA
  418. static HWCryptoHook_RSALoadKey_t *p_hwcrhk_RSALoadKey = NULL;
  419. static HWCryptoHook_RSAGetPublicKey_t *p_hwcrhk_RSAGetPublicKey = NULL;
  420. static HWCryptoHook_RSAUnloadKey_t *p_hwcrhk_RSAUnloadKey = NULL;
  421. # endif
  422. static HWCryptoHook_ModExpCRT_t *p_hwcrhk_ModExpCRT = NULL;
  423. /* Used in the DSO operations. */
  424. static const char *HWCRHK_LIBNAME = NULL;
  425. static void free_HWCRHK_LIBNAME(void)
  426. {
  427. if (HWCRHK_LIBNAME)
  428. OPENSSL_free((void *)HWCRHK_LIBNAME);
  429. HWCRHK_LIBNAME = NULL;
  430. }
  431. static const char *get_HWCRHK_LIBNAME(void)
  432. {
  433. if (HWCRHK_LIBNAME)
  434. return HWCRHK_LIBNAME;
  435. return "nfhwcrhk";
  436. }
  437. static long set_HWCRHK_LIBNAME(const char *name)
  438. {
  439. free_HWCRHK_LIBNAME();
  440. return (((HWCRHK_LIBNAME = BUF_strdup(name)) != NULL) ? 1 : 0);
  441. }
  442. static const char *n_hwcrhk_Init = "HWCryptoHook_Init";
  443. static const char *n_hwcrhk_Finish = "HWCryptoHook_Finish";
  444. static const char *n_hwcrhk_ModExp = "HWCryptoHook_ModExp";
  445. # ifndef OPENSSL_NO_RSA
  446. static const char *n_hwcrhk_RSA = "HWCryptoHook_RSA";
  447. # endif
  448. static const char *n_hwcrhk_RandomBytes = "HWCryptoHook_RandomBytes";
  449. # ifndef OPENSSL_NO_RSA
  450. static const char *n_hwcrhk_RSALoadKey = "HWCryptoHook_RSALoadKey";
  451. static const char *n_hwcrhk_RSAGetPublicKey = "HWCryptoHook_RSAGetPublicKey";
  452. static const char *n_hwcrhk_RSAUnloadKey = "HWCryptoHook_RSAUnloadKey";
  453. # endif
  454. static const char *n_hwcrhk_ModExpCRT = "HWCryptoHook_ModExpCRT";
  455. /*
  456. * HWCryptoHook library functions and mechanics - these are used by the
  457. * higher-level functions further down. NB: As and where there's no error
  458. * checking, take a look lower down where these functions are called, the
  459. * checking and error handling is probably down there.
  460. */
  461. /* utility function to obtain a context */
  462. static int get_context(HWCryptoHook_ContextHandle * hac,
  463. HWCryptoHook_CallerContext * cac)
  464. {
  465. char tempbuf[1024];
  466. HWCryptoHook_ErrMsgBuf rmsg;
  467. rmsg.buf = tempbuf;
  468. rmsg.size = sizeof(tempbuf);
  469. *hac = p_hwcrhk_Init(&hwcrhk_globals, sizeof(hwcrhk_globals), &rmsg, cac);
  470. if (!*hac)
  471. return 0;
  472. return 1;
  473. }
  474. /* similarly to release one. */
  475. static void release_context(HWCryptoHook_ContextHandle hac)
  476. {
  477. p_hwcrhk_Finish(hac);
  478. }
  479. /* Destructor (complements the "ENGINE_chil()" constructor) */
  480. static int hwcrhk_destroy(ENGINE *e)
  481. {
  482. free_HWCRHK_LIBNAME();
  483. ERR_unload_HWCRHK_strings();
  484. return 1;
  485. }
  486. /* (de)initialisation functions. */
  487. static int hwcrhk_init(ENGINE *e)
  488. {
  489. HWCryptoHook_Init_t *p1;
  490. HWCryptoHook_Finish_t *p2;
  491. HWCryptoHook_ModExp_t *p3;
  492. # ifndef OPENSSL_NO_RSA
  493. HWCryptoHook_RSA_t *p4;
  494. HWCryptoHook_RSALoadKey_t *p5;
  495. HWCryptoHook_RSAGetPublicKey_t *p6;
  496. HWCryptoHook_RSAUnloadKey_t *p7;
  497. # endif
  498. HWCryptoHook_RandomBytes_t *p8;
  499. HWCryptoHook_ModExpCRT_t *p9;
  500. if (hwcrhk_dso != NULL) {
  501. HWCRHKerr(HWCRHK_F_HWCRHK_INIT, HWCRHK_R_ALREADY_LOADED);
  502. goto err;
  503. }
  504. /* Attempt to load libnfhwcrhk.so/nfhwcrhk.dll/whatever. */
  505. hwcrhk_dso = DSO_load(NULL, get_HWCRHK_LIBNAME(), NULL, 0);
  506. if (hwcrhk_dso == NULL) {
  507. HWCRHKerr(HWCRHK_F_HWCRHK_INIT, HWCRHK_R_DSO_FAILURE);
  508. goto err;
  509. }
  510. if (!(p1 = (HWCryptoHook_Init_t *)
  511. DSO_bind_func(hwcrhk_dso, n_hwcrhk_Init)) ||
  512. !(p2 = (HWCryptoHook_Finish_t *)
  513. DSO_bind_func(hwcrhk_dso, n_hwcrhk_Finish)) ||
  514. !(p3 = (HWCryptoHook_ModExp_t *)
  515. DSO_bind_func(hwcrhk_dso, n_hwcrhk_ModExp)) ||
  516. # ifndef OPENSSL_NO_RSA
  517. !(p4 = (HWCryptoHook_RSA_t *)
  518. DSO_bind_func(hwcrhk_dso, n_hwcrhk_RSA)) ||
  519. !(p5 = (HWCryptoHook_RSALoadKey_t *)
  520. DSO_bind_func(hwcrhk_dso, n_hwcrhk_RSALoadKey)) ||
  521. !(p6 = (HWCryptoHook_RSAGetPublicKey_t *)
  522. DSO_bind_func(hwcrhk_dso, n_hwcrhk_RSAGetPublicKey)) ||
  523. !(p7 = (HWCryptoHook_RSAUnloadKey_t *)
  524. DSO_bind_func(hwcrhk_dso, n_hwcrhk_RSAUnloadKey)) ||
  525. # endif
  526. !(p8 = (HWCryptoHook_RandomBytes_t *)
  527. DSO_bind_func(hwcrhk_dso, n_hwcrhk_RandomBytes)) ||
  528. !(p9 = (HWCryptoHook_ModExpCRT_t *)
  529. DSO_bind_func(hwcrhk_dso, n_hwcrhk_ModExpCRT))) {
  530. HWCRHKerr(HWCRHK_F_HWCRHK_INIT, HWCRHK_R_DSO_FAILURE);
  531. goto err;
  532. }
  533. /* Copy the pointers */
  534. p_hwcrhk_Init = p1;
  535. p_hwcrhk_Finish = p2;
  536. p_hwcrhk_ModExp = p3;
  537. # ifndef OPENSSL_NO_RSA
  538. p_hwcrhk_RSA = p4;
  539. p_hwcrhk_RSALoadKey = p5;
  540. p_hwcrhk_RSAGetPublicKey = p6;
  541. p_hwcrhk_RSAUnloadKey = p7;
  542. # endif
  543. p_hwcrhk_RandomBytes = p8;
  544. p_hwcrhk_ModExpCRT = p9;
  545. /*
  546. * Check if the application decided to support dynamic locks, and if it
  547. * does, use them.
  548. */
  549. if (disable_mutex_callbacks == 0) {
  550. if (CRYPTO_get_dynlock_create_callback() != NULL &&
  551. CRYPTO_get_dynlock_lock_callback() != NULL &&
  552. CRYPTO_get_dynlock_destroy_callback() != NULL) {
  553. hwcrhk_globals.mutex_init = hwcrhk_mutex_init;
  554. hwcrhk_globals.mutex_acquire = hwcrhk_mutex_lock;
  555. hwcrhk_globals.mutex_release = hwcrhk_mutex_unlock;
  556. hwcrhk_globals.mutex_destroy = hwcrhk_mutex_destroy;
  557. }
  558. }
  559. /*
  560. * Try and get a context - if not, we may have a DSO but no accelerator!
  561. */
  562. if (!get_context(&hwcrhk_context, &password_context)) {
  563. HWCRHKerr(HWCRHK_F_HWCRHK_INIT, HWCRHK_R_UNIT_FAILURE);
  564. goto err;
  565. }
  566. /* Everything's fine. */
  567. # ifndef OPENSSL_NO_RSA
  568. if (hndidx_rsa == -1)
  569. hndidx_rsa = RSA_get_ex_new_index(0,
  570. "nFast HWCryptoHook RSA key handle",
  571. NULL, NULL, NULL);
  572. # endif
  573. return 1;
  574. err:
  575. if (hwcrhk_dso)
  576. DSO_free(hwcrhk_dso);
  577. hwcrhk_dso = NULL;
  578. p_hwcrhk_Init = NULL;
  579. p_hwcrhk_Finish = NULL;
  580. p_hwcrhk_ModExp = NULL;
  581. # ifndef OPENSSL_NO_RSA
  582. p_hwcrhk_RSA = NULL;
  583. p_hwcrhk_RSALoadKey = NULL;
  584. p_hwcrhk_RSAGetPublicKey = NULL;
  585. p_hwcrhk_RSAUnloadKey = NULL;
  586. # endif
  587. p_hwcrhk_ModExpCRT = NULL;
  588. p_hwcrhk_RandomBytes = NULL;
  589. return 0;
  590. }
  591. static int hwcrhk_finish(ENGINE *e)
  592. {
  593. int to_return = 1;
  594. free_HWCRHK_LIBNAME();
  595. if (hwcrhk_dso == NULL) {
  596. HWCRHKerr(HWCRHK_F_HWCRHK_FINISH, HWCRHK_R_NOT_LOADED);
  597. to_return = 0;
  598. goto err;
  599. }
  600. release_context(hwcrhk_context);
  601. if (!DSO_free(hwcrhk_dso)) {
  602. HWCRHKerr(HWCRHK_F_HWCRHK_FINISH, HWCRHK_R_DSO_FAILURE);
  603. to_return = 0;
  604. goto err;
  605. }
  606. err:
  607. if (logstream)
  608. BIO_free(logstream);
  609. hwcrhk_dso = NULL;
  610. p_hwcrhk_Init = NULL;
  611. p_hwcrhk_Finish = NULL;
  612. p_hwcrhk_ModExp = NULL;
  613. # ifndef OPENSSL_NO_RSA
  614. p_hwcrhk_RSA = NULL;
  615. p_hwcrhk_RSALoadKey = NULL;
  616. p_hwcrhk_RSAGetPublicKey = NULL;
  617. p_hwcrhk_RSAUnloadKey = NULL;
  618. # endif
  619. p_hwcrhk_ModExpCRT = NULL;
  620. p_hwcrhk_RandomBytes = NULL;
  621. return to_return;
  622. }
  623. static int hwcrhk_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void))
  624. {
  625. int to_return = 1;
  626. switch (cmd) {
  627. case HWCRHK_CMD_SO_PATH:
  628. if (hwcrhk_dso) {
  629. HWCRHKerr(HWCRHK_F_HWCRHK_CTRL, HWCRHK_R_ALREADY_LOADED);
  630. return 0;
  631. }
  632. if (p == NULL) {
  633. HWCRHKerr(HWCRHK_F_HWCRHK_CTRL, ERR_R_PASSED_NULL_PARAMETER);
  634. return 0;
  635. }
  636. return set_HWCRHK_LIBNAME((const char *)p);
  637. case ENGINE_CTRL_SET_LOGSTREAM:
  638. {
  639. BIO *bio = (BIO *)p;
  640. CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
  641. if (logstream) {
  642. BIO_free(logstream);
  643. logstream = NULL;
  644. }
  645. if (CRYPTO_add(&bio->references, 1, CRYPTO_LOCK_BIO) > 1)
  646. logstream = bio;
  647. else
  648. HWCRHKerr(HWCRHK_F_HWCRHK_CTRL, HWCRHK_R_BIO_WAS_FREED);
  649. }
  650. CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
  651. break;
  652. case ENGINE_CTRL_SET_PASSWORD_CALLBACK:
  653. CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
  654. password_context.password_callback = (pem_password_cb *)f;
  655. CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
  656. break;
  657. case ENGINE_CTRL_SET_USER_INTERFACE:
  658. case HWCRHK_CMD_SET_USER_INTERFACE:
  659. CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
  660. password_context.ui_method = (UI_METHOD *)p;
  661. CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
  662. break;
  663. case ENGINE_CTRL_SET_CALLBACK_DATA:
  664. case HWCRHK_CMD_SET_CALLBACK_DATA:
  665. CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
  666. password_context.callback_data = p;
  667. CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
  668. break;
  669. /*
  670. * this enables or disables the "SimpleForkCheck" flag used in the
  671. * initialisation structure.
  672. */
  673. case ENGINE_CTRL_CHIL_SET_FORKCHECK:
  674. case HWCRHK_CMD_FORK_CHECK:
  675. CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
  676. if (i)
  677. hwcrhk_globals.flags |= HWCryptoHook_InitFlags_SimpleForkCheck;
  678. else
  679. hwcrhk_globals.flags &= ~HWCryptoHook_InitFlags_SimpleForkCheck;
  680. CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
  681. break;
  682. /*
  683. * This will prevent the initialisation function from "installing"
  684. * the mutex-handling callbacks, even if they are available from
  685. * within the library (or were provided to the library from the
  686. * calling application). This is to remove any baggage for
  687. * applications not using multithreading.
  688. */
  689. case ENGINE_CTRL_CHIL_NO_LOCKING:
  690. CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
  691. disable_mutex_callbacks = 1;
  692. CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
  693. break;
  694. case HWCRHK_CMD_THREAD_LOCKING:
  695. CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
  696. disable_mutex_callbacks = ((i == 0) ? 0 : 1);
  697. CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
  698. break;
  699. /* The command isn't understood by this engine */
  700. default:
  701. HWCRHKerr(HWCRHK_F_HWCRHK_CTRL,
  702. HWCRHK_R_CTRL_COMMAND_NOT_IMPLEMENTED);
  703. to_return = 0;
  704. break;
  705. }
  706. return to_return;
  707. }
  708. static EVP_PKEY *hwcrhk_load_privkey(ENGINE *eng, const char *key_id,
  709. UI_METHOD *ui_method,
  710. void *callback_data)
  711. {
  712. # ifndef OPENSSL_NO_RSA
  713. RSA *rtmp = NULL;
  714. # endif
  715. EVP_PKEY *res = NULL;
  716. # ifndef OPENSSL_NO_RSA
  717. HWCryptoHook_MPI e, n;
  718. HWCryptoHook_RSAKeyHandle *hptr;
  719. # endif
  720. # if !defined(OPENSSL_NO_RSA)
  721. char tempbuf[1024];
  722. HWCryptoHook_ErrMsgBuf rmsg;
  723. HWCryptoHook_PassphraseContext ppctx;
  724. # endif
  725. # if !defined(OPENSSL_NO_RSA)
  726. rmsg.buf = tempbuf;
  727. rmsg.size = sizeof(tempbuf);
  728. # endif
  729. if (!hwcrhk_context) {
  730. HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY, HWCRHK_R_NOT_INITIALISED);
  731. goto err;
  732. }
  733. # ifndef OPENSSL_NO_RSA
  734. hptr = OPENSSL_malloc(sizeof(HWCryptoHook_RSAKeyHandle));
  735. if (!hptr) {
  736. HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY, ERR_R_MALLOC_FAILURE);
  737. goto err;
  738. }
  739. ppctx.ui_method = ui_method;
  740. ppctx.callback_data = callback_data;
  741. if (p_hwcrhk_RSALoadKey(hwcrhk_context, key_id, hptr, &rmsg, &ppctx)) {
  742. HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY, HWCRHK_R_CHIL_ERROR);
  743. ERR_add_error_data(1, rmsg.buf);
  744. goto err;
  745. }
  746. if (!*hptr) {
  747. HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY, HWCRHK_R_NO_KEY);
  748. goto err;
  749. }
  750. # endif
  751. # ifndef OPENSSL_NO_RSA
  752. rtmp = RSA_new_method(eng);
  753. RSA_set_ex_data(rtmp, hndidx_rsa, (char *)hptr);
  754. rtmp->e = BN_new();
  755. rtmp->n = BN_new();
  756. rtmp->flags |= RSA_FLAG_EXT_PKEY;
  757. MPI2BN(rtmp->e, e);
  758. MPI2BN(rtmp->n, n);
  759. if (p_hwcrhk_RSAGetPublicKey(*hptr, &n, &e, &rmsg)
  760. != HWCRYPTOHOOK_ERROR_MPISIZE) {
  761. HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY, HWCRHK_R_CHIL_ERROR);
  762. ERR_add_error_data(1, rmsg.buf);
  763. goto err;
  764. }
  765. bn_expand2(rtmp->e, e.size / sizeof(BN_ULONG));
  766. bn_expand2(rtmp->n, n.size / sizeof(BN_ULONG));
  767. MPI2BN(rtmp->e, e);
  768. MPI2BN(rtmp->n, n);
  769. if (p_hwcrhk_RSAGetPublicKey(*hptr, &n, &e, &rmsg)) {
  770. HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY, HWCRHK_R_CHIL_ERROR);
  771. ERR_add_error_data(1, rmsg.buf);
  772. goto err;
  773. }
  774. rtmp->e->top = e.size / sizeof(BN_ULONG);
  775. bn_fix_top(rtmp->e);
  776. rtmp->n->top = n.size / sizeof(BN_ULONG);
  777. bn_fix_top(rtmp->n);
  778. res = EVP_PKEY_new();
  779. EVP_PKEY_assign_RSA(res, rtmp);
  780. # endif
  781. if (!res)
  782. HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY,
  783. HWCRHK_R_PRIVATE_KEY_ALGORITHMS_DISABLED);
  784. return res;
  785. err:
  786. if (res)
  787. EVP_PKEY_free(res);
  788. # ifndef OPENSSL_NO_RSA
  789. if (rtmp)
  790. RSA_free(rtmp);
  791. # endif
  792. return NULL;
  793. }
  794. static EVP_PKEY *hwcrhk_load_pubkey(ENGINE *eng, const char *key_id,
  795. UI_METHOD *ui_method, void *callback_data)
  796. {
  797. EVP_PKEY *res = NULL;
  798. # ifndef OPENSSL_NO_RSA
  799. res = hwcrhk_load_privkey(eng, key_id, ui_method, callback_data);
  800. # endif
  801. if (res)
  802. switch (res->type) {
  803. # ifndef OPENSSL_NO_RSA
  804. case EVP_PKEY_RSA:
  805. {
  806. RSA *rsa = NULL;
  807. CRYPTO_w_lock(CRYPTO_LOCK_EVP_PKEY);
  808. rsa = res->pkey.rsa;
  809. res->pkey.rsa = RSA_new();
  810. res->pkey.rsa->n = rsa->n;
  811. res->pkey.rsa->e = rsa->e;
  812. rsa->n = NULL;
  813. rsa->e = NULL;
  814. CRYPTO_w_unlock(CRYPTO_LOCK_EVP_PKEY);
  815. RSA_free(rsa);
  816. }
  817. break;
  818. # endif
  819. default:
  820. HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PUBKEY,
  821. HWCRHK_R_CTRL_COMMAND_NOT_IMPLEMENTED);
  822. goto err;
  823. }
  824. return res;
  825. err:
  826. if (res)
  827. EVP_PKEY_free(res);
  828. return NULL;
  829. }
  830. /* A little mod_exp */
  831. static int hwcrhk_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
  832. const BIGNUM *m, BN_CTX *ctx)
  833. {
  834. char tempbuf[1024];
  835. HWCryptoHook_ErrMsgBuf rmsg;
  836. /*
  837. * Since HWCryptoHook_MPI is pretty compatible with BIGNUM's, we use them
  838. * directly, plus a little macro magic. We only thing we need to make
  839. * sure of is that enough space is allocated.
  840. */
  841. HWCryptoHook_MPI m_a, m_p, m_n, m_r;
  842. int to_return, ret;
  843. to_return = 0; /* expect failure */
  844. rmsg.buf = tempbuf;
  845. rmsg.size = sizeof(tempbuf);
  846. if (!hwcrhk_context) {
  847. HWCRHKerr(HWCRHK_F_HWCRHK_MOD_EXP, HWCRHK_R_NOT_INITIALISED);
  848. goto err;
  849. }
  850. /* Prepare the params */
  851. bn_expand2(r, m->top); /* Check for error !! */
  852. BN2MPI(m_a, a);
  853. BN2MPI(m_p, p);
  854. BN2MPI(m_n, m);
  855. MPI2BN(r, m_r);
  856. /* Perform the operation */
  857. ret = p_hwcrhk_ModExp(hwcrhk_context, m_a, m_p, m_n, &m_r, &rmsg);
  858. /* Convert the response */
  859. r->top = m_r.size / sizeof(BN_ULONG);
  860. bn_fix_top(r);
  861. if (ret < 0) {
  862. /*
  863. * FIXME: When this error is returned, HWCryptoHook is telling us
  864. * that falling back to software computation might be a good thing.
  865. */
  866. if (ret == HWCRYPTOHOOK_ERROR_FALLBACK) {
  867. HWCRHKerr(HWCRHK_F_HWCRHK_MOD_EXP, HWCRHK_R_REQUEST_FALLBACK);
  868. } else {
  869. HWCRHKerr(HWCRHK_F_HWCRHK_MOD_EXP, HWCRHK_R_REQUEST_FAILED);
  870. }
  871. ERR_add_error_data(1, rmsg.buf);
  872. goto err;
  873. }
  874. to_return = 1;
  875. err:
  876. return to_return;
  877. }
  878. # ifndef OPENSSL_NO_RSA
  879. static int hwcrhk_rsa_mod_exp(BIGNUM *r, const BIGNUM *I, RSA *rsa,
  880. BN_CTX *ctx)
  881. {
  882. char tempbuf[1024];
  883. HWCryptoHook_ErrMsgBuf rmsg;
  884. HWCryptoHook_RSAKeyHandle *hptr;
  885. int to_return = 0, ret;
  886. rmsg.buf = tempbuf;
  887. rmsg.size = sizeof(tempbuf);
  888. if (!hwcrhk_context) {
  889. HWCRHKerr(HWCRHK_F_HWCRHK_RSA_MOD_EXP, HWCRHK_R_NOT_INITIALISED);
  890. goto err;
  891. }
  892. /*
  893. * This provides support for nForce keys. Since that's opaque data all
  894. * we do is provide a handle to the proper key and let HWCryptoHook take
  895. * care of the rest.
  896. */
  897. if ((hptr =
  898. (HWCryptoHook_RSAKeyHandle *) RSA_get_ex_data(rsa, hndidx_rsa))
  899. != NULL) {
  900. HWCryptoHook_MPI m_a, m_r;
  901. if (!rsa->n) {
  902. HWCRHKerr(HWCRHK_F_HWCRHK_RSA_MOD_EXP,
  903. HWCRHK_R_MISSING_KEY_COMPONENTS);
  904. goto err;
  905. }
  906. /* Prepare the params */
  907. bn_expand2(r, rsa->n->top); /* Check for error !! */
  908. BN2MPI(m_a, I);
  909. MPI2BN(r, m_r);
  910. /* Perform the operation */
  911. ret = p_hwcrhk_RSA(m_a, *hptr, &m_r, &rmsg);
  912. /* Convert the response */
  913. r->top = m_r.size / sizeof(BN_ULONG);
  914. bn_fix_top(r);
  915. if (ret < 0) {
  916. /*
  917. * FIXME: When this error is returned, HWCryptoHook is telling us
  918. * that falling back to software computation might be a good
  919. * thing.
  920. */
  921. if (ret == HWCRYPTOHOOK_ERROR_FALLBACK) {
  922. HWCRHKerr(HWCRHK_F_HWCRHK_RSA_MOD_EXP,
  923. HWCRHK_R_REQUEST_FALLBACK);
  924. } else {
  925. HWCRHKerr(HWCRHK_F_HWCRHK_RSA_MOD_EXP,
  926. HWCRHK_R_REQUEST_FAILED);
  927. }
  928. ERR_add_error_data(1, rmsg.buf);
  929. goto err;
  930. }
  931. } else {
  932. HWCryptoHook_MPI m_a, m_p, m_q, m_dmp1, m_dmq1, m_iqmp, m_r;
  933. if (!rsa->p || !rsa->q || !rsa->dmp1 || !rsa->dmq1 || !rsa->iqmp) {
  934. HWCRHKerr(HWCRHK_F_HWCRHK_RSA_MOD_EXP,
  935. HWCRHK_R_MISSING_KEY_COMPONENTS);
  936. goto err;
  937. }
  938. /* Prepare the params */
  939. bn_expand2(r, rsa->n->top); /* Check for error !! */
  940. BN2MPI(m_a, I);
  941. BN2MPI(m_p, rsa->p);
  942. BN2MPI(m_q, rsa->q);
  943. BN2MPI(m_dmp1, rsa->dmp1);
  944. BN2MPI(m_dmq1, rsa->dmq1);
  945. BN2MPI(m_iqmp, rsa->iqmp);
  946. MPI2BN(r, m_r);
  947. /* Perform the operation */
  948. ret = p_hwcrhk_ModExpCRT(hwcrhk_context, m_a, m_p, m_q,
  949. m_dmp1, m_dmq1, m_iqmp, &m_r, &rmsg);
  950. /* Convert the response */
  951. r->top = m_r.size / sizeof(BN_ULONG);
  952. bn_fix_top(r);
  953. if (ret < 0) {
  954. /*
  955. * FIXME: When this error is returned, HWCryptoHook is telling us
  956. * that falling back to software computation might be a good
  957. * thing.
  958. */
  959. if (ret == HWCRYPTOHOOK_ERROR_FALLBACK) {
  960. HWCRHKerr(HWCRHK_F_HWCRHK_RSA_MOD_EXP,
  961. HWCRHK_R_REQUEST_FALLBACK);
  962. } else {
  963. HWCRHKerr(HWCRHK_F_HWCRHK_RSA_MOD_EXP,
  964. HWCRHK_R_REQUEST_FAILED);
  965. }
  966. ERR_add_error_data(1, rmsg.buf);
  967. goto err;
  968. }
  969. }
  970. /*
  971. * If we're here, we must be here with some semblance of success :-)
  972. */
  973. to_return = 1;
  974. err:
  975. return to_return;
  976. }
  977. # endif
  978. # ifndef OPENSSL_NO_RSA
  979. /* This function is aliased to mod_exp (with the mont stuff dropped). */
  980. static int hwcrhk_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
  981. const BIGNUM *m, BN_CTX *ctx,
  982. BN_MONT_CTX *m_ctx)
  983. {
  984. return hwcrhk_mod_exp(r, a, p, m, ctx);
  985. }
  986. static int hwcrhk_rsa_finish(RSA *rsa)
  987. {
  988. HWCryptoHook_RSAKeyHandle *hptr;
  989. hptr = RSA_get_ex_data(rsa, hndidx_rsa);
  990. if (hptr) {
  991. p_hwcrhk_RSAUnloadKey(*hptr, NULL);
  992. OPENSSL_free(hptr);
  993. RSA_set_ex_data(rsa, hndidx_rsa, NULL);
  994. }
  995. return 1;
  996. }
  997. # endif
  998. # ifndef OPENSSL_NO_DH
  999. /* This function is aliased to mod_exp (with the dh and mont dropped). */
  1000. static int hwcrhk_mod_exp_dh(const DH *dh, BIGNUM *r,
  1001. const BIGNUM *a, const BIGNUM *p,
  1002. const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
  1003. {
  1004. return hwcrhk_mod_exp(r, a, p, m, ctx);
  1005. }
  1006. # endif
  1007. /* Random bytes are good */
  1008. static int hwcrhk_rand_bytes(unsigned char *buf, int num)
  1009. {
  1010. char tempbuf[1024];
  1011. HWCryptoHook_ErrMsgBuf rmsg;
  1012. int to_return = 0; /* assume failure */
  1013. int ret;
  1014. rmsg.buf = tempbuf;
  1015. rmsg.size = sizeof(tempbuf);
  1016. if (!hwcrhk_context) {
  1017. HWCRHKerr(HWCRHK_F_HWCRHK_RAND_BYTES, HWCRHK_R_NOT_INITIALISED);
  1018. goto err;
  1019. }
  1020. ret = p_hwcrhk_RandomBytes(hwcrhk_context, buf, num, &rmsg);
  1021. if (ret < 0) {
  1022. /*
  1023. * FIXME: When this error is returned, HWCryptoHook is telling us
  1024. * that falling back to software computation might be a good thing.
  1025. */
  1026. if (ret == HWCRYPTOHOOK_ERROR_FALLBACK) {
  1027. HWCRHKerr(HWCRHK_F_HWCRHK_RAND_BYTES, HWCRHK_R_REQUEST_FALLBACK);
  1028. } else {
  1029. HWCRHKerr(HWCRHK_F_HWCRHK_RAND_BYTES, HWCRHK_R_REQUEST_FAILED);
  1030. }
  1031. ERR_add_error_data(1, rmsg.buf);
  1032. goto err;
  1033. }
  1034. to_return = 1;
  1035. err:
  1036. return to_return;
  1037. }
  1038. static int hwcrhk_rand_status(void)
  1039. {
  1040. return 1;
  1041. }
  1042. /*
  1043. * Mutex calls: since the HWCryptoHook model closely follows the POSIX model
  1044. * these just wrap the POSIX functions and add some logging.
  1045. */
  1046. static int hwcrhk_mutex_init(HWCryptoHook_Mutex * mt,
  1047. HWCryptoHook_CallerContext * cactx)
  1048. {
  1049. mt->lockid = CRYPTO_get_new_dynlockid();
  1050. if (mt->lockid == 0)
  1051. return 1; /* failure */
  1052. return 0; /* success */
  1053. }
  1054. static int hwcrhk_mutex_lock(HWCryptoHook_Mutex * mt)
  1055. {
  1056. CRYPTO_w_lock(mt->lockid);
  1057. return 0;
  1058. }
  1059. static void hwcrhk_mutex_unlock(HWCryptoHook_Mutex * mt)
  1060. {
  1061. CRYPTO_w_unlock(mt->lockid);
  1062. }
  1063. static void hwcrhk_mutex_destroy(HWCryptoHook_Mutex * mt)
  1064. {
  1065. CRYPTO_destroy_dynlockid(mt->lockid);
  1066. }
  1067. static int hwcrhk_get_pass(const char *prompt_info,
  1068. int *len_io, char *buf,
  1069. HWCryptoHook_PassphraseContext * ppctx,
  1070. HWCryptoHook_CallerContext * cactx)
  1071. {
  1072. pem_password_cb *callback = NULL;
  1073. void *callback_data = NULL;
  1074. UI_METHOD *ui_method = NULL;
  1075. /*
  1076. * Despite what the documentation says prompt_info can be an empty
  1077. * string.
  1078. */
  1079. if (prompt_info && !*prompt_info)
  1080. prompt_info = NULL;
  1081. if (cactx) {
  1082. if (cactx->ui_method)
  1083. ui_method = cactx->ui_method;
  1084. if (cactx->password_callback)
  1085. callback = cactx->password_callback;
  1086. if (cactx->callback_data)
  1087. callback_data = cactx->callback_data;
  1088. }
  1089. if (ppctx) {
  1090. if (ppctx->ui_method) {
  1091. ui_method = ppctx->ui_method;
  1092. callback = NULL;
  1093. }
  1094. if (ppctx->callback_data)
  1095. callback_data = ppctx->callback_data;
  1096. }
  1097. if (callback == NULL && ui_method == NULL) {
  1098. HWCRHKerr(HWCRHK_F_HWCRHK_GET_PASS, HWCRHK_R_NO_CALLBACK);
  1099. return -1;
  1100. }
  1101. if (ui_method) {
  1102. UI *ui = UI_new_method(ui_method);
  1103. if (ui) {
  1104. int ok;
  1105. char *prompt = UI_construct_prompt(ui,
  1106. "pass phrase", prompt_info);
  1107. ok = UI_add_input_string(ui, prompt,
  1108. UI_INPUT_FLAG_DEFAULT_PWD,
  1109. buf, 0, (*len_io) - 1);
  1110. UI_add_user_data(ui, callback_data);
  1111. UI_ctrl(ui, UI_CTRL_PRINT_ERRORS, 1, 0, 0);
  1112. if (ok >= 0)
  1113. do {
  1114. ok = UI_process(ui);
  1115. }
  1116. while (ok < 0 && UI_ctrl(ui, UI_CTRL_IS_REDOABLE, 0, 0, 0));
  1117. if (ok >= 0)
  1118. *len_io = strlen(buf);
  1119. UI_free(ui);
  1120. OPENSSL_free(prompt);
  1121. }
  1122. } else {
  1123. *len_io = callback(buf, *len_io, 0, callback_data);
  1124. }
  1125. if (!*len_io)
  1126. return -1;
  1127. return 0;
  1128. }
  1129. static int hwcrhk_insert_card(const char *prompt_info,
  1130. const char *wrong_info,
  1131. HWCryptoHook_PassphraseContext * ppctx,
  1132. HWCryptoHook_CallerContext * cactx)
  1133. {
  1134. int ok = -1;
  1135. UI *ui;
  1136. void *callback_data = NULL;
  1137. UI_METHOD *ui_method = NULL;
  1138. if (cactx) {
  1139. if (cactx->ui_method)
  1140. ui_method = cactx->ui_method;
  1141. if (cactx->callback_data)
  1142. callback_data = cactx->callback_data;
  1143. }
  1144. if (ppctx) {
  1145. if (ppctx->ui_method)
  1146. ui_method = ppctx->ui_method;
  1147. if (ppctx->callback_data)
  1148. callback_data = ppctx->callback_data;
  1149. }
  1150. if (ui_method == NULL) {
  1151. HWCRHKerr(HWCRHK_F_HWCRHK_INSERT_CARD, HWCRHK_R_NO_CALLBACK);
  1152. return -1;
  1153. }
  1154. ui = UI_new_method(ui_method);
  1155. if (ui) {
  1156. char answer;
  1157. char buf[BUFSIZ];
  1158. /*
  1159. * Despite what the documentation says wrong_info can be an empty
  1160. * string.
  1161. */
  1162. if (wrong_info && *wrong_info)
  1163. BIO_snprintf(buf, sizeof(buf) - 1,
  1164. "Current card: \"%s\"\n", wrong_info);
  1165. else
  1166. buf[0] = 0;
  1167. ok = UI_dup_info_string(ui, buf);
  1168. if (ok >= 0 && prompt_info) {
  1169. BIO_snprintf(buf, sizeof(buf) - 1,
  1170. "Insert card \"%s\"", prompt_info);
  1171. ok = UI_dup_input_boolean(ui, buf,
  1172. "\n then hit <enter> or C<enter> to cancel\n",
  1173. "\r\n", "Cc", UI_INPUT_FLAG_ECHO,
  1174. &answer);
  1175. }
  1176. UI_add_user_data(ui, callback_data);
  1177. if (ok >= 0)
  1178. ok = UI_process(ui);
  1179. UI_free(ui);
  1180. if (ok == -2 || (ok >= 0 && answer == 'C'))
  1181. ok = 1;
  1182. else if (ok < 0)
  1183. ok = -1;
  1184. else
  1185. ok = 0;
  1186. }
  1187. return ok;
  1188. }
  1189. static void hwcrhk_log_message(void *logstr, const char *message)
  1190. {
  1191. BIO *lstream = NULL;
  1192. CRYPTO_w_lock(CRYPTO_LOCK_BIO);
  1193. if (logstr)
  1194. lstream = *(BIO **)logstr;
  1195. if (lstream) {
  1196. BIO_printf(lstream, "%s\n", message);
  1197. }
  1198. CRYPTO_w_unlock(CRYPTO_LOCK_BIO);
  1199. }
  1200. /*
  1201. * This stuff is needed if this ENGINE is being compiled into a
  1202. * self-contained shared-library.
  1203. */
  1204. # ifndef OPENSSL_NO_DYNAMIC_ENGINE
  1205. static int bind_fn(ENGINE *e, const char *id)
  1206. {
  1207. if (id && (strcmp(id, engine_hwcrhk_id) != 0) &&
  1208. (strcmp(id, engine_hwcrhk_id_alt) != 0))
  1209. return 0;
  1210. if (!bind_helper(e))
  1211. return 0;
  1212. return 1;
  1213. }
  1214. IMPLEMENT_DYNAMIC_CHECK_FN()
  1215. IMPLEMENT_DYNAMIC_BIND_FN(bind_fn)
  1216. # endif /* OPENSSL_NO_DYNAMIC_ENGINE */
  1217. # endif /* !OPENSSL_NO_HW_CHIL */
  1218. #endif /* !OPENSSL_NO_HW */