STM32 安全引导加载程序安全启用始终失败,并显示“[SBOOT] 安全问题:执行已停止!”

STM32 secure boot loader security enable fails consistently with "[SBOOT] Security issue : Execution stopped !"

我禁用了 STM32F405RGT6 安全引导加载程序 运行 安全标志。所以我尽量把安全flags/options一一介绍。独立于我在 app_sfu.h 中启用的标志,代码在 sfu_boot.c

中 SFU_BOOT_SM_VerifyUserFwSignature 函数的第一个 FLOW_CONTROL_CHECK 中失败

我添加了日志记录以准确显示发生的情况:

  /* Double security check :
 - testing "static protections" twice will avoid basic hardware attack
 - flow control reached : dynamic protections checked
 - re-execute static then dynamic check
 - errors caught by FLOW_CONTROL ==> infinite loop */
  TRACE("= [SBOOT] FLOW_CONTROL_CHECK(%x, %x)\n", uFlowProtectValue, FLOW_CTRL_RUNTIME_PROTECT);
  FLOW_CONTROL_CHECK(uFlowProtectValue, FLOW_CTRL_RUNTIME_PROTECT);

跟踪的输出显示:

= [SBOOT] FLOW_CONTROL_CHECK(1554b, 30f1)

FLOW_CONTROL_CHECK 宏比较两个值。如果它们不同,则程序失败。

据我了解代码,uFlowProtectValue 包含 运行 时间保护值,在实际执行时处于活动状态,而 FLOW_CTRL_RUNTIME_PROTECT 是编译时间#define,应该与我们是什么 运行.

问题的核心是 运行 时间保护值是我所期望的,而编译时间#define 永远不会与 0x30f1 不同。

#define 出现在 ST 提供的代码中,您的母亲可能不赞成,至少因为它似乎不起作用:

  /**
  * @brief  SFU_BOOT Flow Control : Control values static protections
  */
#define FLOW_CTRL_UBE (FLOW_CTRL_INIT_VALUE ^ FLOW_STEP_UBE)
#define FLOW_CTRL_WRP (FLOW_CTRL_UBE ^ FLOW_STEP_WRP)
#define FLOW_CTRL_PCROP (FLOW_CTRL_WRP ^ FLOW_STEP_PCROP)
#define FLOW_CTRL_SEC_MEM (FLOW_CTRL_PCROP ^ FLOW_STEP_SEC_MEM)
#define FLOW_CTRL_RDP (FLOW_CTRL_SEC_MEM ^ FLOW_STEP_RDP)
#define FLOW_CTRL_STATIC_PROTECT FLOW_CTRL_RDP

/**
  * @brief  SFU_BOOT Flow Control : Control values runtime protections
  */
#define FLOW_CTRL_TAMPER (FLOW_CTRL_STATIC_PROTECT ^ FLOW_STEP_TAMPER)
#define FLOW_CTRL_MPU (FLOW_CTRL_TAMPER ^ FLOW_STEP_MPU)
#define FLOW_CTRL_FWALL (FLOW_CTRL_MPU ^ FLOW_STEP_FWALL)
#define FLOW_CTRL_DMA (FLOW_CTRL_FWALL ^ FLOW_STEP_DMA)
#define FLOW_CTRL_IWDG (FLOW_CTRL_DMA ^ FLOW_STEP_IWDG)
#define FLOW_CTRL_DAP (FLOW_CTRL_IWDG ^ FLOW_STEP_DAP)
#define FLOW_CTRL_RUNTIME_PROTECT FLOW_CTRL_DAP

我上面的跟踪输出中的十六进制数字来自启用内部看门狗 IWDG。

这些值是从三个涉及的位图中异或的:

#define FLOW_CTRL_INIT_VALUE 0x00005776U         /*!< Init value definition */
#define FLOW_STEP_UBE 0x00006787U                /*!< Step UBE value */
#define FLOW_STEP_IWDG 0x000165baU               /*!< Step IWDG value */

前两者的异或运算结果为 0x30f1,如果对其加上 FLOW_STEP_IWDG,则得到 0x1554b。

所以启用IWDG的运行时间值是正确的,而编译时间值是错误的。

怎么可能?

好吧,这太傻了:所有涉及的代码均由 ST Microelectronics 提供。

使用 app_sfu.h 中的所有安全定义的 sfu_boot.h 文件没有 #include app_sfu.h 并且它没有内置检查来验证 app_sfu.h 有确实被包含在包含链中的某个地方。因此,我将#include "app_sfu.h" 添加到 ST Microelectronic 提供的 sfu_boot.h 中,问题就消失了。

对于给您带来的不便,我们深表歉意:-)