C++ C++;AES-NI解密256位块

C++ C++;AES-NI解密256位块,c++,cryptography,aes,aes-ni,C++,Cryptography,Aes,Aes Ni,这就是我的问题。。我正在为一个库编写一个AES-NI实现,我被256位块的解密困住了。这是我所知道的。。128位块工作正常。256块的加密与经验证的Rijndael实现一致。扩展键还与其他Rijndael实现对齐(允许小尾端字节顺序)。 该例程使用混合和移位掩码来补偿256位块的偏移列混洗,它与用于加密该块的掩码相反,这也经过测试,似乎工作正常。 下面是加密函数: void Encrypt32(const std::vector<byte> &Input, const

这就是我的问题。。我正在为一个库编写一个AES-NI实现,我被256位块的解密困住了。这是我所知道的。。128位块工作正常。256块的加密与经验证的Rijndael实现一致。扩展键还与其他Rijndael实现对齐(允许小尾端字节顺序)。 该例程使用混合和移位掩码来补偿256位块的偏移列混洗,它与用于加密该块的掩码相反,这也经过测试,似乎工作正常。 下面是加密函数:

    void Encrypt32(const std::vector<byte> &Input, const size_t InOffset, std::vector<byte> &Output, const size_t OutOffset)
{
    const size_t LRD = m_expKey.size() - 3;
    size_t keyCtr = 0;
    __m128i RIJNDAEL256_MASK = { 0,1,6,7,4,5,10,11,8,9,14,15,12,13,2,3 };
    __m128i BLEND_MASK = _mm_set_epi32(0x80000000, 0x80800000, 0x80800000, 0x80808000);
    __m128i block1 = _mm_loadu_si128((const __m128i*)(const void*)&Input[InOffset]);
    __m128i block2 = _mm_loadu_si128((const __m128i*)(const void*)&Input[InOffset + 16]);
    __m128i temp1, temp2;

    block1 = _mm_xor_si128(block1, m_expKey[keyCtr]);
    block2 = _mm_xor_si128(block2, m_expKey[++keyCtr]);

    while (keyCtr != LRD)
    {
        temp1 = _mm_blendv_epi8(block1, block2, BLEND_MASK);    // combine 2 blocks
        temp2 = _mm_blendv_epi8(block2, block1, BLEND_MASK);
        temp1 = _mm_shuffle_epi8(temp1, RIJNDAEL256_MASK);      // shuffle
        temp2 = _mm_shuffle_epi8(temp2, RIJNDAEL256_MASK);
        block1 = _mm_aesenc_si128(temp1, m_expKey[++keyCtr]);   // encrypt
        block2 = _mm_aesenc_si128(temp2, m_expKey[++keyCtr]);
    }

    temp1 = _mm_blendv_epi8(block1, block2, BLEND_MASK);
    temp2 = _mm_blendv_epi8(block2, block1, BLEND_MASK);
    temp1 = _mm_shuffle_epi8(temp1, RIJNDAEL256_MASK);
    temp2 = _mm_shuffle_epi8(temp2, RIJNDAEL256_MASK);
    block1 = _mm_aesenclast_si128(temp1, m_expKey[++keyCtr]);
    block2 = _mm_aesenclast_si128(temp2, m_expKey[++keyCtr]);

    _mm_storeu_si128((__m128i*)(void*)&Output[OutOffset], block1);
    _mm_storeu_si128((__m128i*)(void*)&Output[OutOffset + 16], block2);
}
void Encrypt32(常量std::vector&Input、常量size\u t InOffset、std::vector&Output、常量size\u t OutOffset)
{
const size\u t LRD=m\u expKey.size()-3;
尺寸\u t键中心=0;
__m128i RIJNDAEL256_掩码={0,1,6,7,4,5,10,11,8,9,14,15,12,13,2,3};
__m128i混合_掩码=_mm_集_epi32(0x8000000、0x80800000、0x80800000、0x808000);
__m128i块1=_mm_loadu_si128((常量m128i*)(常量void*)和输入[InOffset]);
__m128i块2=_mm_loadu_si128((常量m128i*)(常量void*)和输入[InOffset+16]);
__m128i temp1、temp2;
block1=_-mm_-xor_-si128(block1,m_-expKey[keyCtr]);
block2=_mm_xor_si128(block2,m_expKey[++keyCtr]);
while(keyCtr!=LRD)
{
temp1=_mm_blendv_epi8(块1、块2、混合_掩码);//组合2个块
temp2=_mm_blendv_epi8(块2,块1,混合膜);
temp1=_mm_shuffle_epi8(temp1,RIJNDAEL256_MASK);//shuffle
temp2=_mm_shuffle_epi8(temp2,RIJNDAEL256_掩码);
block1=_mm_aesenc_si128(temp1,m_expKey[++keyCtr]);//加密
block2=_mm_aesenc_si128(temp2,m_expKey[++keyCtr]);
}
temp1=_mm_blendv_epi8(块1、块2、混合膜);
temp2=_mm_blendv_epi8(块2,块1,混合膜);
temp1=_mm_shuffle_epi8(temp1,RIJNDAEL256_掩码);
temp2=_mm_shuffle_epi8(temp2,RIJNDAEL256_掩码);
块1=_mm_aesenclast_si128(temp1,m_expKey[++keyCtr]);
block2=_mm_aesenclast_si128(temp2,m_expKey[++keyCtr]);
_mm_storeu_si128((__m128i*)(void*)和输出[OutOffset],block1);
_mm_storeu_si128((__m128i*)(void*)和输出[OutOffset+16],块2);
}
这是逆变换:

    void Decrypt32(const std::vector<byte> &Input, const size_t InOffset, std::vector<byte> &Output, const size_t OutOffset)
{
    const size_t LRD = m_expKey.size() - 3;
    __m128i RIJNDAELINV_MASK = { 0,1,14,15,4,5,2,3,8,9,6,7,12,13,10,11 };
    __m128i BLEND_MASK = _mm_set_epi32(0x80000000, 0x80800000, 0x80800000, 0x80808000);
    __m128i block1 = _mm_loadu_si128((const __m128i*)(const void*)&Input[InOffset]);
    __m128i block2 = _mm_loadu_si128((const __m128i*)(const void*)&Input[InOffset + 16]);
    __m128i temp1, temp2;
    size_t keyCtr = 0;

    block1 = _mm_xor_si128(block1, m_expKey[keyCtr]);
    block2 = _mm_xor_si128(block2, m_expKey[++keyCtr]);

    while (keyCtr != LRD)
    {
        temp1 = _mm_aesdec_si128(block1, m_expKey[++keyCtr]);   // decrypt
        temp2 = _mm_aesdec_si128(block2, m_expKey[++keyCtr]);
        temp1 = _mm_shuffle_epi8(temp1, RIJNDAELINV_MASK);      // shuffle
        temp2 = _mm_shuffle_epi8(temp2, RIJNDAELINV_MASK);
        block1 = _mm_blendv_epi8(temp1, temp2, BLEND_MASK);     // combine
        block2 = _mm_blendv_epi8(temp2, temp1, BLEND_MASK);
    }

    temp1 = _mm_aesdeclast_si128(block1, m_expKey[++keyCtr]);
    temp2 = _mm_aesdeclast_si128(block2, m_expKey[++keyCtr]);
    temp1 = _mm_shuffle_epi8(temp1, RIJNDAELINV_MASK);
    temp2 = _mm_shuffle_epi8(temp2, RIJNDAELINV_MASK);
    block1 = _mm_blendv_epi8(temp1, temp2, BLEND_MASK);
    block2 = _mm_blendv_epi8(temp2, temp1, BLEND_MASK);

    _mm_storeu_si128((__m128i*)(void*)&Output[OutOffset], block1);
    _mm_storeu_si128((__m128i*)(void*)&Output[OutOffset + 16], block2);
}
void Decrypt32(常量std::vector&Input、常量size\u t InOffset、std::vector&Output、常量size\u t OutOffset)
{
const size\u t LRD=m\u expKey.size()-3;
__m128i RIJNDAELINV_面具={0,1,14,15,4,5,2,3,8,9,6,7,12,13,10,11};
__m128i混合_掩码=_mm_集_epi32(0x8000000、0x80800000、0x80800000、0x808000);
__m128i块1=_mm_loadu_si128((常量m128i*)(常量void*)和输入[InOffset]);
__m128i块2=_mm_loadu_si128((常量m128i*)(常量void*)和输入[InOffset+16]);
__m128i temp1、temp2;
尺寸\u t键中心=0;
block1=_-mm_-xor_-si128(block1,m_-expKey[keyCtr]);
block2=_mm_xor_si128(block2,m_expKey[++keyCtr]);
while(keyCtr!=LRD)
{
temp1=_mm_aesdec_si128(block1,m_expKey[++keyCtr]);//解密
temp2=_mm_aesdec_si128(块2,m_expKey[++keyCtr]);
temp1=_mm_shuffle_epi8(temp1,RIJNDAELINV_MASK);//shuffle
temp2=_mm_shuffle_epi8(temp2,RIJNDAELINV_面具);
block1=_-mm_-blendv_-epi8(temp1、temp2、BLEND_-MASK);//组合
block2=_-mm_-blendv_-epi8(temp2,temp1,BLEND_-MASK);
}
temp1=_mm_aesdeclast_si128(块1,m_expKey[++keyCtr]);
temp2=_mm_aesdeclast_si128(块2,m_expKey[++keyCtr]);
temp1=_mm_shuffle_epi8(temp1,RIJNDAELINV_面具);
temp2=_mm_shuffle_epi8(temp2,RIJNDAELINV_面具);
block1=_-mm_-blendv_-epi8(temp1、temp2、BLEND_-MASK);
block2=_-mm_-blendv_-epi8(temp2,temp1,BLEND_-MASK);
_mm_storeu_si128((__m128i*)(void*)和输出[OutOffset],block1);
_mm_storeu_si128((__m128i*)(void*)和输出[OutOffset+16],块2);
}

我已经调试了好几个小时了,只是没能发现问题,有人能理解为什么这不起作用吗?如果有帮助,我可以将代码发布到git。

AES只有一个块大小:128位。Rijndael支持其他块大小,如256位,但请注意,对较大的块大小进行的检查要少得多,而且它们可能更不安全。@zaph-安全性降低的原因是较宽的块从同一固定输入密钥生成的圆密钥是原来的两倍,但这不是这个代码的问题。我投票赞成这个问题,因为它是一个确定的问题。但是,结合安全操作模式的分组密码应该足以加密256位的块。我不完全明白改用Rijndael-256的意义(再说一遍,使用256位分组密码是有原因的,所以没问题)。这里最好的办法是调试或打印中间值,并将它们与已经执行Rijndael-256的实现进行比较。@Maarten-我已经放弃了256。。我以后再看(沮丧)。不过,这种方法的问题在于,Intel NI是LE,Rijndael是BE,因此您必须转置每轮输出,或者将Rijndael写入LE以进行比较(最佳选择)。AES只有一个块大小:128位。Rijndael支持其他块大小,如256位,但请注意,对较大的块大小进行的检查要少得多,而且它们可能更不安全。@zaph-安全性降低的原因是较宽的块从同一固定输入密钥生成的圆密钥是原来的两倍,但这不是这个代码的问题。我投票赞成这个问题,因为它是一个确定的问题。但是,结合安全操作模式的分组密码应该足以加密256位的块。我不完全明白改用Rijndael-256的意义(再说一遍,使用256位分组密码是有原因的,所以没问题)。这里最好的办法是调试或打印中间值,并将它们与已经执行Rijndael-256的实现进行比较。@Maarten-我已经放弃了256。。稍后我将重新访问它(fru)