[STM32U5] 【NUCLEO-U575ZI-Q测评】+第二篇_TrustZone测试

[复制链接]
1121|2
 楼主| zhanzr21 发表于 2023-3-14 20:53 | 显示全部楼层 |阅读模式
本帖最后由 zhanzr21 于 2023-3-14 20:55 编辑

#申请原创#

Trust Zone M特性简介
TrustZone是ARM-v8M内核推出的安全特性,严格来讲叫做TrustZone-M,因为CortexA系列的TrustZone功能早已存在多年,而且TrustZone-M更偏向于嵌入式场景,跟TrustZone差别还是很大的.
Cortex M23,Cortex M33, Cortex M35是目前基于v8M内核的几款内核, STM32U575的内核是CortexM33.
TrustZone-M特性是厂商可以选择的一个特性,如果不实现这个特性,M33和M4/M7类似.
file:///C:/Users/Lenovo/AppData/Local/Temp/msohtmlclip1/01/clip_image026.jpg
3340964106bd93c0af.png

如果实现了TrustZone-M,则有一些附加的IP.
1351064106bfa664c4.png

可以看到从IP上看,MPU变成了MPU_S/MPU_NS两个IP,另外多了SAU.
STM32U5系列的MCU是实现了TrustZone-M这个特性的,所以有SAU,MPU_S,MPU_NS这些单元.
值得一提的是,STM32U5TrustZone-M特性是通过OptionBit控制的,如果不需要TrustZoneM特性,可以进行关闭,这时M33内核与M4,M7内核差不多.
对于TrustZone M这个特性,如下几点可以帮助读者建立初步概念:
  • 1. 对于CortexM系列的内核,  ARM v8M内核开始支持, 目前有CortexM23, M33, M35几个系列;
  • 2.对于内核而言,要么支持Trust Zone M,要么不支持,对于STM32U5系列,这个是OptionBit控制的,通过STM32Cube Programmer等烧写器可以修改这个选项
  • 3. 当关闭Trust Zone M后, Cortex M33与M4/M7类似
  • 4. 开始Trust Zone M后, 一些IP/寄存器有双份, 即Trusted/Untrusted,也可以称之为Secure/Non-Secure.
  • 5.CPU还是一个, 开始Trust Zone M后,上电自动进入Secure模式,Secure模式可以跳转到Non-Secure区,Non-Secure区通过特殊的方式可以读写Secure区的空间, 所以事实上还有第三个区, 一般称之为Non-Secure-Call区,Secure区可以直接读写Non-Secure区.
  • 6.内存空间可以划分为Secure/Non-Secure区,外设也可以指定由Secure区操作,或者Non-Secure操作,一旦指定为Secure区,Non-Secure区的程序不能直接读写该区间/外设
  • 7.可以简单把Secure区看作PC电脑上具有最高优先级别的UEFI/BIOS/ME模式,Non-Secure区看作常规的OS.(这个比喻不是很恰当,权且这样说吧)

关于Trust Zone M,内容太多, 本贴只能简要解绍下,STM32U5芯片如何创建一个支持TrustZone的工程.
第一步, 修改Option Bit
8042264106c333007a.png

TZEN最重要的, 不使能的话, 该芯片无Trust Zone-M特性, M4/M7类似. 要使用该特性的话,把这个勾上.
4261064106c544acc4.png

4122264106c5c49fcd.png

我们把0x80000000开始到0x8100000的区间配置为了Secure区, 后面Secure区间的代码放在这个区间, 其余区间存放Non-Secure区间的代码.注意对于Secure区间的代码烧写,要指定一个偏移量把0x8000000的地址偏移到0xC000000上去, 这是STM32U5特殊的配置.
第二步-创建CubeMX工程, 划分外设
6936364106c73f3f99.png


创建工程时就需要指定是否使用TrustZone, 使用TrustZone时实际上创建了两个工程, Secure和Non-Secure版本.
再来指定外设
4485664106c8b00290.png

第一步,我们故意把HASH IP分给Non-Secure, RNG IP分给Secure. 这种情况下, Non-Secure区不能直接访问RNG这个IP.
之后按照常规生成代码, 会生成两个工程, 分别对应SecureNon Secure区间.
两个工程的ROM区和RAM区不要重合.
Secure
:
3444664106ca162cf3.png

其下载配置:
6543464106cb485be9.png

Non-Secure区:
1575864106cc8407fe.png

其下载配置:
3584164106ce2416f6.png

先构建Secure区并下载,再构建Non-Secure区并下载:
205564106cf76edeb.png

