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

#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;
}