IC:

支持的芯片

Ameba SoC

RTL8721Dx

RTL8726E

RTL8720E

RTL8730E

支持状态

Y

Y

Y

Y

概述

硬件加密引擎(也称 IPsec)通过硬件加速实现密码学功能(如认证、加解密),相较于软件实现具有以下优势:

  • ​高性能​​:通过硬件卸载减少 CPU 负载,提升加解密效率;

  • ​​高安全性​​:密钥可通过 OTP 物理存储,避免软件直接访问密钥,防止密钥泄露;

  • ​资源节省​​:减少内存占用和软件开销,适用于嵌入式场景。

OTP 密钥管理

硬件加密引擎提供了两种密钥加载方式​​:

  • ​软件传递​​:密钥由应用程序动态传入(软件可访问)

  • OTP 自动加载​​:密钥预烧录至 OTP 物理存储区(软件不可访问,仅加密引擎可访问,防止被篡改或读取)

OTP 物理存储区支持存储6组密钥,需通过 efuse 命令烧录。

在这六个密钥中,SHA HMAC 支持两个安全密钥和两个非安全密钥,AES 则支持四个安全密钥和四个非安全密钥。

../../_images/opt_keys_for_crypto_rtl8721d.svg

引擎类型

安全性

密钥索引

OTP 密钥

SHA HMAC

安全

0

S_IPSEC_Key1

SHA HMAC

安全

1

S_IPSEC_Key2

SHA HMAC

非安全

0

NS_IPSEC_Key1

SHA HMAC

非安全

1

NS_IPSEC_Key2

AES

安全

0

S_IPSEC_Key1

AES

安全

1

S_IPSEC_Key2

AES

安全

2

RSIP_AES_key1

AES

安全

3

RSIP_AES_key2

AES

非安全

0

NS_IPSEC_Key1

AES

非安全

1

NS_IPSEC_Key2

AES

非安全

2

RSIP_AES_key1

AES

非安全

3

RSIP_AES_key2

OTP 密钥的详细功能如下所示:

OTP 密钥名称

地址

大小

默认值

描述

S_IPSEC_Key1 (RDP)

逻辑映射 0x200

32 字节

每个字节为 0xFF

启用 OTPKey_init 功能时,安全加密引擎将自动加载此密钥

用于 HMAC 或 AES 算法

S_IPSEC_Key2

(安全启动 HMAC)

逻辑映射 0x220

32 字节

每个字节为 0xFF

NS_IPSEC_Key1

逻辑映射 0x240

32 字节

每个字节为 0xFF

启用 OTPKey_init 功能时,非安全加密引擎将自动加载此密钥

用于 HMAC 或 AES 算法

NS_IPSEC_Key2

逻辑映射 0x260

32 字节

每个字节为 0xFF

RSIP_AES_key1

逻辑映射 0x2c0

32 字节

每个字节为 0xFF

启用 OTPKey_init 功能时,非安全 AES 引擎和安全 AES 引擎

将自动加载此密钥用于 AES 算法

RSIP_AES_key2

逻辑映射 0x2e0

32 字节

每个字节为 0xFF

S_IPSEC_Key1_Read_Protection

物理映射 0x365[3]

1 比特

1

0:启用 S_IPSEC_Key1 读保护,禁止密钥被读出

1:禁用 S_IPSEC_Key1 读保护

S_IPSEC_Key1_Write_Protection

物理映射 0x365[4]

1 比特

1

0:启用 S_IPSEC_Key1 写保护,禁止密钥被黑客写为全 0

1:禁用 S_IPSEC_Key1 写保护

S_IPSEC_Key2_Read_Protection

物理映射 0x365[5]

1 比特

1

0:启用 S_IPSEC_Key2 读保护,禁止密钥被读出

1:禁用 S_IPSEC_Key2 读保护

S_IPSEC_Key2_Write_Protection

物理映射 0x365[6]

1 比特

1

0:启用 S_IPSEC_Key2 写保护,禁止密钥被黑客写为全 0

1:禁用 S_IPSEC_Key2 写保护

NS_IPSEC_Key1_Read_Protection

物理映射 0x365[7]

1 比特

1

0:启用 NS_IPSEC_Key1 读保护,禁止密钥被读出

