diff --git a/edge.c b/edge.c index d1945bd..04f232c 100644 --- a/edge.c +++ b/edge.c @@ -150,7 +150,7 @@ static void help() { #endif /* #ifndef WIN32 */ #ifdef __linux__ "[-T ]" - "[-n cidr:gateway] " + "[-n cidr:gateway] " #endif "[-m ] " "-l \n" @@ -159,7 +159,7 @@ static void help() { #ifndef __APPLE__ "[-D] " #endif - "[-r] [-E] [-v] [-i ] [-L ] [-t ] [-A[]] [-z[]] [-h]\n\n"); + "[-r] [-E] [-v] [-i ] [-L ] [-t ] [-A[]] [-z[]] [-h]\n\n"); #if defined(N2N_CAN_NAME_IFACE) printf("-d | tun device name\n"); @@ -340,8 +340,6 @@ static int setOption(int optkey, char *optargument, n2n_priv_config_t *ec, n2n_e case 'k': /* encrypt key */ { if(conf->encrypt_key) free(conf->encrypt_key); - if(conf->transop_id == N2N_TRANSFORM_ID_NULL) - conf->transop_id = N2N_TRANSFORM_ID_TWOFISH; conf->encrypt_key = strdup(optargument); traceEvent(TRACE_DEBUG, "encrypt_key = '%s'\n", conf->encrypt_key); break; @@ -361,7 +359,7 @@ static int setOption(int optkey, char *optargument, n2n_priv_config_t *ec, n2n_e cipher = atoi(optargument); } else { 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-CBC cipher for payload encryption."); cipher = N2N_TRANSFORM_ID_AESCBC; // default, if '-A' only } @@ -529,14 +527,14 @@ static int setOption(int optkey, char *optargument, n2n_priv_config_t *ec, n2n_e /* *********************************************** */ static const struct option long_options[] = { - { "community", required_argument, NULL, 'c' }, - { "supernode-list", required_argument, NULL, 'l' }, - { "tun-device", required_argument, NULL, 'd' }, - { "euid", required_argument, NULL, 'u' }, - { "egid", required_argument, NULL, 'g' }, - { "help" , no_argument, NULL, 'h' }, - { "verbose", no_argument, NULL, 'v' }, - { NULL, 0, NULL, 0 } + { "community", required_argument, NULL, 'c' }, + { "supernode-list", required_argument, NULL, 'l' }, + { "tun-device", required_argument, NULL, 'd' }, + { "euid", required_argument, NULL, 'u' }, + { "egid", required_argument, NULL, 'g' }, + { "help" , no_argument, NULL, 'h' }, + { "verbose", no_argument, NULL, 'v' }, + { NULL, 0, NULL, 0 } }; /* *************************************************** */ @@ -660,18 +658,18 @@ static int loadFromFile(const char *path, n2n_edge_conf_t *conf, n2n_priv_config #if defined(DUMMY_ID_00001) /* Disabled waiting for config option to enable it */ static char gratuitous_arp[] = { - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* Dest mac */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Src mac */ - 0x08, 0x06, /* ARP */ - 0x00, 0x01, /* Ethernet */ - 0x08, 0x00, /* IP */ - 0x06, /* Hw Size */ - 0x04, /* Protocol Size */ - 0x00, 0x01, /* ARP Request */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Src mac */ - 0x00, 0x00, 0x00, 0x00, /* Src IP */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Target mac */ - 0x00, 0x00, 0x00, 0x00 /* Target IP */ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* Dest mac */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Src mac */ + 0x08, 0x06, /* ARP */ + 0x00, 0x01, /* Ethernet */ + 0x08, 0x00, /* IP */ + 0x06, /* Hw Size */ + 0x04, /* Protocol Size */ + 0x00, 0x01, /* ARP Request */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Src mac */ + 0x00, 0x00, 0x00, 0x00, /* Src IP */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Target mac */ + 0x00, 0x00, 0x00, 0x00 /* Target IP */ }; /* ************************************** */ @@ -763,7 +761,7 @@ static int keep_on_running; #ifdef WIN32 BOOL WINAPI term_handler(DWORD sig) #else -static void term_handler(int sig) + static void term_handler(int sig) #endif { static int called = 0; @@ -832,9 +830,17 @@ int main(int argc, char* argv[]) { /* Load from current directory */ rc = loadFromFile("edge.conf", &conf, &ec); #else - rc = -1; + rc = -1; #endif + if(conf.transop_id == N2N_TRANSFORM_ID_NULL) { + if(conf.encrypt_key) { + traceEvent(TRACE_WARNING, "Ignoring -k as -A1 was set"); + free(conf.encrypt_key); + conf.encrypt_key = NULL; + } + } + if(rc < 0) help(); diff --git a/speck.c b/speck.c index 9b05968..589cd19 100644 --- a/speck.c +++ b/speck.c @@ -6,6 +6,7 @@ #include #include +#include "speck.h" #if defined (__AVX2__) // AVX support ---------------------------------------------------- @@ -89,134 +90,134 @@ 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)) typedef struct { - u256 rk[34]; - u64 key[34]; + u256 rk[34]; + u64 key[34]; } speck_context_t; static int speck_encrypt_xor(unsigned char *out, const unsigned char *in, u64 nonce[], speck_context_t *ctx, int numbytes) { - u64 x[2], y[2]; - u256 X[4], Y[4], Z[4]; - - if (numbytes == 16) { - x[0] = nonce[1]; y[0] = nonce[0]; nonce[0]++; - Encrypt (x, y, ctx->key, 1); - ((u64 *)out)[1] = x[0]; ((u64 *)out)[0] = y[0]; - return 0; - } - - if (numbytes == 32) { - x[0] = nonce[1]; y[0] = nonce[0]; nonce[0]++; - x[1] = nonce[1]; y[1] = nonce[0]; nonce[0]++; - Encrypt (x , y, ctx->key, 2); - ((u64 *)out)[1] = x[0] ^ ((u64 *)in)[1]; ((u64 *)out)[0] = y[0] ^ ((u64 *)in)[0]; - ((u64 *)out)[3] = x[1] ^ ((u64 *)in)[3]; ((u64 *)out)[2] = y[1] ^ ((u64 *)in)[2]; - return 0; - } - - SET1 (X[0], nonce[1]); SET4 (Y[0], nonce[0]); - - if (numbytes == 64) - Encrypt (X, Y, ctx->rk, 4); - else { - X[1] = X[0]; - Y[1] = ADD (Y[0], _four); - if (numbytes == 128) - Encrypt (X, Y, ctx->rk, 8); - else { - X[2] = X[0]; - Y[2] = ADD (Y[1], _four); - if (numbytes == 192) - Encrypt (X, Y, ctx->rk, 12); - else { - X[3] = X[0]; - Y[3] = ADD (Y[2], _four); - Encrypt (X, Y, ctx->rk, 16); - } - } - } - - nonce[0] += (numbytes>>4); - - XOR_STORE (in, out, X[0], Y[0]); - if (numbytes >= 128) - XOR_STORE (in + 64, out + 64, X[1], Y[1]); - if (numbytes >= 192) - XOR_STORE (in + 128, out + 128, X[2], Y[2]); - if (numbytes >= 256) - XOR_STORE (in + 192, out + 192, X[3], Y[3]); - - return 0; + u64 x[2], y[2]; + u256 X[4], Y[4], Z[4]; + + if (numbytes == 16) { + x[0] = nonce[1]; y[0] = nonce[0]; nonce[0]++; + Encrypt (x, y, ctx->key, 1); + ((u64 *)out)[1] = x[0]; ((u64 *)out)[0] = y[0]; + return 0; + } + + if (numbytes == 32) { + x[0] = nonce[1]; y[0] = nonce[0]; nonce[0]++; + x[1] = nonce[1]; y[1] = nonce[0]; nonce[0]++; + Encrypt (x , y, ctx->key, 2); + ((u64 *)out)[1] = x[0] ^ ((u64 *)in)[1]; ((u64 *)out)[0] = y[0] ^ ((u64 *)in)[0]; + ((u64 *)out)[3] = x[1] ^ ((u64 *)in)[3]; ((u64 *)out)[2] = y[1] ^ ((u64 *)in)[2]; + return 0; + } + + SET1 (X[0], nonce[1]); SET4 (Y[0], nonce[0]); + + if (numbytes == 64) + Encrypt (X, Y, ctx->rk, 4); + else { + X[1] = X[0]; + Y[1] = ADD (Y[0], _four); + if (numbytes == 128) + Encrypt (X, Y, ctx->rk, 8); + else { + X[2] = X[0]; + Y[2] = ADD (Y[1], _four); + if (numbytes == 192) + Encrypt (X, Y, ctx->rk, 12); + else { + X[3] = X[0]; + Y[3] = ADD (Y[2], _four); + Encrypt (X, Y, ctx->rk, 16); + } + } + } + + nonce[0] += (numbytes>>4); + + XOR_STORE (in, out, X[0], Y[0]); + if (numbytes >= 128) + XOR_STORE (in + 64, out + 64, X[1], Y[1]); + if (numbytes >= 192) + XOR_STORE (in + 128, out + 128, X[2], Y[2]); + if (numbytes >= 256) + XOR_STORE (in + 192, out + 192, X[3], Y[3]); + + return 0; } int speck_ctr( unsigned char *out, const unsigned char *in, unsigned long long inlen, const unsigned char *n, speck_context_t *ctx) { - int i; - u64 nonce[2]; - unsigned char block[16]; - u64 * const block64 = (u64 *)block; - - if (!inlen) - return 0; - - nonce[0] = ((u64 *)n)[0]; - nonce[1] = ((u64 *)n)[1]; - - while (inlen >= 256) { - speck_encrypt_xor (out, in, nonce, ctx, 256); - in += 256; inlen -= 256; out += 256; - } - - if (inlen >= 192) { - speck_encrypt_xor (out, in, nonce, ctx, 192); - in += 192; inlen -= 192; out += 192; - } - - if (inlen >= 128) { - speck_encrypt_xor (out, in, nonce, ctx, 128); - in += 128; inlen -= 128; out += 128; - } - - if (inlen >= 64) { - speck_encrypt_xor (out, in, nonce, ctx, 64); - in += 64; inlen -= 64; out += 64; - } - - if (inlen >= 32) { - speck_encrypt_xor (out, in, nonce, ctx, 32); - in += 32; inlen -= 32; out += 32; - } - - if (inlen >= 16) { - speck_encrypt_xor (block, in, nonce, ctx, 16); - ((u64 *)out)[0] = block64[0] ^ ((u64 *)in)[0]; - ((u64 *)out)[1] = block64[1] ^ ((u64 *)in)[1]; - in += 16; inlen -= 16; out += 16; - } - - if (inlen > 0) { - speck_encrypt_xor (block, in, nonce, ctx, 16); - for (i = 0; i < inlen; i++) - out[i] = block[i] ^ in[i]; - } - - return 0; + int i; + u64 nonce[2]; + unsigned char block[16]; + u64 * const block64 = (u64 *)block; + + if (!inlen) + return 0; + + nonce[0] = ((u64 *)n)[0]; + nonce[1] = ((u64 *)n)[1]; + + while (inlen >= 256) { + speck_encrypt_xor (out, in, nonce, ctx, 256); + in += 256; inlen -= 256; out += 256; + } + + if (inlen >= 192) { + speck_encrypt_xor (out, in, nonce, ctx, 192); + in += 192; inlen -= 192; out += 192; + } + + if (inlen >= 128) { + speck_encrypt_xor (out, in, nonce, ctx, 128); + in += 128; inlen -= 128; out += 128; + } + + if (inlen >= 64) { + speck_encrypt_xor (out, in, nonce, ctx, 64); + in += 64; inlen -= 64; out += 64; + } + + if (inlen >= 32) { + speck_encrypt_xor (out, in, nonce, ctx, 32); + in += 32; inlen -= 32; out += 32; + } + + if (inlen >= 16) { + speck_encrypt_xor (block, in, nonce, ctx, 16); + ((u64 *)out)[0] = block64[0] ^ ((u64 *)in)[0]; + ((u64 *)out)[1] = block64[1] ^ ((u64 *)in)[1]; + in += 16; inlen -= 16; out += 16; + } + + if (inlen > 0) { + speck_encrypt_xor (block, in, nonce, ctx, 16); + for (i = 0; i < inlen; i++) + out[i] = block[i] ^ in[i]; + } + + return 0; } int speck_expand_key (const unsigned char *k, speck_context_t *ctx) { - u64 K[4]; - size_t i; - for (i = 0; i < numkeywords; i++) - K[i] = ((u64 *)k)[i]; + u64 K[4]; + size_t i; + for (i = 0; i < numkeywords; i++) + K[i] = ((u64 *)k)[i]; - EK (K[0], K[1], K[2], K[3], ctx->rk, ctx->key); + EK (K[0], K[1], K[2], K[3], ctx->rk, ctx->key); - return 0; + return 0; } @@ -301,117 +302,117 @@ 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)) typedef struct { - u128 rk[34]; - u64 key[34]; + u128 rk[34]; + u64 key[34]; } speck_context_t; 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]; - u128 X[4], Y[4], Z[4]; - - if (numbytes == 16) { - x[0] = nonce[1]; y[0] = nonce[0]; nonce[0]++; - Encrypt (x, y, ctx.key, 1); - ((u64 *)out)[1] = x[0]; ((u64 *)out)[0] = y[0]; - return 0; - } - - SET1 (X[0], nonce[1]); SET2 (Y[0], nonce[0]); - - if (numbytes == 32) - Encrypt (X, Y, ctx.rk, 2); - else { - X[1] = X[0]; Y[1] = ADD (Y[0], _two); - if (numbytes == 64) - Encrypt (X, Y, ctx.rk, 4); - else { - X[2] = X[0]; Y[2] = ADD (Y[1], _two); - if (numbytes == 96) - Encrypt (X, Y, ctx.rk, 6); - else { - X[3] = X[0]; Y[3] = ADD (Y[2], _two); - Encrypt (X, Y, ctx.rk, 8); - } - } - } - - nonce[0] += (numbytes>>4); - - XOR_STORE (in, out, X[0], Y[0]); - if (numbytes >= 64) - XOR_STORE (in + 32, out + 32, X[1], Y[1]); - if (numbytes >= 96) - XOR_STORE (in + 64, out + 64, X[2], Y[2]); - if (numbytes >= 128) - XOR_STORE (in + 96, out + 96, X[3], Y[3]); - - return 0; + u64 x[2], y[2]; + u128 X[4], Y[4], Z[4]; + + if (numbytes == 16) { + x[0] = nonce[1]; y[0] = nonce[0]; nonce[0]++; + Encrypt (x, y, ctx.key, 1); + ((u64 *)out)[1] = x[0]; ((u64 *)out)[0] = y[0]; + return 0; + } + + SET1 (X[0], nonce[1]); SET2 (Y[0], nonce[0]); + + if (numbytes == 32) + Encrypt (X, Y, ctx.rk, 2); + else { + X[1] = X[0]; Y[1] = ADD (Y[0], _two); + if (numbytes == 64) + Encrypt (X, Y, ctx.rk, 4); + else { + X[2] = X[0]; Y[2] = ADD (Y[1], _two); + if (numbytes == 96) + Encrypt (X, Y, ctx.rk, 6); + else { + X[3] = X[0]; Y[3] = ADD (Y[2], _two); + Encrypt (X, Y, ctx.rk, 8); + } + } + } + + nonce[0] += (numbytes>>4); + + XOR_STORE (in, out, X[0], Y[0]); + if (numbytes >= 64) + XOR_STORE (in + 32, out + 32, X[1], Y[1]); + if (numbytes >= 96) + XOR_STORE (in + 64, out + 64, X[2], Y[2]); + if (numbytes >= 128) + XOR_STORE (in + 96, out + 96, X[3], Y[3]); + + return 0; } int speck_ctr (unsigned char *out, const unsigned char *in, unsigned long long inlen, const unsigned char *n, const speck_context_t ctx) { - int i; - u64 nonce[2]; - unsigned char block[16]; - u64 * const block64 = (u64 *)block; - - if (!inlen) - return 0; - - nonce[0] = ((u64 *)n)[0]; - nonce[1] = ((u64 *)n)[1]; - - while (inlen >= 128) { - speck_encrypt_xor (out, in, nonce, ctx, 128); - in += 128; inlen -= 128; out += 128; - } - - if (inlen >= 96) { - speck_encrypt_xor (out, in, nonce, ctx, 96); - in += 96; inlen -= 96; out += 96; - } - - if (inlen >= 64) { - speck_encrypt_xor (out, in, nonce, ctx, 64); - in += 64; inlen -= 64; out += 64; - } - - if (inlen >= 32) { - speck_encrypt_xor (out, in, nonce, ctx, 32); - in += 32; inlen -= 32; out += 32; - } - - if (inlen >= 16) { - speck_encrypt_xor (block, in, nonce, ctx, 16); - ((u64 *)out)[0] = block64[0] ^ ((u64 *)in)[0]; - ((u64 *)out)[1] = block64[1] ^ ((u64 *)in)[1]; - in += 16; inlen -= 16; out += 16; - } - - if (inlen > 0) { - speck_encrypt_xor (block, in, nonce, ctx, 16); - for (i = 0; i < inlen; i++) - out[i] = block[i] ^ in[i]; - } - - return 0; + int i; + u64 nonce[2]; + unsigned char block[16]; + u64 * const block64 = (u64 *)block; + + if (!inlen) + return 0; + + nonce[0] = ((u64 *)n)[0]; + nonce[1] = ((u64 *)n)[1]; + + while (inlen >= 128) { + speck_encrypt_xor (out, in, nonce, ctx, 128); + in += 128; inlen -= 128; out += 128; + } + + if (inlen >= 96) { + speck_encrypt_xor (out, in, nonce, ctx, 96); + in += 96; inlen -= 96; out += 96; + } + + if (inlen >= 64) { + speck_encrypt_xor (out, in, nonce, ctx, 64); + in += 64; inlen -= 64; out += 64; + } + + if (inlen >= 32) { + speck_encrypt_xor (out, in, nonce, ctx, 32); + in += 32; inlen -= 32; out += 32; + } + + if (inlen >= 16) { + speck_encrypt_xor (block, in, nonce, ctx, 16); + ((u64 *)out)[0] = block64[0] ^ ((u64 *)in)[0]; + ((u64 *)out)[1] = block64[1] ^ ((u64 *)in)[1]; + in += 16; inlen -= 16; out += 16; + } + + if (inlen > 0) { + speck_encrypt_xor (block, in, nonce, ctx, 16); + for (i = 0; i < inlen; i++) + out[i] = block[i] ^ in[i]; + } + + return 0; } int speck_expand_key (const unsigned char *k, speck_context_t *ctx) { - u64 K[4]; - size_t i; - for (i = 0; i < numkeywords; i++) - K[i] = ((u64 *)k)[i]; + u64 K[4]; + size_t i; + for (i = 0; i < numkeywords; i++) + K[i] = ((u64 *)k)[i]; - EK (K[0], K[1], K[2], K[3], ctx->rk, ctx->key); + EK (K[0], K[1], K[2], K[3], ctx->rk, ctx->key); - return 0; + return 0; } @@ -485,115 +486,115 @@ 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)) typedef struct { - u128 rk[34]; - u64 key[34]; + u128 rk[34]; + u64 key[34]; } speck_context_t; static int speck_encrypt_xor (unsigned char *out, const unsigned char *in, u64 nonce[], speck_context_t *ctx, int numbytes) { - u64 x[2], y[2]; - u128 X[4], Y[4], Z[4]; - - if (numbytes == 16) { - x[0] = nonce[1]; y[0]=nonce[0]; nonce[0]++; - Encrypt (x, y, ctx->key, 1); - ((u64 *)out)[1] = x[0]; ((u64 *)out)[0] = y[0]; - return 0; - } - - SET1 (X[0], nonce[1]); SET2 (Y[0], nonce[0]); - - if (numbytes == 32) - Encrypt (X, Y, ctx->rk, 2); - else { - X[1] = X[0]; SET2 (Y[1], nonce[0]); - if (numbytes == 64) - Encrypt (X, Y, ctx->rk, 4); - else { - X[2] = X[0]; SET2 (Y[2], nonce[0]); - if (numbytes == 96) - Encrypt (X, Y, ctx->rk, 6); - else { - X[3] = X[0]; SET2 (Y[3], nonce[0]); - Encrypt (X, Y, ctx->rk, 8); - } - } - } - - XOR_STORE (in, out, X[0], Y[0]); - if (numbytes >= 64) - XOR_STORE (in + 32, out + 32, X[1], Y[1]); - if (numbytes >= 96) - XOR_STORE (in + 64, out + 64, X[2], Y[2]); - if (numbytes >= 128) - XOR_STORE (in + 96, out + 96, X[3], Y[3]); - - return 0; + u64 x[2], y[2]; + u128 X[4], Y[4], Z[4]; + + if (numbytes == 16) { + x[0] = nonce[1]; y[0]=nonce[0]; nonce[0]++; + Encrypt (x, y, ctx->key, 1); + ((u64 *)out)[1] = x[0]; ((u64 *)out)[0] = y[0]; + return 0; + } + + SET1 (X[0], nonce[1]); SET2 (Y[0], nonce[0]); + + if (numbytes == 32) + Encrypt (X, Y, ctx->rk, 2); + else { + X[1] = X[0]; SET2 (Y[1], nonce[0]); + if (numbytes == 64) + Encrypt (X, Y, ctx->rk, 4); + else { + X[2] = X[0]; SET2 (Y[2], nonce[0]); + if (numbytes == 96) + Encrypt (X, Y, ctx->rk, 6); + else { + X[3] = X[0]; SET2 (Y[3], nonce[0]); + Encrypt (X, Y, ctx->rk, 8); + } + } + } + + XOR_STORE (in, out, X[0], Y[0]); + if (numbytes >= 64) + XOR_STORE (in + 32, out + 32, X[1], Y[1]); + if (numbytes >= 96) + XOR_STORE (in + 64, out + 64, X[2], Y[2]); + if (numbytes >= 128) + XOR_STORE (in + 96, out + 96, X[3], Y[3]); + + return 0; } int speck_ctr (unsigned char *out, const unsigned char *in, unsigned long long inlen, const unsigned char *n, speck_context_t *ctx) { - int i; - u64 nonce[2]; - unsigned char block[16]; - u64 *const block64 = (u64 *)block; - - if (!inlen) - return 0; - - nonce[0] = ((u64 *)n)[0]; - nonce[1] = ((u64 *)n)[1]; - - while (inlen >= 128) { - speck_encrypt_xor (out, in, nonce, ctx, 128); - in += 128; inlen -= 128; out += 128; - } - - if (inlen >= 96) { - speck_encrypt_xor (out, in, nonce, ctx, 96); - in += 96; inlen -= 96; out += 96; - } - - if (inlen >= 64) { - speck_encrypt_xor (out, in, nonce, ctx, 64); - in += 64; inlen -= 64; out += 64; - } - - if (inlen >= 32) { - speck_encrypt_xor (out, in, nonce, ctx, 32); - in += 32; inlen -= 32; out += 32; - } - - if (inlen >= 16) { - speck_encrypt_xor (block, in, nonce, ctx, 16); - ((u64 *)out)[0] = block64[0] ^ ((u64 *)in)[0]; - ((u64 *)out)[1] = block64[1] ^ ((u64 *)in)[1]; - in += 16; inlen -= 16; out += 16; - } - - if (inlen > 0) { - speck_encrypt_xor (block, in, nonce, ctx, 16); - for (i = 0; i < inlen; i++) - out[i] = block[i] ^ in[i]; - } - - return 0; + int i; + u64 nonce[2]; + unsigned char block[16]; + u64 *const block64 = (u64 *)block; + + if (!inlen) + return 0; + + nonce[0] = ((u64 *)n)[0]; + nonce[1] = ((u64 *)n)[1]; + + while (inlen >= 128) { + speck_encrypt_xor (out, in, nonce, ctx, 128); + in += 128; inlen -= 128; out += 128; + } + + if (inlen >= 96) { + speck_encrypt_xor (out, in, nonce, ctx, 96); + in += 96; inlen -= 96; out += 96; + } + + if (inlen >= 64) { + speck_encrypt_xor (out, in, nonce, ctx, 64); + in += 64; inlen -= 64; out += 64; + } + + if (inlen >= 32) { + speck_encrypt_xor (out, in, nonce, ctx, 32); + in += 32; inlen -= 32; out += 32; + } + + if (inlen >= 16) { + speck_encrypt_xor (block, in, nonce, ctx, 16); + ((u64 *)out)[0] = block64[0] ^ ((u64 *)in)[0]; + ((u64 *)out)[1] = block64[1] ^ ((u64 *)in)[1]; + in += 16; inlen -= 16; out += 16; + } + + if (inlen > 0) { + speck_encrypt_xor (block, in, nonce, ctx, 16); + for (i = 0; i < inlen; i++) + out[i] = block[i] ^ in[i]; + } + + return 0; } int speck_expand_key (const unsigned char *k, speck_context_t *ctx) { - u64 K[4]; - size_t i; - for (i = 0; i < numkeywords; i++) - K[i] = ((u64 *)k)[i]; + u64 K[4]; + size_t i; + for (i = 0; i < numkeywords; i++) + K[i] = ((u64 *)k)[i]; - EK (K[0], K[1], K[2], K[3], ctx->rk, ctx->key); + EK (K[0], K[1], K[2], K[3], ctx->rk, ctx->key); - return 0; + return 0; } @@ -606,77 +607,73 @@ int speck_expand_key (const unsigned char *k, speck_context_t *ctx) { #define ROL64(x,r) (((x)<<(r))|((x)>>(64-(r)))) #define R(x,y,k) (x=ROR64(x,8), x+=y, x^=k, y=ROL64(y,3), y^=x) -typedef struct { - u64 key[34]; -} speck_context_t; - static int speck_encrypt (u64 *u, u64 *v, speck_context_t *ctx) { - u64 i, x = *u, y = *v; + u64 i, x = *u, y = *v; - for (i = 0; i < 34; i++) - R (x, y, ctx->key[i]); + for (i = 0; i < 34; i++) + R (x, y, ctx->key[i]); - *u = x; *v = y; + *u = x; *v = y; - return 0; + return 0; } int speck_ctr (unsigned char *out, const unsigned char *in, unsigned long long inlen, const unsigned char *n, speck_context_t *ctx) { - u64 i, nonce[2], x, y, t; - unsigned char *block = malloc (16); - - if (!inlen) { - free (block); - return 0; - } - nonce[0] = htole64 ( ((u64*)n)[0] ); - nonce[1] = htole64 ( ((u64*)n)[1] ); - - t=0; - while (inlen >= 16) { - x = nonce[1]; y = nonce[0]; nonce[0]++; - speck_encrypt (&x, &y, ctx); - ((u64 *)out)[1+t] = htole64 (x ^ ((u64 *)in)[1+t]); - ((u64 *)out)[0+t] = htole64 (y ^ ((u64 *)in)[0+t]); - t += 2; - inlen -= 16; - } - if (inlen > 0) { - x = nonce[1]; y = nonce[0]; - speck_encrypt (&x, &y, ctx); - ((u64 *)block)[1] = htole64 (x); ((u64 *)block)[0] = htole64 (y); - for (i = 0; i < inlen; i++) - out[i + 8*t] = block[i] ^ in[i + 8*t]; - } - - free (block); - return 0; + u64 i, nonce[2], x, y, t; + unsigned char *block = malloc (16); + + if (!inlen) { + free (block); + return 0; + } + nonce[0] = htole64 ( ((u64*)n)[0] ); + nonce[1] = htole64 ( ((u64*)n)[1] ); + + t=0; + while (inlen >= 16) { + x = nonce[1]; y = nonce[0]; nonce[0]++; + speck_encrypt (&x, &y, ctx); + ((u64 *)out)[1+t] = htole64 (x ^ ((u64 *)in)[1+t]); + ((u64 *)out)[0+t] = htole64 (y ^ ((u64 *)in)[0+t]); + t += 2; + inlen -= 16; + } + if (inlen > 0) { + x = nonce[1]; y = nonce[0]; + speck_encrypt (&x, &y, ctx); + ((u64 *)block)[1] = htole64 (x); ((u64 *)block)[0] = htole64 (y); + for (i = 0; i < inlen; i++) + out[i + 8*t] = block[i] ^ in[i + 8*t]; + } + + free (block); + return 0; } int speck_expand_key (const unsigned char *k, speck_context_t *ctx) { - u64 K[4]; - u64 i; - - for (i = 0; i < 4; i++) - K[i] = htole64 ( ((u64 *)k)[i] ); - - for (i = 0; i < 33; i += 3) { - ctx->key[i ] = K[0]; - R (K[1], K[0], i ); - ctx->key[i+1] = K[0]; - R (K[2], K[0], i + 1); - ctx->key[i+2] = K[0]; - R (K[3], K[0], i + 2); - } - ctx->key[33] = K[0]; - return 1; + u64 K[4]; + u64 i; + + for (i = 0; i < 4; i++) + K[i] = htole64 ( ((u64 *)k)[i] ); + + for (i = 0; i < 33; i += 3) { + ctx->key[i ] = K[0]; + R (K[1], K[0], i ); + ctx->key[i+1] = K[0]; + R (K[2], K[0], i + 1); + ctx->key[i+2] = K[0]; + R (K[3], K[0], i + 2); + } + ctx->key[33] = K[0]; + return 1; } @@ -685,45 +682,45 @@ int speck_expand_key (const unsigned char *k, speck_context_t *ctx) { 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 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 iv[16] = { 0x70, 0x6f, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x20, - 0x49, 0x6e, 0x20, 0x74, 0x68, 0x6f, 0x73, 0x65 }; + uint8_t iv[16] = { 0x70, 0x6f, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x20, + 0x49, 0x6e, 0x20, 0x74, 0x68, 0x6f, 0x73, 0x65 }; - uint8_t pt[16] = { 0x00 }; + uint8_t pt[16] = { 0x00 }; - // expected outcome (according to pp. 35 & 36 of Implementation Guide) - uint8_t ct[16] = { 0x43, 0x8f, 0x18, 0x9c, 0x8d, 0xb4, 0xee, 0x4e, - 0x3e, 0xf5, 0xc0, 0x05, 0x04, 0x01, 0x09, 0x41 }; + // expected outcome (according to pp. 35 & 36 of Implementation Guide) + uint8_t ct[16] = { 0x43, 0x8f, 0x18, 0x9c, 0x8d, 0xb4, 0xee, 0x4e, + 0x3e, 0xf5, 0xc0, 0x05, 0x04, 0x01, 0x09, 0x41 }; - speck_context_t ctx; + speck_context_t ctx; - speck_expand_key (key, &ctx); + speck_expand_key (key, &ctx); #if defined (SPECK_CTX_BYVAL) - speck_ctr (pt, pt, 16, iv, ctx); + speck_ctr (pt, pt, 16, iv, ctx); #else - speck_ctr (pt, pt, 16, iv, &ctx); + 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"); + 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; + int ret = 1; + for (i=0; i < 16; i++) + if (pt[i] != ct[i]) ret = 0; - return (ret); + return (ret); } /* -int main (int argc, char* argv[]) { + int main (int argc, char* argv[]) { - fprintf (stdout, "SPECK SELF TEST RESULT: %u\n", speck_test (0,NULL)); -} + fprintf (stdout, "SPECK SELF TEST RESULT: %u\n", speck_test (0,NULL)); + } */ diff --git a/speck.h b/speck.h index b7a498b..df5ab58 100644 --- a/speck.h +++ b/speck.h @@ -1,3 +1,12 @@ +// cipher SPECK -- 128 bit block size -- 256 bit key size +// 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/ + +#ifdef __APPLE__ +#include +#define htole64(x) OSSwapHostToLittleInt64(x) +#endif + #define u64 uint64_t #if defined (__AVX2__) @@ -6,8 +15,8 @@ #include #define u256 __m256i typedef struct { - u256 rk[34]; - u64 key[34]; + u256 rk[34]; + u64 key[34]; } speck_context_t; #elif defined (__SSE4_2__) @@ -17,8 +26,8 @@ typedef struct { #include #define u128 __m128i typedef struct { - u128 rk[34]; - u64 key[34]; + u128 rk[34]; + u64 key[34]; } speck_context_t; #elif defined (__ARM_NEON) @@ -26,14 +35,14 @@ typedef struct { #include #define u128 uint64x2_t typedef struct { - u128 rk[34]; - u64 key[34]; + u128 rk[34]; + u64 key[34]; } speck_context_t; #else typedef struct { - u64 key[34]; + u64 key[34]; } speck_context_t; #endif @@ -44,7 +53,7 @@ int speck_ctr (unsigned char *out, const unsigned char *in, unsigned long long i #if defined (SPECK_CTX_BYVAL) speck_context_t ctx); #else - speck_context_t *ctx); +speck_context_t *ctx); #endif