|
STM32G474xx HAL用户手册
|
00001 /** 00002 ****************************************************************************** 00003 * @file stm32g4xx_hal_cryp.c 00004 * @author MCD Application Team 00005 * @brief CRYP HAL模块驱动。 00006 * 本文件提供固件功能来管理加密(CRYP)外设的以下功能: 00007 * + 初始化、去初始化、设置配置和获取配置功能 00008 * + AES处理功能 00009 * + DMA回调功能 00010 * + CRYP中断处理程序管理 00011 * + 外设状态功能 00012 * 00013 ****************************************************************************** 00014 * @attention 00016 * 00017 * Copyright (c) 2019 STMicroelectronics. 00018 * All rights reserved. 00019 * 00020 * This software is licensed under terms that can be found in the LICENSE file 00021 * in the root directory of this software component. 00022 * If no LICENSE file comes with this software, it is provided AS-IS. 00023 * 00024 ****************************************************************************** 00025 @verbatim 00026 ============================================================================== 00027 ##### 如何使用此驱动 ##### 00028 ============================================================================== 00029 [..] 00030 CRYP HAL驱动可用于CRYP或TinyAES外设,如下所示: 00031 00032 (#)通过实现HAL_CRYP_MspInit()初始化CRYP底层资源: 00033 (##) 使用__HAL_RCC_CRYP_CLK_ENABLE()启用CRYP接口时钟 00034 或TinyAES外设的__HAL_RCC_AES_CLK_ENABLE() 00035 (##) 如果使用中断(例如HAL_CRYP_Encrypt_IT()) 00036 (+++) 使用HAL_NVIC_SetPriority()配置CRYP中断优先级 00037 (+++) 使用HAL_NVIC_EnableIRQ()启用CRYP IRQ处理程序 00038 (+++) 在CRYP IRQ处理程序中调用HAL_CRYP_IRQHandler() 00039 (##) 如果使用DMA控制数据传输(例如HAL_CRYP_Encrypt_DMA()) 00040 (+++) 使用__RCC_DMAx_CLK_ENABLE()启用DMAx接口时钟 00041 (+++) 配置并启用两个DMA流,一个用于管理从内存到外设的数据传输 00042 (输入流),另一个用于管理从外设到内存的数据 00043 传输(输出流) 00044 (+++) 使用__HAL_LINKDMA()将初始化的DMA句柄关联到CRYP DMA句柄 00045 (+++) 配置优先级并在两个DMA通道上启用传输完成 00046 中断的NVIC。输出通道应具有比输入通道更高的 00047 优先级HAL_NVIC_SetPriority()和HAL_NVIC_EnableIRQ()。 00048 00049 (#)根据指定参数初始化CRYP: 00050 (##) 数据类型:1位、8位、16位或32位。 00051 (##) 密钥大小:128、192或256。 00052 (##) 算法模式:DES/TDES算法ECB/CBC或AES算法ECB/CBC/CTR/GCM或CCM。 00053 (##) 初始化向量(计数器)。在ECB模式下不使用。 00054 (##) 用于加密/解密的密钥缓冲区。 00055 (+++) 在某些特定配置中,密钥由应用程序在HAL范围外编写。 00056 在这种情况下,用户仍可以照常使用HAL API,但必须确保pKey指针设置为NULL。 00057 (##) DataWidthUnit字段。它指定数据长度(或认证的数据长度)。 00058 算法)是按字还是按字节。 00060 (##) 仅在AES GCM和CCM算法中用于认证的头部。 00061 (##) HeaderSize字段,提供头部缓冲区的大小(按字或字节), 00062 取决于HeaderWidthUnit字段。 00063 (##) HeaderWidthUnit字段。它指定头部长度(对于认证算法) 00064 是按字还是按字节。 00065 (##) B0块是仅在AES CCM模式下使用的第一个认证块。 00066 (##) KeyIVConfigSkip用于连续处理多条消息(请参阅下面的更多信息)。 00067 00069 (#)提供三种处理(加密/解密)函数: 00070 (##) 轮询模式:加密和解密API是阻塞函数 00071 即它们处理数据并等待处理完成, 00072 例如HAL_CRYP_Encrypt和HAL_CRYP_Decrypt 00073 (##) 中断模式:加密和解密API是非阻塞函数 00074 即它们在中断下处理数据, 00075 例如HAL_CRYP_Encrypt_IT和HAL_CRYP_Decrypt_IT 00076 (##) DMA模式:加密和解密API是非阻塞函数 00077 即数据传输由DMA确保, 00078 例如HAL_CRYP_Encrypt_DMA和HAL_CRYP_Decrypt_DMA 00079 00080 (#)当在HAL_CRYP_Init()之后首次调用处理函数时 00081 配置CRYP外设并处理输入缓冲区。 00083 第二次调用时,无需初始化CRYP,用户需要通过 00084 HAL_CRYP_GetConfig() API获取当前配置,然后只需 00085 HAL_CRYP_SetConfig()设置新参数,最后可以开始加密/解密。 00086 00087 (#)调用HAL_CRYP_DeInit()去初始化CRYP外设。 00088 00089 (#)要使用HAL_CRYP_Encrypt()或HAL_CRYP_Decrypt()连续调用处理单个消息 00090 而无需在每个API调用之间重新配置密钥或初始化向量, 00091 初始化结构中的字段KeyIVConfigSkip必须设置为CRYP_KEYIVCONFIG_ONCE。 00092 HAL_CRYP_Encrypt_IT()、HAL_CRYP_Decrypt_IT()、HAL_CRYP_Encrypt_DMA() 00093 或HAL_CRYP_Decrypt_DMA()的连续调用也是如此。 00094 00095 [..] 00096 加密处理器支持以下标准: 00097 (#) 数据加密标准(DES)和三重DES(TDES)仅由CRYP1外设支持: 00098 (##) 64位数据块处理 00099 (##) 支持的链接模式: 00100 (+++) 电子密码本(ECB) 00101 (+++) 密码块链接(CBC) 00102 (##) 支持的密钥长度:64位、128位和192位。 00103 (#) 高级加密标准(AES)由CRYP1和TinyAES外设支持: 00104 (##) 128位数据块处理 00105 (##) 支持的链接模式: 00106 (+++) 电子密码本(ECB) 00107 (+++) 密码块链接(CBC) 00108 (+++) 计数器模式(CTR) 00109 (+++) Galois/计数器模式(GCM/GMAC) 00110 (+++) 带密码块链接的消息认证码计数器(CCM) 00111 (##) 支持的密钥长度: 00112 (+++) CRYP1外设:128位、192位和256位。 00113 (+++) TinyAES外设:128位和256位 00114 00115 [..] 00116 (@) 必须特别注意密钥和初始化向量IV的格式! 00117 00118 [..] 如果密钥定义为128位长数组key[127..0] = {b127 ... b0},其中 00119 b127是MSB,b0是LSB,则必须将密钥存储在MCU内存中 00120 (+) 作为字序列,其中MSB字先出现(占据 00120 最低内存地址) 00121 (++) 地址n+0:0b b127 .. b120 b119 .. b112 b111 .. b104 b103 .. b96 00122 (++) 地址n+4:0b b95 .. b88 b87 .. b80 b79 .. b72 b71 .. b64 00123 (++) 地址n+8:0b b63 .. b56 b55 .. b48 b47 .. b40 b39 .. b32 00124 (++) 地址n+C:0b b31 .. b24 b23 .. b16 b15 .. b8 b7 .. b0 00125 [..] 下面,另一个图示,考虑由16字节{B15..B0}组成的128位长密钥。 00126 组成密钥的4个32位字必须按以下方式存储在MCU内存中: 00127 (+) 地址n+0:0x B15 B14 B13 B12 00128 (+) 地址n+4:0x B11 B10 B9 B8 00129 (+) 地址n+8:0x B7 B6 B5 B4 00130 (+) 地址n+C:0x B3 B2 B1 B0 00131 [..] 这导致预期的设置 00132 (+) AES_KEYR3 = 0x B15 B14 B13 B12 00133 (+) AES_KEYR2 = 0x B11 B10 B9 B8 00134 (+) AES_KEYR1 = 0x B7 B6 B5 B4 00135 (+) AES_KEYR0 = 0x B3 B2 B1 B0 00136 00137 [..] 256位长密钥(由32字节{B31..B0}组成)也必须应用相同的格式。 00138 组成密钥的8个32位字必须按以下方式存储在MCU内存中: 00139 (+) 地址n+00:0x B31 B30 B29 B28 00140 (+) 地址n+04:0x B27 B26 B25 B24 00141 (+) 地址n+08:0x B23 B22 B21 B20 00142 (+) 地址n+0C:0x B19 B18 B17 B16 00143 (+) 地址n+10:0x B15 B14 B13 B12 00144 (+) 地址n+14:0x B11 B10 B9 B8 00145 (+) 地址n+18:0x B7 B6 B5 B4 00146 (+) 地址n+1C:0x B3 B2 B1 B0 00147 [..] 这导致预期的设置 00148 (+) AES_KEYR7 = 0x B31 B30 B29 B28 00149 (+) AES_KEYR6 = 0x B27 B26 B25 B24 00150 (+) AES_KEYR5 = 0x B23 B22 B21 B20 00151 (+) AES_KEYR4 = 0x B19 B18 B17 B16 00152 (+) AES_KEYR3 = 0x B15 B14 B13 B12 00153 (+) AES_KEYR2 = 0x B11 B10 B9 B8 00154 (+) AES_KEYR1 = 0x B7 B6 B5 B4 00155 (+) AES_KEYR0 = 0x B3 B2 B1 B0 00156 00157 [..] 初始化向量IV(4个32位字)的格式必须与 00158 128位长密钥相同。 00159 00160 [..] 请注意,密钥和IV寄存器对交换模式选择不敏感。 00161 00162 [..] 本节描述CRYP1和TinyAES外设支持的AES Galois/计数器模式(GCM): 00163 (#) 支持的算法: 00164 (##) Galois/计数器模式(GCM) 00165 (##) Galois消息认证码(GMAC):与仅由头部组成的GCM算法完全相同。 00166 (#) GCM执行四个阶段: 00167 (##) 初始化阶段:外设准备GCM哈希子密钥(H)并进行IV处理 00168 (##) 头部阶段:外设处理附加认证数据(AAD),仅进行哈希 00169 计算。 00170 (##) 负载阶段:外设处理明文(P),包括哈希计算+密钥流 00171 加密+数据异或。对于密文(C)的工作方式类似。 00172 (##) 最终阶段:外设使用最后一块数据生成认证标签(T)。 00173 (#) GCM中的消息结构定义如下: 00174 (##) 由IV和计数器组成的16字节初始计数器块(ICB) 00175 (##) 认证头A(也称为附加认证数据AAD) 00176 这部分消息仅被认证,不加密。 00177 (##) 明文消息P既被认证又被加密为密文。 00178 GCM标准规定密文与明文具有相同的位长度。 00179 (##) 最后一块由A的长度(64位)和密文的长度 00180 (64位)组成 00181 00183 [..] 下面提供了GCM消息结构的更详细描述。 00184 00185 [..] 本节描述CRYP1和TinyAES外设支持的AES计数器与密码块链接-消息 00186 认证码(CCM): 00187 (#) CCM的特定参数: 00188 00189 (##) B0块:遵循NIST特别出版物800-38C, 00190 (##) B1块(头部) 00191 (##) CTRx块:控制块 00192 00193 [..] 下面提供了CCM消息结构的详细描述。 00194 00195 (#) CRYP1外设的CCM执行四个阶段: 00196 (##) 初始化阶段:外设准备GCM哈希子密钥(H)并进行IV处理 00197 (##) 头部阶段:外设处理附加认证数据(AAD),仅进行哈希 00198 计算。 00199 (##) 负载阶段:外设处理明文(P),包括哈希计算+密钥流 00200 加密+数据异或。对于密文(C)的工作方式类似。 00201 (##) 最终阶段:外设使用最后一块数据生成认证标签(T)。 00202 (#) TinyAES外设中的CCM: 00203 (##) 为了执行消息负载加密或解密,AES配置为CTR模式。 00204 (##) 认证执行两个阶段: 00205 - 头部阶段:外设首先处理附加认证数据(AAD),然后处理明文消息 00206 仅使用明文负载(不是密文负载),不产生输出。 00207 (##) 最终阶段:外设使用最后一块数据生成认证标签(T)。 00208 00209 *** 回调注册 *** 00210 ============================= 00211 00212 [..] 00213 编译定义USE_HAL_CRYP_REGISTER_CALLBACKS设置为1时 00214 允许用户动态配置驱动回调。 00215 使用函数HAL_CRYP_RegisterCallback()或HAL_CRYP_RegisterXXXCallback() 00216 注册中断回调。 00217 00218 [..] 00219 函数HAL_CRYP_RegisterCallback()允许注册以下回调: 00220 (+) In