Internet Engineering Task Force d. bider
Internet-Draft Bitvise Limited
Intended status: Informational 7 July 2020
Expires: 8 January 2021
QUIC-based UDP Transport for Secure Shell (SSH)
draft-bider-ssh-quic-01
Abstract
The Secure Shell protocol (SSH) [RFC4251] is widely used for purposes
including secure remote administration, file transfer using SFTP and
SCP, and encrypted tunneling of TCP connections. Because it is based
on TCP, SSH suffers similar problems as motivate the HTTP protocol to
transition its transport to UDP-based QUIC [QUIC]. These include:
unauthenticated network intermediaries can trivially disconnect SSH
sessions; SSH connections are lost when mobile clients change IP
addresses; performance limitations in OS-based TCP stacks; any many
round-trips to establish the connection. This memo specifies SSH key
exchange over UDP and leverages QUIC to provide a UDP-based
transport.
Status of This Memo
This Internet-Draft is submitted in full conformance with the
provisions of BCP 78 and BCP 79.
Internet-Drafts are working documents of the Internet Engineering
Task Force (IETF). Note that other groups may also distribute
working documents as Internet-Drafts. The list of current Internet-
Drafts is at https://datatracker.ietf.org/drafts/current/.
Internet-Drafts are draft documents valid for a maximum of six months
and may be updated, replaced, or obsoleted by other documents at any
time. It is inappropriate to use Internet-Drafts as reference
material or to cite them other than as "work in progress."
This Internet-Draft will expire on 8 January 2021.
Copyright Notice
Copyright (c) 2020 IETF Trust and the persons identified as the
document authors. All rights reserved.
This document is subject to BCP 78 and the IETF Trust's Legal
Provisions Relating to IETF Documents (https://trustee.ietf.org/
license-info) in effect on the date of publication of this document.
bider Expires 8 January 2021 [Page 1]
Internet-Draft SSH/QUIC July 2020
Please review these documents carefully, as they describe your rights
and restrictions with respect to this document. Code Components
extracted from this document must include Simplified BSD License text
as described in Section 4.e of the Trust Legal Provisions and are
provided without warranty as described in the Simplified BSD License.
Table of Contents
1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 2
1.1. Requirements Terminology . . . . . . . . . . . . . . . . 3
2. SSH/QUIC key exchange . . . . . . . . . . . . . . . . . . . . 3
2.1. Distinguishing SSH key exchange from QUIC datagrams . . . 3
2.2. Wire Encoding . . . . . . . . . . . . . . . . . . . . . . 3
2.3. Packet Limits . . . . . . . . . . . . . . . . . . . . . . 4
2.4. Required TLS Cipher Suites . . . . . . . . . . . . . . . 4
2.5. Random Elements . . . . . . . . . . . . . . . . . . . . . 4
2.6. Errors in Key Exchange . . . . . . . . . . . . . . . . . 6
2.6.1. "disc-reason" Extension Pair . . . . . . . . . . . . 6
2.6.2. "err-desc" Extension Pair . . . . . . . . . . . . . . 6
2.7. SSH_QUIC_INIT . . . . . . . . . . . . . . . . . . . . . . 6
2.7.1. Extensibility . . . . . . . . . . . . . . . . . . . . 9
2.8. SSH_QUIC_REPLY . . . . . . . . . . . . . . . . . . . . . 10
2.8.1. Error Reply . . . . . . . . . . . . . . . . . . . . . 12
2.8.2. Extensibility . . . . . . . . . . . . . . . . . . . . 13
2.9. SSH_QUIC_CANCEL . . . . . . . . . . . . . . . . . . . . . 14
2.9.1. Extensibility . . . . . . . . . . . . . . . . . . . . 15
3. Key Exchange Methods . . . . . . . . . . . . . . . . . . . . 15
3.1. Required Key Exchange Methods . . . . . . . . . . . . . . 16
3.2. Example: "curve25519-sha256" . . . . . . . . . . . . . . 17
4. SSH_MSG_EXT_INFO and the SSH Version String . . . . . . . . . 17
4.1. "ssh-version" Extension . . . . . . . . . . . . . . . . . 18
5. QUIC Session Setup . . . . . . . . . . . . . . . . . . . . . 19
5.1. Shared Secrets . . . . . . . . . . . . . . . . . . . . . 19
6. SSH/QUIC Packet Format . . . . . . . . . . . . . . . . . . . 20
7. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 21
8. Security Considerations . . . . . . . . . . . . . . . . . . . 21
9. References . . . . . . . . . . . . . . . . . . . . . . . . . 21
9.1. Normative References . . . . . . . . . . . . . . . . . . 21
9.2. Informative References . . . . . . . . . . . . . . . . . 22
Appendix A. Appendix: Generating Random Lengths . . . . . . . . 22
Author's Address . . . . . . . . . . . . . . . . . . . . . . . . 23
1. Introduction
THIS DOCUMENT IS AN EARLY VERSION AND IS A WORK IN PROGRESS.
NON-LATEST DRAFT VERSIONS MUST BE DISREGARDED.
bider Expires 8 January 2021 [Page 2]
Internet-Draft SSH/QUIC July 2020
IMPLEMENTATION AT THIS STAGE IS EXPERIMENTAL.
CONTACT THE AUTHOR IF YOU INTEND TO IMPLEMENT.
This memo specifies SSH key exchange over UDP, and then leverages
QUIC to provide a UDP-based transport for SSH. QUIC's use of the TLS
handshake is replaced with a 1-RTT SSH/QUIC key exchange. The SSH
Authentication Protocol [RFC4252] and the SSH Connection Protocol
[RFC4254] are then conducted over UDP stream 0 in the same way as
they would be over TCP.
1.1. Requirements Terminology
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
"SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and
"OPTIONAL" in this document are to be interpreted as described in
BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all
capitals, as shown here.
2. SSH/QUIC key exchange
2.1. Distinguishing SSH key exchange from QUIC datagrams
UDP datagrams which form the SSH/QUIC key exchange are sent between
the same client and server IP addresses and ports as QUIC datagrams.
It is therefore necessary for clients and servers to distinguish SSH
key exchange datagrams from QUIC datagrams.
A distinction is allowed by that SSH/QUIC only requires the sending
of QUIC Short Header Packets. Therefore, all UDP datagrams where the
first byte has its high bit set can be handled as part of an SSH/QUIC
key exchange.
2.2. Wire Encoding
This memo uses wire encoding types "byte", "uint32", "mpint" and
"string" with meanings as described in [RFC4251].
This memo defines a new wire encoding type "short-str", encoded as
follows:
byte n = short-str-len (valid values: 0..255)
byte[n] short-str-value
Figure 1
bider Expires 8 January 2021 [Page 3]
Internet-Draft SSH/QUIC July 2020
2.3. Packet Limits
Clients and servers MUST accept SSH_QUIC_INIT, SSH_QUIC_REPLY and
SSH_QUIC_CANCEL packets of sizes at least up to 32768 bytes. This
corresponds to minimum SSH packet limits which implementations must
support as per [RFC4253], Section 6.1.
2.4. Required TLS Cipher Suites
Clients and servers are REQUIRED to implement the TLS cipher suites
TLS_AES_128_GCM_SHA256 and TLS_AES_256_GCM_SHA384 [RFC8446]. Other
cipher suites are optional.
Clients and servers MAY permit the user to disable a required cipher
suite. However, required suites MUST be enabled by default.
2.5. Random Elements
Unlike SSH over TCP, the packets SSH_QUIC_INIT and SSH_QUIC_REPLY do
not provide a "cookie" field for random data. Instead, clients and
servers MUST insert random data using the Extensibility mechanisms.
At the very minimum, clients and servers MUST insert at least 16
Random Bytes or at least one Random Name, as described in
Section 2.7.1 and Section 2.8.2. If at all possible, the random data
MUST come from a cryptographically strong random source.
Implementations that are unable to meet this requirement MUST still
insert the minimum amount of random data, as unpredictably as they
are able. Compromising on this requirement reduces the security of
any sessions created on the basis of such SSH_QUIC_INIT and
SSH_QUIC_REPLY.
Lengths of Random Names and Random Bytes SHOULD be chosen at random
such that lengths in the shorter end of the range are significantly
more probable, but long lengths are still selected. See Appendix A.
Random Bytes
Random Bytes are generated with values 0..255, in a range of lengths
as specified for the particular usage context.
Random Name
A Random Name is generated in one of two forms: Assigned Form or
Private Form. One of the two forms is randomly chosen so that
Assigned Form, which is shorter, is more likely. The maximum length
of a Random Name is 64 bytes.
bider Expires 8 January 2021 [Page 4]
Internet-Draft SSH/QUIC July 2020
Assigned Form
A Random Name in Assigned Form is generated as a string of random
characters with ASCII values 33..126 (inclusive), except @ and the
comma (","). Other characters MUST NOT be included. To avoid
collisions as effectively as a random UUID, a Random Name in Assigned
Form MUST contain at least 20 random characters if the complete
character set is used. A Random Name in Assigned Form MUST then be
of length 20..64 bytes.
Implementations MAY remove up to 7 characters from the character set
-- reducing it to 85..91 characters -- without increasing the minimum
length. If the character set is further reduced to 69..84
characters, implementations MUST generate at least 21 random
characters instead.
Example Random Names in Assigned Form:
d`kbi>AGrj~r{3lo_Q4r
wNT)=/8C<(DB1|tr:>1f[xq>9bG
u7^dE'\EE_}N}^"J5syI?/8jIxup#s7BM:]>{IT_p3Z~wJDYIBX.4zzQ$@denisbider.com
?`z4bb/}
&Wuf6O7CE?cA`$j"@bider.us
Figure 3
Alternately, implementations MAY generate a Random Name in Anonymous
Form with the format "(local)@(domain).example.com". In this case,
both "(local)" and "(domain)" are replaced by random ASCII characters
from the set A..Z, a..z, and 0..9. This is to ensure that the suffix
has valid domain name syntax.
To avoid collisions as effectively as a random UUID, a Random Name in
Anonymous Form MUST contain at least 22 random characters. A Random
Name in Anonymous Form MUST then be of length 35..64 bytes.
bider Expires 8 January 2021 [Page 5]
Internet-Draft SSH/QUIC July 2020
2.6. Errors in Key Exchange
To assist users, clients and servers SHOULD report key exchange
errors as follows:
1. If a server cannot send a successful SSH_QUIC_REPLY, it SHOULD
send an Error Reply. See Section 2.8.1.
2. If a client receives an invalid SSH_QUIC_REPLY, it SHOULD send an
SSH_QUIC_CANCEL. See Section 2.9.
Both packet types use the following extension pairs.
2.6.1. "disc-reason" Extension Pair
"ext-pair-name" contains "disc-reason".
"ext-pair-data" encodes a uint32 with the SSH disconnect reason code.
Reason codes are defined in the table "Disconnect Messages Reason
Codes and Descriptions" in the IANA registry "Secure Shell (SSH)
Protocol Parameters" [IANA-SSH].
2.6.2. "err-desc" Extension Pair
"ext-pair-name" contains "err-desc".
"ext-pair-data" encodes a human-readable error description in any
language intended to be relevant to the user, encoded as UTF-8.
Receivers that process error descriptions MUST validate that the
description is valid UTF-8. If a description is long, receivers
SHOULD truncate it to a reasonable length depending on the processing
context. For example, a debug log file can record a full 32 kB error
description, while a production log file SHOULD truncate it to a much
shorter length.
2.7. SSH_QUIC_INIT
A client begins an SSH/QUIC session by sending one or more copies of
SSH_QUIC_INIT. If multiple copies are sent, copies intended for the
same connection MUST be identical. A reasonable strategy is to send
one copy every 50 - 500 ms until the client receives a valid
SSH_QUIC_REPLY or times out. A server MUST remember recently
received SSH_QUIC_INIT packets and send identical SSH_QUIC_REPLY
responses. If different SSH_QUIC_INIT packets are received from the
same client IP address, the server MUST assume they are intended to
begin separate connections, even if they specify the same "client-
connection-id". A server MAY implement throttling of incoming
bider Expires 8 January 2021 [Page 6]
Internet-Draft SSH/QUIC July 2020
connections, by IP address or otherwise, where excessive
SSH_QUIC_INIT packets are disregarded. Once a server receives QUIC
data confirming that a client has processed an SSH_QUIC_REPLY, the
server MUST disregard any further identical copies of the same
SSH_QUIC_INIT, at least until the SSH/QUIC session started by such an
SSH_QUIC_INIT ends.
The SSH_QUIC_INIT packet is a UDP datagram with the following layout:
byte SSH_QUIC_INIT = 0x80 (see Extensibility)
short-str client-connection-id (MAY be empty)
byte v = nr-quic-versions (MUST NOT be zero)
uint32[v] client-quic-versions
string client-sig-algs (MUST NOT be empty)
byte f = nr-trusted-fingerprints (MAY be zero)
the following 1 field repeated f times:
short-str trusted-fingerprint (MUST NOT be empty)
byte k = nr-client-kex-algs (MUST NOT be zero)
the following 2 fields repeated k times:
short-str client-kex-alg-name (MUST NOT be empty)
string client-kex-alg-data (MUST NOT be empty)
byte c = nr-cipher-suites (MUST NOT be zero)
the following 1 field repeated c times:
short-str quic-tls-cipher-suite
byte e = nr-ext-pairs (see Extensibility)
the following 2 fields repeated e times:
short-str ext-pair-name (MUST NOT be empty)
string ext-pair-data (MAY be empty)
byte[0..] padding: all 0xFF to minimal packet size 1400
Figure 4
SSH_QUIC_INIT does not include an SSH version string. Instead,
clients MUST use SSH_MSG_EXT_INFO for this purpose. See Section 4.
SSH_QUIC_INIT does not include a "cookie" field for random data.
Clients MUST insert random data using Extensibility mechanisms. See
Section 2.7.1 and Section 2.5.
bider Expires 8 January 2021 [Page 7]
Internet-Draft SSH/QUIC July 2020
The field "client-connection-id" contains a QUIC Connection ID of
length 0..20 bytes. The server will use this as the QUIC Destination
Connection ID in QUIC packets sent to the client. Clients are not
required to use a Connection ID if they are using other means of
routing connections.
The fields "client-quic-versions" enumerate QUIC protocol versions
supported by the client. The client MUST send at least one version.
The client MUST send supported versions in the order it prefers the
server to use them.
The field "client-sig-algs" MUST contain at least one signature
algorithm supported by the client for server authentication. These
are the same algorithms as used in SSH_MSG_KEXINIT ([RFC4253],
Section 7.1) in the field "server_host_key_algorithms". The client
MUST send signature algorithms in the order it prefers the server to
use them.
There MAY be zero or more "trusted-fingerprint" fields. Each
"trusted-fingerprint" contains a binary fingerprint of a host key
that is trusted for this connection by the client. The fingerprint
algorithm is left unspecified. The server SHOULD try to match the
fingerprint using all algorithms it supports which produce the
provided fingerprint size. The current recommended fingerprint
algorithm is SHA-256, with fingerprint size 32 bytes. Servers MUST
tolerate the presence of unrecognized fingerprints of any size. The
client MUST send trusted host key fingerprints in the order it
prefers the server to use them.
The packet MUST include at least one SSH key exchange algorithm,
encoded as a pair of "client-kex-alg-name" and "client-kex-alg-data"
fields. The field "client-kex-alg-name" MUST specify a key exchange
method which would be valid in the field "kex_algorithms" in
SSH_MSG_KEXINIT under [RFC4253], Section 7.1. In addition, the key
exchange method MUST meet criteria in Section 3.
If the client wishes to simply advertise its support for a particular
key exchange algorithm, but does not prefer to use it in this
connection, it MAY enumerate the algorithm with empty "client-kex-
alg-data". Otherwise, if the client wishes to allow the algorithm to
be used, it MUST include non-empty "client-kex-alg-data". In this
case, "client-kex-alg-data" contains the client's portion of key
exchange inputs as specified in Section 3. The client MAY send
multiple key exchange algorithms with filled-out "client-kex-alg-
data". The client MUST send these algorithms in the order it prefers
the server to use them.
bider Expires 8 January 2021 [Page 8]
Internet-Draft SSH/QUIC July 2020
There MUST be at least one "quic-tls-cipher-suite" field. Each of
these specifies a TLS cipher suite ([RFC8446], Appendix B.4) which is
supported by the client, and which can be used with a version of QUIC
([QUIC], [QUIC-TLS]) supported by the client. The client MUST
enumerate supported cipher suites in the order it prefers the server
to use them.
The client MAY send any number of extensions, encoded as a pair of
"ext-pair-name" and "ext-pair-data" fields. This memo defines no
extensions, but see Section 2.7.1.
The "padding" field contains all 0xFF bytes to ensure SSH_QUIC_INIT
is at least 1400 bytes in length. Servers MUST ignore SSH_QUIC_INIT
packets with a UDP datagram size less than 1400 bytes. This is
REQUIRED to prevent abuse of SSH_QUIC_INIT for Amplified Reflection
DDoS. If the size of SSH_QUIC_INIT is already 1400 bytes or larger,
the padding MAY be omitted.
2.7.1. Extensibility
Implementations MUST allow room for future extensibility of
SSH_QUIC_INIT in the following manners:
1. By using a different packet type in the first byte -- this is, a
value other than 0x80 used by SSH_QUIC_INIT. Servers MUST NOT
penalize clients for sending unknown packet types unless there is
another reason to penalize the client, such as a blocked IP
address or the sheer volume of datagrams.
2. By including algorithms in "client-sig-algs" which are unknown to
or not supported by the server. Servers MUST tolerate the
presence of such algorithms.
3. By including fingerprints in "trusted-fingerprints" that use
algorithms or lengths that are unknown to or not supported by the
server. Servers MUST tolerate the presence of such fingerprints.
4. By including SSH key exchange algorithms which are unknown to or
not supported by the server, with algorithm data in a format
that's unknown to or not supported by the server. Servers MUST
tolerate the presence of such algorithms and their data.
5. By including QUIC TLS cipher suites which are unknown to or not
supported by the server. Servers MUST tolerate the presence of
such cipher suites.
bider Expires 8 January 2021 [Page 9]
Internet-Draft SSH/QUIC July 2020
6. By including extensions which are unknown to or not supported by
the server, with extension data in a format that's unknown to or
not supported by the server. Servers MUST tolerate the presence
of such extensions and their data.
Experience shows that any extensibility which is not actively
exercised is lost due to implementations that lock down expectations
incorrectly. Therefore, all clients MUST do at least one of the
following, in each SSH_QUIC_INIT packet, at random:
1. In the field "client-sig-algs", include in a random position at
least one Random Name (Section 2.5).
2. In the fields "client-quic-versions", include in a random
position a version number of the form 0x0A?A?A?A, where ?
indicates a random nibble. See [QUIC], section "Versions". Note
the difference from the random version pattern in the server's
SSH_QUIC_REPLY. Due to the minimal amount of entropy provided by
this rule, this MUST NOT be the only insertion of randomness made
in a packet.
3. Include in a random position at least one host key fingerprint
consisting of 16..255 Random Bytes (Section 2.5).
4. Include in a random position at least one SSH key exchange
algorithm where the field "client-kex-alg-name" contains a Random
Name, and the field "client-kex-alg-data" contains 0..1000 Random
Bytes.
5. In the fields "quic-tls-cipher-suite", include in a random
position at least one entry consisting of 16..255 Random Bytes.
6. In extension pairs, include in a random position at least one
extension where the field "ext-pair-name" contains a Random Name,
and the field "ext-pair-value" contains 0..1000 Random Bytes.
2.8. SSH_QUIC_REPLY
Implementations MUST take care to prevent abuse of the SSH/QUIC key
exchange for Amplified Reflection DDoS attacks. This means:
1. A server MUST NOT send more than one SSH_QUIC_REPLY in response
to any individual SSH_QUIC_INIT.
2. A server MUST NOT respond to any SSH_QUIC_INIT smaller than 1400
bytes.
bider Expires 8 January 2021 [Page 10]
Internet-Draft SSH/QUIC July 2020
3. Before sending an SSH_QUIC_REPLY, the server MUST verify that the
reply is shorter than the SSH_QUIC_INIT packet to which it is
replying. If this is not the case, the server MUST send an Error
Reply (Section 2.8.1). Such an Error Reply MUST be shorter than
the SSH_QUIC_INIT packet.
The SSH_QUIC_REPLY packet is a UDP datagram with the following
layout:
byte SSH_QUIC_REPLY = 0x81
short-str server-connection-id (Non-empty except on error)
byte v = nr-quic-versions (MUST NOT be zero)
uint32[v] server-quic-versions
string server-sig-algs (MUST NOT be empty)
string server-kex-algs (MUST NOT be empty)
byte c = nr-cipher-suites (MUST NOT be zero)
the following 1 field repeated c times:
short-str quic-tls-cipher-suite
byte e = nr-ext-pairs (see Extensibility)
the following 2 fields repeated e times:
short-str ext-pair-name (MUST NOT be empty)
string ext-pair-data (MAY be empty)
string server-kex-alg-data (Non-empty except on error)
Figure 5
SSH_QUIC_REPLY does not include an SSH version string. Instead,
servers MUST use SSH_MSG_EXT_INFO for this purpose. See Section 4.
SSH_QUIC_REPLY does not include a "cookie" field for random data.
Servers MUST insert random data using Extensibility mechanisms. See
Section 2.8.2 and Section 2.5.
The field "server-connection-id" contains a QUIC Connection ID of
length 0..20 bytes. The client will use this as the QUIC Destination
Connection ID in QUIC packets sent to the server.
The fields "server-quic-versions" enumerate QUIC protocol versions
supported by the server. The server MUST send at least one version.
The QUIC version used for the connection is the first version
enumerated in "client-quic-versions" which is also present in
"server-quic-versions". If there is no such version, see
Section 2.8.1.
bider Expires 8 January 2021 [Page 11]
Internet-Draft SSH/QUIC July 2020
The field "server-sig-algs" MUST contain at least one signature
algorithm supported by the server. These are the same algorithms as
used in SSH_MSG_KEXINIT ([RFC4253], Section 7.1) in the field
"server_host_key_algorithms". The server MUST use a host key it
possesses that (1) matches any fingerprint enumerated in the
"trusted-fingerprint" fields in SSH_QUIC_INIT, regardless of
fingerprint position; and (2) can be used with the earliest possible
signature algorithm enumerated in "client-sig-algs". If there is no
such host key, the server MUST use any host key that can be used with
the earliest possible signature algorithm enumerated in "client-sig-
algs". If there is no such host key either, see Section 2.8.1.
...
...
...
...
...
...
...
The server MAY send any number of extensions, encoded as a pair of
"ext-pair-name" and "ext-pair-data" fields. This memo defines no
extensions, but see Section 2.8.2.
2.8.1. Error Reply
If a server encounters an error which is appropriate to communicate
to the client, the server MAY send an "Error Reply" version of
SSH_QUIC_REPLY. Such a reply is created as follows:
* The server includes and populates all fields of SSH_QUIC_REPLY as
it would normally, except that the fields "server-connection-id"
and "server-kex-alg-data" MUST remain empty.
* In the extension pair fields, a "disc-reason" Extension Pair MUST
be included. An "err-desc" Extension Pair MAY also be included.
See Section 2.6.
* Extensibility considerations in Section 2.8.2 also apply to an
Error Reply.
bider Expires 8 January 2021 [Page 12]
Internet-Draft SSH/QUIC July 2020
If the server does not support any of the QUIC protocol versions
enumerated by the client, the server SHOULD send an Error Reply with
the disconnect reason code
SSH_DISCONNECT_PROTOCOL_VERSION_NOT_SUPPORTED.
In the following circumstances, the server SHOULD send an Error Reply
with the disconnect reason code SSH_DISCONNECT_KEY_EXCHANGE_FAILED:
* If the server could have sent a successful SSH_QUIC_REPLY, but it
would have been larger than the client's SSH_QUIC_INIT.
* If the server possesses no server host key that can be used with a
signature algorithm enumerated in the client's SSH_QUIC_INIT.
* If the server supports no key exchange algorithms matching the
ones for which the client sent "client-kex-alg-data" in its
SSH_QUIC_INPUT.
* If the server supports no TLS cipher suites enumerated in the
client's SSH_QUIC_INIT.
Besides "disc-reason", an "err-desc" extension pair SHOULD be
included to describe the specific error.
2.8.2. Extensibility
Implementations MUST allow room for future extensibility of
SSH_QUIC_REPLY in the following manners:
1. By including algorithms in "server-sig-algs" which are unknown to
or not supported by the client. Clients MUST tolerate the
presence of such algorithms.
2. By including SSH key exchange algorithms which are unknown to or
not supported by the server, with algorithm data in a format
that's unknown to or not supported by the server. Servers MUST
tolerate the presence of such algorithms and their data.
3. By including QUIC TLS cipher suites which are unknown to or not
supported by the client. Clients MUST tolerate the presence of
such cipher suites.
4. By including extensions which are unknown to or not supported by
the client, with extension data in a format that's unknown to or
not supported by the client. Clients MUST tolerate the presence
of such extensions and their data.
bider Expires 8 January 2021 [Page 13]
Internet-Draft SSH/QUIC July 2020
Experience shows that any extensibility which is not actively
exercised is lost due to implementations that lock down expectations
incorrectly. Therefore, all servers MUST do at least one of the
following, in each SSH_QUIC_REPLY packet, at random:
1. In the fields "server-quic-versions", include in a random
position a version number of the form 0xFA?A?A?A, where ?
indicates a random nibble. See [QUIC], section "Versions". Note
the difference from the random version pattern in the client's
SSH_QUIC_INIT. Due to the minimal amount of entropy provided by
this rule, this MUST NOT be the only insertion of randomness made
in a packet.
2. In the field "server-sig-algs", include in a random position one
Random Name (Section 2.5).
3. In the field "server-kex-algs", include in a random position one
Random Name (Section 2.5).
4. In the fields "quic-tls-cipher-suite", include in a random
position one entry consisting of 16..100 Random Bytes.
5. In extension pairs, include in a random position one extension
pair where the field "ext-pair-name" contains a Random Name, and
the field "ext-pair-value" contains 0..100 Random Bytes.
2.9. SSH_QUIC_CANCEL
If a client cannot process the server's successful SSH_QUIC_REPLY,
the client SHOULD report the error to the server using
SSH_QUIC_CANCEL.
A client MUST NOT send an SSH_QUIC_CANCEL in response to an
SSH_QUIC_REPLY which is itself an Error Reply. A client MUST assume
that such a connection was already canceled by the server.
The SSH_QUIC_CANCEL packet is a UDP datagram with the following
layout:
byte SSH_QUIC_CANCEL = 0x82
short-str server-connection-id
byte e = nr-ext-pairs (see Extensibility)
the following 2 fields repeated e times:
short-str ext-pair-name (MUST NOT be empty)
string ext-pair-data (MAY be empty)
Figure 6
bider Expires 8 January 2021 [Page 14]
Internet-Draft SSH/QUIC July 2020
The "server-connection-id" field MUST equal the "server-connection-
id" field in the server's SSH_QUIC_REPLY.
In the extension pair fields, a "disc-reason" Extension Pair MUST be
included. An "err-desc" Extension Pair MAY also be included. See
Section 2.6.
2.9.1. Extensibility
Extensibility considerations also apply to SSH_QUIC_CANCEL:
* Clients MAY include extensions which are unknown to or not
supported by the server, with extension data in a format that's
unknown to or not supported by the server.
* Servers MUST tolerate the presence of such extensions and their
data.
* Clients SHOULD include, in a random position, at least one
extension pair where the field "ext-pair-name" contains a Random
Name, and the field "ext-pair-value" contains 0..300 Random Bytes.
3. Key Exchange Methods
Clients and servers MAY use any key exchange method which is defined
for SSH over TCP, whether it is assigned or private, as long as it
meets all of the following criteria:
1. The algorithm requires exactly one message from the client to the
server, for example SSH_MSG_KEX_ECDH_INIT. We call this message
KEXMSG_CLIENT.
2. The algorithm requires exactly one reply from the server to the
client, for example SSH_MSG_KEX_ECDH_REPLY. We call this message
KEXMSG_SERVER.
3. The algorithm specifies a hash function HASH, for example SHA-
256, SHA-384, or SHA-512.
4. The algorithm specifies calculation of an exchange hash H by
applying HASH to a concatenation of encoded fields.
5. The algorithm uses a server host key to sign H.
6. The algorithm includes the server's public host key, and the
signature of H, in its KEXMSG_SERVER message to the client.
bider Expires 8 January 2021 [Page 15]
Internet-Draft SSH/QUIC July 2020
7. The algorithm produces a shared secret K, represented as a signed
multi-precision integer.
Any such algorithm is modified for use in SSH over QUIC as follows:
1. The field "client-kex-alg-data" in SSH_QUIC_INIT encodes the same
fields, in the same order, as KEXMSG_CLIENT, except that the
leading byte for the SSH packet type is replaced with 0xFA.
2. The field "server-kex-alg-data" in SSH_QUIC_REPLY encodes the
same fields, in the same order, as KEXMSG_SERVER, except that the
leading byte for the SSH packet type is replaced with 0xFB.
3. The calculation of H specified by the algorithm is not performed.
Instead, H is calculated by applying the hash function HASH to a
concatenation of the following:
string Content of SSH_QUIC_INIT
string Content of SSH_QUIC_REPLY, excluding "server-kex-alg-data"
The fields of "server-kex-alg-data", excluding signature
mpint K
Figure 7
When a field is excluded as above, the entire encoding of the field
is omitted: both the encoding of the content and the encoding of the
length.
When SSH packet type bytes are replaced with 0xFA and 0xFB instead of
being removed, this is to ensure that at least two fields remain in
the encoded content. If this were not the case, there would be
situations where an outer string (the field "client-kex-alg-data")
contains a single inner string (from KEXMSG_CLIENT). This is prone
to confusion by implementers who could then incorrectly encode a
single string only.
3.1. Required Key Exchange Methods
Clients and servers are REQUIRED to implement the key exchange method
"curve25519-sha256" [RFC8731]. All other key exchange methods are
optional.
Clients and servers MAY permit the user to disable a required key
exchange method. However, required methods MUST be enabled by
default.
bider Expires 8 January 2021 [Page 16]
Internet-Draft SSH/QUIC July 2020
3.2. Example: "curve25519-sha256"
As an example, when using the SSH key exchange method
"curve25519-sha256", the SSH_QUIC_INIT field "client-kex-alg-data" is
derived from SSH_MSG_KEX_ECDH_INIT ([RFC5656], Section 4) and
contains the following:
byte 0xFA
string Q_C, client's ephemeral public key octet string
Figure 8
The SSH_QUIC_REPLY field "server-kex-alg-data" is derived from
SSH_MSG_KEX_ECDH_REPLY and contains the following:
byte 0xFB
string K_S, server's public host key
string Q_S, server's ephemeral public key octet string
string the signature on the exchange hash
Figure 9
The shared secret K is calculated as in [RFC8731]. Then the exchange
hash H is calculated by applying SHA-256 to a concatenation of the
following:
string Content of SSH_QUIC_INIT
string Content of SSH_QUIC_REPLY, except "server-kex-alg-data"
byte 0xFB
string K_S, server's public host key
string Q_S, server's ephemeral public key octet string
mpint K
Figure 10
This allows the server to generate the signature and include it in
the "server-kex-alg-data" field sent to the client.
4. SSH_MSG_EXT_INFO and the SSH Version String
A common user complaint to SSH application authors is that SSH over
TCP sends the application version in plain text. The application
version cannot be omitted, otherwise implementations cannot support a
number of behaviors which other software versions implement
incorrectly.
bider Expires 8 January 2021 [Page 17]
Internet-Draft SSH/QUIC July 2020
A prominent example is the order of arguments in the SFTP request
SSH_FXP_SYMLINK. To send a request that will have the expected
effect, the client MUST consult the server's version string to know
whether the server uses the standard order of fields, or a reverse
order used by OpenSSH.
SSH over QUIC removes the version string from the SSH key exchange.
Instead, all clients and servers are REQUIRED to send and accept
SSH_MSG_EXT_INFO [RFC8308], and to include the "ssh-version"
extension (below).
Clients MUST send SSH_MSG_EXT_INFO as the very first SSH packet over
QUIC. The client MUST include the "ssh-version" extension in this
SSH_MSG_EXT_INFO.
Servers MUST send SSH_MSG_EXT_INFO either:
1. as the very first SSH packet over QUIC, and/or
2. immediately preceding the server's SSH_MSG_USERAUTH_SUCCESS.
A server MUST include the "ssh-version" extension in at least one of
its SSH_MSG_EXT_INFO. If the server sends SSH_MSG_EXT_INFO at both
opportunities, it MAY omit "ssh-version" at the first opportunity,
but only if it will send it in the second opportunity. The second
SSH_MSG_EXT_INFO sent by the server MAY change a previously sent
"ssh-version" extension value to include more specific detail. For
example, the server MAY include a more accurate server version. The
client MUST use the "ssh-version" value which was most recently
received from the server.
4.1. "ssh-version" Extension
The "ssh-version" extension is encoded in SSH_MSG_EXT_INFO as
follows:
string "ssh-version"
string ssh-version-string
Figure 11
The extension value, "ssh-version-string", contains the same SSH
version string as sent at the start of SSH over TCP ([RFC4253],
Section 4.2). Examples:
SSH-2.0-Product_1.2
SSH-2.0-0.12 Library: Application 1.23.00
bider Expires 8 January 2021 [Page 18]
Internet-Draft SSH/QUIC July 2020
Figure 12
5. QUIC Session Setup
When the server has sent its SSH_QUIC_REPLY, and when the client has
received it, they each initialize the QUIC session [QUIC] [QUIC-TLS]
as follows:
* The QUIC protocol version is set to the first version advertised
in the client's SSH_QUIC_INIT which is also present in the
server's SSH_QUIC_REPLY.
* Session state is set as if a TLS handshake had just completed.
* The TLS cipher suite is set to the first TLS cipher suite
advertised in SSH_QUIC_INIT which is also present in
SSH_QUIC_REPLY.
* The QUIC Key Phase bit is set to 0.
* The shared secrets that would have been obtained from the TLS
handshake are instead generated from the SSH key exchange
(Section 5.1).
Clients and servers MUST immediately begin to use QUIC Short Header
Packets. Implementations MUST NOT send QUIC Long Header Packets,
since they could be confused with the SSH/QUIC key exchange.
5.1. Shared Secrets
QUIC-TLS [QUIC-TLS] uses a client secret and a server secret from
which it generates an AEAD key, an IV, and a header protection key
for each sending direction.
An SSH key exchange produces a shared secret K, represented as an SSH
multi-precision integer, and an exchange digest H, represented as
binary data [RFC4253]. An SSH key exchange is parameterized with a
hash function we call HASH. Note that HASH can be a different hash
function, producing a different hash length, than the hash function
used by the negotiated TLS cipher suite.
To compute the initial QUIC client and server secrets, the client and
server encode the following binary data, which we call "secret_data":
mpint K
string H
Figure 13
bider Expires 8 January 2021 [Page 19]
Internet-Draft SSH/QUIC July 2020
The client and server secrets are then calculated as follows:
client_secret = HMAC-HASH("ssh/quic client", secret_data)
server_secret = HMAC-HASH("ssh/quic server", secret_data)
Figure 14
The HMAC construct is as specified in [RFC2104], instantiated using
the SSH key exchange hash function, HASH.
QUIC keys and IVs are derived from these secrets using the regular
QUIC-TLS key derivation process [QUIC-TLS]. Keys generated from
these secrets are considered 1-RTT keys.
Clients and servers MUST implement QUIC key updates using the regular
QUIC-TLS key update process [QUIC-TLS], respecting the QUIC-TLS
minimum key update frequencies.
6. SSH/QUIC Packet Format
All SSH/QUIC packets are sent on QUIC stream 0. No other QUIC
streams are used in SSH over QUIC.
Each side serializes its SSH packets for sending over QUIC as
follows:
uint32 n = payload-len
byte[n] payload
Figure 15
Since security is provided by QUIC-TLS [QUIC-TLS], MAC and random
padding are omitted at this stage.
In SSH/QUIC, compression algorithms negotiated in the initial SSH key
exchange are ignored. Such compression does NOT take effect.
Compression MAY be negotiated using the "delay-compression" extension
in [RFC8308]. If "delay-compression" is negotiated, and conditions
to enable compression are met, then the "payload" field is
compressed.
Otherwise, the "payload" field contains the same packet information
as the "payload" field in the Binary Packet Protocol defined in
[RFC4253].
bider Expires 8 January 2021 [Page 20]
Internet-Draft SSH/QUIC July 2020
7. IANA Considerations
This document requests no changes to IANA registries.
8. Security Considerations
Clients and servers MUST insert into SSH_QUIC_INIT and SSH_QUIC_REPLY
at least the minimum amount of cryptographically random data as
specified in the section Random Elements. Compromising on this
requirement reduces the security of any session created on the basis
of such an SSH_QUIC_INIT or SSH_QUIC_REPLY.
9. References
9.1. Normative References
[QUIC] Iyengar, J. and M. Thomson, "QUIC: A UDP-Based Multiplexed
and Secure Transport", 2020, .
[QUIC-TLS] Thomson, M. and S. Turner, "Using TLS to Secure QUIC",
2020,
.
[RFC2104] Krawczyk, H., Bellare, M., and R. Canetti, "HMAC: Keyed-
Hashing for Message Authentication", RFC 2104,
DOI 10.17487/RFC2104, February 1997,
.
[RFC2119] Bradner, S., "Key words for use in RFCs to Indicate
Requirement Levels", BCP 14, RFC 2119,
DOI 10.17487/RFC2119, March 1997,
.
[RFC4251] Ylonen, T. and C. Lonvick, Ed., "The Secure Shell (SSH)
Protocol Architecture", RFC 4251, DOI 10.17487/RFC4251,
January 2006, .
[RFC4253] Ylonen, T. and C. Lonvick, Ed., "The Secure Shell (SSH)
Transport Layer Protocol", RFC 4253, DOI 10.17487/RFC4253,
January 2006, .
[RFC5656] Stebila, D. and J. Green, "Elliptic Curve Algorithm
Integration in the Secure Shell Transport Layer",
RFC 5656, DOI 10.17487/RFC5656, December 2009,
.
bider Expires 8 January 2021 [Page 21]
Internet-Draft SSH/QUIC July 2020
[RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC
2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174,
May 2017, .
[RFC8308] Bider, D., "Extension Negotiation in the Secure Shell
(SSH) Protocol", RFC 8308, DOI 10.17487/RFC8308, March
2018, .
[RFC8446] Rescorla, E., "The Transport Layer Security (TLS) Protocol
Version 1.3", RFC 8446, DOI 10.17487/RFC8446, August 2018,
.
[RFC8731] Adamantiadis, A., Josefsson, S., and M. Baushke, "Secure
Shell (SSH) Key Exchange Method Using Curve25519 and
Curve448", RFC 8731, DOI 10.17487/RFC8731, February 2020,
.
9.2. Informative References
[IANA-SSH] IANA, "Secure Shell (SSH) Protocol Parameters",
.
[RFC4250] Lehtinen, S. and C. Lonvick, Ed., "The Secure Shell (SSH)
Protocol Assigned Numbers", RFC 4250,
DOI 10.17487/RFC4250, January 2006,
.
[RFC4252] Ylonen, T. and C. Lonvick, Ed., "The Secure Shell (SSH)
Authentication Protocol", RFC 4252, DOI 10.17487/RFC4252,
January 2006, .
[RFC4254] Ylonen, T. and C. Lonvick, Ed., "The Secure Shell (SSH)
Connection Protocol", RFC 4254, DOI 10.17487/RFC4254,
January 2006, .
Appendix A. Appendix: Generating Random Lengths
The SSH/QUIC extensibility mechanism calls for generating random
lengths such that values in the shorter end of the range are
significantly more probable, but long lengths are still selected.
The following C example shows a simple two-step process to prefer
shorter lengths:
bider Expires 8 January 2021 [Page 22]
Internet-Draft SSH/QUIC July 2020
int RandomIntBetweenZeroAnd(int maxValueInclusive);
int RandomLen_PreferShort(int minLen, int maxLen)
{
int const SPAN_THRESHOLD = 7;
int lenSpan = maxLen - minLen;
if (lenSpan <= 0)
return minLen;
if (lenSpan > SPAN_THRESHOLD)
if (0 != RandomIntBetweenZeroAnd(3))
return minLen + RandomIntBetweenZeroAnd(SPAN_THRESHOLD);
return minLen + RandomIntBetweenZeroAnd(lenSpan);
}
Figure 16
Author's Address
denis bider
Bitvise Limited
4105 Lombardy Ct
Colleyville, TX 76034
United States
Email: ietf-draft@denisbider.com
bider Expires 8 January 2021 [Page 23]