e_chil.c 41 KB

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