Skip to content

Commit 87847ff

Browse files
authored
Merge pull request #18 from gpappasv/feature/security
[bootloader/auth] Adding asymmetric encryption and authentication of fw
2 parents d518a76 + fe4da51 commit 87847ff

34 files changed

+36122
-93
lines changed

README.md

+5-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# Description of repository
2-
This is a repository that a custom stm32 bootloader is being developed.
2+
This is a repository that a custom lightweight stm32 bootloader is being developed.
33

44
The bootloader is designed to have an easily portable core, by just replacing the driver layer, with the board specific one.
55
The current implementation focuses on the STM32F401RE board.
@@ -14,11 +14,14 @@ The current implementation focuses on the STM32F401RE board.
1414
# Bootloader features
1515
- Adaptable application space.
1616
- Checksum verification, before booting the application.
17-
- Authentication of the application. (Secure boot)
17+
- Authentication of the application. (Secure boot). ECDSA is used.
1818
- Easy to port to other microcontrollers.
1919
- Recovery mode (firmware update support).
2020
- Backup image recovery. If the main application is broken, the secondary is tested.
2121
- Secure communication through the custom communication protocol.
22+
- Bootloader flash used: ~14.5kB
23+
24+
NOTE: More in-depth documentation about how the bootloader works can be found under **docs**.
2225

2326
# Configuration
2427
TODO.

projects/app/boards/stm32f401re/STM32F401RETx_FLASH.ld

+2-2
Original file line numberDiff line numberDiff line change
@@ -59,10 +59,10 @@ _Min_Heap_Size = 0x200; /* required amount of heap */
5959
_Min_Stack_Size = 0x400; /* required amount of stack */
6060

6161
/* Image header info */
62-
__header_size_bytes__ = 40;
62+
__header_size_bytes__ = 72;
6363
__header_crc_size_bytes__ = 4;
6464
__header_fw_ver_size_bytes__ = 4;
65-
__header_hash_size_bytes__ = 32;
65+
__header_hash_size_bytes__ = 64;
6666

6767
/* Primary app info */
6868
__flash_app_start__ = 0x08008000;

projects/bootloader/CMakeLists.txt

+6-1
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ message(STATUS "CMAKE_TOOLCHAIN_FILE is: ${CMAKE_TOOLCHAIN_FILE}")
4545

4646
# --- HAL drivers ---
4747
include(${GIT_ROOT_DIR}/projects/bootloader/hal-drivers.cmake)
48+
include(${GIT_ROOT_DIR}/projects/bootloader/uECC-lib.cmake)
4849

4950
# --- Application code ---
5051
# List of bootloader's source files
@@ -66,13 +67,16 @@ set(SRC_FILES
6667
${GIT_ROOT_DIR}/projects/bootloader/src/drivers/mpu/mpu_driver.c
6768
${GIT_ROOT_DIR}/projects/bootloader/src/com_protocol/com_protocol.c
6869
${GIT_ROOT_DIR}/projects/bootloader/src/firmware_update/firmware_update.c
70+
${GIT_ROOT_DIR}/projects/bootloader/src/authentication/authentication.c
71+
${GIT_ROOT_DIR}/projects/bootloader/src/authentication/sha256.c
6972
)
7073

7174
# Build the executable based on the source files
7275
add_executable(${EXECUTABLE} ${SRC_FILES})
7376

7477
# Link all external libraries to executable
7578
target_link_libraries(${EXECUTABLE} hal_drivers)
79+
target_link_libraries(${EXECUTABLE} uECC)
7680

