📄 des_hardware.c
字号:
//------------------------------------------------------------------------------
// File: des_hardware.c
// Function: Firmware encryption using DES hardware acceleration
// Supported chip(s):
// - AT91SAM7XC128
// - AT91SAM7XC256
// Supported toolchain(s):
// - IAR Embedded Workbench
// Date created: 09 June 2006
// Created by: JJo
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
// Includes
//------------------------------------------------------------------------------
#include "des_hardware.h"
#if defined(USE_ENCRYPTION) && defined(ENCRYPTION_3DES_HARD)
//------------------------------------------------------------------------------
// Global variables
//------------------------------------------------------------------------------
#ifdef ENCRYPTION_CTR
unsigned char CTR[ENCRYPTION_BLOCK_LENGTH];
#endif
//------------------------------------------------------------------------------
// Inline functions
//------------------------------------------------------------------------------
/**
* Name: ASCII2Hex
* Purpose: Converts an ASCII value to an hexadecimal one
* Input(s):
* - ASCII string
* - Buffer to store integer value
* - Length of string
*/
static inline void ASCII2Hex(const unsigned char * ascii, unsigned char * binary, unsigned int length) {
for (unsigned int i=0; i < length; i++) {
if (ascii[i*2] >= 'A') {
binary[i] = ascii[i*2] - 'A' + 10;
}
else {
binary[i] = ascii[i*2] - '0';
}
binary[i] <<= 4;
if (ascii[i*2+1] >= 'A') {
binary[i] += ascii[i*2+1] - 'A' + 10;
}
else {
binary[i] += ascii[i*2+1] - '0';
}
}
}
//------------------------------------------------------------------------------
// Functions
//------------------------------------------------------------------------------
/**
* Name: des_hard_init
* Purpose: Initializes the AES peripheral
*/
void des_hard_init(void) {
// Local variables
unsigned char key[ENCRYPTION_KEY_LENGTH];
debug_printf("DES/HARD: Initializing ...\n");
// Activate peripheral clock
AT91F_TDES_CfgPMC();
// Load mode
#if (ENCRYPTION_KEY_LENGTH == 24)
AT91F_TDES_CfgModeReg(AT91C_BASE_TDES, AT91C_TDES_SMOD_MANUAL | TDES_MODE |
AT91C_TDES_TDESMOD | TDES_CIPHER);
#else
AT91F_TDES_CfgModeReg(AT91C_BASE_TDES, AT91C_TDES_SMOD_MANUAL | TDES_MODE |
AT91C_TDES_KEYMOD | AT91C_TDES_TDESMOD | TDES_CIPHER);
#endif
// Convert and load key
ASCII2Hex(ENCRYPTION_KEY, key, ENCRYPTION_KEY_LENGTH);
AT91C_BASE_TDES->TDES_KEY1WxR[0] = ((int *) key)[0];
AT91C_BASE_TDES->TDES_KEY1WxR[1] = ((int *) key)[1];
AT91C_BASE_TDES->TDES_KEY2WxR[0] = ((int *) key)[2];
AT91C_BASE_TDES->TDES_KEY2WxR[1] = ((int *) key)[3];
#if (ENCRYPTION_KEY_LENGTH == 24)
AT91C_BASE_TDES->TDES_KEY3WxR[0] = ((int *) key)[4];
AT91C_BASE_TDES->TDES_KEY3WxR[1] = ((int *) key)[5];
#endif
#if defined(ENCRYPTION_CBC)
unsigned char IV[8];
ASCII2Hex(ENCRYPTION_IV, IV, ENCRYPTION_BLOCK_LENGTH);
AT91C_BASE_TDES->TDES_IVxR[0] = ((int *) IV)[0];
AT91C_BASE_TDES->TDES_IVxR[1] = ((int *) IV)[1];
#elif defined(ENCRYPTION_CTR)
// Convert IV
ASCII2Hex(ENCRYPTION_IV, CTR, ENCRYPTION_BLOCK_LENGTH);
#endif
debug_printf("DES/HARD: Initialization done.\n");
}
/**
* Name: des_hard_cleanup
* Purpose: Cleans up the AES peripheral
*/
void des_hard_cleanup(void) {
debug_printf("DES/HARD: Cleaning up ...\n");
AT91F_TDES_CfgModeReg(AT91C_BASE_TDES, 0);
AT91F_PMC_DisablePeriphClock(AT91C_BASE_PMC, 1 << AT91C_ID_TDES);
debug_printf("DES/HARD: Cleanup done.\n");
}
/**
* Name: des_hard_decrypt
* Purpose: Decrypts a variable-length cipher text
* Input(s):
* - Cipher text to decrypt
* - Buffer to store plain text
* - Length of cipher text (in bytes)
*/
int des_hard_decrypt(const unsigned char * cipherText,
unsigned char * plainText,
unsigned int length) {
#if defined(ENCRYPTION_ECB) || defined(ENCRYPTION_CBC)
for (unsigned int l=0; l < length;) {
// Load counter and encrypt it
AT91C_BASE_TDES->TDES_IDATAxR[0] = ((int *) &cipherText[l])[0];
AT91C_BASE_TDES->TDES_IDATAxR[1] = ((int *) &cipherText[l])[1];
AT91F_TDES_StartProcessing(AT91C_BASE_TDES);
while (!AT91F_TDES_IsStatusSet(AT91C_BASE_TDES, AT91C_TDES_DATRDY));
((int *) &plainText[l])[0] = AT91C_BASE_TDES->TDES_ODATAxR[0];
((int *) &plainText[l])[1] = AT91C_BASE_TDES->TDES_ODATAxR[1];
l += ENCRYPTION_BLOCK_LENGTH;
}
#elif defined(ENCRYPTION_CTR)
// Local variables
unsigned int bytes;
unsigned char block[ENCRYPTION_BLOCK_LENGTH];
// Decrypt
for (unsigned int e=0; e < length;) {
// Load counter and encrypt it
AT91C_BASE_TDES->TDES_IDATAxR[0] = ((int *) CTR)[0];
AT91C_BASE_TDES->TDES_IDATAxR[1] = ((int *) CTR)[1];
AT91F_TDES_StartProcessing(AT91C_BASE_TDES);
while (!AT91F_TDES_IsStatusSet(AT91C_BASE_TDES, AT91C_TDES_DATRDY));
((int *) block)[0] = AT91C_BASE_TDES->TDES_ODATAxR[0];
((int *) block)[1] = AT91C_BASE_TDES->TDES_ODATAxR[1];
// XOR current plain text block with encrypted counter
if ((length-e) < ENCRYPTION_BLOCK_LENGTH) {
bytes = length - e;
}
else {
bytes = ENCRYPTION_BLOCK_LENGTH;
}
for (unsigned int i=0; i < bytes; i++) {
plainText[e+i] = cipherText[e+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 *) CTR)[i] != 0) {
break;
}
}
e += bytes;
}
#endif // ENCRYPTION_CTR
return OK;
}
#endif // defined(USE_ENCRYPTION) && defined(ENCRYPTION_3DES_HARD)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -