/* crypto/engine/hw_zencod.c */
 /*
  * Written by Fred Donnat (frederic.donnat@zencod.com) for "zencod" * engine
  * integration in order to redirect crypto computing on a crypto * hardware
  * accelerator zenssl32 ;-) * * Date : 25 jun 2002 * Revision : 17 Ju7 2002
  * * Version : zencod_engine-0.9.7
  */

/* ====================================================================
 * Copyright (c) 1999-2001 The OpenSSL Project.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. All advertising materials mentioning features or use of this
 *    software must display the following acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
 *
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
 *    endorse or promote products derived from this software without
 *    prior written permission. For written permission, please contact
 *    licensing@OpenSSL.org.
 *
 * 5. Products derived from this software may not be called "OpenSSL"
 *    nor may "OpenSSL" appear in their names without prior written
 *    permission of the OpenSSL Project.
 *
 * 6. Redistributions of any form whatsoever must retain the following
 *    acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
 *
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 * ====================================================================
 *
 * This product includes cryptographic software written by Eric Young
 * (eay@cryptsoft.com).  This product includes software written by Tim
 * Hudson (tjh@cryptsoft.com).
 *
 */

/* ENGINE general include */
#include <stdio.h>
#include <openssl/crypto.h>
#include <openssl/dso.h>
#include <openssl/engine.h>

#ifndef OPENSSL_NO_HW
# ifndef OPENSSL_NO_HW_ZENCOD

#  ifdef FLAT_INC
#   include "hw_zencod.h"
#  else
#   include "vendor_defns/hw_zencod.h"
#  endif

#  define ZENCOD_LIB_NAME "zencod engine"
#  include "hw_zencod_err.c"

#  define FAIL_TO_SOFTWARE                -15

#  define ZEN_LIBRARY     "zenbridge"

#  ifdef ZENCOD_TRACING
#   define PERROR(s)     perror(s)
#   define CHEESE()      fputs("## [ZenEngine] ## " __FUNCTION__ "\n", stderr)
#  else
#   define PERROR(s)
#   define CHEESE()
#  endif

/* Sorry ;) */
#  ifndef WIN32
static inline void esrever(unsigned char *d, int l)
{
    for (; --l > 0; --l, d++) {
        *d ^= *(d + l);
        *(d + l) ^= *d;
        *d ^= *(d + l);
    }
}

static inline void ypcmem(unsigned char *d, const unsigned char *s, int l)
{
    for (d += l; l--;)
        *--d = *s++;
}
#  else
static __inline void esrever(unsigned char *d, int l)
{
    for (; --l > 0; --l, d++) {
        *d ^= *(d + l);
        *(d + l) ^= *d;
        *d ^= *(d + l);
    }
}

static __inline void ypcmem(unsigned char *d, const unsigned char *s, int l)
{
    for (d += l; l--;)
        *--d = *s++;
}
#  endif

#  define BIGNUM2ZEN(n, bn)       (ptr_zencod_init_number((n), \
                                        (unsigned long) ((bn)->top * BN_BITS2), \
                                        (unsigned char *) ((bn)->d)))

#  define ZEN_BITS(n, bytes)      (ptr_zencod_bytes2bits((unsigned char *) (n), (unsigned long) (bytes)))
#  define ZEN_BYTES(bits) (ptr_zencod_bits2bytes((unsigned long) (bits)))

/* Function for ENGINE detection and control */
static int zencod_destroy(ENGINE *e);
static int zencod_init(ENGINE *e);
static int zencod_finish(ENGINE *e);
static int zencod_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) ());

/* BIGNUM stuff */
static int zencod_bn_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
                             const BIGNUM *m, BN_CTX *ctx);

/* RSA stuff */
#  ifndef OPENSSL_NO_RSA
static int RSA_zencod_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa);
static int RSA_zencod_bn_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
                                 const BIGNUM *m, BN_CTX *ctx,
                                 BN_MONT_CTX *m_ctx);
#  endif

/* DSA stuff */
#  ifndef OPENSSL_NO_DSA
static int DSA_zencod_bn_mod_exp(DSA *dsa, BIGNUM *r, BIGNUM *a,
                                 const BIGNUM *p, const BIGNUM *m,
                                 BN_CTX *ctx, BN_MONT_CTX *m_ctx);

static DSA_SIG *DSA_zencod_do_sign(const unsigned char *dgst, int dlen,
                                   DSA *dsa);
static int DSA_zencod_do_verify(const unsigned char *dgst, int dgst_len,
                                DSA_SIG *sig, DSA *dsa);
#  endif

/* DH stuff */
#  ifndef OPENSSL_NO_DH
static int DH_zencod_bn_mod_exp(const DH *dh, BIGNUM *r, const BIGNUM *a,
                                const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
                                BN_MONT_CTX *m_ctx);
static int DH_zencod_generate_key(DH *dh);
static int DH_zencod_compute_key(unsigned char *key, const BIGNUM *pub_key,
                                 DH *dh);
#  endif

/* Rand stuff */
static void RAND_zencod_seed(const void *buf, int num);
static int RAND_zencod_rand_bytes(unsigned char *buf, int num);
static int RAND_zencod_rand_status(void);

/* Digest Stuff */
static int engine_digests(ENGINE *e, const EVP_MD **digest, const int **nids,
                          int nid);

/* Cipher Stuff */
static int engine_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
                          const int **nids, int nid);

#  define ZENCOD_CMD_SO_PATH                      ENGINE_CMD_BASE
static const ENGINE_CMD_DEFN zencod_cmd_defns[] = {
    {ZENCOD_CMD_SO_PATH,
     "SO_PATH",
     "Specifies the path to the 'zenbridge' shared library",
     ENGINE_CMD_FLAG_STRING},
    {0, NULL, NULL, 0}
};

#  ifndef OPENSSL_NO_RSA
/*
 * Our internal RSA_METHOD specific to zencod ENGINE providing pointers to
 * our function
 */
static RSA_METHOD zencod_rsa = {
    "ZENCOD RSA method",
    NULL,
    NULL,
    NULL,
    NULL,
    RSA_zencod_rsa_mod_exp,
    RSA_zencod_bn_mod_exp,
    NULL,
    NULL,
    0,
    NULL,
    NULL,
    NULL
};
#  endif

#  ifndef OPENSSL_NO_DSA
/*
 * Our internal DSA_METHOD specific to zencod ENGINE providing pointers to
 * our function
 */
static DSA_METHOD zencod_dsa = {
    "ZENCOD DSA method",
    DSA_zencod_do_sign,
    NULL,
    DSA_zencod_do_verify,
    NULL,
    DSA_zencod_bn_mod_exp,
    NULL,
    NULL,
    0,
    NULL
};
#  endif

#  ifndef OPENSSL_NO_DH
/*
 * Our internal DH_METHOD specific to zencod ENGINE providing pointers to our
 * function
 */
static DH_METHOD zencod_dh = {
    "ZENCOD DH method",
    DH_zencod_generate_key,
    DH_zencod_compute_key,
    DH_zencod_bn_mod_exp,
    NULL,
    NULL,
    0,
    NULL
};
#  endif

/*
 * Our internal RAND_meth specific to zencod ZNGINE providing pointers to our
 * function
 */
static RAND_METHOD zencod_rand = {
    RAND_zencod_seed,
    RAND_zencod_rand_bytes,
    NULL,
    NULL,
    RAND_zencod_rand_bytes,
    RAND_zencod_rand_status
};

/* Constants used when creating the ENGINE */
static const char *engine_zencod_id = "zencod";
static const char *engine_zencod_name = "ZENCOD hardware engine support";

/*
 * This internal function is used by ENGINE_zencod () and possibly by the
 * "dynamic" ENGINE support too ;-)
 */
