1 /* 2 * Copyright (c) 2020 Yubico AB. All rights reserved. 3 * Use of this source code is governed by a BSD-style 4 * license that can be found in the LICENSE file. 5 */ 6 7 #include <sys/types.h> 8 #include <sys/uio.h> 9 #include <sys/socket.h> 10 11 #include <linux/nfc.h> 12 13 #include <errno.h> 14 #include <libudev.h> 15 #include <signal.h> 16 #include <stdio.h> 17 #include <string.h> 18 #include <unistd.h> 19 20 #include "fido.h" 21 #include "fido/param.h" 22 #include "netlink.h" 23 #include "iso7816.h" 24 25 #define TX_CHUNK_SIZE 240 26 27 static const uint8_t aid[] = { 0xa0, 0x00, 0x00, 0x06, 0x47, 0x2f, 0x00, 0x01 }; 28 static const uint8_t v_u2f[] = { 'U', '2', 'F', '_', 'V', '2' }; 29 static const uint8_t v_fido[] = { 'F', 'I', 'D', 'O', '_', '2', '_', '0' }; 30 31 struct nfc_linux { 32 int fd; 33 uint32_t dev; 34 uint32_t target; 35 sigset_t sigmask; 36 const sigset_t *sigmaskp; 37 struct fido_nl *nl; 38 }; 39 40 static int 41 tx_short_apdu(fido_dev_t *d, const iso7816_header_t *h, const uint8_t *payload, 42 uint8_t payload_len, uint8_t cla_flags) 43 { 44 uint8_t apdu[5 + UINT8_MAX + 1]; 45 uint8_t sw[2]; 46 size_t apdu_len; 47 int ok = -1; 48 49 memset(&apdu, 0, sizeof(apdu)); 50 apdu[0] = h->cla | cla_flags; 51 apdu[1] = h->ins; 52 apdu[2] = h->p1; 53 apdu[3] = h->p2; 54 apdu[4] = payload_len; 55 memcpy(&apdu[5], payload, payload_len); 56 apdu_len = (size_t)(5 + payload_len + 1); 57 58 if (d->io.write(d->io_handle, apdu, apdu_len) < 0) { 59 fido_log_debug("%s: write", __func__); 60 goto fail; 61 } 62 63 if (cla_flags & 0x10) { 64 if (d->io.read(d->io_handle, sw, sizeof(sw), -1) != 2) { 65 fido_log_debug("%s: read", __func__); 66 goto fail; 67 } 68 if ((sw[0] << 8 | sw[1]) != SW_NO_ERROR) { 69 fido_log_debug("%s: unexpected sw", __func__); 70 goto fail; 71 } 72 } 73 74 ok = 0; 75 fail: 76 explicit_bzero(apdu, sizeof(apdu)); 77 78 return (ok); 79 } 80 81 static int 82 nfc_do_tx(fido_dev_t *d, const uint8_t *apdu_ptr, size_t apdu_len) 83 { 84 iso7816_header_t h; 85 86 if (fido_buf_read(&apdu_ptr, &apdu_len, &h, sizeof(h)) < 0) { 87 fido_log_debug("%s: header", __func__); 88 return (-1); 89 } 90 if (apdu_len < 2) { 91 fido_log_debug("%s: apdu_len %zu", __func__, apdu_len); 92 return (-1); 93 } 94 95 apdu_len -= 2; /* trim le1 le2 */ 96 97 while (apdu_len > TX_CHUNK_SIZE) { 98 if (tx_short_apdu(d, &h, apdu_ptr, TX_CHUNK_SIZE, 0x10) < 0) { 99 fido_log_debug("%s: chain", __func__); 100 return (-1); 101 } 102 apdu_ptr += TX_CHUNK_SIZE; 103 apdu_len -= TX_CHUNK_SIZE; 104 } 105 106 if (tx_short_apdu(d, &h, apdu_ptr, (uint8_t)apdu_len, 0) < 0) { 107 fido_log_debug("%s: tx_short_apdu", __func__); 108 return (-1); 109 } 110 111 return (0); 112 } 113 114 int 115 fido_nfc_tx(fido_dev_t *d, uint8_t cmd, const unsigned char *buf, size_t count) 116 { 117 iso7816_apdu_t *apdu = NULL; 118 const uint8_t *ptr; 119 size_t len; 120 int ok = -1; 121 122 switch (cmd) { 123 case CTAP_CMD_INIT: /* select */ 124 if ((apdu = iso7816_new(0, 0xa4, 0x04, sizeof(aid))) == NULL || 125 iso7816_add(apdu, aid, sizeof(aid)) < 0) { 126 fido_log_debug("%s: iso7816", __func__); 127 goto fail; 128 } 129 break; 130 case CTAP_CMD_CBOR: /* wrap cbor */ 131 if (count > UINT16_MAX || (apdu = iso7816_new(0x80, 0x10, 0x80, 132 (uint16_t)count)) == NULL || 133 iso7816_add(apdu, buf, count) < 0) { 134 fido_log_debug("%s: iso7816", __func__); 135 goto fail; 136 } 137 break; 138 case CTAP_CMD_MSG: /* already an apdu */ 139 break; 140 default: 141 fido_log_debug("%s: cmd=%02x", __func__, cmd); 142 goto fail; 143 } 144 145 if (apdu != NULL) { 146 ptr = iso7816_ptr(apdu); 147 len = iso7816_len(apdu); 148 } else { 149 ptr = buf; 150 len = count; 151 } 152 153 if (nfc_do_tx(d, ptr, len) < 0) { 154 fido_log_debug("%s: nfc_do_tx", __func__); 155 goto fail; 156 } 157 158 ok = 0; 159 fail: 160 iso7816_free(&apdu); 161 162 return (ok); 163 } 164 165 static int 166 rx_init(fido_dev_t *d, unsigned char *buf, size_t count, int ms) 167 { 168 fido_ctap_info_t *attr = (fido_ctap_info_t *)buf; 169 uint8_t f[64]; 170 int n; 171 172 if (count != sizeof(*attr)) { 173 fido_log_debug("%s: count=%zu", __func__, count); 174 return (-1); 175 } 176 177 memset(attr, 0, sizeof(*attr)); 178 179 if ((n = d->io.read(d->io_handle, f, sizeof(f), ms)) < 2 || 180 (f[n - 2] << 8 | f[n - 1]) != SW_NO_ERROR) { 181 fido_log_debug("%s: read", __func__); 182 return (-1); 183 } 184 185 n -= 2; 186 187 if (n == sizeof(v_u2f) && memcmp(f, v_u2f, sizeof(v_u2f)) == 0) 188 attr->flags = FIDO_CAP_CBOR; 189 else if (n == sizeof(v_fido) && memcmp(f, v_fido, sizeof(v_fido)) == 0) 190 attr->flags = FIDO_CAP_CBOR | FIDO_CAP_NMSG; 191 else { 192 fido_log_debug("%s: unknown version string", __func__); 193 #ifdef FIDO_FUZZ 194 attr->flags = FIDO_CAP_CBOR | FIDO_CAP_NMSG; 195 #else 196 return (-1); 197 #endif 198 } 199 200 memcpy(&attr->nonce, &d->nonce, sizeof(attr->nonce)); /* XXX */ 201 202 return ((int)count); 203 } 204 205 static int 206 tx_get_response(fido_dev_t *d, uint8_t count) 207 { 208 uint8_t apdu[5]; 209 210 memset(apdu, 0, sizeof(apdu)); 211 apdu[1] = 0xc0; /* GET_RESPONSE */ 212 apdu[4] = count; 213 214 if (d->io.write(d->io_handle, apdu, sizeof(apdu)) < 0) { 215 fido_log_debug("%s: write", __func__); 216 return (-1); 217 } 218 219 return (0); 220 } 221 222 static int 223 rx_apdu(fido_dev_t *d, uint8_t sw[2], unsigned char **buf, size_t *count, int *ms) 224 { 225 uint8_t f[256 + 2]; 226 struct timespec ts; 227 int n, ok = -1; 228 229 if (fido_time_now(&ts) != 0) 230 goto fail; 231 232 if ((n = d->io.read(d->io_handle, f, sizeof(f), *ms)) < 2) { 233 fido_log_debug("%s: read", __func__); 234 goto fail; 235 } 236 237 if (fido_time_delta(&ts, ms) != 0) 238 goto fail; 239 240 if (fido_buf_write(buf, count, f, (size_t)(n - 2)) < 0) { 241 fido_log_debug("%s: fido_buf_write", __func__); 242 goto fail; 243 } 244 245 memcpy(sw, f + n - 2, 2); 246 247 ok = 0; 248 fail: 249 explicit_bzero(f, sizeof(f)); 250 251 return (ok); 252 } 253 254 static int 255 rx_msg(fido_dev_t *d, unsigned char *buf, size_t count, int ms) 256 { 257 uint8_t sw[2]; 258 const size_t bufsiz = count; 259 260 if (rx_apdu(d, sw, &buf, &count, &ms) < 0) { 261 fido_log_debug("%s: preamble", __func__); 262 return (-1); 263 } 264 265 while (sw[0] == SW1_MORE_DATA) 266 if (tx_get_response(d, sw[1]) < 0 || 267 rx_apdu(d, sw, &buf, &count, &ms) < 0) { 268 fido_log_debug("%s: chain", __func__); 269 return (-1); 270 } 271 272 if (fido_buf_write(&buf, &count, sw, sizeof(sw)) < 0) { 273 fido_log_debug("%s: sw", __func__); 274 return (-1); 275 } 276 277 if (bufsiz - count > INT_MAX) { 278 fido_log_debug("%s: bufsiz", __func__); 279 return (-1); 280 } 281 282 return ((int)(bufsiz - count)); 283 } 284 285 static int 286 rx_cbor(fido_dev_t *d, unsigned char *buf, size_t count, int ms) 287 { 288 int r; 289 290 if ((r = rx_msg(d, buf, count, ms)) < 2) 291 return (-1); 292 293 return (r - 2); 294 } 295 296 int 297 fido_nfc_rx(fido_dev_t *d, uint8_t cmd, unsigned char *buf, size_t count, int ms) 298 { 299 switch (cmd) { 300 case CTAP_CMD_INIT: 301 return (rx_init(d, buf, count, ms)); 302 case CTAP_CMD_CBOR: 303 return (rx_cbor(d, buf, count, ms)); 304 case CTAP_CMD_MSG: 305 return (rx_msg(d, buf, count, ms)); 306 default: 307 fido_log_debug("%s: cmd=%02x", __func__, cmd); 308 return (-1); 309 } 310 } 311 312 static char * 313 get_parent_attr(struct udev_device *dev, const char *subsystem, 314 const char *devtype, const char *attr) 315 { 316 struct udev_device *parent; 317 const char *value; 318 319 if ((parent = udev_device_get_parent_with_subsystem_devtype(dev, 320 subsystem, devtype)) == NULL || (value = 321 udev_device_get_sysattr_value(parent, attr)) == NULL) 322 return (NULL); 323 324 return (strdup(value)); 325 } 326 327 static char * 328 get_usb_attr(struct udev_device *dev, const char *attr) 329 { 330 return (get_parent_attr(dev, "usb", "usb_device", attr)); 331 } 332 333 static int 334 to_int(const char *str, int base) 335 { 336 char *ep; 337 long long ll; 338 339 ll = strtoll(str, &ep, base); 340 if (str == ep || *ep != '\0') 341 return (-1); 342 else if (ll == LLONG_MIN && errno == ERANGE) 343 return (-1); 344 else if (ll == LLONG_MAX && errno == ERANGE) 345 return (-1); 346 else if (ll < 0 || ll > INT_MAX) 347 return (-1); 348 349 return ((int)ll); 350 } 351 352 static int 353 copy_info(fido_dev_info_t *di, struct udev *udev, 354 struct udev_list_entry *udev_entry) 355 { 356 const char *name; 357 char *str; 358 struct udev_device *dev = NULL; 359 void *ctx = NULL; 360 int id, ok = -1; 361 362 memset(di, 0, sizeof(*di)); 363 364 if ((name = udev_list_entry_get_name(udev_entry)) == NULL || 365 (dev = udev_device_new_from_syspath(udev, name)) == NULL) 366 goto fail; 367 if (asprintf(&di->path, "%s/%s", FIDO_NFC_PREFIX, name) == -1) 368 goto fail; 369 if ((di->manufacturer = get_usb_attr(dev, "manufacturer")) == NULL) 370 di->manufacturer = strdup(""); 371 if ((di->product = get_usb_attr(dev, "product")) == NULL) 372 di->product = strdup(""); 373 if (di->manufacturer == NULL || di->product == NULL) 374 goto fail; 375 /* XXX assumes USB for vendor/product info */ 376 if ((str = get_usb_attr(dev, "idVendor")) != NULL && 377 (id = to_int(str, 16)) > 0 && id <= UINT16_MAX) 378 di->vendor_id = (int16_t)id; 379 free(str); 380 if ((str = get_usb_attr(dev, "idProduct")) != NULL && 381 (id = to_int(str, 16)) > 0 && id <= UINT16_MAX) 382 di->product_id = (int16_t)id; 383 free(str); 384 385 if ((ctx = fido_nfc_open(di->path)) == NULL) { 386 fido_log_debug("%s: fido_nfc_open", __func__); 387 goto fail; 388 } 389 390 ok = 0; 391 fail: 392 if (dev != NULL) 393 udev_device_unref(dev); 394 if (ctx != NULL) 395 fido_nfc_close(ctx); 396 397 if (ok < 0) { 398 free(di->path); 399 free(di->manufacturer); 400 free(di->product); 401 explicit_bzero(di, sizeof(*di)); 402 } 403 404 return (ok); 405 } 406 407 static int 408 sysnum_from_syspath(const char *path) 409 { 410 struct udev *udev = NULL; 411 struct udev_device *dev = NULL; 412 const char *str; 413 int idx; 414 415 if ((udev = udev_new()) == NULL || 416 (dev = udev_device_new_from_syspath(udev, path)) == NULL || 417 (str = udev_device_get_sysnum(dev)) == NULL) 418 idx = -1; 419 else 420 idx = to_int(str, 10); 421 422 if (dev != NULL) 423 udev_device_unref(dev); 424 if (udev != NULL) 425 udev_unref(udev); 426 427 return (idx); 428 } 429 430 int 431 fido_nfc_manifest(fido_dev_info_t *devlist, size_t ilen, size_t *olen) 432 { 433 struct udev *udev = NULL; 434 struct udev_enumerate *udev_enum = NULL; 435 struct udev_list_entry *udev_list; 436 struct udev_list_entry *udev_entry; 437 int r = FIDO_ERR_INTERNAL; 438 439 *olen = 0; 440 441 if (ilen == 0) 442 return (FIDO_OK); 443 444 if (devlist == NULL) 445 return (FIDO_ERR_INVALID_ARGUMENT); 446 447 if ((udev = udev_new()) == NULL || 448 (udev_enum = udev_enumerate_new(udev)) == NULL) 449 goto fail; 450 451 if (udev_enumerate_add_match_subsystem(udev_enum, "nfc") < 0 || 452 udev_enumerate_scan_devices(udev_enum) < 0) 453 goto fail; 454 455 if ((udev_list = udev_enumerate_get_list_entry(udev_enum)) == NULL) { 456 r = FIDO_OK; /* zero nfc devices */ 457 goto fail; 458 } 459 460 udev_list_entry_foreach(udev_entry, udev_list) { 461 if (copy_info(&devlist[*olen], udev, udev_entry) == 0) { 462 devlist[*olen].io = (fido_dev_io_t) { 463 fido_nfc_open, 464 fido_nfc_close, 465 fido_nfc_read, 466 fido_nfc_write, 467 }; 468 devlist[*olen].transport = (fido_dev_transport_t) { 469 fido_nfc_rx, 470 fido_nfc_tx, 471 }; 472 if (++(*olen) == ilen) 473 break; 474 } 475 } 476 477 r = FIDO_OK; 478 fail: 479 if (udev_enum != NULL) 480 udev_enumerate_unref(udev_enum); 481 if (udev != NULL) 482 udev_unref(udev); 483 484 return (r); 485 } 486 487 static int 488 nfc_target_connect(struct nfc_linux *ctx) 489 { 490 struct sockaddr_nfc sa; 491 492 memset(&sa, 0, sizeof(sa)); 493 sa.sa_family = AF_NFC; 494 sa.dev_idx = ctx->dev; 495 sa.target_idx = ctx->target; 496 sa.nfc_protocol = NFC_PROTO_ISO14443; 497 498 if ((ctx->fd = socket(AF_NFC, SOCK_SEQPACKET | SOCK_CLOEXEC, 499 NFC_SOCKPROTO_RAW)) == -1) { 500 fido_log_error(errno, "%s: socket", __func__); 501 return (-1); 502 } 503 if (connect(ctx->fd, (struct sockaddr *)&sa, sizeof(sa)) == -1) { 504 fido_log_error(errno, "%s: connect", __func__); 505 if (close(ctx->fd) == -1) 506 fido_log_error(errno, "%s: close", __func__); 507 ctx->fd = -1; 508 return (-1); 509 } 510 511 return (0); 512 } 513 514 static void 515 nfc_free(struct nfc_linux **ctx_p) 516 { 517 struct nfc_linux *ctx; 518 519 if (ctx_p == NULL || (ctx = *ctx_p) == NULL) 520 return; 521 if (ctx->fd != -1 && close(ctx->fd) == -1) 522 fido_log_error(errno, "%s: close", __func__); 523 if (ctx->nl != NULL) 524 fido_nl_free(&ctx->nl); 525 526 free(ctx); 527 *ctx_p = NULL; 528 } 529 530 static struct nfc_linux * 531 nfc_new(uint32_t dev) 532 { 533 struct nfc_linux *ctx; 534 535 if ((ctx = calloc(1, sizeof(*ctx))) == NULL || 536 (ctx->nl = fido_nl_new()) == NULL) { 537 nfc_free(&ctx); 538 return (NULL); 539 } 540 541 ctx->fd = -1; 542 ctx->dev = dev; 543 544 return (ctx); 545 } 546 547 void * 548 fido_nfc_open(const char *path) 549 { 550 struct nfc_linux *ctx = NULL; 551 int idx; 552 553 if (strncmp(path, FIDO_NFC_PREFIX, strlen(FIDO_NFC_PREFIX)) != 0) { 554 fido_log_debug("%s: bad prefix", __func__); 555 goto fail; 556 } 557 if ((idx = sysnum_from_syspath(path + strlen(FIDO_NFC_PREFIX))) < 0 || 558 (ctx = nfc_new((uint32_t)idx)) == NULL) { 559 fido_log_debug("%s: nfc_new", __func__); 560 goto fail; 561 } 562 if (fido_nl_power_nfc(ctx->nl, ctx->dev) < 0 || 563 fido_nl_get_nfc_target(ctx->nl, ctx->dev, &ctx->target) < 0 || 564 nfc_target_connect(ctx) < 0) { 565 fido_log_debug("%s: netlink", __func__); 566 goto fail; 567 } 568 569 return (ctx); 570 fail: 571 nfc_free(&ctx); 572 return (NULL); 573 } 574 575 void 576 fido_nfc_close(void *handle) 577 { 578 struct nfc_linux *ctx = handle; 579 580 nfc_free(&ctx); 581 } 582 583 int 584 fido_nfc_set_sigmask(void *handle, const fido_sigset_t *sigmask) 585 { 586 struct nfc_linux *ctx = handle; 587 588 ctx->sigmask = *sigmask; 589 ctx->sigmaskp = &ctx->sigmask; 590 591 return (FIDO_OK); 592 } 593 594 int 595 fido_nfc_read(void *handle, unsigned char *buf, size_t len, int ms) 596 { 597 struct nfc_linux *ctx = handle; 598 struct iovec iov[2]; 599 uint8_t preamble; 600 ssize_t r; 601 602 memset(&iov, 0, sizeof(iov)); 603 iov[0].iov_base = &preamble; 604 iov[0].iov_len = sizeof(preamble); 605 iov[1].iov_base = buf; 606 iov[1].iov_len = len; 607 608 if (fido_hid_unix_wait(ctx->fd, ms, ctx->sigmaskp) < 0) { 609 fido_log_debug("%s: fido_hid_unix_wait", __func__); 610 return (-1); 611 } 612 if ((r = readv(ctx->fd, iov, nitems(iov))) == -1) { 613 fido_log_error(errno, "%s: read", __func__); 614 return (-1); 615 } 616 if (r < 1) { 617 fido_log_debug("%s: %zd < 1", __func__, r); 618 return (-1); 619 } 620 if (preamble != 0x00) { 621 fido_log_debug("%s: preamble", __func__); 622 return (-1); 623 } 624 625 r--; 626 fido_log_xxd(buf, (size_t)r, "%s", __func__); 627 628 return ((int)r); 629 } 630 631 int 632 fido_nfc_write(void *handle, const unsigned char *buf, size_t len) 633 { 634 struct nfc_linux *ctx = handle; 635 ssize_t r; 636 637 fido_log_xxd(buf, len, "%s", __func__); 638 639 if (len > INT_MAX) { 640 fido_log_debug("%s: len", __func__); 641 return (-1); 642 } 643 if ((r = write(ctx->fd, buf, len)) == -1) { 644 fido_log_error(errno, "%s: write", __func__); 645 return (-1); 646 } 647 if (r < 0 || (size_t)r != len) { 648 fido_log_debug("%s: %zd != %zu", __func__, r, len); 649 return (-1); 650 } 651 652 return ((int)r); 653 } 654