您的位置:首页 > 其它

mbedtls移植到k20简要笔记

2017-03-20 17:07 1166 查看
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.csdn.net/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();
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  mbedtls 移植