Crypto算法库使用技巧 —— 基于STM32 AES GCM应用提示

发布者:琴弦悠扬最新更新时间:2023-02-06 来源: jdzj关键字:STM32  AES 手机看文章 扫描二维码
随时随地手机看文章

引言

X-CUBE-CRYPTOLIB 是基于 STM32 的 Crypto 算法库,支持对称密钥、非对称密钥、哈希等多种算法。正确地使用 Cyrptolib 算法库,可以在应用程序中实现数据加密、设备身份认证、加密通信等多种应用层所需的安全功能。相反,若不能正确地使用算法库往往会带来加解密数据错误等系列问题。


关于 STM32 Crypto 算法库应用中的常见的问题之一就是应用程序没有使能 MCU 的CRC 模块,尽管输出的数据和期望值不同,但加解密函数的调用并未返回异常。本文在此描述另外一种没有正确使用算法库的情况。


问题描述

客户应用项目中需要在固件更新过程中对固件进行加密并验证,根据推荐采用了 AES- GCM 算法完成该任务。下载的固件通过 AES-GCM 进行加密,并带 TAG 可以用于验证固件来源的合法性。在项目的代码中使用 X-Cube-Cryptolib 进行 AES-GCM 运算。上位机使用 cryptopp820 加密库对固件目标 bin 文件进行加密,然后在 MCU 上通过X-Cube- Cryptolib 加密库进行 AES-GCM128 解密,解密数据没有问题,但是 TAG 数据总是无法校验通过。


问题分析与定位


正常情况下,当调用 AES_GCM_Decrypt_Finish(P_pAESGCMctx, NULL, P_pOutputSize);执行后,AESctx.mFlags 结果会提示是否通过校验。如果校验成功,该值应该等于 0x22,而运行结果中看到的却是 0x12。


确认库函数使用方法

将调用 AES-GCM 功能的代码放在 X-Cube-Cryptolib 中一个简单的测试程序的环境进行测试,查看是否有该问题,结果发现测试程序中 AES-GCM 校验是可以成功的,但是集成到客户应用中时就无法成功。那我们接下来重点研究应用程序环境。


应用程序环境

应用程序使用了 FreeRTOS,基于 IAR 编译环境。


查看库文件的使用

确认使用了正确的库文件。


确认是否存在多线程访问

AES-GCM 的函数会在几个线程中调用,而且确认不会出现同时调用的情况,不存在 raise condition 的问题。


查看内存使用情况

最初怀疑是否因为任务栈溢出造成,于是查看内存使用情况。

  • IAR stack size: 0x4800

  • IAR heap size: 0x4000

  • FreeRTOS heap size: 85KB

  • 执行AES 运算的线程 stack size: 2560B

通过 FreeRTOS 的 uxTaskGetStackHighWaterMark() 函数查看该线程还有 500 字节左右剩余空间。

AESGCMctx_stt 结构的大小有 2360 字节,AES-GCM 加解密函数需要的 stack 大小大概在 450 字节左右,但是应用代码中将该变量定义为全局变量,以便可以在几个不同的线程中使用,这样可以确认线程栈大小没有问题,不存在 stack overflow 的问题。


查看生成代码的.map 文件

通过比较,所有 cryptolib 中的 symbol 在 map 中的大小都正常,唯一有问题的是 AESGCMctx_stt结构变量的大小。

  • 应用代码.map:AESctx 0x2002f1f4 0x8f8 Data Gb AES_GCM_Decrypt.o [1]

  • 正常测试代码 .map:AESctx 0x20002e64 0x938 Data Gb AES_GCM.o [1]

验证不过的问题应该和这个结构的数据有直接关系,接下来研究是什么造成了这个不同。


查看项目使用的 crypto 库头文件

经检查,INCLUDE_AES192 和 INCLUDE_AES256 两个宏定义在 config.h 的定义中被注释掉,这将导致aes_gcm.h中AESGCMctx_stt数据结构的成员变量 uint32_t amExpKey[CRL_AES_MAX_EXPKEY_SIZE];的大小发生变化,因为CRL_AES_MAX_EXPKEY_SIZE 的定义根据INCLUDE_AES128/192/256 是否定义会有所不同。

