Disable security key for bigendian interop.
[openssh.git] / PROTOCOL.u2f
blobf8ca56b11c8cfc76adcedf813205e7d00171f913
1 This document describes OpenSSH's support for U2F/FIDO security keys.
3 Background
4 ----------
6 U2F is an open standard for two-factor authentication hardware, widely
7 used for user authentication to websites. U2F tokens are ubiquitous,
8 available from a number of manufacturers and are currently by far the
9 cheapest way for users to achieve hardware-backed credential storage.
11 The U2F protocol however cannot be trivially used as an SSH protocol key
12 type as both the inputs to the signature operation and the resultant
13 signature differ from those specified for SSH. For similar reasons,
14 integration of U2F devices cannot be achieved via the PKCS#11 API.
16 U2F also offers a number of features that are attractive in the context
17 of SSH authentication. They can be configured to require indication
18 of "user presence" for each signature operation (typically achieved
19 by requiring the user touch the key). They also offer an attestation
20 mechanism at key enrollment time that can be used to prove that a
21 given key is backed by hardware. Finally the signature format includes
22 a monotonic signature counter that can be used (at scale) to detect
23 concurrent use of a private key, should it be extracted from hardware.
25 U2F private keys are generated through an enrollment operation,
26 which takes an application ID - a URL-like string, typically "ssh:"
27 in this case, but a HTTP origin for the case of web authentication,
28 and a challenge string (typically randomly generated). The enrollment
29 operation returns a public key, a key handle that must be used to invoke
30 the hardware-backed private key, some flags and signed attestation
31 information that may be used to verify that a private key is hosted on a
32 particular hardware instance.
34 It is common for U2F hardware to derive private keys from the key handle
35 in conjunction with a small per-device secret that is unique to the
36 hardware, thus requiring little on-device storage for an effectively
37 unlimited number of supported keys. This drives the requirement that
38 the key handle be supplied for each signature operation. U2F tokens
39 primarily use ECDSA signatures in the NIST-P256 field, though the FIDO2
40 standard specifies additional key types, including one based on Ed25519.
42 Use of U2F security keys does not automatically imply multi-factor
43 authentication. From sshd's perspective, a security key constitutes a
44 single factor of authentication, even if protected by a PIN or biometric
45 authentication.  To enable multi-factor authentication in ssh, please
46 refer to the AuthenticationMethods option in sshd_config(5).
49 SSH U2F Key formats
50 -------------------
52 OpenSSH integrates U2F as new key and corresponding certificate types:
54         sk-ecdsa-sha2-nistp256@openssh.com
55         sk-ecdsa-sha2-nistp256-cert-v01@openssh.com
56         sk-ssh-ed25519@openssh.com
57         sk-ssh-ed25519-cert-v01@openssh.com
59 While each uses ecdsa-sha256-nistp256 as the underlying signature primitive,
60 keys require extra information in the public and private keys, and in
61 the signature object itself. As such they cannot be made compatible with
62 the existing ecdsa-sha2-nistp* key types.
64 The format of a sk-ecdsa-sha2-nistp256@openssh.com public key is:
66         string          "sk-ecdsa-sha2-nistp256@openssh.com"
67         string          curve name
68         ec_point        Q
69         string          application (user-specified, but typically "ssh:")
71 The corresponding private key contains:
73         string          "sk-ecdsa-sha2-nistp256@openssh.com"
74         string          curve name
75         ec_point        Q
76         string          application (user-specified, but typically "ssh:")
77         uint8           flags
78         string          key_handle
79         string          reserved
81 The format of a sk-ssh-ed25519@openssh.com public key is:
83         string          "sk-ssh-ed25519@openssh.com"
84         string          public key
85         string          application (user-specified, but typically "ssh:")
87 With a private half consisting of:
89         string          "sk-ssh-ed25519@openssh.com"
90         string          public key
91         string          application (user-specified, but typically "ssh:")
92         uint8           flags
93         string          key_handle
94         string          reserved
96 The certificate form for SSH U2F keys appends the usual certificate
97 information to the public key:
99         string          "sk-ecdsa-sha2-nistp256-cert-v01@openssh.com"
100         string          nonce
101         string          curve name
102         ec_point        Q
103         string          application
104         uint64          serial
105         uint32          type
106         string          key id
107         string          valid principals
108         uint64          valid after
109         uint64          valid before
110         string          critical options
111         string          extensions
112         string          reserved
113         string          signature key
114         string          signature
116 and for security key ed25519 certificates:
118         string          "sk-ssh-ed25519-cert-v01@openssh.com"
119         string          nonce
120         string          public key
121         string          application
122         uint64          serial
123         uint32          type
124         string          key id
125         string          valid principals
126         uint64          valid after
127         uint64          valid before
128         string          critical options
129         string          extensions
130         string          reserved
131         string          signature key
132         string          signature
134 Both security key certificates use the following encoding for private keys:
136         string          type (e.g. "sk-ssh-ed25519-cert-v01@openssh.com")
137         string          pubkey (the above key/cert structure)
138         string          application
139         uint8           flags
140         string          key_handle
141         string          reserved
143 During key generation, the hardware also returns attestation information
144 that may be used to cryptographically prove that a given key is
145 hardware-backed. Unfortunately, the protocol required for this proof is
146 not privacy-preserving and may be used to identify U2F tokens with at
147 least manufacturer and batch number granularity. For this reason, we
148 choose not to include this information in the public key or save it by
149 default.
151 Attestation information is useful for out-of-band key and certificate
152 registration workflows, e.g. proving to a CA that a key is backed
153 by trusted hardware before it will issue a certificate. To support this
154 case, OpenSSH optionally allows retaining the attestation information
155 at the time of key generation. It will take the following format:
157         string          "ssh-sk-attest-v01"
158         string          attestation certificate
159         string          enrollment signature
160         string          authenticator data (CBOR encoded)
161         uint32          reserved flags
162         string          reserved string
164 A previous version of this format, emitted prior to OpenSSH 8.4 omitted
165 the authenticator data.
167         string          "ssh-sk-attest-v00"
168         string          attestation certificate
169         string          enrollment signature
170         uint32          reserved flags
171         string          reserved string
173 OpenSSH treats the attestation certificate and enrollment signatures as
174 opaque objects and does no interpretation of them itself.
176 SSH U2F signatures
177 ------------------
179 In addition to the message to be signed, the U2F signature operation
180 requires the key handle and a few additional parameters. The signature
181 is signed over a blob that consists of:
183         byte[32]        SHA256(application)
184         byte            flags (including "user present", extensions present)
185         uint32          counter
186         byte[]          extensions
187         byte[32]        SHA256(message)
189 No extensions are yet defined for SSH use. If any are defined in the future,
190 it will be possible to infer their presence from the contents of the "flags"
191 value.
193 The signature returned from U2F hardware takes the following format:
195         byte            flags (including "user present")
196         uint32          counter
197         byte[]          ecdsa_signature (in X9.62 format).
199 For use in the SSH protocol, we wish to avoid server-side parsing of ASN.1
200 format data in the pre-authentication attack surface. Therefore, the
201 signature format used on the wire in SSH2_USERAUTH_REQUEST packets will
202 be reformatted to better match the existing signature encoding:
204         string          "sk-ecdsa-sha2-nistp256@openssh.com"
205         string          ecdsa_signature
206         byte            flags
207         uint32          counter
209 Where the "ecdsa_signature" field follows the RFC5656 ECDSA signature
210 encoding:
212         mpint           r
213         mpint           s
215 For Ed25519 keys the signature is encoded as:
217         string          "sk-ssh-ed25519@openssh.com"
218         string          signature
219         byte            flags
220         uint32          counter
222 webauthn signatures
223 -------------------
225 The W3C/FIDO webauthn[1] standard defines a mechanism for a web browser to
226 interact with FIDO authentication tokens. This standard builds upon the
227 FIDO standards, but requires different signature contents to raw FIDO
228 messages. OpenSSH supports ECDSA/p256 webauthn signatures through the
229 "webauthn-sk-ecdsa-sha2-nistp256@openssh.com" signature algorithm.
231 The wire encoding for a webauthn-sk-ecdsa-sha2-nistp256@openssh.com
232 signature is similar to the sk-ecdsa-sha2-nistp256@openssh.com format:
234         string          "webauthn-sk-ecdsa-sha2-nistp256@openssh.com"
235         string          ecdsa_signature
236         byte            flags
237         uint32          counter
238         string          origin
239         string          clientData
240         string          extensions
242 Where "origin" is the HTTP origin making the signature, "clientData" is
243 the JSON-like structure signed by the browser and "extensions" are any
244 extensions used in making the signature.
246 [1] https://www.w3.org/TR/webauthn-2/
248 ssh-agent protocol extensions
249 -----------------------------
251 ssh-agent requires a protocol extension to support U2F keys. At
252 present the closest analogue to Security Keys in ssh-agent are PKCS#11
253 tokens, insofar as they require a middleware library to communicate with
254 the device that holds the keys. Unfortunately, the protocol message used
255 to add PKCS#11 keys to ssh-agent does not include any way to send the
256 key handle to the agent as U2F keys require.
258 To avoid this, without having to add wholly new messages to the agent
259 protocol, we will use the existing SSH2_AGENTC_ADD_ID_CONSTRAINED message
260 with a new key constraint extension to encode a path to the middleware
261 library for the key. The format of this constraint extension would be:
263         byte            SSH_AGENT_CONSTRAIN_EXTENSION
264         string          sk-provider@openssh.com
265         string          middleware path
267 This constraint-based approach does not present any compatibility
268 problems.
270 OpenSSH integration
271 -------------------
273 U2F tokens may be attached via a number of means, including USB and NFC.
274 The USB interface is standardised around a HID protocol, but we want to
275 be able to support other transports as well as dummy implementations for
276 regress testing. For this reason, OpenSSH shall support a dynamically-
277 loaded middleware libraries to communicate with security keys, but offer
278 support for the common case of USB HID security keys internally.
280 The middleware library need only expose a handful of functions and
281 numbers listed in sk-api.h. Included in the defined numbers is a
282 SSH_SK_VERSION_MAJOR that should be incremented for each incompatible
283 API change.
285 miscellaneous options may be passed to the middleware as a NULL-
286 terminated array of pointers to struct sk_option. The middleware may
287 ignore unsupported or unknown options unless the "required" flag is set,
288 in which case it should return failure if an unsupported option is
289 requested.
291 At present the following options names are supported:
293         "device"
295         Specifies a specific FIDO device on which to perform the
296         operation. The value in this field is interpreted by the
297         middleware but it would be typical to specify a path to
298         a /dev node for the device in question.
300         "user"
302         Specifies the FIDO2 username used when enrolling a key,
303         overriding OpenSSH's default of using an all-zero username.
305 In OpenSSH, the middleware will be invoked by using a similar mechanism to
306 ssh-pkcs11-helper to provide address-space containment of the
307 middleware from ssh-agent.
309 $OpenBSD: PROTOCOL.u2f,v 1.26 2020/09/09 03:08:01 djm Exp $