Commit 0e994190 by Enrico Pozzobon

Merge branch 'master' of lab.las3.de:lwc/candidates

parents cad26506 4eeaed87

Too many changes to show.

To preserve performance only 1000 of 1000+ files are displayed.

/*
* 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_ACE_H
#define LWCRYPTO_ACE_H
#include "aead-common.h"
/**
* \file ace.h
* \brief ACE authenticated encryption algorithm.
*
* ACE is an authenticated encryption algorithm with a 128-bit key,
* a 128-bit nonce, and a 128-bit tag. It uses a duplex construction
* on top of a 320-bit permutation. The permutation is a generalised
* version of sLiSCP-light, extended from 256 bits to 320 bits.
* ACE also has a companion hash algorithm with a 256-bit output.
*
* References: https://uwaterloo.ca/communications-security-lab/lwc/ace
*/
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief Size of the key for ACE.
*/
#define ACE_KEY_SIZE 16
/**
* \brief Size of the authentication tag for ACE.
*/
#define ACE_TAG_SIZE 16
/**
* \brief Size of the nonce for ACE.
*/
#define ACE_NONCE_SIZE 16
/**
* \brief Size of the hash output for ACE-HASH.
*/
#define ACE_HASH_SIZE 32
/**
* \brief Meta-information block for the ACE cipher.
*/
extern aead_cipher_t const ace_cipher;
/**
* \brief Meta-information block for the ACE-HASH hash algorithm.
*/
extern aead_hash_algorithm_t const ace_hash_algorithm;
/**
* \brief State information for the ACE-HASH incremental hash mode.
*/
typedef union
{
struct {
unsigned char state[40]; /**< Current hash state */
unsigned char count; /**< Number of bytes in the current block */
} s; /**< State */
unsigned long long align; /**< For alignment of this structure */
} ace_hash_state_t;
/**
* \brief Encrypts and authenticates a packet with ACE.
*
* \param c Buffer to receive the output.
* \param clen On exit, set to the length of the output which includes
* the ciphertext and the 16 byte 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 - not used by this algorithm.
* \param npub Points to the public nonce for the packet which must
* be 16 bytes in length.
* \param k Points to the 16 bytes of the key to use to encrypt the packet.
*
* \return 0 on success, or a negative value if there was an error in
* the parameters.
*
* \sa ace_aead_decrypt()
*/
int ace_aead_encrypt
(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 ACE.
*
* \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 - not used by this algorithm.
* \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 16 byte 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 which must
* be 16 bytes in length.
* \param k Points to the 16 bytes of 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.
*
* \sa ace_aead_encrypt()
*/
int ace_aead_decrypt
(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 with ACE-HASH to generate a hash value.
*
* \param out Buffer to receive the hash output which must be at least
* ACE_HASH_SIZE bytes in length.
* \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.
*/
int ace_hash
(unsigned char *out, const unsigned char *in, unsigned long long inlen);
/**
* \brief Initializes the state for an ACE-HASH hashing operation.
*
* \param state Hash state to be initialized.
*
* \sa ace_hash_update(), ace_hash_finalize(), ace_hash()
*/
void ace_hash_init(ace_hash_state_t *state);
/**
* \brief Updates the ACE-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.
*
* \sa ace_hash_init(), ace_hash_finalize()
*/
void ace_hash_update
(ace_hash_state_t *state, const unsigned char *in,
unsigned long long inlen);
/**
* \brief Returns the final hash value from an ACE-HASH hashing operation.
*
* \param state Hash state to be finalized.
* \param out Points to the output buffer to receive the 32-byte hash value.
*
* \sa ace_hash_init(), ace_hash_update()
*/
void ace_hash_finalize(ace_hash_state_t *state, unsigned char *out);
#ifdef __cplusplus
}
#endif
#endif
/*
* 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);
#ifdef __cplusplus
}
#endif
#endif
#define CRYPTO_KEYBYTES 16
#define CRYPTO_NSECBYTES 0
#define CRYPTO_NPUBBYTES 16
#define CRYPTO_ABYTES 16
#define CRYPTO_NOOVERLAP 1
#include "ace.h"
int crypto_aead_encrypt
(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)
{
return ace_aead_encrypt
(c, clen, m, mlen, ad, adlen, nsec, npub, k);
}
int crypto_aead_decrypt
(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)
{
return ace_aead_decrypt
(m, mlen, nsec, c, clen, ad, adlen, npub, k);
}
/*
* 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 LW_INTERNAL_SLISCP_LIGHT_H
#define LW_INTERNAL_SLISCP_LIGHT_H
/**
* \file internal-sliscp-light.h
* \brief sLiSCP-light permutation
*
* There are three variants of sLiSCP-light in use in the NIST submissions:
*
* \li sLiSCP-light-256 with a 256-bit block size, used in SPIX and SpoC.
* \li sLiSCP-light-192 with a 192-bit block size, used in SpoC.
* \li sLiSCP-light-320 with a 320-bit block size, used in ACE.
*
* References: https://uwaterloo.ca/communications-security-lab/lwc/ace,
* https://uwaterloo.ca/communications-security-lab/lwc/spix,
* https://uwaterloo.ca/communications-security-lab/lwc/spoc
*/
#include "internal-util.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief Size of the state for sLiSCP-light-256.
*/
#define SLISCP_LIGHT256_STATE_SIZE 32
/**
* \brief Size of the state for sLiSCP-light-192.
*/
#define SLISCP_LIGHT192_STATE_SIZE 24
/**
* \brief Size of the state for sLiSCP-light-320.
*/
#define SLISCP_LIGHT320_STATE_SIZE 40
/**
* \brief Performs the sLiSCP-light permutation on a 256-bit block.
*
* \param block Points to the block to be permuted.
* \param rounds Number of rounds to be performed, usually 9 or 18.
*
* The bytes of the block are assumed to be rearranged to match the
* requirements of the SPIX cipher. SPIX places the rate bytes at
* positions 8, 9, 10, 11, 24, 25, 26, and 27.
*
* This function assumes that bytes 24-27 have been pre-swapped with
* bytes 12-15 so that the rate portion of the state is contiguous.
*
* The sliscp_light256_swap_spix() function can be used to switch
* between the canonical order and the pre-swapped order.
*
* \sa sliscp_light256_swap_spix()
*/
void sliscp_light256_permute_spix(unsigned char block[32], unsigned rounds);
/**
* \brief Swaps rate bytes in a sLiSCP-light 256-bit block for SPIX.
*
* \param block Points to the block to be rate-swapped.
*
* \sa sliscp_light256_permute_spix()
*/
void sliscp_light256_swap_spix(unsigned char block[32]);
/**
* \brief Performs the sLiSCP-light permutation on a 256-bit block.
*
* \param block Points to the block to be permuted.
*
* The bytes of the block are assumed to be rearranged to match the
* requirements of the SpoC-128 cipher. SpoC-128 interleaves the
* rate bytes and the mask bytes. This version assumes that the
* rate and mask are in contiguous bytes of the state.
*
* SpoC-128 absorbs bytes using the mask bytes of the state at offsets
* 8, 9, 10, 11, 12, 13, 14, 15, 24, 25, 26, 27, 28, 29, 30, and 31.
* It squeezes bytes using the rate bytes of the state at offsets
* 0, 1, 2, 3, 4, 5, 6, 7, 16, 17, 18, 19, 20, 21, 22, and 23.
*
* This function assumes that bytes 8-15 have been pre-swapped with 16-23
* so that the rate and mask portions of the state are contiguous.
*
* The sliscp_light256_swap_spoc() function can be used to switch
* between the canonical order and the pre-swapped order.
*
* \sa sliscp_light256_swap_spoc()
*/
void sliscp_light256_permute_spoc(unsigned char block[32]);
/**
* \brief Swaps rate bytes in a sLiSCP-light 256-bit block for SpoC-128.
*
* \param block Points to the block to be rate-swapped.
*
* \sa sliscp_light256_permute_spoc()
*/
void sliscp_light256_swap_spoc(unsigned char block[32]);
/**
* \brief Performs the sLiSCP-light permutation on a 192-bit block.
*
* \param block Points to the block to be permuted.
*/
void sliscp_light192_permute(unsigned char block[24]);
/**
* \brief Performs the sLiSCP-light permutation on a 320-bit block.
*
* \param block Points to the block to be permuted.
*
* The ACE specification refers to this permutation as "ACE" but that
* can be confused with the name of the AEAD mode so we call this
* permutation "sLiSCP-light-320" instead.
*
* ACE absorbs and squeezes data at the rate bytes 0, 1, 2, 3, 16, 17, 18, 19.
* Efficiency can suffer because of the discontinuity in rate byte positions.
*
* To counteract this, we assume that the input to the permutation has been
* pre-swapped: bytes 4, 5, 6, 7 are swapped with bytes 16, 17, 18, 19 so
* that the rate is contiguous at the start of the state.
*
* The sliscp_light320_swap() function can be used to switch between the
* canonical order and the pre-swapped order.
*
* \sa sliscp_light320_swap()
*/
void sliscp_light320_permute(unsigned char block[40]);
/**
* \brief Swaps rate bytes in a sLiSCP-light 320-bit block.
*
* \param block Points to the block to be rate-swapped.
*
* \sa sliscp_light320_permute()
*/
void sliscp_light320_swap(unsigned char block[40]);
#ifdef __cplusplus
}
#endif
#endif
/*
* 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_ACE_H
#define LWCRYPTO_ACE_H
#include "aead-common.h"
/**
* \file ace.h
* \brief ACE authenticated encryption algorithm.
*
* ACE is an authenticated encryption algorithm with a 128-bit key,
* a 128-bit nonce, and a 128-bit tag. It uses a duplex construction
* on top of a 320-bit permutation. The permutation is a generalised
* version of sLiSCP-light, extended from 256 bits to 320 bits.
* ACE also has a companion hash algorithm with a 256-bit output.
*
* References: https://uwaterloo.ca/communications-security-lab/lwc/ace
*/
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief Size of the key for ACE.
*/
#define ACE_KEY_SIZE 16
/**
* \brief Size of the authentication tag for ACE.
*/
#define ACE_TAG_SIZE 16
/**
* \brief Size of the nonce for ACE.
*/
#define ACE_NONCE_SIZE 16
/**
* \brief Size of the hash output for ACE-HASH.
*/
#define ACE_HASH_SIZE 32
/**
* \brief Meta-information block for the ACE cipher.
*/
extern aead_cipher_t const ace_cipher;
/**
* \brief Meta-information block for the ACE-HASH hash algorithm.
*/
extern aead_hash_algorithm_t const ace_hash_algorithm;
/**
* \brief State information for the ACE-HASH incremental hash mode.
*/
typedef union
{
struct {
unsigned char state[40]; /**< Current hash state */
unsigned char count; /**< Number of bytes in the current block */
} s; /**< State */
unsigned long long align; /**< For alignment of this structure */
} ace_hash_state_t;
/**
* \brief Encrypts and authenticates a packet with ACE.
*
* \param c Buffer to receive the output.
* \param clen On exit, set to the length of the output which includes
* the ciphertext and the 16 byte 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 - not used by this algorithm.
* \param npub Points to the public nonce for the packet which must
* be 16 bytes in length.
* \param k Points to the 16 bytes of the key to use to encrypt the packet.
*
* \return 0 on success, or a negative value if there was an error in
* the parameters.
*
* \sa ace_aead_decrypt()
*/
int ace_aead_encrypt
(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 ACE.
*
* \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 - not used by this algorithm.
* \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 16 byte 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 which must
* be 16 bytes in length.
* \param k Points to the 16 bytes of 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.
*
* \sa ace_aead_encrypt()
*/
int ace_aead_decrypt
(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 with ACE-HASH to generate a hash value.
*
* \param out Buffer to receive the hash output which must be at least
* ACE_HASH_SIZE bytes in length.
* \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.
*/
int ace_hash
(unsigned char *out, const unsigned char *in, unsigned long long inlen);
/**
* \brief Initializes the state for an ACE-HASH hashing operation.
*
* \param state Hash state to be initialized.
*
* \sa ace_hash_update(), ace_hash_finalize(), ace_hash()
*/
void ace_hash_init(ace_hash_state_t *state);
/**
* \brief Updates the ACE-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.
*
* \sa ace_hash_init(), ace_hash_finalize()
*/
void ace_hash_update
(ace_hash_state_t *state, const unsigned char *in,
unsigned long long inlen);
/**
* \brief Returns the final hash value from an ACE-HASH hashing operation.
*
* \param state Hash state to be finalized.
* \param out Points to the output buffer to receive the 32-byte hash value.
*
* \sa ace_hash_init(), ace_hash_update()
*/
void ace_hash_finalize(ace_hash_state_t *state, unsigned char *out);
#ifdef __cplusplus
}
#endif
#endif
/*
* 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);
#ifdef __cplusplus
}
#endif
#endif
#include "ace.h"
int crypto_hash
(unsigned char *out, const unsigned char *in, unsigned long long inlen)
{
return ace_hash(out, in, inlen);
}
/*
* 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 LW_INTERNAL_SLISCP_LIGHT_H
#define LW_INTERNAL_SLISCP_LIGHT_H
/**
* \file internal-sliscp-light.h
* \brief sLiSCP-light permutation
*
* There are three variants of sLiSCP-light in use in the NIST submissions:
*
* \li sLiSCP-light-256 with a 256-bit block size, used in SPIX and SpoC.
* \li sLiSCP-light-192 with a 192-bit block size, used in SpoC.
* \li sLiSCP-light-320 with a 320-bit block size, used in ACE.
*
* References: https://uwaterloo.ca/communications-security-lab/lwc/ace,
* https://uwaterloo.ca/communications-security-lab/lwc/spix,
* https://uwaterloo.ca/communications-security-lab/lwc/spoc
*/
#include "internal-util.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief Size of the state for sLiSCP-light-256.
*/
#define SLISCP_LIGHT256_STATE_SIZE 32
/**
* \brief Size of the state for sLiSCP-light-192.
*/
#define SLISCP_LIGHT192_STATE_SIZE 24
/**
* \brief Size of the state for sLiSCP-light-320.
*/
#define SLISCP_LIGHT320_STATE_SIZE 40
/**
* \brief Performs the sLiSCP-light permutation on a 256-bit block.
*
* \param block Points to the block to be permuted.
* \param rounds Number of rounds to be performed, usually 9 or 18.
*
* The bytes of the block are assumed to be rearranged to match the
* requirements of the SPIX cipher. SPIX places the rate bytes at
* positions 8, 9, 10, 11, 24, 25, 26, and 27.
*
* This function assumes that bytes 24-27 have been pre-swapped with
* bytes 12-15 so that the rate portion of the state is contiguous.
*
* The sliscp_light256_swap_spix() function can be used to switch
* between the canonical order and the pre-swapped order.
*
* \sa sliscp_light256_swap_spix()
*/
void sliscp_light256_permute_spix(unsigned char block[32], unsigned rounds);
/**
* \brief Swaps rate bytes in a sLiSCP-light 256-bit block for SPIX.
*
* \param block Points to the block to be rate-swapped.
*
* \sa sliscp_light256_permute_spix()
*/
void sliscp_light256_swap_spix(unsigned char block[32]);
/**
* \brief Performs the sLiSCP-light permutation on a 256-bit block.
*
* \param block Points to the block to be permuted.
*
* The bytes of the block are assumed to be rearranged to match the
* requirements of the SpoC-128 cipher. SpoC-128 interleaves the
* rate bytes and the mask bytes. This version assumes that the
* rate and mask are in contiguous bytes of the state.
*
* SpoC-128 absorbs bytes using the mask bytes of the state at offsets
* 8, 9, 10, 11, 12, 13, 14, 15, 24, 25, 26, 27, 28, 29, 30, and 31.
* It squeezes bytes using the rate bytes of the state at offsets
* 0, 1, 2, 3, 4, 5, 6, 7, 16, 17, 18, 19, 20, 21, 22, and 23.
*
* This function assumes that bytes 8-15 have been pre-swapped with 16-23
* so that the rate and mask portions of the state are contiguous.
*
* The sliscp_light256_swap_spoc() function can be used to switch
* between the canonical order and the pre-swapped order.
*
* \sa sliscp_light256_swap_spoc()
*/
void sliscp_light256_permute_spoc(unsigned char block[32]);
/**
* \brief Swaps rate bytes in a sLiSCP-light 256-bit block for SpoC-128.
*
* \param block Points to the block to be rate-swapped.
*
* \sa sliscp_light256_permute_spoc()
*/
void sliscp_light256_swap_spoc(unsigned char block[32]);
/**
* \brief Performs the sLiSCP-light permutation on a 192-bit block.
*
* \param block Points to the block to be permuted.
*/
void sliscp_light192_permute(unsigned char block[24]);
/**
* \brief Performs the sLiSCP-light permutation on a 320-bit block.
*
* \param block Points to the block to be permuted.
*
* The ACE specification refers to this permutation as "ACE" but that
* can be confused with the name of the AEAD mode so we call this
* permutation "sLiSCP-light-320" instead.
*
* ACE absorbs and squeezes data at the rate bytes 0, 1, 2, 3, 16, 17, 18, 19.
* Efficiency can suffer because of the discontinuity in rate byte positions.
*
* To counteract this, we assume that the input to the permutation has been
* pre-swapped: bytes 4, 5, 6, 7 are swapped with bytes 16, 17, 18, 19 so
* that the rate is contiguous at the start of the state.
*
* The sliscp_light320_swap() function can be used to switch between the
* canonical order and the pre-swapped order.
*
* \sa sliscp_light320_swap()
*/
void sliscp_light320_permute(unsigned char block[40]);
/**
* \brief Swaps rate bytes in a sLiSCP-light 320-bit block.
*
* \param block Points to the block to be rate-swapped.
*
* \sa sliscp_light320_permute()
*/
void sliscp_light320_swap(unsigned char block[40]);
#ifdef __cplusplus
}
#endif
#endif
/*
* 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);
#ifdef __cplusplus
}
#endif
#endif
#define CRYPTO_KEYBYTES 16
#define CRYPTO_NSECBYTES 0
#define CRYPTO_NPUBBYTES 16
#define CRYPTO_ABYTES 16
#define CRYPTO_NOOVERLAP 1
#include "ascon128.h"
int crypto_aead_encrypt
(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)
{
return ascon128a_aead_encrypt
(c, clen, m, mlen, ad, adlen, nsec, npub, k);
}
int crypto_aead_decrypt
(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)
{
return ascon128a_aead_decrypt
(m, mlen, nsec, c, clen, ad, adlen, npub, k);
}
#if defined(__AVR__)
#include <avr/io.h>
/* Automatically generated - do not edit */
.text
.global ascon_permute
.type ascon_permute, @function
ascon_permute:
push r2
push r3
push r4
push r5
push r6
push r7
push r8
push r9
push r10
push r11
push r12
push r13
push r14
push r15
push r16
push r17
movw r30,r24
.L__stack_usage = 18
ldi r18,15
sub r18,r22
swap r18
or r22,r18
ldd r3,Z+16
ldd r2,Z+17
ldd r27,Z+18
ldd r26,Z+19
ldd r21,Z+20
ldd r20,Z+21
ldd r19,Z+22
ldd r18,Z+23
ldd r11,Z+32
ldd r10,Z+33
ldd r9,Z+34
ldd r8,Z+35
ldd r7,Z+36
ldd r6,Z+37
ldd r5,Z+38
ldd r4,Z+39
20:
eor r18,r22
ldd r23,Z+7
ldd r12,Z+15
ldd r13,Z+31
eor r23,r4
eor r4,r13
eor r18,r12
mov r14,r23
mov r15,r12
mov r24,r18
mov r25,r13
mov r16,r4
com r14
com r15
com r24
com r25
com r16
and r14,r12
and r15,r18
and r24,r13
and r25,r4
and r16,r23
eor r23,r15
eor r12,r24
eor r18,r25
eor r13,r16
eor r4,r14
eor r12,r23
eor r23,r4
eor r13,r18
com r18
std Z+7,r23
std Z+15,r12
std Z+31,r13
std Z+39,r4
ldd r23,Z+6
ldd r12,Z+14
ldd r13,Z+30
eor r23,r5
eor r5,r13
eor r19,r12
mov r14,r23
mov r15,r12
mov r24,r19
mov r25,r13
mov r16,r5
com r14
com r15
com r24
com r25
com r16
and r14,r12
and r15,r19
and r24,r13
and r25,r5
and r16,r23
eor r23,r15
eor r12,r24
eor r19,r25
eor r13,r16
eor r5,r14
eor r12,r23
eor r23,r5
eor r13,r19
com r19
std Z+6,r23
std Z+14,r12
std Z+30,r13
std Z+38,r5
ldd r23,Z+5
ldd r12,Z+13
ldd r13,Z+29
eor r23,r6
eor r6,r13
eor r20,r12
mov r14,r23
mov r15,r12
mov r24,r20
mov r25,r13
mov r16,r6
com r14
com r15
com r24
com r25
com r16
and r14,r12
and r15,r20
and r24,r13
and r25,r6
and r16,r23
eor r23,r15
eor r12,r24
eor r20,r25
eor r13,r16
eor r6,r14
eor r12,r23
eor r23,r6
eor r13,r20
com r20
std Z+5,r23
std Z+13,r12
std Z+29,r13
std Z+37,r6
ldd r23,Z+4
ldd r12,Z+12
ldd r13,Z+28
eor r23,r7
eor r7,r13
eor r21,r12
mov r14,r23
mov r15,r12
mov r24,r21
mov r25,r13
mov r16,r7
com r14
com r15
com r24
com r25
com r16
and r14,r12
and r15,r21
and r24,r13
and r25,r7
and r16,r23
eor r23,r15
eor r12,r24
eor r21,r25
eor r13,r16
eor r7,r14
eor r12,r23
eor r23,r7
eor r13,r21
com r21
std Z+4,r23
std Z+12,r12
std Z+28,r13
std Z+36,r7
ldd r23,Z+3
ldd r12,Z+11
ldd r13,Z+27
eor r23,r8
eor r8,r13
eor r26,r12
mov r14,r23
mov r15,r12
mov r24,r26
mov r25,r13
mov r16,r8
com r14
com r15
com r24
com r25
com r16
and r14,r12
and r15,r26
and r24,r13
and r25,r8
and r16,r23
eor r23,r15
eor r12,r24
eor r26,r25
eor r13,r16
eor r8,r14
eor r12,r23
eor r23,r8
eor r13,r26
com r26
std Z+3,r23
std Z+11,r12
std Z+27,r13
std Z+35,r8
ldd r23,Z+2
ldd r12,Z+10
ldd r13,Z+26
eor r23,r9
eor r9,r13
eor r27,r12
mov r14,r23
mov r15,r12
mov r24,r27
mov r25,r13
mov r16,r9
com r14
com r15
com r24
com r25
com r16
and r14,r12
and r15,r27
and r24,r13
and r25,r9
and r16,r23
eor r23,r15
eor r12,r24
eor r27,r25
eor r13,r16
eor r9,r14
eor r12,r23
eor r23,r9
eor r13,r27
com r27
std Z+2,r23
std Z+10,r12
std Z+26,r13
std Z+34,r9
ldd r23,Z+1
ldd r12,Z+9
ldd r13,Z+25
eor r23,r10
eor r10,r13
eor r2,r12
mov r14,r23
mov r15,r12
mov r24,r2
mov r25,r13
mov r16,r10
com r14
com r15
com r24
com r25
com r16
and r14,r12
and r15,r2
and r24,r13
and r25,r10
and r16,r23
eor r23,r15
eor r12,r24
eor r2,r25
eor r13,r16
eor r10,r14
eor r12,r23
eor r23,r10
eor r13,r2
com r2
std Z+1,r23
std Z+9,r12
std Z+25,r13
std Z+33,r10
ld r23,Z
ldd r12,Z+8
ldd r13,Z+24
eor r23,r11
eor r11,r13
eor r3,r12
mov r14,r23
mov r15,r12
mov r24,r3
mov r25,r13
mov r16,r11
com r14
com r15
com r24
com r25
com r16
and r14,r12
and r15,r3
and r24,r13
and r25,r11
and r16,r23
eor r23,r15
eor r12,r24
eor r3,r25
eor r13,r16
eor r11,r14
eor r12,r23
eor r23,r11
eor r13,r3
com r3
st Z,r23
std Z+8,r12
std Z+24,r13
std Z+32,r11
ld r11,Z
ldd r10,Z+1
ldd r9,Z+2
ldd r8,Z+3
ldd r7,Z+4
ldd r6,Z+5
ldd r5,Z+6
ldd r4,Z+7
movw r12,r4
movw r14,r6
movw r24,r8
movw r16,r10
mov r0,r12
mov r12,r14
mov r14,r24
mov r24,r16
mov r16,r0
mov r0,r13
mov r13,r15
mov r15,r25
mov r25,r17
mov r17,r0
mov r0,r1
lsr r17
ror r16
ror r25
ror r24
ror r15
ror r14
ror r13
ror r12
ror r0
lsr r17
ror r16
ror r25
ror r24
ror r15
ror r14
ror r13
ror r12
ror r0
lsr r17
ror r16
ror r25
ror r24
ror r15
ror r14
ror r13
ror r12
ror r0
or r17,r0
eor r12,r4
eor r13,r5
eor r14,r6
eor r15,r7
eor r24,r8
eor r25,r9
eor r16,r10
eor r17,r11
mov r23,r4
mov r0,r5
push r6
mov r4,r7
mov r5,r8
mov r6,r9
mov r7,r10
mov r8,r11
pop r11
mov r10,r0
mov r9,r23
mov r0,r1
lsr r11
ror r10
ror r9
ror r8
ror r7
ror r6
ror r5
ror r4
ror r0
lsr r11
ror r10
ror r9
ror r8
ror r7
ror r6
ror r5
ror r4
ror r0
lsr r11
ror r10
ror r9
ror r8
ror r7
ror r6
ror r5
ror r4
ror r0
lsr r11
ror r10
ror r9
ror r8
ror r7
ror r6
ror r5
ror r4
ror r0
or r11,r0
eor r4,r12
eor r5,r13
eor r6,r14
eor r7,r15
eor r8,r24
eor r9,r25
eor r10,r16
eor r11,r17
st Z,r11
std Z+1,r10
std Z+2,r9
std Z+3,r8
std Z+4,r7
std Z+5,r6
std Z+6,r5
std Z+7,r4
ldd r11,Z+8
ldd r10,Z+9
ldd r9,Z+10
ldd r8,Z+11
ldd r7,Z+12
ldd r6,Z+13
ldd r5,Z+14
ldd r4,Z+15
movw r12,r4
movw r14,r6
movw r24,r8
movw r16,r10
lsl r12
rol r13
rol r14
rol r15
rol r24
rol r25
rol r16
rol r17
adc r12,r1
lsl r12
rol r13
rol r14
rol r15
rol r24
rol r25
rol r16
rol r17
adc r12,r1
lsl r12
rol r13
rol r14
rol r15
rol r24
rol r25
rol r16
rol r17
adc r12,r1
eor r12,r4
eor r13,r5
eor r14,r6
eor r15,r7
eor r24,r8
eor r25,r9
eor r16,r10
eor r17,r11
mov r23,r9
mov r0,r10
push r11
mov r11,r8
mov r10,r7
mov r9,r6
mov r8,r5
mov r7,r4
pop r6
mov r5,r0
mov r4,r23
lsl r4
rol r5
rol r6
rol r7
rol r8
rol r9
rol r10
rol r11
adc r4,r1
eor r4,r12
eor r5,r13
eor r6,r14
eor r7,r15
eor r8,r24
eor r9,r25
eor r10,r16
eor r11,r17
std Z+8,r11
std Z+9,r10
std Z+10,r9
std Z+11,r8
std Z+12,r7
std Z+13,r6
std Z+14,r5
std Z+15,r4
movw r12,r18
movw r14,r20
movw r24,r26
movw r16,r2
bst r12,0
lsr r17
ror r16
ror r25
ror r24
ror r15
ror r14
ror r13
ror r12
bld r17,7
eor r12,r18
eor r13,r19
eor r14,r20
eor r15,r21
eor r24,r26
eor r25,r27
eor r16,r2
eor r17,r3
mov r0,r18
mov r18,r19
mov r19,r20
mov r20,r21
mov r21,r26
mov r26,r27
mov r27,r2
mov r2,r3
mov r3,r0
lsl r18
rol r19
rol r20
rol r21
rol r26
rol r27
rol r2
rol r3
adc r18,r1
lsl r18
rol r19
rol r20
rol r21
rol r26
rol r27
rol r2
rol r3
adc r18,r1
eor r18,r12
eor r19,r13
eor r20,r14
eor r21,r15
eor r26,r24
eor r27,r25
eor r2,r16
eor r3,r17
ldd r11,Z+24
ldd r10,Z+25
ldd r9,Z+26
ldd r8,Z+27
ldd r7,Z+28
ldd r6,Z+29
ldd r5,Z+30
ldd r4,Z+31
movw r12,r4
movw r14,r6
movw r24,r8
movw r16,r10
mov r0,r12
mov r12,r13
mov r13,r14
mov r14,r15
mov r15,r24
mov r24,r25
mov r25,r16
mov r16,r17
mov r17,r0
mov r0,r1
lsr r17
ror r16
ror r25
ror r24
ror r15
ror r14
ror r13
ror r12
ror r0
lsr r17
ror r16
ror r25
ror r24
ror r15
ror r14
ror r13
ror r12
ror r0
or r17,r0
eor r12,r4
eor r13,r5
eor r14,r6
eor r15,r7
eor r24,r8
eor r25,r9
eor r16,r10
eor r17,r11
mov r0,r4
mov r4,r6
mov r6,r8
mov r8,r10
mov r10,r0
mov r0,r5
mov r5,r7
mov r7,r9
mov r9,r11
mov r11,r0
mov r0,r1
lsr r11
ror r10
ror r9
ror r8
ror r7
ror r6
ror r5
ror r4
ror r0
or r11,r0
eor r4,r12
eor r5,r13
eor r6,r14
eor r7,r15
eor r8,r24
eor r9,r25
eor r10,r16
eor r11,r17
std Z+24,r11
std Z+25,r10
std Z+26,r9
std Z+27,r8
std Z+28,r7
std Z+29,r6
std Z+30,r5
std Z+31,r4
ldd r11,Z+32
ldd r10,Z+33
ldd r9,Z+34
ldd r8,Z+35
ldd r7,Z+36
ldd r6,Z+37
ldd r5,Z+38
ldd r4,Z+39
movw r12,r4
movw r14,r6
movw r24,r8
movw r16,r10
mov r0,r12
mov r12,r13
mov r13,r14
mov r14,r15
mov r15,r24
mov r24,r25
mov r25,r16
mov r16,r17
mov r17,r0
lsl r12
rol r13
rol r14
rol r15
rol r24
rol r25
rol r16
rol r17
adc r12,r1
eor r12,r4
eor r13,r5
eor r14,r6
eor r15,r7
eor r24,r8
eor r25,r9
eor r16,r10
eor r17,r11
mov r23,r9
mov r0,r10
push r11
mov r11,r8
mov r10,r7
mov r9,r6
mov r8,r5
mov r7,r4
pop r6
mov r5,r0
mov r4,r23
mov r0,r1
lsr r11
ror r10
ror r9
ror r8
ror r7
ror r6
ror r5
ror r4
ror r0
or r11,r0
eor r4,r12
eor r5,r13
eor r6,r14
eor r7,r15
eor r8,r24
eor r9,r25
eor r10,r16
eor r11,r17
subi r22,15
ldi r25,60
cpse r22,r25
rjmp 20b
std Z+16,r3
std Z+17,r2
std Z+18,r27
std Z+19,r26
std Z+20,r21
std Z+21,r20
std Z+22,r19
std Z+23,r18
std Z+32,r11
std Z+33,r10
std Z+34,r9
std Z+35,r8
std Z+36,r7
std Z+37,r6
std Z+38,r5
std Z+39,r4
pop r17
pop r16
pop r15
pop r14
pop r13
pop r12
pop r11
pop r10
pop r9
pop r8
pop r7
pop r6
pop r5
pop r4
pop r3
pop r2
ret
.size ascon_permute, .-ascon_permute
#endif
/*
* 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 "internal-ascon.h"
#if !defined(__AVR__)
void ascon_permute(ascon_state_t *state, uint8_t first_round)
{
uint64_t t0, t1, t2, t3, t4;
#if defined(LW_UTIL_LITTLE_ENDIAN)
uint64_t x0 = be_load_word64(state->B);
uint64_t x1 = be_load_word64(state->B + 8);
uint64_t x2 = be_load_word64(state->B + 16);
uint64_t x3 = be_load_word64(state->B + 24);
uint64_t x4 = be_load_word64(state->B + 32);
#else
uint64_t x0 = state->S[0];
uint64_t x1 = state->S[1];
uint64_t x2 = state->S[2];
uint64_t x3 = state->S[3];
uint64_t x4 = state->S[4];
#endif
while (first_round < 12) {
/* Add the round constant to the state */
x2 ^= ((0x0F - first_round) << 4) | first_round;
/* Substitution layer - apply the s-box using bit-slicing
* according to the algorithm recommended in the specification */
x0 ^= x4; x4 ^= x3; x2 ^= x1;
t0 = ~x0; t1 = ~x1; t2 = ~x2; t3 = ~x3; t4 = ~x4;
t0 &= x1; t1 &= x2; t2 &= x3; t3 &= x4; t4 &= x0;
x0 ^= t1; x1 ^= t2; x2 ^= t3; x3 ^= t4; x4 ^= t0;
x1 ^= x0; x0 ^= x4; x3 ^= x2; x2 = ~x2;
/* Linear diffusion layer */
x0 ^= rightRotate19_64(x0) ^ rightRotate28_64(x0);
x1 ^= rightRotate61_64(x1) ^ rightRotate39_64(x1);
x2 ^= rightRotate1_64(x2) ^ rightRotate6_64(x2);
x3 ^= rightRotate10_64(x3) ^ rightRotate17_64(x3);
x4 ^= rightRotate7_64(x4) ^ rightRotate41_64(x4);
/* Move onto the next round */
++first_round;
}
#if defined(LW_UTIL_LITTLE_ENDIAN)
be_store_word64(state->B, x0);
be_store_word64(state->B + 8, x1);
be_store_word64(state->B + 16, x2);
be_store_word64(state->B + 24, x3);
be_store_word64(state->B + 32, x4);
#else
state->S[0] = x0;
state->S[1] = x1;
state->S[2] = x2;
state->S[3] = x3;
state->S[4] = x4;
#endif
}
#endif /* !__AVR__ */
/*
* 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 LW_INTERNAL_ASCON_H
#define LW_INTERNAL_ASCON_H
#include "internal-util.h"
/**
* \file internal-ascon.h
* \brief Internal implementation of the ASCON permutation.
*
* References: http://competitions.cr.yp.to/round3/asconv12.pdf,
* http://ascon.iaik.tugraz.at/
*/
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief Structure of the internal state of the ASCON permutation.
*/
typedef union
{
uint64_t S[5]; /**< Words of the state */
uint8_t B[40]; /**< Bytes of the state */
} ascon_state_t;
/**
* \brief Permutes the ASCON state.
*
* \param state The ASCON state to be permuted.
* \param first_round The first round (of 12) to be performed; 0, 4, or 6.
*
* The input and output \a state will be in big-endian byte order.
*/
void ascon_permute(ascon_state_t *state, uint8_t first_round);
#ifdef __cplusplus
}
#endif
#endif
/*
* 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);
#ifdef __cplusplus
}
#endif
#endif
#define CRYPTO_KEYBYTES 16
#define CRYPTO_NSECBYTES 0
#define CRYPTO_NPUBBYTES 16
#define CRYPTO_ABYTES 16
#define CRYPTO_NOOVERLAP 1
#include "ascon128.h"
int crypto_aead_encrypt
(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)
{
return ascon128_aead_encrypt
(c, clen, m, mlen, ad, adlen, nsec, npub, k);
}
int crypto_aead_decrypt
(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)
{
return ascon128_aead_decrypt
(m, mlen, nsec, c, clen, ad, adlen, npub, k);
}
#if defined(__AVR__)
#include <avr/io.h>
/* Automatically generated - do not edit */
.text
.global ascon_permute
.type ascon_permute, @function
ascon_permute:
push r2
push r3
push r4
push r5
push r6
push r7
push r8
push r9
push r10
push r11
push r12
push r13
push r14
push r15
push r16
push r17
movw r30,r24
.L__stack_usage = 18
ldi r18,15
sub r18,r22
swap r18
or r22,r18
ldd r3,Z+16
ldd r2,Z+17
ldd r27,Z+18
ldd r26,Z+19
ldd r21,Z+20
ldd r20,Z+21
ldd r19,Z+22
ldd r18,Z+23
ldd r11,Z+32
ldd r10,Z+33
ldd r9,Z+34
ldd r8,Z+35
ldd r7,Z+36
ldd r6,Z+37
ldd r5,Z+38
ldd r4,Z+39
20:
eor r18,r22
ldd r23,Z+7
ldd r12,Z+15
ldd r13,Z+31
eor r23,r4
eor r4,r13
eor r18,r12
mov r14,r23
mov r15,r12
mov r24,r18
mov r25,r13
mov r16,r4
com r14
com r15
com r24
com r25
com r16
and r14,r12
and r15,r18
and r24,r13
and r25,r4
and r16,r23
eor r23,r15
eor r12,r24
eor r18,r25
eor r13,r16
eor r4,r14
eor r12,r23
eor r23,r4
eor r13,r18
com r18
std Z+7,r23
std Z+15,r12
std Z+31,r13
std Z+39,r4
ldd r23,Z+6
ldd r12,Z+14
ldd r13,Z+30
eor r23,r5
eor r5,r13
eor r19,r12
mov r14,r23
mov r15,r12
mov r24,r19
mov r25,r13
mov r16,r5
com r14
com r15
com r24
com r25
com r16
and r14,r12
and r15,r19
and r24,r13
and r25,r5
and r16,r23
eor r23,r15
eor r12,r24
eor r19,r25
eor r13,r16
eor r5,r14
eor r12,r23
eor r23,r5
eor r13,r19
com r19
std Z+6,r23
std Z+14,r12
std Z+30,r13
std Z+38,r5
ldd r23,Z+5
ldd r12,Z+13
ldd r13,Z+29
eor r23,r6
eor r6,r13
eor r20,r12
mov r14,r23
mov r15,r12
mov r24,r20
mov r25,r13
mov r16,r6
com r14
com r15
com r24
com r25
com r16
and r14,r12
and r15,r20
and r24,r13
and r25,r6
and r16,r23
eor r23,r15
eor r12,r24
eor r20,r25
eor r13,r16
eor r6,r14
eor r12,r23
eor r23,r6
eor r13,r20
com r20
std Z+5,r23
std Z+13,r12
std Z+29,r13
std Z+37,r6
ldd r23,Z+4
ldd r12,Z+12
ldd r13,Z+28
eor r23,r7
eor r7,r13
eor r21,r12
mov r14,r23
mov r15,r12
mov r24,r21
mov r25,r13
mov r16,r7
com r14
com r15
com r24
com r25
com r16
and r14,r12
and r15,r21
and r24,r13
and r25,r7
and r16,r23
eor r23,r15
eor r12,r24
eor r21,r25
eor r13,r16
eor r7,r14
eor r12,r23
eor r23,r7
eor r13,r21
com r21
std Z+4,r23
std Z+12,r12
std Z+28,r13
std Z+36,r7
ldd r23,Z+3
ldd r12,Z+11
ldd r13,Z+27
eor r23,r8
eor r8,r13
eor r26,r12
mov r14,r23
mov r15,r12
mov r24,r26
mov r25,r13
mov r16,r8
com r14
com r15
com r24
com r25
com r16
and r14,r12
and r15,r26
and r24,r13
and r25,r8
and r16,r23
eor r23,r15
eor r12,r24
eor r26,r25
eor r13,r16
eor r8,r14
eor r12,r23
eor r23,r8
eor r13,r26
com r26
std Z+3,r23
std Z+11,r12
std Z+27,r13
std Z+35,r8
ldd r23,Z+2
ldd r12,Z+10
ldd r13,Z+26
eor r23,r9
eor r9,r13
eor r27,r12
mov r14,r23
mov r15,r12
mov r24,r27
mov r25,r13
mov r16,r9
com r14
com r15
com r24
com r25
com r16
and r14,r12
and r15,r27
and r24,r13
and r25,r9
and r16,r23
eor r23,r15
eor r12,r24
eor r27,r25
eor r13,r16
eor r9,r14
eor r12,r23
eor r23,r9
eor r13,r27
com r27
std Z+2,r23
std Z+10,r12
std Z+26,r13
std Z+34,r9
ldd r23,Z+1
ldd r12,Z+9
ldd r13,Z+25
eor r23,r10
eor r10,r13
eor r2,r12
mov r14,r23
mov r15,r12
mov r24,r2
mov r25,r13
mov r16,r10
com r14
com r15
com r24
com r25
com r16
and r14,r12
and r15,r2
and r24,r13
and r25,r10
and r16,r23
eor r23,r15
eor r12,r24
eor r2,r25
eor r13,r16
eor r10,r14
eor r12,r23
eor r23,r10
eor r13,r2
com r2
std Z+1,r23
std Z+9,r12
std Z+25,r13
std Z+33,r10
ld r23,Z
ldd r12,Z+8
ldd r13,Z+24
eor r23,r11
eor r11,r13
eor r3,r12
mov r14,r23
mov r15,r12
mov r24,r3
mov r25,r13
mov r16,r11
com r14
com r15
com r24
com r25
com r16
and r14,r12
and r15,r3
and r24,r13
and r25,r11
and r16,r23
eor r23,r15
eor r12,r24
eor r3,r25
eor r13,r16
eor r11,r14
eor r12,r23
eor r23,r11
eor r13,r3
com r3
st Z,r23
std Z+8,r12
std Z+24,r13
std Z+32,r11
ld r11,Z
ldd r10,Z+1
ldd r9,Z+2
ldd r8,Z+3
ldd r7,Z+4
ldd r6,Z+5
ldd r5,Z+6
ldd r4,Z+7
movw r12,r4
movw r14,r6
movw r24,r8
movw r16,r10
mov r0,r12
mov r12,r14
mov r14,r24
mov r24,r16
mov r16,r0
mov r0,r13
mov r13,r15
mov r15,r25
mov r25,r17
mov r17,r0
mov r0,r1
lsr r17
ror r16
ror r25
ror r24
ror r15
ror r14
ror r13
ror r12
ror r0
lsr r17
ror r16
ror r25
ror r24
ror r15
ror r14
ror r13
ror r12
ror r0
lsr r17
ror r16
ror r25
ror r24
ror r15
ror r14
ror r13
ror r12
ror r0
or r17,r0
eor r12,r4
eor r13,r5
eor r14,r6
eor r15,r7
eor r24,r8
eor r25,r9
eor r16,r10
eor r17,r11
mov r23,r4
mov r0,r5
push r6
mov r4,r7
mov r5,r8
mov r6,r9
mov r7,r10
mov r8,r11
pop r11
mov r10,r0
mov r9,r23
mov r0,r1
lsr r11
ror r10
ror r9
ror r8
ror r7
ror r6
ror r5
ror r4
ror r0
lsr r11
ror r10
ror r9
ror r8
ror r7
ror r6
ror r5
ror r4
ror r0
lsr r11
ror r10
ror r9
ror r8
ror r7
ror r6
ror r5
ror r4
ror r0
lsr r11
ror r10
ror r9
ror r8
ror r7
ror r6
ror r5
ror r4
ror r0
or r11,r0
eor r4,r12
eor r5,r13
eor r6,r14
eor r7,r15
eor r8,r24
eor r9,r25
eor r10,r16
eor r11,r17
st Z,r11
std Z+1,r10
std Z+2,r9
std Z+3,r8
std Z+4,r7
std Z+5,r6
std Z+6,r5
std Z+7,r4
ldd r11,Z+8
ldd r10,Z+9
ldd r9,Z+10
ldd r8,Z+11
ldd r7,Z+12
ldd r6,Z+13
ldd r5,Z+14
ldd r4,Z+15
movw r12,r4
movw r14,r6
movw r24,r8
movw r16,r10
lsl r12
rol r13
rol r14
rol r15
rol r24
rol r25
rol r16
rol r17
adc r12,r1
lsl r12
rol r13
rol r14
rol r15
rol r24
rol r25
rol r16
rol r17
adc r12,r1
lsl r12
rol r13
rol r14
rol r15
rol r24
rol r25
rol r16
rol r17
adc r12,r1
eor r12,r4
eor r13,r5
eor r14,r6
eor r15,r7
eor r24,r8
eor r25,r9
eor r16,r10
eor r17,r11
mov r23,r9
mov r0,r10
push r11
mov r11,r8
mov r10,r7
mov r9,r6
mov r8,r5
mov r7,r4
pop r6
mov r5,r0
mov r4,r23
lsl r4
rol r5
rol r6
rol r7
rol r8
rol r9
rol r10
rol r11
adc r4,r1
eor r4,r12
eor r5,r13
eor r6,r14
eor r7,r15
eor r8,r24
eor r9,r25
eor r10,r16
eor r11,r17
std Z+8,r11
std Z+9,r10
std Z+10,r9
std Z+11,r8
std Z+12,r7
std Z+13,r6
std Z+14,r5
std Z+15,r4
movw r12,r18
movw r14,r20
movw r24,r26
movw r16,r2
bst r12,0
lsr r17
ror r16
ror r25
ror r24
ror r15
ror r14
ror r13
ror r12
bld r17,7
eor r12,r18
eor r13,r19
eor r14,r20
eor r15,r21
eor r24,r26
eor r25,r27
eor r16,r2
eor r17,r3
mov r0,r18
mov r18,r19
mov r19,r20
mov r20,r21
mov r21,r26
mov r26,r27
mov r27,r2
mov r2,r3
mov r3,r0
lsl r18
rol r19
rol r20
rol r21
rol r26
rol r27
rol r2
rol r3
adc r18,r1
lsl r18
rol r19
rol r20
rol r21
rol r26
rol r27
rol r2
rol r3
adc r18,r1
eor r18,r12
eor r19,r13
eor r20,r14
eor r21,r15
eor r26,r24
eor r27,r25
eor r2,r16
eor r3,r17
ldd r11,Z+24
ldd r10,Z+25
ldd r9,Z+26
ldd r8,Z+27
ldd r7,Z+28
ldd r6,Z+29
ldd r5,Z+30
ldd r4,Z+31
movw r12,r4
movw r14,r6
movw r24,r8
movw r16,r10
mov r0,r12
mov r12,r13
mov r13,r14
mov r14,r15
mov r15,r24
mov r24,r25
mov r25,r16
mov r16,r17
mov r17,r0
mov r0,r1
lsr r17
ror r16
ror r25
ror r24
ror r15
ror r14
ror r13
ror r12
ror r0
lsr r17
ror r16
ror r25
ror r24
ror r15
ror r14
ror r13
ror r12
ror r0
or r17,r0
eor r12,r4
eor r13,r5
eor r14,r6
eor r15,r7
eor r24,r8
eor r25,r9
eor r16,r10
eor r17,r11
mov r0,r4
mov r4,r6
mov r6,r8
mov r8,r10
mov r10,r0
mov r0,r5
mov r5,r7
mov r7,r9
mov r9,r11
mov r11,r0
mov r0,r1
lsr r11
ror r10
ror r9
ror r8
ror r7
ror r6
ror r5
ror r4
ror r0
or r11,r0
eor r4,r12
eor r5,r13
eor r6,r14
eor r7,r15
eor r8,r24
eor r9,r25
eor r10,r16
eor r11,r17
std Z+24,r11
std Z+25,r10
std Z+26,r9
std Z+27,r8
std Z+28,r7
std Z+29,r6
std Z+30,r5
std Z+31,r4
ldd r11,Z+32
ldd r10,Z+33
ldd r9,Z+34
ldd r8,Z+35
ldd r7,Z+36
ldd r6,Z+37
ldd r5,Z+38
ldd r4,Z+39
movw r12,r4
movw r14,r6
movw r24,r8
movw r16,r10
mov r0,r12
mov r12,r13
mov r13,r14
mov r14,r15
mov r15,r24
mov r24,r25
mov r25,r16
mov r16,r17
mov r17,r0
lsl r12
rol r13
rol r14
rol r15
rol r24
rol r25
rol r16
rol r17
adc r12,r1
eor r12,r4
eor r13,r5
eor r14,r6
eor r15,r7
eor r24,r8
eor r25,r9
eor r16,r10
eor r17,r11
mov r23,r9
mov r0,r10
push r11
mov r11,r8
mov r10,r7
mov r9,r6
mov r8,r5
mov r7,r4
pop r6
mov r5,r0
mov r4,r23
mov r0,r1
lsr r11
ror r10
ror r9
ror r8
ror r7
ror r6
ror r5
ror r4
ror r0
or r11,r0
eor r4,r12
eor r5,r13
eor r6,r14
eor r7,r15
eor r8,r24
eor r9,r25
eor r10,r16
eor r11,r17
subi r22,15
ldi r25,60
cpse r22,r25
rjmp 20b
std Z+16,r3
std Z+17,r2
std Z+18,r27
std Z+19,r26
std Z+20,r21
std Z+21,r20
std Z+22,r19
std Z+23,r18
std Z+32,r11
std Z+33,r10
std Z+34,r9
std Z+35,r8
std Z+36,r7
std Z+37,r6
std Z+38,r5
std Z+39,r4
pop r17
pop r16
pop r15
pop r14
pop r13
pop r12
pop r11
pop r10
pop r9
pop r8
pop r7
pop r6
pop r5
pop r4
pop r3
pop r2
ret
.size ascon_permute, .-ascon_permute
#endif
/*
* 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 "internal-ascon.h"
#if !defined(__AVR__)
void ascon_permute(ascon_state_t *state, uint8_t first_round)
{
uint64_t t0, t1, t2, t3, t4;
#if defined(LW_UTIL_LITTLE_ENDIAN)
uint64_t x0 = be_load_word64(state->B);
uint64_t x1 = be_load_word64(state->B + 8);
uint64_t x2 = be_load_word64(state->B + 16);
uint64_t x3 = be_load_word64(state->B + 24);
uint64_t x4 = be_load_word64(state->B + 32);
#else
uint64_t x0 = state->S[0];
uint64_t x1 = state->S[1];
uint64_t x2 = state->S[2];
uint64_t x3 = state->S[3];
uint64_t x4 = state->S[4];
#endif
while (first_round < 12) {
/* Add the round constant to the state */
x2 ^= ((0x0F - first_round) << 4) | first_round;
/* Substitution layer - apply the s-box using bit-slicing
* according to the algorithm recommended in the specification */
x0 ^= x4; x4 ^= x3; x2 ^= x1;
t0 = ~x0; t1 = ~x1; t2 = ~x2; t3 = ~x3; t4 = ~x4;
t0 &= x1; t1 &= x2; t2 &= x3; t3 &= x4; t4 &= x0;
x0 ^= t1; x1 ^= t2; x2 ^= t3; x3 ^= t4; x4 ^= t0;
x1 ^= x0; x0 ^= x4; x3 ^= x2; x2 = ~x2;
/* Linear diffusion layer */
x0 ^= rightRotate19_64(x0) ^ rightRotate28_64(x0);
x1 ^= rightRotate61_64(x1) ^ rightRotate39_64(x1);
x2 ^= rightRotate1_64(x2) ^ rightRotate6_64(x2);
x3 ^= rightRotate10_64(x3) ^ rightRotate17_64(x3);
x4 ^= rightRotate7_64(x4) ^ rightRotate41_64(x4);
/* Move onto the next round */
++first_round;
}
#if defined(LW_UTIL_LITTLE_ENDIAN)
be_store_word64(state->B, x0);
be_store_word64(state->B + 8, x1);
be_store_word64(state->B + 16, x2);
be_store_word64(state->B + 24, x3);
be_store_word64(state->B + 32, x4);
#else
state->S[0] = x0;
state->S[1] = x1;
state->S[2] = x2;
state->S[3] = x3;
state->S[4] = x4;
#endif
}
#endif /* !__AVR__ */
/*
* 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 LW_INTERNAL_ASCON_H
#define LW_INTERNAL_ASCON_H
#include "internal-util.h"
/**
* \file internal-ascon.h
* \brief Internal implementation of the ASCON permutation.
*
* References: http://competitions.cr.yp.to/round3/asconv12.pdf,
* http://ascon.iaik.tugraz.at/
*/
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief Structure of the internal state of the ASCON permutation.
*/
typedef union
{
uint64_t S[5]; /**< Words of the state */
uint8_t B[40]; /**< Bytes of the state */
} ascon_state_t;
/**
* \brief Permutes the ASCON state.
*
* \param state The ASCON state to be permuted.
* \param first_round The first round (of 12) to be performed; 0, 4, or 6.
*
* The input and output \a state will be in big-endian byte order.
*/
void ascon_permute(ascon_state_t *state, uint8_t first_round);
#ifdef __cplusplus
}
#endif
#endif
/*
* 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);
#ifdef __cplusplus
}
#endif
#endif
#define CRYPTO_KEYBYTES 20
#define CRYPTO_NSECBYTES 0
#define CRYPTO_NPUBBYTES 16
#define CRYPTO_ABYTES 16
#define CRYPTO_NOOVERLAP 1
#include "ascon128.h"
int crypto_aead_encrypt
(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)
{
return ascon80pq_aead_encrypt
(c, clen, m, mlen, ad, adlen, nsec, npub, k);
}
int crypto_aead_decrypt
(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)
{
return ascon80pq_aead_decrypt
(m, mlen, nsec, c, clen, ad, adlen, npub, k);
}
#if defined(__AVR__)
#include <avr/io.h>
/* Automatically generated - do not edit */
.text
.global ascon_permute
.type ascon_permute, @function
ascon_permute:
push r2
push r3
push r4
push r5
push r6
push r7
push r8
push r9
push r10
push r11
push r12
push r13
push r14
push r15
push r16
push r17
movw r30,r24
.L__stack_usage = 18
ldi r18,15
sub r18,r22
swap r18
or r22,r18
ldd r3,Z+16
ldd r2,Z+17
ldd r27,Z+18
ldd r26,Z+19
ldd r21,Z+20
ldd r20,Z+21
ldd r19,Z+22
ldd r18,Z+23
ldd r11,Z+32
ldd r10,Z+33
ldd r9,Z+34
ldd r8,Z+35
ldd r7,Z+36
ldd r6,Z+37
ldd r5,Z+38
ldd r4,Z+39
20:
eor r18,r22
ldd r23,Z+7
ldd r12,Z+15
ldd r13,Z+31
eor r23,r4
eor r4,r13
eor r18,r12
mov r14,r23
mov r15,r12
mov r24,r18
mov r25,r13
mov r16,r4
com r14
com r15
com r24
com r25
com r16
and r14,r12
and r15,r18
and r24,r13
and r25,r4
and r16,r23
eor r23,r15
eor r12,r24
eor r18,r25
eor r13,r16
eor r4,r14
eor r12,r23
eor r23,r4
eor r13,r18
com r18
std Z+7,r23
std Z+15,r12
std Z+31,r13
std Z+39,r4
ldd r23,Z+6
ldd r12,Z+14
ldd r13,Z+30
eor r23,r5
eor r5,r13
eor r19,r12
mov r14,r23
mov r15,r12
mov r24,r19
mov r25,r13
mov r16,r5
com r14
com r15
com r24
com r25
com r16
and r14,r12
and r15,r19
and r24,r13
and r25,r5
and r16,r23
eor r23,r15
eor r12,r24
eor r19,r25
eor r13,r16
eor r5,r14
eor r12,r23
eor r23,r5
eor r13,r19
com r19
std Z+6,r23
std Z+14,r12
std Z+30,r13
std Z+38,r5
ldd r23,Z+5
ldd r12,Z+13
ldd r13,Z+29
eor r23,r6
eor r6,r13
eor r20,r12
mov r14,r23
mov r15,r12
mov r24,r20
mov r25,r13
mov r16,r6
com r14
com r15
com r24
com r25
com r16
and r14,r12
and r15,r20
and r24,r13
and r25,r6
and r16,r23
eor r23,r15
eor r12,r24
eor r20,r25
eor r13,r16
eor r6,r14
eor r12,r23
eor r23,r6
eor r13,r20
com r20
std Z+5,r23
std Z+13,r12
std Z+29,r13
std Z+37,r6
ldd r23,Z+4
ldd r12,Z+12
ldd r13,Z+28
eor r23,r7
eor r7,r13
eor r21,r12
mov r14,r23
mov r15,r12
mov r24,r21
mov r25,r13
mov r16,r7
com r14
com r15
com r24
com r25
com r16
and r14,r12
and r15,r21
and r24,r13
and r25,r7
and r16,r23
eor r23,r15
eor r12,r24
eor r21,r25
eor r13,r16
eor r7,r14
eor r12,r23
eor r23,r7
eor r13,r21
com r21
std Z+4,r23
std Z+12,r12
std Z+28,r13
std Z+36,r7
ldd r23,Z+3
ldd r12,Z+11
ldd r13,Z+27
eor r23,r8
eor r8,r13
eor r26,r12
mov r14,r23
mov r15,r12
mov r24,r26
mov r25,r13
mov r16,r8
com r14
com r15
com r24
com r25
com r16
and r14,r12
and r15,r26
and r24,r13
and r25,r8
and r16,r23
eor r23,r15
eor r12,r24
eor r26,r25
eor r13,r16
eor r8,r14
eor r12,r23
eor r23,r8
eor r13,r26
com r26
std Z+3,r23
std Z+11,r12
std Z+27,r13
std Z+35,r8
ldd r23,Z+2
ldd r12,Z+10
ldd r13,Z+26
eor r23,r9
eor r9,r13
eor r27,r12
mov r14,r23
mov r15,r12
mov r24,r27
mov r25,r13
mov r16,r9
com r14
com r15
com r24
com r25
com r16
and r14,r12
and r15,r27
and r24,r13
and r25,r9
and r16,r23
eor r23,r15
eor r12,r24
eor r27,r25
eor r13,r16
eor r9,r14
eor r12,r23
eor r23,r9
eor r13,r27
com r27
std Z+2,r23
std Z+10,r12
std Z+26,r13
std Z+34,r9
ldd r23,Z+1
ldd r12,Z+9
ldd r13,Z+25
eor r23,r10
eor r10,r13
eor r2,r12
mov r14,r23
mov r15,r12
mov r24,r2
mov r25,r13
mov r16,r10
com r14
com r15
com r24
com r25
com r16
and r14,r12
and r15,r2
and r24,r13
and r25,r10
and r16,r23
eor r23,r15
eor r12,r24
eor r2,r25
eor r13,r16
eor r10,r14
eor r12,r23
eor r23,r10
eor r13,r2
com r2
std Z+1,r23
std Z+9,r12
std Z+25,r13
std Z+33,r10
ld r23,Z
ldd r12,Z+8
ldd r13,Z+24
eor r23,r11
eor r11,r13
eor r3,r12
mov r14,r23
mov r15,r12
mov r24,r3
mov r25,r13
mov r16,r11
com r14
com r15
com r24
com r25
com r16
and r14,r12
and r15,r3
and r24,r13
and r25,r11
and r16,r23
eor r23,r15
eor r12,r24
eor r3,r25
eor r13,r16
eor r11,r14
eor r12,r23
eor r23,r11
eor r13,r3
com r3
st Z,r23
std Z+8,r12
std Z+24,r13
std Z+32,r11
ld r11,Z
ldd r10,Z+1
ldd r9,Z+2
ldd r8,Z+3
ldd r7,Z+4
ldd r6,Z+5
ldd r5,Z+6
ldd r4,Z+7
movw r12,r4
movw r14,r6
movw r24,r8
movw r16,r10
mov r0,r12
mov r12,r14
mov r14,r24
mov r24,r16
mov r16,r0
mov r0,r13
mov r13,r15
mov r15,r25
mov r25,r17
mov r17,r0
mov r0,r1
lsr r17
ror r16
ror r25
ror r24
ror r15
ror r14
ror r13
ror r12
ror r0
lsr r17
ror r16
ror r25
ror r24
ror r15
ror r14
ror r13
ror r12
ror r0
lsr r17
ror r16
ror r25
ror r24
ror r15
ror r14
ror r13
ror r12
ror r0
or r17,r0
eor r12,r4
eor r13,r5
eor r14,r6
eor r15,r7
eor r24,r8
eor r25,r9
eor r16,r10
eor r17,r11
mov r23,r4
mov r0,r5
push r6
mov r4,r7
mov r5,r8
mov r6,r9
mov r7,r10
mov r8,r11
pop r11
mov r10,r0
mov r9,r23
mov r0,r1
lsr r11
ror r10
ror r9
ror r8
ror r7
ror r6
ror r5
ror r4
ror r0
lsr r11
ror r10
ror r9
ror r8
ror r7
ror r6
ror r5
ror r4
ror r0
lsr r11
ror r10
ror r9
ror r8
ror r7
ror r6
ror r5
ror r4
ror r0
lsr r11
ror r10
ror r9
ror r8
ror r7
ror r6
ror r5
ror r4
ror r0
or r11,r0
eor r4,r12
eor r5,r13
eor r6,r14
eor r7,r15
eor r8,r24
eor r9,r25
eor r10,r16
eor r11,r17
st Z,r11
std Z+1,r10
std Z+2,r9
std Z+3,r8
std Z+4,r7
std Z+5,r6
std Z+6,r5
std Z+7,r4
ldd r11,Z+8
ldd r10,Z+9
ldd r9,Z+10
ldd r8,Z+11
ldd r7,Z+12
ldd r6,Z+13
ldd r5,Z+14
ldd r4,Z+15
movw r12,r4
movw r14,r6
movw r24,r8
movw r16,r10
lsl r12
rol r13
rol r14
rol r15
rol r24
rol r25
rol r16
rol r17
adc r12,r1
lsl r12
rol r13
rol r14
rol r15
rol r24
rol r25
rol r16
rol r17
adc r12,r1
lsl r12
rol r13
rol r14
rol r15
rol r24
rol r25
rol r16
rol r17
adc r12,r1
eor r12,r4
eor r13,r5
eor r14,r6
eor r15,r7
eor r24,r8
eor r25,r9
eor r16,r10
eor r17,r11
mov r23,r9
mov r0,r10
push r11
mov r11,r8
mov r10,r7
mov r9,r6
mov r8,r5
mov r7,r4
pop r6
mov r5,r0
mov r4,r23
lsl r4
rol r5
rol r6
rol r7
rol r8
rol r9
rol r10
rol r11
adc r4,r1
eor r4,r12
eor r5,r13
eor r6,r14
eor r7,r15
eor r8,r24
eor r9,r25
eor r10,r16
eor r11,r17
std Z+8,r11
std Z+9,r10
std Z+10,r9
std Z+11,r8
std Z+12,r7
std Z+13,r6
std Z+14,r5
std Z+15,r4
movw r12,r18
movw r14,r20
movw r24,r26
movw r16,r2
bst r12,0
lsr r17
ror r16
ror r25
ror r24
ror r15
ror r14
ror r13
ror r12
bld r17,7
eor r12,r18
eor r13,r19
eor r14,r20
eor r15,r21
eor r24,r26
eor r25,r27
eor r16,r2
eor r17,r3
mov r0,r18
mov r18,r19
mov r19,r20
mov r20,r21
mov r21,r26
mov r26,r27
mov r27,r2
mov r2,r3
mov r3,r0
lsl r18
rol r19
rol r20
rol r21
rol r26
rol r27
rol r2
rol r3
adc r18,r1
lsl r18
rol r19
rol r20
rol r21
rol r26
rol r27
rol r2
rol r3
adc r18,r1
eor r18,r12
eor r19,r13
eor r20,r14
eor r21,r15
eor r26,r24
eor r27,r25
eor r2,r16
eor r3,r17
ldd r11,Z+24
ldd r10,Z+25
ldd r9,Z+26
ldd r8,Z+27
ldd r7,Z+28
ldd r6,Z+29
ldd r5,Z+30
ldd r4,Z+31
movw r12,r4
movw r14,r6
movw r24,r8
movw r16,r10
mov r0,r12
mov r12,r13
mov r13,r14
mov r14,r15
mov r15,r24
mov r24,r25
mov r25,r16
mov r16,r17
mov r17,r0
mov r0,r1
lsr r17
ror r16
ror r25
ror r24
ror r15
ror r14
ror r13
ror r12
ror r0
lsr r17
ror r16
ror r25
ror r24
ror r15
ror r14
ror r13
ror r12
ror r0
or r17,r0
eor r12,r4
eor r13,r5
eor r14,r6
eor r15,r7
eor r24,r8
eor r25,r9
eor r16,r10
eor r17,r11
mov r0,r4
mov r4,r6
mov r6,r8
mov r8,r10
mov r10,r0
mov r0,r5
mov r5,r7
mov r7,r9
mov r9,r11
mov r11,r0
mov r0,r1
lsr r11
ror r10
ror r9
ror r8
ror r7
ror r6
ror r5
ror r4
ror r0
or r11,r0
eor r4,r12
eor r5,r13
eor r6,r14
eor r7,r15
eor r8,r24
eor r9,r25
eor r10,r16
eor r11,r17
std Z+24,r11
std Z+25,r10
std Z+26,r9
std Z+27,r8
std Z+28,r7
std Z+29,r6
std Z+30,r5
std Z+31,r4
ldd r11,Z+32
ldd r10,Z+33
ldd r9,Z+34
ldd r8,Z+35
ldd r7,Z+36
ldd r6,Z+37
ldd r5,Z+38
ldd r4,Z+39
movw r12,r4
movw r14,r6
movw r24,r8
movw r16,r10
mov r0,r12
mov r12,r13
mov r13,r14
mov r14,r15
mov r15,r24
mov r24,r25
mov r25,r16
mov r16,r17
mov r17,r0
lsl r12
rol r13
rol r14
rol r15
rol r24
rol r25
rol r16
rol r17
adc r12,r1
eor r12,r4
eor r13,r5
eor r14,r6
eor r15,r7
eor r24,r8
eor r25,r9
eor r16,r10
eor r17,r11
mov r23,r9
mov r0,r10
push r11
mov r11,r8
mov r10,r7
mov r9,r6
mov r8,r5
mov r7,r4
pop r6
mov r5,r0
mov r4,r23
mov r0,r1
lsr r11
ror r10
ror r9
ror r8
ror r7
ror r6
ror r5
ror r4
ror r0
or r11,r0
eor r4,r12
eor r5,r13
eor r6,r14
eor r7,r15
eor r8,r24
eor r9,r25
eor r10,r16
eor r11,r17
subi r22,15
ldi r25,60
cpse r22,r25
rjmp 20b
std Z+16,r3
std Z+17,r2
std Z+18,r27
std Z+19,r26
std Z+20,r21
std Z+21,r20
std Z+22,r19
std Z+23,r18
std Z+32,r11
std Z+33,r10
std Z+34,r9
std Z+35,r8
std Z+36,r7
std Z+37,r6
std Z+38,r5
std Z+39,r4
pop r17
pop r16
pop r15
pop r14
pop r13
pop r12
pop r11
pop r10
pop r9
pop r8
pop r7
pop r6
pop r5
pop r4
pop r3
pop r2
ret
.size ascon_permute, .-ascon_permute
#endif
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment