1 /* $OpenBSD: tpm.c,v 1.11 2021/01/28 17:19:40 cheloha Exp $ */ 2 3 /* 4 * Minimal interface to Trusted Platform Module chips implementing the 5 * TPM Interface Spec 1.2, just enough to tell the TPM to save state before 6 * a system suspend. 7 * 8 * Copyright (c) 2008, 2009 Michael Shalayeff 9 * Copyright (c) 2009, 2010 Hans-Joerg Hoexer 10 * Copyright (c) 2016 joshua stein <jcs@openbsd.org> 11 * All rights reserved. 12 * 13 * Permission to use, copy, modify, and distribute this software for any 14 * purpose with or without fee is hereby granted, provided that the above 15 * copyright notice and this permission notice appear in all copies. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 18 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 19 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 20 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 21 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN 22 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 23 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 24 */ 25 26 #include <sys/param.h> 27 #include <sys/systm.h> 28 #include <sys/device.h> 29 #include <sys/malloc.h> 30 31 #include <machine/bus.h> 32 #include <machine/apmvar.h> 33 34 #include <dev/acpi/acpireg.h> 35 #include <dev/acpi/acpivar.h> 36 #include <dev/acpi/acpidev.h> 37 #include <dev/acpi/amltypes.h> 38 #include <dev/acpi/dsdt.h> 39 40 /* #define TPM_DEBUG */ 41 42 #ifdef TPM_DEBUG 43 #define DPRINTF(x) printf x 44 #else 45 #define DPRINTF(x) 46 #endif 47 48 #define TPM_BUFSIZ 1024 49 #define TPM_HDRSIZE 10 50 #define TPM_PARAM_SIZE 0x0001 51 52 #define TPM_ACCESS 0x0000 /* access register */ 53 #define TPM_ACCESS_ESTABLISHMENT 0x01 /* establishment */ 54 #define TPM_ACCESS_REQUEST_USE 0x02 /* request using locality */ 55 #define TPM_ACCESS_REQUEST_PENDING 0x04 /* pending request */ 56 #define TPM_ACCESS_SEIZE 0x08 /* request locality seize */ 57 #define TPM_ACCESS_SEIZED 0x10 /* locality has been seized */ 58 #define TPM_ACCESS_ACTIVE_LOCALITY 0x20 /* locality is active */ 59 #define TPM_ACCESS_VALID 0x80 /* bits are valid */ 60 #define TPM_ACCESS_BITS \ 61 "\020\01EST\02REQ\03PEND\04SEIZE\05SEIZED\06ACT\010VALID" 62 63 #define TPM_INTERRUPT_ENABLE 0x0008 64 #define TPM_GLOBAL_INT_ENABLE 0x80000000 /* enable ints */ 65 #define TPM_CMD_READY_INT 0x00000080 /* cmd ready enable */ 66 #define TPM_INT_EDGE_FALLING 0x00000018 67 #define TPM_INT_EDGE_RISING 0x00000010 68 #define TPM_INT_LEVEL_LOW 0x00000008 69 #define TPM_INT_LEVEL_HIGH 0x00000000 70 #define TPM_LOCALITY_CHANGE_INT 0x00000004 /* locality change enable */ 71 #define TPM_STS_VALID_INT 0x00000002 /* int on TPM_STS_VALID is set */ 72 #define TPM_DATA_AVAIL_INT 0x00000001 /* int on TPM_STS_DATA_AVAIL is set */ 73 #define TPM_INTERRUPT_ENABLE_BITS \ 74 "\020\040ENA\010RDY\03LOCH\02STSV\01DRDY" 75 76 #define TPM_INT_VECTOR 0x000c /* 8 bit reg for 4 bit irq vector */ 77 #define TPM_INT_STATUS 0x0010 /* bits are & 0x87 from TPM_INTERRUPT_ENABLE */ 78 79 #define TPM_INTF_CAPABILITIES 0x0014 /* capability register */ 80 #define TPM_INTF_BURST_COUNT_STATIC 0x0100 /* TPM_STS_BMASK static */ 81 #define TPM_INTF_CMD_READY_INT 0x0080 /* int on ready supported */ 82 #define TPM_INTF_INT_EDGE_FALLING 0x0040 /* falling edge ints supported */ 83 #define TPM_INTF_INT_EDGE_RISING 0x0020 /* rising edge ints supported */ 84 #define TPM_INTF_INT_LEVEL_LOW 0x0010 /* level-low ints supported */ 85 #define TPM_INTF_INT_LEVEL_HIGH 0x0008 /* level-high ints supported */ 86 #define TPM_INTF_LOCALITY_CHANGE_INT 0x0004 /* locality-change int (mb 1) */ 87 #define TPM_INTF_STS_VALID_INT 0x0002 /* TPM_STS_VALID int supported */ 88 #define TPM_INTF_DATA_AVAIL_INT 0x0001 /* TPM_STS_DATA_AVAIL int supported (mb 1) */ 89 #define TPM_CAPSREQ \ 90 (TPM_INTF_DATA_AVAIL_INT|TPM_INTF_LOCALITY_CHANGE_INT|TPM_INTF_INT_LEVEL_LOW) 91 #define TPM_CAPBITS \ 92 "\020\01IDRDY\02ISTSV\03ILOCH\04IHIGH\05ILOW\06IEDGE\07IFALL\010IRDY\011BCST" 93 94 #define TPM_STS 0x0018 /* status register */ 95 #define TPM_STS_MASK 0x000000ff /* status bits */ 96 #define TPM_STS_BMASK 0x00ffff00 /* ro io burst size */ 97 #define TPM_STS_VALID 0x00000080 /* ro other bits are valid */ 98 #define TPM_STS_CMD_READY 0x00000040 /* rw chip/signal ready */ 99 #define TPM_STS_GO 0x00000020 /* wo start the command */ 100 #define TPM_STS_DATA_AVAIL 0x00000010 /* ro data available */ 101 #define TPM_STS_DATA_EXPECT 0x00000008 /* ro more data to be written */ 102 #define TPM_STS_RESP_RETRY 0x00000002 /* wo resend the response */ 103 #define TPM_STS_BITS "\020\010VALID\07RDY\06GO\05DRDY\04EXPECT\02RETRY" 104 105 #define TPM_DATA 0x0024 106 #define TPM_ID 0x0f00 107 #define TPM_REV 0x0f04 108 #define TPM_SIZE 0x5000 /* five pages of the above */ 109 110 #define TPM_ACCESS_TMO 2000 /* 2sec */ 111 #define TPM_READY_TMO 2000 /* 2sec */ 112 #define TPM_READ_TMO 120000 /* 2 minutes */ 113 #define TPM_BURST_TMO 2000 /* 2sec */ 114 115 struct tpm_softc { 116 struct device sc_dev; 117 118 bus_space_tag_t sc_bt; 119 bus_space_handle_t sc_bh; 120 121 struct acpi_softc *sc_acpi; 122 struct aml_node *sc_devnode; 123 124 uint32_t sc_devid; 125 uint32_t sc_rev; 126 127 int sc_enabled; 128 }; 129 130 const struct { 131 uint32_t devid; 132 char name[32]; 133 } tpm_devs[] = { 134 { 0x000615d1, "Infineon SLD9630 1.1" }, 135 { 0x000b15d1, "Infineon SLB9635 1.2" }, 136 { 0x100214e4, "Broadcom BCM0102" }, 137 { 0x00fe1050, "WEC WPCT200" }, 138 { 0x687119fa, "SNS SSX35" }, 139 { 0x2e4d5453, "STM ST19WP18" }, 140 { 0x32021114, "Atmel 97SC3203" }, 141 { 0x10408086, "Intel INTC0102" }, 142 { 0, "" }, 143 }; 144 145 int tpm_match(struct device *, void *, void *); 146 void tpm_attach(struct device *, struct device *, void *); 147 int tpm_activate(struct device *, int); 148 149 int tpm_probe(bus_space_tag_t, bus_space_handle_t); 150 int tpm_init(struct tpm_softc *); 151 int tpm_read(struct tpm_softc *, void *, int, size_t *, int); 152 int tpm_write(struct tpm_softc *, void *, int); 153 int tpm_suspend(struct tpm_softc *); 154 int tpm_resume(struct tpm_softc *); 155 156 int tpm_waitfor(struct tpm_softc *, uint8_t, int); 157 int tpm_request_locality(struct tpm_softc *, int); 158 void tpm_release_locality(struct tpm_softc *); 159 int tpm_getburst(struct tpm_softc *); 160 uint8_t tpm_status(struct tpm_softc *); 161 162 struct cfattach tpm_ca = { 163 sizeof(struct tpm_softc), 164 tpm_match, 165 tpm_attach, 166 NULL, 167 tpm_activate 168 }; 169 170 struct cfdriver tpm_cd = { 171 NULL, "tpm", DV_DULL 172 }; 173 174 const char *tpm_hids[] = { 175 "PNP0C31", 176 "ATM1200", 177 "IFX0102", 178 "BCM0101", 179 "BCM0102", 180 "NSC1200", 181 "ICO0102", 182 NULL 183 }; 184 185 int 186 tpm_match(struct device *parent, void *match, void *aux) 187 { 188 struct acpi_attach_args *aa = aux; 189 struct cfdata *cf = match; 190 191 return (acpi_matchhids(aa, tpm_hids, cf->cf_driver->cd_name)); 192 } 193 194 void 195 tpm_attach(struct device *parent, struct device *self, void *aux) 196 { 197 struct tpm_softc *sc = (struct tpm_softc *)self; 198 struct acpi_attach_args *aaa = aux; 199 int64_t sta; 200 201 sc->sc_acpi = (struct acpi_softc *)parent; 202 sc->sc_devnode = aaa->aaa_node; 203 sc->sc_enabled = 0; 204 205 printf(" %s", sc->sc_devnode->name); 206 207 sta = acpi_getsta(sc->sc_acpi, sc->sc_devnode); 208 if ((sta & (STA_PRESENT | STA_ENABLED | STA_DEV_OK)) != 209 (STA_PRESENT | STA_ENABLED | STA_DEV_OK)) { 210 printf(": not enabled\n"); 211 return; 212 } 213 214 if (aaa->aaa_naddr < 1) { 215 printf(": no registers\n"); 216 return; 217 } 218 219 printf(" addr 0x%llx/0x%llx", aaa->aaa_addr[0], aaa->aaa_size[0]); 220 221 sc->sc_bt = aaa->aaa_bst[0]; 222 if (bus_space_map(sc->sc_bt, aaa->aaa_addr[0], aaa->aaa_size[0], 223 0, &sc->sc_bh)) { 224 printf(": can't map registers\n"); 225 return; 226 } 227 228 if (!tpm_probe(sc->sc_bt, sc->sc_bh)) { 229 printf(": probe failed\n"); 230 return; 231 } 232 233 if (tpm_init(sc) != 0) { 234 printf(": init failed\n"); 235 return; 236 } 237 238 printf("\n"); 239 sc->sc_enabled = 1; 240 } 241 242 int 243 tpm_activate(struct device *self, int act) 244 { 245 struct tpm_softc *sc = (struct tpm_softc *)self; 246 247 switch (act) { 248 case DVACT_SUSPEND: 249 if (!sc->sc_enabled) { 250 DPRINTF(("%s: suspend, but not enabled\n", 251 sc->sc_dev.dv_xname)); 252 return 0; 253 } 254 tpm_suspend(sc); 255 break; 256 257 case DVACT_WAKEUP: 258 if (!sc->sc_enabled) { 259 DPRINTF(("%s: wakeup, but not enabled\n", 260 sc->sc_dev.dv_xname)); 261 return 0; 262 } 263 tpm_resume(sc); 264 break; 265 } 266 267 return 0; 268 } 269 270 int 271 tpm_suspend(struct tpm_softc *sc) 272 { 273 uint8_t command[] = { 274 0, 0xc1, /* TPM_TAG_RQU_COMMAND */ 275 0, 0, 0, 10, /* Length in bytes */ 276 0, 0, 0, 0x98 /* TPM_ORD_SaveStates */ 277 }; 278 279 DPRINTF(("%s: saving state preparing for suspend\n", 280 sc->sc_dev.dv_xname)); 281 282 /* 283 * Tell the chip to save its state so the BIOS can then restore it upon 284 * resume. 285 */ 286 tpm_write(sc, &command, sizeof(command)); 287 tpm_read(sc, &command, sizeof(command), NULL, TPM_HDRSIZE); 288 289 return 0; 290 } 291 292 int 293 tpm_resume(struct tpm_softc *sc) 294 { 295 /* 296 * TODO: The BIOS should have restored the chip's state for us already, 297 * but we should tell the chip to do a self-test here (according to the 298 * Linux driver). 299 */ 300 301 DPRINTF(("%s: resume\n", sc->sc_dev.dv_xname)); 302 return 0; 303 } 304 305 int 306 tpm_probe(bus_space_tag_t bt, bus_space_handle_t bh) 307 { 308 uint32_t r; 309 int tries = 10000; 310 311 /* wait for chip to settle */ 312 while (tries--) { 313 if (bus_space_read_1(bt, bh, TPM_ACCESS) & TPM_ACCESS_VALID) 314 break; 315 else if (!tries) { 316 printf(": timed out waiting for validity\n"); 317 return 1; 318 } 319 320 DELAY(10); 321 } 322 323 r = bus_space_read_4(bt, bh, TPM_INTF_CAPABILITIES); 324 if (r == 0xffffffff) 325 return 0; 326 327 return 1; 328 } 329 330 int 331 tpm_init(struct tpm_softc *sc) 332 { 333 uint32_t r, intmask; 334 int i; 335 336 r = bus_space_read_4(sc->sc_bt, sc->sc_bh, TPM_INTF_CAPABILITIES); 337 if ((r & TPM_CAPSREQ) != TPM_CAPSREQ || 338 !(r & (TPM_INTF_INT_EDGE_RISING | TPM_INTF_INT_LEVEL_LOW))) { 339 DPRINTF((": caps too low (caps=%b)\n", r, TPM_CAPBITS)); 340 return 0; 341 } 342 343 /* ack and disable all interrupts, we'll be using polling only */ 344 intmask = bus_space_read_4(sc->sc_bt, sc->sc_bh, TPM_INTERRUPT_ENABLE); 345 intmask |= TPM_INTF_CMD_READY_INT | TPM_INTF_LOCALITY_CHANGE_INT | 346 TPM_INTF_DATA_AVAIL_INT | TPM_INTF_STS_VALID_INT; 347 intmask &= ~TPM_GLOBAL_INT_ENABLE; 348 bus_space_write_4(sc->sc_bt, sc->sc_bh, TPM_INTERRUPT_ENABLE, intmask); 349 350 if (tpm_request_locality(sc, 0)) { 351 printf(", requesting locality failed\n"); 352 return 1; 353 } 354 355 sc->sc_devid = bus_space_read_4(sc->sc_bt, sc->sc_bh, TPM_ID); 356 sc->sc_rev = bus_space_read_1(sc->sc_bt, sc->sc_bh, TPM_REV); 357 358 for (i = 0; tpm_devs[i].devid; i++) 359 if (tpm_devs[i].devid == sc->sc_devid) 360 break; 361 362 if (tpm_devs[i].devid) 363 printf(", %s rev 0x%x", tpm_devs[i].name, sc->sc_rev); 364 else 365 printf(", device 0x%08x rev 0x%x", sc->sc_devid, sc->sc_rev); 366 367 return 0; 368 } 369 370 int 371 tpm_request_locality(struct tpm_softc *sc, int l) 372 { 373 uint32_t r; 374 int to; 375 376 if (l != 0) 377 return EINVAL; 378 379 if ((bus_space_read_1(sc->sc_bt, sc->sc_bh, TPM_ACCESS) & 380 (TPM_ACCESS_VALID | TPM_ACCESS_ACTIVE_LOCALITY)) == 381 (TPM_ACCESS_VALID | TPM_ACCESS_ACTIVE_LOCALITY)) 382 return 0; 383 384 bus_space_write_1(sc->sc_bt, sc->sc_bh, TPM_ACCESS, 385 TPM_ACCESS_REQUEST_USE); 386 387 to = TPM_ACCESS_TMO * 100; /* steps of 10 microseconds */ 388 389 while ((r = bus_space_read_1(sc->sc_bt, sc->sc_bh, TPM_ACCESS) & 390 (TPM_ACCESS_VALID | TPM_ACCESS_ACTIVE_LOCALITY)) != 391 (TPM_ACCESS_VALID | TPM_ACCESS_ACTIVE_LOCALITY) && to--) { 392 DELAY(10); 393 } 394 395 if ((r & (TPM_ACCESS_VALID | TPM_ACCESS_ACTIVE_LOCALITY)) != 396 (TPM_ACCESS_VALID | TPM_ACCESS_ACTIVE_LOCALITY)) { 397 DPRINTF(("%s: %s: access %b\n", sc->sc_dev.dv_xname, __func__, 398 r, TPM_ACCESS_BITS)); 399 return EBUSY; 400 } 401 402 return 0; 403 } 404 405 void 406 tpm_release_locality(struct tpm_softc *sc) 407 { 408 if ((bus_space_read_1(sc->sc_bt, sc->sc_bh, TPM_ACCESS) & 409 (TPM_ACCESS_REQUEST_PENDING|TPM_ACCESS_VALID)) == 410 (TPM_ACCESS_REQUEST_PENDING|TPM_ACCESS_VALID)) { 411 DPRINTF(("%s: releasing locality\n", sc->sc_dev.dv_xname)); 412 bus_space_write_1(sc->sc_bt, sc->sc_bh, TPM_ACCESS, 413 TPM_ACCESS_ACTIVE_LOCALITY); 414 } 415 } 416 417 int 418 tpm_getburst(struct tpm_softc *sc) 419 { 420 int burst, burst2, to; 421 422 to = TPM_BURST_TMO * 100; /* steps of 10 microseconds */ 423 424 burst = 0; 425 while (burst == 0 && to--) { 426 /* 427 * Burst count has to be read from bits 8 to 23 without 428 * touching any other bits, eg. the actual status bits 0 to 7. 429 */ 430 burst = bus_space_read_1(sc->sc_bt, sc->sc_bh, TPM_STS + 1); 431 DPRINTF(("%s: %s: read1(0x%x): 0x%x\n", sc->sc_dev.dv_xname, 432 __func__, TPM_STS + 1, burst)); 433 burst2 = bus_space_read_1(sc->sc_bt, sc->sc_bh, TPM_STS + 2); 434 DPRINTF(("%s: %s: read1(0x%x): 0x%x\n", sc->sc_dev.dv_xname, 435 __func__, TPM_STS + 2, burst2)); 436 burst |= burst2 << 8; 437 if (burst) 438 return burst; 439 440 DELAY(10); 441 } 442 443 DPRINTF(("%s: getburst timed out\n", sc->sc_dev.dv_xname)); 444 445 return 0; 446 } 447 448 uint8_t 449 tpm_status(struct tpm_softc *sc) 450 { 451 return bus_space_read_1(sc->sc_bt, sc->sc_bh, TPM_STS) & TPM_STS_MASK; 452 } 453 454 int 455 tpm_waitfor(struct tpm_softc *sc, uint8_t mask, int msecs) 456 { 457 int usecs; 458 uint8_t status; 459 460 usecs = msecs * 1000; 461 462 while (((status = tpm_status(sc)) & mask) != mask) { 463 if (usecs == 0) { 464 DPRINTF(("%s: %s: timed out, status 0x%x != 0x%x\n", 465 sc->sc_dev.dv_xname, __func__, status, mask)); 466 return status; 467 } 468 469 usecs--; 470 DELAY(1); 471 } 472 473 return 0; 474 } 475 476 int 477 tpm_read(struct tpm_softc *sc, void *buf, int len, size_t *count, 478 int flags) 479 { 480 uint8_t *p = buf; 481 uint8_t c; 482 size_t cnt; 483 int rv, n, bcnt; 484 485 DPRINTF(("%s: %s %d:", sc->sc_dev.dv_xname, __func__, len)); 486 487 cnt = 0; 488 while (len > 0) { 489 if ((rv = tpm_waitfor(sc, TPM_STS_DATA_AVAIL | TPM_STS_VALID, 490 TPM_READ_TMO))) 491 return rv; 492 493 bcnt = tpm_getburst(sc); 494 n = MIN(len, bcnt); 495 496 for (; n--; len--) { 497 c = bus_space_read_1(sc->sc_bt, sc->sc_bh, TPM_DATA); 498 DPRINTF((" %02x", c)); 499 *p++ = c; 500 cnt++; 501 } 502 503 if ((flags & TPM_PARAM_SIZE) == 0 && cnt >= 6) 504 break; 505 } 506 507 DPRINTF(("\n")); 508 509 if (count) 510 *count = cnt; 511 512 return 0; 513 } 514 515 int 516 tpm_write(struct tpm_softc *sc, void *buf, int len) 517 { 518 uint8_t *p = buf; 519 uint8_t status; 520 size_t count = 0; 521 int rv, r; 522 523 if ((rv = tpm_request_locality(sc, 0)) != 0) 524 return rv; 525 526 DPRINTF(("%s: %s %d:", sc->sc_dev.dv_xname, __func__, len)); 527 for (r = 0; r < len; r++) 528 DPRINTF((" %02x", (uint8_t)(*(p + r)))); 529 DPRINTF(("\n")); 530 531 /* read status */ 532 status = tpm_status(sc); 533 if ((status & TPM_STS_CMD_READY) == 0) { 534 /* abort! */ 535 bus_space_write_1(sc->sc_bt, sc->sc_bh, TPM_STS, 536 TPM_STS_CMD_READY); 537 if ((rv = tpm_waitfor(sc, TPM_STS_CMD_READY, TPM_READ_TMO))) { 538 DPRINTF(("%s: failed waiting for ready after abort " 539 "(0x%x)\n", sc->sc_dev.dv_xname, rv)); 540 return rv; 541 } 542 } 543 544 while (count < len - 1) { 545 for (r = tpm_getburst(sc); r > 0 && count < len - 1; r--) { 546 DPRINTF(("%s: %s: write1(0x%x, 0x%x)\n", 547 sc->sc_dev.dv_xname, __func__, TPM_DATA, *p)); 548 bus_space_write_1(sc->sc_bt, sc->sc_bh, TPM_DATA, *p++); 549 count++; 550 } 551 if ((rv = tpm_waitfor(sc, TPM_STS_VALID | TPM_STS_DATA_EXPECT, 552 TPM_READ_TMO))) { 553 DPRINTF(("%s: %s: failed waiting for next byte (%d)\n", 554 sc->sc_dev.dv_xname, __func__, rv)); 555 return rv; 556 } 557 } 558 559 DPRINTF(("%s: %s: write1(0x%x, 0x%x)\n", sc->sc_dev.dv_xname, __func__, 560 TPM_DATA, *p)); 561 bus_space_write_1(sc->sc_bt, sc->sc_bh, TPM_DATA, *p); 562 count++; 563 564 if ((rv = tpm_waitfor(sc, TPM_STS_VALID, TPM_READ_TMO))) { 565 DPRINTF(("%s: %s: failed after last byte (%d)\n", 566 sc->sc_dev.dv_xname, __func__, rv)); 567 return rv; 568 } 569 570 if ((status = tpm_status(sc)) & TPM_STS_DATA_EXPECT) { 571 DPRINTF(("%s: %s: final status still expecting data: %b\n", 572 sc->sc_dev.dv_xname, __func__, status, TPM_STS_BITS)); 573 return status; 574 } 575 576 DPRINTF(("%s: final status after write: %b\n", sc->sc_dev.dv_xname, 577 status, TPM_STS_BITS)); 578 579 /* XXX: are we ever sending non-command data? */ 580 bus_space_write_1(sc->sc_bt, sc->sc_bh, TPM_STS, TPM_STS_GO); 581 582 return 0; 583 } 584