mbedtls移植到k20简要笔记

本文介绍mbedtls库的移植步骤,包括配置随机数生成器、程序裁剪等,并提供了一个基于rt-thread操作系统的示例代码,展示了如何进行SSL/TLS连接。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

mbedtls下载:

https://github.com/ARMmbed/mbedtls


移植源文件:

1)拿出解压后的mbedtls-development目录下的include文件和library文件

2)拿出mbedtls-development\programs\ssl下的demo,如ssl_client1.c(客户端代码)


程序处理:

1)随机数生成器

若芯片不支持随机数发生器可在config.h中打开宏  MBEDTLS_TEST_NULL_ENTROPY 并屏蔽宏  MBEDTLS_HAVEGE_C ,这样并不安全

若芯片支持随机数发生器则在config.h中关闭宏  MBEDTLS_TEST_NULL_ENTROPY 并打开宏  MBEDTLS_HAVEGE_C 

问题可在 mbedtls论坛上查询


2)程序裁剪:

为节省ROM和RAM,在config.h中注释如下宏定义

MBEDTLS_SELF_TEST //自测

MBEDTLS_VERSION_FEATURES  //disable run-time checking and save ROM space

其他根据宏定义的说明适当打开或屏蔽,如:MBEDTLS_BLOWFISH_C//实际不适用这个算法,可注释以节省空间


3)time接口:

在platform_time.h中

重定向 mbedtls_time宏,根据当前平台重新实现time接口,如这里实现如下

platform_time.h中:

#define mbedtls_time   new_time

new_time 接口实现如下,这里使用RTC寄存器

time_t new_time(time_t * parm)
{
struct tm* p;
RTC_QuickInit();
time_t timep = (time_t)RTC_GetTSR();
if(timep <= 1000)
{
timep = 0x95272759;
}
    p = localtime(&timep);
    timep = mktime(p);
return timep;
}

证书部分:

证书制作参照 openssl+tomcat7使用简明笔记http://blog.youkuaiyun.com/ppdyhappy/article/details/56019429

    if( ( ret = mbedtls_ssl_set_hostname( &ssl, "host_name") ) != 0 )
    {
        mbedtls_printf( " failed\n  ! mbedtls_ssl_set_hostname returned %d\r\n", ret );
        goto exit;
    }

这里host_name对应服务器证书中的common name


使用openssl公钥最短为512bit,如此可降低芯片处理难度,对应要在x509_crt.c中修改公钥长度,修改部分如下:

const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_default =
{
    /* Hashes from SHA-1 and above */
    MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA1 ) |
    MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_RIPEMD160 ) |
    MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA224 ) |
    MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA256 ) |
    MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA384 ) |
    MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA512 ),
    0xFFFFFFF, /* Any PK alg    */
    0xFFFFFFF, /* Any curve     */
    512, // 2048 修改这里
};

这边实测mbedtls大概占用RAM 16kb左右

mbedtls论坛:https://tls.mbed.org/discussions


植接口及测试部分代码:

ssl_interface.h

//*******************************************************************//

#ifndef _SSL_INTERFACE_H_
#define _SSL_INTERFACE_H_

int ssl_create( void );
int ssl_close( void );
int ssl_write( const unsigned char *buf, uint32_t len );
int ssl_read( unsigned char *buf, uint32_t len );

#endif



ssl_interface.c //rt-thread 操作系统,代码还未完善

//*******************************************************************//

#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif

#if defined(MBEDTLS_PLATFORM_C)
#include "mbedtls/platform.h"
#else
#include <stdio.h>
#include <stdlib.h>
#define mbedtls_time       mktime 
#define mbedtls_time_t     time_t
#define mbedtls_fprintf    fprintf
//#define mbedtls_printf     rt_kprintf
#endif

#include "mbedtls/net_sockets.h"
#include "mbedtls/debug.h"
#include "mbedtls/ssl.h"
#include "mbedtls/entropy.h"
#include "mbedtls/ctr_drbg.h"
#include "mbedtls/error.h"
#include "mbedtls/certs.h"

#include <string.h>

#include "socket.h"               //socket接口用
#include "ssl_interface.h"
#include "common.h"          //

