From: Richard Levitte Date: Tue, 28 Feb 2017 13:47:55 +0000 (+0100) Subject: Move the CHIL engine to demos/engines X-Git-Tag: OpenSSL_1_1_1-pre1~2241 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=44e2d45ffdcda4160d7d36a5b0ee702d0ebad8ac;p=oweals%2Fopenssl.git Move the CHIL engine to demos/engines Moving out of the way, Makefile to be added Reviewed-by: Rich Salz (Merged from https://github.com/openssl/openssl/pull/2780) --- diff --git a/demos/engines/e_chil.c b/demos/engines/e_chil.c new file mode 100644 index 0000000000..8d81b46fec --- /dev/null +++ b/demos/engines/e_chil.c @@ -0,0 +1,1285 @@ +/* + * Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include +#include +#include "internal/dso.h" +#include +#include +#include +#ifndef OPENSSL_NO_RSA +# include +#endif +#ifndef OPENSSL_NO_DH +# include +#endif +#include + +#ifndef OPENSSL_NO_HW +# ifndef OPENSSL_NO_HW_CHIL + +/*- + * Attribution notice: nCipher have said several times that it's OK for + * us to implement a general interface to their boxes, and recently declared + * their HWCryptoHook to be public, and therefore available for us to use. + * Thanks, nCipher. + * + * The hwcryptohook.h included here is from May 2000. + * [Richard Levitte] + */ +# ifdef FLAT_INC +# include "hwcryptohook.h" +# else +# include "vendor_defns/hwcryptohook.h" +# endif + +# define HWCRHK_LIB_NAME "CHIL engine" +# include "e_chil_err.c" + +static CRYPTO_RWLOCK *chil_lock; + +static int hwcrhk_destroy(ENGINE *e); +static int hwcrhk_init(ENGINE *e); +static int hwcrhk_finish(ENGINE *e); +static int hwcrhk_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void)); + +/* Functions to handle mutexes */ +static int hwcrhk_mutex_init(HWCryptoHook_Mutex *, + HWCryptoHook_CallerContext *); +static int hwcrhk_mutex_lock(HWCryptoHook_Mutex *); +static void hwcrhk_mutex_unlock(HWCryptoHook_Mutex *); +static void hwcrhk_mutex_destroy(HWCryptoHook_Mutex *); + +/* BIGNUM stuff */ +static int hwcrhk_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx); + +# ifndef OPENSSL_NO_RSA +/* RSA stuff */ +static int hwcrhk_rsa_mod_exp(BIGNUM *r, const BIGNUM *I, RSA *rsa, + BN_CTX *ctx); +/* This function is aliased to mod_exp (with the mont stuff dropped). */ +static int hwcrhk_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, + BN_MONT_CTX *m_ctx); +static int hwcrhk_rsa_finish(RSA *rsa); +# endif + +# ifndef OPENSSL_NO_DH +/* DH stuff */ +/* This function is alised to mod_exp (with the DH and mont dropped). */ +static int hwcrhk_mod_exp_dh(const DH *dh, BIGNUM *r, + const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, + BN_MONT_CTX *m_ctx); +# endif + +/* RAND stuff */ +static int hwcrhk_rand_bytes(unsigned char *buf, int num); +static int hwcrhk_rand_status(void); + +/* KM stuff */ +static EVP_PKEY *hwcrhk_load_privkey(ENGINE *eng, const char *key_id, + UI_METHOD *ui_method, + void *callback_data); +static EVP_PKEY *hwcrhk_load_pubkey(ENGINE *eng, const char *key_id, + UI_METHOD *ui_method, + void *callback_data); + +/* Interaction stuff */ +static int hwcrhk_insert_card(const char *prompt_info, + const char *wrong_info, + HWCryptoHook_PassphraseContext * ppctx, + HWCryptoHook_CallerContext * cactx); +static int hwcrhk_get_pass(const char *prompt_info, + int *len_io, char *buf, + HWCryptoHook_PassphraseContext * ppctx, + HWCryptoHook_CallerContext * cactx); +static void hwcrhk_log_message(void *logstr, const char *message); + +/* The definitions for control commands specific to this engine */ +# define HWCRHK_CMD_SO_PATH ENGINE_CMD_BASE +# define HWCRHK_CMD_FORK_CHECK (ENGINE_CMD_BASE + 1) +# define HWCRHK_CMD_THREAD_LOCKING (ENGINE_CMD_BASE + 2) +# define HWCRHK_CMD_SET_USER_INTERFACE (ENGINE_CMD_BASE + 3) +# define HWCRHK_CMD_SET_CALLBACK_DATA (ENGINE_CMD_BASE + 4) +static const ENGINE_CMD_DEFN hwcrhk_cmd_defns[] = { + {HWCRHK_CMD_SO_PATH, + "SO_PATH", + "Specifies the path to the 'hwcrhk' shared library", + ENGINE_CMD_FLAG_STRING}, + {HWCRHK_CMD_FORK_CHECK, + "FORK_CHECK", + "Turns fork() checking on (non-zero) or off (zero)", + ENGINE_CMD_FLAG_NUMERIC}, + {HWCRHK_CMD_THREAD_LOCKING, + "THREAD_LOCKING", + "Turns thread-safe locking on (zero) or off (non-zero)", + ENGINE_CMD_FLAG_NUMERIC}, + {HWCRHK_CMD_SET_USER_INTERFACE, + "SET_USER_INTERFACE", + "Set the global user interface (internal)", + ENGINE_CMD_FLAG_INTERNAL}, + {HWCRHK_CMD_SET_CALLBACK_DATA, + "SET_CALLBACK_DATA", + "Set the global user interface extra data (internal)", + ENGINE_CMD_FLAG_INTERNAL}, + {0, NULL, NULL, 0} +}; + +# ifndef OPENSSL_NO_RSA +/* Our internal RSA_METHOD that we provide pointers to */ +static RSA_METHOD hwcrhk_rsa = { + "CHIL RSA method", + NULL, + NULL, + NULL, + NULL, + hwcrhk_rsa_mod_exp, + hwcrhk_mod_exp_mont, + NULL, + hwcrhk_rsa_finish, + 0, + NULL, + NULL, + NULL, + NULL +}; +# endif + +# ifndef OPENSSL_NO_DH +/* Our internal DH_METHOD that we provide pointers to */ +static DH_METHOD hwcrhk_dh = { + "CHIL DH method", + NULL, + NULL, + hwcrhk_mod_exp_dh, + NULL, + NULL, + 0, + NULL, + NULL +}; +# endif + +static RAND_METHOD hwcrhk_rand = { + /* "CHIL RAND method", */ + NULL, + hwcrhk_rand_bytes, + NULL, + NULL, + hwcrhk_rand_bytes, + hwcrhk_rand_status, +}; + +/* Constants used when creating the ENGINE */ +static const char *engine_hwcrhk_id = "chil"; +static const char *engine_hwcrhk_name = "CHIL hardware engine support"; +# ifndef OPENSSL_NO_DYNAMIC_ENGINE +/* Compatibility hack, the dynamic library uses this form in the path */ +static const char *engine_hwcrhk_id_alt = "ncipher"; +# endif + +/* Internal stuff for HWCryptoHook */ + +/* Some structures needed for proper use of thread locks */ +/* + * hwcryptohook.h has some typedefs that turn struct HWCryptoHook_MutexValue + * into HWCryptoHook_Mutex + */ +struct HWCryptoHook_MutexValue { + CRYPTO_RWLOCK *lock; +}; + +/* + * hwcryptohook.h has some typedefs that turn struct + * HWCryptoHook_PassphraseContextValue into HWCryptoHook_PassphraseContext + */ +struct HWCryptoHook_PassphraseContextValue { + UI_METHOD *ui_method; + void *callback_data; +}; + +/* + * hwcryptohook.h has some typedefs that turn struct + * HWCryptoHook_CallerContextValue into HWCryptoHook_CallerContext + */ +struct HWCryptoHook_CallerContextValue { + pem_password_cb *password_callback; /* Deprecated! Only present for + * backward compatibility! */ + UI_METHOD *ui_method; + void *callback_data; +}; + +/* + * The MPI structure in HWCryptoHook is pretty compatible with OpenSSL + * BIGNUM's, so lets define a couple of conversion macros + */ +# define BN2MPI(mp, bn) \ + {mp.size = bn->top * sizeof(BN_ULONG); mp.buf = (unsigned char *)bn->d;} +# define MPI2BN(bn, mp) \ + {mp.size = bn->dmax * sizeof(BN_ULONG); mp.buf = (unsigned char *)bn->d;} + +static BIO *logstream = NULL; +static int disable_mutex_callbacks = 0; + +/* + * One might wonder why these are needed, since one can pass down at least a + * UI_METHOD and a pointer to callback data to the key-loading functions. The + * thing is that the ModExp and RSAImmed functions can load keys as well, if + * the data they get is in a special, nCipher-defined format (hint: if you + * look at the private exponent of the RSA data as a string, you'll see this + * string: "nCipher KM tool key id", followed by some bytes, followed a key + * identity string, followed by more bytes. This happens when you use + * "embed" keys instead of "hwcrhk" keys). Unfortunately, those functions do + * not take any passphrase or caller context, and our functions can't really + * take any callback data either. Still, the "insert_card" and + * "get_passphrase" callbacks may be called down the line, and will need to + * know what user interface callbacks to call, and having callback data from + * the application may be a nice thing as well, so we need to keep track of + * that globally. + */ +static HWCryptoHook_CallerContext password_context = { NULL, NULL, NULL }; + +/* Stuff to pass to the HWCryptoHook library */ +static HWCryptoHook_InitInfo hwcrhk_globals = { + HWCryptoHook_InitFlags_SimpleForkCheck, /* Flags */ + &logstream, /* logstream */ + sizeof(BN_ULONG), /* limbsize */ + 0, /* mslimb first: false for BNs */ + -1, /* msbyte first: use native */ + 0, /* Max mutexes, 0 = no small limit */ + 0, /* Max simultaneous, 0 = default */ + + /* + * The next few are mutex stuff: we write wrapper functions around the OS + * mutex functions. We initialise them to 0 here, and change that to + * actual function pointers in hwcrhk_init() if dynamic locks are + * supported (that is, if the application programmer has made sure of + * setting up callbacks bafore starting this engine) *and* if + * disable_mutex_callbacks hasn't been set by a call to + * ENGINE_ctrl(ENGINE_CTRL_CHIL_NO_LOCKING). + */ + sizeof(HWCryptoHook_Mutex), + 0, + 0, + 0, + 0, + + /* + * The next few are condvar stuff: we write wrapper functions round the + * OS functions. Currently not implemented and not and absolute + * necessity even in threaded programs, therefore 0'ed. Will hopefully + * be implemented some day, since it enhances the efficiency of + * HWCryptoHook. + */ + 0, /* sizeof(HWCryptoHook_CondVar), */ + 0, /* hwcrhk_cv_init, */ + 0, /* hwcrhk_cv_wait, */ + 0, /* hwcrhk_cv_signal, */ + 0, /* hwcrhk_cv_broadcast, */ + 0, /* hwcrhk_cv_destroy, */ + + hwcrhk_get_pass, /* pass phrase */ + hwcrhk_insert_card, /* insert a card */ + hwcrhk_log_message /* Log message */ +}; + +/* Now, to our own code */ + +/* + * This internal function is used by ENGINE_chil() and possibly by the + * "dynamic" ENGINE support too + */ +static int bind_helper(ENGINE *e) +{ +# ifndef OPENSSL_NO_RSA + const RSA_METHOD *meth1; +# endif +# ifndef OPENSSL_NO_DH + const DH_METHOD *meth2; +# endif + + chil_lock = CRYPTO_THREAD_lock_new(); + if (chil_lock == NULL) { + HWCRHKerr(HWCRHK_F_BIND_HELPER, ERR_R_MALLOC_FAILURE); + return 0; + } + + if (!ENGINE_set_id(e, engine_hwcrhk_id) || + !ENGINE_set_name(e, engine_hwcrhk_name) || +# ifndef OPENSSL_NO_RSA + !ENGINE_set_RSA(e, &hwcrhk_rsa) || +# endif +# ifndef OPENSSL_NO_DH + !ENGINE_set_DH(e, &hwcrhk_dh) || +# endif + !ENGINE_set_RAND(e, &hwcrhk_rand) || + !ENGINE_set_destroy_function(e, hwcrhk_destroy) || + !ENGINE_set_init_function(e, hwcrhk_init) || + !ENGINE_set_finish_function(e, hwcrhk_finish) || + !ENGINE_set_ctrl_function(e, hwcrhk_ctrl) || + !ENGINE_set_load_privkey_function(e, hwcrhk_load_privkey) || + !ENGINE_set_load_pubkey_function(e, hwcrhk_load_pubkey) || + !ENGINE_set_cmd_defns(e, hwcrhk_cmd_defns)) + return 0; + +# ifndef OPENSSL_NO_RSA + /* + * We know that the "PKCS1_OpenSSL()" functions hook properly to the + * cswift-specific mod_exp and mod_exp_crt so we use those functions. NB: + * We don't use ENGINE_openssl() or anything "more generic" because + * something like the RSAref code may not hook properly, and if you own + * one of these cards then you have the right to do RSA operations on it + * anyway! + */ + meth1 = RSA_PKCS1_OpenSSL(); + hwcrhk_rsa.rsa_pub_enc = meth1->rsa_pub_enc; + hwcrhk_rsa.rsa_pub_dec = meth1->rsa_pub_dec; + hwcrhk_rsa.rsa_priv_enc = meth1->rsa_priv_enc; + hwcrhk_rsa.rsa_priv_dec = meth1->rsa_priv_dec; +# endif + +# ifndef OPENSSL_NO_DH + /* Much the same for Diffie-Hellman */ + meth2 = DH_OpenSSL(); + hwcrhk_dh.generate_key = meth2->generate_key; + hwcrhk_dh.compute_key = meth2->compute_key; +# endif + + /* Ensure the hwcrhk error handling is set up */ + ERR_load_HWCRHK_strings(); + + return 1; +} + +# ifdef OPENSSL_NO_DYNAMIC_ENGINE +static ENGINE *engine_chil(void) +{ + ENGINE *ret = ENGINE_new(); + if (ret == NULL) + return NULL; + if (!bind_helper(ret)) { + ENGINE_free(ret); + return NULL; + } + return ret; +} + +void ENGINE_load_chil(void) +{ + /* Copied from eng_[openssl|dyn].c */ + ENGINE *toadd = engine_chil(); + if (!toadd) + return; + ENGINE_add(toadd); + ENGINE_free(toadd); + ERR_clear_error(); +} +# endif + +/* + * This is a process-global DSO handle used for loading and unloading the + * HWCryptoHook library. NB: This is only set (or unset) during an init() or + * finish() call (reference counts permitting) and they're operating with + * global locks, so this should be thread-safe implicitly. + */ +static DSO *hwcrhk_dso = NULL; +static HWCryptoHook_ContextHandle hwcrhk_context = 0; +# ifndef OPENSSL_NO_RSA +/* Index for KM handle. Not really used yet. */ +static int hndidx_rsa = -1; +# endif + +/* + * These are the function pointers that are (un)set when the library has + * successfully (un)loaded. + */ +static HWCryptoHook_Init_t *p_hwcrhk_Init = NULL; +static HWCryptoHook_Finish_t *p_hwcrhk_Finish = NULL; +static HWCryptoHook_ModExp_t *p_hwcrhk_ModExp = NULL; +# ifndef OPENSSL_NO_RSA +static HWCryptoHook_RSA_t *p_hwcrhk_RSA = NULL; +# endif +static HWCryptoHook_RandomBytes_t *p_hwcrhk_RandomBytes = NULL; +# ifndef OPENSSL_NO_RSA +static HWCryptoHook_RSALoadKey_t *p_hwcrhk_RSALoadKey = NULL; +static HWCryptoHook_RSAGetPublicKey_t *p_hwcrhk_RSAGetPublicKey = NULL; +static HWCryptoHook_RSAUnloadKey_t *p_hwcrhk_RSAUnloadKey = NULL; +# endif +static HWCryptoHook_ModExpCRT_t *p_hwcrhk_ModExpCRT = NULL; + +/* Used in the DSO operations. */ +static const char *HWCRHK_LIBNAME = NULL; +static void free_HWCRHK_LIBNAME(void) +{ + OPENSSL_free(HWCRHK_LIBNAME); + HWCRHK_LIBNAME = NULL; +} + +static const char *get_HWCRHK_LIBNAME(void) +{ + if (HWCRHK_LIBNAME) + return HWCRHK_LIBNAME; + return "nfhwcrhk"; +} + +static long set_HWCRHK_LIBNAME(const char *name) +{ + free_HWCRHK_LIBNAME(); + return (((HWCRHK_LIBNAME = OPENSSL_strdup(name)) != NULL) ? 1 : 0); +} + +static const char *n_hwcrhk_Init = "HWCryptoHook_Init"; +static const char *n_hwcrhk_Finish = "HWCryptoHook_Finish"; +static const char *n_hwcrhk_ModExp = "HWCryptoHook_ModExp"; +# ifndef OPENSSL_NO_RSA +static const char *n_hwcrhk_RSA = "HWCryptoHook_RSA"; +# endif +static const char *n_hwcrhk_RandomBytes = "HWCryptoHook_RandomBytes"; +# ifndef OPENSSL_NO_RSA +static const char *n_hwcrhk_RSALoadKey = "HWCryptoHook_RSALoadKey"; +static const char *n_hwcrhk_RSAGetPublicKey = "HWCryptoHook_RSAGetPublicKey"; +static const char *n_hwcrhk_RSAUnloadKey = "HWCryptoHook_RSAUnloadKey"; +# endif +static const char *n_hwcrhk_ModExpCRT = "HWCryptoHook_ModExpCRT"; + +/* + * HWCryptoHook library functions and mechanics - these are used by the + * higher-level functions further down. NB: As and where there's no error + * checking, take a look lower down where these functions are called, the + * checking and error handling is probably down there. + */ + +/* utility function to obtain a context */ +static int get_context(HWCryptoHook_ContextHandle * hac, + HWCryptoHook_CallerContext * cac) +{ + char tempbuf[1024]; + HWCryptoHook_ErrMsgBuf rmsg; + + rmsg.buf = tempbuf; + rmsg.size = sizeof(tempbuf); + + *hac = p_hwcrhk_Init(&hwcrhk_globals, sizeof(hwcrhk_globals), &rmsg, cac); + if (!*hac) + return 0; + return 1; +} + +/* similarly to release one. */ +static void release_context(HWCryptoHook_ContextHandle hac) +{ + p_hwcrhk_Finish(hac); +} + +/* Destructor (complements the "ENGINE_chil()" constructor) */ +static int hwcrhk_destroy(ENGINE *e) +{ + free_HWCRHK_LIBNAME(); + ERR_unload_HWCRHK_strings(); + CRYPTO_THREAD_lock_free(chil_lock); + return 1; +} + +/* (de)initialisation functions. */ +static int hwcrhk_init(ENGINE *e) +{ + HWCryptoHook_Init_t *p1; + HWCryptoHook_Finish_t *p2; + HWCryptoHook_ModExp_t *p3; +# ifndef OPENSSL_NO_RSA + HWCryptoHook_RSA_t *p4; + HWCryptoHook_RSALoadKey_t *p5; + HWCryptoHook_RSAGetPublicKey_t *p6; + HWCryptoHook_RSAUnloadKey_t *p7; +# endif + HWCryptoHook_RandomBytes_t *p8; + HWCryptoHook_ModExpCRT_t *p9; + + if (hwcrhk_dso != NULL) { + HWCRHKerr(HWCRHK_F_HWCRHK_INIT, HWCRHK_R_ALREADY_LOADED); + goto err; + } + /* Attempt to load libnfhwcrhk.so/nfhwcrhk.dll/whatever. */ + hwcrhk_dso = DSO_load(NULL, get_HWCRHK_LIBNAME(), NULL, 0); + if (hwcrhk_dso == NULL) { + HWCRHKerr(HWCRHK_F_HWCRHK_INIT, HWCRHK_R_DSO_FAILURE); + goto err; + } + +#define BINDIT(t, name) (t *)DSO_bind_func(hwcrhk_dso, name) + if ((p1 = BINDIT(HWCryptoHook_Init_t, n_hwcrhk_Init)) == NULL + || (p2 = BINDIT(HWCryptoHook_Finish_t, n_hwcrhk_Finish)) == NULL + || (p3 = BINDIT(HWCryptoHook_ModExp_t, n_hwcrhk_ModExp)) == NULL +# ifndef OPENSSL_NO_RSA + || (p4 = BINDIT(HWCryptoHook_RSA_t, n_hwcrhk_RSA)) == NULL + || (p5 = BINDIT(HWCryptoHook_RSALoadKey_t, n_hwcrhk_RSALoadKey)) == NULL + || (p6 = BINDIT(HWCryptoHook_RSAGetPublicKey_t, n_hwcrhk_RSAGetPublicKey)) == NULL + || (p7 = BINDIT(HWCryptoHook_RSAUnloadKey_t, n_hwcrhk_RSAUnloadKey)) == NULL +# endif + || (p8 = BINDIT(HWCryptoHook_RandomBytes_t, n_hwcrhk_RandomBytes)) == NULL + || (p9 = BINDIT(HWCryptoHook_ModExpCRT_t, n_hwcrhk_ModExpCRT)) == NULL) { + HWCRHKerr(HWCRHK_F_HWCRHK_INIT, HWCRHK_R_DSO_FAILURE); + goto err; + } + /* Copy the pointers */ + p_hwcrhk_Init = p1; + p_hwcrhk_Finish = p2; + p_hwcrhk_ModExp = p3; +# ifndef OPENSSL_NO_RSA + p_hwcrhk_RSA = p4; + p_hwcrhk_RSALoadKey = p5; + p_hwcrhk_RSAGetPublicKey = p6; + p_hwcrhk_RSAUnloadKey = p7; +# endif + p_hwcrhk_RandomBytes = p8; + p_hwcrhk_ModExpCRT = p9; + + /* + * Check if the application decided to support dynamic locks, and if it + * does, use them. + */ + if (disable_mutex_callbacks == 0) { + hwcrhk_globals.mutex_init = hwcrhk_mutex_init; + hwcrhk_globals.mutex_acquire = hwcrhk_mutex_lock; + hwcrhk_globals.mutex_release = hwcrhk_mutex_unlock; + hwcrhk_globals.mutex_destroy = hwcrhk_mutex_destroy; + } + + /* + * Try and get a context - if not, we may have a DSO but no accelerator! + */ + if (!get_context(&hwcrhk_context, &password_context)) { + HWCRHKerr(HWCRHK_F_HWCRHK_INIT, HWCRHK_R_UNIT_FAILURE); + goto err; + } + /* Everything's fine. */ +# ifndef OPENSSL_NO_RSA + if (hndidx_rsa == -1) + hndidx_rsa = RSA_get_ex_new_index(0, + "nFast HWCryptoHook RSA key handle", + NULL, NULL, NULL); +# endif + return 1; + err: + DSO_free(hwcrhk_dso); + hwcrhk_dso = NULL; + p_hwcrhk_Init = NULL; + p_hwcrhk_Finish = NULL; + p_hwcrhk_ModExp = NULL; +# ifndef OPENSSL_NO_RSA + p_hwcrhk_RSA = NULL; + p_hwcrhk_RSALoadKey = NULL; + p_hwcrhk_RSAGetPublicKey = NULL; + p_hwcrhk_RSAUnloadKey = NULL; +# endif + p_hwcrhk_ModExpCRT = NULL; + p_hwcrhk_RandomBytes = NULL; + return 0; +} + +static int hwcrhk_finish(ENGINE *e) +{ + int to_return = 1; + free_HWCRHK_LIBNAME(); + if (hwcrhk_dso == NULL) { + HWCRHKerr(HWCRHK_F_HWCRHK_FINISH, HWCRHK_R_NOT_LOADED); + to_return = 0; + goto err; + } + release_context(hwcrhk_context); + if (!DSO_free(hwcrhk_dso)) { + HWCRHKerr(HWCRHK_F_HWCRHK_FINISH, HWCRHK_R_DSO_FAILURE); + to_return = 0; + goto err; + } + err: + BIO_free(logstream); + hwcrhk_dso = NULL; + p_hwcrhk_Init = NULL; + p_hwcrhk_Finish = NULL; + p_hwcrhk_ModExp = NULL; +# ifndef OPENSSL_NO_RSA + p_hwcrhk_RSA = NULL; + p_hwcrhk_RSALoadKey = NULL; + p_hwcrhk_RSAGetPublicKey = NULL; + p_hwcrhk_RSAUnloadKey = NULL; +# endif + p_hwcrhk_ModExpCRT = NULL; + p_hwcrhk_RandomBytes = NULL; + return to_return; +} + +static int hwcrhk_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void)) +{ + int to_return = 1; + + switch (cmd) { + case HWCRHK_CMD_SO_PATH: + if (hwcrhk_dso) { + HWCRHKerr(HWCRHK_F_HWCRHK_CTRL, HWCRHK_R_ALREADY_LOADED); + return 0; + } + if (p == NULL) { + HWCRHKerr(HWCRHK_F_HWCRHK_CTRL, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + return set_HWCRHK_LIBNAME((const char *)p); + case ENGINE_CTRL_SET_LOGSTREAM: + { + BIO *bio = (BIO *)p; + + CRYPTO_THREAD_write_lock(chil_lock); + BIO_free(logstream); + logstream = NULL; + if (BIO_up_ref(bio)) + logstream = bio; + else + HWCRHKerr(HWCRHK_F_HWCRHK_CTRL, HWCRHK_R_BIO_WAS_FREED); + } + CRYPTO_THREAD_unlock(chil_lock); + break; + case ENGINE_CTRL_SET_PASSWORD_CALLBACK: + CRYPTO_THREAD_write_lock(chil_lock); + password_context.password_callback = (pem_password_cb *)f; + CRYPTO_THREAD_unlock(chil_lock); + break; + case ENGINE_CTRL_SET_USER_INTERFACE: + case HWCRHK_CMD_SET_USER_INTERFACE: + CRYPTO_THREAD_write_lock(chil_lock); + password_context.ui_method = (UI_METHOD *)p; + CRYPTO_THREAD_unlock(chil_lock); + break; + case ENGINE_CTRL_SET_CALLBACK_DATA: + case HWCRHK_CMD_SET_CALLBACK_DATA: + CRYPTO_THREAD_write_lock(chil_lock); + password_context.callback_data = p; + CRYPTO_THREAD_unlock(chil_lock); + break; + /* + * this enables or disables the "SimpleForkCheck" flag used in the + * initialisation structure. + */ + case ENGINE_CTRL_CHIL_SET_FORKCHECK: + case HWCRHK_CMD_FORK_CHECK: + CRYPTO_THREAD_write_lock(chil_lock); + if (i) + hwcrhk_globals.flags |= HWCryptoHook_InitFlags_SimpleForkCheck; + else + hwcrhk_globals.flags &= ~HWCryptoHook_InitFlags_SimpleForkCheck; + CRYPTO_THREAD_unlock(chil_lock); + break; + /* + * This will prevent the initialisation function from "installing" + * the mutex-handling callbacks, even if they are available from + * within the library (or were provided to the library from the + * calling application). This is to remove any baggage for + * applications not using multithreading. + */ + case ENGINE_CTRL_CHIL_NO_LOCKING: + CRYPTO_THREAD_write_lock(chil_lock); + disable_mutex_callbacks = 1; + CRYPTO_THREAD_unlock(chil_lock); + break; + case HWCRHK_CMD_THREAD_LOCKING: + CRYPTO_THREAD_write_lock(chil_lock); + disable_mutex_callbacks = ((i == 0) ? 0 : 1); + CRYPTO_THREAD_unlock(chil_lock); + break; + + /* The command isn't understood by this engine */ + default: + HWCRHKerr(HWCRHK_F_HWCRHK_CTRL, + HWCRHK_R_CTRL_COMMAND_NOT_IMPLEMENTED); + to_return = 0; + break; + } + + return to_return; +} + +static EVP_PKEY *hwcrhk_load_privkey(ENGINE *eng, const char *key_id, + UI_METHOD *ui_method, + void *callback_data) +{ +# ifndef OPENSSL_NO_RSA + RSA *rtmp = NULL; +# endif + EVP_PKEY *res = NULL; +# ifndef OPENSSL_NO_RSA + HWCryptoHook_MPI e, n; + HWCryptoHook_RSAKeyHandle *hptr; +# endif +# if !defined(OPENSSL_NO_RSA) + char tempbuf[1024]; + HWCryptoHook_ErrMsgBuf rmsg; + HWCryptoHook_PassphraseContext ppctx; +# endif + +# if !defined(OPENSSL_NO_RSA) + rmsg.buf = tempbuf; + rmsg.size = sizeof(tempbuf); +# endif + + if (!hwcrhk_context) { + HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY, HWCRHK_R_NOT_INITIALISED); + goto err; + } +# ifndef OPENSSL_NO_RSA + hptr = OPENSSL_malloc(sizeof(*hptr)); + if (hptr == NULL) { + HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY, ERR_R_MALLOC_FAILURE); + goto err; + } + ppctx.ui_method = ui_method; + ppctx.callback_data = callback_data; + if (p_hwcrhk_RSALoadKey(hwcrhk_context, key_id, hptr, &rmsg, &ppctx)) { + HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY, HWCRHK_R_CHIL_ERROR); + ERR_add_error_data(1, rmsg.buf); + goto err; + } + if (!*hptr) { + HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY, HWCRHK_R_NO_KEY); + goto err; + } +# endif +# ifndef OPENSSL_NO_RSA + rtmp = RSA_new_method(eng); + RSA_set_ex_data(rtmp, hndidx_rsa, (char *)hptr); + rtmp->e = BN_new(); + rtmp->n = BN_new(); + rtmp->flags |= RSA_FLAG_EXT_PKEY; + MPI2BN(rtmp->e, e); + MPI2BN(rtmp->n, n); + if (p_hwcrhk_RSAGetPublicKey(*hptr, &n, &e, &rmsg) + != HWCRYPTOHOOK_ERROR_MPISIZE) { + HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY, HWCRHK_R_CHIL_ERROR); + ERR_add_error_data(1, rmsg.buf); + goto err; + } + + bn_expand2(rtmp->e, e.size / sizeof(BN_ULONG)); + bn_expand2(rtmp->n, n.size / sizeof(BN_ULONG)); + MPI2BN(rtmp->e, e); + MPI2BN(rtmp->n, n); + + if (p_hwcrhk_RSAGetPublicKey(*hptr, &n, &e, &rmsg)) { + HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY, HWCRHK_R_CHIL_ERROR); + ERR_add_error_data(1, rmsg.buf); + goto err; + } + rtmp->e->top = e.size / sizeof(BN_ULONG); + bn_fix_top(rtmp->e); + rtmp->n->top = n.size / sizeof(BN_ULONG); + bn_fix_top(rtmp->n); + + res = EVP_PKEY_new(); + if (res == NULL) { + HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY, HWCRHK_R_CHIL_ERROR); + goto err; + } + EVP_PKEY_assign_RSA(res, rtmp); +# endif + + if (res == NULL) + HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY, + HWCRHK_R_PRIVATE_KEY_ALGORITHMS_DISABLED); + + return res; + err: +# ifndef OPENSSL_NO_RSA + RSA_free(rtmp); +# endif + return NULL; +} + +static EVP_PKEY *hwcrhk_load_pubkey(ENGINE *eng, const char *key_id, + UI_METHOD *ui_method, void *callback_data) +{ + EVP_PKEY *res = NULL; + +# ifndef OPENSSL_NO_RSA + res = hwcrhk_load_privkey(eng, key_id, ui_method, callback_data); +# endif + + if (res) + switch (res->type) { +# ifndef OPENSSL_NO_RSA + case EVP_PKEY_RSA: + { + RSA *rsa = NULL; + + CRYPTO_THREAD_write_lock(chil_lock); + rsa = res->pkey.rsa; + res->pkey.rsa = RSA_new(); + res->pkey.rsa->n = rsa->n; + res->pkey.rsa->e = rsa->e; + rsa->n = NULL; + rsa->e = NULL; + CRYPTO_THREAD_unlock(chil_lock); + RSA_free(rsa); + } + break; +# endif + default: + HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PUBKEY, + HWCRHK_R_CTRL_COMMAND_NOT_IMPLEMENTED); + goto err; + } + + return res; + err: + EVP_PKEY_free(res); + return NULL; +} + +/* A little mod_exp */ +static int hwcrhk_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx) +{ + char tempbuf[1024]; + HWCryptoHook_ErrMsgBuf rmsg; + /* + * Since HWCryptoHook_MPI is pretty compatible with BIGNUM's, we use them + * directly, plus a little macro magic. We only thing we need to make + * sure of is that enough space is allocated. + */ + HWCryptoHook_MPI m_a, m_p, m_n, m_r; + int to_return, ret; + + to_return = 0; /* expect failure */ + rmsg.buf = tempbuf; + rmsg.size = sizeof(tempbuf); + + if (!hwcrhk_context) { + HWCRHKerr(HWCRHK_F_HWCRHK_MOD_EXP, HWCRHK_R_NOT_INITIALISED); + goto err; + } + /* Prepare the params */ + bn_expand2(r, m->top); /* Check for error !! */ + BN2MPI(m_a, a); + BN2MPI(m_p, p); + BN2MPI(m_n, m); + MPI2BN(r, m_r); + + /* Perform the operation */ + ret = p_hwcrhk_ModExp(hwcrhk_context, m_a, m_p, m_n, &m_r, &rmsg); + + /* Convert the response */ + r->top = m_r.size / sizeof(BN_ULONG); + bn_fix_top(r); + + if (ret < 0) { + /* + * FIXME: When this error is returned, HWCryptoHook is telling us + * that falling back to software computation might be a good thing. + */ + if (ret == HWCRYPTOHOOK_ERROR_FALLBACK) { + HWCRHKerr(HWCRHK_F_HWCRHK_MOD_EXP, HWCRHK_R_REQUEST_FALLBACK); + } else { + HWCRHKerr(HWCRHK_F_HWCRHK_MOD_EXP, HWCRHK_R_REQUEST_FAILED); + } + ERR_add_error_data(1, rmsg.buf); + goto err; + } + + to_return = 1; + err: + return to_return; +} + +# ifndef OPENSSL_NO_RSA +static int hwcrhk_rsa_mod_exp(BIGNUM *r, const BIGNUM *I, RSA *rsa, + BN_CTX *ctx) +{ + char tempbuf[1024]; + HWCryptoHook_ErrMsgBuf rmsg; + HWCryptoHook_RSAKeyHandle *hptr; + int to_return = 0, ret; + + rmsg.buf = tempbuf; + rmsg.size = sizeof(tempbuf); + + if (!hwcrhk_context) { + HWCRHKerr(HWCRHK_F_HWCRHK_RSA_MOD_EXP, HWCRHK_R_NOT_INITIALISED); + goto err; + } + + /* + * This provides support for nForce keys. Since that's opaque data all + * we do is provide a handle to the proper key and let HWCryptoHook take + * care of the rest. + */ + if ((hptr = + (HWCryptoHook_RSAKeyHandle *) RSA_get_ex_data(rsa, hndidx_rsa)) + != NULL) { + HWCryptoHook_MPI m_a, m_r; + + if (!rsa->n) { + HWCRHKerr(HWCRHK_F_HWCRHK_RSA_MOD_EXP, + HWCRHK_R_MISSING_KEY_COMPONENTS); + goto err; + } + + /* Prepare the params */ + bn_expand2(r, rsa->n->top); /* Check for error !! */ + BN2MPI(m_a, I); + MPI2BN(r, m_r); + + /* Perform the operation */ + ret = p_hwcrhk_RSA(m_a, *hptr, &m_r, &rmsg); + + /* Convert the response */ + r->top = m_r.size / sizeof(BN_ULONG); + bn_fix_top(r); + + if (ret < 0) { + /* + * FIXME: When this error is returned, HWCryptoHook is telling us + * that falling back to software computation might be a good + * thing. + */ + if (ret == HWCRYPTOHOOK_ERROR_FALLBACK) { + HWCRHKerr(HWCRHK_F_HWCRHK_RSA_MOD_EXP, + HWCRHK_R_REQUEST_FALLBACK); + } else { + HWCRHKerr(HWCRHK_F_HWCRHK_RSA_MOD_EXP, + HWCRHK_R_REQUEST_FAILED); + } + ERR_add_error_data(1, rmsg.buf); + goto err; + } + } else { + HWCryptoHook_MPI m_a, m_p, m_q, m_dmp1, m_dmq1, m_iqmp, m_r; + + if (!rsa->p || !rsa->q || !rsa->dmp1 || !rsa->dmq1 || !rsa->iqmp) { + HWCRHKerr(HWCRHK_F_HWCRHK_RSA_MOD_EXP, + HWCRHK_R_MISSING_KEY_COMPONENTS); + goto err; + } + + /* Prepare the params */ + bn_expand2(r, rsa->n->top); /* Check for error !! */ + BN2MPI(m_a, I); + BN2MPI(m_p, rsa->p); + BN2MPI(m_q, rsa->q); + BN2MPI(m_dmp1, rsa->dmp1); + BN2MPI(m_dmq1, rsa->dmq1); + BN2MPI(m_iqmp, rsa->iqmp); + MPI2BN(r, m_r); + + /* Perform the operation */ + ret = p_hwcrhk_ModExpCRT(hwcrhk_context, m_a, m_p, m_q, + m_dmp1, m_dmq1, m_iqmp, &m_r, &rmsg); + + /* Convert the response */ + r->top = m_r.size / sizeof(BN_ULONG); + bn_fix_top(r); + + if (ret < 0) { + /* + * FIXME: When this error is returned, HWCryptoHook is telling us + * that falling back to software computation might be a good + * thing. + */ + if (ret == HWCRYPTOHOOK_ERROR_FALLBACK) { + HWCRHKerr(HWCRHK_F_HWCRHK_RSA_MOD_EXP, + HWCRHK_R_REQUEST_FALLBACK); + } else { + HWCRHKerr(HWCRHK_F_HWCRHK_RSA_MOD_EXP, + HWCRHK_R_REQUEST_FAILED); + } + ERR_add_error_data(1, rmsg.buf); + goto err; + } + } + /* + * If we're here, we must be here with some semblance of success :-) + */ + to_return = 1; + err: + return to_return; +} +# endif + +# ifndef OPENSSL_NO_RSA +/* This function is aliased to mod_exp (with the mont stuff dropped). */ +static int hwcrhk_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, + BN_MONT_CTX *m_ctx) +{ + return hwcrhk_mod_exp(r, a, p, m, ctx); +} + +static int hwcrhk_rsa_finish(RSA *rsa) +{ + HWCryptoHook_RSAKeyHandle *hptr; + + hptr = RSA_get_ex_data(rsa, hndidx_rsa); + if (hptr) { + p_hwcrhk_RSAUnloadKey(*hptr, NULL); + OPENSSL_free(hptr); + RSA_set_ex_data(rsa, hndidx_rsa, NULL); + } + return 1; +} + +# endif + +# ifndef OPENSSL_NO_DH +/* This function is aliased to mod_exp (with the dh and mont dropped). */ +static int hwcrhk_mod_exp_dh(const DH *dh, BIGNUM *r, + const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx) +{ + return hwcrhk_mod_exp(r, a, p, m, ctx); +} +# endif + +/* Random bytes are good */ +static int hwcrhk_rand_bytes(unsigned char *buf, int num) +{ + char tempbuf[1024]; + HWCryptoHook_ErrMsgBuf rmsg; + int to_return = 0; /* assume failure */ + int ret; + + rmsg.buf = tempbuf; + rmsg.size = sizeof(tempbuf); + + if (!hwcrhk_context) { + HWCRHKerr(HWCRHK_F_HWCRHK_RAND_BYTES, HWCRHK_R_NOT_INITIALISED); + goto err; + } + + ret = p_hwcrhk_RandomBytes(hwcrhk_context, buf, num, &rmsg); + if (ret < 0) { + /* + * FIXME: When this error is returned, HWCryptoHook is telling us + * that falling back to software computation might be a good thing. + */ + if (ret == HWCRYPTOHOOK_ERROR_FALLBACK) { + HWCRHKerr(HWCRHK_F_HWCRHK_RAND_BYTES, HWCRHK_R_REQUEST_FALLBACK); + } else { + HWCRHKerr(HWCRHK_F_HWCRHK_RAND_BYTES, HWCRHK_R_REQUEST_FAILED); + } + ERR_add_error_data(1, rmsg.buf); + goto err; + } + to_return = 1; + err: + return to_return; +} + +static int hwcrhk_rand_status(void) +{ + return 1; +} + +/* + * Mutex calls: since the HWCryptoHook model closely follows the POSIX model + * these just wrap the POSIX functions and add some logging. + */ + +static int hwcrhk_mutex_init(HWCryptoHook_Mutex * mt, + HWCryptoHook_CallerContext * cactx) +{ + mt->lock = CRYPTO_THREAD_lock_new(); + if (mt->lock == NULL) { + HWCRHKerr(HWCRHK_F_HWCRHK_MUTEX_INIT, ERR_R_MALLOC_FAILURE); + return 1; /* failure */ + } + return 0; /* success */ +} + +static int hwcrhk_mutex_lock(HWCryptoHook_Mutex * mt) +{ + CRYPTO_THREAD_write_lock(mt->lock); + return 0; +} + +static void hwcrhk_mutex_unlock(HWCryptoHook_Mutex * mt) +{ + CRYPTO_THREAD_unlock(mt->lock); +} + +static void hwcrhk_mutex_destroy(HWCryptoHook_Mutex * mt) +{ + CRYPTO_THREAD_lock_free(mt->lock); +} + +static int hwcrhk_get_pass(const char *prompt_info, + int *len_io, char *buf, + HWCryptoHook_PassphraseContext * ppctx, + HWCryptoHook_CallerContext * cactx) +{ + pem_password_cb *callback = NULL; + void *callback_data = NULL; + UI_METHOD *ui_method = NULL; + /* + * Despite what the documentation says prompt_info can be an empty + * string. + */ + if (prompt_info && !*prompt_info) + prompt_info = NULL; + + if (cactx) { + if (cactx->ui_method) + ui_method = cactx->ui_method; + if (cactx->password_callback) + callback = cactx->password_callback; + if (cactx->callback_data) + callback_data = cactx->callback_data; + } + if (ppctx) { + if (ppctx->ui_method) { + ui_method = ppctx->ui_method; + callback = NULL; + } + if (ppctx->callback_data) + callback_data = ppctx->callback_data; + } + if (callback == NULL && ui_method == NULL) { + HWCRHKerr(HWCRHK_F_HWCRHK_GET_PASS, HWCRHK_R_NO_CALLBACK); + return -1; + } + + if (ui_method) { + UI *ui = UI_new_method(ui_method); + if (ui) { + int ok; + char *prompt = UI_construct_prompt(ui, + "pass phrase", prompt_info); + + ok = UI_add_input_string(ui, prompt, + UI_INPUT_FLAG_DEFAULT_PWD, + buf, 0, (*len_io) - 1); + UI_add_user_data(ui, callback_data); + UI_ctrl(ui, UI_CTRL_PRINT_ERRORS, 1, 0, 0); + + if (ok >= 0) + do { + ok = UI_process(ui); + } + while (ok < 0 && UI_ctrl(ui, UI_CTRL_IS_REDOABLE, 0, 0, 0)); + + if (ok >= 0) + *len_io = strlen(buf); + + UI_free(ui); + OPENSSL_free(prompt); + } + } else { + *len_io = callback(buf, *len_io, 0, callback_data); + } + if (!*len_io) + return -1; + return 0; +} + +static int hwcrhk_insert_card(const char *prompt_info, + const char *wrong_info, + HWCryptoHook_PassphraseContext * ppctx, + HWCryptoHook_CallerContext * cactx) +{ + int ok = -1; + UI *ui; + void *callback_data = NULL; + UI_METHOD *ui_method = NULL; + + if (cactx) { + if (cactx->ui_method) + ui_method = cactx->ui_method; + if (cactx->callback_data) + callback_data = cactx->callback_data; + } + if (ppctx) { + if (ppctx->ui_method) + ui_method = ppctx->ui_method; + if (ppctx->callback_data) + callback_data = ppctx->callback_data; + } + if (ui_method == NULL) { + HWCRHKerr(HWCRHK_F_HWCRHK_INSERT_CARD, HWCRHK_R_NO_CALLBACK); + return -1; + } + + ui = UI_new_method(ui_method); + + if (ui) { + char answer = '\0'; + char buf[BUFSIZ]; + /* + * Despite what the documentation says wrong_info can be an empty + * string. + */ + if (wrong_info && *wrong_info) + BIO_snprintf(buf, sizeof(buf) - 1, + "Current card: \"%s\"\n", wrong_info); + else + buf[0] = 0; + ok = UI_dup_info_string(ui, buf); + if (ok >= 0 && prompt_info) { + BIO_snprintf(buf, sizeof(buf) - 1, + "Insert card \"%s\"", prompt_info); + ok = UI_dup_input_boolean(ui, buf, + "\n then hit or C to cancel\n", + "\r\n", "Cc", UI_INPUT_FLAG_ECHO, + &answer); + } + UI_add_user_data(ui, callback_data); + + if (ok >= 0) + ok = UI_process(ui); + UI_free(ui); + + if (ok == -2 || (ok >= 0 && answer == 'C')) + ok = 1; + else if (ok < 0) + ok = -1; + else + ok = 0; + } + return ok; +} + +static void hwcrhk_log_message(void *logstr, const char *message) +{ + BIO *lstream = NULL; + + if (logstr) + lstream = *(BIO **)logstr; + if (lstream) { + BIO_printf(lstream, "%s\n", message); + } +} + +/* + * This stuff is needed if this ENGINE is being compiled into a + * self-contained shared-library. + */ +# ifndef OPENSSL_NO_DYNAMIC_ENGINE +static int bind_fn(ENGINE *e, const char *id) +{ + if (id && (strcmp(id, engine_hwcrhk_id) != 0) && + (strcmp(id, engine_hwcrhk_id_alt) != 0)) + return 0; + if (!bind_helper(e)) + return 0; + return 1; +} + +IMPLEMENT_DYNAMIC_CHECK_FN() + IMPLEMENT_DYNAMIC_BIND_FN(bind_fn) +# endif /* OPENSSL_NO_DYNAMIC_ENGINE */ +# endif /* !OPENSSL_NO_HW_CHIL */ +#endif /* !OPENSSL_NO_HW */ diff --git a/demos/engines/e_chil.ec b/demos/engines/e_chil.ec new file mode 100644 index 0000000000..b5a76e17df --- /dev/null +++ b/demos/engines/e_chil.ec @@ -0,0 +1 @@ +L HWCRHK e_chil_err.h e_chil_err.c diff --git a/demos/engines/e_chil_err.c b/demos/engines/e_chil_err.c new file mode 100644 index 0000000000..0058684f79 --- /dev/null +++ b/demos/engines/e_chil_err.c @@ -0,0 +1,111 @@ +/* + * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +/* + * NOTE: this file was auto generated by the mkerr.pl script: any changes + * made to it will be overwritten when the script next updates this file, + * only reason strings will be preserved. + */ + +#include +#include +#include "e_chil_err.h" + +/* BEGIN ERROR CODES */ +#ifndef OPENSSL_NO_ERR + +# define ERR_FUNC(func) ERR_PACK(0,func,0) +# define ERR_REASON(reason) ERR_PACK(0,0,reason) + +static ERR_STRING_DATA HWCRHK_str_functs[] = { + {ERR_FUNC(HWCRHK_F_HWCRHK_CTRL), "HWCRHK_CTRL"}, + {ERR_FUNC(HWCRHK_F_HWCRHK_FINISH), "HWCRHK_FINISH"}, + {ERR_FUNC(HWCRHK_F_HWCRHK_GET_PASS), "HWCRHK_GET_PASS"}, + {ERR_FUNC(HWCRHK_F_HWCRHK_INIT), "HWCRHK_INIT"}, + {ERR_FUNC(HWCRHK_F_HWCRHK_INSERT_CARD), "HWCRHK_INSERT_CARD"}, + {ERR_FUNC(HWCRHK_F_HWCRHK_LOAD_PRIVKEY), "HWCRHK_LOAD_PRIVKEY"}, + {ERR_FUNC(HWCRHK_F_HWCRHK_LOAD_PUBKEY), "HWCRHK_LOAD_PUBKEY"}, + {ERR_FUNC(HWCRHK_F_HWCRHK_MOD_EXP), "HWCRHK_MOD_EXP"}, + {ERR_FUNC(HWCRHK_F_HWCRHK_RAND_BYTES), "HWCRHK_RAND_BYTES"}, + {ERR_FUNC(HWCRHK_F_HWCRHK_RSA_MOD_EXP), "HWCRHK_RSA_MOD_EXP"}, + {0, NULL} +}; + +static ERR_STRING_DATA HWCRHK_str_reasons[] = { + {ERR_REASON(HWCRHK_R_ALREADY_LOADED), "already loaded"}, + {ERR_REASON(HWCRHK_R_BIO_WAS_FREED), "bio was freed"}, + {ERR_REASON(HWCRHK_R_CHIL_ERROR), "chil error"}, + {ERR_REASON(HWCRHK_R_CTRL_COMMAND_NOT_IMPLEMENTED), + "ctrl command not implemented"}, + {ERR_REASON(HWCRHK_R_DSO_FAILURE), "dso failure"}, + {ERR_REASON(HWCRHK_R_MISSING_KEY_COMPONENTS), "missing key components"}, + {ERR_REASON(HWCRHK_R_NOT_INITIALISED), "not initialised"}, + {ERR_REASON(HWCRHK_R_NOT_LOADED), "not loaded"}, + {ERR_REASON(HWCRHK_R_NO_CALLBACK), "no callback"}, + {ERR_REASON(HWCRHK_R_NO_KEY), "no key"}, + {ERR_REASON(HWCRHK_R_PRIVATE_KEY_ALGORITHMS_DISABLED), + "private key algorithms disabled"}, + {ERR_REASON(HWCRHK_R_REQUEST_FAILED), "request failed"}, + {ERR_REASON(HWCRHK_R_REQUEST_FALLBACK), "request fallback"}, + {ERR_REASON(HWCRHK_R_UNIT_FAILURE), "unit failure"}, + {0, NULL} +}; + +#endif + +#ifdef HWCRHK_LIB_NAME +static ERR_STRING_DATA HWCRHK_lib_name[] = { + {0, HWCRHK_LIB_NAME}, + {0, NULL} +}; +#endif + +static int HWCRHK_lib_error_code = 0; +static int HWCRHK_error_init = 1; + +static void ERR_load_HWCRHK_strings(void) +{ + if (HWCRHK_lib_error_code == 0) + HWCRHK_lib_error_code = ERR_get_next_error_library(); + + if (HWCRHK_error_init) { + HWCRHK_error_init = 0; +#ifndef OPENSSL_NO_ERR + ERR_load_strings(HWCRHK_lib_error_code, HWCRHK_str_functs); + ERR_load_strings(HWCRHK_lib_error_code, HWCRHK_str_reasons); +#endif + +#ifdef HWCRHK_LIB_NAME + HWCRHK_lib_name->error = ERR_PACK(HWCRHK_lib_error_code, 0, 0); + ERR_load_strings(0, HWCRHK_lib_name); +#endif + } +} + +static void ERR_unload_HWCRHK_strings(void) +{ + if (HWCRHK_error_init == 0) { +#ifndef OPENSSL_NO_ERR + ERR_unload_strings(HWCRHK_lib_error_code, HWCRHK_str_functs); + ERR_unload_strings(HWCRHK_lib_error_code, HWCRHK_str_reasons); +#endif + +#ifdef HWCRHK_LIB_NAME + ERR_unload_strings(0, HWCRHK_lib_name); +#endif + HWCRHK_error_init = 1; + } +} + +static void ERR_HWCRHK_error(int function, int reason, char *file, int line) +{ + if (HWCRHK_lib_error_code == 0) + HWCRHK_lib_error_code = ERR_get_next_error_library(); + ERR_PUT_error(HWCRHK_lib_error_code, function, reason, file, line); +} diff --git a/demos/engines/e_chil_err.h b/demos/engines/e_chil_err.h new file mode 100644 index 0000000000..b0f0dd98d3 --- /dev/null +++ b/demos/engines/e_chil_err.h @@ -0,0 +1,64 @@ +/* + * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +/* + * NOTE: this file was auto generated by the mkerr.pl script: any changes + * made to it will be overwritten when the script next updates this file, + * only reason strings will be preserved. + */ + +#ifndef HEADER_HWCRHK_ERR_H +# define HEADER_HWCRHK_ERR_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* BEGIN ERROR CODES */ +static void ERR_load_HWCRHK_strings(void); +static void ERR_unload_HWCRHK_strings(void); +static void ERR_HWCRHK_error(int function, int reason, char *file, int line); +# define HWCRHKerr(f,r) ERR_HWCRHK_error((f),(r),OPENSSL_FILE,OPENSSL_LINE) + +/* Error codes for the HWCRHK functions. */ + +/* Function codes. */ +# define HWCRHK_F_HWCRHK_CTRL 100 +# define HWCRHK_F_HWCRHK_FINISH 101 +# define HWCRHK_F_HWCRHK_GET_PASS 102 +# define HWCRHK_F_HWCRHK_INIT 103 +# define HWCRHK_F_HWCRHK_INSERT_CARD 104 +# define HWCRHK_F_HWCRHK_LOAD_PRIVKEY 105 +# define HWCRHK_F_HWCRHK_LOAD_PUBKEY 106 +# define HWCRHK_F_HWCRHK_MOD_EXP 107 +# define HWCRHK_F_HWCRHK_RAND_BYTES 108 +# define HWCRHK_F_HWCRHK_RSA_MOD_EXP 109 +# define HWCRHK_F_BIND_HELPER 110 +# define HWCRHK_F_HWCRHK_MUTEX_INIT 111 + +/* Reason codes. */ +# define HWCRHK_R_ALREADY_LOADED 100 +# define HWCRHK_R_BIO_WAS_FREED 101 +# define HWCRHK_R_CHIL_ERROR 102 +# define HWCRHK_R_CTRL_COMMAND_NOT_IMPLEMENTED 103 +# define HWCRHK_R_DSO_FAILURE 104 +# define HWCRHK_R_MISSING_KEY_COMPONENTS 105 +# define HWCRHK_R_NOT_INITIALISED 106 +# define HWCRHK_R_NOT_LOADED 107 +# define HWCRHK_R_NO_CALLBACK 108 +# define HWCRHK_R_NO_KEY 109 +# define HWCRHK_R_PRIVATE_KEY_ALGORITHMS_DISABLED 110 +# define HWCRHK_R_REQUEST_FAILED 111 +# define HWCRHK_R_REQUEST_FALLBACK 112 +# define HWCRHK_R_UNIT_FAILURE 113 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/engines/e_chil.c b/engines/e_chil.c deleted file mode 100644 index 8d81b46fec..0000000000 --- a/engines/e_chil.c +++ /dev/null @@ -1,1285 +0,0 @@ -/* - * Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the OpenSSL license (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include -#include -#include -#include -#include "internal/dso.h" -#include -#include -#include -#ifndef OPENSSL_NO_RSA -# include -#endif -#ifndef OPENSSL_NO_DH -# include -#endif -#include - -#ifndef OPENSSL_NO_HW -# ifndef OPENSSL_NO_HW_CHIL - -/*- - * Attribution notice: nCipher have said several times that it's OK for - * us to implement a general interface to their boxes, and recently declared - * their HWCryptoHook to be public, and therefore available for us to use. - * Thanks, nCipher. - * - * The hwcryptohook.h included here is from May 2000. - * [Richard Levitte] - */ -# ifdef FLAT_INC -# include "hwcryptohook.h" -# else -# include "vendor_defns/hwcryptohook.h" -# endif - -# define HWCRHK_LIB_NAME "CHIL engine" -# include "e_chil_err.c" - -static CRYPTO_RWLOCK *chil_lock; - -static int hwcrhk_destroy(ENGINE *e); -static int hwcrhk_init(ENGINE *e); -static int hwcrhk_finish(ENGINE *e); -static int hwcrhk_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void)); - -/* Functions to handle mutexes */ -static int hwcrhk_mutex_init(HWCryptoHook_Mutex *, - HWCryptoHook_CallerContext *); -static int hwcrhk_mutex_lock(HWCryptoHook_Mutex *); -static void hwcrhk_mutex_unlock(HWCryptoHook_Mutex *); -static void hwcrhk_mutex_destroy(HWCryptoHook_Mutex *); - -/* BIGNUM stuff */ -static int hwcrhk_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, - const BIGNUM *m, BN_CTX *ctx); - -# ifndef OPENSSL_NO_RSA -/* RSA stuff */ -static int hwcrhk_rsa_mod_exp(BIGNUM *r, const BIGNUM *I, RSA *rsa, - BN_CTX *ctx); -/* This function is aliased to mod_exp (with the mont stuff dropped). */ -static int hwcrhk_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, - const BIGNUM *m, BN_CTX *ctx, - BN_MONT_CTX *m_ctx); -static int hwcrhk_rsa_finish(RSA *rsa); -# endif - -# ifndef OPENSSL_NO_DH -/* DH stuff */ -/* This function is alised to mod_exp (with the DH and mont dropped). */ -static int hwcrhk_mod_exp_dh(const DH *dh, BIGNUM *r, - const BIGNUM *a, const BIGNUM *p, - const BIGNUM *m, BN_CTX *ctx, - BN_MONT_CTX *m_ctx); -# endif - -/* RAND stuff */ -static int hwcrhk_rand_bytes(unsigned char *buf, int num); -static int hwcrhk_rand_status(void); - -/* KM stuff */ -static EVP_PKEY *hwcrhk_load_privkey(ENGINE *eng, const char *key_id, - UI_METHOD *ui_method, - void *callback_data); -static EVP_PKEY *hwcrhk_load_pubkey(ENGINE *eng, const char *key_id, - UI_METHOD *ui_method, - void *callback_data); - -/* Interaction stuff */ -static int hwcrhk_insert_card(const char *prompt_info, - const char *wrong_info, - HWCryptoHook_PassphraseContext * ppctx, - HWCryptoHook_CallerContext * cactx); -static int hwcrhk_get_pass(const char *prompt_info, - int *len_io, char *buf, - HWCryptoHook_PassphraseContext * ppctx, - HWCryptoHook_CallerContext * cactx); -static void hwcrhk_log_message(void *logstr, const char *message); - -/* The definitions for control commands specific to this engine */ -# define HWCRHK_CMD_SO_PATH ENGINE_CMD_BASE -# define HWCRHK_CMD_FORK_CHECK (ENGINE_CMD_BASE + 1) -# define HWCRHK_CMD_THREAD_LOCKING (ENGINE_CMD_BASE + 2) -# define HWCRHK_CMD_SET_USER_INTERFACE (ENGINE_CMD_BASE + 3) -# define HWCRHK_CMD_SET_CALLBACK_DATA (ENGINE_CMD_BASE + 4) -static const ENGINE_CMD_DEFN hwcrhk_cmd_defns[] = { - {HWCRHK_CMD_SO_PATH, - "SO_PATH", - "Specifies the path to the 'hwcrhk' shared library", - ENGINE_CMD_FLAG_STRING}, - {HWCRHK_CMD_FORK_CHECK, - "FORK_CHECK", - "Turns fork() checking on (non-zero) or off (zero)", - ENGINE_CMD_FLAG_NUMERIC}, - {HWCRHK_CMD_THREAD_LOCKING, - "THREAD_LOCKING", - "Turns thread-safe locking on (zero) or off (non-zero)", - ENGINE_CMD_FLAG_NUMERIC}, - {HWCRHK_CMD_SET_USER_INTERFACE, - "SET_USER_INTERFACE", - "Set the global user interface (internal)", - ENGINE_CMD_FLAG_INTERNAL}, - {HWCRHK_CMD_SET_CALLBACK_DATA, - "SET_CALLBACK_DATA", - "Set the global user interface extra data (internal)", - ENGINE_CMD_FLAG_INTERNAL}, - {0, NULL, NULL, 0} -}; - -# ifndef OPENSSL_NO_RSA -/* Our internal RSA_METHOD that we provide pointers to */ -static RSA_METHOD hwcrhk_rsa = { - "CHIL RSA method", - NULL, - NULL, - NULL, - NULL, - hwcrhk_rsa_mod_exp, - hwcrhk_mod_exp_mont, - NULL, - hwcrhk_rsa_finish, - 0, - NULL, - NULL, - NULL, - NULL -}; -# endif - -# ifndef OPENSSL_NO_DH -/* Our internal DH_METHOD that we provide pointers to */ -static DH_METHOD hwcrhk_dh = { - "CHIL DH method", - NULL, - NULL, - hwcrhk_mod_exp_dh, - NULL, - NULL, - 0, - NULL, - NULL -}; -# endif - -static RAND_METHOD hwcrhk_rand = { - /* "CHIL RAND method", */ - NULL, - hwcrhk_rand_bytes, - NULL, - NULL, - hwcrhk_rand_bytes, - hwcrhk_rand_status, -}; - -/* Constants used when creating the ENGINE */ -static const char *engine_hwcrhk_id = "chil"; -static const char *engine_hwcrhk_name = "CHIL hardware engine support"; -# ifndef OPENSSL_NO_DYNAMIC_ENGINE -/* Compatibility hack, the dynamic library uses this form in the path */ -static const char *engine_hwcrhk_id_alt = "ncipher"; -# endif - -/* Internal stuff for HWCryptoHook */ - -/* Some structures needed for proper use of thread locks */ -/* - * hwcryptohook.h has some typedefs that turn struct HWCryptoHook_MutexValue - * into HWCryptoHook_Mutex - */ -struct HWCryptoHook_MutexValue { - CRYPTO_RWLOCK *lock; -}; - -/* - * hwcryptohook.h has some typedefs that turn struct - * HWCryptoHook_PassphraseContextValue into HWCryptoHook_PassphraseContext - */ -struct HWCryptoHook_PassphraseContextValue { - UI_METHOD *ui_method; - void *callback_data; -}; - -/* - * hwcryptohook.h has some typedefs that turn struct - * HWCryptoHook_CallerContextValue into HWCryptoHook_CallerContext - */ -struct HWCryptoHook_CallerContextValue { - pem_password_cb *password_callback; /* Deprecated! Only present for - * backward compatibility! */ - UI_METHOD *ui_method; - void *callback_data; -}; - -/* - * The MPI structure in HWCryptoHook is pretty compatible with OpenSSL - * BIGNUM's, so lets define a couple of conversion macros - */ -# define BN2MPI(mp, bn) \ - {mp.size = bn->top * sizeof(BN_ULONG); mp.buf = (unsigned char *)bn->d;} -# define MPI2BN(bn, mp) \ - {mp.size = bn->dmax * sizeof(BN_ULONG); mp.buf = (unsigned char *)bn->d;} - -static BIO *logstream = NULL; -static int disable_mutex_callbacks = 0; - -/* - * One might wonder why these are needed, since one can pass down at least a - * UI_METHOD and a pointer to callback data to the key-loading functions. The - * thing is that the ModExp and RSAImmed functions can load keys as well, if - * the data they get is in a special, nCipher-defined format (hint: if you - * look at the private exponent of the RSA data as a string, you'll see this - * string: "nCipher KM tool key id", followed by some bytes, followed a key - * identity string, followed by more bytes. This happens when you use - * "embed" keys instead of "hwcrhk" keys). Unfortunately, those functions do - * not take any passphrase or caller context, and our functions can't really - * take any callback data either. Still, the "insert_card" and - * "get_passphrase" callbacks may be called down the line, and will need to - * know what user interface callbacks to call, and having callback data from - * the application may be a nice thing as well, so we need to keep track of - * that globally. - */ -static HWCryptoHook_CallerContext password_context = { NULL, NULL, NULL }; - -/* Stuff to pass to the HWCryptoHook library */ -static HWCryptoHook_InitInfo hwcrhk_globals = { - HWCryptoHook_InitFlags_SimpleForkCheck, /* Flags */ - &logstream, /* logstream */ - sizeof(BN_ULONG), /* limbsize */ - 0, /* mslimb first: false for BNs */ - -1, /* msbyte first: use native */ - 0, /* Max mutexes, 0 = no small limit */ - 0, /* Max simultaneous, 0 = default */ - - /* - * The next few are mutex stuff: we write wrapper functions around the OS - * mutex functions. We initialise them to 0 here, and change that to - * actual function pointers in hwcrhk_init() if dynamic locks are - * supported (that is, if the application programmer has made sure of - * setting up callbacks bafore starting this engine) *and* if - * disable_mutex_callbacks hasn't been set by a call to - * ENGINE_ctrl(ENGINE_CTRL_CHIL_NO_LOCKING). - */ - sizeof(HWCryptoHook_Mutex), - 0, - 0, - 0, - 0, - - /* - * The next few are condvar stuff: we write wrapper functions round the - * OS functions. Currently not implemented and not and absolute - * necessity even in threaded programs, therefore 0'ed. Will hopefully - * be implemented some day, since it enhances the efficiency of - * HWCryptoHook. - */ - 0, /* sizeof(HWCryptoHook_CondVar), */ - 0, /* hwcrhk_cv_init, */ - 0, /* hwcrhk_cv_wait, */ - 0, /* hwcrhk_cv_signal, */ - 0, /* hwcrhk_cv_broadcast, */ - 0, /* hwcrhk_cv_destroy, */ - - hwcrhk_get_pass, /* pass phrase */ - hwcrhk_insert_card, /* insert a card */ - hwcrhk_log_message /* Log message */ -}; - -/* Now, to our own code */ - -/* - * This internal function is used by ENGINE_chil() and possibly by the - * "dynamic" ENGINE support too - */ -static int bind_helper(ENGINE *e) -{ -# ifndef OPENSSL_NO_RSA - const RSA_METHOD *meth1; -# endif -# ifndef OPENSSL_NO_DH - const DH_METHOD *meth2; -# endif - - chil_lock = CRYPTO_THREAD_lock_new(); - if (chil_lock == NULL) { - HWCRHKerr(HWCRHK_F_BIND_HELPER, ERR_R_MALLOC_FAILURE); - return 0; - } - - if (!ENGINE_set_id(e, engine_hwcrhk_id) || - !ENGINE_set_name(e, engine_hwcrhk_name) || -# ifndef OPENSSL_NO_RSA - !ENGINE_set_RSA(e, &hwcrhk_rsa) || -# endif -# ifndef OPENSSL_NO_DH - !ENGINE_set_DH(e, &hwcrhk_dh) || -# endif - !ENGINE_set_RAND(e, &hwcrhk_rand) || - !ENGINE_set_destroy_function(e, hwcrhk_destroy) || - !ENGINE_set_init_function(e, hwcrhk_init) || - !ENGINE_set_finish_function(e, hwcrhk_finish) || - !ENGINE_set_ctrl_function(e, hwcrhk_ctrl) || - !ENGINE_set_load_privkey_function(e, hwcrhk_load_privkey) || - !ENGINE_set_load_pubkey_function(e, hwcrhk_load_pubkey) || - !ENGINE_set_cmd_defns(e, hwcrhk_cmd_defns)) - return 0; - -# ifndef OPENSSL_NO_RSA - /* - * We know that the "PKCS1_OpenSSL()" functions hook properly to the - * cswift-specific mod_exp and mod_exp_crt so we use those functions. NB: - * We don't use ENGINE_openssl() or anything "more generic" because - * something like the RSAref code may not hook properly, and if you own - * one of these cards then you have the right to do RSA operations on it - * anyway! - */ - meth1 = RSA_PKCS1_OpenSSL(); - hwcrhk_rsa.rsa_pub_enc = meth1->rsa_pub_enc; - hwcrhk_rsa.rsa_pub_dec = meth1->rsa_pub_dec; - hwcrhk_rsa.rsa_priv_enc = meth1->rsa_priv_enc; - hwcrhk_rsa.rsa_priv_dec = meth1->rsa_priv_dec; -# endif - -# ifndef OPENSSL_NO_DH - /* Much the same for Diffie-Hellman */ - meth2 = DH_OpenSSL(); - hwcrhk_dh.generate_key = meth2->generate_key; - hwcrhk_dh.compute_key = meth2->compute_key; -# endif - - /* Ensure the hwcrhk error handling is set up */ - ERR_load_HWCRHK_strings(); - - return 1; -} - -# ifdef OPENSSL_NO_DYNAMIC_ENGINE -static ENGINE *engine_chil(void) -{ - ENGINE *ret = ENGINE_new(); - if (ret == NULL) - return NULL; - if (!bind_helper(ret)) { - ENGINE_free(ret); - return NULL; - } - return ret; -} - -void ENGINE_load_chil(void) -{ - /* Copied from eng_[openssl|dyn].c */ - ENGINE *toadd = engine_chil(); - if (!toadd) - return; - ENGINE_add(toadd); - ENGINE_free(toadd); - ERR_clear_error(); -} -# endif - -/* - * This is a process-global DSO handle used for loading and unloading the - * HWCryptoHook library. NB: This is only set (or unset) during an init() or - * finish() call (reference counts permitting) and they're operating with - * global locks, so this should be thread-safe implicitly. - */ -static DSO *hwcrhk_dso = NULL; -static HWCryptoHook_ContextHandle hwcrhk_context = 0; -# ifndef OPENSSL_NO_RSA -/* Index for KM handle. Not really used yet. */ -static int hndidx_rsa = -1; -# endif - -/* - * These are the function pointers that are (un)set when the library has - * successfully (un)loaded. - */ -static HWCryptoHook_Init_t *p_hwcrhk_Init = NULL; -static HWCryptoHook_Finish_t *p_hwcrhk_Finish = NULL; -static HWCryptoHook_ModExp_t *p_hwcrhk_ModExp = NULL; -# ifndef OPENSSL_NO_RSA -static HWCryptoHook_RSA_t *p_hwcrhk_RSA = NULL; -# endif -static HWCryptoHook_RandomBytes_t *p_hwcrhk_RandomBytes = NULL; -# ifndef OPENSSL_NO_RSA -static HWCryptoHook_RSALoadKey_t *p_hwcrhk_RSALoadKey = NULL; -static HWCryptoHook_RSAGetPublicKey_t *p_hwcrhk_RSAGetPublicKey = NULL; -static HWCryptoHook_RSAUnloadKey_t *p_hwcrhk_RSAUnloadKey = NULL; -# endif -static HWCryptoHook_ModExpCRT_t *p_hwcrhk_ModExpCRT = NULL; - -/* Used in the DSO operations. */ -static const char *HWCRHK_LIBNAME = NULL; -static void free_HWCRHK_LIBNAME(void) -{ - OPENSSL_free(HWCRHK_LIBNAME); - HWCRHK_LIBNAME = NULL; -} - -static const char *get_HWCRHK_LIBNAME(void) -{ - if (HWCRHK_LIBNAME) - return HWCRHK_LIBNAME; - return "nfhwcrhk"; -} - -static long set_HWCRHK_LIBNAME(const char *name) -{ - free_HWCRHK_LIBNAME(); - return (((HWCRHK_LIBNAME = OPENSSL_strdup(name)) != NULL) ? 1 : 0); -} - -static const char *n_hwcrhk_Init = "HWCryptoHook_Init"; -static const char *n_hwcrhk_Finish = "HWCryptoHook_Finish"; -static const char *n_hwcrhk_ModExp = "HWCryptoHook_ModExp"; -# ifndef OPENSSL_NO_RSA -static const char *n_hwcrhk_RSA = "HWCryptoHook_RSA"; -# endif -static const char *n_hwcrhk_RandomBytes = "HWCryptoHook_RandomBytes"; -# ifndef OPENSSL_NO_RSA -static const char *n_hwcrhk_RSALoadKey = "HWCryptoHook_RSALoadKey"; -static const char *n_hwcrhk_RSAGetPublicKey = "HWCryptoHook_RSAGetPublicKey"; -static const char *n_hwcrhk_RSAUnloadKey = "HWCryptoHook_RSAUnloadKey"; -# endif -static const char *n_hwcrhk_ModExpCRT = "HWCryptoHook_ModExpCRT"; - -/* - * HWCryptoHook library functions and mechanics - these are used by the - * higher-level functions further down. NB: As and where there's no error - * checking, take a look lower down where these functions are called, the - * checking and error handling is probably down there. - */ - -/* utility function to obtain a context */ -static int get_context(HWCryptoHook_ContextHandle * hac, - HWCryptoHook_CallerContext * cac) -{ - char tempbuf[1024]; - HWCryptoHook_ErrMsgBuf rmsg; - - rmsg.buf = tempbuf; - rmsg.size = sizeof(tempbuf); - - *hac = p_hwcrhk_Init(&hwcrhk_globals, sizeof(hwcrhk_globals), &rmsg, cac); - if (!*hac) - return 0; - return 1; -} - -/* similarly to release one. */ -static void release_context(HWCryptoHook_ContextHandle hac) -{ - p_hwcrhk_Finish(hac); -} - -/* Destructor (complements the "ENGINE_chil()" constructor) */ -static int hwcrhk_destroy(ENGINE *e) -{ - free_HWCRHK_LIBNAME(); - ERR_unload_HWCRHK_strings(); - CRYPTO_THREAD_lock_free(chil_lock); - return 1; -} - -/* (de)initialisation functions. */ -static int hwcrhk_init(ENGINE *e) -{ - HWCryptoHook_Init_t *p1; - HWCryptoHook_Finish_t *p2; - HWCryptoHook_ModExp_t *p3; -# ifndef OPENSSL_NO_RSA - HWCryptoHook_RSA_t *p4; - HWCryptoHook_RSALoadKey_t *p5; - HWCryptoHook_RSAGetPublicKey_t *p6; - HWCryptoHook_RSAUnloadKey_t *p7; -# endif - HWCryptoHook_RandomBytes_t *p8; - HWCryptoHook_ModExpCRT_t *p9; - - if (hwcrhk_dso != NULL) { - HWCRHKerr(HWCRHK_F_HWCRHK_INIT, HWCRHK_R_ALREADY_LOADED); - goto err; - } - /* Attempt to load libnfhwcrhk.so/nfhwcrhk.dll/whatever. */ - hwcrhk_dso = DSO_load(NULL, get_HWCRHK_LIBNAME(), NULL, 0); - if (hwcrhk_dso == NULL) { - HWCRHKerr(HWCRHK_F_HWCRHK_INIT, HWCRHK_R_DSO_FAILURE); - goto err; - } - -#define BINDIT(t, name) (t *)DSO_bind_func(hwcrhk_dso, name) - if ((p1 = BINDIT(HWCryptoHook_Init_t, n_hwcrhk_Init)) == NULL - || (p2 = BINDIT(HWCryptoHook_Finish_t, n_hwcrhk_Finish)) == NULL - || (p3 = BINDIT(HWCryptoHook_ModExp_t, n_hwcrhk_ModExp)) == NULL -# ifndef OPENSSL_NO_RSA - || (p4 = BINDIT(HWCryptoHook_RSA_t, n_hwcrhk_RSA)) == NULL - || (p5 = BINDIT(HWCryptoHook_RSALoadKey_t, n_hwcrhk_RSALoadKey)) == NULL - || (p6 = BINDIT(HWCryptoHook_RSAGetPublicKey_t, n_hwcrhk_RSAGetPublicKey)) == NULL - || (p7 = BINDIT(HWCryptoHook_RSAUnloadKey_t, n_hwcrhk_RSAUnloadKey)) == NULL -# endif - || (p8 = BINDIT(HWCryptoHook_RandomBytes_t, n_hwcrhk_RandomBytes)) == NULL - || (p9 = BINDIT(HWCryptoHook_ModExpCRT_t, n_hwcrhk_ModExpCRT)) == NULL) { - HWCRHKerr(HWCRHK_F_HWCRHK_INIT, HWCRHK_R_DSO_FAILURE); - goto err; - } - /* Copy the pointers */ - p_hwcrhk_Init = p1; - p_hwcrhk_Finish = p2; - p_hwcrhk_ModExp = p3; -# ifndef OPENSSL_NO_RSA - p_hwcrhk_RSA = p4; - p_hwcrhk_RSALoadKey = p5; - p_hwcrhk_RSAGetPublicKey = p6; - p_hwcrhk_RSAUnloadKey = p7; -# endif - p_hwcrhk_RandomBytes = p8; - p_hwcrhk_ModExpCRT = p9; - - /* - * Check if the application decided to support dynamic locks, and if it - * does, use them. - */ - if (disable_mutex_callbacks == 0) { - hwcrhk_globals.mutex_init = hwcrhk_mutex_init; - hwcrhk_globals.mutex_acquire = hwcrhk_mutex_lock; - hwcrhk_globals.mutex_release = hwcrhk_mutex_unlock; - hwcrhk_globals.mutex_destroy = hwcrhk_mutex_destroy; - } - - /* - * Try and get a context - if not, we may have a DSO but no accelerator! - */ - if (!get_context(&hwcrhk_context, &password_context)) { - HWCRHKerr(HWCRHK_F_HWCRHK_INIT, HWCRHK_R_UNIT_FAILURE); - goto err; - } - /* Everything's fine. */ -# ifndef OPENSSL_NO_RSA - if (hndidx_rsa == -1) - hndidx_rsa = RSA_get_ex_new_index(0, - "nFast HWCryptoHook RSA key handle", - NULL, NULL, NULL); -# endif - return 1; - err: - DSO_free(hwcrhk_dso); - hwcrhk_dso = NULL; - p_hwcrhk_Init = NULL; - p_hwcrhk_Finish = NULL; - p_hwcrhk_ModExp = NULL; -# ifndef OPENSSL_NO_RSA - p_hwcrhk_RSA = NULL; - p_hwcrhk_RSALoadKey = NULL; - p_hwcrhk_RSAGetPublicKey = NULL; - p_hwcrhk_RSAUnloadKey = NULL; -# endif - p_hwcrhk_ModExpCRT = NULL; - p_hwcrhk_RandomBytes = NULL; - return 0; -} - -static int hwcrhk_finish(ENGINE *e) -{ - int to_return = 1; - free_HWCRHK_LIBNAME(); - if (hwcrhk_dso == NULL) { - HWCRHKerr(HWCRHK_F_HWCRHK_FINISH, HWCRHK_R_NOT_LOADED); - to_return = 0; - goto err; - } - release_context(hwcrhk_context); - if (!DSO_free(hwcrhk_dso)) { - HWCRHKerr(HWCRHK_F_HWCRHK_FINISH, HWCRHK_R_DSO_FAILURE); - to_return = 0; - goto err; - } - err: - BIO_free(logstream); - hwcrhk_dso = NULL; - p_hwcrhk_Init = NULL; - p_hwcrhk_Finish = NULL; - p_hwcrhk_ModExp = NULL; -# ifndef OPENSSL_NO_RSA - p_hwcrhk_RSA = NULL; - p_hwcrhk_RSALoadKey = NULL; - p_hwcrhk_RSAGetPublicKey = NULL; - p_hwcrhk_RSAUnloadKey = NULL; -# endif - p_hwcrhk_ModExpCRT = NULL; - p_hwcrhk_RandomBytes = NULL; - return to_return; -} - -static int hwcrhk_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void)) -{ - int to_return = 1; - - switch (cmd) { - case HWCRHK_CMD_SO_PATH: - if (hwcrhk_dso) { - HWCRHKerr(HWCRHK_F_HWCRHK_CTRL, HWCRHK_R_ALREADY_LOADED); - return 0; - } - if (p == NULL) { - HWCRHKerr(HWCRHK_F_HWCRHK_CTRL, ERR_R_PASSED_NULL_PARAMETER); - return 0; - } - return set_HWCRHK_LIBNAME((const char *)p); - case ENGINE_CTRL_SET_LOGSTREAM: - { - BIO *bio = (BIO *)p; - - CRYPTO_THREAD_write_lock(chil_lock); - BIO_free(logstream); - logstream = NULL; - if (BIO_up_ref(bio)) - logstream = bio; - else - HWCRHKerr(HWCRHK_F_HWCRHK_CTRL, HWCRHK_R_BIO_WAS_FREED); - } - CRYPTO_THREAD_unlock(chil_lock); - break; - case ENGINE_CTRL_SET_PASSWORD_CALLBACK: - CRYPTO_THREAD_write_lock(chil_lock); - password_context.password_callback = (pem_password_cb *)f; - CRYPTO_THREAD_unlock(chil_lock); - break; - case ENGINE_CTRL_SET_USER_INTERFACE: - case HWCRHK_CMD_SET_USER_INTERFACE: - CRYPTO_THREAD_write_lock(chil_lock); - password_context.ui_method = (UI_METHOD *)p; - CRYPTO_THREAD_unlock(chil_lock); - break; - case ENGINE_CTRL_SET_CALLBACK_DATA: - case HWCRHK_CMD_SET_CALLBACK_DATA: - CRYPTO_THREAD_write_lock(chil_lock); - password_context.callback_data = p; - CRYPTO_THREAD_unlock(chil_lock); - break; - /* - * this enables or disables the "SimpleForkCheck" flag used in the - * initialisation structure. - */ - case ENGINE_CTRL_CHIL_SET_FORKCHECK: - case HWCRHK_CMD_FORK_CHECK: - CRYPTO_THREAD_write_lock(chil_lock); - if (i) - hwcrhk_globals.flags |= HWCryptoHook_InitFlags_SimpleForkCheck; - else - hwcrhk_globals.flags &= ~HWCryptoHook_InitFlags_SimpleForkCheck; - CRYPTO_THREAD_unlock(chil_lock); - break; - /* - * This will prevent the initialisation function from "installing" - * the mutex-handling callbacks, even if they are available from - * within the library (or were provided to the library from the - * calling application). This is to remove any baggage for - * applications not using multithreading. - */ - case ENGINE_CTRL_CHIL_NO_LOCKING: - CRYPTO_THREAD_write_lock(chil_lock); - disable_mutex_callbacks = 1; - CRYPTO_THREAD_unlock(chil_lock); - break; - case HWCRHK_CMD_THREAD_LOCKING: - CRYPTO_THREAD_write_lock(chil_lock); - disable_mutex_callbacks = ((i == 0) ? 0 : 1); - CRYPTO_THREAD_unlock(chil_lock); - break; - - /* The command isn't understood by this engine */ - default: - HWCRHKerr(HWCRHK_F_HWCRHK_CTRL, - HWCRHK_R_CTRL_COMMAND_NOT_IMPLEMENTED); - to_return = 0; - break; - } - - return to_return; -} - -static EVP_PKEY *hwcrhk_load_privkey(ENGINE *eng, const char *key_id, - UI_METHOD *ui_method, - void *callback_data) -{ -# ifndef OPENSSL_NO_RSA - RSA *rtmp = NULL; -# endif - EVP_PKEY *res = NULL; -# ifndef OPENSSL_NO_RSA - HWCryptoHook_MPI e, n; - HWCryptoHook_RSAKeyHandle *hptr; -# endif -# if !defined(OPENSSL_NO_RSA) - char tempbuf[1024]; - HWCryptoHook_ErrMsgBuf rmsg; - HWCryptoHook_PassphraseContext ppctx; -# endif - -# if !defined(OPENSSL_NO_RSA) - rmsg.buf = tempbuf; - rmsg.size = sizeof(tempbuf); -# endif - - if (!hwcrhk_context) { - HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY, HWCRHK_R_NOT_INITIALISED); - goto err; - } -# ifndef OPENSSL_NO_RSA - hptr = OPENSSL_malloc(sizeof(*hptr)); - if (hptr == NULL) { - HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY, ERR_R_MALLOC_FAILURE); - goto err; - } - ppctx.ui_method = ui_method; - ppctx.callback_data = callback_data; - if (p_hwcrhk_RSALoadKey(hwcrhk_context, key_id, hptr, &rmsg, &ppctx)) { - HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY, HWCRHK_R_CHIL_ERROR); - ERR_add_error_data(1, rmsg.buf); - goto err; - } - if (!*hptr) { - HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY, HWCRHK_R_NO_KEY); - goto err; - } -# endif -# ifndef OPENSSL_NO_RSA - rtmp = RSA_new_method(eng); - RSA_set_ex_data(rtmp, hndidx_rsa, (char *)hptr); - rtmp->e = BN_new(); - rtmp->n = BN_new(); - rtmp->flags |= RSA_FLAG_EXT_PKEY; - MPI2BN(rtmp->e, e); - MPI2BN(rtmp->n, n); - if (p_hwcrhk_RSAGetPublicKey(*hptr, &n, &e, &rmsg) - != HWCRYPTOHOOK_ERROR_MPISIZE) { - HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY, HWCRHK_R_CHIL_ERROR); - ERR_add_error_data(1, rmsg.buf); - goto err; - } - - bn_expand2(rtmp->e, e.size / sizeof(BN_ULONG)); - bn_expand2(rtmp->n, n.size / sizeof(BN_ULONG)); - MPI2BN(rtmp->e, e); - MPI2BN(rtmp->n, n); - - if (p_hwcrhk_RSAGetPublicKey(*hptr, &n, &e, &rmsg)) { - HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY, HWCRHK_R_CHIL_ERROR); - ERR_add_error_data(1, rmsg.buf); - goto err; - } - rtmp->e->top = e.size / sizeof(BN_ULONG); - bn_fix_top(rtmp->e); - rtmp->n->top = n.size / sizeof(BN_ULONG); - bn_fix_top(rtmp->n); - - res = EVP_PKEY_new(); - if (res == NULL) { - HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY, HWCRHK_R_CHIL_ERROR); - goto err; - } - EVP_PKEY_assign_RSA(res, rtmp); -# endif - - if (res == NULL) - HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY, - HWCRHK_R_PRIVATE_KEY_ALGORITHMS_DISABLED); - - return res; - err: -# ifndef OPENSSL_NO_RSA - RSA_free(rtmp); -# endif - return NULL; -} - -static EVP_PKEY *hwcrhk_load_pubkey(ENGINE *eng, const char *key_id, - UI_METHOD *ui_method, void *callback_data) -{ - EVP_PKEY *res = NULL; - -# ifndef OPENSSL_NO_RSA - res = hwcrhk_load_privkey(eng, key_id, ui_method, callback_data); -# endif - - if (res) - switch (res->type) { -# ifndef OPENSSL_NO_RSA - case EVP_PKEY_RSA: - { - RSA *rsa = NULL; - - CRYPTO_THREAD_write_lock(chil_lock); - rsa = res->pkey.rsa; - res->pkey.rsa = RSA_new(); - res->pkey.rsa->n = rsa->n; - res->pkey.rsa->e = rsa->e; - rsa->n = NULL; - rsa->e = NULL; - CRYPTO_THREAD_unlock(chil_lock); - RSA_free(rsa); - } - break; -# endif - default: - HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PUBKEY, - HWCRHK_R_CTRL_COMMAND_NOT_IMPLEMENTED); - goto err; - } - - return res; - err: - EVP_PKEY_free(res); - return NULL; -} - -/* A little mod_exp */ -static int hwcrhk_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, - const BIGNUM *m, BN_CTX *ctx) -{ - char tempbuf[1024]; - HWCryptoHook_ErrMsgBuf rmsg; - /* - * Since HWCryptoHook_MPI is pretty compatible with BIGNUM's, we use them - * directly, plus a little macro magic. We only thing we need to make - * sure of is that enough space is allocated. - */ - HWCryptoHook_MPI m_a, m_p, m_n, m_r; - int to_return, ret; - - to_return = 0; /* expect failure */ - rmsg.buf = tempbuf; - rmsg.size = sizeof(tempbuf); - - if (!hwcrhk_context) { - HWCRHKerr(HWCRHK_F_HWCRHK_MOD_EXP, HWCRHK_R_NOT_INITIALISED); - goto err; - } - /* Prepare the params */ - bn_expand2(r, m->top); /* Check for error !! */ - BN2MPI(m_a, a); - BN2MPI(m_p, p); - BN2MPI(m_n, m); - MPI2BN(r, m_r); - - /* Perform the operation */ - ret = p_hwcrhk_ModExp(hwcrhk_context, m_a, m_p, m_n, &m_r, &rmsg); - - /* Convert the response */ - r->top = m_r.size / sizeof(BN_ULONG); - bn_fix_top(r); - - if (ret < 0) { - /* - * FIXME: When this error is returned, HWCryptoHook is telling us - * that falling back to software computation might be a good thing. - */ - if (ret == HWCRYPTOHOOK_ERROR_FALLBACK) { - HWCRHKerr(HWCRHK_F_HWCRHK_MOD_EXP, HWCRHK_R_REQUEST_FALLBACK); - } else { - HWCRHKerr(HWCRHK_F_HWCRHK_MOD_EXP, HWCRHK_R_REQUEST_FAILED); - } - ERR_add_error_data(1, rmsg.buf); - goto err; - } - - to_return = 1; - err: - return to_return; -} - -# ifndef OPENSSL_NO_RSA -static int hwcrhk_rsa_mod_exp(BIGNUM *r, const BIGNUM *I, RSA *rsa, - BN_CTX *ctx) -{ - char tempbuf[1024]; - HWCryptoHook_ErrMsgBuf rmsg; - HWCryptoHook_RSAKeyHandle *hptr; - int to_return = 0, ret; - - rmsg.buf = tempbuf; - rmsg.size = sizeof(tempbuf); - - if (!hwcrhk_context) { - HWCRHKerr(HWCRHK_F_HWCRHK_RSA_MOD_EXP, HWCRHK_R_NOT_INITIALISED); - goto err; - } - - /* - * This provides support for nForce keys. Since that's opaque data all - * we do is provide a handle to the proper key and let HWCryptoHook take - * care of the rest. - */ - if ((hptr = - (HWCryptoHook_RSAKeyHandle *) RSA_get_ex_data(rsa, hndidx_rsa)) - != NULL) { - HWCryptoHook_MPI m_a, m_r; - - if (!rsa->n) { - HWCRHKerr(HWCRHK_F_HWCRHK_RSA_MOD_EXP, - HWCRHK_R_MISSING_KEY_COMPONENTS); - goto err; - } - - /* Prepare the params */ - bn_expand2(r, rsa->n->top); /* Check for error !! */ - BN2MPI(m_a, I); - MPI2BN(r, m_r); - - /* Perform the operation */ - ret = p_hwcrhk_RSA(m_a, *hptr, &m_r, &rmsg); - - /* Convert the response */ - r->top = m_r.size / sizeof(BN_ULONG); - bn_fix_top(r); - - if (ret < 0) { - /* - * FIXME: When this error is returned, HWCryptoHook is telling us - * that falling back to software computation might be a good - * thing. - */ - if (ret == HWCRYPTOHOOK_ERROR_FALLBACK) { - HWCRHKerr(HWCRHK_F_HWCRHK_RSA_MOD_EXP, - HWCRHK_R_REQUEST_FALLBACK); - } else { - HWCRHKerr(HWCRHK_F_HWCRHK_RSA_MOD_EXP, - HWCRHK_R_REQUEST_FAILED); - } - ERR_add_error_data(1, rmsg.buf); - goto err; - } - } else { - HWCryptoHook_MPI m_a, m_p, m_q, m_dmp1, m_dmq1, m_iqmp, m_r; - - if (!rsa->p || !rsa->q || !rsa->dmp1 || !rsa->dmq1 || !rsa->iqmp) { - HWCRHKerr(HWCRHK_F_HWCRHK_RSA_MOD_EXP, - HWCRHK_R_MISSING_KEY_COMPONENTS); - goto err; - } - - /* Prepare the params */ - bn_expand2(r, rsa->n->top); /* Check for error !! */ - BN2MPI(m_a, I); - BN2MPI(m_p, rsa->p); - BN2MPI(m_q, rsa->q); - BN2MPI(m_dmp1, rsa->dmp1); - BN2MPI(m_dmq1, rsa->dmq1); - BN2MPI(m_iqmp, rsa->iqmp); - MPI2BN(r, m_r); - - /* Perform the operation */ - ret = p_hwcrhk_ModExpCRT(hwcrhk_context, m_a, m_p, m_q, - m_dmp1, m_dmq1, m_iqmp, &m_r, &rmsg); - - /* Convert the response */ - r->top = m_r.size / sizeof(BN_ULONG); - bn_fix_top(r); - - if (ret < 0) { - /* - * FIXME: When this error is returned, HWCryptoHook is telling us - * that falling back to software computation might be a good - * thing. - */ - if (ret == HWCRYPTOHOOK_ERROR_FALLBACK) { - HWCRHKerr(HWCRHK_F_HWCRHK_RSA_MOD_EXP, - HWCRHK_R_REQUEST_FALLBACK); - } else { - HWCRHKerr(HWCRHK_F_HWCRHK_RSA_MOD_EXP, - HWCRHK_R_REQUEST_FAILED); - } - ERR_add_error_data(1, rmsg.buf); - goto err; - } - } - /* - * If we're here, we must be here with some semblance of success :-) - */ - to_return = 1; - err: - return to_return; -} -# endif - -# ifndef OPENSSL_NO_RSA -/* This function is aliased to mod_exp (with the mont stuff dropped). */ -static int hwcrhk_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, - const BIGNUM *m, BN_CTX *ctx, - BN_MONT_CTX *m_ctx) -{ - return hwcrhk_mod_exp(r, a, p, m, ctx); -} - -static int hwcrhk_rsa_finish(RSA *rsa) -{ - HWCryptoHook_RSAKeyHandle *hptr; - - hptr = RSA_get_ex_data(rsa, hndidx_rsa); - if (hptr) { - p_hwcrhk_RSAUnloadKey(*hptr, NULL); - OPENSSL_free(hptr); - RSA_set_ex_data(rsa, hndidx_rsa, NULL); - } - return 1; -} - -# endif - -# ifndef OPENSSL_NO_DH -/* This function is aliased to mod_exp (with the dh and mont dropped). */ -static int hwcrhk_mod_exp_dh(const DH *dh, BIGNUM *r, - const BIGNUM *a, const BIGNUM *p, - const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx) -{ - return hwcrhk_mod_exp(r, a, p, m, ctx); -} -# endif - -/* Random bytes are good */ -static int hwcrhk_rand_bytes(unsigned char *buf, int num) -{ - char tempbuf[1024]; - HWCryptoHook_ErrMsgBuf rmsg; - int to_return = 0; /* assume failure */ - int ret; - - rmsg.buf = tempbuf; - rmsg.size = sizeof(tempbuf); - - if (!hwcrhk_context) { - HWCRHKerr(HWCRHK_F_HWCRHK_RAND_BYTES, HWCRHK_R_NOT_INITIALISED); - goto err; - } - - ret = p_hwcrhk_RandomBytes(hwcrhk_context, buf, num, &rmsg); - if (ret < 0) { - /* - * FIXME: When this error is returned, HWCryptoHook is telling us - * that falling back to software computation might be a good thing. - */ - if (ret == HWCRYPTOHOOK_ERROR_FALLBACK) { - HWCRHKerr(HWCRHK_F_HWCRHK_RAND_BYTES, HWCRHK_R_REQUEST_FALLBACK); - } else { - HWCRHKerr(HWCRHK_F_HWCRHK_RAND_BYTES, HWCRHK_R_REQUEST_FAILED); - } - ERR_add_error_data(1, rmsg.buf); - goto err; - } - to_return = 1; - err: - return to_return; -} - -static int hwcrhk_rand_status(void) -{ - return 1; -} - -/* - * Mutex calls: since the HWCryptoHook model closely follows the POSIX model - * these just wrap the POSIX functions and add some logging. - */ - -static int hwcrhk_mutex_init(HWCryptoHook_Mutex * mt, - HWCryptoHook_CallerContext * cactx) -{ - mt->lock = CRYPTO_THREAD_lock_new(); - if (mt->lock == NULL) { - HWCRHKerr(HWCRHK_F_HWCRHK_MUTEX_INIT, ERR_R_MALLOC_FAILURE); - return 1; /* failure */ - } - return 0; /* success */ -} - -static int hwcrhk_mutex_lock(HWCryptoHook_Mutex * mt) -{ - CRYPTO_THREAD_write_lock(mt->lock); - return 0; -} - -static void hwcrhk_mutex_unlock(HWCryptoHook_Mutex * mt) -{ - CRYPTO_THREAD_unlock(mt->lock); -} - -static void hwcrhk_mutex_destroy(HWCryptoHook_Mutex * mt) -{ - CRYPTO_THREAD_lock_free(mt->lock); -} - -static int hwcrhk_get_pass(const char *prompt_info, - int *len_io, char *buf, - HWCryptoHook_PassphraseContext * ppctx, - HWCryptoHook_CallerContext * cactx) -{ - pem_password_cb *callback = NULL; - void *callback_data = NULL; - UI_METHOD *ui_method = NULL; - /* - * Despite what the documentation says prompt_info can be an empty - * string. - */ - if (prompt_info && !*prompt_info) - prompt_info = NULL; - - if (cactx) { - if (cactx->ui_method) - ui_method = cactx->ui_method; - if (cactx->password_callback) - callback = cactx->password_callback; - if (cactx->callback_data) - callback_data = cactx->callback_data; - } - if (ppctx) { - if (ppctx->ui_method) { - ui_method = ppctx->ui_method; - callback = NULL; - } - if (ppctx->callback_data) - callback_data = ppctx->callback_data; - } - if (callback == NULL && ui_method == NULL) { - HWCRHKerr(HWCRHK_F_HWCRHK_GET_PASS, HWCRHK_R_NO_CALLBACK); - return -1; - } - - if (ui_method) { - UI *ui = UI_new_method(ui_method); - if (ui) { - int ok; - char *prompt = UI_construct_prompt(ui, - "pass phrase", prompt_info); - - ok = UI_add_input_string(ui, prompt, - UI_INPUT_FLAG_DEFAULT_PWD, - buf, 0, (*len_io) - 1); - UI_add_user_data(ui, callback_data); - UI_ctrl(ui, UI_CTRL_PRINT_ERRORS, 1, 0, 0); - - if (ok >= 0) - do { - ok = UI_process(ui); - } - while (ok < 0 && UI_ctrl(ui, UI_CTRL_IS_REDOABLE, 0, 0, 0)); - - if (ok >= 0) - *len_io = strlen(buf); - - UI_free(ui); - OPENSSL_free(prompt); - } - } else { - *len_io = callback(buf, *len_io, 0, callback_data); - } - if (!*len_io) - return -1; - return 0; -} - -static int hwcrhk_insert_card(const char *prompt_info, - const char *wrong_info, - HWCryptoHook_PassphraseContext * ppctx, - HWCryptoHook_CallerContext * cactx) -{ - int ok = -1; - UI *ui; - void *callback_data = NULL; - UI_METHOD *ui_method = NULL; - - if (cactx) { - if (cactx->ui_method) - ui_method = cactx->ui_method; - if (cactx->callback_data) - callback_data = cactx->callback_data; - } - if (ppctx) { - if (ppctx->ui_method) - ui_method = ppctx->ui_method; - if (ppctx->callback_data) - callback_data = ppctx->callback_data; - } - if (ui_method == NULL) { - HWCRHKerr(HWCRHK_F_HWCRHK_INSERT_CARD, HWCRHK_R_NO_CALLBACK); - return -1; - } - - ui = UI_new_method(ui_method); - - if (ui) { - char answer = '\0'; - char buf[BUFSIZ]; - /* - * Despite what the documentation says wrong_info can be an empty - * string. - */ - if (wrong_info && *wrong_info) - BIO_snprintf(buf, sizeof(buf) - 1, - "Current card: \"%s\"\n", wrong_info); - else - buf[0] = 0; - ok = UI_dup_info_string(ui, buf); - if (ok >= 0 && prompt_info) { - BIO_snprintf(buf, sizeof(buf) - 1, - "Insert card \"%s\"", prompt_info); - ok = UI_dup_input_boolean(ui, buf, - "\n then hit or C to cancel\n", - "\r\n", "Cc", UI_INPUT_FLAG_ECHO, - &answer); - } - UI_add_user_data(ui, callback_data); - - if (ok >= 0) - ok = UI_process(ui); - UI_free(ui); - - if (ok == -2 || (ok >= 0 && answer == 'C')) - ok = 1; - else if (ok < 0) - ok = -1; - else - ok = 0; - } - return ok; -} - -static void hwcrhk_log_message(void *logstr, const char *message) -{ - BIO *lstream = NULL; - - if (logstr) - lstream = *(BIO **)logstr; - if (lstream) { - BIO_printf(lstream, "%s\n", message); - } -} - -/* - * This stuff is needed if this ENGINE is being compiled into a - * self-contained shared-library. - */ -# ifndef OPENSSL_NO_DYNAMIC_ENGINE -static int bind_fn(ENGINE *e, const char *id) -{ - if (id && (strcmp(id, engine_hwcrhk_id) != 0) && - (strcmp(id, engine_hwcrhk_id_alt) != 0)) - return 0; - if (!bind_helper(e)) - return 0; - return 1; -} - -IMPLEMENT_DYNAMIC_CHECK_FN() - IMPLEMENT_DYNAMIC_BIND_FN(bind_fn) -# endif /* OPENSSL_NO_DYNAMIC_ENGINE */ -# endif /* !OPENSSL_NO_HW_CHIL */ -#endif /* !OPENSSL_NO_HW */ diff --git a/engines/e_chil.ec b/engines/e_chil.ec deleted file mode 100644 index b5a76e17df..0000000000 --- a/engines/e_chil.ec +++ /dev/null @@ -1 +0,0 @@ -L HWCRHK e_chil_err.h e_chil_err.c diff --git a/engines/e_chil_err.c b/engines/e_chil_err.c deleted file mode 100644 index 0058684f79..0000000000 --- a/engines/e_chil_err.c +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the OpenSSL license (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -/* - * NOTE: this file was auto generated by the mkerr.pl script: any changes - * made to it will be overwritten when the script next updates this file, - * only reason strings will be preserved. - */ - -#include -#include -#include "e_chil_err.h" - -/* BEGIN ERROR CODES */ -#ifndef OPENSSL_NO_ERR - -# define ERR_FUNC(func) ERR_PACK(0,func,0) -# define ERR_REASON(reason) ERR_PACK(0,0,reason) - -static ERR_STRING_DATA HWCRHK_str_functs[] = { - {ERR_FUNC(HWCRHK_F_HWCRHK_CTRL), "HWCRHK_CTRL"}, - {ERR_FUNC(HWCRHK_F_HWCRHK_FINISH), "HWCRHK_FINISH"}, - {ERR_FUNC(HWCRHK_F_HWCRHK_GET_PASS), "HWCRHK_GET_PASS"}, - {ERR_FUNC(HWCRHK_F_HWCRHK_INIT), "HWCRHK_INIT"}, - {ERR_FUNC(HWCRHK_F_HWCRHK_INSERT_CARD), "HWCRHK_INSERT_CARD"}, - {ERR_FUNC(HWCRHK_F_HWCRHK_LOAD_PRIVKEY), "HWCRHK_LOAD_PRIVKEY"}, - {ERR_FUNC(HWCRHK_F_HWCRHK_LOAD_PUBKEY), "HWCRHK_LOAD_PUBKEY"}, - {ERR_FUNC(HWCRHK_F_HWCRHK_MOD_EXP), "HWCRHK_MOD_EXP"}, - {ERR_FUNC(HWCRHK_F_HWCRHK_RAND_BYTES), "HWCRHK_RAND_BYTES"}, - {ERR_FUNC(HWCRHK_F_HWCRHK_RSA_MOD_EXP), "HWCRHK_RSA_MOD_EXP"}, - {0, NULL} -}; - -static ERR_STRING_DATA HWCRHK_str_reasons[] = { - {ERR_REASON(HWCRHK_R_ALREADY_LOADED), "already loaded"}, - {ERR_REASON(HWCRHK_R_BIO_WAS_FREED), "bio was freed"}, - {ERR_REASON(HWCRHK_R_CHIL_ERROR), "chil error"}, - {ERR_REASON(HWCRHK_R_CTRL_COMMAND_NOT_IMPLEMENTED), - "ctrl command not implemented"}, - {ERR_REASON(HWCRHK_R_DSO_FAILURE), "dso failure"}, - {ERR_REASON(HWCRHK_R_MISSING_KEY_COMPONENTS), "missing key components"}, - {ERR_REASON(HWCRHK_R_NOT_INITIALISED), "not initialised"}, - {ERR_REASON(HWCRHK_R_NOT_LOADED), "not loaded"}, - {ERR_REASON(HWCRHK_R_NO_CALLBACK), "no callback"}, - {ERR_REASON(HWCRHK_R_NO_KEY), "no key"}, - {ERR_REASON(HWCRHK_R_PRIVATE_KEY_ALGORITHMS_DISABLED), - "private key algorithms disabled"}, - {ERR_REASON(HWCRHK_R_REQUEST_FAILED), "request failed"}, - {ERR_REASON(HWCRHK_R_REQUEST_FALLBACK), "request fallback"}, - {ERR_REASON(HWCRHK_R_UNIT_FAILURE), "unit failure"}, - {0, NULL} -}; - -#endif - -#ifdef HWCRHK_LIB_NAME -static ERR_STRING_DATA HWCRHK_lib_name[] = { - {0, HWCRHK_LIB_NAME}, - {0, NULL} -}; -#endif - -static int HWCRHK_lib_error_code = 0; -static int HWCRHK_error_init = 1; - -static void ERR_load_HWCRHK_strings(void) -{ - if (HWCRHK_lib_error_code == 0) - HWCRHK_lib_error_code = ERR_get_next_error_library(); - - if (HWCRHK_error_init) { - HWCRHK_error_init = 0; -#ifndef OPENSSL_NO_ERR - ERR_load_strings(HWCRHK_lib_error_code, HWCRHK_str_functs); - ERR_load_strings(HWCRHK_lib_error_code, HWCRHK_str_reasons); -#endif - -#ifdef HWCRHK_LIB_NAME - HWCRHK_lib_name->error = ERR_PACK(HWCRHK_lib_error_code, 0, 0); - ERR_load_strings(0, HWCRHK_lib_name); -#endif - } -} - -static void ERR_unload_HWCRHK_strings(void) -{ - if (HWCRHK_error_init == 0) { -#ifndef OPENSSL_NO_ERR - ERR_unload_strings(HWCRHK_lib_error_code, HWCRHK_str_functs); - ERR_unload_strings(HWCRHK_lib_error_code, HWCRHK_str_reasons); -#endif - -#ifdef HWCRHK_LIB_NAME - ERR_unload_strings(0, HWCRHK_lib_name); -#endif - HWCRHK_error_init = 1; - } -} - -static void ERR_HWCRHK_error(int function, int reason, char *file, int line) -{ - if (HWCRHK_lib_error_code == 0) - HWCRHK_lib_error_code = ERR_get_next_error_library(); - ERR_PUT_error(HWCRHK_lib_error_code, function, reason, file, line); -} diff --git a/engines/e_chil_err.h b/engines/e_chil_err.h deleted file mode 100644 index b0f0dd98d3..0000000000 --- a/engines/e_chil_err.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the OpenSSL license (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -/* - * NOTE: this file was auto generated by the mkerr.pl script: any changes - * made to it will be overwritten when the script next updates this file, - * only reason strings will be preserved. - */ - -#ifndef HEADER_HWCRHK_ERR_H -# define HEADER_HWCRHK_ERR_H - -#ifdef __cplusplus -extern "C" { -#endif - -/* BEGIN ERROR CODES */ -static void ERR_load_HWCRHK_strings(void); -static void ERR_unload_HWCRHK_strings(void); -static void ERR_HWCRHK_error(int function, int reason, char *file, int line); -# define HWCRHKerr(f,r) ERR_HWCRHK_error((f),(r),OPENSSL_FILE,OPENSSL_LINE) - -/* Error codes for the HWCRHK functions. */ - -/* Function codes. */ -# define HWCRHK_F_HWCRHK_CTRL 100 -# define HWCRHK_F_HWCRHK_FINISH 101 -# define HWCRHK_F_HWCRHK_GET_PASS 102 -# define HWCRHK_F_HWCRHK_INIT 103 -# define HWCRHK_F_HWCRHK_INSERT_CARD 104 -# define HWCRHK_F_HWCRHK_LOAD_PRIVKEY 105 -# define HWCRHK_F_HWCRHK_LOAD_PUBKEY 106 -# define HWCRHK_F_HWCRHK_MOD_EXP 107 -# define HWCRHK_F_HWCRHK_RAND_BYTES 108 -# define HWCRHK_F_HWCRHK_RSA_MOD_EXP 109 -# define HWCRHK_F_BIND_HELPER 110 -# define HWCRHK_F_HWCRHK_MUTEX_INIT 111 - -/* Reason codes. */ -# define HWCRHK_R_ALREADY_LOADED 100 -# define HWCRHK_R_BIO_WAS_FREED 101 -# define HWCRHK_R_CHIL_ERROR 102 -# define HWCRHK_R_CTRL_COMMAND_NOT_IMPLEMENTED 103 -# define HWCRHK_R_DSO_FAILURE 104 -# define HWCRHK_R_MISSING_KEY_COMPONENTS 105 -# define HWCRHK_R_NOT_INITIALISED 106 -# define HWCRHK_R_NOT_LOADED 107 -# define HWCRHK_R_NO_CALLBACK 108 -# define HWCRHK_R_NO_KEY 109 -# define HWCRHK_R_PRIVATE_KEY_ALGORITHMS_DISABLED 110 -# define HWCRHK_R_REQUEST_FAILED 111 -# define HWCRHK_R_REQUEST_FALLBACK 112 -# define HWCRHK_R_UNIT_FAILURE 113 - -#ifdef __cplusplus -} -#endif -#endif