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-Hash256
pull/573/head
Hosam Elkoulak 2026-04-17 16:33:20 +02:00
parent bfdda5612e
commit d000810206
6 changed files with 564 additions and 0 deletions

View File

@ -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.

View File

@ -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

View File

@ -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'.

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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.