我正在尝试使用这段代码,代码摘自英特尔白皮书,如下所示。我的目标是使用AES-NI执行256位块加密.我使用该方法成功地导出了密钥调度,该方法是在Intel AES-NI库中提供的,用于扩展密钥:iEncExpandKey256(key,expandedKey);和expandedKey在我的非AES-NI实现中工作得很好。
但是,当我将值传递到Rijndael256_encrypt(testVector,testResult,expandedKey,32,1) ;时,我会得到一个错误:“试图访问受保护的内存,这通常表示内存已损坏”,导致此情况的代码行为data1 = _mm_xor_si128(data1, KS[0]); /* round 0 (initial xor) */,如下所示。
所以我的问题是,这种错误的可能错误是什么?我目前的假设是,data1和KS可能大小不同,我目前仍在验证。除此之外,我不太确定我还能去哪里看。如果有人能为我指出正确的方向来排除这个错误,我们将不胜感激。
#include <wmmintrin.h>
#include <emmintrin.h>
#include <smmintrin.h>
void Rijndael256_encrypt (unsigned char *in,
unsigned char *out,
unsigned char *Key_Schedule,
unsigned long long length,
int number_of_rounds)
{
__m128i tmp1, tmp2, data1 ,data2;
__m128i RIJNDAEL256_MASK =
_mm_set_epi32(0x03020d0c, 0x0f0e0908, 0x0b0a0504, 0x07060100);
__m128i BLEND_MASK=
_mm_set_epi32(0x80000000, 0x80800000, 0x80800000, 0x80808000);
__m128i *KS = (__m128i*)Key_Schedule;
int i,j;
for(i=0; i < length/32; i++) { /* loop over the data blocks */
data1 = _mm_loadu_si128(&((__m128i*)in)[i*2+0]); /* load data block */
data2 = _mm_loadu_si128(&((__m128i*)in)[i*2+1]);
data1 = _mm_xor_si128(data1, KS[0]); /* round 0 (initial xor) */
data2 = _mm_xor_si128(data2, KS[1]);
/* Do number_of_rounds-1 AES rounds */
for(j=1; j < number_of_rounds; j++) {
/*Blend to compensate for the shift rows shifts bytes between two
128 bit blocks*/
tmp1 = _mm_blendv_epi8(data1, data2, BLEND_MASK);
tmp2 = _mm_blendv_epi8(data2, data1, BLEND_MASK);
/*Shuffle that compensates for the additional shift in rows 3 and 4
as opposed to rijndael128 (AES)*/
tmp1 = _mm_shuffle_epi8(tmp1, RIJNDAEL256_MASK);
tmp2 = _mm_shuffle_epi8(tmp2, RIJNDAEL256_MASK);
/*This is the encryption step that includes sub bytes, shift rows,
mix columns, xor with round key*/
data1 = _mm_aesenc_si128(tmp1, KS[j*2]);
data2 = _mm_aesenc_si128(tmp2, KS[j*2+1]);
}
tmp1 = _mm_blendv_epi8(data1, data2, BLEND_MASK);
tmp2 = _mm_blendv_epi8(data2, data1, BLEND_MASK);
tmp1 = _mm_shuffle_epi8(tmp1, RIJNDAEL256_MASK);
tmp2 = _mm_shuffle_epi8(tmp2, RIJNDAEL256_MASK);
tmp1 = _mm_aesenclast_si128(tmp1, KS[j*2+0]); /*last AES round */
tmp2 = _mm_aesenclast_si128(tmp2, KS[j*2+1]);
_mm_storeu_si128(&((__m128i*)out)[i*2+0],tmp1);
_mm_storeu_si128(&((__m128i*)out)[i*2+1],tmp2);
}
}发布于 2014-07-15 10:17:34
你有:
UCHAR* Key_Schedule=Key_schedule+4;这是不对齐的Key_Schedule,因为Key_schedule是(我希望!)对齐了,你增加了32位。
您要求CPU做一些硬件无法做的事情,因为数据线是连线的。这是一个严重的过度简化,但:您可以认为CPU有16个8位插槽,必须从它读取。为了读取数据,它发送一个地址,这个地址是字节地址除以16,然后决定从哪个时隙读取。如果组成128位地址的所有16个字节的字节地址除以16时不相同,那么就不可能将16个字节读入16个槽中。
如果不希望将对齐要求强加到函数的所有参数上,则需要将函数本身复制到对齐缓冲区中。
在加载和存储时,SSE操作需要对齐到16。-- AES本质
https://stackoverflow.com/questions/24754292
复制相似问题