All of lore.kernel.org
 help / color / mirror / Atom feed
* [kvm-unit-tests PATCH v4 0/5] s390x: Attestation tests
@ 2022-04-21  9:45 Steffen Eiden
  2022-04-21  9:45 ` [kvm-unit-tests PATCH v4 1/5] s390x: uv-host: Add invalid command attestation check Steffen Eiden
                   ` (4 more replies)
  0 siblings, 5 replies; 10+ messages in thread
From: Steffen Eiden @ 2022-04-21  9:45 UTC (permalink / raw)
  To: Thomas Huth, Janosch Frank, Claudio Imbrenda, David Hildenbrand
  Cc: kvm, linux-s390

This series adds some test in s390x/uv-guest.c verifying error paths of the
Request Attestation Measurement UVC.
Also adds a test in s390x/uv-host.c to verify that the
Request Attestation Measurement UVC cannot be called in guest1.

Additionally, adds a shared bit test and removes duplicated tests.

v3->v4:
  * renamed PATCH 1
  * moved attestation guest tests into own file
  * rebased onto current master

v2->v3:
  * added test for share bits as new PATCH 4/5
  * added r-b from Claudio in PATCH 1/4
  * replaced all u* with uint*_t
  * incorporated misc feedback from Claudio

v1->v2:
  * renamed 'uv_get_info(void)' to 'uv_get_query_data(void)'
  * renamed various fields in 'struct uv_arcb_v1'
  * added a test for invalid additional size
  * added r-b from Janosch in PATCH 1/4
  * added r-b from Janosch in PATCH 3/4

Steffen Eiden (5):
  s390x: uv-host: Add invalid command attestation check
  s390x: lib: Add QUI getter
  s390x: uv-guest: remove duplicated checks
  s390x: uv-guest: add share bit test
  s390x: uv-guest: Add attestation tests

 lib/s390x/asm/uv.h |  28 +++++-
 lib/s390x/uv.c     |   8 ++
 lib/s390x/uv.h     |   1 +
 s390x/Makefile     |   1 +
 s390x/pv-attest.c  | 225 +++++++++++++++++++++++++++++++++++++++++++++
 s390x/uv-guest.c   |  49 ++++++----
 s390x/uv-host.c    |   1 +
 7 files changed, 293 insertions(+), 20 deletions(-)
 create mode 100644 s390x/pv-attest.c

-- 
2.30.2


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [kvm-unit-tests PATCH v4 1/5] s390x: uv-host: Add invalid command attestation check
  2022-04-21  9:45 [kvm-unit-tests PATCH v4 0/5] s390x: Attestation tests Steffen Eiden
@ 2022-04-21  9:45 ` Steffen Eiden
  2022-04-21  9:45 ` [kvm-unit-tests PATCH v4 2/5] s390x: lib: Add QUI getter Steffen Eiden
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 10+ messages in thread
From: Steffen Eiden @ 2022-04-21  9:45 UTC (permalink / raw)
  To: Thomas Huth, Janosch Frank, Claudio Imbrenda, David Hildenbrand
  Cc: kvm, linux-s390

Adds an invalid command test for attestation in the uv-host.

Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
Reviewed-by: Janosch Frank <frankja@linux.ibm.com>
Reviewed-by: Claudio Imbrenda <imbrenda@linux.ibm.com>
---
 lib/s390x/asm/uv.h | 23 ++++++++++++++++++++++-
 s390x/uv-host.c    |  1 +
 2 files changed, 23 insertions(+), 1 deletion(-)

