1
0
Fork 0
mirror of https://github.com/Scandal-UK/Incognito_RCM.git synced 2024-12-23 18:56:01 +00:00
Incognito_RCM/source/keys/XTS_AES.c

172 lines
6.2 KiB
C
Raw Normal View History

2019-09-23 16:09:44 +01:00
/* ============================================================================================================ *
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 종료 } ********************************************/
}