Add fips provider code for handling self test data
authorShane Lontis <shane.lontis@oracle.com>
Sun, 18 Aug 2019 23:18:33 +0000 (09:18 +1000)
committerShane Lontis <shane.lontis@oracle.com>
Sun, 18 Aug 2019 23:18:33 +0000 (09:18 +1000)
More PR's related to self test will be derived from this PR.

Note: the code removed in core_get_params() was causing a freeze since the
fips module was being loaded from a config file, which then called core_get_params()
which then tried to init the config fle again...

Reviewed-by: Richard Levitte <levitte@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/9596)

crypto/provider_core.c
doc/man5/config.pod
doc/man5/fips_config.pod [new file with mode: 0644]
doc/man7/provider-base.pod
include/openssl/core_names.h
include/openssl/core_numbers.h
include/openssl/fips_names.h [new file with mode: 0644]
providers/fips/fipsprov.c
providers/fips/selftest.h [new file with mode: 0644]

index 6abada3..541a1e1 100644 (file)
@@ -9,6 +9,7 @@
 
 #include <openssl/core.h>
 #include <openssl/core_numbers.h>
+#include <openssl/core_names.h>
 #include <openssl/params.h>
 #include <openssl/opensslv.h>
 #include "internal/cryptlib_int.h"
@@ -751,7 +752,7 @@ const OSSL_ALGORITHM *ossl_provider_query_operation(const OSSL_PROVIDER *prov,
  * never knows.
  */
 static const OSSL_PARAM param_types[] = {
-    OSSL_PARAM_DEFN("openssl-verstion", OSSL_PARAM_UTF8_PTR, NULL, 0),
+    OSSL_PARAM_DEFN("openssl-version", OSSL_PARAM_UTF8_PTR, NULL, 0),
     OSSL_PARAM_DEFN("provider-name", OSSL_PARAM_UTF8_PTR, NULL, 0),
     OSSL_PARAM_END
 };
@@ -781,16 +782,16 @@ static int core_get_params(const OSSL_PROVIDER *prov, OSSL_PARAM params[])
     int i;
     OSSL_PARAM *p;
 
-#ifndef FIPS_MODE
-    /* Load config before we attempt to read any provider parameters */
-    OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CONFIG, NULL);
-#endif
-
     if ((p = OSSL_PARAM_locate(params, "openssl-version")) != NULL)
         OSSL_PARAM_set_utf8_ptr(p, OPENSSL_VERSION_STR);
     if ((p = OSSL_PARAM_locate(params, "provider-name")) != NULL)
         OSSL_PARAM_set_utf8_ptr(p, prov->name);
 
+#ifndef FIPS_MODE
+    if ((p = OSSL_PARAM_locate(params, OSSL_PROV_PARAM_MODULE_FILENAME)) != NULL)
+        OSSL_PARAM_set_utf8_ptr(p, ossl_provider_module_path(prov));
+#endif
+
     if (prov->parameters == NULL)
         return 1;
 
@@ -800,7 +801,6 @@ static int core_get_params(const OSSL_PROVIDER *prov, OSSL_PARAM params[])
         if ((p = OSSL_PARAM_locate(params, pair->name)) != NULL)
             OSSL_PARAM_set_utf8_ptr(p, pair->value);
     }
-
     return 1;
 }
 
