From af26d7d6f01068809f17cc2d49a9b3d573c640a9 Mon Sep 17 00:00:00 2001 From: Tamas Ban Date: Mon, 10 Jan 2022 17:04:03 +0100 Subject: [PATCH 1/8] feat(drivers/arm/mhu): add MHU driver The Arm Message Handling Unit (MHU) is a mailbox controller used to communicate with other processing element(s). Adding a driver to enable the communication: - Adding generic MHU driver interface, - Adding MHU_v2_x driver. Driver supports: - Discovering available MHU channels, - Sending / receiving words over MHU channels, - Signaling happens over a dedicated channel. Signed-off-by: Tamas Ban Signed-off-by: David Vincze Change-Id: I41a5b968f6b8319cdbdf7907d70bd8837839862e --- drivers/arm/mhu/mhu_v2_x.c | 379 +++++++++++++++++++++++++++++ drivers/arm/mhu/mhu_v2_x.h | 210 ++++++++++++++++ drivers/arm/mhu/mhu_wrapper_v2_x.c | 302 +++++++++++++++++++++++ include/drivers/arm/mhu.h | 79 ++++++ 4 files changed, 970 insertions(+) create mode 100644 drivers/arm/mhu/mhu_v2_x.c create mode 100644 drivers/arm/mhu/mhu_v2_x.h create mode 100644 drivers/arm/mhu/mhu_wrapper_v2_x.c create mode 100644 include/drivers/arm/mhu.h diff --git a/drivers/arm/mhu/mhu_v2_x.c b/drivers/arm/mhu/mhu_v2_x.c new file mode 100644 index 000000000..3103b9243 --- /dev/null +++ b/drivers/arm/mhu/mhu_v2_x.c @@ -0,0 +1,379 @@ +/* + * Copyright (c) 2020-2022, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include + +#include "mhu_v2_x.h" + +#define MHU_V2_X_MAX_CHANNELS 124 +#define MHU_V2_1_MAX_CHCOMB_INT 4 +#define ENABLE 0x1 +#define DISABLE 0x0 +#define CLEAR_INTR 0x1 +#define CH_PER_CH_COMB 0x20 +#define SEND_FRAME(p_mhu) ((struct mhu_v2_x_send_frame_t *)p_mhu) +#define RECV_FRAME(p_mhu) ((struct mhu_v2_x_recv_frame_t *)p_mhu) + +#define MHU_MAJOR_REV_V2 0x1u +#define MHU_MINOR_REV_2_0 0x0u +#define MHU_MINOR_REV_2_1 0x1u + +struct mhu_v2_x_send_ch_window_t { + /* Offset: 0x00 (R/ ) Channel Status */ + volatile uint32_t ch_st; + /* Offset: 0x04 (R/ ) Reserved */ + volatile uint32_t reserved_0; + /* Offset: 0x08 (R/ ) Reserved */ + volatile uint32_t reserved_1; + /* Offset: 0x0C ( /W) Channel Set */ + volatile uint32_t ch_set; + /* Offset: 0x10 (R/ ) Channel Interrupt Status (Reserved in 2.0) */ + volatile uint32_t ch_int_st; + /* Offset: 0x14 ( /W) Channel Interrupt Clear (Reserved in 2.0) */ + volatile uint32_t ch_int_clr; + /* Offset: 0x18 (R/W) Channel Interrupt Enable (Reserved in 2.0) */ + volatile uint32_t ch_int_en; + /* Offset: 0x1C (R/ ) Reserved */ + volatile uint32_t reserved_2; +}; + +struct mhu_v2_x_send_frame_t { + /* Offset: 0x000 ( / ) Sender Channel Window 0 -123 */ + struct mhu_v2_x_send_ch_window_t send_ch_window[MHU_V2_X_MAX_CHANNELS]; + /* Offset: 0xF80 (R/ ) Message Handling Unit Configuration */ + volatile uint32_t mhu_cfg; + /* Offset: 0xF84 (R/W) Response Configuration */ + volatile uint32_t resp_cfg; + /* Offset: 0xF88 (R/W) Access Request */ + volatile uint32_t access_request; + /* Offset: 0xF8C (R/ ) Access Ready */ + volatile uint32_t access_ready; + /* Offset: 0xF90 (R/ ) Interrupt Status */ + volatile uint32_t int_st; + /* Offset: 0xF94 ( /W) Interrupt Clear */ + volatile uint32_t int_clr; + /* Offset: 0xF98 (R/W) Interrupt Enable */ + volatile uint32_t int_en; + /* Offset: 0xF9C (R/ ) Reserved */ + volatile uint32_t reserved_0; + /* Offset: 0xFA0 (R/W) Channel Combined IRQ Stat (Reserved in 2.0) */ + volatile uint32_t ch_comb_int_st[MHU_V2_1_MAX_CHCOMB_INT]; + /* Offset: 0xFC4 (R/ ) Reserved */ + volatile uint32_t reserved_1[6]; + /* Offset: 0xFC8 (R/ ) Implementer Identification Register */ + volatile uint32_t iidr; + /* Offset: 0xFCC (R/ ) Architecture Identification Register */ + volatile uint32_t aidr; + /* Offset: 0xFD0 (R/ ) */ + volatile uint32_t pid_1[4]; + /* Offset: 0xFE0 (R/ ) */ + volatile uint32_t pid_0[4]; + /* Offset: 0xFF0 (R/ ) */ + volatile uint32_t cid[4]; +}; + +struct mhu_v2_x_rec_ch_window_t { + /* Offset: 0x00 (R/ ) Channel Status */ + volatile uint32_t ch_st; + /* Offset: 0x04 (R/ ) Channel Status Masked */ + volatile uint32_t ch_st_msk; + /* Offset: 0x08 ( /W) Channel Clear */ + volatile uint32_t ch_clr; + /* Offset: 0x0C (R/ ) Reserved */ + volatile uint32_t reserved_0; + /* Offset: 0x10 (R/ ) Channel Mask Status */ + volatile uint32_t ch_msk_st; + /* Offset: 0x14 ( /W) Channel Mask Set */ + volatile uint32_t ch_msk_set; + /* Offset: 0x18 ( /W) Channel Mask Clear */ + volatile uint32_t ch_msk_clr; + /* Offset: 0x1C (R/ ) Reserved */ + volatile uint32_t reserved_1; +}; + +struct mhu_v2_x_recv_frame_t { + /* Offset: 0x000 ( / ) Receiver Channel Window 0 -123 */ + struct mhu_v2_x_rec_ch_window_t rec_ch_window[MHU_V2_X_MAX_CHANNELS]; + /* Offset: 0xF80 (R/ ) Message Handling Unit Configuration */ + volatile uint32_t mhu_cfg; + /* Offset: 0xF84 (R/ ) Reserved */ + volatile uint32_t reserved_0[3]; + /* Offset: 0xF90 (R/ ) Interrupt Status (Reserved in 2.0) */ + volatile uint32_t int_st; + /* Offset: 0xF94 (R/ ) Interrupt Clear (Reserved in 2.0) */ + volatile uint32_t int_clr; + /* Offset: 0xF98 (R/W) Interrupt Enable (Reserved in 2.0) */ + volatile uint32_t int_en; + /* Offset: 0xF9C (R/ ) Reserved */ + volatile uint32_t reserved_1; + /* Offset: 0xFA0 (R/ ) Channel Combined IRQ Stat (Reserved in 2.0) */ + volatile uint32_t ch_comb_int_st[MHU_V2_1_MAX_CHCOMB_INT]; + /* Offset: 0xFB0 (R/ ) Reserved */ + volatile uint32_t reserved_2[6]; + /* Offset: 0xFC8 (R/ ) Implementer Identification Register */ + volatile uint32_t iidr; + /* Offset: 0xFCC (R/ ) Architecture Identification Register */ + volatile uint32_t aidr; + /* Offset: 0xFD0 (R/ ) */ + volatile uint32_t pid_1[4]; + /* Offset: 0xFE0 (R/ ) */ + volatile uint32_t pid_0[4]; + /* Offset: 0xFF0 (R/ ) */ + volatile uint32_t cid[4]; +}; + +union mhu_v2_x_frame { + struct mhu_v2_x_send_frame_t send_frame; + struct mhu_v2_x_recv_frame_t recv_frame; +}; + +enum mhu_v2_x_error_t mhu_v2_x_driver_init(struct mhu_v2_x_dev_t *dev, + enum mhu_v2_x_supported_revisions rev) +{ + uint32_t AIDR = 0; + union mhu_v2_x_frame *p_mhu; + + assert(dev != NULL); + + p_mhu = (union mhu_v2_x_frame *)dev->base; + + if (dev->is_initialized) { + return MHU_V_2_X_ERR_ALREADY_INIT; + } + + if (rev == MHU_REV_READ_FROM_HW) { + /* Read revision from HW */ + if (dev->frame == MHU_V2_X_RECEIVER_FRAME) { + AIDR = p_mhu->recv_frame.aidr; + } else { + AIDR = p_mhu->send_frame.aidr; + } + + /* Get bits 7:4 to read major revision */ + if (((AIDR >> 4) & 0b1111) != MHU_MAJOR_REV_V2) { + /* Unsupported MHU version */ + return MHU_V_2_X_ERR_UNSUPPORTED_VERSION; + } /* No need to save major version, driver only supports MHUv2 */ + + /* Get bits 3:0 to read minor revision */ + dev->subversion = AIDR & 0b1111; + + if (dev->subversion != MHU_MINOR_REV_2_0 && + dev->subversion != MHU_MINOR_REV_2_1) { + /* Unsupported subversion */ + return MHU_V_2_X_ERR_UNSUPPORTED_VERSION; + } + } else { + /* Revisions were provided by caller */ + if (rev == MHU_REV_2_0) { + dev->subversion = MHU_MINOR_REV_2_0; + } else if (rev == MHU_REV_2_1) { + dev->subversion = MHU_MINOR_REV_2_1; + } else { + /* Unsupported subversion */ + return MHU_V_2_X_ERR_UNSUPPORTED_VERSION; + } /* No need to save major version, driver only supports MHUv2 */ + } + + dev->is_initialized = true; + + return MHU_V_2_X_ERR_NONE; +} + +uint32_t mhu_v2_x_get_num_channel_implemented(const struct mhu_v2_x_dev_t *dev) +{ + union mhu_v2_x_frame *p_mhu; + + assert(dev != NULL); + + p_mhu = (union mhu_v2_x_frame *)dev->base; + + if (!(dev->is_initialized)) { + return MHU_V_2_X_ERR_NOT_INIT; + } + + if (dev->frame == MHU_V2_X_SENDER_FRAME) { + return (SEND_FRAME(p_mhu))->mhu_cfg; + } else { + assert(dev->frame == MHU_V2_X_RECEIVER_FRAME); + return (RECV_FRAME(p_mhu))->mhu_cfg; + } +} + +enum mhu_v2_x_error_t mhu_v2_x_channel_send(const struct mhu_v2_x_dev_t *dev, + uint32_t channel, uint32_t val) +{ + union mhu_v2_x_frame *p_mhu; + + assert(dev != NULL); + + p_mhu = (union mhu_v2_x_frame *)dev->base; + + if (!(dev->is_initialized)) { + return MHU_V_2_X_ERR_NOT_INIT; + } + + if (dev->frame == MHU_V2_X_SENDER_FRAME) { + (SEND_FRAME(p_mhu))->send_ch_window[channel].ch_set = val; + return MHU_V_2_X_ERR_NONE; + } else { + return MHU_V_2_X_ERR_INVALID_ARG; + } +} + +enum mhu_v2_x_error_t mhu_v2_x_channel_poll(const struct mhu_v2_x_dev_t *dev, + uint32_t channel, uint32_t *value) +{ + union mhu_v2_x_frame *p_mhu; + + assert(dev != NULL); + + p_mhu = (union mhu_v2_x_frame *)dev->base; + + if (!(dev->is_initialized)) { + return MHU_V_2_X_ERR_NOT_INIT; + } + + if (dev->frame == MHU_V2_X_SENDER_FRAME) { + *value = (SEND_FRAME(p_mhu))->send_ch_window[channel].ch_st; + return MHU_V_2_X_ERR_NONE; + } else { + return MHU_V_2_X_ERR_INVALID_ARG; + } +} + +enum mhu_v2_x_error_t mhu_v2_x_channel_clear(const struct mhu_v2_x_dev_t *dev, + uint32_t channel) +{ + union mhu_v2_x_frame *p_mhu; + + assert(dev != NULL); + + p_mhu = (union mhu_v2_x_frame *)dev->base; + + if (!(dev->is_initialized)) { + return MHU_V_2_X_ERR_NOT_INIT; + } + + if (dev->frame == MHU_V2_X_RECEIVER_FRAME) { + (RECV_FRAME(p_mhu))->rec_ch_window[channel].ch_clr = UINT32_MAX; + return MHU_V_2_X_ERR_NONE; + } else { + return MHU_V_2_X_ERR_INVALID_ARG; + } +} + +enum mhu_v2_x_error_t mhu_v2_x_channel_receive( + const struct mhu_v2_x_dev_t *dev, uint32_t channel, uint32_t *value) +{ + union mhu_v2_x_frame *p_mhu; + + assert(dev != NULL); + + p_mhu = (union mhu_v2_x_frame *)dev->base; + + if (!(dev->is_initialized)) { + return MHU_V_2_X_ERR_NOT_INIT; + } + + if (dev->frame == MHU_V2_X_RECEIVER_FRAME) { + *value = (RECV_FRAME(p_mhu))->rec_ch_window[channel].ch_st; + return MHU_V_2_X_ERR_NONE; + } else { + return MHU_V_2_X_ERR_INVALID_ARG; + } +} + +enum mhu_v2_x_error_t mhu_v2_x_channel_mask_set( + const struct mhu_v2_x_dev_t *dev, uint32_t channel, uint32_t mask) +{ + union mhu_v2_x_frame *p_mhu; + + assert(dev != NULL); + + p_mhu = (union mhu_v2_x_frame *)dev->base; + + if (!(dev->is_initialized)) { + return MHU_V_2_X_ERR_NOT_INIT; + } + + if (dev->frame == MHU_V2_X_RECEIVER_FRAME) { + (RECV_FRAME(p_mhu))->rec_ch_window[channel].ch_msk_set = mask; + return MHU_V_2_X_ERR_NONE; + } else { + return MHU_V_2_X_ERR_INVALID_ARG; + } +} + +enum mhu_v2_x_error_t mhu_v2_x_channel_mask_clear( + const struct mhu_v2_x_dev_t *dev, uint32_t channel, uint32_t mask) +{ + union mhu_v2_x_frame *p_mhu; + + assert(dev != NULL); + + p_mhu = (union mhu_v2_x_frame *)dev->base; + + if (!(dev->is_initialized)) { + return MHU_V_2_X_ERR_NOT_INIT; + } + + if (dev->frame == MHU_V2_X_RECEIVER_FRAME) { + (RECV_FRAME(p_mhu))->rec_ch_window[channel].ch_msk_clr = mask; + return MHU_V_2_X_ERR_NONE; + } else { + return MHU_V_2_X_ERR_INVALID_ARG; + } +} +enum mhu_v2_x_error_t mhu_v2_x_initiate_transfer( + const struct mhu_v2_x_dev_t *dev) +{ + union mhu_v2_x_frame *p_mhu; + + assert(dev != NULL); + + p_mhu = (union mhu_v2_x_frame *)dev->base; + + if (!(dev->is_initialized)) { + return MHU_V_2_X_ERR_NOT_INIT; + } + + if (dev->frame != MHU_V2_X_SENDER_FRAME) { + return MHU_V_2_X_ERR_INVALID_ARG; + } + + (SEND_FRAME(p_mhu))->access_request = ENABLE; + + while (!((SEND_FRAME(p_mhu))->access_ready)) { + /* Wait in a loop for access ready signal to be high */ + ; + } + + return MHU_V_2_X_ERR_NONE; +} + +enum mhu_v2_x_error_t mhu_v2_x_close_transfer(const struct mhu_v2_x_dev_t *dev) +{ + union mhu_v2_x_frame *p_mhu; + + assert(dev != NULL); + + p_mhu = (union mhu_v2_x_frame *)dev->base; + + if (!(dev->is_initialized)) { + return MHU_V_2_X_ERR_NOT_INIT; + } + + if (dev->frame != MHU_V2_X_SENDER_FRAME) { + return MHU_V_2_X_ERR_INVALID_ARG; + } + + (SEND_FRAME(p_mhu))->access_request = DISABLE; + + return MHU_V_2_X_ERR_NONE; +} diff --git a/drivers/arm/mhu/mhu_v2_x.h b/drivers/arm/mhu/mhu_v2_x.h new file mode 100644 index 000000000..10247d24f --- /dev/null +++ b/drivers/arm/mhu/mhu_v2_x.h @@ -0,0 +1,210 @@ +/* + * Copyright (c) 2020-2022, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef MHU_V2_X_H +#define MHU_V2_X_H + +#include +#include + +#define MHU_2_X_INTR_NR2R_OFF (0x0u) +#define MHU_2_X_INTR_R2NR_OFF (0x1u) +#define MHU_2_1_INTR_CHCOMB_OFF (0x2u) + +#define MHU_2_X_INTR_NR2R_MASK (0x1u << MHU_2_X_INTR_NR2R_OFF) +#define MHU_2_X_INTR_R2NR_MASK (0x1u << MHU_2_X_INTR_R2NR_OFF) +#define MHU_2_1_INTR_CHCOMB_MASK (0x1u << MHU_2_1_INTR_CHCOMB_OFF) + +enum mhu_v2_x_frame_t { + MHU_V2_X_SENDER_FRAME = 0x0u, + MHU_V2_X_RECEIVER_FRAME = 0x1u, +}; + +enum mhu_v2_x_supported_revisions { + MHU_REV_READ_FROM_HW = 0, + MHU_REV_2_0, + MHU_REV_2_1, +}; + +struct mhu_v2_x_dev_t { + uintptr_t base; + enum mhu_v2_x_frame_t frame; + uint32_t subversion; /*!< Hardware subversion: v2.X */ + bool is_initialized; /*!< Indicates if the MHU driver + * is initialized and enabled + */ +}; + +/** + * MHU v2 error enumeration types. + */ +enum mhu_v2_x_error_t { + MHU_V_2_X_ERR_NONE = 0, + MHU_V_2_X_ERR_NOT_INIT = -1, + MHU_V_2_X_ERR_ALREADY_INIT = -2, + MHU_V_2_X_ERR_UNSUPPORTED_VERSION = -3, + MHU_V_2_X_ERR_INVALID_ARG = -4, + MHU_V_2_X_ERR_GENERAL = -5 +}; + +/** + * Initializes the driver. + * + * dev MHU device struct mhu_v2_x_dev_t. + * rev MHU revision (if can't be identified from HW). + * + * Reads the MHU hardware version. + * + * Returns mhu_v2_x_error_t error code. + * + * MHU revision only has to be specified when versions can't be read + * from HW (ARCH_MAJOR_REV reg reads as 0x0). + * + * This function doesn't check if dev is NULL. + */ +enum mhu_v2_x_error_t mhu_v2_x_driver_init(struct mhu_v2_x_dev_t *dev, + enum mhu_v2_x_supported_revisions rev); + +/** + * Returns the number of channels implemented. + * + * dev MHU device struct mhu_v2_x_dev_t. + * + * This function doesn't check if dev is NULL. + */ +uint32_t mhu_v2_x_get_num_channel_implemented( + const struct mhu_v2_x_dev_t *dev); + +/** + * Sends the value over a channel. + * + * dev MHU device struct mhu_v2_x_dev_t. + * channel Channel to send the value over. + * val Value to send. + * + * Sends the value over a channel. + * + * Returns mhu_v2_x_error_t error code. + * + * This function doesn't check if dev is NULL. + * This function doesn't check if channel is implemented. + */ +enum mhu_v2_x_error_t mhu_v2_x_channel_send(const struct mhu_v2_x_dev_t *dev, + uint32_t channel, uint32_t val); + +/** + * Polls sender channel status. + * + * dev MHU device struct mhu_v2_x_dev_t. + * channel Channel to poll the status of. + * value Pointer to variable that will store the value. + * + * Polls sender channel status. + * + * Returns mhu_v2_x_error_t error code. + * + * This function doesn't check if dev is NULL. + * This function doesn't check if channel is implemented. + */ +enum mhu_v2_x_error_t mhu_v2_x_channel_poll(const struct mhu_v2_x_dev_t *dev, + uint32_t channel, uint32_t *value); + +/** + * Clears the channel after the value is send over it. + * + * dev MHU device struct mhu_v2_x_dev_t. + * channel Channel to clear. + * + * Clears the channel after the value is send over it. + * + * Returns mhu_v2_x_error_t error code.. + * + * This function doesn't check if dev is NULL. + * This function doesn't check if channel is implemented. + */ +enum mhu_v2_x_error_t mhu_v2_x_channel_clear(const struct mhu_v2_x_dev_t *dev, + uint32_t channel); + +/** + * Receives the value over a channel. + * + * dev MHU device struct mhu_v2_x_dev_t. + * channel Channel to receive the value from. + * value Pointer to variable that will store the value. + * + * Receives the value over a channel. + * + * Returns mhu_v2_x_error_t error code. + * + * This function doesn't check if dev is NULL. + * This function doesn't check if channel is implemented. + */ +enum mhu_v2_x_error_t mhu_v2_x_channel_receive( + const struct mhu_v2_x_dev_t *dev, uint32_t channel, uint32_t *value); + +/** + * Sets bits in the Channel Mask. + * + * dev MHU device struct mhu_v2_x_dev_t. + * channel Which channel's mask to set. + * mask Mask to be set over a receiver frame. + * + * Sets bits in the Channel Mask. + * + * Returns mhu_v2_x_error_t error code.. + * + * This function doesn't check if dev is NULL. + * This function doesn't check if channel is implemented. + */ +enum mhu_v2_x_error_t mhu_v2_x_channel_mask_set( + const struct mhu_v2_x_dev_t *dev, uint32_t channel, uint32_t mask); + +/** + * Clears bits in the Channel Mask. + * + * dev MHU device struct mhu_v2_x_dev_t. + * channel Which channel's mask to clear. + * mask Mask to be clear over a receiver frame. + * + * Clears bits in the Channel Mask. + * + * Returns mhu_v2_x_error_t error code. + * + * This function doesn't check if dev is NULL. + * This function doesn't check if channel is implemented. + */ +enum mhu_v2_x_error_t mhu_v2_x_channel_mask_clear( + const struct mhu_v2_x_dev_t *dev, uint32_t channel, uint32_t mask); + +/** + * Initiates a MHU transfer with the handshake signals. + * + * dev MHU device struct mhu_v2_x_dev_t. + * + * Initiates a MHU transfer with the handshake signals in a blocking mode. + * + * Returns mhu_v2_x_error_t error code. + * + * This function doesn't check if dev is NULL. + */ +enum mhu_v2_x_error_t mhu_v2_x_initiate_transfer( + const struct mhu_v2_x_dev_t *dev); + +/** + * Closes a MHU transfer with the handshake signals. + * + * dev MHU device struct mhu_v2_x_dev_t. + * + * Closes a MHU transfer with the handshake signals in a blocking mode. + * + * Returns mhu_v2_x_error_t error code. + * + * This function doesn't check if dev is NULL. + */ +enum mhu_v2_x_error_t mhu_v2_x_close_transfer( + const struct mhu_v2_x_dev_t *dev); + +#endif /* MHU_V2_X_H */ diff --git a/drivers/arm/mhu/mhu_wrapper_v2_x.c b/drivers/arm/mhu/mhu_wrapper_v2_x.c new file mode 100644 index 000000000..d8b7cfdab --- /dev/null +++ b/drivers/arm/mhu/mhu_wrapper_v2_x.c @@ -0,0 +1,302 @@ +/* + * Copyright (c) 2022, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include + +#include + +#include "mhu_v2_x.h" + +#define MHU_NOTIFY_VALUE (1234u) + +/* + * MHU devices for host: + * HSE: Host to Secure Enclave (sender device) + * SEH: Secure Enclave to Host (receiver device) + */ +struct mhu_v2_x_dev_t MHU1_HSE_DEV = {0, MHU_V2_X_SENDER_FRAME}; +struct mhu_v2_x_dev_t MHU1_SEH_DEV = {0, MHU_V2_X_RECEIVER_FRAME}; + +static enum mhu_error_t error_mapping_to_mhu_error_t(enum mhu_v2_x_error_t err) +{ + switch (err) { + case MHU_V_2_X_ERR_NONE: + return MHU_ERR_NONE; + case MHU_V_2_X_ERR_NOT_INIT: + return MHU_ERR_NOT_INIT; + case MHU_V_2_X_ERR_ALREADY_INIT: + return MHU_ERR_ALREADY_INIT; + case MHU_V_2_X_ERR_UNSUPPORTED_VERSION: + return MHU_ERR_UNSUPPORTED_VERSION; + case MHU_V_2_X_ERR_INVALID_ARG: + return MHU_ERR_INVALID_ARG; + case MHU_V_2_X_ERR_GENERAL: + return MHU_ERR_GENERAL; + default: + return MHU_ERR_GENERAL; + } +} + +static enum mhu_v2_x_error_t signal_and_wait_for_clear(void) +{ + enum mhu_v2_x_error_t err; + struct mhu_v2_x_dev_t *dev = &MHU1_HSE_DEV; + uint32_t val = MHU_NOTIFY_VALUE; + /* Using the last channel for notifications */ + uint32_t channel_notify = mhu_v2_x_get_num_channel_implemented(dev) - 1; + + err = mhu_v2_x_channel_send(dev, channel_notify, val); + if (err != MHU_V_2_X_ERR_NONE) { + return err; + } + + do { + err = mhu_v2_x_channel_poll(dev, channel_notify, &val); + if (err != MHU_V_2_X_ERR_NONE) { + break; + } + } while (val != 0); + + return err; +} + +static enum mhu_v2_x_error_t wait_for_signal(void) +{ + enum mhu_v2_x_error_t err; + struct mhu_v2_x_dev_t *dev = &MHU1_SEH_DEV; + uint32_t val = 0; + /* Using the last channel for notifications */ + uint32_t channel_notify = mhu_v2_x_get_num_channel_implemented(dev) - 1; + + do { + err = mhu_v2_x_channel_receive(dev, channel_notify, &val); + if (err != MHU_V_2_X_ERR_NONE) { + break; + } + } while (val != MHU_NOTIFY_VALUE); + + return err; +} + +static enum mhu_v2_x_error_t clear_and_wait_for_next_signal(void) +{ + enum mhu_v2_x_error_t err; + struct mhu_v2_x_dev_t *dev = &MHU1_SEH_DEV; + uint32_t num_channels = mhu_v2_x_get_num_channel_implemented(dev); + uint32_t i; + + /* Clear all channels */ + for (i = 0; i < num_channels; ++i) { + err = mhu_v2_x_channel_clear(dev, i); + if (err != MHU_V_2_X_ERR_NONE) { + return err; + } + } + + return wait_for_signal(); +} + +enum mhu_error_t mhu_init_sender(uintptr_t mhu_sender_base) +{ + enum mhu_v2_x_error_t err; + + assert(mhu_sender_base != (uintptr_t)NULL); + + MHU1_HSE_DEV.base = mhu_sender_base; + + err = mhu_v2_x_driver_init(&MHU1_HSE_DEV, MHU_REV_READ_FROM_HW); + return error_mapping_to_mhu_error_t(err); +} + +enum mhu_error_t mhu_init_receiver(uintptr_t mhu_receiver_base) +{ + enum mhu_v2_x_error_t err; + uint32_t num_channels, i; + + assert(mhu_receiver_base != (uintptr_t)NULL); + + MHU1_SEH_DEV.base = mhu_receiver_base; + + err = mhu_v2_x_driver_init(&MHU1_SEH_DEV, MHU_REV_READ_FROM_HW); + if (err != MHU_V_2_X_ERR_NONE) { + return error_mapping_to_mhu_error_t(err); + } + + num_channels = mhu_v2_x_get_num_channel_implemented(&MHU1_SEH_DEV); + + /* Mask all channels except the notifying channel */ + for (i = 0; i < (num_channels - 1); ++i) { + err = mhu_v2_x_channel_mask_set(&MHU1_SEH_DEV, i, UINT32_MAX); + if (err != MHU_V_2_X_ERR_NONE) { + return error_mapping_to_mhu_error_t(err); + } + } + + /* The last channel is used for notifications */ + err = mhu_v2_x_channel_mask_clear( + &MHU1_SEH_DEV, (num_channels - 1), UINT32_MAX); + return error_mapping_to_mhu_error_t(err); +} + +/* + * Public function. See mhu.h + * + * The basic steps of transferring a message: + * 1. Initiate MHU transfer. + * 2. Send over the size of the payload on Channel 1. It is the very first + * 4 Bytes of the transfer. Continue with Channel 2. + * 3. Send over the payload, writing the channels one after the other + * (4 Bytes each). The last available channel is reserved for controlling + * the transfer. + * When the last channel is reached or no more data is left, STOP. + * 4. Notify the receiver using the last channel and wait for acknowledge. + * If there is still data to transfer, jump to step 3. Otherwise, proceed. + * 5. Close MHU transfer. + * + */ +enum mhu_error_t mhu_send_data(const uint8_t *send_buffer, size_t size) +{ + enum mhu_v2_x_error_t err; + struct mhu_v2_x_dev_t *dev = &MHU1_HSE_DEV; + uint32_t num_channels = mhu_v2_x_get_num_channel_implemented(dev); + uint32_t chan = 0; + uint32_t i; + uint32_t *p; + + /* For simplicity, require the send_buffer to be 4-byte aligned */ + if ((uintptr_t)send_buffer & 0x3U) { + return MHU_ERR_INVALID_ARG; + } + + err = mhu_v2_x_initiate_transfer(dev); + if (err != MHU_V_2_X_ERR_NONE) { + return error_mapping_to_mhu_error_t(err); + } + + /* First send over the size of the actual message */ + err = mhu_v2_x_channel_send(dev, chan, (uint32_t)size); + if (err != MHU_V_2_X_ERR_NONE) { + return error_mapping_to_mhu_error_t(err); + } + chan++; + + p = (uint32_t *)send_buffer; + for (i = 0; i < size; i += 4) { + err = mhu_v2_x_channel_send(dev, chan, *p++); + if (err != MHU_V_2_X_ERR_NONE) { + return error_mapping_to_mhu_error_t(err); + } + if (++chan == (num_channels - 1)) { + err = signal_and_wait_for_clear(); + if (err != MHU_V_2_X_ERR_NONE) { + return error_mapping_to_mhu_error_t(err); + } + chan = 0; + } + } + + /* Signal the end of transfer. + * It's not required to send a signal when the message was + * perfectly-aligned (num_channels - 1 channels were used in the last + * round) preventing it from signaling twice at the end of transfer. + */ + if (chan != 0) { + err = signal_and_wait_for_clear(); + if (err != MHU_V_2_X_ERR_NONE) { + return error_mapping_to_mhu_error_t(err); + } + } + + err = mhu_v2_x_close_transfer(dev); + return error_mapping_to_mhu_error_t(err); +} + +/* + * Public function. See mhu.h + * + * The basic steps of receiving a message: + * 1. Read the size of the payload from Channel 1. It is the very first + * 4 Bytes of the transfer. Continue with Channel 2. + * 2. Receive the payload, read the channels one after the other + * (4 Bytes each). The last available channel is reserved for controlling + * the transfer. + * When the last channel is reached clear all the channels + * (also sending an acknowledge on the last channel). + * 3. If there is still data to receive wait for a notification on the last + * channel and jump to step 2 as soon as it arrived. Otherwise, proceed. + * 4. End of transfer. + * + */ +enum mhu_error_t mhu_receive_data(uint8_t *receive_buffer, size_t *size) +{ + enum mhu_v2_x_error_t err; + struct mhu_v2_x_dev_t *dev = &MHU1_SEH_DEV; + uint32_t num_channels = mhu_v2_x_get_num_channel_implemented(dev); + uint32_t chan = 0; + uint32_t message_len; + uint32_t i; + uint32_t *p; + + /* For simplicity, require: + * - the receive_buffer to be 4-byte aligned, + * - the buffer size to be a multiple of 4. + */ + if (((uintptr_t)receive_buffer & 0x3U) || (*size & 0x3U)) { + return MHU_ERR_INVALID_ARG; + } + + /* Busy wait for incoming reply */ + err = wait_for_signal(); + if (err != MHU_V_2_X_ERR_NONE) { + return error_mapping_to_mhu_error_t(err); + } + + /* The first word is the length of the actual message */ + err = mhu_v2_x_channel_receive(dev, chan, &message_len); + if (err != MHU_V_2_X_ERR_NONE) { + return error_mapping_to_mhu_error_t(err); + } + chan++; + + if (message_len > *size) { + /* Message buffer too small */ + *size = message_len; + return MHU_ERR_BUFFER_TOO_SMALL; + } + + p = (uint32_t *)receive_buffer; + for (i = 0; i < message_len; i += 4) { + err = mhu_v2_x_channel_receive(dev, chan, p++); + if (err != MHU_V_2_X_ERR_NONE) { + return error_mapping_to_mhu_error_t(err); + } + + /* Only wait for next transfer if there is still missing data */ + if (++chan == (num_channels - 1) && (message_len - i) > 4) { + /* Busy wait for next transfer */ + err = clear_and_wait_for_next_signal(); + if (err != MHU_V_2_X_ERR_NONE) { + return error_mapping_to_mhu_error_t(err); + } + chan = 0; + } + } + + /* Clear all channels */ + for (i = 0; i < num_channels; ++i) { + err = mhu_v2_x_channel_clear(dev, i); + if (err != MHU_V_2_X_ERR_NONE) { + return error_mapping_to_mhu_error_t(err); + } + } + + *size = message_len; + + return MHU_ERR_NONE; +} diff --git a/include/drivers/arm/mhu.h b/include/drivers/arm/mhu.h new file mode 100644 index 000000000..7745bd9d8 --- /dev/null +++ b/include/drivers/arm/mhu.h @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2022, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef MHU_H +#define MHU_H + +#include +#include + +/** + * Generic MHU error enumeration types. + */ +enum mhu_error_t { + MHU_ERR_NONE = 0, + MHU_ERR_NOT_INIT = -1, + MHU_ERR_ALREADY_INIT = -2, + MHU_ERR_UNSUPPORTED_VERSION = -3, + MHU_ERR_UNSUPPORTED = -4, + MHU_ERR_INVALID_ARG = -5, + MHU_ERR_BUFFER_TOO_SMALL = -6, + MHU_ERR_GENERAL = -7, +}; + +/** + * Initializes sender MHU. + * + * mhu_sender_base Base address of sender MHU. + * + * Returns mhu_error_t error code. + * + * This function must be called before mhu_send_data(). + */ +enum mhu_error_t mhu_init_sender(uintptr_t mhu_sender_base); + + +/** + * Initializes receiver MHU. + * + * mhu_receiver_base Base address of receiver MHU. + * + * Returns mhu_error_t error code. + * + * This function must be called before mhu_receive_data(). + */ +enum mhu_error_t mhu_init_receiver(uintptr_t mhu_receiver_base); + +/** + * Sends data over MHU. + * + * send_buffer Pointer to buffer containing the data to be transmitted. + * size Size of the data to be transmitted in bytes. + * + * Returns mhu_error_t error code. + * + * The send_buffer must be 4-byte aligned and its length must be at least + * (4 - (size % 4)) bytes bigger than the data size to prevent buffer + * over-reading. + */ +enum mhu_error_t mhu_send_data(const uint8_t *send_buffer, size_t size); + +/** + * Receives data from MHU. + * + * receive_buffer Pointer the buffer where to store the received data. + * size As input the size of the receive_buffer, as output the + * number of bytes received. As a limitation, + * the size of the buffer must be a multiple of 4. + * + * Returns mhu_error_t error code. + * + * The receive_buffer must be 4-byte aligned and its length must be a + * multiple of 4. + */ +enum mhu_error_t mhu_receive_data(uint8_t *receive_buffer, size_t *size); + +#endif /* MHU_H */ From 758c64715b691be92de623f81032494e38a43cc8 Mon Sep 17 00:00:00 2001 From: Tamas Ban Date: Tue, 18 Jan 2022 16:19:17 +0100 Subject: [PATCH 2/8] feat(lib/psa): add measured boot API A secure enclave could provide an alternate backend for measured boot. This API can be used to store measurements in a secure enclave, which provides the measured boot runtime service. Signed-off-by: Tamas Ban Change-Id: I2448e324e7ece6b318403c5937dfe7abea53d0f3 --- include/lib/psa/measured_boot.h | 77 +++++++++++++++++++++ include/lib/psa/psa/client.h | 102 ++++++++++++++++++++++++++++ include/lib/psa/psa/error.h | 42 ++++++++++++ include/lib/psa/psa_manifest/sid.h | 21 ++++++ lib/psa/measured_boot.c | 104 +++++++++++++++++++++++++++++ lib/psa/measured_boot_private.h | 24 +++++++ 6 files changed, 370 insertions(+) create mode 100644 include/lib/psa/measured_boot.h create mode 100644 include/lib/psa/psa/client.h create mode 100644 include/lib/psa/psa/error.h create mode 100644 include/lib/psa/psa_manifest/sid.h create mode 100644 lib/psa/measured_boot.c create mode 100644 lib/psa/measured_boot_private.h diff --git a/include/lib/psa/measured_boot.h b/include/lib/psa/measured_boot.h new file mode 100644 index 000000000..bdb79d5d6 --- /dev/null +++ b/include/lib/psa/measured_boot.h @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2022, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + */ + +#ifndef PSA_MEASURED_BOOT_H +#define PSA_MEASURED_BOOT_H + +#include +#include +#include + +#include "psa/error.h" + +/* Minimum measurement value size that can be requested to store */ +#define MEASUREMENT_VALUE_MIN_SIZE 32U +/* Maximum measurement value size that can be requested to store */ +#define MEASUREMENT_VALUE_MAX_SIZE 64U +/* Minimum signer id size that can be requested to store */ +#define SIGNER_ID_MIN_SIZE MEASUREMENT_VALUE_MIN_SIZE +/* Maximum signer id size that can be requested to store */ +#define SIGNER_ID_MAX_SIZE MEASUREMENT_VALUE_MAX_SIZE +/* The theoretical maximum image version is: "255.255.65535\0" */ +#define VERSION_MAX_SIZE 14U +/* Example sw_type: "BL_2, BL_33, etc." */ +#define SW_TYPE_MAX_SIZE 20U +#define NUM_OF_MEASUREMENT_SLOTS 32U + + +/** + * Extends and stores a measurement to the requested slot. + * + * index Slot number in which measurement is to be stored + * signer_id Pointer to signer_id buffer. + * signer_id_size Size of the signer_id buffer in bytes. + * version Pointer to version buffer. + * version_size Size of the version buffer in bytes. + * measurement_algo Algorithm identifier used for measurement. + * sw_type Pointer to sw_type buffer. + * sw_type_size Size of the sw_type buffer in bytes. + * measurement_value Pointer to measurement_value buffer. + * measurement_value_size Size of the measurement_value buffer in bytes. + * lock_measurement Boolean flag requesting whether the measurement + * is to be locked. + * + * PSA_SUCCESS: + * - Success. + * PSA_ERROR_INVALID_ARGUMENT: + * - The size of any argument is invalid OR + * - Input Measurement value is NULL OR + * - Input Signer ID is NULL OR + * - Requested slot index is invalid. + * PSA_ERROR_BAD_STATE: + * - Request to lock, when slot is already locked. + * PSA_ERROR_NOT_PERMITTED: + * - When the requested slot is not accessible to the caller. + */ + +/* Not a standard PSA API, just an extension therefore use the 'rss_' prefix + * rather than the usual 'psa_'. + */ +psa_status_t +rss_measured_boot_extend_measurement(uint8_t index, + const uint8_t *signer_id, + size_t signer_id_size, + const uint8_t *version, + size_t version_size, + uint32_t measurement_algo, + const uint8_t *sw_type, + size_t sw_type_size, + const uint8_t *measurement_value, + size_t measurement_value_size, + bool lock_measurement); + +#endif /* PSA_MEASURED_BOOT_H */ diff --git a/include/lib/psa/psa/client.h b/include/lib/psa/psa/client.h new file mode 100644 index 000000000..56fe0288f --- /dev/null +++ b/include/lib/psa/psa/client.h @@ -0,0 +1,102 @@ + +/* + * Copyright (c) 2018-2021, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + */ + +#ifndef PSA_CLIENT_H +#define PSA_CLIENT_H + +#include +#include + +#include + +#ifndef IOVEC_LEN +#define IOVEC_LEN(arr) ((uint32_t)(sizeof(arr)/sizeof(arr[0]))) +#endif +/*********************** PSA Client Macros and Types *************************/ +/** + * The version of the PSA Framework API that is being used to build the calling + * firmware. Only part of features of FF-M v1.1 have been implemented. FF-M v1.1 + * is compatible with v1.0. + */ +#define PSA_FRAMEWORK_VERSION (0x0101u) +/** + * Return value from psa_version() if the requested RoT Service is not present + * in the system. + */ +#define PSA_VERSION_NONE (0u) +/** + * The zero-value null handle can be assigned to variables used in clients and + * RoT Services, indicating that there is no current connection or message. + */ +#define PSA_NULL_HANDLE ((psa_handle_t)0) +/** + * Tests whether a handle value returned by psa_connect() is valid. + */ +#define PSA_HANDLE_IS_VALID(handle) ((psa_handle_t)(handle) > 0) +/** + * Converts the handle value returned from a failed call psa_connect() into + * an error code. + */ +#define PSA_HANDLE_TO_ERROR(handle) ((psa_status_t)(handle)) +/** + * Maximum number of input and output vectors for a request to psa_call(). + */ +#define PSA_MAX_IOVEC (4u) +/** + * An IPC message type that indicates a generic client request. + */ +#define PSA_IPC_CALL (0) +typedef int32_t psa_handle_t; +/** + * A read-only input memory region provided to an RoT Service. + */ +typedef struct psa_invec { + const void *base; /*!< the start address of the memory buffer */ + size_t len; /*!< the size in bytes */ +} psa_invec; +/** + * A writable output memory region provided to an RoT Service. + */ +typedef struct psa_outvec { + void *base; /*!< the start address of the memory buffer */ + size_t len; /*!< the size in bytes */ +} psa_outvec; + +/** + * Call an RoT Service on an established connection. + * + * handle A handle to an established connection. + * type The request type. Must be zero(PSA_IPC_CALL) or positive. + * in_vec Array of input psa_invec structures. + * in_len Number of input psa_invec structures. + * out_vec Array of output psa_outvec structures. + * out_len Number of output psa_outvec structures. + * + * Return value >=0 RoT Service-specific status value. + * Return value <0 RoT Service-specific error code. + * + * PSA_ERROR_PROGRAMMER_ERROR: + * - The connection has been terminated by the RoT Service. + * + * The call is a PROGRAMMER ERROR if one or more of the following are true: + * - An invalid handle was passed. + * - The connection is already handling a request. + * - type < 0. + * - An invalid memory reference was provided. + * - in_len + out_len > PSA_MAX_IOVEC. + * - The message is unrecognized by the RoT. + * - Service or incorrectly formatted. + */ +psa_status_t psa_call(psa_handle_t handle, + int32_t type, + const psa_invec *in_vec, + size_t in_len, + psa_outvec *out_vec, + size_t out_len); + +#endif /* PSA_CLIENT_H */ diff --git a/include/lib/psa/psa/error.h b/include/lib/psa/psa/error.h new file mode 100644 index 000000000..8a6eb7be7 --- /dev/null +++ b/include/lib/psa/psa/error.h @@ -0,0 +1,42 @@ + +/* + * Copyright (c) 2019-2021, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + */ + +#ifndef PSA_ERROR_H +#define PSA_ERROR_H + +#include + +typedef int32_t psa_status_t; + +#define PSA_SUCCESS ((psa_status_t)0) +#define PSA_SUCCESS_REBOOT ((psa_status_t)1) +#define PSA_SUCCESS_RESTART ((psa_status_t)2) +#define PSA_ERROR_PROGRAMMER_ERROR ((psa_status_t)-129) +#define PSA_ERROR_CONNECTION_REFUSED ((psa_status_t)-130) +#define PSA_ERROR_CONNECTION_BUSY ((psa_status_t)-131) +#define PSA_ERROR_GENERIC_ERROR ((psa_status_t)-132) +#define PSA_ERROR_NOT_PERMITTED ((psa_status_t)-133) +#define PSA_ERROR_NOT_SUPPORTED ((psa_status_t)-134) +#define PSA_ERROR_INVALID_ARGUMENT ((psa_status_t)-135) +#define PSA_ERROR_INVALID_HANDLE ((psa_status_t)-136) +#define PSA_ERROR_BAD_STATE ((psa_status_t)-137) +#define PSA_ERROR_BUFFER_TOO_SMALL ((psa_status_t)-138) +#define PSA_ERROR_ALREADY_EXISTS ((psa_status_t)-139) +#define PSA_ERROR_DOES_NOT_EXIST ((psa_status_t)-140) +#define PSA_ERROR_INSUFFICIENT_MEMORY ((psa_status_t)-141) +#define PSA_ERROR_INSUFFICIENT_STORAGE ((psa_status_t)-142) +#define PSA_ERROR_INSUFFICIENT_DATA ((psa_status_t)-143) +#define PSA_ERROR_SERVICE_FAILURE ((psa_status_t)-144) +#define PSA_ERROR_COMMUNICATION_FAILURE ((psa_status_t)-145) +#define PSA_ERROR_STORAGE_FAILURE ((psa_status_t)-146) +#define PSA_ERROR_HARDWARE_FAILURE ((psa_status_t)-147) +#define PSA_ERROR_INVALID_SIGNATURE ((psa_status_t)-149) +#define PSA_ERROR_DEPENDENCY_NEEDED ((psa_status_t)-156) +#define PSA_ERROR_CURRENTLY_INSTALLING ((psa_status_t)-157) + +#endif /* PSA_ERROR_H */ diff --git a/include/lib/psa/psa_manifest/sid.h b/include/lib/psa/psa_manifest/sid.h new file mode 100644 index 000000000..947e58f09 --- /dev/null +++ b/include/lib/psa/psa_manifest/sid.h @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2019-2022, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + */ + +#ifndef PSA_MANIFEST_SID_H +#define PSA_MANIFEST_SID_H + +/******** PSA_SP_INITIAL_ATTESTATION ********/ +#define RSS_ATTESTATION_SERVICE_SID (0x00000020U) +#define RSS_ATTESTATION_SERVICE_VERSION (1U) +#define RSS_ATTESTATION_SERVICE_HANDLE (0x40000103U) + +/******** PSA_SP_MEASURED_BOOT ********/ +#define RSS_MEASURED_BOOT_SID (0x000000E0U) +#define RSS_MEASURED_BOOT_VERSION (1U) +#define RSS_MEASURED_BOOT_HANDLE (0x40000104U) + +#endif /* PSA_MANIFEST_SID_H */ diff --git a/lib/psa/measured_boot.c b/lib/psa/measured_boot.c new file mode 100644 index 000000000..f4216ebf1 --- /dev/null +++ b/lib/psa/measured_boot.c @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2022, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + */ + +#include + +#include +#include +#include +#include + +#include "measured_boot_private.h" + +static void print_byte_array(const uint8_t *array, size_t len) +{ + unsigned int i; + + if (array == NULL || len == 0U) { + (void)printf("\n"); + } + + for (i = 0U; i < len; ++i) { + (void)printf(" %02x", array[i]); + if ((i & U(0xF)) == U(0xF)) { + (void)printf("\n"); + if (i < (len - 1U)) { + INFO("\t\t:"); + } + } + } +} + +static void log_measurement(uint8_t index, + const uint8_t *signer_id, + size_t signer_id_size, + const uint8_t *version, /* string */ + uint32_t measurement_algo, + const uint8_t *sw_type, /* string */ + const uint8_t *measurement_value, + size_t measurement_value_size, + bool lock_measurement) +{ + INFO("Measured boot extend measurement:\n"); + INFO(" - slot : %u\n", index); + INFO(" - signer_id :"); + print_byte_array(signer_id, signer_id_size); + INFO(" - version : %s\n", version); + INFO(" - algorithm : %x\n", measurement_algo); + INFO(" - sw_type : %s\n", sw_type); + INFO(" - measurement :"); + print_byte_array(measurement_value, measurement_value_size); + INFO(" - locking : %s\n", lock_measurement ? "true" : "false"); +} + +psa_status_t +rss_measured_boot_extend_measurement(uint8_t index, + const uint8_t *signer_id, + size_t signer_id_size, + const uint8_t *version, + size_t version_size, + uint32_t measurement_algo, + const uint8_t *sw_type, + size_t sw_type_size, + const uint8_t *measurement_value, + size_t measurement_value_size, + bool lock_measurement) +{ + struct measured_boot_extend_iovec_t extend_iov = { + .index = index, + .lock_measurement = lock_measurement, + .measurement_algo = measurement_algo, + .sw_type = {0}, + .sw_type_size = sw_type_size, + }; + + psa_invec in_vec[] = { + {.base = &extend_iov, + .len = sizeof(struct measured_boot_extend_iovec_t)}, + {.base = signer_id, .len = signer_id_size}, + {.base = version, .len = version_size}, + {.base = measurement_value, .len = measurement_value_size} + }; + + uint32_t sw_type_size_limited; + + if (sw_type != NULL) { + sw_type_size_limited = (sw_type_size < SW_TYPE_MAX_SIZE) ? + sw_type_size : SW_TYPE_MAX_SIZE; + memcpy(extend_iov.sw_type, sw_type, sw_type_size_limited); + } + + log_measurement(index, signer_id, signer_id_size, + version, measurement_algo, sw_type, + measurement_value, measurement_value_size, + lock_measurement); + + return psa_call(RSS_MEASURED_BOOT_HANDLE, + RSS_MEASURED_BOOT_EXTEND, + in_vec, IOVEC_LEN(in_vec), + NULL, 0); +} diff --git a/lib/psa/measured_boot_private.h b/lib/psa/measured_boot_private.h new file mode 100644 index 000000000..649c3f6a4 --- /dev/null +++ b/lib/psa/measured_boot_private.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2022, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + */ + +#ifndef PSA_MEASURED_BOOT_PRIVATE_H +#define PSA_MEASURED_BOOT_PRIVATE_H + +#include + +/* Measured boot message types that distinguish its services */ +#define RSS_MEASURED_BOOT_EXTEND 1002U + +struct measured_boot_extend_iovec_t { + uint8_t index; + uint8_t lock_measurement; + uint32_t measurement_algo; + uint8_t sw_type[SW_TYPE_MAX_SIZE]; + uint8_t sw_type_size; +}; + +#endif /* PSA_MEASURED_BOOT_PRIVATE_H */ From 084856513d6730a50a3d65ac9c3bdae465117c40 Mon Sep 17 00:00:00 2001 From: Tamas Ban Date: Fri, 11 Feb 2022 15:24:05 +0100 Subject: [PATCH 3/8] feat(lib/psa): add initial attestation API Supports: - Get Platform Attestation token from secure enclave Signed-off-by: Tamas Ban Change-Id: Icaeb7b4eaff08e10f449fbf752068de3ac7974bf --- include/lib/psa/initial_attestation.h | 54 +++++++++++++++++++++++++++ lib/psa/initial_attestation.c | 36 ++++++++++++++++++ 2 files changed, 90 insertions(+) create mode 100644 include/lib/psa/initial_attestation.h create mode 100644 lib/psa/initial_attestation.c diff --git a/include/lib/psa/initial_attestation.h b/include/lib/psa/initial_attestation.h new file mode 100644 index 000000000..93169f018 --- /dev/null +++ b/include/lib/psa/initial_attestation.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2018-2022, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + */ + +#ifndef PSA_INITIAL_ATTESTATION_H +#define PSA_INITIAL_ATTESTATION_H + +#include +#include +#include + +#include "psa/error.h" + +/* + * Initial attestation API version is: 1.0.0 + */ +#define PSA_INITIAL_ATTEST_API_VERSION_MAJOR (1) +#define PSA_INITIAL_ATTEST_API_VERSION_MINOR (0) + +/* The allowed size of input challenge in bytes. */ +#define PSA_INITIAL_ATTEST_CHALLENGE_SIZE_32 32U +#define PSA_INITIAL_ATTEST_CHALLENGE_SIZE_48 48U +#define PSA_INITIAL_ATTEST_CHALLENGE_SIZE_64 64U + +/* Initial Attestation message types that distinguish Attest services. */ +#define RSS_ATTEST_GET_TOKEN 1001U +#define RSS_ATTEST_GET_TOKEN_SIZE 1002U +#define RSS_ATTEST_GET_DELEGATED_KEY 1003U + +/** + * Get the platform attestation token. + * + * auth_challenge Pointer to buffer where challenge input is stored. This + * must be the hash of the public part of the delegated + * attestation key. + * challenge_size Size of challenge object in bytes. + * token_buf Pointer to the buffer where attestation token will be + * stored. + * token_buf_size Size of allocated buffer for token, in bytes. + * token_size Size of the token that has been returned, in bytes. + * + * Returns error code as specified in psa_status_t. + */ +psa_status_t +psa_initial_attest_get_token(const uint8_t *auth_challenge, + size_t challenge_size, + uint8_t *token_buf, + size_t token_buf_size, + size_t *token_size); + +#endif /* PSA_INITIAL_ATTESTATION_H */ diff --git a/lib/psa/initial_attestation.c b/lib/psa/initial_attestation.c new file mode 100644 index 000000000..aa0bba0cc --- /dev/null +++ b/lib/psa/initial_attestation.c @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2018-2022, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + */ + +#include +#include +#include + +psa_status_t +psa_initial_attest_get_token(const uint8_t *auth_challenge, + size_t challenge_size, + uint8_t *token_buf, + size_t token_buf_size, + size_t *token_size) +{ + psa_status_t status; + psa_invec in_vec[] = { + {auth_challenge, challenge_size} + }; + psa_outvec out_vec[] = { + {token_buf, token_buf_size}, + }; + + status = psa_call(RSS_ATTESTATION_SERVICE_HANDLE, RSS_ATTEST_GET_TOKEN, + in_vec, IOVEC_LEN(in_vec), + out_vec, IOVEC_LEN(out_vec)); + + if (status == PSA_SUCCESS) { + *token_size = out_vec[0].len; + } + + return status; +} From ce0c40edc93aa403cdd2eb6c630ad23e28b01c3e Mon Sep 17 00:00:00 2001 From: Tamas Ban Date: Tue, 18 Jan 2022 16:32:18 +0100 Subject: [PATCH 4/8] feat(drivers/arm/rss): add RSS communication driver This commit adds a driver to conduct the AP's communication with the Runtime Security Subsystem (RSS). RSS is Arm's reference implementation for the CCA HES [1]. It can be considered as a secure enclave to which, for example, certain services can be offloaded such as initial attestation. RSS comms driver: - Relies on MHU v2.x communication IP, using a generic MHU API, - Exposes the psa_call(..) API to the upper layers. [1] https://developer.arm.com/documentation/DEN0096/latest Signed-off-by: Tamas Ban Signed-off-by: David Vincze Change-Id: Ib174ac7d1858834006bbaf8aad0eb31e3a3ad107 --- drivers/arm/rss/rss_comms.c | 225 ++++++++++++++++++++++++++++++++ include/drivers/arm/rss_comms.h | 15 +++ 2 files changed, 240 insertions(+) create mode 100644 drivers/arm/rss/rss_comms.c create mode 100644 include/drivers/arm/rss_comms.h diff --git a/drivers/arm/rss/rss_comms.c b/drivers/arm/rss/rss_comms.c new file mode 100644 index 000000000..28a492567 --- /dev/null +++ b/drivers/arm/rss/rss_comms.c @@ -0,0 +1,225 @@ +/* + * Copyright (c) 2022, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +#include +#include +#include +#include +#include + +#include + +#define TYPE_OFFSET U(16) +#define TYPE_MASK (0xFFFFUL << TYPE_OFFSET) +#define IN_LEN_OFFSET U(8) +#define IN_LEN_MASK (0xFFUL << IN_LEN_OFFSET) +#define OUT_LEN_OFFSET U(0) +#define OUT_LEN_MASK (0xFFUL << OUT_LEN_OFFSET) + +#define PARAM_PACK(type, in_len, out_len) \ + (((((uint32_t)type) << TYPE_OFFSET) & TYPE_MASK) | \ + ((((uint32_t)in_len) << IN_LEN_OFFSET) & IN_LEN_MASK) | \ + ((((uint32_t)out_len) << OUT_LEN_OFFSET) & OUT_LEN_MASK)) + +#define PARAM_UNPACK_IN_LEN(ctrl_param) \ + ((size_t)(((ctrl_param) & IN_LEN_MASK) >> IN_LEN_OFFSET)) + +/* Message types */ +struct __packed packed_psa_call_t { + uint8_t protocol_ver; + uint8_t seq_num; + uint16_t client_id; + psa_handle_t handle; + uint32_t ctrl_param; /* type, in_len, out_len */ + uint16_t io_size[4]; +}; + +struct __packed packed_psa_reply_t { + uint8_t protocol_ver; + uint8_t seq_num; + uint16_t client_id; + int32_t return_val; + uint16_t out_size[4]; +}; + +/* + * In the current implementation the RoT Service request that requires the + * biggest message buffer is the RSS_ATTEST_GET_TOKEN. The maximum required + * buffer size is calculated based on the platform-specific needs of + * this request. + */ +#define MAX_REQUEST_PAYLOAD_SIZE (PSA_INITIAL_ATTEST_CHALLENGE_SIZE_64 \ + + PLAT_ATTEST_TOKEN_MAX_SIZE) + +/* Buffer to store the messages to be sent/received. */ +static uint8_t message_buf[MAX_REQUEST_PAYLOAD_SIZE] __aligned(4); + +static int32_t pack_params(const psa_invec *invecs, + size_t in_len, + uint8_t *buf, + size_t *buf_len) +{ + uint32_t i; + size_t payload_size = 0U; + + for (i = 0U; i < in_len; ++i) { + if (invecs[i].len > *buf_len - payload_size) { + return -1; + } + memcpy(buf + payload_size, invecs[i].base, invecs[i].len); + payload_size += invecs[i].len; + } + + *buf_len = payload_size; + return 0; +} + +static int serialise_message(const struct packed_psa_call_t *msg, + const psa_invec *invecs, + uint8_t *payload_buf, + size_t *payload_len) +{ + size_t message_len = 0U; + size_t len; + + /* Copy the message header into the payload buffer. */ + len = sizeof(*msg); + if (len > *payload_len) { + ERROR("[RSS-COMMS] Message buffer too small.\n"); + return -1; + } + memcpy(payload_buf, (const void *)msg, len); + message_len += len; + + /* The input data will follow the message header in the payload buffer. */ + len = *payload_len - message_len; + if (pack_params(invecs, PARAM_UNPACK_IN_LEN(msg->ctrl_param), + payload_buf + message_len, &len) != 0) { + ERROR("[RSS-COMMS] Message buffer too small.\n"); + return -1; + } + message_len += len; + + *payload_len = message_len; + return 0; +} + +static void unpack_params(const uint8_t *buf, + psa_outvec *outvecs, + size_t out_len) +{ + size_t i; + + for (i = 0U; i < out_len; ++i) { + memcpy(outvecs[i].base, buf, outvecs[i].len); + buf += outvecs[i].len; + } +} + +static void deserialise_reply(struct packed_psa_reply_t *reply, + psa_outvec *outvecs, + size_t outlen, + const uint8_t *message, + size_t message_len) +{ + uint32_t i; + + memcpy(reply, message, sizeof(*reply)); + + /* Outvecs */ + for (i = 0U; i < outlen; ++i) { + outvecs[i].len = reply->out_size[i]; + } + + unpack_params(message + sizeof(*reply), outvecs, outlen); +} + +psa_status_t psa_call(psa_handle_t handle, int32_t type, + const psa_invec *in_vec, size_t in_len, + psa_outvec *out_vec, size_t out_len) +{ + enum mhu_error_t err; + static uint32_t seq_num = 1U; + struct packed_psa_call_t msg = { + .protocol_ver = 0U, + .seq_num = seq_num, + /* No need to distinguish callers (currently concurrent calls are not supported). */ + .client_id = 1U, + .handle = handle, + .ctrl_param = PARAM_PACK(type, in_len, out_len), + }; + + struct packed_psa_reply_t reply = {0}; + size_t message_size; + uint32_t i; + + /* Fill msg iovec lengths */ + for (i = 0U; i < in_len; ++i) { + msg.io_size[i] = in_vec[i].len; + } + for (i = 0U; i < out_len; ++i) { + msg.io_size[in_len + i] = out_vec[i].len; + } + + message_size = sizeof(message_buf); + if (serialise_message(&msg, in_vec, message_buf, &message_size)) { + /* Local buffer is probably too small. */ + return PSA_ERROR_INSUFFICIENT_MEMORY; + } + + err = mhu_send_data(message_buf, message_size); + if (err != MHU_ERR_NONE) { + return PSA_ERROR_COMMUNICATION_FAILURE; + } + + message_size = sizeof(message_buf); +#if DEBUG + /* + * Poisoning the message buffer (with a known pattern). + * Helps in detecting hypothetical RSS communication bugs. + */ + memset(message_buf, 0xA5, message_size); +#endif + err = mhu_receive_data(message_buf, &message_size); + if (err != MHU_ERR_NONE) { + return PSA_ERROR_COMMUNICATION_FAILURE; + } + + deserialise_reply(&reply, out_vec, out_len, message_buf, message_size); + + seq_num++; + + VERBOSE("[RSS-COMMS] Received reply\n"); + VERBOSE("protocol_ver=%d\n", reply.protocol_ver); + VERBOSE("seq_num=%d\n", reply.seq_num); + VERBOSE("client_id=%d\n", reply.client_id); + VERBOSE("return_val=%d\n", reply.return_val); + VERBOSE("out_size[0]=%d\n", reply.out_size[0]); + + return reply.return_val; +} + +int rss_comms_init(uintptr_t mhu_sender_base, uintptr_t mhu_receiver_base) +{ + enum mhu_error_t err; + + err = mhu_init_sender(mhu_sender_base); + if (err != MHU_ERR_NONE) { + ERROR("[RSS-COMMS] Host to RSS MHU driver initialization failed: %d\n", err); + return -1; + } + + err = mhu_init_receiver(mhu_receiver_base); + if (err != MHU_ERR_NONE) { + ERROR("[RSS-COMMS] RSS to Host MHU driver initialization failed: %d\n", err); + return -1; + } + + return 0; +} diff --git a/include/drivers/arm/rss_comms.h b/include/drivers/arm/rss_comms.h new file mode 100644 index 000000000..b96c79f7c --- /dev/null +++ b/include/drivers/arm/rss_comms.h @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2022, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + */ + +#ifndef RSS_COMMS_H +#define RSS_COMMS_H + +#include + +int rss_comms_init(uintptr_t mhu_sender_base, uintptr_t mhu_receiver_base); + +#endif /* RSS_COMMS_H */ From 0442ebd2e9bcf5fa4344d8fa8ef4b69a3b249e33 Mon Sep 17 00:00:00 2001 From: Tamas Ban Date: Tue, 11 Jan 2022 20:24:24 +0100 Subject: [PATCH 5/8] feat(drivers/measured_boot): add RSS backend Runtime Security Subsystem (RSS) provides for the host: - Runtime service to store measurments, which were computed by the host during measured boot. Signed-off-by: Tamas Ban Change-Id: Ia9e4e8a1fe8f01a28da1fd8c434b780f2a08f94e --- drivers/measured_boot/rss/rss_measured_boot.c | 125 ++++++++++++++++++ .../measured_boot/rss/rss_measured_boot.mk | 35 +++++ .../measured_boot/rss/rss_measured_boot.h | 53 ++++++++ 3 files changed, 213 insertions(+) create mode 100644 drivers/measured_boot/rss/rss_measured_boot.c create mode 100644 drivers/measured_boot/rss/rss_measured_boot.mk create mode 100644 include/drivers/measured_boot/rss/rss_measured_boot.h diff --git a/drivers/measured_boot/rss/rss_measured_boot.c b/drivers/measured_boot/rss/rss_measured_boot.c new file mode 100644 index 000000000..fe2baf055 --- /dev/null +++ b/drivers/measured_boot/rss/rss_measured_boot.c @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2022, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#define MBOOT_ALG_SHA512 0 +#define MBOOT_ALG_SHA384 1 +#define MBOOT_ALG_SHA256 2 + +#if MBOOT_ALG_ID == MBOOT_ALG_SHA512 +#define CRYPTO_MD_ID CRYPTO_MD_SHA512 +#define PSA_CRYPTO_MD_ID PSA_ALG_SHA_512 +#elif MBOOT_ALG_ID == MBOOT_ALG_SHA384 +#define CRYPTO_MD_ID CRYPTO_MD_SHA384 +#define PSA_CRYPTO_MD_ID PSA_ALG_SHA_384 +#elif MBOOT_ALG_ID == MBOOT_ALG_SHA256 +#define CRYPTO_MD_ID CRYPTO_MD_SHA256 +#define PSA_CRYPTO_MD_ID PSA_ALG_SHA_256 +#else +# error Invalid Measured Boot algorithm. +#endif /* MBOOT_ALG_ID */ + +/* Pointer to struct rss_mboot_metadata */ +static struct rss_mboot_metadata *plat_metadata_ptr; + +/* Functions' declarations */ +void rss_measured_boot_init(void) +{ + /* At this point it is expected that communication channel over MHU + * is already initialised by platform init. + */ + + /* Get pointer to platform's struct rss_mboot_metadata structure */ + plat_metadata_ptr = plat_rss_mboot_get_metadata(); + assert(plat_metadata_ptr != NULL); +} + +int rss_mboot_measure_and_record(uintptr_t data_base, uint32_t data_size, + uint32_t data_id) +{ + unsigned char hash_data[CRYPTO_MD_MAX_SIZE]; + int rc; + psa_status_t ret; + const struct rss_mboot_metadata *metadata_ptr = plat_metadata_ptr; + + /* Get the metadata associated with this image. */ + while ((metadata_ptr->id != RSS_MBOOT_INVALID_ID) && + (metadata_ptr->id != data_id)) { + metadata_ptr++; + } + + /* If image is not present in metadata array then skip */ + if (metadata_ptr->id == RSS_MBOOT_INVALID_ID) { + return 0; + } + + /* Calculate hash */ + rc = crypto_mod_calc_hash(CRYPTO_MD_ID, + (void *)data_base, data_size, hash_data); + if (rc != 0) { + return rc; + } + + ret = rss_measured_boot_extend_measurement( + metadata_ptr->slot, + metadata_ptr->signer_id, + metadata_ptr->signer_id_size, + metadata_ptr->version, + metadata_ptr->version_size, + PSA_CRYPTO_MD_ID, + metadata_ptr->sw_type, + metadata_ptr->sw_type_size, + hash_data, + MBOOT_DIGEST_SIZE, + metadata_ptr->lock_measurement); + if (ret != PSA_SUCCESS) { + return ret; + } + + return 0; +} + +int rss_mboot_set_signer_id(unsigned int img_id, + const void *pk_ptr, + size_t pk_len) +{ + unsigned char hash_data[CRYPTO_MD_MAX_SIZE]; + struct rss_mboot_metadata *metadata_ptr = plat_metadata_ptr; + int rc; + + /* Get the metadata associated with this image. */ + while ((metadata_ptr->id != RSS_MBOOT_INVALID_ID) && + (metadata_ptr->id != img_id)) { + metadata_ptr++; + } + + /* If image is not present in metadata array then skip */ + if (metadata_ptr->id == RSS_MBOOT_INVALID_ID) { + return 0; + } + + /* Calculate public key hash */ + rc = crypto_mod_calc_hash(CRYPTO_MD_ID, (void *)pk_ptr, + pk_len, hash_data); + if (rc != 0) { + return rc; + } + + /* Update metadata struct with the received signer_id */ + (void)memcpy(metadata_ptr->signer_id, hash_data, MBOOT_DIGEST_SIZE); + metadata_ptr->signer_id_size = MBOOT_DIGEST_SIZE; + + return 0; +} diff --git a/drivers/measured_boot/rss/rss_measured_boot.mk b/drivers/measured_boot/rss/rss_measured_boot.mk new file mode 100644 index 000000000..01545afeb --- /dev/null +++ b/drivers/measured_boot/rss/rss_measured_boot.mk @@ -0,0 +1,35 @@ +# +# Copyright (c) 2022, Arm Limited. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +# Hash algorithm for measured boot +# SHA-256 (or stronger) is required. +# TODO: The measurement algorithm incorrectly suggests that the TPM backend +# is used which may not be the case. It is currently being worked on and +# soon TPM_HASH_ALG will be replaced by a more generic name. +TPM_HASH_ALG := sha256 + +ifeq (${TPM_HASH_ALG}, sha512) + MBOOT_ALG_ID := MBOOT_ALG_SHA512 + MBOOT_DIGEST_SIZE := 64U +else ifeq (${TPM_HASH_ALG}, sha384) + MBOOT_ALG_ID := MBOOT_ALG_SHA384 + MBOOT_DIGEST_SIZE := 48U +else + MBOOT_ALG_ID := MBOOT_ALG_SHA256 + MBOOT_DIGEST_SIZE := 32U +endif #TPM_HASH_ALG + +# Set definitions for Measured Boot driver. +$(eval $(call add_defines,\ + $(sort \ + MBOOT_ALG_ID \ + MBOOT_DIGEST_SIZE \ + MBOOT_RSS_BACKEND \ +))) + +MEASURED_BOOT_SRC_DIR := drivers/measured_boot/rss/ + +MEASURED_BOOT_SOURCES += ${MEASURED_BOOT_SRC_DIR}rss_measured_boot.c diff --git a/include/drivers/measured_boot/rss/rss_measured_boot.h b/include/drivers/measured_boot/rss/rss_measured_boot.h new file mode 100644 index 000000000..b8cf8dae9 --- /dev/null +++ b/include/drivers/measured_boot/rss/rss_measured_boot.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2022, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef RSS_MEASURED_BOOT_H +#define RSS_MEASURED_BOOT_H + +#include + +#include +#include + +#define RSS_MBOOT_INVALID_ID UINT32_MAX + +/* + * Each boot measurement has some metadata (i.e. a string) that identifies + * what was measured and how. The sw_type field of the rss_mboot_metadata + * structure represents the role of the software component that was measured. + * The below macros define strings suitable for the sw_type. + * The key thing is to choose meaningful strings so that when the attestation + * token is verified, then the different components can be identified. + */ +#define RSS_MBOOT_BL2_STRING "BL_2" +#define RSS_MBOOT_BL31_STRING "SECURE_RT_EL3" +#define RSS_MBOOT_FW_CONFIG_STRING "FW_CONFIG" +#define RSS_MBOOT_TB_FW_CONFIG_STRING "TB_FW_CONFIG" +#define RSS_MBOOT_RMM_STRING "RMM" + + +struct rss_mboot_metadata { + unsigned int id; + uint8_t slot; + uint8_t signer_id[SIGNER_ID_MAX_SIZE]; + size_t signer_id_size; + uint8_t version[VERSION_MAX_SIZE]; + size_t version_size; + uint8_t sw_type[SW_TYPE_MAX_SIZE]; + size_t sw_type_size; + bool lock_measurement; +}; + +/* Functions' declarations */ +void rss_measured_boot_init(void); +struct rss_mboot_metadata *plat_rss_mboot_get_metadata(void); +int rss_mboot_measure_and_record(uintptr_t data_base, uint32_t data_size, + uint32_t data_id); + +/* TODO: These metadata are currently not available during TF-A boot */ +int rss_mboot_set_signer_id(unsigned int img_id, const void *pk_ptr, size_t pk_len); + +#endif /* RSS_MEASURED_BOOT_H */ From 0ce2072d9b9f419bb19595454395a33a5857ca2f Mon Sep 17 00:00:00 2001 From: Tamas Ban Date: Tue, 18 Jan 2022 16:20:47 +0100 Subject: [PATCH 6/8] feat(lib/psa): mock PSA APIs Introduce PLAT_RSS_NOT_SUPPORTED build config to provide a mocked version of PSA APIs. The goal is to test the RSS backend based measured boot and attestation token request integration on such a platform (AEM FVP) where RSS is otherwise unsupported. The mocked PSA API version does not send a request to the RSS, it only returns with success and hard-coded values. Signed-off-by: Tamas Ban Change-Id: Ice8d174adf828c1df08fc589f0e17abd1e382a4d --- Makefile | 2 + docs/getting_started/build-options.rst | 5 + lib/psa/initial_attestation.c | 127 +++++++++++++++++++++++++ lib/psa/measured_boot.c | 25 +++++ make_helpers/defaults.mk | 3 + 5 files changed, 162 insertions(+) diff --git a/Makefile b/Makefile index 16c85bcd2..b42bdc537 100644 --- a/Makefile +++ b/Makefile @@ -1011,6 +1011,7 @@ $(eval $(call assert_booleans,\ NS_TIMER_SWITCH \ OVERRIDE_LIBC \ PL011_GENERIC_UART \ + PLAT_RSS_NOT_SUPPORTED \ PROGRAMMABLE_RESET_ADDRESS \ PSCI_EXTENDED_STATE_ID \ RESET_TO_BL31 \ @@ -1146,6 +1147,7 @@ $(eval $(call add_defines,\ NS_TIMER_SWITCH \ PL011_GENERIC_UART \ PLAT_${PLAT} \ + PLAT_RSS_NOT_SUPPORTED \ PROGRAMMABLE_RESET_ADDRESS \ PSCI_EXTENDED_STATE_ID \ RAS_EXTENSION \ diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst index d2cda4dcc..742b6b589 100644 --- a/docs/getting_started/build-options.rst +++ b/docs/getting_started/build-options.rst @@ -994,6 +994,11 @@ Common build options if FEAT_TRF is implemented. This flag can take the values 0 to 2, to align with the ``FEATURE_DETECTION`` mechanism. This flag is disabled by default. +- ``PLAT_RSS_NOT_SUPPORTED``: Boolean option to enable the usage of the PSA + APIs on platforms that doesn't support RSS (providing Arm CCA HES + functionalities). When enabled (``1``), a mocked version of the APIs are used. + The default value is 0. + GICv3 driver options -------------------- diff --git a/lib/psa/initial_attestation.c b/lib/psa/initial_attestation.c index aa0bba0cc..44498a857 100644 --- a/lib/psa/initial_attestation.c +++ b/lib/psa/initial_attestation.c @@ -9,6 +9,7 @@ #include #include +#if !PLAT_RSS_NOT_SUPPORTED psa_status_t psa_initial_attest_get_token(const uint8_t *auth_challenge, size_t challenge_size, @@ -34,3 +35,129 @@ psa_initial_attest_get_token(const uint8_t *auth_challenge, return status; } + +#else /* !PLAT_RSS_NOT_SUPPORTED */ + +#include + +static const uint8_t platform_token[] = { + 0xD2, 0x84, 0x43, 0xA1, 0x01, 0x26, 0xA0, 0x59, + 0x02, 0xBE, 0xAA, 0x3A, 0x00, 0x01, 0x24, 0xFF, + 0x58, 0x20, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB, + 0xAB, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB, + 0xAB, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB, + 0xAB, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB, + 0xAB, 0xAB, 0x3A, 0x00, 0x01, 0x24, 0xFB, 0x58, + 0x20, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, + 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, + 0xAF, 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, + 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, + 0xBF, 0x3A, 0x00, 0x01, 0x25, 0x00, 0x58, 0x21, + 0x01, 0xFA, 0x58, 0x75, 0x5F, 0x65, 0x86, 0x27, + 0xCE, 0x54, 0x60, 0xF2, 0x9B, 0x75, 0x29, 0x67, + 0x13, 0x24, 0x8C, 0xAE, 0x7A, 0xD9, 0xE2, 0x98, + 0x4B, 0x90, 0x28, 0x0E, 0xFC, 0xBC, 0xB5, 0x02, + 0x48, 0x3A, 0x00, 0x01, 0x24, 0xFA, 0x58, 0x20, + 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, + 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, + 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, + 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, + 0x3A, 0x00, 0x01, 0x24, 0xF8, 0x20, 0x3A, 0x00, + 0x01, 0x24, 0xF9, 0x00, 0x3A, 0x00, 0x01, 0x24, + 0xFD, 0x85, 0xA5, 0x05, 0x58, 0x20, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x60, + 0x01, 0x65, 0x42, 0x4C, 0x31, 0x5F, 0x32, 0x06, + 0x66, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x02, + 0x58, 0x20, 0xF8, 0xB7, 0xCE, 0xAD, 0x9B, 0xE4, + 0x5A, 0x8F, 0x5C, 0x52, 0x6F, 0x0C, 0x05, 0x25, + 0x8F, 0xF3, 0xE9, 0x81, 0xDC, 0xBC, 0xF2, 0x05, + 0x7F, 0x33, 0xF6, 0xBB, 0xDC, 0xD9, 0x4D, 0xA2, + 0x34, 0x3A, 0xA5, 0x05, 0x58, 0x20, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x67, + 0x31, 0x2E, 0x37, 0x2E, 0x32, 0x2B, 0x30, 0x01, + 0x63, 0x42, 0x4C, 0x32, 0x06, 0x66, 0x53, 0x48, + 0x41, 0x32, 0x35, 0x36, 0x02, 0x58, 0x20, 0x3A, + 0xE5, 0x9E, 0x40, 0xA9, 0x6B, 0xD5, 0x29, 0x1C, + 0xAB, 0x7A, 0x5F, 0xBD, 0x1F, 0x9A, 0xA6, 0x52, + 0xFB, 0x77, 0x7D, 0xA3, 0xEC, 0x9C, 0x29, 0xBC, + 0xE6, 0x5B, 0x3B, 0x43, 0xFC, 0x9D, 0x26, 0xA5, + 0x05, 0x58, 0x20, 0xBF, 0xE6, 0xD8, 0x6F, 0x88, + 0x26, 0xF4, 0xFF, 0x97, 0xFB, 0x96, 0xC4, 0xE6, + 0xFB, 0xC4, 0x99, 0x3E, 0x46, 0x19, 0xFC, 0x56, + 0x5D, 0xA2, 0x6A, 0xDF, 0x34, 0xC3, 0x29, 0x48, + 0x9A, 0xDC, 0x38, 0x04, 0x67, 0x31, 0x2E, 0x35, + 0x2E, 0x30, 0x2B, 0x30, 0x01, 0x64, 0x52, 0x54, + 0x5F, 0x30, 0x06, 0x66, 0x53, 0x48, 0x41, 0x32, + 0x35, 0x36, 0x02, 0x58, 0x20, 0x47, 0x94, 0x9D, + 0x27, 0x33, 0x82, 0x45, 0x1A, 0xDD, 0x25, 0xF4, + 0x9A, 0x89, 0x6F, 0x5F, 0xD9, 0xB0, 0xE8, 0x14, + 0xD3, 0xA4, 0x9B, 0x53, 0xB0, 0x44, 0x0B, 0xCF, + 0x32, 0x1A, 0xC4, 0xD2, 0x65, 0xA5, 0x05, 0x58, + 0x20, 0xB3, 0x60, 0xCA, 0xF5, 0xC9, 0x8C, 0x6B, + 0x94, 0x2A, 0x48, 0x82, 0xFA, 0x9D, 0x48, 0x23, + 0xEF, 0xB1, 0x66, 0xA9, 0xEF, 0x6A, 0x6E, 0x4A, + 0xA3, 0x7C, 0x19, 0x19, 0xED, 0x1F, 0xCC, 0xC0, + 0x49, 0x04, 0x67, 0x30, 0x2E, 0x30, 0x2E, 0x37, + 0x2B, 0x30, 0x01, 0x64, 0x52, 0x54, 0x5F, 0x31, + 0x06, 0x66, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, + 0x02, 0x58, 0x20, 0xCD, 0x38, 0xBE, 0xC8, 0xB7, + 0xC0, 0x9E, 0xD5, 0x24, 0x30, 0xFE, 0xC8, 0xD0, + 0x19, 0x12, 0x56, 0xB2, 0x7A, 0xA5, 0x53, 0x6F, + 0xBC, 0x7D, 0x09, 0xCA, 0x11, 0xDD, 0x90, 0xD7, + 0xD6, 0x70, 0xFD, 0xA5, 0x05, 0x58, 0x20, 0xAA, + 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, + 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, + 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, + 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x04, + 0x60, 0x01, 0x60, 0x06, 0x66, 0x53, 0x48, 0x41, + 0x32, 0x35, 0x36, 0x02, 0x58, 0x20, 0x28, 0x3D, + 0x0C, 0x25, 0x22, 0x0C, 0x87, 0x46, 0xA0, 0x58, + 0x64, 0x6C, 0x0B, 0x14, 0x37, 0x39, 0x40, 0x9D, + 0x2D, 0x11, 0xD1, 0xCC, 0x54, 0x51, 0xB4, 0x29, + 0x22, 0xCD, 0x70, 0x92, 0x71, 0xC3, 0x3A, 0x00, + 0x01, 0x25, 0x01, 0x77, 0x77, 0x77, 0x77, 0x2E, + 0x74, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x66, + 0x69, 0x72, 0x6D, 0x77, 0x61, 0x72, 0x65, 0x2E, + 0x6F, 0x72, 0x67, 0x3A, 0x00, 0x01, 0x24, 0xF7, + 0x71, 0x50, 0x53, 0x41, 0x5F, 0x49, 0x4F, 0x54, + 0x5F, 0x50, 0x52, 0x4F, 0x46, 0x49, 0x4C, 0x45, + 0x5F, 0x31, 0x3A, 0x00, 0x01, 0x24, 0xFC, 0x70, + 0x30, 0x36, 0x30, 0x34, 0x35, 0x36, 0x35, 0x32, + 0x37, 0x32, 0x38, 0x32, 0x39, 0x31, 0x30, 0x30, + 0x58, 0x40, 0x1E, 0x0D, 0x2B, 0xD8, 0x7A, 0xC9, + 0x2D, 0xCB, 0x73, 0xD1, 0x42, 0x2F, 0xBF, 0xDA, + 0x24, 0x71, 0xE2, 0xAF, 0xEA, 0x48, 0x60, 0x17, + 0x23, 0x75, 0x64, 0xAC, 0xCC, 0x23, 0xA2, 0x67, + 0xC4, 0xE7, 0x8F, 0x1C, 0x7C, 0x68, 0x49, 0x42, + 0x4D, 0xDA, 0xC6, 0xD6, 0x21, 0x1C, 0xAA, 0x00, + 0xDA, 0x1E, 0x68, 0x56, 0xA3, 0x48, 0xEE, 0xA7, + 0x92, 0xA9, 0x09, 0x83, 0x42, 0x04, 0x06, 0x9E, + 0x62, 0xBB +}; + +psa_status_t +psa_initial_attest_get_token(const uint8_t *auth_challenge, + size_t challenge_size, + uint8_t *token_buf, + size_t token_buf_size, + size_t *token_size) +{ + (void)auth_challenge; + (void)challenge_size; + + if (token_buf_size < sizeof(platform_token)) { + return PSA_ERROR_BUFFER_TOO_SMALL; + } + + (void)memcpy(token_buf, platform_token, sizeof(platform_token)); + *token_size = sizeof(platform_token); + + return PSA_SUCCESS; +} +#endif /* !PLAT_RSS_NOT_SUPPORTED */ diff --git a/lib/psa/measured_boot.c b/lib/psa/measured_boot.c index f4216ebf1..5d3ca8ed2 100644 --- a/lib/psa/measured_boot.c +++ b/lib/psa/measured_boot.c @@ -55,6 +55,7 @@ static void log_measurement(uint8_t index, INFO(" - locking : %s\n", lock_measurement ? "true" : "false"); } +#if !PLAT_RSS_NOT_SUPPORTED psa_status_t rss_measured_boot_extend_measurement(uint8_t index, const uint8_t *signer_id, @@ -102,3 +103,27 @@ rss_measured_boot_extend_measurement(uint8_t index, in_vec, IOVEC_LEN(in_vec), NULL, 0); } + +#else /* !PLAT_RSS_NOT_SUPPORTED */ + +psa_status_t +rss_measured_boot_extend_measurement(uint8_t index, + const uint8_t *signer_id, + size_t signer_id_size, + const uint8_t *version, + size_t version_size, + uint32_t measurement_algo, + const uint8_t *sw_type, + size_t sw_type_size, + const uint8_t *measurement_value, + size_t measurement_value_size, + bool lock_measurement) +{ + log_measurement(index, signer_id, signer_id_size, + version, measurement_algo, sw_type, + measurement_value, measurement_value_size, + lock_measurement); + + return PSA_SUCCESS; +} +#endif /* !PLAT_RSS_NOT_SUPPORTED */ diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk index 6e572377b..d5383a10f 100644 --- a/make_helpers/defaults.mk +++ b/make_helpers/defaults.mk @@ -460,3 +460,6 @@ ENABLE_TRF_FOR_NS := 0 # SCR_EL3.TWEDEL(4bit) field, when FEAT_TWED is implemented. # By default it takes 0, and need to be updated by the platforms. TWED_DELAY := 0 + +# By default, disable the mocking of RSS provided services +PLAT_RSS_NOT_SUPPORTED := 0 From c44e50b72567205650c6455f3a258f36af0c84dd Mon Sep 17 00:00:00 2001 From: Tamas Ban Date: Fri, 11 Feb 2022 09:49:36 +0100 Subject: [PATCH 7/8] feat(plat/arm/fvp): enable RSS backend based measured boot Enable the RSS backend based measured boot feature. In the absence of RSS the mocked version of PSA APIs are used. They always return with success and hard-code data. Signed-off-by: Tamas Ban Change-Id: I7543e9033a7a21f1b836d911d8d9498c6e09b956 --- .../measured_boot/rss/rss_measured_boot.h | 2 ++ plat/arm/board/fvp/fvp_bl1_measured_boot.c | 32 ++++++++++++++++- plat/arm/board/fvp/fvp_bl2_measured_boot.c | 35 +++++++++++++++++++ plat/arm/board/fvp/fvp_common_measured_boot.c | 34 ++++++++++++++---- plat/arm/board/fvp/platform.mk | 26 ++++++++++++-- 5 files changed, 119 insertions(+), 10 deletions(-) diff --git a/include/drivers/measured_boot/rss/rss_measured_boot.h b/include/drivers/measured_boot/rss/rss_measured_boot.h index b8cf8dae9..fe885765c 100644 --- a/include/drivers/measured_boot/rss/rss_measured_boot.h +++ b/include/drivers/measured_boot/rss/rss_measured_boot.h @@ -24,8 +24,10 @@ */ #define RSS_MBOOT_BL2_STRING "BL_2" #define RSS_MBOOT_BL31_STRING "SECURE_RT_EL3" +#define RSS_MBOOT_HW_CONFIG_STRING "HW_CONFIG" #define RSS_MBOOT_FW_CONFIG_STRING "FW_CONFIG" #define RSS_MBOOT_TB_FW_CONFIG_STRING "TB_FW_CONFIG" +#define RSS_MBOOT_SOC_FW_CONFIG_STRING "SOC_FW_CONFIG" #define RSS_MBOOT_RMM_STRING "RMM" diff --git a/plat/arm/board/fvp/fvp_bl1_measured_boot.c b/plat/arm/board/fvp/fvp_bl1_measured_boot.c index 546855527..76cd91824 100644 --- a/plat/arm/board/fvp/fvp_bl1_measured_boot.c +++ b/plat/arm/board/fvp/fvp_bl1_measured_boot.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Arm Limited. All rights reserved. + * Copyright (c) 2021-2022, Arm Limited. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -7,6 +7,7 @@ #include #include +#include #include /* Event Log data */ @@ -21,10 +22,39 @@ const event_log_metadata_t fvp_event_log_metadata[] = { { EVLOG_INVALID_ID, NULL, (unsigned int)(-1) } /* Terminator */ }; +/* FVP table with platform specific image IDs and metadata. Intentionally not a + * const struct, some members might set by bootloaders during trusted boot. + */ +struct rss_mboot_metadata fvp_rss_mboot_metadata[] = { + { + .id = FW_CONFIG_ID, + .slot = U(6), + .signer_id_size = SIGNER_ID_MIN_SIZE, + .sw_type = RSS_MBOOT_FW_CONFIG_STRING, + .lock_measurement = true }, + { + .id = TB_FW_CONFIG_ID, + .slot = U(7), + .signer_id_size = SIGNER_ID_MIN_SIZE, + .sw_type = RSS_MBOOT_TB_FW_CONFIG_STRING, + .lock_measurement = true }, + { + .id = BL2_IMAGE_ID, + .slot = U(8), + .signer_id_size = SIGNER_ID_MIN_SIZE, + .sw_type = RSS_MBOOT_BL2_STRING, + .lock_measurement = true }, + + { + .id = RSS_MBOOT_INVALID_ID } +}; + void bl1_plat_mboot_init(void) { event_log_init(event_log, event_log + sizeof(event_log)); event_log_write_header(); + + rss_measured_boot_init(); } void bl1_plat_mboot_finish(void) diff --git a/plat/arm/board/fvp/fvp_bl2_measured_boot.c b/plat/arm/board/fvp/fvp_bl2_measured_boot.c index 1f3827831..fd15b70d3 100644 --- a/plat/arm/board/fvp/fvp_bl2_measured_boot.c +++ b/plat/arm/board/fvp/fvp_bl2_measured_boot.c @@ -7,6 +7,7 @@ #include #include +#include #include #include @@ -35,6 +36,38 @@ const event_log_metadata_t fvp_event_log_metadata[] = { { EVLOG_INVALID_ID, NULL, (unsigned int)(-1) } /* Terminator */ }; +/* FVP table with platform specific image IDs and metadata. Intentionally not a + * const struct, some members might set by bootloaders during trusted boot. + */ +struct rss_mboot_metadata fvp_rss_mboot_metadata[] = { + { + .id = BL31_IMAGE_ID, + .slot = U(9), + .signer_id_size = SIGNER_ID_MIN_SIZE, + .sw_type = RSS_MBOOT_BL31_STRING, + .lock_measurement = true }, + { + .id = HW_CONFIG_ID, + .slot = U(10), + .signer_id_size = SIGNER_ID_MIN_SIZE, + .sw_type = RSS_MBOOT_HW_CONFIG_STRING, + .lock_measurement = true }, + { + .id = SOC_FW_CONFIG_ID, + .slot = U(11), + .signer_id_size = SIGNER_ID_MIN_SIZE, + .sw_type = RSS_MBOOT_SOC_FW_CONFIG_STRING, + .lock_measurement = true }, + { + .id = RMM_IMAGE_ID, + .slot = U(12), + .signer_id_size = SIGNER_ID_MIN_SIZE, + .sw_type = RSS_MBOOT_RMM_STRING, + .lock_measurement = true }, + { + .id = RSS_MBOOT_INVALID_ID } +}; + void bl2_plat_mboot_init(void) { uint8_t *event_log_start; @@ -64,6 +97,8 @@ void bl2_plat_mboot_init(void) PLAT_ARM_EVENT_LOG_MAX_SIZE); event_log_init((uint8_t *)event_log_start, event_log_finish); + + rss_measured_boot_init(); } int plat_mboot_measure_critical_data(unsigned int critical_data_id, diff --git a/plat/arm/board/fvp/fvp_common_measured_boot.c b/plat/arm/board/fvp/fvp_common_measured_boot.c index 6a403d945..93aa0558c 100644 --- a/plat/arm/board/fvp/fvp_common_measured_boot.c +++ b/plat/arm/board/fvp/fvp_common_measured_boot.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Arm Limited. All rights reserved. + * Copyright (c) 2021-2022, Arm Limited. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -9,27 +9,47 @@ #include #include +#include #include #include extern event_log_metadata_t fvp_event_log_metadata[]; +extern struct rss_mboot_metadata fvp_rss_mboot_metadata[]; const event_log_metadata_t *plat_event_log_get_metadata(void) { return fvp_event_log_metadata; } +struct rss_mboot_metadata *plat_rss_mboot_get_metadata(void) +{ + return fvp_rss_mboot_metadata; +} + int plat_mboot_measure_image(unsigned int image_id, image_info_t *image_data) { + int err; + int rc = 0; + /* Calculate image hash and record data in Event Log */ - int err = event_log_measure_and_record(image_data->image_base, - image_data->image_size, - image_id); + err = event_log_measure_and_record(image_data->image_base, + image_data->image_size, + image_id); if (err != 0) { ERROR("%s%s image id %u (%i)\n", - "Failed to ", "record", image_id, err); - return err; + "Failed to ", "record in event log", image_id, err); + rc = err; } - return 0; + /* Calculate image hash and record data in RSS */ + err = rss_mboot_measure_and_record(image_data->image_base, + image_data->image_size, + image_id); + if (err != 0) { + ERROR("%s%s image id %u (%i)\n", + "Failed to ", "record in RSS", image_id, err); + rc = (rc == 0) ? err : -1; + } + + return rc; } diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk index d89e91f71..89ca18540 100644 --- a/plat/arm/board/fvp/platform.mk +++ b/plat/arm/board/fvp/platform.mk @@ -367,14 +367,36 @@ ifneq (${BL2_AT_EL3}, 0) override BL1_SOURCES = endif +# Include Measured Boot makefile before any Crypto library makefile. +# Crypto library makefile may need default definitions of Measured Boot build +# flags present in Measured Boot makefile. +ifeq (${MEASURED_BOOT},1) + RSS_MEASURED_BOOT_MK := drivers/measured_boot/rss/rss_measured_boot.mk + $(info Including ${RSS_MEASURED_BOOT_MK}) + include ${RSS_MEASURED_BOOT_MK} + + BL1_SOURCES += ${MEASURED_BOOT_SOURCES} + BL2_SOURCES += ${MEASURED_BOOT_SOURCES} +endif + include plat/arm/board/common/board_common.mk include plat/arm/common/arm_common.mk ifeq (${MEASURED_BOOT},1) BL1_SOURCES += plat/arm/board/fvp/fvp_common_measured_boot.c \ - plat/arm/board/fvp/fvp_bl1_measured_boot.c + plat/arm/board/fvp/fvp_bl1_measured_boot.c \ + lib/psa/measured_boot.c + BL2_SOURCES += plat/arm/board/fvp/fvp_common_measured_boot.c \ - plat/arm/board/fvp/fvp_bl2_measured_boot.c + plat/arm/board/fvp/fvp_bl2_measured_boot.c \ + lib/psa/measured_boot.c + +PLAT_INCLUDES += -Iinclude/lib/psa + +# RSS is not supported on FVP right now. Thus, we use the mocked version +# of PSA Measured Boot APIs. They return with success and hard-coded data. +PLAT_RSS_NOT_SUPPORTED := 1 + endif ifeq (${TRUSTED_BOARD_BOOT}, 1) From c671daeeea03d618d65f44f129a62f1b21213e13 Mon Sep 17 00:00:00 2001 From: David Vincze Date: Thu, 12 May 2022 16:07:03 +0200 Subject: [PATCH 8/8] docs(maintainers): add PSA, MHU, RSS comms code owners Adding Sandrine Bailleux for the PSA APIs and myself for the MHU and RSS comms drivers as code owner. Change-Id: Ib948479cc6e46163aae59c938877a2d0bcf91754 Signed-off-by: David Vincze --- docs/about/maintainers.rst | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/docs/about/maintainers.rst b/docs/about/maintainers.rst index b9b58782c..c62a6beb2 100644 --- a/docs/about/maintainers.rst +++ b/docs/about/maintainers.rst @@ -293,6 +293,20 @@ GIC driver :|G|: `odeprez`_ :|F|: drivers/arm/gic/ +Message Handling Unit (MHU) driver +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +:|M|: David Vincze +:|G|: `davidvincze`_ +:|F|: include/drivers/arm/mhu.h +:|F|: drivers/arm/mhu + +Runtime Security Subsystem (RSS) comms driver +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +:|M|: David Vincze +:|G|: `davidvincze`_ +:|F|: include/drivers/arm/rss_comms.h +:|F|: drivers/arm/rss + Libfdt wrappers ^^^^^^^^^^^^^^^ :|M|: Madhukar Pappireddy @@ -331,6 +345,13 @@ PSA Firmware Update :|F|: drivers/fwu :|F|: include/drivers/fwu +Platform Security Architecture (PSA) APIs +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +:|M|: Sandrine Bailleux +:|G|: `sandrine-bailleux-arm`_ +:|F|: include/lib/psa +:|F|: lib/psa + System Control and Management Interface (SCMI) Server ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ :|M|: Etienne Carriere @@ -821,6 +842,7 @@ Conventional Changelog Extensions .. _b49020: https://github.com/b49020 .. _carlocaione: https://github.com/carlocaione .. _danh-arm: https://github.com/danh-arm +.. _davidvincze: https://github.com/davidvincze .. _etienne-lms: https://github.com/etienne-lms .. _glneo: https://github.com/glneo .. _grandpaul: https://github.com/grandpaul