| 
									
										
										
										
											2019-09-15 17:55:10 +08:00
										 |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2021-02-18 22:57:13 +08:00
										 |  |  |  * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. | 
					
						
							| 
									
										
										
										
											2019-09-15 17:55:10 +08:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2020-04-27 12:59:50 +08:00
										 |  |  |  * Licensed under the Apache License 2.0 (the "License").  You may not use | 
					
						
							| 
									
										
										
										
											2019-09-15 17:55:10 +08:00
										 |  |  |  * 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 <string.h>
 | 
					
						
							|  |  |  | #include <openssl/evp.h>
 | 
					
						
							|  |  |  | #include <openssl/params.h>
 | 
					
						
							| 
									
										
										
										
											2019-09-19 00:27:10 +08:00
										 |  |  | #include <openssl/crypto.h>
 | 
					
						
							| 
									
										
										
										
											2021-05-26 03:08:03 +08:00
										 |  |  | #include "internal/cryptlib.h"
 | 
					
						
							| 
									
										
										
										
											2020-06-29 10:20:41 +08:00
										 |  |  | #include <openssl/fipskey.h>
 | 
					
						
							| 
									
										
										
										
											2020-07-21 14:30:02 +08:00
										 |  |  | #include <openssl/err.h>
 | 
					
						
							| 
									
										
										
										
											2021-02-06 00:40:42 +08:00
										 |  |  | #include <openssl/proverr.h>
 | 
					
						
							| 
									
										
										
										
											2019-09-19 00:27:10 +08:00
										 |  |  | #include "e_os.h"
 | 
					
						
							| 
									
										
										
										
											2020-09-07 09:58:48 +08:00
										 |  |  | #include "prov/providercommon.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-19 00:27:10 +08:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * We're cheating here. Normally we don't allow RUN_ONCE usage inside the FIPS | 
					
						
							|  |  |  |  * module because all such initialisation should be associated with an | 
					
						
							| 
									
										
										
										
											2020-10-15 17:55:50 +08:00
										 |  |  |  * individual OSSL_LIB_CTX. That doesn't work with the self test though because | 
					
						
							|  |  |  |  * it should be run once regardless of the number of OSSL_LIB_CTXs we have. | 
					
						
							| 
									
										
										
										
											2019-09-19 00:27:10 +08:00
										 |  |  |  */ | 
					
						
							|  |  |  | #define ALLOW_RUN_ONCE_IN_FIPS
 | 
					
						
							| 
									
										
										
										
											2021-05-26 03:08:03 +08:00
										 |  |  | #include "internal/thread_once.h"
 | 
					
						
							| 
									
										
										
										
											2020-01-15 08:48:01 +08:00
										 |  |  | #include "self_test.h"
 | 
					
						
							| 
									
										
										
										
											2019-09-15 17:55:10 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | #define FIPS_STATE_INIT     0
 | 
					
						
							| 
									
										
										
										
											2019-09-19 00:27:10 +08:00
										 |  |  | #define FIPS_STATE_SELFTEST 1
 | 
					
						
							|  |  |  | #define FIPS_STATE_RUNNING  2
 | 
					
						
							| 
									
										
										
										
											2019-09-15 17:55:10 +08:00
										 |  |  | #define FIPS_STATE_ERROR    3
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-10 05:08:57 +08:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * The number of times the module will report it is in the error state | 
					
						
							|  |  |  |  * before going quiet. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | #define FIPS_ERROR_REPORTING_RATE_LIMIT     10
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-15 17:55:10 +08:00
										 |  |  | /* The size of a temp buffer used to read in data */ | 
					
						
							|  |  |  | #define INTEGRITY_BUF_SIZE (4096)
 | 
					
						
							|  |  |  | #define MAX_MD_SIZE 64
 | 
					
						
							|  |  |  | #define MAC_NAME    "HMAC"
 | 
					
						
							|  |  |  | #define DIGEST_NAME "SHA256"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-10 12:01:30 +08:00
										 |  |  | static int FIPS_conditional_error_check = 1; | 
					
						
							| 
									
										
										
										
											2019-09-19 00:27:10 +08:00
										 |  |  | static CRYPTO_RWLOCK *self_test_lock = NULL; | 
					
						
							| 
									
										
										
										
											2021-01-27 23:51:48 +08:00
										 |  |  | static CRYPTO_RWLOCK *fips_state_lock = NULL; | 
					
						
							| 
									
										
										
										
											2020-06-29 10:20:41 +08:00
										 |  |  | static unsigned char fixed_key[32] = { FIPS_KEY_ELEMENTS }; | 
					
						
							| 
									
										
										
										
											2019-09-15 17:55:10 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-19 00:27:10 +08:00
										 |  |  | static CRYPTO_ONCE fips_self_test_init = CRYPTO_ONCE_STATIC_INIT; | 
					
						
							|  |  |  | DEFINE_RUN_ONCE_STATIC(do_fips_self_test_init) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-09-19 18:52:45 +08:00
										 |  |  |     /*
 | 
					
						
							| 
									
										
										
										
											2021-01-27 23:51:48 +08:00
										 |  |  |      * These locks get freed in platform specific ways that may occur after we | 
					
						
							| 
									
										
										
										
											2019-09-19 18:52:45 +08:00
										 |  |  |      * do mem leak checking. If we don't know how to free it for a particular | 
					
						
							| 
									
										
										
										
											2021-01-27 23:51:48 +08:00
										 |  |  |      * platform then we just leak it deliberately. | 
					
						
							| 
									
										
										
										
											2019-09-19 18:52:45 +08:00
										 |  |  |      */ | 
					
						
							| 
									
										
										
										
											2019-09-19 00:27:10 +08:00
										 |  |  |     self_test_lock = CRYPTO_THREAD_lock_new(); | 
					
						
							| 
									
										
										
										
											2021-01-27 23:51:48 +08:00
										 |  |  |     fips_state_lock = CRYPTO_THREAD_lock_new(); | 
					
						
							| 
									
										
										
										
											2019-09-19 00:27:10 +08:00
										 |  |  |     return self_test_lock != NULL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-18 17:03:28 +08:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * Declarations for the DEP entry/exit points. | 
					
						
							|  |  |  |  * Ones not required or incorrect need to be undefined or redefined respectively. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | #define DEP_INITIAL_STATE   FIPS_STATE_INIT
 | 
					
						
							|  |  |  | #define DEP_INIT_ATTRIBUTE  static
 | 
					
						
							|  |  |  | #define DEP_FINI_ATTRIBUTE  static
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void init(void); | 
					
						
							|  |  |  | static void cleanup(void); | 
					
						
							| 
									
										
										
										
											2019-12-22 07:44:38 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-19 00:27:10 +08:00
										 |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2021-05-18 17:03:28 +08:00
										 |  |  |  * This is the Default Entry Point (DEP) code. | 
					
						
							| 
									
										
										
										
											2019-09-19 00:27:10 +08:00
										 |  |  |  * See FIPS 140-2 IG 9.10 | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | #if defined(_WIN32) || defined(__CYGWIN__)
 | 
					
						
							|  |  |  | # ifdef __CYGWIN__
 | 
					
						
							|  |  |  | /* pick DLL_[PROCESS|THREAD]_[ATTACH|DETACH] definitions */ | 
					
						
							|  |  |  | #  include <windows.h>
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * this has side-effect of _WIN32 getting defined, which otherwise is | 
					
						
							|  |  |  |  * mutually exclusive with __CYGWIN__... | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | # endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved); | 
					
						
							|  |  |  | BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     switch (fdwReason) { | 
					
						
							|  |  |  |     case DLL_PROCESS_ATTACH: | 
					
						
							| 
									
										
										
										
											2019-12-22 07:44:38 +08:00
										 |  |  |         init(); | 
					
						
							| 
									
										
										
										
											2019-09-19 00:27:10 +08:00
										 |  |  |         break; | 
					
						
							|  |  |  |     case DLL_PROCESS_DETACH: | 
					
						
							| 
									
										
										
										
											2019-12-22 07:44:38 +08:00
										 |  |  |         cleanup(); | 
					
						
							| 
									
										
										
										
											2019-09-19 00:27:10 +08:00
										 |  |  |         break; | 
					
						
							|  |  |  |     default: | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return TRUE; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2022-04-21 14:49:04 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | #elif defined(__GNUC__)
 | 
					
						
							|  |  |  | # undef DEP_INIT_ATTRIBUTE
 | 
					
						
							|  |  |  | # undef DEP_FINI_ATTRIBUTE
 | 
					
						
							|  |  |  | # define DEP_INIT_ATTRIBUTE static __attribute__((constructor))
 | 
					
						
							|  |  |  | # define DEP_FINI_ATTRIBUTE static __attribute__((destructor))
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-07 09:33:28 +08:00
										 |  |  | #elif defined(__sun)
 | 
					
						
							| 
									
										
										
										
											2019-12-22 07:44:38 +08:00
										 |  |  | # pragma init(init)
 | 
					
						
							|  |  |  | # pragma fini(cleanup)
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-07 09:33:28 +08:00
										 |  |  | #elif defined(_AIX)
 | 
					
						
							|  |  |  | void _init(void); | 
					
						
							|  |  |  | void _cleanup(void); | 
					
						
							|  |  |  | # pragma init(_init)
 | 
					
						
							|  |  |  | # pragma fini(_cleanup)
 | 
					
						
							|  |  |  | void _init(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     init(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | void _cleanup(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     cleanup(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-22 07:44:38 +08:00
										 |  |  | #elif defined(__hpux)
 | 
					
						
							|  |  |  | # pragma init "init"
 | 
					
						
							|  |  |  | # pragma fini "cleanup"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-21 06:30:14 +08:00
										 |  |  | #elif defined(__TANDEM)
 | 
					
						
							|  |  |  | /* Method automatically called by the NonStop OS when the DLL loads */ | 
					
						
							|  |  |  | void __INIT__init(void) { | 
					
						
							|  |  |  |     init(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Method automatically called by the NonStop OS prior to unloading the DLL */ | 
					
						
							|  |  |  | void __TERM__cleanup(void) { | 
					
						
							|  |  |  |     cleanup(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-18 17:03:28 +08:00
										 |  |  | #else
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * This build does not support any kind of DEP. | 
					
						
							|  |  |  |  * We force the self-tests to run as part of the FIPS provider initialisation | 
					
						
							|  |  |  |  * rather than being triggered by the DEP. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | # undef DEP_INIT_ATTRIBUTE
 | 
					
						
							|  |  |  | # undef DEP_FINI_ATTRIBUTE
 | 
					
						
							|  |  |  | # undef DEP_INITIAL_STATE
 | 
					
						
							|  |  |  | # define DEP_INITIAL_STATE  FIPS_STATE_SELFTEST
 | 
					
						
							| 
									
										
										
										
											2019-12-22 07:44:38 +08:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2019-09-19 00:27:10 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-18 17:03:28 +08:00
										 |  |  | static int FIPS_state = DEP_INITIAL_STATE; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if defined(DEP_INIT_ATTRIBUTE)
 | 
					
						
							| 
									
										
										
										
											2019-12-22 07:44:38 +08:00
										 |  |  | DEP_INIT_ATTRIBUTE void init(void) | 
					
						
							| 
									
										
										
										
											2019-09-19 00:27:10 +08:00
										 |  |  | { | 
					
						
							|  |  |  |     FIPS_state = FIPS_STATE_SELFTEST; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2021-05-18 17:03:28 +08:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2019-09-19 00:27:10 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-18 17:03:28 +08:00
										 |  |  | #if defined(DEP_FINI_ATTRIBUTE)
 | 
					
						
							| 
									
										
										
										
											2019-12-22 07:44:38 +08:00
										 |  |  | DEP_FINI_ATTRIBUTE void cleanup(void) | 
					
						
							| 
									
										
										
										
											2019-09-19 00:27:10 +08:00
										 |  |  | { | 
					
						
							|  |  |  |     CRYPTO_THREAD_lock_free(self_test_lock); | 
					
						
							| 
									
										
										
										
											2021-01-27 23:51:48 +08:00
										 |  |  |     CRYPTO_THREAD_lock_free(fips_state_lock); | 
					
						
							| 
									
										
										
										
											2019-09-19 00:27:10 +08:00
										 |  |  | } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-15 17:55:10 +08:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * Calculate the HMAC SHA256 of data read using a BIO and read_cb, and verify | 
					
						
							|  |  |  |  * the result matches the expected value. | 
					
						
							|  |  |  |  * Return 1 if verified, or 0 if it fails. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2020-06-21 07:19:16 +08:00
										 |  |  | static int verify_integrity(OSSL_CORE_BIO *bio, OSSL_FUNC_BIO_read_ex_fn read_ex_cb, | 
					
						
							| 
									
										
										
										
											2019-09-15 17:55:10 +08:00
										 |  |  |                             unsigned char *expected, size_t expected_len, | 
					
						
							| 
									
										
										
										
											2020-10-15 17:55:50 +08:00
										 |  |  |                             OSSL_LIB_CTX *libctx, OSSL_SELF_TEST *ev, | 
					
						
							| 
									
										
										
										
											2020-01-15 08:48:01 +08:00
										 |  |  |                             const char *event_type) | 
					
						
							| 
									
										
										
										
											2019-09-15 17:55:10 +08:00
										 |  |  | { | 
					
						
							|  |  |  |     int ret = 0, status; | 
					
						
							|  |  |  |     unsigned char out[MAX_MD_SIZE]; | 
					
						
							|  |  |  |     unsigned char buf[INTEGRITY_BUF_SIZE]; | 
					
						
							|  |  |  |     size_t bytes_read = 0, out_len = 0; | 
					
						
							|  |  |  |     EVP_MAC *mac = NULL; | 
					
						
							|  |  |  |     EVP_MAC_CTX *ctx = NULL; | 
					
						
							| 
									
										
										
										
											2021-02-25 11:51:03 +08:00
										 |  |  |     OSSL_PARAM params[2], *p = params; | 
					
						
							| 
									
										
										
										
											2019-09-15 17:55:10 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-03 12:02:36 +08:00
										 |  |  |     OSSL_SELF_TEST_onbegin(ev, event_type, OSSL_SELF_TEST_DESC_INTEGRITY_HMAC); | 
					
						
							| 
									
										
										
										
											2020-01-15 08:48:01 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-15 17:55:10 +08:00
										 |  |  |     mac = EVP_MAC_fetch(libctx, MAC_NAME, NULL); | 
					
						
							| 
									
										
										
										
											2020-09-21 08:47:03 +08:00
										 |  |  |     if (mac == NULL) | 
					
						
							|  |  |  |         goto err; | 
					
						
							| 
									
										
										
										
											2020-06-18 16:26:22 +08:00
										 |  |  |     ctx = EVP_MAC_CTX_new(mac); | 
					
						
							| 
									
										
										
										
											2020-09-21 08:47:03 +08:00
										 |  |  |     if (ctx == NULL) | 
					
						
							| 
									
										
										
										
											2019-09-15 17:55:10 +08:00
										 |  |  |         goto err; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-13 13:49:05 +08:00
										 |  |  |     *p++ = OSSL_PARAM_construct_utf8_string("digest", DIGEST_NAME, 0); | 
					
						
							| 
									
										
										
										
											2019-09-15 17:55:10 +08:00
										 |  |  |     *p = OSSL_PARAM_construct_end(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-25 11:51:03 +08:00
										 |  |  |     if (!EVP_MAC_init(ctx, fixed_key, sizeof(fixed_key), params)) | 
					
						
							| 
									
										
										
										
											2019-09-15 17:55:10 +08:00
										 |  |  |         goto err; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     while (1) { | 
					
						
							|  |  |  |         status = read_ex_cb(bio, buf, sizeof(buf), &bytes_read); | 
					
						
							|  |  |  |         if (status != 1) | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         if (!EVP_MAC_update(ctx, buf, bytes_read)) | 
					
						
							|  |  |  |             goto err; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (!EVP_MAC_final(ctx, out, &out_len, sizeof(out))) | 
					
						
							|  |  |  |         goto err; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-03 12:02:36 +08:00
										 |  |  |     OSSL_SELF_TEST_oncorrupt_byte(ev, out); | 
					
						
							| 
									
										
										
										
											2019-09-15 17:55:10 +08:00
										 |  |  |     if (expected_len != out_len | 
					
						
							|  |  |  |             || memcmp(expected, out, out_len) != 0) | 
					
						
							|  |  |  |         goto err; | 
					
						
							|  |  |  |     ret = 1; | 
					
						
							|  |  |  | err: | 
					
						
							| 
									
										
										
										
											2020-03-03 12:02:36 +08:00
										 |  |  |     OSSL_SELF_TEST_onend(ev, ret); | 
					
						
							| 
									
										
										
										
											2020-06-18 16:26:22 +08:00
										 |  |  |     EVP_MAC_CTX_free(ctx); | 
					
						
							| 
									
										
										
										
											2019-09-15 17:55:10 +08:00
										 |  |  |     EVP_MAC_free(mac); | 
					
						
							|  |  |  |     return ret; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-27 23:51:48 +08:00
										 |  |  | static void set_fips_state(int state) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2021-02-19 04:31:56 +08:00
										 |  |  |     if (ossl_assert(CRYPTO_THREAD_write_lock(fips_state_lock) != 0)) { | 
					
						
							|  |  |  |         FIPS_state = state; | 
					
						
							|  |  |  |         CRYPTO_THREAD_unlock(fips_state_lock); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-01-27 23:51:48 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-15 17:55:10 +08:00
										 |  |  | /* This API is triggered either on loading of the FIPS module or on demand */ | 
					
						
							| 
									
										
										
										
											2019-09-19 00:27:10 +08:00
										 |  |  | int SELF_TEST_post(SELF_TEST_POST_PARAMS *st, int on_demand_test) | 
					
						
							| 
									
										
										
										
											2019-09-15 17:55:10 +08:00
										 |  |  | { | 
					
						
							|  |  |  |     int ok = 0; | 
					
						
							|  |  |  |     int kats_already_passed = 0; | 
					
						
							|  |  |  |     long checksum_len; | 
					
						
							| 
									
										
										
										
											2020-05-06 19:29:57 +08:00
										 |  |  |     OSSL_CORE_BIO *bio_module = NULL, *bio_indicator = NULL; | 
					
						
							| 
									
										
										
										
											2019-09-15 17:55:10 +08:00
										 |  |  |     unsigned char *module_checksum = NULL; | 
					
						
							|  |  |  |     unsigned char *indicator_checksum = NULL; | 
					
						
							| 
									
										
										
										
											2019-09-19 00:27:10 +08:00
										 |  |  |     int loclstate; | 
					
						
							| 
									
										
										
										
											2020-03-03 12:02:36 +08:00
										 |  |  |     OSSL_SELF_TEST *ev = NULL; | 
					
						
							| 
									
										
										
										
											2019-09-19 00:27:10 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (!RUN_ONCE(&fips_self_test_init, do_fips_self_test_init)) | 
					
						
							|  |  |  |         return 0; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-19 04:31:56 +08:00
										 |  |  |     if (!CRYPTO_THREAD_read_lock(fips_state_lock)) | 
					
						
							|  |  |  |         return 0; | 
					
						
							| 
									
										
										
										
											2019-09-19 00:27:10 +08:00
										 |  |  |     loclstate = FIPS_state; | 
					
						
							| 
									
										
										
										
											2021-01-27 23:51:48 +08:00
										 |  |  |     CRYPTO_THREAD_unlock(fips_state_lock); | 
					
						
							| 
									
										
										
										
											2019-09-15 17:55:10 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-19 00:27:10 +08:00
										 |  |  |     if (loclstate == FIPS_STATE_RUNNING) { | 
					
						
							|  |  |  |         if (!on_demand_test) | 
					
						
							|  |  |  |             return 1; | 
					
						
							|  |  |  |     } else if (loclstate != FIPS_STATE_SELFTEST) { | 
					
						
							| 
									
										
										
										
											2020-07-21 14:30:02 +08:00
										 |  |  |         ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_STATE); | 
					
						
							| 
									
										
										
										
											2019-09-19 00:27:10 +08:00
										 |  |  |         return 0; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-19 04:31:56 +08:00
										 |  |  |     if (!CRYPTO_THREAD_write_lock(self_test_lock)) | 
					
						
							|  |  |  |         return 0; | 
					
						
							|  |  |  |     if (!CRYPTO_THREAD_read_lock(fips_state_lock)) { | 
					
						
							|  |  |  |         CRYPTO_THREAD_unlock(self_test_lock); | 
					
						
							|  |  |  |         return 0; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-09-19 00:27:10 +08:00
										 |  |  |     if (FIPS_state == FIPS_STATE_RUNNING) { | 
					
						
							| 
									
										
										
										
											2021-01-27 23:51:48 +08:00
										 |  |  |         CRYPTO_THREAD_unlock(fips_state_lock); | 
					
						
							| 
									
										
										
										
											2019-09-19 00:27:10 +08:00
										 |  |  |         if (!on_demand_test) { | 
					
						
							|  |  |  |             CRYPTO_THREAD_unlock(self_test_lock); | 
					
						
							|  |  |  |             return 1; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2021-01-27 23:51:48 +08:00
										 |  |  |         set_fips_state(FIPS_STATE_SELFTEST); | 
					
						
							| 
									
										
										
										
											2019-09-19 00:27:10 +08:00
										 |  |  |     } else if (FIPS_state != FIPS_STATE_SELFTEST) { | 
					
						
							| 
									
										
										
										
											2021-01-27 23:51:48 +08:00
										 |  |  |         CRYPTO_THREAD_unlock(fips_state_lock); | 
					
						
							| 
									
										
										
										
											2019-09-19 00:27:10 +08:00
										 |  |  |         CRYPTO_THREAD_unlock(self_test_lock); | 
					
						
							| 
									
										
										
										
											2020-07-21 14:30:02 +08:00
										 |  |  |         ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_STATE); | 
					
						
							| 
									
										
										
										
											2019-09-19 00:27:10 +08:00
										 |  |  |         return 0; | 
					
						
							| 
									
										
										
										
											2021-01-27 23:51:48 +08:00
										 |  |  |     } else { | 
					
						
							|  |  |  |         CRYPTO_THREAD_unlock(fips_state_lock); | 
					
						
							| 
									
										
										
										
											2019-09-19 00:27:10 +08:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-01-27 23:51:48 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-15 17:55:10 +08:00
										 |  |  |     if (st == NULL | 
					
						
							| 
									
										
										
										
											2020-07-21 14:30:02 +08:00
										 |  |  |             || st->module_checksum_data == NULL) { | 
					
						
							|  |  |  |         ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_CONFIG_DATA); | 
					
						
							| 
									
										
										
										
											2019-09-15 17:55:10 +08:00
										 |  |  |         goto end; | 
					
						
							| 
									
										
										
										
											2020-07-21 14:30:02 +08:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-09-15 17:55:10 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-03 12:02:36 +08:00
										 |  |  |     ev = OSSL_SELF_TEST_new(st->cb, st->cb_arg); | 
					
						
							|  |  |  |     if (ev == NULL) | 
					
						
							|  |  |  |         goto end; | 
					
						
							| 
									
										
										
										
											2020-01-15 08:48:01 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-15 17:55:10 +08:00
										 |  |  |     module_checksum = OPENSSL_hexstr2buf(st->module_checksum_data, | 
					
						
							|  |  |  |                                          &checksum_len); | 
					
						
							| 
									
										
										
										
											2020-07-21 14:30:02 +08:00
										 |  |  |     if (module_checksum == NULL) { | 
					
						
							|  |  |  |         ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_CONFIG_DATA); | 
					
						
							| 
									
										
										
										
											2019-09-15 17:55:10 +08:00
										 |  |  |         goto end; | 
					
						
							| 
									
										
										
										
											2020-07-21 14:30:02 +08:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-09-15 17:55:10 +08:00
										 |  |  |     bio_module = (*st->bio_new_file_cb)(st->module_filename, "rb"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* Always check the integrity of the fips module */ | 
					
						
							|  |  |  |     if (bio_module == NULL | 
					
						
							|  |  |  |             || !verify_integrity(bio_module, st->bio_read_ex_cb, | 
					
						
							| 
									
										
										
										
											2020-01-15 08:48:01 +08:00
										 |  |  |                                  module_checksum, checksum_len, st->libctx, | 
					
						
							| 
									
										
										
										
											2020-07-21 14:30:02 +08:00
										 |  |  |                                  ev, OSSL_SELF_TEST_TYPE_MODULE_INTEGRITY)) { | 
					
						
							|  |  |  |         ERR_raise(ERR_LIB_PROV, PROV_R_MODULE_INTEGRITY_FAILURE); | 
					
						
							| 
									
										
										
										
											2019-09-15 17:55:10 +08:00
										 |  |  |         goto end; | 
					
						
							| 
									
										
										
										
											2020-07-21 14:30:02 +08:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-09-15 17:55:10 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /* This will be NULL during installation - so the self test KATS will run */ | 
					
						
							|  |  |  |     if (st->indicator_data != NULL) { | 
					
						
							|  |  |  |         /*
 | 
					
						
							|  |  |  |          * If the kats have already passed indicator is set - then check the | 
					
						
							|  |  |  |          * integrity of the indicator. | 
					
						
							|  |  |  |          */ | 
					
						
							| 
									
										
										
										
											2020-07-21 14:30:02 +08:00
										 |  |  |         if (st->indicator_checksum_data == NULL) { | 
					
						
							|  |  |  |             ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_CONFIG_DATA); | 
					
						
							| 
									
										
										
										
											2019-09-15 17:55:10 +08:00
										 |  |  |             goto end; | 
					
						
							| 
									
										
										
										
											2020-07-21 14:30:02 +08:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2019-09-15 17:55:10 +08:00
										 |  |  |         indicator_checksum = OPENSSL_hexstr2buf(st->indicator_checksum_data, | 
					
						
							|  |  |  |                                                 &checksum_len); | 
					
						
							| 
									
										
										
										
											2020-07-21 14:30:02 +08:00
										 |  |  |         if (indicator_checksum == NULL) { | 
					
						
							|  |  |  |             ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_CONFIG_DATA); | 
					
						
							| 
									
										
										
										
											2019-09-15 17:55:10 +08:00
										 |  |  |             goto end; | 
					
						
							| 
									
										
										
										
											2020-07-21 14:30:02 +08:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2019-09-15 17:55:10 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |         bio_indicator = | 
					
						
							|  |  |  |             (*st->bio_new_buffer_cb)(st->indicator_data, | 
					
						
							|  |  |  |                                      strlen(st->indicator_data)); | 
					
						
							|  |  |  |         if (bio_indicator == NULL | 
					
						
							|  |  |  |                 || !verify_integrity(bio_indicator, st->bio_read_ex_cb, | 
					
						
							|  |  |  |                                      indicator_checksum, checksum_len, | 
					
						
							| 
									
										
										
										
											2020-03-03 12:02:36 +08:00
										 |  |  |                                      st->libctx, ev, | 
					
						
							| 
									
										
										
										
											2020-07-21 14:30:02 +08:00
										 |  |  |                                      OSSL_SELF_TEST_TYPE_INSTALL_INTEGRITY)) { | 
					
						
							|  |  |  |             ERR_raise(ERR_LIB_PROV, PROV_R_INDICATOR_INTEGRITY_FAILURE); | 
					
						
							| 
									
										
										
										
											2019-09-15 17:55:10 +08:00
										 |  |  |             goto end; | 
					
						
							| 
									
										
										
										
											2020-07-21 14:30:02 +08:00
										 |  |  |         } else { | 
					
						
							| 
									
										
										
										
											2019-09-15 17:55:10 +08:00
										 |  |  |             kats_already_passed = 1; | 
					
						
							| 
									
										
										
										
											2020-07-21 14:30:02 +08:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2019-09-15 17:55:10 +08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-05 08:36:41 +08:00
										 |  |  |     /*
 | 
					
						
							|  |  |  |      * Only runs the KAT's during installation OR on_demand(). | 
					
						
							|  |  |  |      * NOTE: If the installation option 'self_test_onload' is chosen then this | 
					
						
							|  |  |  |      * path will always be run, since kats_already_passed will always be 0. | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2019-09-15 17:55:10 +08:00
										 |  |  |     if (on_demand_test || kats_already_passed == 0) { | 
					
						
							| 
									
										
										
										
											2020-07-21 14:30:02 +08:00
										 |  |  |         if (!SELF_TEST_kats(ev, st->libctx)) { | 
					
						
							|  |  |  |             ERR_raise(ERR_LIB_PROV, PROV_R_SELF_TEST_KAT_FAILURE); | 
					
						
							| 
									
										
										
										
											2020-01-15 08:48:01 +08:00
										 |  |  |             goto end; | 
					
						
							| 
									
										
										
										
											2020-07-21 14:30:02 +08:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2019-09-15 17:55:10 +08:00
										 |  |  |     } | 
					
						
							|  |  |  |     ok = 1; | 
					
						
							|  |  |  | end: | 
					
						
							| 
									
										
										
										
											2020-03-03 12:02:36 +08:00
										 |  |  |     OSSL_SELF_TEST_free(ev); | 
					
						
							| 
									
										
										
										
											2019-09-15 17:55:10 +08:00
										 |  |  |     OPENSSL_free(module_checksum); | 
					
						
							|  |  |  |     OPENSSL_free(indicator_checksum); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-03 07:29:51 +08:00
										 |  |  |     if (st != NULL) { | 
					
						
							|  |  |  |         (*st->bio_free_cb)(bio_indicator); | 
					
						
							|  |  |  |         (*st->bio_free_cb)(bio_module); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-09-10 05:08:57 +08:00
										 |  |  |     if (ok) | 
					
						
							| 
									
										
										
										
											2021-01-27 23:51:48 +08:00
										 |  |  |         set_fips_state(FIPS_STATE_RUNNING); | 
					
						
							| 
									
										
										
										
											2020-09-10 05:08:57 +08:00
										 |  |  |     else | 
					
						
							| 
									
										
										
										
											2020-09-10 12:01:30 +08:00
										 |  |  |         ossl_set_error_state(OSSL_SELF_TEST_TYPE_NONE); | 
					
						
							| 
									
										
										
										
											2019-09-19 00:27:10 +08:00
										 |  |  |     CRYPTO_THREAD_unlock(self_test_lock); | 
					
						
							| 
									
										
										
										
											2019-09-15 17:55:10 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     return ok; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2020-08-09 16:06:52 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-10 12:01:30 +08:00
										 |  |  | void SELF_TEST_disable_conditional_error_state(void) | 
					
						
							| 
									
										
										
										
											2020-09-10 05:08:57 +08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-09-10 12:01:30 +08:00
										 |  |  |     FIPS_conditional_error_check = 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void ossl_set_error_state(const char *type) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     int cond_test = (type != NULL && strcmp(type, OSSL_SELF_TEST_TYPE_PCT) == 0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!cond_test || (FIPS_conditional_error_check == 1)) { | 
					
						
							| 
									
										
										
										
											2021-01-27 23:51:48 +08:00
										 |  |  |         set_fips_state(FIPS_STATE_ERROR); | 
					
						
							| 
									
										
										
										
											2020-09-10 12:01:30 +08:00
										 |  |  |         ERR_raise(ERR_LIB_PROV, PROV_R_FIPS_MODULE_ENTERING_ERROR_STATE); | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |         ERR_raise(ERR_LIB_PROV, PROV_R_FIPS_MODULE_CONDITIONAL_ERROR); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-09-10 05:08:57 +08:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2020-08-09 16:06:52 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-07 09:58:48 +08:00
										 |  |  | int ossl_prov_is_running(void) | 
					
						
							| 
									
										
										
										
											2020-08-09 16:06:52 +08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-01-27 23:51:48 +08:00
										 |  |  |     int res; | 
					
						
							| 
									
										
										
										
											2020-09-10 05:08:57 +08:00
										 |  |  |     static unsigned int rate_limit = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-27 23:51:48 +08:00
										 |  |  |     if (!CRYPTO_THREAD_read_lock(fips_state_lock)) | 
					
						
							|  |  |  |         return 0; | 
					
						
							|  |  |  |     res = FIPS_state == FIPS_STATE_RUNNING | 
					
						
							|  |  |  |                         || FIPS_state == FIPS_STATE_SELFTEST; | 
					
						
							|  |  |  |     if (FIPS_state == FIPS_STATE_ERROR) { | 
					
						
							|  |  |  |         CRYPTO_THREAD_unlock(fips_state_lock); | 
					
						
							|  |  |  |         if (!CRYPTO_THREAD_write_lock(fips_state_lock)) | 
					
						
							|  |  |  |             return 0; | 
					
						
							| 
									
										
										
										
											2020-09-10 05:08:57 +08:00
										 |  |  |         if (rate_limit++ < FIPS_ERROR_REPORTING_RATE_LIMIT) | 
					
						
							|  |  |  |             ERR_raise(ERR_LIB_PROV, PROV_R_FIPS_MODULE_IN_ERROR_STATE); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-01-27 23:51:48 +08:00
										 |  |  |     CRYPTO_THREAD_unlock(fips_state_lock); | 
					
						
							| 
									
										
										
										
											2020-09-10 05:08:57 +08:00
										 |  |  |     return res; | 
					
						
							| 
									
										
										
										
											2020-08-09 16:06:52 +08:00
										 |  |  | } |