Commit 7498fcdd authored by obronchain's avatar obronchain

first commit

parents
MIT License
Copyright (c) 2019 Gaëtan Cassiers
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.
# Spook Embedded Systems Implementations
Spook software implementations for Cortex-Mx microprocessors.
## Implementations
A straightforward, standard and portable C99 implementation. It is based on the reference implementation with changes to enable better compiler optimizations.
These primitives have much better performance than the reference implementation, however they are not fully optimized either: portability and code simplicity are also a concern.
## Configuration
Selecting the spook variant is done by means of the `#define`s `MULTI_USER` and `SMALL_PERM` (both default to `0`, which gives the primary candidate).
## Build
Have a look at `test/Makefile`.
## Test
```sh
$ cd test
$ ./test.sh
```
## Contributing
Contributions of any kind (code, bug reports, benckmarks, ...) are welcome. Please contact us at `team@spook.dev`.
## License
This software distributed under the terms of the MIT license. See [LICENSE](LICENSE) for details.
#include "parameters.h"
#define CRYPTO_KEYBYTES KEYBYTES
#define CRYPTO_NPUBBYTES 16
#define CRYPTO_NSECBYTES 0
#define CRYPTO_ABYTES 16
#define CRYPTO_NOOVERLAP 1
/* MIT License
*
* Copyright (c) 2019 Gaëtan Cassiers Olivier Bronchain
*
* 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 <string.h>
#include <stdint.h>
#include "primitives.h"
#define CLYDE_128_NS 6 // Number of steps
#define CLYDE_128_NR 2 * CLYDE_128_NS // Number of rounds
// Round constants for Clyde-128
static const uint32_t clyde128_rc[CLYDE_128_NR][LS_ROWS] = {
{ 1, 0, 0, 0 }, // 0
{ 0, 1, 0, 0 }, // 1
{ 0, 0, 1, 0 }, // 2
{ 0, 0, 0, 1 }, // 3
{ 1, 1, 0, 0 }, // 4
{ 0, 1, 1, 0 }, // 5
{ 0, 0, 1, 1 }, // 6
{ 1, 1, 0, 1 }, // 7
{ 1, 0, 1, 0 }, // 8
{ 0, 1, 0, 1 }, // 9
{ 1, 1, 1, 0 }, // 10
{ 0, 1, 1, 1 } // 11
};
// Apply a S-box layer to a Clyde-128 state.
static void sbox_layer(uint32_t* state) {
uint32_t y1 = (state[0] & state[1]) ^ state[2];
uint32_t y0 = (state[3] & state[0]) ^ state[1];
uint32_t y3 = (y1 & state[3]) ^ state[0];
uint32_t y2 = (y0 & y1) ^ state[3];
state[0] = y0;
state[1] = y1;
state[2] = y2;
state[3] = y3;
}
// Apply a L-box to a pair of Clyde-128 rows.
#define ROT32(x,n) ((uint32_t)(((x)>>(n))|((x)<<(32-(n)))))
static void lbox(uint32_t* x, uint32_t* y) {
uint32_t a, b, c, d;
a = *x ^ ROT32(*x, 12);
b = *y ^ ROT32(*y, 12);
a = a ^ ROT32(a, 3);
b = b ^ ROT32(b, 3);
a = a ^ ROT32(*x, 17);
b = b ^ ROT32(*y, 17);
c = a ^ ROT32(a, 31);
d = b ^ ROT32(b, 31);
a = a ^ ROT32(d, 26);
b = b ^ ROT32(c, 25);
a = a ^ ROT32(c, 15);
b = b ^ ROT32(d, 15);
*x = a;
*y = b;
}
#define XORLS(DEST, OP) do { \
(DEST)[0] ^= (OP)[0]; \
(DEST)[1] ^= (OP)[1]; \
(DEST)[2] ^= (OP)[2]; \
(DEST)[3] ^= (OP)[3]; } while (0)
#define XORCST(DEST, LFSR) do { \
(DEST)[0] ^= ((LFSR)>>3 & 0x1); \
(DEST)[1] ^= ((LFSR)>>2 & 0x1); \
(DEST)[2] ^= ((LFSR)>>1 & 0x1); \
(DEST)[3] ^= ((LFSR) & 0x1); } while (0)
void clyde128_encrypt(clyde128_state state, const clyde128_state t, const unsigned char* k) {
// Key schedule
clyde128_state k_st;
memcpy(k_st, k, CLYDE128_NBYTES);
clyde128_state tk[3] = {
{ t[0], t[1], t[2], t[3] },
{ t[0] ^ t[2], t[1] ^ t[3], t[0], t[1] },
{ t[2], t[3], t[0] ^ t[2], t[1] ^ t[3] }
};
XORLS(tk[0], k_st);
XORLS(tk[1], k_st);
XORLS(tk[2], k_st);
// Datapath
XORLS(state, tk[0]);
uint32_t off = 0x924; // 2-bits describing the round key
uint32_t lfsr = 0x8; // LFSR for round constant
for (uint32_t s = 0; s < CLYDE_128_NS; s++) {
sbox_layer(state);
lbox(&state[0], &state[1]);
lbox(&state[2], &state[3]);
XORCST(state,lfsr);
uint32_t b = lfsr & 0x1;
lfsr = (lfsr^(b<<3) | b<<4)>>1; // update LFSR
sbox_layer(state);
lbox(&state[0], &state[1]);
lbox(&state[2], &state[3]);
XORCST(state,lfsr);
b = lfsr & 0x1;
lfsr = (lfsr^(b<<3) | b<<4)>>1; // update LFSR
off >>=2;
XORLS(state, tk[off&0x03]);
}
}
/* MIT License
*
* Copyright (c) 2019 Gaëtan Cassiers
*
* 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 <string.h>
#include <stdint.h>
#ifdef BENCH_IACA
#include "iacaMarks.h"
#else
#define IACA_START
#define IACA_END
#endif
#include "primitives.h"
#define CLYDE_128_NS 6 // Number of steps
#define CLYDE_128_NR 2 * CLYDE_128_NS // Number of rounds
// Round constants for Clyde-128
static const uint32_t clyde128_rc[CLYDE_128_NR][LS_ROWS] = {
{ 1, 0, 0, 0 }, // 0
{ 0, 1, 0, 0 }, // 1
{ 0, 0, 1, 0 }, // 2
{ 0, 0, 0, 1 }, // 3
{ 1, 1, 0, 0 }, // 4
{ 0, 1, 1, 0 }, // 5
{ 0, 0, 1, 1 }, // 6
{ 1, 1, 0, 1 }, // 7
{ 1, 0, 1, 0 }, // 8
{ 0, 1, 0, 1 }, // 9
{ 1, 1, 1, 0 }, // 10
{ 0, 1, 1, 1 } // 11
};
// Apply a inverse S-box layer to a Clyde-128 state.
static void sbox_layer_inv(uint32_t* state) {
uint32_t y3 = (state[0] & state[1]) ^ state[2];
uint32_t y0 = (state[1] & y3) ^ state[3];
uint32_t y1 = (y3 & y0) ^ state[0];
uint32_t y2 = (y0 & y1) ^ state[1];
state[0] = y0;
state[1] = y1;
state[2] = y2;
state[3] = y3;
}
// Apply a inverse L-box to a pair of Clyde-128 rows.
#define ROT32(x,n) ((uint32_t)(((x)>>(n))|((x)<<(32-(n)))))
static void lbox_inv(uint32_t* x, uint32_t* y) {
uint32_t a, b, c, d;
a = *x ^ ROT32(*x, 25);
b = *y ^ ROT32(*y, 25);
c = *x ^ ROT32(a, 31);
d = *y ^ ROT32(b, 31);
c = c ^ ROT32(a, 20);
d = d ^ ROT32(b, 20);
a = c ^ ROT32(c, 31);
b = d ^ ROT32(d, 31);
c = c ^ ROT32(b, 26);
d = d ^ ROT32(a, 25);
a = a ^ ROT32(c, 17);
b = b ^ ROT32(d, 17);
a = ROT32(a, 16);
b = ROT32(b, 16);
*x = a;
*y = b;
}
#define XORLS(DEST, OP) do { \
(DEST)[0] ^= (OP)[0]; \
(DEST)[1] ^= (OP)[1]; \
(DEST)[2] ^= (OP)[2]; \
(DEST)[3] ^= (OP)[3]; } while (0)
void clyde128_decrypt(clyde128_state state, const clyde128_state t, const unsigned char* k) {
// Key schedule
clyde128_state k_st;
memcpy(k_st, k, CLYDE128_NBYTES);
clyde128_state tk[3] = {
{ t[0], t[1], t[2], t[3] },
{ t[0] ^ t[2], t[1] ^ t[3], t[0], t[1] },
{ t[2], t[3], t[0] ^ t[2], t[1] ^ t[3] }
};
XORLS(tk[0], k);
XORLS(tk[1], k);
XORLS(tk[2], k);
// Datapath
for (unsigned int s = 0; s < CLYDE_128_NS; s++) {
IACA_START
unsigned int r = 2 * s;
unsigned int off = (s+1) % 3;
XORLS(state, tk[off]);
XORLS(state, clyde128_rc[r+1]);
lbox_inv(&state[0], &state[1]);
lbox_inv(&state[2], &state[3]);
sbox_layer_inv(state);
XORLS(state, clyde128_rc[r]);
lbox_inv(&state[0], &state[1]);
lbox_inv(&state[2], &state[3]);
sbox_layer_inv(state);
}
IACA_END
XORLS(state, tk[0]);
}
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);
/* Spook Reference Implementation v1
*
* Written in 2019 at UCLouvain (Belgium) by Olivier Bronchain, Gaetan Cassiers
* and Charles Momin.
* To the extent possible under law, the author(s) have dedicated all copyright
* and related and neighboring rights to this software to the public domain
* worldwide. This software is distributed without any warranty.
*
* You should have received a copy of the CC0 Public Domain Dedication along with
* this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
*/
#include "crypto_aead.h"
#include "s1p.h"
#ifdef __GNUC__
#define UNUSED __attribute__((unused))
#else
#define UNUSED
#endif
// Spook encryption.
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 UNUSED,
const unsigned char* npub, const unsigned char* k) {
unsigned char p[P_NBYTES];
const unsigned char* k_priv;
init_keys(&k_priv, p, k);
s1p_encrypt(c, clen, ad, adlen, m, mlen, k_priv, p, npub);
return 0;
}
// Spook encryption.
int crypto_aead_decrypt(unsigned char* m, unsigned long long* mlen,
unsigned char* nsec UNUSED, const unsigned char* c,
unsigned long long clen, const unsigned char* ad,
unsigned long long adlen, const unsigned char* npub,
const unsigned char* k) {
unsigned char p[P_NBYTES];
const unsigned char* k_priv;
init_keys(&k_priv, p, k);
return s1p_decrypt(m, mlen, ad, adlen, c, clen, k_priv, p, npub);
}
/*
* Copyright (2008-2009) Intel Corporation All Rights Reserved.
* The source code contained or described herein and all documents
* related to the source code ("Material") are owned by Intel Corporation
* or its suppliers or licensors. Title to the Material remains with
* Intel Corporation or its suppliers and licensors. The Material
* contains trade secrets and proprietary and confidential information
* of Intel or its suppliers and licensors. The Material is protected
* by worldwide copyright and trade secret laws and treaty provisions.
* No part of the Material may be used, copied, reproduced, modified,
* published, uploaded, posted, transmitted, distributed, or disclosed
* in any way without Intel(R)s prior express written permission.
*
* No license under any patent, copyright, trade secret or other
* intellectual property right is granted to or conferred upon you by
* disclosure or delivery of the Materials, either expressly, by implication,
* inducement, estoppel or otherwise. Any license under such intellectual
* property rights must be express and approved by Intel in writing.
*/
#if defined (__GNUC__)
#define IACA_SSC_MARK( MARK_ID ) \
__asm__ __volatile__ ( \
"\n\t movl $"#MARK_ID", %%ebx" \
"\n\t .byte 0x64, 0x67, 0x90" \
: : : "memory" );
#else
#define IACA_SSC_MARK(x) {__asm mov ebx, x\
__asm _emit 0x64 \
__asm _emit 0x67 \
__asm _emit 0x90 }
#endif
#define IACA_START {IACA_SSC_MARK(111)}
#define IACA_END {IACA_SSC_MARK(222)}
#ifdef _WIN64
#include <intrin.h>
#define IACA_VC64_START __writegsbyte(111, 111);
#define IACA_VC64_END __writegsbyte(222, 222);
#endif
/**************** asm *****************
;START_MARKER
mov ebx, 111
db 0x64, 0x67, 0x90
;END_MARKER
mov ebx, 222
db 0x64, 0x67, 0x90
**************************************/
/* Spook Reference Implementation v1
*
* Written in 2019 at UCLouvain (Belgium) by Olivier Bronchain, Gaetan Cassiers
* and Charles Momin.
* To the extent possible under law, the author(s) have dedicated all copyright
* and related and neighboring rights to this software to the public domain
* worldwide. This software is distributed without any warranty.
*
* You should have received a copy of the CC0 Public Domain Dedication along with
* this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
*/
#ifndef _PARAMETERS_H_
#define _PARAMETERS_H_
// Selects the "su" variant if set to 0 and the "mu" variant if set to "1"
#ifndef MULTI_USER
#define MULTI_USER 0
#endif // MULTI_USER
// Selects the "512" variant if set to 0 and the "384" variant if set to "1"
#ifndef SMALL_PERM
#define SMALL_PERM 0
#endif // SMALL_PERM
#if MULTI_USER
#define KEYBYTES 32
#else
#define KEYBYTES 16
#endif
#include "api.h"
#if (KEYBYTES != CRYPTO_KEYBYTES)
#error "Wrong parameters in api.h"
#endif
#endif //_PARAMETERS_H_
/* Spook Reference Implementation v1
*
* Written in 2019 at UCLouvain (Belgium) by Olivier Bronchain, Gaetan Cassiers
* and Charles Momin.
* To the extent possible under law, the author(s) have dedicated all copyright
* and related and neighboring rights to this software to the public domain
* worldwide. This software is distributed without any warranty.
*
* You should have received a copy of the CC0 Public Domain Dedication along with
* this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
*/
#ifndef _H_PRIMITIVES_H_
#define _H_PRIMITIVES_H_
#include <stdint.h>
#include "parameters.h"
#define CLYDE128_NBYTES 16
#if SMALL_PERM
#define SHADOW_NBYTES 48
#else
#define SHADOW_NBYTES 64
#endif // SMALL_PERM
#define LS_ROWS 4 // Rows in the LS design
#define LS_ROW_BYTES 4 // number of bytes per row in the LS design
#define MLS_BUNDLES \
(SHADOW_NBYTES / (LS_ROWS* LS_ROW_BYTES)) // Bundles in the mLS design
#define CLYDE_TYPE "clyde_32bit.c"
#define SHADOW_TYPE "shadow_128bit.c"
typedef __attribute__((aligned(16))) uint32_t clyde128_state[LS_ROWS];
typedef __attribute__((aligned(64))) clyde128_state shadow_state[MLS_BUNDLES];
void clyde128_encrypt(clyde128_state state,
const clyde128_state t, const unsigned char* k);
void shadow(shadow_state state);
#endif //_H_PRIMITIVES_H_
/* MIT License
*
* Copyright (c) 2019 Gaëtan Cassiers
*
* 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 <stdlib.h>
#include <string.h>
#include <stdint.h>
#include "s1p.h"
#include "parameters.h"
#include "primitives.h"
#define CAPACITY_BYTES 32
#define RATE_BYTES (SHADOW_NBYTES - CAPACITY_BYTES)
#define RATE_BUNDLES (RATE_BYTES/(LS_ROWS*LS_ROW_BYTES))
// Working mode for block compression.
typedef enum {
AD,
PLAINTEXT,
CIPHERTEXT
} compress_mode;
static void compress_block(unsigned char *state, unsigned char *out,
const unsigned char *d, compress_mode mode,
unsigned long long offset, unsigned long long n);
static unsigned long long compress_data(shadow_state state,
unsigned char *out,
const unsigned char *d,
unsigned long long dlen,
compress_mode mode);
static void init_sponge_state(shadow_state state,
const unsigned char *k, const unsigned char *p,
const unsigned char *n);
static void xor_bytes(unsigned char* dest, const unsigned char* src1,
const unsigned char* src2, unsigned long long n);
void init_keys(const unsigned char **k, unsigned char p[P_NBYTES],
const unsigned char *k_glob) {
*k = k_glob;
#if MULTI_USER
memcpy(p, k_glob + CLYDE128_NBYTES, P_NBYTES);
p[P_NBYTES - 1] &= 0x7F; // set last p bit to 0
p[P_NBYTES - 1] |= 0x40; // set next to last p bit to 0
#else
memset(p, 0, P_NBYTES);
#endif // MULTI_USER
}
static void init_sponge_state(shadow_state state,
const unsigned char *k, const unsigned char *p,
const unsigned char *n) {
// init state
memset(state, 0, SHADOW_NBYTES);
memcpy(state[0], p, P_NBYTES);
memcpy(state[1], n, CRYPTO_NPUBBYTES);
// TBC
memcpy(state[MLS_BUNDLES-1], n, CRYPTO_NPUBBYTES);
clyde128_encrypt(state[MLS_BUNDLES-1], state[0], k);
// initial permutation
shadow(state);
}
void s1p_encrypt(unsigned char *c, unsigned long long *clen,
const unsigned char *ad, unsigned long long adlen,
const unsigned char *m, unsigned long long mlen,
const unsigned char *k, const unsigned char *p,
const unsigned char *n) {
// permutation state
shadow_state state;
init_sponge_state(state, k, p, n);
// compress associated data
compress_data(state, NULL, ad, adlen, AD);
// compress message
unsigned long long c_bytes = 0;
if (mlen > 0) {
state[RATE_BUNDLES][0] ^= 0x01;
c_bytes = compress_data(state, c, m, mlen, PLAINTEXT);
}
// tag
state[1][LS_ROWS- 1] |= 0x80000000;
clyde128_encrypt(state[0], state[1], k);
memcpy(c+c_bytes, state[0], CLYDE128_NBYTES);
*clen = c_bytes + CLYDE128_NBYTES;
}
int s1p_decrypt(unsigned char *m, unsigned long long *mlen,
const unsigned char *ad, unsigned long long adlen,
const unsigned char *c, unsigned long long clen,
const unsigned char *k, const unsigned char *p,
const unsigned char *n) {
// permutation state
shadow_state state;
init_sponge_state(state, k, p, n);
// compress associated data
compress_data(state, NULL, ad, adlen, AD);
// compress message
unsigned long long m_bytes = 0;
if (clen > CLYDE128_NBYTES) {
state[RATE_BUNDLES][0] ^= 0x01;
m_bytes = compress_data(state, m, c, clen - CLYDE128_NBYTES, CIPHERTEXT);
}
// tag verification
state[1][LS_ROWS- 1] |= 0x80000000;
clyde128_encrypt(state[0], state[1], k);
unsigned char *st0 = (unsigned char *) state[0];
int tag_ok = 1;
for (int i = 0; i < 4*LS_ROWS; i++) {
tag_ok &= (st0[i] == c[m_bytes+i]);
}
if (tag_ok) {
*mlen = m_bytes;
return 0;
} else {
// Reset output buffer to avoid unintended unauthenticated plaintext
// release.
memset(m, 0, clen - CLYDE128_NBYTES);
*mlen = 0;
return -1;
}
}
// Compress a block into the state. Length of the block is n and buffers are
// accessed starting at offset. Input block is d, output is written into
// buffer out if mode is PLAINTEXT or CIPHERTEXT.
// Only the XOR operation is performed, not XORing of padding constants.
static void compress_block(unsigned char *state, unsigned char *out,
const unsigned char *d, compress_mode mode,
unsigned long long offset, unsigned long long n) {
if (mode == CIPHERTEXT) {
xor_bytes(out + offset, state, d + offset, n);
memcpy(state, d + offset, n);
} else {
xor_bytes(state, state, d + offset, n);
if (mode == PLAINTEXT) {
memcpy(out + offset, state, n);
}
}
}
// Compress a block into the state (in duplex-sponge mode).
// Input data buffer is d with length dlen.
// Output is written into buffer out if mode is PLAINTEXT or CIPHERTEXT.
// Padding is handled if needed.
static unsigned long long compress_data(shadow_state state,
unsigned char *out,
const unsigned char *d,
unsigned long long dlen,
compress_mode mode) {
unsigned long long i;
for (i = 0; i < dlen / RATE_BYTES; i++) {
compress_block((uint8_t *)state, out, d, mode, i * RATE_BYTES, RATE_BYTES);
shadow(state);
}
int rem = dlen % RATE_BYTES;
if (rem != 0) {
compress_block((uint8_t *)state, out, d, mode, i * RATE_BYTES, rem);
((uint8_t *)state)[rem] ^= 0x01;
((uint8_t *)state)[RATE_BYTES] ^= 0x02;
shadow(state);
}
return i * RATE_BYTES + rem;
}
// XOR buffers src1 and src2 into buffer dest (all buffers contain n bytes).
void xor_bytes(unsigned char* dest, const unsigned char* src1,
const unsigned char* src2, unsigned long long n) {
for (unsigned long long i = 0; i < n; i++) {
dest[i] = src1[i] ^ src2[i];
}
}
/* MIT License
*
* Copyright (c) 2019 Gaëtan Cassiers
*
* 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 _H_S1P_H_
#define _H_S1P_H_
#include "parameters.h"
// Size of the P parameter
#define P_NBYTES 16