概括而言,CCM 操作按照以下顺序执行:
- 提供 CCM 上下文(密钥、IV(包括标志)、长度和模式)
- 提供仅哈希数据
- 提供下一个仅哈希数据
- 提供最后一个仅哈希数据
- 提供第一个加密数据
- 提供下一个加密数据
- 读取结果数据并提供下一个加密数据
- ...
- 读取结果数据并提供最后一个加密数据
- 读取结果数据
- 读取结果数据
- 读取身份验证结果 (TAG)
可通过 DMA 或 CPU 软件管理数据的读取/写入。
要对 N 个明文块和 M 个 AAD 块实施 CCM 加密,请执行以下步骤:
- 配置输出 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中所述加载加密/解密密钥
- 通过写入 IV0、IV1、IV2 和 IV3 寄存器来加载初始化矢量 (IV)(必须包含加密操作的标志和用于身份验证和加密的 NONCE 字节)
- 配置 CTRL 寄存器以将分组密码加密模式设置为 CCM
- 通过 CTRL[KEY_SIZ] 选择密钥大小
- 通过 CTRL[DIR] = 1 选择加密方向
- 通过设置 CTRL[CCM] = 1 选择 CCM 模式
- 通过以下设置选择 CTR 模式:CTRL[CTR] =
1
-
通过设置 CTRL[SAVE_CNTXT] = 1 来启用 TAG 保存
- 配置 CTRL[CCML] - CCM-L 可以设置为任意值,表示 CCML 的加密数据长度字段加上一个字节
- 配置 CTRL[CTR_WIDTH] - 注意:CCM-L 在 IV 寄存器中设置用于 CCM 操作的实际计数器字段宽度,范围为 2 (CCM-L = 1) 到最多 8 (CCM-L = 7) 字节(含)。通过 CTR_WIDTH 选择的实际计数器宽度必须足够长才能涵盖该字段。选择的计数器字段宽度必须使计数器不会溢出
- 配置 CTRL[CCMM] - CCM-M 可以设置为任意值,对实际处理没有影响(只是存在于操作开始时加密的特殊“B0”块中)。CPU 必须从 128 位 TAG 中选择有效 TAG 字节(这些字节在最低有效的 2 * (CCMM + 1) 字节内)
- 将加密/解密字节计数 N×4 写入 AES C_LENGTH_0 和 C_LENGTH_1 寄存器
- 将身份验证数据 (AAD) 字节计数 M*4 写入 AES AAD_LENGTH 寄存器
- 等待表示整个操作完成的 DMA 输出通道中断。输出存储在步骤 1c 中配置的起始位置
- 从 TAG0/1/2/3 寄存器中读取最终 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 和长度值。