Petr Tesarik a30ba3
From: =?UTF-8?q?Stephan=20M=C3=BCller?= <smueller@chronox.de>
Petr Tesarik a30ba3
Date: Mon, 20 Jul 2020 19:08:32 +0200
Petr Tesarik a30ba3
Subject: crypto: dh - check validity of Z before export
Petr Tesarik a30ba3
Git-commit: 90fa9ae51c1f2fa932bfa0a4d19163d49f0c1c46
Petr Tesarik a30ba3
Patch-mainline: v5.9-rc1
Petr Tesarik a30ba3
References: bsc#1175718
Petr Tesarik a30ba3
Petr Tesarik a30ba3
SP800-56A rev3 section 5.7.1.1 step 2 mandates that the validity of the
Petr Tesarik a30ba3
calculated shared secret is verified before the data is returned to the
Petr Tesarik a30ba3
caller. This patch adds the validation check.
Petr Tesarik a30ba3
Petr Tesarik a30ba3
Signed-off-by: Stephan Mueller <smueller@chronox.de>
Petr Tesarik a30ba3
Acked-by: Neil Horman <nhorman@redhat.com>
Petr Tesarik a30ba3
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Petr Tesarik a30ba3
Acked-by: Petr Tesarik <ptesarik@suse.com>
Petr Tesarik a30ba3
---
Petr Tesarik a30ba3
 crypto/dh.c |   29 +++++++++++++++++++++++++++++
Petr Tesarik a30ba3
 1 file changed, 29 insertions(+)
Petr Tesarik a30ba3
Petr Tesarik a30ba3
--- a/crypto/dh.c
Petr Tesarik a30ba3
+++ b/crypto/dh.c
Petr Tesarik a30ba3
@@ -9,6 +9,7 @@
Petr Tesarik a30ba3
 #include <crypto/internal/kpp.h>
Petr Tesarik a30ba3
 #include <crypto/kpp.h>
Petr Tesarik a30ba3
 #include <crypto/dh.h>
Petr Tesarik a30ba3
+#include <linux/fips.h>
Petr Tesarik a30ba3
 #include <linux/mpi.h>
Petr Tesarik a30ba3
 
Petr Tesarik a30ba3
 struct dh_ctx {
Petr Tesarik a30ba3
@@ -179,6 +180,34 @@ static int dh_compute_value(struct kpp_r
Petr Tesarik a30ba3
 	if (ret)
Petr Tesarik a30ba3
 		goto err_free_base;
Petr Tesarik a30ba3
 
Petr Tesarik a30ba3
+	/* SP800-56A rev3 5.7.1.1 check: Validation of shared secret */
Petr Tesarik a30ba3
+	if (fips_enabled && req->src) {
Petr Tesarik a30ba3
+		MPI pone;
Petr Tesarik a30ba3
+
Petr Tesarik a30ba3
+		/* z <= 1 */
Petr Tesarik a30ba3
+		if (mpi_cmp_ui(val, 1) < 1) {
Petr Tesarik a30ba3
+			ret = -EBADMSG;
Petr Tesarik a30ba3
+			goto err_free_base;
Petr Tesarik a30ba3
+		}
Petr Tesarik a30ba3
+
Petr Tesarik a30ba3
+		/* z == p - 1 */
Petr Tesarik a30ba3
+		pone = mpi_alloc(0);
Petr Tesarik a30ba3
+
Petr Tesarik a30ba3
+		if (!pone) {
Petr Tesarik a30ba3
+			ret = -ENOMEM;
Petr Tesarik a30ba3
+			goto err_free_base;
Petr Tesarik a30ba3
+		}
Petr Tesarik a30ba3
+
Petr Tesarik a30ba3
+		ret = mpi_sub_ui(pone, ctx->p, 1);
Petr Tesarik a30ba3
+		if (!ret && !mpi_cmp(pone, val))
Petr Tesarik a30ba3
+			ret = -EBADMSG;
Petr Tesarik a30ba3
+
Petr Tesarik a30ba3
+		mpi_free(pone);
Petr Tesarik a30ba3
+
Petr Tesarik a30ba3
+		if (ret)
Petr Tesarik a30ba3
+			goto err_free_base;
Petr Tesarik a30ba3
+	}
Petr Tesarik a30ba3
+
Petr Tesarik a30ba3
 	ret = mpi_write_to_sgl(val, req->dst, req->dst_len, &sign;;
Petr Tesarik a30ba3
 	if (ret)
Petr Tesarik a30ba3
 		goto err_free_base;