为何libsodium的sodium_is_zero函数使用volatile关键字?
关于libsodium中sodium_is_zero函数里volatile关键字的作用
先看libsodium库中sodium_is_zero函数的实现:
int sodium_is_zero(const unsigned char *n, const size_t nlen) { size_t i; volatile unsigned char d = 0U; for (i = 0U; i < nlen; i++) { d |= n[i]; } return 1 & ((d - 1) >> 8); }
为什么要给变量d加上volatile关键字?
这个函数的核心是安全判断内存区域是否全为0,而密码学场景下必须杜绝侧信道攻击的可能,volatile的作用正是为了防止编译器优化引入时序泄露:
没有
volatile时,编译器会做「短路优化」:一旦检测到某个n[i]不为0,就会提前终止循环,直接得出“非全零”的结论。这种优化会让函数的执行时间和输入强相关——全零输入会跑完整个循环,非全零输入会提前结束,攻击者可以通过测量执行时间的差异,推断出输入是否全零,这就是典型的时序侧信道泄露。加上
volatile后,编译器会认为变量d的值可能被外部因素意外修改(即使实际不会),因此必须严格按照代码语义执行每一次循环中的d |= n[i]操作,不能提前退出循环,也不能跳过任何一次内存读取。这样不管输入是否全零,函数都会执行完整个循环,执行时间基本一致,彻底消除了时序差异带来的泄露风险。
内容的提问来源于stack exchange,提问作者Ryan Burn
相关产品推荐
相关产品推荐

