1e1051a39Sopenharmony_ci/* 2e1051a39Sopenharmony_ci * Copyright 2019-2022 The OpenSSL Project Authors. All Rights Reserved. 3e1051a39Sopenharmony_ci * 4e1051a39Sopenharmony_ci * Licensed under the Apache License 2.0 (the "License"). You may not use 5e1051a39Sopenharmony_ci * this file except in compliance with the License. You can obtain a copy 6e1051a39Sopenharmony_ci * in the file LICENSE in the source distribution or at 7e1051a39Sopenharmony_ci * https://www.openssl.org/source/license.html 8e1051a39Sopenharmony_ci */ 9e1051a39Sopenharmony_ci 10e1051a39Sopenharmony_ci#include <string.h> 11e1051a39Sopenharmony_ci#include <openssl/evp.h> 12e1051a39Sopenharmony_ci#include <openssl/params.h> 13e1051a39Sopenharmony_ci#include <openssl/crypto.h> 14e1051a39Sopenharmony_ci#include "internal/cryptlib.h" 15e1051a39Sopenharmony_ci#include <openssl/fipskey.h> 16e1051a39Sopenharmony_ci#include <openssl/err.h> 17e1051a39Sopenharmony_ci#include <openssl/proverr.h> 18e1051a39Sopenharmony_ci#include "e_os.h" 19e1051a39Sopenharmony_ci#include "prov/providercommon.h" 20e1051a39Sopenharmony_ci 21e1051a39Sopenharmony_ci/* 22e1051a39Sopenharmony_ci * We're cheating here. Normally we don't allow RUN_ONCE usage inside the FIPS 23e1051a39Sopenharmony_ci * module because all such initialisation should be associated with an 24e1051a39Sopenharmony_ci * individual OSSL_LIB_CTX. That doesn't work with the self test though because 25e1051a39Sopenharmony_ci * it should be run once regardless of the number of OSSL_LIB_CTXs we have. 26e1051a39Sopenharmony_ci */ 27e1051a39Sopenharmony_ci#define ALLOW_RUN_ONCE_IN_FIPS 28e1051a39Sopenharmony_ci#include "internal/thread_once.h" 29e1051a39Sopenharmony_ci#include "self_test.h" 30e1051a39Sopenharmony_ci 31e1051a39Sopenharmony_ci#define FIPS_STATE_INIT 0 32e1051a39Sopenharmony_ci#define FIPS_STATE_SELFTEST 1 33e1051a39Sopenharmony_ci#define FIPS_STATE_RUNNING 2 34e1051a39Sopenharmony_ci#define FIPS_STATE_ERROR 3 35e1051a39Sopenharmony_ci 36e1051a39Sopenharmony_ci/* 37e1051a39Sopenharmony_ci * The number of times the module will report it is in the error state 38e1051a39Sopenharmony_ci * before going quiet. 39e1051a39Sopenharmony_ci */ 40e1051a39Sopenharmony_ci#define FIPS_ERROR_REPORTING_RATE_LIMIT 10 41e1051a39Sopenharmony_ci 42e1051a39Sopenharmony_ci/* The size of a temp buffer used to read in data */ 43e1051a39Sopenharmony_ci#define INTEGRITY_BUF_SIZE (4096) 44e1051a39Sopenharmony_ci#define MAX_MD_SIZE 64 45e1051a39Sopenharmony_ci#define MAC_NAME "HMAC" 46e1051a39Sopenharmony_ci#define DIGEST_NAME "SHA256" 47e1051a39Sopenharmony_ci 48e1051a39Sopenharmony_cistatic int FIPS_conditional_error_check = 1; 49e1051a39Sopenharmony_cistatic CRYPTO_RWLOCK *self_test_lock = NULL; 50e1051a39Sopenharmony_cistatic CRYPTO_RWLOCK *fips_state_lock = NULL; 51e1051a39Sopenharmony_cistatic unsigned char fixed_key[32] = { FIPS_KEY_ELEMENTS }; 52e1051a39Sopenharmony_ci 53e1051a39Sopenharmony_cistatic CRYPTO_ONCE fips_self_test_init = CRYPTO_ONCE_STATIC_INIT; 54e1051a39Sopenharmony_ciDEFINE_RUN_ONCE_STATIC(do_fips_self_test_init) 55e1051a39Sopenharmony_ci{ 56e1051a39Sopenharmony_ci /* 57e1051a39Sopenharmony_ci * These locks get freed in platform specific ways that may occur after we 58e1051a39Sopenharmony_ci * do mem leak checking. If we don't know how to free it for a particular 59e1051a39Sopenharmony_ci * platform then we just leak it deliberately. 60e1051a39Sopenharmony_ci */ 61e1051a39Sopenharmony_ci self_test_lock = CRYPTO_THREAD_lock_new(); 62e1051a39Sopenharmony_ci fips_state_lock = CRYPTO_THREAD_lock_new(); 63e1051a39Sopenharmony_ci return self_test_lock != NULL; 64e1051a39Sopenharmony_ci} 65e1051a39Sopenharmony_ci 66e1051a39Sopenharmony_ci/* 67e1051a39Sopenharmony_ci * Declarations for the DEP entry/exit points. 68e1051a39Sopenharmony_ci * Ones not required or incorrect need to be undefined or redefined respectively. 69e1051a39Sopenharmony_ci */ 70e1051a39Sopenharmony_ci#define DEP_INITIAL_STATE FIPS_STATE_INIT 71e1051a39Sopenharmony_ci#define DEP_INIT_ATTRIBUTE static 72e1051a39Sopenharmony_ci#define DEP_FINI_ATTRIBUTE static 73e1051a39Sopenharmony_ci 74e1051a39Sopenharmony_cistatic void init(void); 75e1051a39Sopenharmony_cistatic void cleanup(void); 76e1051a39Sopenharmony_ci 77e1051a39Sopenharmony_ci/* 78e1051a39Sopenharmony_ci * This is the Default Entry Point (DEP) code. 79e1051a39Sopenharmony_ci * See FIPS 140-2 IG 9.10 80e1051a39Sopenharmony_ci */ 81e1051a39Sopenharmony_ci#if defined(_WIN32) || defined(__CYGWIN__) 82e1051a39Sopenharmony_ci# ifdef __CYGWIN__ 83e1051a39Sopenharmony_ci/* pick DLL_[PROCESS|THREAD]_[ATTACH|DETACH] definitions */ 84e1051a39Sopenharmony_ci# include <windows.h> 85e1051a39Sopenharmony_ci/* 86e1051a39Sopenharmony_ci * this has side-effect of _WIN32 getting defined, which otherwise is 87e1051a39Sopenharmony_ci * mutually exclusive with __CYGWIN__... 88e1051a39Sopenharmony_ci */ 89e1051a39Sopenharmony_ci# endif 90e1051a39Sopenharmony_ci 91e1051a39Sopenharmony_ciBOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved); 92e1051a39Sopenharmony_ciBOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) 93e1051a39Sopenharmony_ci{ 94e1051a39Sopenharmony_ci switch (fdwReason) { 95e1051a39Sopenharmony_ci case DLL_PROCESS_ATTACH: 96e1051a39Sopenharmony_ci init(); 97e1051a39Sopenharmony_ci break; 98e1051a39Sopenharmony_ci case DLL_PROCESS_DETACH: 99e1051a39Sopenharmony_ci cleanup(); 100e1051a39Sopenharmony_ci break; 101e1051a39Sopenharmony_ci default: 102e1051a39Sopenharmony_ci break; 103e1051a39Sopenharmony_ci } 104e1051a39Sopenharmony_ci return TRUE; 105e1051a39Sopenharmony_ci} 106e1051a39Sopenharmony_ci 107e1051a39Sopenharmony_ci#elif defined(__GNUC__) && !defined(_AIX) 108e1051a39Sopenharmony_ci# undef DEP_INIT_ATTRIBUTE 109e1051a39Sopenharmony_ci# undef DEP_FINI_ATTRIBUTE 110e1051a39Sopenharmony_ci# define DEP_INIT_ATTRIBUTE static __attribute__((constructor)) 111e1051a39Sopenharmony_ci# define DEP_FINI_ATTRIBUTE static __attribute__((destructor)) 112e1051a39Sopenharmony_ci 113e1051a39Sopenharmony_ci#elif defined(__sun) 114e1051a39Sopenharmony_ci# pragma init(init) 115e1051a39Sopenharmony_ci# pragma fini(cleanup) 116e1051a39Sopenharmony_ci 117e1051a39Sopenharmony_ci#elif defined(_AIX) && !defined(__GNUC__) 118e1051a39Sopenharmony_civoid _init(void); 119e1051a39Sopenharmony_civoid _cleanup(void); 120e1051a39Sopenharmony_ci# pragma init(_init) 121e1051a39Sopenharmony_ci# pragma fini(_cleanup) 122e1051a39Sopenharmony_civoid _init(void) 123e1051a39Sopenharmony_ci{ 124e1051a39Sopenharmony_ci init(); 125e1051a39Sopenharmony_ci} 126e1051a39Sopenharmony_civoid _cleanup(void) 127e1051a39Sopenharmony_ci{ 128e1051a39Sopenharmony_ci cleanup(); 129e1051a39Sopenharmony_ci} 130e1051a39Sopenharmony_ci 131e1051a39Sopenharmony_ci#elif defined(__hpux) 132e1051a39Sopenharmony_ci# pragma init "init" 133e1051a39Sopenharmony_ci# pragma fini "cleanup" 134e1051a39Sopenharmony_ci 135e1051a39Sopenharmony_ci#elif defined(__TANDEM) 136e1051a39Sopenharmony_ci/* Method automatically called by the NonStop OS when the DLL loads */ 137e1051a39Sopenharmony_civoid __INIT__init(void) { 138e1051a39Sopenharmony_ci init(); 139e1051a39Sopenharmony_ci} 140e1051a39Sopenharmony_ci 141e1051a39Sopenharmony_ci/* Method automatically called by the NonStop OS prior to unloading the DLL */ 142e1051a39Sopenharmony_civoid __TERM__cleanup(void) { 143e1051a39Sopenharmony_ci cleanup(); 144e1051a39Sopenharmony_ci} 145e1051a39Sopenharmony_ci 146e1051a39Sopenharmony_ci#else 147e1051a39Sopenharmony_ci/* 148e1051a39Sopenharmony_ci * This build does not support any kind of DEP. 149e1051a39Sopenharmony_ci * We force the self-tests to run as part of the FIPS provider initialisation 150e1051a39Sopenharmony_ci * rather than being triggered by the DEP. 151e1051a39Sopenharmony_ci */ 152e1051a39Sopenharmony_ci# undef DEP_INIT_ATTRIBUTE 153e1051a39Sopenharmony_ci# undef DEP_FINI_ATTRIBUTE 154e1051a39Sopenharmony_ci# undef DEP_INITIAL_STATE 155e1051a39Sopenharmony_ci# define DEP_INITIAL_STATE FIPS_STATE_SELFTEST 156e1051a39Sopenharmony_ci#endif 157e1051a39Sopenharmony_ci 158e1051a39Sopenharmony_cistatic int FIPS_state = DEP_INITIAL_STATE; 159e1051a39Sopenharmony_ci 160e1051a39Sopenharmony_ci#if defined(DEP_INIT_ATTRIBUTE) 161e1051a39Sopenharmony_ciDEP_INIT_ATTRIBUTE void init(void) 162e1051a39Sopenharmony_ci{ 163e1051a39Sopenharmony_ci FIPS_state = FIPS_STATE_SELFTEST; 164e1051a39Sopenharmony_ci} 165e1051a39Sopenharmony_ci#endif 166e1051a39Sopenharmony_ci 167e1051a39Sopenharmony_ci#if defined(DEP_FINI_ATTRIBUTE) 168e1051a39Sopenharmony_ciDEP_FINI_ATTRIBUTE void cleanup(void) 169e1051a39Sopenharmony_ci{ 170e1051a39Sopenharmony_ci CRYPTO_THREAD_lock_free(self_test_lock); 171e1051a39Sopenharmony_ci CRYPTO_THREAD_lock_free(fips_state_lock); 172e1051a39Sopenharmony_ci} 173e1051a39Sopenharmony_ci#endif 174e1051a39Sopenharmony_ci 175e1051a39Sopenharmony_ci/* 176e1051a39Sopenharmony_ci * Calculate the HMAC SHA256 of data read using a BIO and read_cb, and verify 177e1051a39Sopenharmony_ci * the result matches the expected value. 178e1051a39Sopenharmony_ci * Return 1 if verified, or 0 if it fails. 179e1051a39Sopenharmony_ci */ 180e1051a39Sopenharmony_cistatic int verify_integrity(OSSL_CORE_BIO *bio, OSSL_FUNC_BIO_read_ex_fn read_ex_cb, 181e1051a39Sopenharmony_ci unsigned char *expected, size_t expected_len, 182e1051a39Sopenharmony_ci OSSL_LIB_CTX *libctx, OSSL_SELF_TEST *ev, 183e1051a39Sopenharmony_ci const char *event_type) 184e1051a39Sopenharmony_ci{ 185e1051a39Sopenharmony_ci int ret = 0, status; 186e1051a39Sopenharmony_ci unsigned char out[MAX_MD_SIZE]; 187e1051a39Sopenharmony_ci unsigned char buf[INTEGRITY_BUF_SIZE]; 188e1051a39Sopenharmony_ci size_t bytes_read = 0, out_len = 0; 189e1051a39Sopenharmony_ci EVP_MAC *mac = NULL; 190e1051a39Sopenharmony_ci EVP_MAC_CTX *ctx = NULL; 191e1051a39Sopenharmony_ci OSSL_PARAM params[2], *p = params; 192e1051a39Sopenharmony_ci 193e1051a39Sopenharmony_ci OSSL_SELF_TEST_onbegin(ev, event_type, OSSL_SELF_TEST_DESC_INTEGRITY_HMAC); 194e1051a39Sopenharmony_ci 195e1051a39Sopenharmony_ci mac = EVP_MAC_fetch(libctx, MAC_NAME, NULL); 196e1051a39Sopenharmony_ci if (mac == NULL) 197e1051a39Sopenharmony_ci goto err; 198e1051a39Sopenharmony_ci ctx = EVP_MAC_CTX_new(mac); 199e1051a39Sopenharmony_ci if (ctx == NULL) 200e1051a39Sopenharmony_ci goto err; 201e1051a39Sopenharmony_ci 202e1051a39Sopenharmony_ci *p++ = OSSL_PARAM_construct_utf8_string("digest", DIGEST_NAME, 0); 203e1051a39Sopenharmony_ci *p = OSSL_PARAM_construct_end(); 204e1051a39Sopenharmony_ci 205e1051a39Sopenharmony_ci if (!EVP_MAC_init(ctx, fixed_key, sizeof(fixed_key), params)) 206e1051a39Sopenharmony_ci goto err; 207e1051a39Sopenharmony_ci 208e1051a39Sopenharmony_ci while (1) { 209e1051a39Sopenharmony_ci status = read_ex_cb(bio, buf, sizeof(buf), &bytes_read); 210e1051a39Sopenharmony_ci if (status != 1) 211e1051a39Sopenharmony_ci break; 212e1051a39Sopenharmony_ci if (!EVP_MAC_update(ctx, buf, bytes_read)) 213e1051a39Sopenharmony_ci goto err; 214e1051a39Sopenharmony_ci } 215e1051a39Sopenharmony_ci if (!EVP_MAC_final(ctx, out, &out_len, sizeof(out))) 216e1051a39Sopenharmony_ci goto err; 217e1051a39Sopenharmony_ci 218e1051a39Sopenharmony_ci OSSL_SELF_TEST_oncorrupt_byte(ev, out); 219e1051a39Sopenharmony_ci if (expected_len != out_len 220e1051a39Sopenharmony_ci || memcmp(expected, out, out_len) != 0) 221e1051a39Sopenharmony_ci goto err; 222e1051a39Sopenharmony_ci ret = 1; 223e1051a39Sopenharmony_cierr: 224e1051a39Sopenharmony_ci OSSL_SELF_TEST_onend(ev, ret); 225e1051a39Sopenharmony_ci EVP_MAC_CTX_free(ctx); 226e1051a39Sopenharmony_ci EVP_MAC_free(mac); 227e1051a39Sopenharmony_ci return ret; 228e1051a39Sopenharmony_ci} 229e1051a39Sopenharmony_ci 230e1051a39Sopenharmony_cistatic void set_fips_state(int state) 231e1051a39Sopenharmony_ci{ 232e1051a39Sopenharmony_ci if (ossl_assert(CRYPTO_THREAD_write_lock(fips_state_lock) != 0)) { 233e1051a39Sopenharmony_ci FIPS_state = state; 234e1051a39Sopenharmony_ci CRYPTO_THREAD_unlock(fips_state_lock); 235e1051a39Sopenharmony_ci } 236e1051a39Sopenharmony_ci} 237e1051a39Sopenharmony_ci 238e1051a39Sopenharmony_ci/* This API is triggered either on loading of the FIPS module or on demand */ 239e1051a39Sopenharmony_ciint SELF_TEST_post(SELF_TEST_POST_PARAMS *st, int on_demand_test) 240e1051a39Sopenharmony_ci{ 241e1051a39Sopenharmony_ci int ok = 0; 242e1051a39Sopenharmony_ci int kats_already_passed = 0; 243e1051a39Sopenharmony_ci long checksum_len; 244e1051a39Sopenharmony_ci OSSL_CORE_BIO *bio_module = NULL, *bio_indicator = NULL; 245e1051a39Sopenharmony_ci unsigned char *module_checksum = NULL; 246e1051a39Sopenharmony_ci unsigned char *indicator_checksum = NULL; 247e1051a39Sopenharmony_ci int loclstate; 248e1051a39Sopenharmony_ci OSSL_SELF_TEST *ev = NULL; 249e1051a39Sopenharmony_ci 250e1051a39Sopenharmony_ci if (!RUN_ONCE(&fips_self_test_init, do_fips_self_test_init)) 251e1051a39Sopenharmony_ci return 0; 252e1051a39Sopenharmony_ci 253e1051a39Sopenharmony_ci if (!CRYPTO_THREAD_read_lock(fips_state_lock)) 254e1051a39Sopenharmony_ci return 0; 255e1051a39Sopenharmony_ci loclstate = FIPS_state; 256e1051a39Sopenharmony_ci CRYPTO_THREAD_unlock(fips_state_lock); 257e1051a39Sopenharmony_ci 258e1051a39Sopenharmony_ci if (loclstate == FIPS_STATE_RUNNING) { 259e1051a39Sopenharmony_ci if (!on_demand_test) 260e1051a39Sopenharmony_ci return 1; 261e1051a39Sopenharmony_ci } else if (loclstate != FIPS_STATE_SELFTEST) { 262e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_STATE); 263e1051a39Sopenharmony_ci return 0; 264e1051a39Sopenharmony_ci } 265e1051a39Sopenharmony_ci 266e1051a39Sopenharmony_ci if (!CRYPTO_THREAD_write_lock(self_test_lock)) 267e1051a39Sopenharmony_ci return 0; 268e1051a39Sopenharmony_ci if (!CRYPTO_THREAD_read_lock(fips_state_lock)) { 269e1051a39Sopenharmony_ci CRYPTO_THREAD_unlock(self_test_lock); 270e1051a39Sopenharmony_ci return 0; 271e1051a39Sopenharmony_ci } 272e1051a39Sopenharmony_ci if (FIPS_state == FIPS_STATE_RUNNING) { 273e1051a39Sopenharmony_ci CRYPTO_THREAD_unlock(fips_state_lock); 274e1051a39Sopenharmony_ci if (!on_demand_test) { 275e1051a39Sopenharmony_ci CRYPTO_THREAD_unlock(self_test_lock); 276e1051a39Sopenharmony_ci return 1; 277e1051a39Sopenharmony_ci } 278e1051a39Sopenharmony_ci set_fips_state(FIPS_STATE_SELFTEST); 279e1051a39Sopenharmony_ci } else if (FIPS_state != FIPS_STATE_SELFTEST) { 280e1051a39Sopenharmony_ci CRYPTO_THREAD_unlock(fips_state_lock); 281e1051a39Sopenharmony_ci CRYPTO_THREAD_unlock(self_test_lock); 282e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_STATE); 283e1051a39Sopenharmony_ci return 0; 284e1051a39Sopenharmony_ci } else { 285e1051a39Sopenharmony_ci CRYPTO_THREAD_unlock(fips_state_lock); 286e1051a39Sopenharmony_ci } 287e1051a39Sopenharmony_ci 288e1051a39Sopenharmony_ci if (st == NULL 289e1051a39Sopenharmony_ci || st->module_checksum_data == NULL) { 290e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_CONFIG_DATA); 291e1051a39Sopenharmony_ci goto end; 292e1051a39Sopenharmony_ci } 293e1051a39Sopenharmony_ci 294e1051a39Sopenharmony_ci ev = OSSL_SELF_TEST_new(st->cb, st->cb_arg); 295e1051a39Sopenharmony_ci if (ev == NULL) 296e1051a39Sopenharmony_ci goto end; 297e1051a39Sopenharmony_ci 298e1051a39Sopenharmony_ci module_checksum = OPENSSL_hexstr2buf(st->module_checksum_data, 299e1051a39Sopenharmony_ci &checksum_len); 300e1051a39Sopenharmony_ci if (module_checksum == NULL) { 301e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_CONFIG_DATA); 302e1051a39Sopenharmony_ci goto end; 303e1051a39Sopenharmony_ci } 304e1051a39Sopenharmony_ci bio_module = (*st->bio_new_file_cb)(st->module_filename, "rb"); 305e1051a39Sopenharmony_ci 306e1051a39Sopenharmony_ci /* Always check the integrity of the fips module */ 307e1051a39Sopenharmony_ci if (bio_module == NULL 308e1051a39Sopenharmony_ci || !verify_integrity(bio_module, st->bio_read_ex_cb, 309e1051a39Sopenharmony_ci module_checksum, checksum_len, st->libctx, 310e1051a39Sopenharmony_ci ev, OSSL_SELF_TEST_TYPE_MODULE_INTEGRITY)) { 311e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PROV, PROV_R_MODULE_INTEGRITY_FAILURE); 312e1051a39Sopenharmony_ci goto end; 313e1051a39Sopenharmony_ci } 314e1051a39Sopenharmony_ci 315e1051a39Sopenharmony_ci /* This will be NULL during installation - so the self test KATS will run */ 316e1051a39Sopenharmony_ci if (st->indicator_data != NULL) { 317e1051a39Sopenharmony_ci /* 318e1051a39Sopenharmony_ci * If the kats have already passed indicator is set - then check the 319e1051a39Sopenharmony_ci * integrity of the indicator. 320e1051a39Sopenharmony_ci */ 321e1051a39Sopenharmony_ci if (st->indicator_checksum_data == NULL) { 322e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_CONFIG_DATA); 323e1051a39Sopenharmony_ci goto end; 324e1051a39Sopenharmony_ci } 325e1051a39Sopenharmony_ci indicator_checksum = OPENSSL_hexstr2buf(st->indicator_checksum_data, 326e1051a39Sopenharmony_ci &checksum_len); 327e1051a39Sopenharmony_ci if (indicator_checksum == NULL) { 328e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_CONFIG_DATA); 329e1051a39Sopenharmony_ci goto end; 330e1051a39Sopenharmony_ci } 331e1051a39Sopenharmony_ci 332e1051a39Sopenharmony_ci bio_indicator = 333e1051a39Sopenharmony_ci (*st->bio_new_buffer_cb)(st->indicator_data, 334e1051a39Sopenharmony_ci strlen(st->indicator_data)); 335e1051a39Sopenharmony_ci if (bio_indicator == NULL 336e1051a39Sopenharmony_ci || !verify_integrity(bio_indicator, st->bio_read_ex_cb, 337e1051a39Sopenharmony_ci indicator_checksum, checksum_len, 338e1051a39Sopenharmony_ci st->libctx, ev, 339e1051a39Sopenharmony_ci OSSL_SELF_TEST_TYPE_INSTALL_INTEGRITY)) { 340e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PROV, PROV_R_INDICATOR_INTEGRITY_FAILURE); 341e1051a39Sopenharmony_ci goto end; 342e1051a39Sopenharmony_ci } else { 343e1051a39Sopenharmony_ci kats_already_passed = 1; 344e1051a39Sopenharmony_ci } 345e1051a39Sopenharmony_ci } 346e1051a39Sopenharmony_ci 347e1051a39Sopenharmony_ci /* 348e1051a39Sopenharmony_ci * Only runs the KAT's during installation OR on_demand(). 349e1051a39Sopenharmony_ci * NOTE: If the installation option 'self_test_onload' is chosen then this 350e1051a39Sopenharmony_ci * path will always be run, since kats_already_passed will always be 0. 351e1051a39Sopenharmony_ci */ 352e1051a39Sopenharmony_ci if (on_demand_test || kats_already_passed == 0) { 353e1051a39Sopenharmony_ci if (!SELF_TEST_kats(ev, st->libctx)) { 354e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PROV, PROV_R_SELF_TEST_KAT_FAILURE); 355e1051a39Sopenharmony_ci goto end; 356e1051a39Sopenharmony_ci } 357e1051a39Sopenharmony_ci } 358e1051a39Sopenharmony_ci ok = 1; 359e1051a39Sopenharmony_ciend: 360e1051a39Sopenharmony_ci OSSL_SELF_TEST_free(ev); 361e1051a39Sopenharmony_ci OPENSSL_free(module_checksum); 362e1051a39Sopenharmony_ci OPENSSL_free(indicator_checksum); 363e1051a39Sopenharmony_ci 364e1051a39Sopenharmony_ci if (st != NULL) { 365e1051a39Sopenharmony_ci (*st->bio_free_cb)(bio_indicator); 366e1051a39Sopenharmony_ci (*st->bio_free_cb)(bio_module); 367e1051a39Sopenharmony_ci } 368e1051a39Sopenharmony_ci if (ok) 369e1051a39Sopenharmony_ci set_fips_state(FIPS_STATE_RUNNING); 370e1051a39Sopenharmony_ci else 371e1051a39Sopenharmony_ci ossl_set_error_state(OSSL_SELF_TEST_TYPE_NONE); 372e1051a39Sopenharmony_ci CRYPTO_THREAD_unlock(self_test_lock); 373e1051a39Sopenharmony_ci 374e1051a39Sopenharmony_ci return ok; 375e1051a39Sopenharmony_ci} 376e1051a39Sopenharmony_ci 377e1051a39Sopenharmony_civoid SELF_TEST_disable_conditional_error_state(void) 378e1051a39Sopenharmony_ci{ 379e1051a39Sopenharmony_ci FIPS_conditional_error_check = 0; 380e1051a39Sopenharmony_ci} 381e1051a39Sopenharmony_ci 382e1051a39Sopenharmony_civoid ossl_set_error_state(const char *type) 383e1051a39Sopenharmony_ci{ 384e1051a39Sopenharmony_ci int cond_test = (type != NULL && strcmp(type, OSSL_SELF_TEST_TYPE_PCT) == 0); 385e1051a39Sopenharmony_ci 386e1051a39Sopenharmony_ci if (!cond_test || (FIPS_conditional_error_check == 1)) { 387e1051a39Sopenharmony_ci set_fips_state(FIPS_STATE_ERROR); 388e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PROV, PROV_R_FIPS_MODULE_ENTERING_ERROR_STATE); 389e1051a39Sopenharmony_ci } else { 390e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PROV, PROV_R_FIPS_MODULE_CONDITIONAL_ERROR); 391e1051a39Sopenharmony_ci } 392e1051a39Sopenharmony_ci} 393e1051a39Sopenharmony_ci 394e1051a39Sopenharmony_ciint ossl_prov_is_running(void) 395e1051a39Sopenharmony_ci{ 396e1051a39Sopenharmony_ci int res; 397e1051a39Sopenharmony_ci static unsigned int rate_limit = 0; 398e1051a39Sopenharmony_ci 399e1051a39Sopenharmony_ci if (!CRYPTO_THREAD_read_lock(fips_state_lock)) 400e1051a39Sopenharmony_ci return 0; 401e1051a39Sopenharmony_ci res = FIPS_state == FIPS_STATE_RUNNING 402e1051a39Sopenharmony_ci || FIPS_state == FIPS_STATE_SELFTEST; 403e1051a39Sopenharmony_ci if (FIPS_state == FIPS_STATE_ERROR) { 404e1051a39Sopenharmony_ci CRYPTO_THREAD_unlock(fips_state_lock); 405e1051a39Sopenharmony_ci if (!CRYPTO_THREAD_write_lock(fips_state_lock)) 406e1051a39Sopenharmony_ci return 0; 407e1051a39Sopenharmony_ci if (rate_limit++ < FIPS_ERROR_REPORTING_RATE_LIMIT) 408e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PROV, PROV_R_FIPS_MODULE_IN_ERROR_STATE); 409e1051a39Sopenharmony_ci } 410e1051a39Sopenharmony_ci CRYPTO_THREAD_unlock(fips_state_lock); 411e1051a39Sopenharmony_ci return res; 412e1051a39Sopenharmony_ci} 413