Module Name:    src
Committed By:   christos
Date:           Fri Aug 11 23:02:08 UTC 2023

Modified Files:
        src/external/bsd/libfido2/dist/src: assert.c cred.c hid_netbsd.c
        src/external/bsd/libfido2/dist/tools: util.c
        src/external/bsd/libfido2/lib: Makefile
Removed Files:
        src/external/bsd/libfido2/dist/openbsd-compat: hkdf.c hkdf.h

Log Message:
Merge conflicts between libfido2-1.8.0 and libfido2-1.13.0


To generate a diff of this commit:
cvs rdiff -u -r1.1.1.1 -r0 \
    src/external/bsd/libfido2/dist/openbsd-compat/hkdf.c \
    src/external/bsd/libfido2/dist/openbsd-compat/hkdf.h
cvs rdiff -u -r1.2 -r1.3 src/external/bsd/libfido2/dist/src/assert.c \
    src/external/bsd/libfido2/dist/src/cred.c
cvs rdiff -u -r1.3 -r1.4 src/external/bsd/libfido2/dist/src/hid_netbsd.c
cvs rdiff -u -r1.3 -r1.4 src/external/bsd/libfido2/dist/tools/util.c
cvs rdiff -u -r1.10 -r1.11 src/external/bsd/libfido2/lib/Makefile

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/external/bsd/libfido2/dist/src/assert.c
diff -u src/external/bsd/libfido2/dist/src/assert.c:1.2 src/external/bsd/libfido2/dist/src/assert.c:1.3
--- src/external/bsd/libfido2/dist/src/assert.c:1.2	Mon May  8 19:45:52 2023
+++ src/external/bsd/libfido2/dist/src/assert.c	Fri Aug 11 19:02:08 2023
@@ -1,10 +1,10 @@
 /*
- * Copyright (c) 2018-2021 Yubico AB. All rights reserved.
+ * Copyright (c) 2018-2022 Yubico AB. All rights reserved.
  * Use of this source code is governed by a BSD-style
  * license that can be found in the LICENSE file.
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
-#include <openssl/ecdsa.h>
 #include <openssl/sha.h>
 
 #include "fido.h"
@@ -79,7 +79,7 @@ parse_assert_reply(const cbor_item_t *ke
 
 static int
 fido_dev_get_assert_tx(fido_dev_t *dev, fido_assert_t *assert,
-    const es256_pk_t *pk, const fido_blob_t *ecdh, const char *pin)
+    const es256_pk_t *pk, const fido_blob_t *ecdh, const char *pin, int *ms)
 {
 	fido_blob_t	 f;
 	fido_opt_t	 uv = assert->uv;
@@ -127,7 +127,7 @@ fido_dev_get_assert_tx(fido_dev_t *dev, 
 	if (pin != NULL || (uv == FIDO_OPT_TRUE &&
 	    fido_dev_supports_permissions(dev))) {
 		if ((r = cbor_add_uv_params(dev, cmd, &assert->cdh, pk, ecdh,
-		    pin, assert->rp_id, &argv[5], &argv[6])) != FIDO_OK) {
+		    pin, assert->rp_id, &argv[5], &argv[6], ms)) != FIDO_OK) {
 			fido_log_debug("%s: cbor_add_uv_params", __func__);
 			goto fail;
 		}
@@ -144,7 +144,7 @@ fido_dev_get_assert_tx(fido_dev_t *dev, 
 
 	/* frame and transmit */
 	if (cbor_build_frame(cmd, argv, nitems(argv), &f) < 0 ||
-	    fido_tx(dev, CTAP_CMD_CBOR, f.ptr, f.len) < 0) {
+	    fido_tx(dev, CTAP_CMD_CBOR, f.ptr, f.len, ms) < 0) {
 		fido_log_debug("%s: fido_tx", __func__);
 		r = FIDO_ERR_TX;
 		goto fail;
@@ -159,52 +159,61 @@ fail:
 }
 
 static int
