diff options
author | Jason A. Donenfeld <Jason@zx2c4.com> | 2016-12-23 16:25:18 +0100 |
---|---|---|
committer | Jason A. Donenfeld <Jason@zx2c4.com> | 2016-12-23 21:09:23 +0100 |
commit | 6e4a10e8f2c73951f8e8fc2ac2821c5582d133bc (patch) | |
tree | ca4a7d47dcc49b699c4916addfd7cc555b977fb2 /src/cookie.c | |
parent | wg-config: cleanups (diff) | |
download | wireguard-monolithic-historical-6e4a10e8f2c73951f8e8fc2ac2821c5582d133bc.tar.xz wireguard-monolithic-historical-6e4a10e8f2c73951f8e8fc2ac2821c5582d133bc.zip |
cookies: use xchacha20poly1305 instead of chacha20poly1305
This allows us to precompute the blake2s calls and save cycles, since
hchacha is fast.
Diffstat (limited to 'src/cookie.c')
-rw-r--r-- | src/cookie.c | 65 |
1 files changed, 29 insertions, 36 deletions
diff --git a/src/cookie.c b/src/cookie.c index a2d1b22..b0f1284 100644 --- a/src/cookie.c +++ b/src/cookie.c @@ -23,6 +23,31 @@ int cookie_checker_init(struct cookie_checker *checker, struct wireguard_device return 0; } +static int precompute_peer_key(struct wireguard_peer *peer, void *psk) +{ + blake2s(peer->latest_cookie.cookie_decryption_key, peer->handshake.remote_static, psk, NOISE_SYMMETRIC_KEY_LEN, NOISE_PUBLIC_KEY_LEN, psk ? NOISE_SYMMETRIC_KEY_LEN : 0); + return 0; +} + +void cookie_checker_precompute_keys(struct cookie_checker *checker, struct wireguard_peer *peer) +{ + down_read(&checker->device->static_identity.lock); + if (unlikely(checker->device->static_identity.has_identity)) { + memset(checker->cookie_encryption_key, 0, NOISE_SYMMETRIC_KEY_LEN); + goto out; + } + + if (peer) + precompute_peer_key(peer, checker->device->static_identity.has_psk ? checker->device->static_identity.preshared_key : NULL); + else { + blake2s(checker->cookie_encryption_key, checker->device->static_identity.static_public, checker->device->static_identity.preshared_key, NOISE_SYMMETRIC_KEY_LEN, NOISE_PUBLIC_KEY_LEN, checker->device->static_identity.has_psk ? NOISE_SYMMETRIC_KEY_LEN : 0); + peer_for_each_unlocked(checker->device, precompute_peer_key, checker->device->static_identity.has_psk ? checker->device->static_identity.preshared_key : NULL); + } + +out: + up_read(&checker->device->static_identity.lock); +} + void cookie_checker_uninit(struct cookie_checker *checker) { ratelimiter_uninit(&checker->ratelimiter); @@ -159,32 +184,16 @@ void cookie_add_mac_to_packet(void *message, size_t len, struct wireguard_peer * void cookie_message_create(struct message_handshake_cookie *dst, struct sk_buff *skb, void *data_start, size_t data_len, __le32 index, struct cookie_checker *checker) { struct message_macs *macs = (struct message_macs *)((u8 *)data_start + data_len - sizeof(struct message_macs)); - struct blake2s_state state; u8 key[NOISE_SYMMETRIC_KEY_LEN]; u8 cookie[COOKIE_LEN]; dst->header.type = cpu_to_le32(MESSAGE_HANDSHAKE_COOKIE); dst->receiver_index = index; - get_random_bytes(dst->salt, COOKIE_SALT_LEN); - blake2s(dst->salt, dst->salt, NULL, COOKIE_SALT_LEN, COOKIE_SALT_LEN, 0); /* Avoid directly transmitting RNG output. */ - - down_read(&checker->device->static_identity.lock); - if (unlikely(!checker->device->static_identity.has_identity)) { - memset(dst, 0, sizeof(struct message_handshake_cookie)); - up_read(&checker->device->static_identity.lock); - return; - } - if (checker->device->static_identity.has_psk) - blake2s_init_key(&state, NOISE_SYMMETRIC_KEY_LEN, checker->device->static_identity.preshared_key, NOISE_SYMMETRIC_KEY_LEN); - else - blake2s_init(&state, NOISE_SYMMETRIC_KEY_LEN); - blake2s_update(&state, checker->device->static_identity.static_public, NOISE_PUBLIC_KEY_LEN); - up_read(&checker->device->static_identity.lock); - blake2s_update(&state, dst->salt, COOKIE_SALT_LEN); - blake2s_final(&state, key, NOISE_SYMMETRIC_KEY_LEN); + get_random_bytes(dst->nonce, COOKIE_NONCE_LEN); + blake2s(dst->nonce, dst->nonce, NULL, COOKIE_NONCE_LEN, COOKIE_NONCE_LEN, 0); /* Avoid directly transmitting RNG output. */ make_cookie(cookie, skb, checker); - chacha20poly1305_encrypt(dst->encrypted_cookie, cookie, COOKIE_LEN, macs->mac1, COOKIE_LEN, 0, key); + xchacha20poly1305_encrypt(dst->encrypted_cookie, cookie, COOKIE_LEN, macs->mac1, COOKIE_LEN, dst->nonce, checker->cookie_encryption_key); memzero_explicit(key, NOISE_HASH_LEN); memzero_explicit(cookie, COOKIE_LEN); @@ -192,7 +201,6 @@ void cookie_message_create(struct message_handshake_cookie *dst, struct sk_buff void cookie_message_consume(struct message_handshake_cookie *src, struct wireguard_device *wg) { - struct blake2s_state state; u8 key[NOISE_SYMMETRIC_KEY_LEN]; u8 cookie[COOKIE_LEN]; struct index_hashtable_entry *entry; @@ -208,23 +216,8 @@ void cookie_message_consume(struct message_handshake_cookie *src, struct wiregua } up_read(&entry->peer->latest_cookie.lock); - down_read(&wg->static_identity.lock); - if (unlikely(!wg->static_identity.has_identity)) { - up_read(&wg->static_identity.lock); - goto out; - } - if (wg->static_identity.has_psk) - blake2s_init_key(&state, NOISE_SYMMETRIC_KEY_LEN, wg->static_identity.preshared_key, NOISE_SYMMETRIC_KEY_LEN); - else - blake2s_init(&state, NOISE_SYMMETRIC_KEY_LEN); - up_read(&wg->static_identity.lock); - - blake2s_update(&state, entry->peer->handshake.remote_static, NOISE_PUBLIC_KEY_LEN); - blake2s_update(&state, src->salt, COOKIE_SALT_LEN); - blake2s_final(&state, key, NOISE_SYMMETRIC_KEY_LEN); - down_write(&entry->peer->latest_cookie.lock); - if (chacha20poly1305_decrypt(cookie, src->encrypted_cookie, sizeof(src->encrypted_cookie), entry->peer->latest_cookie.last_mac1_sent, COOKIE_LEN, 0, key)) { + if (xchacha20poly1305_decrypt(cookie, src->encrypted_cookie, sizeof(src->encrypted_cookie), entry->peer->latest_cookie.last_mac1_sent, COOKIE_LEN, src->nonce, entry->peer->latest_cookie.cookie_decryption_key)) { memcpy(entry->peer->latest_cookie.cookie, cookie, COOKIE_LEN); entry->peer->latest_cookie.birthdate = get_jiffies_64(); entry->peer->latest_cookie.is_valid = true; |