OpenBSD kernel implementation

Matt ncon at mail.noconroy.net
Tue Dec 11 14:24:39 CET 2018


Hi all,

Below is a message sent to tech at openbsd.org discussing potential design
for a WireGuard kernel module. It is unedited, so keep in mind the
context.

----------------

For the last few weeks I have been playing with some kernel development
in my spare time, specifically writing a ground up implementation of
WireGuard [1]. In it's current state, it is compatible with the Linux
kernel module and wireguard-go, however it was not heading in the
direction I was hoping; clear code, simple implementation, and secure.

Those that are interested can see [2]

I've spent some time thinking if I want to continue, however at this
point I would like some validation whether this is something that is
desired or may be desired in the future.

Currently, I want to take all the code that doesn't need to be in the
kernel and move it to userspace, which is essentially the handshake
code, timeout timers and state machine functions. What is left is
essentially the transport function (IPSEC transform equivalent),
peforming simple crypto on incoming/outgoing packets. This design is
somewhat similar to how IPSEC is currently implemented in OpenBSD. I
believe this is a reasonable approach, but welcome comments on things I
may not have considered.

This is a rough diagram of the design outlined above:

+----------------------------------------------------------------------+
|                                                                      |
|  +--------------------------+   +-------------------------------+    |
|  |                          |   |                               |    |
|  |  +--------------------+  |   |  +-------------------------+  |    |
|  |  | wg(4)              |  |   |  | handshake proc          |  |    |
|  |  | - ioctl(2) control |<------->| - setup interface       |  |    |
|  |  | - passes handshake |<------->| - handle handshakes     |  |    |
|  |  |   packets over     |  |   |  | - passes key to iface   |  |    |
|  |  |   socket to user   |  |   |  |                         |  |    |
|  |  | - handles all      |  |   |  +-------------------------+  |    |
|  |  |   transport pkts   |  |   |               |               |    |
|  |  | - performs         |  |   |  +-------------------------+  |    |
|  |  |   cryptokey        |  |   |  | crypto proc             |  |    |
|  |  |   routing          |  |   |  | - handle crypto ops     |  |    |
|  |  |                    |  |   |  | - HSM-like              |  |    |
|  |  |                    |  |   |  | - esssentially stores   |  |    |
|  |  |                    |  |   |  |   private and psk       |  |    |
|  |  +--------------------+  |   |  +-------------------------+  |    |
|  |  Kernel                  |   |  User                         |    |
|  +--------------------------+   +-------------------------------+    |
|                      - priv-sep userspace code                       |
|   WireGuard OpenBSD  - minimal kernel code (use crypto(9))           |
|                      - hopefully more performant than pure userspace |
+----------------------------------------------------------------------+

The wg(4) is a tunnel network interface, with packet level encryption.
Packets will arrive at the interface, encrypted and routed to the
allocated peer.  Incoming packets will be decrypted, route verified and
pass in on the interface.  No crypto needs to be added to the kernel, as
crypto(9) provides CRYPTO_CHACHA20_POLY1305.  The interface will need to
perform routing for 'cryptokey routing' [3], however the interface that
/usr/src/sys/net/art.h provides is generic enough that the routing
requires minimal new implementation.

The wg(4) interface listens on a SOCK_DGRAM currently (using
socreate(9)), and that works fine for the current implementation,
however with the user-kernel separation, the handshake specific packets
will need to be passed from that socket into userspace. Does anyone have
a solid idea? Otherwise I'll play around with using a separate socket
for that.

The idea of having the handshake code in userspace allows for multiple
implementations, however ideally an efficient C implementation can be
included in base. The wg(4) interface configuration API will be
exceptionally stable and well defined.

Unfortunately, up until this point, I have not spoken to anyone already
involved in WireGuard development - however hopefully that changes soon.
I hope to have similar discussions with those who are more invested in
WireGuard than myself.

Any feedback in regards to design or if this is something that people
would welcome in OpenBSD would be much appreciated.

Best Regards,
Matt

[1] https://www.wireguard.com/

[2] https://noconroy.net/files/if_wg.tar.gz

[3] https://www.wireguard.com/papers/wireguard.pdf



More information about the WireGuard mailing list