C 具有192位和256位密钥的AES-NI内部函数

C 具有192位和256位密钥的AES-NI内部函数,c,aes,intrinsics,C,Aes,Intrinsics,我最近在堆栈溢出上发现了一个代码,它使用wmmintrin.h,以便使用AES-ECB/AES-CBC/AES加密数据块,不管是什么,都使用128位密钥 代码(如下所示)工作得非常好,但它只使用128位密钥,我非常希望它能够使用192位密钥和256位密钥 有没有办法用相同的代码运行192位和256位加密?比如增加一些回合?因为我知道128位密钥需要10轮加密,192位密钥需要12轮加密,256位密钥需要14轮加密,但我不确定我自己能不能实现这一点,所以如果你能帮我 以下是我找到的代码: #ifn

我最近在堆栈溢出上发现了一个代码,它使用wmmintrin.h,以便使用AES-ECB/AES-CBC/AES加密数据块,不管是什么,都使用128位密钥

代码(如下所示)工作得非常好,但它只使用128位密钥,我非常希望它能够使用192位密钥和256位密钥

有没有办法用相同的代码运行192位和256位加密?比如增加一些回合?因为我知道128位密钥需要10轮加密,192位密钥需要12轮加密,256位密钥需要14轮加密,但我不确定我自己能不能实现这一点,所以如果你能帮我

以下是我找到的代码:

#ifndef __AES_NI_H__
#define __AES_NI_H__

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>     //for int8_t
#include <string.h>     //for memcmp
#include <wmmintrin.h>  //for intrinsics for AES-NI
//compile using gcc and following arguments: -g;-O0;-Wall;-msse2;-msse;-march=native;-maes

//internal stuff

//macros
#define DO_ENC_BLOCK(m,k) \
    do{\
        m = _mm_xor_si128       (m, k[ 0]); \
        m = _mm_aesenc_si128    (m, k[ 1]); \
        m = _mm_aesenc_si128    (m, k[ 2]); \
        m = _mm_aesenc_si128    (m, k[ 3]); \
        m = _mm_aesenc_si128    (m, k[ 4]); \
        m = _mm_aesenc_si128    (m, k[ 5]); \
        m = _mm_aesenc_si128    (m, k[ 6]); \
        m = _mm_aesenc_si128    (m, k[ 7]); \
        m = _mm_aesenc_si128    (m, k[ 8]); \
        m = _mm_aesenc_si128    (m, k[ 9]); \
        m = _mm_aesenclast_si128(m, k[10]);\
    }while(0)

#define DO_DEC_BLOCK(m,k) \
    do{\
        m = _mm_xor_si128       (m, k[10+0]); \
        m = _mm_aesdec_si128    (m, k[10+1]); \
        m = _mm_aesdec_si128    (m, k[10+2]); \
        m = _mm_aesdec_si128    (m, k[10+3]); \
        m = _mm_aesdec_si128    (m, k[10+4]); \
        m = _mm_aesdec_si128    (m, k[10+5]); \
        m = _mm_aesdec_si128    (m, k[10+6]); \
        m = _mm_aesdec_si128    (m, k[10+7]); \
        m = _mm_aesdec_si128    (m, k[10+8]); \
        m = _mm_aesdec_si128    (m, k[10+9]); \
        m = _mm_aesdeclast_si128(m, k[0]);\
    }while(0)

#define AES_128_key_exp(k, rcon) aes_128_key_expansion(k, _mm_aeskeygenassist_si128(k, rcon))

static __m128i aes_128_key_expansion(__m128i key, __m128i keygened) {
    keygened = _mm_shuffle_epi32(keygened, _MM_SHUFFLE(3, 3, 3, 3));
    key = _mm_xor_si128(key, _mm_slli_si128(key, 4));
    key = _mm_xor_si128(key, _mm_slli_si128(key, 4));
    key = _mm_xor_si128(key, _mm_slli_si128(key, 4));
    return _mm_xor_si128(key, keygened);
}

//public API
static void aes128_load_key_enc_only(uint8_t *enc_key, __m128i *key_schedule) {
    key_schedule[0] = _mm_loadu_si128((const __m128i*) enc_key);
    key_schedule[1] = AES_128_key_exp(key_schedule[0], 0x01);
    key_schedule[2] = AES_128_key_exp(key_schedule[1], 0x02);
    key_schedule[3] = AES_128_key_exp(key_schedule[2], 0x04);
    key_schedule[4] = AES_128_key_exp(key_schedule[3], 0x08);
    key_schedule[5] = AES_128_key_exp(key_schedule[4], 0x10);
    key_schedule[6] = AES_128_key_exp(key_schedule[5], 0x20);
    key_schedule[7] = AES_128_key_exp(key_schedule[6], 0x40);
    key_schedule[8] = AES_128_key_exp(key_schedule[7], 0x80);
    key_schedule[9] = AES_128_key_exp(key_schedule[8], 0x1B);
    key_schedule[10] = AES_128_key_exp(key_schedule[9], 0x36);
}

