Skip to main content
欢迎来到PAWPAW技术文档网站了解更多信息

保护知识产权和设备真实性

xCORE 设备内置了一次性可编程(OTP)存储器,可在设备生产测试阶段或之后进行编程。您可以将 xCORE AES 模块程序到设备的 OTP 中,使得程序能够以加密形式存储在闪存上。这样做主要提供以下好处:

  • 保密性

    加密程序难以进行逆向工程分析。

  • 程序真实性

    AES 加载器将拒绝加载经篡改的或第三方的程序。

  • 设备真实性

    使用您的私钥加密的程序,无法被第三方提供的 xCORE 设备克隆。

AES 模块一旦被编程,OTP 的安全位将被激活,使得每个 Tile 变成一个“安全岛屿”,在这里所有的计算、内存访问、I/O 和通信都仅能由运行在该 Tile 上的代码控制。激活这些位将:

  • 强制引导从 OTP 启动,以防止绕过启动过程,

  • 关闭对该 Tile 的 JTAG 访问,以防止密钥泄露,

  • 阻止对 OTP 的进一步写入,以避免后续的更改。

危险

虽然 AES 模块为防御一般黑客攻击提供了强大的保护措施,但需要认识到,不存在绝对的安全措施,任何决心十足、资源充足的攻击者理论上都有可能提取您的密钥。

xCORE AES 模块

xCORE AES 模块负责对来自 SPI 闪存设备的程序进行认证和解密。一旦被编入设备,它将启用以下安全启动流程,如 使用 AES 模块的安全启动流程 所示。

../../../_images/aes-boot.png

图 7 使用 AES 模块的安全启动流程

  1. 设备从其 ROM 加载主引导程序,该程序检测到 OTP 中设定了安全启动位,随后加载并执行 OTP 中的 AES 模块。

  2. AES 模块通过 SPI 接口将闪存加载器加载至 RAM。

  3. AES 模块利用 CMAC-AES-128 算法及 128 位认证密钥对闪存加载器进行认证。若认证失败,启动过程将终止。

  4. AES 模块将认证密钥和解密密钥存入寄存器,然后跳转至闪存加载器。

闪存加载器将执行以下操作:

  1. 选择验证 CRC 后编号最高的镜像。

  2. 使用其 CMAC 标签和认证密钥对选定的镜像头部进行认证。若认证失败,启动过程将终止。

  3. 对程序/数据段表进行认证、解密并加载到内存中。若任一镜像认证失败,启动过程将终止。

  4. 开始执行程序。

针对多节点系统,AES 模块被编入某一 Tile 的 OTP 中,而安全的 boot-from-xCONNECT Link 协议则被编入所有其他 Tiles 中。

开发时启用 AES 模块

您可以在开发过程或设备制造阶段的任何时刻激活 AES 模块。在开发环境中,您可以激活该模块但不设置安全位,使得:

  • XFLASH 可以用来将程序加载到闪存,

  • XGDB 可用于调试设备上运行的程序,

  • XBURN 可以在之后写入额外的 OTP 位以保护设备。

在生产环境中,必须采取措施保护设备,防止最终用户从 OTP 中读取密钥。

要将 AES 模块编程到您的开发板上的 xCORE 设备,请 启动XTC工具 并执行以下命令:

  1. xburn --genkey *keyfile*

    XBURN 生成两个随机的 128 位密钥并存入 keyfile 中。第一行是认证密钥,第二行是解密密钥。

    这些密钥通过开源库 crypto++ 生成。如果您愿意,也可以自行创建此文件并提供您的密钥。

  2. xburn -l

    XBURN 显示连接到您 PC 的所有 JTAG 适配器及其各自 JTAG 链上的设备的编号列表,格式为:

    ID - NAME (ADAPTER-SERIAL-NUMBER)

  3. xburn --id *ID* --lock *keyfile* --target-file *target*.xn --enable-jtag --disable-master-lock

    XBURN 将 AES 模块和安全密钥写入目标设备的 OTP 存储,并设置其安全启动位。用于启动的 SPI 端口信息从 XN 文件中获取。

要对您的程序进行加密并写入闪存,请执行以下命令:

xflash --id *ID* *bin*.xe --key *keyfile*

要保护 xCORE 设备,以防止任何进一步开发活动,请执行以下命令:

xburn --id *ID* --target-file *target*.xn --disable-jtag --enable-master-lock

生产环境下的闪存编程流程

在生产制造环境中,通常需要将相同程序编程到多个 SPI 设备中。

要生成加密的 xCORE 闪存格式镜像,请启动XTC工具并执行以下命令:

