From 9aea35967263038151a3f9f7c00b867be0e11949 Mon Sep 17 00:00:00 2001 From: Sultan Alsawaf Date: Fri, 19 Sep 2025 17:09:06 -0700 Subject: [PATCH 1/2] crypto: seqiv - flag instantiations as FIPS compliant feature FIPS enablement commit-author Vladis Dronov commit e3a5a100a7dcd102b45f6b402f3d8b6a3ceabc1c commit-source https://gitlab.com/cki-project/kernel-ark.git JIRA: https://issues.redhat.com/browse/RHEL-54183 Upstream Status: RHEL only Forwardport of 45e87c3b9284 ("crypto: seqiv - flag instantiations as FIPS compliant") from C9S. This patch has no chances to be accepted upstream, see the commit message below. Author: Nicolai Stange crypto: seqiv - flag instantiations as FIPS compliant For gcm(aes) with external IV generation, FIPS 140-3 requires the verification of all external IV generation operations in order to ensure the uniqueness of the IV (see IG C.H). This is being deemed unfeasible and thus, only internal IV generation, i.e. wrapping gcm(aes) with seqiv(), can effectively be considered as approved. The standard approach would be to disallow plain gcm(aes) and to only allow seqiv(gcm(aes)) in FIPS mode. However, there are quite some plain gcm(aes) usage sites in the kernel: a quick grep reveals samba, macsec, ceph, mac80211, tipc, tls, etc. and breaking these in FIPS mode would be highly undesirable. It might perhaps be possible to convert some of these to seqiv(gcm(aes)), but for some others it might be entirely impossible due to e.g. protocol constraints. For the time being, an alternative approach has been proposed as a workaround: make seqiv() set a new flag, CRYPTO_TFM_FIPS_COMPLIANCE, on the transforms and document that in the particular case of gcm(aes), callers must check for this flag in order to determine FIPS compliance. Implement this. Signed-off-by: Nicolai Stange Signed-off-by: Vladis Dronov (cherry picked from commit e3a5a100a7dcd102b45f6b402f3d8b6a3ceabc1c) Signed-off-by: Sultan Alsawaf --- crypto/seqiv.c | 15 ++++++++++++++- include/linux/crypto.h | 2 ++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/crypto/seqiv.c b/crypto/seqiv.c index 17e11d51ddc36..9c136a3b62679 100644 --- a/crypto/seqiv.c +++ b/crypto/seqiv.c @@ -132,6 +132,19 @@ static int seqiv_aead_decrypt(struct aead_request *req) return crypto_aead_decrypt(subreq); } +static int aead_init_seqiv(struct crypto_aead *aead) +{ + int err; + + err = aead_init_geniv(aead); + if (err) + return err; + + crypto_aead_set_flags(aead, CRYPTO_TFM_FIPS_COMPLIANCE); + + return 0; +} + static int seqiv_aead_create(struct crypto_template *tmpl, struct rtattr **tb) { struct aead_instance *inst; @@ -149,7 +162,7 @@ static int seqiv_aead_create(struct crypto_template *tmpl, struct rtattr **tb) inst->alg.encrypt = seqiv_aead_encrypt; inst->alg.decrypt = seqiv_aead_decrypt; - inst->alg.init = aead_init_geniv; + inst->alg.init = aead_init_seqiv; inst->alg.exit = aead_exit_geniv; inst->alg.base.cra_ctxsize = sizeof(struct aead_geniv_ctx); diff --git a/include/linux/crypto.h b/include/linux/crypto.h index 59021b8609a70..cd78d16ee5d65 100644 --- a/include/linux/crypto.h +++ b/include/linux/crypto.h @@ -135,6 +135,8 @@ #define CRYPTO_TFM_REQ_MAY_BACKLOG 0x00000400 #define CRYPTO_TFM_REQ_NEED_RESEED 0x00000800 +#define CRYPTO_TFM_FIPS_COMPLIANCE 0x80000000 + /* * Miscellaneous stuff. */ From b0f0c553a1377f786af3ce475c6c0ce18cad7388 Mon Sep 17 00:00:00 2001 From: Sultan Alsawaf Date: Fri, 19 Sep 2025 17:13:16 -0700 Subject: [PATCH 2/2] crypto: dh - implement FIPS PCT feature FIPS enablement commit-author Vladis Dronov commit 6030c378bf503f83af9d46e58d43e164fa49eaa5 commit-source https://gitlab.com/cki-project/kernel-ark.git JIRA: https://issues.redhat.com/browse/RHEL-54183 Upstream Status: RHEL only Forwardport of 8d6b650d93e2 ("crypto: dh - implement FIPS PCT") from C9S. The below patch from Nicolai is not going to be accepted upstream. Add a panic on a failed test per FIPS certification requirement. From: Nicolai Stange Date: Tue, 30 Nov 2021 16:51:12 +0100 Subject: [PATCH] crypto: dh - implement FIPS PCT References: jsc#SLE-21132,bsc#1191256 Patch-mainline: Never, not upstreamable SP800-56Arev3, 5.6.2.1.4 ("Owner Assurance of Pair-wise Consistency") requires that a pair-wise consistency check needs to be conducted on a keypair. A pair-wise consistency test (PCT) is meant to ensure that a some provided public key is indeed associated with the given private one. As the kernel's DH implementation always computes the public key from the private one, this is guaranteed already as per the API. However, in the course of the certification process, there had been a lengthy discussion regarding this topic, with the result that a PCT is nonetheless mandatory. Simply implement a PCT for DH and move on. As mandated by SP800-56Arev3, 5.6.2.1.4, the PCT involves recomputing the public key and comparing it against the one under test. Signed-off-by: Nicolai Stange Signed-off-by: Vladis Dronov (cherry picked from commit 6030c378bf503f83af9d46e58d43e164fa49eaa5) Signed-off-by: Sultan Alsawaf --- crypto/dh.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/crypto/dh.c b/crypto/dh.c index afc0fd8477613..e13258c3d1d1a 100644 --- a/crypto/dh.c +++ b/crypto/dh.c @@ -227,10 +227,35 @@ static int dh_compute_value(struct kpp_request *req) /* SP800-56A rev 3 5.6.2.1.3 key check */ } else { + MPI val_pct; + if (dh_is_pubkey_valid(ctx, val)) { ret = -EAGAIN; goto err_free_val; } + + /* + * SP800-56Arev3, 5.6.2.1.4: ("Owner Assurance + * of Pair-wise Consistency"): recompute the + * public key and check if the results match. + */ + val_pct = mpi_alloc(0); + if (!val_pct) { + ret = -ENOMEM; + goto err_free_val; + } + + ret = _compute_val(ctx, base, val_pct); + if (ret) { + mpi_free(val_pct); + goto err_free_val; + } + + if (mpi_cmp(val, val_pct) != 0) { + fips_fail_notify(); + panic("dh: pair-wise consistency test failed\n"); + } + mpi_free(val_pct); } }