mirror of
https://github.com/ntop/n2n.git
synced 2024-09-20 00:51:10 +02:00
speck transform code clean-up
This commit is contained in:
parent
b3d4f21c91
commit
e8181c96f9
|
@ -1,3 +1,22 @@
|
||||||
|
/**
|
||||||
|
* (C) 2007-20 - ntop.org and contributors
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not see see <http://www.gnu.org/licenses/>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
// cipher SPECK -- 128 bit block size -- 256 bit key size
|
// cipher SPECK -- 128 bit block size -- 256 bit key size
|
||||||
// taken from (and modified: removed pure crypto-stream generation and seperated key expansion)
|
// taken from (and modified: removed pure crypto-stream generation and seperated key expansion)
|
||||||
// https://github.com/nsacyber/simon-speck-supercop/blob/master/crypto_stream/speck128256ctr/
|
// https://github.com/nsacyber/simon-speck-supercop/blob/master/crypto_stream/speck128256ctr/
|
||||||
|
@ -7,13 +26,20 @@
|
||||||
#define SPECK_H
|
#define SPECK_H
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "portable_endian.h"
|
||||||
|
|
||||||
#define u32 uint32_t
|
#define u32 uint32_t
|
||||||
#define u64 uint64_t
|
#define u64 uint64_t
|
||||||
|
|
||||||
|
#define N2N_SPECK_IVEC_SIZE 16
|
||||||
|
#define SPECK_KEY_BYTES (256/8)
|
||||||
|
|
||||||
|
|
||||||
#if defined (__AVX2__)
|
#if defined (__AVX2__)
|
||||||
|
|
||||||
#define SPECK_ALIGNED_CTX 32
|
|
||||||
#include <immintrin.h>
|
#include <immintrin.h>
|
||||||
|
#define SPECK_ALIGNED_CTX 32
|
||||||
#define u256 __m256i
|
#define u256 __m256i
|
||||||
typedef struct {
|
typedef struct {
|
||||||
u256 rk[34];
|
u256 rk[34];
|
||||||
|
@ -22,9 +48,9 @@ typedef struct {
|
||||||
|
|
||||||
#elif defined (__SSE4_2__)
|
#elif defined (__SSE4_2__)
|
||||||
|
|
||||||
|
#include <immintrin.h>
|
||||||
#define SPECK_ALIGNED_CTX 16
|
#define SPECK_ALIGNED_CTX 16
|
||||||
#define SPECK_CTX_BYVAL 1
|
#define SPECK_CTX_BYVAL 1
|
||||||
#include <immintrin.h>
|
|
||||||
#define u128 __m128i
|
#define u128 __m128i
|
||||||
typedef struct {
|
typedef struct {
|
||||||
u128 rk[34];
|
u128 rk[34];
|
||||||
|
@ -48,33 +74,30 @@ typedef struct {
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// -----
|
||||||
|
|
||||||
int speck_ctr (unsigned char *out, const unsigned char *in, unsigned long long inlen,
|
int speck_ctr (unsigned char *out, const unsigned char *in, unsigned long long inlen,
|
||||||
const unsigned char *n,
|
const unsigned char *n,
|
||||||
#if defined (SPECK_CTX_BYVAL)
|
|
||||||
speck_context_t ctx);
|
|
||||||
#else
|
|
||||||
speck_context_t *ctx);
|
speck_context_t *ctx);
|
||||||
#endif
|
|
||||||
|
|
||||||
|
int speck_init (const unsigned char *k, speck_context_t **ctx);
|
||||||
|
|
||||||
int speck_expand_key (const unsigned char *k, speck_context_t *ctx);
|
int speck_deinit (speck_context_t *ctx);
|
||||||
|
|
||||||
|
// -----
|
||||||
|
|
||||||
int speck_he (unsigned char *out, const unsigned char *in, unsigned long long inlen,
|
int speck_he (unsigned char *out, const unsigned char *in, unsigned long long inlen,
|
||||||
const unsigned char *n, speck_context_t *ctx);
|
const unsigned char *n, speck_context_t *ctx);
|
||||||
|
|
||||||
|
|
||||||
int speck_expand_key_he (const unsigned char *k, speck_context_t *ctx);
|
int speck_expand_key_he (const unsigned char *k, speck_context_t *ctx);
|
||||||
|
|
||||||
|
// -----
|
||||||
|
|
||||||
int speck_he_iv_encrypt (unsigned char *inout, speck_context_t *ctx);
|
int speck_he_iv_encrypt (unsigned char *inout, speck_context_t *ctx);
|
||||||
|
|
||||||
|
|
||||||
int speck_he_iv_decrypt (unsigned char *inout, speck_context_t *ctx);
|
int speck_he_iv_decrypt (unsigned char *inout, speck_context_t *ctx);
|
||||||
|
|
||||||
|
|
||||||
int speck_expand_key_he_iv (const unsigned char *k, speck_context_t *ctx);
|
int speck_expand_key_he_iv (const unsigned char *k, speck_context_t *ctx);
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif // SPECK_H
|
||||||
|
|
184
src/speck.c
184
src/speck.c
|
@ -1,9 +1,26 @@
|
||||||
|
/**
|
||||||
|
* (C) 2007-20 - ntop.org and contributors
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not see see <http://www.gnu.org/licenses/>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
// cipher SPECK -- 128 bit block size -- 256 bit key size -- CTR mode
|
// cipher SPECK -- 128 bit block size -- 256 bit key size -- CTR mode
|
||||||
// taken from (and modified: removed pure crypto-stream generation and seperated key expansion)
|
// taken from (and modified: removed pure crypto-stream generation and seperated key expansion)
|
||||||
// https://github.com/nsacyber/simon-speck-supercop/blob/master/crypto_stream/speck128256ctr/
|
// https://github.com/nsacyber/simon-speck-supercop/blob/master/crypto_stream/speck128256ctr/
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include "portable_endian.h"
|
|
||||||
|
|
||||||
#include "speck.h"
|
#include "speck.h"
|
||||||
|
|
||||||
|
@ -139,7 +156,7 @@ static int speck_encrypt_xor(unsigned char *out, const unsigned char *in, u64 no
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int speck_ctr( unsigned char *out, const unsigned char *in, unsigned long long inlen,
|
static int internal_speck_ctr(unsigned char *out, const unsigned char *in, unsigned long long inlen,
|
||||||
const unsigned char *n, speck_context_t *ctx) {
|
const unsigned char *n, speck_context_t *ctx) {
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
|
@ -195,10 +212,11 @@ int speck_ctr( unsigned char *out, const unsigned char *in, unsigned long long i
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int speck_expand_key (const unsigned char *k, speck_context_t *ctx) {
|
static int speck_expand_key (const unsigned char *k, speck_context_t *ctx) {
|
||||||
|
|
||||||
u64 K[4];
|
u64 K[4];
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
for (i = 0; i < numkeywords; i++)
|
for (i = 0; i < numkeywords; i++)
|
||||||
K[i] = ((u64 *)k)[i];
|
K[i] = ((u64 *)k)[i];
|
||||||
|
|
||||||
|
@ -281,6 +299,7 @@ int speck_expand_key (const unsigned char *k, speck_context_t *ctx) {
|
||||||
RK(C,A,k,key,28), RK(D,A,k,key,29), RK(B,A,k,key,30), RK(C,A,k,key,31), RK(D,A,k,key,32), RK(B,A,k,key,33))
|
RK(C,A,k,key,28), RK(D,A,k,key,29), RK(B,A,k,key,30), RK(C,A,k,key,31), RK(D,A,k,key,32), RK(B,A,k,key,33))
|
||||||
|
|
||||||
|
|
||||||
|
// attention: ctx is provided by value as it is faster in this case, astonishingly
|
||||||
static int speck_encrypt_xor (unsigned char *out, const unsigned char *in, u64 nonce[], const speck_context_t ctx, int numbytes) {
|
static int speck_encrypt_xor (unsigned char *out, const unsigned char *in, u64 nonce[], const speck_context_t ctx, int numbytes) {
|
||||||
|
|
||||||
u64 x[2], y[2];
|
u64 x[2], y[2];
|
||||||
|
@ -325,8 +344,8 @@ static int speck_encrypt_xor (unsigned char *out, const unsigned char *in, u64 n
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// attention: ctx is provided by value as it is faster in this case, astonishingly
|
||||||
int speck_ctr (unsigned char *out, const unsigned char *in, unsigned long long inlen,
|
static int internal_speck_ctr (unsigned char *out, const unsigned char *in, unsigned long long inlen,
|
||||||
const unsigned char *n, const speck_context_t ctx) {
|
const unsigned char *n, const speck_context_t ctx) {
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
|
@ -377,10 +396,11 @@ int speck_ctr (unsigned char *out, const unsigned char *in, unsigned long long i
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int speck_expand_key (const unsigned char *k, speck_context_t *ctx) {
|
static int speck_expand_key (const unsigned char *k, speck_context_t *ctx) {
|
||||||
|
|
||||||
u64 K[4];
|
u64 K[4];
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
for (i = 0; i < numkeywords; i++)
|
for (i = 0; i < numkeywords; i++)
|
||||||
K[i] = ((u64 *)k)[i];
|
K[i] = ((u64 *)k)[i];
|
||||||
|
|
||||||
|
@ -497,7 +517,7 @@ static int speck_encrypt_xor (unsigned char *out, const unsigned char *in, u64 n
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int speck_ctr (unsigned char *out, const unsigned char *in, unsigned long long inlen,
|
static int internal_speck_ctr (unsigned char *out, const unsigned char *in, unsigned long long inlen,
|
||||||
const unsigned char *n, speck_context_t *ctx) {
|
const unsigned char *n, speck_context_t *ctx) {
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
|
@ -548,10 +568,11 @@ int speck_ctr (unsigned char *out, const unsigned char *in, unsigned long long i
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int speck_expand_key (const unsigned char *k, speck_context_t *ctx) {
|
static int speck_expand_key (const unsigned char *k, speck_context_t *ctx) {
|
||||||
|
|
||||||
u64 K[4];
|
u64 K[4];
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
for (i = 0; i < numkeywords; i++)
|
for (i = 0; i < numkeywords; i++)
|
||||||
K[i] = ((u64 *)k)[i];
|
K[i] = ((u64 *)k)[i];
|
||||||
|
|
||||||
|
@ -582,7 +603,7 @@ static int speck_encrypt (u64 *u, u64 *v, speck_context_t *ctx) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int speck_ctr (unsigned char *out, const unsigned char *in, unsigned long long inlen,
|
static int internal_speck_ctr (unsigned char *out, const unsigned char *in, unsigned long long inlen,
|
||||||
const unsigned char *n, speck_context_t *ctx) {
|
const unsigned char *n, speck_context_t *ctx) {
|
||||||
|
|
||||||
u64 i, nonce[2], x, y, t;
|
u64 i, nonce[2], x, y, t;
|
||||||
|
@ -617,7 +638,7 @@ int speck_ctr (unsigned char *out, const unsigned char *in, unsigned long long i
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int speck_expand_key (const unsigned char *k, speck_context_t *ctx) {
|
static int speck_expand_key (const unsigned char *k, speck_context_t *ctx) {
|
||||||
|
|
||||||
u64 K[4];
|
u64 K[4];
|
||||||
u64 i;
|
u64 i;
|
||||||
|
@ -638,12 +659,55 @@ int speck_expand_key (const unsigned char *k, speck_context_t *ctx) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif // AVX, SSE, NEON, plain C ------------------------------------------------
|
#endif // AVX, SSE, NEON, plain C
|
||||||
|
|
||||||
|
|
||||||
|
// this functions wraps the call to internal speck_ctr functions which have slightly different
|
||||||
|
// signature -- ctx by value for SSE with SPECK_CTX_BYVAL defined in speck.h, by name otherwise
|
||||||
|
inline int speck_ctr (unsigned char *out, const unsigned char *in, unsigned long long inlen,
|
||||||
|
const unsigned char *n, speck_context_t *ctx) {
|
||||||
|
|
||||||
|
return internal_speck_ctr (out, in, inlen, n,
|
||||||
|
#if defined (SPECK_CTX_BYVAL)
|
||||||
|
*ctx);
|
||||||
|
#else
|
||||||
|
ctx);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int speck_init (const unsigned char *k, speck_context_t **ctx) {
|
||||||
|
|
||||||
|
#if defined (SPECK_ALIGNED_CTX)
|
||||||
|
*ctx = (speck_context_t*) _mm_malloc (sizeof(speck_context_t), SPECK_ALIGNED_CTX);
|
||||||
|
#else
|
||||||
|
*ctx = (speck_context_t*) calloc (1, sizeof(speck_context_t));
|
||||||
|
#endif
|
||||||
|
if(!(*ctx)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return speck_expand_key(k, *ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int speck_deinit (speck_context_t *ctx) {
|
||||||
|
|
||||||
|
#if defined (SPECK_ALIGNED_CTX)
|
||||||
|
_mm_free (ctx);
|
||||||
|
#else
|
||||||
|
free (ctx);
|
||||||
|
#endif
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
// cipher SPECK -- 128 bit block size -- 128 bit key size -- CTR mode
|
// cipher SPECK -- 128 bit block size -- 128 bit key size -- CTR mode
|
||||||
// used for header encryption, thus the prefix 'he_'
|
// used for header encryption, thus the prefix 'he_'
|
||||||
// for now: just plain C -- AVX, SSE, NEON might follow
|
// for now: just plain C -- AVX, SSE, NEON do not make sense for short header
|
||||||
|
|
||||||
#define ROR64(x,r) (((x)>>(r))|((x)<<(64-(r))))
|
#define ROR64(x,r) (((x)>>(r))|((x)<<(64-(r))))
|
||||||
#define ROL64(x,r) (((x)<<(r))|((x)>>(64-(r))))
|
#define ROL64(x,r) (((x)<<(r))|((x)>>(64-(r))))
|
||||||
|
@ -787,97 +851,3 @@ int speck_expand_key_he_iv (const unsigned char *k, speck_context_t *ctx) {
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
/*
|
|
||||||
// code for testing -- to be removed when finished
|
|
||||||
#include <stdio.h> // for testing
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
int speck_test () {
|
|
||||||
|
|
||||||
uint8_t key[32] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
|
||||||
0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
|
|
||||||
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
|
|
||||||
0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F };
|
|
||||||
|
|
||||||
uint8_t k96[12] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
|
|
||||||
0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D };
|
|
||||||
|
|
||||||
uint8_t iv[16] = { 0x70, 0x6f, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x20,
|
|
||||||
0x49, 0x6e, 0x20, 0x74, 0x68, 0x6f, 0x73, 0x65 };
|
|
||||||
|
|
||||||
uint8_t xv[16] = { 0x20, 0x6d, 0x61, 0x64, 0x65, 0x20, 0x69, 0x74,
|
|
||||||
0x20, 0x65, 0x71, 0x75, 0x69, 0x76, 0x61, 0x6c };
|
|
||||||
|
|
||||||
uint8_t p96[12] = { 0x20, 0x75, 0x73, 0x61, 0x67, 0x65,
|
|
||||||
0x2C, 0x20, 0x68, 0x6F, 0x77, 0x65 };
|
|
||||||
|
|
||||||
uint8_t pt[16] = { 0x00 };
|
|
||||||
|
|
||||||
// expected outcome (according to pp. 35 & 36 of Implementation Guide 1.1 as of 2019) and
|
|
||||||
// original cipher presentation as of 2013 in which notably a different endianess is used
|
|
||||||
uint8_t ct[16] = { 0x43, 0x8f, 0x18, 0x9c, 0x8d, 0xb4, 0xee, 0x4e,
|
|
||||||
0x3e, 0xf5, 0xc0, 0x05, 0x04, 0x01, 0x09, 0x41 };
|
|
||||||
|
|
||||||
uint8_t xt[16] = { 0x18, 0x0d, 0x57, 0x5c, 0xdf, 0xfe, 0x60, 0x78,
|
|
||||||
0x65, 0x32, 0x78, 0x79, 0x51, 0x98, 0x5d, 0xa6 };
|
|
||||||
|
|
||||||
uint8_t x96[12] = { 0xAA, 0x79, 0x8F, 0xDE, 0xBD, 0x62,
|
|
||||||
0x78, 0x71, 0xAB, 0x09, 0x4D, 0x9E };
|
|
||||||
speck_context_t ctx;
|
|
||||||
|
|
||||||
speck_expand_key (key, &ctx);
|
|
||||||
#if defined (SPECK_CTX_BYVAL)
|
|
||||||
speck_ctr (pt, pt, 16, iv, ctx);
|
|
||||||
#else
|
|
||||||
speck_ctr (pt, pt, 16, iv, &ctx);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
u64 i;
|
|
||||||
fprintf (stderr, "rk00: %016llx\n", ctx.key[0]);
|
|
||||||
fprintf (stderr, "rk33: %016llx\n", ctx.key[33]);
|
|
||||||
fprintf (stderr, "out : %016lx\n", *(uint64_t*)pt);
|
|
||||||
fprintf (stderr, "mem : " ); for (i=0; i < 16; i++) fprintf (stderr, "%02x ", pt[i]); fprintf (stderr, "\n");
|
|
||||||
|
|
||||||
int ret = 1;
|
|
||||||
for (i=0; i < 16; i++)
|
|
||||||
if (pt[i] != ct[i]) ret = 0;
|
|
||||||
|
|
||||||
memset (pt, 0, 16);
|
|
||||||
speck_expand_key_he (key, &ctx);
|
|
||||||
speck_he (pt, pt, 16, xv, &ctx);
|
|
||||||
|
|
||||||
fprintf (stderr, "rk00: %016llx\n", ctx.key[0]);
|
|
||||||
fprintf (stderr, "rk31: %016llx\n", ctx.key[31]);
|
|
||||||
fprintf (stderr, "out : %016lx\n", *(uint64_t*)pt);
|
|
||||||
fprintf (stderr, "mem : " ); for (i=0; i < 16; i++) fprintf (stderr, "%02x ", pt[i]); fprintf (stderr, "\n");
|
|
||||||
|
|
||||||
for (i=0; i < 16; i++)
|
|
||||||
if (pt[i] != xt[i]) ret = 0;
|
|
||||||
|
|
||||||
speck_expand_key_he_iv (k96, &ctx);
|
|
||||||
speck_he_iv_encrypt (p96, &ctx);
|
|
||||||
// speck_he_iv_decrypt (p96, &ctx);
|
|
||||||
// speck_he_iv_encrypt (p96, &ctx);
|
|
||||||
|
|
||||||
fprintf (stderr, "rk00: %016llx\n", ctx.key[0]);
|
|
||||||
fprintf (stderr, "rk27: %016llx\n", ctx.key[27]);
|
|
||||||
fprintf (stderr, "out : %016lx\n", *(uint64_t*)p96);
|
|
||||||
fprintf (stderr, "mem : " ); for (i=0; i < 12; i++) fprintf (stderr, "%02x ", p96[i]); fprintf (stderr, "\n");
|
|
||||||
|
|
||||||
for (i=0; i < 12; i++)
|
|
||||||
if (p96[i] != x96[i]) ret = 0;
|
|
||||||
|
|
||||||
return (ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int main (int argc, char* argv[]) {
|
|
||||||
|
|
||||||
fprintf (stdout, "SPECK SELF TEST RESULT: %u\n", speck_test (0,NULL));
|
|
||||||
}
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
|
@ -16,19 +16,16 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "n2n.h"
|
#include "n2n.h"
|
||||||
|
|
||||||
#define N2N_SPECK_IVEC_SIZE 16
|
|
||||||
|
|
||||||
#define SPECK_KEY_BYTES (256/8)
|
|
||||||
|
|
||||||
/* Speck plaintext preamble */
|
/* Speck plaintext preamble */
|
||||||
#define TRANSOP_SPECK_PREAMBLE_SIZE (N2N_SPECK_IVEC_SIZE)
|
#define TRANSOP_SPECK_PREAMBLE_SIZE (N2N_SPECK_IVEC_SIZE)
|
||||||
|
|
||||||
typedef unsigned char n2n_speck_ivec_t[N2N_SPECK_IVEC_SIZE];
|
|
||||||
|
|
||||||
typedef struct transop_speck {
|
typedef struct transop_speck {
|
||||||
speck_context_t ctx; /* the round keys for payload encryption & decryption */
|
speck_context_t *ctx; /* the round keys for payload encryption & decryption */
|
||||||
} transop_speck_t;
|
} transop_speck_t;
|
||||||
|
|
||||||
/* ****************************************************** */
|
/* ****************************************************** */
|
||||||
|
@ -36,30 +33,15 @@ typedef struct transop_speck {
|
||||||
static int transop_deinit_speck(n2n_trans_op_t *arg) {
|
static int transop_deinit_speck(n2n_trans_op_t *arg) {
|
||||||
transop_speck_t *priv = (transop_speck_t *)arg->priv;
|
transop_speck_t *priv = (transop_speck_t *)arg->priv;
|
||||||
|
|
||||||
if(priv)
|
if(priv->ctx) speck_deinit(priv->ctx);
|
||||||
#if defined (SPECK_ALIGNED_CTX)
|
|
||||||
_mm_free (priv);
|
if(priv) free (priv);
|
||||||
#else
|
|
||||||
free (priv);
|
|
||||||
#endif
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ****************************************************** */
|
/* ****************************************************** */
|
||||||
|
|
||||||
static void set_speck_iv(transop_speck_t *priv, n2n_speck_ivec_t ivec) {
|
|
||||||
// keep in mind the following condition: N2N_SPECK_IVEC_SIZE % sizeof(rand_value) == 0 !
|
|
||||||
uint64_t rand_value;
|
|
||||||
uint8_t i;
|
|
||||||
|
|
||||||
for (i = 0; i < N2N_SPECK_IVEC_SIZE; i += sizeof(rand_value)) {
|
|
||||||
rand_value = n2n_rand();
|
|
||||||
memcpy(ivec + i, &rand_value, sizeof(rand_value));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ****************************************************** */
|
|
||||||
|
|
||||||
/** The Speck packet format consists of:
|
/** The Speck packet format consists of:
|
||||||
*
|
*
|
||||||
* - a 128-bit random IV
|
* - a 128-bit random IV
|
||||||
|
@ -74,31 +56,30 @@ static int transop_encode_speck(n2n_trans_op_t * arg,
|
||||||
const uint8_t * inbuf,
|
const uint8_t * inbuf,
|
||||||
size_t in_len,
|
size_t in_len,
|
||||||
const uint8_t * peer_mac) {
|
const uint8_t * peer_mac) {
|
||||||
|
|
||||||
int len=-1;
|
int len=-1;
|
||||||
transop_speck_t * priv = (transop_speck_t *)arg->priv;
|
transop_speck_t * priv = (transop_speck_t *)arg->priv;
|
||||||
|
|
||||||
if(in_len <= N2N_PKT_BUF_SIZE) {
|
if(in_len <= N2N_PKT_BUF_SIZE) {
|
||||||
if((in_len + TRANSOP_SPECK_PREAMBLE_SIZE) <= out_len) {
|
if((in_len + TRANSOP_SPECK_PREAMBLE_SIZE) <= out_len) {
|
||||||
size_t idx=0;
|
size_t idx=0;
|
||||||
n2n_speck_ivec_t enc_ivec = {0};
|
|
||||||
|
|
||||||
traceEvent(TRACE_DEBUG, "encode_speck %lu bytes", in_len);
|
traceEvent(TRACE_DEBUG, "encode_speck %lu bytes", in_len);
|
||||||
|
|
||||||
/* Generate and encode the IV. */
|
/* Generate and encode the IV. */
|
||||||
set_speck_iv(priv, enc_ivec);
|
encode_uint64(outbuf, &idx, n2n_rand());
|
||||||
encode_buf(outbuf, &idx, &enc_ivec, N2N_SPECK_IVEC_SIZE);
|
encode_uint64(outbuf, &idx, n2n_rand());
|
||||||
|
|
||||||
/* Encrypt the payload and write the ciphertext after the iv. */
|
/* Encrypt the payload and write the ciphertext after the iv. */
|
||||||
/* len is set to the length of the cipher plain text to be encrpyted
|
/* len is set to the length of the cipher plain text to be encrpyted
|
||||||
which is (in this case) identical to original packet lentgh */
|
which is (in this case) identical to original packet lentgh */
|
||||||
len = in_len;
|
len = in_len;
|
||||||
|
speck_ctr (outbuf + TRANSOP_SPECK_PREAMBLE_SIZE, // output starts right after the iv
|
||||||
|
inbuf, // input
|
||||||
|
in_len, // len
|
||||||
|
outbuf, // iv (already encoded in outbuf, speck does not change it)
|
||||||
|
priv->ctx); // ctx already setup with round keys
|
||||||
|
|
||||||
speck_ctr (outbuf + TRANSOP_SPECK_PREAMBLE_SIZE, inbuf, in_len, enc_ivec,
|
|
||||||
#if defined (SPECK_CTX_BYVAL)
|
|
||||||
(priv->ctx));
|
|
||||||
#else
|
|
||||||
&(priv->ctx));
|
|
||||||
#endif
|
|
||||||
traceEvent(TRACE_DEBUG, "encode_speck: encrypted %u bytes.\n", in_len);
|
traceEvent(TRACE_DEBUG, "encode_speck: encrypted %u bytes.\n", in_len);
|
||||||
|
|
||||||
len += TRANSOP_SPECK_PREAMBLE_SIZE; /* size of data carried in UDP. */
|
len += TRANSOP_SPECK_PREAMBLE_SIZE; /* size of data carried in UDP. */
|
||||||
|
@ -119,6 +100,7 @@ static int transop_decode_speck(n2n_trans_op_t * arg,
|
||||||
const uint8_t * inbuf,
|
const uint8_t * inbuf,
|
||||||
size_t in_len,
|
size_t in_len,
|
||||||
const uint8_t * peer_mac) {
|
const uint8_t * peer_mac) {
|
||||||
|
|
||||||
int len=0;
|
int len=0;
|
||||||
transop_speck_t * priv = (transop_speck_t *)arg->priv;
|
transop_speck_t * priv = (transop_speck_t *)arg->priv;
|
||||||
|
|
||||||
|
@ -128,21 +110,17 @@ static int transop_decode_speck(n2n_trans_op_t * arg,
|
||||||
{
|
{
|
||||||
size_t rem=in_len;
|
size_t rem=in_len;
|
||||||
size_t idx=0;
|
size_t idx=0;
|
||||||
n2n_speck_ivec_t dec_ivec = {0};
|
|
||||||
|
|
||||||
traceEvent(TRACE_DEBUG, "decode_speck %lu bytes", in_len);
|
traceEvent(TRACE_DEBUG, "decode_speck %lu bytes", in_len);
|
||||||
|
|
||||||
len = (in_len - TRANSOP_SPECK_PREAMBLE_SIZE);
|
len = (in_len - TRANSOP_SPECK_PREAMBLE_SIZE);
|
||||||
|
speck_ctr (outbuf, // output
|
||||||
|
inbuf + TRANSOP_SPECK_PREAMBLE_SIZE, // encrypted data starts right after preamble (IV)
|
||||||
|
len, // len
|
||||||
|
inbuf, // IV can be found at input's beginning
|
||||||
|
priv->ctx); // ctx already setup with round keys
|
||||||
|
|
||||||
/* Get the IV */
|
traceEvent(TRACE_DEBUG, "decode_speck decrypted %u bytes.\n", len);
|
||||||
decode_buf((uint8_t *)&dec_ivec, N2N_SPECK_IVEC_SIZE, inbuf, &rem, &idx);
|
|
||||||
|
|
||||||
speck_ctr (outbuf, inbuf + TRANSOP_SPECK_PREAMBLE_SIZE, len, dec_ivec,
|
|
||||||
#if defined (SPECK_CTX_BYVAL)
|
|
||||||
(priv->ctx));
|
|
||||||
#else
|
|
||||||
&(priv->ctx));
|
|
||||||
#endif
|
|
||||||
traceEvent(TRACE_DEBUG, "decode_speck: decrypted %u bytes.\n", len);
|
|
||||||
|
|
||||||
} else
|
} else
|
||||||
traceEvent(TRACE_ERROR, "decode_speck inbuf wrong size (%ul) to decrypt.", in_len);
|
traceEvent(TRACE_ERROR, "decode_speck inbuf wrong size (%ul) to decrypt.", in_len);
|
||||||
|
@ -154,20 +132,17 @@ static int transop_decode_speck(n2n_trans_op_t * arg,
|
||||||
|
|
||||||
static int setup_speck_key(transop_speck_t *priv, const uint8_t *key, ssize_t key_size) {
|
static int setup_speck_key(transop_speck_t *priv, const uint8_t *key, ssize_t key_size) {
|
||||||
|
|
||||||
uint8_t key_mat_buf[32] = { 0x00 };
|
uint8_t key_mat_buf[32];
|
||||||
|
|
||||||
/* Clear out any old possibly longer key matter. */
|
|
||||||
memset(&(priv->ctx), 0, sizeof(speck_context_t) );
|
|
||||||
|
|
||||||
/* the input key always gets hashed to make a more unpredictable and more complete use of the key space */
|
/* the input key always gets hashed to make a more unpredictable and more complete use of the key space */
|
||||||
pearson_hash_256(key_mat_buf, key, key_size);
|
pearson_hash_256(key_mat_buf, key, key_size);
|
||||||
|
|
||||||
/* expand the key material to the context (= round keys) */
|
/* expand the key material to the context (= round keys) */
|
||||||
speck_expand_key (key_mat_buf, &(priv->ctx));
|
speck_init(key_mat_buf, &(priv->ctx));
|
||||||
|
|
||||||
traceEvent(TRACE_DEBUG, "Speck key setup completed\n");
|
traceEvent(TRACE_DEBUG, "setup_speck_key completed\n");
|
||||||
|
|
||||||
return(0);
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ****************************************************** */
|
/* ****************************************************** */
|
||||||
|
@ -175,8 +150,10 @@ static int setup_speck_key(transop_speck_t *priv, const uint8_t *key, ssize_t ke
|
||||||
static void transop_tick_speck(n2n_trans_op_t * arg, time_t now) { ; }
|
static void transop_tick_speck(n2n_trans_op_t * arg, time_t now) { ; }
|
||||||
|
|
||||||
/* ****************************************************** */
|
/* ****************************************************** */
|
||||||
|
|
||||||
/* Speck initialization function */
|
/* Speck initialization function */
|
||||||
int n2n_transop_speck_init(const n2n_edge_conf_t *conf, n2n_trans_op_t *ttt) {
|
int n2n_transop_speck_init(const n2n_edge_conf_t *conf, n2n_trans_op_t *ttt) {
|
||||||
|
|
||||||
transop_speck_t *priv;
|
transop_speck_t *priv;
|
||||||
const u_char *encrypt_key = (const u_char *)conf->encrypt_key;
|
const u_char *encrypt_key = (const u_char *)conf->encrypt_key;
|
||||||
size_t encrypt_key_len = strlen(conf->encrypt_key);
|
size_t encrypt_key_len = strlen(conf->encrypt_key);
|
||||||
|
@ -188,17 +165,14 @@ int n2n_transop_speck_init(const n2n_edge_conf_t *conf, n2n_trans_op_t *ttt) {
|
||||||
ttt->deinit = transop_deinit_speck;
|
ttt->deinit = transop_deinit_speck;
|
||||||
ttt->fwd = transop_encode_speck;
|
ttt->fwd = transop_encode_speck;
|
||||||
ttt->rev = transop_decode_speck;
|
ttt->rev = transop_decode_speck;
|
||||||
#if defined (SPECK_ALIGNED_CTX)
|
|
||||||
priv = (transop_speck_t*) _mm_malloc (sizeof(transop_speck_t), SPECK_ALIGNED_CTX);
|
|
||||||
#else
|
|
||||||
priv = (transop_speck_t*) calloc(1, sizeof(transop_speck_t));
|
priv = (transop_speck_t*) calloc(1, sizeof(transop_speck_t));
|
||||||
#endif
|
|
||||||
if(!priv) {
|
if(!priv) {
|
||||||
traceEvent(TRACE_ERROR, "cannot allocate transop_speck_t memory");
|
traceEvent(TRACE_ERROR, "n2n_transop_speck_init cannot allocate transop_speck_t memory");
|
||||||
return(-1);
|
return(-1);
|
||||||
}
|
}
|
||||||
ttt->priv = priv;
|
ttt->priv = priv;
|
||||||
|
|
||||||
/* Setup the cipher and key */
|
/* Setup the cipher and key */
|
||||||
return(setup_speck_key(priv, encrypt_key, encrypt_key_len));
|
return setup_speck_key(priv, encrypt_key, encrypt_key_len);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user