//#define INCLUDE_DES ((uint16_t)0x0001) /*!< DES functions are included in the library. *///#define INCLUDE_TDES ((uint16_t)0x0002) /*!< TripleDES (TDES) functions are included in the library. */#define INCLUDE_AES128 ((uint16_t)0x0004) /*!< AES functions with key size of 128 bit are included in the library. *///#define INCLUDE_AES192 ((uint16_t)0x0008)/*!< AES functions with key size of 192 bit are included in the library. *///#define INCLUDE_AES256 ((uint16_t)0x0010)/*!< AES functions with key size of 256 bit are included in the library. *///#define INCLUDE_ARC4 ((uint16_t)0x0020) /*!< ARC4 functions are included in the library. *///#define INCLUDE_CHACHA ((uint16_t)0x0040) /*!< ChaCha functions are included in the library. *///#define INCLUDE_CHACHA20POLY1305 ((uint16_t)0x0080) /*!< oly1305- AES functions are included in the library */


问题解决


将 config.h 里面被注释掉的两行定义打开,重新编译,此时 TAG 验证能够正常通过。#define INCLUDE_AES128 ((uint16_t)0x0004)/*!< AES functions with key size of 128 bit are included in the library. */#define INCLUDE_AES192 ((uint16_t)0x0008)/*!< AES functions with key size of 192 bit are included in the library. */#define INCLUDE_AES256 ((uint16_t)0x0010)/*!< AES functions with key size of 256 bit are included in the library. */


小结


简言之,如果使用 X-Cube-Cryptolib 库的话,作为用户就不要改动 config.h 的内容, 不可想当然地自行调整配置。其实,库是预先编译好了的,所有的功能都已经包含,只是链接的时候根据用户使用到的函数去链接最终的目标文件。这个客户就是按照以为关闭某些配置可以节省代码空间的想法,贸然注释掉了他以为自己不需要的功能,造成数据结构大小发生变化等,影响加密库的正常使用。

关键字:STM32  AES 引用地址:Crypto算法库使用技巧 —— 基于STM32 AES GCM应用提示

上一篇:工程师笔记 | 使用UART IDLE中断接收不定长数据
下一篇:工程师笔记 | STM32H7 RAMECC功能及应用

推荐阅读最新更新时间:2024-11-18 10:33

