OpenSSL 3.0.7在RTOS上随机数种子初始化失败求助
OpenSSL 3.0.7 移植RTOS平台随机数初始化问题排查与解决方案
问题背景
我们正尝试将OpenSSL 3.0.7移植到RTOS平台,遭遇随机数初始化失败问题。相同代码逻辑在OpenSSL 1.1.1和1.0.2版本中可正常运行。需要明确OpenSSL 3.0.7中随机数种子初始化的步骤/函数调用方法,并排查现有代码问题。
旧版本(1.0.2/1.1.1)初始化代码
RAND_DRBG *master = NULL; master = RAND_DRBG_get0_master(); if(!master) { return 0; }
注:RAND_DRBG_get0_master()在OpenSSL 3.0.7中已废弃。
用户尝试的3.0.7版本代码(失败)
我们尝试用RAND_get0_public()替代,但调用后master为NULL导致失败,代码如下:
EVP_RAND_CTX *master = NULL; master = RAND_get0_public(NULL);
一、OpenSSL 3.0.7 随机数种子初始化正确步骤
OpenSSL 3.0重构了随机数架构,不再直接暴露DRBG实例,改为通过EVP_RAND相关接口操作。针对RTOS这类无系统原生随机源的环境,需手动完成以下步骤:
全局初始化OpenSSL库
必须先调用OPENSSL_init_crypto()完成全局初始化,确保随机数子系统被正确加载:OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CRYPTO_STRINGS | OPENSSL_INIT_ADD_ALL_CIPHERS | OPENSSL_INIT_ADD_ALL_DIGESTS, NULL);绑定自定义熵源(RTOS必备)
RTOS通常没有系统默认熵源,需通过RAND_set_rand_method()绑定自定义的熵采集函数(比如从硬件随机数模块、定时器抖动等获取熵):static int custom_rand_bytes(unsigned char *buf, int num) { // 替换为RTOS环境下的实际熵采集逻辑 for (int i = 0; i < num; i++) { buf[i] = read_hardware_rng_register(); } return num; } // 初始化时绑定自定义方法 static RAND_METHOD custom_rand = {0}; custom_rand.bytes = custom_rand_bytes; RAND_set_rand_method(&custom_rand);显式初始化随机数种子
无需直接获取master上下文,调用RAND_poll()强制从绑定的熵源采集种子,完成随机数系统初始化:if (RAND_poll() != 1) { // 初始化失败处理 return 0; }
二、用户尝试代码的问题排查
调用RAND_get0_public(NULL)返回NULL的核心原因:
- 未完成全局初始化:OpenSSL 3.0要求必须先调用
OPENSSL_init_crypto(),否则随机数子系统未启动,RAND_get0_public()会返回NULL。 - 无默认熵源:RTOS环境下没有系统提供的熵源,OpenSSL不会自动创建默认的
EVP_RAND_CTX,必须先绑定自定义熵源并完成RAND_poll()。 - 参数逻辑误区:
RAND_get0_public()的NULL参数表示使用全局上下文,但前提是全局上下文已完成初始化并绑定有效熵源。
三、修正后的初始化代码示例
#include <openssl/rand.h> #include <openssl/crypto.h> // 自定义熵采集函数,需根据RTOS硬件环境实现 static int custom_rand_bytes(unsigned char *buf, int num) { for (int i = 0; i < num; i++) { buf[i] = (unsigned char)rtos_get_hardware_random_byte(); } return num; } int init_openssl_random(void) { // 初始化OpenSSL全局上下文 OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CRYPTO_STRINGS | OPENSSL_INIT_ADD_ALL_CIPHERS | OPENSSL_INIT_ADD_ALL_DIGESTS, NULL); // 绑定自定义随机数方法 static RAND_METHOD custom_rand = {0}; custom_rand.bytes = custom_rand_bytes; RAND_set_rand_method(&custom_rand); // 强制采集种子初始化 if (RAND_poll() != 1) { return 0; } // 验证随机数生成功能 unsigned char test_buf[16]; if (RAND_bytes(test_buf, sizeof(test_buf)) != 1) { return 0; } return 1; }
内容的提问来源于stack exchange,提问作者Anshu Agarwal
相关产品推荐
相关产品推荐

