From d0008102060ac564d6490f11c69dd5aa007d943d Mon Sep 17 00:00:00 2001 From: Hosam Elkoulak Date: Fri, 17 Apr 2026 16:33:20 +0200 Subject: [PATCH 1/3] 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 --- crypto/README.md | 2 + crypto/ascon/Makefile | 12 + crypto/ascon/README.md | 20 ++ crypto/ascon/ascon-file-encrypt.c | 404 ++++++++++++++++++++++++++++++ hash/Ascon-Hash256.c | 116 +++++++++ hash/README.md | 10 + 6 files changed, 564 insertions(+) create mode 100644 crypto/ascon/Makefile create mode 100644 crypto/ascon/README.md create mode 100644 crypto/ascon/ascon-file-encrypt.c create mode 100644 hash/Ascon-Hash256.c diff --git a/crypto/README.md b/crypto/README.md index 882e4e0b3..656941f46 100644 --- a/crypto/README.md +++ b/crypto/README.md @@ -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. diff --git a/crypto/ascon/Makefile b/crypto/ascon/Makefile new file mode 100644 index 000000000..27ed4ffad --- /dev/null +++ b/crypto/ascon/Makefile @@ -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 diff --git a/crypto/ascon/README.md b/crypto/ascon/README.md new file mode 100644 index 000000000..ef9792d6a --- /dev/null +++ b/crypto/ascon/README.md @@ -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 -o + + 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'. diff --git a/crypto/ascon/ascon-file-encrypt.c b/crypto/ascon/ascon-file-encrypt.c new file mode 100644 index 000000000..cb75aca28 --- /dev/null +++ b/crypto/ascon/ascon-file-encrypt.c @@ -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 +#endif +#include +#include +#include +#include +#include +#include +#include +#include + +#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> " + "\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; +} diff --git a/hash/Ascon-Hash256.c b/hash/Ascon-Hash256.c new file mode 100644 index 000000000..bf2d24c12 --- /dev/null +++ b/hash/Ascon-Hash256.c @@ -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 +#endif +#include +#include +#include +#include + +#ifdef HAVE_ASCON +void usage(void) +{ + printf("./Ascon-Hash256 \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; +} diff --git a/hash/README.md b/hash/README.md index 6a5e65cd9..2c0389510 100644 --- a/hash/README.md +++ b/hash/README.md @@ -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. From ae042f171ccd739880c3ee64446f55687fbd733d Mon Sep 17 00:00:00 2001 From: Hosam Elkoulak Date: Fri, 1 May 2026 08:33:16 +0200 Subject: [PATCH 2/3] Fixes for ascon-file-encrypt --- crypto/ascon/Makefile | 2 +- crypto/ascon/ascon-file-encrypt.c | 283 ++++++++++++++++++------------ 2 files changed, 172 insertions(+), 113 deletions(-) diff --git a/crypto/ascon/Makefile b/crypto/ascon/Makefile index 27ed4ffad..be042f9a2 100644 --- a/crypto/ascon/Makefile +++ b/crypto/ascon/Makefile @@ -4,7 +4,7 @@ WOLFSSL_INSTALL_DIR=/usr/local LIBS=-L$(WOLFSSL_INSTALL_DIR)/lib -lwolfssl ascon-file-encrypt: ascon-file-encrypt.o - $(CC) -o $@ $^ $(CFLAGS) $(LIBS) + $(CC) -o $@ $^ $(CFLAGS) $(LIBS) .PHONY: clean diff --git a/crypto/ascon/ascon-file-encrypt.c b/crypto/ascon/ascon-file-encrypt.c index cb75aca28..dc69e055c 100644 --- a/crypto/ascon/ascon-file-encrypt.c +++ b/crypto/ascon/ascon-file-encrypt.c @@ -34,13 +34,7 @@ #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 -}; +#define FILE_HEADER_SIZE 40 static const byte ad[AD_SIZE] = { 0x00, 0x01, 0x02, 0x03, @@ -53,17 +47,34 @@ static const byte ad[AD_SIZE] = { 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); +void MemFree(wc_AsconAEAD128 *ascon, byte *key, int size, FILE *inFile, FILE *outFile, WC_RNG* rng, byte *input, byte *output, int length, int rngInit) { + if (input != NULL) { + memset(input, 0, length); + free(input); + } + if (output != NULL) { + memset(output, 0, length); + free(output); + } + if (outFile != NULL) { + fclose(outFile); + } + if (inFile != NULL) { + fclose(inFile); + } + if (key != NULL) { + memset(key, 0, size); + free(key); + } + /* Those two functions check validity of pointer before freeing it*/ + if (rngInit && rng != NULL) { + wc_FreeRng(rng); + } + + if (ascon != NULL) { + wc_AsconAEAD128_Free(ascon); + } + } /* @@ -90,9 +101,11 @@ int GenerateKey(WC_RNG* rng, byte* key, int size, byte* salt) */ 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}; + WC_RNG rng; + int rngInit = 0; + byte nonce[ASCON_AEAD128_NONCE_SZ] = {0}; + byte salt[SALT_SIZE] = {0}; + byte tag[ASCON_AEAD128_TAG_SZ] = {0}; int ret = 0; @@ -110,6 +123,7 @@ int AsconEncrypt(wc_AsconAEAD128* ascon, byte* key, int size, FILE* inFile, FILE ret = -1030; continue; } + rngInit = 1; /* reads from inFile and writes whatever is there to the input array */ ret = fread(input, 1, inputLength, inFile); @@ -133,6 +147,13 @@ int AsconEncrypt(wc_AsconAEAD128* ascon, byte* key, int size, FILE* inFile, FILE continue; } + /* Generate random nonce for each encryption */ + ret = wc_RNG_GenerateBlock(&rng, nonce, ASCON_AEAD128_NONCE_SZ); + if (ret != 0) { + ret = -1020; + continue; + } + /* sets nonce */ ret = wc_AsconAEAD128_SetNonce(ascon, nonce); if (ret != 0) { @@ -165,12 +186,13 @@ int AsconEncrypt(wc_AsconAEAD128* ascon, byte* key, int size, FILE* inFile, FILE /* writes to outFile */ fwrite(salt, 1, SALT_SIZE, outFile); + fwrite(nonce, 1, ASCON_AEAD128_NONCE_SZ, 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); + MemFree(ascon, key, size, inFile, outFile, &rng, input, output, inputLength, rngInit); return ret; } @@ -179,11 +201,11 @@ int AsconEncrypt(wc_AsconAEAD128* ascon, byte* key, int size, FILE* inFile, FILE */ 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; + WC_RNG rng; + int rngInit = 0; + byte nonce[ASCON_AEAD128_NONCE_SZ] = {0}; + byte salt[SALT_SIZE] = {0}; + byte tag[ASCON_AEAD128_TAG_SZ] = {0}; int ret = 0; @@ -195,89 +217,102 @@ int AsconDecrypt(wc_AsconAEAD128* ascon, byte* key, int size, FILE* inFile, FILE byte* input = malloc(aSize); byte* output = malloc(aSize); - while (ret == 0) { + while (ret == 0) { // While loop is used as a kind of jump ret = wc_InitRng(&rng); if (ret != 0) { printf("Failed to initialize random number generator\n"); ret = -1030; continue; } + rngInit = 1; + /* 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"); + if (ret != length) { + printf("Error while reading input file.\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)]; + int i = 0; + + if (length > FILE_HEADER_SIZE) { + + /* finds salt from input message */ + for (; i < SALT_SIZE; i++) { + salt[i] = input[i]; + } + + /* finds nonce from input message */ + for (; i < ASCON_AEAD128_NONCE_SZ + SALT_SIZE; i++) { + nonce[i - SALT_SIZE] = input[i]; + } + + /* finds tag from input message */ + for (; i < FILE_HEADER_SIZE; i++) { + tag[i - SALT_SIZE - ASCON_AEAD128_NONCE_SZ] = 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/nonce/tag block from being decrypted */ + length -= FILE_HEADER_SIZE; + for (int j = 0; j < length; j++) { + /* shifts message: ignores salt/nonce/tag on message*/ + input[j] = input[j + FILE_HEADER_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; + } else { + printf("Invalid length of input file\n"); + break; } - - /* 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); + MemFree(ascon, key, size, inFile, outFile, &rng, input, output, aSize, rngInit); return ret; } @@ -287,10 +322,11 @@ int AsconDecrypt(wc_AsconAEAD128* ascon, byte* key, int size, FILE* inFile, FILE void help() { printf("\n~~~~~~~~~~~~~~~~~~~~|Help|~~~~~~~~~~~~~~~~~~~~~\n\n"); - printf("Usage: ./ascon-encrypt <-option> " - "\n\n"); + printf("Usage: ./ascon-file-encrypt -d|-e -i " + "-o \n\n"); printf("Options\n"); - printf("-d Decryption\n-e Encryption\n-h Help\n"); + printf("-d Decryption\n-e Encryption\n-i Input file\n"); + printf("-o Output file\n-h Help\n"); } /* @@ -299,6 +335,7 @@ void help() int NoEcho(char* key) { struct termios oflags, nflags; + int ret = 0; /* disabling echo */ tcgetattr(fileno(stdin), &oflags); @@ -306,24 +343,32 @@ int NoEcho(char* key) 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; - } + while (ret == 0) { + if (tcsetattr(fileno(stdin), TCSANOW, &nflags) != 0) { + printf("Error: tcsetattr failed to disable terminal echo\n"); + ret = -1060; + continue; + } - printf("Unique Password: "); - if (fgets(key, ASCON_AEAD128_KEY_SZ, stdin) == NULL) { - printf("Error: fgets failed to retrieve secure key input\n"); - return -1070; + printf("Unique Password: "); + if (fgets(key, ASCON_AEAD128_KEY_SZ, stdin) == NULL) { + printf("Error: fgets failed to retrieve secure key input\n"); + ret = -1070; + continue; + } + + if (key[strlen(key) - 1] == '\n') { + key[strlen(key) - 1] = 0; + } + break; } - key[strlen(key) - 1] = 0; - /* restore terminal */ + /* restore terminal regardless */ if (tcsetattr(fileno(stdin), TCSANOW, &oflags) != 0) { printf("Error: tcsetattr failed to enable terminal echo\n"); - return -1080; + ret = -1080; } - return 0; + return ret; } @@ -360,12 +405,20 @@ int main(int argc, char** argv) case 'i': /* input file */ in = optarg; inCheck = 1; - inFile = fopen(in, "r"); + inFile = fopen(in, "rb"); + if (inFile == NULL) { + printf("Error: unable to open input file\n"); + return -1010; + } break; case 'o': /* output file */ out = optarg; outCheck = 1; - outFile = fopen(out, "w"); + outFile = fopen(out, "wb"); + if (outFile == NULL) { + printf("Error: unable to open output file\n"); + return -1010; + } break; case '?': if (optopt) { @@ -384,6 +437,12 @@ int main(int argc, char** argv) else if (choice != 'n') { key = malloc(ASCON_AEAD128_KEY_SZ); /* sets size memory of key */ + if (key == NULL) { + printf("Could not allocate memory for key\n"); + return -1010; + } + // Assign default value for key + memcpy((char*)key, "0123456789abcdef", ASCON_AEAD128_KEY_SZ); ret = NoEcho((char*)key); ascon = wc_AsconAEAD128_New(); if (ascon == NULL) { From 09d5072fdb17459f3e4be46da3e52ade81646301 Mon Sep 17 00:00:00 2001 From: Hosam Elkoulak Date: Fri, 1 May 2026 09:07:21 +0200 Subject: [PATCH 3/3] Fixes for Ascon-Hash256 --- hash/Ascon-Hash256.c | 113 ++++++++++++++++++++++++++----------------- hash/README.md | 2 +- 2 files changed, 69 insertions(+), 46 deletions(-) diff --git a/hash/Ascon-Hash256.c b/hash/Ascon-Hash256.c index bf2d24c12..13ade4118 100644 --- a/hash/Ascon-Hash256.c +++ b/hash/Ascon-Hash256.c @@ -37,15 +37,23 @@ void usage(void) #endif void free_mem(wc_AsconHash256 *asconHash, byte *hash, byte *rawInput, FILE *inputStream) { - fclose(inputStream); - free(rawInput); - free(hash); - wc_AsconHash256_Free(asconHash); + if (asconHash != NULL) { + wc_AsconHash256_Free(asconHash); + } + if (rawInput != NULL) { + free(rawInput); + } + if (inputStream != NULL) { + fclose(inputStream); + } + if (hash != NULL) { + free(hash); + } } int main(int argc, char** argv) { - int ret = -1; + int ret = 0; #ifdef HAVE_ASCON wc_AsconHash256* asconHash = NULL; byte* hash = NULL; @@ -59,55 +67,70 @@ int main(int argc, char** argv) 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; - } + while (1) { + inputStream = fopen(fName, "rb"); + if (inputStream == NULL) { + printf("ERROR: Unable to open file\n"); + ret = -1; + break; + } - /* find length of the file */ - fseek(inputStream, 0, SEEK_END); - fileLength = (int) ftell(inputStream); - fseek(inputStream, 0, SEEK_SET); + /* 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"); - } + /* Create and initialize hash context */ + asconHash = wc_AsconHash256_New(); + if (asconHash == NULL) { + printf("ERROR: Unable to create the hash context\n"); + ret = -1; + break; + } - hash = (byte*) malloc(ASCON_HASH256_SZ); - if (hash == NULL) { - printf("ERROR: Unable to allocate space for hash value\n"); - } + hash = (byte*) malloc(ASCON_HASH256_SZ); + if (hash == NULL) { + printf("ERROR: Unable to allocate space for hash value\n"); + ret = -1; + break; + } - rawInput = (byte*) malloc(fileLength); - if (rawInput == NULL) { - printf("ERROR: Unable to allocate space for raw input\n"); - } + rawInput = (byte*) malloc(fileLength); + if (rawInput == NULL) { + printf("ERROR: Unable to allocate space for raw input\n"); + ret = -1; + break; + } - /* 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"); - } + /* Read input file into a byte array*/ + size_t read = fread(rawInput, 1, fileLength, inputStream); + if (read != fileLength) { + printf("ERROR: Failed to read the size of input file\n"); + ret = -1; + break; + } - ret = wc_AsconHash256_Update(asconHash, rawInput, fileLength); - if (ret != 0) { - printf("ERROR: Hash update failed\n"); - } + ret = wc_AsconHash256_Update(asconHash, rawInput, fileLength); + if (ret != 0) { + printf("ERROR: Hash update failed\n"); + ret = -1; + break; + } - 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"); + ret = wc_AsconHash256_Final(asconHash, hash); + if (ret != 0) { + printf("ERROR: Hash operation failed"); + ret = -1; + break; + } + break; } + 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"); diff --git a/hash/README.md b/hash/README.md index 2c0389510..996bd0fe5 100644 --- a/hash/README.md +++ b/hash/README.md @@ -37,7 +37,7 @@ LIBS+=$(STATIC_LIB) ## Usage -### `Ascon-hash` +### `Ascon-Hash256` This example shows how to hash an input file using Ascon-Hash256.