STM32G474xx HAL用户手册
stm32g4xx_hal_cryp.c
转到该文件的文档。
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