The key exchange procedure is similar to the ECDH method described in Section 4
of RFC 5656
, though with a different wire encoding used for public values and the final shared secret. Public ephemeral keys are encoded for transmission as standard SSH strings.
The protocol flow, the SSH_MSG_KEX_ECDH_INIT and SSH_MSG_KEX_ECDH_REPLY messages, and the structure of the exchange hash are identical to Section 4
of RFC 5656
The method names registered by this document are "curve25519-sha256" and "curve448-sha512".
The methods are based on Curve25519 and Curve448 scalar multiplication, as described in [RFC 7748
]. Private and public keys are generated as described therein. Public keys are defined as strings of 32 bytes for Curve25519 and 56 bytes for Curve448.
The key-agreement schemes "curve25519-sha256" and "curve448-sha512" perform the Diffie-Hellman protocol using the functions X25519 and X448, respectively. Implementations SHOULD
compute these functions using the algorithms described in [RFC 7748
]. When they do so, implementations MUST
check whether the computed Diffie-Hellman shared secret is the all-zero value and abort if so, as described in Section 6
of RFC 7748
. Alternative implementations of these functions SHOULD
abort when either the client or the server input forces the shared secret to one of a small set of values, as described in Sections 6
of [RFC 7748
]. Clients and servers MUST
also abort if the length of the received public keys are not the expected lengths. An abort for these purposes is defined as a disconnect (SSH_MSG_DISCONNECT) of the session and SHOULD
use the SSH_DISCONNECT_KEY_EXCHANGE_FAILED reason for the message [IANA-REASON
]. No further validation is required beyond what is described in [RFC 7748
]. The derived shared secret is 32 bytes when "curve25519-sha256" is used and 56 bytes when "curve448-sha512" is used. The encodings of all values are defined in [RFC 7748
]. The hash used is SHA-256 for "curve25519-sha256" and SHA-512 for "curve448-sha512".
The following step differs from [RFC 5656
], which uses a different conversion. This is not intended to modify that text generally, but only to be applicable to the scope of the mechanism described in this document.
The shared secret, K, is defined in [RFC 4253
] and [RFC 5656
] as an integer encoded as a multiple precision integer (mpint). Curve25519/448 outputs a binary string X, which is the 32- or 56-byte point obtained by scalar multiplication of the other side's public key and the local private key scalar. The 32 or 56 bytes of X are converted into K by interpreting the octets as an unsigned fixed-length integer encoded in network byte order.
The mpint K is then encoded using the process described in Section 5
of RFC 4251
, and the resulting bytes are fed as described in [RFC 4253
] to the key exchange method's hash function to generate encryption keys.
When performing the X25519 or X448 operations, the integer values there will be encoded into byte strings by doing a fixed-length unsigned little-endian conversion, per [RFC 7748
]. It is only later when these byte strings are then passed to the ECDH function in SSH that the bytes are reinterpreted as a fixed-length unsigned big-endian integer value K, and then later that K value is encoded as a variable-length signed "mpint" before being fed to the hash algorithm used for key generation. The mpint K is then fed along with other data to the key exchange method's hash function to generate encryption keys.