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/threads_common.h"
22 #include "internal/tsan_assist.h"
23 #include "prov/providercommon.h"
24 #include "crypto/rand.h"
25 
26 /*
27  * We're cheating here. Normally we don't allow RUN_ONCE usage inside the FIPS
28  * module because all such initialisation should be associated with an
29  * individual OSSL_LIB_CTX. That doesn't work with the self test though because
30  * it should be run once regardless of the number of OSSL_LIB_CTXs we have.
31  */
32 #define ALLOW_RUN_ONCE_IN_FIPS
33 #include "internal/thread_once.h"
34 #include "self_test.h"
35 
36 #define FIPS_STATE_INIT     0
37 #define FIPS_STATE_SELFTEST 1
38 #define FIPS_STATE_RUNNING  2
39 #define FIPS_STATE_ERROR    3
40 
41 /*
42  * The number of times the module will report it is in the error state
43  * before going quiet.
44  */
45 #define FIPS_ERROR_REPORTING_RATE_LIMIT     10
46 
47 /* The size of a temp buffer used to read in data */
48 #define INTEGRITY_BUF_SIZE (4096)
49 #define MAX_MD_SIZE 64
50 #define MAC_NAME    "HMAC"
51 #define DIGEST_NAME "SHA256"
52 
53 static int FIPS_conditional_error_check = 1;
54 static CRYPTO_RWLOCK *self_test_lock = NULL;
55 
56 static CRYPTO_ONCE fips_self_test_init = CRYPTO_ONCE_STATIC_INIT;
57 #if !defined(OPENSSL_NO_FIPS_POST)
58 static unsigned char fixed_key[32] = { FIPS_KEY_ELEMENTS };
59 #endif
60 
DEFINE_RUN_ONCE_STATIC(do_fips_self_test_init)61 DEFINE_RUN_ONCE_STATIC(do_fips_self_test_init)
62 {
63     /*
64      * These locks get freed in platform specific ways that may occur after we
65      * do mem leak checking. If we don't know how to free it for a particular
66      * platform then we just leak it deliberately.
67      */
68     self_test_lock = CRYPTO_THREAD_lock_new();
69     return self_test_lock != NULL;
70 }
71 
72 /*
73  * Declarations for the DEP entry/exit points.
74  * Ones not required or incorrect need to be undefined or redefined respectively.
75  */
76 #define DEP_INITIAL_STATE   FIPS_STATE_INIT
77 #define DEP_INIT_ATTRIBUTE  static
78 #define DEP_FINI_ATTRIBUTE  static
79 
80 static void init(void);
81 static void cleanup(void);
82 
83 /*
84  * This is the Default Entry Point (DEP) code.
85  * See FIPS 140-2 IG 9.10
86  */
87 #if defined(_WIN32) || defined(__CYGWIN__)
88 # ifdef __CYGWIN__
89 /* pick DLL_[PROCESS|THREAD]_[ATTACH|DETACH] definitions */
90 #  include <windows.h>
91 /*
92  * this has side-effect of _WIN32 getting defined, which otherwise is
93  * mutually exclusive with __CYGWIN__...
94  */
95 # endif
96 
97 BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved);
DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved)98 BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
99 {
100     switch (fdwReason) {
101     case DLL_PROCESS_ATTACH:
102         init();
103         break;
104     case DLL_PROCESS_DETACH:
105         cleanup();
106         break;
107     default:
108         break;
109     }
110     return TRUE;
111 }
112 
113 #elif defined(__GNUC__) && !defined(_AIX)
114 # undef DEP_INIT_ATTRIBUTE
115 # undef DEP_FINI_ATTRIBUTE
116 # define DEP_INIT_ATTRIBUTE static __attribute__((constructor))
117 # define DEP_FINI_ATTRIBUTE static __attribute__((destructor))
118 
119 #elif defined(__sun)
120 # pragma init(init)
121 # pragma fini(cleanup)
122 
123 #elif defined(_AIX) && !defined(__GNUC__)
124 void _init(void);
125 void _cleanup(void);
126 # pragma init(_init)
127 # pragma fini(_cleanup)
_init(void)128 void _init(void)
129 {
130     init();
131 }
_cleanup(void)132 void _cleanup(void)
133 {
134     cleanup();
135 }
136 
137 #elif defined(__hpux)
138 # pragma init "init"
139 # pragma fini "cleanup"
140 
141 #elif defined(__TANDEM)
142 /* Method automatically called by the NonStop OS when the DLL loads */
__INIT__init(void)143 void __INIT__init(void) {
144     init();
145 }
146 
147 /* Method automatically called by the NonStop OS prior to unloading the DLL */
__TERM__cleanup(void)148 void __TERM__cleanup(void) {
149     cleanup();
150 }
151 
152 #else
153 /*
154  * This build does not support any kind of DEP.
155  * We force the self-tests to run as part of the FIPS provider initialisation
156  * rather than being triggered by the DEP.
157  */
158 # undef DEP_INIT_ATTRIBUTE
159 # undef DEP_FINI_ATTRIBUTE
160 # undef DEP_INITIAL_STATE
161 # define DEP_INITIAL_STATE  FIPS_STATE_SELFTEST
162 #endif
163 
164 static TSAN_QUALIFIER int FIPS_state = DEP_INITIAL_STATE;
165 
166 #if defined(DEP_INIT_ATTRIBUTE)
init(void)167 DEP_INIT_ATTRIBUTE void init(void)
168 {
169     tsan_store(&FIPS_state, FIPS_STATE_SELFTEST);
170 }
171 #endif
172 
173 #if defined(DEP_FINI_ATTRIBUTE)
cleanup(void)174 DEP_FINI_ATTRIBUTE void cleanup(void)
175 {
176     CRYPTO_THREAD_lock_free(self_test_lock);
177     CRYPTO_THREAD_clean_local_for_fips();
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 
integrity_self_test(OSSL_SELF_TEST * ev,OSSL_LIB_CTX * libctx)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  */
verify_integrity(OSSL_CORE_BIO * bio,OSSL_FUNC_BIO_read_ex_fn read_ex_cb,unsigned char * expected,size_t expected_len,OSSL_LIB_CTX * libctx,OSSL_SELF_TEST * ev,const char * event_type)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 
set_fips_state(int state)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 */
ossl_fips_self_testing(void)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 */
SELF_TEST_post(SELF_TEST_POST_PARAMS * st,int on_demand_test)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)) == 0) {
395             ERR_raise(ERR_LIB_PROV, PROV_R_SELF_TEST_KAT_FAILURE);
396             goto end;
397         }
398 
399     ok = 1;
400 end:
401     EVP_RAND_free(testrand);
402     OSSL_SELF_TEST_free(ev);
403     OPENSSL_free(module_checksum);
404 
405     if (st != NULL)
406         (*st->bio_free_cb)(bio_module);
407 
408     if (ok)
409         set_fips_state(FIPS_STATE_RUNNING);
410     else
411         ossl_set_error_state(OSSL_SELF_TEST_TYPE_NONE);
412     CRYPTO_THREAD_unlock(self_test_lock);
413 
414     return ok;
415 #else
416     set_fips_state(FIPS_STATE_RUNNING);
417     CRYPTO_THREAD_unlock(self_test_lock);
418     return 1;
419 #endif /* !defined(OPENSSL_NO_FIPS_POST) */
420 }
421 
SELF_TEST_disable_conditional_error_state(void)422 void SELF_TEST_disable_conditional_error_state(void)
423 {
424     FIPS_conditional_error_check = 0;
425 }
426 
ossl_set_error_state(const char * type)427 void ossl_set_error_state(const char *type)
428 {
429     int cond_test = (type != NULL && strcmp(type, OSSL_SELF_TEST_TYPE_PCT) == 0);
430 
431     if (!cond_test || (FIPS_conditional_error_check == 1)) {
432         set_fips_state(FIPS_STATE_ERROR);
433         ERR_raise(ERR_LIB_PROV, PROV_R_FIPS_MODULE_ENTERING_ERROR_STATE);
434     } else {
435         ERR_raise(ERR_LIB_PROV, PROV_R_FIPS_MODULE_CONDITIONAL_ERROR);
436     }
437 }
438 
ossl_prov_is_running(void)439 int ossl_prov_is_running(void)
440 {
441     int res, loclstate;
442     static TSAN_QUALIFIER unsigned int rate_limit = 0;
443 
444     loclstate = tsan_load(&FIPS_state);
445     res = loclstate == FIPS_STATE_RUNNING || loclstate == FIPS_STATE_SELFTEST;
446     if (loclstate == FIPS_STATE_ERROR)
447         if (tsan_counter(&rate_limit) < FIPS_ERROR_REPORTING_RATE_LIMIT)
448             ERR_raise(ERR_LIB_PROV, PROV_R_FIPS_MODULE_IN_ERROR_STATE);
449     return res;
450 }
451