RFC 8731
Secure Shell (SSH) Key Exchange Method Using Curve25519 and Curve448
RFC 8731: Secure Shell (SSH) Key Exchange Method Using Curve25519 and Curve448 π
okay bestie, this is RFC 8731 π«Ά It's an IETF doc, and it's a Standards Track one, which means it's an actual official spec. It was written by A. Adamantiadis (libssh), S. Josefsson (SJD AB), and M. Baushke (Juniper Networks, Inc.), and it came out in February 2020. Its ISSN is 2070-1721. The header doesn't list anything it obsoletes or updates, so there's nothing to call out there. πΈ
Abstract β¨
So the whole point of this doc is to spec how to use the Curve25519 and Curve448 key exchange methods in the Secure Shell (SSH) protocol. Main character energy π
Status of This Memo π¦
This is an Internet Standards Track doc, so it's official π
This doc is a product of the Internet Engineering Task Force (IETF), and it reflects the consensus of the IETF community. It got public review and was approved for publication by the Internet Engineering Steering Group (IESG). If you want more on Internet Standards, check out Section 2 of RFC 7841.
Info about the current status of this doc, any errata, and how to send feedback lives at https://www.rfc-editor.org/info/rfc8731. π
Copyright Notice π
Copyright (c) 2020 IETF Trust and the persons identified as the document authors. All rights reserved. π
This doc is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (https://trustee.ietf.org/license-info) as they stand on the publication date. Please actually read these, because they lay out your rights and restrictions for this doc π Code Components pulled out of this doc must include Simplified BSD License text, as described in Section 4.e of the Trust Legal Provisions, and they come without warranty, as described in the Simplified BSD License.
Table of Contents π§
1. Introduction
2. Requirements Language
3. Key Exchange Methods
3.1. Shared Secret Encoding
4. Security Considerations
5. IANA Considerations
6. References
6.1. Normative References
6.2. Informative References
Acknowledgements
Authors' Addresses
1. Introduction π¦
Okay so SSH [RFC4251] is a secure remote login protocol, and it's giving very "trust me." π The key exchange protocol in [RFC4253] supports an extensible set of methods, and [RFC5656] explains how elliptic curves get plugged into that extensible SSH framework. This doc reuses the Elliptic Curve Diffie-Hellman (ECDH) key exchange protocol messages defined in Section 7.1 (ECDH Message Numbers) of [RFC5656]. The other parts of [RFC5656], like Elliptic Curve Menezes-Qu-Vanstone (ECMQV) key agreement and Elliptic Curve Digital Signature Algorithm (ECDSA), are not in scope here π ββοΈ
This doc explains how to implement key exchange based on Curve25519 and Curve448 [RFC7748] in SSH β¨ For Curve25519 with SHA-256 [RFC6234][SHS], the algorithm is equivalent to the privately defined algorithm "curve25519-sha256@libssh.org". At the time of publication, that one was implemented and widely deployed in libssh [libssh] and OpenSSH [OpenSSH], so it's been a whole thing π The Curve448 key exchange method is similar, except it uses SHA-512 [RFC6234][SHS] instead.
2. Requirements Language π
Here's how the key words work. In this doc, "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" get interpreted as described in BCP 14 [RFC2119] [RFC8174], but only when they show up in all capitals, like they do right here π«Ά
3. Key Exchange Methods πΈ
The key exchange procedure is basically the ECDH method from Section 4 of [RFC5656], just with a different wire encoding for the public values and the final shared secret. Public ephemeral keys get 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 all identical to Section 4 of [RFC5656]. Same vibes, no notes π
The method names this doc registers are "curve25519-sha256" and "curve448-sha512" β¨
These methods are built on Curve25519 and Curve448 scalar multiplication, as described in [RFC7748]. Private and public keys get generated the way that RFC describes. Public keys are strings of 32 bytes for Curve25519 and 56 bytes for Curve448 π
The key-agreement schemes "curve25519-sha256" and "curve448-sha512" do the Diffie-Hellman protocol using the functions X25519 and X448, respectively. Implementations SHOULD compute these functions with the algorithms in [RFC7748]. When they do, implementations MUST check whether the computed Diffie-Hellman shared secret is the all-zero value, and abort if it is, as described in Section 6 of [RFC7748]. Alternative implementations of these functions SHOULD abort when either the client's or the server's input forces the shared secret into one of a small set of values, as described in Sections 6 and 7 of [RFC7748]. Clients and servers MUST also abort if the received public keys aren't the expected lengths π€
For these purposes, an abort is defined as a disconnect (SSH_MSG_DISCONNECT) of the session, and it SHOULD use the SSH_DISCONNECT_KEY_EXCHANGE_FAILED reason for the message [IANA-REASON]. No further validation is required beyond what [RFC7748] already describes β
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 [RFC7748]. The hash is SHA-256 for "curve25519-sha256" and SHA-512 for "curve448-sha512" π₯
3.1. Shared Secret Encoding π
This step is different from [RFC5656], which uses a different conversion. It's not meant to change that text in general, just to fit the scope of the mechanism in this doc π
The shared secret, K, is defined in [RFC4253] and [RFC5656] 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 you get from scalar multiplication of the other side's public key and the local private key scalar. To turn those 32 or 56 bytes of X into K, you interpret the octets as an unsigned fixed-length integer encoded in network byte order. Iconic π§
Then the mpint K gets encoded using the process in Section 5 of [RFC4251], and the resulting bytes are fed, as described in [RFC4253], into the key exchange method's hash function to generate encryption keys π¦
When you're doing the X25519 or X448 operations, the integer values get encoded into byte strings with a fixed-length unsigned little-endian conversion, per [RFC7748]. It's only later, when those byte strings get passed to the ECDH function in SSH, that the bytes are reinterpreted as a fixed-length unsigned big-endian integer value K. After that, K gets encoded as a variable-length signed "mpint" before it's fed into the hash algorithm used for key generation. Then the mpint K gets fed, along with other data, into the key exchange method's hash function to generate encryption keys. It's a whole journey, bestie ππ
Okay bestie, let's finish this one off π π
7. Acknowledgements β¨
The curve25519-sha256 key exchange method is identical to the curve25519-sha256@libssh.org key exchange method that Aris Adamantiadis made and put into libssh and OpenSSH. Like, he's the original genius here π«ΆπΈ
Thanks to these amazing people for reviewing and commenting: Denis Bider, Damien Miller, Niels Moeller, Matt Johnston, Eric Rescorla, Ron Frederick, and Stefan Buehler. Y'all are literal legends ππ
Authors' Addresses
Aris Adamantiadis libssh
Email: aris@badcode.be π¦
Simon Josefsson SJD AB
Email: simon@josefsson.org π§
Mark D. Baushke Juniper Networks, Inc.
Email: mdb@juniper.net π
π¦ where this page comes from
- ietf: rfc8731 2020-02
- π girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms