Merge branch 'dev' into revCc20

This commit is contained in:
Logan oos Even 2020-09-01 20:16:32 +05:45 committed by GitHub
commit 90a071a1d3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 1139 additions and 325 deletions

View File

@ -4,7 +4,7 @@ include(CheckFunctionExists)
SET(CMAKE_VERBOSE_MAKEFILE ON) SET(CMAKE_VERBOSE_MAKEFILE ON)
# N2n release information # N2n release information
set(N2N_VERSION "2.7.0") set(N2N_VERSION "2.9.0")
set(N2N_OSNAME ${CMAKE_SYSTEM}) set(N2N_OSNAME ${CMAKE_SYSTEM})
execute_process( execute_process(
COMMAND git --version COMMAND git --version
@ -29,7 +29,7 @@ MESSAGE(STATUS "Build from git rev: ${N2N_VERSION}")
endif (GIT_EXIST) endif (GIT_EXIST)
add_definitions(-DCMAKE_BUILD) add_definitions(-DCMAKE_BUILD)
add_definitions(-DGIT_RELEASE="" -DPACKAGE_VERSION="${N2N_VERSION}" -DPACKAGE_OSNAME="${N2N_OSNAME}") add_definitions(-DGIT_RELEASE="${N2N_VERSION}" -DPACKAGE_VERSION="${N2N_VERSION}" -DPACKAGE_OSNAME="${N2N_OSNAME}")
add_definitions(-DN2N_VERSION="${N2N_VERSION}" -DN2N_OSNAME="${N2N_OSNAME}") add_definitions(-DN2N_VERSION="${N2N_VERSION}" -DN2N_OSNAME="${N2N_OSNAME}")

View File

@ -28,9 +28,9 @@ fi
AC_CHECK_LIB([crypto], [AES_cbc_encrypt]) AC_CHECK_LIB([crypto], [AES_cbc_encrypt])
if test "x$ac_cv_lib_crypto_AES_cbc_encrypt" != xyes; then if test "x$ac_cv_lib_crypto_AES_cbc_encrypt" != xyes; then
AC_MSG_RESULT(Building n2n without AES support) AC_MSG_RESULT(OpenSSL not present)
else else
AC_DEFINE([N2N_HAVE_AES], [], [Have AES support]) AC_DEFINE([HAVE_OPENSSL_1_0], [], [OpenSSL 1.0 is present])
N2N_LIBS="-lcrypto ${N2N_LIBS}" N2N_LIBS="-lcrypto ${N2N_LIBS}"
fi fi

View File

@ -17,7 +17,7 @@ The following chart might help to make a quick comparison and decide what cipher
| Cipher | Mode | Block Size | Key Size | IV length |Speed | Built-In | Origin | | Cipher | Mode | Block Size | Key Size | IV length |Speed | Built-In | Origin |
| :---: | :---:| :---: | :---: | :---: |:---: | :---: | --- | | :---: | :---:| :---: | :---: | :---: |:---: | :---: | --- |
|Twofish | CTS | 128 bits | 256 bit | 32 bit | - | Y | Bruce Schneier | |Twofish | CTS | 128 bits | 256 bit | 128 bit | -..O | Y | Bruce Schneier |
|AES | CBC | 128 bits | 128, 192, 256 bit| 128 bit | O..+ | N | Joan Daemen, Vincent Rijmen, NSA-approved | |AES | CBC | 128 bits | 128, 192, 256 bit| 128 bit | O..+ | N | Joan Daemen, Vincent Rijmen, NSA-approved |
|ChaCha20| CTR | Stream | 256 bit | 128 bit | +..++| N | Daniel J. Bernstein | |ChaCha20| CTR | Stream | 256 bit | 128 bit | +..++| N | Daniel J. Bernstein |
|SPECK | CTR | Stream | 256 bit | 128 bit | ++ | Y | NSA | |SPECK | CTR | Stream | 256 bit | 128 bit | ++ | Y | NSA |
@ -28,13 +28,11 @@ Note that AES and ChaCha20 are available only if n2n is compiled with openSSL su
### Twofish ### Twofish
This implementation prepends a 32 bit random value to the plain text. In the `src/transform_tf.c` file, it is called `nonce`. In CBC mode, this basically has the same effect as a respectively shorter IV. This implementation prepends a 128 bit random value to the plain text. Its size is adjustable by changing the `TF_PREAMBLE_SIZE` definition found in `src/transform_tf.c`. It defaults to TF_BLOCK_SIZE (== 16). As CTS uses underlying CBC mode, this basically has the same effect as a respectively shorter IV.
Twofish requires no padding as it employs a CBC/CTS scheme which can send out plaintext-length ciphertexts. The scheme however has a small flaw in handling messages shorter than one block, only low-level programmer might encounter this. Twofish requires no padding as it employs a CBC/CTS scheme which can send out plaintext-length ciphertexts. The scheme however has a small flaw in handling messages shorter than one block, only low-level programmer might encounter this.
Twofish is the slowest of the ciphers present. On Intel CPUs, Twofish usually is the slowest of the ciphers present. However, on Raspberry Pi 3B+, Twofish was observed to be faster than AES-CTS. Your mileage may vary. Cipher speed's can be compared running the `tools/n2n-benchmark` tool.
_We might try to find a faster implementation._
### AES ### AES
@ -42,8 +40,6 @@ AES also prepends a random value to the plaintext. Its size is adjustable by cha
AES relies on openSSL's `evp_*` interface which also offers hardware acceleration where available (SSE, AES-NI, …). It however is slower than the following stream ciphers because the CBC mode cannot compete with the optimized stream ciphers. AES relies on openSSL's `evp_*` interface which also offers hardware acceleration where available (SSE, AES-NI, …). It however is slower than the following stream ciphers because the CBC mode cannot compete with the optimized stream ciphers.
_Perhaps, AES-CTR being a stream cipher could have competed with the stream ciphers._
### ChaCha20 ### ChaCha20
ChaCha20 was the first stream cipher supported by n2n. ChaCha20 was the first stream cipher supported by n2n.
@ -52,13 +48,13 @@ It also relies on openSSL's `evp_*` interface. It does not use the Poly1305 mess
The random full 128-bit IV is transmitted in plain. The random full 128-bit IV is transmitted in plain.
ChaCha20 usually performs faster than AES-CBC. ChaCha20 usually performs faster than AES-CTS.
### SPECK ### SPECK
SPECK is recommended by the NSA for offical use in case AES implementation is not feasible due to system constraints (performance, size, …). The block cipher is used in CTR mode making it a stream cipher. The random full 128-bit IV is transmitted in plain. SPECK is recommended by the NSA for offical use in case AES implementation is not feasible due to system constraints (performance, size, …). The block cipher is used in CTR mode making it a stream cipher. The random full 128-bit IV is transmitted in plain.
On Intel CPUs, SPECK performs even faster than openSSL's ChaCha20 as it takes advantage of SSE4 or AVX2 if available (compile using `-march=native`). On Raspberry's ARM CPU, it is second place behind ChaCha20 and before AES-CBC. On Intel CPUs, SPECK performs even faster than openSSL's ChaCha20 as it takes advantage of SSE4 or AVX2 if available (compile using `-march=native`). On Raspberry's ARM CPU, it is second place behind ChaCha20 and before Twofish.
### Random Numbers ### Random Numbers

View File

@ -17,17 +17,17 @@
*/ */
#ifdef N2N_HAVE_AES #include "n2n.h" // HAVE_OPENSSL_1_1, HAVE_OPENSSL_1_0, traceEvent ...
#ifndef AES_H #ifndef AES_H
#define AES_H #define AES_H
#include <stdint.h> #include <stdint.h>
#include <stdlib.h>
#include <openssl/aes.h> #include "portable_endian.h"
#include <openssl/evp.h>
#include <openssl/err.h>
#define AES_BLOCK_SIZE 16 #define AES_BLOCK_SIZE 16
#define AES_IV_SIZE (AES_BLOCK_SIZE) #define AES_IV_SIZE (AES_BLOCK_SIZE)
@ -37,19 +37,39 @@
#define AES128_KEY_BYTES (128/8) #define AES128_KEY_BYTES (128/8)
#if defined (HAVE_OPENSSL_1_1) // openSSL 1.1 ---------------------------------------------
#include <openssl/aes.h>
#include <openssl/evp.h>
#include <openssl/err.h>
typedef struct aes_context_t { typedef struct aes_context_t {
#ifdef HAVE_OPENSSL_1_1
EVP_CIPHER_CTX *enc_ctx; /* openssl's reusable evp_* en/de-cryption context */ EVP_CIPHER_CTX *enc_ctx; /* openssl's reusable evp_* en/de-cryption context */
EVP_CIPHER_CTX *dec_ctx; /* openssl's reusable evp_* en/de-cryption context */ EVP_CIPHER_CTX *dec_ctx; /* openssl's reusable evp_* en/de-cryption context */
const EVP_CIPHER *cipher; /* cipher to use: e.g. EVP_aes_128_cbc */ const EVP_CIPHER *cipher; /* cipher to use: e.g. EVP_aes_128_cbc */
uint8_t key[AES256_KEY_BYTES]; /* the pure key data for payload encryption & decryption */ uint8_t key[AES256_KEY_BYTES]; /* the pure key data for payload encryption & decryption */
AES_KEY ecb_dec_key; /* one step ecb decryption key */ AES_KEY ecb_dec_key; /* one step ecb decryption key */
#else } aes_context_t;
#elif defined (HAVE_OPENSSL_1_0) // openSSL 1.0 -------------------------------------------
#include <openssl/aes.h>
typedef struct aes_context_t {
AES_KEY enc_key; /* tx key */ AES_KEY enc_key; /* tx key */
AES_KEY dec_key; /* tx key */ AES_KEY dec_key; /* tx key */
#endif
} aes_context_t; } aes_context_t;
#else // plain C --------------------------------------------------------------------------
typedef struct aes_context_t {
uint32_t enc_rk[60]; // round keys for encryption
uint32_t dec_rk[60]; // round keys for decryption
int Nr; // number of rounds
} aes_context_t;
#endif
int aes_cbc_encrypt (unsigned char *out, const unsigned char *in, size_t in_len, int aes_cbc_encrypt (unsigned char *out, const unsigned char *in, size_t in_len,
const unsigned char *iv, aes_context_t *ctx); const unsigned char *iv, aes_context_t *ctx);
@ -61,7 +81,7 @@ int aes_ecb_decrypt (unsigned char *out, const unsigned char *in, aes_context_t
int aes_init (const unsigned char *key, size_t key_size, aes_context_t **ctx); int aes_init (const unsigned char *key, size_t key_size, aes_context_t **ctx);
int aes_deinit (aes_context_t *ctx);
#endif // AES_H #endif // AES_H
#endif // N2N_HAVE_AES

View File

@ -83,14 +83,12 @@
#define N2N_CAN_NAME_IFACE 1 #define N2N_CAN_NAME_IFACE 1
#include <linux/netlink.h> #include <linux/netlink.h>
#include <linux/rtnetlink.h> #include <linux/rtnetlink.h>
#include <sys/syscall.h>
#include <unistd.h> #include <unistd.h>
#include <net/if_arp.h> #include <net/if_arp.h>
#include <net/if.h> #include <net/if.h>
#include <linux/if_tun.h> #include <linux/if_tun.h>
#include <linux/netlink.h> #include <linux/netlink.h>
#include <linux/rtnetlink.h> #include <linux/rtnetlink.h>
#define GRND_NONBLOCK 1
#endif /* #ifdef __linux__ */ #endif /* #ifdef __linux__ */
#ifdef __FreeBSD__ #ifdef __FreeBSD__
@ -100,10 +98,6 @@
#include <syslog.h> #include <syslog.h>
#include <sys/wait.h> #include <sys/wait.h>
#if defined (__RDRND__) || defined (__RDSEED__)
#include <immintrin.h>
#endif
#define ETH_ADDR_LEN 6 #define ETH_ADDR_LEN 6
struct ether_hdr struct ether_hdr
@ -130,12 +124,11 @@ typedef struct ether_hdr ether_hdr_t;
#include <assert.h> #include <assert.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <stdint.h> #include <stdint.h>
#ifdef N2N_HAVE_AES #if defined (HAVE_OPENSSL_1_0) || defined (HAVE_OPENSSL_1_1)
#include <openssl/opensslv.h> #include <openssl/opensslv.h>
#include <openssl/crypto.h> #include <openssl/crypto.h>
#endif #endif
#define closesocket(a) close(a) #define closesocket(a) close(a)
#endif /* #ifndef WIN32 */ #endif /* #ifndef WIN32 */
@ -422,9 +415,7 @@ typedef struct n2n_sn
/* Transop Init Functions */ /* Transop Init Functions */
int n2n_transop_null_init(const n2n_edge_conf_t *conf, n2n_trans_op_t *ttt); int n2n_transop_null_init(const n2n_edge_conf_t *conf, n2n_trans_op_t *ttt);
int n2n_transop_tf_init(const n2n_edge_conf_t *conf, n2n_trans_op_t *ttt); int n2n_transop_tf_init(const n2n_edge_conf_t *conf, n2n_trans_op_t *ttt);
#ifdef N2N_HAVE_AES int n2n_transop_aes_init(const n2n_edge_conf_t *conf, n2n_trans_op_t *ttt);
int n2n_transop_aes_cbc_init(const n2n_edge_conf_t *conf, n2n_trans_op_t *ttt);
#endif
int n2n_transop_cc20_init(const n2n_edge_conf_t *conf, n2n_trans_op_t *ttt); int n2n_transop_cc20_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); int n2n_transop_speck_init(const n2n_edge_conf_t *conf, n2n_trans_op_t *ttt);

View File

@ -51,9 +51,6 @@
#define TIME_STAMP_JITTER 0x0000000027100000LL /* we allow a packet to arrive 160 ms (== 0x27100 us) before another #define TIME_STAMP_JITTER 0x0000000027100000LL /* we allow a packet to arrive 160 ms (== 0x27100 us) before another
* set to 0x0000000000000000LL if increasing (or equal) time stamps allowed only */ * set to 0x0000000000000000LL if increasing (or equal) time stamps allowed only */
/* parameter for random number generation */
#define RND_RETRIES 1000 /* syscall and inquiring random number from hardware generators might fail, so we will retry */
/* N2N compression indicators. */ /* N2N compression indicators. */
/* Compression is disabled by default for outgoing packets if no cli /* Compression is disabled by default for outgoing packets if no cli
* option is given. All edges are built with decompression support so * option is given. All edges are built with decompression support so

View File

@ -29,7 +29,7 @@ typedef enum n2n_transform {
N2N_TRANSFORM_ID_INVAL = 0, N2N_TRANSFORM_ID_INVAL = 0,
N2N_TRANSFORM_ID_NULL = 1, N2N_TRANSFORM_ID_NULL = 1,
N2N_TRANSFORM_ID_TWOFISH = 2, N2N_TRANSFORM_ID_TWOFISH = 2,
N2N_TRANSFORM_ID_AESCBC = 3, N2N_TRANSFORM_ID_AES = 3,
N2N_TRANSFORM_ID_CHACHA20 = 4, N2N_TRANSFORM_ID_CHACHA20 = 4,
N2N_TRANSFORM_ID_SPECK = 5, N2N_TRANSFORM_ID_SPECK = 5,
} n2n_transform_t; } n2n_transform_t;

View File

@ -16,19 +16,46 @@
* *
*/ */
/* The WIN32 code is still untested and thus commented
#ifndef RND_H
#define RND_H
#include <stdint.h>
#include <stddef.h>
#include <time.h> // time, clock
#include "n2n.h" // traceEvent
// syscall and inquiring random number from hardware generators might fail, so we will retry
#define RND_RETRIES 1000
#if defined (__linux__)
#include <sys/syscall.h> // syscall, SYS_getrandom
#ifdef SYS_getrandom
#define GRND_NONBLOCK 1
#include <errno.h> // errno, EAGAIN
#endif
#endif
#if defined (__RDRND__) || defined (__RDSEED__)
#include <immintrin.h> // _rdrand64_step, rdseed4_step
#endif
/* The WIN32 code is still untested and thus commented, also see random_numbers.c
#if defined (WIN32) #if defined (WIN32)
#include <Wincrypt.h> #include <Wincrypt.h> // HCTYPTPROV, Crypt*-functions
#endif #endif
*/ */
struct rn_generator_state_t {
uint64_t a, b;
};
struct splitmix64_state_t { typedef struct rn_generator_state_t {
uint64_t a, b;
} rn_generator_state_t;
typedef struct splitmix64_state_t {
uint64_t s; uint64_t s;
}; } splitmix64_state_t;
int n2n_srand (uint64_t seed); int n2n_srand (uint64_t seed);
@ -36,3 +63,6 @@ int n2n_srand (uint64_t seed);
uint64_t n2n_rand (); uint64_t n2n_rand ();
uint64_t n2n_seed (); uint64_t n2n_seed ();
#endif // RND_H

View File

@ -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

View File

@ -53,6 +53,7 @@ THE SOFTWARE.
#include <stdint.h> #include <stdint.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include "portable_endian.h"
#define TF_BLOCK_SIZE 16 #define TF_BLOCK_SIZE 16
@ -78,5 +79,7 @@ int tf_cbc_decrypt (unsigned char *out, const unsigned char *in, size_t in_len,
int tf_init (const unsigned char *key, size_t key_size, tf_context_t **ctx); int tf_init (const unsigned char *key, size_t key_size, tf_context_t **ctx);
int tf_deinit (tf_context_t *ctx);
#endif // TF_H #endif // TF_H

883
src/aes.c
View File

@ -17,13 +17,12 @@
*/ */
#include "n2n.h" #include "aes.h"
#ifdef N2N_HAVE_AES
/* ****************************************************** */ #if defined (HAVE_OPENSSL_1_1) // openSSL 1.1 ---------------------------------------------
#ifdef HAVE_OPENSSL_1_1
// get any erorr message out of openssl // get any erorr message out of openssl
// taken from https://en.wikibooks.org/wiki/OpenSSL/Error_handling // taken from https://en.wikibooks.org/wiki/OpenSSL/Error_handling
static char *openssl_err_as_string (void) { static char *openssl_err_as_string (void) {
@ -40,14 +39,11 @@ static char *openssl_err_as_string (void) {
BIO_free (bio); BIO_free (bio);
return ret; return ret;
} }
#endif
/* ****************************************************** */
int aes_cbc_encrypt (unsigned char *out, const unsigned char *in, size_t in_len, int aes_cbc_encrypt (unsigned char *out, const unsigned char *in, size_t in_len,
const unsigned char *iv, aes_context_t *ctx) { const unsigned char *iv, aes_context_t *ctx) {
#ifdef HAVE_OPENSSL_1_1
int evp_len; int evp_len;
int evp_ciphertext_len; int evp_ciphertext_len;
@ -74,26 +70,14 @@ int aes_cbc_encrypt (unsigned char *out, const unsigned char *in, size_t in_len,
openssl_err_as_string()); openssl_err_as_string());
EVP_CIPHER_CTX_reset(ctx->enc_ctx); EVP_CIPHER_CTX_reset(ctx->enc_ctx);
#else
uint8_t tmp_iv[AES_IV_SIZE];
memcpy (tmp_iv, iv, AES_IV_SIZE);
AES_cbc_encrypt(in, // source
out, // destination
in_len, // enc size
&(ctx->enc_key),
tmp_iv,
AES_ENCRYPT);
#endif
return(0); return 0;
} }
/* ****************************************************** */
int aes_cbc_decrypt (unsigned char *out, const unsigned char *in, size_t in_len, int aes_cbc_decrypt (unsigned char *out, const unsigned char *in, size_t in_len,
const unsigned char *iv, aes_context_t *ctx) { const unsigned char *iv, aes_context_t *ctx) {
#ifdef HAVE_OPENSSL_1_1
int evp_len; int evp_len;
int evp_plaintext_len; int evp_plaintext_len;
@ -120,7 +104,85 @@ int aes_cbc_decrypt (unsigned char *out, const unsigned char *in, size_t in_len,
openssl_err_as_string()); openssl_err_as_string());
EVP_CIPHER_CTX_reset(ctx->dec_ctx); EVP_CIPHER_CTX_reset(ctx->dec_ctx);
#else
return 0;
}
int aes_ecb_decrypt (unsigned char *out, const unsigned char *in, aes_context_t *ctx) {
AES_ecb_encrypt(in, out, &(ctx->ecb_dec_key), AES_DECRYPT);
return 0;
}
int aes_init (const unsigned char *key, size_t key_size, aes_context_t **ctx) {
// allocate context...
*ctx = (aes_context_t*) calloc(1, sizeof(aes_context_t));
if (!(*ctx))
return -1;
// ...and fill her up
// initialize data structures
if(!((*ctx)->enc_ctx = EVP_CIPHER_CTX_new())) {
traceEvent(TRACE_ERROR, "aes_init openssl's evp_* encryption context creation failed: %s",
openssl_err_as_string());
return -1;
}
if(!((*ctx)->dec_ctx = EVP_CIPHER_CTX_new())) {
traceEvent(TRACE_ERROR, "aes_init openssl's evp_* decryption context creation failed: %s",
openssl_err_as_string());
return -1;
}
// check key size and make key size (given in bytes) dependant settings
switch(key_size) {
case AES128_KEY_BYTES: // 128 bit key size
(*ctx)->cipher = EVP_aes_128_cbc();
break;
case AES192_KEY_BYTES: // 192 bit key size
(*ctx)->cipher = EVP_aes_192_cbc();
break;
case AES256_KEY_BYTES: // 256 bit key size
(*ctx)->cipher = EVP_aes_256_cbc();
break;
default:
traceEvent(TRACE_ERROR, "aes_init invalid key size %u\n", key_size);
return -1;
}
// key materiel handling
memcpy((*ctx)->key, key, key_size);
AES_set_decrypt_key(key, key_size * 8, &((*ctx)->ecb_dec_key));
return 0;
}
#elif defined (HAVE_OPENSSL_1_0) // openSSL 1.0 -------------------------------------------
int aes_cbc_encrypt (unsigned char *out, const unsigned char *in, size_t in_len,
const unsigned char *iv, aes_context_t *ctx) {
uint8_t tmp_iv[AES_IV_SIZE];
memcpy (tmp_iv, iv, AES_IV_SIZE);
AES_cbc_encrypt(in, // source
out, // destination
in_len, // enc size
&(ctx->enc_key),
tmp_iv,
AES_ENCRYPT);
return 0;
}
int aes_cbc_decrypt (unsigned char *out, const unsigned char *in, size_t in_len,
const unsigned char *iv, aes_context_t *ctx) {
uint8_t tmp_iv[AES_IV_SIZE]; uint8_t tmp_iv[AES_IV_SIZE];
memcpy (tmp_iv, iv, AES_IV_SIZE); memcpy (tmp_iv, iv, AES_IV_SIZE);
AES_cbc_encrypt(in, // source AES_cbc_encrypt(in, // source
@ -129,25 +191,18 @@ int aes_cbc_decrypt (unsigned char *out, const unsigned char *in, size_t in_len,
&(ctx->dec_key), &(ctx->dec_key),
tmp_iv, tmp_iv,
AES_DECRYPT); AES_DECRYPT);
#endif
return 0; return 0;
} }
/* ****************************************************** */
int aes_ecb_decrypt (unsigned char *out, const unsigned char *in, aes_context_t *ctx) { int aes_ecb_decrypt (unsigned char *out, const unsigned char *in, aes_context_t *ctx) {
#ifdef HAVE_OPENSSL_1_1
AES_ecb_encrypt(in, out, &(ctx->ecb_dec_key), AES_DECRYPT);
#else
AES_ecb_encrypt(in, out, &(ctx->dec_key), AES_DECRYPT); AES_ecb_encrypt(in, out, &(ctx->dec_key), AES_DECRYPT);
#endif
return(0); return 0;
} }
/* ****************************************************** */
int aes_init (const unsigned char *key, size_t key_size, aes_context_t **ctx) { int aes_init (const unsigned char *key, size_t key_size, aes_context_t **ctx) {
@ -158,6 +213,746 @@ int aes_init (const unsigned char *key, size_t key_size, aes_context_t **ctx) {
// ...and fill her up // ...and fill her up
// initialize data structures // initialize data structures
// check key size and make key size (given in bytes) dependant settings
switch(key_size) {
case AES128_KEY_BYTES: // 128 bit key size
break;
case AES192_KEY_BYTES: // 192 bit key size
break;
case AES256_KEY_BYTES: // 256 bit key size
break;
default:
traceEvent(TRACE_ERROR, "aes_init invalid key size %u\n", key_size);
return -1;
}
// key materiel handling
AES_set_encrypt_key(key, key_size * 8, &((*ctx)->enc_key));
AES_set_decrypt_key(key, key_size * 8, &((*ctx)->dec_key));
return 0;
}
#else // plain C --------------------------------------------------------------------------
// rijndael-alg-fst.c version 3.0 (December 2000)
// optimised ANSI C code for the Rijndael cipher (now AES)
// original authors: Vincent Rijmen <vincent.rijmen@esat.kuleuven.ac.be>
// Antoon Bosselaers <antoon.bosselaers@esat.kuleuven.ac.be>
// Paulo Barreto <paulo.barreto@terra.com.br>
//
// was put in the public domain, taken (and modified) from
// https://fastcrypto.org/front/misc/rijndael-alg-fst.c
// Te0[x] = S [x].[02, 01, 01, 03];
static const uint32_t Te0[256] = {
0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU, 0xfff2f20dU, 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U,
0x60303050U, 0x02010103U, 0xce6767a9U, 0x562b2b7dU, 0xe7fefe19U, 0xb5d7d762U, 0x4dababe6U, 0xec76769aU,
0x8fcaca45U, 0x1f82829dU, 0x89c9c940U, 0xfa7d7d87U, 0xeffafa15U, 0xb25959ebU, 0x8e4747c9U, 0xfbf0f00bU,
0x41adadecU, 0xb3d4d467U, 0x5fa2a2fdU, 0x45afafeaU, 0x239c9cbfU, 0x53a4a4f7U, 0xe4727296U, 0x9bc0c05bU,
0x75b7b7c2U, 0xe1fdfd1cU, 0x3d9393aeU, 0x4c26266aU, 0x6c36365aU, 0x7e3f3f41U, 0xf5f7f702U, 0x83cccc4fU,
0x6834345cU, 0x51a5a5f4U, 0xd1e5e534U, 0xf9f1f108U, 0xe2717193U, 0xabd8d873U, 0x62313153U, 0x2a15153fU,
0x0804040cU, 0x95c7c752U, 0x46232365U, 0x9dc3c35eU, 0x30181828U, 0x379696a1U, 0x0a05050fU, 0x2f9a9ab5U,
0x0e070709U, 0x24121236U, 0x1b80809bU, 0xdfe2e23dU, 0xcdebeb26U, 0x4e272769U, 0x7fb2b2cdU, 0xea75759fU,
0x1209091bU, 0x1d83839eU, 0x582c2c74U, 0x341a1a2eU, 0x361b1b2dU, 0xdc6e6eb2U, 0xb45a5aeeU, 0x5ba0a0fbU,
0xa45252f6U, 0x763b3b4dU, 0xb7d6d661U, 0x7db3b3ceU, 0x5229297bU, 0xdde3e33eU, 0x5e2f2f71U, 0x13848497U,
0xa65353f5U, 0xb9d1d168U, 0x00000000U, 0xc1eded2cU, 0x40202060U, 0xe3fcfc1fU, 0x79b1b1c8U, 0xb65b5bedU,
0xd46a6abeU, 0x8dcbcb46U, 0x67bebed9U, 0x7239394bU, 0x944a4adeU, 0x984c4cd4U, 0xb05858e8U, 0x85cfcf4aU,
0xbbd0d06bU, 0xc5efef2aU, 0x4faaaae5U, 0xedfbfb16U, 0x864343c5U, 0x9a4d4dd7U, 0x66333355U, 0x11858594U,
0x8a4545cfU, 0xe9f9f910U, 0x04020206U, 0xfe7f7f81U, 0xa05050f0U, 0x783c3c44U, 0x259f9fbaU, 0x4ba8a8e3U,
0xa25151f3U, 0x5da3a3feU, 0x804040c0U, 0x058f8f8aU, 0x3f9292adU, 0x219d9dbcU, 0x70383848U, 0xf1f5f504U,
0x63bcbcdfU, 0x77b6b6c1U, 0xafdada75U, 0x42212163U, 0x20101030U, 0xe5ffff1aU, 0xfdf3f30eU, 0xbfd2d26dU,
0x81cdcd4cU, 0x180c0c14U, 0x26131335U, 0xc3ecec2fU, 0xbe5f5fe1U, 0x359797a2U, 0x884444ccU, 0x2e171739U,
0x93c4c457U, 0x55a7a7f2U, 0xfc7e7e82U, 0x7a3d3d47U, 0xc86464acU, 0xba5d5de7U, 0x3219192bU, 0xe6737395U,
0xc06060a0U, 0x19818198U, 0x9e4f4fd1U, 0xa3dcdc7fU, 0x44222266U, 0x542a2a7eU, 0x3b9090abU, 0x0b888883U,
0x8c4646caU, 0xc7eeee29U, 0x6bb8b8d3U, 0x2814143cU, 0xa7dede79U, 0xbc5e5ee2U, 0x160b0b1dU, 0xaddbdb76U,
0xdbe0e03bU, 0x64323256U, 0x743a3a4eU, 0x140a0a1eU, 0x924949dbU, 0x0c06060aU, 0x4824246cU, 0xb85c5ce4U,
0x9fc2c25dU, 0xbdd3d36eU, 0x43acacefU, 0xc46262a6U, 0x399191a8U, 0x319595a4U, 0xd3e4e437U, 0xf279798bU,
0xd5e7e732U, 0x8bc8c843U, 0x6e373759U, 0xda6d6db7U, 0x018d8d8cU, 0xb1d5d564U, 0x9c4e4ed2U, 0x49a9a9e0U,
0xd86c6cb4U, 0xac5656faU, 0xf3f4f407U, 0xcfeaea25U, 0xca6565afU, 0xf47a7a8eU, 0x47aeaee9U, 0x10080818U,
0x6fbabad5U, 0xf0787888U, 0x4a25256fU, 0x5c2e2e72U, 0x381c1c24U, 0x57a6a6f1U, 0x73b4b4c7U, 0x97c6c651U,
0xcbe8e823U, 0xa1dddd7cU, 0xe874749cU, 0x3e1f1f21U, 0x964b4bddU, 0x61bdbddcU, 0x0d8b8b86U, 0x0f8a8a85U,
0xe0707090U, 0x7c3e3e42U, 0x71b5b5c4U, 0xcc6666aaU, 0x904848d8U, 0x06030305U, 0xf7f6f601U, 0x1c0e0e12U,
0xc26161a3U, 0x6a35355fU, 0xae5757f9U, 0x69b9b9d0U, 0x17868691U, 0x99c1c158U, 0x3a1d1d27U, 0x279e9eb9U,
0xd9e1e138U, 0xebf8f813U, 0x2b9898b3U, 0x22111133U, 0xd26969bbU, 0xa9d9d970U, 0x078e8e89U, 0x339494a7U,
0x2d9b9bb6U, 0x3c1e1e22U, 0x15878792U, 0xc9e9e920U, 0x87cece49U, 0xaa5555ffU, 0x50282878U, 0xa5dfdf7aU,
0x038c8c8fU, 0x59a1a1f8U, 0x09898980U, 0x1a0d0d17U, 0x65bfbfdaU, 0xd7e6e631U, 0x844242c6U, 0xd06868b8U,
0x824141c3U, 0x299999b0U, 0x5a2d2d77U, 0x1e0f0f11U, 0x7bb0b0cbU, 0xa85454fcU, 0x6dbbbbd6U, 0x2c16163aU };
// Te1[x] = S [x].[03, 02, 01, 01];
static const uint32_t Te1[256] = {
0xa5c66363U, 0x84f87c7cU, 0x99ee7777U, 0x8df67b7bU, 0x0dfff2f2U, 0xbdd66b6bU, 0xb1de6f6fU, 0x5491c5c5U,
0x50603030U, 0x03020101U, 0xa9ce6767U, 0x7d562b2bU, 0x19e7fefeU, 0x62b5d7d7U, 0xe64dababU, 0x9aec7676U,
0x458fcacaU, 0x9d1f8282U, 0x4089c9c9U, 0x87fa7d7dU, 0x15effafaU, 0xebb25959U, 0xc98e4747U, 0x0bfbf0f0U,
0xec41adadU, 0x67b3d4d4U, 0xfd5fa2a2U, 0xea45afafU, 0xbf239c9cU, 0xf753a4a4U, 0x96e47272U, 0x5b9bc0c0U,
0xc275b7b7U, 0x1ce1fdfdU, 0xae3d9393U, 0x6a4c2626U, 0x5a6c3636U, 0x417e3f3fU, 0x02f5f7f7U, 0x4f83ccccU,
0x5c683434U, 0xf451a5a5U, 0x34d1e5e5U, 0x08f9f1f1U, 0x93e27171U, 0x73abd8d8U, 0x53623131U, 0x3f2a1515U,
0x0c080404U, 0x5295c7c7U, 0x65462323U, 0x5e9dc3c3U, 0x28301818U, 0xa1379696U, 0x0f0a0505U, 0xb52f9a9aU,
0x090e0707U, 0x36241212U, 0x9b1b8080U, 0x3ddfe2e2U, 0x26cdebebU, 0x694e2727U, 0xcd7fb2b2U, 0x9fea7575U,
0x1b120909U, 0x9e1d8383U, 0x74582c2cU, 0x2e341a1aU, 0x2d361b1bU, 0xb2dc6e6eU, 0xeeb45a5aU, 0xfb5ba0a0U,
0xf6a45252U, 0x4d763b3bU, 0x61b7d6d6U, 0xce7db3b3U, 0x7b522929U, 0x3edde3e3U, 0x715e2f2fU, 0x97138484U,
0xf5a65353U, 0x68b9d1d1U, 0x00000000U, 0x2cc1ededU, 0x60402020U, 0x1fe3fcfcU, 0xc879b1b1U, 0xedb65b5bU,
0xbed46a6aU, 0x468dcbcbU, 0xd967bebeU, 0x4b723939U, 0xde944a4aU, 0xd4984c4cU, 0xe8b05858U, 0x4a85cfcfU,
0x6bbbd0d0U, 0x2ac5efefU, 0xe54faaaaU, 0x16edfbfbU, 0xc5864343U, 0xd79a4d4dU, 0x55663333U, 0x94118585U,
0xcf8a4545U, 0x10e9f9f9U, 0x06040202U, 0x81fe7f7fU, 0xf0a05050U, 0x44783c3cU, 0xba259f9fU, 0xe34ba8a8U,
0xf3a25151U, 0xfe5da3a3U, 0xc0804040U, 0x8a058f8fU, 0xad3f9292U, 0xbc219d9dU, 0x48703838U, 0x04f1f5f5U,
0xdf63bcbcU, 0xc177b6b6U, 0x75afdadaU, 0x63422121U, 0x30201010U, 0x1ae5ffffU, 0x0efdf3f3U, 0x6dbfd2d2U,
0x4c81cdcdU, 0x14180c0cU, 0x35261313U, 0x2fc3ececU, 0xe1be5f5fU, 0xa2359797U, 0xcc884444U, 0x392e1717U,
0x5793c4c4U, 0xf255a7a7U, 0x82fc7e7eU, 0x477a3d3dU, 0xacc86464U, 0xe7ba5d5dU, 0x2b321919U, 0x95e67373U,
0xa0c06060U, 0x98198181U, 0xd19e4f4fU, 0x7fa3dcdcU, 0x66442222U, 0x7e542a2aU, 0xab3b9090U, 0x830b8888U,
0xca8c4646U, 0x29c7eeeeU, 0xd36bb8b8U, 0x3c281414U, 0x79a7dedeU, 0xe2bc5e5eU, 0x1d160b0bU, 0x76addbdbU,
0x3bdbe0e0U, 0x56643232U, 0x4e743a3aU, 0x1e140a0aU, 0xdb924949U, 0x0a0c0606U, 0x6c482424U, 0xe4b85c5cU,
0x5d9fc2c2U, 0x6ebdd3d3U, 0xef43acacU, 0xa6c46262U, 0xa8399191U, 0xa4319595U, 0x37d3e4e4U, 0x8bf27979U,
0x32d5e7e7U, 0x438bc8c8U, 0x596e3737U, 0xb7da6d6dU, 0x8c018d8dU, 0x64b1d5d5U, 0xd29c4e4eU, 0xe049a9a9U,
0xb4d86c6cU, 0xfaac5656U, 0x07f3f4f4U, 0x25cfeaeaU, 0xafca6565U, 0x8ef47a7aU, 0xe947aeaeU, 0x18100808U,
0xd56fbabaU, 0x88f07878U, 0x6f4a2525U, 0x725c2e2eU, 0x24381c1cU, 0xf157a6a6U, 0xc773b4b4U, 0x5197c6c6U,
0x23cbe8e8U, 0x7ca1ddddU, 0x9ce87474U, 0x213e1f1fU, 0xdd964b4bU, 0xdc61bdbdU, 0x860d8b8bU, 0x850f8a8aU,
0x90e07070U, 0x427c3e3eU, 0xc471b5b5U, 0xaacc6666U, 0xd8904848U, 0x05060303U, 0x01f7f6f6U, 0x121c0e0eU,
0xa3c26161U, 0x5f6a3535U, 0xf9ae5757U, 0xd069b9b9U, 0x91178686U, 0x5899c1c1U, 0x273a1d1dU, 0xb9279e9eU,
0x38d9e1e1U, 0x13ebf8f8U, 0xb32b9898U, 0x33221111U, 0xbbd26969U, 0x70a9d9d9U, 0x89078e8eU, 0xa7339494U,
0xb62d9b9bU, 0x223c1e1eU, 0x92158787U, 0x20c9e9e9U, 0x4987ceceU, 0xffaa5555U, 0x78502828U, 0x7aa5dfdfU,
0x8f038c8cU, 0xf859a1a1U, 0x80098989U, 0x171a0d0dU, 0xda65bfbfU, 0x31d7e6e6U, 0xc6844242U, 0xb8d06868U,
0xc3824141U, 0xb0299999U, 0x775a2d2dU, 0x111e0f0fU, 0xcb7bb0b0U, 0xfca85454U, 0xd66dbbbbU, 0x3a2c1616U };
// Te2[x] = S [x].[01, 03, 02, 01];
static const uint32_t Te2[256] = {
0x63a5c663U, 0x7c84f87cU, 0x7799ee77U, 0x7b8df67bU, 0xf20dfff2U, 0x6bbdd66bU, 0x6fb1de6fU, 0xc55491c5U,
0x30506030U, 0x01030201U, 0x67a9ce67U, 0x2b7d562bU, 0xfe19e7feU, 0xd762b5d7U, 0xabe64dabU, 0x769aec76U,
0xca458fcaU, 0x829d1f82U, 0xc94089c9U, 0x7d87fa7dU, 0xfa15effaU, 0x59ebb259U, 0x47c98e47U, 0xf00bfbf0U,
0xadec41adU, 0xd467b3d4U, 0xa2fd5fa2U, 0xafea45afU, 0x9cbf239cU, 0xa4f753a4U, 0x7296e472U, 0xc05b9bc0U,
0xb7c275b7U, 0xfd1ce1fdU, 0x93ae3d93U, 0x266a4c26U, 0x365a6c36U, 0x3f417e3fU, 0xf702f5f7U, 0xcc4f83ccU,
0x345c6834U, 0xa5f451a5U, 0xe534d1e5U, 0xf108f9f1U, 0x7193e271U, 0xd873abd8U, 0x31536231U, 0x153f2a15U,
0x040c0804U, 0xc75295c7U, 0x23654623U, 0xc35e9dc3U, 0x18283018U, 0x96a13796U, 0x050f0a05U, 0x9ab52f9aU,
0x07090e07U, 0x12362412U, 0x809b1b80U, 0xe23ddfe2U, 0xeb26cdebU, 0x27694e27U, 0xb2cd7fb2U, 0x759fea75U,
0x091b1209U, 0x839e1d83U, 0x2c74582cU, 0x1a2e341aU, 0x1b2d361bU, 0x6eb2dc6eU, 0x5aeeb45aU, 0xa0fb5ba0U,
0x52f6a452U, 0x3b4d763bU, 0xd661b7d6U, 0xb3ce7db3U, 0x297b5229U, 0xe33edde3U, 0x2f715e2fU, 0x84971384U,
0x53f5a653U, 0xd168b9d1U, 0x00000000U, 0xed2cc1edU, 0x20604020U, 0xfc1fe3fcU, 0xb1c879b1U, 0x5bedb65bU,
0x6abed46aU, 0xcb468dcbU, 0xbed967beU, 0x394b7239U, 0x4ade944aU, 0x4cd4984cU, 0x58e8b058U, 0xcf4a85cfU,
0xd06bbbd0U, 0xef2ac5efU, 0xaae54faaU, 0xfb16edfbU, 0x43c58643U, 0x4dd79a4dU, 0x33556633U, 0x85941185U,
0x45cf8a45U, 0xf910e9f9U, 0x02060402U, 0x7f81fe7fU, 0x50f0a050U, 0x3c44783cU, 0x9fba259fU, 0xa8e34ba8U,
0x51f3a251U, 0xa3fe5da3U, 0x40c08040U, 0x8f8a058fU, 0x92ad3f92U, 0x9dbc219dU, 0x38487038U, 0xf504f1f5U,
0xbcdf63bcU, 0xb6c177b6U, 0xda75afdaU, 0x21634221U, 0x10302010U, 0xff1ae5ffU, 0xf30efdf3U, 0xd26dbfd2U,
0xcd4c81cdU, 0x0c14180cU, 0x13352613U, 0xec2fc3ecU, 0x5fe1be5fU, 0x97a23597U, 0x44cc8844U, 0x17392e17U,
0xc45793c4U, 0xa7f255a7U, 0x7e82fc7eU, 0x3d477a3dU, 0x64acc864U, 0x5de7ba5dU, 0x192b3219U, 0x7395e673U,
0x60a0c060U, 0x81981981U, 0x4fd19e4fU, 0xdc7fa3dcU, 0x22664422U, 0x2a7e542aU, 0x90ab3b90U, 0x88830b88U,
0x46ca8c46U, 0xee29c7eeU, 0xb8d36bb8U, 0x143c2814U, 0xde79a7deU, 0x5ee2bc5eU, 0x0b1d160bU, 0xdb76addbU,
0xe03bdbe0U, 0x32566432U, 0x3a4e743aU, 0x0a1e140aU, 0x49db9249U, 0x060a0c06U, 0x246c4824U, 0x5ce4b85cU,
0xc25d9fc2U, 0xd36ebdd3U, 0xacef43acU, 0x62a6c462U, 0x91a83991U, 0x95a43195U, 0xe437d3e4U, 0x798bf279U,
0xe732d5e7U, 0xc8438bc8U, 0x37596e37U, 0x6db7da6dU, 0x8d8c018dU, 0xd564b1d5U, 0x4ed29c4eU, 0xa9e049a9U,
0x6cb4d86cU, 0x56faac56U, 0xf407f3f4U, 0xea25cfeaU, 0x65afca65U, 0x7a8ef47aU, 0xaee947aeU, 0x08181008U,
0xbad56fbaU, 0x7888f078U, 0x256f4a25U, 0x2e725c2eU, 0x1c24381cU, 0xa6f157a6U, 0xb4c773b4U, 0xc65197c6U,
0xe823cbe8U, 0xdd7ca1ddU, 0x749ce874U, 0x1f213e1fU, 0x4bdd964bU, 0xbddc61bdU, 0x8b860d8bU, 0x8a850f8aU,
0x7090e070U, 0x3e427c3eU, 0xb5c471b5U, 0x66aacc66U, 0x48d89048U, 0x03050603U, 0xf601f7f6U, 0x0e121c0eU,
0x61a3c261U, 0x355f6a35U, 0x57f9ae57U, 0xb9d069b9U, 0x86911786U, 0xc15899c1U, 0x1d273a1dU, 0x9eb9279eU,
0xe138d9e1U, 0xf813ebf8U, 0x98b32b98U, 0x11332211U, 0x69bbd269U, 0xd970a9d9U, 0x8e89078eU, 0x94a73394U,
0x9bb62d9bU, 0x1e223c1eU, 0x87921587U, 0xe920c9e9U, 0xce4987ceU, 0x55ffaa55U, 0x28785028U, 0xdf7aa5dfU,
0x8c8f038cU, 0xa1f859a1U, 0x89800989U, 0x0d171a0dU, 0xbfda65bfU, 0xe631d7e6U, 0x42c68442U, 0x68b8d068U,
0x41c38241U, 0x99b02999U, 0x2d775a2dU, 0x0f111e0fU, 0xb0cb7bb0U, 0x54fca854U, 0xbbd66dbbU, 0x163a2c16U };
// Te3[x] = S [x].[01, 01, 03, 02];
static const uint32_t Te3[256] = {
0x6363a5c6U, 0x7c7c84f8U, 0x777799eeU, 0x7b7b8df6U, 0xf2f20dffU, 0x6b6bbdd6U, 0x6f6fb1deU, 0xc5c55491U,
0x30305060U, 0x01010302U, 0x6767a9ceU, 0x2b2b7d56U, 0xfefe19e7U, 0xd7d762b5U, 0xababe64dU, 0x76769aecU,
0xcaca458fU, 0x82829d1fU, 0xc9c94089U, 0x7d7d87faU, 0xfafa15efU, 0x5959ebb2U, 0x4747c98eU, 0xf0f00bfbU,
0xadadec41U, 0xd4d467b3U, 0xa2a2fd5fU, 0xafafea45U, 0x9c9cbf23U, 0xa4a4f753U, 0x727296e4U, 0xc0c05b9bU,
0xb7b7c275U, 0xfdfd1ce1U, 0x9393ae3dU, 0x26266a4cU, 0x36365a6cU, 0x3f3f417eU, 0xf7f702f5U, 0xcccc4f83U,
0x34345c68U, 0xa5a5f451U, 0xe5e534d1U, 0xf1f108f9U, 0x717193e2U, 0xd8d873abU, 0x31315362U, 0x15153f2aU,
0x04040c08U, 0xc7c75295U, 0x23236546U, 0xc3c35e9dU, 0x18182830U, 0x9696a137U, 0x05050f0aU, 0x9a9ab52fU,
0x0707090eU, 0x12123624U, 0x80809b1bU, 0xe2e23ddfU, 0xebeb26cdU, 0x2727694eU, 0xb2b2cd7fU, 0x75759feaU,
0x09091b12U, 0x83839e1dU, 0x2c2c7458U, 0x1a1a2e34U, 0x1b1b2d36U, 0x6e6eb2dcU, 0x5a5aeeb4U, 0xa0a0fb5bU,
0x5252f6a4U, 0x3b3b4d76U, 0xd6d661b7U, 0xb3b3ce7dU, 0x29297b52U, 0xe3e33eddU, 0x2f2f715eU, 0x84849713U,
0x5353f5a6U, 0xd1d168b9U, 0x00000000U, 0xeded2cc1U, 0x20206040U, 0xfcfc1fe3U, 0xb1b1c879U, 0x5b5bedb6U,
0x6a6abed4U, 0xcbcb468dU, 0xbebed967U, 0x39394b72U, 0x4a4ade94U, 0x4c4cd498U, 0x5858e8b0U, 0xcfcf4a85U,
0xd0d06bbbU, 0xefef2ac5U, 0xaaaae54fU, 0xfbfb16edU, 0x4343c586U, 0x4d4dd79aU, 0x33335566U, 0x85859411U,
0x4545cf8aU, 0xf9f910e9U, 0x02020604U, 0x7f7f81feU, 0x5050f0a0U, 0x3c3c4478U, 0x9f9fba25U, 0xa8a8e34bU,
0x5151f3a2U, 0xa3a3fe5dU, 0x4040c080U, 0x8f8f8a05U, 0x9292ad3fU, 0x9d9dbc21U, 0x38384870U, 0xf5f504f1U,
0xbcbcdf63U, 0xb6b6c177U, 0xdada75afU, 0x21216342U, 0x10103020U, 0xffff1ae5U, 0xf3f30efdU, 0xd2d26dbfU,
0xcdcd4c81U, 0x0c0c1418U, 0x13133526U, 0xecec2fc3U, 0x5f5fe1beU, 0x9797a235U, 0x4444cc88U, 0x1717392eU,
0xc4c45793U, 0xa7a7f255U, 0x7e7e82fcU, 0x3d3d477aU, 0x6464acc8U, 0x5d5de7baU, 0x19192b32U, 0x737395e6U,
0x6060a0c0U, 0x81819819U, 0x4f4fd19eU, 0xdcdc7fa3U, 0x22226644U, 0x2a2a7e54U, 0x9090ab3bU, 0x8888830bU,
0x4646ca8cU, 0xeeee29c7U, 0xb8b8d36bU, 0x14143c28U, 0xdede79a7U, 0x5e5ee2bcU, 0x0b0b1d16U, 0xdbdb76adU,
0xe0e03bdbU, 0x32325664U, 0x3a3a4e74U, 0x0a0a1e14U, 0x4949db92U, 0x06060a0cU, 0x24246c48U, 0x5c5ce4b8U,
0xc2c25d9fU, 0xd3d36ebdU, 0xacacef43U, 0x6262a6c4U, 0x9191a839U, 0x9595a431U, 0xe4e437d3U, 0x79798bf2U,
0xe7e732d5U, 0xc8c8438bU, 0x3737596eU, 0x6d6db7daU, 0x8d8d8c01U, 0xd5d564b1U, 0x4e4ed29cU, 0xa9a9e049U,
0x6c6cb4d8U, 0x5656faacU, 0xf4f407f3U, 0xeaea25cfU, 0x6565afcaU, 0x7a7a8ef4U, 0xaeaee947U, 0x08081810U,
0xbabad56fU, 0x787888f0U, 0x25256f4aU, 0x2e2e725cU, 0x1c1c2438U, 0xa6a6f157U, 0xb4b4c773U, 0xc6c65197U,
0xe8e823cbU, 0xdddd7ca1U, 0x74749ce8U, 0x1f1f213eU, 0x4b4bdd96U, 0xbdbddc61U, 0x8b8b860dU, 0x8a8a850fU,
0x707090e0U, 0x3e3e427cU, 0xb5b5c471U, 0x6666aaccU, 0x4848d890U, 0x03030506U, 0xf6f601f7U, 0x0e0e121cU,
0x6161a3c2U, 0x35355f6aU, 0x5757f9aeU, 0xb9b9d069U, 0x86869117U, 0xc1c15899U, 0x1d1d273aU, 0x9e9eb927U,
0xe1e138d9U, 0xf8f813ebU, 0x9898b32bU, 0x11113322U, 0x6969bbd2U, 0xd9d970a9U, 0x8e8e8907U, 0x9494a733U,
0x9b9bb62dU, 0x1e1e223cU, 0x87879215U, 0xe9e920c9U, 0xcece4987U, 0x5555ffaaU, 0x28287850U, 0xdfdf7aa5U,
0x8c8c8f03U, 0xa1a1f859U, 0x89898009U, 0x0d0d171aU, 0xbfbfda65U, 0xe6e631d7U, 0x4242c684U, 0x6868b8d0U,
0x4141c382U, 0x9999b029U, 0x2d2d775aU, 0x0f0f111eU, 0xb0b0cb7bU, 0x5454fca8U, 0xbbbbd66dU, 0x16163a2cU };
// Te4[x] = S [x].[01, 01, 01, 01];
static const uint32_t Te4[256] = {
0x63636363U, 0x7c7c7c7cU, 0x77777777U, 0x7b7b7b7bU, 0xf2f2f2f2U, 0x6b6b6b6bU, 0x6f6f6f6fU, 0xc5c5c5c5U,
0x30303030U, 0x01010101U, 0x67676767U, 0x2b2b2b2bU, 0xfefefefeU, 0xd7d7d7d7U, 0xababababU, 0x76767676U,
0xcacacacaU, 0x82828282U, 0xc9c9c9c9U, 0x7d7d7d7dU, 0xfafafafaU, 0x59595959U, 0x47474747U, 0xf0f0f0f0U,
0xadadadadU, 0xd4d4d4d4U, 0xa2a2a2a2U, 0xafafafafU, 0x9c9c9c9cU, 0xa4a4a4a4U, 0x72727272U, 0xc0c0c0c0U,
0xb7b7b7b7U, 0xfdfdfdfdU, 0x93939393U, 0x26262626U, 0x36363636U, 0x3f3f3f3fU, 0xf7f7f7f7U, 0xccccccccU,
0x34343434U, 0xa5a5a5a5U, 0xe5e5e5e5U, 0xf1f1f1f1U, 0x71717171U, 0xd8d8d8d8U, 0x31313131U, 0x15151515U,
0x04040404U, 0xc7c7c7c7U, 0x23232323U, 0xc3c3c3c3U, 0x18181818U, 0x96969696U, 0x05050505U, 0x9a9a9a9aU,
0x07070707U, 0x12121212U, 0x80808080U, 0xe2e2e2e2U, 0xebebebebU, 0x27272727U, 0xb2b2b2b2U, 0x75757575U,
0x09090909U, 0x83838383U, 0x2c2c2c2cU, 0x1a1a1a1aU, 0x1b1b1b1bU, 0x6e6e6e6eU, 0x5a5a5a5aU, 0xa0a0a0a0U,
0x52525252U, 0x3b3b3b3bU, 0xd6d6d6d6U, 0xb3b3b3b3U, 0x29292929U, 0xe3e3e3e3U, 0x2f2f2f2fU, 0x84848484U,
0x53535353U, 0xd1d1d1d1U, 0x00000000U, 0xededededU, 0x20202020U, 0xfcfcfcfcU, 0xb1b1b1b1U, 0x5b5b5b5bU,
0x6a6a6a6aU, 0xcbcbcbcbU, 0xbebebebeU, 0x39393939U, 0x4a4a4a4aU, 0x4c4c4c4cU, 0x58585858U, 0xcfcfcfcfU,
0xd0d0d0d0U, 0xefefefefU, 0xaaaaaaaaU, 0xfbfbfbfbU, 0x43434343U, 0x4d4d4d4dU, 0x33333333U, 0x85858585U,
0x45454545U, 0xf9f9f9f9U, 0x02020202U, 0x7f7f7f7fU, 0x50505050U, 0x3c3c3c3cU, 0x9f9f9f9fU, 0xa8a8a8a8U,
0x51515151U, 0xa3a3a3a3U, 0x40404040U, 0x8f8f8f8fU, 0x92929292U, 0x9d9d9d9dU, 0x38383838U, 0xf5f5f5f5U,
0xbcbcbcbcU, 0xb6b6b6b6U, 0xdadadadaU, 0x21212121U, 0x10101010U, 0xffffffffU, 0xf3f3f3f3U, 0xd2d2d2d2U,
0xcdcdcdcdU, 0x0c0c0c0cU, 0x13131313U, 0xececececU, 0x5f5f5f5fU, 0x97979797U, 0x44444444U, 0x17171717U,
0xc4c4c4c4U, 0xa7a7a7a7U, 0x7e7e7e7eU, 0x3d3d3d3dU, 0x64646464U, 0x5d5d5d5dU, 0x19191919U, 0x73737373U,
0x60606060U, 0x81818181U, 0x4f4f4f4fU, 0xdcdcdcdcU, 0x22222222U, 0x2a2a2a2aU, 0x90909090U, 0x88888888U,
0x46464646U, 0xeeeeeeeeU, 0xb8b8b8b8U, 0x14141414U, 0xdedededeU, 0x5e5e5e5eU, 0x0b0b0b0bU, 0xdbdbdbdbU,
0xe0e0e0e0U, 0x32323232U, 0x3a3a3a3aU, 0x0a0a0a0aU, 0x49494949U, 0x06060606U, 0x24242424U, 0x5c5c5c5cU,
0xc2c2c2c2U, 0xd3d3d3d3U, 0xacacacacU, 0x62626262U, 0x91919191U, 0x95959595U, 0xe4e4e4e4U, 0x79797979U,
0xe7e7e7e7U, 0xc8c8c8c8U, 0x37373737U, 0x6d6d6d6dU, 0x8d8d8d8dU, 0xd5d5d5d5U, 0x4e4e4e4eU, 0xa9a9a9a9U,
0x6c6c6c6cU, 0x56565656U, 0xf4f4f4f4U, 0xeaeaeaeaU, 0x65656565U, 0x7a7a7a7aU, 0xaeaeaeaeU, 0x08080808U,
0xbabababaU, 0x78787878U, 0x25252525U, 0x2e2e2e2eU, 0x1c1c1c1cU, 0xa6a6a6a6U, 0xb4b4b4b4U, 0xc6c6c6c6U,
0xe8e8e8e8U, 0xddddddddU, 0x74747474U, 0x1f1f1f1fU, 0x4b4b4b4bU, 0xbdbdbdbdU, 0x8b8b8b8bU, 0x8a8a8a8aU,
0x70707070U, 0x3e3e3e3eU, 0xb5b5b5b5U, 0x66666666U, 0x48484848U, 0x03030303U, 0xf6f6f6f6U, 0x0e0e0e0eU,
0x61616161U, 0x35353535U, 0x57575757U, 0xb9b9b9b9U, 0x86868686U, 0xc1c1c1c1U, 0x1d1d1d1dU, 0x9e9e9e9eU,
0xe1e1e1e1U, 0xf8f8f8f8U, 0x98989898U, 0x11111111U, 0x69696969U, 0xd9d9d9d9U, 0x8e8e8e8eU, 0x94949494U,
0x9b9b9b9bU, 0x1e1e1e1eU, 0x87878787U, 0xe9e9e9e9U, 0xcecececeU, 0x55555555U, 0x28282828U, 0xdfdfdfdfU,
0x8c8c8c8cU, 0xa1a1a1a1U, 0x89898989U, 0x0d0d0d0dU, 0xbfbfbfbfU, 0xe6e6e6e6U, 0x42424242U, 0x68686868U,
0x41414141U, 0x99999999U, 0x2d2d2d2dU, 0x0f0f0f0fU, 0xb0b0b0b0U, 0x54545454U, 0xbbbbbbbbU, 0x16161616U };
// Td0[x] = Si[x].[0e, 09, 0d, 0b];
static const uint32_t Td0[256] = {
0x51f4a750U, 0x7e416553U, 0x1a17a4c3U, 0x3a275e96U, 0x3bab6bcbU, 0x1f9d45f1U, 0xacfa58abU, 0x4be30393U,
0x2030fa55U, 0xad766df6U, 0x88cc7691U, 0xf5024c25U, 0x4fe5d7fcU, 0xc52acbd7U, 0x26354480U, 0xb562a38fU,
0xdeb15a49U, 0x25ba1b67U, 0x45ea0e98U, 0x5dfec0e1U, 0xc32f7502U, 0x814cf012U, 0x8d4697a3U, 0x6bd3f9c6U,
0x038f5fe7U, 0x15929c95U, 0xbf6d7aebU, 0x955259daU, 0xd4be832dU, 0x587421d3U, 0x49e06929U, 0x8ec9c844U,
0x75c2896aU, 0xf48e7978U, 0x99583e6bU, 0x27b971ddU, 0xbee14fb6U, 0xf088ad17U, 0xc920ac66U, 0x7dce3ab4U,
0x63df4a18U, 0xe51a3182U, 0x97513360U, 0x62537f45U, 0xb16477e0U, 0xbb6bae84U, 0xfe81a01cU, 0xf9082b94U,
0x70486858U, 0x8f45fd19U, 0x94de6c87U, 0x527bf8b7U, 0xab73d323U, 0x724b02e2U, 0xe31f8f57U, 0x6655ab2aU,
0xb2eb2807U, 0x2fb5c203U, 0x86c57b9aU, 0xd33708a5U, 0x302887f2U, 0x23bfa5b2U, 0x02036abaU, 0xed16825cU,
0x8acf1c2bU, 0xa779b492U, 0xf307f2f0U, 0x4e69e2a1U, 0x65daf4cdU, 0x0605bed5U, 0xd134621fU, 0xc4a6fe8aU,
0x342e539dU, 0xa2f355a0U, 0x058ae132U, 0xa4f6eb75U, 0x0b83ec39U, 0x4060efaaU, 0x5e719f06U, 0xbd6e1051U,
0x3e218af9U, 0x96dd063dU, 0xdd3e05aeU, 0x4de6bd46U, 0x91548db5U, 0x71c45d05U, 0x0406d46fU, 0x605015ffU,
0x1998fb24U, 0xd6bde997U, 0x894043ccU, 0x67d99e77U, 0xb0e842bdU, 0x07898b88U, 0xe7195b38U, 0x79c8eedbU,
0xa17c0a47U, 0x7c420fe9U, 0xf8841ec9U, 0x00000000U, 0x09808683U, 0x322bed48U, 0x1e1170acU, 0x6c5a724eU,
0xfd0efffbU, 0x0f853856U, 0x3daed51eU, 0x362d3927U, 0x0a0fd964U, 0x685ca621U, 0x9b5b54d1U, 0x24362e3aU,
0x0c0a67b1U, 0x9357e70fU, 0xb4ee96d2U, 0x1b9b919eU, 0x80c0c54fU, 0x61dc20a2U, 0x5a774b69U, 0x1c121a16U,
0xe293ba0aU, 0xc0a02ae5U, 0x3c22e043U, 0x121b171dU, 0x0e090d0bU, 0xf28bc7adU, 0x2db6a8b9U, 0x141ea9c8U,
0x57f11985U, 0xaf75074cU, 0xee99ddbbU, 0xa37f60fdU, 0xf701269fU, 0x5c72f5bcU, 0x44663bc5U, 0x5bfb7e34U,
0x8b432976U, 0xcb23c6dcU, 0xb6edfc68U, 0xb8e4f163U, 0xd731dccaU, 0x42638510U, 0x13972240U, 0x84c61120U,
0x854a247dU, 0xd2bb3df8U, 0xaef93211U, 0xc729a16dU, 0x1d9e2f4bU, 0xdcb230f3U, 0x0d8652ecU, 0x77c1e3d0U,
0x2bb3166cU, 0xa970b999U, 0x119448faU, 0x47e96422U, 0xa8fc8cc4U, 0xa0f03f1aU, 0x567d2cd8U, 0x223390efU,
0x87494ec7U, 0xd938d1c1U, 0x8ccaa2feU, 0x98d40b36U, 0xa6f581cfU, 0xa57ade28U, 0xdab78e26U, 0x3fadbfa4U,
0x2c3a9de4U, 0x5078920dU, 0x6a5fcc9bU, 0x547e4662U, 0xf68d13c2U, 0x90d8b8e8U, 0x2e39f75eU, 0x82c3aff5U,
0x9f5d80beU, 0x69d0937cU, 0x6fd52da9U, 0xcf2512b3U, 0xc8ac993bU, 0x10187da7U, 0xe89c636eU, 0xdb3bbb7bU,
0xcd267809U, 0x6e5918f4U, 0xec9ab701U, 0x834f9aa8U, 0xe6956e65U, 0xaaffe67eU, 0x21bccf08U, 0xef15e8e6U,
0xbae79bd9U, 0x4a6f36ceU, 0xea9f09d4U, 0x29b07cd6U, 0x31a4b2afU, 0x2a3f2331U, 0xc6a59430U, 0x35a266c0U,
0x744ebc37U, 0xfc82caa6U, 0xe090d0b0U, 0x33a7d815U, 0xf104984aU, 0x41ecdaf7U, 0x7fcd500eU, 0x1791f62fU,
0x764dd68dU, 0x43efb04dU, 0xccaa4d54U, 0xe49604dfU, 0x9ed1b5e3U, 0x4c6a881bU, 0xc12c1fb8U, 0x4665517fU,
0x9d5eea04U, 0x018c355dU, 0xfa877473U, 0xfb0b412eU, 0xb3671d5aU, 0x92dbd252U, 0xe9105633U, 0x6dd64713U,
0x9ad7618cU, 0x37a10c7aU, 0x59f8148eU, 0xeb133c89U, 0xcea927eeU, 0xb761c935U, 0xe11ce5edU, 0x7a47b13cU,
0x9cd2df59U, 0x55f2733fU, 0x1814ce79U, 0x73c737bfU, 0x53f7cdeaU, 0x5ffdaa5bU, 0xdf3d6f14U, 0x7844db86U,
0xcaaff381U, 0xb968c43eU, 0x3824342cU, 0xc2a3405fU, 0x161dc372U, 0xbce2250cU, 0x283c498bU, 0xff0d9541U,
0x39a80171U, 0x080cb3deU, 0xd8b4e49cU, 0x6456c190U, 0x7bcb8461U, 0xd532b670U, 0x486c5c74U, 0xd0b85742U };
// Td1[x] = Si[x].[0b, 0e, 09, 0d];
static const uint32_t Td1[256] = {
0x5051f4a7U, 0x537e4165U, 0xc31a17a4U, 0x963a275eU, 0xcb3bab6bU, 0xf11f9d45U, 0xabacfa58U, 0x934be303U,
0x552030faU, 0xf6ad766dU, 0x9188cc76U, 0x25f5024cU, 0xfc4fe5d7U, 0xd7c52acbU, 0x80263544U, 0x8fb562a3U,
0x49deb15aU, 0x6725ba1bU, 0x9845ea0eU, 0xe15dfec0U, 0x02c32f75U, 0x12814cf0U, 0xa38d4697U, 0xc66bd3f9U,
0xe7038f5fU, 0x9515929cU, 0xebbf6d7aU, 0xda955259U, 0x2dd4be83U, 0xd3587421U, 0x2949e069U, 0x448ec9c8U,
0x6a75c289U, 0x78f48e79U, 0x6b99583eU, 0xdd27b971U, 0xb6bee14fU, 0x17f088adU, 0x66c920acU, 0xb47dce3aU,
0x1863df4aU, 0x82e51a31U, 0x60975133U, 0x4562537fU, 0xe0b16477U, 0x84bb6baeU, 0x1cfe81a0U, 0x94f9082bU,
0x58704868U, 0x198f45fdU, 0x8794de6cU, 0xb7527bf8U, 0x23ab73d3U, 0xe2724b02U, 0x57e31f8fU, 0x2a6655abU,
0x07b2eb28U, 0x032fb5c2U, 0x9a86c57bU, 0xa5d33708U, 0xf2302887U, 0xb223bfa5U, 0xba02036aU, 0x5ced1682U,
0x2b8acf1cU, 0x92a779b4U, 0xf0f307f2U, 0xa14e69e2U, 0xcd65daf4U, 0xd50605beU, 0x1fd13462U, 0x8ac4a6feU,
0x9d342e53U, 0xa0a2f355U, 0x32058ae1U, 0x75a4f6ebU, 0x390b83ecU, 0xaa4060efU, 0x065e719fU, 0x51bd6e10U,
0xf93e218aU, 0x3d96dd06U, 0xaedd3e05U, 0x464de6bdU, 0xb591548dU, 0x0571c45dU, 0x6f0406d4U, 0xff605015U,
0x241998fbU, 0x97d6bde9U, 0xcc894043U, 0x7767d99eU, 0xbdb0e842U, 0x8807898bU, 0x38e7195bU, 0xdb79c8eeU,
0x47a17c0aU, 0xe97c420fU, 0xc9f8841eU, 0x00000000U, 0x83098086U, 0x48322bedU, 0xac1e1170U, 0x4e6c5a72U,
0xfbfd0effU, 0x560f8538U, 0x1e3daed5U, 0x27362d39U, 0x640a0fd9U, 0x21685ca6U, 0xd19b5b54U, 0x3a24362eU,
0xb10c0a67U, 0x0f9357e7U, 0xd2b4ee96U, 0x9e1b9b91U, 0x4f80c0c5U, 0xa261dc20U, 0x695a774bU, 0x161c121aU,
0x0ae293baU, 0xe5c0a02aU, 0x433c22e0U, 0x1d121b17U, 0x0b0e090dU, 0xadf28bc7U, 0xb92db6a8U, 0xc8141ea9U,
0x8557f119U, 0x4caf7507U, 0xbbee99ddU, 0xfda37f60U, 0x9ff70126U, 0xbc5c72f5U, 0xc544663bU, 0x345bfb7eU,
0x768b4329U, 0xdccb23c6U, 0x68b6edfcU, 0x63b8e4f1U, 0xcad731dcU, 0x10426385U, 0x40139722U, 0x2084c611U,
0x7d854a24U, 0xf8d2bb3dU, 0x11aef932U, 0x6dc729a1U, 0x4b1d9e2fU, 0xf3dcb230U, 0xec0d8652U, 0xd077c1e3U,
0x6c2bb316U, 0x99a970b9U, 0xfa119448U, 0x2247e964U, 0xc4a8fc8cU, 0x1aa0f03fU, 0xd8567d2cU, 0xef223390U,
0xc787494eU, 0xc1d938d1U, 0xfe8ccaa2U, 0x3698d40bU, 0xcfa6f581U, 0x28a57adeU, 0x26dab78eU, 0xa43fadbfU,
0xe42c3a9dU, 0x0d507892U, 0x9b6a5fccU, 0x62547e46U, 0xc2f68d13U, 0xe890d8b8U, 0x5e2e39f7U, 0xf582c3afU,
0xbe9f5d80U, 0x7c69d093U, 0xa96fd52dU, 0xb3cf2512U, 0x3bc8ac99U, 0xa710187dU, 0x6ee89c63U, 0x7bdb3bbbU,
0x09cd2678U, 0xf46e5918U, 0x01ec9ab7U, 0xa8834f9aU, 0x65e6956eU, 0x7eaaffe6U, 0x0821bccfU, 0xe6ef15e8U,
0xd9bae79bU, 0xce4a6f36U, 0xd4ea9f09U, 0xd629b07cU, 0xaf31a4b2U, 0x312a3f23U, 0x30c6a594U, 0xc035a266U,
0x37744ebcU, 0xa6fc82caU, 0xb0e090d0U, 0x1533a7d8U, 0x4af10498U, 0xf741ecdaU, 0x0e7fcd50U, 0x2f1791f6U,
0x8d764dd6U, 0x4d43efb0U, 0x54ccaa4dU, 0xdfe49604U, 0xe39ed1b5U, 0x1b4c6a88U, 0xb8c12c1fU, 0x7f466551U,
0x049d5eeaU, 0x5d018c35U, 0x73fa8774U, 0x2efb0b41U, 0x5ab3671dU, 0x5292dbd2U, 0x33e91056U, 0x136dd647U,
0x8c9ad761U, 0x7a37a10cU, 0x8e59f814U, 0x89eb133cU, 0xeecea927U, 0x35b761c9U, 0xede11ce5U, 0x3c7a47b1U,
0x599cd2dfU, 0x3f55f273U, 0x791814ceU, 0xbf73c737U, 0xea53f7cdU, 0x5b5ffdaaU, 0x14df3d6fU, 0x867844dbU,
0x81caaff3U, 0x3eb968c4U, 0x2c382434U, 0x5fc2a340U, 0x72161dc3U, 0x0cbce225U, 0x8b283c49U, 0x41ff0d95U,
0x7139a801U, 0xde080cb3U, 0x9cd8b4e4U, 0x906456c1U, 0x617bcb84U, 0x70d532b6U, 0x74486c5cU, 0x42d0b857U };
// Td2[x] = Si[x].[0d, 0b, 0e, 09];
static const uint32_t Td2[256] = {
0xa75051f4U, 0x65537e41U, 0xa4c31a17U, 0x5e963a27U, 0x6bcb3babU, 0x45f11f9dU, 0x58abacfaU, 0x03934be3U,
0xfa552030U, 0x6df6ad76U, 0x769188ccU, 0x4c25f502U, 0xd7fc4fe5U, 0xcbd7c52aU, 0x44802635U, 0xa38fb562U,
0x5a49deb1U, 0x1b6725baU, 0x0e9845eaU, 0xc0e15dfeU, 0x7502c32fU, 0xf012814cU, 0x97a38d46U, 0xf9c66bd3U,
0x5fe7038fU, 0x9c951592U, 0x7aebbf6dU, 0x59da9552U, 0x832dd4beU, 0x21d35874U, 0x692949e0U, 0xc8448ec9U,
0x896a75c2U, 0x7978f48eU, 0x3e6b9958U, 0x71dd27b9U, 0x4fb6bee1U, 0xad17f088U, 0xac66c920U, 0x3ab47dceU,
0x4a1863dfU, 0x3182e51aU, 0x33609751U, 0x7f456253U, 0x77e0b164U, 0xae84bb6bU, 0xa01cfe81U, 0x2b94f908U,
0x68587048U, 0xfd198f45U, 0x6c8794deU, 0xf8b7527bU, 0xd323ab73U, 0x02e2724bU, 0x8f57e31fU, 0xab2a6655U,
0x2807b2ebU, 0xc2032fb5U, 0x7b9a86c5U, 0x08a5d337U, 0x87f23028U, 0xa5b223bfU, 0x6aba0203U, 0x825ced16U,
0x1c2b8acfU, 0xb492a779U, 0xf2f0f307U, 0xe2a14e69U, 0xf4cd65daU, 0xbed50605U, 0x621fd134U, 0xfe8ac4a6U,
0x539d342eU, 0x55a0a2f3U, 0xe132058aU, 0xeb75a4f6U, 0xec390b83U, 0xefaa4060U, 0x9f065e71U, 0x1051bd6eU,
0x8af93e21U, 0x063d96ddU, 0x05aedd3eU, 0xbd464de6U, 0x8db59154U, 0x5d0571c4U, 0xd46f0406U, 0x15ff6050U,
0xfb241998U, 0xe997d6bdU, 0x43cc8940U, 0x9e7767d9U, 0x42bdb0e8U, 0x8b880789U, 0x5b38e719U, 0xeedb79c8U,
0x0a47a17cU, 0x0fe97c42U, 0x1ec9f884U, 0x00000000U, 0x86830980U, 0xed48322bU, 0x70ac1e11U, 0x724e6c5aU,
0xfffbfd0eU, 0x38560f85U, 0xd51e3daeU, 0x3927362dU, 0xd9640a0fU, 0xa621685cU, 0x54d19b5bU, 0x2e3a2436U,
0x67b10c0aU, 0xe70f9357U, 0x96d2b4eeU, 0x919e1b9bU, 0xc54f80c0U, 0x20a261dcU, 0x4b695a77U, 0x1a161c12U,
0xba0ae293U, 0x2ae5c0a0U, 0xe0433c22U, 0x171d121bU, 0x0d0b0e09U, 0xc7adf28bU, 0xa8b92db6U, 0xa9c8141eU,
0x198557f1U, 0x074caf75U, 0xddbbee99U, 0x60fda37fU, 0x269ff701U, 0xf5bc5c72U, 0x3bc54466U, 0x7e345bfbU,
0x29768b43U, 0xc6dccb23U, 0xfc68b6edU, 0xf163b8e4U, 0xdccad731U, 0x85104263U, 0x22401397U, 0x112084c6U,
0x247d854aU, 0x3df8d2bbU, 0x3211aef9U, 0xa16dc729U, 0x2f4b1d9eU, 0x30f3dcb2U, 0x52ec0d86U, 0xe3d077c1U,
0x166c2bb3U, 0xb999a970U, 0x48fa1194U, 0x642247e9U, 0x8cc4a8fcU, 0x3f1aa0f0U, 0x2cd8567dU, 0x90ef2233U,
0x4ec78749U, 0xd1c1d938U, 0xa2fe8ccaU, 0x0b3698d4U, 0x81cfa6f5U, 0xde28a57aU, 0x8e26dab7U, 0xbfa43fadU,
0x9de42c3aU, 0x920d5078U, 0xcc9b6a5fU, 0x4662547eU, 0x13c2f68dU, 0xb8e890d8U, 0xf75e2e39U, 0xaff582c3U,
0x80be9f5dU, 0x937c69d0U, 0x2da96fd5U, 0x12b3cf25U, 0x993bc8acU, 0x7da71018U, 0x636ee89cU, 0xbb7bdb3bU,
0x7809cd26U, 0x18f46e59U, 0xb701ec9aU, 0x9aa8834fU, 0x6e65e695U, 0xe67eaaffU, 0xcf0821bcU, 0xe8e6ef15U,
0x9bd9bae7U, 0x36ce4a6fU, 0x09d4ea9fU, 0x7cd629b0U, 0xb2af31a4U, 0x23312a3fU, 0x9430c6a5U, 0x66c035a2U,
0xbc37744eU, 0xcaa6fc82U, 0xd0b0e090U, 0xd81533a7U, 0x984af104U, 0xdaf741ecU, 0x500e7fcdU, 0xf62f1791U,
0xd68d764dU, 0xb04d43efU, 0x4d54ccaaU, 0x04dfe496U, 0xb5e39ed1U, 0x881b4c6aU, 0x1fb8c12cU, 0x517f4665U,
0xea049d5eU, 0x355d018cU, 0x7473fa87U, 0x412efb0bU, 0x1d5ab367U, 0xd25292dbU, 0x5633e910U, 0x47136dd6U,
0x618c9ad7U, 0x0c7a37a1U, 0x148e59f8U, 0x3c89eb13U, 0x27eecea9U, 0xc935b761U, 0xe5ede11cU, 0xb13c7a47U,
0xdf599cd2U, 0x733f55f2U, 0xce791814U, 0x37bf73c7U, 0xcdea53f7U, 0xaa5b5ffdU, 0x6f14df3dU, 0xdb867844U,
0xf381caafU, 0xc43eb968U, 0x342c3824U, 0x405fc2a3U, 0xc372161dU, 0x250cbce2U, 0x498b283cU, 0x9541ff0dU,
0x017139a8U, 0xb3de080cU, 0xe49cd8b4U, 0xc1906456U, 0x84617bcbU, 0xb670d532U, 0x5c74486cU, 0x5742d0b8U };
// Td3[x] = Si[x].[09, 0d, 0b, 0e];
static const uint32_t Td3[256] = {
0xf4a75051U, 0x4165537eU, 0x17a4c31aU, 0x275e963aU, 0xab6bcb3bU, 0x9d45f11fU, 0xfa58abacU, 0xe303934bU,
0x30fa5520U, 0x766df6adU, 0xcc769188U, 0x024c25f5U, 0xe5d7fc4fU, 0x2acbd7c5U, 0x35448026U, 0x62a38fb5U,
0xb15a49deU, 0xba1b6725U, 0xea0e9845U, 0xfec0e15dU, 0x2f7502c3U, 0x4cf01281U, 0x4697a38dU, 0xd3f9c66bU,
0x8f5fe703U, 0x929c9515U, 0x6d7aebbfU, 0x5259da95U, 0xbe832dd4U, 0x7421d358U, 0xe0692949U, 0xc9c8448eU,
0xc2896a75U, 0x8e7978f4U, 0x583e6b99U, 0xb971dd27U, 0xe14fb6beU, 0x88ad17f0U, 0x20ac66c9U, 0xce3ab47dU,
0xdf4a1863U, 0x1a3182e5U, 0x51336097U, 0x537f4562U, 0x6477e0b1U, 0x6bae84bbU, 0x81a01cfeU, 0x082b94f9U,
0x48685870U, 0x45fd198fU, 0xde6c8794U, 0x7bf8b752U, 0x73d323abU, 0x4b02e272U, 0x1f8f57e3U, 0x55ab2a66U,
0xeb2807b2U, 0xb5c2032fU, 0xc57b9a86U, 0x3708a5d3U, 0x2887f230U, 0xbfa5b223U, 0x036aba02U, 0x16825cedU,
0xcf1c2b8aU, 0x79b492a7U, 0x07f2f0f3U, 0x69e2a14eU, 0xdaf4cd65U, 0x05bed506U, 0x34621fd1U, 0xa6fe8ac4U,
0x2e539d34U, 0xf355a0a2U, 0x8ae13205U, 0xf6eb75a4U, 0x83ec390bU, 0x60efaa40U, 0x719f065eU, 0x6e1051bdU,
0x218af93eU, 0xdd063d96U, 0x3e05aeddU, 0xe6bd464dU, 0x548db591U, 0xc45d0571U, 0x06d46f04U, 0x5015ff60U,
0x98fb2419U, 0xbde997d6U, 0x4043cc89U, 0xd99e7767U, 0xe842bdb0U, 0x898b8807U, 0x195b38e7U, 0xc8eedb79U,
0x7c0a47a1U, 0x420fe97cU, 0x841ec9f8U, 0x00000000U, 0x80868309U, 0x2bed4832U, 0x1170ac1eU, 0x5a724e6cU,
0x0efffbfdU, 0x8538560fU, 0xaed51e3dU, 0x2d392736U, 0x0fd9640aU, 0x5ca62168U, 0x5b54d19bU, 0x362e3a24U,
0x0a67b10cU, 0x57e70f93U, 0xee96d2b4U, 0x9b919e1bU, 0xc0c54f80U, 0xdc20a261U, 0x774b695aU, 0x121a161cU,
0x93ba0ae2U, 0xa02ae5c0U, 0x22e0433cU, 0x1b171d12U, 0x090d0b0eU, 0x8bc7adf2U, 0xb6a8b92dU, 0x1ea9c814U,
0xf1198557U, 0x75074cafU, 0x99ddbbeeU, 0x7f60fda3U, 0x01269ff7U, 0x72f5bc5cU, 0x663bc544U, 0xfb7e345bU,
0x4329768bU, 0x23c6dccbU, 0xedfc68b6U, 0xe4f163b8U, 0x31dccad7U, 0x63851042U, 0x97224013U, 0xc6112084U,
0x4a247d85U, 0xbb3df8d2U, 0xf93211aeU, 0x29a16dc7U, 0x9e2f4b1dU, 0xb230f3dcU, 0x8652ec0dU, 0xc1e3d077U,
0xb3166c2bU, 0x70b999a9U, 0x9448fa11U, 0xe9642247U, 0xfc8cc4a8U, 0xf03f1aa0U, 0x7d2cd856U, 0x3390ef22U,
0x494ec787U, 0x38d1c1d9U, 0xcaa2fe8cU, 0xd40b3698U, 0xf581cfa6U, 0x7ade28a5U, 0xb78e26daU, 0xadbfa43fU,
0x3a9de42cU, 0x78920d50U, 0x5fcc9b6aU, 0x7e466254U, 0x8d13c2f6U, 0xd8b8e890U, 0x39f75e2eU, 0xc3aff582U,
0x5d80be9fU, 0xd0937c69U, 0xd52da96fU, 0x2512b3cfU, 0xac993bc8U, 0x187da710U, 0x9c636ee8U, 0x3bbb7bdbU,
0x267809cdU, 0x5918f46eU, 0x9ab701ecU, 0x4f9aa883U, 0x956e65e6U, 0xffe67eaaU, 0xbccf0821U, 0x15e8e6efU,
0xe79bd9baU, 0x6f36ce4aU, 0x9f09d4eaU, 0xb07cd629U, 0xa4b2af31U, 0x3f23312aU, 0xa59430c6U, 0xa266c035U,
0x4ebc3774U, 0x82caa6fcU, 0x90d0b0e0U, 0xa7d81533U, 0x04984af1U, 0xecdaf741U, 0xcd500e7fU, 0x91f62f17U,
0x4dd68d76U, 0xefb04d43U, 0xaa4d54ccU, 0x9604dfe4U, 0xd1b5e39eU, 0x6a881b4cU, 0x2c1fb8c1U, 0x65517f46U,
0x5eea049dU, 0x8c355d01U, 0x877473faU, 0x0b412efbU, 0x671d5ab3U, 0xdbd25292U, 0x105633e9U, 0xd647136dU,
0xd7618c9aU, 0xa10c7a37U, 0xf8148e59U, 0x133c89ebU, 0xa927eeceU, 0x61c935b7U, 0x1ce5ede1U, 0x47b13c7aU,
0xd2df599cU, 0xf2733f55U, 0x14ce7918U, 0xc737bf73U, 0xf7cdea53U, 0xfdaa5b5fU, 0x3d6f14dfU, 0x44db8678U,
0xaff381caU, 0x68c43eb9U, 0x24342c38U, 0xa3405fc2U, 0x1dc37216U, 0xe2250cbcU, 0x3c498b28U, 0x0d9541ffU,
0xa8017139U, 0x0cb3de08U, 0xb4e49cd8U, 0x56c19064U, 0xcb84617bU, 0x32b670d5U, 0x6c5c7448U, 0xb85742d0U };
// Td4[x] = Si[x].[01, 01, 01, 01];
static const uint32_t Td4[256] = {
0x52525252U, 0x09090909U, 0x6a6a6a6aU, 0xd5d5d5d5U, 0x30303030U, 0x36363636U, 0xa5a5a5a5U, 0x38383838U,
0xbfbfbfbfU, 0x40404040U, 0xa3a3a3a3U, 0x9e9e9e9eU, 0x81818181U, 0xf3f3f3f3U, 0xd7d7d7d7U, 0xfbfbfbfbU,
0x7c7c7c7cU, 0xe3e3e3e3U, 0x39393939U, 0x82828282U, 0x9b9b9b9bU, 0x2f2f2f2fU, 0xffffffffU, 0x87878787U,
0x34343434U, 0x8e8e8e8eU, 0x43434343U, 0x44444444U, 0xc4c4c4c4U, 0xdedededeU, 0xe9e9e9e9U, 0xcbcbcbcbU,
0x54545454U, 0x7b7b7b7bU, 0x94949494U, 0x32323232U, 0xa6a6a6a6U, 0xc2c2c2c2U, 0x23232323U, 0x3d3d3d3dU,
0xeeeeeeeeU, 0x4c4c4c4cU, 0x95959595U, 0x0b0b0b0bU, 0x42424242U, 0xfafafafaU, 0xc3c3c3c3U, 0x4e4e4e4eU,
0x08080808U, 0x2e2e2e2eU, 0xa1a1a1a1U, 0x66666666U, 0x28282828U, 0xd9d9d9d9U, 0x24242424U, 0xb2b2b2b2U,
0x76767676U, 0x5b5b5b5bU, 0xa2a2a2a2U, 0x49494949U, 0x6d6d6d6dU, 0x8b8b8b8bU, 0xd1d1d1d1U, 0x25252525U,
0x72727272U, 0xf8f8f8f8U, 0xf6f6f6f6U, 0x64646464U, 0x86868686U, 0x68686868U, 0x98989898U, 0x16161616U,
0xd4d4d4d4U, 0xa4a4a4a4U, 0x5c5c5c5cU, 0xccccccccU, 0x5d5d5d5dU, 0x65656565U, 0xb6b6b6b6U, 0x92929292U,
0x6c6c6c6cU, 0x70707070U, 0x48484848U, 0x50505050U, 0xfdfdfdfdU, 0xededededU, 0xb9b9b9b9U, 0xdadadadaU,
0x5e5e5e5eU, 0x15151515U, 0x46464646U, 0x57575757U, 0xa7a7a7a7U, 0x8d8d8d8dU, 0x9d9d9d9dU, 0x84848484U,
0x90909090U, 0xd8d8d8d8U, 0xababababU, 0x00000000U, 0x8c8c8c8cU, 0xbcbcbcbcU, 0xd3d3d3d3U, 0x0a0a0a0aU,
0xf7f7f7f7U, 0xe4e4e4e4U, 0x58585858U, 0x05050505U, 0xb8b8b8b8U, 0xb3b3b3b3U, 0x45454545U, 0x06060606U,
0xd0d0d0d0U, 0x2c2c2c2cU, 0x1e1e1e1eU, 0x8f8f8f8fU, 0xcacacacaU, 0x3f3f3f3fU, 0x0f0f0f0fU, 0x02020202U,
0xc1c1c1c1U, 0xafafafafU, 0xbdbdbdbdU, 0x03030303U, 0x01010101U, 0x13131313U, 0x8a8a8a8aU, 0x6b6b6b6bU,
0x3a3a3a3aU, 0x91919191U, 0x11111111U, 0x41414141U, 0x4f4f4f4fU, 0x67676767U, 0xdcdcdcdcU, 0xeaeaeaeaU,
0x97979797U, 0xf2f2f2f2U, 0xcfcfcfcfU, 0xcecececeU, 0xf0f0f0f0U, 0xb4b4b4b4U, 0xe6e6e6e6U, 0x73737373U,
0x96969696U, 0xacacacacU, 0x74747474U, 0x22222222U, 0xe7e7e7e7U, 0xadadadadU, 0x35353535U, 0x85858585U,
0xe2e2e2e2U, 0xf9f9f9f9U, 0x37373737U, 0xe8e8e8e8U, 0x1c1c1c1cU, 0x75757575U, 0xdfdfdfdfU, 0x6e6e6e6eU,
0x47474747U, 0xf1f1f1f1U, 0x1a1a1a1aU, 0x71717171U, 0x1d1d1d1dU, 0x29292929U, 0xc5c5c5c5U, 0x89898989U,
0x6f6f6f6fU, 0xb7b7b7b7U, 0x62626262U, 0x0e0e0e0eU, 0xaaaaaaaaU, 0x18181818U, 0xbebebebeU, 0x1b1b1b1bU,
0xfcfcfcfcU, 0x56565656U, 0x3e3e3e3eU, 0x4b4b4b4bU, 0xc6c6c6c6U, 0xd2d2d2d2U, 0x79797979U, 0x20202020U,
0x9a9a9a9aU, 0xdbdbdbdbU, 0xc0c0c0c0U, 0xfefefefeU, 0x78787878U, 0xcdcdcdcdU, 0x5a5a5a5aU, 0xf4f4f4f4U,
0x1f1f1f1fU, 0xddddddddU, 0xa8a8a8a8U, 0x33333333U, 0x88888888U, 0x07070707U, 0xc7c7c7c7U, 0x31313131U,
0xb1b1b1b1U, 0x12121212U, 0x10101010U, 0x59595959U, 0x27272727U, 0x80808080U, 0xececececU, 0x5f5f5f5fU,
0x60606060U, 0x51515151U, 0x7f7f7f7fU, 0xa9a9a9a9U, 0x19191919U, 0xb5b5b5b5U, 0x4a4a4a4aU, 0x0d0d0d0dU,
0x2d2d2d2dU, 0xe5e5e5e5U, 0x7a7a7a7aU, 0x9f9f9f9fU, 0x93939393U, 0xc9c9c9c9U, 0x9c9c9c9cU, 0xefefefefU,
0xa0a0a0a0U, 0xe0e0e0e0U, 0x3b3b3b3bU, 0x4d4d4d4dU, 0xaeaeaeaeU, 0x2a2a2a2aU, 0xf5f5f5f5U, 0xb0b0b0b0U,
0xc8c8c8c8U, 0xebebebebU, 0xbbbbbbbbU, 0x3c3c3c3cU, 0x83838383U, 0x53535353U, 0x99999999U, 0x61616161U,
0x17171717U, 0x2b2b2b2bU, 0x04040404U, 0x7e7e7e7eU, 0xbabababaU, 0x77777777U, 0xd6d6d6d6U, 0x26262626U,
0xe1e1e1e1U, 0x69696969U, 0x14141414U, 0x63636363U, 0x55555555U, 0x21212121U, 0x0c0c0c0cU, 0x7d7d7d7dU };
// for 128-bit blocks, Rijndael never uses more than 10 rcon values
static const uint32_t rcon[] = {
0x01000000, 0x02000000, 0x04000000, 0x08000000,
0x10000000, 0x20000000, 0x40000000, 0x80000000,
0x1B000000, 0x36000000 };
#define GETU32(p) (be32toh((*((uint32_t*)(p)))))
#define PUTU32(ct, st) { *((uint32_t*)(ct)) = htobe32((st)); }
#define b0(x) ((uint8_t)(x))
#define b1(x) ((uint8_t)((x) >> 8))
#define b2(x) ((uint8_t)((x) >> 16))
#define b3(x) ((uint8_t)((x) >> 24))
#define m0(x) ((x) & 0x000000ff)
#define m1(x) ((x) & 0x0000ff00)
#define m2(x) ((x) & 0x00ff0000)
#define m3(x) ((x) & 0xff000000)
/**
* Expand the cipher key into the encryption key schedule.
*
* @return the number of rounds for the given cipher key size.
*/
static int aes_internal_key_setup_enc (uint32_t rk[/*4*(Nr + 1)*/], const uint8_t cipherKey[], int keyBits) {
int i = 0;
uint32_t temp;
rk[0] = GETU32(cipherKey );
rk[1] = GETU32(cipherKey + 4);
rk[2] = GETU32(cipherKey + 8);
rk[3] = GETU32(cipherKey + 12);
if (keyBits == 128) {
for (;;) {
temp = rk[3];
rk[4] = rk[0] ^
(Te4[b2(temp)] & 0xff000000) ^
(Te4[b1(temp)] & 0x00ff0000) ^
(Te4[b0(temp)] & 0x0000ff00) ^
(Te4[b3(temp)] & 0x000000ff) ^
rcon[i];
rk[5] = rk[1] ^ rk[4];
rk[6] = rk[2] ^ rk[5];
rk[7] = rk[3] ^ rk[6];
if (++i == 10) {
return 10;
}
rk += 4;
}
}
rk[4] = GETU32(cipherKey + 16);
rk[5] = GETU32(cipherKey + 20);
if (keyBits == 192) {
for (;;) {
temp = rk[ 5];
rk[ 6] = rk[ 0] ^
(Te4[b2(temp)] & 0xff000000) ^
(Te4[b1(temp)] & 0x00ff0000) ^
(Te4[b0(temp)] & 0x0000ff00) ^
(Te4[b3(temp)] & 0x000000ff) ^
rcon[i];
rk[ 7] = rk[ 1] ^ rk[ 6];
rk[ 8] = rk[ 2] ^ rk[ 7];
rk[ 9] = rk[ 3] ^ rk[ 8];
if (++i == 8) {
return 12;
}
rk[10] = rk[ 4] ^ rk[ 9];
rk[11] = rk[ 5] ^ rk[10];
rk += 6;
}
}
rk[6] = GETU32(cipherKey + 24);
rk[7] = GETU32(cipherKey + 28);
if (keyBits == 256) {
for (;;) {
temp = rk[ 7];
rk[ 8] = rk[ 0] ^
(Te4[b2(temp)] & 0xff000000) ^
(Te4[b1(temp)] & 0x00ff0000) ^
(Te4[b0(temp)] & 0x0000ff00) ^
(Te4[b3(temp)] & 0x000000ff) ^
rcon[i];
rk[ 9] = rk[ 1] ^ rk[ 8];
rk[10] = rk[ 2] ^ rk[ 9];
rk[11] = rk[ 3] ^ rk[10];
if (++i == 7) {
return 14;
}
temp = rk[11];
rk[12] = rk[ 4] ^
(Te4[b3(temp)] & 0xff000000) ^
(Te4[b2(temp)] & 0x00ff0000) ^
(Te4[b1(temp)] & 0x0000ff00) ^
(Te4[b0(temp)] & 0x000000ff);
rk[13] = rk[ 5] ^ rk[12];
rk[14] = rk[ 6] ^ rk[13];
rk[15] = rk[ 7] ^ rk[14];
rk += 8;
}
}
return 0;
}
/**
* Expand the cipher key into the decryption key schedule.
*
* @return the number of rounds for the given cipher key size.
*/
#define INVMIXCOLRK(n) rk[n] = Td0[b0(Te4[b3(rk[n])])] ^ Td1[b0(Te4[b2(rk[n])])] ^ Td2[b0(Te4[b1(rk[n])])] ^ Td3[b0(Te4[b0(rk[n])])]
static int aes_internal_key_setup_dec (uint32_t rk[/*4*(Nr + 1)*/], const uint8_t cipherKey[], int keyBits) {
int Nr, i, j;
uint32_t temp;
// expand the cipher key
Nr = aes_internal_key_setup_enc(rk, cipherKey, keyBits);
// invert the order of the round keys
for (i = 0, j = 4*Nr; i < j; i += 4, j -= 4) {
temp = rk[i ]; rk[i ] = rk[j ]; rk[j ] = temp;
temp = rk[i + 1]; rk[i + 1] = rk[j + 1]; rk[j + 1] = temp;
temp = rk[i + 2]; rk[i + 2] = rk[j + 2]; rk[j + 2] = temp;
temp = rk[i + 3]; rk[i + 3] = rk[j + 3]; rk[j + 3] = temp;
}
// apply the inverse MixColumn transform to all round keys but the first and the last
for (i = 1; i < Nr; i++) {
rk += 4;
INVMIXCOLRK(0);
INVMIXCOLRK(1);
INVMIXCOLRK(2);
INVMIXCOLRK(3);
}
return Nr;
}
#define AES_ENC_ROUND(DST, SRC, round) \
DST##0 = Te0[b3(SRC##0)] ^ Te1[b2(SRC##1)] ^ Te2[b1(SRC##2)] ^ Te3[b0(SRC##3)] ^ rk[4 * round + 0]; \
DST##1 = Te0[b3(SRC##1)] ^ Te1[b2(SRC##2)] ^ Te2[b1(SRC##3)] ^ Te3[b0(SRC##0)] ^ rk[4 * round + 1]; \
DST##2 = Te0[b3(SRC##2)] ^ Te1[b2(SRC##3)] ^ Te2[b1(SRC##0)] ^ Te3[b0(SRC##1)] ^ rk[4 * round + 2]; \
DST##3 = Te0[b3(SRC##3)] ^ Te1[b2(SRC##0)] ^ Te2[b1(SRC##1)] ^ Te3[b0(SRC##2)] ^ rk[4 * round + 3];
static void aes_internal_encrypt (const uint32_t rk[/*4*(Nr + 1)*/], int Nr, const uint8_t pt[16], uint8_t ct[16]) {
uint32_t s0, s1, s2, s3, t0, t1, t2, t3;
// map byte array block to cipher state and add initial round key
s0 = GETU32(pt ) ^ rk[0];
s1 = GETU32(pt + 4) ^ rk[1];
s2 = GETU32(pt + 8) ^ rk[2];
s3 = GETU32(pt + 12) ^ rk[3];
AES_ENC_ROUND(t, s, 1);
AES_ENC_ROUND(s, t, 2);
AES_ENC_ROUND(t, s, 3);
AES_ENC_ROUND(s, t, 4);
AES_ENC_ROUND(t, s, 5);
AES_ENC_ROUND(s, t, 6);
AES_ENC_ROUND(t, s, 7);
AES_ENC_ROUND(s, t, 8);
AES_ENC_ROUND(t, s, 9);
if(Nr > 10) {
AES_ENC_ROUND(s, t, 10);
AES_ENC_ROUND(t, s, 11);
if(Nr > 12) {
AES_ENC_ROUND(s, t, 12);
AES_ENC_ROUND(t, s, 13);
}
}
rk += Nr << 2;
// apply last round and map cipher state to byte array block
s0 = m3(Te4[b3(t0)]) ^ m2(Te4[b2(t1)]) ^ m1(Te4[b1(t2)]) ^ m0(Te4[b0(t3)]) ^ rk[0];
PUTU32(ct , s0);
s1 = m3(Te4[b3(t1)]) ^ m2(Te4[b2(t2)]) ^ m1(Te4[b1(t3)]) ^ m0(Te4[b0(t0)]) ^ rk[1];
PUTU32(ct + 4, s1);
s2 = m3(Te4[b3(t2)]) ^ m2(Te4[b2(t3)]) ^ m1(Te4[b1(t0)]) ^ m0(Te4[b0(t1)]) ^ rk[2];
PUTU32(ct + 8, s2);
s3 = m3(Te4[b3(t3)]) ^ m2(Te4[b2(t0)]) ^ m1(Te4[b1(t1)]) ^ m0(Te4[b0(t2)]) ^ rk[3];
PUTU32(ct + 12, s3);
}
#define AES_DEC_ROUND(DST, SRC, round) \
DST##0 = Td0[b3(SRC##0)] ^ Td1[b2(SRC##3)] ^ Td2[b1(SRC##2)] ^ Td3[b0(SRC##1)] ^ rk[4 * round + 0]; \
DST##1 = Td0[b3(SRC##1)] ^ Td1[b2(SRC##0)] ^ Td2[b1(SRC##3)] ^ Td3[b0(SRC##2)] ^ rk[4 * round + 1]; \
DST##2 = Td0[b3(SRC##2)] ^ Td1[b2(SRC##1)] ^ Td2[b1(SRC##0)] ^ Td3[b0(SRC##3)] ^ rk[4 * round + 2]; \
DST##3 = Td0[b3(SRC##3)] ^ Td1[b2(SRC##2)] ^ Td2[b1(SRC##1)] ^ Td3[b0(SRC##0)] ^ rk[4 * round + 3];
static void aes_internal_decrypt (const uint32_t rk[/*4*(Nr + 1)*/], int Nr, const uint8_t ct[16], uint8_t pt[16]) {
uint32_t s0, s1, s2, s3, t0, t1, t2, t3;
// map byte array block to cipher state and add initial round key
s0 = GETU32(ct ) ^ rk[0];
s1 = GETU32(ct + 4) ^ rk[1];
s2 = GETU32(ct + 8) ^ rk[2];
s3 = GETU32(ct + 12) ^ rk[3];
AES_DEC_ROUND(t, s, 1);
AES_DEC_ROUND(s, t, 2);
AES_DEC_ROUND(t, s, 3);
AES_DEC_ROUND(s, t, 4);
AES_DEC_ROUND(t, s, 5);
AES_DEC_ROUND(s, t, 6);
AES_DEC_ROUND(t, s, 7);
AES_DEC_ROUND(s, t, 8);
AES_DEC_ROUND(t, s, 9);
if(Nr > 10) {
AES_DEC_ROUND(s, t, 10);
AES_DEC_ROUND(t, s, 11);
if(Nr > 12) {
AES_DEC_ROUND(s, t, 12);
AES_DEC_ROUND(t, s, 13);
}
}
rk += Nr << 2;
// apply last round and map cipher state to byte array block
s0 = m3(Td4[b3(t0)]) ^ m2(Td4[b2(t3)]) ^ m1(Td4[b1(t2)]) ^ m0(Td4[b0(t1)]) ^ rk[0];
PUTU32(pt , s0);
s1 = m3(Td4[b3(t1)]) ^ m2(Td4[b2(t0)]) ^ m1(Td4[b1(t3)]) ^ m0(Td4[b0(t2)]) ^ rk[1];
PUTU32(pt + 4, s1);
s2 = m3(Td4[b3(t2)]) ^ m2(Td4[b2(t1)]) ^ m1(Td4[b1(t0)]) ^ m0(Td4[b0(t3)]) ^ rk[2];
PUTU32(pt + 8, s2);
s3 = m3(Td4[b3(t3)]) ^ m2(Td4[b2(t2)]) ^ m1(Td4[b1(t1)]) ^ m0(Td4[b0(t0)]) ^ rk[3];
PUTU32(pt + 12, s3);
}
// public API
int aes_ecb_decrypt (unsigned char *out, const unsigned char *in, aes_context_t *ctx) {
aes_internal_decrypt(ctx->dec_rk, ctx->Nr, in, out);
return AES_BLOCK_SIZE;
}
// not used
int aes_ecb_encrypt (unsigned char *out, const unsigned char *in, aes_context_t *ctx) {
aes_internal_encrypt(ctx->enc_rk, ctx->Nr, in, out);
return AES_BLOCK_SIZE;
}
#define fix_xor(target, source) *(uint32_t*)&(target)[0] = *(uint32_t*)&(target)[0] ^ *(uint32_t*)&(source)[0]; *(uint32_t*)&(target)[4] = *(uint32_t*)&(target)[4] ^ *(uint32_t*)&(source)[4]; \
*(uint32_t*)&(target)[8] = *(uint32_t*)&(target)[8] ^ *(uint32_t*)&(source)[8]; *(uint32_t*)&(target)[12] = *(uint32_t*)&(target)[12] ^ *(uint32_t*)&(source)[12];
int aes_cbc_encrypt (unsigned char *out, const unsigned char *in, size_t in_len,
const unsigned char *iv, aes_context_t *ctx) {
uint8_t tmp[AES_BLOCK_SIZE];
size_t i;
size_t n;
memcpy(tmp, iv, AES_BLOCK_SIZE);
n = in_len / AES_BLOCK_SIZE;
for(i=0; i < n; i++) {
fix_xor(tmp, &in[i * AES_BLOCK_SIZE]);
aes_internal_encrypt(ctx->enc_rk, ctx->Nr, tmp, tmp);
memcpy(&out[i * AES_BLOCK_SIZE], tmp, AES_BLOCK_SIZE);
}
return n * AES_BLOCK_SIZE;
}
int aes_cbc_decrypt (unsigned char *out, const unsigned char *in, size_t in_len,
const unsigned char *iv, aes_context_t *ctx) {
uint8_t tmp[AES_BLOCK_SIZE];
uint8_t old[AES_BLOCK_SIZE];
size_t i;
size_t n;
memcpy(tmp, iv, AES_BLOCK_SIZE);
n = in_len / AES_BLOCK_SIZE;
for(i=0; i < n; i++) {
memcpy(old, &in[i * AES_BLOCK_SIZE], AES_BLOCK_SIZE);
aes_internal_decrypt(ctx->dec_rk, ctx->Nr, &in[i * AES_BLOCK_SIZE], &out[i * AES_BLOCK_SIZE]);
fix_xor(&out[i * AES_BLOCK_SIZE], tmp);
memcpy(tmp, old, AES_BLOCK_SIZE);
}
return n * AES_BLOCK_SIZE;
}
int aes_init (const unsigned char *key, size_t key_size, aes_context_t **ctx) {
// allocate context...
*ctx = (aes_context_t*) calloc(1, sizeof(aes_context_t));
if (!(*ctx))
return -1;
// ...and fill her up
// initialize data structures
// check key size and make key size (given in bytes) dependant settings
switch(key_size) {
case AES128_KEY_BYTES: // 128 bit key size
break;
case AES192_KEY_BYTES: // 192 bit key size
break;
case AES256_KEY_BYTES: // 256 bit key size
break;
default:
traceEvent(TRACE_ERROR, "aes_init invalid key size %u\n", key_size);
return -1;
}
// key materiel handling
(*ctx)->Nr = aes_internal_key_setup_enc((*ctx)->enc_rk/*[4*(Nr + 1)]*/, key, 8 * key_size);
aes_internal_key_setup_dec((*ctx)->dec_rk/*[4*(Nr + 1)]*/, key, 8 * key_size);
return 0;
}
#endif // openSSL 1.1, openSSL 1.0, plain C -----------------------------------------------
int aes_deinit (aes_context_t *ctx) {
if (ctx) free (ctx);
return 0;
}
// --- for testing ------------------------------------------------------------------------
// --- remove when done ---
/* int aes_init (const unsigned char *key, size_t key_size, aes_context_t **ctx) {
// allocate context...
*ctx = (aes_context_t*) calloc(1, sizeof(aes_context_t));
if (!(*ctx))
return -1;
// ...and fill her up
// initialize data structures
#ifdef HAVE_OPENSSL_1_1 #ifdef HAVE_OPENSSL_1_1
if(!((*ctx)->enc_ctx = EVP_CIPHER_CTX_new())) { if(!((*ctx)->enc_ctx = EVP_CIPHER_CTX_new())) {
traceEvent(TRACE_ERROR, "aes_init openssl's evp_* encryption context creation failed: %s", traceEvent(TRACE_ERROR, "aes_init openssl's evp_* encryption context creation failed: %s",
@ -203,7 +998,31 @@ int aes_init (const unsigned char *key, size_t key_size, aes_context_t **ctx) {
#endif #endif
return 0; return 0;
} */
#ifdef TEST_AES
int main () {
uint32_t rk[60];
uint8_t key[32] = {0};
// uint8_t pt[16] = {0xf3, 0x44, 0x81, 0xec, 0x3c, 0xc6, 0x27, 0xba,
// 0xcd, 0x5d, 0xc3, 0xfb, 0x08, 0xf2, 0x73, 0xe6 };
uint8_t pt[16] = {0x01, 0x47, 0x30, 0xf8, 0x0a, 0xc6, 0x25, 0xfe,
0x84, 0xf0, 0x26, 0xc6, 0x0b, 0xfd, 0x54, 0x7d };
uint8_t ct[16] = {0};
int i;
i = aes_internal_key_setup_enc(rk/*[4*(Nr + 1)]*/, key, 8 * sizeof(key));
printf ("i = %u\n",i);
aes_internal_encrypt(rk, i, pt, ct);
i = aes_internal_key_setup_dec(rk/*[4*(Nr + 1)]*/, key, 8 * sizeof(key));
memset (pt, 0, 16);
aes_internal_decrypt(rk, i, ct, pt);
for(i = 0; i < 16; i++)
printf ("%02x",pt[i]);
printf ("\n");
} }
#endif
#endif // N2N_HAVE_AES

View File

@ -165,9 +165,7 @@ static void help() {
printf("-A1 | Disable payload encryption. Do not use with key (defaulting to Twofish then).\n"); printf("-A1 | Disable payload encryption. Do not use with key (defaulting to Twofish then).\n");
printf("-A2 ... -A5 or -A | Choose a cipher for payload encryption, requires a key: -A2 = Twofish (default),\n"); printf("-A2 ... -A5 or -A | Choose a cipher for payload encryption, requires a key: -A2 = Twofish (default),\n");
printf(" | " printf(" | "
#ifdef N2N_HAVE_AES printf(" | -A3 or -A (deprecated) = AES, "
"-A3 or -A (deprecated) = AES-CBC, "
#endif
"-A4 = ChaCha20, " "-A4 = ChaCha20, "
"-A5 = Speck-CTR.\n"); "-A5 = Speck-CTR.\n");
printf("-H | Enable full header encryption. Requires supernode with fixed community.\n"); printf("-H | Enable full header encryption. Requires supernode with fixed community.\n");
@ -241,13 +239,11 @@ static void setPayloadEncryption( n2n_edge_conf_t *conf, int cipher) {
conf->transop_id = N2N_TRANSFORM_ID_TWOFISH; conf->transop_id = N2N_TRANSFORM_ID_TWOFISH;
break; break;
} }
#ifdef N2N_HAVE_AES
case 3: case 3:
{ {
conf->transop_id = N2N_TRANSFORM_ID_AESCBC; conf->transop_id = N2N_TRANSFORM_ID_AES;
break; break;
} }
#endif
case 4: case 4:
{ {
conf->transop_id = N2N_TRANSFORM_ID_CHACHA20; conf->transop_id = N2N_TRANSFORM_ID_CHACHA20;
@ -361,9 +357,9 @@ static int setOption(int optkey, char *optargument, n2n_tuntap_priv_config_t *ec
cipher = atoi(optargument); cipher = atoi(optargument);
} else { } else {
traceEvent(TRACE_NORMAL, "the use of the solitary -A switch is deprecated and might not be supported in future versions. " traceEvent(TRACE_NORMAL, "the use of the solitary -A switch is deprecated and might not be supported in future versions. "
"please use -A3 instead to choose a the AES-CBC cipher for payload encryption."); "please use -A3 instead to choose a the AES cipher for payload encryption.");
cipher = N2N_TRANSFORM_ID_AESCBC; // default, if '-A' only cipher = N2N_TRANSFORM_ID_AES; // default, if '-A' only
} }
setPayloadEncryption(conf, cipher); setPayloadEncryption(conf, cipher);

View File

@ -101,8 +101,8 @@ int edge_get_management_socket(n2n_edge_t *eee) {
const char* transop_str(enum n2n_transform tr) { const char* transop_str(enum n2n_transform tr) {
switch(tr) { switch(tr) {
case N2N_TRANSFORM_ID_NULL: return("null"); case N2N_TRANSFORM_ID_NULL: return("null");
case N2N_TRANSFORM_ID_TWOFISH: return("twofish"); case N2N_TRANSFORM_ID_TWOFISH: return("Twofish");
case N2N_TRANSFORM_ID_AESCBC: return("AES-CBC"); case N2N_TRANSFORM_ID_AES: return("AES");
case N2N_TRANSFORM_ID_CHACHA20:return("ChaCha20"); case N2N_TRANSFORM_ID_CHACHA20:return("ChaCha20");
case N2N_TRANSFORM_ID_SPECK :return("Speck"); case N2N_TRANSFORM_ID_SPECK :return("Speck");
default: return("invalid"); default: return("invalid");
@ -221,11 +221,9 @@ n2n_edge_t* edge_init(const n2n_edge_conf_t *conf, int *rv) {
case N2N_TRANSFORM_ID_TWOFISH: case N2N_TRANSFORM_ID_TWOFISH:
rc = n2n_transop_tf_init(&eee->conf, &eee->transop); rc = n2n_transop_tf_init(&eee->conf, &eee->transop);
break; break;
#ifdef N2N_HAVE_AES case N2N_TRANSFORM_ID_AES:
case N2N_TRANSFORM_ID_AESCBC: rc = n2n_transop_aes_init(&eee->conf, &eee->transop);
rc = n2n_transop_aes_cbc_init(&eee->conf, &eee->transop);
break; break;
#endif
case N2N_TRANSFORM_ID_CHACHA20: case N2N_TRANSFORM_ID_CHACHA20:
rc = n2n_transop_cc20_init(&eee->conf, &eee->transop); rc = n2n_transop_cc20_init(&eee->conf, &eee->transop);
break; break;

View File

@ -16,11 +16,8 @@
* *
*/ */
#ifdef SYS_getrandom
#include <errno.h>
#endif
#include "n2n.h" #include "random_numbers.h"
/* The following code offers an alterate pseudo random number generator /* The following code offers an alterate pseudo random number generator
@ -31,13 +28,13 @@
/* The state must be seeded in a way that it is not all zero, choose some /* The state must be seeded in a way that it is not all zero, choose some
arbitrary defaults (in this case: taken from splitmix64) */ arbitrary defaults (in this case: taken from splitmix64) */
static struct rn_generator_state_t rn_current_state = { static rn_generator_state_t rn_current_state = {
.a = 0x9E3779B97F4A7C15, .a = 0x9E3779B97F4A7C15,
.b = 0xBF58476D1CE4E5B9 }; .b = 0xBF58476D1CE4E5B9 };
/* used for mixing the initializing seed */ /* used for mixing the initializing seed */
static uint64_t splitmix64 (struct splitmix64_state_t *state) { static uint64_t splitmix64 (splitmix64_state_t *state) {
uint64_t result = state->s; uint64_t result = state->s;
@ -51,8 +48,9 @@ static uint64_t splitmix64 (struct splitmix64_state_t *state) {
int n2n_srand (uint64_t seed) { int n2n_srand (uint64_t seed) {
uint8_t i; uint8_t i;
struct splitmix64_state_t smstate = {seed}; splitmix64_state_t smstate = {seed};
rn_current_state.a = 0; rn_current_state.a = 0;
rn_current_state.b = 0; rn_current_state.b = 0;
@ -67,7 +65,7 @@ int n2n_srand (uint64_t seed) {
rn_current_state.b = 0xBF58476D1CE4E5B9; rn_current_state.b = 0xBF58476D1CE4E5B9;
} }
/* stabilize in unlikely case of weak state with only a few bits set */ // stabilize in unlikely case of weak state with only a few bits set
for(i = 0; i < 32; i++) for(i = 0; i < 32; i++)
n2n_rand(); n2n_rand();
@ -166,10 +164,10 @@ uint64_t n2n_seed (void) {
ret += seed; ret += seed;
#endif */ #endif */
seed = time(NULL); /* UTC in seconds */ seed = time(NULL); // UTC in seconds
ret += seed; ret += seed;
seed = clock() * 18444244737; /* clock() = ticks since program start */ seed = clock() * 18444244737; // clock() = ticks since program start
ret += seed; ret += seed;
return ret; return ret;

View File

@ -997,6 +997,7 @@ static int process_udp(n2n_sn_t * sss,
memcpy(ack.edgeMac, reg.edgeMac, sizeof(n2n_mac_t)); memcpy(ack.edgeMac, reg.edgeMac, sizeof(n2n_mac_t));
if ((reg.dev_addr.net_addr == 0) || (reg.dev_addr.net_addr == 0xFFFFFFFF) || (reg.dev_addr.net_bitlen == 0) || if ((reg.dev_addr.net_addr == 0) || (reg.dev_addr.net_addr == 0xFFFFFFFF) || (reg.dev_addr.net_bitlen == 0) ||
((reg.dev_addr.net_addr & 0xFFFF0000) == 0xA9FE0000 /* 169.254.0.0 */)) { ((reg.dev_addr.net_addr & 0xFFFF0000) == 0xA9FE0000 /* 169.254.0.0 */)) {
memset(&ipaddr, 0, sizeof(n2n_ip_subnet_t));
assign_one_ip_addr(comm, &ipaddr); assign_one_ip_addr(comm, &ipaddr);
ack.dev_addr.net_addr = ipaddr.net_addr; ack.dev_addr.net_addr = ipaddr.net_addr;
ack.dev_addr.net_bitlen = ipaddr.net_bitlen; ack.dev_addr.net_bitlen = ipaddr.net_bitlen;

View File

@ -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,57 @@ 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(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 +853,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));
}
*/

View File

@ -48,7 +48,7 @@ THE SOFTWARE.
#include "tf.h" #include "tf.h"
#include "portable_endian.h"
const uint8_t RS[4][8] = { { 0x01, 0xA4, 0x55, 0x87, 0x5A, 0x58, 0xDB, 0x9E, }, const uint8_t RS[4][8] = { { 0x01, 0xA4, 0x55, 0x87, 0x5A, 0x58, 0xDB, 0x9E, },
{ 0xA4, 0x56, 0x82, 0xF3, 0x1E, 0xC6, 0x68, 0xE5, }, { 0xA4, 0x56, 0x82, 0xF3, 0x1E, 0xC6, 0x68, 0xE5, },
@ -503,3 +503,11 @@ int tf_init (const unsigned char *key, size_t key_size, tf_context_t **ctx) {
return 0; return 0;
} }
int tf_deinit (tf_context_t *ctx) {
if (ctx) free (ctx);
return 0;
}

View File

@ -19,8 +19,6 @@
#include "n2n.h" #include "n2n.h"
#ifdef N2N_HAVE_AES
// size of random value prepended to plaintext defaults to AES BLOCK_SIZE; // size of random value prepended to plaintext defaults to AES BLOCK_SIZE;
// gradually abandoning security, lower values could be chosen; // gradually abandoning security, lower values could be chosen;
@ -29,7 +27,7 @@
// might encounter an issue with lower values here // might encounter an issue with lower values here
#define AES_PREAMBLE_SIZE (AES_BLOCK_SIZE) #define AES_PREAMBLE_SIZE (AES_BLOCK_SIZE)
// cbc mode is being used with random value prepended to plaintext // cts/cbc mode is being used with random value prepended to plaintext
// instead of iv so, actual iv is aes_null_iv // instead of iv so, actual iv is aes_null_iv
const uint8_t aes_null_iv[AES_IV_SIZE] = {0}; const uint8_t aes_null_iv[AES_IV_SIZE] = {0};
@ -42,7 +40,7 @@ typedef struct transop_aes {
static int transop_deinit_aes(n2n_trans_op_t *arg) { static int transop_deinit_aes(n2n_trans_op_t *arg) {
transop_aes_t *priv = (transop_aes_t *)arg->priv; transop_aes_t *priv = (transop_aes_t *)arg->priv;
if(priv->ctx) free(priv->ctx); if(priv->ctx) aes_deinit(priv->ctx);
if(priv) free(priv); if(priv) free(priv);
@ -219,13 +217,14 @@ static void transop_tick_aes(n2n_trans_op_t * arg, time_t now) { ; }
/* ****************************************************** */ /* ****************************************************** */
// AES initialization function // AES initialization function
int n2n_transop_aes_cbc_init(const n2n_edge_conf_t *conf, n2n_trans_op_t *ttt) { int n2n_transop_aes_init(const n2n_edge_conf_t *conf, n2n_trans_op_t *ttt) {
transop_aes_t *priv; transop_aes_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);
memset(ttt, 0, sizeof(*ttt)); memset(ttt, 0, sizeof(*ttt));
ttt->transform_id = N2N_TRANSFORM_ID_AESCBC; ttt->transform_id = N2N_TRANSFORM_ID_AES;
ttt->tick = transop_tick_aes; ttt->tick = transop_tick_aes;
ttt->deinit = transop_deinit_aes; ttt->deinit = transop_deinit_aes;
@ -234,7 +233,7 @@ int n2n_transop_aes_cbc_init(const n2n_edge_conf_t *conf, n2n_trans_op_t *ttt) {
priv = (transop_aes_t*) calloc(1, sizeof(transop_aes_t)); priv = (transop_aes_t*) calloc(1, sizeof(transop_aes_t));
if(!priv) { if(!priv) {
traceEvent(TRACE_ERROR, "n2n_transop_aes_cbc_init cannot allocate transop_aes_t memory"); traceEvent(TRACE_ERROR, "n2n_transop_aes_init cannot allocate transop_aes_t memory");
return(-1); return(-1);
} }
ttt->priv = priv; ttt->priv = priv;
@ -242,5 +241,3 @@ int n2n_transop_aes_cbc_init(const n2n_edge_conf_t *conf, n2n_trans_op_t *ttt) {
// setup the cipher and key // setup the cipher and key
return(setup_aes_key(priv, encrypt_key, encrypt_key_len)); return(setup_aes_key(priv, encrypt_key, encrypt_key_len));
} }
#endif // N2N_HAVE_AES

View File

@ -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);
} }

View File

@ -40,7 +40,7 @@ typedef struct transop_tf {
static int transop_deinit_tf(n2n_trans_op_t *arg) { static int transop_deinit_tf(n2n_trans_op_t *arg) {
transop_tf_t *priv = (transop_tf_t *)arg->priv; transop_tf_t *priv = (transop_tf_t *)arg->priv;
if(priv->ctx) free(priv->ctx); if(priv->ctx) tf_deinit(priv->ctx);
if(priv) free(priv); if(priv) free(priv);
@ -81,12 +81,8 @@ static int transop_encode_tf(n2n_trans_op_t * arg,
traceEvent(TRACE_DEBUG, "transop_encode_tf %lu bytes plaintext", in_len); traceEvent(TRACE_DEBUG, "transop_encode_tf %lu bytes plaintext", in_len);
// full block sized random value (128 bit) // full block sized random value (128 bit)
// !!! replace with 2 calls to encode_uint64(...) as as available encode_uint64(assembly, &idx, n2n_rand());
// !!! which is still under consideration in pull request 'revAes' encode_uint64(assembly, &idx, n2n_rand());
encode_uint32(assembly, &idx, n2n_rand());
encode_uint32(assembly, &idx, n2n_rand());
encode_uint32(assembly, &idx, n2n_rand());
encode_uint32(assembly, &idx, n2n_rand());
// adjust for maybe differently chosen TF_PREAMBLE_SIZE // adjust for maybe differently chosen TF_PREAMBLE_SIZE
idx = TF_PREAMBLE_SIZE; idx = TF_PREAMBLE_SIZE;
@ -210,6 +206,7 @@ static void transop_tick_tf(n2n_trans_op_t * arg, time_t now) { ; }
// Twofish initialization function // Twofish initialization function
int n2n_transop_tf_init(const n2n_edge_conf_t *conf, n2n_trans_op_t *ttt) { int n2n_transop_tf_init(const n2n_edge_conf_t *conf, n2n_trans_op_t *ttt) {
transop_tf_t *priv; transop_tf_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);
@ -225,10 +222,10 @@ int n2n_transop_tf_init(const n2n_edge_conf_t *conf, n2n_trans_op_t *ttt) {
priv = (transop_tf_t*) calloc(1, sizeof(transop_tf_t)); priv = (transop_tf_t*) calloc(1, sizeof(transop_tf_t));
if(!priv) { if(!priv) {
traceEvent(TRACE_ERROR, "n2n_transop_tf_cbc_init cannot allocate transop_tf_t memory"); traceEvent(TRACE_ERROR, "n2n_transop_tf_cbc_init cannot allocate transop_tf_t memory");
return(-1); return -1;
} }
ttt->priv = priv; ttt->priv = priv;
// setup the cipher and key // setup the cipher and key
return(setup_tf_key(priv, encrypt_key, encrypt_key_len)); return setup_tf_key(priv, encrypt_key, encrypt_key_len);
} }

View File

@ -63,9 +63,8 @@ static void parseArgs(int argc, char * argv[]) {
int main(int argc, char * argv[]) { int main(int argc, char * argv[]) {
uint8_t pktbuf[N2N_PKT_BUF_SIZE]; uint8_t pktbuf[N2N_PKT_BUF_SIZE];
n2n_trans_op_t transop_null, transop_tf; n2n_trans_op_t transop_null, transop_tf;
#ifdef N2N_HAVE_AES
n2n_trans_op_t transop_aes_cbc; n2n_trans_op_t transop_aes_cbc;
#endif n2n_trans_op_t transop_aes;
n2n_trans_op_t transop_cc20; n2n_trans_op_t transop_cc20;
n2n_trans_op_t transop_speck; n2n_trans_op_t transop_speck;
@ -81,27 +80,22 @@ int main(int argc, char * argv[]) {
/* Init transopts */ /* Init transopts */
n2n_transop_null_init(&conf, &transop_null); n2n_transop_null_init(&conf, &transop_null);
n2n_transop_tf_init(&conf, &transop_tf); n2n_transop_tf_init(&conf, &transop_tf);
#ifdef N2N_HAVE_AES
n2n_transop_aes_cbc_init(&conf, &transop_aes_cbc); n2n_transop_aes_cbc_init(&conf, &transop_aes_cbc);
#endif n2n_transop_aes_init(&conf, &transop_aes);
n2n_transop_cc20_init(&conf, &transop_cc20); n2n_transop_cc20_init(&conf, &transop_cc20);
n2n_transop_speck_init(&conf, &transop_speck); n2n_transop_speck_init(&conf, &transop_speck);
/* Run the tests */ /* Run the tests */
run_transop_benchmark("transop_null", &transop_null, &conf, pktbuf); run_transop_benchmark("transop_null", &transop_null, &conf, pktbuf);
run_transop_benchmark("transop_tf", &transop_tf, &conf, pktbuf); run_transop_benchmark("transop_tf", &transop_tf, &conf, pktbuf);
#ifdef N2N_HAVE_AES run_transop_benchmark("transop_aes", &transop_aes, &conf, pktbuf);
run_transop_benchmark("transop_aes", &transop_aes_cbc, &conf, pktbuf);
#endif
run_transop_benchmark("transop_cc20", &transop_cc20, &conf, pktbuf); run_transop_benchmark("transop_cc20", &transop_cc20, &conf, pktbuf);
run_transop_benchmark("transop_speck", &transop_speck, &conf, pktbuf); run_transop_benchmark("transop_speck", &transop_speck, &conf, pktbuf);
/* Cleanup */ /* Cleanup */
transop_null.deinit(&transop_null); transop_null.deinit(&transop_null);
transop_tf.deinit(&transop_tf); transop_tf.deinit(&transop_tf);
#ifdef N2N_HAVE_AES transop_aes.deinit(&transop_aes);
transop_aes_cbc.deinit(&transop_aes_cbc);
#endif
transop_cc20.deinit(&transop_cc20); transop_cc20.deinit(&transop_cc20);
transop_speck.deinit(&transop_speck); transop_speck.deinit(&transop_speck);

View File

@ -44,7 +44,7 @@ static void help() {
fprintf(stderr, "-c <community> | Specify the community.\n"); fprintf(stderr, "-c <community> | Specify the community.\n");
fprintf(stderr, "-k <key> | Specify the encryption key.\n"); fprintf(stderr, "-k <key> | Specify the encryption key.\n");
#ifdef N2N_HAVE_AES #ifdef N2N_HAVE_AES
fprintf(stderr, "-A | Use AES CBC decryption (default=use twofish).\n"); fprintf(stderr, "-A | Use AES decryption (default=use twofish).\n");
#endif #endif
fprintf(stderr, "-B <bpf> | Use set a BPF filter for the capture.\n"); fprintf(stderr, "-B <bpf> | Use set a BPF filter for the capture.\n");
fprintf(stderr, "-w <fname> | Write decoded PCAP to file.\n"); fprintf(stderr, "-w <fname> | Write decoded PCAP to file.\n");
@ -103,7 +103,7 @@ static int decode_encrypted_packet(const u_char *packet, struct pcap_pkthdr *hea
return(-1); return(-1);
} }
break; break;
case N2N_TRANSFORM_ID_AESCBC: case N2N_TRANSFORM_ID_AES:
if(!aes_mode) { if(!aes_mode) {
traceEvent(TRACE_INFO, "Skipping AES encrypted packet"); traceEvent(TRACE_INFO, "Skipping AES encrypted packet");
return(-1); return(-1);
@ -280,7 +280,7 @@ int main(int argc, char* argv[]) {
#ifdef N2N_HAVE_AES #ifdef N2N_HAVE_AES
if(aes_mode) if(aes_mode)
n2n_transop_aes_cbc_init(&conf, &transop); n2n_transop_aes_init(&conf, &transop);
else else
#endif #endif
n2n_transop_tf_init(&conf, &transop); n2n_transop_tf_init(&conf, &transop);