Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
eaa6af2
Return UART flash read error on timeout
danielinux Apr 29, 2026
f86ffd8
Fix delta update cleanup on early errors
danielinux Apr 29, 2026
b0f1bf9
Handle library image malloc failure
danielinux Apr 29, 2026
bcd75b0
Fix multiboot debug header length guard
danielinux Apr 29, 2026
b6e6dc0
Harden local secret comparisons
danielinux Apr 29, 2026
1e6dd16
Harden encrypted key comparisons
danielinux Apr 29, 2026
74c0d29
Add single-partition disk boot tests
danielinux Apr 29, 2026
6e8e20c
Cap backward delta match length
danielinux Apr 29, 2026
dfc7656
Validate GPT partition array CRC
danielinux Apr 29, 2026
8eddbf3
zeroize ARM TEE PS buffers on reuse
danielinux Apr 29, 2026
98d1e77
Abort QSPI writes after WE failure
danielinux Apr 29, 2026
54b2ba3
Bound TPM name fallback copies
danielinux Apr 29, 2026
26cae31
Fix decrypted blob TLV parsing
danielinux Apr 29, 2026
cc6f52e
Add final sanity check after boot hook
danielinux Apr 29, 2026
c39522e
Add inverse delta version gate tests
danielinux Apr 29, 2026
47ef6b4
Add GPT single-sector partition test
danielinux Apr 29, 2026
afa9641
Add sector flag unit coverage
danielinux Apr 29, 2026
a60461f
Fix XMSS keygen param fallback
danielinux Apr 29, 2026
05f5f5c
Zeroize XMSS key readback buffer
danielinux Apr 29, 2026
47e1f77
Zero LMS key verify buffer
danielinux Apr 29, 2026
2a9aa60
Fixed test regressions
danielinux Apr 29, 2026
8eb7fa6
Addressed copilot's comments
danielinux Apr 29, 2026
8c0b44c
Fixed size-all thresholds
danielinux Apr 29, 2026
1226776
Modernize riscv build test
danielinux Apr 29, 2026
971f0c6
Improve readability of changes in disk.c
danielinux Apr 29, 2026
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
67 changes: 8 additions & 59 deletions .github/workflows/test-build-riscv.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ jobs:

build:
runs-on: ubuntu-24.04
container:
image: ghcr.io/wolfssl/wolfboot-ci-riscv:v1.0
timeout-minutes: 30
steps:
- uses: actions/checkout@v4
Expand All @@ -31,69 +33,16 @@ jobs:
path: freedom-e-sdk
submodules: recursive

- name: Workaround for sources.list
- name: Trust workspace
run: |
# Replace sources
git config --global --add safe.directory "$GITHUB_WORKSPACE"

set -euxo pipefail

# Peek (what repos are active now)
apt-cache policy
grep -RInE '^(deb|Types|URIs)' /etc/apt || true

# Enable nullglob so *.list/*.sources that don't exist don't break sed
shopt -s nullglob

echo "Replace sources.list (legacy)"
sudo sed -i \
-e "s|https\?://azure\.archive\.ubuntu\.com/ubuntu/?|http://mirror.arizona.edu/ubuntu/|g" \
/etc/apt/sources.list || true

