Files
2026-05-21 08:07:16 +08:00

360 lines
12 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
* 标准AES-128-CBC实现 - 与OpenSSL完全兼容
* 基于FIPS-197标准
*/
#include "aes.h"
#include <string.h>
// S-box
static const uint8_t sbox[256] = {
0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
};
static const uint8_t rsbox[256] = {
0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
};
// Rcon
static const uint8_t Rcon[11] = {
0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36
};
#define getSBoxValue(num) (sbox[(num)])
#define getSBoxInvert(num) (rsbox[(num)])
// 密钥扩展
/* 函数作用:根据 AES-128 主密钥生成每轮加密使用的轮密钥。 */
static void KeyExpansion(uint8_t* RoundKey, const uint8_t* Key)
{
unsigned i, j, k;
uint8_t tempa[4];
// 前4个轮密钥直接复制
for (i = 0; i < 4; ++i) {
RoundKey[(i * 4) + 0] = Key[(i * 4) + 0];
RoundKey[(i * 4) + 1] = Key[(i * 4) + 1];
RoundKey[(i * 4) + 2] = Key[(i * 4) + 2];
RoundKey[(i * 4) + 3] = Key[(i * 4) + 3];
}
// 生成其余轮密钥
for (i = 4; i < 44; ++i) {
k = (i - 1) * 4;
tempa[0] = RoundKey[k + 0];
tempa[1] = RoundKey[k + 1];
tempa[2] = RoundKey[k + 2];
tempa[3] = RoundKey[k + 3];
if (i % 4 == 0) {
// RotWord
const uint8_t u8tmp = tempa[0];
tempa[0] = tempa[1];
tempa[1] = tempa[2];
tempa[2] = tempa[3];
tempa[3] = u8tmp;
// SubWord
tempa[0] = getSBoxValue(tempa[0]);
tempa[1] = getSBoxValue(tempa[1]);
tempa[2] = getSBoxValue(tempa[2]);
tempa[3] = getSBoxValue(tempa[3]);
tempa[0] = tempa[0] ^ Rcon[i / 4];
}
j = i * 4;
k = (i - 4) * 4;
RoundKey[j + 0] = RoundKey[k + 0] ^ tempa[0];
RoundKey[j + 1] = RoundKey[k + 1] ^ tempa[1];
RoundKey[j + 2] = RoundKey[k + 2] ^ tempa[2];
RoundKey[j + 3] = RoundKey[k + 3] ^ tempa[3];
}
}
// AddRoundKey
/* 函数作用:将当前状态矩阵与指定轮密钥进行异或。 */
static void AddRoundKey(uint8_t round, uint8_t* state, const uint8_t* RoundKey)
{
uint8_t i, j;
for (i = 0; i < 4; ++i) {
for (j = 0; j < 4; ++j) {
state[i * 4 + j] ^= RoundKey[(round * 16) + (i * 4 + j)];
}
}
}
// SubBytes
/* 函数作用:使用 AES S 盒对状态矩阵进行字节替换。 */
static void SubBytes(uint8_t* state)
{
uint8_t i;
for (i = 0; i < 16; ++i) {
state[i] = getSBoxValue(state[i]);
}
}
// ShiftRows
/* 函数作用:执行 AES 加密流程中的行移位变换。 */
static void ShiftRows(uint8_t* state)
{
uint8_t temp;
// 第二行左移1字节
temp = state[1];
state[1] = state[5];
state[5] = state[9];
state[9] = state[13];
state[13] = temp;
// 第三行左移2字节
temp = state[2];
state[2] = state[10];
state[10] = temp;
temp = state[6];
state[6] = state[14];
state[14] = temp;
// 第四行左移3字节
temp = state[15];
state[15] = state[11];
state[11] = state[7];
state[7] = state[3];
state[3] = temp;
}
// xtime (用于MixColumns)
/* 函数作用:在 AES 有限域中执行乘以 2 的运算。 */
static uint8_t xtime(uint8_t x)
{
return ((x << 1) ^ (((x >> 7) & 1) * 0x1b));
}
// MixColumns
/* 函数作用:执行 AES 加密流程中的列混淆变换。 */
static void MixColumns(uint8_t* state)
{
uint8_t i;
uint8_t Tmp, Tm, t;
for (i = 0; i < 4; ++i) {
t = state[i * 4 + 0];
Tmp = state[i * 4 + 0] ^ state[i * 4 + 1] ^ state[i * 4 + 2] ^ state[i * 4 + 3];
Tm = state[i * 4 + 0] ^ state[i * 4 + 1];
Tm = xtime(Tm);
state[i * 4 + 0] ^= Tm ^ Tmp;
Tm = state[i * 4 + 1] ^ state[i * 4 + 2];
Tm = xtime(Tm);
state[i * 4 + 1] ^= Tm ^ Tmp;
Tm = state[i * 4 + 2] ^ state[i * 4 + 3];
Tm = xtime(Tm);
state[i * 4 + 2] ^= Tm ^ Tmp;
Tm = state[i * 4 + 3] ^ t;
Tm = xtime(Tm);
state[i * 4 + 3] ^= Tm ^ Tmp;
}
}
// Cipher - AES加密核心
/* 函数作用:对 16 字节状态块执行完整 AES 加密。 */
static void Cipher(uint8_t* state, const uint8_t* RoundKey)
{
uint8_t round = 0;
// 初始轮密钥加
AddRoundKey(0, state, RoundKey);
// 9轮标准变换
for (round = 1; round < 10; ++round) {
SubBytes(state);
ShiftRows(state);
MixColumns(state);
AddRoundKey(round, state, RoundKey);
}
// 最后一轮(无MixColumns)
SubBytes(state);
ShiftRows(state);
AddRoundKey(10, state, RoundKey);
}
/* 函数作用:在 AES 有限域中执行两个字节的乘法。 */
static uint8_t Multiply(uint8_t x, uint8_t y)
{
return (((y & 1) * x) ^
(((y >> 1) & 1) * xtime(x)) ^
(((y >> 2) & 1) * xtime(xtime(x))) ^
(((y >> 3) & 1) * xtime(xtime(xtime(x)))) ^
(((y >> 4) & 1) * xtime(xtime(xtime(xtime(x))))));
}
/* 函数作用:使用 AES 逆 S 盒对状态矩阵进行逆字节替换。 */
static void InvSubBytes(uint8_t* state)
{
uint8_t i;
for (i = 0; i < 16; ++i) {
state[i] = getSBoxInvert(state[i]);
}
}
/* 函数作用:执行 AES 解密流程中的逆行移位变换。 */
static void InvShiftRows(uint8_t* state)
{
uint8_t temp;
temp = state[13];
state[13] = state[9];
state[9] = state[5];
state[5] = state[1];
state[1] = temp;
temp = state[2];
state[2] = state[10];
state[10] = temp;
temp = state[6];
state[6] = state[14];
state[14] = temp;
temp = state[3];
state[3] = state[7];
state[7] = state[11];
state[11] = state[15];
state[15] = temp;
}
/* 函数作用:执行 AES 解密流程中的逆列混淆变换。 */
static void InvMixColumns(uint8_t* state)
{
uint8_t i;
uint8_t a, b, c, d;
for (i = 0; i < 4; ++i) {
a = state[i * 4 + 0];
b = state[i * 4 + 1];
c = state[i * 4 + 2];
d = state[i * 4 + 3];
state[i * 4 + 0] = Multiply(a, 0x0e) ^ Multiply(b, 0x0b) ^ Multiply(c, 0x0d) ^ Multiply(d, 0x09);
state[i * 4 + 1] = Multiply(a, 0x09) ^ Multiply(b, 0x0e) ^ Multiply(c, 0x0b) ^ Multiply(d, 0x0d);
state[i * 4 + 2] = Multiply(a, 0x0d) ^ Multiply(b, 0x09) ^ Multiply(c, 0x0e) ^ Multiply(d, 0x0b);
state[i * 4 + 3] = Multiply(a, 0x0b) ^ Multiply(b, 0x0d) ^ Multiply(c, 0x09) ^ Multiply(d, 0x0e);
}
}
/* 函数作用:对 16 字节状态块执行完整 AES 解密。 */
static void InvCipher(uint8_t* state, const uint8_t* RoundKey)
{
uint8_t round;
AddRoundKey(10, state, RoundKey);
for (round = 9; ; --round) {
InvShiftRows(state);
InvSubBytes(state);
AddRoundKey(round, state, RoundKey);
if (round == 0) {
break;
}
InvMixColumns(state);
}
}
// ========== 公开API函数 ==========
/* 函数作用:初始化 AES 上下文并生成轮密钥。 */
void AES_init_ctx(struct AES_ctx* ctx, const uint8_t* key)
{
KeyExpansion(ctx->RoundKey, key);
}
/* 函数作用:初始化 AES 上下文并设置 CBC 模式 IV。 */
void AES_init_ctx_iv(struct AES_ctx* ctx, const uint8_t* key, const uint8_t* iv)
{
KeyExpansion(ctx->RoundKey, key);
memcpy(ctx->Iv, iv, AES_BLOCKLEN);
}
/* 函数作用:对单个 16 字节数据块执行 AES-ECB 加密。 */
void AES_ECB_encrypt(const struct AES_ctx* ctx, uint8_t* buf)
{
Cipher(buf, ctx->RoundKey);
}
/* 函数作用:使用 AES-CBC 模式加密指定长度的数据缓冲区。 */
void AES_CBC_encrypt_buffer(struct AES_ctx* ctx, uint8_t* buf, size_t length)
{
size_t i;
uint8_t j;
for (i = 0; i < length; i += AES_BLOCKLEN) {
// XOR with IV/previous ciphertext block
for (j = 0; j < AES_BLOCKLEN; ++j) {
buf[i + j] ^= ctx->Iv[j];
}
// Encrypt block
Cipher(buf + i, ctx->RoundKey);
// Update IV to current ciphertext block
memcpy(ctx->Iv, buf + i, AES_BLOCKLEN);
}
}
/* 函数作用:对单个 16 字节数据块执行 AES-ECB 解密。 */
void AES_ECB_decrypt(const struct AES_ctx* ctx, uint8_t* buf)
{
InvCipher(buf, ctx->RoundKey);
}
/* 函数作用:使用 AES-CBC 模式解密指定长度的数据缓冲区。 */
void AES_CBC_decrypt_buffer(struct AES_ctx* ctx, uint8_t* buf, size_t length)
{
size_t i;
uint8_t j;
uint8_t store_next_iv[AES_BLOCKLEN];
for (i = 0; i < length; i += AES_BLOCKLEN) {
memcpy(store_next_iv, buf + i, AES_BLOCKLEN);
InvCipher(buf + i, ctx->RoundKey);
for (j = 0; j < AES_BLOCKLEN; ++j) {
buf[i + j] ^= ctx->Iv[j];
}
memcpy(ctx->Iv, store_next_iv, AES_BLOCKLEN);
}
}