Commit d560a00f by Rhys Weatherley Committed by Sebastian Renner

Updated implementations from Rhys

parent ba578844
/*
* Copyright (C) 2021 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_ASCON_AEAD_H
#define LWCRYPTO_ASCON_AEAD_H
#include <stddef.h>
/**
* \file ascon-aead.h
* \brief ASCON-128 encryption algorithm and related family members.
*
* The ASCON family consists of several related algorithms:
*
* \li ASCON-128 with a 128-bit key, a 128-bit nonce, a 128-bit authentication
* tag, and a block rate of 64 bits.
* \li ASCON-128a with a 128-bit key, a 128-bit nonce, a 128-bit authentication
* tag, and a block rate of 128 bits. This is faster than ASCON-128 but may
* not be as secure.
* \li ASCON-80pq with a 160-bit key, a 128-bit nonce, a 128-bit authentication
* tag, and a block rate of 64 bits. This is similar to ASCON-128 but has a
* 160-bit key instead which may be more resistant against quantum computers.
* \li ASCON-HASH and ASCON-HASHA with a 256-bit hash output.
* \li ASCON-XOF and ASCON-XOFA with extensible hash output (XOF mode).
*
* References: https://ascon.iaik.tugraz.at/
*/
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief Size of the key for ASCON-128 and ASCON-128a.
*/
#define ASCON128_KEY_SIZE 16
/**
* \brief Size of the nonce for ASCON-128 and ASCON-128a.
*/
#define ASCON128_NONCE_SIZE 16
/**
* \brief Size of the authentication tag for ASCON-128 and ASCON-128a.
*/
#define ASCON128_TAG_SIZE 16
/**
* \brief Size of the key for ASCON-80pq.
*/
#define ASCON80PQ_KEY_SIZE 20
/**
* \brief Size of the nonce for ASCON-80pq.
*/
#define ASCON80PQ_NONCE_SIZE 16
/**
* \brief Size of the authentication tag for ASCON-80pq.
*/
#define ASCON80PQ_TAG_SIZE 16
/**
* \brief Encrypts and authenticates a packet with ASCON-128.
*
* \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 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 ascon128_aead_decrypt()
*/
int ascon128_aead_encrypt
(unsigned char *c, size_t *clen,
const unsigned char *m, size_t mlen,
const unsigned char *ad, size_t adlen,
const unsigned char *npub,
const unsigned char *k);
/**
* \brief Decrypts and authenticates a packet with ASCON-128.
*
* \param m Buffer to receive the plaintext message on output.
* \param mlen Receives the length of the plaintext message on output.
* \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 ascon128_aead_encrypt()
*/
int ascon128_aead_decrypt
(unsigned char *m, size_t *mlen,
const unsigned char *c, size_t clen,
const unsigned char *ad, size_t adlen,
const unsigned char *npub,
const unsigned char *k);
/**
* \brief Encrypts and authenticates a packet with ASCON-128a.
*
* \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 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 ascon128a_aead_decrypt()
*/
int ascon128a_aead_encrypt
(unsigned char *c, size_t *clen,
const unsigned char *m, size_t mlen,
const unsigned char *ad, size_t adlen,
const unsigned char *npub,
const unsigned char *k);
/**
* \brief Decrypts and authenticates a packet with ASCON-128a.
*
* \param m Buffer to receive the plaintext message on output.
* \param mlen Receives the length of the plaintext message on output.
* \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 ascon128a_aead_encrypt()
*/
int ascon128a_aead_decrypt
(unsigned char *m, size_t *mlen,
const unsigned char *c, size_t clen,
const unsigned char *ad, size_t adlen,
const unsigned char *npub,
const unsigned char *k);
/**
* \brief Encrypts and authenticates a packet with ASCON-80pq.
*
* \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 npub Points to the public nonce for the packet which must
* be 16 bytes in length.
* \param k Points to the 20 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 ascon80pq_aead_decrypt()
*/
int ascon80pq_aead_encrypt
(unsigned char *c, size_t *clen,
const unsigned char *m, size_t mlen,
const unsigned char *ad, size_t adlen,
const unsigned char *npub,
const unsigned char *k);
/**
* \brief Decrypts and authenticates a packet with ASCON-80pq.
*
* \param m Buffer to receive the plaintext message on output.
* \param mlen Receives the length of the plaintext message on output.
* \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 20 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 ascon80pq_aead_encrypt()
*/
int ascon80pq_aead_decrypt
(unsigned char *m, size_t *mlen,
const unsigned char *c, size_t clen,
const unsigned char *ad, size_t adlen,
const unsigned char *npub,
const unsigned char *k);
#ifdef __cplusplus
}
#endif
#endif
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
);
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
);
#include "ascon128.h"
#include "ascon-aead.h"
int crypto_aead_encrypt
(unsigned char *c, unsigned long long *clen,
......@@ -9,8 +9,12 @@ int crypto_aead_encrypt
const unsigned char *npub,
const unsigned char *k)
{
return ascon128a_aead_encrypt
(c, clen, m, mlen, ad, adlen, nsec, npub, k);
size_t len = 0;
int result = ascon128a_aead_encrypt
(c, &len, m, mlen, ad, adlen, npub, k);
(void)nsec;
*clen = len;
return result;
}
int crypto_aead_decrypt
......@@ -21,6 +25,10 @@ int crypto_aead_decrypt
const unsigned char *npub,
const unsigned char *k)
{
return ascon128a_aead_decrypt
(m, mlen, nsec, c, clen, ad, adlen, npub, k);
size_t len = 0;
int result = ascon128a_aead_decrypt
(m, &len, c, clen, ad, adlen, npub, k);
(void)nsec;
*mlen = len;
return result;
}
#if defined(__AVR__)
/*
* Copyright (C) 2021 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 <avr/io.h>
/* Automatically generated - do not edit */
......@@ -49,287 +71,223 @@ ascon_permute:
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
mov r14,r12
mov r15,r23
mov r24,r13
eor r14,r18
eor r15,r4
eor r24,r4
com r4
or r4,r13
eor r4,r14
eor r13,r12
or r13,r14
eor r13,r15
eor r18,r15
or r18,r12
eor r18,r24
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
and r12,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
or r23,r24
eor r23,r14
std Z+31,r23
std Z+39,r12
std Z+15,r13
std Z+23,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
mov r14,r12
mov r15,r23
mov r24,r13
eor r14,r19
eor r15,r5
eor r24,r5
com r5
or r5,r13
eor r5,r14
eor r13,r12
or r13,r14
eor r13,r15
eor r19,r15
or r19,r12
eor r19,r24
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
and r12,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
or r23,r24
eor r23,r14
std Z+30,r23
std Z+38,r12
std Z+14,r13
std Z+22,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
mov r14,r12
mov r15,r23
mov r24,r13
eor r14,r20
eor r15,r6
eor r24,r6
com r6
or r6,r13
eor r6,r14
eor r13,r12
or r13,r14
eor r13,r15
eor r20,r15
or r20,r12
eor r20,r24
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
and r12,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
or r23,r24
eor r23,r14
std Z+29,r23
std Z+37,r12
std Z+13,r13
std Z+21,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
mov r14,r12
mov r15,r23
mov r24,r13
eor r14,r21
eor r15,r7
eor r24,r7
com r7
or r7,r13
eor r7,r14
eor r13,r12
or r13,r14
eor r13,r15
eor r21,r15
or r21,r12
eor r21,r24
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
and r12,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
or r23,r24
eor r23,r14
std Z+28,r23
std Z+36,r12
std Z+12,r13
std Z+20,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
mov r14,r12
mov r15,r23
mov r24,r13
eor r14,r26
eor r15,r8
eor r24,r8
com r8
or r8,r13
eor r8,r14
eor r13,r12
or r13,r14
eor r13,r15
eor r26,r15
or r26,r12
eor r26,r24
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
and r12,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
or r23,r24
eor r23,r14
std Z+27,r23
std Z+35,r12
std Z+11,r13
std Z+19,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
mov r14,r12
mov r15,r23
mov r24,r13
eor r14,r27
eor r15,r9
eor r24,r9
com r9
or r9,r13
eor r9,r14
eor r13,r12
or r13,r14
eor r13,r15
eor r27,r15
or r27,r12
eor r27,r24
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
and r12,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
or r23,r24
eor r23,r14
std Z+26,r23
std Z+34,r12
std Z+10,r13
std Z+18,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
mov r14,r12
mov r15,r23
mov r24,r13
eor r14,r2
eor r15,r10
eor r24,r10
com r10
or r10,r13
eor r10,r14
eor r13,r12
or r13,r14
eor r13,r15
eor r2,r15
or r2,r12
eor r2,r24
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
and r12,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
or r23,r24
eor r23,r14
std Z+25,r23
std Z+33,r12
std Z+9,r13
std Z+17,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
mov r14,r12
mov r15,r23
mov r24,r13
eor r14,r3
eor r15,r11
eor r24,r11
com r11
or r11,r13
eor r11,r14
eor r13,r12
or r13,r14
eor r13,r15
eor r3,r15
or r3,r12
eor r3,r24
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
and r12,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
or r23,r24
eor r23,r14
std Z+24,r23
std Z+32,r12
std Z+8,r13
std Z+16,r11
movw r12,r18
movw r14,r20
movw r24,r26
movw r16,r2
mov r0,r12
mov r12,r14
mov r14,r24
......@@ -369,79 +327,79 @@ ascon_permute:
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
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 r23,r18
mov r0,r19
push r20
mov r18,r21
mov r19,r26
mov r20,r27
mov r21,r2
mov r26,r3
pop r3
mov r2,r0
mov r27,r23
mov r0,r1
lsr r11
ror r10
ror r9
ror r8
ror r7
ror r6
ror r5
ror r4
lsr r3
ror r2
ror r27
ror r26
ror r21
ror r20
ror r19
ror r18
ror r0
lsr r11
ror r10
ror r9
ror r8
ror r7
ror r6
ror r5
ror r4
lsr r3
ror r2
ror r27
ror r26
ror r21
ror r20
ror r19
ror r18
ror r0
lsr r11
ror r10
ror r9
ror r8
ror r7
ror r6
ror r5
ror r4
lsr r3
ror r2
ror r27
ror r26
ror r21
ror r20
ror r19
ror r18
ror r0
lsr r11
ror r10
ror r9
ror r8
ror r7
ror r6
ror r5
ror r4
lsr r3
ror r2
ror r27
ror r26
ror r21
ror r20
ror r19
ror r18
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
or r3,r0
eor r18,r12
eor r19,r13
eor r20,r14
eor r21,r15
eor r26,r24
eor r27,r25
eor r2,r16
eor r3,r17
st Z,r3
std Z+1,r2
std Z+2,r27
std Z+3,r26
std Z+4,r21
std Z+5,r20
std Z+6,r19
std Z+7,r18
ldd r11,Z+8
ldd r10,Z+9
ldd r9,Z+10
......@@ -525,6 +483,14 @@ ascon_permute:
std Z+13,r6
std Z+14,r5
std Z+15,r4
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
movw r12,r18
movw r14,r20
movw r24,r26
......
/*
* Copyright (C) 2020 Southern Storm Software, Pty Ltd.
* Copyright (C) 2021 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"),
......@@ -22,7 +22,19 @@
#include "internal-ascon.h"
#if !defined(__AVR__)
/* Determine which versions should be accelerated with assembly code */
#if defined(__AVR__)
#define ASCON_ASM_REGULAR 1
#define ASCON_ASM_SLICED 0
#elif defined(__ARM_ARCH_ISA_THUMB) && __ARM_ARCH == 7
#define ASCON_ASM_REGULAR 1
#define ASCON_ASM_SLICED 1
#else
#define ASCON_ASM_REGULAR 0
#define ASCON_ASM_SLICED 0
#endif
#if !ASCON_ASM_REGULAR
void ascon_permute(ascon_state_t *state, uint8_t first_round)
{
......@@ -77,4 +89,120 @@ void ascon_permute(ascon_state_t *state, uint8_t first_round)
#endif
}
#endif /* !__AVR__ */
#endif /* !ASCON_ASM_REGULAR */
#if ASCON_SLICED && !ASCON_ASM_SLICED
void ascon_to_sliced(ascon_state_t *state)
{
int index;
uint32_t high, low;
for (index = 0; index < 10; index += 2) {
high = be_load_word32(state->B + index * 4);
low = be_load_word32(state->B + index * 4 + 4);
ascon_separate(high);
ascon_separate(low);
state->W[index] = (high << 16) | (low & 0x0000FFFFU);
state->W[index + 1] = (high & 0xFFFF0000U) | (low >> 16);
}
}
void ascon_from_sliced(ascon_state_t *state)
{
int index;
uint32_t high, low;
for (index = 0; index < 10; index += 2) {
high = (state->W[index] >> 16) | (state->W[index + 1] & 0xFFFF0000U);
low = (state->W[index] & 0x0000FFFFU) | (state->W[index + 1] << 16);
ascon_combine(high);
ascon_combine(low);
be_store_word32(state->B + index * 4, high);
be_store_word32(state->B + index * 4 + 4, low);
}
}
void ascon_permute_sliced(ascon_state_t *state, uint8_t first_round)
{
static const unsigned char RC[12 * 2] = {
12, 12, 9, 12, 12, 9, 9, 9, 6, 12, 3, 12,
6, 9, 3, 9, 12, 6, 9, 6, 12, 3, 9, 3
};
const unsigned char *rc = RC + first_round * 2;
uint32_t t0, t1, t2, t3, t4;
/* Load the state into local variables */
uint32_t x0_e = state->W[0];
uint32_t x0_o = state->W[1];
uint32_t x1_e = state->W[2];
uint32_t x1_o = state->W[3];
uint32_t x2_e = state->W[4];
uint32_t x2_o = state->W[5];
uint32_t x3_e = state->W[6];
uint32_t x3_o = state->W[7];
uint32_t x4_e = state->W[8];
uint32_t x4_o = state->W[9];
/* Perform all permutation rounds */
while (first_round < 12) {
/* Add the round constants for this round to the state */
x2_e ^= rc[0];
x2_o ^= rc[1];
rc += 2;
/* Substitution layer */
#define ascon_sbox(x0, x1, x2, x3, x4) \
do { \
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; \
} while (0)
ascon_sbox(x0_e, x1_e, x2_e, x3_e, x4_e);
ascon_sbox(x0_o, x1_o, x2_o, x3_o, x4_o);
/* Linear diffusion layer */
/* x0 ^= rightRotate19_64(x0) ^ rightRotate28_64(x0); */
t0 = x0_e ^ rightRotate4(x0_o);
t1 = x0_o ^ rightRotate5(x0_e);
x0_e ^= rightRotate9(t1);
x0_o ^= rightRotate10(t0);
/* x1 ^= rightRotate61_64(x1) ^ rightRotate39_64(x1); */
t0 = x1_e ^ rightRotate11(x1_e);
t1 = x1_o ^ rightRotate11(x1_o);
x1_e ^= rightRotate19(t1);
x1_o ^= rightRotate20(t0);
/* x2 ^= rightRotate1_64(x2) ^ rightRotate6_64(x2); */
t0 = x2_e ^ rightRotate2(x2_o);
t1 = x2_o ^ rightRotate3(x2_e);
x2_e ^= t1;
x2_o ^= rightRotate1(t0);
/* x3 ^= rightRotate10_64(x3) ^ rightRotate17_64(x3); */
t0 = x3_e ^ rightRotate3(x3_o);
t1 = x3_o ^ rightRotate4(x3_e);
x3_e ^= rightRotate5(t0);
x3_o ^= rightRotate5(t1);
/* x4 ^= rightRotate7_64(x4) ^ rightRotate41_64(x4); */
t0 = x4_e ^ rightRotate17(x4_e);
t1 = x4_o ^ rightRotate17(x4_o);
x4_e ^= rightRotate3(t1);
x4_o ^= rightRotate4(t0);
/* Move onto the next round */
++first_round;
}
/* Write the local variables back to the state */
state->W[0] = x0_e;
state->W[1] = x0_o;
state->W[2] = x1_e;
state->W[3] = x1_o;
state->W[4] = x2_e;
state->W[5] = x2_o;
state->W[6] = x3_e;
state->W[7] = x3_o;
state->W[8] = x4_e;
state->W[9] = x4_o;
}
#endif /* ASCON_SLICED */
/*
* Copyright (C) 2020 Southern Storm Software, Pty Ltd.
* Copyright (C) 2021 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"),
......@@ -38,11 +38,36 @@ extern "C" {
#endif
/**
* \brief Defined to 1 if the 32-bit sliced version of ASCON is preferred.
*/
#if !defined(__AVR__) && !defined(LW_UTIL_CPU_IS_64BIT)
#define ASCON_SLICED 1
#else
#define ASCON_SLICED 0
#endif
/**
* \brief Initialization vector for ASCON-128.
*/
#define ASCON128_IV 0x80400c0600000000ULL
/**
* \brief Initialization vector for ASCON-128a.
*/
#define ASCON128a_IV 0x80800c0800000000ULL
/**
* \brief Initialization vector for ASCON-80pq.
*/
#define ASCON80PQ_IV 0xa0400c06U
/**
* \brief Structure of the internal state of the ASCON permutation.
*/
typedef union
{
uint64_t S[5]; /**< Words of the state */
uint64_t S[5]; /**< 64-bit words of the state */
uint32_t W[10]; /**< 32-bit words of the state */
uint8_t B[40]; /**< Bytes of the state */
} ascon_state_t;
......@@ -57,6 +82,237 @@ typedef union
*/
void ascon_permute(ascon_state_t *state, uint8_t first_round);
#if ASCON_SLICED
/**
* \brief Converts an ASCON state from byte form into sliced form.
*
* \param state The ASCON state to be converted, in big-endian byte order
* on entry and in host byte order on exit.
*/
void ascon_to_sliced(ascon_state_t *state);
/**
* \brief Converts an ASCON state from sliced form into byte form.
*
* \param state The ASCON state to be converted, in host byte order
* on entry and in big-endian byte order on exit.
*/
void ascon_from_sliced(ascon_state_t *state);
/**
* \brief Permutes the ASCON state in sliced form.
*
* \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 host byte order.
*/
void ascon_permute_sliced(ascon_state_t *state, uint8_t first_round);
/** @cond ascon_bit_separation */
/* http://programming.sirrida.de/perm_fn.html#bit_permute_step */
#define ascon_bit_permute_step(_y, mask, shift) \
do { \
uint32_t y = (_y); \
uint32_t t = ((y >> (shift)) ^ y) & (mask); \
(_y) = (y ^ t) ^ (t << (shift)); \
} while (0)
/* Separates a 32-bit word into two 16-bit halves with all the even
* bits in the bottom half and all the odd bits in the top half.
*
* Permutation generated with "http://programming.sirrida.de/calcperm.php"
*
* P = [0 16 1 17 2 18 3 19 4 20 5 21 6 22 7 23 8 24
* 9 25 10 26 11 27 12 28 13 29 14 30 15 31]
*/
#define ascon_separate(x) \
do { \
ascon_bit_permute_step((x), 0x22222222, 1); \
ascon_bit_permute_step((x), 0x0c0c0c0c, 2); \
ascon_bit_permute_step((x), 0x00f000f0, 4); \
ascon_bit_permute_step((x), 0x0000ff00, 8); \
} while (0)
#define ascon_combine(x) \
do { \
ascon_bit_permute_step((x), 0x0000aaaa, 15); \
ascon_bit_permute_step((x), 0x0000cccc, 14); \
ascon_bit_permute_step((x), 0x0000f0f0, 12); \
ascon_bit_permute_step((x), 0x0000ff00, 8); \
} while (0)
/** @endcond */
/**
* \brief Sets data into the ASCON state in sliced form.
*
* \param state The ASCON state for the data to be absorbed into.
* \param data Points to 8 bytes of data in big-endian byte order to set.
* \param offset Offset of the 64-bit word within the state to set at,
* between 0 and 4.
*/
#define ascon_set_sliced(state, data, offset) \
do { \
ascon_state_t *s = (state); \
uint32_t high = be_load_word32((data)); \
uint32_t low = be_load_word32((data) + 4); \
ascon_separate(high); \
ascon_separate(low); \
s->W[(offset) * 2] = (high << 16) | (low & 0x0000FFFFU); \
s->W[(offset) * 2 + 1] = (high & 0xFFFF0000U) | (low >> 16); \
} while (0)
/**
* \brief Absorbs data into the ASCON state in sliced form.
*
* \param state The ASCON state for the data to be absorbed into.
* \param data Points to 8 bytes of data in big-endian byte order to absorb.
* \param offset Offset of the 64-bit word within the state to absorb at,
* between 0 and 4.
*/
#define ascon_absorb_sliced(state, data, offset) \
do { \
ascon_state_t *s = (state); \
uint32_t high = be_load_word32((data)); \
uint32_t low = be_load_word32((data) + 4); \
ascon_separate(high); \
ascon_separate(low); \
s->W[(offset) * 2] ^= (high << 16) | (low & 0x0000FFFFU); \
s->W[(offset) * 2 + 1] ^= (high & 0xFFFF0000U) | (low >> 16); \
} while (0)
/**
* \brief Absorbs 32 bits of data into the ASCON state in sliced form.
*
* \param state The ASCON state for the data to be absorbed into.
* \param data Points to 4 bytes of data in big-endian byte order to absorb.
* \param offset Offset of the 64-bit word within the state to absorb at,
* between 0 and 4.
*
* The data is absorbed into the low bits of the 64-bit word at \a offset.
*/
#define ascon_absorb32_low_sliced(state, data, offset) \
do { \
ascon_state_t *s = (state); \
uint32_t low = be_load_word32((data)); \
ascon_separate(low); \
s->W[(offset) * 2] ^= (low & 0x0000FFFFU); \
s->W[(offset) * 2 + 1] ^= (low >> 16); \
} while (0)
/**
* \brief Absorbs 32 bits of data into the ASCON state in sliced form.
*
* \param state The ASCON state for the data to be absorbed into.
* \param data Points to 4 bytes of data in big-endian byte order to absorb.
* \param offset Offset of the 64-bit word within the state to absorb at,
* between 0 and 4.
*
* The data is absorbed into the high bits of the 64-bit word at \a offset.
*/
#define ascon_absorb32_high_sliced(state, data, offset) \
do { \
ascon_state_t *s = (state); \
uint32_t high = be_load_word32((data)); \
ascon_separate(high); \
s->W[(offset) * 2] ^= (high << 16); \
s->W[(offset) * 2 + 1] ^= (high & 0xFFFF0000U); \
} while (0)
/**
* \brief Squeezes data from the ASCON state in sliced form.
*
* \param state The ASCON state to extract the data from.
* \param data Points to the 8 bytes to be extracted from the state.
* \param offset Offset of the 64-bit word within the state to extract,
* between 0 and 4.
*/
#define ascon_squeeze_sliced(state, data, offset) \
do { \
ascon_state_t *s = (state); \
uint32_t high, low; \
high = (s->W[(offset) * 2] >> 16) | \
(s->W[(offset) * 2 + 1] & 0xFFFF0000U); \
low = (s->W[(offset) * 2] & 0x0000FFFFU) | \
(s->W[(offset) * 2 + 1] << 16); \
ascon_combine(high); \
ascon_combine(low); \
be_store_word32((data), high); \
be_store_word32((data) + 4, low); \
} while (0)
/**
* \brief Encrypts data using the ASCON state in sliced form.
*
* \param state The ASCON state.
* \param c Points to 8 bytes of output ciphertext in big-endian byte order.
* \param m Points to 8 bytes of input plaintext in big-endian byte order.
* \param offset Offset of the 64-bit word within the state to absorb
* and squeeze at, between 0 and 4.
*/
#define ascon_encrypt_sliced(state, c, m, offset) \
do { \
ascon_state_t *s = (state); \
uint32_t high = be_load_word32((m)); \
uint32_t low = be_load_word32((m) + 4); \
ascon_separate(high); \
ascon_separate(low); \
s->W[(offset) * 2] ^= (high << 16) | (low & 0x0000FFFFU); \
s->W[(offset) * 2 + 1] ^= (high & 0xFFFF0000U) | (low >> 16); \
high = (s->W[(offset) * 2] >> 16) | \
(s->W[(offset) * 2 + 1] & 0xFFFF0000U); \
low = (s->W[(offset) * 2] & 0x0000FFFFU) | \
(s->W[(offset) * 2 + 1] << 16); \
ascon_combine(high); \
ascon_combine(low); \
be_store_word32((c), high); \
be_store_word32((c) + 4, low); \
} while (0)
/**
* \brief Decrypts data using the ASCON state in sliced form.
*
* \param state The ASCON state.
* \param m Points to 8 bytes of output plaintext in big-endian byte order.
* \param c Points to 8 bytes of input ciphertext in big-endian byte order.
* \param offset Offset of the 64-bit word within the state to absorb
* and squeeze at, between 0 and 4.
*/
#define ascon_decrypt_sliced(state, m, c, offset) \
do { \
ascon_state_t *s = (state); \
uint32_t high, low, high2, low2; \
high = be_load_word32((c)); \
low = be_load_word32((c) + 4); \
ascon_separate(high); \
ascon_separate(low); \
high2 = high ^ ((s->W[(offset) * 2] >> 16) | \
(s->W[(offset) * 2 + 1] & 0xFFFF0000U)); \
low2 = low ^ ((s->W[(offset) * 2] & 0x0000FFFFU) | \
(s->W[(offset) * 2 + 1] << 16)); \
s->W[(offset) * 2] = (high << 16) | (low & 0x0000FFFFU); \
s->W[(offset) * 2 + 1] = (high & 0xFFFF0000U) | (low >> 16); \
ascon_combine(high2); \
ascon_combine(low2); \
be_store_word32((m), high2); \
be_store_word32((m) + 4, low2); \
} while (0)
#endif /* ASCON_SLICED */
/**
* \def ascon_separator()
* \brief Absorbs the standard ASCON separator for switching between
* associated data and message payload.
*/
#if ASCON_SLICED
#define ascon_separator() (state.W[8] ^= 0x01)
#else
#define ascon_separator() (state.B[39] ^= 0x01)
#endif
#ifdef __cplusplus
}
#endif
......
/*
* Copyright (C) 2021 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-util.h"
int aead_check_tag
(unsigned char *plaintext, size_t plaintext_len,
const unsigned char *tag1, const unsigned char *tag2, size_t 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;
}
void aead_clean(void *buf, unsigned size)
{
/* Force the use of volatile so that we actually clear the memory.
* Otherwise the compiler might optimise the entire contents of this
* function away, which will not be secure.
*
* Even this may not work. Some platforms have bzero_explicit() or
* memset_s() that could be used in place of this implementation. */
volatile uint8_t *d = (volatile uint8_t *)buf;
while (size > 0) {
*d++ = 0;
--size;
}
}
/*
* Copyright (C) 2020 Southern Storm Software, Pty Ltd.
* Copyright (C) 2021 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"),
......@@ -23,6 +23,7 @@
#ifndef LW_INTERNAL_UTIL_H
#define LW_INTERNAL_UTIL_H
#include <stddef.h>
#include <stdint.h>
/* Figure out how to inline functions using this C compiler */
......@@ -53,6 +54,13 @@
#error "Cannot determine the endianess of this platform"
#endif
/* Determine if we are compiling for a 64-bit CPU */
#if defined(__x86_64) || defined(__x86_64__) || \
defined(__aarch64__) || defined(__ARM_ARCH_ISA_A64) || \
defined(_M_AMD64) || defined(_M_X64) || defined(_M_IA64)
#define LW_UTIL_CPU_IS_64BIT 1
#endif
/* Helper macros to load and store values while converting endian-ness */
/* Load a big-endian 32-bit word from a byte buffer */
......@@ -89,6 +97,11 @@
(ptr)[3] = (uint8_t)(_x >> 24); \
} while (0)
/* Reverses the bytes in a 32-bit word */
#define reverse_word32(x) \
(((x) >> 24) | (((x) >> 8) & 0x0000FF00U) | \
(((x) << 8) & 0x00FF0000U) | ((x) << 24))
/* Load a big-endian 64-bit word from a byte buffer */
#define be_load_word64(ptr) \
((((uint64_t)((ptr)[0])) << 56) | \
......@@ -699,4 +712,52 @@
#define rightRotate6_8(a) (rightRotate_8((a), 6))
#define rightRotate7_8(a) (rightRotate_8((a), 7))
/**
* \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 size 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, size_t plaintext_len,
const unsigned char *tag1, const unsigned char *tag2, size_t size);
/**
* \brief Attempts to cleans a buffer that contains sensitive material.
*
* \param buf Points to the buffer to clear.
* \param size Size of the buffer to clear in bytes.
*/
void aead_clean(void *buf, unsigned size);
/**
* \brief Number of bytes to retrieve from the system TRNG each time
* we need to reseed application-level PRNG's.
*/
#define AEAD_SYSTEM_SEED_SIZE 32
/**
* \brief Gets data from the system TRNG to reseed application-level PRNG's.
*
* \param seed Points to the buffer to be populated with the system seed.
*
* \return Non-zero if \a seed has been filled with TRNG data or zero
* if there is no accessible TRNG on this system.
*
* The quality of the returned seed data may be very poor or may not
* distribute the entropy evenly throughout the returned \a seed buffer.
* The application should use a PRNG to hash the seed data into a more
* useful random sequence.
*/
int aead_random_get_system_seed(unsigned char seed[AEAD_SYSTEM_SEED_SIZE]);
#endif
/*
* Copyright (C) 2021 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_ASCON_AEAD_H
#define LWCRYPTO_ASCON_AEAD_H
#include <stddef.h>
/**
* \file ascon-aead.h
* \brief ASCON-128 encryption algorithm and related family members.
*
* The ASCON family consists of several related algorithms:
*
* \li ASCON-128 with a 128-bit key, a 128-bit nonce, a 128-bit authentication
* tag, and a block rate of 64 bits.
* \li ASCON-128a with a 128-bit key, a 128-bit nonce, a 128-bit authentication
* tag, and a block rate of 128 bits. This is faster than ASCON-128 but may
* not be as secure.
* \li ASCON-80pq with a 160-bit key, a 128-bit nonce, a 128-bit authentication
* tag, and a block rate of 64 bits. This is similar to ASCON-128 but has a
* 160-bit key instead which may be more resistant against quantum computers.
* \li ASCON-HASH and ASCON-HASHA with a 256-bit hash output.
* \li ASCON-XOF and ASCON-XOFA with extensible hash output (XOF mode).
*
* References: https://ascon.iaik.tugraz.at/
*/
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief Size of the key for ASCON-128 and ASCON-128a.
*/
#define ASCON128_KEY_SIZE 16
/**
* \brief Size of the nonce for ASCON-128 and ASCON-128a.
*/
#define ASCON128_NONCE_SIZE 16
/**
* \brief Size of the authentication tag for ASCON-128 and ASCON-128a.
*/
#define ASCON128_TAG_SIZE 16
/**
* \brief Size of the key for ASCON-80pq.
*/
#define ASCON80PQ_KEY_SIZE 20
/**
* \brief Size of the nonce for ASCON-80pq.
*/
#define ASCON80PQ_NONCE_SIZE 16
/**
* \brief Size of the authentication tag for ASCON-80pq.
*/
#define ASCON80PQ_TAG_SIZE 16
/**
* \brief Encrypts and authenticates a packet with ASCON-128.
*
* \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 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 ascon128_aead_decrypt()
*/
int ascon128_aead_encrypt
(unsigned char *c, size_t *clen,
const unsigned char *m, size_t mlen,
const unsigned char *ad, size_t adlen,
const unsigned char *npub,
const unsigned char *k);
/**
* \brief Decrypts and authenticates a packet with ASCON-128.
*
* \param m Buffer to receive the plaintext message on output.
* \param mlen Receives the length of the plaintext message on output.
* \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 ascon128_aead_encrypt()
*/
int ascon128_aead_decrypt
(unsigned char *m, size_t *mlen,
const unsigned char *c, size_t clen,
const unsigned char *ad, size_t adlen,
const unsigned char *npub,
const unsigned char *k);
/**
* \brief Encrypts and authenticates a packet with ASCON-128a.
*
* \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 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 ascon128a_aead_decrypt()
*/
int ascon128a_aead_encrypt
(unsigned char *c, size_t *clen,
const unsigned char *m, size_t mlen,
const unsigned char *ad, size_t adlen,
const unsigned char *npub,
const unsigned char *k);
/**
* \brief Decrypts and authenticates a packet with ASCON-128a.
*
* \param m Buffer to receive the plaintext message on output.
* \param mlen Receives the length of the plaintext message on output.
* \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 ascon128a_aead_encrypt()
*/
int ascon128a_aead_decrypt
(unsigned char *m, size_t *mlen,
const unsigned char *c, size_t clen,
const unsigned char *ad, size_t adlen,
const unsigned char *npub,
const unsigned char *k);
/**
* \brief Encrypts and authenticates a packet with ASCON-80pq.
*
* \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 npub Points to the public nonce for the packet which must
* be 16 bytes in length.
* \param k Points to the 20 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 ascon80pq_aead_decrypt()
*/
int ascon80pq_aead_encrypt
(unsigned char *c, size_t *clen,
const unsigned char *m, size_t mlen,
const unsigned char *ad, size_t adlen,
const unsigned char *npub,
const unsigned char *k);
/**
* \brief Decrypts and authenticates a packet with ASCON-80pq.
*
* \param m Buffer to receive the plaintext message on output.
* \param mlen Receives the length of the plaintext message on output.
* \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 20 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 ascon80pq_aead_encrypt()
*/
int ascon80pq_aead_decrypt
(unsigned char *m, size_t *mlen,
const unsigned char *c, size_t clen,
const unsigned char *ad, size_t adlen,
const unsigned char *npub,
const unsigned char *k);
#ifdef __cplusplus
}
#endif
#endif
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
);
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
);
#include "ascon128.h"
#include "ascon-aead.h"
int crypto_aead_encrypt
(unsigned char *c, unsigned long long *clen,
......@@ -9,8 +9,12 @@ int crypto_aead_encrypt
const unsigned char *npub,
const unsigned char *k)
{
return ascon128_aead_encrypt
(c, clen, m, mlen, ad, adlen, nsec, npub, k);
size_t len = 0;
int result = ascon128_aead_encrypt
(c, &len, m, mlen, ad, adlen, npub, k);
(void)nsec;
*clen = len;
return result;
}
int crypto_aead_decrypt
......@@ -21,6 +25,10 @@ int crypto_aead_decrypt
const unsigned char *npub,
const unsigned char *k)
{
return ascon128_aead_decrypt
(m, mlen, nsec, c, clen, ad, adlen, npub, k);
size_t len = 0;
int result = ascon128_aead_decrypt
(m, &len, c, clen, ad, adlen, npub, k);
(void)nsec;
*mlen = len;
return result;
}
#if defined(__AVR__)
/*
* Copyright (C) 2021 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 <avr/io.h>
/* Automatically generated - do not edit */
......@@ -49,287 +71,223 @@ ascon_permute:
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
mov r14,r12
mov r15,r23
mov r24,r13
eor r14,r18
eor r15,r4
eor r24,r4
com r4
or r4,r13
eor r4,r14
eor r13,r12
or r13,r14
eor r13,r15
eor r18,r15
or r18,r12
eor r18,r24
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
and r12,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
or r23,r24
eor r23,r14
std Z+31,r23
std Z+39,r12
std Z+15,r13
std Z+23,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
mov r14,r12
mov r15,r23
mov r24,r13
eor r14,r19
eor r15,r5
eor r24,r5
com r5
or r5,r13
eor r5,r14
eor r13,r12
or r13,r14
eor r13,r15
eor r19,r15
or r19,r12
eor r19,r24
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
and r12,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
or r23,r24
eor r23,r14
std Z+30,r23
std Z+38,r12
std Z+14,r13
std Z+22,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
mov r14,r12
mov r15,r23
mov r24,r13
eor r14,r20
eor r15,r6
eor r24,r6
com r6
or r6,r13
eor r6,r14
eor r13,r12
or r13,r14
eor r13,r15
eor r20,r15
or r20,r12
eor r20,r24
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
and r12,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
or r23,r24
eor r23,r14
std Z+29,r23
std Z+37,r12
std Z+13,r13
std Z+21,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
mov r14,r12
mov r15,r23
mov r24,r13
eor r14,r21
eor r15,r7
eor r24,r7
com r7
or r7,r13
eor r7,r14
eor r13,r12
or r13,r14
eor r13,r15
eor r21,r15
or r21,r12
eor r21,r24
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
and r12,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
or r23,r24
eor r23,r14
std Z+28,r23
std Z+36,r12
std Z+12,r13
std Z+20,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
mov r14,r12
mov r15,r23
mov r24,r13
eor r14,r26
eor r15,r8
eor r24,r8
com r8
or r8,r13
eor r8,r14
eor r13,r12
or r13,r14
eor r13,r15
eor r26,r15
or r26,r12
eor r26,r24
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
and r12,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
or r23,r24
eor r23,r14
std Z+27,r23
std Z+35,r12
std Z+11,r13
std Z+19,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
mov r14,r12
mov r15,r23
mov r24,r13
eor r14,r27
eor r15,r9
eor r24,r9
com r9
or r9,r13
eor r9,r14
eor r13,r12
or r13,r14
eor r13,r15
eor r27,r15
or r27,r12
eor r27,r24
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
and r12,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
or r23,r24
eor r23,r14
std Z+26,r23
std Z+34,r12
std Z+10,r13
std Z+18,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
mov r14,r12
mov r15,r23
mov r24,r13
eor r14,r2
eor r15,r10
eor r24,r10
com r10
or r10,r13
eor r10,r14
eor r13,r12
or r13,r14
eor r13,r15
eor r2,r15
or r2,r12
eor r2,r24
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
and r12,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
or r23,r24
eor r23,r14
std Z+25,r23
std Z+33,r12
std Z+9,r13
std Z+17,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
mov r14,r12
mov r15,r23
mov r24,r13
eor r14,r3
eor r15,r11
eor r24,r11
com r11
or r11,r13
eor r11,r14
eor r13,r12
or r13,r14
eor r13,r15
eor r3,r15
or r3,r12
eor r3,r24
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
and r12,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
or r23,r24
eor r23,r14
std Z+24,r23
std Z+32,r12
std Z+8,r13
std Z+16,r11
movw r12,r18
movw r14,r20
movw r24,r26
movw r16,r2
mov r0,r12
mov r12,r14
mov r14,r24
......@@ -369,79 +327,79 @@ ascon_permute:
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
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 r23,r18
mov r0,r19
push r20
mov r18,r21
mov r19,r26
mov r20,r27
mov r21,r2
mov r26,r3
pop r3
mov r2,r0
mov r27,r23
mov r0,r1
lsr r11
ror r10
ror r9
ror r8
ror r7
ror r6
ror r5
ror r4
lsr r3
ror r2
ror r27
ror r26
ror r21
ror r20
ror r19
ror r18
ror r0
lsr r11
ror r10
ror r9
ror r8
ror r7
ror r6
ror r5
ror r4
lsr r3
ror r2
ror r27
ror r26
ror r21
ror r20
ror r19
ror r18
ror r0
lsr r11
ror r10
ror r9
ror r8
ror r7
ror r6
ror r5
ror r4
lsr r3
ror r2
ror r27
ror r26
ror r21
ror r20
ror r19
ror r18
ror r0
lsr r11
ror r10
ror r9
ror r8
ror r7
ror r6
ror r5
ror r4
lsr r3
ror r2
ror r27
ror r26
ror r21
ror r20
ror r19
ror r18
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
or r3,r0
eor r18,r12
eor r19,r13
eor r20,r14
eor r21,r15
eor r26,r24
eor r27,r25
eor r2,r16
eor r3,r17
st Z,r3
std Z+1,r2
std Z+2,r27
std Z+3,r26
std Z+4,r21
std Z+5,r20
std Z+6,r19
std Z+7,r18
ldd r11,Z+8
ldd r10,Z+9
ldd r9,Z+10
......@@ -525,6 +483,14 @@ ascon_permute:
std Z+13,r6
std Z+14,r5
std Z+15,r4
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
movw r12,r18
movw r14,r20
movw r24,r26
......
/*
* Copyright (C) 2020 Southern Storm Software, Pty Ltd.
* Copyright (C) 2021 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"),
......@@ -22,7 +22,19 @@
#include "internal-ascon.h"
#if !defined(__AVR__)
/* Determine which versions should be accelerated with assembly code */
#if defined(__AVR__)
#define ASCON_ASM_REGULAR 1
#define ASCON_ASM_SLICED 0
#elif defined(__ARM_ARCH_ISA_THUMB) && __ARM_ARCH == 7
#define ASCON_ASM_REGULAR 1
#define ASCON_ASM_SLICED 1
#else
#define ASCON_ASM_REGULAR 0
#define ASCON_ASM_SLICED 0
#endif
#if !ASCON_ASM_REGULAR
void ascon_permute(ascon_state_t *state, uint8_t first_round)
{
......@@ -77,4 +89,120 @@ void ascon_permute(ascon_state_t *state, uint8_t first_round)
#endif
}
#endif /* !__AVR__ */
#endif /* !ASCON_ASM_REGULAR */
#if ASCON_SLICED && !ASCON_ASM_SLICED
void ascon_to_sliced(ascon_state_t *state)
{
int index;
uint32_t high, low;
for (index = 0; index < 10; index += 2) {
high = be_load_word32(state->B + index * 4);
low = be_load_word32(state->B + index * 4 + 4);
ascon_separate(high);
ascon_separate(low);
state->W[index] = (high << 16) | (low & 0x0000FFFFU);
state->W[index + 1] = (high & 0xFFFF0000U) | (low >> 16);
}
}
void ascon_from_sliced(ascon_state_t *state)
{
int index;
uint32_t high, low;
for (index = 0; index < 10; index += 2) {
high = (state->W[index] >> 16) | (state->W[index + 1] & 0xFFFF0000U);
low = (state->W[index] & 0x0000FFFFU) | (state->W[index + 1] << 16);
ascon_combine(high);
ascon_combine(low);
be_store_word32(state->B + index * 4, high);
be_store_word32(state->B + index * 4 + 4, low);
}
}
void ascon_permute_sliced(ascon_state_t *state, uint8_t first_round)
{
static const unsigned char RC[12 * 2] = {
12, 12, 9, 12, 12, 9, 9, 9, 6, 12, 3, 12,
6, 9, 3, 9, 12, 6, 9, 6, 12, 3, 9, 3
};
const unsigned char *rc = RC + first_round * 2;
uint32_t t0, t1, t2, t3, t4;
/* Load the state into local variables */
uint32_t x0_e = state->W[0];
uint32_t x0_o = state->W[1];
uint32_t x1_e = state->W[2];
uint32_t x1_o = state->W[3];
uint32_t x2_e = state->W[4];
uint32_t x2_o = state->W[5];
uint32_t x3_e = state->W[6];
uint32_t x3_o = state->W[7];
uint32_t x4_e = state->W[8];
uint32_t x4_o = state->W[9];
/* Perform all permutation rounds */
while (first_round < 12) {
/* Add the round constants for this round to the state */
x2_e ^= rc[0];
x2_o ^= rc[1];
rc += 2;
/* Substitution layer */
#define ascon_sbox(x0, x1, x2, x3, x4) \
do { \
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; \
} while (0)
ascon_sbox(x0_e, x1_e, x2_e, x3_e, x4_e);
ascon_sbox(x0_o, x1_o, x2_o, x3_o, x4_o);
/* Linear diffusion layer */
/* x0 ^= rightRotate19_64(x0) ^ rightRotate28_64(x0); */
t0 = x0_e ^ rightRotate4(x0_o);
t1 = x0_o ^ rightRotate5(x0_e);
x0_e ^= rightRotate9(t1);
x0_o ^= rightRotate10(t0);
/* x1 ^= rightRotate61_64(x1) ^ rightRotate39_64(x1); */
t0 = x1_e ^ rightRotate11(x1_e);
t1 = x1_o ^ rightRotate11(x1_o);
x1_e ^= rightRotate19(t1);
x1_o ^= rightRotate20(t0);
/* x2 ^= rightRotate1_64(x2) ^ rightRotate6_64(x2); */
t0 = x2_e ^ rightRotate2(x2_o);
t1 = x2_o ^ rightRotate3(x2_e);
x2_e ^= t1;
x2_o ^= rightRotate1(t0);
/* x3 ^= rightRotate10_64(x3) ^ rightRotate17_64(x3); */
t0 = x3_e ^ rightRotate3(x3_o);
t1 = x3_o ^ rightRotate4(x3_e);
x3_e ^= rightRotate5(t0);
x3_o ^= rightRotate5(t1);
/* x4 ^= rightRotate7_64(x4) ^ rightRotate41_64(x4); */
t0 = x4_e ^ rightRotate17(x4_e);
t1 = x4_o ^ rightRotate17(x4_o);
x4_e ^= rightRotate3(t1);
x4_o ^= rightRotate4(t0);
/* Move onto the next round */
++first_round;
}
/* Write the local variables back to the state */
state->W[0] = x0_e;
state->W[1] = x0_o;
state->W[2] = x1_e;
state->W[3] = x1_o;
state->W[4] = x2_e;
state->W[5] = x2_o;
state->W[6] = x3_e;
state->W[7] = x3_o;
state->W[8] = x4_e;
state->W[9] = x4_o;
}
#endif /* ASCON_SLICED */
/*
* Copyright (C) 2020 Southern Storm Software, Pty Ltd.
* Copyright (C) 2021 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"),
......@@ -38,11 +38,36 @@ extern "C" {
#endif
/**
* \brief Defined to 1 if the 32-bit sliced version of ASCON is preferred.
*/
#if !defined(__AVR__) && !defined(LW_UTIL_CPU_IS_64BIT)
#define ASCON_SLICED 1
#else
#define ASCON_SLICED 0
#endif
/**
* \brief Initialization vector for ASCON-128.
*/
#define ASCON128_IV 0x80400c0600000000ULL
/**
* \brief Initialization vector for ASCON-128a.
*/
#define ASCON128a_IV 0x80800c0800000000ULL
/**
* \brief Initialization vector for ASCON-80pq.
*/
#define ASCON80PQ_IV 0xa0400c06U
/**
* \brief Structure of the internal state of the ASCON permutation.
*/
typedef union
{
uint64_t S[5]; /**< Words of the state */
uint64_t S[5]; /**< 64-bit words of the state */
uint32_t W[10]; /**< 32-bit words of the state */
uint8_t B[40]; /**< Bytes of the state */
} ascon_state_t;
......@@ -57,6 +82,237 @@ typedef union
*/
void ascon_permute(ascon_state_t *state, uint8_t first_round);
#if ASCON_SLICED
/**
* \brief Converts an ASCON state from byte form into sliced form.
*
* \param state The ASCON state to be converted, in big-endian byte order
* on entry and in host byte order on exit.
*/
void ascon_to_sliced(ascon_state_t *state);
/**
* \brief Converts an ASCON state from sliced form into byte form.
*
* \param state The ASCON state to be converted, in host byte order
* on entry and in big-endian byte order on exit.
*/
void ascon_from_sliced(ascon_state_t *state);
/**
* \brief Permutes the ASCON state in sliced form.
*
* \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 host byte order.
*/
void ascon_permute_sliced(ascon_state_t *state, uint8_t first_round);
/** @cond ascon_bit_separation */
/* http://programming.sirrida.de/perm_fn.html#bit_permute_step */
#define ascon_bit_permute_step(_y, mask, shift) \
do { \
uint32_t y = (_y); \
uint32_t t = ((y >> (shift)) ^ y) & (mask); \
(_y) = (y ^ t) ^ (t << (shift)); \
} while (0)
/* Separates a 32-bit word into two 16-bit halves with all the even
* bits in the bottom half and all the odd bits in the top half.
*
* Permutation generated with "http://programming.sirrida.de/calcperm.php"
*
* P = [0 16 1 17 2 18 3 19 4 20 5 21 6 22 7 23 8 24
* 9 25 10 26 11 27 12 28 13 29 14 30 15 31]
*/
#define ascon_separate(x) \
do { \
ascon_bit_permute_step((x), 0x22222222, 1); \
ascon_bit_permute_step((x), 0x0c0c0c0c, 2); \
ascon_bit_permute_step((x), 0x00f000f0, 4); \
ascon_bit_permute_step((x), 0x0000ff00, 8); \
} while (0)
#define ascon_combine(x) \
do { \
ascon_bit_permute_step((x), 0x0000aaaa, 15); \
ascon_bit_permute_step((x), 0x0000cccc, 14); \
ascon_bit_permute_step((x), 0x0000f0f0, 12); \
ascon_bit_permute_step((x), 0x0000ff00, 8); \
} while (0)
/** @endcond */
/**
* \brief Sets data into the ASCON state in sliced form.
*
* \param state The ASCON state for the data to be absorbed into.
* \param data Points to 8 bytes of data in big-endian byte order to set.
* \param offset Offset of the 64-bit word within the state to set at,
* between 0 and 4.
*/
#define ascon_set_sliced(state, data, offset) \
do { \
ascon_state_t *s = (state); \
uint32_t high = be_load_word32((data)); \
uint32_t low = be_load_word32((data) + 4); \
ascon_separate(high); \
ascon_separate(low); \
s->W[(offset) * 2] = (high << 16) | (low & 0x0000FFFFU); \
s->W[(offset) * 2 + 1] = (high & 0xFFFF0000U) | (low >> 16); \
} while (0)
/**
* \brief Absorbs data into the ASCON state in sliced form.
*
* \param state The ASCON state for the data to be absorbed into.
* \param data Points to 8 bytes of data in big-endian byte order to absorb.
* \param offset Offset of the 64-bit word within the state to absorb at,
* between 0 and 4.
*/
#define ascon_absorb_sliced(state, data, offset) \
do { \
ascon_state_t *s = (state); \
uint32_t high = be_load_word32((data)); \
uint32_t low = be_load_word32((data) + 4); \
ascon_separate(high); \
ascon_separate(low); \
s->W[(offset) * 2] ^= (high << 16) | (low & 0x0000FFFFU); \
s->W[(offset) * 2 + 1] ^= (high & 0xFFFF0000U) | (low >> 16); \
} while (0)
/**
* \brief Absorbs 32 bits of data into the ASCON state in sliced form.
*
* \param state The ASCON state for the data to be absorbed into.
* \param data Points to 4 bytes of data in big-endian byte order to absorb.
* \param offset Offset of the 64-bit word within the state to absorb at,
* between 0 and 4.
*
* The data is absorbed into the low bits of the 64-bit word at \a offset.
*/
#define ascon_absorb32_low_sliced(state, data, offset) \
do { \
ascon_state_t *s = (state); \
uint32_t low = be_load_word32((data)); \
ascon_separate(low); \
s->W[(offset) * 2] ^= (low & 0x0000FFFFU); \
s->W[(offset) * 2 + 1] ^= (low >> 16); \
} while (0)
/**
* \brief Absorbs 32 bits of data into the ASCON state in sliced form.
*
* \param state The ASCON state for the data to be absorbed into.
* \param data Points to 4 bytes of data in big-endian byte order to absorb.
* \param offset Offset of the 64-bit word within the state to absorb at,
* between 0 and 4.
*
* The data is absorbed into the high bits of the 64-bit word at \a offset.
*/
#define ascon_absorb32_high_sliced(state, data, offset) \
do { \
ascon_state_t *s = (state); \
uint32_t high = be_load_word32((data)); \
ascon_separate(high); \
s->W[(offset) * 2] ^= (high << 16); \
s->W[(offset) * 2 + 1] ^= (high & 0xFFFF0000U); \
} while (0)
/**
* \brief Squeezes data from the ASCON state in sliced form.
*
* \param state The ASCON state to extract the data from.
* \param data Points to the 8 bytes to be extracted from the state.
* \param offset Offset of the 64-bit word within the state to extract,
* between 0 and 4.
*/
#define ascon_squeeze_sliced(state, data, offset) \
do { \
ascon_state_t *s = (state); \
uint32_t high, low; \
high = (s->W[(offset) * 2] >> 16) | \
(s->W[(offset) * 2 + 1] & 0xFFFF0000U); \
low = (s->W[(offset) * 2] & 0x0000FFFFU) | \
(s->W[(offset) * 2 + 1] << 16); \
ascon_combine(high); \
ascon_combine(low); \
be_store_word32((data), high); \
be_store_word32((data) + 4, low); \
} while (0)
/**
* \brief Encrypts data using the ASCON state in sliced form.
*
* \param state The ASCON state.
* \param c Points to 8 bytes of output ciphertext in big-endian byte order.
* \param m Points to 8 bytes of input plaintext in big-endian byte order.
* \param offset Offset of the 64-bit word within the state to absorb
* and squeeze at, between 0 and 4.
*/
#define ascon_encrypt_sliced(state, c, m, offset) \
do { \
ascon_state_t *s = (state); \
uint32_t high = be_load_word32((m)); \
uint32_t low = be_load_word32((m) + 4); \
ascon_separate(high); \
ascon_separate(low); \
s->W[(offset) * 2] ^= (high << 16) | (low & 0x0000FFFFU); \
s->W[(offset) * 2 + 1] ^= (high & 0xFFFF0000U) | (low >> 16); \
high = (s->W[(offset) * 2] >> 16) | \
(s->W[(offset) * 2 + 1] & 0xFFFF0000U); \
low = (s->W[(offset) * 2] & 0x0000FFFFU) | \
(s->W[(offset) * 2 + 1] << 16); \
ascon_combine(high); \
ascon_combine(low); \
be_store_word32((c), high); \
be_store_word32((c) + 4, low); \
} while (0)
/**
* \brief Decrypts data using the ASCON state in sliced form.
*
* \param state The ASCON state.
* \param m Points to 8 bytes of output plaintext in big-endian byte order.
* \param c Points to 8 bytes of input ciphertext in big-endian byte order.
* \param offset Offset of the 64-bit word within the state to absorb
* and squeeze at, between 0 and 4.
*/
#define ascon_decrypt_sliced(state, m, c, offset) \
do { \
ascon_state_t *s = (state); \
uint32_t high, low, high2, low2; \
high = be_load_word32((c)); \
low = be_load_word32((c) + 4); \
ascon_separate(high); \
ascon_separate(low); \
high2 = high ^ ((s->W[(offset) * 2] >> 16) | \
(s->W[(offset) * 2 + 1] & 0xFFFF0000U)); \
low2 = low ^ ((s->W[(offset) * 2] & 0x0000FFFFU) | \
(s->W[(offset) * 2 + 1] << 16)); \
s->W[(offset) * 2] = (high << 16) | (low & 0x0000FFFFU); \
s->W[(offset) * 2 + 1] = (high & 0xFFFF0000U) | (low >> 16); \
ascon_combine(high2); \
ascon_combine(low2); \
be_store_word32((m), high2); \
be_store_word32((m) + 4, low2); \
} while (0)
#endif /* ASCON_SLICED */
/**
* \def ascon_separator()
* \brief Absorbs the standard ASCON separator for switching between
* associated data and message payload.
*/
#if ASCON_SLICED
#define ascon_separator() (state.W[8] ^= 0x01)
#else
#define ascon_separator() (state.B[39] ^= 0x01)
#endif
#ifdef __cplusplus
}
#endif
......
/*
* Copyright (C) 2021 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-util.h"
int aead_check_tag
(unsigned char *plaintext, size_t plaintext_len,
const unsigned char *tag1, const unsigned char *tag2, size_t 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;
}
void aead_clean(void *buf, unsigned size)
{
/* Force the use of volatile so that we actually clear the memory.
* Otherwise the compiler might optimise the entire contents of this
* function away, which will not be secure.
*
* Even this may not work. Some platforms have bzero_explicit() or
* memset_s() that could be used in place of this implementation. */
volatile uint8_t *d = (volatile uint8_t *)buf;
while (size > 0) {
*d++ = 0;
--size;
}
}
/*
* Copyright (C) 2020 Southern Storm Software, Pty Ltd.
* Copyright (C) 2021 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"),
......@@ -23,6 +23,7 @@
#ifndef LW_INTERNAL_UTIL_H
#define LW_INTERNAL_UTIL_H
#include <stddef.h>
#include <stdint.h>
/* Figure out how to inline functions using this C compiler */
......@@ -53,6 +54,13 @@
#error "Cannot determine the endianess of this platform"
#endif
/* Determine if we are compiling for a 64-bit CPU */
#if defined(__x86_64) || defined(__x86_64__) || \
defined(__aarch64__) || defined(__ARM_ARCH_ISA_A64) || \
defined(_M_AMD64) || defined(_M_X64) || defined(_M_IA64)
#define LW_UTIL_CPU_IS_64BIT 1
#endif
/* Helper macros to load and store values while converting endian-ness */
/* Load a big-endian 32-bit word from a byte buffer */
......@@ -89,6 +97,11 @@
(ptr)[3] = (uint8_t)(_x >> 24); \
} while (0)
/* Reverses the bytes in a 32-bit word */
#define reverse_word32(x) \
(((x) >> 24) | (((x) >> 8) & 0x0000FF00U) | \
(((x) << 8) & 0x00FF0000U) | ((x) << 24))
/* Load a big-endian 64-bit word from a byte buffer */
#define be_load_word64(ptr) \
((((uint64_t)((ptr)[0])) << 56) | \
......@@ -699,4 +712,52 @@
#define rightRotate6_8(a) (rightRotate_8((a), 6))
#define rightRotate7_8(a) (rightRotate_8((a), 7))
/**
* \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 size 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, size_t plaintext_len,
const unsigned char *tag1, const unsigned char *tag2, size_t size);
/**
* \brief Attempts to cleans a buffer that contains sensitive material.
*
* \param buf Points to the buffer to clear.
* \param size Size of the buffer to clear in bytes.
*/
void aead_clean(void *buf, unsigned size);
/**
* \brief Number of bytes to retrieve from the system TRNG each time
* we need to reseed application-level PRNG's.
*/
#define AEAD_SYSTEM_SEED_SIZE 32
/**
* \brief Gets data from the system TRNG to reseed application-level PRNG's.
*
* \param seed Points to the buffer to be populated with the system seed.
*
* \return Non-zero if \a seed has been filled with TRNG data or zero
* if there is no accessible TRNG on this system.
*
* The quality of the returned seed data may be very poor or may not
* distribute the entropy evenly throughout the returned \a seed buffer.
* The application should use a PRNG to hash the seed data into a more
* useful random sequence.
*/
int aead_random_get_system_seed(unsigned char seed[AEAD_SYSTEM_SEED_SIZE]);
#endif
/*
* Copyright (C) 2021 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_ASCON_AEAD_H
#define LWCRYPTO_ASCON_AEAD_H
#include <stddef.h>
/**
* \file ascon-aead.h
* \brief ASCON-128 encryption algorithm and related family members.
*
* The ASCON family consists of several related algorithms:
*
* \li ASCON-128 with a 128-bit key, a 128-bit nonce, a 128-bit authentication
* tag, and a block rate of 64 bits.
* \li ASCON-128a with a 128-bit key, a 128-bit nonce, a 128-bit authentication
* tag, and a block rate of 128 bits. This is faster than ASCON-128 but may
* not be as secure.
* \li ASCON-80pq with a 160-bit key, a 128-bit nonce, a 128-bit authentication
* tag, and a block rate of 64 bits. This is similar to ASCON-128 but has a
* 160-bit key instead which may be more resistant against quantum computers.
* \li ASCON-HASH and ASCON-HASHA with a 256-bit hash output.
* \li ASCON-XOF and ASCON-XOFA with extensible hash output (XOF mode).
*
* References: https://ascon.iaik.tugraz.at/
*/
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief Size of the key for ASCON-128 and ASCON-128a.
*/
#define ASCON128_KEY_SIZE 16
/**
* \brief Size of the nonce for ASCON-128 and ASCON-128a.
*/
#define ASCON128_NONCE_SIZE 16
/**
* \brief Size of the authentication tag for ASCON-128 and ASCON-128a.
*/
#define ASCON128_TAG_SIZE 16
/**
* \brief Size of the key for ASCON-80pq.
*/
#define ASCON80PQ_KEY_SIZE 20
/**
* \brief Size of the nonce for ASCON-80pq.
*/
#define ASCON80PQ_NONCE_SIZE 16
/**
* \brief Size of the authentication tag for ASCON-80pq.
*/
#define ASCON80PQ_TAG_SIZE 16
/**
* \brief Encrypts and authenticates a packet with ASCON-128.
*
* \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 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 ascon128_aead_decrypt()
*/
int ascon128_aead_encrypt
(unsigned char *c, size_t *clen,
const unsigned char *m, size_t mlen,
const unsigned char *ad, size_t adlen,
const unsigned char *npub,
const unsigned char *k);
/**
* \brief Decrypts and authenticates a packet with ASCON-128.
*
* \param m Buffer to receive the plaintext message on output.
* \param mlen Receives the length of the plaintext message on output.
* \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 ascon128_aead_encrypt()
*/
int ascon128_aead_decrypt
(unsigned char *m, size_t *mlen,
const unsigned char *c, size_t clen,
const unsigned char *ad, size_t adlen,
const unsigned char *npub,
const unsigned char *k);
/**
* \brief Encrypts and authenticates a packet with ASCON-128a.
*
* \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 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 ascon128a_aead_decrypt()
*/
int ascon128a_aead_encrypt
(unsigned char *c, size_t *clen,
const unsigned char *m, size_t mlen,
const unsigned char *ad, size_t adlen,
const unsigned char *npub,
const unsigned char *k);
/**
* \brief Decrypts and authenticates a packet with ASCON-128a.
*
* \param m Buffer to receive the plaintext message on output.
* \param mlen Receives the length of the plaintext message on output.
* \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 ascon128a_aead_encrypt()
*/
int ascon128a_aead_decrypt
(unsigned char *m, size_t *mlen,
const unsigned char *c, size_t clen,
const unsigned char *ad, size_t adlen,
const unsigned char *npub,
const unsigned char *k);
/**
* \brief Encrypts and authenticates a packet with ASCON-80pq.
*
* \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 npub Points to the public nonce for the packet which must
* be 16 bytes in length.
* \param k Points to the 20 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 ascon80pq_aead_decrypt()
*/
int ascon80pq_aead_encrypt
(unsigned char *c, size_t *clen,
const unsigned char *m, size_t mlen,
const unsigned char *ad, size_t adlen,
const unsigned char *npub,
const unsigned char *k);
/**
* \brief Decrypts and authenticates a packet with ASCON-80pq.
*
* \param m Buffer to receive the plaintext message on output.
* \param mlen Receives the length of the plaintext message on output.
* \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 20 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 ascon80pq_aead_encrypt()
*/
int ascon80pq_aead_decrypt
(unsigned char *m, size_t *mlen,
const unsigned char *c, size_t clen,
const unsigned char *ad, size_t adlen,
const unsigned char *npub,
const unsigned char *k);
#ifdef __cplusplus
}
#endif
#endif
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
);
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
);
#include "ascon128.h"
#include "ascon-aead.h"
int crypto_aead_encrypt
(unsigned char *c, unsigned long long *clen,
......@@ -9,8 +9,12 @@ int crypto_aead_encrypt
const unsigned char *npub,
const unsigned char *k)
{
return ascon80pq_aead_encrypt
(c, clen, m, mlen, ad, adlen, nsec, npub, k);
size_t len = 0;
int result = ascon80pq_aead_encrypt
(c, &len, m, mlen, ad, adlen, npub, k);
(void)nsec;
*clen = len;
return result;
}
int crypto_aead_decrypt
......@@ -21,6 +25,10 @@ int crypto_aead_decrypt
const unsigned char *npub,
const unsigned char *k)
{
return ascon80pq_aead_decrypt
(m, mlen, nsec, c, clen, ad, adlen, npub, k);
size_t len = 0;
int result = ascon80pq_aead_decrypt
(m, &len, c, clen, ad, adlen, npub, k);
(void)nsec;
*mlen = len;
return result;
}
#if defined(__AVR__)
/*
* Copyright (C) 2021 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 <avr/io.h>
/* Automatically generated - do not edit */
......@@ -49,287 +71,223 @@ ascon_permute:
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
mov r14,r12
mov r15,r23
mov r24,r13
eor r14,r18
eor r15,r4
eor r24,r4
com r4
or r4,r13
eor r4,r14
eor r13,r12
or r13,r14
eor r13,r15
eor r18,r15
or r18,r12
eor r18,r24
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
and r12,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
or r23,r24
eor r23,r14
std Z+31,r23
std Z+39,r12
std Z+15,r13
std Z+23,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
mov r14,r12
mov r15,r23
mov r24,r13
eor r14,r19
eor r15,r5
eor r24,r5
com r5
or r5,r13
eor r5,r14
eor r13,r12
or r13,r14
eor r13,r15
eor r19,r15
or r19,r12
eor r19,r24
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
and r12,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
or r23,r24
eor r23,r14
std Z+30,r23
std Z+38,r12
std Z+14,r13
std Z+22,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
mov r14,r12
mov r15,r23
mov r24,r13
eor r14,r20
eor r15,r6
eor r24,r6
com r6
or r6,r13
eor r6,r14
eor r13,r12
or r13,r14
eor r13,r15
eor r20,r15
or r20,r12
eor r20,r24
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
and r12,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
or r23,r24
eor r23,r14
std Z+29,r23
std Z+37,r12
std Z+13,r13
std Z+21,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
mov r14,r12
mov r15,r23
mov r24,r13
eor r14,r21
eor r15,r7
eor r24,r7
com r7
or r7,r13
eor r7,r14
eor r13,r12
or r13,r14
eor r13,r15
eor r21,r15
or r21,r12
eor r21,r24
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
and r12,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
or r23,r24
eor r23,r14
std Z+28,r23
std Z+36,r12
std Z+12,r13
std Z+20,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
mov r14,r12
mov r15,r23
mov r24,r13
eor r14,r26
eor r15,r8
eor r24,r8
com r8
or r8,r13
eor r8,r14
eor r13,r12
or r13,r14
eor r13,r15
eor r26,r15
or r26,r12
eor r26,r24
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
and r12,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
or r23,r24
eor r23,r14
std Z+27,r23
std Z+35,r12
std Z+11,r13
std Z+19,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
mov r14,r12
mov r15,r23
mov r24,r13
eor r14,r27
eor r15,r9
eor r24,r9
com r9
or r9,r13
eor r9,r14
eor r13,r12
or r13,r14
eor r13,r15
eor r27,r15
or r27,r12
eor r27,r24
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
and r12,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
or r23,r24
eor r23,r14
std Z+26,r23
std Z+34,r12
std Z+10,r13
std Z+18,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
mov r14,r12
mov r15,r23
mov r24,r13
eor r14,r2
eor r15,r10
eor r24,r10
com r10
or r10,r13
eor r10,r14
eor r13,r12
or r13,r14
eor r13,r15
eor r2,r15
or r2,r12
eor r2,r24
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
and r12,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
or r23,r24
eor r23,r14
std Z+25,r23
std Z+33,r12
std Z+9,r13
std Z+17,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
mov r14,r12
mov r15,r23
mov r24,r13
eor r14,r3
eor r15,r11
eor r24,r11
com r11
or r11,r13
eor r11,r14
eor r13,r12
or r13,r14
eor r13,r15
eor r3,r15
or r3,r12
eor r3,r24
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
and r12,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
or r23,r24
eor r23,r14
std Z+24,r23
std Z+32,r12
std Z+8,r13
std Z+16,r11
movw r12,r18
movw r14,r20
movw r24,r26
movw r16,r2
mov r0,r12
mov r12,r14
mov r14,r24
......@@ -369,79 +327,79 @@ ascon_permute:
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
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 r23,r18
mov r0,r19
push r20
mov r18,r21
mov r19,r26
mov r20,r27
mov r21,r2
mov r26,r3
pop r3
mov r2,r0
mov r27,r23
mov r0,r1
lsr r11
ror r10
ror r9
ror r8
ror r7
ror r6
ror r5
ror r4
lsr r3
ror r2
ror r27
ror r26
ror r21
ror r20
ror r19
ror r18
ror r0
lsr r11
ror r10
ror r9
ror r8
ror r7
ror r6
ror r5
ror r4
lsr r3
ror r2
ror r27
ror r26
ror r21
ror r20
ror r19
ror r18
ror r0
lsr r11
ror r10
ror r9
ror r8
ror r7
ror r6
ror r5
ror r4
lsr r3
ror r2
ror r27
ror r26
ror r21
ror r20
ror r19
ror r18
ror r0
lsr r11
ror r10
ror r9
ror r8
ror r7
ror r6
ror r5
ror r4
lsr r3
ror r2
ror r27
ror r26
ror r21
ror r20
ror r19
ror r18
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
or r3,r0
eor r18,r12
eor r19,r13
eor r20,r14
eor r21,r15
eor r26,r24
eor r27,r25
eor r2,r16
eor r3,r17
st Z,r3
std Z+1,r2
std Z+2,r27
std Z+3,r26
std Z+4,r21
std Z+5,r20
std Z+6,r19
std Z+7,r18
ldd r11,Z+8
ldd r10,Z+9
ldd r9,Z+10
......@@ -525,6 +483,14 @@ ascon_permute:
std Z+13,r6
std Z+14,r5
std Z+15,r4
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
movw r12,r18
movw r14,r20
movw r24,r26
......
/*
* Copyright (C) 2020 Southern Storm Software, Pty Ltd.
* Copyright (C) 2021 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"),
......@@ -22,7 +22,19 @@
#include "internal-ascon.h"
#if !defined(__AVR__)
/* Determine which versions should be accelerated with assembly code */
#if defined(__AVR__)
#define ASCON_ASM_REGULAR 1
#define ASCON_ASM_SLICED 0
#elif defined(__ARM_ARCH_ISA_THUMB) && __ARM_ARCH == 7
#define ASCON_ASM_REGULAR 1
#define ASCON_ASM_SLICED 1
#else
#define ASCON_ASM_REGULAR 0
#define ASCON_ASM_SLICED 0
#endif
#if !ASCON_ASM_REGULAR
void ascon_permute(ascon_state_t *state, uint8_t first_round)
{
......@@ -77,4 +89,120 @@ void ascon_permute(ascon_state_t *state, uint8_t first_round)
#endif
}
#endif /* !__AVR__ */
#endif /* !ASCON_ASM_REGULAR */
#if ASCON_SLICED && !ASCON_ASM_SLICED
void ascon_to_sliced(ascon_state_t *state)
{
int index;
uint32_t high, low;
for (index = 0; index < 10; index += 2) {
high = be_load_word32(state->B + index * 4);
low = be_load_word32(state->B + index * 4 + 4);
ascon_separate(high);
ascon_separate(low);
state->W[index] = (high << 16) | (low & 0x0000FFFFU);
state->W[index + 1] = (high & 0xFFFF0000U) | (low >> 16);
}
}
void ascon_from_sliced(ascon_state_t *state)
{
int index;
uint32_t high, low;
for (index = 0; index < 10; index += 2) {
high = (state->W[index] >> 16) | (state->W[index + 1] & 0xFFFF0000U);
low = (state->W[index] & 0x0000FFFFU) | (state->W[index + 1] << 16);
ascon_combine(high);
ascon_combine(low);
be_store_word32(state->B + index * 4, high);
be_store_word32(state->B + index * 4 + 4, low);
}
}
void ascon_permute_sliced(ascon_state_t *state, uint8_t first_round)
{
static const unsigned char RC[12 * 2] = {
12, 12, 9, 12, 12, 9, 9, 9, 6, 12, 3, 12,
6, 9, 3, 9, 12, 6, 9, 6, 12, 3, 9, 3
};
const unsigned char *rc = RC + first_round * 2;
uint32_t t0, t1, t2, t3, t4;
/* Load the state into local variables */
uint32_t x0_e = state->W[0];
uint32_t x0_o = state->W[1];
uint32_t x1_e = state->W[2];
uint32_t x1_o = state->W[3];
uint32_t x2_e = state->W[4];
uint32_t x2_o = state->W[5];
uint32_t x3_e = state->W[6];
uint32_t x3_o = state->W[7];
uint32_t x4_e = state->W[8];
uint32_t x4_o = state->W[9];
/* Perform all permutation rounds */
while (first_round < 12) {
/* Add the round constants for this round to the state */
x2_e ^= rc[0];
x2_o ^= rc[1];
rc += 2;
/* Substitution layer */
#define ascon_sbox(x0, x1, x2, x3, x4) \
do { \
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; \
} while (0)
ascon_sbox(x0_e, x1_e, x2_e, x3_e, x4_e);
ascon_sbox(x0_o, x1_o, x2_o, x3_o, x4_o);
/* Linear diffusion layer */
/* x0 ^= rightRotate19_64(x0) ^ rightRotate28_64(x0); */
t0 = x0_e ^ rightRotate4(x0_o);
t1 = x0_o ^ rightRotate5(x0_e);
x0_e ^= rightRotate9(t1);
x0_o ^= rightRotate10(t0);
/* x1 ^= rightRotate61_64(x1) ^ rightRotate39_64(x1); */
t0 = x1_e ^ rightRotate11(x1_e);
t1 = x1_o ^ rightRotate11(x1_o);
x1_e ^= rightRotate19(t1);
x1_o ^= rightRotate20(t0);
/* x2 ^= rightRotate1_64(x2) ^ rightRotate6_64(x2); */
t0 = x2_e ^ rightRotate2(x2_o);
t1 = x2_o ^ rightRotate3(x2_e);
x2_e ^= t1;
x2_o ^= rightRotate1(t0);
/* x3 ^= rightRotate10_64(x3) ^ rightRotate17_64(x3); */
t0 = x3_e ^ rightRotate3(x3_o);
t1 = x3_o ^ rightRotate4(x3_e);
x3_e ^= rightRotate5(t0);
x3_o ^= rightRotate5(t1);
/* x4 ^= rightRotate7_64(x4) ^ rightRotate41_64(x4); */
t0 = x4_e ^ rightRotate17(x4_e);
t1 = x4_o ^ rightRotate17(x4_o);
x4_e ^= rightRotate3(t1);
x4_o ^= rightRotate4(t0);
/* Move onto the next round */
++first_round;
}
/* Write the local variables back to the state */
state->W[0] = x0_e;
state->W[1] = x0_o;
state->W[2] = x1_e;
state->W[3] = x1_o;
state->W[4] = x2_e;
state->W[5] = x2_o;
state->W[6] = x3_e;
state->W[7] = x3_o;
state->W[8] = x4_e;
state->W[9] = x4_o;
}
#endif /* ASCON_SLICED */
/*
* Copyright (C) 2020 Southern Storm Software, Pty Ltd.
* Copyright (C) 2021 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"),
......@@ -38,11 +38,36 @@ extern "C" {
#endif
/**
* \brief Defined to 1 if the 32-bit sliced version of ASCON is preferred.
*/
#if !defined(__AVR__) && !defined(LW_UTIL_CPU_IS_64BIT)
#define ASCON_SLICED 1
#else
#define ASCON_SLICED 0
#endif
/**
* \brief Initialization vector for ASCON-128.
*/
#define ASCON128_IV 0x80400c0600000000ULL
/**
* \brief Initialization vector for ASCON-128a.
*/
#define ASCON128a_IV 0x80800c0800000000ULL
/**
* \brief Initialization vector for ASCON-80pq.
*/
#define ASCON80PQ_IV 0xa0400c06U
/**
* \brief Structure of the internal state of the ASCON permutation.
*/
typedef union
{
uint64_t S[5]; /**< Words of the state */
uint64_t S[5]; /**< 64-bit words of the state */
uint32_t W[10]; /**< 32-bit words of the state */
uint8_t B[40]; /**< Bytes of the state */
} ascon_state_t;
......@@ -57,6 +82,237 @@ typedef union
*/
void ascon_permute(ascon_state_t *state, uint8_t first_round);
#if ASCON_SLICED
/**
* \brief Converts an ASCON state from byte form into sliced form.
*
* \param state The ASCON state to be converted, in big-endian byte order
* on entry and in host byte order on exit.
*/
void ascon_to_sliced(ascon_state_t *state);
/**
* \brief Converts an ASCON state from sliced form into byte form.
*
* \param state The ASCON state to be converted, in host byte order
* on entry and in big-endian byte order on exit.
*/
void ascon_from_sliced(ascon_state_t *state);
/**
* \brief Permutes the ASCON state in sliced form.
*
* \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 host byte order.
*/
void ascon_permute_sliced(ascon_state_t *state, uint8_t first_round);
/** @cond ascon_bit_separation */
/* http://programming.sirrida.de/perm_fn.html#bit_permute_step */
#define ascon_bit_permute_step(_y, mask, shift) \
do { \
uint32_t y = (_y); \
uint32_t t = ((y >> (shift)) ^ y) & (mask); \
(_y) = (y ^ t) ^ (t << (shift)); \
} while (0)
/* Separates a 32-bit word into two 16-bit halves with all the even
* bits in the bottom half and all the odd bits in the top half.
*
* Permutation generated with "http://programming.sirrida.de/calcperm.php"
*
* P = [0 16 1 17 2 18 3 19 4 20 5 21 6 22 7 23 8 24
* 9 25 10 26 11 27 12 28 13 29 14 30 15 31]
*/
#define ascon_separate(x) \
do { \
ascon_bit_permute_step((x), 0x22222222, 1); \
ascon_bit_permute_step((x), 0x0c0c0c0c, 2); \
ascon_bit_permute_step((x), 0x00f000f0, 4); \
ascon_bit_permute_step((x), 0x0000ff00, 8); \
} while (0)
#define ascon_combine(x) \
do { \
ascon_bit_permute_step((x), 0x0000aaaa, 15); \
ascon_bit_permute_step((x), 0x0000cccc, 14); \
ascon_bit_permute_step((x), 0x0000f0f0, 12); \
ascon_bit_permute_step((x), 0x0000ff00, 8); \
} while (0)
/** @endcond */
/**
* \brief Sets data into the ASCON state in sliced form.
*
* \param state The ASCON state for the data to be absorbed into.
* \param data Points to 8 bytes of data in big-endian byte order to set.
* \param offset Offset of the 64-bit word within the state to set at,
* between 0 and 4.
*/
#define ascon_set_sliced(state, data, offset) \
do { \
ascon_state_t *s = (state); \
uint32_t high = be_load_word32((data)); \
uint32_t low = be_load_word32((data) + 4); \
ascon_separate(high); \
ascon_separate(low); \
s->W[(offset) * 2] = (high << 16) | (low & 0x0000FFFFU); \
s->W[(offset) * 2 + 1] = (high & 0xFFFF0000U) | (low >> 16); \
} while (0)
/**
* \brief Absorbs data into the ASCON state in sliced form.
*
* \param state The ASCON state for the data to be absorbed into.
* \param data Points to 8 bytes of data in big-endian byte order to absorb.
* \param offset Offset of the 64-bit word within the state to absorb at,
* between 0 and 4.
*/
#define ascon_absorb_sliced(state, data, offset) \
do { \
ascon_state_t *s = (state); \
uint32_t high = be_load_word32((data)); \
uint32_t low = be_load_word32((data) + 4); \
ascon_separate(high); \
ascon_separate(low); \
s->W[(offset) * 2] ^= (high << 16) | (low & 0x0000FFFFU); \
s->W[(offset) * 2 + 1] ^= (high & 0xFFFF0000U) | (low >> 16); \
} while (0)
/**
* \brief Absorbs 32 bits of data into the ASCON state in sliced form.
*
* \param state The ASCON state for the data to be absorbed into.
* \param data Points to 4 bytes of data in big-endian byte order to absorb.
* \param offset Offset of the 64-bit word within the state to absorb at,
* between 0 and 4.
*
* The data is absorbed into the low bits of the 64-bit word at \a offset.
*/
#define ascon_absorb32_low_sliced(state, data, offset) \
do { \
ascon_state_t *s = (state); \
uint32_t low = be_load_word32((data)); \
ascon_separate(low); \
s->W[(offset) * 2] ^= (low & 0x0000FFFFU); \
s->W[(offset) * 2 + 1] ^= (low >> 16); \
} while (0)
/**
* \brief Absorbs 32 bits of data into the ASCON state in sliced form.
*
* \param state The ASCON state for the data to be absorbed into.
* \param data Points to 4 bytes of data in big-endian byte order to absorb.
* \param offset Offset of the 64-bit word within the state to absorb at,
* between 0 and 4.
*
* The data is absorbed into the high bits of the 64-bit word at \a offset.
*/
#define ascon_absorb32_high_sliced(state, data, offset) \
do { \
ascon_state_t *s = (state); \
uint32_t high = be_load_word32((data)); \
ascon_separate(high); \
s->W[(offset) * 2] ^= (high << 16); \
s->W[(offset) * 2 + 1] ^= (high & 0xFFFF0000U); \
} while (0)
/**
* \brief Squeezes data from the ASCON state in sliced form.
*
* \param state The ASCON state to extract the data from.
* \param data Points to the 8 bytes to be extracted from the state.
* \param offset Offset of the 64-bit word within the state to extract,
* between 0 and 4.
*/
#define ascon_squeeze_sliced(state, data, offset) \
do { \
ascon_state_t *s = (state); \
uint32_t high, low; \
high = (s->W[(offset) * 2] >> 16) | \
(s->W[(offset) * 2 + 1] & 0xFFFF0000U); \
low = (s->W[(offset) * 2] & 0x0000FFFFU) | \
(s->W[(offset) * 2 + 1] << 16); \
ascon_combine(high); \
ascon_combine(low); \
be_store_word32((data), high); \
be_store_word32((data) + 4, low); \
} while (0)
/**
* \brief Encrypts data using the ASCON state in sliced form.
*
* \param state The ASCON state.
* \param c Points to 8 bytes of output ciphertext in big-endian byte order.
* \param m Points to 8 bytes of input plaintext in big-endian byte order.
* \param offset Offset of the 64-bit word within the state to absorb
* and squeeze at, between 0 and 4.
*/
#define ascon_encrypt_sliced(state, c, m, offset) \
do { \
ascon_state_t *s = (state); \
uint32_t high = be_load_word32((m)); \
uint32_t low = be_load_word32((m) + 4); \
ascon_separate(high); \
ascon_separate(low); \
s->W[(offset) * 2] ^= (high << 16) | (low & 0x0000FFFFU); \
s->W[(offset) * 2 + 1] ^= (high & 0xFFFF0000U) | (low >> 16); \
high = (s->W[(offset) * 2] >> 16) | \
(s->W[(offset) * 2 + 1] & 0xFFFF0000U); \
low = (s->W[(offset) * 2] & 0x0000FFFFU) | \
(s->W[(offset) * 2 + 1] << 16); \
ascon_combine(high); \
ascon_combine(low); \
be_store_word32((c), high); \
be_store_word32((c) + 4, low); \
} while (0)
/**
* \brief Decrypts data using the ASCON state in sliced form.
*
* \param state The ASCON state.
* \param m Points to 8 bytes of output plaintext in big-endian byte order.
* \param c Points to 8 bytes of input ciphertext in big-endian byte order.
* \param offset Offset of the 64-bit word within the state to absorb
* and squeeze at, between 0 and 4.
*/
#define ascon_decrypt_sliced(state, m, c, offset) \
do { \
ascon_state_t *s = (state); \
uint32_t high, low, high2, low2; \
high = be_load_word32((c)); \
low = be_load_word32((c) + 4); \
ascon_separate(high); \
ascon_separate(low); \
high2 = high ^ ((s->W[(offset) * 2] >> 16) | \
(s->W[(offset) * 2 + 1] & 0xFFFF0000U)); \
low2 = low ^ ((s->W[(offset) * 2] & 0x0000FFFFU) | \
(s->W[(offset) * 2 + 1] << 16)); \
s->W[(offset) * 2] = (high << 16) | (low & 0x0000FFFFU); \
s->W[(offset) * 2 + 1] = (high & 0xFFFF0000U) | (low >> 16); \
ascon_combine(high2); \
ascon_combine(low2); \
be_store_word32((m), high2); \
be_store_word32((m) + 4, low2); \
} while (0)
#endif /* ASCON_SLICED */
/**
* \def ascon_separator()
* \brief Absorbs the standard ASCON separator for switching between
* associated data and message payload.
*/
#if ASCON_SLICED
#define ascon_separator() (state.W[8] ^= 0x01)
#else
#define ascon_separator() (state.B[39] ^= 0x01)
#endif
#ifdef __cplusplus
}
#endif
......
/*
* Copyright (C) 2021 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-util.h"
int aead_check_tag
(unsigned char *plaintext, size_t plaintext_len,
const unsigned char *tag1, const unsigned char *tag2, size_t 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;
}
void aead_clean(void *buf, unsigned size)
{
/* Force the use of volatile so that we actually clear the memory.
* Otherwise the compiler might optimise the entire contents of this
* function away, which will not be secure.
*
* Even this may not work. Some platforms have bzero_explicit() or
* memset_s() that could be used in place of this implementation. */
volatile uint8_t *d = (volatile uint8_t *)buf;
while (size > 0) {
*d++ = 0;
--size;
}
}
/*
* Copyright (C) 2020 Southern Storm Software, Pty Ltd.
* Copyright (C) 2021 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"),
......@@ -23,6 +23,7 @@
#ifndef LW_INTERNAL_UTIL_H
#define LW_INTERNAL_UTIL_H
#include <stddef.h>
#include <stdint.h>
/* Figure out how to inline functions using this C compiler */
......@@ -53,6 +54,13 @@
#error "Cannot determine the endianess of this platform"
#endif
/* Determine if we are compiling for a 64-bit CPU */
#if defined(__x86_64) || defined(__x86_64__) || \
defined(__aarch64__) || defined(__ARM_ARCH_ISA_A64) || \
defined(_M_AMD64) || defined(_M_X64) || defined(_M_IA64)
#define LW_UTIL_CPU_IS_64BIT 1
#endif
/* Helper macros to load and store values while converting endian-ness */
/* Load a big-endian 32-bit word from a byte buffer */
......@@ -89,6 +97,11 @@
(ptr)[3] = (uint8_t)(_x >> 24); \
} while (0)
/* Reverses the bytes in a 32-bit word */
#define reverse_word32(x) \
(((x) >> 24) | (((x) >> 8) & 0x0000FF00U) | \
(((x) << 8) & 0x00FF0000U) | ((x) << 24))
/* Load a big-endian 64-bit word from a byte buffer */
#define be_load_word64(ptr) \
((((uint64_t)((ptr)[0])) << 56) | \
......@@ -699,4 +712,52 @@
#define rightRotate6_8(a) (rightRotate_8((a), 6))
#define rightRotate7_8(a) (rightRotate_8((a), 7))
/**
* \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 size 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, size_t plaintext_len,
const unsigned char *tag1, const unsigned char *tag2, size_t size);
/**
* \brief Attempts to cleans a buffer that contains sensitive material.
*
* \param buf Points to the buffer to clear.
* \param size Size of the buffer to clear in bytes.
*/
void aead_clean(void *buf, unsigned size);
/**
* \brief Number of bytes to retrieve from the system TRNG each time
* we need to reseed application-level PRNG's.
*/
#define AEAD_SYSTEM_SEED_SIZE 32
/**
* \brief Gets data from the system TRNG to reseed application-level PRNG's.
*
* \param seed Points to the buffer to be populated with the system seed.
*
* \return Non-zero if \a seed has been filled with TRNG data or zero
* if there is no accessible TRNG on this system.
*
* The quality of the returned seed data may be very poor or may not
* distribute the entropy evenly throughout the returned \a seed buffer.
* The application should use a PRNG to hash the seed data into a more
* useful random sequence.
*/
int aead_random_get_system_seed(unsigned char seed[AEAD_SYSTEM_SEED_SIZE]);
#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.
#define CRYPTO_KEYBYTES 16
#define CRYPTO_NSECBYTES 0
#define CRYPTO_NPUBBYTES 16
#define CRYPTO_ABYTES 16
#define CRYPTO_NOOVERLAP 1
#define CRYPTO_BYTES 32
/*
* Copyright (C) 2021 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_ASCON_AEAD_H
#define LWCRYPTO_ASCON_AEAD_H
#include <stddef.h>
/**
* \file ascon-aead.h
* \brief ASCON-128 encryption algorithm and related family members.
*
* The ASCON family consists of several related algorithms:
*
* \li ASCON-128 with a 128-bit key, a 128-bit nonce, a 128-bit authentication
* tag, and a block rate of 64 bits.
* \li ASCON-128a with a 128-bit key, a 128-bit nonce, a 128-bit authentication
* tag, and a block rate of 128 bits. This is faster than ASCON-128 but may
* not be as secure.
* \li ASCON-80pq with a 160-bit key, a 128-bit nonce, a 128-bit authentication
* tag, and a block rate of 64 bits. This is similar to ASCON-128 but has a
* 160-bit key instead which may be more resistant against quantum computers.
* \li ASCON-HASH and ASCON-HASHA with a 256-bit hash output.
* \li ASCON-XOF and ASCON-XOFA with extensible hash output (XOF mode).
*
* References: https://ascon.iaik.tugraz.at/
*/
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief Size of the key for ASCON-128 and ASCON-128a.
*/
#define ASCON128_KEY_SIZE 16
/**
* \brief Size of the nonce for ASCON-128 and ASCON-128a.
*/
#define ASCON128_NONCE_SIZE 16
/**
* \brief Size of the authentication tag for ASCON-128 and ASCON-128a.
*/
#define ASCON128_TAG_SIZE 16
/**
* \brief Size of the key for ASCON-80pq.
*/
#define ASCON80PQ_KEY_SIZE 20
/**
* \brief Size of the nonce for ASCON-80pq.
*/
#define ASCON80PQ_NONCE_SIZE 16
/**
* \brief Size of the authentication tag for ASCON-80pq.
*/
#define ASCON80PQ_TAG_SIZE 16
/**
* \brief Encrypts and authenticates a packet with ASCON-128.
*
* \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 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 ascon128_aead_decrypt()
*/
int ascon128_aead_encrypt
(unsigned char *c, size_t *clen,
const unsigned char *m, size_t mlen,
const unsigned char *ad, size_t adlen,
const unsigned char *npub,
const unsigned char *k);
/**
* \brief Decrypts and authenticates a packet with ASCON-128.
*
* \param m Buffer to receive the plaintext message on output.
* \param mlen Receives the length of the plaintext message on output.
* \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 ascon128_aead_encrypt()
*/
int ascon128_aead_decrypt
(unsigned char *m, size_t *mlen,
const unsigned char *c, size_t clen,
const unsigned char *ad, size_t adlen,
const unsigned char *npub,
const unsigned char *k);
/**
* \brief Encrypts and authenticates a packet with ASCON-128a.
*
* \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 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 ascon128a_aead_decrypt()
*/
int ascon128a_aead_encrypt
(unsigned char *c, size_t *clen,
const unsigned char *m, size_t mlen,
const unsigned char *ad, size_t adlen,
const unsigned char *npub,
const unsigned char *k);
/**
* \brief Decrypts and authenticates a packet with ASCON-128a.
*
* \param m Buffer to receive the plaintext message on output.
* \param mlen Receives the length of the plaintext message on output.
* \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 ascon128a_aead_encrypt()
*/
int ascon128a_aead_decrypt
(unsigned char *m, size_t *mlen,
const unsigned char *c, size_t clen,
const unsigned char *ad, size_t adlen,
const unsigned char *npub,
const unsigned char *k);
/**
* \brief Encrypts and authenticates a packet with ASCON-80pq.
*
* \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 npub Points to the public nonce for the packet which must
* be 16 bytes in length.
* \param k Points to the 20 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 ascon80pq_aead_decrypt()
*/
int ascon80pq_aead_encrypt
(unsigned char *c, size_t *clen,
const unsigned char *m, size_t mlen,
const unsigned char *ad, size_t adlen,
const unsigned char *npub,
const unsigned char *k);
/**
* \brief Decrypts and authenticates a packet with ASCON-80pq.
*
* \param m Buffer to receive the plaintext message on output.
* \param mlen Receives the length of the plaintext message on output.
* \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 20 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 ascon80pq_aead_encrypt()
*/
int ascon80pq_aead_decrypt
(unsigned char *m, size_t *mlen,
const unsigned char *c, size_t clen,
const unsigned char *ad, size_t adlen,
const unsigned char *npub,
const unsigned char *k);
#ifdef __cplusplus
}
#endif
#endif
/*
* Copyright (C) 2021 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 "ascon-hash.h"
#include <string.h>
int ascon_hash(unsigned char *out, const unsigned char *in, size_t inlen)
{
ascon_xof_state_t state;
ascon_hash_init(&state);
ascon_xof_absorb(&state, in, inlen);
ascon_xof_squeeze(&state, out, ASCON_HASH_SIZE);
return 0;
}
void ascon_hash_init(ascon_hash_state_t *state)
{
/* IV for ASCON-HASH after processing it with the permutation */
static unsigned char const hash_iv[40] = {
0xee, 0x93, 0x98, 0xaa, 0xdb, 0x67, 0xf0, 0x3d,
0x8b, 0xb2, 0x18, 0x31, 0xc6, 0x0f, 0x10, 0x02,
0xb4, 0x8a, 0x92, 0xdb, 0x98, 0xd5, 0xda, 0x62,
0x43, 0x18, 0x99, 0x21, 0xb8, 0xf8, 0xe3, 0xe8,
0x34, 0x8f, 0xa5, 0xc9, 0xd5, 0x25, 0xe1, 0x40
};
memcpy(state->s.state, hash_iv, sizeof(hash_iv));
state->s.count = 0;
state->s.mode = 0;
}
void ascon_hash_update
(ascon_hash_state_t *state, const unsigned char *in, size_t inlen)
{
ascon_xof_absorb(state, in, inlen);
}
void ascon_hash_finalize(ascon_hash_state_t *state, unsigned char *out)
{
ascon_xof_squeeze(state, out, ASCON_HASH_SIZE);
}
int ascon_hasha(unsigned char *out, const unsigned char *in, size_t inlen)
{
ascon_xof_state_t state;
ascon_hasha_init(&state);
ascon_xofa_absorb(&state, in, inlen);
ascon_xofa_squeeze(&state, out, ASCON_HASH_SIZE);
return 0;
}
void ascon_hasha_init(ascon_hash_state_t *state)
{
/* IV for ASCON-HASHA after processing it with the permutation */
static unsigned char const hash_iv[40] = {
0x01, 0x47, 0x01, 0x94, 0xfc, 0x65, 0x28, 0xa6,
0x73, 0x8e, 0xc3, 0x8a, 0xc0, 0xad, 0xff, 0xa7,
0x2e, 0xc8, 0xe3, 0x29, 0x6c, 0x76, 0x38, 0x4c,
0xd6, 0xf6, 0xa5, 0x4d, 0x7f, 0x52, 0x37, 0x7d,
0xa1, 0x3c, 0x42, 0xa2, 0x23, 0xbe, 0x8d, 0x87
};
memcpy(state->s.state, hash_iv, sizeof(hash_iv));
state->s.count = 0;
state->s.mode = 0;
}
void ascon_hasha_update
(ascon_hash_state_t *state, const unsigned char *in, size_t inlen)
{
ascon_xofa_absorb(state, in, inlen);
}
void ascon_hasha_finalize(ascon_hash_state_t *state, unsigned char *out)
{
ascon_xofa_squeeze(state, out, ASCON_HASH_SIZE);
}
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