1 /*
2 * Copyright 2019-2024 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/tsan_assist.h"
21 #include "prov/providercommon.h"
22 #include "crypto/rand.h"
23
24 /*
25 * We're cheating here. Normally we don't allow RUN_ONCE usage inside the FIPS
26 * module because all such initialisation should be associated with an
27 * individual OSSL_LIB_CTX. That doesn't work with the self test though because
28 * it should be run once regardless of the number of OSSL_LIB_CTXs we have.
29 */
30 #define ALLOW_RUN_ONCE_IN_FIPS
31 #include "internal/thread_once.h"
32 #include "self_test.h"
33
34 #define FIPS_STATE_INIT 0
35 #define FIPS_STATE_SELFTEST 1
36 #define FIPS_STATE_RUNNING 2
37 #define FIPS_STATE_ERROR 3
38
39 /*
40 * The number of times the module will report it is in the error state
41 * before going quiet.
42 */
43 #define FIPS_ERROR_REPORTING_RATE_LIMIT 10
44
45 /* The size of a temp buffer used to read in data */
46 #define INTEGRITY_BUF_SIZE (4096)
47 #define MAX_MD_SIZE 64
48 #define MAC_NAME "HMAC"
49 #define DIGEST_NAME "SHA256"
50
51 static int FIPS_conditional_error_check = 1;
52 static CRYPTO_RWLOCK *self_test_lock = NULL;
53
54 static CRYPTO_ONCE fips_self_test_init = CRYPTO_ONCE_STATIC_INIT;
55 #if !defined(OPENSSL_NO_FIPS_POST)
56 static unsigned char fixed_key[32] = { FIPS_KEY_ELEMENTS };
57 #endif
58
DEFINE_RUN_ONCE_STATIC(do_fips_self_test_init)59 DEFINE_RUN_ONCE_STATIC(do_fips_self_test_init)
60 {
61 /*
62 * These locks get freed in platform specific ways that may occur after we
63 * do mem leak checking. If we don't know how to free it for a particular
64 * platform then we just leak it deliberately.
65 */
66 self_test_lock = CRYPTO_THREAD_lock_new();
67 return self_test_lock != NULL;
68 }
69
70 /*
71 * Declarations for the DEP entry/exit points.
72 * Ones not required or incorrect need to be undefined or redefined respectively.
73 */
74 #define DEP_INITIAL_STATE FIPS_STATE_INIT
75 #define DEP_INIT_ATTRIBUTE static
76 #define DEP_FINI_ATTRIBUTE static
77
78 static void init(void);
79 static void cleanup(void);
80
81 /*
82 * This is the Default Entry Point (DEP) code.
83 * See FIPS 140-2 IG 9.10
84 */
85 #if defined(_WIN32) || defined(__CYGWIN__)
86 # ifdef __CYGWIN__
87 /* pick DLL_[PROCESS|THREAD]_[ATTACH|DETACH] definitions */
88 # include <windows.h>
89 /*
90 * this has side-effect of _WIN32 getting defined, which otherwise is
91 * mutually exclusive with __CYGWIN__...
92 */
93 # endif
94
95 BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved);
DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved)96 BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
97 {
98 switch (fdwReason) {
99 case DLL_PROCESS_ATTACH:
100 init();
101 break;
102 case DLL_PROCESS_DETACH:
103 cleanup();
104 break;
105 default:
106 break;
107 }
108 return TRUE;
109 }
110
111 #elif defined(__GNUC__) && !defined(_AIX)
112 # undef DEP_INIT_ATTRIBUTE
113 # undef DEP_FINI_ATTRIBUTE
114 # define DEP_INIT_ATTRIBUTE static __attribute__((constructor))
115 # define DEP_FINI_ATTRIBUTE static __attribute__((destructor))
116
117 #elif defined(__sun)
118 # pragma init(init)
119 # pragma fini(cleanup)
120
121 #elif defined(_AIX) && !defined(__GNUC__)
122 void _init(void);
123 void _cleanup(void);
124 # pragma init(_init)
125 # pragma fini(_cleanup)
_init(void)126 void _init(void)
127 {
128 init();
129 }
_cleanup(void)130 void _cleanup(void)
131 {
132 cleanup();
133 }
134
135 #elif defined(__hpux)
136 # pragma init "init"
137 # pragma fini "cleanup"
138
139 #elif defined(__TANDEM)
140 /* Method automatically called by the NonStop OS when the DLL loads */
__INIT__init(void)141 void __INIT__init(void) {
142 init();
143 }
144
145 /* Method automatically called by the NonStop OS prior to unloading the DLL */
__TERM__cleanup(void)146 void __TERM__cleanup(void) {
147 cleanup();
148 }
149
150 #else
151 /*
152 * This build does not support any kind of DEP.
153 * We force the self-tests to run as part of the FIPS provider initialisation
154 * rather than being triggered by the DEP.
155 */
156 # undef DEP_INIT_ATTRIBUTE
157 # undef DEP_FINI_ATTRIBUTE
158 # undef DEP_INITIAL_STATE
159 # define DEP_INITIAL_STATE FIPS_STATE_SELFTEST
160 #endif
161
162 static TSAN_QUALIFIER int FIPS_state = DEP_INITIAL_STATE;
163
164 #if defined(DEP_INIT_ATTRIBUTE)
init(void)165 DEP_INIT_ATTRIBUTE void init(void)
166 {
167 tsan_store(&FIPS_state, FIPS_STATE_SELFTEST);
168 }
169 #endif
170
171 #if defined(DEP_FINI_ATTRIBUTE)
cleanup(void)172 DEP_FINI_ATTRIBUTE void cleanup(void)
173 {
174 CRYPTO_THREAD_lock_free(self_test_lock);
175 }
176 #endif
177
178 #if !defined(OPENSSL_NO_FIPS_POST)
179 /*
180 * We need an explicit HMAC-SHA-256 KAT even though it is also
181 * checked as part of the KDF KATs. Refer IG 10.3.
182 */
183 static const unsigned char hmac_kat_pt[] = {
184 0xdd, 0x0c, 0x30, 0x33, 0x35, 0xf9, 0xe4, 0x2e,
185 0xc2, 0xef, 0xcc, 0xbf, 0x07, 0x95, 0xee, 0xa2
186 };
187 static const unsigned char hmac_kat_key[] = {
188 0xf4, 0x55, 0x66, 0x50, 0xac, 0x31, 0xd3, 0x54,
189 0x61, 0x61, 0x0b, 0xac, 0x4e, 0xd8, 0x1b, 0x1a,
190 0x18, 0x1b, 0x2d, 0x8a, 0x43, 0xea, 0x28, 0x54,
191 0xcb, 0xae, 0x22, 0xca, 0x74, 0x56, 0x08, 0x13
192 };
193 static const unsigned char hmac_kat_digest[] = {
194 0xf5, 0xf5, 0xe5, 0xf2, 0x66, 0x49, 0xe2, 0x40,
195 0xfc, 0x9e, 0x85, 0x7f, 0x2b, 0x9a, 0xbe, 0x28,
196 0x20, 0x12, 0x00, 0x92, 0x82, 0x21, 0x3e, 0x51,
197 0x44, 0x5d, 0xe3, 0x31, 0x04, 0x01, 0x72, 0x6b
198 };
199
integrity_self_test(OSSL_SELF_TEST * ev,OSSL_LIB_CTX * libctx)200 static int integrity_self_test(OSSL_SELF_TEST *ev, OSSL_LIB_CTX *libctx)
201 {
202 int ok = 0;
203 unsigned char out[EVP_MAX_MD_SIZE];
204 size_t out_len = 0;
205
206 OSSL_PARAM params[2];
207 EVP_MAC *mac = EVP_MAC_fetch(libctx, MAC_NAME, NULL);
208 EVP_MAC_CTX *ctx = EVP_MAC_CTX_new(mac);
209
210 OSSL_SELF_TEST_onbegin(ev, OSSL_SELF_TEST_TYPE_KAT_INTEGRITY,
211 OSSL_SELF_TEST_DESC_INTEGRITY_HMAC);
212
213 params[0] = OSSL_PARAM_construct_utf8_string("digest", DIGEST_NAME, 0);
214 params[1] = OSSL_PARAM_construct_end();
215
216 if (ctx == NULL
217 || mac == NULL
218 || !EVP_MAC_init(ctx, hmac_kat_key, sizeof(hmac_kat_key), params)
219 || !EVP_MAC_update(ctx, hmac_kat_pt, sizeof(hmac_kat_pt))
220 || !EVP_MAC_final(ctx, out, &out_len, MAX_MD_SIZE))
221 goto err;
222
223 /* Optional corruption */
224 OSSL_SELF_TEST_oncorrupt_byte(ev, out);
225
226 if (out_len != sizeof(hmac_kat_digest)
227 || memcmp(out, hmac_kat_digest, out_len) != 0)
228 goto err;
229 ok = 1;
230 err:
231 OSSL_SELF_TEST_onend(ev, ok);
232 EVP_MAC_free(mac);
233 EVP_MAC_CTX_free(ctx);
234 return ok;
235 }
236
237 /*
238 * Calculate the HMAC SHA256 of data read using a BIO and read_cb, and verify
239 * the result matches the expected value.
240 * Return 1 if verified, or 0 if it fails.
241 */
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)242 static int verify_integrity(OSSL_CORE_BIO *bio, OSSL_FUNC_BIO_read_ex_fn read_ex_cb,
243 unsigned char *expected, size_t expected_len,
244 OSSL_LIB_CTX *libctx, OSSL_SELF_TEST *ev,
245 const char *event_type)
246 {
247 int ret = 0, status;
248 unsigned char out[MAX_MD_SIZE];
249 unsigned char buf[INTEGRITY_BUF_SIZE];
250 size_t bytes_read = 0, out_len = 0;
251 EVP_MAC *mac = NULL;
252 EVP_MAC_CTX *ctx = NULL;
253 OSSL_PARAM params[2], *p = params;
254
255 if (!integrity_self_test(ev, libctx))
256 goto err;
257
258 OSSL_SELF_TEST_onbegin(ev, event_type, OSSL_SELF_TEST_DESC_INTEGRITY_HMAC);
259
260 mac = EVP_MAC_fetch(libctx, MAC_NAME, NULL);
261 if (mac == NULL)
262 goto err;
263 ctx = EVP_MAC_CTX_new(mac);
264 if (ctx == NULL)
265 goto err;
266
267 *p++ = OSSL_PARAM_construct_utf8_string("digest", DIGEST_NAME, 0);
268 *p = OSSL_PARAM_construct_end();
269
270 if (!EVP_MAC_init(ctx, fixed_key, sizeof(fixed_key), params))
271 goto err;
272
273 while (1) {
274 status = read_ex_cb(bio, buf, sizeof(buf), &bytes_read);
275 if (status != 1)
276 break;
277 if (!EVP_MAC_update(ctx, buf, bytes_read))
278 goto err;
279 }
280 if (!EVP_MAC_final(ctx, out, &out_len, sizeof(out)))
281 goto err;
282
283 OSSL_SELF_TEST_oncorrupt_byte(ev, out);
284 if (expected_len != out_len
285 || memcmp(expected, out, out_len) != 0)
286 goto err;
287 ret = 1;
288 err:
289 OSSL_SELF_TEST_onend(ev, ret);
290 EVP_MAC_CTX_free(ctx);
291 EVP_MAC_free(mac);
292 return ret;
293 }
294 #endif /* OPENSSL_NO_FIPS_POST */
295
set_fips_state(int state)296 static void set_fips_state(int state)
297 {
298 tsan_store(&FIPS_state, state);
299 }
300
301 /* 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)302 int SELF_TEST_post(SELF_TEST_POST_PARAMS *st, int on_demand_test)
303 {
304 int loclstate;
305 #if !defined(OPENSSL_NO_FIPS_POST)
306 int ok = 0;
307 long checksum_len;
308 OSSL_CORE_BIO *bio_module = NULL;
309 unsigned char *module_checksum = NULL;
310 OSSL_SELF_TEST *ev = NULL;
311 EVP_RAND *testrand = NULL;
312 EVP_RAND_CTX *rng;
313 #endif
314
315 if (!RUN_ONCE(&fips_self_test_init, do_fips_self_test_init))
316 return 0;
317
318 loclstate = tsan_load(&FIPS_state);
319
320 if (loclstate == FIPS_STATE_RUNNING) {
321 if (!on_demand_test)
322 return 1;
323 } else if (loclstate != FIPS_STATE_SELFTEST) {
324 ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_STATE);
325 return 0;
326 }
327
328 if (!CRYPTO_THREAD_write_lock(self_test_lock))
329 return 0;
330
331 #if !defined(OPENSSL_NO_FIPS_POST)
332 loclstate = tsan_load(&FIPS_state);
333 if (loclstate == FIPS_STATE_RUNNING) {
334 if (!on_demand_test) {
335 CRYPTO_THREAD_unlock(self_test_lock);
336 return 1;
337 }
338 set_fips_state(FIPS_STATE_SELFTEST);
339 } else if (loclstate != FIPS_STATE_SELFTEST) {
340 CRYPTO_THREAD_unlock(self_test_lock);
341 ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_STATE);
342 return 0;
343 }
344
345 if (st == NULL
346 || st->module_checksum_data == NULL) {
347 ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_CONFIG_DATA);
348 goto end;
349 }
350
351 ev = OSSL_SELF_TEST_new(st->cb, st->cb_arg);
352 if (ev == NULL)
353 goto end;
354
355 module_checksum = OPENSSL_hexstr2buf(st->module_checksum_data,
356 &checksum_len);
357 if (module_checksum == NULL) {
358 ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_CONFIG_DATA);
359 goto end;
360 }
361 bio_module = (*st->bio_new_file_cb)(st->module_filename, "rb");
362
363 /* Always check the integrity of the fips module */
364 if (bio_module == NULL
365 || !verify_integrity(bio_module, st->bio_read_ex_cb,
366 module_checksum, checksum_len, st->libctx,
367 ev, OSSL_SELF_TEST_TYPE_MODULE_INTEGRITY)) {
368 ERR_raise(ERR_LIB_PROV, PROV_R_MODULE_INTEGRITY_FAILURE);
369 goto end;
370 }
371
372 if (!SELF_TEST_kats(ev, st->libctx)) {
373 ERR_raise(ERR_LIB_PROV, PROV_R_SELF_TEST_KAT_FAILURE);
374 goto end;
375 }
376
377 /* Verify that the RNG has been restored properly */
378 rng = ossl_rand_get0_private_noncreating(st->libctx);
379 if (rng != NULL)
380 if ((testrand = EVP_RAND_fetch(st->libctx, "TEST-RAND", NULL)) == NULL
381 || strcmp(EVP_RAND_get0_name(EVP_RAND_CTX_get0_rand(rng)),
382 EVP_RAND_get0_name(testrand)) == 0) {
383 ERR_raise(ERR_LIB_PROV, PROV_R_SELF_TEST_KAT_FAILURE);
384 goto end;
385 }
386
387 ok = 1;
388 end:
389 EVP_RAND_free(testrand);
390 OSSL_SELF_TEST_free(ev);
391 OPENSSL_free(module_checksum);
392
393 if (st != NULL)
394 (*st->bio_free_cb)(bio_module);
395
396 if (ok)
397 set_fips_state(FIPS_STATE_RUNNING);
398 else
399 ossl_set_error_state(OSSL_SELF_TEST_TYPE_NONE);
400 CRYPTO_THREAD_unlock(self_test_lock);
401
402 return ok;
403 #else
404 set_fips_state(FIPS_STATE_RUNNING);
405 CRYPTO_THREAD_unlock(self_test_lock);
406 return 1;
407 #endif /* !defined(OPENSSL_NO_FIPS_POST) */
408 }
409
SELF_TEST_disable_conditional_error_state(void)410 void SELF_TEST_disable_conditional_error_state(void)
411 {
412 FIPS_conditional_error_check = 0;
413 }
414
ossl_set_error_state(const char * type)415 void ossl_set_error_state(const char *type)
416 {
417 int cond_test = (type != NULL && strcmp(type, OSSL_SELF_TEST_TYPE_PCT) == 0);
418
419 if (!cond_test || (FIPS_conditional_error_check == 1)) {
420 set_fips_state(FIPS_STATE_ERROR);
421 ERR_raise(ERR_LIB_PROV, PROV_R_FIPS_MODULE_ENTERING_ERROR_STATE);
422 } else {
423 ERR_raise(ERR_LIB_PROV, PROV_R_FIPS_MODULE_CONDITIONAL_ERROR);
424 }
425 }
426
ossl_prov_is_running(void)427 int ossl_prov_is_running(void)
428 {
429 int res, loclstate;
430 static TSAN_QUALIFIER unsigned int rate_limit = 0;
431
432 loclstate = tsan_load(&FIPS_state);
433 res = loclstate == FIPS_STATE_RUNNING || loclstate == FIPS_STATE_SELFTEST;
434 if (loclstate == FIPS_STATE_ERROR)
435 if (tsan_counter(&rate_limit) < FIPS_ERROR_REPORTING_RATE_LIMIT)
436 ERR_raise(ERR_LIB_PROV, PROV_R_FIPS_MODULE_IN_ERROR_STATE);
437 return res;
438 }
439