1:禁用 NS_IPSEC_Key1 读保护

NS_IPSEC_Key1_Write_Protection

物理映射 0x366[0]

1 比特

1

0:启用 NS_IPSEC_Key1 写保护,禁止密钥被黑客写为全 0

1:禁用 NS_IPSEC_Key1 写保护

NS_IPSEC_Key2_Read_Protection

物理映射 0x366[1]

1 比特

1

0:启用 NS_IPSEC_Key2 读保护,禁止密钥被读出

1:禁用 NS_IPSEC_Key2 读保护

NS_IPSEC_Key2_Write_Protection

物理映射 0x366[2]

1 比特

1

0:启用 NS_IPSEC_Key2 写保护,禁止密钥被黑客写为全 0

1:禁用 NS_IPSEC_Key2 写保护

RSIP_AES_Key1_Read_Protection

物理映射 0x366[7]

1 比特

1

0:启用 RSIP_AES_Key1 读保护,禁止密钥被黑客写为全 0

1:禁用 RSIP_AES_Key1 读保护

RSIP_AES_Key1_Write_Protection

物理映射 0x367[0]

1 比特

1

0:启用 RSIP_AES_Key1 写保护,禁止密钥被读出

1:禁用 RSIP_AES_Key1 写保护

RSIP_AES_Key2_Read_Protection

物理映射 0x367[1]

1 比特

1

0:启用 RSIP_AES_Key2 读保护,禁止密钥被黑客写为全 0

1:禁用 RSIP_AES_Key2 读保护

RSIP_AES_Key2_Write_Protection

物理映射 0x367[2]

1 比特

1

0:启用 RSIP_AES_Key2 写保护,禁止密钥被读出

1:禁用 RSIP_AES_Key2 写保护

备注

  • 对于 IPsec 的两个安全密钥:如果系统启用了 RDP,SDK 默认使用 S_IPSEC_Key1 实现安全数据保护;如果安全启动模块选择 HMAC 作为哈希算法,则使用 S_IPSEC_Key2

  • 用户需根据上述规则合理分配密钥用途,完整配置流程请参考 安全启动读保护.

密钥顺序与字节序

加密引擎的密钥字节序与 mbedtls 一致,需遵循​​小端模式。

例如,某个32位密钥为: 0x0123456789abcdef0123456789abcdef00112233445566778899aabbccddeeff

当使用 Realtek API 或 mbedtls API 将密钥传递至硬件加密引擎时,按​​小端模式​​将密钥字节逆序排列后为:

u8 key1[32]={
0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa, 0x99, 0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11, 0x00,
0xef, 0xcd, 0xab, 0x89, 0x67, 0x45, 0x23, 0x01, 0xef, 0xcd, 0xab, 0x89, 0x67, 0x45, 0x23, 0x01
};

以 NS_SHA_key2 为例,使用 efuse wraw 命令将密钥烧录至 OTP 物理地址 0x260 的操作如下:

efuse wraw 0x260 20 ffeeddccbbaa99887766554433221100efcdab8967452301efcdab8967452301

对应 OTP 中的内容为:

0x260

ff

ee

dd

cc

bb

aa

99

88

77

66

55

44

33

22

11

00

0x270

ef

cd

ab

89

67

45

23

01

ef

cd

ab

89

67

45

23

01

密钥烧录流程

烧写 OTP 物理地址映射的流程如下:

  1. 生成密钥

  2. 使用命令 efuse wraw <address> <length> <data> 将密钥写入 OTP 物理地址映射

    efuse wraw 0x260 20 0123456789abcdef0123456789abcdef00112233445566778899aabbccddeeff
    
  3. 使用 efuse rraw 命令回读 OTP 密钥以验证写入是否正确。若验证失败,需重新写入

    efuse rraw
    
  4. 确认密钥写入无误后,启用密钥读保护和写保护,防止密钥泄露或被篡改

    efuse wraw 0x366 1 f9
    

备注

密钥的读保护和写保护一旦烧录,密钥将永久无法再次读取。请妥善保管密钥对。

用法

初始化

在使用加密引擎开始计算前,必须调用初始化 API 初始化该模块。

备注

