fix(rme): use RMM shared buffer for attest SMCs
Use the RMM shared buffer to attestation token and signing key SMCs.
Signed-off-by: Javier Almansa Sobrino <javier.almansasobrino@arm.com>
Change-Id: I313838b26d3d9334fb0fe8cd4b229a326440d2f4
diff --git a/include/services/rmmd_svc.h b/include/services/rmmd_svc.h
index 8e9bdab..6adc5f3 100644
--- a/include/services/rmmd_svc.h
+++ b/include/services/rmmd_svc.h
@@ -84,12 +84,12 @@
#define RMMD_GTSI_UNDELEGATE SMC64_RMMD_EL3_FID(U(1))
/* Return error codes from RMM-EL3 SMCs */
-#define RMMD_OK 0
-#define RMMD_ERR_BAD_ADDR -2
-#define RMMD_ERR_BAD_PAS -3
-#define RMMD_ERR_NOMEM -4
-#define RMMD_ERR_INVAL -5
-#define RMMD_ERR_UNK -6
+#define E_RMM_OK 0
+#define E_RMM_UNK -1
+#define E_RMM_BAD_ADDR -2
+#define E_RMM_BAD_PAS -3
+#define E_RMM_NOMEM -4
+#define E_RMM_INVAL -5
/* Acceptable SHA sizes for Challenge object */
#define SHA256_DIGEST_SIZE 32U
diff --git a/plat/arm/board/fvp/include/platform_def.h b/plat/arm/board/fvp/include/platform_def.h
index 73d7ada..d0f8aa9 100644
--- a/plat/arm/board/fvp/include/platform_def.h
+++ b/plat/arm/board/fvp/include/platform_def.h
@@ -137,13 +137,13 @@
# define PLAT_ARM_MMAP_ENTRIES 9
# if USE_DEBUGFS
# if ENABLE_RME
-# define MAX_XLAT_TABLES 10
+# define MAX_XLAT_TABLES 9
# else
# define MAX_XLAT_TABLES 8
# endif
# else
# if ENABLE_RME
-# define MAX_XLAT_TABLES 9
+# define MAX_XLAT_TABLES 8
# else
# define MAX_XLAT_TABLES 7
# endif
diff --git a/services/std_svc/rmmd/rmmd_attest.c b/services/std_svc/rmmd/rmmd_attest.c
index 6c5f368..355b034 100644
--- a/services/std_svc/rmmd/rmmd_attest.c
+++ b/services/std_svc/rmmd/rmmd_attest.c
@@ -56,110 +56,96 @@
}
/*
- * TODO: Have different error codes for different errors so that the caller can
- * differentiate various error cases.
+ * Helper function to validate that the buffer base and length are
+ * within range.
*/
-int rmmd_attest_get_platform_token(uint64_t buf_pa, uint64_t *buf_len, uint64_t challenge_hash_len)
+static int validate_buffer_params(uint64_t buf_pa, uint64_t buf_len)
{
- int err;
- uintptr_t va;
- uint8_t temp_buf[SHA512_DIGEST_SIZE];
+ unsigned long shared_buf_page;
+ uintptr_t shared_buf_base;
- /*
- * TODO: Currently we don't validate incoming buf_pa. This is a
- * prototype and we will need to allocate static buffer for EL3-RMM
- * communication.
- */
+ (void)plat_rmmd_get_el3_rmm_shared_mem(&shared_buf_base);
- /* We need a page of buffer to pass data */
- if (*buf_len != PAGE_SIZE) {
- ERROR("Invalid buffer length\n");
- return RMMD_ERR_INVAL;
+ shared_buf_page = shared_buf_base & ~PAGE_SIZE_MASK;
+
+ /* Validate the buffer pointer */
+ if ((buf_pa & ~PAGE_SIZE_MASK) != shared_buf_page) {
+ ERROR("Buffer PA out of range\n");
+ return E_RMM_BAD_ADDR;
}
- if ((challenge_hash_len != SHA256_DIGEST_SIZE) &&
- (challenge_hash_len != SHA384_DIGEST_SIZE) &&
- (challenge_hash_len != SHA512_DIGEST_SIZE)) {
- ERROR("Invalid hash size: %lu\n", challenge_hash_len);
- return RMMD_ERR_INVAL;
+ /* Validate the size of the shared area */
+ if (((buf_pa + buf_len - 1UL) & ~PAGE_SIZE_MASK) != shared_buf_page) {
+ ERROR("Invalid buffer length\n");
+ return E_RMM_INVAL;
}
- spin_lock(&lock);
+ return 0; /* No error */
+}
+
+int rmmd_attest_get_platform_token(uint64_t buf_pa, uint64_t *buf_size,
+ uint64_t c_size)
+{
+ int err;
+ uint8_t temp_buf[SHA512_DIGEST_SIZE];
- /* Map the buffer that was provided by the RMM. */
- err = mmap_add_dynamic_region_alloc_va(buf_pa, &va, PAGE_SIZE,
- MT_RW_DATA | MT_REALM);
+ err = validate_buffer_params(buf_pa, *buf_size);
if (err != 0) {
- ERROR("mmap_add_dynamic_region_alloc_va failed: %d (%p).\n"
- , err, (void *)buf_pa);
- spin_unlock(&lock);
- return RMMD_ERR_NOMEM;
+ return err;
}
- (void)memcpy(temp_buf, (void *)va, challenge_hash_len);
+ if ((c_size != SHA256_DIGEST_SIZE) &&
+ (c_size != SHA384_DIGEST_SIZE) &&
+ (c_size != SHA512_DIGEST_SIZE)) {
+ ERROR("Invalid hash size: %lu\n", c_size);
+ return E_RMM_INVAL;
+ }
+
+ spin_lock(&lock);
- print_challenge((uint8_t *)temp_buf, challenge_hash_len);
+ (void)memcpy(temp_buf, (void *)buf_pa, c_size);
+
+ print_challenge((uint8_t *)temp_buf, c_size);
/* Get the platform token. */
- err = plat_rmmd_get_cca_attest_token(va,
- buf_len, (uintptr_t)temp_buf, challenge_hash_len);
+ err = plat_rmmd_get_cca_attest_token((uintptr_t)buf_pa,
+ buf_size, (uintptr_t)temp_buf, c_size);
if (err != 0) {
ERROR("Failed to get platform token: %d.\n", err);
- err = RMMD_ERR_UNK;
+ err = E_RMM_UNK;
}
- /* Unmap RMM memory. */
- (void)mmap_remove_dynamic_region(va, PAGE_SIZE);
spin_unlock(&lock);
return err;
}
-int rmmd_attest_get_signing_key(uint64_t buf_pa, uint64_t *buf_len,
+int rmmd_attest_get_signing_key(uint64_t buf_pa, uint64_t *buf_size,
uint64_t ecc_curve)
{
int err;
- uintptr_t va;
-
- /*
- * TODO: Currently we don't validate incoming buf_pa. This is a
- * prototype and we will need to allocate static buffer for EL3-RMM
- * communication.
- */
- /* We need a page of buffer to pass data */
- if (*buf_len != PAGE_SIZE) {
- ERROR("Invalid buffer length\n");
- return RMMD_ERR_INVAL;
+ err = validate_buffer_params(buf_pa, *buf_size);
+ if (err != 0) {
+ return err;
}
if (ecc_curve != ATTEST_KEY_CURVE_ECC_SECP384R1) {
ERROR("Invalid ECC curve specified\n");
- return RMMD_ERR_INVAL;
+ return E_RMM_INVAL;
}
spin_lock(&lock);
- /* Map the buffer that was provided by the RMM. */
- err = mmap_add_dynamic_region_alloc_va(buf_pa, &va, PAGE_SIZE,
- MT_RW_DATA | MT_REALM);
- if (err != 0) {
- ERROR("mmap_add_dynamic_region_alloc_va failed: %d (%p).\n"
- , err, (void *)buf_pa);
- spin_unlock(&lock);
- return RMMD_ERR_NOMEM;
- }
-
/* Get the Realm attestation key. */
- err = plat_rmmd_get_cca_realm_attest_key(va, buf_len, (unsigned int)ecc_curve);
+ err = plat_rmmd_get_cca_realm_attest_key((uintptr_t)buf_pa, buf_size,
+ (unsigned int)ecc_curve);
if (err != 0) {
ERROR("Failed to get attestation key: %d.\n", err);
- err = RMMD_ERR_UNK;
+ err = E_RMM_UNK;
}
- /* Unmap RMM memory. */
- (void)mmap_remove_dynamic_region(va, PAGE_SIZE);
spin_unlock(&lock);
return err;
diff --git a/services/std_svc/rmmd/rmmd_main.c b/services/std_svc/rmmd/rmmd_main.c
index d128e3e..27a1ad9 100644
--- a/services/std_svc/rmmd/rmmd_main.c
+++ b/services/std_svc/rmmd/rmmd_main.c
@@ -33,12 +33,6 @@
#include "rmmd_private.h"
/*******************************************************************************
- * RMM <-> EL3 shared buffer information.
- ******************************************************************************/
-static size_t shared_buf_size;
-static uintptr_t shared_buf_base;
-
-/*******************************************************************************
* RMM boot failure flag
******************************************************************************/
static bool rmm_boot_failed;
@@ -172,6 +166,8 @@
******************************************************************************/
int rmmd_setup(void)
{
+ size_t shared_buf_size __unused;
+ uintptr_t shared_buf_base;
uint32_t ep_attr;
unsigned int linear_id = plat_my_core_pos();
rmmd_rmm_context_t *rmm_ctx = &rmm_context[linear_id];
@@ -371,15 +367,15 @@
int ret;
if (error == 0) {
- return RMMD_OK;
+ return E_RMM_OK;
}
if (error == -EINVAL) {
- ret = RMMD_ERR_BAD_ADDR;
+ ret = E_RMM_BAD_ADDR;
} else {
/* This is the only other error code we expect */
assert(error == -EPERM);
- ret = RMMD_ERR_BAD_PAS;
+ ret = E_RMM_BAD_PAS;
}
ERROR("RMMD: PAS Transition failed. GPT ret = %d, PA: 0x%"PRIx64 ", FID = 0x%x\n",
diff --git a/services/std_svc/rmmd/rmmd_private.h b/services/std_svc/rmmd/rmmd_private.h
index e964ead..4954a43 100644
--- a/services/std_svc/rmmd/rmmd_private.h
+++ b/services/std_svc/rmmd/rmmd_private.h
@@ -46,10 +46,10 @@
__dead2 void rmmd_rmm_sync_exit(uint64_t rc);
/* Functions implementing attestation utilities for RMM */
-int rmmd_attest_get_platform_token(uint64_t buf_pa, uint64_t *buf_len,
- uint64_t challenge_hash_len);
-int rmmd_attest_get_signing_key(uint64_t buf_pa, uint64_t *buf_len,
- uint64_t ecc_curve);
+int rmmd_attest_get_platform_token(uint64_t buf_pa, uint64_t *buf_size,
+ uint64_t c_size);
+int rmmd_attest_get_signing_key(uint64_t buf_pa, uint64_t *buf_size,
+ uint64_t ecc_curve);
/* Assembly helpers */
uint64_t rmmd_rmm_enter(uint64_t *c_rt_ctx);