diff options
author | Michael Brown <mcb30@ipxe.org> | 2024-01-30 13:14:21 +0000 |
---|---|---|
committer | Michael Brown <mcb30@ipxe.org> | 2024-01-30 13:21:01 +0000 |
commit | 27398f136030efb8845c45fbe154e544feefd7e5 (patch) | |
tree | 11a7010a065c90bb0e0cd8040a158cf9cb41e09c /src/crypto | |
parent | de8a0821c7bc737e724fa3dfb6d89dc36f591d7a (diff) | |
download | ipxe-27398f136030efb8845c45fbe154e544feefd7e5.tar.gz |
[crypto] Check for all-zeros result from X25519 key exchange
RFC7748 states that it is entirely optional for X25519 Diffie-Hellman
implementations to check whether or not the result is the all-zero
value (indicating that an attacker sent a malicious public key with a
small order). RFC8422 states that implementations in TLS must abort
the handshake if the all-zero value is obtained.
Return an error if the all-zero value is obtained, so that the TLS
code will not require knowledge specific to the X25519 curve.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/crypto')
-rw-r--r-- | src/crypto/x25519.c | 11 |
1 files changed, 8 insertions, 3 deletions
diff --git a/src/crypto/x25519.c b/src/crypto/x25519.c index 750a2a71c..d3a19bc8e 100644 --- a/src/crypto/x25519.c +++ b/src/crypto/x25519.c @@ -59,6 +59,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); #include <stdint.h> #include <string.h> #include <assert.h> +#include <errno.h> #include <ipxe/init.h> #include <ipxe/x25519.h> @@ -781,10 +782,11 @@ static void x25519_reverse ( struct x25519_value *value ) { * @v base Base point * @v scalar Scalar multiple * @v result Point to hold result (may overlap base point) + * @ret rc Return status code */ -void x25519_key ( const struct x25519_value *base, - const struct x25519_value *scalar, - struct x25519_value *result ) { +int x25519_key ( const struct x25519_value *base, + const struct x25519_value *scalar, + struct x25519_value *result ) { struct x25519_value *tmp = result; union x25519_quad257 point; @@ -805,4 +807,7 @@ void x25519_key ( const struct x25519_value *base, /* Reverse result */ bigint_done ( &point.value, result->raw, sizeof ( result->raw ) ); x25519_reverse ( result ); + + /* Fail if result was all zeros (as required by RFC8422) */ + return ( bigint_is_zero ( &point.value ) ? -EPERM : 0 ); } |