echo "Replace sources.list.d/*.list (legacy)"
for f in /etc/apt/sources.list.d/*.list; do
sudo sed -i \
-e "s|https\?://azure\.archive\.ubuntu\.com/ubuntu/?|http://mirror.arizona.edu/ubuntu/|g" \
"$f"
done

echo "Replace sources.list.d/*.sources (deb822)"
for f in /etc/apt/sources.list.d/*.sources; do
sudo sed -i \
-e "s|https\?://azure\.archive\.ubuntu\.com/ubuntu/?|http://mirror.arizona.edu/ubuntu/|g" \
-e "s|https\?://azure\.archive\.ubuntu\.com|http://mirror.arizona.edu|g" \
"$f"
done

echo "Fix /etc/apt/apt-mirrors.txt (used by URIs: mirror+file:...)"
if grep -qE '^[[:space:]]*https?://azure\.archive\.ubuntu\.com/ubuntu/?' /etc/apt/apt-mirrors.txt; then
# Replace azure with our mirror (idempotent)
sudo sed -i 's|https\?://azure\.archive\.ubuntu\.com/ubuntu/|http://mirror.arizona.edu/ubuntu/|g' /etc/apt/apt-mirrors.txt
fi

# Peek (verify changes)
grep -RIn "azure.archive.ubuntu.com" /etc/apt || true
grep -RInE '^(deb|Types|URIs)' /etc/apt || true
echo "--- apt-mirrors.txt ---"
cat /etc/apt/apt-mirrors.txt || true

- name: Update repository
run: sudo apt-get update -o Acquire::Retries=3
- name: Add preinstalled RISC-V toolchain to PATH
run: |
echo "/opt/xpack-riscv-none-elf-gcc-15.2.0-1/bin" >> "$GITHUB_PATH"

# ============================================================
# xPack RISC-V GCC — single toolchain with full multilib
# supporting both rv32 and rv64 targets (including rv32imac/ilp32
# and rv64imac/lp64 which riscv-collab nightly builds lack).
# https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack
# ============================================================
- name: Download and install xPack RISC-V toolchain
- name: Check RISC-V toolchain
run: |
XPACK_VER="15.2.0-1"
XPACK_FILE="xpack-riscv-none-elf-gcc-${XPACK_VER}-linux-x64.tar.gz"
wget -q "https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack/releases/download/v${XPACK_VER}/${XPACK_FILE}"
echo "aaaa8060c914851a3e5ee1ba82cc3d6f80972f90638a05c6e823a37557a33758 ${XPACK_FILE}" | sha256sum -c -
tar -xf "${XPACK_FILE}"
echo "$GITHUB_WORKSPACE/xpack-riscv-none-elf-gcc-${XPACK_VER}/bin" >> $GITHUB_PATH
export PATH="$GITHUB_WORKSPACE/xpack-riscv-none-elf-gcc-${XPACK_VER}/bin:$PATH"
riscv-none-elf-gcc --version
riscv-none-elf-gcc -print-multi-lib | head -5

Expand Down
3 changes: 3 additions & 0 deletions hal/library.c
Original file line number Diff line number Diff line change
Expand Up @@ -191,13 +191,16 @@ int main(int argc, const char* argv[])
if (((void*)gImage) == NULL) {
wolfBoot_printf("failed to malloc %zu bytes for image\n", sz);
ret = -1;
goto close_img;
}

bread = fread((void*)gImage, 1, sz, img);
if (bread != sz) {
ret = -2;
wolfBoot_printf("read %zu of %zu bytes from %s\n", bread, sz, argv[1]);
}

close_img:
fclose(img);
} else {
wolfBoot_printf("usage: %s image_file.bin\n", argv[0]);
Expand Down
34 changes: 33 additions & 1 deletion include/gpt.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,13 @@ struct gpt_part_info {
uint16_t name[GPT_PART_NAME_SIZE];
};

/**
* @brief CRC32 context for GPT header and partition-array validation.
*/
struct gpt_crc32_ctx {
uint32_t value;
};

/**
* @brief Check MBR for protective GPT partition entry.
*
Expand Down Expand Up @@ -139,6 +146,32 @@ int gpt_parse_header(const uint8_t *sector, struct guid_ptable *hdr);
int gpt_parse_partition(const uint8_t *entry_data, uint32_t entry_size,
struct gpt_part_info *part);

/**
* @brief Initialize a GPT CRC32 calculation.
*
* @param[out] ctx Pointer to CRC32 context.
*/
void gpt_crc32_init(struct gpt_crc32_ctx *ctx);

/**
* @brief Accumulate bytes into a GPT CRC32 calculation.
*
* @param[in,out] ctx Pointer to CRC32 context.
* @param[in] data Pointer to input bytes.
* @param[in] len Number of bytes to process.
*/
void gpt_crc32_update(struct gpt_crc32_ctx *ctx, const uint8_t *data,
uint32_t len);

