diff --git a/GD32E50X_BOOT.cbuild-pack.yml b/GD32E50X_BOOT.cbuild-pack.yml index 52d4e5a..0d19c98 100644 --- a/GD32E50X_BOOT.cbuild-pack.yml +++ b/GD32E50X_BOOT.cbuild-pack.yml @@ -1,14 +1,4 @@ cbuild-pack: resolved-packs: - resolved-pack: ARM::CMSIS@6.1.0 - selected-by-pack: - - ARM::CMSIS - - resolved-pack: ARM::CMSIS-DSP@1.16.2 - selected-by-pack: - - ARM::CMSIS-DSP - - resolved-pack: ARM::CMSIS-NN@4.1.0 - selected-by-pack: - - ARM::CMSIS-NN - resolved-pack: GigaDevice::GD32E50x_DFP@1.9.0 - selected-by-pack: - - GigaDevice::GD32E50x_DFP diff --git a/GD32E50X_BOOT/device/SpiOta.cpp b/GD32E50X_BOOT/device/SpiOta.cpp index 08def4e..4b7227b 100644 --- a/GD32E50X_BOOT/device/SpiOta.cpp +++ b/GD32E50X_BOOT/device/SpiOta.cpp @@ -442,10 +442,7 @@ void SpiOta::isrProcessFrame() { s_hasCachedResp = true; } if (s_otaHandler != nullptr) { s_otaHandler->resetToIdle(); } - s_otaSessionActive = false; - s_otaDataWi = 0U; - s_otaDataRi = 0U; - s_otaDataCnt = 0U; + /* resetToIdle 已 clearOtaSessionQueues;此处再清 RX 流边界 */ s_rxStreamLen = 0U; return; } @@ -752,6 +749,18 @@ void SpiOta::configureExti() { nvic_irq_enable(EXTI10_15_IRQn, 1U, 1U); } +void SpiOta::clearOtaSessionQueues() { + /* ISR 与主循环都可能碰 DATA 队列/CREDIT,关中断做原子清理。 */ + uint32_t primask = enterCritical(); + s_otaDataWi = 0U; + s_otaDataRi = 0U; + s_otaDataCnt = 0U; + s_otaSessionActive = false; + /* 恢复 CREDIT,避免失败后 CREDIT=0 卡住后续握手/重传。 */ + g_localCredit = CONFIG_OTA_FLASH_BUF_SLOTS; + exitCritical(primask); +} + void SpiOta::init() { s_csActive = false; s_rxStreamLen = 0U; @@ -773,6 +782,7 @@ void SpiOta::init() { s_otaDataWi = 0U; s_otaDataRi = 0U; s_otaDataCnt = 0U; + g_localCredit = CONFIG_OTA_FLASH_BUF_SLOTS; configureGpio(); configureDma(); configureSpi0(); diff --git a/GD32E50X_BOOT/device/SpiOta.h b/GD32E50X_BOOT/device/SpiOta.h index 22265ff..d306d9c 100644 --- a/GD32E50X_BOOT/device/SpiOta.h +++ b/GD32E50X_BOOT/device/SpiOta.h @@ -79,6 +79,12 @@ public: /** @brief ISR DATA 队列中待处理包数(供 OTA.cpp 计算 CREDIT 用)。 */ static u8 pendingDataCount(); + /** + * @brief OTA 会话完整复位(CANCEL / resetToIdle / 进 BOOT 共用)。 + * 清空 ISR DATA 队列、会话标志,并恢复 g_localCredit。 + */ + static void clearOtaSessionQueues(); + /** @brief 主循环入队 TX 后装载 DMA + 更新 DATA_READY(擦除中途刷 WAIT 用)。 */ static void servicePendingTx(); diff --git a/GD32E50X_BOOT/main.cpp b/GD32E50X_BOOT/main.cpp index b6db3e7..7419b8f 100644 --- a/GD32E50X_BOOT/main.cpp +++ b/GD32E50X_BOOT/main.cpp @@ -248,10 +248,33 @@ void BootloaderSystem::run() { #if DEBUG_PRINT printf("[BOOT] path=stay_in_ota\r\n"); #endif + /* stay_in_ota 期间若 OTA 会话结束(被 CANCEL 或超时回 IDLE), + * 必须主动跳回 APP,否则电机会永久停在 Bootloader, + * 表现为取消 OTA 后 CAN 业务帧再无 ACK、整条总线"通信不通"。 + * 旧实现是 while(1) 无退出条件,且 OTA.cpp 的 CANCEL 分支只置 IDLE + * 不跳 APP,连 OTA_TIMEOUT 兜底也因 ota_time 不再累加而失效。 */ uint32_t hb_ota = 0U; + uint32_t idle_since = 0U; + bool was_active = false; while (1) { pollAllLinks(); heartbeatPrint(hb_ota, 1U, "stay_in_ota"); + + const bool active_now = ota.isActive(); + if (active_now) { + was_active = true; + idle_since = 0U; + } else if (was_active) { + /* 曾进入 OTA,现在回到 IDLE(CANCEL/超时/完成)→ 跳回 APP */ +#if DEBUG_PRINT + printf("[BOOT] stay_in_ota -> ota ended, jump app\r\n"); +#endif + if (verifyAppCrc(APPLATEST_START_ADDR)) { + ota.jumpToApplication(); + } + /* jumpToApplication 失败(CRC/向量不合法)则留在 BOOT */ + was_active = false; + } delay_1ms(1); } } else { diff --git a/GD32E50X_BOOT/sys/OTA.cpp b/GD32E50X_BOOT/sys/OTA.cpp index 123dbff..4f0ee20 100644 --- a/GD32E50X_BOOT/sys/OTA.cpp +++ b/GD32E50X_BOOT/sys/OTA.cpp @@ -256,6 +256,30 @@ static inline void send_structured_ack(uint32_t seq_or_flag) { * * @return 无。 */ +/** + * @brief 完整复位 OTA 会话到 IDLE(密钥/缓冲/CREDIT/SPI 队列一并清理)。 + */ +void OTAHandler::resetToIdle() { + ota_state = OTA_STATE_IDLE; + ota_time = 0; + ota_error = OTA_ERROR_NONE; + received_size = 0; + expected_size = 0; + memset(current_K_session, 0, sizeof(current_K_session)); + memset(nonce_server, 0, sizeof(nonce_server)); + memset(&aes_ctx, 0, sizeof(aes_ctx)); + pending_flash_erase = false; + pending_app_jump = false; + pending_finish_ack = false; + pending_finish_ota = false; + flash_buf_wi = 0U; + flash_buf_ri = 0U; + flash_buf_cnt = 0U; + next_expected_packet = 0U; + /* SPI 侧:清 ISR DATA 队列 + 恢复 g_localCredit,避免失败后半会话残留 */ + SpiOta::clearOtaSessionQueues(); +} + void OTAHandler::init() { /** 默认回包出口先绑定到 CAN。 */ transport_send = ota_can_sender; @@ -341,8 +365,8 @@ void OTAHandler::process() { pending_finish_ota = false; if (!validateApplication()) { + resetToIdle(); ota_error = OTA_ERROR_FLASH_ERROR; - ota_state = OTA_STATE_IDLE; send_error_frame(0xFFFFFFFFU, OTA_ERROR_FLASH_ERROR); } else { /** 计算并写入 A区固件 CRC32,供后续启动时完整性校验。 */ @@ -395,12 +419,11 @@ void OTAHandler::process() { if (ota_time > OTA_TIMEOUT) { /** * OTA 会话超时: - * - 复位状态机到空闲态 + * - 完整复位状态机到空闲态(含 CREDIT/缓冲) * - 上报超时错误 * - 如果当前主应用仍有效,则尝试回到主应用运行 */ - ota_time = 0; - ota_state = OTA_STATE_IDLE; + resetToIdle(); ota_error = OTA_ERROR_TIMEOUT; volatile u32 *flash_ptr = (volatile u32 *)n_APP_LATEST_CHECK_ADDR; @@ -771,12 +794,21 @@ void OTAHandler::handleLinkMessage(ota_link_msg_type_t type, u8 *data, u8 len) { } #endif /** - * CANCEL:无条件终止当前 OTA 会话,回到空闲态。 + * CANCEL:无条件终止当前 OTA 会话,完整回到空闲态。 + * 走 resetToIdle():清密钥/缓冲/CREDIT/SPI DATA 队列,避免半会话残留。 + * 仅置 IDLE 不跳 APP:跳转由 main.cpp stay_in_ota 循环检测 ota.isActive() + * 变 false 后统一执行,避免在此处关中断/校验与 ISR 上下文冲突。 + * 回 ACK 便于 ESP32 确认远端已清理(无 payload 时也 ACK)。 */ if (type == OTA_LINK_MSG_CANCEL) { - ota_state = OTA_STATE_IDLE; - ota_time = 0; - ota_error = OTA_ERROR_NONE; + resetToIdle(); +#if DEBUG_PRINT + printf("[OTA] CANCEL -> resetToIdle\r\n"); +#endif + { + u8 cancel_ack[1] = {0x03U}; + send_ack_frame(1, cancel_ack); + } return; } /** @@ -865,8 +897,8 @@ void OTAHandler::handleLinkMessage(ota_link_msg_type_t type, u8 *data, u8 len) { } else { u32 offset = receive_packet_num * OTA_PACKET_SIZE; if (offset >= expected_size) { + resetToIdle(); ota_error = OTA_ERROR_INVALID_SIZE; - ota_state = OTA_STATE_IDLE; send_error_frame(receive_packet_num, OTA_ERROR_INVALID_SIZE); return; } @@ -936,8 +968,8 @@ void OTAHandler::handleLinkMessage(ota_link_msg_type_t type, u8 *data, u8 len) { received_size = 0; next_expected_packet = 0U; } else { + resetToIdle(); ota_error = OTA_ERROR_INVALID_SIZE; - ota_state = OTA_STATE_IDLE; send_error_frame(0U, OTA_ERROR_INVALID_SIZE); return; } @@ -964,8 +996,8 @@ void OTAHandler::handleLinkMessage(ota_link_msg_type_t type, u8 *data, u8 len) { return; } + resetToIdle(); ota_error = OTA_ERROR_INVALID_PACKET; - ota_state = OTA_STATE_IDLE; send_error_frame(0xFFFFFFFFU, OTA_ERROR_INVALID_PACKET); return; } @@ -978,12 +1010,12 @@ void OTAHandler::handleLinkMessage(ota_link_msg_type_t type, u8 *data, u8 len) { send_wait_frame(1, wait_hint); } else { - ota_error = OTA_ERROR_INVALID_PACKET; #if DEBUG_PRINT printf("[OTA] DATA ignored/INV_PKT: type=%u len=%u state=%u\r\n", (unsigned)type, (unsigned)len, (unsigned)ota_state); #endif - ota_state = OTA_STATE_IDLE; + resetToIdle(); + ota_error = OTA_ERROR_INVALID_PACKET; send_error_frame(0xFFFFFFFFU, OTA_ERROR_INVALID_PACKET); } } @@ -1050,8 +1082,8 @@ void OTAHandler::handleLinkMessage(ota_link_msg_type_t type, u8 *data, u8 len) { } if (memcmp(plaintext, expected, 16) != 0) { + resetToIdle(); ota_error = OTA_ERROR_INVALID_KEY; - ota_state = OTA_STATE_IDLE; send_error_frame(0xFFFFFFFFU, OTA_ERROR_INVALID_KEY); return; } @@ -1062,8 +1094,8 @@ void OTAHandler::handleLinkMessage(ota_link_msg_type_t type, u8 *data, u8 len) { } /** 其它情况一律判定为握手非法。 */ else { + resetToIdle(); ota_error = OTA_ERROR_INVALID_HANDSHAKE; - ota_state = OTA_STATE_IDLE; send_error_frame(0xFFFFFFFFU, OTA_ERROR_INVALID_HANDSHAKE); return; } diff --git a/GD32E50X_BOOT/sys/OTA.h b/GD32E50X_BOOT/sys/OTA.h index d9d6ac7..09a7635 100644 --- a/GD32E50X_BOOT/sys/OTA.h +++ b/GD32E50X_BOOT/sys/OTA.h @@ -84,31 +84,15 @@ class OTAHandler { u8 getState() const { return (u8)ota_state; } /** - * @brief 重置 OTA 状态机到 IDLE,用于进BOOT命令等场景。 + * @brief 重置 OTA 状态机到 IDLE(完整清理会话上下文)。 * - * 上位机发 0xB0 进BOOT命令时,如果设备已在 BOOT 中, - * 需要将 OTA 状态机重置为 IDLE,确保后续握手能正常进行。 + * 用于:0xB0 进 BOOT、SPI/CAN CANCEL、握手/认证失败、会话超时等。 + * 除状态枚举外,清密钥/缓冲/pending,并恢复 g_localCredit, + * 避免失败后卡在 WAITING_* 或 CREDIT=0 导致下次握手异常。 * * @return 无。 */ - void resetToIdle() { - ota_state = OTA_STATE_IDLE; - ota_time = 0; - ota_error = OTA_ERROR_NONE; - received_size = 0; - expected_size = 0; - memset(current_K_session, 0, sizeof(current_K_session)); - memset(nonce_server, 0, sizeof(nonce_server)); - memset(&aes_ctx, 0, sizeof(aes_ctx)); - pending_flash_erase = false; - pending_app_jump = false; - pending_finish_ack = false; - pending_finish_ota = false; - flash_buf_wi = 0U; - flash_buf_ri = 0U; - flash_buf_cnt = 0U; - next_expected_packet = 0U; - } + void resetToIdle(); /** * @brief 设置当前底层回包发送函数。 diff --git a/GD32E50X_BOOT/sys/aes128.cpp b/GD32E50X_BOOT/sys/aes128.cpp index 10b1e17..e2af516 100644 --- a/GD32E50X_BOOT/sys/aes128.cpp +++ b/GD32E50X_BOOT/sys/aes128.cpp @@ -1,7 +1,7 @@ #include "aes128.h" /** S盒 (Substitution Box) */ -static const u8 sbox[256] = { +static const uint8_t sbox[256] = { 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, 0xb7, 0xfd, 0x93, 0x26, @@ -26,7 +26,7 @@ static const u8 sbox[256] = { 0xb0, 0x54, 0xbb, 0x16}; /** 逆S盒 (InvSBox) */ -const u8 inv_sbox[256] = { +const uint8_t inv_sbox[256] = { 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb, 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb, 0x54, 0x7b, 0x94, 0x32, @@ -51,11 +51,11 @@ const u8 inv_sbox[256] = { 0x55, 0x21, 0x0c, 0x7d}; /** 轮常量 */ -static const u8 rcon[10] = {0x01, 0x02, 0x04, 0x08, 0x10, +static const uint8_t rcon[10] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36}; /** 伽罗瓦域乘法 (xtime) - 确保正确 */ -static u8 xtime(u8 x) { return (x << 1) ^ (((x >> 7) & 1) * 0x1b); } +static uint8_t xtime(uint8_t x) { return (x << 1) ^ (((x >> 7) & 1) * 0x1b); } /** 关键修复:AES状态矩阵是列优先排列! */ /** 内存布局应该是:s00, s10, s20, s30, s01, s11, s21, s31, ... */ @@ -69,8 +69,8 @@ static u8 xtime(u8 x) { return (x << 1) ^ (((x >> 7) & 1) * 0x1b); } * @param round_key 指向 16 字节轮密钥的指针。 * @return 无。 */ -void add_round_key(u8 *state, const u8 *round_key) { - for (u8 i = 0; i < 16; i++) { +void add_round_key(uint8_t *state, const uint8_t *round_key) { + for (uint8_t i = 0; i < 16; i++) { state[i] ^= round_key[i]; } } @@ -82,8 +82,8 @@ void add_round_key(u8 *state, const u8 *round_key) { * @param state 指向 16 字节状态矩阵的指针。 * @return 无。 */ -void sub_bytes(u8 *state) { - for (u8 i = 0; i < 16; i++) { +void sub_bytes(uint8_t *state) { + for (uint8_t i = 0; i < 16; i++) { state[i] = sbox[state[i]]; } } @@ -95,8 +95,8 @@ void sub_bytes(u8 *state) { * @param state 指向 16 字节状态矩阵的指针。 * @return 无。 */ -void shift_rows(u8 *state) { - u8 temp; +void shift_rows(uint8_t *state) { + uint8_t temp; /** AES状态矩阵(列优先): */ /** 列0: state[0], state[1], state[2], state[3] -> 行0,1,2,3 */ @@ -135,11 +135,11 @@ void shift_rows(u8 *state) { * @param state 指向 16 字节状态矩阵的指针。 * @return 无。 */ -void mix_columns(u8 *state) { - u8 a[4], b[4]; +void mix_columns(uint8_t *state) { + uint8_t a[4], b[4]; /** 处理每一列 */ - for (u8 col = 0; col < 4; col++) { + for (uint8_t col = 0; col < 4; col++) { /** 获取当前列的4个字节 */ a[0] = state[col * 4 + 0]; a[1] = state[col * 4 + 1]; @@ -161,9 +161,9 @@ void mix_columns(u8 *state) { } /** 伽罗瓦域乘法 (用于逆列混合) */ -static u8 gf_mul(u8 a, u8 b) { - u8 p = 0; - u8 high_bit; +static uint8_t gf_mul(uint8_t a, uint8_t b) { + uint8_t p = 0; + uint8_t high_bit; while (b) { if (b & 1) { @@ -186,8 +186,8 @@ static u8 gf_mul(u8 a, u8 b) { * @param state 指向 16 字节状态矩阵的指针。 * @return 无。 */ -void inv_sub_bytes(u8 *state) { - for (u8 i = 0; i < 16; i++) { +void inv_sub_bytes(uint8_t *state) { + for (uint8_t i = 0; i < 16; i++) { state[i] = inv_sbox[state[i]]; } } @@ -199,8 +199,8 @@ void inv_sub_bytes(u8 *state) { * @param state 指向 16 字节状态矩阵的指针。 * @return 无。 */ -void inv_shift_rows(u8 *state) { - u8 temp; +void inv_shift_rows(uint8_t *state) { + uint8_t temp; /** 第2行右移1位 */ temp = state[13]; @@ -232,11 +232,11 @@ void inv_shift_rows(u8 *state) { * @param state 指向 16 字节状态矩阵的指针。 * @return 无。 */ -void inv_mix_columns(u8 *state) { - u8 a[4], b[4]; +void inv_mix_columns(uint8_t *state) { + uint8_t a[4], b[4]; /** 处理每一列 */ - for (u8 col = 0; col < 4; col++) { + for (uint8_t col = 0; col < 4; col++) { /** 获取当前列的4个字节 */ a[0] = state[col * 4 + 0]; a[1] = state[col * 4 + 1]; @@ -263,8 +263,8 @@ void inv_mix_columns(u8 *state) { /** 密钥扩展 - 修复为标准实现 */ static void key_expansion(aes128_context *ctx) { - u8 temp[4]; - u8 i, rcon_iter = 0; + uint8_t temp[4]; + uint8_t i, rcon_iter = 0; /** 复制原始密钥到第一轮密钥 */ memcpy(ctx->round_keys[0], ctx->key, 16); @@ -278,7 +278,7 @@ static void key_expansion(aes128_context *ctx) { temp[3] = ctx->round_keys[i - 1][15]; /** 字循环 (RotWord) */ - u8 t = temp[0]; + uint8_t t = temp[0]; temp[0] = temp[1]; temp[1] = temp[2]; temp[2] = temp[3]; @@ -300,7 +300,7 @@ static void key_expansion(aes128_context *ctx) { ctx->round_keys[i][3] = ctx->round_keys[i - 1][3] ^ temp[3]; /** 生成其他列 */ - for (u8 j = 1; j < 4; j++) { + for (uint8_t j = 1; j < 4; j++) { ctx->round_keys[i][j * 4 + 0] = ctx->round_keys[i][(j - 1) * 4 + 0] ^ ctx->round_keys[i - 1][j * 4 + 0]; @@ -324,7 +324,7 @@ static void key_expansion(aes128_context *ctx) { * @param key 指向 16 字节密钥的指针。 * @return 无。 */ -void aes128_set_key(aes128_context *ctx, const u8 *key) { +void aes128_set_key(aes128_context *ctx, const uint8_t *key) { memcpy(ctx->key, key, AES128_KEY_LEN); key_expansion(ctx); } @@ -337,7 +337,7 @@ void aes128_set_key(aes128_context *ctx, const u8 *key) { * @param output 指向输出缓冲区的指针。 * @return 无。 */ -void aes128_encrypt_block(aes128_context *ctx, const u8 *input, u8 *output) { +void aes128_encrypt_block(aes128_context *ctx, const uint8_t *input, uint8_t *output) { /** 复制输入到状态 */ memcpy(ctx->state, input, AES_BLOCK_SIZE); @@ -345,7 +345,7 @@ void aes128_encrypt_block(aes128_context *ctx, const u8 *input, u8 *output) { add_round_key(ctx->state, ctx->round_keys[0]); /** 9轮标准轮 */ - for (u8 round = 1; round <= 9; round++) { + for (uint8_t round = 1; round <= 9; round++) { sub_bytes(ctx->state); shift_rows(ctx->state); mix_columns(ctx->state); @@ -369,8 +369,8 @@ void aes128_encrypt_block(aes128_context *ctx, const u8 *input, u8 *output) { * @param output 指向 48 字节输出缓冲区的指针。 * @return 无。 */ -void aes128_ecb_encrypt_48bytes(aes128_context *ctx, const u8 *input, - u8 *output) { +void aes128_ecb_encrypt_48bytes(aes128_context *ctx, const uint8_t *input, + uint8_t *output) { /** 分3块加密 (48 = 16 * 3) */ aes128_encrypt_block(ctx, input, output); aes128_encrypt_block(ctx, input + 16, output + 16); @@ -385,7 +385,7 @@ void aes128_ecb_encrypt_48bytes(aes128_context *ctx, const u8 *input, * @param output 指向输出缓冲区的指针。 * @return 无。 */ -void aes128_decrypt_block(aes128_context *ctx, const u8 *input, u8 *output) { +void aes128_decrypt_block(aes128_context *ctx, const uint8_t *input, uint8_t *output) { /** 复制输入到状态 */ memcpy(ctx->state, input, AES_BLOCK_SIZE); @@ -393,7 +393,7 @@ void aes128_decrypt_block(aes128_context *ctx, const u8 *input, u8 *output) { add_round_key(ctx->state, ctx->round_keys[10]); /** 9轮标准解密轮 */ - for (u8 round = 9; round >= 1; round--) { + for (uint8_t round = 9; round >= 1; round--) { inv_shift_rows(ctx->state); inv_sub_bytes(ctx->state); add_round_key(ctx->state, ctx->round_keys[round]); @@ -417,8 +417,8 @@ void aes128_decrypt_block(aes128_context *ctx, const u8 *input, u8 *output) { * @param output 指向 48 字节输出缓冲区的指针。 * @return 无。 */ -void aes128_ecb_decrypt_48bytes(aes128_context *ctx, const u8 *input, - u8 *output) { +void aes128_ecb_decrypt_48bytes(aes128_context *ctx, const uint8_t *input, + uint8_t *output) { /** 分3块解密 (48 = 16 * 3) */ aes128_decrypt_block(ctx, input, output); aes128_decrypt_block(ctx, input + 16, output + 16); @@ -434,11 +434,11 @@ void aes128_ecb_decrypt_48bytes(aes128_context *ctx, const u8 *input, * @retval 1 验证成功。 * @retval 0 验证失败。 */ -u8 aes128_verify_encryption(aes128_context *ctx, const u8 *original_data, +uint8_t aes128_verify_encryption(aes128_context *ctx, const uint8_t *original_data, size_t length) { - u8 temp_ciphertext[48]; - u8 temp_plaintext[48]; - u8 result = 1; /**< 1表示验证成功,0表示失败 */ + uint8_t temp_ciphertext[48]; + uint8_t temp_plaintext[48]; + uint8_t result = 1; /**< 1表示验证成功,0表示失败 */ /** 1. 加密原始数据 */ aes128_ecb_encrypt_48bytes(ctx, original_data, temp_ciphertext); diff --git a/GD32E50X_BOOT/sys/aes128.h b/GD32E50X_BOOT/sys/aes128.h index b29a0a7..48d51e0 100644 --- a/GD32E50X_BOOT/sys/aes128.h +++ b/GD32E50X_BOOT/sys/aes128.h @@ -1,6 +1,11 @@ #ifndef __AES_H #define __AES_H -#include "cstdint" + +/** + * AES-128 公共头:自包含,不依赖 config.h 的 u8 别名或 include 顺序。 + */ +#include +#include #include /** @brief AES-128 密钥长度,单位为字节。 */ @@ -13,9 +18,9 @@ * @brief AES-128 上下文。 */ typedef struct { - u8 key[AES128_KEY_LEN]; /**< 原始 128bit 密钥。 */ - u8 round_keys[11][16]; /**< 扩展后的 11 组轮密钥。 */ - u8 state[AES_BLOCK_SIZE]; /**< 当前状态矩阵。 */ + uint8_t key[AES128_KEY_LEN]; /**< 原始 128bit 密钥。 */ + uint8_t round_keys[11][16]; /**< 扩展后的 11 组轮密钥。 */ + uint8_t state[AES_BLOCK_SIZE]; /**< 当前状态矩阵。 */ } aes128_context; /** @@ -25,7 +30,7 @@ typedef struct { * @param round_key 指向 16 字节轮密钥的指针。 * @return 无。 */ -void add_round_key(u8 *state, const u8 *round_key); +void add_round_key(uint8_t *state, const uint8_t *round_key); /** * @brief 对状态矩阵执行 SubBytes 变换。 @@ -33,7 +38,7 @@ void add_round_key(u8 *state, const u8 *round_key); * @param state 指向 16 字节状态矩阵的指针。 * @return 无。 */ -void sub_bytes(u8 *state); +void sub_bytes(uint8_t *state); /** * @brief 对状态矩阵执行 ShiftRows 变换。 @@ -41,7 +46,7 @@ void sub_bytes(u8 *state); * @param state 指向 16 字节状态矩阵的指针。 * @return 无。 */ -void shift_rows(u8 *state); +void shift_rows(uint8_t *state); /** * @brief 对状态矩阵执行 MixColumns 变换。 @@ -49,7 +54,7 @@ void shift_rows(u8 *state); * @param state 指向 16 字节状态矩阵的指针。 * @return 无。 */ -void mix_columns(u8 *state); +void mix_columns(uint8_t *state); /** * @brief 对状态矩阵执行逆字节替换。 @@ -57,7 +62,7 @@ void mix_columns(u8 *state); * @param state 指向 16 字节状态矩阵的指针。 * @return 无。 */ -void inv_sub_bytes(u8 *state); +void inv_sub_bytes(uint8_t *state); /** * @brief 对状态矩阵执行逆行移位。 @@ -65,7 +70,7 @@ void inv_sub_bytes(u8 *state); * @param state 指向 16 字节状态矩阵的指针。 * @return 无。 */ -void inv_shift_rows(u8 *state); +void inv_shift_rows(uint8_t *state); /** * @brief 对状态矩阵执行逆列混合。 @@ -73,7 +78,7 @@ void inv_shift_rows(u8 *state); * @param state 指向 16 字节状态矩阵的指针。 * @return 无。 */ -void inv_mix_columns(u8 *state); +void inv_mix_columns(uint8_t *state); /** * @brief 设置 AES-128 密钥并完成轮密钥扩展。 @@ -82,7 +87,7 @@ void inv_mix_columns(u8 *state); * @param key 指向 16 字节密钥的指针。 * @return 无。 */ -void aes128_set_key(aes128_context *ctx, const u8 *key); +void aes128_set_key(aes128_context *ctx, const uint8_t *key); /** * @brief 加密单个 16 字节分组。 @@ -92,7 +97,7 @@ void aes128_set_key(aes128_context *ctx, const u8 *key); * @param output 指向 16 字节输出缓冲区的指针。 * @return 无。 */ -void aes128_encrypt_block(aes128_context *ctx, const u8 *input, u8 *output); +void aes128_encrypt_block(aes128_context *ctx, const uint8_t *input, uint8_t *output); /** * @brief 以 ECB 模式加密 48 字节数据。 @@ -102,8 +107,8 @@ void aes128_encrypt_block(aes128_context *ctx, const u8 *input, u8 *output); * @param output 指向 48 字节输出缓冲区的指针。 * @return 无。 */ -void aes128_ecb_encrypt_48bytes(aes128_context *ctx, const u8 *input, - u8 *output); +void aes128_ecb_encrypt_48bytes(aes128_context *ctx, const uint8_t *input, + uint8_t *output); /** * @brief 解密单个 16 字节分组。 @@ -113,7 +118,7 @@ void aes128_ecb_encrypt_48bytes(aes128_context *ctx, const u8 *input, * @param output 指向 16 字节输出缓冲区的指针。 * @return 无。 */ -void aes128_decrypt_block(aes128_context *ctx, const u8 *input, u8 *output); +void aes128_decrypt_block(aes128_context *ctx, const uint8_t *input, uint8_t *output); /** * @brief 以 ECB 模式解密 48 字节数据。 @@ -123,8 +128,8 @@ void aes128_decrypt_block(aes128_context *ctx, const u8 *input, u8 *output); * @param output 指向 48 字节输出缓冲区的指针。 * @return 无。 */ -void aes128_ecb_decrypt_48bytes(aes128_context *ctx, const u8 *input, - u8 *output); +void aes128_ecb_decrypt_48bytes(aes128_context *ctx, const uint8_t *input, + uint8_t *output); /** * @brief 执行 AES 加密-解密自检。 @@ -135,10 +140,10 @@ void aes128_ecb_decrypt_48bytes(aes128_context *ctx, const u8 *input, * @retval 1 验证成功。 * @retval 0 验证失败。 */ -u8 aes128_verify_encryption(aes128_context *ctx, const u8 *original_data, +uint8_t aes128_verify_encryption(aes128_context *ctx, const uint8_t *original_data, size_t length); /** @brief 逆 S 盒查找表。 */ -extern const u8 inv_sbox[256]; +extern const uint8_t inv_sbox[256]; #endif /* __AES_H */ diff --git a/GD32E50X_BOOT/sys/config.h b/GD32E50X_BOOT/sys/config.h index 862a6a4..90f3853 100644 --- a/GD32E50X_BOOT/sys/config.h +++ b/GD32E50X_BOOT/sys/config.h @@ -16,7 +16,7 @@ typedef uint32_t u32; #define BOOT_FW_VERSION_MAJOR 1U #define BOOT_FW_VERSION_MINOR 1U #define BOOT_FW_VERSION_PATCH 0U -#define BOOT_FW_VERSION_BUILD 0U +#define BOOT_FW_VERSION_BUILD 1U /** * Flash 布局说明(GD32E508VE,512KB)