mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2025-08-02 04:04:39 +02:00
Initial ASCON hash256 and AEAD128 support based on NIST SP 800-232 ipd
Implemented based on the NIST Initial Public Draft "NIST SP 800-232 ipd". Testing based on KAT's available at https://github.com/ascon/ascon-c. Added configuration for testing in github action.
This commit is contained in:
1
.github/workflows/os-check.yml
vendored
1
.github/workflows/os-check.yml
vendored
@@ -40,6 +40,7 @@ jobs:
|
|||||||
--enable-dtls-mtu',
|
--enable-dtls-mtu',
|
||||||
'--enable-dtls --enable-dtlscid --enable-dtls13 --enable-secure-renegotiation
|
'--enable-dtls --enable-dtlscid --enable-dtls13 --enable-secure-renegotiation
|
||||||
--enable-psk --enable-aesccm --enable-nullcipher CPPFLAGS=-DWOLFSSL_STATIC_RSA',
|
--enable-psk --enable-aesccm --enable-nullcipher CPPFLAGS=-DWOLFSSL_STATIC_RSA',
|
||||||
|
'--enable-ascon',
|
||||||
]
|
]
|
||||||
name: make check
|
name: make check
|
||||||
if: github.repository_owner == 'wolfssl'
|
if: github.repository_owner == 'wolfssl'
|
||||||
|
@@ -564,6 +564,7 @@ WOLFSSL_ALLOW_TLS_SHA1
|
|||||||
WOLFSSL_ALTERNATIVE_DOWNGRADE
|
WOLFSSL_ALTERNATIVE_DOWNGRADE
|
||||||
WOLFSSL_ALT_NAMES_NO_REV
|
WOLFSSL_ALT_NAMES_NO_REV
|
||||||
WOLFSSL_ARM_ARCH_NEON_64BIT
|
WOLFSSL_ARM_ARCH_NEON_64BIT
|
||||||
|
WOLFSSL_ASCON_UNROLL
|
||||||
WOLFSSL_ASNC_CRYPT
|
WOLFSSL_ASNC_CRYPT
|
||||||
WOLFSSL_ASN_EXTRA
|
WOLFSSL_ASN_EXTRA
|
||||||
WOLFSSL_ASN_INT_LEAD_0_ANY
|
WOLFSSL_ASN_INT_LEAD_0_ANY
|
||||||
|
12
configure.ac
12
configure.ac
@@ -6055,6 +6055,17 @@ then
|
|||||||
AM_CFLAGS="$AM_CFLAGS -DHAVE_XCHACHA"
|
AM_CFLAGS="$AM_CFLAGS -DHAVE_XCHACHA"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# ASCON
|
||||||
|
AC_ARG_ENABLE([ascon],
|
||||||
|
[AS_HELP_STRING([--enable-ascon],[Enable ASCON (default: disabled).])],
|
||||||
|
[ ENABLED_ASCON=$enableval ],
|
||||||
|
[ ENABLED_ASCON=no]
|
||||||
|
)
|
||||||
|
|
||||||
|
if test "$ENABLED_ASCON" = "yes"
|
||||||
|
then
|
||||||
|
AM_CFLAGS="$AM_CFLAGS -DHAVE_ASCON"
|
||||||
|
fi
|
||||||
|
|
||||||
# Hash DRBG
|
# Hash DRBG
|
||||||
AC_ARG_ENABLE([hashdrbg],
|
AC_ARG_ENABLE([hashdrbg],
|
||||||
@@ -10073,6 +10084,7 @@ AM_CONDITIONAL([BUILD_SHA3],[test "x$ENABLED_SHA3" != "xno" || test "x$ENABLED_U
|
|||||||
AM_CONDITIONAL([BUILD_POLY1305],[test "x$ENABLED_POLY1305" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"])
|
AM_CONDITIONAL([BUILD_POLY1305],[test "x$ENABLED_POLY1305" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"])
|
||||||
AM_CONDITIONAL([BUILD_CHACHA],[test "x$ENABLED_CHACHA" = "xyes" || test "x$ENABLED_CHACHA" = "xnoasm" || test "x$ENABLED_USERSETTINGS" = "xyes"])
|
AM_CONDITIONAL([BUILD_CHACHA],[test "x$ENABLED_CHACHA" = "xyes" || test "x$ENABLED_CHACHA" = "xnoasm" || test "x$ENABLED_USERSETTINGS" = "xyes"])
|
||||||
AM_CONDITIONAL([BUILD_XCHACHA],[test "x$ENABLED_XCHACHA" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"])
|
AM_CONDITIONAL([BUILD_XCHACHA],[test "x$ENABLED_XCHACHA" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"])
|
||||||
|
AM_CONDITIONAL([BUILD_ASCON],[test "x$ENABLED_ASCON" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"])
|
||||||
AM_CONDITIONAL([BUILD_SM2],[test "x$ENABLED_SM2" != "xno" || test "x$ENABLED_USERSETTINGS" = "xyes"])
|
AM_CONDITIONAL([BUILD_SM2],[test "x$ENABLED_SM2" != "xno" || test "x$ENABLED_USERSETTINGS" = "xyes"])
|
||||||
AM_CONDITIONAL([BUILD_SM3],[test "x$ENABLED_SM3" != "xno" || test "x$ENABLED_USERSETTINGS" = "xyes"])
|
AM_CONDITIONAL([BUILD_SM3],[test "x$ENABLED_SM3" != "xno" || test "x$ENABLED_USERSETTINGS" = "xyes"])
|
||||||
AM_CONDITIONAL([BUILD_SM4],[test "x$ENABLED_SM4" != "xno" || test "x$ENABLED_USERSETTINGS" = "xyes"])
|
AM_CONDITIONAL([BUILD_SM4],[test "x$ENABLED_SM4" != "xno" || test "x$ENABLED_USERSETTINGS" = "xyes"])
|
||||||
|
@@ -1164,6 +1164,10 @@ src_libwolfssl@LIBSUFFIX@_la_SOURCES += wolfcrypt/src/chacha20_poly1305.c
|
|||||||
endif BUILD_POLY1305
|
endif BUILD_POLY1305
|
||||||
endif BUILD_CHACHA
|
endif BUILD_CHACHA
|
||||||
|
|
||||||
|
if BUILD_ASCON
|
||||||
|
src_libwolfssl@LIBSUFFIX@_la_SOURCES += wolfcrypt/src/ascon.c
|
||||||
|
endif
|
||||||
|
|
||||||
if !BUILD_INLINE
|
if !BUILD_INLINE
|
||||||
src_libwolfssl@LIBSUFFIX@_la_SOURCES += wolfcrypt/src/misc.c
|
src_libwolfssl@LIBSUFFIX@_la_SOURCES += wolfcrypt/src/misc.c
|
||||||
endif
|
endif
|
||||||
|
@@ -553,6 +553,10 @@
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_ASCON
|
||||||
|
#include <wolfssl/wolfcrypt/ascon.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_FIPS
|
#ifdef HAVE_FIPS
|
||||||
#include <wolfssl/wolfcrypt/fips_test.h>
|
#include <wolfssl/wolfcrypt/fips_test.h>
|
||||||
|
|
||||||
@@ -669,6 +673,7 @@
|
|||||||
#define BENCH_BLAKE2B 0x00008000
|
#define BENCH_BLAKE2B 0x00008000
|
||||||
#define BENCH_BLAKE2S 0x00010000
|
#define BENCH_BLAKE2S 0x00010000
|
||||||
#define BENCH_SM3 0x00020000
|
#define BENCH_SM3 0x00020000
|
||||||
|
#define BENCH_ASCON_HASH256 0x00040000
|
||||||
|
|
||||||
/* MAC algorithms. */
|
/* MAC algorithms. */
|
||||||
#define BENCH_CMAC 0x00000001
|
#define BENCH_CMAC 0x00000001
|
||||||
@@ -949,6 +954,9 @@ static const bench_alg bench_digest_opt[] = {
|
|||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_BLAKE2S
|
#ifdef HAVE_BLAKE2S
|
||||||
{ "-blake2s", BENCH_BLAKE2S },
|
{ "-blake2s", BENCH_BLAKE2S },
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_ASCON
|
||||||
|
{ "-ascon-hash", BENCH_ASCON_HASH256 },
|
||||||
#endif
|
#endif
|
||||||
{ NULL, 0 }
|
{ NULL, 0 }
|
||||||
};
|
};
|
||||||
@@ -3515,6 +3523,10 @@ static void* benchmarks_do(void* args)
|
|||||||
if (bench_all || (bench_digest_algs & BENCH_BLAKE2S))
|
if (bench_all || (bench_digest_algs & BENCH_BLAKE2S))
|
||||||
bench_blake2s();
|
bench_blake2s();
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAVE_ASCON
|
||||||
|
if (bench_all || (bench_digest_algs & BENCH_ASCON_HASH256))
|
||||||
|
bench_ascon_hash();
|
||||||
|
#endif
|
||||||
#ifdef WOLFSSL_CMAC
|
#ifdef WOLFSSL_CMAC
|
||||||
if (bench_all || (bench_mac_algs & BENCH_CMAC)) {
|
if (bench_all || (bench_mac_algs & BENCH_CMAC)) {
|
||||||
bench_cmac(0);
|
bench_cmac(0);
|
||||||
@@ -7996,6 +8008,64 @@ void bench_blake2s(void)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_ASCON
|
||||||
|
void bench_ascon_hash(void)
|
||||||
|
{
|
||||||
|
wc_AsconHash256 ascon;
|
||||||
|
byte digest[ASCON_HASH256_SZ];
|
||||||
|
double start;
|
||||||
|
int ret = 0, i, count;
|
||||||
|
|
||||||
|
if (digest_stream) {
|
||||||
|
ret = wc_AsconHash256_Init(&ascon);
|
||||||
|
if (ret != 0) {
|
||||||
|
printf("wc_AsconHash256_Init failed, ret = %d\n", ret);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bench_stats_start(&count, &start);
|
||||||
|
do {
|
||||||
|
for (i = 0; i < numBlocks; i++) {
|
||||||
|
ret = wc_AsconHash256_Update(&ascon, bench_plain, bench_size);
|
||||||
|
if (ret != 0) {
|
||||||
|
printf("wc_AsconHash256_Update failed, ret = %d\n", ret);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ret = wc_AsconHash256_Final(&ascon, digest);
|
||||||
|
if (ret != 0) {
|
||||||
|
printf("wc_AsconHash256_Final failed, ret = %d\n", ret);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
count += i;
|
||||||
|
} while (bench_stats_check(start));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
bench_stats_start(&count, &start);
|
||||||
|
do {
|
||||||
|
for (i = 0; i < numBlocks; i++) {
|
||||||
|
ret = wc_AsconHash256_Init(&ascon);
|
||||||
|
if (ret != 0) {
|
||||||
|
printf("wc_AsconHash256_Init failed, ret = %d\n", ret);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ret = wc_AsconHash256_Update(&ascon, bench_plain, bench_size);
|
||||||
|
if (ret != 0) {
|
||||||
|
printf("wc_AsconHash256_Update failed, ret = %d\n", ret);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ret = wc_AsconHash256_Final(&ascon, digest);
|
||||||
|
if (ret != 0) {
|
||||||
|
printf("wc_AsconHash256_Final failed, ret = %d\n", ret);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
count += i;
|
||||||
|
} while (bench_stats_check(start));
|
||||||
|
}
|
||||||
|
bench_stats_sym_finish("ASCON hash", 0, count, bench_size, start, ret);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef WOLFSSL_CMAC
|
#ifdef WOLFSSL_CMAC
|
||||||
|
|
||||||
|
@@ -128,6 +128,7 @@ void bench_sakke(void);
|
|||||||
void bench_rng(void);
|
void bench_rng(void);
|
||||||
void bench_blake2b(void);
|
void bench_blake2b(void);
|
||||||
void bench_blake2s(void);
|
void bench_blake2s(void);
|
||||||
|
void bench_ascon_hash(void);
|
||||||
void bench_pbkdf2(void);
|
void bench_pbkdf2(void);
|
||||||
void bench_falconKeySign(byte level);
|
void bench_falconKeySign(byte level);
|
||||||
void bench_dilithiumKeySign(byte level);
|
void bench_dilithiumKeySign(byte level);
|
||||||
|
465
wolfcrypt/src/ascon.c
Normal file
465
wolfcrypt/src/ascon.c
Normal file
@@ -0,0 +1,465 @@
|
|||||||
|
/* ascon.c
|
||||||
|
*
|
||||||
|
* Copyright (C) 2006-2025 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 HAVE_CONFIG_H
|
||||||
|
#include <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <wolfssl/wolfcrypt/settings.h>
|
||||||
|
|
||||||
|
#ifdef HAVE_ASCON
|
||||||
|
|
||||||
|
#include <wolfssl/wolfcrypt/ascon.h>
|
||||||
|
#include <wolfssl/wolfcrypt/error-crypt.h>
|
||||||
|
#include <wolfssl/wolfcrypt/logging.h>
|
||||||
|
#ifdef NO_INLINE
|
||||||
|
#include <wolfssl/wolfcrypt/misc.h>
|
||||||
|
#else
|
||||||
|
#define WOLFSSL_MISC_INCLUDED
|
||||||
|
#include <wolfcrypt/src/misc.c>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Implementation of the ASCON AEAD and HASH algorithms. Based on the NIST
|
||||||
|
* Initial Public Draft "NIST SP 800-232 ipd" and reference implementation found
|
||||||
|
* at https://github.com/ascon/ascon-c.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TODO
|
||||||
|
* - Add support for big-endian systems
|
||||||
|
* - Add support for 32-bit and smaller systems */
|
||||||
|
|
||||||
|
#define MAX_ROUNDS 12
|
||||||
|
|
||||||
|
/* Table 4 */
|
||||||
|
static const byte round_constants[MAX_ROUNDS] = {
|
||||||
|
0xf0, 0xe1, 0xd2, 0xc3, 0xb4, 0xa5, 0x96, 0x87, 0x78, 0x69, 0x5a, 0x4b
|
||||||
|
};
|
||||||
|
|
||||||
|
static byte start_index(byte rounds)
|
||||||
|
{
|
||||||
|
switch (rounds) {
|
||||||
|
case 6:
|
||||||
|
return 6;
|
||||||
|
case 8:
|
||||||
|
return 4;
|
||||||
|
case 12:
|
||||||
|
return 0;
|
||||||
|
default:
|
||||||
|
WOLFSSL_MSG("Something went wrong in wolfCrypt logic. Wrong ASCON "
|
||||||
|
"rounds value.");
|
||||||
|
return MAX_ROUNDS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static WC_INLINE void ascon_round(AsconState* a, byte round)
|
||||||
|
{
|
||||||
|
AsconState tmp;
|
||||||
|
/* 2.6.1 Addition of Constants */
|
||||||
|
a->s64[2] ^= round_constants[round];
|
||||||
|
/* 2.6.2 Substitution Layer */
|
||||||
|
a->s64[0] ^= a->s64[4];
|
||||||
|
a->s64[4] ^= a->s64[3];
|
||||||
|
a->s64[2] ^= a->s64[1];
|
||||||
|
tmp.s64[0] = a->s64[0] ^ (~a->s64[1] & a->s64[2]);
|
||||||
|
tmp.s64[2] = a->s64[2] ^ (~a->s64[3] & a->s64[4]);
|
||||||
|
tmp.s64[4] = a->s64[4] ^ (~a->s64[0] & a->s64[1]);
|
||||||
|
tmp.s64[1] = a->s64[1] ^ (~a->s64[2] & a->s64[3]);
|
||||||
|
tmp.s64[3] = a->s64[3] ^ (~a->s64[4] & a->s64[0]);
|
||||||
|
tmp.s64[1] ^= tmp.s64[0];
|
||||||
|
tmp.s64[3] ^= tmp.s64[2];
|
||||||
|
tmp.s64[0] ^= tmp.s64[4];
|
||||||
|
tmp.s64[2] = ~tmp.s64[2];
|
||||||
|
/* 2.6.3 Linear Diffusion Layer */
|
||||||
|
a->s64[4] =
|
||||||
|
tmp.s64[4] ^ rotrFixed64(tmp.s64[4], 7) ^ rotrFixed64(tmp.s64[4], 41);
|
||||||
|
a->s64[1] =
|
||||||
|
tmp.s64[1] ^ rotrFixed64(tmp.s64[1], 61) ^ rotrFixed64(tmp.s64[1], 39);
|
||||||
|
a->s64[3] =
|
||||||
|
tmp.s64[3] ^ rotrFixed64(tmp.s64[3], 10) ^ rotrFixed64(tmp.s64[3], 17);
|
||||||
|
a->s64[0] =
|
||||||
|
tmp.s64[0] ^ rotrFixed64(tmp.s64[0], 19) ^ rotrFixed64(tmp.s64[0], 28);
|
||||||
|
a->s64[2] =
|
||||||
|
tmp.s64[2] ^ rotrFixed64(tmp.s64[2], 1) ^ rotrFixed64(tmp.s64[2], 6);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void permutation(AsconState* a, byte rounds)
|
||||||
|
{
|
||||||
|
byte i = start_index(rounds);
|
||||||
|
for (; i < MAX_ROUNDS; i++) {
|
||||||
|
ascon_round(a, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* AsconHash API */
|
||||||
|
|
||||||
|
wc_AsconHash256* wc_AsconHash256_New(void)
|
||||||
|
{
|
||||||
|
wc_AsconHash256* ret = (wc_AsconHash256*)XMALLOC(sizeof(wc_AsconHash256),
|
||||||
|
NULL, DYNAMIC_TYPE_ASCON);
|
||||||
|
if (ret != NULL) {
|
||||||
|
if (wc_AsconHash256_Init(ret) != 0) {
|
||||||
|
wc_AsconHash256_Free(ret);
|
||||||
|
ret = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void wc_AsconHash256_Free(wc_AsconHash256* a)
|
||||||
|
{
|
||||||
|
if (a != NULL) {
|
||||||
|
wc_AsconHash256_Deinit(a);
|
||||||
|
XFREE(a, NULL, DYNAMIC_TYPE_ASCON);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int wc_AsconHash256_Init(wc_AsconHash256* a)
|
||||||
|
{
|
||||||
|
if (a == NULL)
|
||||||
|
return BAD_FUNC_ARG;
|
||||||
|
|
||||||
|
XMEMSET(a, 0, sizeof(*a));
|
||||||
|
|
||||||
|
a->state.s64[0] = ASCON_HASH256_IV;
|
||||||
|
permutation(&a->state, ASCON_HASH256_ROUNDS);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void wc_AsconHash256_Deinit(wc_AsconHash256* a)
|
||||||
|
{
|
||||||
|
if (a != NULL) {
|
||||||
|
ForceZero(a, sizeof(*a));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int wc_AsconHash256_Update(wc_AsconHash256* a, const byte* data, word32 dataSz)
|
||||||
|
{
|
||||||
|
if (a == NULL || (data == NULL && dataSz != 0))
|
||||||
|
return BAD_FUNC_ARG;
|
||||||
|
|
||||||
|
if (dataSz == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* Process leftover block */
|
||||||
|
if (a->lastBlkSz != 0) {
|
||||||
|
word32 toProcess = min(ASCON_HASH256_RATE - a->lastBlkSz, dataSz);
|
||||||
|
xorbuf(a->state.s8 + a->lastBlkSz, data, toProcess);
|
||||||
|
data += toProcess;
|
||||||
|
dataSz -= toProcess;
|
||||||
|
a->lastBlkSz += toProcess;
|
||||||
|
|
||||||
|
if (a->lastBlkSz < ASCON_HASH256_RATE)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
permutation(&a->state, ASCON_HASH256_ROUNDS);
|
||||||
|
/* Reset the counter */
|
||||||
|
a->lastBlkSz = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (dataSz >= ASCON_HASH256_RATE) {
|
||||||
|
/* Read in input as little endian numbers */
|
||||||
|
xorbuf(a->state.s64, data, ASCON_HASH256_RATE);
|
||||||
|
permutation(&a->state, ASCON_HASH256_ROUNDS);
|
||||||
|
data += ASCON_HASH256_RATE;
|
||||||
|
dataSz -= ASCON_HASH256_RATE;
|
||||||
|
}
|
||||||
|
|
||||||
|
xorbuf(a->state.s64, data, dataSz);
|
||||||
|
a->lastBlkSz = dataSz;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int wc_AsconHash256_Final(wc_AsconHash256* a, byte* hash)
|
||||||
|
{
|
||||||
|
byte i;
|
||||||
|
|
||||||
|
if (a == NULL || hash == NULL)
|
||||||
|
return BAD_FUNC_ARG;
|
||||||
|
|
||||||
|
/* Process last block */
|
||||||
|
a->state.s8[a->lastBlkSz] ^= 1;
|
||||||
|
|
||||||
|
for (i = 0; i < ASCON_HASH256_SZ; i += ASCON_HASH256_RATE) {
|
||||||
|
permutation(&a->state, ASCON_HASH256_ROUNDS);
|
||||||
|
XMEMCPY(hash, a->state.s64, ASCON_HASH256_RATE);
|
||||||
|
hash += ASCON_HASH256_RATE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Clear state as soon as possible */
|
||||||
|
wc_AsconHash256_Deinit(a);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* AsconAEAD API */
|
||||||
|
|
||||||
|
wc_AsconAEAD128* wc_AsconAEAD128_New(void)
|
||||||
|
{
|
||||||
|
wc_AsconAEAD128 *ret = (wc_AsconAEAD128*) XMALLOC(sizeof(wc_AsconAEAD128),
|
||||||
|
NULL, DYNAMIC_TYPE_ASCON);
|
||||||
|
if (ret != NULL) {
|
||||||
|
if (wc_AsconAEAD128_Init(ret) != 0) {
|
||||||
|
wc_AsconAEAD128_Free(ret);
|
||||||
|
ret = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void wc_AsconAEAD128_Free(wc_AsconAEAD128 *a)
|
||||||
|
{
|
||||||
|
if (a != NULL) {
|
||||||
|
wc_AsconAEAD128_Deinit(a);
|
||||||
|
XFREE(a, NULL, DYNAMIC_TYPE_ASCON);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int wc_AsconAEAD128_Init(wc_AsconAEAD128 *a)
|
||||||
|
{
|
||||||
|
if (a == NULL)
|
||||||
|
return BAD_FUNC_ARG;
|
||||||
|
|
||||||
|
XMEMSET(a, 0, sizeof(*a));
|
||||||
|
a->state.s64[0] = ASCON_AEAD128_IV;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void wc_AsconAEAD128_Deinit(wc_AsconAEAD128 *a)
|
||||||
|
{
|
||||||
|
if (a != NULL) {
|
||||||
|
ForceZero(a, sizeof(*a));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int wc_AsconAEAD128_SetKey(wc_AsconAEAD128* a, const byte* key)
|
||||||
|
{
|
||||||
|
if (a == NULL || key == NULL)
|
||||||
|
return BAD_FUNC_ARG;
|
||||||
|
if (a->KeySet)
|
||||||
|
return BAD_STATE_E;
|
||||||
|
|
||||||
|
XMEMCPY(a->key, key, ASCON_AEAD128_KEY_SZ);
|
||||||
|
a->state.s64[1] = a->key[0];
|
||||||
|
a->state.s64[2] = a->key[1];
|
||||||
|
a->KeySet = 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int wc_AsconAEAD128_SetNonce(wc_AsconAEAD128* a, const byte* nonce)
|
||||||
|
{
|
||||||
|
if (a == NULL || nonce == NULL)
|
||||||
|
return BAD_FUNC_ARG;
|
||||||
|
if (a->NonceSet)
|
||||||
|
return BAD_STATE_E;
|
||||||
|
|
||||||
|
XMEMCPY(&a->state.s64[3], nonce, ASCON_AEAD128_NONCE_SZ);
|
||||||
|
a->NonceSet = 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int wc_AsconAEAD128_SetAD(wc_AsconAEAD128* a, const byte* ad,
|
||||||
|
word32 adSz)
|
||||||
|
{
|
||||||
|
if (a == NULL || (ad == NULL && adSz > 0))
|
||||||
|
return BAD_FUNC_ARG;
|
||||||
|
if (!a->KeySet || !a->NonceSet) /* key and nonce must be set before */
|
||||||
|
return BAD_STATE_E;
|
||||||
|
|
||||||
|
permutation(&a->state, ASCON_AEAD128_ROUNDS_PA);
|
||||||
|
a->state.s64[3] ^= a->key[0];
|
||||||
|
a->state.s64[4] ^= a->key[1];
|
||||||
|
|
||||||
|
if (adSz > 0) {
|
||||||
|
while (adSz >= ASCON_AEAD128_RATE) {
|
||||||
|
xorbuf(a->state.s64, ad, ASCON_AEAD128_RATE);
|
||||||
|
permutation(&a->state, ASCON_AEAD128_ROUNDS_PB);
|
||||||
|
ad += ASCON_AEAD128_RATE;
|
||||||
|
adSz -= ASCON_AEAD128_RATE;
|
||||||
|
}
|
||||||
|
xorbuf(a->state.s64, ad, adSz);
|
||||||
|
/* Pad the last block */
|
||||||
|
a->state.s8[adSz] ^= 1;
|
||||||
|
permutation(&a->state, ASCON_AEAD128_ROUNDS_PB);
|
||||||
|
}
|
||||||
|
a->state.s64[4] ^= 1ULL << 63;
|
||||||
|
|
||||||
|
a->ADSet = 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int wc_AsconAEAD128_EncryptUpdate(wc_AsconAEAD128* a, byte* out,
|
||||||
|
const byte* in, word32 inSz)
|
||||||
|
{
|
||||||
|
if (a == NULL || (in == NULL && inSz > 0))
|
||||||
|
return BAD_FUNC_ARG;
|
||||||
|
if (!a->KeySet || !a->NonceSet || !a->ADSet)
|
||||||
|
return BAD_STATE_E;
|
||||||
|
|
||||||
|
if (a->op == ASCON_AEAD128_NOTSET)
|
||||||
|
a->op = ASCON_AEAD128_ENCRYPT;
|
||||||
|
else if (a->op != ASCON_AEAD128_ENCRYPT)
|
||||||
|
return BAD_STATE_E;
|
||||||
|
|
||||||
|
/* Process leftover block */
|
||||||
|
if (a->lastBlkSz != 0) {
|
||||||
|
word32 toProcess = min(ASCON_AEAD128_RATE - a->lastBlkSz, inSz);
|
||||||
|
xorbuf(&a->state.s8[a->lastBlkSz], in, toProcess);
|
||||||
|
XMEMCPY(out, &a->state.s8[a->lastBlkSz], toProcess);
|
||||||
|
a->lastBlkSz += toProcess;
|
||||||
|
in += toProcess;
|
||||||
|
out += toProcess;
|
||||||
|
inSz -= toProcess;
|
||||||
|
|
||||||
|
if (a->lastBlkSz < ASCON_AEAD128_RATE)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
permutation(&a->state, ASCON_AEAD128_ROUNDS_PB);
|
||||||
|
a->lastBlkSz = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (inSz >= ASCON_AEAD128_RATE) {
|
||||||
|
xorbuf(a->state.s64, in, ASCON_AEAD128_RATE);
|
||||||
|
XMEMCPY(out, a->state.s64, ASCON_AEAD128_RATE);
|
||||||
|
permutation(&a->state, ASCON_AEAD128_ROUNDS_PB);
|
||||||
|
in += ASCON_AEAD128_RATE;
|
||||||
|
out += ASCON_AEAD128_RATE;
|
||||||
|
inSz -= ASCON_AEAD128_RATE;
|
||||||
|
}
|
||||||
|
|
||||||
|
xorbuf(a->state.s64, in, inSz);
|
||||||
|
XMEMCPY(out, a->state.s64, inSz);
|
||||||
|
a->lastBlkSz = inSz;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int wc_AsconAEAD128_EncryptFinal(wc_AsconAEAD128* a, byte* tag)
|
||||||
|
{
|
||||||
|
if (a == NULL || tag == NULL)
|
||||||
|
return BAD_FUNC_ARG;
|
||||||
|
if (!a->KeySet || !a->NonceSet || !a->ADSet)
|
||||||
|
return BAD_STATE_E;
|
||||||
|
|
||||||
|
if (a->op != ASCON_AEAD128_ENCRYPT)
|
||||||
|
return BAD_STATE_E;
|
||||||
|
|
||||||
|
/* Pad last block */
|
||||||
|
a->state.s8[a->lastBlkSz] ^= 1;
|
||||||
|
|
||||||
|
a->state.s64[2] ^= a->key[0];
|
||||||
|
a->state.s64[3] ^= a->key[1];
|
||||||
|
permutation(&a->state, ASCON_AEAD128_ROUNDS_PA);
|
||||||
|
a->state.s64[3] ^= a->key[0];
|
||||||
|
a->state.s64[4] ^= a->key[1];
|
||||||
|
|
||||||
|
XMEMCPY(tag, &a->state.s64[3], ASCON_AEAD128_TAG_SZ);
|
||||||
|
|
||||||
|
/* Clear state as soon as possible */
|
||||||
|
wc_AsconAEAD128_Deinit(a);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int wc_AsconAEAD128_DecryptUpdate(wc_AsconAEAD128* a, byte* out,
|
||||||
|
const byte* in, word32 inSz)
|
||||||
|
{
|
||||||
|
if (a == NULL || (in == NULL && inSz > 0))
|
||||||
|
return BAD_FUNC_ARG;
|
||||||
|
if (!a->KeySet || !a->NonceSet || !a->ADSet)
|
||||||
|
return BAD_STATE_E;
|
||||||
|
|
||||||
|
if (a->op == ASCON_AEAD128_NOTSET)
|
||||||
|
a->op = ASCON_AEAD128_DECRYPT;
|
||||||
|
else if (a->op != ASCON_AEAD128_DECRYPT)
|
||||||
|
return BAD_STATE_E;
|
||||||
|
|
||||||
|
/* Process leftover block */
|
||||||
|
if (a->lastBlkSz != 0) {
|
||||||
|
word32 toProcess = min(ASCON_AEAD128_RATE - a->lastBlkSz, inSz);
|
||||||
|
xorbufout(out, a->state.s8 + a->lastBlkSz, in, toProcess);
|
||||||
|
XMEMCPY(a->state.s8 + a->lastBlkSz, in, toProcess);
|
||||||
|
in += toProcess;
|
||||||
|
out += toProcess;
|
||||||
|
inSz -= toProcess;
|
||||||
|
a->lastBlkSz += toProcess;
|
||||||
|
|
||||||
|
if (a->lastBlkSz < ASCON_AEAD128_RATE)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
permutation(&a->state, ASCON_AEAD128_ROUNDS_PB);
|
||||||
|
a->lastBlkSz = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (inSz >= ASCON_AEAD128_RATE) {
|
||||||
|
xorbufout(out, a->state.s64, in, ASCON_AEAD128_RATE);
|
||||||
|
XMEMCPY(a->state.s64, in, ASCON_AEAD128_RATE);
|
||||||
|
permutation(&a->state, ASCON_AEAD128_ROUNDS_PB);
|
||||||
|
in += ASCON_AEAD128_RATE;
|
||||||
|
out += ASCON_AEAD128_RATE;
|
||||||
|
inSz -= ASCON_AEAD128_RATE;
|
||||||
|
}
|
||||||
|
|
||||||
|
xorbufout(out, a->state.s64, in, inSz);
|
||||||
|
XMEMCPY(a->state.s64, in, inSz);
|
||||||
|
a->lastBlkSz = inSz;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int wc_AsconAEAD128_DecryptFinal(wc_AsconAEAD128* a, const byte* tag)
|
||||||
|
{
|
||||||
|
if (a == NULL || tag == NULL)
|
||||||
|
return BAD_FUNC_ARG;
|
||||||
|
if (!a->KeySet || !a->NonceSet || !a->ADSet)
|
||||||
|
return BAD_STATE_E;
|
||||||
|
|
||||||
|
if (a->op != ASCON_AEAD128_DECRYPT)
|
||||||
|
return BAD_STATE_E;
|
||||||
|
|
||||||
|
/* Pad last block */
|
||||||
|
a->state.s8[a->lastBlkSz] ^= 1;
|
||||||
|
|
||||||
|
a->state.s64[2] ^= a->key[0];
|
||||||
|
a->state.s64[3] ^= a->key[1];
|
||||||
|
permutation(&a->state, ASCON_AEAD128_ROUNDS_PA);
|
||||||
|
a->state.s64[3] ^= a->key[0];
|
||||||
|
a->state.s64[4] ^= a->key[1];
|
||||||
|
|
||||||
|
if (ConstantCompare(tag, (const byte*)&a->state.s64[3],
|
||||||
|
ASCON_AEAD128_TAG_SZ) != 0)
|
||||||
|
return ASCON_AUTH_E;
|
||||||
|
|
||||||
|
/* Clear state as soon as possible */
|
||||||
|
wc_AsconAEAD128_Deinit(a);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* HAVE_ASCON */
|
@@ -651,6 +651,9 @@ const char* wc_GetErrorString(int error)
|
|||||||
case DEADLOCK_AVERTED_E:
|
case DEADLOCK_AVERTED_E:
|
||||||
return "Deadlock averted -- retry the call";
|
return "Deadlock averted -- retry the call";
|
||||||
|
|
||||||
|
case ASCON_AUTH_E:
|
||||||
|
return "ASCON Authentication check fail";
|
||||||
|
|
||||||
case MAX_CODE_E:
|
case MAX_CODE_E:
|
||||||
case WC_SPAN1_MIN_CODE_E:
|
case WC_SPAN1_MIN_CODE_E:
|
||||||
case MIN_CODE_E:
|
case MIN_CODE_E:
|
||||||
|
6509
wolfcrypt/test/ascon-kat.h
Normal file
6509
wolfcrypt/test/ascon-kat.h
Normal file
File diff suppressed because it is too large
Load Diff
@@ -13,6 +13,7 @@ wolfcrypt_test_testwolfcrypt_SOURCES = wolfcrypt/test/test.c
|
|||||||
wolfcrypt_test_testwolfcrypt_LDADD = src/libwolfssl@LIBSUFFIX@.la $(LIB_STATIC_ADD)
|
wolfcrypt_test_testwolfcrypt_LDADD = src/libwolfssl@LIBSUFFIX@.la $(LIB_STATIC_ADD)
|
||||||
wolfcrypt_test_testwolfcrypt_DEPENDENCIES = src/libwolfssl@LIBSUFFIX@.la
|
wolfcrypt_test_testwolfcrypt_DEPENDENCIES = src/libwolfssl@LIBSUFFIX@.la
|
||||||
noinst_HEADERS += wolfcrypt/test/test.h wolfcrypt/test/test_paths.h.in
|
noinst_HEADERS += wolfcrypt/test/test.h wolfcrypt/test/test_paths.h.in
|
||||||
|
noinst_HEADERS += wolfcrypt/test/ascon-kat.h
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
@@ -48,6 +48,13 @@
|
|||||||
#include <wolfssl/wolfcrypt/wc_port.h>
|
#include <wolfssl/wolfcrypt/wc_port.h>
|
||||||
#include <wolfssl/wolfcrypt/mem_track.h>
|
#include <wolfssl/wolfcrypt/mem_track.h>
|
||||||
|
|
||||||
|
#ifdef NO_INLINE
|
||||||
|
#include <wolfssl/wolfcrypt/misc.h>
|
||||||
|
#else
|
||||||
|
#define WOLFSSL_MISC_INCLUDED
|
||||||
|
#include <wolfcrypt/src/misc.c>
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(HAVE_WOLFCRYPT_TEST_OPTIONS)
|
#if defined(HAVE_WOLFCRYPT_TEST_OPTIONS)
|
||||||
#include <wolfssl/ssl.h>
|
#include <wolfssl/ssl.h>
|
||||||
#define err_sys err_sys_remap /* remap err_sys */
|
#define err_sys err_sys_remap /* remap err_sys */
|
||||||
@@ -285,6 +292,7 @@ const byte const_byte_array[] = "A+Gd\0\0\0";
|
|||||||
#include <wolfssl/wolfcrypt/srp.h>
|
#include <wolfssl/wolfcrypt/srp.h>
|
||||||
#include <wolfssl/wolfcrypt/chacha.h>
|
#include <wolfssl/wolfcrypt/chacha.h>
|
||||||
#include <wolfssl/wolfcrypt/chacha20_poly1305.h>
|
#include <wolfssl/wolfcrypt/chacha20_poly1305.h>
|
||||||
|
#include <wolfssl/wolfcrypt/ascon.h>
|
||||||
#include <wolfssl/wolfcrypt/pwdbased.h>
|
#include <wolfssl/wolfcrypt/pwdbased.h>
|
||||||
#include <wolfssl/wolfcrypt/ripemd.h>
|
#include <wolfssl/wolfcrypt/ripemd.h>
|
||||||
#include <wolfssl/wolfcrypt/error-crypt.h>
|
#include <wolfssl/wolfcrypt/error-crypt.h>
|
||||||
@@ -590,6 +598,8 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t aes192_test(void);
|
|||||||
WOLFSSL_TEST_SUBROUTINE wc_test_ret_t aes256_test(void);
|
WOLFSSL_TEST_SUBROUTINE wc_test_ret_t aes256_test(void);
|
||||||
WOLFSSL_TEST_SUBROUTINE wc_test_ret_t aesofb_test(void);
|
WOLFSSL_TEST_SUBROUTINE wc_test_ret_t aesofb_test(void);
|
||||||
WOLFSSL_TEST_SUBROUTINE wc_test_ret_t cmac_test(void);
|
WOLFSSL_TEST_SUBROUTINE wc_test_ret_t cmac_test(void);
|
||||||
|
WOLFSSL_TEST_SUBROUTINE wc_test_ret_t ascon_hash256_test(void);
|
||||||
|
WOLFSSL_TEST_SUBROUTINE wc_test_ret_t ascon_aead128_test(void);
|
||||||
#if defined(WOLFSSL_SIPHASH)
|
#if defined(WOLFSSL_SIPHASH)
|
||||||
WOLFSSL_TEST_SUBROUTINE wc_test_ret_t siphash_test(void);
|
WOLFSSL_TEST_SUBROUTINE wc_test_ret_t siphash_test(void);
|
||||||
#endif
|
#endif
|
||||||
@@ -1947,6 +1957,18 @@ options: [-s max_relative_stack_bytes] [-m max_relative_heap_memory_bytes]\n\
|
|||||||
TEST_PASS("ChaCha20-Poly1305 AEAD test passed!\n");
|
TEST_PASS("ChaCha20-Poly1305 AEAD test passed!\n");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_ASCON
|
||||||
|
if ( (ret = ascon_hash256_test()) != 0)
|
||||||
|
return err_sys("ASCON Hash test failed!\n", ret);
|
||||||
|
else
|
||||||
|
TEST_PASS("ASCON Hash test passed!\n");
|
||||||
|
|
||||||
|
if ( (ret = ascon_aead128_test()) != 0)
|
||||||
|
return err_sys("ASCON AEAD test failed!\n", ret);
|
||||||
|
else
|
||||||
|
TEST_PASS("ASCON AEAD test passed!\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(HAVE_XCHACHA) && defined(HAVE_POLY1305)
|
#if defined(HAVE_XCHACHA) && defined(HAVE_POLY1305)
|
||||||
if ( (ret = XChaCha20Poly1305_test()) != 0)
|
if ( (ret = XChaCha20Poly1305_test()) != 0)
|
||||||
TEST_FAIL("XChaCha20-Poly1305 AEAD test failed!\n", ret);
|
TEST_FAIL("XChaCha20-Poly1305 AEAD test failed!\n", ret);
|
||||||
@@ -8784,6 +8806,214 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t chacha20_poly1305_aead_test(void)
|
|||||||
}
|
}
|
||||||
#endif /* HAVE_CHACHA && HAVE_POLY1305 */
|
#endif /* HAVE_CHACHA && HAVE_POLY1305 */
|
||||||
|
|
||||||
|
#ifdef HAVE_ASCON
|
||||||
|
#include <wolfcrypt/test/ascon-kat.h>
|
||||||
|
WOLFSSL_TEST_SUBROUTINE wc_test_ret_t ascon_hash256_test(void)
|
||||||
|
{
|
||||||
|
WOLFSSL_SMALL_STACK_STATIC byte msg[1024];
|
||||||
|
byte mdOut[ASCON_HASH256_SZ];
|
||||||
|
const size_t test_rounds = sizeof(msg) + 1; /* +1 to test 0-len msg */
|
||||||
|
|
||||||
|
wc_AsconHash256 asconHash;
|
||||||
|
int err;
|
||||||
|
word32 i;
|
||||||
|
|
||||||
|
if (XELEM_CNT(ascon_hash256_output) != test_rounds)
|
||||||
|
return WC_TEST_RET_ENC_EC(BAD_FUNC_ARG);
|
||||||
|
|
||||||
|
/* init msg buffer */
|
||||||
|
for (i = 0; i < sizeof(msg); i++)
|
||||||
|
msg[i] = (byte)i;
|
||||||
|
|
||||||
|
for (i = 0; i < test_rounds; i++) {
|
||||||
|
XMEMSET(mdOut, 0, sizeof(mdOut));
|
||||||
|
err = wc_AsconHash256_Init(&asconHash);
|
||||||
|
if (err != 0)
|
||||||
|
return WC_TEST_RET_ENC_EC(err);
|
||||||
|
err = wc_AsconHash256_Update(&asconHash, msg, i);
|
||||||
|
if (err != 0)
|
||||||
|
return WC_TEST_RET_ENC_EC(err);
|
||||||
|
err = wc_AsconHash256_Final(&asconHash, mdOut);
|
||||||
|
if (err != 0)
|
||||||
|
return WC_TEST_RET_ENC_EC(err);
|
||||||
|
if (XMEMCMP(mdOut, ascon_hash256_output[i], ASCON_HASH256_SZ) != 0)
|
||||||
|
return WC_TEST_RET_ENC_NC;
|
||||||
|
wc_AsconHash256_Deinit(&asconHash);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Test separated update */
|
||||||
|
for (i = 0; i < test_rounds; i++) {
|
||||||
|
word32 half_i = i / 2;
|
||||||
|
XMEMSET(mdOut, 0, sizeof(mdOut));
|
||||||
|
err = wc_AsconHash256_Init(&asconHash);
|
||||||
|
if (err != 0)
|
||||||
|
return WC_TEST_RET_ENC_EC(err);
|
||||||
|
err = wc_AsconHash256_Update(&asconHash, msg, half_i);
|
||||||
|
if (err != 0)
|
||||||
|
return WC_TEST_RET_ENC_EC(err);
|
||||||
|
err = wc_AsconHash256_Update(&asconHash, msg + half_i, i - half_i);
|
||||||
|
if (err != 0)
|
||||||
|
return WC_TEST_RET_ENC_EC(err);
|
||||||
|
err = wc_AsconHash256_Final(&asconHash, mdOut);
|
||||||
|
if (err != 0)
|
||||||
|
return WC_TEST_RET_ENC_EC(err);
|
||||||
|
if (XMEMCMP(mdOut, ascon_hash256_output[i], ASCON_HASH256_SZ) != 0)
|
||||||
|
return WC_TEST_RET_ENC_NC;
|
||||||
|
wc_AsconHash256_Deinit(&asconHash);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
WOLFSSL_TEST_SUBROUTINE wc_test_ret_t ascon_aead128_test(void)
|
||||||
|
{
|
||||||
|
word32 i;
|
||||||
|
wc_AsconAEAD128 asconAEAD;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
for (i = 0; i < XELEM_CNT(ascon_aead128_kat); i++) {
|
||||||
|
byte key[ASCON_AEAD128_KEY_SZ];
|
||||||
|
byte nonce[ASCON_AEAD128_NONCE_SZ];
|
||||||
|
byte pt[32]; /* longest plaintext we test is 32 bytes */
|
||||||
|
word32 ptSz;
|
||||||
|
byte ad[32]; /* longest AD we test is 32 bytes */
|
||||||
|
word32 adSz;
|
||||||
|
byte ct[48]; /* longest ciphertext we test is 32 bytes + 16 bytes tag */
|
||||||
|
word32 ctSz;
|
||||||
|
word32 j;
|
||||||
|
byte tag[ASCON_AEAD128_TAG_SZ];
|
||||||
|
byte buf[32]; /* longest buffer we test is 32 bytes */
|
||||||
|
|
||||||
|
XMEMSET(key, 0, sizeof(key));
|
||||||
|
XMEMSET(nonce, 0, sizeof(nonce));
|
||||||
|
XMEMSET(pt, 0, sizeof(pt));
|
||||||
|
XMEMSET(ad, 0, sizeof(ad));
|
||||||
|
XMEMSET(ct, 0, sizeof(ct));
|
||||||
|
XMEMSET(tag, 0, sizeof(tag));
|
||||||
|
|
||||||
|
/* Convert HEX strings to byte stream */
|
||||||
|
for (j = 0; ascon_aead128_kat[i][0][j] != '\0'; j += 2) {
|
||||||
|
key[j/2] = HexCharToByte(ascon_aead128_kat[i][0][j]) << 4 |
|
||||||
|
HexCharToByte(ascon_aead128_kat[i][0][j+1]);
|
||||||
|
}
|
||||||
|
for (j = 0; ascon_aead128_kat[i][1][j] != '\0'; j += 2) {
|
||||||
|
nonce[j/2] = HexCharToByte(ascon_aead128_kat[i][1][j]) << 4 |
|
||||||
|
HexCharToByte(ascon_aead128_kat[i][1][j+1]);
|
||||||
|
}
|
||||||
|
for (j = 0; ascon_aead128_kat[i][2][j] != '\0'; j += 2) {
|
||||||
|
pt[j/2] = HexCharToByte(ascon_aead128_kat[i][2][j]) << 4 |
|
||||||
|
HexCharToByte(ascon_aead128_kat[i][2][j+1]);
|
||||||
|
}
|
||||||
|
ptSz = j/2;
|
||||||
|
for (j = 0; ascon_aead128_kat[i][3][j] != '\0'; j += 2) {
|
||||||
|
ad[j/2] = HexCharToByte(ascon_aead128_kat[i][3][j]) << 4 |
|
||||||
|
HexCharToByte(ascon_aead128_kat[i][3][j+1]);
|
||||||
|
}
|
||||||
|
adSz = j/2;
|
||||||
|
for (j = 0; ascon_aead128_kat[i][4][j] != '\0'; j += 2) {
|
||||||
|
ct[j/2] = HexCharToByte(ascon_aead128_kat[i][4][j]) << 4 |
|
||||||
|
HexCharToByte(ascon_aead128_kat[i][4][j+1]);
|
||||||
|
}
|
||||||
|
ctSz = j/2 - ASCON_AEAD128_TAG_SZ;
|
||||||
|
|
||||||
|
for (j = 0; j < 4; j++) {
|
||||||
|
err = wc_AsconAEAD128_Init(&asconAEAD);
|
||||||
|
if (err != 0)
|
||||||
|
return WC_TEST_RET_ENC_EC(err);
|
||||||
|
|
||||||
|
err = wc_AsconAEAD128_SetKey(&asconAEAD, key);
|
||||||
|
if (err != 0)
|
||||||
|
return WC_TEST_RET_ENC_EC(err);
|
||||||
|
|
||||||
|
err = wc_AsconAEAD128_SetNonce(&asconAEAD, nonce);
|
||||||
|
if (err != 0)
|
||||||
|
return WC_TEST_RET_ENC_EC(err);
|
||||||
|
|
||||||
|
err = wc_AsconAEAD128_SetAD(&asconAEAD, ad, adSz);
|
||||||
|
if (err != 0)
|
||||||
|
return WC_TEST_RET_ENC_EC(err);
|
||||||
|
|
||||||
|
if (j == 0) {
|
||||||
|
/* Encryption test */
|
||||||
|
err = wc_AsconAEAD128_EncryptUpdate(&asconAEAD, buf, pt, ptSz);
|
||||||
|
if (err != 0)
|
||||||
|
return WC_TEST_RET_ENC_EC(err);
|
||||||
|
|
||||||
|
if (XMEMCMP(buf, ct, ptSz) != 0)
|
||||||
|
return WC_TEST_RET_ENC_NC;
|
||||||
|
|
||||||
|
err = wc_AsconAEAD128_EncryptFinal(&asconAEAD, tag);
|
||||||
|
if (err != 0)
|
||||||
|
return WC_TEST_RET_ENC_EC(err);
|
||||||
|
|
||||||
|
if (XMEMCMP(tag, ct + ptSz, ASCON_AEAD128_TAG_SZ) != 0)
|
||||||
|
return WC_TEST_RET_ENC_NC;
|
||||||
|
}
|
||||||
|
else if (j == 1) {
|
||||||
|
/* Decryption test */
|
||||||
|
err = wc_AsconAEAD128_DecryptUpdate(&asconAEAD, buf, ct, ctSz);
|
||||||
|
if (err != 0)
|
||||||
|
return WC_TEST_RET_ENC_EC(err);
|
||||||
|
|
||||||
|
if (XMEMCMP(buf, pt, ctSz) != 0)
|
||||||
|
return WC_TEST_RET_ENC_NC;
|
||||||
|
|
||||||
|
err = wc_AsconAEAD128_DecryptFinal(&asconAEAD, ct + ctSz);
|
||||||
|
if (err != 0)
|
||||||
|
return WC_TEST_RET_ENC_EC(err);
|
||||||
|
}
|
||||||
|
else if (j == 2) {
|
||||||
|
/* Split encryption test */
|
||||||
|
err = wc_AsconAEAD128_EncryptUpdate(&asconAEAD, buf, pt,
|
||||||
|
ptSz/2);
|
||||||
|
if (err != 0)
|
||||||
|
return WC_TEST_RET_ENC_EC(err);
|
||||||
|
|
||||||
|
err = wc_AsconAEAD128_EncryptUpdate(&asconAEAD, buf + (ptSz/2),
|
||||||
|
pt + (ptSz/2), ptSz - (ptSz/2));
|
||||||
|
if (err != 0)
|
||||||
|
return WC_TEST_RET_ENC_EC(err);
|
||||||
|
|
||||||
|
if (XMEMCMP(buf, ct, ptSz) != 0)
|
||||||
|
return WC_TEST_RET_ENC_NC;
|
||||||
|
|
||||||
|
err = wc_AsconAEAD128_EncryptFinal(&asconAEAD, tag);
|
||||||
|
if (err != 0)
|
||||||
|
return WC_TEST_RET_ENC_EC(err);
|
||||||
|
|
||||||
|
if (XMEMCMP(tag, ct + ptSz, ASCON_AEAD128_TAG_SZ) != 0)
|
||||||
|
return WC_TEST_RET_ENC_NC;
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (j == 3) {
|
||||||
|
/* Split decryption test */
|
||||||
|
err = wc_AsconAEAD128_DecryptUpdate(&asconAEAD, buf, ct,
|
||||||
|
ctSz/2);
|
||||||
|
if (err != 0)
|
||||||
|
return WC_TEST_RET_ENC_EC(err);
|
||||||
|
|
||||||
|
err = wc_AsconAEAD128_DecryptUpdate(&asconAEAD, buf + (ctSz/2),
|
||||||
|
ct + (ctSz/2), ctSz - (ctSz/2));
|
||||||
|
if (err != 0)
|
||||||
|
return WC_TEST_RET_ENC_EC(err);
|
||||||
|
|
||||||
|
if (XMEMCMP(buf, pt, ctSz) != 0)
|
||||||
|
return WC_TEST_RET_ENC_NC;
|
||||||
|
|
||||||
|
err = wc_AsconAEAD128_DecryptFinal(&asconAEAD, ct + ctSz);
|
||||||
|
if (err != 0)
|
||||||
|
return WC_TEST_RET_ENC_EC(err);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
wc_AsconAEAD128_Deinit(&asconAEAD);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif /* HAVE_ASCON */
|
||||||
|
|
||||||
#ifndef NO_DES3
|
#ifndef NO_DES3
|
||||||
WOLFSSL_TEST_SUBROUTINE wc_test_ret_t des_test(void)
|
WOLFSSL_TEST_SUBROUTINE wc_test_ret_t des_test(void)
|
||||||
|
113
wolfssl/wolfcrypt/ascon.h
Normal file
113
wolfssl/wolfcrypt/ascon.h
Normal file
@@ -0,0 +1,113 @@
|
|||||||
|
/* ascon.h
|
||||||
|
*
|
||||||
|
* Copyright (C) 2006-2025 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef WOLF_CRYPT_ASCON_H
|
||||||
|
#define WOLF_CRYPT_ASCON_H
|
||||||
|
|
||||||
|
#ifdef HAVE_ASCON
|
||||||
|
|
||||||
|
#include <wolfssl/wolfcrypt/types.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define ASCON_HASH256_SZ 32
|
||||||
|
/* Data block size in bytes */
|
||||||
|
#define ASCON_HASH256_RATE 8
|
||||||
|
#define ASCON_HASH256_ROUNDS 12
|
||||||
|
#define ASCON_HASH256_IV 0x0000080100CC0002ULL
|
||||||
|
|
||||||
|
#define ASCON_AEAD128_ROUNDS_PA 12
|
||||||
|
#define ASCON_AEAD128_ROUNDS_PB 8
|
||||||
|
#define ASCON_AEAD128_IV 0x00001000808C0001ULL
|
||||||
|
#define ASCON_AEAD128_KEY_SZ 16
|
||||||
|
#define ASCON_AEAD128_NONCE_SZ 16
|
||||||
|
#define ASCON_AEAD128_TAG_SZ 16
|
||||||
|
#define ASCON_AEAD128_RATE 16
|
||||||
|
|
||||||
|
typedef union AsconState {
|
||||||
|
word64 s64[5];
|
||||||
|
word32 s32[10];
|
||||||
|
word16 s16[20];
|
||||||
|
byte s8[40];
|
||||||
|
} AsconState;
|
||||||
|
|
||||||
|
typedef struct wc_AsconHash256 {
|
||||||
|
AsconState state;
|
||||||
|
byte lastBlkSz;
|
||||||
|
} wc_AsconHash256;
|
||||||
|
|
||||||
|
enum {
|
||||||
|
ASCON_AEAD128_NOTSET = 0,
|
||||||
|
ASCON_AEAD128_ENCRYPT = 1,
|
||||||
|
ASCON_AEAD128_DECRYPT = 2
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct wc_AsconAEAD128 {
|
||||||
|
AsconState state;
|
||||||
|
byte lastBlkSz;
|
||||||
|
/* needed throughout both encrypt and decrypt */
|
||||||
|
word64 key[ASCON_AEAD128_KEY_SZ/sizeof(word64)];
|
||||||
|
byte KeySet:1; /* has the key been processed */
|
||||||
|
byte NonceSet:1; /* has the nonce been processed */
|
||||||
|
byte ADSet:1; /* has the associated data been processed */
|
||||||
|
byte op:2; /* 0 for not set, 1 for encrypt, 2 for decrypt */
|
||||||
|
} wc_AsconAEAD128;
|
||||||
|
|
||||||
|
/* AsconHash API */
|
||||||
|
|
||||||
|
WOLFSSL_API wc_AsconHash256* wc_AsconHash256_New(void);
|
||||||
|
WOLFSSL_API void wc_AsconHash256_Free(wc_AsconHash256* a);
|
||||||
|
WOLFSSL_API int wc_AsconHash256_Init(wc_AsconHash256* a);
|
||||||
|
WOLFSSL_API void wc_AsconHash256_Deinit(wc_AsconHash256* a);
|
||||||
|
WOLFSSL_API int wc_AsconHash256_Update(wc_AsconHash256* a, const byte* data,
|
||||||
|
word32 dataSz);
|
||||||
|
WOLFSSL_API int wc_AsconHash256_Final(wc_AsconHash256* a, byte* hash);
|
||||||
|
|
||||||
|
WOLFSSL_API wc_AsconAEAD128* wc_AsconAEAD128_New(void);
|
||||||
|
WOLFSSL_API void wc_AsconAEAD128_Free(wc_AsconAEAD128* a);
|
||||||
|
WOLFSSL_API int wc_AsconAEAD128_Init(wc_AsconAEAD128* a);
|
||||||
|
WOLFSSL_API void wc_AsconAEAD128_Deinit(wc_AsconAEAD128* a);
|
||||||
|
|
||||||
|
/* AsconAEAD API */
|
||||||
|
|
||||||
|
WOLFSSL_API int wc_AsconAEAD128_SetKey(wc_AsconAEAD128* a, const byte* key);
|
||||||
|
WOLFSSL_API int wc_AsconAEAD128_SetNonce(wc_AsconAEAD128* a, const byte* nonce);
|
||||||
|
WOLFSSL_API int wc_AsconAEAD128_SetAD(wc_AsconAEAD128* a, const byte* ad,
|
||||||
|
word32 adSz);
|
||||||
|
|
||||||
|
WOLFSSL_API int wc_AsconAEAD128_EncryptUpdate(wc_AsconAEAD128* a, byte* out,
|
||||||
|
const byte* in, word32 inSz);
|
||||||
|
WOLFSSL_API int wc_AsconAEAD128_EncryptFinal(wc_AsconAEAD128* a, byte* tag);
|
||||||
|
|
||||||
|
WOLFSSL_API int wc_AsconAEAD128_DecryptUpdate(wc_AsconAEAD128* a, byte* out,
|
||||||
|
const byte* in, word32 inSz);
|
||||||
|
WOLFSSL_API int wc_AsconAEAD128_DecryptFinal(wc_AsconAEAD128* a,
|
||||||
|
const byte* tag);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
} /* extern "C" */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* HAVE_ASCON */
|
||||||
|
|
||||||
|
#endif /* WOLF_CRYPT_ASCON_H */
|
@@ -303,11 +303,12 @@ enum wolfCrypt_ErrorCodes {
|
|||||||
WC_SPAN2_FIRST_E = -1000,
|
WC_SPAN2_FIRST_E = -1000,
|
||||||
|
|
||||||
DEADLOCK_AVERTED_E = -1000, /* Deadlock averted -- retry the call */
|
DEADLOCK_AVERTED_E = -1000, /* Deadlock averted -- retry the call */
|
||||||
|
ASCON_AUTH_E = -1001, /* ASCON Authentication check failure */
|
||||||
|
|
||||||
WC_SPAN2_LAST_E = -1000, /* Update to indicate last used error code */
|
WC_SPAN2_LAST_E = -1001, /* Update to indicate last used error code */
|
||||||
WC_SPAN2_MIN_CODE_E = -1999, /* Last usable code in span 2 */
|
WC_SPAN2_MIN_CODE_E = -1999, /* Last usable code in span 2 */
|
||||||
|
|
||||||
WC_LAST_E = -1000, /* the last code used either here or in
|
WC_LAST_E = -1001, /* the last code used either here or in
|
||||||
* error-ssl.h
|
* error-ssl.h
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@@ -4,6 +4,7 @@
|
|||||||
nobase_include_HEADERS+= \
|
nobase_include_HEADERS+= \
|
||||||
wolfssl/wolfcrypt/aes.h \
|
wolfssl/wolfcrypt/aes.h \
|
||||||
wolfssl/wolfcrypt/arc4.h \
|
wolfssl/wolfcrypt/arc4.h \
|
||||||
|
wolfssl/wolfcrypt/ascon.h \
|
||||||
wolfssl/wolfcrypt/asn.h \
|
wolfssl/wolfcrypt/asn.h \
|
||||||
wolfssl/wolfcrypt/asn_public.h \
|
wolfssl/wolfcrypt/asn_public.h \
|
||||||
wolfssl/wolfcrypt/poly1305.h \
|
wolfssl/wolfcrypt/poly1305.h \
|
||||||
|
@@ -1110,6 +1110,7 @@ typedef struct w64wrapper {
|
|||||||
DYNAMIC_TYPE_BIO = 102,
|
DYNAMIC_TYPE_BIO = 102,
|
||||||
DYNAMIC_TYPE_X509_ACERT = 103,
|
DYNAMIC_TYPE_X509_ACERT = 103,
|
||||||
DYNAMIC_TYPE_OS_BUF = 104,
|
DYNAMIC_TYPE_OS_BUF = 104,
|
||||||
|
DYNAMIC_TYPE_ASCON = 105,
|
||||||
DYNAMIC_TYPE_SNIFFER_SERVER = 1000,
|
DYNAMIC_TYPE_SNIFFER_SERVER = 1000,
|
||||||
DYNAMIC_TYPE_SNIFFER_SESSION = 1001,
|
DYNAMIC_TYPE_SNIFFER_SESSION = 1001,
|
||||||
DYNAMIC_TYPE_SNIFFER_PB = 1002,
|
DYNAMIC_TYPE_SNIFFER_PB = 1002,
|
||||||
|
Reference in New Issue
Block a user