static int bind_helper(ENGINE *e)
{

#  ifndef OPENSSL_NO_RSA
    const RSA_METHOD *meth_rsa;
#  endif
#  ifndef OPENSSL_NO_DSA
    const DSA_METHOD *meth_dsa;
#  endif
#  ifndef OPENSSL_NO_DH
    const DH_METHOD *meth_dh;
#  endif

    const RAND_METHOD *meth_rand;

    if (!ENGINE_set_id(e, engine_zencod_id) ||
        !ENGINE_set_name(e, engine_zencod_name) ||
#  ifndef OPENSSL_NO_RSA
        !ENGINE_set_RSA(e, &zencod_rsa) ||
#  endif
#  ifndef OPENSSL_NO_DSA
        !ENGINE_set_DSA(e, &zencod_dsa) ||
#  endif
#  ifndef OPENSSL_NO_DH
        !ENGINE_set_DH(e, &zencod_dh) ||
#  endif
        !ENGINE_set_RAND(e, &zencod_rand) ||
        !ENGINE_set_destroy_function(e, zencod_destroy) ||
        !ENGINE_set_init_function(e, zencod_init) ||
        !ENGINE_set_finish_function(e, zencod_finish) ||
        !ENGINE_set_ctrl_function(e, zencod_ctrl) ||
        !ENGINE_set_cmd_defns(e, zencod_cmd_defns) ||
        !ENGINE_set_digests(e, engine_digests) ||
        !ENGINE_set_ciphers(e, engine_ciphers)) {
        return 0;
    }
#  ifndef OPENSSL_NO_RSA
    /*
     * We know that the "PKCS1_SSLeay()" functions hook properly to the
     * Zencod-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!
     */
    meth_rsa = RSA_PKCS1_SSLeay();

    zencod_rsa.rsa_pub_enc = meth_rsa->rsa_pub_enc;
    zencod_rsa.rsa_pub_dec = meth_rsa->rsa_pub_dec;
    zencod_rsa.rsa_priv_enc = meth_rsa->rsa_priv_enc;
    zencod_rsa.rsa_priv_dec = meth_rsa->rsa_priv_dec;
    /* meth_rsa->rsa_mod_exp */
    /* meth_rsa->bn_mod_exp */
    zencod_rsa.init = meth_rsa->init;
    zencod_rsa.finish = meth_rsa->finish;
#  endif

#  ifndef OPENSSL_NO_DSA
    /*
     * We use OpenSSL meth to supply what we don't provide ;-*)
     */
    meth_dsa = DSA_OpenSSL();

    /* meth_dsa->dsa_do_sign */
    zencod_dsa.dsa_sign_setup = meth_dsa->dsa_sign_setup;
    /* meth_dsa->dsa_do_verify */
    zencod_dsa.dsa_mod_exp = meth_dsa->dsa_mod_exp;
    /* zencod_dsa.bn_mod_exp = meth_dsa->bn_mod_exp ; */
    zencod_dsa.init = meth_dsa->init;
    zencod_dsa.finish = meth_dsa->finish;
#  endif

#  ifndef OPENSSL_NO_DH
    /*
     * We use OpenSSL meth to supply what we don't provide ;-*)
     */
    meth_dh = DH_OpenSSL();

    /* zencod_dh.generate_key = meth_dh->generate_key ; */
    /* zencod_dh.compute_key = meth_dh->compute_key ; */
    /* zencod_dh.bn_mod_exp = meth_dh->bn_mod_exp ; */
    zencod_dh.init = meth_dh->init;
    zencod_dh.finish = meth_dh->finish;

#  endif

    /*
     * We use OpenSSL (SSLeay) meth to supply what we don't provide ;-*)
     */
    meth_rand = RAND_SSLeay();

    /* meth_rand->seed ; */
    /* zencod_rand.seed = meth_rand->seed ; */
    /* meth_rand->bytes ; */
    /* zencod_rand.bytes = meth_rand->bytes ; */
    zencod_rand.cleanup = meth_rand->cleanup;
    zencod_rand.add = meth_rand->add;
    /* meth_rand->pseudorand ; */
    /* zencod_rand.pseudorand = meth_rand->pseudorand ; */
    /* zencod_rand.status = meth_rand->status ; */
    /* meth_rand->status ; */

    /* Ensure the zencod error handling is set up */
    ERR_load_ZENCOD_strings();
    return 1;
}

/*
 * As this is only ever called once, there's no need for locking (indeed -
 * the lock will already be held by our caller!!!)
 */
static ENGINE *ENGINE_zencod(void)
{

    ENGINE *eng = ENGINE_new();

    if (!eng) {
        return NULL;
    }
    if (!bind_helper(eng)) {
        ENGINE_free(eng);
        return NULL;
    }

    return eng;
}

#  ifdef ENGINE_DYNAMIC_SUPPORT
static
#  endif
void ENGINE_load_zencod(void)
{
    /* Copied from eng_[openssl|dyn].c */
    ENGINE *toadd = ENGINE_zencod();
    if (!toadd)
        return;
    ENGINE_add(toadd);
    ENGINE_free(toadd);
    ERR_clear_error();
}

/*
 * This is a process-global DSO handle used for loading and unloading the
 * ZENBRIDGE 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 *zencod_dso = NULL;

static t_zencod_test *ptr_zencod_test = NULL;
static t_zencod_bytes2bits *ptr_zencod_bytes2bits = NULL;
static t_zencod_bits2bytes *ptr_zencod_bits2bytes = NULL;
static t_zencod_new_number *ptr_zencod_new_number = NULL;
static t_zencod_init_number *ptr_zencod_init_number = NULL;

static t_zencod_rsa_mod_exp *ptr_zencod_rsa_mod_exp = NULL;
static t_zencod_rsa_mod_exp_crt *ptr_zencod_rsa_mod_exp_crt = NULL;
static t_zencod_dsa_do_sign *ptr_zencod_dsa_do_sign = NULL;
static t_zencod_dsa_do_verify *ptr_zencod_dsa_do_verify = NULL;
static t_zencod_dh_generate_key *ptr_zencod_dh_generate_key = NULL;
static t_zencod_dh_compute_key *ptr_zencod_dh_compute_key = NULL;
static t_zencod_rand_bytes *ptr_zencod_rand_bytes = NULL;
static t_zencod_math_mod_exp *ptr_zencod_math_mod_exp = NULL;

static t_zencod_md5_init *ptr_zencod_md5_init = NULL;
static t_zencod_md5_update *ptr_zencod_md5_update = NULL;
static t_zencod_md5_do_final *ptr_zencod_md5_do_final = NULL;
static t_zencod_sha1_init *ptr_zencod_sha1_init = NULL;
static t_zencod_sha1_update *ptr_zencod_sha1_update = NULL;
static t_zencod_sha1_do_final *ptr_zencod_sha1_do_final = NULL;

static t_zencod_xdes_cipher *ptr_zencod_xdes_cipher = NULL;
static t_zencod_rc4_cipher *ptr_zencod_rc4_cipher = NULL;

/*
 * These are the static string constants for the DSO file name and the
 * function symbol names to bind to.
 */
static const char *ZENCOD_LIBNAME = ZEN_LIBRARY;

static const char *ZENCOD_Fct_0 = "test_device";
static const char *ZENCOD_Fct_1 = "zenbridge_bytes2bits";
static const char *ZENCOD_Fct_2 = "zenbridge_bits2bytes";
static const char *ZENCOD_Fct_3 = "zenbridge_new_number";
static const char *ZENCOD_Fct_4 = "zenbridge_init_number";

static const char *ZENCOD_Fct_exp_1 = "zenbridge_rsa_mod_exp";
static const char *ZENCOD_Fct_exp_2 = "zenbridge_rsa_mod_exp_crt";
static const char *ZENCOD_Fct_dsa_1 = "zenbridge_dsa_do_sign";
static const char *ZENCOD_Fct_dsa_2 = "zenbridge_dsa_do_verify";
static const char *ZENCOD_Fct_dh_1 = "zenbridge_dh_generate_key";
static const char *ZENCOD_Fct_dh_2 = "zenbridge_dh_compute_key";
static const char *ZENCOD_Fct_rand_1 = "zenbridge_rand_bytes";
static const char *ZENCOD_Fct_math_1 = "zenbridge_math_mod_exp";

static const char *ZENCOD_Fct_md5_1 = "zenbridge_md5_init";
static const char *ZENCOD_Fct_md5_2 = "zenbridge_md5_update";
static const char *ZENCOD_Fct_md5_3 = "zenbridge_md5_do_final";
static const char *ZENCOD_Fct_sha1_1 = "zenbridge_sha1_init";
static const char *ZENCOD_Fct_sha1_2 = "zenbridge_sha1_update";
static const char *ZENCOD_Fct_sha1_3 = "zenbridge_sha1_do_final";

static const char *ZENCOD_Fct_xdes_1 = "zenbridge_xdes_cipher";
static const char *ZENCOD_Fct_rc4_1 = "zenbridge_rc4_cipher";

/*
 * Destructor (complements the "ENGINE_zencod ()" constructor)
 */
static int zencod_destroy(ENGINE *e)
{

    ERR_unload_ZENCOD_strings();

    return 1;
}

/*
 * (de)initialisation functions. Control Function
 */
static int zencod_init(ENGINE *e)
{

    t_zencod_test *ptr_0;
    t_zencod_bytes2bits *ptr_1;
    t_zencod_bits2bytes *ptr_2;
    t_zencod_new_number *ptr_3;
    t_zencod_init_number *ptr_4;
    t_zencod_rsa_mod_exp *ptr_exp_1;
    t_zencod_rsa_mod_exp_crt *ptr_exp_2;
    t_zencod_dsa_do_sign *ptr_dsa_1;
    t_zencod_dsa_do_verify *ptr_dsa_2;
    t_zencod_dh_generate_key *ptr_dh_1;
    t_zencod_dh_compute_key *ptr_dh_2;
    t_zencod_rand_bytes *ptr_rand_1;
    t_zencod_math_mod_exp *ptr_math_1;
    t_zencod_md5_init *ptr_md5_1;
    t_zencod_md5_update *ptr_md5_2;
    t_zencod_md5_do_final *ptr_md5_3;
    t_zencod_sha1_init *ptr_sha1_1;
    t_zencod_sha1_update *ptr_sha1_2;
    t_zencod_sha1_do_final *ptr_sha1_3;
    t_zencod_xdes_cipher *ptr_xdes_1;
    t_zencod_rc4_cipher *ptr_rc4_1;

    CHEESE();

    /*
     * We Should add some tests for non NULL parameters or bad value !!
     * Stuff to be done ...
     */

    if (zencod_dso != NULL) {
        ZENCODerr(ZENCOD_F_ZENCOD_INIT, ZENCOD_R_ALREADY_LOADED);
        goto err;
    }
    /*
     * Trying to load the Library "cryptozen"
     */
    zencod_dso = DSO_load(NULL, ZENCOD_LIBNAME, NULL, 0);
    if (zencod_dso == NULL) {
        ZENCODerr(ZENCOD_F_ZENCOD_INIT, ZENCOD_R_DSO_FAILURE);
        goto err;
    }

    /*
     * Trying to load Function from the Library
     */
    if (!
        (ptr_1 =
         (t_zencod_bytes2bits *) DSO_bind_func(zencod_dso, ZENCOD_Fct_1))
|| !(ptr_2 = (t_zencod_bits2bytes *) DSO_bind_func(zencod_dso, ZENCOD_Fct_2))
|| !(ptr_3 = (t_zencod_new_number *) DSO_bind_func(zencod_dso, ZENCOD_Fct_3))
|| !(ptr_4 = (t_zencod_init_number *) DSO_bind_func(zencod_dso, ZENCOD_Fct_4))
|| !(ptr_exp_1 =
     (t_zencod_rsa_mod_exp *) DSO_bind_func(zencod_dso, ZENCOD_Fct_exp_1))
|| !(ptr_exp_2 =
     (t_zencod_rsa_mod_exp_crt *) DSO_bind_func(zencod_dso, ZENCOD_Fct_exp_2))
|| !(ptr_dsa_1 =
     (t_zencod_dsa_do_sign *) DSO_bind_func(zencod_dso, ZENCOD_Fct_dsa_1))
|| !(ptr_dsa_2 =
     (t_zencod_dsa_do_verify *) DSO_bind_func(zencod_dso, ZENCOD_Fct_dsa_2))
|| !(ptr_dh_1 =
     (t_zencod_dh_generate_key *) DSO_bind_func(zencod_dso, ZENCOD_Fct_dh_1))
|| !(ptr_dh_2 =
     (t_zencod_dh_compute_key *) DSO_bind_func(zencod_dso, ZENCOD_Fct_dh_2))
|| !(ptr_rand_1 =
     (t_zencod_rand_bytes *) DSO_bind_func(zencod_dso, ZENCOD_Fct_rand_1))
|| !(ptr_math_1 =
     (t_zencod_math_mod_exp *) DSO_bind_func(zencod_dso, ZENCOD_Fct_math_1))
|| !(ptr_0 = (t_zencod_test *) DSO_bind_func(zencod_dso, ZENCOD_Fct_0))
|| !(ptr_md5_1 =
     (t_zencod_md5_init *) DSO_bind_func(zencod_dso, ZENCOD_Fct_md5_1))
|| !(ptr_md5_2 =
     (t_zencod_md5_update *) DSO_bind_func(zencod_dso, ZENCOD_Fct_md5_2))
|| !(ptr_md5_3 =
     (t_zencod_md5_do_final *) DSO_bind_func(zencod_dso, ZENCOD_Fct_md5_3))
|| !(ptr_sha1_1 =
     (t_zencod_sha1_init *) DSO_bind_func(zencod_dso, ZENCOD_Fct_sha1_1))
|| !(ptr_sha1_2 =
     (t_zencod_sha1_update *) DSO_bind_func(zencod_dso, ZENCOD_Fct_sha1_2))
|| !(ptr_sha1_3 =
     (t_zencod_sha1_do_final *) DSO_bind_func(zencod_dso, ZENCOD_Fct_sha1_3))
|| !(ptr_xdes_1 =
     (t_zencod_xdes_cipher *) DSO_bind_func(zencod_dso, ZENCOD_Fct_xdes_1))
|| !(ptr_rc4_1 =
     (t_zencod_rc4_cipher *) DSO_bind_func(zencod_dso, ZENCOD_Fct_rc4_1))) {

        ZENCODerr(ZENCOD_F_ZENCOD_INIT, ZENCOD_R_DSO_FAILURE);
        goto err;
    }

    /*
     * The function from "cryptozen" Library have been correctly loaded so
     * copy them
     */
    ptr_zencod_test = ptr_0;
    ptr_zencod_bytes2bits = ptr_1;
    ptr_zencod_bits2bytes = ptr_2;
    ptr_zencod_new_number = ptr_3;
    ptr_zencod_init_number = ptr_4;
    ptr_zencod_rsa_mod_exp = ptr_exp_1;
    ptr_zencod_rsa_mod_exp_crt = ptr_exp_2;
    ptr_zencod_dsa_do_sign = ptr_dsa_1;
    ptr_zencod_dsa_do_verify = ptr_dsa_2;
    ptr_zencod_dh_generate_key = ptr_dh_1;
    ptr_zencod_dh_compute_key = ptr_dh_2;
    ptr_zencod_rand_bytes = ptr_rand_1;
    ptr_zencod_math_mod_exp = ptr_math_1;
    ptr_zencod_test = ptr_0;
    ptr_zencod_md5_init = ptr_md5_1;
    ptr_zencod_md5_update = ptr_md5_2;
    ptr_zencod_md5_do_final = ptr_md5_3;
    ptr_zencod_sha1_init = ptr_sha1_1;
    ptr_zencod_sha1_update = ptr_sha1_2;
    ptr_zencod_sha1_do_final = ptr_sha1_3;
    ptr_zencod_xdes_cipher = ptr_xdes_1;
    ptr_zencod_rc4_cipher = ptr_rc4_1;

    /*
     * We should peform a test to see if there is actually any unit runnig on
     * the system ... Even if the cryptozen library is loaded the module coul
     * not be loaded on the system ... For now we may just open and close the
     * device !!
     */

    if (ptr_zencod_test() != 0) {
        ZENCODerr(ZENCOD_F_ZENCOD_INIT, ZENCOD_R_UNIT_FAILURE);
        goto err;
    }

    return 1;
 err:
    if (zencod_dso) {
        DSO_free(zencod_dso);
    }
    zencod_dso = NULL;
    ptr_zencod_bytes2bits = NULL;
    ptr_zencod_bits2bytes = NULL;
    ptr_zencod_new_number = NULL;
    ptr_zencod_init_number = NULL;
    ptr_zencod_rsa_mod_exp = NULL;
    ptr_zencod_rsa_mod_exp_crt = NULL;
    ptr_zencod_dsa_do_sign = NULL;
    ptr_zencod_dsa_do_verify = NULL;
    ptr_zencod_dh_generate_key = NULL;
    ptr_zencod_dh_compute_key = NULL;
    ptr_zencod_rand_bytes = NULL;
    ptr_zencod_math_mod_exp = NULL;
    ptr_zencod_test = NULL;
    ptr_zencod_md5_init = NULL;
    ptr_zencod_md5_update = NULL;
    ptr_zencod_md5_do_final = NULL;
    ptr_zencod_sha1_init = NULL;
    ptr_zencod_sha1_update = NULL;
    ptr_zencod_sha1_do_final = NULL;
    ptr_zencod_xdes_cipher = NULL;
    ptr_zencod_rc4_cipher = NULL;

    return 0;
}

