2021-01-04 22:01:28

by Stephan Müller

[permalink] [raw]
Subject: [PATCH 0/5] Add KDF implementations to crypto API

Hi,

The key derviation functions are considered to be a cryptographic
operation. As cryptographic operations are provided via the kernel
crypto API, this patch set consolidates the KDF implementations into the
crypto API.

The KDF implementations are provided as service functions. Yet, the
interface to the two provided KDFs are identical with the goal to allow
them to be transformed into a crypto API template eventually.

The KDFs execute a power-on self test with test vectors from commonly
known sources.

Tbe SP800-108 KDF implementation is used to replace the implementation
in the keys subsystem. The implementation was verified using the
keyutils command line test code provided in
tests/keyctl/dh_compute/valid. All tests show that the expected values
are calculated with the new code.

The HKDF addition is used to replace the implementation in the filesystem
crypto extension. This code was tested by using an EXT4 encrypted file
system that was created and contains files written to by the current
implementation. Using the new implementation a successful read of the
existing files was possible and new files / directories were created
and read successfully. These newly added file system objects could be
successfully read using the current code. Yet if there is a test suite
to validate whether the invokcation of the HKDF calculates the same
result as the existing implementation, I would be happy to validate
the implementation accordingly.

Stephan Mueller (5):
crypto: Add key derivation self-test support code
crypto: add SP800-108 counter key derivation function
crypto: add RFC5869 HKDF
security: DH - use KDF implementation from crypto API
fs: use HKDF implementation from kernel crypto API

crypto/Kconfig | 14 ++
crypto/Makefile | 6 +
crypto/hkdf.c | 226 +++++++++++++++++++++++++
crypto/kdf_sp800108.c | 149 ++++++++++++++++
fs/crypto/Kconfig | 2 +-
fs/crypto/fscrypt_private.h | 4 +-
fs/crypto/hkdf.c | 108 +++---------
include/crypto/hkdf.h | 48 ++++++
include/crypto/internal/kdf_selftest.h | 68 ++++++++
include/crypto/kdf_sp800108.h | 59 +++++++
security/keys/Kconfig | 2 +-
security/keys/dh.c | 118 ++-----------
12 files changed, 617 insertions(+), 187 deletions(-)
create mode 100644 crypto/hkdf.c
create mode 100644 crypto/kdf_sp800108.c
create mode 100644 include/crypto/hkdf.h
create mode 100644 include/crypto/internal/kdf_selftest.h
create mode 100644 include/crypto/kdf_sp800108.h

--
2.26.2





2021-01-04 22:03:04

by Stephan Müller

[permalink] [raw]
Subject: [PATCH 1/5] crypto: Add key derivation self-test support code

As a preparation to add the key derivation implementations, the
self-test data structure definition and the common test code is made
available.

The test framework follows the testing applied by the NIST CAVP test
approach.

The structure of the test code follows the implementations found in
crypto/testmgr.c|h. In case the KDF implementations will be made
available via a kernel crypto API templates, the test code is intended
to be merged into testmgr.c|h.

Signed-off-by: Stephan Mueller <[email protected]>
---
include/crypto/internal/kdf_selftest.h | 68 ++++++++++++++++++++++++++
1 file changed, 68 insertions(+)
create mode 100644 include/crypto/internal/kdf_selftest.h

diff --git a/include/crypto/internal/kdf_selftest.h b/include/crypto/internal/kdf_selftest.h
new file mode 100644
index 000000000000..c4f80d2cc61c
--- /dev/null
+++ b/include/crypto/internal/kdf_selftest.h
@@ -0,0 +1,68 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+/*
+ * Copyright (C) 2020, Stephan Mueller <[email protected]>
+ */
+
+#ifndef _CRYPTO_KDF_SELFTEST_H
+#define _CRYPTO_KDF_SELFTEST_H
+
+#include <crypto/hash.h>
+#include <linux/uio.h>
+
+struct kdf_testvec {
+ struct kvec seed[2];
+ unsigned int seed_nvec;
+ struct kvec info;
+ unsigned char *expected;
+ size_t expectedlen;
+};
+
+static inline int
+kdf_test(const struct kdf_testvec *test, const char *name,
+ int (*crypto_kdf_setkey)(struct crypto_shash *kmd,
+ const struct kvec *seed,
+ unsigned int seed_nvec),
+ int (*crypto_kdf_generate)(struct crypto_shash *kmd,
+ const struct kvec *info,
+ unsigned int info_nvec,
+ u8 *dst, unsigned int dlen))
+{
+ struct crypto_shash *kmd;
+ int ret;
+ u8 *buf = kzalloc(test->expectedlen, GFP_KERNEL);
+
+ if (!buf)
+ return -ENOMEM;
+
+ kmd = crypto_alloc_shash(name, 0, 0);
+ if (IS_ERR(kmd)) {
+ pr_err("alg: kdf: could not allocate cipher handle for %s\n",
+ name);
+ kfree(buf);
+ return -ENOMEM;
+ }
+
+ ret = crypto_kdf_setkey(kmd, test->seed, test->seed_nvec);
+ if (ret) {
+ pr_err("alg: kdf: could not set key derivation key\n");
+ goto err;
+ }
+
+ ret = crypto_kdf_generate(kmd, &test->info, 1, buf, test->expectedlen);
+ if (ret) {
+ pr_err("alg: kdf: could not obtain key data\n");
+ goto err;
+ }
+
+ ret = memcmp(test->expected, buf, test->expectedlen);
+ if (ret)
+ ret = -EINVAL;
+
+err:
+ crypto_free_shash(kmd);
+ kfree(buf);
+ return ret;
+}
+
+#endif /* _CRYPTO_KDF_SELFTEST_H */
--
2.26.2