VirtualBox

source: vbox/trunk/src/libs/openssl-3.1.0/providers/fips/self_test.c@ 100111

Last change on this file since 100111 was 99366, checked in by vboxsync, 21 months ago

openssl-3.1.0: Applied and adjusted our OpenSSL changes to 3.0.7. bugref:10418

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

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette