All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Stephan Müller" <smueller@chronox.de>
To: Herbert Xu <herbert@gondor.apana.org.au>
Cc: Eric Biggers <ebiggers@kernel.org>,
	James Bottomley <James.Bottomley@hansenpartnership.com>,
	Andy Lutomirski <luto@amacapital.net>,
	"Lee, Chun-Yi" <joeyli.kernel@gmail.com>,
	"Rafael J . Wysocki" <rjw@rjwysocki.net>,
	Pavel Machek <pavel@ucw.cz>,
	linux-kernel@vger.kernel.org, linux-pm@vger.kernel.org,
	keyrings@vger.kernel.org,
	"Rafael J. Wysocki" <rafael.j.wysocki@intel.com>,
	Chen Yu <yu.c.chen@intel.com>, Oliver Neukum <oneukum@suse.com>,
	Ryan Chen <yu.chen.surf@gmail.com>,
	David Howells <dhowells@redhat.com>,
	Giovanni Gherdovich <ggherdovich@suse.cz>,
	Randy Dunlap <rdunlap@infradead.org>,
	Jann Horn <jannh@google.com>, Andy Lutomirski <luto@kernel.org>,
	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	[thread overview]
Message-ID: <2831352.yMFniVK4cV@positron.chronox.de> (raw)
In-Reply-To: <2082192.jPI8ve1O8G@positron.chronox.de>

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 <smueller@chronox.de>
---
 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 <smueller@chronox.de>
