📄 aes_reference.c
字号:
}
}
// Last round (no MixColumns)
for (unsigned int j=0; j < BC; j++) {
((int *) a)[j] = (t0f[b[j][0]]) ^
(t1f[b[(j+shifts[SC][0][1])%BC][1]]) ^
(t2f[b[(j+shifts[SC][0][2])%BC][2]]) ^
(t3f[b[(j+shifts[SC][0][3])%BC][3]]) ^
((int *) rk[ROUNDS])[j];
}
}
#endif
/**
* Name: decrypt
* Purpose: Decrypts a block of plain text using precalculated LUTs
* Input(s):
* - Block of cipher text to decrypt
* - Expanded key
* - Pointer to table T0
* - Pointer to table T1
* - Pointer to table T2
* - Pointer to table T3
* - Pointer to table TF
*/
#if defined(ENCRYPTION_ECB) || defined(ENCRYPTION_CBC)
static inline void decrypt(unsigned char a[BC][4],
const unsigned char rk[ROUNDS+1][BC][4],
unsigned int * t0,
unsigned int * t1,
unsigned int * t2,
unsigned int * t3,
unsigned int * tf) {
// Local variables
unsigned char b[BC][4];
// First key addition
addRoundKey(a, rk[ROUNDS]);
// ROUNDS-1 ordinary rounds
for(unsigned int r=ROUNDS-1; r > 0; r--) {
for (unsigned int j=0; j < BC; j++) {
((int *) b)[j] = t0[a[j][0]] ^
t1[a[(j+shifts[SC][1][1])%BC][1]] ^
t2[a[(j+shifts[SC][1][2])%BC][2]] ^
t3[a[(j+shifts[SC][1][3])%BC][3]] ^
((int *) rk[r])[j];
}
if ((--r) == 0) {
break;
}
for (unsigned int j=0; j < BC; j++) {
((int *) a)[j] = t0[b[j][0]] ^
t1[b[(j+shifts[SC][1][1])%BC][1]] ^
t2[b[(j+shifts[SC][1][2])%BC][2]] ^
t3[b[(j+shifts[SC][1][3])%BC][3]] ^
((int *) rk[r])[j];
}
}
// Last round (no MixColumns)
for (unsigned int j=0; j < BC; j++) {
((int *) a)[j] = (t0f[b[j][0]]) ^
(t1f[b[(j+shifts[SC][1][1])%BC][1]]) ^
(t2f[b[(j+shifts[SC][1][2])%BC][2]]) ^
(t3f[b[(j+shifts[SC][1][3])%BC][3]]) ^
((int *) rk[0])[j];
}
}
#endif
/**
* Name: ASCII2Hex
* Purpose: Converts an ASCII hexadecimal representation to a raw binary one
* Input(s):
* - ASCII value
* - Buffer to store binary value
* - Size of value
*/
static void ASCII2Hex(const unsigned char * ascii, unsigned char * binary, unsigned int length) {
// Local variables
unsigned char * ptr;
ptr = (unsigned char *) binary;
for (unsigned int i=0; i < length; i++, ptr++, ascii++) {
if (*ascii >= 'A') {
*ptr = *ascii - 'A' + 10;
}
else {
*ptr = *ascii - '0';
}
*ptr <<= 4;
ascii++;
if (*ascii >= 'A') {
*ptr += *ascii - 'A' + 10;
}
else {
*ptr += *ascii - '0';
}
}
}
/**
* Name: ecb_decrypt
* Purpose: Decrypts a cipher text using ECB mode
* Input(s):
* - Cipher text to decrypt
* - Buffer to store plain text
* - Length of cipher text
* - Expanded key to use
* Output: OK if successful, ERROR otherwise
*/
#if defined(ENCRYPTION_ECB)
static inline unsigned int ecb_decrypt(const unsigned char * cipherText,
unsigned char * plainText,
unsigned int length,
const unsigned char expandedKey[ROUNDS+1][BC][4]) {
// Local variables
unsigned char block[BC][4];
// Check input parameters
if ((cipherText == NULL) || (plainText == NULL) || (expandedKey == NULL)) {
debug_printf("AES/REF: NULL parameter(s).\n");
return ERROR;
}
if (length%ENCRYPTION_BLOCK_LENGTH != 0) {
debug_printf("AES/REF: Data length must be a multiple of the cipher block size.\n");
return ERROR;
}
// ECB decryption
for (unsigned int l=0; l < length;) {
// Copy cipher text block, decrypt it and copy result
for (unsigned int i=0; i < ENCRYPTION_BLOCK_LENGTH; i++) {
((char *) block)[i] = cipherText[l+i];
}
decrypt(block, expandedKey, T0, T1, T2, T3, TF);
for (unsigned int i=0; i < ENCRYPTION_BLOCK_LENGTH; i++) {
plainText[l+i] = ((char *) block)[i];
}
l += ENCRYPTION_BLOCK_LENGTH;
}
return OK;
}
#endif
/**
* Name: cbc_decrypt
* Purpose: Decrypts a cipher text using CBC mode
* Input(s):
* - Cipher text to decrypt
* - Buffer to store plain text
* - Length of cipher text (in bytes)
* - Expanded key to use
* - Initialization vector to use
* Ouput: OK if successful, ERROR otherwise
*/
#if defined(ENCRYPTION_CBC)
static inline unsigned int cbc_decrypt(const unsigned char * cipherText,
unsigned char * plainText,
unsigned int length,
const unsigned char expandedKey[ROUNDS+1][BC][4],
unsigned char IV[BC][4]) {
// Local variables
unsigned char block[BC][4];
// Check input parameters
if ((cipherText == NULL) || (plainText == NULL)) {
debug_printf("AES/REF: NULL parameter(s).\n");
return ERROR;
}
if (length%ENCRYPTION_BLOCK_LENGTH != 0) {
debug_printf("AES/REF: Cipher text length must be a multiple of the cipher block length.\n");
return ERROR;
}
// Decrypt data
for (unsigned int l=0; l < length;) {
// Copy and decrypt a block of cipher text
for (unsigned int i=0; i < BC; i++) {
((int *) block)[i] = ((int *) &cipherText[l])[i];
}
decrypt(block, expandedKey, T0, T1, T2, T3, TF);
// Xor decrypted text & IV, copy new IV
for (unsigned int i=0; i < BC; i++) {
unsigned int tmp = ((int *) block)[i] ^ ((int *) IV)[i];
((int *) IV)[i] = ((int *) &cipherText[l])[i];
((int *) &plainText[l])[i] = tmp;
}
// Loop progression
l += ENCRYPTION_BLOCK_LENGTH;
}
return OK;
}
#endif
/**
* Name: ctr_decrypt
* Purpose: Decrypts a cipher text using CTR mode
* Input(s):
* - Cipher text to decrypt
* - Buffer to store plain text
* - Length of cipher text
* - Expanded key to use
* - Initialization vector to use
* Output: OK if successful, ERROR otherwise
*/
#if defined(ENCRYPTION_CTR)
static inline unsigned int ctr_decrypt(const unsigned char * cipherText,
unsigned char * plainText,
unsigned int length,
const unsigned char expandedKey[ROUNDS+1][BC][4],
unsigned char IV[BC][4]) {
// Local variables
unsigned char block[BC][4];
unsigned int bytes;
// Check input parameters
if ((cipherText == NULL) || (plainText == NULL)) {
return ERROR;
}
for (unsigned int l=0; l < length;) {
// Copy counter and encrypt it
copyBlock(IV, block);
encrypt(block, expandedKey, T0, T1, T2, T3, TF);
// XOR current plain text block with encrypted counter
bytes = min(length - l, ENCRYPTION_BLOCK_LENGTH);
for (unsigned int i=0; i < bytes; i++) {
plainText[l+i] = cipherText[l+i] ^ ((char *) block)[i];
}
// Increment counter (big-endian) and number of encrypted bytes
for (int i=ENCRYPTION_BLOCK_LENGTH-1; i >= 0; i--) {
if (++((char *) IV)[i] != 0) {
break;
}
}
l += bytes;
}
return OK;
}
#endif
//------------------------------------------------------------------------------
// Functions
//------------------------------------------------------------------------------
/**
* Name: aes_ref_init
* Purpose: Initializes the AES algorithm
*/
void aes_ref_init(void) {
debug_printf("AES/REF: Initializing ...\n");
ASCII2Hex(ENCRYPTION_KEY, (unsigned char *) key, ENCRYPTION_KEY_LENGTH);
#if defined(ENCRYPTION_ECB) || defined(ENCRYPTION_CBC)
// Initialize key schedule
invKeySchedule(key, expandedKey);
// Generate lookup tables
generateDecryptionLUTs(T0, T1, T2, T3, TF, Si);
#elif defined(ENCRYPTION_CTR)
// Initialize key schedule
keySchedule(key, expandedKey);
// Generate lookup tables
generateEncryptionLUTs(T0, T1, T2, T3, TF, S);
#endif
#if defined(ENCRYPTION_CBC) || defined(ENCRYPTION_CTR)
// Initialize counter
ASCII2Hex(ENCRYPTION_IV, (unsigned char *) IV, ENCRYPTION_BLOCK_LENGTH);
#endif
debug_printf("AES/REF: Initialization done.\n");
}
/**
* Name: aes_ref_cleanup
* Purpose: Cleanup the AES algorithm
*/
void aes_ref_cleanup(void) {
debug_printf("AES/REF: Cleaning up ...\n");
debug_printf("AES/REF: Cleanup done.\n");
}
/**
* Name: aes_ref_decrypt
* Purpose: Decrypt a cipher text of variable length
* Input(s):
* - Cipher text to decrypt
* - Buffer to store plain text
* - Length of cipher text (in bytes)
* Output: OK if decryption was successful, ERROR otherwise.
*/
int aes_ref_decrypt(const unsigned char * cipherText,
unsigned char * plainText,
unsigned int length) {
#if defined(ENCRYPTION_ECB)
return ecb_decrypt(cipherText, plainText, length, expandedKey);
#elif defined(ENCRYPTION_CBC)
return cbc_decrypt(cipherText, plainText, length, expandedKey, IV);;
#elif defined(ENCRYPTION_CTR)
return ctr_decrypt(cipherText, plainText, length, expandedKey, IV);
#endif
}
#endif // defined(USE_ENCRYPTION) && defined(ENCRYPTION_AES_REF)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -