Merge "refactor(rmmd): plat token requests in pieces" into integration

This commit is contained in:
Soby Mathew 2024-09-13 16:05:16 +02:00 committed by TrustedFirmware Code Review
commit 051c7ad81f
9 changed files with 115 additions and 32 deletions

View file

@ -52,7 +52,7 @@ are explained below:
- ``RES0``: Bit 31 of the version number is reserved 0 as to maintain
consistency with the versioning schemes used in other parts of RMM.
This document specifies the 0.2 version of Boot Interface ABI and RMM-EL3
This document specifies the 0.3 version of Boot Interface ABI and RMM-EL3
services specification and the 0.3 version of the Boot Manifest.
.. _rmm_el3_boot_interface:
@ -238,6 +238,7 @@ error condition as described in the following table:
``E_RMM_BAD_PAS``,Incorrect PAS,-3
``E_RMM_NOMEM``,Not enough memory to perform an operation,-4
``E_RMM_INVAL``,The value of an argument was invalid,-5
``E_RMM_AGAIN``,The resource is busy. Try again.,-6
If multiple failure conditions are detected in an RMM to EL3 command, then EL3
is allowed to return an error code corresponding to any of the failure
@ -442,7 +443,21 @@ Supported ECC Curves
RMM_ATTEST_GET_PLAT_TOKEN command
=================================
Retrieve the Platform Token from EL3.
Retrieve the Platform Token from EL3. If the entire token does not fit in the
buffer, EL3 returns a hunk of the token (via ``tokenHunkSize`` parameter) and
indicates the remaining bytes that are pending retrieval (via ``remainingSize``
parameter). The challenge object for the platform token must be populated in
the buffer for the first call of this command and the size of the object is
indicated by ``c_size`` parameter. Subsequent calls to retrieve remaining hunks of
the token must be made with ``c_size`` as 0.
If ``c_size`` is not 0, this command could cause regeneration of platform token
and will return token hunk corresponding to beginning of the token.
It is valid for the calls of this command to return ``E_RMM_AGAIN`` error,
which is an indication to the caller to retry this command again. Depending on the
platform, this mechanism can be used to implement queuing to HES, if HES is
involved in platform token generation.
FID
---
@ -457,9 +472,9 @@ Input values
:widths: 1 1 1 1 5
fid,x0,[63:0],UInt64,Command FID
buf_pa,x1,[63:0],Address,PA of the platform attestation token. The challenge object is passed in this buffer. The PA must belong to the shared buffer
buf_pa,x1,[63:0],Address,"PA of the platform attestation token. The challenge object must be passed in this buffer for the first call of this command. Any subsequent calls, if required to retrieve the full token, should not have this object. The PA must belong to the shared buffer."
buf_size,x2,[63:0],Size,Size in bytes of the platform attestation token buffer. ``bufPa + bufSize`` must lie within the shared buffer
c_size,x3,[63:0],Size,Size in bytes of the challenge object. It corresponds to the size of one of the defined SHA algorithms
c_size,x3,[63:0],Size,"Size in bytes of the challenge object. It corresponds to the size of one of the defined SHA algorithms. Any subsequent calls, if required to retrieve the full token, should set this size to 0."
Output values
-------------
@ -469,7 +484,8 @@ Output values
:widths: 1 1 1 1 5
Result,x0,[63:0],Error Code,Command return status
tokenSize,x1,[63:0],Size,Size of the platform token
tokenHunkSize,x1,[63:0],Size,Size of the platform token hunk retrieved
remainingSize,x2,[63:0],Size,Remaining bytes of the token that are pending retrieval
Failure conditions
------------------
@ -481,9 +497,11 @@ a failure. The errors are ordered by condition check.
:header: "ID", "Condition"
:widths: 1 5
``E_RMM_AGAIN``,Resource for Platform token retrieval is busy. Try again.
``E_RMM_BAD_ADDR``,``PA`` is outside the shared buffer
``E_RMM_INVAL``,``PA + BSize`` is outside the shared buffer
``E_RMM_INVAL``,``CSize`` does not represent the size of a supported SHA algorithm
``E_RMM_INVAL``,``CSize`` does not represent the size of a supported SHA algorithm for the first call to this command
``E_RMM_INVAL``,``CSize`` is not 0 for subsequent calls to retrieve remaining hunks of the token
``E_RMM_UNK``,An unknown error occurred whilst processing the command
``E_RMM_OK``,No errors detected

