mbedtls系列文章
一、自己适配随机数生成器
1. 配置宏
/**
* \def MBEDTLS_ENTROPY_HARDWARE_ALT
*
* Uncomment this macro to let mbed TLS use your own implementation of a
* hardware entropy collector.
*
* Your function must be called \c mbedtls_hardware_poll(), have the same
* prototype as declared in entropy_poll.h, and accept NULL as first argument.
*
* Uncomment to use your own hardware entropy collector.
*/
#define MBEDTLS_ENTROPY_HARDWARE_ALT
如果不想使用mbedtls提供的随机数生成器,而是想使用操作系统提供的、或者硬件随机数生成器(RNG),则在mbedtls配置文件中开启该宏定义。
2. 适配mbedtls_hardware_poll函数
创建一个新文件用于存放我们编写的该函数实现,这里我创建文件entropy_hardware_alt.c
。
实现时需要包含头文件entropy_poll.h
,其中包含了 mbedtls_hardware_poll() 函数的原型定义:
#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
/**
* \brief Entropy poll callback for a hardware source
*
* \warning This is not provided by mbed TLS!
* See \c MBEDTLS_ENTROPY_HARDWARE_ALT in config.h.
*
* \note This must accept NULL as its first argument.
*/
int mbedtls_hardware_poll( void *data,
unsigned char *output, size_t len, size_t *olen );
#endif
这里我使用之前移植到小熊派开发板的工程,先开启RNG外设,然后使用硬件RNG外设实现该函数。
① 开启硬件RNG外设:
② 编辑文件entropy_hardware_alt.c
,实现函数
#include "mbedtls/entropy_poll.h"
#ifdef MBEDTLS_ENTROPY_HARDWARE_ALT
#include "main.h"
#include "string.h"
#include "stm32l4xx_hal.h"
#include "mbedtls/entropy_poll.h"
extern RNG_HandleTypeDef hrng;
int mbedtls_hardware_poll( void *Data, unsigned char *Output, size_t Len, size_t *oLen )
{
uint32_t index;
uint32_t randomValue;
for (index = 0; index < Len/4; index++)
{
if (HAL_RNG_GenerateRandomNumber(&hrng, &randomValue) == HAL_OK)
{
*oLen += 4;
memset(&(Output[index * 4]), (int)randomValue, 4);
}
else
{
Error_Handler();
}
}
return 0;
}
#endif /*MBEDTLS_ENTROPY_HARDWARE_ALT*/
二、测试随机数生成器
1. 宏配置
使用mbedtls随机数生成功能需要开启以下宏:
① MBEDTLS_ENTROPY_C
/**
* \def MBEDTLS_ENTROPY_C
*
* Enable the platform-specific entropy code.
*
* Module: library/entropy.c
* Caller:
*
* Requires: MBEDTLS_SHA512_C or MBEDTLS_SHA256_C
*
* This module provides a generic entropy pool
*/
#define MBEDTLS_ENTROPY_C
② MBEDTLS_AES_C
/**
* \def MBEDTLS_AES_C
*
* Enable the AES block cipher.
*
* Module: library/aes.c
* Caller: library/cipher.c
* library/pem.c
* library/ctr_drbg.c
*
* This module enables the following ciphersuites (if other requisites are
* enabled as well):
* MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA
* MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
* MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA
* MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
* MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256
* MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384
* MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256
* MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384
* MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256
* MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384
* MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256
* MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384
* MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
* MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
* MBEDTLS_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
* MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
* MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
* MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
* MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
* MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
* MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA
* MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
* MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
* MBEDTLS_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
* MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
* MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
* MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
* MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
* MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
* MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA
* MBEDTLS_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384
* MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384
* MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384
* MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA
* MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA
* MBEDTLS_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256
* MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256
* MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256
* MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA
* MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA
* MBEDTLS_TLS_RSA_WITH_AES_256_GCM_SHA384
* MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA256
* MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA
* MBEDTLS_TLS_RSA_WITH_AES_128_GCM_SHA256
* MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA256
* MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA
* MBEDTLS_TLS_RSA_PSK_WITH_AES_256_GCM_SHA384
* MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA384
* MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA
* MBEDTLS_TLS_RSA_PSK_WITH_AES_128_GCM_SHA256
* MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA256
* MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA
* MBEDTLS_TLS_PSK_WITH_AES_256_GCM_SHA384
* MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA384
* MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA
* MBEDTLS_TLS_PSK_WITH_AES_128_GCM_SHA256
* MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA256
* MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA
*
* PEM_PARSE uses AES for decrypting encrypted keys.
*/
#define MBEDTLS_AES_C
③ MBEDTLS_CTR_DRBG_C
/**
* \def MBEDTLS_CTR_DRBG_C
*
* Enable the CTR_DRBG AES-based random generator.
* The CTR_DRBG generator uses AES-256 by default.
* To use AES-128 instead, enable MBEDTLS_CTR_DRBG_USE_128_BIT_KEY below.
*
* Module: library/ctr_drbg.c
* Caller:
*
* Requires: MBEDTLS_AES_C
*
* This module provides the CTR_DRBG AES random number generator.
*/
#define MBEDTLS_CTR_DRBG_C
特别注意!如是cubemx自动生成的mbedtls工程,请屏蔽宏
MBEDTLS_AES_ROM_TABLES
,如果开启之后会导致Hardfault!问题有待分析。
2. 测试代码
在main.c中包含头文件:
#include "mbedtls/entropy.h"
#include "mbedtls/ctr_drbg.h"
在main函数中添加drgb生成随机数的测试代码:
/* 1. crt_drbg test */
int ret;
const char *pers = "crbg_test";
mbedtls_entropy_context entropy;
mbedtls_ctr_drbg_context ctr_drbg;
mbedtls_ctr_drbg_init( &ctr_drbg );
printf( "\n . Seeding the random number generator..." );
fflush( stdout );
mbedtls_entropy_init( &entropy );
if( ( ret = mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func, &entropy,
(const unsigned char *) pers,
strlen( pers ) ) ) != 0 )
{
printf( " failed\n ! mbedtls_ctr_drbg_seed returned %d\n", ret );
goto exit;
}
printf( " ok\n" );
printf( "\n . generate random data..." );
fflush( stdout );
uint8_t data_buf[10];
if ( ( ret = mbedtls_ctr_drbg_random(&ctr_drbg, data_buf, sizeof(data_buf) ) ) != 0) {
printf( " failed\n ! mbedtls_ctr_drbg_random returned %d\n", ret );
goto exit;
}
printf( " ok\n" );
printf("random data:[");
for (int i = 0; i < sizeof(data_buf); i++) {
printf("%02x ", data_buf[i]);
}
printf("]\r\n");
还需要添加exit标号,这里我添加到死循环前面:
3. 测试结果
编译,下载,在串口助手中查看运行结果:
按下复位再次运行,比较生成的随机数:
接收精彩文章及资源推送,请订阅我的微信公众号:『mculover666』。