Latest update.

This commit is contained in:
2020-01-17 19:45:12 +09:00
parent 016df9f433
commit 0f7abb4eb6
1100 changed files with 47785 additions and 16292 deletions
+16 -8
View File
@@ -1,23 +1,22 @@
LIBS=../../libcrypto
$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 \
m_sigver.c
m_sigver.c pmeth_lib.c signature.c p_lib.c pmeth_gn.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\
e_rc4.c e_aes.c names.c e_seed.c e_aria.c e_sm4.c \
e_xcbc_d.c e_rc2.c e_cast.c e_rc5.c \
m_null.c m_wp.c m_ripemd.c \
p_open.c p_seal.c p_sign.c p_verify.c p_lib.c p_enc.c p_dec.c \
e_xcbc_d.c e_rc2.c e_cast.c e_rc5.c m_null.c \
p_open.c p_seal.c p_sign.c p_verify.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 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 \
pkey_kdf.c e_old.c pmeth_fn.c\
e_aes_cbc_hmac_sha1.c e_aes_cbc_hmac_sha256.c e_rc4_hmac_md5.c \
e_chacha20_poly1305.c \
pkey_mac.c exchange.c \
legacy_sha.c legacy_md5_sha1.c
legacy_sha.c
IF[{- !$disabled{md2} -}]
SOURCE[../../libcrypto]=legacy_md2.c
@@ -26,11 +25,20 @@ IF[{- !$disabled{md4} -}]
SOURCE[../../libcrypto]=legacy_md4.c
ENDIF
IF[{- !$disabled{md5} -}]
SOURCE[../../libcrypto]=legacy_md5.c
SOURCE[../../libcrypto]=legacy_md5.c legacy_md5_sha1.c
ENDIF
IF[{- !$disabled{mdc2} -}]
SOURCE[../../libcrypto]=legacy_mdc2.c
ENDIF
IF[{- !$disabled{blake2} -}]
SOURCE[../../libcrypto]=legacy_blake2.c
ENDIF
IF[{- !$disabled{whirlpool} -}]
SOURCE[../../libcrypto]=legacy_wp.c
ENDIF
IF[{- !$disabled{rmd160} -}]
SOURCE[../../libcrypto]=legacy_ripemd.c
ENDIF
SOURCE[../../providers/libfips.a]=$COMMON
+18 -9
View File
@@ -165,7 +165,7 @@ int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl)
if (type->prov == NULL) {
#ifdef FIPS_MODE
/* We only do explict fetches inside the FIPS module */
/* We only do explicit fetches inside the FIPS module */
EVPerr(EVP_F_EVP_DIGESTINIT_EX, EVP_R_INITIALIZATION_ERROR);
return 0;
#else
@@ -303,7 +303,9 @@ int EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *data, size_t count)
return 0;
}
if (ctx->digest == NULL || ctx->digest->prov == NULL)
if (ctx->digest == NULL
|| ctx->digest->prov == NULL
|| (ctx->flags & EVP_MD_CTX_FLAG_NO_INIT) != 0)
goto legacy;
if (ctx->digest->dupdate == NULL) {
@@ -422,7 +424,8 @@ int EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in)
return 0;
}
if (in->digest->prov == NULL)
if (in->digest->prov == NULL
|| (in->flags & EVP_MD_CTX_FLAG_NO_INIT) != 0)
goto legacy;
if (in->digest->dupctx == NULL) {
@@ -730,12 +733,19 @@ static void set_legacy_nid(const char *name, void *vlegacy_nid)
{
int nid;
int *legacy_nid = vlegacy_nid;
/*
* We use lowest level function to get the associated method, because
* higher level functions such as EVP_get_digestbyname() have changed
* to look at providers too.
*/
const void *legacy_method = OBJ_NAME_get(name, OBJ_NAME_TYPE_MD_METH);
if (*legacy_nid == -1) /* We found a clash already */
return;
if ((nid = OBJ_sn2nid(name)) == NID_undef
&& (nid = OBJ_ln2nid(name)) == NID_undef)
if (legacy_method == NULL)
return;
nid = EVP_MD_nid(legacy_method);
if (*legacy_nid != NID_undef && *legacy_nid != nid) {
*legacy_nid = -1;
return;
@@ -746,7 +756,7 @@ static void set_legacy_nid(const char *name, void *vlegacy_nid)
static void *evp_md_from_dispatch(int name_id,
const OSSL_DISPATCH *fns,
OSSL_PROVIDER *prov, void *unused)
OSSL_PROVIDER *prov)
{
EVP_MD *md = NULL;
int fncnt = 0;
@@ -873,8 +883,7 @@ 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, NULL, evp_md_up_ref,
evp_md_free);
evp_md_from_dispatch, evp_md_up_ref, evp_md_free);
return md;
}
@@ -908,5 +917,5 @@ void EVP_MD_do_all_provided(OPENSSL_CTX *libctx,
{
evp_generic_do_all(libctx, OSSL_OP_DIGEST,
(void (*)(void *, void *))fn, arg,
evp_md_from_dispatch, NULL, evp_md_free);
evp_md_from_dispatch, evp_md_free);
}
+9 -5
View File
@@ -7,6 +7,12 @@
* https://www.openssl.org/source/license.html
*/
/*
* This file uses the low level AES functions (which are deprecated for
* non-internal use) in order to implement the EVP AES ciphers.
*/
#include "internal/deprecated.h"
#include <string.h>
#include <assert.h>
#include <openssl/opensslconf.h>
@@ -20,7 +26,7 @@
#include "internal/cryptlib.h"
#include "crypto/modes.h"
#include "crypto/siv.h"
#include "crypto/ciphermode_platform.h"
#include "crypto/aes_platform.h"
#include "evp_local.h"
typedef struct {
@@ -130,8 +136,6 @@ static void ctr64_inc(unsigned char *counter)
#if defined(AESNI_CAPABLE)
# if defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD64) || defined(_M_X64)
# define AES_gcm_encrypt aesni_gcm_encrypt
# define AES_gcm_decrypt aesni_gcm_decrypt
# 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 */
@@ -915,7 +919,7 @@ typedef struct {
} icv;
unsigned char k[32];
} kmac_param;
/* KMAC-AES paramater block - end */
/* KMAC-AES parameter block - end */
union {
unsigned long long g[2];
@@ -3228,7 +3232,7 @@ static int aes_xts_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
return 0;
/*
* Impose a limit of 2^20 blocks per data unit as specifed by
* Impose a limit of 2^20 blocks per data unit as specified by
* IEEE Std 1619-2018. The earlier and obsolete IEEE Std 1619-2007
* indicated that this was a SHOULD NOT rather than a MUST NOT.
* NIST SP 800-38E mandates the same limit.
+7
View File
@@ -7,6 +7,13 @@
* https://www.openssl.org/source/license.html
*/
/*
* AES low level APIs are deprecated for public use, but still ok for internal
* use where we're using them to implement the higher level EVP interface, as is
* the case here.
*/
#include "internal/deprecated.h"
#include <stdio.h>
#include <string.h>
#include <openssl/opensslconf.h>
+7
View File
@@ -7,6 +7,13 @@
* https://www.openssl.org/source/license.html
*/
/*
* AES low level APIs are deprecated for public use, but still ok for internal
* use where we're using them to implement the higher level EVP interface, as is
* the case here.
*/
#include "internal/deprecated.h"
#include <stdio.h>
#include <string.h>
#include <openssl/opensslconf.h>
+5 -2
View File
@@ -695,8 +695,6 @@ static int aria_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
if (!cctx->iv_set)
return -1;
if (!EVP_CIPHER_CTX_encrypting(ctx) && !cctx->tag_set)
return -1;
if (!out) {
if (!in) {
if (CRYPTO_ccm128_setiv(ccm, EVP_CIPHER_CTX_iv_noconst(ctx),
@@ -711,6 +709,11 @@ static int aria_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
CRYPTO_ccm128_aad(ccm, in, len);
return len;
}
/* The tag must be set before actually decrypting data */
if (!EVP_CIPHER_CTX_encrypting(ctx) && !cctx->tag_set)
return -1;
/* If not set length yet do it */
if (!cctx->len_set) {
if (CRYPTO_ccm128_setiv(ccm, EVP_CIPHER_CTX_iv_noconst(ctx),
+6
View File
@@ -7,6 +7,12 @@
* https://www.openssl.org/source/license.html
*/
/*
* BF low level APIs are deprecated for public use, but still ok for internal
* use.
*/
#include "internal/deprecated.h"
#include <stdio.h>
#include "internal/cryptlib.h"
#ifndef OPENSSL_NO_BF
+7 -1
View File
@@ -7,6 +7,12 @@
* https://www.openssl.org/source/license.html
*/
/*
* Camellia low level APIs are deprecated for public use, but still ok for
* internal use.
*/
#include "internal/deprecated.h"
#include <openssl/opensslconf.h>
#ifdef OPENSSL_NO_CAMELLIA
NON_EMPTY_TRANSLATION_UNIT
@@ -19,7 +25,7 @@ NON_EMPTY_TRANSLATION_UNIT
# include <openssl/camellia.h>
# include "crypto/evp.h"
# include "crypto/modes.h"
# include "crypto/ciphermode_platform.h"
# include "crypto/cmll_platform.h"
static int camellia_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
const unsigned char *iv, int enc);
+6
View File
@@ -7,6 +7,12 @@
* https://www.openssl.org/source/license.html
*/
/*
* CAST low level APIs are deprecated for public use, but still ok for
* internal use.
*/
#include "internal/deprecated.h"
#include <stdio.h>
#include "internal/cryptlib.h"
+1 -1
View File
@@ -8,7 +8,7 @@
*/
#include <openssl/opensslconf.h>
#if OPENSSL_API_0_9_8
#ifdef OPENSSL_NO_DEPRECATED_0_9_8
NON_EMPTY_TRANSLATION_UNIT
#else
+6
View File
@@ -7,6 +7,12 @@
* https://www.openssl.org/source/license.html
*/
/*
* RC2 low level APIs are deprecated for public use, but still ok for internal
* use.
*/
#include "internal/deprecated.h"
#include <stdio.h>
#include "internal/cryptlib.h"
+6
View File
@@ -7,6 +7,12 @@
* https://www.openssl.org/source/license.html
*/
/*
* RC4 low level APIs are deprecated for public use, but still ok for internal
* use.
*/
#include "internal/deprecated.h"
#include <stdio.h>
#include "internal/cryptlib.h"
+7
View File
@@ -7,6 +7,13 @@
* https://www.openssl.org/source/license.html
*/
/*
* RC4 low level APIs are deprecated for public use, but still ok for internal
* use.
*/
#include "internal/deprecated.h"
#include <internal/cryptlib.h>
#include <openssl/opensslconf.h>
#include <stdio.h>
+6
View File
@@ -7,6 +7,12 @@
* https://www.openssl.org/source/license.html
*/
/*
* RC5 low level APIs are deprecated for public use, but still ok for internal
* use.
*/
#include "internal/deprecated.h"
#include <stdio.h>
#include "internal/cryptlib.h"
+6
View File
@@ -7,6 +7,12 @@
* https://www.openssl.org/source/license.html
*/
/*
* SEED low level APIs are deprecated for public use, but still ok for
* internal use.
*/
#include "internal/deprecated.h"
#include <openssl/opensslconf.h>
#ifdef OPENSSL_NO_SEED
NON_EMPTY_TRANSLATION_UNIT
+141 -25
View File
@@ -171,6 +171,13 @@ int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
case NID_aes_256_gcm:
case NID_aes_192_gcm:
case NID_aes_128_gcm:
case NID_aes_256_siv:
case NID_aes_192_siv:
case NID_aes_128_siv:
case NID_aes_256_cbc_hmac_sha256:
case NID_aes_128_cbc_hmac_sha256:
case NID_aes_256_cbc_hmac_sha1:
case NID_aes_128_cbc_hmac_sha1:
case NID_id_aes256_wrap:
case NID_id_aes256_wrap_pad:
case NID_id_aes192_wrap:
@@ -280,6 +287,7 @@ int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
case NID_rc2_ofb64:
case NID_chacha20:
case NID_chacha20_poly1305:
case NID_rc4_hmac_md5:
break;
default:
goto legacy;
@@ -313,7 +321,7 @@ int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
if (cipher->prov == NULL) {
#ifdef FIPS_MODE
/* We only do explict fetches inside the FIPS module */
/* We only do explicit fetches inside the FIPS module */
EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_INITIALIZATION_ERROR);
return 0;
#else
@@ -1022,17 +1030,31 @@ 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;
OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END };
size_t len = keylen;
if (c->cipher->prov != NULL) {
int ok;
OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END };
size_t len = keylen;
params[0] = OSSL_PARAM_construct_size_t(OSSL_CIPHER_PARAM_KEYLEN, &len);
ok = evp_do_ciph_ctx_setparams(c->cipher, c->provctx, params);
if (EVP_CIPHER_CTX_key_length(c) == keylen)
return 1;
if (ok != EVP_CTRL_RET_UNSUPPORTED)
return ok;
/* Check the cipher actually understands this parameter */
if (OSSL_PARAM_locate_const(EVP_CIPHER_settable_ctx_params(c->cipher),
OSSL_CIPHER_PARAM_KEYLEN) == NULL)
return 0;
params[0] = OSSL_PARAM_construct_size_t(OSSL_CIPHER_PARAM_KEYLEN, &len);
ok = evp_do_ciph_ctx_setparams(c->cipher, c->provctx, params);
return ok > 0 ? 1 : 0;
}
/* TODO(3.0) legacy code follows */
/*
* Note there have never been any built-in ciphers that define this flag
* since it was first introduced.
*/
if (c->cipher->flags & EVP_CIPH_CUSTOM_KEY_LENGTH)
return EVP_CIPHER_CTX_ctrl(c, EVP_CTRL_SET_KEY_LENGTH, keylen, NULL);
if (EVP_CIPHER_CTX_key_length(c) == keylen)
@@ -1068,7 +1090,9 @@ int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr)
int set_params = 1;
size_t sz = arg;
unsigned int i;
OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END };
OSSL_PARAM params[4] = {
OSSL_PARAM_END, OSSL_PARAM_END, OSSL_PARAM_END, OSSL_PARAM_END
};
if (ctx == NULL || ctx->cipher == NULL) {
EVPerr(EVP_F_EVP_CIPHER_CTX_CTRL, EVP_R_NO_CIPHER_SET);
@@ -1111,10 +1135,22 @@ int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr)
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);
case EVP_CTRL_AEAD_SET_IV_FIXED:
params[0] = OSSL_PARAM_construct_octet_string(
OSSL_CIPHER_PARAM_AEAD_TLS1_IV_FIXED, ptr, sz);
break;
case EVP_CTRL_GCM_IV_GEN:
set_params = 0;
if (arg < 0)
sz = 0; /* special case that uses the iv length */
params[0] = OSSL_PARAM_construct_octet_string(
OSSL_CIPHER_PARAM_AEAD_TLS1_GET_IV_GEN, ptr, sz);
break;
case EVP_CTRL_GCM_SET_IV_INV:
if (arg < 0)
return 0;
params[0] = OSSL_PARAM_construct_octet_string(
OSSL_CIPHER_PARAM_AEAD_TLS1_SET_IV_INV, ptr, sz);
break;
case EVP_CTRL_GET_RC5_ROUNDS:
set_params = 0; /* Fall thru */
@@ -1124,19 +1160,20 @@ int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr)
i = (unsigned int)arg;
params[0] = OSSL_PARAM_construct_uint(OSSL_CIPHER_PARAM_ROUNDS, &i);
break;
case EVP_CTRL_SET_SPEED:
if (arg < 0)
return 0;
i = (unsigned int)arg;
params[0] = OSSL_PARAM_construct_uint(OSSL_CIPHER_PARAM_SPEED, &i);
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_SET_MAC_KEY:
params[0] =
OSSL_PARAM_construct_octet_string(OSSL_CIPHER_PARAM_AEAD_MAC_KEY,
ptr, sz);
break;
case EVP_CTRL_AEAD_TLS1_AAD:
/* This one does a set and a get - since it returns a padding size */
/* This one does a set and a get - since it returns a size */
params[0] =
OSSL_PARAM_construct_octet_string(OSSL_CIPHER_PARAM_AEAD_TLS1_AAD,
ptr, sz);
@@ -1156,6 +1193,76 @@ int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr)
params[0] = OSSL_PARAM_construct_size_t(OSSL_CIPHER_PARAM_RC2_KEYBITS, &sz);
break;
#endif /* OPENSSL_NO_RC2 */
#if !defined(OPENSSL_NO_MULTIBLOCK)
case EVP_CTRL_TLS1_1_MULTIBLOCK_MAX_BUFSIZE:
params[0] = OSSL_PARAM_construct_size_t(
OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_MAX_SEND_FRAGMENT, &sz);
ret = evp_do_ciph_ctx_setparams(ctx->cipher, ctx->provctx, params);
if (ret <= 0)
return 0;
params[0] = OSSL_PARAM_construct_size_t(
OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_MAX_BUFSIZE, &sz);
params[1] = OSSL_PARAM_construct_end();
ret = evp_do_ciph_ctx_getparams(ctx->cipher, ctx->provctx, params);
if (ret <= 0)
return 0;
return sz;
case EVP_CTRL_TLS1_1_MULTIBLOCK_AAD: {
EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM *p =
(EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM *)ptr;
if (arg < (int)sizeof(EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM))
return 0;
params[0] = OSSL_PARAM_construct_octet_string(
OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_AAD, (void*)p->inp, p->len);
params[1] = OSSL_PARAM_construct_uint(
OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_INTERLEAVE, &p->interleave);
ret = evp_do_ciph_ctx_setparams(ctx->cipher, ctx->provctx, params);
if (ret <= 0)
return ret;
/* Retrieve the return values changed by the set */
params[0] = OSSL_PARAM_construct_size_t(
OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_AAD_PACKLEN, &sz);
params[1] = OSSL_PARAM_construct_uint(
OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_INTERLEAVE, &p->interleave);
params[2] = OSSL_PARAM_construct_end();
ret = evp_do_ciph_ctx_getparams(ctx->cipher, ctx->provctx, params);
if (ret <= 0)
return 0;
return sz;
}
case EVP_CTRL_TLS1_1_MULTIBLOCK_ENCRYPT: {
EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM *p =
(EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM *)ptr;
params[0] = OSSL_PARAM_construct_octet_string(
OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_ENC, p->out, p->len);
params[1] = OSSL_PARAM_construct_octet_string(
OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_ENC_IN, (void*)p->inp,
p->len);
params[2] = OSSL_PARAM_construct_uint(
OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_INTERLEAVE, &p->interleave);
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_TLS1_MULTIBLOCK_ENC_LEN, &sz);
params[1] = OSSL_PARAM_construct_end();
ret = evp_do_ciph_ctx_getparams(ctx->cipher, ctx->provctx, params);
if (ret <= 0)
return 0;
return sz;
}
#endif /* OPENSSL_NO_MULTIBLOCK */
case EVP_CTRL_AEAD_SET_MAC_KEY:
if (arg < 0)
return -1;
params[0] = OSSL_PARAM_construct_octet_string(
OSSL_CIPHER_PARAM_AEAD_MAC_KEY, ptr, sz);
break;
}
if (set_params)
@@ -1335,12 +1442,18 @@ static void set_legacy_nid(const char *name, void *vlegacy_nid)
{
int nid;
int *legacy_nid = vlegacy_nid;
/*
* We use lowest level function to get the associated method, because
* higher level functions such as EVP_get_cipherbyname() have changed
* to look at providers too.
*/
const void *legacy_method = OBJ_NAME_get(name, OBJ_NAME_TYPE_CIPHER_METH);
if (*legacy_nid == -1) /* We found a clash already */
return;
if ((nid = OBJ_sn2nid(name)) == NID_undef
&& (nid = OBJ_ln2nid(name)) == NID_undef)
if (legacy_method == NULL)
return;
nid = EVP_CIPHER_nid(legacy_method);
if (*legacy_nid != NID_undef && *legacy_nid != nid) {
*legacy_nid = -1;
return;
@@ -1351,8 +1464,7 @@ static void set_legacy_nid(const char *name, void *vlegacy_nid)
static void *evp_cipher_from_dispatch(const int name_id,
const OSSL_DISPATCH *fns,
OSSL_PROVIDER *prov,
void *unused)
OSSL_PROVIDER *prov)
{
EVP_CIPHER *cipher = NULL;
int fnciphcnt = 0, fnctxcnt = 0;
@@ -1492,9 +1604,13 @@ 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, NULL, evp_cipher_up_ref,
evp_cipher_from_dispatch, evp_cipher_up_ref,
evp_cipher_free);
if (cipher != NULL && !evp_cipher_cache_constants(cipher)) {
EVP_CIPHER_free(cipher);
cipher = NULL;
}
return cipher;
}
@@ -1527,5 +1643,5 @@ void EVP_CIPHER_do_all_provided(OPENSSL_CTX *libctx,
{
evp_generic_do_all(libctx, OSSL_OP_CIPHER,
(void (*)(void *, void *))fn, arg,
evp_cipher_from_dispatch, NULL, evp_cipher_free);
evp_cipher_from_dispatch, evp_cipher_free);
}
+103 -178
View File
@@ -22,124 +22,60 @@
#define NAME_SEPARATOR ':'
static void default_method_store_free(void *vstore)
static void evp_method_store_free(void *vstore)
{
ossl_method_store_free(vstore);
}
static void *default_method_store_new(OPENSSL_CTX *ctx)
static void *evp_method_store_new(OPENSSL_CTX *ctx)
{
return ossl_method_store_new(ctx);
}
static const OPENSSL_CTX_METHOD default_method_store_method = {
default_method_store_new,
default_method_store_free,
static const OPENSSL_CTX_METHOD evp_method_store_method = {
evp_method_store_new,
evp_method_store_free,
};
/* Data to be passed through ossl_method_construct() */
struct method_data_st {
struct evp_method_data_st {
OPENSSL_CTX *libctx;
OSSL_METHOD_CONSTRUCT_METHOD *mcm;
int operation_id; /* For get_method_from_store() */
int name_id; /* For get_method_from_store() */
const char *names; /* For get_method_from_store() */
const char *propquery; /* For get_method_from_store() */
int operation_id; /* For get_evp_method_from_store() */
int name_id; /* For get_evp_method_from_store() */
const char *names; /* For get_evp_method_from_store() */
const char *propquery; /* For get_evp_method_from_store() */
void *(*method_from_dispatch)(int name_id, const OSSL_DISPATCH *,
OSSL_PROVIDER *, void *);
void *method_data;
OSSL_PROVIDER *);
int (*refcnt_up_method)(void *method);
void (*destruct_method)(void *method);
};
static int add_names_to_namemap(OSSL_NAMEMAP *namemap,
const char *names)
{
const char *p, *q;
size_t l;
int id = 0;
/* Check that we have a namemap and that there is at least one name */
if (namemap == NULL) {
ERR_raise(ERR_LIB_EVP, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
/*
* Check that no name is an empty string, and that all names have at
* most one numeric identity together.
*/
for (p = names; *p != '\0'; p = (q == NULL ? p + l : q + 1)) {
int this_id;
if ((q = strchr(p, NAME_SEPARATOR)) == NULL)
l = strlen(p); /* offset to \0 */
else
l = q - p; /* offset to the next separator */
this_id = ossl_namemap_name2num_n(namemap, p, l);
if (*p == '\0' || *p == NAME_SEPARATOR) {
ERR_raise(ERR_LIB_EVP, EVP_R_BAD_ALGORITHM_NAME);
return 0;
}
if (id == 0)
id = this_id;
else if (this_id != 0 && this_id != id) {
ERR_raise_data(ERR_LIB_EVP, EVP_R_CONFLICTING_ALGORITHM_NAME,
"\"%.*s\" has an existing different identity %d (from \"%s\")",
l, p, this_id, names);
return 0;
}
}
/* Now that we have checked, register all names */
for (p = names; *p != '\0'; p = (q == NULL ? p + l : q + 1)) {
int this_id;
if ((q = strchr(p, NAME_SEPARATOR)) == NULL)
l = strlen(p); /* offset to \0 */
else
l = q - p; /* offset to the next separator */
this_id = ossl_namemap_add_n(namemap, id, p, l);
if (id == 0)
id = this_id;
else if (this_id != id) {
ERR_raise_data(ERR_LIB_EVP, ERR_R_INTERNAL_ERROR,
"Got id %d when expecting %d", this_id, id);
return 0;
}
}
return id;
}
/*
* Generic routines to fetch / create EVP methods with ossl_method_construct()
*/
static void *alloc_tmp_method_store(OPENSSL_CTX *ctx)
static void *alloc_tmp_evp_method_store(OPENSSL_CTX *ctx)
{
return ossl_method_store_new(ctx);
}
static void dealloc_tmp_method_store(void *store)
static void dealloc_tmp_evp_method_store(void *store)
{
if (store != NULL)
ossl_method_store_free(store);
}
static OSSL_METHOD_STORE *get_default_method_store(OPENSSL_CTX *libctx)
static OSSL_METHOD_STORE *get_evp_method_store(OPENSSL_CTX *libctx)
{
return openssl_ctx_get_data(libctx, OPENSSL_CTX_DEFAULT_METHOD_STORE_INDEX,
&default_method_store_method);
return openssl_ctx_get_data(libctx, OPENSSL_CTX_EVP_METHOD_STORE_INDEX,
&evp_method_store_method);
}
/*
* To identity the method in the method store, we mix the name identity
* with the operation identity, with the assumption that we don't have
* more than 2^24 names or more than 2^8 operation types.
* To identity the method in the EVP method store, we mix the name identity
* with the operation identity, with the assumption that we don't have more
* than 2^24 names or more than 2^8 operation types.
*
* The resulting identity is a 32-bit integer, composed like this:
*
@@ -147,7 +83,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, int name_id)
static uint32_t evp_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))
@@ -155,18 +91,18 @@ static uint32_t method_id(unsigned int operation_id, int name_id)
return ((name_id << 8) & 0xFFFFFF00) | (operation_id & 0x000000FF);
}
static void *get_method_from_store(OPENSSL_CTX *libctx, void *store,
void *data)
static void *get_evp_method_from_store(OPENSSL_CTX *libctx, void *store,
void *data)
{
struct method_data_st *methdata = data;
struct evp_method_data_st *methdata = data;
void *method = NULL;
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.
* get_evp_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);
@@ -180,40 +116,35 @@ static void *get_method_from_store(OPENSSL_CTX *libctx, void *store,
}
if (name_id == 0
|| (meth_id = method_id(methdata->operation_id, name_id)) == 0)
|| (meth_id = evp_method_id(methdata->operation_id, name_id)) == 0)
return NULL;
if (store == NULL
&& (store = get_default_method_store(libctx)) == NULL)
&& (store = get_evp_method_store(libctx)) == NULL)
return NULL;
(void)ossl_method_store_fetch(store, meth_id, methdata->propquery,
&method);
if (method != NULL
&& !methdata->refcnt_up_method(method)) {
method = NULL;
}
if (!ossl_method_store_fetch(store, meth_id, methdata->propquery,
&method))
return NULL;
return method;
}
static int put_method_in_store(OPENSSL_CTX *libctx, void *store,
void *method, const OSSL_PROVIDER *prov,
int operation_id, const char *names,
const char *propdef, void *data)
static int put_evp_method_in_store(OPENSSL_CTX *libctx, void *store,
void *method, const OSSL_PROVIDER *prov,
int operation_id, const char *names,
const char *propdef, void *data)
{
struct method_data_st *methdata = data;
struct evp_method_data_st *methdata = data;
OSSL_NAMEMAP *namemap;
int name_id;
uint32_t meth_id;
size_t l = 0;
/*
* put_method_in_store() is only called with a method that was
* successfully created by construct_method() below, which means
* that all the names should already be stored in the namemap with
* the same numeric identity, so just use the first to get that
* identity.
* put_evp_method_in_store() is only called with an EVP method that was
* successfully created by construct_method() below, which means that
* all the names should already be stored in the namemap with the same
* numeric identity, so just use the first to get that identity.
*/
if (names != NULL) {
const char *q = strchr(names, NAME_SEPARATOR);
@@ -223,11 +154,11 @@ static int put_method_in_store(OPENSSL_CTX *libctx, void *store,
if ((namemap = ossl_namemap_stored(libctx)) == NULL
|| (name_id = ossl_namemap_name2num_n(namemap, names, l)) == 0
|| (meth_id = method_id(operation_id, name_id)) == 0)
|| (meth_id = evp_method_id(operation_id, name_id)) == 0)
return 0;
if (store == NULL
&& (store = get_default_method_store(libctx)) == NULL)
&& (store = get_evp_method_store(libctx)) == NULL)
return 0;
return ossl_method_store_add(store, prov, meth_id, propdef, method,
@@ -239,45 +170,46 @@ static int put_method_in_store(OPENSSL_CTX *libctx, void *store,
* 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 *names, const OSSL_DISPATCH *fns,
OSSL_PROVIDER *prov, void *data)
static void *construct_evp_method(const OSSL_ALGORITHM *algodef,
OSSL_PROVIDER *prov, void *data)
{
/*
* This function is only called if get_method_from_store() returned
* This function is only called if get_evp_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.
* know that ossl_namemap_add_name() will return its corresponding
* number.
*/
struct method_data_st *methdata = data;
struct evp_method_data_st *methdata = data;
OPENSSL_CTX *libctx = ossl_provider_library_context(prov);
OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx);
int name_id = add_names_to_namemap(namemap, names);
const char *names = algodef->algorithm_names;
int name_id = ossl_namemap_add_names(namemap, 0, names, NAME_SEPARATOR);
if (name_id == 0)
return NULL;
return methdata->method_from_dispatch(name_id, fns, prov,
methdata->method_data);
return methdata->method_from_dispatch(name_id, algodef->implementation,
prov);
}
static void destruct_method(void *method, void *data)
static void destruct_evp_method(void *method, void *data)
{
struct method_data_st *methdata = data;
struct evp_method_data_st *methdata = data;
methdata->destruct_method(method);
}
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 *))
static void *
inner_evp_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),
int (*up_ref_method)(void *),
void (*free_method)(void *))
{
OSSL_METHOD_STORE *store = get_default_method_store(libctx);
OSSL_METHOD_STORE *store = get_evp_method_store(libctx);
OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx);
uint32_t meth_id = 0;
void *method = NULL;
@@ -304,26 +236,26 @@ static void *inner_generic_fetch(OPENSSL_CTX *libctx, int operation_id,
name_id = ossl_namemap_name2num(namemap, name);
/*
* If we have a name id, calculate a method id with method_id().
* If we have a name id, calculate a method id with evp_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.
* evp_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 (name_id != 0 && (meth_id = method_id(operation_id, name_id)) == 0)
if (name_id != 0 && (meth_id = evp_method_id(operation_id, name_id)) == 0)
return NULL;
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,
get_method_from_store,
put_method_in_store,
construct_method,
destruct_method
alloc_tmp_evp_method_store,
dealloc_tmp_evp_method_store,
get_evp_method_from_store,
put_evp_method_in_store,
construct_evp_method,
destruct_evp_method
};
struct method_data_st mcmdata;
struct evp_method_data_st mcmdata;
mcmdata.mcm = &mcm;
mcmdata.libctx = libctx;
@@ -332,26 +264,23 @@ static void *inner_generic_fetch(OPENSSL_CTX *libctx, int operation_id,
mcmdata.names = 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;
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 name_id and methodid, since those have
* already been calculated in get_method_from_store() and
* put_method_in_store() above.
* there is a correct name_id and meth_id, since those have
* already been calculated in get_evp_method_from_store() and
* put_evp_method_in_store() above.
*/
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);
meth_id = evp_method_id(operation_id, name_id);
ossl_method_store_cache_set(store, meth_id, properties, method,
up_ref_method, free_method);
}
} else {
up_ref_method(method);
}
return method;
@@ -361,16 +290,13 @@ 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,
OSSL_PROVIDER *prov),
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);
return inner_evp_generic_fetch(libctx,
operation_id, 0, name, properties,
new_method, up_ref_method, free_method);
}
/*
@@ -384,21 +310,18 @@ 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,
OSSL_PROVIDER *prov),
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);
return inner_evp_generic_fetch(libctx,
operation_id, name_id, NULL, properties,
new_method, 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);
OSSL_METHOD_STORE *store = get_evp_method_store(libctx);
if (store != NULL)
return ossl_method_store_set_global_properties(store, propq);
@@ -410,8 +333,7 @@ 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 *method_data;
OSSL_PROVIDER *prov);
void (*free_method)(void *);
};
@@ -421,12 +343,12 @@ static void do_one(OSSL_PROVIDER *provider, const OSSL_ALGORITHM *algo,
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 = add_names_to_namemap(namemap, algo->algorithm_names);
int name_id = ossl_namemap_add_names(namemap, 0, algo->algorithm_names,
NAME_SEPARATOR);
void *method = NULL;
if (name_id != 0)
method = data->new_method(name_id, algo->implementation, provider,
data->method_data);
method = data->new_method(name_id, algo->implementation, provider);
if (method != NULL) {
data->user_fn(method, data->user_arg);
@@ -439,15 +361,12 @@ void evp_generic_do_all(OPENSSL_CTX *libctx, int operation_id,
void *user_arg,
void *(*new_method)(int name_id,
const OSSL_DISPATCH *fns,
OSSL_PROVIDER *prov,
void *method_data),
void *method_data,
OSSL_PROVIDER *prov),
void (*free_method)(void *))
{
struct do_all_data_st data;
data.new_method = new_method;
data.method_data = method_data;
data.free_method = free_method;
data.user_fn = user_fn;
data.user_arg = user_arg;
@@ -462,11 +381,17 @@ const char *evp_first_name(OSSL_PROVIDER *prov, int name_id)
return ossl_namemap_num2name(namemap, name_id, 0);
}
int evp_is_a(OSSL_PROVIDER *prov, int number, const char *name)
int evp_is_a(OSSL_PROVIDER *prov, int number,
const char *legacy_name, const char *name)
{
/*
* For a |prov| that is NULL, the library context will be NULL
*/
OPENSSL_CTX *libctx = ossl_provider_library_context(prov);
OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx);
if (prov == NULL)
number = ossl_namemap_name2num(namemap, legacy_name);
return ossl_namemap_name2num(namemap, name) == number;
}
+37 -50
View File
@@ -272,16 +272,38 @@ int EVP_CIPHER_type(const EVP_CIPHER *ctx)
}
}
int EVP_CIPHER_block_size(const EVP_CIPHER *cipher)
int evp_cipher_cache_constants(EVP_CIPHER *cipher)
{
int ok;
size_t v = cipher->block_size;
OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END };
size_t ivlen = 0;
size_t blksz = 0;
size_t keylen = 0;
unsigned int mode = 0;
unsigned long flags = 0;
OSSL_PARAM params[6];
params[0] = OSSL_PARAM_construct_size_t(OSSL_CIPHER_PARAM_BLOCK_SIZE, &v);
params[0] = OSSL_PARAM_construct_size_t(OSSL_CIPHER_PARAM_BLOCK_SIZE, &blksz);
params[1] = OSSL_PARAM_construct_size_t(OSSL_CIPHER_PARAM_IVLEN, &ivlen);
params[2] = OSSL_PARAM_construct_size_t(OSSL_CIPHER_PARAM_KEYLEN, &keylen);
params[3] = OSSL_PARAM_construct_uint(OSSL_CIPHER_PARAM_MODE, &mode);
params[4] = OSSL_PARAM_construct_ulong(OSSL_CIPHER_PARAM_FLAGS, &flags);
params[5] = OSSL_PARAM_construct_end();
ok = evp_do_ciph_getparams(cipher, params);
if (ok) {
/* Provided implementations may have a custom cipher_cipher */
if (cipher->prov != NULL && cipher->ccipher != NULL)
flags |= EVP_CIPH_FLAG_CUSTOM_CIPHER;
cipher->block_size = blksz;
cipher->iv_len = ivlen;
cipher->key_len = keylen;
cipher->flags = flags | mode;
}
return ok;
}
return ok != 0 ? (int)v : EVP_CTRL_RET_UNSUPPORTED;
int EVP_CIPHER_block_size(const EVP_CIPHER *cipher)
{
return cipher->block_size;
}
int EVP_CIPHER_CTX_block_size(const EVP_CIPHER_CTX *ctx)
@@ -340,18 +362,7 @@ 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;
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);
/* Provided implementations may have a custom cipher_cipher */
if (cipher->prov != NULL && cipher->ccipher != NULL)
v |= EVP_CIPH_FLAG_CUSTOM_CIPHER;
return ok != 0 ? v : 0;
return cipher->flags;
}
void *EVP_CIPHER_CTX_get_app_data(const EVP_CIPHER_CTX *ctx)
@@ -381,14 +392,7 @@ void *EVP_CIPHER_CTX_set_cipher_data(EVP_CIPHER_CTX *ctx, void *cipher_data)
int EVP_CIPHER_iv_length(const EVP_CIPHER *cipher)
{
int ok;
size_t v = cipher->iv_len;
OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END };
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;
return cipher->iv_len;
}
int EVP_CIPHER_CTX_iv_length(const EVP_CIPHER_CTX *ctx)
@@ -501,14 +505,7 @@ int EVP_CIPHER_CTX_set_num(EVP_CIPHER_CTX *ctx, int num)
int EVP_CIPHER_key_length(const EVP_CIPHER *cipher)
{
int ok;
size_t v = cipher->key_len;
OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END };
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;
return cipher->key_len;
}
int EVP_CIPHER_CTX_key_length(const EVP_CIPHER_CTX *ctx)
@@ -535,14 +532,9 @@ int EVP_CIPHER_CTX_nid(const EVP_CIPHER_CTX *ctx)
int EVP_CIPHER_is_a(const EVP_CIPHER *cipher, const char *name)
{
#ifndef FIPS_MODE
if (cipher->prov == NULL) {
int nid = EVP_CIPHER_nid(cipher);
return nid == OBJ_sn2nid(name) || nid == OBJ_ln2nid(name);
}
#endif
return evp_is_a(cipher->prov, cipher->name_id, name);
if (cipher->prov != NULL)
return evp_is_a(cipher->prov, cipher->name_id, NULL, name);
return evp_is_a(NULL, 0, EVP_CIPHER_name(cipher), name);
}
int EVP_CIPHER_number(const EVP_CIPHER *cipher)
@@ -576,19 +568,14 @@ const OSSL_PROVIDER *EVP_CIPHER_provider(const EVP_CIPHER *cipher)
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;
return EVP_CIPHER_flags(cipher) & EVP_CIPH_MODE;
}
int EVP_MD_is_a(const EVP_MD *md, const char *name)
{
return evp_is_a(md->prov, md->name_id, name);
if (md->prov != NULL)
return evp_is_a(md->prov, md->name_id, NULL, name);
return evp_is_a(NULL, 0, EVP_MD_name(md), name);
}
int EVP_MD_number(const EVP_MD *md)
+31 -14
View File
@@ -80,6 +80,8 @@ struct evp_keymgmt_st {
OSSL_OP_keymgmt_exportdomparams_fn *exportdomparams;
OSSL_OP_keymgmt_importdomparam_types_fn *importdomparam_types;
OSSL_OP_keymgmt_exportdomparam_types_fn *exportdomparam_types;
OSSL_OP_keymgmt_get_domparam_params_fn *get_domparam_params;
OSSL_OP_keymgmt_gettable_domparam_params_fn *gettable_domparam_params;
/* Key routines */
OSSL_OP_keymgmt_importkey_fn *importkey;
@@ -89,6 +91,10 @@ struct evp_keymgmt_st {
OSSL_OP_keymgmt_exportkey_fn *exportkey;
OSSL_OP_keymgmt_importkey_types_fn *importkey_types;
OSSL_OP_keymgmt_exportkey_types_fn *exportkey_types;
OSSL_OP_keymgmt_get_key_params_fn *get_key_params;
OSSL_OP_keymgmt_gettable_key_params_fn *gettable_key_params;
OSSL_OP_keymgmt_query_operation_name_fn *query_operation_name;
} /* EVP_KEYMGMT */ ;
struct keymgmt_data_st {
@@ -102,8 +108,6 @@ struct evp_keyexch_st {
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;
@@ -120,8 +124,6 @@ struct evp_signature_st {
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;
@@ -147,6 +149,25 @@ struct evp_signature_st {
OSSL_OP_signature_settable_ctx_md_params_fn *settable_ctx_md_params;
} /* EVP_SIGNATURE */;
struct evp_asym_cipher_st {
int name_id;
OSSL_PROVIDER *prov;
CRYPTO_REF_COUNT refcnt;
CRYPTO_RWLOCK *lock;
OSSL_OP_asym_cipher_newctx_fn *newctx;
OSSL_OP_asym_cipher_encrypt_init_fn *encrypt_init;
OSSL_OP_asym_cipher_encrypt_fn *encrypt;
OSSL_OP_asym_cipher_decrypt_init_fn *decrypt_init;
OSSL_OP_asym_cipher_decrypt_fn *decrypt;
OSSL_OP_asym_cipher_freectx_fn *freectx;
OSSL_OP_asym_cipher_dupctx_fn *dupctx;
OSSL_OP_asym_cipher_get_ctx_params_fn *get_ctx_params;
OSSL_OP_asym_cipher_gettable_ctx_params_fn *gettable_ctx_params;
OSSL_OP_asym_cipher_set_ctx_params_fn *set_ctx_params;
OSSL_OP_asym_cipher_settable_ctx_params_fn *settable_ctx_params;
} /* EVP_ASYM_CIPHER */;
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,
@@ -180,18 +201,14 @@ void *evp_generic_fetch(OPENSSL_CTX *ctx, 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,
OSSL_PROVIDER *prov),
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,
OSSL_PROVIDER *prov),
int (*up_ref_method)(void *),
void (*free_method)(void *));
void evp_generic_do_all(OPENSSL_CTX *libctx, int operation_id,
@@ -199,9 +216,7 @@ void evp_generic_do_all(OPENSSL_CTX *libctx, int operation_id,
void *user_arg,
void *(*new_method)(int name_id,
const OSSL_DISPATCH *fns,
OSSL_PROVIDER *prov,
void *method_data),
void *method_data,
OSSL_PROVIDER *prov),
void (*free_method)(void *));
/* Internal fetchers for method types that are to be combined with others */
@@ -260,7 +275,9 @@ 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);
int evp_is_a(OSSL_PROVIDER *prov, int number,
const char *legacy_name, const char *name);
void evp_names_do_all(OSSL_PROVIDER *prov, int number,
void (*fn)(const char *name, void *data),
void *data);
int evp_cipher_cache_constants(EVP_CIPHER *cipher);
+67 -86
View File
@@ -20,8 +20,14 @@ static EVP_KEYEXCH *evp_keyexch_new(OSSL_PROVIDER *prov)
{
EVP_KEYEXCH *exchange = OPENSSL_zalloc(sizeof(EVP_KEYEXCH));
if (exchange == NULL) {
ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE);
return NULL;
}
exchange->lock = CRYPTO_THREAD_lock_new();
if (exchange->lock == NULL) {
ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE);
OPENSSL_free(exchange);
return NULL;
}
@@ -34,38 +40,17 @@ static EVP_KEYEXCH *evp_keyexch_new(OSSL_PROVIDER *prov)
static void *evp_keyexch_from_dispatch(int name_id,
const OSSL_DISPATCH *fns,
OSSL_PROVIDER *prov,
void *vkeymgmt_data)
OSSL_PROVIDER *prov)
{
/*
* 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) {
@@ -135,7 +120,6 @@ static void *evp_keyexch_from_dispatch(int name_id,
err:
EVP_KEYEXCH_free(exchange);
EVP_KEYMGMT_free(keymgmt);
return NULL;
}
@@ -147,7 +131,6 @@ void EVP_KEYEXCH_free(EVP_KEYEXCH *exchange)
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);
@@ -170,71 +153,81 @@ OSSL_PROVIDER *EVP_KEYEXCH_provider(const EVP_KEYEXCH *exchange)
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;
return evp_generic_fetch(ctx, OSSL_OP_KEYEXCH, algorithm, properties,
evp_keyexch_from_dispatch,
(int (*)(void *))EVP_KEYEXCH_up_ref,
(void (*)(void *))EVP_KEYEXCH_free);
}
int EVP_PKEY_derive_init_ex(EVP_PKEY_CTX *ctx, EVP_KEYEXCH *exchange)
int EVP_PKEY_derive_init(EVP_PKEY_CTX *ctx)
{
int ret;
void *provkey = NULL;
EVP_KEYEXCH *exchange = 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 = EVP_PKEY_OP_DERIVE;
if (ctx->engine != NULL)
if (ctx->engine != NULL || ctx->keytype == 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;
if (ctx->keymgmt == NULL)
ctx->keymgmt =
EVP_KEYMGMT_fetch(ctx->libctx, ctx->keytype, ctx->propquery);
if (ctx->keymgmt != NULL) {
const char *supported_exch = NULL;
if (ctx->keymgmt->query_operation_name != NULL)
supported_exch =
ctx->keymgmt->query_operation_name(OSSL_OP_KEYEXCH);
/*
* TODO(3.0): Check for legacy handling. Remove this once all all
* algorithms are moved to providers.
* If we didn't get a supported exch, assume there is one with the
* same name as the key type.
*/
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 (supported_exch == NULL)
supported_exch = ctx->keytype;
if (exchange == NULL) {
EVPerr(EVP_F_EVP_PKEY_DERIVE_INIT_EX, EVP_R_INITIALIZATION_ERROR);
goto err;
}
/*
* Because we cleared out old ops, we shouldn't need to worry about
* checking if exchange is already there.
*/
exchange =
EVP_KEYEXCH_fetch(ctx->libctx, supported_exch, ctx->propquery);
}
if (ctx->keymgmt == NULL
|| exchange == NULL
|| (EVP_KEYMGMT_provider(ctx->keymgmt)
!= EVP_KEYEXCH_provider(exchange))) {
/*
* We don't have the full support we need with provided methods,
* let's go see if legacy does. Also, we don't need to free
* ctx->keymgmt here, as it's not necessarily tied to this
* operation. It will be freed by EVP_PKEY_CTX_free().
*/
EVP_KEYEXCH_free(exchange);
goto legacy;
}
ctx->op.kex.exchange = exchange;
if (ctx->pkey != NULL) {
provkey =
evp_keymgmt_export_to_provider(ctx->pkey, exchange->keymgmt, 0);
if (provkey == NULL) {
EVPerr(EVP_F_EVP_PKEY_DERIVE_INIT_EX, EVP_R_INITIALIZATION_ERROR);
goto err;
}
provkey = evp_keymgmt_export_to_provider(ctx->pkey, ctx->keymgmt, 0);
/* If export failed, legacy may be able to pick it up */
if (provkey == NULL)
goto legacy;
}
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);
EVPerr(0, EVP_R_INITIALIZATION_ERROR);
goto err;
}
ret = exchange->init(ctx->op.kex.exchprovctx, provkey);
@@ -245,9 +238,8 @@ int EVP_PKEY_derive_init_ex(EVP_PKEY_CTX *ctx, EVP_KEYEXCH *exchange)
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);
if (ctx->pmeth == NULL || ctx->pmeth->derive == NULL) {
EVPerr(0, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
return -2;
}
@@ -259,11 +251,6 @@ int EVP_PKEY_derive_init_ex(EVP_PKEY_CTX *ctx, EVP_KEYEXCH *exchange)
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;
@@ -284,12 +271,10 @@ int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer)
return -2;
}
provkey =
evp_keymgmt_export_to_provider(peer, ctx->op.kex.exchange->keymgmt, 0);
if (provkey == NULL) {
EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER, ERR_R_INTERNAL_ERROR);
return 0;
}
provkey = evp_keymgmt_export_to_provider(peer, ctx->keymgmt, 0);
/* If export failed, legacy may be able to pick it up */
if (provkey == NULL)
goto legacy;
return ctx->op.kex.exchange->set_peer(ctx->op.kex.exchprovctx, provkey);
legacy:
@@ -395,20 +380,16 @@ int EVP_KEYEXCH_number(const EVP_KEYEXCH *keyexch)
int EVP_KEYEXCH_is_a(const EVP_KEYEXCH *keyexch, const char *name)
{
return evp_is_a(keyexch->prov, keyexch->name_id, name);
return evp_is_a(keyexch->prov, keyexch->name_id, NULL, name);
}
void EVP_KEYEXCH_do_all_provided(OPENSSL_CTX *libctx,
void (*fn)(EVP_KEYEXCH *keyexch, void *arg),
void *arg)
{
struct keymgmt_data_st keymgmt_data;
keymgmt_data.ctx = libctx;
keymgmt_data.properties = NULL;
evp_generic_do_all(libctx, OSSL_OP_KEYEXCH,
(void (*)(void *, void *))fn, arg,
evp_keyexch_from_dispatch, &keymgmt_data,
evp_keyexch_from_dispatch,
(void (*)(void *))EVP_KEYEXCH_free);
}
+1 -1
View File
@@ -90,7 +90,7 @@ int EVP_KDF_number(const EVP_KDF *kdf)
int EVP_KDF_is_a(const EVP_KDF *kdf, const char *name)
{
return evp_is_a(kdf->prov, kdf->name_id, name);
return evp_is_a(kdf->prov, kdf->name_id, NULL, name);
}
const OSSL_PROVIDER *EVP_KDF_provider(const EVP_KDF *kdf)
+3 -4
View File
@@ -54,8 +54,7 @@ static void *evp_kdf_new(void)
static void *evp_kdf_from_dispatch(int name_id,
const OSSL_DISPATCH *fns,
OSSL_PROVIDER *prov,
void *method_data)
OSSL_PROVIDER *prov)
{
EVP_KDF *kdf = NULL;
int fnkdfcnt = 0, fnctxcnt = 0;
@@ -152,7 +151,7 @@ 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_from_dispatch, evp_kdf_up_ref,
evp_kdf_free);
}
@@ -193,5 +192,5 @@ void EVP_KDF_do_all_provided(OPENSSL_CTX *libctx,
{
evp_generic_do_all(libctx, OSSL_OP_KDF,
(void (*)(void *, void *))fn, arg,
evp_kdf_from_dispatch, NULL, evp_kdf_free);
evp_kdf_from_dispatch, evp_kdf_free);
}
+136 -107
View File
@@ -7,62 +7,29 @@
* https://www.openssl.org/source/license.html
*/
#include <openssl/core_names.h>
#include "internal/cryptlib.h"
#include "internal/nelem.h"
#include "crypto/evp.h"
#include "crypto/asn1.h"
#include "internal/core.h"
#include "internal/provider.h"
#include "evp_local.h"
static OSSL_PARAM *paramdefs_to_params(const OSSL_PARAM *paramdefs)
struct import_data_st {
void *provctx;
void *(*importfn)(void *provctx, const OSSL_PARAM params[]);
/* Result */
void *provdata;
};
static int try_import(const OSSL_PARAM params[], void *arg)
{
size_t cnt;
const OSSL_PARAM *p;
OSSL_PARAM *params, *q;
struct import_data_st *data = arg;
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;
if (space == 0)
return NULL;
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;
data->provdata = data->importfn(data->provctx, params);
return data->provdata != NULL;
}
void *evp_keymgmt_export_to_provider(EVP_PKEY *pk, EVP_KEYMGMT *keymgmt,
@@ -121,68 +88,39 @@ void *evp_keymgmt_export_to_provider(EVP_PKEY *pk, EVP_KEYMGMT *keymgmt,
* the new provider.
*/
void *(*importfn)(void *provctx, const OSSL_PARAM params[]) =
/* Setup for the export callback */
struct import_data_st import_data;
import_data.importfn =
want_domainparams ? keymgmt->importdomparams : keymgmt->importkey;
import_data.provdata = NULL;
/*
* If the given keymgmt doesn't have an import function, give up
*/
if (importfn == NULL)
if (import_data.importfn == 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 =
int (*exportfn)(void *provctx, OSSL_CALLBACK *cb, void *cbarg) =
want_domainparams
? pk->pkeys[j].keymgmt->exportdomparams
: pk->pkeys[j].keymgmt->exportkey;
if (exportfn != NULL) {
import_data.provctx =
ossl_provider_ctx(EVP_KEYMGMT_provider(keymgmt));
int (*exportfn)(void *provctx, OSSL_PARAM params[]) = NULL;
if (pk->pkeys[j].domainparams != want_domainparams)
continue;
exportfn = want_domainparams
? pk->pkeys[j].keymgmt->exportdomparams
: pk->pkeys[j].keymgmt->exportkey;
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 */
exportfn(pk->pkeys[j].provdata, params);
/*
* Allocate space and assign 'data' to point into the
* data block.
* If something goes wrong, go to the next cached key.
* The export function calls the callback (try_import), which
* does the import for us.
* Even though we got a success return, we double check that
* we actually got something, just in case some implementation
* forgets to check the return value.
*/
if ((data = allocate_params_space(params)) == NULL)
goto cont;
/*
* Call the exportkey function a second time, to get
* the data filled.
* If something goes wrong, go to the next cached key.
*/
if (!exportfn(pk->pkeys[j].provdata, params))
goto cont;
/*
* We should have all the data at this point, so import
* into the new provider and hope to get a key back.
*/
provdata = importfn(provctx, params);
cont:
OPENSSL_free(params);
OPENSSL_free(data);
if (provdata != NULL)
if (exportfn(pk->pkeys[j].provdata, &try_import, &import_data)
&& (provdata = import_data.provdata) != NULL)
break;
}
}
@@ -195,12 +133,7 @@ void *evp_keymgmt_export_to_provider(EVP_PKEY *pk, EVP_KEYMGMT *keymgmt,
*/
j = ossl_assert(i < OSSL_NELEM(pk->pkeys));
if (provdata != NULL) {
EVP_KEYMGMT_up_ref(keymgmt);
pk->pkeys[i].keymgmt = keymgmt;
pk->pkeys[i].provdata = provdata;
pk->pkeys[i].domainparams = want_domainparams;
}
evp_keymgmt_cache_pkey(pk, i, keymgmt, provdata, want_domainparams);
return provdata;
}
@@ -224,9 +157,65 @@ void evp_keymgmt_clear_pkey_cache(EVP_PKEY *pk)
keymgmt->freekey(provdata);
EVP_KEYMGMT_free(keymgmt);
}
pk->cache.size = 0;
pk->cache.bits = 0;
pk->cache.security_bits = 0;
}
}
void evp_keymgmt_cache_pkey(EVP_PKEY *pk, size_t index, EVP_KEYMGMT *keymgmt,
void *provdata, int domainparams)
{
if (provdata != NULL) {
EVP_KEYMGMT_up_ref(keymgmt);
pk->pkeys[index].keymgmt = keymgmt;
pk->pkeys[index].provdata = provdata;
pk->pkeys[index].domainparams = domainparams;
/*
* Cache information about the domain parameters or key. Only needed
* for the "original" provider side key.
*
* This services functions like EVP_PKEY_size, EVP_PKEY_bits, etc
*/
if (index == 0) {
int ok;
int bits = 0;
int security_bits = 0;
int size = 0;
OSSL_PARAM params[4];
params[0] = OSSL_PARAM_construct_int(OSSL_PKEY_PARAM_BITS, &bits);
params[1] = OSSL_PARAM_construct_int(OSSL_PKEY_PARAM_SECURITY_BITS,
&security_bits);
params[2] = OSSL_PARAM_construct_int(OSSL_PKEY_PARAM_MAX_SIZE, &size);
params[3] = OSSL_PARAM_construct_end();
ok = domainparams
? evp_keymgmt_get_domparam_params(keymgmt, provdata, params)
: evp_keymgmt_get_key_params(keymgmt, provdata, params);
if (ok) {
pk->cache.size = size;
pk->cache.bits = bits;
pk->cache.security_bits = security_bits;
}
}
}
}
void *evp_keymgmt_fromdata(EVP_PKEY *target, EVP_KEYMGMT *keymgmt,
const OSSL_PARAM params[], int domainparams)
{
void *provctx = ossl_provider_ctx(EVP_KEYMGMT_provider(keymgmt));
void *provdata = domainparams
? keymgmt->importdomparams(provctx, params)
: keymgmt->importkey(provctx, params);
evp_keymgmt_clear_pkey_cache(target);
evp_keymgmt_cache_pkey(target, 0, keymgmt, provdata, domainparams);
return provdata;
}
/* internal functions */
/* TODO(3.0) decide if these should be public or internal */
@@ -253,9 +242,10 @@ void evp_keymgmt_freedomparams(const EVP_KEYMGMT *keymgmt,
}
int evp_keymgmt_exportdomparams(const EVP_KEYMGMT *keymgmt,
void *provdomparams, OSSL_PARAM params[])
void *provdomparams,
OSSL_CALLBACK *param_cb, void *cbarg)
{
return keymgmt->exportdomparams(provdomparams, params);
return keymgmt->exportdomparams(provdomparams, param_cb, cbarg);
}
const OSSL_PARAM *evp_keymgmt_importdomparam_types(const EVP_KEYMGMT *keymgmt)
@@ -263,11 +253,31 @@ const OSSL_PARAM *evp_keymgmt_importdomparam_types(const EVP_KEYMGMT *keymgmt)
return keymgmt->importdomparam_types();
}
/*
* TODO(v3.0) investigate if we need this function. 'openssl provider' may
* be a caller...
*/
const OSSL_PARAM *evp_keymgmt_exportdomparam_types(const EVP_KEYMGMT *keymgmt)
{
return keymgmt->exportdomparam_types();
}
int evp_keymgmt_get_domparam_params(const EVP_KEYMGMT *keymgmt,
void *provdomparams, OSSL_PARAM params[])
{
if (keymgmt->get_domparam_params == NULL)
return 1;
return keymgmt->get_domparam_params(provdomparams, params);
}
const OSSL_PARAM *
evp_keymgmt_gettable_domparam_params(const EVP_KEYMGMT *keymgmt)
{
if (keymgmt->gettable_domparam_params == NULL)
return NULL;
return keymgmt->gettable_domparam_params();
}
void *evp_keymgmt_importkey(const EVP_KEYMGMT *keymgmt,
const OSSL_PARAM params[])
@@ -299,9 +309,9 @@ void evp_keymgmt_freekey(const EVP_KEYMGMT *keymgmt, void *provkey)
}
int evp_keymgmt_exportkey(const EVP_KEYMGMT *keymgmt, void *provkey,
OSSL_PARAM params[])
OSSL_CALLBACK *param_cb, void *cbarg)
{
return keymgmt->exportkey(provkey, params);
return keymgmt->exportkey(provkey, param_cb, cbarg);
}
const OSSL_PARAM *evp_keymgmt_importkey_types(const EVP_KEYMGMT *keymgmt)
@@ -309,7 +319,26 @@ const OSSL_PARAM *evp_keymgmt_importkey_types(const EVP_KEYMGMT *keymgmt)
return keymgmt->importkey_types();
}
/*
* TODO(v3.0) investigate if we need this function. 'openssl provider' may
* be a caller...
*/
const OSSL_PARAM *evp_keymgmt_exportkey_types(const EVP_KEYMGMT *keymgmt)
{
return keymgmt->exportkey_types();
}
int evp_keymgmt_get_key_params(const EVP_KEYMGMT *keymgmt,
void *provkey, OSSL_PARAM params[])
{
if (keymgmt->get_key_params == NULL)
return 1;
return keymgmt->get_key_params(provkey, params);
}
const OSSL_PARAM *evp_keymgmt_gettable_key_params(const EVP_KEYMGMT *keymgmt)
{
if (keymgmt->gettable_key_params == NULL)
return NULL;
return keymgmt->gettable_key_params();
}
+36 -7
View File
@@ -35,8 +35,7 @@ static void *keymgmt_new(void)
static void *keymgmt_from_dispatch(int name_id,
const OSSL_DISPATCH *fns,
OSSL_PROVIDER *prov,
void *unused)
OSSL_PROVIDER *prov)
{
EVP_KEYMGMT *keymgmt = NULL;
@@ -82,6 +81,16 @@ static void *keymgmt_from_dispatch(int name_id,
keymgmt->exportdomparam_types =
OSSL_get_OP_keymgmt_exportdomparam_types(fns);
break;
case OSSL_FUNC_KEYMGMT_GET_DOMPARAM_PARAMS:
if (keymgmt->get_domparam_params == NULL)
keymgmt->get_domparam_params =
OSSL_get_OP_keymgmt_get_domparam_params(fns);
break;
case OSSL_FUNC_KEYMGMT_GETTABLE_DOMPARAM_PARAMS:
if (keymgmt->gettable_domparam_params == NULL)
keymgmt->gettable_domparam_params =
OSSL_get_OP_keymgmt_gettable_domparam_params(fns);
break;
case OSSL_FUNC_KEYMGMT_IMPORTKEY:
if (keymgmt->importkey != NULL)
break;
@@ -119,6 +128,22 @@ static void *keymgmt_from_dispatch(int name_id,
keymgmt->exportkey_types =
OSSL_get_OP_keymgmt_exportkey_types(fns);
break;
case OSSL_FUNC_KEYMGMT_GET_KEY_PARAMS:
if (keymgmt->get_key_params == NULL)
keymgmt->get_key_params =
OSSL_get_OP_keymgmt_get_key_params(fns);
break;
case OSSL_FUNC_KEYMGMT_GETTABLE_KEY_PARAMS:
if (keymgmt->gettable_key_params == NULL)
keymgmt->gettable_key_params =
OSSL_get_OP_keymgmt_gettable_key_params(fns);
break;
case OSSL_FUNC_KEYMGMT_QUERY_OPERATION_NAME:
if (keymgmt->query_operation_name != NULL)
break;
keymgmt->query_operation_name =
OSSL_get_OP_keymgmt_query_operation_name(fns);
break;
}
}
/*
@@ -138,10 +163,14 @@ static void *keymgmt_from_dispatch(int name_id,
&& keymgmt->importdomparams == NULL)
|| (keymgmt->exportdomparam_types != NULL
&& keymgmt->exportdomparams == NULL)
|| (keymgmt->gettable_domparam_params != NULL
&& keymgmt->get_domparam_params == NULL)
|| (keymgmt->importkey_types != NULL
&& keymgmt->importkey == NULL)
|| (keymgmt->exportkey_types != NULL
&& keymgmt->exportkey == NULL)) {
&& keymgmt->exportkey == NULL)
|| (keymgmt->gettable_key_params != NULL
&& keymgmt->get_key_params == NULL)) {
EVP_KEYMGMT_free(keymgmt);
EVPerr(0, EVP_R_INVALID_PROVIDER_FUNCTIONS);
return NULL;
@@ -158,7 +187,7 @@ EVP_KEYMGMT *evp_keymgmt_fetch_by_number(OPENSSL_CTX *ctx, int name_id,
{
return evp_generic_fetch_by_number(ctx,
OSSL_OP_KEYMGMT, name_id, properties,
keymgmt_from_dispatch, NULL,
keymgmt_from_dispatch,
(int (*)(void *))EVP_KEYMGMT_up_ref,
(void (*)(void *))EVP_KEYMGMT_free);
}
@@ -167,7 +196,7 @@ 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,
keymgmt_from_dispatch,
(int (*)(void *))EVP_KEYMGMT_up_ref,
(void (*)(void *))EVP_KEYMGMT_free);
}
@@ -207,7 +236,7 @@ int EVP_KEYMGMT_number(const EVP_KEYMGMT *keymgmt)
int EVP_KEYMGMT_is_a(const EVP_KEYMGMT *keymgmt, const char *name)
{
return evp_is_a(keymgmt->prov, keymgmt->name_id, name);
return evp_is_a(keymgmt->prov, keymgmt->name_id, NULL, name);
}
void EVP_KEYMGMT_do_all_provided(OPENSSL_CTX *libctx,
@@ -216,7 +245,7 @@ void EVP_KEYMGMT_do_all_provided(OPENSSL_CTX *libctx,
{
evp_generic_do_all(libctx, OSSL_OP_KEYMGMT,
(void (*)(void *, void *))fn, arg,
keymgmt_from_dispatch, NULL,
keymgmt_from_dispatch,
(void (*)(void *))EVP_KEYMGMT_free);
}
+46
View File
@@ -0,0 +1,46 @@
/*
* 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 "crypto/evp.h"
#include "prov/blake2.h" /* diverse BLAKE2 macros */
#include "legacy_meth.h"
#define blake2b_init blake2b512_init
#define blake2s_init blake2s256_init
IMPLEMENT_LEGACY_EVP_MD_METH_LC(blake2s_int, blake2s)
IMPLEMENT_LEGACY_EVP_MD_METH_LC(blake2b_int, blake2b)
static const EVP_MD blake2b_md = {
NID_blake2b512,
0,
BLAKE2B_DIGEST_LENGTH,
0,
LEGACY_EVP_MD_METH_TABLE(blake2b_int_init, blake2b_int_update,
blake2b_int_final, NULL, BLAKE2B_BLOCKBYTES),
};
const EVP_MD *EVP_blake2b512(void)
{
return &blake2b_md;
}
static const EVP_MD blake2s_md = {
NID_blake2s256,
0,
BLAKE2S_DIGEST_LENGTH,
0,
LEGACY_EVP_MD_METH_TABLE(blake2s_int_init, blake2s_int_update,
blake2s_int_final, NULL, BLAKE2S_BLOCKBYTES),
};
const EVP_MD *EVP_blake2s256(void)
{
return &blake2s_md;
}
+10 -12
View File
@@ -7,29 +7,27 @@
* https://www.openssl.org/source/license.html
*/
#include <openssl/opensslconf.h>
/*
* MD2 low level APIs are deprecated for public use, but still ok for
* internal use.
*/
#include "internal/deprecated.h"
#ifndef OPENSSL_NO_MD2
#include <openssl/md2.h>
#include "crypto/evp.h"
#include "legacy_meth.h"
# include <openssl/md2.h>
# include "crypto/evp.h"
IMPLEMENT_LEGACY_EVP_MD_METH(md2, MD2)
static const EVP_MD md2_md = {
NID_md2,
NID_md2WithRSAEncryption,
MD2_DIGEST_LENGTH,
0,
NULL,
NULL,
NULL,
NULL,
NULL,
MD2_BLOCK,
LEGACY_EVP_MD_METH_TABLE(md2_init, md2_update, md2_final, NULL, MD2_BLOCK)
};
const EVP_MD *EVP_md2(void)
{
return &md2_md;
}
#endif /* OPENSSL_NO_MD2 */
+10 -12
View File
@@ -7,29 +7,27 @@
* https://www.openssl.org/source/license.html
*/
#include <openssl/opensslconf.h>
/*
* MD4 low level APIs are deprecated for public use, but still ok for
* internal use.
*/
#include "internal/deprecated.h"
#ifndef OPENSSL_NO_MD4
#include <openssl/md4.h>
#include "crypto/evp.h"
#include "legacy_meth.h"
# include <openssl/md4.h>
# include "crypto/evp.h"
IMPLEMENT_LEGACY_EVP_MD_METH(md4, MD4)
static const EVP_MD md4_md = {
NID_md4,
NID_md4WithRSAEncryption,
MD4_DIGEST_LENGTH,
0,
NULL,
NULL,
NULL,
NULL,
NULL,
MD4_CBLOCK,
LEGACY_EVP_MD_METH_TABLE(md4_init, md4_update, md4_final, NULL, MD4_CBLOCK),
};
const EVP_MD *EVP_md4(void)
{
return &md4_md;
}
#endif /* OPENSSL_NO_MD4 */
+5 -13
View File
@@ -7,29 +7,21 @@
* https://www.openssl.org/source/license.html
*/
#include <openssl/opensslconf.h>
#include <openssl/md5.h>
#include "crypto/evp.h"
#include "legacy_meth.h"
#ifndef OPENSSL_NO_MD5
# include <openssl/md5.h>
# include "crypto/evp.h"
IMPLEMENT_LEGACY_EVP_MD_METH(md5, MD5)
static const EVP_MD md5_md = {
NID_md5,
NID_md5WithRSAEncryption,
MD5_DIGEST_LENGTH,
0,
NULL,
NULL,
NULL,
NULL,
NULL,
MD5_CBLOCK,
LEGACY_EVP_MD_METH_TABLE(md5_init, md5_update, md5_final, NULL, MD5_CBLOCK)
};
const EVP_MD *EVP_md5(void)
{
return &md5_md;
}
#endif /* OPENSSL_NO_MD5 */
+10 -14
View File
@@ -7,31 +7,27 @@
* https://www.openssl.org/source/license.html
*/
#include <openssl/opensslconf.h>
#include "crypto/evp.h"
#include "prov/md5_sha1.h" /* diverse MD5_SHA1 macros */
#include "legacy_meth.h"
#ifndef OPENSSL_NO_MD5
# include <openssl/obj_mac.h>
# include "crypto/evp.h"
IMPLEMENT_LEGACY_EVP_MD_METH_LC(md5_sha1_int, md5_sha1)
static int md5_sha1_int_ctrl(EVP_MD_CTX *ctx, int cmd, int mslen, void *ms)
{
return md5_sha1_ctrl(EVP_MD_CTX_md_data(ctx), cmd, mslen, ms);
}
static const EVP_MD md5_sha1_md = {
NID_md5_sha1,
NID_md5_sha1,
MD5_SHA1_DIGEST_LENGTH,
0,
NULL,
NULL,
NULL,
NULL,
NULL,
MD5_SHA1_CBLOCK,
LEGACY_EVP_MD_METH_TABLE(md5_sha1_int_init, md5_sha1_int_update,
md5_sha1_int_final, md5_sha1_int_ctrl,
MD5_SHA1_CBLOCK),
};
const EVP_MD *EVP_md5_sha1(void)
{
return &md5_sha1_md;
}
#endif /* OPENSSL_NO_MD5 */
+11 -12
View File
@@ -7,29 +7,28 @@
* https://www.openssl.org/source/license.html
*/
#include <openssl/opensslconf.h>
/*
* MDC2 low level APIs are deprecated for public use, but still ok for
* internal use.
*/
#include "internal/deprecated.h"
#ifndef OPENSSL_NO_MDC2
#include <openssl/mdc2.h>
#include "crypto/evp.h"
#include "legacy_meth.h"
# include <openssl/mdc2.h>
# include "crypto/evp.h"
IMPLEMENT_LEGACY_EVP_MD_METH(mdc2, MDC2)
static const EVP_MD mdc2_md = {
NID_mdc2,
NID_mdc2WithRSA,
MDC2_DIGEST_LENGTH,
0,
NULL,
NULL,
NULL,
NULL,
NULL,
MDC2_BLOCK,
LEGACY_EVP_MD_METH_TABLE(mdc2_init, mdc2_update, mdc2_final, NULL,
MDC2_BLOCK),
};
const EVP_MD *EVP_mdc2(void)
{
return &mdc2_md;
}
#endif /* OPENSSL_NO_MDC2 */
+40
View File
@@ -0,0 +1,40 @@
/*
* 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
*/
#define IMPLEMENT_LEGACY_EVP_MD_METH(nm, fn) \
static int nm##_init(EVP_MD_CTX *ctx) \
{ \
return fn##_Init(EVP_MD_CTX_md_data(ctx)); \
} \
static int nm##_update(EVP_MD_CTX *ctx, const void *data, size_t count) \
{ \
return fn##_Update(EVP_MD_CTX_md_data(ctx), data, count); \
} \
static int nm##_final(EVP_MD_CTX *ctx, unsigned char *md) \
{ \
return fn##_Final(md, EVP_MD_CTX_md_data(ctx)); \
}
#define IMPLEMENT_LEGACY_EVP_MD_METH_LC(nm, fn) \
static int nm##_init(EVP_MD_CTX *ctx) \
{ \
return fn##_init(EVP_MD_CTX_md_data(ctx)); \
} \
static int nm##_update(EVP_MD_CTX *ctx, const void *data, size_t count) \
{ \
return fn##_update(EVP_MD_CTX_md_data(ctx), data, count); \
} \
static int nm##_final(EVP_MD_CTX *ctx, unsigned char *md) \
{ \
return fn##_final(md, EVP_MD_CTX_md_data(ctx)); \
}
#define LEGACY_EVP_MD_METH_TABLE(init, update, final, ctrl, blksz) \
init, update, final, NULL, NULL, blksz, 0, ctrl
+34
View File
@@ -0,0 +1,34 @@
/*
* Copyright 1995-2016 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
*/
/*
* RIPEMD160 low level APIs are deprecated for public use, but still ok for
* internal use.
*/
#include "internal/deprecated.h"
#include <openssl/ripemd.h>
#include "crypto/evp.h"
#include "legacy_meth.h"
IMPLEMENT_LEGACY_EVP_MD_METH(ripe, RIPEMD160)
static const EVP_MD ripemd160_md = {
NID_ripemd160,
NID_ripemd160WithRSA,
RIPEMD160_DIGEST_LENGTH,
0,
LEGACY_EVP_MD_METH_TABLE(ripe_init, ripe_update, ripe_final, NULL,
RIPEMD160_CBLOCK),
};
const EVP_MD *EVP_ripemd160(void)
{
return &ripemd160_md;
}
+107 -79
View File
@@ -7,24 +7,83 @@
* https://www.openssl.org/source/license.html
*/
#include <openssl/opensslconf.h>
#include <openssl/obj_mac.h>
#include <openssl/sha.h> /* diverse SHA macros */
#include "internal/sha3.h" /* KECCAK1600_WIDTH */
#include "crypto/evp.h"
/* Used by legacy methods */
#include "crypto/sha.h"
#include "legacy_meth.h"
#include "evp_local.h"
/*-
* LEGACY methods for SHA.
* These only remain to support engines that can get these methods.
* Hardware support for SHA3 has been removed from these legacy cases.
*/
#define IMPLEMENT_LEGACY_EVP_MD_METH_SHA3(nm, fn, tag) \
static int nm##_init(EVP_MD_CTX *ctx) \
{ \
return fn##_init(EVP_MD_CTX_md_data(ctx), tag, ctx->digest->md_size * 8); \
} \
static int nm##_update(EVP_MD_CTX *ctx, const void *data, size_t count) \
{ \
return fn##_update(EVP_MD_CTX_md_data(ctx), data, count); \
} \
static int nm##_final(EVP_MD_CTX *ctx, unsigned char *md) \
{ \
return fn##_final(md, EVP_MD_CTX_md_data(ctx)); \
}
#define IMPLEMENT_LEGACY_EVP_MD_METH_SHAKE(nm, fn, tag) \
static int nm##_init(EVP_MD_CTX *ctx) \
{ \
return fn##_init(EVP_MD_CTX_md_data(ctx), tag, ctx->digest->md_size * 8); \
} \
#define sha512_224_Init sha512_224_init
#define sha512_256_Init sha512_256_init
#define sha512_224_Update SHA512_Update
#define sha512_224_Final SHA512_Final
#define sha512_256_Update SHA512_Update
#define sha512_256_Final SHA512_Final
IMPLEMENT_LEGACY_EVP_MD_METH(sha1, SHA1)
IMPLEMENT_LEGACY_EVP_MD_METH(sha224, SHA224)
IMPLEMENT_LEGACY_EVP_MD_METH(sha256, SHA256)
IMPLEMENT_LEGACY_EVP_MD_METH(sha384, SHA384)
IMPLEMENT_LEGACY_EVP_MD_METH(sha512, SHA512)
IMPLEMENT_LEGACY_EVP_MD_METH(sha512_224_int, sha512_224)
IMPLEMENT_LEGACY_EVP_MD_METH(sha512_256_int, sha512_256)
IMPLEMENT_LEGACY_EVP_MD_METH_SHA3(sha3_int, sha3, '\x06')
IMPLEMENT_LEGACY_EVP_MD_METH_SHAKE(shake, sha3, '\x1f')
static int sha1_int_ctrl(EVP_MD_CTX *ctx, int cmd, int p1, void *p2)
{
return sha1_ctrl(ctx != NULL ? EVP_MD_CTX_md_data(ctx) : NULL, cmd, p1, p2);
}
static int shake_ctrl(EVP_MD_CTX *evp_ctx, int cmd, int p1, void *p2)
{
KECCAK1600_CTX *ctx = evp_ctx->md_data;
switch (cmd) {
case EVP_MD_CTRL_XOF_LEN:
ctx->md_size = p1;
return 1;
default:
return 0;
}
}
static const EVP_MD sha1_md = {
NID_sha1,
NID_sha1WithRSAEncryption,
SHA_DIGEST_LENGTH,
EVP_MD_FLAG_DIGALGID_ABSENT,
NULL,
NULL,
NULL,
NULL,
NULL,
SHA_CBLOCK,
LEGACY_EVP_MD_METH_TABLE(sha1_init, sha1_update, sha1_final, sha1_int_ctrl,
SHA_CBLOCK),
};
const EVP_MD *EVP_sha1(void)
@@ -37,12 +96,8 @@ static const EVP_MD sha224_md = {
NID_sha224WithRSAEncryption,
SHA224_DIGEST_LENGTH,
EVP_MD_FLAG_DIGALGID_ABSENT,
NULL,
NULL,
NULL,
NULL,
NULL,
SHA256_CBLOCK,
LEGACY_EVP_MD_METH_TABLE(sha224_init, sha224_update, sha224_final, NULL,
SHA256_CBLOCK),
};
const EVP_MD *EVP_sha224(void)
@@ -55,12 +110,8 @@ static const EVP_MD sha256_md = {
NID_sha256WithRSAEncryption,
SHA256_DIGEST_LENGTH,
EVP_MD_FLAG_DIGALGID_ABSENT,
NULL,
NULL,
NULL,
NULL,
NULL,
SHA256_CBLOCK,
LEGACY_EVP_MD_METH_TABLE(sha256_init, sha256_update, sha256_final, NULL,
SHA256_CBLOCK),
};
const EVP_MD *EVP_sha256(void)
@@ -73,12 +124,8 @@ static const EVP_MD sha512_224_md = {
NID_sha512_224WithRSAEncryption,
SHA224_DIGEST_LENGTH,
EVP_MD_FLAG_DIGALGID_ABSENT,
NULL,
NULL,
NULL,
NULL,
NULL,
SHA512_CBLOCK,
LEGACY_EVP_MD_METH_TABLE(sha512_224_int_init, sha512_224_int_update,
sha512_224_int_final, NULL, SHA512_CBLOCK),
};
const EVP_MD *EVP_sha512_224(void)
@@ -91,12 +138,8 @@ static const EVP_MD sha512_256_md = {
NID_sha512_256WithRSAEncryption,
SHA256_DIGEST_LENGTH,
EVP_MD_FLAG_DIGALGID_ABSENT,
NULL,
NULL,
NULL,
NULL,
NULL,
SHA512_CBLOCK,
LEGACY_EVP_MD_METH_TABLE(sha512_256_int_init, sha512_256_int_update,
sha512_256_int_final, NULL, SHA512_CBLOCK),
};
const EVP_MD *EVP_sha512_256(void)
@@ -109,12 +152,8 @@ static const EVP_MD sha384_md = {
NID_sha384WithRSAEncryption,
SHA384_DIGEST_LENGTH,
EVP_MD_FLAG_DIGALGID_ABSENT,
NULL,
NULL,
NULL,
NULL,
NULL,
SHA512_CBLOCK,
LEGACY_EVP_MD_METH_TABLE(sha384_init, sha384_update, sha384_final, NULL,
SHA512_CBLOCK),
};
const EVP_MD *EVP_sha384(void)
@@ -127,12 +166,8 @@ static const EVP_MD sha512_md = {
NID_sha512WithRSAEncryption,
SHA512_DIGEST_LENGTH,
EVP_MD_FLAG_DIGALGID_ABSENT,
NULL,
NULL,
NULL,
NULL,
NULL,
SHA512_CBLOCK,
LEGACY_EVP_MD_METH_TABLE(sha512_init, sha512_update, sha512_final, NULL,
SHA512_CBLOCK),
};
const EVP_MD *EVP_sha512(void)
@@ -140,40 +175,33 @@ const EVP_MD *EVP_sha512(void)
return &sha512_md;
}
# define EVP_MD_SHA3(bitlen) \
const EVP_MD *EVP_sha3_##bitlen(void) \
{ \
static const EVP_MD sha3_##bitlen##_md = { \
NID_sha3_##bitlen, \
NID_RSA_SHA3_##bitlen, \
bitlen / 8, \
EVP_MD_FLAG_DIGALGID_ABSENT, \
NULL, \
NULL, \
NULL, \
NULL, \
NULL, \
(KECCAK1600_WIDTH - bitlen * 2) / 8, \
}; \
return &sha3_##bitlen##_md; \
}
# define EVP_MD_SHAKE(bitlen) \
const EVP_MD *EVP_shake##bitlen(void) \
{ \
static const EVP_MD shake##bitlen##_md = { \
NID_shake##bitlen, \
0, \
bitlen / 8, \
EVP_MD_FLAG_XOF, \
NULL, \
NULL, \
NULL, \
NULL, \
NULL, \
(KECCAK1600_WIDTH - bitlen * 2) / 8, \
}; \
return &shake##bitlen##_md; \
}
#define EVP_MD_SHA3(bitlen) \
const EVP_MD *EVP_sha3_##bitlen(void) \
{ \
static const EVP_MD sha3_##bitlen##_md = { \
NID_sha3_##bitlen, \
NID_RSA_SHA3_##bitlen, \
bitlen / 8, \
EVP_MD_FLAG_DIGALGID_ABSENT, \
LEGACY_EVP_MD_METH_TABLE(sha3_int_init, sha3_int_update, \
sha3_int_final, NULL, \
(KECCAK1600_WIDTH - bitlen * 2) / 8), \
}; \
return &sha3_##bitlen##_md; \
}
#define EVP_MD_SHAKE(bitlen) \
const EVP_MD *EVP_shake##bitlen(void) \
{ \
static const EVP_MD shake##bitlen##_md = { \
NID_shake##bitlen, \
0, \
bitlen / 8, \
EVP_MD_FLAG_XOF, \
LEGACY_EVP_MD_METH_TABLE(shake_init, sha3_int_update, sha3_int_final, \
shake_ctrl, (KECCAK1600_WIDTH - bitlen * 2) / 8), \
}; \
return &shake##bitlen##_md; \
}
EVP_MD_SHA3(224)
EVP_MD_SHA3(256)
+34
View File
@@ -0,0 +1,34 @@
/*
* Copyright 2005-2016 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
*/
/*
* Whirlpool low level APIs are deprecated for public use, but still ok for
* internal use.
*/
#include "internal/deprecated.h"
#include <openssl/whrlpool.h>
#include "crypto/evp.h"
#include "legacy_meth.h"
IMPLEMENT_LEGACY_EVP_MD_METH(wp, WHIRLPOOL)
static const EVP_MD whirlpool_md = {
NID_whirlpool,
0,
WHIRLPOOL_DIGEST_LENGTH,
0,
LEGACY_EVP_MD_METH_TABLE(wp_init, wp_update, wp_final, NULL,
WHIRLPOOL_BBLOCK / 8),
};
const EVP_MD *EVP_whirlpool(void)
{
return &whirlpool_md;
}
-55
View File
@@ -1,55 +0,0 @@
/*
* Copyright 1995-2016 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 <stdio.h>
#include "internal/cryptlib.h"
#ifndef OPENSSL_NO_RMD160
# include <openssl/ripemd.h>
# include <openssl/evp.h>
# include <openssl/objects.h>
# include <openssl/x509.h>
# include <openssl/rsa.h>
# include "crypto/evp.h"
static int init(EVP_MD_CTX *ctx)
{
return RIPEMD160_Init(EVP_MD_CTX_md_data(ctx));
}
static int update(EVP_MD_CTX *ctx, const void *data, size_t count)
{
return RIPEMD160_Update(EVP_MD_CTX_md_data(ctx), data, count);
}
static int final(EVP_MD_CTX *ctx, unsigned char *md)
{
return RIPEMD160_Final(md, EVP_MD_CTX_md_data(ctx));
}
static const EVP_MD ripemd160_md = {
NID_ripemd160,
NID_ripemd160WithRSA,
RIPEMD160_DIGEST_LENGTH,
0,
init,
update,
final,
NULL,
NULL,
RIPEMD160_CBLOCK,
sizeof(EVP_MD *) + sizeof(RIPEMD160_CTX),
};
const EVP_MD *EVP_ripemd160(void)
{
return &ripemd160_md;
}
#endif
+115 -75
View File
@@ -27,9 +27,10 @@ static int update(EVP_MD_CTX *ctx, const void *data, size_t datalen)
static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
const EVP_MD *type, const char *mdname,
const char *props, ENGINE *e, EVP_PKEY *pkey,
EVP_SIGNATURE *signature, int ver)
int ver)
{
EVP_PKEY_CTX *locpctx = NULL;
EVP_SIGNATURE *signature = NULL;
void *provkey = NULL;
int ret;
@@ -43,66 +44,92 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
ctx->provctx = NULL;
}
if (ctx->pctx == NULL) {
if (ctx->pctx == NULL)
ctx->pctx = EVP_PKEY_CTX_new(pkey, e);
if (ctx->pctx == NULL)
return 0;
} else if (pkey != NULL) {
if (!EVP_PKEY_up_ref(pkey))
return 0;
EVP_PKEY_free(ctx->pctx->pkey);
ctx->pctx->pkey = pkey;
}
if (ctx->pctx == NULL)
return 0;
locpctx = ctx->pctx;
evp_pkey_ctx_free_old_ops(locpctx);
if (locpctx->pkey == NULL)
if (locpctx->keytype == NULL)
goto legacy;
if (e != NULL || locpctx->engine != NULL)
goto legacy;
if (signature != NULL) {
if (!EVP_SIGNATURE_up_ref(signature))
goto err;
} else {
/*
* TODO(3.0): Check for legacy handling. Remove this once all all
* algorithms are moved to providers.
*/
switch (locpctx->pkey->type) {
case NID_dsa:
break;
default:
goto legacy;
}
signature
= EVP_SIGNATURE_fetch(NULL, OBJ_nid2sn(locpctx->pkey->type), NULL);
if (signature == NULL) {
ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR);
goto err;
if (mdname == NULL) {
if (type != NULL) {
mdname = EVP_MD_name(type);
} else if (pkey != NULL) {
/*
* TODO(v3.0) work out a better way for EVP_PKEYs with no legacy
* component.
*/
if (pkey->pkey.ptr != NULL) {
int def_nid;
if (EVP_PKEY_get_default_digest_nid(pkey, &def_nid) > 0)
mdname = OBJ_nid2sn(def_nid);
}
}
}
locpctx->operation = ver ? EVP_PKEY_OP_VERIFYCTX
: EVP_PKEY_OP_SIGNCTX;
if (locpctx->keymgmt == NULL)
locpctx->keymgmt = EVP_KEYMGMT_fetch(locpctx->libctx, locpctx->keytype,
locpctx->propquery);
if (locpctx->keymgmt != NULL) {
const char *supported_sig = NULL;
if (locpctx->keymgmt->query_operation_name != NULL)
supported_sig =
locpctx->keymgmt->query_operation_name(OSSL_OP_SIGNATURE);
/*
* If we didn't get a supported sig, assume there is one with the
* same name as the key type.
*/
if (supported_sig == NULL)
supported_sig = locpctx->keytype;
/*
* Because we cleared out old ops, we shouldn't need to worry about
* checking if signature is already there.
*/
signature = EVP_SIGNATURE_fetch(locpctx->libctx, supported_sig,
locpctx->propquery);
}
if (locpctx->keymgmt == NULL
|| signature == NULL
|| (EVP_KEYMGMT_provider(locpctx->keymgmt)
!= EVP_SIGNATURE_provider(signature))) {
/*
* We don't have the full support we need with provided methods,
* let's go see if legacy does. Also, we don't need to free
* ctx->keymgmt here, as it's not necessarily tied to this
* operation. It will be freed by EVP_PKEY_CTX_free().
*/
EVP_SIGNATURE_free(signature);
goto legacy;
}
/* No more legacy from here down to legacy: */
locpctx->op.sig.signature = signature;
provkey =
evp_keymgmt_export_to_provider(locpctx->pkey, locpctx->keymgmt, 0);
/* If export failed, legacy may be able to pick it up */
if (provkey == NULL)
goto legacy;
locpctx->operation = ver ? EVP_PKEY_OP_VERIFYCTX
: EVP_PKEY_OP_SIGNCTX;
locpctx->op.sig.sigprovctx
= signature->newctx(ossl_provider_ctx(signature->prov));
if (locpctx->op.sig.sigprovctx == NULL) {
ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR);
goto err;
}
provkey =
evp_keymgmt_export_to_provider(locpctx->pkey, signature->keymgmt, 0);
if (provkey == NULL) {
ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR);
goto err;
}
if (mdname == NULL) {
mdname = EVP_MD_name(type);
if (type != NULL) {
ctx->reqdigest = type;
} else {
/*
@@ -111,11 +138,8 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
* man pages), i.e. the ref count is not updated so the EVP_MD should
* not be used beyound the lifetime of the EVP_MD_CTX.
*/
ctx->reqdigest
= ctx->fetched_digest
= EVP_MD_fetch(
ossl_provider_library_context(EVP_SIGNATURE_provider(signature)),
mdname, props);
ctx->reqdigest = ctx->fetched_digest =
EVP_MD_fetch(locpctx->libctx, mdname, props);
}
if (ver) {
@@ -123,15 +147,15 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR);
goto err;
}
ret = signature->digest_verify_init(locpctx->op.sig.sigprovctx, mdname,
props, provkey);
ret = signature->digest_verify_init(locpctx->op.sig.sigprovctx,
mdname, props, provkey);
} else {
if (signature->digest_sign_init == NULL) {
ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR);
goto err;
}
ret = signature->digest_sign_init(locpctx->op.sig.sigprovctx, mdname,
props, provkey);
ret = signature->digest_sign_init(locpctx->op.sig.sigprovctx,
mdname, props, provkey);
}
return ret ? 1 : 0;
@@ -141,6 +165,11 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
return 0;
legacy:
if (ctx->pctx->pmeth == NULL) {
EVPerr(0, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
return 0;
}
if (!(ctx->pctx->pmeth->flags & EVP_PKEY_FLAG_SIGCTX_CUSTOM)) {
if (type == NULL) {
@@ -197,31 +226,28 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
}
int EVP_DigestSignInit_ex(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
const char *mdname, const char *props, EVP_PKEY *pkey,
EVP_SIGNATURE *signature)
const char *mdname, const char *props, EVP_PKEY *pkey)
{
return do_sigver_init(ctx, pctx, NULL, mdname, props, NULL, pkey, signature,
0);
return do_sigver_init(ctx, pctx, NULL, mdname, props, NULL, pkey, 0);
}
int EVP_DigestSignInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey)
{
return do_sigver_init(ctx, pctx, type, NULL, NULL, e, pkey, NULL, 0);
return do_sigver_init(ctx, pctx, type, NULL, NULL, e, pkey, 0);
}
int EVP_DigestVerifyInit_ex(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
const char *mdname, const char *props,
EVP_PKEY *pkey, EVP_SIGNATURE *signature)
EVP_PKEY *pkey)
{
return do_sigver_init(ctx, pctx, NULL, mdname, props, NULL, pkey, signature,
1);
return do_sigver_init(ctx, pctx, NULL, mdname, props, NULL, pkey, 1);
}
int EVP_DigestVerifyInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey)
{
return do_sigver_init(ctx, pctx, type, NULL, NULL, e, pkey, NULL, 1);
return do_sigver_init(ctx, pctx, type, NULL, NULL, e, pkey, 1);
}
#endif /* FIPS_MDOE */
@@ -276,34 +302,42 @@ int EVP_DigestSignFinal(EVP_MD_CTX *ctx, unsigned char *sigret,
sigret, siglen, SIZE_MAX);
legacy:
if (pctx == NULL || pctx->pmeth == NULL) {
ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR);
return 0;
}
if (pctx->pmeth->flags & EVP_PKEY_FLAG_SIGCTX_CUSTOM) {
if (!sigret)
if (sigret == NULL)
return pctx->pmeth->signctx(pctx, sigret, siglen, ctx);
if (ctx->flags & EVP_MD_CTX_FLAG_FINALISE)
r = pctx->pmeth->signctx(pctx, sigret, siglen, ctx);
else {
EVP_PKEY_CTX *dctx = EVP_PKEY_CTX_dup(ctx->pctx);
if (!dctx)
EVP_PKEY_CTX *dctx = EVP_PKEY_CTX_dup(pctx);
if (dctx == NULL)
return 0;
r = dctx->pmeth->signctx(dctx, sigret, siglen, ctx);
EVP_PKEY_CTX_free(dctx);
}
return r;
}
if (pctx->pmeth->signctx)
if (pctx->pmeth->signctx != NULL)
sctx = 1;
else
sctx = 0;
if (sigret) {
if (sigret != NULL) {
unsigned char md[EVP_MAX_MD_SIZE];
unsigned int mdlen = 0;
if (ctx->flags & EVP_MD_CTX_FLAG_FINALISE) {
if (sctx)
r = ctx->pctx->pmeth->signctx(ctx->pctx, sigret, siglen, ctx);
r = pctx->pmeth->signctx(pctx, sigret, siglen, ctx);
else
r = EVP_DigestFinal_ex(ctx, md, &mdlen);
} else {
EVP_MD_CTX *tmp_ctx = EVP_MD_CTX_new();
if (tmp_ctx == NULL)
return 0;
if (!EVP_MD_CTX_copy_ex(tmp_ctx, ctx)) {
@@ -319,7 +353,7 @@ int EVP_DigestSignFinal(EVP_MD_CTX *ctx, unsigned char *sigret,
}
if (sctx || !r)
return r;
if (EVP_PKEY_sign(ctx->pctx, sigret, siglen, md, mdlen) <= 0)
if (EVP_PKEY_sign(pctx, sigret, siglen, md, mdlen) <= 0)
return 0;
} else {
if (sctx) {
@@ -327,6 +361,7 @@ int EVP_DigestSignFinal(EVP_MD_CTX *ctx, unsigned char *sigret,
return 0;
} else {
int s = EVP_MD_size(ctx->digest);
if (s < 0 || EVP_PKEY_sign(pctx, sigret, siglen, NULL, s) <= 0)
return 0;
}
@@ -337,7 +372,7 @@ int EVP_DigestSignFinal(EVP_MD_CTX *ctx, unsigned char *sigret,
int EVP_DigestSign(EVP_MD_CTX *ctx, unsigned char *sigret, size_t *siglen,
const unsigned char *tbs, size_t tbslen)
{
if (ctx->pctx->pmeth->digestsign != NULL)
if (ctx->pctx->pmeth != NULL && ctx->pctx->pmeth->digestsign != NULL)
return ctx->pctx->pmeth->digestsign(ctx, sigret, siglen, tbs, tbslen);
if (sigret != NULL && EVP_DigestSignUpdate(ctx, tbs, tbslen) <= 0)
return 0;
@@ -363,13 +398,18 @@ int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sig,
sig, siglen);
legacy:
if (ctx->pctx->pmeth->verifyctx)
if (pctx == NULL || pctx->pmeth == NULL) {
ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR);
return 0;
}
if (pctx->pmeth->verifyctx != NULL)
vctx = 1;
else
vctx = 0;
if (ctx->flags & EVP_MD_CTX_FLAG_FINALISE) {
if (vctx)
r = ctx->pctx->pmeth->verifyctx(ctx->pctx, sig, siglen, ctx);
r = pctx->pmeth->verifyctx(pctx, sig, siglen, ctx);
else
r = EVP_DigestFinal_ex(ctx, md, &mdlen);
} else {
@@ -389,13 +429,13 @@ int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sig,
}
if (vctx || !r)
return r;
return EVP_PKEY_verify(ctx->pctx, sig, siglen, md, mdlen);
return EVP_PKEY_verify(pctx, sig, siglen, md, mdlen);
}
int EVP_DigestVerify(EVP_MD_CTX *ctx, const unsigned char *sigret,
size_t siglen, const unsigned char *tbs, size_t tbslen)
{
if (ctx->pctx->pmeth->digestverify != NULL)
if (ctx->pctx->pmeth != NULL && ctx->pctx->pmeth->digestverify != NULL)
return ctx->pctx->pmeth->digestverify(ctx, sigret, siglen, tbs, tbslen);
if (EVP_DigestVerifyUpdate(ctx, tbs, tbslen) <= 0)
return -1;
-54
View File
@@ -1,54 +0,0 @@
/*
* Copyright 2005-2016 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 <stdio.h>
#include "internal/cryptlib.h"
#ifndef OPENSSL_NO_WHIRLPOOL
# include <openssl/evp.h>
# include <openssl/objects.h>
# include <openssl/x509.h>
# include <openssl/whrlpool.h>
# include "crypto/evp.h"
static int init(EVP_MD_CTX *ctx)
{
return WHIRLPOOL_Init(EVP_MD_CTX_md_data(ctx));
}
static int update(EVP_MD_CTX *ctx, const void *data, size_t count)
{
return WHIRLPOOL_Update(EVP_MD_CTX_md_data(ctx), data, count);
}
static int final(EVP_MD_CTX *ctx, unsigned char *md)
{
return WHIRLPOOL_Final(md, EVP_MD_CTX_md_data(ctx));
}
static const EVP_MD whirlpool_md = {
NID_whirlpool,
0,
WHIRLPOOL_DIGEST_LENGTH,
0,
init,
update,
final,
NULL,
NULL,
WHIRLPOOL_BBLOCK / 8,
sizeof(EVP_MD *) + sizeof(WHIRLPOOL_CTX),
};
const EVP_MD *EVP_whirlpool(void)
{
return &whirlpool_md;
}
#endif
+1 -1
View File
@@ -165,7 +165,7 @@ int EVP_MAC_number(const EVP_MAC *mac)
int EVP_MAC_is_a(const EVP_MAC *mac, const char *name)
{
return evp_is_a(mac->prov, mac->name_id, name);
return evp_is_a(mac->prov, mac->name_id, NULL, name);
}
void EVP_MAC_names_do_all(const EVP_MAC *mac,
+3 -4
View File
@@ -48,8 +48,7 @@ static void *evp_mac_new(void)
static void *evp_mac_from_dispatch(int name_id,
const OSSL_DISPATCH *fns,
OSSL_PROVIDER *prov,
void *unused)
OSSL_PROVIDER *prov)
{
EVP_MAC *mac = NULL;
int fnmaccnt = 0, fnctxcnt = 0;
@@ -154,7 +153,7 @@ 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_from_dispatch, evp_mac_up_ref,
evp_mac_free);
}
@@ -200,5 +199,5 @@ void EVP_MAC_do_all_provided(OPENSSL_CTX *libctx,
{
evp_generic_do_all(libctx, OSSL_OP_MAC,
(void (*)(void *, void *))fn, arg,
evp_mac_from_dispatch, NULL, evp_mac_free);
evp_mac_from_dispatch, evp_mac_free);
}
+74 -5
View File
@@ -8,11 +8,12 @@
*/
#include <stdio.h>
#include "internal/cryptlib.h"
#include <openssl/evp.h>
#include <openssl/kdf.h>
#include "crypto/objects.h"
#include <openssl/x509.h>
#include "internal/cryptlib.h"
#include "internal/namemap.h"
#include "crypto/objects.h"
#include "crypto/evp.h"
int EVP_add_cipher(const EVP_CIPHER *c)
@@ -56,26 +57,94 @@ int EVP_add_digest(const EVP_MD *md)
return r;
}
static void cipher_from_name(const char *name, void *data)
{
const EVP_CIPHER **cipher = data;
if (*cipher != NULL)
return;
*cipher = (const EVP_CIPHER *)OBJ_NAME_get(name, OBJ_NAME_TYPE_CIPHER_METH);
}
const EVP_CIPHER *EVP_get_cipherbyname(const char *name)
{
return evp_get_cipherbyname_ex(NULL, name);
}
const EVP_CIPHER *evp_get_cipherbyname_ex(OPENSSL_CTX *libctx, const char *name)
{
const EVP_CIPHER *cp;
OSSL_NAMEMAP *namemap;
int id;
if (!OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS, NULL))
return NULL;
cp = (const EVP_CIPHER *)OBJ_NAME_get(name, OBJ_NAME_TYPE_CIPHER_METH);
if (cp != NULL)
return cp;
/*
* It's not in the method database, but it might be there under a different
* name. So we check for aliases in the EVP namemap and try all of those
* in turn.
*/
namemap = ossl_namemap_stored(libctx);
id = ossl_namemap_name2num(namemap, name);
if (id == 0)
return NULL;
ossl_namemap_doall_names(namemap, id, cipher_from_name, &cp);
return cp;
}
static void digest_from_name(const char *name, void *data)
{
const EVP_MD **md = data;
if (*md != NULL)
return;
*md = (const EVP_MD *)OBJ_NAME_get(name, OBJ_NAME_TYPE_MD_METH);
}
const EVP_MD *EVP_get_digestbyname(const char *name)
{
const EVP_MD *cp;
return evp_get_digestbyname_ex(NULL, name);
}
const EVP_MD *evp_get_digestbyname_ex(OPENSSL_CTX *libctx, const char *name)
{
const EVP_MD *dp;
OSSL_NAMEMAP *namemap;
int id;
if (!OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_DIGESTS, NULL))
return NULL;
cp = (const EVP_MD *)OBJ_NAME_get(name, OBJ_NAME_TYPE_MD_METH);
return cp;
dp = (const EVP_MD *)OBJ_NAME_get(name, OBJ_NAME_TYPE_MD_METH);
if (dp != NULL)
return dp;
/*
* It's not in the method database, but it might be there under a different
* name. So we check for aliases in the EVP namemap and try all of those
* in turn.
*/
namemap = ossl_namemap_stored(libctx);
id = ossl_namemap_name2num(namemap, name);
if (id == 0)
return NULL;
ossl_namemap_doall_names(namemap, id, digest_from_name, &dp);
return dp;
}
void evp_cleanup_int(void)
+207 -120
View File
@@ -21,18 +21,25 @@
#include <openssl/cmac.h>
#include <openssl/engine.h>
#include <openssl/params.h>
#include <openssl/serializer.h>
#include <openssl/core_names.h>
#include "crypto/asn1.h"
#include "crypto/evp.h"
#include "internal/provider.h"
static void EVP_PKEY_free_it(EVP_PKEY *x);
static void evp_pkey_free_it(EVP_PKEY *key);
#ifndef FIPS_MODE
int EVP_PKEY_bits(const EVP_PKEY *pkey)
{
if (pkey && pkey->ameth && pkey->ameth->pkey_bits)
return pkey->ameth->pkey_bits(pkey);
if (pkey != NULL) {
if (pkey->ameth == NULL)
return pkey->cache.bits;
else if (pkey->ameth->pkey_bits)
return pkey->ameth->pkey_bits(pkey);
}
return 0;
}
@@ -40,21 +47,16 @@ int EVP_PKEY_security_bits(const EVP_PKEY *pkey)
{
if (pkey == NULL)
return 0;
if (pkey->ameth == NULL || pkey->ameth->pkey_security_bits == NULL)
if (pkey->ameth == NULL)
return pkey->cache.security_bits;
if (pkey->ameth->pkey_security_bits == NULL)
return -2;
return pkey->ameth->pkey_security_bits(pkey);
}
int EVP_PKEY_size(const EVP_PKEY *pkey)
{
if (pkey && pkey->ameth && pkey->ameth->pkey_size)
return pkey->ameth->pkey_size(pkey);
return 0;
}
int EVP_PKEY_save_parameters(EVP_PKEY *pkey, int mode)
{
#ifndef OPENSSL_NO_DSA
# ifndef OPENSSL_NO_DSA
if (pkey->type == EVP_PKEY_DSA) {
int ret = pkey->save_parameters;
@@ -62,8 +64,8 @@ int EVP_PKEY_save_parameters(EVP_PKEY *pkey, int mode)
pkey->save_parameters = mode;
return ret;
}
#endif
#ifndef OPENSSL_NO_EC
# endif
# ifndef OPENSSL_NO_EC
if (pkey->type == EVP_PKEY_EC) {
int ret = pkey->save_parameters;
@@ -71,7 +73,7 @@ int EVP_PKEY_save_parameters(EVP_PKEY *pkey, int mode)
pkey->save_parameters = mode;
return ret;
}
#endif
# endif
return 0;
}
@@ -105,7 +107,7 @@ int EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from)
int EVP_PKEY_missing_parameters(const EVP_PKEY *pkey)
{
if (pkey->ameth && pkey->ameth->param_missing)
if (pkey != NULL && pkey->ameth && pkey->ameth->param_missing)
return pkey->ameth->param_missing(pkey);
return 0;
}
@@ -140,38 +142,6 @@ int EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
return -2;
}
EVP_PKEY *EVP_PKEY_new(void)
{
EVP_PKEY *ret = OPENSSL_zalloc(sizeof(*ret));
if (ret == NULL) {
EVPerr(EVP_F_EVP_PKEY_NEW, ERR_R_MALLOC_FAILURE);
return NULL;
}
ret->type = EVP_PKEY_NONE;
ret->save_type = EVP_PKEY_NONE;
ret->references = 1;
ret->save_parameters = 1;
ret->lock = CRYPTO_THREAD_lock_new();
if (ret->lock == NULL) {
EVPerr(EVP_F_EVP_PKEY_NEW, ERR_R_MALLOC_FAILURE);
OPENSSL_free(ret);
return NULL;
}
return ret;
}
int EVP_PKEY_up_ref(EVP_PKEY *pkey)
{
int i;
if (CRYPTO_UP_REF(&pkey->references, &i, pkey->lock) <= 0)
return 0;
REF_PRINT_COUNT("EVP_PKEY", pkey);
REF_ASSERT_ISNT(i < 2);
return ((i > 1) ? 1 : 0);
}
/*
* Setup a public key ASN1 method and ENGINE from a NID or a string. If pkey
@@ -186,29 +156,29 @@ static int pkey_set_type(EVP_PKEY *pkey, ENGINE *e, int type, const char *str,
if (pkey) {
if (pkey->pkey.ptr)
EVP_PKEY_free_it(pkey);
evp_pkey_free_it(pkey);
/*
* If key type matches and a method exists then this lookup has
* succeeded once so just indicate success.
*/
if ((type == pkey->save_type) && pkey->ameth)
return 1;
#ifndef OPENSSL_NO_ENGINE
# ifndef OPENSSL_NO_ENGINE
/* If we have ENGINEs release them */
ENGINE_finish(pkey->engine);
pkey->engine = NULL;
ENGINE_finish(pkey->pmeth_engine);
pkey->pmeth_engine = NULL;
#endif
# endif
}
if (str)
ameth = EVP_PKEY_asn1_find_str(eptr, str, len);
else
ameth = EVP_PKEY_asn1_find(eptr, type);
#ifndef OPENSSL_NO_ENGINE
# ifndef OPENSSL_NO_ENGINE
if (pkey == NULL && eptr != NULL)
ENGINE_finish(e);
#endif
# endif
if (ameth == NULL) {
EVPerr(EVP_F_PKEY_SET_TYPE, EVP_R_UNSUPPORTED_ALGORITHM);
return 0;
@@ -320,10 +290,10 @@ int EVP_PKEY_get_raw_public_key(const EVP_PKEY *pkey, unsigned char *pub,
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
# ifndef OPENSSL_NO_CMAC
# ifndef OPENSSL_NO_ENGINE
const char *engine_id = e != NULL ? ENGINE_get_id(e) : NULL;
# endif
# endif
const char *cipher_name = EVP_CIPHER_name(cipher);
const OSSL_PROVIDER *prov = EVP_CIPHER_provider(cipher);
OPENSSL_CTX *libctx =
@@ -341,11 +311,11 @@ EVP_PKEY *EVP_PKEY_new_CMAC_key(ENGINE *e, const unsigned char *priv,
goto err;
}
# ifndef OPENSSL_NO_ENGINE
# ifndef OPENSSL_NO_ENGINE
if (engine_id != NULL)
params[paramsn++] =
OSSL_PARAM_construct_utf8_string("engine", (char *)engine_id, 0);
# endif
# endif
params[paramsn++] =
OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_CIPHER,
@@ -368,11 +338,11 @@ EVP_PKEY *EVP_PKEY_new_CMAC_key(ENGINE *e, const unsigned char *priv,
EVP_MAC_CTX_free(cmctx);
EVP_MAC_free(cmac);
return NULL;
#else
# else
EVPerr(EVP_F_EVP_PKEY_NEW_CMAC_KEY,
EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
return NULL;
#endif
# endif
}
int EVP_PKEY_set_type(EVP_PKEY *pkey, int type)
@@ -404,7 +374,7 @@ int EVP_PKEY_set_alias_type(EVP_PKEY *pkey, int type)
return 1;
}
#ifndef OPENSSL_NO_ENGINE
# ifndef OPENSSL_NO_ENGINE
int EVP_PKEY_set1_engine(EVP_PKEY *pkey, ENGINE *e)
{
if (e != NULL) {
@@ -427,7 +397,7 @@ ENGINE *EVP_PKEY_get0_engine(const EVP_PKEY *pkey)
{
return pkey->engine;
}
#endif
# endif
int EVP_PKEY_assign(EVP_PKEY *pkey, int type, void *key)
{
if (pkey == NULL || !EVP_PKEY_set_type(pkey, type))
@@ -453,7 +423,7 @@ const unsigned char *EVP_PKEY_get0_hmac(const EVP_PKEY *pkey, size_t *len)
return os->data;
}
#ifndef OPENSSL_NO_POLY1305
# ifndef OPENSSL_NO_POLY1305
const unsigned char *EVP_PKEY_get0_poly1305(const EVP_PKEY *pkey, size_t *len)
{
ASN1_OCTET_STRING *os = NULL;
@@ -465,9 +435,9 @@ const unsigned char *EVP_PKEY_get0_poly1305(const EVP_PKEY *pkey, size_t *len)
*len = os->length;
return os->data;
}
#endif
# endif
#ifndef OPENSSL_NO_SIPHASH
# ifndef OPENSSL_NO_SIPHASH
const unsigned char *EVP_PKEY_get0_siphash(const EVP_PKEY *pkey, size_t *len)
{
ASN1_OCTET_STRING *os = NULL;
@@ -480,9 +450,9 @@ const unsigned char *EVP_PKEY_get0_siphash(const EVP_PKEY *pkey, size_t *len)
*len = os->length;
return os->data;
}
#endif
# endif
#ifndef OPENSSL_NO_RSA
# ifndef OPENSSL_NO_RSA
int EVP_PKEY_set1_RSA(EVP_PKEY *pkey, RSA *key)
{
int ret = EVP_PKEY_assign_RSA(pkey, key);
@@ -493,7 +463,7 @@ int EVP_PKEY_set1_RSA(EVP_PKEY *pkey, RSA *key)
RSA *EVP_PKEY_get0_RSA(const EVP_PKEY *pkey)
{
if (pkey->type != EVP_PKEY_RSA) {
if (pkey->type != EVP_PKEY_RSA && pkey->type != EVP_PKEY_RSA_PSS) {
EVPerr(EVP_F_EVP_PKEY_GET0_RSA, EVP_R_EXPECTING_AN_RSA_KEY);
return NULL;
}
@@ -507,9 +477,9 @@ RSA *EVP_PKEY_get1_RSA(EVP_PKEY *pkey)
RSA_up_ref(ret);
return ret;
}
#endif
# endif
#ifndef OPENSSL_NO_DSA
# ifndef OPENSSL_NO_DSA
int EVP_PKEY_set1_DSA(EVP_PKEY *pkey, DSA *key)
{
int ret = EVP_PKEY_assign_DSA(pkey, key);
@@ -534,9 +504,9 @@ DSA *EVP_PKEY_get1_DSA(EVP_PKEY *pkey)
DSA_up_ref(ret);
return ret;
}
#endif
# endif
#ifndef OPENSSL_NO_EC
# ifndef OPENSSL_NO_EC
int EVP_PKEY_set1_EC_KEY(EVP_PKEY *pkey, EC_KEY *key)
{
@@ -562,13 +532,15 @@ EC_KEY *EVP_PKEY_get1_EC_KEY(EVP_PKEY *pkey)
EC_KEY_up_ref(ret);
return ret;
}
#endif
# endif
#ifndef OPENSSL_NO_DH
# ifndef OPENSSL_NO_DH
int EVP_PKEY_set1_DH(EVP_PKEY *pkey, DH *key)
{
int ret = EVP_PKEY_assign_DH(pkey, key);
int type = DH_get0_q(key) == NULL ? EVP_PKEY_DH : EVP_PKEY_DHX;
int ret = EVP_PKEY_assign(pkey, type, key);
if (ret)
DH_up_ref(key);
return ret;
@@ -590,7 +562,7 @@ DH *EVP_PKEY_get1_DH(EVP_PKEY *pkey)
DH_up_ref(ret);
return ret;
}
#endif
# endif
int EVP_PKEY_type(int type)
{
@@ -602,9 +574,9 @@ int EVP_PKEY_type(int type)
ret = ameth->pkey_id;
else
ret = NID_undef;
#ifndef OPENSSL_NO_ENGINE
# ifndef OPENSSL_NO_ENGINE
ENGINE_finish(e);
#endif
# endif
return ret;
}
@@ -618,75 +590,104 @@ int EVP_PKEY_base_id(const EVP_PKEY *pkey)
return EVP_PKEY_type(pkey->type);
}
void EVP_PKEY_free(EVP_PKEY *x)
static int print_reset_indent(BIO **out, int pop_f_prefix, long saved_indent)
{
int i;
BIO_set_indent(*out, saved_indent);
if (pop_f_prefix) {
BIO *next = BIO_pop(*out);
if (x == NULL)
return;
CRYPTO_DOWN_REF(&x->references, &i, x->lock);
REF_PRINT_COUNT("EVP_PKEY", x);
if (i > 0)
return;
REF_ASSERT_ISNT(i < 0);
EVP_PKEY_free_it(x);
CRYPTO_THREAD_lock_free(x->lock);
sk_X509_ATTRIBUTE_pop_free(x->attributes, X509_ATTRIBUTE_free);
OPENSSL_free(x);
BIO_free(*out);
*out = next;
}
return 1;
}
static void EVP_PKEY_free_it(EVP_PKEY *x)
static int print_set_indent(BIO **out, int *pop_f_prefix, long *saved_indent,
long indent)
{
/* internal function; x is never NULL */
*pop_f_prefix = 0;
*saved_indent = 0;
if (indent > 0) {
long i = BIO_get_indent(*out);
evp_keymgmt_clear_pkey_cache(x);
if (x->ameth && x->ameth->pkey_free) {
x->ameth->pkey_free(x);
x->pkey.ptr = NULL;
*saved_indent = (i < 0 ? 0 : i);
if (BIO_set_indent(*out, indent) <= 0) {
if ((*out = BIO_push(BIO_new(BIO_f_prefix()), *out)) == NULL)
return 0;
*pop_f_prefix = 1;
}
if (BIO_set_indent(*out, indent) <= 0) {
print_reset_indent(out, *pop_f_prefix, *saved_indent);
return 0;
}
}
#ifndef OPENSSL_NO_ENGINE
ENGINE_finish(x->engine);
x->engine = NULL;
ENGINE_finish(x->pmeth_engine);
x->pmeth_engine = NULL;
#endif
return 1;
}
static int unsup_alg(BIO *out, const EVP_PKEY *pkey, int indent,
const char *kstr)
{
BIO_indent(out, indent, 128);
BIO_printf(out, "%s algorithm \"%s\" unsupported\n",
kstr, OBJ_nid2ln(pkey->type));
return 1;
return BIO_indent(out, indent, 128)
&& BIO_printf(out, "%s algorithm \"%s\" unsupported\n",
kstr, OBJ_nid2ln(pkey->type)) > 0;
}
static int print_pkey(const EVP_PKEY *pkey, BIO *out, int indent,
const char *propquery /* For provided serialization */,
int (*legacy_print)(BIO *out, const EVP_PKEY *pkey,
int indent, ASN1_PCTX *pctx),
ASN1_PCTX *legacy_pctx /* For legacy print */)
{
int pop_f_prefix;
long saved_indent;
OSSL_SERIALIZER_CTX *ctx = NULL;
int ret = -2; /* default to unsupported */
if (!print_set_indent(&out, &pop_f_prefix, &saved_indent, indent))
return 0;
ctx = OSSL_SERIALIZER_CTX_new_by_EVP_PKEY(pkey, propquery);
if (OSSL_SERIALIZER_CTX_get_serializer(ctx) != NULL)
ret = OSSL_SERIALIZER_to_bio(ctx, out);
OSSL_SERIALIZER_CTX_free(ctx);
if (ret != -2)
goto end;
/* legacy fallback */
if (legacy_print != NULL)
ret = legacy_print(out, pkey, 0, legacy_pctx);
else
ret = unsup_alg(out, pkey, 0, "Public Key");
end:
print_reset_indent(&out, pop_f_prefix, saved_indent);
return ret;
}
int EVP_PKEY_print_public(BIO *out, const EVP_PKEY *pkey,
int indent, ASN1_PCTX *pctx)
{
if (pkey->ameth && pkey->ameth->pub_print)
return pkey->ameth->pub_print(out, pkey, indent, pctx);
return unsup_alg(out, pkey, indent, "Public Key");
return print_pkey(pkey, out, indent, OSSL_SERIALIZER_PUBKEY_TO_TEXT_PQ,
(pkey->ameth != NULL ? pkey->ameth->pub_print : NULL),
pctx);
}
int EVP_PKEY_print_private(BIO *out, const EVP_PKEY *pkey,
int indent, ASN1_PCTX *pctx)
{
if (pkey->ameth && pkey->ameth->priv_print)
return pkey->ameth->priv_print(out, pkey, indent, pctx);
return unsup_alg(out, pkey, indent, "Private Key");
return print_pkey(pkey, out, indent, OSSL_SERIALIZER_PrivateKey_TO_TEXT_PQ,
(pkey->ameth != NULL ? pkey->ameth->priv_print : NULL),
pctx);
}
int EVP_PKEY_print_params(BIO *out, const EVP_PKEY *pkey,
int indent, ASN1_PCTX *pctx)
{
if (pkey->ameth && pkey->ameth->param_print)
return pkey->ameth->param_print(out, pkey, indent, pctx);
return unsup_alg(out, pkey, indent, "Parameters");
return print_pkey(pkey, out, indent, OSSL_SERIALIZER_Parameters_TO_TEXT_PQ,
(pkey->ameth != NULL ? pkey->ameth->param_print : NULL),
pctx);
}
static int evp_pkey_asn1_ctrl(EVP_PKEY *pkey, int op, int arg1, void *arg2)
@@ -740,3 +741,89 @@ size_t EVP_PKEY_get1_tls_encodedpoint(EVP_PKEY *pkey, unsigned char **ppt)
return 0;
return rv;
}
#endif /* FIPS_MODE */
/*- All methods below can also be used in FIPS_MODE */
EVP_PKEY *EVP_PKEY_new(void)
{
EVP_PKEY *ret = OPENSSL_zalloc(sizeof(*ret));
if (ret == NULL) {
EVPerr(EVP_F_EVP_PKEY_NEW, ERR_R_MALLOC_FAILURE);
return NULL;
}
ret->type = EVP_PKEY_NONE;
ret->save_type = EVP_PKEY_NONE;
ret->references = 1;
ret->save_parameters = 1;
ret->lock = CRYPTO_THREAD_lock_new();
if (ret->lock == NULL) {
EVPerr(EVP_F_EVP_PKEY_NEW, ERR_R_MALLOC_FAILURE);
OPENSSL_free(ret);
return NULL;
}
return ret;
}
int EVP_PKEY_up_ref(EVP_PKEY *pkey)
{
int i;
if (CRYPTO_UP_REF(&pkey->references, &i, pkey->lock) <= 0)
return 0;
REF_PRINT_COUNT("EVP_PKEY", pkey);
REF_ASSERT_ISNT(i < 2);
return ((i > 1) ? 1 : 0);
}
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;
}
#if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODE)
ENGINE_finish(x->engine);
x->engine = NULL;
ENGINE_finish(x->pmeth_engine);
x->pmeth_engine = NULL;
#endif
}
void EVP_PKEY_free(EVP_PKEY *x)
{
int i;
if (x == NULL)
return;
CRYPTO_DOWN_REF(&x->references, &i, x->lock);
REF_PRINT_COUNT("EVP_PKEY", x);
if (i > 0)
return;
REF_ASSERT_ISNT(i < 0);
evp_pkey_free_it(x);
CRYPTO_THREAD_lock_free(x->lock);
#ifndef FIPS_MODE
sk_X509_ATTRIBUTE_pop_free(x->attributes, X509_ATTRIBUTE_free);
#endif
OPENSSL_free(x);
}
int EVP_PKEY_size(const EVP_PKEY *pkey)
{
if (pkey != NULL) {
if (pkey->ameth == NULL)
return pkey->cache.size;
else if (pkey->ameth->pkey_size != NULL)
return pkey->ameth->pkey_size(pkey);
}
return 0;
}
+310 -568
View File
@@ -16,341 +16,11 @@
#include "internal/provider.h"
#include "evp_local.h"
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 digsignfncnt = 0, digverifyfncnt = 0;
int gparamfncnt = 0, sparamfncnt = 0, gmdparamfncnt = 0, smdparamfncnt = 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_DIGEST_SIGN_INIT:
if (signature->digest_sign_init != NULL)
break;
signature->digest_sign_init
= OSSL_get_OP_signature_digest_sign_init(fns);
digsignfncnt++;
break;
case OSSL_FUNC_SIGNATURE_DIGEST_SIGN_UPDATE:
if (signature->digest_sign_update != NULL)
break;
signature->digest_sign_update
= OSSL_get_OP_signature_digest_sign_update(fns);
digsignfncnt++;
break;
case OSSL_FUNC_SIGNATURE_DIGEST_SIGN_FINAL:
if (signature->digest_sign_final != NULL)
break;
signature->digest_sign_final
= OSSL_get_OP_signature_digest_sign_final(fns);
digsignfncnt++;
break;
case OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_INIT:
if (signature->digest_verify_init != NULL)
break;
signature->digest_verify_init
= OSSL_get_OP_signature_digest_verify_init(fns);
digverifyfncnt++;
break;
case OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_UPDATE:
if (signature->digest_verify_update != NULL)
break;
signature->digest_verify_update
= OSSL_get_OP_signature_digest_verify_update(fns);
digverifyfncnt++;
break;
case OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_FINAL:
if (signature->digest_verify_final != NULL)
break;
signature->digest_verify_final
= OSSL_get_OP_signature_digest_verify_final(fns);
digverifyfncnt++;
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;
case OSSL_FUNC_SIGNATURE_GET_CTX_MD_PARAMS:
if (signature->get_ctx_md_params != NULL)
break;
signature->get_ctx_md_params
= OSSL_get_OP_signature_get_ctx_md_params(fns);
gmdparamfncnt++;
break;
case OSSL_FUNC_SIGNATURE_GETTABLE_CTX_MD_PARAMS:
if (signature->gettable_ctx_md_params != NULL)
break;
signature->gettable_ctx_md_params
= OSSL_get_OP_signature_gettable_ctx_md_params(fns);
gmdparamfncnt++;
break;
case OSSL_FUNC_SIGNATURE_SET_CTX_MD_PARAMS:
if (signature->set_ctx_md_params != NULL)
break;
signature->set_ctx_md_params
= OSSL_get_OP_signature_set_ctx_md_params(fns);
smdparamfncnt++;
break;
case OSSL_FUNC_SIGNATURE_SETTABLE_CTX_MD_PARAMS:
if (signature->settable_ctx_md_params != NULL)
break;
signature->settable_ctx_md_params
= OSSL_get_OP_signature_settable_ctx_md_params(fns);
smdparamfncnt++;
break;
}
}
if (ctxfncnt != 2
|| (signfncnt == 0
&& verifyfncnt == 0
&& verifyrecfncnt == 0
&& digsignfncnt == 0
&& digverifyfncnt == 0)
|| (signfncnt != 0 && signfncnt != 2)
|| (verifyfncnt != 0 && verifyfncnt != 2)
|| (verifyrecfncnt != 0 && verifyrecfncnt != 2)
|| (digsignfncnt != 0 && digsignfncnt != 3)
|| (digverifyfncnt != 0 && digverifyfncnt != 3)
|| (gparamfncnt != 0 && gparamfncnt != 2)
|| (sparamfncnt != 0 && sparamfncnt != 2)
|| (gmdparamfncnt != 0 && gmdparamfncnt != 2)
|| (smdparamfncnt != 0 && smdparamfncnt != 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 set of
* "signature" functions:
* (sign_init, sign) or
* (verify_init verify) or
* (verify_recover_init, verify_recover) or
* (digest_sign_init, digest_sign_update, digest_sign_final) or
* (digest_verify_init, digest_verify_update, digest_verify_final).
*
* 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 same rules
* apply to the "md_params" functions. 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);
}
int EVP_SIGNATURE_is_a(const EVP_SIGNATURE *signature, const char *name)
{
return evp_is_a(signature->prov, signature->name_id, name);
}
int EVP_SIGNATURE_number(const EVP_SIGNATURE *signature)
{
return signature->name_id;
}
void EVP_SIGNATURE_do_all_provided(OPENSSL_CTX *libctx,
void (*fn)(EVP_SIGNATURE *signature,
void *arg),
void *arg)
{
struct keymgmt_data_st keymgmt_data;
keymgmt_data.ctx = libctx;
keymgmt_data.properties = NULL;
evp_generic_do_all(libctx, OSSL_OP_SIGNATURE,
(void (*)(void *, void *))fn, arg,
evp_signature_from_dispatch, &keymgmt_data,
(void (*)(void *))EVP_SIGNATURE_free);
}
void EVP_SIGNATURE_names_do_all(const EVP_SIGNATURE *signature,
void (*fn)(const char *name, void *data),
void *data)
{
if (signature->prov != NULL)
evp_names_do_all(signature->prov, signature->name_id, fn, data);
}
static int evp_pkey_signature_init(EVP_PKEY_CTX *ctx, EVP_SIGNATURE *signature,
int operation)
static int evp_pkey_asym_cipher_init(EVP_PKEY_CTX *ctx, int operation)
{
int ret = 0;
void *provkey = NULL;
EVP_ASYM_CIPHER *cipher = NULL;
if (ctx == NULL) {
EVPerr(0, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
@@ -360,77 +30,79 @@ static int evp_pkey_signature_init(EVP_PKEY_CTX *ctx, EVP_SIGNATURE *signature,
evp_pkey_ctx_free_old_ops(ctx);
ctx->operation = operation;
if (ctx->engine != NULL)
if (ctx->keytype == NULL || 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;
if (ctx->keymgmt == NULL)
ctx->keymgmt =
EVP_KEYMGMT_fetch(ctx->libctx, ctx->keytype, ctx->propquery);
if (ctx->keymgmt != NULL) {
const char *supported_ciph = NULL;
if (ctx->keymgmt->query_operation_name != NULL)
supported_ciph =
ctx->keymgmt->query_operation_name(OSSL_OP_ASYM_CIPHER);
/*
* TODO(3.0): Check for legacy handling. Remove this once all all
* algorithms are moved to providers.
* If we didn't get a supported ciph, assume there is one with the
* same name as the key type.
*/
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 (supported_ciph == NULL)
supported_ciph = ctx->keytype;
if (signature == NULL) {
EVPerr(0, EVP_R_INITIALIZATION_ERROR);
goto err;
}
/*
* Because we cleared out old ops, we shouldn't need to worry about
* checking if cipher is already there.
*/
cipher =
EVP_ASYM_CIPHER_fetch(ctx->libctx, supported_ciph, ctx->propquery);
}
ctx->op.sig.signature = signature;
if (ctx->keymgmt == NULL
|| cipher == NULL
|| (EVP_KEYMGMT_provider(ctx->keymgmt)
!= EVP_ASYM_CIPHER_provider(cipher))) {
/*
* We don't have the full support we need with provided methods,
* let's go see if legacy does. Also, we don't need to free
* ctx->keymgmt here, as it's not necessarily tied to this
* operation. It will be freed by EVP_PKEY_CTX_free().
*/
EVP_ASYM_CIPHER_free(cipher);
goto legacy;
}
ctx->op.ciph.cipher = cipher;
if (ctx->pkey != NULL) {
provkey =
evp_keymgmt_export_to_provider(ctx->pkey, signature->keymgmt, 0);
if (provkey == NULL) {
EVPerr(0, EVP_R_INITIALIZATION_ERROR);
goto err;
}
provkey = evp_keymgmt_export_to_provider(ctx->pkey, ctx->keymgmt, 0);
/* If export failed, legacy may be able to pick it up */
if (provkey == NULL)
goto legacy;
}
ctx->op.sig.sigprovctx = signature->newctx(ossl_provider_ctx(signature->prov));
if (ctx->op.sig.sigprovctx == NULL) {
ctx->op.ciph.ciphprovctx = cipher->newctx(ossl_provider_ctx(cipher->prov));
if (ctx->op.ciph.ciphprovctx == 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) {
case EVP_PKEY_OP_ENCRYPT:
if (cipher->encrypt_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);
ret = cipher->encrypt_init(ctx->op.ciph.ciphprovctx, provkey);
break;
case EVP_PKEY_OP_VERIFY:
if (signature->verify_init == NULL) {
case EVP_PKEY_OP_DECRYPT:
if (cipher->decrypt_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);
ret = cipher->decrypt_init(ctx->op.ciph.ciphprovctx, provkey);
break;
default:
EVPerr(0, EVP_R_INITIALIZATION_ERROR);
@@ -438,244 +110,314 @@ static int evp_pkey_signature_init(EVP_PKEY_CTX *ctx, EVP_SIGNATURE *signature,
}
if (ret <= 0) {
signature->freectx(ctx->op.sig.sigprovctx);
ctx->op.sig.sigprovctx = NULL;
cipher->freectx(ctx->op.ciph.ciphprovctx);
ctx->op.ciph.ciphprovctx = 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)) {
if (ctx->pmeth == NULL || ctx->pmeth->encrypt == 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)
switch(ctx->operation) {
case EVP_PKEY_OP_ENCRYPT:
if (ctx->pmeth->encrypt_init == NULL)
return 1;
ret = ctx->pmeth->sign_init(ctx);
ret = ctx->pmeth->encrypt_init(ctx);
break;
case EVP_PKEY_OP_VERIFY:
if (ctx->pmeth->verify_init == NULL)
case EVP_PKEY_OP_DECRYPT:
if (ctx->pmeth->decrypt_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);
ret = ctx->pmeth->decrypt_init(ctx);
break;
default:
EVPerr(0, EVP_R_INITIALIZATION_ERROR);
goto err;
ret = -1;
}
if (ret <= 0)
goto err;
return ret;
err:
ctx->operation = EVP_PKEY_OP_UNDEFINED;
if (ret <= 0)
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)
{
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)
{
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(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)
{
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)
{
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(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)
{
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)
{
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(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);
}
int EVP_PKEY_encrypt_init(EVP_PKEY_CTX *ctx)
{
int ret;
if (!ctx || !ctx->pmeth || !ctx->pmeth->encrypt) {
EVPerr(EVP_F_EVP_PKEY_ENCRYPT_INIT,
EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
return -2;
}
ctx->operation = EVP_PKEY_OP_ENCRYPT;
if (!ctx->pmeth->encrypt_init)
return 1;
ret = ctx->pmeth->encrypt_init(ctx);
if (ret <= 0)
ctx->operation = EVP_PKEY_OP_UNDEFINED;
return ret;
return evp_pkey_asym_cipher_init(ctx, EVP_PKEY_OP_ENCRYPT);
}
int EVP_PKEY_encrypt(EVP_PKEY_CTX *ctx,
unsigned char *out, size_t *outlen,
const unsigned char *in, size_t inlen)
{
if (!ctx || !ctx->pmeth || !ctx->pmeth->encrypt) {
int ret;
if (ctx == NULL) {
EVPerr(0, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
return -2;
}
if (ctx->operation != EVP_PKEY_OP_ENCRYPT) {
EVPerr(0, EVP_R_OPERATON_NOT_INITIALIZED);
return -1;
}
if (ctx->op.ciph.ciphprovctx == NULL)
goto legacy;
ret = ctx->op.ciph.cipher->encrypt(ctx->op.ciph.ciphprovctx, out, outlen,
(out == NULL ? 0 : *outlen), in, inlen);
return ret;
legacy:
if (ctx->pmeth == NULL || ctx->pmeth->encrypt == NULL) {
EVPerr(EVP_F_EVP_PKEY_ENCRYPT,
EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
return -2;
}
if (ctx->operation != EVP_PKEY_OP_ENCRYPT) {
EVPerr(EVP_F_EVP_PKEY_ENCRYPT, EVP_R_OPERATON_NOT_INITIALIZED);
return -1;
}
M_check_autoarg(ctx, out, outlen, EVP_F_EVP_PKEY_ENCRYPT)
return ctx->pmeth->encrypt(ctx, out, outlen, in, inlen);
}
int EVP_PKEY_decrypt_init(EVP_PKEY_CTX *ctx)
{
int ret;
if (!ctx || !ctx->pmeth || !ctx->pmeth->decrypt) {
EVPerr(EVP_F_EVP_PKEY_DECRYPT_INIT,
EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
return -2;
}
ctx->operation = EVP_PKEY_OP_DECRYPT;
if (!ctx->pmeth->decrypt_init)
return 1;
ret = ctx->pmeth->decrypt_init(ctx);
if (ret <= 0)
ctx->operation = EVP_PKEY_OP_UNDEFINED;
return ret;
return evp_pkey_asym_cipher_init(ctx, EVP_PKEY_OP_DECRYPT);
}
int EVP_PKEY_decrypt(EVP_PKEY_CTX *ctx,
unsigned char *out, size_t *outlen,
const unsigned char *in, size_t inlen)
{
if (!ctx || !ctx->pmeth || !ctx->pmeth->decrypt) {
int ret;
if (ctx == NULL) {
EVPerr(0, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
return -2;
}
if (ctx->operation != EVP_PKEY_OP_DECRYPT) {
EVPerr(0, EVP_R_OPERATON_NOT_INITIALIZED);
return -1;
}
if (ctx->op.ciph.ciphprovctx == NULL)
goto legacy;
ret = ctx->op.ciph.cipher->decrypt(ctx->op.ciph.ciphprovctx, out, outlen,
(out == NULL ? 0 : *outlen), in, inlen);
return ret;
legacy:
if (ctx->pmeth == NULL || ctx->pmeth->decrypt == NULL) {
EVPerr(EVP_F_EVP_PKEY_DECRYPT,
EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
return -2;
}
if (ctx->operation != EVP_PKEY_OP_DECRYPT) {
EVPerr(EVP_F_EVP_PKEY_DECRYPT, EVP_R_OPERATON_NOT_INITIALIZED);
return -1;
}
M_check_autoarg(ctx, out, outlen, EVP_F_EVP_PKEY_DECRYPT)
return ctx->pmeth->decrypt(ctx, out, outlen, in, inlen);
}
static EVP_ASYM_CIPHER *evp_asym_cipher_new(OSSL_PROVIDER *prov)
{
EVP_ASYM_CIPHER *cipher = OPENSSL_zalloc(sizeof(EVP_ASYM_CIPHER));
if (cipher == NULL) {
ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE);
return NULL;
}
cipher->lock = CRYPTO_THREAD_lock_new();
if (cipher->lock == NULL) {
ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE);
OPENSSL_free(cipher);
return NULL;
}
cipher->prov = prov;
ossl_provider_up_ref(prov);
cipher->refcnt = 1;
return cipher;
}
static void *evp_asym_cipher_from_dispatch(int name_id,
const OSSL_DISPATCH *fns,
OSSL_PROVIDER *prov)
{
EVP_ASYM_CIPHER *cipher = NULL;
int ctxfncnt = 0, encfncnt = 0, decfncnt = 0;
int gparamfncnt = 0, sparamfncnt = 0;
if ((cipher = evp_asym_cipher_new(prov)) == NULL) {
ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE);
goto err;
}
cipher->name_id = name_id;
for (; fns->function_id != 0; fns++) {
switch (fns->function_id) {
case OSSL_FUNC_ASYM_CIPHER_NEWCTX:
if (cipher->newctx != NULL)
break;
cipher->newctx = OSSL_get_OP_asym_cipher_newctx(fns);
ctxfncnt++;
break;
case OSSL_FUNC_ASYM_CIPHER_ENCRYPT_INIT:
if (cipher->encrypt_init != NULL)
break;
cipher->encrypt_init = OSSL_get_OP_asym_cipher_encrypt_init(fns);
encfncnt++;
break;
case OSSL_FUNC_ASYM_CIPHER_ENCRYPT:
if (cipher->encrypt != NULL)
break;
cipher->encrypt = OSSL_get_OP_asym_cipher_encrypt(fns);
encfncnt++;
break;
case OSSL_FUNC_ASYM_CIPHER_DECRYPT_INIT:
if (cipher->decrypt_init != NULL)
break;
cipher->decrypt_init = OSSL_get_OP_asym_cipher_decrypt_init(fns);
decfncnt++;
break;
case OSSL_FUNC_ASYM_CIPHER_DECRYPT:
if (cipher->decrypt != NULL)
break;
cipher->decrypt = OSSL_get_OP_asym_cipher_decrypt(fns);
decfncnt++;
break;
case OSSL_FUNC_ASYM_CIPHER_FREECTX:
if (cipher->freectx != NULL)
break;
cipher->freectx = OSSL_get_OP_asym_cipher_freectx(fns);
ctxfncnt++;
break;
case OSSL_FUNC_ASYM_CIPHER_DUPCTX:
if (cipher->dupctx != NULL)
break;
cipher->dupctx = OSSL_get_OP_asym_cipher_dupctx(fns);
break;
case OSSL_FUNC_ASYM_CIPHER_GET_CTX_PARAMS:
if (cipher->get_ctx_params != NULL)
break;
cipher->get_ctx_params
= OSSL_get_OP_asym_cipher_get_ctx_params(fns);
gparamfncnt++;
break;
case OSSL_FUNC_ASYM_CIPHER_GETTABLE_CTX_PARAMS:
if (cipher->gettable_ctx_params != NULL)
break;
cipher->gettable_ctx_params
= OSSL_get_OP_asym_cipher_gettable_ctx_params(fns);
gparamfncnt++;
break;
case OSSL_FUNC_ASYM_CIPHER_SET_CTX_PARAMS:
if (cipher->set_ctx_params != NULL)
break;
cipher->set_ctx_params
= OSSL_get_OP_asym_cipher_set_ctx_params(fns);
sparamfncnt++;
break;
case OSSL_FUNC_ASYM_CIPHER_SETTABLE_CTX_PARAMS:
if (cipher->settable_ctx_params != NULL)
break;
cipher->settable_ctx_params
= OSSL_get_OP_asym_cipher_settable_ctx_params(fns);
sparamfncnt++;
break;
}
}
if (ctxfncnt != 2
|| (encfncnt != 0 && encfncnt != 2)
|| (decfncnt != 0 && decfncnt != 2)
|| (encfncnt != 2 && decfncnt != 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
* "cipher" functions: (encrypt_init, encrypt) or
* (decrypt_init decrypt). 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 cipher;
err:
EVP_ASYM_CIPHER_free(cipher);
return NULL;
}
void EVP_ASYM_CIPHER_free(EVP_ASYM_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_ASYM_CIPHER_up_ref(EVP_ASYM_CIPHER *cipher)
{
int ref = 0;
CRYPTO_UP_REF(&cipher->refcnt, &ref, cipher->lock);
return 1;
}
OSSL_PROVIDER *EVP_ASYM_CIPHER_provider(const EVP_ASYM_CIPHER *cipher)
{
return cipher->prov;
}
EVP_ASYM_CIPHER *EVP_ASYM_CIPHER_fetch(OPENSSL_CTX *ctx, const char *algorithm,
const char *properties)
{
return evp_generic_fetch(ctx, OSSL_OP_ASYM_CIPHER, algorithm, properties,
evp_asym_cipher_from_dispatch,
(int (*)(void *))EVP_ASYM_CIPHER_up_ref,
(void (*)(void *))EVP_ASYM_CIPHER_free);
}
int EVP_ASYM_CIPHER_is_a(const EVP_ASYM_CIPHER *cipher, const char *name)
{
return evp_is_a(cipher->prov, cipher->name_id, NULL, name);
}
int EVP_ASYM_CIPHER_number(const EVP_ASYM_CIPHER *cipher)
{
return cipher->name_id;
}
void EVP_ASYM_CIPHER_do_all_provided(OPENSSL_CTX *libctx,
void (*fn)(EVP_ASYM_CIPHER *cipher,
void *arg),
void *arg)
{
evp_generic_do_all(libctx, OSSL_OP_ASYM_CIPHER,
(void (*)(void *, void *))fn, arg,
evp_asym_cipher_from_dispatch,
(void (*)(void *))EVP_ASYM_CIPHER_free);
}
void EVP_ASYM_CIPHER_names_do_all(const EVP_ASYM_CIPHER *cipher,
void (*fn)(const char *name, void *data),
void *data)
{
if (cipher->prov != NULL)
evp_names_do_all(cipher->prov, cipher->name_id, fn, data);
}
+92
View File
@@ -15,7 +15,9 @@
#include "crypto/bn.h"
#include "crypto/asn1.h"
#include "crypto/evp.h"
#include "evp_local.h"
#ifndef FIPS_MODE
int EVP_PKEY_paramgen_init(EVP_PKEY_CTX *ctx)
{
int ret;
@@ -237,3 +239,93 @@ int EVP_PKEY_param_check(EVP_PKEY_CTX *ctx)
return pkey->ameth->pkey_param_check(pkey);
}
#endif /* FIPS_MODE */
/*- All methods below can also be used in FIPS_MODE */
static int fromdata_init(EVP_PKEY_CTX *ctx, int operation)
{
if (ctx == NULL || ctx->keytype == NULL)
goto not_supported;
evp_pkey_ctx_free_old_ops(ctx);
ctx->operation = operation;
if (ctx->keymgmt == NULL)
ctx->keymgmt = EVP_KEYMGMT_fetch(ctx->libctx, ctx->keytype,
ctx->propquery);
if (ctx->keymgmt == NULL)
goto not_supported;
return 1;
not_supported:
ctx->operation = EVP_PKEY_OP_UNDEFINED;
ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
return -2;
}
int EVP_PKEY_param_fromdata_init(EVP_PKEY_CTX *ctx)
{
return fromdata_init(ctx, EVP_PKEY_OP_PARAMFROMDATA);
}
int EVP_PKEY_key_fromdata_init(EVP_PKEY_CTX *ctx)
{
return fromdata_init(ctx, EVP_PKEY_OP_KEYFROMDATA);
}
int EVP_PKEY_fromdata(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey, OSSL_PARAM params[])
{
void *provdata = NULL;
if (ctx == NULL || (ctx->operation & EVP_PKEY_OP_TYPE_FROMDATA) == 0) {
ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
return -2;
}
if (ppkey == NULL)
return -1;
if (*ppkey == NULL)
*ppkey = EVP_PKEY_new();
if (*ppkey == NULL) {
ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE);
return -1;
}
provdata =
evp_keymgmt_fromdata(*ppkey, ctx->keymgmt, params,
ctx->operation == EVP_PKEY_OP_PARAMFROMDATA);
if (provdata == NULL)
return 0;
/* provdata is cached in *ppkey, so we need not bother with it further */
return 1;
}
/*
* TODO(3.0) Re-evaluate the names, it's possible that we find these to be
* better:
*
* EVP_PKEY_param_settable()
* EVP_PKEY_param_gettable()
*/
const OSSL_PARAM *EVP_PKEY_param_fromdata_settable(EVP_PKEY_CTX *ctx)
{
/* We call fromdata_init to get ctx->keymgmt populated */
if (fromdata_init(ctx, EVP_PKEY_OP_UNDEFINED))
return evp_keymgmt_importdomparam_types(ctx->keymgmt);
return NULL;
}
const OSSL_PARAM *EVP_PKEY_key_fromdata_settable(EVP_PKEY_CTX *ctx)
{
/* We call fromdata_init to get ctx->keymgmt populated */
if (fromdata_init(ctx, EVP_PKEY_OP_UNDEFINED))
return evp_keymgmt_importdomparam_types(ctx->keymgmt);
return NULL;
}
+341 -110
View File
@@ -15,6 +15,7 @@
#include <openssl/x509v3.h>
#include <openssl/core_names.h>
#include <openssl/dh.h>
#include <openssl/rsa.h>
#include "internal/cryptlib.h"
#include "crypto/asn1.h"
#include "crypto/evp.h"
@@ -22,6 +23,8 @@
#include "internal/provider.h"
#include "evp_local.h"
#ifndef FIPS_MODE
typedef const EVP_PKEY_METHOD *(*pmeth_fn)(void);
typedef int sk_cmp_fn_type(const char *const *a, const char *const *b);
@@ -29,50 +32,50 @@ static STACK_OF(EVP_PKEY_METHOD) *app_pkey_methods = NULL;
/* This array needs to be in order of NIDs */
static pmeth_fn standard_methods[] = {
#ifndef OPENSSL_NO_RSA
# ifndef OPENSSL_NO_RSA
rsa_pkey_method,
#endif
#ifndef OPENSSL_NO_DH
# endif
# ifndef OPENSSL_NO_DH
dh_pkey_method,
#endif
#ifndef OPENSSL_NO_DSA
# endif
# ifndef OPENSSL_NO_DSA
dsa_pkey_method,
#endif
#ifndef OPENSSL_NO_EC
# endif
# ifndef OPENSSL_NO_EC
ec_pkey_method,
#endif
# endif
hmac_pkey_method,
#ifndef OPENSSL_NO_CMAC
# ifndef OPENSSL_NO_CMAC
cmac_pkey_method,
#endif
#ifndef OPENSSL_NO_RSA
# endif
# ifndef OPENSSL_NO_RSA
rsa_pss_pkey_method,
#endif
#ifndef OPENSSL_NO_DH
# endif
# ifndef OPENSSL_NO_DH
dhx_pkey_method,
#endif
#ifndef OPENSSL_NO_SCRYPT
# endif
# ifndef OPENSSL_NO_SCRYPT
scrypt_pkey_method,
#endif
# endif
tls1_prf_pkey_method,
#ifndef OPENSSL_NO_EC
# ifndef OPENSSL_NO_EC
ecx25519_pkey_method,
ecx448_pkey_method,
#endif
# endif
hkdf_pkey_method,
#ifndef OPENSSL_NO_POLY1305
# ifndef OPENSSL_NO_POLY1305
poly1305_pkey_method,
#endif
#ifndef OPENSSL_NO_SIPHASH
# endif
# ifndef OPENSSL_NO_SIPHASH
siphash_pkey_method,
#endif
#ifndef OPENSSL_NO_EC
# endif
# ifndef OPENSSL_NO_EC
ed25519_pkey_method,
ed448_pkey_method,
#endif
#ifndef OPENSSL_NO_SM2
# endif
# ifndef OPENSSL_NO_SM2
sm2_pkey_method,
#endif
# endif
};
DECLARE_OBJ_BSEARCH_CMP_FN(const EVP_PKEY_METHOD *, pmeth_fn, pmeth_func);
@@ -111,9 +114,27 @@ const EVP_PKEY_METHOD *EVP_PKEY_meth_find(int type)
return (**ret)();
}
static EVP_PKEY_CTX *int_ctx_new(EVP_PKEY *pkey, ENGINE *e,
EVP_PKEY_METHOD *EVP_PKEY_meth_new(int id, int flags)
{
EVP_PKEY_METHOD *pmeth;
pmeth = OPENSSL_zalloc(sizeof(*pmeth));
if (pmeth == NULL) {
EVPerr(EVP_F_EVP_PKEY_METH_NEW, ERR_R_MALLOC_FAILURE);
return NULL;
}
pmeth->pkey_id = id;
pmeth->flags = flags | EVP_PKEY_FLAG_DYNAMIC;
return pmeth;
}
#endif /* FIPS_MODE */
static EVP_PKEY_CTX *int_ctx_new(OPENSSL_CTX *libctx,
EVP_PKEY *pkey, ENGINE *e,
const char *name, const char *propquery,
int id)
{
EVP_PKEY_CTX *ret;
const EVP_PKEY_METHOD *pmeth = NULL;
@@ -125,16 +146,59 @@ static EVP_PKEY_CTX *int_ctx_new(EVP_PKEY *pkey, ENGINE *e,
if (pkey == NULL && e == NULL && id == -1)
goto common;
/*
* If the key doesn't contain anything legacy, then it must be provided,
* so we extract the necessary information and use that.
*/
if (pkey != NULL && pkey->ameth == NULL) {
/* If we have an engine, something went wrong somewhere... */
if (!ossl_assert(e == NULL))
return NULL;
name = evp_first_name(pkey->pkeys[0].keymgmt->prov,
pkey->pkeys[0].keymgmt->name_id);
/*
* TODO: I wonder if the EVP_PKEY should have the name and propquery
* that were used when building it.... /RL
*/
goto common;
}
#ifndef FIPS_MODE
/* TODO(3.0) Legacy code should be removed when all is provider based */
/* BEGIN legacy */
if (id == -1) {
if (pkey == NULL)
return 0;
return NULL;
id = pkey->type;
}
name = OBJ_nid2sn(id);
/*
* Here, we extract what information we can for the purpose of
* supporting usage with implementations from providers, to make
* for a smooth transition from legacy stuff to provider based stuff.
*
* If an engine is given, this is entirely legacy, and we should not
* pretend anything else, so we only set the name when no engine is
* given. If both are already given, someone made a mistake, and
* since that can only happen internally, it's safe to make an
* assertion.
*/
if (!ossl_assert(e == NULL || name == NULL))
return NULL;
if (e == NULL)
name = OBJ_nid2sn(id);
propquery = NULL;
#ifndef OPENSSL_NO_ENGINE
/*
* We were called using legacy data, or an EVP_PKEY, but an EVP_PKEY
* isn't tied to a specific library context, so we fall back to the
* default library context.
* TODO(v3.0): an EVP_PKEY that doesn't originate from a leagacy key
* structure only has the pkeys[] cache, where the first element is
* considered the "origin". Investigate if that could be a suitable
* way to find a library context.
*/
libctx = NULL;
# ifndef OPENSSL_NO_ENGINE
if (e == NULL && pkey != NULL)
e = pkey->pmeth_engine != NULL ? pkey->pmeth_engine : pkey->engine;
/* Try to find an ENGINE which implements this method */
@@ -154,28 +218,29 @@ static EVP_PKEY_CTX *int_ctx_new(EVP_PKEY *pkey, ENGINE *e,
if (e)
pmeth = ENGINE_get_pkey_meth(e, id);
else
#endif
# endif
pmeth = EVP_PKEY_meth_find(id);
if (pmeth == NULL) {
#ifndef OPENSSL_NO_ENGINE
# ifndef OPENSSL_NO_ENGINE
ENGINE_finish(e);
#endif
# endif
EVPerr(EVP_F_INT_CTX_NEW, EVP_R_UNSUPPORTED_ALGORITHM);
return NULL;
}
/* END legacy */
#endif /* FIPS_MODE */
common:
ret = OPENSSL_zalloc(sizeof(*ret));
if (ret == NULL) {
#ifndef OPENSSL_NO_ENGINE
#if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODE)
ENGINE_finish(e);
#endif
EVPerr(EVP_F_INT_CTX_NEW, ERR_R_MALLOC_FAILURE);
return NULL;
}
ret->algorithm = name;
ret->libctx = libctx;
ret->keytype = name;
ret->propquery = propquery;
ret->engine = e;
ret->pmeth = pmeth;
@@ -195,34 +260,67 @@ static EVP_PKEY_CTX *int_ctx_new(EVP_PKEY *pkey, ENGINE *e,
return ret;
}
/*- All methods below can also be used in FIPS_MODE */
EVP_PKEY_CTX *EVP_PKEY_CTX_new_from_name(OPENSSL_CTX *libctx,
const char *name,
const char *propquery)
{
return int_ctx_new(libctx, NULL, NULL, name, propquery, -1);
}
EVP_PKEY_CTX *EVP_PKEY_CTX_new_from_pkey(OPENSSL_CTX *libctx, EVP_PKEY *pkey)
{
return int_ctx_new(libctx, pkey, NULL, NULL, NULL, -1);
}
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 (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);
ctx->op.sig.sigprovctx = NULL;
ctx->op.sig.signature = NULL;
}
/* TODO(3.0): add dependancies and uncomment this when available for fips mode */
#ifndef FIPS_MODE
else 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);
ctx->op.kex.exchprovctx = NULL;
ctx->op.kex.exchange = NULL;
} else if (EVP_PKEY_CTX_IS_ASYM_CIPHER_OP(ctx)) {
if (ctx->op.ciph.ciphprovctx != NULL && ctx->op.ciph.cipher != NULL)
ctx->op.ciph.cipher->freectx(ctx->op.ciph.ciphprovctx);
EVP_ASYM_CIPHER_free(ctx->op.ciph.cipher);
ctx->op.ciph.ciphprovctx = NULL;
ctx->op.ciph.cipher = NULL;
}
#endif
}
EVP_PKEY_METHOD *EVP_PKEY_meth_new(int id, int flags)
void EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx)
{
EVP_PKEY_METHOD *pmeth;
if (ctx == NULL)
return;
if (ctx->pmeth && ctx->pmeth->cleanup)
ctx->pmeth->cleanup(ctx);
pmeth = OPENSSL_zalloc(sizeof(*pmeth));
if (pmeth == NULL) {
EVPerr(EVP_F_EVP_PKEY_METH_NEW, ERR_R_MALLOC_FAILURE);
return NULL;
}
evp_pkey_ctx_free_old_ops(ctx);
EVP_KEYMGMT_free(ctx->keymgmt);
pmeth->pkey_id = id;
pmeth->flags = flags | EVP_PKEY_FLAG_DYNAMIC;
return pmeth;
EVP_PKEY_free(ctx->pkey);
EVP_PKEY_free(ctx->peerkey);
#if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODE)
ENGINE_finish(ctx->engine);
#endif
OPENSSL_free(ctx);
}
#ifndef FIPS_MODE
void EVP_PKEY_meth_get0_info(int *ppkey_id, int *pflags,
const EVP_PKEY_METHOD *meth)
{
@@ -283,19 +381,14 @@ void EVP_PKEY_meth_free(EVP_PKEY_METHOD *pmeth)
EVP_PKEY_CTX *EVP_PKEY_CTX_new(EVP_PKEY *pkey, ENGINE *e)
{
return int_ctx_new(pkey, e, NULL, NULL, -1);
return int_ctx_new(NULL, pkey, e, NULL, NULL, -1);
}
EVP_PKEY_CTX *EVP_PKEY_CTX_new_id(int id, ENGINE *e)
{
return int_ctx_new(NULL, e, NULL, NULL, id);
return int_ctx_new(NULL, NULL, e, NULL, NULL, id);
}
EVP_PKEY_CTX *EVP_PKEY_CTX_new_provided(const char *name,
const char *propquery)
{
return int_ctx_new(NULL, NULL, name, propquery, -1);
}
EVP_PKEY_CTX *EVP_PKEY_CTX_dup(const EVP_PKEY_CTX *pctx)
{
@@ -307,13 +400,13 @@ EVP_PKEY_CTX *EVP_PKEY_CTX_dup(const EVP_PKEY_CTX *pctx)
|| (EVP_PKEY_CTX_IS_SIGNATURE_OP(pctx)
&& pctx->op.sig.sigprovctx == NULL)))
return NULL;
#ifndef OPENSSL_NO_ENGINE
# ifndef OPENSSL_NO_ENGINE
/* Make sure it's safe to copy a pkey context using an ENGINE */
if (pctx->engine && !ENGINE_init(pctx->engine)) {
EVPerr(EVP_F_EVP_PKEY_CTX_DUP, ERR_R_ENGINE_LIB);
return 0;
}
#endif
# endif
rctx = OPENSSL_zalloc(sizeof(*rctx));
if (rctx == NULL) {
EVPerr(EVP_F_EVP_PKEY_CTX_DUP, ERR_R_MALLOC_FAILURE);
@@ -324,7 +417,8 @@ EVP_PKEY_CTX *EVP_PKEY_CTX_dup(const EVP_PKEY_CTX *pctx)
EVP_PKEY_up_ref(pctx->pkey);
rctx->pkey = pctx->pkey;
rctx->operation = pctx->operation;
rctx->algorithm = pctx->algorithm;
rctx->libctx = pctx->libctx;
rctx->keytype = pctx->keytype;
rctx->propquery = pctx->propquery;
if (EVP_PKEY_CTX_IS_DERIVE_OP(pctx)) {
@@ -367,12 +461,32 @@ EVP_PKEY_CTX *EVP_PKEY_CTX_dup(const EVP_PKEY_CTX *pctx)
}
return rctx;
}
} else if (EVP_PKEY_CTX_IS_ASYM_CIPHER_OP(pctx)) {
if (pctx->op.ciph.cipher != NULL) {
rctx->op.ciph.cipher = pctx->op.ciph.cipher;
if (!EVP_ASYM_CIPHER_up_ref(rctx->op.ciph.cipher)) {
OPENSSL_free(rctx);
return NULL;
}
}
if (pctx->op.ciph.ciphprovctx != NULL) {
if (!ossl_assert(pctx->op.ciph.cipher != NULL))
return NULL;
rctx->op.ciph.ciphprovctx
= pctx->op.ciph.cipher->dupctx(pctx->op.ciph.ciphprovctx);
if (rctx->op.ciph.ciphprovctx == NULL) {
EVP_ASYM_CIPHER_free(rctx->op.ciph.cipher);
OPENSSL_free(rctx);
return NULL;
}
return rctx;
}
}
rctx->pmeth = pctx->pmeth;
#ifndef OPENSSL_NO_ENGINE
# ifndef OPENSSL_NO_ENGINE
rctx->engine = pctx->engine;
#endif
# endif
if (pctx->peerkey)
EVP_PKEY_up_ref(pctx->peerkey);
@@ -439,44 +553,7 @@ const EVP_PKEY_METHOD *EVP_PKEY_meth_get0(size_t idx)
return NULL;
return sk_EVP_PKEY_METHOD_value(app_pkey_methods, idx);
}
void EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx)
{
if (ctx == NULL)
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
ENGINE_finish(ctx->engine);
#endif
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)
{
@@ -492,9 +569,48 @@ int EVP_PKEY_CTX_set_params(EVP_PKEY_CTX *ctx, OSSL_PARAM *params)
&& ctx->op.sig.signature->set_ctx_params != NULL)
return ctx->op.sig.signature->set_ctx_params(ctx->op.sig.sigprovctx,
params);
if (EVP_PKEY_CTX_IS_ASYM_CIPHER_OP(ctx)
&& ctx->op.ciph.ciphprovctx != NULL
&& ctx->op.ciph.cipher != NULL
&& ctx->op.ciph.cipher->set_ctx_params != NULL)
return ctx->op.ciph.cipher->set_ctx_params(ctx->op.ciph.ciphprovctx,
params);
return 0;
}
#ifndef FIPS_MODE
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);
if (EVP_PKEY_CTX_IS_ASYM_CIPHER_OP(ctx)
&& ctx->op.ciph.ciphprovctx != NULL
&& ctx->op.ciph.cipher != NULL
&& ctx->op.ciph.cipher->get_ctx_params != NULL)
return ctx->op.ciph.cipher->get_ctx_params(ctx->op.ciph.ciphprovctx,
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();
if (EVP_PKEY_CTX_IS_ASYM_CIPHER_OP(ctx)
&& ctx->op.ciph.cipher != NULL
&& ctx->op.ciph.cipher->gettable_ctx_params != NULL)
return ctx->op.ciph.cipher->gettable_ctx_params();
return NULL;
}
const OSSL_PARAM *EVP_PKEY_CTX_settable_params(EVP_PKEY_CTX *ctx)
{
if (EVP_PKEY_CTX_IS_DERIVE_OP(ctx)
@@ -505,11 +621,15 @@ const OSSL_PARAM *EVP_PKEY_CTX_settable_params(EVP_PKEY_CTX *ctx)
&& ctx->op.sig.signature != NULL
&& ctx->op.sig.signature->settable_ctx_params != NULL)
return ctx->op.sig.signature->settable_ctx_params();
if (EVP_PKEY_CTX_IS_ASYM_CIPHER_OP(ctx)
&& ctx->op.ciph.cipher != NULL
&& ctx->op.ciph.cipher->settable_ctx_params != NULL)
return ctx->op.ciph.cipher->settable_ctx_params();
return NULL;
}
#ifndef OPENSSL_NO_DH
# ifndef OPENSSL_NO_DH
int EVP_PKEY_CTX_set_dh_pad(EVP_PKEY_CTX *ctx, int pad)
{
OSSL_PARAM dh_pad_params[2];
@@ -531,7 +651,7 @@ int EVP_PKEY_CTX_set_dh_pad(EVP_PKEY_CTX *ctx, int pad)
return EVP_PKEY_CTX_set_params(ctx, dh_pad_params);
}
#endif
# endif
int EVP_PKEY_CTX_get_signature_md(EVP_PKEY_CTX *ctx, const EVP_MD **md)
{
@@ -559,7 +679,7 @@ int EVP_PKEY_CTX_get_signature_md(EVP_PKEY_CTX *ctx, const EVP_MD **md)
if (!EVP_PKEY_CTX_get_params(ctx, sig_md_params))
return 0;
tmp = EVP_get_digestbyname(name);
tmp = evp_get_digestbyname_ex(ctx->libctx, name);
if (tmp == NULL)
return 0;
@@ -611,14 +731,41 @@ 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
# ifndef OPENSSL_NO_DH
case EVP_PKEY_CTRL_DH_PAD:
return EVP_PKEY_CTX_set_dh_pad(ctx, p1);
#endif
# 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);
case EVP_PKEY_CTRL_RSA_PADDING:
return EVP_PKEY_CTX_set_rsa_padding(ctx, p1);
case EVP_PKEY_CTRL_GET_RSA_PADDING:
return EVP_PKEY_CTX_get_rsa_padding(ctx, p2);
case EVP_PKEY_CTRL_RSA_OAEP_MD:
return EVP_PKEY_CTX_set_rsa_oaep_md(ctx, p2);
case EVP_PKEY_CTRL_GET_RSA_OAEP_MD:
return EVP_PKEY_CTX_get_rsa_oaep_md(ctx, p2);
case EVP_PKEY_CTRL_RSA_MGF1_MD:
return EVP_PKEY_CTX_set_rsa_oaep_md(ctx, p2);
case EVP_PKEY_CTRL_GET_RSA_MGF1_MD:
return EVP_PKEY_CTX_get_rsa_oaep_md(ctx, p2);
case EVP_PKEY_CTRL_RSA_OAEP_LABEL:
return EVP_PKEY_CTX_set0_rsa_oaep_label(ctx, p2, p1);
case EVP_PKEY_CTRL_GET_RSA_OAEP_LABEL:
return EVP_PKEY_CTX_get0_rsa_oaep_label(ctx, (unsigned char **)p2);
case EVP_PKEY_CTRL_PKCS7_ENCRYPT:
case EVP_PKEY_CTRL_PKCS7_DECRYPT:
# ifndef OPENSSL_NO_CMS
case EVP_PKEY_CTRL_CMS_DECRYPT:
case EVP_PKEY_CTRL_CMS_ENCRYPT:
# endif
if (ctx->pmeth->pkey_id != EVP_PKEY_RSA_PSS)
return 1;
ERR_raise(ERR_LIB_EVP,
EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
return -2;
}
return 0;
}
@@ -634,8 +781,10 @@ int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype,
}
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))
|| (EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx)
&& ctx->op.sig.sigprovctx != NULL)
|| (EVP_PKEY_CTX_IS_ASYM_CIPHER_OP(ctx)
&& ctx->op.ciph.ciphprovctx != NULL))
return legacy_ctrl_to_param(ctx, keytype, optype, cmd, p1, p2);
if (ctx->pmeth == NULL || ctx->pmeth->ctrl == NULL) {
@@ -677,14 +826,14 @@ int EVP_PKEY_CTX_ctrl_uint64(EVP_PKEY_CTX *ctx, int keytype, int optype,
static int legacy_ctrl_str_to_param(EVP_PKEY_CTX *ctx, const char *name,
const char *value)
{
#ifndef OPENSSL_NO_DH
# 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
# endif
if (strcmp(name, "digest") == 0) {
int ret;
EVP_MD *md;
@@ -700,6 +849,52 @@ static int legacy_ctrl_str_to_param(EVP_PKEY_CTX *ctx, const char *name,
return ret;
}
if (strcmp(name, "rsa_padding_mode") == 0) {
int pm;
if (strcmp(value, "pkcs1") == 0) {
pm = RSA_PKCS1_PADDING;
} else if (strcmp(value, "sslv23") == 0) {
pm = RSA_SSLV23_PADDING;
} else if (strcmp(value, "none") == 0) {
pm = RSA_NO_PADDING;
} else if (strcmp(value, "oeap") == 0) {
pm = RSA_PKCS1_OAEP_PADDING;
} else if (strcmp(value, "oaep") == 0) {
pm = RSA_PKCS1_OAEP_PADDING;
} else if (strcmp(value, "x931") == 0) {
pm = RSA_X931_PADDING;
} else if (strcmp(value, "pss") == 0) {
pm = RSA_PKCS1_PSS_PADDING;
} else {
ERR_raise(ERR_LIB_RSA, RSA_R_UNKNOWN_PADDING_TYPE);
return -2;
}
return EVP_PKEY_CTX_set_rsa_padding(ctx, pm);
}
if (strcmp(name, "rsa_mgf1_md") == 0)
return EVP_PKEY_CTX_set_rsa_mgf1_md_name(ctx, value, NULL);
if (strcmp(name, "rsa_oaep_md") == 0)
return EVP_PKEY_CTX_set_rsa_oaep_md_name(ctx, value, NULL);
if (strcmp(name, "rsa_oaep_label") == 0) {
unsigned char *lab;
long lablen;
int ret;
lab = OPENSSL_hexstr2buf(value, &lablen);
if (lab == NULL)
return 0;
ret = EVP_PKEY_CTX_set0_rsa_oaep_label(ctx, lab, lablen);
if (ret <= 0)
OPENSSL_free(lab);
return ret;
}
return 0;
}
@@ -713,7 +908,9 @@ int EVP_PKEY_CTX_ctrl_str(EVP_PKEY_CTX *ctx,
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))
&& ctx->op.sig.sigprovctx != NULL)
|| (EVP_PKEY_CTX_IS_ASYM_CIPHER_OP(ctx)
&& ctx->op.ciph.ciphprovctx != NULL))
return legacy_ctrl_str_to_param(ctx, name, value);
if (!ctx || !ctx->pmeth || !ctx->pmeth->ctrl_str) {
@@ -951,6 +1148,21 @@ void EVP_PKEY_meth_set_ctrl(EVP_PKEY_METHOD *pmeth,
pmeth->ctrl_str = ctrl_str;
}
void EVP_PKEY_meth_set_digestsign(EVP_PKEY_METHOD *pmeth,
int (*digestsign) (EVP_MD_CTX *ctx, unsigned char *sig, size_t *siglen,
const unsigned char *tbs, size_t tbslen))
{
pmeth->digestsign = digestsign;
}
void EVP_PKEY_meth_set_digestverify(EVP_PKEY_METHOD *pmeth,
int (*digestverify) (EVP_MD_CTX *ctx, const unsigned char *sig,
size_t siglen, const unsigned char *tbs,
size_t tbslen))
{
pmeth->digestverify = digestverify;
}
void EVP_PKEY_meth_set_check(EVP_PKEY_METHOD *pmeth,
int (*check) (EVP_PKEY *pkey))
{
@@ -1143,6 +1355,23 @@ void EVP_PKEY_meth_get_ctrl(const EVP_PKEY_METHOD *pmeth,
*pctrl_str = pmeth->ctrl_str;
}
void EVP_PKEY_meth_get_digestsign(EVP_PKEY_METHOD *pmeth,
int (**digestsign) (EVP_MD_CTX *ctx, unsigned char *sig, size_t *siglen,
const unsigned char *tbs, size_t tbslen))
{
if (digestsign)
*digestsign = pmeth->digestsign;
}
void EVP_PKEY_meth_get_digestverify(EVP_PKEY_METHOD *pmeth,
int (**digestverify) (EVP_MD_CTX *ctx, const unsigned char *sig,
size_t siglen, const unsigned char *tbs,
size_t tbslen))
{
if (digestverify)
*digestverify = pmeth->digestverify;
}
void EVP_PKEY_meth_get_check(const EVP_PKEY_METHOD *pmeth,
int (**pcheck) (EVP_PKEY *pkey))
{
@@ -1171,3 +1400,5 @@ void EVP_PKEY_meth_get_digest_custom(EVP_PKEY_METHOD *pmeth,
if (pdigest_custom != NULL)
*pdigest_custom = pmeth->digest_custom;
}
#endif /* FIPS_MODE */
+580
View File
@@ -0,0 +1,580 @@
/*
* Copyright 2006-2016 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 <stdio.h>
#include <stdlib.h>
#include <openssl/objects.h>
#include <openssl/evp.h>
#include "internal/cryptlib.h"
#include "crypto/evp.h"
#include "internal/provider.h"
#include "evp_local.h"
static EVP_SIGNATURE *evp_signature_new(OSSL_PROVIDER *prov)
{
EVP_SIGNATURE *signature = OPENSSL_zalloc(sizeof(EVP_SIGNATURE));
if (signature == NULL) {
ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE);
return NULL;
}
signature->lock = CRYPTO_THREAD_lock_new();
if (signature->lock == NULL) {
ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE);
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)
{
EVP_SIGNATURE *signature = NULL;
int ctxfncnt = 0, signfncnt = 0, verifyfncnt = 0, verifyrecfncnt = 0;
int digsignfncnt = 0, digverifyfncnt = 0;
int gparamfncnt = 0, sparamfncnt = 0, gmdparamfncnt = 0, smdparamfncnt = 0;
if ((signature = evp_signature_new(prov)) == NULL) {
ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE);
goto err;
}
signature->name_id = name_id;
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_DIGEST_SIGN_INIT:
if (signature->digest_sign_init != NULL)
break;
signature->digest_sign_init
= OSSL_get_OP_signature_digest_sign_init(fns);
digsignfncnt++;
break;
case OSSL_FUNC_SIGNATURE_DIGEST_SIGN_UPDATE:
if (signature->digest_sign_update != NULL)
break;
signature->digest_sign_update
= OSSL_get_OP_signature_digest_sign_update(fns);
digsignfncnt++;
break;
case OSSL_FUNC_SIGNATURE_DIGEST_SIGN_FINAL:
if (signature->digest_sign_final != NULL)
break;
signature->digest_sign_final
= OSSL_get_OP_signature_digest_sign_final(fns);
digsignfncnt++;
break;
case OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_INIT:
if (signature->digest_verify_init != NULL)
break;
signature->digest_verify_init
= OSSL_get_OP_signature_digest_verify_init(fns);
digverifyfncnt++;
break;
case OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_UPDATE:
if (signature->digest_verify_update != NULL)
break;
signature->digest_verify_update
= OSSL_get_OP_signature_digest_verify_update(fns);
digverifyfncnt++;
break;
case OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_FINAL:
if (signature->digest_verify_final != NULL)
break;
signature->digest_verify_final
= OSSL_get_OP_signature_digest_verify_final(fns);
digverifyfncnt++;
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;
case OSSL_FUNC_SIGNATURE_GET_CTX_MD_PARAMS:
if (signature->get_ctx_md_params != NULL)
break;
signature->get_ctx_md_params
= OSSL_get_OP_signature_get_ctx_md_params(fns);
gmdparamfncnt++;
break;
case OSSL_FUNC_SIGNATURE_GETTABLE_CTX_MD_PARAMS:
if (signature->gettable_ctx_md_params != NULL)
break;
signature->gettable_ctx_md_params
= OSSL_get_OP_signature_gettable_ctx_md_params(fns);
gmdparamfncnt++;
break;
case OSSL_FUNC_SIGNATURE_SET_CTX_MD_PARAMS:
if (signature->set_ctx_md_params != NULL)
break;
signature->set_ctx_md_params
= OSSL_get_OP_signature_set_ctx_md_params(fns);
smdparamfncnt++;
break;
case OSSL_FUNC_SIGNATURE_SETTABLE_CTX_MD_PARAMS:
if (signature->settable_ctx_md_params != NULL)
break;
signature->settable_ctx_md_params
= OSSL_get_OP_signature_settable_ctx_md_params(fns);
smdparamfncnt++;
break;
}
}
if (ctxfncnt != 2
|| (signfncnt == 0
&& verifyfncnt == 0
&& verifyrecfncnt == 0
&& digsignfncnt == 0
&& digverifyfncnt == 0)
|| (signfncnt != 0 && signfncnt != 2)
|| (verifyfncnt != 0 && verifyfncnt != 2)
|| (verifyrecfncnt != 0 && verifyrecfncnt != 2)
|| (digsignfncnt != 0 && digsignfncnt != 3)
|| (digverifyfncnt != 0 && digverifyfncnt != 3)
|| (gparamfncnt != 0 && gparamfncnt != 2)
|| (sparamfncnt != 0 && sparamfncnt != 2)
|| (gmdparamfncnt != 0 && gmdparamfncnt != 2)
|| (smdparamfncnt != 0 && smdparamfncnt != 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 set of
* "signature" functions:
* (sign_init, sign) or
* (verify_init verify) or
* (verify_recover_init, verify_recover) or
* (digest_sign_init, digest_sign_update, digest_sign_final) or
* (digest_verify_init, digest_verify_update, digest_verify_final).
*
* 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 same rules
* apply to the "md_params" functions. The dupctx function is optional.
*/
ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_PROVIDER_FUNCTIONS);
goto err;
}
return signature;
err:
EVP_SIGNATURE_free(signature);
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;
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)
{
return evp_generic_fetch(ctx, OSSL_OP_SIGNATURE, algorithm, properties,
evp_signature_from_dispatch,
(int (*)(void *))EVP_SIGNATURE_up_ref,
(void (*)(void *))EVP_SIGNATURE_free);
}
int EVP_SIGNATURE_is_a(const EVP_SIGNATURE *signature, const char *name)
{
return evp_is_a(signature->prov, signature->name_id, NULL, name);
}
int EVP_SIGNATURE_number(const EVP_SIGNATURE *signature)
{
return signature->name_id;
}
void EVP_SIGNATURE_do_all_provided(OPENSSL_CTX *libctx,
void (*fn)(EVP_SIGNATURE *signature,
void *arg),
void *arg)
{
evp_generic_do_all(libctx, OSSL_OP_SIGNATURE,
(void (*)(void *, void *))fn, arg,
evp_signature_from_dispatch,
(void (*)(void *))EVP_SIGNATURE_free);
}
void EVP_SIGNATURE_names_do_all(const EVP_SIGNATURE *signature,
void (*fn)(const char *name, void *data),
void *data)
{
if (signature->prov != NULL)
evp_names_do_all(signature->prov, signature->name_id, fn, data);
}
static int evp_pkey_signature_init(EVP_PKEY_CTX *ctx, int operation)
{
int ret = 0;
void *provkey = NULL;
EVP_SIGNATURE *signature = 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->keytype == NULL)
goto legacy;
if (ctx->keymgmt == NULL)
ctx->keymgmt =
EVP_KEYMGMT_fetch(ctx->libctx, ctx->keytype, ctx->propquery);
if (ctx->keymgmt != NULL) {
const char *supported_sig = NULL;
if (ctx->keymgmt->query_operation_name != NULL)
supported_sig =
ctx->keymgmt->query_operation_name(OSSL_OP_SIGNATURE);
/*
* If we didn't get a supported sig, assume there is one with the
* same name as the key type.
*/
if (supported_sig == NULL)
supported_sig = ctx->keytype;
/*
* Because we cleared out old ops, we shouldn't need to worry about
* checking if signature is already there.
*/
signature =
EVP_SIGNATURE_fetch(ctx->libctx, supported_sig, ctx->propquery);
}
if (ctx->keymgmt == NULL
|| signature == NULL
|| (EVP_KEYMGMT_provider(ctx->keymgmt)
!= EVP_SIGNATURE_provider(signature))) {
/*
* We don't have the full support we need with provided methods,
* let's go see if legacy does. Also, we don't need to free
* ctx->keymgmt here, as it's not necessarily tied to this
* operation. It will be freed by EVP_PKEY_CTX_free().
*/
EVP_SIGNATURE_free(signature);
goto legacy;
}
ctx->op.sig.signature = signature;
if (ctx->pkey != NULL) {
provkey =
evp_keymgmt_export_to_provider(ctx->pkey, ctx->keymgmt, 0);
/* If export failed, legacy may be able to pick it up */
if (provkey == NULL)
goto legacy;
}
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(EVP_PKEY_CTX *ctx)
{
return evp_pkey_signature_init(ctx, 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)
{
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(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(EVP_PKEY_CTX *ctx)
{
return evp_pkey_signature_init(ctx, 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)
{
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(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(EVP_PKEY_CTX *ctx)
{
return evp_pkey_signature_init(ctx, 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)
{
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(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);
}