evp_md_from_algorithm, evp_md_up_ref, evp_md_free);
}
+EVP_MD *evp_digest_fetch_from_prov(OSSL_PROVIDER *prov,
+ const char *algorithm,
+ const char *properties)
+{
+ return evp_generic_fetch_from_prov(prov, OSSL_OP_DIGEST,
+ algorithm, properties,
+ evp_md_from_algorithm,
+ evp_md_up_ref,
+ evp_md_free);
+}
+
typedef struct {
int md_nid;
int hmac_nid;
EVP_CIPHER *evp_cipher_fetch_from_prov(OSSL_PROVIDER *prov,
const char *algorithm,
const char *properties);
+EVP_MD *evp_digest_fetch_from_prov(OSSL_PROVIDER *prov,
+ const char *algorithm,
+ const char *properties);
+EVP_MAC *evp_mac_fetch_from_prov(OSSL_PROVIDER *prov,
+ const char *algorithm,
+ const char *properties);
/* Internal structure constructors for fetched methods */
EVP_MD *evp_md_new(void);
(void (*)(void *, void *))fn, arg,
evp_mac_from_algorithm, evp_mac_up_ref, evp_mac_free);
}
+
+EVP_MAC *evp_mac_fetch_from_prov(OSSL_PROVIDER *prov,
+ const char *algorithm,
+ const char *properties)
+{
+ return evp_generic_fetch_from_prov(prov, OSSL_OP_MAC,
+ algorithm, properties,
+ evp_mac_from_algorithm,
+ evp_mac_up_ref,
+ evp_mac_free);
+}
const EVP_MD *ossl_prov_digest_md(const PROV_DIGEST *pd);
ENGINE *ossl_prov_digest_engine(const PROV_DIGEST *pd);
+/* Set a specific md, resets current digests first */
+void ossl_prov_digest_set_md(PROV_DIGEST *pd, EVP_MD *md);
/*
* Set the various parameters on an EVP_MAC_CTX from the supplied arguments.
return pd->md != NULL;
}
+void ossl_prov_digest_set_md(PROV_DIGEST *pd, EVP_MD *md)
+{
+ ossl_prov_digest_reset(pd);
+ pd->md = pd->alloc_md = md;
+}
+
const EVP_MD *ossl_prov_digest_md(const PROV_DIGEST *pd)
{
return pd->md;
#include "prov/provider_util.h"
#include "prov/implementations.h"
#include "drbg_local.h"
+#include "crypto/evp.h"
+#include "crypto/evp/evp_local.h"
+#include "internal/provider.h"
static OSSL_FUNC_rand_newctx_fn drbg_hash_new_wrapper;
static OSSL_FUNC_rand_freectx_fn drbg_hash_free;
return known_gettable_ctx_params;
}
+static int drbg_fetch_digest_from_prov(const OSSL_PARAM params[],
+ OSSL_LIB_CTX *libctx,
+ EVP_MD **digest)
+{
+ OSSL_PROVIDER *prov = NULL;
+ const OSSL_PARAM *p;
+ EVP_MD *md = NULL;
+ int ret = 0;
+
+ if (digest == NULL)
+ return 0;
+
+ if ((p = OSSL_PARAM_locate_const(params,
+ OSSL_PROV_PARAM_CORE_PROV_NAME)) == NULL)
+ return 0;
+ if (p->data_type != OSSL_PARAM_UTF8_STRING)
+ return 0;
+ if ((prov = ossl_provider_find(libctx, (const char *)p->data, 1)) == NULL)
+ return 0;
+
+ p = OSSL_PARAM_locate_const(params, OSSL_ALG_PARAM_DIGEST);
+ if (p == NULL) {
+ ret = 1;
+ goto done;
+ }
+
+ if (p->data_type != OSSL_PARAM_UTF8_STRING)
+ goto done;
+
+ md = evp_digest_fetch_from_prov(prov, (const char *)p->data, NULL);
+ if (md) {
+ EVP_MD_free(*digest);
+ *digest = md;
+ ret = 1;
+ }
+
+done:
+ ossl_provider_free(prov);
+ return ret;
+}
+
static int drbg_hash_set_ctx_params_locked(void *vctx, const OSSL_PARAM params[])
{
PROV_DRBG *ctx = (PROV_DRBG *)vctx;
PROV_DRBG_HASH *hash = (PROV_DRBG_HASH *)ctx->data;
OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(ctx->provctx);
+ EVP_MD *prov_md = NULL;
const EVP_MD *md;
int md_size;
OSSL_DRBG_PARAM_FIPS_DIGEST_CHECK))
return 0;
- if (!ossl_prov_digest_load_from_params(&hash->digest, params, libctx))
- return 0;
+ /* try to fetch digest from provider */
+ (void)ERR_set_mark();
+ if (!drbg_fetch_digest_from_prov(params, libctx, &prov_md)) {
+ (void)ERR_pop_to_mark();
+ /* fall back to full implementation search */
+ if (!ossl_prov_digest_load_from_params(&hash->digest, params, libctx))
+ return 0;
+ } else {
+ (void)ERR_clear_last_mark();
+ if (prov_md)
+ ossl_prov_digest_set_md(&hash->digest, prov_md);
+ }
md = ossl_prov_digest_md(&hash->digest);
if (md != NULL) {
#include "prov/provider_ctx.h"
#include "prov/hmac_drbg.h"
#include "drbg_local.h"
+#include "crypto/evp.h"
+#include "crypto/evp/evp_local.h"
+#include "internal/provider.h"
static OSSL_FUNC_rand_newctx_fn drbg_hmac_new_wrapper;
static OSSL_FUNC_rand_freectx_fn drbg_hmac_free;
return known_gettable_ctx_params;
}
+static int drbg_fetch_algs_from_prov(const OSSL_PARAM params[],
+ OSSL_LIB_CTX *libctx,
+ EVP_MAC_CTX **macctx,
+ EVP_MD **digest)
+{
+ OSSL_PROVIDER *prov = NULL;
+ const OSSL_PARAM *p;
+ EVP_MD *md = NULL;
+ EVP_MAC *mac = NULL;
+ int ret = 0;
+
+ if (macctx == NULL || digest == NULL)
+ return 0;
+
+ if ((p = OSSL_PARAM_locate_const(params,
+ OSSL_PROV_PARAM_CORE_PROV_NAME)) == NULL)
+ return 0;
+ if (p->data_type != OSSL_PARAM_UTF8_STRING)
+ return 0;
+ if ((prov = ossl_provider_find(libctx, (const char *)p->data, 1)) == NULL)
+ return 0;
+
+ p = OSSL_PARAM_locate_const(params, OSSL_ALG_PARAM_DIGEST);
+ if (p) {
+ if (p->data_type != OSSL_PARAM_UTF8_STRING)
+ goto done;
+
+ md = evp_digest_fetch_from_prov(prov, (const char *)p->data, NULL);
+ if (md) {
+ EVP_MD_free(*digest);
+ *digest = md;
+ } else {
+ goto done;
+ }
+ }
+
+ p = OSSL_PARAM_locate_const(params, OSSL_ALG_PARAM_MAC);
+ if (p == NULL) {
+ ret = 1;
+ goto done;
+ }
+
+ if (p->data_type != OSSL_PARAM_UTF8_STRING)
+ goto done;
+
+ EVP_MAC_CTX_free(*macctx);
+ *macctx = NULL;
+
+ mac = evp_mac_fetch_from_prov(prov, (const char *)p->data, NULL);
+ if (mac) {
+ *macctx = EVP_MAC_CTX_new(mac);
+ /* The context holds on to the MAC */
+ EVP_MAC_free(mac);
+ ret = 1;
+ }
+
+done:
+ ossl_provider_free(prov);
+ return ret;
+}
+
static int drbg_hmac_set_ctx_params_locked(void *vctx, const OSSL_PARAM params[])
{
PROV_DRBG *ctx = (PROV_DRBG *)vctx;
PROV_DRBG_HMAC *hmac = (PROV_DRBG_HMAC *)ctx->data;
OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(ctx->provctx);
+ EVP_MD *prov_md = NULL;
const EVP_MD *md;
int md_size;
OSSL_DRBG_PARAM_FIPS_DIGEST_CHECK))
return 0;
- if (!ossl_prov_digest_load_from_params(&hmac->digest, params, libctx))
- return 0;
+ /* try to fetch mac and digest from provider */
+ (void)ERR_set_mark();
+ if (!drbg_fetch_algs_from_prov(params, libctx, &hmac->ctx, &prov_md)) {
+ (void)ERR_pop_to_mark();
+ /* fall back to full implementation search */
+ if (!ossl_prov_digest_load_from_params(&hmac->digest, params, libctx))
+ return 0;
+
+ if (!ossl_prov_macctx_load_from_params(&hmac->ctx, params,
+ NULL, NULL, NULL, libctx))
+ return 0;
+ } else {
+ (void)ERR_clear_last_mark();
+ if (prov_md)
+ ossl_prov_digest_set_md(&hmac->digest, prov_md);
+ }
md = ossl_prov_digest_md(&hmac->digest);
if (md != NULL && !ossl_drbg_verify_digest(ctx, libctx, md))
return 0; /* Error already raised for us */
- if (!ossl_prov_macctx_load_from_params(&hmac->ctx, params,
- NULL, NULL, NULL, libctx))
- return 0;
-
if (md != NULL && hmac->ctx != NULL) {
/* These are taken from SP 800-90 10.1 Table 2 */
md_size = EVP_MD_get_size(md);