From 7111e1f77ccb1e86cc85d09c1a36caede9725f3a Mon Sep 17 00:00:00 2001 From: Mark Wooding Date: Fri, 28 Apr 2017 22:51:36 +0100 Subject: [PATCH] xdh.c: New module defining elliptic curve Diffie--Hellman functions. This provides X25519 and X448 as premade Diffie--Hellman closures. They should be used directly rather than applied to arguments. Signed-off-by: Mark Wooding --- Makefile.in | 2 +- magic.h | 2 + modules.c | 1 + secnet-wireshark.lua | 4 ++ secnet.8 | 30 +++++++++++++++ secnet.h | 1 + xdh.c | 105 +++++++++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 144 insertions(+), 1 deletion(-) create mode 100644 xdh.c diff --git a/Makefile.in b/Makefile.in index d31d44e..a130c20 100644 --- a/Makefile.in +++ b/Makefile.in @@ -61,7 +61,7 @@ TARGETS:=secnet OBJECTS:=secnet.o util.o conffile.yy.o conffile.tab.o conffile.o modules.o \ resolver.o random.o udp.o site.o transform-cbcmac.o transform-eax.o \ comm-common.o polypath.o \ - netlink.o rsa.o dh.o serpent.o serpentbe.o \ + netlink.o rsa.o dh.o xdh.o serpent.o serpentbe.o \ f25519.o x25519.o fgoldi.o x448.o \ md5.o sha512.o tun.o slip.o sha1.o ipaddr.o log.o \ process.o @LIBOBJS@ \ diff --git a/magic.h b/magic.h index 9c071c0..ca613cb 100644 --- a/magic.h +++ b/magic.h @@ -111,6 +111,8 @@ #define CAPAB_BIT_SERPENT256CBC 8 #define CAPAB_BIT_EAXSERPENT 9 #define CAPAB_BIT_TRADZP 10 +#define CAPAB_BIT_X25519 11 +#define CAPAB_BIT_X448 12 #define CAPAB_BIT_EXPLICIT_TRANSFORM_DH 15 #define CAPAB_BIT_MAX 31 diff --git a/modules.c b/modules.c index a5c3c8d..f5f6281 100644 --- a/modules.c +++ b/modules.c @@ -32,6 +32,7 @@ void init_builtin_modules(dict_t *dict) netlink_module(dict); rsa_module(dict); dh_module(dict); + xdh_module(dict); md5_module(dict); slip_module(dict); tun_module(dict); diff --git a/secnet-wireshark.lua b/secnet-wireshark.lua index 2a6761d..b9c42b8 100644 --- a/secnet-wireshark.lua +++ b/secnet-wireshark.lua @@ -226,6 +226,10 @@ local CAPTAB = { desc = "Serpent256-EAX transform" }, [10] = { name = "tradzp", kind = "dhgroup", desc = "Traditional Z_p Diffie--Hellman key agreement" }, + [11] = { name = "x25519", kind = "dhgroup", + desc = "X25519 elliptic curve Diffie--Hellman key agreement" }, + [12] = { name = "x448", kind = "dhgroup", + desc = "X448 elliptic curve Diffie--Hellman key agreement" }, [31] = { name = "mobile-priority", kind = "early", desc = "Mobile site takes priority in case of MSG1 crossing" } } diff --git a/secnet.8 b/secnet.8 index 525e854..087273d 100644 --- a/secnet.8 +++ b/secnet.8 @@ -340,6 +340,36 @@ The default capability number is 10. .PP A \fIdh closure\fR defines a group to be used for key exchange. +.SS x25519 +.PP +\fBx25519 +.PP +A premade \fIdh closure\fR +which uses Daniel Bernstein's X25519 key-exchange function. +This uses an elliptic curve called Curve25519, +defined over a 255-bit field. +The function is fast and very well-studied. +.PP +A \fIdh closure\fR defines a group to be used for key exchange. +The +.B x25519 +Diffie\(enHellman group always uses capability number 24. + +.SS x448 +.PP +\fBx448 +.PP +A premade \fIdh closure\fR +which uses Mike Hamburg's X448 key-exchange function. +This uses an elliptic curve called Ed448-Goldilocks, +defined over a 448-bit field. +The function is unusually quick and fairly well studied. +.PP +A \fIdh closure\fR defines a group to be used for key exchange. +The +.B x448 +Diffie\(enHellman group always uses capability number 25. + .SS logfile \fBlogfile(\fIDICT\fB)\fR => \fIlog closure\fR .PP diff --git a/secnet.h b/secnet.h index cda7f1d..e54dbbe 100644 --- a/secnet.h +++ b/secnet.h @@ -350,6 +350,7 @@ extern init_module transform_cbcmac_module; extern init_module netlink_module; extern init_module rsa_module; extern init_module dh_module; +extern init_module xdh_module; extern init_module md5_module; extern init_module slip_module; extern init_module tun_module; diff --git a/xdh.c b/xdh.c new file mode 100644 index 0000000..5795f43 --- /dev/null +++ b/xdh.c @@ -0,0 +1,105 @@ +/* + * xdh.c: x-coordinate-only Montgomery-ladder elliptic-curve Diffie--Hellman + */ +/* + * This file is Free Software. It was originally written for secnet. + * + * Copyright 2017 Mark Wooding + * + * You may redistribute secnet as a whole and/or modify it under the + * terms of the GNU General Public License as published by the Free + * Software Foundation; either version 3, or (at your option) any + * later version. + * + * You may redistribute this file and/or modify it under the terms of + * the GNU General Public License as published by the Free Software + * Foundation; either version 2, or (at your option) any later + * version. + * + * This software 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 software; if not, see + * https://www.gnu.org/licenses/gpl.html. + */ + +#include +#include + +#include "secnet.h" +#include "magic.h" +#include "util.h" + +#include "x25519.h" +#include "x448.h" + +#define XDH_MAXSZ 64 + +typedef void xdh_fn(uint8_t *z, const uint8_t *k, const uint8_t *x); + +struct xdh { + closure_t cl; + struct dh_if ops; + xdh_fn *fn; + const uint8_t *base; +}; + +static int32_t xdh_makepublic(void *sst, void *pub, int32_t publen, + uint8_t *k, int32_t klen) +{ + struct xdh *st = sst; + + assert(klen == st->ops.secret_len); + assert(publen >= st->ops.public_len); + st->fn(pub, k, st->base); + return st->ops.public_len; +} + +static bool_t xdh_makeshared(void *sst, + uint8_t *k, int32_t klen, + const void *pub, int32_t publen, + uint8_t *z, int32_t zlen) +{ + struct xdh *st = sst; + + assert(klen == st->ops.secret_len); + assert(zlen >= st->ops.shared_len); + if (publen != st->ops.public_len) { + Message(M_ERR, + "xdh_makeshared: incoming public point has wrong length"); + return False; + } + st->fn(z, k, pub); + return (True); +} + +static void make_xdh_closure(dict_t *dict, const char *name, xdh_fn *fn, + const uint8_t *base, size_t sz, int cap) +{ + struct xdh *st; + + NEW(st); + st->cl.description = name; + st->cl.type = CL_DH; + st->cl.apply = 0; + st->cl.interface = &st->ops; + st->ops.st = st; + st->ops.makepublic = xdh_makepublic; + st->ops.makeshared = xdh_makeshared; + st->ops.secret_len = st->ops.public_len = st->ops.shared_len = sz; + st->ops.capab_bit = cap; + st->fn = fn; + st->base = base; + dict_add(dict, name, new_closure(&st->cl)); +} + +void xdh_module(dict_t *dict) +{ + make_xdh_closure(dict, "x25519", x25519, x25519_base, + X25519_PUBSZ, CAPAB_BIT_X25519); + make_xdh_closure(dict, "x448", x448, x448_base, + X448_PUBSZ, CAPAB_BIT_X448); +} -- 2.11.0