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, ast@kernel.org, daniel@iogearbox.net,
	andrii@kernel.org, martin.lau@linux.dev, song@kernel.org,
	yhs@fb.com, john.fastabend@gmail.com, kpsingh@kernel.org,
	sdf@google.com, haoluo@google.com, jolsa@kernel.org,
	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,
	Roberto Sassu <roberto.sassu@huawei.com>
Subject: [RFC][PATCH 5/6] selftests/bpf: Prepare a test for UMD-parsed signatures
Date: Tue, 25 Apr 2023 19:35:56 +0200	[thread overview]
Message-ID: <20230425173557.724688-6-roberto.sassu@huaweicloud.com> (raw)
In-Reply-To: <20230425173557.724688-1-roberto.sassu@huaweicloud.com>

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

Reuse the existing test for PKCS#7 signatures, to test also UMD-parsed
signatures.

Don't enable the test just yet, as the test would fail without a UMD parser
for PGP keys and signatures.

Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
---
 ...ify_pkcs7_sig.c => verify_pkcs7_umd_sig.c} | 109 ++++++++++++++----
 ...kcs7_sig.c => test_verify_pkcs7_umd_sig.c} |  18 ++-
 .../testing/selftests/bpf/verify_sig_setup.sh |  82 +++++++++++--
 3 files changed, 176 insertions(+), 33 deletions(-)
 rename tools/testing/selftests/bpf/prog_tests/{verify_pkcs7_sig.c => verify_pkcs7_umd_sig.c} (75%)
 rename tools/testing/selftests/bpf/progs/{test_verify_pkcs7_sig.c => test_verify_pkcs7_umd_sig.c} (82%)

diff --git a/tools/testing/selftests/bpf/prog_tests/verify_pkcs7_sig.c b/tools/testing/selftests/bpf/prog_tests/verify_pkcs7_umd_sig.c
similarity index 75%
rename from tools/testing/selftests/bpf/prog_tests/verify_pkcs7_sig.c
rename to tools/testing/selftests/bpf/prog_tests/verify_pkcs7_umd_sig.c
index dd7f2bc7004..94d78146989 100644
--- a/tools/testing/selftests/bpf/prog_tests/verify_pkcs7_sig.c
+++ b/tools/testing/selftests/bpf/prog_tests/verify_pkcs7_umd_sig.c
@@ -18,7 +18,7 @@
 #include <linux/keyctl.h>
 #include <test_progs.h>
 
-#include "test_verify_pkcs7_sig.skel.h"
+#include "test_verify_pkcs7_umd_sig.skel.h"
 
 #define MAX_DATA_SIZE (1024 * 1024)
 #define MAX_SIG_SIZE 1024
@@ -29,6 +29,24 @@
 /* In stripped ARM and x86-64 modules, ~ is surprisingly rare. */
 #define MODULE_SIG_STRING "~Module signature appended~\n"
 
+#define PKEY_ID_PGP 0
+#define PKEY_ID_X509 1
+#define PKEY_ID_PKCS7 2
+
+static char *key_types_str[PKEY_ID_PKCS7 + 1] = {
+	[PKEY_ID_PGP] = "pgp",
+	[PKEY_ID_X509] = "x509",
+	[PKEY_ID_PKCS7] = "pkcs7",
+};
+
+enum algos { ALGO_RSA, ALGO_ECDSA_P256, ALGO_ECDSA_P384, ALGO__LAST };
+
+static char *algos_str[ALGO_ECDSA_P384 + 1] = {
+	[ALGO_RSA] = "rsa",
+	[ALGO_ECDSA_P256] = "ecdsa_p256",
+	[ALGO_ECDSA_P384] = "ecdsa_p384",
+};
+
 /*
  * Module signature information block.
  *
@@ -74,13 +92,15 @@ static int libbpf_print_cb(enum libbpf_print_level level, const char *fmt,
 	return 0;
 }
 
-static int _run_setup_process(const char *setup_dir, const char *cmd)
+static int _run_setup_process(const char *setup_dir, const char *cmd,
+			      __u8 key_type, __u8 pkey_algo)
 {
 	int child_pid, child_status;
 
 	child_pid = fork();
 	if (child_pid == 0) {
-		execlp("./verify_sig_setup.sh", "./verify_sig_setup.sh", cmd,
+		execlp("./verify_sig_setup.sh", "./verify_sig_setup.sh",
+		       cmd, key_types_str[key_type], algos_str[pkey_algo] ?: "",
 		       setup_dir, NULL);
 		exit(errno);
 
@@ -92,7 +112,8 @@ static int _run_setup_process(const char *setup_dir, const char *cmd)
 	return -EINVAL;
 }
 
-static int populate_data_item_str(const char *tmp_dir, struct data *data_item)
+static int populate_data_item_str(const char *tmp_dir, __u8 key_type,
+				  struct data *data_item)
 {
 	struct stat st;
 	char data_template[] = "/tmp/dataXXXXXX";
@@ -123,10 +144,26 @@ static int populate_data_item_str(const char *tmp_dir, struct data *data_item)
 	}
 
 	if (child_pid == 0) {
-		snprintf(path, sizeof(path), "%s/signing_key.pem", tmp_dir);
-
-		return execlp("./sign-file", "./sign-file", "-d", "sha256",
-			      path, path, data_template, NULL);
+		if (key_type == PKEY_ID_PKCS7) {
+			snprintf(path, sizeof(path), "%s/signing_key.pem",
+				 tmp_dir);
+
+			return execlp("./sign-file", "./sign-file", "-d",
+				      "sha256", path, path, data_template,
+				      NULL);
+		} else {
+			snprintf(path, sizeof(path), "%s.gpg", data_template);
+
+			return execlp("gpg", "gpg", "--no-options",
+				      "--no-auto-check-trustdb",
+				      "--no-permission-warning",
+				      "--default-key", "eBPF_UMD_Test",
+				      "--sign", "-o", path, "--batch", "--yes",
+				      "--compress-algo=none", "-b",
+				      "--passphrase", "abc",
+				      "--pinentry-mode", "loopback", "-q",
+				      data_template, NULL);
+		}
 	}
 
 	waitpid(child_pid, &child_status, 0);
@@ -135,7 +172,10 @@ static int populate_data_item_str(const char *tmp_dir, struct data *data_item)
 	if (ret)
 		goto out;
 
-	snprintf(path, sizeof(path), "%s.p7s", data_template);
+	if (key_type == PKEY_ID_PKCS7)
+		snprintf(path, sizeof(path), "%s.p7s", data_template);
+	else
+		snprintf(path, sizeof(path), "%s.gpg", data_template);
 
 	ret = stat(path, &st);
 	if (ret == -1) {
@@ -254,12 +294,12 @@ static int populate_data_item_mod(struct data *data_item)
 	return ret;
 }
 
-void test_verify_pkcs7_sig(void)
+static void test_verify_pkcs7_umd_sig(__u8 key_type, __u8 pkey_algo)
 {
 	libbpf_print_fn_t old_print_cb;
 	char tmp_dir_template[] = "/tmp/verify_sigXXXXXX";
 	char *tmp_dir;
-	struct test_verify_pkcs7_sig *skel = NULL;
+	struct test_verify_pkcs7_umd_sig *skel = NULL;
 	struct bpf_map *map;
 	struct data data;
 	int ret, zero = 0;
@@ -272,37 +312,38 @@ void test_verify_pkcs7_sig(void)
 	if (!ASSERT_OK_PTR(tmp_dir, "mkdtemp"))
 		return;
 
-	ret = _run_setup_process(tmp_dir, "setup");
+	ret = _run_setup_process(tmp_dir, "setup", key_type, pkey_algo);
 	if (!ASSERT_OK(ret, "_run_setup_process"))
 		goto close_prog;
 
-	skel = test_verify_pkcs7_sig__open();
-	if (!ASSERT_OK_PTR(skel, "test_verify_pkcs7_sig__open"))
+	skel = test_verify_pkcs7_umd_sig__open();
+	if (!ASSERT_OK_PTR(skel, "test_verify_pkcs7_umd_sig__open"))
 		goto close_prog;
 
 	old_print_cb = libbpf_set_print(libbpf_print_cb);
-	ret = test_verify_pkcs7_sig__load(skel);
+	ret = test_verify_pkcs7_umd_sig__load(skel);
 	libbpf_set_print(old_print_cb);
 
 	if (ret < 0 && kfunc_not_supported) {
 		printf(
-		  "%s:SKIP:bpf_verify_pkcs7_signature() kfunc not supported\n",
+		  "%s:SKIP:bpf_verify_*_signature() kfunc not supported\n",
 		  __func__);
 		test__skip();
 		goto close_prog;
 	}
 
-	if (!ASSERT_OK(ret, "test_verify_pkcs7_sig__load"))
+	if (!ASSERT_OK(ret, "test_verify_pkcs7_umd_sig__load"))
 		goto close_prog;
 
-	ret = test_verify_pkcs7_sig__attach(skel);
-	if (!ASSERT_OK(ret, "test_verify_pkcs7_sig__attach"))
+	ret = test_verify_pkcs7_umd_sig__attach(skel);
+	if (!ASSERT_OK(ret, "test_verify_pkcs7_umd_sig__attach"))
 		goto close_prog;
 
 	map = bpf_object__find_map_by_name(skel->obj, "data_input");
 	if (!ASSERT_OK_PTR(map, "data_input not found"))
 		goto close_prog;
 
+	skel->bss->key_type = key_type;
 	skel->bss->monitored_pid = getpid();
 
 	/* Test without data and signature. */