static void aes128_load_key(uint8_t *enc_key, __m128i *key_schedule) {
    aes128_load_key_enc_only(enc_key, key_schedule);

    // generate decryption keys in reverse order.
    // k[10] is shared by last encryption and first decryption rounds
    // k[0] is shared by first encryption round and last decryption round (and is the original user key)
    // For some implementation reasons, decryption key schedule is NOT the encryption key schedule in reverse order
    key_schedule[11] = _mm_aesimc_si128(key_schedule[9]);
    key_schedule[12] = _mm_aesimc_si128(key_schedule[8]);
    key_schedule[13] = _mm_aesimc_si128(key_schedule[7]);
    key_schedule[14] = _mm_aesimc_si128(key_schedule[6]);
    key_schedule[15] = _mm_aesimc_si128(key_schedule[5]);
    key_schedule[16] = _mm_aesimc_si128(key_schedule[4]);
    key_schedule[17] = _mm_aesimc_si128(key_schedule[3]);
    key_schedule[18] = _mm_aesimc_si128(key_schedule[2]);
    key_schedule[19] = _mm_aesimc_si128(key_schedule[1]);
}

static void aes128_enc(__m128i *key_schedule, uint8_t *plainText, uint8_t *cipherText) {
    __m128i m = _mm_loadu_si128((__m128i *) plainText);

    DO_ENC_BLOCK(m, key_schedule);

    _mm_storeu_si128((__m128i *) cipherText, m);
}

static void aes128_dec(__m128i *key_schedule, uint8_t *cipherText, uint8_t *plainText) {
    __m128i m = _mm_loadu_si128((__m128i *) cipherText);

    DO_DEC_BLOCK(m, key_schedule);

    _mm_storeu_si128((__m128i *) plainText, m);
}

//return 0 if no error
//1 if encryption failed
//2 if decryption failed
//3 if both failed
static int aes128_self_test(void) {
    uint8_t plain[] = { 0x32, 0x43, 0xf6, 0xa8, 0x88, 0x5a, 0x30, 0x8d, 0x31, 0x31, 0x98, 0xa2, 0xe0, 0x37, 0x07, 0x34 };
    uint8_t enc_key[] = { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c };
    uint8_t cipher[] = { 0x39, 0x25, 0x84, 0x1d, 0x02, 0xdc, 0x09, 0xfb, 0xdc, 0x11, 0x85, 0x97, 0x19, 0x6a, 0x0b, 0x32 };
    uint8_t computed_cipher[16];
    uint8_t computed_plain[16];
    int out = 0;
    __m128i key_schedule[20];
    aes128_load_key(enc_key, key_schedule);
    aes128_enc(key_schedule, plain, computed_cipher);
    aes128_dec(key_schedule, cipher, computed_plain);
    if (memcmp(cipher, computed_cipher, sizeof(cipher))) out = 1;
    if (memcmp(plain, computed_plain, sizeof(plain))) out |= 2;
    return out;
}
#endif