7781
# List of compiler defines, prefix with -D compiler option
7882
target_compile_definitions(${EXECUTABLE} PRIVATE
@@ -91,6 +95,7 @@ target_include_directories(${EXECUTABLE} PRIVATE
9195
${GIT_ROOT_DIR}/projects/bootloader/src/drivers
9296
${GIT_ROOT_DIR}/projects/bootloader/src/com_protocol
9397
${GIT_ROOT_DIR}/projects/bootloader/src/firmware_update
98+
${GIT_ROOT_DIR}/projects/bootloader/src/authentication
9499
)
95100

96101
# Compiler options
@@ -104,7 +109,7 @@ target_compile_options(${EXECUTABLE} PRIVATE
104109
-ffunction-sections
105110
-fstack-usage
106111
# Optimise for size
107-
#-Os
112+
-Os
108113
)
109114

110115
get_target_property(COMPILE_OPTIONS ${EXECUTABLE} COMPILE_OPTIONS)

projects/bootloader/README.md

+4-1
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,7 @@ The bootloader software architecture can be found under docs, in high level desi
2727
is that, changing the implementations under src/drivers to be compatible with another device, should make the porting
2828
of the bootloader smooth.
2929

30-
TODO: GPA: provide a full bootloader architecture documentation when finished!
30+
TODO: GPA: provide a full bootloader architecture documentation when finished!
31+
32+
# Steps to use the bootloader security features (authentication)
33+

projects/bootloader/boards/stm32f401re/STM32F401RETx_FLASH.ld

+2-2
Original file line numberDiff line numberDiff line change
@@ -59,10 +59,10 @@ _Min_Heap_Size = 0x200; /* required amount of heap */
5959
_Min_Stack_Size = 0x400; /* required amount of stack */
6060

6161
/* Image header info; This should be used as is */
62-
__header_size_bytes__ = 40;
62+
__header_size_bytes__ = 72;
6363
__header_crc_size_bytes__ = 4;
6464
__header_fw_ver_size_bytes__ = 4;
65-
__header_hash_size_bytes__ = 32;
65+
__header_hash_size_bytes__ = 64;
6666

6767
/* Primary app info; This should be adjusted based on the app needs */
6868
__flash_app_start__ = 0x08008000;

projects/bootloader/hal-drivers.cmake

+3-1
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,9 @@ target_compile_options(hal_drivers PRIVATE -Wno-unused-parameter -mthumb
4242
-Wextra
4343
-fdata-sections
4444
-ffunction-sections
45-
-fstack-usage)
45+
-fstack-usage
46+
-Os
47+
)
4648

