Latest update.
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
LIBS=../../libcrypto
|
||||
$COMMON=digest.c evp_enc.c evp_lib.c evp_fetch.c cmeth_lib.c evp_utils.c
|
||||
$COMMON=digest.c evp_enc.c evp_lib.c evp_fetch.c cmeth_lib.c evp_utils.c \
|
||||
mac_lib.c mac_meth.c keymgmt_meth.c keymgmt_lib.c kdf_lib.c kdf_meth.c
|
||||
SOURCE[../../libcrypto]=$COMMON\
|
||||
encode.c evp_key.c evp_cnf.c \
|
||||
e_des.c e_bf.c e_idea.c e_des3.c e_camellia.c\
|
||||
@@ -10,12 +11,12 @@ SOURCE[../../libcrypto]=$COMMON\
|
||||
p_open.c p_seal.c p_sign.c p_verify.c p_lib.c p_enc.c p_dec.c \
|
||||
bio_md.c bio_b64.c bio_enc.c evp_err.c e_null.c \
|
||||
c_allc.c c_alld.c bio_ok.c \
|
||||
evp_pkey.c kdf_lib.c evp_pbe.c p5_crpt.c p5_crpt2.c pbe_scrypt.c \
|
||||
pkey_kdf.c c_allkdf.c \
|
||||
evp_pkey.c evp_pbe.c p5_crpt.c p5_crpt2.c pbe_scrypt.c \
|
||||
pkey_kdf.c \
|
||||
e_old.c pmeth_lib.c pmeth_fn.c pmeth_gn.c m_sigver.c \
|
||||
e_aes_cbc_hmac_sha1.c e_aes_cbc_hmac_sha256.c e_rc4_hmac_md5.c \
|
||||
e_chacha20_poly1305.c \
|
||||
mac_lib.c c_allm.c pkey_mac.c
|
||||
pkey_mac.c exchange.c
|
||||
SOURCE[../../providers/fips]=$COMMON
|
||||
|
||||
INCLUDE[e_aes.o]=.. ../modes
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
/*
|
||||
* Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (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 <openssl/evp.h>
|
||||
#include "internal/evp_int.h"
|
||||
|
||||
void openssl_add_all_kdfs_int(void)
|
||||
{
|
||||
EVP_add_kdf(&pbkdf2_kdf_meth);
|
||||
#ifndef OPENSSL_NO_SCRYPT
|
||||
EVP_add_kdf(&scrypt_kdf_meth);
|
||||
#endif
|
||||
EVP_add_kdf(&tls1_prf_kdf_meth);
|
||||
EVP_add_kdf(&hkdf_kdf_meth);
|
||||
EVP_add_kdf(&sshkdf_kdf_meth);
|
||||
EVP_add_kdf(&ss_kdf_meth);
|
||||
EVP_add_kdf(&x963_kdf_meth);
|
||||
#ifndef OPENSSL_NO_CMS
|
||||
EVP_add_kdf(&x942_kdf_meth);
|
||||
#endif
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
/*
|
||||
* Copyright 2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (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 <openssl/evp.h>
|
||||
#include "internal/evp_int.h"
|
||||
|
||||
void openssl_add_all_macs_int(void)
|
||||
{
|
||||
#ifndef OPENSSL_NO_BLAKE2
|
||||
EVP_add_mac(&blake2b_mac_meth);
|
||||
EVP_add_mac(&blake2s_mac_meth);
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_CMAC
|
||||
EVP_add_mac(&cmac_meth);
|
||||
#endif
|
||||
EVP_add_mac(&gmac_meth);
|
||||
EVP_add_mac(&hmac_meth);
|
||||
EVP_add_mac(&kmac128_meth);
|
||||
EVP_add_mac(&kmac256_meth);
|
||||
#ifndef OPENSSL_NO_SIPHASH
|
||||
EVP_add_mac(&siphash_meth);
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_POLY1305
|
||||
EVP_add_mac(&poly1305_meth);
|
||||
#endif
|
||||
}
|
||||
+39
-28
@@ -16,28 +16,29 @@
|
||||
|
||||
EVP_CIPHER *EVP_CIPHER_meth_new(int cipher_type, int block_size, int key_len)
|
||||
{
|
||||
EVP_CIPHER *cipher = OPENSSL_zalloc(sizeof(EVP_CIPHER));
|
||||
EVP_CIPHER *cipher = evp_cipher_new();
|
||||
|
||||
if (cipher != NULL) {
|
||||
cipher->nid = cipher_type;
|
||||
cipher->block_size = block_size;
|
||||
cipher->key_len = key_len;
|
||||
cipher->lock = CRYPTO_THREAD_lock_new();
|
||||
if (cipher->lock == NULL) {
|
||||
OPENSSL_free(cipher);
|
||||
return NULL;
|
||||
}
|
||||
cipher->refcnt = 1;
|
||||
}
|
||||
return cipher;
|
||||
}
|
||||
|
||||
EVP_CIPHER *EVP_CIPHER_meth_dup(const EVP_CIPHER *cipher)
|
||||
{
|
||||
EVP_CIPHER *to = EVP_CIPHER_meth_new(cipher->nid, cipher->block_size,
|
||||
cipher->key_len);
|
||||
EVP_CIPHER *to = NULL;
|
||||
|
||||
if (to != NULL) {
|
||||
/*
|
||||
* Non-legacy EVP_CIPHERs can't be duplicated like this.
|
||||
* Use EVP_CIPHER_up_ref() instead.
|
||||
*/
|
||||
if (cipher->prov != NULL)
|
||||
return NULL;
|
||||
|
||||
if ((to = EVP_CIPHER_meth_new(cipher->nid, cipher->block_size,
|
||||
cipher->key_len)) != NULL) {
|
||||
CRYPTO_RWLOCK *lock = to->lock;
|
||||
|
||||
memcpy(to, cipher, sizeof(*to));
|
||||
@@ -48,40 +49,32 @@ EVP_CIPHER *EVP_CIPHER_meth_dup(const EVP_CIPHER *cipher)
|
||||
|
||||
void EVP_CIPHER_meth_free(EVP_CIPHER *cipher)
|
||||
{
|
||||
if (cipher != NULL) {
|
||||
int i;
|
||||
|
||||
CRYPTO_DOWN_REF(&cipher->refcnt, &i, cipher->lock);
|
||||
if (i > 0)
|
||||
return;
|
||||
ossl_provider_free(cipher->prov);
|
||||
CRYPTO_THREAD_lock_free(cipher->lock);
|
||||
OPENSSL_free(cipher);
|
||||
}
|
||||
}
|
||||
|
||||
int EVP_CIPHER_up_ref(EVP_CIPHER *cipher)
|
||||
{
|
||||
int ref = 0;
|
||||
|
||||
CRYPTO_UP_REF(&cipher->refcnt, &ref, cipher->lock);
|
||||
return 1;
|
||||
EVP_CIPHER_free(cipher);
|
||||
}
|
||||
|
||||
int EVP_CIPHER_meth_set_iv_length(EVP_CIPHER *cipher, int iv_len)
|
||||
{
|
||||
if (cipher->iv_len != 0)
|
||||
return 0;
|
||||
|
||||
cipher->iv_len = iv_len;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int EVP_CIPHER_meth_set_flags(EVP_CIPHER *cipher, unsigned long flags)
|
||||
{
|
||||
if (cipher->flags != 0)
|
||||
return 0;
|
||||
|
||||
cipher->flags = flags;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int EVP_CIPHER_meth_set_impl_ctx_size(EVP_CIPHER *cipher, int ctx_size)
|
||||
{
|
||||
if (cipher->ctx_size != 0)
|
||||
return 0;
|
||||
|
||||
cipher->ctx_size = ctx_size;
|
||||
return 1;
|
||||
}
|
||||
@@ -92,6 +85,9 @@ int EVP_CIPHER_meth_set_init(EVP_CIPHER *cipher,
|
||||
const unsigned char *iv,
|
||||
int enc))
|
||||
{
|
||||
if (cipher->init != NULL)
|
||||
return 0;
|
||||
|
||||
cipher->init = init;
|
||||
return 1;
|
||||
}
|
||||
@@ -102,6 +98,9 @@ int EVP_CIPHER_meth_set_do_cipher(EVP_CIPHER *cipher,
|
||||
const unsigned char *in,
|
||||
size_t inl))
|
||||
{
|
||||
if (cipher->do_cipher != NULL)
|
||||
return 0;
|
||||
|
||||
cipher->do_cipher = do_cipher;
|
||||
return 1;
|
||||
}
|
||||
@@ -109,6 +108,9 @@ int EVP_CIPHER_meth_set_do_cipher(EVP_CIPHER *cipher,
|
||||
int EVP_CIPHER_meth_set_cleanup(EVP_CIPHER *cipher,
|
||||
int (*cleanup) (EVP_CIPHER_CTX *))
|
||||
{
|
||||
if (cipher->cleanup != NULL)
|
||||
return 0;
|
||||
|
||||
cipher->cleanup = cleanup;
|
||||
return 1;
|
||||
}
|
||||
@@ -117,6 +119,9 @@ int EVP_CIPHER_meth_set_set_asn1_params(EVP_CIPHER *cipher,
|
||||
int (*set_asn1_parameters) (EVP_CIPHER_CTX *,
|
||||
ASN1_TYPE *))
|
||||
{
|
||||
if (cipher->set_asn1_parameters != NULL)
|
||||
return 0;
|
||||
|
||||
cipher->set_asn1_parameters = set_asn1_parameters;
|
||||
return 1;
|
||||
}
|
||||
@@ -125,6 +130,9 @@ int EVP_CIPHER_meth_set_get_asn1_params(EVP_CIPHER *cipher,
|
||||
int (*get_asn1_parameters) (EVP_CIPHER_CTX *,
|
||||
ASN1_TYPE *))
|
||||
{
|
||||
if (cipher->get_asn1_parameters != NULL)
|
||||
return 0;
|
||||
|
||||
cipher->get_asn1_parameters = get_asn1_parameters;
|
||||
return 1;
|
||||
}
|
||||
@@ -133,6 +141,9 @@ int EVP_CIPHER_meth_set_ctrl(EVP_CIPHER *cipher,
|
||||
int (*ctrl) (EVP_CIPHER_CTX *, int type,
|
||||
int arg, void *ptr))
|
||||
{
|
||||
if (cipher->ctrl != NULL)
|
||||
return 0;
|
||||
|
||||
cipher->ctrl = ctrl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
+179
-73
@@ -86,7 +86,7 @@ void EVP_MD_CTX_free(EVP_MD_CTX *ctx)
|
||||
|
||||
EVP_MD_CTX_reset(ctx);
|
||||
|
||||
EVP_MD_meth_free(ctx->fetched_digest);
|
||||
EVP_MD_free(ctx->fetched_digest);
|
||||
ctx->fetched_digest = NULL;
|
||||
ctx->digest = NULL;
|
||||
ctx->reqdigest = NULL;
|
||||
@@ -156,7 +156,7 @@ int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl)
|
||||
|| (ctx->flags & EVP_MD_CTX_FLAG_NO_INIT) != 0) {
|
||||
if (ctx->digest == ctx->fetched_digest)
|
||||
ctx->digest = NULL;
|
||||
EVP_MD_meth_free(ctx->fetched_digest);
|
||||
EVP_MD_free(ctx->fetched_digest);
|
||||
ctx->fetched_digest = NULL;
|
||||
goto legacy;
|
||||
}
|
||||
@@ -181,7 +181,7 @@ int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl)
|
||||
return 0;
|
||||
}
|
||||
type = provmd;
|
||||
EVP_MD_meth_free(ctx->fetched_digest);
|
||||
EVP_MD_free(ctx->fetched_digest);
|
||||
ctx->fetched_digest = provmd;
|
||||
#endif
|
||||
}
|
||||
@@ -266,8 +266,13 @@ int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl)
|
||||
skip_to_init:
|
||||
#endif
|
||||
#ifndef FIPS_MODE
|
||||
/* TODO(3.0): Temporarily no support for EVP_DigestSign* in FIPS module */
|
||||
if (ctx->pctx != NULL) {
|
||||
/*
|
||||
* TODO(3.0): Temporarily no support for EVP_DigestSign* inside FIPS module
|
||||
* or when using providers.
|
||||
*/
|
||||
if (ctx->pctx != NULL
|
||||
&& (!EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx->pctx)
|
||||
|| ctx->pctx->op.sig.signature == NULL)) {
|
||||
int r;
|
||||
r = EVP_PKEY_CTX_ctrl(ctx->pctx, -1, EVP_PKEY_OP_TYPE_SIG,
|
||||
EVP_PKEY_CTRL_DIGESTINIT, 0, ctx);
|
||||
@@ -415,7 +420,7 @@ int EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in)
|
||||
|
||||
EVP_MD_CTX_reset(out);
|
||||
if (out->fetched_digest != NULL)
|
||||
EVP_MD_meth_free(out->fetched_digest);
|
||||
EVP_MD_free(out->fetched_digest);
|
||||
*out = *in;
|
||||
/* NULL out pointers in case of error */
|
||||
out->pctx = NULL;
|
||||
@@ -524,68 +529,139 @@ int EVP_Digest(const void *data, size_t count,
|
||||
return ret;
|
||||
}
|
||||
|
||||
int EVP_MD_get_params(const EVP_MD *digest, OSSL_PARAM params[])
|
||||
{
|
||||
if (digest != NULL && digest->get_params != NULL)
|
||||
return digest->get_params(params);
|
||||
return 0;
|
||||
}
|
||||
|
||||
const OSSL_PARAM *EVP_MD_gettable_params(const EVP_MD *digest)
|
||||
{
|
||||
if (digest != NULL && digest->gettable_params != NULL)
|
||||
return digest->gettable_params();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int EVP_MD_CTX_set_params(EVP_MD_CTX *ctx, const OSSL_PARAM params[])
|
||||
{
|
||||
if (ctx->digest != NULL && ctx->digest->set_params != NULL)
|
||||
return ctx->digest->set_params(ctx->provctx, params);
|
||||
if (ctx->digest != NULL && ctx->digest->set_ctx_params != NULL)
|
||||
return ctx->digest->set_ctx_params(ctx->provctx, params);
|
||||
return 0;
|
||||
}
|
||||
|
||||
const OSSL_PARAM *EVP_MD_CTX_settable_params(const EVP_MD *digest)
|
||||
{
|
||||
if (digest != NULL && digest->settable_ctx_params != NULL)
|
||||
return digest->settable_ctx_params();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int EVP_MD_CTX_get_params(EVP_MD_CTX *ctx, OSSL_PARAM params[])
|
||||
{
|
||||
if (ctx->digest != NULL && ctx->digest->get_params != NULL)
|
||||
return ctx->digest->get_params(ctx->provctx, params);
|
||||
return ctx->digest->get_ctx_params(ctx->provctx, params);
|
||||
return 0;
|
||||
}
|
||||
|
||||
const OSSL_PARAM *EVP_MD_CTX_gettable_params(const EVP_MD *digest)
|
||||
{
|
||||
if (digest != NULL && digest->gettable_ctx_params != NULL)
|
||||
return digest->gettable_ctx_params();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* TODO(3.0): Remove legacy code below - only used by engines & DigestSign */
|
||||
int EVP_MD_CTX_ctrl(EVP_MD_CTX *ctx, int cmd, int p1, void *p2)
|
||||
{
|
||||
if (ctx->digest != NULL) {
|
||||
if (ctx->digest->prov != NULL) {
|
||||
OSSL_PARAM params[2];
|
||||
size_t i, n = 0;
|
||||
int ret = EVP_CTRL_RET_UNSUPPORTED;
|
||||
int set_params = 1;
|
||||
size_t sz;
|
||||
OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END };
|
||||
|
||||
switch (cmd) {
|
||||
case EVP_MD_CTRL_XOF_LEN:
|
||||
if (ctx->digest->set_params == NULL)
|
||||
break;
|
||||
i = (size_t)p1;
|
||||
params[n++] =
|
||||
OSSL_PARAM_construct_size_t(OSSL_DIGEST_PARAM_XOFLEN, &i);
|
||||
params[n++] = OSSL_PARAM_construct_end();
|
||||
return ctx->digest->set_params(ctx->provctx, params);
|
||||
case EVP_MD_CTRL_MICALG:
|
||||
if (ctx->digest->get_params == NULL)
|
||||
break;
|
||||
params[n++] =
|
||||
OSSL_PARAM_construct_utf8_string(OSSL_DIGEST_PARAM_MICALG,
|
||||
p2, p1 ? p1 : 9999);
|
||||
params[n++] = OSSL_PARAM_construct_end();
|
||||
return ctx->digest->get_params(ctx->provctx, params);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/* legacy code */
|
||||
if (ctx->digest->md_ctrl != NULL) {
|
||||
int ret = ctx->digest->md_ctrl(ctx, cmd, p1, p2);
|
||||
if (ret <= 0)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
if (ctx == NULL || ctx->digest == NULL) {
|
||||
ERR_raise(ERR_LIB_EVP, EVP_R_MESSAGE_DIGEST_IS_NULL);
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
|
||||
if (ctx->digest->prov == NULL)
|
||||
goto legacy;
|
||||
|
||||
switch (cmd) {
|
||||
case EVP_MD_CTRL_XOF_LEN:
|
||||
sz = (size_t)p1;
|
||||
params[0] = OSSL_PARAM_construct_size_t(OSSL_DIGEST_PARAM_XOFLEN, &sz);
|
||||
break;
|
||||
case EVP_MD_CTRL_MICALG:
|
||||
set_params = 0;
|
||||
params[0] = OSSL_PARAM_construct_utf8_string(OSSL_DIGEST_PARAM_MICALG,
|
||||
p2, p1 ? p1 : 9999);
|
||||
break;
|
||||
default:
|
||||
return EVP_CTRL_RET_UNSUPPORTED;
|
||||
}
|
||||
|
||||
if (set_params)
|
||||
ret = evp_do_md_ctx_setparams(ctx->digest, ctx->provctx, params);
|
||||
else
|
||||
ret = evp_do_md_ctx_getparams(ctx->digest, ctx->provctx, params);
|
||||
return ret;
|
||||
|
||||
|
||||
/* TODO(3.0): Remove legacy code below */
|
||||
legacy:
|
||||
if (ctx->digest->md_ctrl == NULL) {
|
||||
ERR_raise(ERR_LIB_EVP, EVP_R_CTRL_NOT_IMPLEMENTED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = ctx->digest->md_ctrl(ctx, cmd, p1, p2);
|
||||
if (ret <= 0)
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void *evp_md_from_dispatch(const OSSL_DISPATCH *fns,
|
||||
OSSL_PROVIDER *prov)
|
||||
EVP_MD *evp_md_new(void)
|
||||
{
|
||||
EVP_MD *md = OPENSSL_zalloc(sizeof(*md));
|
||||
|
||||
if (md != NULL) {
|
||||
md->lock = CRYPTO_THREAD_lock_new();
|
||||
if (md->lock == NULL) {
|
||||
OPENSSL_free(md);
|
||||
return NULL;
|
||||
}
|
||||
md->refcnt = 1;
|
||||
}
|
||||
return md;
|
||||
}
|
||||
|
||||
static void *evp_md_from_dispatch(int name_id,
|
||||
const OSSL_DISPATCH *fns,
|
||||
OSSL_PROVIDER *prov, void *unused)
|
||||
{
|
||||
EVP_MD *md = NULL;
|
||||
int fncnt = 0;
|
||||
|
||||
/* EVP_MD_fetch() will set the legacy NID if available */
|
||||
if ((md = EVP_MD_meth_new(NID_undef, NID_undef)) == NULL)
|
||||
if ((md = evp_md_new()) == NULL) {
|
||||
EVPerr(0, ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
md->name_id = name_id;
|
||||
|
||||
#ifndef FIPS_MODE
|
||||
{
|
||||
/*
|
||||
* FIPS module note: since internal fetches will be entirely
|
||||
* provider based, we know that none of its code depends on legacy
|
||||
* NIDs or any functionality that use them.
|
||||
*
|
||||
* TODO(3.x) get rid of the need for legacy NIDs
|
||||
*/
|
||||
md->type = OBJ_sn2nid(evp_first_name(prov, name_id));
|
||||
}
|
||||
#endif
|
||||
|
||||
for (; fns->function_id != 0; fns++) {
|
||||
switch (fns->function_id) {
|
||||
@@ -628,34 +704,44 @@ static void *evp_md_from_dispatch(const OSSL_DISPATCH *fns,
|
||||
if (md->dupctx == NULL)
|
||||
md->dupctx = OSSL_get_OP_digest_dupctx(fns);
|
||||
break;
|
||||
case OSSL_FUNC_DIGEST_SIZE:
|
||||
if (md->size == NULL)
|
||||
md->size = OSSL_get_OP_digest_size(fns);
|
||||
break;
|
||||
case OSSL_FUNC_DIGEST_BLOCK_SIZE:
|
||||
if (md->dblock_size == NULL)
|
||||
md->dblock_size = OSSL_get_OP_digest_block_size(fns);
|
||||
break;
|
||||
case OSSL_FUNC_DIGEST_SET_PARAMS:
|
||||
if (md->set_params == NULL)
|
||||
md->set_params = OSSL_get_OP_digest_set_params(fns);
|
||||
break;
|
||||
case OSSL_FUNC_DIGEST_GET_PARAMS:
|
||||
if (md->get_params == NULL)
|
||||
md->get_params = OSSL_get_OP_digest_get_params(fns);
|
||||
break;
|
||||
case OSSL_FUNC_DIGEST_SET_CTX_PARAMS:
|
||||
if (md->set_ctx_params == NULL)
|
||||
md->set_ctx_params = OSSL_get_OP_digest_set_ctx_params(fns);
|
||||
break;
|
||||
case OSSL_FUNC_DIGEST_GET_CTX_PARAMS:
|
||||
if (md->get_ctx_params == NULL)
|
||||
md->get_ctx_params = OSSL_get_OP_digest_get_ctx_params(fns);
|
||||
break;
|
||||
case OSSL_FUNC_DIGEST_GETTABLE_PARAMS:
|
||||
if (md->gettable_params == NULL)
|
||||
md->gettable_params = OSSL_get_OP_digest_gettable_params(fns);
|
||||
break;
|
||||
case OSSL_FUNC_DIGEST_SETTABLE_CTX_PARAMS:
|
||||
if (md->settable_ctx_params == NULL)
|
||||
md->settable_ctx_params =
|
||||
OSSL_get_OP_digest_settable_ctx_params(fns);
|
||||
break;
|
||||
case OSSL_FUNC_DIGEST_GETTABLE_CTX_PARAMS:
|
||||
if (md->gettable_ctx_params == NULL)
|
||||
md->gettable_ctx_params =
|
||||
OSSL_get_OP_digest_gettable_ctx_params(fns);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ((fncnt != 0 && fncnt != 5)
|
||||
|| (fncnt == 0 && md->digest == NULL)
|
||||
|| md->size == NULL) {
|
||||
|| (fncnt == 0 && md->digest == NULL)) {
|
||||
/*
|
||||
* In order to be a consistent set of functions we either need the
|
||||
* whole set of init/update/final etc functions or none of them.
|
||||
* The "digest" function can standalone. We at least need one way to
|
||||
* generate digests.
|
||||
*/
|
||||
EVP_MD_meth_free(md);
|
||||
EVP_MD_free(md);
|
||||
ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_PROVIDER_FUNCTIONS);
|
||||
return NULL;
|
||||
}
|
||||
md->prov = prov;
|
||||
@@ -672,7 +758,7 @@ static int evp_md_up_ref(void *md)
|
||||
|
||||
static void evp_md_free(void *md)
|
||||
{
|
||||
EVP_MD_meth_free(md);
|
||||
EVP_MD_free(md);
|
||||
}
|
||||
|
||||
EVP_MD *EVP_MD_fetch(OPENSSL_CTX *ctx, const char *algorithm,
|
||||
@@ -680,20 +766,40 @@ EVP_MD *EVP_MD_fetch(OPENSSL_CTX *ctx, const char *algorithm,
|
||||
{
|
||||
EVP_MD *md =
|
||||
evp_generic_fetch(ctx, OSSL_OP_DIGEST, algorithm, properties,
|
||||
evp_md_from_dispatch, evp_md_up_ref,
|
||||
evp_md_from_dispatch, NULL, evp_md_up_ref,
|
||||
evp_md_free);
|
||||
|
||||
#ifndef FIPS_MODE
|
||||
/* TODO(3.x) get rid of the need for legacy NIDs */
|
||||
if (md != NULL) {
|
||||
/*
|
||||
* FIPS module note: since internal fetches will be entirely
|
||||
* provider based, we know that none of its code depends on legacy
|
||||
* NIDs or any functionality that use them.
|
||||
*/
|
||||
md->type = OBJ_sn2nid(algorithm);
|
||||
}
|
||||
#endif
|
||||
|
||||
return md;
|
||||
}
|
||||
|
||||
int EVP_MD_up_ref(EVP_MD *md)
|
||||
{
|
||||
int ref = 0;
|
||||
|
||||
CRYPTO_UP_REF(&md->refcnt, &ref, md->lock);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void EVP_MD_free(EVP_MD *md)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (md == NULL)
|
||||
return;
|
||||
|
||||
CRYPTO_DOWN_REF(&md->refcnt, &i, md->lock);
|
||||
if (i > 0)
|
||||
return;
|
||||
ossl_provider_free(md->prov);
|
||||
CRYPTO_THREAD_lock_free(md->lock);
|
||||
OPENSSL_free(md);
|
||||
}
|
||||
|
||||
void EVP_MD_do_all_ex(OPENSSL_CTX *libctx,
|
||||
void (*fn)(EVP_MD *mac, void *arg),
|
||||
void *arg)
|
||||
{
|
||||
evp_generic_do_all(libctx, OSSL_OP_DIGEST,
|
||||
(void (*)(void *, void *))fn, arg,
|
||||
evp_md_from_dispatch, NULL, evp_md_free);
|
||||
}
|
||||
+108
-464
@@ -19,7 +19,8 @@
|
||||
#include "internal/evp_int.h"
|
||||
#include "internal/cryptlib.h"
|
||||
#include "internal/modes_int.h"
|
||||
#include "modes_lcl.h"
|
||||
#include "internal/siv_int.h"
|
||||
#include "internal/ciphermode_platform.h"
|
||||
#include "evp_locl.h"
|
||||
|
||||
typedef struct {
|
||||
@@ -111,50 +112,6 @@ typedef struct {
|
||||
|
||||
#define MAXBITCHUNK ((size_t)1<<(sizeof(size_t)*8-4))
|
||||
|
||||
#ifdef VPAES_ASM
|
||||
int vpaes_set_encrypt_key(const unsigned char *userKey, int bits,
|
||||
AES_KEY *key);
|
||||
int vpaes_set_decrypt_key(const unsigned char *userKey, int bits,
|
||||
AES_KEY *key);
|
||||
|
||||
void vpaes_encrypt(const unsigned char *in, unsigned char *out,
|
||||
const AES_KEY *key);
|
||||
void vpaes_decrypt(const unsigned char *in, unsigned char *out,
|
||||
const AES_KEY *key);
|
||||
|
||||
void vpaes_cbc_encrypt(const unsigned char *in,
|
||||
unsigned char *out,
|
||||
size_t length,
|
||||
const AES_KEY *key, unsigned char *ivec, int enc);
|
||||
#endif
|
||||
#ifdef BSAES_ASM
|
||||
void bsaes_cbc_encrypt(const unsigned char *in, unsigned char *out,
|
||||
size_t length, const AES_KEY *key,
|
||||
unsigned char ivec[16], int enc);
|
||||
void bsaes_ctr32_encrypt_blocks(const unsigned char *in, unsigned char *out,
|
||||
size_t len, const AES_KEY *key,
|
||||
const unsigned char ivec[16]);
|
||||
void bsaes_xts_encrypt(const unsigned char *inp, unsigned char *out,
|
||||
size_t len, const AES_KEY *key1,
|
||||
const AES_KEY *key2, const unsigned char iv[16]);
|
||||
void bsaes_xts_decrypt(const unsigned char *inp, unsigned char *out,
|
||||
size_t len, const AES_KEY *key1,
|
||||
const AES_KEY *key2, const unsigned char iv[16]);
|
||||
#endif
|
||||
#ifdef AES_CTR_ASM
|
||||
void AES_ctr32_encrypt(const unsigned char *in, unsigned char *out,
|
||||
size_t blocks, const AES_KEY *key,
|
||||
const unsigned char ivec[AES_BLOCK_SIZE]);
|
||||
#endif
|
||||
#ifdef AES_XTS_ASM
|
||||
void AES_xts_encrypt(const unsigned char *inp, unsigned char *out, size_t len,
|
||||
const AES_KEY *key1, const AES_KEY *key2,
|
||||
const unsigned char iv[16]);
|
||||
void AES_xts_decrypt(const unsigned char *inp, unsigned char *out, size_t len,
|
||||
const AES_KEY *key1, const AES_KEY *key2,
|
||||
const unsigned char iv[16]);
|
||||
#endif
|
||||
|
||||
/* increment counter (64-bit int) by 1 */
|
||||
static void ctr64_inc(unsigned char *counter)
|
||||
{
|
||||
@@ -171,105 +128,10 @@ static void ctr64_inc(unsigned char *counter)
|
||||
} while (n);
|
||||
}
|
||||
|
||||
#if defined(OPENSSL_CPUID_OBJ) && (defined(__powerpc__) || defined(__ppc__) || defined(_ARCH_PPC))
|
||||
# include "ppc_arch.h"
|
||||
# ifdef VPAES_ASM
|
||||
# define VPAES_CAPABLE (OPENSSL_ppccap_P & PPC_ALTIVEC)
|
||||
# endif
|
||||
# define HWAES_CAPABLE (OPENSSL_ppccap_P & PPC_CRYPTO207)
|
||||
# define HWAES_set_encrypt_key aes_p8_set_encrypt_key
|
||||
# define HWAES_set_decrypt_key aes_p8_set_decrypt_key
|
||||
# define HWAES_encrypt aes_p8_encrypt
|
||||
# define HWAES_decrypt aes_p8_decrypt
|
||||
# define HWAES_cbc_encrypt aes_p8_cbc_encrypt
|
||||
# define HWAES_ctr32_encrypt_blocks aes_p8_ctr32_encrypt_blocks
|
||||
# define HWAES_xts_encrypt aes_p8_xts_encrypt
|
||||
# define HWAES_xts_decrypt aes_p8_xts_decrypt
|
||||
#endif
|
||||
|
||||
#if defined(AES_ASM) && !defined(I386_ONLY) && ( \
|
||||
((defined(__i386) || defined(__i386__) || \
|
||||
defined(_M_IX86)) && defined(OPENSSL_IA32_SSE2))|| \
|
||||
defined(__x86_64) || defined(__x86_64__) || \
|
||||
defined(_M_AMD64) || defined(_M_X64) )
|
||||
|
||||
extern unsigned int OPENSSL_ia32cap_P[];
|
||||
|
||||
# ifdef VPAES_ASM
|
||||
# define VPAES_CAPABLE (OPENSSL_ia32cap_P[1]&(1<<(41-32)))
|
||||
# endif
|
||||
# ifdef BSAES_ASM
|
||||
# define BSAES_CAPABLE (OPENSSL_ia32cap_P[1]&(1<<(41-32)))
|
||||
# endif
|
||||
/*
|
||||
* AES-NI section
|
||||
*/
|
||||
# define AESNI_CAPABLE (OPENSSL_ia32cap_P[1]&(1<<(57-32)))
|
||||
|
||||
int aesni_set_encrypt_key(const unsigned char *userKey, int bits,
|
||||
AES_KEY *key);
|
||||
int aesni_set_decrypt_key(const unsigned char *userKey, int bits,
|
||||
AES_KEY *key);
|
||||
|
||||
void aesni_encrypt(const unsigned char *in, unsigned char *out,
|
||||
const AES_KEY *key);
|
||||
void aesni_decrypt(const unsigned char *in, unsigned char *out,
|
||||
const AES_KEY *key);
|
||||
|
||||
void aesni_ecb_encrypt(const unsigned char *in,
|
||||
unsigned char *out,
|
||||
size_t length, const AES_KEY *key, int enc);
|
||||
void aesni_cbc_encrypt(const unsigned char *in,
|
||||
unsigned char *out,
|
||||
size_t length,
|
||||
const AES_KEY *key, unsigned char *ivec, int enc);
|
||||
|
||||
void aesni_ctr32_encrypt_blocks(const unsigned char *in,
|
||||
unsigned char *out,
|
||||
size_t blocks,
|
||||
const void *key, const unsigned char *ivec);
|
||||
|
||||
void aesni_xts_encrypt(const unsigned char *in,
|
||||
unsigned char *out,
|
||||
size_t length,
|
||||
const AES_KEY *key1, const AES_KEY *key2,
|
||||
const unsigned char iv[16]);
|
||||
|
||||
void aesni_xts_decrypt(const unsigned char *in,
|
||||
unsigned char *out,
|
||||
size_t length,
|
||||
const AES_KEY *key1, const AES_KEY *key2,
|
||||
const unsigned char iv[16]);
|
||||
|
||||
void aesni_ccm64_encrypt_blocks(const unsigned char *in,
|
||||
unsigned char *out,
|
||||
size_t blocks,
|
||||
const void *key,
|
||||
const unsigned char ivec[16],
|
||||
unsigned char cmac[16]);
|
||||
|
||||
void aesni_ccm64_decrypt_blocks(const unsigned char *in,
|
||||
unsigned char *out,
|
||||
size_t blocks,
|
||||
const void *key,
|
||||
const unsigned char ivec[16],
|
||||
unsigned char cmac[16]);
|
||||
|
||||
#if defined(AESNI_CAPABLE)
|
||||
# if defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD64) || defined(_M_X64)
|
||||
size_t aesni_gcm_encrypt(const unsigned char *in,
|
||||
unsigned char *out,
|
||||
size_t len,
|
||||
const void *key, unsigned char ivec[16], u64 *Xi);
|
||||
# define AES_gcm_encrypt aesni_gcm_encrypt
|
||||
size_t aesni_gcm_decrypt(const unsigned char *in,
|
||||
unsigned char *out,
|
||||
size_t len,
|
||||
const void *key, unsigned char ivec[16], u64 *Xi);
|
||||
# define AES_gcm_decrypt aesni_gcm_decrypt
|
||||
void gcm_ghash_avx(u64 Xi[2], const u128 Htable[16], const u8 *in,
|
||||
size_t len);
|
||||
# define AES_GCM_ASM(gctx) (gctx->ctr==aesni_ctr32_encrypt_blocks && \
|
||||
gctx->gcm.ghash==gcm_ghash_avx)
|
||||
# define AES_GCM_ASM2(gctx) (gctx->gcm.block==(block128_f)aesni_encrypt && \
|
||||
gctx->gcm.ghash==gcm_ghash_avx)
|
||||
# undef AES_GCM_ASM2 /* minor size optimization */
|
||||
@@ -405,7 +267,7 @@ static int aesni_xts_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
|
||||
|
||||
/*
|
||||
* Verify that the two keys are different.
|
||||
*
|
||||
*
|
||||
* This addresses Rogaway's vulnerability.
|
||||
* See comment in aes_xts_init_key() below.
|
||||
*/
|
||||
@@ -471,19 +333,6 @@ static int aesni_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
|
||||
const unsigned char *in, size_t len);
|
||||
|
||||
# ifndef OPENSSL_NO_OCB
|
||||
void aesni_ocb_encrypt(const unsigned char *in, unsigned char *out,
|
||||
size_t blocks, const void *key,
|
||||
size_t start_block_num,
|
||||
unsigned char offset_i[16],
|
||||
const unsigned char L_[][16],
|
||||
unsigned char checksum[16]);
|
||||
void aesni_ocb_decrypt(const unsigned char *in, unsigned char *out,
|
||||
size_t blocks, const void *key,
|
||||
size_t start_block_num,
|
||||
unsigned char offset_i[16],
|
||||
const unsigned char L_[][16],
|
||||
unsigned char checksum[16]);
|
||||
|
||||
static int aesni_ocb_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
|
||||
const unsigned char *iv, int enc)
|
||||
{
|
||||
@@ -584,81 +433,7 @@ static const EVP_CIPHER aes_##keylen##_##mode = { \
|
||||
const EVP_CIPHER *EVP_aes_##keylen##_##mode(void) \
|
||||
{ return AESNI_CAPABLE?&aesni_##keylen##_##mode:&aes_##keylen##_##mode; }
|
||||
|
||||
#elif defined(AES_ASM) && (defined(__sparc) || defined(__sparc__))
|
||||
|
||||
# include "sparc_arch.h"
|
||||
|
||||
extern unsigned int OPENSSL_sparcv9cap_P[];
|
||||
|
||||
/*
|
||||
* Initial Fujitsu SPARC64 X support
|
||||
*/
|
||||
# define HWAES_CAPABLE (OPENSSL_sparcv9cap_P[0] & SPARCV9_FJAESX)
|
||||
# define HWAES_set_encrypt_key aes_fx_set_encrypt_key
|
||||
# define HWAES_set_decrypt_key aes_fx_set_decrypt_key
|
||||
# define HWAES_encrypt aes_fx_encrypt
|
||||
# define HWAES_decrypt aes_fx_decrypt
|
||||
# define HWAES_cbc_encrypt aes_fx_cbc_encrypt
|
||||
# define HWAES_ctr32_encrypt_blocks aes_fx_ctr32_encrypt_blocks
|
||||
|
||||
# define SPARC_AES_CAPABLE (OPENSSL_sparcv9cap_P[1] & CFR_AES)
|
||||
|
||||
void aes_t4_set_encrypt_key(const unsigned char *key, int bits, AES_KEY *ks);
|
||||
void aes_t4_set_decrypt_key(const unsigned char *key, int bits, AES_KEY *ks);
|
||||
void aes_t4_encrypt(const unsigned char *in, unsigned char *out,
|
||||
const AES_KEY *key);
|
||||
void aes_t4_decrypt(const unsigned char *in, unsigned char *out,
|
||||
const AES_KEY *key);
|
||||
/*
|
||||
* Key-length specific subroutines were chosen for following reason.
|
||||
* Each SPARC T4 core can execute up to 8 threads which share core's
|
||||
* resources. Loading as much key material to registers allows to
|
||||
* minimize references to shared memory interface, as well as amount
|
||||
* of instructions in inner loops [much needed on T4]. But then having
|
||||
* non-key-length specific routines would require conditional branches
|
||||
* either in inner loops or on subroutines' entries. Former is hardly
|
||||
* acceptable, while latter means code size increase to size occupied
|
||||
* by multiple key-length specific subroutines, so why fight?
|
||||
*/
|
||||
void aes128_t4_cbc_encrypt(const unsigned char *in, unsigned char *out,
|
||||
size_t len, const AES_KEY *key,
|
||||
unsigned char *ivec);
|
||||
void aes128_t4_cbc_decrypt(const unsigned char *in, unsigned char *out,
|
||||
size_t len, const AES_KEY *key,
|
||||
unsigned char *ivec);
|
||||
void aes192_t4_cbc_encrypt(const unsigned char *in, unsigned char *out,
|
||||
size_t len, const AES_KEY *key,
|
||||
unsigned char *ivec);
|
||||
void aes192_t4_cbc_decrypt(const unsigned char *in, unsigned char *out,
|
||||
size_t len, const AES_KEY *key,
|
||||
unsigned char *ivec);
|
||||
void aes256_t4_cbc_encrypt(const unsigned char *in, unsigned char *out,
|
||||
size_t len, const AES_KEY *key,
|
||||
unsigned char *ivec);
|
||||
void aes256_t4_cbc_decrypt(const unsigned char *in, unsigned char *out,
|
||||
size_t len, const AES_KEY *key,
|
||||
unsigned char *ivec);
|
||||
void aes128_t4_ctr32_encrypt(const unsigned char *in, unsigned char *out,
|
||||
size_t blocks, const AES_KEY *key,
|
||||
unsigned char *ivec);
|
||||
void aes192_t4_ctr32_encrypt(const unsigned char *in, unsigned char *out,
|
||||
size_t blocks, const AES_KEY *key,
|
||||
unsigned char *ivec);
|
||||
void aes256_t4_ctr32_encrypt(const unsigned char *in, unsigned char *out,
|
||||
size_t blocks, const AES_KEY *key,
|
||||
unsigned char *ivec);
|
||||
void aes128_t4_xts_encrypt(const unsigned char *in, unsigned char *out,
|
||||
size_t blocks, const AES_KEY *key1,
|
||||
const AES_KEY *key2, const unsigned char *ivec);
|
||||
void aes128_t4_xts_decrypt(const unsigned char *in, unsigned char *out,
|
||||
size_t blocks, const AES_KEY *key1,
|
||||
const AES_KEY *key2, const unsigned char *ivec);
|
||||
void aes256_t4_xts_encrypt(const unsigned char *in, unsigned char *out,
|
||||
size_t blocks, const AES_KEY *key1,
|
||||
const AES_KEY *key2, const unsigned char *ivec);
|
||||
void aes256_t4_xts_decrypt(const unsigned char *in, unsigned char *out,
|
||||
size_t blocks, const AES_KEY *key1,
|
||||
const AES_KEY *key2, const unsigned char *ivec);
|
||||
#elif defined(SPARC_AES_CAPABLE)
|
||||
|
||||
static int aes_t4_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
|
||||
const unsigned char *iv, int enc)
|
||||
@@ -824,7 +599,7 @@ static int aes_t4_xts_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
|
||||
|
||||
/*
|
||||
* Verify that the two keys are different.
|
||||
*
|
||||
*
|
||||
* This addresses Rogaway's vulnerability.
|
||||
* See comment in aes_xts_init_key() below.
|
||||
*/
|
||||
@@ -1012,12 +787,8 @@ static const EVP_CIPHER aes_##keylen##_##mode = { \
|
||||
const EVP_CIPHER *EVP_aes_##keylen##_##mode(void) \
|
||||
{ return SPARC_AES_CAPABLE?&aes_t4_##keylen##_##mode:&aes_##keylen##_##mode; }
|
||||
|
||||
#elif defined(OPENSSL_CPUID_OBJ) && defined(__s390__)
|
||||
/*
|
||||
* IBM S390X support
|
||||
*/
|
||||
# include "s390x_arch.h"
|
||||
|
||||
#elif defined(S390X_aes_128_CAPABLE)
|
||||
/* IBM S390X support */
|
||||
typedef struct {
|
||||
union {
|
||||
OSSL_UNION_ALIGN;
|
||||
@@ -1170,25 +941,11 @@ typedef struct {
|
||||
} aes;
|
||||
} S390X_AES_CCM_CTX;
|
||||
|
||||
/* Convert key size to function code: [16,24,32] -> [18,19,20]. */
|
||||
# define S390X_AES_FC(keylen) (S390X_AES_128 + ((((keylen) << 3) - 128) >> 6))
|
||||
|
||||
/* Most modes of operation need km for partial block processing. */
|
||||
# define S390X_aes_128_CAPABLE (OPENSSL_s390xcap_P.km[0] & \
|
||||
S390X_CAPBIT(S390X_AES_128))
|
||||
# define S390X_aes_192_CAPABLE (OPENSSL_s390xcap_P.km[0] & \
|
||||
S390X_CAPBIT(S390X_AES_192))
|
||||
# define S390X_aes_256_CAPABLE (OPENSSL_s390xcap_P.km[0] & \
|
||||
S390X_CAPBIT(S390X_AES_256))
|
||||
|
||||
# define s390x_aes_init_key aes_init_key
|
||||
static int s390x_aes_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
|
||||
const unsigned char *iv, int enc);
|
||||
|
||||
# define S390X_aes_128_cbc_CAPABLE 1 /* checked by callee */
|
||||
# define S390X_aes_192_cbc_CAPABLE 1
|
||||
# define S390X_aes_256_cbc_CAPABLE 1
|
||||
# define S390X_AES_CBC_CTX EVP_AES_KEY
|
||||
# define S390X_AES_CBC_CTX EVP_AES_KEY
|
||||
|
||||
# define s390x_aes_cbc_init_key aes_init_key
|
||||
|
||||
@@ -1196,10 +953,6 @@ static int s390x_aes_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
|
||||
static int s390x_aes_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
|
||||
const unsigned char *in, size_t len);
|
||||
|
||||
# define S390X_aes_128_ecb_CAPABLE S390X_aes_128_CAPABLE
|
||||
# define S390X_aes_192_ecb_CAPABLE S390X_aes_192_CAPABLE
|
||||
# define S390X_aes_256_ecb_CAPABLE S390X_aes_256_CAPABLE
|
||||
|
||||
static int s390x_aes_ecb_init_key(EVP_CIPHER_CTX *ctx,
|
||||
const unsigned char *key,
|
||||
const unsigned char *iv, int enc)
|
||||
@@ -1224,16 +977,6 @@ static int s390x_aes_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
|
||||
return 1;
|
||||
}
|
||||
|
||||
# define S390X_aes_128_ofb_CAPABLE (S390X_aes_128_CAPABLE && \
|
||||
(OPENSSL_s390xcap_P.kmo[0] & \
|
||||
S390X_CAPBIT(S390X_AES_128)))
|
||||
# define S390X_aes_192_ofb_CAPABLE (S390X_aes_192_CAPABLE && \
|
||||
(OPENSSL_s390xcap_P.kmo[0] & \
|
||||
S390X_CAPBIT(S390X_AES_192)))
|
||||
# define S390X_aes_256_ofb_CAPABLE (S390X_aes_256_CAPABLE && \
|
||||
(OPENSSL_s390xcap_P.kmo[0] & \
|
||||
S390X_CAPBIT(S390X_AES_256)))
|
||||
|
||||
static int s390x_aes_ofb_init_key(EVP_CIPHER_CTX *ctx,
|
||||
const unsigned char *key,
|
||||
const unsigned char *ivec, int enc)
|
||||
@@ -1289,16 +1032,6 @@ static int s390x_aes_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
|
||||
return 1;
|
||||
}
|
||||
|
||||
# define S390X_aes_128_cfb_CAPABLE (S390X_aes_128_CAPABLE && \
|
||||
(OPENSSL_s390xcap_P.kmf[0] & \
|
||||
S390X_CAPBIT(S390X_AES_128)))
|
||||
# define S390X_aes_192_cfb_CAPABLE (S390X_aes_192_CAPABLE && \
|
||||
(OPENSSL_s390xcap_P.kmf[0] & \
|
||||
S390X_CAPBIT(S390X_AES_192)))
|
||||
# define S390X_aes_256_cfb_CAPABLE (S390X_aes_256_CAPABLE && \
|
||||
(OPENSSL_s390xcap_P.kmf[0] & \
|
||||
S390X_CAPBIT(S390X_AES_256)))
|
||||
|
||||
static int s390x_aes_cfb_init_key(EVP_CIPHER_CTX *ctx,
|
||||
const unsigned char *key,
|
||||
const unsigned char *ivec, int enc)
|
||||
@@ -1365,13 +1098,6 @@ static int s390x_aes_cfb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
|
||||
return 1;
|
||||
}
|
||||
|
||||
# define S390X_aes_128_cfb8_CAPABLE (OPENSSL_s390xcap_P.kmf[0] & \
|
||||
S390X_CAPBIT(S390X_AES_128))
|
||||
# define S390X_aes_192_cfb8_CAPABLE (OPENSSL_s390xcap_P.kmf[0] & \
|
||||
S390X_CAPBIT(S390X_AES_192))
|
||||
# define S390X_aes_256_cfb8_CAPABLE (OPENSSL_s390xcap_P.kmf[0] & \
|
||||
S390X_CAPBIT(S390X_AES_256))
|
||||
|
||||
static int s390x_aes_cfb8_init_key(EVP_CIPHER_CTX *ctx,
|
||||
const unsigned char *key,
|
||||
const unsigned char *ivec, int enc)
|
||||
@@ -1400,20 +1126,13 @@ static int s390x_aes_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
|
||||
return 1;
|
||||
}
|
||||
|
||||
# define S390X_aes_128_cfb1_CAPABLE 0
|
||||
# define S390X_aes_192_cfb1_CAPABLE 0
|
||||
# define S390X_aes_256_cfb1_CAPABLE 0
|
||||
|
||||
# define s390x_aes_cfb1_init_key aes_init_key
|
||||
|
||||
# define s390x_aes_cfb1_cipher aes_cfb1_cipher
|
||||
static int s390x_aes_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
|
||||
const unsigned char *in, size_t len);
|
||||
|
||||
# define S390X_aes_128_ctr_CAPABLE 1 /* checked by callee */
|
||||
# define S390X_aes_192_ctr_CAPABLE 1
|
||||
# define S390X_aes_256_ctr_CAPABLE 1
|
||||
# define S390X_AES_CTR_CTX EVP_AES_KEY
|
||||
# define S390X_AES_CTR_CTX EVP_AES_KEY
|
||||
|
||||
# define s390x_aes_ctr_init_key aes_init_key
|
||||
|
||||
@@ -1421,18 +1140,8 @@ static int s390x_aes_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
|
||||
static int s390x_aes_ctr_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
|
||||
const unsigned char *in, size_t len);
|
||||
|
||||
# define S390X_aes_128_gcm_CAPABLE (S390X_aes_128_CAPABLE && \
|
||||
(OPENSSL_s390xcap_P.kma[0] & \
|
||||
S390X_CAPBIT(S390X_AES_128)))
|
||||
# define S390X_aes_192_gcm_CAPABLE (S390X_aes_192_CAPABLE && \
|
||||
(OPENSSL_s390xcap_P.kma[0] & \
|
||||
S390X_CAPBIT(S390X_AES_192)))
|
||||
# define S390X_aes_256_gcm_CAPABLE (S390X_aes_256_CAPABLE && \
|
||||
(OPENSSL_s390xcap_P.kma[0] & \
|
||||
S390X_CAPBIT(S390X_AES_256)))
|
||||
|
||||
/* iv + padding length for iv lengths != 12 */
|
||||
# define S390X_gcm_ivpadlen(i) ((((i) + 15) >> 4 << 4) + 16)
|
||||
# define S390X_gcm_ivpadlen(i) ((((i) + 15) >> 4 << 4) + 16)
|
||||
|
||||
/*-
|
||||
* Process additional authenticated data. Returns 0 on success. Code is
|
||||
@@ -1625,7 +1334,7 @@ static int s390x_aes_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
|
||||
|
||||
switch (type) {
|
||||
case EVP_CTRL_INIT:
|
||||
ivlen = EVP_CIPHER_CTX_iv_length(c);
|
||||
ivlen = EVP_CIPHER_iv_length(c->cipher);
|
||||
iv = EVP_CIPHER_CTX_iv_noconst(c);
|
||||
gctx->key_set = 0;
|
||||
gctx->iv_set = 0;
|
||||
@@ -1636,6 +1345,10 @@ static int s390x_aes_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
|
||||
gctx->tls_aad_len = -1;
|
||||
return 1;
|
||||
|
||||
case EVP_CTRL_GET_IVLEN:
|
||||
*(int *)ptr = gctx->ivlen;
|
||||
return 1;
|
||||
|
||||
case EVP_CTRL_AEAD_SET_IVLEN:
|
||||
if (arg <= 0)
|
||||
return 0;
|
||||
@@ -1953,9 +1666,7 @@ static int s390x_aes_gcm_cleanup(EVP_CIPHER_CTX *c)
|
||||
return 1;
|
||||
}
|
||||
|
||||
# define S390X_AES_XTS_CTX EVP_AES_XTS_CTX
|
||||
# define S390X_aes_128_xts_CAPABLE 1 /* checked by callee */
|
||||
# define S390X_aes_256_xts_CAPABLE 1
|
||||
# define S390X_AES_XTS_CTX EVP_AES_XTS_CTX
|
||||
|
||||
# define s390x_aes_xts_init_key aes_xts_init_key
|
||||
static int s390x_aes_xts_init_key(EVP_CIPHER_CTX *ctx,
|
||||
@@ -1968,18 +1679,6 @@ static int s390x_aes_xts_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
|
||||
static int s390x_aes_xts_ctrl(EVP_CIPHER_CTX *, int type, int arg, void *ptr);
|
||||
# define s390x_aes_xts_cleanup aes_xts_cleanup
|
||||
|
||||
# define S390X_aes_128_ccm_CAPABLE (S390X_aes_128_CAPABLE && \
|
||||
(OPENSSL_s390xcap_P.kmac[0] & \
|
||||
S390X_CAPBIT(S390X_AES_128)))
|
||||
# define S390X_aes_192_ccm_CAPABLE (S390X_aes_192_CAPABLE && \
|
||||
(OPENSSL_s390xcap_P.kmac[0] & \
|
||||
S390X_CAPBIT(S390X_AES_192)))
|
||||
# define S390X_aes_256_ccm_CAPABLE (S390X_aes_256_CAPABLE && \
|
||||
(OPENSSL_s390xcap_P.kmac[0] & \
|
||||
S390X_CAPBIT(S390X_AES_256)))
|
||||
|
||||
# define S390X_CCM_AAD_FLAG 0x40
|
||||
|
||||
/*-
|
||||
* Set nonce and length fields. Code is big-endian.
|
||||
*/
|
||||
@@ -2092,13 +1791,13 @@ static int s390x_aes_ccm(S390X_AES_CCM_CTX *ctx, const unsigned char *in,
|
||||
ctx->aes.ccm.nonce.b[15] = 1;
|
||||
|
||||
if (n != len)
|
||||
return -1; /* length mismatch */
|
||||
return -1; /* length mismatch */
|
||||
|
||||
if (enc) {
|
||||
/* Two operations per block plus one for tag encryption */
|
||||
ctx->aes.ccm.blocks += (((len + 15) >> 4) << 1) + 1;
|
||||
if (ctx->aes.ccm.blocks > (1ULL << 61))
|
||||
return -2; /* too much data */
|
||||
return -2; /* too much data */
|
||||
}
|
||||
|
||||
num = 0;
|
||||
@@ -2147,7 +1846,7 @@ static int s390x_aes_ccm(S390X_AES_CCM_CTX *ctx, const unsigned char *in,
|
||||
ctx->aes.ccm.kmac_param.icv.g[0] ^= ctx->aes.ccm.buf.g[0];
|
||||
ctx->aes.ccm.kmac_param.icv.g[1] ^= ctx->aes.ccm.buf.g[1];
|
||||
|
||||
ctx->aes.ccm.nonce.b[0] = flags; /* restore flags field */
|
||||
ctx->aes.ccm.nonce.b[0] = flags; /* restore flags field */
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2358,6 +2057,10 @@ static int s390x_aes_ccm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
|
||||
cctx->aes.ccm.tls_aad_len = -1;
|
||||
return 1;
|
||||
|
||||
case EVP_CTRL_GET_IVLEN:
|
||||
*(int *)ptr = 15 - cctx->aes.ccm.l;
|
||||
return 1;
|
||||
|
||||
case EVP_CTRL_AEAD_TLS1_AAD:
|
||||
if (arg != EVP_AEAD_TLS1_AAD_LEN)
|
||||
return 0;
|
||||
@@ -2451,10 +2154,7 @@ static int s390x_aes_ccm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
|
||||
# define s390x_aes_ccm_cleanup aes_ccm_cleanup
|
||||
|
||||
# ifndef OPENSSL_NO_OCB
|
||||
# define S390X_AES_OCB_CTX EVP_AES_OCB_CTX
|
||||
# define S390X_aes_128_ocb_CAPABLE 0
|
||||
# define S390X_aes_192_ocb_CAPABLE 0
|
||||
# define S390X_aes_256_ocb_CAPABLE 0
|
||||
# define S390X_AES_OCB_CTX EVP_AES_OCB_CTX
|
||||
|
||||
# define s390x_aes_ocb_init_key aes_ocb_init_key
|
||||
static int s390x_aes_ocb_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
|
||||
@@ -2470,9 +2170,6 @@ static int s390x_aes_ocb_ctrl(EVP_CIPHER_CTX *, int type, int arg, void *ptr);
|
||||
|
||||
# ifndef OPENSSL_NO_SIV
|
||||
# define S390X_AES_SIV_CTX EVP_AES_SIV_CTX
|
||||
# define S390X_aes_128_siv_CAPABLE 0
|
||||
# define S390X_aes_192_siv_CAPABLE 0
|
||||
# define S390X_aes_256_siv_CAPABLE 0
|
||||
|
||||
# define s390x_aes_siv_init_key aes_siv_init_key
|
||||
# define s390x_aes_siv_cipher aes_siv_cipher
|
||||
@@ -2480,77 +2177,77 @@ static int s390x_aes_ocb_ctrl(EVP_CIPHER_CTX *, int type, int arg, void *ptr);
|
||||
# define s390x_aes_siv_ctrl aes_siv_ctrl
|
||||
# endif
|
||||
|
||||
# define BLOCK_CIPHER_generic(nid,keylen,blocksize,ivlen,nmode,mode, \
|
||||
MODE,flags) \
|
||||
static const EVP_CIPHER s390x_aes_##keylen##_##mode = { \
|
||||
nid##_##keylen##_##nmode,blocksize, \
|
||||
keylen / 8, \
|
||||
ivlen, \
|
||||
flags | EVP_CIPH_##MODE##_MODE, \
|
||||
s390x_aes_##mode##_init_key, \
|
||||
s390x_aes_##mode##_cipher, \
|
||||
NULL, \
|
||||
sizeof(S390X_AES_##MODE##_CTX), \
|
||||
NULL, \
|
||||
NULL, \
|
||||
NULL, \
|
||||
NULL \
|
||||
}; \
|
||||
static const EVP_CIPHER aes_##keylen##_##mode = { \
|
||||
nid##_##keylen##_##nmode, \
|
||||
blocksize, \
|
||||
keylen / 8, \
|
||||
ivlen, \
|
||||
flags | EVP_CIPH_##MODE##_MODE, \
|
||||
aes_init_key, \
|
||||
aes_##mode##_cipher, \
|
||||
NULL, \
|
||||
sizeof(EVP_AES_KEY), \
|
||||
NULL, \
|
||||
NULL, \
|
||||
NULL, \
|
||||
NULL \
|
||||
}; \
|
||||
const EVP_CIPHER *EVP_aes_##keylen##_##mode(void) \
|
||||
{ \
|
||||
return S390X_aes_##keylen##_##mode##_CAPABLE ? \
|
||||
&s390x_aes_##keylen##_##mode : &aes_##keylen##_##mode; \
|
||||
# define BLOCK_CIPHER_generic(nid,keylen,blocksize,ivlen,nmode,mode, \
|
||||
MODE,flags) \
|
||||
static const EVP_CIPHER s390x_aes_##keylen##_##mode = { \
|
||||
nid##_##keylen##_##nmode,blocksize, \
|
||||
keylen / 8, \
|
||||
ivlen, \
|
||||
flags | EVP_CIPH_##MODE##_MODE, \
|
||||
s390x_aes_##mode##_init_key, \
|
||||
s390x_aes_##mode##_cipher, \
|
||||
NULL, \
|
||||
sizeof(S390X_AES_##MODE##_CTX), \
|
||||
NULL, \
|
||||
NULL, \
|
||||
NULL, \
|
||||
NULL \
|
||||
}; \
|
||||
static const EVP_CIPHER aes_##keylen##_##mode = { \
|
||||
nid##_##keylen##_##nmode, \
|
||||
blocksize, \
|
||||
keylen / 8, \
|
||||
ivlen, \
|
||||
flags | EVP_CIPH_##MODE##_MODE, \
|
||||
aes_init_key, \
|
||||
aes_##mode##_cipher, \
|
||||
NULL, \
|
||||
sizeof(EVP_AES_KEY), \
|
||||
NULL, \
|
||||
NULL, \
|
||||
NULL, \
|
||||
NULL \
|
||||
}; \
|
||||
const EVP_CIPHER *EVP_aes_##keylen##_##mode(void) \
|
||||
{ \
|
||||
return S390X_aes_##keylen##_##mode##_CAPABLE ? \
|
||||
&s390x_aes_##keylen##_##mode : &aes_##keylen##_##mode; \
|
||||
}
|
||||
|
||||
# define BLOCK_CIPHER_custom(nid,keylen,blocksize,ivlen,mode,MODE,flags)\
|
||||
static const EVP_CIPHER s390x_aes_##keylen##_##mode = { \
|
||||
nid##_##keylen##_##mode, \
|
||||
blocksize, \
|
||||
(EVP_CIPH_##MODE##_MODE==EVP_CIPH_XTS_MODE||EVP_CIPH_##MODE##_MODE==EVP_CIPH_SIV_MODE ? 2 : 1) * keylen / 8, \
|
||||
ivlen, \
|
||||
flags | EVP_CIPH_##MODE##_MODE, \
|
||||
s390x_aes_##mode##_init_key, \
|
||||
s390x_aes_##mode##_cipher, \
|
||||
s390x_aes_##mode##_cleanup, \
|
||||
sizeof(S390X_AES_##MODE##_CTX), \
|
||||
NULL, \
|
||||
NULL, \
|
||||
s390x_aes_##mode##_ctrl, \
|
||||
NULL \
|
||||
}; \
|
||||
static const EVP_CIPHER aes_##keylen##_##mode = { \
|
||||
nid##_##keylen##_##mode,blocksize, \
|
||||
(EVP_CIPH_##MODE##_MODE==EVP_CIPH_XTS_MODE||EVP_CIPH_##MODE##_MODE==EVP_CIPH_SIV_MODE ? 2 : 1) * keylen / 8, \
|
||||
ivlen, \
|
||||
flags | EVP_CIPH_##MODE##_MODE, \
|
||||
aes_##mode##_init_key, \
|
||||
aes_##mode##_cipher, \
|
||||
aes_##mode##_cleanup, \
|
||||
sizeof(EVP_AES_##MODE##_CTX), \
|
||||
NULL, \
|
||||
NULL, \
|
||||
aes_##mode##_ctrl, \
|
||||
NULL \
|
||||
}; \
|
||||
const EVP_CIPHER *EVP_aes_##keylen##_##mode(void) \
|
||||
{ \
|
||||
return S390X_aes_##keylen##_##mode##_CAPABLE ? \
|
||||
&s390x_aes_##keylen##_##mode : &aes_##keylen##_##mode; \
|
||||
static const EVP_CIPHER s390x_aes_##keylen##_##mode = { \
|
||||
nid##_##keylen##_##mode, \
|
||||
blocksize, \
|
||||
(EVP_CIPH_##MODE##_MODE==EVP_CIPH_XTS_MODE||EVP_CIPH_##MODE##_MODE==EVP_CIPH_SIV_MODE ? 2 : 1) * keylen / 8, \
|
||||
ivlen, \
|
||||
flags | EVP_CIPH_##MODE##_MODE, \
|
||||
s390x_aes_##mode##_init_key, \
|
||||
s390x_aes_##mode##_cipher, \
|
||||
s390x_aes_##mode##_cleanup, \
|
||||
sizeof(S390X_AES_##MODE##_CTX), \
|
||||
NULL, \
|
||||
NULL, \
|
||||
s390x_aes_##mode##_ctrl, \
|
||||
NULL \
|
||||
}; \
|
||||
static const EVP_CIPHER aes_##keylen##_##mode = { \
|
||||
nid##_##keylen##_##mode,blocksize, \
|
||||
(EVP_CIPH_##MODE##_MODE==EVP_CIPH_XTS_MODE||EVP_CIPH_##MODE##_MODE==EVP_CIPH_SIV_MODE ? 2 : 1) * keylen / 8, \
|
||||
ivlen, \
|
||||
flags | EVP_CIPH_##MODE##_MODE, \
|
||||
aes_##mode##_init_key, \
|
||||
aes_##mode##_cipher, \
|
||||
aes_##mode##_cleanup, \
|
||||
sizeof(EVP_AES_##MODE##_CTX), \
|
||||
NULL, \
|
||||
NULL, \
|
||||
aes_##mode##_ctrl, \
|
||||
NULL \
|
||||
}; \
|
||||
const EVP_CIPHER *EVP_aes_##keylen##_##mode(void) \
|
||||
{ \
|
||||
return S390X_aes_##keylen##_##mode##_CAPABLE ? \
|
||||
&s390x_aes_##keylen##_##mode : &aes_##keylen##_##mode; \
|
||||
}
|
||||
|
||||
#else
|
||||
@@ -2583,48 +2280,6 @@ const EVP_CIPHER *EVP_aes_##keylen##_##mode(void) \
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(OPENSSL_CPUID_OBJ) && (defined(__arm__) || defined(__arm) || defined(__aarch64__))
|
||||
# include "arm_arch.h"
|
||||
# if __ARM_MAX_ARCH__>=7
|
||||
# if defined(BSAES_ASM)
|
||||
# define BSAES_CAPABLE (OPENSSL_armcap_P & ARMV7_NEON)
|
||||
# endif
|
||||
# if defined(VPAES_ASM)
|
||||
# define VPAES_CAPABLE (OPENSSL_armcap_P & ARMV7_NEON)
|
||||
# endif
|
||||
# define HWAES_CAPABLE (OPENSSL_armcap_P & ARMV8_AES)
|
||||
# define HWAES_set_encrypt_key aes_v8_set_encrypt_key
|
||||
# define HWAES_set_decrypt_key aes_v8_set_decrypt_key
|
||||
# define HWAES_encrypt aes_v8_encrypt
|
||||
# define HWAES_decrypt aes_v8_decrypt
|
||||
# define HWAES_cbc_encrypt aes_v8_cbc_encrypt
|
||||
# define HWAES_ctr32_encrypt_blocks aes_v8_ctr32_encrypt_blocks
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(HWAES_CAPABLE)
|
||||
int HWAES_set_encrypt_key(const unsigned char *userKey, const int bits,
|
||||
AES_KEY *key);
|
||||
int HWAES_set_decrypt_key(const unsigned char *userKey, const int bits,
|
||||
AES_KEY *key);
|
||||
void HWAES_encrypt(const unsigned char *in, unsigned char *out,
|
||||
const AES_KEY *key);
|
||||
void HWAES_decrypt(const unsigned char *in, unsigned char *out,
|
||||
const AES_KEY *key);
|
||||
void HWAES_cbc_encrypt(const unsigned char *in, unsigned char *out,
|
||||
size_t length, const AES_KEY *key,
|
||||
unsigned char *ivec, const int enc);
|
||||
void HWAES_ctr32_encrypt_blocks(const unsigned char *in, unsigned char *out,
|
||||
size_t len, const AES_KEY *key,
|
||||
const unsigned char ivec[16]);
|
||||
void HWAES_xts_encrypt(const unsigned char *inp, unsigned char *out,
|
||||
size_t len, const AES_KEY *key1,
|
||||
const AES_KEY *key2, const unsigned char iv[16]);
|
||||
void HWAES_xts_decrypt(const unsigned char *inp, unsigned char *out,
|
||||
size_t len, const AES_KEY *key1,
|
||||
const AES_KEY *key2, const unsigned char iv[16]);
|
||||
#endif
|
||||
|
||||
#define BLOCK_CIPHER_generic_pack(nid,keylen,flags) \
|
||||
BLOCK_CIPHER_generic(nid,keylen,16,16,cbc,cbc,CBC,flags|EVP_CIPH_FLAG_DEFAULT_ASN1) \
|
||||
BLOCK_CIPHER_generic(nid,keylen,16,0,ecb,ecb,ECB,flags|EVP_CIPH_FLAG_DEFAULT_ASN1) \
|
||||
@@ -2889,13 +2544,17 @@ static int aes_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
|
||||
case EVP_CTRL_INIT:
|
||||
gctx->key_set = 0;
|
||||
gctx->iv_set = 0;
|
||||
gctx->ivlen = c->cipher->iv_len;
|
||||
gctx->ivlen = EVP_CIPHER_iv_length(c->cipher);
|
||||
gctx->iv = c->iv;
|
||||
gctx->taglen = -1;
|
||||
gctx->iv_gen = 0;
|
||||
gctx->tls_aad_len = -1;
|
||||
return 1;
|
||||
|
||||
case EVP_CTRL_GET_IVLEN:
|
||||
*(int *)ptr = gctx->ivlen;
|
||||
return 1;
|
||||
|
||||
case EVP_CTRL_AEAD_SET_IVLEN:
|
||||
if (arg <= 0)
|
||||
return 0;
|
||||
@@ -3408,7 +3067,7 @@ static int aes_gcm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
|
||||
#define CUSTOM_FLAGS (EVP_CIPH_FLAG_DEFAULT_ASN1 \
|
||||
| EVP_CIPH_CUSTOM_IV | EVP_CIPH_FLAG_CUSTOM_CIPHER \
|
||||
| EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CTRL_INIT \
|
||||
| EVP_CIPH_CUSTOM_COPY)
|
||||
| EVP_CIPH_CUSTOM_COPY | EVP_CIPH_CUSTOM_IV_LENGTH)
|
||||
|
||||
BLOCK_CIPHER_custom(NID_aes, 128, 1, 12, gcm, GCM,
|
||||
EVP_CIPH_FLAG_AEAD_CIPHER | CUSTOM_FLAGS)
|
||||
@@ -3613,6 +3272,10 @@ static int aes_ccm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
|
||||
cctx->tls_aad_len = -1;
|
||||
return 1;
|
||||
|
||||
case EVP_CTRL_GET_IVLEN:
|
||||
*(int *)ptr = 15 - cctx->L;
|
||||
return 1;
|
||||
|
||||
case EVP_CTRL_AEAD_TLS1_AAD:
|
||||
/* Save the AAD for later use */
|
||||
if (arg != EVP_AEAD_TLS1_AAD_LEN)
|
||||
@@ -4061,13 +3724,17 @@ static int aes_ocb_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
|
||||
case EVP_CTRL_INIT:
|
||||
octx->key_set = 0;
|
||||
octx->iv_set = 0;
|
||||
octx->ivlen = EVP_CIPHER_CTX_iv_length(c);
|
||||
octx->ivlen = EVP_CIPHER_iv_length(c->cipher);
|
||||
octx->iv = EVP_CIPHER_CTX_iv_noconst(c);
|
||||
octx->taglen = 16;
|
||||
octx->data_buf_len = 0;
|
||||
octx->aad_buf_len = 0;
|
||||
return 1;
|
||||
|
||||
case EVP_CTRL_GET_IVLEN:
|
||||
*(int *)ptr = octx->ivlen;
|
||||
return 1;
|
||||
|
||||
case EVP_CTRL_AEAD_SET_IVLEN:
|
||||
/* IV len must be 1 to 15 */
|
||||
if (arg <= 0 || arg > 15)
|
||||
@@ -4110,29 +3777,6 @@ static int aes_ocb_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
|
||||
}
|
||||
}
|
||||
|
||||
# ifdef HWAES_CAPABLE
|
||||
# ifdef HWAES_ocb_encrypt
|
||||
void HWAES_ocb_encrypt(const unsigned char *in, unsigned char *out,
|
||||
size_t blocks, const void *key,
|
||||
size_t start_block_num,
|
||||
unsigned char offset_i[16],
|
||||
const unsigned char L_[][16],
|
||||
unsigned char checksum[16]);
|
||||
# else
|
||||
# define HWAES_ocb_encrypt ((ocb128_f)NULL)
|
||||
# endif
|
||||
# ifdef HWAES_ocb_decrypt
|
||||
void HWAES_ocb_decrypt(const unsigned char *in, unsigned char *out,
|
||||
size_t blocks, const void *key,
|
||||
size_t start_block_num,
|
||||
unsigned char offset_i[16],
|
||||
const unsigned char L_[][16],
|
||||
unsigned char checksum[16]);
|
||||
# else
|
||||
# define HWAES_ocb_decrypt ((ocb128_f)NULL)
|
||||
# endif
|
||||
# endif
|
||||
|
||||
static int aes_ocb_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
|
||||
const unsigned char *iv, int enc)
|
||||
{
|
||||
|
||||
@@ -7,17 +7,16 @@
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <openssl/opensslconf.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/opensslconf.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/objects.h>
|
||||
#include <openssl/aes.h>
|
||||
#include <openssl/sha.h>
|
||||
#include <openssl/rand.h>
|
||||
#include "modes_lcl.h"
|
||||
#include "internal/cryptlib.h"
|
||||
#include "internal/modes_int.h"
|
||||
#include "internal/evp_int.h"
|
||||
#include "internal/constant_time_locl.h"
|
||||
|
||||
@@ -37,7 +36,6 @@ typedef struct {
|
||||
defined(__x86_64) || defined(__x86_64__) || \
|
||||
defined(_M_AMD64) || defined(_M_X64) )
|
||||
|
||||
extern unsigned int OPENSSL_ia32cap_P[];
|
||||
# define AESNI_CAPABLE (1<<(57-32))
|
||||
|
||||
int aesni_set_encrypt_key(const unsigned char *userKey, int bits,
|
||||
|
||||
@@ -7,18 +7,16 @@
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <openssl/opensslconf.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
#include <openssl/opensslconf.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/objects.h>
|
||||
#include <openssl/aes.h>
|
||||
#include <openssl/sha.h>
|
||||
#include <openssl/rand.h>
|
||||
#include "modes_lcl.h"
|
||||
#include "internal/cryptlib.h"
|
||||
#include "internal/modes_int.h"
|
||||
#include "internal/constant_time_locl.h"
|
||||
#include "internal/evp_int.h"
|
||||
|
||||
@@ -38,7 +36,6 @@ typedef struct {
|
||||
defined(__x86_64) || defined(__x86_64__) || \
|
||||
defined(_M_AMD64) || defined(_M_X64) )
|
||||
|
||||
extern unsigned int OPENSSL_ia32cap_P[];
|
||||
# define AESNI_CAPABLE (1<<(57-32))
|
||||
|
||||
int aesni_set_encrypt_key(const unsigned char *userKey, int bits,
|
||||
|
||||
+12
-3
@@ -16,7 +16,7 @@
|
||||
# include <openssl/rand_drbg.h>
|
||||
# include "internal/aria.h"
|
||||
# include "internal/evp_int.h"
|
||||
# include "modes_lcl.h"
|
||||
# include "internal/modes_int.h"
|
||||
# include "evp_locl.h"
|
||||
|
||||
/* ARIA subkey Structure */
|
||||
@@ -252,13 +252,17 @@ static int aria_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
|
||||
case EVP_CTRL_INIT:
|
||||
gctx->key_set = 0;
|
||||
gctx->iv_set = 0;
|
||||
gctx->ivlen = EVP_CIPHER_CTX_iv_length(c);
|
||||
gctx->ivlen = EVP_CIPHER_iv_length(c->cipher);
|
||||
gctx->iv = EVP_CIPHER_CTX_iv_noconst(c);
|
||||
gctx->taglen = -1;
|
||||
gctx->iv_gen = 0;
|
||||
gctx->tls_aad_len = -1;
|
||||
return 1;
|
||||
|
||||
case EVP_CTRL_GET_IVLEN:
|
||||
*(int *)ptr = gctx->ivlen;
|
||||
return 1;
|
||||
|
||||
case EVP_CTRL_AEAD_SET_IVLEN:
|
||||
if (arg <= 0)
|
||||
return 0;
|
||||
@@ -539,6 +543,10 @@ static int aria_ccm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
|
||||
cctx->tls_aad_len = -1;
|
||||
return 1;
|
||||
|
||||
case EVP_CTRL_GET_IVLEN:
|
||||
*(int *)ptr = 15 - cctx->L;
|
||||
return 1;
|
||||
|
||||
case EVP_CTRL_AEAD_TLS1_AAD:
|
||||
/* Save the AAD for later use */
|
||||
if (arg != EVP_AEAD_TLS1_AAD_LEN)
|
||||
@@ -742,7 +750,8 @@ static int aria_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
|
||||
#define ARIA_AUTH_FLAGS (EVP_CIPH_FLAG_DEFAULT_ASN1 \
|
||||
| EVP_CIPH_CUSTOM_IV | EVP_CIPH_FLAG_CUSTOM_CIPHER \
|
||||
| EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CTRL_INIT \
|
||||
| EVP_CIPH_CUSTOM_COPY | EVP_CIPH_FLAG_AEAD_CIPHER)
|
||||
| EVP_CIPH_CUSTOM_COPY | EVP_CIPH_FLAG_AEAD_CIPHER \
|
||||
| EVP_CIPH_CUSTOM_IV_LENGTH)
|
||||
|
||||
#define BLOCK_CIPHER_aead(nid,keylen,blocksize,ivlen,nmode,mode,MODE,flags) \
|
||||
static const EVP_CIPHER aria_##keylen##_##mode = { \
|
||||
|
||||
+2
-29
@@ -18,7 +18,8 @@ NON_EMPTY_TRANSLATION_UNIT
|
||||
# include <assert.h>
|
||||
# include <openssl/camellia.h>
|
||||
# include "internal/evp_int.h"
|
||||
# include "modes_lcl.h"
|
||||
# include "internal/modes_int.h"
|
||||
# include "internal/ciphermode_platform.h"
|
||||
|
||||
static int camellia_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
|
||||
const unsigned char *iv, int enc);
|
||||
@@ -43,34 +44,6 @@ typedef struct {
|
||||
* assembler support was in general requested... */
|
||||
# include "sparc_arch.h"
|
||||
|
||||
extern unsigned int OPENSSL_sparcv9cap_P[];
|
||||
|
||||
# define SPARC_CMLL_CAPABLE (OPENSSL_sparcv9cap_P[1] & CFR_CAMELLIA)
|
||||
|
||||
void cmll_t4_set_key(const unsigned char *key, int bits, CAMELLIA_KEY *ks);
|
||||
void cmll_t4_encrypt(const unsigned char *in, unsigned char *out,
|
||||
const CAMELLIA_KEY *key);
|
||||
void cmll_t4_decrypt(const unsigned char *in, unsigned char *out,
|
||||
const CAMELLIA_KEY *key);
|
||||
|
||||
void cmll128_t4_cbc_encrypt(const unsigned char *in, unsigned char *out,
|
||||
size_t len, const CAMELLIA_KEY *key,
|
||||
unsigned char *ivec);
|
||||
void cmll128_t4_cbc_decrypt(const unsigned char *in, unsigned char *out,
|
||||
size_t len, const CAMELLIA_KEY *key,
|
||||
unsigned char *ivec);
|
||||
void cmll256_t4_cbc_encrypt(const unsigned char *in, unsigned char *out,
|
||||
size_t len, const CAMELLIA_KEY *key,
|
||||
unsigned char *ivec);
|
||||
void cmll256_t4_cbc_decrypt(const unsigned char *in, unsigned char *out,
|
||||
size_t len, const CAMELLIA_KEY *key,
|
||||
unsigned char *ivec);
|
||||
void cmll128_t4_ctr32_encrypt(const unsigned char *in, unsigned char *out,
|
||||
size_t blocks, const CAMELLIA_KEY *key,
|
||||
unsigned char *ivec);
|
||||
void cmll256_t4_ctr32_encrypt(const unsigned char *in, unsigned char *out,
|
||||
size_t blocks, const CAMELLIA_KEY *key,
|
||||
unsigned char *ivec);
|
||||
|
||||
static int cmll_t4_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
|
||||
const unsigned char *iv, int enc)
|
||||
|
||||
@@ -575,6 +575,10 @@ static int chacha20_poly1305_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg,
|
||||
}
|
||||
return 1;
|
||||
|
||||
case EVP_CTRL_GET_IVLEN:
|
||||
*(int *)ptr = actx->nonce_len;
|
||||
return 1;
|
||||
|
||||
case EVP_CTRL_AEAD_SET_IVLEN:
|
||||
if (actx->draft) return -1;
|
||||
if (arg <= 0 || arg > CHACHA20_POLY1305_MAX_IVLEN)
|
||||
@@ -656,7 +660,8 @@ static EVP_CIPHER chacha20_poly1305 = {
|
||||
12, /* iv_len, 96-bit nonce in the context */
|
||||
EVP_CIPH_FLAG_AEAD_CIPHER | EVP_CIPH_CUSTOM_IV |
|
||||
EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CTRL_INIT |
|
||||
EVP_CIPH_CUSTOM_COPY | EVP_CIPH_FLAG_CUSTOM_CIPHER,
|
||||
EVP_CIPH_CUSTOM_COPY | EVP_CIPH_FLAG_CUSTOM_CIPHER |
|
||||
EVP_CIPH_CUSTOM_IV_LENGTH,
|
||||
chacha20_poly1305_init_key,
|
||||
chacha20_poly1305_cipher,
|
||||
chacha20_poly1305_cleanup,
|
||||
|
||||
@@ -51,7 +51,7 @@ static int rc4_hmac_md5_init_key(EVP_CIPHER_CTX *ctx,
|
||||
return 1;
|
||||
}
|
||||
|
||||
# if defined(RC4_ASM) && defined(MD5_ASM) && ( \
|
||||
# if defined(RC4_ASM) && defined(MD5_ASM) && ( \
|
||||
defined(__x86_64) || defined(__x86_64__) || \
|
||||
defined(_M_AMD64) || defined(_M_X64) )
|
||||
# define STITCHED_CALL
|
||||
@@ -71,7 +71,6 @@ static int rc4_hmac_md5_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
|
||||
* rc4_md5-x86_64.pl */
|
||||
md5_off = MD5_CBLOCK - key->md.num, blocks;
|
||||
unsigned int l;
|
||||
extern unsigned int OPENSSL_ia32cap_P[];
|
||||
# endif
|
||||
size_t plen = key->payload_length;
|
||||
|
||||
|
||||
+323
-67
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
@@ -35,7 +35,7 @@ int EVP_CIPHER_CTX_reset(EVP_CIPHER_CTX *ctx)
|
||||
ctx->provctx = NULL;
|
||||
}
|
||||
if (ctx->fetched_cipher != NULL)
|
||||
EVP_CIPHER_meth_free(ctx->fetched_cipher);
|
||||
EVP_CIPHER_free(ctx->fetched_cipher);
|
||||
memset(ctx, 0, sizeof(*ctx));
|
||||
|
||||
return 1;
|
||||
@@ -133,7 +133,7 @@ int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
|
||||
|| impl != NULL) {
|
||||
if (ctx->cipher == ctx->fetched_cipher)
|
||||
ctx->cipher = NULL;
|
||||
EVP_CIPHER_meth_free(ctx->fetched_cipher);
|
||||
EVP_CIPHER_free(ctx->fetched_cipher);
|
||||
ctx->fetched_cipher = NULL;
|
||||
goto legacy;
|
||||
}
|
||||
@@ -163,6 +163,104 @@ int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
|
||||
case NID_aes_256_ctr:
|
||||
case NID_aes_192_ctr:
|
||||
case NID_aes_128_ctr:
|
||||
case NID_aes_128_xts:
|
||||
case NID_aes_256_xts:
|
||||
case NID_aes_256_ocb:
|
||||
case NID_aes_192_ocb:
|
||||
case NID_aes_128_ocb:
|
||||
case NID_aes_256_gcm:
|
||||
case NID_aes_192_gcm:
|
||||
case NID_aes_128_gcm:
|
||||
case NID_id_aes256_wrap:
|
||||
case NID_id_aes256_wrap_pad:
|
||||
case NID_id_aes192_wrap:
|
||||
case NID_id_aes192_wrap_pad:
|
||||
case NID_id_aes128_wrap:
|
||||
case NID_id_aes128_wrap_pad:
|
||||
case NID_aria_256_gcm:
|
||||
case NID_aria_192_gcm:
|
||||
case NID_aria_128_gcm:
|
||||
case NID_aes_256_ccm:
|
||||
case NID_aes_192_ccm:
|
||||
case NID_aes_128_ccm:
|
||||
case NID_aria_256_ccm:
|
||||
case NID_aria_192_ccm:
|
||||
case NID_aria_128_ccm:
|
||||
case NID_aria_256_ecb:
|
||||
case NID_aria_192_ecb:
|
||||
case NID_aria_128_ecb:
|
||||
case NID_aria_256_cbc:
|
||||
case NID_aria_192_cbc:
|
||||
case NID_aria_128_cbc:
|
||||
case NID_aria_256_ofb128:
|
||||
case NID_aria_192_ofb128:
|
||||
case NID_aria_128_ofb128:
|
||||
case NID_aria_256_cfb128:
|
||||
case NID_aria_192_cfb128:
|
||||
case NID_aria_128_cfb128:
|
||||
case NID_aria_256_cfb1:
|
||||
case NID_aria_192_cfb1:
|
||||
case NID_aria_128_cfb1:
|
||||
case NID_aria_256_cfb8:
|
||||
case NID_aria_192_cfb8:
|
||||
case NID_aria_128_cfb8:
|
||||
case NID_aria_256_ctr:
|
||||
case NID_aria_192_ctr:
|
||||
case NID_aria_128_ctr:
|
||||
case NID_camellia_256_ecb:
|
||||
case NID_camellia_192_ecb:
|
||||
case NID_camellia_128_ecb:
|
||||
case NID_camellia_256_cbc:
|
||||
case NID_camellia_192_cbc:
|
||||
case NID_camellia_128_cbc:
|
||||
case NID_camellia_256_ofb128:
|
||||
case NID_camellia_192_ofb128:
|
||||
case NID_camellia_128_ofb128:
|
||||
case NID_camellia_256_cfb128:
|
||||
case NID_camellia_192_cfb128:
|
||||
case NID_camellia_128_cfb128:
|
||||
case NID_camellia_256_cfb1:
|
||||
case NID_camellia_192_cfb1:
|
||||
case NID_camellia_128_cfb1:
|
||||
case NID_camellia_256_cfb8:
|
||||
case NID_camellia_192_cfb8:
|
||||
case NID_camellia_128_cfb8:
|
||||
case NID_camellia_256_ctr:
|
||||
case NID_camellia_192_ctr:
|
||||
case NID_camellia_128_ctr:
|
||||
case NID_des_ede3_cbc:
|
||||
case NID_des_ede3_ecb:
|
||||
case NID_des_ede3_ofb64:
|
||||
case NID_des_ede3_cfb64:
|
||||
case NID_des_ede3_cfb8:
|
||||
case NID_des_ede3_cfb1:
|
||||
case NID_des_ede_cbc:
|
||||
case NID_des_ede_ecb:
|
||||
case NID_des_ede_ofb64:
|
||||
case NID_des_ede_cfb64:
|
||||
case NID_desx_cbc:
|
||||
case NID_id_smime_alg_CMS3DESwrap:
|
||||
case NID_bf_cbc:
|
||||
case NID_bf_ecb:
|
||||
case NID_bf_cfb64:
|
||||
case NID_bf_ofb64:
|
||||
case NID_idea_cbc:
|
||||
case NID_idea_ecb:
|
||||
case NID_idea_cfb64:
|
||||
case NID_idea_ofb64:
|
||||
case NID_cast5_cbc:
|
||||
case NID_cast5_ecb:
|
||||
case NID_cast5_cfb64:
|
||||
case NID_cast5_ofb64:
|
||||
case NID_seed_cbc:
|
||||
case NID_seed_ecb:
|
||||
case NID_seed_cfb128:
|
||||
case NID_seed_ofb128:
|
||||
case NID_sm4_cbc:
|
||||
case NID_sm4_ecb:
|
||||
case NID_sm4_ctr:
|
||||
case NID_sm4_cfb128:
|
||||
case NID_sm4_ofb128:
|
||||
break;
|
||||
default:
|
||||
goto legacy;
|
||||
@@ -191,9 +289,7 @@ int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
|
||||
ctx->flags = flags;
|
||||
}
|
||||
|
||||
if (cipher != NULL)
|
||||
ctx->cipher = cipher;
|
||||
else
|
||||
if (cipher == NULL)
|
||||
cipher = ctx->cipher;
|
||||
|
||||
if (cipher->prov == NULL) {
|
||||
@@ -210,7 +306,7 @@ int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
|
||||
return 0;
|
||||
}
|
||||
cipher = provciph;
|
||||
EVP_CIPHER_meth_free(ctx->fetched_cipher);
|
||||
EVP_CIPHER_free(ctx->fetched_cipher);
|
||||
ctx->fetched_cipher = provciph;
|
||||
#endif
|
||||
}
|
||||
@@ -920,11 +1016,14 @@ int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
|
||||
|
||||
int EVP_CIPHER_CTX_set_key_length(EVP_CIPHER_CTX *c, int keylen)
|
||||
{
|
||||
int ok = evp_do_param(c->cipher, &keylen, sizeof(keylen),
|
||||
OSSL_CIPHER_PARAM_KEYLEN, OSSL_PARAM_INTEGER,
|
||||
evp_do_ciph_ctx_setparams, c->provctx);
|
||||
int ok;
|
||||
OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END };
|
||||
size_t len = keylen;
|
||||
|
||||
if (ok != -2)
|
||||
params[0] = OSSL_PARAM_construct_size_t(OSSL_CIPHER_PARAM_KEYLEN, &len);
|
||||
ok = evp_do_ciph_ctx_setparams(c->cipher, c->provctx, params);
|
||||
|
||||
if (ok != EVP_CTRL_RET_UNSUPPORTED)
|
||||
return ok;
|
||||
|
||||
/* TODO(3.0) legacy code follows */
|
||||
@@ -943,23 +1042,28 @@ int EVP_CIPHER_CTX_set_key_length(EVP_CIPHER_CTX *c, int keylen)
|
||||
int EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX *ctx, int pad)
|
||||
{
|
||||
int ok;
|
||||
OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END };
|
||||
unsigned int pd = pad;
|
||||
|
||||
if (pad)
|
||||
ctx->flags &= ~EVP_CIPH_NO_PADDING;
|
||||
else
|
||||
ctx->flags |= EVP_CIPH_NO_PADDING;
|
||||
|
||||
ok = evp_do_param(ctx->cipher, &pad, sizeof(pad),
|
||||
OSSL_CIPHER_PARAM_PADDING, OSSL_PARAM_INTEGER,
|
||||
evp_do_ciph_ctx_setparams, ctx->provctx);
|
||||
params[0] = OSSL_PARAM_construct_uint(OSSL_CIPHER_PARAM_PADDING, &pd);
|
||||
ok = evp_do_ciph_ctx_setparams(ctx->cipher, ctx->provctx, params);
|
||||
|
||||
return ok != 0;
|
||||
}
|
||||
|
||||
int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr)
|
||||
{
|
||||
int ret = -2; /* Unsupported */
|
||||
int ret = EVP_CTRL_RET_UNSUPPORTED;
|
||||
int set_params = 1;
|
||||
size_t sz = arg;
|
||||
OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END };
|
||||
|
||||
if (!ctx->cipher) {
|
||||
if (ctx == NULL || ctx->cipher == NULL) {
|
||||
EVPerr(EVP_F_EVP_CIPHER_CTX_CTRL, EVP_R_NO_CIPHER_SET);
|
||||
return 0;
|
||||
}
|
||||
@@ -969,31 +1073,71 @@ int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr)
|
||||
|
||||
switch (type) {
|
||||
case EVP_CTRL_SET_KEY_LENGTH:
|
||||
ret = evp_do_param(ctx->cipher, &arg, sizeof(arg),
|
||||
OSSL_CIPHER_PARAM_KEYLEN, OSSL_PARAM_INTEGER,
|
||||
evp_do_ciph_ctx_setparams, ctx->provctx);
|
||||
break;
|
||||
case EVP_CTRL_GET_IV:
|
||||
ret = evp_do_param(ctx->cipher, ptr, arg,
|
||||
OSSL_CIPHER_PARAM_IV, OSSL_PARAM_OCTET_STRING,
|
||||
evp_do_ciph_ctx_getparams, ctx->provctx);
|
||||
params[0] = OSSL_PARAM_construct_size_t(OSSL_CIPHER_PARAM_KEYLEN, &sz);
|
||||
break;
|
||||
case EVP_CTRL_RAND_KEY: /* Used by DES */
|
||||
set_params = 0;
|
||||
params[0] =
|
||||
OSSL_PARAM_construct_octet_string(OSSL_CIPHER_PARAM_RANDOM_KEY,
|
||||
ptr, sz);
|
||||
break;
|
||||
|
||||
case EVP_CTRL_SET_PIPELINE_OUTPUT_BUFS: /* Used by DASYNC */
|
||||
case EVP_CTRL_INIT: /* TODO(3.0) Purely legacy, no provider counterpart */
|
||||
ret = -2; /* Unsupported */
|
||||
default:
|
||||
return EVP_CTRL_RET_UNSUPPORTED;
|
||||
case EVP_CTRL_GET_IV:
|
||||
set_params = 0;
|
||||
params[0] = OSSL_PARAM_construct_octet_string(OSSL_CIPHER_PARAM_IV,
|
||||
ptr, sz);
|
||||
break;
|
||||
case EVP_CTRL_AEAD_SET_IVLEN:
|
||||
if (arg < 0)
|
||||
return 0;
|
||||
params[0] = OSSL_PARAM_construct_size_t(OSSL_CIPHER_PARAM_IVLEN, &sz);
|
||||
break;
|
||||
case EVP_CTRL_GCM_SET_IV_FIXED:
|
||||
params[0] =
|
||||
OSSL_PARAM_construct_octet_string(OSSL_CIPHER_PARAM_AEAD_TLS1_IV_FIXED,
|
||||
ptr, sz);
|
||||
break;
|
||||
case EVP_CTRL_AEAD_GET_TAG:
|
||||
set_params = 0; /* Fall thru */
|
||||
case EVP_CTRL_AEAD_SET_TAG:
|
||||
params[0] = OSSL_PARAM_construct_octet_string(OSSL_CIPHER_PARAM_AEAD_TAG,
|
||||
ptr, sz);
|
||||
break;
|
||||
case EVP_CTRL_AEAD_TLS1_AAD:
|
||||
/* This one does a set and a get - since it returns a padding size */
|
||||
params[0] =
|
||||
OSSL_PARAM_construct_octet_string(OSSL_CIPHER_PARAM_AEAD_TLS1_AAD,
|
||||
ptr, sz);
|
||||
ret = evp_do_ciph_ctx_setparams(ctx->cipher, ctx->provctx, params);
|
||||
if (ret <= 0)
|
||||
return ret;
|
||||
params[0] =
|
||||
OSSL_PARAM_construct_size_t(OSSL_CIPHER_PARAM_AEAD_TLS1_AAD_PAD, &sz);
|
||||
ret = evp_do_ciph_ctx_getparams(ctx->cipher, ctx->provctx, params);
|
||||
if (ret <= 0)
|
||||
return 0;
|
||||
return sz;
|
||||
}
|
||||
|
||||
if (set_params)
|
||||
ret = evp_do_ciph_ctx_setparams(ctx->cipher, ctx->provctx, params);
|
||||
else
|
||||
ret = evp_do_ciph_ctx_getparams(ctx->cipher, ctx->provctx, params);
|
||||
return ret;
|
||||
|
||||
legacy:
|
||||
if (!ctx->cipher->ctrl) {
|
||||
/* TODO(3.0): Remove legacy code below */
|
||||
legacy:
|
||||
if (ctx->cipher->ctrl == NULL) {
|
||||
EVPerr(EVP_F_EVP_CIPHER_CTX_CTRL, EVP_R_CTRL_NOT_IMPLEMENTED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = ctx->cipher->ctrl(ctx, type, arg, ptr);
|
||||
if (ret == -1) {
|
||||
if (ret == EVP_CTRL_RET_UNSUPPORTED) {
|
||||
EVPerr(EVP_F_EVP_CIPHER_CTX_CTRL,
|
||||
EVP_R_CTRL_OPERATION_NOT_IMPLEMENTED);
|
||||
return 0;
|
||||
@@ -1001,19 +1145,66 @@ int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr)
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if !defined(FIPS_MODE)
|
||||
/* TODO(3.0): No support for RAND yet in the FIPS module */
|
||||
int EVP_CIPHER_get_params(EVP_CIPHER *cipher, OSSL_PARAM params[])
|
||||
{
|
||||
if (cipher != NULL && cipher->get_params != NULL)
|
||||
return cipher->get_params(params);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int EVP_CIPHER_CTX_set_params(EVP_CIPHER_CTX *ctx, const OSSL_PARAM params[])
|
||||
{
|
||||
if (ctx->cipher != NULL && ctx->cipher->set_ctx_params != NULL)
|
||||
return ctx->cipher->set_ctx_params(ctx->provctx, params);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int EVP_CIPHER_CTX_get_params(EVP_CIPHER_CTX *ctx, OSSL_PARAM params[])
|
||||
{
|
||||
if (ctx->cipher != NULL && ctx->cipher->get_ctx_params != NULL)
|
||||
return ctx->cipher->get_ctx_params(ctx->provctx, params);
|
||||
return 0;
|
||||
}
|
||||
|
||||
const OSSL_PARAM *EVP_CIPHER_gettable_params(const EVP_CIPHER *cipher)
|
||||
{
|
||||
if (cipher != NULL && cipher->gettable_params != NULL)
|
||||
return cipher->gettable_params();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const OSSL_PARAM *EVP_CIPHER_CTX_settable_params(const EVP_CIPHER *cipher)
|
||||
{
|
||||
if (cipher != NULL && cipher->settable_ctx_params != NULL)
|
||||
return cipher->settable_ctx_params();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const OSSL_PARAM *EVP_CIPHER_CTX_gettable_params(const EVP_CIPHER *cipher)
|
||||
{
|
||||
if (cipher != NULL && cipher->gettable_ctx_params != NULL)
|
||||
return cipher->gettable_ctx_params();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int EVP_CIPHER_CTX_rand_key(EVP_CIPHER_CTX *ctx, unsigned char *key)
|
||||
{
|
||||
int kl;
|
||||
if (ctx->cipher->flags & EVP_CIPH_RAND_KEY)
|
||||
return EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_RAND_KEY, 0, key);
|
||||
kl = EVP_CIPHER_CTX_key_length(ctx);
|
||||
if (kl <= 0 || RAND_priv_bytes(key, kl) <= 0)
|
||||
return 0;
|
||||
return 1;
|
||||
|
||||
#ifdef FIPS_MODE
|
||||
return 0;
|
||||
#else
|
||||
{
|
||||
int kl;
|
||||
|
||||
kl = EVP_CIPHER_CTX_key_length(ctx);
|
||||
if (kl <= 0 || RAND_priv_bytes(key, kl) <= 0)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
#endif /* FIPS_MODE */
|
||||
}
|
||||
#endif
|
||||
|
||||
int EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, const EVP_CIPHER_CTX *in)
|
||||
{
|
||||
@@ -1081,18 +1272,47 @@ int EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, const EVP_CIPHER_CTX *in)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void *evp_cipher_from_dispatch(const OSSL_DISPATCH *fns,
|
||||
OSSL_PROVIDER *prov)
|
||||
EVP_CIPHER *evp_cipher_new(void)
|
||||
{
|
||||
EVP_CIPHER *cipher = OPENSSL_zalloc(sizeof(EVP_CIPHER));
|
||||
|
||||
if (cipher != NULL) {
|
||||
cipher->lock = CRYPTO_THREAD_lock_new();
|
||||
if (cipher->lock == NULL) {
|
||||
OPENSSL_free(cipher);
|
||||
return NULL;
|
||||
}
|
||||
cipher->refcnt = 1;
|
||||
}
|
||||
return cipher;
|
||||
}
|
||||
|
||||
static void *evp_cipher_from_dispatch(const int name_id,
|
||||
const OSSL_DISPATCH *fns,
|
||||
OSSL_PROVIDER *prov,
|
||||
void *unused)
|
||||
{
|
||||
EVP_CIPHER *cipher = NULL;
|
||||
int fnciphcnt = 0, fnctxcnt = 0;
|
||||
|
||||
/*
|
||||
* The legacy NID is set by EVP_CIPHER_fetch() if the name exists in
|
||||
* the object database.
|
||||
*/
|
||||
if ((cipher = EVP_CIPHER_meth_new(0, 0, 0)) == NULL)
|
||||
if ((cipher = evp_cipher_new()) == NULL) {
|
||||
EVPerr(0, ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
cipher->name_id = name_id;
|
||||
|
||||
#ifndef FIPS_MODE
|
||||
{
|
||||
/*
|
||||
* FIPS module note: since internal fetches will be entirely
|
||||
* provider based, we know that none of its code depends on legacy
|
||||
* NIDs or any functionality that use them.
|
||||
*
|
||||
* TODO(3.x) get rid of the need for legacy NIDs
|
||||
*/
|
||||
cipher->nid = OBJ_sn2nid(evp_first_name(prov, name_id));
|
||||
}
|
||||
#endif
|
||||
|
||||
for (; fns->function_id != 0; fns++) {
|
||||
switch (fns->function_id) {
|
||||
@@ -1147,15 +1367,32 @@ static void *evp_cipher_from_dispatch(const OSSL_DISPATCH *fns,
|
||||
break;
|
||||
cipher->get_params = OSSL_get_OP_cipher_get_params(fns);
|
||||
break;
|
||||
case OSSL_FUNC_CIPHER_CTX_GET_PARAMS:
|
||||
if (cipher->ctx_get_params != NULL)
|
||||
case OSSL_FUNC_CIPHER_GET_CTX_PARAMS:
|
||||
if (cipher->get_ctx_params != NULL)
|
||||
break;
|
||||
cipher->ctx_get_params = OSSL_get_OP_cipher_ctx_get_params(fns);
|
||||
cipher->get_ctx_params = OSSL_get_OP_cipher_get_ctx_params(fns);
|
||||
break;
|
||||
case OSSL_FUNC_CIPHER_CTX_SET_PARAMS:
|
||||
if (cipher->ctx_set_params != NULL)
|
||||
case OSSL_FUNC_CIPHER_SET_CTX_PARAMS:
|
||||
if (cipher->set_ctx_params != NULL)
|
||||
break;
|
||||
cipher->ctx_set_params = OSSL_get_OP_cipher_ctx_set_params(fns);
|
||||
cipher->set_ctx_params = OSSL_get_OP_cipher_set_ctx_params(fns);
|
||||
break;
|
||||
case OSSL_FUNC_CIPHER_GETTABLE_PARAMS:
|
||||
if (cipher->gettable_params != NULL)
|
||||
break;
|
||||
cipher->gettable_params = OSSL_get_OP_cipher_gettable_params(fns);
|
||||
break;
|
||||
case OSSL_FUNC_CIPHER_GETTABLE_CTX_PARAMS:
|
||||
if (cipher->gettable_ctx_params != NULL)
|
||||
break;
|
||||
cipher->gettable_ctx_params =
|
||||
OSSL_get_OP_cipher_gettable_ctx_params(fns);
|
||||
break;
|
||||
case OSSL_FUNC_CIPHER_SETTABLE_CTX_PARAMS:
|
||||
if (cipher->settable_ctx_params != NULL)
|
||||
break;
|
||||
cipher->settable_ctx_params =
|
||||
OSSL_get_OP_cipher_settable_ctx_params(fns);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1165,11 +1402,10 @@ static void *evp_cipher_from_dispatch(const OSSL_DISPATCH *fns,
|
||||
/*
|
||||
* In order to be a consistent set of functions we must have at least
|
||||
* a complete set of "encrypt" functions, or a complete set of "decrypt"
|
||||
* functions, or a single "cipher" function. In all cases we need a
|
||||
* complete set of context management functions, as well as the
|
||||
* blocksize, iv_length and key_length functions.
|
||||
* functions, or a single "cipher" function. In all cases we need both
|
||||
* the "newctx" and "freectx" functions.
|
||||
*/
|
||||
EVP_CIPHER_meth_free(cipher);
|
||||
EVP_CIPHER_free(cipher);
|
||||
EVPerr(EVP_F_EVP_CIPHER_FROM_DISPATCH, EVP_R_INVALID_PROVIDER_FUNCTIONS);
|
||||
return NULL;
|
||||
}
|
||||
@@ -1187,7 +1423,7 @@ static int evp_cipher_up_ref(void *cipher)
|
||||
|
||||
static void evp_cipher_free(void *cipher)
|
||||
{
|
||||
EVP_CIPHER_meth_free(cipher);
|
||||
EVP_CIPHER_free(cipher);
|
||||
}
|
||||
|
||||
EVP_CIPHER *EVP_CIPHER_fetch(OPENSSL_CTX *ctx, const char *algorithm,
|
||||
@@ -1195,20 +1431,40 @@ EVP_CIPHER *EVP_CIPHER_fetch(OPENSSL_CTX *ctx, const char *algorithm,
|
||||
{
|
||||
EVP_CIPHER *cipher =
|
||||
evp_generic_fetch(ctx, OSSL_OP_CIPHER, algorithm, properties,
|
||||
evp_cipher_from_dispatch, evp_cipher_up_ref,
|
||||
evp_cipher_from_dispatch, NULL, evp_cipher_up_ref,
|
||||
evp_cipher_free);
|
||||
|
||||
#ifndef FIPS_MODE
|
||||
/* TODO(3.x) get rid of the need for legacy NIDs */
|
||||
if (cipher != NULL) {
|
||||
/*
|
||||
* FIPS module note: since internal fetches will be entirely
|
||||
* provider based, we know that none of its code depends on legacy
|
||||
* NIDs or any functionality that use them.
|
||||
*/
|
||||
cipher->nid = OBJ_sn2nid(algorithm);
|
||||
}
|
||||
#endif
|
||||
|
||||
return cipher;
|
||||
}
|
||||
|
||||
int EVP_CIPHER_up_ref(EVP_CIPHER *cipher)
|
||||
{
|
||||
int ref = 0;
|
||||
|
||||
CRYPTO_UP_REF(&cipher->refcnt, &ref, cipher->lock);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void EVP_CIPHER_free(EVP_CIPHER *cipher)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (cipher == NULL)
|
||||
return;
|
||||
|
||||
CRYPTO_DOWN_REF(&cipher->refcnt, &i, cipher->lock);
|
||||
if (i > 0)
|
||||
return;
|
||||
ossl_provider_free(cipher->prov);
|
||||
CRYPTO_THREAD_lock_free(cipher->lock);
|
||||
OPENSSL_free(cipher);
|
||||
}
|
||||
|
||||
void EVP_CIPHER_do_all_ex(OPENSSL_CTX *libctx,
|
||||
void (*fn)(EVP_CIPHER *mac, void *arg),
|
||||
void *arg)
|
||||
{
|
||||
evp_generic_do_all(libctx, OSSL_OP_CIPHER,
|
||||
(void (*)(void *, void *))fn, arg,
|
||||
evp_cipher_from_dispatch, NULL, evp_cipher_free);
|
||||
}
|
||||
+8
-185
@@ -13,188 +13,6 @@
|
||||
|
||||
#ifndef OPENSSL_NO_ERR
|
||||
|
||||
static const ERR_STRING_DATA EVP_str_functs[] = {
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_AESNI_INIT_KEY, 0), "aesni_init_key"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_AESNI_XTS_INIT_KEY, 0), "aesni_xts_init_key"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_AES_GCM_CTRL, 0), "aes_gcm_ctrl"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_AES_GCM_TLS_CIPHER, 0), "aes_gcm_tls_cipher"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_AES_INIT_KEY, 0), "aes_init_key"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_AES_OCB_CIPHER, 0), "aes_ocb_cipher"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_AES_T4_INIT_KEY, 0), "aes_t4_init_key"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_AES_T4_XTS_INIT_KEY, 0),
|
||||
"aes_t4_xts_init_key"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_AES_WRAP_CIPHER, 0), "aes_wrap_cipher"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_AES_XTS_CIPHER, 0), "aes_xts_cipher"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_AES_XTS_INIT_KEY, 0), "aes_xts_init_key"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_ALG_MODULE_INIT, 0), "alg_module_init"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_ARIA_CCM_INIT_KEY, 0), "aria_ccm_init_key"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_ARIA_GCM_CTRL, 0), "aria_gcm_ctrl"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_ARIA_GCM_INIT_KEY, 0), "aria_gcm_init_key"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_ARIA_INIT_KEY, 0), "aria_init_key"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_B64_NEW, 0), "b64_new"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_BLAKE2B_MAC_CTRL, 0), "blake2b_mac_ctrl"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_BLAKE2B_MAC_INIT, 0), "blake2b_mac_init"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_BLAKE2S_MAC_CTRL, 0), "blake2s_mac_ctrl"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_BLAKE2S_MAC_INIT, 0), "blake2s_mac_init"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_CAMELLIA_INIT_KEY, 0), "camellia_init_key"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_CHACHA20_POLY1305_CTRL, 0),
|
||||
"chacha20_poly1305_ctrl"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_CMLL_T4_INIT_KEY, 0), "cmll_t4_init_key"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_DES_EDE3_WRAP_CIPHER, 0),
|
||||
"des_ede3_wrap_cipher"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_DO_SIGVER_INIT, 0), "do_sigver_init"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_ENC_NEW, 0), "enc_new"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_CIPHERINIT_EX, 0), "EVP_CipherInit_ex"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_CIPHER_ASN1_TO_PARAM, 0),
|
||||
"EVP_CIPHER_asn1_to_param"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_CIPHER_CTX_COPY, 0),
|
||||
"EVP_CIPHER_CTX_copy"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_CIPHER_CTX_CTRL, 0),
|
||||
"EVP_CIPHER_CTX_ctrl"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_CIPHER_CTX_SET_KEY_LENGTH, 0),
|
||||
"EVP_CIPHER_CTX_set_key_length"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_CIPHER_CTX_SET_PADDING, 0),
|
||||
"EVP_CIPHER_CTX_set_padding"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_CIPHER_FROM_DISPATCH, 0),
|
||||
"evp_cipher_from_dispatch"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_CIPHER_MODE, 0), "EVP_CIPHER_mode"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_CIPHER_PARAM_TO_ASN1, 0),
|
||||
"EVP_CIPHER_param_to_asn1"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_DECRYPTFINAL_EX, 0),
|
||||
"EVP_DecryptFinal_ex"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_DECRYPTUPDATE, 0), "EVP_DecryptUpdate"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_DIGESTFINALXOF, 0), "EVP_DigestFinalXOF"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_DIGESTFINAL_EX, 0), "EVP_DigestFinal_ex"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_DIGESTINIT_EX, 0), "EVP_DigestInit_ex"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_DIGESTUPDATE, 0), "EVP_DigestUpdate"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_ENCRYPTDECRYPTUPDATE, 0),
|
||||
"evp_EncryptDecryptUpdate"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_ENCRYPTFINAL_EX, 0),
|
||||
"EVP_EncryptFinal_ex"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_ENCRYPTUPDATE, 0), "EVP_EncryptUpdate"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_KDF_CTRL, 0), "EVP_KDF_ctrl"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_KDF_CTRL_STR, 0), "EVP_KDF_ctrl_str"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_KDF_CTX_NEW, 0), "EVP_KDF_CTX_new"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_KDF_CTX_NEW_ID, 0), "EVP_KDF_CTX_new_id"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_MAC_CTRL, 0), "EVP_MAC_ctrl"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_MAC_CTRL_STR, 0), "EVP_MAC_ctrl_str"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_MAC_CTX_DUP, 0), "EVP_MAC_CTX_dup"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_MAC_CTX_NEW, 0), "EVP_MAC_CTX_new"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_MAC_INIT, 0), "EVP_MAC_init"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_MD_BLOCK_SIZE, 0), "EVP_MD_block_size"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_MD_CTX_COPY_EX, 0), "EVP_MD_CTX_copy_ex"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_MD_SIZE, 0), "EVP_MD_size"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_OPENINIT, 0), "EVP_OpenInit"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PBE_ALG_ADD, 0), "EVP_PBE_alg_add"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PBE_ALG_ADD_TYPE, 0),
|
||||
"EVP_PBE_alg_add_type"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PBE_CIPHERINIT, 0), "EVP_PBE_CipherInit"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PBE_SCRYPT, 0), "EVP_PBE_scrypt"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKCS82PKEY, 0), "EVP_PKCS82PKEY"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY2PKCS8, 0), "EVP_PKEY2PKCS8"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_ASN1_ADD0, 0), "EVP_PKEY_asn1_add0"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_CHECK, 0), "EVP_PKEY_check"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_COPY_PARAMETERS, 0),
|
||||
"EVP_PKEY_copy_parameters"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_CTX_CTRL, 0), "EVP_PKEY_CTX_ctrl"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_CTX_CTRL_STR, 0),
|
||||
"EVP_PKEY_CTX_ctrl_str"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_CTX_DUP, 0), "EVP_PKEY_CTX_dup"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_CTX_MD, 0), "EVP_PKEY_CTX_md"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_DECRYPT, 0), "EVP_PKEY_decrypt"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_DECRYPT_INIT, 0),
|
||||
"EVP_PKEY_decrypt_init"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_DECRYPT_OLD, 0),
|
||||
"EVP_PKEY_decrypt_old"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_DERIVE, 0), "EVP_PKEY_derive"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_DERIVE_INIT, 0),
|
||||
"EVP_PKEY_derive_init"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_DERIVE_SET_PEER, 0),
|
||||
"EVP_PKEY_derive_set_peer"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_ENCRYPT, 0), "EVP_PKEY_encrypt"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_ENCRYPT_INIT, 0),
|
||||
"EVP_PKEY_encrypt_init"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_ENCRYPT_OLD, 0),
|
||||
"EVP_PKEY_encrypt_old"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_GET0_DH, 0), "EVP_PKEY_get0_DH"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_GET0_DSA, 0), "EVP_PKEY_get0_DSA"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_GET0_EC_KEY, 0),
|
||||
"EVP_PKEY_get0_EC_KEY"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_GET0_HMAC, 0), "EVP_PKEY_get0_hmac"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_GET0_POLY1305, 0),
|
||||
"EVP_PKEY_get0_poly1305"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_GET0_RSA, 0), "EVP_PKEY_get0_RSA"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_GET0_SIPHASH, 0),
|
||||
"EVP_PKEY_get0_siphash"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_GET_RAW_PRIVATE_KEY, 0),
|
||||
"EVP_PKEY_get_raw_private_key"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_GET_RAW_PUBLIC_KEY, 0),
|
||||
"EVP_PKEY_get_raw_public_key"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_KEYGEN, 0), "EVP_PKEY_keygen"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_KEYGEN_INIT, 0),
|
||||
"EVP_PKEY_keygen_init"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_METH_ADD0, 0), "EVP_PKEY_meth_add0"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_METH_NEW, 0), "EVP_PKEY_meth_new"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_NEW, 0), "EVP_PKEY_new"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_NEW_CMAC_KEY, 0),
|
||||
"EVP_PKEY_new_CMAC_key"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_NEW_RAW_PRIVATE_KEY, 0),
|
||||
"EVP_PKEY_new_raw_private_key"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_NEW_RAW_PUBLIC_KEY, 0),
|
||||
"EVP_PKEY_new_raw_public_key"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_PARAMGEN, 0), "EVP_PKEY_paramgen"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_PARAMGEN_INIT, 0),
|
||||
"EVP_PKEY_paramgen_init"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_PARAM_CHECK, 0),
|
||||
"EVP_PKEY_param_check"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_PUBLIC_CHECK, 0),
|
||||
"EVP_PKEY_public_check"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_SET1_ENGINE, 0),
|
||||
"EVP_PKEY_set1_engine"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_SET_ALIAS_TYPE, 0),
|
||||
"EVP_PKEY_set_alias_type"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_SIGN, 0), "EVP_PKEY_sign"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_SIGN_INIT, 0), "EVP_PKEY_sign_init"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_VERIFY, 0), "EVP_PKEY_verify"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_VERIFY_INIT, 0),
|
||||
"EVP_PKEY_verify_init"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_VERIFY_RECOVER, 0),
|
||||
"EVP_PKEY_verify_recover"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_VERIFY_RECOVER_INIT, 0),
|
||||
"EVP_PKEY_verify_recover_init"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_SET_DEFAULT_PROPERTIES, 0),
|
||||
"EVP_set_default_properties"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_SIGNFINAL, 0), "EVP_SignFinal"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_VERIFYFINAL, 0), "EVP_VerifyFinal"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_GMAC_CTRL, 0), "gmac_ctrl"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_INT_CTX_NEW, 0), "int_ctx_new"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_KMAC_CTRL, 0), "kmac_ctrl"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_KMAC_INIT, 0), "kmac_init"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_OK_NEW, 0), "ok_new"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_PKCS5_PBE_KEYIVGEN, 0), "PKCS5_PBE_keyivgen"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_PKCS5_V2_PBE_KEYIVGEN, 0),
|
||||
"PKCS5_v2_PBE_keyivgen"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN, 0),
|
||||
"PKCS5_v2_PBKDF2_keyivgen"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_PKCS5_V2_SCRYPT_KEYIVGEN, 0),
|
||||
"PKCS5_v2_scrypt_keyivgen"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_PKEY_KDF_CTRL, 0), "pkey_kdf_ctrl"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_PKEY_MAC_COPY, 0), "pkey_mac_copy"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_PKEY_MAC_INIT, 0), "pkey_mac_init"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_PKEY_SET_TYPE, 0), "pkey_set_type"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_POLY1305_CTRL, 0), "poly1305_ctrl"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_RC2_MAGIC_TO_METH, 0), "rc2_magic_to_meth"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_RC5_CTRL, 0), "rc5_ctrl"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_R_32_12_16_INIT_KEY, 0),
|
||||
"r_32_12_16_init_key"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_S390X_AES_GCM_CTRL, 0), "s390x_aes_gcm_ctrl"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_S390X_AES_GCM_TLS_CIPHER, 0),
|
||||
"s390x_aes_gcm_tls_cipher"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_SCRYPT_ALG, 0), "scrypt_alg"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_UPDATE, 0), "update"},
|
||||
{0, NULL}
|
||||
};
|
||||
|
||||
static const ERR_STRING_DATA EVP_str_reasons[] = {
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_AES_KEY_SETUP_FAILED),
|
||||
"aes key setup failed"},
|
||||
@@ -205,6 +23,10 @@ static const ERR_STRING_DATA EVP_str_reasons[] = {
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_BUFFER_TOO_SMALL), "buffer too small"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_CAMELLIA_KEY_SETUP_FAILED),
|
||||
"camellia key setup failed"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_CANNOT_GET_PARAMETERS),
|
||||
"cannot get parameters"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_CANNOT_SET_PARAMETERS),
|
||||
"cannot set parameters"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_CIPHER_NOT_GCM_MODE),
|
||||
"cipher not gcm mode"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_CIPHER_PARAMETER_ERROR),
|
||||
@@ -277,6 +99,9 @@ static const ERR_STRING_DATA EVP_str_reasons[] = {
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_NO_CIPHER_SET), "no cipher set"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_NO_DEFAULT_DIGEST), "no default digest"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_NO_DIGEST_SET), "no digest set"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_NO_KEYMGMT_AVAILABLE),
|
||||
"no keymgmt available"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_NO_KEYMGMT_PRESENT), "no keymgmt present"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_NO_KEY_SET), "no key set"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_NO_OPERATION_SET), "no operation set"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_ONLY_ONESHOT_SUPPORTED),
|
||||
@@ -336,10 +161,8 @@ static const ERR_STRING_DATA EVP_str_reasons[] = {
|
||||
int ERR_load_EVP_strings(void)
|
||||
{
|
||||
#ifndef OPENSSL_NO_ERR
|
||||
if (ERR_func_error_string(EVP_str_functs[0].error) == NULL) {
|
||||
ERR_load_strings_const(EVP_str_functs);
|
||||
if (ERR_reason_error_string(EVP_str_reasons[0].error) == NULL)
|
||||
ERR_load_strings_const(EVP_str_reasons);
|
||||
}
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
+206
-47
@@ -15,6 +15,7 @@
|
||||
#include "internal/thread_once.h"
|
||||
#include "internal/property.h"
|
||||
#include "internal/core.h"
|
||||
#include "internal/provider.h"
|
||||
#include "internal/namemap.h"
|
||||
#include "internal/evp_int.h" /* evp_locl.h needs it */
|
||||
#include "evp_locl.h"
|
||||
@@ -38,9 +39,14 @@ static const OPENSSL_CTX_METHOD default_method_store_method = {
|
||||
/* Data to be passed through ossl_method_construct() */
|
||||
struct method_data_st {
|
||||
OPENSSL_CTX *libctx;
|
||||
const char *name;
|
||||
OSSL_METHOD_CONSTRUCT_METHOD *mcm;
|
||||
void *(*method_from_dispatch)(const OSSL_DISPATCH *, OSSL_PROVIDER *);
|
||||
int operation_id; /* For get_method_from_store() */
|
||||
int name_id; /* For get_method_from_store() */
|
||||
const char *name; /* For get_method_from_store() */
|
||||
const char *propquery; /* For get_method_from_store() */
|
||||
void *(*method_from_dispatch)(int name_id, const OSSL_DISPATCH *,
|
||||
OSSL_PROVIDER *, void *);
|
||||
void *method_data;
|
||||
int (*refcnt_up_method)(void *method);
|
||||
void (*destruct_method)(void *method);
|
||||
};
|
||||
@@ -76,7 +82,7 @@ static OSSL_METHOD_STORE *get_default_method_store(OPENSSL_CTX *libctx)
|
||||
* | name identity | op id |
|
||||
* +------------------------+--------+
|
||||
*/
|
||||
static uint32_t method_id(unsigned int operation_id, unsigned int name_id)
|
||||
static uint32_t method_id(unsigned int operation_id, int name_id)
|
||||
{
|
||||
if (!ossl_assert(name_id < (1 << 24) || operation_id < (1 << 8))
|
||||
|| !ossl_assert(name_id > 0 && operation_id > 0))
|
||||
@@ -85,25 +91,36 @@ static uint32_t method_id(unsigned int operation_id, unsigned int name_id)
|
||||
}
|
||||
|
||||
static void *get_method_from_store(OPENSSL_CTX *libctx, void *store,
|
||||
int operation_id, const char *name,
|
||||
const char *propquery, void *data)
|
||||
void *data)
|
||||
{
|
||||
struct method_data_st *methdata = data;
|
||||
void *method = NULL;
|
||||
OSSL_NAMEMAP *namemap;
|
||||
int nameid;
|
||||
uint32_t methid;
|
||||
int name_id;
|
||||
uint32_t meth_id;
|
||||
|
||||
/*
|
||||
* get_method_from_store() is only called to try and get the method
|
||||
* that evp_generic_fetch() is asking for, and the operation id as
|
||||
* well as the name or name id are passed via methdata.
|
||||
*/
|
||||
if ((name_id = methdata->name_id) == 0) {
|
||||
OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx);
|
||||
|
||||
if (namemap == 0)
|
||||
return NULL;
|
||||
name_id = ossl_namemap_name2num(namemap, methdata->name);
|
||||
}
|
||||
|
||||
if (name_id == 0
|
||||
|| (meth_id = method_id(methdata->operation_id, name_id)) == 0)
|
||||
return NULL;
|
||||
|
||||
if (store == NULL
|
||||
&& (store = get_default_method_store(libctx)) == NULL)
|
||||
return NULL;
|
||||
|
||||
if ((namemap = ossl_namemap_stored(libctx)) == NULL
|
||||
|| (nameid = ossl_namemap_name2num(namemap, name)) == 0
|
||||
|| (methid = method_id(operation_id, nameid)) == 0)
|
||||
return NULL;
|
||||
|
||||
(void)ossl_method_store_fetch(store, methid, propquery, &method);
|
||||
(void)ossl_method_store_fetch(store, meth_id, methdata->propquery,
|
||||
&method);
|
||||
|
||||
if (method != NULL
|
||||
&& !methdata->refcnt_up_method(method)) {
|
||||
@@ -113,37 +130,59 @@ static void *get_method_from_store(OPENSSL_CTX *libctx, void *store,
|
||||
}
|
||||
|
||||
static int put_method_in_store(OPENSSL_CTX *libctx, void *store,
|
||||
void *method, int operation_id,
|
||||
const char *name, const char *propdef,
|
||||
void *data)
|
||||
void *method, const OSSL_PROVIDER *prov,
|
||||
int operation_id, const char *name,
|
||||
const char *propdef, void *data)
|
||||
{
|
||||
struct method_data_st *methdata = data;
|
||||
OSSL_NAMEMAP *namemap;
|
||||
int nameid;
|
||||
uint32_t methid;
|
||||
int name_id;
|
||||
uint32_t meth_id;
|
||||
|
||||
if ((namemap = ossl_namemap_stored(methdata->libctx)) == NULL
|
||||
|| (nameid = ossl_namemap_add(namemap, 0, name)) == 0
|
||||
|| (methid = method_id(operation_id, nameid)) == 0)
|
||||
/*
|
||||
* put_method_in_store() is only called with a method that was
|
||||
* successfully created by construct_method() below, which means
|
||||
* the name should already be stored in the namemap, so just use it.
|
||||
*/
|
||||
if ((namemap = ossl_namemap_stored(libctx)) == NULL
|
||||
|| (name_id = ossl_namemap_name2num(namemap, name)) == 0
|
||||
|| (meth_id = method_id(operation_id, name_id)) == 0)
|
||||
return 0;
|
||||
|
||||
if (store == NULL
|
||||
&& (store = get_default_method_store(libctx)) == NULL)
|
||||
return 0;
|
||||
|
||||
if (methdata->refcnt_up_method(method)
|
||||
&& ossl_method_store_add(store, methid, propdef, method,
|
||||
methdata->destruct_method))
|
||||
return 1;
|
||||
return 0;
|
||||
return ossl_method_store_add(store, prov, meth_id, propdef, method,
|
||||
methdata->refcnt_up_method,
|
||||
methdata->destruct_method);
|
||||
}
|
||||
|
||||
/*
|
||||
* The core fetching functionality passes the name of the implementation.
|
||||
* This function is responsible to getting an identity number for it.
|
||||
*/
|
||||
static void *construct_method(const char *name, const OSSL_DISPATCH *fns,
|
||||
OSSL_PROVIDER *prov, void *data)
|
||||
{
|
||||
/*
|
||||
* This function is only called if get_method_from_store() returned
|
||||
* NULL, so it's safe to say that of all the spots to create a new
|
||||
* namemap entry, this is it. Should the name already exist there, we
|
||||
* know that ossl_namemap_add() will return its corresponding number.
|
||||
*
|
||||
* TODO(3.0): If this function gets an array of names instead of just
|
||||
* one, we need to check through all the names to see if at least one
|
||||
* of them has an associated number, and use that. If several names
|
||||
* have associated numbers that differ from each other, it's an error.
|
||||
*/
|
||||
struct method_data_st *methdata = data;
|
||||
OPENSSL_CTX *libctx = ossl_provider_library_context(prov);
|
||||
OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx);
|
||||
int name_id = ossl_namemap_add(namemap, 0, name);
|
||||
|
||||
return methdata->method_from_dispatch(fns, prov);
|
||||
return methdata->method_from_dispatch(name_id, fns, prov,
|
||||
methdata->method_data);
|
||||
}
|
||||
|
||||
static void destruct_method(void *method, void *data)
|
||||
@@ -153,17 +192,20 @@ static void destruct_method(void *method, void *data)
|
||||
methdata->destruct_method(method);
|
||||
}
|
||||
|
||||
void *evp_generic_fetch(OPENSSL_CTX *libctx, int operation_id,
|
||||
const char *name, const char *properties,
|
||||
void *(*new_method)(const OSSL_DISPATCH *fns,
|
||||
OSSL_PROVIDER *prov),
|
||||
int (*up_ref_method)(void *),
|
||||
void (*free_method)(void *))
|
||||
static void *inner_generic_fetch(OPENSSL_CTX *libctx, int operation_id,
|
||||
int name_id, const char *name,
|
||||
const char *properties,
|
||||
void *(*new_method)(int name_id,
|
||||
const OSSL_DISPATCH *fns,
|
||||
OSSL_PROVIDER *prov,
|
||||
void *method_data),
|
||||
void *method_data,
|
||||
int (*up_ref_method)(void *),
|
||||
void (*free_method)(void *))
|
||||
{
|
||||
OSSL_METHOD_STORE *store = get_default_method_store(libctx);
|
||||
OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx);
|
||||
int nameid = 0;
|
||||
uint32_t methid = 0;
|
||||
uint32_t meth_id = 0;
|
||||
void *method = NULL;
|
||||
|
||||
if (store == NULL || namemap == NULL)
|
||||
@@ -177,17 +219,28 @@ void *evp_generic_fetch(OPENSSL_CTX *libctx, int operation_id,
|
||||
return NULL;
|
||||
|
||||
/*
|
||||
* If we have been passed neither a name_id or a name, we have an
|
||||
* internal programming error.
|
||||
*/
|
||||
if (!ossl_assert(name_id != 0 || name != NULL))
|
||||
return NULL;
|
||||
|
||||
/* If we haven't received a name id yet, try to get one for the name */
|
||||
if (name_id == 0)
|
||||
name_id = ossl_namemap_name2num(namemap, name);
|
||||
|
||||
/*
|
||||
* If we have a name id, calculate a method id with method_id().
|
||||
*
|
||||
* method_id returns 0 if we have too many operations (more than
|
||||
* about 2^8) or too many names (more than about 2^24). In that
|
||||
* case, we can't create any new method.
|
||||
*/
|
||||
if ((nameid = ossl_namemap_name2num(namemap, name)) != 0
|
||||
&& (methid = method_id(operation_id, nameid)) == 0)
|
||||
if (name_id != 0 && (meth_id = method_id(operation_id, name_id)) == 0)
|
||||
return NULL;
|
||||
|
||||
if (nameid == 0
|
||||
|| !ossl_method_store_cache_get(store, methid, properties,
|
||||
&method)) {
|
||||
if (meth_id == 0
|
||||
|| !ossl_method_store_cache_get(store, meth_id, properties, &method)) {
|
||||
OSSL_METHOD_CONSTRUCT_METHOD mcm = {
|
||||
alloc_tmp_method_store,
|
||||
dealloc_tmp_method_store,
|
||||
@@ -200,23 +253,28 @@ void *evp_generic_fetch(OPENSSL_CTX *libctx, int operation_id,
|
||||
|
||||
mcmdata.mcm = &mcm;
|
||||
mcmdata.libctx = libctx;
|
||||
mcmdata.operation_id = operation_id;
|
||||
mcmdata.name_id = name_id;
|
||||
mcmdata.name = name;
|
||||
mcmdata.propquery = properties;
|
||||
mcmdata.method_from_dispatch = new_method;
|
||||
mcmdata.destruct_method = free_method;
|
||||
mcmdata.refcnt_up_method = up_ref_method;
|
||||
mcmdata.destruct_method = free_method;
|
||||
if ((method = ossl_method_construct(libctx, operation_id, name,
|
||||
properties, 0 /* !force_cache */,
|
||||
mcmdata.method_data = method_data;
|
||||
if ((method = ossl_method_construct(libctx, operation_id,
|
||||
0 /* !force_cache */,
|
||||
&mcm, &mcmdata)) != NULL) {
|
||||
/*
|
||||
* If construction did create a method for us, we know that
|
||||
* there is a correct nameid and methodid, since those have
|
||||
* there is a correct name_id and methodid, since those have
|
||||
* already been calculated in get_method_from_store() and
|
||||
* put_method_in_store() above.
|
||||
*/
|
||||
nameid = ossl_namemap_name2num(namemap, name);
|
||||
methid = method_id(operation_id, nameid);
|
||||
ossl_method_store_cache_set(store, methid, properties, method);
|
||||
if (name_id == 0)
|
||||
name_id = ossl_namemap_name2num(namemap, name);
|
||||
meth_id = method_id(operation_id, name_id);
|
||||
ossl_method_store_cache_set(store, meth_id, properties, method);
|
||||
}
|
||||
} else {
|
||||
up_ref_method(method);
|
||||
@@ -225,6 +283,45 @@ void *evp_generic_fetch(OPENSSL_CTX *libctx, int operation_id,
|
||||
return method;
|
||||
}
|
||||
|
||||
void *evp_generic_fetch(OPENSSL_CTX *libctx, int operation_id,
|
||||
const char *name, const char *properties,
|
||||
void *(*new_method)(int name_id,
|
||||
const OSSL_DISPATCH *fns,
|
||||
OSSL_PROVIDER *prov,
|
||||
void *method_data),
|
||||
void *method_data,
|
||||
int (*up_ref_method)(void *),
|
||||
void (*free_method)(void *))
|
||||
{
|
||||
return inner_generic_fetch(libctx,
|
||||
operation_id, 0, name, properties,
|
||||
new_method, method_data,
|
||||
up_ref_method, free_method);
|
||||
}
|
||||
|
||||
/*
|
||||
* evp_generic_fetch_by_number() is special, and only returns methods for
|
||||
* already known names, i.e. it refuses to work if no name_id can be found
|
||||
* (it's considered an internal programming error).
|
||||
* This is meant to be used when one method needs to fetch an associated
|
||||
* other method.
|
||||
*/
|
||||
void *evp_generic_fetch_by_number(OPENSSL_CTX *libctx, int operation_id,
|
||||
int name_id, const char *properties,
|
||||
void *(*new_method)(int name_id,
|
||||
const OSSL_DISPATCH *fns,
|
||||
OSSL_PROVIDER *prov,
|
||||
void *method_data),
|
||||
void *method_data,
|
||||
int (*up_ref_method)(void *),
|
||||
void (*free_method)(void *))
|
||||
{
|
||||
return inner_generic_fetch(libctx,
|
||||
operation_id, name_id, NULL, properties,
|
||||
new_method, method_data,
|
||||
up_ref_method, free_method);
|
||||
}
|
||||
|
||||
int EVP_set_default_properties(OPENSSL_CTX *libctx, const char *propq)
|
||||
{
|
||||
OSSL_METHOD_STORE *store = get_default_method_store(libctx);
|
||||
@@ -234,3 +331,65 @@ int EVP_set_default_properties(OPENSSL_CTX *libctx, const char *propq)
|
||||
EVPerr(EVP_F_EVP_SET_DEFAULT_PROPERTIES, ERR_R_INTERNAL_ERROR);
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct do_all_data_st {
|
||||
void (*user_fn)(void *method, void *arg);
|
||||
void *user_arg;
|
||||
void *(*new_method)(const int name_id, const OSSL_DISPATCH *fns,
|
||||
OSSL_PROVIDER *prov, void *method_data);
|
||||
void (*free_method)(void *);
|
||||
};
|
||||
|
||||
static void do_one(OSSL_PROVIDER *provider, const OSSL_ALGORITHM *algo,
|
||||
int no_store, void *vdata)
|
||||
{
|
||||
struct do_all_data_st *data = vdata;
|
||||
OPENSSL_CTX *libctx = ossl_provider_library_context(provider);
|
||||
OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx);
|
||||
int name_id = ossl_namemap_add(namemap, 0, algo->algorithm_name);
|
||||
void *method = NULL;
|
||||
|
||||
if (name_id != 0)
|
||||
method = data->new_method(name_id, algo->implementation, provider,
|
||||
NULL);
|
||||
|
||||
if (method != NULL) {
|
||||
data->user_fn(method, data->user_arg);
|
||||
data->free_method(method);
|
||||
}
|
||||
}
|
||||
|
||||
void evp_generic_do_all(OPENSSL_CTX *libctx, int operation_id,
|
||||
void (*user_fn)(void *method, void *arg),
|
||||
void *user_arg,
|
||||
void *(*new_method)(int name_id,
|
||||
const OSSL_DISPATCH *fns,
|
||||
OSSL_PROVIDER *prov,
|
||||
void *method_data),
|
||||
void *method_data,
|
||||
void (*free_method)(void *))
|
||||
{
|
||||
struct do_all_data_st data;
|
||||
|
||||
data.new_method = new_method;
|
||||
data.free_method = free_method;
|
||||
data.user_fn = user_fn;
|
||||
data.user_arg = user_arg;
|
||||
ossl_algorithm_do_all(libctx, operation_id, method_data, do_one, &data);
|
||||
}
|
||||
|
||||
const char *evp_first_name(OSSL_PROVIDER *prov, int name_id)
|
||||
{
|
||||
OPENSSL_CTX *libctx = ossl_provider_library_context(prov);
|
||||
OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx);
|
||||
|
||||
return ossl_namemap_num2name(namemap, name_id, 0);
|
||||
}
|
||||
|
||||
int evp_is_a(OSSL_PROVIDER *prov, int number, const char *name)
|
||||
{
|
||||
OPENSSL_CTX *libctx = ossl_provider_library_context(prov);
|
||||
OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx);
|
||||
|
||||
return ossl_namemap_name2num(namemap, name) == number;
|
||||
}
|
||||
+211
-91
@@ -13,6 +13,7 @@
|
||||
#include <openssl/objects.h>
|
||||
#include <openssl/params.h>
|
||||
#include <openssl/core_names.h>
|
||||
#include <openssl/dh.h>
|
||||
#include "internal/evp_int.h"
|
||||
#include "internal/provider.h"
|
||||
#include "evp_locl.h"
|
||||
@@ -59,10 +60,10 @@ int EVP_CIPHER_param_to_asn1(EVP_CIPHER_CTX *c, ASN1_TYPE *type)
|
||||
}
|
||||
} else
|
||||
ret = -1;
|
||||
if (ret <= 0)
|
||||
EVPerr(EVP_F_EVP_CIPHER_PARAM_TO_ASN1, ret == -2 ?
|
||||
ASN1_R_UNSUPPORTED_CIPHER :
|
||||
EVP_R_CIPHER_PARAMETER_ERROR);
|
||||
if (ret == -2)
|
||||
EVPerr(EVP_F_EVP_CIPHER_PARAM_TO_ASN1, ASN1_R_UNSUPPORTED_CIPHER);
|
||||
else if (ret <= 0)
|
||||
EVPerr(EVP_F_EVP_CIPHER_PARAM_TO_ASN1, EVP_R_CIPHER_PARAMETER_ERROR);
|
||||
if (ret < -1)
|
||||
ret = -1;
|
||||
return ret;
|
||||
@@ -105,10 +106,10 @@ int EVP_CIPHER_asn1_to_param(EVP_CIPHER_CTX *c, ASN1_TYPE *type)
|
||||
}
|
||||
} else
|
||||
ret = -1;
|
||||
if (ret <= 0)
|
||||
EVPerr(EVP_F_EVP_CIPHER_ASN1_TO_PARAM, ret == -2 ?
|
||||
EVP_R_UNSUPPORTED_CIPHER :
|
||||
EVP_R_CIPHER_PARAMETER_ERROR);
|
||||
if (ret == -2)
|
||||
EVPerr(EVP_F_EVP_CIPHER_ASN1_TO_PARAM, EVP_R_UNSUPPORTED_CIPHER);
|
||||
else if (ret <= 0)
|
||||
EVPerr(EVP_F_EVP_CIPHER_ASN1_TO_PARAM, EVP_R_CIPHER_PARAMETER_ERROR);
|
||||
if (ret < -1)
|
||||
ret = -1;
|
||||
return ret;
|
||||
@@ -217,12 +218,14 @@ int EVP_CIPHER_type(const EVP_CIPHER *ctx)
|
||||
|
||||
int EVP_CIPHER_block_size(const EVP_CIPHER *cipher)
|
||||
{
|
||||
int v = cipher->block_size;
|
||||
int ok = evp_do_param(cipher, &v, sizeof(v),
|
||||
OSSL_CIPHER_PARAM_BLOCK_SIZE, OSSL_PARAM_INTEGER,
|
||||
evp_do_ciph_getparams, NULL);
|
||||
int ok;
|
||||
size_t v = cipher->block_size;
|
||||
OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END };
|
||||
|
||||
return ok != 0 ? v : -1;
|
||||
params[0] = OSSL_PARAM_construct_size_t(OSSL_CIPHER_PARAM_BLOCK_SIZE, &v);
|
||||
ok = evp_do_ciph_getparams(cipher, params);
|
||||
|
||||
return ok != 0 ? (int)v : EVP_CTRL_RET_UNSUPPORTED;
|
||||
}
|
||||
|
||||
int EVP_CIPHER_CTX_block_size(const EVP_CIPHER_CTX *ctx)
|
||||
@@ -265,10 +268,12 @@ int EVP_CIPHER_CTX_encrypting(const EVP_CIPHER_CTX *ctx)
|
||||
|
||||
unsigned long EVP_CIPHER_flags(const EVP_CIPHER *cipher)
|
||||
{
|
||||
int ok;
|
||||
unsigned long v = cipher->flags;
|
||||
int ok = evp_do_param(cipher, &v, sizeof(v),
|
||||
OSSL_CIPHER_PARAM_FLAGS, OSSL_PARAM_UNSIGNED_INTEGER,
|
||||
evp_do_ciph_getparams, NULL);
|
||||
OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END };
|
||||
|
||||
params[0] = OSSL_PARAM_construct_ulong(OSSL_CIPHER_PARAM_FLAGS, &v);
|
||||
ok = evp_do_ciph_getparams(cipher, params);
|
||||
|
||||
return ok != 0 ? v : 0;
|
||||
}
|
||||
@@ -300,17 +305,46 @@ void *EVP_CIPHER_CTX_set_cipher_data(EVP_CIPHER_CTX *ctx, void *cipher_data)
|
||||
|
||||
int EVP_CIPHER_iv_length(const EVP_CIPHER *cipher)
|
||||
{
|
||||
int v = cipher->iv_len;
|
||||
int ok = evp_do_param(cipher, &v, sizeof(v),
|
||||
OSSL_CIPHER_PARAM_IVLEN, OSSL_PARAM_UNSIGNED_INTEGER,
|
||||
evp_do_ciph_getparams, NULL);
|
||||
int ok;
|
||||
size_t v = cipher->iv_len;
|
||||
OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END };
|
||||
|
||||
return ok != 0 ? v: -1;
|
||||
params[0] = OSSL_PARAM_construct_size_t(OSSL_CIPHER_PARAM_IVLEN, &v);
|
||||
ok = evp_do_ciph_getparams(cipher, params);
|
||||
|
||||
return ok != 0 ? (int)v : EVP_CTRL_RET_UNSUPPORTED;
|
||||
}
|
||||
|
||||
int EVP_CIPHER_CTX_iv_length(const EVP_CIPHER_CTX *ctx)
|
||||
{
|
||||
return EVP_CIPHER_iv_length(ctx->cipher);
|
||||
int rv, len = EVP_CIPHER_iv_length(ctx->cipher);
|
||||
size_t v = len;
|
||||
OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END };
|
||||
|
||||
params[0] = OSSL_PARAM_construct_size_t(OSSL_CIPHER_PARAM_IVLEN, &v);
|
||||
rv = evp_do_ciph_ctx_getparams(ctx->cipher, ctx->provctx, params);
|
||||
if (rv == EVP_CTRL_RET_UNSUPPORTED)
|
||||
goto legacy;
|
||||
return rv != 0 ? (int)v : -1;
|
||||
/* TODO (3.0) Remove legacy support */
|
||||
legacy:
|
||||
if ((EVP_CIPHER_flags(ctx->cipher) & EVP_CIPH_CUSTOM_IV_LENGTH) != 0) {
|
||||
rv = EVP_CIPHER_CTX_ctrl((EVP_CIPHER_CTX *)ctx, EVP_CTRL_GET_IVLEN,
|
||||
0, &len);
|
||||
return (rv == 1) ? len : -1;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
int EVP_CIPHER_CTX_tag_length(const EVP_CIPHER_CTX *ctx)
|
||||
{
|
||||
int ret;
|
||||
size_t v = 0;
|
||||
OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END };
|
||||
|
||||
params[0] = OSSL_PARAM_construct_size_t(OSSL_CIPHER_PARAM_AEAD_TAGLEN, &v);
|
||||
ret = evp_do_ciph_ctx_getparams(ctx->cipher, ctx->provctx, params);
|
||||
return ret == 1 ? (int)v : 0;
|
||||
}
|
||||
|
||||
const unsigned char *EVP_CIPHER_CTX_original_iv(const EVP_CIPHER_CTX *ctx)
|
||||
@@ -323,22 +357,30 @@ const unsigned char *EVP_CIPHER_CTX_original_iv(const EVP_CIPHER_CTX *ctx)
|
||||
*/
|
||||
const unsigned char *EVP_CIPHER_CTX_iv(const EVP_CIPHER_CTX *ctx)
|
||||
{
|
||||
int ok;
|
||||
const unsigned char *v = ctx->iv;
|
||||
int ok = evp_do_param(ctx->cipher, &v, sizeof(ctx->iv),
|
||||
OSSL_CIPHER_PARAM_IV, OSSL_PARAM_OCTET_PTR,
|
||||
evp_do_ciph_ctx_getparams, ctx->provctx);
|
||||
OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END };
|
||||
|
||||
return ok != 0 ? v: NULL;
|
||||
params[0] =
|
||||
OSSL_PARAM_construct_octet_ptr(OSSL_CIPHER_PARAM_IV, (void **)&v,
|
||||
sizeof(ctx->iv));
|
||||
ok = evp_do_ciph_ctx_getparams(ctx->cipher, ctx->provctx, params);
|
||||
|
||||
return ok != 0 ? v : NULL;
|
||||
}
|
||||
|
||||
unsigned char *EVP_CIPHER_CTX_iv_noconst(EVP_CIPHER_CTX *ctx)
|
||||
{
|
||||
int ok;
|
||||
unsigned char *v = ctx->iv;
|
||||
int ok = evp_do_param(ctx->cipher, &v, sizeof(ctx->iv),
|
||||
OSSL_CIPHER_PARAM_IV, OSSL_PARAM_OCTET_PTR,
|
||||
evp_do_ciph_ctx_getparams, ctx->provctx);
|
||||
OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END };
|
||||
|
||||
return ok != 0 ? v: NULL;
|
||||
params[0] =
|
||||
OSSL_PARAM_construct_octet_ptr(OSSL_CIPHER_PARAM_IV, (void **)&v,
|
||||
sizeof(ctx->iv));
|
||||
ok = evp_do_ciph_ctx_getparams(ctx->cipher, ctx->provctx, params);
|
||||
|
||||
return ok != 0 ? v : NULL;
|
||||
}
|
||||
|
||||
unsigned char *EVP_CIPHER_CTX_buf_noconst(EVP_CIPHER_CTX *ctx)
|
||||
@@ -348,42 +390,52 @@ unsigned char *EVP_CIPHER_CTX_buf_noconst(EVP_CIPHER_CTX *ctx)
|
||||
|
||||
int EVP_CIPHER_CTX_num(const EVP_CIPHER_CTX *ctx)
|
||||
{
|
||||
int v = ctx->num;
|
||||
int ok = evp_do_param(ctx->cipher, &v, sizeof(v),
|
||||
OSSL_CIPHER_PARAM_NUM, OSSL_PARAM_INTEGER,
|
||||
evp_do_ciph_ctx_getparams, ctx->provctx);
|
||||
int ok;
|
||||
unsigned int v = (unsigned int)ctx->num;
|
||||
OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END };
|
||||
|
||||
return ok != 0 ? v: -1;
|
||||
params[0] = OSSL_PARAM_construct_uint(OSSL_CIPHER_PARAM_NUM, &v);
|
||||
ok = evp_do_ciph_ctx_getparams(ctx->cipher, ctx->provctx, params);
|
||||
|
||||
return ok != 0 ? (int)v : EVP_CTRL_RET_UNSUPPORTED;
|
||||
}
|
||||
|
||||
int EVP_CIPHER_CTX_set_num(EVP_CIPHER_CTX *ctx, int num)
|
||||
{
|
||||
int ok = evp_do_param(ctx->cipher, &num, sizeof(num),
|
||||
OSSL_CIPHER_PARAM_NUM, OSSL_PARAM_INTEGER,
|
||||
evp_do_ciph_ctx_setparams, ctx->provctx);
|
||||
int ok;
|
||||
unsigned int n = (unsigned int)num;
|
||||
OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END };
|
||||
|
||||
ctx->num = num;
|
||||
params[0] = OSSL_PARAM_construct_uint(OSSL_CIPHER_PARAM_NUM, &n);
|
||||
ok = evp_do_ciph_ctx_setparams(ctx->cipher, ctx->provctx, params);
|
||||
|
||||
if (ok != 0)
|
||||
ctx->num = (int)n;
|
||||
return ok != 0;
|
||||
}
|
||||
|
||||
int EVP_CIPHER_key_length(const EVP_CIPHER *cipher)
|
||||
{
|
||||
int v = cipher->key_len;
|
||||
int ok = evp_do_param(cipher, &v, sizeof(v),
|
||||
OSSL_CIPHER_PARAM_KEYLEN, OSSL_PARAM_INTEGER,
|
||||
evp_do_ciph_getparams, NULL);
|
||||
int ok;
|
||||
size_t v = cipher->key_len;
|
||||
OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END };
|
||||
|
||||
return ok != 0 ? v: -1;
|
||||
params[0] = OSSL_PARAM_construct_size_t(OSSL_CIPHER_PARAM_KEYLEN, &v);
|
||||
ok = evp_do_ciph_getparams(cipher, params);
|
||||
|
||||
return ok != 0 ? (int)v : EVP_CTRL_RET_UNSUPPORTED;
|
||||
}
|
||||
|
||||
int EVP_CIPHER_CTX_key_length(const EVP_CIPHER_CTX *ctx)
|
||||
{
|
||||
int v = ctx->key_len;
|
||||
int ok = evp_do_param(ctx->cipher, &v, sizeof(v),
|
||||
OSSL_CIPHER_PARAM_KEYLEN, OSSL_PARAM_INTEGER,
|
||||
evp_do_ciph_ctx_getparams, ctx->provctx);
|
||||
int ok;
|
||||
size_t v = ctx->key_len;
|
||||
OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END };
|
||||
|
||||
return ok != 0 ? v: -1;
|
||||
params[0] = OSSL_PARAM_construct_size_t(OSSL_CIPHER_PARAM_KEYLEN, &v);
|
||||
ok = evp_do_ciph_ctx_getparams(ctx->cipher, ctx->provctx, params);
|
||||
|
||||
return ok != 0 ? (int)v : EVP_CTRL_RET_UNSUPPORTED;
|
||||
}
|
||||
|
||||
int EVP_CIPHER_nid(const EVP_CIPHER *cipher)
|
||||
@@ -396,28 +448,70 @@ int EVP_CIPHER_CTX_nid(const EVP_CIPHER_CTX *ctx)
|
||||
return ctx->cipher->nid;
|
||||
}
|
||||
|
||||
int EVP_CIPHER_mode(const EVP_CIPHER *cipher)
|
||||
int EVP_CIPHER_is_a(const EVP_CIPHER *cipher, const char *name)
|
||||
{
|
||||
int v = EVP_CIPHER_flags(cipher) & EVP_CIPH_MODE;
|
||||
int ok = evp_do_param(cipher, &v, sizeof(v),
|
||||
OSSL_CIPHER_PARAM_MODE, OSSL_PARAM_INTEGER,
|
||||
evp_do_ciph_getparams, NULL);
|
||||
|
||||
return ok != 0 ? v: 0;
|
||||
return evp_is_a(cipher->prov, cipher->name_id, name);
|
||||
}
|
||||
|
||||
const char *EVP_CIPHER_name(const EVP_CIPHER *cipher)
|
||||
{
|
||||
if (cipher->prov != NULL)
|
||||
return evp_first_name(cipher->prov, cipher->name_id);
|
||||
#ifndef FIPS_MODE
|
||||
return OBJ_nid2sn(EVP_CIPHER_nid(cipher));
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
const OSSL_PROVIDER *EVP_CIPHER_provider(const EVP_CIPHER *cipher)
|
||||
{
|
||||
return cipher->prov;
|
||||
}
|
||||
|
||||
int EVP_CIPHER_mode(const EVP_CIPHER *cipher)
|
||||
{
|
||||
int ok;
|
||||
unsigned int v = EVP_CIPHER_flags(cipher) & EVP_CIPH_MODE;
|
||||
OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END };
|
||||
|
||||
params[0] = OSSL_PARAM_construct_uint(OSSL_CIPHER_PARAM_MODE, &v);
|
||||
ok = evp_do_ciph_getparams(cipher, params);
|
||||
|
||||
return ok != 0 ? (int)v : 0;
|
||||
}
|
||||
|
||||
const char *EVP_MD_name(const EVP_MD *md)
|
||||
{
|
||||
if (md->prov != NULL)
|
||||
return evp_first_name(md->prov, md->name_id);
|
||||
#ifndef FIPS_MODE
|
||||
return OBJ_nid2sn(EVP_MD_nid(md));
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
const OSSL_PROVIDER *EVP_MD_provider(const EVP_MD *md)
|
||||
{
|
||||
return md->prov;
|
||||
}
|
||||
|
||||
int EVP_MD_block_size(const EVP_MD *md)
|
||||
{
|
||||
int ok;
|
||||
size_t v = md->block_size;
|
||||
OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END };
|
||||
|
||||
if (md == NULL) {
|
||||
EVPerr(EVP_F_EVP_MD_BLOCK_SIZE, EVP_R_MESSAGE_DIGEST_IS_NULL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (md->prov != NULL && md->dblock_size != NULL)
|
||||
return (int)md->dblock_size();
|
||||
params[0] = OSSL_PARAM_construct_size_t(OSSL_DIGEST_PARAM_BLOCK_SIZE, &v);
|
||||
ok = evp_do_md_getparams(md, params);
|
||||
|
||||
return md->block_size;
|
||||
return ok != 0 ? (int)v : -1;
|
||||
}
|
||||
|
||||
int EVP_MD_type(const EVP_MD *md)
|
||||
@@ -432,94 +526,105 @@ int EVP_MD_pkey_type(const EVP_MD *md)
|
||||
|
||||
int EVP_MD_size(const EVP_MD *md)
|
||||
{
|
||||
if (!md) {
|
||||
int ok;
|
||||
size_t v = md->md_size;
|
||||
OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END };
|
||||
|
||||
if (md == NULL) {
|
||||
EVPerr(EVP_F_EVP_MD_SIZE, EVP_R_MESSAGE_DIGEST_IS_NULL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (md->prov != NULL && md->size != NULL)
|
||||
return (int)md->size();
|
||||
params[0] = OSSL_PARAM_construct_size_t(OSSL_DIGEST_PARAM_SIZE, &v);
|
||||
ok = evp_do_md_getparams(md, params);
|
||||
|
||||
return md->md_size;
|
||||
return ok != 0 ? (int)v : -1;
|
||||
}
|
||||
|
||||
unsigned long EVP_MD_flags(const EVP_MD *md)
|
||||
{
|
||||
return md->flags;
|
||||
int ok;
|
||||
unsigned long v = md->flags;
|
||||
OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END };
|
||||
|
||||
params[0] = OSSL_PARAM_construct_ulong(OSSL_CIPHER_PARAM_FLAGS, &v);
|
||||
ok = evp_do_md_getparams(md, params);
|
||||
|
||||
return ok != 0 ? v : 0;
|
||||
}
|
||||
|
||||
EVP_MD *EVP_MD_meth_new(int md_type, int pkey_type)
|
||||
{
|
||||
EVP_MD *md = OPENSSL_zalloc(sizeof(*md));
|
||||
EVP_MD *md = evp_md_new();
|
||||
|
||||
if (md != NULL) {
|
||||
md->type = md_type;
|
||||
md->pkey_type = pkey_type;
|
||||
md->lock = CRYPTO_THREAD_lock_new();
|
||||
if (md->lock == NULL) {
|
||||
OPENSSL_free(md);
|
||||
return NULL;
|
||||
}
|
||||
md->refcnt = 1;
|
||||
}
|
||||
return md;
|
||||
}
|
||||
|
||||
EVP_MD *EVP_MD_meth_dup(const EVP_MD *md)
|
||||
{
|
||||
EVP_MD *to = EVP_MD_meth_new(md->type, md->pkey_type);
|
||||
EVP_MD *to = NULL;
|
||||
|
||||
if (to != NULL) {
|
||||
/*
|
||||
* Non-legacy EVP_MDs can't be duplicated like this.
|
||||
* Use EVP_MD_up_ref() instead.
|
||||
*/
|
||||
if (md->prov != NULL)
|
||||
return NULL;
|
||||
|
||||
if ((to = EVP_MD_meth_new(md->type, md->pkey_type)) != NULL) {
|
||||
CRYPTO_RWLOCK *lock = to->lock;
|
||||
|
||||
memcpy(to, md, sizeof(*to));
|
||||
to->lock = lock;
|
||||
}
|
||||
return to;
|
||||
}
|
||||
|
||||
int EVP_MD_up_ref(EVP_MD *md)
|
||||
{
|
||||
int ref = 0;
|
||||
|
||||
CRYPTO_UP_REF(&md->refcnt, &ref, md->lock);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void EVP_MD_meth_free(EVP_MD *md)
|
||||
{
|
||||
if (md != NULL) {
|
||||
int i;
|
||||
|
||||
CRYPTO_DOWN_REF(&md->refcnt, &i, md->lock);
|
||||
if (i > 0)
|
||||
return;
|
||||
ossl_provider_free(md->prov);
|
||||
CRYPTO_THREAD_lock_free(md->lock);
|
||||
OPENSSL_free(md);
|
||||
}
|
||||
EVP_MD_free(md);
|
||||
}
|
||||
int EVP_MD_meth_set_input_blocksize(EVP_MD *md, int blocksize)
|
||||
{
|
||||
if (md->block_size != 0)
|
||||
return 0;
|
||||
|
||||
md->block_size = blocksize;
|
||||
return 1;
|
||||
}
|
||||
int EVP_MD_meth_set_result_size(EVP_MD *md, int resultsize)
|
||||
{
|
||||
if (md->md_size != 0)
|
||||
return 0;
|
||||
|
||||
md->md_size = resultsize;
|
||||
return 1;
|
||||
}
|
||||
int EVP_MD_meth_set_app_datasize(EVP_MD *md, int datasize)
|
||||
{
|
||||
if (md->ctx_size != 0)
|
||||
return 0;
|
||||
|
||||
md->ctx_size = datasize;
|
||||
return 1;
|
||||
}
|
||||
int EVP_MD_meth_set_flags(EVP_MD *md, unsigned long flags)
|
||||
{
|
||||
if (md->flags != 0)
|
||||
return 0;
|
||||
|
||||
md->flags = flags;
|
||||
return 1;
|
||||
}
|
||||
int EVP_MD_meth_set_init(EVP_MD *md, int (*init)(EVP_MD_CTX *ctx))
|
||||
{
|
||||
if (md->init != NULL)
|
||||
return 0;
|
||||
|
||||
md->init = init;
|
||||
return 1;
|
||||
}
|
||||
@@ -527,29 +632,44 @@ int EVP_MD_meth_set_update(EVP_MD *md, int (*update)(EVP_MD_CTX *ctx,
|
||||
const void *data,
|
||||
size_t count))
|
||||
{
|
||||
if (md->update != NULL)
|
||||
return 0;
|
||||
|
||||
md->update = update;
|
||||
return 1;
|
||||
}
|
||||
int EVP_MD_meth_set_final(EVP_MD *md, int (*final)(EVP_MD_CTX *ctx,
|
||||
unsigned char *md))
|
||||
{
|
||||
if (md->final != NULL)
|
||||
return 0;
|
||||
|
||||
md->final = final;
|
||||
return 1;
|
||||
}
|
||||
int EVP_MD_meth_set_copy(EVP_MD *md, int (*copy)(EVP_MD_CTX *to,
|
||||
const EVP_MD_CTX *from))
|
||||
{
|
||||
if (md->copy != NULL)
|
||||
return 0;
|
||||
|
||||
md->copy = copy;
|
||||
return 1;
|
||||
}
|
||||
int EVP_MD_meth_set_cleanup(EVP_MD *md, int (*cleanup)(EVP_MD_CTX *ctx))
|
||||
{
|
||||
if (md->cleanup != NULL)
|
||||
return 0;
|
||||
|
||||
md->cleanup = cleanup;
|
||||
return 1;
|
||||
}
|
||||
int EVP_MD_meth_set_ctrl(EVP_MD *md, int (*ctrl)(EVP_MD_CTX *ctx, int cmd,
|
||||
int p1, void *p2))
|
||||
{
|
||||
if (md->md_ctrl != NULL)
|
||||
return 0;
|
||||
|
||||
md->md_ctrl = ctrl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
+146
-27
@@ -9,6 +9,11 @@
|
||||
|
||||
/* EVP_MD_CTX related stuff */
|
||||
|
||||
#include <openssl/core_numbers.h>
|
||||
|
||||
#define EVP_CTRL_RET_UNSUPPORTED -1
|
||||
|
||||
|
||||
struct evp_md_ctx_st {
|
||||
const EVP_MD *reqdigest; /* The original requested digest */
|
||||
const EVP_MD *digest;
|
||||
@@ -51,15 +56,87 @@ struct evp_cipher_ctx_st {
|
||||
} /* EVP_CIPHER_CTX */ ;
|
||||
|
||||
struct evp_mac_ctx_st {
|
||||
const EVP_MAC *meth; /* Method structure */
|
||||
EVP_MAC *meth; /* Method structure */
|
||||
void *data; /* Individual method data */
|
||||
} /* EVP_MAC_CTX */;
|
||||
|
||||
struct evp_kdf_ctx_st {
|
||||
const EVP_KDF *meth; /* Method structure */
|
||||
EVP_KDF_IMPL *impl; /* Algorithm-specific data */
|
||||
EVP_KDF *meth; /* Method structure */
|
||||
void *data; /* Algorithm-specific data */
|
||||
} /* EVP_KDF_CTX */ ;
|
||||
|
||||
struct evp_keymgmt_st {
|
||||
int id; /* libcrypto internal */
|
||||
|
||||
int name_id;
|
||||
OSSL_PROVIDER *prov;
|
||||
CRYPTO_REF_COUNT refcnt;
|
||||
CRYPTO_RWLOCK *lock;
|
||||
|
||||
/* Domain parameter routines */
|
||||
OSSL_OP_keymgmt_importdomparams_fn *importdomparams;
|
||||
OSSL_OP_keymgmt_gendomparams_fn *gendomparams;
|
||||
OSSL_OP_keymgmt_freedomparams_fn *freedomparams;
|
||||
OSSL_OP_keymgmt_exportdomparams_fn *exportdomparams;
|
||||
OSSL_OP_keymgmt_importdomparam_types_fn *importdomparam_types;
|
||||
OSSL_OP_keymgmt_exportdomparam_types_fn *exportdomparam_types;
|
||||
|
||||
/* Key routines */
|
||||
OSSL_OP_keymgmt_importkey_fn *importkey;
|
||||
OSSL_OP_keymgmt_genkey_fn *genkey;
|
||||
OSSL_OP_keymgmt_loadkey_fn *loadkey;
|
||||
OSSL_OP_keymgmt_freekey_fn *freekey;
|
||||
OSSL_OP_keymgmt_exportkey_fn *exportkey;
|
||||
OSSL_OP_keymgmt_importkey_types_fn *importkey_types;
|
||||
OSSL_OP_keymgmt_exportkey_types_fn *exportkey_types;
|
||||
} /* EVP_KEYMGMT */ ;
|
||||
|
||||
struct keymgmt_data_st {
|
||||
OPENSSL_CTX *ctx;
|
||||
const char *properties;
|
||||
};
|
||||
|
||||
struct evp_keyexch_st {
|
||||
int name_id;
|
||||
OSSL_PROVIDER *prov;
|
||||
CRYPTO_REF_COUNT refcnt;
|
||||
CRYPTO_RWLOCK *lock;
|
||||
|
||||
EVP_KEYMGMT *keymgmt;
|
||||
|
||||
OSSL_OP_keyexch_newctx_fn *newctx;
|
||||
OSSL_OP_keyexch_init_fn *init;
|
||||
OSSL_OP_keyexch_set_peer_fn *set_peer;
|
||||
OSSL_OP_keyexch_derive_fn *derive;
|
||||
OSSL_OP_keyexch_freectx_fn *freectx;
|
||||
OSSL_OP_keyexch_dupctx_fn *dupctx;
|
||||
OSSL_OP_keyexch_set_ctx_params_fn *set_ctx_params;
|
||||
OSSL_OP_keyexch_settable_ctx_params_fn *settable_ctx_params;
|
||||
} /* EVP_KEYEXCH */;
|
||||
|
||||
struct evp_signature_st {
|
||||
int name_id;
|
||||
OSSL_PROVIDER *prov;
|
||||
CRYPTO_REF_COUNT refcnt;
|
||||
CRYPTO_RWLOCK *lock;
|
||||
|
||||
EVP_KEYMGMT *keymgmt;
|
||||
|
||||
OSSL_OP_signature_newctx_fn *newctx;
|
||||
OSSL_OP_signature_sign_init_fn *sign_init;
|
||||
OSSL_OP_signature_sign_fn *sign;
|
||||
OSSL_OP_signature_verify_init_fn *verify_init;
|
||||
OSSL_OP_signature_verify_fn *verify;
|
||||
OSSL_OP_signature_verify_recover_init_fn *verify_recover_init;
|
||||
OSSL_OP_signature_verify_recover_fn *verify_recover;
|
||||
OSSL_OP_signature_freectx_fn *freectx;
|
||||
OSSL_OP_signature_dupctx_fn *dupctx;
|
||||
OSSL_OP_signature_get_ctx_params_fn *get_ctx_params;
|
||||
OSSL_OP_signature_gettable_ctx_params_fn *gettable_ctx_params;
|
||||
OSSL_OP_signature_set_ctx_params_fn *set_ctx_params;
|
||||
OSSL_OP_signature_settable_ctx_params_fn *settable_ctx_params;
|
||||
} /* EVP_SIGNATURE */;
|
||||
|
||||
int PKCS5_v2_PBKDF2_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass,
|
||||
int passlen, ASN1_TYPE *param,
|
||||
const EVP_CIPHER *c, const EVP_MD *md,
|
||||
@@ -90,16 +167,45 @@ int is_partially_overlapping(const void *ptr1, const void *ptr2, int len);
|
||||
#include <openssl/core.h>
|
||||
|
||||
void *evp_generic_fetch(OPENSSL_CTX *ctx, int operation_id,
|
||||
const char *algorithm, const char *properties,
|
||||
void *(*new_method)(const OSSL_DISPATCH *fns,
|
||||
OSSL_PROVIDER *prov),
|
||||
const char *name, const char *properties,
|
||||
void *(*new_method)(int name_id,
|
||||
const OSSL_DISPATCH *fns,
|
||||
OSSL_PROVIDER *prov,
|
||||
void *method_data),
|
||||
void *method_data,
|
||||
int (*up_ref_method)(void *),
|
||||
void (*free_method)(void *));
|
||||
void *evp_generic_fetch_by_number(OPENSSL_CTX *ctx, int operation_id,
|
||||
int name_id, const char *properties,
|
||||
void *(*new_method)(int name_id,
|
||||
const OSSL_DISPATCH *fns,
|
||||
OSSL_PROVIDER *prov,
|
||||
void *method_data),
|
||||
void *method_data,
|
||||
int (*up_ref_method)(void *),
|
||||
void (*free_method)(void *));
|
||||
void evp_generic_do_all(OPENSSL_CTX *libctx, int operation_id,
|
||||
void (*user_fn)(void *method, void *arg),
|
||||
void *user_arg,
|
||||
void *(*new_method)(int name_id,
|
||||
const OSSL_DISPATCH *fns,
|
||||
OSSL_PROVIDER *prov,
|
||||
void *method_data),
|
||||
void *method_data,
|
||||
void (*free_method)(void *));
|
||||
|
||||
/* Internal fetchers for method types that are to be combined with others */
|
||||
EVP_KEYMGMT *evp_keymgmt_fetch_by_number(OPENSSL_CTX *ctx, int name_id,
|
||||
const char *properties);
|
||||
|
||||
/* Internal structure constructors for fetched methods */
|
||||
EVP_MD *evp_md_new(void);
|
||||
EVP_CIPHER *evp_cipher_new(void);
|
||||
|
||||
/* Helper functions to avoid duplicating code */
|
||||
|
||||
/*
|
||||
* The callbacks implement different ways to pass a params array to the
|
||||
* These methods implement different ways to pass a params array to the
|
||||
* provider. They will return one of these values:
|
||||
*
|
||||
* -2 if the method doesn't come from a provider
|
||||
@@ -109,26 +215,39 @@ void *evp_generic_fetch(OPENSSL_CTX *ctx, int operation_id,
|
||||
* or the return value from the desired function
|
||||
* (evp_do_param will return it to the caller)
|
||||
*/
|
||||
int evp_do_ciph_getparams(const void *vciph, void *ignored,
|
||||
OSSL_PARAM params[]);
|
||||
int evp_do_ciph_ctx_getparams(const void *vciph, void *provctx,
|
||||
int evp_do_ciph_getparams(const EVP_CIPHER *ciph, OSSL_PARAM params[]);
|
||||
int evp_do_ciph_ctx_getparams(const EVP_CIPHER *ciph, void *provctx,
|
||||
OSSL_PARAM params[]);
|
||||
int evp_do_ciph_ctx_setparams(const void *vciph, void *provctx,
|
||||
int evp_do_ciph_ctx_setparams(const EVP_CIPHER *ciph, void *provctx,
|
||||
OSSL_PARAM params[]);
|
||||
int evp_do_md_getparams(const EVP_MD *md, OSSL_PARAM params[]);
|
||||
int evp_do_md_ctx_getparams(const EVP_MD *md, void *provctx,
|
||||
OSSL_PARAM params[]);
|
||||
int evp_do_md_ctx_setparams(const EVP_MD *md, void *provctx,
|
||||
OSSL_PARAM params[]);
|
||||
|
||||
/*-
|
||||
* prepares a singular parameter, then calls the callback to execute.
|
||||
*
|
||||
* |method| points to the method used by the callback.
|
||||
* EVP_CIPHER, EVP_MD, ...
|
||||
* |ptr| points at the data to transfer.
|
||||
* |sz| is the size of the data to transfer.
|
||||
* |key| is the name of the parameter to pass.
|
||||
* |datatype| is the data type of the parameter to pass.
|
||||
* |cb| is the callback that actually performs the parameter passing
|
||||
* |cb_ctx| is the cipher context
|
||||
*/
|
||||
int evp_do_param(const void *method, void *ptr, size_t sz, const char *key,
|
||||
int datatype,
|
||||
int (*cb)(const void *method, void *ctx, OSSL_PARAM params[]),
|
||||
void *cb_ctx);
|
||||
OSSL_PARAM *evp_pkey_to_param(EVP_PKEY *pkey, size_t *sz);
|
||||
|
||||
#define M_check_autoarg(ctx, arg, arglen, err) \
|
||||
if (ctx->pmeth->flags & EVP_PKEY_FLAG_AUTOARGLEN) { \
|
||||
size_t pksize = (size_t)EVP_PKEY_size(ctx->pkey); \
|
||||
\
|
||||
if (pksize == 0) { \
|
||||
ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_KEY); /*ckerr_ignore*/ \
|
||||
return 0; \
|
||||
} \
|
||||
if (arg == NULL) { \
|
||||
*arglen = pksize; \
|
||||
return 1; \
|
||||
} \
|
||||
if (*arglen < pksize) { \
|
||||
ERR_raise(ERR_LIB_EVP, EVP_R_BUFFER_TOO_SMALL); /*ckerr_ignore*/ \
|
||||
return 0; \
|
||||
} \
|
||||
}
|
||||
|
||||
void evp_pkey_ctx_free_old_ops(EVP_PKEY_CTX *ctx);
|
||||
|
||||
/* OSSL_PROVIDER * is only used to get the library context */
|
||||
const char *evp_first_name(OSSL_PROVIDER *prov, int name_id);
|
||||
int evp_is_a(OSSL_PROVIDER *prov, int number, const char *name);
|
||||
+60
-57
@@ -17,62 +17,65 @@
|
||||
#include "internal/evp_int.h" /* evp_locl.h needs it */
|
||||
#include "evp_locl.h"
|
||||
|
||||
int evp_do_ciph_getparams(const void *vciph, void *ignored,
|
||||
OSSL_PARAM params[])
|
||||
{
|
||||
const EVP_CIPHER *ciph = vciph;
|
||||
|
||||
if (ciph->prov == NULL)
|
||||
return -2;
|
||||
if (ciph->get_params == NULL)
|
||||
return -1;
|
||||
return ciph->get_params(params);
|
||||
}
|
||||
|
||||
int evp_do_ciph_ctx_getparams(const void *vciph, void *provctx,
|
||||
OSSL_PARAM params[])
|
||||
{
|
||||
const EVP_CIPHER *ciph = vciph;
|
||||
|
||||
if (ciph->prov == NULL)
|
||||
return -2;
|
||||
if (ciph->ctx_get_params == NULL)
|
||||
return -1;
|
||||
return ciph->ctx_get_params(provctx, params);
|
||||
}
|
||||
|
||||
int evp_do_ciph_ctx_setparams(const void *vciph, void *provctx,
|
||||
OSSL_PARAM params[])
|
||||
{
|
||||
const EVP_CIPHER *ciph = vciph;
|
||||
|
||||
if (ciph->prov == NULL)
|
||||
return -2;
|
||||
if (ciph->ctx_set_params == NULL)
|
||||
return -1;
|
||||
return ciph->ctx_set_params(provctx, params);
|
||||
}
|
||||
|
||||
int evp_do_param(const void *method, void *ptr, size_t sz, const char *key,
|
||||
int datatype,
|
||||
int (*cb)(const void *method, void *ctx, OSSL_PARAM params[]),
|
||||
void *cb_ctx)
|
||||
{
|
||||
OSSL_PARAM params[2] = {
|
||||
OSSL_PARAM_END,
|
||||
OSSL_PARAM_END
|
||||
};
|
||||
int ret;
|
||||
|
||||
params[0].key = key;
|
||||
params[0].data_type = datatype;
|
||||
params[0].data = ptr;
|
||||
params[0].data_size = sz;
|
||||
|
||||
ret = cb(method, cb_ctx, params);
|
||||
if (ret == -1) {
|
||||
EVPerr(0, EVP_R_CTRL_NOT_IMPLEMENTED);
|
||||
ret = 0;
|
||||
/*
|
||||
* EVP_CTRL_RET_UNSUPPORTED = -1 is the returned value from any ctrl function
|
||||
* where the control command isn't supported, and an alternative code path
|
||||
* may be chosen.
|
||||
* Since these functions are used to implement ctrl functionality, we
|
||||
* use the same value, and other callers will have to compensate.
|
||||
*/
|
||||
#define PARAM_CHECK(obj, func, errfunc) \
|
||||
if (obj == NULL) \
|
||||
return 0; \
|
||||
if (obj->prov == NULL) \
|
||||
return EVP_CTRL_RET_UNSUPPORTED; \
|
||||
if (obj->func == NULL) { \
|
||||
errfunc(); \
|
||||
return 0; \
|
||||
}
|
||||
return ret;
|
||||
|
||||
#define PARAM_FUNC(name, func, type, err) \
|
||||
int name (const type *obj, OSSL_PARAM params[]) \
|
||||
{ \
|
||||
PARAM_CHECK(obj, func, err) \
|
||||
return obj->func(params); \
|
||||
}
|
||||
|
||||
#define PARAM_CTX_FUNC(name, func, type, err) \
|
||||
int name (const type *obj, void *provctx, OSSL_PARAM params[]) \
|
||||
{ \
|
||||
PARAM_CHECK(obj, func, err) \
|
||||
return obj->func(provctx, params); \
|
||||
}
|
||||
|
||||
#define PARAM_FUNCTIONS(type, \
|
||||
getname, getfunc, \
|
||||
getctxname, getctxfunc, \
|
||||
setctxname, setctxfunc) \
|
||||
PARAM_FUNC(getname, getfunc, type, geterr) \
|
||||
PARAM_CTX_FUNC(getctxname, getctxfunc, type, geterr) \
|
||||
PARAM_CTX_FUNC(setctxname, setctxfunc, type, seterr)
|
||||
|
||||
/*
|
||||
* These error functions are a workaround for the error scripts, which
|
||||
* currently require that XXXerr method appears inside a function (not a macro).
|
||||
*/
|
||||
static void geterr(void)
|
||||
{
|
||||
EVPerr(0, EVP_R_CANNOT_GET_PARAMETERS);
|
||||
}
|
||||
|
||||
static void seterr(void)
|
||||
{
|
||||
EVPerr(0, EVP_R_CANNOT_SET_PARAMETERS);
|
||||
}
|
||||
|
||||
PARAM_FUNCTIONS(EVP_CIPHER,
|
||||
evp_do_ciph_getparams, get_params,
|
||||
evp_do_ciph_ctx_getparams, get_ctx_params,
|
||||
evp_do_ciph_ctx_setparams, set_ctx_params)
|
||||
|
||||
PARAM_FUNCTIONS(EVP_MD,
|
||||
evp_do_md_getparams, get_params,
|
||||
evp_do_md_ctx_getparams, get_ctx_params,
|
||||
evp_do_md_ctx_setparams, set_ctx_params)
|
||||
@@ -0,0 +1,388 @@
|
||||
/*
|
||||
* Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (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 <openssl/crypto.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/err.h>
|
||||
#include "internal/refcount.h"
|
||||
#include "internal/evp_int.h"
|
||||
#include "internal/provider.h"
|
||||
#include "internal/numbers.h" /* includes SIZE_MAX */
|
||||
#include "evp_locl.h"
|
||||
|
||||
static EVP_KEYEXCH *evp_keyexch_new(OSSL_PROVIDER *prov)
|
||||
{
|
||||
EVP_KEYEXCH *exchange = OPENSSL_zalloc(sizeof(EVP_KEYEXCH));
|
||||
|
||||
exchange->lock = CRYPTO_THREAD_lock_new();
|
||||
if (exchange->lock == NULL) {
|
||||
OPENSSL_free(exchange);
|
||||
return NULL;
|
||||
}
|
||||
exchange->prov = prov;
|
||||
ossl_provider_up_ref(prov);
|
||||
exchange->refcnt = 1;
|
||||
|
||||
return exchange;
|
||||
}
|
||||
|
||||
static void *evp_keyexch_from_dispatch(int name_id,
|
||||
const OSSL_DISPATCH *fns,
|
||||
OSSL_PROVIDER *prov,
|
||||
void *vkeymgmt_data)
|
||||
{
|
||||
/*
|
||||
* Key exchange cannot work without a key, and key management
|
||||
* from the same provider to manage its keys. We therefore fetch
|
||||
* a key management method using the same algorithm and properties
|
||||
* and pass that down to evp_generic_fetch to be passed on to our
|
||||
* evp_keyexch_from_dispatch, which will attach the key management
|
||||
* method to the newly created key exchange method as long as the
|
||||
* provider matches.
|
||||
*/
|
||||
struct keymgmt_data_st *keymgmt_data = vkeymgmt_data;
|
||||
EVP_KEYMGMT *keymgmt =
|
||||
evp_keymgmt_fetch_by_number(keymgmt_data->ctx, name_id,
|
||||
keymgmt_data->properties);
|
||||
EVP_KEYEXCH *exchange = NULL;
|
||||
int fncnt = 0, paramfncnt = 0;
|
||||
|
||||
if (keymgmt == NULL || EVP_KEYMGMT_provider(keymgmt) != prov) {
|
||||
ERR_raise(ERR_LIB_EVP, EVP_R_NO_KEYMGMT_AVAILABLE);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if ((exchange = evp_keyexch_new(prov)) == NULL) {
|
||||
ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
|
||||
exchange->name_id = name_id;
|
||||
exchange->keymgmt = keymgmt;
|
||||
keymgmt = NULL; /* avoid double free on failure below */
|
||||
|
||||
for (; fns->function_id != 0; fns++) {
|
||||
switch (fns->function_id) {
|
||||
case OSSL_FUNC_KEYEXCH_NEWCTX:
|
||||
if (exchange->newctx != NULL)
|
||||
break;
|
||||
exchange->newctx = OSSL_get_OP_keyexch_newctx(fns);
|
||||
fncnt++;
|
||||
break;
|
||||
case OSSL_FUNC_KEYEXCH_INIT:
|
||||
if (exchange->init != NULL)
|
||||
break;
|
||||
exchange->init = OSSL_get_OP_keyexch_init(fns);
|
||||
fncnt++;
|
||||
break;
|
||||
case OSSL_FUNC_KEYEXCH_SET_PEER:
|
||||
if (exchange->set_peer != NULL)
|
||||
break;
|
||||
exchange->set_peer = OSSL_get_OP_keyexch_set_peer(fns);
|
||||
break;
|
||||
case OSSL_FUNC_KEYEXCH_DERIVE:
|
||||
if (exchange->derive != NULL)
|
||||
break;
|
||||
exchange->derive = OSSL_get_OP_keyexch_derive(fns);
|
||||
fncnt++;
|
||||
break;
|
||||
case OSSL_FUNC_KEYEXCH_FREECTX:
|
||||
if (exchange->freectx != NULL)
|
||||
break;
|
||||
exchange->freectx = OSSL_get_OP_keyexch_freectx(fns);
|
||||
fncnt++;
|
||||
break;
|
||||
case OSSL_FUNC_KEYEXCH_DUPCTX:
|
||||
if (exchange->dupctx != NULL)
|
||||
break;
|
||||
exchange->dupctx = OSSL_get_OP_keyexch_dupctx(fns);
|
||||
break;
|
||||
case OSSL_FUNC_KEYEXCH_SET_CTX_PARAMS:
|
||||
if (exchange->set_ctx_params != NULL)
|
||||
break;
|
||||
exchange->set_ctx_params = OSSL_get_OP_keyexch_set_ctx_params(fns);
|
||||
paramfncnt++;
|
||||
break;
|
||||
case OSSL_FUNC_KEYEXCH_SETTABLE_CTX_PARAMS:
|
||||
if (exchange->settable_ctx_params != NULL)
|
||||
break;
|
||||
exchange->settable_ctx_params
|
||||
= OSSL_get_OP_keyexch_settable_ctx_params(fns);
|
||||
paramfncnt++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (fncnt != 4 || (paramfncnt != 0 && paramfncnt != 2)) {
|
||||
/*
|
||||
* In order to be a consistent set of functions we must have at least
|
||||
* a complete set of "exchange" functions: init, derive, newctx,
|
||||
* and freectx. The set_ctx_params and settable_ctx_params functions are
|
||||
* optional, but if one of them is present then the other one must also
|
||||
* be present. The dupctx and set_peer functions are optional.
|
||||
*/
|
||||
EVPerr(EVP_F_EVP_KEYEXCH_FROM_DISPATCH,
|
||||
EVP_R_INVALID_PROVIDER_FUNCTIONS);
|
||||
goto err;
|
||||
}
|
||||
|
||||
return exchange;
|
||||
|
||||
err:
|
||||
EVP_KEYEXCH_free(exchange);
|
||||
EVP_KEYMGMT_free(keymgmt);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void EVP_KEYEXCH_free(EVP_KEYEXCH *exchange)
|
||||
{
|
||||
if (exchange != NULL) {
|
||||
int i;
|
||||
|
||||
CRYPTO_DOWN_REF(&exchange->refcnt, &i, exchange->lock);
|
||||
if (i > 0)
|
||||
return;
|
||||
EVP_KEYMGMT_free(exchange->keymgmt);
|
||||
ossl_provider_free(exchange->prov);
|
||||
CRYPTO_THREAD_lock_free(exchange->lock);
|
||||
OPENSSL_free(exchange);
|
||||
}
|
||||
}
|
||||
|
||||
int EVP_KEYEXCH_up_ref(EVP_KEYEXCH *exchange)
|
||||
{
|
||||
int ref = 0;
|
||||
|
||||
CRYPTO_UP_REF(&exchange->refcnt, &ref, exchange->lock);
|
||||
return 1;
|
||||
}
|
||||
|
||||
OSSL_PROVIDER *EVP_KEYEXCH_provider(const EVP_KEYEXCH *exchange)
|
||||
{
|
||||
return exchange->prov;
|
||||
}
|
||||
|
||||
EVP_KEYEXCH *EVP_KEYEXCH_fetch(OPENSSL_CTX *ctx, const char *algorithm,
|
||||
const char *properties)
|
||||
{
|
||||
EVP_KEYEXCH *keyexch = NULL;
|
||||
struct keymgmt_data_st keymgmt_data;
|
||||
|
||||
keymgmt_data.ctx = ctx;
|
||||
keymgmt_data.properties = properties;
|
||||
keyexch = evp_generic_fetch(ctx, OSSL_OP_KEYEXCH, algorithm, properties,
|
||||
evp_keyexch_from_dispatch, &keymgmt_data,
|
||||
(int (*)(void *))EVP_KEYEXCH_up_ref,
|
||||
(void (*)(void *))EVP_KEYEXCH_free);
|
||||
|
||||
return keyexch;
|
||||
}
|
||||
|
||||
int EVP_PKEY_derive_init_ex(EVP_PKEY_CTX *ctx, EVP_KEYEXCH *exchange)
|
||||
{
|
||||
int ret;
|
||||
void *provkey = NULL;
|
||||
|
||||
evp_pkey_ctx_free_old_ops(ctx);
|
||||
ctx->operation = EVP_PKEY_OP_DERIVE;
|
||||
|
||||
if (ctx->engine != NULL)
|
||||
goto legacy;
|
||||
|
||||
if (exchange != NULL) {
|
||||
if (!EVP_KEYEXCH_up_ref(exchange))
|
||||
goto err;
|
||||
} else {
|
||||
int nid = ctx->pkey != NULL ? ctx->pkey->type : ctx->pmeth->pkey_id;
|
||||
|
||||
/*
|
||||
* TODO(3.0): Check for legacy handling. Remove this once all all
|
||||
* algorithms are moved to providers.
|
||||
*/
|
||||
if (ctx->pkey != NULL) {
|
||||
switch (ctx->pkey->type) {
|
||||
case EVP_PKEY_DH:
|
||||
break;
|
||||
default:
|
||||
goto legacy;
|
||||
}
|
||||
exchange = EVP_KEYEXCH_fetch(NULL, OBJ_nid2sn(nid), NULL);
|
||||
} else {
|
||||
goto legacy;
|
||||
}
|
||||
|
||||
if (exchange == NULL) {
|
||||
EVPerr(EVP_F_EVP_PKEY_DERIVE_INIT_EX, EVP_R_INITIALIZATION_ERROR);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
ctx->op.kex.exchange = exchange;
|
||||
if (ctx->pkey != NULL) {
|
||||
provkey = evp_keymgmt_export_to_provider(ctx->pkey, exchange->keymgmt);
|
||||
if (provkey == NULL) {
|
||||
EVPerr(EVP_F_EVP_PKEY_DERIVE_INIT_EX, EVP_R_INITIALIZATION_ERROR);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
ctx->op.kex.exchprovctx = exchange->newctx(ossl_provider_ctx(exchange->prov));
|
||||
if (ctx->op.kex.exchprovctx == NULL) {
|
||||
/* The provider key can stay in the cache */
|
||||
EVPerr(EVP_F_EVP_PKEY_DERIVE_INIT_EX, EVP_R_INITIALIZATION_ERROR);
|
||||
goto err;
|
||||
}
|
||||
ret = exchange->init(ctx->op.kex.exchprovctx, provkey);
|
||||
|
||||
return ret ? 1 : 0;
|
||||
err:
|
||||
ctx->operation = EVP_PKEY_OP_UNDEFINED;
|
||||
return 0;
|
||||
|
||||
legacy:
|
||||
if (ctx == NULL || ctx->pmeth == NULL || ctx->pmeth->derive == NULL) {
|
||||
EVPerr(EVP_F_EVP_PKEY_DERIVE_INIT_EX,
|
||||
EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
|
||||
return -2;
|
||||
}
|
||||
|
||||
if (ctx->pmeth->derive_init == NULL)
|
||||
return 1;
|
||||
ret = ctx->pmeth->derive_init(ctx);
|
||||
if (ret <= 0)
|
||||
ctx->operation = EVP_PKEY_OP_UNDEFINED;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int EVP_PKEY_derive_init(EVP_PKEY_CTX *ctx)
|
||||
{
|
||||
return EVP_PKEY_derive_init_ex(ctx, NULL);
|
||||
}
|
||||
|
||||
int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer)
|
||||
{
|
||||
int ret;
|
||||
void *provkey = NULL;
|
||||
|
||||
if (ctx == NULL) {
|
||||
EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER,
|
||||
EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
|
||||
return -2;
|
||||
}
|
||||
|
||||
if (!EVP_PKEY_CTX_IS_DERIVE_OP(ctx) || ctx->op.kex.exchprovctx == NULL)
|
||||
goto legacy;
|
||||
|
||||
if (ctx->op.kex.exchange->set_peer == NULL) {
|
||||
EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER,
|
||||
EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
|
||||
return -2;
|
||||
}
|
||||
|
||||
provkey = evp_keymgmt_export_to_provider(peer,
|
||||
ctx->op.kex.exchange->keymgmt);
|
||||
if (provkey == NULL) {
|
||||
EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER, ERR_R_INTERNAL_ERROR);
|
||||
return 0;
|
||||
}
|
||||
return ctx->op.kex.exchange->set_peer(ctx->op.kex.exchprovctx, provkey);
|
||||
|
||||
legacy:
|
||||
if (ctx->pmeth == NULL
|
||||
|| !(ctx->pmeth->derive != NULL
|
||||
|| ctx->pmeth->encrypt != NULL
|
||||
|| ctx->pmeth->decrypt != NULL)
|
||||
|| ctx->pmeth->ctrl == NULL) {
|
||||
EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER,
|
||||
EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
|
||||
return -2;
|
||||
}
|
||||
if (ctx->operation != EVP_PKEY_OP_DERIVE
|
||||
&& ctx->operation != EVP_PKEY_OP_ENCRYPT
|
||||
&& ctx->operation != EVP_PKEY_OP_DECRYPT) {
|
||||
EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER,
|
||||
EVP_R_OPERATON_NOT_INITIALIZED);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = ctx->pmeth->ctrl(ctx, EVP_PKEY_CTRL_PEER_KEY, 0, peer);
|
||||
|
||||
if (ret <= 0)
|
||||
return ret;
|
||||
|
||||
if (ret == 2)
|
||||
return 1;
|
||||
|
||||
if (ctx->pkey == NULL) {
|
||||
EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER, EVP_R_NO_KEY_SET);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ctx->pkey->type != peer->type) {
|
||||
EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER, EVP_R_DIFFERENT_KEY_TYPES);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* For clarity. The error is if parameters in peer are
|
||||
* present (!missing) but don't match. EVP_PKEY_cmp_parameters may return
|
||||
* 1 (match), 0 (don't match) and -2 (comparison is not defined). -1
|
||||
* (different key types) is impossible here because it is checked earlier.
|
||||
* -2 is OK for us here, as well as 1, so we can check for 0 only.
|
||||
*/
|
||||
if (!EVP_PKEY_missing_parameters(peer) &&
|
||||
!EVP_PKEY_cmp_parameters(ctx->pkey, peer)) {
|
||||
EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER, EVP_R_DIFFERENT_PARAMETERS);
|
||||
return -1;
|
||||
}
|
||||
|
||||
EVP_PKEY_free(ctx->peerkey);
|
||||
ctx->peerkey = peer;
|
||||
|
||||
ret = ctx->pmeth->ctrl(ctx, EVP_PKEY_CTRL_PEER_KEY, 1, peer);
|
||||
|
||||
if (ret <= 0) {
|
||||
ctx->peerkey = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
EVP_PKEY_up_ref(peer);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int EVP_PKEY_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *pkeylen)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (ctx == NULL) {
|
||||
EVPerr(EVP_F_EVP_PKEY_DERIVE,
|
||||
EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
|
||||
return -2;
|
||||
}
|
||||
|
||||
if (!EVP_PKEY_CTX_IS_DERIVE_OP(ctx)) {
|
||||
EVPerr(EVP_F_EVP_PKEY_DERIVE, EVP_R_OPERATON_NOT_INITIALIZED);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ctx->op.kex.exchprovctx == NULL)
|
||||
goto legacy;
|
||||
|
||||
ret = ctx->op.kex.exchange->derive(ctx->op.kex.exchprovctx, key, pkeylen,
|
||||
SIZE_MAX);
|
||||
|
||||
return ret;
|
||||
legacy:
|
||||
if (ctx == NULL || ctx->pmeth == NULL || ctx->pmeth->derive == NULL) {
|
||||
EVPerr(EVP_F_EVP_PKEY_DERIVE,
|
||||
EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
|
||||
return -2;
|
||||
}
|
||||
|
||||
M_check_autoarg(ctx, key, pkeylen, EVP_F_EVP_PKEY_DERIVE)
|
||||
return ctx->pmeth->derive(ctx, key, pkeylen);
|
||||
}
|
||||
+91
-65
@@ -15,12 +15,15 @@
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/x509v3.h>
|
||||
#include <openssl/kdf.h>
|
||||
#include <openssl/core.h>
|
||||
#include <openssl/core_names.h>
|
||||
#include "internal/asn1_int.h"
|
||||
#include "internal/evp_int.h"
|
||||
#include "internal/numbers.h"
|
||||
#include "internal/provider.h"
|
||||
#include "evp_locl.h"
|
||||
|
||||
EVP_KDF_CTX *EVP_KDF_CTX_new(const EVP_KDF *kdf)
|
||||
EVP_KDF_CTX *EVP_KDF_CTX_new(EVP_KDF *kdf)
|
||||
{
|
||||
EVP_KDF_CTX *ctx = NULL;
|
||||
|
||||
@@ -28,8 +31,12 @@ EVP_KDF_CTX *EVP_KDF_CTX_new(const EVP_KDF *kdf)
|
||||
return NULL;
|
||||
|
||||
ctx = OPENSSL_zalloc(sizeof(EVP_KDF_CTX));
|
||||
if (ctx == NULL || (ctx->impl = kdf->new()) == NULL) {
|
||||
if (ctx == NULL
|
||||
|| (ctx->data = kdf->newctx(ossl_provider_ctx(kdf->prov))) == NULL
|
||||
|| !EVP_KDF_up_ref(kdf)) {
|
||||
EVPerr(EVP_F_EVP_KDF_CTX_NEW, ERR_R_MALLOC_FAILURE);
|
||||
if (ctx != NULL)
|
||||
kdf->freectx(ctx->data);
|
||||
OPENSSL_free(ctx);
|
||||
ctx = NULL;
|
||||
} else {
|
||||
@@ -38,16 +45,52 @@ EVP_KDF_CTX *EVP_KDF_CTX_new(const EVP_KDF *kdf)
|
||||
return ctx;
|
||||
}
|
||||
|
||||
EVP_KDF_CTX *EVP_KDF_CTX_new_id(int id)
|
||||
void EVP_KDF_CTX_free(EVP_KDF_CTX *ctx)
|
||||
{
|
||||
const EVP_KDF *kdf = EVP_get_kdfbynid(id);
|
||||
|
||||
return EVP_KDF_CTX_new(kdf);
|
||||
if (ctx != NULL) {
|
||||
ctx->meth->freectx(ctx->data);
|
||||
ctx->data = NULL;
|
||||
EVP_KDF_free(ctx->meth);
|
||||
OPENSSL_free(ctx);
|
||||
}
|
||||
}
|
||||
|
||||
int EVP_KDF_nid(const EVP_KDF *kdf)
|
||||
EVP_KDF_CTX *EVP_KDF_CTX_dup(const EVP_KDF_CTX *src)
|
||||
{
|
||||
return kdf->type;
|
||||
EVP_KDF_CTX *dst;
|
||||
|
||||
if (src == NULL || src->data == NULL || src->meth->dupctx == NULL)
|
||||
return NULL;
|
||||
|
||||
dst = OPENSSL_malloc(sizeof(*dst));
|
||||
if (dst == NULL) {
|
||||
EVPerr(EVP_F_EVP_KDF_CTX_DUP, ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memcpy(dst, src, sizeof(*dst));
|
||||
if (!EVP_KDF_up_ref(dst->meth)) {
|
||||
EVPerr(EVP_F_EVP_KDF_CTX_DUP, ERR_R_MALLOC_FAILURE);
|
||||
OPENSSL_free(dst);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
dst->data = src->meth->dupctx(src->data);
|
||||
if (dst->data == NULL) {
|
||||
EVP_KDF_CTX_free(dst);
|
||||
return NULL;
|
||||
}
|
||||
return dst;
|
||||
}
|
||||
|
||||
const char *EVP_KDF_name(const EVP_KDF *kdf)
|
||||
{
|
||||
return evp_first_name(kdf->prov, kdf->name_id);
|
||||
}
|
||||
|
||||
const OSSL_PROVIDER *EVP_KDF_provider(const EVP_KDF *kdf)
|
||||
{
|
||||
return kdf->prov;
|
||||
}
|
||||
|
||||
const EVP_KDF *EVP_KDF_CTX_kdf(EVP_KDF_CTX *ctx)
|
||||
@@ -55,75 +98,31 @@ const EVP_KDF *EVP_KDF_CTX_kdf(EVP_KDF_CTX *ctx)
|
||||
return ctx->meth;
|
||||
}
|
||||
|
||||
void EVP_KDF_CTX_free(EVP_KDF_CTX *ctx)
|
||||
{
|
||||
if (ctx == NULL)
|
||||
return;
|
||||
|
||||
ctx->meth->free(ctx->impl);
|
||||
OPENSSL_free(ctx);
|
||||
}
|
||||
|
||||
void EVP_KDF_reset(EVP_KDF_CTX *ctx)
|
||||
{
|
||||
if (ctx == NULL)
|
||||
return;
|
||||
|
||||
if (ctx->meth->reset != NULL)
|
||||
ctx->meth->reset(ctx->impl);
|
||||
}
|
||||
|
||||
int EVP_KDF_ctrl(EVP_KDF_CTX *ctx, int cmd, ...)
|
||||
{
|
||||
int ret;
|
||||
va_list args;
|
||||
|
||||
va_start(args, cmd);
|
||||
ret = EVP_KDF_vctrl(ctx, cmd, args);
|
||||
va_end(args);
|
||||
|
||||
if (ret == -2)
|
||||
EVPerr(EVP_F_EVP_KDF_CTRL, EVP_R_COMMAND_NOT_SUPPORTED);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int EVP_KDF_vctrl(EVP_KDF_CTX *ctx, int cmd, va_list args)
|
||||
{
|
||||
if (ctx == NULL)
|
||||
return 0;
|
||||
|
||||
return ctx->meth->ctrl(ctx->impl, cmd, args);
|
||||
}
|
||||
|
||||
int EVP_KDF_ctrl_str(EVP_KDF_CTX *ctx, const char *type, const char *value)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (ctx == NULL)
|
||||
return 0;
|
||||
|
||||
if (ctx->meth->ctrl_str == NULL) {
|
||||
EVPerr(EVP_F_EVP_KDF_CTRL_STR, EVP_R_COMMAND_NOT_SUPPORTED);
|
||||
return -2;
|
||||
}
|
||||
|
||||
ret = ctx->meth->ctrl_str(ctx->impl, type, value);
|
||||
if (ret == -2)
|
||||
EVPerr(EVP_F_EVP_KDF_CTRL_STR, EVP_R_COMMAND_NOT_SUPPORTED);
|
||||
|
||||
return ret;
|
||||
ctx->meth->reset(ctx->data);
|
||||
}
|
||||
|
||||
size_t EVP_KDF_size(EVP_KDF_CTX *ctx)
|
||||
{
|
||||
OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END };
|
||||
size_t s;
|
||||
|
||||
if (ctx == NULL)
|
||||
return 0;
|
||||
|
||||
if (ctx->meth->size == NULL)
|
||||
return SIZE_MAX;
|
||||
|
||||
return ctx->meth->size(ctx->impl);
|
||||
*params = OSSL_PARAM_construct_size_t(OSSL_KDF_PARAM_SIZE, &s);
|
||||
if (ctx->meth->get_ctx_params != NULL
|
||||
&& ctx->meth->get_ctx_params(ctx->data, params))
|
||||
return s;
|
||||
if (ctx->meth->get_params != NULL
|
||||
&& ctx->meth->get_params(params))
|
||||
return s;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int EVP_KDF_derive(EVP_KDF_CTX *ctx, unsigned char *key, size_t keylen)
|
||||
@@ -131,5 +130,32 @@ int EVP_KDF_derive(EVP_KDF_CTX *ctx, unsigned char *key, size_t keylen)
|
||||
if (ctx == NULL)
|
||||
return 0;
|
||||
|
||||
return ctx->meth->derive(ctx->impl, key, keylen);
|
||||
return ctx->meth->derive(ctx->data, key, keylen);
|
||||
}
|
||||
|
||||
/*
|
||||
* The {get,set}_params functions return 1 if there is no corresponding
|
||||
* function in the implementation. This is the same as if there was one,
|
||||
* but it didn't recognise any of the given params, i.e. nothing in the
|
||||
* bag of parameters was useful.
|
||||
*/
|
||||
int EVP_KDF_get_params(EVP_KDF *kdf, OSSL_PARAM params[])
|
||||
{
|
||||
if (kdf->get_params != NULL)
|
||||
return kdf->get_params(params);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int EVP_KDF_CTX_get_params(EVP_KDF_CTX *ctx, OSSL_PARAM params[])
|
||||
{
|
||||
if (ctx->meth->get_ctx_params != NULL)
|
||||
return ctx->meth->get_ctx_params(ctx->data, params);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int EVP_KDF_CTX_set_params(EVP_KDF_CTX *ctx, const OSSL_PARAM params[])
|
||||
{
|
||||
if (ctx->meth->set_ctx_params != NULL)
|
||||
return ctx->meth->set_ctx_params(ctx->data, params);
|
||||
return 1;
|
||||
}
|
||||
@@ -0,0 +1,197 @@
|
||||
/*
|
||||
* Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (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 <openssl/evp.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/core.h>
|
||||
#include <openssl/core_numbers.h>
|
||||
#include <openssl/kdf.h>
|
||||
#include "internal/evp_int.h"
|
||||
#include "internal/provider.h"
|
||||
#include "evp_locl.h"
|
||||
|
||||
static int evp_kdf_up_ref(void *vkdf)
|
||||
{
|
||||
EVP_KDF *kdf = (EVP_KDF *)vkdf;
|
||||
int ref = 0;
|
||||
|
||||
CRYPTO_UP_REF(&kdf->refcnt, &ref, kdf->lock);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void evp_kdf_free(void *vkdf){
|
||||
EVP_KDF *kdf = (EVP_KDF *)vkdf;
|
||||
int ref = 0;
|
||||
|
||||
if (kdf != NULL) {
|
||||
CRYPTO_DOWN_REF(&kdf->refcnt, &ref, kdf->lock);
|
||||
if (ref <= 0) {
|
||||
ossl_provider_free(kdf->prov);
|
||||
CRYPTO_THREAD_lock_free(kdf->lock);
|
||||
OPENSSL_free(kdf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void *evp_kdf_new(void)
|
||||
{
|
||||
EVP_KDF *kdf = NULL;
|
||||
|
||||
if ((kdf = OPENSSL_zalloc(sizeof(*kdf))) == NULL
|
||||
|| (kdf->lock = CRYPTO_THREAD_lock_new()) == NULL) {
|
||||
OPENSSL_free(kdf);
|
||||
return NULL;
|
||||
}
|
||||
kdf->refcnt = 1;
|
||||
return kdf;
|
||||
}
|
||||
|
||||
static void *evp_kdf_from_dispatch(int name_id,
|
||||
const OSSL_DISPATCH *fns,
|
||||
OSSL_PROVIDER *prov,
|
||||
void *method_data)
|
||||
{
|
||||
EVP_KDF *kdf = NULL;
|
||||
int fnkdfcnt = 0, fnctxcnt = 0;
|
||||
|
||||
if ((kdf = evp_kdf_new()) == NULL) {
|
||||
EVPerr(0, ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
kdf->name_id = name_id;
|
||||
|
||||
for (; fns->function_id != 0; fns++) {
|
||||
switch (fns->function_id) {
|
||||
case OSSL_FUNC_KDF_NEWCTX:
|
||||
if (kdf->newctx != NULL)
|
||||
break;
|
||||
kdf->newctx = OSSL_get_OP_kdf_newctx(fns);
|
||||
fnctxcnt++;
|
||||
break;
|
||||
case OSSL_FUNC_KDF_DUPCTX:
|
||||
if (kdf->dupctx != NULL)
|
||||
break;
|
||||
kdf->dupctx = OSSL_get_OP_kdf_dupctx(fns);
|
||||
break;
|
||||
case OSSL_FUNC_KDF_FREECTX:
|
||||
if (kdf->freectx != NULL)
|
||||
break;
|
||||
kdf->freectx = OSSL_get_OP_kdf_freectx(fns);
|
||||
fnctxcnt++;
|
||||
break;
|
||||
case OSSL_FUNC_KDF_RESET:
|
||||
if (kdf->reset != NULL)
|
||||
break;
|
||||
kdf->reset = OSSL_get_OP_kdf_reset(fns);
|
||||
break;
|
||||
case OSSL_FUNC_KDF_DERIVE:
|
||||
if (kdf->derive != NULL)
|
||||
break;
|
||||
kdf->derive = OSSL_get_OP_kdf_derive(fns);
|
||||
fnkdfcnt++;
|
||||
break;
|
||||
case OSSL_FUNC_KDF_GETTABLE_PARAMS:
|
||||
if (kdf->gettable_params != NULL)
|
||||
break;
|
||||
kdf->gettable_params =
|
||||
OSSL_get_OP_kdf_gettable_params(fns);
|
||||
break;
|
||||
case OSSL_FUNC_KDF_GETTABLE_CTX_PARAMS:
|
||||
if (kdf->gettable_ctx_params != NULL)
|
||||
break;
|
||||
kdf->gettable_ctx_params =
|
||||
OSSL_get_OP_kdf_gettable_ctx_params(fns);
|
||||
break;
|
||||
case OSSL_FUNC_KDF_SETTABLE_CTX_PARAMS:
|
||||
if (kdf->settable_ctx_params != NULL)
|
||||
break;
|
||||
kdf->settable_ctx_params =
|
||||
OSSL_get_OP_kdf_settable_ctx_params(fns);
|
||||
break;
|
||||
case OSSL_FUNC_KDF_GET_PARAMS:
|
||||
if (kdf->get_params != NULL)
|
||||
break;
|
||||
kdf->get_params = OSSL_get_OP_kdf_get_params(fns);
|
||||
break;
|
||||
case OSSL_FUNC_KDF_GET_CTX_PARAMS:
|
||||
if (kdf->get_ctx_params != NULL)
|
||||
break;
|
||||
kdf->get_ctx_params = OSSL_get_OP_kdf_get_ctx_params(fns);
|
||||
break;
|
||||
case OSSL_FUNC_KDF_SET_CTX_PARAMS:
|
||||
if (kdf->set_ctx_params != NULL)
|
||||
break;
|
||||
kdf->set_ctx_params = OSSL_get_OP_kdf_set_ctx_params(fns);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (fnkdfcnt != 1 || fnctxcnt != 2) {
|
||||
/*
|
||||
* In order to be a consistent set of functions we must have at least
|
||||
* a derive function, and a complete set of context management
|
||||
* functions.
|
||||
*/
|
||||
evp_kdf_free(kdf);
|
||||
ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_PROVIDER_FUNCTIONS);
|
||||
return NULL;
|
||||
}
|
||||
kdf->prov = prov;
|
||||
if (prov != NULL)
|
||||
ossl_provider_up_ref(prov);
|
||||
|
||||
return kdf;
|
||||
}
|
||||
|
||||
EVP_KDF *EVP_KDF_fetch(OPENSSL_CTX *libctx, const char *algorithm,
|
||||
const char *properties)
|
||||
{
|
||||
return evp_generic_fetch(libctx, OSSL_OP_KDF, algorithm, properties,
|
||||
evp_kdf_from_dispatch, NULL, evp_kdf_up_ref,
|
||||
evp_kdf_free);
|
||||
}
|
||||
|
||||
int EVP_KDF_up_ref(EVP_KDF *kdf)
|
||||
{
|
||||
return evp_kdf_up_ref(kdf);
|
||||
}
|
||||
|
||||
void EVP_KDF_free(EVP_KDF *kdf)
|
||||
{
|
||||
evp_kdf_free(kdf);
|
||||
}
|
||||
|
||||
const OSSL_PARAM *EVP_KDF_gettable_params(const EVP_KDF *kdf)
|
||||
{
|
||||
if (kdf->gettable_params == NULL)
|
||||
return NULL;
|
||||
return kdf->gettable_params();
|
||||
}
|
||||
|
||||
const OSSL_PARAM *EVP_KDF_CTX_gettable_params(const EVP_KDF *kdf)
|
||||
{
|
||||
if (kdf->gettable_ctx_params == NULL)
|
||||
return NULL;
|
||||
return kdf->gettable_ctx_params();
|
||||
}
|
||||
|
||||
const OSSL_PARAM *EVP_KDF_CTX_settable_params(const EVP_KDF *kdf)
|
||||
{
|
||||
if (kdf->settable_ctx_params == NULL)
|
||||
return NULL;
|
||||
return kdf->settable_ctx_params();
|
||||
}
|
||||
|
||||
void EVP_KDF_do_all_ex(OPENSSL_CTX *libctx,
|
||||
void (*fn)(EVP_KDF *kdf, void *arg),
|
||||
void *arg)
|
||||
{
|
||||
evp_generic_do_all(libctx, OSSL_OP_KDF,
|
||||
(void (*)(void *, void *))fn, arg,
|
||||
evp_kdf_from_dispatch, NULL, evp_kdf_free);
|
||||
}
|
||||
@@ -0,0 +1,288 @@
|
||||
/*
|
||||
* Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (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 "internal/cryptlib.h"
|
||||
#include "internal/nelem.h"
|
||||
#include "internal/evp_int.h"
|
||||
#include "internal/asn1_int.h"
|
||||
#include "internal/provider.h"
|
||||
#include "evp_locl.h"
|
||||
|
||||
static OSSL_PARAM *paramdefs_to_params(const OSSL_PARAM *paramdefs)
|
||||
{
|
||||
size_t cnt;
|
||||
const OSSL_PARAM *p;
|
||||
OSSL_PARAM *params, *q;
|
||||
|
||||
for (cnt = 1, p = paramdefs; p->key != NULL; p++, cnt++)
|
||||
continue;
|
||||
|
||||
params = OPENSSL_zalloc(cnt * sizeof(*params));
|
||||
|
||||
for (p = paramdefs, q = params; ; p++, q++) {
|
||||
*q = *p;
|
||||
if (p->key == NULL)
|
||||
break;
|
||||
|
||||
q->data = NULL; /* In case the provider used it */
|
||||
q->return_size = 0;
|
||||
}
|
||||
|
||||
return params;
|
||||
}
|
||||
|
||||
typedef union align_block_un {
|
||||
OSSL_UNION_ALIGN;
|
||||
} ALIGN_BLOCK;
|
||||
|
||||
#define ALIGN_SIZE sizeof(ALIGN_BLOCK)
|
||||
|
||||
static void *allocate_params_space(OSSL_PARAM *params)
|
||||
{
|
||||
unsigned char *data = NULL;
|
||||
size_t space;
|
||||
OSSL_PARAM *p;
|
||||
|
||||
for (space = 0, p = params; p->key != NULL; p++)
|
||||
space += ((p->return_size + ALIGN_SIZE - 1) / ALIGN_SIZE) * ALIGN_SIZE;
|
||||
|
||||
data = OPENSSL_zalloc(space);
|
||||
|
||||
for (space = 0, p = params; p->key != NULL; p++) {
|
||||
p->data = data + space;
|
||||
space += ((p->return_size + ALIGN_SIZE - 1) / ALIGN_SIZE) * ALIGN_SIZE;
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
void *evp_keymgmt_export_to_provider(EVP_PKEY *pk, EVP_KEYMGMT *keymgmt)
|
||||
{
|
||||
void *provkey = NULL;
|
||||
size_t i, j;
|
||||
|
||||
/*
|
||||
* If there is an underlying legacy key and it has changed, invalidate
|
||||
* the cache of provider keys.
|
||||
*/
|
||||
if (pk->pkey.ptr != NULL) {
|
||||
/*
|
||||
* If there is no dirty counter, this key can't be used with
|
||||
* providers.
|
||||
*/
|
||||
if (pk->ameth->dirty_cnt == NULL)
|
||||
return NULL;
|
||||
|
||||
if (pk->ameth->dirty_cnt(pk) != pk->dirty_cnt_copy)
|
||||
evp_keymgmt_clear_pkey_cache(pk);
|
||||
}
|
||||
|
||||
/*
|
||||
* See if we have exported to this provider already.
|
||||
* If we have, return immediately.
|
||||
*/
|
||||
for (i = 0;
|
||||
i < OSSL_NELEM(pk->pkeys) && pk->pkeys[i].keymgmt != NULL;
|
||||
i++) {
|
||||
if (keymgmt == pk->pkeys[i].keymgmt)
|
||||
return pk->pkeys[i].provkey;
|
||||
}
|
||||
|
||||
if (pk->pkey.ptr != NULL) {
|
||||
/* There is a legacy key, try to export that one to the provider */
|
||||
|
||||
/* If the legacy key doesn't have an export function, give up */
|
||||
if (pk->ameth->export_to == NULL)
|
||||
return NULL;
|
||||
|
||||
/* Otherwise, simply use it */
|
||||
provkey = pk->ameth->export_to(pk, keymgmt);
|
||||
|
||||
/* Synchronize the dirty count, but only if we exported successfully */
|
||||
if (provkey != NULL)
|
||||
pk->dirty_cnt_copy = pk->ameth->dirty_cnt(pk);
|
||||
|
||||
} else {
|
||||
/*
|
||||
* Here, there is no legacy key, so we look at the already cached
|
||||
* provider keys, and import from the first that supports it
|
||||
* (i.e. use its export function), and export the imported data to
|
||||
* the new provider.
|
||||
*/
|
||||
|
||||
/*
|
||||
* If the given keymgmt doesn't have an import function, give up
|
||||
*/
|
||||
if (keymgmt->importkey == NULL)
|
||||
return NULL;
|
||||
|
||||
for (j = 0; j < i && pk->pkeys[j].keymgmt != NULL; j++) {
|
||||
if (pk->pkeys[j].keymgmt->exportkey != NULL) {
|
||||
const OSSL_PARAM *paramdefs = NULL;
|
||||
OSSL_PARAM *params = NULL;
|
||||
void *data = NULL;
|
||||
void *provctx =
|
||||
ossl_provider_ctx(EVP_KEYMGMT_provider(keymgmt));
|
||||
|
||||
paramdefs = pk->pkeys[j].keymgmt->exportkey_types();
|
||||
/*
|
||||
* All params have 'data' set to NULL. In that case,
|
||||
* the exportkey call should just fill in 'return_size'
|
||||
* in all applicable params.
|
||||
*/
|
||||
params = paramdefs_to_params(paramdefs);
|
||||
/* Get 'return_size' filled */
|
||||
pk->pkeys[j].keymgmt->exportkey(pk->pkeys[j].provkey, params);
|
||||
|
||||
/*
|
||||
* Allocate space and assign 'data' to point into the
|
||||
* data block
|
||||
*/
|
||||
data = allocate_params_space(params);
|
||||
|
||||
/*
|
||||
* Call the exportkey function a second time, to get
|
||||
* the data filled
|
||||
*/
|
||||
pk->pkeys[j].keymgmt->exportkey(pk->pkeys[j].provkey, params);
|
||||
|
||||
/*
|
||||
* We should have all the data at this point, so import
|
||||
* into the new provider and hope to get a key back.
|
||||
*/
|
||||
provkey = keymgmt->importkey(provctx, params);
|
||||
OPENSSL_free(params);
|
||||
OPENSSL_free(data);
|
||||
|
||||
if (provkey != NULL)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* TODO(3.0) Right now, we assume we have ample space. We will
|
||||
* have to think about a cache aging scheme, though, if |i| indexes
|
||||
* outside the array.
|
||||
*/
|
||||
j = ossl_assert(i < OSSL_NELEM(pk->pkeys));
|
||||
|
||||
if (provkey != NULL) {
|
||||
EVP_KEYMGMT_up_ref(keymgmt);
|
||||
pk->pkeys[i].keymgmt = keymgmt;
|
||||
pk->pkeys[i].provkey = provkey;
|
||||
}
|
||||
return provkey;
|
||||
}
|
||||
|
||||
void evp_keymgmt_clear_pkey_cache(EVP_PKEY *pk)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
if (pk != NULL) {
|
||||
for (i = 0;
|
||||
i < OSSL_NELEM(pk->pkeys) && pk->pkeys[i].keymgmt != NULL;
|
||||
i++) {
|
||||
EVP_KEYMGMT *keymgmt = pk->pkeys[i].keymgmt;
|
||||
void *provkey = pk->pkeys[i].provkey;
|
||||
|
||||
pk->pkeys[i].keymgmt = NULL;
|
||||
pk->pkeys[i].provkey = NULL;
|
||||
keymgmt->freekey(provkey);
|
||||
EVP_KEYMGMT_free(keymgmt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* internal functions */
|
||||
/* TODO(3.0) decide if these should be public or internal */
|
||||
void *evp_keymgmt_importdomparams(const EVP_KEYMGMT *keymgmt,
|
||||
const OSSL_PARAM params[])
|
||||
{
|
||||
void *provctx = ossl_provider_ctx(EVP_KEYMGMT_provider(keymgmt));
|
||||
|
||||
return keymgmt->importdomparams(provctx, params);
|
||||
}
|
||||
|
||||
void *evp_keymgmt_gendomparams(const EVP_KEYMGMT *keymgmt,
|
||||
const OSSL_PARAM params[])
|
||||
{
|
||||
void *provctx = ossl_provider_ctx(EVP_KEYMGMT_provider(keymgmt));
|
||||
|
||||
return keymgmt->gendomparams(provctx, params);
|
||||
}
|
||||
|
||||
void evp_keymgmt_freedomparams(const EVP_KEYMGMT *keymgmt,
|
||||
void *provdomparams)
|
||||
{
|
||||
keymgmt->freedomparams(provdomparams);
|
||||
}
|
||||
|
||||
int evp_keymgmt_exportdomparams(const EVP_KEYMGMT *keymgmt,
|
||||
void *provdomparams, OSSL_PARAM params[])
|
||||
{
|
||||
return keymgmt->exportdomparams(provdomparams, params);
|
||||
}
|
||||
|
||||
const OSSL_PARAM *evp_keymgmt_importdomparam_types(const EVP_KEYMGMT *keymgmt)
|
||||
{
|
||||
return keymgmt->importdomparam_types();
|
||||
}
|
||||
|
||||
const OSSL_PARAM *evp_keymgmt_exportdomparam_types(const EVP_KEYMGMT *keymgmt)
|
||||
{
|
||||
return keymgmt->exportdomparam_types();
|
||||
}
|
||||
|
||||
|
||||
void *evp_keymgmt_importkey(const EVP_KEYMGMT *keymgmt,
|
||||
const OSSL_PARAM params[])
|
||||
{
|
||||
void *provctx = ossl_provider_ctx(EVP_KEYMGMT_provider(keymgmt));
|
||||
|
||||
return keymgmt->importkey(provctx, params);
|
||||
}
|
||||
|
||||
void *evp_keymgmt_genkey(const EVP_KEYMGMT *keymgmt, void *domparams,
|
||||
const OSSL_PARAM params[])
|
||||
{
|
||||
void *provctx = ossl_provider_ctx(EVP_KEYMGMT_provider(keymgmt));
|
||||
|
||||
return keymgmt->genkey(provctx, domparams, params);
|
||||
}
|
||||
|
||||
void *evp_keymgmt_loadkey(const EVP_KEYMGMT *keymgmt,
|
||||
void *id, size_t idlen)
|
||||
{
|
||||
void *provctx = ossl_provider_ctx(EVP_KEYMGMT_provider(keymgmt));
|
||||
|
||||
return keymgmt->loadkey(provctx, id, idlen);
|
||||
}
|
||||
|
||||
void evp_keymgmt_freekey(const EVP_KEYMGMT *keymgmt, void *provkey)
|
||||
{
|
||||
keymgmt->freekey(provkey);
|
||||
}
|
||||
|
||||
int evp_keymgmt_exportkey(const EVP_KEYMGMT *keymgmt, void *provkey,
|
||||
OSSL_PARAM params[])
|
||||
{
|
||||
return keymgmt->exportkey(provkey, params);
|
||||
}
|
||||
|
||||
const OSSL_PARAM *evp_keymgmt_importkey_types(const EVP_KEYMGMT *keymgmt)
|
||||
{
|
||||
return keymgmt->importkey_types();
|
||||
}
|
||||
|
||||
const OSSL_PARAM *evp_keymgmt_exportkey_types(const EVP_KEYMGMT *keymgmt)
|
||||
{
|
||||
return keymgmt->exportkey_types();
|
||||
}
|
||||
@@ -0,0 +1,202 @@
|
||||
/*
|
||||
* Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (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 <openssl/crypto.h>
|
||||
#include <openssl/core_numbers.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/err.h>
|
||||
#include "internal/provider.h"
|
||||
#include "internal/refcount.h"
|
||||
#include "internal/evp_int.h"
|
||||
#include "evp_locl.h"
|
||||
|
||||
|
||||
static void *keymgmt_new(void)
|
||||
{
|
||||
EVP_KEYMGMT *keymgmt = NULL;
|
||||
|
||||
if ((keymgmt = OPENSSL_zalloc(sizeof(*keymgmt))) == NULL
|
||||
|| (keymgmt->lock = CRYPTO_THREAD_lock_new()) == NULL) {
|
||||
EVP_KEYMGMT_free(keymgmt);
|
||||
EVPerr(0, ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
keymgmt->refcnt = 1;
|
||||
|
||||
return keymgmt;
|
||||
}
|
||||
|
||||
static void *keymgmt_from_dispatch(int name_id,
|
||||
const OSSL_DISPATCH *fns,
|
||||
OSSL_PROVIDER *prov,
|
||||
void *unused)
|
||||
{
|
||||
EVP_KEYMGMT *keymgmt = NULL;
|
||||
|
||||
if ((keymgmt = keymgmt_new()) == NULL) {
|
||||
EVP_KEYMGMT_free(keymgmt);
|
||||
return NULL;
|
||||
}
|
||||
keymgmt->name_id = name_id;
|
||||
|
||||
for (; fns->function_id != 0; fns++) {
|
||||
switch (fns->function_id) {
|
||||
case OSSL_FUNC_KEYMGMT_IMPORTDOMPARAMS:
|
||||
if (keymgmt->importdomparams != NULL)
|
||||
break;
|
||||
keymgmt->importdomparams =
|
||||
OSSL_get_OP_keymgmt_importdomparams(fns);
|
||||
break;
|
||||
case OSSL_FUNC_KEYMGMT_GENDOMPARAMS:
|
||||
if (keymgmt->gendomparams != NULL)
|
||||
break;
|
||||
keymgmt->gendomparams = OSSL_get_OP_keymgmt_gendomparams(fns);
|
||||
break;
|
||||
case OSSL_FUNC_KEYMGMT_FREEDOMPARAMS:
|
||||
if (keymgmt->freedomparams != NULL)
|
||||
break;
|
||||
keymgmt->freedomparams = OSSL_get_OP_keymgmt_freedomparams(fns);
|
||||
break;
|
||||
case OSSL_FUNC_KEYMGMT_EXPORTDOMPARAMS:
|
||||
if (keymgmt->exportdomparams != NULL)
|
||||
break;
|
||||
keymgmt->exportdomparams =
|
||||
OSSL_get_OP_keymgmt_exportdomparams(fns);
|
||||
break;
|
||||
case OSSL_FUNC_KEYMGMT_IMPORTDOMPARAM_TYPES:
|
||||
if (keymgmt->importdomparam_types != NULL)
|
||||
break;
|
||||
keymgmt->importdomparam_types =
|
||||
OSSL_get_OP_keymgmt_importdomparam_types(fns);
|
||||
break;
|
||||
case OSSL_FUNC_KEYMGMT_EXPORTDOMPARAM_TYPES:
|
||||
if (keymgmt->exportdomparam_types != NULL)
|
||||
break;
|
||||
keymgmt->exportdomparam_types =
|
||||
OSSL_get_OP_keymgmt_exportdomparam_types(fns);
|
||||
break;
|
||||
case OSSL_FUNC_KEYMGMT_IMPORTKEY:
|
||||
if (keymgmt->importkey != NULL)
|
||||
break;
|
||||
keymgmt->importkey = OSSL_get_OP_keymgmt_importkey(fns);
|
||||
break;
|
||||
case OSSL_FUNC_KEYMGMT_GENKEY:
|
||||
if (keymgmt->genkey != NULL)
|
||||
break;
|
||||
keymgmt->genkey = OSSL_get_OP_keymgmt_genkey(fns);
|
||||
break;
|
||||
case OSSL_FUNC_KEYMGMT_LOADKEY:
|
||||
if (keymgmt->loadkey != NULL)
|
||||
break;
|
||||
keymgmt->loadkey = OSSL_get_OP_keymgmt_loadkey(fns);
|
||||
break;
|
||||
case OSSL_FUNC_KEYMGMT_FREEKEY:
|
||||
if (keymgmt->freekey != NULL)
|
||||
break;
|
||||
keymgmt->freekey = OSSL_get_OP_keymgmt_freekey(fns);
|
||||
break;
|
||||
case OSSL_FUNC_KEYMGMT_EXPORTKEY:
|
||||
if (keymgmt->exportkey != NULL)
|
||||
break;
|
||||
keymgmt->exportkey = OSSL_get_OP_keymgmt_exportkey(fns);
|
||||
break;
|
||||
case OSSL_FUNC_KEYMGMT_IMPORTKEY_TYPES:
|
||||
if (keymgmt->importkey_types != NULL)
|
||||
break;
|
||||
keymgmt->importkey_types =
|
||||
OSSL_get_OP_keymgmt_importkey_types(fns);
|
||||
break;
|
||||
case OSSL_FUNC_KEYMGMT_EXPORTKEY_TYPES:
|
||||
if (keymgmt->exportkey_types != NULL)
|
||||
break;
|
||||
keymgmt->exportkey_types =
|
||||
OSSL_get_OP_keymgmt_exportkey_types(fns);
|
||||
break;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Try to check that the method is sensible.
|
||||
* It makes no sense being able to free stuff if you can't create it.
|
||||
* It makes no sense providing OSSL_PARAM descriptors for import and
|
||||
* export if you can't import or export.
|
||||
*/
|
||||
if ((keymgmt->freedomparams != NULL
|
||||
&& (keymgmt->importdomparams == NULL
|
||||
&& keymgmt->gendomparams == NULL))
|
||||
|| (keymgmt->freekey != NULL
|
||||
&& (keymgmt->importkey == NULL
|
||||
&& keymgmt->genkey == NULL
|
||||
&& keymgmt->loadkey == NULL))
|
||||
|| (keymgmt->importdomparam_types != NULL
|
||||
&& keymgmt->importdomparams == NULL)
|
||||
|| (keymgmt->exportdomparam_types != NULL
|
||||
&& keymgmt->exportdomparams == NULL)
|
||||
|| (keymgmt->importkey_types != NULL
|
||||
&& keymgmt->importkey == NULL)
|
||||
|| (keymgmt->exportkey_types != NULL
|
||||
&& keymgmt->exportkey == NULL)) {
|
||||
EVP_KEYMGMT_free(keymgmt);
|
||||
EVPerr(0, EVP_R_INVALID_PROVIDER_FUNCTIONS);
|
||||
return NULL;
|
||||
}
|
||||
keymgmt->prov = prov;
|
||||
if (prov != NULL)
|
||||
ossl_provider_up_ref(prov);
|
||||
|
||||
return keymgmt;
|
||||
}
|
||||
|
||||
EVP_KEYMGMT *evp_keymgmt_fetch_by_number(OPENSSL_CTX *ctx, int name_id,
|
||||
const char *properties)
|
||||
{
|
||||
return evp_generic_fetch_by_number(ctx,
|
||||
OSSL_OP_KEYMGMT, name_id, properties,
|
||||
keymgmt_from_dispatch, NULL,
|
||||
(int (*)(void *))EVP_KEYMGMT_up_ref,
|
||||
(void (*)(void *))EVP_KEYMGMT_free);
|
||||
}
|
||||
|
||||
EVP_KEYMGMT *EVP_KEYMGMT_fetch(OPENSSL_CTX *ctx, const char *algorithm,
|
||||
const char *properties)
|
||||
{
|
||||
return evp_generic_fetch(ctx, OSSL_OP_KEYMGMT, algorithm, properties,
|
||||
keymgmt_from_dispatch, NULL,
|
||||
(int (*)(void *))EVP_KEYMGMT_up_ref,
|
||||
(void (*)(void *))EVP_KEYMGMT_free);
|
||||
}
|
||||
|
||||
int EVP_KEYMGMT_up_ref(EVP_KEYMGMT *keymgmt)
|
||||
{
|
||||
int ref = 0;
|
||||
|
||||
CRYPTO_UP_REF(&keymgmt->refcnt, &ref, keymgmt->lock);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void EVP_KEYMGMT_free(EVP_KEYMGMT *keymgmt)
|
||||
{
|
||||
int ref = 0;
|
||||
|
||||
if (keymgmt == NULL)
|
||||
return;
|
||||
|
||||
CRYPTO_DOWN_REF(&keymgmt->refcnt, &ref, keymgmt->lock);
|
||||
if (ref > 0)
|
||||
return;
|
||||
ossl_provider_free(keymgmt->prov);
|
||||
CRYPTO_THREAD_lock_free(keymgmt->lock);
|
||||
OPENSSL_free(keymgmt);
|
||||
}
|
||||
|
||||
const OSSL_PROVIDER *EVP_KEYMGMT_provider(const EVP_KEYMGMT *keymgmt)
|
||||
{
|
||||
return keymgmt->prov;
|
||||
}
|
||||
|
||||
@@ -36,12 +36,6 @@ static int shake_init(EVP_MD_CTX *ctx)
|
||||
return sha3_init(EVP_MD_CTX_md_data(ctx), '\x1f', ctx->digest->md_size * 8);
|
||||
}
|
||||
|
||||
static int kmac_init(EVP_MD_CTX *ctx)
|
||||
{
|
||||
return keccak_kmac_init(EVP_MD_CTX_md_data(ctx), '\x04',
|
||||
ctx->digest->md_size * 8 / 2);
|
||||
}
|
||||
|
||||
static int shake_ctrl(EVP_MD_CTX *evp_ctx, int cmd, int p1, void *p2)
|
||||
{
|
||||
KECCAK1600_CTX *ctx = evp_ctx->md_data;
|
||||
@@ -323,27 +317,3 @@ EVP_MD_SHA3(512)
|
||||
|
||||
EVP_MD_SHAKE(128)
|
||||
EVP_MD_SHAKE(256)
|
||||
|
||||
|
||||
# define EVP_MD_KECCAK_KMAC(bitlen) \
|
||||
const EVP_MD *evp_keccak_kmac##bitlen(void) \
|
||||
{ \
|
||||
static const EVP_MD kmac_##bitlen##_md = { \
|
||||
NID_kmac##bitlen, \
|
||||
0, \
|
||||
2 * bitlen / 8, \
|
||||
EVP_MD_FLAG_XOF, \
|
||||
kmac_init, \
|
||||
update, \
|
||||
final, \
|
||||
NULL, \
|
||||
NULL, \
|
||||
(KECCAK1600_WIDTH - bitlen * 2) / 8, \
|
||||
sizeof(KECCAK1600_CTX), \
|
||||
shake_ctrl \
|
||||
}; \
|
||||
return &kmac_##bitlen##_md; \
|
||||
}
|
||||
|
||||
EVP_MD_KECCAK_KMAC(128)
|
||||
EVP_MD_KECCAK_KMAC(256)
|
||||
+62
-100
@@ -11,26 +11,24 @@
|
||||
#include <stdarg.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/core.h>
|
||||
#include <openssl/core_names.h>
|
||||
#include <openssl/ossl_typ.h>
|
||||
#include "internal/nelem.h"
|
||||
#include "internal/evp_int.h"
|
||||
#include "internal/provider.h"
|
||||
#include "evp_locl.h"
|
||||
|
||||
EVP_MAC_CTX *EVP_MAC_CTX_new_id(int id)
|
||||
{
|
||||
const EVP_MAC *mac = EVP_get_macbynid(id);
|
||||
|
||||
if (mac == NULL)
|
||||
return NULL;
|
||||
return EVP_MAC_CTX_new(mac);
|
||||
}
|
||||
|
||||
EVP_MAC_CTX *EVP_MAC_CTX_new(const EVP_MAC *mac)
|
||||
EVP_MAC_CTX *EVP_MAC_CTX_new(EVP_MAC *mac)
|
||||
{
|
||||
EVP_MAC_CTX *ctx = OPENSSL_zalloc(sizeof(EVP_MAC_CTX));
|
||||
|
||||
if (ctx == NULL || (ctx->data = mac->new()) == NULL) {
|
||||
if (ctx == NULL
|
||||
|| (ctx->data = mac->newctx(ossl_provider_ctx(mac->prov))) == NULL
|
||||
|| !EVP_MAC_up_ref(mac)) {
|
||||
EVPerr(EVP_F_EVP_MAC_CTX_NEW, ERR_R_MALLOC_FAILURE);
|
||||
if (ctx != NULL)
|
||||
mac->freectx(ctx->data);
|
||||
OPENSSL_free(ctx);
|
||||
ctx = NULL;
|
||||
} else {
|
||||
@@ -41,9 +39,11 @@ EVP_MAC_CTX *EVP_MAC_CTX_new(const EVP_MAC *mac)
|
||||
|
||||
void EVP_MAC_CTX_free(EVP_MAC_CTX *ctx)
|
||||
{
|
||||
if (ctx != NULL && ctx->data != NULL) {
|
||||
ctx->meth->free(ctx->data);
|
||||
if (ctx != NULL) {
|
||||
ctx->meth->freectx(ctx->data);
|
||||
ctx->data = NULL;
|
||||
/* refcnt-- */
|
||||
EVP_MAC_free(ctx->meth);
|
||||
}
|
||||
OPENSSL_free(ctx);
|
||||
}
|
||||
@@ -62,8 +62,13 @@ EVP_MAC_CTX *EVP_MAC_CTX_dup(const EVP_MAC_CTX *src)
|
||||
}
|
||||
|
||||
*dst = *src;
|
||||
if (!EVP_MAC_up_ref(dst->meth)) {
|
||||
EVPerr(EVP_F_EVP_MAC_CTX_DUP, ERR_R_MALLOC_FAILURE);
|
||||
OPENSSL_free(dst);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
dst->data = src->meth->dup(src->data);
|
||||
dst->data = src->meth->dupctx(src->data);
|
||||
if (dst->data == NULL) {
|
||||
EVP_MAC_CTX_free(dst);
|
||||
return NULL;
|
||||
@@ -72,16 +77,31 @@ EVP_MAC_CTX *EVP_MAC_CTX_dup(const EVP_MAC_CTX *src)
|
||||
return dst;
|
||||
}
|
||||
|
||||
const EVP_MAC *EVP_MAC_CTX_mac(EVP_MAC_CTX *ctx)
|
||||
EVP_MAC *EVP_MAC_CTX_mac(EVP_MAC_CTX *ctx)
|
||||
{
|
||||
return ctx->meth;
|
||||
}
|
||||
|
||||
size_t EVP_MAC_size(EVP_MAC_CTX *ctx)
|
||||
{
|
||||
if (ctx->data != NULL)
|
||||
return ctx->meth->size(ctx->data);
|
||||
/* If the MAC hasn't been initialized yet, we return zero */
|
||||
size_t sz = 0;
|
||||
|
||||
if (ctx->data != NULL) {
|
||||
OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END };
|
||||
|
||||
params[0] = OSSL_PARAM_construct_size_t(OSSL_MAC_PARAM_SIZE, &sz);
|
||||
if (ctx->meth->get_ctx_params != NULL) {
|
||||
if (ctx->meth->get_ctx_params(ctx->data, params))
|
||||
return sz;
|
||||
} else if (ctx->meth->get_params != NULL) {
|
||||
if (ctx->meth->get_params(params))
|
||||
return sz;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* If the MAC hasn't been initialized yet, or there is no size to get,
|
||||
* we return zero
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -97,101 +117,43 @@ int EVP_MAC_update(EVP_MAC_CTX *ctx, const unsigned char *data, size_t datalen)
|
||||
return ctx->meth->update(ctx->data, data, datalen);
|
||||
}
|
||||
|
||||
int EVP_MAC_final(EVP_MAC_CTX *ctx, unsigned char *out, size_t *poutlen)
|
||||
int EVP_MAC_final(EVP_MAC_CTX *ctx,
|
||||
unsigned char *out, size_t *outl, size_t outsize)
|
||||
{
|
||||
int l = ctx->meth->size(ctx->data);
|
||||
int l = EVP_MAC_size(ctx);
|
||||
|
||||
if (l < 0)
|
||||
return 0;
|
||||
if (poutlen != NULL)
|
||||
*poutlen = l;
|
||||
if (outl != NULL)
|
||||
*outl = l;
|
||||
if (out == NULL)
|
||||
return 1;
|
||||
return ctx->meth->final(ctx->data, out);
|
||||
return ctx->meth->final(ctx->data, out, outl, outsize);
|
||||
}
|
||||
|
||||
int EVP_MAC_ctrl(EVP_MAC_CTX *ctx, int cmd, ...)
|
||||
/*
|
||||
* The {get,set}_params functions return 1 if there is no corresponding
|
||||
* function in the implementation. This is the same as if there was one,
|
||||
* but it didn't recognise any of the given params, i.e. nothing in the
|
||||
* bag of parameters was useful.
|
||||
*/
|
||||
int EVP_MAC_get_params(EVP_MAC *mac, OSSL_PARAM params[])
|
||||
{
|
||||
int ok = -1;
|
||||
va_list args;
|
||||
|
||||
va_start(args, cmd);
|
||||
ok = EVP_MAC_vctrl(ctx, cmd, args);
|
||||
va_end(args);
|
||||
|
||||
if (ok == -2)
|
||||
EVPerr(EVP_F_EVP_MAC_CTRL, EVP_R_COMMAND_NOT_SUPPORTED);
|
||||
|
||||
return ok;
|
||||
if (mac->get_params != NULL)
|
||||
return mac->get_params(params);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int EVP_MAC_vctrl(EVP_MAC_CTX *ctx, int cmd, va_list args)
|
||||
int EVP_MAC_CTX_get_params(EVP_MAC_CTX *ctx, OSSL_PARAM params[])
|
||||
{
|
||||
int ok = 1;
|
||||
|
||||
if (ctx == NULL || ctx->meth == NULL)
|
||||
return -2;
|
||||
|
||||
switch (cmd) {
|
||||
#if 0
|
||||
case ...:
|
||||
/* code */
|
||||
ok = 1;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
if (ctx->meth->ctrl != NULL)
|
||||
ok = ctx->meth->ctrl(ctx->data, cmd, args);
|
||||
else
|
||||
ok = -2;
|
||||
break;
|
||||
}
|
||||
|
||||
return ok;
|
||||
if (ctx->meth->get_ctx_params != NULL)
|
||||
return ctx->meth->get_ctx_params(ctx->data, params);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int EVP_MAC_ctrl_str(EVP_MAC_CTX *ctx, const char *type, const char *value)
|
||||
int EVP_MAC_CTX_set_params(EVP_MAC_CTX *ctx, const OSSL_PARAM params[])
|
||||
{
|
||||
int ok = 1;
|
||||
|
||||
if (ctx == NULL || ctx->meth == NULL || ctx->meth->ctrl_str == NULL) {
|
||||
EVPerr(EVP_F_EVP_MAC_CTRL_STR, EVP_R_COMMAND_NOT_SUPPORTED);
|
||||
return -2;
|
||||
}
|
||||
|
||||
ok = ctx->meth->ctrl_str(ctx->data, type, value);
|
||||
|
||||
if (ok == -2)
|
||||
EVPerr(EVP_F_EVP_MAC_CTRL_STR, EVP_R_COMMAND_NOT_SUPPORTED);
|
||||
return ok;
|
||||
}
|
||||
|
||||
int EVP_MAC_str2ctrl(EVP_MAC_CTX *ctx, int cmd, const char *value)
|
||||
{
|
||||
size_t len;
|
||||
|
||||
len = strlen(value);
|
||||
if (len > INT_MAX)
|
||||
return -1;
|
||||
return EVP_MAC_ctrl(ctx, cmd, value, len);
|
||||
}
|
||||
|
||||
int EVP_MAC_hex2ctrl(EVP_MAC_CTX *ctx, int cmd, const char *hex)
|
||||
{
|
||||
unsigned char *bin;
|
||||
long binlen;
|
||||
int rv = -1;
|
||||
|
||||
bin = OPENSSL_hexstr2buf(hex, &binlen);
|
||||
if (bin == NULL)
|
||||
return 0;
|
||||
if (binlen <= INT_MAX)
|
||||
rv = EVP_MAC_ctrl(ctx, cmd, bin, (size_t)binlen);
|
||||
OPENSSL_free(bin);
|
||||
return rv;
|
||||
}
|
||||
|
||||
int EVP_MAC_nid(const EVP_MAC *mac)
|
||||
{
|
||||
return mac->type;
|
||||
if (ctx->meth->set_ctx_params != NULL)
|
||||
return ctx->meth->set_ctx_params(ctx->data, params);
|
||||
return 1;
|
||||
}
|
||||
@@ -0,0 +1,214 @@
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/core.h>
|
||||
#include <openssl/core_numbers.h>
|
||||
#include "internal/evp_int.h"
|
||||
#include "internal/provider.h"
|
||||
#include "evp_locl.h"
|
||||
|
||||
static int evp_mac_up_ref(void *vmac)
|
||||
{
|
||||
EVP_MAC *mac = vmac;
|
||||
int ref = 0;
|
||||
|
||||
CRYPTO_UP_REF(&mac->refcnt, &ref, mac->lock);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void evp_mac_free(void *vmac)
|
||||
{
|
||||
EVP_MAC *mac = vmac;
|
||||
int ref = 0;
|
||||
|
||||
if (mac == NULL)
|
||||
return;
|
||||
|
||||
CRYPTO_DOWN_REF(&mac->refcnt, &ref, mac->lock);
|
||||
if (ref > 0)
|
||||
return;
|
||||
ossl_provider_free(mac->prov);
|
||||
CRYPTO_THREAD_lock_free(mac->lock);
|
||||
OPENSSL_free(mac);
|
||||
}
|
||||
|
||||
static void *evp_mac_new(void)
|
||||
{
|
||||
EVP_MAC *mac = NULL;
|
||||
|
||||
if ((mac = OPENSSL_zalloc(sizeof(*mac))) == NULL
|
||||
|| (mac->lock = CRYPTO_THREAD_lock_new()) == NULL) {
|
||||
evp_mac_free(mac);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
mac->refcnt = 1;
|
||||
|
||||
return mac;
|
||||
}
|
||||
|
||||
static void *evp_mac_from_dispatch(int name_id,
|
||||
const OSSL_DISPATCH *fns,
|
||||
OSSL_PROVIDER *prov,
|
||||
void *unused)
|
||||
{
|
||||
EVP_MAC *mac = NULL;
|
||||
int fnmaccnt = 0, fnctxcnt = 0;
|
||||
|
||||
if ((mac = evp_mac_new()) == NULL) {
|
||||
EVPerr(0, ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
mac->name_id = name_id;
|
||||
|
||||
for (; fns->function_id != 0; fns++) {
|
||||
switch (fns->function_id) {
|
||||
case OSSL_FUNC_MAC_NEWCTX:
|
||||
if (mac->newctx != NULL)
|
||||
break;
|
||||
mac->newctx = OSSL_get_OP_mac_newctx(fns);
|
||||
fnctxcnt++;
|
||||
break;
|
||||
case OSSL_FUNC_MAC_DUPCTX:
|
||||
if (mac->dupctx != NULL)
|
||||
break;
|
||||
mac->dupctx = OSSL_get_OP_mac_dupctx(fns);
|
||||
break;
|
||||
case OSSL_FUNC_MAC_FREECTX:
|
||||
if (mac->freectx != NULL)
|
||||
break;
|
||||
mac->freectx = OSSL_get_OP_mac_freectx(fns);
|
||||
fnctxcnt++;
|
||||
break;
|
||||
case OSSL_FUNC_MAC_INIT:
|
||||
if (mac->init != NULL)
|
||||
break;
|
||||
mac->init = OSSL_get_OP_mac_init(fns);
|
||||
fnmaccnt++;
|
||||
break;
|
||||
case OSSL_FUNC_MAC_UPDATE:
|
||||
if (mac->update != NULL)
|
||||
break;
|
||||
mac->update = OSSL_get_OP_mac_update(fns);
|
||||
fnmaccnt++;
|
||||
break;
|
||||
case OSSL_FUNC_MAC_FINAL:
|
||||
if (mac->final != NULL)
|
||||
break;
|
||||
mac->final = OSSL_get_OP_mac_final(fns);
|
||||
fnmaccnt++;
|
||||
break;
|
||||
case OSSL_FUNC_MAC_GETTABLE_PARAMS:
|
||||
if (mac->gettable_params != NULL)
|
||||
break;
|
||||
mac->gettable_params =
|
||||
OSSL_get_OP_mac_gettable_params(fns);
|
||||
break;
|
||||
case OSSL_FUNC_MAC_GETTABLE_CTX_PARAMS:
|
||||
if (mac->gettable_ctx_params != NULL)
|
||||
break;
|
||||
mac->gettable_ctx_params =
|
||||
OSSL_get_OP_mac_gettable_ctx_params(fns);
|
||||
break;
|
||||
case OSSL_FUNC_MAC_SETTABLE_CTX_PARAMS:
|
||||
if (mac->settable_ctx_params != NULL)
|
||||
break;
|
||||
mac->settable_ctx_params =
|
||||
OSSL_get_OP_mac_settable_ctx_params(fns);
|
||||
break;
|
||||
case OSSL_FUNC_MAC_GET_PARAMS:
|
||||
if (mac->get_params != NULL)
|
||||
break;
|
||||
mac->get_params = OSSL_get_OP_mac_get_params(fns);
|
||||
break;
|
||||
case OSSL_FUNC_MAC_GET_CTX_PARAMS:
|
||||
if (mac->get_ctx_params != NULL)
|
||||
break;
|
||||
mac->get_ctx_params = OSSL_get_OP_mac_get_ctx_params(fns);
|
||||
break;
|
||||
case OSSL_FUNC_MAC_SET_CTX_PARAMS:
|
||||
if (mac->set_ctx_params != NULL)
|
||||
break;
|
||||
mac->set_ctx_params = OSSL_get_OP_mac_set_ctx_params(fns);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (fnmaccnt != 3
|
||||
|| fnctxcnt != 2) {
|
||||
/*
|
||||
* In order to be a consistent set of functions we must have at least
|
||||
* a complete set of "mac" functions, and a complete set of context
|
||||
* management functions, as well as the size function.
|
||||
*/
|
||||
evp_mac_free(mac);
|
||||
ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_PROVIDER_FUNCTIONS);
|
||||
return NULL;
|
||||
}
|
||||
mac->prov = prov;
|
||||
if (prov != NULL)
|
||||
ossl_provider_up_ref(prov);
|
||||
|
||||
return mac;
|
||||
}
|
||||
|
||||
EVP_MAC *EVP_MAC_fetch(OPENSSL_CTX *libctx, const char *algorithm,
|
||||
const char *properties)
|
||||
{
|
||||
return evp_generic_fetch(libctx, OSSL_OP_MAC, algorithm, properties,
|
||||
evp_mac_from_dispatch, NULL, evp_mac_up_ref,
|
||||
evp_mac_free);
|
||||
}
|
||||
|
||||
int EVP_MAC_up_ref(EVP_MAC *mac)
|
||||
{
|
||||
return evp_mac_up_ref(mac);
|
||||
}
|
||||
|
||||
void EVP_MAC_free(EVP_MAC *mac)
|
||||
{
|
||||
evp_mac_free(mac);
|
||||
}
|
||||
|
||||
int EVP_MAC_is_a(const EVP_MAC *mac, const char *name)
|
||||
{
|
||||
return evp_is_a(mac->prov, mac->name_id, name);
|
||||
}
|
||||
|
||||
const char *EVP_MAC_name(const EVP_MAC *mac)
|
||||
{
|
||||
return evp_first_name(mac->prov, mac->name_id);
|
||||
}
|
||||
|
||||
const OSSL_PROVIDER *EVP_MAC_provider(const EVP_MAC *mac)
|
||||
{
|
||||
return mac->prov;
|
||||
}
|
||||
|
||||
const OSSL_PARAM *EVP_MAC_gettable_params(const EVP_MAC *mac)
|
||||
{
|
||||
if (mac->gettable_params == NULL)
|
||||
return NULL;
|
||||
return mac->gettable_params();
|
||||
}
|
||||
|
||||
const OSSL_PARAM *EVP_MAC_CTX_gettable_params(const EVP_MAC *mac)
|
||||
{
|
||||
if (mac->gettable_ctx_params == NULL)
|
||||
return NULL;
|
||||
return mac->gettable_ctx_params();
|
||||
}
|
||||
|
||||
const OSSL_PARAM *EVP_MAC_CTX_settable_params(const EVP_MAC *mac)
|
||||
{
|
||||
if (mac->settable_ctx_params == NULL)
|
||||
return NULL;
|
||||
return mac->settable_ctx_params();
|
||||
}
|
||||
|
||||
void EVP_MAC_do_all_ex(OPENSSL_CTX *libctx,
|
||||
void (*fn)(EVP_MAC *mac, void *arg),
|
||||
void *arg)
|
||||
{
|
||||
evp_generic_do_all(libctx, OSSL_OP_MAC,
|
||||
(void (*)(void *, void *))fn, arg,
|
||||
evp_mac_from_dispatch, NULL, evp_mac_free);
|
||||
}
|
||||
@@ -56,39 +56,6 @@ int EVP_add_digest(const EVP_MD *md)
|
||||
return r;
|
||||
}
|
||||
|
||||
int EVP_add_mac(const EVP_MAC *m)
|
||||
{
|
||||
int r;
|
||||
|
||||
if (m == NULL)
|
||||
return 0;
|
||||
|
||||
r = OBJ_NAME_add(OBJ_nid2sn(m->type), OBJ_NAME_TYPE_MAC_METH,
|
||||
(const char *)m);
|
||||
if (r == 0)
|
||||
return 0;
|
||||
r = OBJ_NAME_add(OBJ_nid2ln(m->type), OBJ_NAME_TYPE_MAC_METH,
|
||||
(const char *)m);
|
||||
return r;
|
||||
}
|
||||
|
||||
/* TODO(3.0) Is this needed after changing to providers? */
|
||||
int EVP_add_kdf(const EVP_KDF *k)
|
||||
{
|
||||
int r;
|
||||
|
||||
if (k == NULL)
|
||||
return 0;
|
||||
|
||||
r = OBJ_NAME_add(OBJ_nid2sn(k->type), OBJ_NAME_TYPE_KDF_METH,
|
||||
(const char *)k);
|
||||
if (r == 0)
|
||||
return 0;
|
||||
r = OBJ_NAME_add(OBJ_nid2ln(k->type), OBJ_NAME_TYPE_KDF_METH,
|
||||
(const char *)k);
|
||||
return r;
|
||||
}
|
||||
|
||||
const EVP_CIPHER *EVP_get_cipherbyname(const char *name)
|
||||
{
|
||||
const EVP_CIPHER *cp;
|
||||
@@ -111,32 +78,8 @@ const EVP_MD *EVP_get_digestbyname(const char *name)
|
||||
return cp;
|
||||
}
|
||||
|
||||
const EVP_MAC *EVP_get_macbyname(const char *name)
|
||||
{
|
||||
const EVP_MAC *mp;
|
||||
|
||||
if (!OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_MACS, NULL))
|
||||
return NULL;
|
||||
|
||||
mp = (const EVP_MAC *)OBJ_NAME_get(name, OBJ_NAME_TYPE_MAC_METH);
|
||||
return mp;
|
||||
}
|
||||
|
||||
/* TODO(3.0) Is this API needed after implementing providers? */
|
||||
const EVP_KDF *EVP_get_kdfbyname(const char *name)
|
||||
{
|
||||
const EVP_KDF *kdf;
|
||||
|
||||
if (!OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_KDFS, NULL))
|
||||
return NULL;
|
||||
|
||||
kdf = (const EVP_KDF *)OBJ_NAME_get(name, OBJ_NAME_TYPE_KDF_METH);
|
||||
return kdf;
|
||||
}
|
||||
|
||||
void evp_cleanup_int(void)
|
||||
{
|
||||
OBJ_NAME_cleanup(OBJ_NAME_TYPE_MAC_METH);
|
||||
OBJ_NAME_cleanup(OBJ_NAME_TYPE_KDF_METH);
|
||||
OBJ_NAME_cleanup(OBJ_NAME_TYPE_CIPHER_METH);
|
||||
OBJ_NAME_cleanup(OBJ_NAME_TYPE_MD_METH);
|
||||
@@ -237,48 +180,3 @@ void EVP_MD_do_all_sorted(void (*fn) (const EVP_MD *md,
|
||||
dc.arg = arg;
|
||||
OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_MD_METH, do_all_md_fn, &dc);
|
||||
}
|
||||
|
||||
/* TODO(3.0) Are these do_all API's needed for MAC? */
|
||||
struct doall_mac {
|
||||
void *arg;
|
||||
void (*fn) (const EVP_MAC *ciph,
|
||||
const char *from, const char *to, void *arg);
|
||||
};
|
||||
|
||||
static void do_all_mac_fn(const OBJ_NAME *nm, void *arg)
|
||||
{
|
||||
struct doall_mac *dc = arg;
|
||||
|
||||
if (nm->alias)
|
||||
dc->fn(NULL, nm->name, nm->data, dc->arg);
|
||||
else
|
||||
dc->fn((const EVP_MAC *)nm->data, nm->name, NULL, dc->arg);
|
||||
}
|
||||
|
||||
void EVP_MAC_do_all(void (*fn)
|
||||
(const EVP_MAC *ciph, const char *from, const char *to,
|
||||
void *x), void *arg)
|
||||
{
|
||||
struct doall_mac dc;
|
||||
|
||||
/* Ignore errors */
|
||||
OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_MACS, NULL);
|
||||
|
||||
dc.fn = fn;
|
||||
dc.arg = arg;
|
||||
OBJ_NAME_do_all(OBJ_NAME_TYPE_MAC_METH, do_all_mac_fn, &dc);
|
||||
}
|
||||
|
||||
void EVP_MAC_do_all_sorted(void (*fn)
|
||||
(const EVP_MAC *ciph, const char *from,
|
||||
const char *to, void *x), void *arg)
|
||||
{
|
||||
struct doall_mac dc;
|
||||
|
||||
/* Ignore errors */
|
||||
OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_MACS, NULL);
|
||||
|
||||
dc.fn = fn;
|
||||
dc.arg = arg;
|
||||
OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_MAC_METH, do_all_mac_fn, &dc);
|
||||
}
|
||||
+18
-8
@@ -15,6 +15,7 @@
|
||||
#include <openssl/kdf.h>
|
||||
#include <openssl/hmac.h>
|
||||
#include <openssl/trace.h>
|
||||
#include <openssl/core_names.h>
|
||||
#include "internal/evp_int.h"
|
||||
#include "evp_locl.h"
|
||||
|
||||
@@ -23,8 +24,11 @@ int PKCS5_PBKDF2_HMAC(const char *pass, int passlen,
|
||||
const EVP_MD *digest, int keylen, unsigned char *out)
|
||||
{
|
||||
const char *empty = "";
|
||||
int rv = 1;
|
||||
int rv = 1, mode = 1;
|
||||
EVP_KDF *kdf;
|
||||
EVP_KDF_CTX *kctx;
|
||||
const char *mdname = EVP_MD_name(digest);
|
||||
OSSL_PARAM params[6], *p = params;
|
||||
|
||||
/* Keep documented behaviour. */
|
||||
if (pass == NULL) {
|
||||
@@ -36,15 +40,21 @@ int PKCS5_PBKDF2_HMAC(const char *pass, int passlen,
|
||||
if (salt == NULL && saltlen == 0)
|
||||
salt = (unsigned char *)empty;
|
||||
|
||||
kctx = EVP_KDF_CTX_new_id(EVP_KDF_PBKDF2);
|
||||
kdf = EVP_KDF_fetch(NULL, OSSL_KDF_NAME_PBKDF2, NULL);
|
||||
kctx = EVP_KDF_CTX_new(kdf);
|
||||
EVP_KDF_free(kdf);
|
||||
if (kctx == NULL)
|
||||
return 0;
|
||||
if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_PASS, pass, (size_t)passlen) != 1
|
||||
|| EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_PBKDF2_PKCS5_MODE, 1) != 1
|
||||
|| EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_SALT,
|
||||
salt, (size_t)saltlen) != 1
|
||||
|| EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_ITER, iter) != 1
|
||||
|| EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_MD, digest) != 1
|
||||
*p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_PASSWORD,
|
||||
(char *)pass, (size_t)passlen);
|
||||
*p++ = OSSL_PARAM_construct_int(OSSL_KDF_PARAM_PKCS5, &mode);
|
||||
*p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SALT,
|
||||
(unsigned char *)salt, saltlen);
|
||||
*p++ = OSSL_PARAM_construct_int(OSSL_KDF_PARAM_ITER, &iter);
|
||||
*p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST,
|
||||
(char *)mdname, strlen(mdname) + 1);
|
||||
*p = OSSL_PARAM_construct_end();
|
||||
if (EVP_KDF_CTX_set_params(kctx, params) != 1
|
||||
|| EVP_KDF_derive(kctx, out, keylen) != 1)
|
||||
rv = 0;
|
||||
|
||||
|
||||
+34
-4
@@ -20,9 +20,12 @@
|
||||
#include <openssl/dh.h>
|
||||
#include <openssl/cmac.h>
|
||||
#include <openssl/engine.h>
|
||||
#include <openssl/params.h>
|
||||
#include <openssl/core_names.h>
|
||||
|
||||
#include "internal/asn1_int.h"
|
||||
#include "internal/evp_int.h"
|
||||
#include "internal/provider.h"
|
||||
|
||||
static void EVP_PKEY_free_it(EVP_PKEY *x);
|
||||
|
||||
@@ -318,8 +321,18 @@ EVP_PKEY *EVP_PKEY_new_CMAC_key(ENGINE *e, const unsigned char *priv,
|
||||
size_t len, const EVP_CIPHER *cipher)
|
||||
{
|
||||
#ifndef OPENSSL_NO_CMAC
|
||||
# ifndef OPENSSL_NO_ENGINE
|
||||
const char *engine_id = e != NULL ? ENGINE_get_id(e) : NULL;
|
||||
# endif
|
||||
const char *cipher_name = EVP_CIPHER_name(cipher);
|
||||
const OSSL_PROVIDER *prov = EVP_CIPHER_provider(cipher);
|
||||
OPENSSL_CTX *libctx =
|
||||
prov == NULL ? NULL : ossl_provider_library_context(prov);
|
||||
EVP_PKEY *ret = EVP_PKEY_new();
|
||||
EVP_MAC_CTX *cmctx = EVP_MAC_CTX_new_id(EVP_MAC_CMAC);
|
||||
EVP_MAC *cmac = EVP_MAC_fetch(libctx, OSSL_MAC_NAME_CMAC, NULL);
|
||||
EVP_MAC_CTX *cmctx = cmac != NULL ? EVP_MAC_CTX_new(cmac) : NULL;
|
||||
OSSL_PARAM params[4];
|
||||
size_t paramsn = 0;
|
||||
|
||||
if (ret == NULL
|
||||
|| cmctx == NULL
|
||||
@@ -328,9 +341,22 @@ EVP_PKEY *EVP_PKEY_new_CMAC_key(ENGINE *e, const unsigned char *priv,
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (EVP_MAC_ctrl(cmctx, EVP_MAC_CTRL_SET_ENGINE, e) <= 0
|
||||
|| EVP_MAC_ctrl(cmctx, EVP_MAC_CTRL_SET_CIPHER, cipher) <= 0
|
||||
|| EVP_MAC_ctrl(cmctx, EVP_MAC_CTRL_SET_KEY, priv, len) <= 0) {
|
||||
# ifndef OPENSSL_NO_ENGINE
|
||||
if (engine_id != NULL)
|
||||
params[paramsn++] =
|
||||
OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_ENGINE,
|
||||
(char *)engine_id, 0);
|
||||
# endif
|
||||
|
||||
params[paramsn++] =
|
||||
OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_CIPHER,
|
||||
(char *)cipher_name, 0);
|
||||
params[paramsn++] =
|
||||
OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY,
|
||||
(char *)priv, len);
|
||||
params[paramsn] = OSSL_PARAM_construct_end();
|
||||
|
||||
if (!EVP_MAC_CTX_set_params(cmctx, params)) {
|
||||
EVPerr(EVP_F_EVP_PKEY_NEW_CMAC_KEY, EVP_R_KEY_SETUP_FAILED);
|
||||
goto err;
|
||||
}
|
||||
@@ -341,6 +367,7 @@ EVP_PKEY *EVP_PKEY_new_CMAC_key(ENGINE *e, const unsigned char *priv,
|
||||
err:
|
||||
EVP_PKEY_free(ret);
|
||||
EVP_MAC_CTX_free(cmctx);
|
||||
EVP_MAC_free(cmac);
|
||||
return NULL;
|
||||
#else
|
||||
EVPerr(EVP_F_EVP_PKEY_NEW_CMAC_KEY,
|
||||
@@ -613,6 +640,9 @@ void EVP_PKEY_free(EVP_PKEY *x)
|
||||
static void EVP_PKEY_free_it(EVP_PKEY *x)
|
||||
{
|
||||
/* internal function; x is never NULL */
|
||||
|
||||
evp_keymgmt_clear_pkey_cache(x);
|
||||
|
||||
if (x->ameth && x->ameth->pkey_free) {
|
||||
x->ameth->pkey_free(x);
|
||||
x->pkey.ptr = NULL;
|
||||
|
||||
+17
-8
@@ -10,6 +10,7 @@
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/kdf.h>
|
||||
#include <openssl/core_names.h>
|
||||
#include "internal/numbers.h"
|
||||
|
||||
#ifndef OPENSSL_NO_SCRYPT
|
||||
@@ -40,7 +41,9 @@ int EVP_PBE_scrypt(const char *pass, size_t passlen,
|
||||
{
|
||||
const char *empty = "";
|
||||
int rv = 1;
|
||||
EVP_KDF *kdf;
|
||||
EVP_KDF_CTX *kctx;
|
||||
OSSL_PARAM params[7], *z = params;
|
||||
|
||||
if (r > UINT32_MAX || p > UINT32_MAX) {
|
||||
EVPerr(EVP_F_EVP_PBE_SCRYPT, EVP_R_PARAMETER_TOO_LARGE);
|
||||
@@ -59,17 +62,23 @@ int EVP_PBE_scrypt(const char *pass, size_t passlen,
|
||||
if (maxmem == 0)
|
||||
maxmem = SCRYPT_MAX_MEM;
|
||||
|
||||
kctx = EVP_KDF_CTX_new_id(EVP_KDF_SCRYPT);
|
||||
kdf = EVP_KDF_fetch(NULL, OSSL_KDF_NAME_SCRYPT, NULL);
|
||||
kctx = EVP_KDF_CTX_new(kdf);
|
||||
EVP_KDF_free(kdf);
|
||||
if (kctx == NULL)
|
||||
return 0;
|
||||
|
||||
if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_PASS, pass, (size_t)passlen) != 1
|
||||
|| EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_SALT,
|
||||
salt, (size_t)saltlen) != 1
|
||||
|| EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_SCRYPT_N, N) != 1
|
||||
|| EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_SCRYPT_R, (uint32_t)r) != 1
|
||||
|| EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_SCRYPT_P, (uint32_t)p) != 1
|
||||
|| EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_MAXMEM_BYTES, maxmem) != 1
|
||||
*z++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_PASSWORD,
|
||||
(unsigned char *)pass,
|
||||
passlen);
|
||||
*z++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SALT,
|
||||
(unsigned char *)salt, saltlen);
|
||||
*z++ = OSSL_PARAM_construct_uint64(OSSL_KDF_PARAM_SCRYPT_N, &N);
|
||||
*z++ = OSSL_PARAM_construct_uint64(OSSL_KDF_PARAM_SCRYPT_R, &r);
|
||||
*z++ = OSSL_PARAM_construct_uint64(OSSL_KDF_PARAM_SCRYPT_P, &p);
|
||||
*z++ = OSSL_PARAM_construct_uint64(OSSL_KDF_PARAM_SCRYPT_MAXMEM, &maxmem);
|
||||
*z = OSSL_PARAM_construct_end();
|
||||
if (EVP_KDF_CTX_set_params(kctx, params) != 1
|
||||
|| EVP_KDF_derive(kctx, key, keylen) != 1)
|
||||
rv = 0;
|
||||
|
||||
|
||||
+204
-60
@@ -11,131 +11,247 @@
|
||||
#include <string.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/buffer.h>
|
||||
#include <openssl/kdf.h>
|
||||
#include <openssl/core.h>
|
||||
#include <openssl/core_names.h>
|
||||
#include <openssl/params.h>
|
||||
#include "internal/numbers.h"
|
||||
#include "internal/evp_int.h"
|
||||
|
||||
#define MAX_PARAM 20
|
||||
|
||||
typedef struct {
|
||||
EVP_KDF_CTX *kctx;
|
||||
/*
|
||||
* EVP_PKEY implementations collect bits of certain data
|
||||
*/
|
||||
BUF_MEM *collected_seed;
|
||||
BUF_MEM *collected_info;
|
||||
} EVP_PKEY_KDF_CTX;
|
||||
|
||||
static void pkey_kdf_free_collected(EVP_PKEY_KDF_CTX *pkctx)
|
||||
{
|
||||
BUF_MEM_free(pkctx->collected_seed);
|
||||
pkctx->collected_seed = NULL;
|
||||
BUF_MEM_free(pkctx->collected_info);
|
||||
pkctx->collected_info = NULL;
|
||||
}
|
||||
|
||||
static int pkey_kdf_init(EVP_PKEY_CTX *ctx)
|
||||
{
|
||||
EVP_PKEY_KDF_CTX *pkctx;
|
||||
EVP_KDF_CTX *kctx;
|
||||
const char *kdf_name = OBJ_nid2sn(ctx->pmeth->pkey_id);
|
||||
EVP_KDF *kdf;
|
||||
|
||||
kctx = EVP_KDF_CTX_new_id(ctx->pmeth->pkey_id);
|
||||
if (kctx == NULL)
|
||||
pkctx = OPENSSL_zalloc(sizeof(*pkctx));
|
||||
if (pkctx == NULL)
|
||||
return 0;
|
||||
|
||||
ctx->data = kctx;
|
||||
kdf = EVP_KDF_fetch(NULL, kdf_name, NULL);
|
||||
kctx = EVP_KDF_CTX_new(kdf);
|
||||
EVP_KDF_free(kdf);
|
||||
if (kctx == NULL) {
|
||||
OPENSSL_free(pkctx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
pkctx->kctx = kctx;
|
||||
ctx->data = pkctx;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void pkey_kdf_cleanup(EVP_PKEY_CTX *ctx)
|
||||
{
|
||||
EVP_KDF_CTX *kctx = ctx->data;
|
||||
EVP_PKEY_KDF_CTX *pkctx = ctx->data;
|
||||
|
||||
EVP_KDF_CTX_free(kctx);
|
||||
EVP_KDF_CTX_free(pkctx->kctx);
|
||||
pkey_kdf_free_collected(pkctx);
|
||||
OPENSSL_free(pkctx);
|
||||
}
|
||||
|
||||
static int collect(BUF_MEM **collector, void *data, size_t datalen)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
if (*collector == NULL)
|
||||
*collector = BUF_MEM_new();
|
||||
if (*collector == NULL) {
|
||||
ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (data != NULL && datalen > 0) {
|
||||
i = (*collector)->length; /* BUF_MEM_grow() changes it! */
|
||||
|
||||
if (!BUF_MEM_grow(*collector, i + datalen))
|
||||
return 0;
|
||||
memcpy((*collector)->data + i, data, datalen);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int pkey_kdf_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
|
||||
{
|
||||
EVP_KDF_CTX *kctx = ctx->data;
|
||||
uint64_t u64_value;
|
||||
int cmd;
|
||||
int ret;
|
||||
EVP_PKEY_KDF_CTX *pkctx = ctx->data;
|
||||
EVP_KDF_CTX *kctx = pkctx->kctx;
|
||||
enum { T_OCTET_STRING, T_UINT64, T_DIGEST, T_INT } cmd;
|
||||
const char *name, *mdname;
|
||||
BUF_MEM **collector = NULL;
|
||||
OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END };
|
||||
|
||||
switch (type) {
|
||||
case EVP_PKEY_CTRL_PASS:
|
||||
cmd = EVP_KDF_CTRL_SET_PASS;
|
||||
cmd = T_OCTET_STRING;
|
||||
name = OSSL_KDF_PARAM_PASSWORD;
|
||||
break;
|
||||
case EVP_PKEY_CTRL_HKDF_SALT:
|
||||
case EVP_PKEY_CTRL_SCRYPT_SALT:
|
||||
cmd = EVP_KDF_CTRL_SET_SALT;
|
||||
cmd = T_OCTET_STRING;
|
||||
name = OSSL_KDF_PARAM_SALT;
|
||||
break;
|
||||
case EVP_PKEY_CTRL_TLS_MD:
|
||||
case EVP_PKEY_CTRL_HKDF_MD:
|
||||
cmd = EVP_KDF_CTRL_SET_MD;
|
||||
cmd = T_DIGEST;
|
||||
name = OSSL_KDF_PARAM_DIGEST;
|
||||
break;
|
||||
case EVP_PKEY_CTRL_TLS_SECRET:
|
||||
cmd = EVP_KDF_CTRL_SET_TLS_SECRET;
|
||||
ret = EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_RESET_TLS_SEED);
|
||||
if (ret < 1)
|
||||
return ret;
|
||||
cmd = T_OCTET_STRING;
|
||||
name = OSSL_KDF_PARAM_SECRET;
|
||||
/*
|
||||
* Perform the semantics described in
|
||||
* EVP_PKEY_CTX_add1_tls1_prf_seed(3)
|
||||
*/
|
||||
if (ctx->pmeth->pkey_id == NID_tls1_prf) {
|
||||
BUF_MEM_free(pkctx->collected_seed);
|
||||
pkctx->collected_seed = NULL;
|
||||
}
|
||||
break;
|
||||
case EVP_PKEY_CTRL_TLS_SEED:
|
||||
cmd = EVP_KDF_CTRL_ADD_TLS_SEED;
|
||||
cmd = T_OCTET_STRING;
|
||||
name = OSSL_KDF_PARAM_SEED;
|
||||
collector = &pkctx->collected_seed;
|
||||
break;
|
||||
case EVP_PKEY_CTRL_HKDF_KEY:
|
||||
cmd = EVP_KDF_CTRL_SET_KEY;
|
||||
cmd = T_OCTET_STRING;
|
||||
name = OSSL_KDF_PARAM_KEY;
|
||||
break;
|
||||
case EVP_PKEY_CTRL_HKDF_INFO:
|
||||
cmd = EVP_KDF_CTRL_ADD_HKDF_INFO;
|
||||
cmd = T_OCTET_STRING;
|
||||
name = OSSL_KDF_PARAM_INFO;
|
||||
collector = &pkctx->collected_info;
|
||||
break;
|
||||
case EVP_PKEY_CTRL_HKDF_MODE:
|
||||
cmd = EVP_KDF_CTRL_SET_HKDF_MODE;
|
||||
cmd = T_INT;
|
||||
name = OSSL_KDF_PARAM_MODE;
|
||||
break;
|
||||
case EVP_PKEY_CTRL_SCRYPT_N:
|
||||
cmd = EVP_KDF_CTRL_SET_SCRYPT_N;
|
||||
cmd = T_UINT64;
|
||||
name = OSSL_KDF_PARAM_SCRYPT_N;
|
||||
break;
|
||||
case EVP_PKEY_CTRL_SCRYPT_R:
|
||||
cmd = EVP_KDF_CTRL_SET_SCRYPT_R;
|
||||
cmd = T_UINT64; /* Range checking occurs on the provider side */
|
||||
name = OSSL_KDF_PARAM_SCRYPT_R;
|
||||
break;
|
||||
case EVP_PKEY_CTRL_SCRYPT_P:
|
||||
cmd = EVP_KDF_CTRL_SET_SCRYPT_P;
|
||||
cmd = T_UINT64; /* Range checking occurs on the provider side */
|
||||
name = OSSL_KDF_PARAM_SCRYPT_P;
|
||||
break;
|
||||
case EVP_PKEY_CTRL_SCRYPT_MAXMEM_BYTES:
|
||||
cmd = EVP_KDF_CTRL_SET_MAXMEM_BYTES;
|
||||
cmd = T_UINT64;
|
||||
name = OSSL_KDF_PARAM_SCRYPT_MAXMEM;
|
||||
break;
|
||||
default:
|
||||
return -2;
|
||||
}
|
||||
|
||||
switch (cmd) {
|
||||
case EVP_KDF_CTRL_SET_PASS:
|
||||
case EVP_KDF_CTRL_SET_SALT:
|
||||
case EVP_KDF_CTRL_SET_KEY:
|
||||
case EVP_KDF_CTRL_SET_TLS_SECRET:
|
||||
case EVP_KDF_CTRL_ADD_TLS_SEED:
|
||||
case EVP_KDF_CTRL_ADD_HKDF_INFO:
|
||||
return EVP_KDF_ctrl(kctx, cmd, (const unsigned char *)p2, (size_t)p1);
|
||||
|
||||
case EVP_KDF_CTRL_SET_MD:
|
||||
return EVP_KDF_ctrl(kctx, cmd, (const EVP_MD *)p2);
|
||||
|
||||
case EVP_KDF_CTRL_SET_HKDF_MODE:
|
||||
return EVP_KDF_ctrl(kctx, cmd, (int)p1);
|
||||
|
||||
case EVP_KDF_CTRL_SET_SCRYPT_R:
|
||||
case EVP_KDF_CTRL_SET_SCRYPT_P:
|
||||
u64_value = *(uint64_t *)p2;
|
||||
if (u64_value > UINT32_MAX) {
|
||||
EVPerr(EVP_F_PKEY_KDF_CTRL, EVP_R_PARAMETER_TOO_LARGE);
|
||||
return 0;
|
||||
if (collector != NULL) {
|
||||
switch (cmd) {
|
||||
case T_OCTET_STRING:
|
||||
return collect(collector, p2, p1);
|
||||
default:
|
||||
OPENSSL_assert("You shouldn't be here");
|
||||
break;
|
||||
}
|
||||
|
||||
return EVP_KDF_ctrl(kctx, cmd, (uint32_t)u64_value);
|
||||
|
||||
case EVP_KDF_CTRL_SET_SCRYPT_N:
|
||||
case EVP_KDF_CTRL_SET_MAXMEM_BYTES:
|
||||
return EVP_KDF_ctrl(kctx, cmd, *(uint64_t *)p2);
|
||||
|
||||
default:
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
switch (cmd) {
|
||||
case T_OCTET_STRING:
|
||||
params[0] =
|
||||
OSSL_PARAM_construct_octet_string(name, (unsigned char *)p2,
|
||||
(size_t)p1);
|
||||
break;
|
||||
|
||||
case T_DIGEST:
|
||||
mdname = EVP_MD_name((const EVP_MD *)p2);
|
||||
params[0] = OSSL_PARAM_construct_utf8_string(name, (char *)mdname,
|
||||
strlen(mdname) + 1);
|
||||
break;
|
||||
|
||||
/*
|
||||
* These are special because the helper macros pass a pointer to the
|
||||
* stack, so a local copy is required.
|
||||
*/
|
||||
case T_INT:
|
||||
params[0] = OSSL_PARAM_construct_int(name, &p1);
|
||||
break;
|
||||
|
||||
case T_UINT64:
|
||||
params[0] = OSSL_PARAM_construct_uint64(name, (uint64_t *)p2);
|
||||
break;
|
||||
}
|
||||
|
||||
return EVP_KDF_CTX_set_params(kctx, params);
|
||||
}
|
||||
|
||||
static int pkey_kdf_ctrl_str(EVP_PKEY_CTX *ctx, const char *type,
|
||||
const char *value)
|
||||
{
|
||||
EVP_KDF_CTX *kctx = ctx->data;
|
||||
EVP_PKEY_KDF_CTX *pkctx = ctx->data;
|
||||
EVP_KDF_CTX *kctx = pkctx->kctx;
|
||||
const EVP_KDF *kdf = EVP_KDF_CTX_kdf(kctx);
|
||||
BUF_MEM **collector = NULL;
|
||||
const OSSL_PARAM *defs = EVP_KDF_CTX_settable_params(kdf);
|
||||
OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END };
|
||||
int ok = 0;
|
||||
|
||||
/* Deal with ctrl name aliasing */
|
||||
if (strcmp(type, "md") == 0)
|
||||
return EVP_KDF_ctrl_str(kctx, "digest", value);
|
||||
return EVP_KDF_ctrl_str(kctx, type, value);
|
||||
type = OSSL_KDF_PARAM_DIGEST;
|
||||
/* scrypt uses 'N', params uses 'n' */
|
||||
if (strcmp(type, "N") == 0)
|
||||
type = OSSL_KDF_PARAM_SCRYPT_N;
|
||||
|
||||
if (!OSSL_PARAM_allocate_from_text(¶ms[0], defs, type,
|
||||
value, strlen(value)))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* We do the same special casing of seed and info here as in
|
||||
* pkey_kdf_ctrl()
|
||||
*/
|
||||
if (strcmp(params[0].key, OSSL_KDF_PARAM_SEED) == 0)
|
||||
collector = &pkctx->collected_seed;
|
||||
else if (strcmp(params[0].key, OSSL_KDF_PARAM_INFO) == 0)
|
||||
collector = &pkctx->collected_info;
|
||||
|
||||
if (collector != NULL)
|
||||
ok = collect(collector, params[0].data, params[0].data_size);
|
||||
else
|
||||
ok = EVP_KDF_CTX_set_params(kctx, params);
|
||||
OPENSSL_free(params[0].data);
|
||||
return ok;
|
||||
}
|
||||
|
||||
static int pkey_kdf_derive_init(EVP_PKEY_CTX *ctx)
|
||||
{
|
||||
EVP_KDF_CTX *kctx = ctx->data;
|
||||
EVP_PKEY_KDF_CTX *pkctx = ctx->data;
|
||||
|
||||
EVP_KDF_reset(kctx);
|
||||
pkey_kdf_free_collected(pkctx);
|
||||
if (pkctx->kctx != NULL)
|
||||
EVP_KDF_reset(pkctx->kctx);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -146,9 +262,37 @@ static int pkey_kdf_derive_init(EVP_PKEY_CTX *ctx)
|
||||
static int pkey_kdf_derive(EVP_PKEY_CTX *ctx, unsigned char *key,
|
||||
size_t *keylen)
|
||||
{
|
||||
EVP_KDF_CTX *kctx = ctx->data;
|
||||
EVP_PKEY_KDF_CTX *pkctx = ctx->data;
|
||||
EVP_KDF_CTX *kctx = pkctx->kctx;
|
||||
size_t outlen = EVP_KDF_size(kctx);
|
||||
int r;
|
||||
|
||||
if (pkctx->collected_seed != NULL) {
|
||||
OSSL_PARAM params[] = { OSSL_PARAM_END, OSSL_PARAM_END };
|
||||
|
||||
params[0] =
|
||||
OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SEED,
|
||||
pkctx->collected_seed->data,
|
||||
pkctx->collected_seed->length);
|
||||
|
||||
r = EVP_KDF_CTX_set_params(kctx, params);
|
||||
pkey_kdf_free_collected(pkctx);
|
||||
if (!r)
|
||||
return 0;
|
||||
}
|
||||
if (pkctx->collected_info != NULL) {
|
||||
OSSL_PARAM params[] = { OSSL_PARAM_END, OSSL_PARAM_END };
|
||||
|
||||
params[0] =
|
||||
OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_INFO,
|
||||
pkctx->collected_info->data,
|
||||
pkctx->collected_info->length);
|
||||
|
||||
r = EVP_KDF_CTX_set_params(kctx, params);
|
||||
pkey_kdf_free_collected(pkctx);
|
||||
if (!r)
|
||||
return 0;
|
||||
}
|
||||
if (outlen == 0 || outlen == SIZE_MAX) {
|
||||
/* Variable-output algorithm */
|
||||
if (key == NULL)
|
||||
|
||||
+160
-35
@@ -7,8 +7,12 @@
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/engine.h>
|
||||
#include <openssl/params.h>
|
||||
#include <openssl/core_names.h>
|
||||
#include "internal/evp_int.h"
|
||||
#include "evp_locl.h"
|
||||
|
||||
@@ -40,18 +44,21 @@ typedef struct {
|
||||
} raw_data;
|
||||
} MAC_PKEY_CTX;
|
||||
|
||||
static void pkey_mac_cleanup(EVP_PKEY_CTX *ctx);
|
||||
|
||||
static int pkey_mac_init(EVP_PKEY_CTX *ctx)
|
||||
{
|
||||
MAC_PKEY_CTX *hctx;
|
||||
/* We're being smart and using the same base NIDs for PKEY and for MAC */
|
||||
int nid = ctx->pmeth->pkey_id;
|
||||
EVP_MAC *mac = EVP_MAC_fetch(NULL, OBJ_nid2sn(nid), NULL);
|
||||
|
||||
if ((hctx = OPENSSL_zalloc(sizeof(*hctx))) == NULL) {
|
||||
EVPerr(EVP_F_PKEY_MAC_INIT, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* We're being smart and using the same base NIDs for PKEY and for MAC */
|
||||
hctx->ctx = EVP_MAC_CTX_new_id(nid);
|
||||
hctx->ctx = EVP_MAC_CTX_new(mac);
|
||||
if (hctx->ctx == NULL) {
|
||||
OPENSSL_free(hctx);
|
||||
return 0;
|
||||
@@ -64,14 +71,13 @@ static int pkey_mac_init(EVP_PKEY_CTX *ctx)
|
||||
hctx->raw_data.ktmp.type = V_ASN1_OCTET_STRING;
|
||||
}
|
||||
|
||||
pkey_mac_cleanup(ctx);
|
||||
EVP_PKEY_CTX_set_data(ctx, hctx);
|
||||
ctx->keygen_info_count = 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void pkey_mac_cleanup(EVP_PKEY_CTX *ctx);
|
||||
|
||||
static int pkey_mac_copy(EVP_PKEY_CTX *dst, const EVP_PKEY_CTX *src)
|
||||
{
|
||||
MAC_PKEY_CTX *sctx, *dctx;
|
||||
@@ -93,6 +99,17 @@ static int pkey_mac_copy(EVP_PKEY_CTX *dst, const EVP_PKEY_CTX *src)
|
||||
if (dctx->ctx == NULL)
|
||||
goto err;
|
||||
|
||||
/*
|
||||
* Normally, nothing special would be done with the MAC method. In
|
||||
* this particular case, though, the MAC method was fetched internally
|
||||
* by pkey_mac_init() above or by EVP_PKEY_new_CMAC_key() and passed
|
||||
* via the EVP_MAC_CTX, so it is effectively like every new EVP_MAC_CTX
|
||||
* fetches the MAC method anew in this case. Therefore, its reference
|
||||
* count must be adjusted here.
|
||||
*/
|
||||
if (!EVP_MAC_up_ref(EVP_MAC_CTX_mac(dctx->ctx)))
|
||||
goto err;
|
||||
|
||||
dctx->type = sctx->type;
|
||||
|
||||
switch (dctx->type) {
|
||||
@@ -117,9 +134,16 @@ static int pkey_mac_copy(EVP_PKEY_CTX *dst, const EVP_PKEY_CTX *src)
|
||||
|
||||
static void pkey_mac_cleanup(EVP_PKEY_CTX *ctx)
|
||||
{
|
||||
MAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(ctx);
|
||||
/*
|
||||
* For the exact same reasons the MAC reference count is incremented
|
||||
* in pkey_mac_copy() above, it must be explicitly freed here.
|
||||
*/
|
||||
|
||||
MAC_PKEY_CTX *hctx = ctx == NULL ? NULL : EVP_PKEY_CTX_get_data(ctx);
|
||||
|
||||
if (hctx != NULL) {
|
||||
EVP_MAC *mac = EVP_MAC_CTX_mac(hctx->ctx);
|
||||
|
||||
switch (hctx->type) {
|
||||
case MAC_TYPE_RAW:
|
||||
OPENSSL_clear_free(hctx->raw_data.ktmp.data,
|
||||
@@ -127,6 +151,7 @@ static void pkey_mac_cleanup(EVP_PKEY_CTX *ctx)
|
||||
break;
|
||||
}
|
||||
EVP_MAC_CTX_free(hctx->ctx);
|
||||
EVP_MAC_free(mac);
|
||||
OPENSSL_free(hctx);
|
||||
EVP_PKEY_CTX_set_data(ctx, NULL);
|
||||
}
|
||||
@@ -156,6 +181,8 @@ static int pkey_mac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
|
||||
|
||||
if (cmkey == NULL)
|
||||
return 0;
|
||||
if (!EVP_MAC_up_ref(EVP_MAC_CTX_mac(hctx->ctx)))
|
||||
return 0;
|
||||
EVP_PKEY_assign(pkey, nid, cmkey);
|
||||
}
|
||||
break;
|
||||
@@ -194,25 +221,34 @@ static int pkey_mac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx)
|
||||
&& (ctx->pmeth->flags & EVP_PKEY_FLAG_SIGCTX_CUSTOM) != 0;
|
||||
|
||||
if (set_key) {
|
||||
if (EVP_PKEY_id(EVP_PKEY_CTX_get0_pkey(ctx))
|
||||
!= EVP_MAC_nid(EVP_MAC_CTX_mac(hctx->ctx)))
|
||||
if (!EVP_MAC_is_a(EVP_MAC_CTX_mac(hctx->ctx),
|
||||
OBJ_nid2sn(EVP_PKEY_id(EVP_PKEY_CTX_get0_pkey(ctx)))))
|
||||
return 0;
|
||||
key = EVP_PKEY_get0(EVP_PKEY_CTX_get0_pkey(ctx));
|
||||
if (key == NULL)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Some MACs don't support this control... that's fine */
|
||||
EVP_MAC_ctrl(hctx->ctx, EVP_MAC_CTRL_SET_FLAGS,
|
||||
EVP_MD_CTX_test_flags(mctx, ~EVP_MD_CTX_FLAG_NO_INIT));
|
||||
|
||||
EVP_MD_CTX_set_flags(mctx, EVP_MD_CTX_FLAG_NO_INIT);
|
||||
EVP_MD_CTX_set_update_fn(mctx, int_update);
|
||||
|
||||
if (set_key)
|
||||
rv = EVP_MAC_ctrl(hctx->ctx, EVP_MAC_CTRL_SET_KEY, key->data,
|
||||
key->length);
|
||||
return rv > 0;
|
||||
/* Some MACs don't support this control... that's fine */
|
||||
{
|
||||
OSSL_PARAM params[3];
|
||||
size_t params_n = 0;
|
||||
int flags = EVP_MD_CTX_test_flags(mctx, ~EVP_MD_CTX_FLAG_NO_INIT);
|
||||
|
||||
/* TODO(3.0) "flags" isn't quite right, i.e. a quick hack for now */
|
||||
params[params_n++] =
|
||||
OSSL_PARAM_construct_int(OSSL_MAC_PARAM_FLAGS, &flags);
|
||||
if (set_key)
|
||||
params[params_n++] =
|
||||
OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY,
|
||||
key->data, key->length);
|
||||
params[params_n++] = OSSL_PARAM_construct_end();
|
||||
rv = EVP_MAC_CTX_set_params(hctx->ctx, params);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
static int pkey_mac_signctx(EVP_PKEY_CTX *ctx, unsigned char *sig,
|
||||
@@ -220,7 +256,7 @@ static int pkey_mac_signctx(EVP_PKEY_CTX *ctx, unsigned char *sig,
|
||||
{
|
||||
MAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(ctx);
|
||||
|
||||
return EVP_MAC_final(hctx->ctx, sig, siglen);
|
||||
return EVP_MAC_final(hctx->ctx, sig, siglen, EVP_MAC_size(hctx->ctx));
|
||||
}
|
||||
|
||||
static int pkey_mac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
|
||||
@@ -235,14 +271,24 @@ static int pkey_mac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
|
||||
return -2; /* The raw types don't support ciphers */
|
||||
case MAC_TYPE_MAC:
|
||||
{
|
||||
int rv;
|
||||
OSSL_PARAM params[3];
|
||||
size_t params_n = 0;
|
||||
char *ciphname = (char *)OBJ_nid2sn(EVP_CIPHER_nid(p2));
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
char *engineid = (char *)ENGINE_get_id(ctx->engine);
|
||||
|
||||
if ((rv = EVP_MAC_ctrl(hctx->ctx, EVP_MAC_CTRL_SET_ENGINE,
|
||||
ctx->engine)) <= 0
|
||||
|| (rv = EVP_MAC_ctrl(hctx->ctx, EVP_MAC_CTRL_SET_CIPHER,
|
||||
p2)) <= 0
|
||||
|| !(rv = EVP_MAC_init(hctx->ctx)))
|
||||
return rv;
|
||||
params[params_n++] =
|
||||
OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_ENGINE,
|
||||
engineid, 0);
|
||||
#endif
|
||||
params[params_n++] =
|
||||
OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_CIPHER,
|
||||
ciphname, 0);
|
||||
params[params_n] = OSSL_PARAM_construct_end();
|
||||
|
||||
if (!EVP_MAC_CTX_set_params(hctx->ctx, params)
|
||||
|| !EVP_MAC_init(hctx->ctx))
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@@ -276,8 +322,40 @@ static int pkey_mac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
|
||||
break;
|
||||
|
||||
case EVP_PKEY_CTRL_SET_DIGEST_SIZE:
|
||||
return EVP_MAC_ctrl(hctx->ctx, EVP_MAC_CTRL_SET_SIZE, (size_t)p1);
|
||||
{
|
||||
OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END };
|
||||
size_t size = (size_t)p1;
|
||||
size_t verify = 0;
|
||||
|
||||
/*
|
||||
* We verify that the length is actually set by getting back
|
||||
* the same parameter and checking that it matches what we
|
||||
* tried to set.
|
||||
* TODO(3.0) when we have a more direct mechanism to check if
|
||||
* a parameter was used, we must refactor this to use that.
|
||||
*/
|
||||
|
||||
params[0] =
|
||||
OSSL_PARAM_construct_size_t(OSSL_MAC_PARAM_SIZE, &size);
|
||||
|
||||
if (!EVP_MAC_CTX_set_params(hctx->ctx, params))
|
||||
return 0;
|
||||
|
||||
params[0] =
|
||||
OSSL_PARAM_construct_size_t(OSSL_MAC_PARAM_SIZE, &verify);
|
||||
|
||||
if (!EVP_MAC_CTX_get_params(hctx->ctx, params))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Since EVP_MAC_CTX_{get,set}_params() returned successfully,
|
||||
* we can only assume that the size was ignored, i.e. this
|
||||
* control is unsupported.
|
||||
*/
|
||||
if (verify != size)
|
||||
return -2;
|
||||
}
|
||||
break;
|
||||
case EVP_PKEY_CTRL_SET_MAC_KEY:
|
||||
switch (hctx->type) {
|
||||
case MAC_TYPE_RAW:
|
||||
@@ -287,8 +365,17 @@ static int pkey_mac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
|
||||
return 0;
|
||||
break;
|
||||
case MAC_TYPE_MAC:
|
||||
if (EVP_MAC_ctrl(hctx->ctx, EVP_MAC_CTRL_SET_KEY, p2, p1) <= 0)
|
||||
return 0;
|
||||
{
|
||||
OSSL_PARAM params[2];
|
||||
size_t params_n = 0;
|
||||
|
||||
params[params_n++] =
|
||||
OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY,
|
||||
p2, p1);
|
||||
params[params_n] = OSSL_PARAM_construct_end();
|
||||
|
||||
return EVP_MAC_CTX_set_params(hctx->ctx, params);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
/* This should be dead code */
|
||||
@@ -303,17 +390,31 @@ static int pkey_mac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
|
||||
if (!EVP_MAC_init(hctx->ctx))
|
||||
return 0;
|
||||
{
|
||||
int rv;
|
||||
ASN1_OCTET_STRING *key =
|
||||
(ASN1_OCTET_STRING *)ctx->pkey->pkey.ptr;
|
||||
OSSL_PARAM params[4];
|
||||
size_t params_n = 0;
|
||||
char *mdname =
|
||||
(char *)OBJ_nid2sn(EVP_MD_nid(hctx->raw_data.md));
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
char *engineid = ctx->engine == NULL
|
||||
? NULL : (char *)ENGINE_get_id(ctx->engine);
|
||||
|
||||
if ((rv = EVP_MAC_ctrl(hctx->ctx, EVP_MAC_CTRL_SET_ENGINE,
|
||||
ctx->engine)) <= 0
|
||||
|| (rv = EVP_MAC_ctrl(hctx->ctx, EVP_MAC_CTRL_SET_MD,
|
||||
hctx->raw_data.md)) <= 0
|
||||
|| (rv = EVP_MAC_ctrl(hctx->ctx, EVP_MAC_CTRL_SET_KEY,
|
||||
key->data, key->length)) <= 0)
|
||||
return rv;
|
||||
if (engineid != NULL) {
|
||||
params[params_n++] =
|
||||
OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_ENGINE,
|
||||
engineid, 0);
|
||||
}
|
||||
#endif
|
||||
params[params_n++] =
|
||||
OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST,
|
||||
mdname, 0);
|
||||
params[params_n++] =
|
||||
OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY,
|
||||
key->data, key->length);
|
||||
params[params_n] = OSSL_PARAM_construct_end();
|
||||
|
||||
return EVP_MAC_CTX_set_params(hctx->ctx, params);
|
||||
}
|
||||
break;
|
||||
case MAC_TYPE_MAC:
|
||||
@@ -335,8 +436,32 @@ static int pkey_mac_ctrl_str(EVP_PKEY_CTX *ctx,
|
||||
const char *type, const char *value)
|
||||
{
|
||||
MAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(ctx);
|
||||
const EVP_MAC *mac = EVP_MAC_CTX_mac(hctx->ctx);
|
||||
OSSL_PARAM params[2];
|
||||
int ok = 0;
|
||||
|
||||
return EVP_MAC_ctrl_str(hctx->ctx, type, value);
|
||||
/*
|
||||
* Translation of some control names that are equivalent to a single
|
||||
* parameter name.
|
||||
*
|
||||
* "md" and "digest" are the same thing, we use the single "digest"
|
||||
*
|
||||
* "digestsize" was a setting control in siphash, but naming wise,
|
||||
* it's really the same as "size".
|
||||
*/
|
||||
if (strcmp(type, "md") == 0)
|
||||
type = OSSL_MAC_PARAM_DIGEST;
|
||||
else if (strcmp(type, "digestsize") == 0)
|
||||
type = OSSL_MAC_PARAM_SIZE;
|
||||
|
||||
if (!OSSL_PARAM_allocate_from_text(¶ms[0],
|
||||
EVP_MAC_CTX_settable_params(mac),
|
||||
type, value, strlen(value) + 1))
|
||||
return 0;
|
||||
params[1] = OSSL_PARAM_construct_end();
|
||||
ok = EVP_MAC_CTX_set_params(hctx->ctx, params);
|
||||
OPENSSL_free(params[0].data);
|
||||
return ok;
|
||||
}
|
||||
|
||||
const EVP_PKEY_METHOD cmac_pkey_meth = {
|
||||
|
||||
+425
-163
@@ -9,126 +9,483 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "internal/cryptlib.h"
|
||||
#include <openssl/objects.h>
|
||||
#include <openssl/evp.h>
|
||||
#include "internal/cryptlib.h"
|
||||
#include "internal/evp_int.h"
|
||||
#include "internal/provider.h"
|
||||
#include "evp_locl.h"
|
||||
|
||||
#define M_check_autoarg(ctx, arg, arglen, err) \
|
||||
if (ctx->pmeth->flags & EVP_PKEY_FLAG_AUTOARGLEN) { \
|
||||
size_t pksize = (size_t)EVP_PKEY_size(ctx->pkey); \
|
||||
\
|
||||
if (pksize == 0) { \
|
||||
EVPerr(err, EVP_R_INVALID_KEY); /*ckerr_ignore*/ \
|
||||
return 0; \
|
||||
} \
|
||||
if (!arg) { \
|
||||
*arglen = pksize; \
|
||||
return 1; \
|
||||
} \
|
||||
if (*arglen < pksize) { \
|
||||
EVPerr(err, EVP_R_BUFFER_TOO_SMALL); /*ckerr_ignore*/ \
|
||||
return 0; \
|
||||
} \
|
||||
static EVP_SIGNATURE *evp_signature_new(OSSL_PROVIDER *prov)
|
||||
{
|
||||
EVP_SIGNATURE *signature = OPENSSL_zalloc(sizeof(EVP_SIGNATURE));
|
||||
|
||||
signature->lock = CRYPTO_THREAD_lock_new();
|
||||
if (signature->lock == NULL) {
|
||||
OPENSSL_free(signature);
|
||||
return NULL;
|
||||
}
|
||||
signature->prov = prov;
|
||||
ossl_provider_up_ref(prov);
|
||||
signature->refcnt = 1;
|
||||
|
||||
return signature;
|
||||
}
|
||||
|
||||
static void *evp_signature_from_dispatch(int name_id,
|
||||
const OSSL_DISPATCH *fns,
|
||||
OSSL_PROVIDER *prov,
|
||||
void *vkeymgmt_data)
|
||||
{
|
||||
/*
|
||||
* Signature functions cannot work without a key, and key management
|
||||
* from the same provider to manage its keys. We therefore fetch
|
||||
* a key management method using the same algorithm and properties
|
||||
* and pass that down to evp_generic_fetch to be passed on to our
|
||||
* evp_signature_from_dispatch, which will attach the key management
|
||||
* method to the newly created key exchange method as long as the
|
||||
* provider matches.
|
||||
*/
|
||||
struct keymgmt_data_st *keymgmt_data = vkeymgmt_data;
|
||||
EVP_KEYMGMT *keymgmt =
|
||||
evp_keymgmt_fetch_by_number(keymgmt_data->ctx, name_id,
|
||||
keymgmt_data->properties);
|
||||
EVP_SIGNATURE *signature = NULL;
|
||||
int ctxfncnt = 0, signfncnt = 0, verifyfncnt = 0, verifyrecfncnt = 0;
|
||||
int gparamfncnt = 0, sparamfncnt = 0;
|
||||
|
||||
if (keymgmt == NULL || EVP_KEYMGMT_provider(keymgmt) != prov) {
|
||||
ERR_raise(ERR_LIB_EVP, EVP_R_NO_KEYMGMT_AVAILABLE);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if ((signature = evp_signature_new(prov)) == NULL) {
|
||||
ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
|
||||
signature->name_id = name_id;
|
||||
signature->keymgmt = keymgmt;
|
||||
keymgmt = NULL; /* avoid double free on failure below */
|
||||
|
||||
for (; fns->function_id != 0; fns++) {
|
||||
switch (fns->function_id) {
|
||||
case OSSL_FUNC_SIGNATURE_NEWCTX:
|
||||
if (signature->newctx != NULL)
|
||||
break;
|
||||
signature->newctx = OSSL_get_OP_signature_newctx(fns);
|
||||
ctxfncnt++;
|
||||
break;
|
||||
case OSSL_FUNC_SIGNATURE_SIGN_INIT:
|
||||
if (signature->sign_init != NULL)
|
||||
break;
|
||||
signature->sign_init = OSSL_get_OP_signature_sign_init(fns);
|
||||
signfncnt++;
|
||||
break;
|
||||
case OSSL_FUNC_SIGNATURE_SIGN:
|
||||
if (signature->sign != NULL)
|
||||
break;
|
||||
signature->sign = OSSL_get_OP_signature_sign(fns);
|
||||
signfncnt++;
|
||||
break;
|
||||
case OSSL_FUNC_SIGNATURE_VERIFY_INIT:
|
||||
if (signature->verify_init != NULL)
|
||||
break;
|
||||
signature->verify_init = OSSL_get_OP_signature_verify_init(fns);
|
||||
verifyfncnt++;
|
||||
break;
|
||||
case OSSL_FUNC_SIGNATURE_VERIFY:
|
||||
if (signature->verify != NULL)
|
||||
break;
|
||||
signature->verify = OSSL_get_OP_signature_verify(fns);
|
||||
verifyfncnt++;
|
||||
break;
|
||||
case OSSL_FUNC_SIGNATURE_VERIFY_RECOVER_INIT:
|
||||
if (signature->verify_recover_init != NULL)
|
||||
break;
|
||||
signature->verify_recover_init
|
||||
= OSSL_get_OP_signature_verify_recover_init(fns);
|
||||
verifyrecfncnt++;
|
||||
break;
|
||||
case OSSL_FUNC_SIGNATURE_VERIFY_RECOVER:
|
||||
if (signature->verify_recover != NULL)
|
||||
break;
|
||||
signature->verify_recover
|
||||
= OSSL_get_OP_signature_verify_recover(fns);
|
||||
verifyrecfncnt++;
|
||||
break;
|
||||
case OSSL_FUNC_SIGNATURE_FREECTX:
|
||||
if (signature->freectx != NULL)
|
||||
break;
|
||||
signature->freectx = OSSL_get_OP_signature_freectx(fns);
|
||||
ctxfncnt++;
|
||||
break;
|
||||
case OSSL_FUNC_SIGNATURE_DUPCTX:
|
||||
if (signature->dupctx != NULL)
|
||||
break;
|
||||
signature->dupctx = OSSL_get_OP_signature_dupctx(fns);
|
||||
break;
|
||||
case OSSL_FUNC_SIGNATURE_GET_CTX_PARAMS:
|
||||
if (signature->get_ctx_params != NULL)
|
||||
break;
|
||||
signature->get_ctx_params
|
||||
= OSSL_get_OP_signature_get_ctx_params(fns);
|
||||
gparamfncnt++;
|
||||
break;
|
||||
case OSSL_FUNC_SIGNATURE_GETTABLE_CTX_PARAMS:
|
||||
if (signature->gettable_ctx_params != NULL)
|
||||
break;
|
||||
signature->gettable_ctx_params
|
||||
= OSSL_get_OP_signature_gettable_ctx_params(fns);
|
||||
gparamfncnt++;
|
||||
break;
|
||||
case OSSL_FUNC_SIGNATURE_SET_CTX_PARAMS:
|
||||
if (signature->set_ctx_params != NULL)
|
||||
break;
|
||||
signature->set_ctx_params
|
||||
= OSSL_get_OP_signature_set_ctx_params(fns);
|
||||
sparamfncnt++;
|
||||
break;
|
||||
case OSSL_FUNC_SIGNATURE_SETTABLE_CTX_PARAMS:
|
||||
if (signature->settable_ctx_params != NULL)
|
||||
break;
|
||||
signature->settable_ctx_params
|
||||
= OSSL_get_OP_signature_settable_ctx_params(fns);
|
||||
sparamfncnt++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (ctxfncnt != 2
|
||||
|| (signfncnt != 2 && verifyfncnt != 2 && verifyrecfncnt != 2)
|
||||
|| (gparamfncnt != 0 && gparamfncnt != 2)
|
||||
|| (sparamfncnt != 0 && sparamfncnt != 2)) {
|
||||
/*
|
||||
* In order to be a consistent set of functions we must have at least
|
||||
* a set of context functions (newctx and freectx) as well as a pair of
|
||||
* "signature" functions: (sign_init, sign) or (verify_init verify) or
|
||||
* (verify_recover_init, verify_recover). set_ctx_params and
|
||||
* settable_ctx_params are optional, but if one of them is present then
|
||||
* the other one must also be present. The same applies to
|
||||
* get_ctx_params and gettable_ctx_params. The dupctx function is
|
||||
* optional.
|
||||
*/
|
||||
ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_PROVIDER_FUNCTIONS);
|
||||
goto err;
|
||||
}
|
||||
|
||||
return signature;
|
||||
err:
|
||||
EVP_SIGNATURE_free(signature);
|
||||
EVP_KEYMGMT_free(keymgmt);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void EVP_SIGNATURE_free(EVP_SIGNATURE *signature)
|
||||
{
|
||||
if (signature != NULL) {
|
||||
int i;
|
||||
|
||||
CRYPTO_DOWN_REF(&signature->refcnt, &i, signature->lock);
|
||||
if (i > 0)
|
||||
return;
|
||||
EVP_KEYMGMT_free(signature->keymgmt);
|
||||
ossl_provider_free(signature->prov);
|
||||
CRYPTO_THREAD_lock_free(signature->lock);
|
||||
OPENSSL_free(signature);
|
||||
}
|
||||
}
|
||||
|
||||
int EVP_SIGNATURE_up_ref(EVP_SIGNATURE *signature)
|
||||
{
|
||||
int ref = 0;
|
||||
|
||||
CRYPTO_UP_REF(&signature->refcnt, &ref, signature->lock);
|
||||
return 1;
|
||||
}
|
||||
|
||||
OSSL_PROVIDER *EVP_SIGNATURE_provider(const EVP_SIGNATURE *signature)
|
||||
{
|
||||
return signature->prov;
|
||||
}
|
||||
|
||||
EVP_SIGNATURE *EVP_SIGNATURE_fetch(OPENSSL_CTX *ctx, const char *algorithm,
|
||||
const char *properties)
|
||||
{
|
||||
struct keymgmt_data_st keymgmt_data;
|
||||
|
||||
/*
|
||||
* A signature operation cannot work without a key, so we need key
|
||||
* management from the same provider to manage its keys.
|
||||
*/
|
||||
keymgmt_data.ctx = ctx;
|
||||
keymgmt_data.properties = properties;
|
||||
return evp_generic_fetch(ctx, OSSL_OP_SIGNATURE, algorithm, properties,
|
||||
evp_signature_from_dispatch, &keymgmt_data,
|
||||
(int (*)(void *))EVP_SIGNATURE_up_ref,
|
||||
(void (*)(void *))EVP_SIGNATURE_free);
|
||||
}
|
||||
|
||||
static int evp_pkey_signature_init(EVP_PKEY_CTX *ctx, EVP_SIGNATURE *signature,
|
||||
int operation)
|
||||
{
|
||||
int ret = 0;
|
||||
void *provkey = NULL;
|
||||
|
||||
if (ctx == NULL) {
|
||||
EVPerr(0, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
|
||||
return -2;
|
||||
}
|
||||
|
||||
evp_pkey_ctx_free_old_ops(ctx);
|
||||
ctx->operation = operation;
|
||||
|
||||
if (ctx->engine != NULL)
|
||||
goto legacy;
|
||||
|
||||
if (signature != NULL) {
|
||||
if (!EVP_SIGNATURE_up_ref(signature))
|
||||
goto err;
|
||||
} else {
|
||||
int nid = ctx->pkey != NULL ? ctx->pkey->type : ctx->pmeth->pkey_id;
|
||||
|
||||
/*
|
||||
* TODO(3.0): Check for legacy handling. Remove this once all all
|
||||
* algorithms are moved to providers.
|
||||
*/
|
||||
if (ctx->pkey != NULL) {
|
||||
switch (ctx->pkey->type) {
|
||||
case NID_dsa:
|
||||
break;
|
||||
default:
|
||||
goto legacy;
|
||||
}
|
||||
signature = EVP_SIGNATURE_fetch(NULL, OBJ_nid2sn(nid), NULL);
|
||||
} else {
|
||||
goto legacy;
|
||||
}
|
||||
|
||||
if (signature == NULL) {
|
||||
EVPerr(0, EVP_R_INITIALIZATION_ERROR);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
ctx->op.sig.signature = signature;
|
||||
if (ctx->pkey != NULL) {
|
||||
provkey = evp_keymgmt_export_to_provider(ctx->pkey, signature->keymgmt);
|
||||
if (provkey == NULL) {
|
||||
EVPerr(0, EVP_R_INITIALIZATION_ERROR);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
ctx->op.sig.sigprovctx = signature->newctx(ossl_provider_ctx(signature->prov));
|
||||
if (ctx->op.sig.sigprovctx == NULL) {
|
||||
/* The provider key can stay in the cache */
|
||||
EVPerr(0, EVP_R_INITIALIZATION_ERROR);
|
||||
goto err;
|
||||
}
|
||||
|
||||
switch (operation) {
|
||||
case EVP_PKEY_OP_SIGN:
|
||||
if (signature->sign_init == NULL) {
|
||||
EVPerr(0, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
|
||||
ret = -2;
|
||||
goto err;
|
||||
}
|
||||
ret = signature->sign_init(ctx->op.sig.sigprovctx, provkey);
|
||||
break;
|
||||
case EVP_PKEY_OP_VERIFY:
|
||||
if (signature->verify_init == NULL) {
|
||||
EVPerr(0, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
|
||||
ret = -2;
|
||||
goto err;
|
||||
}
|
||||
ret = signature->verify_init(ctx->op.sig.sigprovctx, provkey);
|
||||
break;
|
||||
case EVP_PKEY_OP_VERIFYRECOVER:
|
||||
if (signature->verify_recover_init == NULL) {
|
||||
EVPerr(0, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
|
||||
ret = -2;
|
||||
goto err;
|
||||
}
|
||||
ret = signature->verify_recover_init(ctx->op.sig.sigprovctx, provkey);
|
||||
break;
|
||||
default:
|
||||
EVPerr(0, EVP_R_INITIALIZATION_ERROR);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (ret <= 0) {
|
||||
signature->freectx(ctx->op.sig.sigprovctx);
|
||||
ctx->op.sig.sigprovctx = NULL;
|
||||
goto err;
|
||||
}
|
||||
return 1;
|
||||
|
||||
legacy:
|
||||
if (ctx->pmeth == NULL
|
||||
|| (operation == EVP_PKEY_OP_SIGN && ctx->pmeth->sign == NULL)
|
||||
|| (operation == EVP_PKEY_OP_VERIFY && ctx->pmeth->verify == NULL)
|
||||
|| (operation == EVP_PKEY_OP_VERIFYRECOVER
|
||||
&& ctx->pmeth->verify_recover == NULL)) {
|
||||
EVPerr(0, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
|
||||
return -2;
|
||||
}
|
||||
|
||||
switch (operation) {
|
||||
case EVP_PKEY_OP_SIGN:
|
||||
if (ctx->pmeth->sign_init == NULL)
|
||||
return 1;
|
||||
ret = ctx->pmeth->sign_init(ctx);
|
||||
break;
|
||||
case EVP_PKEY_OP_VERIFY:
|
||||
if (ctx->pmeth->verify_init == NULL)
|
||||
return 1;
|
||||
ret = ctx->pmeth->verify_init(ctx);
|
||||
break;
|
||||
case EVP_PKEY_OP_VERIFYRECOVER:
|
||||
if (ctx->pmeth->verify_recover_init == NULL)
|
||||
return 1;
|
||||
ret = ctx->pmeth->verify_recover_init(ctx);
|
||||
break;
|
||||
default:
|
||||
EVPerr(0, EVP_R_INITIALIZATION_ERROR);
|
||||
goto err;
|
||||
}
|
||||
if (ret <= 0)
|
||||
goto err;
|
||||
return ret;
|
||||
|
||||
err:
|
||||
ctx->operation = EVP_PKEY_OP_UNDEFINED;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int EVP_PKEY_sign_init_ex(EVP_PKEY_CTX *ctx, EVP_SIGNATURE *signature)
|
||||
{
|
||||
return evp_pkey_signature_init(ctx, signature, EVP_PKEY_OP_SIGN);
|
||||
}
|
||||
|
||||
int EVP_PKEY_sign_init(EVP_PKEY_CTX *ctx)
|
||||
{
|
||||
int ret;
|
||||
if (!ctx || !ctx->pmeth || !ctx->pmeth->sign) {
|
||||
EVPerr(EVP_F_EVP_PKEY_SIGN_INIT,
|
||||
EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
|
||||
return -2;
|
||||
}
|
||||
ctx->operation = EVP_PKEY_OP_SIGN;
|
||||
if (!ctx->pmeth->sign_init)
|
||||
return 1;
|
||||
ret = ctx->pmeth->sign_init(ctx);
|
||||
if (ret <= 0)
|
||||
ctx->operation = EVP_PKEY_OP_UNDEFINED;
|
||||
return ret;
|
||||
return evp_pkey_signature_init(ctx, NULL, EVP_PKEY_OP_SIGN);
|
||||
}
|
||||
|
||||
int EVP_PKEY_sign(EVP_PKEY_CTX *ctx,
|
||||
unsigned char *sig, size_t *siglen,
|
||||
const unsigned char *tbs, size_t tbslen)
|
||||
{
|
||||
if (!ctx || !ctx->pmeth || !ctx->pmeth->sign) {
|
||||
EVPerr(EVP_F_EVP_PKEY_SIGN,
|
||||
EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
|
||||
int ret;
|
||||
|
||||
if (ctx == NULL) {
|
||||
EVPerr(0, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
|
||||
return -2;
|
||||
}
|
||||
|
||||
if (ctx->operation != EVP_PKEY_OP_SIGN) {
|
||||
EVPerr(EVP_F_EVP_PKEY_SIGN, EVP_R_OPERATON_NOT_INITIALIZED);
|
||||
EVPerr(0, EVP_R_OPERATON_NOT_INITIALIZED);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ctx->op.sig.sigprovctx == NULL)
|
||||
goto legacy;
|
||||
|
||||
ret = ctx->op.sig.signature->sign(ctx->op.sig.sigprovctx, sig, siglen,
|
||||
SIZE_MAX, tbs, tbslen);
|
||||
|
||||
return ret;
|
||||
legacy:
|
||||
|
||||
if (ctx->pmeth == NULL || ctx->pmeth->sign == NULL) {
|
||||
EVPerr(0, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
|
||||
return -2;
|
||||
}
|
||||
|
||||
M_check_autoarg(ctx, sig, siglen, EVP_F_EVP_PKEY_SIGN)
|
||||
return ctx->pmeth->sign(ctx, sig, siglen, tbs, tbslen);
|
||||
}
|
||||
|
||||
int EVP_PKEY_verify_init_ex(EVP_PKEY_CTX *ctx, EVP_SIGNATURE *signature)
|
||||
{
|
||||
return evp_pkey_signature_init(ctx, signature, EVP_PKEY_OP_VERIFY);
|
||||
}
|
||||
|
||||
int EVP_PKEY_verify_init(EVP_PKEY_CTX *ctx)
|
||||
{
|
||||
int ret;
|
||||
if (!ctx || !ctx->pmeth || !ctx->pmeth->verify) {
|
||||
EVPerr(EVP_F_EVP_PKEY_VERIFY_INIT,
|
||||
EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
|
||||
return -2;
|
||||
}
|
||||
ctx->operation = EVP_PKEY_OP_VERIFY;
|
||||
if (!ctx->pmeth->verify_init)
|
||||
return 1;
|
||||
ret = ctx->pmeth->verify_init(ctx);
|
||||
if (ret <= 0)
|
||||
ctx->operation = EVP_PKEY_OP_UNDEFINED;
|
||||
return ret;
|
||||
return evp_pkey_signature_init(ctx, NULL, EVP_PKEY_OP_VERIFY);
|
||||
}
|
||||
|
||||
int EVP_PKEY_verify(EVP_PKEY_CTX *ctx,
|
||||
const unsigned char *sig, size_t siglen,
|
||||
const unsigned char *tbs, size_t tbslen)
|
||||
{
|
||||
if (!ctx || !ctx->pmeth || !ctx->pmeth->verify) {
|
||||
EVPerr(EVP_F_EVP_PKEY_VERIFY,
|
||||
EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
|
||||
int ret;
|
||||
|
||||
if (ctx == NULL) {
|
||||
EVPerr(0, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
|
||||
return -2;
|
||||
}
|
||||
|
||||
if (ctx->operation != EVP_PKEY_OP_VERIFY) {
|
||||
EVPerr(EVP_F_EVP_PKEY_VERIFY, EVP_R_OPERATON_NOT_INITIALIZED);
|
||||
EVPerr(0, EVP_R_OPERATON_NOT_INITIALIZED);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ctx->op.sig.sigprovctx == NULL)
|
||||
goto legacy;
|
||||
|
||||
ret = ctx->op.sig.signature->verify(ctx->op.sig.sigprovctx, sig, siglen,
|
||||
tbs, tbslen);
|
||||
|
||||
return ret;
|
||||
legacy:
|
||||
if (ctx->pmeth == NULL || ctx->pmeth->verify == NULL) {
|
||||
EVPerr(0, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
|
||||
return -2;
|
||||
}
|
||||
|
||||
return ctx->pmeth->verify(ctx, sig, siglen, tbs, tbslen);
|
||||
}
|
||||
|
||||
int EVP_PKEY_verify_recover_init_ex(EVP_PKEY_CTX *ctx, EVP_SIGNATURE *signature)
|
||||
{
|
||||
return evp_pkey_signature_init(ctx, signature, EVP_PKEY_OP_VERIFYRECOVER);
|
||||
}
|
||||
|
||||
int EVP_PKEY_verify_recover_init(EVP_PKEY_CTX *ctx)
|
||||
{
|
||||
int ret;
|
||||
if (!ctx || !ctx->pmeth || !ctx->pmeth->verify_recover) {
|
||||
EVPerr(EVP_F_EVP_PKEY_VERIFY_RECOVER_INIT,
|
||||
EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
|
||||
return -2;
|
||||
}
|
||||
ctx->operation = EVP_PKEY_OP_VERIFYRECOVER;
|
||||
if (!ctx->pmeth->verify_recover_init)
|
||||
return 1;
|
||||
ret = ctx->pmeth->verify_recover_init(ctx);
|
||||
if (ret <= 0)
|
||||
ctx->operation = EVP_PKEY_OP_UNDEFINED;
|
||||
return ret;
|
||||
return evp_pkey_signature_init(ctx, NULL, EVP_PKEY_OP_VERIFYRECOVER);
|
||||
}
|
||||
|
||||
int EVP_PKEY_verify_recover(EVP_PKEY_CTX *ctx,
|
||||
unsigned char *rout, size_t *routlen,
|
||||
const unsigned char *sig, size_t siglen)
|
||||
{
|
||||
if (!ctx || !ctx->pmeth || !ctx->pmeth->verify_recover) {
|
||||
EVPerr(EVP_F_EVP_PKEY_VERIFY_RECOVER,
|
||||
EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
|
||||
int ret;
|
||||
|
||||
if (ctx == NULL) {
|
||||
EVPerr(0, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
|
||||
return -2;
|
||||
}
|
||||
|
||||
if (ctx->operation != EVP_PKEY_OP_VERIFYRECOVER) {
|
||||
EVPerr(EVP_F_EVP_PKEY_VERIFY_RECOVER, EVP_R_OPERATON_NOT_INITIALIZED);
|
||||
EVPerr(0, EVP_R_OPERATON_NOT_INITIALIZED);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ctx->op.sig.sigprovctx == NULL)
|
||||
goto legacy;
|
||||
|
||||
ret = ctx->op.sig.signature->verify_recover(ctx->op.sig.sigprovctx, rout,
|
||||
routlen,
|
||||
(rout == NULL ? 0 : *routlen),
|
||||
sig, siglen);
|
||||
return ret;
|
||||
legacy:
|
||||
if (ctx->pmeth == NULL || ctx->pmeth->verify_recover == NULL) {
|
||||
EVPerr(0, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
|
||||
return -2;
|
||||
}
|
||||
M_check_autoarg(ctx, rout, routlen, EVP_F_EVP_PKEY_VERIFY_RECOVER)
|
||||
return ctx->pmeth->verify_recover(ctx, rout, routlen, sig, siglen);
|
||||
}
|
||||
@@ -200,98 +557,3 @@ int EVP_PKEY_decrypt(EVP_PKEY_CTX *ctx,
|
||||
M_check_autoarg(ctx, out, outlen, EVP_F_EVP_PKEY_DECRYPT)
|
||||
return ctx->pmeth->decrypt(ctx, out, outlen, in, inlen);
|
||||
}
|
||||
|
||||
int EVP_PKEY_derive_init(EVP_PKEY_CTX *ctx)
|
||||
{
|
||||
int ret;
|
||||
if (!ctx || !ctx->pmeth || !ctx->pmeth->derive) {
|
||||
EVPerr(EVP_F_EVP_PKEY_DERIVE_INIT,
|
||||
EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
|
||||
return -2;
|
||||
}
|
||||
ctx->operation = EVP_PKEY_OP_DERIVE;
|
||||
if (!ctx->pmeth->derive_init)
|
||||
return 1;
|
||||
ret = ctx->pmeth->derive_init(ctx);
|
||||
if (ret <= 0)
|
||||
ctx->operation = EVP_PKEY_OP_UNDEFINED;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer)
|
||||
{
|
||||
int ret;
|
||||
if (!ctx || !ctx->pmeth
|
||||
|| !(ctx->pmeth->derive || ctx->pmeth->encrypt || ctx->pmeth->decrypt)
|
||||
|| !ctx->pmeth->ctrl) {
|
||||
EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER,
|
||||
EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
|
||||
return -2;
|
||||
}
|
||||
if (ctx->operation != EVP_PKEY_OP_DERIVE
|
||||
&& ctx->operation != EVP_PKEY_OP_ENCRYPT
|
||||
&& ctx->operation != EVP_PKEY_OP_DECRYPT) {
|
||||
EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER,
|
||||
EVP_R_OPERATON_NOT_INITIALIZED);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = ctx->pmeth->ctrl(ctx, EVP_PKEY_CTRL_PEER_KEY, 0, peer);
|
||||
|
||||
if (ret <= 0)
|
||||
return ret;
|
||||
|
||||
if (ret == 2)
|
||||
return 1;
|
||||
|
||||
if (!ctx->pkey) {
|
||||
EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER, EVP_R_NO_KEY_SET);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ctx->pkey->type != peer->type) {
|
||||
EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER, EVP_R_DIFFERENT_KEY_TYPES);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* For clarity. The error is if parameters in peer are
|
||||
* present (!missing) but don't match. EVP_PKEY_cmp_parameters may return
|
||||
* 1 (match), 0 (don't match) and -2 (comparison is not defined). -1
|
||||
* (different key types) is impossible here because it is checked earlier.
|
||||
* -2 is OK for us here, as well as 1, so we can check for 0 only.
|
||||
*/
|
||||
if (!EVP_PKEY_missing_parameters(peer) &&
|
||||
!EVP_PKEY_cmp_parameters(ctx->pkey, peer)) {
|
||||
EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER, EVP_R_DIFFERENT_PARAMETERS);
|
||||
return -1;
|
||||
}
|
||||
|
||||
EVP_PKEY_free(ctx->peerkey);
|
||||
ctx->peerkey = peer;
|
||||
|
||||
ret = ctx->pmeth->ctrl(ctx, EVP_PKEY_CTRL_PEER_KEY, 1, peer);
|
||||
|
||||
if (ret <= 0) {
|
||||
ctx->peerkey = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
EVP_PKEY_up_ref(peer);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int EVP_PKEY_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *pkeylen)
|
||||
{
|
||||
if (!ctx || !ctx->pmeth || !ctx->pmeth->derive) {
|
||||
EVPerr(EVP_F_EVP_PKEY_DERIVE,
|
||||
EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
|
||||
return -2;
|
||||
}
|
||||
if (ctx->operation != EVP_PKEY_OP_DERIVE) {
|
||||
EVPerr(EVP_F_EVP_PKEY_DERIVE, EVP_R_OPERATON_NOT_INITIALIZED);
|
||||
return -1;
|
||||
}
|
||||
M_check_autoarg(ctx, key, pkeylen, EVP_F_EVP_PKEY_DERIVE)
|
||||
return ctx->pmeth->derive(ctx, key, pkeylen);
|
||||
}
|
||||
+305
-16
@@ -1,3 +1,4 @@
|
||||
|
||||
/*
|
||||
* Copyright 2006-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
@@ -9,13 +10,17 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "internal/cryptlib.h"
|
||||
#include <openssl/engine.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/x509v3.h>
|
||||
#include <openssl/core_names.h>
|
||||
#include <openssl/dh.h>
|
||||
#include "internal/cryptlib.h"
|
||||
#include "internal/asn1_int.h"
|
||||
#include "internal/evp_int.h"
|
||||
#include "internal/numbers.h"
|
||||
#include "internal/provider.h"
|
||||
#include "evp_locl.h"
|
||||
|
||||
typedef int sk_cmp_fn_type(const char *const *a, const char *const *b);
|
||||
|
||||
@@ -103,8 +108,17 @@ const EVP_PKEY_METHOD *EVP_PKEY_meth_find(int type)
|
||||
static EVP_PKEY_CTX *int_ctx_new(EVP_PKEY *pkey, ENGINE *e, int id)
|
||||
{
|
||||
EVP_PKEY_CTX *ret;
|
||||
const EVP_PKEY_METHOD *pmeth;
|
||||
const EVP_PKEY_METHOD *pmeth = NULL;
|
||||
|
||||
/*
|
||||
* When using providers, the context is bound to the algo implementation
|
||||
* later.
|
||||
*/
|
||||
if (pkey == NULL && e == NULL && id == -1)
|
||||
goto common;
|
||||
|
||||
/* TODO(3.0) Legacy code should be removed when all is provider based */
|
||||
/* BEGIN legacy */
|
||||
if (id == -1) {
|
||||
if (pkey == NULL)
|
||||
return 0;
|
||||
@@ -140,7 +154,9 @@ static EVP_PKEY_CTX *int_ctx_new(EVP_PKEY *pkey, ENGINE *e, int id)
|
||||
EVPerr(EVP_F_INT_CTX_NEW, EVP_R_UNSUPPORTED_ALGORITHM);
|
||||
return NULL;
|
||||
}
|
||||
/* END legacy */
|
||||
|
||||
common:
|
||||
ret = OPENSSL_zalloc(sizeof(*ret));
|
||||
if (ret == NULL) {
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
@@ -156,7 +172,7 @@ static EVP_PKEY_CTX *int_ctx_new(EVP_PKEY *pkey, ENGINE *e, int id)
|
||||
if (pkey != NULL)
|
||||
EVP_PKEY_up_ref(pkey);
|
||||
|
||||
if (pmeth->init) {
|
||||
if (pmeth != NULL && pmeth->init != NULL) {
|
||||
if (pmeth->init(ret) <= 0) {
|
||||
ret->pmeth = NULL;
|
||||
EVP_PKEY_CTX_free(ret);
|
||||
@@ -167,6 +183,19 @@ static EVP_PKEY_CTX *int_ctx_new(EVP_PKEY *pkey, ENGINE *e, int id)
|
||||
return ret;
|
||||
}
|
||||
|
||||
void evp_pkey_ctx_free_old_ops(EVP_PKEY_CTX *ctx)
|
||||
{
|
||||
if (EVP_PKEY_CTX_IS_DERIVE_OP(ctx)) {
|
||||
if (ctx->op.kex.exchprovctx != NULL && ctx->op.kex.exchange != NULL)
|
||||
ctx->op.kex.exchange->freectx(ctx->op.kex.exchprovctx);
|
||||
EVP_KEYEXCH_free(ctx->op.kex.exchange);
|
||||
} else if (EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx)) {
|
||||
if (ctx->op.sig.sigprovctx != NULL && ctx->op.sig.signature != NULL)
|
||||
ctx->op.sig.signature->freectx(ctx->op.sig.sigprovctx);
|
||||
EVP_SIGNATURE_free(ctx->op.sig.signature);
|
||||
}
|
||||
}
|
||||
|
||||
EVP_PKEY_METHOD *EVP_PKEY_meth_new(int id, int flags)
|
||||
{
|
||||
EVP_PKEY_METHOD *pmeth;
|
||||
@@ -253,7 +282,12 @@ EVP_PKEY_CTX *EVP_PKEY_CTX_new_id(int id, ENGINE *e)
|
||||
EVP_PKEY_CTX *EVP_PKEY_CTX_dup(const EVP_PKEY_CTX *pctx)
|
||||
{
|
||||
EVP_PKEY_CTX *rctx;
|
||||
if (!pctx->pmeth || !pctx->pmeth->copy)
|
||||
|
||||
if (((pctx->pmeth == NULL) || (pctx->pmeth->copy == NULL))
|
||||
&& ((EVP_PKEY_CTX_IS_DERIVE_OP(pctx)
|
||||
&& pctx->op.kex.exchprovctx == NULL)
|
||||
|| (EVP_PKEY_CTX_IS_SIGNATURE_OP(pctx)
|
||||
&& pctx->op.sig.sigprovctx == NULL)))
|
||||
return NULL;
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
/* Make sure it's safe to copy a pkey context using an ENGINE */
|
||||
@@ -262,31 +296,68 @@ EVP_PKEY_CTX *EVP_PKEY_CTX_dup(const EVP_PKEY_CTX *pctx)
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
rctx = OPENSSL_malloc(sizeof(*rctx));
|
||||
rctx = OPENSSL_zalloc(sizeof(*rctx));
|
||||
if (rctx == NULL) {
|
||||
EVPerr(EVP_F_EVP_PKEY_CTX_DUP, ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (pctx->pkey != NULL)
|
||||
EVP_PKEY_up_ref(pctx->pkey);
|
||||
rctx->pkey = pctx->pkey;
|
||||
rctx->operation = pctx->operation;
|
||||
|
||||
if (EVP_PKEY_CTX_IS_DERIVE_OP(pctx)) {
|
||||
if (pctx->op.kex.exchange != NULL) {
|
||||
rctx->op.kex.exchange = pctx->op.kex.exchange;
|
||||
if (!EVP_KEYEXCH_up_ref(rctx->op.kex.exchange)) {
|
||||
OPENSSL_free(rctx);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
if (pctx->op.kex.exchprovctx != NULL) {
|
||||
if (!ossl_assert(pctx->op.kex.exchange != NULL))
|
||||
return NULL;
|
||||
rctx->op.kex.exchprovctx
|
||||
= pctx->op.kex.exchange->dupctx(pctx->op.kex.exchprovctx);
|
||||
if (rctx->op.kex.exchprovctx == NULL) {
|
||||
EVP_KEYEXCH_free(rctx->op.kex.exchange);
|
||||
OPENSSL_free(rctx);
|
||||
return NULL;
|
||||
}
|
||||
return rctx;
|
||||
}
|
||||
} else if (EVP_PKEY_CTX_IS_SIGNATURE_OP(pctx)) {
|
||||
if (pctx->op.sig.signature != NULL) {
|
||||
rctx->op.sig.signature = pctx->op.sig.signature;
|
||||
if (!EVP_SIGNATURE_up_ref(rctx->op.sig.signature)) {
|
||||
OPENSSL_free(rctx);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
if (pctx->op.sig.sigprovctx != NULL) {
|
||||
if (!ossl_assert(pctx->op.sig.signature != NULL))
|
||||
return NULL;
|
||||
rctx->op.sig.sigprovctx
|
||||
= pctx->op.sig.signature->dupctx(pctx->op.sig.sigprovctx);
|
||||
if (rctx->op.sig.sigprovctx == NULL) {
|
||||
EVP_SIGNATURE_free(rctx->op.sig.signature);
|
||||
OPENSSL_free(rctx);
|
||||
return NULL;
|
||||
}
|
||||
return rctx;
|
||||
}
|
||||
}
|
||||
|
||||
rctx->pmeth = pctx->pmeth;
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
rctx->engine = pctx->engine;
|
||||
#endif
|
||||
|
||||
if (pctx->pkey)
|
||||
EVP_PKEY_up_ref(pctx->pkey);
|
||||
|
||||
rctx->pkey = pctx->pkey;
|
||||
|
||||
if (pctx->peerkey)
|
||||
EVP_PKEY_up_ref(pctx->peerkey);
|
||||
|
||||
rctx->peerkey = pctx->peerkey;
|
||||
|
||||
rctx->data = NULL;
|
||||
rctx->app_data = NULL;
|
||||
rctx->operation = pctx->operation;
|
||||
|
||||
if (pctx->pmeth->copy(rctx, pctx) > 0)
|
||||
return rctx;
|
||||
|
||||
@@ -355,6 +426,9 @@ void EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx)
|
||||
return;
|
||||
if (ctx->pmeth && ctx->pmeth->cleanup)
|
||||
ctx->pmeth->cleanup(ctx);
|
||||
|
||||
evp_pkey_ctx_free_old_ops(ctx);
|
||||
|
||||
EVP_PKEY_free(ctx->pkey);
|
||||
EVP_PKEY_free(ctx->peerkey);
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
@@ -363,12 +437,188 @@ void EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx)
|
||||
OPENSSL_free(ctx);
|
||||
}
|
||||
|
||||
int EVP_PKEY_CTX_get_params(EVP_PKEY_CTX *ctx, OSSL_PARAM *params)
|
||||
{
|
||||
if (EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx)
|
||||
&& ctx->op.sig.sigprovctx != NULL
|
||||
&& ctx->op.sig.signature != NULL
|
||||
&& ctx->op.sig.signature->get_ctx_params != NULL)
|
||||
return ctx->op.sig.signature->get_ctx_params(ctx->op.sig.sigprovctx,
|
||||
params);
|
||||
return 0;
|
||||
}
|
||||
|
||||
const OSSL_PARAM *EVP_PKEY_CTX_gettable_params(EVP_PKEY_CTX *ctx)
|
||||
{
|
||||
if (EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx)
|
||||
&& ctx->op.sig.signature != NULL
|
||||
&& ctx->op.sig.signature->gettable_ctx_params != NULL)
|
||||
return ctx->op.sig.signature->gettable_ctx_params();
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int EVP_PKEY_CTX_set_params(EVP_PKEY_CTX *ctx, OSSL_PARAM *params)
|
||||
{
|
||||
if (EVP_PKEY_CTX_IS_DERIVE_OP(ctx)
|
||||
&& ctx->op.kex.exchprovctx != NULL
|
||||
&& ctx->op.kex.exchange != NULL
|
||||
&& ctx->op.kex.exchange->set_ctx_params != NULL)
|
||||
return ctx->op.kex.exchange->set_ctx_params(ctx->op.kex.exchprovctx,
|
||||
params);
|
||||
if (EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx)
|
||||
&& ctx->op.sig.sigprovctx != NULL
|
||||
&& ctx->op.sig.signature != NULL
|
||||
&& ctx->op.sig.signature->set_ctx_params != NULL)
|
||||
return ctx->op.sig.signature->set_ctx_params(ctx->op.sig.sigprovctx,
|
||||
params);
|
||||
return 0;
|
||||
}
|
||||
|
||||
const OSSL_PARAM *EVP_PKEY_CTX_settable_params(EVP_PKEY_CTX *ctx)
|
||||
{
|
||||
if (EVP_PKEY_CTX_IS_DERIVE_OP(ctx)
|
||||
&& ctx->op.kex.exchange != NULL
|
||||
&& ctx->op.kex.exchange->settable_ctx_params != NULL)
|
||||
return ctx->op.kex.exchange->settable_ctx_params();
|
||||
if (EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx)
|
||||
&& ctx->op.sig.signature != NULL
|
||||
&& ctx->op.sig.signature->settable_ctx_params != NULL)
|
||||
return ctx->op.sig.signature->settable_ctx_params();
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifndef OPENSSL_NO_DH
|
||||
int EVP_PKEY_CTX_set_dh_pad(EVP_PKEY_CTX *ctx, int pad)
|
||||
{
|
||||
OSSL_PARAM dh_pad_params[2];
|
||||
unsigned int upad = pad;
|
||||
|
||||
/* We use EVP_PKEY_CTX_ctrl return values */
|
||||
if (ctx == NULL || !EVP_PKEY_CTX_IS_DERIVE_OP(ctx)) {
|
||||
ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
|
||||
return -2;
|
||||
}
|
||||
|
||||
/* TODO(3.0): Remove this eventually when no more legacy */
|
||||
if (ctx->op.kex.exchprovctx == NULL)
|
||||
return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, EVP_PKEY_OP_DERIVE,
|
||||
EVP_PKEY_CTRL_DH_PAD, pad, NULL);
|
||||
|
||||
dh_pad_params[0] = OSSL_PARAM_construct_uint(OSSL_EXCHANGE_PARAM_PAD, &upad);
|
||||
dh_pad_params[1] = OSSL_PARAM_construct_end();
|
||||
|
||||
return EVP_PKEY_CTX_set_params(ctx, dh_pad_params);
|
||||
}
|
||||
#endif
|
||||
|
||||
int EVP_PKEY_CTX_get_signature_md(EVP_PKEY_CTX *ctx, const EVP_MD **md)
|
||||
{
|
||||
OSSL_PARAM sig_md_params[3], *p = sig_md_params;
|
||||
/* 80 should be big enough */
|
||||
char name[80] = "";
|
||||
const EVP_MD *tmp;
|
||||
|
||||
if (ctx == NULL || !EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx)) {
|
||||
ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
|
||||
/* Uses the same return values as EVP_PKEY_CTX_ctrl */
|
||||
return -2;
|
||||
}
|
||||
|
||||
/* TODO(3.0): Remove this eventually when no more legacy */
|
||||
if (ctx->op.sig.sigprovctx == NULL)
|
||||
return EVP_PKEY_CTX_ctrl(ctx, -1, EVP_PKEY_OP_TYPE_SIG,
|
||||
EVP_PKEY_CTRL_GET_MD, 0, (void *)(md));
|
||||
|
||||
*p++ = OSSL_PARAM_construct_utf8_string(OSSL_SIGNATURE_PARAM_DIGEST,
|
||||
name,
|
||||
sizeof(name));
|
||||
*p++ = OSSL_PARAM_construct_end();
|
||||
|
||||
if (!EVP_PKEY_CTX_get_params(ctx, sig_md_params))
|
||||
return 0;
|
||||
|
||||
tmp = EVP_get_digestbyname(name);
|
||||
if (tmp == NULL)
|
||||
return 0;
|
||||
|
||||
*md = tmp;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int EVP_PKEY_CTX_set_signature_md(EVP_PKEY_CTX *ctx, const EVP_MD *md)
|
||||
{
|
||||
OSSL_PARAM sig_md_params[3], *p = sig_md_params;
|
||||
size_t mdsize;
|
||||
const char *name;
|
||||
|
||||
if (ctx == NULL || !EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx)) {
|
||||
ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
|
||||
/* Uses the same return values as EVP_PKEY_CTX_ctrl */
|
||||
return -2;
|
||||
}
|
||||
|
||||
/* TODO(3.0): Remove this eventually when no more legacy */
|
||||
if (ctx->op.sig.sigprovctx == NULL)
|
||||
return EVP_PKEY_CTX_ctrl(ctx, -1, EVP_PKEY_OP_TYPE_SIG,
|
||||
EVP_PKEY_CTRL_MD, 0, (void *)(md));
|
||||
|
||||
if (md == NULL) {
|
||||
name = "";
|
||||
mdsize = 0;
|
||||
} else {
|
||||
mdsize = EVP_MD_size(md);
|
||||
name = EVP_MD_name(md);
|
||||
}
|
||||
|
||||
*p++ = OSSL_PARAM_construct_utf8_string(OSSL_SIGNATURE_PARAM_DIGEST,
|
||||
/*
|
||||
* Cast away the const. This is read
|
||||
* only so should be safe
|
||||
*/
|
||||
(char *)name,
|
||||
strlen(name) + 1);
|
||||
*p++ = OSSL_PARAM_construct_size_t(OSSL_SIGNATURE_PARAM_DIGEST_SIZE,
|
||||
&mdsize);
|
||||
*p++ = OSSL_PARAM_construct_end();
|
||||
|
||||
return EVP_PKEY_CTX_set_params(ctx, sig_md_params);
|
||||
}
|
||||
|
||||
static int legacy_ctrl_to_param(EVP_PKEY_CTX *ctx, int keytype, int optype,
|
||||
int cmd, int p1, void *p2)
|
||||
{
|
||||
switch (cmd) {
|
||||
#ifndef OPENSSL_NO_DH
|
||||
case EVP_PKEY_CTRL_DH_PAD:
|
||||
return EVP_PKEY_CTX_set_dh_pad(ctx, p1);
|
||||
#endif
|
||||
case EVP_PKEY_CTRL_MD:
|
||||
return EVP_PKEY_CTX_set_signature_md(ctx, p2);
|
||||
case EVP_PKEY_CTRL_GET_MD:
|
||||
return EVP_PKEY_CTX_get_signature_md(ctx, p2);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype,
|
||||
int cmd, int p1, void *p2)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!ctx || !ctx->pmeth || !ctx->pmeth->ctrl) {
|
||||
if (ctx == NULL) {
|
||||
EVPerr(EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_COMMAND_NOT_SUPPORTED);
|
||||
return -2;
|
||||
}
|
||||
|
||||
if ((EVP_PKEY_CTX_IS_DERIVE_OP(ctx) && ctx->op.kex.exchprovctx != NULL)
|
||||
|| (EVP_PKEY_CTX_IS_DERIVE_OP(ctx)
|
||||
&& ctx->op.sig.sigprovctx != NULL))
|
||||
return legacy_ctrl_to_param(ctx, keytype, optype, cmd, p1, p2);
|
||||
|
||||
if (ctx->pmeth == NULL || ctx->pmeth->ctrl == NULL) {
|
||||
EVPerr(EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_COMMAND_NOT_SUPPORTED);
|
||||
return -2;
|
||||
}
|
||||
@@ -404,9 +654,48 @@ int EVP_PKEY_CTX_ctrl_uint64(EVP_PKEY_CTX *ctx, int keytype, int optype,
|
||||
return EVP_PKEY_CTX_ctrl(ctx, keytype, optype, cmd, 0, &value);
|
||||
}
|
||||
|
||||
static int legacy_ctrl_str_to_param(EVP_PKEY_CTX *ctx, const char *name,
|
||||
const char *value)
|
||||
{
|
||||
#ifndef OPENSSL_NO_DH
|
||||
if (strcmp(name, "dh_pad") == 0) {
|
||||
int pad;
|
||||
|
||||
pad = atoi(value);
|
||||
return EVP_PKEY_CTX_set_dh_pad(ctx, pad);
|
||||
}
|
||||
#endif
|
||||
if (strcmp(name, "digest") == 0) {
|
||||
int ret;
|
||||
EVP_MD *md;
|
||||
|
||||
if (!EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx) || ctx->op.sig.signature == NULL)
|
||||
return 0;
|
||||
md = EVP_MD_fetch(ossl_provider_library_context(ctx->op.sig.signature->prov),
|
||||
value, NULL);
|
||||
if (md == NULL)
|
||||
return 0;
|
||||
ret = EVP_PKEY_CTX_set_signature_md(ctx, md);
|
||||
EVP_MD_meth_free(md);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int EVP_PKEY_CTX_ctrl_str(EVP_PKEY_CTX *ctx,
|
||||
const char *name, const char *value)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
EVPerr(EVP_F_EVP_PKEY_CTX_CTRL_STR, EVP_R_COMMAND_NOT_SUPPORTED);
|
||||
return -2;
|
||||
}
|
||||
|
||||
if ((EVP_PKEY_CTX_IS_DERIVE_OP(ctx) && ctx->op.kex.exchprovctx != NULL)
|
||||
|| (EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx)
|
||||
&& ctx->op.sig.sigprovctx != NULL))
|
||||
return legacy_ctrl_str_to_param(ctx, name, value);
|
||||
|
||||
if (!ctx || !ctx->pmeth || !ctx->pmeth->ctrl_str) {
|
||||
EVPerr(EVP_F_EVP_PKEY_CTX_CTRL_STR, EVP_R_COMMAND_NOT_SUPPORTED);
|
||||
return -2;
|
||||
|
||||
Reference in New Issue
Block a user