Two examples for Ascon-AEAD128 and Ascon-Hash256
Fix typos No need to input key size as the size for ascon AEAD algorithm is fixed Add an example for algorithm Ascon-Hash256pull/573/head
parent
bfdda5612e
commit
d000810206
|
|
@ -6,6 +6,8 @@ For further usage and details:
|
|||
|
||||
Please see the [3des/README.md](3des/README.md) for 3des.
|
||||
|
||||
Please see the [ascon/README.md](ascon/README.md) for ascon.
|
||||
|
||||
Please see the [aes/README.md](aes/README.md) for aes.
|
||||
|
||||
Please see the [camellia/README.md](camellia/README.md) for camellia.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,12 @@
|
|||
CC=gcc
|
||||
CFLAGS=-Wall -g
|
||||
WOLFSSL_INSTALL_DIR=/usr/local
|
||||
LIBS=-L$(WOLFSSL_INSTALL_DIR)/lib -lwolfssl
|
||||
|
||||
ascon-file-encrypt: ascon-file-encrypt.o
|
||||
$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
|
||||
|
||||
.PHONY: clean
|
||||
|
||||
clean:
|
||||
rm -f *.o ascon-file-encrypt
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
How to use ascon-file-encrypt.c
|
||||
|
||||
1) a. Compile wolfSSL with ./configure --enable-pwdbased --enable-ascon --enable-experimental, run
|
||||
'make', and then install by typing 'sudo make install'.
|
||||
b. In the crypto/ascon directory run the Makefile by typing 'make'.
|
||||
2) Make a file to encode. Can be any file (ex. .txt .in .out .file etc.)
|
||||
3) run the executable, for help run with -h flag. Basic command is as follows:
|
||||
./ascon-file-encrypt <-option> -i <input.file> -o <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 executable as well as any created
|
||||
files. Making sure that the only files left are 'ascon-file-encrypt.c',
|
||||
'Makefile', and 'README'.
|
||||
|
|
@ -0,0 +1,404 @@
|
|||
/* ascon-file-encrypt.c
|
||||
*
|
||||
* Copyright (C) 2006-2020 wolfSSL Inc.
|
||||
*
|
||||
* This file is part of wolfSSL. (formerly known as CyaSSL)
|
||||
*
|
||||
* wolfSSL 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.
|
||||
*
|
||||
* wolfSSL 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
|
||||
*/
|
||||
|
||||
#ifdef NO_INLINE
|
||||
#include <wolfssl/wolfcrypt/misc.h>
|
||||
#endif
|
||||
#include <wolfssl/options.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <termios.h>
|
||||
#include <wolfssl/wolfcrypt/ascon.h>
|
||||
#include <wolfssl/wolfcrypt/sha256.h>
|
||||
#include <wolfssl/wolfcrypt/random.h>
|
||||
#include <wolfssl/wolfcrypt/pwdbased.h>
|
||||
|
||||
#define ASCON_AEAD128_RATE 16
|
||||
#define SALT_SIZE 8
|
||||
#define AD_SIZE 32
|
||||
|
||||
static const byte nonce[ASCON_AEAD128_NONCE_SZ] = {
|
||||
0x00, 0x01, 0x02, 0x03,
|
||||
0x04, 0x05, 0x06, 0x07,
|
||||
0x08, 0x09, 0x0A, 0x0B,
|
||||
0x0C, 0x0D, 0x0E, 0x0F
|
||||
};
|
||||
|
||||
static const byte ad[AD_SIZE] = {
|
||||
0x00, 0x01, 0x02, 0x03,
|
||||
0x04, 0x05, 0x06, 0x07,
|
||||
0x08, 0x09, 0x0A, 0x0B,
|
||||
0x0C, 0x0D, 0x0E, 0x0F,
|
||||
0x10, 0x11, 0x12, 0x13,
|
||||
0x14, 0x15, 0x16, 0x17,
|
||||
0x18, 0x19, 0x01A, 0x1B,
|
||||
0x1C, 0x1D, 0x1E, 0x1F,
|
||||
};
|
||||
|
||||
void MemFree(wc_AsconAEAD128 *ascon, byte *key, int size, FILE *inFile, FILE *outFile, WC_RNG rng, byte *input, byte *output, int length) {
|
||||
memset(input, 0, length);
|
||||
memset(output, 0, length);
|
||||
memset(key, 0, size);
|
||||
free(input);
|
||||
free(output);
|
||||
free(key);
|
||||
fclose(inFile);
|
||||
fclose(outFile);
|
||||
wc_FreeRng(&rng);
|
||||
wc_AsconAEAD128_Free(ascon);
|
||||
}
|
||||
|
||||
/*
|
||||
* Makes a cryptographically secure key by stretching a user entered key
|
||||
*/
|
||||
int GenerateKey(WC_RNG* rng, byte* key, int size, byte* salt)
|
||||
{
|
||||
|
||||
int ret = wc_RNG_GenerateBlock(rng, salt, SALT_SIZE);
|
||||
if (ret != 0)
|
||||
return -1020;
|
||||
|
||||
/* stretches key */
|
||||
ret = wc_PBKDF2(key, key, strlen((const char*)key), salt, SALT_SIZE, 4096,
|
||||
size, WC_SHA256);
|
||||
if (ret != 0)
|
||||
return -1030;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Encrypts a file using Ascon
|
||||
*/
|
||||
int AsconEncrypt(wc_AsconAEAD128* ascon, byte* key, int size, FILE* inFile, FILE* outFile)
|
||||
{
|
||||
WC_RNG rng;
|
||||
byte salt[SALT_SIZE] = {0};
|
||||
byte tag[ASCON_AEAD128_TAG_SZ] = {0};
|
||||
|
||||
int ret = 0;
|
||||
|
||||
fseek(inFile, 0, SEEK_END);
|
||||
const int inputLength = ftell(inFile);
|
||||
fseek(inFile, 0, SEEK_SET);
|
||||
|
||||
byte* input = malloc(inputLength);
|
||||
byte* output = malloc(inputLength);
|
||||
|
||||
while (ret == 0) { // to avoid memory leakage in case of an error
|
||||
ret = wc_InitRng(&rng);
|
||||
if (ret != 0) {
|
||||
printf("Failed to initialize random number generator\n");
|
||||
ret = -1030;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* reads from inFile and writes whatever is there to the input array */
|
||||
ret = fread(input, 1, inputLength, inFile);
|
||||
if (ret == 0) {
|
||||
printf("Input file does not exist.\n");
|
||||
ret = -1010;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* stretches key to fit size */
|
||||
ret = GenerateKey(&rng, key, size, salt);
|
||||
if (ret != 0) {
|
||||
ret = -1040;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* sets key */
|
||||
ret = wc_AsconAEAD128_SetKey(ascon, key);
|
||||
if (ret != 0) {
|
||||
ret = -1001;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* sets nonce */
|
||||
ret = wc_AsconAEAD128_SetNonce(ascon, nonce);
|
||||
if (ret != 0) {
|
||||
ret = -1001;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
/* sets additional data */
|
||||
ret = wc_AsconAEAD128_SetAD(ascon, ad, AD_SIZE);
|
||||
if (ret != 0) {
|
||||
ret = -1001;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
/* encrypts the message to the output based on input length */
|
||||
ret = wc_AsconAEAD128_EncryptUpdate(ascon, output, input, inputLength);
|
||||
if (ret != 0) {
|
||||
ret = -1005;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Finalize encryption and generate tag */
|
||||
ret = wc_AsconAEAD128_EncryptFinal(ascon, tag);
|
||||
if (ret != 0) {
|
||||
ret = -1005;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* writes to outFile */
|
||||
fwrite(salt, 1, SALT_SIZE, outFile);
|
||||
fwrite(tag, 1, ASCON_AEAD128_TAG_SZ, outFile);
|
||||
fwrite(output, 1, inputLength, outFile);
|
||||
break;
|
||||
}
|
||||
/* closes the opened files and frees the memory*/
|
||||
MemFree(ascon, key, size, inFile, outFile, rng, input, output, inputLength);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Decrypts a file using Ascon
|
||||
*/
|
||||
int AsconDecrypt(wc_AsconAEAD128* ascon, byte* key, int size, FILE* inFile, FILE* outFile)
|
||||
{
|
||||
WC_RNG rng;
|
||||
byte salt[SALT_SIZE] = {0};
|
||||
byte tag[ASCON_AEAD128_TAG_SZ] = {0};
|
||||
|
||||
int i = 0;
|
||||
int ret = 0;
|
||||
|
||||
|
||||
fseek(inFile, 0, SEEK_END);
|
||||
int length = ftell(inFile);
|
||||
fseek(inFile, 0, SEEK_SET);
|
||||
const int aSize = length;
|
||||
|
||||
byte* input = malloc(aSize);
|
||||
byte* output = malloc(aSize);
|
||||
|
||||
while (ret == 0) {
|
||||
ret = wc_InitRng(&rng);
|
||||
if (ret != 0) {
|
||||
printf("Failed to initialize random number generator\n");
|
||||
ret = -1030;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* reads from inFile and writes whatever is there to the input array */
|
||||
ret = fread(input, 1, length, inFile);
|
||||
if (ret == 0) {
|
||||
printf("Input file does not exist.\n");
|
||||
ret = -1010;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* finds salt from input message */
|
||||
for (i = 0; i < SALT_SIZE; i++) {
|
||||
salt[i] = input[i];
|
||||
}
|
||||
|
||||
/* finds tag from input message */
|
||||
for (i = SALT_SIZE; i < ASCON_AEAD128_TAG_SZ + SALT_SIZE; i++) {
|
||||
tag[i - SALT_SIZE] = input[i];
|
||||
}
|
||||
|
||||
/* replicates old key if keys match */
|
||||
ret = wc_PBKDF2(key, key, strlen((const char*)key), salt, SALT_SIZE, 4096,
|
||||
size, WC_SHA256);
|
||||
if (ret != 0) {
|
||||
ret = -1050;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
/* sets key */
|
||||
ret = wc_AsconAEAD128_SetKey(ascon, key);
|
||||
if (ret != 0) {
|
||||
ret = -1001;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
/* sets nonce */
|
||||
ret = wc_AsconAEAD128_SetNonce(ascon, nonce);
|
||||
if (ret != 0) {
|
||||
ret = -1001;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* sets additional data */
|
||||
ret = wc_AsconAEAD128_SetAD(ascon, ad, AD_SIZE);
|
||||
if (ret != 0) {
|
||||
ret = -1001;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* change length to remove salt/tag block from being decrypted */
|
||||
length -= (ASCON_AEAD128_TAG_SZ + SALT_SIZE);
|
||||
for (i = 0; i < length; i++) {
|
||||
/* shifts message: ignores salt/tag on message*/
|
||||
input[i] = input[i + (ASCON_AEAD128_TAG_SZ + SALT_SIZE)];
|
||||
}
|
||||
|
||||
/* decrypts the message to output based on input length */
|
||||
ret = wc_AsconAEAD128_DecryptUpdate(ascon, output, input, length);
|
||||
if (ret != 0) {
|
||||
ret = -1006;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Finalize decryption and verify tag */
|
||||
ret = wc_AsconAEAD128_DecryptFinal(ascon, tag);
|
||||
if (ret != 0) {
|
||||
ret = -1001; // ASCON_AUTH_E
|
||||
continue;
|
||||
}
|
||||
|
||||
/* writes output to the outFile based on shortened length */
|
||||
fwrite(output, 1, length, outFile);
|
||||
break;
|
||||
}
|
||||
MemFree(ascon, key, size, inFile, outFile, rng, input, output, aSize);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* help message
|
||||
*/
|
||||
void help()
|
||||
{
|
||||
printf("\n~~~~~~~~~~~~~~~~~~~~|Help|~~~~~~~~~~~~~~~~~~~~~\n\n");
|
||||
printf("Usage: ./ascon-encrypt <-option> <file.in> "
|
||||
"<file.out>\n\n");
|
||||
printf("Options\n");
|
||||
printf("-d Decryption\n-e Encryption\n-h Help\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* temporarily disables echoing in terminal for secure key input
|
||||
*/
|
||||
int NoEcho(char* key)
|
||||
{
|
||||
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: tcsetattr failed to disable terminal echo\n");
|
||||
return -1060;
|
||||
}
|
||||
|
||||
printf("Unique Password: ");
|
||||
if (fgets(key, ASCON_AEAD128_KEY_SZ, stdin) == NULL) {
|
||||
printf("Error: fgets failed to retrieve secure key input\n");
|
||||
return -1070;
|
||||
}
|
||||
key[strlen(key) - 1] = 0;
|
||||
|
||||
/* restore terminal */
|
||||
if (tcsetattr(fileno(stdin), TCSANOW, &oflags) != 0) {
|
||||
printf("Error: tcsetattr failed to enable terminal echo\n");
|
||||
return -1080;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
wc_AsconAEAD128* ascon = NULL;
|
||||
byte* key = NULL; /* user entered key */
|
||||
FILE* inFile = NULL;
|
||||
FILE* outFile = NULL;
|
||||
|
||||
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;
|
||||
char choice = 'n';
|
||||
|
||||
|
||||
|
||||
while ((option = getopt(argc, argv, "dei:o:h")) != -1) {
|
||||
switch (option) {
|
||||
case 'd': /* if entered decrypt */
|
||||
choice = 'd';
|
||||
break;
|
||||
case 'e': /* if entered encrypt */
|
||||
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 (choice != 'n') {
|
||||
key = malloc(ASCON_AEAD128_KEY_SZ); /* sets size memory of key */
|
||||
ret = NoEcho((char*)key);
|
||||
ascon = wc_AsconAEAD128_New();
|
||||
if (ascon == NULL) {
|
||||
free(key);
|
||||
printf("Error: initiating Ascon object failed\n");
|
||||
return -1030;
|
||||
}
|
||||
if (choice == 'e')
|
||||
AsconEncrypt(ascon, key, ASCON_AEAD128_KEY_SZ, inFile, outFile);
|
||||
else if (choice == 'd')
|
||||
AsconDecrypt(ascon, key, ASCON_AEAD128_KEY_SZ, inFile, outFile);
|
||||
}
|
||||
else if (choice == 'n') {
|
||||
printf("Must select either -e[16] or -d[16] for encryption and decryption\n");
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -0,0 +1,116 @@
|
|||
/* Ascon-Hash256.c
|
||||
*
|
||||
* Copyright (C) 2006-2020 wolfSSL Inc.
|
||||
*
|
||||
* This file is part of wolfSSL.
|
||||
*
|
||||
* wolfSSL 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.
|
||||
*
|
||||
* wolfSSL 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-1335, USA
|
||||
*/
|
||||
|
||||
|
||||
#ifdef NO_INLINE
|
||||
#include <wolfssl/wolfcrypt/misc.h>
|
||||
#endif
|
||||
#include <wolfssl/options.h>
|
||||
#include <wolfssl/wolfcrypt/settings.h>
|
||||
#include <wolfssl/ssl.h>
|
||||
#include <wolfssl/wolfcrypt/ascon.h>
|
||||
|
||||
#ifdef HAVE_ASCON
|
||||
void usage(void)
|
||||
{
|
||||
printf("./Ascon-Hash256 <file to hash>\n");
|
||||
exit(-99);
|
||||
}
|
||||
#endif
|
||||
|
||||
void free_mem(wc_AsconHash256 *asconHash, byte *hash, byte *rawInput, FILE *inputStream) {
|
||||
fclose(inputStream);
|
||||
free(rawInput);
|
||||
free(hash);
|
||||
wc_AsconHash256_Free(asconHash);
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
int ret = -1;
|
||||
#ifdef HAVE_ASCON
|
||||
wc_AsconHash256* asconHash = NULL;
|
||||
byte* hash = NULL;
|
||||
byte* rawInput = NULL;
|
||||
FILE* inputStream = NULL;
|
||||
char* fName = NULL;
|
||||
int fileLength = 0;
|
||||
|
||||
if (argc < 2)
|
||||
usage();
|
||||
fName = argv[1];
|
||||
printf("Hash input file %s\n", fName);
|
||||
|
||||
inputStream = fopen(fName, "rb");
|
||||
if (inputStream == NULL) {
|
||||
printf("ERROR: Unable to open file\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* find length of the file */
|
||||
fseek(inputStream, 0, SEEK_END);
|
||||
fileLength = (int) ftell(inputStream);
|
||||
fseek(inputStream, 0, SEEK_SET);
|
||||
|
||||
/* Create and initialize hash context */
|
||||
asconHash = wc_AsconHash256_New();
|
||||
if (asconHash == NULL) {
|
||||
printf("ERROR: Unable to create the hash context\n");
|
||||
}
|
||||
|
||||
hash = (byte*) malloc(ASCON_HASH256_SZ);
|
||||
if (hash == NULL) {
|
||||
printf("ERROR: Unable to allocate space for hash value\n");
|
||||
}
|
||||
|
||||
rawInput = (byte*) malloc(fileLength);
|
||||
if (rawInput == NULL) {
|
||||
printf("ERROR: Unable to allocate space for raw input\n");
|
||||
}
|
||||
|
||||
/* Read input file into a byte array*/
|
||||
ret = fread(rawInput, 1, fileLength, inputStream);
|
||||
if (ret != fileLength) {
|
||||
printf("ERROR: Failed to read the size of input file\n");
|
||||
}
|
||||
|
||||
ret = wc_AsconHash256_Update(asconHash, rawInput, fileLength);
|
||||
if (ret != 0) {
|
||||
printf("ERROR: Hash update failed\n");
|
||||
}
|
||||
|
||||
ret = wc_AsconHash256_Final(asconHash, hash);
|
||||
if (ret != 0) {
|
||||
printf("ERROR: Hash operation failed");
|
||||
}
|
||||
else {
|
||||
printf("Hash result is: ");
|
||||
for (int i = 0; i < ASCON_HASH256_SZ; i++)
|
||||
printf("%02x", hash[i]);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
free_mem(asconHash, hash, rawInput, inputStream);
|
||||
#else
|
||||
printf("Please enable Ascon-Hash256 (--enable-ascon --enable-experimental) in wolfCrypt\n");
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -37,6 +37,16 @@ LIBS+=$(STATIC_LIB)
|
|||
|
||||
## Usage
|
||||
|
||||
### `Ascon-hash`
|
||||
|
||||
This example shows how to hash an input file using Ascon-Hash256.
|
||||
|
||||
```
|
||||
./Ascon-Hash256 input.txt
|
||||
Hash input file input.txt
|
||||
Hash result is: cfef206d17eff5187fe5b5451326d5489eab2d65fe71faab84a6d9300ef7c6f8
|
||||
```
|
||||
|
||||
### `sha256-hash`
|
||||
|
||||
This example shows how to hash an input file using SHA-256.
|
||||
|
|
|
|||
Loading…
Reference in New Issue