Latest update.
This commit is contained in:
+83
-46
@@ -34,6 +34,15 @@
|
||||
#include "prov/provider_util.h"
|
||||
#include "self_test.h"
|
||||
|
||||
/*
|
||||
* Forward declarations to ensure that interface functions are correctly
|
||||
* defined.
|
||||
*/
|
||||
static OSSL_provider_teardown_fn fips_teardown;
|
||||
static OSSL_provider_gettable_params_fn fips_gettable_params;
|
||||
static OSSL_provider_get_params_fn fips_get_params;
|
||||
static OSSL_provider_query_operation_fn fips_query;
|
||||
|
||||
#define ALGC(NAMES, FUNC, CHECK) { { NAMES, "provider=fips,fips=yes", FUNC }, CHECK }
|
||||
#define ALG(NAMES, FUNC) ALGC(NAMES, FUNC, NULL)
|
||||
|
||||
@@ -72,7 +81,7 @@ static OSSL_CRYPTO_secure_allocated_fn *c_CRYPTO_secure_allocated;
|
||||
static OSSL_BIO_vsnprintf_fn *c_BIO_vsnprintf;
|
||||
|
||||
typedef struct fips_global_st {
|
||||
const OSSL_PROVIDER *prov;
|
||||
const OSSL_CORE_HANDLE *handle;
|
||||
} FIPS_GLOBAL;
|
||||
|
||||
static void *fips_prov_ossl_ctx_new(OPENSSL_CTX *libctx)
|
||||
@@ -127,9 +136,8 @@ static OSSL_PARAM core_params[] =
|
||||
};
|
||||
|
||||
/* TODO(3.0): To be removed */
|
||||
static int dummy_evp_call(void *provctx)
|
||||
static int dummy_evp_call(OPENSSL_CTX *libctx)
|
||||
{
|
||||
OPENSSL_CTX *libctx = PROV_LIBRARY_CONTEXT_OF(provctx);
|
||||
EVP_MD_CTX *ctx = EVP_MD_CTX_new();
|
||||
EVP_MD *sha256 = EVP_MD_fetch(libctx, "SHA256", NULL);
|
||||
EVP_KDF *kdf = EVP_KDF_fetch(libctx, OSSL_KDF_NAME_PBKDF2, NULL);
|
||||
@@ -208,12 +216,12 @@ static int dummy_evp_call(void *provctx)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const OSSL_PARAM *fips_gettable_params(const OSSL_PROVIDER *prov)
|
||||
static const OSSL_PARAM *fips_gettable_params(void *provctx)
|
||||
{
|
||||
return fips_param_types;
|
||||
}
|
||||
|
||||
static int fips_get_params(const OSSL_PROVIDER *prov, OSSL_PARAM params[])
|
||||
static int fips_get_params(void *provctx, OSSL_PARAM params[])
|
||||
{
|
||||
OSSL_PARAM *p;
|
||||
|
||||
@@ -233,7 +241,7 @@ static int fips_get_params(const OSSL_PROVIDER *prov, OSSL_PARAM params[])
|
||||
/* FIPS specific version of the function of the same name in provlib.c */
|
||||
const char *ossl_prov_util_nid_to_name(int nid)
|
||||
{
|
||||
/* We don't have OBJ_nid2n() in FIPS_MODE so we have an explicit list */
|
||||
/* We don't have OBJ_nid2n() in FIPS_MODULE so we have an explicit list */
|
||||
|
||||
switch (nid) {
|
||||
/* Digests */
|
||||
@@ -469,6 +477,7 @@ static const OSSL_ALGORITHM fips_keymgmt[] = {
|
||||
{ "DSA", "provider=fips,fips=yes", dsa_keymgmt_functions },
|
||||
#endif
|
||||
{ "RSA:rsaEncryption", "provider=fips,fips=yes", rsa_keymgmt_functions },
|
||||
{ "RSA-PSS:RSASSA-PSS", "provider=default", rsapss_keymgmt_functions },
|
||||
#ifndef OPENSSL_NO_EC
|
||||
{ "EC:id-ecPublicKey", "provider=fips,fips=yes", ec_keymgmt_functions },
|
||||
{ "X25519", "provider=fips,fips=no", x25519_keymgmt_functions },
|
||||
@@ -479,9 +488,8 @@ static const OSSL_ALGORITHM fips_keymgmt[] = {
|
||||
{ NULL, NULL, NULL }
|
||||
};
|
||||
|
||||
static const OSSL_ALGORITHM *fips_query(OSSL_PROVIDER *prov,
|
||||
int operation_id,
|
||||
int *no_cache)
|
||||
static const OSSL_ALGORITHM *fips_query(void *provctx, int operation_id,
|
||||
int *no_cache)
|
||||
{
|
||||
*no_cache = 0;
|
||||
switch (operation_id) {
|
||||
@@ -506,13 +514,24 @@ static const OSSL_ALGORITHM *fips_query(OSSL_PROVIDER *prov,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void fips_teardown(void *provctx)
|
||||
{
|
||||
OPENSSL_CTX_free(PROV_LIBRARY_CONTEXT_OF(provctx));
|
||||
PROV_CTX_free(provctx);
|
||||
}
|
||||
|
||||
static void fips_intern_teardown(void *provctx)
|
||||
{
|
||||
/*
|
||||
* We know that the library context is the same as for the outer provider,
|
||||
* so no need to destroy it here.
|
||||
*/
|
||||
PROV_CTX_free(provctx);
|
||||
}
|
||||
|
||||
/* Functions we provide to the core */
|
||||
static const OSSL_DISPATCH fips_dispatch_table[] = {
|
||||
/*
|
||||
* To release our resources we just need to free the OPENSSL_CTX so we just
|
||||
* use OPENSSL_CTX_free directly as our teardown function
|
||||
*/
|
||||
{ OSSL_FUNC_PROVIDER_TEARDOWN, (void (*)(void))OPENSSL_CTX_free },
|
||||
{ OSSL_FUNC_PROVIDER_TEARDOWN, (void (*)(void))fips_teardown },
|
||||
{ OSSL_FUNC_PROVIDER_GETTABLE_PARAMS, (void (*)(void))fips_gettable_params },
|
||||
{ OSSL_FUNC_PROVIDER_GET_PARAMS, (void (*)(void))fips_get_params },
|
||||
{ OSSL_FUNC_PROVIDER_QUERY_OPERATION, (void (*)(void))fips_query },
|
||||
@@ -521,18 +540,19 @@ static const OSSL_DISPATCH fips_dispatch_table[] = {
|
||||
|
||||
/* Functions we provide to ourself */
|
||||
static const OSSL_DISPATCH intern_dispatch_table[] = {
|
||||
{ OSSL_FUNC_PROVIDER_TEARDOWN, (void (*)(void))fips_intern_teardown },
|
||||
{ OSSL_FUNC_PROVIDER_QUERY_OPERATION, (void (*)(void))fips_query },
|
||||
{ 0, NULL }
|
||||
};
|
||||
|
||||
|
||||
int OSSL_provider_init(const OSSL_PROVIDER *provider,
|
||||
int OSSL_provider_init(const OSSL_CORE_HANDLE *handle,
|
||||
const OSSL_DISPATCH *in,
|
||||
const OSSL_DISPATCH **out,
|
||||
void **provctx)
|
||||
{
|
||||
FIPS_GLOBAL *fgbl;
|
||||
OPENSSL_CTX *ctx;
|
||||
OPENSSL_CTX *libctx = NULL;
|
||||
OSSL_self_test_cb_fn *stcbfn = NULL;
|
||||
OSSL_core_get_library_context_fn *c_get_libctx = NULL;
|
||||
|
||||
@@ -627,7 +647,7 @@ int OSSL_provider_init(const OSSL_PROVIDER *provider,
|
||||
}
|
||||
|
||||
if (stcbfn != NULL && c_get_libctx != NULL) {
|
||||
stcbfn(c_get_libctx(provider), &selftest_params.cb,
|
||||
stcbfn(c_get_libctx(handle), &selftest_params.cb,
|
||||
&selftest_params.cb_arg);
|
||||
}
|
||||
else {
|
||||
@@ -635,39 +655,47 @@ int OSSL_provider_init(const OSSL_PROVIDER *provider,
|
||||
selftest_params.cb_arg = NULL;
|
||||
}
|
||||
|
||||
if (!c_get_params(provider, core_params))
|
||||
if (!c_get_params(handle, core_params))
|
||||
return 0;
|
||||
|
||||
/* Create a context. */
|
||||
if ((ctx = OPENSSL_CTX_new()) == NULL)
|
||||
return 0;
|
||||
if ((fgbl = openssl_ctx_get_data(ctx, OPENSSL_CTX_FIPS_PROV_INDEX,
|
||||
&fips_prov_ossl_ctx_method)) == NULL) {
|
||||
OPENSSL_CTX_free(ctx);
|
||||
return 0;
|
||||
if ((*provctx = PROV_CTX_new()) == NULL
|
||||
|| (libctx = OPENSSL_CTX_new()) == NULL) {
|
||||
/*
|
||||
* We free libctx separately here and only here because it hasn't
|
||||
* been attached to *provctx. All other error paths below rely
|
||||
* solely on fips_teardown.
|
||||
*/
|
||||
OPENSSL_CTX_free(libctx);
|
||||
goto err;
|
||||
}
|
||||
PROV_CTX_set0_library_context(*provctx, libctx);
|
||||
PROV_CTX_set0_handle(*provctx, handle);
|
||||
|
||||
fgbl->prov = provider;
|
||||
if ((fgbl = openssl_ctx_get_data(libctx, OPENSSL_CTX_FIPS_PROV_INDEX,
|
||||
&fips_prov_ossl_ctx_method)) == NULL)
|
||||
goto err;
|
||||
|
||||
selftest_params.libctx = PROV_LIBRARY_CONTEXT_OF(ctx);
|
||||
if (!SELF_TEST_post(&selftest_params, 0)) {
|
||||
OPENSSL_CTX_free(ctx);
|
||||
return 0;
|
||||
}
|
||||
fgbl->handle = handle;
|
||||
|
||||
selftest_params.libctx = libctx;
|
||||
if (!SELF_TEST_post(&selftest_params, 0))
|
||||
goto err;
|
||||
|
||||
/*
|
||||
* TODO(3.0): Remove me. This is just a dummy call to demonstrate making
|
||||
* EVP calls from within the FIPS module.
|
||||
*/
|
||||
if (!dummy_evp_call(ctx)) {
|
||||
OPENSSL_CTX_free(ctx);
|
||||
return 0;
|
||||
}
|
||||
if (!dummy_evp_call(libctx))
|
||||
goto err;
|
||||
|
||||
*out = fips_dispatch_table;
|
||||
*provctx = ctx;
|
||||
|
||||
return 1;
|
||||
err:
|
||||
fips_teardown(*provctx);
|
||||
*provctx = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -678,7 +706,7 @@ int OSSL_provider_init(const OSSL_PROVIDER *provider,
|
||||
* that was used in the EVP call that initiated this recursive call.
|
||||
*/
|
||||
OSSL_provider_init_fn fips_intern_provider_init;
|
||||
int fips_intern_provider_init(const OSSL_PROVIDER *provider,
|
||||
int fips_intern_provider_init(const OSSL_CORE_HANDLE *handle,
|
||||
const OSSL_DISPATCH *in,
|
||||
const OSSL_DISPATCH **out,
|
||||
void **provctx)
|
||||
@@ -698,14 +726,15 @@ int fips_intern_provider_init(const OSSL_PROVIDER *provider,
|
||||
if (c_get_libctx == NULL)
|
||||
return 0;
|
||||
|
||||
*provctx = c_get_libctx(provider);
|
||||
|
||||
/*
|
||||
* Safety measure... we should get the library context that was
|
||||
* created up in OSSL_provider_init().
|
||||
*/
|
||||
if (*provctx == NULL)
|
||||
if ((*provctx = PROV_CTX_new()) == NULL)
|
||||
return 0;
|
||||
/*
|
||||
* Using the parent library context only works because we are a built-in
|
||||
* internal provider. This is not something that most providers would be
|
||||
* able to do.
|
||||
*/
|
||||
PROV_CTX_set0_library_context(*provctx, (OPENSSL_CTX *)c_get_libctx(handle));
|
||||
PROV_CTX_set0_handle(*provctx, handle);
|
||||
|
||||
*out = intern_dispatch_table;
|
||||
return 1;
|
||||
@@ -750,15 +779,23 @@ int ERR_pop_to_mark(void)
|
||||
return c_pop_error_to_mark(NULL);
|
||||
}
|
||||
|
||||
const OSSL_PROVIDER *FIPS_get_provider(OPENSSL_CTX *ctx)
|
||||
/*
|
||||
* This must take a library context, since it's called from the depths
|
||||
* of crypto/initthread.c code, where it's (correctly) assumed that the
|
||||
* passed caller argument is an OPENSSL_CTX pointer (since the same routine
|
||||
* is also called from other parts of libcrypto, which all pass around a
|
||||
* OPENSSL_CTX pointer)
|
||||
*/
|
||||
const OSSL_CORE_HANDLE *FIPS_get_core_handle(OPENSSL_CTX *libctx)
|
||||
{
|
||||
FIPS_GLOBAL *fgbl = openssl_ctx_get_data(ctx, OPENSSL_CTX_FIPS_PROV_INDEX,
|
||||
FIPS_GLOBAL *fgbl = openssl_ctx_get_data(libctx,
|
||||
OPENSSL_CTX_FIPS_PROV_INDEX,
|
||||
&fips_prov_ossl_ctx_method);
|
||||
|
||||
if (fgbl == NULL)
|
||||
return NULL;
|
||||
|
||||
return fgbl->prov;
|
||||
return fgbl->handle;
|
||||
}
|
||||
|
||||
void *CRYPTO_malloc(size_t num, const char *file, int line)
|
||||
|
||||
Reference in New Issue
Block a user