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 # ifdef OPENSSL_PEDANTIC_ZEROIZATION
293 OPENSSL_cleanse(out, sizeof(out));
294 # endif
295 return ret;
296 }
297 #endif /* OPENSSL_NO_FIPS_POST */
298
set_fips_state(int state)299 static void set_fips_state(int state)
300 {
301 tsan_store(&FIPS_state, state);
302 }
303
304 /* 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)305 int SELF_TEST_post(SELF_TEST_POST_PARAMS *st, int on_demand_test)
306 {
307 int loclstate;
308 #if !defined(OPENSSL_NO_FIPS_POST)
309 int ok = 0;
310 long checksum_len;
311 OSSL_CORE_BIO *bio_module = NULL;
312 unsigned char *module_checksum = NULL;
313 OSSL_SELF_TEST *ev = NULL;
314 EVP_RAND *testrand = NULL;
315 EVP_RAND_CTX *rng;
316 #endif
317
318 if (!RUN_ONCE(&fips_self_test_init, do_fips_self_test_init))
319 return 0;
320
321 loclstate = tsan_load(&FIPS_state);
322
323 if (loclstate == FIPS_STATE_RUNNING) {
324 if (!on_demand_test)
325 return 1;
326 } else if (loclstate != FIPS_STATE_SELFTEST) {
327 ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_STATE);
328 return 0;
329 }
330
331 if (!CRYPTO_THREAD_write_lock(self_test_lock))
332 return 0;
333
334 #if !defined(OPENSSL_NO_FIPS_POST)
335 loclstate = tsan_load(&FIPS_state);
336 if (loclstate == FIPS_STATE_RUNNING) {
337 if (!on_demand_test) {
338 CRYPTO_THREAD_unlock(self_test_lock);
339 return 1;
340 }
341 set_fips_state(FIPS_STATE_SELFTEST);
342 } else if (loclstate != FIPS_STATE_SELFTEST) {
343 CRYPTO_THREAD_unlock(self_test_lock);
344 ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_STATE);
345 return 0;
346 }
347
348 if (st == NULL
349 || st->module_checksum_data == NULL) {
350 ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_CONFIG_DATA);
351 goto end;
352 }
353
354 ev = OSSL_SELF_TEST_new(st->cb, st->cb_arg);
355 if (ev == NULL)
356 goto end;
357
358 module_checksum = OPENSSL_hexstr2buf(st->module_checksum_data,
359 &checksum_len);
360 if (module_checksum == NULL) {
361 ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_CONFIG_DATA);
362 goto end;
363 }
364 bio_module = (*st->bio_new_file_cb)(st->module_filename, "rb");
365
366 /* Always check the integrity of the fips module */
367 if (bio_module == NULL
368 || !verify_integrity(bio_module, st->bio_read_ex_cb,
369 module_checksum, checksum_len, st->libctx,
370 ev, OSSL_SELF_TEST_TYPE_MODULE_INTEGRITY)) {
371 ERR_raise(ERR_LIB_PROV, PROV_R_MODULE_INTEGRITY_FAILURE);
372 goto end;
373 }
374
375 if (!SELF_TEST_kats(ev, st->libctx)) {
376 ERR_raise(ERR_LIB_PROV, PROV_R_SELF_TEST_KAT_FAILURE);
377 goto end;
378 }
379
380 /* Verify that the RNG has been restored properly */
381 rng = ossl_rand_get0_private_noncreating(st->libctx);
382 if (rng != NULL)
383 if ((testrand = EVP_RAND_fetch(st->libctx, "TEST-RAND", NULL)) == NULL
384 || strcmp(EVP_RAND_get0_name(EVP_RAND_CTX_get0_rand(rng)),
385 EVP_RAND_get0_name(testrand)) == 0) {
386 ERR_raise(ERR_LIB_PROV, PROV_R_SELF_TEST_KAT_FAILURE);
387 goto end;
388 }
389
390 ok = 1;
391 end:
392 EVP_RAND_free(testrand);
393 OSSL_SELF_TEST_free(ev);
394 OPENSSL_free(module_checksum);
395
396 if (st != NULL)
397 (*st->bio_free_cb)(bio_module);
398
399 if (ok)
400 set_fips_state(FIPS_STATE_RUNNING);
401 else
402 ossl_set_error_state(OSSL_SELF_TEST_TYPE_NONE);
403 CRYPTO_THREAD_unlock(self_test_lock);
404
405 return ok;
406 #else
407 set_fips_state(FIPS_STATE_RUNNING);
408 CRYPTO_THREAD_unlock(self_test_lock);
409 return 1;
410 #endif /* !defined(OPENSSL_NO_FIPS_POST) */
411 }
412
SELF_TEST_disable_conditional_error_state(void)413 void SELF_TEST_disable_conditional_error_state(void)
414 {
415 FIPS_conditional_error_check = 0;
416 }
417
ossl_set_error_state(const char * type)418 void ossl_set_error_state(const char *type)
419 {
420 int cond_test = (type != NULL && strcmp(type, OSSL_SELF_TEST_TYPE_PCT) == 0);
421
422 if (!cond_test || (FIPS_conditional_error_check == 1)) {
423 set_fips_state(FIPS_STATE_ERROR);
424 ERR_raise(ERR_LIB_PROV, PROV_R_FIPS_MODULE_ENTERING_ERROR_STATE);
425 } else {
426 ERR_raise(ERR_LIB_PROV, PROV_R_FIPS_MODULE_CONDITIONAL_ERROR);
427 }
428 }
429
ossl_prov_is_running(void)430 int ossl_prov_is_running(void)
431 {
432 int res, loclstate;
433 static TSAN_QUALIFIER unsigned int rate_limit = 0;
434
435 loclstate = tsan_load(&FIPS_state);
436 res = loclstate == FIPS_STATE_RUNNING || loclstate == FIPS_STATE_SELFTEST;
437 if (loclstate == FIPS_STATE_ERROR)
438 if (tsan_counter(&rate_limit) < FIPS_ERROR_REPORTING_RATE_LIMIT)
439 ERR_raise(ERR_LIB_PROV, PROV_R_FIPS_MODULE_IN_ERROR_STATE);
440 return res;
441 }
442