Merge branch 'master' of https://github.com/wolfSSL/wolfssl-examples
commit
df0d8bceb1
|
@ -0,0 +1,349 @@
|
|||
/* 3des-file-encrypt.c
|
||||
*
|
||||
* Copyright (C) 2006-2014 wolfSSL Inc.
|
||||
* This file is part of CyaSSL.
|
||||
*
|
||||
* CyaSSL is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* CyaSSL is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,USA
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <termios.h>
|
||||
#include <cyassl/options.h>
|
||||
#include <cyassl/ctaocrypt/des3.h>
|
||||
#include <cyassl/ctaocrypt/sha256.h>
|
||||
#include <cyassl/ctaocrypt/random.h>
|
||||
#include <cyassl/ctaocrypt/pwdbased.h>
|
||||
|
||||
#define DES3_BLOCK_SIZE 24 /* size of encryption blocks */
|
||||
#define SALT_SIZE 8
|
||||
|
||||
/*
|
||||
* Makes a cyptographically secure key by stretching a user entered key
|
||||
*/
|
||||
int GenerateKey(RNG* rng, byte* key, int size, byte* salt, int pad)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = RNG_GenerateBlock(rng, salt, SALT_SIZE);
|
||||
if (ret != 0)
|
||||
return -1020;
|
||||
|
||||
if (pad == 0) /* sets first value of salt to check if the */
|
||||
salt[0] = 0; /* message is padded */
|
||||
|
||||
/* stretches key */
|
||||
ret = PBKDF2(key, key, strlen((const char*)key), salt, SALT_SIZE, 4096,
|
||||
size, SHA256);
|
||||
if (ret != 0)
|
||||
return -1030;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Encrypts a file using 3DES
|
||||
*/
|
||||
int Des3Encrypt(Des3* des3, byte* key, int size, FILE* inFile, FILE* outFile)
|
||||
{
|
||||
RNG rng;
|
||||
byte iv[DES3_BLOCK_SIZE];
|
||||
byte* input;
|
||||
byte* output;
|
||||
byte salt[SALT_SIZE] = {0};
|
||||
|
||||
int i = 0;
|
||||
int ret = 0;
|
||||
int inputLength;
|
||||
int length;
|
||||
int padCounter = 0;
|
||||
|
||||
fseek(inFile, 0, SEEK_END);
|
||||
inputLength = ftell(inFile);
|
||||
fseek(inFile, 0, SEEK_SET);
|
||||
|
||||
length = inputLength;
|
||||
/* pads the length until it evenly matches a block / increases pad number*/
|
||||
while (length % DES3_BLOCK_SIZE != 0) {
|
||||
length++;
|
||||
padCounter++;
|
||||
}
|
||||
|
||||
input = malloc(length);
|
||||
output = malloc(length);
|
||||
|
||||
ret = InitRng(&rng);
|
||||
if (ret != 0) {
|
||||
printf("Failed to initialize random number generator\n");
|
||||
return -1030;
|
||||
}
|
||||
|
||||
/* reads from inFile and wrties whatever is there to the input array */
|
||||
ret = fread(input, 1, inputLength, inFile);
|
||||
if (ret == 0) {
|
||||
printf("Input file does not exist.\n");
|
||||
return -1010;
|
||||
}
|
||||
for (i = inputLength; i < length; i++) {
|
||||
/* padds the added characters with the number of pads */
|
||||
input[i] = padCounter;
|
||||
}
|
||||
|
||||
ret = RNG_GenerateBlock(&rng, iv, DES3_BLOCK_SIZE);
|
||||
if (ret != 0)
|
||||
return -1020;
|
||||
|
||||
/* stretches key to fit size */
|
||||
ret = GenerateKey(&rng, key, size, salt, padCounter);
|
||||
if (ret != 0)
|
||||
return -1040;
|
||||
|
||||
/* sets key */
|
||||
ret = Des3_SetKey(des3, key, iv, DES_ENCRYPTION);
|
||||
if (ret != 0)
|
||||
return -1001;
|
||||
|
||||
/* encrypts the message to the ouput based on input length + padding */
|
||||
ret = Des3_CbcEncrypt(des3, output, input, length);
|
||||
if (ret != 0)
|
||||
return -1005;
|
||||
|
||||
/* writes to outFile */
|
||||
fwrite(salt, 1, SALT_SIZE, outFile);
|
||||
fwrite(iv, 1, DES3_BLOCK_SIZE, outFile);
|
||||
fwrite(output, 1, length, outFile);
|
||||
|
||||
/* closes the opened files and frees the memory*/
|
||||
memset(input, 0, length);
|
||||
memset(output, 0, length);
|
||||
memset(key, 0, size);
|
||||
free(input);
|
||||
free(output);
|
||||
free(key);
|
||||
fclose(inFile);
|
||||
fclose(outFile);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Decrypts a file using 3DES
|
||||
*/
|
||||
int Des3Decrypt(Des3* des3, byte* key, int size, FILE* inFile, FILE* outFile)
|
||||
{
|
||||
RNG rng;
|
||||
byte iv[DES3_BLOCK_SIZE];
|
||||
byte* input;
|
||||
byte* output;
|
||||
byte salt[SALT_SIZE] = {0};
|
||||
|
||||
int i = 0;
|
||||
int ret = 0;
|
||||
int length;
|
||||
int aSize;
|
||||
|
||||
fseek(inFile, 0, SEEK_END);
|
||||
length = ftell(inFile);
|
||||
fseek(inFile, 0, SEEK_SET);
|
||||
aSize = length;
|
||||
|
||||
input = malloc(aSize);
|
||||
output = malloc(aSize);
|
||||
|
||||
InitRng(&rng);
|
||||
|
||||
/* reads from inFile and wrties whatever is there to the input array */
|
||||
ret = fread(input, 1, length, inFile);
|
||||
if (ret == 0) {
|
||||
printf("Input file does not exist.\n");
|
||||
return -1010;
|
||||
}
|
||||
for (i = 0; i < SALT_SIZE; i++) {
|
||||
/* finds salt from input message */
|
||||
salt[i] = input[i];
|
||||
}
|
||||
for (i = SALT_SIZE; i < DES3_BLOCK_SIZE + SALT_SIZE; i++) {
|
||||
/* finds iv from input message */
|
||||
iv[i - SALT_SIZE] = input[i];
|
||||
}
|
||||
|
||||
/* replicates old key if keys match */
|
||||
ret = PBKDF2(key, key, strlen((const char*)key), salt, SALT_SIZE, 4096,
|
||||
size, SHA256);
|
||||
if (ret != 0)
|
||||
return -1050;
|
||||
|
||||
/* sets key */
|
||||
ret = Des3_SetKey(des3, key, iv, DES_DECRYPTION);
|
||||
if (ret != 0)
|
||||
return -1002;
|
||||
|
||||
/* change length to remove salt/iv block from being decrypted */
|
||||
length -= (DES3_BLOCK_SIZE + SALT_SIZE);
|
||||
for (i = 0; i < length; i++) {
|
||||
/* shifts message: ignores salt/iv on message*/
|
||||
input[i] = input[i + (DES3_BLOCK_SIZE + SALT_SIZE)];
|
||||
}
|
||||
/* decrypts the message to output based on input length + padding */
|
||||
ret = Des3_CbcDecrypt(des3, output, input, length);
|
||||
if (ret != 0)
|
||||
return -1006;
|
||||
|
||||
if (salt[0] != 0) {
|
||||
/* reduces length based on number of padded elements */
|
||||
length -= output[length-1];
|
||||
}
|
||||
/* writes output to the outFile based on shortened length */
|
||||
fwrite(output, 1, length, outFile);
|
||||
|
||||
/* closes the opened files and frees the memory*/
|
||||
memset(input, 0, aSize);
|
||||
memset(output, 0, aSize);
|
||||
memset(key, 0, size);
|
||||
free(input);
|
||||
free(output);
|
||||
free(key);
|
||||
fclose(inFile);
|
||||
fclose(outFile);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* help message
|
||||
*/
|
||||
void help()
|
||||
{
|
||||
printf("\n~~~~~~~~~~~~~~~~~~~~|Help|~~~~~~~~~~~~~~~~~~~~~\n\n");
|
||||
printf("Usage: ./3des-encrypt <-option> <KeySize> <file.in> "
|
||||
"<file.out>\n\n");
|
||||
printf("Options\n");
|
||||
printf("-d Decryption\n-e Encryption\n-h Help\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* temporarily deisables echoing in terminal for secure key input
|
||||
*/
|
||||
int NoEcho(char* key, int size)
|
||||
{
|
||||
struct termios oflags, nflags;
|
||||
|
||||
/* disabling echo */
|
||||
tcgetattr(fileno(stdin), &oflags);
|
||||
nflags = oflags;
|
||||
nflags.c_lflag &= ~ECHO;
|
||||
nflags.c_lflag |= ECHONL;
|
||||
|
||||
if (tcsetattr(fileno(stdin), TCSANOW, &nflags) != 0) {
|
||||
printf("Error\n");
|
||||
return -1060;
|
||||
}
|
||||
|
||||
printf("Key: ");
|
||||
fgets(key, size, stdin);
|
||||
key[strlen(key) - 1] = 0;
|
||||
|
||||
/* restore terminal */
|
||||
if (tcsetattr(fileno(stdin), TCSANOW, &oflags) != 0) {
|
||||
printf("Error\n");
|
||||
return -1070;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SizeCheck(int size)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (size != 56 && size != 112 && size != 168) {
|
||||
/* if the entered size does not match acceptable size */
|
||||
printf("Invalid 3DES key size\n");
|
||||
ret = -1080;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
Des3 des3;
|
||||
byte* key; /* user entered key */
|
||||
FILE* inFile;
|
||||
FILE* outFile;
|
||||
|
||||
const char* in;
|
||||
const char* out;
|
||||
|
||||
int option; /* choice of how to run program */
|
||||
int ret = 0; /* return value */
|
||||
int inCheck = 0;
|
||||
int outCheck = 0;
|
||||
int size = 0;
|
||||
char choice = 'n';
|
||||
|
||||
while ((option = getopt(argc, argv, "d:e:i:o:h")) != -1) {
|
||||
switch (option) {
|
||||
case 'd': /* if entered decrypt */
|
||||
size = atoi(optarg);
|
||||
ret = SizeCheck(size);
|
||||
choice = 'd';
|
||||
break;
|
||||
case 'e': /* if entered encrypt */
|
||||
size = atoi(optarg);
|
||||
ret = SizeCheck(size);
|
||||
choice = 'e';
|
||||
break;
|
||||
case 'h': /* if entered 'help' */
|
||||
help();
|
||||
break;
|
||||
case 'i': /* input file */
|
||||
in = optarg;
|
||||
inCheck = 1;
|
||||
inFile = fopen(in, "r");
|
||||
break;
|
||||
case 'o': /* output file */
|
||||
out = optarg;
|
||||
outCheck = 1;
|
||||
outFile = fopen(out, "w");
|
||||
break;
|
||||
case '?':
|
||||
if (optopt) {
|
||||
printf("Ending Session\n");
|
||||
return -111;
|
||||
}
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
if (inCheck == 0 || outCheck == 0) {
|
||||
printf("Must have both input and output file");
|
||||
printf(": -i filename -o filename\n");
|
||||
}
|
||||
|
||||
else if (ret == 0 && choice != 'n') {
|
||||
key = malloc(size); /* sets size memory of key */
|
||||
ret = NoEcho((char*)key, size);
|
||||
if (choice == 'e')
|
||||
Des3Encrypt(&des3, key, size, inFile, outFile);
|
||||
else if (choice == 'd')
|
||||
Des3Decrypt(&des3, key, size, inFile, outFile);
|
||||
}
|
||||
else if (choice == 'n') {
|
||||
printf("Must select either -e or -d for encryption and decryption\n");
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
CC=gcc
|
||||
CFLAGS=-Wall
|
||||
LIBS= -lcyassl
|
||||
|
||||
3des-file-encrypt: 3des-file-encrypt.o
|
||||
$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
|
||||
|
||||
.PHONY: clean
|
||||
|
||||
clean:
|
||||
rm -f *.o 3des-file-encrypt
|
|
@ -0,0 +1,19 @@
|
|||
How to use 3des-file-encrypt.c
|
||||
|
||||
1) Start by typing make
|
||||
2) Make a file to encode. Can be any file (ex. .txt .in .out .file etc.)
|
||||
3) run the excecutable, for help run with -h flag. Basic command is as follows:
|
||||
|
||||
./3des-file-encrypt <-option> <KeySize> <input.file> <output.file>
|
||||
|
||||
typing -e for option will encrypt the input.file onto the output.file.
|
||||
typing -d for option will decrypt the input.file onto the output.file.
|
||||
NOTE: When decrypting make sure the key is the same used for the
|
||||
encryption, otherwise it won't decode correctly. Which is the idea.
|
||||
Only those with the key will be able to decode the message. If no
|
||||
key is entered into the command line, it will use "0123456789abcdef"
|
||||
by default.
|
||||
|
||||
4) Running 'make clean' will delete the excecutable as well as any created
|
||||
files. Making sure that the only files left are '3des-file-encrypt.c',
|
||||
'Makefile', and 'README'.
|
|
@ -0,0 +1,11 @@
|
|||
CC=gcc
|
||||
CFLAGS=-Wall
|
||||
LIBS= -lcyassl
|
||||
|
||||
aes-file-encrypt: aes-file-encrypt.o
|
||||
$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
|
||||
|
||||
.PHONY: clean
|
||||
|
||||
clean:
|
||||
rm -f *.o aes-file-encrypt
|
|
@ -0,0 +1,19 @@
|
|||
How to use aes-file-encrypt.c
|
||||
|
||||
1) Start by typing make
|
||||
2) Make a file to encode. Can be any file (ex. .txt .in .out .file etc.)
|
||||
3) run the excecutable, for help run with -h flag. Basic command is as follows:
|
||||
|
||||
./aes-file-encrypt <-option> <KeySize> <input.file> <output.file>
|
||||
|
||||
typing -e for option will encrypt the input.file onto the output.file.
|
||||
typing -d for option will decrypt the input.file onto the output.file.
|
||||
NOTE: When decrypting make sure the key is the same used for the
|
||||
encryption, otherwise it won't decode correctly. Which is the idea.
|
||||
Only those with the key will be able to decode the message. If no
|
||||
key is entered into the command line, it will use "0123456789abcdef"
|
||||
by default.
|
||||
|
||||
4) Running 'make clean' will delete the excecutable as well as any created
|
||||
files. Making sure that the only files left are 'aes-file-encrypt.c',
|
||||
'Makefile', and 'README'.
|
|
@ -0,0 +1,347 @@
|
|||
/* aes-file-encrypt.c
|
||||
*
|
||||
* Copyright (C) 2006-2014 wolfSSL Inc.
|
||||
* This file is part of CyaSSL.
|
||||
*
|
||||
* CyaSSL is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* CyaSSL is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,USA
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <termios.h>
|
||||
#include <cyassl/options.h>
|
||||
#include <cyassl/ctaocrypt/aes.h>
|
||||
#include <cyassl/ctaocrypt/sha256.h>
|
||||
#include <cyassl/ctaocrypt/random.h>
|
||||
#include <cyassl/ctaocrypt/pwdbased.h>
|
||||
|
||||
#define SALT_SIZE 8
|
||||
|
||||
/*
|
||||
* Makes a cyptographically secure key by stretching a user entered key
|
||||
*/
|
||||
int GenerateKey(RNG* rng, byte* key, int size, byte* salt, int pad)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = RNG_GenerateBlock(rng, salt, SALT_SIZE);
|
||||
if (ret != 0)
|
||||
return -1020;
|
||||
|
||||
if (pad == 0)
|
||||
salt[0] = 0;
|
||||
|
||||
/* stretches key */
|
||||
ret = PBKDF2(key, key, strlen((const char*)key), salt, SALT_SIZE, 4096,
|
||||
size, SHA256);
|
||||
if (ret != 0)
|
||||
return -1030;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Encrypts a file using AES
|
||||
*/
|
||||
int AesEncrypt(Aes* aes, byte* key, int size, FILE* inFile, FILE* outFile)
|
||||
{
|
||||
RNG rng;
|
||||
byte iv[AES_BLOCK_SIZE];
|
||||
byte* input;
|
||||
byte* output;
|
||||
byte salt[SALT_SIZE] = {0};
|
||||
|
||||
int i = 0;
|
||||
int ret = 0;
|
||||
int inputLength;
|
||||
int length;
|
||||
int padCounter = 0;
|
||||
|
||||
fseek(inFile, 0, SEEK_END);
|
||||
inputLength = ftell(inFile);
|
||||
fseek(inFile, 0, SEEK_SET);
|
||||
|
||||
length = inputLength;
|
||||
/* pads the length until it evenly matches a block / increases pad number*/
|
||||
while (length % AES_BLOCK_SIZE != 0) {
|
||||
length++;
|
||||
padCounter++;
|
||||
}
|
||||
|
||||
input = malloc(length);
|
||||
output = malloc(length);
|
||||
|
||||
ret = InitRng(&rng);
|
||||
if (ret != 0) {
|
||||
printf("Failed to initialize random number generator\n");
|
||||
return -1030;
|
||||
}
|
||||
|
||||
/* reads from inFile and wrties whatever is there to the input array */
|
||||
ret = fread(input, 1, inputLength, inFile);
|
||||
if (ret == 0) {
|
||||
printf("Input file does not exist.\n");
|
||||
return -1010;
|
||||
}
|
||||
for (i = inputLength; i < length; i++) {
|
||||
/* padds the added characters with the number of pads */
|
||||
input[i] = padCounter;
|
||||
}
|
||||
|
||||
ret = RNG_GenerateBlock(&rng, iv, AES_BLOCK_SIZE);
|
||||
if (ret != 0)
|
||||
return -1020;
|
||||
|
||||
/* stretches key to fit size */
|
||||
ret = GenerateKey(&rng, key, size, salt, padCounter);
|
||||
if (ret != 0)
|
||||
return -1040;
|
||||
|
||||
/* sets key */
|
||||
ret = AesSetKey(aes, key, AES_BLOCK_SIZE, iv, AES_ENCRYPTION);
|
||||
if (ret != 0)
|
||||
return -1001;
|
||||
|
||||
/* encrypts the message to the ouput based on input length + padding */
|
||||
ret = AesCbcEncrypt(aes, output, input, length);
|
||||
if (ret != 0)
|
||||
return -1005;
|
||||
|
||||
/* writes to outFile */
|
||||
fwrite(salt, 1, SALT_SIZE, outFile);
|
||||
fwrite(iv, 1, AES_BLOCK_SIZE, outFile);
|
||||
fwrite(output, 1, length, outFile);
|
||||
|
||||
/* closes the opened files and frees the memory*/
|
||||
memset(input, 0, length);
|
||||
memset(output, 0, length);
|
||||
memset(key, 0, size);
|
||||
free(input);
|
||||
free(output);
|
||||
free(key);
|
||||
fclose(inFile);
|
||||
fclose(outFile);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Decryptsr a file using AES
|
||||
*/
|
||||
int AesDecrypt(Aes* aes, byte* key, int size, FILE* inFile, FILE* outFile)
|
||||
{
|
||||
RNG rng;
|
||||
byte iv[AES_BLOCK_SIZE];
|
||||
byte* input;
|
||||
byte* output;
|
||||
byte salt[SALT_SIZE] = {0};
|
||||
|
||||
int i = 0;
|
||||
int ret = 0;
|
||||
int length;
|
||||
int aSize;
|
||||
|
||||
fseek(inFile, 0, SEEK_END);
|
||||
length = ftell(inFile);
|
||||
fseek(inFile, 0, SEEK_SET);
|
||||
aSize = length;
|
||||
|
||||
input = malloc(aSize);
|
||||
output = malloc(aSize);
|
||||
|
||||
InitRng(&rng);
|
||||
|
||||
/* reads from inFile and wrties whatever is there to the input array */
|
||||
ret = fread(input, 1, length, inFile);
|
||||
if (ret == 0) {
|
||||
printf("Input file does not exist.\n");
|
||||
return -1010;
|
||||
}
|
||||
for (i = 0; i < SALT_SIZE; i++) {
|
||||
/* finds salt from input message */
|
||||
salt[i] = input[i];
|
||||
}
|
||||
for (i = SALT_SIZE; i < AES_BLOCK_SIZE + SALT_SIZE; i++) {
|
||||
/* finds iv from input message */
|
||||
iv[i - SALT_SIZE] = input[i];
|
||||
}
|
||||
|
||||
/* replicates old key if keys match */
|
||||
ret = PBKDF2(key, key, strlen((const char*)key), salt, SALT_SIZE, 4096,
|
||||
size, SHA256);
|
||||
if (ret != 0)
|
||||
return -1050;
|
||||
|
||||
/* sets key */
|
||||
ret = AesSetKey(aes, key, AES_BLOCK_SIZE, iv, AES_DECRYPTION);
|
||||
if (ret != 0)
|
||||
return -1002;
|
||||
|
||||
/* change length to remove salt/iv block from being decrypted */
|
||||
length -= (AES_BLOCK_SIZE + SALT_SIZE);
|
||||
for (i = 0; i < length; i++) {
|
||||
/* shifts message: ignores salt/iv on message*/
|
||||
input[i] = input[i + (AES_BLOCK_SIZE + SALT_SIZE)];
|
||||
}
|
||||
/* decrypts the message to output based on input length + padding*/
|
||||
ret = AesCbcDecrypt(aes, output, input, length);
|
||||
if (ret != 0)
|
||||
return -1006;
|
||||
|
||||
if (salt[0] != 0) {
|
||||
/* reduces length based on number of padded elements */
|
||||
length -= output[length-1];
|
||||
}
|
||||
/* writes output to the outFile based on shortened length */
|
||||
fwrite(output, 1, length, outFile);
|
||||
|
||||
/* closes the opened files and frees the memory*/
|
||||
memset(input, 0, aSize);
|
||||
memset(output, 0, aSize);
|
||||
memset(key, 0, size);
|
||||
free(input);
|
||||
free(output);
|
||||
free(key);
|
||||
fclose(inFile);
|
||||
fclose(outFile);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* help message
|
||||
*/
|
||||
void help()
|
||||
{
|
||||
printf("\n~~~~~~~~~~~~~~~~~~~~|Help|~~~~~~~~~~~~~~~~~~~~~\n\n");
|
||||
printf("Usage: ./aes-file-encrypt <-option> <KeySize> <-i file.in> "
|
||||
"<-o file.out>\n\n");
|
||||
printf("Options\n");
|
||||
printf("-d Decryption\n-e Encryption\n-h Help\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* temporarily deisables echoing in terminal for secure key input
|
||||
*/
|
||||
int NoEcho(char* key, int size)
|
||||
{
|
||||
struct termios oflags, nflags;
|
||||
|
||||
/* disabling echo */
|
||||
tcgetattr(fileno(stdin), &oflags);
|
||||
nflags = oflags;
|
||||
nflags.c_lflag &= ~ECHO;
|
||||
nflags.c_lflag |= ECHONL;
|
||||
|
||||
if (tcsetattr(fileno(stdin), TCSANOW, &nflags) != 0) {
|
||||
printf("Error\n");
|
||||
return -1060;
|
||||
}
|
||||
|
||||
printf("Key: ");
|
||||
fgets(key, size, stdin);
|
||||
key[strlen(key) - 1] = 0;
|
||||
|
||||
/* restore terminal */
|
||||
if (tcsetattr(fileno(stdin), TCSANOW, &oflags) != 0) {
|
||||
printf("Error\n");
|
||||
return -1070;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SizeCheck(int size)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (size != 128 && size != 192 && size != 256) {
|
||||
/* if the entered size does not match acceptable size */
|
||||
printf("Invalid AES key size\n");
|
||||
ret = -1080;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
Aes aes;
|
||||
byte* key; /* user entered key */
|
||||
FILE* inFile;
|
||||
FILE* outFile;
|
||||
|
||||
const char* in;
|
||||
const char* out;
|
||||
|
||||
int option; /* choice of how to run program */
|
||||
int ret = 0; /* return value */
|
||||
int size = 0;
|
||||
int inCheck = 0;
|
||||
int outCheck = 0;
|
||||
char choice = 'n';
|
||||
|
||||
while ((option = getopt(argc, argv, "d:e:i:o:h")) != -1) {
|
||||
switch (option) {
|
||||
case 'd': /* if entered decrypt */
|
||||
size = atoi(optarg);
|
||||
ret = SizeCheck(size);
|
||||
choice = 'd';
|
||||
break;
|
||||
case 'e': /* if entered encrypt */
|
||||
size = atoi(optarg);
|
||||
ret = SizeCheck(size);
|
||||
choice = 'e';
|
||||
break;
|
||||
case 'h': /* if entered 'help' */
|
||||
help();
|
||||
break;
|
||||
case 'i': /* input file */
|
||||
in = optarg;
|
||||
inCheck = 1;
|
||||
inFile = fopen(in, "r");
|
||||
break;
|
||||
case 'o': /* output file */
|
||||
out = optarg;
|
||||
outCheck = 1;
|
||||
outFile = fopen(out, "w");
|
||||
break;
|
||||
case '?':
|
||||
if (optopt) {
|
||||
printf("Ending Session\n");
|
||||
return -111;
|
||||
}
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
}
|
||||
if (inCheck == 0 || outCheck == 0) {
|
||||
printf("Must have both input and output file");
|
||||
printf(": -i filename -o filename\n");
|
||||
}
|
||||
else if (ret == 0 && choice != 'n') {
|
||||
key = malloc(size); /* sets size memory of key */
|
||||
ret = NoEcho((char*)key, size);
|
||||
if (choice == 'e')
|
||||
AesEncrypt(&aes, key, size, inFile, outFile);
|
||||
else if (choice == 'd')
|
||||
AesDecrypt(&aes, key, size, inFile, outFile);
|
||||
}
|
||||
else if (choice == 'n') {
|
||||
printf("Must select either -e or -d for encryption and decryption\n");
|
||||
ret = -110;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
CC=gcc
|
||||
CFLAGS=-Wall
|
||||
LIBS= -lcyassl
|
||||
|
||||
camellia-encrypt: camellia-encrypt.o
|
||||
$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
|
||||
|
||||
.PHONY: clean
|
||||
|
||||
clean:
|
||||
rm -f *.o camellia-encrypt
|
|
@ -0,0 +1,19 @@
|
|||
How to use camellia-encrypt.c
|
||||
|
||||
1) Start by typing make
|
||||
2) Make a file to encode. Can be any file (ex. .txt .in .out .file etc.)
|
||||
3) run the excecutable, for help run with -h flag. Basic command is as follows:
|
||||
|
||||
./camellia-encrypt <-option> <input.file> <KeySize> <output.file>
|
||||
|
||||
typing -e for option will encrypt the input.file onto the output.file.
|
||||
typing -d for option will decrypt the input.file onto the output.file.
|
||||
NOTE: When decrypting make sure the key is the same used for the
|
||||
encryption, otherwise it won't decode correctly. Which is the idea.
|
||||
Only those with the key will be able to decode the message. If no
|
||||
key is entered into the command line, it will use "0123456789abcdef"
|
||||
by default.
|
||||
|
||||
4) Running 'make clean' will delete the excecutable as well as any created
|
||||
files. Making sure that the only files left are 'camellia-encrypt.c',
|
||||
'Makefile', and 'README'.
|
|
@ -0,0 +1,345 @@
|
|||
/* camellia-encrypt.c
|
||||
*
|
||||
* Copyright (C) 2006-2014 wolfSSL Inc.
|
||||
* This file is part of CyaSSL.
|
||||
*
|
||||
* CyaSSL is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* CyaSSL is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,USA
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <termios.h>
|
||||
#include <cyassl/options.h>
|
||||
#include <cyassl/ctaocrypt/sha256.h>
|
||||
#include <cyassl/ctaocrypt/random.h>
|
||||
#include <cyassl/ctaocrypt/pwdbased.h>
|
||||
#include <cyassl/ctaocrypt/camellia.h>
|
||||
|
||||
#define SALT_SIZE 8
|
||||
|
||||
/*
|
||||
* Makes a cyptographically secure key by stretMDMching a user entered key
|
||||
*/
|
||||
int GenerateKey(RNG* rng, byte* key, int size, byte* salt, int pad)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = RNG_GenerateBlock(rng, salt, SALT_SIZE-1);
|
||||
if (ret != 0)
|
||||
return -1020;
|
||||
|
||||
if (pad == 0) /* sets first value of salt to check if the */
|
||||
salt[0] = 0; /* message is padded */
|
||||
|
||||
/* stretches key */
|
||||
ret = PBKDF2(key, key, strlen((const char*)key), salt, SALT_SIZE, 4096,
|
||||
size, SHA256);
|
||||
if (ret != 0)
|
||||
return -1030;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Encrypts a file using Camellia
|
||||
*/
|
||||
int CamelliaEncrypt(Camellia* cam, byte* key, int size, FILE* inFile,
|
||||
FILE* outFile)
|
||||
{
|
||||
RNG rng;
|
||||
byte iv[CAMELLIA_BLOCK_SIZE];
|
||||
byte* input;
|
||||
byte* output;
|
||||
byte salt[SALT_SIZE] = {0};
|
||||
|
||||
int i = 0;
|
||||
int ret = 0;
|
||||
int inputLength;
|
||||
int length;
|
||||
int padCounter = 0;
|
||||
|
||||
fseek(inFile, 0, SEEK_END);
|
||||
inputLength = ftell(inFile);
|
||||
fseek(inFile, 0, SEEK_SET);
|
||||
|
||||
length = inputLength;
|
||||
/* pads the length until it evenly matches a block / increases pad number*/
|
||||
while (length % CAMELLIA_BLOCK_SIZE != 0) {
|
||||
length++;
|
||||
padCounter++;
|
||||
}
|
||||
|
||||
input = malloc(length);
|
||||
output = malloc(length);
|
||||
|
||||
ret = InitRng(&rng);
|
||||
if (ret != 0) {
|
||||
printf("Failed to initialize random number generator\n");
|
||||
return -1030;
|
||||
}
|
||||
|
||||
/* reads from inFile and wrties whatever is there to the input array */
|
||||
ret = fread(input, 1, inputLength, inFile);
|
||||
if (ret == 0) {
|
||||
printf("Input file does not exist.\n");
|
||||
return -1010;
|
||||
}
|
||||
for (i = inputLength; i < length; i++) {
|
||||
/* padds the added characters with the number of pads */
|
||||
input[i] = padCounter;
|
||||
}
|
||||
|
||||
ret = RNG_GenerateBlock(&rng, iv, CAMELLIA_BLOCK_SIZE);
|
||||
if (ret != 0)
|
||||
return -1020;
|
||||
|
||||
/* stretches key to fit size */
|
||||
ret = GenerateKey(&rng, key, size, salt, padCounter);
|
||||
if (ret != 0)
|
||||
return -1040;
|
||||
|
||||
/* sets key */
|
||||
ret = CamelliaSetKey(cam, key, CAMELLIA_BLOCK_SIZE, iv);
|
||||
if (ret != 0)
|
||||
return -1001;
|
||||
|
||||
/* encrypts the message to the ouput based on input length + padding */
|
||||
CamelliaCbcEncrypt(cam, output, input, length);
|
||||
|
||||
/* writes to outFile */
|
||||
fwrite(salt, 1, SALT_SIZE, outFile);
|
||||
fwrite(iv, 1, CAMELLIA_BLOCK_SIZE, outFile);
|
||||
fwrite(output, 1, length, outFile);
|
||||
|
||||
/* closes the opened files and frees the memory*/
|
||||
memset(input, 0, length);
|
||||
memset(output, 0, length);
|
||||
memset(key, 0, size);
|
||||
free(input);
|
||||
free(output);
|
||||
free(key);
|
||||
fclose(inFile);
|
||||
fclose(outFile);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Decrypts a file using Camellia
|
||||
*/
|
||||
int CamelliaDecrypt(Camellia* cam, byte* key, int size, FILE* inFile,
|
||||
FILE* outFile)
|
||||
{
|
||||
RNG rng;
|
||||
byte iv[CAMELLIA_BLOCK_SIZE];
|
||||
byte* input;
|
||||
byte* output;
|
||||
byte salt[SALT_SIZE] = {0};
|
||||
|
||||
int i = 0;
|
||||
int ret = 0;
|
||||
int length;
|
||||
int aSize;
|
||||
|
||||
fseek(inFile, 0, SEEK_END);
|
||||
length = ftell(inFile);
|
||||
fseek(inFile, 0, SEEK_SET);
|
||||
aSize = length;
|
||||
|
||||
input = malloc(aSize);
|
||||
output = malloc(aSize);
|
||||
|
||||
InitRng(&rng);
|
||||
|
||||
/* reads from inFile and wrties whatever is there to the input array */
|
||||
ret = fread(input, 1, length, inFile);
|
||||
if (ret == 0) {
|
||||
printf("Input file does not exist.\n");
|
||||
return -1010;
|
||||
}
|
||||
for (i = 0; i < SALT_SIZE; i++) {
|
||||
/* finds salt from input message */
|
||||
salt[i] = input[i];
|
||||
}
|
||||
for (i = SALT_SIZE; i < CAMELLIA_BLOCK_SIZE + SALT_SIZE; i++) {
|
||||
/* finds iv from input message */
|
||||
iv[i - SALT_SIZE] = input[i];
|
||||
}
|
||||
|
||||
/* replicates old key if keys match */
|
||||
ret = PBKDF2(key, key, strlen((const char*)key), salt, SALT_SIZE, 4096,
|
||||
size, SHA256);
|
||||
if (ret != 0)
|
||||
return -1050;
|
||||
|
||||
/* sets key */
|
||||
ret = CamelliaSetKey(cam, key, CAMELLIA_BLOCK_SIZE, iv);
|
||||
if (ret != 0)
|
||||
return -1002;
|
||||
|
||||
/* change length to remove salt/iv block from being decrypted */
|
||||
length -= (CAMELLIA_BLOCK_SIZE + SALT_SIZE);
|
||||
for (i = 0; i < length; i++) {
|
||||
/* shifts message: ignores salt/iv on message*/
|
||||
input[i] = input[i + (CAMELLIA_BLOCK_SIZE + SALT_SIZE)];
|
||||
}
|
||||
/* decrypts the message to output based on input length + padding */
|
||||
CamelliaCbcDecrypt(cam, output, input, length);
|
||||
|
||||
if (salt[0] != 0) {
|
||||
/* reduces length based on number of padded elements */
|
||||
length -= output[length-1];
|
||||
}
|
||||
/* writes output to the outFile based on shortened length */
|
||||
fwrite(output, 1, length, outFile);
|
||||
|
||||
/* closes the opened files and frees the memory*/
|
||||
memset(input, 0, aSize);
|
||||
memset(output, 0, aSize);
|
||||
memset(key, 0, size);
|
||||
free(input);
|
||||
free(output);
|
||||
free(key);
|
||||
fclose(inFile);
|
||||
fclose(outFile);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* help message
|
||||
*/
|
||||
void help()
|
||||
{
|
||||
printf("\n~~~~~~~~~~~~~~~~~~~~|Help|~~~~~~~~~~~~~~~~~~~~~\n\n");
|
||||
printf("Usage: ./camellia-file-encrypt <-option> <KeySize> <-i file.in> "
|
||||
"<-o file.out>\n\n");
|
||||
printf("Options\n");
|
||||
printf("-d Decryption\n-e Encryption\n-h Help\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* temporarily deisables echoing in terminal for secure key input
|
||||
*/
|
||||
int NoEcho(char* key, int size)
|
||||
{
|
||||
struct termios oflags, nflags;
|
||||
|
||||
/* disabling echo */
|
||||
tcgetattr(fileno(stdin), &oflags);
|
||||
nflags = oflags;
|
||||
nflags.c_lflag &= ~ECHO;
|
||||
nflags.c_lflag |= ECHONL;
|
||||
|
||||
if (tcsetattr(fileno(stdin), TCSANOW, &nflags) != 0) {
|
||||
printf("Error\n");
|
||||
return -1060;
|
||||
}
|
||||
|
||||
printf("Key: ");
|
||||
fgets(key, size, stdin);
|
||||
key[strlen(key) - 1] = 0;
|
||||
|
||||
/* restore terminal */
|
||||
if (tcsetattr(fileno(stdin), TCSANOW, &oflags) != 0) {
|
||||
printf("Error\n");
|
||||
return -1070;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SizeCheck(int size)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (size != 128 && size != 192 && size != 256) {
|
||||
/* if the entered size does not match acceptable size */
|
||||
printf("Invalid Camellia key size\n");
|
||||
ret = -1080;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
Camellia cam;
|
||||
byte* key; /* user entered key */
|
||||
FILE* inFile;
|
||||
FILE* outFile;
|
||||
|
||||
const char* in;
|
||||
const char* out;
|
||||
|
||||
int option; /* choice of how to run program */
|
||||
int ret = 0; /* return value */
|
||||
int inCheck = 0;
|
||||
int outCheck = 0;
|
||||
int size = 0;
|
||||
char choice = 'n';
|
||||
|
||||
while ((option = getopt(argc, argv, "d:e:i:o:h")) != -1) {
|
||||
switch (option) {
|
||||
case 'd': /* if entered decrypt */
|
||||
size = atoi(optarg);
|
||||
ret = SizeCheck(size);
|
||||
choice = 'd';
|
||||
break;
|
||||
case 'e': /* if entered encrypt */
|
||||
size = atoi(optarg);
|
||||
ret = SizeCheck(size);
|
||||
choice = 'e';
|
||||
break;
|
||||
case 'h': /* if entered 'help' */
|
||||
help();
|
||||
break;
|
||||
case 'i': /* input file */
|
||||
in = optarg;
|
||||
inCheck = 1;
|
||||
inFile = fopen(in, "r");
|
||||
break;
|
||||
case 'o': /* output file */
|
||||
out = optarg;
|
||||
outCheck = 1;
|
||||
outFile = fopen(out, "w");
|
||||
break;
|
||||
case '?':
|
||||
if (optopt) {
|
||||
printf("Ending Session\n");
|
||||
return -111;
|
||||
}
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
}
|
||||
if (inCheck == 0 || outCheck == 0) {
|
||||
printf("Must have both input and output file");
|
||||
printf(": -i filename -o filename\n");
|
||||
}
|
||||
|
||||
else if (ret == 0 && choice != 'n') {
|
||||
key = malloc(size); /* sets size memory of key */
|
||||
ret = NoEcho((char*)key, size);
|
||||
if (choice == 'e')
|
||||
CamelliaEncrypt(&cam, key, size, inFile, outFile);
|
||||
else if (choice == 'd')
|
||||
CamelliaDecrypt(&cam, key, size, inFile, outFile);
|
||||
}
|
||||
else if (choice == 'n') {
|
||||
printf("Must select either -e or -d for encryption and decryption\n");
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
|
@ -22,7 +22,6 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <sys/select.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <cyassl/ssl.h> /* CyaSSL security library */
|
||||
#include <fcntl.h> /* nonblocking I/O library */
|
||||
|
@ -113,6 +112,7 @@ int ClientGreet(CYASSL* ssl)
|
|||
/* data to send to the server, data recieved from the server */
|
||||
char sendBuff[MAXDATASIZE], rcvBuff[MAXDATASIZE] = {0};
|
||||
int ret = 0;
|
||||
int count = 0;
|
||||
|
||||
printf("Message for server:\t");
|
||||
fgets(sendBuff, MAXDATASIZE, stdin);
|
||||
|
@ -129,9 +129,11 @@ int ClientGreet(CYASSL* ssl)
|
|||
/* the server failed to send data, or error trying */
|
||||
ret = CyaSSL_get_error(ssl, 0);
|
||||
while (ret == SSL_ERROR_WANT_READ) {
|
||||
count++;
|
||||
ret = CyaSSL_read(ssl, rcvBuff, MAXDATASIZE);
|
||||
ret = CyaSSL_get_error(ssl, 0);
|
||||
}
|
||||
printf("counter %d\n", count);
|
||||
if (ret < 0) {
|
||||
ret = CyaSSL_get_error(ssl, 0);
|
||||
printf("Read error. Error: %d\n", ret);
|
||||
|
|
Loading…
Reference in New Issue