static int zencod_finish(ENGINE *e)
{

    CHEESE();

    /*
     * We Should add some tests for non NULL parameters or bad value !!
     * Stuff to be done ...
     */
    if (zencod_dso == NULL) {
        ZENCODerr(ZENCOD_F_ZENCOD_FINISH, ZENCOD_R_NOT_LOADED);
        return 0;
    }
    if (!DSO_free(zencod_dso)) {
        ZENCODerr(ZENCOD_F_ZENCOD_FINISH, ZENCOD_R_DSO_FAILURE);
        return 0;
    }

    zencod_dso = NULL;

    ptr_zencod_bytes2bits = NULL;
    ptr_zencod_bits2bytes = NULL;
    ptr_zencod_new_number = NULL;
    ptr_zencod_init_number = NULL;
    ptr_zencod_rsa_mod_exp = NULL;
    ptr_zencod_rsa_mod_exp_crt = NULL;
    ptr_zencod_dsa_do_sign = NULL;
    ptr_zencod_dsa_do_verify = NULL;
    ptr_zencod_dh_generate_key = NULL;
    ptr_zencod_dh_compute_key = NULL;
    ptr_zencod_rand_bytes = NULL;
    ptr_zencod_math_mod_exp = NULL;
    ptr_zencod_test = NULL;
    ptr_zencod_md5_init = NULL;
    ptr_zencod_md5_update = NULL;
    ptr_zencod_md5_do_final = NULL;
    ptr_zencod_sha1_init = NULL;
    ptr_zencod_sha1_update = NULL;
    ptr_zencod_sha1_do_final = NULL;
    ptr_zencod_xdes_cipher = NULL;
    ptr_zencod_rc4_cipher = NULL;

    return 1;
}

static int zencod_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) ())
{

    int initialised = ((zencod_dso == NULL) ? 0 : 1);

    CHEESE();

    /*
     * We Should add some tests for non NULL parameters or bad value !!
     * Stuff to be done ...
     */
    switch (cmd) {
    case ZENCOD_CMD_SO_PATH:
        if (p == NULL) {
            ZENCODerr(ZENCOD_F_ZENCOD_CTRL, ERR_R_PASSED_NULL_PARAMETER);
            return 0;
        }
        if (initialised) {
            ZENCODerr(ZENCOD_F_ZENCOD_CTRL, ZENCOD_R_ALREADY_LOADED);
            return 0;
        }
        ZENCOD_LIBNAME = (const char *)p;
        return 1;
    default:
        break;
    }

    ZENCODerr(ZENCOD_F_ZENCOD_CTRL, ZENCOD_R_CTRL_COMMAND_NOT_IMPLEMENTED);

    return 0;
}

/*
 * BIGNUM stuff Functions
 */
static int zencod_bn_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
                             const BIGNUM *m, BN_CTX *ctx)
{
    zen_nb_t y, x, e, n;
    int ret;

    CHEESE();

    if (!zencod_dso) {
        ENGINEerr(ZENCOD_F_ZENCOD_BN_MOD_EXP, ZENCOD_R_NOT_LOADED);
        return 0;
    }

    if (!bn_wexpand(r, m->top + 1)) {
        ENGINEerr(ZENCOD_F_ZENCOD_BN_MOD_EXP, ZENCOD_R_BN_EXPAND_FAIL);
        return 0;
    }

    memset(r->d, 0, BN_num_bytes(m));

    ptr_zencod_init_number(&y, (r->dmax - 1) * sizeof(BN_ULONG) * 8,
                           (unsigned char *)r->d);
    BIGNUM2ZEN(&x, a);
    BIGNUM2ZEN(&e, p);
    BIGNUM2ZEN(&n, m);

    /* Must invert x and e parameter due to BN mod exp prototype ... */
    ret = ptr_zencod_math_mod_exp(&y, &e, &x, &n);

    if (ret) {
        PERROR("zenbridge_math_mod_exp");
        ENGINEerr(ZENCOD_F_ZENCOD_BN_MOD_EXP, ZENCOD_R_REQUEST_FAILED);
        return 0;
    }

    r->top = (BN_num_bits(m) + BN_BITS2 - 1) / BN_BITS2;

    return 1;
}

/*
 * RSA stuff Functions
 */
#  ifndef OPENSSL_NO_RSA
static int RSA_zencod_rsa_mod_exp(BIGNUM *r0, const BIGNUM *i, RSA *rsa)
{

    CHEESE();

    if (!zencod_dso) {
        ENGINEerr(ZENCOD_F_ZENCOD_RSA_MOD_EXP_CRT, ZENCOD_R_NOT_LOADED);
        return 0;
    }

    if (!rsa->p || !rsa->q || !rsa->dmp1 || !rsa->dmq1 || !rsa->iqmp) {
        ENGINEerr(ZENCOD_F_ZENCOD_RSA_MOD_EXP_CRT,
                  ZENCOD_R_BAD_KEY_COMPONENTS);
        return 0;
    }

    /* Do in software if argument is too large for hardware */
    if (RSA_size(rsa) * 8 > ZENBRIDGE_MAX_KEYSIZE_RSA_CRT) {
        const RSA_METHOD *meth;

        meth = RSA_PKCS1_SSLeay();
        return meth->rsa_mod_exp(r0, i, rsa);
    } else {
        zen_nb_t y, x, p, q, dmp1, dmq1, iqmp;

        if (!bn_expand(r0, RSA_size(rsa) * 8)) {
            ENGINEerr(ZENCOD_F_ZENCOD_RSA_MOD_EXP_CRT,
                      ZENCOD_R_BN_EXPAND_FAIL);
            return 0;
        }
        r0->top = (RSA_size(rsa) * 8 + BN_BITS2 - 1) / BN_BITS2;

        BIGNUM2ZEN(&x, i);
        BIGNUM2ZEN(&y, r0);
        BIGNUM2ZEN(&p, rsa->p);
        BIGNUM2ZEN(&q, rsa->q);
        BIGNUM2ZEN(&dmp1, rsa->dmp1);
        BIGNUM2ZEN(&dmq1, rsa->dmq1);
        BIGNUM2ZEN(&iqmp, rsa->iqmp);

        if (ptr_zencod_rsa_mod_exp_crt(&y, &x, &p, &q, &dmp1, &dmq1, &iqmp) <
            0) {
            PERROR("zenbridge_rsa_mod_exp_crt");
            ENGINEerr(ZENCOD_F_ZENCOD_RSA_MOD_EXP_CRT,
                      ZENCOD_R_REQUEST_FAILED);
            return 0;
        }

        return 1;
    }
}

/*
 * This function is aliased to RSA_mod_exp (with the mont stuff dropped).
 */