/**
* @brief Finalize a GPT CRC32 calculation.
*
* @param[in] ctx Pointer to CRC32 context.
*
* @return Final CRC32 value.
*/
uint32_t gpt_crc32_final(const struct gpt_crc32_ctx *ctx);

/**
* @brief Compare UTF-16 partition name with ASCII string.
*
Expand All @@ -152,4 +185,3 @@ int gpt_parse_partition(const uint8_t *entry_data, uint32_t entry_size,
int gpt_part_name_eq(const uint16_t *utf16_name, const char *ascii_label);

#endif /* GPT_H */

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

#include <wolfssl/wolfcrypt/memory.h>
#include <wolfssl/wolfcrypt/types.h>
#include <wolfboot/arm_tee_api.h>
#include <wolfboot/dice.h>
Expand Down Expand Up @@ -240,6 +241,7 @@ static struct wolfboot_ps_entry *wolfboot_ps_alloc(psa_storage_uid_t uid)
{
for (size_t i = 0; i < WOLFBOOT_PS_MAX_ENTRIES; i++) {
if (!g_ps_entries[i].in_use) {
wc_ForceZero(g_ps_entries[i].data, sizeof(g_ps_entries[i].data));
g_ps_entries[i].in_use = 1;
g_ps_entries[i].uid = uid;
g_ps_entries[i].size = 0;
Expand Down Expand Up @@ -844,6 +846,7 @@ int32_t arm_tee_psa_call(psa_handle_t handle, int32_t type,
if (entry == NULL) {
return PSA_ERROR_DOES_NOT_EXIST;
}
wc_ForceZero(entry->data, sizeof(entry->data));
entry->in_use = 0;
entry->uid = 0;
entry->size = 0;
Expand Down
1 change: 1 addition & 0 deletions src/delta.c
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,7 @@ int wb_diff(WB_DIFF_CTX *ctx, uint8_t *patch, uint32_t len)
pb+= BLOCK_HDR_SIZE;
ctx->off_b += BLOCK_HDR_SIZE;
while ((pb < pb_limit) &&
(match_len < UINT16_MAX) &&
(ctx->off_b < ctx->size_b) &&
(*pb == *(ctx->src_b + ctx->off_b))) {
/* Extend match as long as the areas have the
Expand Down
32 changes: 32 additions & 0 deletions src/disk.c
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,11 @@ int disk_open(int drv)
uint32_t i;
uint32_t n_parts = 0;
uint32_t gpt_lba = 0;
uint32_t chunk = 0;
uint64_t array_addr = 0;
uint64_t bytes_left = 0;
uint8_t sector[GPT_SECTOR_SIZE] XALIGNED(4);
struct gpt_crc32_ctx part_crc;

if ((drv < 0) || (drv >= MAX_DISKS)) {
wolfBoot_printf("Attempting to access invalid drive %d\r\n", drv);
Expand Down Expand Up @@ -162,6 +166,34 @@ int disk_open(int drv)
wolfBoot_printf("Valid GPT partition table\r\n");
wolfBoot_printf("Max number of partitions: %d\r\n", ptable.n_part);

array_addr = ptable.start_array * GPT_SECTOR_SIZE;
bytes_left = (uint64_t)ptable.n_part * ptable.array_sz;

gpt_crc32_init(&part_crc);
while (bytes_left > 0) {
chunk = GPT_SECTOR_SIZE;

if (bytes_left < chunk) {
chunk = (uint32_t)bytes_left;
}

r = disk_read(drv, array_addr, chunk, sector);
if (r < 0) {
Drives[drv].is_open = 0;
return -1;
}

gpt_crc32_update(&part_crc, sector, chunk);
array_addr += chunk;
bytes_left -= chunk;
}

if (gpt_crc32_final(&part_crc) != ptable.part_crc) {
wolfBoot_printf("Invalid GPT partition entry array CRC\r\n");
Drives[drv].is_open = 0;
return -1;
}

n_parts = ptable.n_part;
if (n_parts > MAX_PARTITIONS)
n_parts = MAX_PARTITIONS;
Expand Down
35 changes: 28 additions & 7 deletions src/gpt.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,21 +34,39 @@

#include "gpt.h"

static uint32_t gpt_crc32(const uint8_t *data, uint32_t len)
void gpt_crc32_init(struct gpt_crc32_ctx *ctx)
{
if (ctx != NULL) {
ctx->value = 0xFFFFFFFFU;
}
}

void gpt_crc32_update(struct gpt_crc32_ctx *ctx, const uint8_t *data,
uint32_t len)
{
uint32_t crc = 0xFFFFFFFFU;
uint32_t i;
uint32_t j;

if (ctx == NULL || data == NULL) {
return;
}

for (i = 0; i < len; i++) {
crc ^= data[i];
ctx->value ^= data[i];
for (j = 0; j < 8; j++) {
uint32_t mask = -(crc & 1U);
crc = (crc >> 1) ^ (0xEDB88320U & mask);
uint32_t mask = -(ctx->value & 1U);
ctx->value = (ctx->value >> 1) ^ (0xEDB88320U & mask);
}
}
}

uint32_t gpt_crc32_final(const struct gpt_crc32_ctx *ctx)
{
if (ctx == NULL) {
return 0;
}

return ~crc;
return ~ctx->value;
}

/**
Expand Down Expand Up @@ -116,6 +134,7 @@ int gpt_parse_header(const uint8_t *sector, struct guid_ptable *hdr)
{
const struct guid_ptable *src;
struct guid_ptable tmp;
struct gpt_crc32_ctx crc;

if (sector == NULL || hdr == NULL) {
return -1;
Expand All @@ -134,7 +153,9 @@ int gpt_parse_header(const uint8_t *sector, struct guid_ptable *hdr)

memcpy(&tmp, src, sizeof(tmp));
tmp.hdr_crc32 = 0;
if (gpt_crc32((const uint8_t *)&tmp, src->hdr_size) != src->hdr_crc32) {
gpt_crc32_init(&crc);
gpt_crc32_update(&crc, (const uint8_t *)&tmp, src->hdr_size);
if (gpt_crc32_final(&crc) != src->hdr_crc32) {
return -1;
}

Expand Down
8 changes: 5 additions & 3 deletions src/libwolfboot.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,12 @@
#ifdef EXT_ENCRYPTED
static int encrypt_key_is_erased(const uint8_t *key, uint32_t len)
{
const volatile uint8_t *vkey = key;
uint8_t diff = 0;
uint32_t i;

for (i = 0; i < len; i++)
diff |= key[i] ^ FLASH_BYTE_ERASED;
diff |= vkey[i] ^ FLASH_BYTE_ERASED;

return diff == 0;
}
Expand All @@ -85,13 +86,14 @@ static int fallback_iv_forced = 0;

static int encrypt_key_is_valid(const uint8_t *key, uint32_t len)
{
const volatile uint8_t *vkey = key;
uint8_t has_one = 0;
uint8_t has_zero = 0;
uint32_t i;

for (i = 0; i < len; i++) {
has_one |= key[i];
has_zero |= (uint8_t)~key[i];
has_one |= vkey[i];
has_zero |= (uint8_t)~vkey[i];
}

return (has_one != 0) && (has_zero != 0);
Expand Down
4 changes: 3 additions & 1 deletion src/multiboot.c
Original file line number Diff line number Diff line change
Expand Up @@ -351,8 +351,10 @@ static void mb2_dump_header(void* mbHeader) {
MB2_DEBUG_PRINTF("Checksum: 0x%x\r\n", header->checksum);

tags = (uint8_t*)header + sizeof(*header);
if (header->header_length < sizeof(struct mb2_header))
if (header->header_length < sizeof(struct mb2_header)) {
MB2_DEBUG_PRINTF("Invalid header length\r\n");
return;
}
mb2_dump_tags(tags, header->header_length - sizeof(*header));
}
#endif /* DEBUG_MB2 */
Expand Down
Loading
Loading