View file

@ -2248,26 +2248,35 @@ Function : plat_rmmd_get_cca_attest_token() [mandatory when ENABLE_RME == 1]
::
Argument : uintptr_t, size_t *, uintptr_t, size_t
Argument : uintptr_t, size_t *, uintptr_t, size_t, size_t *
Return : int
This function returns the Platform attestation token.
This function returns the Platform attestation token. If the full token does
not fit in the buffer, the function will return a hunk of the token and
indicate how many bytes were copied and how many are pending. Multiple calls
to this function may be needed to retrieve the entire token.
The parameters of the function are:
arg0 - A pointer to the buffer where the Platform token should be copied by
this function. The buffer must be big enough to hold the Platform
token.
this function. If the platform token does not completely fit in the
buffer, the function may return a piece of the token only.
arg1 - Contains the size (in bytes) of the buffer passed in arg0. The
function returns the platform token length in this parameter.
arg1 - Contains the size (in bytes) of the buffer passed in arg0. In
addition, this parameter is used by the function to return the size
of the platform token length hunk copied to the buffer.
arg2 - A pointer to the buffer where the challenge object is stored.
arg3 - The length of the challenge object in bytes. Possible values are 32,
48 and 64.
48 and 64. This argument must be zero for subsequent calls to
retrieve the remaining hunks of the token.
The function returns 0 on success, -EINVAL on failure.
arg4 - Returns the remaining length of the token (in bytes) that is yet to
be returned in further calls.
The function returns 0 on success, -EINVAL on failure and -EAGAIN if the
resource associated with the platform token retrieval is busy.
Function : plat_rmmd_get_cca_realm_attest_key() [mandatory when ENABLE_RME == 1]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View file

@ -370,8 +370,10 @@ plat_local_state_t plat_get_target_pwr_state(unsigned int lvl,
* Mandatory BL31 functions when ENABLE_RME=1
******************************************************************************/
#if ENABLE_RME
int plat_rmmd_get_cca_attest_token(uintptr_t buf, size_t *len,
uintptr_t hash, size_t hash_size);
uintptr_t hash, size_t hash_size,
uint64_t *remaining_len);
int plat_rmmd_get_cca_realm_attest_key(uintptr_t buf, size_t *len,
unsigned int type);
size_t plat_rmmd_get_el3_rmm_shared_mem(uintptr_t *shared);

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2021-2022, Arm Limited and Contributors. All rights reserved.
* Copyright (c) 2021-2024, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -90,6 +90,7 @@
#define E_RMM_BAD_PAS -3
#define E_RMM_NOMEM -4
#define E_RMM_INVAL -5
#define E_RMM_AGAIN -6
/* Return error codes from RMI SMCs */
#define RMI_SUCCESS 0
@ -156,7 +157,7 @@
* Increase this when a bug is fixed, or a feature is added without
* breaking compatibility.
*/
#define RMM_EL3_IFC_VERSION_MINOR (U(2))
#define RMM_EL3_IFC_VERSION_MINOR (U(3))
#define RMM_EL3_INTERFACE_VERSION \
(((RMM_EL3_IFC_VERSION_MAJOR << 16) & 0x7FFFF) | \

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2022-2023, Arm Limited and Contributors. All rights reserved.
* Copyright (c) 2022-2024, Arm Limited and Contributors. All rights reserved.
* Copyright (c) 2024, Linaro Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
@ -205,24 +205,54 @@ static const uint8_t sample_platform_token[] = {
0x43, 0x54, 0x4d, 0xb5, 0x88, 0xd6, 0xae, 0x67,
0x35, 0x7a, 0xfd, 0xb0, 0x5f, 0x95, 0xb7
};
static uint64_t platform_token_offset;
/*
* Get the hardcoded platform attestation token as FVP does not support
* RSE.
*
* Note: This implementation caters for retrieval of the platform token
* in hunks to facilitate EL3-RMM interface testing. For most platforms,
* since the shared buffer size is known, the implementation can be more
* optimized.
*/
int plat_rmmd_get_cca_attest_token(uintptr_t buf, size_t *len,
uintptr_t hash, size_t hash_size)
uintptr_t hash, size_t hash_size,
size_t *remaining_len)
{
(void)hash;
(void)hash_size;
size_t platform_token_size = sizeof(sample_platform_token);
size_t local_hunk_len;
size_t local_remaining_len;
if (*len < sizeof(sample_platform_token)) {
if (hash_size != 0) {
platform_token_offset = 0;
} else if (platform_token_offset == 0) {
return -EINVAL;
}
(void)memcpy((void *)buf, (const void *)sample_platform_token,
sizeof(sample_platform_token));
*len = sizeof(sample_platform_token);
local_hunk_len = *len;
local_remaining_len = platform_token_size - platform_token_offset;
/*
* If the buffer is enough to fit the remaining bytes of the token,
* return only the remaining bytes of the token.
*/
if (local_hunk_len >= local_remaining_len) {
local_hunk_len = local_remaining_len;
}
/* Update remaining bytes according to hunk size */
local_remaining_len -= local_hunk_len;
(void)memcpy((void *)buf,
(const void *)sample_platform_token
+ platform_token_offset,
local_hunk_len);
platform_token_offset += local_hunk_len;
*len = local_hunk_len;
*remaining_len = local_remaining_len;
return 0;
}

View file

@ -4,23 +4,32 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <assert.h>
#include <errno.h>
#include <stdint.h>
#include <cca_attestation.h>
#include <common/debug.h>
#include <plat/common/common_def.h>
#include <psa/error.h>
int plat_rmmd_get_cca_attest_token(uintptr_t buf, size_t *len,
uintptr_t hash, size_t hash_size)
uintptr_t hash, size_t hash_size,
size_t *remaining_len)
{
psa_status_t ret;
assert(*len == SZ_4K);
ret = cca_attestation_get_plat_token(buf, len, hash, hash_size);
if (ret != PSA_SUCCESS) {
ERROR("Unable to fetch CCA attestation token\n");
return -1;
}
assert(*len <= SZ_4K);
*remaining_len = 0;
return 0;
}

