/* test_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 #endif #if !defined(WOLFSSL_USER_SETTINGS) && !defined(WOLFSSL_NO_OPTIONS_H) #include #endif #include #ifdef NO_INLINE #include #else #define WOLFSSL_MISC_INCLUDED #include #endif #include #include #include #include #ifdef HAVE_ASCON #include #endif int test_ascon_hash256(void) { EXPECT_DECLS; #ifdef HAVE_ASCON 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 = NULL; word32 i; ExpectIntEQ(XELEM_CNT(ascon_hash256_output), test_rounds); /* init msg buffer */ for (i = 0; i < sizeof(msg); i++) msg[i] = (byte)i; ExpectNotNull(asconHash = wc_AsconHash256_New()); for (i = 0; i < test_rounds && EXPECT_SUCCESS(); i++) { XMEMSET(mdOut, 0, sizeof(mdOut)); ExpectIntEQ(wc_AsconHash256_Init(asconHash), 0); ExpectIntEQ(wc_AsconHash256_Update(asconHash, msg, i), 0); ExpectIntEQ(wc_AsconHash256_Final(asconHash, mdOut), 0); ExpectBufEQ(mdOut, ascon_hash256_output[i], ASCON_HASH256_SZ); wc_AsconHash256_Clear(asconHash); } /* Test separated update */ for (i = 0; i < test_rounds && EXPECT_SUCCESS(); i++) { word32 half_i = i / 2; XMEMSET(mdOut, 0, sizeof(mdOut)); ExpectIntEQ(wc_AsconHash256_Init(asconHash), 0); ExpectIntEQ(wc_AsconHash256_Update(asconHash, msg, half_i), 0); ExpectIntEQ(wc_AsconHash256_Update(asconHash, msg + half_i, i - half_i), 0); ExpectIntEQ(wc_AsconHash256_Final(asconHash, mdOut), 0); ExpectBufEQ(mdOut, ascon_hash256_output[i], ASCON_HASH256_SZ); wc_AsconHash256_Clear(asconHash); } wc_AsconHash256_Free(asconHash); #endif return EXPECT_RESULT(); } int test_ascon_aead128(void) { EXPECT_DECLS; #ifdef HAVE_ASCON word32 i; wc_AsconAEAD128* asconAEAD = NULL; ExpectNotNull(asconAEAD = wc_AsconAEAD128_New()); 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++) { ExpectIntEQ(wc_AsconAEAD128_Init(asconAEAD), 0); ExpectIntEQ(wc_AsconAEAD128_SetKey(asconAEAD, key), 0); ExpectIntEQ(wc_AsconAEAD128_SetNonce(asconAEAD, nonce), 0); ExpectIntEQ(wc_AsconAEAD128_SetAD(asconAEAD, ad, adSz), 0); if (j == 0) { /* Encryption test */ ExpectIntEQ(wc_AsconAEAD128_EncryptUpdate(asconAEAD, buf, pt, ptSz), 0); ExpectBufEQ(buf, ct, ptSz); ExpectIntEQ(wc_AsconAEAD128_EncryptFinal(asconAEAD, tag), 0); ExpectBufEQ(tag, ct + ptSz, ASCON_AEAD128_TAG_SZ); } else if (j == 1) { /* Decryption test */ ExpectIntEQ(wc_AsconAEAD128_DecryptUpdate(asconAEAD, buf, ct, ctSz), 0); ExpectBufEQ(buf, pt, ctSz); ExpectIntEQ(wc_AsconAEAD128_DecryptFinal(asconAEAD, ct + ctSz), 0); } else if (j == 2) { /* Split encryption test */ ExpectIntEQ(wc_AsconAEAD128_EncryptUpdate(asconAEAD, buf, pt, ptSz / 2), 0); ExpectIntEQ(wc_AsconAEAD128_EncryptUpdate(asconAEAD, buf + (ptSz/2), pt + (ptSz/2), ptSz - (ptSz/2)), 0); ExpectBufEQ(buf, ct, ptSz); ExpectIntEQ(wc_AsconAEAD128_EncryptFinal(asconAEAD, tag), 0); ExpectBufEQ(tag, ct + ptSz, ASCON_AEAD128_TAG_SZ); } else if (j == 3) { /* Split decryption test */ ExpectIntEQ(wc_AsconAEAD128_DecryptUpdate(asconAEAD, buf, ct, ctSz / 2), 0); ExpectIntEQ(wc_AsconAEAD128_DecryptUpdate(asconAEAD, buf + (ctSz/2), ct + (ctSz/2), ctSz - (ctSz/2)), 0); ExpectBufEQ(buf, pt, ctSz); ExpectIntEQ(wc_AsconAEAD128_DecryptFinal(asconAEAD, ct + ctSz), 0); } wc_AsconAEAD128_Clear(asconAEAD); } } wc_AsconAEAD128_Free(asconAEAD); #endif return EXPECT_RESULT(); }