/*
 * 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 */
