Skip to content

Commit 1549425

Browse files
authored
Merge pull request #8873 from philljj/fix_fips_enabled
linuxkm: don't toggle fips_enabled.
2 parents 6cb0c85 + b6b58a9 commit 1549425

4 files changed

Lines changed: 151 additions & 61 deletions

File tree

.wolfssl_known_macro_extras

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,7 @@ LIBWOLFSSL_VERSION_GIT_HASH_DATE
294294
LIBWOLFSSL_VERSION_GIT_ORIGIN
295295
LIBWOLFSSL_VERSION_GIT_SHORT_HASH
296296
LIBWOLFSSL_VERSION_GIT_TAG
297+
LINUXKM_DONT_FORCE_FIPS_ENABLED
297298
LINUXKM_FPU_STATES_FOLLOW_THREADS
298299
LINUXKM_LKCAPI_PRIORITY_ALLOW_MASKING
299300
LINUX_CYCLE_COUNT

linuxkm/lkcapi_ecdh_glue.c

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -885,12 +885,23 @@ static int linuxkm_test_ecdh_nist_driver(const char * driver,
885885
*/
886886
tfm = crypto_alloc_kpp(driver, 0, 0);
887887
if (IS_ERR(tfm)) {
888-
pr_err("error: allocating kpp algorithm %s failed: %ld\n",
889-
driver, PTR_ERR(tfm));
890-
if (PTR_ERR(tfm) == -ENOMEM)
891-
test_rc = MEMORY_E;
888+
#if defined(HAVE_FIPS) && defined(CONFIG_CRYPTO_MANAGER) && \
889+
!defined(CONFIG_CRYPTO_MANAGER_DISABLE_TESTS)
890+
if ((PTR_ERR(tfm) == -ENOENT) && fips_enabled) {
891+
pr_info("info: skipping unsupported kpp algorithm %s: %ld\n",
892+
driver, PTR_ERR(tfm));
893+
test_rc = NOT_COMPILED_IN;
894+
}
892895
else
893-
test_rc = BAD_FUNC_ARG;
896+
#endif
897+
{
898+
pr_err("error: allocating kpp algorithm %s failed: %ld\n",
899+
driver, PTR_ERR(tfm));
900+
if (PTR_ERR(tfm) == -ENOMEM)
901+
test_rc = MEMORY_E;
902+
else
903+
test_rc = BAD_FUNC_ARG;
904+
}
894905
tfm = NULL;
895906
goto test_ecdh_nist_end;
896907
}

linuxkm/lkcapi_ecdsa_glue.c

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -727,12 +727,27 @@ static int linuxkm_test_ecdsa_nist_driver(const char * driver,
727727
*/
728728
tfm = crypto_alloc_akcipher(driver, 0, 0);
729729
if (IS_ERR(tfm)) {
730-
pr_err("error: allocating akcipher algorithm %s failed: %ld\n",
731-
driver, PTR_ERR(tfm));
732-
if (PTR_ERR(tfm) == -ENOMEM)
733-
test_rc = MEMORY_E;
730+
#if (LINUX_VERSION_CODE < KERNEL_VERSION(6, 3, 0)) && \
731+
defined(HAVE_FIPS) && defined(CONFIG_CRYPTO_MANAGER) && \
732+
!defined(CONFIG_CRYPTO_MANAGER_DISABLE_TESTS)
733+
/* ecdsa was not recognized as fips_allowed before linux v6.3
734+
* in kernel crypto/testmgr.c, and the kernel will block
735+
* its allocation if fips_enabled is set. */
736+
if ((PTR_ERR(tfm) == -ENOENT) && fips_enabled) {
737+
pr_info("info: skipping unsupported akcipher algorithm %s: %ld\n",
738+
driver, PTR_ERR(tfm));
739+
test_rc = NOT_COMPILED_IN;
740+
}
734741
else
735-
test_rc = BAD_FUNC_ARG;
742+
#endif
743+
{
744+
pr_err("error: allocating akcipher algorithm %s failed: %ld\n",
745+
driver, PTR_ERR(tfm));
746+
if (PTR_ERR(tfm) == -ENOMEM)
747+
test_rc = MEMORY_E;
748+
else
749+
test_rc = BAD_FUNC_ARG;
750+
}
736751
tfm = NULL;
737752
goto test_ecdsa_nist_end;
738753
}

linuxkm/lkcapi_glue.c

Lines changed: 114 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,11 @@ WC_MAYBE_UNUSED static int check_shash_driver_masking(struct crypto_shash *tfm,
222222
static int linuxkm_lkcapi_register(void);
223223
static int linuxkm_lkcapi_unregister(void);
224224

225+
#if defined(HAVE_FIPS) && defined(CONFIG_CRYPTO_MANAGER) && \
226+
!defined(CONFIG_CRYPTO_MANAGER_DISABLE_TESTS)
227+
static int enabled_fips = 0;
228+
#endif
229+
225230
static ssize_t install_algs_handler(struct kobject *kobj, struct kobj_attribute *attr,
226231
const char *buf, size_t count)
227232
{
@@ -261,6 +266,14 @@ static ssize_t deinstall_algs_handler(struct kobject *kobj, struct kobj_attribut
261266
if (ret != 0)
262267
return ret;
263268

269+
#if defined(HAVE_FIPS) && defined(CONFIG_CRYPTO_MANAGER) && \
270+
!defined(CONFIG_CRYPTO_MANAGER_DISABLE_TESTS)
271+
if (enabled_fips) {
272+
pr_info("wolfCrypt: restoring fips_enabled to off.");
273+
enabled_fips = fips_enabled = 0;
274+
}
275+
#endif
276+
264277
return count;
265278
}
266279

@@ -305,10 +318,6 @@ static int linuxkm_lkcapi_register(void)
305318
{
306319
int ret = -1;
307320
int seen_err = 0;
308-
#if defined(HAVE_FIPS) && defined(CONFIG_CRYPTO_MANAGER) && \
309-
!defined(CONFIG_CRYPTO_MANAGER_DISABLE_TESTS)
310-
int enabled_fips = 0;
311-
#endif
312321

313322
ret = linuxkm_lkcapi_sysfs_install();
314323
if (ret)
@@ -321,12 +330,14 @@ static int linuxkm_lkcapi_register(void)
321330
*/
322331
disable_setkey_warnings = 1;
323332
#endif
324-
#if defined(HAVE_FIPS) && defined(CONFIG_CRYPTO_MANAGER) && \
325-
!defined(CONFIG_CRYPTO_MANAGER_DISABLE_TESTS)
333+
#if !defined(LINUXKM_DONT_FORCE_FIPS_ENABLED) && \
334+
defined(HAVE_FIPS) && defined(CONFIG_CRYPTO_MANAGER) && \
335+
!defined(CONFIG_CRYPTO_MANAGER_DISABLE_TESTS)
326336
if (! fips_enabled) {
327-
/* temporarily assert system-wide FIPS status, to disable FIPS-forbidden
337+
/* assert system-wide FIPS status, to disable FIPS-forbidden
328338
* test vectors and fuzzing from the CRYPTO_MANAGER.
329339
*/
340+
pr_info("wolfCrypt: changing fips_enabled from 0 to 1 for FIPS module.");
330341
enabled_fips = fips_enabled = 1;
331342
}
332343
#endif
@@ -365,6 +376,59 @@ static int linuxkm_lkcapi_register(void)
365376
} \
366377
} while (0)
367378

379+
#if defined(HAVE_FIPS) && defined(CONFIG_CRYPTO_MANAGER) && \
380+
!defined(CONFIG_CRYPTO_MANAGER_DISABLE_TESTS)
381+
/* Same as above, but allow for option to skip problematic algs that are
382+
* not consistently labeled fips_allowed in crypto/testmgr.c, and hence
383+
* may be rejected by the kernel at runtime if is_fips is true. */
384+
#define REGISTER_ALG_OPTIONAL(alg, alg_class, tester) do {\
385+
if (! alg ## _loaded) { \
386+
ret = (crypto_register_ ## alg_class)(&(alg)); \
387+
if (ret) { \
388+
if (fips_enabled && (ret == WC_NO_ERR_TRACE(NOT_COMPILED_IN))) { \
389+
pr_info("wolfCrypt: skipping FIPS-incompatible alg %s.\n", \
390+
(alg).base.cra_driver_name); \
391+
} \
392+
else { \
393+
seen_err = ret; \
394+
pr_err("ERROR: crypto_register_" #alg_class \
395+
" for %s failed " \
396+
"with return code %d.\n", \
397+
(alg).base.cra_driver_name, ret); \
398+
} \
399+
} else { \
400+
ret = (tester()); \
401+
if (ret) { \
402+
if (fips_enabled && (ret == WC_NO_ERR_TRACE(NOT_COMPILED_IN))) { \
403+
pr_info("wolfCrypt: skipping FIPS-incompatible alg %s.\n", \
404+
(alg).base.cra_driver_name); \
405+
} \
406+
else { \
407+
seen_err = -EINVAL; \
408+
pr_err("ERROR: wolfCrypt self-test for %s failed " \
409+
"with return code %d.\n", \
410+
(alg).base.cra_driver_name, ret); \
411+
} \
412+
(crypto_unregister_ ## alg_class)(&(alg)); \
413+
if (! (alg.base.cra_flags & CRYPTO_ALG_DEAD)) { \
414+
pr_err("ERROR: alg %s not _DEAD " \
415+
"after crypto_unregister_%s -- " \
416+
"marking as loaded despite test failure.", \
417+
(alg).base.cra_driver_name, \
418+
#alg_class); \
419+
alg ## _loaded = 1; \
420+
++linuxkm_lkcapi_n_registered; \
421+
} \
422+
} else { \
423+
alg ## _loaded = 1; \
424+
++linuxkm_lkcapi_n_registered; \
425+
WOLFKM_INSTALL_NOTICE(alg) \
426+
} \
427+
} \
428+
} \
429+
} while (0)
430+
#endif /* HAVE_FIPS && CONFIG_CRYPTO_MANAGER && etc.. */
431+
368432
/* We always register the derivative/composite algs first, to assure that
369433
* the kernel doesn't synthesize them dynamically from our primitives.
370434
*/
@@ -464,7 +528,6 @@ static int linuxkm_lkcapi_register(void)
464528
#endif
465529

466530
#ifdef LINUXKM_LKCAPI_REGISTER_ECDSA
467-
468531
#if (LINUX_VERSION_CODE < KERNEL_VERSION(6, 3, 0)) && \
469532
defined(HAVE_FIPS) && defined(CONFIG_CRYPTO_FIPS) && \
470533
defined(CONFIG_CRYPTO_MANAGER) && \
@@ -473,30 +536,43 @@ static int linuxkm_lkcapi_register(void)
473536
* ecdsa was not recognized as fips_allowed before linux v6.3
474537
* in kernel crypto/testmgr.c.
475538
*/
476-
fips_enabled = 0;
477-
#endif
539+
#if defined(LINUXKM_ECC192)
540+
REGISTER_ALG_OPTIONAL(ecdsa_nist_p192, akcipher,
541+
linuxkm_test_ecdsa_nist_p192);
542+
#endif /* LINUXKM_ECC192 */
478543

479-
#if defined(LINUXKM_ECC192)
480-
REGISTER_ALG(ecdsa_nist_p192, akcipher,
481-
linuxkm_test_ecdsa_nist_p192);
482-
#endif /* LINUXKM_ECC192 */
544+
REGISTER_ALG_OPTIONAL(ecdsa_nist_p256, akcipher,
545+
linuxkm_test_ecdsa_nist_p256);
483546

484-
REGISTER_ALG(ecdsa_nist_p256, akcipher,
485-
linuxkm_test_ecdsa_nist_p256);
547+
REGISTER_ALG_OPTIONAL(ecdsa_nist_p384, akcipher,
548+
linuxkm_test_ecdsa_nist_p384);
486549

487-
REGISTER_ALG(ecdsa_nist_p384, akcipher,
488-
linuxkm_test_ecdsa_nist_p384);
550+
#if defined(HAVE_ECC521)
551+
REGISTER_ALG_OPTIONAL(ecdsa_nist_p521, akcipher,
552+
linuxkm_test_ecdsa_nist_p521);
553+
#endif /* HAVE_ECC521 */
554+
#else
555+
#if defined(LINUXKM_ECC192)
556+
REGISTER_ALG(ecdsa_nist_p192, akcipher,
557+
linuxkm_test_ecdsa_nist_p192);
558+
#endif /* LINUXKM_ECC192 */
489559

490-
#if defined(HAVE_ECC521)
491-
REGISTER_ALG(ecdsa_nist_p521, akcipher,
492-
linuxkm_test_ecdsa_nist_p521);
493-
#endif /* HAVE_ECC521 */
560+
REGISTER_ALG(ecdsa_nist_p256, akcipher,
561+
linuxkm_test_ecdsa_nist_p256);
562+
563+
REGISTER_ALG(ecdsa_nist_p384, akcipher,
564+
linuxkm_test_ecdsa_nist_p384);
565+
566+
#if defined(HAVE_ECC521)
567+
REGISTER_ALG(ecdsa_nist_p521, akcipher,
568+
linuxkm_test_ecdsa_nist_p521);
569+
#endif /* HAVE_ECC521 */
570+
#endif /* if linux < 6.3 && HAVE_FIPS && etc.. */
494571

495572
#if (LINUX_VERSION_CODE < KERNEL_VERSION(6, 3, 0)) && \
496573
defined(HAVE_FIPS) && defined(CONFIG_CRYPTO_FIPS) && \
497574
defined(CONFIG_CRYPTO_MANAGER) && \
498575
!defined(CONFIG_CRYPTO_MANAGER_DISABLE_TESTS)
499-
fips_enabled = 1;
500576
#endif
501577

502578
#endif /* LINUXKM_LKCAPI_REGISTER_ECDSA */
@@ -514,33 +590,24 @@ static int linuxkm_lkcapi_register(void)
514590
* Given the above, and given we're not actually relying on the crypto
515591
* manager for FIPS self tests, and given the FIPS ECDH implementation passes
516592
* the non-FIPS ECDH crypto manager tests, the pragmatic solution we settle
517-
* on here for ECDH is to always clear fips_enabled in target kernels that
518-
* have it.
593+
* on here is for ECDH loading to be optional when fips and fips tests are
594+
* enabled. Failures because of !fips_allowed are skipped over.
519595
*/
520-
521-
#if defined(CONFIG_CRYPTO_FIPS) && \
522-
defined(CONFIG_CRYPTO_MANAGER) && \
523-
!defined(CONFIG_CRYPTO_MANAGER_DISABLE_TESTS)
524-
fips_enabled = 0;
525-
#endif
526-
527-
#if defined(LINUXKM_ECC192)
528-
REGISTER_ALG(ecdh_nist_p192, kpp,
529-
linuxkm_test_ecdh_nist_p192);
530-
#endif /* LINUXKM_ECC192 */
531-
532-
REGISTER_ALG(ecdh_nist_p256, kpp,
533-
linuxkm_test_ecdh_nist_p256);
534-
535-
REGISTER_ALG(ecdh_nist_p384, kpp,
536-
linuxkm_test_ecdh_nist_p384);
537-
538596
#if defined(CONFIG_CRYPTO_FIPS) && \
539597
defined(CONFIG_CRYPTO_MANAGER) && \
540598
!defined(CONFIG_CRYPTO_MANAGER_DISABLE_TESTS)
541-
fips_enabled = 1;
542-
#endif
543-
599+
#if defined(LINUXKM_ECC192)
600+
REGISTER_ALG_OPTIONAL(ecdh_nist_p192, kpp, linuxkm_test_ecdh_nist_p192);
601+
#endif /* LINUXKM_ECC192 */
602+
REGISTER_ALG_OPTIONAL(ecdh_nist_p256, kpp, linuxkm_test_ecdh_nist_p256);
603+
REGISTER_ALG_OPTIONAL(ecdh_nist_p384, kpp, linuxkm_test_ecdh_nist_p384);
604+
#else
605+
#if defined(LINUXKM_ECC192)
606+
REGISTER_ALG(ecdh_nist_p192, kpp, linuxkm_test_ecdh_nist_p192);
607+
#endif /* LINUXKM_ECC192 */
608+
REGISTER_ALG(ecdh_nist_p256, kpp, linuxkm_test_ecdh_nist_p256);
609+
REGISTER_ALG(ecdh_nist_p384, kpp, linuxkm_test_ecdh_nist_p384);
610+
#endif /* CONFIG_CRYPTO_FIPS && etc.. */
544611
#endif /* LINUXKM_LKCAPI_REGISTER_ECDH */
545612

546613
#ifdef LINUXKM_LKCAPI_REGISTER_RSA
@@ -625,12 +692,8 @@ static int linuxkm_lkcapi_register(void)
625692
#endif /* LINUXKM_LKCAPI_REGISTER_DH */
626693

627694
#undef REGISTER_ALG
695+
#undef REGISTER_ALG_OPTIONAL
628696

629-
#if defined(HAVE_FIPS) && defined(CONFIG_CRYPTO_MANAGER) && \
630-
!defined(CONFIG_CRYPTO_MANAGER_DISABLE_TESTS)
631-
if (enabled_fips)
632-
fips_enabled = 0;
633-
#endif
634697
#ifdef CONFIG_CRYPTO_MANAGER_EXTRA_TESTS
635698
disable_setkey_warnings = 0;
636699
#endif

0 commit comments

Comments
 (0)