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