mirror of
https://github.com/mytechnotalent/Embedded-Hacking.git
synced 2026-10-22 07:18:47 +02:00
Add 0x0026a custom AES-128-CMAC secure bootloader, Week 11a notebook, and README links
This commit is contained in:
1 parent
b85aaf72d6
commit
bec685d573
33 files changed
+3451
No files matched your search
@@ -0,0 +1,29 @@
|
||||
/**
|
||||
* @file aes_cmac.c
|
||||
* @brief AES-128-CMAC primitives implemented on top of the SDK Mbed TLS.
|
||||
* @author Kevin Thomas
|
||||
* @date 2026
|
||||
*
|
||||
* MIT License
|
||||
* Copyright (c) 2026 Kevin Thomas
|
||||
*/
|
||||
|
||||
#include "mbedtls/cmac.h"
|
||||
#include "mbedtls/cipher.h"
|
||||
#include "aes_cmac.h"
|
||||
|
||||
int aes128_cmac(const uint8_t *key, const uint8_t *data, size_t len,
|
||||
uint8_t *tag) {
|
||||
const mbedtls_cipher_info_t *info;
|
||||
info = mbedtls_cipher_info_from_type(MBEDTLS_CIPHER_AES_128_ECB);
|
||||
if (info == NULL) return -1;
|
||||
return mbedtls_cipher_cmac(info, key, 128, data, len, tag);
|
||||
}
|
||||
|
||||
bool cmac_tags_equal(const uint8_t *a, const uint8_t *b) {
|
||||
uint8_t diff = 0;
|
||||
for (size_t i = 0; i < AES_BLOCK_SIZE; i++) {
|
||||
diff |= (uint8_t)(a[i] ^ b[i]);
|
||||
}
|
||||
return diff == 0;
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/**
|
||||
* @file boot.c
|
||||
* @brief Secure boot console and application handoff helpers.
|
||||
* @author Kevin Thomas
|
||||
* @date 2026
|
||||
*
|
||||
* MIT License
|
||||
* Copyright (c) 2026 Kevin Thomas
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "pico/stdlib.h"
|
||||
#include "boot.h"
|
||||
#include "image.h"
|
||||
|
||||
void boot_init(void) {
|
||||
stdio_init_all();
|
||||
sleep_ms(2000);
|
||||
printf("\n=== 0x0026a secure bootloader ===\n");
|
||||
}
|
||||
|
||||
void boot_halt(const char *reason) {
|
||||
printf("BOOT FAILED: %s\n", reason);
|
||||
while (true) {
|
||||
sleep_ms(500);
|
||||
}
|
||||
}
|
||||
|
||||
void boot_launch(const fw_manifest_t *manifest) {
|
||||
printf("signature valid, entering app at 0x%08lx\n",
|
||||
(unsigned long)manifest->app_base);
|
||||
image_start(manifest->app_base);
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/**
|
||||
* @file image.c
|
||||
* @brief Loads the application stack pointer and branches to its reset vector.
|
||||
* @author Kevin Thomas
|
||||
* @date 2026
|
||||
*
|
||||
* MIT License
|
||||
* Copyright (c) 2026 Kevin Thomas
|
||||
*/
|
||||
|
||||
#include "image.h"
|
||||
|
||||
/** @brief Application reset handler signature. */
|
||||
typedef void (*image_entry_t)(void);
|
||||
|
||||
/**
|
||||
* @brief Mask interrupts and point VTOR at the incoming image.
|
||||
* @param base Vector table base address written to the VTOR register.
|
||||
* @return void No return value.
|
||||
*/
|
||||
static void halt_irq_and_rebase(uint32_t base) {
|
||||
__asm volatile ("cpsid i" ::: "memory");
|
||||
*(volatile uint32_t *)0xE000ED08U = base;
|
||||
}
|
||||
|
||||
void image_start(uint32_t vector_base) {
|
||||
uint32_t *vectors = (uint32_t *)vector_base;
|
||||
image_entry_t entry = (image_entry_t)vectors[1];
|
||||
halt_irq_and_rebase(vector_base);
|
||||
__asm volatile ("msr msp, %0" :: "r" (vectors[0]) : "memory");
|
||||
__asm volatile ("dsb\n\tisb" ::: "memory");
|
||||
entry();
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/**
|
||||
* @file main.c
|
||||
* @brief Secure bootloader entry point (verify AES-128-CMAC, then boot).
|
||||
* @author Kevin Thomas
|
||||
* @date 2026
|
||||
*
|
||||
* MIT License
|
||||
* Copyright (c) 2026 Kevin Thomas
|
||||
*
|
||||
* -----------------------------------------------------------------------------
|
||||
*
|
||||
* This file is deliberately thin: it only sequences the secure boot steps.
|
||||
* The console setup, halt reporting, and application handoff live in boot.c;
|
||||
* the CMAC verification (and its key) live in verify.c; the manifest lives in
|
||||
* manifest.c; and the raw reset-vector jump lives in image.c.
|
||||
*
|
||||
* Flash map (2 MiB, RP2350 Pico 2):
|
||||
* 0x10000000 bootloader image (this program)
|
||||
* 0x1001F000 one-sector firmware manifest (magic, size, CMAC tag)
|
||||
* 0x10020000 signed application image
|
||||
*/
|
||||
|
||||
#include "manifest.h"
|
||||
#include "boot.h"
|
||||
#include "verify.h"
|
||||
|
||||
int main(void) {
|
||||
fw_manifest_t manifest;
|
||||
boot_init();
|
||||
manifest_read(&manifest);
|
||||
if (!manifest_is_valid(&manifest)) boot_halt("manifest invalid");
|
||||
if (!verify_manifest(&manifest)) boot_halt("firmware signature invalid");
|
||||
boot_launch(&manifest);
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
/**
|
||||
* @file manifest.c
|
||||
* @brief Reads and validates the firmware manifest from XIP flash.
|
||||
* @author Kevin Thomas
|
||||
* @date 2026
|
||||
*
|
||||
* MIT License
|
||||
* Copyright (c) 2026 Kevin Thomas
|
||||
*/
|
||||
|
||||
#include "flash_layout.h"
|
||||
#include "manifest.h"
|
||||
|
||||
void manifest_read(fw_manifest_t *out) {
|
||||
const fw_manifest_t *src = (const fw_manifest_t *)FW_MANIFEST_BASE;
|
||||
*out = *src;
|
||||
}
|
||||
|
||||
bool manifest_is_valid(const fw_manifest_t *manifest) {
|
||||
if (manifest->magic != FW_MANIFEST_MAGIC) return false;
|
||||
if (manifest->version != FW_MANIFEST_VERSION) return false;
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
/**
|
||||
* @file verify.c
|
||||
* @brief Firmware authenticity verification for the secure bootloader.
|
||||
* @author Kevin Thomas
|
||||
* @date 2026
|
||||
*
|
||||
* MIT License
|
||||
* Copyright (c) 2026 Kevin Thomas
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include "flash_layout.h"
|
||||
#include "verify.h"
|
||||
#include "aes_cmac.h"
|
||||
|
||||
/** @brief AES-128 key that authenticates the application image. */
|
||||
static const uint8_t fw_key[FW_TAG_SIZE] = {
|
||||
0x49, 0x72, 0x6F, 0x6E, 0x4E, 0x65, 0x74, 0x42,
|
||||
0x6F, 0x6F, 0x74, 0x4B, 0x65, 0x79, 0x21, 0x21
|
||||
};
|
||||
|
||||
bool verify_manifest(const fw_manifest_t *manifest) {
|
||||
const uint8_t *base = (const uint8_t *)manifest->app_base;
|
||||
uint8_t computed[FW_TAG_SIZE];
|
||||
int rc = aes128_cmac(fw_key, base, manifest->app_size, computed);
|
||||
if (rc != 0) return false;
|
||||
return cmac_tags_equal(computed, manifest->tag);
|
||||
}
|
||||
Reference in new issue
Block a user