在此模式下,引擎在内部计算 H 和 Y0 加密值。概括而言,编程涉及以下步骤:
- 提供 GCM 上下文(密钥、IV、长度和模式)。
- 提供 AAD 数据(并等待 H 计算和 Y0 加密)。
- 提供下一个 AAD 数据。
- 提供最后一个 AAD 数据。
- 提供第一个加密数据。
- 提供下一个加密数据。
- 读取结果数据并提供下一个加密数据。
- ...
- 读取结果数据并提供最后一个加密数据。
- 读取结果数据。
- 读取结果数据。
- 读取身份验证结果 (TAG)。
要对 N 个明文块和 M 个 AAD 块实施 GCM 加密,请执行以下步骤:
- 配置输出 DMA 通道以保存密文:
- 将 DMA 通道触发器选项设置为 AES Trig1
- 将 DMA 通道源地址设置为 DATA_OUT
- 将 DMA 通道目标地址设置为要存储密文的位置(例如,SRAM)
- 将 DMA 通道传输大小设置为 N×4
- 将 DMA 通道模式设置为单字或单字节传输模式
- 在 AES 事件寄存器中,取消屏蔽 DMA_TRIG_DATAOUT 的 IMASK 寄存器中的 Trig1
- 配置输入 DMA 通道以加载 AAD 和明文:
- 将 DMA 通道触发器选项设置为 AES Trig0
- 将 DMA 通道源地址设置为存储明文的位置(例如,SRAM)
- 将 DMA 通道目标地址设置为 DATA_IN
- 将 DMA 通道传输大小设置为 (N+M)*4
- 将 DMA 通道模式设置为单字或单字节传输模式
- 在 AES 事件寄存器中,取消屏蔽 DMA_TRIG0 的 IMASK 寄存器中的 Trig0
- 为 DMA 控制器中的输出 DMA 通道配置并启用 DMA 中断
- 配置 DMA_HS 以实现基于 DMA 的握手:设置 DMA_HS[DMA_DATA_ACK] = 1
- 按照节 10.2.1中所述加载加密/解密密钥
- 向 GCMCCM_TAGn (0,1,2,3) 寄存器加载 0
- 通过写入 IV0、IV1、IV2 和 IV3 寄存器来加载初始化矢量 (IV)
- 配置 CTRL 寄存器以将分组密码加密模式设置为 GCM
- 通过 CTRL[KEY_SIZ] 选择密钥大小
- 通过 CTRL[DIR] = 1 选择加密方向
- 通过设置 CTRL[GCM] = 3 选择 GCM 模式
- 通过以下设置选择 CTR 模式:CTRL[CTR] =
1
-
通过设置 CTRL[SAVE_CNTXT] = 1 来启用 TAG 保存
- 将加密/解密字节计数 N×4 写入 AES C_LENGTH_0 和 C_LENGTH_1 寄存器
- 将身份验证数据 (AAD) 字节计数 M*4 写入 AES AAD_LENGTH 寄存器
- 等待表示整个操作完成的 DMA 输出通道中断。输出存储在步骤 1c 中配置的起始位置
- 从 TAG0、TAG1、TAG2、TAG3 寄存器中读取最终 TAG
注: AAD 和加密数据可能在结尾出现错位。CPU 必须用零将这两者填充到 128 位边界。更正式的说法是 AAD 和加密数据填充必须满足位字符串:0n,其中 0 <= n <= 127。这意味着 AAD 必须作为独立的块提供给引擎,以便加密数据在开始时为 128 位对齐。如果 AAD/加密数据流为 128 位对齐,则无需填充。由于引擎仅支持字节,n 必须满足 (n MOD 8) = 0。此外,由于单个 DMA 通道同时提供 AAD 和明文,因此必须将整个数据连续组织到存储器中,首先是 M 个 AAD 块,然后是 N 个明文块。当 CPU 软件通过中断处理来直接提供输入时,这种存储器连续性限制不适用。
不要在两个长度值中都加载零。如果完成了一个数据流,而下一个数据流使用相同的密钥和控制方式,则只需要重新加载 IV 和长度值。