c - 为什么未初始化的内存可以安全地用于 OpenSSL 的随机数生成器?

标签 c openssl undefined-behavior

因此,距 Debian 维护者臭名昭著地导致 RNG 种子变得可预测由 commenting out a usage of uninitialized data 已经过去十一年多了。 .

这个问题在网络圈子里引起了很多热烈的讨论,大部分的焦点似乎都在批评审查过程或攻击有问题的开发者。

但是,我无法找到任何有关该部分最初出现的实际思考过程的信息。许多用户争辩说“最坏的情况下,它不会造成伤害”——然而,这对我来说似乎完全违反直觉。

毕竟,从未初始化的内存中读取会调用未定义的行为,臭名昭著的是,这会导致鼻恶魔、运行网络攻击或格式化硬盘。因此,在我看来,将这种逻辑引入任何程序——更不用说加密库了——可以让你进行积极的编译器优化,避免彻底的灾难。

因此,我的问题:

  • 我是不是误会了什么?为什么这实际上没有调用 UB,而是在标准下明确定义?
  • 如果它确实调用了 UB,为什么这个行为最初包含在 OpenSSL 中?

最佳答案

Debian 的“修复”是 completely incorrect . ssleay_rand_add唯一 向池中添加熵的函数。真正的罪魁祸首是在调用 的位置,它应该在那里被修复——因为函数本身 没有任何问题。

基本上是这样的:

void add_entropy(void *buf, size_t length) {
    actually_add_entropy(buf, length);
}

int main(void) {
    char buf[256];

    // uninitialized local variable
    add_entropy(buf, length);

    // calculate more entropy to buf
    // ...
    add_entropy(buf, length);
}

如果您查看代码,问题在于第一次调用中传入的参数才是真正的罪魁祸首,第二种情况没问题,因为 buf 现在已初始化。正确的修复方法是“修复”add_entropy,如下所示:

void add_entropy(void *buf, size_t length) {
    // valgrind complains about buf being uninitialized so
    // actually_add_entropy(buf, length);
}

然而,他们正确尝试删除未初始化数组的使用 - 除了 UB 和 USB,它可能一直在掩盖代码中的严重问题 - 很可能是熵从未初始化的数据中初始化,因此可能仍然是可猜测或可控制的——但只是这一次更难注意到。

关于c - 为什么未初始化的内存可以安全地用于 OpenSSL 的随机数生成器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45395435/

相关文章:

Python 请求和 OpenSSL - 超过 HTTPSConnectionPool 最大重试次数

c++ - 与 boost::asio 和 OpenSSL 的客户端服务器通信中的证书验证失败

c - 为什么这些构造使用增量前和增量后未定义的行为?

c - 使用 libharu 库对 pdf 进行编码

c++ - 如何强制 avcodec 使用未对齐的帧数据平面?

c - 跳过 getchar 和 scanf 的麻烦

c - 释放分配给 char* (由 `malloc` 分配)的 int* 是否会调用未定义的行为?

c - Strsep 在我的 Mac OS X x86_64 系统上返回 32 位指针

openssl - 如何创建自己的扩展验证证书以显示绿色条?

c++ - 是否使用无效指针未定义行为初始化指针声明符?