All of lore.kernel.org
 help / color / mirror / Atom feed
From: Roberto Sassu <roberto.sassu@huaweicloud.com>
To: dhowells@redhat.com, dwmw2@infradead.org,
	herbert@gondor.apana.org.au, davem@davemloft.net,
	jarkko@kernel.org, song@kernel.org, jolsa@kernel.org,
	ast@kernel.org, daniel@iogearbox.net, andrii@kernel.org,
	martin.lau@linux.dev, yhs@fb.com, john.fastabend@gmail.com,
	kpsingh@kernel.org, sdf@google.com, haoluo@google.com,
	rostedt@goodmis.org, mhiramat@kernel.org, mykolal@fb.com,
	shuah@kernel.org
Cc: linux-kernel@vger.kernel.org, keyrings@vger.kernel.org,
	linux-crypto@vger.kernel.org, bpf@vger.kernel.org,
	linux-trace-kernel@vger.kernel.org,
	linux-kselftest@vger.kernel.org, pbrobinson@gmail.com,
	zbyszek@in.waw.pl, zohar@linux.ibm.com,
	linux-integrity@vger.kernel.org, paul@paul-moore.com,
	linux-security-module@vger.kernel.org, wiktor@metacode.biz,
	devel@lists.sequoia-pgp.org, gnupg-devel@gnupg.org,
	ebiggers@kernel.org, Jason@zx2c4.com, mail@maciej.szmigiero.name,
	antony@vennard.ch, konstantin@linuxfoundation.org,
	James.Bottomley@HansenPartnership.com,
	Roberto Sassu <roberto.sassu@huawei.com>
Subject: [RFC][PATCH 04/10] KEYS: asymmetric: Introduce the user asymmetric key parser
Date: Thu,  6 Jul 2023 16:42:17 +0200	[thread overview]
Message-ID: <20230706144225.1046544-5-roberto.sassu@huaweicloud.com> (raw)
In-Reply-To: <20230706144225.1046544-1-roberto.sassu@huaweicloud.com>

From: Roberto Sassu <roberto.sassu@huawei.com>

Introduce a new parser for user asymmetric keys, in TLV format. User space
tools are expected to convert keys from their original format to the TLV
format.

Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
---
 crypto/asymmetric_keys/Kconfig            |   1 +
 crypto/asymmetric_keys/Makefile           |   3 +-
 crypto/asymmetric_keys/asymmetric_type.c  |   3 +-
 crypto/asymmetric_keys/uasym_key_parser.c | 229 ++++++++++++++++++++++
 crypto/asymmetric_keys/uasym_parser.h     |   5 +
 include/keys/asymmetric-type.h            |   1 +
 include/uapi/linux/uasym_parser.h         |   7 +
 7 files changed, 247 insertions(+), 2 deletions(-)
 create mode 100644 crypto/asymmetric_keys/uasym_key_parser.c

diff --git a/crypto/asymmetric_keys/Kconfig b/crypto/asymmetric_keys/Kconfig
index 4f86fe78efd..d4b8f52a126 100644
--- a/crypto/asymmetric_keys/Kconfig
+++ b/crypto/asymmetric_keys/Kconfig
@@ -88,6 +88,7 @@ config FIPS_SIGNATURE_SELFTEST
 config UASYM_KEYS_SIGS
 	tristate "User asymmetric keys and signatures"
 	depends on ASYMMETRIC_PUBLIC_KEY_SUBTYPE
+	select CRYPTO_PUB_KEY_INFO
 	help
 	  This option enables user asymmetric keys and signatures. They are
 	  keys and signatures converted in user space from their native
diff --git a/crypto/asymmetric_keys/Makefile b/crypto/asymmetric_keys/Makefile
index ac3955d834f..6708a9e81ed 100644
--- a/crypto/asymmetric_keys/Makefile
+++ b/crypto/asymmetric_keys/Makefile
@@ -82,4 +82,5 @@ $(obj)/mscode.asn1.o: $(obj)/mscode.asn1.c $(obj)/mscode.asn1.h
 #
 obj-$(CONFIG_UASYM_KEYS_SIGS) += uasym_keys_sigs.o
 uasym_keys_sigs-y := \
-	uasym_parser.o
+	uasym_parser.o \
+	uasym_key_parser.o
diff --git a/crypto/asymmetric_keys/asymmetric_type.c b/crypto/asymmetric_keys/asymmetric_type.c
index a5da8ccd353..53d0fc26eac 100644
--- a/crypto/asymmetric_keys/asymmetric_type.c
+++ b/crypto/asymmetric_keys/asymmetric_type.c
@@ -430,7 +430,7 @@ static int asymmetric_key_preparse(struct key_preparsed_payload *prep)
 /*
  * Clean up the key ID list
  */