int main()
{
    uint8_t input[16]; memset(input, 0, 16); input[0] = 'A';
    uint8_t output[16];
    uint8_t keyText[16] = "This is my key.";

    __m128i key[20];

    aes128_load_key(keyText, key);
    aes128_enc(key, input, output);

    for (unsigned int i = 0; i < 16; i++)
        printf("%02X", output[i]);

    getchar();
    return 0;
}
\ifndef\uu AES\u NI\H__
#定义__
#包括
#包括
#包含//用于int8\t
#包括//用于memcmp
#包含//用于AES-NI的本质
//使用gcc和以下参数编译:-g-O0-墙-msse2-msse-三月=本地人-梅斯
//内部材料
//宏
#定义DO_ENC_块(m,k)\
做{\
m=_-mm_-xor_-si128(m,k[0])\
m=_-mm_-aesenc_-si128(m,k[1])\
m=_-mm_-aesenc_-si128(m,k[2])\
m=_-mm_-aesenc_-si128(m,k[3])\
m=_-mm_-aesenc_-si128(m,k[4])\
m=_-mm_-aesenc_-si128(m,k[5])\
m=_-mm_-aesenc_-si128(m,k[6])\
m=_-mm_-aesenc_-si128(m,k[7])\
m=_-mm_-aesenc_-si128(m,k[8])\
m=_-mm_-aesenc_-si128(m,k[9])\
m=_-mm_-aesenclast_-si128(m,k[10])\
}而(0)
#定义DO_DEC_块(m,k)\
做{\
m=_-mm_-xor_-si128(m,k[10+0])\
m=_mm_aesdec_si128(m,k[10+1])\
m=_mm_aesdec_si128(m,k[10+2])\
m=_-mm_-aesdec_-si128(m,k[10+3])\
m=_mm_aesdec_si128(m,k[10+4])\
m=_-mm_-aesdec_-si128(m,k[10+5])\
m=_mm_aesdec_si128(m,k[10+6])\
m=_mm_aesdec_si128(m,k[10+7])\
m=_-mm_-aesdec_-si128(m,k[10+8])\
m=_-mm_-aesdec_-si128(m,k[10+9])\
m=_-mm_-aesdeclast_-si128(m,k[0])\
}而(0)
#定义AES_128_key_exp(k,rcon)AES_128_key_扩展(k,mm_aeskeygenassist_si128(k,rcon))
静态uu m128i aes u 128 u密钥扩展(uu m128i密钥,uu m128i密钥生成){
keygened=_-mm_-shuffle_-epi32(keygened,_-mm_-shuffle(3,3,3,3));
key=_-mm_-xor_-si128(key,_-mm_-slli_-si128(key,4));
key=_-mm_-xor_-si128(key,_-mm_-slli_-si128(key,4));
key=_-mm_-xor_-si128(key,_-mm_-slli_-si128(key,4));
返回_mm_xor_si128(key,keygened);
}
//公共API
静态无效aes128仅加载密钥加密(uint8密钥加密,m128i密钥调度){
密钥计划[0]=_mm_loadu_si128((const u m128i*)加密密钥;
密钥调度[1]=AES密钥128密钥exp(密钥调度[0],0x01);
密钥调度[2]=AES密钥调度[1],0x02;
密钥调度[3]=AES密钥128密钥exp(密钥调度[2],0x04);
密钥调度[4]=AES密钥128密钥exp(密钥调度[3],0x08);
密钥调度[5]=AES密钥128密钥exp(密钥调度[4],0x10);
密钥调度[6]=AES密钥128密钥exp(密钥调度[5],0x20);
密钥调度[7]=AES密钥128密钥exp(密钥调度[6],0x40);
密钥调度[8]=AES密钥128密钥exp(密钥调度[7],0x80);
密钥调度[9]=AES密钥128密钥exp(密钥调度[8],0x1B);
密钥调度[10]=AES密钥128密钥exp(密钥调度[9],0x36);
}
静态无效aes128_加载_键(uint8_t*enc_键,__m128i*键时间表){
aes128仅加载密钥加密(加密密钥、密钥调度);
//按相反顺序生成解密密钥。
//k[10]由最后一轮加密和第一轮解密共享
//k[0]由第一轮加密和最后一轮解密共享(并且是原始用户密钥)
//出于某些实现原因,解密密钥计划与加密密钥计划的顺序相反
关键时刻表[11]=关键时刻表[9];
关键时刻表[12]=关键时刻表[8];
关键时刻表[13]=关键时刻表[7];
关键时刻表[14]=关键时刻表[6];
关键时刻表[15]=关键时刻表[5];
关键时刻表[16]=关键时刻表[4];
关键时刻表[17]=关键时刻表[3];
关键时刻表[18]=关键时刻表[2];
关键时刻表[19]=关键时刻表[1];
}
静态无效aes128加密(\uuuuM128i*密钥\u计划,uint8\u t*明文,uint8\u t*密文){
__m128i m=_mm_loadu_si128((u m128i*)明文);
DO_ENC_BLOCK(m,关键时刻表);
_mm_storeu_si128((u m128i*)密文,m);
}
静态无效aes128 dec(uuuM128i*密钥计划,uint8\u t*密文,uint8\u t*明文){
__m128i m=_mm_loadu_si128((u m128i*)密文);
DO_DEC_区块(m,关键时刻表);
_mm_storeu_si128((_m128i*)明文,m);
}
//如果没有错误,则返回0
//1如果加密失败
//2如果解密失败
//3如果两者都失败
静态自测试(无效){
uint8_t plain[]={0x32、0x43、0xf6、0xa8、0x88、0x5a、0x30、0x8d、0x31、0x31、0x98、0xa2、0xe0、0x37、0x07、0x34};
uint8加密键[]={0x2b、0x7e、0x15、0x16、0x28、0xae、0xd2、0xa6、0xab、0xf7、0x15、0x88、0x09、0xcf、0x4f、0x3c};
uint8_t密码[]={0x39、0x25、0x84、0x1d、0x02、0xdc、0x09、0xfb、0xdc、0x11、0x85、0x97、0x19、0x6a、0x0b、0x32};
uint8_t计算密码[16];
uint8计算平面[16];
int out=0;
__m128i钥匙表[20];
aes128加载密钥(加密密钥、密钥调度);
aes128加密(密钥调度、普通、计算加密);
aes128 dec(密钥调度、密码、计算普通);
如果(memcmp(cipher,computed_cipher,sizeof(cipher)))out=1;
如果(memcmp(平原,计算的平原,平原的大小))out |=2;
返回;
}
#恩迪夫
int main()
{
uint8_t输入[16];memset(输入,0,16);输入[0]=“A”;
uint8_t输出[16];
uint8\u t keyText[16]=“这是我的钥匙。”;
__m128i键[20];
aes128_加载_键(键文本,键);
aes128_enc(键、输入、输出);
for(无符号整数i=0;i<16;i++)