打印
[应用相关]

STM32移植使用mbedtls-2.24.0

[复制链接]
1311|8
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
labasi|  楼主 | 2021-7-4 16:28 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
(1)关于PolarSSL
mbed TLS(以前称为PolarSSL)是TLS和SSL协议的实现,并且需要相应的加密算法和支持代码。这是双重许可与Apache许可证 2.0版(与GPLv2许可也可)。
核心SSL库用C编程语言编写,并实现SSL模块,基本加密功能并提供各种实用功能。与OpenSSL和TLS的其他实现不同,mbed TLS设计为适合小型嵌入式设备,最小完整的TLS堆栈需要60KB的程序空间和64KB的RAM。它也是高度模块化的:每个组件,如加密函数,可以独立于框架的其余部分使用。因为mbed TLS是用C编程语言编写的,没有外部依赖,现在叫MbedTSL,PolarSSL源码,也许是最小巧的ssl代码库。高效、便于移植和集成。尤其适合嵌入式应用。

本章就基于STM32移植mbedtls-2.24.0版本进行测试与使用!



注意:因为本章节只是用了加解密的API,没有使用网络进行SSL认证操作,如果要使用mbedtls的SSL认证,最低的硬件环境最低需要60K的FLASH以及64K的SRAM(内存),如果你使用的比较低端的STM32,那么无解,没法用embedtls。。。




使用特权

评论回复
沙发
labasi|  楼主 | 2021-7-4 16:29 | 只看该作者
(2)mbedtls移植

首先使用STM32CubeMX建立裸机工程,我使用的是STM32F103RB,配置了串口一当作信息输出的端口,这里注意,mbedtls所使用的栈空间是比较大的,所以在STM32CubeMX输出工程的时候将栈空间调大,如下图:


使用特权

评论回复
板凳
labasi|  楼主 | 2021-7-4 16:29 | 只看该作者

下载解压mbedtls源码目录如下:


使用特权

评论回复
地板
labasi|  楼主 | 2021-7-4 16:30 | 只看该作者
而我们需要的仅仅是configs(配置头文件)、include(头文件)、library(源码)。

configs,该文件夹内的是配置头文件,可以根据不同需求进行选择,例如我们本次是在嵌入式系统上使用,资源有限,所以就选择config-mini-tls1_1.h这个配置文件,复制该文件内的内容替换mbedtls的默认配置头文件mbedtls/config.h即可。
include,所有头文件
library,所有源代码
首先在STM32 工程目录下建立文件夹mbedtls,并将mbedtls源码目录下的include和library两个文件夹复制过来,复制config-mini-tls1_1.h文件中的内容替换include/config.h。(注:include/config.h文件是只读的,需要先修改权限为读写)。

打开keil工程将源码添加进来:

添加头文件包含:


修改include/config.h配置文件:

注释掉宏定义MBEDTLS_HAVE_TIME,因为我们目前没有用到时间相关的
注释掉宏定义MBEDTLS_NET_C,因为没有用到网络
注释掉宏定义MBEDTLS_FS_IO,这是带系统时候需要用到的标准系统调用IO,例如linux下的系统调用函数read、write等,裸机我们没有用到
添加一个宏定义MBEDTLS_NO_PLATFORM_ENTROPY,单片机无系统所以需要添加该宏。
然后编译工程即可~!


使用特权

评论回复
5
labasi|  楼主 | 2021-7-4 16:30 | 只看该作者
(3)移植测试
将printf函数重定向到串口一输出:

/// 重定向printf函数到串口一
int fputc(int ch, FILE* fp)
{
    while (__HAL_UART_GET_FLAG(&huart1, UART_FLAG_TXE) != SET);
    huart1.Instance->DR = (uint8_t)(ch & 0XFF);
    return ch;
}




下面我们开始编写代码测试,测试两个,一个是base64编码的,另一个是AES加解密的,
需要添加头文件:

#include "mbedtls/config.h"
#include "mbedtls/aes.h"
#include "mbedtls/base64.h"


使用特权

评论回复
6
labasi|  楼主 | 2021-7-4 16:31 | 只看该作者
base64编解码测试代码:

