微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

STM32 加密思考

STM32的加密思路

  1. 使用系统启动程序STM32 Flash Loader demonstrator将Flash设置为读保护。
    所有以调试工具、内置SRAM或FSMC执行代码等方式对主存储器访问的操作将被禁止,只允许用户代码对主Flash存储器的读操作和编程操作(除了Flash开始的4KB区域不能编程)。用户代码允许自主编程可以实现IAP或者数据存储等功能
    这样破解者将不能用调试工具、内置SRAM或者FSMC执行代码等方式读出Flash中的代码。破解者也不能使用系统启动程序读取代码,因为要解除读保护,将执行整个芯片的擦除操作。
  2. 主程序中使用设备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中存储加密后的结果。
  3. 固件的加密。有两种方案:一是传输过程的加密,另外一种是固件镜像的加密。具体方案待补充。

程序加密的实现

//加密后的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编程将不成功。
    [未完待续]

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