当系统进入低功耗状态时,加密引擎电源将被关闭,其配置参数将重置为默认值。因此,建议在系统唤醒后重新执行初始化流程以确保功能正常。

自动加载 OTP 密钥

  1. 初始化 AES OTP 密钥功能

    CRYPTO_OTPKey_Init(keynum, ENABLE);
    
  2. 初始化 HMAC OTP 密钥功能

    CRYPTO_OTPKey_SHA_Init(keynum, ENABLE);
    

开始加密引擎计算

选择哈希或加密算法,调用相关 API 执行哈希摘要或加密运算。

哈希算法

如果选择哈希算法,且消息长度不超过 245745 字节 (即 15 × (2¹⁴ -1)),可直接使用哈希 API rtl_crypto_xxx 计算摘要。

如果消息长度超过该限制(245745 字节),或需要将消息分割为多个固定大小的数据块进行处理,应使用 分块哈希机制(Sequential Hash Mechanism) 进行验证。

分块哈希操作步骤:

  1. 初始化分块哈希:调用 rtl_crypto_xxx_init 初始化上下文。

  2. 处理分块数据:对每个数据块调用 rtl_crypto_xxx_update

  3. 处理末块数据:对最后一个数据块调用 rtl_crypto_xxx_final 生成最终摘要。

备注

  • 加密引擎通过 DMA 传输数据并绕过 D-Cache,若摘要数组为栈变量且首地址未按32 字节对齐,可能导致缓存行脏数据。解决方法如下:

    • 将摘要数组定义为全局变量

    • 或确保局部变量的摘要数组首地址 32 字节对齐

    • 或计算完成后强制从内存同步数据

    DCache_Invalidate(((u32)digest&CACHE_LINE_ADDR_MSK),(sizeof(digest)+CACHE_LINE_SIZE));
    
  • 应用核(如 KM4)进入电源门控状态后,需重新初始化该模块以恢复正常功能

  • 为避免多核同时访问加密引擎导致错误,需在 CRYPTO_OTPKey_Init 前后添加互斥锁,互斥锁会在加密引擎计算完成后释放

    /*获取信号量以取得加密引擎使用权*/
    {
    while (IPC_SEMTake(IPC_SEM_CRYPTO, timeout) != _TRUE);
    CRYPTO_OTPKey_SHA_Init(keynum, status);
    rtl_crypto_hmac_sha2_update(u8 *message, IN u32 msglen, hw_sha_context *ctx);
    ...
    rtl_crypto_hmac_sha2_final(u8 *pDigest, hw_sha_context *ctx);
    
    /*释放信号量以归还加密引擎使用权*/
    IPC_SEMFree(IPC_SEM_CRYPTO);
    }
    

加密算法

使用加密算法加密/解密消息的步骤如下:

  1. 调用加密 API rtl_crypto_aes_xxx_init 完成初始化

  2. 加密/解密消息

    • 调用 rtl_crypto_aes_xxx_encrypt 对原始消息进行加密

    • 调用 rtl_crypto_aes_xxx_decrypt 对原始消息进行解密

备注

为避免多核同时访问加密引擎导致错误,需在 CRYPTO_OTPKey_Init 前后添加互斥锁,互斥锁会在 rtl_crypto_aes_xxx_encryptrtl_crypto_aes_xxx_decrypt 之后释放。

/*获取信号量以取得加密引擎使用权*/
while (IPC_SEMTake(IPC_SEM_CRYPTO, timeout) != _TRUE);
CRYPTO_OTPKey_Init(keynum, status);
rtl_crypto_aes_xxx_encrypt(message, msglen, pIv, ivlen, pResult);
/*free sema to release the right to crypto engine*/
IPC_SEMFree(IPC_SEM_CRYPTO);
/*take sema to obtain the right to crypto engine*/
while (IPC_SEMTake(IPC_SEM_CRYPTO, timeout) != _TRUE);
   CRYPTO_OTPKey_Init(keynum, status);
   rtl_crypto_aes_xxx_decrypt(message, msglen, pIv, ivlen, pResult);
/*释放信号量以归还加密引擎使用权*/
IPC_SEMFree(IPC_SEM_CRYPTO);

代码样例

相关代码样例位于 {SDK}\component\example\peripheral\raw\Crypto