Home | History | Annotate | Line # | Download | only in fips
      1      1.1  christos /*
      2      1.1  christos  * Copyright 2019-2025 The OpenSSL Project Authors. All Rights Reserved.
      3      1.1  christos  *
      4      1.1  christos  * Licensed under the Apache License 2.0 (the "License").  You may not use
      5      1.1  christos  * this file except in compliance with the License.  You can obtain a copy
      6      1.1  christos  * in the file LICENSE in the source distribution or at
      7      1.1  christos  * https://www.openssl.org/source/license.html
      8      1.1  christos  */
      9      1.1  christos 
     10      1.1  christos #include <string.h>
     11      1.1  christos #include <openssl/evp.h>
     12      1.1  christos #include <openssl/params.h>
     13      1.1  christos #include <openssl/crypto.h>
     14      1.1  christos #include "internal/cryptlib.h"
     15      1.1  christos #include <openssl/fipskey.h>
     16      1.1  christos #include <openssl/err.h>
     17      1.1  christos #include <openssl/proverr.h>
     18      1.1  christos #include <openssl/rand.h>
     19      1.1  christos #include "internal/e_os.h"
     20      1.1  christos #include "internal/fips.h"
     21      1.1  christos #include "internal/tsan_assist.h"
     22      1.1  christos #include "prov/providercommon.h"
     23      1.1  christos #include "crypto/rand.h"
     24      1.1  christos 
     25      1.1  christos /*
     26      1.1  christos  * We're cheating here. Normally we don't allow RUN_ONCE usage inside the FIPS
     27      1.1  christos  * module because all such initialisation should be associated with an
     28      1.1  christos  * individual OSSL_LIB_CTX. That doesn't work with the self test though because
     29      1.1  christos  * it should be run once regardless of the number of OSSL_LIB_CTXs we have.
     30      1.1  christos  */
     31      1.1  christos #define ALLOW_RUN_ONCE_IN_FIPS
     32      1.1  christos #include "internal/thread_once.h"
     33      1.1  christos #include "self_test.h"
     34      1.1  christos 
     35  1.1.1.2  christos #define FIPS_STATE_INIT 0
     36      1.1  christos #define FIPS_STATE_SELFTEST 1
     37  1.1.1.2  christos #define FIPS_STATE_RUNNING 2
     38  1.1.1.2  christos #define FIPS_STATE_ERROR 3
     39      1.1  christos 
     40      1.1  christos /*
     41      1.1  christos  * The number of times the module will report it is in the error state
     42      1.1  christos  * before going quiet.
     43      1.1  christos  */
     44  1.1.1.2  christos #define FIPS_ERROR_REPORTING_RATE_LIMIT 10
     45      1.1  christos 
     46      1.1  christos /* The size of a temp buffer used to read in data */
     47      1.1  christos #define INTEGRITY_BUF_SIZE (4096)
     48      1.1  christos #define MAX_MD_SIZE 64
     49  1.1.1.2  christos #define MAC_NAME "HMAC"
     50      1.1  christos #define DIGEST_NAME "SHA256"
     51      1.1  christos 
     52      1.1  christos static int FIPS_conditional_error_check = 1;
     53      1.1  christos static CRYPTO_RWLOCK *self_test_lock = NULL;
     54      1.1  christos 
     55      1.1  christos static CRYPTO_ONCE fips_self_test_init = CRYPTO_ONCE_STATIC_INIT;
     56      1.1  christos #if !defined(OPENSSL_NO_FIPS_POST)
     57      1.1  christos static unsigned char fixed_key[32] = { FIPS_KEY_ELEMENTS };
     58      1.1  christos #endif
     59      1.1  christos 
     60      1.1  christos DEFINE_RUN_ONCE_STATIC(do_fips_self_test_init)
     61      1.1  christos {
     62      1.1  christos     /*
     63      1.1  christos      * These locks get freed in platform specific ways that may occur after we
     64      1.1  christos      * do mem leak checking. If we don't know how to free it for a particular
     65      1.1  christos      * platform then we just leak it deliberately.
     66      1.1  christos      */
     67      1.1  christos     self_test_lock = CRYPTO_THREAD_lock_new();
     68      1.1  christos     return self_test_lock != NULL;
     69      1.1  christos }
     70      1.1  christos 
     71      1.1  christos /*
     72      1.1  christos  * Declarations for the DEP entry/exit points.
     73      1.1  christos  * Ones not required or incorrect need to be undefined or redefined respectively.
     74      1.1  christos  */
     75  1.1.1.2  christos #define DEP_INITIAL_STATE FIPS_STATE_INIT
     76  1.1.1.2  christos #define DEP_INIT_ATTRIBUTE static
     77  1.1.1.2  christos #define DEP_FINI_ATTRIBUTE static
     78      1.1  christos 
     79      1.1  christos static void init(void);
     80      1.1  christos static void cleanup(void);
     81      1.1  christos 
     82      1.1  christos /*
     83      1.1  christos  * This is the Default Entry Point (DEP) code.
     84      1.1  christos  * See FIPS 140-2 IG 9.10
     85      1.1  christos  */
     86      1.1  christos #if defined(_WIN32) || defined(__CYGWIN__)
     87  1.1.1.2  christos #ifdef __CYGWIN__
     88      1.1  christos /* pick DLL_[PROCESS|THREAD]_[ATTACH|DETACH] definitions */
     89  1.1.1.2  christos #include <windows.h>
     90      1.1  christos /*
     91      1.1  christos  * this has side-effect of _WIN32 getting defined, which otherwise is
     92      1.1  christos  * mutually exclusive with __CYGWIN__...
     93      1.1  christos  */
     94  1.1.1.2  christos #endif
     95      1.1  christos 
     96      1.1  christos BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved);
     97      1.1  christos BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
     98      1.1  christos {
     99      1.1  christos     switch (fdwReason) {
    100      1.1  christos     case DLL_PROCESS_ATTACH:
    101      1.1  christos         init();
    102      1.1  christos         break;
    103      1.1  christos     case DLL_PROCESS_DETACH:
    104      1.1  christos         cleanup();
    105      1.1  christos         break;
    106      1.1  christos     default:
    107      1.1  christos         break;
    108      1.1  christos     }
    109      1.1  christos     return TRUE;
    110      1.1  christos }
    111      1.1  christos 
    112      1.1  christos #elif defined(__GNUC__) && !defined(_AIX)
    113  1.1.1.2  christos #undef DEP_INIT_ATTRIBUTE
    114  1.1.1.2  christos #undef DEP_FINI_ATTRIBUTE
    115  1.1.1.2  christos #define DEP_INIT_ATTRIBUTE static __attribute__((constructor))
    116  1.1.1.2  christos #define DEP_FINI_ATTRIBUTE static __attribute__((destructor))
    117      1.1  christos 
    118      1.1  christos #elif defined(__sun)
    119  1.1.1.2  christos #pragma init(init)
    120  1.1.1.2  christos #pragma fini(cleanup)
    121      1.1  christos 
    122      1.1  christos #elif defined(_AIX) && !defined(__GNUC__)
    123      1.1  christos void _init(void);
    124      1.1  christos void _cleanup(void);
    125  1.1.1.2  christos #pragma init(_init)
    126  1.1.1.2  christos #pragma fini(_cleanup)
    127      1.1  christos void _init(void)
    128      1.1  christos {
    129      1.1  christos     init();
    130      1.1  christos }
    131      1.1  christos void _cleanup(void)
    132      1.1  christos {
    133      1.1  christos     cleanup();
    134      1.1  christos }
    135      1.1  christos 
    136      1.1  christos #elif defined(__hpux)
    137  1.1.1.2  christos #pragma init "init"
    138  1.1.1.2  christos #pragma fini "cleanup"
    139      1.1  christos 
    140      1.1  christos #elif defined(__TANDEM)
    141      1.1  christos /* Method automatically called by the NonStop OS when the DLL loads */
    142  1.1.1.2  christos void __INIT__init(void)
    143  1.1.1.2  christos {
    144      1.1  christos     init();
    145      1.1  christos }
    146      1.1  christos 
    147      1.1  christos /* Method automatically called by the NonStop OS prior to unloading the DLL */
    148  1.1.1.2  christos void __TERM__cleanup(void)
    149  1.1.1.2  christos {
    150      1.1  christos     cleanup();
    151      1.1  christos }
    152      1.1  christos 
    153      1.1  christos #else
    154      1.1  christos /*
    155      1.1  christos  * This build does not support any kind of DEP.
    156      1.1  christos  * We force the self-tests to run as part of the FIPS provider initialisation
    157      1.1  christos  * rather than being triggered by the DEP.
    158      1.1  christos  */
    159  1.1.1.2  christos #undef DEP_INIT_ATTRIBUTE
    160  1.1.1.2  christos #undef DEP_FINI_ATTRIBUTE
    161  1.1.1.2  christos #undef DEP_INITIAL_STATE
    162  1.1.1.2  christos #define DEP_INITIAL_STATE FIPS_STATE_SELFTEST
    163      1.1  christos #endif
    164      1.1  christos 
    165      1.1  christos static TSAN_QUALIFIER int FIPS_state = DEP_INITIAL_STATE;
    166      1.1  christos 
    167      1.1  christos #if defined(DEP_INIT_ATTRIBUTE)
    168      1.1  christos DEP_INIT_ATTRIBUTE void init(void)
    169      1.1  christos {
    170      1.1  christos     tsan_store(&FIPS_state, FIPS_STATE_SELFTEST);
    171      1.1  christos }
    172      1.1  christos #endif
    173      1.1  christos 
    174      1.1  christos #if defined(DEP_FINI_ATTRIBUTE)
    175      1.1  christos DEP_FINI_ATTRIBUTE void cleanup(void)
    176      1.1  christos {
    177      1.1  christos     CRYPTO_THREAD_lock_free(self_test_lock);
    178      1.1  christos }
    179      1.1  christos #endif
    180      1.1  christos 
    181      1.1  christos #if !defined(OPENSSL_NO_FIPS_POST)
    182      1.1  christos /*
    183      1.1  christos  * We need an explicit HMAC-SHA-256 KAT even though it is also
    184      1.1  christos  * checked as part of the KDF KATs.  Refer IG 10.3.
    185      1.1  christos  */
    186      1.1  christos static const unsigned char hmac_kat_pt[] = {
    187      1.1  christos     0xdd, 0x0c, 0x30, 0x33, 0x35, 0xf9, 0xe4, 0x2e,
    188      1.1  christos     0xc2, 0xef, 0xcc, 0xbf, 0x07, 0x95, 0xee, 0xa2
    189      1.1  christos };
    190      1.1  christos static const unsigned char hmac_kat_key[] = {
    191      1.1  christos     0xf4, 0x55, 0x66, 0x50, 0xac, 0x31, 0xd3, 0x54,
    192      1.1  christos     0x61, 0x61, 0x0b, 0xac, 0x4e, 0xd8, 0x1b, 0x1a,
    193      1.1  christos     0x18, 0x1b, 0x2d, 0x8a, 0x43, 0xea, 0x28, 0x54,
    194      1.1  christos     0xcb, 0xae, 0x22, 0xca, 0x74, 0x56, 0x08, 0x13
    195      1.1  christos };
    196      1.1  christos static const unsigned char hmac_kat_digest[] = {
    197      1.1  christos     0xf5, 0xf5, 0xe5, 0xf2, 0x66, 0x49, 0xe2, 0x40,
    198      1.1  christos     0xfc, 0x9e, 0x85, 0x7f, 0x2b, 0x9a, 0xbe, 0x28,
    199      1.1  christos     0x20, 0x12, 0x00, 0x92, 0x82, 0x21, 0x3e, 0x51,
    200      1.1  christos     0x44, 0x5d, 0xe3, 0x31, 0x04, 0x01, 0x72, 0x6b
    201      1.1  christos };
    202      1.1  christos 
    203      1.1  christos static int integrity_self_test(OSSL_SELF_TEST *ev, OSSL_LIB_CTX *libctx)
    204      1.1  christos {
    205      1.1  christos     int ok = 0;
    206      1.1  christos     unsigned char out[EVP_MAX_MD_SIZE];
    207      1.1  christos     size_t out_len = 0;
    208      1.1  christos 
    209  1.1.1.2  christos     OSSL_PARAM params[2];
    210  1.1.1.2  christos     EVP_MAC *mac = EVP_MAC_fetch(libctx, MAC_NAME, NULL);
    211      1.1  christos     EVP_MAC_CTX *ctx = EVP_MAC_CTX_new(mac);
    212      1.1  christos 
    213      1.1  christos     OSSL_SELF_TEST_onbegin(ev, OSSL_SELF_TEST_TYPE_KAT_INTEGRITY,
    214  1.1.1.2  christos         OSSL_SELF_TEST_DESC_INTEGRITY_HMAC);
    215      1.1  christos 
    216      1.1  christos     params[0] = OSSL_PARAM_construct_utf8_string("digest", DIGEST_NAME, 0);
    217      1.1  christos     params[1] = OSSL_PARAM_construct_end();
    218      1.1  christos 
    219      1.1  christos     if (ctx == NULL
    220  1.1.1.2  christos         || mac == NULL
    221  1.1.1.2  christos         || !EVP_MAC_init(ctx, hmac_kat_key, sizeof(hmac_kat_key), params)
    222  1.1.1.2  christos         || !EVP_MAC_update(ctx, hmac_kat_pt, sizeof(hmac_kat_pt))
    223  1.1.1.2  christos         || !EVP_MAC_final(ctx, out, &out_len, MAX_MD_SIZE))
    224      1.1  christos         goto err;
    225      1.1  christos 
    226      1.1  christos     /* Optional corruption */
    227      1.1  christos     OSSL_SELF_TEST_oncorrupt_byte(ev, out);
    228      1.1  christos 
    229      1.1  christos     if (out_len != sizeof(hmac_kat_digest)
    230  1.1.1.2  christos         || memcmp(out, hmac_kat_digest, out_len) != 0)
    231      1.1  christos         goto err;
    232      1.1  christos     ok = 1;
    233      1.1  christos err:
    234      1.1  christos     OSSL_SELF_TEST_onend(ev, ok);
    235      1.1  christos     EVP_MAC_free(mac);
    236      1.1  christos     EVP_MAC_CTX_free(ctx);
    237      1.1  christos     return ok;
    238      1.1  christos }
    239      1.1  christos 
    240      1.1  christos /*
    241      1.1  christos  * Calculate the HMAC SHA256 of data read using a BIO and read_cb, and verify
    242      1.1  christos  * the result matches the expected value.
    243      1.1  christos  * Return 1 if verified, or 0 if it fails.
    244      1.1  christos  */
    245      1.1  christos static int verify_integrity(OSSL_CORE_BIO *bio, OSSL_FUNC_BIO_read_ex_fn read_ex_cb,
    246  1.1.1.2  christos     unsigned char *expected, size_t expected_len,
    247  1.1.1.2  christos     OSSL_LIB_CTX *libctx, OSSL_SELF_TEST *ev,
    248  1.1.1.2  christos     const char *event_type)
    249      1.1  christos {
    250      1.1  christos     int ret = 0, status;
    251      1.1  christos     unsigned char out[MAX_MD_SIZE];
    252      1.1  christos     unsigned char buf[INTEGRITY_BUF_SIZE];
    253      1.1  christos     size_t bytes_read = 0, out_len = 0;
    254      1.1  christos     EVP_MAC *mac = NULL;
    255      1.1  christos     EVP_MAC_CTX *ctx = NULL;
    256      1.1  christos     OSSL_PARAM params[2], *p = params;
    257      1.1  christos 
    258      1.1  christos     if (!integrity_self_test(ev, libctx))
    259      1.1  christos         goto err;
    260      1.1  christos 
    261      1.1  christos     OSSL_SELF_TEST_onbegin(ev, event_type, OSSL_SELF_TEST_DESC_INTEGRITY_HMAC);
    262      1.1  christos 
    263      1.1  christos     mac = EVP_MAC_fetch(libctx, MAC_NAME, NULL);
    264      1.1  christos     if (mac == NULL)
    265      1.1  christos         goto err;
    266      1.1  christos     ctx = EVP_MAC_CTX_new(mac);
    267      1.1  christos     if (ctx == NULL)
    268      1.1  christos         goto err;
    269      1.1  christos 
    270      1.1  christos     *p++ = OSSL_PARAM_construct_utf8_string("digest", DIGEST_NAME, 0);
    271      1.1  christos     *p = OSSL_PARAM_construct_end();
    272      1.1  christos 
    273      1.1  christos     if (!EVP_MAC_init(ctx, fixed_key, sizeof(fixed_key), params))
    274      1.1  christos         goto err;
    275      1.1  christos 
    276      1.1  christos     while (1) {
    277      1.1  christos         status = read_ex_cb(bio, buf, sizeof(buf), &bytes_read);
    278      1.1  christos         if (status != 1)
    279      1.1  christos             break;
    280      1.1  christos         if (!EVP_MAC_update(ctx, buf, bytes_read))
    281      1.1  christos             goto err;
    282      1.1  christos     }
    283      1.1  christos     if (!EVP_MAC_final(ctx, out, &out_len, sizeof(out)))
    284      1.1  christos         goto err;
    285      1.1  christos 
    286      1.1  christos     OSSL_SELF_TEST_oncorrupt_byte(ev, out);
    287      1.1  christos     if (expected_len != out_len
    288  1.1.1.2  christos         || memcmp(expected, out, out_len) != 0)
    289      1.1  christos         goto err;
    290      1.1  christos     ret = 1;
    291      1.1  christos err:
    292      1.1  christos     OSSL_SELF_TEST_onend(ev, ret);
    293      1.1  christos     EVP_MAC_CTX_free(ctx);
    294      1.1  christos     EVP_MAC_free(mac);
    295  1.1.1.2  christos #ifdef OPENSSL_PEDANTIC_ZEROIZATION
    296      1.1  christos     OPENSSL_cleanse(out, sizeof(out));
    297  1.1.1.2  christos #endif
    298      1.1  christos     return ret;
    299      1.1  christos }
    300      1.1  christos #endif /* OPENSSL_NO_FIPS_POST */
    301      1.1  christos 
    302      1.1  christos static void set_fips_state(int state)
    303      1.1  christos {
    304      1.1  christos     tsan_store(&FIPS_state, state);
    305      1.1  christos }
    306      1.1  christos 
    307      1.1  christos /* Return 1 if the FIPS self tests are running and 0 otherwise */
    308      1.1  christos int ossl_fips_self_testing(void)
    309      1.1  christos {
    310      1.1  christos     return tsan_load(&FIPS_state) == FIPS_STATE_SELFTEST;
    311      1.1  christos }
    312      1.1  christos 
    313      1.1  christos /* This API is triggered either on loading of the FIPS module or on demand */
    314      1.1  christos int SELF_TEST_post(SELF_TEST_POST_PARAMS *st, int on_demand_test)
    315      1.1  christos {
    316      1.1  christos     int loclstate;
    317      1.1  christos #if !defined(OPENSSL_NO_FIPS_POST)
    318      1.1  christos     int ok = 0;
    319      1.1  christos     long checksum_len;
    320      1.1  christos     OSSL_CORE_BIO *bio_module = NULL;
    321      1.1  christos     unsigned char *module_checksum = NULL;
    322      1.1  christos     OSSL_SELF_TEST *ev = NULL;
    323      1.1  christos     EVP_RAND *testrand = NULL;
    324      1.1  christos     EVP_RAND_CTX *rng;
    325      1.1  christos #endif
    326      1.1  christos 
    327      1.1  christos     if (!RUN_ONCE(&fips_self_test_init, do_fips_self_test_init))
    328      1.1  christos         return 0;
    329      1.1  christos 
    330      1.1  christos     loclstate = tsan_load(&FIPS_state);
    331      1.1  christos 
    332      1.1  christos     if (loclstate == FIPS_STATE_RUNNING) {
    333      1.1  christos         if (!on_demand_test)
    334      1.1  christos             return 1;
    335      1.1  christos     } else if (loclstate != FIPS_STATE_SELFTEST) {
    336      1.1  christos         ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_STATE);
    337      1.1  christos         return 0;
    338      1.1  christos     }
    339      1.1  christos 
    340      1.1  christos     if (!CRYPTO_THREAD_write_lock(self_test_lock))
    341      1.1  christos         return 0;
    342      1.1  christos 
    343      1.1  christos #if !defined(OPENSSL_NO_FIPS_POST)
    344      1.1  christos     loclstate = tsan_load(&FIPS_state);
    345      1.1  christos     if (loclstate == FIPS_STATE_RUNNING) {
    346      1.1  christos         if (!on_demand_test) {
    347      1.1  christos             CRYPTO_THREAD_unlock(self_test_lock);
    348      1.1  christos             return 1;
    349      1.1  christos         }
    350      1.1  christos         set_fips_state(FIPS_STATE_SELFTEST);
    351      1.1  christos     } else if (loclstate != FIPS_STATE_SELFTEST) {
    352      1.1  christos         CRYPTO_THREAD_unlock(self_test_lock);
    353      1.1  christos         ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_STATE);
    354      1.1  christos         return 0;
    355      1.1  christos     }
    356      1.1  christos 
    357      1.1  christos     if (st == NULL
    358  1.1.1.2  christos         || st->module_checksum_data == NULL) {
    359      1.1  christos         ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_CONFIG_DATA);
    360      1.1  christos         goto end;
    361      1.1  christos     }
    362      1.1  christos 
    363      1.1  christos     ev = OSSL_SELF_TEST_new(st->cb, st->cb_arg);
    364      1.1  christos     if (ev == NULL)
    365      1.1  christos         goto end;
    366      1.1  christos 
    367      1.1  christos     module_checksum = OPENSSL_hexstr2buf(st->module_checksum_data,
    368  1.1.1.2  christos         &checksum_len);
    369      1.1  christos     if (module_checksum == NULL) {
    370      1.1  christos         ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_CONFIG_DATA);
    371      1.1  christos         goto end;
    372      1.1  christos     }
    373      1.1  christos     bio_module = (*st->bio_new_file_cb)(st->module_filename, "rb");
    374      1.1  christos 
    375      1.1  christos     /* Always check the integrity of the fips module */
    376      1.1  christos     if (bio_module == NULL
    377  1.1.1.2  christos         || !verify_integrity(bio_module, st->bio_read_ex_cb,
    378  1.1.1.2  christos             module_checksum, checksum_len, st->libctx,
    379  1.1.1.2  christos             ev, OSSL_SELF_TEST_TYPE_MODULE_INTEGRITY)) {
    380      1.1  christos         ERR_raise(ERR_LIB_PROV, PROV_R_MODULE_INTEGRITY_FAILURE);
    381      1.1  christos         goto end;
    382      1.1  christos     }
    383      1.1  christos 
    384      1.1  christos     if (!SELF_TEST_kats(ev, st->libctx)) {
    385      1.1  christos         ERR_raise(ERR_LIB_PROV, PROV_R_SELF_TEST_KAT_FAILURE);
    386      1.1  christos         goto end;
    387      1.1  christos     }
    388      1.1  christos 
    389      1.1  christos     /* Verify that the RNG has been restored properly */
    390      1.1  christos     rng = ossl_rand_get0_private_noncreating(st->libctx);
    391      1.1  christos     if (rng != NULL)
    392      1.1  christos         if ((testrand = EVP_RAND_fetch(st->libctx, "TEST-RAND", NULL)) == NULL
    393  1.1.1.2  christos             || strcmp(EVP_RAND_get0_name(EVP_RAND_CTX_get0_rand(rng)),
    394  1.1.1.2  christos                    EVP_RAND_get0_name(testrand))
    395  1.1.1.2  christos                 == 0) {
    396      1.1  christos             ERR_raise(ERR_LIB_PROV, PROV_R_SELF_TEST_KAT_FAILURE);
    397      1.1  christos             goto end;
    398      1.1  christos         }
    399      1.1  christos 
    400      1.1  christos     ok = 1;
    401      1.1  christos end:
    402      1.1  christos     EVP_RAND_free(testrand);
    403      1.1  christos     OSSL_SELF_TEST_free(ev);
    404      1.1  christos     OPENSSL_free(module_checksum);
    405      1.1  christos 
    406      1.1  christos     if (st != NULL)
    407      1.1  christos         (*st->bio_free_cb)(bio_module);
    408      1.1  christos 
    409      1.1  christos     if (ok)
    410      1.1  christos         set_fips_state(FIPS_STATE_RUNNING);
    411      1.1  christos     else
    412      1.1  christos         ossl_set_error_state(OSSL_SELF_TEST_TYPE_NONE);
    413      1.1  christos     CRYPTO_THREAD_unlock(self_test_lock);
    414      1.1  christos 
    415      1.1  christos     return ok;
    416      1.1  christos #else
    417      1.1  christos     set_fips_state(FIPS_STATE_RUNNING);
    418      1.1  christos     CRYPTO_THREAD_unlock(self_test_lock);
    419      1.1  christos     return 1;
    420      1.1  christos #endif /* !defined(OPENSSL_NO_FIPS_POST) */
    421      1.1  christos }
    422      1.1  christos 
    423      1.1  christos void SELF_TEST_disable_conditional_error_state(void)
    424      1.1  christos {
    425      1.1  christos     FIPS_conditional_error_check = 0;
    426      1.1  christos }
    427      1.1  christos 
    428      1.1  christos void ossl_set_error_state(const char *type)
    429      1.1  christos {
    430  1.1.1.2  christos     int cond_test = 0;
    431  1.1.1.2  christos     int import_pct = 0;
    432  1.1.1.2  christos 
    433  1.1.1.2  christos     if (type != NULL) {
    434  1.1.1.2  christos         cond_test = strcmp(type, OSSL_SELF_TEST_TYPE_PCT) == 0;
    435  1.1.1.2  christos         import_pct = strcmp(type, OSSL_SELF_TEST_TYPE_PCT_IMPORT) == 0;
    436  1.1.1.2  christos     }
    437      1.1  christos 
    438  1.1.1.2  christos     if (import_pct) {
    439  1.1.1.2  christos         /* Failure to import is transient to avoid a DoS attack */
    440  1.1.1.2  christos         ERR_raise(ERR_LIB_PROV, PROV_R_FIPS_MODULE_IMPORT_PCT_ERROR);
    441  1.1.1.2  christos     } else if (!cond_test || (FIPS_conditional_error_check == 1)) {
    442      1.1  christos         set_fips_state(FIPS_STATE_ERROR);
    443      1.1  christos         ERR_raise(ERR_LIB_PROV, PROV_R_FIPS_MODULE_ENTERING_ERROR_STATE);
    444      1.1  christos     } else {
    445      1.1  christos         ERR_raise(ERR_LIB_PROV, PROV_R_FIPS_MODULE_CONDITIONAL_ERROR);
    446      1.1  christos     }
    447      1.1  christos }
    448      1.1  christos 
    449      1.1  christos int ossl_prov_is_running(void)
    450      1.1  christos {
    451      1.1  christos     int res, loclstate;
    452      1.1  christos     static TSAN_QUALIFIER unsigned int rate_limit = 0;
    453      1.1  christos 
    454      1.1  christos     loclstate = tsan_load(&FIPS_state);
    455      1.1  christos     res = loclstate == FIPS_STATE_RUNNING || loclstate == FIPS_STATE_SELFTEST;
    456      1.1  christos     if (loclstate == FIPS_STATE_ERROR)
    457      1.1  christos         if (tsan_counter(&rate_limit) < FIPS_ERROR_REPORTING_RATE_LIMIT)
    458      1.1  christos             ERR_raise(ERR_LIB_PROV, PROV_R_FIPS_MODULE_IN_ERROR_STATE);
    459      1.1  christos     return res;
    460      1.1  christos }
    461