Latest update.

This commit is contained in:
2019-09-21 00:43:47 +09:00
parent 2e57f602ae
commit 62515c7d8d
1131 changed files with 47556 additions and 24957 deletions
+5 -4
View File
@@ -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
-27
View File
@@ -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
}
-32
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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)
{
+3 -5
View File
@@ -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,
+3 -6
View File
@@ -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
View File
@@ -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
View File
@@ -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)
+6 -1
View File
@@ -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,
+1 -2
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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)
+388
View File
@@ -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
View File
@@ -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;
}
+197
View File
@@ -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);
}
+288
View File
@@ -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();
}
+202
View File
@@ -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;
}
-30
View File
@@ -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
View File
@@ -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;
}
+214
View File
@@ -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);
}
-102
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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(&params[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
View File
@@ -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(&params[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
View File
@@ -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
View File
@@ -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;