From e400e93bccaaf4bfc6813a15f45100f2abaa6f40 Mon Sep 17 00:00:00 2001 From: Simon Tatham Date: Sat, 23 Mar 2019 07:55:58 +0000 Subject: [PATCH] Reduce Curve25519 public values mod 2^255. I just spotted this requirement in RFC 7748. A _sensible_ Ed25519 public value is an integer less than p=2^255-19, but the transport format allows encoding of numbers up to 2^256, and RFC 7748 has a specific recommendation for what to do with overlarge ones: namely, ignore the topmost bit if it is set (i.e. reduce mod 2^255), and deal with the remaining 19 overlarge values by reducing mod p. Apparently the purpose is to 'increase resistance to implementation fingerprinting', so the lack of this step wasn't a serious interoperability or security issue. --- sshecc.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/sshecc.c b/sshecc.c index 2bbed6da..e414c468 100644 --- a/sshecc.c +++ b/sshecc.c @@ -1357,6 +1357,14 @@ static mp_int *ssh_ecdhkex_w_getkey(ecdh_key *dh, ptrlen remoteKey) static mp_int *ssh_ecdhkex_m_getkey(ecdh_key *dh, ptrlen remoteKey) { mp_int *remote_x = mp_from_bytes_le(remoteKey); + + /* Per RFC 7748 section 5, discard any set bits of the other + * side's public value beyond the minimum number of bits required + * to represent all valid values. However, an overlarge value that + * still fits into the remaining number of bits is accepted, and + * will be reduced mod p. */ + mp_reduce_mod_2to(remote_x, dh->curve->fieldBits); + if (mp_eq_integer(remote_x, 0)) { /* * The libssh spec for Curve25519 key exchange says that