diff --git a/lib/s390x/asm/uv.h b/lib/s390x/asm/uv.h
index 70bf65c4..7c8c399d 100644
--- a/lib/s390x/asm/uv.h
+++ b/lib/s390x/asm/uv.h
@@ -1,7 +1,7 @@
 /*
  * s390x Ultravisor related definitions
  *
- * Copyright (c) 2020 IBM Corp
+ * Copyright IBM Corp. 2020, 2022
  *
  * Authors:
  *  Janosch Frank <frankja@linux.ibm.com>
@@ -47,6 +47,7 @@
 #define UVC_CMD_UNPIN_PAGE_SHARED	0x0342
 #define UVC_CMD_SET_SHARED_ACCESS	0x1000
 #define UVC_CMD_REMOVE_SHARED_ACCESS	0x1001
+#define UVC_CMD_ATTESTATION		0x1020
 
 /* Bits in installed uv calls */
 enum uv_cmds_inst {
@@ -71,6 +72,7 @@ enum uv_cmds_inst {
 	BIT_UVC_CMD_UNSHARE_ALL = 20,
 	BIT_UVC_CMD_PIN_PAGE_SHARED = 21,
 	BIT_UVC_CMD_UNPIN_PAGE_SHARED = 22,
+	BIT_UVC_CMD_ATTESTATION = 28,
 };
 
 struct uv_cb_header {
@@ -178,6 +180,25 @@ struct uv_cb_cfs {
 	u64 paddr;
 }  __attribute__((packed))  __attribute__((aligned(8)));
 
+/* Retrieve Attestation Measurement */
+struct uv_cb_attest {
+	struct uv_cb_header header;	/* 0x0000 */
+	uint64_t reserved08[2];		/* 0x0008 */
+	uint64_t arcb_addr;		/* 0x0018 */
+	uint64_t continuation_token;	/* 0x0020 */
+	uint8_t  reserved28[6];		/* 0x0028 */
+	uint16_t user_data_length;	/* 0x002e */
+	uint8_t  user_data[256];	/* 0x0030 */
+	uint32_t reserved130[3];	/* 0x0130 */
+	uint32_t measurement_length;	/* 0x013c */
+	uint64_t measurement_address;	/* 0x0140 */
+	uint8_t  config_uid[16];	/* 0x0148 */
+	uint32_t reserved158;		/* 0x0158 */
+	uint32_t add_data_length;	/* 0x015c */
+	uint64_t add_data_address;	/* 0x0160 */
+	uint64_t reserved168[4];	/* 0x0168 */
+}  __attribute__((packed))  __attribute__((aligned(8)));
+
 /* Set Secure Config Parameter */
 struct uv_cb_ssc {
 	struct uv_cb_header header;
diff --git a/s390x/uv-host.c b/s390x/uv-host.c
index d3018e3c..726bcfa5 100644
--- a/s390x/uv-host.c
+++ b/s390x/uv-host.c
@@ -418,6 +418,7 @@ static struct cmd_list invalid_cmds[] = {
 	{ "bogus", 0x4242, sizeof(struct uv_cb_header), -1},
 	{ "share", UVC_CMD_SET_SHARED_ACCESS, sizeof(struct uv_cb_share), BIT_UVC_CMD_SET_SHARED_ACCESS },
 	{ "unshare", UVC_CMD_REMOVE_SHARED_ACCESS, sizeof(struct uv_cb_share), BIT_UVC_CMD_REMOVE_SHARED_ACCESS },
+	{ "attest", UVC_CMD_ATTESTATION, sizeof(struct uv_cb_attest), BIT_UVC_CMD_ATTESTATION },
 	{ NULL, 0, 0 },
 };
 
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [kvm-unit-tests PATCH v4 2/5] s390x: lib: Add QUI getter
  2022-04-21  9:45 [kvm-unit-tests PATCH v4 0/5] s390x: Attestation tests Steffen Eiden
  2022-04-21  9:45 ` [kvm-unit-tests PATCH v4 1/5] s390x: uv-host: Add invalid command attestation check Steffen Eiden
@ 2022-04-21  9:45 ` Steffen Eiden
  2022-04-21 11:26   ` Janosch Frank
  2022-04-21  9:45 ` [kvm-unit-tests PATCH v4 3/5] s390x: uv-guest: remove duplicated checks Steffen Eiden
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 10+ messages in thread
From: Steffen Eiden @ 2022-04-21  9:45 UTC (permalink / raw)
  To: Thomas Huth, Janosch Frank, Claudio Imbrenda, David Hildenbrand
  Cc: kvm, linux-s390

Some tests need the information provided by the QUI UVC and lib/s390x/uv.c
already has cached the qui result. Let's add a function to avoid
unnecessary QUI UVCs.

Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
---
 lib/s390x/uv.c | 8 ++++++++
 lib/s390x/uv.h | 1 +
 2 files changed, 9 insertions(+)

diff --git a/lib/s390x/uv.c b/lib/s390x/uv.c
index 6fe11dff..602cbbfc 100644
--- a/lib/s390x/uv.c
+++ b/lib/s390x/uv.c
@@ -47,6 +47,14 @@ bool uv_query_test_call(unsigned int nr)
 	return test_bit_inv(nr, uvcb_qui.inst_calls_list);
 }
 
+const struct uv_cb_qui *uv_get_query_data(void)
+{
+	/* Query needs to be called first */
+	assert(uvcb_qui.header.rc);
+
+	return &uvcb_qui;
+}
+
 int uv_setup(void)
 {
 	if (!test_facility(158))
diff --git a/lib/s390x/uv.h b/lib/s390x/uv.h
index 8175d9c6..44264861 100644
--- a/lib/s390x/uv.h
+++ b/lib/s390x/uv.h
@@ -8,6 +8,7 @@
 bool uv_os_is_guest(void);
 bool uv_os_is_host(void);
 bool uv_query_test_call(unsigned int nr);
+const struct uv_cb_qui *uv_get_query_data(void);
 void uv_init(void);
 int uv_setup(void);
 void uv_create_guest(struct vm *vm);
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [kvm-unit-tests PATCH v4 3/5] s390x: uv-guest: remove duplicated checks
  2022-04-21  9:45 [kvm-unit-tests PATCH v4 0/5] s390x: Attestation tests Steffen Eiden
  2022-04-21  9:45 ` [kvm-unit-tests PATCH v4 1/5] s390x: uv-host: Add invalid command attestation check Steffen Eiden
  2022-04-21  9:45 ` [kvm-unit-tests PATCH v4 2/5] s390x: lib: Add QUI getter Steffen Eiden
@ 2022-04-21  9:45 ` Steffen Eiden
  2022-04-21  9:45 ` [kvm-unit-tests PATCH v4 4/5] s390x: uv-guest: add share bit test Steffen Eiden
  2022-04-21  9:45 ` [kvm-unit-tests PATCH v4 5/5] s390x: uv-guest: Add attestation tests Steffen Eiden
  4 siblings, 0 replies; 10+ messages in thread
From: Steffen Eiden @ 2022-04-21  9:45 UTC (permalink / raw)
  To: Thomas Huth, Janosch Frank, Claudio Imbrenda, David Hildenbrand
  Cc: kvm, linux-s390

Removing some tests which are done at other points in the code
implicitly.

In lib/s390x/uc.c#setup_uv(void) the rc of the qui result is verified
using asserts.
The whole test is fenced by lib/s390x/uc.c#uv_os_is_guest(void) that
checks if SET and REMOVE SHARED is present.

Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
Reviewed-by: Janosch Frank <frankja@linux.ibm.com>
---
 s390x/uv-guest.c | 22 +++++++---------------
 1 file changed, 7 insertions(+), 15 deletions(-)

diff --git a/s390x/uv-guest.c b/s390x/uv-guest.c
index 99120cae..728c60aa 100644
--- a/s390x/uv-guest.c
+++ b/s390x/uv-guest.c
@@ -69,23 +69,15 @@ static void test_query(void)
 	cc = uv_call(0, (u64)&uvcb);
 	report(cc == 1 && uvcb.header.rc == UVC_RC_INV_LEN, "length");
 
-	uvcb.header.len = sizeof(uvcb);
-	cc = uv_call(0, (u64)&uvcb);
-	report((!cc && uvcb.header.rc == UVC_RC_EXECUTED) ||
-	       (cc == 1 && uvcb.header.rc == 0x100),
-		"successful query");
-
 	/*
-	 * These bits have been introduced with the very first
-	 * Ultravisor version and are expected to always be available
-	 * because they are basic building blocks.
+	 * BIT_UVC_CMD_QUI, BIT_UVC_CMD_SET_SHARED_ACCESS and
+	 * BIT_UVC_CMD_REMOVE_SHARED_ACCESS are always present as they
+	 * have been introduced with the first Ultravisor version.
+	 * However, we only need to check for QUI as
+	 * SET/REMOVE SHARED are used to fence this test to be only
+	 * executed by protected guests.
 	 */
-	report(test_bit_inv(BIT_UVC_CMD_QUI, &uvcb.inst_calls_list[0]),
-	       "query indicated");
-	report(test_bit_inv(BIT_UVC_CMD_SET_SHARED_ACCESS, &uvcb.inst_calls_list[0]),
-	       "share indicated");
-	report(test_bit_inv(BIT_UVC_CMD_REMOVE_SHARED_ACCESS, &uvcb.inst_calls_list[0]),
-	       "unshare indicated");
+	report(uv_query_test_call(BIT_UVC_CMD_QUI), "query indicated");
 	report_prefix_pop();
 }
 
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [kvm-unit-tests PATCH v4 4/5] s390x: uv-guest: add share bit test
  2022-04-21  9:45 [kvm-unit-tests PATCH v4 0/5] s390x: Attestation tests Steffen Eiden
                   ` (2 preceding siblings ...)
  2022-04-21  9:45 ` [kvm-unit-tests PATCH v4 3/5] s390x: uv-guest: remove duplicated checks Steffen Eiden
@ 2022-04-21  9:45 ` Steffen Eiden
  2022-04-21 11:33   ` Janosch Frank
  2022-04-21  9:45 ` [kvm-unit-tests PATCH v4 5/5] s390x: uv-guest: Add attestation tests Steffen Eiden
  4 siblings, 1 reply; 10+ messages in thread
From: Steffen Eiden @ 2022-04-21  9:45 UTC (permalink / raw)
  To: Thomas Huth, Janosch Frank, Claudio Imbrenda, David Hildenbrand
  Cc: kvm, linux-s390

The UV facility bits shared/unshared must both be set or none.

Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
---
 s390x/uv-guest.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/s390x/uv-guest.c b/s390x/uv-guest.c
index 728c60aa..77057bd2 100644
--- a/s390x/uv-guest.c
+++ b/s390x/uv-guest.c
@@ -159,6 +159,14 @@ static void test_invalid(void)
 	report_prefix_pop();
 }
 
+static void test_share_bits(void)
+{
+	bool unshare = uv_query_test_call(BIT_UVC_CMD_REMOVE_SHARED_ACCESS);
+	bool share = uv_query_test_call(BIT_UVC_CMD_SET_SHARED_ACCESS);
+
+	report(!(share ^ unshare), "share bits");
+}
+
 int main(void)
 {
 	bool has_uvc = test_facility(158);
@@ -169,6 +177,12 @@ int main(void)
 		goto done;
 	}
 
+	/*
+	 * Needs to be done before the guest-fence,
+	 * as the fence tests if both shared bits are present
+	 */
+	test_share_bits();
+
 	if (!uv_os_is_guest()) {
 		report_skip("Not a protected guest");
 		goto done;
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [kvm-unit-tests PATCH v4 5/5] s390x: uv-guest: Add attestation tests
  2022-04-21  9:45 [kvm-unit-tests PATCH v4 0/5] s390x: Attestation tests Steffen Eiden
                   ` (3 preceding siblings ...)
  2022-04-21  9:45 ` [kvm-unit-tests PATCH v4 4/5] s390x: uv-guest: add share bit test Steffen Eiden
@ 2022-04-21  9:45 ` Steffen Eiden
  2022-04-26  9:22   ` Janosch Frank
  4 siblings, 1 reply; 10+ messages in thread
From: Steffen Eiden @ 2022-04-21  9:45 UTC (permalink / raw)
  To: Thomas Huth, Janosch Frank, Claudio Imbrenda, David Hildenbrand
  Cc: kvm, linux-s390

Adds several tests to verify correct error paths of attestation.

Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
---
 lib/s390x/asm/uv.h |   5 +-
 s390x/Makefile     |   1 +
 s390x/pv-attest.c  | 225 +++++++++++++++++++++++++++++++++++++++++++++
 s390x/uv-guest.c   |  13 ++-
 4 files changed, 240 insertions(+), 4 deletions(-)
 create mode 100644 s390x/pv-attest.c

diff --git a/lib/s390x/asm/uv.h b/lib/s390x/asm/uv.h
index 7c8c399d..38920461 100644
--- a/lib/s390x/asm/uv.h
+++ b/lib/s390x/asm/uv.h
@@ -108,7 +108,10 @@ struct uv_cb_qui {
 	u8  reserved88[158 - 136];	/* 0x0088 */
 	uint16_t max_guest_cpus;	/* 0x009e */
 	u64 uv_feature_indications;	/* 0x00a0 */
-	u8  reserveda8[200 - 168];	/* 0x00a8 */
+	uint8_t  reserveda8[224 - 168];	/* 0x00a8 */
+	uint64_t supp_att_hdr_ver;	/* 0x00e0 */
+	uint64_t supp_paf;		/* 0x00e8 */
+	uint8_t  reservedf0[256 - 240];	/* 0x00f0 */
 }  __attribute__((packed))  __attribute__((aligned(8)));
 
 struct uv_cb_cgc {
diff --git a/s390x/Makefile b/s390x/Makefile
index 8ff84db5..5a49d1e7 100644
--- a/s390x/Makefile
+++ b/s390x/Makefile
@@ -29,6 +29,7 @@ tests += $(TEST_DIR)/mvpg-sie.elf
 tests += $(TEST_DIR)/spec_ex-sie.elf
 tests += $(TEST_DIR)/firq.elf
 tests += $(TEST_DIR)/epsw.elf
+tests += $(TEST_DIR)/pv-attest.elf
 
 pv-tests += $(TEST_DIR)/pv-diags.elf
 
diff --git a/s390x/pv-attest.c b/s390x/pv-attest.c
new file mode 100644
index 00000000..e31780a3
--- /dev/null
+++ b/s390x/pv-attest.c
@@ -0,0 +1,225 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Retrieve Attestation Measurement Utravisor Call tests
+ *
+ * Copyright IBM Corp. 2022
+ *
+ * Authors:
+ *  Steffen Eiden <seiden@linux.ibm.com>
+ */
+
+#include <libcflat.h>
+#include <alloc_page.h>
+#include <asm/page.h>
+#include <asm/facility.h>
+#include <asm/uv.h>
+#include <sclp.h>
+#include <uv.h>
+
+#define ARCB_VERSION_NONE 0
+#define ARCB_VERSION_1 0x0100
+#define ARCB_MEAS_NONE 0
+#define ARCB_MEAS_HMAC_SHA512 1
+#define MEASUREMENT_SIZE_HMAC_SHA512 64
+#define PAF_PHKH_ATT (1ULL << 61)
+#define ADDITIONAL_SIZE_PAF_PHKH_ATT 32
+/* arcb with one key slot and no nonce */
+struct uv_arcb_v1 {
+	uint64_t reserved0;		/* 0x0000 */
+	uint32_t req_ver;		/* 0x0008 */
+	uint32_t req_len;		/* 0x000c */
+	uint8_t  iv[12];		/* 0x0010 */
+	uint32_t reserved1c;		/* 0x001c */
+	uint8_t  reserved20[7];		/* 0x0020 */
+	uint8_t  nks;			/* 0x0027 */
+	int32_t reserved28;		/* 0x0028 */
+	uint32_t sea;			/* 0x002c */
+	uint64_t plaint_att_flags;	/* 0x0030 */
+	uint32_t meas_alg_id;		/* 0x0038 */
+	uint32_t reserved3c;		/* 0x003c */
+	uint8_t  cpk[160];		/* 0x0040 */
+	uint8_t  key_slot[80];		/* 0x00e0 */
+	uint8_t  meas_key[64];		/* 0x0130 */
+	uint8_t  tag[16];		/* 0x0170 */
+} __attribute__((packed));
+
+struct attest_request_v1 {
+	struct uv_arcb_v1 arcb;
+	uint8_t measurement[MEASUREMENT_SIZE_HMAC_SHA512];
+	uint8_t additional[ADDITIONAL_SIZE_PAF_PHKH_ATT];
+};
+
+static void test_attest_v1(uint64_t page)
+{
+	struct uv_cb_attest uvcb = {
+		.header.cmd = UVC_CMD_ATTESTATION,
+		.header.len = sizeof(uvcb),
+	};
+	const struct uv_cb_qui *uvcb_qui = uv_get_query_data();
+	struct attest_request_v1 *attest_req = (void *)page;
+	struct uv_arcb_v1 *arcb = &attest_req->arcb;
+	int cc;
+
+	report_prefix_push("v1");
+	if (!test_bit_inv(0, &uvcb_qui->supp_att_hdr_ver)) {
+		report_skip("Attestation version 1 not supported");
+		goto done;
+	}
+
+	memset((void *)page, 0, PAGE_SIZE);
+
+	/*
+	 * Create a minimal arcb/uvcb such that FW has everything to start
+	 * unsealing the request. However, this unsealing will fail as the
+	 * kvm-unit-test framework provides no cryptography functions that
+	 * would be needed to seal such requests.
+	 */
+	arcb->req_ver = ARCB_VERSION_1;
+	arcb->req_len = sizeof(*arcb);
+	arcb->nks = 1;
+	arcb->sea = sizeof(arcb->meas_key);
+	arcb->plaint_att_flags = PAF_PHKH_ATT;
+	arcb->meas_alg_id = ARCB_MEAS_HMAC_SHA512;
+	uvcb.arcb_addr = (uint64_t)&attest_req->arcb;
+	uvcb.measurement_address = (uint64_t)attest_req->measurement;
+	uvcb.measurement_length = sizeof(attest_req->measurement);
+	uvcb.add_data_address = (uint64_t)attest_req->additional;
+	uvcb.add_data_length = sizeof(attest_req->additional);
+
+	uvcb.continuation_token = 0xff;
+	cc = uv_call(0, (uint64_t)&uvcb);
+	report(cc == 1 && uvcb.header.rc == 0x0101, "invalid continuation token");
+	uvcb.continuation_token = 0;
+
+	uvcb.user_data_length = sizeof(uvcb.user_data) + 1;
+	cc = uv_call(0, (uint64_t)&uvcb);
+	report(cc == 1 && uvcb.header.rc == 0x0102, "invalid user data size");
+	uvcb.user_data_length = 0;
+
+	uvcb.arcb_addr = get_ram_size() + PAGE_SIZE;
+	cc = uv_call(0, (uint64_t)&uvcb);
+	report(cc == 1 && uvcb.header.rc == 0x0103, "invalid address arcb");
+	uvcb.arcb_addr = page;
+
+	/* 0104 - 0105 need an unseal-able request */
+
+	arcb->req_ver = ARCB_VERSION_NONE;
+	cc = uv_call(0, (uint64_t)&uvcb);
+	report(cc == 1 && uvcb.header.rc == 0x0106, "unsupported version");
+	arcb->req_ver = ARCB_VERSION_1;
+
+	arcb->req_len += 1;
+	cc = uv_call(0, (uint64_t)&uvcb);
+	report(cc == 1 && uvcb.header.rc == 0x0107, "arcb too big");
+	arcb->req_len -= 1;
+
+	/*
+	 * The arcb needs to grow as well if number of key slots (nks)
+	 * is increased. However, this is not the case and there is no explicit
+	 * 'too many/less nks for that arcb size' error code -> expect 0x0107
+	 */
+	arcb->nks = 2;
+	cc = uv_call(0, (uint64_t)&uvcb);
+	report(cc == 1 && uvcb.header.rc == 0x0107, "too many nks for arcb");
+	arcb->nks = 1;
+
+	arcb->nks = 0;
+	cc = uv_call(0, (uint64_t)&uvcb);
+	report(cc == 1 && uvcb.header.rc == 0x0108, "invalid num key slots");
+	arcb->nks = 1;
+
+	/*
+	 * Possible valid size (when using nonce).
+	 * However, req_len too small to host a nonce
+	 */
+	arcb->sea = 80;
+	cc = uv_call(0, (uint64_t)&uvcb);
+	report(cc == 1 && uvcb.header.rc == 0x0109, "encrypted size too big");
+	arcb->sea = 17;
+	cc = uv_call(0, (uint64_t)&uvcb);
+	report(cc == 1 && uvcb.header.rc == 0x0109, "encrypted size too small");
+	arcb->sea = 64;
+
+	arcb->plaint_att_flags = uvcb_qui->supp_paf ^ GENMASK_ULL(63, 0);
+	cc = uv_call(0, (uint64_t)&uvcb);
+	report(cc == 1 && uvcb.header.rc == 0x010a, "invalid flag");
+	arcb->plaint_att_flags = PAF_PHKH_ATT;
+
+	arcb->meas_alg_id = ARCB_MEAS_NONE;
+	cc = uv_call(0, (uint64_t)&uvcb);
+	report(cc == 1 && uvcb.header.rc == 0x010b, "invalid measurement algorithm");
+	arcb->meas_alg_id = ARCB_MEAS_HMAC_SHA512;
+
+	cc = uv_call(0, (uint64_t)&uvcb);
+	report(cc == 1 && uvcb.header.rc == 0x010c, "unable unseal");
+
+	uvcb.measurement_length = 0;
+	cc = uv_call(0, (uint64_t)&uvcb);
+	report(cc == 1 && uvcb.header.rc == 0x010d, "invalid measurement size");
+	uvcb.measurement_length = sizeof(attest_req->measurement);
+
+	uvcb.add_data_length = 0;
+	cc = uv_call(0, (uint64_t)&uvcb);
+	report(cc == 1 && uvcb.header.rc == 0x010e, "invalid additional size");
+	uvcb.add_data_length = sizeof(attest_req->additional);
+
+done:
+	report_prefix_pop();
+}
+
+static void test_attest(uint64_t page)
+{
+	struct uv_cb_attest uvcb = {
+		.header.cmd = UVC_CMD_ATTESTATION,
+		.header.len = sizeof(uvcb),
+	};
+	const struct uv_cb_qui *uvcb_qui = uv_get_query_data();
+	int cc;
+
+	/* Verify that the UV supports at least one header version */
+	report(uvcb_qui->supp_att_hdr_ver, "has hdr support");
+
+	memset((void *)page, 0, PAGE_SIZE);
+
+	uvcb.header.len -= 1;
+	cc = uv_call(0, (uint64_t)&uvcb);
+	report(cc && uvcb.header.rc == UVC_RC_INV_LEN, "uvcb too small");
+	uvcb.header.len += 1;
+
+	uvcb.header.len += 1;
+	cc = uv_call(0, (uint64_t)&uvcb);
+	report(cc && uvcb.header.rc == UVC_RC_INV_LEN, "uvcb too large");
+	uvcb.header.len -= 1;
+}
+
+int main(void)
+{
+	bool has_uvc = test_facility(158);
+	uint64_t page;
+
+
+	report_prefix_push("attestation");
+	if (!has_uvc) {
+		report_skip("Ultravisor call facility is not available");
+		goto done;
+	}
+
+	if (!uv_os_is_guest()) {
+		report_skip("Not a protected guest");
+		goto done;
+	}
+
+	if (!uv_query_test_call(BIT_UVC_CMD_ATTESTATION)) {
+		report_skip("Attestation not supported.");
+		goto done;
+	}
+
+	page = (uint64_t)alloc_page();
+	/* The privilege check is done in uv-guest.c */
+	test_attest(page);
+	test_attest_v1(page);
+	free_page((void *)page);
+done:
+	report_prefix_pop();
+	return report_summary();
+}
diff --git a/s390x/uv-guest.c b/s390x/uv-guest.c
index 77057bd2..c3a90614 100644
--- a/s390x/uv-guest.c
+++ b/s390x/uv-guest.c
@@ -2,7 +2,7 @@
 /*
  * Guest Ultravisor Call tests
  *
- * Copyright (c) 2020 IBM Corp
+ * Copyright IBM Corp. 2020, 2022
  *
  * Authors:
  *  Janosch Frank <frankja@linux.ibm.com>
@@ -53,6 +53,15 @@ static void test_priv(void)
 	check_pgm_int_code(PGM_INT_CODE_PRIVILEGED_OPERATION);
 	report_prefix_pop();
 
+	report_prefix_push("attest");
+	uvcb.cmd = UVC_CMD_ATTESTATION;
+	uvcb.len = sizeof(struct uv_cb_attest);
+	expect_pgm_int();
+	enter_pstate();
+	uv_call_once(0, (uint64_t)&uvcb);
+	check_pgm_int_code(PGM_INT_CODE_PRIVILEGED_OPERATION);
+	report_prefix_pop();
+
 	report_prefix_pop();
 }
 
@@ -111,8 +120,6 @@ static void test_sharing(void)
 	cc = uv_call(0, (u64)&uvcb);
 	report(cc == 0 && uvcb.header.rc == UVC_RC_EXECUTED, "unshare");
 	report_prefix_pop();
-
-	report_prefix_pop();
 }
 
 static struct {
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [kvm-unit-tests PATCH v4 2/5] s390x: lib: Add QUI getter
  2022-04-21  9:45 ` [kvm-unit-tests PATCH v4 2/5] s390x: lib: Add QUI getter Steffen Eiden
@ 2022-04-21 11:26   ` Janosch Frank
  0 siblings, 0 replies; 10+ messages in thread
From: Janosch Frank @ 2022-04-21 11:26 UTC (permalink / raw)
  To: Steffen Eiden, Thomas Huth, Claudio Imbrenda, David Hildenbrand
  Cc: kvm, linux-s390

On 4/21/22 11:45, Steffen Eiden wrote:
> Some tests need the information provided by the QUI UVC and lib/s390x/uv.c
> already has cached the qui result. Let's add a function to avoid
> unnecessary QUI UVCs.
> 
> Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>

If you fix the issue below:
Reviewed-by: Janosch Frank <frankja@linux.ibm.com>

> ---
>   lib/s390x/uv.c | 8 ++++++++
>   lib/s390x/uv.h | 1 +
>   2 files changed, 9 insertions(+)
> 
> diff --git a/lib/s390x/uv.c b/lib/s390x/uv.c
> index 6fe11dff..602cbbfc 100644
> --- a/lib/s390x/uv.c
> +++ b/lib/s390x/uv.c
> @@ -47,6 +47,14 @@ bool uv_query_test_call(unsigned int nr)
>   	return test_bit_inv(nr, uvcb_qui.inst_calls_list);
>   }
>   
> +const struct uv_cb_qui *uv_get_query_data(void)
> +{
> +	/* Query needs to be called first */
> +	assert(uvcb_qui.header.rc);


uvcb_qui.header.rc == 1 || uvcb_qui.header.rc == 0x100

> +
> +	return &uvcb_qui;
> +}
> +
>   int uv_setup(void)
>   {
>   	if (!test_facility(158))
> diff --git a/lib/s390x/uv.h b/lib/s390x/uv.h
> index 8175d9c6..44264861 100644
> --- a/lib/s390x/uv.h
> +++ b/lib/s390x/uv.h
> @@ -8,6 +8,7 @@
>   bool uv_os_is_guest(void);
>   bool uv_os_is_host(void);
>   bool uv_query_test_call(unsigned int nr);
> +const struct uv_cb_qui *uv_get_query_data(void);
>   void uv_init(void);
>   int uv_setup(void);
>   void uv_create_guest(struct vm *vm);


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [kvm-unit-tests PATCH v4 4/5] s390x: uv-guest: add share bit test
  2022-04-21  9:45 ` [kvm-unit-tests PATCH v4 4/5] s390x: uv-guest: add share bit test Steffen Eiden
@ 2022-04-21 11:33   ` Janosch Frank
  0 siblings, 0 replies; 10+ messages in thread
From: Janosch Frank @ 2022-04-21 11:33 UTC (permalink / raw)
  To: Steffen Eiden, Thomas Huth, Claudio Imbrenda, David Hildenbrand
  Cc: kvm, linux-s390

On 4/21/22 11:45, Steffen Eiden wrote:
> The UV facility bits shared/unshared must both be set or none.
> 
> Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
> ---
>   s390x/uv-guest.c | 14 ++++++++++++++
>   1 file changed, 14 insertions(+)
> 
> diff --git a/s390x/uv-guest.c b/s390x/uv-guest.c
> index 728c60aa..77057bd2 100644
> --- a/s390x/uv-guest.c
> +++ b/s390x/uv-guest.c
> @@ -159,6 +159,14 @@ static void test_invalid(void)
>   	report_prefix_pop();
>   }
>   
> +static void test_share_bits(void)
> +{
> +	bool unshare = uv_query_test_call(BIT_UVC_CMD_REMOVE_SHARED_ACCESS);
> +	bool share = uv_query_test_call(BIT_UVC_CMD_SET_SHARED_ACCESS);
> +

report_prefix_push("query");

> +	report(!(share ^ unshare), "share bits");

"share bits are identical" ?

report_prefix_pop();

> +}
> +
>   int main(void)
>   {
>   	bool has_uvc = test_facility(158);
> @@ -169,6 +177,12 @@ int main(void)
>   		goto done;
>   	}
>   
> +	/*
> +	 * Needs to be done before the guest-fence,
> +	 * as the fence tests if both shared bits are present
> +	 */
> +	test_share_bits();
> +
>   	if (!uv_os_is_guest()) {
>   		report_skip("Not a protected guest");
>   		goto done;


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [kvm-unit-tests PATCH v4 5/5] s390x: uv-guest: Add attestation tests
  2022-04-21  9:45 ` [kvm-unit-tests PATCH v4 5/5] s390x: uv-guest: Add attestation tests Steffen Eiden
@ 2022-04-26  9:22   ` Janosch Frank
  2022-04-26  9:39     ` Steffen Eiden
  0 siblings, 1 reply; 10+ messages in thread
From: Janosch Frank @ 2022-04-26  9:22 UTC (permalink / raw)
  To: Steffen Eiden, Thomas Huth, Claudio Imbrenda, David Hildenbrand
  Cc: kvm, linux-s390

On 4/21/22 11:45, Steffen Eiden wrote:
> Adds several tests to verify correct error paths of attestation.
> 
> Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
> ---
>   lib/s390x/asm/uv.h |   5 +-
>   s390x/Makefile     |   1 +
>   s390x/pv-attest.c  | 225 +++++++++++++++++++++++++++++++++++++++++++++
>   s390x/uv-guest.c   |  13 ++-
>   4 files changed, 240 insertions(+), 4 deletions(-)
>   create mode 100644 s390x/pv-attest.c
> 
> diff --git a/lib/s390x/asm/uv.h b/lib/s390x/asm/uv.h
> index 7c8c399d..38920461 100644
> --- a/lib/s390x/asm/uv.h
> +++ b/lib/s390x/asm/uv.h
> @@ -108,7 +108,10 @@ struct uv_cb_qui {
>   	u8  reserved88[158 - 136];	/* 0x0088 */
>   	uint16_t max_guest_cpus;	/* 0x009e */
>   	u64 uv_feature_indications;	/* 0x00a0 */
> -	u8  reserveda8[200 - 168];	/* 0x00a8 */
> +	uint8_t  reserveda8[224 - 168];	/* 0x00a8 */
> +	uint64_t supp_att_hdr_ver;	/* 0x00e0 */
> +	uint64_t supp_paf;		/* 0x00e8 */
> +	uint8_t  reservedf0[256 - 240];	/* 0x00f0 */
>   }  __attribute__((packed))  __attribute__((aligned(8)));
>   
>   struct uv_cb_cgc {
> diff --git a/s390x/Makefile b/s390x/Makefile
> index 8ff84db5..5a49d1e7 100644
> --- a/s390x/Makefile
> +++ b/s390x/Makefile
> @@ -29,6 +29,7 @@ tests += $(TEST_DIR)/mvpg-sie.elf
>   tests += $(TEST_DIR)/spec_ex-sie.elf
>   tests += $(TEST_DIR)/firq.elf
>   tests += $(TEST_DIR)/epsw.elf
> +tests += $(TEST_DIR)/pv-attest.elf
>   
>   pv-tests += $(TEST_DIR)/pv-diags.elf
>   
> diff --git a/s390x/pv-attest.c b/s390x/pv-attest.c
> new file mode 100644
> index 00000000..e31780a3
> --- /dev/null
> +++ b/s390x/pv-attest.c
> @@ -0,0 +1,225 @@
[...]
> +
> +static void test_attest_v1(uint64_t page)
> +{
> +	struct uv_cb_attest uvcb = {
> +		.header.cmd = UVC_CMD_ATTESTATION,
> +		.header.len = sizeof(uvcb),
> +	};
> +	const struct uv_cb_qui *uvcb_qui = uv_get_query_data();
> +	struct attest_request_v1 *attest_req = (void *)page;
> +	struct uv_arcb_v1 *arcb = &attest_req->arcb;
> +	int cc;
> +
> +	report_prefix_push("v1");
> +	if (!test_bit_inv(0, &uvcb_qui->supp_att_hdr_ver)) {
> +		report_skip("Attestation version 1 not supported");
> +		goto done;
> +	}
> +
> +	memset((void *)page, 0, PAGE_SIZE);
> +
> +	/*
> +	 * Create a minimal arcb/uvcb such that FW has everything to start
> +	 * unsealing the request. However, this unsealing will fail as the
> +	 * kvm-unit-test framework provides no cryptography functions that
> +	 * would be needed to seal such requests.
> +	 */
> +	arcb->req_ver = ARCB_VERSION_1;
> +	arcb->req_len = sizeof(*arcb);
> +	arcb->nks = 1;
> +	arcb->sea = sizeof(arcb->meas_key);
> +	arcb->plaint_att_flags = PAF_PHKH_ATT;
> +	arcb->meas_alg_id = ARCB_MEAS_HMAC_SHA512;
> +	uvcb.arcb_addr = (uint64_t)&attest_req->arcb;
> +	uvcb.measurement_address = (uint64_t)attest_req->measurement;
> +	uvcb.measurement_length = sizeof(attest_req->measurement);
> +	uvcb.add_data_address = (uint64_t)attest_req->additional;
> +	uvcb.add_data_length = sizeof(attest_req->additional);
> +
> +	uvcb.continuation_token = 0xff;
> +	cc = uv_call(0, (uint64_t)&uvcb);
> +	report(cc == 1 && uvcb.header.rc == 0x0101, "invalid continuation token");

Please don't add the 0 to the front of the rc values.

[...]

> @@ -111,8 +120,6 @@ static void test_sharing(void)
>   	cc = uv_call(0, (u64)&uvcb);
>   	report(cc == 0 && uvcb.header.rc == UVC_RC_EXECUTED, "unshare");
>   	report_prefix_pop();
> -
> -	report_prefix_pop();

That's unrelated, no?

>   }
>   
>   static struct {


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [kvm-unit-tests PATCH v4 5/5] s390x: uv-guest: Add attestation tests
  2022-04-26  9:22   ` Janosch Frank
@ 2022-04-26  9:39     ` Steffen Eiden
  0 siblings, 0 replies; 10+ messages in thread
From: Steffen Eiden @ 2022-04-26  9:39 UTC (permalink / raw)
  To: Janosch Frank, Thomas Huth, Claudio Imbrenda, David Hildenbrand
  Cc: kvm, linux-s390


Hi Janosch,

thanks for your review.

On 4/26/22 11:22, Janosch Frank wrote:
> On 4/21/22 11:45, Steffen Eiden wrote:
>> Adds several tests to verify correct error paths of attestation.
>>
>> Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
>> ---
>>   lib/s390x/asm/uv.h |   5 +-
>>   s390x/Makefile     |   1 +
>>   s390x/pv-attest.c  | 225 +++++++++++++++++++++++++++++++++++++++++++++
>>   s390x/uv-guest.c   |  13 ++-
>>   4 files changed, 240 insertions(+), 4 deletions(-)
>>   create mode 100644 s390x/pv-attest.c
>>
>> diff --git a/lib/s390x/asm/uv.h b/lib/s390x/asm/uv.h
>> index 7c8c399d..38920461 100644
>> --- a/lib/s390x/asm/uv.h
>> +++ b/lib/s390x/asm/uv.h
>> @@ -108,7 +108,10 @@ struct uv_cb_qui {
>>       u8  reserved88[158 - 136];    /* 0x0088 */
>>       uint16_t max_guest_cpus;    /* 0x009e */
>>       u64 uv_feature_indications;    /* 0x00a0 */
>> -    u8  reserveda8[200 - 168];    /* 0x00a8 */
>> +    uint8_t  reserveda8[224 - 168];    /* 0x00a8 */
>> +    uint64_t supp_att_hdr_ver;    /* 0x00e0 */
>> +    uint64_t supp_paf;        /* 0x00e8 */
>> +    uint8_t  reservedf0[256 - 240];    /* 0x00f0 */
>>   }  __attribute__((packed))  __attribute__((aligned(8)));
>>   struct uv_cb_cgc {
>> diff --git a/s390x/Makefile b/s390x/Makefile
>> index 8ff84db5..5a49d1e7 100644
>> --- a/s390x/Makefile
>> +++ b/s390x/Makefile
>> @@ -29,6 +29,7 @@ tests += $(TEST_DIR)/mvpg-sie.elf
>>   tests += $(TEST_DIR)/spec_ex-sie.elf
>>   tests += $(TEST_DIR)/firq.elf
>>   tests += $(TEST_DIR)/epsw.elf
>> +tests += $(TEST_DIR)/pv-attest.elf
>>   pv-tests += $(TEST_DIR)/pv-diags.elf
>> diff --git a/s390x/pv-attest.c b/s390x/pv-attest.c
>> new file mode 100644
>> index 00000000..e31780a3
>> --- /dev/null
>> +++ b/s390x/pv-attest.c
>> @@ -0,0 +1,225 @@
> [...]
>> +
>> +static void test_attest_v1(uint64_t page)
>> +{
>> +    struct uv_cb_attest uvcb = {
>> +        .header.cmd = UVC_CMD_ATTESTATION,
>> +        .header.len = sizeof(uvcb),
>> +    };
>> +    const struct uv_cb_qui *uvcb_qui = uv_get_query_data();
>> +    struct attest_request_v1 *attest_req = (void *)page;
>> +    struct uv_arcb_v1 *arcb = &attest_req->arcb;
>> +    int cc;
>> +
>> +    report_prefix_push("v1");
>> +    if (!test_bit_inv(0, &uvcb_qui->supp_att_hdr_ver)) {
>> +        report_skip("Attestation version 1 not supported");
>> +        goto done;
>> +    }
>> +
>> +    memset((void *)page, 0, PAGE_SIZE);
>> +
>> +    /*
>> +     * Create a minimal arcb/uvcb such that FW has everything to start
>> +     * unsealing the request. However, this unsealing will fail as the
>> +     * kvm-unit-test framework provides no cryptography functions that
>> +     * would be needed to seal such requests.
>> +     */
>> +    arcb->req_ver = ARCB_VERSION_1;
>> +    arcb->req_len = sizeof(*arcb);
>> +    arcb->nks = 1;
>> +    arcb->sea = sizeof(arcb->meas_key);
>> +    arcb->plaint_att_flags = PAF_PHKH_ATT;
>> +    arcb->meas_alg_id = ARCB_MEAS_HMAC_SHA512;
>> +    uvcb.arcb_addr = (uint64_t)&attest_req->arcb;
>> +    uvcb.measurement_address = (uint64_t)attest_req->measurement;
>> +    uvcb.measurement_length = sizeof(attest_req->measurement);
>> +    uvcb.add_data_address = (uint64_t)attest_req->additional;
>> +    uvcb.add_data_length = sizeof(attest_req->additional);
>> +
>> +    uvcb.continuation_token = 0xff;
>> +    cc = uv_call(0, (uint64_t)&uvcb);
>> +    report(cc == 1 && uvcb.header.rc == 0x0101, "invalid continuation 
>> token");
> 
> Please don't add the 0 to the front of the rc values.
OK
> 
> [...]
> 
>> @@ -111,8 +120,6 @@ static void test_sharing(void)
>>       cc = uv_call(0, (u64)&uvcb);
>>       report(cc == 0 && uvcb.header.rc == UVC_RC_EXECUTED, "unshare");
>>       report_prefix_pop();
>> -
>> -    report_prefix_pop();
> 
> That's unrelated, no?
Right, it is now unrelated. I forgot to remove that change for v4.
  In the previous version this double pop would mess with the output as
`test_sharing` was not the last test in that file
(attestation test followed).
I'll add another fix patch for this.

> 
>>   }
>>   static struct {
> 

Steffen

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2022-04-26 10:13 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-04-21  9:45 [kvm-unit-tests PATCH v4 0/5] s390x: Attestation tests Steffen Eiden
2022-04-21  9:45 ` [kvm-unit-tests PATCH v4 1/5] s390x: uv-host: Add invalid command attestation check Steffen Eiden
2022-04-21  9:45 ` [kvm-unit-tests PATCH v4 2/5] s390x: lib: Add QUI getter Steffen Eiden
2022-04-21 11:26   ` Janosch Frank
2022-04-21  9:45 ` [kvm-unit-tests PATCH v4 3/5] s390x: uv-guest: remove duplicated checks Steffen Eiden
2022-04-21  9:45 ` [kvm-unit-tests PATCH v4 4/5] s390x: uv-guest: add share bit test Steffen Eiden
2022-04-21 11:33   ` Janosch Frank
2022-04-21  9:45 ` [kvm-unit-tests PATCH v4 5/5] s390x: uv-guest: Add attestation tests Steffen Eiden
2022-04-26  9:22   ` Janosch Frank
2022-04-26  9:39     ` Steffen Eiden

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.