1 /* $NetBSD: tpm.c,v 1.16 2019/10/09 14:03:58 maxv Exp $ */ 2 3 /* 4 * Copyright (c) 2019 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Maxime Villard. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 /* 33 * Copyright (c) 2008, 2009 Michael Shalayeff 34 * Copyright (c) 2009, 2010 Hans-Joerg Hoexer 35 * All rights reserved. 36 * 37 * Permission to use, copy, modify, and distribute this software for any 38 * purpose with or without fee is hereby granted, provided that the above 39 * copyright notice and this permission notice appear in all copies. 40 * 41 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 42 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 43 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 44 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 45 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN 46 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 47 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 48 */ 49 50 #include <sys/cdefs.h> 51 __KERNEL_RCSID(0, "$NetBSD: tpm.c,v 1.16 2019/10/09 14:03:58 maxv Exp $"); 52 53 #include <sys/param.h> 54 #include <sys/systm.h> 55 #include <sys/kernel.h> 56 #include <sys/malloc.h> 57 #include <sys/proc.h> 58 #include <sys/device.h> 59 #include <sys/conf.h> 60 #include <sys/bus.h> 61 #include <sys/pmf.h> 62 63 #include <dev/ic/tpmreg.h> 64 #include <dev/ic/tpmvar.h> 65 66 #include "ioconf.h" 67 68 CTASSERT(sizeof(struct tpm_header) == 10); 69 70 #define TPM_BUFSIZ 1024 71 72 #define TPM_PARAM_SIZE 0x0001 /* that's a flag */ 73 74 /* Timeouts. */ 75 #define TPM_ACCESS_TMO 2000 /* 2sec */ 76 #define TPM_READY_TMO 2000 /* 2sec */ 77 #define TPM_READ_TMO 2000 /* 2sec */ 78 #define TPM_BURST_TMO 2000 /* 2sec */ 79 80 #define TPM_CAPS_REQUIRED \ 81 (TPM_INTF_DATA_AVAIL_INT|TPM_INTF_LOCALITY_CHANGE_INT| \ 82 TPM_INTF_INT_LEVEL_LOW) 83 84 static inline int 85 tpm_tmotohz(int tmo) 86 { 87 struct timeval tv; 88 89 tv.tv_sec = tmo / 1000; 90 tv.tv_usec = 1000 * (tmo % 1000); 91 92 return tvtohz(&tv); 93 } 94 95 static int 96 tpm_getburst(struct tpm_softc *sc) 97 { 98 int burst, to, rv; 99 100 to = tpm_tmotohz(TPM_BURST_TMO); 101 102 while (to--) { 103 /* 104 * Burst count is in bits 23:8, so read the two higher bytes. 105 */ 106 burst = bus_space_read_1(sc->sc_bt, sc->sc_bh, TPM_STS + 1); 107 burst |= bus_space_read_1(sc->sc_bt, sc->sc_bh, TPM_STS + 2) 108 << 8; 109 110 if (burst) 111 return burst; 112 113 rv = tsleep(sc, PCATCH, "tpm_getburst", 1); 114 if (rv && rv != EWOULDBLOCK) { 115 return 0; 116 } 117 } 118 119 return 0; 120 } 121 122 static inline uint8_t 123 tpm_status(struct tpm_softc *sc) 124 { 125 return bus_space_read_1(sc->sc_bt, sc->sc_bh, TPM_STS) & 126 TPM_STS_STATUS_BITS; 127 } 128 129 /* -------------------------------------------------------------------------- */ 130 131 static bool 132 tpm12_suspend(struct tpm_softc *sc) 133 { 134 static const uint8_t command[10] = { 135 0x00, 0xC1, /* TPM_TAG_RQU_COMMAND */ 136 0x00, 0x00, 0x00, 10, /* Length in bytes */ 137 0x00, 0x00, 0x00, 0x98 /* TPM_ORD_SaveState */ 138 }; 139 struct tpm_header response; 140 141 if ((*sc->sc_intf->write)(sc, &command, sizeof(command)) != 0) 142 return false; 143 if ((*sc->sc_intf->read)(sc, &response, sizeof(response), NULL, 0) != 0) 144 return false; 145 if (TPM_BE32(response.code) != 0) 146 return false; 147 148 return true; 149 } 150 151 static bool 152 tpm20_suspend(struct tpm_softc *sc) 153 { 154 static const uint8_t command[12] = { 155 0x80, 0x01, /* TPM_ST_NO_SESSIONS */ 156 0x00, 0x00, 0x00, 12, /* Length in bytes */ 157 0x00, 0x00, 0x01, 0x45, /* TPM_CC_Shutdown */ 158 0x00, 0x01 /* TPM_SU_STATE */ 159 }; 160 struct tpm_header response; 161 162 if ((*sc->sc_intf->write)(sc, &command, sizeof(command)) != 0) 163 return false; 164 if ((*sc->sc_intf->read)(sc, &response, sizeof(response), NULL, 0) != 0) 165 return false; 166 if (TPM_BE32(response.code) != 0) 167 return false; 168 169 return true; 170 } 171 172 bool 173 tpm_suspend(device_t dev, const pmf_qual_t *qual) 174 { 175 struct tpm_softc *sc = device_private(dev); 176 177 switch (sc->sc_ver) { 178 case TPM_1_2: 179 return tpm12_suspend(sc); 180 case TPM_2_0: 181 return tpm20_suspend(sc); 182 default: 183 panic("%s: impossible", __func__); 184 } 185 } 186 187 bool 188 tpm_resume(device_t dev, const pmf_qual_t *qual) 189 { 190 /* 191 * Don't do anything, the BIOS is supposed to restore the previously 192 * saved state. 193 */ 194 return true; 195 } 196 197 /* -------------------------------------------------------------------------- */ 198 199 static int 200 tpm_poll(struct tpm_softc *sc, uint8_t mask, int to, wchan_t chan) 201 { 202 int rv; 203 204 while (((sc->sc_status = tpm_status(sc)) & mask) != mask && to--) { 205 rv = tsleep(chan, PCATCH, "tpm_poll", 1); 206 if (rv && rv != EWOULDBLOCK) { 207 return rv; 208 } 209 } 210 211 return 0; 212 } 213 214 static int 215 tpm_waitfor(struct tpm_softc *sc, uint8_t bits, int tmo, wchan_t chan) 216 { 217 int retry, to, rv; 218 uint8_t todo; 219 220 to = tpm_tmotohz(tmo); 221 retry = 3; 222 223 restart: 224 todo = bits; 225 226 /* 227 * TPM_STS_VALID has priority over the others. 228 */ 229 if (todo & TPM_STS_VALID) { 230 if ((rv = tpm_poll(sc, TPM_STS_VALID, to+1, chan)) != 0) 231 return rv; 232 todo &= ~TPM_STS_VALID; 233 } 234 235 if ((rv = tpm_poll(sc, todo, to, chan)) != 0) 236 return rv; 237 238 if ((todo & sc->sc_status) != todo) { 239 if ((retry-- > 0) && (bits & TPM_STS_VALID)) { 240 bus_space_write_1(sc->sc_bt, sc->sc_bh, TPM_STS, 241 TPM_STS_RESP_RETRY); 242 goto restart; 243 } 244 return EIO; 245 } 246 247 return 0; 248 } 249 250 /* -------------------------------------------------------------------------- */ 251 252 /* 253 * TPM using the TIS 1.2 interface. 254 */ 255 256 static int 257 tpm12_request_locality(struct tpm_softc *sc, int l) 258 { 259 uint32_t r; 260 int to, rv; 261 262 if (l != 0) 263 return EINVAL; 264 265 if ((bus_space_read_1(sc->sc_bt, sc->sc_bh, TPM_ACCESS) & 266 (TPM_ACCESS_VALID | TPM_ACCESS_ACTIVE_LOCALITY)) == 267 (TPM_ACCESS_VALID | TPM_ACCESS_ACTIVE_LOCALITY)) 268 return 0; 269 270 bus_space_write_1(sc->sc_bt, sc->sc_bh, TPM_ACCESS, 271 TPM_ACCESS_REQUEST_USE); 272 273 to = tpm_tmotohz(TPM_ACCESS_TMO); 274 275 while ((r = bus_space_read_1(sc->sc_bt, sc->sc_bh, TPM_ACCESS) & 276 (TPM_ACCESS_VALID | TPM_ACCESS_ACTIVE_LOCALITY)) != 277 (TPM_ACCESS_VALID | TPM_ACCESS_ACTIVE_LOCALITY) && to--) { 278 rv = tsleep(sc->sc_intf->init, PCATCH, "tpm_locality", 1); 279 if (rv && rv != EWOULDBLOCK) { 280 return rv; 281 } 282 } 283 284 if ((r & (TPM_ACCESS_VALID | TPM_ACCESS_ACTIVE_LOCALITY)) != 285 (TPM_ACCESS_VALID | TPM_ACCESS_ACTIVE_LOCALITY)) { 286 return EBUSY; 287 } 288 289 return 0; 290 } 291 292 static int 293 tpm_tis12_probe(bus_space_tag_t bt, bus_space_handle_t bh) 294 { 295 uint32_t cap; 296 uint8_t reg; 297 int tmo; 298 299 cap = bus_space_read_4(bt, bh, TPM_INTF_CAPABILITY); 300 if (cap == 0xffffffff) 301 return EINVAL; 302 if ((cap & TPM_CAPS_REQUIRED) != TPM_CAPS_REQUIRED) 303 return ENOTSUP; 304 305 /* Request locality 0. */ 306 bus_space_write_1(bt, bh, TPM_ACCESS, TPM_ACCESS_REQUEST_USE); 307 308 /* Wait for it to become active. */ 309 tmo = TPM_ACCESS_TMO; /* Milliseconds. */ 310 while ((reg = bus_space_read_1(bt, bh, TPM_ACCESS) & 311 (TPM_ACCESS_VALID | TPM_ACCESS_ACTIVE_LOCALITY)) != 312 (TPM_ACCESS_VALID | TPM_ACCESS_ACTIVE_LOCALITY) && tmo--) { 313 DELAY(1000); /* 1 millisecond. */ 314 } 315 if ((reg & (TPM_ACCESS_VALID | TPM_ACCESS_ACTIVE_LOCALITY)) != 316 (TPM_ACCESS_VALID | TPM_ACCESS_ACTIVE_LOCALITY)) { 317 return ETIMEDOUT; 318 } 319 320 if (bus_space_read_4(bt, bh, TPM_ID) == 0xffffffff) 321 return EINVAL; 322 323 return 0; 324 } 325 326 static int 327 tpm_tis12_init(struct tpm_softc *sc) 328 { 329 int rv; 330 331 sc->sc_caps = bus_space_read_4(sc->sc_bt, sc->sc_bh, 332 TPM_INTF_CAPABILITY); 333 sc->sc_devid = bus_space_read_4(sc->sc_bt, sc->sc_bh, TPM_ID); 334 sc->sc_rev = bus_space_read_1(sc->sc_bt, sc->sc_bh, TPM_REV); 335 336 aprint_normal_dev(sc->sc_dev, "device 0x%08x rev 0x%x\n", 337 sc->sc_devid, sc->sc_rev); 338 339 if ((rv = tpm12_request_locality(sc, 0)) != 0) 340 return rv; 341 342 /* Abort whatever it thought it was doing. */ 343 bus_space_write_1(sc->sc_bt, sc->sc_bh, TPM_STS, TPM_STS_CMD_READY); 344 345 return 0; 346 } 347 348 static int 349 tpm_tis12_start(struct tpm_softc *sc, int rw) 350 { 351 int rv; 352 353 if (rw == UIO_READ) { 354 rv = tpm_waitfor(sc, TPM_STS_DATA_AVAIL | TPM_STS_VALID, 355 TPM_READ_TMO, sc->sc_intf->read); 356 return rv; 357 } 358 359 /* Request the 0th locality. */ 360 if ((rv = tpm12_request_locality(sc, 0)) != 0) 361 return rv; 362 363 sc->sc_status = tpm_status(sc); 364 if (sc->sc_status & TPM_STS_CMD_READY) 365 return 0; 366 367 /* Abort previous and restart. */ 368 bus_space_write_1(sc->sc_bt, sc->sc_bh, TPM_STS, TPM_STS_CMD_READY); 369 rv = tpm_waitfor(sc, TPM_STS_CMD_READY, TPM_READY_TMO, sc->sc_intf->write); 370 if (rv) 371 return rv; 372 373 return 0; 374 } 375 376 static int 377 tpm_tis12_read(struct tpm_softc *sc, void *buf, size_t len, size_t *count, 378 int flags) 379 { 380 uint8_t *p = buf; 381 size_t cnt; 382 int rv, n; 383 384 cnt = 0; 385 while (len > 0) { 386 rv = tpm_waitfor(sc, TPM_STS_DATA_AVAIL | TPM_STS_VALID, 387 TPM_READ_TMO, sc->sc_intf->read); 388 if (rv) 389 return rv; 390 391 n = MIN(len, tpm_getburst(sc)); 392 while (n > 0) { 393 *p++ = bus_space_read_1(sc->sc_bt, sc->sc_bh, TPM_DATA); 394 cnt++; 395 len--; 396 n--; 397 } 398 399 if ((flags & TPM_PARAM_SIZE) == 0 && cnt >= 6) 400 break; 401 } 402 403 if (count) 404 *count = cnt; 405 406 return 0; 407 } 408 409 static int 410 tpm_tis12_write(struct tpm_softc *sc, const void *buf, size_t len) 411 { 412 const uint8_t *p = buf; 413 size_t cnt; 414 int rv, r; 415 416 if (len == 0) 417 return 0; 418 if ((rv = tpm12_request_locality(sc, 0)) != 0) 419 return rv; 420 421 cnt = 0; 422 while (cnt < len - 1) { 423 for (r = tpm_getburst(sc); r > 0 && cnt < len - 1; r--) { 424 bus_space_write_1(sc->sc_bt, sc->sc_bh, TPM_DATA, *p++); 425 cnt++; 426 } 427 if ((rv = tpm_waitfor(sc, TPM_STS_VALID, TPM_READ_TMO, sc))) { 428 return rv; 429 } 430 sc->sc_status = tpm_status(sc); 431 if (!(sc->sc_status & TPM_STS_DATA_EXPECT)) { 432 return EIO; 433 } 434 } 435 436 bus_space_write_1(sc->sc_bt, sc->sc_bh, TPM_DATA, *p++); 437 cnt++; 438 439 if ((rv = tpm_waitfor(sc, TPM_STS_VALID, TPM_READ_TMO, sc))) { 440 return rv; 441 } 442 if ((sc->sc_status & TPM_STS_DATA_EXPECT) != 0) { 443 return EIO; 444 } 445 446 return 0; 447 } 448 449 static int 450 tpm_tis12_end(struct tpm_softc *sc, int rw, int err) 451 { 452 int rv = 0; 453 454 if (rw == UIO_READ) { 455 rv = tpm_waitfor(sc, TPM_STS_VALID, TPM_READ_TMO, sc->sc_intf->read); 456 if (rv) 457 return rv; 458 459 /* Still more data? */ 460 sc->sc_status = tpm_status(sc); 461 if (!err && (sc->sc_status & TPM_STS_DATA_AVAIL)) { 462 rv = EIO; 463 } 464 465 bus_space_write_1(sc->sc_bt, sc->sc_bh, TPM_STS, 466 TPM_STS_CMD_READY); 467 468 /* Release the 0th locality. */ 469 bus_space_write_1(sc->sc_bt, sc->sc_bh, TPM_ACCESS, 470 TPM_ACCESS_ACTIVE_LOCALITY); 471 } else { 472 /* Hungry for more? */ 473 sc->sc_status = tpm_status(sc); 474 if (!err && (sc->sc_status & TPM_STS_DATA_EXPECT)) { 475 rv = EIO; 476 } 477 478 bus_space_write_1(sc->sc_bt, sc->sc_bh, TPM_STS, 479 err ? TPM_STS_CMD_READY : TPM_STS_GO); 480 } 481 482 return rv; 483 } 484 485 const struct tpm_intf tpm_intf_tis12 = { 486 .version = TIS_1_2, 487 .probe = tpm_tis12_probe, 488 .init = tpm_tis12_init, 489 .start = tpm_tis12_start, 490 .read = tpm_tis12_read, 491 .write = tpm_tis12_write, 492 .end = tpm_tis12_end 493 }; 494 495 /* -------------------------------------------------------------------------- */ 496 497 static dev_type_open(tpmopen); 498 static dev_type_close(tpmclose); 499 static dev_type_read(tpmread); 500 static dev_type_write(tpmwrite); 501 static dev_type_ioctl(tpmioctl); 502 503 const struct cdevsw tpm_cdevsw = { 504 .d_open = tpmopen, 505 .d_close = tpmclose, 506 .d_read = tpmread, 507 .d_write = tpmwrite, 508 .d_ioctl = tpmioctl, 509 .d_stop = nostop, 510 .d_tty = notty, 511 .d_poll = nopoll, 512 .d_mmap = nommap, 513 .d_kqfilter = nokqfilter, 514 .d_discard = nodiscard, 515 .d_flag = D_OTHER | D_MPSAFE, 516 }; 517 518 static int 519 tpmopen(dev_t dev, int flag, int mode, struct lwp *l) 520 { 521 struct tpm_softc *sc = device_lookup_private(&tpm_cd, minor(dev)); 522 int ret = 0; 523 524 if (sc == NULL) 525 return ENXIO; 526 527 mutex_enter(&sc->sc_lock); 528 if (sc->sc_busy) { 529 ret = EBUSY; 530 } else { 531 sc->sc_busy = true; 532 } 533 mutex_exit(&sc->sc_lock); 534 535 return ret; 536 } 537 538 static int 539 tpmclose(dev_t dev, int flag, int mode, struct lwp *l) 540 { 541 struct tpm_softc *sc = device_lookup_private(&tpm_cd, minor(dev)); 542 int ret = 0; 543 544 if (sc == NULL) 545 return ENXIO; 546 547 mutex_enter(&sc->sc_lock); 548 if (!sc->sc_busy) { 549 ret = EINVAL; 550 } else { 551 sc->sc_busy = false; 552 } 553 mutex_exit(&sc->sc_lock); 554 555 return ret; 556 } 557 558 static int 559 tpmread(dev_t dev, struct uio *uio, int flags) 560 { 561 struct tpm_softc *sc = device_lookup_private(&tpm_cd, minor(dev)); 562 struct tpm_header hdr; 563 uint8_t buf[TPM_BUFSIZ]; 564 size_t cnt, len, n; 565 int rv; 566 567 if (sc == NULL) 568 return ENXIO; 569 570 if ((rv = (*sc->sc_intf->start)(sc, UIO_READ))) 571 return rv; 572 573 /* Get the header. */ 574 if ((rv = (*sc->sc_intf->read)(sc, &hdr, sizeof(hdr), &cnt, 0))) { 575 goto out; 576 } 577 len = TPM_BE32(hdr.length); 578 if (len > uio->uio_resid || len < cnt) { 579 rv = EIO; 580 goto out; 581 } 582 583 /* Copy out the header. */ 584 if ((rv = uiomove(&hdr, cnt, uio))) { 585 goto out; 586 } 587 588 /* Process the rest. */ 589 len -= cnt; 590 while (len > 0) { 591 n = MIN(sizeof(buf), len); 592 if ((rv = (*sc->sc_intf->read)(sc, buf, n, NULL, TPM_PARAM_SIZE))) { 593 goto out; 594 } 595 if ((rv = uiomove(buf, n, uio))) { 596 goto out; 597 } 598 len -= n; 599 } 600 601 out: 602 rv = (*sc->sc_intf->end)(sc, UIO_READ, rv); 603 return rv; 604 } 605 606 static int 607 tpmwrite(dev_t dev, struct uio *uio, int flags) 608 { 609 struct tpm_softc *sc = device_lookup_private(&tpm_cd, minor(dev)); 610 uint8_t buf[TPM_BUFSIZ]; 611 int n, rv; 612 613 if (sc == NULL) 614 return ENXIO; 615 616 n = MIN(sizeof(buf), uio->uio_resid); 617 if ((rv = uiomove(buf, n, uio))) { 618 goto out; 619 } 620 if ((rv = (*sc->sc_intf->start)(sc, UIO_WRITE))) { 621 goto out; 622 } 623 if ((rv = (*sc->sc_intf->write)(sc, buf, n))) { 624 goto out; 625 } 626 627 rv = (*sc->sc_intf->end)(sc, UIO_WRITE, rv); 628 out: 629 return rv; 630 } 631 632 static int 633 tpmioctl(dev_t dev, u_long cmd, void *addr, int flag, struct lwp *l) 634 { 635 struct tpm_softc *sc = device_lookup_private(&tpm_cd, minor(dev)); 636 struct tpm_ioc_getinfo *info; 637 638 if (sc == NULL) 639 return ENXIO; 640 641 switch (cmd) { 642 case TPM_IOC_GETINFO: 643 info = addr; 644 info->api_version = TPM_API_VERSION; 645 info->tpm_version = sc->sc_ver; 646 info->itf_version = sc->sc_intf->version; 647 info->device_id = sc->sc_devid; 648 info->device_rev = sc->sc_rev; 649 info->device_caps = sc->sc_caps; 650 return 0; 651 default: 652 break; 653 } 654 655 return ENOTTY; 656 } 657