基于闪存的微控制器在代码发布中的代码保护简介
扫描二维码
随时随地手机看文章
包装信息可能包含:指定目标设备、代码版本、大小、日期和其它对用户有用的信息。这个信息可警告操作员正在使用一个较低版本的固件,从而会使设备的部分性能降低,或者正在装载一个不支持的指定设备。
在如今竞争激烈的市场中,保护公司的知识产权(IP)是最高优先级的事项之一。多年的开发可能产生了包含很多商业秘密或专有算法的设计。随着基于闪存的微控制器得到更多地应用并集成了更多的特性,许多公司摒弃传统的一次性可编程(OTP)微控制器(MCU),转而采用闪存。
闪存允许在生产线的终点进行实时编程,也允许在生产之后修改代码。但是如果通过因特网,公司将面临IP将泄漏给竞争者的问题。应该采用各种方法来控制更新授权许可,并在泄漏产品的IP的情况下, 提供现场更新。
代码保护
保护现场配置的软件产品的方法很多,采用哪种方法取决于供应商希望保护什么。大多数软件保护机制是防止对程序或数据进行未经授权的复制。如今复制文件非常容易,通过因特网能很快地找到许多拷贝。当固件是某个硬件平台的一部分时,保护固件中包含的IP通常比保护对文件的拷贝更重要。当然,如果固件更新需要购买,那么保护拷贝也很重要。
另一个问题涉及基于微控制器产品破解密码的性能。RSA和DES标准对性能和存储器的要求都很高。不幸的是,大多数的微控制器在这两方面的资源都有限,从而要求不同的加密和解密方法。我们必须提供一种通用的或者针对特定设备的密钥方案。
简单密码
循环码(Rolling-code)产生器已在车库门锁、安全进出卡等多种设备上应用多年。图1显示简单的循环码产生器是如何工作的。一组具有相同时钟信号的双稳态触发器串联连接,其输出端有各种抽头。在给出的例子中,Q2端没有被使用,其余的输出端连接唯一的OR功能端口,该端口在每个时钟信号沿得到新的输入位。可能产生的组合数目取决于触发器的个数和接到OR函数端口的抽头个数。
通常将几个触发器的输出用作循环钥匙码。实际应用时(如作在车库门锁),使用一个完全相同的发生器来测试钥匙码。随着新码被不断地使用,会发生整个序列重复出现的情况,这可能是在千万或几亿个钥匙码之后。这时就不能再使用它了。在用于车库门锁的情况下,它可以防止罪犯用无线接收机盗听并简单地重现钥匙码以开门。
在代码加密的情况下,触发器的输出与被加密或解密的数据被送到另外一个OR函数端口(图2中的A1)。数据的每个字节、字或双字都与选中的触发器端口进行OR运算,再加上用户特定另外函数。那个函数可以简单到只加上一个常数。这个过程必须是可逆的,所以用户定义的函数不是随机的。由安置触发器抽头决定的密码和由移位寄存器的初态、所选定的种子一起提供了加密和解密的算法。可按照串行数字的方法拆分这些密码,以向特定设备提供唯一的密码。也就是说,设备的串行号码仅提供一半的密码信息,制造商保留其余密码信息。很明显,这种方案存在着多种排列。
在固件更新是向全球发布时,例如,适用所有产品的错误的更新,可以使用一个特别的串行码。解密引擎首先尝试用全球码,-----可能是一个特殊数字图样。如果全球码没有解密出正确的校验和,才使用唯一的密码。它可以告诉装载程序:加密的源文件包含了什么类型的固件更新数据。
传输方法
很明显,产品内必须要有某种解码引擎和代码装载程序。这里讨论的技术可以用COP8微控制器来解释。该目标控制器是包含32KB闪存和1KB RAM的COP8CBR。 对于现场可更新的设备,必须注意这样一个说明以防止误解:微控制器必须具有一边运行程序一边对闪存进行编程的能力。不能用把控制器保持在重新设置状态或者要求外部编程来更新存储着程序的闪存。解码和装载程序必须驻留在控制器内部,并且完全可靠。COP8闪存产品能满足这些要求。
固件的装载程序是一个代码模块,它在重新设置后运行,并能判断本次装载是否有效。如果发现被装载的代码无效,装载程序就进入装载模式(LOAD MODE),直到有能够操作的固体程序。可通过控制器提供的物理层接口来实现这点。COP8可使用串口。如果当前代码是有效的,装载程序会把控制交给固件应用程序的入口。
COP8系列的另一个特性是可以采用软件陷阱以引导恢复机制。它执行操作码0x00,可将这个操作码编程到所有未用单元。如果这个操作码被执行,操作将从软件陷阱向量开始,使装载程序重新评估固件的完整性。这是一个容错的好特性。不管什么原因,代码被破坏,装载程序将得到控制,以便让技术人员(或用户)重新装载固件。
装载程序使用数据包,数据包有数据头和校验和以验证传输。如果数据包传输到了控制器并且校验和是正确的,则装载程序把它交给解码引擎(如果它是加密的)。在加密数据的内部有另外一个密码校验和,这给解密引擎一个验证密码信息的手段。它将首先应用通用码并测试校验和,如果失败,则利用来自串行数字的唯一密码重试。如果再次失败,则告诉装载程序固件对这个设备无效。这也可防止代码被未经授权的篡改和意外损坏。
如果解密引擎成功地解码数据, 它将把数据交给在闪存中对实际闪存块进行编程的程序例程。当然,对于不同产家,这个程序是不同的,在后面的设计实例中将给出COP8的程序。这个程序保留了一个128字节的RAM用于更新闪存。当然,这块RAM在装载程序完成后可以存放应用程序的数据。
设计实例
图3是一个具备解密功能的固件装载程序的流程图。装载程序使用在编程器和系统模拟程序中广泛使用的修改版Intel HEX数据格式。这将使应用程序现有架构支持标准并易于使用。装载固件程序用COP8汇编语言编写,以简少代码,并利用器件全部的闪存特性。
简单来说,Intel HEX格式是一种用ASCII编码表示的数据记录格式,用于向设备的存储器编程对象代码或数据。该格式由下列字段组成:使用ASCII字