Move the CHIL engine to demos/engines
authorRichard Levitte <levitte@openssl.org>
Tue, 28 Feb 2017 13:47:55 +0000 (14:47 +0100)
committerRichard Levitte <levitte@openssl.org>
Tue, 28 Feb 2017 14:03:06 +0000 (15:03 +0100)
Moving out of the way, Makefile to be added

Reviewed-by: Rich Salz <rsalz@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/2780)

demos/engines/e_chil.c [new file with mode: 0644]
demos/engines/e_chil.ec [new file with mode: 0644]
demos/engines/e_chil_err.c [new file with mode: 0644]
demos/engines/e_chil_err.h [new file with mode: 0644]
engines/e_chil.c [deleted file]
engines/e_chil.ec [deleted file]
engines/e_chil_err.c [deleted file]
engines/e_chil_err.h [deleted file]

diff --git a/demos/engines/e_chil.c b/demos/engines/e_chil.c
new file mode 100644 (file)
index 0000000..8d81b46
--- /dev/null
@@ -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 <stdio.h>
+#include <string.h>
+#include <openssl/crypto.h>
+#include <openssl/pem.h>
+#include "internal/dso.h"
+#include <openssl/engine.h>
+#include <openssl/ui.h>
+#include <openssl/rand.h>
+#ifndef OPENSSL_NO_RSA
+# include <openssl/rsa.h>
+#endif
+#ifndef OPENSSL_NO_DH
+# include <openssl/dh.h>
+#endif
+#include <openssl/bn.h>
+
+#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 <enter> or C<enter> 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 (file)
index 0000000..b5a76e1
--- /dev/null
@@ -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 (file)
index 0000000..0058684
--- /dev/null
@@ -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 <stdio.h>
+#include <openssl/err.h>
+#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 (file)
index 0000000..b0f0dd9
--- /dev/null
@@ -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 (file)
index 8d81b46..0000000
+++ /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 <stdio.h>
-#include <string.h>
-#include <openssl/crypto.h>
-#include <openssl/pem.h>
-#include "internal/dso.h"
-#include <openssl/engine.h>
-#include <openssl/ui.h>
-#include <openssl/rand.h>
-#ifndef OPENSSL_NO_RSA
-# include <openssl/rsa.h>
-#endif
-#ifndef OPENSSL_NO_DH
-# include <openssl/dh.h>
-#endif
-#include <openssl/bn.h>
-
-#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 <enter> or C<enter> 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 (file)
index b5a76e1..0000000
+++ /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 (file)
index 0058684..0000000
+++ /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 <stdio.h>
-#include <openssl/err.h>
-#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 (file)
index b0f0dd9..0000000
+++ /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