#define SERVER_PORT 8080
#define SERVER_NAME "www.baidu.com" //
#define SERVER_HOSTNAME "hello" //server's certificate common name

#define DEBUG_LEVEL 1

static void my_debug( void *ctx, int level,
                      const char *file, int line,
                      const char *str )
{
    ((void) level);
    mbedtls_fprintf( (FILE *) ctx, "%s:%04d: %s", file, line, str );
    fflush(  (FILE *) ctx  );
}

static int32_t ssl_socketID = 0;
static void ssl_socket_recive_data(char * recv_buff, rt_uint32_t len);
static int ssl_connect_net(void)
{
    int32_t aswResult;
SockAddr addr;

    memcpy(addr.g_u8_socket_connect_host,SERVER_NAME,sizeof(SERVER_NAME));
    addr.g_u16_socket_connect_port = SERVER_PORT;
    addr.g_vd_socket_rtcp_data_cb = ssl_socket_recive_data;

    if (0 == ssl_socketID)
    {
        ssl_socketID = g_s32_NET_socket();
}

if(ssl_socketID < 0)
{
return -1;
}

if(g_s32_NET_connect(ssl_socketID,&addr,sizeof(SockAddr)) != 0)
{
return -1;
}

return 0;
}

static char ssl_rec_buf[500] = {0};
/*
ssl_rec_flag:-2 receive action is error
ssl_rec_flag:-1 no receive action
ssl_rec_flag:0 have receive action
ssl_rec_flag:1 have read action
ssl_rec_flag:2 read over
*/

//#define 

static int ssl_rec_flag = -1;
static uint32_t ssl_rec_len = 0;

static void ssl_socket_recive_data(char * recv_buff, uint32_t len)
{
if((ssl_rec_flag != -1) || (ssl_rec_flag != 2))
{
ssl_rec_flag = -2;
}

if(ssl_rec_flag == 1)
{

}
else
{
ssl_rec_len = len;

memcpy(ssl_rec_buf, recv_buff, len);

ssl_rec_flag = 0;
}

}
//int32_t g_s32_NET_write(int32_t sockfd, void *buf, uint32_t count)
//MBEDTLS_ERR_NET_SEND_FAILED
static int wrap_ssl_send( void *ctx, unsigned char *buf, size_t len )
{
ctx = ctx;

if(g_s32_NET_write(ssl_socketID, (void*)buf, (uint32_t)len) == -1)
{
return MBEDTLS_ERR_NET_SEND_FAILED;
}

return (int)len;
}

static void wait_socket_rev(uint32_t count)
{

}

//MBEDTLS_ERR_NET_RECV_FAILED
static int wrap_ssl_recv( void *ctx, unsigned char *buf, size_t len )
{
static size_t get_len = 0;
static size_t sum_len = 0;
size_t temp_len = 0;
uint32_t k = 0;

ctx = ctx;

if(-2 == ssl_rec_flag)
{
return MBEDTLS_ERR_NET_RECV_FAILED;
}

// have read action
if(ssl_rec_flag == 1)
{
// do nothing
}
else
{
while(ssl_rec_flag != 0)
{
DelayMs(1);

k += 1;

if(k == 10000)
{
return MBEDTLS_ERR_NET_RECV_FAILED;
}
}

sum_len = (size_t)ssl_rec_len;
get_len = 0;
}
// have receive action
if(ssl_rec_flag == 0)
{
ssl_rec_flag = 1;
}

if(sum_len >= (len + get_len))
{
temp_len = len;
}
else
{
temp_len = sum_len - get_len;
}

if(0 == temp_len)
{
return MBEDTLS_ERR_NET_RECV_FAILED;
}

memcpy(buf, ssl_rec_buf + get_len, temp_len);

get_len += temp_len;

if(get_len == sum_len)
{
ssl_rec_flag = 2;
}
else if(get_len > sum_len)
{
//
}
else
{

}

return (int)temp_len;
}
//0:no close action 1:have close action
static uint8_t close_socket_flag = 0;
static int close_socket_ret = 0;