@@ -313,7 +354,7 @@ void test_verify_pkcs7_sig(void)
 		goto close_prog;
 
 	/* Test successful signature verification with session keyring. */
-	ret = populate_data_item_str(tmp_dir, &data);
+	ret = populate_data_item_str(tmp_dir, key_type, &data);
 	if (!ASSERT_OK(ret, "populate_data_item_str"))
 		goto close_prog;
 
@@ -363,9 +404,13 @@ void test_verify_pkcs7_sig(void)
 	if (!ASSERT_LT(ret, 0, "bpf_map_update_elem data_input"))
 		goto close_prog;
 
-	ret = populate_data_item_mod(&data);
-	if (!ASSERT_OK(ret, "populate_data_item_mod"))
-		goto close_prog;
+	data.data_len = 0;
+
+	if (key_type == PKEY_ID_PKCS7) {
+		ret = populate_data_item_mod(&data);
+		if (!ASSERT_OK(ret, "populate_data_item_mod"))
+			goto close_prog;
+	}
 
 	/* Test signature verification with system keyrings. */
 	if (data.data_len) {
@@ -392,11 +437,25 @@ void test_verify_pkcs7_sig(void)
 	}
 
 close_prog:
-	_run_setup_process(tmp_dir, "cleanup");
+	_run_setup_process(tmp_dir, "cleanup", key_type, pkey_algo);
 
 	if (!skel)
 		return;
 
 	skel->bss->monitored_pid = 0;
-	test_verify_pkcs7_sig__destroy(skel);
+	test_verify_pkcs7_umd_sig__destroy(skel);
+}
+
+void test_verify_pkcs7_sig(void)
+{
+	return test_verify_pkcs7_umd_sig(PKEY_ID_PKCS7, ALGO__LAST);
+}
+
+void test_verify_umd_sig(void)
+{
+	int i;
+
+	/* Change the limit to ALGO__LAST when UMD supports PGP. */
+	for (i = 0; i < 0; i++)
+		test_verify_pkcs7_umd_sig(PKEY_ID_PGP, i);
 }
diff --git a/tools/testing/selftests/bpf/progs/test_verify_pkcs7_sig.c b/tools/testing/selftests/bpf/progs/test_verify_pkcs7_umd_sig.c
similarity index 82%
rename from tools/testing/selftests/bpf/progs/test_verify_pkcs7_sig.c
rename to tools/testing/selftests/bpf/progs/test_verify_pkcs7_umd_sig.c
index 7748cc23de8..e22b013a4e4 100644
--- a/tools/testing/selftests/bpf/progs/test_verify_pkcs7_sig.c
+++ b/tools/testing/selftests/bpf/progs/test_verify_pkcs7_umd_sig.c
@@ -20,10 +20,14 @@ extern void bpf_key_put(struct bpf_key *key) __ksym;
 extern int bpf_verify_pkcs7_signature(struct bpf_dynptr *data_ptr,
 				      struct bpf_dynptr *sig_ptr,
 				      struct bpf_key *trusted_keyring) __ksym;
