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.
163 lines
5.4 KiB
163 lines
5.4 KiB
/**
|
|
*--------------------------------------------------------------------\n
|
|
* HSLU T&A Hochschule Luzern Technik+Architektur \n
|
|
*--------------------------------------------------------------------\n
|
|
*
|
|
* \brief model solution for ASYD assignment crypto 01
|
|
* \file
|
|
* \author Stefano Nicora, stefano.nicora@hslu.ch
|
|
* \date 12.10.22
|
|
*
|
|
*--------------------------------------------------------------------
|
|
*/
|
|
|
|
#include <stdint.h>
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include "XTEA-CBC.h"
|
|
|
|
void encrypt(uint32_t key[4], uint8_t numberOfCycles);
|
|
void decrypt(uint32_t key[4], uint8_t numberOfCycles);
|
|
|
|
/* source: https://en.wikipedia.org/wiki/XTEA */
|
|
|
|
/* filenames as of this code:
|
|
* plaintext.txt => holds the message you want to encrypt
|
|
* encrypted.cip => holds the encrypted message
|
|
* decrypted.txt => holds the decrypted output from "encrypted.cip"
|
|
*/
|
|
|
|
void main(void) {
|
|
uint32_t key[4] = { 1, 3, 1, 2};
|
|
encrypt(key, 32);
|
|
decrypt(key, 32);
|
|
}
|
|
|
|
void encrypt(uint32_t key[4], uint8_t numberOfCycles) {
|
|
|
|
/* duplicate code that hasn't been moved to a separate function for readability reasons */
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
/* variables */
|
|
uint32_t amountOfCharsInFile = 0;
|
|
/* https://www.programiz.com/c-programming/c-file-input-output */
|
|
FILE* fileHandle = fopen("plaintext.txt", "r");
|
|
if (fileHandle == NULL) {
|
|
return;
|
|
}
|
|
|
|
/* get total number of characters in file to encrypt */
|
|
while (getc(fileHandle) != EOF) {
|
|
amountOfCharsInFile++;
|
|
}
|
|
|
|
/* allocate enough memory for the whole file to be read */
|
|
char* inputText = (char*)calloc(amountOfCharsInFile + 8, sizeof(char)); /* add 8 for extra padding in case the file contains some sort of rest in regards to amountOfCharsInFile % 8 */
|
|
if (inputText == NULL) {
|
|
return;
|
|
}
|
|
|
|
/* close and reopen file to start at the beginning of the file again */
|
|
fclose(fileHandle);
|
|
fileHandle = fopen("plaintext.txt", "r");
|
|
if (fileHandle == NULL) {
|
|
return;
|
|
}
|
|
|
|
/* read the whole file into memory */
|
|
for (uint32_t i = 0; i < amountOfCharsInFile; i++) {
|
|
inputText[i] = getc(fileHandle);
|
|
}
|
|
fclose(fileHandle);
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
/* loop through the whole array to encrypt the whole message
|
|
This happens two blocks of 32bit (= 8 characters) at a time
|
|
Hence the increase of "i" by 8
|
|
*/
|
|
for (uint32_t i = 0; i < amountOfCharsInFile; i += 8) { /* + 8 to compensate for the requested element size of the encipher function (32 bit) */
|
|
/* dereferencing and forwarding the address of the key ensures,
|
|
* that we don't ready from a random address in memory. Rookie mistakes happen :) */
|
|
encipher_CBC(numberOfCycles, &(inputText[i]), &(*key));
|
|
}
|
|
|
|
/* generate new file where encryption is stored */
|
|
fileHandle = fopen("encrypted.cip", "w");
|
|
if (fileHandle == NULL) {
|
|
return;
|
|
}
|
|
/* fill new file with content */
|
|
/* to get the extra character padding we might unintentionally drop
|
|
* we need to read up to a multiple of 8 (32 bit)
|
|
*/
|
|
for (uint32_t i = 0; i < (amountOfCharsInFile + (8-(amountOfCharsInFile%8))); i++) {
|
|
putc(inputText[i], fileHandle);
|
|
}
|
|
fclose(fileHandle);
|
|
free(inputText);
|
|
}
|
|
|
|
void decrypt(uint32_t key[4], uint8_t numberOfCycles) {
|
|
|
|
/* duplicate code that hasn't been moved to a separate function for readability reasons */
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
/* variables */
|
|
uint32_t amountOfCharsInFile = 0;
|
|
|
|
/* https://www.programiz.com/c-programming/c-file-input-output */
|
|
FILE* fileHandle = fopen("encrypted.cip", "r");
|
|
if (fileHandle == NULL) {
|
|
return;
|
|
}
|
|
|
|
/* get total number of characters in file to decrypt */
|
|
while (getc(fileHandle) != EOF) {
|
|
amountOfCharsInFile++;
|
|
}
|
|
|
|
/* allocate memory for the whole file to be read */
|
|
char* inputText = (char*)calloc(amountOfCharsInFile + 10, sizeof(char)); /* add 10 for extra padding */
|
|
if (inputText == NULL) {
|
|
return;
|
|
}
|
|
|
|
/* close and reopen file to start at the beginning of the file again */
|
|
fclose(fileHandle);
|
|
fileHandle = fopen("encrypted.cip", "r");
|
|
if (fileHandle == NULL) {
|
|
return;
|
|
}
|
|
|
|
/* read the whole file into memory */
|
|
for (uint32_t i = 0; i < amountOfCharsInFile; i++) {
|
|
inputText[i] = getc(fileHandle);
|
|
}
|
|
fclose(fileHandle);
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
/* loop through the whole array to encrypt the whole message
|
|
This happens two blocks of 32bit (= 4 characters) at a time
|
|
Hence the increase of "i" by 8
|
|
*/
|
|
|
|
for (uint32_t i = 0; i < amountOfCharsInFile; i += 8) { /* i += 8*/
|
|
/* dereferencing and forwarding the address of the key ensures,
|
|
* that we don't ready from a random address in memory. Rookie mistakes happen :) */
|
|
decipher_CBC(numberOfCycles, &(inputText[i]), &(*key));
|
|
}
|
|
|
|
/* generate new file where the decryption is stored */
|
|
fileHandle = fopen("decrypted.txt", "w");
|
|
if (fileHandle == NULL) {
|
|
return;
|
|
}
|
|
/* fill new file with content */
|
|
for (uint32_t i = 0; i < amountOfCharsInFile; i++) {
|
|
putc(inputText[i], fileHandle);
|
|
}
|
|
fclose(fileHandle);
|
|
free(inputText);
|
|
} |