mirror of
https://github.com/ARM-software/arm-trusted-firmware.git
synced 2025-04-24 22:05:40 +00:00
feat(rmmd): el3 token sign during attestation
Add required SMCs by RMM to push attestation signing requests to EL3 and get responses. EL3 may then choose to push these requests to a HES as suitable for a platform. This patch also supports the new RMM_EL3_FEATURES interface, that RMM can use to query for support for HES based signing. The new interface exposes a feature register with different bits defining different discoverable features. This new interface is available starting the 0.4 version of the RMM-EL3 interface, causing the version to bump up. This patch also adds a platform port for FVP that implements the platform hooks required to enable the new SMCs, but it does not push to a HES and instead copies a zeroed buffer in EL3. Change-Id: I69c110252835122a9533e71bdcce10b5f2a686b2 Signed-off-by: Raghu Krishnamurthy <raghupathyk@nvidia.com>
This commit is contained in:
parent
75b0d5756f
commit
6a88ec8b30
10 changed files with 344 additions and 7 deletions
2
Makefile
2
Makefile
|
@ -1177,6 +1177,7 @@ $(eval $(call assert_booleans,\
|
||||||
HW_ASSISTED_COHERENCY \
|
HW_ASSISTED_COHERENCY \
|
||||||
MEASURED_BOOT \
|
MEASURED_BOOT \
|
||||||
DICE_PROTECTION_ENVIRONMENT \
|
DICE_PROTECTION_ENVIRONMENT \
|
||||||
|
RMMD_ENABLE_EL3_TOKEN_SIGN \
|
||||||
DRTM_SUPPORT \
|
DRTM_SUPPORT \
|
||||||
NS_TIMER_SWITCH \
|
NS_TIMER_SWITCH \
|
||||||
OVERRIDE_LIBC \
|
OVERRIDE_LIBC \
|
||||||
|
@ -1331,6 +1332,7 @@ $(eval $(call add_defines,\
|
||||||
ENABLE_PMF \
|
ENABLE_PMF \
|
||||||
ENABLE_PSCI_STAT \
|
ENABLE_PSCI_STAT \
|
||||||
ENABLE_RME \
|
ENABLE_RME \
|
||||||
|
RMMD_ENABLE_EL3_TOKEN_SIGN \
|
||||||
ENABLE_RUNTIME_INSTRUMENTATION \
|
ENABLE_RUNTIME_INSTRUMENTATION \
|
||||||
ENABLE_SME_FOR_NS \
|
ENABLE_SME_FOR_NS \
|
||||||
ENABLE_SME2_FOR_NS \
|
ENABLE_SME2_FOR_NS \
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
#endif
|
#endif
|
||||||
#if ENABLE_RME
|
#if ENABLE_RME
|
||||||
#include <services/rmm_core_manifest.h>
|
#include <services/rmm_core_manifest.h>
|
||||||
|
#include <services/rmm_el3_token_sign.h>
|
||||||
#endif
|
#endif
|
||||||
#include <drivers/fwu/fwu_metadata.h>
|
#include <drivers/fwu/fwu_metadata.h>
|
||||||
#if TRNG_SUPPORT
|
#if TRNG_SUPPORT
|
||||||
|
@ -376,6 +377,15 @@ int plat_rmmd_get_cca_attest_token(uintptr_t buf, size_t *len,
|
||||||
uint64_t *remaining_len);
|
uint64_t *remaining_len);
|
||||||
int plat_rmmd_get_cca_realm_attest_key(uintptr_t buf, size_t *len,
|
int plat_rmmd_get_cca_realm_attest_key(uintptr_t buf, size_t *len,
|
||||||
unsigned int type);
|
unsigned int type);
|
||||||
|
/* The following 3 functions are to be implement if
|
||||||
|
* RMMD_ENABLE_EL3_TOKEN_SIGN=1.
|
||||||
|
* The following three functions are expected to return E_RMM_* error codes.
|
||||||
|
*/
|
||||||
|
int plat_rmmd_el3_token_sign_get_rak_pub(uintptr_t buf, size_t *len,
|
||||||
|
unsigned int type);
|
||||||
|
int plat_rmmd_el3_token_sign_push_req(
|
||||||
|
const struct el3_token_sign_request *req);
|
||||||
|
int plat_rmmd_el3_token_sign_pull_resp(struct el3_token_sign_response *resp);
|
||||||
size_t plat_rmmd_get_el3_rmm_shared_mem(uintptr_t *shared);
|
size_t plat_rmmd_get_el3_rmm_shared_mem(uintptr_t *shared);
|
||||||
int plat_rmmd_load_manifest(struct rmm_manifest *manifest);
|
int plat_rmmd_load_manifest(struct rmm_manifest *manifest);
|
||||||
#endif
|
#endif
|
||||||
|
|
63
include/services/rmm_el3_token_sign.h
Normal file
63
include/services/rmm_el3_token_sign.h
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2024, NVIDIA Corporation. All rights reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef RMM_EL3_TOKEN_SIGN_H
|
||||||
|
#define RMM_EL3_TOKEN_SIGN_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <lib/cassert.h>
|
||||||
|
#include <services/rmmd_svc.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Defines member of structure and reserves space
|
||||||
|
* for the next member with specified offset.
|
||||||
|
*/
|
||||||
|
/* cppcheck-suppress [misra-c2012-20.7] */
|
||||||
|
#define SET_MEMBER(member, start, end) \
|
||||||
|
union { \
|
||||||
|
member; \
|
||||||
|
unsigned char reserved##end[((end) - (start))]; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define EL3_TOKEN_RESPONSE_MAX_SIG_LEN U(512)
|
||||||
|
|
||||||
|
struct el3_token_sign_request {
|
||||||
|
SET_MEMBER(uint32_t sig_alg_id, 0x0, 0x8);
|
||||||
|
SET_MEMBER(uint64_t rec_granule, 0x8, 0x10);
|
||||||
|
SET_MEMBER(uint64_t req_ticket, 0x10, 0x18);
|
||||||
|
SET_MEMBER(uint32_t hash_alg_id, 0x18, 0x20);
|
||||||
|
SET_MEMBER(uint8_t hash_buf[SHA512_DIGEST_SIZE], 0x20, 0x60);
|
||||||
|
};
|
||||||
|
|
||||||
|
CASSERT(__builtin_offsetof(struct el3_token_sign_request, sig_alg_id) == 0x0U,
|
||||||
|
assert_el3_token_sign_request_sig_alg_mismatch);
|
||||||
|
CASSERT(__builtin_offsetof(struct el3_token_sign_request, rec_granule) == 0x8U,
|
||||||
|
assert_el3_token_sign_request_rec_granule_mismatch);
|
||||||
|
CASSERT(__builtin_offsetof(struct el3_token_sign_request, req_ticket) == 0x10U,
|
||||||
|
assert_el3_token_sign_request_req_ticket_mismatch);
|
||||||
|
CASSERT(__builtin_offsetof(struct el3_token_sign_request, hash_alg_id) == 0x18U,
|
||||||
|
assert_el3_token_sign_request_hash_alg_id_mismatch);
|
||||||
|
CASSERT(__builtin_offsetof(struct el3_token_sign_request, hash_buf) == 0x20U,
|
||||||
|
assert_el3_token_sign_request_hash_buf_mismatch);
|
||||||
|
|
||||||
|
|
||||||
|
struct el3_token_sign_response {
|
||||||
|
SET_MEMBER(uint64_t rec_granule, 0x0, 0x8);
|
||||||
|
SET_MEMBER(uint64_t req_ticket, 0x8, 0x10);
|
||||||
|
SET_MEMBER(uint16_t sig_len, 0x10, 0x12);
|
||||||
|
SET_MEMBER(uint8_t signature_buf[EL3_TOKEN_RESPONSE_MAX_SIG_LEN], 0x12, 0x212);
|
||||||
|
};
|
||||||
|
|
||||||
|
CASSERT(__builtin_offsetof(struct el3_token_sign_response, rec_granule) == 0x0U,
|
||||||
|
assert_el3_token_sign_resp_rec_granule_mismatch);
|
||||||
|
CASSERT(__builtin_offsetof(struct el3_token_sign_response, req_ticket) == 0x8U,
|
||||||
|
assert_el3_token_sign_resp_req_ticket_mismatch);
|
||||||
|
CASSERT(__builtin_offsetof(struct el3_token_sign_response, sig_len) == 0x10U,
|
||||||
|
assert_el3_token_sign_resp_sig_len_mismatch);
|
||||||
|
CASSERT(__builtin_offsetof(struct el3_token_sign_response, signature_buf) == 0x12U,
|
||||||
|
assert_el3_token_sign_resp_sig_buf_mismatch);
|
||||||
|
|
||||||
|
#endif /* RMM_EL3_TOKEN_SIGN_H */
|
|
@ -129,8 +129,43 @@
|
||||||
/* 0x1B3 */
|
/* 0x1B3 */
|
||||||
#define RMM_ATTEST_GET_PLAT_TOKEN SMC64_RMMD_EL3_FID(U(3))
|
#define RMM_ATTEST_GET_PLAT_TOKEN SMC64_RMMD_EL3_FID(U(3))
|
||||||
|
|
||||||
|
/* Starting RMM-EL3 interface version 0.4 */
|
||||||
|
#define RMM_EL3_FEATURES SMC64_RMMD_EL3_FID(U(4))
|
||||||
|
#define RMM_EL3_FEAT_REG_0_IDX U(0)
|
||||||
|
/* Bit 0 of FEAT_REG_0 */
|
||||||
|
/* 1 - the feature is present in EL3 , 0 - the feature is absent */
|
||||||
|
#define RMM_EL3_FEAT_REG_0_EL3_TOKEN_SIGN_MASK U(0x1)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Function codes to support attestation where EL3 is used to sign
|
||||||
|
* realm attestation tokens. In this model, the private key is not
|
||||||
|
* exposed to the RMM.
|
||||||
|
* The arguments to this SMC are:
|
||||||
|
* arg0 - Function ID.
|
||||||
|
* arg1 - Opcode, one of:
|
||||||
|
* RMM_EL3_TOKEN_SIGN_PUSH_REQ_OP,
|
||||||
|
* RMM_EL3_TOKEN_SIGN_PULL_RESP_OP,
|
||||||
|
* RMM_EL3_TOKEN_SIGN_GET_RAK_PUB_OP
|
||||||
|
* arg2 - Pointer to buffer with request/response structures,
|
||||||
|
* which is in the RMM<->EL3 shared buffer.
|
||||||
|
* arg3 - Buffer size of memory pointed by arg2.
|
||||||
|
* arg4 - ECC Curve, when opcode is RMM_EL3_TOKEN_SIGN_GET_RAK_PUB_OP
|
||||||
|
* The return arguments are:
|
||||||
|
* ret0 - Status/Error
|
||||||
|
* ret1 - Size of public key if opcode is RMM_EL3_TOKEN_SIGN_GET_RAK_PUB_OP
|
||||||
|
*/
|
||||||
|
#define RMM_EL3_TOKEN_SIGN SMC64_RMMD_EL3_FID(U(5))
|
||||||
|
|
||||||
|
/* Opcodes for RMM_EL3_TOKEN_SIGN */
|
||||||
|
#define RMM_EL3_TOKEN_SIGN_PUSH_REQ_OP U(1)
|
||||||
|
#define RMM_EL3_TOKEN_SIGN_PULL_RESP_OP U(2)
|
||||||
|
#define RMM_EL3_TOKEN_SIGN_GET_RAK_PUB_OP U(3)
|
||||||
|
|
||||||
/* ECC Curve types for attest key generation */
|
/* ECC Curve types for attest key generation */
|
||||||
#define ATTEST_KEY_CURVE_ECC_SECP384R1 0
|
#define ATTEST_KEY_CURVE_ECC_SECP384R1 U(0)
|
||||||
|
|
||||||
|
/* Identifier for the hash algorithm used for attestation signing */
|
||||||
|
#define EL3_TOKEN_SIGN_HASH_ALG_SHA384 U(1)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* RMM_BOOT_COMPLETE originates on RMM when the boot finishes (either cold
|
* RMM_BOOT_COMPLETE originates on RMM when the boot finishes (either cold
|
||||||
|
@ -153,7 +188,7 @@
|
||||||
* Increase this when a bug is fixed, or a feature is added without
|
* Increase this when a bug is fixed, or a feature is added without
|
||||||
* breaking compatibility.
|
* breaking compatibility.
|
||||||
*/
|
*/
|
||||||
#define RMM_EL3_IFC_VERSION_MINOR (U(3))
|
#define RMM_EL3_IFC_VERSION_MINOR (U(4))
|
||||||
|
|
||||||
#define RMM_EL3_INTERFACE_VERSION \
|
#define RMM_EL3_INTERFACE_VERSION \
|
||||||
(((RMM_EL3_IFC_VERSION_MAJOR << 16) & 0x7FFFF) | \
|
(((RMM_EL3_IFC_VERSION_MAJOR << 16) & 0x7FFFF) | \
|
||||||
|
|
|
@ -409,3 +409,6 @@ EARLY_CONSOLE := 0
|
||||||
# Allow platforms to save/restore DSU PMU registers over a power cycle.
|
# Allow platforms to save/restore DSU PMU registers over a power cycle.
|
||||||
# Disabled by default and must be enabled by individual platforms.
|
# Disabled by default and must be enabled by individual platforms.
|
||||||
PRESERVE_DSU_PMU_REGS := 0
|
PRESERVE_DSU_PMU_REGS := 0
|
||||||
|
|
||||||
|
# Enable RMMD to forward attestation requests from RMM to EL3.
|
||||||
|
RMMD_ENABLE_EL3_TOKEN_SIGN := 0
|
||||||
|
|
98
plat/arm/board/fvp/fvp_el3_token_sign.c
Normal file
98
plat/arm/board/fvp/fvp_el3_token_sign.c
Normal file
|
@ -0,0 +1,98 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2024, NVIDIA Corporation. All rights reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <plat/common/platform.h>
|
||||||
|
#include <services/rmm_el3_token_sign.h>
|
||||||
|
|
||||||
|
static struct el3_token_sign_request el3_req = { 0 };
|
||||||
|
static bool el3_req_valid;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* According to https://www.secg.org/sec1-v2.pdf 2.3.3
|
||||||
|
* the size of the ECDSA P384 public key is 97 bytes,
|
||||||
|
* with the first byte being 0x04.
|
||||||
|
*/
|
||||||
|
static uint8_t sample_attest_pub_key[] = {
|
||||||
|
0x04, 0x76, 0xf9, 0x88, 0x09, 0x1b, 0xe5, 0x85, 0xed, 0x41,
|
||||||
|
0x80, 0x1a, 0xec, 0xfa, 0xb8, 0x58, 0x54, 0x8c, 0x63, 0x05,
|
||||||
|
0x7e, 0x16, 0xb0, 0xe6, 0x76, 0x12, 0x0b, 0xbd, 0x0d, 0x2f,
|
||||||
|
0x9c, 0x29, 0xe0, 0x56, 0xc5, 0xd4, 0x1a, 0x01, 0x30, 0xeb,
|
||||||
|
0x9c, 0x21, 0x51, 0x78, 0x99, 0xdc, 0x23, 0x14, 0x6b, 0x28,
|
||||||
|
0xe1, 0xb0, 0x62, 0xbd, 0x3e, 0xa4, 0xb3, 0x15, 0xfd, 0x21,
|
||||||
|
0x9f, 0x1c, 0xbb, 0x52, 0x8c, 0xb6, 0xe7, 0x4c, 0xa4, 0x9b,
|
||||||
|
0xe1, 0x67, 0x73, 0x73, 0x4f, 0x61, 0xa1, 0xca, 0x61, 0x03,
|
||||||
|
0x1b, 0x2b, 0xbf, 0x3d, 0x91, 0x8f, 0x2f, 0x94, 0xff, 0xc4,
|
||||||
|
0x22, 0x8e, 0x50, 0x91, 0x95, 0x44, 0xae
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* FVP does not support HES, so provide 0's as keys.
|
||||||
|
*/
|
||||||
|
int plat_rmmd_el3_token_sign_get_rak_pub(uintptr_t buf, size_t *len,
|
||||||
|
unsigned int type)
|
||||||
|
{
|
||||||
|
(void)type;
|
||||||
|
if (*len < sizeof(sample_attest_pub_key)) {
|
||||||
|
return E_RMM_INVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type != ATTEST_KEY_CURVE_ECC_SECP384R1) {
|
||||||
|
ERROR("Invalid ECC curve specified\n");
|
||||||
|
return E_RMM_INVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
*len = sizeof(sample_attest_pub_key);
|
||||||
|
|
||||||
|
(void)memcpy((void *)buf, sample_attest_pub_key,
|
||||||
|
sizeof(sample_attest_pub_key));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int plat_rmmd_el3_token_sign_push_req(const struct el3_token_sign_request *req)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* TODO: Today this function is called with a lock held on the
|
||||||
|
* RMM<->EL3 shared buffer. In the future, we may move to a
|
||||||
|
* different design that may require handling multi-threaded
|
||||||
|
* calls to this function, for example, if we have a per CPU
|
||||||
|
* buffer between RMM and EL3.
|
||||||
|
*/
|
||||||
|
if (el3_req_valid) {
|
||||||
|
return E_RMM_AGAIN;
|
||||||
|
}
|
||||||
|
|
||||||
|
el3_req = *req;
|
||||||
|
|
||||||
|
if ((el3_req.hash_alg_id != EL3_TOKEN_SIGN_HASH_ALG_SHA384) ||
|
||||||
|
(el3_req.sig_alg_id != ATTEST_KEY_CURVE_ECC_SECP384R1)) {
|
||||||
|
return E_RMM_INVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
el3_req_valid = true;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int plat_rmmd_el3_token_sign_pull_resp(struct el3_token_sign_response *resp)
|
||||||
|
{
|
||||||
|
if (!el3_req_valid) {
|
||||||
|
return E_RMM_AGAIN;
|
||||||
|
}
|
||||||
|
|
||||||
|
resp->rec_granule = el3_req.rec_granule;
|
||||||
|
resp->req_ticket = el3_req.req_ticket;
|
||||||
|
resp->sig_len = (uint16_t)sizeof(resp->signature_buf);
|
||||||
|
/* TODO: Provide real signature */
|
||||||
|
memset(resp->signature_buf, 0, sizeof(resp->signature_buf));
|
||||||
|
|
||||||
|
el3_req_valid = false;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -264,7 +264,8 @@ BL2_SOURCES += plat/arm/board/fvp/aarch64/fvp_helpers.S \
|
||||||
plat/arm/board/fvp/fvp_cpu_pwr.c
|
plat/arm/board/fvp/fvp_cpu_pwr.c
|
||||||
|
|
||||||
BL31_SOURCES += plat/arm/board/fvp/fvp_plat_attest_token.c \
|
BL31_SOURCES += plat/arm/board/fvp/fvp_plat_attest_token.c \
|
||||||
plat/arm/board/fvp/fvp_realm_attest_key.c
|
plat/arm/board/fvp/fvp_realm_attest_key.c \
|
||||||
|
plat/arm/board/fvp/fvp_el3_token_sign.c
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq (${ENABLE_FEAT_RNG_TRAP},1)
|
ifeq (${ENABLE_FEAT_RNG_TRAP},1)
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2022-2024, Arm Limited. All rights reserved.
|
* Copyright (c) 2022-2024, Arm Limited. All rights reserved.
|
||||||
|
* Copyright (c) 2024, NVIDIA Corporation. All rights reserved.
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*/
|
*/
|
||||||
|
@ -12,7 +13,8 @@
|
||||||
#include <lib/xlat_tables/xlat_tables_v2.h>
|
#include <lib/xlat_tables/xlat_tables_v2.h>
|
||||||
#include <plat/common/platform.h>
|
#include <plat/common/platform.h>
|
||||||
#include "rmmd_private.h"
|
#include "rmmd_private.h"
|
||||||
#include <services/rmmd_svc.h>
|
#include <services/rmm_el3_token_sign.h>
|
||||||
|
#include <smccc_helpers.h>
|
||||||
|
|
||||||
static spinlock_t lock;
|
static spinlock_t lock;
|
||||||
|
|
||||||
|
@ -163,3 +165,103 @@ int rmmd_attest_get_signing_key(uint64_t buf_pa, uint64_t *buf_size,
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int rmmd_el3_token_sign_push_req(uint64_t buf_pa, uint64_t buf_size)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
|
||||||
|
err = validate_buffer_params(buf_pa, buf_size);
|
||||||
|
if (err != 0) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (buf_size < sizeof(struct el3_token_sign_request)) {
|
||||||
|
return E_RMM_INVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
spin_lock(&lock);
|
||||||
|
|
||||||
|
/* Call platform port to handle attestation toekn signing request. */
|
||||||
|
err = plat_rmmd_el3_token_sign_push_req((struct el3_token_sign_request *)buf_pa);
|
||||||
|
|
||||||
|
spin_unlock(&lock);
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int rmmd_el3_token_sign_pull_resp(uint64_t buf_pa, uint64_t buf_size)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
|
||||||
|
err = validate_buffer_params(buf_pa, buf_size);
|
||||||
|
if (err != 0) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (buf_size < sizeof(struct el3_token_sign_response)) {
|
||||||
|
return E_RMM_INVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
spin_lock(&lock);
|
||||||
|
|
||||||
|
/* Pull attestation signing response from HES. */
|
||||||
|
err = plat_rmmd_el3_token_sign_pull_resp(
|
||||||
|
(struct el3_token_sign_response *)buf_pa);
|
||||||
|
|
||||||
|
spin_unlock(&lock);
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int rmmd_attest_get_attest_pub_key(uint64_t buf_pa, uint64_t *buf_size,
|
||||||
|
uint64_t ecc_curve)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
|
||||||
|
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 E_RMM_INVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
spin_lock(&lock);
|
||||||
|
|
||||||
|
/* Get the Realm attestation public key from platform port. */
|
||||||
|
err = plat_rmmd_el3_token_sign_get_rak_pub(
|
||||||
|
(uintptr_t)buf_pa, buf_size, (unsigned int)ecc_curve);
|
||||||
|
|
||||||
|
spin_unlock(&lock);
|
||||||
|
if (err != 0) {
|
||||||
|
ERROR("Failed to get attestation public key from HES: %d.\n",
|
||||||
|
err);
|
||||||
|
err = E_RMM_UNK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t rmmd_el3_token_sign(void *handle, uint64_t opcode, uint64_t x2,
|
||||||
|
uint64_t x3, uint64_t x4)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
switch (opcode) {
|
||||||
|
case RMM_EL3_TOKEN_SIGN_PUSH_REQ_OP:
|
||||||
|
ret = rmmd_el3_token_sign_push_req(x2, x3);
|
||||||
|
SMC_RET1(handle, ret);
|
||||||
|
case RMM_EL3_TOKEN_SIGN_PULL_RESP_OP:
|
||||||
|
ret = rmmd_el3_token_sign_pull_resp(x2, x3);
|
||||||
|
SMC_RET1(handle, ret);
|
||||||
|
case RMM_EL3_TOKEN_SIGN_GET_RAK_PUB_OP:
|
||||||
|
ret = rmmd_attest_get_attest_pub_key(x2, &x3, x4);
|
||||||
|
SMC_RET2(handle, ret, x3);
|
||||||
|
default:
|
||||||
|
SMC_RET1(handle, SMC_UNK);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -441,6 +441,21 @@ static int gpt_to_gts_error(int error, uint32_t smc_fid, uint64_t address)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int rmm_el3_ifc_get_feat_register(uint64_t feat_reg_idx,
|
||||||
|
uint64_t *feat_reg)
|
||||||
|
{
|
||||||
|
if (feat_reg_idx != RMM_EL3_FEAT_REG_0_IDX) {
|
||||||
|
ERROR("RMMD: Failed to get feature register %ld\n", feat_reg_idx);
|
||||||
|
return E_RMM_INVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
*feat_reg = 0UL;
|
||||||
|
#if RMMD_ENABLE_EL3_TOKEN_SIGN
|
||||||
|
*feat_reg |= RMM_EL3_FEAT_REG_0_EL3_TOKEN_SIGN_MASK;
|
||||||
|
#endif
|
||||||
|
return E_RMM_OK;
|
||||||
|
}
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* This function handles RMM-EL3 interface SMCs
|
* This function handles RMM-EL3 interface SMCs
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
@ -448,7 +463,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,
|
uint64_t x3, uint64_t x4, void *cookie,
|
||||||
void *handle, uint64_t flags)
|
void *handle, uint64_t flags)
|
||||||
{
|
{
|
||||||
uint64_t remaining_len = 0;
|
uint64_t remaining_len = 0UL;
|
||||||
uint32_t src_sec_state;
|
uint32_t src_sec_state;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
@ -479,7 +494,13 @@ uint64_t rmmd_rmm_el3_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2,
|
||||||
case RMM_ATTEST_GET_REALM_KEY:
|
case RMM_ATTEST_GET_REALM_KEY:
|
||||||
ret = rmmd_attest_get_signing_key(x1, &x2, x3);
|
ret = rmmd_attest_get_signing_key(x1, &x2, x3);
|
||||||
SMC_RET2(handle, ret, x2);
|
SMC_RET2(handle, ret, x2);
|
||||||
|
case RMM_EL3_FEATURES:
|
||||||
|
ret = rmm_el3_ifc_get_feat_register(x1, &x2);
|
||||||
|
SMC_RET2(handle, ret, x2);
|
||||||
|
#if RMMD_ENABLE_EL3_TOKEN_SIGN
|
||||||
|
case RMM_EL3_TOKEN_SIGN:
|
||||||
|
return rmmd_el3_token_sign(handle, x1, x2, x3, x4);
|
||||||
|
#endif
|
||||||
case RMM_BOOT_COMPLETE:
|
case RMM_BOOT_COMPLETE:
|
||||||
VERBOSE("RMMD: running rmmd_rmm_sync_exit\n");
|
VERBOSE("RMMD: running rmmd_rmm_sync_exit\n");
|
||||||
rmmd_rmm_sync_exit(x1);
|
rmmd_rmm_sync_exit(x1);
|
||||||
|
|
|
@ -51,6 +51,8 @@ int rmmd_attest_get_platform_token(uint64_t buf_pa, uint64_t *buf_size,
|
||||||
uint64_t *remaining_len);
|
uint64_t *remaining_len);
|
||||||
int rmmd_attest_get_signing_key(uint64_t buf_pa, uint64_t *buf_size,
|
int rmmd_attest_get_signing_key(uint64_t buf_pa, uint64_t *buf_size,
|
||||||
uint64_t ecc_curve);
|
uint64_t ecc_curve);
|
||||||
|
uint64_t rmmd_el3_token_sign(void *handle, uint64_t x1, uint64_t x2,
|
||||||
|
uint64_t x3, uint64_t x4);
|
||||||
|
|
||||||
/* Assembly helpers */
|
/* Assembly helpers */
|
||||||
uint64_t rmmd_rmm_enter(uint64_t *c_rt_ctx);
|
uint64_t rmmd_rmm_enter(uint64_t *c_rt_ctx);
|
||||||
|
|
Loading…
Add table
Reference in a new issue