W80X 系列芯片的程序保护措施共有三种方式: 防拷贝, 固件加密, 固件签名. 在防拷贝的基础上使用固件签名和固件加密可以进一步提高保护级别. 防拷贝的原理是利用芯片的 Flash Unique ID 的唯一性来对比判断, 如果一致才能继续运行程序. 在生产烧录固件阶段, 我们将待烧录测试的设备称作 DUT, 在固件烧录时, 烧录工具会读取 DUT 的 Flash Unique ID, 加密后写入 Flash 的 A 地址, 烧录成功后, 设备程序运行时, 先读取芯片的 Flash Unique ID, 接着读取 A 地址存放的加密 ID, 进行解密, 解密后对比两个 ID 是否一致, 如果一致, 接着运行程序, 如果不一致, 则认为程序被拷贝运行, 停止运行.
1, 安装 openssl 工具
需要 1. 0 及以上版本, 文件夹中自带了 win 64 位 1. 1 版本的安装文件, 也可以从其他地方下载. 安装过程按照提示点下一步直到完成即可.
2, 解压 FirmUpdate_2. 2. 0. 8. zip
3, 从官网获取 SDK
4, 固件加密和固件签名
4. 1 使用 CDK 编译工具
- 在 tools/W80x/utilities/aft_build_project. sh 文件中:
设置 code_encrypt = 1 表示使能固件加密;
设置 signature = 1 标识使能固件签名;
将 5 个 openssl. exe 添加对应的安装路径;
设置固件加密秘钥参数, 参数长度为 16 字节, 比如下图中使用的是 0~F 这 16 个十六进制数字, 则在. sh 文件中参数位置写的是对应的 ASCII 码;
- 在 tools/W80x/ca/key. txt 文件中:
修改为对应的固件加密 key 值, 长度为 16 字节数据;
- 在 tools/W80x/ca/cakey. pem 和 capub. pem 文件中:
cakey. pem 是 RSA 签名私钥, 用于 openssl 签名固件, capub. pem 是公钥, 用于解签, 将两个文件里的内容替换为自己的公私钥.
4. 2 使用 make 编译工具
- 在 tools/w800/. config 文件中:
设置 CONFIG_W800_IMAGE_SIGNATURE = 1, 使能固件签名;
设置 CONFIG_W800_CODE_ENCRYPT = 1, 使能固件加密;
在 tools/w800/rules. mk 文件中:
如下图位置, 修改固件加密使用的 key, 长度为 16 字节数据转换为对应的 ASCII 字符串;
- 在 tools/w800/ca/key. txt 文件中:
修改为对应的固件加密 key 值, 长度为 16 字节数据;
- 在 tools/800/ca/cakey. pem 和 capub. pem 文件中:
cakey. pem 是 RSA 签名私钥, 用于 openssl 签名固件, capub. pem 是公钥, 用于解签, 将两个文件里的内容替换为自己的公私钥.
5, 防拷贝判断
SDK demo 中的 Avoid_Copy_Firm 接口为参考实现, 主要流程为读取当前芯片的 Flash Unique ID, 读取 ID 加密后的数据, 解密对比是否一致, 若不一致则中断程序运行. 可以将该接口放在 mian 函数的起始位置或者关键路径.
示例中有三个地方用户可以自定义, 对应于烧录工具用例中的修改, 即: 解密方式, 加密数据存储位置, 秘钥.
- 解密方式: 芯片提供了硬件加解密的功能, 能实现 rc4, aes, des, 3des 的加解密, 如果采用了其他的加密方式, 则需要自己实现相关的解密功能;
- 加密数据存储位置: 需要和烧录工具 AvoidCopyTestCase 用例中的 Location 参数一致;
- 秘钥: 需要和烧录工具 AvoidCopyTestCase 用例中的 Key 参数一致, demo 中直接用数组的方式指定了秘钥, 也可以是存放在 flash 中的某个位置去读取;
6, 固件烧录
- 将编译后的固件复制到烧录工具文件夹内;
- 用自己的 capub. pem 替换工具文件夹中的已有文件;
- 在 ToolConfig. ini 文件中:
修改 TestCaseConfig=AvoidCopyTestCases. xml, 此处以防拷贝烧录为例, 如果还需要其他测试功能, 可以参考 WM_W800 批量烧录工具具体操作指南_V2. 1. doc 进行用例组合;
添加设备端口号至 COMS Layout;
保存关闭, 如果已打开工具, 需要关闭工具后重新打开, 配置才能生效;
- 在 AvoidCopyTestCases. xml 文件中:
倒数第三个用例 AvoidCopyTestCase 的功能为读取 DUT 的 Flash Unique ID, 用参数 Key 的值做为秘钥进行 AES128 ECB 加密, 将加密结果写入参数 Location 指定的位置. 需要与步骤 5 中的三个地方对应:
加密方式: 工具使用的加密方式为 AES128 ECB, 如果想采用其他的加密方式需要提出需求对工具进行修改;
加密秘钥, 需要和加密方式对应, 如果采用默认的 AES128 ECB 加密, 那么秘钥的长度为 16 字节, 转化为对应的 ASCII 字符串, 如示例中的秘钥为 0~F 这 16 个十六进制数转化为对应的 ASCII 字符串;
保存位置, 加密后的数据保存位置.
- 修改最后的 FirmUpdateTestCase 用例中固件的名字, 与复制的固件名字一致, 保存关闭;
打开 FirmUpdate. exe, 勾选设备端口号, 拉低 boot (PA0) , 按下 reset, 开始烧录固件, 烧录完成后会提示成功或者失败;
拉高 boot, 按下 reset 复位设备, 即可验证防拷贝功能是否生效.
7, 注意事项
如果在开发验证阶段使用了 FirmUpdate. exe 烧录了防拷贝固件, 后续想烧录不带防拷贝功能的固件, 则需要修改 AvoidCopyTestCases. xml 中倒数第四个用例 WriteSignEnableTestCase 中的参数 Enable 改为 0, 同时 WriteDebugLevelTestCase 的调试级别改为 0, 烧录固件后即可. 之后就可以使用 Upgrade Tools 工具正常烧录固件.
学习了