summaryrefslogtreecommitdiff
path: root/src/lib/crypt.c
diff options
context:
space:
mode:
authorDimitri Staessens <dimitri@ouroboros.rocks>2020-02-24 22:30:22 +0100
committerSander Vrijders <sander@ouroboros.rocks>2020-02-25 08:21:09 +0100
commitfe6b60909d455abdac7885ceaba1097749e7aeb1 (patch)
treeffd3f3c6a2f15a1af5b393d8a5c068304b29a636 /src/lib/crypt.c
parent11fbe2f998a39ca156e2c806fd78f2af781836a4 (diff)
downloadouroboros-fe6b60909d455abdac7885ceaba1097749e7aeb1.tar.gz
ouroboros-fe6b60909d455abdac7885ceaba1097749e7aeb1.zip
lib, ipcpd: piggyback ECDHE on flow allocation
The initial implementation for the ECDHE key exchange was doing the key exchange after a flow was established. The public keys are now sent allowg on the flow allocation messages, so that an encrypted tunnel can be created within 1 RTT. The flow allocation steps had to be extended to pass the opaque data ('piggybacking'). Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
Diffstat (limited to 'src/lib/crypt.c')
-rw-r--r--src/lib/crypt.c197
1 files changed, 77 insertions, 120 deletions
diff --git a/src/lib/crypt.c b/src/lib/crypt.c
index 929d73f9..1fa12bb8 100644
--- a/src/lib/crypt.c
+++ b/src/lib/crypt.c
@@ -27,9 +27,9 @@
#include <openssl/ec.h>
#include <openssl/pem.h>
-#define MSGBUFSZ 2048
+#include <openssl/bio.h>
+
#define IVSZ 16
-#define DH_TIMEO 2 /* seconds */
/* SYMMKEYSZ defined in dev.c */
/*
@@ -90,7 +90,7 @@ static int __openssl_ecdh_derive_secret(EVP_PKEY * kp,
return -ECRYPT;
}
-static int __openssl_ecdh_gen_key(EVP_PKEY ** kp)
+static int __openssl_ecdh_gen_key(void ** kp)
{
EVP_PKEY_CTX * ctx = NULL;
EVP_PKEY_CTX * kctx = NULL;
@@ -121,7 +121,7 @@ static int __openssl_ecdh_gen_key(EVP_PKEY ** kp)
if (ret != 1)
goto fail_keygen;
- ret = EVP_PKEY_keygen(kctx, kp);
+ ret = EVP_PKEY_keygen(kctx, (EVP_PKEY **) kp);
if (ret != 1)
goto fail_keygen;
@@ -141,114 +141,57 @@ static int __openssl_ecdh_gen_key(EVP_PKEY ** kp)
return -ECRYPT;
}
-/* ECDH from the server side. */
-static int openssl_ecdh_srv(int fd,
- uint8_t * s)
+static ssize_t openssl_ecdh_pkp_create(void ** pkp,
+ uint8_t * pk)
{
- EVP_PKEY * kp = NULL;
- EVP_PKEY * pub = NULL;
- uint8_t buf[MSGBUFSZ];
- ssize_t len;
- int buf_sz;
uint8_t * pos;
- struct timespec timeo = {DH_TIMEO,0};
-
- assert(s != NULL);
+ ssize_t len;
- (void) fd;
- (void) s;
+ assert(pkp != NULL);
+ assert(*pkp == NULL);
+ assert(pk != NULL);
- if (__openssl_ecdh_gen_key(&kp) < 0)
- goto fail_gen_key;
+ if (__openssl_ecdh_gen_key(pkp) < 0)
+ return -ECRYPT;
- fccntl(fd, FLOWSRCVTIMEO, &timeo);
+ assert(*pkp != NULL);
- len = flow_read(fd, buf, MSGBUFSZ);
+ pos = pk; /* i2d_PUBKEY increments the pointer, don't use buf! */
+ len = i2d_PUBKEY(*pkp, &pos);
if (len < 0) {
- fccntl(fd, FLOWSRCVTIMEO, NULL);
- goto fail_get_key;
+ EVP_PKEY_free(*pkp);
+ return -ECRYPT;
}
- fccntl(fd, FLOWSRCVTIMEO, NULL);
-
- pos = buf; /* i2d_PUBKEY increments the pointer, don't use buf! */
- pub = d2i_PUBKEY(NULL, (const uint8_t **) &pos, (long) len);
-
- pos = buf; /* i2d_PUBKEY increments the pointer, don't use buf! */
- buf_sz = i2d_PUBKEY(kp, &pos);
- if (buf_sz < 0)
- goto fail_get_key;
-
- if (flow_write(fd, buf, (size_t) buf_sz) < 0)
- goto fail_get_key;
-
- if (__openssl_ecdh_derive_secret(kp, pub, s) < 0)
- goto fail_get_key;
-
- EVP_PKEY_free(kp);
- EVP_PKEY_free(pub);
-
- return 0;
-
- fail_get_key:
- EVP_PKEY_free(kp);
- fail_gen_key:
- return -ECRYPT;
+ return len;
}
-/* ECDH from the client side. */
-static int openssl_ecdh_clt(int fd,
- uint8_t * s)
+static void openssl_ecdh_pkp_destroy(void * pkp)
{
- EVP_PKEY * kp = NULL;
- EVP_PKEY * pub = NULL;
- uint8_t buf[MSGBUFSZ];
- int buf_sz;
- uint8_t * pos;
- ssize_t len;
- struct timespec timeo = {DH_TIMEO,0};
-
- assert(s != NULL);
-
- (void) fd;
- (void) s;
-
- if (__openssl_ecdh_gen_key(&kp) < 0)
- goto fail_gen_key;
-
- pos = buf; /* i2d_PUBKEY increments the pointer, don't use buf! */
- buf_sz = i2d_PUBKEY(kp, &pos);
- if (buf_sz < 0)
- goto fail_get_key;
-
- if (flow_write(fd, buf, (size_t) buf_sz) < 0)
- goto fail_get_key;
-
- fccntl(fd, FLOWSRCVTIMEO, &timeo);
-
- len = flow_read(fd, buf, MSGBUFSZ);
- if (len < 0) {
- fccntl(fd, FLOWSRCVTIMEO, NULL);
- goto fail_get_key;
- }
+ EVP_PKEY_free((EVP_PKEY *) pkp);
+}
- fccntl(fd, FLOWSRCVTIMEO, NULL);
+static int openssl_ecdh_derive(void * pkp,
+ uint8_t * pk,
+ size_t len,
+ uint8_t * s)
+{
+ uint8_t * pos;
+ EVP_PKEY * pub;
- pos = buf; /* i2d_PUBKEY increments the pointer, don't use buf! */
+ pos = pk; /* d2i_PUBKEY increments the pointer, don't use key ptr! */
pub = d2i_PUBKEY(NULL, (const uint8_t **) &pos, (long) len);
+ if (pub == NULL)
+ return -ECRYPT;
- if (__openssl_ecdh_derive_secret(kp, pub, s) < 0)
- goto fail_get_key;
+ if (__openssl_ecdh_derive_secret(pkp, pub, s) < 0) {
+ EVP_PKEY_free(pub);
+ return -ECRYPT;
+ }
- EVP_PKEY_free(kp);
EVP_PKEY_free(pub);
return 0;
-
- fail_get_key:
- EVP_PKEY_free(kp);
- fail_gen_key:
- return -ECRYPT;
}
/*
@@ -394,51 +337,64 @@ static int openssl_decrypt(struct flow * f,
}
-static int openssl_crypt_init(struct flow * f)
+static int openssl_crypt_init(void ** ctx)
{
- f->ctx = EVP_CIPHER_CTX_new();
- if (f->ctx == NULL)
- goto fail_new;
+ *ctx = EVP_CIPHER_CTX_new();
+ if (*ctx == NULL)
+ return -ECRYPT;
return 0;
-
- fail_new:
- return -ECRYPT;
}
-static void openssl_crypt_fini(struct flow * f)
+static void openssl_crypt_fini(void * ctx)
{
- EVP_CIPHER_CTX_free(f->ctx);
- f->ctx = NULL;
+ EVP_CIPHER_CTX_free(ctx);
}
#endif /* HAVE_OPENSSL */
-static int crypt_dh_srv(int fd,
- uint8_t * s)
+static int crypt_dh_pkp_create(void ** pkp,
+ uint8_t * pk)
{
#ifdef HAVE_OPENSSL
- return openssl_ecdh_srv(fd, s);
+ assert(pkp != NULL);
+ *pkp = NULL;
+ return openssl_ecdh_pkp_create(pkp, pk);
#else
- (void) fd;
+ (void) pkp;
+ (void) pk;
- memset(s, 0, SYMMKEYSZ);
+ memset(pk, 0, MSGBUFSZ);
return -ECRYPT;
#endif
}
-static int crypt_dh_clt(int fd,
- uint8_t * s)
+static void crypt_dh_pkp_destroy(void * pkp)
{
#ifdef HAVE_OPENSSL
- return openssl_ecdh_clt(fd, s);
+ openssl_ecdh_pkp_destroy(pkp);
#else
- (void) fd;
+ (void) pkp;
+ return 0;
+#endif
+}
+
+static int crypt_dh_derive(void * pkp,
+ uint8_t * pk,
+ size_t len,
+ uint8_t * s)
+{
+#ifdef HAVE_OPENSSL
+ return openssl_ecdh_derive(pkp, pk, len, s);
+#else
+ (void) pkp;
+ (void) pk;
+ (void) len;
memset(s, 0, SYMMKEYSZ);
- return 0;
+ return -ECRYPT;
#endif
}
@@ -464,27 +420,28 @@ static int crypt_decrypt(struct flow * f,
(void) f;
(void) sdb;
- return 0;
+ return -ECRYPT;
#endif
}
-
-static int crypt_init(struct flow * f)
+static int crypt_init(void ** ctx)
{
#ifdef HAVE_OPENSSL
- return openssl_crypt_init(f);
+ return openssl_crypt_init(ctx);
#else
- (void) f;
+ assert(ctx != NULL);
+ *ctx = NULL;
return 0;
#endif
}
-static void crypt_fini(struct flow * f)
+static void crypt_fini(void * ctx)
{
#ifdef HAVE_OPENSSL
- openssl_crypt_fini(f);
+ openssl_crypt_fini(ctx);
#else
- (void) f;
+ assert(ctx == NULL);
+ (void) ctx;
#endif
}