Add FIPS indicator callback.

Add a FIPS indicator callback that can be set via
OSSL_INDICATOR_set_callback(). This callback is intended to be run
whenever a non approved algorithm check has occurred and strict checking
has been disabled.The callback may be used to
log non approved algorithms. The callback is passed a type and
description string as well as the cbarg specified in OSSL_INDICATOR_set_callback.
The return value can be either 0 or 1.
A value of 0 can be used for testing purposes to force an error to occur from the algorithm
that called the callback.

Reviewed-by: Neil Horman <nhorman@openssl.org>
Reviewed-by: Paul Dale <pauli@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/24623)
This commit is contained in:
slontis 2024-07-01 11:11:16 +10:00 committed by Pauli
parent 45cada1339
commit 0557d6c62b
11 changed files with 224 additions and 3 deletions

View File

@ -91,7 +91,7 @@ DEFINE[../providers/libdefault.a]=$CPUIDDEF
$CORE_COMMON=provider_core.c provider_predefined.c \
core_fetch.c core_algorithm.c core_namemap.c self_test_core.c
SOURCE[../libcrypto]=$CORE_COMMON provider_conf.c
SOURCE[../libcrypto]=$CORE_COMMON provider_conf.c indicator_core.c
SOURCE[../providers/libfips.a]=$CORE_COMMON
# Central utilities

View File

@ -40,6 +40,7 @@ struct ossl_lib_ctx_st {
OSSL_METHOD_STORE *encoder_store;
OSSL_METHOD_STORE *store_loader_store;
void *self_test_cb;
void *indicator_cb;
#endif
#if defined(OPENSSL_THREADS)
void *threads;
@ -177,6 +178,9 @@ static int context_init(OSSL_LIB_CTX *ctx)
ctx->self_test_cb = ossl_self_test_set_callback_new(ctx);
if (ctx->self_test_cb == NULL)
goto err;
ctx->indicator_cb = ossl_indicator_set_callback_new(ctx);
if (ctx->indicator_cb == NULL)
goto err;
#endif
#ifdef FIPS_MODULE
@ -313,6 +317,11 @@ static void context_deinit_objs(OSSL_LIB_CTX *ctx)
}
#ifndef FIPS_MODULE
if (ctx->indicator_cb != NULL) {
ossl_indicator_set_callback_free(ctx->indicator_cb);
ctx->indicator_cb = NULL;
}
if (ctx->self_test_cb != NULL) {
ossl_self_test_set_callback_free(ctx->self_test_cb);
ctx->self_test_cb = NULL;
@ -604,6 +613,8 @@ void *ossl_lib_ctx_get_data(OSSL_LIB_CTX *ctx, int index)
return ctx->store_loader_store;
case OSSL_LIB_CTX_SELF_TEST_CB_INDEX:
return ctx->self_test_cb;
case OSSL_LIB_CTX_INDICATOR_CB_INDEX:
return ctx->indicator_cb;
#endif
#ifndef OPENSSL_NO_THREAD_POOL
case OSSL_LIB_CTX_THREAD_INDEX:

55
crypto/indicator_core.c Normal file
View File

@ -0,0 +1,55 @@
/*
* Copyright 2024 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 <openssl/indicator.h>
#include <openssl/core_names.h>
#include <openssl/params.h>
#include "internal/cryptlib.h"
#include "crypto/context.h"
typedef struct indicator_cb_st
{
OSSL_INDICATOR_CALLBACK *cb;
} INDICATOR_CB;
void *ossl_indicator_set_callback_new(OSSL_LIB_CTX *ctx)
{
INDICATOR_CB *cb;
cb = OPENSSL_zalloc(sizeof(*cb));
return cb;
}
void ossl_indicator_set_callback_free(void *cb)
{
OPENSSL_free(cb);
}
static INDICATOR_CB *get_indicator_callback(OSSL_LIB_CTX *libctx)
{
return ossl_lib_ctx_get_data(libctx, OSSL_LIB_CTX_INDICATOR_CB_INDEX);
}
void OSSL_INDICATOR_set_callback(OSSL_LIB_CTX *libctx,
OSSL_INDICATOR_CALLBACK *cb)
{
INDICATOR_CB *icb = get_indicator_callback(libctx);
if (icb != NULL)
icb->cb = cb;
}
void OSSL_INDICATOR_get_callback(OSSL_LIB_CTX *libctx,
OSSL_INDICATOR_CALLBACK **cb)
{
INDICATOR_CB *icb = get_indicator_callback(libctx);
if (cb != NULL)
*cb = (icb != NULL ? icb->cb : NULL);
}

View File

@ -32,6 +32,7 @@
#include "crypto/context.h"
#ifndef FIPS_MODULE
# include <openssl/self_test.h>
# include <openssl/indicator.h>
#endif
/*
@ -1934,6 +1935,7 @@ OSSL_FUNC_BIO_up_ref_fn ossl_core_bio_up_ref;
OSSL_FUNC_BIO_free_fn ossl_core_bio_free;
OSSL_FUNC_BIO_vprintf_fn ossl_core_bio_vprintf;
OSSL_FUNC_BIO_vsnprintf_fn BIO_vsnprintf;
static OSSL_FUNC_indicator_cb_fn core_indicator_get_callback;
static OSSL_FUNC_self_test_cb_fn core_self_test_get_callback;
static OSSL_FUNC_get_entropy_fn rand_get_entropy;
static OSSL_FUNC_get_user_entropy_fn rand_get_user_entropy;
@ -2097,6 +2099,12 @@ static int core_pop_error_to_mark(const OSSL_CORE_HANDLE *handle)
return ERR_pop_to_mark();
}
static void core_indicator_get_callback(OPENSSL_CORE_CTX *libctx,
OSSL_INDICATOR_CALLBACK **cb)
{
OSSL_INDICATOR_get_callback((OSSL_LIB_CTX *)libctx, cb);
}
static void core_self_test_get_callback(OPENSSL_CORE_CTX *libctx,
OSSL_CALLBACK **cb, void **cbarg)
{
@ -2258,6 +2266,7 @@ static const OSSL_DISPATCH core_dispatch_[] = {
{ OSSL_FUNC_BIO_VPRINTF, (void (*)(void))ossl_core_bio_vprintf },
{ OSSL_FUNC_BIO_VSNPRINTF, (void (*)(void))BIO_vsnprintf },
{ OSSL_FUNC_SELF_TEST_CB, (void (*)(void))core_self_test_get_callback },
{ OSSL_FUNC_INDICATOR_CB, (void (*)(void))core_indicator_get_callback },
{ OSSL_FUNC_GET_ENTROPY, (void (*)(void))rand_get_entropy },
{ OSSL_FUNC_GET_USER_ENTROPY, (void (*)(void))rand_get_user_entropy },
{ OSSL_FUNC_CLEANUP_ENTROPY, (void (*)(void))rand_cleanup_entropy },

View File

@ -1747,6 +1747,10 @@ DEPEND[html/man3/OSSL_IETF_ATTR_SYNTAX_print.html]=man3/OSSL_IETF_ATTR_SYNTAX_pr
GENERATE[html/man3/OSSL_IETF_ATTR_SYNTAX_print.html]=man3/OSSL_IETF_ATTR_SYNTAX_print.pod
DEPEND[man/man3/OSSL_IETF_ATTR_SYNTAX_print.3]=man3/OSSL_IETF_ATTR_SYNTAX_print.pod
GENERATE[man/man3/OSSL_IETF_ATTR_SYNTAX_print.3]=man3/OSSL_IETF_ATTR_SYNTAX_print.pod
DEPEND[html/man3/OSSL_INDICATOR_set_callback.html]=man3/OSSL_INDICATOR_set_callback.pod
GENERATE[html/man3/OSSL_INDICATOR_set_callback.html]=man3/OSSL_INDICATOR_set_callback.pod
DEPEND[man/man3/OSSL_INDICATOR_set_callback.3]=man3/OSSL_INDICATOR_set_callback.pod
GENERATE[man/man3/OSSL_INDICATOR_set_callback.3]=man3/OSSL_INDICATOR_set_callback.pod
DEPEND[html/man3/OSSL_ITEM.html]=man3/OSSL_ITEM.pod
GENERATE[html/man3/OSSL_ITEM.html]=man3/OSSL_ITEM.pod
DEPEND[man/man3/OSSL_ITEM.3]=man3/OSSL_ITEM.pod
@ -3424,6 +3428,7 @@ html/man3/OSSL_HTTP_parse_url.html \
html/man3/OSSL_HTTP_transfer.html \
html/man3/OSSL_IETF_ATTR_SYNTAX.html \
html/man3/OSSL_IETF_ATTR_SYNTAX_print.html \
html/man3/OSSL_INDICATOR_set_callback.html \
html/man3/OSSL_ITEM.html \
html/man3/OSSL_LIB_CTX.html \
html/man3/OSSL_LIB_CTX_set_conf_diagnostics.html \
@ -4083,6 +4088,7 @@ man/man3/OSSL_HTTP_parse_url.3 \
man/man3/OSSL_HTTP_transfer.3 \
man/man3/OSSL_IETF_ATTR_SYNTAX.3 \
man/man3/OSSL_IETF_ATTR_SYNTAX_print.3 \
man/man3/OSSL_INDICATOR_set_callback.3 \
man/man3/OSSL_ITEM.3 \
man/man3/OSSL_LIB_CTX.3 \
man/man3/OSSL_LIB_CTX_set_conf_diagnostics.3 \

View File

@ -0,0 +1,81 @@
=pod
=head1 NAME
OSSL_INDICATOR_set_callback,
OSSL_INDICATOR_get_callback - specify a callback for FIPS indicators
=head1 SYNOPSIS
#include <openssl/indicator.h>
typedef int (OSSL_INDICATOR_CALLBACK)(const char *type, const char *desc,
const OSSL_PARAM params[]);
void OSSL_INDICATOR_set_callback(OSSL_LIB_CTX *libctx,
OSSL_INDICATOR_CALLBACK *cb);
void OSSL_INDICATOR_get_callback(OSSL_LIB_CTX *libctx,
OSSL_INDICATOR_CALLBACK **cb);
=head1 DESCRIPTION
OSSL_INDICATOR_set_callback() sets a user callback I<cb> associated with a
I<libctx> that will be called when a non approved FIPS operation is detected.
The user's callback may be triggered multiple times during an algorithm operation
to indicate different approved mode checks have failed.
Non approved operations may only occur if the user has deliberately chosen to do
so (either by setting a global FIPS configuration option or via an option in an
algorithm's operation context).
The user's callback B<OSSL_INDICATOR_CALLBACK> I<type> and I<desc>
contain the algorithm type and operation that is not approved.
I<params> is not currently used.
If the user callback returns 0, an error will occur in the caller. This can be
used for testing purposes.
=head1 RETURN VALUES
OSSL_INDICATOR_get_callback() returns the callback that has been set via
OSSL_INDICATOR_set_callback() for the given library context I<libctx>, or NULL
if no callback is currently set.
=head1 EXAMPLES
A simple indicator callback to log non approved FIPS operations
static int indicator_cb(const char *type, const char *desc,
const OSSL_PARAM params[])
{
if (type != NULL && desc != NULL)
fprintf(stdout, "%s %s is not approved\n", type, desc);
end:
/* For Testing purposes you could return 0 here to cause an error */
return 1;
}
OSSL_INDICATOR_set_callback(libctx, indicator_cb);
=head1 SEE ALSO
L<openssl-core.h(7)>,
L<OSSL_PROVIDER-FIPS(7)>
L<OSSL_LIB_CTX(3)>
=head1 HISTORY
The functions described here were added in OpenSSL 3.4.
=head1 COPYRIGHT
Copyright 2024 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
L<https://www.openssl.org/source/license.html>.
=cut

View File

@ -20,6 +20,7 @@ void *ossl_bio_core_globals_new(OSSL_LIB_CTX *);
void *ossl_child_prov_ctx_new(OSSL_LIB_CTX *);
void *ossl_prov_drbg_nonce_ctx_new(OSSL_LIB_CTX *);
void *ossl_self_test_set_callback_new(OSSL_LIB_CTX *);
void *ossl_indicator_set_callback_new(OSSL_LIB_CTX *);
void *ossl_rand_crng_ctx_new(OSSL_LIB_CTX *);
int ossl_thread_register_fips(OSSL_LIB_CTX *);
void *ossl_thread_event_ctx_new(OSSL_LIB_CTX *);
@ -38,6 +39,7 @@ void ossl_prov_conf_ctx_free(void *);
void ossl_bio_core_globals_free(void *);
void ossl_child_prov_ctx_free(void *);
void ossl_prov_drbg_nonce_ctx_free(void *);
void ossl_indicator_set_callback_free(void *cb);
void ossl_self_test_set_callback_free(void *);
void ossl_rand_crng_ctx_free(void *);
void ossl_thread_event_ctx_free(void *);

View File

@ -117,7 +117,8 @@ typedef struct ossl_ex_data_global_st {
# define OSSL_LIB_CTX_THREAD_INDEX 19
# define OSSL_LIB_CTX_DECODER_CACHE_INDEX 20
# define OSSL_LIB_CTX_COMP_METHODS 21
# define OSSL_LIB_CTX_MAX_INDEXES 21
# define OSSL_LIB_CTX_INDICATOR_CB_INDEX 22
# define OSSL_LIB_CTX_MAX_INDEXES 22
OSSL_LIB_CTX *ossl_lib_ctx_get_concrete(OSSL_LIB_CTX *ctx);
int ossl_lib_ctx_is_default(OSSL_LIB_CTX *ctx);

View File

@ -13,6 +13,7 @@
# include <stdarg.h>
# include <openssl/core.h>
# include <openssl/indicator.h>
# ifdef __cplusplus
extern "C" {
@ -182,6 +183,9 @@ OSSL_CORE_MAKE_FUNC(int, BIO_ctrl, (OSSL_CORE_BIO *bio,
#define OSSL_FUNC_GET_USER_ENTROPY 98
#define OSSL_FUNC_GET_USER_NONCE 99
#define OSSL_FUNC_INDICATOR_CB 95
OSSL_CORE_MAKE_FUNC(void, indicator_cb, (OPENSSL_CORE_CTX *ctx,
OSSL_INDICATOR_CALLBACK **cb))
#define OSSL_FUNC_SELF_TEST_CB 100
OSSL_CORE_MAKE_FUNC(void, self_test_cb, (OPENSSL_CORE_CTX *ctx, OSSL_CALLBACK **cb,
void **cbarg))
@ -588,6 +592,7 @@ OSSL_CORE_MAKE_FUNC(void *, keymgmt_new, (void *provctx))
# define OSSL_FUNC_KEYMGMT_GEN_SETTABLE_PARAMS 5
# define OSSL_FUNC_KEYMGMT_GEN 6
# define OSSL_FUNC_KEYMGMT_GEN_CLEANUP 7
OSSL_CORE_MAKE_FUNC(void *, keymgmt_gen_init,
(void *provctx, int selection, const OSSL_PARAM params[]))
OSSL_CORE_MAKE_FUNC(int, keymgmt_gen_set_template,

View File

@ -0,0 +1,31 @@
/*
* Copyright 2024 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
*/
#ifndef OPENSSL_INDICATOR_H
# define OPENSSL_INDICATOR_H
# pragma once
# ifdef __cplusplus
extern "C" {
# endif
#include <openssl/params.h>
typedef int (OSSL_INDICATOR_CALLBACK)(const char *type, const char *desc,
const OSSL_PARAM params[]);
void OSSL_INDICATOR_set_callback(OSSL_LIB_CTX *libctx,
OSSL_INDICATOR_CALLBACK *cb);
void OSSL_INDICATOR_get_callback(OSSL_LIB_CTX *libctx,
OSSL_INDICATOR_CALLBACK **cb);
# ifdef __cplusplus
}
# endif
#endif /* OPENSSL_INDICATOR_H */

View File

@ -1,5 +1,5 @@
/*
* Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 2019-2024 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
@ -14,6 +14,7 @@
#include <openssl/fips_names.h>
#include <openssl/rand.h> /* RAND_get0_public() */
#include <openssl/proverr.h>
#include <openssl/indicator.h>
#include "internal/cryptlib.h"
#include "prov/implementations.h"
#include "prov/names.h"
@ -76,6 +77,7 @@ static OSSL_FUNC_CRYPTO_secure_clear_free_fn *c_CRYPTO_secure_clear_free;
static OSSL_FUNC_CRYPTO_secure_allocated_fn *c_CRYPTO_secure_allocated;
static OSSL_FUNC_BIO_vsnprintf_fn *c_BIO_vsnprintf;
static OSSL_FUNC_self_test_cb_fn *c_stcbfn = NULL;
static OSSL_FUNC_indicator_cb_fn *c_indcbfn = NULL;
static OSSL_FUNC_core_get_libctx_fn *c_get_libctx = NULL;
typedef struct {
@ -689,6 +691,9 @@ int OSSL_provider_init_int(const OSSL_CORE_HANDLE *handle,
case OSSL_FUNC_SELF_TEST_CB:
set_func(c_stcbfn, OSSL_FUNC_self_test_cb(in));
break;
case OSSL_FUNC_INDICATOR_CB:
set_func(c_indcbfn, OSSL_FUNC_indicator_cb(in));
break;
default:
/* Just ignore anything we don't understand */
break;
@ -954,6 +959,7 @@ FIPS_FEATURE_CHECK(FIPS_security_check_enabled, fips_security_checks)
FIPS_FEATURE_CHECK(FIPS_tls_prf_ems_check, fips_tls1_prf_ems_check)
FIPS_FEATURE_CHECK(FIPS_restricted_drbg_digests_enabled,
fips_restricted_drgb_digests)
#undef FIPS_FEATURE_CHECK
void OSSL_SELF_TEST_get_callback(OSSL_LIB_CTX *libctx, OSSL_CALLBACK **cb,
@ -971,3 +977,17 @@ void OSSL_SELF_TEST_get_callback(OSSL_LIB_CTX *libctx, OSSL_CALLBACK **cb,
*cbarg = NULL;
}
}
void OSSL_INDICATOR_get_callback(OSSL_LIB_CTX *libctx,
OSSL_INDICATOR_CALLBACK **cb)
{
assert(libctx != NULL);
if (c_indcbfn != NULL && c_get_libctx != NULL) {
/* Get the parent libctx */
c_indcbfn(c_get_libctx(FIPS_get_core_handle(libctx)), cb);
} else {
if (cb != NULL)
*cb = NULL;
}
}