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