mirror of
https://github.com/Scandal-UK/Incognito_RCM.git
synced 2024-12-23 10:52:06 +00:00
171 lines
6.2 KiB
C
171 lines
6.2 KiB
C
/* ============================================================================================================ *
|
|
2012036901 - 윤진한
|
|
주 의 사 항
|
|
|
|
|
|
1. 주석으로 표현된 구현 블록 13에서 14번까지 구현하여 128비트 AES 암호화 알고리즘을 구현해야 함
|
|
2. AES.c를 먼저 구현한 다음, 해당 파일을 구현함
|
|
3. 사전에 주어진 메뉴얼 속 수도코드를 참고하여 구현함
|
|
4. 구현은 다양한 방식으로 이뤄질 수 있음
|
|
5. AES.h에 정의된 AES128(...) 함수만을 이용해서 구현해야 함
|
|
6. XTS_AES128(...) 함수의 호출과 리턴이 여러번 반복되더라도 메모리 누수가 생기지 않게 함
|
|
|
|
* ============================================================================================================ */
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include "XTS_AES.h"
|
|
#include "AES128.h"
|
|
|
|
/*********************************************** { 구현 13 시작 } ********************************************/
|
|
#define KEY_SIZE 16
|
|
#define BLOCK_SIZE 16
|
|
extern uint8_t iv[];
|
|
uint8_t iv2[BLOCK_SIZE];
|
|
|
|
// Additional Generator function in GF(2^128) to make tweakable variable.
|
|
void GF_Mutiplication_xts(uint8_t *T){
|
|
|
|
uint32_t x;
|
|
uint8_t t, tt;
|
|
|
|
for (x = t = 0;x < BLOCK_SIZE;x ++) {
|
|
tt = *(T + x) >> 7;
|
|
*(T + x) = ((*(T + x) << 1) | t) & 0xFF;
|
|
t = tt;
|
|
}
|
|
if (tt) {
|
|
*(T) ^= 0x87;
|
|
}
|
|
}
|
|
// Generator function in GF(2^128).
|
|
/*********************************************** { 구현 13 종료 } ********************************************/
|
|
|
|
|
|
/* <128비트 XTS_AES 암복호화 함수>
|
|
*
|
|
* mode가 ENC일 경우 평문을 암호화하고, DEC일 경우 암호문을 복호화하는 함수
|
|
*
|
|
* [ENC 모드]
|
|
* plain 평문 바이트 배열
|
|
* cipher 결과(암호문)이 담길 바이트 배열. 호출하는 사용자가 사전에 메모리를 할당하여 파라미터로 넘김
|
|
* size 평문 크기 (바이트 단위)
|
|
* key 256비트 암호키 (32바이트). 상위 16바이트는 key1, 하위 16바이트는 key2
|
|
*
|
|
* [DEC 모드]
|
|
* plain 결과(평문)가 담길 바이트 배열. 호출하는 사용자가 사전에 메모리를 할당하여 파라미터로 넘김
|
|
* cipher 암호문 바이트 배열
|
|
* size 암호문 크기 (바이트 단위)
|
|
* key 256비트 암호키 (32바이트). 상위 16바이트는 key1, 하위 16바이트는 key2
|
|
*/
|
|
void XTS_AES128(BYTE *plain, BYTE *cipher, unsigned int size, BYTE* key, int mode){
|
|
|
|
/*********************************************** { 구현 14 시작 } ********************************************/
|
|
int i,j,tmp = 0;
|
|
BYTE *T = (BYTE *)malloc(sizeof(BYTE)*BLOCK_SIZE);
|
|
BYTE *T2 = (BYTE *)malloc(sizeof(BYTE)*BLOCK_SIZE);
|
|
BYTE *PP = (BYTE *)malloc(sizeof(BYTE)*BLOCK_SIZE);
|
|
BYTE *CC = (BYTE *)malloc(sizeof(BYTE)*BLOCK_SIZE);
|
|
|
|
for (i = 0;i < BLOCK_SIZE;i ++){
|
|
*(iv2 + i) = *(iv + i);
|
|
} // copy initial vector to use ENC / DEC.
|
|
|
|
AES128(iv2,T,key + KEY_SIZE,ENC);
|
|
// create initial T with iv. ( ∂(0) == E(key2)(iv,T) )
|
|
|
|
if(mode == ENC){
|
|
|
|
for (i = 0;i < size/BLOCK_SIZE;i ++){
|
|
|
|
for (j = 0;j < BLOCK_SIZE;j ++){
|
|
*(PP + j) = plain[ i*BLOCK_SIZE + j ] ^ *(T + j);
|
|
}// create PP blocks.
|
|
AES128(PP,CC,key,ENC);
|
|
// create CC blocks.
|
|
for (j = 0;j < BLOCK_SIZE;j ++){
|
|
cipher[ i*BLOCK_SIZE + j ] = *(CC + j) ^ *(T + j);
|
|
}// create ciper blocks.
|
|
GF_Mutiplication_xts(T);
|
|
// create tweakable block.
|
|
}// when plain text is 16 multiples, it's over.
|
|
|
|
if (size%BLOCK_SIZE != 0){
|
|
// cipertext stealing.
|
|
|
|
for (j = 0;j < (size%BLOCK_SIZE);j ++){
|
|
cipher[ i*BLOCK_SIZE + j ] = cipher[ (i-1)*16 + j ];
|
|
*(PP + j) = *(T + j) ^ plain[ i*BLOCK_SIZE + j ];
|
|
}// shift and XOR.
|
|
for (j = size%BLOCK_SIZE;j < BLOCK_SIZE;j ++){
|
|
*(PP + j) = *(T + j) ^ cipher[ (i-1)*BLOCK_SIZE + j ];
|
|
}// create Additional PP blocks.
|
|
AES128(PP,CC,key,ENC);
|
|
// create Additional CC blocks.
|
|
for (j = 0;j < BLOCK_SIZE;j ++){
|
|
cipher[ (i-1)*BLOCK_SIZE + j ] = *(T + j) ^ *(CC + j);
|
|
}// create Additional ciper blocks.
|
|
|
|
}// when plain text length is not 16 multiples, it's done.
|
|
|
|
}else if(mode == DEC){
|
|
|
|
int check = (size%BLOCK_SIZE==0) ? 0 : 1;
|
|
// judge variable that size%BLOCK_SIZE is 0 or is not 0.
|
|
// check == 0 is size%BLOCK_SIZE == 0.
|
|
// check == 1 is size%BLOCK_SIZE != 0.
|
|
for (i = 0;i < size/BLOCK_SIZE;i ++){
|
|
|
|
if (i == size/BLOCK_SIZE - 1 && check) {
|
|
tmp = size/BLOCK_SIZE - 1;
|
|
break;
|
|
}
|
|
// when ciper text length is not 16 multiples.
|
|
for (j = 0;j < BLOCK_SIZE;j ++){
|
|
*(CC + j) = cipher[ i*BLOCK_SIZE + j ] ^ *(T + j);
|
|
}// create PP blocks.
|
|
AES128(PP,CC,key,DEC);
|
|
// create CC blocks.
|
|
for (j = 0;j < BLOCK_SIZE;j ++){
|
|
plain[ i*BLOCK_SIZE + j ] = *(PP + j) ^ *(T + j);
|
|
}// create plain blocks.
|
|
GF_Mutiplication_xts(T);
|
|
// create tweakable block.
|
|
}
|
|
|
|
if (check) {
|
|
// when ciper text length is not 16 multiples.
|
|
// cipertext stealing.
|
|
for (j = 0;j < BLOCK_SIZE;j ++){
|
|
*(T2 + j) = *(T + j);
|
|
}// copy tweakable block to tmp array.
|
|
GF_Mutiplication_xts(T);
|
|
// create tweakable block.
|
|
for (j = 0;j < BLOCK_SIZE;j ++){
|
|
*(CC + j) = *(T + j) ^ cipher[ tmp*BLOCK_SIZE + j ];
|
|
}// create Additional ciper blocks.
|
|
AES128(PP,CC,key,DEC);
|
|
// create CC blocks.
|
|
for (j = 0;j < size%BLOCK_SIZE;j ++){
|
|
plain[ (tmp + 1)*BLOCK_SIZE + j ] = *(T + j) ^ *(PP + j);
|
|
*(CC + j) = *(T2 + j) ^ cipher[ (tmp + 1)*BLOCK_SIZE + j ];
|
|
}// shift and XOR.
|
|
for (j = size%BLOCK_SIZE;j < BLOCK_SIZE;j ++){
|
|
*(CC + j) = *(T2 + j) ^ *(T + j) ^ *(PP + j);
|
|
}// create Additional ciper blocks.
|
|
AES128(PP,CC,key,DEC);
|
|
for (j = 0;j < BLOCK_SIZE;j ++){
|
|
plain[ tmp*BLOCK_SIZE + j ] = *(T2 + j) ^ *(PP + j);
|
|
}// create Additional PP blocks.
|
|
}
|
|
|
|
}else{
|
|
fprintf(stderr, "Invalid mode!\n");
|
|
exit(1);
|
|
}
|
|
free(T);
|
|
free(T2);
|
|
free(PP);
|
|
free(CC);
|
|
/*********************************************** { 구현 14 종료 } ********************************************/
|
|
}
|