-fido_dev_get_assert_rx(fido_dev_t *dev, fido_assert_t *assert, int ms)
+fido_dev_get_assert_rx(fido_dev_t *dev, fido_assert_t *assert, int *ms)
 {
-	unsigned char	reply[FIDO_MAXMSG];
-	int		reply_len;
-	int		r;
+	unsigned char	*msg;
+	int		 msglen;
+	int		 r;
 
 	fido_assert_reset_rx(assert);
 
-	if ((reply_len = fido_rx(dev, CTAP_CMD_CBOR, &reply, sizeof(reply),
-	    ms)) < 0) {
+	if ((msg = malloc(FIDO_MAXMSG)) == NULL) {
+		r = FIDO_ERR_INTERNAL;
+		goto out;
+	}
+
+	if ((msglen = fido_rx(dev, CTAP_CMD_CBOR, msg, FIDO_MAXMSG, ms)) < 0) {
 		fido_log_debug("%s: fido_rx", __func__);
-		return (FIDO_ERR_RX);
+		r = FIDO_ERR_RX;
+		goto out;
 	}
 
 	/* start with room for a single assertion */
-	if ((assert->stmt = calloc(1, sizeof(fido_assert_stmt))) == NULL)
-		return (FIDO_ERR_INTERNAL);
-
+	if ((assert->stmt = calloc(1, sizeof(fido_assert_stmt))) == NULL) {
+		r = FIDO_ERR_INTERNAL;
+		goto out;
+	}
 	assert->stmt_len = 0;
 	assert->stmt_cnt = 1;
 
 	/* adjust as needed */
-	if ((r = cbor_parse_reply(reply, (size_t)reply_len, assert,
+	if ((r = cbor_parse_reply(msg, (size_t)msglen, assert,
 	    adjust_assert_count)) != FIDO_OK) {
 		fido_log_debug("%s: adjust_assert_count", __func__);
-		return (r);
+		goto out;
 	}
 
 	/* parse the first assertion */
-	if ((r = cbor_parse_reply(reply, (size_t)reply_len,
-	    &assert->stmt[assert->stmt_len], parse_assert_reply)) != FIDO_OK) {
+	if ((r = cbor_parse_reply(msg, (size_t)msglen, &assert->stmt[0],
+	    parse_assert_reply)) != FIDO_OK) {
 		fido_log_debug("%s: parse_assert_reply", __func__);
-		return (r);
+		goto out;
 	}
+	assert->stmt_len = 1;
 
-	assert->stmt_len++;
+	r = FIDO_OK;
+out:
+	freezero(msg, FIDO_MAXMSG);
 
-	return (FIDO_OK);
+	return (r);
 }
 
 static int
-fido_get_next_assert_tx(fido_dev_t *dev)
+fido_get_next_assert_tx(fido_dev_t *dev, int *ms)
 {
 	const unsigned char cbor[] = { CTAP_CBOR_NEXT_ASSERT };
 
-	if (fido_tx(dev, CTAP_CMD_CBOR, cbor, sizeof(cbor)) < 0) {
+	if (fido_tx(dev, CTAP_CMD_CBOR, cbor, sizeof(cbor), ms) < 0) {
 		fido_log_debug("%s: fido_tx", __func__);
 		return (FIDO_ERR_TX);
 	}
@@ -213,46 +222,57 @@ fido_get_next_assert_tx(fido_dev_t *dev)
 }
 
 static int
-fido_get_next_assert_rx(fido_dev_t *dev, fido_assert_t *assert, int ms)
+fido_get_next_assert_rx(fido_dev_t *dev, fido_assert_t *assert, int *ms)
 {
-	unsigned char	reply[FIDO_MAXMSG];
-	int		reply_len;
-	int		r;
+	unsigned char	*msg;
+	int		 msglen;
+	int		 r;
+
+	if ((msg = malloc(FIDO_MAXMSG)) == NULL) {
+		r = FIDO_ERR_INTERNAL;
+		goto out;
+	}
 
-	if ((reply_len = fido_rx(dev, CTAP_CMD_CBOR, &reply, sizeof(reply),
-	    ms)) < 0) {
+	if ((msglen = fido_rx(dev, CTAP_CMD_CBOR, msg, FIDO_MAXMSG, ms)) < 0) {
 		fido_log_debug("%s: fido_rx", __func__);
-		return (FIDO_ERR_RX);
+		r = FIDO_ERR_RX;
+		goto out;
 	}
 
 	/* sanity check */
 	if (assert->stmt_len >= assert->stmt_cnt) {
 		fido_log_debug("%s: stmt_len=%zu, stmt_cnt=%zu", __func__,
 		    assert->stmt_len, assert->stmt_cnt);
-		return (FIDO_ERR_INTERNAL);
+		r = FIDO_ERR_INTERNAL;
+		goto out;
 	}
 
-	if ((r = cbor_parse_reply(reply, (size_t)reply_len,
+	if ((r = cbor_parse_reply(msg, (size_t)msglen,
 	    &assert->stmt[assert->stmt_len], parse_assert_reply)) != FIDO_OK) {
 		fido_log_debug("%s: parse_assert_reply", __func__);
-		return (r);
+		goto out;
 	}
 
-	return (FIDO_OK);
+	r = FIDO_OK;
+out:
+	freezero(msg, FIDO_MAXMSG);
+
+	return (r);
 }
 
 static int
 fido_dev_get_assert_wait(fido_dev_t *dev, fido_assert_t *assert,
-    const es256_pk_t *pk, const fido_blob_t *ecdh, const char *pin, int ms)
+    const es256_pk_t *pk, const fido_blob_t *ecdh, const char *pin, int *ms)
 {
 	int r;
 
-	if ((r = fido_dev_get_assert_tx(dev, assert, pk, ecdh, pin)) != FIDO_OK ||
+	if ((r = fido_dev_get_assert_tx(dev, assert, pk, ecdh, pin,
+	    ms)) != FIDO_OK ||
 	    (r = fido_dev_get_assert_rx(dev, assert, ms)) != FIDO_OK)
 		return (r);
 
 	while (assert->stmt_len < assert->stmt_cnt) {
-		if ((r = fido_get_next_assert_tx(dev)) != FIDO_OK ||
+		if ((r = fido_get_next_assert_tx(dev, ms)) != FIDO_OK ||
 		    (r = fido_get_next_assert_rx(dev, assert, ms)) != FIDO_OK)
 			return (r);
 		assert->stmt_len++;
@@ -286,11 +306,12 @@ fido_dev_get_assert(fido_dev_t *dev, fid
 {
 	fido_blob_t	*ecdh = NULL;
 	es256_pk_t	*pk = NULL;
+	int		 ms = dev->timeout_ms;
 	int		 r;
 
 #ifdef USE_WINHELLO
 	if (dev->flags & FIDO_DEV_WINHELLO)
-		return (fido_winhello_get_assert(dev, assert, pin));
+		return (fido_winhello_get_assert(dev, assert, pin, ms));
 #endif
 
 	if (assert->rp_id == NULL || assert->cdh.ptr == NULL) {
@@ -302,19 +323,19 @@ fido_dev_get_assert(fido_dev_t *dev, fid
 	if (fido_dev_is_fido2(dev) == false) {
 		if (pin != NULL || assert->ext.mask != 0)
 			return (FIDO_ERR_UNSUPPORTED_OPTION);
-		return (u2f_authenticate(dev, assert, -1));
+		return (u2f_authenticate(dev, assert, &ms));
 	}
 
 	if (pin != NULL || (assert->uv == FIDO_OPT_TRUE &&
 	    fido_dev_supports_permissions(dev)) ||
 	    (assert->ext.mask & FIDO_EXT_HMAC_SECRET)) {
-		if ((r = fido_do_ecdh(dev, &pk, &ecdh)) != FIDO_OK) {
+		if ((r = fido_do_ecdh(dev, &pk, &ecdh, &ms)) != FIDO_OK) {
 			fido_log_debug("%s: fido_do_ecdh", __func__);
 			goto fail;
 		}
 	}
 
-	r = fido_dev_get_assert_wait(dev, assert, pk, ecdh, pin, -1);
+	r = fido_dev_get_assert_wait(dev, assert, pk, ecdh, pin, &ms);
 	if (r == FIDO_OK && (assert->ext.mask & FIDO_EXT_HMAC_SECRET))
 		if (decrypt_hmac_secrets(dev, assert, ecdh) < 0) {
 			fido_log_debug("%s: decrypt_hmac_secrets", __func__);
@@ -364,169 +385,107 @@ check_extensions(int authdata_ext, int e
 	return (0);
 }
 
-int
-fido_get_signed_hash(int cose_alg, fido_blob_t *dgst,
-    const fido_blob_t *clientdata, const fido_blob_t *authdata_cbor)
+static int
+get_es256_hash(fido_blob_t *dgst, const fido_blob_t *clientdata,
+    const fido_blob_t *authdata)
 {
-	cbor_item_t		*item = NULL;
-	unsigned char		*authdata_ptr = NULL;
-	size_t			 authdata_len;
-	struct cbor_load_result	 cbor;
-	SHA256_CTX		 ctx;
-	int			 ok = -1;
+	const EVP_MD	*md;
+	EVP_MD_CTX	*ctx = NULL;
 
-	if ((item = cbor_load(authdata_cbor->ptr, authdata_cbor->len,
-	    &cbor)) == NULL || cbor_isa_bytestring(item) == false ||
-	    cbor_bytestring_is_definite(item) == false) {
-		fido_log_debug("%s: authdata", __func__);
-		goto fail;
+	if (dgst->len < SHA256_DIGEST_LENGTH ||
+	    (md = EVP_sha256()) == NULL ||
+	    (ctx = EVP_MD_CTX_new()) == NULL ||
+	    EVP_DigestInit_ex(ctx, md, NULL) != 1 ||
+	    EVP_DigestUpdate(ctx, authdata->ptr, authdata->len) != 1 ||
+	    EVP_DigestUpdate(ctx, clientdata->ptr, clientdata->len) != 1 ||
+	    EVP_DigestFinal_ex(ctx, dgst->ptr, NULL) != 1) {
+		EVP_MD_CTX_free(ctx);
+		return (-1);
 	}
+	dgst->len = SHA256_DIGEST_LENGTH;
 
-	authdata_ptr = cbor_bytestring_handle(item);
-	authdata_len = cbor_bytestring_length(item);
-
-	if (cose_alg != COSE_EDDSA) {
-		if (dgst->len < SHA256_DIGEST_LENGTH || SHA256_Init(&ctx) == 0 ||
-		    SHA256_Update(&ctx, authdata_ptr, authdata_len) == 0 ||
-		    SHA256_Update(&ctx, clientdata->ptr, clientdata->len) == 0 ||
-		    SHA256_Final(dgst->ptr, &ctx) == 0) {
-			fido_log_debug("%s: sha256", __func__);
-			goto fail;
-		}
-		dgst->len = SHA256_DIGEST_LENGTH;
-	} else {
-		if (SIZE_MAX - authdata_len < clientdata->len ||
-		    dgst->len < authdata_len + clientdata->len) {
-			fido_log_debug("%s: memcpy", __func__);
-			goto fail;
-		}
-		memcpy(dgst->ptr, authdata_ptr, authdata_len);
-		memcpy(dgst->ptr + authdata_len, clientdata->ptr,
-		    clientdata->len);
-		dgst->len = authdata_len + clientdata->len;
-	}
+	EVP_MD_CTX_free(ctx);
 
-	ok = 0;
-fail:
-	if (item != NULL)
-		cbor_decref(&item);
-
-	return (ok);
+	return (0);
 }
 
-int
-fido_verify_sig_es256(const fido_blob_t *dgst, const es256_pk_t *pk,
-    const fido_blob_t *sig)
+static int
+get_es384_hash(fido_blob_t *dgst, const fido_blob_t *clientdata,
+    const fido_blob_t *authdata)
 {
-	EVP_PKEY	*pkey = NULL;
-	EC_KEY		*ec = NULL;
-	int		 ok = -1;
-
-	/* ECDSA_verify needs ints */
-	if (dgst->len > INT_MAX || sig->len > INT_MAX) {
-		fido_log_debug("%s: dgst->len=%zu, sig->len=%zu", __func__,
-		    dgst->len, sig->len);
-		return (-1);
-	}
-
-	if ((pkey = es256_pk_to_EVP_PKEY(pk)) == NULL ||
-	    (ec = __UNCONST(EVP_PKEY_get0_EC_KEY(pkey))) == NULL) {
-		fido_log_debug("%s: pk -> ec", __func__);
-		goto fail;
-	}
+	const EVP_MD	*md;
+	EVP_MD_CTX	*ctx = NULL;
 
-	if (ECDSA_verify(0, dgst->ptr, (int)dgst->len, sig->ptr,
-	    (int)sig->len, ec) != 1) {
-		fido_log_debug("%s: ECDSA_verify", __func__);
-		goto fail;
+	if (dgst->len < SHA384_DIGEST_LENGTH ||
+	    (md = EVP_sha384()) == NULL ||
+	    (ctx = EVP_MD_CTX_new()) == NULL ||
+	    EVP_DigestInit_ex(ctx, md, NULL) != 1 ||
+	    EVP_DigestUpdate(ctx, authdata->ptr, authdata->len) != 1 ||
+	    EVP_DigestUpdate(ctx, clientdata->ptr, clientdata->len) != 1 ||
+	    EVP_DigestFinal_ex(ctx, dgst->ptr, NULL) != 1) {
+		EVP_MD_CTX_free(ctx);
+		return (-1);
 	}
+	dgst->len = SHA384_DIGEST_LENGTH;
 
-	ok = 0;
-fail:
-	if (pkey != NULL)
-		EVP_PKEY_free(pkey);
+	EVP_MD_CTX_free(ctx);
 
-	return (ok);
+	return (0);
 }
 
-int
-fido_verify_sig_rs256(const fido_blob_t *dgst, const rs256_pk_t *pk,
-    const fido_blob_t *sig)
+static int
+get_eddsa_hash(fido_blob_t *dgst, const fido_blob_t *clientdata,
+    const fido_blob_t *authdata)
 {
-	EVP_PKEY	*pkey = NULL;
-	RSA		*rsa = NULL;
-	int		 ok = -1;
-
-	/* RSA_verify needs unsigned ints */
-	if (dgst->len > UINT_MAX || sig->len > UINT_MAX) {
-		fido_log_debug("%s: dgst->len=%zu, sig->len=%zu", __func__,
-		    dgst->len, sig->len);
+	if (SIZE_MAX - authdata->len < clientdata->len ||
+	    dgst->len < authdata->len + clientdata->len)
 		return (-1);
-	}
-
-	if ((pkey = rs256_pk_to_EVP_PKEY(pk)) == NULL ||
-	    (rsa = __UNCONST(EVP_PKEY_get0_RSA(pkey))) == NULL) {
-		fido_log_debug("%s: pk -> ec", __func__);
-		goto fail;
-	}
 
-	if (RSA_verify(NID_sha256, dgst->ptr, (unsigned int)dgst->len, sig->ptr,
-	    (unsigned int)sig->len, rsa) != 1) {
-		fido_log_debug("%s: RSA_verify", __func__);
-		goto fail;
-	}
-
-	ok = 0;
-fail:
-	if (pkey != NULL)
-		EVP_PKEY_free(pkey);
+	memcpy(dgst->ptr, authdata->ptr, authdata->len);
+	memcpy(dgst->ptr + authdata->len, clientdata->ptr, clientdata->len);
+	dgst->len = authdata->len + clientdata->len;
 
-	return (ok);
+	return (0);
 }
 
 int
-fido_verify_sig_eddsa(const fido_blob_t *dgst, const eddsa_pk_t *pk,
-    const fido_blob_t *sig)
+fido_get_signed_hash(int cose_alg, fido_blob_t *dgst,
+    const fido_blob_t *clientdata, const fido_blob_t *authdata_cbor)
 {
-	EVP_PKEY	*pkey = NULL;
-	EVP_MD_CTX	*mdctx = NULL;
-	int		 ok = -1;
-
-	/* EVP_DigestVerify needs ints */
-	if (dgst->len > INT_MAX || sig->len > INT_MAX) {
-		fido_log_debug("%s: dgst->len=%zu, sig->len=%zu", __func__,
-		    dgst->len, sig->len);
-		return (-1);
-	}
+	cbor_item_t		*item = NULL;
+	fido_blob_t		 authdata;
+	struct cbor_load_result	 cbor;
+	int			 ok = -1;
 
-	if ((pkey = eddsa_pk_to_EVP_PKEY(pk)) == NULL) {
-		fido_log_debug("%s: pk -> pkey", __func__);
-		goto fail;
-	}
+	fido_log_debug("%s: cose_alg=%d", __func__, cose_alg);
 
-	if ((mdctx = EVP_MD_CTX_new()) == NULL) {
-		fido_log_debug("%s: EVP_MD_CTX_new", __func__);
-		goto fail;
-	}
-
-	if (EVP_DigestVerifyInit(mdctx, NULL, NULL, NULL, pkey) != 1) {
-		fido_log_debug("%s: EVP_DigestVerifyInit", __func__);
+	if ((item = cbor_load(authdata_cbor->ptr, authdata_cbor->len,
+	    &cbor)) == NULL || cbor_isa_bytestring(item) == false ||
+	    cbor_bytestring_is_definite(item) == false) {
+		fido_log_debug("%s: authdata", __func__);
 		goto fail;
 	}
+	authdata.ptr = cbor_bytestring_handle(item);
+	authdata.len = cbor_bytestring_length(item);
 
-	if (EVP_DigestVerify(mdctx, sig->ptr, sig->len, dgst->ptr,
-	    dgst->len) != 1) {
-		fido_log_debug("%s: EVP_DigestVerify", __func__);
-		goto fail;
+	switch (cose_alg) {
+	case COSE_ES256:
+	case COSE_RS256:
+		ok = get_es256_hash(dgst, clientdata, &authdata);
+		break;
+	case COSE_ES384:
+		ok = get_es384_hash(dgst, clientdata, &authdata);
+		break;
+	case COSE_EDDSA:
+		ok = get_eddsa_hash(dgst, clientdata, &authdata);
+		break;
+	default:
+		fido_log_debug("%s: unknown cose_alg", __func__);
+		break;
 	}
-
-	ok = 0;
 fail:
-	if (mdctx != NULL)
-		EVP_MD_CTX_free(mdctx);
-
-	if (pkey != NULL)
-		EVP_PKEY_free(pkey);
+	if (item != NULL)
+		cbor_decref(&item);
 
 	return (ok);
 }
@@ -589,13 +548,16 @@ fido_assert_verify(const fido_assert_t *
 
 	switch (cose_alg) {
 	case COSE_ES256:
-		ok = fido_verify_sig_es256(&dgst, pk, &stmt->sig);
+		ok = es256_pk_verify_sig(&dgst, pk, &stmt->sig);
+		break;
+	case COSE_ES384:
+		ok = es384_pk_verify_sig(&dgst, pk, &stmt->sig);
 		break;
 	case COSE_RS256:
-		ok = fido_verify_sig_rs256(&dgst, pk, &stmt->sig);
+		ok = rs256_pk_verify_sig(&dgst, pk, &stmt->sig);
 		break;
 	case COSE_EDDSA:
-		ok = fido_verify_sig_eddsa(&dgst, pk, &stmt->sig);
+		ok = eddsa_pk_verify_sig(&dgst, pk, &stmt->sig);
 		break;
 	default:
 		fido_log_debug("%s: unsupported cose_alg %d", __func__,
@@ -711,7 +673,15 @@ fail:
 	free(id.ptr);
 
 	return (r);
+}
 
+int
+fido_assert_empty_allow_list(fido_assert_t *assert)
+{
+	fido_free_blob_array(&assert->allow_list);
+	memset(&assert->allow_list, 0, sizeof(assert->allow_list));
+
+	return (FIDO_OK);
 }
 
 int
@@ -778,15 +748,15 @@ fido_assert_reset_tx(fido_assert_t *asse
 	fido_blob_reset(&assert->cd);
 	fido_blob_reset(&assert->cdh);
 	fido_blob_reset(&assert->ext.hmac_salt);
-	fido_free_blob_array(&assert->allow_list);
+	fido_assert_empty_allow_list(assert);
 	memset(&assert->ext, 0, sizeof(assert->ext));
-	memset(&assert->allow_list, 0, sizeof(assert->allow_list));
 	assert->rp_id = NULL;
 	assert->up = FIDO_OPT_OMIT;
 	assert->uv = FIDO_OPT_OMIT;
 }
 
-static void fido_assert_reset_extattr(fido_assert_extattr_t *ext)
+static void
+fido_assert_reset_extattr(fido_assert_extattr_t *ext)
 {
 	fido_blob_reset(&ext->hmac_secret_enc);
 	fido_blob_reset(&ext->blob);
Index: src/external/bsd/libfido2/dist/src/cred.c
diff -u src/external/bsd/libfido2/dist/src/cred.c:1.2 src/external/bsd/libfido2/dist/src/cred.c:1.3
--- src/external/bsd/libfido2/dist/src/cred.c:1.2	Mon May  8 19:45:52 2023
+++ src/external/bsd/libfido2/dist/src/cred.c	Fri Aug 11 19:02:08 2023
@@ -1,7 +1,8 @@
 /*
- * Copyright (c) 2018 Yubico AB. All rights reserved.
+ * Copyright (c) 2018-2022 Yubico AB. All rights reserved.
  * Use of this source code is governed by a BSD-style
  * license that can be found in the LICENSE file.
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #include <openssl/sha.h>
@@ -10,6 +11,10 @@
 #include "fido.h"
 #include "fido/es256.h"
 
+#ifndef FIDO_MAXMSG_CRED
+#define FIDO_MAXMSG_CRED	4096
+#endif
+
 static int
 parse_makecred_reply(const cbor_item_t *key, const cbor_item_t *val, void *arg)
 {
@@ -43,7 +48,8 @@ parse_makecred_reply(const cbor_item_t *
 }
 
 static int
-fido_dev_make_cred_tx(fido_dev_t *dev, fido_cred_t *cred, const char *pin)
+fido_dev_make_cred_tx(fido_dev_t *dev, fido_cred_t *cred, const char *pin,
+    int *ms)
 {
 	fido_blob_t	 f;
 	fido_blob_t	*ecdh = NULL;
@@ -92,12 +98,12 @@ fido_dev_make_cred_tx(fido_dev_t *dev, f
 	/* user verification */
 	if (pin != NULL || (uv == FIDO_OPT_TRUE &&
 	    fido_dev_supports_permissions(dev))) {
-		if ((r = fido_do_ecdh(dev, &pk, &ecdh)) != FIDO_OK) {
+		if ((r = fido_do_ecdh(dev, &pk, &ecdh, ms)) != FIDO_OK) {
 			fido_log_debug("%s: fido_do_ecdh", __func__);
 			goto fail;
 		}
 		if ((r = cbor_add_uv_params(dev, cmd, &cred->cdh, pk, ecdh,
-		    pin, cred->rp.id, &argv[7], &argv[8])) != FIDO_OK) {
+		    pin, cred->rp.id, &argv[7], &argv[8], ms)) != FIDO_OK) {
 			fido_log_debug("%s: cbor_add_uv_params", __func__);
 			goto fail;
 		}
@@ -114,7 +120,7 @@ fido_dev_make_cred_tx(fido_dev_t *dev, f
 
 	/* framing and transmission */
 	if (cbor_build_frame(cmd, argv, nitems(argv), &f) < 0 ||
-	    fido_tx(dev, CTAP_CMD_CBOR, f.ptr, f.len) < 0) {
+	    fido_tx(dev, CTAP_CMD_CBOR, f.ptr, f.len, ms) < 0) {
 		fido_log_debug("%s: fido_tx", __func__);
 		r = FIDO_ERR_TX;
 		goto fail;
@@ -131,42 +137,55 @@ fail:
 }
 
 static int
-fido_dev_make_cred_rx(fido_dev_t *dev, fido_cred_t *cred, int ms)
+fido_dev_make_cred_rx(fido_dev_t *dev, fido_cred_t *cred, int *ms)
 {
-	unsigned char	reply[FIDO_MAXMSG];
-	int		reply_len;
-	int		r;
+	unsigned char	*reply;
+	int		 reply_len;
+	int		 r;
 
 	fido_cred_reset_rx(cred);
 
-	if ((reply_len = fido_rx(dev, CTAP_CMD_CBOR, &reply, sizeof(reply),
+	if ((reply = malloc(FIDO_MAXMSG_CRED)) == NULL) {
+		r = FIDO_ERR_INTERNAL;
+		goto fail;
+	}
+
+	if ((reply_len = fido_rx(dev, CTAP_CMD_CBOR, reply, FIDO_MAXMSG_CRED,
 	    ms)) < 0) {
 		fido_log_debug("%s: fido_rx", __func__);
-		return (FIDO_ERR_RX);
+		r = FIDO_ERR_RX;
+		goto fail;
 	}
 
 	if ((r = cbor_parse_reply(reply, (size_t)reply_len, cred,
 	    parse_makecred_reply)) != FIDO_OK) {
 		fido_log_debug("%s: parse_makecred_reply", __func__);
-		return (r);
+		goto fail;
 	}
 
 	if (cred->fmt == NULL || fido_blob_is_empty(&cred->authdata_cbor) ||
 	    fido_blob_is_empty(&cred->attcred.id)) {
-		fido_cred_reset_rx(cred);
-		return (FIDO_ERR_INVALID_CBOR);
+		r = FIDO_ERR_INVALID_CBOR;
+		goto fail;
 	}
 
-	return (FIDO_OK);
+	r = FIDO_OK;
+fail:
+	free(reply);
+
+	if (r != FIDO_OK)
+		fido_cred_reset_rx(cred);
+
+	return (r);
 }
 
 static int
 fido_dev_make_cred_wait(fido_dev_t *dev, fido_cred_t *cred, const char *pin,
-    int ms)
+    int *ms)
 {
 	int  r;
 
-	if ((r = fido_dev_make_cred_tx(dev, cred, pin)) != FIDO_OK ||
+	if ((r = fido_dev_make_cred_tx(dev, cred, pin, ms)) != FIDO_OK ||
 	    (r = fido_dev_make_cred_rx(dev, cred, ms)) != FIDO_OK)
 		return (r);
 
@@ -176,18 +195,20 @@ fido_dev_make_cred_wait(fido_dev_t *dev,
 int
 fido_dev_make_cred(fido_dev_t *dev, fido_cred_t *cred, const char *pin)
 {
+	int ms = dev->timeout_ms;
+
 #ifdef USE_WINHELLO
 	if (dev->flags & FIDO_DEV_WINHELLO)
-		return (fido_winhello_make_cred(dev, cred, pin));
+		return (fido_winhello_make_cred(dev, cred, pin, ms));
 #endif
 	if (fido_dev_is_fido2(dev) == false) {
 		if (pin != NULL || cred->rk == FIDO_OPT_TRUE ||
 		    cred->ext.mask != 0)
 			return (FIDO_ERR_UNSUPPORTED_OPTION);
-		return (u2f_register(dev, cred, -1));
+		return (u2f_register(dev, cred, &ms));
 	}
 
-	return (fido_dev_make_cred_wait(dev, cred, pin, -1));
+	return (fido_dev_make_cred_wait(dev, cred, pin, &ms));
 }
 
 static int
@@ -225,66 +246,85 @@ get_signed_hash_u2f(fido_blob_t *dgst, c
     size_t rp_id_len, const fido_blob_t *clientdata, const fido_blob_t *id,
     const es256_pk_t *pk)
 {
-	const uint8_t		zero = 0;
-	const uint8_t		four = 4; /* uncompressed point */
-	SHA256_CTX		ctx;
-
-	if (dgst->len != SHA256_DIGEST_LENGTH || SHA256_Init(&ctx) == 0 ||
-	    SHA256_Update(&ctx, &zero, sizeof(zero)) == 0 ||
-	    SHA256_Update(&ctx, rp_id, rp_id_len) == 0 ||
-	    SHA256_Update(&ctx, clientdata->ptr, clientdata->len) == 0 ||
-	    SHA256_Update(&ctx, id->ptr, id->len) == 0 ||
-	    SHA256_Update(&ctx, &four, sizeof(four)) == 0 ||
-	    SHA256_Update(&ctx, pk->x, sizeof(pk->x)) == 0 ||
-	    SHA256_Update(&ctx, pk->y, sizeof(pk->y)) == 0 ||
-	    SHA256_Final(dgst->ptr, &ctx) == 0) {
+	const uint8_t	 zero = 0;
+	const uint8_t	 four = 4; /* uncompressed point */
+	const EVP_MD	*md = NULL;
+	EVP_MD_CTX	*ctx = NULL;
+	int		 ok = -1;
+
+	if (dgst->len < SHA256_DIGEST_LENGTH ||
+	    (md = EVP_sha256()) == NULL ||
+	    (ctx = EVP_MD_CTX_new()) == NULL ||
+	    EVP_DigestInit_ex(ctx, md, NULL) != 1 ||
+	    EVP_DigestUpdate(ctx, &zero, sizeof(zero)) != 1 ||
+	    EVP_DigestUpdate(ctx, rp_id, rp_id_len) != 1 ||
+	    EVP_DigestUpdate(ctx, clientdata->ptr, clientdata->len) != 1 ||
+	    EVP_DigestUpdate(ctx, id->ptr, id->len) != 1 ||
+	    EVP_DigestUpdate(ctx, &four, sizeof(four)) != 1 ||
+	    EVP_DigestUpdate(ctx, pk->x, sizeof(pk->x)) != 1 ||
+	    EVP_DigestUpdate(ctx, pk->y, sizeof(pk->y)) != 1 ||
+	    EVP_DigestFinal_ex(ctx, dgst->ptr, NULL) != 1) {
 		fido_log_debug("%s: sha256", __func__);
-		return (-1);
+		goto fail;
 	}
+	dgst->len = SHA256_DIGEST_LENGTH;
 
-	return (0);
+	ok = 0;
+fail:
+	EVP_MD_CTX_free(ctx);
+
+	return (ok);
 }
 
 static int
-verify_sig(const fido_blob_t *dgst, const fido_blob_t *x5c,
-    const fido_blob_t *sig)
+verify_attstmt(const fido_blob_t *dgst, const fido_attstmt_t *attstmt)
 {
 	BIO		*rawcert = NULL;
 	X509		*cert = NULL;
 	EVP_PKEY	*pkey = NULL;
-	EC_KEY		*ec;
 	int		 ok = -1;
 
 	/* openssl needs ints */
-	if (dgst->len > INT_MAX || x5c->len > INT_MAX || sig->len > INT_MAX) {
-		fido_log_debug("%s: dgst->len=%zu, x5c->len=%zu, sig->len=%zu",
-		    __func__, dgst->len, x5c->len, sig->len);
+	if (attstmt->x5c.len > INT_MAX) {
+		fido_log_debug("%s: x5c.len=%zu", __func__, attstmt->x5c.len);
 		return (-1);
 	}
 
 	/* fetch key from x509 */
-	if ((rawcert = BIO_new_mem_buf(x5c->ptr, (int)x5c->len)) == NULL ||
+	if ((rawcert = BIO_new_mem_buf(attstmt->x5c.ptr,
+	    (int)attstmt->x5c.len)) == NULL ||
 	    (cert = d2i_X509_bio(rawcert, NULL)) == NULL ||
-	    (pkey = X509_get_pubkey(cert)) == NULL ||
-	    (ec = __UNCONST(EVP_PKEY_get0_EC_KEY(pkey))) == NULL) {
+	    (pkey = X509_get_pubkey(cert)) == NULL) {
 		fido_log_debug("%s: x509 key", __func__);
 		goto fail;
 	}
 
-	if (ECDSA_verify(0, dgst->ptr, (int)dgst->len, sig->ptr,
-	    (int)sig->len, ec) != 1) {
-		fido_log_debug("%s: ECDSA_verify", __func__);
-		goto fail;
+	switch (attstmt->alg) {
+	case COSE_UNSPEC:
+	case COSE_ES256:
+		ok = es256_verify_sig(dgst, pkey, &attstmt->sig);
+		break;
+	case COSE_ES384:
+		ok = es384_verify_sig(dgst, pkey, &attstmt->sig);
+		break;
+	case COSE_RS256:
+		ok = rs256_verify_sig(dgst, pkey, &attstmt->sig);
+		break;
+	case COSE_RS1:
+		ok = rs1_verify_sig(dgst, pkey, &attstmt->sig);
+		break;
+	case COSE_EDDSA:
+		ok = eddsa_verify_sig(dgst, pkey, &attstmt->sig);
+		break;
+	default:
+		fido_log_debug("%s: unknown alg %d", __func__, attstmt->alg);
+		break;
 	}
 
-	ok = 0;
 fail:
-	if (rawcert != NULL)
-		BIO_free(rawcert);
-	if (cert != NULL)
-		X509_free(cert);
-	if (pkey != NULL)
-		EVP_PKEY_free(pkey);
+	BIO_free(rawcert);
+	X509_free(cert);
+	EVP_PKEY_free(pkey);
 
 	return (ok);
 }
@@ -292,8 +332,9 @@ fail:
 int
 fido_cred_verify(const fido_cred_t *cred)
 {
-	unsigned char	buf[SHA256_DIGEST_LENGTH];
+	unsigned char	buf[1024]; /* XXX */
 	fido_blob_t	dgst;
+	int		cose_alg;
 	int		r;
 
 	dgst.ptr = buf;
@@ -333,8 +374,11 @@ fido_cred_verify(const fido_cred_t *cred
 		goto out;
 	}
 
+	if ((cose_alg = cred->attstmt.alg) == COSE_UNSPEC)
+		cose_alg = COSE_ES256; /* backwards compat */
+
 	if (!strcmp(cred->fmt, "packed")) {
-		if (fido_get_signed_hash(COSE_ES256, &dgst, &cred->cdh,
+		if (fido_get_signed_hash(cose_alg, &dgst, &cred->cdh,
 		    &cred->authdata_cbor) < 0) {
 			fido_log_debug("%s: fido_get_signed_hash", __func__);
 			r = FIDO_ERR_INTERNAL;
@@ -348,14 +392,21 @@ fido_cred_verify(const fido_cred_t *cred
 			r = FIDO_ERR_INTERNAL;
 			goto out;
 		}
+	} else if (!strcmp(cred->fmt, "tpm")) {
+		if (fido_get_signed_hash_tpm(&dgst, &cred->cdh,
+		    &cred->authdata_raw, &cred->attstmt, &cred->attcred) < 0) {
+			fido_log_debug("%s: fido_get_signed_hash_tpm", __func__);
+			r = FIDO_ERR_INTERNAL;
+			goto out;
+		}
 	} else {
 		fido_log_debug("%s: unknown fmt %s", __func__, cred->fmt);
 		r = FIDO_ERR_INVALID_ARGUMENT;
 		goto out;
 	}
 
-	if (verify_sig(&dgst, &cred->attstmt.x5c, &cred->attstmt.sig) < 0) {
-		fido_log_debug("%s: verify_sig", __func__);
+	if (verify_attstmt(&dgst, &cred->attstmt) < 0) {
+		fido_log_debug("%s: verify_attstmt", __func__);
 		r = FIDO_ERR_INVALID_SIG;
 		goto out;
 	}
@@ -435,15 +486,19 @@ fido_cred_verify_self(const fido_cred_t 
 
 	switch (cred->attcred.type) {
 	case COSE_ES256:
-		ok = fido_verify_sig_es256(&dgst, &cred->attcred.pubkey.es256,
+		ok = es256_pk_verify_sig(&dgst, &cred->attcred.pubkey.es256,
+		    &cred->attstmt.sig);
+		break;
+	case COSE_ES384:
+		ok = es384_pk_verify_sig(&dgst, &cred->attcred.pubkey.es384,
 		    &cred->attstmt.sig);
 		break;
 	case COSE_RS256:
-		ok = fido_verify_sig_rs256(&dgst, &cred->attcred.pubkey.rs256,
+		ok = rs256_pk_verify_sig(&dgst, &cred->attcred.pubkey.rs256,
 		    &cred->attstmt.sig);
 		break;
 	case COSE_EDDSA:
-		ok = fido_verify_sig_eddsa(&dgst, &cred->attcred.pubkey.eddsa,
+		ok = eddsa_pk_verify_sig(&dgst, &cred->attcred.pubkey.eddsa,
 		    &cred->attstmt.sig);
 		break;
 	default:
@@ -482,6 +537,18 @@ fido_cred_clean_authdata(fido_cred_t *cr
 	memset(&cred->attcred, 0, sizeof(cred->attcred));
 }
 
+static void
+fido_cred_clean_attstmt(fido_attstmt_t *attstmt)
+{
+	fido_blob_reset(&attstmt->certinfo);
+	fido_blob_reset(&attstmt->pubarea);
+	fido_blob_reset(&attstmt->cbor);
+	fido_blob_reset(&attstmt->x5c);
+	fido_blob_reset(&attstmt->sig);
+
+	memset(attstmt, 0, sizeof(*attstmt));
+}
+
 void
 fido_cred_reset_tx(fido_cred_t *cred)
 {
@@ -495,11 +562,10 @@ fido_cred_reset_tx(fido_cred_t *cred)
 	free(cred->user.icon);
 	free(cred->user.name);
 	free(cred->user.display_name);
-	fido_free_blob_array(&cred->excl);
+	fido_cred_empty_exclude_list(cred);
 
 	memset(&cred->rp, 0, sizeof(cred->rp));
 	memset(&cred->user, 0, sizeof(cred->user));
-	memset(&cred->excl, 0, sizeof(cred->excl));
 	memset(&cred->ext, 0, sizeof(cred->ext));
 
 	cred->type = 0;
@@ -513,8 +579,7 @@ fido_cred_reset_rx(fido_cred_t *cred)
 	free(cred->fmt);
 	cred->fmt = NULL;
 	fido_cred_clean_authdata(cred);
-	fido_blob_reset(&cred->attstmt.x5c);
-	fido_blob_reset(&cred->attstmt.sig);
+	fido_cred_clean_attstmt(&cred->attstmt);
 	fido_blob_reset(&cred->largeblob_key);
 }
 
@@ -568,7 +633,6 @@ fail:
 		fido_cred_clean_authdata(cred);
 
 	return (r);
-
 }
 
 int
@@ -610,7 +674,6 @@ fail:
 		fido_cred_clean_authdata(cred);
 
 	return (r);
-
 }
 
 int
@@ -641,6 +704,39 @@ fido_cred_set_sig(fido_cred_t *cred, con
 }
 
 int
+fido_cred_set_attstmt(fido_cred_t *cred, const unsigned char *ptr, size_t len)
+{
+	cbor_item_t		*item = NULL;
+	struct cbor_load_result	 cbor;
+	int			 r = FIDO_ERR_INVALID_ARGUMENT;
+
+	fido_cred_clean_attstmt(&cred->attstmt);
+
+	if (ptr == NULL || len == 0)
+		goto fail;
+
+	if ((item = cbor_load(ptr, len, &cbor)) == NULL) {
+		fido_log_debug("%s: cbor_load", __func__);
+		goto fail;
+	}
+
+	if (cbor_decode_attstmt(item, &cred->attstmt) < 0) {
+		fido_log_debug("%s: cbor_decode_attstmt", __func__);
+		goto fail;
+	}
+
+	r = FIDO_OK;
+fail:
+	if (item != NULL)
+		cbor_decref(&item);
+
+	if (r != FIDO_OK)
+		fido_cred_clean_attstmt(&cred->attstmt);
+
+	return (r);
+}
+
+int
 fido_cred_exclude(fido_cred_t *cred, const unsigned char *id_ptr, size_t id_len)
 {
 	fido_blob_t id_blob;
@@ -669,6 +765,15 @@ fido_cred_exclude(fido_cred_t *cred, con
 }
 
 int
+fido_cred_empty_exclude_list(fido_cred_t *cred)
+{
+	fido_free_blob_array(&cred->excl);
+	memset(&cred->excl, 0, sizeof(cred->excl));
+
+	return (FIDO_OK);
+}
+
+int
 fido_cred_set_clientdata(fido_cred_t *cred, const unsigned char *data,
     size_t data_len)
 {
@@ -834,6 +939,19 @@ fido_cred_set_prot(fido_cred_t *cred, in
 }
 
 int
+fido_cred_set_pin_minlen(fido_cred_t *cred, size_t len)
+{
+	if (len == 0)
+		cred->ext.mask &= ~FIDO_EXT_MINPINLEN;
+	else
+		cred->ext.mask |= FIDO_EXT_MINPINLEN;
+
+	cred->ext.minpinlen = len;
+
+	return (FIDO_OK);
+}
+
+int
 fido_cred_set_blob(fido_cred_t *cred, const unsigned char *ptr, size_t len)
 {
 	if (ptr == NULL || len == 0)
@@ -856,7 +974,7 @@ fido_cred_set_fmt(fido_cred_t *cred, con
 		return (FIDO_ERR_INVALID_ARGUMENT);
 
 	if (strcmp(fmt, "packed") && strcmp(fmt, "fido-u2f") &&
-	    strcmp(fmt, "none"))
+	    strcmp(fmt, "none") && strcmp(fmt, "tpm"))
 		return (FIDO_ERR_INVALID_ARGUMENT);
 
 	if ((cred->fmt = strdup(fmt)) == NULL)
@@ -868,8 +986,10 @@ fido_cred_set_fmt(fido_cred_t *cred, con
 int
 fido_cred_set_type(fido_cred_t *cred, int cose_alg)
 {
-	if ((cose_alg != COSE_ES256 && cose_alg != COSE_RS256 &&
-	    cose_alg != COSE_EDDSA) || cred->type != 0)
+	if (cred->type != 0)
+		return (FIDO_ERR_INVALID_ARGUMENT);
+	if (cose_alg != COSE_ES256 && cose_alg != COSE_ES384 &&
+	    cose_alg != COSE_RS256 && cose_alg != COSE_EDDSA)
 		return (FIDO_ERR_INVALID_ARGUMENT);
 
 	cred->type = cose_alg;
@@ -956,6 +1076,18 @@ fido_cred_authdata_raw_len(const fido_cr
 }
 
 const unsigned char *
+fido_cred_attstmt_ptr(const fido_cred_t *cred)
+{
+	return (cred->attstmt.cbor.ptr);
+}
+
+size_t
+fido_cred_attstmt_len(const fido_cred_t *cred)
+{
+	return (cred->attstmt.cbor.len);
+}
+
+const unsigned char *
 fido_cred_pubkey_ptr(const fido_cred_t *cred)
 {
 	const void *ptr;
@@ -964,6 +1096,9 @@ fido_cred_pubkey_ptr(const fido_cred_t *
 	case COSE_ES256:
 		ptr = &cred->attcred.pubkey.es256;
 		break;
+	case COSE_ES384:
+		ptr = &cred->attcred.pubkey.es384;
+		break;
 	case COSE_RS256:
 		ptr = &cred->attcred.pubkey.rs256;
 		break;
@@ -987,6 +1122,9 @@ fido_cred_pubkey_len(const fido_cred_t *
 	case COSE_ES256:
 		len = sizeof(cred->attcred.pubkey.es256);
 		break;
+	case COSE_ES384:
+		len = sizeof(cred->attcred.pubkey.es384);
+		break;
 	case COSE_RS256:
 		len = sizeof(cred->attcred.pubkey.rs256);
 		break;
@@ -1031,6 +1169,12 @@ fido_cred_prot(const fido_cred_t *cred)
 	return (cred->ext.prot);
 }
 
+size_t
+fido_cred_pin_minlen(const fido_cred_t *cred)
+{
+	return (cred->ext.minpinlen);
+}
+
 const char *
 fido_cred_fmt(const fido_cred_t *cred)
 {

Index: src/external/bsd/libfido2/dist/src/hid_netbsd.c
diff -u src/external/bsd/libfido2/dist/src/hid_netbsd.c:1.3 src/external/bsd/libfido2/dist/src/hid_netbsd.c:1.4
--- src/external/bsd/libfido2/dist/src/hid_netbsd.c:1.3	Thu Jun 17 08:53:43 2021
+++ src/external/bsd/libfido2/dist/src/hid_netbsd.c	Fri Aug 11 19:02:08 2023
@@ -2,6 +2,7 @@
  * Copyright (c) 2020 Yubico AB. All rights reserved.
  * Use of this source code is governed by a BSD-style
  * license that can be found in the LICENSE file.
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #include <sys/types.h>

Index: src/external/bsd/libfido2/dist/tools/util.c
diff -u src/external/bsd/libfido2/dist/tools/util.c:1.3 src/external/bsd/libfido2/dist/tools/util.c:1.4
--- src/external/bsd/libfido2/dist/tools/util.c:1.3	Fri Sep 24 09:07:34 2021
+++ src/external/bsd/libfido2/dist/tools/util.c	Fri Aug 11 19:02:08 2023
@@ -1,7 +1,8 @@
 /*
- * Copyright (c) 2018-2021 Yubico AB. All rights reserved.
+ * Copyright (c) 2018-2022 Yubico AB. All rights reserved.
  * Use of this source code is governed by a BSD-style
  * license that can be found in the LICENSE file.
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #include <sys/types.h>
@@ -13,6 +14,7 @@
 
 #include <fido.h>
 #include <fido/es256.h>
+#include <fido/es384.h>
 #include <fido/rs256.h>
 #include <fido/eddsa.h>
 
@@ -245,7 +247,7 @@ fail:
 }
 
 int
-write_ec_pubkey(FILE *f, const void *ptr, size_t len)
+write_es256_pubkey(FILE *f, const void *ptr, size_t len)
 {
 	EVP_PKEY *pkey = NULL;
 	es256_pk_t *pk = NULL;
@@ -282,6 +284,44 @@ fail:
 	return (ok);
 }
 
+int
+write_es384_pubkey(FILE *f, const void *ptr, size_t len)
+{
+	EVP_PKEY *pkey = NULL;
+	es384_pk_t *pk = NULL;
+	int ok = -1;
+
+	if ((pk = es384_pk_new()) == NULL) {
+		warnx("es384_pk_new");
+		goto fail;
+	}
+
+	if (es384_pk_from_ptr(pk, ptr, len) != FIDO_OK) {
+		warnx("es384_pk_from_ptr");
+		goto fail;
+	}
+
+	if ((pkey = es384_pk_to_EVP_PKEY(pk)) == NULL) {
+		warnx("es384_pk_to_EVP_PKEY");
+		goto fail;
+	}
+
+	if (PEM_write_PUBKEY(f, pkey) == 0) {
+		warnx("PEM_write_PUBKEY");
+		goto fail;
+	}
+
+	ok = 0;
+fail:
+	es384_pk_free(&pk);
+
+	if (pkey != NULL) {
+		EVP_PKEY_free(pkey);
+	}
+
+	return (ok);
+}
+
 RSA *
 read_rsa_pubkey(const char *path)
 {
@@ -426,16 +466,24 @@ print_cred(FILE *out_f, int type, const 
 
 	fprintf(out_f, "%s\n", id);
 
-	if (type == COSE_ES256) {
-		write_ec_pubkey(out_f, fido_cred_pubkey_ptr(cred),
+	switch (type) {
+	case COSE_ES256:
+		write_es256_pubkey(out_f, fido_cred_pubkey_ptr(cred),
+		    fido_cred_pubkey_len(cred));
+		break;
+	case COSE_ES384:
+		write_es384_pubkey(out_f, fido_cred_pubkey_ptr(cred),
 		    fido_cred_pubkey_len(cred));
-	} else if (type == COSE_RS256) {
+		break;
+	case COSE_RS256:
 		write_rsa_pubkey(out_f, fido_cred_pubkey_ptr(cred),
 		    fido_cred_pubkey_len(cred));
-	} else if (type == COSE_EDDSA) {
+		break;
+	case COSE_EDDSA:
 		write_eddsa_pubkey(out_f, fido_cred_pubkey_ptr(cred),
 		    fido_cred_pubkey_len(cred));
-	} else {
+		break;
+	default:
 		errx(1, "print_cred: unknown type");
 	}
 
@@ -447,6 +495,8 @@ cose_type(const char *str, int *type)
 {
 	if (strcmp(str, "es256") == 0)
 		*type = COSE_ES256;
+	else if (strcmp(str, "es384") == 0)
+		*type = COSE_ES384;
 	else if (strcmp(str, "rs256") == 0)
 		*type = COSE_RS256;
 	else if (strcmp(str, "eddsa") == 0)
@@ -463,12 +513,14 @@ const char *
 cose_string(int type)
 {
 	switch (type) {
-	case COSE_EDDSA:
-		return ("eddsa");
 	case COSE_ES256:
 		return ("es256");
+	case COSE_ES384:
+		return ("es384");
 	case COSE_RS256:
 		return ("rs256");
+	case COSE_EDDSA:
+		return ("eddsa");
 	default:
 		return ("unknown");
 	}

Index: src/external/bsd/libfido2/lib/Makefile
diff -u src/external/bsd/libfido2/lib/Makefile:1.10 src/external/bsd/libfido2/lib/Makefile:1.11
--- src/external/bsd/libfido2/lib/Makefile:1.10	Sat May 13 09:04:03 2023
+++ src/external/bsd/libfido2/lib/Makefile	Fri Aug 11 19:02:08 2023
@@ -1,4 +1,4 @@
-# $NetBSD: Makefile,v 1.10 2023/05/13 13:04:03 riastradh Exp $
+# $NetBSD: Makefile,v 1.11 2023/08/11 23:02:08 christos Exp $
 
 NOLINT=
 .include <bsd.own.mk>
@@ -32,6 +32,7 @@ ecdh.c \
 eddsa.c \
 err.c \
 es256.c \
+es384.c \
 hid.c \
 hid_netbsd.c \
 hid_unix.c \
@@ -43,7 +44,12 @@ log.c \
 pin.c \
 random.c \
 reset.c \
+rs1.c \
 rs256.c \
+time.c \
+tpm.c \
+touch.c \
+types.c \
 u2f.c
 
 SRCS+= \
@@ -60,6 +66,7 @@ fido/credman.h \
 fido/eddsa.h \
 fido/err.h \
 fido/es256.h \
+fido/es384.h \
 fido/param.h \
 fido/rs256.h \
 fido/types.h
@@ -69,6 +76,7 @@ INCSDIR=/usr/include
 MAN+= \
 eddsa_pk_new.3 \
 es256_pk_new.3 \
+es384_pk_new.3 \
 fido_assert_allow_cred.3 \
 fido_assert_new.3 \
 fido_assert_set_authdata.3 \
@@ -96,7 +104,7 @@ fido_init.3 \
 fido_strerr.3 \
 rs256_pk_new.3
 
-SHLIB_MAJOR=4
+SHLIB_MAJOR=5
 SHLIB_MINOR=0
 
 .SUFFIXES: .in
@@ -118,6 +126,7 @@ COPTS.cred.c+=-Wno-error=deprecated-decl
 COPTS.ecdh.c+=-Wno-error=deprecated-declarations
 COPTS.ecdh.c+=-Wno-error=pointer-sign
 COPTS.es256.c+=-Wno-error=deprecated-declarations
+COPTS.es384.c+=-Wno-error=deprecated-declarations
 COPTS.rs256.c+=-Wno-error=deprecated-declarations
 
 .include <bsd.lib.mk>

Reply via email to