Blob Blame History Raw
From: Nicolai Stange <nstange@suse.de>
Date: Mon, 31 Jan 2022 07:47:41 +0100
Subject: [PATCH] crypto: seqiv - flag instantiations as FIPS compliant
References: jsc#SLE-21132,bsc#1194778
Patch-mainline: Never, might be better adjusting all gcm() usages upstream

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 <nstange@suse.de>

---
 crypto/seqiv.c         |   15 ++++++++++++++-
 include/linux/crypto.h |    2 ++
 2 files changed, 16 insertions(+), 1 deletion(-)

--- a/crypto/seqiv.c
+++ b/crypto/seqiv.c
@@ -133,6 +133,19 @@ static int seqiv_aead_decrypt(struct aea
 	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;
@@ -150,7 +163,7 @@ static int seqiv_aead_create(struct cryp
 	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);
--- a/include/linux/crypto.h
+++ b/include/linux/crypto.h
@@ -142,6 +142,8 @@
 #define CRYPTO_TFM_REQ_MAY_SLEEP	0x00000200
 #define CRYPTO_TFM_REQ_MAY_BACKLOG	0x00000400
 
+#define CRYPTO_TFM_FIPS_COMPLIANCE	0x80000000
+
 /*
  * Miscellaneous stuff.
  */