Commit 526bda82 by Enrico Pozzobon

Merge branch 'rhys'

parent 745e7f1d
......@@ -52,23 +52,6 @@ static void hyena_double_delta(unsigned char D[8])
}
/**
* \brief Triples a delta value in the F(2^64) field.
*
* \param D The delta value to be tripled.
*
* D' = D ^ (D << 1) if the top-most bit is 0, or D' = D ^ (D << 1) ^ 0x1B
* otherwise.
*/
static void hyena_triple_delta(unsigned char D[8])
{
unsigned index;
unsigned char mask = (unsigned char)(((signed char)(D[0])) >> 7);
for (index = 0; index < 7; ++index)
D[index] ^= (D[index] << 1) | (D[index + 1] >> 7);
D[7] ^= (D[7] << 1) ^ (mask & 0x1B);
}
/**
* \brief Process the associated data for HYENA.
*
* \param ks Key schedule for the GIFT-128 cipher.
......@@ -83,26 +66,27 @@ static void hyena_process_ad
unsigned long long adlen)
{
unsigned char feedback[16];
hyena_double_delta(D);
while (adlen > 16) {
hyena_double_delta(D);
memcpy(feedback, ad, 16);
lw_xor_block(feedback + 8, Y + 8, 8);
lw_xor_block(feedback + 8, D, 8);
lw_xor_block(Y, feedback, 16);
gift128n_encrypt(ks, Y, Y);
hyena_double_delta(D);
ad += 16;
adlen -= 16;
}
if (adlen == 16) {
hyena_triple_delta(D);
hyena_double_delta(D);
memcpy(feedback, ad, 16);
lw_xor_block(feedback + 8, Y + 8, 8);
lw_xor_block(feedback + 8, D, 8);
lw_xor_block(Y, feedback, 16);
} else {
unsigned temp = (unsigned)adlen;
hyena_triple_delta(D);
hyena_triple_delta(D);
hyena_double_delta(D);
hyena_double_delta(D);
memcpy(feedback, ad, temp);
feedback[temp] = 0x01;
memset(feedback + temp + 1, 0, 15 - temp);
......@@ -132,7 +116,8 @@ int hyena_aead_encrypt
*clen = mlen + HYENA_TAG_SIZE;
/* Set up the key schedule and use it to encrypt the nonce */
gift128n_init(&ks, k);
if (!gift128n_init(&ks, k, HYENA_KEY_SIZE))
return -1;
Y[0] = 0;
if (adlen == 0)
Y[0] |= 0x01;
......@@ -164,7 +149,8 @@ int hyena_aead_encrypt
}
gift128n_encrypt(&ks, Y, Y);
if (mlen == 16) {
hyena_triple_delta(D);
hyena_double_delta(D);
hyena_double_delta(D);
memcpy(feedback, m, 16);
lw_xor_block(feedback + 8, Y + 8, 8);
lw_xor_block(feedback + 8, D, 8);
......@@ -173,8 +159,9 @@ int hyena_aead_encrypt
c += 16;
} else {
unsigned temp = (unsigned)mlen;
hyena_triple_delta(D);
hyena_triple_delta(D);
hyena_double_delta(D);
hyena_double_delta(D);
hyena_double_delta(D);
memcpy(feedback, m, temp);
feedback[temp] = 0x01;
memset(feedback + temp + 1, 0, 15 - temp);
......@@ -220,7 +207,8 @@ int hyena_aead_decrypt
*mlen = clen - HYENA_TAG_SIZE;
/* Set up the key schedule and use it to encrypt the nonce */
gift128n_init(&ks, k);
if (!gift128n_init(&ks, k, HYENA_KEY_SIZE))
return -1;
Y[0] = 0;
if (adlen == 0)
Y[0] |= 0x01;
......@@ -254,7 +242,8 @@ int hyena_aead_decrypt
}
gift128n_encrypt(&ks, Y, Y);
if (clen == 16) {
hyena_triple_delta(D);
hyena_double_delta(D);
hyena_double_delta(D);
memcpy(feedback + 8, c + 8, 8);
lw_xor_block_2_src(m, c, Y, 16);
memcpy(feedback, m, 8);
......@@ -263,8 +252,9 @@ int hyena_aead_decrypt
c += 16;
} else {
unsigned temp = (unsigned)clen;
hyena_triple_delta(D);
hyena_triple_delta(D);
hyena_double_delta(D);
hyena_double_delta(D);
hyena_double_delta(D);
if (temp > 8) {
memcpy(feedback + 8, c + 8, temp - 8);
lw_xor_block_2_src(m, c, Y, temp);
......
......@@ -47,13 +47,11 @@
* in any of the NIST submissions so we don't bother with it in this library.
*
* References: https://eprint.iacr.org/2017/622.pdf,
* https://eprint.iacr.org/2020/412.pdf,
* https://giftcipher.github.io/gift/
*/
#include <stddef.h>
#include <stdint.h>
#include "internal-gift128-config.h"
#ifdef __cplusplus
extern "C" {
......@@ -65,23 +63,16 @@ extern "C" {
#define GIFT128_BLOCK_SIZE 16
/**
* \var GIFT128_ROUND_KEYS
* \brief Number of round keys for the GIFT-128 key schedule.
* \brief Number of round keys for the fixsliced representation of GIFT-128.
*/
#if GIFT128_VARIANT == GIFT128_VARIANT_TINY
#define GIFT128_ROUND_KEYS 4
#elif GIFT128_VARIANT == GIFT128_VARIANT_SMALL
#define GIFT128_ROUND_KEYS 20
#else
#define GIFT128_ROUND_KEYS 80
#endif
/**
* \brief Structure of the key schedule for GIFT-128 (bit-sliced).
*/
typedef struct
{
/** Pre-computed round keys for bit-sliced GIFT-128 */
/** Pre-computed round keys in the fixsliced form */
uint32_t k[GIFT128_ROUND_KEYS];
} gift128b_key_schedule_t;
......@@ -90,9 +81,14 @@ typedef struct
* \brief Initializes the key schedule for GIFT-128 (bit-sliced).
*
* \param ks Points to the key schedule to initialize.
* \param key Points to the 16 bytes of the key data.
* \param key Points to the key data.
* \param key_len Length of the key data, which must be 16.
*
* \return Non-zero on success or zero if there is something wrong
* with the parameters.
*/
void gift128b_init(gift128b_key_schedule_t *ks, const unsigned char *key);
int gift128b_init
(gift128b_key_schedule_t *ks, const unsigned char *key, size_t key_len);
/**
* \brief Encrypts a 128-bit block with GIFT-128 (bit-sliced).
......@@ -149,9 +145,14 @@ typedef gift128b_key_schedule_t gift128n_key_schedule_t;
* \brief Initializes the key schedule for GIFT-128 (nibble-based).
*
* \param ks Points to the key schedule to initialize.
* \param key Points to the 16 bytes of the key data.
* \param key Points to the key data.
* \param key_len Length of the key data, which must be 16.
*
* \return Non-zero on success or zero if there is something wrong
* with the parameters.
*/
void gift128n_init(gift128n_key_schedule_t *ks, const unsigned char *key);
int gift128n_init
(gift128n_key_schedule_t *ks, const unsigned char *key, size_t key_len);
/**
* \brief Encrypts a 128-bit block with GIFT-128 (nibble-based).
......@@ -181,31 +182,13 @@ void gift128n_decrypt
(const gift128n_key_schedule_t *ks, unsigned char *output,
const unsigned char *input);
/* 4-bit tweak values expanded to 32-bit for TweGIFT-128 */
#define GIFT128T_TWEAK_0 0x00000000 /**< TweGIFT-128 tweak value 0 */
#define GIFT128T_TWEAK_1 0xe1e1e1e1 /**< TweGIFT-128 tweak value 1 */
#define GIFT128T_TWEAK_2 0xd2d2d2d2 /**< TweGIFT-128 tweak value 2 */
#define GIFT128T_TWEAK_3 0x33333333 /**< TweGIFT-128 tweak value 3 */
#define GIFT128T_TWEAK_4 0xb4b4b4b4 /**< TweGIFT-128 tweak value 4 */
#define GIFT128T_TWEAK_5 0x55555555 /**< TweGIFT-128 tweak value 5 */
#define GIFT128T_TWEAK_6 0x66666666 /**< TweGIFT-128 tweak value 6 */
#define GIFT128T_TWEAK_7 0x87878787 /**< TweGIFT-128 tweak value 7 */
#define GIFT128T_TWEAK_8 0x78787878 /**< TweGIFT-128 tweak value 8 */
#define GIFT128T_TWEAK_9 0x99999999 /**< TweGIFT-128 tweak value 9 */
#define GIFT128T_TWEAK_10 0xaaaaaaaa /**< TweGIFT-128 tweak value 10 */
#define GIFT128T_TWEAK_11 0x4b4b4b4b /**< TweGIFT-128 tweak value 11 */
#define GIFT128T_TWEAK_12 0xcccccccc /**< TweGIFT-128 tweak value 12 */
#define GIFT128T_TWEAK_13 0x2d2d2d2d /**< TweGIFT-128 tweak value 13 */
#define GIFT128T_TWEAK_14 0x1e1e1e1e /**< TweGIFT-128 tweak value 14 */
#define GIFT128T_TWEAK_15 0xffffffff /**< TweGIFT-128 tweak value 15 */
/**
* \brief Encrypts a 128-bit block with TweGIFT-128 (tweakable variant).
*
* \param ks Points to the GIFT-128 key schedule.
* \param output Output buffer which must be at least 16 bytes in length.
* \param input Input buffer which must be at least 16 bytes in length.
* \param tweak 4-bit tweak value expanded to 32-bit.
* \param tweak 4-bit tweak value.
*
* The \a input and \a output buffers can be the same buffer for
* in-place encryption.
......@@ -217,7 +200,7 @@ void gift128n_decrypt
*/
void gift128t_encrypt
(const gift128n_key_schedule_t *ks, unsigned char *output,
const unsigned char *input, uint32_t tweak);
const unsigned char *input, unsigned char tweak);
/**
* \brief Decrypts a 128-bit block with TweGIFT-128 (tweakable variant).
......@@ -225,7 +208,7 @@ void gift128t_encrypt
* \param ks Points to the GIFT-128 key schedule.
* \param output Output buffer which must be at least 16 bytes in length.
* \param input Input buffer which must be at least 16 bytes in length.
* \param tweak 4-bit tweak value expanded to 32-bit.
* \param tweak 4-bit tweak value.
*
* The \a input and \a output buffers can be the same buffer for
* in-place encryption.
......@@ -237,7 +220,7 @@ void gift128t_encrypt
*/
void gift128t_decrypt
(const gift128n_key_schedule_t *ks, unsigned char *output,
const unsigned char *input, uint32_t tweak);
const unsigned char *input, unsigned char tweak);
#ifdef __cplusplus
}
......
......@@ -238,17 +238,6 @@
} \
} while (0)
/* Rotation functions need to be optimised for best performance on AVR.
* The most efficient rotations are where the number of bits is 1 or a
* multiple of 8, so we compose the efficient rotations to produce all
* other rotation counts of interest. */
#if defined(__AVR__)
#define LW_CRYPTO_ROTATE32_COMPOSED 1
#else
#define LW_CRYPTO_ROTATE32_COMPOSED 0
#endif
/* Rotation macros for 32-bit arguments */
/* Generic left rotate */
......@@ -265,8 +254,6 @@
(_temp >> (bits)) | (_temp << (32 - (bits))); \
}))
#if !LW_CRYPTO_ROTATE32_COMPOSED
/* Left rotate by a specific number of bits. These macros may be replaced
* with more efficient ones on platforms that lack a barrel shifter */
#define leftRotate1(a) (leftRotate((a), 1))
......@@ -335,138 +322,6 @@
#define rightRotate30(a) (rightRotate((a), 30))
#define rightRotate31(a) (rightRotate((a), 31))
#else /* LW_CRYPTO_ROTATE32_COMPOSED */
/* Composed rotation macros where 1 and 8 are fast, but others are slow */
/* Left rotate by 1 */
#define leftRotate1(a) (leftRotate((a), 1))
/* Left rotate by 2 */
#define leftRotate2(a) (leftRotate(leftRotate((a), 1), 1))
/* Left rotate by 3 */
#define leftRotate3(a) (leftRotate(leftRotate(leftRotate((a), 1), 1), 1))
/* Left rotate by 4 */
#define leftRotate4(a) (leftRotate(leftRotate(leftRotate(leftRotate((a), 1), 1), 1), 1))
/* Left rotate by 5: Rotate left by 8, then right by 3 */
#define leftRotate5(a) (rightRotate(rightRotate(rightRotate(leftRotate((a), 8), 1), 1), 1))
/* Left rotate by 6: Rotate left by 8, then right by 2 */
#define leftRotate6(a) (rightRotate(rightRotate(leftRotate((a), 8), 1), 1))
/* Left rotate by 7: Rotate left by 8, then right by 1 */
#define leftRotate7(a) (rightRotate(leftRotate((a), 8), 1))
/* Left rotate by 8 */
#define leftRotate8(a) (leftRotate((a), 8))
/* Left rotate by 9: Rotate left by 8, then left by 1 */
#define leftRotate9(a) (leftRotate(leftRotate((a), 8), 1))
/* Left rotate by 10: Rotate left by 8, then left by 2 */
#define leftRotate10(a) (leftRotate(leftRotate(leftRotate((a), 8), 1), 1))
/* Left rotate by 11: Rotate left by 8, then left by 3 */
#define leftRotate11(a) (leftRotate(leftRotate(leftRotate(leftRotate((a), 8), 1), 1), 1))
/* Left rotate by 12: Rotate left by 16, then right by 4 */
#define leftRotate12(a) (rightRotate(rightRotate(rightRotate(rightRotate(leftRotate((a), 16), 1), 1), 1), 1))
/* Left rotate by 13: Rotate left by 16, then right by 3 */
#define leftRotate13(a) (rightRotate(rightRotate(rightRotate(leftRotate((a), 16), 1), 1), 1))
/* Left rotate by 14: Rotate left by 16, then right by 2 */
#define leftRotate14(a) (rightRotate(rightRotate(leftRotate((a), 16), 1), 1))
/* Left rotate by 15: Rotate left by 16, then right by 1 */
#define leftRotate15(a) (rightRotate(leftRotate((a), 16), 1))
/* Left rotate by 16 */
#define leftRotate16(a) (leftRotate((a), 16))
/* Left rotate by 17: Rotate left by 16, then left by 1 */
#define leftRotate17(a) (leftRotate(leftRotate((a), 16), 1))
/* Left rotate by 18: Rotate left by 16, then left by 2 */
#define leftRotate18(a) (leftRotate(leftRotate(leftRotate((a), 16), 1), 1))
/* Left rotate by 19: Rotate left by 16, then left by 3 */
#define leftRotate19(a) (leftRotate(leftRotate(leftRotate(leftRotate((a), 16), 1), 1), 1))
/* Left rotate by 20: Rotate left by 16, then left by 4 */
#define leftRotate20(a) (leftRotate(leftRotate(leftRotate(leftRotate(leftRotate((a), 16), 1), 1), 1), 1))
/* Left rotate by 21: Rotate left by 24, then right by 3 */
#define leftRotate21(a) (rightRotate(rightRotate(rightRotate(leftRotate((a), 24), 1), 1), 1))
/* Left rotate by 22: Rotate left by 24, then right by 2 */
#define leftRotate22(a) (rightRotate(rightRotate(leftRotate((a), 24), 1), 1))
/* Left rotate by 23: Rotate left by 24, then right by 1 */
#define leftRotate23(a) (rightRotate(leftRotate((a), 24), 1))
/* Left rotate by 24 */
#define leftRotate24(a) (leftRotate((a), 24))
/* Left rotate by 25: Rotate left by 24, then left by 1 */
#define leftRotate25(a) (leftRotate(leftRotate((a), 24), 1))
/* Left rotate by 26: Rotate left by 24, then left by 2 */
#define leftRotate26(a) (leftRotate(leftRotate(leftRotate((a), 24), 1), 1))
/* Left rotate by 27: Rotate left by 24, then left by 3 */
#define leftRotate27(a) (leftRotate(leftRotate(leftRotate(leftRotate((a), 24), 1), 1), 1))
/* Left rotate by 28: Rotate right by 4 */
#define leftRotate28(a) (rightRotate(rightRotate(rightRotate(rightRotate((a), 1), 1), 1), 1))
/* Left rotate by 29: Rotate right by 3 */
#define leftRotate29(a) (rightRotate(rightRotate(rightRotate((a), 1), 1), 1))
/* Left rotate by 30: Rotate right by 2 */
#define leftRotate30(a) (rightRotate(rightRotate((a), 1), 1))
/* Left rotate by 31: Rotate right by 1 */
#define leftRotate31(a) (rightRotate((a), 1))
/* Define the 32-bit right rotations in terms of left rotations */
#define rightRotate1(a) (leftRotate31((a)))
#define rightRotate2(a) (leftRotate30((a)))
#define rightRotate3(a) (leftRotate29((a)))
#define rightRotate4(a) (leftRotate28((a)))
#define rightRotate5(a) (leftRotate27((a)))
#define rightRotate6(a) (leftRotate26((a)))
#define rightRotate7(a) (leftRotate25((a)))
#define rightRotate8(a) (leftRotate24((a)))
#define rightRotate9(a) (leftRotate23((a)))
#define rightRotate10(a) (leftRotate22((a)))
#define rightRotate11(a) (leftRotate21((a)))
#define rightRotate12(a) (leftRotate20((a)))
#define rightRotate13(a) (leftRotate19((a)))
#define rightRotate14(a) (leftRotate18((a)))
#define rightRotate15(a) (leftRotate17((a)))
#define rightRotate16(a) (leftRotate16((a)))
#define rightRotate17(a) (leftRotate15((a)))
#define rightRotate18(a) (leftRotate14((a)))
#define rightRotate19(a) (leftRotate13((a)))
#define rightRotate20(a) (leftRotate12((a)))
#define rightRotate21(a) (leftRotate11((a)))
#define rightRotate22(a) (leftRotate10((a)))
#define rightRotate23(a) (leftRotate9((a)))
#define rightRotate24(a) (leftRotate8((a)))
#define rightRotate25(a) (leftRotate7((a)))
#define rightRotate26(a) (leftRotate6((a)))
#define rightRotate27(a) (leftRotate5((a)))
#define rightRotate28(a) (leftRotate4((a)))
#define rightRotate29(a) (leftRotate3((a)))
#define rightRotate30(a) (leftRotate2((a)))
#define rightRotate31(a) (leftRotate1((a)))
#endif /* LW_CRYPTO_ROTATE32_COMPOSED */
/* Rotation macros for 64-bit arguments */
/* Generic left rotate */
......
This source diff could not be displayed because it is too large. You can view the blob instead.
/*
* Copyright (C) 2020 Southern Storm Software, Pty Ltd.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#include "aead-common.h"
int aead_check_tag
(unsigned char *plaintext, unsigned long long plaintext_len,
const unsigned char *tag1, const unsigned char *tag2,
unsigned size)
{
/* Set "accum" to -1 if the tags match, or 0 if they don't match */
int accum = 0;
while (size > 0) {
accum |= (*tag1++ ^ *tag2++);
--size;
}
accum = (accum - 1) >> 8;
/* Destroy the plaintext if the tag match failed */
while (plaintext_len > 0) {
*plaintext++ &= accum;
--plaintext_len;
}
/* If "accum" is 0, return -1, otherwise return 0 */
return ~accum;
}
int aead_check_tag_precheck
(unsigned char *plaintext, unsigned long long plaintext_len,
const unsigned char *tag1, const unsigned char *tag2,
unsigned size, int precheck)
{
/* Set "accum" to -1 if the tags match, or 0 if they don't match */
int accum = 0;
while (size > 0) {
accum |= (*tag1++ ^ *tag2++);
--size;
}
accum = ((accum - 1) >> 8) & precheck;
/* Destroy the plaintext if the tag match failed */
while (plaintext_len > 0) {
*plaintext++ &= accum;
--plaintext_len;
}
/* If "accum" is 0, return -1, otherwise return 0 */
return ~accum;
}
/*
* Copyright (C) 2020 Southern Storm Software, Pty Ltd.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#ifndef LWCRYPTO_AEAD_COMMON_H
#define LWCRYPTO_AEAD_COMMON_H
#include <stddef.h>
/**
* \file aead-common.h
* \brief Definitions that are common across AEAD schemes.
*
* AEAD stands for "Authenticated Encryption with Associated Data".
* It is a standard API pattern for securely encrypting and
* authenticating packets of data.
*/
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief Encrypts and authenticates a packet with an AEAD scheme.
*
* \param c Buffer to receive the output.
* \param clen On exit, set to the length of the output which includes
* the ciphertext and the authentication tag.
* \param m Buffer that contains the plaintext message to encrypt.
* \param mlen Length of the plaintext message in bytes.
* \param ad Buffer that contains associated data to authenticate
* along with the packet but which does not need to be encrypted.
* \param adlen Length of the associated data in bytes.
* \param nsec Secret nonce - normally not used by AEAD schemes.
* \param npub Points to the public nonce for the packet.
* \param k Points to the key to use to encrypt the packet.
*
* \return 0 on success, or a negative value if there was an error in
* the parameters.
*/
typedef int (*aead_cipher_encrypt_t)
(unsigned char *c, unsigned long long *clen,
const unsigned char *m, unsigned long long mlen,
const unsigned char *ad, unsigned long long adlen,
const unsigned char *nsec,
const unsigned char *npub,
const unsigned char *k);
/**
* \brief Decrypts and authenticates a packet with an AEAD scheme.
*
* \param m Buffer to receive the plaintext message on output.
* \param mlen Receives the length of the plaintext message on output.
* \param nsec Secret nonce - normally not used by AEAD schemes.
* \param c Buffer that contains the ciphertext and authentication
* tag to decrypt.
* \param clen Length of the input data in bytes, which includes the
* ciphertext and the authentication tag.
* \param ad Buffer that contains associated data to authenticate
* along with the packet but which does not need to be encrypted.
* \param adlen Length of the associated data in bytes.
* \param npub Points to the public nonce for the packet.
* \param k Points to the key to use to decrypt the packet.
*
* \return 0 on success, -1 if the authentication tag was incorrect,
* or some other negative number if there was an error in the parameters.
*/
typedef int (*aead_cipher_decrypt_t)
(unsigned char *m, unsigned long long *mlen,
unsigned char *nsec,
const unsigned char *c, unsigned long long clen,
const unsigned char *ad, unsigned long long adlen,
const unsigned char *npub,
const unsigned char *k);
/**
* \brief Hashes a block of input data.
*
* \param out Buffer to receive the hash output.
* \param in Points to the input data to be hashed.
* \param inlen Length of the input data in bytes.
*
* \return Returns zero on success or -1 if there was an error in the
* parameters.
*/
typedef int (*aead_hash_t)
(unsigned char *out, const unsigned char *in, unsigned long long inlen);
/**
* \brief Initializes the state for a hashing operation.
*
* \param state Hash state to be initialized.
*/
typedef void (*aead_hash_init_t)(void *state);
/**
* \brief Updates a hash state with more input data.
*
* \param state Hash state to be updated.
* \param in Points to the input data to be incorporated into the state.
* \param inlen Length of the input data to be incorporated into the state.
*/
typedef void (*aead_hash_update_t)
(void *state, const unsigned char *in, unsigned long long inlen);
/**
* \brief Returns the final hash value from a hashing operation.
*
* \param Hash state to be finalized.
* \param out Points to the output buffer to receive the hash value.
*/
typedef void (*aead_hash_finalize_t)(void *state, unsigned char *out);
/**
* \brief Aborbs more input data into an XOF state.
*
* \param state XOF state to be updated.
* \param in Points to the input data to be absorbed into the state.
* \param inlen Length of the input data to be absorbed into the state.
*
* \sa ascon_xof_init(), ascon_xof_squeeze()
*/
typedef void (*aead_xof_absorb_t)
(void *state, const unsigned char *in, unsigned long long inlen);
/**
* \brief Squeezes output data from an XOF state.
*
* \param state XOF state to squeeze the output data from.
* \param out Points to the output buffer to receive the squeezed data.
* \param outlen Number of bytes of data to squeeze out of the state.
*/
typedef void (*aead_xof_squeeze_t)
(void *state, unsigned char *out, unsigned long long outlen);
/**
* \brief No special AEAD features.
*/
#define AEAD_FLAG_NONE 0x0000
/**
* \brief The natural byte order of the AEAD cipher is little-endian.
*
* If this flag is not present, then the natural byte order of the
* AEAD cipher should be assumed to be big-endian.
*
* The natural byte order may be useful when formatting packet sequence
* numbers as nonces. The application needs to know whether the sequence
* number should be packed into the leading or trailing bytes of the nonce.
*/
#define AEAD_FLAG_LITTLE_ENDIAN 0x0001
/**
* \brief Meta-information about an AEAD cipher.
*/
typedef struct
{
const char *name; /**< Name of the cipher */
unsigned key_len; /**< Length of the key in bytes */
unsigned nonce_len; /**< Length of the nonce in bytes */
unsigned tag_len; /**< Length of the tag in bytes */
unsigned flags; /**< Flags for extra features */
aead_cipher_encrypt_t encrypt; /**< AEAD encryption function */
aead_cipher_decrypt_t decrypt; /**< AEAD decryption function */
} aead_cipher_t;
/**
* \brief Meta-information about a hash algorithm that is related to an AEAD.
*
* Regular hash algorithms should provide the "hash", "init", "update",
* and "finalize" functions. Extensible Output Functions (XOF's) should
* proivde the "hash", "init", "absorb", and "squeeze" functions.
*/
typedef struct
{
const char *name; /**< Name of the hash algorithm */
size_t state_size; /**< Size of the incremental state structure */
unsigned hash_len; /**< Length of the hash in bytes */
unsigned flags; /**< Flags for extra features */
aead_hash_t hash; /**< All in one hashing function */
aead_hash_init_t init; /**< Incremental hash/XOF init function */
aead_hash_update_t update; /**< Incremental hash update function */
aead_hash_finalize_t finalize; /**< Incremental hash finalize function */
aead_xof_absorb_t absorb; /**< Incremental XOF absorb function */
aead_xof_squeeze_t squeeze; /**< Incremental XOF squeeze function */
} aead_hash_algorithm_t;
/**
* \brief Check an authentication tag in constant time.
*
* \param plaintext Points to the plaintext data.
* \param plaintext_len Length of the plaintext in bytes.
* \param tag1 First tag to compare.
* \param tag2 Second tag to compare.
* \param tag_len Length of the tags in bytes.
*
* \return Returns -1 if the tag check failed or 0 if the check succeeded.
*
* If the tag check fails, then the \a plaintext will also be zeroed to
* prevent it from being used accidentally by the application when the
* ciphertext was invalid.
*/
int aead_check_tag
(unsigned char *plaintext, unsigned long long plaintext_len,
const unsigned char *tag1, const unsigned char *tag2,
unsigned tag_len);
/**
* \brief Check an authentication tag in constant time with a previous check.
*
* \param plaintext Points to the plaintext data.
* \param plaintext_len Length of the plaintext in bytes.
* \param tag1 First tag to compare.
* \param tag2 Second tag to compare.
* \param tag_len Length of the tags in bytes.
* \param precheck Set to -1 if previous check succeeded or 0 if it failed.
*
* \return Returns -1 if the tag check failed or 0 if the check succeeded.
*
* If the tag check fails, then the \a plaintext will also be zeroed to
* prevent it from being used accidentally by the application when the
* ciphertext was invalid.
*
* This version can be used to incorporate other information about the
* correctness of the plaintext into the final result.
*/
int aead_check_tag_precheck
(unsigned char *plaintext, unsigned long long plaintext_len,
const unsigned char *tag1, const unsigned char *tag2,
unsigned tag_len, int precheck);