STM32G474xx HAL用户手册
stm32g4xx_hal_cryp.c文件参考

CRYP HAL模块驱动。本文件提供了用于管理加密(CRYP)外设以下功能的固件函数:+ 初始化、去初始化、设置配置和获取配置函数+ AES处理函数+ DMA回调函数+ CRYP IRQ中断处理程序管理+ 外设状态函数。 更多...

#include "stm32g4xx_hal.h"

转到此文件的源代码。


详细说明

CRYP HAL模块驱动。本文件提供了用于管理加密(CRYP)外设以下功能的固件函数:+ 初始化、去初始化、设置配置和获取配置函数+ AES处理函数+ DMA回调函数+ CRYP IRQ中断处理程序管理+ 外设状态函数。

作者:
MCD应用团队
注意:

版权所有(c)2019 STMicroelectronics。保留所有权利。

本软件根据LICENSE文件中规定的条款提供。如果本软件未随附LICENSE文件,则按"原样"提供。

  ==============================================================================
                     ##### 如何使用此驱动 #####
  ==============================================================================
    [..]
      CRYP HAL驱动可用于CRYP或TinyAES外设,如下所述:

      (#)通过实现HAL_CRYP_MspInit()初始化CRYP底层资源:
         (##) 使用__HAL_RCC_CRYP_CLK_ENABLE()启用CRYP接口时钟
              或针对TinyAES外设使用__HAL_RCC_AES_CLK_ENABLE()
         (##) 如果使用中断(例如HAL_CRYP_Encrypt_IT())
             (+++) 使用HAL_NVIC_SetPriority()配置CRYP中断优先级
             (+++) 使用HAL_NVIC_EnableIRQ()启用CRYP IRQ中断处理程序
             (+++) 在CRYP IRQ中断处理程序中,调用HAL_CRYP_IRQHandler()
         (##) 如果使用DMA控制数据传输(例如HAL_CRYP_Encrypt_DMA())
             (+++) 使用__RCC_DMAx_CLK_ENABLE()启用DMAx接口时钟
             (+++) 配置并启用两个DMA流:一个用于管理从内存到外设的数据传输(输入流),
                  另一个用于管理从外设到内存的数据传输(输出流)
             (+++) 使用__HAL_LINKDMA()将初始化的DMA句柄关联到CRYP DMA句柄
             (+++) 为两个DMA通道的传输完成中断配置优先级并启用NVIC。
                  输出通道应具有比输入通道更高的优先级,使用HAL_NVIC_SetPriority()
                  和HAL_NVIC_EnableIRQ()。

      (#)根据指定参数初始化CRYP:
         (##) 数据类型:1位、8位、16位或32位。
         (##) 密钥大小:128、192或256。
         (##) 算法模式:DES/TDES算法ECB/CBC或AES算法ECB/CBC/CTR/GCM或CCM。
         (##) 初始化向量(计数器)。ECB模式下不使用。
         (##) 用于加密/解密的密钥缓冲区。
             (+++) 在某些特定配置中,密钥由应用程序代码在HAL范围外写入。
                  在这种情况下,用户仍可照常使用HAL API,但必须确保pKey指针设置为NULL。
         (##) DataWidthUnit字段。指定数据长度(或认证算法的有效载荷长度)是以字还是以字节为单位。
         (##) 仅在AES GCM和CCM算法中用于认证的头部。
         (##) HeaderSize提供头部缓冲区的大小(以字或字节为单位),取决于HeaderWidthUnit字段。
         (##) HeaderWidthUnit字段。指定头部长度(对于认证算法)是以字还是以字节为单位。
         (##) B0块是仅在AES CCM模式下使用的第一个认证块。
         (##) KeyIVConfigSkip用于连续处理多条消息(详见下文)。

      (#)提供三种处理(加密/解密)函数:
         (##) 轮询模式:加密和解密API是阻塞函数
              即它们处理数据并等待处理完成,
              例如HAL_CRYP_Encrypt和HAL_CRYP_Decrypt
         (##) 中断模式:加密和解密API是非阻塞函数
              即它们在中断下处理数据,
              例如HAL_CRYP_Encrypt_IT和HAL_CRYP_Decrypt_IT
         (##) DMA模式:加密和解密API是非阻塞函数
              即数据传输由DMA保证,
              例如HAL_CRYP_Encrypt_DMA和HAL_CRYP_Decrypt_DMA

      (#)当在HAL_CRYP_Init()之后首次调用处理函数时,
         CRYP外设被配置并处理输入缓冲区。
         第二次调用时,无需初始化CRYP,用户需要通过
         HAL_CRYP_GetConfig() API获取当前配置,然后只需要调用
         HAL_CRYP_SetConfig()设置新参数,最后用户可以开始加密/解密。

       (#)调用HAL_CRYP_DeInit()去初始化CRYP外设。

       (#)要使用连续调用HAL_CRYP_Encrypt()或HAL_CRYP_Decrypt()
          处理单条消息而无需在每次API调用之间重新配置密钥或初始化向量,
          初始化结构中的字段KeyIVConfigSkip必须设置为CRYP_KEYIVCONFIG_ONCE。
          对于HAL_CRYP_Encrypt_IT()、HAL_CRYP_Decrypt_IT()、HAL_CRYP_Encrypt_DMA()
          或HAL_CRYP_Decrypt_DMA()的连续调用同样适用。

    [..]
      加密处理器支持以下标准:
      (#) 数据加密标准(DES)和三重DES(TDES)仅由CRYP1外设支持:
         (##) 64位数据块处理
         (##) 支持的链接模式:
             (+++) 电子密码本(ECB)
             (+++) 密码块链接(CBC)
         (##) 支持的密钥长度:64位、128位和192位。
      (#) 高级加密标准(AES)由CRYP1和TinyAES外设支持:
         (##) 128位数据块处理
         (##) 支持的链接模式:
             (+++) 电子密码本(ECB)
             (+++) 密码块链接(CBC)
             (+++) 计数器模式(CTR)
             (+++) 伽罗瓦/计数器模式(GCM/GMAC)
             (+++) 带密码块链接的消息认证码计数器模式(CCM)
         (##) 支持的密钥长度:
             (+++) 对于CRYP1外设:128位、192位和256位。
             (+++) 对于TinyAES外设:128位和256位

    [..]
    (@) 必须特别注意格式化密钥和初始化向量IV!

    [..] 如果密钥定义为128位长数组key[127..0] = {b127 ... b0},其中
         b127是MSB,b0是LSB,密钥必须按以下方式存储在MCU内存中
         (+) 首先是MSB字(占据最低内存地址)
          (++)   地址n+0 : 0b b127 .. b120 b119 .. b112 b111 .. b104 b103 .. b96
          (++)   地址n+4 : 0b b95 .. b88 b87 .. b80 b79 .. b72 b71 .. b64
          (++)   地址n+8 : 0b b63 .. b56 b55 .. b48 b47 .. b40 b39 .. b32
          (++)   地址n+C : 0b b31 .. b24 b23 .. b16 b15 .. b8 b7 .. b0
     [..] 以下是另一个示例,当考虑由16个字节{B15..B0}组成的128位长密钥时。
         组成密钥的4个32位字必须按以下方式存储在MCU内存中:
          (+)    地址n+0 : 0x B15 B14 B13 B12
          (+)    地址n+4 : 0x B11 B10 B9 B8
          (+)    地址n+8 : 0x B7 B6 B5 B4
          (+)    地址n+C : 0x B3 B2 B1 B0
     [..]  这将导致预期的设置
       (+)       AES_KEYR3 = 0x B15 B14 B13 B12
       (+)       AES_KEYR2 = 0x B11 B10 B9 B8
       (+)       AES_KEYR1 = 0x B7 B6 B5 B4
       (+)       AES_KEYR0 = 0x B3 B2 B1 B0

    [..]  对于由32个字节{B31..B0}组成的256位长密钥,必须使用相同的格式。
         组成密钥的8个32位字必须按以下方式存储在MCU内存中:
          (+)    地址n+00 : 0x B31 B30 B29 B28
          (+)    地址n+04 : 0x B27 B26 B25 B24
          (+)    地址n+08 : 0x B23 B22 B21 B20
          (+)    地址n+0C : 0x B19 B18 B17 B16
          (+)    地址n+10 : 0x B15 B14 B13 B12
          (+)    地址n+14 : 0x B11 B10 B9 B8
          (+)    地址n+18 : 0x B7 B6 B5 B4
          (+)    地址n+1C : 0x B3 B2 B1 B0
     [..]  这将导致预期的设置
       (+)       AES_KEYR7 = 0x B31 B30 B29 B28
       (+)       AES_KEYR6 = 0x B27 B26 B25 B24
       (+)       AES_KEYR5 = 0x B23 B22 B21 B20
       (+)       AES_KEYR4 = 0x B19 B18 B17 B16
       (+)       AES_KEYR3 = 0x B15 B14 B13 B12
       (+)       AES_KEYR2 = 0x B11 B10 B9 B8
       (+)       AES_KEYR1 = 0x B7 B6 B5 B4
       (+)       AES_KEYR0 = 0x B3 B2 B1 B0

    [..] 初始化向量IV(4个32位字)的格式必须与
         128位长密钥相同。

    [..] 请注意,密钥和IV寄存器对交换模式选择不敏感。

    [..]  本节介绍CRYP1和TinyAES外设支持的AES伽罗瓦/计数器模式(GCM):
      (#)  支持的算法:
         (##) 伽罗瓦/计数器模式(GCM)
         (##) 伽罗瓦消息认证码(GMAC):与仅由头部组成的GCM算法完全相同。
      (#)  GCM执行四个阶段:
         (##) 初始化阶段:外设准备GCM哈希子密钥(H)并进行IV处理
         (##) 头部阶段:外设处理附加认证数据(AAD),仅进行哈希计算。
         (##) 有效载荷阶段:外设处理明文(P)并进行哈希计算+密钥流加密+数据异或。
              对于密文(C)处理方式类似。
         (##) 最终阶段:外设使用最后的数据块生成认证标签(T)。
      (#)  GCM中消息结构定义如下:
         (##) 16字节初始计数器块(ICB)由IV和计数器组成
         (##) 认证头部A(也称为附加认证数据AAD)
          消息的这部分仅被认证,不被加密。
         (##) 明文消息P既被认证又被加密为密文。
          GCM标准规定密文与明文具有相同的位长度。
         (##) 最后一块由A的长度(64位)和密文的长度(64位)组成

    [..]  以下提供了GCM消息结构的更详细说明。

    [..]  本节介绍CRYP1和TinyAES外设支持的带密码块链接的消息认证码计数器模式(CCM):
      (#)  CCM的特定参数:

         (##) B0块:遵循NIST特别出版物800-38C,
         (##) B1块(头部)
         (##) CTRx块:控制块

    [..]  以下提供了CCM消息结构的详细说明。

      (#)  CRYP1外设CCM执行四个阶段:
         (##) 初始化阶段:外设准备GCM哈希子密钥(H)并进行IV处理
         (##) 头部阶段:外设处理附加认证数据(AAD),仅进行哈希计算。
         (##) 有效载荷阶段:外设处理明文(P)并进行哈希计算+密钥流加密+数据异或。
              对于密文(C)处理方式类似。
         (##) 最终阶段:外设使用最后的数据块生成认证标签(T)。
      (#)    TinyAES外设中的CCM:
         (##) 要执行消息有效载荷加密或解密,AES配置为CTR模式。
         (##) 对于认证执行两个阶段:
          - 头部阶段:外设首先处理附加认证数据(AAD),然后处理明文消息
          仅使用明文有效载荷(不是密文有效载荷),不产生输出。
         (##) 最终阶段:外设使用最后的数据块生成认证标签(T)。

  *** 回调注册 ***
  =============================

  [..]
  当编译定义USE_HAL_CRYP_REGISTER_CALLBACKS设置为1时,
  允许用户动态配置驱动回调。
  使用函数HAL_CRYP_RegisterCallback()或HAL_CRYP_RegisterXXXCallback()
  注册中断回调。

  [..]
  函数HAL_CRYP_RegisterCallback()允许注册以下回调:
    (+) InCpltCallback     :  输入FIFO传输完成回调。
    (+) OutCpltCallback    : 输出FIFO传输完成回调。
    (+) ErrorCallback      : 错误检测回调。
    (+) MspInitCallback    : CRYP MspInit。
    (+) MspDeInitCallback  : CRYP MspDeInit。
  此函数接受HAL外设句柄、回调ID和用户回调函数指针作为参数。

  [..]
  使用函数HAL_CRYP_UnRegisterCallback()将回调重置为默认弱函数。
  HAL_CRYP_UnRegisterCallback()接受HAL外设句柄和回调ID作为参数。
  此函数允许重置以下回调:
    (+) InCpltCallback     :  输入FIFO传输完成回调。
    (+) OutCpltCallback    : 输出FIFO传输完成回调。
    (+) ErrorCallback      : 错误检测回调。
    (+) MspInitCallback    : CRYP MspInit。
    (+) MspDeInitCallback  : CRYP MspDeInit。

  [..]
  默认情况下,在HAL_CRYP_Init()之后且状态为HAL_CRYP_STATE_RESET时,
  所有回调都设置为相应的弱函数:
  示例HAL_CRYP_InCpltCallback()、HAL_CRYP_OutCpltCallback()。
  MspInit和MspDeInit函数例外,它们仅在
  HAL_CRYP_Init()/HAL_CRYP_DeInit()中当这些回调为null时(未预先注册)
  才重置为传统的弱函数。
  否则,如果MspInit或MspDeInit不为null,HAL_CRYP_Init()/HAL_CRYP_DeInit()
  保留并使用用户的MspInit/MspDeInit函数(已预先注册)

  [..]
  回调只能在HAL_CRYP_STATE_READY状态下注册/注销。
  MspInit/MspDeInit回调例外,它们可以在HAL_CRYP_STATE_READY或
  HAL_CRYP_STATE_RESET状态下注册/注销,
  因此已注册的用户MspInit/DeInit回调可在Init/DeInit期间使用。
  在这种情况下,首先使用HAL_CRYP_RegisterCallback()注册MspInit/MspDeInit用户回调,
  然后再调用HAL_CRYP_DeInit()或HAL_CRYP_Init()函数。

  [..]
  当编译定义USE_HAL_CRYP_REGISTER_CALLBACKS设置为0或
  未定义时,回调注册功能不可用,所有回调都设置为
  相应的弱函数。


  *** 挂起/恢复功能 ***
  ==============================

  [..]
  当编译定义USE_HAL_CRYP_SUSPEND_RESUME设置为1时,
  允许用户使用挂起/恢复功能。
  低优先级数据块处理可以挂起以处理高优先级数据块。
  当高优先级数据块处理完成后,低优先级数据块处理可以从
  挂起点恢复继续执行。此功能仅适用于非阻塞中断模式。

  [..] 用户必须使用HAL_CRYP_Suspend()挂起低优先级数据块处理。
  此API管理硬件块处理的挂起并保存稍后重新启动所需的
  所有内部数据。HAL_CRYP_Suspend()完成后,用户可以启动
  任何其他数据块的处理(高优先级数据块处理)。

  [..] 高优先级数据块处理完成后,用户必须调用HAL_CRYP_Resume()
  恢复低优先级数据块处理。加密(或解密)从挂起点重新开始,
  并正常结束。

  [..] HAL_CRYP_Suspend()在挂起请求发送过晚时(即低优先级数据块处理即将结束时)
  报告错误。对于认证算法,不建议挂起标签生成处理。

    [..]
    (@) 如果密钥在HAL范围外写入(用户将pKey指针设置为NULL的情况),
        块处理挂起/恢复机制不适用。

    [..]
    (@) 如果密钥和初始化向量仅配置一次,并且在连续处理时跳过配置
        (KeyIVConfigSkip设置为CRYP_KEYIVCONFIG_ONCE的情况),
        块处理挂起/恢复机制不适用。

  

定义于文件stm32g4xx_hal_cryp.c中。