carloscn / blog

My blog
Apache License 2.0
134 stars 38 forks source link

[S32K344] Secure Boot Application #241

Open carloscn opened 3 months ago

carloscn commented 3 months ago

[S32K344] Secure Boot Application

1. Overall

本文来捋顺以下,Secure Boot如何使能。和其他MCU的Secure Boot不同,S32K344的固件需要SoC之上的HSE进行密钥管理和固件签名,而其他的MCU控制器通常是在编译固件的时候进行签名,接着使用烧录器烧录到芯片的NVM中。

对于一般的Secure Boot和S32K3系列的Secure Boot做以下对比:

一般MCU S32K344
代码编译 HOST HOST
RSA私钥存储 HOST或者服务器 HSE
RSA公钥存储 HOST或者服务器 + 固件 HSE
根信任 eFUSE中的pub key hash HSE
签名者 HOST或者服务器 HSE

1.1 流程概述

对于S32K344理论上需要编译两个工程:

首先,是App工程。该工程就是我们正常的S32K344的业务工程。不过相比于普通的业务工程,还需要定义包含App头的描述之类的,所以link文件和工程需要做一些适配;

然后,是Secure Boot配置工程。该工程用于配置Secure Boot,在编译阶段,我们需要把App工程的二进制指定到该工程中。通过烧录和运行该工程,该工程会完成:

当Secure Boot配置工程执行完成之后,在板子下一次reset之后,就完成了secure boot的使能,并且能正确引导App工程的启动。

如果需要重新烧录固件,则需要重新使用Secure Boot配置工程。

1.2 如何保证安全性

Secure Boot保证的是非法固件的启动和运行,安全性的保证是通过HSE的签名操作。

攻击1 : 在一个已经启动Secure Boot的设备上,替换NVM存储器(例如Flash)

通过SBAF(BootROM)程序强制从HSE启动,并利用HSE内置密钥进行固件验证,确实能够有效防止未经授权的固件运行。这种设计确保了攻击者即使通过物理手段替换NVM,也无法绕过HSE的签名验证,从而防止恶意固件的加载。因此,这种机制能够有效抵御通过NVM替换进行的攻击,提供了很强的安全性。

攻击2:通过JTAG接口下载恶意代码并尝试清空HSE的密钥

SoC启动HSE之后,需要开启Secure Debug功能。通过在eFUSE中烧录DAPK或AES密钥,或通过挑战响应模式来验证调试者的身份,这种机制能够有效地防止未经授权的JTAG访问。如果攻击者没有正确的密钥或身份验证手段,那么他们将无法通过JTAG接口重新烧录程序或清空HSE的密钥。因此,这种机制在防止物理调试接口攻击方面是安全的。参考: https://www.pemicro.com/blog/index.cfm?post_id=216

攻击3:通过App的外部接口进行反向固件注入

SBAF程序会强制通过HSE验证固件,并且MPU配置了对HSE区域的保护。对于普通应用程序区域,HSE在启动时验证固件的签名,防止未授权固件通过外部接口(如网络、串口)注入。而对于HSE固件,MPU的保护使得HSE区域无法被写入,从而防止通过应用程序进行的攻击。

攻击4:回滚攻击

攻击者可能尝试通过将固件或软件降级到一个存在已知漏洞的版本,从而利用这些漏洞进行攻击。启动HSE的固件,不可以卸载HSE,只能升级。

2. 使能Secure Boot

2.1 工程依赖配置

在使能Secure Boot基于 https://github.com/carloscn/libs/blob/master/nxp/s32k344/sw745310_SecureBootAppNoteDemo.zip 这个版本,手册对应AN13465 Rev. 0.1.1.0, 12/2021。S32K344无论是HSE还是RTD,都对版本比较敏感。因此,我们谨慎对待版本的选择。主要涉及:

RTD Driver的安装是通过S32DS安装,类似可以串口的工程: https://github.com/carloscn/blog/issues/240

HSE Firmware安装,请参考: https://github.com/carloscn/blog/issues/236

Secure Boot的工程我放在这里:

打开之后:

通过S32DS.3.5 IDE,import功能,打开exist project,导入工程:

需要先编译App (S32K344_SecureBootAppABSwap_Example_100_341_FW0110),再编译Cfg (S32K344_SecureBootCfgABSwap_Example_100_341_FW0110),因为Cfg需要依赖App的bin文件。

2.2 App工程编译

工程 S32K344_SecureBootAppABSwap_Example_100_341_FW0110 未来是我们自己的业务工程。在NXP的工程中 S32K344_SecureBootAppABSwap_Example_100_341_FW0110和S32K344_SecureBootCfgABSwap_Example_100_341_FW0110共用一个main.c文件,通过工程定义的宏定义隔离开功能。

NXP的Secure Boot的Demo工程环境变量有问题,修改成为:

我的S32DS.3.5安装路径并非是默认的路径,而是C:\opt\NXP\S32DS.3.5,所以环境变量应该替换成为正确的环境变量。