xflash *prog*.xe -key *keyfile* -o *image-file*

该镜像可以直接通过第三方闪存编程器编程到闪存中,或者可以通过使用 XFLASH(借助 xCORE 设备)进行编程。使用 XFLASH 编程,请执行以下命令:

  1. xflash -l

    XFLASH 显示连接到您 PC 的所有 JTAG 适配器及其各自 JTAG 链上的设备的编号列表,格式为:

    ID - NAME (ADAPTER-SERIAL-NUMBER)

  2. xflash --id *ID* --target-file *platform*.xn --write-all *image-file*

    XFLASH 创建一个包含初级加载器和工厂镜像(由您编译的程序的二进制和数据段组成)的 xCORE 闪存格式镜像,并通过 xCORE 设备将此镜像写入闪存。

XN 文件必须定义一个 SPI 闪存设备,并指定它连接到的 xCORE 设备的四个端口。

生产环境下的 OTP 编程流程

在生产制造环境中,通常需要将相同的密钥编程到多个 xCORE 设备中。

要生成包含 AES 模块和安全密钥的 OTP 镜像,请启动XTC工具并执行以下命令:

  1. xburn --genkey *keyfile*

    XBURN 生成两个随机的 128 位密钥并存入 keyfile 中。第一行是认证密钥,第二行是解密密钥。

    这些密钥通过开源库 crypto++ 生成。如果您愿意,也可以自行创建此文件并提供您的密钥。

  2. xburn --target-file *target*.xn --lock *keyfile* -o *aes-image*.otp

    XBURN 创建一个包含 AES 模块、安全密钥和安全位值的镜像。

警告

该镜像包含密钥,必须严格保密。

要在生产环境中将 AES 模块和安全位编程到设备中,请执行以下命令:

  1. xburn -l

    XBURN 显示连接到主机的所有 JTAG 适配器及其各自 JTAG 链上的设备的编号列表,格式为:

    ID - NAME (ADAPTER-SERIAL-NUMBER)

  2. xburn --id *ID* --target-file *target*.xn *aes-image*.otp

    XBURN 执行一个程序,将 AES 模块和安全密钥编程进设备的 OTP,并设置安全启动位。XBURN 成功返回 0,失败返回非零值。

应用设计的安全考量

在程序设计中,对各种软件和硬件功能的使用及其潜在的安全影响需要慎重考虑:

  • 数据分区

    由于数据分区既未加密也未签名,因此对于安全应用而言,必须将其视作不可信赖的。尽管可以为数据分区设计强健的安全方案,但这需要由应用程序自身来实现,XFLASH 并不提供此类支持。

  • 软件定义内存

    软件内存支持安全应用的使用,但“.SwMem”段中的数据不会进行签名或加密处理。因此,应用程序需要认为这些段中存储的数据以及运行时从闪存读取的数据是不可信的。

    应用程序可以采用与数据分区相似的方式实现安全方案,但这可能会牺牲软件内存的性能。

  • LPDDR

    “.ExtMem”段中的数据通过安全引导程序从闪存加载,并利用提供给 XFLASH 的密钥进行加密和签名。

    这为存储在 LPDDR 内存中的数据提供了基本安全保障。但需注意,LPDDR 作为外部离芯片存储,在应用运行期间可能遭受硬件攻击的监听和篡改。

    因此,安全应用在使用 LPDDR 时应严格遵循安全编程规范进行谨慎处理。

如果您的应用程序需求包括上述功能,并且追求高水平的安全性,确保应用程序不信任任何存在于外部存储器中的数据变得尤为重要。

具体而言,这包括:

  1. 利用现代加密标准验证外部数据的真实性

    为防止在初次验证后外部数据被篡改的攻击,必须每次读取数据时都进行验证。

    针对大量数据,可以考虑使用如哈希树这样的结构来实现高效且经过验证的访问。

    如果需要对外部数据保密,还应考虑进行加密处理。

    将密钥材料嵌入到应用程序代码中是安全的,因为它将由 xCORE AES 模块保护。但强烈建议不要在您的应用程序中重用 XBURN 和 XFLASH 提供的安全引导密钥,而应使用不同的密钥,以防应用程序被破解时导致安全引导密钥泄露。

  2. 应用程序的防御性编程

    身份验证是第一道防线——第二道则是设计应用程序,确保即使外部数据被攻击者修改,应用程序也不会因此受到损害。

    这需要彻底审查代码,确保在收到异常外部数据时,程序的行为是可预测且安全的。

    不可预测的行为可能导致缓冲区溢出或类似的漏洞,攻击者可能利用这些漏洞控制设备并泄露知识产权。