mirror of
https://github.com/ntop/n2n.git
synced 2024-09-20 00:51:10 +02:00
prepared header encryption
This commit is contained in:
parent
105cc40bd4
commit
43feafa1b6
|
@ -61,8 +61,12 @@ add_library(n2n n2n.c
|
||||||
transform_null.c
|
transform_null.c
|
||||||
transform_tf.c
|
transform_tf.c
|
||||||
transform_aes.c
|
transform_aes.c
|
||||||
|
transform_cc20.c
|
||||||
|
transform_speck.c
|
||||||
|
speck.c
|
||||||
random_numbers.c
|
random_numbers.c
|
||||||
pearson.c
|
pearson.c
|
||||||
|
header_encryption.c
|
||||||
tuntap_freebsd.c
|
tuntap_freebsd.c
|
||||||
tuntap_netbsd.c
|
tuntap_netbsd.c
|
||||||
tuntap_linux.c
|
tuntap_linux.c
|
||||||
|
|
|
@ -51,7 +51,7 @@ N2N_LIB=libn2n.a
|
||||||
N2N_OBJS=n2n.o wire.o minilzo.o twofish.o speck.o \
|
N2N_OBJS=n2n.o wire.o minilzo.o twofish.o speck.o \
|
||||||
edge_utils.o sn_utils.o \
|
edge_utils.o sn_utils.o \
|
||||||
transform_null.o transform_tf.o transform_aes.o transform_cc20.o transform_speck.o \
|
transform_null.o transform_tf.o transform_aes.o transform_cc20.o transform_speck.o \
|
||||||
pearson.o \
|
header_encryption.o pearson.o \
|
||||||
tuntap_freebsd.o tuntap_netbsd.o tuntap_linux.o random_numbers.o \
|
tuntap_freebsd.o tuntap_netbsd.o tuntap_linux.o random_numbers.o \
|
||||||
tuntap_osx.o
|
tuntap_osx.o
|
||||||
LIBS_EDGE+=$(LIBS_EDGE_OPT)
|
LIBS_EDGE+=$(LIBS_EDGE_OPT)
|
||||||
|
|
|
@ -1,35 +1,38 @@
|
||||||
#include <stdio.h>
|
#include "header_encryption.h"
|
||||||
#include <stdint.h>
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
// #include "n2n_wire.h" // n2n_community_t
|
|
||||||
#include "n2n.h"
|
#include "n2n.h"
|
||||||
#include "speck.h"
|
#include "random_numbers.h"
|
||||||
|
#include "pearson.h"
|
||||||
#include "portable_endian.h"
|
#include "portable_endian.h"
|
||||||
|
|
||||||
|
|
||||||
uint32_t decryt_packet_header (uint8_t packet[], uint8_t packet_len,
|
#include <stdio.h>
|
||||||
char * community_name, speck_ctx * ctx) {
|
|
||||||
|
|
||||||
|
uint32_t packet_header_decrypt (uint8_t packet[], uint8_t packet_len,
|
||||||
|
char * community_name, he_context_t * ctx) {
|
||||||
|
|
||||||
// assemble IV
|
// assemble IV
|
||||||
// the last four are ASCII "n2n!" and do not get overwritten
|
// the last four are ASCII "n2n!" and do not get overwritten
|
||||||
uint8_t iv[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
uint8_t iv[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x6E, 0x32, 0x6E, 0x21 };
|
0x00, 0x00, 0x00, 0x00, 0x6E, 0x32, 0x6E, 0x21 };
|
||||||
// the first 96 bits of the packet are used padded with ASCII "n2n!"
|
// the first 96 bits of the packet get padded with ASCII "n2n!"
|
||||||
// to full 128 bit IV
|
// to full 128 bit IV
|
||||||
memcopy (iv, packet, 12);
|
memcpy (iv, packet, 12);
|
||||||
|
// alternatively, consider: pearson_hash_128 (iv, packet, 12);
|
||||||
// alternatively, consider: pearson_hash_128 (iv, packet, 12)
|
|
||||||
|
|
||||||
// try community name as possible key and check for magic bytes
|
// try community name as possible key and check for magic bytes
|
||||||
uint32_t magic = 0x6E326E00; // ="n2n_"
|
uint32_t magic = 0x6E326E00; // ="n2n_"
|
||||||
uint32_t test_magic;
|
uint32_t test_magic;
|
||||||
// check for magic bytes and resonable value in header len field
|
// check for magic bytes and resonable value in header len field
|
||||||
speck_he ((uint8_t*)&test_magic, &packet[12], 4, iv, ctx);
|
speck_he ((uint8_t*)&test_magic, &packet[12], 4, iv, (speck_context_t*)ctx);
|
||||||
test_magic = be32toh (test_magic);
|
test_magic = be32toh (test_magic);
|
||||||
if ( ((test_magic << 8) == magic)
|
if ( ((test_magic << 8) == magic)
|
||||||
&& ((test_magic >> 24) <= packet_len) // (test_masgic >> 24) is header_len
|
&& ((test_magic >> 24) <= packet_len) // (test_masgic >> 24) is header_len
|
||||||
) {
|
) {
|
||||||
speck_he (&packet[12], &packet[12], (test_magic >> 24) - 12, iv, ctx);
|
speck_he (&packet[12], &packet[12], (test_magic >> 24) - 12, iv, (speck_context_t*)ctx);
|
||||||
// restore original packet order
|
// restore original packet order
|
||||||
memcpy (&packet[0], &packet[16], 4);
|
memcpy (&packet[0], &packet[16], 4);
|
||||||
memcpy (&packet[4], community_name, N2N_COMMUNITY_SIZE);
|
memcpy (&packet[4], community_name, N2N_COMMUNITY_SIZE);
|
||||||
|
@ -39,7 +42,7 @@ uint32_t decryt_packet_header (uint8_t packet[], uint8_t packet_len,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int32_t decryt_packet_header_if_required (uint8_t packet[], uint16_t packet_len,
|
int32_t packet_header_decrypt_if_required (uint8_t packet[], uint16_t packet_len,
|
||||||
struct sn_community *communities) {
|
struct sn_community *communities) {
|
||||||
|
|
||||||
if (packet_len < 20)
|
if (packet_len < 20)
|
||||||
|
@ -58,8 +61,12 @@ int32_t decryt_packet_header_if_required (uint8_t packet[], uint16_t packet_len,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
// most probably unencrypted
|
// most probably unencrypted
|
||||||
return (1);
|
|
||||||
|
|
||||||
|
// TODO:
|
||||||
|
// !!! make sure, no downgrading happens here !!!
|
||||||
|
// NOT FOR DEFINETLY ENCRYPTED COMMUNITIES / NO DOWNGRADE, NO INJECTION
|
||||||
|
|
||||||
|
return (HEADER_ENCRYPTION_NONE);
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
// most probably encrypted
|
// most probably encrypted
|
||||||
|
@ -67,24 +74,23 @@ int32_t decryt_packet_header_if_required (uint8_t packet[], uint16_t packet_len,
|
||||||
int32_t ret;
|
int32_t ret;
|
||||||
struct sn_community *c, *tmp;
|
struct sn_community *c, *tmp;
|
||||||
HASH_ITER (hh, communities, c, tmp) {
|
HASH_ITER (hh, communities, c, tmp) {
|
||||||
// check if this is an encrypted community
|
// skip the definitely unencrypted communities
|
||||||
if ( ret = decrypt_packet_header (packet, packet_len, c->community, c-> ctx) ) {
|
if (c->header_encryption == HEADER_ENCRYPTION_NONE)
|
||||||
// no upgrade from unencrypted to encrypted
|
continue;
|
||||||
if (c->header_encryption == 1)
|
if ( (ret = packet_header_decrypt (packet, packet_len, c->community, &(c->header_encryption_ctx))) ) {
|
||||||
return (-2);
|
|
||||||
// set to 'encrypted'
|
// set to 'encrypted'
|
||||||
c->header_encryption = 2;
|
c->header_encryption = HEADER_ENCRYPTION_ENABLED;
|
||||||
// no need to test any further
|
// no need to test any further
|
||||||
return (2);
|
return (HEADER_ENCRYPTION_ENABLED);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// no match
|
// no matching key/community
|
||||||
return (-3);
|
return (-3);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int32_t encryt_packet_header (uint8_t packet[], uint8_t header_len, speck_ctx * ctx) {
|
int32_t packet_header_encrypt (uint8_t packet[], uint8_t header_len, he_context_t * ctx) {
|
||||||
|
|
||||||
if (header_len < 20)
|
if (header_len < 20)
|
||||||
return (-1);
|
return (-1);
|
||||||
|
@ -100,5 +106,16 @@ int32_t encryt_packet_header (uint8_t packet[], uint8_t header_len, speck_ctx *
|
||||||
|
|
||||||
iv[12] = header_len;
|
iv[12] = header_len;
|
||||||
|
|
||||||
speck_he (&packet[12], &packet[12], header_len - 12, iv, ctx);
|
speck_he (&packet[12], &packet[12], header_len - 12, iv, (speck_context_t*)ctx);
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void packet_header_setup_key (char * community_name, he_context_t * ctx) {
|
||||||
|
|
||||||
|
uint8_t key[16];
|
||||||
|
pearson_hash_128 (key, (uint8_t*)community_name, N2N_COMMUNITY_SIZE);
|
||||||
|
|
||||||
|
speck_expand_key_he (key, ctx);
|
||||||
}
|
}
|
||||||
|
|
17
header_encryption.h
Normal file
17
header_encryption.h
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "speck.h"
|
||||||
|
typedef speck_context_t he_context_t;
|
||||||
|
|
||||||
|
|
||||||
|
#define HEADER_ENCRYPTION_UNKNOWN 0
|
||||||
|
#define HEADER_ENCRYPTION_NONE 1
|
||||||
|
#define HEADER_ENCRYPTION_ENABLED 2
|
||||||
|
|
||||||
|
|
||||||
|
uint32_t decrypt_packet_header (uint8_t packet[], uint8_t packet_len,
|
||||||
|
char * community_name, he_context_t * ctx);
|
||||||
|
|
||||||
|
int32_t encryt_packet_header (uint8_t packet[], uint8_t header_len, he_context_t * ctx);
|
||||||
|
|
||||||
|
int32_t encryt_packet_header (uint8_t packet[], uint8_t header_len, he_context_t * ctx);
|
6
n2n.h
6
n2n.h
|
@ -111,6 +111,7 @@ typedef struct ether_hdr ether_hdr_t;
|
||||||
#include <openssl/opensslv.h>
|
#include <openssl/opensslv.h>
|
||||||
#include <openssl/crypto.h>
|
#include <openssl/crypto.h>
|
||||||
#include "minilzo.h"
|
#include "minilzo.h"
|
||||||
|
#include "header_encryption.h"
|
||||||
|
|
||||||
#define closesocket(a) close(a)
|
#define closesocket(a) close(a)
|
||||||
#endif /* #ifndef WIN32 */
|
#endif /* #ifndef WIN32 */
|
||||||
|
@ -160,6 +161,7 @@ typedef struct tuntap_dev {
|
||||||
#define MSG_TYPE_FEDERATION 8
|
#define MSG_TYPE_FEDERATION 8
|
||||||
#define MSG_TYPE_PEER_INFO 9
|
#define MSG_TYPE_PEER_INFO 9
|
||||||
#define MSG_TYPE_QUERY_PEER 10
|
#define MSG_TYPE_QUERY_PEER 10
|
||||||
|
#define MSG_TYPE_MAX_TYPE 10
|
||||||
|
|
||||||
/* 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
|
||||||
|
@ -225,6 +227,8 @@ typedef struct n2n_edge_conf {
|
||||||
n2n_sn_name_t sn_ip_array[N2N_EDGE_NUM_SUPERNODES];
|
n2n_sn_name_t sn_ip_array[N2N_EDGE_NUM_SUPERNODES];
|
||||||
n2n_route_t *routes; /**< Networks to route through n2n */
|
n2n_route_t *routes; /**< Networks to route through n2n */
|
||||||
n2n_community_t community_name; /**< The community. 16 full octets. */
|
n2n_community_t community_name; /**< The community. 16 full octets. */
|
||||||
|
uint8_t header_encryption; /**< Header encryption indicator. */
|
||||||
|
he_context_t header_encryption_ctx; /**< Header encryption cipher context. */
|
||||||
n2n_transform_t transop_id; /**< The transop to use. */
|
n2n_transform_t transop_id; /**< The transop to use. */
|
||||||
uint16_t compression; /**< Compress outgoing data packets before encryption */
|
uint16_t compression; /**< Compress outgoing data packets before encryption */
|
||||||
uint16_t num_routes; /**< Number of routes in routes */
|
uint16_t num_routes; /**< Number of routes in routes */
|
||||||
|
@ -270,6 +274,8 @@ typedef struct sn_stats
|
||||||
struct sn_community
|
struct sn_community
|
||||||
{
|
{
|
||||||
char community[N2N_COMMUNITY_SIZE];
|
char community[N2N_COMMUNITY_SIZE];
|
||||||
|
uint8_t header_encryption; /* Header encryption indicator. */
|
||||||
|
he_context_t header_encryption_ctx; /* Header encryption cipher context. */
|
||||||
struct peer_info *edges; /* Link list of registered edges. */
|
struct peer_info *edges; /* Link list of registered edges. */
|
||||||
|
|
||||||
UT_hash_handle hh; /* makes this structure hashable */
|
UT_hash_handle hh; /* makes this structure hashable */
|
||||||
|
|
56
pearson.c
56
pearson.c
|
@ -157,3 +157,59 @@ void pearson_hash_256 (uint8_t *out, const uint8_t *in, size_t len) {
|
||||||
o = (uint64_t*)&out[24];
|
o = (uint64_t*)&out[24];
|
||||||
*o = lower_hash;
|
*o = lower_hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void pearson_hash_128 (uint8_t *out, const uint8_t *in, size_t len) {
|
||||||
|
|
||||||
|
/* initial values - astonishingly, assembling using SHIFTs and ORs (in register)
|
||||||
|
* works faster on well pipelined CPUs than loading the 64-bit value from memory.
|
||||||
|
* however, there is one advantage to loading from memory: as we also store back to
|
||||||
|
* memory at the end, we do not need to care about endianess! */
|
||||||
|
uint8_t upper[8] = { 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08 };
|
||||||
|
uint8_t lower[8] = { 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00 };
|
||||||
|
|
||||||
|
uint64_t upper_hash_mask = *(uint64_t*)&upper;
|
||||||
|
uint64_t lower_hash_mask = *(uint64_t*)&lower;
|
||||||
|
|
||||||
|
uint64_t upper_hash = 0;
|
||||||
|
uint64_t lower_hash = 0;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < len; i++) {
|
||||||
|
// broadcast the character, xor into hash, make them different permutations
|
||||||
|
uint64_t c = (uint8_t)in[i];
|
||||||
|
c |= c << 8;
|
||||||
|
c |= c << 16;
|
||||||
|
c |= c << 32;
|
||||||
|
upper_hash ^= c ^ upper_hash_mask;
|
||||||
|
lower_hash ^= c ^ lower_hash_mask;
|
||||||
|
// table lookup
|
||||||
|
uint8_t x;
|
||||||
|
uint64_t h = 0;
|
||||||
|
x = upper_hash; x = t[x]; upper_hash >>= 8; h |= x; h=ROR64(h,8);
|
||||||
|
x = upper_hash; x = t[x]; upper_hash >>= 8; h |= x; h=ROR64(h,8);
|
||||||
|
x = upper_hash; x = t[x]; upper_hash >>= 8; h |= x; h=ROR64(h,8);
|
||||||
|
x = upper_hash; x = t[x]; upper_hash >>= 8; h |= x; h=ROR64(h,8);
|
||||||
|
x = upper_hash; x = t[x]; upper_hash >>= 8; h |= x; h=ROR64(h,8);
|
||||||
|
x = upper_hash; x = t[x]; upper_hash >>= 8; h |= x; h=ROR64(h,8);
|
||||||
|
x = upper_hash; x = t[x]; upper_hash >>= 8; h |= x; h=ROR64(h,8);
|
||||||
|
x = upper_hash; x = t[x]; upper_hash >>= 8; h |= x; h=ROR64(h,8);
|
||||||
|
upper_hash = h;
|
||||||
|
|
||||||
|
h = 0;
|
||||||
|
x = lower_hash; x = t[x]; lower_hash >>= 8; h |= x; h=ROR64(h,8);
|
||||||
|
x = lower_hash; x = t[x]; lower_hash >>= 8; h |= x; h=ROR64(h,8);
|
||||||
|
x = lower_hash; x = t[x]; lower_hash >>= 8; h |= x; h=ROR64(h,8);
|
||||||
|
x = lower_hash; x = t[x]; lower_hash >>= 8; h |= x; h=ROR64(h,8);
|
||||||
|
x = lower_hash; x = t[x]; lower_hash >>= 8; h |= x; h=ROR64(h,8);
|
||||||
|
x = lower_hash; x = t[x]; lower_hash >>= 8; h |= x; h=ROR64(h,8);
|
||||||
|
x = lower_hash; x = t[x]; lower_hash >>= 8; h |= x; h=ROR64(h,8);
|
||||||
|
x = lower_hash; x = t[x]; lower_hash >>= 8; h |= x; h=ROR64(h,8);
|
||||||
|
lower_hash = h;
|
||||||
|
}
|
||||||
|
// store output
|
||||||
|
uint64_t *o;
|
||||||
|
o = (uint64_t*)&out[0];
|
||||||
|
*o = upper_hash;
|
||||||
|
o = (uint64_t*)&out[8];
|
||||||
|
*o = lower_hash;
|
||||||
|
}
|
||||||
|
|
|
@ -17,3 +17,5 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void pearson_hash_256 (uint8_t *out, const uint8_t *in, size_t len);
|
void pearson_hash_256 (uint8_t *out, const uint8_t *in, size_t len);
|
||||||
|
|
||||||
|
void pearson_hash_128 (uint8_t *out, const uint8_t *in, size_t len);
|
||||||
|
|
7
speck.h
7
speck.h
|
@ -2,6 +2,10 @@
|
||||||
// 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/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef SPECK_H
|
||||||
|
#define SPECK_H
|
||||||
|
|
||||||
#define u32 uint32_t
|
#define u32 uint32_t
|
||||||
#define u64 uint64_t
|
#define u64 uint64_t
|
||||||
|
|
||||||
|
@ -61,3 +65,6 @@ int speck_he (unsigned char *out, const unsigned char *in, unsigned long long in
|
||||||
|
|
||||||
|
|
||||||
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);
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue
Block a user