1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* 28 * TPM 1.2 Driver for the TPMs that follow TIS v1.2 29 */ 30 31 #include <sys/devops.h> /* used by dev_ops */ 32 #include <sys/conf.h> /* used by dev_ops,cb_ops */ 33 #include <sys/modctl.h> /* for _init,_info,_fini,mod_* */ 34 #include <sys/ddi.h> /* used by all entry points */ 35 #include <sys/sunddi.h> /* used by all entry points */ 36 #include <sys/cmn_err.h> /* used for debug outputs */ 37 #include <sys/types.h> /* used by prop_op, ddi_prop_op */ 38 39 #include <sys/file.h> /* used by open, close */ 40 #include <sys/errno.h> /* used by open,close,read,write */ 41 #include <sys/open.h> /* used by open,close,read,write */ 42 #include <sys/cred.h> /* used by open,close,read */ 43 #include <sys/uio.h> /* used by read */ 44 #include <sys/stat.h> /* defines S_IFCHR */ 45 46 #include <sys/byteorder.h> /* for ntohs, ntohl, htons, htonl */ 47 48 #ifdef sun4v 49 #include <sys/hypervisor_api.h> 50 #include <sys/hsvc.h> 51 #endif 52 53 #include <tss/platform.h> /* from SUNWtss */ 54 #include <tss/tpm.h> /* from SUNWtss */ 55 56 #include "tpm_tis.h" 57 #include "tpm_ddi.h" 58 #include "tpm_duration.h" 59 60 #define TPM_HEADER_SIZE 10 61 typedef enum { 62 TPM_TAG_OFFSET = 0, 63 TPM_PARAMSIZE_OFFSET = 2, 64 TPM_RETURN_OFFSET = 6, 65 TPM_COMMAND_CODE_OFFSET = 6, 66 } TPM_HEADER_OFFSET_T; 67 68 /* 69 * This is to address some TPMs that does not report the correct duration 70 * and timeouts. In our experience with the production TPMs, we encountered 71 * time errors such as GetCapability command from TPM reporting the timeout 72 * and durations in milliseconds rather than microseconds. Some other TPMs 73 * report the value 0's 74 * 75 * Short Duration is based on section 11.3.4 of TIS speciciation, that 76 * TPM_GetCapability (short duration) commands should not be longer than 750ms 77 * and that section 11.3.7 states that TPM_ContinueSelfTest (medium duration) 78 * should not be longer than 1 second. 79 */ 80 #define DEFAULT_SHORT_DURATION 750000 81 #define DEFAULT_MEDIUM_DURATION 1000000 82 #define DEFAULT_LONG_DURATION 300000000 83 #define DEFAULT_TIMEOUT_A 750000 84 #define DEFAULT_TIMEOUT_B 2000000 85 #define DEFAULT_TIMEOUT_C 750000 86 #define DEFAULT_TIMEOUT_D 750000 87 88 /* 89 * In order to test the 'millisecond bug', we test if DURATIONS and TIMEOUTS 90 * are unreasonably low...such as 10 milliseconds (TPM isn't that fast). 91 * and 400 milliseconds for long duration 92 */ 93 #define TEN_MILLISECONDS 10000 /* 10 milliseconds */ 94 #define FOUR_HUNDRED_MILLISECONDS 400000 /* 4 hundred milliseconds */ 95 96 #define DEFAULT_LOCALITY 0 97 /* 98 * TPM input/output buffer offsets 99 */ 100 101 typedef enum { 102 TPM_CAP_RESPSIZE_OFFSET = 10, 103 TPM_CAP_RESP_OFFSET = 14, 104 } TPM_CAP_RET_OFFSET_T; 105 106 typedef enum { 107 TPM_CAP_TIMEOUT_A_OFFSET = 14, 108 TPM_CAP_TIMEOUT_B_OFFSET = 18, 109 TPM_CAP_TIMEOUT_C_OFFSET = 22, 110 TPM_CAP_TIMEOUT_D_OFFSET = 26, 111 } TPM_CAP_TIMEOUT_OFFSET_T; 112 113 typedef enum { 114 TPM_CAP_DUR_SHORT_OFFSET = 14, 115 TPM_CAP_DUR_MEDIUM_OFFSET = 18, 116 TPM_CAP_DUR_LONG_OFFSET = 22, 117 } TPM_CAP_DURATION_OFFSET_T; 118 119 #define TPM_CAP_VERSION_INFO_OFFSET 14 120 #define TPM_CAP_VERSION_INFO_SIZE 15 121 122 /* 123 * Internal TPM command functions 124 */ 125 static int itpm_command(tpm_state_t *tpm, uint8_t *buf, size_t bufsiz); 126 static int tpm_get_timeouts(tpm_state_t *tpm); 127 static int tpm_get_duration(tpm_state_t *tpm); 128 static int tpm_get_version(tpm_state_t *tpm); 129 static int tpm_continue_selftest(tpm_state_t *tpm); 130 131 /* 132 * Internal TIS related functions 133 */ 134 static int tpm_wait_for_stat(tpm_state_t *, uint8_t, clock_t); 135 static clock_t tpm_get_ordinal_duration(tpm_state_t *, uint8_t); 136 static int tis_check_active_locality(tpm_state_t *, char); 137 static int tis_request_locality(tpm_state_t *, char); 138 static void tis_release_locality(tpm_state_t *, char, int); 139 static int tis_init(tpm_state_t *); 140 static uint8_t tis_get_status(tpm_state_t *); 141 static int tis_send_data(tpm_state_t *, uint8_t *, size_t); 142 static int tis_recv_data(tpm_state_t *, uint8_t *, size_t); 143 144 /* Auxilliary */ 145 static int receive_data(tpm_state_t *, uint8_t *, size_t); 146 static inline int tpm_io_lock(tpm_state_t *); 147 static inline void tpm_unlock(tpm_state_t *); 148 static void tpm_cleanup(dev_info_t *, tpm_state_t *); 149 150 /* 151 * Sun DDI/DDK entry points 152 */ 153 154 /* Declaration of autoconfig functions */ 155 static int tpm_attach(dev_info_t *, ddi_attach_cmd_t); 156 static int tpm_detach(dev_info_t *, ddi_detach_cmd_t); 157 static int tpm_getinfo(dev_info_t *, ddi_info_cmd_t, void *, void **); 158 static int tpm_quiesce(dev_info_t *); 159 /* End of autoconfig functions */ 160 161 /* Declaration of driver entry point functions */ 162 static int tpm_open(dev_t *, int, int, cred_t *); 163 static int tpm_close(dev_t, int, int, cred_t *); 164 static int tpm_read(dev_t, struct uio *, cred_t *); 165 static int tpm_write(dev_t, struct uio *, cred_t *); 166 /* End of driver entry point functions */ 167 168 /* cb_ops structure */ 169 static struct cb_ops tpm_cb_ops = { 170 tpm_open, 171 tpm_close, 172 nodev, /* no strategy - nodev returns ENXIO */ 173 nodev, /* no print */ 174 nodev, /* no dump */ 175 tpm_read, 176 tpm_write, 177 nodev, /* no ioctl */ 178 nodev, /* no devmap */ 179 nodev, /* no mmap */ 180 nodev, /* no segmap */ 181 nochpoll, /* returns ENXIO for non-pollable devices */ 182 ddi_prop_op, 183 NULL, /* streamtab struc */ 184 D_MP, /* compatibility flags */ 185 CB_REV, /* cb_ops revision number */ 186 nodev, /* no aread */ 187 nodev /* no awrite */ 188 }; 189 190 /* dev_ops structure */ 191 static struct dev_ops tpm_dev_ops = { 192 DEVO_REV, 193 0, /* reference count */ 194 tpm_getinfo, 195 nulldev, /* no identify - nulldev returns 0 */ 196 nulldev, 197 tpm_attach, 198 tpm_detach, 199 nodev, /* no reset - nodev returns ENXIO */ 200 &tpm_cb_ops, 201 (struct bus_ops *)NULL, 202 nodev, /* no power */ 203 tpm_quiesce 204 }; 205 206 /* modldrv structure */ 207 static struct modldrv modldrv = { 208 &mod_driverops, /* Type: This is a driver */ 209 "TPM 1.2 driver", /* Name of the module. */ 210 &tpm_dev_ops 211 }; 212 213 /* modlinkage structure */ 214 static struct modlinkage tpm_ml = { 215 MODREV_1, 216 &modldrv, 217 NULL 218 }; 219 220 221 #ifdef KCF_TPM_RNG_PROVIDER 222 223 #define IDENT_TPMRNG "TPM Random Number Generator" 224 225 #include <sys/crypto/common.h> 226 #include <sys/crypto/impl.h> 227 #include <sys/crypto/spi.h> 228 /* 229 * CSPI information (entry points, provider info, etc.) 230 */ 231 static void tpmrng_provider_status(crypto_provider_handle_t, uint_t *); 232 233 static crypto_control_ops_t tpmrng_control_ops = { 234 tpmrng_provider_status 235 }; 236 237 static int tpmrng_seed_random(crypto_provider_handle_t, crypto_session_id_t, 238 uchar_t *, size_t, uint_t, uint32_t, crypto_req_handle_t); 239 240 static int tpmrng_generate_random(crypto_provider_handle_t, 241 crypto_session_id_t, uchar_t *, size_t, crypto_req_handle_t); 242 243 static crypto_random_number_ops_t tpmrng_random_number_ops = { 244 tpmrng_seed_random, 245 tpmrng_generate_random 246 }; 247 248 static int tpmrng_ext_info(crypto_provider_handle_t, 249 crypto_provider_ext_info_t *, 250 crypto_req_handle_t); 251 252 static crypto_provider_management_ops_t tpmrng_extinfo_op = { 253 tpmrng_ext_info, 254 NULL, 255 NULL, 256 NULL 257 }; 258 259 static int tpmrng_register(tpm_state_t *); 260 static int tpmrng_unregister(tpm_state_t *); 261 262 static crypto_ops_t tpmrng_crypto_ops = { 263 &tpmrng_control_ops, 264 NULL, 265 NULL, 266 NULL, 267 NULL, 268 NULL, 269 NULL, 270 NULL, 271 &tpmrng_random_number_ops, 272 NULL, 273 NULL, 274 NULL, 275 &tpmrng_extinfo_op, 276 NULL, 277 NULL 278 }; 279 280 static crypto_provider_info_t tpmrng_prov_info = { 281 CRYPTO_SPI_VERSION_2, 282 "TPM Random Number Provider", 283 CRYPTO_HW_PROVIDER, 284 NULL, 285 NULL, 286 &tpmrng_crypto_ops, 287 0, 288 NULL, 289 0, 290 NULL 291 }; 292 #endif /* KCF_TPM_RNG_PROVIDER */ 293 294 static void *statep = NULL; 295 296 /* 297 * Inline code to get exclusive lock on the TPM device and to make sure 298 * the device is not suspended. This grabs the primary TPM mutex (pm_mutex) 299 * and then checks the suspend status. If suspended, it will wait until 300 * the device is "resumed" before releasing the pm_mutex and continuing. 301 */ 302 #define TPM_EXCLUSIVE_LOCK(tpm) { \ 303 mutex_enter(&tpm->pm_mutex); \ 304 while (tpm->suspended) \ 305 cv_wait(&tpm->suspend_cv, &tpm->pm_mutex); \ 306 mutex_exit(&tpm->pm_mutex); } 307 308 /* 309 * TPM accessor functions 310 */ 311 #ifdef sun4v 312 313 extern uint64_t 314 hcall_tpm_get(uint64_t, uint64_t, uint64_t, uint64_t *); 315 316 extern uint64_t 317 hcall_tpm_put(uint64_t, uint64_t, uint64_t, uint64_t); 318 319 static inline uint8_t 320 tpm_get8(tpm_state_t *tpm, unsigned long offset) 321 { 322 uint64_t value; 323 324 ASSERT(tpm != NULL); 325 (void) hcall_tpm_get(tpm->locality, offset, sizeof (uint8_t), &value); 326 return ((uint8_t)value); 327 } 328 329 static inline uint32_t 330 tpm_get32(tpm_state_t *tpm, unsigned long offset) 331 { 332 uint64_t value; 333 334 ASSERT(tpm != NULL); 335 (void) hcall_tpm_get(tpm->locality, offset, sizeof (uint32_t), &value); 336 return ((uint32_t)value); 337 } 338 339 static inline void 340 tpm_put8(tpm_state_t *tpm, unsigned long offset, uint8_t value) 341 { 342 ASSERT(tpm != NULL); 343 (void) hcall_tpm_put(tpm->locality, offset, sizeof (uint8_t), value); 344 } 345 346 #else 347 348 static inline uint8_t 349 tpm_get8(tpm_state_t *tpm, unsigned long offset) 350 { 351 ASSERT(tpm != NULL); 352 353 return (ddi_get8(tpm->handle, 354 (uint8_t *)(TPM_LOCALITY_OFFSET(tpm->locality) | 355 (uintptr_t)tpm->addr + offset))); 356 } 357 358 static inline uint32_t 359 tpm_get32(tpm_state_t *tpm, unsigned long offset) 360 { 361 ASSERT(tpm != NULL); 362 return (ddi_get32(tpm->handle, 363 (uint32_t *)(TPM_LOCALITY_OFFSET(tpm->locality) | 364 (uintptr_t)tpm->addr + offset))); 365 } 366 367 static inline void 368 tpm_put8(tpm_state_t *tpm, unsigned long offset, uint8_t value) 369 { 370 ASSERT(tpm != NULL); 371 ddi_put8(tpm->handle, 372 (uint8_t *)(TPM_LOCALITY_OFFSET(tpm->locality) | 373 (uintptr_t)tpm->addr + offset), value); 374 } 375 376 #endif /* sun4v */ 377 378 /* 379 * TPM commands to get the TPM's properties, e.g.,timeout 380 */ 381 /*ARGSUSED*/ 382 static int 383 tpm_quiesce(dev_info_t *dip) 384 { 385 return (DDI_SUCCESS); 386 } 387 388 static uint32_t 389 load32(uchar_t *ptr, uint32_t offset) 390 { 391 uint32_t val; 392 bcopy(ptr + offset, &val, sizeof (uint32_t)); 393 394 return (ntohl(val)); 395 } 396 397 /* 398 * Get the actual timeouts supported by the TPM by issuing TPM_GetCapability 399 * with the subcommand TPM_CAP_PROP_TIS_TIMEOUT 400 * TPM_GetCapability (TPM Main Part 3 Rev. 94, pg.38) 401 */ 402 static int 403 tpm_get_timeouts(tpm_state_t *tpm) 404 { 405 int ret; 406 uint32_t timeout; /* in milliseconds */ 407 uint32_t len; 408 409 /* The buffer size (30) needs room for 4 timeout values (uint32_t) */ 410 uint8_t buf[30] = { 411 0, 193, /* TPM_TAG_RQU_COMMAND */ 412 0, 0, 0, 22, /* paramsize in bytes */ 413 0, 0, 0, 101, /* TPM_ORD_GetCapability */ 414 0, 0, 0, 5, /* TPM_CAP_Prop */ 415 0, 0, 0, 4, /* SUB_CAP size in bytes */ 416 0, 0, 1, 21 /* TPM_CAP_PROP_TIS_TIMEOUT(0x115) */ 417 }; 418 char *myname = "tpm_get_timeout"; 419 420 ASSERT(tpm != NULL); 421 422 ret = itpm_command(tpm, buf, sizeof (buf)); 423 if (ret != DDI_SUCCESS) { 424 #ifdef DEBUG 425 cmn_err(CE_WARN, "!%s: itpm_command failed", myname); 426 #endif 427 return (DDI_FAILURE); 428 } 429 430 /* 431 * Get the length of the returned buffer 432 * Make sure that there are 4 timeout values returned 433 * length of the capability response is stored in data[10-13] 434 * Also the TPM is in network byte order 435 */ 436 len = load32(buf, TPM_CAP_RESPSIZE_OFFSET); 437 if (len != 4 * sizeof (uint32_t)) { 438 #ifdef DEBUG 439 cmn_err(CE_WARN, "!%s: capability response size should be %d" 440 "instead len = %d", 441 myname, (int)(4 * sizeof (uint32_t)), (int)len); 442 #endif 443 return (DDI_FAILURE); 444 } 445 446 /* Get the four timeout's: a,b,c,d (they are 4 bytes long each) */ 447 timeout = load32(buf, TPM_CAP_TIMEOUT_A_OFFSET); 448 if (timeout == 0) { 449 timeout = DEFAULT_TIMEOUT_A; 450 } else if (timeout < TEN_MILLISECONDS) { 451 /* timeout is in millisecond range (should be microseconds) */ 452 timeout *= 1000; 453 } 454 tpm->timeout_a = drv_usectohz(timeout); 455 456 timeout = load32(buf, TPM_CAP_TIMEOUT_B_OFFSET); 457 if (timeout == 0) { 458 timeout = DEFAULT_TIMEOUT_B; 459 } else if (timeout < TEN_MILLISECONDS) { 460 /* timeout is in millisecond range (should be microseconds) */ 461 timeout *= 1000; 462 } 463 tpm->timeout_b = drv_usectohz(timeout); 464 465 timeout = load32(buf, TPM_CAP_TIMEOUT_C_OFFSET); 466 if (timeout == 0) { 467 timeout = DEFAULT_TIMEOUT_C; 468 } else if (timeout < TEN_MILLISECONDS) { 469 /* timeout is in millisecond range (should be microseconds) */ 470 timeout *= 1000; 471 } 472 tpm->timeout_c = drv_usectohz(timeout); 473 474 timeout = load32(buf, TPM_CAP_TIMEOUT_D_OFFSET); 475 if (timeout == 0) { 476 timeout = DEFAULT_TIMEOUT_D; 477 } else if (timeout < TEN_MILLISECONDS) { 478 /* timeout is in millisecond range (should be microseconds) */ 479 timeout *= 1000; 480 } 481 tpm->timeout_d = drv_usectohz(timeout); 482 483 return (DDI_SUCCESS); 484 } 485 486 /* 487 * Get the actual timeouts supported by the TPM by issuing TPM_GetCapability 488 * with the subcommand TPM_CAP_PROP_TIS_DURATION 489 * TPM_GetCapability (TPM Main Part 3 Rev. 94, pg.38) 490 */ 491 static int 492 tpm_get_duration(tpm_state_t *tpm) { 493 int ret; 494 uint32_t duration; 495 uint32_t len; 496 uint8_t buf[30] = { 497 0, 193, /* TPM_TAG_RQU_COMMAND */ 498 0, 0, 0, 22, /* paramsize in bytes */ 499 0, 0, 0, 101, /* TPM_ORD_GetCapability */ 500 0, 0, 0, 5, /* TPM_CAP_Prop */ 501 0, 0, 0, 4, /* SUB_CAP size in bytes */ 502 0, 0, 1, 32 /* TPM_CAP_PROP_TIS_DURATION(0x120) */ 503 }; 504 char *myname = "tpm_get_duration"; 505 506 ASSERT(tpm != NULL); 507 508 ret = itpm_command(tpm, buf, sizeof (buf)); 509 if (ret != DDI_SUCCESS) { 510 #ifdef DEBUG 511 cmn_err(CE_WARN, "!%s: itpm_command failed with ret code: 0x%x", 512 myname, ret); 513 #endif 514 return (DDI_FAILURE); 515 } 516 517 /* 518 * Get the length of the returned buffer 519 * Make sure that there are 3 duration values (S,M,L: in that order) 520 * length of the capability response is stored in data[10-13] 521 * Also the TPM is in network byte order 522 */ 523 len = load32(buf, TPM_CAP_RESPSIZE_OFFSET); 524 if (len != 3 * sizeof (uint32_t)) { 525 #ifdef DEBUG 526 cmn_err(CE_WARN, "!%s: capability response should be %d, " 527 "instead, it's %d", 528 myname, (int)(3 * sizeof (uint32_t)), (int)len); 529 #endif 530 return (DDI_FAILURE); 531 } 532 533 duration = load32(buf, TPM_CAP_DUR_SHORT_OFFSET); 534 if (duration == 0) { 535 duration = DEFAULT_SHORT_DURATION; 536 } else if (duration < TEN_MILLISECONDS) { 537 duration *= 1000; 538 } 539 tpm->duration[TPM_SHORT] = drv_usectohz(duration); 540 541 duration = load32(buf, TPM_CAP_DUR_MEDIUM_OFFSET); 542 if (duration == 0) { 543 duration = DEFAULT_MEDIUM_DURATION; 544 } else if (duration < TEN_MILLISECONDS) { 545 duration *= 1000; 546 } 547 tpm->duration[TPM_MEDIUM] = drv_usectohz(duration); 548 549 duration = load32(buf, TPM_CAP_DUR_LONG_OFFSET); 550 if (duration == 0) { 551 duration = DEFAULT_LONG_DURATION; 552 } else if (duration < FOUR_HUNDRED_MILLISECONDS) { 553 duration *= 1000; 554 } 555 tpm->duration[TPM_LONG] = drv_usectohz(duration); 556 557 /* Just make the undefined duration be the same as the LONG */ 558 tpm->duration[TPM_UNDEFINED] = tpm->duration[TPM_LONG]; 559 560 return (DDI_SUCCESS); 561 } 562 563 /* 564 * Get the actual timeouts supported by the TPM by issuing TPM_GetCapability 565 * with the subcommand TPM_CAP_PROP_TIS_DURATION 566 * TPM_GetCapability (TPM Main Part 3 Rev. 94, pg.38) 567 */ 568 static int 569 tpm_get_version(tpm_state_t *tpm) { 570 int ret; 571 uint32_t len; 572 char vendorId[5]; 573 /* If this buf is too small, the "vendor specific" data won't fit */ 574 uint8_t buf[64] = { 575 0, 193, /* TPM_TAG_RQU_COMMAND */ 576 0, 0, 0, 18, /* paramsize in bytes */ 577 0, 0, 0, 101, /* TPM_ORD_GetCapability */ 578 0, 0, 0, 0x1A, /* TPM_CAP_VERSION_VAL */ 579 0, 0, 0, 0, /* SUB_CAP size in bytes */ 580 }; 581 char *myname = "tpm_get_version"; 582 583 ASSERT(tpm != NULL); 584 585 ret = itpm_command(tpm, buf, sizeof (buf)); 586 if (ret != DDI_SUCCESS) { 587 #ifdef DEBUG 588 cmn_err(CE_WARN, "!%s: itpm_command failed with ret code: 0x%x", 589 myname, ret); 590 #endif 591 return (DDI_FAILURE); 592 } 593 594 /* 595 * Get the length of the returned buffer. 596 */ 597 len = load32(buf, TPM_CAP_RESPSIZE_OFFSET); 598 if (len < TPM_CAP_VERSION_INFO_SIZE) { 599 #ifdef DEBUG 600 cmn_err(CE_WARN, "!%s: capability response should be greater" 601 " than %d, instead, it's %d", 602 myname, TPM_CAP_VERSION_INFO_SIZE, len); 603 #endif 604 return (DDI_FAILURE); 605 } 606 607 bcopy(buf + TPM_CAP_VERSION_INFO_OFFSET, &tpm->vers_info, 608 TPM_CAP_VERSION_INFO_SIZE); 609 610 bcopy(tpm->vers_info.tpmVendorID, vendorId, 611 sizeof (tpm->vers_info.tpmVendorID)); 612 vendorId[4] = '\0'; 613 614 cmn_err(CE_NOTE, "!TPM found: Ver %d.%d, Rev %d.%d, " 615 "SpecLevel %d, errataRev %d, VendorId '%s'", 616 tpm->vers_info.version.major, /* Version */ 617 tpm->vers_info.version.minor, 618 tpm->vers_info.version.revMajor, /* Revision */ 619 tpm->vers_info.version.revMinor, 620 (int)ntohs(tpm->vers_info.specLevel), 621 tpm->vers_info.errataRev, 622 vendorId); 623 624 /* 625 * This driver only supports TPM Version 1.2 626 */ 627 if (tpm->vers_info.version.major != 1 && 628 tpm->vers_info.version.minor != 2) { 629 cmn_err(CE_WARN, "!%s: Unsupported TPM version (%d.%d)", 630 myname, 631 tpm->vers_info.version.major, /* Version */ 632 tpm->vers_info.version.minor); 633 return (DDI_FAILURE); 634 } 635 636 return (DDI_SUCCESS); 637 } 638 639 /* 640 * To prevent the TPM from complaining that certain functions are not tested 641 * we run this command when the driver attaches. 642 * For details see Section 4.2 of TPM Main Part 3 Command Specification 643 */ 644 static int 645 tpm_continue_selftest(tpm_state_t *tpm) { 646 int ret; 647 uint8_t buf[10] = { 648 0, 193, /* TPM_TAG_RQU COMMAND */ 649 0, 0, 0, 10, /* paramsize in bytes */ 650 0, 0, 0, 83 /* TPM_ORD_ContinueSelfTest */ 651 }; 652 char *myname = "tpm_continue_selftest"; 653 654 /* Need a longer timeout */ 655 ret = itpm_command(tpm, buf, sizeof (buf)); 656 if (ret != DDI_SUCCESS) { 657 #ifdef DEBUG 658 cmn_err(CE_WARN, "!%s: itpm_command failed", myname); 659 #endif 660 return (DDI_FAILURE); 661 } 662 663 return (DDI_SUCCESS); 664 } 665 /* 666 * Auxilary Functions 667 */ 668 669 /* 670 * Find out how long we should wait for the TPM command to complete a command 671 */ 672 static clock_t 673 tpm_get_ordinal_duration(tpm_state_t *tpm, uint8_t ordinal) 674 { 675 uint8_t index; 676 char *myname = "tpm_get_ordinal_duration"; 677 678 ASSERT(tpm != NULL); 679 680 /* Default and failure case for IFX */ 681 /* Is it a TSC_ORDINAL? */ 682 if (ordinal & TSC_ORDINAL_MASK) { 683 if (ordinal > TSC_ORDINAL_MAX) { 684 #ifdef DEBUG 685 cmn_err(CE_WARN, 686 "!%s: tsc ordinal: %d exceeds MAX: %d", 687 myname, ordinal, TSC_ORDINAL_MAX); 688 #endif 689 return (0); 690 } 691 index = tsc_ords_duration[ordinal]; 692 } else { 693 if (ordinal > TPM_ORDINAL_MAX) { 694 #ifdef DEBUG 695 cmn_err(CE_WARN, 696 "!%s: ordinal %d exceeds MAX: %d", 697 myname, ordinal, TPM_ORDINAL_MAX); 698 #endif 699 return (0); 700 } 701 index = tpm_ords_duration[ordinal]; 702 } 703 704 if (index > TPM_DURATION_MAX_IDX) { 705 #ifdef DEBUG 706 cmn_err(CE_WARN, "!%s: duration index '%d' is out of bounds", 707 myname, index); 708 #endif 709 return (0); 710 } 711 return (tpm->duration[index]); 712 } 713 714 /* 715 * Internal TPM Transmit Function: 716 * Calls implementation specific sendto and receive 717 * The code assumes that the buffer is in network byte order 718 */ 719 static int 720 itpm_command(tpm_state_t *tpm, uint8_t *buf, size_t bufsiz) 721 { 722 int ret; 723 uint32_t count; 724 char *myname = "itpm_command"; 725 726 ASSERT(tpm != NULL && buf != NULL); 727 728 /* The byte order is network byte order so convert it */ 729 count = load32(buf, TPM_PARAMSIZE_OFFSET); 730 731 if (count == 0 || (count > bufsiz)) { 732 #ifdef DEBUG 733 cmn_err(CE_WARN, "!%s: invalid byte count value " 734 "(%d > bufsiz %d)", myname, (int)count, (int)bufsiz); 735 #endif 736 return (DDI_FAILURE); 737 } 738 739 /* Send the command */ 740 ret = tis_send_data(tpm, buf, count); 741 if (ret != DDI_SUCCESS) { 742 #ifdef DEBUG 743 cmn_err(CE_WARN, "!%s: tis_send_data failed with error %x", 744 myname, ret); 745 #endif 746 return (DDI_FAILURE); 747 } 748 749 /* 750 * Now receive the data from the tpm 751 * Should at least receive "the common" 10 bytes (TPM_HEADER_SIZE) 752 */ 753 ret = tis_recv_data(tpm, buf, bufsiz); 754 if (ret < TPM_HEADER_SIZE) { 755 #ifdef DEBUG 756 cmn_err(CE_WARN, "!%s: tis_recv_data failed", myname); 757 #endif 758 return (DDI_FAILURE); 759 } 760 761 /* Check the return code */ 762 ret = load32(buf, TPM_RETURN_OFFSET); 763 if (ret != TPM_SUCCESS) { 764 if (ret == TPM_E_DEACTIVATED) 765 cmn_err(CE_WARN, "!%s: TPM is deactivated", myname); 766 else if (ret == TPM_E_DISABLED) 767 cmn_err(CE_WARN, "!%s: TPM is disabled", myname); 768 else 769 cmn_err(CE_WARN, "!%s: TPM error code 0x%0x", 770 myname, ret); 771 return (DDI_FAILURE); 772 } 773 774 return (DDI_SUCCESS); 775 } 776 777 /* 778 * Whenever the driver wants to write to the DATA_IO register, it must need 779 * to figure out the burstcount. This is the amount of bytes it can write 780 * before having to wait for long LPC bus cycle 781 * 782 * Returns: 0 if error, burst count if sucess 783 */ 784 static uint16_t 785 tpm_get_burstcount(tpm_state_t *tpm) { 786 clock_t stop; 787 uint16_t burstcnt; 788 789 ASSERT(tpm != NULL); 790 791 /* 792 * Spec says timeout should be TIMEOUT_D 793 * burst count is TPM_STS bits 8..23 794 */ 795 stop = ddi_get_lbolt() + tpm->timeout_d; 796 do { 797 /* 798 * burstcnt is stored as a little endian value 799 * 'ntohs' doesn't work since the value is not word-aligned 800 */ 801 burstcnt = tpm_get8(tpm, TPM_STS + 1); 802 burstcnt += tpm_get8(tpm, TPM_STS + 2) << 8; 803 804 if (burstcnt) 805 return (burstcnt); 806 807 delay(tpm->timeout_poll); 808 } while (ddi_get_lbolt() < stop); 809 810 return (0); 811 } 812 813 /* 814 * Writing 1 to TPM_STS_CMD_READY bit in TPM_STS will do the following: 815 * 1. The TPM will clears IO buffers if any 816 * 2. The TPM will enters either Idle or Ready state within TIMEOUT_B 817 * (checked in the calling function) 818 */ 819 static void 820 tpm_set_ready(tpm_state_t *tpm) { 821 tpm_put8(tpm, TPM_STS, TPM_STS_CMD_READY); 822 } 823 824 static int 825 receive_data(tpm_state_t *tpm, uint8_t *buf, size_t bufsiz) { 826 int size = 0; 827 int retried = 0; 828 uint8_t stsbits; 829 830 /* A number of consecutive bytes that can be written to TPM */ 831 uint16_t burstcnt; 832 833 ASSERT(tpm != NULL && buf != NULL); 834 retry: 835 while (size < bufsiz && 836 (tpm_wait_for_stat(tpm, 837 (TPM_STS_DATA_AVAIL|TPM_STS_VALID), 838 tpm->timeout_c) == DDI_SUCCESS)) { 839 /* 840 * Burstcount should be available within TIMEOUT_D 841 * after STS is set to valid 842 * burstcount is dynamic, so have to get it each time 843 */ 844 burstcnt = tpm_get_burstcount(tpm); 845 for (; burstcnt > 0 && size < bufsiz; burstcnt--) { 846 buf[size++] = tpm_get8(tpm, TPM_DATA_FIFO); 847 } 848 } 849 stsbits = tis_get_status(tpm); 850 /* check to see if we need to retry (just once) */ 851 if (size < bufsiz && !(stsbits & TPM_STS_DATA_AVAIL) && retried == 0) { 852 /* issue responseRetry (TIS 1.2 pg 54) */ 853 tpm_put8(tpm, TPM_STS, TPM_STS_RESPONSE_RETRY); 854 /* update the retry counter so we only retry once */ 855 retried++; 856 /* reset the size to 0 and reread the entire response */ 857 size = 0; 858 goto retry; 859 } 860 return (size); 861 } 862 863 /* Receive the data from the TPM */ 864 static int 865 tis_recv_data(tpm_state_t *tpm, uint8_t *buf, size_t bufsiz) { 866 int ret; 867 int size = 0; 868 uint32_t expected, status; 869 uint32_t cmdresult; 870 char *myname = "tis_recv_data"; 871 872 ASSERT(tpm != NULL && buf != NULL); 873 874 if (bufsiz < TPM_HEADER_SIZE) { 875 /* There should be at least tag, paramsize, return code */ 876 #ifdef DEBUG 877 cmn_err(CE_WARN, "!%s: received data should contain at least " 878 "the header which is %d bytes long", 879 myname, TPM_HEADER_SIZE); 880 #endif 881 goto OUT; 882 } 883 884 /* Read tag(2 bytes), paramsize(4), and result(4) */ 885 size = receive_data(tpm, buf, TPM_HEADER_SIZE); 886 if (size < TPM_HEADER_SIZE) { 887 #ifdef DEBUG 888 cmn_err(CE_WARN, "!%s: recv TPM_HEADER failed, size = %d", 889 myname, size); 890 #endif 891 goto OUT; 892 } 893 894 cmdresult = load32(buf, TPM_RETURN_OFFSET); 895 896 /* Get 'paramsize'(4 bytes)--it includes tag and paramsize */ 897 expected = load32(buf, TPM_PARAMSIZE_OFFSET); 898 if (expected > bufsiz) { 899 #ifdef DEBUG 900 cmn_err(CE_WARN, "!%s: paramSize is bigger " 901 "than the requested size: paramSize=%d bufsiz=%d result=%d", 902 myname, (int)expected, (int)bufsiz, cmdresult); 903 #endif 904 goto OUT; 905 } 906 907 /* Read in the rest of the data from the TPM */ 908 size += receive_data(tpm, (uint8_t *)&buf[TPM_HEADER_SIZE], 909 expected - TPM_HEADER_SIZE); 910 if (size < expected) { 911 #ifdef DEBUG 912 cmn_err(CE_WARN, "!%s: received data length (%d) " 913 "is less than expected (%d)", myname, size, expected); 914 #endif 915 goto OUT; 916 } 917 918 /* The TPM MUST set the state to stsValid within TIMEOUT_C */ 919 ret = tpm_wait_for_stat(tpm, TPM_STS_VALID, tpm->timeout_c); 920 921 status = tis_get_status(tpm); 922 if (ret != DDI_SUCCESS) { 923 #ifdef DEBUG 924 cmn_err(CE_WARN, "!%s: TPM didn't set stsValid after its I/O: " 925 "status = 0x%08X", myname, status); 926 #endif 927 goto OUT; 928 } 929 930 /* There is still more data? */ 931 if (status & TPM_STS_DATA_AVAIL) { 932 #ifdef DEBUG 933 cmn_err(CE_WARN, "!%s: TPM_STS_DATA_AVAIL is set:0x%08X", 934 myname, status); 935 #endif 936 goto OUT; 937 } 938 939 /* 940 * Release the control of the TPM after we are done with it 941 * it...so others can also get a chance to send data 942 */ 943 tis_release_locality(tpm, tpm->locality, 0); 944 945 OUT: 946 tpm_set_ready(tpm); 947 tis_release_locality(tpm, tpm->locality, 0); 948 return (size); 949 } 950 951 /* 952 * Send the data (TPM commands) to the Data IO register 953 */ 954 static int 955 tis_send_data(tpm_state_t *tpm, uint8_t *buf, size_t bufsiz) { 956 int ret; 957 uint8_t status; 958 uint16_t burstcnt; 959 uint32_t ordinal; 960 size_t count = 0; 961 char *myname = "tis_send_data"; 962 963 ASSERT(tpm != NULL && buf != NULL); 964 965 if (bufsiz == 0) { 966 #ifdef DEBUG 967 cmn_err(CE_WARN, "!%s: bufsiz arg is zero", myname); 968 #endif 969 return (DDI_FAILURE); 970 } 971 972 /* Put the TPM in ready state */ 973 status = tis_get_status(tpm); 974 975 if (!(status & TPM_STS_CMD_READY)) { 976 tpm_set_ready(tpm); 977 ret = tpm_wait_for_stat(tpm, TPM_STS_CMD_READY, tpm->timeout_b); 978 if (ret != DDI_SUCCESS) { 979 #ifdef DEBUG 980 cmn_err(CE_WARN, "!%s: could not put the TPM " 981 "in the command ready state:" 982 "tpm_wait_for_stat returned error", 983 myname); 984 #endif 985 goto FAIL; 986 } 987 } 988 989 /* 990 * Now we are ready to send command 991 * TPM's burstcount dictates how many bytes we can write at a time 992 * Burstcount is dynamic if INTF_CAPABILITY for static burstcount is 993 * not set. 994 */ 995 while (count < bufsiz - 1) { 996 burstcnt = tpm_get_burstcount(tpm); 997 if (burstcnt == 0) { 998 #ifdef DEBUG 999 cmn_err(CE_WARN, "!%s: tpm_get_burstcnt returned error", 1000 myname); 1001 #endif 1002 ret = DDI_FAILURE; 1003 goto FAIL; 1004 } 1005 1006 for (; burstcnt > 0 && count < bufsiz - 1; burstcnt--) { 1007 tpm_put8(tpm, TPM_DATA_FIFO, buf[count]); 1008 count++; 1009 } 1010 /* Wait for TPM to indicate that it is ready for more data */ 1011 ret = tpm_wait_for_stat(tpm, 1012 (TPM_STS_VALID | TPM_STS_DATA_EXPECT), tpm->timeout_c); 1013 if (ret != DDI_SUCCESS) { 1014 #ifdef DEBUG 1015 cmn_err(CE_WARN, "!%s: TPM didn't enter STS_VALID " 1016 "state", myname); 1017 #endif 1018 goto FAIL; 1019 } 1020 } 1021 /* We can't exit the loop above unless we wrote bufsiz-1 bytes */ 1022 1023 /* Write last byte */ 1024 tpm_put8(tpm, TPM_DATA_FIFO, buf[count]); 1025 count++; 1026 1027 /* Wait for the TPM to enter Valid State */ 1028 ret = tpm_wait_for_stat(tpm, TPM_STS_VALID, tpm->timeout_c); 1029 if (ret == DDI_FAILURE) { 1030 #ifdef DEBUG 1031 cmn_err(CE_WARN, "!%s: tpm didn't enter STS_VALID state", 1032 myname); 1033 #endif 1034 goto FAIL; 1035 } 1036 1037 status = tis_get_status(tpm); 1038 /* The TPM should NOT be expecing more data at this point */ 1039 if ((status & TPM_STS_DATA_EXPECT) != 0) { 1040 #ifdef DEBUG 1041 cmn_err(CE_WARN, "!%s: DATA_EXPECT should not be set after " 1042 "writing the last byte: status=0x%08X", myname, status); 1043 #endif 1044 ret = DDI_FAILURE; 1045 goto FAIL; 1046 } 1047 1048 /* 1049 * Final step: Writing TPM_STS_GO to TPM_STS 1050 * register will actually send the command. 1051 */ 1052 tpm_put8(tpm, TPM_STS, TPM_STS_GO); 1053 1054 /* Ordinal/Command_code is located in buf[6..9] */ 1055 ordinal = load32(buf, TPM_COMMAND_CODE_OFFSET); 1056 1057 ret = tpm_wait_for_stat(tpm, TPM_STS_DATA_AVAIL | TPM_STS_VALID, 1058 tpm_get_ordinal_duration(tpm, ordinal)); 1059 if (ret == DDI_FAILURE) { 1060 #ifdef DEBUG 1061 status = tis_get_status(tpm); 1062 if (!(status & TPM_STS_DATA_AVAIL) || 1063 !(status & TPM_STS_VALID)) { 1064 cmn_err(CE_WARN, "!%s: TPM not ready or valid " 1065 "(ordinal = %d timeout = %ld status = 0x%0x)", 1066 myname, ordinal, 1067 tpm_get_ordinal_duration(tpm, ordinal), 1068 status); 1069 } else { 1070 cmn_err(CE_WARN, "!%s: tpm_wait_for_stat " 1071 "(DATA_AVAIL | VALID) failed status = 0x%0X", 1072 myname, status); 1073 } 1074 #endif 1075 goto FAIL; 1076 } 1077 return (DDI_SUCCESS); 1078 1079 FAIL: 1080 tpm_set_ready(tpm); 1081 tis_release_locality(tpm, tpm->locality, 0); 1082 return (ret); 1083 } 1084 1085 /* 1086 * Clear XrequestUse and Xactivelocality, where X is the current locality 1087 */ 1088 static void 1089 tis_release_locality(tpm_state_t *tpm, char locality, int force) { 1090 ASSERT(tpm != NULL && locality >= 0 && locality < 5); 1091 1092 if (force || 1093 (tpm_get8(tpm, TPM_ACCESS) & 1094 (TPM_ACCESS_REQUEST_PENDING | TPM_ACCESS_VALID)) == 1095 (TPM_ACCESS_REQUEST_PENDING | TPM_ACCESS_VALID)) { 1096 /* 1097 * Writing 1 to active locality bit in TPM_ACCESS 1098 * register reliquishes the control of the locality 1099 */ 1100 tpm_put8(tpm, TPM_ACCESS, TPM_ACCESS_ACTIVE_LOCALITY); 1101 } 1102 } 1103 1104 /* 1105 * Checks whether the given locality is active 1106 * Use TPM_ACCESS register and the masks TPM_ACCESS_VALID,TPM_ACTIVE_LOCALITY 1107 */ 1108 static int 1109 tis_check_active_locality(tpm_state_t *tpm, char locality) { 1110 uint8_t access_bits; 1111 uint8_t old_locality; 1112 1113 ASSERT(tpm != NULL && locality >= 0 && locality < 5); 1114 1115 old_locality = tpm->locality; 1116 tpm->locality = locality; 1117 1118 /* Just check to see if the requested locality works */ 1119 access_bits = tpm_get8(tpm, TPM_ACCESS); 1120 access_bits &= (TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID); 1121 1122 /* this was just a check, not a request to switch */ 1123 tpm->locality = old_locality; 1124 1125 if (access_bits == (TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID)) { 1126 return (DDI_SUCCESS); 1127 } else { 1128 return (DDI_FAILURE); 1129 } 1130 } 1131 1132 /* Request the TPM to be in the given locality */ 1133 static int 1134 tis_request_locality(tpm_state_t *tpm, char locality) { 1135 clock_t timeout; 1136 int ret; 1137 char *myname = "tis_request_locality"; 1138 1139 ASSERT(tpm != NULL && locality >= 0 && locality < 5); 1140 1141 ret = tis_check_active_locality(tpm, locality); 1142 1143 if (ret == DDI_SUCCESS) { 1144 /* Locality is already active */ 1145 tpm->locality = locality; 1146 return (DDI_SUCCESS); 1147 } 1148 1149 tpm_put8(tpm, TPM_ACCESS, TPM_ACCESS_REQUEST_USE); 1150 timeout = ddi_get_lbolt() + tpm->timeout_a; 1151 1152 /* Using polling */ 1153 while (tis_check_active_locality(tpm, locality) 1154 != DDI_SUCCESS) { 1155 if (ddi_get_lbolt() >= timeout) { 1156 #ifdef DEBUG 1157 cmn_err(CE_WARN, "!%s: (interrupt-disabled) " 1158 "tis_request_locality timed out (timeout_a = %ld)", 1159 myname, tpm->timeout_a); 1160 #endif 1161 return (DDI_FAILURE); 1162 } 1163 delay(tpm->timeout_poll); 1164 } 1165 1166 tpm->locality = locality; 1167 return (DDI_SUCCESS); 1168 } 1169 1170 /* Read the status register */ 1171 static uint8_t 1172 tis_get_status(tpm_state_t *tpm) { 1173 return (tpm_get8(tpm, TPM_STS)); 1174 } 1175 1176 static int 1177 tpm_wait_for_stat(tpm_state_t *tpm, uint8_t mask, clock_t timeout) { 1178 char *myname = "tpm_wait_for_stat"; 1179 clock_t absolute_timeout = ddi_get_lbolt() + timeout; 1180 1181 /* Using polling */ 1182 while ((tis_get_status(tpm) & mask) != mask) { 1183 if (ddi_get_lbolt() >= absolute_timeout) { 1184 /* Timeout reached */ 1185 #ifdef DEBUG 1186 cmn_err(CE_WARN, "!%s: using " 1187 "polling - reached timeout (%ld usecs)", 1188 myname, drv_hztousec(timeout)); 1189 #endif 1190 return (DDI_FAILURE); 1191 } 1192 delay(tpm->timeout_poll); 1193 } 1194 return (DDI_SUCCESS); 1195 } 1196 1197 /* 1198 * Initialize TPM device 1199 * 1. Find out supported interrupt capabilities 1200 * 2. Set up interrupt handler if supported (some BIOSes don't support 1201 * interrupts for TPMS, in which case we set up polling) 1202 * 3. Determine timeouts and commands duration 1203 */ 1204 static int 1205 tis_init(tpm_state_t *tpm) { 1206 uint32_t intf_caps; 1207 int ret; 1208 char *myname = "tis_init"; 1209 1210 /* 1211 * Temporarily set up timeouts before we get the real timeouts 1212 * by issuing TPM_CAP commands (but to issue TPM_CAP commands, 1213 * you need TIMEOUTs defined...chicken and egg problem here. 1214 * TPM timeouts: Convert the milliseconds to clock cycles 1215 */ 1216 tpm->timeout_a = drv_usectohz(TIS_TIMEOUT_A); 1217 tpm->timeout_b = drv_usectohz(TIS_TIMEOUT_B); 1218 tpm->timeout_c = drv_usectohz(TIS_TIMEOUT_C); 1219 tpm->timeout_d = drv_usectohz(TIS_TIMEOUT_D); 1220 /* 1221 * Do the same with the duration (real duration will be filled out 1222 * when we call TPM_GetCapability to get the duration values from 1223 * the TPM itself). 1224 */ 1225 tpm->duration[TPM_SHORT] = drv_usectohz(TPM_DEFAULT_DURATION); 1226 tpm->duration[TPM_MEDIUM] = drv_usectohz(TPM_DEFAULT_DURATION); 1227 tpm->duration[TPM_LONG] = drv_usectohz(TPM_DEFAULT_DURATION); 1228 tpm->duration[TPM_UNDEFINED] = drv_usectohz(TPM_DEFAULT_DURATION); 1229 1230 /* Find out supported capabilities */ 1231 intf_caps = tpm_get32(tpm, TPM_INTF_CAP); 1232 1233 /* Upper 3 bytes should always return 0 */ 1234 if (intf_caps & 0x7FFFFF00) { 1235 cmn_err(CE_WARN, "!%s: bad intf_caps value 0x%0X", 1236 myname, intf_caps); 1237 return (DDI_FAILURE); 1238 } 1239 1240 /* These two interrupts are mandatory */ 1241 if (!(intf_caps & TPM_INTF_INT_LOCALITY_CHANGE_INT)) { 1242 cmn_err(CE_WARN, 1243 "!%s: Mandatory capability Locality Change Int " 1244 "not supported", myname); 1245 return (DDI_FAILURE); 1246 } 1247 if (!(intf_caps & TPM_INTF_INT_DATA_AVAIL_INT)) { 1248 cmn_err(CE_WARN, "!%s: Mandatory capability Data Available Int " 1249 "not supported.", myname); 1250 return (DDI_FAILURE); 1251 } 1252 1253 /* 1254 * Before we start writing anything to TPM's registers, 1255 * make sure we are in locality 0 1256 */ 1257 ret = tis_request_locality(tpm, DEFAULT_LOCALITY); 1258 if (ret != DDI_SUCCESS) { 1259 cmn_err(CE_WARN, "!%s: Unable to request locality %d", myname, 1260 DEFAULT_LOCALITY); 1261 return (DDI_FAILURE); 1262 } /* Now we can refer to the locality as tpm->locality */ 1263 1264 tpm->timeout_poll = drv_usectohz(TPM_POLLING_TIMEOUT); 1265 tpm->intr_enabled = 0; 1266 1267 /* Get the real timeouts from the TPM */ 1268 ret = tpm_get_timeouts(tpm); 1269 if (ret != DDI_SUCCESS) { 1270 cmn_err(CE_WARN, "!%s: tpm_get_timeouts error", myname); 1271 return (DDI_FAILURE); 1272 } 1273 1274 ret = tpm_get_duration(tpm); 1275 if (ret != DDI_SUCCESS) { 1276 cmn_err(CE_WARN, "!%s: tpm_get_duration error", myname); 1277 return (DDI_FAILURE); 1278 } 1279 1280 /* This gets the TPM version information */ 1281 ret = tpm_get_version(tpm); 1282 if (ret != DDI_SUCCESS) { 1283 cmn_err(CE_WARN, "!%s: tpm_get_version error", myname); 1284 return (DDI_FAILURE); 1285 } 1286 1287 /* 1288 * Unless the TPM completes the test of its commands, 1289 * it can return an error when the untested commands are called 1290 */ 1291 ret = tpm_continue_selftest(tpm); 1292 if (ret != DDI_SUCCESS) { 1293 cmn_err(CE_WARN, "!%s: tpm_continue_selftest error", myname); 1294 return (DDI_FAILURE); 1295 } 1296 return (DDI_SUCCESS); 1297 } 1298 1299 /* 1300 * Module Entry points 1301 */ 1302 int 1303 _init(void) 1304 { 1305 int ret; 1306 1307 ret = ddi_soft_state_init(&statep, sizeof (tpm_state_t), 1); 1308 if (ret) { 1309 #ifdef DEBUG 1310 cmn_err(CE_WARN, "!ddi_soft_state_init failed: %d", ret); 1311 #endif 1312 return (ret); 1313 } 1314 ret = mod_install(&tpm_ml); 1315 if (ret != 0) { 1316 #ifdef DEBUG 1317 cmn_err(CE_WARN, "!_init: mod_install returned non-zero"); 1318 #endif 1319 ddi_soft_state_fini(&statep); 1320 return (ret); 1321 } 1322 1323 return (ret); 1324 } 1325 1326 int 1327 _info(struct modinfo *modinfop) 1328 { 1329 int ret; 1330 ret = mod_info(&tpm_ml, modinfop); 1331 #ifdef DEBUG 1332 if (ret == 0) 1333 cmn_err(CE_WARN, "!mod_info failed: %d", ret); 1334 #endif 1335 1336 return (ret); 1337 } 1338 1339 int 1340 _fini() 1341 { 1342 int ret; 1343 1344 ret = mod_remove(&tpm_ml); 1345 if (ret != 0) 1346 return (ret); 1347 1348 ddi_soft_state_fini(&statep); 1349 1350 return (ret); 1351 } 1352 /* End of driver configuration functions */ 1353 1354 static int 1355 tpm_resume(tpm_state_t *tpm) 1356 { 1357 mutex_enter(&tpm->pm_mutex); 1358 if (!tpm->suspended) { 1359 mutex_exit(&tpm->pm_mutex); 1360 return (DDI_FAILURE); 1361 } 1362 tpm->suspended = 0; 1363 cv_broadcast(&tpm->suspend_cv); 1364 mutex_exit(&tpm->pm_mutex); 1365 1366 return (DDI_SUCCESS); 1367 } 1368 1369 #ifdef sun4v 1370 static uint64_t hsvc_tpm_minor = 0; 1371 static hsvc_info_t hsvc_tpm = { 1372 HSVC_REV_1, NULL, HSVC_GROUP_TPM, 1, 0, NULL 1373 }; 1374 #endif 1375 1376 /* 1377 * Sun DDI/DDK entry points 1378 */ 1379 static int 1380 tpm_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) 1381 { 1382 int ret; 1383 int instance; 1384 #ifndef sun4v 1385 int idx, nregs; 1386 #endif 1387 char *myname = "tpm_attach"; 1388 tpm_state_t *tpm = NULL; 1389 1390 ASSERT(dip != NULL); 1391 1392 instance = ddi_get_instance(dip); 1393 if (instance < 0) 1394 return (DDI_FAILURE); 1395 1396 /* Nothing out of ordinary here */ 1397 switch (cmd) { 1398 case DDI_ATTACH: 1399 if (ddi_soft_state_zalloc(statep, instance) == DDI_SUCCESS) { 1400 tpm = ddi_get_soft_state(statep, instance); 1401 if (tpm == NULL) { 1402 #ifdef DEBUG 1403 cmn_err(CE_WARN, 1404 "!%s: cannot get state information.", 1405 myname); 1406 #endif 1407 return (DDI_FAILURE); 1408 } 1409 tpm->dip = dip; 1410 } else { 1411 #ifdef DEBUG 1412 cmn_err(CE_WARN, 1413 "!%s: cannot allocate state information.", 1414 myname); 1415 #endif 1416 return (DDI_FAILURE); 1417 } 1418 break; 1419 case DDI_RESUME: 1420 tpm = ddi_get_soft_state(statep, instance); 1421 if (tpm == NULL) { 1422 #ifdef DEBUG 1423 cmn_err(CE_WARN, "!%s: cannot get state information.", 1424 myname); 1425 #endif 1426 return (DDI_FAILURE); 1427 } 1428 return (tpm_resume(tpm)); 1429 default: 1430 #ifdef DEBUG 1431 cmn_err(CE_WARN, "!%s: cmd %d is not implemented", myname, cmd); 1432 #endif 1433 ret = DDI_FAILURE; 1434 goto FAIL; 1435 } 1436 1437 /* Zeroize the flag, which is used to keep track of what is allocated */ 1438 tpm->flags = 0; 1439 1440 #ifdef sun4v 1441 ret = hsvc_register(&hsvc_tpm, &hsvc_tpm_minor); 1442 if (ret != 0) { 1443 cmn_err(CE_WARN, "!%s: failed to register with " 1444 "hypervisor: 0x%0x", myname, ret); 1445 goto FAIL; 1446 } 1447 tpm->flags |= TPM_HSVC_REGISTERED; 1448 #else 1449 tpm->accattr.devacc_attr_version = DDI_DEVICE_ATTR_V0; 1450 tpm->accattr.devacc_attr_endian_flags = DDI_NEVERSWAP_ACC; 1451 tpm->accattr.devacc_attr_dataorder = DDI_STRICTORDER_ACC; 1452 1453 idx = 0; 1454 ret = ddi_dev_nregs(tpm->dip, &nregs); 1455 if (ret != DDI_SUCCESS) 1456 goto FAIL; 1457 1458 /* 1459 * TPM vendors put the TPM registers in different 1460 * slots in their register lists. They are not always 1461 * the 1st set of registers, for instance. 1462 * Loop until we find the set that matches the expected 1463 * register size (0x5000). 1464 */ 1465 for (idx = 0; idx < nregs; idx++) { 1466 off_t regsize; 1467 1468 if ((ret = ddi_dev_regsize(tpm->dip, idx, ®size)) != 1469 DDI_SUCCESS) 1470 goto FAIL; 1471 /* The TIS spec says the TPM registers must be 0x5000 bytes */ 1472 if (regsize == 0x5000) 1473 break; 1474 } 1475 if (idx == nregs) { 1476 ret = DDI_FAILURE; 1477 goto FAIL; 1478 } 1479 1480 ret = ddi_regs_map_setup(tpm->dip, idx, (caddr_t *)&tpm->addr, 1481 (offset_t)0, (offset_t)0x5000, 1482 &tpm->accattr, &tpm->handle); 1483 1484 if (ret != DDI_SUCCESS) { 1485 goto FAIL; 1486 } 1487 tpm->flags |= TPM_DIDREGSMAP; 1488 #endif 1489 /* Enable TPM device according to the TIS specification */ 1490 ret = tis_init(tpm); 1491 if (ret != DDI_SUCCESS) { 1492 #ifdef DEBUG 1493 cmn_err(CE_WARN, "!%s: tis_init() failed with error %d", 1494 myname, ret); 1495 #endif 1496 1497 /* We need to clean up the ddi_regs_map_setup call */ 1498 if (tpm->flags & TPM_DIDREGSMAP) { 1499 ddi_regs_map_free(&tpm->handle); 1500 tpm->handle = NULL; 1501 tpm->flags &= ~TPM_DIDREGSMAP; 1502 } 1503 goto FAIL; 1504 } 1505 1506 /* Initialize the inter-process lock */ 1507 mutex_init(&tpm->dev_lock, NULL, MUTEX_DRIVER, NULL); 1508 mutex_init(&tpm->pm_mutex, NULL, MUTEX_DRIVER, NULL); 1509 cv_init(&tpm->suspend_cv, NULL, CV_DRIVER, NULL); 1510 1511 /* Set the suspend/resume property */ 1512 (void) ddi_prop_update_string(DDI_DEV_T_NONE, dip, 1513 "pm-hardware-state", "needs-suspend-resume"); 1514 1515 mutex_enter(&tpm->pm_mutex); 1516 tpm->suspended = 0; 1517 mutex_exit(&tpm->pm_mutex); 1518 1519 tpm->flags |= TPM_DID_MUTEX; 1520 1521 /* Initialize the buffer and the lock associated with it */ 1522 tpm->bufsize = TPM_IO_BUF_SIZE; 1523 tpm->iobuf = kmem_zalloc((sizeof (uint8_t))*(tpm->bufsize), KM_SLEEP); 1524 tpm->flags |= TPM_DID_IO_ALLOC; 1525 1526 mutex_init(&tpm->iobuf_lock, NULL, MUTEX_DRIVER, NULL); 1527 tpm->flags |= TPM_DID_IO_MUTEX; 1528 1529 cv_init(&tpm->iobuf_cv, NULL, CV_DRIVER, NULL); 1530 tpm->flags |= TPM_DID_IO_CV; 1531 1532 /* Create minor node */ 1533 ret = ddi_create_minor_node(dip, "tpm", S_IFCHR, ddi_get_instance(dip), 1534 DDI_PSEUDO, 0); 1535 if (ret != DDI_SUCCESS) { 1536 #ifdef DEBUG 1537 cmn_err(CE_WARN, "!%s: ddi_create_minor_node failed", myname); 1538 #endif 1539 goto FAIL; 1540 } 1541 tpm->flags |= TPM_DIDMINOR; 1542 1543 #ifdef KCF_TPM_RNG_PROVIDER 1544 /* register RNG with kcf */ 1545 if (tpmrng_register(tpm) != DDI_SUCCESS) 1546 cmn_err(CE_WARN, "!%s: tpm RNG failed to register with kcf", 1547 myname); 1548 #endif 1549 1550 return (DDI_SUCCESS); 1551 FAIL: 1552 if (tpm != NULL) { 1553 tpm_cleanup(dip, tpm); 1554 ddi_soft_state_free(statep, instance); 1555 tpm = NULL; 1556 } 1557 1558 return (DDI_FAILURE); 1559 } 1560 1561 /* 1562 * Called by tpm_detach and tpm_attach (only on failure) 1563 * Free up the resources that are allocated 1564 */ 1565 static void 1566 tpm_cleanup(dev_info_t *dip, tpm_state_t *tpm) 1567 { 1568 if (tpm == NULL) 1569 return; 1570 1571 #ifdef KCF_TPM_RNG_PROVIDER 1572 (void) tpmrng_unregister(tpm); 1573 #endif 1574 1575 #ifdef sun4v 1576 if (tpm->flags & TPM_HSVC_REGISTERED) { 1577 (void) hsvc_unregister(&hsvc_tpm); 1578 tpm->flags &= ~(TPM_HSVC_REGISTERED); 1579 } 1580 #endif 1581 if (tpm->flags & TPM_DID_MUTEX) { 1582 mutex_destroy(&tpm->dev_lock); 1583 mutex_destroy(&tpm->pm_mutex); 1584 cv_destroy(&tpm->suspend_cv); 1585 tpm->flags &= ~(TPM_DID_MUTEX); 1586 } 1587 if (tpm->flags & TPM_DID_IO_ALLOC) { 1588 ASSERT(tpm->iobuf != NULL); 1589 kmem_free(tpm->iobuf, (sizeof (uint8_t))*(tpm->bufsize)); 1590 tpm->flags &= ~(TPM_DID_IO_ALLOC); 1591 } 1592 if (tpm->flags & TPM_DID_IO_MUTEX) { 1593 mutex_destroy(&tpm->iobuf_lock); 1594 tpm->flags &= ~(TPM_DID_IO_MUTEX); 1595 } 1596 if (tpm->flags & TPM_DID_IO_CV) { 1597 cv_destroy(&tpm->iobuf_cv); 1598 tpm->flags &= ~(TPM_DID_IO_CV); 1599 } 1600 if (tpm->flags & TPM_DIDREGSMAP) { 1601 /* Free the mapped addresses */ 1602 if (tpm->handle != NULL) 1603 ddi_regs_map_free(&tpm->handle); 1604 tpm->flags &= ~(TPM_DIDREGSMAP); 1605 } 1606 if (tpm->flags & TPM_DIDMINOR) { 1607 /* Remove minor node */ 1608 ddi_remove_minor_node(dip, NULL); 1609 tpm->flags &= ~(TPM_DIDMINOR); 1610 } 1611 } 1612 1613 static int 1614 tpm_suspend(tpm_state_t *tpm) 1615 { 1616 if (tpm == NULL) 1617 return (DDI_FAILURE); 1618 mutex_enter(&tpm->pm_mutex); 1619 if (tpm->suspended) { 1620 mutex_exit(&tpm->pm_mutex); 1621 return (DDI_SUCCESS); 1622 } 1623 tpm->suspended = 1; 1624 mutex_exit(&tpm->pm_mutex); 1625 1626 return (DDI_SUCCESS); 1627 } 1628 1629 static int 1630 tpm_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) 1631 { 1632 char *myname = "tpm_detach"; 1633 int instance; 1634 tpm_state_t *tpm; 1635 1636 ASSERT(dip != NULL); 1637 1638 instance = ddi_get_instance(dip); 1639 if (instance < 0) 1640 return (DDI_FAILURE); 1641 1642 if ((tpm = ddi_get_soft_state(statep, instance)) == NULL) { 1643 #ifdef DEBUG 1644 cmn_err(CE_WARN, "!%s: stored pointer to tpm state is NULL", 1645 myname); 1646 #endif 1647 return (ENXIO); 1648 } 1649 1650 switch (cmd) { 1651 case DDI_DETACH: 1652 /* Body is after the switch stmt */ 1653 break; 1654 case DDI_SUSPEND: 1655 return (tpm_suspend(tpm)); 1656 default: 1657 #ifdef DEBUG 1658 cmn_err(CE_WARN, "!%s: case %d not implemented", myname, cmd); 1659 #endif 1660 return (DDI_FAILURE); 1661 } 1662 1663 /* Since we are freeing tpm structure, we need to gain the lock */ 1664 tpm_cleanup(dip, tpm); 1665 1666 /* Free the soft state */ 1667 ddi_soft_state_free(statep, instance); 1668 tpm = NULL; 1669 1670 return (DDI_SUCCESS); 1671 } 1672 1673 /*ARGSUSED*/ 1674 static int 1675 tpm_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg, void **resultp) 1676 { 1677 char *myname = "tpm_getinfo"; 1678 int instance; 1679 tpm_state_t *tpm; 1680 1681 instance = ddi_get_instance(dip); 1682 if ((tpm = ddi_get_soft_state(statep, instance)) == NULL) { 1683 #ifdef DEBUG 1684 cmn_err(CE_WARN, "!%s: stored pointer to tpm state is NULL", 1685 myname); 1686 #endif 1687 return (DDI_FAILURE); 1688 } 1689 1690 switch (cmd) { 1691 case DDI_INFO_DEVT2DEVINFO: 1692 *resultp = tpm->dip; 1693 break; 1694 case DDI_INFO_DEVT2INSTANCE: 1695 *resultp = 0; 1696 break; 1697 default: 1698 #ifdef DEBUG 1699 cmn_err(CE_WARN, "!%s: cmd %d is not implemented", myname, cmd); 1700 #endif 1701 return (DDI_FAILURE); 1702 } 1703 return (DDI_SUCCESS); 1704 } 1705 1706 /* 1707 * Driver entry points 1708 */ 1709 1710 /*ARGSUSED*/ 1711 static int 1712 tpm_open(dev_t *devp, int flag, int otyp, cred_t *cred) 1713 { 1714 char *myname = "tpm_open"; 1715 int instance; 1716 tpm_state_t *tpm; 1717 1718 ASSERT(devp != NULL); 1719 1720 instance = getminor(*devp); 1721 if ((tpm = ddi_get_soft_state(statep, instance)) == NULL) { 1722 #ifdef DEBUG 1723 cmn_err(CE_WARN, "!%s: stored pointer to tpm state is NULL", 1724 myname); 1725 #endif 1726 return (ENXIO); 1727 } 1728 if (otyp != OTYP_CHR) { 1729 #ifdef DEBUG 1730 cmn_err(CE_WARN, "!%s: otyp(%d) != OTYP_CHR(%d)", 1731 myname, otyp, OTYP_CHR); 1732 #endif 1733 return (EINVAL); 1734 } 1735 TPM_EXCLUSIVE_LOCK(tpm); 1736 1737 mutex_enter(&tpm->dev_lock); 1738 if (tpm->dev_held) { 1739 #ifdef DEBUG 1740 cmn_err(CE_WARN, "!%s: the device is already being used", 1741 myname); 1742 #endif 1743 mutex_exit(&tpm->dev_lock); 1744 return (EBUSY); 1745 } 1746 1747 /* The device is free so mark it busy */ 1748 tpm->dev_held = 1; 1749 mutex_exit(&tpm->dev_lock); 1750 1751 return (0); 1752 } 1753 1754 /*ARGSUSED*/ 1755 static int 1756 tpm_close(dev_t dev, int flag, int otyp, cred_t *cred) 1757 { 1758 char *myname = "tpm_close"; 1759 int instance; 1760 tpm_state_t *tpm; 1761 1762 instance = getminor(dev); 1763 if ((tpm = ddi_get_soft_state(statep, instance)) == NULL) { 1764 #ifdef DEBUG 1765 cmn_err(CE_WARN, "!%s: stored pointer to tpm state is NULL", 1766 myname); 1767 #endif 1768 return (ENXIO); 1769 } 1770 if (otyp != OTYP_CHR) { 1771 #ifdef DEBUG 1772 cmn_err(CE_WARN, "!%s: otyp(%d) != OTYP_CHR(%d)", 1773 myname, otyp, OTYP_CHR); 1774 #endif 1775 return (EINVAL); 1776 } 1777 TPM_EXCLUSIVE_LOCK(tpm); 1778 1779 ASSERT(tpm->dev_held); 1780 1781 mutex_enter(&tpm->dev_lock); 1782 ASSERT(mutex_owned(&tpm->dev_lock)); 1783 tpm->dev_held = 0; 1784 mutex_exit(&tpm->dev_lock); 1785 1786 return (0); 1787 } 1788 1789 /*ARGSUSED*/ 1790 static int 1791 tpm_read(dev_t dev, struct uio *uiop, cred_t *credp) 1792 { 1793 int ret; 1794 uint32_t size; 1795 char *myname = "tpm_read"; 1796 int instance; 1797 tpm_state_t *tpm; 1798 1799 instance = getminor(dev); 1800 if ((tpm = ddi_get_soft_state(statep, instance)) == NULL) { 1801 #ifdef DEBUG 1802 cmn_err(CE_WARN, "!%s: stored pointer to tpm state is NULL", 1803 myname); 1804 #endif 1805 return (ENXIO); 1806 } 1807 if (uiop == NULL) { 1808 #ifdef DEBUG 1809 cmn_err(CE_WARN, "!%s: passed in uiop is NULL", myname); 1810 #endif 1811 return (EFAULT); 1812 } 1813 1814 TPM_EXCLUSIVE_LOCK(tpm); 1815 1816 /* Receive the data after requiring the lock */ 1817 ret = tpm_io_lock(tpm); 1818 1819 /* Timeout reached */ 1820 if (ret) 1821 return (ret); 1822 1823 if (uiop->uio_resid > tpm->bufsize) { 1824 #ifdef DEBUG 1825 cmn_err(CE_WARN, "!%s: read_in data is bigger " 1826 "than tpm->bufsize:read in:%d, bufsiz:%d", 1827 myname, (int)uiop->uio_resid, (int)tpm->bufsize); 1828 #endif 1829 ret = EIO; 1830 goto OUT; 1831 } 1832 1833 ret = tis_recv_data(tpm, tpm->iobuf, tpm->bufsize); 1834 if (ret < TPM_HEADER_SIZE) { 1835 #ifdef DEBUG 1836 cmn_err(CE_WARN, "!%s: tis_recv_data returned error", myname); 1837 #endif 1838 ret = EIO; 1839 goto OUT; 1840 } 1841 1842 size = load32(tpm->iobuf, 2); 1843 if (ret != size) { 1844 #ifdef DEBUG 1845 cmn_err(CE_WARN, "!%s: tis_recv_data:" 1846 "expected size=%d, actually read=%d", 1847 myname, size, ret); 1848 #endif 1849 ret = EIO; 1850 goto OUT; 1851 } 1852 1853 /* Send the buffer from the kernel to the userspace */ 1854 ret = uiomove(tpm->iobuf, size, UIO_READ, uiop); 1855 if (ret) { 1856 #ifdef DEBUG 1857 cmn_err(CE_WARN, "!%s: uiomove returned error", myname); 1858 #endif 1859 goto OUT; 1860 } 1861 1862 /* Zeroize the buffer... */ 1863 bzero(tpm->iobuf, tpm->bufsize); 1864 ret = DDI_SUCCESS; 1865 OUT: 1866 /* We are done now: wake up the waiting threads */ 1867 tpm_unlock(tpm); 1868 1869 return (ret); 1870 } 1871 1872 /*ARGSUSED*/ 1873 static int 1874 tpm_write(dev_t dev, struct uio *uiop, cred_t *credp) 1875 { 1876 int ret; 1877 size_t len; 1878 uint32_t size; 1879 char *myname = "tpm_write"; 1880 int instance; 1881 tpm_state_t *tpm; 1882 1883 instance = getminor(dev); 1884 if ((tpm = ddi_get_soft_state(statep, instance)) == NULL) { 1885 #ifdef DEBUG 1886 cmn_err(CE_WARN, "!%s: stored pointer to tpm state is NULL", 1887 myname); 1888 #endif 1889 return (ENXIO); 1890 } 1891 1892 if (uiop == NULL) { 1893 #ifdef DEBUG 1894 cmn_err(CE_WARN, "!%s: passed in uiop is NULL", myname); 1895 #endif 1896 return (EFAULT); 1897 } 1898 1899 TPM_EXCLUSIVE_LOCK(tpm); 1900 1901 len = uiop->uio_resid; 1902 if (len == 0) { 1903 #ifdef DEBUG 1904 cmn_err(CE_WARN, "!%s: requested read of len 0", myname); 1905 #endif 1906 return (0); 1907 } 1908 1909 /* Get the lock for using iobuf */ 1910 ret = tpm_io_lock(tpm); 1911 /* Timeout Reached */ 1912 if (ret) 1913 return (ret); 1914 1915 /* Copy the header and parse the structure to find out the size... */ 1916 ret = uiomove(tpm->iobuf, TPM_HEADER_SIZE, UIO_WRITE, uiop); 1917 if (ret) { 1918 #ifdef DEBUG 1919 cmn_err(CE_WARN, "!%s: uiomove returned error" 1920 "while getting the the header", 1921 myname); 1922 #endif 1923 goto OUT; 1924 } 1925 1926 /* Get the buffersize from the command buffer structure */ 1927 size = load32(tpm->iobuf, TPM_PARAMSIZE_OFFSET); 1928 1929 /* Copy the command to the contiguous buffer */ 1930 if (size > tpm->bufsize) { 1931 #ifdef DEBUG 1932 cmn_err(CE_WARN, "!%s: size %d is greater than " 1933 "the tpm input buffer size %d", 1934 myname, (int)size, (int)tpm->bufsize); 1935 #endif 1936 ret = ENXIO; 1937 goto OUT; 1938 } 1939 1940 /* Copy the buffer from the userspace to kernel */ 1941 ret = uiomove(tpm->iobuf+TPM_HEADER_SIZE, size-TPM_HEADER_SIZE, 1942 UIO_WRITE, uiop); 1943 1944 if (ret) { 1945 #ifdef DEBUG 1946 cmn_err(CE_WARN, "!%s: uiomove returned error" 1947 "while getting the rest of the command", myname); 1948 #endif 1949 goto OUT; 1950 } 1951 1952 /* Send the command */ 1953 ret = tis_send_data(tpm, tpm->iobuf, size); 1954 if (ret != DDI_SUCCESS) { 1955 #ifdef DEBUG 1956 cmn_err(CE_WARN, "!%s: tis_send_data returned error", myname); 1957 #endif 1958 ret = EFAULT; 1959 goto OUT; 1960 } 1961 1962 /* Zeroize the buffer... */ 1963 bzero(tpm->iobuf, tpm->bufsize); 1964 ret = DDI_SUCCESS; 1965 OUT: 1966 tpm_unlock(tpm); 1967 return (ret); 1968 } 1969 1970 /* 1971 * This is to deal with the contentions for the iobuf 1972 */ 1973 static inline int 1974 tpm_io_lock(tpm_state_t *tpm) 1975 { 1976 int ret; 1977 clock_t timeout; 1978 1979 mutex_enter(&tpm->iobuf_lock); 1980 ASSERT(mutex_owned(&tpm->iobuf_lock)); 1981 1982 timeout = ddi_get_lbolt() + drv_usectohz(TPM_IO_TIMEOUT); 1983 1984 /* Wait until the iobuf becomes free with the timeout */ 1985 while (tpm->iobuf_inuse) { 1986 ret = cv_timedwait(&tpm->iobuf_cv, &tpm->iobuf_lock, timeout); 1987 if (ret <= 0) { 1988 /* Timeout reached */ 1989 mutex_exit(&tpm->iobuf_lock); 1990 #ifdef DEBUG 1991 cmn_err(CE_WARN, "!tpm_io_lock:iorequest timed out"); 1992 #endif 1993 return (ETIME); 1994 } 1995 } 1996 tpm->iobuf_inuse = 1; 1997 mutex_exit(&tpm->iobuf_lock); 1998 return (0); 1999 } 2000 2001 /* 2002 * This is to deal with the contentions for the iobuf 2003 */ 2004 static inline void 2005 tpm_unlock(tpm_state_t *tpm) 2006 { 2007 /* Wake up the waiting threads */ 2008 mutex_enter(&tpm->iobuf_lock); 2009 ASSERT(tpm->iobuf_inuse == 1 && mutex_owned(&tpm->iobuf_lock)); 2010 tpm->iobuf_inuse = 0; 2011 cv_broadcast(&tpm->iobuf_cv); 2012 mutex_exit(&tpm->iobuf_lock); 2013 } 2014 2015 #ifdef KCF_TPM_RNG_PROVIDER 2016 /* 2017 * Random number generator entry points 2018 */ 2019 static void 2020 strncpy_spacepad(uchar_t *s1, char *s2, int n) 2021 { 2022 int s2len = strlen(s2); 2023 (void) strncpy((char *)s1, s2, n); 2024 if (s2len < n) 2025 (void) memset(s1 + s2len, ' ', n - s2len); 2026 } 2027 2028 /*ARGSUSED*/ 2029 static int 2030 tpmrng_ext_info(crypto_provider_handle_t prov, 2031 crypto_provider_ext_info_t *ext_info, 2032 crypto_req_handle_t cfreq) 2033 { 2034 tpm_state_t *tpm = (tpm_state_t *)prov; 2035 char buf[64]; 2036 2037 if (tpm == NULL) 2038 return (DDI_FAILURE); 2039 2040 strncpy_spacepad(ext_info->ei_manufacturerID, 2041 (char *)tpm->vers_info.tpmVendorID, 2042 sizeof (ext_info->ei_manufacturerID)); 2043 2044 strncpy_spacepad(ext_info->ei_model, "0", 2045 sizeof (ext_info->ei_model)); 2046 strncpy_spacepad(ext_info->ei_serial_number, "0", 2047 sizeof (ext_info->ei_serial_number)); 2048 2049 ext_info->ei_flags = CRYPTO_EXTF_RNG | CRYPTO_EXTF_SO_PIN_LOCKED; 2050 ext_info->ei_max_session_count = CRYPTO_EFFECTIVELY_INFINITE; 2051 ext_info->ei_max_pin_len = 0; 2052 ext_info->ei_min_pin_len = 0; 2053 ext_info->ei_total_public_memory = CRYPTO_UNAVAILABLE_INFO; 2054 ext_info->ei_free_public_memory = CRYPTO_UNAVAILABLE_INFO; 2055 ext_info->ei_total_private_memory = CRYPTO_UNAVAILABLE_INFO; 2056 ext_info->ei_free_public_memory = CRYPTO_UNAVAILABLE_INFO; 2057 ext_info->ei_time[0] = 0; 2058 2059 ext_info->ei_hardware_version.cv_major = tpm->vers_info.version.major; 2060 ext_info->ei_hardware_version.cv_minor = tpm->vers_info.version.minor; 2061 ext_info->ei_firmware_version.cv_major = 2062 tpm->vers_info.version.revMajor; 2063 ext_info->ei_firmware_version.cv_minor = 2064 tpm->vers_info.version.revMinor; 2065 2066 (void) snprintf(buf, sizeof (buf), "tpmrng TPM RNG"); 2067 2068 strncpy_spacepad(ext_info->ei_label, buf, 2069 sizeof (ext_info->ei_label)); 2070 #undef BUFSZ 2071 return (CRYPTO_SUCCESS); 2072 2073 } 2074 2075 static int 2076 tpmrng_register(tpm_state_t *tpm) 2077 { 2078 int ret; 2079 char ID[64]; 2080 crypto_mech_name_t *rngmech; 2081 2082 ASSERT(tpm != NULL); 2083 2084 (void) snprintf(ID, sizeof (ID), "tpmrng %s", IDENT_TPMRNG); 2085 2086 tpmrng_prov_info.pi_provider_description = ID; 2087 tpmrng_prov_info.pi_provider_dev.pd_hw = tpm->dip; 2088 tpmrng_prov_info.pi_provider_handle = tpm; 2089 2090 ret = crypto_register_provider(&tpmrng_prov_info, &tpm->n_prov); 2091 if (ret != CRYPTO_SUCCESS) { 2092 tpm->n_prov = NULL; 2093 return (DDI_FAILURE); 2094 } 2095 2096 crypto_provider_notification(tpm->n_prov, CRYPTO_PROVIDER_READY); 2097 2098 rngmech = kmem_zalloc(strlen("random") + 1, KM_SLEEP); 2099 (void) memcpy(rngmech, "random", 6); 2100 ret = crypto_load_dev_disabled("tpm", ddi_get_instance(tpm->dip), 2101 1, rngmech); 2102 #ifdef DEBUG 2103 if (ret != CRYPTO_SUCCESS) 2104 cmn_err(CE_WARN, "!crypto_load_dev_disabled failed (%d)", ret); 2105 #endif 2106 return (DDI_SUCCESS); 2107 } 2108 2109 static int 2110 tpmrng_unregister(tpm_state_t *tpm) 2111 { 2112 int ret; 2113 ASSERT(tpm != NULL); 2114 if (tpm->n_prov) { 2115 ret = crypto_unregister_provider(tpm->n_prov); 2116 tpm->n_prov = NULL; 2117 if (ret != CRYPTO_SUCCESS) 2118 return (DDI_FAILURE); 2119 } 2120 return (DDI_SUCCESS); 2121 } 2122 2123 /*ARGSUSED*/ 2124 static void 2125 tpmrng_provider_status(crypto_provider_handle_t provider, uint_t *status) 2126 { 2127 *status = CRYPTO_PROVIDER_READY; 2128 } 2129 2130 /*ARGSUSED*/ 2131 static int 2132 tpmrng_seed_random(crypto_provider_handle_t provider, crypto_session_id_t sid, 2133 uchar_t *buf, size_t len, uint_t entropy_est, uint32_t flags, 2134 crypto_req_handle_t req) 2135 { 2136 int ret; 2137 tpm_state_t *tpm; 2138 uint32_t len32; 2139 /* Max length of seed is 256 bytes, add 14 for header. */ 2140 uint8_t cmdbuf[270] = { 2141 0, 193, /* TPM_TAG_RQU COMMAND */ 2142 0, 0, 0, 0x0A, /* paramsize in bytes */ 2143 0, 0, 0, TPM_ORD_StirRandom, 2144 0, 0, 0, 0 /* number of input bytes (< 256) */ 2145 }; 2146 uint32_t buflen; 2147 2148 if (len == 0 || len > 255 || buf == NULL) 2149 return (CRYPTO_ARGUMENTS_BAD); 2150 2151 tpm = (tpm_state_t *)provider; 2152 if (tpm == NULL) 2153 return (CRYPTO_INVALID_CONTEXT); 2154 2155 /* Acquire lock for exclusive use of TPM */ 2156 TPM_EXCLUSIVE_LOCK(tpm); 2157 2158 ret = tpm_io_lock(tpm); 2159 /* Timeout reached */ 2160 if (ret) 2161 return (CRYPTO_BUSY); 2162 2163 /* TPM only handles 32 bit length, so truncate if too big. */ 2164 len32 = (uint32_t)len; 2165 buflen = len32 + 14; 2166 2167 /* The length must be in network order */ 2168 buflen = htonl(buflen); 2169 bcopy(&buflen, cmdbuf + 2, sizeof (uint32_t)); 2170 2171 /* Convert it back */ 2172 buflen = ntohl(buflen); 2173 2174 /* length must be in network order */ 2175 len32 = htonl(len32); 2176 bcopy(&len32, cmdbuf + 10, sizeof (uint32_t)); 2177 2178 /* convert it back */ 2179 len32 = ntohl(len32); 2180 2181 bcopy(buf, cmdbuf + 14, len32); 2182 2183 ret = itpm_command(tpm, cmdbuf, buflen); 2184 tpm_unlock(tpm); 2185 2186 if (ret != DDI_SUCCESS) { 2187 #ifdef DEBUG 2188 cmn_err(CE_WARN, "!tpmrng_seed_random failed"); 2189 #endif 2190 return (CRYPTO_FAILED); 2191 } 2192 2193 return (CRYPTO_SUCCESS); 2194 } 2195 2196 /* ARGSUSED */ 2197 static int 2198 tpmrng_generate_random(crypto_provider_handle_t provider, 2199 crypto_session_id_t sid, uchar_t *buf, size_t len, crypto_req_handle_t req) 2200 { 2201 int ret; 2202 tpm_state_t *tpm; 2203 uint8_t hdr[14] = { 2204 0, 193, /* TPM_TAG_RQU COMMAND */ 2205 0, 0, 0, 14, /* paramsize in bytes */ 2206 0, 0, 0, TPM_ORD_GetRandom, 2207 0, 0, 0, 0 2208 }; 2209 uint8_t *cmdbuf = NULL; 2210 uint32_t len32 = (uint32_t)len; 2211 uint32_t buflen = len32 + sizeof (hdr); 2212 2213 if (len == 0 || buf == NULL) 2214 return (CRYPTO_ARGUMENTS_BAD); 2215 2216 tpm = (tpm_state_t *)provider; 2217 if (tpm == NULL) 2218 return (CRYPTO_INVALID_CONTEXT); 2219 2220 TPM_EXCLUSIVE_LOCK(tpm); 2221 2222 ret = tpm_io_lock(tpm); 2223 /* Timeout reached */ 2224 if (ret) 2225 return (CRYPTO_BUSY); 2226 2227 cmdbuf = kmem_zalloc(buflen, KM_SLEEP); 2228 bcopy(hdr, cmdbuf, sizeof (hdr)); 2229 2230 /* Length is written in network byte order */ 2231 len32 = htonl(len32); 2232 bcopy(&len32, cmdbuf + 10, sizeof (uint32_t)); 2233 2234 ret = itpm_command(tpm, cmdbuf, buflen); 2235 if (ret != DDI_SUCCESS) { 2236 #ifdef DEBUG 2237 cmn_err(CE_WARN, "!tpmrng_generate_random failed"); 2238 #endif 2239 kmem_free(cmdbuf, buflen); 2240 tpm_unlock(tpm); 2241 return (CRYPTO_FAILED); 2242 } 2243 2244 /* Find out how many bytes were really returned */ 2245 len32 = load32(cmdbuf, 10); 2246 2247 /* Copy the random bytes back to the callers buffer */ 2248 bcopy(cmdbuf + 14, buf, len32); 2249 2250 kmem_free(cmdbuf, buflen); 2251 tpm_unlock(tpm); 2252 2253 return (CRYPTO_SUCCESS); 2254 } 2255 #endif /* KCF_TPM_RNG_PROVIDER */ 2256