+extern int bpf_verify_umd_signature(struct bpf_dynptr *data_ptr,
+				    struct bpf_dynptr *sig_ptr,
+				    struct bpf_key *trusted_keyring) __ksym;
 
 __u32 monitored_pid;
 __u32 user_keyring_serial;
 __u64 system_keyring_id;
+__u8 key_type;
 
 struct data {
 	__u8 data[MAX_DATA_SIZE];
@@ -86,7 +90,19 @@ int BPF_PROG(bpf, int cmd, union bpf_attr *attr, unsigned int size)
 	if (!trusted_keyring)
 		return -ENOENT;
 
-	ret = bpf_verify_pkcs7_signature(&data_ptr, &sig_ptr, trusted_keyring);
+	switch (key_type) {
+	case PKEY_ID_PKCS7:
+		ret = bpf_verify_pkcs7_signature(&data_ptr, &sig_ptr,
+						 trusted_keyring);
+		break;
+	case PKEY_ID_PGP:
+		ret = bpf_verify_umd_signature(&data_ptr, &sig_ptr,
+					       trusted_keyring);
+		break;
+	default:
+		ret = -EOPNOTSUPP;
+		break;
+	}
 
 	bpf_key_put(trusted_keyring);
 
diff --git a/tools/testing/selftests/bpf/verify_sig_setup.sh b/tools/testing/selftests/bpf/verify_sig_setup.sh
index ba08922b4a2..5f6e612aae9 100755
--- a/tools/testing/selftests/bpf/verify_sig_setup.sh
+++ b/tools/testing/selftests/bpf/verify_sig_setup.sh
@@ -26,13 +26,39 @@ subjectKeyIdentifier=hash
 authorityKeyIdentifier=keyid
 "
 
+gpg_genkey_content_common="\
+     Name-Real: eBPF_UMD_Test
+     Name-Comment: eBPF_UMD_Test
+     Name-Email: ebpf_umd_test@localhost
+     Expire-Date: 0
+     Passphrase: abc
+     %commit
+"
+gpg_genkey_content_rsa="\
+     Key-Type: RSA
+     Key-Length: 4096
+     $gpg_genkey_content_common
+"
+
+gpg_genkey_content_ecdsa_p256="\
+     Key-Type: ECDSA
+     Key-Curve: NIST P-256
+     $gpg_genkey_content_common
+"
+
+gpg_genkey_content_ecdsa_p384="\
+     Key-Type: ECDSA
+     Key-Curve: NIST P-384
+     $gpg_genkey_content_common
+"
+
 usage()
 {
-	echo "Usage: $0 <setup|cleanup <existing_tmp_dir>"
+	echo "Usage: $0 <setup|cleanup> <key type> <existing_tmp_dir>"
 	exit 1
 }
 
-setup()
+setup_pkcs7()
 {
 	local tmp_dir="$1"
 
@@ -52,11 +78,37 @@ setup()
 	keyctl link $key_id $keyring_id
 }
 
-cleanup() {
+setup_pgp()
+{
+	local tmp_dir="$1"
+	local varname="gpg_genkey_content_$2"
+
+	modprobe ecdsa_generic
+
+	echo "${!varname}" > ${tmp_dir}/gpg.genkey
+	gpg --batch --generate-key ${tmp_dir}/gpg.genkey
+
+	key_id=$(gpg --export eBPF_UMD_Test | keyctl padd asymmetric ebpf_testing_key @s)
+	keyring_id=$(keyctl newring ebpf_testing_keyring @s)
+	keyctl link $key_id $keyring_id
+}
+
+cleanup_pkcs7() {
+	local tmp_dir="$1"
+
+	keyctl unlink $(keyctl search @s asymmetric ebpf_testing_key) @s
+	keyctl unlink $(keyctl search @s keyring ebpf_testing_keyring) @s
+	rm -rf ${tmp_dir}
+}
+
+cleanup_pgp() {
 	local tmp_dir="$1"
 
 	keyctl unlink $(keyctl search @s asymmetric ebpf_testing_key) @s
 	keyctl unlink $(keyctl search @s keyring ebpf_testing_keyring) @s
+	key_fingerprint=$(gpg --fingerprint --with-colons eBPF_UMD_Test | awk -F ":" '$1 == "fpr" {print $(NF-1)}')
+	gpg --delete-secret-key --batch --yes $key_fingerprint
+	gpg --delete-key --batch --yes $key_fingerprint
 	rm -rf ${tmp_dir}
 }
 
@@ -75,17 +127,33 @@ catch()
 
 main()
 {
-	[[ $# -ne 2 ]] && usage
+	[[ $# -ne 4 ]] && usage
 
 	local action="$1"
-	local tmp_dir="$2"
+	local key_type="$2"
+	local key_algo="$3"
+	local tmp_dir="$4"
 
 	[[ ! -d "${tmp_dir}" ]] && echo "Directory ${tmp_dir} doesn't exist" && exit 1
 
 	if [[ "${action}" == "setup" ]]; then
-		setup "${tmp_dir}"
+		if [[ "${key_type}" == "pkcs7" ]]; then
+			setup_pkcs7 "${tmp_dir}"
+		elif [[ "${key_type}" == "pgp" ]]; then
+			setup_pgp "${tmp_dir}" "${key_algo}"
+		else
+			echo "Unknown key type: ${key_type}"
+			exit 1
+		fi
 	elif [[ "${action}" == "cleanup" ]]; then
-		cleanup "${tmp_dir}"
+		if [[ "${key_type}" == "pkcs7" ]]; then
+			cleanup_pkcs7 "${tmp_dir}"
+		elif [[ "${key_type}" == "pgp" ]]; then
+			cleanup_pgp "${tmp_dir}"
+		else
+			echo "Unknown key type: ${key_type}"
+			exit 1
+		fi
 	else
 		echo "Unknown action: ${action}"
 		exit 1
-- 
2.25.1


  parent reply	other threads:[~2023-04-25 17:39 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-04-25 17:35 [RFC][PATCH 0/6] KEYS: Introduce user mode key and signature parsers Roberto Sassu
2023-04-25 17:35 ` [RFC][PATCH 1/6] KEYS: asymmetric: Introduce UMD-based asymmetric key parser Roberto Sassu
2023-04-25 17:35 ` [RFC][PATCH 2/6] KEYS: asymmetric: Introduce UMD-based asymmetric key signature parser Roberto Sassu
2023-04-25 17:35 ` [RFC][PATCH 3/6] verification: Introduce verify_umd_signature() and verify_umd_message_sig() Roberto Sassu
2023-04-26  0:28   ` Jarkko Sakkinen
2023-04-26 11:42     ` Roberto Sassu
2023-04-26 18:25       ` Jarkko Sakkinen
2023-04-26 18:27         ` Jarkko Sakkinen
2023-04-25 17:35 ` [RFC][PATCH 4/6] bpf: Introduce bpf_verify_umd_signature() kfunc Roberto Sassu
2023-04-25 21:25   ` Yonghong Song
2023-04-26 11:44     ` Roberto Sassu
2023-04-25 17:35 ` Roberto Sassu [this message]
2023-04-25 17:35 ` [RFC][PATCH 6/6] KEYS: asymmetric: Add UMD handler 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=20230425173557.724688-6-roberto.sassu@huaweicloud.com \
    --to=roberto.sassu@huaweicloud.com \
    --cc=andrii@kernel.org \
    --cc=ast@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=daniel@iogearbox.net \
    --cc=davem@davemloft.net \
    --cc=dhowells@redhat.com \
    --cc=dwmw2@infradead.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=kpsingh@kernel.org \
    --cc=linux-crypto@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-kselftest@vger.kernel.org \
    --cc=linux-trace-kernel@vger.kernel.org \
    --cc=martin.lau@linux.dev \
    --cc=mhiramat@kernel.org \
    --cc=mykolal@fb.com \
    --cc=roberto.sassu@huawei.com \
    --cc=rostedt@goodmis.org \
    --cc=sdf@google.com \
    --cc=shuah@kernel.org \
    --cc=song@kernel.org \
    --cc=yhs@fb.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.