简单看看代码从Secure区跳到Non-Secure区的跳转点:
芯片上电后来到Secure区内,代码与一般CortexM工程无异:
  1. int main(void)
  2. {
  3.   /* SAU/IDAU, FPU and interrupts secure/non-secure allocation setup done */
  4. /* in SystemInit() based on partition_stm32u575xx.h file's definitions. */
  5.   /* USER CODE BEGIN 1 */

  6.   /* USER CODE END 1 */

  7.   /* MCU Configuration--------------------------------------------------------*/

  8.   /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  9.   HAL_Init();

  10.   /* USER CODE BEGIN Init */

  11.   /* USER CODE END Init */

  12.   /* Configure the system clock */
  13.   SystemClock_Config();

  14.   /* Configure the System Power */
  15.   SystemPower_Config();
  16.   /* GTZC initialisation */
  17.   MX_GTZC_S_Init();

  18.   /* USER CODE BEGIN SysInit */

  19.   /* USER CODE END SysInit */

  20.   /* Initialize all configured peripherals */
  21.   MX_GPIO_Init();
  22.   /* USER CODE BEGIN 2 */

  23.   /* USER CODE END 2 */

  24.   /*************** Setup and jump to non-secure *******************************/

  25.   NonSecure_Init();
但是NonSecure_Init这个函数不会返回, 会跳转到Non-Secure区, 类似于BootLoader->Application跳转.

  1. /**
  2.   * [url=home.php?mod=space&uid=247401]@brief[/url]  Non-secure call function
  3.   *         This function is responsible for Non-secure initialization and switch
  4.   *         to non-secure state
  5.   * @retval None
  6.   */
  7. static void NonSecure_Init(void)
  8. {
  9.   funcptr_NS NonSecure_ResetHandler;

  10.   SCB_NS->VTOR = VTOR_TABLE_NS_START_ADDR;

  11.   /* Set non-secure main stack (MSP_NS) */
  12.   __TZ_set_MSP_NS((*(uint32_t *)VTOR_TABLE_NS_START_ADDR));

  13.   /* Get non-secure reset handler */
  14.   NonSecure_ResetHandler = (funcptr_NS)(*((uint32_t *)((VTOR_TABLE_NS_START_ADDR) + 4U)));

  15.   /* Start non-secure state software application */
  16.   NonSecure_ResetHandler();
  17. }
这时Non-Secure区工程没有RNG的初始化代码, 我们做一点Hack, 把HAL库里的RNG初始化和使用代码拷贝到Non-Secure工程中进行随机数生成并打印:
  1. /****************************************************************************/
  2.   /*************************** Hash-SHA256
  3.    * ***************************************/
  4.   /****************************************************************************/
  5.   if (HAL_HASH_DeInit(&hhash) != HAL_OK) {
  6.     Error_Handler();
  7.   }
  8.   MX_HASH_Init();

  9.   if (HAL_HASHEx_SHA256_Start(&hhash, (uint8_t *)aInput, INPUT_TAB_SIZE,
  10.                               aHashDigest, 0xFF) != HAL_OK) {
  11.     Error_Handler();
  12.   }
  13.   printf("Hash-SHA256 test passed.\n");
  14.   print_hex(aHashDigest, 32);
  15.         
  16.   while (1)
  17.   {
  18.                 halStatus = HAL_RNG_GenerateRandomNumber(&hrng, &random32bit);                  
  19.                 printf("%p %u %u\n", main, SystemCoreClock, HAL_GetTick());
  20.                 printf("%u, %p %08X\n", halStatus, &random32bit, random32bit);
  21.                 HAL_Delay(3000);
可以看到随机数生成函数返回错误:
  1. Core Freq:160000000 Hz
  2. Hash-SHA1 test passed.
  3. F859C18DEC9472427924FB61EF7C6A6B670BF9C3
  4. Hash-MD5 test passed.
  5. 6707862C7CD0B522B2DD22D8477BE318
  6. Hash-SHA224 test passed.
  7. 76CCDD1FDE036CDE39C9D23CE6BDB169FF743B89D15791BFBA109A55
  8. Hash-SHA256 test passed.
  9. 9691CF47C93807990B049AD4D2E7F60133AB48AADA53A80889A3DA46170F4AFE
  10. 081026d5 160000000 3
  11. 1, 200461e4 713A21DC
第三步, 重新划分外设

6116164106d75bd438.png

这一次把RNG也分给Non-Secure区间, 再次生成代码,构建下载, 这样就可以看到随机数生成函数正确返回了.
  1. Core Freq:160000000 Hz
  2. Hash-SHA1 test passed.
  3. F859C18DEC9472427924FB61EF7C6A6B670BF9C3
  4. Hash-MD5 test passed.
  5. 6707862C7CD0B522B2DD22D8477BE318
  6. Hash-SHA224 test passed.
  7. 76CCDD1FDE036CDE39C9D23CE6BDB169FF743B89D15791BFBA109A55
  8. Hash-SHA256 test passed.
  9. 9691CF47C93807990B049AD4D2E7F60133AB48AADA53A80889A3DA46170F4AFE
  10. 081026d5 160000000 3
  11. 0, 200461e4 57FD111A
小结

TrustZone M有很多种特性, 这里只说了最简单的一种应用模式:即外设划分区间,一般用于OEM厂商保留某些外设仅供自己操作, 下游的开发商不能直接访问,必须通过OEM厂商提供的库来使用,这种场景.

Trust Zone M的应用场景当然不限于此, 后续有时间还会继续发一些学习心得.

代码还是这个位置下载, 包括CubeMX 工程:
git@github.com:zhanzr/Nucelo144-STM32U575.git
分支: trustzone_test





Henryko 发表于 2024-1-12 16:16 | 显示全部楼层
其他型号不用改偏移地址吗
 楼主| zhanzr21 发表于 2024-1-13 18:33 | 显示全部楼层
Henryko 发表于 2024-1-12 16:16
其他型号不用改偏移地址吗

不同型号偏移地址不同的, 不过很容易可以查到这个地址
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:每天都進步

91

主题

1017

帖子

34

粉丝
快速回复 在线客服 返回列表 返回顶部