1 /*
2 * Copyright 2019-2026 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 #ifndef __CYGWIN__
105 cleanup();
106 #endif
107 break;
108 default:
109 break;
110 }
111 return TRUE;
112 }
113
114 #elif defined(__GNUC__) && !defined(_AIX)
115 #undef DEP_INIT_ATTRIBUTE
116 #undef DEP_FINI_ATTRIBUTE
117 #define DEP_INIT_ATTRIBUTE static __attribute__((constructor))
118 #define DEP_FINI_ATTRIBUTE static __attribute__((destructor))
119
120 #elif defined(__sun)
121 #pragma init(init)
122 #pragma fini(cleanup)
123
124 #elif defined(_AIX) && !defined(__GNUC__)
125 void _init(void);
126 void _cleanup(void);
127 #pragma init(_init)
128 #pragma fini(_cleanup)
_init(void)129 void _init(void)
130 {
131 init();
132 }
_cleanup(void)133 void _cleanup(void)
134 {
135 cleanup();
136 }
137
138 #elif defined(__hpux)
139 #pragma init "init"
140 #pragma fini "cleanup"
141
142 #elif defined(__TANDEM)
143 /* Method automatically called by the NonStop OS when the DLL loads */
__INIT__init(void)144 void __INIT__init(void)
145 {
146 init();
147 }
148
149 /* Method automatically called by the NonStop OS prior to unloading the DLL */
__TERM__cleanup(void)150 void __TERM__cleanup(void)
151 {
152 cleanup();
153 }
154
155 #else
156 /*
157 * This build does not support any kind of DEP.
158 * We force the self-tests to run as part of the FIPS provider initialisation
159 * rather than being triggered by the DEP.
160 */
161 #undef DEP_INIT_ATTRIBUTE
162 #undef DEP_FINI_ATTRIBUTE
163 #undef DEP_INITIAL_STATE
164 #define DEP_INITIAL_STATE FIPS_STATE_SELFTEST
165 #endif
166
167 static TSAN_QUALIFIER int FIPS_state = DEP_INITIAL_STATE;
168
169 #if defined(DEP_INIT_ATTRIBUTE)
init(void)170 DEP_INIT_ATTRIBUTE void init(void)
171 {
172 tsan_store(&FIPS_state, FIPS_STATE_SELFTEST);
173 }
174 #endif
175
176 #if defined(DEP_FINI_ATTRIBUTE)
cleanup(void)177 DEP_FINI_ATTRIBUTE void cleanup(void)
178 {
179 CRYPTO_THREAD_lock_free(self_test_lock);
180 }
181 #endif
182
183 #if !defined(OPENSSL_NO_FIPS_POST)
184 /*
185 * We need an explicit HMAC-SHA-256 KAT even though it is also
186 * checked as part of the KDF KATs. Refer IG 10.3.
187 */
188 static const unsigned char hmac_kat_pt[] = {
189 0xdd, 0x0c, 0x30, 0x33, 0x35, 0xf9, 0xe4, 0x2e,
190 0xc2, 0xef, 0xcc, 0xbf, 0x07, 0x95, 0xee, 0xa2
191 };
192 static const unsigned char hmac_kat_key[] = {
193 0xf4, 0x55, 0x66, 0x50, 0xac, 0x31, 0xd3, 0x54,
194 0x61, 0x61, 0x0b, 0xac, 0x4e, 0xd8, 0x1b, 0x1a,
195 0x18, 0x1b, 0x2d, 0x8a, 0x43, 0xea, 0x28, 0x54,
196 0xcb, 0xae, 0x22, 0xca, 0x74, 0x56, 0x08, 0x13
197 };
198 static const unsigned char hmac_kat_digest[] = {
199 0xf5, 0xf5, 0xe5, 0xf2, 0x66, 0x49, 0xe2, 0x40,
200 0xfc, 0x9e, 0x85, 0x7f, 0x2b, 0x9a, 0xbe, 0x28,
201 0x20, 0x12, 0x00, 0x92, 0x82, 0x21, 0x3e, 0x51,
202 0x44, 0x5d, 0xe3, 0x31, 0x04, 0x01, 0x72, 0x6b
203 };
204
integrity_self_test(OSSL_SELF_TEST * ev,OSSL_LIB_CTX * libctx)205 static int integrity_self_test(OSSL_SELF_TEST *ev, OSSL_LIB_CTX *libctx)
206 {
207 int ok = 0;
208 unsigned char out[EVP_MAX_MD_SIZE];
209 size_t out_len = 0;
210
211 OSSL_PARAM params[2];
212 EVP_MAC *mac = EVP_MAC_fetch(libctx, MAC_NAME, NULL);
213 EVP_MAC_CTX *ctx = EVP_MAC_CTX_new(mac);
214
215 OSSL_SELF_TEST_onbegin(ev, OSSL_SELF_TEST_TYPE_KAT_INTEGRITY,
216 OSSL_SELF_TEST_DESC_INTEGRITY_HMAC);
217
218 params[0] = OSSL_PARAM_construct_utf8_string("digest", DIGEST_NAME, 0);
219 params[1] = OSSL_PARAM_construct_end();
220
221 if (ctx == NULL
222 || mac == NULL
223 || !EVP_MAC_init(ctx, hmac_kat_key, sizeof(hmac_kat_key), params)
224 || !EVP_MAC_update(ctx, hmac_kat_pt, sizeof(hmac_kat_pt))
225 || !EVP_MAC_final(ctx, out, &out_len, MAX_MD_SIZE))
226 goto err;
227
228 /* Optional corruption */
229 OSSL_SELF_TEST_oncorrupt_byte(ev, out);
230
231 if (out_len != sizeof(hmac_kat_digest)
232 || memcmp(out, hmac_kat_digest, out_len) != 0)
233 goto err;
234 ok = 1;
235 err:
236 OSSL_SELF_TEST_onend(ev, ok);
237 EVP_MAC_free(mac);
238 EVP_MAC_CTX_free(ctx);
239 return ok;
240 }
241
242 /*
243 * Calculate the HMAC SHA256 of data read using a BIO and read_cb, and verify
244 * the result matches the expected value.
245 * Return 1 if verified, or 0 if it fails.
246 */
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)247 static int verify_integrity(OSSL_CORE_BIO *bio, OSSL_FUNC_BIO_read_ex_fn read_ex_cb,
248 unsigned char *expected, size_t expected_len,
249 OSSL_LIB_CTX *libctx, OSSL_SELF_TEST *ev,
250 const char *event_type)
251 {
252 int ret = 0, status;
253 unsigned char out[MAX_MD_SIZE];
254 unsigned char buf[INTEGRITY_BUF_SIZE];
255 size_t bytes_read = 0, out_len = 0;
256 EVP_MAC *mac = NULL;
257 EVP_MAC_CTX *ctx = NULL;
258 OSSL_PARAM params[2], *p = params;
259
260 if (!integrity_self_test(ev, libctx))
261 goto err;
262
263 OSSL_SELF_TEST_onbegin(ev, event_type, OSSL_SELF_TEST_DESC_INTEGRITY_HMAC);
264
265 mac = EVP_MAC_fetch(libctx, MAC_NAME, NULL);
266 if (mac == NULL)
267 goto err;
268 ctx = EVP_MAC_CTX_new(mac);
269 if (ctx == NULL)
270 goto err;
271
272 *p++ = OSSL_PARAM_construct_utf8_string("digest", DIGEST_NAME, 0);
273 *p = OSSL_PARAM_construct_end();
274
275 if (!EVP_MAC_init(ctx, fixed_key, sizeof(fixed_key), params))
276 goto err;
277
278 while (1) {
279 status = read_ex_cb(bio, buf, sizeof(buf), &bytes_read);
280 if (status != 1)
281 break;
282 if (!EVP_MAC_update(ctx, buf, bytes_read))
283 goto err;
284 }
285 if (!EVP_MAC_final(ctx, out, &out_len, sizeof(out)))
286 goto err;
287
288 OSSL_SELF_TEST_oncorrupt_byte(ev, out);
289 if (expected_len != out_len
290 || memcmp(expected, out, out_len) != 0)
291 goto err;
292 ret = 1;
293 err:
294 OSSL_SELF_TEST_onend(ev, ret);
295 EVP_MAC_CTX_free(ctx);
296 EVP_MAC_free(mac);
297 #ifdef OPENSSL_PEDANTIC_ZEROIZATION
298 OPENSSL_cleanse(out, sizeof(out));
299 #endif
300 return ret;
301 }
302 #endif /* OPENSSL_NO_FIPS_POST */
303
set_fips_state(int state)304 static void set_fips_state(int state)
305 {
306 tsan_store(&FIPS_state, state);
307 }
308
309 /* Return 1 if the FIPS self tests are running and 0 otherwise */
ossl_fips_self_testing(void)310 int ossl_fips_self_testing(void)
311 {
312 return tsan_load(&FIPS_state) == FIPS_STATE_SELFTEST;
313 }
314
315 /* 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)316 int SELF_TEST_post(SELF_TEST_POST_PARAMS *st, int on_demand_test)
317 {
318 int loclstate;
319 #if !defined(OPENSSL_NO_FIPS_POST)
320 int ok = 0;
321 long checksum_len;
322 OSSL_CORE_BIO *bio_module = NULL;
323 unsigned char *module_checksum = NULL;
324 OSSL_SELF_TEST *ev = NULL;
325 EVP_RAND *testrand = NULL;
326 EVP_RAND_CTX *rng;
327 #endif
328
329 if (!RUN_ONCE(&fips_self_test_init, do_fips_self_test_init))
330 return 0;
331
332 loclstate = tsan_load(&FIPS_state);
333
334 if (loclstate == FIPS_STATE_RUNNING) {
335 if (!on_demand_test)
336 return 1;
337 } else if (loclstate != FIPS_STATE_SELFTEST) {
338 ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_STATE);
339 return 0;
340 }
341
342 if (!CRYPTO_THREAD_write_lock(self_test_lock))
343 return 0;
344
345 #if !defined(OPENSSL_NO_FIPS_POST)
346 loclstate = tsan_load(&FIPS_state);
347 if (loclstate == FIPS_STATE_RUNNING) {
348 if (!on_demand_test) {
349 CRYPTO_THREAD_unlock(self_test_lock);
350 return 1;
351 }
352 set_fips_state(FIPS_STATE_SELFTEST);
353 } else if (loclstate != FIPS_STATE_SELFTEST) {
354 CRYPTO_THREAD_unlock(self_test_lock);
355 ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_STATE);
356 return 0;
357 }
358
359 if (st == NULL
360 || st->module_checksum_data == NULL) {
361 ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_CONFIG_DATA);
362 goto end;
363 }
364
365 ev = OSSL_SELF_TEST_new(st->cb, st->cb_arg);
366 if (ev == NULL)
367 goto end;
368
369 module_checksum = OPENSSL_hexstr2buf(st->module_checksum_data,
370 &checksum_len);
371 if (module_checksum == NULL) {
372 ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_CONFIG_DATA);
373 goto end;
374 }
375 bio_module = (*st->bio_new_file_cb)(st->module_filename, "rb");
376
377 /* Always check the integrity of the fips module */
378 if (bio_module == NULL
379 || !verify_integrity(bio_module, st->bio_read_ex_cb,
380 module_checksum, checksum_len, st->libctx,
381 ev, OSSL_SELF_TEST_TYPE_MODULE_INTEGRITY)) {
382 ERR_raise(ERR_LIB_PROV, PROV_R_MODULE_INTEGRITY_FAILURE);
383 goto end;
384 }
385
386 if (!SELF_TEST_kats(ev, st->libctx)) {
387 ERR_raise(ERR_LIB_PROV, PROV_R_SELF_TEST_KAT_FAILURE);
388 goto end;
389 }
390
391 /* Verify that the RNG has been restored properly */
392 rng = ossl_rand_get0_private_noncreating(st->libctx);
393 if (rng != NULL)
394 if ((testrand = EVP_RAND_fetch(st->libctx, "TEST-RAND", NULL)) == NULL
395 || strcmp(EVP_RAND_get0_name(EVP_RAND_CTX_get0_rand(rng)),
396 EVP_RAND_get0_name(testrand))
397 == 0) {
398 ERR_raise(ERR_LIB_PROV, PROV_R_SELF_TEST_KAT_FAILURE);
399 goto end;
400 }
401
402 ok = 1;
403 end:
404 EVP_RAND_free(testrand);
405 OSSL_SELF_TEST_free(ev);
406 OPENSSL_free(module_checksum);
407
408 if (st != NULL)
409 (*st->bio_free_cb)(bio_module);
410
411 if (ok)
412 set_fips_state(FIPS_STATE_RUNNING);
413 else
414 ossl_set_error_state(OSSL_SELF_TEST_TYPE_NONE);
415 CRYPTO_THREAD_unlock(self_test_lock);
416
417 return ok;
418 #else
419 set_fips_state(FIPS_STATE_RUNNING);
420 CRYPTO_THREAD_unlock(self_test_lock);
421 return 1;
422 #endif /* !defined(OPENSSL_NO_FIPS_POST) */
423 }
424
SELF_TEST_disable_conditional_error_state(void)425 void SELF_TEST_disable_conditional_error_state(void)
426 {
427 FIPS_conditional_error_check = 0;
428 }
429
ossl_set_error_state(const char * type)430 void ossl_set_error_state(const char *type)
431 {
432 int cond_test = 0;
433 int import_pct = 0;
434
435 if (type != NULL) {
436 cond_test = strcmp(type, OSSL_SELF_TEST_TYPE_PCT) == 0;
437 import_pct = strcmp(type, OSSL_SELF_TEST_TYPE_PCT_IMPORT) == 0;
438 }
439
440 if (import_pct) {
441 /* Failure to import is transient to avoid a DoS attack */
442 ERR_raise(ERR_LIB_PROV, PROV_R_FIPS_MODULE_IMPORT_PCT_ERROR);
443 } else if (!cond_test || (FIPS_conditional_error_check == 1)) {
444 set_fips_state(FIPS_STATE_ERROR);
445 ERR_raise(ERR_LIB_PROV, PROV_R_FIPS_MODULE_ENTERING_ERROR_STATE);
446 } else {
447 ERR_raise(ERR_LIB_PROV, PROV_R_FIPS_MODULE_CONDITIONAL_ERROR);
448 }
449 }
450
ossl_prov_is_running(void)451 int ossl_prov_is_running(void)
452 {
453 int res, loclstate;
454 static TSAN_QUALIFIER unsigned int rate_limit = 0;
455
456 loclstate = tsan_load(&FIPS_state);
457 res = loclstate == FIPS_STATE_RUNNING || loclstate == FIPS_STATE_SELFTEST;
458 if (loclstate == FIPS_STATE_ERROR)
459 if (tsan_counter(&rate_limit) < FIPS_ERROR_REPORTING_RATE_LIMIT)
460 ERR_raise(ERR_LIB_PROV, PROV_R_FIPS_MODULE_IN_ERROR_STATE);
461 return res;
462 }
463