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
DEFINE_RUN_ONCE_STATIC(do_fips_self_test_init)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);
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)
_init(void)127 void _init(void)
128 {
129 init();
130 }
_cleanup(void)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 */
__INIT__init(void)142 void __INIT__init(void)
143 {
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 {
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)
init(void)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)
cleanup(void)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
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))
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
SELF_TEST_disable_conditional_error_state(void)423 void SELF_TEST_disable_conditional_error_state(void)
424 {
425 FIPS_conditional_error_check = 0;
426 }
427
ossl_set_error_state(const char * type)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
ossl_prov_is_running(void)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