Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions hal/mpfs250.c
Original file line number Diff line number Diff line change
Expand Up @@ -1056,9 +1056,11 @@ static void qspi_uart_program(void)
return;
}
if (!((addr >= WOLFBOOT_PARTITION_BOOT_ADDRESS &&
addr + size <= WOLFBOOT_PARTITION_BOOT_ADDRESS + WOLFBOOT_PARTITION_SIZE) ||
addr < WOLFBOOT_PARTITION_BOOT_ADDRESS + WOLFBOOT_PARTITION_SIZE &&
size <= WOLFBOOT_PARTITION_BOOT_ADDRESS + WOLFBOOT_PARTITION_SIZE - addr) ||
(addr >= WOLFBOOT_PARTITION_UPDATE_ADDRESS &&
addr + size <= WOLFBOOT_PARTITION_UPDATE_ADDRESS + WOLFBOOT_PARTITION_SIZE))) {
addr < WOLFBOOT_PARTITION_UPDATE_ADDRESS + WOLFBOOT_PARTITION_SIZE &&
size <= WOLFBOOT_PARTITION_UPDATE_ADDRESS + WOLFBOOT_PARTITION_SIZE - addr))) {
uart_qspi_puts("QSPI-PROG: Outside partition\r\n");
return;
}
Expand Down
16 changes: 10 additions & 6 deletions hal/nxp_ls1028a.c
Original file line number Diff line number Diff line change
Expand Up @@ -553,7 +553,8 @@ void xspi_flash_write(uintptr_t address, const uint8_t *data, uint32_t len)
while (!(XSPI_INTR & XSPI_INTR_IPTXWE_MASK));

for(j = 0; j < XSPI_IP_WM_SIZE; j+=4) {
memcpy(&tx_data, data++, 4);
memcpy(&tx_data, data, 4);
data += 4;
xspi_writereg((uint32_t*)XSPI_TFD_BASE + j, tx_data);
}

Expand All @@ -570,8 +571,9 @@ void xspi_flash_write(uintptr_t address, const uint8_t *data, uint32_t len)

for(j = 0; j < remaining; j+=4) {
tx_data = 0;
rem_size = (remaining < 4) ? remaining : 4;
memcpy(&tx_data, data++, rem_size);
rem_size = ((remaining - j) < 4) ? (remaining - j) : 4;
memcpy(&tx_data, data, rem_size);
data += rem_size;
xspi_writereg((uint32_t*)XSPI_TFD_BASE + j, tx_data);
}

Expand All @@ -583,7 +585,7 @@ void xspi_flash_write(uintptr_t address, const uint8_t *data, uint32_t len)
XSPI_IPCMD_START();

/* Wait command done */
while (!(XSPI_INTR & XSPI_IPCMDDONE))
while (!(XSPI_INTR & XSPI_IPCMDDONE));

/* Flush fifo, set done flag */
XSPI_IPTXFCR = XSPI_IPRCFCR_FLUSH;
Expand Down Expand Up @@ -625,12 +627,13 @@ int hal_flash_erase(uintptr_t address, int len)
{
uint32_t num_sectors = 0;
uint32_t i = 0;
uint8_t status[4] = {0, 0, 0, 0};

num_sectors = len / FLASH_ERASE_SIZE;
num_sectors += (len % FLASH_ERASE_SIZE) ? 1 : 0;

for (i = 0; i < num_sectors; i++) {
uint8_t status[4] = {0, 0, 0, 0};

xspi_write_en(address + i * FLASH_ERASE_SIZE);
xspi_flash_sec_erase(address + i * FLASH_ERASE_SIZE);

Expand Down Expand Up @@ -671,12 +674,13 @@ int ext_flash_erase(uintptr_t address, int len)
{
uint32_t num_sectors = 0;
uint32_t i = 0;
uint8_t status[4] = {0, 0, 0, 0};

num_sectors = len / FLASH_ERASE_SIZE;
num_sectors += (len % FLASH_ERASE_SIZE) ? 1 : 0;

for (i = 0; i < num_sectors; i++) {
uint8_t status[4] = {0, 0, 0, 0};

xspi_write_en(address + i * FLASH_ERASE_SIZE);
xspi_flash_sec_erase(address + i * FLASH_ERASE_SIZE);

Expand Down
101 changes: 97 additions & 4 deletions src/arm_tee_psa_ipc.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
#include <psa/crypto.h>
#include <psa/error.h>

#include <arm_cmse.h>

#include <wolfssl/wolfcrypt/memory.h>
#include <wolfssl/wolfcrypt/types.h>
#include <wolfboot/arm_tee_api.h>
Expand Down Expand Up @@ -113,6 +115,11 @@ struct arm_tee_crypto_pack_iovec {
};
};

/* Upper bound on the number of in/out descriptors accepted by
* arm_tee_psa_call(). The NSC veneer packs in_len/out_len into 3-bit fields,
* so a non-secure caller can request at most 7 of each. */
#define ARM_TEE_PSA_MAX_IOVEC 7

struct wolfboot_hash_slot {
uint32_t handle;
psa_hash_operation_t op;
Expand Down Expand Up @@ -351,7 +358,8 @@ static psa_status_t wolfboot_crypto_dispatch(const psa_invec *in_vec,
psa_outvec *out_vec,
size_t out_len)
{
const struct arm_tee_crypto_pack_iovec *iov;
struct arm_tee_crypto_pack_iovec iov_s;
const struct arm_tee_crypto_pack_iovec *iov = &iov_s;
psa_status_t init_status;

if (in_vec == NULL || in_len == 0) {
Expand All @@ -363,10 +371,15 @@ static psa_status_t wolfboot_crypto_dispatch(const psa_invec *in_vec,
return init_status;
}

iov = (const struct arm_tee_crypto_pack_iovec *)in_vec[0].base;
if (iov == NULL || in_vec[0].len < sizeof(struct arm_tee_crypto_pack_iovec)) {
if (in_vec[0].base == NULL ||
in_vec[0].len < sizeof(struct arm_tee_crypto_pack_iovec)) {
return PSA_ERROR_INVALID_ARGUMENT;
}
/* Snapshot the packed iovec header out of NS memory once. Its fields
* (function_id, key_id, alg, op_handle, ...) are read repeatedly below;
* dereferencing the NS copy each time would let a racing NS agent change
* them mid-dispatch. */
iov_s = *(const struct arm_tee_crypto_pack_iovec *)in_vec[0].base;

switch (iov->function_id) {
case ARM_TEE_CRYPTO_GENERATE_RANDOM_SID:
Expand Down Expand Up @@ -750,7 +763,7 @@ psa_handle_t arm_tee_psa_connect(uint32_t sid, uint32_t version)
return (psa_handle_t)PSA_ERROR_CONNECTION_REFUSED;
}

int32_t arm_tee_psa_call(psa_handle_t handle, int32_t type,
static int32_t arm_tee_psa_dispatch(psa_handle_t handle, int32_t type,
const psa_invec *in_vec, size_t in_len,
psa_outvec *out_vec, size_t out_len)
{
Expand Down Expand Up @@ -992,6 +1005,86 @@ int32_t arm_tee_psa_call(psa_handle_t handle, int32_t type,
return PSA_ERROR_NOT_SUPPORTED;
}

int32_t arm_tee_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)
{
psa_invec in_vec_s[ARM_TEE_PSA_MAX_IOVEC];
psa_outvec out_vec_s[ARM_TEE_PSA_MAX_IOVEC];
int32_t result;
size_t i;

/* Reject more descriptors than the Secure-stack snapshots can hold. This
* also keeps the in_len/out_len * sizeof() products below from
* overflowing size_t. */
if (in_len > ARM_TEE_PSA_MAX_IOVEC || out_len > ARM_TEE_PSA_MAX_IOVEC) {
return PSA_ERROR_INVALID_ARGUMENT;
}

if (in_len > 0 && in_vec == NULL) {
return PSA_ERROR_INVALID_ARGUMENT;
}
if (in_len > 0 &&
cmse_check_address_range((void *)in_vec, in_len * sizeof(*in_vec),
CMSE_NONSECURE) == NULL) {
return PSA_ERROR_INVALID_ARGUMENT;
}
if (out_len > 0 && out_vec == NULL) {
return PSA_ERROR_INVALID_ARGUMENT;
}
if (out_len > 0 &&
cmse_check_address_range(out_vec, out_len * sizeof(*out_vec),
CMSE_NONSECURE) == NULL) {
return PSA_ERROR_INVALID_ARGUMENT;
}

/* Snapshot the NS-supplied descriptor arrays into Secure-stack copies
* before validating them, or they might be changed under our nose by NS.
*/
for (i = 0; i < in_len; i++) {
in_vec_s[i] = in_vec[i];
}
for (i = 0; i < out_len; i++) {
out_vec_s[i] = out_vec[i];
}

for (i = 0; i < in_len; i++) {
if (in_vec_s[i].len > 0 && in_vec_s[i].base == NULL) {
return PSA_ERROR_INVALID_ARGUMENT;
}
if (in_vec_s[i].len > 0 &&
cmse_check_address_range((void *)in_vec_s[i].base,
in_vec_s[i].len,
CMSE_NONSECURE) == NULL) {
return PSA_ERROR_INVALID_ARGUMENT;
}
}
for (i = 0; i < out_len; i++) {
if (out_vec_s[i].len > 0 && out_vec_s[i].base == NULL) {
return PSA_ERROR_INVALID_ARGUMENT;
}
if (out_vec_s[i].len > 0 &&
cmse_check_address_range(out_vec_s[i].base,
out_vec_s[i].len,
CMSE_NONSECURE) == NULL) {
return PSA_ERROR_INVALID_ARGUMENT;
}
}

result = arm_tee_psa_dispatch(handle, type,
in_len > 0 ? in_vec_s : NULL, in_len,
out_len > 0 ? out_vec_s : NULL, out_len);

/* Propagate the (possibly updated) output lengths from the Secure snapshot
* back to the NS descriptor array. Only the .len scalars are written back;
* .base is never copied out from Secure-derived values. */
for (i = 0; i < out_len; i++) {
out_vec[i].len = out_vec_s[i].len;
}

return result;
}

void arm_tee_psa_close(psa_handle_t handle)
{
(void)handle;
Expand Down
4 changes: 4 additions & 0 deletions src/elf.c
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,10 @@ int elf_load_image_mmu(uint8_t *image, uint32_t image_sz, uintptr_t *pentry,
return -4; /* segment offset/size out of bounds */
}

if (GET_E64(vaddr) > (uint64_t)UINTPTR_MAX - GET_E64(mem_size)) {
return -5; /* segment destination out of range */
}

#ifdef DEBUG_ELF
if (file_size > 0) {
wolfBoot_printf(
Expand Down
6 changes: 4 additions & 2 deletions src/libwolfboot.c
Original file line number Diff line number Diff line change
Expand Up @@ -2471,7 +2471,7 @@ int wolfBoot_nsc_erase_update(uint32_t address, uint32_t len)

if (address > WOLFBOOT_PARTITION_SIZE)
return -1;
if (address + len > WOLFBOOT_PARTITION_SIZE)
if (len > WOLFBOOT_PARTITION_SIZE - address)
return -1;

hal_flash_unlock();
Expand All @@ -2487,7 +2487,9 @@ int wolfBoot_nsc_write_update(uint32_t address, const uint8_t *buf, uint32_t len

if (address > WOLFBOOT_PARTITION_SIZE)
return -1;
if (address + len > WOLFBOOT_PARTITION_SIZE)
if (len > WOLFBOOT_PARTITION_SIZE - address)
return -1;
if (len > 0 && WOLFBOOT_NSC_NS_RW(buf, len) == NULL)
return -1;
hal_flash_unlock();
ret = hal_flash_write(address + WOLFBOOT_PARTITION_UPDATE_ADDRESS, buf, len);
Expand Down
Loading
Loading