/* 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:
    if (bn_r)
        BN_free(bn_r);
    if (bn_s)
        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_prv)
        BN_free(bn_prv);
    if (!dh->pub_key && bn_pub)
        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 */
