From patchwork Wed Jan 16 11:07:34 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stephan Mueller X-Patchwork-Id: 10765763 X-Patchwork-Delegate: herbert@gondor.apana.org.au Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id D9F9E13BF for ; Wed, 16 Jan 2019 11:12:30 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C97532C440 for ; Wed, 16 Jan 2019 11:12:30 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id BD9C82D4BE; Wed, 16 Jan 2019 11:12:30 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.7 required=2.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 4FC7F2C279 for ; Wed, 16 Jan 2019 11:12:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2392401AbfAPLMY (ORCPT ); Wed, 16 Jan 2019 06:12:24 -0500 Received: from mo4-p03-ob.smtp.rzone.de ([85.215.255.104]:26740 "EHLO mo4-p03-ob.smtp.rzone.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2389696AbfAPLMC (ORCPT ); Wed, 16 Jan 2019 06:12:02 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; t=1547637119; s=strato-dkim-0002; d=chronox.de; h=References:In-Reply-To:Message-ID:Date:Subject:Cc:To:From: X-RZG-CLASS-ID:X-RZG-AUTH:From:Subject:Sender; bh=pSfduHW8di1A56/Fcff8gBYrw/e7p9TbH/mFZ8R2KMQ=; b=P/TRbXXWA4LEkLQ0T188OtZ1APiZ4lc6V0l7tgCR/oP9igZvP0eCy3F0/I/s+oRFHu DpMoNhUo9xSnGQal7JKvF4tnFtUfHUHkAm1DBgHcBS9fyWCd0WLbBEM0/c17P5E/zc7t Hu+j3rxQnSplrFXmRpkasddFEF17lxwRZ54dKgG2ZmkGys93dVseJHhLvOAvVBoms8ms TGuTmH6jpskSxaERLroDx1vC57HSHiEECPDOD7Mu16Z4yYN10v39crpU0tAAfzIqOvL0 nk5gqpwUhHTv5FlQsxJbroHYMHod/VUAi85TlT/IM74tm0Hf54vwUMMgkjpKhu6QHXXp I6nQ== X-RZG-AUTH: ":P2ERcEykfu11Y98lp/T7+hdri+uKZK8TKWEqNyiHySGSa9k9yWgdNs16dfA/c7fW145n" X-RZG-CLASS-ID: mo00 Received: from positron.chronox.de by smtp.strato.de (RZmta 44.9 AUTH) with ESMTPSA id 309bcfv0GBBg4Ne (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (curve secp521r1 with 521 ECDH bits, eq. 15360 bits RSA)) (Client did not present a certificate); Wed, 16 Jan 2019 12:11:42 +0100 (CET) From: Stephan =?iso-8859-1?q?M=FCller?= To: Herbert Xu Cc: Eric Biggers , James Bottomley , Andy Lutomirski , "Lee, Chun-Yi" , "Rafael J . Wysocki" , Pavel Machek , linux-kernel@vger.kernel.org, linux-pm@vger.kernel.org, keyrings@vger.kernel.org, "Rafael J. Wysocki" , Chen Yu , Oliver Neukum , Ryan Chen , David Howells , Giovanni Gherdovich , Randy Dunlap , Jann Horn , Andy Lutomirski , linux-crypto@vger.kernel.org Subject: [PATCH v2 1/6] crypto: add template handling for RNGs Date: Wed, 16 Jan 2019 12:07:34 +0100 Message-ID: <61907509.O7QvflLhaU@positron.chronox.de> In-Reply-To: <2082192.jPI8ve1O8G@positron.chronox.de> References: <20190103143227.9138-1-jlee@suse.com> <9733066.Vrs4h5eWcW@positron.chronox.de> <2082192.jPI8ve1O8G@positron.chronox.de> MIME-Version: 1.0 Sender: linux-crypto-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-crypto@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Adds ability to register templates for pseudo random number generators (PRNG). PRNGs are "meta" mechanisms using raw cipher primitives. Thus, PRNGs can now be implemented as templates to allow the complete flexibility the kernel crypto API provides. The RNG API provides access to the PRNG algorithms without an entropy management. Signed-off-by: Stephan Mueller --- crypto/rng.c | 44 +++++++++++++++++++++++++++++++++++ include/crypto/internal/rng.h | 26 +++++++++++++++++++++ 2 files changed, 70 insertions(+) diff --git a/crypto/rng.c b/crypto/rng.c index 33c38a72bff5..da4fd03c0acd 100644 --- a/crypto/rng.c +++ b/crypto/rng.c @@ -64,6 +64,25 @@ static int crypto_rng_init_tfm(struct crypto_tfm *tfm) return 0; } +static inline struct rng_alg *__crypto_rng_alg(struct crypto_alg *alg) +{ + return container_of(alg, struct rng_alg, base); +} + +static inline struct rng_instance *rng_instance( + struct crypto_instance *inst) +{ + return container_of(__crypto_rng_alg(&inst->alg), + struct rng_instance, alg); +} + +static void crypto_rng_free_instance(struct crypto_instance *inst) +{ + struct rng_instance *rng = rng_instance(inst); + + rng->free(rng); +} + static unsigned int seedsize(struct crypto_alg *alg) { struct rng_alg *ralg = container_of(alg, struct rng_alg, base); @@ -102,6 +121,7 @@ static void crypto_rng_show(struct seq_file *m, struct crypto_alg *alg) static const struct crypto_type crypto_rng_type = { .extsize = crypto_alg_extsize, .init_tfm = crypto_rng_init_tfm, + .free = crypto_rng_free_instance, #ifdef CONFIG_PROC_FS .show = crypto_rng_show, #endif @@ -229,5 +249,29 @@ void crypto_unregister_rngs(struct rng_alg *algs, int count) } EXPORT_SYMBOL_GPL(crypto_unregister_rngs); +static int rng_prepare_alg(struct rng_alg *alg) +{ + struct crypto_alg *base = &alg->base; + + base->cra_type = &crypto_rng_type; + base->cra_flags &= ~CRYPTO_ALG_TYPE_MASK; + base->cra_flags |= CRYPTO_ALG_TYPE_RNG; + + return 0; +} + +int rng_register_instance(struct crypto_template *tmpl, + struct rng_instance *inst) +{ + int err; + + err = rng_prepare_alg(&inst->alg); + if (err) + return err; + + return crypto_register_instance(tmpl, rng_crypto_instance(inst)); +} +EXPORT_SYMBOL_GPL(rng_register_instance); + MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Random Number Generator"); diff --git a/include/crypto/internal/rng.h b/include/crypto/internal/rng.h index a52ef3483dd7..bfe4482ad336 100644 --- a/include/crypto/internal/rng.h +++ b/include/crypto/internal/rng.h @@ -42,4 +42,30 @@ static inline void crypto_rng_set_entropy(struct crypto_rng *tfm, crypto_rng_alg(tfm)->set_ent(tfm, data, len); } +struct rng_instance { + void (*free)(struct rng_instance *inst); + struct rng_alg alg; +}; + +static inline struct rng_instance *rng_alloc_instance( + const char *name, struct crypto_alg *alg) +{ + return crypto_alloc_instance(name, alg, + sizeof(struct rng_instance) - sizeof(*alg)); +} + +static inline struct crypto_instance *rng_crypto_instance( + struct rng_instance *inst) +{ + return container_of(&inst->alg.base, struct crypto_instance, alg); +} + +static inline void *rng_instance_ctx(struct rng_instance *inst) +{ + return crypto_instance_ctx(rng_crypto_instance(inst)); +} + +int rng_register_instance(struct crypto_template *tmpl, + struct rng_instance *inst); + #endif From patchwork Wed Jan 16 11:08:04 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stephan Mueller X-Patchwork-Id: 10765761 X-Patchwork-Delegate: herbert@gondor.apana.org.au Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id AA5C01580 for ; Wed, 16 Jan 2019 11:12:23 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 98D1F2C426 for ; Wed, 16 Jan 2019 11:12:23 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 962D02DA3B; Wed, 16 Jan 2019 11:12:23 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.7 required=2.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 63AA22D00B for ; Wed, 16 Jan 2019 11:12:22 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2392404AbfAPLMD (ORCPT ); Wed, 16 Jan 2019 06:12:03 -0500 Received: from mo4-p03-ob.smtp.rzone.de ([85.215.255.101]:19671 "EHLO mo4-p03-ob.smtp.rzone.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2389691AbfAPLMD (ORCPT ); Wed, 16 Jan 2019 06:12:03 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; t=1547637117; s=strato-dkim-0002; d=chronox.de; h=References:In-Reply-To:Message-ID:Date:Subject:Cc:To:From: X-RZG-CLASS-ID:X-RZG-AUTH:From:Subject:Sender; bh=GQJhTmUnOqxfkRSVM1X0DzZ3XYX0KegWrMkfp5PBcdE=; b=URAhe/tTipmMO6cawSEG0REnQ5Il6LMIr7zLq+ZN+/NsYqVo1/1a+iYgD3+PufPNqD l/5bAbCTQERu7D/kcq4DUunrWiTOWEwT8RKHQvndx6+2TOoy8748+Lt/wwQIv1u4vaz7 eRFz7H/pbfV1Tqi1Hizq31+RmAbx3kx9BagXGGGuUfwfjzYLeqc3vqT82JvhWEX7gD7o RIl/zXanQx7Fc20Azuanagb5XxbyPDkgTE9KB0mSwF0uoGjZA+39XWDybpWhs2rzCZLh 4dQ1M0spLRR8/BCDlEamKUJflRfQOiEDjtQRuK4P2KFq8slktgJBeuGrFR1fhqSTnobS zbdA== X-RZG-AUTH: ":P2ERcEykfu11Y98lp/T7+hdri+uKZK8TKWEqNyiHySGSa9k9yWgdNs16dfA/c7fW145n" X-RZG-CLASS-ID: mo00 Received: from positron.chronox.de by smtp.strato.de (RZmta 44.9 AUTH) with ESMTPSA id 309bcfv0GBBb4Nb (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (curve secp521r1 with 521 ECDH bits, eq. 15360 bits RSA)) (Client did not present a certificate); Wed, 16 Jan 2019 12:11:37 +0100 (CET) From: Stephan =?iso-8859-1?q?M=FCller?= To: Herbert Xu Cc: Eric Biggers , James Bottomley , Andy Lutomirski , "Lee, Chun-Yi" , "Rafael J . Wysocki" , Pavel Machek , linux-kernel@vger.kernel.org, linux-pm@vger.kernel.org, keyrings@vger.kernel.org, "Rafael J. Wysocki" , Chen Yu , Oliver Neukum , Ryan Chen , David Howells , Giovanni Gherdovich , Randy Dunlap , Jann Horn , Andy Lutomirski , linux-crypto@vger.kernel.org Subject: [PATCH v2 2/6] crypto: kdf - SP800-108 Key Derivation Function Date: Wed, 16 Jan 2019 12:08:04 +0100 Message-ID: <2831352.yMFniVK4cV@positron.chronox.de> In-Reply-To: <2082192.jPI8ve1O8G@positron.chronox.de> References: <20190103143227.9138-1-jlee@suse.com> <9733066.Vrs4h5eWcW@positron.chronox.de> <2082192.jPI8ve1O8G@positron.chronox.de> MIME-Version: 1.0 Sender: linux-crypto-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-crypto@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP The SP800-108 compliant Key Derivation Function provides three KDF types which are all implemented, including the counter-based KDF, the double-pipeline KDF and the feedback KDF. The code comments provide details about how to invoke the different KDF types. Signed-off-by: Stephan Mueller --- crypto/Kconfig | 7 + crypto/Makefile | 1 + crypto/kdf_sp800108.c | 491 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 499 insertions(+) create mode 100644 crypto/kdf_sp800108.c diff --git a/crypto/Kconfig b/crypto/Kconfig index 86960aa53e0f..7c0336c9ba9c 100644 --- a/crypto/Kconfig +++ b/crypto/Kconfig @@ -561,6 +561,13 @@ config CRYPTO_HMAC HMAC: Keyed-Hashing for Message Authentication (RFC2104). This is required for IPSec. +config CRYPTO_KDF_SP800108 + tristate "Key Derivation Function (SP800-108)" + select CRYPTO_RNG + help + Support for KDF compliant to SP800-108. All three types of + KDF specified in SP800-108 are implemented. + config CRYPTO_XCBC tristate "XCBC support" select CRYPTO_HASH diff --git a/crypto/Makefile b/crypto/Makefile index 799ed5e94606..eead7ec9fd8e 100644 --- a/crypto/Makefile +++ b/crypto/Makefile @@ -58,6 +58,7 @@ crypto_user-y := crypto_user_base.o crypto_user-$(CONFIG_CRYPTO_STATS) += crypto_user_stat.o obj-$(CONFIG_CRYPTO_CMAC) += cmac.o obj-$(CONFIG_CRYPTO_HMAC) += hmac.o +obj-$(CONFIG_CRYPTO_KDF_SP800108) += kdf_sp800108.o obj-$(CONFIG_CRYPTO_VMAC) += vmac.o obj-$(CONFIG_CRYPTO_XCBC) += xcbc.o obj-$(CONFIG_CRYPTO_NULL2) += crypto_null.o diff --git a/crypto/kdf_sp800108.c b/crypto/kdf_sp800108.c new file mode 100644 index 000000000000..33b26659afa7 --- /dev/null +++ b/crypto/kdf_sp800108.c @@ -0,0 +1,491 @@ +// SPDX-License-Identifier: GPL-2.0 + +/* + * SP800-108 Key-derivation function + * + * Copyright (C) 2019, Stephan Mueller + */ + +/* + * For performing a KDF operation, the following input is required + * from the caller: + * + * * Keying material to be used to derive the new keys from + * (denoted as Ko in SP800-108) + * * Label -- a free form binary string + * * Context -- a free form binary string + * + * The KDF is implemented as a random number generator. + * + * The Ko keying material is to be provided with the initialization of the KDF + * "random number generator", i.e. with the crypto_rng_reset function. + * + * The Label and Context concatenated string is provided when obtaining random + * numbers, i.e. with the crypto_rng_generate function. The caller must format + * the free-form Label || Context input as deemed necessary for the given + * purpose. Note, SP800-108 mandates that the Label and Context are separated + * by a 0x00 byte, i.e. the caller shall provide the input as + * Label || 0x00 || Context when trying to be compliant to SP800-108. For + * the feedback KDF, an IV is required as documented below. + * + * Example without proper error handling: + * char *keying_material = "\x00\x11\x22\x33\x44\x55\x66\x77"; + * char *label_context = "\xde\xad\xbe\xef\x00\xde\xad\xbe\xef"; + * kdf = crypto_alloc_rng(name, 0, 0); + * crypto_rng_reset(kdf, keying_material, 8); + * crypto_rng_generate(kdf, label_context, 9, outbuf, outbuflen); + */ + +#include +#include +#include +#include +#include + +struct crypto_kdf_ctx { + struct crypto_shash *kmd; +}; + +#define CRYPTO_KDF_MAX_DIGESTSIZE 64 +#define CRYPTO_KDF_MAX_ALIGNMASK 0x3f + +static inline void crypto_kdf_init_desc(struct shash_desc *desc, + struct crypto_shash *kmd) +{ + desc->tfm = kmd; + desc->flags = 0; +} + +/* + * Implementation of the KDF in double pipeline iteration mode according with + * counter to SP800-108 section 5.3. + * + * The caller must provide Label || 0x00 || Context in src. This src pointer + * may also be NULL if the caller wishes not to provide anything. + */ +static int crypto_kdf_dpi_generate(struct crypto_rng *rng, + const u8 *src, unsigned int slen, + u8 *dst, unsigned int dlen) +{ + const struct crypto_kdf_ctx *ctx = crypto_tfm_ctx(crypto_rng_tfm(rng)); + struct crypto_shash *kmd = ctx->kmd; + SHASH_DESC_ON_STACK(desc, kmd); + __be32 counter = cpu_to_be32(1); + const unsigned int h = crypto_shash_digestsize(kmd); + const unsigned int alignmask = crypto_shash_alignmask(kmd); + int err = 0; + u8 *dst_orig = dst; + u8 Aiblock[CRYPTO_KDF_MAX_DIGESTSIZE + CRYPTO_KDF_MAX_ALIGNMASK]; + u8 *Ai = PTR_ALIGN((u8 *)Aiblock, alignmask + 1); + + crypto_kdf_init_desc(desc, kmd); + + memset(Ai, 0, h); + + while (dlen) { + /* Calculate A(i) */ + if (dst == dst_orig && src && slen) + /* 5.3 step 4 and 5.a */ + err = crypto_shash_digest(desc, src, slen, Ai); + else + /* 5.3 step 5.a */ + err = crypto_shash_digest(desc, Ai, h, Ai); + if (err) + goto out; + + /* Calculate K(i) -- step 5.b */ + err = crypto_shash_init(desc); + if (err) + goto out; + + err = crypto_shash_update(desc, Ai, h); + if (err) + goto out; + + err = crypto_shash_update(desc, (u8 *)&counter, sizeof(__be32)); + if (err) + goto out; + if (src && slen) { + err = crypto_shash_update(desc, src, slen); + if (err) + goto out; + } + + if (dlen < h) { + u8 tmpbuffer[CRYPTO_KDF_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); + shash_desc_zero(desc); + memzero_explicit(Ai, h); + return err; +} + +/* + * Implementation of the KDF in feedback mode with a non-NULL IV and with + * counter according to SP800-108 section 5.2. The IV is supplied with src + * and must be equal to the digestsize of the used keyed message digest. + * + * In addition, the caller must provide Label || 0x00 || Context in src. This + * src pointer must not be NULL as the IV is required. The ultimate format of + * the src pointer is IV || Label || 0x00 || Context where the length of the + * IV is equal to the output size of the PRF. + */ +static int crypto_kdf_fb_generate(struct crypto_rng *rng, + const u8 *src, unsigned int slen, + u8 *dst, unsigned int dlen) +{ + const struct crypto_kdf_ctx *ctx = crypto_tfm_ctx(crypto_rng_tfm(rng)); + struct crypto_shash *kmd = ctx->kmd; + SHASH_DESC_ON_STACK(desc, kmd); + __be32 counter = cpu_to_be32(1); + const unsigned int h = crypto_shash_digestsize(kmd); + unsigned int labellen = 0; + int err = 0; + u8 *dst_orig = dst; + const u8 *label; + + /* require the presence of an IV */ + if (!src || slen < h) + return -EINVAL; + + crypto_kdf_init_desc(desc, kmd); + + /* calculate the offset of the label / context data */ + label = src + h; + labellen = slen - h; + + while (dlen) { + err = crypto_shash_init(desc); + if (err) + goto out; + + /* + * Feedback mode applies to all rounds except first which uses + * the IV. + */ + if (dst_orig == dst) + err = crypto_shash_update(desc, src, h); + else + err = crypto_shash_update(desc, dst - h, h); + if (err) + goto out; + + err = crypto_shash_update(desc, (u8 *)&counter, sizeof(__be32)); + if (err) + goto out; + if (labellen) { + err = crypto_shash_update(desc, label, labellen); + if (err) + goto out; + } + + if (dlen < h) { + u8 tmpbuffer[CRYPTO_KDF_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); + return err; +} + +/* + * 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-108: + * The caller must provide Label || 0x00 || Context in src. This src pointer + * may also be NULL if the caller wishes not to provide anything. + * + * SP800-56A: + * The key provided for the HMAC during the crypto_rng_reset shall NOT be the + * shared secret from the DH operation, but an independently generated key. + * 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). + */ +static int crypto_kdf_ctr_generate(struct crypto_rng *rng, + const u8 *src, unsigned int slen, + u8 *dst, unsigned int dlen) +{ + const struct crypto_kdf_ctx *ctx = crypto_tfm_ctx(crypto_rng_tfm(rng)); + struct crypto_shash *kmd = ctx->kmd; + SHASH_DESC_ON_STACK(desc, kmd); + __be32 counter = cpu_to_be32(1); + const unsigned int h = crypto_shash_digestsize(kmd); + int err = 0; + u8 *dst_orig = dst; + + crypto_kdf_init_desc(desc, 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; + + if (src && slen) { + err = crypto_shash_update(desc, src, slen); + if (err) + goto out; + } + + if (dlen < h) { + u8 tmpbuffer[CRYPTO_KDF_MAX_DIGESTSIZE]; + + err = crypto_shash_final(desc, tmpbuffer); + if (err) + goto out; + memcpy(dst, tmpbuffer, dlen); + memzero_explicit(tmpbuffer, h); + return 0; + } + + 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); + shash_desc_zero(desc); + return err; +} + +/* + * The seeding of the KDF allows to set a key which must be at least + * digestsize long. + */ +static int crypto_kdf_seed(struct crypto_rng *rng, + const u8 *seed, unsigned int slen) +{ + const struct crypto_kdf_ctx *ctx = crypto_tfm_ctx(crypto_rng_tfm(rng)); + unsigned int ds = crypto_shash_digestsize(ctx->kmd); + + /* Check according to SP800-108 section 7.2 */ + if (ds > slen) + return -EINVAL; + + /* + * We require that we operate on a MAC -- if we do not operate on a + * MAC, this function returns an error. + */ + return crypto_shash_setkey(ctx->kmd, seed, slen); +} + +static int crypto_kdf_init_tfm(struct crypto_tfm *tfm) +{ + struct crypto_instance *inst = crypto_tfm_alg_instance(tfm); + struct crypto_shash_spawn *spawn = crypto_instance_ctx(inst); + struct crypto_kdf_ctx *ctx = crypto_tfm_ctx(tfm); + struct crypto_shash *kmd; + + kmd = crypto_spawn_shash(spawn); + if (IS_ERR(kmd)) + return PTR_ERR(kmd); + + ctx->kmd = kmd; + + return 0; +} + +static void crypto_kdf_exit_tfm(struct crypto_tfm *tfm) +{ + struct crypto_kdf_ctx *ctx = crypto_tfm_ctx(tfm); + + crypto_free_shash(ctx->kmd); +} + +static void crypto_kdf_free(struct rng_instance *inst) +{ + crypto_drop_spawn(rng_instance_ctx(inst)); + kfree(inst); +} + +static int crypto_kdf_alloc_common(struct crypto_template *tmpl, + struct rtattr **tb, + const u8 *name, + int (*generate)(struct crypto_rng *tfm, + const u8 *src, + unsigned int slen, + u8 *dst, unsigned int dlen)) +{ + struct rng_instance *inst; + struct crypto_alg *alg; + struct shash_alg *salg; + int err; + unsigned int ds; + + err = crypto_check_attr_type(tb, CRYPTO_ALG_TYPE_RNG); + if (err) + return err; + + salg = shash_attr_alg(tb[1], 0, 0); + if (IS_ERR(salg)) + return PTR_ERR(salg); + + /* Require a keyed message digest */ + if (!salg->setkey) + return -EOPNOTSUPP; + + ds = salg->digestsize; + /* Hashes with no digest size are not allowed for KDFs. */ + if (!ds || WARN_ON(ds > CRYPTO_KDF_MAX_DIGESTSIZE)) + return -EOPNOTSUPP; + + alg = &salg->base; + if (WARN_ON(CRYPTO_KDF_MAX_ALIGNMASK < alg->cra_alignmask)) + return -EOPNOTSUPP; + + inst = rng_alloc_instance(name, alg); + err = PTR_ERR(inst); + if (IS_ERR(inst)) + goto out_put_alg; + + err = crypto_init_shash_spawn(rng_instance_ctx(inst), salg, + rng_crypto_instance(inst)); + if (err) + goto free_inst; + + inst->alg.base.cra_priority = alg->cra_priority; + inst->alg.base.cra_blocksize = alg->cra_blocksize; + inst->alg.base.cra_alignmask = alg->cra_alignmask; + + inst->alg.generate = generate; + inst->alg.seed = crypto_kdf_seed; + inst->alg.seedsize = ds; + + inst->alg.base.cra_init = crypto_kdf_init_tfm; + inst->alg.base.cra_exit = crypto_kdf_exit_tfm; + inst->alg.base.cra_ctxsize = sizeof(struct crypto_kdf_ctx); + + inst->free = crypto_kdf_free; + + err = rng_register_instance(tmpl, inst); + + if (err) { + crypto_drop_spawn(rng_instance_ctx(inst)); +free_inst: + kfree(inst); + } + +out_put_alg: + crypto_mod_put(alg); + return err; +} + +static int crypto_kdf_ctr_create(struct crypto_template *tmpl, + struct rtattr **tb) +{ + return crypto_kdf_alloc_common(tmpl, tb, "kdf_ctr", + crypto_kdf_ctr_generate); +} + +static struct crypto_template crypto_kdf_ctr_tmpl = { + .name = "kdf_ctr", + .create = crypto_kdf_ctr_create, + .module = THIS_MODULE, +}; + +static int crypto_kdf_fb_create(struct crypto_template *tmpl, + struct rtattr **tb) { + return crypto_kdf_alloc_common(tmpl, tb, "kdf_fb", + crypto_kdf_fb_generate); +} + +static struct crypto_template crypto_kdf_fb_tmpl = { + .name = "kdf_fb", + .create = crypto_kdf_fb_create, + .module = THIS_MODULE, +}; + +static int crypto_kdf_dpi_create(struct crypto_template *tmpl, + struct rtattr **tb) { + return crypto_kdf_alloc_common(tmpl, tb, "kdf_dpi", + crypto_kdf_dpi_generate); +} + +static struct crypto_template crypto_kdf_dpi_tmpl = { + .name = "kdf_dpi", + .create = crypto_kdf_dpi_create, + .module = THIS_MODULE, +}; + +static int __init crypto_kdf_init(void) +{ + int err = crypto_register_template(&crypto_kdf_ctr_tmpl); + + if (err) + return err; + + err = crypto_register_template(&crypto_kdf_fb_tmpl); + if (err) { + crypto_unregister_template(&crypto_kdf_ctr_tmpl); + return err; + } + + err = crypto_register_template(&crypto_kdf_dpi_tmpl); + if (err) { + crypto_unregister_template(&crypto_kdf_ctr_tmpl); + crypto_unregister_template(&crypto_kdf_fb_tmpl); + } + return err; +} + +static void __exit crypto_kdf_exit(void) +{ + crypto_unregister_template(&crypto_kdf_ctr_tmpl); + crypto_unregister_template(&crypto_kdf_fb_tmpl); + crypto_unregister_template(&crypto_kdf_dpi_tmpl); +} + +module_init(crypto_kdf_init); +module_exit(crypto_kdf_exit); + +MODULE_LICENSE("GPL v2"); +MODULE_AUTHOR("Stephan Mueller "); +MODULE_DESCRIPTION("Key Derivation Function conformant to SP800-108"); +MODULE_ALIAS_CRYPTO("kdf_ctr"); +MODULE_ALIAS_CRYPTO("kdf_fb"); +MODULE_ALIAS_CRYPTO("kdf_dpi"); From patchwork Wed Jan 16 11:08:29 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stephan Mueller X-Patchwork-Id: 10765767 X-Patchwork-Delegate: herbert@gondor.apana.org.au Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 22AD51580 for ; Wed, 16 Jan 2019 11:12:35 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 12AC62C67F for ; Wed, 16 Jan 2019 11:12:35 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 06B0A2C680; Wed, 16 Jan 2019 11:12:35 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.7 required=2.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id E2D302C3AA for ; Wed, 16 Jan 2019 11:12:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2392389AbfAPLMA (ORCPT ); Wed, 16 Jan 2019 06:12:00 -0500 Received: from mo4-p03-ob.smtp.rzone.de ([85.215.255.103]:8863 "EHLO mo4-p03-ob.smtp.rzone.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730526AbfAPLMA (ORCPT ); Wed, 16 Jan 2019 06:12:00 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; t=1547637112; s=strato-dkim-0002; d=chronox.de; h=References:In-Reply-To:Message-ID:Date:Subject:Cc:To:From: X-RZG-CLASS-ID:X-RZG-AUTH:From:Subject:Sender; bh=sTChyO5sil1yDQGIPAkiWjuaAsMmqvKVZBUqplTCU7Y=; b=gV5Di6Df9XjGlFP3cQfcTLkrnr+/UNVRauJPPlWTYx0wvsE7oUuHjvPt8nyN3W3DQP AIXXVSJG3/zl6t35FpDA/p7w2hsCl3jmlieDy1aACC5PaKJ5uzkd7eccZoJAbYzn4LSM woqxH0AIxqBftcaP7byNlb7Q8ZZ/T7FFLM4Mh3V/9Z5uuwmZJf4cBh1DOAPtSlgnhjhN kZDGSZKBnSP2YHuLpcVV/HbdGotz059ZiHclh7egefOUIgAtVwMar+nu6fV7KVUqY8i3 qI1VgyA9lMj251ngcpdE2t/LbiSlWlkBdEg62oq/GtfZiBAywTYcd40R8jpgyDx7rTt7 LuPg== X-RZG-AUTH: ":P2ERcEykfu11Y98lp/T7+hdri+uKZK8TKWEqNyiHySGSa9k9yWgdNs16dfA/c7fW145n" X-RZG-CLASS-ID: mo00 Received: from positron.chronox.de by smtp.strato.de (RZmta 44.9 AUTH) with ESMTPSA id 309bcfv0GBBV4NY (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (curve secp521r1 with 521 ECDH bits, eq. 15360 bits RSA)) (Client did not present a certificate); Wed, 16 Jan 2019 12:11:31 +0100 (CET) From: Stephan =?iso-8859-1?q?M=FCller?= To: Herbert Xu Cc: Eric Biggers , James Bottomley , Andy Lutomirski , "Lee, Chun-Yi" , "Rafael J . Wysocki" , Pavel Machek , linux-kernel@vger.kernel.org, linux-pm@vger.kernel.org, keyrings@vger.kernel.org, "Rafael J. Wysocki" , Chen Yu , Oliver Neukum , Ryan Chen , David Howells , Giovanni Gherdovich , Randy Dunlap , Jann Horn , Andy Lutomirski , linux-crypto@vger.kernel.org Subject: [PATCH v2 3/6] crypto: kdf - add known answer tests Date: Wed, 16 Jan 2019 12:08:29 +0100 Message-ID: <1981110.LazqzSmiWA@positron.chronox.de> In-Reply-To: <2082192.jPI8ve1O8G@positron.chronox.de> References: <20190103143227.9138-1-jlee@suse.com> <9733066.Vrs4h5eWcW@positron.chronox.de> <2082192.jPI8ve1O8G@positron.chronox.de> MIME-Version: 1.0 Sender: linux-crypto-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-crypto@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Add known answer tests to the testmgr for the KDF (SP800-108) cipher. Signed-off-by: Stephan Mueller --- crypto/testmgr.c | 219 +++++++++++++++++++++++++++++++++++++++++++++++ crypto/testmgr.h | 107 +++++++++++++++++++++++ 2 files changed, 326 insertions(+) diff --git a/crypto/testmgr.c b/crypto/testmgr.c index 0f684a414acb..309819af55d8 100644 --- a/crypto/testmgr.c +++ b/crypto/testmgr.c @@ -110,6 +110,11 @@ struct drbg_test_suite { unsigned int count; }; +struct kdf_test_suite { + const struct kdf_testvec *vecs; + unsigned int count; +}; + struct akcipher_test_suite { const struct akcipher_testvec *vecs; unsigned int count; @@ -133,6 +138,7 @@ struct alg_test_desc { struct hash_test_suite hash; struct cprng_test_suite cprng; struct drbg_test_suite drbg; + struct kdf_test_suite kdf; struct akcipher_test_suite akcipher; struct kpp_test_suite kpp; } suite; @@ -2020,6 +2026,66 @@ static int drbg_cavs_test(const struct drbg_testvec *test, int pr, return ret; } +static int kdf_test(const struct kdf_testvec *test, + const char *driver, u32 type, u32 mask) +{ + int ret = -EAGAIN; + struct crypto_rng *drng; + u8 *buf = kzalloc(test->expectedlen, GFP_KERNEL); + + if (!buf) + return -ENOMEM; + + drng = crypto_alloc_rng(driver, type | CRYPTO_ALG_INTERNAL, mask); + if (IS_ERR(drng)) { + pr_err("alg: kdf: could not allocate cipher handle " + "for %s\n", driver); + kfree(buf); + return -ENOMEM; + } + + ret = crypto_rng_reset(drng, test->K1, test->K1len); + if (ret) { + pr_err("alg: kdf: could not set key derivation key\n"); + goto err; + } + + ret = crypto_rng_generate(drng, test->context, test->contextlen, + 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_rng(drng); + kfree(buf); + return ret; +} + +static int alg_test_kdf(const struct alg_test_desc *desc, const char *driver, + u32 type, u32 mask) +{ + int err = 0; + unsigned int i = 0; + const struct kdf_testvec *template = desc->suite.kdf.vecs; + unsigned int tcount = desc->suite.kdf.count; + + for (i = 0; i < tcount; i++) { + err = kdf_test(&template[i], driver, type, mask); + if (err) { + pr_err("alg: kdf: Test %d failed for %s\n", + i, driver); + err = -EINVAL; + break; + } + } + return err; +} static int alg_test_drbg(const struct alg_test_desc *desc, const char *driver, u32 type, u32 mask) @@ -3220,6 +3286,159 @@ static const struct alg_test_desc alg_test_descs[] = { .alg = "jitterentropy_rng", .fips_allowed = 1, .test = alg_test_null, + }, { + .alg = "kdf_ctr(cmac(aes))", + .test = alg_test_null, + .fips_allowed = 1, + }, { + .alg = "kdf_ctr(cmac(des3_ede))", + .test = alg_test_null, + .fips_allowed = 1, + }, { + .alg = "kdf_ctr(hmac(sha1))", + .test = alg_test_null, + .fips_allowed = 1, + }, { + .alg = "kdf_ctr(hmac(sha224))", + .test = alg_test_null, + .fips_allowed = 1, + }, { + .alg = "kdf_ctr(hmac(sha256))", + .test = alg_test_kdf, + .fips_allowed = 1, + .suite = { + .kdf = __VECS(kdf_ctr_hmac_sha256_tv_template) + } + }, { + .alg = "kdf_ctr(hmac(sha384))", + .test = alg_test_null, + .fips_allowed = 1, + }, { + .alg = "kdf_ctr(hmac(sha512))", + .test = alg_test_null, + .fips_allowed = 1, + }, { + .alg = "kdf_ctr(sha1)", + .test = alg_test_null, + .fips_allowed = 1, + }, { + .alg = "kdf_ctr(sha224)", + .test = alg_test_null, + .fips_allowed = 1, + }, { + .alg = "kdf_ctr(sha256)", + .test = alg_test_null, + .fips_allowed = 1, + }, { + .alg = "kdf_ctr(sha384)", + .test = alg_test_null, + .fips_allowed = 1, + }, { + .alg = "kdf_ctr(sha512)", + .test = alg_test_null, + .fips_allowed = 1, + }, { + .alg = "kdf_dpi(cmac(aes))", + .test = alg_test_null, + .fips_allowed = 1, + }, { + .alg = "kdf_dpi(cmac(des3_ede))", + .test = alg_test_null, + .fips_allowed = 1, + }, { + .alg = "kdf_dpi(hmac(sha1))", + .test = alg_test_null, + .fips_allowed = 1, + }, { + .alg = "kdf_dpi(hmac(sha224))", + .test = alg_test_null, + .fips_allowed = 1, + }, { + .alg = "kdf_dpi(hmac(sha256))", + .test = alg_test_kdf, + .fips_allowed = 1, + .suite = { + .kdf = __VECS(kdf_dpi_hmac_sha256_tv_template) + } + }, { + .alg = "kdf_dpi(hmac(sha384))", + .test = alg_test_null, + .fips_allowed = 1, + }, { + .alg = "kdf_dpi(hmac(sha512))", + .test = alg_test_null, + .fips_allowed = 1, + }, { + .alg = "kdf_dpi(sha1)", + .test = alg_test_null, + .fips_allowed = 1, + }, { + .alg = "kdf_dpi(sha224)", + .test = alg_test_null, + .fips_allowed = 1, + }, { + .alg = "kdf_dpi(sha256)", + .test = alg_test_null, + .fips_allowed = 1, + }, { + .alg = "kdf_dpi(sha384)", + .test = alg_test_null, + .fips_allowed = 1, + }, { + .alg = "kdf_dpi(sha512)", + .test = alg_test_null, + .fips_allowed = 1, + }, { + .alg = "kdf_fb(cmac(aes))", + .test = alg_test_null, + .fips_allowed = 1, + }, { + .alg = "kdf_fb(cmac(des3_ede))", + .test = alg_test_null, + .fips_allowed = 1, + }, { + .alg = "kdf_fb(hmac(sha1))", + .test = alg_test_null, + .fips_allowed = 1, + }, { + .alg = "kdf_fb(hmac(sha224))", + .test = alg_test_null, + .fips_allowed = 1, + }, { + .alg = "kdf_fb(hmac(sha256))", + .test = alg_test_kdf, + .fips_allowed = 1, + .suite = { + .kdf = __VECS(kdf_fb_hmac_sha256_tv_template) + } + }, { + .alg = "kdf_fb(hmac(sha384))", + .test = alg_test_null, + .fips_allowed = 1, + }, { + .alg = "kdf_fb(hmac(sha512))", + .test = alg_test_null, + .fips_allowed = 1, + }, { + .alg = "kdf_fb(sha1)", + .test = alg_test_null, + .fips_allowed = 1, + }, { + .alg = "kdf_fb(sha224)", + .test = alg_test_null, + .fips_allowed = 1, + }, { + .alg = "kdf_fb(sha256)", + .test = alg_test_null, + .fips_allowed = 1, + }, { + .alg = "kdf_fb(sha384)", + .test = alg_test_null, + .fips_allowed = 1, + }, { + .alg = "kdf_fb(sha512)", + .test = alg_test_null, + .fips_allowed = 1, }, { .alg = "kw(aes)", .test = alg_test_skcipher, diff --git a/crypto/testmgr.h b/crypto/testmgr.h index ca8e8ebef309..65fe3d4ef082 100644 --- a/crypto/testmgr.h +++ b/crypto/testmgr.h @@ -122,6 +122,15 @@ struct drbg_testvec { size_t expectedlen; }; +struct kdf_testvec { + unsigned char *K1; + size_t K1len; + unsigned char *context; + size_t contextlen; + unsigned char *expected; + size_t expectedlen; +}; + struct akcipher_testvec { const unsigned char *key; const unsigned char *m; @@ -27892,6 +27901,104 @@ static const struct drbg_testvec drbg_nopr_ctr_aes128_tv_template[] = { }, }; +/* + * 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[] = { + { + .K1 = "\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", + .K1len = 32, + .context = + "\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", + .contextlen = 60, + .expected = + "\x10\x62\x13\x42\xbf\xb0\xfd\x40" + "\x04\x6c\x0e\x29\xf2\xcf\xdb\xf0", + .expectedlen = 16 + } +}; + +/* + * Test vector obtained from + * http://csrc.nist.gov/groups/STM/cavp/documents/KBKDF800-108/FeedbackModeNOzeroiv.zip + */ +static const struct kdf_testvec kdf_fb_hmac_sha256_tv_template[] = { + { + .K1 = "\x93\xf6\x98\xe8\x42\xee\xd7\x53" + "\x94\xd6\x29\xd9\x57\xe2\xe8\x9c" + "\x6e\x74\x1f\x81\x0b\x62\x3c\x8b" + "\x90\x1e\x38\x37\x6d\x06\x8e\x7b", + .K1len = 32, + .context = + "\x9f\x57\x5d\x90\x59\xd3\xe0\xc0" + "\x80\x3f\x08\x11\x2f\x8a\x80\x6d" + "\xe3\xc3\x47\x19\x12\xcd\xf4\x2b" + "\x09\x53\x88\xb1\x4b\x33\x50\x8e" + "\x53\xb8\x9c\x18\x69\x0e\x20\x57" + "\xa1\xd1\x67\x82\x2e\x63\x6d\xe5" + "\x0b\xe0\x01\x85\x32\xc4\x31\xf7" + "\xf5\xe3\x7f\x77\x13\x92\x20\xd5" + "\xe0\x42\x59\x9e\xbe\x26\x6a\xf5" + "\x76\x7e\xe1\x8c\xd2\xc5\xc1\x9a" + "\x1f\x0f\x80", + .contextlen = 83, + .expected = + "\xbd\x14\x76\xf4\x3a\x4e\x31\x57" + "\x47\xcf\x59\x18\xe0\xea\x5b\xc0" + "\xd9\x87\x69\x45\x74\x77\xc3\xab" + "\x18\xb7\x42\xde\xf0\xe0\x79\xa9" + "\x33\xb7\x56\x36\x5a\xfb\x55\x41" + "\xf2\x53\xfe\xe4\x3c\x6f\xd7\x88" + "\xa4\x40\x41\x03\x85\x09\xe9\xee" + "\xb6\x8f\x7d\x65\xff\xbb\x5f\x95", + .expectedlen = 64 + } +}; + +/* + * Test vector obtained from + * http://csrc.nist.gov/groups/STM/cavp/documents/KBKDF800-108/PipelineModewithCounter.zip + */ +static const struct kdf_testvec kdf_dpi_hmac_sha256_tv_template[] = { + { + .K1 = "\x02\xd3\x6f\xa0\x21\xc2\x0d\xdb" + "\xde\xe4\x69\xf0\x57\x94\x68\xba" + "\xe5\xcb\x13\xb5\x48\xb6\xc6\x1c" + "\xdf\x9d\x3e\xc4\x19\x11\x1d\xe2", + .K1len = 32, + .context = + "\x85\xab\xe3\x8b\xf2\x65\xfb\xdc" + "\x64\x45\xae\x5c\x71\x15\x9f\x15" + "\x48\xc7\x3b\x7d\x52\x6a\x62\x31" + "\x04\x90\x4a\x0f\x87\x92\x07\x0b" + "\x3d\xf9\x90\x2b\x96\x69\x49\x04" + "\x25\xa3\x85\xea\xdb\x0f\x9c\x76" + "\xe4\x6f\x0f", + .contextlen = 51, + .expected = + "\xd6\x9f\x74\xf5\x18\xc9\xf6\x4f" + "\x90\xa0\xbe\xeb\xab\x69\xf6\x89" + "\xb7\x3b\x5c\x13\xeb\x0f\x86\x0a" + "\x95\xca\xd7\xd9\x81\x4f\x8c\x50" + "\x6e\xb7\xb1\x79\xa5\xc5\xb4\x46" + "\x6a\x9e\xc1\x54\xc3\xbf\x1c\x13" + "\xef\xd6\xec\x0d\x82\xb0\x2c\x29" + "\xaf\x2c\x69\x02\x99\xed\xc4\x53", + .expectedlen = 64 + } +}; + /* Cast5 test vectors from RFC 2144 */ static const struct cipher_testvec cast5_tv_template[] = { { From patchwork Wed Jan 16 11:08:49 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stephan Mueller X-Patchwork-Id: 10765745 X-Patchwork-Delegate: herbert@gondor.apana.org.au Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id D9414186E for ; Wed, 16 Jan 2019 11:12:01 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C6C5C2D344 for ; Wed, 16 Jan 2019 11:12:01 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id C3BB02D166; Wed, 16 Jan 2019 11:12:01 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.7 required=2.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 21F5D2D929 for ; Wed, 16 Jan 2019 11:12:01 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2392331AbfAPLLs (ORCPT ); Wed, 16 Jan 2019 06:11:48 -0500 Received: from mo4-p02-ob.smtp.rzone.de ([85.215.255.82]:18160 "EHLO mo4-p02-ob.smtp.rzone.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2392367AbfAPLLs (ORCPT ); Wed, 16 Jan 2019 06:11:48 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; t=1547637103; s=strato-dkim-0002; d=chronox.de; h=References:In-Reply-To:Message-ID:Date:Subject:Cc:To:From: X-RZG-CLASS-ID:X-RZG-AUTH:From:Subject:Sender; bh=1Sd5yDNPiSJSxhy4ySS6exTR+m+Hq7U1h1jNBS7Nqmo=; b=kQ88Ul4U4RzOmbAvqIH8r/0nd47iDScwtod6Cxul0x01v+bx2flDcWS7r7Ux5C7nVG dbDJVDJ6jsJtV9ICyfzMX4ctLyLLPyK8aa/Nej5rwFCIkqb6IxlYvRb9vbMIwJGVYiY4 KrzcVBiq4DAcr7t0sPYzjgpVgZt/K3X/a+xRry/mQu0ojIxhPue1juelGR/iR221qmiB IUEBzmPS2B6oESSMTaVa1y2fPRdERhjLdbw4Zp2pLmKJJBkZlF+gVOvMp9obOYvOc3VX iJU+St+MaJdqzCUHn8yZEBhIbVRL+pY2Ug2qFMZ0nskcFuiTkSOVTXhWDS9xdpSCfHsd VQqQ== X-RZG-AUTH: ":P2ERcEykfu11Y98lp/T7+hdri+uKZK8TKWEqNyiHySGSa9k9yWgdNs16dfA/c7fW145n" X-RZG-CLASS-ID: mo00 Received: from positron.chronox.de by smtp.strato.de (RZmta 44.9 AUTH) with ESMTPSA id 309bcfv0GBBQ4NV (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (curve secp521r1 with 521 ECDH bits, eq. 15360 bits RSA)) (Client did not present a certificate); Wed, 16 Jan 2019 12:11:26 +0100 (CET) From: Stephan =?iso-8859-1?q?M=FCller?= To: Herbert Xu Cc: Eric Biggers , James Bottomley , Andy Lutomirski , "Lee, Chun-Yi" , "Rafael J . Wysocki" , Pavel Machek , linux-kernel@vger.kernel.org, linux-pm@vger.kernel.org, keyrings@vger.kernel.org, "Rafael J. Wysocki" , Chen Yu , Oliver Neukum , Ryan Chen , David Howells , Giovanni Gherdovich , Randy Dunlap , Jann Horn , Andy Lutomirski , linux-crypto@vger.kernel.org Subject: [PATCH v2 4/6] crypto: hkdf - HMAC-based Extract-and-Expand KDF Date: Wed, 16 Jan 2019 12:08:49 +0100 Message-ID: <3767574.eZANq8FNrB@positron.chronox.de> In-Reply-To: <2082192.jPI8ve1O8G@positron.chronox.de> References: <20190103143227.9138-1-jlee@suse.com> <9733066.Vrs4h5eWcW@positron.chronox.de> <2082192.jPI8ve1O8G@positron.chronox.de> MIME-Version: 1.0 Sender: linux-crypto-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-crypto@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP The HMAC-based Extract-and-Expand Key Derivation Function is conformant to RFC5869. The extraction phase can be invoked separately from the expansion phase. This implies that the once a key is set and thus the extraction phase was applied, the expansion phase can be invoked multiple times. The HKDF implementation does not restrict the type of keyed message digest it is instantiated with. RFC5869 specifies HMAC-SHA as the only keyed message digest, though. From a cryptographic point of view, using other keyed message digests would result in an equally strong KDF. Signed-off-by: Stephan Mueller --- crypto/Kconfig | 6 ++ crypto/Makefile | 1 + crypto/hkdf.c | 272 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 279 insertions(+) create mode 100644 crypto/hkdf.c diff --git a/crypto/Kconfig b/crypto/Kconfig index 7c0336c9ba9c..c25b2033321a 100644 --- a/crypto/Kconfig +++ b/crypto/Kconfig @@ -568,6 +568,12 @@ config CRYPTO_KDF_SP800108 Support for KDF compliant to SP800-108. All three types of KDF specified in SP800-108 are implemented. +config CRYPTO_HKDF + tristate "HMAC-based Extract-and-Expand Key Derivation Function (HKDF)" + select CRYPTO_RNG + help + Support for KDF conformant to RFC5869. + config CRYPTO_XCBC tristate "XCBC support" select CRYPTO_HASH diff --git a/crypto/Makefile b/crypto/Makefile index eead7ec9fd8e..80363b8cbf6c 100644 --- a/crypto/Makefile +++ b/crypto/Makefile @@ -59,6 +59,7 @@ crypto_user-$(CONFIG_CRYPTO_STATS) += crypto_user_stat.o obj-$(CONFIG_CRYPTO_CMAC) += cmac.o obj-$(CONFIG_CRYPTO_HMAC) += hmac.o obj-$(CONFIG_CRYPTO_KDF_SP800108) += kdf_sp800108.o +obj-$(CONFIG_CRYPTO_HKDF) += hkdf.o obj-$(CONFIG_CRYPTO_VMAC) += vmac.o obj-$(CONFIG_CRYPTO_XCBC) += xcbc.o obj-$(CONFIG_CRYPTO_NULL2) += crypto_null.o diff --git a/crypto/hkdf.c b/crypto/hkdf.c new file mode 100644 index 000000000000..2f392c71c85b --- /dev/null +++ b/crypto/hkdf.c @@ -0,0 +1,272 @@ +// SPDX-License-Identifier: GPL-2.0 + +/* + * HMAC-based Extract-and-Expand Key Derivation Function (conformant to RFC5869) + * + * Copyright (C) 2019, Stephan Mueller + */ + +/* + * The HKDF extract phase is applied with crypto_rng_reset(). + * The HKDF expand phase is applied with crypto_rng_generate(). + */ + +#include +#include +#include +#include +#include +#include + +struct crypto_hkdf_ctx { + struct crypto_shash *kmd; +}; + +#define CRYPTO_HKDF_MAX_DIGESTSIZE 64 + +static inline void crypto_kdf_init_desc(struct shash_desc *desc, + struct crypto_shash *kmd) +{ + desc->tfm = kmd; + desc->flags = 0; +} + +/* + * HKDF expand phase + */ +static int crypto_hkdf_generate(struct crypto_rng *rng, + const u8 *info, unsigned int infolen, + u8 *dst, unsigned int dlen) +{ + const struct crypto_hkdf_ctx *ctx = crypto_tfm_ctx(crypto_rng_tfm(rng)); + struct crypto_shash *kmd = ctx->kmd; + SHASH_DESC_ON_STACK(desc, kmd); + const unsigned int h = crypto_shash_digestsize(kmd); + int err = 0; + u8 *dst_orig = dst; + const u8 *prev = NULL; + u8 ctr = 0x01; + + if (dlen > h * 255) + return -EINVAL; + + crypto_kdf_init_desc(desc, kmd); + + /* T(1) and following */ + while (dlen) { + err = crypto_shash_init(desc); + if (err) + goto out; + + if (prev) { + err = crypto_shash_update(desc, prev, h); + if (err) + goto out; + } + + if (info) { + err = crypto_shash_update(desc, info, infolen); + if (err) + goto out; + } + + if (dlen < h) { + u8 tmpbuffer[CRYPTO_HKDF_MAX_DIGESTSIZE]; + + err = crypto_shash_finup(desc, &ctr, 1, tmpbuffer); + if (err) + goto out; + memcpy(dst, tmpbuffer, dlen); + memzero_explicit(tmpbuffer, h); + goto out; + } + + err = crypto_shash_finup(desc, &ctr, 1, dst); + if (err) + goto out; + + prev = dst; + dst += h; + dlen -= h; + ctr++; + } + +out: + if (err) + memzero_explicit(dst_orig, dlen); + shash_desc_zero(desc); + return err; +} + +/* + * HKDF extract phase. + * + * The seed is defined to be a concatenation of the salt and the IKM. + * The data buffer is pre-pended by a word which provides an u32 value + * with the length of the salt. Thus, the buffer length - salt length is the + * IKM length. + */ +static int crypto_hkdf_seed(struct crypto_rng *rng, + const u8 *seed, unsigned int slen) +{ + const struct crypto_hkdf_ctx *ctx = crypto_tfm_ctx(crypto_rng_tfm(rng)); + struct crypto_shash *kmd = ctx->kmd; + SHASH_DESC_ON_STACK(desc, kmd); + u32 saltlen; + unsigned int h = crypto_shash_digestsize(kmd); + int err; + const u8 null_salt[CRYPTO_HKDF_MAX_DIGESTSIZE] = { 0 }; + u8 prk[CRYPTO_HKDF_MAX_DIGESTSIZE]; + + if (slen < sizeof(saltlen)) + return -EINVAL; + + saltlen = get_unaligned((u32 *)seed); + + seed += sizeof(saltlen); + slen -= sizeof(saltlen); + + if (slen < saltlen) + return -EINVAL; + + crypto_kdf_init_desc(desc, kmd); + + /* Set the salt as HMAC key */ + if (saltlen) + err = crypto_shash_setkey(kmd, seed, saltlen); + else + err = crypto_shash_setkey(kmd, null_salt, h); + if (err) + return err; + + /* Extract the PRK */ + err = crypto_shash_digest(desc, seed + saltlen, slen - saltlen, prk); + if (err) + goto err; + + /* Set the PRK for the expand phase */ + err = crypto_shash_setkey(kmd, prk, h); + +err: + shash_desc_zero(desc); + memzero_explicit(prk, h); + return err; +} + +static int crypto_hkdf_init_tfm(struct crypto_tfm *tfm) +{ + struct crypto_instance *inst = crypto_tfm_alg_instance(tfm); + struct crypto_shash_spawn *spawn = crypto_instance_ctx(inst); + struct crypto_hkdf_ctx *ctx = crypto_tfm_ctx(tfm); + struct crypto_shash *kmd; + + kmd = crypto_spawn_shash(spawn); + if (IS_ERR(kmd)) + return PTR_ERR(kmd); + + ctx->kmd = kmd; + + return 0; +} + +static void crypto_hkdf_exit_tfm(struct crypto_tfm *tfm) +{ + struct crypto_hkdf_ctx *ctx = crypto_tfm_ctx(tfm); + + crypto_free_shash(ctx->kmd); +} + +static void crypto_kdf_free(struct rng_instance *inst) +{ + crypto_drop_spawn(rng_instance_ctx(inst)); + kfree(inst); +} + +static int crypto_hkdf_create(struct crypto_template *tmpl, struct rtattr **tb) +{ + struct rng_instance *inst; + struct crypto_alg *alg; + struct shash_alg *salg; + int err; + unsigned int ds, ss; + + err = crypto_check_attr_type(tb, CRYPTO_ALG_TYPE_RNG); + if (err) + return err; + + salg = shash_attr_alg(tb[1], 0, 0); + if (IS_ERR(salg)) + return PTR_ERR(salg); + + /* Require a keyed message digest */ + if (!salg->setkey) + return -EOPNOTSUPP; + + ds = salg->digestsize; + /* Hashes with no digest size are not allowed for KDFs. */ + if (!ds || WARN_ON(ds > CRYPTO_HKDF_MAX_DIGESTSIZE)) + return -EOPNOTSUPP; + + ss = salg->statesize; + alg = &salg->base; + + inst = rng_alloc_instance("hkdf", alg); + err = PTR_ERR(inst); + if (IS_ERR(inst)) + goto out_put_alg; + + err = crypto_init_shash_spawn(rng_instance_ctx(inst), salg, + rng_crypto_instance(inst)); + if (err) + goto free_inst; + + inst->alg.base.cra_priority = alg->cra_priority; + inst->alg.base.cra_blocksize = alg->cra_blocksize; + inst->alg.base.cra_alignmask = alg->cra_alignmask; + + inst->alg.generate = crypto_hkdf_generate; + inst->alg.seed = crypto_hkdf_seed; + + inst->alg.base.cra_init = crypto_hkdf_init_tfm; + inst->alg.base.cra_exit = crypto_hkdf_exit_tfm; + inst->alg.base.cra_ctxsize = sizeof(struct crypto_hkdf_ctx); + + inst->free = crypto_kdf_free; + + err = rng_register_instance(tmpl, inst); + + if (err) { + crypto_drop_spawn(rng_instance_ctx(inst)); +free_inst: + kfree(inst); + } + + +out_put_alg: + crypto_mod_put(alg); + return err; +} + +static struct crypto_template crypto_hkdf_tmpl = { + .name = "hkdf", + .create = crypto_hkdf_create, + .module = THIS_MODULE, +}; + +static int __init crypto_hkdf_init(void) +{ + return crypto_register_template(&crypto_hkdf_tmpl); +} + +static void __exit crypto_hkdf_exit(void) +{ + crypto_unregister_template(&crypto_hkdf_tmpl); +} + +module_init(crypto_hkdf_init); +module_exit(crypto_hkdf_exit); + +MODULE_LICENSE("GPL v2"); +MODULE_AUTHOR("Stephan Mueller "); +MODULE_DESCRIPTION("HKDF HMAC-based Extract-and-Expand Key Derivation Function (conformant to RFC5869)"); +MODULE_ALIAS_CRYPTO("hkdf"); From patchwork Wed Jan 16 11:09:11 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stephan Mueller X-Patchwork-Id: 10765739 X-Patchwork-Delegate: herbert@gondor.apana.org.au Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 51BE313BF for ; Wed, 16 Jan 2019 11:12:00 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3E6EC2C426 for ; Wed, 16 Jan 2019 11:12:00 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 336682D94C; Wed, 16 Jan 2019 11:12:00 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.7 required=2.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id DD2482C279 for ; Wed, 16 Jan 2019 11:11:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2392366AbfAPLLu (ORCPT ); Wed, 16 Jan 2019 06:11:50 -0500 Received: from mo4-p02-ob.smtp.rzone.de ([85.215.255.80]:34072 "EHLO mo4-p02-ob.smtp.rzone.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2389696AbfAPLLt (ORCPT ); Wed, 16 Jan 2019 06:11:49 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; t=1547637102; s=strato-dkim-0002; d=chronox.de; h=References:In-Reply-To:Message-ID:Date:Subject:Cc:To:From: X-RZG-CLASS-ID:X-RZG-AUTH:From:Subject:Sender; bh=8QSxitv6zhtBvpBZjkKm75lhD+rIZxok0auylrq7C3Q=; b=E9tKUtSX5tQrdsLvrdQR1qpZMfPal8Be85pXbr/nkBJAYRFBJn0qBU5G4aWZzjmhy/ BqZz2cxHFtcIb7u4nU/nfloAqx4mbq6Nl2AcS7e+3+cYmxzWPcXIhhzUsbwQBCVvg6cE Cp4TVFogPR5HtuQQOU9x74zvyR+djyCNTqXdzU8toL+nlO4ixD4RbAwTk4zhNBP1En7r tvAZ7SGkdvYc/l16ODSUrOxgue9YSZZs2Zcn8CIe0qNbkfYv6ZYJu76wGNrUs5zeyRs9 pPMt6G4WZLCUAoTf/PENEhGZsDysAaJUbLdyL0Ddwn65XltgYbwmZ17h7fOs2yKSFqmv aXJg== X-RZG-AUTH: ":P2ERcEykfu11Y98lp/T7+hdri+uKZK8TKWEqNyiHySGSa9k9yWgdNs16dfA/c7fW145n" X-RZG-CLASS-ID: mo00 Received: from positron.chronox.de by smtp.strato.de (RZmta 44.9 AUTH) with ESMTPSA id 309bcfv0GBBK4NS (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (curve secp521r1 with 521 ECDH bits, eq. 15360 bits RSA)) (Client did not present a certificate); Wed, 16 Jan 2019 12:11:20 +0100 (CET) From: Stephan =?iso-8859-1?q?M=FCller?= To: Herbert Xu Cc: Eric Biggers , James Bottomley , Andy Lutomirski , "Lee, Chun-Yi" , "Rafael J . Wysocki" , Pavel Machek , linux-kernel@vger.kernel.org, linux-pm@vger.kernel.org, keyrings@vger.kernel.org, "Rafael J. Wysocki" , Chen Yu , Oliver Neukum , Ryan Chen , David Howells , Giovanni Gherdovich , Randy Dunlap , Jann Horn , Andy Lutomirski , linux-crypto@vger.kernel.org Subject: [PATCH v2 5/6] crypto: hkdf - add known answer tests Date: Wed, 16 Jan 2019 12:09:11 +0100 Message-ID: <2443102.TZCsN2CrQ3@positron.chronox.de> In-Reply-To: <2082192.jPI8ve1O8G@positron.chronox.de> References: <20190103143227.9138-1-jlee@suse.com> <9733066.Vrs4h5eWcW@positron.chronox.de> <2082192.jPI8ve1O8G@positron.chronox.de> MIME-Version: 1.0 Sender: linux-crypto-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-crypto@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Add known answer tests to the testmgr for the HKDF (RFC5869) cipher. The known answer tests are derived from RFC 5869 appendix A. Note, the HKDF is considered to be a FIPS 140-2 allowed (not approved) cipher as of now. Yet, an allowed cipher is usable under FIPS 140-2 rules. Signed-off-by: Stephan Mueller --- crypto/testmgr.c | 26 ++++++++++++++ crypto/testmgr.h | 91 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 117 insertions(+) diff --git a/crypto/testmgr.c b/crypto/testmgr.c index 309819af55d8..0b06721a70df 100644 --- a/crypto/testmgr.c +++ b/crypto/testmgr.c @@ -3189,6 +3189,32 @@ static const struct alg_test_desc alg_test_descs[] = { .suite = { .hash = __VECS(ghash_tv_template) } + }, { + .alg = "hkdf(hmac(sha1))", + .test = alg_test_kdf, + .fips_allowed = 1, + .suite = { + .kdf = __VECS(hkdf_hmac_sha1_tv_template) + } + }, { + .alg = "hkdf(hmac(sha224))", + .test = alg_test_null, + .fips_allowed = 1, + }, { + .alg = "hkdf(hmac(sha256))", + .test = alg_test_kdf, + .fips_allowed = 1, + .suite = { + .kdf = __VECS(hkdf_hmac_sha256_tv_template) + } + }, { + .alg = "hkdf(hmac(sha384))", + .test = alg_test_null, + .fips_allowed = 1, + }, { + .alg = "hkdf(hmac(sha512))", + .test = alg_test_null, + .fips_allowed = 1, }, { .alg = "hmac(md5)", .test = alg_test_hash, diff --git a/crypto/testmgr.h b/crypto/testmgr.h index 65fe3d4ef082..7ffff184fba2 100644 --- a/crypto/testmgr.h +++ b/crypto/testmgr.h @@ -27999,6 +27999,97 @@ static const struct kdf_testvec kdf_dpi_hmac_sha256_tv_template[] = { } }; +/* Test vectors from RFC 5869 appendix A */ +static const struct kdf_testvec hkdf_hmac_sha256_tv_template[] = { + { + .K1 = +#ifdef __LITTLE_ENDIAN + "\x0d\x00\x00\x00" /* salt length */ +#else + "\x00\x00\x00\x0d" /* salt length */ +#endif + "\x00\x01\x02\x03\x04\x05\x06\x07" + "\x08\x09\x0a\x0b\x0c" /* salt */ + "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b" + "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b" + "\x0b\x0b\x0b\x0b\x0b\x0b", /* IKM */ + .K1len = 39, + .context = + "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7" + "\xf8\xf9", + .contextlen = 10, + .expected = + "\x3c\xb2\x5f\x25\xfa\xac\xd5\x7a" + "\x90\x43\x4f\x64\xd0\x36\x2f\x2a" + "\x2d\x2d\x0a\x90\xcf\x1a\x5a\x4c" + "\x5d\xb0\x2d\x56\xec\xc4\xc5\xbf" + "\x34\x00\x72\x08\xd5\xb8\x87\x18" + "\x58\x65", + .expectedlen = 42 + }, { + .K1 = "\x00\x00\x00\x00" /* salt length */ + "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b" + "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b" + "\x0b\x0b\x0b\x0b\x0b\x0b", /* IKM */ + .K1len = 26, + .context = NULL, + .contextlen = 0, + .expected = + "\x8d\xa4\xe7\x75\xa5\x63\xc1\x8f" + "\x71\x5f\x80\x2a\x06\x3c\x5a\x31" + "\xb8\xa1\x1f\x5c\x5e\xe1\x87\x9e" + "\xc3\x45\x4e\x5f\x3c\x73\x8d\x2d" + "\x9d\x20\x13\x95\xfa\xa4\xb6\x1a" + "\x96\xc8", + .expectedlen = 42 + } +}; + +/* Test vectors from RFC 5869 appendix A */ +static const struct kdf_testvec hkdf_hmac_sha1_tv_template[] = { + { + .K1 = +#ifdef __LITTLE_ENDIAN + "\x0d\x00\x00\x00" /* salt length */ +#else + "\x00\x00\x00\x0d" /* salt length */ +#endif + "\x00\x01\x02\x03\x04\x05\x06\x07" + "\x08\x09\x0a\x0b\x0c" /* salt */ + "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b" + "\x0b\x0b\x0b", /* IKM */ + .K1len = 28, + .context = + "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7" + "\xf8\xf9", + .contextlen = 10, + .expected = + "\x08\x5a\x01\xea\x1b\x10\xf3\x69" + "\x33\x06\x8b\x56\xef\xa5\xad\x81" + "\xa4\xf1\x4b\x82\x2f\x5b\x09\x15" + "\x68\xa9\xcd\xd4\xf1\x55\xfd\xa2" + "\xc2\x2e\x42\x24\x78\xd3\x05\xf3" + "\xf8\x96", + .expectedlen = 42 + }, { + .K1 = "\x00\x00\x00\x00" /* salt length */ + "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b" + "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b" + "\x0b\x0b\x0b\x0b\x0b\x0b", /* IKM */ + .K1len = 26, + .context = NULL, + .contextlen = 0, + .expected = + "\x0a\xc1\xaf\x70\x02\xb3\xd7\x61" + "\xd1\xe5\x52\x98\xda\x9d\x05\x06" + "\xb9\xae\x52\x05\x72\x20\xa3\x06" + "\xe0\x7b\x6b\x87\xe8\xdf\x21\xd0" + "\xea\x00\x03\x3d\xe0\x39\x84\xd3" + "\x49\x18", + .expectedlen = 42 + } +}; + /* Cast5 test vectors from RFC 2144 */ static const struct cipher_testvec cast5_tv_template[] = { { From patchwork Wed Jan 16 11:09:33 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stephan Mueller X-Patchwork-Id: 10765753 X-Patchwork-Delegate: herbert@gondor.apana.org.au Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id B81D213BF for ; Wed, 16 Jan 2019 11:12:18 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A96D22D6F8 for ; Wed, 16 Jan 2019 11:12:18 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id A76652D917; Wed, 16 Jan 2019 11:12:18 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.7 required=2.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 6481D2D971 for ; Wed, 16 Jan 2019 11:12:18 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2389691AbfAPLMG (ORCPT ); Wed, 16 Jan 2019 06:12:06 -0500 Received: from mo4-p01-ob.smtp.rzone.de ([85.215.255.52]:16829 "EHLO mo4-p01-ob.smtp.rzone.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730526AbfAPLMF (ORCPT ); Wed, 16 Jan 2019 06:12:05 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; t=1547637120; s=strato-dkim-0002; d=chronox.de; h=References:In-Reply-To:Message-ID:Date:Subject:Cc:To:From: X-RZG-CLASS-ID:X-RZG-AUTH:From:Subject:Sender; bh=z1JSnWMAdIBaOoX07NP+bwCKYNTj6YxEKLWL5bKCEIo=; b=R9zxaQ4ZbtKJVeqA/LKP9r9bKj1vKShb2M/oJuPrsV75zhxLtG+Al1L1b0WFPi06MT ImFWZr4owgGcN3Ro+D6P954QjNBjkDbcbbQWIM/PiNeez5zvDVtDYrj2CBuIqGz5bua2 FF9mwjsheMf9M1LqZOvW/RSnjGTHix3aIwprCqNLPQ4tb03fgdCm+rQ1r/Z961EwjQec VfE4MdFQQruwKSs9Y9TVT90Bd7ocwigoYYgeS29ltWOhS+oVWmEc3yb2kgm6DQ8v/eRt 4mYWaxfn5q2kySDDPjFExHDzowB4CRJj7Ptci/7gP28+KHRz1y4YGQ073dprX8NnIQZi SUHw== X-RZG-AUTH: ":P2ERcEykfu11Y98lp/T7+hdri+uKZK8TKWEqNyiHySGSa9k9yWgdNs16dfA/c7fW145n" X-RZG-CLASS-ID: mo00 Received: from positron.chronox.de by smtp.strato.de (RZmta 44.9 AUTH) with ESMTPSA id 309bcfv0GBBD4NM (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (curve secp521r1 with 521 ECDH bits, eq. 15360 bits RSA)) (Client did not present a certificate); Wed, 16 Jan 2019 12:11:13 +0100 (CET) From: Stephan =?iso-8859-1?q?M=FCller?= To: Herbert Xu Cc: Eric Biggers , James Bottomley , Andy Lutomirski , "Lee, Chun-Yi" , "Rafael J . Wysocki" , Pavel Machek , linux-kernel@vger.kernel.org, linux-pm@vger.kernel.org, keyrings@vger.kernel.org, "Rafael J. Wysocki" , Chen Yu , Oliver Neukum , Ryan Chen , David Howells , Giovanni Gherdovich , Randy Dunlap , Jann Horn , Andy Lutomirski , linux-crypto@vger.kernel.org Subject: [PATCH v2 6/6] crypto: tcrypt - add KDF test invocation Date: Wed, 16 Jan 2019 12:09:33 +0100 Message-ID: <8600018.3ZaGsXI4pz@positron.chronox.de> In-Reply-To: <2082192.jPI8ve1O8G@positron.chronox.de> References: <20190103143227.9138-1-jlee@suse.com> <9733066.Vrs4h5eWcW@positron.chronox.de> <2082192.jPI8ve1O8G@positron.chronox.de> MIME-Version: 1.0 Sender: linux-crypto-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-crypto@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Enable testing of the SP800-108 and RFC5869 KDFs. Signed-off-by: Stephan Mueller --- crypto/tcrypt.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c index e7fb87e114a5..5606e59e80ec 100644 --- a/crypto/tcrypt.c +++ b/crypto/tcrypt.c @@ -2054,6 +2054,14 @@ static int do_test(const char *alg, u32 type, u32 mask, int m, u32 num_mb) ret += tcrypt_test("cbc(sm4)"); ret += tcrypt_test("ctr(sm4)"); break; + case 192: + ret += tcrypt_test("kdf_ctr(hmac(sha256))"); + ret += tcrypt_test("kdf_dpi(hmac(sha256))"); + ret += tcrypt_test("kdf_fb(hmac(sha256))"); + break; + case 193: + ret += tcrypt_test("hkdf(hmac(sha256))"); + break; case 200: test_cipher_speed("ecb(aes)", ENCRYPT, sec, NULL, 0, speed_template_16_24_32);