You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
176 lines
5.7 KiB
176 lines
5.7 KiB
#include "Device/Include/stm32f10x.h" // Device header
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include "AES_CTR.h"
|
|
//À©Õ¹Ãܳ×
|
|
Byte *keyExpansion(Byte *cipherKey) {
|
|
Byte *expandedKey = (Byte *)malloc(sizeof(Byte) * BYTES_IN_EXPANDED_KEY);
|
|
|
|
// get the key of the first round
|
|
for(int i = 0; i < BYTES_IN_ROUND; i++)
|
|
expandedKey[i] = cipherKey[i];
|
|
|
|
// get the key of other rounds
|
|
Byte *temporary_word = (Byte *)malloc(sizeof(Byte) * BYTES_IN_WORD);
|
|
for(int i = 1; i <= NUM_OF_ROUNDS; i++) {
|
|
// calculate the temporary word
|
|
for(int j = 0; j < BYTES_IN_WORD; j++)
|
|
temporary_word[j] = expandedKey[i * BYTES_IN_ROUND - BYTES_IN_WORD + j];
|
|
rotateWord(temporary_word, 1);
|
|
substitutionWord(temporary_word);
|
|
temporary_word[0] = (temporary_word[0] ^ roundConstant[i - 1]);
|
|
|
|
// get the key of this round
|
|
for(int j = 0; j < BYTES_IN_WORD; j++)
|
|
expandedKey[i * BYTES_IN_ROUND + j] = temporary_word[j]
|
|
^ expandedKey[(i - 1) * BYTES_IN_ROUND + j];
|
|
for(int j = 1; j < WORD_IN_ROUND; j++) {
|
|
for(int k = 0; k < BYTES_IN_WORD; k++) {
|
|
expandedKey[i * BYTES_IN_ROUND + j * BYTES_IN_WORD + k] =
|
|
expandedKey[i * BYTES_IN_ROUND + (j - 1) * BYTES_IN_WORD + k] ^
|
|
expandedKey[(i - 1) * BYTES_IN_ROUND + j * BYTES_IN_WORD + k];
|
|
}
|
|
}
|
|
}
|
|
free(temporary_word);
|
|
|
|
return expandedKey;
|
|
}
|
|
//CTR¼ÓÃÜ
|
|
void AES_Encryption(Byte state[][BYTES_IN_WORD], Byte* key) {
|
|
// Round 0: addRoundKey
|
|
addRoundKey(state, key, 0);
|
|
|
|
// Round 1~9: substitutionWord + shiftRow + mixColumn + addRoundKey
|
|
for(int i = 1; i < 10; i++) {
|
|
substitutionWord(state);
|
|
shiftRow(state);
|
|
mixColumn(state);
|
|
addRoundKey(state, key, i);
|
|
}
|
|
|
|
// Round 10: substitutionWord + shiftRow + addRoundKey
|
|
substitutionWord(state);
|
|
shiftRow(state);
|
|
addRoundKey(state, key, 10);
|
|
}
|
|
//CTR½âÃÜ
|
|
void AES_Decryption(Byte state[][BYTES_IN_WORD], Byte* key) {
|
|
// Inv round 10: addRoundKey + shiftRowInv + substitutionWordInv
|
|
addRoundKey(state, key, 10);
|
|
shiftRowInv(state);
|
|
substitutionWordInv(state);
|
|
|
|
// Inv round 9~1: addRoundKey + mixColumnInv + shiftRowInv + substitutionWordInv
|
|
for(int i = 9; i > 0; i--) {
|
|
addRoundKey(state, key, i);
|
|
mixColumnInv(state);
|
|
shiftRowInv(state);
|
|
substitutionWordInv(state);
|
|
}
|
|
|
|
// Inv round 0: addRoundKey
|
|
addRoundKey(state, key, 0);
|
|
}
|
|
|
|
void rotateWord(Byte *word, int offset) {
|
|
Byte *temp = (Byte *)malloc(sizeof(Byte) * BYTES_IN_WORD);
|
|
for(int i = 0; i < BYTES_IN_WORD; i++)
|
|
temp[(i + BYTES_IN_WORD - offset) % 4] = word[i];
|
|
for(int i = 0; i < BYTES_IN_WORD; i++)
|
|
word[i] = temp[i];
|
|
free(temp);
|
|
}
|
|
void substitutionWord(Byte *word) {
|
|
for(int i = 0; i < BYTES_IN_WORD; i++)
|
|
word[i] = sBox[word[i] / 16][word[i] % 16];
|
|
}
|
|
void substitutionWord(Byte state[][BYTES_IN_WORD]) {
|
|
for(int i = 0; i < BYTES_IN_WORD; i++)
|
|
for(int j = 0; j < BYTES_IN_WORD; j++)
|
|
state[i][j] = sBox[state[i][j] / 16][state[i][j] % 16];
|
|
}
|
|
|
|
void substitutionWordInv(Byte state[][BYTES_IN_WORD]) {
|
|
for(int i = 0; i < BYTES_IN_WORD; i++)
|
|
for(int j = 0; j < BYTES_IN_WORD; j++)
|
|
state[i][j] = sBoxInv[state[i][j] / 16][state[i][j] % 16];
|
|
}
|
|
void shiftRow(Byte state[][BYTES_IN_WORD]) {
|
|
for(int i = 0; i < BYTES_IN_WORD; i++)
|
|
rotateWord(state[i], i);
|
|
}
|
|
void shiftRowInv(Byte state[][BYTES_IN_WORD]) {
|
|
for(int i = 1; i < BYTES_IN_WORD; i++)
|
|
rotateWord(state[i], 4 - i);
|
|
}
|
|
void mixColumn(Byte state[][BYTES_IN_WORD]) {
|
|
Byte *temp = (Byte *)malloc(sizeof(Byte) * BYTES_IN_WORD);
|
|
for(int i = 0; i < BYTES_IN_WORD; i++) {
|
|
for(int j = 0; j < BYTES_IN_WORD; j++)
|
|
temp[j] = state[j][i];
|
|
for(int j = 0; j < BYTES_IN_WORD; j++) {
|
|
state[j][i] = 0;
|
|
for(int k = 0; k < BYTES_IN_WORD; k++)
|
|
state[j][i] = (state[j][i] ^ GF_Multiplication(constantMatrix[j][k], temp[k]));
|
|
}
|
|
}
|
|
free(temp);
|
|
}
|
|
void mixColumnInv(Byte state[][BYTES_IN_WORD]) {
|
|
Byte *temp = (Byte *)malloc(sizeof(Byte) * BYTES_IN_WORD);
|
|
for(int i = 0; i < BYTES_IN_WORD; i++) {
|
|
for(int j = 0; j < BYTES_IN_WORD; j++)
|
|
temp[j] = state[j][i];
|
|
for(int j = 0; j < BYTES_IN_WORD; j++) {
|
|
state[j][i] = 0;
|
|
for(int k = 0; k < BYTES_IN_WORD; k++)
|
|
state[j][i] = (state[j][i] ^ GF_Multiplication(constantMatrixInv[j][k], temp[k]));
|
|
}
|
|
}
|
|
free(temp);
|
|
}
|
|
Byte GF_Multiplication(Byte a, Byte b) {
|
|
bool *temp = (bool *)malloc(sizeof(bool) * BIT_IN_BYTE * 2);
|
|
for(int i = 0; i < BIT_IN_BYTE; i++) {
|
|
temp[i] = b % 2;
|
|
b /= 2;
|
|
}
|
|
|
|
short result = 0;
|
|
for(int i = 0; i < BIT_IN_BYTE; i++) {
|
|
result = result ^ ((temp[i] * a) << i);
|
|
}
|
|
|
|
int count = 0;
|
|
int temp_result = result;
|
|
for(int i = 0; i < BIT_IN_BYTE * 2; i++) {
|
|
temp[count++] = temp_result % 2;
|
|
temp_result /= 2;
|
|
}
|
|
for(int i = BIT_IN_BYTE; i < BIT_IN_BYTE * 2; i++)
|
|
if(temp[i] == 1)
|
|
result = result ^ GF_constant[i - BIT_IN_BYTE];
|
|
free(temp);
|
|
return (Byte)result;
|
|
}
|
|
void addRoundKey(Byte state[][BYTES_IN_WORD], Byte* key, int round) {
|
|
for(int i = 0; i < BYTES_IN_WORD; i++)
|
|
for(int j = 0; j < BYTES_IN_WORD; j++)
|
|
state[j][i] = (state[j][i] ^ key[round * BYTES_IN_ROUND + i * 4 + j]);
|
|
}
|
|
void printState(Byte state[][BYTES_IN_WORD]) {
|
|
for(int i = 0; i < BYTES_IN_WORD; i++) {
|
|
for(int j = 0; j < BYTES_IN_WORD; j++)
|
|
printf("%02X ", state[i][j]);
|
|
printf("\n");
|
|
}
|
|
printf("\n");
|
|
}
|
|
|
|
int main()
|
|
{
|
|
|
|
return 0;
|
|
}
|