static int RSA_zencod_bn_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
                                 const BIGNUM *m, BN_CTX *ctx,
                                 BN_MONT_CTX *m_ctx)
{

    CHEESE();

    if (!zencod_dso) {
        ENGINEerr(ZENCOD_F_ZENCOD_RSA_MOD_EXP, ZENCOD_R_NOT_LOADED);
        return 0;
    }

    /* Do in software if argument is too large for hardware */
    if (BN_num_bits(m) > ZENBRIDGE_MAX_KEYSIZE_RSA) {
        const RSA_METHOD *meth;

        meth = RSA_PKCS1_SSLeay();
        return meth->bn_mod_exp(r, a, p, m, ctx, m_ctx);
    } else {
        zen_nb_t y, x, e, n;

        if (!bn_expand(r, BN_num_bits(m))) {
            ENGINEerr(ZENCOD_F_ZENCOD_RSA_MOD_EXP, ZENCOD_R_BN_EXPAND_FAIL);
            return 0;
        }
        r->top = (BN_num_bits(m) + BN_BITS2 - 1) / BN_BITS2;

        BIGNUM2ZEN(&x, a);
        BIGNUM2ZEN(&y, r);
        BIGNUM2ZEN(&e, p);
        BIGNUM2ZEN(&n, m);

        if (ptr_zencod_rsa_mod_exp(&y, &x, &n, &e) < 0) {
            PERROR("zenbridge_rsa_mod_exp");
            ENGINEerr(ZENCOD_F_ZENCOD_RSA_MOD_EXP, ZENCOD_R_REQUEST_FAILED);
            return 0;
        }

        return 1;
    }
}
#  endif                        /* !OPENSSL_NO_RSA */

#  ifndef OPENSSL_NO_DSA
/*
 * DSA stuff Functions
 */
static DSA_SIG *DSA_zencod_do_sign(const unsigned char *dgst, int dlen,
                                   DSA *dsa)
{
    zen_nb_t p, q, g, x, y, r, s, data;
    DSA_SIG *sig;
    BIGNUM *bn_r = NULL;
    BIGNUM *bn_s = NULL;
    char msg[20];

    CHEESE();

    if (!zencod_dso) {
        ENGINEerr(ZENCOD_F_ZENCOD_DSA_DO_SIGN, ZENCOD_R_NOT_LOADED);
        goto FAILED;
    }

    if (dlen > 160) {
        ENGINEerr(ZENCOD_F_ZENCOD_DSA_DO_SIGN, ZENCOD_R_REQUEST_FAILED);
        goto FAILED;
    }

    /* Do in software if argument is too large for hardware */
    if (BN_num_bits(dsa->p) > ZENBRIDGE_MAX_KEYSIZE_DSA_SIGN ||
        BN_num_bits(dsa->g) > ZENBRIDGE_MAX_KEYSIZE_DSA_SIGN) {
        const DSA_METHOD *meth;
        ENGINEerr(ZENCOD_F_ZENCOD_DSA_DO_SIGN, ZENCOD_R_BAD_KEY_COMPONENTS);
        meth = DSA_OpenSSL();
        return meth->dsa_do_sign(dgst, dlen, dsa);
    }

    if (!(bn_s = BN_new()) || !(bn_r = BN_new())) {
        ENGINEerr(ZENCOD_F_ZENCOD_DSA_DO_SIGN, ZENCOD_R_BAD_KEY_COMPONENTS);
        goto FAILED;
    }

    if (!bn_expand(bn_r, 160) || !bn_expand(bn_s, 160)) {
        ENGINEerr(ZENCOD_F_ZENCOD_DSA_DO_SIGN, ZENCOD_R_BN_EXPAND_FAIL);
        goto FAILED;
    }

    bn_r->top = bn_s->top = (160 + BN_BITS2 - 1) / BN_BITS2;
    BIGNUM2ZEN(&p, dsa->p);
    BIGNUM2ZEN(&q, dsa->q);
    BIGNUM2ZEN(&g, dsa->g);
    BIGNUM2ZEN(&x, dsa->priv_key);
    BIGNUM2ZEN(&y, dsa->pub_key);
    BIGNUM2ZEN(&r, bn_r);
    BIGNUM2ZEN(&s, bn_s);
    q.len = x.len = 160;

    ypcmem(msg, dgst, 20);
    ptr_zencod_init_number(&data, 160, msg);

    if (ptr_zencod_dsa_do_sign(0, &data, &y, &p, &q, &g, &x, &r, &s) < 0) {
        PERROR("zenbridge_dsa_do_sign");
        ENGINEerr(ZENCOD_F_ZENCOD_DSA_DO_SIGN, ZENCOD_R_REQUEST_FAILED);
        goto FAILED;
    }

    if (!(sig = DSA_SIG_new())) {
        ENGINEerr(ZENCOD_F_ZENCOD_DSA_DO_SIGN, ZENCOD_R_REQUEST_FAILED);
        goto FAILED;
    }
    sig->r = bn_r;
    sig->s = bn_s;
    return sig;

 FAILED:
    BN_free(bn_r);
    BN_free(bn_s);
    return NULL;
}

static int DSA_zencod_do_verify(const unsigned char *dgst, int dlen,
                                DSA_SIG *sig, DSA *dsa)
{
    zen_nb_t data, p, q, g, y, r, s, v;
    char msg[20];
    char v_data[20];
    int ret;

    CHEESE();

    if (!zencod_dso) {
        ENGINEerr(ZENCOD_F_ZENCOD_DSA_DO_VERIFY, ZENCOD_R_NOT_LOADED);
        return 0;
    }

    if (dlen > 160) {
        ENGINEerr(ZENCOD_F_ZENCOD_DSA_DO_SIGN, ZENCOD_R_REQUEST_FAILED);
        return 0;
    }

    /* Do in software if argument is too large for hardware */
    if (BN_num_bits(dsa->p) > ZENBRIDGE_MAX_KEYSIZE_DSA_SIGN ||
        BN_num_bits(dsa->g) > ZENBRIDGE_MAX_KEYSIZE_DSA_SIGN) {
        const DSA_METHOD *meth;
        ENGINEerr(ZENCOD_F_ZENCOD_DSA_DO_SIGN, ZENCOD_R_BAD_KEY_COMPONENTS);
        meth = DSA_OpenSSL();
        return meth->dsa_do_verify(dgst, dlen, sig, dsa);
    }

    BIGNUM2ZEN(&p, dsa->p);
    BIGNUM2ZEN(&q, dsa->q);
    BIGNUM2ZEN(&g, dsa->g);
    BIGNUM2ZEN(&y, dsa->pub_key);
    BIGNUM2ZEN(&r, sig->r);
    BIGNUM2ZEN(&s, sig->s);
    ptr_zencod_init_number(&v, 160, v_data);
    ypcmem(msg, dgst, 20);
    ptr_zencod_init_number(&data, 160, msg);

    if ((ret =
         ptr_zencod_dsa_do_verify(0, &data, &p, &q, &g, &y, &r, &s,
                                  &v)) < 0) {
        PERROR("zenbridge_dsa_do_verify");
        ENGINEerr(ZENCOD_F_ZENCOD_DSA_DO_VERIFY, ZENCOD_R_REQUEST_FAILED);
        return 0;
    }

    return ((ret == 0) ? 1 : ret);
}

static int DSA_zencod_bn_mod_exp(DSA *dsa, BIGNUM *r, BIGNUM *a,
                                 const BIGNUM *p, const BIGNUM *m,
                                 BN_CTX *ctx, BN_MONT_CTX *m_ctx)
{
    CHEESE();

    return zencod_bn_mod_exp(r, a, p, m, ctx);
}
#  endif                        /* !OPENSSL_NO_DSA */

#  ifndef OPENSSl_NO_DH
/*
 * DH stuff Functions
 */