-static void asymmetric_key_free_kids(struct asymmetric_key_ids *kids)
+void asymmetric_key_free_kids(struct asymmetric_key_ids *kids)
 {
 	int i;
 
@@ -440,6 +440,7 @@ static void asymmetric_key_free_kids(struct asymmetric_key_ids *kids)
 		kfree(kids);
 	}
 }
+EXPORT_SYMBOL_GPL(asymmetric_key_free_kids);
 
 /*
  * Clean up the preparse data
diff --git a/crypto/asymmetric_keys/uasym_key_parser.c b/crypto/asymmetric_keys/uasym_key_parser.c
new file mode 100644
index 00000000000..2de3f9afa64
--- /dev/null
+++ b/crypto/asymmetric_keys/uasym_key_parser.c
@@ -0,0 +1,229 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2023 Huawei Technologies Duesseldorf GmbH
+ *
+ * Author: Roberto Sassu <roberto.sassu@huawei.com>
+ *
+ * Implement the user asymmetric key parser.
+ */
+
+#define pr_fmt(fmt) "UASYM KEY: "fmt
+#include <linux/module.h>
+#include <crypto/public_key.h>
+#include <crypto/pub_key_info.h>
+
+#include "uasym_parser.h"
+
+static int parse_key_pub(struct public_key *pub, enum fields field,
+			 const u8 *field_data, u32 field_data_len)
+{
+	int ret = 0;
+
+	kenter(",%u,%u", field, field_data_len);
+
+	pub->key = kmemdup(field_data, field_data_len, GFP_KERNEL);
+	if (!pub->key) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	pub->keylen = field_data_len;
+	pr_debug("Key length in bytes: %d\n", pub->keylen);
+out:
+	kleave(" = %d", ret);
+	return ret;
+}
+
+int parse_key_algo(const char **pkey_algo, enum fields field,
+		   const u8 *field_data, u32 field_data_len)
+{
+	u8 algo;
+	int ret = 0;
+
+	kenter(",%u,%u", field, field_data_len);
+
+	if (field_data_len != sizeof(u8)) {
+		pr_debug("Unexpected data length %u, expected %lu\n",
+			 field_data_len, sizeof(u8));
+		ret = -EBADMSG;
+		goto out;
+	}
+
+	algo = *field_data;
+
+	if (algo >= PKEY_ALGO__LAST) {
+		pr_debug("Unexpected public key algo %u\n", algo);
+		ret = -EBADMSG;
+		goto out;
+	}
+
+	*pkey_algo = pub_key_algo_name[algo];
+	pr_debug("Public key algo: %s\n", *pkey_algo);
+out:
+	kleave(" = %d", ret);
+	return ret;
+}
+
+int parse_key_kid(struct asymmetric_key_id **id, enum fields field,
+		  const u8 *field_data, u32 field_data_len)
+{
+	int ret = 0;
+
+	kenter(",%u,%u", field, field_data_len);
+
+	*id = asymmetric_key_generate_id(field_data, field_data_len, NULL, 0);
+	if (!*id) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	pr_debug("Key/auth identifier: %*phN\n", (*id)->len, (*id)->data);
+out:
+	kleave(" = %d", ret);
+	return ret;
+}
+
+static int parse_key_desc(struct key_preparsed_payload *prep, enum fields field,
+			  const u8 *field_data, u32 field_data_len)
+{
+	int ret = 0;
+
+	kenter(",%u,%u", field, field_data_len);
+
+	if (field_data[field_data_len - 1] != '\0') {
+		pr_err("Non-terminated string\n");
+		ret = -EBADMSG;
+		goto out;
+	}
+
+	prep->description = kstrndup(field_data, field_data_len, GFP_KERNEL);
+	if (!prep->description) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	pr_debug("Key description: %s\n", prep->description);
+out:
+	kleave(" = %d", ret);
+	return ret;
+}
+
+struct callback_struct {
+	struct public_key *pub;
+	struct asymmetric_key_ids *kids;
+	struct key_preparsed_payload *prep;
+};
+
+static int key_callback(void *callback_data, enum fields field,
+			const u8 *field_data, u32 field_data_len)
+{
+	struct callback_struct *cb_s = (struct callback_struct *)callback_data;
+	struct asymmetric_key_id **id;
+	int ret;
+
+	switch (field) {
+	case KEY_PUB:
+		ret = parse_key_pub(cb_s->pub, field, field_data,
+				    field_data_len);
+		break;
+	case KEY_ALGO:
+		ret = parse_key_algo(&cb_s->pub->pkey_algo, field, field_data,
+				     field_data_len);
+		break;
+	case KEY_KID0:
+		id = (struct asymmetric_key_id **)&cb_s->kids->id[0];
+		ret = parse_key_kid(id, field, field_data, field_data_len);
+		break;
+	case KEY_KID1:
+		id = (struct asymmetric_key_id **)&cb_s->kids->id[1];
+		ret = parse_key_kid(id, field, field_data, field_data_len);
+		break;
+	case KEY_KID2:
+		id = (struct asymmetric_key_id **)&cb_s->kids->id[2];
+		ret = parse_key_kid(id, field, field_data, field_data_len);
+		break;
+	case KEY_DESC:
+		ret = parse_key_desc(cb_s->prep, field, field_data,
+				     field_data_len);
+		break;
+	default:
+		/* Just ignore non-relevant fields. */
+		ret = 0;
+		break;
+	}
+
+	return ret;
+}
+
+static int uasym_key_parse(struct key_preparsed_payload *prep)
+{
+	struct callback_struct cb_s;
+	int ret;
+
+	kenter("");
+
+	cb_s.pub = kzalloc(sizeof(*cb_s.pub), GFP_KERNEL);
+	if (!cb_s.pub) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	cb_s.pub->id_type = "UASYM_KEY";
+
+	cb_s.kids = kzalloc(sizeof(*cb_s.kids), GFP_KERNEL);
+	if (!cb_s.kids) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	cb_s.prep = prep;
+
+	ret = uasym_parse(TYPE_KEY, key_callback, &cb_s, prep->data,
+			  prep->datalen);
+	if (ret < 0)
+		goto out;
+
+	if (!cb_s.pub->key || !cb_s.pub->pkey_algo ||
+	    (!cb_s.kids->id[0] && !cb_s.kids->id[1] && !cb_s.kids->id[2])) {
+		pr_debug("Incomplete data\n");
+		ret = -ENOENT;
+		goto out;
+	}
+
+	/* We're pinning the module by being linked against it */
+	__module_get(public_key_subtype.owner);
+	prep->payload.data[asym_subtype] = &public_key_subtype;
+	prep->payload.data[asym_key_ids] = cb_s.kids;
+	prep->payload.data[asym_crypto] = cb_s.pub;
+	prep->quotalen = 100;
+out:
+	kleave(" = %d", ret);
+
+	if (ret < 0) {
+		public_key_free(cb_s.pub);
+		asymmetric_key_free_kids(cb_s.kids);
+		return ret;
+	}
+
+	return 0;
+}
+
+static struct asymmetric_key_parser uasym_key_parser = {
+	.owner = THIS_MODULE,
+	.name = "uasym_key",
+	.parse = uasym_key_parse
+};
+
+static int __init uasym_key_init(void)
+{
+	return register_asymmetric_key_parser(&uasym_key_parser);
+}
+
+static void __exit uasym_key_exit(void)
+{
+	unregister_asymmetric_key_parser(&uasym_key_parser);
+}
+
+module_init(uasym_key_init);
+module_exit(uasym_key_exit);
+MODULE_LICENSE("GPL");
diff --git a/crypto/asymmetric_keys/uasym_parser.h b/crypto/asymmetric_keys/uasym_parser.h
index 985dda6aad3..0f629fb7a9b 100644
--- a/crypto/asymmetric_keys/uasym_parser.h
+++ b/crypto/asymmetric_keys/uasym_parser.h
@@ -28,3 +28,8 @@ int uasym_parse_data(parse_callback callback, void *callback_data,
 		     u16 num_fields, const u8 *data, size_t data_len);
 int uasym_parse(enum data_types expected_data_type, parse_callback callback,
 		void *callback_data, const u8 *data, size_t data_len);
