aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorJason A. Donenfeld <Jason@zx2c4.com>2020-05-14 21:51:43 -0600
committerJason A. Donenfeld <Jason@zx2c4.com>2020-05-19 23:18:53 -0600
commitccff8b7b8419e3e3729fc5f9ec037611457f1c74 (patch)
tree181cba3ddcf9044c029692f9707cee7436d4aaf4
parentcompat: support RHEL 8 as 8.2, drop 8.1 support (diff)
downloadwireguard-linux-compat-ccff8b7b8419e3e3729fc5f9ec037611457f1c74.tar.xz
wireguard-linux-compat-ccff8b7b8419e3e3729fc5f9ec037611457f1c74.zip
noise: read preshared key while taking lock
Prior we read the preshared key after dropping the handshake lock, which isn't an actual crypto issue if it races, but it's still not quite correct. So copy that part of the state into a temporary like we do with the rest of the handshake state variables. Then we can release the lock, operate on the temporary, and zero it out at the end of the function. In performance tests, the impact of this was entirely unnoticable, probably because those bytes are coming from the same cacheline as other things that are being copied out in the same manner. Reported-by: Matt Dunwoodie <ncon@noconroy.net> Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
-rw-r--r--src/noise.c6
1 files changed, 5 insertions, 1 deletions
diff --git a/src/noise.c b/src/noise.c
index 3217225..41b11fd 100644
--- a/src/noise.c
+++ b/src/noise.c
@@ -717,6 +717,7 @@ wg_noise_handshake_consume_response(struct message_handshake_response *src,
u8 e[NOISE_PUBLIC_KEY_LEN];
u8 ephemeral_private[NOISE_PUBLIC_KEY_LEN];
u8 static_private[NOISE_PUBLIC_KEY_LEN];
+ u8 preshared_key[NOISE_SYMMETRIC_KEY_LEN];
down_read(&wg->static_identity.lock);
@@ -735,6 +736,8 @@ wg_noise_handshake_consume_response(struct message_handshake_response *src,
memcpy(chaining_key, handshake->chaining_key, NOISE_HASH_LEN);
memcpy(ephemeral_private, handshake->ephemeral_private,
NOISE_PUBLIC_KEY_LEN);
+ memcpy(preshared_key, handshake->preshared_key,
+ NOISE_SYMMETRIC_KEY_LEN);
up_read(&handshake->lock);
if (state != HANDSHAKE_CREATED_INITIATION)
@@ -752,7 +755,7 @@ wg_noise_handshake_consume_response(struct message_handshake_response *src,
goto fail;
/* psk */
- mix_psk(chaining_key, hash, key, handshake->preshared_key);
+ mix_psk(chaining_key, hash, key, preshared_key);
/* {} */
if (!message_decrypt(NULL, src->encrypted_nothing,
@@ -785,6 +788,7 @@ out:
memzero_explicit(chaining_key, NOISE_HASH_LEN);
memzero_explicit(ephemeral_private, NOISE_PUBLIC_KEY_LEN);
memzero_explicit(static_private, NOISE_PUBLIC_KEY_LEN);
+ memzero_explicit(preshared_key, NOISE_SYMMETRIC_KEY_LEN);
up_read(&wg->static_identity.lock);
return ret_peer;
}