为什么 RSA_generate_key 使用未初始化的值(根据 valgrind)

Why RSA_generate_key uses uninitialized values (according to valgrind)

我一直在研究涉及密码学的东西。我必须承认我在密码学方面的知识非常基础。因此,我决定在 RSA_generate_keyopenssl 库生成 RSA 密钥后,看看 RSA 结构包含什么。但是我遇到了分段错误:

const unsigned long e = 3;
const int num = 3072;   
...
RSA *rsa_key = RSA_generate_key(num, e, NULL, NULL);
if (!rsa_key)
{
    printf("Failed to generate RSA key!\n");
    return RSA_ERROR_CODE;
}

printf("rsa->pad=0x%x\n", rsa_key->pad);
printf("rsa->version=0x%lx\n", rsa_key->version);
if (rsa_key->n)
{
    printf("rsa->n->top=0x%x\n", rsa_key->n->top); // HERE I got the seg fault
    ....

我觉得它很奇怪,所以我写了一个最小的代码来用 valgrind tool 测试它。这是 C:

中的代码
#include "openssl/rsa.h"
#include <stdio.h>

int main()
{       
    const unsigned long e = 3;   // the exponent, 3 in QVRSA
    const int num = 3072;   

    RSA *rsa_key = RSA_generate_key(num, e, NULL, NULL);

    if (rsa_key == NULL)
    {
        printf("RSA is invalid!\n");
        return 1;
    }

    printf("rsa->pad=0x%x\n", rsa_key->pad);
    printf("rsa->version=0x%lx\n", rsa_key->version);
    if (rsa_key->n)
    {
        printf("rsa->n->top=0x%x\n", rsa_key->n->top);
    }

    RSA_free(rsa_key);
    rsa_key = NULL;
    return 0;
}

编译行:gcc rsa.c -lcrypto -g -O0 -o rsa

这次没有分段错误,输出为:

rsa->pad=0x0 
rsa->version=0x0 
rsa->n->top=0x30

BUT valgrind 触发了大量错误消息:

==6916== Conditional jump or move depends on uninitialised value(s)
==6916==    at 0x4DAEB37: BN_bin2bn (in /usr/lib64/libcrypto.so.0.9.8)
==6916==    by 0x4DB1B62: ??? (in /usr/lib64/libcrypto.so.0.9.8)
==6916==    by 0x4DB4471: BN_generate_prime_ex (in /usr/lib64/libcrypto.so.0.9.8)
==6916==    by 0x4DC8763: RSA_generate_key_ex (in /usr/lib64/libcrypto.so.0.9.8)
==6916==    by 0x4DCB763: RSA_generate_key (in /usr/lib64/libcrypto.so.0.9.8)
==6916==    by 0x40072E: main (rsa.c:9)
==6916==  Uninitialised value was created by a heap allocation
==6916==    at 0x4B23D6D: malloc (vg_replace_malloc.c:270)
==6916==    by 0x4D8936A: CRYPTO_malloc (in /usr/lib64/libcrypto.so.0.9.8)
==6916==    by 0x4DB1AD1: ??? (in /usr/lib64/libcrypto.so.0.9.8)
==6916==    by 0x4DB4471: BN_generate_prime_ex (in /usr/lib64/libcrypto.so.0.9.8)
==6916==    by 0x4DC8763: RSA_generate_key_ex (in /usr/lib64/libcrypto.so.0.9.8)
==6916==    by 0x4DCB763: RSA_generate_key (in /usr/lib64/libcrypto.so.0.9.8)
==6916==    by 0x40072E: main (rsa.c:9)

==6916== Conditional jump or move depends on uninitialised value(s)
==6916==    at 0x4DB44D0: BN_generate_prime_ex (in /usr/lib64/libcrypto.so.0.9.8)
==6916==    by 0x4DC8763: RSA_generate_key_ex (in /usr/lib64/libcrypto.so.0.9.8)
==6916==    by 0x4DCB763: RSA_generate_key (in /usr/lib64/libcrypto.so.0.9.8)
==6916==    by 0x40072E: main (rsa.c:9)
==6916==  Uninitialised value was created by a heap allocation
==6916==    at 0x4B23D6D: malloc (vg_replace_malloc.c:270)
==6916==    by 0x4D8936A: CRYPTO_malloc (in /usr/lib64/libcrypto.so.0.9.8)
==6916==    by 0x4DB1AD1: ??? (in /usr/lib64/libcrypto.so.0.9.8)
==6916==    by 0x4DB4471: BN_generate_prime_ex (in /usr/lib64/libcrypto.so.0.9.8)
==6916==    by 0x4DC8763: RSA_generate_key_ex (in /usr/lib64/libcrypto.so.0.9.8)
==6916==    by 0x4DCB763: RSA_generate_key (in /usr/lib64/libcrypto.so.0.9.8)
==6916==    by 0x40072E: main (rsa.c:9)

还有许多其他条件跳转或移动取决于未初始化的值标题。

为什么? openSSL 中是否存在已知错误,或者它只是一个误报,我原来的分段错误与我原始代码中的一些隐藏错误有关?

我用过:

OpenSSL 正在使用一些未初始化的变量生成随机数据来生成密钥。然后 Valgrind 会报错,所以不是误报。

根据 openSSL FAQ,要摆脱它,请使用 -DPURIFY 进行编译。 但是,您可以讨论测试与生产二进制文件不同的编译二进制文件是否是个好主意。