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