static int ssl_close_socket(void)
{
int ret = 0;

if(1 == close_socket_flag)
return close_socket_ret;

ssl_socketID = 0;

if((close_socket_ret = g_s32_NET_close(ssl_socketID)) != 0)
{
mbedtls_printf("close ssl socket[%d] fail!\r\n", ssl_socketID);
}
else
{
mbedtls_printf("close ssl socket[%d] success!\r\n", ssl_socketID);
}

close_socket_flag = 1;
return close_socket_ret;
}

//0:no clean 1:have clean
static uint8_t clean_flag = 0;
static void ssl_clean_up(void);


mbedtls_net_context server_fd;
mbedtls_entropy_context entropy;
mbedtls_ctr_drbg_context ctr_drbg;
mbedtls_ssl_context ssl;
mbedtls_ssl_config conf;
mbedtls_x509_crt cacert;

int ssl_create( void )
{
    int ret;
    uint32_t flags;
    unsigned char buf[1024];
    const char *pers = "bj";

//Æô¶¯µ÷ÊÔ¹¦ÄÜ
#if defined(MBEDTLS_DEBUG_C)
    mbedtls_debug_set_threshold( DEBUG_LEVEL );
#endif

clean_flag = 0;
close_socket_flag = 0;
close_socket_ret = 0;

    /*
     * 0. Initialize the RNG and the session data
     */
// ÓÃsocket ÅäÖÃ
//    mbedtls_net_init( &server_fd ); // ignore ysw
    mbedtls_ssl_init( &ssl );
    mbedtls_ssl_config_init( &conf );
    mbedtls_x509_crt_init( &cacert );
    mbedtls_ctr_drbg_init( &ctr_drbg );

    mbedtls_printf( "\n  . Seeding the random number generator..." );
    fflush( stdout );
// ìØ³õʼ»¯
    mbedtls_entropy_init( &entropy );
//DRBG---->Deterministic Random Bit Generators Î±Ëæ»úÊý²úÉúÆ÷
    if( ( ret = mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func, &entropy,
                               (const unsigned char *) pers,
                               strlen( pers ) ) ) != 0 )
    {
        mbedtls_printf( " failed\n  ! mbedtls_ctr_drbg_seed returned %d\n", ret );
        goto exit_no_socket;
    }

    mbedtls_printf( " ok\n" );

    /*
     * 0. Initialize certificates
     */
    mbedtls_printf( "  . Loading the CA root certificate ..." );
    fflush( stdout );
//±¾µØÖ¤Êé´¦Àí£¬ÓÃÓÚУÑé·þÎñÆ÷Ö¤ÊéÓ㬿ɼò»¯´¦Àí
//mbedtls_test_cas_pem ´æ·ÅÖ¤ÊéÊý¾ÝµÄbuf
    ret = mbedtls_x509_crt_parse( &cacert, (const unsigned char *) mbedtls_test_cas_pem,
                          mbedtls_test_cas_pem_len );
    if( ret < 0 )
    {
        mbedtls_printf( " failed\n  !  mbedtls_x509_crt_parse returned -0x%x\r\n", -ret );
        goto exit_no_socket;
    }

    mbedtls_printf( " ok (%d skipped)\n", ret );

    /*
     * 1. Start the connection
     */
    mbedtls_printf( "  . Connecting to tcp/%s/%d...", SERVER_NAME, SERVER_PORT );
    fflush( stdout );
//ÏÖÔÚ socket Á¬½Ó½Ó¿ÚºÜ¼òµ¥£¬Ö±½Óµ÷Óü´¿É
#if 0 
    if( ( ret = mbedtls_net_connect( &server_fd, SERVER_NAME,
                                         SERVER_PORT, MBEDTLS_NET_PROTO_TCP ) ) != 0 )
    {
        mbedtls_printf( " failed\n  ! mbedtls_net_connect returned %d\r\n", ret );
        goto exit;
    }
#endif 

    if( ( ret = ssl_connect_net() ) != 0 )
    {
        mbedtls_printf( " failed\n  ! ssl_connect_net returned %d\r\n", ret );
        goto exit;
    } 

    mbedtls_printf( " ok\n" );

    /*
     * 2. Setup stuff
     */
    mbedtls_printf( "  . Setting up the SSL/TLS structure..." );
    fflush( stdout );


