承接上篇,我们初步了解了mbedtls的文件路径以及文件作用以后就是想着如何将mbedtls移植到各种平台。
博主这里只有两种移植方法,第一是将代码移植到VS中,第二个是将代码移植到博主跑动的比较多的小众SOC ESP8266。
移植到ESP8266 SDK中采用了一种比较简单的方法,博主没有使用比较复杂的Mike修改方法,只是将代码复制过去,并将工程搭建起来,这里博主给出搭建的方法。
1.随便选一个ESP8266 的工程,如下所示。
2. 将mbedtls下的library和include两个文件复制到ESP8266的 SDK的路径下,这里博主不采用修改SDK的的mikefile文件的方式嵌入到SDK中,这样做到最小的修改数目。
3.将第三课中在VS中完美完成的测试的MD5代码或者SHA 256算法的代码放入到SDK中。
如将所有的include中的mbedtls代码直接复制到SDK的app\include路径下,如对比截图所示:
其中变化的地方就是博主主要patch的一个文件config.h配置文件。在该文件中,博主需要将仅适配Windows或Linux这种大型系统的特定宏注释掉。
当然这里有个比较取巧的方式,将原本属于mbedtls-2.14.1\configs下的config-mini-tls1_1.h直接复制替换 SDK mbedtls/config.h里面的内容,如图所示:
其中,博主尤其过滤了几个宏,这些宏经过博主的测试都是只能在Windows下发生作用,在ESP8266这种下面嵌入式平台下,会导致编译报错。
需要注释以下的宏:
MBEDTLS_NET_C
/**
* \def MBEDTLS_NET_C
*
* Enable the TCP and UDP over IPv6/IPv4 networking routines.
*
* \note This module only works on POSIX/Unix (including Linux, BSD and OS X)
* and Windows. For other platforms, you'll want to disable it, and write your
* own networking callbacks to be passed to \c mbedtls_ssl_set_bio().
*
* \note See also our Knowledge Base article about porting to a new
* environment:
* https://tls.mbed.org/kb/how-to/how-do-i-port-mbed-tls-to-a-new-environment-OS
*
* Module: library/net_sockets.c
*
* This module provides networking routines.
*/
根据博主的测试,以上的宏如果使能,会导致一些以太网功能的库文件编译失败,比如
可以看出报错为找不到sys/socket.h以太网通讯使用的头文件,以及标注只能在一些大型系统中的报错提醒,对于博主来说直接禁用这个宏,解决所有问题。
MBEDTLS_FS_IO
/**
* \def MBEDTLS_FS_IO
*
* Enable functions that use the filesystem.
*/
这个函数是因为博主所使用的是freertos的小型系统,里面并不具有文件系统功能,所以直接禁用了。不禁用也会出现编译报错问题,更为深刻的问题,博主没有探究,反正和本次移植Hash算法无关。
4.引用博主使用的配置文件的宏
#ifndef MBEDTLS_CONFIG_H
#define MBEDTLS_CONFIG_H
/* System support */
#define MBEDTLS_HAVE_ASM
#define MBEDTLS_HAVE_TIME
/* mbed TLS feature support */
#define MBEDTLS_CIPHER_MODE_CBC
#define MBEDTLS_PKCS1_V15
#define MBEDTLS_KEY_EXCHANGE_RSA_ENABLED
#define MBEDTLS_SSL_PROTO_TLS1_1
/* mbed TLS modules */
#define MBEDTLS_AES_C
#define MBEDTLS_ASN1_PARSE_C
#define MBEDTLS_ASN1_WRITE_C
#define MBEDTLS_BIGNUM_C
#define MBEDTLS_CIPHER_C
#define MBEDTLS_CTR_DRBG_C
#define MBEDTLS_DES_C
#define MBEDTLS_ENTROPY_C
#define MBEDTLS_MD_C
#define MBEDTLS_MD5_C
//#define MBEDTLS_NET_C
#define MBEDTLS_OID_C
#define MBEDTLS_PK_C
#define MBEDTLS_PK_PARSE_C
#define MBEDTLS_RSA_C
#define MBEDTLS_SHA1_C
#define MBEDTLS_SHA256_C
#define MBEDTLS_SSL_CLI_C
#define MBEDTLS_SSL_SRV_C
#define MBEDTLS_SSL_TLS_C
#define MBEDTLS_X509_CRT_PARSE_C
#define MBEDTLS_X509_USE_C
/* For test certificates */
#define MBEDTLS_BASE64_C
#define MBEDTLS_CERTS_C
#define MBEDTLS_PEM_PARSE_C
#define MBEDTLS_ENTROPY_HARDWARE_ALT
/* For testing with compat.sh */
//#define MBEDTLS_FS_IO
#define MBEDTLS_NO_PLATFORM_ENTROPY
#include "mbedtls/check_config.h"
#endif /* MBEDTLS_CONFIG_H */
以上的宏能够用支持HASH算法,RSA算法,其他的算法等待后续探索,但是完全能够满足本次使用的。
5.C库文件的使用
将library下的C文件直接复制到app\driver下,当然要注意不要使用到mbedtls的mikefile,而是沿用ESP8266的milefile文件,请参考博主的步骤,但是ESP8266 driver下的6个文件要保留。
7. 后续就是直接使用博主的代码
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include "mbedtls/sha256.h"
void test_hash()
{
int i;
mbedtls_sha256_context sha256_ctx;
const unsigned char encrypt[] = "hello_worled1234";
os_printf("SHA-256 加密\n");
mbedtls_sha256_init(&sha256_ctx);
mbedtls_sha256_starts(&sha256_ctx, 0); // 0表示传sha256 , 1 表示传SHA-244
mbedtls_sha256_update(&sha256_ctx, encrypt, strlen((char *)encrypt));
mbedtls_sha256_finish(&sha256_ctx, hash);
os_printf("SHA256加密前:[%s]\n", encrypt);
os_printf("SHA256加密后:");
for( i = 0; i < 32; i++)
{
os_printf("%02x", hash[i]);
//os_printf("%02x", i);
}
os_printf("\r\n");
mbedtls_sha256_free(&sha256_ctx);
}
主函数运行位置:
void user_init(void)
{
uart_init_new();
printf("SDK version:%s\n", system_get_sdk_version());
printf("Ai-Thinker Technology Co. Ltd.\r\n%s %s\r\n", __DATE__, __TIME__);
printf("Hello,World!\r\n");
//xTaskCreate(test_hash, "test_hash", 2048, NULL, 4, NULL);
//xTaskCreate(test_rsa, "test_rsa", 2048, NULL, 5, NULL);
while(1)
{
//test_AES();
//test_hash();
test_rsa();
//vTaskDelay(8 / portTICK_RATE_MS);
}
//test_rsa();
}