From patchwork Fri Nov 19 06:55:33 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stephan Mueller X-Patchwork-Id: 12628337 X-Patchwork-Delegate: herbert@gondor.apana.org.au Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1DB61C433EF for ; Fri, 19 Nov 2021 06:59:31 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 0786661ACE for ; Fri, 19 Nov 2021 06:59:31 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232894AbhKSHCa (ORCPT ); Fri, 19 Nov 2021 02:02:30 -0500 Received: from mo4-p02-ob.smtp.rzone.de ([85.215.255.83]:27531 "EHLO mo4-p02-ob.smtp.rzone.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232589AbhKSHC2 (ORCPT ); Fri, 19 Nov 2021 02:02:28 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; t=1637305164; s=strato-dkim-0002; d=chronox.de; h=References:In-Reply-To:Message-ID:Date:Subject:Cc:To:From:Cc:Date: From:Subject:Sender; bh=e9PSTVVwUetqJwcMqAV3hkxvzTITtObwWtsKs4Wuj4k=; b=Wfdld9GrIJ4mtU0K+G2I9/x4yot69C8Ti1u2jX+cVRRkNdoc2O0rh1jJjesFzatomR y4Ek4A0WmhLE0SDp8hqTqWHaa1t7biBvtLxfArwCYmKU6H3sTk9lyw+Kuzsym4t9hPxT vaZSSwL8d+l+wgJL6IeDHpIiIvgcg3rhMHdjuyVhAArj1o4tCPr1s0TOewdHv0bwLHZQ K7irzVqg4K1HnFb8IiHLD/8TKJMfjwfWcbntS02RsfuCjUjcW3MJcH4EjrcDt+nbPYS7 R9atNVz86GE1penHv9RXwNfVg1J1b0HLKO7H4H3gvu3Gj/AAwX1kLm89zWsDWo+o2fAo 3dAg== Authentication-Results: strato.com; dkim=none X-RZG-AUTH: ":P2ERcEykfu11Y98lp/T7+hdri+uKZK8TKWEqNyiHySGSa9k9xmwdNnzGHXPZJ/SWpaI=" X-RZG-CLASS-ID: mo00 Received: from positron.chronox.de by smtp.strato.de (RZmta 47.34.5 DYNA|AUTH) with ESMTPSA id U02dfbxAJ6xOu40 (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256 bits)) (Client did not present a certificate); Fri, 19 Nov 2021 07:59:24 +0100 (CET) From: Stephan =?iso-8859-1?q?M=FCller?= To: herbert@gondor.apana.org.au Cc: ebiggers@kernel.org, jarkko@kernel.org, Mat Martineau , dhowells@redhat.com, linux-kernel@vger.kernel.org, linux-crypto@vger.kernel.org, keyrings@vger.kernel.org, simo@redhat.com Subject: [PATCH v4 1/4] crypto: Add key derivation self-test support code Date: Fri, 19 Nov 2021 07:55:33 +0100 Message-ID: <2156033.vFx2qVVIhK@positron.chronox.de> In-Reply-To: <4642773.OV4Wx5bFTl@positron.chronox.de> References: <4642773.OV4Wx5bFTl@positron.chronox.de> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-crypto@vger.kernel.org As a preparation to add the key derivation implementations, the self-test data structure definition and the common test code is made available. The test framework follows the testing applied by the NIST CAVP test approach. The structure of the test code follows the implementations found in crypto/testmgr.c|h. In case the KDF implementations will be made available via a kernel crypto API templates, the test code is intended to be merged into testmgr.c|h. Signed-off-by: Stephan Mueller --- include/crypto/internal/kdf_selftest.h | 71 ++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 include/crypto/internal/kdf_selftest.h diff --git a/include/crypto/internal/kdf_selftest.h b/include/crypto/internal/kdf_selftest.h new file mode 100644 index 000000000000..4d03d2af57b7 --- /dev/null +++ b/include/crypto/internal/kdf_selftest.h @@ -0,0 +1,71 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +/* + * Copyright (C) 2021, Stephan Mueller + */ + +#ifndef _CRYPTO_KDF_SELFTEST_H +#define _CRYPTO_KDF_SELFTEST_H + +#include +#include + +struct kdf_testvec { + unsigned char *key; + size_t keylen; + unsigned char *ikm; + size_t ikmlen; + struct kvec info; + unsigned char *expected; + size_t expectedlen; +}; + +static inline int +kdf_test(const struct kdf_testvec *test, const char *name, + int (*crypto_kdf_setkey)(struct crypto_shash *kmd, + const u8 *key, size_t keylen, + const u8 *ikm, size_t ikmlen), + int (*crypto_kdf_generate)(struct crypto_shash *kmd, + const struct kvec *info, + unsigned int info_nvec, + u8 *dst, unsigned int dlen)) +{ + struct crypto_shash *kmd; + int ret; + u8 *buf = kzalloc(test->expectedlen, GFP_KERNEL); + + if (!buf) + return -ENOMEM; + + kmd = crypto_alloc_shash(name, 0, 0); + if (IS_ERR(kmd)) { + pr_err("alg: kdf: could not allocate hash handle for %s\n", + name); + kfree(buf); + return -ENOMEM; + } + + ret = crypto_kdf_setkey(kmd, test->key, test->keylen, + test->ikm, test->ikmlen); + if (ret) { + pr_err("alg: kdf: could not set key derivation key\n"); + goto err; + } + + ret = crypto_kdf_generate(kmd, &test->info, 1, buf, test->expectedlen); + if (ret) { + pr_err("alg: kdf: could not obtain key data\n"); + goto err; + } + + ret = memcmp(test->expected, buf, test->expectedlen); + if (ret) + ret = -EINVAL; + +err: + crypto_free_shash(kmd); + kfree(buf); + return ret; +} + +#endif /* _CRYPTO_KDF_SELFTEST_H */ From patchwork Fri Nov 19 06:55:58 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stephan Mueller X-Patchwork-Id: 12628341 X-Patchwork-Delegate: herbert@gondor.apana.org.au Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 56497C433FE for ; Fri, 19 Nov 2021 06:59:34 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 3E76061B54 for ; Fri, 19 Nov 2021 06:59:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232882AbhKSHCa (ORCPT ); Fri, 19 Nov 2021 02:02:30 -0500 Received: from mo4-p02-ob.smtp.rzone.de ([85.215.255.81]:17314 "EHLO mo4-p02-ob.smtp.rzone.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232554AbhKSHC2 (ORCPT ); Fri, 19 Nov 2021 02:02:28 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; t=1637305163; s=strato-dkim-0002; d=chronox.de; h=References:In-Reply-To:Message-ID:Date:Subject:Cc:To:From:Cc:Date: From:Subject:Sender; bh=OwAhOWsN5CO7vUAMlaR0TBHOocQLwiu2cNdTzLjvmPg=; b=jhgxZ+Oan6irh+58AMLDH2YfbbeN01BnX8LjofD4MQ6ChgsY9k+uOkpc848hjoTqtI T44Cp8C35vWQ8AvKHqLXr2d7mOUZjnE59ULq9dsJJ7VX1AY05qhGxjBlgyINGuS/zC0t HIGsxCHbtARABBO9x/mpDbOmeyvjscD4uNtmT5R83CzL26ucKdCIbosZkDQUy40qT0jz aHg5Rr3uMAS/2jt98+85+MK91KsneuEPtxZ5S4B9tU7/iT0YXJgzd+iXeBV0crbUPtAn g+x91h0NaL7/RfmlHxLDSjh7bS3wKHYWoc9k0xfFz288kmF+P84gdoM5Ivu52zCRe1Dj 0y6Q== Authentication-Results: strato.com; dkim=none X-RZG-AUTH: ":P2ERcEykfu11Y98lp/T7+hdri+uKZK8TKWEqNyiHySGSa9k9xmwdNnzGHXPZJ/SWpaI=" X-RZG-CLASS-ID: mo00 Received: from positron.chronox.de by smtp.strato.de (RZmta 47.34.5 DYNA|AUTH) with ESMTPSA id U02dfbxAJ6xNu3z (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256 bits)) (Client did not present a certificate); Fri, 19 Nov 2021 07:59:23 +0100 (CET) From: Stephan =?iso-8859-1?q?M=FCller?= To: herbert@gondor.apana.org.au Cc: ebiggers@kernel.org, jarkko@kernel.org, Mat Martineau , dhowells@redhat.com, linux-kernel@vger.kernel.org, linux-crypto@vger.kernel.org, keyrings@vger.kernel.org, simo@redhat.com Subject: [PATCH v4 2/4] crypto: add SP800-108 counter key derivation function Date: Fri, 19 Nov 2021 07:55:58 +0100 Message-ID: <2387783.XAFRqVoOGU@positron.chronox.de> In-Reply-To: <4642773.OV4Wx5bFTl@positron.chronox.de> References: <4642773.OV4Wx5bFTl@positron.chronox.de> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-crypto@vger.kernel.org SP800-108 defines three KDFs - this patch provides the counter KDF implementation. The KDF is implemented as a service function where the caller has to maintain the hash / HMAC state. Apart from this hash/HMAC state, no additional state is required to be maintained by either the caller or the KDF implementation. The key for the KDF is set with the crypto_kdf108_setkey function which is intended to be invoked before the caller requests a key derivation operation via crypto_kdf108_ctr_generate. SP800-108 allows the use of either a HMAC or a hash as crypto primitive for the KDF. When a HMAC primtive is intended to be used, crypto_kdf108_setkey must be used to set the HMAC key. Otherwise, for a hash crypto primitve crypto_kdf108_ctr_generate can be used immediately after allocating the hash handle. Signed-off-by: Stephan Mueller --- crypto/Kconfig | 4 + crypto/Makefile | 5 ++ crypto/kdf_sp800108.c | 153 ++++++++++++++++++++++++++++++++++ include/crypto/kdf_sp800108.h | 61 ++++++++++++++ 4 files changed, 223 insertions(+) create mode 100644 crypto/kdf_sp800108.c create mode 100644 include/crypto/kdf_sp800108.h diff --git a/crypto/Kconfig b/crypto/Kconfig index 285f82647d2b..01b9ca0836a5 100644 --- a/crypto/Kconfig +++ b/crypto/Kconfig @@ -1845,6 +1845,10 @@ config CRYPTO_JITTERENTROPY random numbers. This Jitterentropy RNG registers with the kernel crypto API and can be used by any caller. +config CRYPTO_KDF800108_CTR + tristate + select CRYPTO_HASH + config CRYPTO_USER_API tristate diff --git a/crypto/Makefile b/crypto/Makefile index 429c4d57458c..d76bff8d0ffd 100644 --- a/crypto/Makefile +++ b/crypto/Makefile @@ -200,3 +200,8 @@ obj-$(CONFIG_ASYMMETRIC_KEY_TYPE) += asymmetric_keys/ obj-$(CONFIG_CRYPTO_HASH_INFO) += hash_info.o crypto_simd-y := simd.o obj-$(CONFIG_CRYPTO_SIMD) += crypto_simd.o + +# +# Key derivation function +# +obj-$(CONFIG_CRYPTO_KDF800108_CTR) += kdf_sp800108.o diff --git a/crypto/kdf_sp800108.c b/crypto/kdf_sp800108.c new file mode 100644 index 000000000000..58edf7797abf --- /dev/null +++ b/crypto/kdf_sp800108.c @@ -0,0 +1,153 @@ +// SPDX-License-Identifier: GPL-2.0 + +/* + * SP800-108 Key-derivation function + * + * Copyright (C) 2021, Stephan Mueller + */ + +#include +#include +#include +#include + +/* + * SP800-108 CTR KDF implementation + */ +int crypto_kdf108_ctr_generate(struct crypto_shash *kmd, + const struct kvec *info, unsigned int info_nvec, + u8 *dst, unsigned int dlen) +{ + SHASH_DESC_ON_STACK(desc, kmd); + __be32 counter = cpu_to_be32(1); + const unsigned int h = crypto_shash_digestsize(kmd), dlen_orig = dlen; + unsigned int i; + int err = 0; + u8 *dst_orig = dst; + + desc->tfm = kmd; + + while (dlen) { + err = crypto_shash_init(desc); + if (err) + goto out; + + err = crypto_shash_update(desc, (u8 *)&counter, sizeof(__be32)); + if (err) + goto out; + + for (i = 0; i < info_nvec; i++) { + err = crypto_shash_update(desc, info[i].iov_base, + info[i].iov_len); + if (err) + goto out; + } + + if (dlen < h) { + u8 tmpbuffer[HASH_MAX_DIGESTSIZE]; + + err = crypto_shash_final(desc, tmpbuffer); + if (err) + goto out; + memcpy(dst, tmpbuffer, dlen); + memzero_explicit(tmpbuffer, h); + goto out; + } + + err = crypto_shash_final(desc, dst); + if (err) + goto out; + + dlen -= h; + dst += h; + counter = cpu_to_be32(be32_to_cpu(counter) + 1); + } + +out: + if (err) + memzero_explicit(dst_orig, dlen_orig); + shash_desc_zero(desc); + return err; +} +EXPORT_SYMBOL(crypto_kdf108_ctr_generate); + +/* + * The seeding of the KDF + */ +int crypto_kdf108_setkey(struct crypto_shash *kmd, + const u8 *key, size_t keylen, + const u8 *ikm, size_t ikmlen) +{ + unsigned int ds = crypto_shash_digestsize(kmd); + + /* SP800-108 does not support IKM */ + if (ikm || ikmlen) + return -EINVAL; + + /* Check according to SP800-108 section 7.2 */ + if (ds > keylen) + return -EINVAL; + + /* Set the key for the MAC used for the KDF. */ + return crypto_shash_setkey(kmd, key, keylen); +} +EXPORT_SYMBOL(crypto_kdf108_setkey); + +/* + * Test vector obtained from + * http://csrc.nist.gov/groups/STM/cavp/documents/KBKDF800-108/CounterMode.zip + */ +static const struct kdf_testvec kdf_ctr_hmac_sha256_tv_template[] = { + { + .key = "\xdd\x1d\x91\xb7\xd9\x0b\x2b\xd3" + "\x13\x85\x33\xce\x92\xb2\x72\xfb" + "\xf8\xa3\x69\x31\x6a\xef\xe2\x42" + "\xe6\x59\xcc\x0a\xe2\x38\xaf\xe0", + .keylen = 32, + .ikm = NULL, + .ikmlen = 0, + .info = { + .iov_base = "\x01\x32\x2b\x96\xb3\x0a\xcd\x19" + "\x79\x79\x44\x4e\x46\x8e\x1c\x5c" + "\x68\x59\xbf\x1b\x1c\xf9\x51\xb7" + "\xe7\x25\x30\x3e\x23\x7e\x46\xb8" + "\x64\xa1\x45\xfa\xb2\x5e\x51\x7b" + "\x08\xf8\x68\x3d\x03\x15\xbb\x29" + "\x11\xd8\x0a\x0e\x8a\xba\x17\xf3" + "\xb4\x13\xfa\xac", + .iov_len = 60 + }, + .expected = "\x10\x62\x13\x42\xbf\xb0\xfd\x40" + "\x04\x6c\x0e\x29\xf2\xcf\xdb\xf0", + .expectedlen = 16 + } +}; + +static int __init crypto_kdf108_init(void) +{ + int ret = kdf_test(&kdf_ctr_hmac_sha256_tv_template[0], "hmac(sha256)", + crypto_kdf108_setkey, crypto_kdf108_ctr_generate); + + if (ret) { + if (fips_enabled) + panic("alg: self-tests for CTR-KDF (hmac(sha256)) failed (rc=%d)\n", + ret); + + WARN(1, + "alg: self-tests for CTR-KDF (hmac(sha256)) failed (rc=%d)\n", + ret); + } else { + pr_info("alg: self-tests for CTR-KDF (hmac(sha256)) passed\n"); + } + + return ret; +} + +static void __exit crypto_kdf108_exit(void) { } + +module_init(crypto_kdf108_init); +module_exit(crypto_kdf108_exit); + +MODULE_LICENSE("GPL v2"); +MODULE_AUTHOR("Stephan Mueller "); +MODULE_DESCRIPTION("Key Derivation Function conformant to SP800-108"); diff --git a/include/crypto/kdf_sp800108.h b/include/crypto/kdf_sp800108.h new file mode 100644 index 000000000000..b7b20a778fb7 --- /dev/null +++ b/include/crypto/kdf_sp800108.h @@ -0,0 +1,61 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +/* + * Copyright (C) 2021, Stephan Mueller + */ + +#ifndef _CRYPTO_KDF108_H +#define _CRYPTO_KDF108_H + +#include +#include + +/** + * Counter KDF generate operation according to SP800-108 section 5.1 + * as well as SP800-56A section 5.8.1 (Single-step KDF). + * + * @kmd Keyed message digest whose key was set with crypto_kdf108_setkey or + * unkeyed message digest + * @info optional context and application specific information - this may be + * NULL + * @info_vec number of optional context/application specific information entries + * @dst destination buffer that the caller already allocated + * @dlen length of the destination buffer - the KDF derives that amount of + * bytes. + * + * To comply with SP800-108, the caller must provide Label || 0x00 || Context + * in the info parameter. + * + * @return 0 on success, < 0 on error + */ +int crypto_kdf108_ctr_generate(struct crypto_shash *kmd, + const struct kvec *info, unsigned int info_nvec, + u8 *dst, unsigned int dlen); + +/** + * Counter KDF setkey operation + * + * @kmd Keyed message digest allocated by the caller. The key should not have + * been set. + * @key Seed key to be used to initialize the keyed message digest context. + * @keylen This length of the key buffer. + * @ikm The SP800-108 KDF does not support IKM - this parameter must be NULL + * @ikmlen This parameter must be 0. + * + * According to SP800-108 section 7.2, the seed key must be at least as large as + * the message digest size of the used keyed message digest. This limitation + * is enforced by the implementation. + * + * SP800-108 allows the use of either a HMAC or a hash primitive. When + * the caller intends to use a hash primitive, the call to + * crypto_kdf108_setkey is not required and the key derivation operation can + * immediately performed using crypto_kdf108_ctr_generate after allocating + * a handle. + * + * @return 0 on success, < 0 on error + */ +int crypto_kdf108_setkey(struct crypto_shash *kmd, + const u8 *key, size_t keylen, + const u8 *ikm, size_t ikmlen); + +#endif /* _CRYPTO_KDF108_H */ From patchwork Fri Nov 19 06:58:44 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stephan Mueller X-Patchwork-Id: 12628333 X-Patchwork-Delegate: herbert@gondor.apana.org.au Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7223DC433FE for ; Fri, 19 Nov 2021 06:59:26 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 5951A61175 for ; Fri, 19 Nov 2021 06:59:26 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231797AbhKSHC0 (ORCPT ); Fri, 19 Nov 2021 02:02:26 -0500 Received: from mo4-p01-ob.smtp.rzone.de ([81.169.146.164]:12406 "EHLO mo4-p01-ob.smtp.rzone.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231264AbhKSHC0 (ORCPT ); Fri, 19 Nov 2021 02:02:26 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; t=1637305163; s=strato-dkim-0002; d=chronox.de; h=References:In-Reply-To:Message-ID:Date:Subject:Cc:To:From:Cc:Date: From:Subject:Sender; bh=O/YcdRCsAW4PWbVTFX7FFzo3cfU7U3Y7Cmf6XywN7qA=; b=fOjift2vSfiZ3UFSL4YV5f8UjiD4U2Edc8x1ceM5nv/q0tx1WLekCaKjpWm2LcPueZ YXDOSvTONB82jRPGFjJgopheE2yYkA69u2Hy1kZ1xOiP/1184x+zQeHiHvD3/HRsmm/n hiMpQpFbUf4tfI2F8lwiEcUQPvsKueln8ueoYtpkU3x8HLj62cJGHFCFsuwM/ZJDOcrr 7ClJ3vyt6ZWlk1/u4B6qBCmHzhcJVI2jnk/HCBbg1GAa5GEmxNb7ASAtRQhBNbWSpN3k O25xACKG0afwIgucxrVHIjHhsl8hupVoKdoKnt2wVgS8B+b/Jjrrso6cG+oiCh0gSFnQ 3KvQ== Authentication-Results: strato.com; dkim=none X-RZG-AUTH: ":P2ERcEykfu11Y98lp/T7+hdri+uKZK8TKWEqNyiHySGSa9k9xmwdNnzGHXPZJ/SWpaI=" X-RZG-CLASS-ID: mo00 Received: from positron.chronox.de by smtp.strato.de (RZmta 47.34.5 DYNA|AUTH) with ESMTPSA id U02dfbxAJ6xMu3y (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256 bits)) (Client did not present a certificate); Fri, 19 Nov 2021 07:59:22 +0100 (CET) From: Stephan =?iso-8859-1?q?M=FCller?= To: herbert@gondor.apana.org.au Cc: ebiggers@kernel.org, jarkko@kernel.org, Mat Martineau , dhowells@redhat.com, linux-kernel@vger.kernel.org, linux-crypto@vger.kernel.org, keyrings@vger.kernel.org, simo@redhat.com Subject: [PATCH v4 3/4] security: DH - remove dead code for zero padding Date: Fri, 19 Nov 2021 07:58:44 +0100 Message-ID: <20729897.4csPzL39Zc@positron.chronox.de> In-Reply-To: <4642773.OV4Wx5bFTl@positron.chronox.de> References: <4642773.OV4Wx5bFTl@positron.chronox.de> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-crypto@vger.kernel.org Remove the specific code that adds a zero padding that was intended to be invoked when the DH operation result was smaller than the modulus. However, this cannot occur any more these days because the function mpi_write_to_sgl is used in the code path that calculates the shared secret in dh_compute_value. This MPI service function guarantees that leading zeros are introduced as needed to ensure the resulting data is exactly as long as the modulus. This implies that the specific code to add zero padding is dead code which can be safely removed. Signed-off-by: Stephan Mueller Acked-by: Mat Martineau --- security/keys/dh.c | 25 ++++--------------------- 1 file changed, 4 insertions(+), 21 deletions(-) diff --git a/security/keys/dh.c b/security/keys/dh.c index 1abfa70ed6e1..56e12dae4534 100644 --- a/security/keys/dh.c +++ b/security/keys/dh.c @@ -141,7 +141,7 @@ static void kdf_dealloc(struct kdf_sdesc *sdesc) * 'dlen' must be a multiple of the digest size. */ static int kdf_ctr(struct kdf_sdesc *sdesc, const u8 *src, unsigned int slen, - u8 *dst, unsigned int dlen, unsigned int zlen) + u8 *dst, unsigned int dlen) { struct shash_desc *desc = &sdesc->shash; unsigned int h = crypto_shash_digestsize(desc->tfm); @@ -158,22 +158,6 @@ static int kdf_ctr(struct kdf_sdesc *sdesc, const u8 *src, unsigned int slen, if (err) goto err; - if (zlen && h) { - u8 tmpbuffer[32]; - size_t chunk = min_t(size_t, zlen, sizeof(tmpbuffer)); - memset(tmpbuffer, 0, chunk); - - do { - err = crypto_shash_update(desc, tmpbuffer, - chunk); - if (err) - goto err; - - zlen -= chunk; - chunk = min_t(size_t, zlen, sizeof(tmpbuffer)); - } while (zlen); - } - if (src && slen) { err = crypto_shash_update(desc, src, slen); if (err) @@ -198,7 +182,7 @@ static int kdf_ctr(struct kdf_sdesc *sdesc, const u8 *src, unsigned int slen, static int keyctl_dh_compute_kdf(struct kdf_sdesc *sdesc, char __user *buffer, size_t buflen, - uint8_t *kbuf, size_t kbuflen, size_t lzero) + uint8_t *kbuf, size_t kbuflen) { uint8_t *outbuf = NULL; int ret; @@ -211,7 +195,7 @@ static int keyctl_dh_compute_kdf(struct kdf_sdesc *sdesc, goto err; } - ret = kdf_ctr(sdesc, kbuf, kbuflen, outbuf, outbuf_len, lzero); + ret = kdf_ctr(sdesc, kbuf, kbuflen, outbuf, outbuf_len); if (ret) goto err; @@ -384,8 +368,7 @@ long __keyctl_dh_compute(struct keyctl_dh_params __user *params, } ret = keyctl_dh_compute_kdf(sdesc, buffer, buflen, outbuf, - req->dst_len + kdfcopy->otherinfolen, - outlen - req->dst_len); + req->dst_len + kdfcopy->otherinfolen); } else if (copy_to_user(buffer, outbuf, req->dst_len) == 0) { ret = req->dst_len; } else { From patchwork Fri Nov 19 06:59:09 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stephan Mueller X-Patchwork-Id: 12628335 X-Patchwork-Delegate: herbert@gondor.apana.org.au Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 343E7C43219 for ; Fri, 19 Nov 2021 06:59:28 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 2036B61B73 for ; Fri, 19 Nov 2021 06:59:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232606AbhKSHC0 (ORCPT ); Fri, 19 Nov 2021 02:02:26 -0500 Received: from mo4-p01-ob.smtp.rzone.de ([81.169.146.165]:27354 "EHLO mo4-p01-ob.smtp.rzone.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231217AbhKSHC0 (ORCPT ); Fri, 19 Nov 2021 02:02:26 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; t=1637305162; s=strato-dkim-0002; d=chronox.de; h=References:In-Reply-To:Message-ID:Date:Subject:Cc:To:From:Cc:Date: From:Subject:Sender; bh=HW9zWqa9H2eD+qVa36LN1OE2n4xyHBwnxzNW7IQv8J4=; b=bfNhvpNz2M8hY5eh60HqIuDMp1dKTSiVVZWLL2I3DB2NH3Z4gWyV09H8IQE54np0cB 8QSJxpqoM0Fojn2ga/SAVEMIMPittgLRisx5ntBq7fgqa23DvNACzVN56xg9efu7HLwf O2QgUoUUwtUw7tTRQawTM/kN1YecHuQwpJgq+fVfe5ul04D9uE2n1Lv9MVXzeyrBeizt 34n3OuOuJOCQOQu6+N7vVZkAOZaADi+Mk09uY6EJpFP9wMCWfse8QP586d8X2ddEnmOy zFhmyBS6Fp3Ja/5jBx/R5RhJq4j698IQPaK+35H/NlakxOpGfOZJxWClMVCh1fTyJa+7 2iBg== Authentication-Results: strato.com; dkim=none X-RZG-AUTH: ":P2ERcEykfu11Y98lp/T7+hdri+uKZK8TKWEqNyiHySGSa9k9xmwdNnzGHXPZJ/SWpaI=" X-RZG-CLASS-ID: mo00 Received: from positron.chronox.de by smtp.strato.de (RZmta 47.34.5 DYNA|AUTH) with ESMTPSA id U02dfbxAJ6xLu3w (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256 bits)) (Client did not present a certificate); Fri, 19 Nov 2021 07:59:21 +0100 (CET) From: Stephan =?iso-8859-1?q?M=FCller?= To: herbert@gondor.apana.org.au Cc: ebiggers@kernel.org, jarkko@kernel.org, Mat Martineau , dhowells@redhat.com, linux-kernel@vger.kernel.org, linux-crypto@vger.kernel.org, keyrings@vger.kernel.org, simo@redhat.com Subject: [PATCH v4 4/4] security: DH - use KDF implementation from crypto API Date: Fri, 19 Nov 2021 07:59:09 +0100 Message-ID: <4181314.UPlyArG6xL@positron.chronox.de> In-Reply-To: <4642773.OV4Wx5bFTl@positron.chronox.de> References: <4642773.OV4Wx5bFTl@positron.chronox.de> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-crypto@vger.kernel.org The kernel crypto API provides the SP800-108 counter KDF implementation. Thus, the separate implementation provided as part of the keys subsystem can be replaced with calls to the KDF offered by the kernel crypto API. The keys subsystem uses the counter KDF with a hash primitive. Thus, it only uses the call to crypto_kdf108_ctr_generate. Signed-off-by: Stephan Mueller Acked-by: Mat Martineau --- security/keys/Kconfig | 2 +- security/keys/dh.c | 109 +++++++----------------------------------- 2 files changed, 19 insertions(+), 92 deletions(-) diff --git a/security/keys/Kconfig b/security/keys/Kconfig index 64b81abd087e..969122c7b92f 100644 --- a/security/keys/Kconfig +++ b/security/keys/Kconfig @@ -109,7 +109,7 @@ config KEY_DH_OPERATIONS bool "Diffie-Hellman operations on retained keys" depends on KEYS select CRYPTO - select CRYPTO_HASH + select CRYPTO_KDF800108_CTR select CRYPTO_DH help This option provides support for calculating Diffie-Hellman diff --git a/security/keys/dh.c b/security/keys/dh.c index 56e12dae4534..4573fc15617d 100644 --- a/security/keys/dh.c +++ b/security/keys/dh.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include "internal.h" @@ -79,17 +80,9 @@ static void dh_crypto_done(struct crypto_async_request *req, int err) complete(&compl->completion); } -struct kdf_sdesc { - struct shash_desc shash; - char ctx[]; -}; - -static int kdf_alloc(struct kdf_sdesc **sdesc_ret, char *hashname) +static int kdf_alloc(struct crypto_shash **hash, char *hashname) { struct crypto_shash *tfm; - struct kdf_sdesc *sdesc; - int size; - int err; /* allocate synchronous hash */ tfm = crypto_alloc_shash(hashname, 0, 0); @@ -98,96 +91,30 @@ static int kdf_alloc(struct kdf_sdesc **sdesc_ret, char *hashname) return PTR_ERR(tfm); } - err = -EINVAL; - if (crypto_shash_digestsize(tfm) == 0) - goto out_free_tfm; - - err = -ENOMEM; - size = sizeof(struct shash_desc) + crypto_shash_descsize(tfm); - sdesc = kmalloc(size, GFP_KERNEL); - if (!sdesc) - goto out_free_tfm; - sdesc->shash.tfm = tfm; + if (crypto_shash_digestsize(tfm) == 0) { + crypto_free_shash(tfm); + return -EINVAL; + } - *sdesc_ret = sdesc; + *hash = tfm; return 0; - -out_free_tfm: - crypto_free_shash(tfm); - return err; } -static void kdf_dealloc(struct kdf_sdesc *sdesc) +static void kdf_dealloc(struct crypto_shash *hash) { - if (!sdesc) - return; - - if (sdesc->shash.tfm) - crypto_free_shash(sdesc->shash.tfm); - - kfree_sensitive(sdesc); -} - -/* - * Implementation of the KDF in counter mode according to SP800-108 section 5.1 - * as well as SP800-56A section 5.8.1 (Single-step KDF). - * - * SP800-56A: - * The src pointer is defined as Z || other info where Z is the shared secret - * from DH and other info is an arbitrary string (see SP800-56A section - * 5.8.1.2). - * - * 'dlen' must be a multiple of the digest size. - */ -static int kdf_ctr(struct kdf_sdesc *sdesc, const u8 *src, unsigned int slen, - u8 *dst, unsigned int dlen) -{ - struct shash_desc *desc = &sdesc->shash; - unsigned int h = crypto_shash_digestsize(desc->tfm); - int err = 0; - u8 *dst_orig = dst; - __be32 counter = cpu_to_be32(1); - - while (dlen) { - err = crypto_shash_init(desc); - if (err) - goto err; - - err = crypto_shash_update(desc, (u8 *)&counter, sizeof(__be32)); - if (err) - goto err; - - if (src && slen) { - err = crypto_shash_update(desc, src, slen); - if (err) - goto err; - } - - err = crypto_shash_final(desc, dst); - if (err) - goto err; - - dlen -= h; - dst += h; - counter = cpu_to_be32(be32_to_cpu(counter) + 1); - } - - return 0; - -err: - memzero_explicit(dst_orig, dlen); - return err; + if (hash) + crypto_free_shash(hash); } -static int keyctl_dh_compute_kdf(struct kdf_sdesc *sdesc, +static int keyctl_dh_compute_kdf(struct crypto_shash *hash, char __user *buffer, size_t buflen, uint8_t *kbuf, size_t kbuflen) { + struct kvec kbuf_iov = { .iov_base = kbuf, .iov_len = kbuflen }; uint8_t *outbuf = NULL; int ret; - size_t outbuf_len = roundup(buflen, - crypto_shash_digestsize(sdesc->shash.tfm)); + size_t outbuf_len = roundup(buflen, crypto_shash_digestsize(hash)); outbuf = kmalloc(outbuf_len, GFP_KERNEL); if (!outbuf) { @@ -195,7 +122,7 @@ static int keyctl_dh_compute_kdf(struct kdf_sdesc *sdesc, goto err; } - ret = kdf_ctr(sdesc, kbuf, kbuflen, outbuf, outbuf_len); + ret = crypto_kdf108_ctr_generate(hash, &kbuf_iov, 1, outbuf, outbuf_len); if (ret) goto err; @@ -224,7 +151,7 @@ long __keyctl_dh_compute(struct keyctl_dh_params __user *params, struct kpp_request *req; uint8_t *secret; uint8_t *outbuf; - struct kdf_sdesc *sdesc = NULL; + struct crypto_shash *hash = NULL; if (!params || (!buffer && buflen)) { ret = -EINVAL; @@ -257,7 +184,7 @@ long __keyctl_dh_compute(struct keyctl_dh_params __user *params, } /* allocate KDF from the kernel crypto API */ - ret = kdf_alloc(&sdesc, hashname); + ret = kdf_alloc(&hash, hashname); kfree(hashname); if (ret) goto out1; @@ -367,7 +294,7 @@ long __keyctl_dh_compute(struct keyctl_dh_params __user *params, goto out6; } - ret = keyctl_dh_compute_kdf(sdesc, buffer, buflen, outbuf, + ret = keyctl_dh_compute_kdf(hash, buffer, buflen, outbuf, req->dst_len + kdfcopy->otherinfolen); } else if (copy_to_user(buffer, outbuf, req->dst_len) == 0) { ret = req->dst_len; @@ -386,7 +313,7 @@ long __keyctl_dh_compute(struct keyctl_dh_params __user *params, out2: dh_free_data(&dh_inputs); out1: - kdf_dealloc(sdesc); + kdf_dealloc(hash); return ret; }