//MBEDTLS_SSL_IS_CLIENT ±íʾÅäÖÃΪ¿Í»§¶Ë
//MBEDTLS_SSL_TRANSPORT_STREAM ±íʾ´«Ê䷽ʽΪTLS
//ÉèÖð汾£¬ MBEDTLS_SSL_PRESET_DEFAULT ±íʾ TLS1.0
    if( ( ret = mbedtls_ssl_config_defaults( &conf,
                    MBEDTLS_SSL_IS_CLIENT,
                    MBEDTLS_SSL_TRANSPORT_STREAM,
                    MBEDTLS_SSL_PRESET_DEFAULT ) ) != 0 )
    {
        mbedtls_printf( " failed\n  ! mbedtls_ssl_config_defaults returned %d\r\n", ret );
        goto exit;
    }

    mbedtls_printf( " ok\n" );

    /* OPTIONAL is not optimal for security,
     * but makes interop easier in this simplified example */
// ÉèÖÃÊý×ÖÖ¤Êé¼ì²éģʽ 
// MBEDTLS_SSL_VERIFY_OPTIONAL ÔÚclientģʽϲ»ÍƼöʹÓã¬ÒòΪ²»¹»°²È«

/*
*  MBEDTLS_SSL_VERIFY_NONE:      peer certificate is not checked
*                        (default on server)
*                        (insecure on client)
*
*  MBEDTLS_SSL_VERIFY_OPTIONAL:  peer certificate is checked, however the
*                        handshake continues even if verification failed;
*                        mbedtls_ssl_get_verify_result() can be called after the
*                        handshake is complete.
*
*  MBEDTLS_SSL_VERIFY_REQUIRED:  peer *must* present a valid certificate,
*                        handshake is aborted if verification failed.
*                        (default on client)
*/
    mbedtls_ssl_conf_authmode( &conf, MBEDTLS_SSL_VERIFY_OPTIONAL );
// Ö¤ÊéÁ´£¬Ô¤ÏÈ´æ·ÅÔÚ±¾µØµÄ
    mbedtls_ssl_conf_ca_chain( &conf, &cacert, NULL );
// ÅäÖÃËæ»úÊýÉú³ÉÆ÷µÄ»Øµ÷º¯Êý
    mbedtls_ssl_conf_rng( &conf, mbedtls_ctr_drbg_random, &ctr_drbg );
// ÅäÖõ÷ÊԻص÷º¯Êý
    mbedtls_ssl_conf_dbg( &conf, my_debug, stdout );
// ¸ù¾ÝconfÉèÖÃssl½á¹¹
    if( ( ret = mbedtls_ssl_setup( &ssl, &conf ) ) != 0 )
    {
        mbedtls_printf( " failed\n  ! mbedtls_ssl_setup returned %d\r\n", ret );
        goto exit;
    }
// ÉèÖÃhost name Óõ½¶¯Ì¬ÄÚ´æ·ÖÅä
    if( ( ret = mbedtls_ssl_set_hostname( &ssl, SERVER_HOSTNAME ) ) != 0 )
    {
        mbedtls_printf( " failed\n  ! mbedtls_ssl_set_hostname returned %d\r\n", ret );
        goto exit;
    }
// ÉèÖ÷¢ËͺͽÓÊÕ½Ó¿Ú
//    mbedtls_ssl_set_bio( &ssl, &server_fd, mbedtls_net_send, mbedtls_net_recv, NULL );
    mbedtls_ssl_set_bio( &ssl, &server_fd, wrap_ssl_send, wrap_ssl_recv, NULL );

    /*
     * 4. Handshake
     */
    mbedtls_printf( "  . Performing the SSL/TLS handshake..." );
    fflush( stdout );


    while( ( ret = mbedtls_ssl_handshake( &ssl ) ) != 0 )
    {
        if( ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE )
        {
            mbedtls_printf( " failed\n  ! mbedtls_ssl_handshake returned -0x%x\r\n", -ret );
            goto exit;
        }
    }

    mbedtls_printf( " ok\n" );
    /*
     * 5. Verify the server certificate
     */
    mbedtls_printf( "  . Verifying peer X.509 certificate..." );

    /* In real life, we probably want to bail out when ret != 0 */
    if( ( flags = mbedtls_ssl_get_verify_result( &ssl ) ) != 0 )
    {
        char vrfy_buf[512];
        mbedtls_printf( " failed\n" );
        mbedtls_x509_crt_verify_info( vrfy_buf, sizeof( vrfy_buf ), "  ! ", flags );
        mbedtls_printf( "%s\n", vrfy_buf );
    }
    else
        mbedtls_printf( " ok\n" );