View file

@ -1,8 +1,9 @@
/*
* Copyright (c) 2022, Arm Limited. All rights reserved.
* Copyright (c) 2022-2024, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <errno.h>
#include <stdint.h>
#include <string.h>
@ -85,7 +86,8 @@ static int validate_buffer_params(uint64_t buf_pa, uint64_t buf_len)
}
int rmmd_attest_get_platform_token(uint64_t buf_pa, uint64_t *buf_size,
uint64_t c_size)
uint64_t c_size,
uint64_t *remaining_len)
{
int err;
uint8_t temp_buf[SHA512_DIGEST_SIZE];
@ -110,9 +112,19 @@ int rmmd_attest_get_platform_token(uint64_t buf_pa, uint64_t *buf_size,
/* Get the platform token. */
err = plat_rmmd_get_cca_attest_token((uintptr_t)buf_pa,
buf_size, (uintptr_t)temp_buf, c_size);
buf_size, (uintptr_t)temp_buf, c_size, remaining_len);
if (err != 0) {
switch (err) {
case 0:
err = E_RMM_OK;
break;
case -EAGAIN:
err = E_RMM_AGAIN;
break;
case -EINVAL:
err = E_RMM_INVAL;
break;
default:
ERROR("Failed to get platform token: %d.\n", err);
err = E_RMM_UNK;
}

View file

@ -448,6 +448,7 @@ uint64_t rmmd_rmm_el3_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2,
uint64_t x3, uint64_t x4, void *cookie,
void *handle, uint64_t flags)
{
uint64_t remaining_len = 0;
uint32_t src_sec_state;
int ret;
@ -473,8 +474,8 @@ uint64_t rmmd_rmm_el3_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2,
ret = gpt_undelegate_pas(x1, PAGE_SIZE_4KB, SMC_FROM_REALM);
SMC_RET1(handle, gpt_to_gts_error(ret, smc_fid, x1));
case RMM_ATTEST_GET_PLAT_TOKEN:
ret = rmmd_attest_get_platform_token(x1, &x2, x3);
SMC_RET2(handle, ret, x2);
ret = rmmd_attest_get_platform_token(x1, &x2, x3, &remaining_len);
SMC_RET3(handle, ret, x2, remaining_len);
case RMM_ATTEST_GET_REALM_KEY:
ret = rmmd_attest_get_signing_key(x1, &x2, x3);
SMC_RET2(handle, ret, x2);

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2021-2022, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2021-2024, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -47,7 +47,8 @@ __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_size,
uint64_t c_size);
uint64_t c_size,
uint64_t *remaining_len);
int rmmd_attest_get_signing_key(uint64_t buf_pa, uint64_t *buf_size,
uint64_t ecc_curve);