]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
Add FIPS indicator callback.
authorslontis <shane.lontis@oracle.com>
Mon, 1 Jul 2024 01:11:16 +0000 (11:11 +1000)
committerPauli <ppzgs1@gmail.com>
Wed, 10 Jul 2024 22:29:43 +0000 (08:29 +1000)
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)

crypto/build.info
crypto/context.c
crypto/indicator_core.c [new file with mode: 0644]
crypto/provider_core.c
doc/build.info
doc/man3/OSSL_INDICATOR_set_callback.pod [new file with mode: 0644]
include/crypto/context.h
include/internal/cryptlib.h
include/openssl/core_dispatch.h
include/openssl/indicator.h [new file with mode: 0644]
providers/fips/fipsprov.c

index 881007f8acb171fdcda0a028beb19333944b6631..2642d30754b585214d2bc888451eaa141c7467d2 100644 (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
index 1059a43b2c80abb4f53e93b58aeffda10cf29711..f3d9f384fc82a3541371385f96794d78a8ecaffc 100644 (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:
diff --git a/crypto/indicator_core.c b/crypto/indicator_core.c
new file mode 100644 (file)
index 0000000..4b3c122
--- /dev/null
@@ -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);
+}
index 693e2913d54764555a773c3d48f43eaae456bde7..266423dda955175be27bce19fce52db177daa28b 100644 (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 },
index b2689b7acebf1245bc61273e56572d4738007b5f..5c24273b63f8ce19df247273c194092968c93270 100644 (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 \
diff --git a/doc/man3/OSSL_INDICATOR_set_callback.pod b/doc/man3/OSSL_INDICATOR_set_callback.pod
new file mode 100644 (file)
index 0000000..34ead2b
--- /dev/null
@@ -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
index 7369a730fb81278bcfa4dc86e2147e06c9a6ee09..8831fcb2a5edcc9c3f3b1848eefb562c6e6d7bd0 100644 (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 *);
index 1635830500c24508a98050ee785b454a079b3371..32caabad7e5b07463f36956b8ce76b9212e39a22 100644 (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);
index a5bc2cf75d345829101a1b3e3ca7999429560d79..fa4de4954c124308c33712b5cfdd1153c25c7673 100644 (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,
diff --git a/include/openssl/indicator.h b/include/openssl/indicator.h
new file mode 100644 (file)
index 0000000..3ea0122
--- /dev/null
@@ -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 */
index 0174c6b33b41d2a717d73168e560eb00bbb2aa09..bae56a8bbae4f1d1d9a11a9567643727f44aca0f 100644 (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;
+    }
+}