[RFC][PATCH 6/6] KEYS: asymmetric: Add UMD handler

From: Roberto Sassu
Date: Tue Apr 25 2023 - 13:39:38 EST


From: Roberto Sassu <roberto.sassu@xxxxxxxxxx>

Introduce the skeleton of the UMD handler, complete enough to talk with
the new key and signature parsers in the kernel.

Commands to parse keys and signatures are not implemented.

Signed-off-by: Roberto Sassu <roberto.sassu@xxxxxxxxxx>
---
.gitignore | 3 +
crypto/asymmetric_keys/Kconfig | 10 +++
crypto/asymmetric_keys/Makefile | 13 +++
crypto/asymmetric_keys/umd_key_sig_loader.c | 32 +++++++
crypto/asymmetric_keys/umd_key_sig_umh_blob.S | 7 ++
crypto/asymmetric_keys/umd_key_sig_umh_user.c | 84 +++++++++++++++++++
6 files changed, 149 insertions(+)
create mode 100644 crypto/asymmetric_keys/umd_key_sig_loader.c
create mode 100644 crypto/asymmetric_keys/umd_key_sig_umh_blob.S
create mode 100644 crypto/asymmetric_keys/umd_key_sig_umh_user.c

diff --git a/.gitignore b/.gitignore
index 7f86e083790..f14e42b7273 100644
--- a/.gitignore
+++ b/.gitignore
@@ -174,3 +174,6 @@ sphinx_*/

# Rust analyzer configuration
/rust-project.json
+
+# User mode driver for asymmetric keys and signatures
+/crypto/asymmetric_keys/umd_key_sig_umh
diff --git a/crypto/asymmetric_keys/Kconfig b/crypto/asymmetric_keys/Kconfig
index d312feae88e..4b53667d209 100644
--- a/crypto/asymmetric_keys/Kconfig
+++ b/crypto/asymmetric_keys/Kconfig
@@ -107,4 +107,14 @@ config UMD_SIG_PARSER
On success, the parser fills the signature from the UMD handler
response.

+config UMD_KEY_SIG_HANDLER
+ tristate "UMD handler for asymmetric keys and signatures"
+ depends on UMD_KEY_PARSER
+ help
+ This option introduces a UMD handler to parse data received from
+ the key and signature kernel parsers.
+
+ It includes just the basic program structure, to be enhanced with
+ actual parsers.
+
endif # ASYMMETRIC_KEY_TYPE
diff --git a/crypto/asymmetric_keys/Makefile b/crypto/asymmetric_keys/Makefile
index 060c699fbb2..d870cc04fcf 100644
--- a/crypto/asymmetric_keys/Makefile
+++ b/crypto/asymmetric_keys/Makefile
@@ -86,3 +86,16 @@ obj-$(CONFIG_UMD_KEY_PARSER) += umd_key_parser.o
# UMD signature parser
#
obj-$(CONFIG_UMD_SIG_PARSER) += umd_sig_parser.o
+
+#
+# UMD handler for asymmetric keys and signatures
+#
+CC=klcc
+userprogs := umd_key_sig_umh
+umd_key_sig_umh-objs := umd_key_sig_umh_user.o
+userldflags += -static
+
+$(obj)/umd_key_sig_umh_blob.o: $(obj)/umd_key_sig_umh
+
+obj-$(CONFIG_UMD_KEY_SIG_HANDLER) += umd_key_sig_user.o
+umd_key_sig_user-objs += umd_key_sig_loader.o umd_key_sig_umh_blob.o
diff --git a/crypto/asymmetric_keys/umd_key_sig_loader.c b/crypto/asymmetric_keys/umd_key_sig_loader.c
new file mode 100644
index 00000000000..b959a42b9fd
--- /dev/null
+++ b/crypto/asymmetric_keys/umd_key_sig_loader.c
@@ -0,0 +1,32 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2023 Huawei Technologies Duesseldorf GmbH
+ *
+ * Author: Roberto Sassu <roberto.sassu@xxxxxxxxxx>
+ *
+ * Implement the loader of the UMD handler.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+
+#include "umd_key.h"
+
+extern char umd_key_umh_start;
+extern char umd_key_umh_end;
+
+MODULE_LICENSE("GPL");
+
+static int __init umd_key_umh_init(void)
+{
+ return umd_mgmt_load(&key_ops, &umd_key_umh_start, &umd_key_umh_end);
+}
+
+static void __exit umd_key_umh_exit(void)
+{
+ umd_mgmt_unload(&key_ops);
+}
+
+module_init(umd_key_umh_init);
+module_exit(umd_key_umh_exit);
diff --git a/crypto/asymmetric_keys/umd_key_sig_umh_blob.S b/crypto/asymmetric_keys/umd_key_sig_umh_blob.S
new file mode 100644
index 00000000000..954cbe891bd
--- /dev/null
+++ b/crypto/asymmetric_keys/umd_key_sig_umh_blob.S
@@ -0,0 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+ .section .init.rodata, "a"
+ .global umd_key_umh_start
+umd_key_umh_start:
+ .incbin "crypto/asymmetric_keys/umd_key_sig_umh"
+ .global umd_key_umh_end
+umd_key_umh_end:
diff --git a/crypto/asymmetric_keys/umd_key_sig_umh_user.c b/crypto/asymmetric_keys/umd_key_sig_umh_user.c
new file mode 100644
index 00000000000..21f53008762
--- /dev/null
+++ b/crypto/asymmetric_keys/umd_key_sig_umh_user.c
@@ -0,0 +1,84 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2023 Huawei Technologies Duesseldorf GmbH
+ *
+ * Author: Roberto Sassu <roberto.sassu@xxxxxxxxxx>
+ *
+ * Implement the UMD handler.
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <errno.h>
+
+#include "umd_key_sig_umh.h"
+
+FILE *debug_f;
+
+int main(int argc, char *argv[])
+{
+ struct msg_in *in = NULL;
+ struct msg_out *out = NULL;
+ size_t in_len, out_len;
+ loff_t pos;
+ int ret = 0;
+
+#ifdef debug
+ debug_f = fopen("/dev/kmsg", "a");
+ fprintf(debug_f, "<5>Started %s\n", argv[0]);
+ fflush(debug_f);
+#endif
+ in = malloc(sizeof(*in));
+ if (!in)
+ goto out;
+
+ out = malloc(sizeof(*out));
+ if (!out)
+ goto out;
+
+ while (1) {
+ int n;
+
+ in_len = sizeof(*in);
+ out_len = sizeof(*out);
+
+ memset(in, 0, in_len);
+ memset(out, 0, out_len);
+
+ pos = 0;
+ while (in_len) {
+ n = read(0, (void *)in + pos, in_len);
+ if (n <= 0) {
+ ret = -EIO;
+ goto out;
+ }
+ in_len -= n;
+ pos += n;
+ }
+
+ switch (in->cmd) {
+ default:
+ out->ret = -EOPNOTSUPP;
+ break;
+ }
+
+ pos = 0;
+ while (out_len) {
+ n = write(1, (void *)out + pos, out_len);
+ if (n <= 0) {
+ ret = -EIO;
+ goto out;
+ }
+ out_len -= n;
+ pos += n;
+ }
+ }
+out:
+ free(in);
+ free(out);
+#ifdef debug
+ fclose(debug_f);
+#endif
+ return ret;
+}
--
2.25.1