aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/src
diff options
context:
space:
mode:
authorJason A. Donenfeld <Jason@zx2c4.com>2017-11-11 12:24:51 +0900
committerJason A. Donenfeld <Jason@zx2c4.com>2017-11-11 12:24:51 +0900
commit46f8cbc99734c77564a3b925a993fcba43da38be (patch)
treebcfdd56b8c5e13463229fa8e39c7fca45a1e9498 /src
parenttools: remove ioctl cruft (diff)
downloadwireguard-monolithic-historical-46f8cbc99734c77564a3b925a993fcba43da38be.tar.xz
wireguard-monolithic-historical-46f8cbc99734c77564a3b925a993fcba43da38be.zip
curve25519: reject deriving from NULL private keys
These aren't actually valid 25519 points pre-normalization, and doing this is required to make unsetting private keys based on all zeros.
Diffstat (limited to 'src')
-rw-r--r--src/crypto/curve25519.c7
-rw-r--r--src/netlink.c16
2 files changed, 16 insertions, 7 deletions
diff --git a/src/crypto/curve25519.c b/src/crypto/curve25519.c
index afc2a99..232c6d4 100644
--- a/src/crypto/curve25519.c
+++ b/src/crypto/curve25519.c
@@ -619,6 +619,10 @@ bool curve25519(u8 mypublic[CURVE25519_POINT_SIZE], const u8 secret[CURVE25519_P
bool curve25519_generate_public(u8 pub[CURVE25519_POINT_SIZE], const u8 secret[CURVE25519_POINT_SIZE])
{
static const u8 basepoint[CURVE25519_POINT_SIZE] __aligned(32) = { 9 };
+
+ if (unlikely(!crypto_memneq(secret, null_point, CURVE25519_POINT_SIZE)))
+ return false;
+
#ifdef CONFIG_X86_64
if (curve25519_use_avx && irq_fpu_usable()) {
kernel_fpu_begin();
@@ -1676,6 +1680,9 @@ bool curve25519_generate_public(u8 pub[CURVE25519_POINT_SIZE], const u8 secret[C
{
static const u8 basepoint[CURVE25519_POINT_SIZE] __aligned(32) = { 9 };
+ if (unlikely(!crypto_memneq(secret, null_point, CURVE25519_POINT_SIZE)))
+ return false;
+
return curve25519(pub, secret, basepoint);
}
#endif
diff --git a/src/netlink.c b/src/netlink.c
index ba9e41b..f2e724a 100644
--- a/src/netlink.c
+++ b/src/netlink.c
@@ -421,15 +421,17 @@ static int set_device(struct sk_buff *skb, struct genl_info *info)
if (info->attrs[WGDEVICE_A_PRIVATE_KEY] && nla_len(info->attrs[WGDEVICE_A_PRIVATE_KEY]) == NOISE_PUBLIC_KEY_LEN) {
struct wireguard_peer *peer, *temp;
- u8 public_key[NOISE_PUBLIC_KEY_LEN] = { 0 }, *private_key = nla_data(info->attrs[WGDEVICE_A_PRIVATE_KEY]);
- /* We remove before setting, to prevent race, which means doing two 25519-genpub ops. */
- __attribute((unused)) bool unused = curve25519_generate_public(public_key, private_key);
+ u8 public_key[NOISE_PUBLIC_KEY_LEN], *private_key = nla_data(info->attrs[WGDEVICE_A_PRIVATE_KEY]);
- peer = pubkey_hashtable_lookup(&wg->peer_hashtable, public_key);
- if (peer) {
- peer_put(peer);
- peer_remove(peer);
+ /* We remove before setting, to prevent race, which means doing two 25519-genpub ops. */
+ if (curve25519_generate_public(public_key, private_key)) {
+ peer = pubkey_hashtable_lookup(&wg->peer_hashtable, public_key);
+ if (peer) {
+ peer_put(peer);
+ peer_remove(peer);
+ }
}
+
noise_set_static_identity_private_key(&wg->static_identity, private_key);
list_for_each_entry_safe(peer, temp, &wg->peer_list, peer_list) {
if (!noise_precompute_static_static(peer))