OpenSSL 1.1.1-pre2
This commit is contained in:
@@ -161,7 +161,7 @@ actually qualitatively different depending on 'nid' (the "des_cbc" EVP_CIPHER is
|
||||
not an interoperable implementation of "aes_256_cbc"), RSA_METHODs are
|
||||
necessarily interoperable and don't have different flavours, only different
|
||||
implementations. In other words, the ENGINE_TABLE for RSA will either be empty,
|
||||
or will have a single ENGING_PILE hashed to by the 'nid' 1 and that pile
|
||||
or will have a single ENGINE_PILE hashed to by the 'nid' 1 and that pile
|
||||
represents ENGINEs that implement the single "type" of RSA there is.
|
||||
|
||||
Cleanup - the registration and unregistration may pose questions about how
|
||||
@@ -188,7 +188,7 @@ state will be unchanged. Thus, no cleanup is required unless registration takes
|
||||
place. ENGINE_cleanup() will simply iterate across a list of registered cleanup
|
||||
callbacks calling each in turn, and will then internally delete its own storage
|
||||
(a STACK). When a cleanup callback is next registered (eg. if the cleanup() is
|
||||
part of a gracefull restart and the application wants to cleanup all state then
|
||||
part of a graceful restart and the application wants to cleanup all state then
|
||||
start again), the internal STACK storage will be freshly allocated. This is much
|
||||
the same as the situation in the ENGINE_TABLE instantiations ... NULL is the
|
||||
initialised state, so only modification operations (not queries) will cause that
|
||||
@@ -204,8 +204,8 @@ exists) - the idea of providing an ENGINE_cpy() function probably wasn't a good
|
||||
one and now certainly doesn't make sense in any generalised way. Some of the
|
||||
RSA, DSA, DH, and RAND functions that were fiddled during the original ENGINE
|
||||
changes have now, as a consequence, been reverted back. This is because the
|
||||
hooking of ENGINE is now automatic (and passive, it can interally use a NULL
|
||||
hooking of ENGINE is now automatic (and passive, it can internally use a NULL
|
||||
ENGINE pointer to simply ignore ENGINE from then on).
|
||||
|
||||
Hell, that should be enough for now ... comments welcome: geoff@openssl.org
|
||||
Hell, that should be enough for now ... comments welcome.
|
||||
|
||||
@@ -4,5 +4,8 @@ SOURCE[../../libcrypto]=\
|
||||
eng_table.c eng_pkey.c eng_fat.c eng_all.c \
|
||||
tb_rsa.c tb_dsa.c tb_dh.c tb_rand.c \
|
||||
tb_cipher.c tb_digest.c tb_pkmeth.c tb_asnmth.c tb_eckey.c \
|
||||
eng_openssl.c eng_cnf.c eng_dyn.c eng_cryptodev.c \
|
||||
eng_openssl.c eng_cnf.c eng_dyn.c \
|
||||
eng_rdrand.c
|
||||
IF[{- !$disabled{devcryptoeng} -}]
|
||||
SOURCE[../../libcrypto]=eng_devcrypto.c
|
||||
ENDIF
|
||||
@@ -18,14 +18,8 @@ void ENGINE_load_builtin_engines(void)
|
||||
OPENSSL_init_crypto(OPENSSL_INIT_ENGINE_ALL_BUILTIN, NULL);
|
||||
}
|
||||
|
||||
#if (defined(__OpenBSD__) || defined(__FreeBSD__) || defined(HAVE_CRYPTODEV)) && !defined(OPENSSL_NO_DEPRECATED)
|
||||
#if (defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__DragonFly__)) && !defined(OPENSSL_NO_DEPRECATED)
|
||||
void ENGINE_setup_bsd_cryptodev(void)
|
||||
{
|
||||
static int bsd_cryptodev_default_loaded = 0;
|
||||
if (!bsd_cryptodev_default_loaded) {
|
||||
OPENSSL_init_crypto(OPENSSL_INIT_ENGINE_CRYPTODEV, NULL);
|
||||
ENGINE_register_all_complete();
|
||||
}
|
||||
bsd_cryptodev_default_loaded = 1;
|
||||
}
|
||||
#endif
|
||||
@@ -1,1757 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-2018 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 <beck@openbsd.org>
|
||||
* Copyright (c) 2002 Theo de Raadt
|
||||
* Copyright (c) 2002 Markus Friedl
|
||||
* 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.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
|
||||
* EXPRESS 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 AUTHOR OR 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <openssl/objects.h>
|
||||
#include <internal/engine.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/crypto.h>
|
||||
|
||||
#if (defined(__unix__) || defined(unix)) && !defined(USG) && \
|
||||
(defined(OpenBSD) || defined(__FreeBSD__))
|
||||
# include <sys/param.h>
|
||||
# if (defined(OpenBSD) && (OpenBSD >= 200112)) || \
|
||||
(defined(__FreeBSD_version) && \
|
||||
((__FreeBSD_version >= 470101 && __FreeBSD_version < 500000) || \
|
||||
__FreeBSD_version >= 500041))
|
||||
# define HAVE_CRYPTODEV
|
||||
# endif
|
||||
# if defined(OpenBSD) && (OpenBSD >= 200110)
|
||||
# define HAVE_SYSLOG_R
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#ifdef HAVE_CRYPTODEV
|
||||
# include <crypto/cryptodev.h>
|
||||
# include <sys/ioctl.h>
|
||||
# include <errno.h>
|
||||
# include <stdio.h>
|
||||
# include <unistd.h>
|
||||
# include <fcntl.h>
|
||||
# include <stdarg.h>
|
||||
# include <syslog.h>
|
||||
# include <errno.h>
|
||||
# include <string.h>
|
||||
#endif
|
||||
#include <openssl/dh.h>
|
||||
#include <openssl/dsa.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/rsa.h>
|
||||
|
||||
#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;
|
||||
# endif
|
||||
};
|
||||
|
||||
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);
|
||||
static int get_cryptodev_ciphers(const int **cnids);
|
||||
# ifdef USE_CRYPTODEV_DIGESTS
|
||||
static int get_cryptodev_digests(const int **cnids);
|
||||
# endif
|
||||
static int cryptodev_usable_ciphers(const int **nids);
|
||||
static int cryptodev_usable_digests(const int **nids);
|
||||
static int cryptodev_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
|
||||
const unsigned char *in, size_t inl);
|
||||
static int cryptodev_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
|
||||
const unsigned char *iv, int enc);
|
||||
static int cryptodev_cleanup(EVP_CIPHER_CTX *ctx);
|
||||
static int cryptodev_engine_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
|
||||
const int **nids, int nid);
|
||||
static int cryptodev_engine_digests(ENGINE *e, const EVP_MD **digest,
|
||||
const int **nids, int nid);
|
||||
static int bn2crparam(const BIGNUM *a, struct crparam *crp);
|
||||
static int crparam2bn(struct crparam *crp, BIGNUM *a);
|
||||
static void zapparams(struct crypt_kop *kop);
|
||||
static int cryptodev_asym(struct crypt_kop *kop, int rlen, BIGNUM *r,
|
||||
int slen, BIGNUM *s);
|
||||
|
||||
static int cryptodev_bn_mod_exp(BIGNUM *r, const BIGNUM *a,
|
||||
const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
|
||||
BN_MONT_CTX *m_ctx);
|
||||
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);
|
||||
#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, 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_int(void);
|
||||
|
||||
static const ENGINE_CMD_DEFN cryptodev_defns[] = {
|
||||
{0, NULL, NULL, 0}
|
||||
};
|
||||
|
||||
static struct {
|
||||
int id;
|
||||
int nid;
|
||||
int ivmax;
|
||||
int keylen;
|
||||
} ciphers[] = {
|
||||
{
|
||||
CRYPTO_ARC4, NID_rc4, 0, 16,
|
||||
},
|
||||
{
|
||||
CRYPTO_DES_CBC, NID_des_cbc, 8, 8,
|
||||
},
|
||||
{
|
||||
CRYPTO_3DES_CBC, NID_des_ede3_cbc, 8, 24,
|
||||
},
|
||||
{
|
||||
CRYPTO_AES_CBC, NID_aes_128_cbc, 16, 16,
|
||||
},
|
||||
{
|
||||
CRYPTO_AES_CBC, NID_aes_192_cbc, 16, 24,
|
||||
},
|
||||
{
|
||||
CRYPTO_AES_CBC, NID_aes_256_cbc, 16, 32,
|
||||
},
|
||||
# ifdef CRYPTO_AES_CTR
|
||||
{
|
||||
CRYPTO_AES_CTR, NID_aes_128_ctr, 14, 16,
|
||||
},
|
||||
{
|
||||
CRYPTO_AES_CTR, NID_aes_192_ctr, 14, 24,
|
||||
},
|
||||
{
|
||||
CRYPTO_AES_CTR, NID_aes_256_ctr, 14, 32,
|
||||
},
|
||||
# endif
|
||||
{
|
||||
CRYPTO_BLF_CBC, NID_bf_cbc, 8, 16,
|
||||
},
|
||||
{
|
||||
CRYPTO_CAST_CBC, NID_cast5_cbc, 8, 16,
|
||||
},
|
||||
{
|
||||
CRYPTO_SKIPJACK_CBC, NID_undef, 0, 0,
|
||||
},
|
||||
{
|
||||
0, NID_undef, 0, 0,
|
||||
},
|
||||
};
|
||||
|
||||
# ifdef USE_CRYPTODEV_DIGESTS
|
||||
static struct {
|
||||
int id;
|
||||
int nid;
|
||||
int keylen;
|
||||
} digests[] = {
|
||||
{
|
||||
CRYPTO_MD5_HMAC, NID_hmacWithMD5, 16
|
||||
},
|
||||
{
|
||||
CRYPTO_SHA1_HMAC, NID_hmacWithSHA1, 20
|
||||
},
|
||||
{
|
||||
CRYPTO_RIPEMD160_HMAC, NID_ripemd160, 16
|
||||
/* ? */
|
||||
},
|
||||
{
|
||||
CRYPTO_MD5_KPDK, NID_undef, 0
|
||||
},
|
||||
{
|
||||
CRYPTO_SHA1_KPDK, NID_undef, 0
|
||||
},
|
||||
{
|
||||
CRYPTO_MD5, NID_md5, 16
|
||||
},
|
||||
{
|
||||
CRYPTO_SHA1, NID_sha1, 20
|
||||
},
|
||||
{
|
||||
0, NID_undef, 0
|
||||
},
|
||||
};
|
||||
# endif
|
||||
|
||||
/*
|
||||
* Return a fd if /dev/crypto seems usable, 0 otherwise.
|
||||
*/
|
||||
static int open_dev_crypto(void)
|
||||
{
|
||||
static int fd = -1;
|
||||
|
||||
if (fd == -1) {
|
||||
if ((fd = open("/dev/crypto", O_RDWR, 0)) == -1)
|
||||
return (-1);
|
||||
/* close on exec */
|
||||
if (fcntl(fd, F_SETFD, 1) == -1) {
|
||||
close(fd);
|
||||
fd = -1;
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
return (fd);
|
||||
}
|
||||
|
||||
static int get_dev_crypto(void)
|
||||
{
|
||||
int fd, retfd;
|
||||
|
||||
if ((fd = open_dev_crypto()) == -1)
|
||||
return (-1);
|
||||
# ifndef CRIOGET_NOT_NEEDED
|
||||
if (ioctl(fd, CRIOGET, &retfd) == -1)
|
||||
return (-1);
|
||||
|
||||
/* close on exec */
|
||||
if (fcntl(retfd, F_SETFD, 1) == -1) {
|
||||
close(retfd);
|
||||
return (-1);
|
||||
}
|
||||
# else
|
||||
retfd = fd;
|
||||
# endif
|
||||
return (retfd);
|
||||
}
|
||||
|
||||
static void put_dev_crypto(int fd)
|
||||
{
|
||||
# ifndef CRIOGET_NOT_NEEDED
|
||||
close(fd);
|
||||
# endif
|
||||
}
|
||||
|
||||
/* Caching version for asym operations */
|
||||
static int get_asym_dev_crypto(void)
|
||||
{
|
||||
static int fd = -1;
|
||||
|
||||
if (fd == -1)
|
||||
fd = get_dev_crypto();
|
||||
return fd;
|
||||
}
|
||||
|
||||
/*
|
||||
* Find out what ciphers /dev/crypto will let us have a session for.
|
||||
* XXX note, that some of these openssl doesn't deal with yet!
|
||||
* returning them here is harmless, as long as we return NULL
|
||||
* when asked for a handler in the cryptodev_engine_ciphers routine
|
||||
*/
|
||||
static int get_cryptodev_ciphers(const int **cnids)
|
||||
{
|
||||
static int nids[CRYPTO_ALGORITHM_MAX];
|
||||
struct session_op sess;
|
||||
int fd, i, count = 0;
|
||||
|
||||
if ((fd = get_dev_crypto()) < 0) {
|
||||
*cnids = NULL;
|
||||
return (0);
|
||||
}
|
||||
memset(&sess, 0, sizeof(sess));
|
||||
sess.key = (caddr_t) "123456789abcdefghijklmno";
|
||||
|
||||
for (i = 0; ciphers[i].id && count < CRYPTO_ALGORITHM_MAX; i++) {
|
||||
if (ciphers[i].nid == NID_undef)
|
||||
continue;
|
||||
sess.cipher = ciphers[i].id;
|
||||
sess.keylen = ciphers[i].keylen;
|
||||
sess.mac = 0;
|
||||
if (ioctl(fd, CIOCGSESSION, &sess) != -1 &&
|
||||
ioctl(fd, CIOCFSESSION, &sess.ses) != -1)
|
||||
nids[count++] = ciphers[i].nid;
|
||||
}
|
||||
put_dev_crypto(fd);
|
||||
|
||||
if (count > 0)
|
||||
*cnids = nids;
|
||||
else
|
||||
*cnids = NULL;
|
||||
return (count);
|
||||
}
|
||||
|
||||
# ifdef USE_CRYPTODEV_DIGESTS
|
||||
/*
|
||||
* Find out what digests /dev/crypto will let us have a session for.
|
||||
* XXX note, that some of these openssl doesn't deal with yet!
|
||||
* returning them here is harmless, as long as we return NULL
|
||||
* when asked for a handler in the cryptodev_engine_digests routine
|
||||
*/
|
||||
static int get_cryptodev_digests(const int **cnids)
|
||||
{
|
||||
static int nids[CRYPTO_ALGORITHM_MAX];
|
||||
struct session_op sess;
|
||||
int fd, i, count = 0;
|
||||
|
||||
if ((fd = get_dev_crypto()) < 0) {
|
||||
*cnids = NULL;
|
||||
return (0);
|
||||
}
|
||||
memset(&sess, 0, sizeof(sess));
|
||||
sess.mackey = (caddr_t) "123456789abcdefghijklmno";
|
||||
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.cipher = 0;
|
||||
if (ioctl(fd, CIOCGSESSION, &sess) != -1 &&
|
||||
ioctl(fd, CIOCFSESSION, &sess.ses) != -1)
|
||||
nids[count++] = digests[i].nid;
|
||||
}
|
||||
put_dev_crypto(fd);
|
||||
|
||||
if (count > 0)
|
||||
*cnids = nids;
|
||||
else
|
||||
*cnids = NULL;
|
||||
return (count);
|
||||
}
|
||||
# endif /* 0 */
|
||||
|
||||
/*
|
||||
* 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, 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 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
|
||||
*
|
||||
* This can (should) be greatly expanded to perhaps take into
|
||||
* account speed of the device, and what we want to do.
|
||||
* (although the disabling of particular alg's could be controlled
|
||||
* by the device driver with sysctl's.) - this is where we
|
||||
* want most of the decisions made about what we actually want
|
||||
* to use from /dev/crypto.
|
||||
*/
|
||||
static int cryptodev_usable_ciphers(const int **nids)
|
||||
{
|
||||
return (get_cryptodev_ciphers(nids));
|
||||
}
|
||||
|
||||
static int cryptodev_usable_digests(const int **nids)
|
||||
{
|
||||
# ifdef USE_CRYPTODEV_DIGESTS
|
||||
return (get_cryptodev_digests(nids));
|
||||
# else
|
||||
/*
|
||||
* XXXX just disable all digests for now, because it sucks.
|
||||
* we need a better way to decide this - i.e. I may not
|
||||
* want digests on slow cards like hifn on fast machines,
|
||||
* but might want them on slow or loaded machines, etc.
|
||||
* will also want them when using crypto cards that don't
|
||||
* 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 algorithms off (or have them off
|
||||
* by default) on cards that generally suck like the hifn.
|
||||
*/
|
||||
*nids = NULL;
|
||||
return (0);
|
||||
# endif
|
||||
}
|
||||
|
||||
static int
|
||||
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 = 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];
|
||||
|
||||
if (state->d_fd < 0)
|
||||
return (0);
|
||||
if (!inl)
|
||||
return (1);
|
||||
if ((inl % EVP_CIPHER_CTX_block_size(ctx)) != 0)
|
||||
return (0);
|
||||
|
||||
memset(&cryp, 0, sizeof(cryp));
|
||||
|
||||
cryp.ses = sess->ses;
|
||||
cryp.flags = 0;
|
||||
cryp.len = inl;
|
||||
cryp.src = (caddr_t) in;
|
||||
cryp.dst = (caddr_t) out;
|
||||
cryp.mac = 0;
|
||||
|
||||
cryp.op = EVP_CIPHER_CTX_encrypting(ctx) ? COP_ENCRYPT : COP_DECRYPT;
|
||||
|
||||
if (EVP_CIPHER_CTX_iv_length(ctx) > 0) {
|
||||
cryp.iv = (caddr_t) 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 error handling this can fail for a number of
|
||||
* different reasons.
|
||||
*/
|
||||
return (0);
|
||||
}
|
||||
|
||||
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(EVP_CIPHER_CTX_iv_noconst(ctx), iiv,
|
||||
EVP_CIPHER_CTX_iv_length(ctx));
|
||||
}
|
||||
return (1);
|
||||
}
|
||||
|
||||
static int
|
||||
cryptodev_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
|
||||
const unsigned char *iv, int enc)
|
||||
{
|
||||
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 (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;
|
||||
}
|
||||
|
||||
if (!ciphers[i].id) {
|
||||
state->d_fd = -1;
|
||||
return (0);
|
||||
}
|
||||
|
||||
memset(sess, 0, sizeof(*sess));
|
||||
|
||||
if ((state->d_fd = get_dev_crypto()) < 0)
|
||||
return (0);
|
||||
|
||||
sess->key = (caddr_t) key;
|
||||
sess->keylen = EVP_CIPHER_CTX_key_length(ctx);
|
||||
sess->cipher = cipher;
|
||||
|
||||
if (ioctl(state->d_fd, CIOCGSESSION, sess) == -1) {
|
||||
put_dev_crypto(state->d_fd);
|
||||
state->d_fd = -1;
|
||||
return (0);
|
||||
}
|
||||
return (1);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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 = 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, 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,
|
||||
* hmm. For right now, we return 0 - I don't believe that to be "right".
|
||||
* we could call the gorpy openssl lib error handlers that print messages
|
||||
* to users of the library. hmm..
|
||||
*/
|
||||
|
||||
if (ioctl(state->d_fd, CIOCFSESSION, &sess->ses) == -1) {
|
||||
ret = 0;
|
||||
} else {
|
||||
ret = 1;
|
||||
}
|
||||
put_dev_crypto(state->d_fd);
|
||||
state->d_fd = -1;
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/*
|
||||
* libcrypto EVP stuff - this is how we get wired to EVP so the engine
|
||||
* gets called when libcrypto requests a cipher NID.
|
||||
*/
|
||||
|
||||
/* RC4 */
|
||||
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 */
|
||||
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 */
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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
|
||||
* a particular NID in the ENGINE. this says what we'll do at the
|
||||
* top level - note, that list is restricted by what we answer with
|
||||
*/
|
||||
static int
|
||||
cryptodev_engine_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
|
||||
const int **nids, int nid)
|
||||
{
|
||||
if (!cipher)
|
||||
return (cryptodev_usable_ciphers(nids));
|
||||
|
||||
switch (nid) {
|
||||
case NID_rc4:
|
||||
*cipher = cryptodev_rc4();
|
||||
break;
|
||||
case NID_des_ede3_cbc:
|
||||
*cipher = cryptodev_3des_cbc();
|
||||
break;
|
||||
case NID_des_cbc:
|
||||
*cipher = cryptodev_des_cbc();
|
||||
break;
|
||||
case NID_bf_cbc:
|
||||
*cipher = cryptodev_bf_cbc();
|
||||
break;
|
||||
case NID_cast5_cbc:
|
||||
*cipher = cryptodev_cast_cbc();
|
||||
break;
|
||||
case NID_aes_128_cbc:
|
||||
*cipher = cryptodev_aes_cbc();
|
||||
break;
|
||||
case NID_aes_192_cbc:
|
||||
*cipher = cryptodev_aes_192_cbc();
|
||||
break;
|
||||
case NID_aes_256_cbc:
|
||||
*cipher = cryptodev_aes_256_cbc();
|
||||
break;
|
||||
# ifdef CRYPTO_AES_CTR
|
||||
case NID_aes_128_ctr:
|
||||
*cipher = cryptodev_aes_ctr();
|
||||
break;
|
||||
case NID_aes_192_ctr:
|
||||
*cipher = cryptodev_aes_192_ctr();
|
||||
break;
|
||||
case NID_aes_256_ctr:
|
||||
*cipher = cryptodev_aes_256_ctr();
|
||||
break;
|
||||
# endif
|
||||
default:
|
||||
*cipher = NULL;
|
||||
break;
|
||||
}
|
||||
return (*cipher != NULL);
|
||||
}
|
||||
|
||||
# ifdef USE_CRYPTODEV_DIGESTS
|
||||
|
||||
/* convert digest type to cryptodev */
|
||||
static int digest_nid_to_cryptodev(int nid)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; digests[i].id; i++)
|
||||
if (digests[i].nid == nid)
|
||||
return (digests[i].id);
|
||||
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 = EVP_MD_CTX_md_data(ctx);
|
||||
struct session_op *sess = &state->d_sess;
|
||||
int digest;
|
||||
|
||||
if ((digest = digest_nid_to_cryptodev(EVP_MD_CTX_type(ctx))) == NID_undef) {
|
||||
printf("cryptodev_digest_init: Can't get digest \n");
|
||||
return (0);
|
||||
}
|
||||
|
||||
memset(state, 0, sizeof(*state));
|
||||
|
||||
if ((state->d_fd = get_dev_crypto()) < 0) {
|
||||
printf("cryptodev_digest_init: Can't get Dev \n");
|
||||
return (0);
|
||||
}
|
||||
|
||||
sess->mackey = state->dummy_mac_key;
|
||||
sess->mackeylen = digest_key_length(EVP_MD_CTX_type(ctx));
|
||||
sess->mac = digest;
|
||||
|
||||
if (ioctl(state->d_fd, CIOCGSESSION, sess) < 0) {
|
||||
put_dev_crypto(state->d_fd);
|
||||
state->d_fd = -1;
|
||||
printf("cryptodev_digest_init: Open session failed\n");
|
||||
return (0);
|
||||
}
|
||||
|
||||
return (1);
|
||||
}
|
||||
|
||||
static int cryptodev_digest_update(EVP_MD_CTX *ctx, const void *data,
|
||||
size_t count)
|
||||
{
|
||||
struct crypt_op cryp;
|
||||
struct dev_crypto_state *state = EVP_MD_CTX_md_data(ctx);
|
||||
struct session_op *sess = &state->d_sess;
|
||||
char *new_mac_data;
|
||||
|
||||
if (!data || state->d_fd < 0) {
|
||||
printf("cryptodev_digest_update: illegal inputs \n");
|
||||
return (0);
|
||||
}
|
||||
|
||||
if (!count) {
|
||||
return (0);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
if (!new_mac_data) {
|
||||
printf("cryptodev_digest_update: realloc failed\n");
|
||||
return (0);
|
||||
}
|
||||
state->mac_data = new_mac_data;
|
||||
|
||||
memcpy(state->mac_data + state->mac_len, data, count);
|
||||
state->mac_len += count;
|
||||
|
||||
return (1);
|
||||
}
|
||||
|
||||
memset(&cryp, 0, sizeof(cryp));
|
||||
|
||||
cryp.ses = sess->ses;
|
||||
cryp.flags = 0;
|
||||
cryp.len = count;
|
||||
cryp.src = (caddr_t) data;
|
||||
cryp.dst = NULL;
|
||||
cryp.mac = (caddr_t) state->digest_res;
|
||||
if (ioctl(state->d_fd, CIOCCRYPT, &cryp) < 0) {
|
||||
printf("cryptodev_digest_update: digest failed\n");
|
||||
return (0);
|
||||
}
|
||||
return (1);
|
||||
}
|
||||
|
||||
static int cryptodev_digest_final(EVP_MD_CTX *ctx, unsigned char *md)
|
||||
{
|
||||
struct crypt_op cryp;
|
||||
struct dev_crypto_state *state = EVP_MD_CTX_md_data(ctx);
|
||||
struct session_op *sess = &state->d_sess;
|
||||
|
||||
int ret = 1;
|
||||
|
||||
if (!md || state->d_fd < 0) {
|
||||
printf("cryptodev_digest_final: illegal input\n");
|
||||
return (0);
|
||||
}
|
||||
|
||||
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;
|
||||
cryp.flags = 0;
|
||||
cryp.len = state->mac_len;
|
||||
cryp.src = state->mac_data;
|
||||
cryp.dst = NULL;
|
||||
cryp.mac = (caddr_t) md;
|
||||
if (ioctl(state->d_fd, CIOCCRYPT, &cryp) < 0) {
|
||||
printf("cryptodev_digest_final: digest failed\n");
|
||||
return (0);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
memcpy(md, state->digest_res, EVP_MD_CTX_size(ctx));
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static int cryptodev_digest_cleanup(EVP_MD_CTX *ctx)
|
||||
{
|
||||
int ret = 1;
|
||||
struct dev_crypto_state *state = EVP_MD_CTX_md_data(ctx);
|
||||
struct session_op *sess = &state->d_sess;
|
||||
|
||||
if (state == NULL)
|
||||
return 0;
|
||||
|
||||
if (state->d_fd < 0) {
|
||||
printf("cryptodev_digest_cleanup: illegal input\n");
|
||||
return (0);
|
||||
}
|
||||
|
||||
OPENSSL_free(state->mac_data);
|
||||
state->mac_data = NULL;
|
||||
state->mac_len = 0;
|
||||
|
||||
if (ioctl(state->d_fd, CIOCFSESSION, &sess->ses) < 0) {
|
||||
printf("cryptodev_digest_cleanup: failed to close session\n");
|
||||
ret = 0;
|
||||
} else {
|
||||
ret = 1;
|
||||
}
|
||||
put_dev_crypto(state->d_fd);
|
||||
state->d_fd = -1;
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static int cryptodev_digest_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from)
|
||||
{
|
||||
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;
|
||||
|
||||
if (dstate == NULL || fstate == NULL)
|
||||
return 1;
|
||||
|
||||
memcpy(dstate, fstate, sizeof(struct dev_crypto_state));
|
||||
|
||||
sess = &dstate->d_sess;
|
||||
|
||||
digest = digest_nid_to_cryptodev(EVP_MD_CTX_type(to));
|
||||
|
||||
sess->mackey = dstate->dummy_mac_key;
|
||||
sess->mackeylen = digest_key_length(EVP_MD_CTX_type(to));
|
||||
sess->mac = digest;
|
||||
|
||||
dstate->d_fd = get_dev_crypto();
|
||||
|
||||
if (ioctl(dstate->d_fd, CIOCGSESSION, sess) < 0) {
|
||||
put_dev_crypto(dstate->d_fd);
|
||||
dstate->d_fd = -1;
|
||||
printf("cryptodev_digest_copy: Open session failed\n");
|
||||
return (0);
|
||||
}
|
||||
|
||||
if (fstate->mac_len != 0) {
|
||||
if (fstate->mac_data != NULL) {
|
||||
dstate->mac_data = OPENSSL_malloc(fstate->mac_len);
|
||||
if (dstate->mac_data == NULL) {
|
||||
printf("cryptodev_digest_copy: mac_data allocation failed\n");
|
||||
return (0);
|
||||
}
|
||||
memcpy(dstate->mac_data, fstate->mac_data, fstate->mac_len);
|
||||
dstate->mac_len = fstate->mac_len;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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 */
|
||||
|
||||
static int
|
||||
cryptodev_engine_digests(ENGINE *e, const EVP_MD **digest,
|
||||
const int **nids, int nid)
|
||||
{
|
||||
if (!digest)
|
||||
return (cryptodev_usable_digests(nids));
|
||||
|
||||
switch (nid) {
|
||||
# ifdef USE_CRYPTODEV_DIGESTS
|
||||
case NID_md5:
|
||||
*digest = cryptodev_md5();
|
||||
break;
|
||||
case NID_sha1:
|
||||
*digest = cryptodev_sha1();
|
||||
break;
|
||||
default:
|
||||
# endif /* USE_CRYPTODEV_DIGESTS */
|
||||
*digest = NULL;
|
||||
break;
|
||||
}
|
||||
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(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
|
||||
* crp->crp_p.
|
||||
*/
|
||||
static int bn2crparam(const BIGNUM *a, struct crparam *crp)
|
||||
{
|
||||
ssize_t bytes, bits;
|
||||
u_char *b;
|
||||
|
||||
crp->crp_p = NULL;
|
||||
crp->crp_nbits = 0;
|
||||
|
||||
bits = BN_num_bits(a);
|
||||
bytes = BN_num_bytes(a);
|
||||
|
||||
b = OPENSSL_zalloc(bytes);
|
||||
if (b == NULL)
|
||||
return (1);
|
||||
|
||||
crp->crp_p = (caddr_t) b;
|
||||
crp->crp_nbits = bits;
|
||||
|
||||
BN_bn2bin(a, b);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Convert a /dev/crypto parameter to a BIGNUM */
|
||||
static int crparam2bn(struct crparam *crp, BIGNUM *a)
|
||||
{
|
||||
u_int8_t *pd;
|
||||
int i, bytes;
|
||||
|
||||
bytes = (crp->crp_nbits + 7) / 8;
|
||||
|
||||
if (bytes == 0)
|
||||
return (-1);
|
||||
|
||||
if ((pd = OPENSSL_malloc(bytes)) == NULL)
|
||||
return (-1);
|
||||
|
||||
for (i = 0; i < bytes; i++)
|
||||
pd[i] = crp->crp_p[bytes - i - 1];
|
||||
|
||||
BN_bin2bn(pd, bytes, a);
|
||||
free(pd);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void zapparams(struct crypt_kop *kop)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < kop->crk_iparams + kop->crk_oparams; i++) {
|
||||
OPENSSL_free(kop->crk_param[i].crp_p);
|
||||
kop->crk_param[i].crp_p = NULL;
|
||||
kop->crk_param[i].crp_nbits = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
cryptodev_asym(struct crypt_kop *kop, int rlen, BIGNUM *r, int slen,
|
||||
BIGNUM *s)
|
||||
{
|
||||
int fd, ret = -1;
|
||||
|
||||
if ((fd = get_asym_dev_crypto()) < 0)
|
||||
return ret;
|
||||
|
||||
if (r) {
|
||||
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 =
|
||||
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++;
|
||||
}
|
||||
|
||||
if (ioctl(fd, CIOCKEY, kop) == 0) {
|
||||
if (r)
|
||||
crparam2bn(&kop->crk_param[kop->crk_iparams], r);
|
||||
if (s)
|
||||
crparam2bn(&kop->crk_param[kop->crk_iparams + 1], s);
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
cryptodev_bn_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
|
||||
const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont)
|
||||
{
|
||||
struct crypt_kop kop;
|
||||
int ret = 1;
|
||||
|
||||
/*
|
||||
* Currently, we know we can do mod exp iff we can do any asymmetric
|
||||
* operations at all.
|
||||
*/
|
||||
if (cryptodev_asymfeat == 0) {
|
||||
ret = BN_mod_exp(r, a, p, m, ctx);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
memset(&kop, 0, sizeof(kop));
|
||||
kop.crk_op = CRK_MOD_EXP;
|
||||
|
||||
/* inputs: a^p % m */
|
||||
if (bn2crparam(a, &kop.crk_param[0]))
|
||||
goto err;
|
||||
if (bn2crparam(p, &kop.crk_param[1]))
|
||||
goto err;
|
||||
if (bn2crparam(m, &kop.crk_param[2]))
|
||||
goto err;
|
||||
kop.crk_iparams = 3;
|
||||
|
||||
if (cryptodev_asym(&kop, BN_num_bytes(m), r, 0, NULL)) {
|
||||
const RSA_METHOD *meth = RSA_PKCS1_OpenSSL();
|
||||
printf("OCF asym process failed, Running in software\n");
|
||||
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_OpenSSL();
|
||||
printf("OCF hardware operation cancelled. Running in Software\n");
|
||||
ret = RSA_meth_get_bn_mod_exp(meth)(r, a, p, m, ctx, in_mont);
|
||||
}
|
||||
/* else cryptodev operation worked ok ==> ret = 1 */
|
||||
|
||||
err:
|
||||
zapparams(&kop);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static int
|
||||
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();
|
||||
RSA_get0_key(rsa, &n, NULL, &d);
|
||||
r = cryptodev_bn_mod_exp(r0, I, d, n, ctx, NULL);
|
||||
BN_CTX_free(ctx);
|
||||
return (r);
|
||||
}
|
||||
|
||||
static int
|
||||
cryptodev_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
|
||||
{
|
||||
struct crypt_kop kop;
|
||||
int ret = 1;
|
||||
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);
|
||||
}
|
||||
|
||||
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(p, &kop.crk_param[0]))
|
||||
goto err;
|
||||
if (bn2crparam(q, &kop.crk_param[1]))
|
||||
goto err;
|
||||
if (bn2crparam(I, &kop.crk_param[2]))
|
||||
goto err;
|
||||
if (bn2crparam(dmp1, &kop.crk_param[3]))
|
||||
goto err;
|
||||
if (bn2crparam(dmq1, &kop.crk_param[4]))
|
||||
goto err;
|
||||
if (bn2crparam(iqmp, &kop.crk_param[5]))
|
||||
goto err;
|
||||
kop.crk_iparams = 6;
|
||||
|
||||
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 = RSA_meth_get_mod_exp(meth)(r0, I, rsa, ctx);
|
||||
|
||||
} else if (ECANCELED == kop.crk_status) {
|
||||
const RSA_METHOD *meth = RSA_PKCS1_OpenSSL();
|
||||
printf("OCF hardware operation cancelled. Running in Software\n");
|
||||
ret = RSA_meth_get_mod_exp(meth)(r0, I, rsa, ctx);
|
||||
}
|
||||
/* else cryptodev operation worked ok ==> ret = 1 */
|
||||
|
||||
err:
|
||||
zapparams(&kop);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
#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)
|
||||
{
|
||||
return cryptodev_bn_mod_exp(r, a, p, m, ctx, m_ctx);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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;
|
||||
|
||||
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 (!bn_mod_exp(dsa, t2, dsapub_key, u2, dsap, ctx, mont))
|
||||
goto err;
|
||||
/* let t1 = t1 * t2 mod p */
|
||||
if (!BN_mod_mul(t1, t1, t2, dsap, ctx))
|
||||
goto err;
|
||||
|
||||
ret = 1;
|
||||
err:
|
||||
BN_free(t2);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static DSA_SIG *cryptodev_dsa_do_sign(const unsigned char *dgst, int dlen,
|
||||
DSA *dsa)
|
||||
{
|
||||
struct crypt_kop kop;
|
||||
BIGNUM *r, *s;
|
||||
const BIGNUM *dsap = NULL, *dsaq = NULL, *dsag = NULL;
|
||||
const BIGNUM *priv_key = NULL;
|
||||
DSA_SIG *dsasig, *dsaret = NULL;
|
||||
|
||||
dsasig = DSA_SIG_new();
|
||||
if (dsasig == NULL)
|
||||
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_nbits = dlen * 8;
|
||||
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(dsaq, &kop.crk_param[2]))
|
||||
goto err;
|
||||
if (bn2crparam(dsag, &kop.crk_param[3]))
|
||||
goto err;
|
||||
if (bn2crparam(priv_key, &kop.crk_param[4]))
|
||||
goto err;
|
||||
kop.crk_iparams = 5;
|
||||
|
||||
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 {
|
||||
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;
|
||||
}
|
||||
|
||||
static int
|
||||
cryptodev_dsa_verify(const unsigned char *dgst, int dlen,
|
||||
DSA_SIG *sig, DSA *dsa)
|
||||
{
|
||||
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_nbits = dlen * 8;
|
||||
DSA_get0_pqg(dsa, &p, &q, &g);
|
||||
if (bn2crparam(p, &kop.crk_param[1]))
|
||||
goto err;
|
||||
if (bn2crparam(q, &kop.crk_param[2]))
|
||||
goto err;
|
||||
if (bn2crparam(g, &kop.crk_param[3]))
|
||||
goto err;
|
||||
DSA_get0_key(dsa, &pub_key, NULL);
|
||||
if (bn2crparam(pub_key, &kop.crk_param[4]))
|
||||
goto err;
|
||||
DSA_SIG_get0(sig, &pr, &ps);
|
||||
if (bn2crparam(pr, &kop.crk_param[5]))
|
||||
goto err;
|
||||
if (bn2crparam(ps, &kop.crk_param[6]))
|
||||
goto err;
|
||||
kop.crk_iparams = 7;
|
||||
|
||||
if (cryptodev_asym(&kop, 0, NULL, 0, NULL) == 0) {
|
||||
/*
|
||||
* OCF success value is 0, if not zero, change dsaret to fail
|
||||
*/
|
||||
if (0 != kop.crk_status)
|
||||
dsaret = 0;
|
||||
} else {
|
||||
dsaret = DSA_meth_get_verify(DSA_OpenSSL())(dgst, dlen, sig, dsa);
|
||||
}
|
||||
err:
|
||||
kop.crk_param[0].crp_p = NULL;
|
||||
zapparams(&kop);
|
||||
return (dsaret);
|
||||
}
|
||||
#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)
|
||||
{
|
||||
return (cryptodev_bn_mod_exp(r, a, p, m, ctx, m_ctx));
|
||||
}
|
||||
|
||||
static int
|
||||
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 DH_meth_get_compute_key(meth)(key, pub_key, dh);
|
||||
}
|
||||
|
||||
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(priv_key, &kop.crk_param[0]))
|
||||
goto err;
|
||||
if (bn2crparam(pub_key, &kop.crk_param[1]))
|
||||
goto err;
|
||||
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_nbits = keylen * 8;
|
||||
kop.crk_oparams = 1;
|
||||
|
||||
if (ioctl(fd, CIOCKEY, &kop) == -1) {
|
||||
const DH_METHOD *meth = DH_OpenSSL();
|
||||
|
||||
dhret = DH_meth_get_compute_key(meth)(key, pub_key, dh);
|
||||
}
|
||||
err:
|
||||
kop.crk_param[3].crp_p = NULL;
|
||||
zapparams(&kop);
|
||||
return (dhret);
|
||||
}
|
||||
|
||||
#endif /* ndef OPENSSL_NO_DH */
|
||||
|
||||
/*
|
||||
* ctrl right now is just a wrapper that doesn't do much
|
||||
* but I expect we'll want some options soon.
|
||||
*/
|
||||
static int
|
||||
cryptodev_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void))
|
||||
{
|
||||
# ifdef HAVE_SYSLOG_R
|
||||
struct syslog_data sd = SYSLOG_DATA_INIT;
|
||||
# endif
|
||||
|
||||
switch (cmd) {
|
||||
default:
|
||||
# ifdef HAVE_SYSLOG_R
|
||||
syslog_r(LOG_ERR, &sd, "cryptodev_ctrl: unknown command %d", cmd);
|
||||
# else
|
||||
syslog(LOG_ERR, "cryptodev_ctrl: unknown command %d", cmd);
|
||||
# endif
|
||||
break;
|
||||
}
|
||||
return (1);
|
||||
}
|
||||
|
||||
void engine_load_cryptodev_int(void)
|
||||
{
|
||||
ENGINE *engine = ENGINE_new();
|
||||
int fd;
|
||||
|
||||
if (engine == NULL)
|
||||
return;
|
||||
if ((fd = get_dev_crypto()) < 0) {
|
||||
ENGINE_free(engine);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* find out what asymmetric crypto algorithms we support
|
||||
*/
|
||||
if (ioctl(fd, CIOCASYMFEAT, &cryptodev_asymfeat) == -1) {
|
||||
put_dev_crypto(fd);
|
||||
ENGINE_free(engine);
|
||||
return;
|
||||
}
|
||||
put_dev_crypto(fd);
|
||||
|
||||
if (!ENGINE_set_id(engine, "cryptodev") ||
|
||||
!ENGINE_set_name(engine, "BSD 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) ||
|
||||
!ENGINE_set_cmd_defns(engine, cryptodev_defns)) {
|
||||
ENGINE_free(engine);
|
||||
return;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
#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);
|
||||
}
|
||||
} else {
|
||||
ENGINE_free(engine);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
#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);
|
||||
ERR_clear_error();
|
||||
}
|
||||
|
||||
#endif /* HAVE_CRYPTODEV */
|
||||
+14
-22
@@ -63,6 +63,8 @@ static int int_ctrl_helper(ENGINE *e, int cmd, long i, void *p,
|
||||
{
|
||||
int idx;
|
||||
char *s = (char *)p;
|
||||
const ENGINE_CMD_DEFN *cdp;
|
||||
|
||||
/* Take care of the easy one first (eg. it requires no searches) */
|
||||
if (cmd == ENGINE_CTRL_GET_FIRST_CMD_TYPE) {
|
||||
if ((e->cmd_defns == NULL) || int_ctrl_cmd_is_null(e->cmd_defns))
|
||||
@@ -91,39 +93,29 @@ static int int_ctrl_helper(ENGINE *e, int cmd, long i, void *p,
|
||||
* For the rest of the commands, the 'long' argument must specify a valid
|
||||
* command number - so we need to conduct a search.
|
||||
*/
|
||||
if ((e->cmd_defns == NULL) || ((idx = int_ctrl_cmd_by_num(e->cmd_defns,
|
||||
(unsigned int)
|
||||
i)) < 0)) {
|
||||
if ((e->cmd_defns == NULL)
|
||||
|| ((idx = int_ctrl_cmd_by_num(e->cmd_defns, (unsigned int)i)) < 0)) {
|
||||
ENGINEerr(ENGINE_F_INT_CTRL_HELPER, ENGINE_R_INVALID_CMD_NUMBER);
|
||||
return -1;
|
||||
}
|
||||
/* Now the logic splits depending on command type */
|
||||
cdp = &e->cmd_defns[idx];
|
||||
switch (cmd) {
|
||||
case ENGINE_CTRL_GET_NEXT_CMD_TYPE:
|
||||
idx++;
|
||||
if (int_ctrl_cmd_is_null(e->cmd_defns + idx))
|
||||
/* end-of-list */
|
||||
return 0;
|
||||
else
|
||||
return e->cmd_defns[idx].cmd_num;
|
||||
cdp++;
|
||||
return int_ctrl_cmd_is_null(cdp) ? 0 : cdp->cmd_num;
|
||||
case ENGINE_CTRL_GET_NAME_LEN_FROM_CMD:
|
||||
return strlen(e->cmd_defns[idx].cmd_name);
|
||||
return strlen(cdp->cmd_name);
|
||||
case ENGINE_CTRL_GET_NAME_FROM_CMD:
|
||||
return BIO_snprintf(s, strlen(e->cmd_defns[idx].cmd_name) + 1,
|
||||
"%s", e->cmd_defns[idx].cmd_name);
|
||||
return strlen(strcpy(s, cdp->cmd_name));
|
||||
case ENGINE_CTRL_GET_DESC_LEN_FROM_CMD:
|
||||
if (e->cmd_defns[idx].cmd_desc)
|
||||
return strlen(e->cmd_defns[idx].cmd_desc);
|
||||
return strlen(int_no_description);
|
||||
return strlen(cdp->cmd_desc == NULL ? int_no_description
|
||||
: cdp->cmd_desc);
|
||||
case ENGINE_CTRL_GET_DESC_FROM_CMD:
|
||||
if (e->cmd_defns[idx].cmd_desc)
|
||||
return BIO_snprintf(s,
|
||||
strlen(e->cmd_defns[idx].cmd_desc) + 1,
|
||||
"%s", e->cmd_defns[idx].cmd_desc);
|
||||
return BIO_snprintf(s, strlen(int_no_description) + 1, "%s",
|
||||
int_no_description);
|
||||
return strlen(strcpy(s, cdp->cmd_desc == NULL ? int_no_description
|
||||
: cdp->cmd_desc));
|
||||
case ENGINE_CTRL_GET_CMD_FLAGS:
|
||||
return e->cmd_defns[idx].cmd_flags;
|
||||
return cdp->cmd_flags;
|
||||
}
|
||||
/* Shouldn't really be here ... */
|
||||
ENGINEerr(ENGINE_F_INT_CTRL_HELPER, ENGINE_R_INTERNAL_LIST_ERROR);
|
||||
|
||||
@@ -0,0 +1,678 @@
|
||||
/*
|
||||
* Copyright 2017 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include "e_os.h"
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <unistd.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/engine.h>
|
||||
#include <openssl/objects.h>
|
||||
#include <crypto/cryptodev.h>
|
||||
|
||||
#include "internal/engine.h"
|
||||
|
||||
#ifdef CRYPTO_ALGORITHM_MIN
|
||||
# define CHECK_BSD_STYLE_MACROS
|
||||
#endif
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Ciphers
|
||||
*
|
||||
* Because they all do the same basic operation, we have only one set of
|
||||
* method functions for them all to share, and a mapping table between
|
||||
* NIDs and cryptodev IDs, with all the necessary size data.
|
||||
*
|
||||
*****/
|
||||
|
||||
struct cipher_ctx {
|
||||
int cfd;
|
||||
struct session_op sess;
|
||||
|
||||
/* to pass from init to do_cipher */
|
||||
const unsigned char *iv;
|
||||
int op; /* COP_ENCRYPT or COP_DECRYPT */
|
||||
};
|
||||
|
||||
static const struct cipher_data_st {
|
||||
int nid;
|
||||
int blocksize;
|
||||
int keylen;
|
||||
int ivlen;
|
||||
int flags;
|
||||
int devcryptoid;
|
||||
} cipher_data[] = {
|
||||
#ifndef OPENSSL_NO_DES
|
||||
{ NID_des_cbc, 8, 8, 8, EVP_CIPH_CBC_MODE, CRYPTO_DES_CBC },
|
||||
{ NID_des_ede3_cbc, 8, 24, 8, EVP_CIPH_CBC_MODE, CRYPTO_3DES_CBC },
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_BF
|
||||
{ NID_bf_cbc, 8, 16, 8, EVP_CIPH_CBC_MODE, CRYPTO_BLF_CBC },
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_CAST
|
||||
{ NID_cast5_cbc, 8, 16, 8, EVP_CIPH_CBC_MODE, CRYPTO_CAST_CBC },
|
||||
#endif
|
||||
{ NID_aes_128_cbc, 16, 128 / 8, 16, EVP_CIPH_CBC_MODE, CRYPTO_AES_CBC },
|
||||
{ NID_aes_192_cbc, 16, 192 / 8, 16, EVP_CIPH_CBC_MODE, CRYPTO_AES_CBC },
|
||||
{ NID_aes_256_cbc, 16, 256 / 8, 16, EVP_CIPH_CBC_MODE, CRYPTO_AES_CBC },
|
||||
#ifndef OPENSSL_NO_RC4
|
||||
{ NID_rc4, 1, 16, 0, CRYPTO_ARC4 },
|
||||
#endif
|
||||
#if !defined(CHECK_BSD_STYLE_MACROS) || defined(CRYPTO_AES_CTR)
|
||||
{ NID_aes_128_ctr, 16, 128 / 8, 16, EVP_CIPH_CTR_MODE, CRYPTO_AES_CTR },
|
||||
{ NID_aes_192_ctr, 16, 192 / 8, 16, EVP_CIPH_CTR_MODE, CRYPTO_AES_CTR },
|
||||
{ NID_aes_256_ctr, 16, 256 / 8, 16, EVP_CIPH_CTR_MODE, CRYPTO_AES_CTR },
|
||||
#endif
|
||||
#if 0 /* Not yet supported */
|
||||
{ NID_aes_128_xts, 16, 128 / 8 * 2, 16, EVP_CIPH_XTS_MODE, CRYPTO_AES_XTS },
|
||||
{ NID_aes_256_xts, 16, 256 / 8 * 2, 16, EVP_CIPH_XTS_MODE, CRYPTO_AES_XTS },
|
||||
#endif
|
||||
#if !defined(CHECK_BSD_STYLE_MACROS) || defined(CRYPTO_AES_ECB)
|
||||
{ NID_aes_128_ecb, 16, 128 / 8, 16, EVP_CIPH_ECB_MODE, CRYPTO_AES_ECB },
|
||||
{ NID_aes_192_ecb, 16, 192 / 8, 16, EVP_CIPH_ECB_MODE, CRYPTO_AES_ECB },
|
||||
{ NID_aes_256_ecb, 16, 256 / 8, 16, EVP_CIPH_ECB_MODE, CRYPTO_AES_ECB },
|
||||
#endif
|
||||
#if 0 /* Not yet supported */
|
||||
{ NID_aes_128_gcm, 16, 128 / 8, 16, EVP_CIPH_GCM_MODE, CRYPTO_AES_GCM },
|
||||
{ NID_aes_192_gcm, 16, 192 / 8, 16, EVP_CIPH_GCM_MODE, CRYPTO_AES_GCM },
|
||||
{ NID_aes_256_gcm, 16, 256 / 8, 16, EVP_CIPH_GCM_MODE, CRYPTO_AES_GCM },
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_CAMELLIA
|
||||
{ NID_camellia_128_cbc, 16, 128 / 8, 16, EVP_CIPH_CBC_MODE,
|
||||
CRYPTO_CAMELLIA_CBC },
|
||||
{ NID_camellia_192_cbc, 16, 192 / 8, 16, EVP_CIPH_CBC_MODE,
|
||||
CRYPTO_CAMELLIA_CBC },
|
||||
{ NID_camellia_256_cbc, 16, 256 / 8, 16, EVP_CIPH_CBC_MODE,
|
||||
CRYPTO_CAMELLIA_CBC },
|
||||
#endif
|
||||
};
|
||||
|
||||
static size_t get_cipher_data_index(int nid)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < OSSL_NELEM(cipher_data); i++)
|
||||
if (nid == cipher_data[i].nid)
|
||||
return i;
|
||||
|
||||
/*
|
||||
* Code further down must make sure that only NIDs in the table above
|
||||
* are used. If any other NID reaches this function, there's a grave
|
||||
* coding error further down.
|
||||
*/
|
||||
assert("Code that never should be reached" == NULL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static const struct cipher_data_st *get_cipher_data(int nid)
|
||||
{
|
||||
return &cipher_data[get_cipher_data_index(nid)];
|
||||
}
|
||||
|
||||
/*
|
||||
* Following are the three necessary functions to map OpenSSL functionality
|
||||
* with cryptodev.
|
||||
*/
|
||||
|
||||
static int cipher_init(EVP_CIPHER_CTX *ctx, const unsigned char *key,
|
||||
const unsigned char *iv, int enc)
|
||||
{
|
||||
struct cipher_ctx *cipher_ctx =
|
||||
(struct cipher_ctx *)EVP_CIPHER_CTX_get_cipher_data(ctx);
|
||||
const struct cipher_data_st *cipher_d =
|
||||
get_cipher_data(EVP_CIPHER_CTX_nid(ctx));
|
||||
|
||||
if ((cipher_ctx->cfd = open("/dev/crypto", O_RDWR, 0)) < 0) {
|
||||
SYSerr(SYS_F_OPEN, errno);
|
||||
return 0;
|
||||
}
|
||||
|
||||
memset(&cipher_ctx->sess, 0, sizeof(cipher_ctx->sess));
|
||||
cipher_ctx->sess.cipher = cipher_d->devcryptoid;
|
||||
cipher_ctx->sess.keylen = cipher_d->keylen;
|
||||
cipher_ctx->sess.key = (void *)key;
|
||||
cipher_ctx->op = enc ? COP_ENCRYPT : COP_DECRYPT;
|
||||
if (ioctl(cipher_ctx->cfd, CIOCGSESSION, &cipher_ctx->sess) < 0) {
|
||||
SYSerr(SYS_F_IOCTL, errno);
|
||||
close(cipher_ctx->cfd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int cipher_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
|
||||
const unsigned char *in, size_t inl)
|
||||
{
|
||||
struct cipher_ctx *cipher_ctx =
|
||||
(struct cipher_ctx *)EVP_CIPHER_CTX_get_cipher_data(ctx);
|
||||
struct crypt_op cryp;
|
||||
#if !defined(COP_FLAG_WRITE_IV)
|
||||
unsigned char saved_iv[EVP_MAX_IV_LENGTH];
|
||||
#endif
|
||||
|
||||
memset(&cryp, 0, sizeof(cryp));
|
||||
cryp.ses = cipher_ctx->sess.ses;
|
||||
cryp.len = inl;
|
||||
cryp.src = (void *)in;
|
||||
cryp.dst = (void *)out;
|
||||
cryp.iv = (void *)EVP_CIPHER_CTX_iv_noconst(ctx);
|
||||
cryp.op = cipher_ctx->op;
|
||||
#if !defined(COP_FLAG_WRITE_IV)
|
||||
cryp.flags = 0;
|
||||
|
||||
if (EVP_CIPHER_CTX_iv_length(ctx) > 0) {
|
||||
assert(inl >= EVP_CIPHER_CTX_iv_length(ctx));
|
||||
if (!EVP_CIPHER_CTX_encrypting(ctx)) {
|
||||
unsigned char *ivptr = in + inl - EVP_CIPHER_CTX_iv_length(ctx);
|
||||
|
||||
memcpy(saved_iv, ivptr, EVP_CIPHER_CTX_iv_length(ctx));
|
||||
}
|
||||
}
|
||||
#else
|
||||
cryp.flags = COP_FLAG_WRITE_IV;
|
||||
#endif
|
||||
|
||||
if (ioctl(cipher_ctx->cfd, CIOCCRYPT, &cryp) < 0) {
|
||||
SYSerr(SYS_F_IOCTL, errno);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if !defined(COP_FLAG_WRITE_IV)
|
||||
if (EVP_CIPHER_CTX_iv_length(ctx) > 0) {
|
||||
unsigned char *ivptr = saved_iv;
|
||||
|
||||
assert(inl >= EVP_CIPHER_CTX_iv_length(ctx));
|
||||
if (!EVP_CIPHER_CTX_encrypting(ctx))
|
||||
ivptr = out + inl - EVP_CIPHER_CTX_iv_length(ctx);
|
||||
|
||||
memcpy(EVP_CIPHER_CTX_iv_noconst(ctx), ivptr,
|
||||
EVP_CIPHER_CTX_iv_length(ctx));
|
||||
}
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int cipher_cleanup(EVP_CIPHER_CTX *ctx)
|
||||
{
|
||||
struct cipher_ctx *cipher_ctx =
|
||||
(struct cipher_ctx *)EVP_CIPHER_CTX_get_cipher_data(ctx);
|
||||
|
||||
if (ioctl(cipher_ctx->cfd, CIOCFSESSION, &cipher_ctx->sess) < 0) {
|
||||
SYSerr(SYS_F_IOCTL, errno);
|
||||
return 0;
|
||||
}
|
||||
if (close(cipher_ctx->cfd) < 0) {
|
||||
SYSerr(SYS_F_CLOSE, errno);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Keep a table of known nids and associated methods.
|
||||
* Note that known_cipher_nids[] isn't necessarily indexed the same way as
|
||||
* cipher_data[] above, which known_cipher_methods[] is.
|
||||
*/
|
||||
static int known_cipher_nids[OSSL_NELEM(cipher_data)];
|
||||
static int known_cipher_nids_amount = -1; /* -1 indicates not yet initialised */
|
||||
static EVP_CIPHER *known_cipher_methods[OSSL_NELEM(cipher_data)] = { NULL, };
|
||||
|
||||
static void prepare_cipher_methods()
|
||||
{
|
||||
size_t i;
|
||||
struct session_op sess;
|
||||
int cfd;
|
||||
|
||||
if ((cfd = open("/dev/crypto", O_RDWR, 0)) < 0)
|
||||
return;
|
||||
|
||||
memset(&sess, 0, sizeof(sess));
|
||||
sess.key = (void *)"01234567890123456789012345678901234567890123456789";
|
||||
|
||||
for (i = 0, known_cipher_nids_amount = 0;
|
||||
i < OSSL_NELEM(cipher_data); i++) {
|
||||
|
||||
/*
|
||||
* Check that the algo is really availably by trying to open and close
|
||||
* a session.
|
||||
*/
|
||||
sess.cipher = cipher_data[i].devcryptoid;
|
||||
sess.keylen = cipher_data[i].keylen;
|
||||
if (ioctl(cfd, CIOCGSESSION, &sess) < 0
|
||||
|| ioctl(cfd, CIOCFSESSION, &sess) < 0)
|
||||
continue;
|
||||
|
||||
if ((known_cipher_methods[i] =
|
||||
EVP_CIPHER_meth_new(cipher_data[i].nid,
|
||||
cipher_data[i].blocksize,
|
||||
cipher_data[i].keylen)) == NULL
|
||||
|| !EVP_CIPHER_meth_set_iv_length(known_cipher_methods[i],
|
||||
cipher_data[i].ivlen)
|
||||
|| !EVP_CIPHER_meth_set_flags(known_cipher_methods[i],
|
||||
cipher_data[i].flags
|
||||
| EVP_CIPH_FLAG_DEFAULT_ASN1)
|
||||
|| !EVP_CIPHER_meth_set_init(known_cipher_methods[i], cipher_init)
|
||||
|| !EVP_CIPHER_meth_set_do_cipher(known_cipher_methods[i],
|
||||
cipher_do_cipher)
|
||||
|| !EVP_CIPHER_meth_set_cleanup(known_cipher_methods[i],
|
||||
cipher_cleanup)
|
||||
|| !EVP_CIPHER_meth_set_impl_ctx_size(known_cipher_methods[i],
|
||||
sizeof(struct cipher_ctx))) {
|
||||
EVP_CIPHER_meth_free(known_cipher_methods[i]);
|
||||
known_cipher_methods[i] = NULL;
|
||||
} else {
|
||||
known_cipher_nids[known_cipher_nids_amount++] =
|
||||
cipher_data[i].nid;
|
||||
}
|
||||
}
|
||||
|
||||
close(cfd);
|
||||
}
|
||||
|
||||
static const EVP_CIPHER *get_cipher_method(int nid)
|
||||
{
|
||||
size_t i = get_cipher_data_index(nid);
|
||||
|
||||
if (i == (size_t)-1)
|
||||
return NULL;
|
||||
return known_cipher_methods[i];
|
||||
}
|
||||
|
||||
static int get_cipher_nids(const int **nids)
|
||||
{
|
||||
*nids = known_cipher_nids;
|
||||
return known_cipher_nids_amount;
|
||||
}
|
||||
|
||||
static void destroy_cipher_method(int nid)
|
||||
{
|
||||
size_t i = get_cipher_data_index(nid);
|
||||
|
||||
EVP_CIPHER_meth_free(known_cipher_methods[i]);
|
||||
known_cipher_methods[i] = NULL;
|
||||
}
|
||||
|
||||
static void destroy_all_cipher_methods()
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < OSSL_NELEM(cipher_data); i++)
|
||||
destroy_cipher_method(cipher_data[i].nid);
|
||||
}
|
||||
|
||||
static int devcrypto_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
|
||||
const int **nids, int nid)
|
||||
{
|
||||
if (cipher == NULL)
|
||||
return get_cipher_nids(nids);
|
||||
|
||||
*cipher = get_cipher_method(nid);
|
||||
|
||||
return *cipher != NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* We only support digests if the cryptodev implementation supports multiple
|
||||
* data updates. Otherwise, we would be forced to maintain a cache, which is
|
||||
* perilous if there's a lot of data coming in (if someone wants to checksum
|
||||
* an OpenSSL tarball, for example).
|
||||
*/
|
||||
#if defined(COP_FLAG_UPDATE) && defined(COP_FLAG_FINAL)
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Digests
|
||||
*
|
||||
* Because they all do the same basic operation, we have only one set of
|
||||
* method functions for them all to share, and a mapping table between
|
||||
* NIDs and cryptodev IDs, with all the necessary size data.
|
||||
*
|
||||
*****/
|
||||
|
||||
struct digest_ctx {
|
||||
int cfd;
|
||||
struct session_op sess;
|
||||
int init;
|
||||
};
|
||||
|
||||
static const struct digest_data_st {
|
||||
int nid;
|
||||
int digestlen;
|
||||
int devcryptoid;
|
||||
} digest_data[] = {
|
||||
#ifndef OPENSSL_NO_MD5
|
||||
{ NID_md5, 16, CRYPTO_MD5 },
|
||||
#endif
|
||||
{ NID_sha1, 20, CRYPTO_SHA1 },
|
||||
#ifndef OPENSSL_NO_RMD160
|
||||
# if !defined(CHECK_BSD_STYLE_MACROS) && defined(CRYPTO_RIPEMD160)
|
||||
{ NID_ripemd160, 20, CRYPTO_RIPEMD160 },
|
||||
# endif
|
||||
#endif
|
||||
#if !defined(CHECK_BSD_STYLE_MACROS) && defined(CRYPTO_SHA2_224)
|
||||
{ NID_sha224, 224 / 8, CRYPTO_SHA2_224 },
|
||||
#endif
|
||||
#if !defined(CHECK_BSD_STYLE_MACROS) && defined(CRYPTO_SHA2_256)
|
||||
{ NID_sha256, 256 / 8, CRYPTO_SHA2_256 },
|
||||
#endif
|
||||
#if !defined(CHECK_BSD_STYLE_MACROS) && defined(CRYPTO_SHA2_384)
|
||||
{ NID_sha384, 384 / 8, CRYPTO_SHA2_384 },
|
||||
#endif
|
||||
#if !defined(CHECK_BSD_STYLE_MACROS) && defined(CRYPTO_SHA2_512)
|
||||
{ NID_sha512, 512 / 8, CRYPTO_SHA2_512 },
|
||||
#endif
|
||||
};
|
||||
|
||||
static size_t get_digest_data_index(int nid)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < OSSL_NELEM(digest_data); i++)
|
||||
if (nid == digest_data[i].nid)
|
||||
return i;
|
||||
|
||||
/*
|
||||
* Code further down must make sure that only NIDs in the table above
|
||||
* are used. If any other NID reaches this function, there's a grave
|
||||
* coding error further down.
|
||||
*/
|
||||
assert("Code that never should be reached" == NULL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static const struct digest_data_st *get_digest_data(int nid)
|
||||
{
|
||||
return &digest_data[get_digest_data_index(nid)];
|
||||
}
|
||||
|
||||
/*
|
||||
* Following are the four necessary functions to map OpenSSL functionality
|
||||
* with cryptodev.
|
||||
*/
|
||||
|
||||
static int digest_init(EVP_MD_CTX *ctx)
|
||||
{
|
||||
struct digest_ctx *digest_ctx =
|
||||
(struct digest_ctx *)EVP_MD_CTX_md_data(ctx);
|
||||
const struct digest_data_st *digest_d =
|
||||
get_digest_data(EVP_MD_CTX_type(ctx));
|
||||
|
||||
if (digest_ctx->init == 0
|
||||
&& (digest_ctx->cfd = open("/dev/crypto", O_RDWR, 0)) < 0) {
|
||||
SYSerr(SYS_F_OPEN, errno);
|
||||
return 0;
|
||||
}
|
||||
|
||||
digest_ctx->init = 1;
|
||||
|
||||
memset(&digest_ctx->sess, 0, sizeof(digest_ctx->sess));
|
||||
digest_ctx->sess.mac = digest_d->devcryptoid;
|
||||
if (ioctl(digest_ctx->cfd, CIOCGSESSION, &digest_ctx->sess) < 0) {
|
||||
SYSerr(SYS_F_IOCTL, errno);
|
||||
close(digest_ctx->cfd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int digest_op(struct digest_ctx *ctx, const void *src, size_t srclen,
|
||||
void *res, unsigned int flags)
|
||||
{
|
||||
struct crypt_op cryp;
|
||||
|
||||
memset(&cryp, 0, sizeof(cryp));
|
||||
cryp.ses = ctx->sess.ses;
|
||||
cryp.len = srclen;
|
||||
cryp.src = (void *)src;
|
||||
cryp.dst = NULL;
|
||||
cryp.mac = res;
|
||||
cryp.flags = flags;
|
||||
return ioctl(ctx->cfd, CIOCCRYPT, &cryp);
|
||||
}
|
||||
|
||||
static int digest_update(EVP_MD_CTX *ctx, const void *data, size_t count)
|
||||
{
|
||||
struct digest_ctx *digest_ctx =
|
||||
(struct digest_ctx *)EVP_MD_CTX_md_data(ctx);
|
||||
|
||||
if (count == 0)
|
||||
return 1;
|
||||
|
||||
if (digest_op(digest_ctx, data, count, NULL, COP_FLAG_UPDATE) < 0) {
|
||||
SYSerr(SYS_F_IOCTL, errno);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int digest_final(EVP_MD_CTX *ctx, unsigned char *md)
|
||||
{
|
||||
struct digest_ctx *digest_ctx =
|
||||
(struct digest_ctx *)EVP_MD_CTX_md_data(ctx);
|
||||
|
||||
if (digest_op(digest_ctx, NULL, 0, md, COP_FLAG_FINAL) < 0) {
|
||||
SYSerr(SYS_F_IOCTL, errno);
|
||||
return 0;
|
||||
}
|
||||
if (ioctl(digest_ctx->cfd, CIOCFSESSION, &digest_ctx->sess) < 0) {
|
||||
SYSerr(SYS_F_IOCTL, errno);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int digest_cleanup(EVP_MD_CTX *ctx)
|
||||
{
|
||||
struct digest_ctx *digest_ctx =
|
||||
(struct digest_ctx *)EVP_MD_CTX_md_data(ctx);
|
||||
|
||||
if (close(digest_ctx->cfd) < 0) {
|
||||
SYSerr(SYS_F_CLOSE, errno);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Keep a table of known nids and associated methods.
|
||||
* Note that known_digest_nids[] isn't necessarily indexed the same way as
|
||||
* digest_data[] above, which known_digest_methods[] is.
|
||||
*/
|
||||
static int known_digest_nids[OSSL_NELEM(digest_data)];
|
||||
static int known_digest_nids_amount = -1; /* -1 indicates not yet initialised */
|
||||
static EVP_MD *known_digest_methods[OSSL_NELEM(digest_data)] = { NULL, };
|
||||
|
||||
static void prepare_digest_methods()
|
||||
{
|
||||
size_t i;
|
||||
struct session_op sess;
|
||||
int cfd;
|
||||
|
||||
if ((cfd = open("/dev/crypto", O_RDWR, 0)) < 0)
|
||||
return;
|
||||
|
||||
memset(&sess, 0, sizeof(sess));
|
||||
|
||||
for (i = 0, known_digest_nids_amount = 0; i < OSSL_NELEM(digest_data);
|
||||
i++) {
|
||||
|
||||
/*
|
||||
* Check that the algo is really availably by trying to open and close
|
||||
* a session.
|
||||
*/
|
||||
sess.mac = digest_data[i].devcryptoid;
|
||||
if (ioctl(cfd, CIOCGSESSION, &sess) < 0
|
||||
|| ioctl(cfd, CIOCFSESSION, &sess) < 0)
|
||||
continue;
|
||||
|
||||
if ((known_digest_methods[i] = EVP_MD_meth_new(digest_data[i].nid,
|
||||
NID_undef)) == NULL
|
||||
|| !EVP_MD_meth_set_result_size(known_digest_methods[i],
|
||||
digest_data[i].digestlen)
|
||||
|| !EVP_MD_meth_set_init(known_digest_methods[i], digest_init)
|
||||
|| !EVP_MD_meth_set_update(known_digest_methods[i], digest_update)
|
||||
|| !EVP_MD_meth_set_final(known_digest_methods[i], digest_final)
|
||||
|| !EVP_MD_meth_set_cleanup(known_digest_methods[i], digest_cleanup)
|
||||
|| !EVP_MD_meth_set_app_datasize(known_digest_methods[i],
|
||||
sizeof(struct digest_ctx))) {
|
||||
EVP_MD_meth_free(known_digest_methods[i]);
|
||||
known_digest_methods[i] = NULL;
|
||||
} else {
|
||||
known_digest_nids[known_digest_nids_amount++] = digest_data[i].nid;
|
||||
}
|
||||
}
|
||||
|
||||
close(cfd);
|
||||
}
|
||||
|
||||
static const EVP_MD *get_digest_method(int nid)
|
||||
{
|
||||
size_t i = get_digest_data_index(nid);
|
||||
|
||||
if (i == (size_t)-1)
|
||||
return NULL;
|
||||
return known_digest_methods[i];
|
||||
}
|
||||
|
||||
static int get_digest_nids(const int **nids)
|
||||
{
|
||||
*nids = known_digest_nids;
|
||||
return known_digest_nids_amount;
|
||||
}
|
||||
|
||||
static void destroy_digest_method(int nid)
|
||||
{
|
||||
size_t i = get_digest_data_index(nid);
|
||||
|
||||
EVP_MD_meth_free(known_digest_methods[i]);
|
||||
known_digest_methods[i] = NULL;
|
||||
}
|
||||
|
||||
static void destroy_all_digest_methods()
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < OSSL_NELEM(digest_data); i++)
|
||||
destroy_digest_method(digest_data[i].nid);
|
||||
}
|
||||
|
||||
static int devcrypto_digests(ENGINE *e, const EVP_MD **digest,
|
||||
const int **nids, int nid)
|
||||
{
|
||||
if (digest == NULL)
|
||||
return get_digest_nids(nids);
|
||||
|
||||
*digest = get_digest_method(nid);
|
||||
|
||||
return *digest != NULL;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* LOAD / UNLOAD
|
||||
*
|
||||
*****/
|
||||
|
||||
static int devcrypto_unload(ENGINE *e)
|
||||
{
|
||||
destroy_all_cipher_methods();
|
||||
#if defined(COP_FLAG_UPDATE) && defined(COP_FLAG_FINAL)
|
||||
destroy_all_digest_methods();
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
/*
|
||||
* This engine is always built into libcrypto, so it doesn't offer any
|
||||
* ability to be dynamically loadable.
|
||||
*/
|
||||
void engine_load_devcrypto_int()
|
||||
{
|
||||
ENGINE *e = NULL;
|
||||
|
||||
if (access("/dev/crypto", R_OK | W_OK) < 0) {
|
||||
fprintf(stderr,
|
||||
"/dev/crypto not present, not enabling devcrypto engine\n");
|
||||
return;
|
||||
}
|
||||
|
||||
prepare_cipher_methods();
|
||||
#if defined(COP_FLAG_UPDATE) && defined(COP_FLAG_FINAL)
|
||||
prepare_digest_methods();
|
||||
#endif
|
||||
|
||||
if ((e = ENGINE_new()) == NULL)
|
||||
return;
|
||||
|
||||
if (!ENGINE_set_id(e, "devcrypto")
|
||||
|| !ENGINE_set_name(e, "/dev/crypto engine")
|
||||
|| !ENGINE_set_destroy_function(e, devcrypto_unload)
|
||||
|
||||
/*
|
||||
* Asymmetric ciphers aren't well supported with /dev/crypto. Among the BSD
|
||||
* implementations, it seems to only exist in FreeBSD, and regarding the
|
||||
* parameters in its crypt_kop, the manual crypto(4) has this to say:
|
||||
*
|
||||
* The semantics of these arguments are currently undocumented.
|
||||
*
|
||||
* Reading through the FreeBSD source code doesn't give much more than
|
||||
* their CRK_MOD_EXP implementation for ubsec.
|
||||
*
|
||||
* It doesn't look much better with cryptodev-linux. They have the crypt_kop
|
||||
* structure as well as the command (CRK_*) in cryptodev.h, but no support
|
||||
* seems to be implemented at all for the moment.
|
||||
*
|
||||
* At the time of writing, it seems impossible to write proper support for
|
||||
* FreeBSD's asym features without some very deep knowledge and access to
|
||||
* specific kernel modules.
|
||||
*
|
||||
* /Richard Levitte, 2017-05-11
|
||||
*/
|
||||
#if 0
|
||||
# ifndef OPENSSL_NO_RSA
|
||||
|| !ENGINE_set_RSA(e, devcrypto_rsa)
|
||||
# endif
|
||||
# ifndef OPENSSL_NO_DSA
|
||||
|| !ENGINE_set_DSA(e, devcrypto_dsa)
|
||||
# endif
|
||||
# ifndef OPENSSL_NO_DH
|
||||
|| !ENGINE_set_DH(e, devcrypto_dh)
|
||||
# endif
|
||||
# ifndef OPENSSL_NO_EC
|
||||
|| !ENGINE_set_EC(e, devcrypto_ec)
|
||||
# endif
|
||||
#endif
|
||||
|| !ENGINE_set_ciphers(e, devcrypto_ciphers)
|
||||
#if defined(COP_FLAG_UPDATE) && defined(COP_FLAG_FINAL)
|
||||
|| !ENGINE_set_digests(e, devcrypto_digests)
|
||||
#endif
|
||||
) {
|
||||
ENGINE_free(e);
|
||||
return;
|
||||
}
|
||||
|
||||
ENGINE_add(e);
|
||||
ENGINE_free(e); /* Loose our local reference */
|
||||
ERR_clear_error();
|
||||
}
|
||||
+118
-90
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Generated by util/mkerr.pl DO NOT EDIT
|
||||
* Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 1995-2017 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
|
||||
@@ -8,103 +8,132 @@
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/engine.h>
|
||||
#include <openssl/engineerr.h>
|
||||
|
||||
/* BEGIN ERROR CODES */
|
||||
#ifndef OPENSSL_NO_ERR
|
||||
|
||||
# define ERR_FUNC(func) ERR_PACK(ERR_LIB_ENGINE,func,0)
|
||||
# define ERR_REASON(reason) ERR_PACK(ERR_LIB_ENGINE,0,reason)
|
||||
|
||||
static ERR_STRING_DATA ENGINE_str_functs[] = {
|
||||
{ERR_FUNC(ENGINE_F_DYNAMIC_CTRL), "dynamic_ctrl"},
|
||||
{ERR_FUNC(ENGINE_F_DYNAMIC_GET_DATA_CTX), "dynamic_get_data_ctx"},
|
||||
{ERR_FUNC(ENGINE_F_DYNAMIC_LOAD), "dynamic_load"},
|
||||
{ERR_FUNC(ENGINE_F_DYNAMIC_SET_DATA_CTX), "dynamic_set_data_ctx"},
|
||||
{ERR_FUNC(ENGINE_F_ENGINE_ADD), "ENGINE_add"},
|
||||
{ERR_FUNC(ENGINE_F_ENGINE_BY_ID), "ENGINE_by_id"},
|
||||
{ERR_FUNC(ENGINE_F_ENGINE_CMD_IS_EXECUTABLE), "ENGINE_cmd_is_executable"},
|
||||
{ERR_FUNC(ENGINE_F_ENGINE_CTRL), "ENGINE_ctrl"},
|
||||
{ERR_FUNC(ENGINE_F_ENGINE_CTRL_CMD), "ENGINE_ctrl_cmd"},
|
||||
{ERR_FUNC(ENGINE_F_ENGINE_CTRL_CMD_STRING), "ENGINE_ctrl_cmd_string"},
|
||||
{ERR_FUNC(ENGINE_F_ENGINE_FINISH), "ENGINE_finish"},
|
||||
{ERR_FUNC(ENGINE_F_ENGINE_GET_CIPHER), "ENGINE_get_cipher"},
|
||||
{ERR_FUNC(ENGINE_F_ENGINE_GET_DIGEST), "ENGINE_get_digest"},
|
||||
{ERR_FUNC(ENGINE_F_ENGINE_GET_FIRST), "ENGINE_get_first"},
|
||||
{ERR_FUNC(ENGINE_F_ENGINE_GET_LAST), "ENGINE_get_last"},
|
||||
{ERR_FUNC(ENGINE_F_ENGINE_GET_NEXT), "ENGINE_get_next"},
|
||||
{ERR_FUNC(ENGINE_F_ENGINE_GET_PKEY_ASN1_METH),
|
||||
static const ERR_STRING_DATA ENGINE_str_functs[] = {
|
||||
{ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_DIGEST_UPDATE, 0), "digest_update"},
|
||||
{ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_DYNAMIC_CTRL, 0), "dynamic_ctrl"},
|
||||
{ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_DYNAMIC_GET_DATA_CTX, 0),
|
||||
"dynamic_get_data_ctx"},
|
||||
{ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_DYNAMIC_LOAD, 0), "dynamic_load"},
|
||||
{ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_DYNAMIC_SET_DATA_CTX, 0),
|
||||
"dynamic_set_data_ctx"},
|
||||
{ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_ENGINE_ADD, 0), "ENGINE_add"},
|
||||
{ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_ENGINE_BY_ID, 0), "ENGINE_by_id"},
|
||||
{ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_ENGINE_CMD_IS_EXECUTABLE, 0),
|
||||
"ENGINE_cmd_is_executable"},
|
||||
{ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_ENGINE_CTRL, 0), "ENGINE_ctrl"},
|
||||
{ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_ENGINE_CTRL_CMD, 0), "ENGINE_ctrl_cmd"},
|
||||
{ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_ENGINE_CTRL_CMD_STRING, 0),
|
||||
"ENGINE_ctrl_cmd_string"},
|
||||
{ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_ENGINE_FINISH, 0), "ENGINE_finish"},
|
||||
{ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_ENGINE_GET_CIPHER, 0),
|
||||
"ENGINE_get_cipher"},
|
||||
{ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_ENGINE_GET_DIGEST, 0),
|
||||
"ENGINE_get_digest"},
|
||||
{ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_ENGINE_GET_FIRST, 0),
|
||||
"ENGINE_get_first"},
|
||||
{ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_ENGINE_GET_LAST, 0), "ENGINE_get_last"},
|
||||
{ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_ENGINE_GET_NEXT, 0), "ENGINE_get_next"},
|
||||
{ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_ENGINE_GET_PKEY_ASN1_METH, 0),
|
||||
"ENGINE_get_pkey_asn1_meth"},
|
||||
{ERR_FUNC(ENGINE_F_ENGINE_GET_PKEY_METH), "ENGINE_get_pkey_meth"},
|
||||
{ERR_FUNC(ENGINE_F_ENGINE_GET_PREV), "ENGINE_get_prev"},
|
||||
{ERR_FUNC(ENGINE_F_ENGINE_INIT), "ENGINE_init"},
|
||||
{ERR_FUNC(ENGINE_F_ENGINE_LIST_ADD), "engine_list_add"},
|
||||
{ERR_FUNC(ENGINE_F_ENGINE_LIST_REMOVE), "engine_list_remove"},
|
||||
{ERR_FUNC(ENGINE_F_ENGINE_LOAD_PRIVATE_KEY), "ENGINE_load_private_key"},
|
||||
{ERR_FUNC(ENGINE_F_ENGINE_LOAD_PUBLIC_KEY), "ENGINE_load_public_key"},
|
||||
{ERR_FUNC(ENGINE_F_ENGINE_LOAD_SSL_CLIENT_CERT),
|
||||
{ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_ENGINE_GET_PKEY_METH, 0),
|
||||
"ENGINE_get_pkey_meth"},
|
||||
{ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_ENGINE_GET_PREV, 0), "ENGINE_get_prev"},
|
||||
{ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_ENGINE_INIT, 0), "ENGINE_init"},
|
||||
{ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_ENGINE_LIST_ADD, 0), "engine_list_add"},
|
||||
{ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_ENGINE_LIST_REMOVE, 0),
|
||||
"engine_list_remove"},
|
||||
{ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_ENGINE_LOAD_PRIVATE_KEY, 0),
|
||||
"ENGINE_load_private_key"},
|
||||
{ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_ENGINE_LOAD_PUBLIC_KEY, 0),
|
||||
"ENGINE_load_public_key"},
|
||||
{ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_ENGINE_LOAD_SSL_CLIENT_CERT, 0),
|
||||
"ENGINE_load_ssl_client_cert"},
|
||||
{ERR_FUNC(ENGINE_F_ENGINE_NEW), "ENGINE_new"},
|
||||
{ERR_FUNC(ENGINE_F_ENGINE_PKEY_ASN1_FIND_STR),
|
||||
{ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_ENGINE_NEW, 0), "ENGINE_new"},
|
||||
{ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_ENGINE_PKEY_ASN1_FIND_STR, 0),
|
||||
"ENGINE_pkey_asn1_find_str"},
|
||||
{ERR_FUNC(ENGINE_F_ENGINE_REMOVE), "ENGINE_remove"},
|
||||
{ERR_FUNC(ENGINE_F_ENGINE_SET_DEFAULT_STRING),
|
||||
{ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_ENGINE_REMOVE, 0), "ENGINE_remove"},
|
||||
{ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_ENGINE_SET_DEFAULT_STRING, 0),
|
||||
"ENGINE_set_default_string"},
|
||||
{ERR_FUNC(ENGINE_F_ENGINE_SET_ID), "ENGINE_set_id"},
|
||||
{ERR_FUNC(ENGINE_F_ENGINE_SET_NAME), "ENGINE_set_name"},
|
||||
{ERR_FUNC(ENGINE_F_ENGINE_TABLE_REGISTER), "engine_table_register"},
|
||||
{ERR_FUNC(ENGINE_F_ENGINE_UNLOCKED_FINISH), "engine_unlocked_finish"},
|
||||
{ERR_FUNC(ENGINE_F_ENGINE_UP_REF), "ENGINE_up_ref"},
|
||||
{ERR_FUNC(ENGINE_F_INT_CTRL_HELPER), "int_ctrl_helper"},
|
||||
{ERR_FUNC(ENGINE_F_INT_ENGINE_CONFIGURE), "int_engine_configure"},
|
||||
{ERR_FUNC(ENGINE_F_INT_ENGINE_MODULE_INIT), "int_engine_module_init"},
|
||||
{ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_ENGINE_SET_ID, 0), "ENGINE_set_id"},
|
||||
{ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_ENGINE_SET_NAME, 0), "ENGINE_set_name"},
|
||||
{ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_ENGINE_TABLE_REGISTER, 0),
|
||||
"engine_table_register"},
|
||||
{ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_ENGINE_UNLOCKED_FINISH, 0),
|
||||
"engine_unlocked_finish"},
|
||||
{ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_ENGINE_UP_REF, 0), "ENGINE_up_ref"},
|
||||
{ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_INT_CTRL_HELPER, 0), "int_ctrl_helper"},
|
||||
{ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_INT_ENGINE_CONFIGURE, 0),
|
||||
"int_engine_configure"},
|
||||
{ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_INT_ENGINE_MODULE_INIT, 0),
|
||||
"int_engine_module_init"},
|
||||
{0, NULL}
|
||||
};
|
||||
|
||||
static ERR_STRING_DATA ENGINE_str_reasons[] = {
|
||||
{ERR_REASON(ENGINE_R_ALREADY_LOADED), "already loaded"},
|
||||
{ERR_REASON(ENGINE_R_ARGUMENT_IS_NOT_A_NUMBER),
|
||||
"argument is not a number"},
|
||||
{ERR_REASON(ENGINE_R_CMD_NOT_EXECUTABLE), "cmd not executable"},
|
||||
{ERR_REASON(ENGINE_R_COMMAND_TAKES_INPUT), "command takes input"},
|
||||
{ERR_REASON(ENGINE_R_COMMAND_TAKES_NO_INPUT), "command takes no input"},
|
||||
{ERR_REASON(ENGINE_R_CONFLICTING_ENGINE_ID), "conflicting engine id"},
|
||||
{ERR_REASON(ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED),
|
||||
"ctrl command not implemented"},
|
||||
{ERR_REASON(ENGINE_R_DSO_FAILURE), "DSO failure"},
|
||||
{ERR_REASON(ENGINE_R_DSO_NOT_FOUND), "dso not found"},
|
||||
{ERR_REASON(ENGINE_R_ENGINES_SECTION_ERROR), "engines section error"},
|
||||
{ERR_REASON(ENGINE_R_ENGINE_CONFIGURATION_ERROR),
|
||||
"engine configuration error"},
|
||||
{ERR_REASON(ENGINE_R_ENGINE_IS_NOT_IN_LIST), "engine is not in the list"},
|
||||
{ERR_REASON(ENGINE_R_ENGINE_SECTION_ERROR), "engine section error"},
|
||||
{ERR_REASON(ENGINE_R_FAILED_LOADING_PRIVATE_KEY),
|
||||
"failed loading private key"},
|
||||
{ERR_REASON(ENGINE_R_FAILED_LOADING_PUBLIC_KEY),
|
||||
"failed loading public key"},
|
||||
{ERR_REASON(ENGINE_R_FINISH_FAILED), "finish failed"},
|
||||
{ERR_REASON(ENGINE_R_ID_OR_NAME_MISSING), "'id' or 'name' missing"},
|
||||
{ERR_REASON(ENGINE_R_INIT_FAILED), "init failed"},
|
||||
{ERR_REASON(ENGINE_R_INTERNAL_LIST_ERROR), "internal list error"},
|
||||
{ERR_REASON(ENGINE_R_INVALID_ARGUMENT), "invalid argument"},
|
||||
{ERR_REASON(ENGINE_R_INVALID_CMD_NAME), "invalid cmd name"},
|
||||
{ERR_REASON(ENGINE_R_INVALID_CMD_NUMBER), "invalid cmd number"},
|
||||
{ERR_REASON(ENGINE_R_INVALID_INIT_VALUE), "invalid init value"},
|
||||
{ERR_REASON(ENGINE_R_INVALID_STRING), "invalid string"},
|
||||
{ERR_REASON(ENGINE_R_NOT_INITIALISED), "not initialised"},
|
||||
{ERR_REASON(ENGINE_R_NOT_LOADED), "not loaded"},
|
||||
{ERR_REASON(ENGINE_R_NO_CONTROL_FUNCTION), "no control function"},
|
||||
{ERR_REASON(ENGINE_R_NO_INDEX), "no index"},
|
||||
{ERR_REASON(ENGINE_R_NO_LOAD_FUNCTION), "no load function"},
|
||||
{ERR_REASON(ENGINE_R_NO_REFERENCE), "no reference"},
|
||||
{ERR_REASON(ENGINE_R_NO_SUCH_ENGINE), "no such engine"},
|
||||
{ERR_REASON(ENGINE_R_UNIMPLEMENTED_CIPHER), "unimplemented cipher"},
|
||||
{ERR_REASON(ENGINE_R_UNIMPLEMENTED_DIGEST), "unimplemented digest"},
|
||||
{ERR_REASON(ENGINE_R_UNIMPLEMENTED_PUBLIC_KEY_METHOD),
|
||||
"unimplemented public key method"},
|
||||
{ERR_REASON(ENGINE_R_VERSION_INCOMPATIBILITY), "version incompatibility"},
|
||||
static const ERR_STRING_DATA ENGINE_str_reasons[] = {
|
||||
{ERR_PACK(ERR_LIB_ENGINE, 0, ENGINE_R_ALREADY_LOADED), "already loaded"},
|
||||
{ERR_PACK(ERR_LIB_ENGINE, 0, ENGINE_R_ARGUMENT_IS_NOT_A_NUMBER),
|
||||
"argument is not a number"},
|
||||
{ERR_PACK(ERR_LIB_ENGINE, 0, ENGINE_R_CMD_NOT_EXECUTABLE),
|
||||
"cmd not executable"},
|
||||
{ERR_PACK(ERR_LIB_ENGINE, 0, ENGINE_R_COMMAND_TAKES_INPUT),
|
||||
"command takes input"},
|
||||
{ERR_PACK(ERR_LIB_ENGINE, 0, ENGINE_R_COMMAND_TAKES_NO_INPUT),
|
||||
"command takes no input"},
|
||||
{ERR_PACK(ERR_LIB_ENGINE, 0, ENGINE_R_CONFLICTING_ENGINE_ID),
|
||||
"conflicting engine id"},
|
||||
{ERR_PACK(ERR_LIB_ENGINE, 0, ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED),
|
||||
"ctrl command not implemented"},
|
||||
{ERR_PACK(ERR_LIB_ENGINE, 0, ENGINE_R_DSO_FAILURE), "DSO failure"},
|
||||
{ERR_PACK(ERR_LIB_ENGINE, 0, ENGINE_R_DSO_NOT_FOUND), "dso not found"},
|
||||
{ERR_PACK(ERR_LIB_ENGINE, 0, ENGINE_R_ENGINES_SECTION_ERROR),
|
||||
"engines section error"},
|
||||
{ERR_PACK(ERR_LIB_ENGINE, 0, ENGINE_R_ENGINE_CONFIGURATION_ERROR),
|
||||
"engine configuration error"},
|
||||
{ERR_PACK(ERR_LIB_ENGINE, 0, ENGINE_R_ENGINE_IS_NOT_IN_LIST),
|
||||
"engine is not in the list"},
|
||||
{ERR_PACK(ERR_LIB_ENGINE, 0, ENGINE_R_ENGINE_SECTION_ERROR),
|
||||
"engine section error"},
|
||||
{ERR_PACK(ERR_LIB_ENGINE, 0, ENGINE_R_FAILED_LOADING_PRIVATE_KEY),
|
||||
"failed loading private key"},
|
||||
{ERR_PACK(ERR_LIB_ENGINE, 0, ENGINE_R_FAILED_LOADING_PUBLIC_KEY),
|
||||
"failed loading public key"},
|
||||
{ERR_PACK(ERR_LIB_ENGINE, 0, ENGINE_R_FINISH_FAILED), "finish failed"},
|
||||
{ERR_PACK(ERR_LIB_ENGINE, 0, ENGINE_R_ID_OR_NAME_MISSING),
|
||||
"'id' or 'name' missing"},
|
||||
{ERR_PACK(ERR_LIB_ENGINE, 0, ENGINE_R_INIT_FAILED), "init failed"},
|
||||
{ERR_PACK(ERR_LIB_ENGINE, 0, ENGINE_R_INTERNAL_LIST_ERROR),
|
||||
"internal list error"},
|
||||
{ERR_PACK(ERR_LIB_ENGINE, 0, ENGINE_R_INVALID_ARGUMENT),
|
||||
"invalid argument"},
|
||||
{ERR_PACK(ERR_LIB_ENGINE, 0, ENGINE_R_INVALID_CMD_NAME),
|
||||
"invalid cmd name"},
|
||||
{ERR_PACK(ERR_LIB_ENGINE, 0, ENGINE_R_INVALID_CMD_NUMBER),
|
||||
"invalid cmd number"},
|
||||
{ERR_PACK(ERR_LIB_ENGINE, 0, ENGINE_R_INVALID_INIT_VALUE),
|
||||
"invalid init value"},
|
||||
{ERR_PACK(ERR_LIB_ENGINE, 0, ENGINE_R_INVALID_STRING), "invalid string"},
|
||||
{ERR_PACK(ERR_LIB_ENGINE, 0, ENGINE_R_NOT_INITIALISED), "not initialised"},
|
||||
{ERR_PACK(ERR_LIB_ENGINE, 0, ENGINE_R_NOT_LOADED), "not loaded"},
|
||||
{ERR_PACK(ERR_LIB_ENGINE, 0, ENGINE_R_NO_CONTROL_FUNCTION),
|
||||
"no control function"},
|
||||
{ERR_PACK(ERR_LIB_ENGINE, 0, ENGINE_R_NO_INDEX), "no index"},
|
||||
{ERR_PACK(ERR_LIB_ENGINE, 0, ENGINE_R_NO_LOAD_FUNCTION),
|
||||
"no load function"},
|
||||
{ERR_PACK(ERR_LIB_ENGINE, 0, ENGINE_R_NO_REFERENCE), "no reference"},
|
||||
{ERR_PACK(ERR_LIB_ENGINE, 0, ENGINE_R_NO_SUCH_ENGINE), "no such engine"},
|
||||
{ERR_PACK(ERR_LIB_ENGINE, 0, ENGINE_R_UNIMPLEMENTED_CIPHER),
|
||||
"unimplemented cipher"},
|
||||
{ERR_PACK(ERR_LIB_ENGINE, 0, ENGINE_R_UNIMPLEMENTED_DIGEST),
|
||||
"unimplemented digest"},
|
||||
{ERR_PACK(ERR_LIB_ENGINE, 0, ENGINE_R_UNIMPLEMENTED_PUBLIC_KEY_METHOD),
|
||||
"unimplemented public key method"},
|
||||
{ERR_PACK(ERR_LIB_ENGINE, 0, ENGINE_R_VERSION_INCOMPATIBILITY),
|
||||
"version incompatibility"},
|
||||
{0, NULL}
|
||||
};
|
||||
|
||||
@@ -113,10 +142,9 @@ static ERR_STRING_DATA ENGINE_str_reasons[] = {
|
||||
int ERR_load_ENGINE_strings(void)
|
||||
{
|
||||
#ifndef OPENSSL_NO_ERR
|
||||
|
||||
if (ERR_func_error_string(ENGINE_str_functs[0].error) == NULL) {
|
||||
ERR_load_strings(0, ENGINE_str_functs);
|
||||
ERR_load_strings(0, ENGINE_str_reasons);
|
||||
ERR_load_strings_const(ENGINE_str_functs);
|
||||
ERR_load_strings_const(ENGINE_str_reasons);
|
||||
}
|
||||
#endif
|
||||
return 1;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright 2001-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright (c) 2002, Oracle and/or its affiliates. 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
|
||||
@@ -7,12 +8,6 @@
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
/* ====================================================================
|
||||
* Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
|
||||
* ECDH support in OpenSSL originally developed by
|
||||
* SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
|
||||
*/
|
||||
|
||||
#include "eng_int.h"
|
||||
#include <openssl/conf.h>
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2001-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2001-2017 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
|
||||
@@ -7,6 +7,7 @@
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include "e_os.h"
|
||||
#include "eng_int.h"
|
||||
|
||||
/*
|
||||
|
||||
+6
-10
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright 2001-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright (c) 2002, Oracle and/or its affiliates. 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
|
||||
@@ -7,18 +8,13 @@
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
/* ====================================================================
|
||||
* Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
|
||||
* ECDH support in OpenSSL originally developed by
|
||||
* SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
|
||||
*/
|
||||
|
||||
#ifndef HEADER_ENGINE_INT_H
|
||||
# define HEADER_ENGINE_INT_H
|
||||
|
||||
# include "internal/cryptlib.h"
|
||||
# include <internal/engine.h>
|
||||
# include <internal/thread_once.h>
|
||||
# include "internal/engine.h"
|
||||
# include "internal/thread_once.h"
|
||||
# include "internal/refcount.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -103,7 +99,7 @@ void engine_table_doall(ENGINE_TABLE *table, engine_table_doall_cb *cb,
|
||||
*/
|
||||
int engine_unlocked_init(ENGINE *e);
|
||||
int engine_unlocked_finish(ENGINE *e, int unlock_for_handlers);
|
||||
int engine_free_util(ENGINE *e, int locked);
|
||||
int engine_free_util(ENGINE *e, int not_locked);
|
||||
|
||||
/*
|
||||
* This function will reset all "set"able values in an ENGINE to NULL. This
|
||||
@@ -156,7 +152,7 @@ struct engine_st {
|
||||
const ENGINE_CMD_DEFN *cmd_defns;
|
||||
int flags;
|
||||
/* reference count on the structure itself */
|
||||
int struct_ref;
|
||||
CRYPTO_REF_COUNT struct_ref;
|
||||
/*
|
||||
* reference count on usability of the engine type. NB: This controls the
|
||||
* loading and initialisation of any functionality required by this
|
||||
|
||||
+12
-6
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2001-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2001-2018 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
|
||||
@@ -7,8 +7,10 @@
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include "e_os.h"
|
||||
#include "eng_int.h"
|
||||
#include <openssl/rand.h>
|
||||
#include "internal/refcount.h"
|
||||
|
||||
CRYPTO_RWLOCK *global_engine_lock;
|
||||
|
||||
@@ -66,17 +68,21 @@ void engine_set_all_null(ENGINE *e)
|
||||
e->flags = 0;
|
||||
}
|
||||
|
||||
int engine_free_util(ENGINE *e, int locked)
|
||||
int engine_free_util(ENGINE *e, int not_locked)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (e == NULL)
|
||||
return 1;
|
||||
if (locked)
|
||||
#ifdef HAVE_ATOMICS
|
||||
CRYPTO_DOWN_REF(&e->struct_ref, &i, global_engine_lock);
|
||||
#else
|
||||
if (not_locked)
|
||||
CRYPTO_atomic_add(&e->struct_ref, -1, &i, global_engine_lock);
|
||||
else
|
||||
i = --e->struct_ref;
|
||||
engine_ref_debug(e, 0, -1)
|
||||
#endif
|
||||
engine_ref_debug(e, 0, -1);
|
||||
if (i > 0)
|
||||
return 1;
|
||||
REF_ASSERT_ISNT(i < 0);
|
||||
@@ -168,12 +174,12 @@ void engine_cleanup_int(void)
|
||||
|
||||
int ENGINE_set_ex_data(ENGINE *e, int idx, void *arg)
|
||||
{
|
||||
return (CRYPTO_set_ex_data(&e->ex_data, idx, arg));
|
||||
return CRYPTO_set_ex_data(&e->ex_data, idx, arg);
|
||||
}
|
||||
|
||||
void *ENGINE_get_ex_data(const ENGINE *e, int idx)
|
||||
{
|
||||
return (CRYPTO_get_ex_data(&e->ex_data, idx));
|
||||
return CRYPTO_get_ex_data(&e->ex_data, idx);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright 2001-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2001-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright (c) 2002, Oracle and/or its affiliates. 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
|
||||
@@ -7,19 +8,13 @@
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
/* ====================================================================
|
||||
* Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
|
||||
* ECDH support in OpenSSL originally developed by
|
||||
* SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
|
||||
*/
|
||||
|
||||
#include "eng_int.h"
|
||||
|
||||
/*
|
||||
* The linked-list of pointers to engine types. engine_list_head incorporates
|
||||
* an implicit structural reference but engine_list_tail does not - the
|
||||
* latter is a computational niceity and only points to something that is
|
||||
* already pointed to by its predecessor in the list (or engine_list_head
|
||||
* latter is a computational optimization and only points to something that
|
||||
* is already pointed to by its predecessor in the list (or engine_list_head
|
||||
* itself). In the same way, the use of the "prev" pointer in each ENGINE is
|
||||
* to save excessive list iteration, it doesn't correspond to an extra
|
||||
* structural reference. Hence, engine_list_head, and each non-null "next"
|
||||
@@ -322,7 +317,7 @@ ENGINE *ENGINE_by_id(const char *id)
|
||||
* Prevent infinite recursion if we're looking for the dynamic engine.
|
||||
*/
|
||||
if (strcmp(id, "dynamic")) {
|
||||
if ((load_dir = getenv("OPENSSL_ENGINES")) == 0)
|
||||
if ((load_dir = getenv("OPENSSL_ENGINES")) == NULL)
|
||||
load_dir = ENGINESDIR;
|
||||
iterator = ENGINE_by_id("dynamic");
|
||||
if (!iterator || !ENGINE_ctrl_cmd_string(iterator, "ID", id, 0) ||
|
||||
@@ -349,6 +344,6 @@ int ENGINE_up_ref(ENGINE *e)
|
||||
ENGINEerr(ENGINE_F_ENGINE_UP_REF, ERR_R_PASSED_NULL_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
CRYPTO_atomic_add(&e->struct_ref, 1, &i, global_engine_lock);
|
||||
CRYPTO_UP_REF(&e->struct_ref, &i, global_engine_lock);
|
||||
return 1;
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright 2001-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright (c) 2002, Oracle and/or its affiliates. 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
|
||||
@@ -7,16 +8,10 @@
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
/* ====================================================================
|
||||
* Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
|
||||
* ECDH support in OpenSSL originally developed by
|
||||
* SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <openssl/crypto.h>
|
||||
#include "internal/cryptlib.h"
|
||||
#include <internal/engine.h>
|
||||
#include "internal/engine.h"
|
||||
#include <openssl/pem.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/rand.h>
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <internal/engine.h>
|
||||
#include "internal/engine.h"
|
||||
#include <openssl/rand.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/crypto.h>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2001-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2001-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
|
||||
@@ -109,11 +109,6 @@ int engine_table_register(ENGINE_TABLE **table, ENGINE_CLEANUP_CB *cleanup,
|
||||
}
|
||||
fnd->funct = NULL;
|
||||
(void)lh_ENGINE_PILE_insert(&(*table)->piles, fnd);
|
||||
if (lh_ENGINE_PILE_retrieve(&(*table)->piles, &tmplate) != fnd) {
|
||||
sk_ENGINE_free(fnd->sk);
|
||||
OPENSSL_free(fnd);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
/* A registration shouldn't add duplicate entries */
|
||||
(void)sk_ENGINE_delete_ptr(fnd->sk, e);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2006-2017 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
|
||||
@@ -7,6 +7,7 @@
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include "e_os.h"
|
||||
#include "eng_int.h"
|
||||
#include <openssl/evp.h>
|
||||
#include "internal/asn1_int.h"
|
||||
|
||||
Reference in New Issue
Block a user