📄 pgpaes.c
字号:
{
int r;
#if AES_WORD_ALIGNMENT
word32 dummy;
word8 a[16], b[16];
#else
word8 *a, *b;
#endif
word8 temp[4][4];
#if AES_WORD_ALIGNMENT
pgpCopyMemory( in, a, sizeof(a) );
#else
a = in;
b = out;
#endif
*((word32*)temp[0]) = *((word32*)a) ^ *((word32*)rk[rounds][0]);
*((word32*)temp[1]) = *((word32*)(a+4)) ^ *((word32*)rk[rounds][1]);
*((word32*)temp[2]) = *((word32*)(a+8)) ^ *((word32*)rk[rounds][2]);
*((word32*)temp[3]) = *((word32*)(a+12)) ^ *((word32*)rk[rounds][3]);
*((word32*)b) = *((word32*)T5[temp[0][0]])
^ *((word32*)T6[temp[3][1]])
^ *((word32*)T7[temp[2][2]])
^ *((word32*)T8[temp[1][3]]);
*((word32*)(b+4)) = *((word32*)T5[temp[1][0]])
^ *((word32*)T6[temp[0][1]])
^ *((word32*)T7[temp[3][2]])
^ *((word32*)T8[temp[2][3]]);
*((word32*)(b+8)) = *((word32*)T5[temp[2][0]])
^ *((word32*)T6[temp[1][1]])
^ *((word32*)T7[temp[0][2]])
^ *((word32*)T8[temp[3][3]]);
*((word32*)(b+12)) = *((word32*)T5[temp[3][0]])
^ *((word32*)T6[temp[2][1]])
^ *((word32*)T7[temp[1][2]])
^ *((word32*)T8[temp[0][3]]);
for(r = rounds-1; r > 1; r--) {
*((word32*)temp[0]) = *((word32*)b) ^ *((word32*)rk[r][0]);
*((word32*)temp[1]) = *((word32*)(b+4)) ^ *((word32*)rk[r][1]);
*((word32*)temp[2]) = *((word32*)(b+8)) ^ *((word32*)rk[r][2]);
*((word32*)temp[3]) = *((word32*)(b+12)) ^ *((word32*)rk[r][3]);
*((word32*)b) = *((word32*)T5[temp[0][0]])
^ *((word32*)T6[temp[3][1]])
^ *((word32*)T7[temp[2][2]])
^ *((word32*)T8[temp[1][3]]);
*((word32*)(b+4)) = *((word32*)T5[temp[1][0]])
^ *((word32*)T6[temp[0][1]])
^ *((word32*)T7[temp[3][2]])
^ *((word32*)T8[temp[2][3]]);
*((word32*)(b+8)) = *((word32*)T5[temp[2][0]])
^ *((word32*)T6[temp[1][1]])
^ *((word32*)T7[temp[0][2]])
^ *((word32*)T8[temp[3][3]]);
*((word32*)(b+12)) = *((word32*)T5[temp[3][0]])
^ *((word32*)T6[temp[2][1]])
^ *((word32*)T7[temp[1][2]])
^ *((word32*)T8[temp[0][3]]);
}
/* last round is special */
*((word32*)temp[0]) = *((word32*)b) ^ *((word32*)rk[1][0]);
*((word32*)temp[1]) = *((word32*)(b+4)) ^ *((word32*)rk[1][1]);
*((word32*)temp[2]) = *((word32*)(b+8)) ^ *((word32*)rk[1][2]);
*((word32*)temp[3]) = *((word32*)(b+12)) ^ *((word32*)rk[1][3]);
b[0] = S5[temp[0][0]];
b[1] = S5[temp[3][1]];
b[2] = S5[temp[2][2]];
b[3] = S5[temp[1][3]];
b[4] = S5[temp[1][0]];
b[5] = S5[temp[0][1]];
b[6] = S5[temp[3][2]];
b[7] = S5[temp[2][3]];
b[8] = S5[temp[2][0]];
b[9] = S5[temp[1][1]];
b[10] = S5[temp[0][2]];
b[11] = S5[temp[3][3]];
b[12] = S5[temp[3][0]];
b[13] = S5[temp[2][1]];
b[14] = S5[temp[1][2]];
b[15] = S5[temp[0][3]];
*((word32*)b) ^= *((word32*)rk[0][0]);
*((word32*)(b+4)) ^= *((word32*)rk[0][1]);
*((word32*)(b+8)) ^= *((word32*)rk[0][2]);
*((word32*)(b+12)) ^= *((word32*)rk[0][3]);
#if AES_WORD_ALIGNMENT
pgpCopyMemory( b, out, sizeof(b) );
#endif
return 0;
}
/*
* Exported functions for PGP
*/
/*
* Flags at end of priv array to record whether key schedule is in encrypt
* or decrypt mode
*/
#define AES_ENCRYPTION_MODE 0x11
#define AES_DECRYPTION_MODE 0x22
static void
aes128Key(void *priv, void const *keymaterial)
{
PGPSize privSize;
PGPInt32 rounds;
rounds = 128/32 + 6;
*(PGPInt32 *)priv = rounds;
privSize = 16*(rounds+1);
rijndaelKeySched( (void *)keymaterial, 128,
(void *)((PGPUInt32 *)priv+1), rounds );
*((PGPByte *)priv+sizeof(PGPInt32)+privSize) = AES_ENCRYPTION_MODE;
}
static void
aes192Key(void *priv, void const *keymaterial)
{
PGPSize privSize;
PGPInt32 rounds;
rounds = 192/32 + 6;
*(PGPInt32 *)priv = rounds;
privSize = 16*(rounds+1);
rijndaelKeySched( (void *)keymaterial, 192, (void *)((PGPUInt32 *)priv+1),
rounds );
*((PGPByte *)priv+sizeof(PGPInt32)+privSize) = AES_ENCRYPTION_MODE;
}
static void
aes256Key(void *priv, void const *keymaterial)
{
PGPSize privSize;
PGPInt32 rounds;
rounds = 256/32 + 6;
*(PGPInt32 *)priv = rounds;
privSize = 16*(rounds+1);
rijndaelKeySched( (void *)keymaterial, 256, (void *)((PGPUInt32 *)priv+1),
rounds );
*((PGPByte *)priv+sizeof(PGPInt32)+privSize) = AES_ENCRYPTION_MODE;
}
static void
aesEncrypt(void *priv, void const *in, void *out)
{
PGPSize privSize;
PGPInt32 rounds;
rounds = *(PGPInt32 *)priv;
privSize = 16*(rounds+1);
/* Make sure key schedule is in the right mode */
if (*((PGPByte *)priv+sizeof(PGPInt32)+privSize) != AES_ENCRYPTION_MODE) {
PGPInt32 keyBits = 32*(rounds-6);
rijndaelKeyDectoEnc( keyBits, (void *)((PGPUInt32 *)priv+1), rounds );
*((PGPByte *)priv+sizeof(PGPInt32)+privSize) = AES_ENCRYPTION_MODE;
}
rijndaelEncrypt( (void *)in, out, (void *)((PGPUInt32 *)priv+1), rounds );
}
static void
aesDecrypt(void *priv, void const *in, void *out)
{
PGPSize privSize;
PGPInt32 rounds;
rounds = *(PGPInt32 *)priv;
privSize = 16*(rounds+1);
/* Make sure key schedule is in the right mode */
if (*((PGPByte *)priv+sizeof(PGPInt32)+privSize) != AES_DECRYPTION_MODE) {
PGPInt32 keyBits = 32*(rounds-6);
rijndaelKeyEnctoDec( keyBits, (void *)((PGPUInt32 *)priv+1), rounds );
*((PGPByte *)priv+sizeof(PGPInt32)+privSize) = AES_DECRYPTION_MODE;
}
rijndaelDecrypt( (void *)in, out, (void *)((PGPUInt32 *)priv+1), rounds );
}
/*
* Define a Cipher for the generic cipher. This is the only
* real exported thing -- everything else can be static, since everything
* is referenced through function pointers!
*/
PGPCipherVTBL const cipherAES128 = {
"AES128",
kPGPCipherAlgorithm_AES128,
16, /* Blocksize */
16, /* Keysize */
4+16*(128/32 + 7)+1, /* 4 byte rounds, Scheduled key, 1 byte enc/dec */
alignof(PGPUInt32),
aes128Key,
aesEncrypt,
aesDecrypt,
NULL
};
PGPCipherVTBL const cipherAES192 = {
"AES192",
kPGPCipherAlgorithm_AES192,
16, /* Blocksize */
24, /* Keysize */
4+16*(192/32 + 7)+1, /* 4 byte rounds, Scheduled key, 1 byte enc/dec */
alignof(PGPUInt32),
aes192Key,
aesEncrypt,
aesDecrypt,
NULL
};
PGPCipherVTBL const cipherAES256 = {
"AES256",
kPGPCipherAlgorithm_AES256,
16, /* Blocksize */
32, /* Keysize */
4+16*(256/32 + 7)+1, /* 4 byte rounds, Scheduled key, 1 byte enc/dec */
alignof(PGPUInt32),
aes256Key,
aesEncrypt,
aesDecrypt,
NULL
};
#if UNITTEST
/* Test vectors, first line from each ECB known answer test */
/* 128 bit key */
PGPByte K1[] = {
0x00, 0x01, 0x02, 0x03, 0x05, 0x06, 0x07, 0x08,
0x0A, 0x0B, 0x0C, 0x0D, 0x0F, 0x10, 0x11, 0x12
};
PGPByte P1[] = {
0x50, 0x68, 0x12, 0xA4, 0x5F, 0x08, 0xC8, 0x89,
0xB9, 0x7F, 0x59, 0x80, 0x03, 0x8B, 0x83, 0x59
};
PGPByte C1[] = {
0xD8, 0xF5, 0x32, 0x53, 0x82, 0x89, 0xEF, 0x7D,
0x06, 0xB5, 0x06, 0xA4, 0xFD, 0x5B, 0xE9, 0xC9
};
/* 192 bit key */
PGPByte K2[] = {
0x00, 0x01, 0x02, 0x03, 0x05, 0x06, 0x07, 0x08,
0x0A, 0x0B, 0x0C, 0x0D, 0x0F, 0x10, 0x11, 0x12,
0x14, 0x15, 0x16, 0x17, 0x19, 0x1A, 0x1B, 0x1C
};
PGPByte P2[] = {
0x2D, 0x33, 0xEE, 0xF2, 0xC0, 0x43, 0x0A, 0x8A,
0x9E, 0xBF, 0x45, 0xE8, 0x09, 0xC4, 0x0B, 0xB6
};
PGPByte C2[] = {
0xDF, 0xF4, 0x94, 0x5E, 0x03, 0x36, 0xDF, 0x4C,
0x1C, 0x56, 0xBC, 0x70, 0x0E, 0xFF, 0x83, 0x7F
};
/* 256 bit key */
PGPByte K3[] = {
0x00, 0x01, 0x02, 0x03, 0x05, 0x06, 0x07, 0x08,
0x0A, 0x0B, 0x0C, 0x0D, 0x0F, 0x10, 0x11, 0x12,
0x14, 0x15, 0x16, 0x17, 0x19, 0x1A, 0x1B, 0x1C,
0x1E, 0x1F, 0x20, 0x21, 0x23, 0x24, 0x25, 0x26
};
PGPByte P3[] = {
0x83, 0x4E, 0xAD, 0xFC, 0xCA, 0xC7, 0xE1, 0xB3,
0x06, 0x64, 0xB1, 0xAB, 0xA4, 0x48, 0x15, 0xAB
};
PGPByte C3[] = {
0x19, 0x46, 0xDA, 0xBF, 0x6A, 0x03, 0xA2, 0xA2,
0xC3, 0xD0, 0xB0, 0x50, 0x80, 0xAE, 0xD6, 0xFC
};
int
main(void)
{ /* Test driver for AES cipher */
PGPByte priv[5 + 16*(256/32 + 7)]; /* size from cipherAES256 */
PGPByte X[16], Y[16];
aes128Key(priv, K1);
aesEncrypt(priv, P1, X);
if (memcmp(C1, X, sizeof(X)) == 0)
printf ("Encryption test 1 passed\n");
else
printf ("ERROR ON ENCRYPTION TEST 1\n");
aesDecrypt(priv, C1, Y);
if (memcmp(P1, Y, sizeof(Y)) == 0)
printf ("Decryption test 1 passed\n");
else
printf ("ERROR ON DECRYPTION TEST 1\n");
aes192Key(priv, K2);
aesEncrypt(priv, P2, X);
if (memcmp(C2, X, sizeof(X)) == 0)
printf ("Encryption test 2 passed\n");
else
printf ("ERROR ON ENCRYPTION TEST 2\n");
aesDecrypt(priv, C2, Y);
if (memcmp(P2, Y, sizeof(Y)) == 0)
printf ("Decryption test 2 passed\n");
else
printf ("ERROR ON DECRYPTION TEST 2\n");
aes256Key(priv, K3);
aesEncrypt(priv, P3, X);
if (memcmp(C3, X, sizeof(X)) == 0)
printf ("Encryption test 3 passed\n");
else
printf ("ERROR ON ENCRYPTION TEST 3\n");
aesDecrypt(priv, C3, Y);
if (memcmp(P3, Y, sizeof(Y)) == 0)
printf ("Decryption test 3 passed\n");
else
printf ("ERROR ON DECRYPTION TEST 3\n");
return 0; /* normal exit */
} /* main */
#endif /* UNITTEST */
#endif /* ] PGP_AES */
/*__Editor_settings____
Local Variables:
tab-width: 4
End:
vi: ts=4 sw=4
vim: si
_____________________*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -