AES密钥扩展
Intel AES-NI 指令集为 AES 密钥扩展提供了几个重要的 intrinsic 函数
// 核心密钥扩展函数
__m128i _mm_aeskeygenassist_si128(__m128i key, int round_constant);
// 加密相关指令
__m128i _mm_aesenc_si128(__m128i state, __m128i round_key);
__m128i _mm_aesenclast_si128(__m128i state, __m128i round_key);
__m128i _mm_aesdec_si128(__m128i state, __m128i round_key);
// 解密相关指令
__m128i _mm_aesdec_si128(__m128i state, __m128i round_key);
__m128i _mm_aesdeclast_si128(__m128i state, __m128i round_key);
// 逆向密钥扩展
__m128i _mm_aesimc_si128(__m128i round_key);
1. 核心密钥扩展函数
1.1. _mm_aeskeygenassist_si128
__m128i _mm_aeskeygenassist_si128(__m128i key, int round_constant);
2. 加密相关指令
2.1. _mm_aesenc_si128
__m128i _mm_aesenc_si128(__m128i state, __m128i round_key);
2.2. _mm_aesenclast_si128
__m128i _mm_aesenclast_si128(__m128i state, __m128i round_key);
2.3. _mm_aesdec_si128
__m128i _mm_aesdec_si128(__m128i state, __m128i round_key);
3. 解密相关指令
3.1. _mm_aesdec_si128
__m128i _mm_aesdec_si128(__m128i state, __m128i round_key);
3.2. _mm_aesdeclast_si128
__m128i _mm_aesdeclast_si128(__m128i state, __m128i round_key);
4. 逆向密钥扩展
4.1. _mm_aesimc_si128
__m128i _mm_aesimc_si128(__m128i round_key);
5. 密钥扩展示例
#include <wmmintrin.h>
#include <emmintrin.h>
void aes128_key_expansion(const unsigned char* user_key, unsigned char* key_schedule) {
__m128i key = _mm_loadu_si128((const __m128i*)user_key);
__m128i temp;
int i;
// 存储初始密钥
_mm_storeu_si128((__m128i*)key_schedule, key);
// 生成10轮密钥(AES-128)
for (i = 0; i < 10; i++) {
temp = _mm_aeskeygenassist_si128(key, 0x01 << i);
// 这里需要配合移位操作完成完整密钥扩展
key = _mm_xor_si128(key, _mm_slli_si128(temp, 4));
key = _mm_xor_si128(key, _mm_slli_si128(temp, 8));
key = _mm_xor_si128(key, _mm_slli_si128(temp, 12));
_mm_storeu_si128((__m128i*)(key_schedule + (i+1)*16), key);
}
}
void aes128_dec_key_expansion(const unsigned char* encrypt_keys,
unsigned char* decrypt_keys) {
// 存储最后一轮密钥(不变)
_mm_storeu_si128((__m128i*)decrypt_keys,
_mm_loadu_si128((const __m128i*)(encrypt_keys + 10*16)));
// 转换其他轮密钥用于解密
for (int i = 1; i < 10; i++) {
_mm_storeu_si128((__m128i*)(decrypt_keys + i*16),
_mm_aesimc_si128(_mm_loadu_si128(
(const __m128i*)(encrypt_keys + (10-i)*16))));
}
// 存储初始密钥
_mm_storeu_si128((__m128i*)(decrypt_keys + 10*16),
_mm_loadu_si128((const __m128i*)encrypt_keys));
}