e_chil.c 37 KB

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