针对黑客非法获取ARM芯片程序的问题,提出了一种能同时防止ARM芯片程序被非法复制及源码窃取的方法。该方法以分散加栽方式规划存储器,以ARM芯片内全球唯一序列号为密钥,对核心程序进行加密处理。
一、分散加载技术介绍
1、分散加载的基本原理
在嵌入式系统中,其存储系统常常由FLASH、ROM、RAM等存储器组成,它们被定位于不同的物理地址范围。为了让软件更好地访问和利用这些存储器并让系统高效的运行,ARM链接器提供了分散加载机制。在链接时可以根据分散加载文件中指定的存储器分配方案,将可执行镜像文件分为指定的分区并定位于指定的存储器物理地址。当嵌入式系统在重新上电或复位时,首先对处理器内部寄存器执行初始化,然后执行ROM存储器的自举代码,根据链接时的存储器分配方案,将相应代码和数据从加载地址复制到运行地址。这样,定位于RAM存储器中的代码和数据就在RAM中执行,而不再从ROM存储器中执行刚。利用分散加载的特性,可以在加载域指定的ROM中存储经过加密的=进制程序,而在对应的运行域RAM中将其还原,RAM的掉电易失性使源程序不被暴露。
2、存储器规划
ARM Cortex—M3芯片有32 KB本地静态RAM和512 KB片内FLASH,其地址映射如图1所示。
由于ARM芯片程序中有大量的公共库程序和简单的流程控制程序,所以不需要加密全部程序,只要加密核心代码即可。本文把ARM程序抽象成三大部分:预处理部分、核心程序部分、其他程序部分。预处理部分最先执行,负责与上位机软件交互、解密加载域并写入对应运行域中。核心程序是芯片代码中需要加密部分,其加载域上存储其密文。其他程序为芯片代码中的公共库程序或简单流程程序,其加载域上直接存储其明文。本文对存储器的规划如表1所列,值得注意的是核心程序的运行域在RAM上。根据分散加载文件的编写规则和表1,编写相应分散加载文件后,使用集成开发环境编译并下载程序,预处理程序、核心程序、其他程序将会被烧写到相应加载域,并且得到三个与之对应的二进制文件。
二、加密方案具体实现
软件加密的目的就是要千方百计造成机器码的错误反汇编或反汇编后的程序不可读,所以可以考虑把程序加密后再烧写到FLASH中,达到完全打乱FLASH程序顺序的作用。这样,不法分子从FLASH中提取的程序,反汇编的结果将是完全不可分析的。被加密的程序运行前,将其解密后到复制到分散加载文件指定的位于RAM的运行域,由于RAM的掉电丢失性,正确的二进制程序将被隐藏。到此为止,已经能够阻止不法分子通过反汇编得到程序的源代码。然而,仍然没有防止仿制者通过非法手段整片复制芯片程序到同型号的其他芯片,从而快速生产出同类电子产品。通过对ARM芯片的分析发现,在所有ARM芯片内部寄存器中,都有一组128位全球唯一芯片序列号。并且此序列号只能被读取,不能被修改,可以以此序列号作为加密算法的密钥,这样,由于所有ARM设备的密钥都不同,不法人员通过简单拷贝芯片程序给其他同类型芯片,会因为密钥不匹配,得不到正确的运行域程序,使整片复制芯片程序的窃取方法失败。
本文的加密方案总体思想如图2所示。首先以分散加载方式规划存储器,正常加载程序。然后将核心程序以ARM序列号为密钥,加密后烧写到分散加载文件指定的加载域上,以密文形式覆盖原有明文。最后,在预处理程序中提取设备序列号,以此为密钥进行解密,将得到的结果复制到分散加载文件指定的运行域中。
1、加密算法选择
在数据加密认证的过程中,选择合适的加密算法是研发工程师首先要考虑的事情。选择加密算法时要结合自身需求,从算法执行速度、安全性、资源占用性等方面进行综合考虑。对称加密算法是常用于嵌入式设备加密的主要方法,其中广范应用的对称加密算法有AES算法和DES算法。DES算法有不能对抗差分和线性密码分析、对系统资源要求高等缺点:2000年,美国国家标准局正式宣布AES算法为新的高级加密标准。AES优点如下:运算速度快,对内存要求低,高安全性等。由于AES算法可以提供128位密钥,所以128位ARM芯片全球唯一序列号不做任何处理便可作为AES算法密钥,本文选用AES算法作为核心程序加密算法。
2、核心程序加密实现过程
根据表l的分散加载方案下载程序到存储器芯片中后,包括核心程序在内的所有程序在FLASH上都以明文存储。要使核心程序不被窃取,必须对其加密处理,以密文覆盖原有明文。在实现时,要设计一个简单的上位机软件,其与芯片中预处理程序配合完成芯片加密工作。上位机可以用MFC或C#开发,笔者以MFC方式实现的上位机软件界面,如图3所示。
上位机可以采用无线、串口、USB接口等任何方式与ARM微处理器进行通信。上位机首先判断是否与ARM设备连接,笔者采用的方法是上位机向微处理器发送CONNECT宏命令,如果从ARM设备收到同样的CON-NECT宏命令,则可以判断ARM设备与上位机成功连接。之后,上位机自动发送GET;二SERIAL—NUMBER宏命令让微处理器调用内置函数读取芯片全球唯一序列号,并将此序列号发送给上位机。选择核心程序对应的二进制文件进行加密处理,上位机会调用AES算法,以芯片全球唯一序列号为密钥产生经过加密的核心程序文件。选择产生的加密核心程序文件,将分散加载文件中核心程序的加载地址和运行地址分别填入上位机软件相应控件,最后,上位机会把经过加密的核心程序文件发送至ARM设备中。芯片中预处理程序接收到加密核心程序后,以在应用编程(IAP)方式将经过加密的核心程序覆盖未加密核心程序的加载域。除此之外,发送加密核心程序的同时,烧写地址(ROM CORE_ADDR)、执行地址(RAM_RUN ADDR)以及核心程序代码大小(CORE_SIZE)三个参数被一起发送给ARM设备,预处理程序解密时要使用以上三个参数。核心程序加密流程如图4所示,执行每一步的结果都会在上位机上得到显示。
3、运行时解密的实现过程
为使此加密方案通用性更强,将与上位机通信的程序和解密程序全部放到预处理程序部分,只要在ARM程序的起始部分添加预处理程序,所有ARM系列微处理器都可以应用此加密方案。预处理程序执行时,首先检测ARM设备是否与上位机相连,如果相连,执行与上位机交互相关程序,如上文提到的接收核心程序密文,以IAP方式覆盖核心程序加载域明文、ARM序列号发送等。如果ARM设备没有与上位机连接,进行运行域解密工作,首先调用ARM芯片提供的API提取内部全球唯一序列号(SER-IAL_ NUMBER),然后以此为密钥,对核心程序加载域(ROM_CORE_ADDR)上的程序执行AES解密,最后将结果复制到核心程序运行域( RAM_RUN_ADDR) 。
采用迭代的方法,每次从核心代码加载域提取128位,将其解密后复制到核心代码运行域,迭代的次数由核心程序代码大小决定。无论要解密的核心程序有多大,此方案只需32字节的额外存储空间。另外,应用ARM处理器特有的32位指令集,可以大幅加快AES解密算法的执行速度。将解密后的核心程序复制到相应运行域后,就可以跳转出预处理程序,执行正常的功能程序。运行时解密过程如图5所示。
小知识之ARM处理器
ARM处理器是Acorn计算机有限公司面向低预算市场设计的第一款RISC微处理器。更早称作Acorn RISC Machine。ARM处理器本身是32位设计,但也配备16位指令集,一般来讲比等价32位代码节省达35%,却能保留32位系统的所有优势。