@@ -868,6 +868,10 @@ static const OSSL_DISPATCH core_dispatch_[] = {
     { OSSL_FUNC_CORE_NEW_ERROR, (void (*)(void))core_new_error },
     { OSSL_FUNC_CORE_SET_ERROR_DEBUG, (void (*)(void))core_set_error_debug },
     { OSSL_FUNC_CORE_VSET_ERROR, (void (*)(void))core_vset_error },
+    { OSSL_FUNC_BIO_NEW_FILE, (void (*)(void))BIO_new_file },
+    { OSSL_FUNC_BIO_NEW_MEMBUF, (void (*)(void))BIO_new_mem_buf },
+    { OSSL_FUNC_BIO_READ, (void (*)(void))BIO_read },
+    { OSSL_FUNC_BIO_FREE, (void (*)(void))BIO_free },
 #endif
 
     { OSSL_FUNC_CRYPTO_MALLOC, (void (*)(void))CRYPTO_malloc },
index cac4ef6..deed6d9 100644 (file)
@@ -504,7 +504,7 @@ file.
 
 =head1 SEE ALSO
 
-L<x509(1)>, L<req(1)>, L<ca(1)>
+L<x509(1)>, L<req(1)>, L<ca(1)>, L<fips_config(5)>
 
 =head1 COPYRIGHT
 
diff --git a/doc/man5/fips_config.pod b/doc/man5/fips_config.pod
new file mode 100644 (file)
index 0000000..7f08fd0
--- /dev/null
@@ -0,0 +1,71 @@
+=pod
+
+=head1 NAME
+
+OPENSSL FIPS CONFIGURATION
+
+=head1 DESCRIPTION
+
+A separate configuration file containing data related to FIPS 'self tests' is
+written to during installation time.
+This data is used for 2 purposes when the fips module is loaded:
+
+=over 4
+
+=item - Verify the module's checksum each time the fips module loads.
+
+=item - Run the startup FIPS self test KATS (known answer tests).
+This only needs to be run once during installation.
+
+=back
+
+The supported options are:
+
+=over 4
+
+=item B<module-checksum>
+
+The calculated MAC of the module file
+
+=item B<install-version>
+
+A version number for the fips install process. Should be 1.
+
+=item B<install-status>
+
+The install status indicator description that will be verified.
+If this field is not present the FIPS self tests will run when the fips module
+loads.
+This value should only be written to after the FIPS module has
+successfully passed its self tests during installation.
+
+=item B<install-checksum>
+
+The calculated MAC of the install status indicator.
+It is initially empty and is written to at the same time as the install_status.
+
+=back
+
+For example:
+
+ [fips_install]
+
+ install-version = 1
+ module-checksum = 41:D0:FA:C2:5D:41:75:CD:7D:C3:90:55:6F:A4:DC
+ install-checksum = FE:10:13:5A:D3:B4:C7:82:1B:1E:17:4C:AC:84:0C
+ install-status = INSTALL_SELF_TEST_KATS_RUN
+
+=head1 SEE ALSO
+
+L<config(5)>
+
+=head1 COPYRIGHT
+
+Copyright 2019 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 0f28ce7..6c43cdd 100644 (file)
@@ -108,6 +108,10 @@ provider):
  CRYPTO_secure_free             OSSL_FUNC_CRYPTO_SECURE_FREE
  CRYPTO_secure_clear_free       OSSL_FUNC_CRYPTO_SECURE_CLEAR_FREE
  CRYPTO_secure_allocated        OSSL_FUNC_CRYPTO_SECURE_ALLOCATED
+ BIO_new_file                   OSSL_FUNC_BIO_NEW_FILE
+ BIO_new_mem_buf                OSSL_FUNC_BIO_NEW_MEMBUF
+ BIO_read                       OSSL_FUNC_BIO_READ
+ BIO_free                       OSSL_FUNC_BIO_FREE
  OPENSSL_cleanse                OSSL_FUNC_OPENSSL_CLEANSE
  OPENSSL_hexstr2buf             OSSL_FUNC_OPENSSL_HEXSTR2BUF
 
@@ -178,6 +182,7 @@ CRYPTO_strndup(), CRYPTO_free(), CRYPTO_clear_free(),
 CRYPTO_realloc(), CRYPTO_clear_realloc(), CRYPTO_secure_malloc(),
 CRYPTO_secure_zalloc(), CRYPTO_secure_free(),
 CRYPTO_secure_clear_free(), CRYPTO_secure_allocated(),
+BIO_new_file(), BIO_new_mem_buf(), BIO_read(), BIO_free(),
 OPENSSL_cleanse(), and OPENSSL_hexstr2buf() correspond exactly to the
 public functions with the same name.
 As a matter of fact, the pointers in the B<OSSL_DISPATCH> array are
index e2d16be..c1bc3a7 100644 (file)
@@ -34,6 +34,11 @@ extern "C" {
  */
 #define OSSL_PROV_PARAM_BUILDINFO   "buildinfo"
 
+/*
+ * The module filename
+ * Type: OSSL_PARAM_OCTET_STRING
+ */
+#define OSSL_PROV_PARAM_MODULE_FILENAME "module-filename"
 
 /* cipher parameters */
 #define OSSL_CIPHER_PARAM_PADDING   "padding"    /* int */
index ad8b345..95cfe46 100644 (file)
@@ -118,6 +118,18 @@ OSSL_CORE_MAKE_FUNC(int,
 OSSL_CORE_MAKE_FUNC(void,
         OPENSSL_cleanse, (void *ptr, size_t len))
 
+/* Bio functions provided by the core */
+#define OSSL_FUNC_BIO_NEW_FILE                22
+#define OSSL_FUNC_BIO_NEW_MEMBUF              23
+#define OSSL_FUNC_BIO_READ                    24
+#define OSSL_FUNC_BIO_FREE                    25
+
+OSSL_CORE_MAKE_FUNC(BIO *, BIO_new_file, (const char *filename, const char *mode))
+OSSL_CORE_MAKE_FUNC(BIO *, BIO_new_membuf, (const void *buf, int len))
+OSSL_CORE_MAKE_FUNC(int, BIO_read, (BIO *bio, void *data, size_t data_len,
+                                    size_t *bytes_read))
+OSSL_CORE_MAKE_FUNC(int, BIO_free, (BIO *bio))
+
 /* Functions provided by the provider to the Core, reserved numbers 1024-1535 */
 # define OSSL_FUNC_PROVIDER_TEARDOWN         1024
 OSSL_CORE_MAKE_FUNC(void,provider_teardown,(void *provctx))
diff --git a/include/openssl/fips_names.h b/include/openssl/fips_names.h
new file mode 100644 (file)
index 0000000..28226f5
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2019 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 OSSL_FIPS_NAMES_H
+# define OSSL_FIPS_NAMES_H
+
+# ifdef __cplusplus
+extern "C" {
+# endif
+
+/*
+ * Parameter names that the FIPS Provider defines
+ */
+
+/*
+ * The calculated MAC of the module file (Used for FIPS Self Testing)
+ * Type: OSSL_PARAM_UTF8_STRING
+ */
+# define OSSL_PROV_FIPS_PARAM_MODULE_MAC      "module-checksum"
+/*
+ * A version number for the fips install process (Used for FIPS Self Testing)
+ * Type: OSSL_PARAM_UTF8_STRING
+ */
+# define OSSL_PROV_FIPS_PARAM_INSTALL_VERSION "install-version"
+/*
+ * The calculated MAC of the install status indicator (Used for FIPS Self Testing)
+ * Type: OSSL_PARAM_UTF8_STRING
+ */
+# define OSSL_PROV_FIPS_PARAM_INSTALL_MAC     "install-checksum"
+/*
+ * The install status indicator (Used for FIPS Self Testing)
+ * Type: OSSL_PARAM_UTF8_STRING
+ */
+# define OSSL_PROV_FIPS_PARAM_INSTALL_STATUS  "install-status"
+
+# ifdef __cplusplus
+}
+# endif
+
+#endif /* OSSL_FIPS_NAMES_H */
index d2d3e60..7afe4f9 100644 (file)
@@ -20,6 +20,7 @@
 #include <openssl/sha.h>
 #include <openssl/rand_drbg.h>
 #include <openssl/ec.h>
+#include <openssl/fips_names.h>
 
 #include "internal/cryptlib.h"
 #include "internal/property.h"
@@ -27,6 +28,7 @@
 #include "internal/provider_algs.h"
 #include "internal/provider_ctx.h"
 #include "internal/providercommon.h"
+#include "selftest.h"
 
 extern OSSL_core_thread_start_fn *c_thread_start;
 
@@ -36,6 +38,9 @@ extern OSSL_core_thread_start_fn *c_thread_start;
  * at the moment because c_put_error/c_add_error_vdata do not provide
  * us with the OPENSSL_CTX as a parameter.
  */
+
+static SELF_TEST_POST_PARAMS selftest_params;
+
 /* Functions provided by the core */
 static OSSL_core_gettable_params_fn *c_gettable_params;
 static OSSL_core_get_params_fn *c_get_params;
@@ -85,6 +90,31 @@ static const OSSL_PARAM fips_param_types[] = {
     OSSL_PARAM_END
 };
 
+/*
+ * Parameters to retrieve from the core provider - required for self testing.
+ * NOTE: inside core_get_params() these will be loaded from config items
+ * stored inside prov->parameters (except for OSSL_PROV_PARAM_MODULE_FILENAME).
+ */
+static OSSL_PARAM core_params[] =
+{
+    OSSL_PARAM_utf8_ptr(OSSL_PROV_PARAM_MODULE_FILENAME,
+                        selftest_params.module_filename,
+                        sizeof(selftest_params.module_filename)),
+    OSSL_PARAM_utf8_ptr(OSSL_PROV_FIPS_PARAM_MODULE_MAC,
+                        selftest_params.module_checksum_data,
+                        sizeof(selftest_params.module_checksum_data)),
+    OSSL_PARAM_utf8_ptr(OSSL_PROV_FIPS_PARAM_INSTALL_MAC,
+                        selftest_params.indicator_checksum_data,
+                        sizeof(selftest_params.indicator_checksum_data)),
+    OSSL_PARAM_utf8_ptr(OSSL_PROV_FIPS_PARAM_INSTALL_STATUS,
+                        selftest_params.indicator_data,
+                        sizeof(selftest_params.indicator_data)),
+    OSSL_PARAM_utf8_ptr(OSSL_PROV_FIPS_PARAM_INSTALL_VERSION,
+                        selftest_params.indicator_version,
+                        sizeof(selftest_params.indicator_version)),
+    OSSL_PARAM_END
+};
+
 /* TODO(3.0): To be removed */
 static int dummy_evp_call(void *provctx)
 {
@@ -384,12 +414,27 @@ int OSSL_provider_init(const OSSL_PROVIDER *provider,
         case OSSL_FUNC_CRYPTO_SECURE_ALLOCATED:
             c_CRYPTO_secure_allocated = OSSL_get_CRYPTO_secure_allocated(in);
             break;
+        case OSSL_FUNC_BIO_NEW_FILE:
+            selftest_params.bio_new_file_cb = OSSL_get_BIO_new_file(in);
+            break;
+        case OSSL_FUNC_BIO_NEW_MEMBUF:
+            selftest_params.bio_new_buffer_cb = OSSL_get_BIO_new_membuf(in);
+            break;
+        case OSSL_FUNC_BIO_READ:
+            selftest_params.bio_read_cb = OSSL_get_BIO_read(in);
+            break;
+        case OSSL_FUNC_BIO_FREE:
+            selftest_params.bio_free_cb = OSSL_get_BIO_free(in);
+            break;
         default:
             /* Just ignore anything we don't understand */
             break;
         }
     }
 
+    if (!c_get_params(provider, core_params))
+        return 0;
+
     /*  Create a context. */
     if ((ctx = OPENSSL_CTX_new()) == NULL)
         return 0;
diff --git a/providers/fips/selftest.h b/providers/fips/selftest.h
new file mode 100644 (file)
index 0000000..3a183f4
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (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/params.h>
+#include <openssl/core_numbers.h>
+
+typedef struct self_test_post_params_st {
+    /* FIPS module integrity check parameters */
+    const char *module_filename;            /* Module file to perform MAC on */
+    const char *module_checksum_data;       /* Expected module MAC integrity */
+
+    /* Used for KAT install indicator integrity check */
+    const char *indicator_version;          /* version - for future proofing */
+    const char *indicator_data;             /* data to perform MAC on */
+    const char *indicator_checksum_data;    /* Expected MAC integrity value */
+
+    /* BIO callbacks supplied to the FIPS provider */
+    OSSL_BIO_new_file_fn *bio_new_file_cb;
+    OSSL_BIO_new_membuf_fn *bio_new_buffer_cb;
+    OSSL_BIO_read_fn *bio_read_cb;
+    OSSL_BIO_free_fn *bio_free_cb;
+
+} SELF_TEST_POST_PARAMS;