【单片机笔记】STM32之程序加密——读保护
沉默的小宇宙
于 2019-12-23 20:01:34 发布
2524
收藏 10
版权
以下内容是在STM32F103系列单片机实验成功!
STM32可以对存储在flash上的程序进行读保护.
启动读保护后,用户就不能再读写程序了.
所以,在烧写程序之前,需要程序调用关闭读保护.关闭读保护后,会自动清空flash上的程序
头文件位于:#include "stm32f10x_flash.h"
启动保护,用在main()函数初始化时调用:
void Set_Protect(void) //启动保护
{
if(FLASH_GetReadOutProtectionStatus() != SET)
{
FLASH_Unlock(); //解锁
FLASH_ReadOutProtection(ENABLE);
FLASH_Lock();//上锁
}
}
注意:
当代码第一次调用Set_Protect()函数启动读保护时。
期间不能再次调用Off_Protect()函数关闭读保护,需要重新断电才能关闭读保护(因为Flash状态启动读保护后,不能立即设置Status=1)
关闭读保护,在串口接收某个有效数据或按下某个按键时,调用:
void Off_Protect(void) //关闭保护
{
if(FLASH_GetReadOutProtectionStatus() != RESET)
{
FLASH_Unlock(); //不解锁FALSH也可设置读保护
FLASH_ReadOutProtection(DISABLE);
FLASH_Lock();//上锁
}
}
By Urien 2019年12月23日 20:00:15
————————————————
版权声明:本文为CSDN博主「沉默的小宇宙」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq997758497/article/details/103672340
综合网上讲解的几种读保护措施,这里简单总结下:
采用stm32唯一ID作为加密的字符,使用固定密码,采用16位字节AES加密的方式生成密文,然后写进flash,,app程序执行的时候需要判断读取的stm32唯一ID号和AES解密出来是否一致,是执行程序,否则不执行,测试过,但这个方案针对生产比较麻烦,这里不采用
ChipUniqueID[2] = *(__IO u32 *)(0X1FFFF7F0); // 高字节
ChipUniqueID[1] = *(__IO u32 *)(0X1FFFF7EC); //
ChipUniqueID[0] = *(__IO u32 *)(0X1FFFF7E8); // 低字节
ChipUniqueID[3] = 0xffffffff;
printf("rn########### 芯片的唯一ID为: %X-%X-%X-%X\n",
ChipUniqueID[0],ChipUniqueID[1],ChipUniqueID[2],ChipUniqueID[3]);
memcpy(aesKey , "chenjianqun66666" ,16); //AES加密密钥,16字节(128bit)
memset(expressText ,0 ,1024);
memset(expressText ,0 ,1024);
AES_Decrypt(expressText , cipherText , aesKey);//useaesKey decrypt 解密
count[0] =((u32)expressText[3]<<24)|((u32)expressText[2]<<16)|((u32)expressText[1]<<8)|((u32)expressText[0]);
count[1] =((u32)expressText[7]<<24)|((u32)expressText[6]<<16)|((u32)expressText[5]<<8)|((u32)expressText[4]);
count[2] =((u32)expressText[11]<<24)|((u32)expressText[10]<<16)|((u32)expressText[9]<<8)|((u32)expressText[8]);
if((count[0] == flash[0])&&(count[1]== flash [1])&&(count[2] == flash [2]))
{undefined
//App程序
}
方案二:
采用stm32内部flash读保护函数进行读保护,此时板卡芯片不能读写也不能烧录,所以再设计方面需要外部触发信号关闭读保护并且擦除flash的程序,(可以采用按键的触发方式,当按键按下的时候,度保护关闭并擦除)此时可以再次读写和烧录。(待测试)
if(GPIO_ReadInputDataBit(GPIOA , GPIO_Pin_0))
{undefined
if(FLASH_GetReadOutProtectionStatus()!=RESET)
{
FLASH_Unlock();
FLASH_ReadOutProtection(DISABLE);
// FLASH_EraseAllPages(); //解除读保护的时候擦除所有
FLASH_Lock();//上锁
}
}
else{undefined
if(FLASH_GetReadOutProtectionStatus()!=SET)
{
FLASH_Unlock();//不解锁FALSH也可设置读保护
FLASH_ReadOutProtection(ENABLE);
FLASH_Lock();//上锁
}
}
这里也可以采用在内部的ram中烧进一段代码,用于取消读保护和擦除,需要再次烧录的时候,使用
Boot0 ,boot1进入ram启动状态即可
方案三:
另一种方式修改flash的选项字节(Option type) 官方工具stlink utility(可以参考https://blog.csdn.net/hxiaohai/article/details/78546431?fps=1&locationNum=5)也是修改这个的保护等级,但是103的好像不行(从以下文件中可以看到103系列并没有选项字节文件,加密方式只能选用上述的方案二,但是207的读保护方式因为没有103在方案二的函数,所以只能设置选项字节)修改STM32F2xx_OPT.s 中RDP寄存器的0xAA,为0x00,注意:这里不可以修改为0xCC,0xCC为最高等级,这个值的修改会导致芯片变成砖头
根据网上的资料:http://www.51hei.com/mcu/2767.html 工程中加入opt.s文件既可以实现对flash的加密,但是解密的时候还是需要用stlink的官方工具stlink utility进行设置,要不然就需要在sram里面设置一份设置选项字节为默认出厂形式才可以再次烧录读写
207xx/40xx芯片
103芯片:
————————————————
版权声明:本文为CSDN博主「kissskill」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/lilijianqun/article/details/79861270