From: Joey Gouly <joey.gouly@arm.com>
To: Andrew Jones <andrew.jones@linux.dev>, <kvmarm@lists.linux.dev>,
<kvm@vger.kernel.org>
Cc: <joey.gouly@arm.com>, Alexandru Elisei <alexandru.elisei@arm.com>,
Christoffer Dall <christoffer.dall@arm.com>,
Fuad Tabba <tabba@google.com>,
Jean-Philippe Brucker <jean-philippe@linaro.org>,
Joey Gouly <Joey.Gouly@arm.com>, Marc Zyngier <maz@kernel.org>,
Mark Rutland <mark.rutland@arm.com>,
Oliver Upton <oliver.upton@linux.dev>,
Paolo Bonzini <pbonzini@redhat.com>,
Quentin Perret <qperret@google.com>,
Steven Price <steven.price@arm.com>,
Suzuki K Poulose <suzuki.poulose@arm.com>,
"Thomas Huth" <thuth@redhat.com>, Will Deacon <will@kernel.org>,
Zenghui Yu <yuzenghui@huawei.com>, <linux-coco@lists.linux.dev>,
<kvmarm@lists.cs.columbia.edu>,
<linux-arm-kernel@lists.infradead.org>,
<linux-kernel@vger.kernel.org>,
Mate Toth-Pal <mate.toth-pal@arm.com>
Subject: [RFC kvm-unit-tests 25/27] arm: realm: Add Realm attestation tests
Date: Fri, 27 Jan 2023 11:41:06 +0000 [thread overview]
Message-ID: <20230127114108.10025-26-joey.gouly@arm.com> (raw)
In-Reply-To: <20230127114108.10025-1-joey.gouly@arm.com>
From: Mate Toth-Pal <mate.toth-pal@arm.com>
Add tests for Attestation and measurement related RSI calls.
Signed-off-by: Mate Toth-Pal <mate.toth-pal@arm.com>
Co-developed-by: Suzuki K Poulose <suzuki.poulose@arm.com>
[ Rewrote the test cases, keeping the core testing data/logic ]
Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
Signed-off-by: Joey Gouly <joey.gouly@arm.com>
---
arm/Makefile.arm64 | 1 +
arm/realm-attest.c | 1125 ++++++++++++++++++++++++++++++++++++++++++++
arm/unittests.cfg | 50 ++
lib/libcflat.h | 1 +
4 files changed, 1177 insertions(+)
create mode 100644 arm/realm-attest.c
diff --git a/arm/Makefile.arm64 b/arm/Makefile.arm64
index f57d0a95..0a0c4f2c 100644
--- a/arm/Makefile.arm64
+++ b/arm/Makefile.arm64
@@ -41,6 +41,7 @@ tests += $(TEST_DIR)/micro-bench.flat
tests += $(TEST_DIR)/cache.flat
tests += $(TEST_DIR)/debug.flat
tests += $(TEST_DIR)/realm-rsi.flat
+tests += $(TEST_DIR)/realm-attest.flat
tests += $(TEST_DIR)/realm-fpu.flat
tests += $(TEST_DIR)/realm-sea.flat
diff --git a/arm/realm-attest.c b/arm/realm-attest.c
new file mode 100644
index 00000000..6c357fb5
--- /dev/null
+++ b/arm/realm-attest.c
@@ -0,0 +1,1125 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2022 Arm Limited.
+ * All rights reserved.
+ */
+#include <libcflat.h>
+
+#include <attest_defines.h>
+#include <alloc.h>
+#include <stdlib.h>
+#include <token_dumper.h>
+#include <token_verifier.h>
+
+#include <asm/io.h>
+#include <asm/page.h>
+#include <asm/rsi.h>
+#include <asm/setup.h>
+#include <asm/smp.h>
+
+
+#define SHA256_SIZE 32
+
+struct challenge {
+ unsigned long words[8];
+};
+
+struct measurement {
+ unsigned long words[8];
+};
+
+static char __attribute__((aligned(SZ_2M))) __attribute__((section(".data")))
+ block_buf_data[SZ_2M * 2];
+
+static char __attribute__((aligned(SZ_2M))) __attribute__((section(".bss")))
+ block_buf_bss[SZ_2M];
+
+static char __attribute__((aligned(SZ_4K))) __attribute__((section(".data")))
+ page_buf_data[SZ_4K];
+
+static char __attribute__((aligned(SZ_4K))) __attribute__((section(".bss")))
+ page_buf_bss[SZ_4K];
+
+/* Page aligned offset within the block mapped buffer */
+#define BLOCK_BUF_OFFSET (SZ_8K)
+
+static inline void debug_print_raw_token(void *buf, size_t size)
+{
+#ifdef PRINT_RAW_TOKEN
+ print_raw_token(buf, size);
+#endif
+}
+
+static inline void debug_print_token(struct attestation_claims *claim)
+{
+#ifdef PRINT_TOKEN
+ print_token(claim);
+#endif
+}
+
+static bool claims_verify_token(char *token, size_t token_size,
+ struct attestation_claims *claims,
+ bool report_success)
+{
+ int verify_rc = verify_token(token, token_size, claims);
+ int cpu = smp_processor_id();
+
+ if (verify_rc == TOKEN_VERIFICATION_ERR_SUCCESS) {
+ if (report_success)
+ report(true, "CPU%d: Verfication of token passed", cpu);
+ return true;
+ }
+
+ report(false,
+ "CPU%d: Verification of token failed with error code %d",
+ cpu, verify_rc);
+
+ return false;
+}
+
+static inline void attest_token_init(phys_addr_t addr,
+ struct challenge *ch,
+ struct smccc_result *res)
+{
+ rsi_attest_token_init(addr, &ch->words[0], res);
+}
+
+
+static inline void attest_token_continue(phys_addr_t addr,
+ struct smccc_result *res)
+{
+ rsi_attest_token_continue(addr, res);
+}
+
+static inline void attest_token_complete(phys_addr_t addr,
+ struct smccc_result *res)
+{
+ do {
+ attest_token_continue(addr, res);
+ } while (res->r0 == RSI_INCOMPLETE);
+}
+
+static void get_attest_token(phys_addr_t ipa,
+ struct challenge *ch,
+ struct smccc_result *res)
+{
+ attest_token_init(ipa, ch, res);
+
+ if (res->r0)
+ return;
+ attest_token_complete(ipa, res);
+}
+
+/*
+ * __get_attest_token_claims: Get attestation token and verify the claims.
+ * If @claims is not NULL, token is parsed and the @claims is populated.
+ * All failures reported. Success is only reported if the @report_success is
+ * true.
+ * Returns whether the calls and verification succeeds
+ */
+static bool __get_attest_token_claims(void *buf, struct challenge *ch,
+ struct attestation_claims *claims,
+ size_t *token_size, bool report_success)
+{
+ struct smccc_result result;
+ struct attestation_claims local_claims;
+ struct attestation_claims *claimsp;
+ bool rc = false;
+
+ /* Use the local_claims if claims is not supplied */
+ claimsp = claims ? : &local_claims;
+
+ get_attest_token(virt_to_phys(buf), ch, &result);
+ if (result.r0) {
+ report(false, "Get attestation token with : %ld", result.r0);
+ return rc;
+ }
+
+ if (report_success)
+ report(true, "Get attestation token");
+
+ /* Update token_size if necessary */
+ if (token_size)
+ *token_size = result.r1;
+
+ return claims_verify_token(buf, result.r1, claimsp, report_success);
+}
+
+static bool get_attest_token_claims(void *buf, struct challenge *ch,
+ struct attestation_claims *claims,
+ size_t *token_size)
+{
+ return __get_attest_token_claims(buf, ch, claims, token_size, false);
+}
+
+static void get_verify_attest_token(void *buf, struct challenge *ch,
+ const char *desc)
+{
+ report_prefix_push(desc);
+ __get_attest_token_claims(buf, ch, NULL, NULL, true);
+ report_prefix_pop();
+}
+
+static void get_verify_attest_token_verbose(void *buf,
+ struct challenge *ch,
+ const char *desc)
+{
+ size_t token_size;
+ struct attestation_claims claims;
+
+ report_prefix_push(desc);
+ if (__get_attest_token_claims(buf, ch, &claims, &token_size, true)) {
+ debug_print_raw_token(buf, token_size);
+ debug_print_token(&claims);
+ }
+ report_prefix_pop();
+}
+
+static void test_get_attest_token(void)
+{
+ char stack_buf[SZ_4K]__attribute__((aligned(SZ_4K)));
+ char *heap_buf;
+ struct challenge ch;
+
+ memset(&ch, 0xAB, sizeof(ch));
+
+ /* Heap buffer */
+ heap_buf = memalign(SZ_4K, SZ_4K);
+ if (heap_buf) {
+ get_verify_attest_token(heap_buf, &ch, "heap buffer");
+ free(heap_buf);
+ } else {
+ report_skip("heap buffer: Failed to allocate");
+ }
+
+ /* Stack buffer */
+ get_verify_attest_token(stack_buf, &ch, "stack buffer");
+ /* Page aligned buffer .data segment */
+ get_verify_attest_token(page_buf_data, &ch, ".data segment buffer");
+ /* Page aligned buffer .bss segment */
+ get_verify_attest_token(page_buf_bss, &ch, ".bss segment buffer");
+ /* Block mapped buffer in .data segment */
+ get_verify_attest_token(&block_buf_data[BLOCK_BUF_OFFSET], &ch,
+ "block mapped .data segment buffer");
+ /* Block mapped buffer in .bss segment */
+ get_verify_attest_token_verbose(&block_buf_bss[BLOCK_BUF_OFFSET],
+ &ch, "block mapped .bss segment buffer");
+}
+
+static void get_attest_token_check_fail(phys_addr_t ipa,
+ struct challenge *ch,
+ return_code_t exp,
+ const char *buf_desc)
+{
+ struct smccc_result result;
+ return_code_t rc;
+
+ report_prefix_push(buf_desc);
+ get_attest_token(ipa, ch, &result);
+ rc = unpack_return_code(result.r0);
+ if (rc.status != exp.status) {
+ report(false, "Get attestation token "
+ "got (%d) expected (%d)",
+ rc.status, exp.status);
+ } else {
+ report(true, "Get attestation token fails as expected");
+ }
+ report_prefix_pop();
+}
+
+static void test_get_attest_token_bad_input(void)
+{
+ struct challenge ch;
+ return_code_t exp;
+
+ memset(page_buf_data, 0, sizeof(page_buf_data));
+ memset(&ch, 0xAB, sizeof(ch));
+ exp = make_return_code(RSI_ERROR_INPUT, 0);
+ get_attest_token_check_fail(virt_to_phys(page_buf_data + 0x100),
+ &ch, exp, "unaligned buffer");
+ get_attest_token_check_fail(__phys_end + SZ_512M, &ch, exp,
+ "buffer outside PAR");
+}
+
+static void test_get_attest_token_abi_misuse(void)
+{
+ struct smccc_result result;
+ struct challenge ch;
+ phys_addr_t ipa = virt_to_phys(page_buf_data);
+ return_code_t rc;
+
+ memset(&ch, 0xAB, sizeof(ch));
+
+ /*
+ * Testcase 1 - Miss call to RSI_ATTEST_TOKEN_INIT
+ *
+ * step1. Execute a successful test to reset the state machine.
+ */
+ report_prefix_push("miss token init");
+ get_attest_token(ipa, &ch, &result);
+ if (result.r0) {
+ report(false, "Get attestation failed %ld", result.r0);
+ report_prefix_pop(); /* miss token init */
+ return;
+ }
+ /*
+ * step2. Execute RSI_ATTEST_TOKEN_CONTINUE without an RSI_ATTEST_TOKEN_INIT.
+ * Expect an error == RSI_ERROR_STATE
+ */
+ attest_token_continue(ipa, &result);
+ rc = unpack_return_code(result.r0);
+ if (rc.status != RSI_ERROR_STATE) {
+ report(false, "Unexpected result (%d, %d) vs (%d) expected",
+ rc.status, rc.index, RSI_ERROR_STATE);
+ report_prefix_pop(); /* miss token init */
+ return;
+ }
+
+ report(true, "Fails as expected");
+ report_prefix_pop(); /* miss token init */
+
+ /*
+ * Test case 2 - Calling with inconsistend input.
+ * step1. Issue RSI_ATTEST_TOKEN_INIT
+ * step2. Modify the challenge and issue RSI_ATTEST_TOKEN_CONTINUE.
+ * Test : Expect error == (RSI_ERROR_INPUT, 0)
+ */
+ report_prefix_push("inconsistent input");
+ attest_token_init(ipa, &ch, &result);
+ rc = unpack_return_code(result.r0);
+ if (result.r0) {
+ report(false, "RSI_ATTEST_TOKEN_INIT failed unexpectedly (%d, %d)",
+ rc.status, rc.index);
+ report_prefix_pop(); /* inconsistent input */
+ return;
+ }
+
+ /*
+ * Corrupt the IPA address input to ATTEST_TOKEN_CONTINUE,
+ */
+ attest_token_continue(ipa ^ 0x1UL, &result);
+ rc = unpack_return_code(result.r0);
+ if (rc.status != RSI_ERROR_INPUT) {
+ report(false, "Attest token continue unexpected results"
+ " (%d) vs expected (%d)",
+ rc.status, RSI_ERROR_INPUT);
+ }
+
+ report_prefix_pop(); /* inconsistent input */
+
+ /*
+ * Test case 3
+ * step1. Complete the token attestation from with proper values.
+ * Failures in the Test case 2 should not affect the completion.
+ */
+ report_prefix_push("valid input after inconsistent input");
+ attest_token_complete(ipa, &result);
+ rc = unpack_return_code(result.r0);
+ if (result.r0) {
+ report(false, "Attest token continue failed with (%d, %d)",
+ rc.status, rc.index);
+ return;
+ } else {
+ report(true, "Attest token continue complete");
+ }
+ report_prefix_pop(); /* Valid input after inconsistent input */
+}
+
+static void test_get_attest_token_abi_abort_req(void)
+{
+ int i;
+ char *p;
+ size_t size;
+ struct attestation_claims claims;
+ struct smccc_result result;
+ struct challenge ch;
+ char stack_buf[SZ_4K] __attribute__((aligned(SZ_4K))) = { 0 };
+ phys_addr_t addr = virt_to_phys(stack_buf);
+
+ /* Set the initial challenge, which will be aborted */
+ memset(&ch, 0xAB, sizeof(ch));
+ attest_token_init(addr, &ch, &result);
+ if (result.r0) {
+ report(false, "Attest token init failed %ld", result.r0);
+ return;
+ }
+
+ /* Execute a few cycles, but not let it complete */
+ for (i = 0; i < 3; i++) {
+ attest_token_continue(addr, &result);
+ if (result.r0 != RSI_INCOMPLETE) {
+ if (result.r0)
+ report(false, "Attest token continue : unexpected "
+ "failure %ld", result.r0);
+ else
+ report_skip("Attest token finished at iteration %d",
+ i + 1);
+ return;
+ }
+ }
+
+ /* Issue a fresh Attest Token request with updated challenge */
+ memset(&ch, 0xEE, sizeof(ch));
+ get_attest_token(addr, &ch, &result);
+ if (result.r0) {
+ report(false, "Attest Token failed %ld", result.r0);
+ return;
+ }
+ claims_verify_token(stack_buf, result.r1, &claims, false);
+
+ /*
+ * TODO: Index of claim in the array depends on the init sequence
+ * in token_verifier.c: init_claim()
+ */
+ p = (char*)claims.realm_token_claims[0].buffer_data.ptr;
+ size = claims.realm_token_claims[0].buffer_data.len;
+
+ /* Verify that token contains the updated challenge. */
+ if (size != sizeof(ch)) {
+ report(false, "Attestation token: abort request: "
+ "claim size mismatch : %ld", result.r0);
+ return;
+ }
+ if (memcmp(p, &ch, size)) {
+ report(false, "Attestation token: abort request: "
+ "claim value mismatch: %ld", result.r0);
+ return;
+ }
+ report(true, "Aborting ongoing request");
+}
+
+static void run_rsi_attest_tests(void)
+{
+ report_prefix_push("attest");
+
+ test_get_attest_token();
+
+ report_prefix_push("bad input");
+ test_get_attest_token_bad_input();
+ report_prefix_pop();
+
+ report_prefix_push("ABI misuse");
+ test_get_attest_token_abi_misuse();
+ report_prefix_pop();
+
+ report_prefix_push("ABI Abort");
+ test_get_attest_token_abi_abort_req();
+ report_prefix_pop();
+
+ report_prefix_pop(); /* attest */
+}
+
+static void run_get_token_times(void *data)
+{
+ char buf[SZ_4K] __attribute__((aligned(SZ_4K)));
+ struct challenge ch;
+ struct attestation_claims claims;
+ unsigned long runs = ((size_t)data);
+ int i, j;
+ int cpu = smp_processor_id();
+
+ report_info("CPU%d: Running get token test %ld times", cpu, runs);
+ for (i = 0; i < runs; i++) {
+ uint8_t pattern = (cpu << 4) | (i & 0xf);
+ size_t token_size;
+ struct claim_t *claim;
+
+ memset(buf, 0, sizeof(buf));
+ memset(&ch, pattern, sizeof(ch));
+
+ if (!get_attest_token_claims(buf, &ch, &claims, &token_size))
+ return;
+ claim = claims.realm_token_claims;
+ if (claim->key != CCA_REALM_CHALLENGE ||
+ claim->buffer_data.len != sizeof(ch)) {
+ report(false, "Invalid challenge size in parsed token:"
+ " %zu (expected %zu)",
+ claim->buffer_data.len, sizeof(ch));
+ return;
+ }
+
+ for (j = 0; j < sizeof(ch); j++) {
+ uint8_t byte = ((uint8_t *)claim->buffer_data.ptr)[j];
+ if (byte != pattern) {
+ report(false, "Invalid byte in challenge[%d]: "
+ " %02x (expected %02x)",
+ j, byte, pattern);
+ return;
+ }
+ }
+ }
+ report(true, "CPU%d: Completed runs", cpu);
+}
+
+static void run_rsi_attest_smp_test(void)
+{
+ unsigned long runs = 100;
+
+ report_prefix_push("attest_smp");
+ on_cpus(run_get_token_times, (void *)runs);
+ report_prefix_pop();
+}
+
+/*
+ * There are 7 slots for measurements. The first is reserved for initial
+ * content measurement. The rest are meant to store runtime measurements.
+ * Runtime measurements are extended (concatenated and hashed). Reading
+ * them back separately is unsupported. They can be queried in an
+ * attestation token.
+ *
+ * Measurement size is 64bytes maximum to accommodate a SHA512 hash.
+ */
+
+static void measurement_extend(int idx, struct measurement *m, size_t size,
+ struct smccc_result *res)
+{
+ rsi_extend_measurement(idx, size, &m->words[0], res);
+}
+
+static void test_extend_measurement(void)
+{
+ struct smccc_result result;
+ struct measurement m;
+ return_code_t rc;
+ int idx;
+
+ memset(&m, 0xEE, sizeof(m));
+ /*
+ * Store Runtime measurements for all possible slots.
+ */
+ for (idx = 1; idx <= REM_COUNT; idx ++) {
+ measurement_extend(idx, &m, sizeof(m.words), &result);
+ rc = unpack_return_code(result.r0);
+ report(!rc.status, "Extend measurement idx: %d (%d, %d)",
+ idx, rc.status, rc.index);
+ }
+}
+
+static void test_extend_measurement_bad_index(struct measurement *m)
+{
+ struct smccc_result result;
+ return_code_t rc;
+ int indices[] = { 0, REM_COUNT + 1 };
+ const char *idx_descs[] = { "reserved", "out-of-bounds" };
+ int i;
+
+ report_prefix_push("index");
+ for (i = 0; i < ARRAY_SIZE(indices); i++) {
+ report_prefix_push(idx_descs[i]);
+ measurement_extend(indices[i], m, sizeof(m->words), &result);
+ rc = unpack_return_code(result.r0);
+
+ if (rc.status != RSI_ERROR_INPUT)
+ report(false, "Extend measurement index: "
+ "actual (%d) vs expected (%d)",
+ rc.status, RSI_ERROR_INPUT);
+ else
+ report(true, "Extend measurement index fails as expected");
+ report_prefix_pop(); /* idx_descs[i] */
+ }
+ report_prefix_pop(); /* index */
+}
+
+static void test_extend_measurement_bad_size(struct measurement *m)
+{
+ struct smccc_result result;
+ return_code_t rc;
+
+ report_prefix_push("size");
+ rsi_extend_measurement(1, 65, &m->words[0], &result);
+ rc = unpack_return_code(result.r0);
+ if (rc.status != RSI_ERROR_INPUT)
+ report(false, "Measurement extend "
+ "actual (%d) vs expected (%d)",
+ rc.status, RSI_ERROR_INPUT);
+ else
+ report(true, "Extend measurement fails as expected");
+ report_prefix_pop(); /* size */
+}
+
+static void test_extend_measurement_bad_input(void)
+{
+ struct measurement m;
+
+ report_prefix_push("bad input");
+ memset(&m, 0xEE, sizeof(m));
+ test_extend_measurement_bad_index(&m);
+ test_extend_measurement_bad_size(&m);
+ report_prefix_pop(); /* bad input */
+}
+
+static void run_rsi_extend_tests(void)
+{
+ report_prefix_push("extend");
+ test_extend_measurement();
+ test_extend_measurement_bad_input();
+ report_prefix_pop(); /* extend */
+}
+
+/*
+ * cpu_extend_run - Parameters for the extend measurement SMP run.
+ * @idx - Pointer to the index
+ * @size - Size of the measurement data
+ * @m - Measurement data.
+ */
+struct cpu_extend_run {
+ int *idx;
+ struct measurement *m;
+ size_t size;
+ unsigned long rc;
+};
+
+/*
+ * We get an array of the parameters for the extend measurement.
+ * The cpu number is the index to the array. At the moment we
+ * only support 2 cpus.
+ */
+static void cpu_run_extend_measurement(void *data)
+{
+ struct smccc_result result;
+ struct cpu_extend_run *run;
+ int me = smp_processor_id();
+
+ assert(me >= 0);
+
+ /* Tests for only 2 CPUs */
+ if (me > 1)
+ return;
+ run = (struct cpu_extend_run *)data + me;
+ rsi_extend_measurement(*run->idx, run->size, &run->m->words[0], &result);
+ run->rc = result.r0;
+ if (result.r0 != 0)
+ report(false, "CPU%d: Extend measurement failed for slot %d",
+ me, *run->idx);
+}
+
+static bool claims_uses_sha256_algo(struct attestation_claims *claims)
+{
+ struct claim_t *claim = claims->realm_token_claims + 2; /* CCA_REALM_HASH_ALGO_ID */
+
+ /* claim->buffer_data.ptr: Not NULL terminated, so using memcmp */
+ return !memcmp(claim->buffer_data.ptr, "sha-256", strlen("sha-256"));
+}
+
+static void test_rsi_extend_smp(void)
+{
+ int slot, m_idx;
+ struct measurement m[2];
+ struct challenge ch;
+ struct attestation_claims claims;
+ size_t token_size;
+
+ /*
+ * Measurements to extend with
+ *
+ * Run CPU0 data CPU1 data
+ * 1: [31 - 0] [55 - 24]
+ * 2: [39 - 8] [63 - 32]
+ * 3: [47 - 16] [71 - 40]
+ */
+ char measure_bytes[] = {
+ 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
+ 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
+ 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
+ 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+ 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
+ 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27
+ };
+
+ /*
+ * The expected measurement values. Each element in the array contains
+ * a possible extended measurement value. (Multiple values are possible
+ * as the extend function might be called in any order by the cores.)
+ * The array contains results for all the possible orders. The number of
+ * possibilities can be calculated as here:
+ * https://math.stackexchange.com/q/1065374
+ */
+ struct extend_smp_expected {
+ const char *sequence;
+ char measurement[SHA256_SIZE];
+ } expected[] = {
+ {
+ "[ cpu0#0 cpu0#1 cpu0#2 cpu1#0 cpu1#1 cpu1#2 ]",
+ {
+ 0xB1, 0xBE, 0x04, 0x25, 0xBB, 0xBC, 0x04, 0x9F,
+ 0x98, 0x4F, 0xFB, 0xDE, 0xAA, 0x00, 0xC9, 0xBC,
+ 0x41, 0x43, 0xDB, 0x16, 0xBB, 0x2A, 0x5F, 0x4B,
+ 0x8B, 0x36, 0xAE, 0x3F, 0xFE, 0x24, 0x23, 0xA4
+ },
+ },
+ {
+ "[ cpu0#0 cpu0#1 cpu1#0 cpu0#2 cpu1#1 cpu1#2 ]",
+ {
+ 0x99, 0x00, 0x5E, 0xB7, 0xF8, 0x84, 0xA3, 0x99,
+ 0x7E, 0x12, 0xDE, 0xD1, 0x5B, 0xA7, 0x07, 0xF4,
+ 0x24, 0x3E, 0x77, 0xED, 0x60, 0xC0, 0xBD, 0x43,
+ 0x3B, 0x60, 0x7E, 0x38, 0xDD, 0x58, 0xC7, 0x46
+ },
+ },
+ {
+ "[ cpu0#0 cpu0#1 cpu1#0 cpu1#1 cpu0#2 cpu1#2 ]",
+ {
+ 0x0B, 0x5E, 0x31, 0x69, 0xAC, 0xAF, 0xA0, 0x8B,
+ 0x4F, 0x90, 0xD1, 0x86, 0xCC, 0x8E, 0x11, 0x42,
+ 0x0B, 0x74, 0x49, 0x6C, 0xA1, 0x27, 0x1B, 0x7C,
+ 0x52, 0x77, 0x7F, 0x2F, 0x53, 0x2F, 0x9A, 0xC1
+ },
+ },
+ {
+ "[ cpu0#0 cpu0#1 cpu1#0 cpu1#1 cpu1#2 cpu0#2 ]",
+ {
+ 0x99, 0xDE, 0xF8, 0x02, 0x27, 0xE9, 0x6F, 0x6F,
+ 0xA6, 0x55, 0xFC, 0x56, 0xCC, 0x7A, 0xFC, 0xEF,
+ 0x2F, 0x0C, 0x45, 0x3E, 0x01, 0xE0, 0x4B, 0xA1,
+ 0x60, 0x96, 0xEE, 0xB1, 0x4A, 0x25, 0x86, 0x89},
+ },
+ {
+ "[ cpu0#0 cpu1#0 cpu0#1 cpu0#2 cpu1#1 cpu1#2 ]",
+ { 0x88, 0x40, 0x05, 0xF5, 0xA6, 0x95, 0xC1, 0xC7,
+ 0xD3, 0x69, 0x16, 0x82, 0x0D, 0x79, 0xC1, 0x5B,
+ 0x4A, 0x48, 0xCA, 0x7F, 0xA5, 0xF3, 0x77, 0x37,
+ 0xBE, 0x0D, 0xAC, 0x2E, 0x42, 0x3E, 0x03, 0x37
+ },
+ },
+ {
+ "[ cpu0#0 cpu1#0 cpu0#1 cpu1#1 cpu0#2 cpu1#2 ]",
+ {
+ 0x68, 0x32, 0xC6, 0xAF, 0x8C, 0x86, 0x77, 0x09,
+ 0x4A, 0xB9, 0xA1, 0x9E, 0xBB, 0x2B, 0x42, 0x35,
+ 0xF8, 0xDE, 0x9A, 0x98, 0x37, 0x7B, 0x3E, 0x82,
+ 0x59, 0x0B, 0xC4, 0xAD, 0x1D, 0x01, 0x28, 0xCA
+ },
+ },
+ {
+ "[ cpu0#0 cpu1#0 cpu0#1 cpu1#1 cpu1#2 cpu0#2 ]",
+ {
+ 0xF5, 0x96, 0x77, 0x68, 0xD9, 0x6A, 0xA2, 0xFC,
+ 0x08, 0x8C, 0xF5, 0xA9, 0x6B, 0xE7, 0x1E, 0x20,
+ 0x35, 0xC1, 0x92, 0xCE, 0xBC, 0x3A, 0x75, 0xEA,
+ 0xB4, 0xEB, 0x17, 0xE5, 0x77, 0x50, 0x85, 0x40
+ },
+
+ },
+ {
+ "[ cpu0#0 cpu1#0 cpu1#1 cpu0#1 cpu0#2 cpu1#2 ]",
+ {
+ 0x4E, 0xA2, 0xD2, 0x79, 0x55, 0x75, 0xCB, 0x86,
+ 0x87, 0x34, 0x35, 0xE7, 0x75, 0xDF, 0xD5, 0x59,
+ 0x58, 0xDE, 0x74, 0x35, 0x68, 0x2B, 0xDC, 0xC8,
+ 0x85, 0x72, 0x97, 0xBE, 0x58, 0xB1, 0x1E, 0xA7
+ },
+
+ },
+ {
+ "[ cpu0#0 cpu1#0 cpu1#1 cpu0#1 cpu1#2 cpu0#2 ]",
+ {
+ 0xD1, 0xC2, 0xC8, 0x08, 0x00, 0x64, 0xB8, 0x1F,
+ 0xA0, 0xA5, 0x32, 0x20, 0xAA, 0x08, 0xC0, 0x48,
+ 0xDB, 0xB1, 0xED, 0xE7, 0xAF, 0x18, 0x2F, 0x7F,
+ 0x3C, 0xB8, 0x58, 0x83, 0xEC, 0xF9, 0x38, 0xFD
+ },
+
+ },
+ {
+ "[ cpu0#0 cpu1#0 cpu1#1 cpu1#2 cpu0#1 cpu0#2 ]",
+ {
+ 0xD1, 0xB8, 0x31, 0x98, 0x8E, 0xF2, 0xE7, 0xF5,
+ 0xBB, 0xD1, 0xE1, 0xC7, 0x3E, 0xB7, 0xA9, 0x18,
+ 0x3B, 0xCC, 0x58, 0x98, 0xED, 0x22, 0x1E, 0xE2,
+ 0x04, 0x76, 0xA1, 0xB9, 0x92, 0x54, 0xB5, 0x5B
+ },
+
+ },
+ {
+ "[ cpu1#0 cpu0#0 cpu0#1 cpu0#2 cpu1#1 cpu1#2 ]",
+ {
+ 0xAB, 0x50, 0x2A, 0x68, 0x28, 0x35, 0x16, 0xA9,
+ 0xDE, 0x26, 0x77, 0xAA, 0x99, 0x29, 0x0E, 0x9C,
+ 0x67, 0x41, 0x64, 0x28, 0x6E, 0xFF, 0x54, 0x33,
+ 0xE5, 0x29, 0xC4, 0xA5, 0x98, 0x40, 0x7E, 0xC9
+ },
+
+ },
+ {
+ "[ cpu1#0 cpu0#0 cpu0#1 cpu1#1 cpu0#2 cpu1#2 ]",
+ {
+ 0xA3, 0x4D, 0xB0, 0x28, 0xAB, 0x01, 0x56, 0xBB,
+ 0x7D, 0xE5, 0x0E, 0x86, 0x26, 0xBB, 0xBB, 0xDE,
+ 0x58, 0x91, 0x88, 0xBB, 0x9F, 0x6A, 0x58, 0x78,
+ 0x30, 0x2C, 0x22, 0x2E, 0x85, 0x7F, 0x87, 0xF6
+ },
+
+ },
+ {
+ "[ cpu1#0 cpu0#0 cpu0#1 cpu1#1 cpu1#2 cpu0#2 ]",
+ {
+ 0x1A, 0x2E, 0xD2, 0xC2, 0x0C, 0xBD, 0x30, 0xDA,
+ 0x4F, 0x37, 0x6B, 0x90, 0xE3, 0x67, 0xFE, 0x61,
+ 0x4F, 0x30, 0xBB, 0x29, 0xBC, 0xAA, 0x6E, 0xC5,
+ 0x60, 0x6E, 0x13, 0x6B, 0x33, 0x3D, 0xC0, 0x11
+ },
+
+ },
+ {
+ "[ cpu1#0 cpu0#0 cpu1#1 cpu0#1 cpu0#2 cpu1#2 ]",
+ {
+ 0x8F, 0xEA, 0xD1, 0x80, 0xE0, 0xBE, 0x27, 0xF7,
+ 0x8D, 0x19, 0xBF, 0x65, 0xBE, 0x92, 0x83, 0x7C,
+ 0x61, 0x8F, 0xC5, 0x8D, 0x0F, 0xAD, 0x89, 0x1E,
+ 0xAE, 0x0A, 0x75, 0xAC, 0x3E, 0x5F, 0xD5, 0x31
+ },
+
+ },
+ {
+ "[ cpu1#0 cpu0#0 cpu1#1 cpu0#1 cpu1#2 cpu0#2 ]",
+ {
+ 0x0F, 0x7B, 0xEE, 0xA5, 0x9A, 0xCD, 0xED, 0x8D,
+ 0x5A, 0x52, 0xFF, 0xD6, 0x30, 0xF4, 0xD9, 0xE9,
+ 0xF4, 0xC1, 0x1A, 0x0C, 0x86, 0x2B, 0x96, 0x2C,
+ 0x0E, 0x2D, 0x1A, 0x2A, 0xFE, 0xE6, 0x7C, 0xAD
+ },
+
+ },
+ {
+ "[ cpu1#0 cpu0#0 cpu1#1 cpu1#2 cpu0#1 cpu0#2 ]",
+ {
+ 0x4A, 0xBA, 0xFF, 0x0B, 0x0B, 0x06, 0xD1, 0xCE,
+ 0x95, 0x91, 0x70, 0x68, 0x20, 0xD6, 0xF2, 0x23,
+ 0xC5, 0x6A, 0x63, 0x2B, 0xCA, 0xDF, 0x37, 0xB5,
+ 0x0B, 0xDC, 0x64, 0x6A, 0xA3, 0xC9, 0x8F, 0x1E
+ },
+
+ },
+ {
+ "[ cpu1#0 cpu1#1 cpu0#0 cpu0#1 cpu0#2 cpu1#2 ]",
+ {
+ 0x3D, 0xB1, 0xE1, 0xBD, 0x85, 0x2C, 0xA0, 0x04,
+ 0xE6, 0x43, 0xE8, 0x82, 0xC3, 0x77, 0xF3, 0xCE,
+ 0x4D, 0x62, 0x2C, 0xF4, 0x65, 0xF6, 0x29, 0x5F,
+ 0x17, 0xDA, 0xD5, 0x79, 0x55, 0xE2, 0x3D, 0x0C
+ },
+
+ },
+ {
+ "[ cpu1#0 cpu1#1 cpu0#0 cpu0#1 cpu1#2 cpu0#2 ]",
+ {
+ 0x5B, 0xFE, 0x29, 0xA4, 0xDA, 0x9F, 0xE7, 0x13,
+ 0x5F, 0xA2, 0xCE, 0x53, 0x40, 0xC0, 0x38, 0xBC,
+ 0x10, 0x7A, 0xF0, 0x29, 0x3C, 0xD6, 0xAF, 0x8A,
+ 0x03, 0x40, 0xED, 0xE1, 0xFD, 0x46, 0xB7, 0x06
+ },
+
+ },
+ {
+ "[ cpu1#0 cpu1#1 cpu0#0 cpu1#2 cpu0#1 cpu0#2 ]",
+ {
+ 0x66, 0x20, 0xA7, 0xBE, 0xED, 0x90, 0x0A, 0x14,
+ 0x95, 0x7A, 0x93, 0x47, 0x1E, 0xA8, 0xDD, 0x6E,
+ 0x25, 0xCB, 0x73, 0x18, 0x77, 0x77, 0x91, 0xE9,
+ 0xCA, 0x17, 0x26, 0x16, 0xAA, 0xC9, 0x34, 0x7A
+ },
+
+ },
+ {
+ "[ cpu1#0 cpu1#1 cpu1#2 cpu0#0 cpu0#1 cpu0#2 ]",
+ {
+ 0x4D, 0xF6, 0xC7, 0x74, 0x37, 0x66, 0x4C, 0x6A,
+ 0x40, 0x32, 0x94, 0x01, 0x17, 0xA2, 0xE6, 0x3D,
+ 0xA8, 0x00, 0x3E, 0xB7, 0x89, 0x24, 0xF4, 0x04,
+ 0x14, 0xA8, 0xA1, 0xD1, 0xCD, 0x5B, 0xC3, 0x60
+ },
+
+ },
+ };
+
+ struct cpu_extend_run cpus[2] = {
+ /* CPU0 */
+ { .idx = &slot, .m = &m[0], .size = SHA256_SIZE },
+ /* CPU1 */
+ { .idx = &slot, .m = &m[1], .size = SHA256_SIZE },
+ };
+
+ for (slot = 1; slot <= REM_COUNT; slot++) {
+ for (m_idx = 0; m_idx < 3; m_idx++) {
+ memcpy(m[0].words, &measure_bytes[m_idx * 8], SHA256_SIZE);
+ memcpy(m[1].words, &measure_bytes[24 + m_idx * 8], SHA256_SIZE);
+ on_cpus(cpu_run_extend_measurement, (void *)&cpus[0]);
+ if (cpus[0].rc || cpus[1].rc)
+ return;
+ }
+ }
+
+ /* Get the token and parse the claims */
+ memset(page_buf_data, 0, sizeof(page_buf_data));
+ memset(&ch, 0xAB, sizeof(ch));
+ if (!get_attest_token_claims(page_buf_data, &ch, &claims, &token_size))
+ return;
+
+ /*
+ * Hard-coded test data expects sha-256 algorithm, skip the measurement
+ * value comparison if realm hash algo is different.
+ */
+ if (!claims_uses_sha256_algo(&claims)) {
+ report_skip("Hash algo is different than sha-256,"
+ " skip measurement value comparison");
+ return;
+ }
+
+ for (slot = 0; slot < REM_COUNT; slot++) {
+ struct claim_t *claim = &claims.realm_measurement_claims[slot];
+ const char *data = claim->buffer_data.ptr;
+ const size_t len = claim->buffer_data.len;
+
+ if (len != SHA256_SIZE) {
+ report(false, "Realm measurement size mismatch "
+ "%zu vs %d (expected)", len, SHA256_SIZE);
+ continue;
+ }
+
+ for (m_idx = 0; m_idx < ARRAY_SIZE(expected); m_idx++) {
+ struct extend_smp_expected *em = &expected[m_idx];
+
+ if (memcmp(data, em->measurement, SHA256_SIZE) == 0) {
+ report(true, "Hash found for slot %d: %s",
+ slot, em->sequence);
+ break;
+ }
+ }
+
+ if (m_idx == ARRAY_SIZE(expected))
+ report(false, "Measurement doesn't match any expected "
+ "sequence for slot %d", slot);
+ }
+}
+
+static void run_rsi_extend_smp_tests(void)
+{
+ report_prefix_push("extend_smp");
+ test_rsi_extend_smp();
+ report_prefix_pop();
+}
+
+static void test_rsi_extend_and_attest(void)
+{
+ struct challenge ch;
+ struct measurement m;
+ struct attestation_claims claims;
+ size_t token_size;
+ int i, j;
+
+ char measure_bytes[] = {
+ 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, /*slot 1*/
+ 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, /*slot 2*/
+ 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, /*slot 3*/
+ 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, /*slot 4*/
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /*slot 5*/
+ 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, /*slot 6*/
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+ 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
+ 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27
+ };
+
+ /* The following expectations assume extending with SHA256 */
+ char expected_measurements[][SHA256_SIZE] = {
+ {
+ 0x88, 0x78, 0xb1, 0x5a, 0x7d, 0x6a, 0x3a, 0x4f,
+ 0x46, 0x4e, 0x8f, 0x9f, 0x42, 0x59, 0x1d, 0xbc,
+ 0x0c, 0xf4, 0xbe, 0xde, 0xa0, 0xec, 0x30, 0x90,
+ 0x03, 0xd2, 0xb2, 0xee, 0x53, 0x65, 0x5e, 0xf8
+ },
+ {
+ 0x58, 0x32, 0x3b, 0xdf, 0x7a, 0x91, 0xf6, 0x8e,
+ 0x80, 0xc7, 0xc8, 0x7f, 0xda, 0x1e, 0x22, 0x6c,
+ 0x8b, 0xe7, 0xee, 0xa9, 0xef, 0x64, 0xa5, 0x21,
+ 0xdb, 0x2c, 0x09, 0xa7, 0xd7, 0x01, 0x92, 0x05
+ },
+ {
+ 0x66, 0xe3, 0x3b, 0x99, 0x49, 0x4d, 0xf4, 0xdd,
+ 0xbc, 0x7a, 0x61, 0x7a, 0xa1, 0x56, 0x7b, 0xf8,
+ 0x96, 0x3f, 0x0a, 0xf3, 0x1e, 0xab, 0xdd, 0x16,
+ 0x37, 0xb0, 0xfb, 0xe0, 0x71, 0x82, 0x66, 0xce
+ },
+ {
+ 0x97, 0x5e, 0x9f, 0x64, 0x79, 0x90, 0xa1, 0x51,
+ 0xd2, 0x5b, 0x73, 0x75, 0x50, 0x94, 0xeb, 0x54,
+ 0x90, 0xbb, 0x1e, 0xf8, 0x3b, 0x2c, 0xb8, 0x3b,
+ 0x6f, 0x24, 0xf3, 0x86, 0x07, 0xe0, 0x58, 0x13
+ },
+ {
+ 0x68, 0x99, 0x86, 0x64, 0x9b, 0xeb, 0xa2, 0xe4,
+ 0x4d, 0x07, 0xbb, 0xb3, 0xa1, 0xd9, 0x2d, 0x07,
+ 0x76, 0x7f, 0x86, 0x19, 0xb8, 0x5f, 0x14, 0x48,
+ 0x1f, 0x38, 0x4b, 0x87, 0x51, 0xdc, 0x10, 0x31
+ },
+ {
+ 0xee, 0x8f, 0xb3, 0xe9, 0xc8, 0xa5, 0xbe, 0x4f,
+ 0x12, 0x90, 0x4a, 0x52, 0xb9, 0xc8, 0x62, 0xd1,
+ 0x8a, 0x44, 0x31, 0xf7, 0x56, 0x7d, 0x96, 0xda,
+ 0x97, 0x7a, 0x9e, 0x96, 0xae, 0x6a, 0x78, 0x43
+ },
+ };
+ int times_to_extend[] = {1, 2, 3, 4, 5, 6};
+
+ memset(page_buf_data, 0, sizeof(page_buf_data));
+ memset(&ch, 0xAB, sizeof(ch));
+ if (!__get_attest_token_claims(page_buf_data, &ch,
+ &claims, &token_size, true))
+ return;
+
+ for (i = 0; i < REM_COUNT; i++) {
+ struct claim_t c = claims.realm_measurement_claims[i];
+ for (j = 0; j < c.buffer_data.len; j++) {
+ if (((char *)c.buffer_data.ptr)[j])
+ break;
+ }
+ }
+
+ report((i == REM_COUNT), "Initial measurements must be 0");
+
+ /* Extend the possible measurements (i.e., 1 to REM_COUNT) */
+ for (i = 1; i <= REM_COUNT; i++) {
+ memcpy(&m.words[0], &measure_bytes[(i - 1) * 8], SHA256_SIZE);
+ for (j = 0; j < times_to_extend[i - 1]; j++) {
+ struct smccc_result r;
+
+ measurement_extend(i, &m, SHA256_SIZE, &r);
+ if (r.r0) {
+ report(false, "Extend measurment slot %d, iteration %d "
+ "failed with %ld", i, j, r.r0);
+ return;
+ }
+ }
+ }
+ report(true, "Extend measurement for all slots completed");
+
+ /* Get the attestation token again */
+ if (!__get_attest_token_claims(page_buf_data, &ch,
+ &claims, &token_size, true))
+ return;
+
+ /*
+ * Hard-coded test data expects sha-256 algorithm, skip the measurement
+ * value comparison if realm hash algo is different.
+ */
+ if (!claims_uses_sha256_algo(&claims))
+ return;
+
+ /* Verify the extended measurements */
+ for (i = 0; i < REM_COUNT; i++) {
+ const char *exp = expected_measurements[i];
+ const char *actual = claims.realm_measurement_claims[i].buffer_data.ptr;
+ const size_t len = claims.realm_measurement_claims[i].buffer_data.len;
+
+ if (len != SHA256_SIZE) {
+ report(false, "Realm measurement: slot: %d, unexpected size "
+ "actual %ld vs %d expected", i, len,
+ SHA256_SIZE);
+ return;
+ }
+ if (memcmp(exp, actual, len)) {
+ report(false, "Measurement doesn't match for slot %d", i);
+ printf("Expected:\n");
+ for (j = 0; j < len; j++)
+ printf("0x%2x ", exp[j]);
+ printf("\nActual:\n");
+ for (j = 0; j < len; j++)
+ printf("0x%2x ", actual[j]);
+ printf("\n");
+ } else {
+ report(true, "Extended measurement match expected for "
+ "slot %d", i);
+
+ }
+ }
+}
+
+static void run_rsi_extend_and_attest_tests(void)
+{
+ report_prefix_push("extend_and_attest");
+ test_rsi_extend_and_attest();
+ report_prefix_pop();
+}
+
+#define MEASUREMENT_MAX_SIZE_LONGS 8
+
+static void test_read_measurement(void)
+{
+ struct smccc_result result;
+ return_code_t rc;
+ unsigned long *m;
+ int i, j;
+
+ /*
+ * We must be able to read all measurements
+ * 0 (Initial read-only measurement and the
+ * realm extendable ones, 1 to REM_COUNT.
+ */
+ for (i = 0; i <= REM_COUNT; i++) {
+ rsi_read_measurement(i, &result);
+ rc = unpack_return_code(result.r0);
+ if (rc.status) {
+ report(false, "Read measurement failed for slot %d with "
+ "(%d, %d)", i, rc.status, rc.index);
+ return;
+ }
+ m = &result.r1;
+ printf("Read measurement slot:%d, Hash = ", i);
+ for (j = 0; j < MEASUREMENT_MAX_SIZE_LONGS; j++)
+ printf("%lx", __builtin_bswap64(*m++));
+ printf("\n");
+ report(true, "Read Measurement Slot: %d", i);
+ }
+}
+
+static void test_read_measurement_bad_input(void)
+{
+ struct smccc_result result;
+ return_code_t rc;
+
+ report_prefix_push("out-of-range index");
+ rsi_read_measurement(REM_COUNT + 1, &result);
+ rc = unpack_return_code(result.r0);
+ if (rc.status != RSI_ERROR_INPUT) {
+ report(false, "Read measurement fails, "
+ "expected (%d), got (%d)",
+ RSI_ERROR_INPUT, rc.status);
+ } else {
+ report(true, "Read measurement fails as expected");
+ }
+ report_prefix_pop(); /* out-of-range index */
+}
+
+static void run_rsi_read_measurement_tests(void)
+{
+ report_prefix_push("measurement");
+ test_read_measurement();
+ test_read_measurement_bad_input();
+ report_prefix_pop();
+}
+
+int main(int argc, char **argv)
+{
+ int i;
+ report_prefix_push("attestation");
+
+ for (i = 1; i < argc; i++) {
+ if (strcmp(argv[i], "attest") == 0)
+ run_rsi_attest_tests();
+ else if (strcmp(argv[i], "attest_smp") == 0)
+ run_rsi_attest_smp_test();
+ else if (strcmp(argv[i], "extend") == 0)
+ run_rsi_extend_tests();
+ else if (strcmp(argv[i], "extend_smp") == 0)
+ run_rsi_extend_smp_tests();
+ else if (strcmp(argv[i], "extend_and_attest") == 0)
+ run_rsi_extend_and_attest_tests();
+ else if (strcmp(argv[i], "measurement") == 0)
+ run_rsi_read_measurement_tests();
+ else
+ report_info("Unknown subtest '%s'", argv[i]);
+ }
+ return report_summary();
+}
diff --git a/arm/unittests.cfg b/arm/unittests.cfg
index bc2354c7..5e9e1cbd 100644
--- a/arm/unittests.cfg
+++ b/arm/unittests.cfg
@@ -311,3 +311,53 @@ file = realm-sea.flat
groups = nodefault realms
accel = kvm
arch = arm64
+
+# Realm Attestation realted tests
+[realm-attest]
+file = realm-attest.flat
+groups = nodefault realms
+smp = 1
+extra_params = -m 32 -append 'attest'
+accel = kvm
+arch = arm64
+
+[realm-attest-smp]
+file = realm-attest.flat
+groups = nodefault realms
+smp = 2
+extra_params = -m 32 -append 'attest_smp'
+accel = kvm
+arch = arm64
+
+[realm-extend]
+file = realm-attest.flat
+groups = nodefault realms
+smp = 1
+extra_params = -m 32 -append 'extend'
+accel = kvm
+arch = arm64
+
+[realm-extend-smp]
+file = realm-attest.flat
+groups = nodefault realms
+smp = 2
+extra_params = -m 32 -append 'extend_smp'
+accel = kvm
+arch = arm64
+
+[realm-extend-and-attest]
+file = realm-attest.flat
+groups = nodefault realms
+smp = 1
+extra_params = -m 32 -append 'extend_and_attest'
+accel = kvm
+arch = arm64
+
+
+[realm-measurement]
+file = realm-attest.flat
+groups = nodefault realms
+smp = 1
+extra_params = -m 32 -append 'measurement'
+accel = kvm
+arch = arm64
diff --git a/lib/libcflat.h b/lib/libcflat.h
index c1fd31ff..893fee6f 100644
--- a/lib/libcflat.h
+++ b/lib/libcflat.h
@@ -163,6 +163,7 @@ extern void setup_vm(void);
#define SZ_64K (1 << 16)
#define SZ_1M (1 << 20)
#define SZ_2M (1 << 21)
+#define SZ_512M (1 << 29)
#define SZ_1G (1 << 30)
#define SZ_2G (1ul << 31)
--
2.17.1
next prev parent reply other threads:[~2023-01-27 11:43 UTC|newest]
Thread overview: 190+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-01-27 11:22 [RFC] Support for Arm CCA VMs on Linux Suzuki K Poulose
2023-01-27 11:27 ` [RFC PATCH 00/14] arm64: Support for running as a guest in Arm CCA Steven Price
2023-01-27 11:27 ` [RFC PATCH 01/14] arm64: remove redundant 'extern' Steven Price
2023-01-27 11:27 ` [RFC PATCH 02/14] arm64: rsi: Add RSI definitions Steven Price
2023-01-27 11:27 ` [RFC PATCH 03/14] arm64: Detect if in a realm and set RIPAS RAM Steven Price
2023-01-27 11:27 ` [RFC PATCH 04/14] arm64: realm: Query IPA size from the RMM Steven Price
2023-01-27 11:27 ` [RFC PATCH 05/14] arm64: Mark all I/O as non-secure shared Steven Price
2023-01-27 11:27 ` [RFC PATCH 06/14] fixmap: Allow architecture overriding set_fixmap_io Steven Price
2023-01-27 11:27 ` [RFC PATCH 07/14] arm64: Override set_fixmap_io Steven Price
2023-01-27 11:27 ` [RFC PATCH 08/14] arm64: Make the PHYS_MASK_SHIFT dynamic Steven Price
2023-01-27 11:27 ` [RFC PATCH 09/14] arm64: Enforce bounce buffers for realm DMA Steven Price
2023-01-27 11:27 ` [RFC PATCH 10/14] arm64: Enable memory encrypt for Realms Steven Price
2023-01-27 11:27 ` [RFC PATCH 11/14] arm64: Force device mappings to be non-secure shared Steven Price
2023-01-27 11:27 ` [RFC PATCH 12/14] efi: arm64: Map Device with Prot Shared Steven Price
2023-01-27 11:27 ` [RFC PATCH 13/14] arm64: realm: Support nonsecure ITS emulation shared Steven Price
2023-01-27 11:27 ` [RFC PATCH 14/14] HACK: Accept prototype RSI version Steven Price
2023-01-27 11:29 ` [RFC PATCH 00/28] arm64: Support for Arm CCA in KVM Steven Price
2023-01-27 11:29 ` [RFC PATCH 01/28] arm64: RME: Handle Granule Protection Faults (GPFs) Steven Price
2023-01-27 11:29 ` [RFC PATCH 02/28] arm64: RME: Add SMC definitions for calling the RMM Steven Price
2023-01-27 11:29 ` [RFC PATCH 03/28] arm64: RME: Add wrappers for RMI calls Steven Price
2023-02-13 16:43 ` Zhi Wang
2024-03-18 7:03 ` Ganapatrao Kulkarni
2024-03-18 11:22 ` Steven Price
2023-01-27 11:29 ` [RFC PATCH 04/28] arm64: RME: Check for RME support at KVM init Steven Price
2023-02-13 15:48 ` Zhi Wang
2023-02-13 15:59 ` Steven Price
2023-03-04 12:07 ` Zhi Wang
2023-02-13 15:55 ` Zhi Wang
2024-03-18 7:17 ` Ganapatrao Kulkarni
2024-03-18 11:22 ` Steven Price
2023-01-27 11:29 ` [RFC PATCH 05/28] arm64: RME: Define the user ABI Steven Price
2023-02-13 16:04 ` Zhi Wang
2023-03-01 11:54 ` Steven Price
2023-03-01 20:21 ` Zhi Wang
2023-01-27 11:29 ` [RFC PATCH 06/28] arm64: RME: ioctls to create and configure realms Steven Price
2023-02-07 12:25 ` Jean-Philippe Brucker
2023-02-07 12:55 ` Suzuki K Poulose
2023-02-13 16:10 ` Zhi Wang
2023-03-01 11:55 ` Steven Price
2023-03-01 20:33 ` Zhi Wang
2023-03-06 19:10 ` Zhi Wang
2023-03-10 15:47 ` Steven Price
2024-03-18 7:40 ` Ganapatrao Kulkarni
2024-03-18 11:22 ` Steven Price
2023-01-27 11:29 ` [RFC PATCH 07/28] arm64: kvm: Allow passing machine type in KVM creation Steven Price
2023-02-13 16:35 ` Zhi Wang
2023-03-01 11:55 ` Steven Price
2023-01-27 11:29 ` [RFC PATCH 08/28] arm64: RME: Keep a spare page delegated to the RMM Steven Price
2023-02-13 16:47 ` Zhi Wang
2023-03-01 11:55 ` Steven Price
2023-03-01 20:50 ` Zhi Wang
2023-01-27 11:29 ` [RFC PATCH 09/28] arm64: RME: RTT handling Steven Price
2023-02-13 17:44 ` Zhi Wang
2023-03-03 14:04 ` Steven Price
2023-03-04 12:32 ` Zhi Wang
2024-03-18 11:01 ` Ganapatrao Kulkarni
2024-03-18 11:25 ` Steven Price
2023-01-27 11:29 ` [RFC PATCH 10/28] arm64: RME: Allocate/free RECs to match vCPUs Steven Price
2023-02-13 18:08 ` Zhi Wang
2023-03-03 14:05 ` Steven Price
2023-03-04 12:46 ` Zhi Wang
2023-01-27 11:29 ` [RFC PATCH 11/28] arm64: RME: Support for the VGIC in realms Steven Price
2023-01-27 11:29 ` [RFC PATCH 12/28] KVM: arm64: Support timers in realm RECs Steven Price
2024-03-18 11:28 ` Ganapatrao Kulkarni
2024-03-18 14:14 ` Steven Price
2023-01-27 11:29 ` [RFC PATCH 13/28] arm64: RME: Allow VMM to set RIPAS Steven Price
2023-02-17 13:07 ` Zhi Wang
2023-03-03 14:05 ` Steven Price
2023-01-27 11:29 ` [RFC PATCH 14/28] arm64: RME: Handle realm enter/exit Steven Price
2023-01-27 11:29 ` [RFC PATCH 15/28] KVM: arm64: Handle realm MMIO emulation Steven Price
2023-03-06 15:37 ` Zhi Wang
2023-03-10 15:47 ` Steven Price
2023-03-14 15:44 ` Zhi Wang
2023-03-22 11:51 ` Steven Price
2023-01-27 11:29 ` [RFC PATCH 16/28] arm64: RME: Allow populating initial contents Steven Price
2023-03-06 17:34 ` Zhi Wang
2023-03-10 15:47 ` Steven Price
2023-03-14 15:31 ` Zhi Wang
2023-03-22 11:51 ` Steven Price
2023-01-27 11:29 ` [RFC PATCH 17/28] arm64: RME: Runtime faulting of memory Steven Price
2023-03-06 18:20 ` Zhi Wang
2023-03-10 15:47 ` Steven Price
2023-03-14 16:41 ` Zhi Wang
2023-01-27 11:29 ` [RFC PATCH 18/28] KVM: arm64: Handle realm VCPU load Steven Price
2023-01-27 11:29 ` [RFC PATCH 19/28] KVM: arm64: Validate register access for a Realm VM Steven Price
2023-01-27 11:29 ` [RFC PATCH 20/28] KVM: arm64: Handle Realm PSCI requests Steven Price
2023-01-27 11:29 ` [RFC PATCH 21/28] KVM: arm64: WARN on injected undef exceptions Steven Price
2023-01-27 11:29 ` [RFC PATCH 22/28] arm64: Don't expose stolen time for realm guests Steven Price
2023-01-27 11:29 ` [RFC PATCH 23/28] KVM: arm64: Allow activating realms Steven Price
2023-01-27 11:29 ` [RFC PATCH 24/28] arm64: rme: allow userspace to inject aborts Steven Price
2023-01-27 11:29 ` [RFC PATCH 25/28] arm64: rme: support RSI_HOST_CALL Steven Price
2023-01-27 11:29 ` [RFC PATCH 26/28] arm64: rme: Allow checking SVE on VM instance Steven Price
2023-01-27 11:29 ` [RFC PATCH 27/28] arm64: RME: Always use 4k pages for realms Steven Price
2023-01-27 11:29 ` [RFC PATCH 28/28] HACK: Accept prototype RMI versions Steven Price
2023-01-27 11:39 ` [RFC kvmtool 00/31] arm64: Support for Arm Confidential Compute Architecture Suzuki K Poulose
2023-01-27 11:39 ` [RFC kvmtool 01/31] arm64: Disable MTE when CFI flash is emulated Suzuki K Poulose
2023-01-27 11:39 ` [RFC kvmtool 02/31] script: update_headers: Ignore missing architectures Suzuki K Poulose
2023-01-27 11:39 ` [RFC kvmtool 03/31] hw: cfi flash: Handle errors in memory transitions Suzuki K Poulose
2023-01-27 11:39 ` [RFC kvmtool 04/31] Add --nocompat option to disable compat warnings Suzuki K Poulose
2023-01-27 12:19 ` Alexandru Elisei
2023-01-27 11:39 ` [RFC kvmtool 05/31] arm64: Check pvtime support against the KVM instance Suzuki K Poulose
2023-01-27 11:39 ` [RFC kvmtool 06/31] arm64: Check SVE capability on the VM instance Suzuki K Poulose
2023-01-27 11:39 ` [RFC kvmtool 07/31] arm64: Add option to disable SVE Suzuki K Poulose
2023-01-27 11:39 ` [RFC kvmtool 08/31] linux: Update kernel headers for RME support Suzuki K Poulose
2023-01-27 11:39 ` [RFC kvmtool 09/31] arm64: Add --realm command line option Suzuki K Poulose
2023-01-27 11:39 ` [RFC kvmtool 10/31] arm64: Create a realm virtual machine Suzuki K Poulose
2023-01-27 11:39 ` [RFC kvmtool 11/31] arm64: Lock realm RAM in memory Suzuki K Poulose
2023-01-27 11:39 ` [RFC kvmtool 12/31] arm64: Create Realm Descriptor Suzuki K Poulose
2023-01-27 11:39 ` [RFC kvmtool 13/31] arm64: Add --measurement-algo command line option for a realm Suzuki K Poulose
2023-01-27 11:39 ` [RFC kvmtool 14/31] arm64: Add configuration step for Realms Suzuki K Poulose
2023-01-27 11:39 ` [RFC kvmtool 15/31] arm64: Add support for Realm Personalisation Value Suzuki K Poulose
2023-01-27 11:39 ` [RFC kvmtool 16/31] arm64: Add support for specifying the SVE vector length for Realm Suzuki K Poulose
2023-01-27 11:39 ` [RFC kvmtool 17/31] arm: Add kernel size to VM context Suzuki K Poulose
2023-01-27 11:39 ` [RFC kvmtool 18/31] arm64: Populate initial realm contents Suzuki K Poulose
2023-03-02 14:03 ` Piotr Sawicki
2023-03-02 14:06 ` Suzuki K Poulose
2023-10-02 9:28 ` Piotr Sawicki
2023-01-27 11:39 ` [RFC kvmtool 19/31] arm64: Don't try to set PSTATE for VCPUs belonging to a realm Suzuki K Poulose
2023-01-27 11:39 ` [RFC kvmtool 20/31] arm64: Finalize realm VCPU after reset Suzuki K Poulose
2023-01-27 11:39 ` [RFC kvmtool 21/31] init: Add last_{init, exit} list macros Suzuki K Poulose
2023-01-27 11:39 ` [RFC kvmtool 22/31] arm64: Activate realm before the first VCPU is run Suzuki K Poulose
2023-01-27 11:39 ` [RFC kvmtool 23/31] arm64: Specify SMC as the PSCI conduits for realms Suzuki K Poulose
2023-01-27 11:39 ` [RFC kvmtool 24/31] arm64: Don't try to debug a realm Suzuki K Poulose
2023-01-27 11:39 ` [RFC kvmtool 25/31] arm64: realm: Double the IPA space Suzuki K Poulose
2023-01-27 11:39 ` [RFC kvmtool 26/31] virtio: Add a wrapper for get_host_features Suzuki K Poulose
2023-01-27 11:39 ` [RFC kvmtool 27/31] virtio: Add arch specific hook for virtio host flags Suzuki K Poulose
2023-01-27 11:39 ` [RFC kvmtool 28/31] arm64: realm: Enforce virtio F_ACCESS_PLATFORM flag Suzuki K Poulose
2023-01-27 11:39 ` [RFC kvmtool 29/31] mmio: add arch hook for an unhandled MMIO access Suzuki K Poulose
2023-01-27 11:39 ` [RFC kvmtool 30/31] arm64: realm: inject an abort on " Suzuki K Poulose
2023-01-27 11:39 ` [RFC kvmtool 31/31] arm64: Allow the user to create a realm Suzuki K Poulose
2023-10-02 9:45 ` [RFC kvmtool 00/31] arm64: Support for Arm Confidential Compute Architecture Piotr Sawicki
2023-01-27 11:40 ` [RFC kvm-unit-tests 00/27] " Joey Gouly
2023-01-27 11:40 ` [RFC kvm-unit-tests 01/27] lib/string: include stddef.h for size_t Joey Gouly
2023-01-31 14:43 ` Thomas Huth
2023-01-27 11:40 ` [RFC kvm-unit-tests 02/27] arm: Expand SMCCC arguments and return values Joey Gouly
2023-01-27 11:40 ` [RFC kvm-unit-tests 03/27] arm: realm: Add RSI interface header Joey Gouly
2023-01-27 11:40 ` [RFC kvm-unit-tests 04/27] arm: Make physical address mask dynamic Joey Gouly
2023-01-27 11:40 ` [RFC kvm-unit-tests 05/27] arm: Introduce NS_SHARED PTE attribute Joey Gouly
2023-01-27 11:40 ` [RFC kvm-unit-tests 06/27] arm: Move io_init after vm initialization Joey Gouly
2023-01-27 11:40 ` [RFC kvm-unit-tests 07/27] arm: realm: Make uart available before MMU is enabled Joey Gouly
2023-01-27 11:40 ` [RFC kvm-unit-tests 08/27] arm: realm: Realm initialisation Joey Gouly
2023-01-27 11:40 ` [RFC kvm-unit-tests 09/27] arm: realm: Add support for changing the state of memory Joey Gouly
2023-01-27 11:40 ` [RFC kvm-unit-tests 10/27] arm: realm: Set RIPAS state for RAM Joey Gouly
2023-01-27 11:40 ` [RFC kvm-unit-tests 11/27] arm: realm: Early memory setup Joey Gouly
2023-01-27 11:40 ` [RFC kvm-unit-tests 12/27] arm: realm: Add RSI version test Joey Gouly
2023-01-27 11:40 ` [RFC kvm-unit-tests 13/27] arm: selftest: realm: skip pabt test when running in a realm Joey Gouly
2023-01-27 11:40 ` [RFC kvm-unit-tests 14/27] arm: realm: add hvc and RSI_HOST_CALL tests Joey Gouly
2023-01-27 11:40 ` [RFC kvm-unit-tests 15/27] arm: realm: Add test for FPU/SIMD context save/restore Joey Gouly
2023-01-27 11:40 ` [RFC kvm-unit-tests 16/27] arm: realm: Add tests for in realm SEA Joey Gouly
2023-01-27 11:40 ` [RFC kvm-unit-tests 17/27] lib/alloc_page: Add shared page allocation support Joey Gouly
2023-01-27 11:40 ` [RFC kvm-unit-tests 18/27] arm: gic-v3-its: Use shared pages wherever needed Joey Gouly
2023-01-27 11:41 ` [RFC kvm-unit-tests 19/27] arm: realm: Enable memory encryption Joey Gouly
2023-01-27 11:41 ` [RFC kvm-unit-tests 20/27] qcbor: Add QCBOR as a submodule Joey Gouly
2023-01-27 11:41 ` [RFC kvm-unit-tests 21/27] arm: Add build steps for QCBOR library Joey Gouly
2023-01-27 11:41 ` [RFC kvm-unit-tests 22/27] arm: Add a library to verify tokens using the " Joey Gouly
2023-01-27 11:41 ` [RFC kvm-unit-tests 23/27] arm: realm: add RSI interface for attestation measurements Joey Gouly
2023-01-27 11:41 ` [RFC kvm-unit-tests 24/27] arm: realm: Add helpers to decode RSI return codes Joey Gouly
2023-01-27 11:41 ` Joey Gouly [this message]
2023-01-27 11:41 ` [RFC kvm-unit-tests 26/27] arm: realm: Add a test for shared memory Joey Gouly
2023-01-27 11:41 ` [RFC kvm-unit-tests 27/27] NOT-FOR-MERGING: add run-realm-tests Joey Gouly
2023-01-27 15:26 ` [RFC] Support for Arm CCA VMs on Linux Jean-Philippe Brucker
2023-02-28 23:35 ` Itaru Kitayama
2023-03-01 9:20 ` Jean-Philippe Brucker
2023-03-01 22:12 ` Itaru Kitayama
2023-03-02 9:18 ` Jean-Philippe Brucker
2023-03-03 9:46 ` Jean-Philippe Brucker
2023-03-03 9:54 ` Suzuki K Poulose
2023-03-03 11:39 ` Jean-Philippe Brucker
2023-03-03 12:08 ` Andrew Jones
2023-03-03 12:19 ` Suzuki K Poulose
2023-03-03 13:06 ` Cornelia Huck
2023-03-03 13:57 ` Jean-Philippe Brucker
2023-02-10 16:51 ` Ryan Roberts
2023-02-10 22:53 ` Itaru Kitayama
2023-02-17 8:02 ` Itaru Kitayama
2023-02-20 10:51 ` Ryan Roberts
2023-02-14 17:13 ` Dr. David Alan Gilbert
2023-03-01 9:58 ` Suzuki K Poulose
2023-03-02 16:46 ` Dr. David Alan Gilbert
2023-03-02 19:02 ` Suzuki K Poulose
2023-07-14 13:46 ` Jonathan Cameron
2023-07-14 15:03 ` Suzuki K Poulose
2023-07-14 16:28 ` Jonathan Cameron
2023-07-17 9:40 ` Suzuki K Poulose
2023-10-02 12:43 ` Suzuki K Poulose
2024-01-10 5:40 ` Itaru Kitayama
2024-01-10 11:41 ` Suzuki K Poulose
2024-01-10 13:44 ` Suzuki K Poulose
2024-01-19 1:26 ` Itaru Kitayama
2024-01-12 5:01 ` Itaru Kitayama
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=20230127114108.10025-26-joey.gouly@arm.com \
--to=joey.gouly@arm.com \
--cc=alexandru.elisei@arm.com \
--cc=andrew.jones@linux.dev \
--cc=christoffer.dall@arm.com \
--cc=jean-philippe@linaro.org \
--cc=kvm@vger.kernel.org \
--cc=kvmarm@lists.cs.columbia.edu \
--cc=kvmarm@lists.linux.dev \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-coco@lists.linux.dev \
--cc=linux-kernel@vger.kernel.org \
--cc=mark.rutland@arm.com \
--cc=mate.toth-pal@arm.com \
--cc=maz@kernel.org \
--cc=oliver.upton@linux.dev \
--cc=pbonzini@redhat.com \
--cc=qperret@google.com \
--cc=steven.price@arm.com \
--cc=suzuki.poulose@arm.com \
--cc=tabba@google.com \
--cc=thuth@redhat.com \
--cc=will@kernel.org \
--cc=yuzenghui@huawei.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).