+ */
+
+/*
+ * 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 <linux/module.h>
+#include <crypto/rng.h>
+#include <crypto/internal/rng.h>
+#include <crypto/hash.h>
+#include <crypto/internal/hash.h>
+
+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 <smueller@chronox.de>");
+MODULE_DESCRIPTION("Key Derivation Function conformant to SP800-108");
+MODULE_ALIAS_CRYPTO("kdf_ctr");
+MODULE_ALIAS_CRYPTO("kdf_fb");
+MODULE_ALIAS_CRYPTO("kdf_dpi");
-- 
2.20.1

WARNING: multiple messages have this Message-ID (diff)
From: "Stephan Müller" <smueller@chronox.de>
To: Herbert Xu <herbert@gondor.apana.org.au>
Cc: Eric Biggers <ebiggers@kernel.org>,
	James Bottomley <James.Bottomley@hansenpartnership.com>,
	Andy Lutomirski <luto@amacapital.net>,
	"Lee, Chun-Yi" <joeyli.kernel@gmail.com>,
	"Rafael J . Wysocki" <rjw@rjwysocki.net>,
	Pavel Machek <pavel@ucw.cz>,
	linux-kernel@vger.kernel.org, linux-pm@vger.kernel.org,
	keyrings@vger.kernel.org,
	"Rafael J. Wysocki" <rafael.j.wysocki@intel.com>,
	Chen Yu <yu.c.chen@intel.com>, Oliver Neukum <oneukum@suse.com>,
	Ryan Chen <yu.chen.surf@gmail.com>,
	David Howells <dhowells@redhat.com>,
	Giovanni Gherdovich <ggherdovich@suse.cz>,
	Randy Dunlap <rdunlap@infradead.org>,
	Jann Horn <jannh@google.com>, Andy Lutomirski <luto@kernel.org>,
	linux-crypto@vger.kernel.org
Subject: [PATCH v2 2/6] crypto: kdf - SP800-108 Key Derivation Function
Date: Wed, 16 Jan 2019 11:08:04 +0000	[thread overview]
Message-ID: <2831352.yMFniVK4cV@positron.chronox.de> (raw)
In-Reply-To: <2082192.jPI8ve1O8G@positron.chronox.de>

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 <smueller@chronox.de>
---
 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 <smueller@chronox.de>
+ */
+
+/*
+ * 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 <linux/module.h>
+#include <crypto/rng.h>
+#include <crypto/internal/rng.h>
+#include <crypto/hash.h>
+#include <crypto/internal/hash.h>
+
+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 <smueller@chronox.de>");
+MODULE_DESCRIPTION("Key Derivation Function conformant to SP800-108");
+MODULE_ALIAS_CRYPTO("kdf_ctr");
+MODULE_ALIAS_CRYPTO("kdf_fb");
+MODULE_ALIAS_CRYPTO("kdf_dpi");
-- 
2.20.1

  parent reply	other threads:[~2019-01-16 11:12 UTC|newest]

Thread overview: 181+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-01-03 14:32 [PATCH 0/5 v2][RFC] Encryption and authentication for hibernate snapshot image Lee, Chun-Yi
2019-01-03 14:32 ` Lee, Chun-Yi
2019-01-03 14:32 ` [PATCH 1/5 v2] PM / hibernate: Create snapshot keys handler Lee, Chun-Yi
2019-01-03 14:32   ` Lee, Chun-Yi
2019-01-06  8:01   ` Stephan Mueller
2019-01-06  8:01     ` Stephan Mueller
2019-01-06  8:25     ` Stephan Mueller
2019-01-06  8:25       ` Stephan Mueller
2019-01-07 15:33     ` joeyli
2019-01-07 15:33       ` joeyli
2019-01-07 15:52       ` Stephan Mueller
2019-01-07 15:52         ` Stephan Mueller
2019-01-08  5:03         ` Herbert Xu
2019-01-08  5:03           ` Herbert Xu
2019-01-08  7:09           ` Stephan Mueller
2019-01-08  7:09             ` Stephan Mueller
2019-01-08 23:54             ` Andy Lutomirski
2019-01-08 23:54               ` Andy Lutomirski
2019-01-09  0:44               ` James Bottomley
2019-01-09  0:44                 ` James Bottomley
2019-01-09  0:44                 ` James Bottomley
2019-01-09  1:43                 ` Andy Lutomirski
2019-01-09  1:43                   ` Andy Lutomirski
2019-01-09  6:49                   ` James Bottomley
2019-01-09  6:49                     ` James Bottomley
2019-01-09 18:11                     ` joeyli
2019-01-09 18:11                       ` joeyli
2019-01-11 15:53                       ` Jarkko Sakkinen
2019-01-11 15:53                         ` Jarkko Sakkinen
2019-01-09 18:34                     ` Andy Lutomirski
2019-01-09 18:34                       ` Andy Lutomirski
2019-01-09 19:46                       ` James Bottomley
2019-01-09 19:46                         ` James Bottomley
2019-01-09 20:12                         ` Andy Lutomirski
2019-01-09 20:12                           ` Andy Lutomirski
2019-01-09 21:43                           ` James Bottomley
2019-01-09 21:43                             ` James Bottomley
2019-01-09 22:19                             ` Pavel Machek
2019-01-09 22:19                               ` Pavel Machek
2019-01-11 16:04                       ` Jarkko Sakkinen
2019-01-11 16:04                         ` Jarkko Sakkinen
2019-01-11 14:02                   ` Jarkko Sakkinen
2019-01-11 14:02                     ` Jarkko Sakkinen
2019-01-11 15:28                     ` James Bottomley
2019-01-11 15:28                       ` James Bottomley
2019-01-18 14:33                       ` Jarkko Sakkinen
2019-01-18 14:33                         ` Jarkko Sakkinen
2019-01-18 20:59                         ` James Bottomley
2019-01-18 20:59                           ` James Bottomley
2019-01-20 16:02                           ` Jarkko Sakkinen
2019-01-20 16:02                             ` Jarkko Sakkinen
2019-01-09  6:45                 ` Stephan Mueller
2019-01-09  6:45                   ` Stephan Mueller
2019-01-09  6:58                   ` James Bottomley
2019-01-09  6:58                     ` James Bottomley
2019-01-09  7:05                     ` Stephan Mueller
2019-01-09  7:05                       ` Stephan Mueller
2019-01-09  8:21                       ` Eric Biggers
2019-01-09  8:21                         ` Eric Biggers
2019-01-09 10:17                         ` Stephan Mueller
2019-01-09 10:17                           ` Stephan Mueller
2019-01-09 17:34                           ` Eric Biggers
2019-01-09 17:34                             ` Eric Biggers
2019-01-09 18:18                             ` Stephan Mueller
2019-01-09 18:18                               ` Stephan Mueller
2019-01-11 19:08                         ` [PATCH 0/6] General Key Derivation Function Support Stephan Müller
2019-01-11 19:08                           ` Stephan Müller
2019-01-11 19:09                           ` [PATCH 1/6] crypto: add template handling for RNGs Stephan Müller
2019-01-11 19:09                             ` Stephan Müller
2019-01-11 19:10                           ` [PATCH 2/6] crypto: kdf - SP800-108 Key Derivation Function Stephan Müller
2019-01-11 19:10                             ` Stephan Müller
2019-01-12  5:27                             ` Eric Biggers
2019-01-12  5:27                               ` Eric Biggers
2019-01-14  9:31                               ` Stephan Müller
2019-01-14  9:31                                 ` Stephan Müller
2019-01-11 19:10                           ` [PATCH 3/6] crypto: kdf - add known answer tests Stephan Müller
2019-01-11 19:10                             ` Stephan Müller
2019-01-12  5:26                             ` Eric Biggers
2019-01-12  5:26                               ` Eric Biggers
2019-01-14  9:26                               ` Stephan Müller
2019-01-14  9:26                                 ` Stephan Müller
2019-01-11 19:10                           ` [PATCH 4/6] crypto: hkdf - RFC5869 Key Derivation Function Stephan Müller
2019-01-11 19:10                             ` Stephan Müller
2019-01-12  5:12                             ` Eric Biggers
2019-01-12  5:12                               ` Eric Biggers
2019-01-12  9:55                               ` Herbert Xu
2019-01-12  9:55                                 ` Herbert Xu
2019-01-13  7:56                                 ` Stephan Müller
2019-01-13  7:56                                   ` Stephan Müller
2019-01-13 16:52                                   ` James Bottomley
2019-01-13 16:52                                     ` James Bottomley
2019-01-14  9:30                               ` Stephan Müller
2019-01-14  9:30                                 ` Stephan Müller
2019-01-14 17:53                                 ` Eric Biggers
2019-01-14 17:53                                   ` Eric Biggers
2019-01-14 18:44                                   ` Stephan Mueller
2019-01-14 18:44                                     ` Stephan Mueller
2019-01-11 19:10                           ` [PATCH 5/6] crypto: hkdf - add known answer tests Stephan Müller
2019-01-11 19:10                             ` Stephan Müller
2019-01-12  5:19                             ` Eric Biggers
2019-01-12  5:19                               ` Eric Biggers
2019-01-14  9:25                               ` Stephan Müller
2019-01-14  9:25                                 ` Stephan Müller
2019-01-14 17:44                                 ` Eric Biggers
2019-01-14 17:44                                   ` Eric Biggers
2019-01-11 19:11                           ` [PATCH 6/6] crypto: tcrypt - add KDF test invocation Stephan Müller
2019-01-11 19:11                             ` Stephan Müller
2019-01-16 11:06                           ` [PATCH v2 0/6] General Key Derivation Function Support Stephan Müller
2019-01-16 11:06                             ` Stephan Müller
2019-01-16 11:07                             ` [PATCH v2 1/6] crypto: add template handling for RNGs Stephan Müller
2019-01-16 11:07                               ` Stephan Müller
2019-01-16 11:08                             ` Stephan Müller [this message]
2019-01-16 11:08                               ` [PATCH v2 2/6] crypto: kdf - SP800-108 Key Derivation Function Stephan Müller
2019-01-16 11:08                             ` [PATCH v2 3/6] crypto: kdf - add known answer tests Stephan Müller
2019-01-16 11:08                               ` Stephan Müller
2019-01-16 11:08                             ` [PATCH v2 4/6] crypto: hkdf - HMAC-based Extract-and-Expand KDF Stephan Müller
2019-01-16 11:08                               ` Stephan Müller
2019-01-16 11:09                             ` [PATCH v2 5/6] crypto: hkdf - add known answer tests Stephan Müller
2019-01-16 11:09                               ` Stephan Müller
2019-01-16 11:09                             ` [PATCH v2 6/6] crypto: tcrypt - add KDF test invocation Stephan Müller
2019-01-16 11:09                               ` Stephan Müller
2019-01-28 10:07                             ` [PATCH v2 0/6] General Key Derivation Function Support Stephan Mueller
2019-01-28 10:07                               ` Stephan Mueller
2019-01-30 10:08                               ` Herbert Xu
2019-01-30 10:08                                 ` Herbert Xu
2019-01-30 14:39                                 ` Stephan Mueller
2019-01-30 14:39                                   ` Stephan Mueller
2019-02-08  7:45                                   ` Herbert Xu
2019-02-08  7:45                                     ` Herbert Xu
2019-02-08  8:00                                     ` Stephan Mueller
2019-02-08  8:00                                       ` Stephan Mueller
2019-02-08  8:05                                       ` Herbert Xu
2019-02-08  8:05                                         ` Herbert Xu
2019-02-08  8:17                                         ` Stephan Mueller
2019-02-08  8:17                                           ` Stephan Mueller
2019-02-19  5:44                                           ` Herbert Xu
2019-02-19  5:44                                             ` Herbert Xu
2019-01-09 15:34                       ` [PATCH 1/5 v2] PM / hibernate: Create snapshot keys handler James Bottomley
2019-01-09 15:34                         ` James Bottomley
2019-01-09  6:27               ` Stephan Mueller
2019-01-09  6:27                 ` Stephan Mueller
2019-01-03 14:32 ` [PATCH 2/5] PM / hibernate: Generate and verify signature for snapshot image Lee, Chun-Yi
2019-01-03 14:32   ` Lee, Chun-Yi
2019-01-06  8:09   ` Stephan Mueller
2019-01-06  8:09     ` Stephan Mueller
2019-01-07 18:58   ` Dan Carpenter
2019-01-07 18:58     ` Dan Carpenter
2019-01-03 14:32 ` [PATCH 3/5] PM / hibernate: Encrypt " Lee, Chun-Yi
2019-01-03 14:32   ` Lee, Chun-Yi
2019-01-06  8:23   ` Stephan Mueller
2019-01-06  8:23     ` Stephan Mueller
2019-01-03 14:32 ` [PATCH 4/5 v2] PM / hibernate: Erase the snapshot master key in snapshot pages Lee, Chun-Yi
2019-01-03 14:32   ` Lee, Chun-Yi
2019-01-03 14:32 ` [PATCH 5/5 v2] PM / hibernate: An option to request that snapshot image must be authenticated Lee, Chun-Yi
2019-01-03 14:32   ` Lee, Chun-Yi
2019-01-06 18:10 ` [PATCH 0/5 v2][RFC] Encryption and authentication for hibernate snapshot image Pavel Machek
2019-01-06 18:10   ` Pavel Machek
2019-01-07 17:37   ` joeyli
2019-01-07 17:37     ` joeyli
2019-01-07 18:07     ` Pavel Machek
2019-01-07 18:07       ` Pavel Machek
2019-01-08 21:41     ` Andy Lutomirski
2019-01-08 21:41       ` Andy Lutomirski
2019-01-08 23:42       ` Pavel Machek
2019-01-08 23:42         ` Pavel Machek
2019-01-09 16:39       ` joeyli
2019-01-09 16:39         ` joeyli
2019-01-09 16:47         ` Stephan Mueller
2019-01-09 16:47           ` Stephan Mueller
2019-01-11 14:29           ` joeyli
2019-01-11 14:29             ` joeyli
2019-01-09 16:51         ` joeyli
2019-01-09 16:51           ` joeyli
2019-01-09 18:47         ` Andy Lutomirski
2019-01-09 18:47           ` Andy Lutomirski
2019-01-10 15:12           ` joeyli
2019-01-10 15:12             ` joeyli
2019-01-11  1:09             ` Andy Lutomirski
2019-01-11  1:09               ` Andy Lutomirski
2019-01-11 14:59               ` joeyli
2019-01-11 14:59                 ` joeyli

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=2831352.yMFniVK4cV@positron.chronox.de \
    --to=smueller@chronox.de \
    --cc=James.Bottomley@hansenpartnership.com \
    --cc=dhowells@redhat.com \
    --cc=ebiggers@kernel.org \
    --cc=ggherdovich@suse.cz \
    --cc=herbert@gondor.apana.org.au \
    --cc=jannh@google.com \
    --cc=joeyli.kernel@gmail.com \
    --cc=keyrings@vger.kernel.org \
    --cc=linux-crypto@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-pm@vger.kernel.org \
    --cc=luto@amacapital.net \
    --cc=luto@kernel.org \
    --cc=oneukum@suse.com \
    --cc=pavel@ucw.cz \
    --cc=rafael.j.wysocki@intel.com \
    --cc=rdunlap@infradead.org \
    --cc=rjw@rjwysocki.net \
    --cc=yu.c.chen@intel.com \
    --cc=yu.chen.surf@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.