logo

oasis

Own branch of Oasis Linux (upstream: <https://git.sr.ht/~mcf/oasis/>) git clone https://anongit.hacktivis.me/git/oasis.git
commit: 014b85bf7248c05a0f83b68c59eaf104ccf34328
parent 12734139a3490cb1c630dbfdeb5172b31dfb510e
Author: Michael Forney <mforney@mforney.org>
Date:   Tue, 26 Nov 2019 19:36:52 -0800

libfido2: Add patches to remove use of packed structs and usleep

Diffstat:

Apkg/libfido2/patch/0002-u2f-Use-nanosleep-instead-of-obsolete-usleep.patch78++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Apkg/libfido2/patch/0003-io-avoid-use-of-packed-struct.patch255+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Apkg/libfido2/patch/0004-iso7816-avoid-use-of-packed-struct.patch141+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Apkg/libfido2/patch/0005-dev-avoid-use-of-packed-struct.patch72++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Apkg/libfido2/patch/0006-cbor-u2f-avoid-use-of-packed-struct.patch204+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Apkg/libfido2/patch/0007-remove-unused-packed.h.patch41+++++++++++++++++++++++++++++++++++++++++
Mpkg/libfido2/ver2+-
7 files changed, 792 insertions(+), 1 deletion(-)

diff --git a/pkg/libfido2/patch/0002-u2f-Use-nanosleep-instead-of-obsolete-usleep.patch b/pkg/libfido2/patch/0002-u2f-Use-nanosleep-instead-of-obsolete-usleep.patch @@ -0,0 +1,78 @@ +From 676714b7c421195115b87b51dfa24d3522703da3 Mon Sep 17 00:00:00 2001 +From: Michael Forney <mforney@mforney.org> +Date: Tue, 26 Nov 2019 13:06:58 -0800 +Subject: [PATCH] u2f: Use nanosleep instead of obsolete usleep + +usleep was declared obsolete in POSIX.1-2001 and removed in +POSIX.1-2008. +--- + src/u2f.c | 27 +++++++++++++++++---------- + 1 file changed, 17 insertions(+), 10 deletions(-) + +diff --git a/src/u2f.c b/src/u2f.c +index 3f2d9aa..22c6ac9 100644 +--- a/src/u2f.c ++++ b/src/u2f.c +@@ -15,15 +15,22 @@ + #include "fido.h" + #include "fido/es256.h" + +-#if defined(_MSC_VER) + static int +-usleep(unsigned int usec) ++sleep_msec(unsigned int msec) + { +- Sleep(usec / 1000); ++#if defined(_MSC_VER) ++ Sleep(msec); + + return (0); +-} ++#else ++ struct timespec ts = { ++ .tv_sec = msec / 1000, ++ .tv_nsec = (msec % 1000) * 1000000, ++ }; ++ ++ return nanosleep(&ts, NULL); + #endif ++} + + static int + sig_get(fido_blob_t *sig, const unsigned char **buf, size_t *len) +@@ -161,8 +168,8 @@ send_dummy_register(fido_dev_t *dev, int ms) + r = FIDO_ERR_RX; + goto fail; + } +- if (usleep((ms == -1 ? 100 : ms) * 1000) < 0) { +- fido_log_debug("%s: usleep", __func__); ++ if (sleep_msec(ms == -1 ? 100 : ms) < 0) { ++ fido_log_debug("%s: sleep_msec", __func__); + r = FIDO_ERR_RX; + goto fail; + } +@@ -338,8 +345,8 @@ do_auth(fido_dev_t *dev, const fido_blob_t *cdh, const char *rp_id, + r = FIDO_ERR_RX; + goto fail; + } +- if (usleep((ms == -1 ? 100 : ms) * 1000) < 0) { +- fido_log_debug("%s: usleep", __func__); ++ if (sleep_msec(ms == -1 ? 100 : ms) < 0) { ++ fido_log_debug("%s: sleep_msec", __func__); + r = FIDO_ERR_RX; + goto fail; + } +@@ -646,8 +653,8 @@ u2f_register(fido_dev_t *dev, fido_cred_t *cred, int ms) + r = FIDO_ERR_RX; + goto fail; + } +- if (usleep((ms == -1 ? 100 : ms) * 1000) < 0) { +- fido_log_debug("%s: usleep", __func__); ++ if (sleep_msec(ms == -1 ? 100 : ms) < 0) { ++ fido_log_debug("%s: sleep_msec", __func__); + r = FIDO_ERR_RX; + goto fail; + } +-- +2.24.0 + diff --git a/pkg/libfido2/patch/0003-io-avoid-use-of-packed-struct.patch b/pkg/libfido2/patch/0003-io-avoid-use-of-packed-struct.patch @@ -0,0 +1,255 @@ +From d72b3ec7c3a4afbc72c50379a65d5c4f2f7c5684 Mon Sep 17 00:00:00 2001 +From: Michael Forney <mforney@mforney.org> +Date: Tue, 26 Nov 2019 18:52:13 -0800 +Subject: [PATCH] io: avoid use of packed struct + +--- + src/io.c | 128 +++++++++++++++++++++++++++---------------------------- + 1 file changed, 62 insertions(+), 66 deletions(-) + +diff --git a/src/io.c b/src/io.c +index aa88720..caff99d 100644 +--- a/src/io.c ++++ b/src/io.c +@@ -9,25 +9,19 @@ + #include <string.h> + + #include "fido.h" +-#include "packed.h" +- +-PACKED_TYPE(frame_t, +-struct frame { +- uint32_t cid; /* channel id */ +- union { +- uint8_t type; +- struct { +- uint8_t cmd; +- uint8_t bcnth; +- uint8_t bcntl; +- uint8_t data[CTAP_RPT_SIZE - 7]; +- } init; +- struct { +- uint8_t seq; +- uint8_t data[CTAP_RPT_SIZE - 5]; +- } cont; +- } body; +-}) ++ ++/* CTAP section 8.1.4 */ ++enum { ++ CID, ++ ++ INIT_CMD = 4, ++ INIT_BCNTH, ++ INIT_BCNTL, ++ INIT_DATA, ++ ++ CONT_SEQ = 4, ++ CONT_DATA, ++}; + + #ifndef MIN + #define MIN(x, y) ((x) > (y) ? (y) : (x)) +@@ -36,22 +30,19 @@ struct frame { + static size_t + tx_preamble(fido_dev_t *d, uint8_t cmd, const void *buf, size_t count) + { +- struct frame *fp; +- unsigned char pkt[sizeof(*fp) + 1]; +- int n; ++ uint8_t pkt[1 + CTAP_RPT_SIZE] = {0}; ++ int n; + + if (d->io.write == NULL || (cmd & 0x80) == 0) + return (0); + +- memset(&pkt, 0, sizeof(pkt)); +- fp = (struct frame *)(pkt + 1); +- fp->cid = d->cid; +- fp->body.init.cmd = 0x80 | cmd; +- fp->body.init.bcnth = (count >> 8) & 0xff; +- fp->body.init.bcntl = count & 0xff; +- count = MIN(count, sizeof(fp->body.init.data)); ++ memcpy(&pkt[1], &d->cid, 4); ++ pkt[1 + INIT_CMD] = 0x80 | cmd; ++ pkt[1 + INIT_BCNTH] = (count >> 8) & 0xff; ++ pkt[1 + INIT_BCNTL] = count & 0xff; ++ count = MIN(count, CTAP_RPT_SIZE - INIT_DATA); + if (count) +- memcpy(&fp->body.init.data, buf, count); ++ memcpy(&pkt[1 + INIT_DATA], buf, count); + + n = d->io.write(d->io_handle, pkt, sizeof(pkt)); + if (n < 0 || (size_t)n != sizeof(pkt)) +@@ -63,19 +54,16 @@ tx_preamble(fido_dev_t *d, uint8_t cmd, const void *buf, size_t count) + static size_t + tx_frame(fido_dev_t *d, int seq, const void *buf, size_t count) + { +- struct frame *fp; +- unsigned char pkt[sizeof(*fp) + 1]; +- int n; ++ uint8_t pkt[1 + CTAP_RPT_SIZE] = {0}; ++ int n; + + if (d->io.write == NULL || seq < 0 || seq > UINT8_MAX) + return (0); + +- memset(&pkt, 0, sizeof(pkt)); +- fp = (struct frame *)(pkt + 1); +- fp->cid = d->cid; +- fp->body.cont.seq = (uint8_t)seq; +- count = MIN(count, sizeof(fp->body.cont.data)); +- memcpy(&fp->body.cont.data, buf, count); ++ memcpy(&pkt[1], &d->cid, 4); ++ pkt[1 + CONT_SEQ] = seq; ++ count = MIN(count, CTAP_RPT_SIZE - CONT_DATA); ++ memcpy(&pkt[1 + CONT_DATA], buf, count); + + n = d->io.write(d->io_handle, pkt, sizeof(pkt)); + if (n < 0 || (size_t)n != sizeof(pkt)) +@@ -123,31 +111,34 @@ fido_tx(fido_dev_t *d, uint8_t cmd, const void *buf, size_t count) + } + + static int +-rx_frame(fido_dev_t *d, struct frame *fp, int ms) ++rx_frame(fido_dev_t *d, uint8_t *fp, int ms) + { + int n; + + if (d->io.read == NULL) + return (-1); + +- n = d->io.read(d->io_handle, (unsigned char *)fp, sizeof(*fp), ms); +- if (n < 0 || (size_t)n != sizeof(*fp)) ++ n = d->io.read(d->io_handle, (unsigned char *)fp, CTAP_RPT_SIZE, ms); ++ if (n < 0 || (size_t)n != CTAP_RPT_SIZE) + return (-1); + + return (0); + } + + static int +-rx_preamble(fido_dev_t *d, struct frame *fp, int ms) ++rx_preamble(fido_dev_t *d, uint8_t *fp, int ms) + { ++ uint32_t cid; ++ + do { + if (rx_frame(d, fp, ms) < 0) + return (-1); ++ memcpy(&cid, &fp[CID], 4); + #ifdef FIDO_FUZZ +- fp->cid = d->cid; ++ cid = d->cid; + #endif +- } while (fp->cid == d->cid && +- fp->body.init.cmd == (CTAP_FRAME_INIT | CTAP_KEEPALIVE)); ++ } while (cid == d->cid && ++ fp[INIT_CMD] == (CTAP_FRAME_INIT | CTAP_KEEPALIVE)); + + return (0); + } +@@ -155,7 +146,8 @@ rx_preamble(fido_dev_t *d, struct frame *fp, int ms) + int + fido_rx(fido_dev_t *d, uint8_t cmd, void *buf, size_t count, int ms) + { +- struct frame f; ++ uint8_t f[CTAP_RPT_SIZE]; ++ uint32_t cid; + uint16_t r; + uint16_t flen; + int seq; +@@ -166,7 +158,7 @@ fido_rx(fido_dev_t *d, uint8_t cmd, void *buf, size_t count, int ms) + return (-1); + } + +- if (rx_preamble(d, &f, ms) < 0) { ++ if (rx_preamble(d, f, ms) < 0) { + fido_log_debug("%s: rx_preamble", __func__); + return (-1); + } +@@ -175,34 +167,36 @@ fido_rx(fido_dev_t *d, uint8_t cmd, void *buf, size_t count, int ms) + (void *)&f, sizeof(f)); + fido_log_xxd(&f, sizeof(f)); + ++ memcpy(&cid, &f[CID], 4); ++ + #ifdef FIDO_FUZZ +- f.cid = d->cid; +- f.body.init.cmd = cmd; ++ cid = d->cid; ++ f[INIT_CMD] = cmd; + #endif + +- if (f.cid != d->cid || f.body.init.cmd != cmd) { ++ if (cid != d->cid || f[INIT_CMD] != cmd) { + fido_log_debug("%s: cid (0x%x, 0x%x), cmd (0x%02x, 0x%02x)", +- __func__, f.cid, d->cid, f.body.init.cmd, cmd); ++ __func__, cid, d->cid, f[INIT_CMD], cmd); + return (-1); + } + +- flen = (f.body.init.bcnth << 8) | f.body.init.bcntl; ++ flen = (f[INIT_BCNTH] << 8) | f[INIT_BCNTL]; + if (count < (size_t)flen) { + fido_log_debug("%s: count < flen (%zu, %zu)", __func__, count, + (size_t)flen); + return (-1); + } +- if (flen < sizeof(f.body.init.data)) { +- memcpy(buf, f.body.init.data, flen); ++ if (flen < CTAP_RPT_SIZE - INIT_DATA) { ++ memcpy(buf, &f[INIT_DATA], flen); + return (flen); + } + +- memcpy(buf, f.body.init.data, sizeof(f.body.init.data)); +- r = sizeof(f.body.init.data); ++ memcpy(buf, &f[INIT_DATA], CTAP_RPT_SIZE - INIT_DATA); ++ r = CTAP_RPT_SIZE - INIT_DATA; + seq = 0; + + while ((size_t)r < flen) { +- if (rx_frame(d, &f, ms) < 0) { ++ if (rx_frame(d, f, ms) < 0) { + fido_log_debug("%s: rx_frame", __func__); + return (-1); + } +@@ -211,24 +205,26 @@ fido_rx(fido_dev_t *d, uint8_t cmd, void *buf, size_t count, int ms) + __func__, (void *)&f, sizeof(f)); + fido_log_xxd(&f, sizeof(f)); + ++ memcpy(&cid, &f[CID], 4); ++ + #ifdef FIDO_FUZZ +- f.cid = d->cid; +- f.body.cont.seq = seq; ++ cid = d->cid; ++ f[CONT_SEQ] = seq; + #endif + +- if (f.cid != d->cid || f.body.cont.seq != seq++) { ++ if (cid != d->cid || f[CONT_SEQ] != seq++) { + fido_log_debug("%s: cid (0x%x, 0x%x), seq (%d, %d)", +- __func__, f.cid, d->cid, f.body.cont.seq, seq); ++ __func__, cid, d->cid, f[CONT_SEQ], seq); + return (-1); + } + + uint8_t *p = (uint8_t *)buf + r; + +- if ((size_t)(flen - r) > sizeof(f.body.cont.data)) { +- memcpy(p, f.body.cont.data, sizeof(f.body.cont.data)); +- r += sizeof(f.body.cont.data); ++ if ((size_t)(flen - r) > CTAP_RPT_SIZE - CONT_DATA) { ++ memcpy(p, &f[CONT_DATA], CTAP_RPT_SIZE - CONT_DATA); ++ r += CTAP_RPT_SIZE - CONT_DATA; + } else { +- memcpy(p, f.body.cont.data, flen - r); ++ memcpy(p, &f[CONT_DATA], flen - r); + r += (flen - r); /* break */ + } + } +-- +2.24.0 + diff --git a/pkg/libfido2/patch/0004-iso7816-avoid-use-of-packed-struct.patch b/pkg/libfido2/patch/0004-iso7816-avoid-use-of-packed-struct.patch @@ -0,0 +1,141 @@ +From b688eb258efa9c07c1deb807ed441bd04cb4e30a Mon Sep 17 00:00:00 2001 +From: Michael Forney <mforney@mforney.org> +Date: Tue, 26 Nov 2019 18:58:05 -0800 +Subject: [PATCH] iso7816: avoid use of packed struct + +--- + src/iso7816.c | 50 ++++++++++++++++++++++++++++++++------------------ + src/iso7816.h | 22 +--------------------- + 2 files changed, 33 insertions(+), 39 deletions(-) + +diff --git a/src/iso7816.c b/src/iso7816.c +index e2ea281..3453df0 100644 +--- a/src/iso7816.c ++++ b/src/iso7816.c +@@ -7,24 +7,40 @@ + #include <string.h> + #include "fido.h" + ++struct iso7816_apdu { ++ size_t max_len; ++ size_t len; ++ uint8_t buf[]; ++}; ++ ++enum { ++ CLA, ++ INS, ++ P1, ++ P2, ++ LC1, ++ LC2, ++ LC3, ++ DATA, ++}; ++ + iso7816_apdu_t * + iso7816_new(uint8_t ins, uint8_t p1, uint16_t payload_len) + { + iso7816_apdu_t *apdu; +- size_t alloc_len; ++ size_t max_len; + +- alloc_len = sizeof(iso7816_apdu_t) + payload_len; ++ max_len = DATA + payload_len; + +- if ((apdu = calloc(1, alloc_len)) == NULL) ++ if ((apdu = calloc(1, sizeof(*apdu) + max_len)) == NULL) + return (NULL); + +- apdu->alloc_len = alloc_len; +- apdu->payload_len = payload_len; +- apdu->payload_ptr = apdu->payload; +- apdu->header.ins = ins; +- apdu->header.p1 = p1; +- apdu->header.lc2 = (payload_len >> 8) & 0xff; +- apdu->header.lc3 = payload_len & 0xff; ++ apdu->max_len = max_len; ++ apdu->buf[INS] = ins; ++ apdu->buf[P1] = p1; ++ apdu->buf[LC2] = (payload_len >> 8) & 0xff; ++ apdu->buf[LC3] = payload_len & 0xff; ++ apdu->len = DATA; + + return (apdu); + } +@@ -37,7 +53,7 @@ iso7816_free(iso7816_apdu_t **apdu_p) + if (apdu_p == NULL || (apdu = *apdu_p) == NULL) + return; + +- explicit_bzero(apdu, apdu->alloc_len); ++ explicit_bzero(apdu, sizeof(*apdu) + apdu->max_len); + free(apdu); + + *apdu_p = NULL; +@@ -46,12 +62,11 @@ iso7816_free(iso7816_apdu_t **apdu_p) + int + iso7816_add(iso7816_apdu_t *apdu, const void *buf, size_t cnt) + { +- if (cnt > apdu->payload_len || cnt > UINT16_MAX) ++ if (cnt > apdu->max_len - apdu->len) + return (-1); + +- memcpy(apdu->payload_ptr, buf, cnt); +- apdu->payload_ptr += cnt; +- apdu->payload_len -= (uint16_t)cnt; ++ memcpy(apdu->buf + apdu->len, buf, cnt); ++ apdu->len += cnt; + + return (0); + } +@@ -59,12 +74,11 @@ iso7816_add(iso7816_apdu_t *apdu, const void *buf, size_t cnt) + const unsigned char * + iso7816_ptr(const iso7816_apdu_t *apdu) + { +- return ((const unsigned char *)&apdu->header); ++ return ((const unsigned char *)&apdu->buf); + } + + size_t + iso7816_len(const iso7816_apdu_t *apdu) + { +- return (apdu->alloc_len - sizeof(apdu->alloc_len) - +- sizeof(apdu->payload_len) - sizeof(apdu->payload_ptr)); ++ return (apdu->len); + } +diff --git a/src/iso7816.h b/src/iso7816.h +index 426cd97..fecfecc 100644 +--- a/src/iso7816.h ++++ b/src/iso7816.h +@@ -7,27 +7,7 @@ + #ifndef _ISO7816_H + #define _ISO7816_H + +-#include "packed.h" +- +-PACKED_TYPE(iso7816_header_t, +-struct iso7816_header { +- uint8_t cla; +- uint8_t ins; +- uint8_t p1; +- uint8_t p2; +- uint8_t lc1; +- uint8_t lc2; +- uint8_t lc3; +-}) +- +-PACKED_TYPE(iso7816_apdu_t, +-struct iso7816_apdu { +- size_t alloc_len; +- uint16_t payload_len; +- uint8_t *payload_ptr; +- iso7816_header_t header; +- uint8_t payload[]; +-}) ++typedef struct iso7816_apdu iso7816_apdu_t; + + const unsigned char *iso7816_ptr(const iso7816_apdu_t *); + int iso7816_add(iso7816_apdu_t *, const void *, size_t); +-- +2.24.0 + diff --git a/pkg/libfido2/patch/0005-dev-avoid-use-of-packed-struct.patch b/pkg/libfido2/patch/0005-dev-avoid-use-of-packed-struct.patch @@ -0,0 +1,72 @@ +From 38ddc101ebcf864112f646026e149a6b0cc7f44a Mon Sep 17 00:00:00 2001 +From: Michael Forney <mforney@mforney.org> +Date: Tue, 26 Nov 2019 19:02:46 -0800 +Subject: [PATCH] dev: avoid use of packed struct + +--- + src/dev.c | 13 +++++++++++-- + src/types.h | 5 ++--- + 2 files changed, 13 insertions(+), 5 deletions(-) + +diff --git a/src/dev.c b/src/dev.c +index d0efac7..d24f707 100644 +--- a/src/dev.c ++++ b/src/dev.c +@@ -102,19 +102,28 @@ fido_dev_open_tx(fido_dev_t *dev, const char *path) + static int + fido_dev_open_rx(fido_dev_t *dev, int ms) + { ++ uint8_t data[17]; + const uint8_t cmd = CTAP_FRAME_INIT | CTAP_CMD_INIT; + int n; + +- if ((n = fido_rx(dev, cmd, &dev->attr, sizeof(dev->attr), ms)) < 0) { ++ if ((n = fido_rx(dev, cmd, data, sizeof(data), ms)) < 0) { + fido_log_debug("%s: fido_rx", __func__); + goto fail; + } + ++ memcpy(&dev->attr.nonce, &data[0], 8); ++ memcpy(&dev->attr.cid, &data[8], 4); ++ dev->attr.protocol = data[12]; ++ dev->attr.major = data[13]; ++ dev->attr.minor = data[14]; ++ dev->attr.build = data[15]; ++ dev->attr.flags = data[16]; ++ + #ifdef FIDO_FUZZ + dev->attr.nonce = dev->nonce; + #endif + +- if ((size_t)n != sizeof(dev->attr) || dev->attr.nonce != dev->nonce) { ++ if ((size_t)n != sizeof(data) || dev->attr.nonce != dev->nonce) { + fido_log_debug("%s: invalid nonce", __func__); + goto fail; + } +diff --git a/src/types.h b/src/types.h +index 42ed1b7..af72710 100644 +--- a/src/types.h ++++ b/src/types.h +@@ -148,9 +148,8 @@ typedef struct fido_dev_info { + char *product; /* product string */ + } fido_dev_info_t; + +-PACKED_TYPE(fido_ctap_info_t, + /* defined in section 8.1.9.1.3 (CTAPHID_INIT) of the fido2 ctap spec */ +-struct fido_ctap_info { ++typedef struct fido_ctap_info { + uint64_t nonce; /* echoed nonce */ + uint32_t cid; /* channel id */ + uint8_t protocol; /* ctaphid protocol id */ +@@ -158,7 +157,7 @@ struct fido_ctap_info { + uint8_t minor; /* minor version number */ + uint8_t build; /* build version number */ + uint8_t flags; /* capabilities flags; see FIDO_CAP_* */ +-}) ++} fido_ctap_info_t; + + typedef struct fido_dev { + uint64_t nonce; /* issued nonce */ +-- +2.24.0 + diff --git a/pkg/libfido2/patch/0006-cbor-u2f-avoid-use-of-packed-struct.patch b/pkg/libfido2/patch/0006-cbor-u2f-avoid-use-of-packed-struct.patch @@ -0,0 +1,204 @@ +From d95bfdbcaadd92fbe04df8b3134be1886377e7a2 Mon Sep 17 00:00:00 2001 +From: Michael Forney <mforney@mforney.org> +Date: Tue, 26 Nov 2019 19:30:10 -0800 +Subject: [PATCH] cbor, u2f: avoid use of packed struct + +This also fixes a bug on big-endian systems where the credential +ID length is placed in the wrong byte. +--- + src/cbor.c | 14 +++++++++-- + src/types.h | 14 ++--------- + src/u2f.c | 70 ++++++++++++++++++++++++++++++++++++----------------- + 3 files changed, 62 insertions(+), 36 deletions(-) + +diff --git a/src/cbor.c b/src/cbor.c +index 3e03592..e60e5e3 100644 +--- a/src/cbor.c ++++ b/src/cbor.c +@@ -1228,7 +1228,12 @@ cbor_decode_cred_authdata(const cbor_item_t *item, int cose_alg, + + fido_log_debug("%s: buf=%p, len=%zu", __func__, (const void *)buf, len); + +- if (fido_buf_read(&buf, &len, authdata, sizeof(*authdata)) < 0) { ++ if (fido_buf_read(&buf, &len, authdata->rp_id_hash, ++ sizeof(authdata->rp_id_hash)) < 0 || ++ fido_buf_read(&buf, &len, &authdata->flags, ++ sizeof(authdata->flags)) < 0 || ++ fido_buf_read(&buf, &len, &authdata->sigcount, ++ sizeof(authdata->sigcount)) < 0) { + fido_log_debug("%s: fido_buf_read", __func__); + return (-1); + } +@@ -1278,7 +1283,12 @@ cbor_decode_assert_authdata(const cbor_item_t *item, fido_blob_t *authdata_cbor, + + fido_log_debug("%s: buf=%p, len=%zu", __func__, (const void *)buf, len); + +- if (fido_buf_read(&buf, &len, authdata, sizeof(*authdata)) < 0) { ++ if (fido_buf_read(&buf, &len, authdata->rp_id_hash, ++ sizeof(authdata->rp_id_hash)) < 0 || ++ fido_buf_read(&buf, &len, &authdata->flags, ++ sizeof(authdata->flags)) < 0 || ++ fido_buf_read(&buf, &len, &authdata->sigcount, ++ sizeof(authdata->sigcount)) < 0) { + fido_log_debug("%s: fido_buf_read", __func__); + return (-1); + } +diff --git a/src/types.h b/src/types.h +index af72710..af1874a 100644 +--- a/src/types.h ++++ b/src/types.h +@@ -7,8 +7,6 @@ + #ifndef _TYPES_H + #define _TYPES_H + +-#include "packed.h" +- + /* COSE ES256 (ECDSA over P-256 with SHA-256) public key */ + typedef struct es256_pk { + unsigned char x[32]; +@@ -31,20 +29,12 @@ typedef struct eddsa_pk { + unsigned char x[32]; + } eddsa_pk_t; + +-PACKED_TYPE(fido_authdata_t, +-struct fido_authdata { ++typedef struct fido_authdata { + unsigned char rp_id_hash[32]; /* sha256 of fido_rp.id */ + uint8_t flags; /* user present/verified */ + uint32_t sigcount; /* signature counter */ + /* actually longer */ +-}) +- +-PACKED_TYPE(fido_attcred_raw_t, +-struct fido_attcred_raw { +- unsigned char aaguid[16]; /* credential's aaguid */ +- uint16_t id_len; /* credential id length */ +- uint8_t body[]; /* credential id + pubkey */ +-}) ++} fido_authdata_t; + + typedef struct fido_attcred { + unsigned char aaguid[16]; /* credential's aaguid */ +diff --git a/src/u2f.c b/src/u2f.c +index 22c6ac9..6db32c5 100644 +--- a/src/u2f.c ++++ b/src/u2f.c +@@ -15,6 +15,29 @@ + #include "fido.h" + #include "fido/es256.h" + ++/* ++ * Web Authentication section 6.1 ++ * https://www.w3.org/TR/webauthn/#authenticator-data ++ */ ++enum { ++ AUTHDATA_RP_ID_HASH = 0, ++ AUTHDATA_FLAGS = 32, ++ AUTHDATA_SIGN_COUNT = 33, ++ ++ AUTHDATA_BASE_SIZE = 37 ++}; ++ ++/* ++ * Web Authentication section 6.4.1 ++ * https://www.w3.org/TR/webauthn/#sec-attested-credential-data ++ */ ++enum { ++ ATTCRED_AAGUID = 0, ++ ATTCRED_CREDENTIAL_ID_LENGTH = 16, ++ ++ ATTCRED_BASE_SIZE = 18 ++}; ++ + static int + sleep_msec(unsigned int msec) + { +@@ -95,23 +118,24 @@ static int + authdata_fake(const char *rp_id, uint8_t flags, uint32_t sigcount, + fido_blob_t *fake_cbor_ad) + { +- fido_authdata_t ad; ++ uint8_t authdata[AUTHDATA_BASE_SIZE] = {0}; ++ unsigned char *rp_id_hash; + cbor_item_t *item = NULL; + size_t alloc_len; + +- memset(&ad, 0, sizeof(ad)); ++ rp_id_hash = (unsigned char *)&authdata[AUTHDATA_RP_ID_HASH]; + + if (SHA256((const void *)rp_id, strlen(rp_id), +- ad.rp_id_hash) != ad.rp_id_hash) { ++ rp_id_hash) != rp_id_hash) { + fido_log_debug("%s: sha256", __func__); + return (-1); + } + +- ad.flags = flags; /* XXX translate? */ +- ad.sigcount = sigcount; ++ authdata[AUTHDATA_FLAGS] = flags; /* XXX translate? */ ++ memcpy(&authdata[AUTHDATA_SIGN_COUNT], &sigcount, 4); + +- if ((item = cbor_build_bytestring((const unsigned char *)&ad, +- sizeof(ad))) == NULL) { ++ if ((item = cbor_build_bytestring((cbor_data)authdata, ++ sizeof(authdata))) == NULL) { + fido_log_debug("%s: cbor_build_bytestring", __func__); + return (-1); + } +@@ -411,18 +435,18 @@ static int + encode_cred_authdata(const char *rp_id, const uint8_t *kh, uint8_t kh_len, + const uint8_t *pubkey, size_t pubkey_len, fido_blob_t *out) + { +- fido_authdata_t authdata; +- fido_attcred_raw_t attcred_raw; +- fido_blob_t pk_blob; +- fido_blob_t authdata_blob; +- cbor_item_t *authdata_cbor = NULL; +- unsigned char *ptr; +- size_t len; +- size_t alloc_len; +- int ok = -1; ++ uint8_t authdata[AUTHDATA_BASE_SIZE] = {0}; ++ unsigned char *rp_id_hash; ++ uint8_t attcred_raw[ATTCRED_BASE_SIZE] = {0}; ++ fido_blob_t pk_blob; ++ fido_blob_t authdata_blob; ++ cbor_item_t *authdata_cbor = NULL; ++ unsigned char *ptr; ++ size_t len; ++ size_t alloc_len; ++ int ok = -1; + + memset(&pk_blob, 0, sizeof(pk_blob)); +- memset(&authdata, 0, sizeof(authdata)); + memset(&authdata_blob, 0, sizeof(authdata_blob)); + memset(out, 0, sizeof(*out)); + +@@ -436,17 +460,19 @@ encode_cred_authdata(const char *rp_id, const uint8_t *kh, uint8_t kh_len, + goto fail; + } + ++ rp_id_hash = (unsigned char *)&authdata[AUTHDATA_RP_ID_HASH]; ++ + if (SHA256((const void *)rp_id, strlen(rp_id), +- authdata.rp_id_hash) != authdata.rp_id_hash) { ++ rp_id_hash) != rp_id_hash) { + fido_log_debug("%s: sha256", __func__); + goto fail; + } + +- authdata.flags = (CTAP_AUTHDATA_ATT_CRED | CTAP_AUTHDATA_USER_PRESENT); +- authdata.sigcount = 0; ++ authdata[AUTHDATA_FLAGS] = (CTAP_AUTHDATA_ATT_CRED | ++ CTAP_AUTHDATA_USER_PRESENT); + +- memset(&attcred_raw.aaguid, 0, sizeof(attcred_raw.aaguid)); +- attcred_raw.id_len = (uint16_t)(kh_len << 8); /* XXX */ ++ /* big-endian, so second byte is LSB */ ++ attcred_raw[ATTCRED_CREDENTIAL_ID_LENGTH + 1] = kh_len; + + len = authdata_blob.len = sizeof(authdata) + sizeof(attcred_raw) + + kh_len + pk_blob.len; +-- +2.24.0 + diff --git a/pkg/libfido2/patch/0007-remove-unused-packed.h.patch b/pkg/libfido2/patch/0007-remove-unused-packed.h.patch @@ -0,0 +1,41 @@ +From 5240c76168f9de8683673892e61dea548eda584e Mon Sep 17 00:00:00 2001 +From: Michael Forney <mforney@mforney.org> +Date: Tue, 26 Nov 2019 19:30:28 -0800 +Subject: [PATCH] remove unused packed.h + +--- + src/packed.h | 22 ---------------------- + 1 file changed, 22 deletions(-) + delete mode 100644 src/packed.h + +diff --git a/src/packed.h b/src/packed.h +deleted file mode 100644 +index 3857c22..0000000 +--- a/src/packed.h ++++ /dev/null +@@ -1,22 +0,0 @@ +-/* +- * Copyright (c) 2018 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. +- */ +- +-#ifndef _PACKED_H +-#define _PACKED_H +- +-#if defined(__GNUC__) +-#define PACKED_TYPE(type, def) \ +- typedef def __attribute__ ((__packed__)) type; +-#elif defined(_MSC_VER) +-#define PACKED_TYPE(type, def) \ +- __pragma(pack(push, 1)) \ +- typedef def type; \ +- __pragma(pack(pop)) +-#else +-#error "please provide a way to define packed types on your platform" +-#endif +- +-#endif /* !_PACKED_H */ +-- +2.24.0 + diff --git a/pkg/libfido2/ver b/pkg/libfido2/ver @@ -1 +1 @@ -1.2.0-95-gad22526 r0 +1.2.0-95-gad22526 r1