WireGuard Archive on lore.kernel.org
 help / Atom feed
* OpenBSD kernel implementation
@ 2018-12-11 13:24 Matt
  2018-12-11 15:29 ` Jason A. Donenfeld
  0 siblings, 1 reply; 5+ messages in thread
From: Matt @ 2018-12-11 13:24 UTC (permalink / raw)
  To: wireguard

Hi all,

Below is a message sent to tech@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

_______________________________________________
WireGuard mailing list
WireGuard@lists.zx2c4.com
https://lists.zx2c4.com/mailman/listinfo/wireguard

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: OpenBSD kernel implementation
  2018-12-11 13:24 OpenBSD kernel implementation Matt
@ 2018-12-11 15:29 ` Jason A. Donenfeld
  2018-12-11 21:22   ` Matt
  2018-12-12 22:34   ` David Gwynne
  0 siblings, 2 replies; 5+ messages in thread
From: Jason A. Donenfeld @ 2018-12-11 15:29 UTC (permalink / raw)
  To: Matt; +Cc: wireguard

Hi Matt,

Exciting to see you working on this. However, I'm afraid the
implementation you describe sounds deeply flawed and kind of misses
the point of WireGuard.

On Tue, Dec 11, 2018 at 2:24 PM Matt wrote:
 > 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.

Do not do this. This is entirely unacceptable and wholly contrary to
the design approach of WireGuard. The transport layer and handshake
layer exist on the same state machine, and I designed the handshake
specifically to be extremely simple and implementable in kernel space.
I'm happy to help you clean up your current approach -- which seems
nicer and closer to the goal -- but your proposed separated approach
is really deeply flawed, and overly complex. Do not make this mistake.

Rather, let's clean up your current WIP together. If you're on IRC,
I'm happy to discuss with you there (I'm zx2c4 on Freenode) and we can
get this into shape.

Regards,
Jason
_______________________________________________
WireGuard mailing list
WireGuard@lists.zx2c4.com
https://lists.zx2c4.com/mailman/listinfo/wireguard

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: OpenBSD kernel implementation
  2018-12-11 15:29 ` Jason A. Donenfeld
@ 2018-12-11 21:22   ` Matt
  2018-12-12 22:34   ` David Gwynne
  1 sibling, 0 replies; 5+ messages in thread
From: Matt @ 2018-12-11 21:22 UTC (permalink / raw)
  To: Jason A. Donenfeld; +Cc: wireguard

Hi Jason,

On Tue, Dec 11, 2018 at 04:29:40PM +0100, Jason A. Donenfeld wrote:
> Hi Matt,
> 
> Exciting to see you working on this. However, I'm afraid the
> implementation you describe sounds deeply flawed and kind of misses
> the point of WireGuard.
> 
> On Tue, Dec 11, 2018 at 2:24 PM Matt wrote:
> > 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.
> 
> Do not do this. This is entirely unacceptable and wholly contrary to
> the design approach of WireGuard. The transport layer and handshake
> layer exist on the same state machine, and I designed the handshake
> specifically to be extremely simple and implementable in kernel space.
> I'm happy to help you clean up your current approach -- which seems
> nicer and closer to the goal -- but your proposed separated approach
> is really deeply flawed, and overly complex. Do not make this mistake.

I don't think I can (morally, or logically) oppose such an argument.
Perhaps I did get a bit too excited and off track.
 
> Rather, let's clean up your current WIP together. If you're on IRC,
> I'm happy to discuss with you there (I'm zx2c4 on Freenode) and we can
> get this into shape.

This sounds like a reasonable way forward.

Cheers,
Matt
_______________________________________________
WireGuard mailing list
WireGuard@lists.zx2c4.com
https://lists.zx2c4.com/mailman/listinfo/wireguard

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: OpenBSD kernel implementation
  2018-12-11 15:29 ` Jason A. Donenfeld
  2018-12-11 21:22   ` Matt
@ 2018-12-12 22:34   ` David Gwynne
  2018-12-12 22:36     ` Jason A. Donenfeld
  1 sibling, 1 reply; 5+ messages in thread
From: David Gwynne @ 2018-12-12 22:34 UTC (permalink / raw)
  To: Jason A. Donenfeld; +Cc: wireguard

Hi Jason and Matt,

Just have a question below.

> On 12 Dec 2018, at 01:29, Jason A. Donenfeld <Jason@zx2c4.com> wrote:
> 
> Hi Matt,
> 
> Exciting to see you working on this. However, I'm afraid the
> implementation you describe sounds deeply flawed and kind of misses
> the point of WireGuard.
> 
> On Tue, Dec 11, 2018 at 2:24 PM Matt wrote:
> > 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.
> 
> Do not do this. This is entirely unacceptable and wholly contrary to
> the design approach of WireGuard. The transport layer and handshake
> layer exist on the same state machine, and I designed the handshake
> specifically to be extremely simple and implementable in kernel space.
> I'm happy to help you clean up your current approach -- which seems
> nicer and closer to the goal -- but your proposed separated approach
> is really deeply flawed, and overly complex. Do not make this mistake.

Did you tie the handshake and data state machines together so you would only have to handle packet crypto operations with a single set of keys? If so, what happens to data packets that are in flight while the handshake is happening? Do you keep the old keys around for a bit to allow operation on them?

> Rather, let's clean up your current WIP together. If you're on IRC,
> I'm happy to discuss with you there (I'm zx2c4 on Freenode) and we can
> get this into shape.
> 
> Regards,
> Jason
> _______________________________________________
> WireGuard mailing list
> WireGuard@lists.zx2c4.com
> https://lists.zx2c4.com/mailman/listinfo/wireguard

_______________________________________________
WireGuard mailing list
WireGuard@lists.zx2c4.com
https://lists.zx2c4.com/mailman/listinfo/wireguard

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: OpenBSD kernel implementation
  2018-12-12 22:34   ` David Gwynne
@ 2018-12-12 22:36     ` Jason A. Donenfeld
  0 siblings, 0 replies; 5+ messages in thread
From: Jason A. Donenfeld @ 2018-12-12 22:36 UTC (permalink / raw)
  To: david; +Cc: WireGuard mailing list

Hi David,

On Wed, Dec 12, 2018 at 11:35 PM David Gwynne <david@gwynne.id.au> wrote:
> Did you tie the handshake and data state machines together so you would only have to handle packet crypto operations with a single set of keys? If so, what happens to data packets that are in flight while the handshake is happening? Do you keep the old keys around for a bit to allow operation on them?

Yes. There's a rotation on a fixed amount of state.

Jason
_______________________________________________
WireGuard mailing list
WireGuard@lists.zx2c4.com
https://lists.zx2c4.com/mailman/listinfo/wireguard

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, back to index

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-12-11 13:24 OpenBSD kernel implementation Matt
2018-12-11 15:29 ` Jason A. Donenfeld
2018-12-11 21:22   ` Matt
2018-12-12 22:34   ` David Gwynne
2018-12-12 22:36     ` Jason A. Donenfeld

WireGuard Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/wireguard/0 wireguard/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 wireguard wireguard/ https://lore.kernel.org/wireguard \
		wireguard@lists.zx2c4.com zx2c4-wireguard@archiver.kernel.org
	public-inbox-index wireguard


Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/com.zx2c4.lists.wireguard


AGPL code for this site: git clone https://public-inbox.org/ public-inbox