X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=crypto%2Fengine%2Feng_cryptodev.c;h=188e61c187c221d71296449365c3beedc74022b1;hp=49a398964b024ddd97e160dbb921ddd2f8d8753c;hb=efcad82bb81962f9e7620396ee2090035d112b32;hpb=16f8d4ebf0fd4847fa83d9c61f4150273cb4f533 diff --git a/crypto/engine/eng_cryptodev.c b/crypto/engine/eng_cryptodev.c index 49a398964b..188e61c187 100644 --- a/crypto/engine/eng_cryptodev.c +++ b/crypto/engine/eng_cryptodev.c @@ -1,7 +1,17 @@ +/* + * Copyright 2002-2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + /* * Copyright (c) 2002 Bob Beck * Copyright (c) 2002 Theo de Raadt * Copyright (c) 2002 Markus Friedl + * Copyright (c) 2012 Nikos Mavrogiannopoulos * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -27,14 +37,15 @@ */ #include -#include +#include #include #include +#include #if (defined(__unix__) || defined(unix)) && !defined(USG) && \ - (defined(OpenBSD) || defined(__FreeBSD__)) + (defined(OpenBSD) || defined(__FreeBSD__) || defined(__DragonFly__)) # include -# if (OpenBSD >= 200112) || ((__FreeBSD_version >= 470101 && __FreeBSD_version < 500000) || __FreeBSD_version >= 500041) +# if (OpenBSD >= 200112) || ((__FreeBSD_version >= 470101 && __FreeBSD_version < 500000) || __FreeBSD_version >= 500041) || defined(__DragonFly__) # define HAVE_CRYPTODEV # endif # if (OpenBSD >= 200110) @@ -42,22 +53,9 @@ # endif #endif -#ifndef HAVE_CRYPTODEV - -void ENGINE_load_cryptodev(void) -{ - /* This is a NOP on platforms without /dev/crypto */ - return; -} - -#else - -# include +#include +#ifdef HAVE_CRYPTODEV # include -# include -# include -# include -# include # include # include # include @@ -67,12 +65,26 @@ void ENGINE_load_cryptodev(void) # include # include # include +#endif +#include +#include +#include +#include + +#ifndef HAVE_CRYPTODEV + +void engine_load_cryptodev_int(void) +{ + /* This is a NOP on platforms without /dev/crypto */ + return; +} + +#else struct dev_crypto_state { struct session_op d_sess; int d_fd; # ifdef USE_CRYPTODEV_DIGESTS - char dummy_mac_key[HASH_MAX_LEN]; unsigned char digest_res[HASH_MAX_LEN]; char *mac_data; int mac_len; @@ -81,6 +93,14 @@ struct dev_crypto_state { static u_int32_t cryptodev_asymfeat = 0; +static RSA_METHOD *cryptodev_rsa; +# ifndef OPENSSL_NO_DSA +static DSA_METHOD *cryptodev_dsa = NULL; +# endif +# ifndef OPENSSL_NO_DH +static DH_METHOD *cryptodev_dh; +# endif + static int get_asym_dev_crypto(void); static int open_dev_crypto(void); static int get_dev_crypto(void); @@ -112,25 +132,29 @@ static int cryptodev_rsa_nocrt_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx); static int cryptodev_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx); -static int cryptodev_dsa_bn_mod_exp(DSA *dsa, BIGNUM *r, BIGNUM *a, +# ifndef OPENSSL_NO_DSA +static int cryptodev_dsa_bn_mod_exp(DSA *dsa, BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); -static int cryptodev_dsa_dsa_mod_exp(DSA *dsa, BIGNUM *t1, BIGNUM *g, - BIGNUM *u1, BIGNUM *pub_key, BIGNUM *u2, - BIGNUM *p, BN_CTX *ctx, - BN_MONT_CTX *mont); +static int cryptodev_dsa_dsa_mod_exp(DSA *dsa, BIGNUM *t1, const BIGNUM *g, + const BIGNUM *u1, const BIGNUM *pub_key, + const BIGNUM *u2, const BIGNUM *p, + BN_CTX *ctx, BN_MONT_CTX *mont); static DSA_SIG *cryptodev_dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa); static int cryptodev_dsa_verify(const unsigned char *dgst, int dgst_len, DSA_SIG *sig, DSA *dsa); +# endif +# ifndef OPENSSL_NO_DH static int cryptodev_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); static int cryptodev_dh_compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh); +# endif static int cryptodev_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void)); -void ENGINE_load_cryptodev(void); +void engine_load_cryptodev_int(void); static const ENGINE_CMD_DEFN cryptodev_defns[] = { {0, NULL, NULL, 0} @@ -189,8 +213,10 @@ static struct { static struct { int id; int nid; - int keylen; + int digestlen; } digests[] = { +# if 0 + /* HMAC is not supported */ { CRYPTO_MD5_HMAC, NID_hmacWithMD5, 16 }, @@ -198,21 +224,30 @@ static struct { CRYPTO_SHA1_HMAC, NID_hmacWithSHA1, 20 }, { - CRYPTO_RIPEMD160_HMAC, NID_ripemd160, 16 - /* ? */ + CRYPTO_SHA2_256_HMAC, NID_hmacWithSHA256, 32 }, { - CRYPTO_MD5_KPDK, NID_undef, 0 + CRYPTO_SHA2_384_HMAC, NID_hmacWithSHA384, 48 }, { - CRYPTO_SHA1_KPDK, NID_undef, 0 + CRYPTO_SHA2_512_HMAC, NID_hmacWithSHA512, 64 }, +# endif { CRYPTO_MD5, NID_md5, 16 }, { CRYPTO_SHA1, NID_sha1, 20 }, + { + CRYPTO_SHA2_256, NID_sha256, 32 + }, + { + CRYPTO_SHA2_384, NID_sha384, 48 + }, + { + CRYPTO_SHA2_512, NID_sha512, 64 + }, { 0, NID_undef, 0 }, @@ -288,13 +323,14 @@ static int get_cryptodev_ciphers(const int **cnids) static int nids[CRYPTO_ALGORITHM_MAX]; struct session_op sess; int fd, i, count = 0; + unsigned char fake_key[CRYPTO_CIPHER_MAX_KEY_LEN]; if ((fd = get_dev_crypto()) < 0) { *cnids = NULL; return (0); } memset(&sess, 0, sizeof(sess)); - sess.key = (caddr_t) "123456789abcdefghijklmno"; + sess.key = (void *)fake_key; for (i = 0; ciphers[i].id && count < CRYPTO_ALGORITHM_MAX; i++) { if (ciphers[i].nid == NID_undef) @@ -325,6 +361,7 @@ static int get_cryptodev_ciphers(const int **cnids) static int get_cryptodev_digests(const int **cnids) { static int nids[CRYPTO_ALGORITHM_MAX]; + unsigned char fake_key[CRYPTO_CIPHER_MAX_KEY_LEN]; struct session_op sess; int fd, i, count = 0; @@ -333,12 +370,12 @@ static int get_cryptodev_digests(const int **cnids) return (0); } memset(&sess, 0, sizeof(sess)); - sess.mackey = (caddr_t) "123456789abcdefghijklmno"; + sess.mackey = (void *)fake_key; for (i = 0; digests[i].id && count < CRYPTO_ALGORITHM_MAX; i++) { if (digests[i].nid == NID_undef) continue; sess.mac = digests[i].id; - sess.mackeylen = digests[i].keylen; + sess.mackeylen = digests[i].digestlen; sess.cipher = 0; if (ioctl(fd, CIOCGSESSION, &sess) != -1 && ioctl(fd, CIOCFSESSION, &sess.ses) != -1) @@ -358,12 +395,12 @@ static int get_cryptodev_digests(const int **cnids) * Find the useable ciphers|digests from dev/crypto - this is the first * thing called by the engine init crud which determines what it * can use for ciphers from this engine. We want to return - * only what we can do, anythine else is handled by software. + * only what we can do, anything else is handled by software. * * If we can't initialize the device to do anything useful for * any reason, we want to return a NULL array, and 0 length, * which forces everything to be done is software. By putting - * the initalization of the device in here, we ensure we can + * the initialization of the device in here, we ensure we can * use this engine as the default, and if for whatever reason * /dev/crypto won't do what we want it will just be done in * software @@ -394,7 +431,7 @@ static int cryptodev_usable_digests(const int **nids) * suck moose gonads - would be nice to be able to decide something * as reasonable default without having hackery that's card dependent. * of course, the default should probably be just do everything, - * with perhaps a sysctl to turn algoritms off (or have them off + * with perhaps a sysctl to turn algorithms off (or have them off * by default) on cards that generally suck like the hifn. */ *nids = NULL; @@ -407,7 +444,7 @@ cryptodev_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) { struct crypt_op cryp; - struct dev_crypto_state *state = ctx->cipher_data; + struct dev_crypto_state *state = EVP_CIPHER_CTX_get_cipher_data(ctx); struct session_op *sess = &state->d_sess; const void *iiv; unsigned char save_iv[EVP_MAX_IV_LENGTH]; @@ -416,7 +453,7 @@ cryptodev_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, return (0); if (!inl) return (1); - if ((inl % ctx->cipher->block_size) != 0) + if ((inl % EVP_CIPHER_CTX_block_size(ctx)) != 0) return (0); memset(&cryp, 0, sizeof(cryp)); @@ -424,35 +461,36 @@ cryptodev_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, cryp.ses = sess->ses; cryp.flags = 0; cryp.len = inl; - cryp.src = (caddr_t) in; - cryp.dst = (caddr_t) out; + cryp.src = (void *) in; + cryp.dst = (void *) out; cryp.mac = 0; - cryp.op = ctx->encrypt ? COP_ENCRYPT : COP_DECRYPT; + cryp.op = EVP_CIPHER_CTX_encrypting(ctx) ? COP_ENCRYPT : COP_DECRYPT; - if (ctx->cipher->iv_len) { - cryp.iv = (caddr_t) ctx->iv; - if (!ctx->encrypt) { - iiv = in + inl - ctx->cipher->iv_len; - memcpy(save_iv, iiv, ctx->cipher->iv_len); + if (EVP_CIPHER_CTX_iv_length(ctx) > 0) { + cryp.iv = (void *) EVP_CIPHER_CTX_iv(ctx); + if (!EVP_CIPHER_CTX_encrypting(ctx)) { + iiv = in + inl - EVP_CIPHER_CTX_iv_length(ctx); + memcpy(save_iv, iiv, EVP_CIPHER_CTX_iv_length(ctx)); } } else cryp.iv = NULL; if (ioctl(state->d_fd, CIOCCRYPT, &cryp) == -1) { /* - * XXX need better errror handling this can fail for a number of + * XXX need better error handling this can fail for a number of * different reasons. */ return (0); } - if (ctx->cipher->iv_len) { - if (ctx->encrypt) - iiv = out + inl - ctx->cipher->iv_len; + if (EVP_CIPHER_CTX_iv_length(ctx) > 0) { + if (EVP_CIPHER_CTX_encrypting(ctx)) + iiv = out + inl - EVP_CIPHER_CTX_iv_length(ctx); else iiv = save_iv; - memcpy(ctx->iv, iiv, ctx->cipher->iv_len); + memcpy(EVP_CIPHER_CTX_iv_noconst(ctx), iiv, + EVP_CIPHER_CTX_iv_length(ctx)); } return (1); } @@ -461,14 +499,14 @@ static int cryptodev_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc) { - struct dev_crypto_state *state = ctx->cipher_data; + struct dev_crypto_state *state = EVP_CIPHER_CTX_get_cipher_data(ctx); struct session_op *sess = &state->d_sess; int cipher = -1, i; for (i = 0; ciphers[i].id; i++) - if (ctx->cipher->nid == ciphers[i].nid && - ctx->cipher->iv_len <= ciphers[i].ivmax && - ctx->key_len == ciphers[i].keylen) { + if (EVP_CIPHER_CTX_nid(ctx) == ciphers[i].nid && + EVP_CIPHER_CTX_iv_length(ctx) <= ciphers[i].ivmax && + EVP_CIPHER_CTX_key_length(ctx) == ciphers[i].keylen) { cipher = ciphers[i].id; break; } @@ -483,8 +521,8 @@ cryptodev_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, if ((state->d_fd = get_dev_crypto()) < 0) return (0); - sess->key = (caddr_t) key; - sess->keylen = ctx->key_len; + sess->key = (void *) key; + sess->keylen = EVP_CIPHER_CTX_key_length(ctx); sess->cipher = cipher; if (ioctl(state->d_fd, CIOCGSESSION, sess) == -1) { @@ -496,20 +534,20 @@ cryptodev_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, } /* - * free anything we allocated earlier when initting a + * free anything we allocated earlier when initing a * session, and close the session. */ static int cryptodev_cleanup(EVP_CIPHER_CTX *ctx) { int ret = 0; - struct dev_crypto_state *state = ctx->cipher_data; + struct dev_crypto_state *state = EVP_CIPHER_CTX_get_cipher_data(ctx); struct session_op *sess = &state->d_sess; if (state->d_fd < 0) return (0); /* - * XXX if this ioctl fails, someting's wrong. the invoker may have called + * XXX if this ioctl fails, something's wrong. the invoker may have called * us with a bogus ctx, or we could have a device that for whatever * reason just doesn't want to play ball - it's not clear what's right * here - should this be an error? should it just increase a counter, @@ -535,151 +573,259 @@ static int cryptodev_cleanup(EVP_CIPHER_CTX *ctx) */ /* RC4 */ -const EVP_CIPHER cryptodev_rc4 = { - NID_rc4, - 1, 16, 0, - EVP_CIPH_VARIABLE_LENGTH, - cryptodev_init_key, - cryptodev_cipher, - cryptodev_cleanup, - sizeof(struct dev_crypto_state), - NULL, - NULL, - NULL -}; +static EVP_CIPHER *rc4_cipher = NULL; +static const EVP_CIPHER *cryptodev_rc4(void) +{ + if (rc4_cipher == NULL) { + EVP_CIPHER *cipher; + + if ((cipher = EVP_CIPHER_meth_new(NID_rc4, 1, 16)) == NULL + || !EVP_CIPHER_meth_set_iv_length(cipher, 0) + || !EVP_CIPHER_meth_set_flags(cipher, EVP_CIPH_VARIABLE_LENGTH) + || !EVP_CIPHER_meth_set_init(cipher, cryptodev_init_key) + || !EVP_CIPHER_meth_set_do_cipher(cipher, cryptodev_cipher) + || !EVP_CIPHER_meth_set_cleanup(cipher, cryptodev_cleanup) + || !EVP_CIPHER_meth_set_impl_ctx_size(cipher, sizeof(struct dev_crypto_state))) { + EVP_CIPHER_meth_free(cipher); + cipher = NULL; + } + rc4_cipher = cipher; + } + return rc4_cipher; +} /* DES CBC EVP */ -const EVP_CIPHER cryptodev_des_cbc = { - NID_des_cbc, - 8, 8, 8, - EVP_CIPH_CBC_MODE, - cryptodev_init_key, - cryptodev_cipher, - cryptodev_cleanup, - sizeof(struct dev_crypto_state), - EVP_CIPHER_set_asn1_iv, - EVP_CIPHER_get_asn1_iv, - NULL -}; +static EVP_CIPHER *des_cbc_cipher = NULL; +static const EVP_CIPHER *cryptodev_des_cbc(void) +{ + if (des_cbc_cipher == NULL) { + EVP_CIPHER *cipher; + + if ((cipher = EVP_CIPHER_meth_new(NID_des_cbc, 8, 8)) == NULL + || !EVP_CIPHER_meth_set_iv_length(cipher, 8) + || !EVP_CIPHER_meth_set_flags(cipher, EVP_CIPH_CBC_MODE) + || !EVP_CIPHER_meth_set_init(cipher, cryptodev_init_key) + || !EVP_CIPHER_meth_set_do_cipher(cipher, cryptodev_cipher) + || !EVP_CIPHER_meth_set_cleanup(cipher, cryptodev_cleanup) + || !EVP_CIPHER_meth_set_impl_ctx_size(cipher, sizeof(struct dev_crypto_state)) + || !EVP_CIPHER_meth_set_set_asn1_params(cipher, EVP_CIPHER_set_asn1_iv) + || !EVP_CIPHER_meth_set_get_asn1_params(cipher, EVP_CIPHER_get_asn1_iv)) { + EVP_CIPHER_meth_free(cipher); + cipher = NULL; + } + des_cbc_cipher = cipher; + } + return des_cbc_cipher; +} /* 3DES CBC EVP */ -const EVP_CIPHER cryptodev_3des_cbc = { - NID_des_ede3_cbc, - 8, 24, 8, - EVP_CIPH_CBC_MODE, - cryptodev_init_key, - cryptodev_cipher, - cryptodev_cleanup, - sizeof(struct dev_crypto_state), - EVP_CIPHER_set_asn1_iv, - EVP_CIPHER_get_asn1_iv, - NULL -}; +static EVP_CIPHER *des3_cbc_cipher = NULL; +static const EVP_CIPHER *cryptodev_3des_cbc(void) +{ + if (des3_cbc_cipher == NULL) { + EVP_CIPHER *cipher; + + if ((cipher = EVP_CIPHER_meth_new(NID_des_ede3_cbc, 8, 24)) == NULL + || !EVP_CIPHER_meth_set_iv_length(cipher, 8) + || !EVP_CIPHER_meth_set_flags(cipher, EVP_CIPH_CBC_MODE) + || !EVP_CIPHER_meth_set_init(cipher, cryptodev_init_key) + || !EVP_CIPHER_meth_set_do_cipher(cipher, cryptodev_cipher) + || !EVP_CIPHER_meth_set_cleanup(cipher, cryptodev_cleanup) + || !EVP_CIPHER_meth_set_impl_ctx_size(cipher, sizeof(struct dev_crypto_state)) + || !EVP_CIPHER_meth_set_set_asn1_params(cipher, EVP_CIPHER_set_asn1_iv) + || !EVP_CIPHER_meth_set_get_asn1_params(cipher, EVP_CIPHER_get_asn1_iv)) { + EVP_CIPHER_meth_free(cipher); + cipher = NULL; + } + des3_cbc_cipher = cipher; + } + return des3_cbc_cipher; +} -const EVP_CIPHER cryptodev_bf_cbc = { - NID_bf_cbc, - 8, 16, 8, - EVP_CIPH_CBC_MODE, - cryptodev_init_key, - cryptodev_cipher, - cryptodev_cleanup, - sizeof(struct dev_crypto_state), - EVP_CIPHER_set_asn1_iv, - EVP_CIPHER_get_asn1_iv, - NULL -}; +static EVP_CIPHER *bf_cbc_cipher = NULL; +static const EVP_CIPHER *cryptodev_bf_cbc(void) +{ + if (bf_cbc_cipher == NULL) { + EVP_CIPHER *cipher; + + if ((cipher = EVP_CIPHER_meth_new(NID_bf_cbc, 8, 16)) == NULL + || !EVP_CIPHER_meth_set_iv_length(cipher, 8) + || !EVP_CIPHER_meth_set_flags(cipher, EVP_CIPH_CBC_MODE) + || !EVP_CIPHER_meth_set_init(cipher, cryptodev_init_key) + || !EVP_CIPHER_meth_set_do_cipher(cipher, cryptodev_cipher) + || !EVP_CIPHER_meth_set_cleanup(cipher, cryptodev_cleanup) + || !EVP_CIPHER_meth_set_impl_ctx_size(cipher, sizeof(struct dev_crypto_state)) + || !EVP_CIPHER_meth_set_set_asn1_params(cipher, EVP_CIPHER_set_asn1_iv) + || !EVP_CIPHER_meth_set_get_asn1_params(cipher, EVP_CIPHER_get_asn1_iv)) { + EVP_CIPHER_meth_free(cipher); + cipher = NULL; + } + bf_cbc_cipher = cipher; + } + return bf_cbc_cipher; +} -const EVP_CIPHER cryptodev_cast_cbc = { - NID_cast5_cbc, - 8, 16, 8, - EVP_CIPH_CBC_MODE, - cryptodev_init_key, - cryptodev_cipher, - cryptodev_cleanup, - sizeof(struct dev_crypto_state), - EVP_CIPHER_set_asn1_iv, - EVP_CIPHER_get_asn1_iv, - NULL -}; +static EVP_CIPHER *cast_cbc_cipher = NULL; +static const EVP_CIPHER *cryptodev_cast_cbc(void) +{ + if (cast_cbc_cipher == NULL) { + EVP_CIPHER *cipher; + + if ((cipher = EVP_CIPHER_meth_new(NID_cast5_cbc, 8, 16)) == NULL + || !EVP_CIPHER_meth_set_iv_length(cipher, 8) + || !EVP_CIPHER_meth_set_flags(cipher, EVP_CIPH_CBC_MODE) + || !EVP_CIPHER_meth_set_init(cipher, cryptodev_init_key) + || !EVP_CIPHER_meth_set_do_cipher(cipher, cryptodev_cipher) + || !EVP_CIPHER_meth_set_cleanup(cipher, cryptodev_cleanup) + || !EVP_CIPHER_meth_set_impl_ctx_size(cipher, sizeof(struct dev_crypto_state)) + || !EVP_CIPHER_meth_set_set_asn1_params(cipher, EVP_CIPHER_set_asn1_iv) + || !EVP_CIPHER_meth_set_get_asn1_params(cipher, EVP_CIPHER_get_asn1_iv)) { + EVP_CIPHER_meth_free(cipher); + cipher = NULL; + } + cast_cbc_cipher = cipher; + } + return cast_cbc_cipher; +} -const EVP_CIPHER cryptodev_aes_cbc = { - NID_aes_128_cbc, - 16, 16, 16, - EVP_CIPH_CBC_MODE, - cryptodev_init_key, - cryptodev_cipher, - cryptodev_cleanup, - sizeof(struct dev_crypto_state), - EVP_CIPHER_set_asn1_iv, - EVP_CIPHER_get_asn1_iv, - NULL -}; +static EVP_CIPHER *aes_cbc_cipher = NULL; +static const EVP_CIPHER *cryptodev_aes_cbc(void) +{ + if (aes_cbc_cipher == NULL) { + EVP_CIPHER *cipher; + + if ((cipher = EVP_CIPHER_meth_new(NID_aes_128_cbc, 16, 16)) == NULL + || !EVP_CIPHER_meth_set_iv_length(cipher, 16) + || !EVP_CIPHER_meth_set_flags(cipher, EVP_CIPH_CBC_MODE) + || !EVP_CIPHER_meth_set_init(cipher, cryptodev_init_key) + || !EVP_CIPHER_meth_set_do_cipher(cipher, cryptodev_cipher) + || !EVP_CIPHER_meth_set_cleanup(cipher, cryptodev_cleanup) + || !EVP_CIPHER_meth_set_impl_ctx_size(cipher, sizeof(struct dev_crypto_state)) + || !EVP_CIPHER_meth_set_set_asn1_params(cipher, EVP_CIPHER_set_asn1_iv) + || !EVP_CIPHER_meth_set_get_asn1_params(cipher, EVP_CIPHER_get_asn1_iv)) { + EVP_CIPHER_meth_free(cipher); + cipher = NULL; + } + aes_cbc_cipher = cipher; + } + return aes_cbc_cipher; +} -const EVP_CIPHER cryptodev_aes_192_cbc = { - NID_aes_192_cbc, - 16, 24, 16, - EVP_CIPH_CBC_MODE, - cryptodev_init_key, - cryptodev_cipher, - cryptodev_cleanup, - sizeof(struct dev_crypto_state), - EVP_CIPHER_set_asn1_iv, - EVP_CIPHER_get_asn1_iv, - NULL -}; +static EVP_CIPHER *aes_192_cbc_cipher = NULL; +static const EVP_CIPHER *cryptodev_aes_192_cbc(void) +{ + if (aes_192_cbc_cipher == NULL) { + EVP_CIPHER *cipher; + + if ((cipher = EVP_CIPHER_meth_new(NID_aes_192_cbc, 16, 24)) == NULL + || !EVP_CIPHER_meth_set_iv_length(cipher, 16) + || !EVP_CIPHER_meth_set_flags(cipher, EVP_CIPH_CBC_MODE) + || !EVP_CIPHER_meth_set_init(cipher, cryptodev_init_key) + || !EVP_CIPHER_meth_set_do_cipher(cipher, cryptodev_cipher) + || !EVP_CIPHER_meth_set_cleanup(cipher, cryptodev_cleanup) + || !EVP_CIPHER_meth_set_impl_ctx_size(cipher, sizeof(struct dev_crypto_state)) + || !EVP_CIPHER_meth_set_set_asn1_params(cipher, EVP_CIPHER_set_asn1_iv) + || !EVP_CIPHER_meth_set_get_asn1_params(cipher, EVP_CIPHER_get_asn1_iv)) { + EVP_CIPHER_meth_free(cipher); + cipher = NULL; + } + aes_192_cbc_cipher = cipher; + } + return aes_192_cbc_cipher; +} -const EVP_CIPHER cryptodev_aes_256_cbc = { - NID_aes_256_cbc, - 16, 32, 16, - EVP_CIPH_CBC_MODE, - cryptodev_init_key, - cryptodev_cipher, - cryptodev_cleanup, - sizeof(struct dev_crypto_state), - EVP_CIPHER_set_asn1_iv, - EVP_CIPHER_get_asn1_iv, - NULL -}; +static EVP_CIPHER *aes_256_cbc_cipher = NULL; +static const EVP_CIPHER *cryptodev_aes_256_cbc(void) +{ + if (aes_256_cbc_cipher == NULL) { + EVP_CIPHER *cipher; + + if ((cipher = EVP_CIPHER_meth_new(NID_aes_256_cbc, 16, 32)) == NULL + || !EVP_CIPHER_meth_set_iv_length(cipher, 16) + || !EVP_CIPHER_meth_set_flags(cipher, EVP_CIPH_CBC_MODE) + || !EVP_CIPHER_meth_set_init(cipher, cryptodev_init_key) + || !EVP_CIPHER_meth_set_do_cipher(cipher, cryptodev_cipher) + || !EVP_CIPHER_meth_set_cleanup(cipher, cryptodev_cleanup) + || !EVP_CIPHER_meth_set_impl_ctx_size(cipher, sizeof(struct dev_crypto_state)) + || !EVP_CIPHER_meth_set_set_asn1_params(cipher, EVP_CIPHER_set_asn1_iv) + || !EVP_CIPHER_meth_set_get_asn1_params(cipher, EVP_CIPHER_get_asn1_iv)) { + EVP_CIPHER_meth_free(cipher); + cipher = NULL; + } + aes_256_cbc_cipher = cipher; + } + return aes_256_cbc_cipher; +} # ifdef CRYPTO_AES_CTR -const EVP_CIPHER cryptodev_aes_ctr = { - NID_aes_128_ctr, - 16, 16, 14, - EVP_CIPH_CTR_MODE, - cryptodev_init_key, - cryptodev_cipher, - cryptodev_cleanup, - sizeof(struct dev_crypto_state), - EVP_CIPHER_set_asn1_iv, - EVP_CIPHER_get_asn1_iv, - NULL -}; +static EVP_CIPHER *aes_ctr_cipher = NULL; +static const EVP_CIPHER *cryptodev_aes_ctr(void) +{ + if (aes_ctr_cipher == NULL) { + EVP_CIPHER *cipher; + + if ((cipher = EVP_CIPHER_meth_new(NID_aes_128_ctr, 16, 16)) == NULL + || !EVP_CIPHER_meth_set_iv_length(cipher, 14) + || !EVP_CIPHER_meth_set_flags(cipher, EVP_CIPH_CTR_MODE) + || !EVP_CIPHER_meth_set_init(cipher, cryptodev_init_key) + || !EVP_CIPHER_meth_set_do_cipher(cipher, cryptodev_cipher) + || !EVP_CIPHER_meth_set_cleanup(cipher, cryptodev_cleanup) + || !EVP_CIPHER_meth_set_impl_ctx_size(cipher, sizeof(struct dev_crypto_state)) + || !EVP_CIPHER_meth_set_set_asn1_params(cipher, EVP_CIPHER_set_asn1_iv) + || !EVP_CIPHER_meth_set_get_asn1_params(cipher, EVP_CIPHER_get_asn1_iv)) { + EVP_CIPHER_meth_free(cipher); + cipher = NULL; + } + aes_ctr_cipher = cipher; + } + return aes_ctr_cipher; +} -const EVP_CIPHER cryptodev_aes_ctr_192 = { - NID_aes_192_ctr, - 16, 24, 14, - EVP_CIPH_CTR_MODE, - cryptodev_init_key, - cryptodev_cipher, - cryptodev_cleanup, - sizeof(struct dev_crypto_state), - EVP_CIPHER_set_asn1_iv, - EVP_CIPHER_get_asn1_iv, - NULL -}; +static EVP_CIPHER *aes_192_ctr_cipher = NULL; +static const EVP_CIPHER *cryptodev_aes_192_ctr(void) +{ + if (aes_192_ctr_cipher == NULL) { + EVP_CIPHER *cipher; + + if ((cipher = EVP_CIPHER_meth_new(NID_aes_192_ctr, 16, 24)) == NULL + || !EVP_CIPHER_meth_set_iv_length(cipher, 14) + || !EVP_CIPHER_meth_set_flags(cipher, EVP_CIPH_CTR_MODE) + || !EVP_CIPHER_meth_set_init(cipher, cryptodev_init_key) + || !EVP_CIPHER_meth_set_do_cipher(cipher, cryptodev_cipher) + || !EVP_CIPHER_meth_set_cleanup(cipher, cryptodev_cleanup) + || !EVP_CIPHER_meth_set_impl_ctx_size(cipher, sizeof(struct dev_crypto_state)) + || !EVP_CIPHER_meth_set_set_asn1_params(cipher, EVP_CIPHER_set_asn1_iv) + || !EVP_CIPHER_meth_set_get_asn1_params(cipher, EVP_CIPHER_get_asn1_iv)) { + EVP_CIPHER_meth_free(cipher); + cipher = NULL; + } + aes_192_ctr_cipher = cipher; + } + return aes_192_ctr_cipher; +} -const EVP_CIPHER cryptodev_aes_ctr_256 = { - NID_aes_256_ctr, - 16, 32, 14, - EVP_CIPH_CTR_MODE, - cryptodev_init_key, - cryptodev_cipher, - cryptodev_cleanup, - sizeof(struct dev_crypto_state), - EVP_CIPHER_set_asn1_iv, - EVP_CIPHER_get_asn1_iv, - NULL -}; +static EVP_CIPHER *aes_256_ctr_cipher = NULL; +static const EVP_CIPHER *cryptodev_aes_256_ctr(void) +{ + if (aes_256_ctr_cipher == NULL) { + EVP_CIPHER *cipher; + + if ((cipher = EVP_CIPHER_meth_new(NID_aes_256_ctr, 16, 32)) == NULL + || !EVP_CIPHER_meth_set_iv_length(cipher, 14) + || !EVP_CIPHER_meth_set_flags(cipher, EVP_CIPH_CTR_MODE) + || !EVP_CIPHER_meth_set_init(cipher, cryptodev_init_key) + || !EVP_CIPHER_meth_set_do_cipher(cipher, cryptodev_cipher) + || !EVP_CIPHER_meth_set_cleanup(cipher, cryptodev_cleanup) + || !EVP_CIPHER_meth_set_impl_ctx_size(cipher, sizeof(struct dev_crypto_state)) + || !EVP_CIPHER_meth_set_set_asn1_params(cipher, EVP_CIPHER_set_asn1_iv) + || !EVP_CIPHER_meth_set_get_asn1_params(cipher, EVP_CIPHER_get_asn1_iv)) { + EVP_CIPHER_meth_free(cipher); + cipher = NULL; + } + aes_256_ctr_cipher = cipher; + } + return aes_256_ctr_cipher; +} # endif /* * Registered by the ENGINE when used to find out how to deal with @@ -695,38 +841,38 @@ cryptodev_engine_ciphers(ENGINE *e, const EVP_CIPHER **cipher, switch (nid) { case NID_rc4: - *cipher = &cryptodev_rc4; + *cipher = cryptodev_rc4(); break; case NID_des_ede3_cbc: - *cipher = &cryptodev_3des_cbc; + *cipher = cryptodev_3des_cbc(); break; case NID_des_cbc: - *cipher = &cryptodev_des_cbc; + *cipher = cryptodev_des_cbc(); break; case NID_bf_cbc: - *cipher = &cryptodev_bf_cbc; + *cipher = cryptodev_bf_cbc(); break; case NID_cast5_cbc: - *cipher = &cryptodev_cast_cbc; + *cipher = cryptodev_cast_cbc(); break; case NID_aes_128_cbc: - *cipher = &cryptodev_aes_cbc; + *cipher = cryptodev_aes_cbc(); break; case NID_aes_192_cbc: - *cipher = &cryptodev_aes_192_cbc; + *cipher = cryptodev_aes_192_cbc(); break; case NID_aes_256_cbc: - *cipher = &cryptodev_aes_256_cbc; + *cipher = cryptodev_aes_256_cbc(); break; # ifdef CRYPTO_AES_CTR case NID_aes_128_ctr: - *cipher = &cryptodev_aes_ctr; + *cipher = cryptodev_aes_ctr(); break; case NID_aes_192_ctr: - *cipher = &cryptodev_aes_ctr_192; + *cipher = cryptodev_aes_192_ctr(); break; case NID_aes_256_ctr: - *cipher = &cryptodev_aes_ctr_256; + *cipher = cryptodev_aes_256_ctr(); break; # endif default: @@ -749,23 +895,13 @@ static int digest_nid_to_cryptodev(int nid) return (0); } -static int digest_key_length(int nid) -{ - int i; - - for (i = 0; digests[i].id; i++) - if (digests[i].nid == nid) - return digests[i].keylen; - return (0); -} - static int cryptodev_digest_init(EVP_MD_CTX *ctx) { - struct dev_crypto_state *state = ctx->md_data; + struct dev_crypto_state *state = EVP_MD_CTX_md_data(ctx); struct session_op *sess = &state->d_sess; int digest; - if ((digest = digest_nid_to_cryptodev(ctx->digest->type)) == NID_undef) { + if ((digest = digest_nid_to_cryptodev(EVP_MD_CTX_type(ctx))) == NID_undef) { printf("cryptodev_digest_init: Can't get digest \n"); return (0); } @@ -777,8 +913,8 @@ static int cryptodev_digest_init(EVP_MD_CTX *ctx) return (0); } - sess->mackey = state->dummy_mac_key; - sess->mackeylen = digest_key_length(ctx->digest->type); + sess->mackey = NULL; + sess->mackeylen = 0; sess->mac = digest; if (ioctl(state->d_fd, CIOCGSESSION, sess) < 0) { @@ -795,7 +931,7 @@ static int cryptodev_digest_update(EVP_MD_CTX *ctx, const void *data, size_t count) { struct crypt_op cryp; - struct dev_crypto_state *state = ctx->md_data; + struct dev_crypto_state *state = EVP_MD_CTX_md_data(ctx); struct session_op *sess = &state->d_sess; char *new_mac_data; @@ -808,7 +944,7 @@ static int cryptodev_digest_update(EVP_MD_CTX *ctx, const void *data, return (0); } - if (!(ctx->flags & EVP_MD_CTX_FLAG_ONESHOT)) { + if (!EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_ONESHOT)) { /* if application doesn't support one buffer */ new_mac_data = OPENSSL_realloc(state->mac_data, state->mac_len + count); @@ -830,9 +966,9 @@ static int cryptodev_digest_update(EVP_MD_CTX *ctx, const void *data, cryp.ses = sess->ses; cryp.flags = 0; cryp.len = count; - cryp.src = (caddr_t) data; + cryp.src = (void *) data; cryp.dst = NULL; - cryp.mac = (caddr_t) state->digest_res; + cryp.mac = (void *) state->digest_res; if (ioctl(state->d_fd, CIOCCRYPT, &cryp) < 0) { printf("cryptodev_digest_update: digest failed\n"); return (0); @@ -843,7 +979,7 @@ static int cryptodev_digest_update(EVP_MD_CTX *ctx, const void *data, static int cryptodev_digest_final(EVP_MD_CTX *ctx, unsigned char *md) { struct crypt_op cryp; - struct dev_crypto_state *state = ctx->md_data; + struct dev_crypto_state *state = EVP_MD_CTX_md_data(ctx); struct session_op *sess = &state->d_sess; int ret = 1; @@ -853,7 +989,7 @@ static int cryptodev_digest_final(EVP_MD_CTX *ctx, unsigned char *md) return (0); } - if (!(ctx->flags & EVP_MD_CTX_FLAG_ONESHOT)) { + if (!EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_ONESHOT)) { /* if application doesn't support one buffer */ memset(&cryp, 0, sizeof(cryp)); cryp.ses = sess->ses; @@ -861,7 +997,7 @@ static int cryptodev_digest_final(EVP_MD_CTX *ctx, unsigned char *md) cryp.len = state->mac_len; cryp.src = state->mac_data; cryp.dst = NULL; - cryp.mac = (caddr_t) md; + cryp.mac = (void *) md; if (ioctl(state->d_fd, CIOCCRYPT, &cryp) < 0) { printf("cryptodev_digest_final: digest failed\n"); return (0); @@ -870,7 +1006,7 @@ static int cryptodev_digest_final(EVP_MD_CTX *ctx, unsigned char *md) return 1; } - memcpy(md, state->digest_res, ctx->digest->md_size); + memcpy(md, state->digest_res, EVP_MD_CTX_size(ctx)); return (ret); } @@ -878,7 +1014,7 @@ static int cryptodev_digest_final(EVP_MD_CTX *ctx, unsigned char *md) static int cryptodev_digest_cleanup(EVP_MD_CTX *ctx) { int ret = 1; - struct dev_crypto_state *state = ctx->md_data; + struct dev_crypto_state *state = EVP_MD_CTX_md_data(ctx); struct session_op *sess = &state->d_sess; if (state == NULL) @@ -907,8 +1043,8 @@ static int cryptodev_digest_cleanup(EVP_MD_CTX *ctx) static int cryptodev_digest_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from) { - struct dev_crypto_state *fstate = from->md_data; - struct dev_crypto_state *dstate = to->md_data; + struct dev_crypto_state *fstate = EVP_MD_CTX_md_data(from); + struct dev_crypto_state *dstate = EVP_MD_CTX_md_data(to); struct session_op *sess; int digest; @@ -919,10 +1055,10 @@ static int cryptodev_digest_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from) sess = &dstate->d_sess; - digest = digest_nid_to_cryptodev(to->digest->type); + digest = digest_nid_to_cryptodev(EVP_MD_CTX_type(to)); - sess->mackey = dstate->dummy_mac_key; - sess->mackeylen = digest_key_length(to->digest->type); + sess->mackey = NULL; + sess->mackeylen = 0; sess->mac = digest; dstate->d_fd = get_dev_crypto(); @@ -949,35 +1085,155 @@ static int cryptodev_digest_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from) return 1; } -const EVP_MD cryptodev_sha1 = { - NID_sha1, - NID_undef, - SHA_DIGEST_LENGTH, - EVP_MD_FLAG_ONESHOT, - cryptodev_digest_init, - cryptodev_digest_update, - cryptodev_digest_final, - cryptodev_digest_copy, - cryptodev_digest_cleanup, - EVP_PKEY_NULL_method, - SHA_CBLOCK, - sizeof(struct dev_crypto_state), -}; +static EVP_MD *sha1_md = NULL; +static const EVP_MD *cryptodev_sha1(void) +{ + if (sha1_md == NULL) { + EVP_MD *md; + + if ((md = EVP_MD_meth_new(NID_sha1, NID_undef)) == NULL + || !EVP_MD_meth_set_result_size(md, SHA_DIGEST_LENGTH) + || !EVP_MD_meth_set_flags(md, EVP_MD_FLAG_ONESHOT) + || !EVP_MD_meth_set_input_blocksize(md, SHA_CBLOCK) + || !EVP_MD_meth_set_app_datasize(md, + sizeof(struct dev_crypto_state)) + || !EVP_MD_meth_set_init(md, cryptodev_digest_init) + || !EVP_MD_meth_set_update(md, cryptodev_digest_update) + || !EVP_MD_meth_set_final(md, cryptodev_digest_final) + || !EVP_MD_meth_set_copy(md, cryptodev_digest_copy) + || !EVP_MD_meth_set_cleanup(md, cryptodev_digest_cleanup)) { + EVP_MD_meth_free(md); + md = NULL; + } + sha1_md = md; + } + return sha1_md; +} -const EVP_MD cryptodev_md5 = { - NID_md5, - NID_undef, - 16 /* MD5_DIGEST_LENGTH */ , - EVP_MD_FLAG_ONESHOT, - cryptodev_digest_init, - cryptodev_digest_update, - cryptodev_digest_final, - cryptodev_digest_copy, - cryptodev_digest_cleanup, - EVP_PKEY_NULL_method, - 64 /* MD5_CBLOCK */ , - sizeof(struct dev_crypto_state), -}; +static EVP_MD *sha256_md = NULL; +static const EVP_MD *cryptodev_sha256(void) +{ + if (sha256_md == NULL) { + EVP_MD *md; + + if ((md = EVP_MD_meth_new(NID_sha256, NID_undef)) == NULL + || !EVP_MD_meth_set_result_size(md, SHA_DIGEST_LENGTH) + || !EVP_MD_meth_set_flags(md, EVP_MD_FLAG_ONESHOT) + || !EVP_MD_meth_set_input_blocksize(md, SHA_CBLOCK) + || !EVP_MD_meth_set_app_datasize(md, + sizeof(struct dev_crypto_state)) + || !EVP_MD_meth_set_init(md, cryptodev_digest_init) + || !EVP_MD_meth_set_update(md, cryptodev_digest_update) + || !EVP_MD_meth_set_final(md, cryptodev_digest_final) + || !EVP_MD_meth_set_copy(md, cryptodev_digest_copy) + || !EVP_MD_meth_set_cleanup(md, cryptodev_digest_cleanup)) { + EVP_MD_meth_free(md); + md = NULL; + } + sha256_md = md; + } + return sha256_md; +} + +static EVP_MD *sha224_md = NULL; +static const EVP_MD *cryptodev_sha224(void) +{ + if (sha224_md == NULL) { + EVP_MD *md; + + if ((md = EVP_MD_meth_new(NID_sha224, NID_undef)) == NULL + || !EVP_MD_meth_set_result_size(md, SHA_DIGEST_LENGTH) + || !EVP_MD_meth_set_flags(md, EVP_MD_FLAG_ONESHOT) + || !EVP_MD_meth_set_input_blocksize(md, SHA_CBLOCK) + || !EVP_MD_meth_set_app_datasize(md, + sizeof(struct dev_crypto_state)) + || !EVP_MD_meth_set_init(md, cryptodev_digest_init) + || !EVP_MD_meth_set_update(md, cryptodev_digest_update) + || !EVP_MD_meth_set_final(md, cryptodev_digest_final) + || !EVP_MD_meth_set_copy(md, cryptodev_digest_copy) + || !EVP_MD_meth_set_cleanup(md, cryptodev_digest_cleanup)) { + EVP_MD_meth_free(md); + md = NULL; + } + sha224_md = md; + } + return sha224_md; +} + +static EVP_MD *sha384_md = NULL; +static const EVP_MD *cryptodev_sha384(void) +{ + if (sha384_md == NULL) { + EVP_MD *md; + + if ((md = EVP_MD_meth_new(NID_sha384, NID_undef)) == NULL + || !EVP_MD_meth_set_result_size(md, SHA_DIGEST_LENGTH) + || !EVP_MD_meth_set_flags(md, EVP_MD_FLAG_ONESHOT) + || !EVP_MD_meth_set_input_blocksize(md, SHA_CBLOCK) + || !EVP_MD_meth_set_app_datasize(md, + sizeof(struct dev_crypto_state)) + || !EVP_MD_meth_set_init(md, cryptodev_digest_init) + || !EVP_MD_meth_set_update(md, cryptodev_digest_update) + || !EVP_MD_meth_set_final(md, cryptodev_digest_final) + || !EVP_MD_meth_set_copy(md, cryptodev_digest_copy) + || !EVP_MD_meth_set_cleanup(md, cryptodev_digest_cleanup)) { + EVP_MD_meth_free(md); + md = NULL; + } + sha384_md = md; + } + return sha384_md; +} + +static EVP_MD *sha512_md = NULL; +static const EVP_MD *cryptodev_sha512(void) +{ + if (sha512_md == NULL) { + EVP_MD *md; + + if ((md = EVP_MD_meth_new(NID_sha512, NID_undef)) == NULL + || !EVP_MD_meth_set_result_size(md, SHA_DIGEST_LENGTH) + || !EVP_MD_meth_set_flags(md, EVP_MD_FLAG_ONESHOT) + || !EVP_MD_meth_set_input_blocksize(md, SHA_CBLOCK) + || !EVP_MD_meth_set_app_datasize(md, + sizeof(struct dev_crypto_state)) + || !EVP_MD_meth_set_init(md, cryptodev_digest_init) + || !EVP_MD_meth_set_update(md, cryptodev_digest_update) + || !EVP_MD_meth_set_final(md, cryptodev_digest_final) + || !EVP_MD_meth_set_copy(md, cryptodev_digest_copy) + || !EVP_MD_meth_set_cleanup(md, cryptodev_digest_cleanup)) { + EVP_MD_meth_free(md); + md = NULL; + } + sha512_md = md; + } + return sha512_md; +} + +static EVP_MD *md5_md = NULL; +static const EVP_MD *cryptodev_md5(void) +{ + if (md5_md == NULL) { + EVP_MD *md; + + if ((md = EVP_MD_meth_new(NID_md5, NID_undef)) == NULL + || !EVP_MD_meth_set_result_size(md, 16 /* MD5_DIGEST_LENGTH */) + || !EVP_MD_meth_set_flags(md, EVP_MD_FLAG_ONESHOT) + || !EVP_MD_meth_set_input_blocksize(md, 64 /* MD5_CBLOCK */) + || !EVP_MD_meth_set_app_datasize(md, + sizeof(struct dev_crypto_state)) + || !EVP_MD_meth_set_init(md, cryptodev_digest_init) + || !EVP_MD_meth_set_update(md, cryptodev_digest_update) + || !EVP_MD_meth_set_final(md, cryptodev_digest_final) + || !EVP_MD_meth_set_copy(md, cryptodev_digest_copy) + || !EVP_MD_meth_set_cleanup(md, cryptodev_digest_cleanup)) { + EVP_MD_meth_free(md); + md = NULL; + } + md5_md = md; + } + return md5_md; +} # endif /* USE_CRYPTODEV_DIGESTS */ @@ -991,10 +1247,22 @@ cryptodev_engine_digests(ENGINE *e, const EVP_MD **digest, switch (nid) { # ifdef USE_CRYPTODEV_DIGESTS case NID_md5: - *digest = &cryptodev_md5; + *digest = cryptodev_md5(); break; case NID_sha1: - *digest = &cryptodev_sha1; + *digest = cryptodev_sha1(); + break; + case NID_sha256: + *digest = cryptodev_sha256(); + break; + case NID_sha224: + *digest = cryptodev_sha224(); + break; + case NID_sha384: + *digest = cryptodev_sha384(); + break; + case NID_sha512: + *digest = cryptodev_sha512(); break; default: # endif /* USE_CRYPTODEV_DIGESTS */ @@ -1004,6 +1272,59 @@ cryptodev_engine_digests(ENGINE *e, const EVP_MD **digest, return (*digest != NULL); } +static int cryptodev_engine_destroy(ENGINE *e) +{ + EVP_CIPHER_meth_free(rc4_cipher); + rc4_cipher = NULL; + EVP_CIPHER_meth_free(des_cbc_cipher); + des_cbc_cipher = NULL; + EVP_CIPHER_meth_free(des3_cbc_cipher); + des3_cbc_cipher = NULL; + EVP_CIPHER_meth_free(bf_cbc_cipher); + bf_cbc_cipher = NULL; + EVP_CIPHER_meth_free(cast_cbc_cipher); + cast_cbc_cipher = NULL; + EVP_CIPHER_meth_free(aes_cbc_cipher); + aes_cbc_cipher = NULL; + EVP_CIPHER_meth_free(aes_192_cbc_cipher); + aes_192_cbc_cipher = NULL; + EVP_CIPHER_meth_free(aes_256_cbc_cipher); + aes_256_cbc_cipher = NULL; +# ifdef CRYPTO_AES_CTR + EVP_CIPHER_meth_free(aes_ctr_cipher); + aes_ctr_cipher = NULL; + EVP_CIPHER_meth_free(aes_192_ctr_cipher); + aes_192_ctr_cipher = NULL; + EVP_CIPHER_meth_free(aes_256_ctr_cipher); + aes_256_ctr_cipher = NULL; +# endif +# ifdef USE_CRYPTODEV_DIGESTS + EVP_MD_meth_free(sha1_md); + sha1_md = NULL; + EVP_MD_meth_free(sha256_md); + sha256_md = NULL; + EVP_MD_meth_free(sha224_md); + sha224_md = NULL; + EVP_MD_meth_free(sha384_md); + sha384_md = NULL; + EVP_MD_meth_free(sha512_md); + sha512_md = NULL; + EVP_MD_meth_free(md5_md); + md5_md = NULL; +# endif + RSA_meth_free(cryptodev_rsa); + cryptodev_rsa = NULL; +# ifndef OPENSSL_NO_DSA + DSA_meth_free(cryptodev_dsa); + cryptodev_dsa = NULL; +# endif +# ifndef OPENSSL_NO_DH + DH_meth_free(cryptodev_dh); + cryptodev_dh = NULL; +# endif + return 1; +} + /* * Convert a BIGNUM to the representation that /dev/crypto needs. * Upon completion of use, the caller is responsible for freeing @@ -1020,12 +1341,11 @@ static int bn2crparam(const BIGNUM *a, struct crparam *crp) bits = BN_num_bits(a); bytes = BN_num_bytes(a); - b = OPENSSL_malloc(bytes); + b = OPENSSL_zalloc(bytes); if (b == NULL) return (1); - memset(b, 0, bytes); - crp->crp_p = (caddr_t) b; + crp->crp_p = (void *) b; crp->crp_nbits = bits; BN_bn2bin(a, b); @@ -1060,8 +1380,7 @@ static void zapparams(struct crypt_kop *kop) int i; for (i = 0; i < kop->crk_iparams + kop->crk_oparams; i++) { - if (kop->crk_param[i].crp_p) - free(kop->crk_param[i].crp_p); + OPENSSL_free(kop->crk_param[i].crp_p); kop->crk_param[i].crp_p = NULL; kop->crk_param[i].crp_nbits = 0; } @@ -1074,16 +1393,24 @@ cryptodev_asym(struct crypt_kop *kop, int rlen, BIGNUM *r, int slen, int fd, ret = -1; if ((fd = get_asym_dev_crypto()) < 0) - return (ret); + return ret; if (r) { - kop->crk_param[kop->crk_iparams].crp_p = calloc(rlen, sizeof(char)); + kop->crk_param[kop->crk_iparams].crp_p = OPENSSL_zalloc(rlen); + if (kop->crk_param[kop->crk_iparams].crp_p == NULL) + return ret; kop->crk_param[kop->crk_iparams].crp_nbits = rlen * 8; kop->crk_oparams++; } if (s) { kop->crk_param[kop->crk_iparams + 1].crp_p = - calloc(slen, sizeof(char)); + OPENSSL_zalloc(slen); + /* No need to free the kop->crk_iparams parameter if it was allocated, + * callers of this routine have to free allocated parameters through + * zapparams both in case of success and failure + */ + if (kop->crk_param[kop->crk_iparams+1].crp_p == NULL) + return ret; kop->crk_param[kop->crk_iparams + 1].crp_nbits = slen * 8; kop->crk_oparams++; } @@ -1096,7 +1423,7 @@ cryptodev_asym(struct crypt_kop *kop, int rlen, BIGNUM *r, int slen, ret = 0; } - return (ret); + return ret; } static int @@ -1128,14 +1455,14 @@ cryptodev_bn_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, kop.crk_iparams = 3; if (cryptodev_asym(&kop, BN_num_bytes(m), r, 0, NULL)) { - const RSA_METHOD *meth = RSA_PKCS1_SSLeay(); + const RSA_METHOD *meth = RSA_PKCS1_OpenSSL(); printf("OCF asym process failed, Running in software\n"); - ret = meth->bn_mod_exp(r, a, p, m, ctx, in_mont); + ret = RSA_meth_get_bn_mod_exp(meth)(r, a, p, m, ctx, in_mont); } else if (ECANCELED == kop.crk_status) { - const RSA_METHOD *meth = RSA_PKCS1_SSLeay(); + const RSA_METHOD *meth = RSA_PKCS1_OpenSSL(); printf("OCF hardware operation cancelled. Running in Software\n"); - ret = meth->bn_mod_exp(r, a, p, m, ctx, in_mont); + ret = RSA_meth_get_bn_mod_exp(meth)(r, a, p, m, ctx, in_mont); } /* else cryptodev operation worked ok ==> ret = 1 */ @@ -1149,8 +1476,12 @@ cryptodev_rsa_nocrt_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) { int r; + const BIGNUM *n = NULL; + const BIGNUM *d = NULL; + ctx = BN_CTX_new(); - r = cryptodev_bn_mod_exp(r0, I, rsa->d, rsa->n, ctx, NULL); + RSA_get0_key(rsa, &n, NULL, &d); + r = cryptodev_bn_mod_exp(r0, I, d, n, ctx, NULL); BN_CTX_free(ctx); return (r); } @@ -1160,8 +1491,18 @@ cryptodev_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) { struct crypt_kop kop; int ret = 1; - - if (!rsa->p || !rsa->q || !rsa->dmp1 || !rsa->dmq1 || !rsa->iqmp) { + const BIGNUM *p = NULL; + const BIGNUM *q = NULL; + const BIGNUM *dmp1 = NULL; + const BIGNUM *dmq1 = NULL; + const BIGNUM *iqmp = NULL; + const BIGNUM *n = NULL; + + RSA_get0_factors(rsa, &p, &q); + RSA_get0_crt_params(rsa, &dmp1, &dmq1, &iqmp); + RSA_get0_key(rsa, &n, NULL, NULL); + + if (!p || !q || !dmp1 || !dmq1 || !iqmp) { /* XXX 0 means failure?? */ return (0); } @@ -1169,29 +1510,29 @@ cryptodev_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) memset(&kop, 0, sizeof(kop)); kop.crk_op = CRK_MOD_EXP_CRT; /* inputs: rsa->p rsa->q I rsa->dmp1 rsa->dmq1 rsa->iqmp */ - if (bn2crparam(rsa->p, &kop.crk_param[0])) + if (bn2crparam(p, &kop.crk_param[0])) goto err; - if (bn2crparam(rsa->q, &kop.crk_param[1])) + if (bn2crparam(q, &kop.crk_param[1])) goto err; if (bn2crparam(I, &kop.crk_param[2])) goto err; - if (bn2crparam(rsa->dmp1, &kop.crk_param[3])) + if (bn2crparam(dmp1, &kop.crk_param[3])) goto err; - if (bn2crparam(rsa->dmq1, &kop.crk_param[4])) + if (bn2crparam(dmq1, &kop.crk_param[4])) goto err; - if (bn2crparam(rsa->iqmp, &kop.crk_param[5])) + if (bn2crparam(iqmp, &kop.crk_param[5])) goto err; kop.crk_iparams = 6; - if (cryptodev_asym(&kop, BN_num_bytes(rsa->n), r0, 0, NULL)) { - const RSA_METHOD *meth = RSA_PKCS1_SSLeay(); + if (cryptodev_asym(&kop, BN_num_bytes(n), r0, 0, NULL)) { + const RSA_METHOD *meth = RSA_PKCS1_OpenSSL(); printf("OCF asym process failed, running in Software\n"); - ret = (*meth->rsa_mod_exp) (r0, I, rsa, ctx); + ret = RSA_meth_get_mod_exp(meth)(r0, I, rsa, ctx); } else if (ECANCELED == kop.crk_status) { - const RSA_METHOD *meth = RSA_PKCS1_SSLeay(); + const RSA_METHOD *meth = RSA_PKCS1_OpenSSL(); printf("OCF hardware operation cancelled. Running in Software\n"); - ret = (*meth->rsa_mod_exp) (r0, I, rsa, ctx); + ret = RSA_meth_get_mod_exp(meth)(r0, I, rsa, ctx); } /* else cryptodev operation worked ok ==> ret = 1 */ @@ -1200,55 +1541,55 @@ cryptodev_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) return (ret); } -static RSA_METHOD cryptodev_rsa = { - "cryptodev RSA method", - NULL, /* rsa_pub_enc */ - NULL, /* rsa_pub_dec */ - NULL, /* rsa_priv_enc */ - NULL, /* rsa_priv_dec */ - NULL, - NULL, - NULL, /* init */ - NULL, /* finish */ - 0, /* flags */ - NULL, /* app_data */ - NULL, /* rsa_sign */ - NULL /* rsa_verify */ -}; - +# ifndef OPENSSL_NO_DSA static int -cryptodev_dsa_bn_mod_exp(DSA *dsa, BIGNUM *r, BIGNUM *a, const BIGNUM *p, +cryptodev_dsa_bn_mod_exp(DSA *dsa, BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx) { - return (cryptodev_bn_mod_exp(r, a, p, m, ctx, m_ctx)); + return cryptodev_bn_mod_exp(r, a, p, m, ctx, m_ctx); } static int -cryptodev_dsa_dsa_mod_exp(DSA *dsa, BIGNUM *t1, BIGNUM *g, - BIGNUM *u1, BIGNUM *pub_key, BIGNUM *u2, BIGNUM *p, - BN_CTX *ctx, BN_MONT_CTX *mont) +cryptodev_dsa_dsa_mod_exp(DSA *dsa, BIGNUM *t1, const BIGNUM *g, + const BIGNUM *u1, const BIGNUM *pub_key, + const BIGNUM *u2, const BIGNUM *p, BN_CTX *ctx, + BN_MONT_CTX *mont) { + const BIGNUM *dsag, *dsap, *dsapub_key; BIGNUM *t2; int ret = 0; + const DSA_METHOD *meth; + int (*bn_mod_exp)(DSA *, BIGNUM *, const BIGNUM *, const BIGNUM *, const BIGNUM *, + BN_CTX *, BN_MONT_CTX *); t2 = BN_new(); + if (t2 == NULL) + goto err; /* v = ( g^u1 * y^u2 mod p ) mod q */ /* let t1 = g ^ u1 mod p */ ret = 0; - if (!dsa->meth->bn_mod_exp(dsa, t1, dsa->g, u1, dsa->p, ctx, mont)) + DSA_get0_pqg(dsa, &dsap, NULL, &dsag); + DSA_get0_key(dsa, &dsapub_key, NULL); + + meth = DSA_get_method(dsa); + if (meth == NULL) + goto err; + bn_mod_exp = DSA_meth_get_bn_mod_exp(meth); + if (bn_mod_exp == NULL) + goto err; + + if (!bn_mod_exp(dsa, t1, dsag, u1, dsap, ctx, mont)) goto err; /* let t2 = y ^ u2 mod p */ - if (!dsa->meth->bn_mod_exp(dsa, t2, dsa->pub_key, u2, dsa->p, ctx, mont)) + if (!bn_mod_exp(dsa, t2, dsapub_key, u2, dsap, ctx, mont)) goto err; - /* let u1 = t1 * t2 mod p */ - if (!BN_mod_mul(u1, t1, t2, dsa->p, ctx)) + /* let t1 = t1 * t2 mod p */ + if (!BN_mod_mul(t1, t1, t2, dsap, ctx)) goto err; - BN_copy(t1, u1); - ret = 1; err: BN_free(t2); @@ -1259,47 +1600,52 @@ static DSA_SIG *cryptodev_dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa) { struct crypt_kop kop; - BIGNUM *r = NULL, *s = NULL; - DSA_SIG *dsaret = NULL; + BIGNUM *r, *s; + const BIGNUM *dsap = NULL, *dsaq = NULL, *dsag = NULL; + const BIGNUM *priv_key = NULL; + DSA_SIG *dsasig, *dsaret = NULL; - if ((r = BN_new()) == NULL) + dsasig = DSA_SIG_new(); + if (dsasig == NULL) goto err; - if ((s = BN_new()) == NULL) { - BN_free(r); - goto err; - } memset(&kop, 0, sizeof(kop)); kop.crk_op = CRK_DSA_SIGN; /* inputs: dgst dsa->p dsa->q dsa->g dsa->priv_key */ - kop.crk_param[0].crp_p = (caddr_t) dgst; + kop.crk_param[0].crp_p = (void *) dgst; kop.crk_param[0].crp_nbits = dlen * 8; - if (bn2crparam(dsa->p, &kop.crk_param[1])) + DSA_get0_pqg(dsa, &dsap, &dsaq, &dsag); + DSA_get0_key(dsa, NULL, &priv_key); + if (bn2crparam(dsap, &kop.crk_param[1])) goto err; - if (bn2crparam(dsa->q, &kop.crk_param[2])) + if (bn2crparam(dsaq, &kop.crk_param[2])) goto err; - if (bn2crparam(dsa->g, &kop.crk_param[3])) + if (bn2crparam(dsag, &kop.crk_param[3])) goto err; - if (bn2crparam(dsa->priv_key, &kop.crk_param[4])) + if (bn2crparam(priv_key, &kop.crk_param[4])) goto err; kop.crk_iparams = 5; - if (cryptodev_asym(&kop, BN_num_bytes(dsa->q), r, - BN_num_bytes(dsa->q), s) == 0) { - dsaret = DSA_SIG_new(); - dsaret->r = r; - dsaret->s = s; + r = BN_new(); + if (r == NULL) + goto err; + s = BN_new(); + if (s == NULL) + goto err; + if (cryptodev_asym(&kop, BN_num_bytes(dsaq), r, + BN_num_bytes(dsaq), s) == 0) { + DSA_SIG_set0(dsasig, r, s); + dsaret = dsasig; } else { - const DSA_METHOD *meth = DSA_OpenSSL(); - BN_free(r); - BN_free(s); - dsaret = (meth->dsa_do_sign) (dgst, dlen, dsa); + dsaret = DSA_meth_get_sign(DSA_OpenSSL())(dgst, dlen, dsa); } err: + if (dsaret != dsasig) + DSA_SIG_free(dsasig); kop.crk_param[0].crp_p = NULL; zapparams(&kop); - return (dsaret); + return dsaret; } static int @@ -1308,24 +1654,28 @@ cryptodev_dsa_verify(const unsigned char *dgst, int dlen, { struct crypt_kop kop; int dsaret = 1; + const BIGNUM *pr, *ps, *p = NULL, *q = NULL, *g = NULL, *pub_key = NULL; memset(&kop, 0, sizeof(kop)); kop.crk_op = CRK_DSA_VERIFY; /* inputs: dgst dsa->p dsa->q dsa->g dsa->pub_key sig->r sig->s */ - kop.crk_param[0].crp_p = (caddr_t) dgst; + kop.crk_param[0].crp_p = (void *) dgst; kop.crk_param[0].crp_nbits = dlen * 8; - if (bn2crparam(dsa->p, &kop.crk_param[1])) + DSA_get0_pqg(dsa, &p, &q, &g); + if (bn2crparam(p, &kop.crk_param[1])) goto err; - if (bn2crparam(dsa->q, &kop.crk_param[2])) + if (bn2crparam(q, &kop.crk_param[2])) goto err; - if (bn2crparam(dsa->g, &kop.crk_param[3])) + if (bn2crparam(g, &kop.crk_param[3])) goto err; - if (bn2crparam(dsa->pub_key, &kop.crk_param[4])) + DSA_get0_key(dsa, &pub_key, NULL); + if (bn2crparam(pub_key, &kop.crk_param[4])) goto err; - if (bn2crparam(sig->r, &kop.crk_param[5])) + DSA_SIG_get0(sig, &pr, &ps); + if (bn2crparam(pr, &kop.crk_param[5])) goto err; - if (bn2crparam(sig->s, &kop.crk_param[6])) + if (bn2crparam(ps, &kop.crk_param[6])) goto err; kop.crk_iparams = 7; @@ -1336,29 +1686,16 @@ cryptodev_dsa_verify(const unsigned char *dgst, int dlen, if (0 != kop.crk_status) dsaret = 0; } else { - const DSA_METHOD *meth = DSA_OpenSSL(); - - dsaret = (meth->dsa_do_verify) (dgst, dlen, sig, dsa); + dsaret = DSA_meth_get_verify(DSA_OpenSSL())(dgst, dlen, sig, dsa); } err: kop.crk_param[0].crp_p = NULL; zapparams(&kop); return (dsaret); } +# endif -static DSA_METHOD cryptodev_dsa = { - "cryptodev DSA method", - NULL, - NULL, /* dsa_sign_setup */ - NULL, - NULL, /* dsa_mod_exp */ - NULL, - NULL, /* init */ - NULL, /* finish */ - 0, /* flags */ - NULL /* app_data */ -}; - +# ifndef OPENSSL_NO_DH static int cryptodev_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, @@ -1373,35 +1710,40 @@ cryptodev_dh_compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh) struct crypt_kop kop; int dhret = 1; int fd, keylen; + const BIGNUM *p = NULL; + const BIGNUM *priv_key = NULL; if ((fd = get_asym_dev_crypto()) < 0) { const DH_METHOD *meth = DH_OpenSSL(); - return ((meth->compute_key) (key, pub_key, dh)); + return DH_meth_get_compute_key(meth)(key, pub_key, dh); } - keylen = BN_num_bits(dh->p); + DH_get0_pqg(dh, &p, NULL, NULL); + DH_get0_key(dh, NULL, &priv_key); + + keylen = BN_num_bits(p); memset(&kop, 0, sizeof(kop)); kop.crk_op = CRK_DH_COMPUTE_KEY; /* inputs: dh->priv_key pub_key dh->p key */ - if (bn2crparam(dh->priv_key, &kop.crk_param[0])) + if (bn2crparam(priv_key, &kop.crk_param[0])) goto err; if (bn2crparam(pub_key, &kop.crk_param[1])) goto err; - if (bn2crparam(dh->p, &kop.crk_param[2])) + if (bn2crparam(p, &kop.crk_param[2])) goto err; kop.crk_iparams = 3; - kop.crk_param[3].crp_p = (caddr_t) key; + kop.crk_param[3].crp_p = (void *) key; kop.crk_param[3].crp_nbits = keylen * 8; kop.crk_oparams = 1; if (ioctl(fd, CIOCKEY, &kop) == -1) { const DH_METHOD *meth = DH_OpenSSL(); - dhret = (meth->compute_key) (key, pub_key, dh); + dhret = DH_meth_get_compute_key(meth)(key, pub_key, dh); } err: kop.crk_param[3].crp_p = NULL; @@ -1409,16 +1751,7 @@ cryptodev_dh_compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh) return (dhret); } -static DH_METHOD cryptodev_dh = { - "cryptodev DH method", - NULL, /* cryptodev_dh_generate_key */ - NULL, - NULL, - NULL, - NULL, - 0, /* flags */ - NULL /* app_data */ -}; +# endif /* ndef OPENSSL_NO_DH */ /* * ctrl right now is just a wrapper that doesn't do much @@ -1443,7 +1776,7 @@ cryptodev_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void)) return (1); } -void ENGINE_load_cryptodev(void) +void engine_load_cryptodev_int(void) { ENGINE *engine = ENGINE_new(); int fd; @@ -1466,7 +1799,8 @@ void ENGINE_load_cryptodev(void) put_dev_crypto(fd); if (!ENGINE_set_id(engine, "cryptodev") || - !ENGINE_set_name(engine, "BSD cryptodev engine") || + !ENGINE_set_name(engine, "cryptodev engine") || + !ENGINE_set_destroy_function(engine, cryptodev_engine_destroy) || !ENGINE_set_ciphers(engine, cryptodev_engine_ciphers) || !ENGINE_set_digests(engine, cryptodev_engine_digests) || !ENGINE_set_ctrl_function(engine, cryptodev_ctrl) || @@ -1475,50 +1809,65 @@ void ENGINE_load_cryptodev(void) return; } - if (ENGINE_set_RSA(engine, &cryptodev_rsa)) { - const RSA_METHOD *rsa_meth = RSA_PKCS1_SSLeay(); - - cryptodev_rsa.bn_mod_exp = rsa_meth->bn_mod_exp; - cryptodev_rsa.rsa_mod_exp = rsa_meth->rsa_mod_exp; - cryptodev_rsa.rsa_pub_enc = rsa_meth->rsa_pub_enc; - cryptodev_rsa.rsa_pub_dec = rsa_meth->rsa_pub_dec; - cryptodev_rsa.rsa_priv_enc = rsa_meth->rsa_priv_enc; - cryptodev_rsa.rsa_priv_dec = rsa_meth->rsa_priv_dec; - if (cryptodev_asymfeat & CRF_MOD_EXP) { - cryptodev_rsa.bn_mod_exp = cryptodev_bn_mod_exp; - if (cryptodev_asymfeat & CRF_MOD_EXP_CRT) - cryptodev_rsa.rsa_mod_exp = cryptodev_rsa_mod_exp; - else - cryptodev_rsa.rsa_mod_exp = cryptodev_rsa_nocrt_mod_exp; + cryptodev_rsa = RSA_meth_dup(RSA_PKCS1_OpenSSL()); + if (cryptodev_rsa != NULL) { + RSA_meth_set1_name(cryptodev_rsa, "cryptodev RSA method"); + RSA_meth_set_flags(cryptodev_rsa, 0); + if (ENGINE_set_RSA(engine, cryptodev_rsa)) { + if (cryptodev_asymfeat & CRF_MOD_EXP) { + RSA_meth_set_bn_mod_exp(cryptodev_rsa, cryptodev_bn_mod_exp); + if (cryptodev_asymfeat & CRF_MOD_EXP_CRT) + RSA_meth_set_mod_exp(cryptodev_rsa, cryptodev_rsa_mod_exp); + else + RSA_meth_set_mod_exp(cryptodev_rsa, + cryptodev_rsa_nocrt_mod_exp); + } } + } else { + ENGINE_free(engine); + return; } - if (ENGINE_set_DSA(engine, &cryptodev_dsa)) { - const DSA_METHOD *meth = DSA_OpenSSL(); - - memcpy(&cryptodev_dsa, meth, sizeof(DSA_METHOD)); - if (cryptodev_asymfeat & CRF_DSA_SIGN) - cryptodev_dsa.dsa_do_sign = cryptodev_dsa_do_sign; - if (cryptodev_asymfeat & CRF_MOD_EXP) { - cryptodev_dsa.bn_mod_exp = cryptodev_dsa_bn_mod_exp; - cryptodev_dsa.dsa_mod_exp = cryptodev_dsa_dsa_mod_exp; +# ifndef OPENSSL_NO_DSA + cryptodev_dsa = DSA_meth_dup(DSA_OpenSSL()); + if (cryptodev_dsa != NULL) { + DSA_meth_set1_name(cryptodev_dsa, "cryptodev DSA method"); + DSA_meth_set_flags(cryptodev_dsa, 0); + if (ENGINE_set_DSA(engine, cryptodev_dsa)) { + if (cryptodev_asymfeat & CRF_DSA_SIGN) + DSA_meth_set_sign(cryptodev_dsa, cryptodev_dsa_do_sign); + if (cryptodev_asymfeat & CRF_MOD_EXP) { + DSA_meth_set_bn_mod_exp(cryptodev_dsa, + cryptodev_dsa_bn_mod_exp); + DSA_meth_set_mod_exp(cryptodev_dsa, cryptodev_dsa_dsa_mod_exp); + } + if (cryptodev_asymfeat & CRF_DSA_VERIFY) + DSA_meth_set_verify(cryptodev_dsa, cryptodev_dsa_verify); } - if (cryptodev_asymfeat & CRF_DSA_VERIFY) - cryptodev_dsa.dsa_do_verify = cryptodev_dsa_verify; + } else { + ENGINE_free(engine); + return; } +# endif - if (ENGINE_set_DH(engine, &cryptodev_dh)) { - const DH_METHOD *dh_meth = DH_OpenSSL(); - - cryptodev_dh.generate_key = dh_meth->generate_key; - cryptodev_dh.compute_key = dh_meth->compute_key; - cryptodev_dh.bn_mod_exp = dh_meth->bn_mod_exp; - if (cryptodev_asymfeat & CRF_MOD_EXP) { - cryptodev_dh.bn_mod_exp = cryptodev_mod_exp_dh; - if (cryptodev_asymfeat & CRF_DH_COMPUTE_KEY) - cryptodev_dh.compute_key = cryptodev_dh_compute_key; +# ifndef OPENSSL_NO_DH + cryptodev_dh = DH_meth_dup(DH_OpenSSL()); + if (cryptodev_dh != NULL) { + DH_meth_set1_name(cryptodev_dh, "cryptodev DH method"); + DH_meth_set_flags(cryptodev_dh, 0); + if (ENGINE_set_DH(engine, cryptodev_dh)) { + if (cryptodev_asymfeat & CRF_MOD_EXP) { + DH_meth_set_bn_mod_exp(cryptodev_dh, cryptodev_mod_exp_dh); + if (cryptodev_asymfeat & CRF_DH_COMPUTE_KEY) + DH_meth_set_compute_key(cryptodev_dh, + cryptodev_dh_compute_key); + } } + } else { + ENGINE_free(engine); + return; } +# endif ENGINE_add(engine); ENGINE_free(engine);