mirror of
https://github.com/QuasarApp/openssl.git
synced 2025-05-12 01:19:41 +00:00
Modify providers that keep track of underlying algorithms
With some provider implementations, there are underlying ciphers, digests and macs. For some of them, the name was retrieved from the method, but since the methods do not store those any more, we add different mechanics. For code that needs to pass on the name of a cipher or diges via parameters, we simply locally store the name that was used when fetching said cipher or digest. This will ensure that any underlying code that needs to fetch that same cipher or digest does so with the exact same name instead of any random name from the set of names associated with the algorithm. For code that needs to check what kind of algorithm was passed, we provide EVP_{type}_is_a(), that returns true if the given method has the given name as one of its names. Reviewed-by: Matt Caswell <matt@openssl.org> (Merged from https://github.com/openssl/openssl/pull/9897)
This commit is contained in:
parent
f7c16d48a9
commit
7cfa1717b8
crypto/evp
doc/man3
include/openssl
providers/common
util
@ -385,3 +385,11 @@ 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)
|
||||
{
|
||||
OPENSSL_CTX *libctx = ossl_provider_library_context(prov);
|
||||
OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx);
|
||||
|
||||
return ossl_namemap_name2num(namemap, name) == number;
|
||||
}
|
||||
|
@ -448,6 +448,11 @@ int EVP_CIPHER_CTX_nid(const EVP_CIPHER_CTX *ctx)
|
||||
return ctx->cipher->nid;
|
||||
}
|
||||
|
||||
int EVP_CIPHER_is_a(const EVP_CIPHER *cipher, const char *name)
|
||||
{
|
||||
return evp_is_a(cipher->prov, cipher->name_id, name);
|
||||
}
|
||||
|
||||
const char *EVP_CIPHER_name(const EVP_CIPHER *cipher)
|
||||
{
|
||||
if (cipher->prov != NULL)
|
||||
|
@ -250,3 +250,4 @@ 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);
|
||||
|
@ -168,6 +168,11 @@ void EVP_MAC_free(EVP_MAC *mac)
|
||||
evp_mac_free(mac);
|
||||
}
|
||||
|
||||
int EVP_MAC_is_a(const EVP_MAC *mac, const char *name)
|
||||
{
|
||||
return evp_is_a(mac->prov, mac->name_id, name);
|
||||
}
|
||||
|
||||
const char *EVP_MAC_name(const EVP_MAC *mac)
|
||||
{
|
||||
return evp_first_name(mac->prov, mac->name_id);
|
||||
|
@ -221,8 +221,8 @@ static int pkey_mac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx)
|
||||
&& (ctx->pmeth->flags & EVP_PKEY_FLAG_SIGCTX_CUSTOM) != 0;
|
||||
|
||||
if (set_key) {
|
||||
if (strcmp(OBJ_nid2sn(EVP_PKEY_id(EVP_PKEY_CTX_get0_pkey(ctx))),
|
||||
EVP_MAC_name(EVP_MAC_CTX_mac(hctx->ctx))) != 0)
|
||||
if (!EVP_MAC_is_a(EVP_MAC_CTX_mac(hctx->ctx),
|
||||
OBJ_nid2sn(EVP_PKEY_id(EVP_PKEY_CTX_get0_pkey(ctx)))))
|
||||
return 0;
|
||||
key = EVP_PKEY_get0(EVP_PKEY_CTX_get0_pkey(ctx));
|
||||
if (key == NULL)
|
||||
|
@ -28,6 +28,7 @@ EVP_CipherFinal,
|
||||
EVP_get_cipherbyname,
|
||||
EVP_get_cipherbynid,
|
||||
EVP_get_cipherbyobj,
|
||||
EVP_CIPHER_is_a,
|
||||
EVP_CIPHER_name,
|
||||
EVP_CIPHER_provider,
|
||||
EVP_CIPHER_nid,
|
||||
@ -116,6 +117,7 @@ EVP_CIPHER_do_all_ex
|
||||
const EVP_CIPHER *EVP_get_cipherbyobj(const ASN1_OBJECT *a);
|
||||
|
||||
int EVP_CIPHER_nid(const EVP_CIPHER *e);
|
||||
int EVP_CIPHER_is_a(const EVP_CIPHER *cipher, const char *name);
|
||||
const char *EVP_CIPHER_name(const EVP_CIPHER *cipher);
|
||||
const OSSL_PROVIDER *EVP_CIPHER_provider(const EVP_CIPHER *cipher);
|
||||
int EVP_CIPHER_block_size(const EVP_CIPHER *e);
|
||||
@ -315,6 +317,9 @@ IDENTIFIER as such it ignores the cipher parameters and 40 bit RC2 and
|
||||
identifier or does not have ASN1 support this function will return
|
||||
B<NID_undef>.
|
||||
|
||||
EVP_CIPHER_is_a() returns 1 if the given I<cipher> is an implementation of an
|
||||
algorithm that's identifiable with I<name>, otherwise 0.
|
||||
|
||||
EVP_CIPHER_name() and EVP_CIPHER_CTX_name() return the name of the passed
|
||||
cipher or context.
|
||||
|
||||
|
@ -2,7 +2,8 @@
|
||||
|
||||
=head1 NAME
|
||||
|
||||
EVP_MAC, EVP_MAC_fetch, EVP_MAC_up_ref, EVP_MAC_free, EVP_MAC_name,
|
||||
EVP_MAC, EVP_MAC_fetch, EVP_MAC_up_ref, EVP_MAC_free,
|
||||
EVP_MAC_is_a, EVP_MAC_name,
|
||||
EVP_MAC_provider, EVP_MAC_get_params, EVP_MAC_gettable_params,
|
||||
EVP_MAC_CTX, EVP_MAC_CTX_new, EVP_MAC_CTX_free, EVP_MAC_CTX_dup,
|
||||
EVP_MAC_CTX_mac, EVP_MAC_CTX_get_params, EVP_MAC_CTX_set_params,
|
||||
@ -21,6 +22,7 @@ EVP_MAC_do_all_ex - EVP MAC routines
|
||||
const char *properties);
|
||||
int EVP_MAC_up_ref(EVP_MAC *mac);
|
||||
void EVP_MAC_free(EVP_MAC *mac);
|
||||
int EVP_MAC_is_a(const EVP_MAC *mac, const char *name);
|
||||
const char *EVP_MAC_name(const EVP_MAC *mac);
|
||||
const OSSL_PROVIDER *EVP_MAC_provider(const EVP_MAC *mac);
|
||||
int EVP_MAC_get_params(EVP_MAC *mac, OSSL_PARAM params[]);
|
||||
@ -157,6 +159,9 @@ EVP_MAC_size() returns the MAC output size for the given context.
|
||||
|
||||
EVP_MAC_name() returns the name of the given MAC implementation.
|
||||
|
||||
EVP_MAC_is_a() checks if the given I<mac> is an implementation of an
|
||||
algorithm that's identifiable with I<name>.
|
||||
|
||||
EVP_MAC_provider() returns the provider that holds the implementation
|
||||
of the given I<mac>.
|
||||
|
||||
@ -256,6 +261,9 @@ EVP_MAC_free() returns nothing at all.
|
||||
EVP_MAC_name() returns the name of the MAC, or NULL if NULL was
|
||||
passed.
|
||||
|
||||
EVP_MAC_is_a() returns 1 if the given method can be identified with
|
||||
the given name, otherwise 0.
|
||||
|
||||
EVP_MAC_provider() returns a pointer to the provider for the MAC, or
|
||||
NULL on error.
|
||||
|
||||
|
@ -475,6 +475,7 @@ void *EVP_MD_CTX_md_data(const EVP_MD_CTX *ctx);
|
||||
|
||||
int EVP_CIPHER_nid(const EVP_CIPHER *cipher);
|
||||
const char *EVP_CIPHER_name(const EVP_CIPHER *cipher);
|
||||
int EVP_CIPHER_is_a(const EVP_CIPHER *cipher, const char *name);
|
||||
const OSSL_PROVIDER *EVP_CIPHER_provider(const EVP_CIPHER *cipher);
|
||||
int EVP_CIPHER_block_size(const EVP_CIPHER *cipher);
|
||||
int EVP_CIPHER_impl_ctx_size(const EVP_CIPHER *cipher);
|
||||
@ -1034,6 +1035,7 @@ EVP_MAC *EVP_MAC_fetch(OPENSSL_CTX *libctx, const char *algorithm,
|
||||
int EVP_MAC_up_ref(EVP_MAC *mac);
|
||||
void EVP_MAC_free(EVP_MAC *mac);
|
||||
const char *EVP_MAC_name(const EVP_MAC *mac);
|
||||
int EVP_MAC_is_a(const EVP_MAC *mac, const char *name);
|
||||
const OSSL_PROVIDER *EVP_MAC_provider(const EVP_MAC *mac);
|
||||
int EVP_MAC_get_params(EVP_MAC *mac, OSSL_PARAM params[]);
|
||||
|
||||
|
@ -21,6 +21,9 @@ typedef struct {
|
||||
|
||||
/* Conditions for legacy EVP_CIPHER uses */
|
||||
ENGINE *engine; /* cipher engine */
|
||||
|
||||
/* Name this was fetched by */
|
||||
char name[51]; /* A longer name would be unexpected */
|
||||
} PROV_CIPHER;
|
||||
|
||||
typedef struct {
|
||||
@ -34,6 +37,9 @@ typedef struct {
|
||||
|
||||
/* Conditions for legacy EVP_MD uses */
|
||||
ENGINE *engine; /* digest engine */
|
||||
|
||||
/* Name this was fetched by */
|
||||
char name[51]; /* A longer name would be unexpected */
|
||||
} PROV_DIGEST;
|
||||
|
||||
/* Cipher functions */
|
||||
@ -43,19 +49,20 @@ typedef struct {
|
||||
* implementation used. If a provider cannot be found, it falls back to trying
|
||||
* non-provider based implementations.
|
||||
*/
|
||||
int ossl_prov_cipher_load_from_params(PROV_CIPHER *pd,
|
||||
int ossl_prov_cipher_load_from_params(PROV_CIPHER *pc,
|
||||
const OSSL_PARAM params[],
|
||||
OPENSSL_CTX *ctx);
|
||||
|
||||
/* Reset the PROV_CIPHER fields and free any allocated cipher reference */
|
||||
void ossl_prov_cipher_reset(PROV_CIPHER *pd);
|
||||
void ossl_prov_cipher_reset(PROV_CIPHER *pc);
|
||||
|
||||
/* Clone a PROV_CIPHER structure into a second */
|
||||
int ossl_prov_cipher_copy(PROV_CIPHER *dst, const PROV_CIPHER *src);
|
||||
|
||||
/* Query the cipher and associated engine (if any) */
|
||||
const EVP_CIPHER *ossl_prov_cipher_cipher(const PROV_CIPHER *pd);
|
||||
ENGINE *ossl_prov_cipher_engine(const PROV_CIPHER *pd);
|
||||
const EVP_CIPHER *ossl_prov_cipher_cipher(const PROV_CIPHER *pc);
|
||||
ENGINE *ossl_prov_cipher_engine(const PROV_CIPHER *pc);
|
||||
const char *ossl_prov_cipher_name(const PROV_CIPHER *pc);
|
||||
|
||||
/* Digest functions */
|
||||
/*
|
||||
@ -77,3 +84,4 @@ int ossl_prov_digest_copy(PROV_DIGEST *dst, const PROV_DIGEST *src);
|
||||
/* Query the digest and associated engine (if any) */
|
||||
const EVP_MD *ossl_prov_digest_md(const PROV_DIGEST *pd);
|
||||
ENGINE *ossl_prov_digest_engine(const PROV_DIGEST *pd);
|
||||
const char *ossl_prov_digest_name(const PROV_DIGEST *pd);
|
||||
|
@ -370,7 +370,6 @@ static int sskdf_derive(void *vctx, unsigned char *key, size_t keylen)
|
||||
int ret;
|
||||
const unsigned char *custom = NULL;
|
||||
size_t custom_len = 0;
|
||||
const char *macname;
|
||||
int default_salt_len;
|
||||
|
||||
/*
|
||||
@ -378,8 +377,7 @@ static int sskdf_derive(void *vctx, unsigned char *key, size_t keylen)
|
||||
* Why does KMAC require a salt length that's shorter than the MD
|
||||
* block size?
|
||||
*/
|
||||
macname = EVP_MAC_name(ctx->mac);
|
||||
if (strcmp(macname, OSSL_MAC_NAME_HMAC) == 0) {
|
||||
if (EVP_MAC_is_a(ctx->mac, OSSL_MAC_NAME_HMAC)) {
|
||||
/* H(x) = HMAC(x, salt, hash) */
|
||||
if (md == NULL) {
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_MESSAGE_DIGEST);
|
||||
@ -388,12 +386,12 @@ static int sskdf_derive(void *vctx, unsigned char *key, size_t keylen)
|
||||
default_salt_len = EVP_MD_block_size(md);
|
||||
if (default_salt_len <= 0)
|
||||
return 0;
|
||||
} else if (strcmp(macname, OSSL_MAC_NAME_KMAC128) == 0
|
||||
|| strcmp(macname, OSSL_MAC_NAME_KMAC256) == 0) {
|
||||
} else if (EVP_MAC_is_a(ctx->mac, OSSL_MAC_NAME_KMAC128)
|
||||
|| EVP_MAC_is_a(ctx->mac, OSSL_MAC_NAME_KMAC256)) {
|
||||
/* H(x) = KMACzzz(x, salt, custom) */
|
||||
custom = kmac_custom_str;
|
||||
custom_len = sizeof(kmac_custom_str);
|
||||
if (strcmp(macname, OSSL_MAC_NAME_KMAC128) == 0)
|
||||
if (EVP_MAC_is_a(ctx->mac, OSSL_MAC_NAME_KMAC128))
|
||||
default_salt_len = SSKDF_KMAC128_DEFAULT_SALT_SIZE;
|
||||
else
|
||||
default_salt_len = SSKDF_KMAC256_DEFAULT_SALT_SIZE;
|
||||
|
@ -17,6 +17,7 @@ void ossl_prov_cipher_reset(PROV_CIPHER *pc)
|
||||
pc->alloc_cipher = NULL;
|
||||
pc->cipher = NULL;
|
||||
pc->engine = NULL;
|
||||
pc->name[0] = '\0';
|
||||
}
|
||||
|
||||
int ossl_prov_cipher_copy(PROV_CIPHER *dst, const PROV_CIPHER *src)
|
||||
@ -26,6 +27,7 @@ int ossl_prov_cipher_copy(PROV_CIPHER *dst, const PROV_CIPHER *src)
|
||||
dst->engine = src->engine;
|
||||
dst->cipher = src->cipher;
|
||||
dst->alloc_cipher = src->alloc_cipher;
|
||||
OPENSSL_strlcpy(dst->name, src->name, sizeof(dst->name));
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -77,6 +79,7 @@ int ossl_prov_cipher_load_from_params(PROV_CIPHER *pc,
|
||||
|
||||
EVP_CIPHER_free(pc->alloc_cipher);
|
||||
pc->cipher = pc->alloc_cipher = EVP_CIPHER_fetch(ctx, p->data, propquery);
|
||||
OPENSSL_strlcpy(pc->name, p->data, sizeof(pc->name));
|
||||
/* TODO legacy stuff, to be removed */
|
||||
#ifndef FIPS_MODE /* Inside the FIPS module, we don't support legacy ciphers */
|
||||
if (pc->cipher == NULL)
|
||||
@ -95,12 +98,18 @@ ENGINE *ossl_prov_cipher_engine(const PROV_CIPHER *pc)
|
||||
return pc->engine;
|
||||
}
|
||||
|
||||
const char *ossl_prov_cipher_name(const PROV_CIPHER *pc)
|
||||
{
|
||||
return pc->name;
|
||||
}
|
||||
|
||||
void ossl_prov_digest_reset(PROV_DIGEST *pd)
|
||||
{
|
||||
EVP_MD_free(pd->alloc_md);
|
||||
pd->alloc_md = NULL;
|
||||
pd->md = NULL;
|
||||
pd->engine = NULL;
|
||||
pd->name[0] = '\0';
|
||||
}
|
||||
|
||||
int ossl_prov_digest_copy(PROV_DIGEST *dst, const PROV_DIGEST *src)
|
||||
@ -110,6 +119,7 @@ int ossl_prov_digest_copy(PROV_DIGEST *dst, const PROV_DIGEST *src)
|
||||
dst->engine = src->engine;
|
||||
dst->md = src->md;
|
||||
dst->alloc_md = src->alloc_md;
|
||||
OPENSSL_strlcpy(dst->name, src->name, sizeof(dst->name));
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -132,6 +142,7 @@ int ossl_prov_digest_load_from_params(PROV_DIGEST *pd,
|
||||
|
||||
EVP_MD_free(pd->alloc_md);
|
||||
pd->md = pd->alloc_md = EVP_MD_fetch(ctx, p->data, propquery);
|
||||
OPENSSL_strlcpy(pd->name, p->data, sizeof(pd->name));
|
||||
/* TODO legacy stuff, to be removed */
|
||||
#ifndef FIPS_MODE /* Inside the FIPS module, we don't support legacy digests */
|
||||
if (pd->md == NULL)
|
||||
@ -150,3 +161,7 @@ ENGINE *ossl_prov_digest_engine(const PROV_DIGEST *pd)
|
||||
return pd->engine;
|
||||
}
|
||||
|
||||
const char *ossl_prov_digest_name(const PROV_DIGEST *pd)
|
||||
{
|
||||
return pd->name;
|
||||
}
|
||||
|
@ -4762,3 +4762,5 @@ ERR_peek_error_all 4878 3_0_0 EXIST::FUNCTION:
|
||||
ERR_peek_last_error_func 4879 3_0_0 EXIST::FUNCTION:
|
||||
ERR_peek_last_error_data 4880 3_0_0 EXIST::FUNCTION:
|
||||
ERR_peek_last_error_all 4881 3_0_0 EXIST::FUNCTION:
|
||||
EVP_CIPHER_is_a 4882 3_0_0 EXIST::FUNCTION:
|
||||
EVP_MAC_is_a 4883 3_0_0 EXIST::FUNCTION:
|
||||
|
Loading…
x
Reference in New Issue
Block a user