118504831SchristosThis document describes OpenSSH's support for U2F/FIDO security keys. 218504831Schristos 318504831SchristosBackground 418504831Schristos---------- 518504831Schristos 618504831SchristosU2F is an open standard for two-factor authentication hardware, widely 718504831Schristosused for user authentication to websites. U2F tokens are ubiquitous, 818504831Schristosavailable from a number of manufacturers and are currently by far the 918504831Schristoscheapest way for users to achieve hardware-backed credential storage. 1018504831Schristos 1118504831SchristosThe U2F protocol however cannot be trivially used as an SSH protocol key 1218504831Schristostype as both the inputs to the signature operation and the resultant 1318504831Schristossignature differ from those specified for SSH. For similar reasons, 1418504831Schristosintegration of U2F devices cannot be achieved via the PKCS#11 API. 1518504831Schristos 1618504831SchristosU2F also offers a number of features that are attractive in the context 1718504831Schristosof SSH authentication. They can be configured to require indication 1818504831Schristosof "user presence" for each signature operation (typically achieved 1918504831Schristosby requiring the user touch the key). They also offer an attestation 2018504831Schristosmechanism at key enrollment time that can be used to prove that a 2118504831Schristosgiven key is backed by hardware. Finally the signature format includes 2218504831Schristosa monotonic signature counter that can be used (at scale) to detect 2318504831Schristosconcurrent use of a private key, should it be extracted from hardware. 2418504831Schristos 2518504831SchristosU2F private keys are generated through an enrollment operation, 2618504831Schristoswhich takes an application ID - a URL-like string, typically "ssh:" 2718504831Schristosin this case, but a HTTP origin for the case of web authentication, 2818504831Schristosand a challenge string (typically randomly generated). The enrollment 2918504831Schristosoperation returns a public key, a key handle that must be used to invoke 3018504831Schristosthe hardware-backed private key, some flags and signed attestation 3118504831Schristosinformation that may be used to verify that a private key is hosted on a 3218504831Schristosparticular hardware instance. 3318504831Schristos 3418504831SchristosIt is common for U2F hardware to derive private keys from the key handle 3518504831Schristosin conjunction with a small per-device secret that is unique to the 3618504831Schristoshardware, thus requiring little on-device storage for an effectively 3718504831Schristosunlimited number of supported keys. This drives the requirement that 3818504831Schristosthe key handle be supplied for each signature operation. U2F tokens 3918504831Schristosprimarily use ECDSA signatures in the NIST-P256 field, though the FIDO2 4018504831Schristosstandard specifies additional key types, including one based on Ed25519. 4118504831Schristos 42*e86f7815SchristosUse of U2F security keys does not automatically imply multi-factor 43*e86f7815Schristosauthentication. From sshd's perspective, a security key constitutes a 44*e86f7815Schristossingle factor of authentication, even if protected by a PIN or biometric 45*e86f7815Schristosauthentication. To enable multi-factor authentication in ssh, please 46*e86f7815Schristosrefer to the AuthenticationMethods option in sshd_config(5). 47*e86f7815Schristos 48*e86f7815Schristos 4918504831SchristosSSH U2F Key formats 5018504831Schristos------------------- 5118504831Schristos 5218504831SchristosOpenSSH integrates U2F as new key and corresponding certificate types: 5318504831Schristos 5418504831Schristos sk-ecdsa-sha2-nistp256@openssh.com 5518504831Schristos sk-ecdsa-sha2-nistp256-cert-v01@openssh.com 5618504831Schristos sk-ssh-ed25519@openssh.com 5718504831Schristos sk-ssh-ed25519-cert-v01@openssh.com 5818504831Schristos 5918504831SchristosWhile each uses ecdsa-sha256-nistp256 as the underlying signature primitive, 6018504831Schristoskeys require extra information in the public and private keys, and in 6118504831Schristosthe signature object itself. As such they cannot be made compatible with 6218504831Schristosthe existing ecdsa-sha2-nistp* key types. 6318504831Schristos 6418504831SchristosThe format of a sk-ecdsa-sha2-nistp256@openssh.com public key is: 6518504831Schristos 6618504831Schristos string "sk-ecdsa-sha2-nistp256@openssh.com" 6718504831Schristos string curve name 6818504831Schristos ec_point Q 6918504831Schristos string application (user-specified, but typically "ssh:") 7018504831Schristos 7118504831SchristosThe corresponding private key contains: 7218504831Schristos 7318504831Schristos string "sk-ecdsa-sha2-nistp256@openssh.com" 7418504831Schristos string curve name 7518504831Schristos ec_point Q 7618504831Schristos string application (user-specified, but typically "ssh:") 7718504831Schristos uint8 flags 7818504831Schristos string key_handle 7918504831Schristos string reserved 8018504831Schristos 8118504831SchristosThe format of a sk-ssh-ed25519@openssh.com public key is: 8218504831Schristos 8318504831Schristos string "sk-ssh-ed25519@openssh.com" 8418504831Schristos string public key 8518504831Schristos string application (user-specified, but typically "ssh:") 8618504831Schristos 8718504831SchristosWith a private half consisting of: 8818504831Schristos 8918504831Schristos string "sk-ssh-ed25519@openssh.com" 9018504831Schristos string public key 9118504831Schristos string application (user-specified, but typically "ssh:") 9218504831Schristos uint8 flags 9318504831Schristos string key_handle 9418504831Schristos string reserved 9518504831Schristos 9618504831SchristosThe certificate form for SSH U2F keys appends the usual certificate 9718504831Schristosinformation to the public key: 9818504831Schristos 9918504831Schristos string "sk-ecdsa-sha2-nistp256-cert-v01@openssh.com" 10018504831Schristos string nonce 10118504831Schristos string curve name 10218504831Schristos ec_point Q 10318504831Schristos string application 10418504831Schristos uint64 serial 10518504831Schristos uint32 type 10618504831Schristos string key id 10718504831Schristos string valid principals 10818504831Schristos uint64 valid after 10918504831Schristos uint64 valid before 11018504831Schristos string critical options 11118504831Schristos string extensions 11218504831Schristos string reserved 11318504831Schristos string signature key 11418504831Schristos string signature 11518504831Schristos 11618504831Schristosand for security key ed25519 certificates: 11718504831Schristos 11818504831Schristos string "sk-ssh-ed25519-cert-v01@openssh.com" 11918504831Schristos string nonce 12018504831Schristos string public key 12118504831Schristos string application 12218504831Schristos uint64 serial 12318504831Schristos uint32 type 12418504831Schristos string key id 12518504831Schristos string valid principals 12618504831Schristos uint64 valid after 12718504831Schristos uint64 valid before 12818504831Schristos string critical options 12918504831Schristos string extensions 13018504831Schristos string reserved 13118504831Schristos string signature key 13218504831Schristos string signature 13318504831Schristos 13418504831SchristosBoth security key certificates use the following encoding for private keys: 13518504831Schristos 13618504831Schristos string type (e.g. "sk-ssh-ed25519-cert-v01@openssh.com") 13718504831Schristos string pubkey (the above key/cert structure) 13818504831Schristos string application 13918504831Schristos uint8 flags 14018504831Schristos string key_handle 14118504831Schristos string reserved 14218504831Schristos 14318504831SchristosDuring key generation, the hardware also returns attestation information 14418504831Schristosthat may be used to cryptographically prove that a given key is 14518504831Schristoshardware-backed. Unfortunately, the protocol required for this proof is 14618504831Schristosnot privacy-preserving and may be used to identify U2F tokens with at 14718504831Schristosleast manufacturer and batch number granularity. For this reason, we 14818504831Schristoschoose not to include this information in the public key or save it by 14918504831Schristosdefault. 15018504831Schristos 15118504831SchristosAttestation information is useful for out-of-band key and certificate 152c7b0de47Schristosregistration workflows, e.g. proving to a CA that a key is backed 15318504831Schristosby trusted hardware before it will issue a certificate. To support this 15418504831Schristoscase, OpenSSH optionally allows retaining the attestation information 15518504831Schristosat the time of key generation. It will take the following format: 15618504831Schristos 157*e86f7815Schristos string "ssh-sk-attest-v01" 158*e86f7815Schristos string attestation certificate 159*e86f7815Schristos string enrollment signature 160*e86f7815Schristos string authenticator data (CBOR encoded) 161*e86f7815Schristos uint32 reserved flags 162*e86f7815Schristos string reserved string 163*e86f7815Schristos 164*e86f7815SchristosA previous version of this format, emitted prior to OpenSSH 8.4 omitted 165*e86f7815Schristosthe authenticator data. 166*e86f7815Schristos 16718504831Schristos string "ssh-sk-attest-v00" 16818504831Schristos string attestation certificate 16918504831Schristos string enrollment signature 17018504831Schristos uint32 reserved flags 17118504831Schristos string reserved string 17218504831Schristos 17318504831SchristosOpenSSH treats the attestation certificate and enrollment signatures as 17418504831Schristosopaque objects and does no interpretation of them itself. 17518504831Schristos 17618504831SchristosSSH U2F signatures 17718504831Schristos------------------ 17818504831Schristos 17918504831SchristosIn addition to the message to be signed, the U2F signature operation 18018504831Schristosrequires the key handle and a few additional parameters. The signature 18118504831Schristosis signed over a blob that consists of: 18218504831Schristos 18318504831Schristos byte[32] SHA256(application) 18418504831Schristos byte flags (including "user present", extensions present) 18518504831Schristos uint32 counter 18618504831Schristos byte[] extensions 18718504831Schristos byte[32] SHA256(message) 18818504831Schristos 189c7b0de47SchristosNo extensions are yet defined for SSH use. If any are defined in the future, 19018504831Schristosit will be possible to infer their presence from the contents of the "flags" 19118504831Schristosvalue. 19218504831Schristos 19318504831SchristosThe signature returned from U2F hardware takes the following format: 19418504831Schristos 19518504831Schristos byte flags (including "user present") 19618504831Schristos uint32 counter 19718504831Schristos byte[] ecdsa_signature (in X9.62 format). 19818504831Schristos 19918504831SchristosFor use in the SSH protocol, we wish to avoid server-side parsing of ASN.1 20018504831Schristosformat data in the pre-authentication attack surface. Therefore, the 20118504831Schristossignature format used on the wire in SSH2_USERAUTH_REQUEST packets will 20218504831Schristosbe reformatted to better match the existing signature encoding: 20318504831Schristos 20418504831Schristos string "sk-ecdsa-sha2-nistp256@openssh.com" 20518504831Schristos string ecdsa_signature 20618504831Schristos byte flags 20718504831Schristos uint32 counter 20818504831Schristos 20918504831SchristosWhere the "ecdsa_signature" field follows the RFC5656 ECDSA signature 21018504831Schristosencoding: 21118504831Schristos 21218504831Schristos mpint r 21318504831Schristos mpint s 21418504831Schristos 21518504831SchristosFor Ed25519 keys the signature is encoded as: 21618504831Schristos 21718504831Schristos string "sk-ssh-ed25519@openssh.com" 21818504831Schristos string signature 21918504831Schristos byte flags 22018504831Schristos uint32 counter 22118504831Schristos 222*e86f7815Schristoswebauthn signatures 223*e86f7815Schristos------------------- 224*e86f7815Schristos 225*e86f7815SchristosThe W3C/FIDO webauthn[1] standard defines a mechanism for a web browser to 226*e86f7815Schristosinteract with FIDO authentication tokens. This standard builds upon the 227*e86f7815SchristosFIDO standards, but requires different signature contents to raw FIDO 228*e86f7815Schristosmessages. OpenSSH supports ECDSA/p256 webauthn signatures through the 229*e86f7815Schristos"webauthn-sk-ecdsa-sha2-nistp256@openssh.com" signature algorithm. 230*e86f7815Schristos 231*e86f7815SchristosThe wire encoding for a webauthn-sk-ecdsa-sha2-nistp256@openssh.com 232*e86f7815Schristossignature is similar to the sk-ecdsa-sha2-nistp256@openssh.com format: 233*e86f7815Schristos 234*e86f7815Schristos string "webauthn-sk-ecdsa-sha2-nistp256@openssh.com" 235*e86f7815Schristos string ecdsa_signature 236*e86f7815Schristos byte flags 237*e86f7815Schristos uint32 counter 238*e86f7815Schristos string origin 239*e86f7815Schristos string clientData 240*e86f7815Schristos string extensions 241*e86f7815Schristos 242*e86f7815SchristosWhere "origin" is the HTTP origin making the signature, "clientData" is 243*e86f7815Schristosthe JSON-like structure signed by the browser and "extensions" are any 244*e86f7815Schristosextensions used in making the signature. 245*e86f7815Schristos 246*e86f7815Schristos[1] https://www.w3.org/TR/webauthn-2/ 247*e86f7815Schristos 24818504831Schristosssh-agent protocol extensions 24918504831Schristos----------------------------- 25018504831Schristos 25118504831Schristosssh-agent requires a protocol extension to support U2F keys. At 25218504831Schristospresent the closest analogue to Security Keys in ssh-agent are PKCS#11 25318504831Schristostokens, insofar as they require a middleware library to communicate with 25418504831Schristosthe device that holds the keys. Unfortunately, the protocol message used 25518504831Schristosto add PKCS#11 keys to ssh-agent does not include any way to send the 25618504831Schristoskey handle to the agent as U2F keys require. 25718504831Schristos 25818504831SchristosTo avoid this, without having to add wholly new messages to the agent 25918504831Schristosprotocol, we will use the existing SSH2_AGENTC_ADD_ID_CONSTRAINED message 26018504831Schristoswith a new key constraint extension to encode a path to the middleware 26118504831Schristoslibrary for the key. The format of this constraint extension would be: 26218504831Schristos 26318504831Schristos byte SSH_AGENT_CONSTRAIN_EXTENSION 26418504831Schristos string sk-provider@openssh.com 26518504831Schristos string middleware path 26618504831Schristos 26718504831SchristosThis constraint-based approach does not present any compatibility 26818504831Schristosproblems. 26918504831Schristos 27018504831SchristosOpenSSH integration 27118504831Schristos------------------- 27218504831Schristos 27318504831SchristosU2F tokens may be attached via a number of means, including USB and NFC. 27418504831SchristosThe USB interface is standardised around a HID protocol, but we want to 27518504831Schristosbe able to support other transports as well as dummy implementations for 27618504831Schristosregress testing. For this reason, OpenSSH shall support a dynamically- 27718504831Schristosloaded middleware libraries to communicate with security keys, but offer 27818504831Schristossupport for the common case of USB HID security keys internally. 27918504831Schristos 280*e86f7815SchristosThe middleware library need only expose a handful of functions and 281*e86f7815Schristosnumbers listed in sk-api.h. Included in the defined numbers is a 282*e86f7815SchristosSSH_SK_VERSION_MAJOR that should be incremented for each incompatible 28318504831SchristosAPI change. 28418504831Schristos 285*e86f7815Schristosmiscellaneous options may be passed to the middleware as a NULL- 286*e86f7815Schristosterminated array of pointers to struct sk_option. The middleware may 287*e86f7815Schristosignore unsupported or unknown options unless the "required" flag is set, 288*e86f7815Schristosin which case it should return failure if an unsupported option is 28918504831Schristosrequested. 29018504831Schristos 29118504831SchristosAt present the following options names are supported: 29218504831Schristos 29318504831Schristos "device" 29418504831Schristos 29518504831Schristos Specifies a specific FIDO device on which to perform the 29618504831Schristos operation. The value in this field is interpreted by the 29718504831Schristos middleware but it would be typical to specify a path to 29818504831Schristos a /dev node for the device in question. 29918504831Schristos 30018504831Schristos "user" 30118504831Schristos 30218504831Schristos Specifies the FIDO2 username used when enrolling a key, 30318504831Schristos overriding OpenSSH's default of using an all-zero username. 30418504831Schristos 30518504831SchristosIn OpenSSH, the middleware will be invoked by using a similar mechanism to 30618504831Schristosssh-pkcs11-helper to provide address-space containment of the 30718504831Schristosmiddleware from ssh-agent. 30818504831Schristos 309*e86f7815Schristos$OpenBSD: PROTOCOL.u2f,v 1.26 2020/09/09 03:08:01 djm Exp $ 310