Adapt for BSD cryptodev.h differences
The BSD cryptodev.h doesn't have things like COP_FLAG_WRITE_IV and COP_FLAG_UPDATE. In that case, we need to implement that functionality ourselves. Reviewed-by: Matt Caswell <matt@openssl.org> (Merged from https://github.com/openssl/openssl/pull/3744)
This commit is contained in:
parent
619eb33a0c
commit
4f79affb05
4 changed files with 71 additions and 16 deletions
|
@ -161,6 +161,9 @@ static int cipher_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
|
||||||
struct cipher_ctx *cipher_ctx =
|
struct cipher_ctx *cipher_ctx =
|
||||||
(struct cipher_ctx *)EVP_CIPHER_CTX_get_cipher_data(ctx);
|
(struct cipher_ctx *)EVP_CIPHER_CTX_get_cipher_data(ctx);
|
||||||
struct crypt_op cryp;
|
struct crypt_op cryp;
|
||||||
|
#if !defined(COP_FLAG_WRITE_IV)
|
||||||
|
unsigned char saved_iv[EVP_MAX_IV_LENGTH];
|
||||||
|
#endif
|
||||||
|
|
||||||
memset(&cryp, 0, sizeof(cryp));
|
memset(&cryp, 0, sizeof(cryp));
|
||||||
cryp.ses = cipher_ctx->sess.ses;
|
cryp.ses = cipher_ctx->sess.ses;
|
||||||
|
@ -169,12 +172,39 @@ static int cipher_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
|
||||||
cryp.dst = (void *)out;
|
cryp.dst = (void *)out;
|
||||||
cryp.iv = (void *)EVP_CIPHER_CTX_iv_noconst(ctx);
|
cryp.iv = (void *)EVP_CIPHER_CTX_iv_noconst(ctx);
|
||||||
cryp.op = cipher_ctx->op;
|
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;
|
cryp.flags = COP_FLAG_WRITE_IV;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (ioctl(cipher_ctx->cfd, CIOCCRYPT, &cryp) < 0) {
|
if (ioctl(cipher_ctx->cfd, CIOCCRYPT, &cryp) < 0) {
|
||||||
SYSerr(SYS_F_IOCTL, errno);
|
SYSerr(SYS_F_IOCTL, errno);
|
||||||
return 0;
|
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;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -298,6 +328,14 @@ static int devcrypto_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
|
||||||
return *cipher != NULL;
|
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
|
* Digests
|
||||||
|
@ -395,18 +433,30 @@ static int digest_init(EVP_MD_CTX *ctx)
|
||||||
return 1;
|
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)
|
static int digest_update(EVP_MD_CTX *ctx, const void *data, size_t count)
|
||||||
{
|
{
|
||||||
struct digest_ctx *digest_ctx =
|
struct digest_ctx *digest_ctx =
|
||||||
(struct digest_ctx *)EVP_MD_CTX_md_data(ctx);
|
(struct digest_ctx *)EVP_MD_CTX_md_data(ctx);
|
||||||
struct crypt_op cryp;
|
|
||||||
|
|
||||||
memset(&cryp, 0, sizeof(cryp));
|
if (count == 0)
|
||||||
cryp.ses = digest_ctx->sess.ses;
|
return 1;
|
||||||
cryp.len = count;
|
|
||||||
cryp.src = (void *)data;
|
if (digest_op(digest_ctx, data, count, NULL, COP_FLAG_UPDATE) < 0) {
|
||||||
cryp.flags = COP_FLAG_UPDATE;
|
|
||||||
if (ioctl(digest_ctx->cfd, CIOCCRYPT, &cryp) < 0) {
|
|
||||||
SYSerr(SYS_F_IOCTL, errno);
|
SYSerr(SYS_F_IOCTL, errno);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -418,15 +468,8 @@ static int digest_final(EVP_MD_CTX *ctx, unsigned char *md)
|
||||||
{
|
{
|
||||||
struct digest_ctx *digest_ctx =
|
struct digest_ctx *digest_ctx =
|
||||||
(struct digest_ctx *)EVP_MD_CTX_md_data(ctx);
|
(struct digest_ctx *)EVP_MD_CTX_md_data(ctx);
|
||||||
struct crypt_op cryp;
|
|
||||||
|
|
||||||
memset(&cryp, 0, sizeof(cryp));
|
if (digest_op(digest_ctx, NULL, 0, md, COP_FLAG_FINAL) < 0) {
|
||||||
cryp.ses = digest_ctx->sess.ses;
|
|
||||||
cryp.len = 0;
|
|
||||||
cryp.src = NULL;
|
|
||||||
cryp.mac = (void *)md;
|
|
||||||
cryp.flags = COP_FLAG_FINAL;
|
|
||||||
if (ioctl(digest_ctx->cfd, CIOCCRYPT, &cryp) < 0) {
|
|
||||||
SYSerr(SYS_F_IOCTL, errno);
|
SYSerr(SYS_F_IOCTL, errno);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -545,6 +588,8 @@ static int devcrypto_digests(ENGINE *e, const EVP_MD **digest,
|
||||||
return *digest != NULL;
|
return *digest != NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
*
|
*
|
||||||
* LOAD / UNLOAD
|
* LOAD / UNLOAD
|
||||||
|
@ -554,7 +599,9 @@ static int devcrypto_digests(ENGINE *e, const EVP_MD **digest,
|
||||||
static int devcrypto_unload(ENGINE *e)
|
static int devcrypto_unload(ENGINE *e)
|
||||||
{
|
{
|
||||||
destroy_all_cipher_methods();
|
destroy_all_cipher_methods();
|
||||||
|
#if defined(COP_FLAG_UPDATE) && defined(COP_FLAG_FINAL)
|
||||||
destroy_all_digest_methods();
|
destroy_all_digest_methods();
|
||||||
|
#endif
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
|
@ -572,7 +619,9 @@ void engine_load_devcrypto_int()
|
||||||
}
|
}
|
||||||
|
|
||||||
prepare_cipher_methods();
|
prepare_cipher_methods();
|
||||||
|
#if defined(COP_FLAG_UPDATE) && defined(COP_FLAG_FINAL)
|
||||||
prepare_digest_methods();
|
prepare_digest_methods();
|
||||||
|
#endif
|
||||||
|
|
||||||
if ((e = ENGINE_new()) == NULL)
|
if ((e = ENGINE_new()) == NULL)
|
||||||
return;
|
return;
|
||||||
|
@ -595,7 +644,10 @@ void engine_load_devcrypto_int()
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|| !ENGINE_set_ciphers(e, devcrypto_ciphers)
|
|| !ENGINE_set_ciphers(e, devcrypto_ciphers)
|
||||||
|| !ENGINE_set_digests(e, devcrypto_digests)) {
|
#if defined(COP_FLAG_UPDATE) && defined(COP_FLAG_FINAL)
|
||||||
|
|| !ENGINE_set_digests(e, devcrypto_digests)
|
||||||
|
#endif
|
||||||
|
) {
|
||||||
ENGINE_free(e);
|
ENGINE_free(e);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
#ifndef OPENSSL_NO_ERR
|
#ifndef OPENSSL_NO_ERR
|
||||||
|
|
||||||
static const ERR_STRING_DATA ENGINE_str_functs[] = {
|
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_CTRL, 0), "dynamic_ctrl"},
|
||||||
{ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_DYNAMIC_GET_DATA_CTX, 0),
|
{ERR_PACK(ERR_LIB_ENGINE, ENGINE_F_DYNAMIC_GET_DATA_CTX, 0),
|
||||||
"dynamic_get_data_ctx"},
|
"dynamic_get_data_ctx"},
|
||||||
|
|
|
@ -589,6 +589,7 @@ EC_F_PKEY_EC_DERIVE:217:pkey_ec_derive
|
||||||
EC_F_PKEY_EC_KEYGEN:199:pkey_ec_keygen
|
EC_F_PKEY_EC_KEYGEN:199:pkey_ec_keygen
|
||||||
EC_F_PKEY_EC_PARAMGEN:219:pkey_ec_paramgen
|
EC_F_PKEY_EC_PARAMGEN:219:pkey_ec_paramgen
|
||||||
EC_F_PKEY_EC_SIGN:218:pkey_ec_sign
|
EC_F_PKEY_EC_SIGN:218:pkey_ec_sign
|
||||||
|
ENGINE_F_DIGEST_UPDATE:198:digest_update
|
||||||
ENGINE_F_DYNAMIC_CTRL:180:dynamic_ctrl
|
ENGINE_F_DYNAMIC_CTRL:180:dynamic_ctrl
|
||||||
ENGINE_F_DYNAMIC_GET_DATA_CTX:181:dynamic_get_data_ctx
|
ENGINE_F_DYNAMIC_GET_DATA_CTX:181:dynamic_get_data_ctx
|
||||||
ENGINE_F_DYNAMIC_LOAD:182:dynamic_load
|
ENGINE_F_DYNAMIC_LOAD:182:dynamic_load
|
||||||
|
|
|
@ -22,6 +22,7 @@ int ERR_load_ENGINE_strings(void);
|
||||||
/*
|
/*
|
||||||
* ENGINE function codes.
|
* ENGINE function codes.
|
||||||
*/
|
*/
|
||||||
|
# define ENGINE_F_DIGEST_UPDATE 198
|
||||||
# define ENGINE_F_DYNAMIC_CTRL 180
|
# define ENGINE_F_DYNAMIC_CTRL 180
|
||||||
# define ENGINE_F_DYNAMIC_GET_DATA_CTX 181
|
# define ENGINE_F_DYNAMIC_GET_DATA_CTX 181
|
||||||
# define ENGINE_F_DYNAMIC_LOAD 182
|
# define ENGINE_F_DYNAMIC_LOAD 182
|
||||||
|
|
Loading…
Reference in a new issue