+
+int parse_key_algo(const char **pkey_algo, enum fields field,
+		   const u8 *field_data, u32 field_data_len);
+int parse_key_kid(struct asymmetric_key_id **id, enum fields field,
+		  const u8 *data, u32 data_len);
diff --git a/include/keys/asymmetric-type.h b/include/keys/asymmetric-type.h
index 69a13e1e5b2..acbb8c805f6 100644
--- a/include/keys/asymmetric-type.h
+++ b/include/keys/asymmetric-type.h
@@ -66,6 +66,7 @@ extern struct asymmetric_key_id *asymmetric_key_generate_id(const void *val_1,
 							    size_t len_1,
 							    const void *val_2,
 							    size_t len_2);
+void asymmetric_key_free_kids(struct asymmetric_key_ids *kids);
 static inline
 const struct asymmetric_key_ids *asymmetric_key_ids(const struct key *key)
 {
diff --git a/include/uapi/linux/uasym_parser.h b/include/uapi/linux/uasym_parser.h
index 8f0bc235492..42e0087ac2b 100644
--- a/include/uapi/linux/uasym_parser.h
+++ b/include/uapi/linux/uasym_parser.h
@@ -62,9 +62,16 @@ struct uasym_entry {
 } __packed;
 
 #define FOR_EACH_DATA_TYPE(DATA_TYPE) \
+	DATA_TYPE(TYPE_KEY) \
 	DATA_TYPE(TYPE__LAST)
 
 #define FOR_EACH_FIELD(FIELD) \
+	FIELD(KEY_PUB) \
+	FIELD(KEY_ALGO) \
+	FIELD(KEY_KID0) \
+	FIELD(KEY_KID1) \
+	FIELD(KEY_KID2) \
+	FIELD(KEY_DESC) \
 	FIELD(FIELD__LAST)
 
 #define GENERATE_ENUM(ENUM) ENUM,
-- 
2.34.1


  parent reply	other threads:[~2023-07-06 14:46 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-07-06 14:42 [RFC][PATCH 00/10] KEYS: Introduce user asymmetric keys and signatures Roberto Sassu
2023-07-06 14:42 ` [RFC][PATCH 01/10] crypto: Export public key algorithm information Roberto Sassu
2023-07-06 14:42 ` [RFC][PATCH 02/10] crypto: Export signature encoding information Roberto Sassu
2023-07-06 14:42 ` [RFC][PATCH 03/10] KEYS: asymmetric: Introduce a parser for user asymmetric keys and sigs Roberto Sassu
2023-07-06 14:42 ` Roberto Sassu [this message]
2023-07-06 14:42 ` [RFC][PATCH 05/10] KEYS: asymmetric: Introduce the user asymmetric key signature parser Roberto Sassu
2023-07-06 14:42 ` [RFC][PATCH 06/10] verification: Add verify_uasym_signature() and verify_uasym_sig_message() Roberto Sassu
2023-07-06 14:42 ` [RFC][PATCH 07/10] KEYS: asymmetric: Preload user asymmetric keys from a keyring blob Roberto Sassu
2023-07-06 14:42 ` [RFC][PATCH 08/10] KEYS: Introduce load_uasym_keyring() Roberto Sassu
2023-07-06 14:42 ` [RFC][PATCH 09/10] bpf: Introduce bpf_verify_uasym_signature() kfunc Roberto Sassu
2023-07-06 14:42 ` [RFC][PATCH 10/10] selftests/bpf: Prepare a test for user asymmetric key signatures Roberto Sassu
2023-07-06 14:42 ` [RFC][GNUPG][PATCH 1/2] Convert PGP keys to the user asymmetric keys format Roberto Sassu
2023-07-06 14:42 ` [RFC][GNUPG][PATCH 2/2] Convert PGP signatures to the user asymmetric key signatures format Roberto Sassu
2023-07-06 23:27 ` [RFC][PATCH 00/10] KEYS: Introduce user asymmetric keys and signatures Alexei Starovoitov
2023-07-07  7:03   ` Roberto Sassu

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=20230706144225.1046544-5-roberto.sassu@huaweicloud.com \
    --to=roberto.sassu@huaweicloud.com \
    --cc=James.Bottomley@HansenPartnership.com \
    --cc=Jason@zx2c4.com \
    --cc=andrii@kernel.org \
    --cc=antony@vennard.ch \
    --cc=ast@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=daniel@iogearbox.net \
    --cc=davem@davemloft.net \
    --cc=devel@lists.sequoia-pgp.org \
    --cc=dhowells@redhat.com \
    --cc=dwmw2@infradead.org \
    --cc=ebiggers@kernel.org \
    --cc=gnupg-devel@gnupg.org \
    --cc=haoluo@google.com \
    --cc=herbert@gondor.apana.org.au \
    --cc=jarkko@kernel.org \
    --cc=john.fastabend@gmail.com \
    --cc=jolsa@kernel.org \
    --cc=keyrings@vger.kernel.org \
    --cc=konstantin@linuxfoundation.org \
    --cc=kpsingh@kernel.org \
    --cc=linux-crypto@vger.kernel.org \
    --cc=linux-integrity@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-kselftest@vger.kernel.org \
    --cc=linux-security-module@vger.kernel.org \
    --cc=linux-trace-kernel@vger.kernel.org \
    --cc=mail@maciej.szmigiero.name \
    --cc=martin.lau@linux.dev \
    --cc=mhiramat@kernel.org \
    --cc=mykolal@fb.com \
    --cc=paul@paul-moore.com \
    --cc=pbrobinson@gmail.com \
    --cc=roberto.sassu@huawei.com \
    --cc=rostedt@goodmis.org \
    --cc=sdf@google.com \
    --cc=shuah@kernel.org \
    --cc=song@kernel.org \
    --cc=wiktor@metacode.biz \
    --cc=yhs@fb.com \
    --cc=zbyszek@in.waw.pl \
    --cc=zohar@linux.ibm.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.