为什么在OpenSSL的随机数生成器中使用未初始化的内存是安全的?

时间:2017-07-30 01:04:46

标签: c openssl undefined-behavior

所以,自从Debian维护者臭名昭着导致RNG种子被commenting out a usage of uninitialized data变得可预测以来,已经过去了11年。

这个问题引起了网络界的热烈讨论,其中大部分焦点似乎都在批评审核流程或攻击相关开发者。

但是,我一直无法找到有关该部门背后的实际思考过程的任何信息。许多用户认为“最坏的情况,它不会受到伤害” - 然而,这对我来说似乎完全违反直觉。

毕竟,从未初始化的内存中读取会调用未定义的行为,臭名昭着的行为会导致鼻子恶魔,运行nethack或格式化硬盘。因此,在我看来,将这种逻辑引入任何程序 - 更不用说加密库 - 可以让您在完全灾难中进行一次积极的编译器优化。

因此,我的问题:

  • 我误解了什么吗?有没有理由说这实际上没有调用UB,而是在标准下定义明确?
  • 如果确实调用了UB,为什么这种行为最初包含在OpenSSL中?

2 个答案:

答案 0 :(得分:2)

Debian“修复”是completely incorrectssleay_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除外,它可能已经掩盖了代码中的严重问题 - 它可能很好地说是熵从未初始化的数据初始化,因此可能仍然可猜测或可控制 - 但只是这一次难以注意到。

答案 1 :(得分:1)

它不是,而且刚刚发生(鼻子恶魔的一种表现)工作得很好。 Debian删除UB是正确的。开始使用OpenSSL是错误的。

相关问题