Использование _mm_aeskeygenassist_si128 для сопоставления эталонных значений - PullRequest
0 голосов
/ 09 мая 2018

Я пытаюсь заставить EAX работать, используя Intel SI. Использование бумаги на https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.197.pdf, У меня есть клавиша ввода:

Cipher Key = 2b 7e 15 16 28 ae d2 a6 ab f7 15 88 09 cf 4f 3c

И я пытаюсь сопоставить второй расширенный ключ, который выглядит следующим образом:

rk[1] = A0 FA FE 17 88 54 2C B1 23 A3 39 39 2A 6C 76 05

Я получил различные фрагменты с использованием встроенных функций Intel из Интернета, например: https://www.thesalmons.org/john/random123/releases/1.09/docs/aes_8h_source.html. Все они сходятся по разному значению:

rk[1] = C0 7F 9F 93 E8 D1 4D 35 43 26 58 BD 4A E9 17 81

Вот пример кода, который я использую:

#include <wmmintrin.h>
#include <emmintrin.h>
#include <smmintrin.h>

void dump(const char *banner, __m128i v) {
    printf("%s: ", banner);
    uint16_t *v64val = (uint16_t*) &v;
    for (int i =0; i < 4; ++i) {
        printf("%02X\n", *(v64val+i*2+1));
        printf("%02X\n", *(v64val+i*2));
    }
}

__m128i AES_128_ASSIST (__m128i temp1, __m128i temp2) { 
    __m128i temp3; 
    temp2 = _mm_shuffle_epi32 (temp2 ,0xff); 
    temp3 = _mm_slli_si128 (temp1, 0x4);
    temp1 = _mm_xor_si128 (temp1, temp3);
    temp3 = _mm_slli_si128 (temp3, 0x4);
    temp1 = _mm_xor_si128 (temp1, temp3);
    temp3 = _mm_slli_si128 (temp3, 0x4);
    temp1 = _mm_xor_si128 (temp1, temp3);
    temp1 = _mm_xor_si128 (temp1, temp2); 
    return temp1; 
}

void AES_key_expansion_raw(uint32_t key[], __m128i *ret) {
    __m128i rkey, tmp2;
    ret[0] = rkey = _mm_loadu_si128((__m128i*)key);

    tmp2 = _mm_aeskeygenassist_si128(rkey, 0x1);
    rkey = AES_128_ASSIST(rkey, tmp2);
    ret[1] = rkey;

    tmp2 = _mm_aeskeygenassist_si128(rkey, 0x2);
    rkey = AES_128_ASSIST(rkey, tmp2);
    ret[2] = rkey;

    tmp2 = _mm_aeskeygenassist_si128(rkey, 0x4);
    rkey = AES_128_ASSIST(rkey, tmp2);
    ret[3] = rkey;

    tmp2 = _mm_aeskeygenassist_si128(rkey, 0x8);
    rkey = AES_128_ASSIST(rkey, tmp2);
    ret[4] = rkey;

    tmp2 = _mm_aeskeygenassist_si128(rkey, 0x10);
    rkey = AES_128_ASSIST(rkey, tmp2);
    ret[5] = rkey;

    tmp2 = _mm_aeskeygenassist_si128(rkey, 0x20);
    rkey = AES_128_ASSIST(rkey, tmp2);
    ret[6] = rkey;

    tmp2 = _mm_aeskeygenassist_si128(rkey, 0x40);
    rkey = AES_128_ASSIST(rkey, tmp2);
    ret[7] = rkey;

    tmp2 = _mm_aeskeygenassist_si128(rkey, 0x80);
    rkey = AES_128_ASSIST(rkey, tmp2);
    ret[8] = rkey;

    tmp2 = _mm_aeskeygenassist_si128(rkey, 0x1b);
    rkey = AES_128_ASSIST(rkey, tmp2);
    ret[9] = rkey;

    tmp2 = _mm_aeskeygenassist_si128(rkey, 0x36);
    rkey = AES_128_ASSIST(rkey, tmp2);
    ret[10] = rkey;
}

int main() {
    printf("INTEL:\n");
    __m128i rdkeys[11];
    uint32_t key[] = {0x2b7e1516, 0x28aed2a6, 0xabf71588, 0x09cf4f3c};
    AES_key_expansion_raw(key, rdkeys);
    for (int i = 0; i < 11; ++i) {
        dump("RK", rdkeys[i]);
    }


    return 0;
}

Я не совсем понял из чтения документов для _mm_aeskeygenassist_si128, как я должен использовать его для генерации круглых ключей, и я еще больше запутался с различными реализациями, которые, как мне кажется, генерируют круглые ключи, которые не не соответствует спецификации AES.

Есть идеи о том, как примирить? Спасибо!

...