为什么大多数 c 编译器没有优化此归零代码?
Why isn't this zeroization code optimized out by most c compilers?
许多加密库包含类似于以下代码段的代码:
/* Implementation that should never be optimized out by the compiler */
static void optimize_proof_zeroize( void *v, size_t n )
{
volatile unsigned char *p = v;
while( n-- ) *p++ = 0;
}
但我天真的实现无法通过优化编译器:
/* Naive zeroization implementation */
static void naive_zeroize( unsigned char *c, size_t n)
{
int i;
for( i = 0; i < n; i++ )
c[i] = 0;
}
该代码用于在释放内存之前将敏感数据归零。由于不再使用缓冲区,优化编译器假设他们可以安全地从编译代码中删除 zeriozation。
是什么阻止了第一个实现被优化掉?
这里的key字是volatile。当一个变量被声明为 volatile
时,它告诉编译器这个变量可以在该程序之外 modified/accessed(例如通过硬件),因此它强制编译器不优化该变量并访问内存引用该变量的时间。
它在加密中的用法通常是从堆栈(局部变量)中清除秘密(密钥)。由于堆栈用于局部变量,常规代码(如 /* Naive zeroization implementation */
中的代码)似乎对程序的其他 variables/state 没有任何影响,因此编译器可能(并且可能会) ) 优化该代码。为了防止它,使用 volatile
限定符使编译器保留该代码并将局部变量的内存内容归零。
编辑
示例:
void decrypt(void* src, void* dest, crypto_stuff_t* params)
{
crypto_key_t decryption_key; // will hold the decryption key
....
....
// end of flow
// we want to zero the content of decryption_key, otherwise its value
// will remain on the stack
// this:
// decryption_key <-- 0;
// will be just optimized out by the compiler
// but this won't:
volatile uint8_t* key_ptr = (uint8_t*)&decryption_key;
int i;
for(i = 0; i < sizeof(crypto_key_t); i++)
key_ptr[i] = 0;
}
许多加密库包含类似于以下代码段的代码:
/* Implementation that should never be optimized out by the compiler */
static void optimize_proof_zeroize( void *v, size_t n )
{
volatile unsigned char *p = v;
while( n-- ) *p++ = 0;
}
但我天真的实现无法通过优化编译器:
/* Naive zeroization implementation */
static void naive_zeroize( unsigned char *c, size_t n)
{
int i;
for( i = 0; i < n; i++ )
c[i] = 0;
}
该代码用于在释放内存之前将敏感数据归零。由于不再使用缓冲区,优化编译器假设他们可以安全地从编译代码中删除 zeriozation。
是什么阻止了第一个实现被优化掉?
这里的key字是volatile。当一个变量被声明为 volatile
时,它告诉编译器这个变量可以在该程序之外 modified/accessed(例如通过硬件),因此它强制编译器不优化该变量并访问内存引用该变量的时间。
它在加密中的用法通常是从堆栈(局部变量)中清除秘密(密钥)。由于堆栈用于局部变量,常规代码(如 /* Naive zeroization implementation */
中的代码)似乎对程序的其他 variables/state 没有任何影响,因此编译器可能(并且可能会) ) 优化该代码。为了防止它,使用 volatile
限定符使编译器保留该代码并将局部变量的内存内容归零。
编辑
示例:
void decrypt(void* src, void* dest, crypto_stuff_t* params)
{
crypto_key_t decryption_key; // will hold the decryption key
....
....
// end of flow
// we want to zero the content of decryption_key, otherwise its value
// will remain on the stack
// this:
// decryption_key <-- 0;
// will be just optimized out by the compiler
// but this won't:
volatile uint8_t* key_ptr = (uint8_t*)&decryption_key;
int i;
for(i = 0; i < sizeof(crypto_key_t); i++)
key_ptr[i] = 0;
}