From fd1a3b5e38721b1d69aae2d9de1a1d9155dfa5c7 Mon Sep 17 00:00:00 2001 From: "markus@openbsd.org" Date: Tue, 12 Nov 2019 19:32:30 +0000 Subject: [PATCH] upstream: update sk-api to version 2 for ed25519 support; ok djm OpenBSD-Commit-ID: 77aa4d5b6ab17987d8a600907b49573940a0044a --- PROTOCOL.u2f | 10 +++++++--- sk-api.h | 12 ++++++++---- ssh-sk.c | 21 ++++++++++++++------- 3 files changed, 29 insertions(+), 14 deletions(-) diff --git a/PROTOCOL.u2f b/PROTOCOL.u2f index a587480be..bd60f9fac 100644 --- a/PROTOCOL.u2f +++ b/PROTOCOL.u2f @@ -138,7 +138,7 @@ The signature returned from U2F hardware takes the following format: For use in the SSH protocol, we wish to avoid server-side parsing of ASN.1 format data in the pre-authentication attack surface. Therefore, the signature format used on the wire in SSH2_USERAUTH_REQUEST packets will -be reformatted slightly: +be reformatted slightly and the ecdsa_signature_blob value has the encoding: mpint r mpint s @@ -184,6 +184,10 @@ The middleware library need only expose a handful of functions: /* Flags */ #define SSH_SK_USER_PRESENCE_REQD 0x01 + /* Algs */ + #define SSH_SK_ECDSA 0x00 + #define SSH_SK_ED25519 0x01 + struct sk_enroll_response { uint8_t *public_key; size_t public_key_len; @@ -208,12 +212,12 @@ The middleware library need only expose a handful of functions: uint32_t sk_api_version(void); /* Enroll a U2F key (private key generation) */ - int sk_enroll(const uint8_t *challenge, size_t challenge_len, + int sk_enroll(int alg, const uint8_t *challenge, size_t challenge_len, const char *application, uint8_t flags, struct sk_enroll_response **enroll_response); /* Sign a challenge */ - int sk_sign(const uint8_t *message, size_t message_len, + int sk_sign(int alg, const uint8_t *message, size_t message_len, const char *application, const uint8_t *key_handle, size_t key_handle_len, uint8_t flags, struct sk_sign_response **sign_response); diff --git a/sk-api.h b/sk-api.h index 2af0ef6f0..5ada30a3d 100644 --- a/sk-api.h +++ b/sk-api.h @@ -1,4 +1,4 @@ -/* $OpenBSD: sk-api.h,v 1.1 2019/10/31 21:16:20 djm Exp $ */ +/* $OpenBSD: sk-api.h,v 1.2 2019/11/12 19:32:30 markus Exp $ */ /* * Copyright (c) 2019 Google LLC * @@ -26,6 +26,10 @@ /* Flags */ #define SSH_SK_USER_PRESENCE_REQD 0x01 +/* Algs */ +#define SSH_SK_ECDSA 0x00 +#define SSH_SK_ED25519 0x01 + struct sk_enroll_response { uint8_t *public_key; size_t public_key_len; @@ -46,19 +50,19 @@ struct sk_sign_response { size_t sig_s_len; }; -#define SSH_SK_VERSION_MAJOR 0x00010000 /* current API version */ +#define SSH_SK_VERSION_MAJOR 0x00020000 /* current API version */ #define SSH_SK_VERSION_MAJOR_MASK 0xffff0000 /* Return the version of the middleware API */ uint32_t sk_api_version(void); /* Enroll a U2F key (private key generation) */ -int sk_enroll(const uint8_t *challenge, size_t challenge_len, +int sk_enroll(int alg, const uint8_t *challenge, size_t challenge_len, const char *application, uint8_t flags, struct sk_enroll_response **enroll_response); /* Sign a challenge */ -int sk_sign(const uint8_t *message, size_t message_len, +int sk_sign(int alg, const uint8_t *message, size_t message_len, const char *application, const uint8_t *key_handle, size_t key_handle_len, uint8_t flags, struct sk_sign_response **sign_response); diff --git a/ssh-sk.c b/ssh-sk.c index 43f808efc..a9da765eb 100644 --- a/ssh-sk.c +++ b/ssh-sk.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-sk.c,v 1.6 2019/11/12 19:31:45 markus Exp $ */ +/* $OpenBSD: ssh-sk.c,v 1.7 2019/11/12 19:32:30 markus Exp $ */ /* * Copyright (c) 2019 Google LLC * @@ -49,12 +49,12 @@ struct sshsk_provider { uint32_t (*sk_api_version)(void); /* Enroll a U2F key (private key generation) */ - int (*sk_enroll)(const uint8_t *challenge, size_t challenge_len, - const char *application, uint8_t flags, + int (*sk_enroll)(int alg, const uint8_t *challenge, + size_t challenge_len, const char *application, uint8_t flags, struct sk_enroll_response **enroll_response); /* Sign a challenge */ - int (*sk_sign)(const uint8_t *message, size_t message_len, + int (*sk_sign)(int alg, const uint8_t *message, size_t message_len, const char *application, const uint8_t *key_handle, size_t key_handle_len, uint8_t flags, struct sk_sign_response **sign_response); @@ -243,13 +243,17 @@ sshsk_enroll(int type, const char *provider_path, const char *application, size_t challenge_len; struct sk_enroll_response *resp = NULL; int r = SSH_ERR_INTERNAL_ERROR; + int alg; *keyp = NULL; if (attest) sshbuf_reset(attest); switch (type) { case KEY_ECDSA_SK: + alg = SSH_SK_ECDSA; + break; case KEY_ED25519_SK: + alg = SSH_SK_ED25519; break; default: error("%s: unsupported key type", __func__); @@ -287,7 +291,7 @@ sshsk_enroll(int type, const char *provider_path, const char *application, } /* XXX validate flags? */ /* enroll key */ - if ((r = skp->sk_enroll(challenge, challenge_len, application, + if ((r = skp->sk_enroll(alg, challenge, challenge_len, application, flags, &resp)) != 0) { error("Security key provider %s returned failure %d", provider_path, r); @@ -427,7 +431,7 @@ sshsk_sign(const char *provider_path, const struct sshkey *key, { struct sshsk_provider *skp = NULL; int r = SSH_ERR_INTERNAL_ERROR; - int type; + int type, alg; struct sk_sign_response *resp = NULL; struct sshbuf *inner_sig = NULL, *sig = NULL; uint8_t message[32]; @@ -439,7 +443,10 @@ sshsk_sign(const char *provider_path, const struct sshkey *key, type = sshkey_type_plain(key->type); switch (type) { case KEY_ECDSA_SK: + alg = SSH_SK_ECDSA; + break; case KEY_ED25519_SK: + alg = SSH_SK_ED25519; break; default: return SSH_ERR_INVALID_ARGUMENT; @@ -462,7 +469,7 @@ sshsk_sign(const char *provider_path, const struct sshkey *key, r = SSH_ERR_INTERNAL_ERROR; goto out; } - if ((r = skp->sk_sign(message, sizeof(message), + if ((r = skp->sk_sign(alg, message, sizeof(message), key->sk_application, sshbuf_ptr(key->sk_key_handle), sshbuf_len(key->sk_key_handle), key->sk_flags, &resp)) != 0) {