diff --git a/patches.suse/crypto-dh-check-validity-of-z-before-export b/patches.suse/crypto-dh-check-validity-of-z-before-export new file mode 100644 index 0000000..2f3b8d7 --- /dev/null +++ b/patches.suse/crypto-dh-check-validity-of-z-before-export @@ -0,0 +1,64 @@ +From: =?UTF-8?q?Stephan=20M=C3=BCller?= +Date: Mon, 20 Jul 2020 19:08:32 +0200 +Subject: crypto: dh - check validity of Z before export +Git-commit: 90fa9ae51c1f2fa932bfa0a4d19163d49f0c1c46 +Patch-mainline: v5.9-rc1 +References: bsc#1175718 + +SP800-56A rev3 section 5.7.1.1 step 2 mandates that the validity of the +calculated shared secret is verified before the data is returned to the +caller. This patch adds the validation check. + +Signed-off-by: Stephan Mueller +Acked-by: Neil Horman +Signed-off-by: Herbert Xu +Acked-by: Petr Tesarik +--- + crypto/dh.c | 29 +++++++++++++++++++++++++++++ + 1 file changed, 29 insertions(+) + +--- a/crypto/dh.c ++++ b/crypto/dh.c +@@ -9,6 +9,7 @@ + #include + #include + #include ++#include + #include + + struct dh_ctx { +@@ -179,6 +180,34 @@ static int dh_compute_value(struct kpp_r + if (ret) + goto err_free_base; + ++ /* SP800-56A rev3 5.7.1.1 check: Validation of shared secret */ ++ if (fips_enabled && req->src) { ++ MPI pone; ++ ++ /* z <= 1 */ ++ if (mpi_cmp_ui(val, 1) < 1) { ++ ret = -EBADMSG; ++ goto err_free_base; ++ } ++ ++ /* z == p - 1 */ ++ pone = mpi_alloc(0); ++ ++ if (!pone) { ++ ret = -ENOMEM; ++ goto err_free_base; ++ } ++ ++ ret = mpi_sub_ui(pone, ctx->p, 1); ++ if (!ret && !mpi_cmp(pone, val)) ++ ret = -EBADMSG; ++ ++ mpi_free(pone); ++ ++ if (ret) ++ goto err_free_base; ++ } ++ + ret = mpi_write_to_sgl(val, req->dst, req->dst_len, &sign); + if (ret) + goto err_free_base; diff --git a/patches.suse/crypto-dh-sp800-56a-rev-3-local-public-key-validation b/patches.suse/crypto-dh-sp800-56a-rev-3-local-public-key-validation new file mode 100644 index 0000000..ad859ad --- /dev/null +++ b/patches.suse/crypto-dh-sp800-56a-rev-3-local-public-key-validation @@ -0,0 +1,89 @@ +From: =?UTF-8?q?Stephan=20M=C3=BCller?= +Date: Mon, 20 Jul 2020 19:08:52 +0200 +Subject: crypto: dh - SP800-56A rev 3 local public key validation +Git-commit: 2ed5ba61cc78f102656eedc0b4c80fd14a5e8c7c +Patch-mainline: v5.9-rc1 +References: bsc#1175718 + +After the generation of a local public key, SP800-56A rev 3 section +5.6.2.1.3 mandates a validation of that key with a full validation +compliant to section 5.6.2.3.1. + +Only if the full validation passes, the key is allowed to be used. + +Signed-off-by: Stephan Mueller +Signed-off-by: Herbert Xu +Acked-by: Petr Tesarik +--- + crypto/dh.c | 59 ++++++++++++++++++++++++++++++++++------------------------- + 1 file changed, 34 insertions(+), 25 deletions(-) + +--- a/crypto/dh.c ++++ b/crypto/dh.c +@@ -180,32 +180,41 @@ static int dh_compute_value(struct kpp_r + if (ret) + goto err_free_base; + +- /* SP800-56A rev3 5.7.1.1 check: Validation of shared secret */ +- if (fips_enabled && req->src) { +- MPI pone; +- +- /* z <= 1 */ +- if (mpi_cmp_ui(val, 1) < 1) { +- ret = -EBADMSG; +- goto err_free_base; ++ if (fips_enabled) { ++ /* SP800-56A rev3 5.7.1.1 check: Validation of shared secret */ ++ if (req->src) { ++ MPI pone; ++ ++ /* z <= 1 */ ++ if (mpi_cmp_ui(val, 1) < 1) { ++ ret = -EBADMSG; ++ goto err_free_base; ++ } ++ ++ /* z == p - 1 */ ++ pone = mpi_alloc(0); ++ ++ if (!pone) { ++ ret = -ENOMEM; ++ goto err_free_base; ++ } ++ ++ ret = mpi_sub_ui(pone, ctx->p, 1); ++ if (!ret && !mpi_cmp(pone, val)) ++ ret = -EBADMSG; ++ ++ mpi_free(pone); ++ ++ if (ret) ++ goto err_free_base; ++ ++ /* SP800-56A rev 3 5.6.2.1.3 key check */ ++ } else { ++ if (dh_is_pubkey_valid(ctx, val)) { ++ ret = -EAGAIN; ++ goto err_free_val; ++ } + } +- +- /* z == p - 1 */ +- pone = mpi_alloc(0); +- +- if (!pone) { +- ret = -ENOMEM; +- goto err_free_base; +- } +- +- ret = mpi_sub_ui(pone, ctx->p, 1); +- if (!ret && !mpi_cmp(pone, val)) +- ret = -EBADMSG; +- +- mpi_free(pone); +- +- if (ret) +- goto err_free_base; + } + + ret = mpi_write_to_sgl(val, req->dst, req->dst_len, &sign); diff --git a/patches.suse/crypto-ecc-sp800-56a-rev-3-local-public-key-validation b/patches.suse/crypto-ecc-sp800-56a-rev-3-local-public-key-validation new file mode 100644 index 0000000..19d7ab6 --- /dev/null +++ b/patches.suse/crypto-ecc-sp800-56a-rev-3-local-public-key-validation @@ -0,0 +1,83 @@ +From: =?UTF-8?q?Stephan=20M=C3=BCller?= +Date: Mon, 20 Jul 2020 19:09:23 +0200 +Subject: crypto: ecc - SP800-56A rev 3 local public key validation +Git-commit: 6914dd53eb7af7cbc66edf7992d600b1e952c40d +Patch-mainline: v5.9-rc1 +References: bsc#1175718 + +After the generation of a local public key, SP800-56A rev 3 section +5.6.2.1.3 mandates a validation of that key with a full validation +compliant to section 5.6.2.3.3. + +Only if the full validation passes, the key is allowed to be used. + +The patch adds the full key validation compliant to 5.6.2.3.3 and +performs the required check on the generated public key. + +Signed-off-by: Stephan Mueller +Signed-off-by: Herbert Xu +[ ptesarik: The export is needed only to share the routines with ecrdsa. + SLE15 does not have the ecrdsa module, so the added function should be + local to crypto/ecc.c. ] +Signed-off-by: Petr Tesarik +--- + crypto/ecc.c | 34 +++++++++++++++++++++++++++++++++- + 1 file changed, 33 insertions(+), 1 deletion(-) + +--- a/crypto/ecc.c ++++ b/crypto/ecc.c +@@ -42,6 +42,9 @@ typedef struct { + u64 m_high; + } uint128_t; + ++static int ecc_is_pubkey_valid_full(const struct ecc_curve *curve, ++ struct ecc_point *pk); ++ + static inline const struct ecc_curve *ecc_get_curve(unsigned int curve_id) + { + switch (curve_id) { +@@ -1404,7 +1407,9 @@ int ecc_make_pub_key(unsigned int curve_ + } + + ecc_point_mult(pk, &curve->g, priv, NULL, curve, ndigits); +- if (ecc_point_is_zero(pk)) { ++ ++ /* SP800-56A rev 3 5.6.2.1.3 key check */ ++ if (ecc_is_pubkey_valid_full(curve, pk)) { + ret = -EAGAIN; + goto err_free_point; + } +@@ -1452,6 +1457,33 @@ int ecc_is_pubkey_valid_partial(const st + } + EXPORT_SYMBOL(ecc_is_pubkey_valid_partial); + ++/* SP800-56A section 5.6.2.3.3 full verification */ ++static int ecc_is_pubkey_valid_full(const struct ecc_curve *curve, ++ struct ecc_point *pk) ++{ ++ struct ecc_point *nQ; ++ ++ /* Checks 1 through 3 */ ++ int ret = ecc_is_pubkey_valid_partial(curve, pk); ++ ++ if (ret) ++ return ret; ++ ++ /* Check 4: Verify that nQ is the zero point. */ ++ nQ = ecc_alloc_point(pk->ndigits); ++ if (!nQ) ++ return -ENOMEM; ++ ++ ecc_point_mult(nQ, pk, curve->n, NULL, curve, pk->ndigits); ++ if (!ecc_point_is_zero(nQ)) ++ ret = -EINVAL; ++ ++ ecc_free_point(nQ); ++ ++ return ret; ++} ++EXPORT_SYMBOL(ecc_is_pubkey_valid_full); ++ + int crypto_ecdh_shared_secret(unsigned int curve_id, unsigned int ndigits, + const u64 *private_key, const u64 *public_key, + u64 *secret) diff --git a/patches.suse/crypto-ecdh-check-validity-of-z-before-export b/patches.suse/crypto-ecdh-check-validity-of-z-before-export new file mode 100644 index 0000000..271d22c --- /dev/null +++ b/patches.suse/crypto-ecdh-check-validity-of-z-before-export @@ -0,0 +1,44 @@ +From: =?UTF-8?q?Stephan=20M=C3=BCller?= +Date: Mon, 20 Jul 2020 19:07:48 +0200 +Subject: crypto: ecdh - check validity of Z before export +Git-commit: e7d2b41e5c773c1e00f0f30519b9790ba7e4a58c +Patch-mainline: v5.9-rc1 +References: bsc#1175718 + +SP800-56A rev3 section 5.7.1.2 step 2 mandates that the validity of the +calculated shared secret is verified before the data is returned to the +caller. Thus, the export function and the validity check functions are +reversed. In addition, the sensitive variables of priv and rand_z are +zeroized. + +Signed-off-by: Stephan Mueller +Reviewed-by: Vitaly Chikunov +Acked-by: Neil Horman +Signed-off-by: Herbert Xu +Acked-by: Petr Tesarik +--- + crypto/ecc.c | 11 ++++++++--- + 1 file changed, 8 insertions(+), 3 deletions(-) + +--- a/crypto/ecc.c ++++ b/crypto/ecc.c +@@ -1495,11 +1495,16 @@ int crypto_ecdh_shared_secret(unsigned i + + ecc_point_mult(product, pk, priv, rand_z, curve, ndigits); + +- ecc_swap_digits(product->x, secret, ndigits); +- +- if (ecc_point_is_zero(product)) ++ if (ecc_point_is_zero(product)) { + ret = -EFAULT; ++ goto err_validity; ++ } ++ ++ ecc_swap_digits(product->x, secret, ndigits); + ++err_validity: ++ memzero_explicit(priv, sizeof(priv)); ++ memzero_explicit(rand_z, sizeof(rand_z)); + ecc_free_point(product); + err_alloc_product: + ecc_free_point(pk); diff --git a/patches.suse/lib-mpi-add-mpi_sub_ui b/patches.suse/lib-mpi-add-mpi_sub_ui new file mode 100644 index 0000000..7d34138 --- /dev/null +++ b/patches.suse/lib-mpi-add-mpi_sub_ui @@ -0,0 +1,128 @@ +From: Marcelo Henrique Cerri +Date: Mon, 20 Jul 2020 19:08:09 +0200 +Subject: lib/mpi: Add mpi_sub_ui() +Git-commit: 4278e9d99e38938a7611b927fa4d73e6c86cb4fc +Patch-mainline: v5.9-rc1 +References: bsc#1175718 + +Add mpi_sub_ui() based on Gnu MP mpz_sub_ui() function from file +mpz/aors_ui.h[1] from change id 510b83519d1c adapting the code to the +kernel's data structures, helper functions and coding style and also +removing the defines used to produce mpz_sub_ui() and mpz_add_ui() +from the same code. + +[1] https://gmplib.org/repo/gmp-6.2/file/510b83519d1c/mpz/aors.h + +Signed-off-by: Marcelo Henrique Cerri +Signed-off-by: Stephan Mueller +Signed-off-by: Herbert Xu +Acked-by: Petr Tesarik +--- + include/linux/mpi.h | 3 + + lib/mpi/Makefile | 1 + lib/mpi/mpi-sub-ui.c | 78 +++++++++++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 82 insertions(+) + +--- a/include/linux/mpi.h ++++ b/include/linux/mpi.h +@@ -63,6 +63,9 @@ int mpi_powm(MPI res, MPI base, MPI exp, + int mpi_cmp_ui(MPI u, ulong v); + int mpi_cmp(MPI u, MPI v); + ++/*-- mpi-sub-ui.c --*/ ++int mpi_sub_ui(MPI w, MPI u, unsigned long vval); ++ + /*-- mpi-bit.c --*/ + void mpi_normalize(MPI a); + unsigned mpi_get_nbits(MPI a); +--- a/lib/mpi/Makefile ++++ b/lib/mpi/Makefile +@@ -16,6 +16,7 @@ mpi-y = \ + mpicoder.o \ + mpi-bit.o \ + mpi-cmp.o \ ++ mpi-sub-ui.o \ + mpih-cmp.o \ + mpih-div.o \ + mpih-mul.o \ +--- /dev/null ++++ b/lib/mpi/mpi-sub-ui.c +@@ -0,0 +1,78 @@ ++// SPDX-License-Identifier: GPL-2.0-or-later ++/* mpi-sub-ui.c - Subtract an unsigned integer from an MPI. ++ * ++ * Copyright 1991, 1993, 1994, 1996, 1999-2002, 2004, 2012, 2013, 2015 ++ * Free Software Foundation, Inc. ++ * ++ * This file was based on the GNU MP Library source file: ++ * https://gmplib.org/repo/gmp-6.2/file/510b83519d1c/mpz/aors_ui.h ++ * ++ * The GNU MP Library is free software; you can redistribute it and/or modify ++ * it under the terms of either: ++ * ++ * * the GNU Lesser General Public License as published by the Free ++ * Software Foundation; either version 3 of the License, or (at your ++ * option) any later version. ++ * ++ * or ++ * ++ * * the GNU General Public License as published by the Free Software ++ * Foundation; either version 2 of the License, or (at your option) any ++ * later version. ++ * ++ * or both in parallel, as here. ++ * ++ * The GNU MP Library is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ++ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * for more details. ++ * ++ * You should have received copies of the GNU General Public License and the ++ * GNU Lesser General Public License along with the GNU MP Library. If not, ++ * see https://www.gnu.org/licenses/. ++ */ ++ ++#include "mpi-internal.h" ++ ++int mpi_sub_ui(MPI w, MPI u, unsigned long vval) ++{ ++ if (u->nlimbs == 0) { ++ if (mpi_resize(w, 1) < 0) ++ return -ENOMEM; ++ w->d[0] = vval; ++ w->nlimbs = (vval != 0); ++ w->sign = (vval != 0); ++ return 0; ++ } ++ ++ /* If not space for W (and possible carry), increase space. */ ++ if (mpi_resize(w, u->nlimbs + 1)) ++ return -ENOMEM; ++ ++ if (u->sign) { ++ mpi_limb_t cy; ++ ++ cy = mpihelp_add_1(w->d, u->d, u->nlimbs, (mpi_limb_t) vval); ++ w->d[u->nlimbs] = cy; ++ w->nlimbs = u->nlimbs + cy; ++ w->sign = 1; ++ } else { ++ /* The signs are different. Need exact comparison to determine ++ * which operand to subtract from which. ++ */ ++ if (u->nlimbs == 1 && u->d[0] < vval) { ++ w->d[0] = vval - u->d[0]; ++ w->nlimbs = 1; ++ w->sign = 1; ++ } else { ++ mpihelp_sub_1(w->d, u->d, u->nlimbs, (mpi_limb_t) vval); ++ /* Size can decrease with at most one limb. */ ++ w->nlimbs = (u->nlimbs - (w->d[u->nlimbs - 1] == 0)); ++ w->sign = 0; ++ } ++ } ++ ++ mpi_normalize(w); ++ return 0; ++} ++EXPORT_SYMBOL_GPL(mpi_sub_ui); diff --git a/series.conf b/series.conf index 4fa2dea..7e9f115 100644 --- a/series.conf +++ b/series.conf @@ -14190,6 +14190,11 @@ patches.suse/crypto-aesni-add-compatibility-with-IAS.patch patches.suse/crypto-aesni-Fix-build-with-LLVM_IAS-1.patch patches.suse/crypto-qat-fix-double-free-in-qat_uclo_create_batch_.patch + patches.suse/crypto-ecdh-check-validity-of-z-before-export + patches.suse/lib-mpi-add-mpi_sub_ui + patches.suse/crypto-dh-check-validity-of-z-before-export + patches.suse/crypto-dh-sp800-56a-rev-3-local-public-key-validation + patches.suse/crypto-ecc-sp800-56a-rev-3-local-public-key-validation patches.suse/mtd-properly-check-all-write-ioctls-for-permissions.patch patches.suse/0007-block-add-docs-for-gendisk-request_queue-refcount-he.patch patches.suse/0008-block-revert-back-to-synchronous-request_queue-remov.patch