STM32 加密思考
作者:互联网
STM32的加密思路
- 使用系统启动程序STM32 Flash Loader demonstrator将Flash设置为读保护。
所有以调试工具、内置SRAM或FSMC执行代码等方式对主存储器访问的操作将被禁止,只允许用户代码对主Flash存储器的读操作和编程操作(除了Flash开始的4KB区域不能编程)。用户代码允许自主编程可以实现IAP或者数据存储等功能。
这样破解者将不能用调试工具、内置SRAM或者FSMC执行代码等方式读出Flash中的代码。破解者也不能使用系统启动程序读取代码,因为要解除读保护,将执行整个芯片的擦除操作。 - 主程序中使用设备ID保护
即使将Flash设置为读保护,破解者也可以通过IAP下载自己的一段小程序,从而读出Flash中的内容。因此,还需要利用设备的唯一ID进行加密保护。在主程序中,加入对设备唯一ID的检测,这样即使破解者读出了芯片中的二进制码,也不能用这个二进制码去复制新的器件。
具体实现方法:
a. 在应用程序中定义1个(32位甚至更多)const变量,变量值全为0xFF。每次启动程序时,检查const变量值如果全为0xFF,就读器件的唯一ID,通过Flash编程写入该const变量中(因为全是0xFF,所以可以编程写入)。
b. 在程序中多个地方检查const变量,如果变量值不为0xFF并且与设备ID不一致,就执行与功能无关代码(比如自擦除)。
这样,即使破解者读出了芯片中的二进制码,因为这份二进制码包含了设备唯一ID,具有唯一性,所以不能复制到其他芯片中。
为了避免破解者利用反汇编,根据芯片ID数据在二进制文件中查找对应相同数据的位置从而破解,可以将ID拆散成不同的组合,并且写到不同且不连续的地方。更进一步,可在程序中检测多份这样的分散ID,以增加反汇编的难度。或者将CPUID进行加密,Flash中存储加密后的结果。 - 固件的加密。有两种方案:一是传输过程的加密,另外一种是固件镜像的加密。具体方案待补充。
程序加密的实现
//加密后的CPUID
volatile const static uint32 CPUIDEncrypt = 0xFFFFFFFF;
//写入加密数据
void WriteEncrypt(void)
{
//第一次烧写:将UID写入到Flash中
if(CPUIDEncrypt==0xFFFFFFFF)
{
uint32_t CpuID[3];
//获取CPU唯一的ID
CpuID[0]=*(vu32*)(UID_BASE);
CpuID[1]=*(vu32*)(UID_BASE+4);
CpuID[2]=*(vu32*)(UID_BASE+8);
//加密算法,很简单的加密算法
uint32_t EncryptCode=(CpuID[0]>>3)+(CpuID[1]>>1)+(CpuID[2]>>2);
FLASH_Unlock();
FLASH_ClearFlag(FLASH_FLAG_BSY|FLASH_FLAG_EOP|FLASH_FLAG_PGERR|FLASH_FLAG_WRPRTERR);
FLASH_ProgramWord((uint32_t)&CPUIDEncrypt, EncryptCode);
FLASH_Lock();
}
}
//判断加密
bool JudgeEncrypt(void)
{
uint32_t CpuID[4];
//获取CPU唯一的ID
CpuID[0]=*(vu32*)(UID_BASE);
CpuID[1]=*(vu32*)(UID_BASE+4);
CpuID[2]=*(vu32*)(UID_BASE+8);
//加密算法,很简单的加密算法
CpuID[3]=(CpuID[0]>>3)+(CpuID[1]>>1)+(CpuID[2]>>2);
//检查Flash中的UID是否合法
return (CPUIDEncrypt == CpuID[3]);
}
- 将写入加密数据和判断加密两个功能分开。写入加密在PrsCtrlTask开始的地方;而判断加密分布到程序的各个角落。
- 非常重要的是CPUID加密值的定义一定要加“volatile”类型,否则按速度优化编译,在判断加密值,不会重新读取加密值,导致判断出错。
volatile const static uint32 CPUIDEncrypt = 0xFFFFFFFF;
- 在工程选项Options->Debugger->Download中选择: use flash loader,否则主程序中对Flash编程将不成功。
[未完待续]
标签:FLASH,加密,UID,Flash,STM32,思考,CpuID,ID 来源: https://blog.csdn.net/Simon_ce/article/details/80197722