fipsinstall.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670
  1. /*
  2. * Copyright 2019-2023 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. #include <string.h>
  10. #include <openssl/evp.h>
  11. #include <openssl/err.h>
  12. #include <openssl/provider.h>
  13. #include <openssl/params.h>
  14. #include <openssl/fips_names.h>
  15. #include <openssl/core_names.h>
  16. #include <openssl/self_test.h>
  17. #include <openssl/fipskey.h>
  18. #include "apps.h"
  19. #include "progs.h"
  20. #define BUFSIZE 4096
  21. /* Configuration file values */
  22. #define VERSION_KEY "version"
  23. #define VERSION_VAL "1"
  24. #define INSTALL_STATUS_VAL "INSTALL_SELF_TEST_KATS_RUN"
  25. static OSSL_CALLBACK self_test_events;
  26. static char *self_test_corrupt_desc = NULL;
  27. static char *self_test_corrupt_type = NULL;
  28. static int self_test_log = 1;
  29. static int quiet = 0;
  30. typedef enum OPTION_choice {
  31. OPT_COMMON,
  32. OPT_IN, OPT_OUT, OPT_MODULE, OPT_PEDANTIC,
  33. OPT_PROV_NAME, OPT_SECTION_NAME, OPT_MAC_NAME, OPT_MACOPT, OPT_VERIFY,
  34. OPT_NO_LOG, OPT_CORRUPT_DESC, OPT_CORRUPT_TYPE, OPT_QUIET, OPT_CONFIG,
  35. OPT_NO_CONDITIONAL_ERRORS,
  36. OPT_NO_SECURITY_CHECKS,
  37. OPT_TLS_PRF_EMS_CHECK,
  38. OPT_DISALLOW_DRGB_TRUNC_DIGEST,
  39. OPT_SELF_TEST_ONLOAD, OPT_SELF_TEST_ONINSTALL
  40. } OPTION_CHOICE;
  41. const OPTIONS fipsinstall_options[] = {
  42. OPT_SECTION("General"),
  43. {"help", OPT_HELP, '-', "Display this summary"},
  44. {"pedantic", OPT_PEDANTIC, '-', "Set options for strict FIPS compliance"},
  45. {"verify", OPT_VERIFY, '-',
  46. "Verify a config file instead of generating one"},
  47. {"module", OPT_MODULE, '<', "File name of the provider module"},
  48. {"provider_name", OPT_PROV_NAME, 's', "FIPS provider name"},
  49. {"section_name", OPT_SECTION_NAME, 's',
  50. "FIPS Provider config section name (optional)"},
  51. {"no_conditional_errors", OPT_NO_CONDITIONAL_ERRORS, '-',
  52. "Disable the ability of the fips module to enter an error state if"
  53. " any conditional self tests fail"},
  54. {"no_security_checks", OPT_NO_SECURITY_CHECKS, '-',
  55. "Disable the run-time FIPS security checks in the module"},
  56. {"self_test_onload", OPT_SELF_TEST_ONLOAD, '-',
  57. "Forces self tests to always run on module load"},
  58. {"self_test_oninstall", OPT_SELF_TEST_ONINSTALL, '-',
  59. "Forces self tests to run once on module installation"},
  60. {"ems_check", OPT_TLS_PRF_EMS_CHECK, '-',
  61. "Enable the run-time FIPS check for EMS during TLS1_PRF"},
  62. {"no_drbg_truncated_digests", OPT_DISALLOW_DRGB_TRUNC_DIGEST, '-',
  63. "Disallow truncated digests with Hash and HMAC DRBGs"},
  64. OPT_SECTION("Input"),
  65. {"in", OPT_IN, '<', "Input config file, used when verifying"},
  66. OPT_SECTION("Output"),
  67. {"out", OPT_OUT, '>', "Output config file, used when generating"},
  68. {"mac_name", OPT_MAC_NAME, 's', "MAC name"},
  69. {"macopt", OPT_MACOPT, 's', "MAC algorithm parameters in n:v form."},
  70. {OPT_MORE_STR, 0, 0, "See 'PARAMETER NAMES' in the EVP_MAC_ docs"},
  71. {"noout", OPT_NO_LOG, '-', "Disable logging of self test events"},
  72. {"corrupt_desc", OPT_CORRUPT_DESC, 's', "Corrupt a self test by description"},
  73. {"corrupt_type", OPT_CORRUPT_TYPE, 's', "Corrupt a self test by type"},
  74. {"config", OPT_CONFIG, '<', "The parent config to verify"},
  75. {"quiet", OPT_QUIET, '-', "No messages, just exit status"},
  76. {NULL}
  77. };
  78. typedef struct {
  79. unsigned int self_test_onload : 1;
  80. unsigned int conditional_errors : 1;
  81. unsigned int security_checks : 1;
  82. unsigned int tls_prf_ems_check : 1;
  83. unsigned int drgb_no_trunc_dgst : 1;
  84. } FIPS_OPTS;
  85. /* Pedantic FIPS compliance */
  86. static const FIPS_OPTS pedantic_opts = {
  87. 1, /* self_test_onload */
  88. 1, /* conditional_errors */
  89. 1, /* security_checks */
  90. 1, /* tls_prf_ems_check */
  91. 1, /* drgb_no_trunc_dgst */
  92. };
  93. /* Default FIPS settings for backward compatibility */
  94. static FIPS_OPTS fips_opts = {
  95. 1, /* self_test_onload */
  96. 1, /* conditional_errors */
  97. 1, /* security_checks */
  98. 0, /* tls_prf_ems_check */
  99. 0, /* drgb_no_trunc_dgst */
  100. };
  101. static int check_non_pedantic_fips(int pedantic, const char *name)
  102. {
  103. if (pedantic) {
  104. BIO_printf(bio_err, "Cannot specify -%s after -pedantic\n", name);
  105. return 0;
  106. }
  107. return 1;
  108. }
  109. static int do_mac(EVP_MAC_CTX *ctx, unsigned char *tmp, BIO *in,
  110. unsigned char *out, size_t *out_len)
  111. {
  112. int ret = 0;
  113. int i;
  114. size_t outsz = *out_len;
  115. if (!EVP_MAC_init(ctx, NULL, 0, NULL))
  116. goto err;
  117. if (EVP_MAC_CTX_get_mac_size(ctx) > outsz)
  118. goto end;
  119. while ((i = BIO_read(in, (char *)tmp, BUFSIZE)) != 0) {
  120. if (i < 0 || !EVP_MAC_update(ctx, tmp, i))
  121. goto err;
  122. }
  123. end:
  124. if (!EVP_MAC_final(ctx, out, out_len, outsz))
  125. goto err;
  126. ret = 1;
  127. err:
  128. return ret;
  129. }
  130. static int load_fips_prov_and_run_self_test(const char *prov_name)
  131. {
  132. int ret = 0;
  133. OSSL_PROVIDER *prov = NULL;
  134. OSSL_PARAM params[4], *p = params;
  135. char *name = "", *vers = "", *build = "";
  136. prov = OSSL_PROVIDER_load(NULL, prov_name);
  137. if (prov == NULL) {
  138. BIO_printf(bio_err, "Failed to load FIPS module\n");
  139. goto end;
  140. }
  141. if (!quiet) {
  142. *p++ = OSSL_PARAM_construct_utf8_ptr(OSSL_PROV_PARAM_NAME,
  143. &name, sizeof(name));
  144. *p++ = OSSL_PARAM_construct_utf8_ptr(OSSL_PROV_PARAM_VERSION,
  145. &vers, sizeof(vers));
  146. *p++ = OSSL_PARAM_construct_utf8_ptr(OSSL_PROV_PARAM_BUILDINFO,
  147. &build, sizeof(build));
  148. *p = OSSL_PARAM_construct_end();
  149. if (!OSSL_PROVIDER_get_params(prov, params)) {
  150. BIO_printf(bio_err, "Failed to query FIPS module parameters\n");
  151. goto end;
  152. }
  153. if (OSSL_PARAM_modified(params))
  154. BIO_printf(bio_err, "\t%-10s\t%s\n", "name:", name);
  155. if (OSSL_PARAM_modified(params + 1))
  156. BIO_printf(bio_err, "\t%-10s\t%s\n", "version:", vers);
  157. if (OSSL_PARAM_modified(params + 2))
  158. BIO_printf(bio_err, "\t%-10s\t%s\n", "build:", build);
  159. }
  160. ret = 1;
  161. end:
  162. OSSL_PROVIDER_unload(prov);
  163. return ret;
  164. }
  165. static int print_mac(BIO *bio, const char *label, const unsigned char *mac,
  166. size_t len)
  167. {
  168. int ret;
  169. char *hexstr = NULL;
  170. hexstr = OPENSSL_buf2hexstr(mac, (long)len);
  171. if (hexstr == NULL)
  172. return 0;
  173. ret = BIO_printf(bio, "%s = %s\n", label, hexstr);
  174. OPENSSL_free(hexstr);
  175. return ret;
  176. }
  177. static int write_config_header(BIO *out, const char *prov_name,
  178. const char *section)
  179. {
  180. return BIO_printf(out, "openssl_conf = openssl_init\n\n")
  181. && BIO_printf(out, "[openssl_init]\n")
  182. && BIO_printf(out, "providers = provider_section\n\n")
  183. && BIO_printf(out, "[provider_section]\n")
  184. && BIO_printf(out, "%s = %s\n\n", prov_name, section);
  185. }
  186. /*
  187. * Outputs a fips related config file that contains entries for the fips
  188. * module checksum, installation indicator checksum and the options
  189. * conditional_errors and security_checks.
  190. *
  191. * Returns 1 if the config file is written otherwise it returns 0 on error.
  192. */
  193. static int write_config_fips_section(BIO *out, const char *section,
  194. unsigned char *module_mac,
  195. size_t module_mac_len,
  196. const FIPS_OPTS *opts,
  197. unsigned char *install_mac,
  198. size_t install_mac_len)
  199. {
  200. int ret = 0;
  201. if (BIO_printf(out, "[%s]\n", section) <= 0
  202. || BIO_printf(out, "activate = 1\n") <= 0
  203. || BIO_printf(out, "%s = %s\n", OSSL_PROV_FIPS_PARAM_INSTALL_VERSION,
  204. VERSION_VAL) <= 0
  205. || BIO_printf(out, "%s = %s\n", OSSL_PROV_FIPS_PARAM_CONDITIONAL_ERRORS,
  206. opts->conditional_errors ? "1" : "0") <= 0
  207. || BIO_printf(out, "%s = %s\n", OSSL_PROV_FIPS_PARAM_SECURITY_CHECKS,
  208. opts->security_checks ? "1" : "0") <= 0
  209. || BIO_printf(out, "%s = %s\n", OSSL_PROV_FIPS_PARAM_TLS1_PRF_EMS_CHECK,
  210. opts->tls_prf_ems_check ? "1" : "0") <= 0
  211. || BIO_printf(out, "%s = %s\n", OSSL_PROV_PARAM_DRBG_TRUNC_DIGEST,
  212. opts->drgb_no_trunc_dgst ? "1" : "0") <= 0
  213. || !print_mac(out, OSSL_PROV_FIPS_PARAM_MODULE_MAC, module_mac,
  214. module_mac_len))
  215. goto end;
  216. if (install_mac != NULL && install_mac_len > 0) {
  217. if (!print_mac(out, OSSL_PROV_FIPS_PARAM_INSTALL_MAC, install_mac,
  218. install_mac_len)
  219. || BIO_printf(out, "%s = %s\n", OSSL_PROV_FIPS_PARAM_INSTALL_STATUS,
  220. INSTALL_STATUS_VAL) <= 0)
  221. goto end;
  222. }
  223. ret = 1;
  224. end:
  225. return ret;
  226. }
  227. static CONF *generate_config_and_load(const char *prov_name,
  228. const char *section,
  229. unsigned char *module_mac,
  230. size_t module_mac_len,
  231. const FIPS_OPTS *opts)
  232. {
  233. BIO *mem_bio = NULL;
  234. CONF *conf = NULL;
  235. mem_bio = BIO_new(BIO_s_mem());
  236. if (mem_bio == NULL)
  237. return 0;
  238. if (!write_config_header(mem_bio, prov_name, section)
  239. || !write_config_fips_section(mem_bio, section,
  240. module_mac, module_mac_len,
  241. opts, NULL, 0))
  242. goto end;
  243. conf = app_load_config_bio(mem_bio, NULL);
  244. if (conf == NULL)
  245. goto end;
  246. if (CONF_modules_load(conf, NULL, 0) <= 0)
  247. goto end;
  248. BIO_free(mem_bio);
  249. return conf;
  250. end:
  251. NCONF_free(conf);
  252. BIO_free(mem_bio);
  253. return NULL;
  254. }
  255. static void free_config_and_unload(CONF *conf)
  256. {
  257. if (conf != NULL) {
  258. NCONF_free(conf);
  259. CONF_modules_unload(1);
  260. }
  261. }
  262. static int verify_module_load(const char *parent_config_file)
  263. {
  264. return OSSL_LIB_CTX_load_config(NULL, parent_config_file);
  265. }
  266. /*
  267. * Returns 1 if the config file entries match the passed in module_mac and
  268. * install_mac values, otherwise it returns 0.
  269. */
  270. static int verify_config(const char *infile, const char *section,
  271. unsigned char *module_mac, size_t module_mac_len,
  272. unsigned char *install_mac, size_t install_mac_len)
  273. {
  274. int ret = 0;
  275. char *s = NULL;
  276. unsigned char *buf1 = NULL, *buf2 = NULL;
  277. long len;
  278. CONF *conf = NULL;
  279. /* read in the existing values and check they match the saved values */
  280. conf = app_load_config(infile);
  281. if (conf == NULL)
  282. goto end;
  283. s = NCONF_get_string(conf, section, OSSL_PROV_FIPS_PARAM_INSTALL_VERSION);
  284. if (s == NULL || strcmp(s, VERSION_VAL) != 0) {
  285. BIO_printf(bio_err, "version not found\n");
  286. goto end;
  287. }
  288. s = NCONF_get_string(conf, section, OSSL_PROV_FIPS_PARAM_MODULE_MAC);
  289. if (s == NULL) {
  290. BIO_printf(bio_err, "Module integrity MAC not found\n");
  291. goto end;
  292. }
  293. buf1 = OPENSSL_hexstr2buf(s, &len);
  294. if (buf1 == NULL
  295. || (size_t)len != module_mac_len
  296. || memcmp(module_mac, buf1, module_mac_len) != 0) {
  297. BIO_printf(bio_err, "Module integrity mismatch\n");
  298. goto end;
  299. }
  300. if (install_mac != NULL && install_mac_len > 0) {
  301. s = NCONF_get_string(conf, section, OSSL_PROV_FIPS_PARAM_INSTALL_STATUS);
  302. if (s == NULL || strcmp(s, INSTALL_STATUS_VAL) != 0) {
  303. BIO_printf(bio_err, "install status not found\n");
  304. goto end;
  305. }
  306. s = NCONF_get_string(conf, section, OSSL_PROV_FIPS_PARAM_INSTALL_MAC);
  307. if (s == NULL) {
  308. BIO_printf(bio_err, "Install indicator MAC not found\n");
  309. goto end;
  310. }
  311. buf2 = OPENSSL_hexstr2buf(s, &len);
  312. if (buf2 == NULL
  313. || (size_t)len != install_mac_len
  314. || memcmp(install_mac, buf2, install_mac_len) != 0) {
  315. BIO_printf(bio_err, "Install indicator status mismatch\n");
  316. goto end;
  317. }
  318. }
  319. ret = 1;
  320. end:
  321. OPENSSL_free(buf1);
  322. OPENSSL_free(buf2);
  323. NCONF_free(conf);
  324. return ret;
  325. }
  326. int fipsinstall_main(int argc, char **argv)
  327. {
  328. int ret = 1, verify = 0, gotkey = 0, gotdigest = 0, pedantic = 0;
  329. const char *section_name = "fips_sect";
  330. const char *mac_name = "HMAC";
  331. const char *prov_name = "fips";
  332. BIO *module_bio = NULL, *mem_bio = NULL, *fout = NULL;
  333. char *in_fname = NULL, *out_fname = NULL, *prog;
  334. char *module_fname = NULL, *parent_config = NULL, *module_path = NULL;
  335. const char *tail;
  336. EVP_MAC_CTX *ctx = NULL, *ctx2 = NULL;
  337. STACK_OF(OPENSSL_STRING) *opts = NULL;
  338. OPTION_CHOICE o;
  339. unsigned char *read_buffer = NULL;
  340. unsigned char module_mac[EVP_MAX_MD_SIZE];
  341. size_t module_mac_len = EVP_MAX_MD_SIZE;
  342. unsigned char install_mac[EVP_MAX_MD_SIZE];
  343. size_t install_mac_len = EVP_MAX_MD_SIZE;
  344. EVP_MAC *mac = NULL;
  345. CONF *conf = NULL;
  346. if ((opts = sk_OPENSSL_STRING_new_null()) == NULL)
  347. goto end;
  348. prog = opt_init(argc, argv, fipsinstall_options);
  349. while ((o = opt_next()) != OPT_EOF) {
  350. switch (o) {
  351. case OPT_EOF:
  352. case OPT_ERR:
  353. opthelp:
  354. BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
  355. goto cleanup;
  356. case OPT_HELP:
  357. opt_help(fipsinstall_options);
  358. ret = 0;
  359. goto end;
  360. case OPT_IN:
  361. in_fname = opt_arg();
  362. break;
  363. case OPT_OUT:
  364. out_fname = opt_arg();
  365. break;
  366. case OPT_PEDANTIC:
  367. fips_opts = pedantic_opts;
  368. pedantic = 1;
  369. break;
  370. case OPT_NO_CONDITIONAL_ERRORS:
  371. if (!check_non_pedantic_fips(pedantic, "no_conditional_errors"))
  372. goto end;
  373. fips_opts.conditional_errors = 0;
  374. break;
  375. case OPT_NO_SECURITY_CHECKS:
  376. if (!check_non_pedantic_fips(pedantic, "no_security_checks"))
  377. goto end;
  378. fips_opts.security_checks = 0;
  379. break;
  380. case OPT_TLS_PRF_EMS_CHECK:
  381. fips_opts.tls_prf_ems_check = 1;
  382. break;
  383. case OPT_DISALLOW_DRGB_TRUNC_DIGEST:
  384. fips_opts.drgb_no_trunc_dgst = 1;
  385. break;
  386. case OPT_QUIET:
  387. quiet = 1;
  388. /* FALLTHROUGH */
  389. case OPT_NO_LOG:
  390. self_test_log = 0;
  391. break;
  392. case OPT_CORRUPT_DESC:
  393. self_test_corrupt_desc = opt_arg();
  394. break;
  395. case OPT_CORRUPT_TYPE:
  396. self_test_corrupt_type = opt_arg();
  397. break;
  398. case OPT_PROV_NAME:
  399. prov_name = opt_arg();
  400. break;
  401. case OPT_MODULE:
  402. module_fname = opt_arg();
  403. break;
  404. case OPT_SECTION_NAME:
  405. section_name = opt_arg();
  406. break;
  407. case OPT_MAC_NAME:
  408. mac_name = opt_arg();
  409. break;
  410. case OPT_CONFIG:
  411. parent_config = opt_arg();
  412. break;
  413. case OPT_MACOPT:
  414. if (!sk_OPENSSL_STRING_push(opts, opt_arg()))
  415. goto opthelp;
  416. if (strncmp(opt_arg(), "hexkey:", 7) == 0)
  417. gotkey = 1;
  418. else if (strncmp(opt_arg(), "digest:", 7) == 0)
  419. gotdigest = 1;
  420. break;
  421. case OPT_VERIFY:
  422. verify = 1;
  423. break;
  424. case OPT_SELF_TEST_ONLOAD:
  425. fips_opts.self_test_onload = 1;
  426. break;
  427. case OPT_SELF_TEST_ONINSTALL:
  428. if (!check_non_pedantic_fips(pedantic, "self_test_oninstall"))
  429. goto end;
  430. fips_opts.self_test_onload = 0;
  431. break;
  432. }
  433. }
  434. /* No extra arguments. */
  435. argc = opt_num_rest();
  436. if (argc != 0 || (verify && in_fname == NULL))
  437. goto opthelp;
  438. if (parent_config != NULL) {
  439. /* Test that a parent config can load the module */
  440. if (verify_module_load(parent_config)) {
  441. ret = OSSL_PROVIDER_available(NULL, prov_name) ? 0 : 1;
  442. if (!quiet) {
  443. BIO_printf(bio_err, "FIPS provider is %s\n",
  444. ret == 0 ? "available" : " not available");
  445. }
  446. }
  447. goto end;
  448. }
  449. if (module_fname == NULL)
  450. goto opthelp;
  451. tail = opt_path_end(module_fname);
  452. if (tail != NULL) {
  453. module_path = OPENSSL_strdup(module_fname);
  454. if (module_path == NULL)
  455. goto end;
  456. module_path[tail - module_fname] = '\0';
  457. if (!OSSL_PROVIDER_set_default_search_path(NULL, module_path))
  458. goto end;
  459. }
  460. if (self_test_log
  461. || self_test_corrupt_desc != NULL
  462. || self_test_corrupt_type != NULL)
  463. OSSL_SELF_TEST_set_callback(NULL, self_test_events, NULL);
  464. /* Use the default FIPS HMAC digest and key if not specified. */
  465. if (!gotdigest && !sk_OPENSSL_STRING_push(opts, "digest:SHA256"))
  466. goto end;
  467. if (!gotkey && !sk_OPENSSL_STRING_push(opts, "hexkey:" FIPS_KEY_STRING))
  468. goto end;
  469. module_bio = bio_open_default(module_fname, 'r', FORMAT_BINARY);
  470. if (module_bio == NULL) {
  471. BIO_printf(bio_err, "Failed to open module file\n");
  472. goto end;
  473. }
  474. read_buffer = app_malloc(BUFSIZE, "I/O buffer");
  475. if (read_buffer == NULL)
  476. goto end;
  477. mac = EVP_MAC_fetch(app_get0_libctx(), mac_name, app_get0_propq());
  478. if (mac == NULL) {
  479. BIO_printf(bio_err, "Unable to get MAC of type %s\n", mac_name);
  480. goto end;
  481. }
  482. ctx = EVP_MAC_CTX_new(mac);
  483. if (ctx == NULL) {
  484. BIO_printf(bio_err, "Unable to create MAC CTX for module check\n");
  485. goto end;
  486. }
  487. if (opts != NULL) {
  488. int ok = 1;
  489. OSSL_PARAM *params =
  490. app_params_new_from_opts(opts, EVP_MAC_settable_ctx_params(mac));
  491. if (params == NULL)
  492. goto end;
  493. if (!EVP_MAC_CTX_set_params(ctx, params)) {
  494. BIO_printf(bio_err, "MAC parameter error\n");
  495. ERR_print_errors(bio_err);
  496. ok = 0;
  497. }
  498. app_params_free(params);
  499. if (!ok)
  500. goto end;
  501. }
  502. ctx2 = EVP_MAC_CTX_dup(ctx);
  503. if (ctx2 == NULL) {
  504. BIO_printf(bio_err, "Unable to create MAC CTX for install indicator\n");
  505. goto end;
  506. }
  507. if (!do_mac(ctx, read_buffer, module_bio, module_mac, &module_mac_len))
  508. goto end;
  509. if (fips_opts.self_test_onload == 0) {
  510. mem_bio = BIO_new_mem_buf((const void *)INSTALL_STATUS_VAL,
  511. strlen(INSTALL_STATUS_VAL));
  512. if (mem_bio == NULL) {
  513. BIO_printf(bio_err, "Unable to create memory BIO\n");
  514. goto end;
  515. }
  516. if (!do_mac(ctx2, read_buffer, mem_bio, install_mac, &install_mac_len))
  517. goto end;
  518. } else {
  519. install_mac_len = 0;
  520. }
  521. if (verify) {
  522. if (!verify_config(in_fname, section_name, module_mac, module_mac_len,
  523. install_mac, install_mac_len))
  524. goto end;
  525. if (!quiet)
  526. BIO_printf(bio_err, "VERIFY PASSED\n");
  527. } else {
  528. conf = generate_config_and_load(prov_name, section_name, module_mac,
  529. module_mac_len, &fips_opts);
  530. if (conf == NULL)
  531. goto end;
  532. if (!load_fips_prov_and_run_self_test(prov_name))
  533. goto end;
  534. fout =
  535. out_fname == NULL ? dup_bio_out(FORMAT_TEXT)
  536. : bio_open_default(out_fname, 'w', FORMAT_TEXT);
  537. if (fout == NULL) {
  538. BIO_printf(bio_err, "Failed to open file\n");
  539. goto end;
  540. }
  541. if (!write_config_fips_section(fout, section_name,
  542. module_mac, module_mac_len, &fips_opts,
  543. install_mac, install_mac_len))
  544. goto end;
  545. if (!quiet)
  546. BIO_printf(bio_err, "INSTALL PASSED\n");
  547. }
  548. ret = 0;
  549. end:
  550. if (ret == 1) {
  551. if (!quiet)
  552. BIO_printf(bio_err, "%s FAILED\n", verify ? "VERIFY" : "INSTALL");
  553. ERR_print_errors(bio_err);
  554. }
  555. cleanup:
  556. OPENSSL_free(module_path);
  557. BIO_free(fout);
  558. BIO_free(mem_bio);
  559. BIO_free(module_bio);
  560. sk_OPENSSL_STRING_free(opts);
  561. EVP_MAC_free(mac);
  562. EVP_MAC_CTX_free(ctx2);
  563. EVP_MAC_CTX_free(ctx);
  564. OPENSSL_free(read_buffer);
  565. free_config_and_unload(conf);
  566. return ret;
  567. }
  568. static int self_test_events(const OSSL_PARAM params[], void *arg)
  569. {
  570. const OSSL_PARAM *p = NULL;
  571. const char *phase = NULL, *type = NULL, *desc = NULL;
  572. int ret = 0;
  573. p = OSSL_PARAM_locate_const(params, OSSL_PROV_PARAM_SELF_TEST_PHASE);
  574. if (p == NULL || p->data_type != OSSL_PARAM_UTF8_STRING)
  575. goto err;
  576. phase = (const char *)p->data;
  577. p = OSSL_PARAM_locate_const(params, OSSL_PROV_PARAM_SELF_TEST_DESC);
  578. if (p == NULL || p->data_type != OSSL_PARAM_UTF8_STRING)
  579. goto err;
  580. desc = (const char *)p->data;
  581. p = OSSL_PARAM_locate_const(params, OSSL_PROV_PARAM_SELF_TEST_TYPE);
  582. if (p == NULL || p->data_type != OSSL_PARAM_UTF8_STRING)
  583. goto err;
  584. type = (const char *)p->data;
  585. if (self_test_log) {
  586. if (strcmp(phase, OSSL_SELF_TEST_PHASE_START) == 0)
  587. BIO_printf(bio_err, "%s : (%s) : ", desc, type);
  588. else if (strcmp(phase, OSSL_SELF_TEST_PHASE_PASS) == 0
  589. || strcmp(phase, OSSL_SELF_TEST_PHASE_FAIL) == 0)
  590. BIO_printf(bio_err, "%s\n", phase);
  591. }
  592. /*
  593. * The self test code will internally corrupt the KAT test result if an
  594. * error is returned during the corrupt phase.
  595. */
  596. if (strcmp(phase, OSSL_SELF_TEST_PHASE_CORRUPT) == 0
  597. && (self_test_corrupt_desc != NULL
  598. || self_test_corrupt_type != NULL)) {
  599. if (self_test_corrupt_desc != NULL
  600. && strcmp(self_test_corrupt_desc, desc) != 0)
  601. goto end;
  602. if (self_test_corrupt_type != NULL
  603. && strcmp(self_test_corrupt_type, type) != 0)
  604. goto end;
  605. BIO_printf(bio_err, "%s ", phase);
  606. goto err;
  607. }
  608. end:
  609. ret = 1;
  610. err:
  611. return ret;
  612. }