return (ret);

exit:

#ifdef MBEDTLS_ERROR_C
    if( ret != 0 )
    {
        char error_buf[100];
        mbedtls_strerror( ret, error_buf, 100 );
        mbedtls_printf("Last error was: %d - %s\r\n", ret, error_buf );
    }
#endif

ssl_close_socket();

exit_no_socket:
ssl_clean_up();

#if defined(_WIN32)
    mbedtls_printf( "  + Press Enter to exit this program.\n" );
    fflush( stdout ); getchar();
#endif

    return( ret );
}
//#endif /* MBEDTLS_BIGNUM_C && MBEDTLS_ENTROPY_C && MBEDTLS_SSL_TLS_C &&
//          MBEDTLS_SSL_CLI_C && MBEDTLS_NET_C && MBEDTLS_RSA_C &&
//          MBEDTLS_CERTS_C && MBEDTLS_PEM_PARSE_C && MBEDTLS_CTR_DRBG_C &&
//          MBEDTLS_X509_CRT_PARSE_C */

// return 0:success
// return -1:fail
int ssl_write( const unsigned char *buf, uint32_t len )
{
int ret;

    while( ( ret = mbedtls_ssl_write( &ssl, buf, (size_t)len ) ) <= 0 )
    {
        if( ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE )
        {
            mbedtls_printf( " failed\n  ! mbedtls_ssl_write returned %d\r\n", ret );

ssl_close_socket();

            ssl_clean_up();

return -1;
        }
    }
return 0;
}

int ssl_read( unsigned char *buf, uint32_t len )
{
int ret;

    do
    {
        ret = mbedtls_ssl_read( &ssl, buf, len );


        if( ret == MBEDTLS_ERR_SSL_WANT_READ || ret == MBEDTLS_ERR_SSL_WANT_WRITE )
            continue;


        if( ret == MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY )
mbedtls_printf( "failed\n  ! mbedtls_ssl_read returned %d\n\n", ret );
mbedtls_ssl_close_notify( &ssl );
ssl_clean_up();

            return -1;

        if( ret < 0 )
        {
            mbedtls_printf( "failed\n  ! mbedtls_ssl_read returned %d\n\n", ret );
ssl_clean_up();
            return -1;
        }

//        if( ret == 0 )
//        {
//            mbedtls_printf( "\n\nEOF\n\n" );
//            break;
//        }


        len = ret;
        mbedtls_printf( " %d bytes read\n\n%s", len, (char *) buf );
    }
    while( 1 ); 

return ret;
}

//clean up
static void ssl_clean_up(void)
{
if(1 == clean_flag)
return;

mbedtls_printf(" ssl clean up\r\n");

    mbedtls_x509_crt_free( &cacert );
    mbedtls_ssl_free( &ssl );
mbedtls_ssl_config_free( &conf );
    mbedtls_ctr_drbg_free( &ctr_drbg );
    mbedtls_entropy_free( &entropy );

clean_flag = 1;
}

//ssl close
int ssl_close( void )
{
mbedtls_printf(" ssl close\r\n");
ssl_clean_up();
return( ssl_close_socket() );
}


测试代码

//*******************************************************************//

unsigned char t_buff[] = {"GET /dispatcher?user=dididada HTTP/1.1\r\nHost: www.baidu.com:8080\r\nAccept: */*\r\nConnection: keep-alive\r\n\r\n"};
unsigned char rec_buf[300] = {0};
 void mbedtls_test(void * parameter)
{
int flag = 0;
flag = ssl_create();
ssl_write(t_buff, sizeof(t_buff));
flag = ssl_read(rec_buf, sizeof(rec_buf));
ssl_close();
}









评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值