电子工程师技术服务社区
公告
登录
|
注册
首页
技术问答
厂商活动
正点原子
板卡试用
资源库
下载
文章
社区首页
文章
全网第一篇!!!基于Stm32的AES128-ECB加密模式--速度更快、功耗更低
分 享
扫描二维码分享
全网第一篇!!!基于Stm32的AES128-ECB加密模式--速度更快、功耗更低
STM32
ECB
AES128
爱笑的男孩
关注
发布时间: 2020-01-06
丨
阅读: 4477
# 全网第一篇!!!基于Stm32的AES128-ECB加密模式--速度更快、功耗更低 ## AES 简述 AES是一个高级加密标准 。按加密方式分为:AES-128、AES-192、AES-256;按加密模式分为:ECB、CBC、CTR、CFB、OCF。其大致流程是:一个明文+一个密钥生成一个密钥!如下图  AES加密原理是【九次四算】+【一次三算】!为什么这样说呢? AE加密函数执行了九次的“字节代换、行移位、列混合、轮密钥加”,和一次的“字节代换、行移位、轮密钥加”,所以笔者(仅仅是笔者)称为【九次四算】+【一次三算】。如果要详细了解什么是“字节代换、行移位、列混合、轮密钥加”,可以看我上一篇博文《AES-128 ECB加密---一看就懂,图文并茂》。 ## 本文目的 上一篇文章,虽然C语言的文件已经实现了AES128-ECB加密与解密的功能,但在含有AES控制器的Stm32单片机,比如:STM32L083CZ,直接用C语言运算,总是有些不靠谱。笔者运行了C语言的AES128加密函数(16个明文、16个key),利用串口时间戳简易读出时间,得出加密时间为6ms左右!但是利用Stm32控制器,完全读不出来,证明控制解密时间至少是微秒级别的!假设工作电流为20mA,每次多了6ms,漏电就是这么产生的,日积月累,明明一个工作三年的终端活生生变成一年!(比如,只是比如!!!) 所以尤其是基于Stm32开发的低功耗终端类通信项目,为了尽可能地降低功耗;所以引进这篇文章《基于Stm32的AES128-ECB加密模式》。 Stm32 AES控制器描述与特征   部分译文: **介绍** AES硬件加速器(AES)使用完全符合联邦信息处理标准(FIPS)出版物197中定义的高级加密标准(AES)的算法和实现对数据进行加密或解密。 支持多种链接模式(ECB,CBC,CTR),密钥大小为128位。 AES加速器是32位AHB外设。 它支持传入和传出数据的DMA单一传输(需要两个DMA通道)。 AES外设为STM32密码库中打包的AES密码算法提供了硬件加速。 AES是一种AMBA AHB从属外设,只能通过32位字单次访问进行访问(否则将生成AHB总线错误,并且将忽略写访问)。 **AES主要功能** •128位数据块处理 •支持128位的密码密钥长度 •具有多种链接模式的加密和解密: –电子密码本(ECB)模式 –密码块链接(CBC)模式 –计数器(CTR)模式 •213个时钟周期延迟,用于处理一个128位数据块 •集成的密钥调度程序及其密钥派生阶段(仅ECB或CBC解密) •AMBA AHB从属外设,仅可通过32位字单次访问进行访问 •用于存储密钥的128位寄存器(四个32位寄存器) •用于存储初始化向量的128位寄存器(四个32位寄存器) –当在CBC模式下配置AES时,用于初始化向量;在选择CTR模式时,用于32位计数器初始化。 •用于数据输入和输出的32位缓冲器 •自动数据流控制,支持使用两个通道的单传输直接内存访问(DMA)(一个用于输入数据,一个用于处理数据) •数据交换逻辑,可支持1位,8位,16位或32位数据 ## Stm32CubeMX创建AES工程--HAL库创建 **STM32CubeMX版本:**Version 5.4.0 **STM32CubeMX下载地址:**https://www.st.com/en/development-tools/stm32cubemx.html 为了更便于读者有一个直观的了解,笔者做了一个思维导图,更方便在宏观上清楚CubeMX的使用:  ### 1.工程开始  ### 2.芯片选型  ### 3.RCC设置 为什么说是可选? 因为Stm32可供使用的RCC始终来源分为内部和外部,这里的LSE、HSE,分别是外部高速晶振和外部低速晶振。若你使用的板子是使用内部晶振驱动就无需选择。  ### 4.Uart选择 按着开发板选择串口,Asynchronous是串口用作异步通信的意思。  ### 5.AES选择  ### 6.Clock Configuartion(必选) 这个必须按着你自己芯片的参数/时钟树选择,由于笔者使用的是内部RC振荡时钟,所以只需要设置最大晶振频率,32MHz,其他系统自动分配。  ### 7.Project Manager #### 7.1Project 选择自己的工程名字、生成路经、IDE。  #### 7.2Code Generator  右上角,生成代码! ## 例程代码 避坑环节:在执行MX_AES_Init();初始化后,每次加密解密函数的使用前,要进行一次DeInit;否则,AES功能无效。 为了便于让读者测试,固在贴下几个重点文件的代码: 第一个main.c ```c /@@* Includes ------------------------------------------------------------------*/ #include "main.h" #include "aes.h" #include "crc.h" #include "rng.h" #include "spi.h" #include "usart.h" #include "gpio.h" /@@* Private includes ----------------------------------------------------------*/ /@@* Private function prototypes -----------------------------------------------*/ void SystemClock_Config(void); /@@** * @brief The application entry point. * @retval int */ extern uint8_t buffer1[16]; extern uint8_t buffer2[16]; extern uint8_t buffer3[16]; int main(void) { int n=0; HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); // MX_CRC_Init(); // MX_SPI1_Init(); // MX_RNG_Init(); MX_USART2_UART_Init(); MX_USART4_UART_Init(); HAL_Delay(1000); MX_AES_Init(); ShowHex("Original data is:",buffer1,16); ShowHex("AesEncrypt data is:",buffer2,16); ShowHex("Decrypt data is:",buffer3,16); } /@@** * @brief System Clock Configuration * @retval None */ void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; RCC_PeriphCLKInitTypeDef PeriphClkInit = {0}; /@@** Configure the main internal regulator output voltage */ __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); /@@** Initializes the CPU, AHB and APB busses clocks */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI; RCC_OscInitStruct.HSIState = RCC_HSI_ON; RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI; RCC_OscInitStruct.PLL.PLLMUL = RCC_PLLMUL_4; RCC_OscInitStruct.PLL.PLLDIV = RCC_PLLDIV_2; if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { Error_Handler(); } /@@** Initializes the CPU, AHB and APB busses clocks */ RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK) { Error_Handler(); } PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART2 | RCC_PERIPHCLK_USB; PeriphClkInit.Usart2ClockSelection = RCC_USART2CLKSOURCE_PCLK1; PeriphClkInit.UsbClockSelection = RCC_USBCLKSOURCE_PLL; if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) { Error_Handler(); } } /@@** * @brief This function is executed in case of error occurrence. * @retval None */ void Error_Handler(void) { dPrintfln("Error_Handler!!"); /@@* USER CODE BEGIN Error_Handler_Debug */ /@@* User can add his own implementation to report the HAL error return state */ /@@* USER CODE END Error_Handler_Debug */ } #ifdef USE_FULL_ASSERT /@@** * @brief Reports the name of the source file and the source line number * where the assert_param error has occurred. * @param file: pointer to the source file name * @param line: assert_param error line source number * @retval None */ void assert_failed(uint8_t *file, uint32_t line) { /@@* USER CODE BEGIN 6 */ /@@* User can add his own implementation to report the file name and line number, tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ /@@* USER CODE END 6 */ } #endif /@@* USE_FULL_ASSERT */ /@@************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ ``` 第二个:aes.c ```c /@@** ****************************************************************************** * File Name : AES.c * Description : This file provides code for the configuration * of the AES instances. ****************************************************************************** * @attention * * <h2><center>© Copyright (c) 2019 STMicroelectronics. * All rights reserved.</center></h2> * * This software component is licensed by ST under BSD 3-Clause license, * the "License"; You may not use this file except in compliance with the * License. You may obtain a copy of the License at: * opensource.org/licenses/BSD-3-Clause * ****************************************************************************** */ /@@* Includes ------------------------------------------------------------------*/ #include "aes.h" #include "usart.h" /@@* USER CODE BEGIN 0 */ /@@* USER CODE END 0 */ CRYP_HandleTypeDef hcryp; uint8_t buffer1[16]="123456781234567"; uint8_t buffer2[16]; uint8_t buffer3[16]; __ALIGN_BEGIN static const uint8_t pKeyAES[16] __ALIGN_END = { 0x21,0x34,0x56,0x11,0x21,0x34,0x56,0x11,0x21,0x34,0x56,0x11,0x21,0x34,0x56,0x11 }; /@@* AES init function */ void MX_AES_Init(void) { HAL_CRYP_DeInit(&hcryp); hcryp.Instance = AES; hcryp.Init.DataType = CRYP_DATATYPE_8B; hcryp.Init.pKey = (uint8_t *)pKeyAES; if (HAL_CRYP_Init(&hcryp) != HAL_OK) { Error_Handler(); } if(HAL_CRYP_AESECB_Encrypt(&hcryp,buffer1,16,buffer2,5000)){ Error_Handler(); } HAL_CRYP_DeInit(&hcryp); if (HAL_CRYP_Init(&hcryp) != HAL_OK) { Error_Handler(); } if(HAL_CRYP_AESECB_Decrypt(&hcryp,buffer2,16,buffer3,5000)){ Error_Handler(); } } void HAL_CRYP_MspInit(CRYP_HandleTypeDef* crypHandle) { if(crypHandle->Instance == AES) { /@@* USER CODE BEGIN AES_MspInit 0 */ /@@* USER CODE END AES_MspInit 0 */ /@@* AES clock enable */ __HAL_RCC_AES_CLK_ENABLE(); /@@* USER CODE BEGIN AES_MspInit 1 */ /@@* USER CODE END AES_MspInit 1 */ } } void HAL_CRYP_MspDeInit(CRYP_HandleTypeDef* crypHandle) { if(crypHandle->Instance == AES) { /@@* USER CODE BEGIN AES_MspDeInit 0 */ /@@* USER CODE END AES_MspDeInit 0 */ /@@* Peripheral clock disable */ __HAL_RCC_AES_CLK_DISABLE(); /@@* USER CODE BEGIN AES_MspDeInit 1 */ /@@* USER CODE END AES_MspDeInit 1 */ } } /@@* USER CODE BEGIN 1 */ /@@* USER CODE END 1 */ /@@************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ ``` 第三个:usart.c ```c /@@** ****************************************************************************** * File Name : USART.c * Description : This file provides code for the configuration * of the USART instances. ****************************************************************************** * @attention * * <h2><center>© Copyright (c) 2019 STMicroelectronics. * All rights reserved.</center></h2> * * This software component is licensed by ST under BSD 3-Clause license, * the "License"; You may not use this file except in compliance with the * License. You may obtain a copy of the License at: * opensource.org/licenses/BSD-3-Clause * ****************************************************************************** */ /@@* Includes ------------------------------------------------------------------*/ #include "usart.h" /@@* USER CODE BEGIN 0 */ /@@* USER CODE END 0 */ UART_HandleTypeDef huart2; UART_HandleTypeDef huart4; /@@* USART2 init function */ void MX_USART2_UART_Init(void) { huart2.Instance = USART2; huart2.Init.BaudRate = 115200; huart2.Init.WordLength = UART_WORDLENGTH_8B; huart2.Init.StopBits = UART_STOPBITS_1; huart2.Init.Parity = UART_PARITY_NONE; huart2.Init.Mode = UART_MODE_TX_RX; huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE; huart2.Init.OverSampling = UART_OVERSAMPLING_16; huart2.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE; huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT; if (HAL_UART_Init(&huart2) != HAL_OK) { Error_Handler(); } } /@@* USART4 init function */ void MX_USART4_UART_Init(void) { huart4.Instance = USART4; huart4.Init.BaudRate = 115200; huart4.Init.WordLength = UART_WORDLENGTH_8B; huart4.Init.StopBits = UART_STOPBITS_1; huart4.Init.Parity = UART_PARITY_NONE; huart4.Init.Mode = UART_MODE_TX_RX; huart4.Init.HwFlowCtl = UART_HWCONTROL_NONE; huart4.Init.OverSampling = UART_OVERSAMPLING_16; huart4.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE; huart4.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT; if (HAL_UART_Init(&huart4) != HAL_OK) { Error_Handler(); } } void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle) { GPIO_InitTypeDef GPIO_InitStruct = {0}; if(uartHandle->Instance == USART2) { /@@* USER CODE BEGIN USART2_MspInit 0 */ /@@* USER CODE END USART2_MspInit 0 */ /@@* USART2 clock enable */ __HAL_RCC_USART2_CLK_ENABLE(); __HAL_RCC_GPIOA_CLK_ENABLE(); /@@**USART2 GPIO Configuration PA2 ------> USART2_TX PA3 ------> USART2_RX */ GPIO_InitStruct.Pin = GPIO_PIN_2 | GPIO_PIN_3; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_PULLUP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; GPIO_InitStruct.Alternate = GPIO_AF4_USART2; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); /@@* USER CODE BEGIN USART2_MspInit 1 */ /@@* USER CODE END USART2_MspInit 1 */ } else if(uartHandle->Instance == USART4) { /@@* USER CODE BEGIN USART4_MspInit 0 */ /@@* USER CODE END USART4_MspInit 0 */ /@@* USART4 clock enable */ __HAL_RCC_USART4_CLK_ENABLE(); __HAL_RCC_GPIOA_CLK_ENABLE(); /@@**USART4 GPIO Configuration PA0 ------> USART4_TX PA1 ------> USART4_RX */ GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_PULLUP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; GPIO_InitStruct.Alternate = GPIO_AF6_USART4; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); /@@* USER CODE BEGIN USART4_MspInit 1 */ /@@* USER CODE END USART4_MspInit 1 */ } } void HAL_UART_MspDeInit(UART_HandleTypeDef* uartHandle) { if(uartHandle->Instance == USART2) { /@@* USER CODE BEGIN USART2_MspDeInit 0 */ /@@* USER CODE END USART2_MspDeInit 0 */ /@@* Peripheral clock disable */ __HAL_RCC_USART2_CLK_DISABLE(); /@@**USART2 GPIO Configuration PA2 ------> USART2_TX PA3 ------> USART2_RX */ HAL_GPIO_DeInit(GPIOA, GPIO_PIN_2 | GPIO_PIN_3); /@@* USER CODE BEGIN USART2_MspDeInit 1 */ /@@* USER CODE END USART2_MspDeInit 1 */ } else if(uartHandle->Instance == USART4) { /@@* USER CODE BEGIN USART4_MspDeInit 0 */ /@@* USER CODE END USART4_MspDeInit 0 */ /@@* Peripheral clock disable */ __HAL_RCC_USART4_CLK_DISABLE(); /@@**USART4 GPIO Configuration PA0 ------> USART4_TX PA1 ------> USART4_RX */ HAL_GPIO_DeInit(GPIOA, GPIO_PIN_0 | GPIO_PIN_1); /@@* USER CODE BEGIN USART4_MspDeInit 1 */ /@@* USER CODE END USART4_MspDeInit 1 */ } } /@@* USER CODE BEGIN 1 */ static void SendChar(UART_HandleTypeDef *huart,uint8_t ch,uint32_t timeout) { uint32_t tick=HAL_GetTick()+timeout; huart->Instance->TDR=ch; while(1){ if(__HAL_UART_GET_FLAG(huart,UART_FLAG_TXE)!=RESET)break; if(HAL_GetTick()>tick)break; } } void UART_SendBuffer(UART_HandleTypeDef *huart,uint8_t *buffer,int length) { while(length--){ SendChar(huart,*buffer++,10); } } int fputc(int ch, FILE *f) { //HAL_UART_Transmit(&hbug, (unsigned char *)&ch, 1, 10); SendChar(&hbug, ch, 10); return ch; } //´òÓ¡16½øÖÆÊý¾Ý void ShowHex(char *name, void *dat, uint32_t size) { uint8_t *pdat = (uint8_t *)dat; if(size >= 10000)return; dPrintfln(" [ %s ]: size=%d", name, size); for(uint32_t i = 0; i < ((size + 15) & (~15)); i++) { if(i % 16 == 0)dPrintf("\r\n "); if(i < size)dPrintf("%02x ", pdat[i]); else dPrintf(" "); if((i + 1) % 16 == 0) { dPrintf(" | "); for(int n = 0; n < 16; n++) { uint8_t ch; ch = pdat[i - 15 + n]; if(ch < ' ' || ch > '~')ch = '.'; if((i - 15 + n) < size)dPrintf("%c", ch); else dPrintf(" "); } } } dPrintf("\r\n"); } /@@* USER CODE END 1 */ /@@************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ ``` 工程已经修改好,记得在在对应H文件添加函数的宏便可使用! ### 总结 对于大神来说,AES的使用并不难。但是对于小白来说,这篇文章的使用能有如一个指明灯,让新手快速地用例程测试,完成上级安排的任务,希望这篇文章对你有所收获。感谢阅读
原创作品,未经权利人授权禁止转载。详情见
转载须知
。
举报文章
点赞
(
1
)
爱笑的男孩
关注
评论
(0)
登录后可评论,请
登录
或
注册
相关文章推荐
MK-米客方德推出工业级存储卡
Beetle ESP32 C3 蓝牙数据收发
Beetle ESP32 C3 wifi联网获取实时天气信息
开箱测评Beetle ESP32-C3 (RISC-V芯片)模块
正点原子数控电源DP100测评
DP100试用评测-----开箱+初体验
Beetle ESP32 C3环境搭建
【花雕体验】16 使用Beetle ESP32 C3控制8X32位WS2812硬屏之二
X
你的打赏是对原创作者最大的认可
请选择打赏IC币的数量,一经提交无法退回 !
100IC币
500IC币
1000IC币
自定义
IC币
确定
X
提交成功 ! 谢谢您的支持
返回
我要举报该内容理由
×
广告及垃圾信息
抄袭或未经授权
其它举报理由
请输入您举报的理由(50字以内)
取消
提交