xref: /openssl/providers/fips/self_test.c (revision 7ed6de99)
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