3

The mac1 field in the WireGuard handshake messages is populated as:

msg.mac1 := Mac(Hash(Label-Mac1 || Spub_m'), msgA)    // first arg is MAC key

Label-Mac1 is a constant, Spub_m' is the static public key of the peer, and msgA is the bytes of the message before the mac1 field.

I don't understand the purpose of this, given that every part of the MAC key is public knowledge (a constant and a static public key, which is handed out to peers out-of-band). The WireGuard whitepaper specifically says that Hash(Label-Mac1 || Spub_m') can be precomputed. What's the point of a MAC with a key that's easily computable from public knowledge? Isn't this MAC no more secure than just a hash of the message?

1 Answers1

1

As best I can gather from the whitepaper, it's because the MAC fields are meant to mitigate DoS attacks, not to provide message authentication.

Specifically, it defends against DoS attacks that don't know the endpoint's public key. The initiator must demonstrate that it knows the endpoint's public key (by sending a valid mac1) in order to get any response — in particular, to force the responder to do a CPU-intensive Curve25519 point multiplication.

From section 5.3:

[...]in order for the responder to remain silent, even while under load, all messages have a first MAC (msg.mac1) that uses the responder’s public key. This means that at the very least, a peer sending a message must know to whom it is talking (by virtue of knowing its public key), in order to elicit any kind of response. Under load or not under load, this first MAC (msg.mac1) always is required to be present and valid. While the public key of the responder itself is not secret, it is sufficiently secret within this attack model, in which the goal is to ensure stealthiness of services, and so knowing the responder’s public key is sufficient proof for already knowing of its existence.

As far as I can tell, it doesn't do much against a DoS attacker who knows the target endpoint's public key.