允许C++编译器优化写入内存:
{
//all this code can be eliminated
char buffer[size];
std::fill_n( buffer, size, 0);
}
Run Code Online (Sandbox Code Playgroud)
处理敏感数据时,典型方法是使用volatile*指针来确保编译器发出内存写入.以下是SecureZeroMemory()Visual C++运行时库中的函数实现方式(WinNT.h):
FORCEINLINE PVOID RtlSecureZeroMemory(
__in_bcount(cnt) PVOID ptr, __in SIZE_T cnt )
{
volatile char *vptr = (volatile char *)ptr;
#if defined(_M_AMD64)
__stosb((PBYTE )((DWORD64)vptr), 0, cnt);
#else
while (cnt) {
*vptr = 0;
vptr++;
cnt--;
}
#endif
return ptr;
}
Run Code Online (Sandbox Code Playgroud)
该函数将传递的指针强制转换为volatile*指针,然后通过后者写入.但是,如果我在局部变量上使用它:
char buffer[size];
SecureZeroMemory( buffer, size );
Run Code Online (Sandbox Code Playgroud)
变量本身不是volatile.因此根据C++标准定义的可观察行为写入buffer不计入可观察行为,看起来它可以被优化掉.
现在有很多关于页面文件,缓存等的评论都是有效的,但是我们在这个问题中忽略它们.这个问题唯一的问题是存储器写入的代码是否被优化掉了.
是否有可能确保在C++中没有优化写入内存的代码?该解决方案SecureZeroMemory()是否符合C++标准?
c++ compiler-construction optimization compiler-optimization
(注意:通过"常数时间",我的意思是当其中一个输入固定而不是O(1)时,机器周期数恒定.这是加密环境中术语的标准含义.)
将固定值与相同大小的未知值进行比较的最常见方法是,通过定时泄漏没有关于固定值的信息是使用XOR循环:
bool compare(const char* fixed, const char* unknown, size_t n)
{
char c = 0;
for (size_t i=0; i<n; ++i)
c |= fixed[i] ^ unknown[i];
return (c == 0);
}
Run Code Online (Sandbox Code Playgroud)
GCC 4.6.3和CLANG 3.0不会在AMD64上短路此循环,即使在-O3(我检查了生成的机器代码).但是,我不知道C标准中的任何内容会阻止某些聪明的编译器识别出如果c非零,那么该函数只能返回false.
如果你愿意接受大的性能损失和概率比较而不是确定性的比较,那么实现恒定时间比较的更偏执方式是计算两个输入的加密哈希值并比较哈希值; 如何对哈希进行比较并不重要,因为除非攻击者能够计算哈希的前映像,否则它不能进行未知值的连续近似.很难想象编译器有足够的智能来优化它,但我无法保证它不会发生.更偏执的方法是使用HMAC和特定于实例的键而不是简单的哈希,尽管我仍然可以想象一个奇迹般智能的优化器,它可以识别出无论使用什么键,它编译的算法只是一种缓慢的方式.进行字符串比较并相应地优化.通过添加额外的复杂层,调用共享库等,我可以使我的比较任意难以优化,但我仍然不能保证没有符合标准的编译器可以使我的比较短路并让我容易受到攻击定时攻击.
有没有办法实现有效的,确定性的,恒定时间的比较,保证始终按照C标准工作?如果没有,任何流行的C(或C++)编译器或库是否提供这样的方法?请引用你的消息来源.
memcmp C实现 - 这个有任何逻辑错误吗?
我正在寻找memcmp()的实现,我找到了这段代码片段,但它清楚地标明代码片段有1个逻辑错误.你能帮我找到逻辑错误吗?
基本上,我使用不同的输入对memcmp()的string.h库实现测试了此代码,但预期的输出始终与函数的库版本相同.
这是代码片段:
#include <stdio.h>
#include <string.h>
int memcmp_test(const char *cs, const char *ct, size_t n)
{
size_t i;
for (i = 0; i < n; i++, cs++, ct++)
{
if (*cs < *ct)
{
return -1;
}
else if (*cs > *ct)
{
return 1;
}
else
{
return 0;
}
}
}
int main()
{
int ret_val = 20; //initialize with non-zero value
char *string1 = "china";
char *string2 = "korea";
ret_val = memcmp_test(string1,string2,5); …Run Code Online (Sandbox Code Playgroud)