void mbedtls_base64_demo(void)
{
        int i = 0;
       
        // 原始数据
        uint8_t plaintext[16] = {'A','B','C','D','E','F','G','H','I','J', 'K', 'L', 'M', 'N', 'O', 'P'};

    // base64编码和解码输出数据的长度
    size_t enclen = 0, declen = 0;

    // 存放base64编码输出
    uint8_t encode[32];

    // 存放base64解码输出
    uint8_t decode[32];

        // 编码
    mbedtls_base64_encode(encode, sizeof(encode), &enclen, plaintext, sizeof(plaintext));

        // 解码
    mbedtls_base64_decode(decode, sizeof(decode), &declen, encode, enclen);

    printf("- enclen:%d\r\n", enclen);
    printf("- encode:%s\r\n", encode);
    printf("- declen:%d\r\n", declen);
    printf("- decode:");
        for(i = 0; i < declen; i++)
        {
                printf("%c", (char)decode[i]);
        }
        printf("\r\n");
}


使用特权

评论回复
7
labasi|  楼主 | 2021-7-4 16:31 | 只看该作者
AES加解密测试代码(ECB模式):

void mbedtls_aes_ecb_demo(void)
{
        int i = 0;
        mbedtls_aes_context ctx;
       
        // 要加密的数据
        uint8_t plaintext[16] = {'A','B','C','D','E','F','G','H','I','J', 'K', 'L', 'M', 'N', 'O', 'P'};

        // 密码
        const uint8_t passwd[32] = "AAAAAAAAAABBBBBBBBBBCCCCCCCCCCDD";
       
        // 加密输出
        uint8_t encrypt[16];
       
        // 解密输出
        uint8_t decrypt[16];

        // 初始化
        mbedtls_aes_init(&ctx);

        // 设置加密密钥
        mbedtls_aes_setkey_enc(&ctx, passwd, 256);
       
        // 加密
        mbedtls_aes_crypt_ecb(&ctx, MBEDTLS_AES_ENCRYPT, plaintext, encrypt);
       
        // 设置解密密钥
        mbedtls_aes_setkey_dec(&ctx, passwd, 256);
       
        // 解密
        mbedtls_aes_crypt_ecb(&ctx, MBEDTLS_AES_DECRYPT, encrypt, decrypt);

        // 清理
        mbedtls_aes_free(&ctx);
       
        printf("encrypt:");
        for(i = 0; i < 16; i++)
        {
                printf("%02X", encrypt[i]);
        }
        printf("\r\n");

        printf("decrypt:");
        for(i = 0; i < 16; i++)
        {
                printf("%c", decrypt[i]);
        }
        printf("\r\n");
}


使用特权

评论回复
8
labasi|  楼主 | 2021-7-4 16:31 | 只看该作者
AES加解密测试代码(CBC模式):

void mbedtls_aes_cbc_demo(void)
{
        int i = 0;

        mbedtls_aes_context ctx;

        // 密码
        uint8_t passwd[16] = "AAAAAAAAAACCCCDD";

        // 用于加密的向量表
        uint8_t iv_encrypt[16] = { 0X00, 0X01, 0X02, 0X03, 0X10, 0X11, 0X12, 0X13, 0X20, 0X21, 0X22, 0X23, 0X30, 0X31, 0X32, 0X33 };

        // 用于解密的向量表
        uint8_t iv_decrypt[16] = { 0X00, 0X01, 0X02, 0X03, 0X10, 0X11, 0X12, 0X13, 0X20, 0X21, 0X22, 0X23, 0X30, 0X31, 0X32, 0X33 };

        // 待加密的数据
        uint8_t plaintext[] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P' };

        // 存储加密后的输出
        uint8_t encrypt[sizeof(plaintext)];

        // 存储解密后的输出
        uint8_t decrypt[sizeof(plaintext)];

        // 加密
        mbedtls_aes_setkey_enc(&ctx, passwd, 128);
        mbedtls_aes_crypt_cbc(&ctx, MBEDTLS_AES_ENCRYPT, sizeof(plaintext), iv_encrypt, plaintext, encrypt);

        // 解密
        mbedtls_aes_setkey_dec(&ctx, passwd, 128);
        mbedtls_aes_crypt_cbc(&ctx, MBEDTLS_AES_DECRYPT, sizeof(plaintext), iv_decrypt, encrypt, decrypt);

        // 打印出加入后的结果
        for (i = 0; i < sizeof(plaintext); i++)
        {
                printf("%02X", encrypt[i]);
        }
        printf("\r\n");

        // 打印处解密后的结果
        for (i = 0; i < sizeof(plaintext); i++)
        {
                printf("%c", decrypt[i]);
        }
        printf("\r\n");
}



使用特权

评论回复
9
labasi|  楼主 | 2021-7-4 16:31 | 只看该作者

main函数如下:

程序运行效果:


网上有很多在线AES、BASE64加解密测试平台,可以去做验证移植测试的准确性!



使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

51

主题

3372

帖子

2

粉丝