static int DH_zencod_generate_key(DH *dh)
{
    BIGNUM *bn_prv = NULL;
    BIGNUM *bn_pub = NULL;
    zen_nb_t y, x, g, p;
    int generate_x;

    CHEESE();

    if (!zencod_dso) {
        ENGINEerr(ZENCOD_F_ZENCOD_DH_GENERATE, ZENCOD_R_NOT_LOADED);
        return 0;
    }

    /* Private key */
    if (dh->priv_key) {
        bn_prv = dh->priv_key;
        generate_x = 0;
    } else {
        if (!(bn_prv = BN_new())) {
            ENGINEerr(ZENCOD_F_ZENCOD_DH_GENERATE, ZENCOD_R_BN_EXPAND_FAIL);
            goto FAILED;
        }
        generate_x = 1;
    }

    /* Public key */
    if (dh->pub_key)
        bn_pub = dh->pub_key;
    else if (!(bn_pub = BN_new())) {
        ENGINEerr(ZENCOD_F_ZENCOD_DH_GENERATE, ZENCOD_R_BN_EXPAND_FAIL);
        goto FAILED;
    }

    /* Expand */
    if (!bn_wexpand(bn_prv, dh->p->dmax) || !bn_wexpand(bn_pub, dh->p->dmax)) {
        ENGINEerr(ZENCOD_F_ZENCOD_DH_GENERATE, ZENCOD_R_BN_EXPAND_FAIL);
        goto FAILED;
    }
    bn_prv->top = dh->p->top;
    bn_pub->top = dh->p->top;

    /* Convert all keys */
    BIGNUM2ZEN(&p, dh->p);
    BIGNUM2ZEN(&g, dh->g);
    BIGNUM2ZEN(&y, bn_pub);
    BIGNUM2ZEN(&x, bn_prv);
    x.len = DH_size(dh) * 8;

    /* Adjust the lengths of P and G */
    p.len = ptr_zencod_bytes2bits(p.data, ZEN_BYTES(p.len));
    g.len = ptr_zencod_bytes2bits(g.data, ZEN_BYTES(g.len));

    /* Send the request to the driver */
    if (ptr_zencod_dh_generate_key(&y, &x, &g, &p, generate_x) < 0) {
        perror("zenbridge_dh_generate_key");
        ENGINEerr(ZENCOD_F_ZENCOD_DH_GENERATE, ZENCOD_R_REQUEST_FAILED);
        goto FAILED;
    }

    dh->priv_key = bn_prv;
    dh->pub_key = bn_pub;

    return 1;

 FAILED:
    if (!dh->priv_key)
        BN_free(bn_prv);
    if (!dh->pub_key)
        BN_free(bn_pub);

    return 0;
}

static int DH_zencod_compute_key(unsigned char *key, const BIGNUM *pub_key,
                                 DH *dh)
{
    zen_nb_t y, x, p, k;

    CHEESE();

    if (!zencod_dso) {
        ENGINEerr(ZENCOD_F_ZENCOD_DH_COMPUTE, ZENCOD_R_NOT_LOADED);
        return 0;
    }

    if (!dh->priv_key) {
        ENGINEerr(ZENCOD_F_ZENCOD_DH_COMPUTE, ZENCOD_R_BAD_KEY_COMPONENTS);
        return 0;
    }

    /* Convert all keys */
    BIGNUM2ZEN(&y, pub_key);
    BIGNUM2ZEN(&x, dh->priv_key);
    BIGNUM2ZEN(&p, dh->p);
    ptr_zencod_init_number(&k, p.len, key);

    /* Adjust the lengths */
    p.len = ptr_zencod_bytes2bits(p.data, ZEN_BYTES(p.len));
    y.len = ptr_zencod_bytes2bits(y.data, ZEN_BYTES(y.len));
    x.len = ptr_zencod_bytes2bits(x.data, ZEN_BYTES(x.len));

    /* Call the hardware */
    if (ptr_zencod_dh_compute_key(&k, &y, &x, &p) < 0) {
        ENGINEerr(ZENCOD_F_ZENCOD_DH_COMPUTE, ZENCOD_R_REQUEST_FAILED);
        return 0;
    }

    /* The key must be written MSB -> LSB */
    k.len = ptr_zencod_bytes2bits(k.data, ZEN_BYTES(k.len));
    esrever(key, ZEN_BYTES(k.len));

    return ZEN_BYTES(k.len);
}

static int DH_zencod_bn_mod_exp(const DH *dh, BIGNUM *r, const BIGNUM *a,
                                const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
                                BN_MONT_CTX *m_ctx)
{
    CHEESE();

    return zencod_bn_mod_exp(r, a, p, m, ctx);
}
#  endif                        /* !OPENSSL_NO_DH */

/*
 * RAND stuff Functions
 */
static void RAND_zencod_seed(const void *buf, int num)
{
    /*
     * Nothing to do cause our crypto accelerator provide a true random
     * generator
     */
}

static int RAND_zencod_rand_bytes(unsigned char *buf, int num)
{
    zen_nb_t r;

    CHEESE();

    if (!zencod_dso) {
        ENGINEerr(ZENCOD_F_ZENCOD_RAND, ZENCOD_R_NOT_LOADED);
        return 0;
    }

    ptr_zencod_init_number(&r, num * 8, buf);

    if (ptr_zencod_rand_bytes(&r, ZENBRIDGE_RNG_DIRECT) < 0) {
        PERROR("zenbridge_rand_bytes");
        ENGINEerr(ZENCOD_F_ZENCOD_RAND, ZENCOD_R_REQUEST_FAILED);
        return 0;
    }

    return 1;
}

static int RAND_zencod_rand_status(void)
{
    CHEESE();

    return 1;
}

/*
 * This stuff is needed if this ENGINE is being compiled into a
 * self-contained shared-library.
 */
#  ifdef ENGINE_DYNAMIC_SUPPORT
static int bind_fn(ENGINE *e, const char *id)
{

    if (id && (strcmp(id, engine_zencod_id) != 0)) {
        return 0;
    }
    if (!bind_helper(e)) {
        return 0;
    }

    return 1;
}

IMPLEMENT_DYNAMIC_CHECK_FN()
    IMPLEMENT_DYNAMIC_BIND_FN(bind_fn)
#  endif                        /* ENGINE_DYNAMIC_SUPPORT */
    /*
     * Adding "Digest" and "Cipher" tools ...
     * This is in development ... ;-)
     * In orfer to code this, i refer to hw_openbsd_dev_crypto and openssl engine made by Geoff Thorpe (if i'm rigth),
     * and evp, sha md5 definitions etc ...
     */
/* First add some include ... */
#  include <openssl/evp.h>
#  include <openssl/sha.h>
#  include <openssl/md5.h>
#  include <openssl/rc4.h>
#  include <openssl/des.h>
/* Some variables declaration ... */
    /*
     * DONS: Disable symetric computation except DES and 3DES, but let part
     * of the code
     */
/* static int engine_digest_nids [ ] = { NID_sha1, NID_md5 } ; */
static int engine_digest_nids[] = { };

static int engine_digest_nids_num = 0;
/*
 * static int engine_cipher_nids [ ] = { NID_rc4, NID_rc4_40, NID_des_cbc,
 * NID_des_ede3_cbc } ;
 */
static int engine_cipher_nids[] = { NID_des_cbc, NID_des_ede3_cbc };

static int engine_cipher_nids_num = 2;

/* Function prototype ... */
/*  SHA stuff */
static int engine_sha1_init(EVP_MD_CTX *ctx);
static int engine_sha1_update(EVP_MD_CTX *ctx, const void *data,
                              unsigned long count);
static int engine_sha1_final(EVP_MD_CTX *ctx, unsigned char *md);

/*  MD5 stuff */
static int engine_md5_init(EVP_MD_CTX *ctx);
static int engine_md5_update(EVP_MD_CTX *ctx, const void *data,
                             unsigned long count);
static int engine_md5_final(EVP_MD_CTX *ctx, unsigned char *md);

static int engine_md_cleanup(EVP_MD_CTX *ctx);
static int engine_md_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from);

/* RC4 Stuff */
static int engine_rc4_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
                               const unsigned char *iv, int enc);
static int engine_rc4_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
                             const unsigned char *in, unsigned int inl);

/* DES Stuff */
static int engine_des_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
                               const unsigned char *iv, int enc);
static int engine_des_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
                                 const unsigned char *in, unsigned int inl);

/*  3DES Stuff */
static int engine_des_ede3_init_key(EVP_CIPHER_CTX *ctx,
                                    const unsigned char *key,
                                    const unsigned char *iv, int enc);
static int engine_des_ede3_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
                                      const unsigned char *in,
                                      unsigned int inl);

static int engine_cipher_cleanup(EVP_CIPHER_CTX *ctx); /* cleanup ctx */

/* The one for SHA ... */
static const EVP_MD engine_sha1_md = {
    NID_sha1,
    NID_sha1WithRSAEncryption,
    SHA_DIGEST_LENGTH,
    EVP_MD_FLAG_ONESHOT,
    /*
     * 0,
     *//*
     * EVP_MD_FLAG_ONESHOT = x0001 digest can only handle a single block *
     * XXX: set according to device info ...
     */
    engine_sha1_init,
    engine_sha1_update,
    engine_sha1_final,
    engine_md_copy,             /* dev_crypto_sha_copy */
    engine_md_cleanup,          /* dev_crypto_sha_cleanup */
    EVP_PKEY_RSA_method,
    SHA_CBLOCK,
    /* sizeof ( EVP_MD * ) + sizeof ( SHA_CTX ) */
    sizeof(ZEN_MD_DATA)
        /*
         * sizeof ( MD_CTX_DATA ) The message digest data structure ...
         */
};

/* The one for MD5 ... */
static const EVP_MD engine_md5_md = {
    NID_md5,
    NID_md5WithRSAEncryption,
    MD5_DIGEST_LENGTH,
    EVP_MD_FLAG_ONESHOT,
    /*
     * 0,
     *//*
     * EVP_MD_FLAG_ONESHOT = x0001 digest can only handle a single block *
     * XXX: set according to device info ...
     */
    engine_md5_init,
    engine_md5_update,
    engine_md5_final,
    engine_md_copy,             /* dev_crypto_md5_copy */
    engine_md_cleanup,          /* dev_crypto_md5_cleanup */
    EVP_PKEY_RSA_method,
    MD5_CBLOCK,
    /* sizeof ( EVP_MD * ) + sizeof ( MD5_CTX ) */
    sizeof(ZEN_MD_DATA)
        /*
         * sizeof ( MD_CTX_DATA ) The message digest data structure ...
         */
};

/* The one for RC4 ... */
#  define EVP_RC4_KEY_SIZE                        16

/* Try something static ... */
typedef struct {
    unsigned int len;
    unsigned int first;
    unsigned char rc4_state[260];
} NEW_ZEN_RC4_KEY;

#  define rc4_data(ctx)                           ( (EVP_RC4_KEY *) ( ctx )->cipher_data )

static const EVP_CIPHER engine_rc4 = {
    NID_rc4,
    1,
    16,                         /* EVP_RC4_KEY_SIZE should be 128 bits */
    0,                          /* FIXME: key should be up to 256 bytes */
    EVP_CIPH_VARIABLE_LENGTH,
    engine_rc4_init_key,
    engine_rc4_cipher,
    engine_cipher_cleanup,
    sizeof(NEW_ZEN_RC4_KEY),
    NULL,
    NULL,
    NULL
};

/* The one for RC4_40 ... */
static const EVP_CIPHER engine_rc4_40 = {
    NID_rc4_40,
    1,
    5,                          /* 40 bits */
    0,
    EVP_CIPH_VARIABLE_LENGTH,
    engine_rc4_init_key,
    engine_rc4_cipher,
    engine_cipher_cleanup,
    sizeof(NEW_ZEN_RC4_KEY),
    NULL,
    NULL,
    NULL
};

/* The one for DES ... */

/* Try something static ... */
typedef struct {
    unsigned char des_key[24];
    unsigned char des_iv[8];
} ZEN_DES_KEY;

static const EVP_CIPHER engine_des_cbc = {
    NID_des_cbc,
    8, 8, 8,
    0 | EVP_CIPH_CBC_MODE,
    engine_des_init_key,
    engine_des_cbc_cipher,
    engine_cipher_cleanup,
    sizeof(ZEN_DES_KEY),
    EVP_CIPHER_set_asn1_iv,
    EVP_CIPHER_get_asn1_iv,
    NULL,
    NULL
};

/* The one for 3DES ... */

/* Try something static ... */
typedef struct {
    unsigned char des3_key[24];
    unsigned char des3_iv[8];
} ZEN_3DES_KEY;

#  define des_data(ctx)                            ( (DES_EDE_KEY *) ( ctx )->cipher_data )

static const EVP_CIPHER engine_des_ede3_cbc = {
    NID_des_ede3_cbc,
    8, 8, 8,
    0 | EVP_CIPH_CBC_MODE,
    engine_des_ede3_init_key,
    engine_des_ede3_cbc_cipher,
    engine_cipher_cleanup,
    sizeof(ZEN_3DES_KEY),
    EVP_CIPHER_set_asn1_iv,
    EVP_CIPHER_get_asn1_iv,
    NULL,
    NULL
};

/* General function cloned on hw_openbsd_dev_crypto one ... */
static int engine_digests(ENGINE *e, const EVP_MD **digest, const int **nids,
                          int nid)
{

#  ifdef DEBUG_ZENCOD_MD
    fprintf(stderr, "\t=>Function : static int engine_digests () called !\n");
#  endif

    if (!digest) {
        /* We are returning a list of supported nids */
        *nids = engine_digest_nids;
        return engine_digest_nids_num;
    }
    /* We are being asked for a specific digest */
    if (nid == NID_md5) {
        *digest = &engine_md5_md;
    } else if (nid == NID_sha1) {
        *digest = &engine_sha1_md;
    } else {
        *digest = NULL;
        return 0;
    }
    return 1;
}

/*
 * SHA stuff Functions
 */
static int engine_sha1_init(EVP_MD_CTX *ctx)
{

    int to_return = 0;

    /* Test with zenbridge library ... */
    to_return = ptr_zencod_sha1_init((ZEN_MD_DATA *)ctx->md_data);
    to_return = !to_return;

    return to_return;
}

static int engine_sha1_update(EVP_MD_CTX *ctx, const void *data,
                              unsigned long count)
{

    zen_nb_t input;
    int to_return = 0;

    /* Convert parameters ... */
    input.len = count;
    input.data = (unsigned char *)data;

    /* Test with zenbridge library ... */
    to_return =
        ptr_zencod_sha1_update((ZEN_MD_DATA *)ctx->md_data,
                               (const zen_nb_t *)&input);
    to_return = !to_return;

    return to_return;
}

static int engine_sha1_final(EVP_MD_CTX *ctx, unsigned char *md)
{

    zen_nb_t output;
    int to_return = 0;

    /* Convert parameters ... */
    output.len = SHA_DIGEST_LENGTH;
    output.data = md;

    /* Test with zenbridge library ... */
    to_return =
        ptr_zencod_sha1_do_final((ZEN_MD_DATA *)ctx->md_data,
                                 (zen_nb_t *) & output);
    to_return = !to_return;

    return to_return;
}

/*
 * MD5 stuff Functions
 */
static int engine_md5_init(EVP_MD_CTX *ctx)
{

    int to_return = 0;

    /* Test with zenbridge library ... */
    to_return = ptr_zencod_md5_init((ZEN_MD_DATA *)ctx->md_data);
    to_return = !to_return;

    return to_return;
}

static int engine_md5_update(EVP_MD_CTX *ctx, const void *data,
                             unsigned long count)
{

    zen_nb_t input;
    int to_return = 0;

    /* Convert parameters ... */
    input.len = count;
    input.data = (unsigned char *)data;

    /* Test with zenbridge library ... */
    to_return =
        ptr_zencod_md5_update((ZEN_MD_DATA *)ctx->md_data,
                              (const zen_nb_t *)&input);
    to_return = !to_return;

    return to_return;
}

static int engine_md5_final(EVP_MD_CTX *ctx, unsigned char *md)
{

    zen_nb_t output;
    int to_return = 0;

    /* Convert parameters ... */
    output.len = MD5_DIGEST_LENGTH;
    output.data = md;

    /* Test with zenbridge library ... */
    to_return =
        ptr_zencod_md5_do_final((ZEN_MD_DATA *)ctx->md_data,
                                (zen_nb_t *) & output);
    to_return = !to_return;

    return to_return;
}

static int engine_md_cleanup(EVP_MD_CTX *ctx)
{

    ZEN_MD_DATA *zen_md_data = (ZEN_MD_DATA *)ctx->md_data;

    if (zen_md_data->HashBuffer != NULL) {
        OPENSSL_free(zen_md_data->HashBuffer);
        zen_md_data->HashBufferSize = 0;
        ctx->md_data = NULL;
    }

    return 1;
}

static int engine_md_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from)
{
    const ZEN_MD_DATA *from_md = (ZEN_MD_DATA *)from->md_data;
    ZEN_MD_DATA *to_md = (ZEN_MD_DATA *)to->md_data;

    to_md->HashBuffer = OPENSSL_malloc(from_md->HashBufferSize);
    if (to_md->HashBuffer == NULL)
        return 0;
    memcpy(to_md->HashBuffer, from_md->HashBuffer, from_md->HashBufferSize);

    return 1;
}

/* General function cloned on hw_openbsd_dev_crypto one ... */
static int engine_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
                          const int **nids, int nid)
{

    if (!cipher) {
        /* We are returning a list of supported nids */
        *nids = engine_cipher_nids;
        return engine_cipher_nids_num;
    }
    /* We are being asked for a specific cipher */
    if (nid == NID_rc4) {
        *cipher = &engine_rc4;
    } else if (nid == NID_rc4_40) {
        *cipher = &engine_rc4_40;
    } else if (nid == NID_des_cbc) {
        *cipher = &engine_des_cbc;
    } else if (nid == NID_des_ede3_cbc) {
        *cipher = &engine_des_ede3_cbc;
    } else {
        *cipher = NULL;
        return 0;
    }

    return 1;
}

static int engine_rc4_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
                               const unsigned char *iv, int enc)
{
    int to_return = 0;
    int i = 0;
    int nb = 0;
    NEW_ZEN_RC4_KEY *tmp_rc4_key = NULL;

    tmp_rc4_key = (NEW_ZEN_RC4_KEY *) (ctx->cipher_data);
    tmp_rc4_key->first = 0;
    tmp_rc4_key->len = ctx->key_len;
    tmp_rc4_key->rc4_state[0] = 0x00;
    tmp_rc4_key->rc4_state[2] = 0x00;
    nb = 256 / ctx->key_len;
    for (i = 0; i < nb; i++) {
        memcpy(&(tmp_rc4_key->rc4_state[4 + i * ctx->key_len]), key,
               ctx->key_len);
    }

    to_return = 1;

    return to_return;
}

static int engine_rc4_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
                             const unsigned char *in, unsigned int in_len)
{

    zen_nb_t output, input;
    zen_nb_t rc4key;
    int to_return = 0;
    NEW_ZEN_RC4_KEY *tmp_rc4_key = NULL;

    /* Convert parameters ... */
    input.len = in_len;
    input.data = (unsigned char *)in;
    output.len = in_len;
    output.data = (unsigned char *)out;

    tmp_rc4_key = ((NEW_ZEN_RC4_KEY *) (ctx->cipher_data));
    rc4key.len = 260;
    rc4key.data = &(tmp_rc4_key->rc4_state[0]);

    /* Test with zenbridge library ... */
    to_return =
        ptr_zencod_rc4_cipher(&output, &input, (const zen_nb_t *)&rc4key,
                              &(tmp_rc4_key->rc4_state[0]),
                              &(tmp_rc4_key->rc4_state[3]),
                              !tmp_rc4_key->first);
    to_return = !to_return;

    /* Update encryption state ... */
    tmp_rc4_key->first = 1;
    tmp_rc4_key = NULL;

    return to_return;
}

static int engine_des_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
                               const unsigned char *iv, int enc)
{

    ZEN_DES_KEY *tmp_des_key = NULL;
    int to_return = 0;

    tmp_des_key = (ZEN_DES_KEY *) (ctx->cipher_data);
    memcpy(&(tmp_des_key->des_key[0]), key, 8);
    memcpy(&(tmp_des_key->des_key[8]), key, 8);
    memcpy(&(tmp_des_key->des_key[16]), key, 8);
    memcpy(&(tmp_des_key->des_iv[0]), iv, 8);

    to_return = 1;

    return to_return;
}

static int engine_des_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
                                 const unsigned char *in, unsigned int inl)
{

    zen_nb_t output, input;
    zen_nb_t deskey_1, deskey_2, deskey_3, iv;
    int to_return = 0;

    /* Convert parameters ... */
    input.len = inl;
    input.data = (unsigned char *)in;
    output.len = inl;
    output.data = out;

    /* Set key parameters ... */
    deskey_1.len = 8;
    deskey_2.len = 8;
    deskey_3.len = 8;
    deskey_1.data =
        (unsigned char *)((ZEN_DES_KEY *) (ctx->cipher_data))->des_key;
    deskey_2.data =
        (unsigned char *)&((ZEN_DES_KEY *) (ctx->cipher_data))->des_key[8];
    deskey_3.data =
        (unsigned char *)&((ZEN_DES_KEY *) (ctx->cipher_data))->des_key[16];

    /* Key correct iv ... */
    memcpy(((ZEN_DES_KEY *) (ctx->cipher_data))->des_iv, ctx->iv, 8);
    iv.len = 8;
    iv.data = (unsigned char *)((ZEN_DES_KEY *) (ctx->cipher_data))->des_iv;

    if (ctx->encrypt == 0) {
        memcpy(ctx->iv, &(input.data[input.len - 8]), 8);
    }

    /* Test with zenbridge library ... */
    to_return = ptr_zencod_xdes_cipher(&output, &input,
                                       (zen_nb_t *) & deskey_1,
                                       (zen_nb_t *) & deskey_2,
                                       (zen_nb_t *) & deskey_3, &iv,
                                       ctx->encrypt);
    to_return = !to_return;

    /*
     * But we need to set up the rigth iv ... Test ENCRYPT or DECRYPT mode to
     * set iv ...
     */
    if (ctx->encrypt == 1) {
        memcpy(ctx->iv, &(output.data[output.len - 8]), 8);
    }

    return to_return;
}

static int engine_des_ede3_init_key(EVP_CIPHER_CTX *ctx,
                                    const unsigned char *key,
                                    const unsigned char *iv, int enc)
{

    ZEN_3DES_KEY *tmp_3des_key = NULL;
    int to_return = 0;

    tmp_3des_key = (ZEN_3DES_KEY *) (ctx->cipher_data);
    memcpy(&(tmp_3des_key->des3_key[0]), key, 24);
    memcpy(&(tmp_3des_key->des3_iv[0]), iv, 8);

    to_return = 1;

    return to_return;
}

static int engine_des_ede3_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
                                      const unsigned char *in,
                                      unsigned int in_len)
{

    zen_nb_t output, input;
    zen_nb_t deskey_1, deskey_2, deskey_3, iv;
    int to_return = 0;

    /* Convert parameters ... */
    input.len = in_len;
    input.data = (unsigned char *)in;
    output.len = in_len;
    output.data = out;

    /* Set key ... */
    deskey_1.len = 8;
    deskey_2.len = 8;
    deskey_3.len = 8;
    deskey_1.data =
        (unsigned char *)((ZEN_3DES_KEY *) (ctx->cipher_data))->des3_key;
    deskey_2.data =
        (unsigned char *)&((ZEN_3DES_KEY *) (ctx->cipher_data))->des3_key[8];
    deskey_3.data =
        (unsigned char *)&((ZEN_3DES_KEY *) (ctx->cipher_data))->des3_key[16];

    /* Key correct iv ... */
    memcpy(((ZEN_3DES_KEY *) (ctx->cipher_data))->des3_iv, ctx->iv, 8);
    iv.len = 8;
    iv.data = (unsigned char *)((ZEN_3DES_KEY *) (ctx->cipher_data))->des3_iv;

    if (ctx->encrypt == 0) {
        memcpy(ctx->iv, &(input.data[input.len - 8]), 8);
    }

    /* Test with zenbridge library ... */
    to_return = ptr_zencod_xdes_cipher(&output, &input,
                                       (zen_nb_t *) & deskey_1,
                                       (zen_nb_t *) & deskey_2,
                                       (zen_nb_t *) & deskey_3, &iv,
                                       ctx->encrypt);
    to_return = !to_return;

    if (ctx->encrypt == 1) {
        memcpy(ctx->iv, &(output.data[output.len - 8]), 8);
    }

    return to_return;
}

static int engine_cipher_cleanup(EVP_CIPHER_CTX *ctx)
{

    /* Set the key pointer ... */
    if (ctx->cipher->nid == NID_rc4 || ctx->cipher->nid == NID_rc4_40) {
    } else if (ctx->cipher->nid == NID_des_cbc) {
    } else if (ctx->cipher->nid == NID_des_ede3_cbc) {
    }

    return 1;
}

# endif                         /* !OPENSSL_NO_HW_ZENCOD */
#endif                          /* !OPENSSL_NO_HW */
