#include "crypto/cryptlib.h"
#include "rand_local.h"
#include "crypto/context.h"
+#include "internal/provider.h"
#ifndef OPENSSL_DEFAULT_SEED_SRC
# define OPENSSL_DEFAULT_SEED_SRC SEED-SRC
EVP_RAND *rand;
RAND_GLOBAL *dgbl = rand_get_global(libctx);
EVP_RAND_CTX *ctx;
- OSSL_PARAM params[8], *p = params;
+ OSSL_PARAM params[9], *p = params;
const OSSL_PARAM *settables;
+ const char *prov_name;
char *name, *cipher;
int use_df = 1;
ERR_raise(ERR_LIB_RAND, RAND_R_UNABLE_TO_FETCH_DRBG);
return NULL;
}
+ prov_name = ossl_provider_name(EVP_RAND_get0_provider(rand));
ctx = EVP_RAND_CTX_new(rand, parent);
EVP_RAND_free(rand);
if (ctx == NULL) {
&& OSSL_PARAM_locate_const(settables, OSSL_DRBG_PARAM_DIGEST))
*p++ = OSSL_PARAM_construct_utf8_string(OSSL_DRBG_PARAM_DIGEST,
dgbl->rng_digest, 0);
+ if (prov_name != NULL)
+ *p++ = OSSL_PARAM_construct_utf8_string(OSSL_PROV_PARAM_CORE_PROV_NAME,
+ (char *)prov_name, 0);
if (dgbl->rng_propq != NULL)
*p++ = OSSL_PARAM_construct_utf8_string(OSSL_DRBG_PARAM_PROPERTIES,
dgbl->rng_propq, 0);
#include "prov/providercommon.h"
#include "prov/provider_ctx.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_ctr_new_wrapper;
static OSSL_FUNC_rand_freectx_fn drbg_ctr_free;
PROV_DRBG *ctx = (PROV_DRBG *)vctx;
PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)ctx->data;
OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(ctx->provctx);
+ OSSL_PROVIDER *prov = NULL;
const OSSL_PARAM *p;
char *ecb;
const char *propquery = NULL;
propquery = (const char *)p->data;
}
+ if ((p = OSSL_PARAM_locate_const(params,
+ OSSL_PROV_PARAM_CORE_PROV_NAME)) != NULL) {
+ if (p->data_type != OSSL_PARAM_UTF8_STRING)
+ return 0;
+ if ((prov = ossl_provider_find(libctx,
+ (const char *)p->data, 1)) == NULL)
+ return 0;
+ }
+
if ((p = OSSL_PARAM_locate_const(params, OSSL_DRBG_PARAM_CIPHER)) != NULL) {
const char *base = (const char *)p->data;
size_t ctr_str_len = sizeof("CTR") - 1;
size_t ecb_str_len = sizeof("ECB") - 1;
if (p->data_type != OSSL_PARAM_UTF8_STRING
- || p->data_size < ctr_str_len)
+ || p->data_size < ctr_str_len) {
+ ossl_provider_free(prov);
return 0;
+ }
if (OPENSSL_strcasecmp("CTR", base + p->data_size - ctr_str_len) != 0) {
ERR_raise(ERR_LIB_PROV, PROV_R_REQUIRE_CTR_MODE_CIPHER);
+ ossl_provider_free(prov);
return 0;
}
- if ((ecb = OPENSSL_strndup(base, p->data_size)) == NULL)
+ if ((ecb = OPENSSL_strndup(base, p->data_size)) == NULL) {
+ ossl_provider_free(prov);
return 0;
+ }
strcpy(ecb + p->data_size - ecb_str_len, "ECB");
EVP_CIPHER_free(ctr->cipher_ecb);
EVP_CIPHER_free(ctr->cipher_ctr);
- ctr->cipher_ctr = EVP_CIPHER_fetch(libctx, base, propquery);
- ctr->cipher_ecb = EVP_CIPHER_fetch(libctx, ecb, propquery);
+ /*
+ * Try to fetch algorithms from our own provider code, fallback
+ * to generic fetch only if that fails
+ */
+ (void)ERR_set_mark();
+ ctr->cipher_ctr = evp_cipher_fetch_from_prov(prov, base, NULL);
+ if (ctr->cipher_ctr == NULL) {
+ (void)ERR_pop_to_mark();
+ ctr->cipher_ctr = EVP_CIPHER_fetch(libctx, base, propquery);
+ } else {
+ (void)ERR_clear_last_mark();
+ }
+ (void)ERR_set_mark();
+ ctr->cipher_ecb = evp_cipher_fetch_from_prov(prov, ecb, NULL);
+ if (ctr->cipher_ecb == NULL) {
+ (void)ERR_pop_to_mark();
+ ctr->cipher_ecb = EVP_CIPHER_fetch(libctx, ecb, propquery);
+ } else {
+ (void)ERR_clear_last_mark();
+ }
OPENSSL_free(ecb);
if (ctr->cipher_ctr == NULL || ctr->cipher_ecb == NULL) {
ERR_raise(ERR_LIB_PROV, PROV_R_UNABLE_TO_FIND_CIPHERS);
+ ossl_provider_free(prov);
return 0;
}
cipher_init = 1;
}
+ ossl_provider_free(prov);
if (cipher_init && !drbg_ctr_init(ctx))
return 0;