[noise] out of curve points

Jason A. Donenfeld Jason at zx2c4.com
Thu Oct 1 06:23:49 PDT 2015


FWIW:

diff --git a/src/crypto/curve25519.c b/src/crypto/curve25519.c
index 88a15f2..31c3753 100644
--- a/src/crypto/curve25519.c
<http://git.zx2c4.com/WireGuard/tree/src/crypto/curve25519.c?id=5e7623a1d383716350313205447d67e7bf40a4f9>
+++ b/src/crypto/curve25519.c
<http://git.zx2c4.com/WireGuard/tree/src/crypto/curve25519.c?id=eeb22e141bd46750e072bfbc20f36ab0d923ecba>
@@ -8,6 +8,7 @@
#include "curve25519.h"
#include <linux/string.h>
#include <linux/random.h>
+#include <crypto/algapi.h>
static __always_inline void normalize_secret(uint8_t
secret[CURVE25519_POINT_SIZE])
{
@@ -16,6 +17,8 @@ static __always_inline void normalize_secret(uint8_t
secret[CURVE25519_POINT_SIZ
secret[31] |= 64;
}
+static const uint8_t zeros[CURVE25519_POINT_SIZE] = { 0 };
+
#ifdef __SIZEOF_INT128__
typedef uint64_t limb;
typedef limb felem[5];
@@ -407,7 +410,7 @@ static void crecip(felem out, const felem z)
/* 2^255 - 21 */ fmul(out, t0, a);
}
-void curve25519(uint8_t mypublic[CURVE25519_POINT_SIZE], const uint8_t
secret[CURVE25519_POINT_SIZE], const uint8_t
basepoint[CURVE25519_POINT_SIZE])
+bool curve25519(uint8_t mypublic[CURVE25519_POINT_SIZE], const uint8_t
secret[CURVE25519_POINT_SIZE], const uint8_t
basepoint[CURVE25519_POINT_SIZE])
{
limb bp[5], x[5], z[5], zmone[5];
uint8_t e[32];
@@ -420,6 +423,13 @@ void curve25519(uint8_t
mypublic[CURVE25519_POINT_SIZE], const uint8_t secret[CU
crecip(zmone, z);
fmul(z, x, zmone);
fcontract(mypublic, z);
+
+ memzero_explicit(e, sizeof(e));
+ memzero_explicit(bp, sizeof(bp));
+ memzero_explicit(x, sizeof(x));
+ memzero_explicit(z, sizeof(z));
+ memzero_explicit(zmone, sizeof(zmone));
+ return crypto_memneq(mypublic, zeros, CURVE25519_POINT_SIZE);
}
#else
@@ -1212,7 +1222,7 @@ static void crecip(limb *out, const limb *z)
/* 2^255 - 21 */ fmul(out,t1,z11);
}
-void curve25519(uint8_t mypublic[CURVE25519_POINT_SIZE], const uint8_t
secret[CURVE25519_POINT_SIZE], const uint8_t
basepoint[CURVE25519_POINT_SIZE])
+bool curve25519(uint8_t mypublic[CURVE25519_POINT_SIZE], const uint8_t
secret[CURVE25519_POINT_SIZE], const uint8_t
basepoint[CURVE25519_POINT_SIZE])
{
limb bp[10], x[10], z[11], zmone[10];
uint8_t e[32];
@@ -1225,6 +1235,13 @@ void curve25519(uint8_t
mypublic[CURVE25519_POINT_SIZE], const uint8_t secret[CU
crecip(zmone, z);
fmul(z, x, zmone);
fcontract(mypublic, z);
+
+ memzero_explicit(e, sizeof(e));
+ memzero_explicit(bp, sizeof(bp));
+ memzero_explicit(x, sizeof(x));
+ memzero_explicit(z, sizeof(z));
+ memzero_explicit(zmone, sizeof(zmone));
+ return crypto_memneq(mypublic, zeros, CURVE25519_POINT_SIZE);
}
#endif
@@ -1238,5 +1255,5 @@ void curve25519_generate_secret(uint8_t
secret[CURVE25519_POINT_SIZE])
void curve25519_generate_public(uint8_t pub[CURVE25519_POINT_SIZE], const
uint8_t secret[CURVE25519_POINT_SIZE])
{
static const uint8_t basepoint[CURVE25519_POINT_SIZE] = { 9 };
- curve25519(pub, secret, basepoint);
+ curve25519(pub, secret, basepoint); /* We don't care about the return
result of this because the basepoint is always correct */
}
diff --git a/src/crypto/curve25519.h b/src/crypto/curve25519.h
index 52756d7..dc1feb9 100644
--- a/src/crypto/curve25519.h
<http://git.zx2c4.com/WireGuard/tree/src/crypto/curve25519.h?id=5e7623a1d383716350313205447d67e7bf40a4f9>
+++ b/src/crypto/curve25519.h
<http://git.zx2c4.com/WireGuard/tree/src/crypto/curve25519.h?id=eeb22e141bd46750e072bfbc20f36ab0d923ecba>
@@ -9,7 +9,7 @@ enum curve25519_lengths {
CURVE25519_POINT_SIZE = 32
};
-void curve25519(uint8_t mypublic[CURVE25519_POINT_SIZE], const uint8_t
secret[CURVE25519_POINT_SIZE], const uint8_t
basepoint[CURVE25519_POINT_SIZE]);
+bool curve25519(uint8_t mypublic[CURVE25519_POINT_SIZE], const uint8_t
secret[CURVE25519_POINT_SIZE], const uint8_t
basepoint[CURVE25519_POINT_SIZE]);
void curve25519_generate_secret(uint8_t secret[CURVE25519_POINT_SIZE]);
void curve25519_generate_public(uint8_t pub[CURVE25519_POINT_SIZE], const
uint8_t secret[CURVE25519_POINT_SIZE]);
diff --git a/src/noise/handshake.c b/src/noise/handshake.c
index ecfb6bd..ed3e149 100644
--- a/src/noise/handshake.c
<http://git.zx2c4.com/WireGuard/tree/src/noise/handshake.c?id=5e7623a1d383716350313205447d67e7bf40a4f9>
+++ b/src/noise/handshake.c
<http://git.zx2c4.com/WireGuard/tree/src/noise/handshake.c?id=eeb22e141bd46750e072bfbc20f36ab0d923ecba>
@@ -58,14 +58,16 @@ bool noise_handshake_create_initiation(struct
noise_message_handshake_initiation
noise_handshake_nocrypt(dst->unencrypted_ephemeral,
peer->handshake.ephemeral_public, NOISE_PUBLIC_KEY_LEN,
peer->handshake.hash);
/* dhes */
- noise_mix_dh(&peer->handshake.key, peer->handshake.ephemeral_private,
peer->handshake.remote_static);
+ if (!noise_mix_dh(&peer->handshake.key,
peer->handshake.ephemeral_private, peer->handshake.remote_static))
+ goto out;
/* s */
if (!noise_handshake_encrypt(dst->encrypted_static,
peer->handshake.static_public, NOISE_PUBLIC_KEY_LEN, &peer->handshake.key,
peer->handshake.hash))
goto out;
/* dhss */
- noise_mix_dh(&peer->handshake.key, peer->handshake.static_private,
peer->handshake.remote_static);
+ if (!noise_mix_dh(&peer->handshake.key, peer->handshake.static_private,
peer->handshake.remote_static))
+ goto out;
/* t */
tai64n_now_packed(timestamp);
@@ -117,14 +119,16 @@ struct wireguard_peer
*noise_handshake_consume_initiation(struct noise_message_h
noise_handshake_nocrypt(e, src->unencrypted_ephemeral,
sizeof(src->unencrypted_ephemeral), hash);
/* dhes */
- noise_mix_dh(&key, static_private, e);
+ if (!noise_mix_dh(&key, static_private, e))
+ goto out;
/* s */
if (!noise_handshake_decrypt(s, src->encrypted_static,
sizeof(src->encrypted_static), &key, hash))
goto out;
/* dhss */
- noise_mix_dh(&key, static_private, s);
+ if (!noise_mix_dh(&key, static_private, s))
+ goto out;
/* t */
if (!noise_handshake_decrypt(t, src->encrypted_timestamp,
sizeof(src->encrypted_timestamp), &key, hash))
@@ -176,10 +180,12 @@ bool noise_handshake_create_response(struct
noise_message_handshake_response *ds
goto out;
/* dhee */
- noise_mix_dh(&peer->handshake.key, peer->handshake.ephemeral_private,
peer->handshake.remote_ephemeral);
+ if (!noise_mix_dh(&peer->handshake.key,
peer->handshake.ephemeral_private, peer->handshake.remote_ephemeral))
+ goto out;
/* dhes */
- noise_mix_dh(&peer->handshake.key, peer->handshake.ephemeral_private,
peer->handshake.remote_static);
+ if (!noise_mix_dh(&peer->handshake.key,
peer->handshake.ephemeral_private, peer->handshake.remote_static))
+ goto out;
if (!noise_handshake_encrypt(dst->encrypted_nothing, NULL, 0,
&peer->handshake.key, peer->handshake.hash))
goto out;
@@ -222,10 +228,12 @@ struct wireguard_peer
*noise_handshake_consume_response(struct noise_message_han
}
/* dhee */
- noise_mix_dh(&key, peer->handshake.ephemeral_private, e);
+ if (!noise_mix_dh(&key, peer->handshake.ephemeral_private, e))
+ goto out;
/* dhes */
- noise_mix_dh(&key, peer->handshake.static_private, e);
+ if (!noise_mix_dh(&key, peer->handshake.static_private, e))
+ goto out;
/* decrypt nothing */
decrypt_success = noise_handshake_decrypt(NULL, src->encrypted_nothing,
sizeof(src->encrypted_nothing), &key, hash);
diff --git a/src/noise/key.c b/src/noise/key.c
index 03089c9..fe7dd54 100644
--- a/src/noise/key.c
<http://git.zx2c4.com/WireGuard/tree/src/noise/key.c?id=5e7623a1d383716350313205447d67e7bf40a4f9>
+++ b/src/noise/key.c
<http://git.zx2c4.com/WireGuard/tree/src/noise/key.c?id=eeb22e141bd46750e072bfbc20f36ab0d923ecba>
@@ -50,12 +50,14 @@ static inline bool derive_key(struct
noise_symmetric_key *dst, struct noise_symm
return true;
}
-void noise_mix_dh(struct noise_symmetric_key *key, const u8
private[NOISE_PUBLIC_KEY_LEN], const u8 public[NOISE_PUBLIC_KEY_LEN])
+bool noise_mix_dh(struct noise_symmetric_key *key, const u8
private[NOISE_PUBLIC_KEY_LEN], const u8 public[NOISE_PUBLIC_KEY_LEN])
{
u8 dh_calculation[NOISE_PUBLIC_KEY_LEN];
- curve25519(dh_calculation, private, public);
+ if (!curve25519(dh_calculation, private, public))
+ return false;
kdf(key, dh_calculation, NOISE_PUBLIC_KEY_LEN);
memzero_explicit(dh_calculation, NOISE_PUBLIC_KEY_LEN);
+ return true;
}
static void clear_old_session(struct rcu_head *rcu)
diff --git a/src/noise/noise.h b/src/noise/noise.h
index 940e519..18f7beb 100644
--- a/src/noise/noise.h
<http://git.zx2c4.com/WireGuard/tree/src/noise/noise.h?id=5e7623a1d383716350313205447d67e7bf40a4f9>
+++ b/src/noise/noise.h
<http://git.zx2c4.com/WireGuard/tree/src/noise/noise.h?id=eeb22e141bd46750e072bfbc20f36ab0d923ecba>
@@ -137,7 +137,7 @@ bool noise_handshake_decrypt(u8 *dst_plaintext, const
u8 *src_ciphertext, size_t
void noise_handshake_nocrypt(u8 *dst, const u8 *src, size_t src_len, u8
hash[NOISE_HASH_LEN]);
void noise_symmetric_key_init(struct noise_symmetric_key *key, const u8
responder_static[NOISE_PUBLIC_KEY_LEN]);
void noise_handshake_clear(struct noise_handshake *handshake);
-void noise_mix_dh(struct noise_symmetric_key *key, const u8
private[NOISE_PUBLIC_KEY_LEN], const u8 public[NOISE_PUBLIC_KEY_LEN]);
+bool noise_mix_dh(struct noise_symmetric_key *key, const u8
private[NOISE_PUBLIC_KEY_LEN], const u8 public[NOISE_PUBLIC_KEY_LEN]);
/* External API: */
bool noise_handshake_create_initiation(struct
noise_message_handshake_initiation *dst, struct noise_peer *peer, u16
self_index);
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://moderncrypto.org/mail-archive/noise/attachments/20151001/61ceec39/attachment.html>


More information about the Noise mailing list