From 9e8d603d14561095fb8d08871319a315d3bf6763 Mon Sep 17 00:00:00 2001 From: Dimitri Staessens Date: Fri, 2 Aug 2019 19:12:34 +0200 Subject: lib: Add per-message encryption with OpenSSL This adds a per-message symmetric encryption using the OpenSSL library. At flow allocation, an Elliptic Curve Diffie-Hellman exchange is performed to derive a shared secret, which is then hashed using SHA3-256 to be used as a key for symmetric AES-256 encryption. Each message on an encrypted flow adds a small crypto header that includes a random 128-bit Initialization Vector (IV). If the server does not have OpenSSL enabled, the flow allocation will fail with an -ECRYPT error. Future optimizations are to piggyback the public keys on the flow allocation message, and to enable per-flow encryption that maintains the context of the encryption over multiple packets and doesn't require sending IVs. Signed-off-by: Dimitri Staessens Signed-off-by: Sander Vrijders --- include/ouroboros/errno.h | 9 ++--- include/ouroboros/qos.h | 74 ++++++++++++++++++++++++++++++++++++++---- include/ouroboros/sockets.h.in | 4 +-- 3 files changed, 75 insertions(+), 12 deletions(-) (limited to 'include') diff --git a/include/ouroboros/errno.h b/include/ouroboros/errno.h index 27b21e82..20049751 100644 --- a/include/ouroboros/errno.h +++ b/include/ouroboros/errno.h @@ -25,11 +25,12 @@ #include -#define ENOTALLOC 1000 /* Flow is not allocated */ -#define EIPCPTYPE 1001 /* Unknown IPCP type */ +#define ENOTALLOC 1000 /* Flow is not allocated */ +#define EIPCPTYPE 1001 /* Unknown IPCP type */ #define EIRMD 1002 /* Failed to communicate with IRMD */ #define EIPCP 1003 /* Failed to communicate with IPCP */ -#define EIPCPSTATE 1004 /* Target in wrong state */ -#define EFLOWDOWN 1005 /* Flow is down */ +#define EIPCPSTATE 1004 /* Target in wrong state */ +#define EFLOWDOWN 1005 /* Flow is down */ +#define ECRYPT 1006 /* Encryption error */ #endif /* OUROBOROS_ERRNO_H */ diff --git a/include/ouroboros/qos.h b/include/ouroboros/qos.h index 0e4518f4..f5becaa6 100644 --- a/include/ouroboros/qos.h +++ b/include/ouroboros/qos.h @@ -34,6 +34,7 @@ typedef struct qos_spec { uint32_t ber; /* Bit error rate, errors per billion bits */ uint8_t in_order; /* In-order delivery, enables FRCT */ uint32_t max_gap; /* In ms */ + uint32_t cypher_s; /* Cypher strength, 0 = no encryption */ } qosspec_t; static const qosspec_t qos_raw = { @@ -43,7 +44,8 @@ static const qosspec_t qos_raw = { .loss = 1, .ber = 1, .in_order = 0, - .max_gap = UINT32_MAX + .max_gap = UINT32_MAX, + .cypher_s = 0 }; static const qosspec_t qos_raw_no_errors = { @@ -53,7 +55,19 @@ static const qosspec_t qos_raw_no_errors = { .loss = 1, .ber = 0, .in_order = 0, - .max_gap = UINT32_MAX + .max_gap = UINT32_MAX, + .cypher_s = 0 +}; + +static const qosspec_t qos_raw_crypt = { + .delay = UINT32_MAX, + .bandwidth = 0, + .availability = 0, + .loss = 1, + .ber = 0, + .in_order = 0, + .max_gap = UINT32_MAX, + .cypher_s = 256 }; static const qosspec_t qos_best_effort = { @@ -63,7 +77,19 @@ static const qosspec_t qos_best_effort = { .loss = 1, .ber = 0, .in_order = 1, - .max_gap = UINT32_MAX + .max_gap = UINT32_MAX, + .cypher_s = 0 +}; + +static const qosspec_t qos_best_effort_crypt = { + .delay = UINT32_MAX, + .bandwidth = 0, + .availability = 0, + .loss = 1, + .ber = 0, + .in_order = 1, + .max_gap = UINT32_MAX, + .cypher_s = 256 }; static const qosspec_t qos_video = { @@ -73,7 +99,19 @@ static const qosspec_t qos_video = { .loss = 1, .ber = 0, .in_order = 1, - .max_gap = 100 + .max_gap = 100, + .cypher_s = 0 +}; + +static const qosspec_t qos_video_crypt = { + .delay = 100, + .bandwidth = UINT64_MAX, + .availability = 3, + .loss = 1, + .ber = 0, + .in_order = 1, + .max_gap = 100, + .cypher_s = 256 }; static const qosspec_t qos_voice = { @@ -83,7 +121,19 @@ static const qosspec_t qos_voice = { .loss = 1, .ber = 0, .in_order = 1, - .max_gap = 50 + .max_gap = 50, + .cypher_s = 0 +}; + +static const qosspec_t qos_voice_crypt = { + .delay = 50, + .bandwidth = 100000, + .availability = 5, + .loss = 1, + .ber = 0, + .in_order = 1, + .max_gap = 50, + .cypher_s = 256 }; static const qosspec_t qos_data = { @@ -93,7 +143,19 @@ static const qosspec_t qos_data = { .loss = 0, .ber = 0, .in_order = 1, - .max_gap = 2000 + .max_gap = 2000, + .cypher_s = 0 +}; + +static const qosspec_t qos_data_crypt = { + .delay = 1000, + .bandwidth = 0, + .availability = 0, + .loss = 0, + .ber = 0, + .in_order = 1, + .max_gap = 2000, + .cypher_s = 256 }; #endif /* OUROBOROS_QOS_H */ diff --git a/include/ouroboros/sockets.h.in b/include/ouroboros/sockets.h.in index 1e9dc9ca..4f03ca46 100644 --- a/include/ouroboros/sockets.h.in +++ b/include/ouroboros/sockets.h.in @@ -60,8 +60,8 @@ irm_msg_t * send_recv_irm_msg(irm_msg_t * msg); /* qos message conversion needed in different components */ -qosspec_msg_t spec_to_msg(qosspec_t * qs); +qosspec_msg_t spec_to_msg(const qosspec_t * qs); -qosspec_t msg_to_spec(qosspec_msg_t * msg); +qosspec_t msg_to_spec(const qosspec_msg_t * msg); #endif -- cgit v1.2.3