C:\opt\NXP\S32DS.3.5\eclipse\..\S32DS\build_tools\gcc_v10.2\gcc-10.2-arm32-eabi\bin;C:\opt\NXP\S32DS.3.5\S32DS\build_tools\msys32\usr\bin;C:/opt/NXP/S32DS.3.5/eclipse/jre/bin/server;C:/opt/NXP/S32DS.3.5/eclipse/jre/bin;C:/opt/NXP/S32DS.3.5/eclipse/jre/lib/amd64;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\WINDOWS\System32\OpenSSH\;C:\Program Files (x86)\PuTTY\;"C:\Program Files\Java\jre1.8.0_221\bin;";C:\Program Files\TortoiseSVN\bin;C:\Program Files\Git\cmd;C:\Program Files\MATLAB\R2020a\runtime\win64;C:\Program Files\MATLAB\R2020a\bin;C:\Program Files\CMake\bin;C:\Program Files\TortoiseGit\bin;C:\Program Files\OpenSSL-Win64\bin;C:\Program Files (x86)\Pulse Secure\VC142.CRT\X64\;C:\Program Files (x86)\Pulse Secure\VC142.CRT\X86\;C:\Program Files (x86)\Common Files\Pulse Secure\VC142.CRT\X64\;C:\Program Files (x86)\Common Files\Pulse Secure\VC142.CRT\X86\;C:\Program Files (x86)\RedHat\java-1.8.0-openjdk-1.8.0.275-1\bin;C:\Program Files (x86)\RedHat\java-1.8.0-openjdk-1.8.0.275-1\jre\bin;C:\Program Files\RedHat\java-1.8.0-openjdk-1.8.0.275-1\bin;C:\Program Files\RedHat\java-1.8.0-openjdk-1.8.0.275-1\jre\bin;C:\Users\NXF55009\AppData\Local\Programs\Python\Python38\Scripts\;C:\Users\NXF55009\AppData\Local\Programs\Python\Python38\;C:\Users\NXF55009\AppData\Local\Microsoft\WindowsApps;c:\Programs\Microsoft VS Code\bin;C:\Program Files\CMake\bin;D:\dev\s32k148avb_master\tools\ninja;C:\opt\NXP\S32DS.3.3\S32DS\build_tools\gcc_v9.2\gcc-9.2-arm32-eabi\bin;C:\Program Files\CodeBlocks\MinGW\bin;;C:\opt\NXP\S32DS.3.5\S32DS\tools\S32Trace\bin;C:\opt\NXP\S32DS.3.5\eclipse

Cfg工程分析

在原始的工程基础上,需要创建以下格式在NVM中:

#ifdef SECURE_BOOT_CFG
const char program_info[] = "CFG";
unsigned int __attribute__((section("._int_ivt_0"))) ivt_flash[] =
{
/*00h*/     SBAF_BOOT_MARKER /* IVT marker */ ,
/* Boot configuration word */
/*04h*/     (CM7_0_ENABLE << CM7_0_ENABLE_SHIFT) | (CM7_1_ENABLE << CM7_1_ENABLE_SHIFT) ,
/*08h*/     IVT_RESERVED /* Reserved */ ,
/*C0h*/     CM7_0_VTOR_ADDR /* CM7_0 Start address */ ,
/*10h*/     IVT_RESERVED /* Reserved */,
/*14h*/     CM7_1_VTOR_ADDR /* CM7_1 Start address , lockstep only run CM7_0 */ ,
/*18h*/     IVT_RESERVED /* Reserved */ ,
/*1ch*/     CM7_2_VTOR_ADDR /* CM7_2 Start address , lockstep only run CM7_0 */ ,
/*20h*/     XRDC_CONFIG_ADDR /* XRDC configuration pointer */ ,
/*24h*/     LF_CONFIG_ADDR /* Lifecycle configuration pointer */ ,
/*28h*/     IVT_RESERVED /* Reserved */,
/*2ch*/     HSE_FW_ADDR /* Reserved */,
/*30h*/     SECURE_BOOT_APP_ADDR ,
/*34h*/     IVT_RESERVED ,
/*38h*/     SECURE_BOOT_BACKUP_ADDR ,
/*3ch*/     IVT_RESERVED ,
/*f0h*/     IVT_GMAC ,
};
#endif

需要注意的是,IVT需要放置在闪存块的开始位置,它通常占据一个完整的扇区(对于S32K344,擦除操作在扇区中进行,一个扇区是8KB,0x2000B),尽管它的大小只有256字节。

App工程分析

显示了App工程中的AppBL内容,包括App代码启动地址、代码大小以及一些基本安全引导所需的信息。应用程序代码地址需要对齐,并通常放置在一个扇区的开始。在原始的工程基础上,需要创建以下格式在NVM中:

这个App的demo实现了一个run_crypto_example的简单功能:

#ifdef SECURE_BOOT_APP
const char program_info[] = "APP";
/*
 * 0x100000 - 1024KB
 * 0x80000  - 512KB
 * 0x40000  - 256KB
 * 0x20000  - 128KB
 * 0x10000  -  64KB
 * */
extern uint32_t __text_start;
extern uint32_t __text_size ;
const hseAppHeader_t __attribute__((section("._app_boot_header"))) app_header =
{
        .hdrTag = 0xD5 ,
        .reserved1 = {0},
        .hdrVersion = 0x60 ,
        .pAppDestAddres = 0x00 ,
        .pAppStartEntry = (uint32_t)( &__text_start ) ,
        .codeLength = (uint32_t)( 0x80000u - APPBL_START_ADDR_OFFSET - APP_HEADER_LENGTH ),
        .coreId = 0x00u ,
        .reserved2 = {0},
};
#endif

相应地map文件:

2.3 上板子测试

Demo是UART0,我的板子是UART3,需要改变一下mex的配置。调试之后烧录cfg工程,运行:

82fc03f9f13c1cf44ae8281e90a1ee8