前提:加密有风险,操作需谨慎
前言
在许多项目中,经过漫长的等待,我们的 FPGA 设计终于可以投入现场部署了。前期的资金的投入及知识产权的保护,我们需要对现场部署的 FPGA 进行比特流保护以防止逆向工程和未经授权的重复使用。

为了保护我们的 FPGA 设计,AMD FPGA 支持高级加密标准 (AES)。这提供了高级别的安全性,因为比特流使用 256 位 AES 密钥加密,并在器件编程时在 FPGA 内部解码。用于解密的 AES 密钥存储在 FPGA 内部的一次性可编程电子熔丝 (eFuse) 或电池供电的 RAM (BBRAM) 中。在本篇博文中,我们将使用 Arty S7-50(便宜) 演示如何将 AES 密钥编程到 BBRAM 中。
BBRAM区域,是一个片内RAM区域。当VCCBATT_0掉电,BBRAM数据将会丢失,AES密钥也将随之丢失。VCCBATT_0该引脚可接一个1.0~1.89V范围电压的电池。
eFuse区域,是一个一次性写入区域,可永久存储密钥,该方法无需电池
在深入介绍具体步骤之前,我想重申一下,开发安全可靠的系统是一个复杂的课题。例如,最好的安全性来自于使用真正随机的密钥,因此我建议除了阅读本博客外,还请阅读XAPP1239(https://docs.xilinx.com/v/u/en-US/xapp1239-fpga-bitstream-encryption)和XAPP1084(https://docs.xilinx.com/v/u/en-US/xapp1084_tamp_resist_dsgns) 。
首先创建一个简单的 MicroBlaze 设计,它每秒通过串口无限输出一个递增计数。该 ELF 文件已与bit合并,一旦 FPGA 配置完成,就会开始输出计数。
要加密比特流,我们需要打开已实现的设计,并在比特流生成选项中设置我们希望加密的比特流。此时,可以根据需要输入加密密钥信息(我强烈建议这样做)。如果此项留空,Vivado 将生成必要的信息,但安全性较低。如果 Vivado 生成了密钥,它将在实现目录中生成一个 *.nky 文件。可以添加此文件,以便在将来运行设计时使用。当然,也可以使用相同的格式来定义生成的密钥。

Device xc7s50;
Key 0 25e2e0380c53f3a3f068baa326733a1e6f5e589a7185339fd73a922e218de87f;
Key StartCBC 9af2391ad0118907e5ba7d4b16a6c3d0;
Key HMAC 37fe8c2b9ab49da759b7cad0687d05b20c2b1a5f09f74441c2201ebfdecb0db3;
保存这些选项后将会向目标 XDC 文件中添加如下约束。
set_property BITSTREAM.ENCRYPTION.ENCRYPT YES [current_design]
set_property BITSTREAM.ENCRYPTION.KEYFILE {C:\hdl_clients\s7_enc\s7_enc.runs\impl_1\design_1_wrapper.nky} [current_design]
将 FPGA 连接到硬件管理器后,就可以对 BBRAM 或 eFuse 密钥进行编程。

在此示例中,我们将选择程序 BBR,这将打开一个对话框,使我们能够对 NKY 文件进行编程。

选择 NKY 文件后,AES 密钥将显示,以便确认是否加载了正确的密钥。关闭对话框后,密钥将被编程,TCL 控制台将显示此操作的成功或失败。

我们现在可以使用已用相同密钥加密的 JTAG 比特流对设计进行编程。
随着新配置的加载,这、将重新启动从 0 开始运行的 MicroBlaze 中的程序。

如果我们关闭电源或重置 BBR 密钥,然后尝试对加密位流进行编程,我们将发现编程未完成,因为 FPGA 中没有存储解密密钥。

使用此流程,可以开始保护已部署的系统。如果使用 eFuse 编程加密密钥,请务必遵守 XAPP1239 中规定的规则,因为 AES 密钥和相关寄存器必须同时进行编程。