4749
target_link_options(hal_drivers PRIVATE
4850
-T${LINKER_FILE}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
/**
2+
* @file authentication.c
3+
* @brief This module is about the authentication of the bootloader. It provides the necessary functions to authenticate
4+
* the application image. The Elliptic Curve Digital Signature Algorithm (ECDSA) is used to sign the application.
5+
* The public key is stored in the bootloader, and the signature is stored in the application image. The bootloader
6+
* will verify the signature of the application image before jumping to it.
7+
*
8+
* The implementation of the ECDSA is not hardware accelerated.
9+
* @version 0.1
10+
* @date 2024-07-06
11+
*
12+
* @copyright Copyright (c) 2024
13+
*
14+
*/
15+
16+
// --- includes --------------------------------------------------------------------------------------------------------
17+
#include "authentication.h"
18+
19+
#include "ecdsa_pub_key.h"
20+
#include "uECC.h"
21+
#include "sha256.h"
22+
23+
#include <stdint.h>
24+
#include <string.h>
25+
#include <stdio.h>
26+
#include <stdbool.h>
27+
28+
// --- external variables ----------------------------------------------------------------------------------------------
29+
extern const uint8_t ecdsa_public_key[];
30+
31+
// --- function definitions --------------------------------------------------------------------------------------------
32+
/**
33+
* @brief Function to verify the signature of the application image. The signature is verified using the ECDSA
34+
* algorithm.
35+
*
36+
* @param app_image_start_addr The start address of the application image.
37+
* @param app_image_size_bytes The size of the application image in bytes.
38+
* @param signature The signature of the application image.
39+
*
40+
* @return true The signature is valid.
41+
* @return false The signature is invalid.
42+
*/
43+
bool
44+
authenticate_application(uint32_t app_image_start_addr, uint32_t app_image_size_bytes, const uint8_t *signature)
45+
{
46+
47+
// Calculate the SHA-256 hash of the application image
48+
SHA256_CTX ctx;
49+
BYTE hash[SHA256_BLOCK_SIZE];
50+
51+
sha256_init(&ctx);
52+
sha256_update(&ctx, (const BYTE *)app_image_start_addr, app_image_size_bytes);
53+
sha256_final(&ctx, hash);
54+
55+
// First check if public key is valid
56+
if (!uECC_valid_public_key(ecdsa_public_key, uECC_secp256r1()))
57+
{
58+
return false;
59+
}
60+
61+
// Verify the signature using the ECDSA algorithm
62+
int ret = uECC_verify(ecdsa_public_key, hash, sizeof(hash), signature, uECC_secp256r1());
63+
64+
// True if the signature is valid
65+
return ret == 1;
66+
}
67+
68+
/**
69+
* @brief Function to get the public key used for verifying the signature of the application image. The public key is
70+
* stored in the bootloader.
71+
*
72+
* @return uint8_t* The public key used for verifying the signature.
73+
*/
74+
const uint8_t *
75+
get_public_key(void)
76+
{
77+
return ecdsa_public_key;
78+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/**
2+
* @file authentication.h
3+
* @brief This module is about the authentication of the bootloader. It provides the necessary functions to authenticate
4+
* the application image. The Elliptic Curve Digital Signature Algorithm (ECDSA) is used to sign the application.
5+
* The public key is stored in the bootloader, and the signature is stored in the application image. The
6+
* bootloader will verify the signature of the application image before jumping to it.
7+
*
8+
* The implementation of the ECDSA is not hardware accelerated.
9+
* @version 0.1
10+
* @date 2024-07-06
11+
*
12+
* @copyright Copyright (c) 2024
13+
*
14+
*/
15+
16+
// --- includes --------------------------------------------------------------------------------------------------------
17+
#include <stdint.h>
18+
#include <stdbool.h>
19+
20+
// --- function declarations -------------------------------------------------------------------------------------------
21+
/**
22+
* @brief Function to verify the signature of the application image. The signature is verified using the ECDSA
23+
* algorithm.
24+
*
25+
* @param app_image_start_addr: The start address of the application image.
26+
* @param app_image_size_bytes: The size of the application image in bytes.
27+
* @param signature: The signature of the application image.
28+
*
29+
* @return true: The signature is valid.
30+
* @return false: The signature is invalid.
31+
*/
32+
bool authenticate_application(uint32_t app_image_start_addr,
33+
uint32_t app_image_size_bytes,
34+
const uint8_t *der_signature);
35+
36+
/**
37+
* @brief Function to get the public key used for verifying the signature of the application image. The public key is
38+
* stored in the bootloader.
39+
*
40+
* @return uint8_t*: The public key used for verifying the signature.
41+
*/
42+
const uint8_t *get_public_key(void);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
2+
/**
3+
* @file ecdsa_pub_key.h
4+
* @brief ECDSA public key in C array format
5+
* @version 0.1
6+
* @date 2024-06-09
7+
*
8+
* @copyright Copyright (c) 2024
9+
*
10+
*/
11+
#ifndef ECDSA_PUB_KEY_H
12+
#define ECDSA_PUB_KEY_H
13+
14+
// --- includes --------------------------------------------------------------------------------------------------------
15+
#include <stdint.h>
16+
17+
// --- constants -------------------------------------------------------------------------------------------------------
18+
const uint8_t ecdsa_public_key[] = {
19+
0x4D, 0xD9, 0x40, 0x4C, 0x97, 0xF7, 0x53, 0x9D, 0xEA, 0x4C, 0xCC, 0x8B, 0xB9, 0x12, 0x60, 0xED, 0x35, 0xC1, 0x24, 0xB7, 0x0C, 0xDD, 0xFC, 0x1A, 0xAC, 0x4B, 0x80, 0x4B, 0xE6, 0xFA, 0xAB, 0xA0, 0x74, 0xC4, 0xBA, 0x52, 0x2D, 0x6E, 0xB5, 0x07, 0x51, 0x0F, 0x2D, 0x4D, 0x10, 0xD2, 0xC7, 0x75, 0xAC, 0x92, 0x72, 0x61, 0xA8, 0xDD, 0x96, 0xD2, 0x47, 0xAC, 0x33, 0xBB, 0x5E, 0x26, 0x3F, 0xA8
20+
};
21+
22+
#endif // ECDSA_PUB_KEY_H

0 commit comments

Comments
 (0)