如何采用STM32单片机读取可变长度数据到内存
首先要解决DMA怎么知道要接收的数据何时开始,何时结束的问题。而且每次传输完数据,要改变下一次数据长度。 如果把DMA设成循环模式肯定是不行的,所以把DMA设置成正常模式。 STM32的串口有监测总线是否处于空闲的功能,我们可以使用这个功能,当数据传输完总线变成空闲状态时产生中断,来对收到的数据进行处理。因此整个过程就变成:当一堆数据开始传输,DMA默默地把数据搬运到内存中,当这堆数据传输完成,总线变成空闲状态时,马上产生中断,在中断服务程序中去做相应处理。 初始化程序: #defineDMA_Rec_Len10//数据缓冲区大小 u8value[DMA_Rec_Len]; voiduart_init_DMA_IN(u
[单片机]
如何采用<font color='red'>STM32</font>单片机读取可变长度数据到内存
STM32 Cubemax(十四) ——基于Cubemax的FreeRTOS移植与LED点灯测试
前言 之前的代码其实一直都是裸机在跑,即本质上就是在一个while(1)中在跑,这对于任务量较小的程序来说,没有什么问题。但最近遇到一些工程性的代码,其参考代码均采用了FreeRTOS操作系统,以此来记录一下自己的学习过程。 一、CubeMax移植FreeRTOS 废话不多说,想把FreeRTOS配置起来,再说一些其他东西。 时钟配置 时钟树配置 这个地方主要根据自己的开发板配置下面两个部分 嘀嗒时钟配置 如果使用FreeRTOS,嘀嗒时钟源要使用定时器产生的,这里不说原因,先配置就好。 FreeRTOS配置 这里下面的配置功能,等有特殊功能需要,再介绍,这里不需要动(其实也就是打开或者关闭一些功能) Fr
[单片机]
<font color='red'>STM32</font> Cubemax(十四) ——基于Cubemax的FreeRTOS移植与LED点灯测试
STM32各个系列时钟调高时出现异常案例
STM32用户反馈,使用STM32F103内部时钟,把系统时钟配置成64MHz单片机就不跑了,配置成36MHz程序就正常妥妥的,频率稍高点就容易导致死机。他贴出的代码如下:void RCC_Configuration(void) { RCC_DeInit();//将外设 RCC寄存器重设为缺省值 RCC_HSICmd(ENABLE);//使能HSI while(RCC_GetFlagStatus(RCC_FLAG_HSIRDY) == RESET);//等待HSI使能成功 //FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable); //FLASH_SetLatency(FLASH
[单片机]
<font color='red'>STM32</font>各个系列时钟调高时出现异常案例
STM32学习记录之看门狗
看门狗(WatchDog)是什么? 看门狗简介 STM32 有两个看门狗,一个是独立看门狗,另外一个是窗口看门狗,独立看门狗号称宠物狗,窗口看门狗号称警犬,本章我们主要分析独立看门狗的功能框图和它的应用。独立看门狗用通俗一点的话来解释就是一个12 位的递减计数器,当计数器的值从某个值一直减到0 的时候,系统就会产生一个复位信号,即IWDG_RESET。如果在计数没减到0之前,刷新了计数器的值的话,那么就不会产生复位信号,这个动作就是我们经常说的喂狗。看门狗功能由VDD电压域供电,在停止模式和待机模式下仍能工作。 看门狗用途 看门狗常用于防止系统跑飞,系统程序崩溃时自动复位重启。为系统运行提供一层保险。 LSI 时钟 独
[单片机]
<font color='red'>STM32</font>学习记录之看门狗
STM32学习笔记之Bootloader升级Ymodem协议简介
YModem协议 YModem协议是由XModem协议演变而来的,每包数据可以达到1024字节,是一个非常高效的文件传输协议 。 源码宏定义 #define SOH (0x01) /* start of 128-byte data packet / #define STX (0x02) / start of 1024-byte data packet / #define EOT (0x04) / end of transmission / #define ACK (0x06) / acknowledge / #define NAK (0x15) / negative acknowledge / #define CA (0x18
[单片机]
<font color='red'>STM32</font>学习笔记之Bootloader升级Ymodem协议简介
stm32CAN通信代码
最近做项目需要用到can通信,这里分享一下自己的can通信学习代码,我使用的是正点原子的精英开发板,参考的资料也是正点原子的库函数指南,此外我也看完了can入门手册(21ic电子网可以下载到),对can通信原理了解了不少,can的内容还是很多的,这里我也不说原理,毕竟内容太多,只分享一下自己的代码,本来是跟着正点原子的例程走的,结果我的tft屏幕坏了(特容易坏),而且自己也只有一块开发板,没有办法,就仿真吧,(插一条:仿真来找小虫子简直不要太爽,我后面分享一下自己用仿真的一些小经验吧),学习32后面基本上要用到按键和LED,建议大家只看原理图自己写一遍,有自己的代码,方便以后调用,显示屏也是OLED和TFT两个在后面的代码调试中结
[单片机]
STM32学习---GPIO和按键(流水灯学习)
//main的完整过程: int main(void){ LED_GPIO_CONFIG(); //定义LED灯; KEY_GPIO_CONFIG(); //定义按键; //循环判断按键的过程: while(1){ if((KEY_SCANF(GPIOC,GPIO_Pin_5)==0)){ //确定按键完全按下 if(GPIO_ReadOutputDataBit(GPIOD,GPIO_Pin_2)==0) //当灯都亮起时,GPIO_ReadOutputDataBit(GPIOD,GPIO_Pin_2)读到输出数据; GPIO_SetBits(GPIOD,GPIO_Pin_2); //
[单片机]
STM32正交编码器驱动,引入(突变)带进位的位置环和速度环
STM32正交编码器驱动,引入(突变)带进位的位置环和速度环 http://bbs.elecfans.com/jishu_484159_1_1.html (出处: 中国电子技术论坛) #include stm32f10x.h #include stm32f10x_encoder.h #include sys.h #include usart.h #include led.h #define COUNTER_RESET (u16)0 #define ICx_FILTER (u8) 0 // 6 - 670nsec #define TIMx_PRE_EMPTION_PRIORITY 1 #define TIMx_SUB_
[单片机]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved