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 cmn_err(CE_WARN, "%s: itpm_command failed", myname); 425 return (DDI_FAILURE); 426 } 427 428 /* 429 * Get the length of the returned buffer 430 * Make sure that there are 4 timeout values returned 431 * length of the capability response is stored in data[10-13] 432 * Also the TPM is in network byte order 433 */ 434 len = load32(buf, TPM_CAP_RESPSIZE_OFFSET); 435 if (len != 4 * sizeof (uint32_t)) { 436 cmn_err(CE_WARN, "%s: capability response size should be %d" 437 "instead it's %d", 438 myname, (int)(4 * sizeof (uint32_t)), (int)len); 439 return (DDI_FAILURE); 440 } 441 442 /* Get the four timeout's: a,b,c,d (they are 4 bytes long each) */ 443 timeout = load32(buf, TPM_CAP_TIMEOUT_A_OFFSET); 444 if (timeout == 0) { 445 timeout = DEFAULT_TIMEOUT_A; 446 } else if (timeout < TEN_MILLISECONDS) { 447 /* timeout is in millisecond range (should be microseconds) */ 448 timeout *= 1000; 449 } 450 tpm->timeout_a = drv_usectohz(timeout); 451 452 timeout = load32(buf, TPM_CAP_TIMEOUT_B_OFFSET); 453 if (timeout == 0) { 454 timeout = DEFAULT_TIMEOUT_B; 455 } else if (timeout < TEN_MILLISECONDS) { 456 /* timeout is in millisecond range (should be microseconds) */ 457 timeout *= 1000; 458 } 459 tpm->timeout_b = drv_usectohz(timeout); 460 461 timeout = load32(buf, TPM_CAP_TIMEOUT_C_OFFSET); 462 if (timeout == 0) { 463 timeout = DEFAULT_TIMEOUT_C; 464 } else if (timeout < TEN_MILLISECONDS) { 465 /* timeout is in millisecond range (should be microseconds) */ 466 timeout *= 1000; 467 } 468 tpm->timeout_c = drv_usectohz(timeout); 469 470 timeout = load32(buf, TPM_CAP_TIMEOUT_D_OFFSET); 471 if (timeout == 0) { 472 timeout = DEFAULT_TIMEOUT_D; 473 } else if (timeout < TEN_MILLISECONDS) { 474 /* timeout is in millisecond range (should be microseconds) */ 475 timeout *= 1000; 476 } 477 tpm->timeout_d = drv_usectohz(timeout); 478 479 return (DDI_SUCCESS); 480 } 481 482 /* 483 * Get the actual timeouts supported by the TPM by issuing TPM_GetCapability 484 * with the subcommand TPM_CAP_PROP_TIS_DURATION 485 * TPM_GetCapability (TPM Main Part 3 Rev. 94, pg.38) 486 */ 487 static int 488 tpm_get_duration(tpm_state_t *tpm) { 489 int ret; 490 uint32_t duration; 491 uint32_t len; 492 uint8_t buf[30] = { 493 0, 193, /* TPM_TAG_RQU_COMMAND */ 494 0, 0, 0, 22, /* paramsize in bytes */ 495 0, 0, 0, 101, /* TPM_ORD_GetCapability */ 496 0, 0, 0, 5, /* TPM_CAP_Prop */ 497 0, 0, 0, 4, /* SUB_CAP size in bytes */ 498 0, 0, 1, 32 /* TPM_CAP_PROP_TIS_DURATION(0x120) */ 499 }; 500 char *myname = "tpm_get_duration"; 501 502 ASSERT(tpm != NULL); 503 504 ret = itpm_command(tpm, buf, sizeof (buf)); 505 if (ret != DDI_SUCCESS) { 506 cmn_err(CE_WARN, "%s: itpm_command failed with ret code: 0x%x", 507 myname, ret); 508 return (DDI_FAILURE); 509 } 510 511 /* 512 * Get the length of the returned buffer 513 * Make sure that there are 3 duration values (S,M,L: in that order) 514 * length of the capability response is stored in data[10-13] 515 * Also the TPM is in network byte order 516 */ 517 len = load32(buf, TPM_CAP_RESPSIZE_OFFSET); 518 if (len != 3 * sizeof (uint32_t)) { 519 cmn_err(CE_WARN, "%s: capability response should be %d, " 520 "instead, it's %d", 521 myname, (int)(3 * sizeof (uint32_t)), (int)len); 522 return (DDI_FAILURE); 523 } 524 525 duration = load32(buf, TPM_CAP_DUR_SHORT_OFFSET); 526 if (duration == 0) { 527 duration = DEFAULT_SHORT_DURATION; 528 } else if (duration < TEN_MILLISECONDS) { 529 duration *= 1000; 530 } 531 tpm->duration[TPM_SHORT] = drv_usectohz(duration); 532 533 duration = load32(buf, TPM_CAP_DUR_MEDIUM_OFFSET); 534 if (duration == 0) { 535 duration = DEFAULT_MEDIUM_DURATION; 536 } else if (duration < TEN_MILLISECONDS) { 537 duration *= 1000; 538 } 539 tpm->duration[TPM_MEDIUM] = drv_usectohz(duration); 540 541 duration = load32(buf, TPM_CAP_DUR_LONG_OFFSET); 542 if (duration == 0) { 543 duration = DEFAULT_LONG_DURATION; 544 } else if (duration < FOUR_HUNDRED_MILLISECONDS) { 545 duration *= 1000; 546 } 547 tpm->duration[TPM_LONG] = drv_usectohz(duration); 548 549 /* Just make the undefined duration be the same as the LONG */ 550 tpm->duration[TPM_UNDEFINED] = tpm->duration[TPM_LONG]; 551 552 return (DDI_SUCCESS); 553 } 554 555 /* 556 * Get the actual timeouts supported by the TPM by issuing TPM_GetCapability 557 * with the subcommand TPM_CAP_PROP_TIS_DURATION 558 * TPM_GetCapability (TPM Main Part 3 Rev. 94, pg.38) 559 */ 560 static int 561 tpm_get_version(tpm_state_t *tpm) { 562 int ret; 563 uint32_t len; 564 char vendorId[5]; 565 /* If this buf is too small, the "vendor specific" data won't fit */ 566 uint8_t buf[64] = { 567 0, 193, /* TPM_TAG_RQU_COMMAND */ 568 0, 0, 0, 18, /* paramsize in bytes */ 569 0, 0, 0, 101, /* TPM_ORD_GetCapability */ 570 0, 0, 0, 0x1A, /* TPM_CAP_VERSION_VAL */ 571 0, 0, 0, 0, /* SUB_CAP size in bytes */ 572 }; 573 char *myname = "tpm_get_version"; 574 575 ASSERT(tpm != NULL); 576 577 ret = itpm_command(tpm, buf, sizeof (buf)); 578 if (ret != DDI_SUCCESS) { 579 cmn_err(CE_WARN, "%s: itpm_command failed with ret code: 0x%x", 580 myname, ret); 581 return (DDI_FAILURE); 582 } 583 584 /* 585 * Get the length of the returned buffer. 586 */ 587 len = load32(buf, TPM_CAP_RESPSIZE_OFFSET); 588 if (len < TPM_CAP_VERSION_INFO_SIZE) { 589 cmn_err(CE_WARN, "%s: capability response should be greater" 590 " than %d, instead, it's %d", 591 myname, 592 TPM_CAP_VERSION_INFO_SIZE, 593 len); 594 return (DDI_FAILURE); 595 } 596 597 bcopy(buf + TPM_CAP_VERSION_INFO_OFFSET, &tpm->vers_info, 598 TPM_CAP_VERSION_INFO_SIZE); 599 600 bcopy(tpm->vers_info.tpmVendorID, vendorId, 601 sizeof (tpm->vers_info.tpmVendorID)); 602 vendorId[4] = '\0'; 603 604 cmn_err(CE_NOTE, "!TPM found: Ver %d.%d, Rev %d.%d, " 605 "SpecLevel %d, errataRev %d, VendorId '%s'", 606 tpm->vers_info.version.major, /* Version */ 607 tpm->vers_info.version.minor, 608 tpm->vers_info.version.revMajor, /* Revision */ 609 tpm->vers_info.version.revMinor, 610 (int)ntohs(tpm->vers_info.specLevel), 611 tpm->vers_info.errataRev, 612 vendorId); 613 614 /* 615 * This driver only supports TPM Version 1.2 616 */ 617 if (tpm->vers_info.version.major != 1 && 618 tpm->vers_info.version.minor != 2) { 619 cmn_err(CE_WARN, "%s: Unsupported TPM version (%d.%d)", 620 myname, 621 tpm->vers_info.version.major, /* Version */ 622 tpm->vers_info.version.minor); 623 return (DDI_FAILURE); 624 } 625 626 return (DDI_SUCCESS); 627 } 628 629 /* 630 * To prevent the TPM from complaining that certain functions are not tested 631 * we run this command when the driver attaches. 632 * For details see Section 4.2 of TPM Main Part 3 Command Specification 633 */ 634 static int 635 tpm_continue_selftest(tpm_state_t *tpm) { 636 int ret; 637 uint8_t buf[10] = { 638 0, 193, /* TPM_TAG_RQU COMMAND */ 639 0, 0, 0, 10, /* paramsize in bytes */ 640 0, 0, 0, 83 /* TPM_ORD_ContinueSelfTest */ 641 }; 642 char *myname = "tpm_continue_selftest"; 643 644 /* Need a longer timeout */ 645 ret = itpm_command(tpm, buf, sizeof (buf)); 646 if (ret != DDI_SUCCESS) { 647 cmn_err(CE_WARN, "%s: itpm_command failed", myname); 648 return (DDI_FAILURE); 649 } 650 651 return (DDI_SUCCESS); 652 } 653 /* 654 * Auxilary Functions 655 */ 656 657 /* 658 * Find out how long we should wait for the TPM command to complete a command 659 */ 660 static clock_t 661 tpm_get_ordinal_duration(tpm_state_t *tpm, uint8_t ordinal) 662 { 663 uint8_t index; 664 char *myname = "tpm_get_ordinal_duration"; 665 666 ASSERT(tpm != NULL); 667 668 /* Default and failure case for IFX */ 669 /* Is it a TSC_ORDINAL? */ 670 if (ordinal & TSC_ORDINAL_MASK) { 671 if (ordinal > TSC_ORDINAL_MAX) { 672 cmn_err(CE_WARN, 673 "%s: tsc ordinal: %d exceeds MAX: %d", 674 myname, ordinal, TSC_ORDINAL_MAX); 675 return (0); 676 } 677 index = tsc_ords_duration[ordinal]; 678 } else { 679 if (ordinal > TPM_ORDINAL_MAX) { 680 cmn_err(CE_WARN, 681 "%s: ordinal %d exceeds MAX: %d", 682 myname, ordinal, TPM_ORDINAL_MAX); 683 return (0); 684 } 685 index = tpm_ords_duration[ordinal]; 686 } 687 688 if (index > TPM_DURATION_MAX_IDX) { 689 cmn_err(CE_WARN, "%s: FATAL:index '%d' is out of bound", 690 myname, index); 691 return (0); 692 } 693 return (tpm->duration[index]); 694 } 695 696 /* 697 * Internal TPM Transmit Function: 698 * Calls implementation specific sendto and receive 699 * The code assumes that the buffer is in network byte order 700 */ 701 static int 702 itpm_command(tpm_state_t *tpm, uint8_t *buf, size_t bufsiz) 703 { 704 int ret; 705 uint32_t count; 706 char *myname = "itpm_command"; 707 708 ASSERT(tpm != NULL && buf != NULL); 709 710 /* The byte order is network byte order so convert it */ 711 count = load32(buf, TPM_PARAMSIZE_OFFSET); 712 713 if (count == 0) { 714 cmn_err(CE_WARN, "%s: count=0, no data? %d", myname, 715 (int)bufsiz); 716 return (DDI_FAILURE); 717 } 718 if (count > bufsiz) { 719 cmn_err(CE_WARN, "%s: invalid count value:count:%d > bufsiz %d", 720 myname, (int)count, (int)bufsiz); 721 return (DDI_FAILURE); 722 } 723 724 /* Send the command */ 725 ret = tis_send_data(tpm, buf, count); 726 if (ret != DDI_SUCCESS) { 727 cmn_err(CE_WARN, "%s: tis_send_data failed with error %x", 728 myname, ret); 729 return (DDI_FAILURE); 730 } 731 732 /* 733 * Now receive the data from the tpm 734 * Should at least receive "the common" 10 bytes (TPM_HEADER_SIZE) 735 */ 736 ret = tis_recv_data(tpm, buf, bufsiz); 737 if (ret < TPM_HEADER_SIZE) { 738 cmn_err(CE_WARN, "%s: tis_recv_data failed", myname); 739 return (DDI_FAILURE); 740 } 741 742 /* Check the return code */ 743 ret = load32(buf, TPM_RETURN_OFFSET); 744 if (ret != TPM_SUCCESS) { 745 if (ret == TPM_E_DEACTIVATED) 746 cmn_err(CE_WARN, "%s: TPM is deactivated", myname); 747 else if (ret == TPM_E_DISABLED) 748 cmn_err(CE_WARN, "%s: TPM is disabled", myname); 749 else 750 cmn_err(CE_WARN, "%s: TPM error code 0x%0x", 751 myname, ret); 752 return (DDI_FAILURE); 753 } 754 755 return (DDI_SUCCESS); 756 } 757 758 /* 759 * Whenever the driver wants to write to the DATA_IO register, it must need 760 * to figure out the burstcount. This is the amount of bytes it can write 761 * before having to wait for long LPC bus cycle 762 * 763 * Returns: 0 if error, burst count if sucess 764 */ 765 static uint16_t 766 tpm_get_burstcount(tpm_state_t *tpm) { 767 clock_t stop; 768 uint16_t burstcnt; 769 770 ASSERT(tpm != NULL); 771 772 /* 773 * Spec says timeout should be TIMEOUT_D 774 * burst count is TPM_STS bits 8..23 775 */ 776 stop = ddi_get_lbolt() + tpm->timeout_d; 777 do { 778 /* 779 * burstcnt is stored as a little endian value 780 * 'ntohs' doesn't work since the value is not word-aligned 781 */ 782 burstcnt = tpm_get8(tpm, TPM_STS + 1); 783 burstcnt += tpm_get8(tpm, TPM_STS + 2) << 8; 784 785 if (burstcnt) 786 return (burstcnt); 787 788 delay(tpm->timeout_poll); 789 } while (ddi_get_lbolt() < stop); 790 791 return (0); 792 } 793 794 /* 795 * Writing 1 to TPM_STS_CMD_READY bit in TPM_STS will do the following: 796 * 1. The TPM will clears IO buffers if any 797 * 2. The TPM will enters either Idle or Ready state within TIMEOUT_B 798 * (checked in the calling function) 799 */ 800 static void 801 tpm_set_ready(tpm_state_t *tpm) { 802 tpm_put8(tpm, TPM_STS, TPM_STS_CMD_READY); 803 } 804 805 static int 806 receive_data(tpm_state_t *tpm, uint8_t *buf, size_t bufsiz) { 807 int size = 0; 808 int retried = 0; 809 uint8_t stsbits; 810 811 /* A number of consecutive bytes that can be written to TPM */ 812 uint16_t burstcnt; 813 814 ASSERT(tpm != NULL && buf != NULL); 815 retry: 816 while (size < bufsiz && 817 (tpm_wait_for_stat(tpm, 818 (TPM_STS_DATA_AVAIL|TPM_STS_VALID), 819 tpm->timeout_c) == DDI_SUCCESS)) { 820 /* 821 * Burstcount should be available within TIMEOUT_D 822 * after STS is set to valid 823 * burstcount is dynamic, so have to get it each time 824 */ 825 burstcnt = tpm_get_burstcount(tpm); 826 for (; burstcnt > 0 && size < bufsiz; burstcnt--) { 827 buf[size++] = tpm_get8(tpm, TPM_DATA_FIFO); 828 } 829 } 830 stsbits = tis_get_status(tpm); 831 /* check to see if we need to retry (just once) */ 832 if (size < bufsiz && !(stsbits & TPM_STS_DATA_AVAIL) && retried == 0) { 833 /* issue responseRetry (TIS 1.2 pg 54) */ 834 tpm_put8(tpm, TPM_STS, TPM_STS_RESPONSE_RETRY); 835 /* update the retry counter so we only retry once */ 836 retried++; 837 /* reset the size to 0 and reread the entire response */ 838 size = 0; 839 goto retry; 840 } 841 return (size); 842 } 843 844 /* Receive the data from the TPM */ 845 static int 846 tis_recv_data(tpm_state_t *tpm, uint8_t *buf, size_t bufsiz) { 847 int ret; 848 int size = 0; 849 uint32_t expected, status; 850 uint32_t cmdresult; 851 char *myname = "tis_recv_data"; 852 853 ASSERT(tpm != NULL && buf != NULL); 854 855 if (bufsiz < TPM_HEADER_SIZE) { 856 /* There should be at least tag,paramsize,return code */ 857 cmn_err(CE_WARN, "%s: received data should contain at least " 858 "the header which is %d bytes long", 859 myname, TPM_HEADER_SIZE); 860 goto OUT; 861 } 862 863 /* Read tag(2 bytes), paramsize(4), and result(4) */ 864 size = receive_data(tpm, buf, TPM_HEADER_SIZE); 865 if (size < TPM_HEADER_SIZE) { 866 cmn_err(CE_WARN, "%s: getting the TPM_HEADER failed: size=%d", 867 myname, size); 868 goto OUT; 869 } 870 871 cmdresult = load32(buf, TPM_RETURN_OFFSET); 872 873 /* Get 'paramsize'(4 bytes)--it includes tag and paramsize */ 874 expected = load32(buf, TPM_PARAMSIZE_OFFSET); 875 if (expected > bufsiz) { 876 cmn_err(CE_WARN, "%s: paramSize is bigger " 877 "than the requested size: paramSize=%d bufsiz=%d result=%d", 878 myname, (int)expected, (int)bufsiz, cmdresult); 879 goto OUT; 880 } 881 882 /* Read in the rest of the data from the TPM */ 883 size += receive_data(tpm, (uint8_t *)&buf[TPM_HEADER_SIZE], 884 expected - TPM_HEADER_SIZE); 885 if (size < expected) { 886 cmn_err(CE_WARN, "%s: received data length=%d " 887 "is less than expected = %d", myname, size, expected); 888 goto OUT; 889 } 890 891 /* The TPM MUST set the state to stsValid within TIMEOUT_C */ 892 ret = tpm_wait_for_stat(tpm, TPM_STS_VALID, tpm->timeout_c); 893 894 status = tis_get_status(tpm); 895 if (ret != DDI_SUCCESS) { 896 cmn_err(CE_WARN, "%s: TPM didn't set stsValid after its I/O: " 897 "status = 0x%08X", myname, status); 898 goto OUT; 899 } 900 901 /* There is still more data? */ 902 if (status & TPM_STS_DATA_AVAIL) { 903 cmn_err(CE_WARN, "%s: Status TPM_STS_DATA_AVAIL set:0x%08X", 904 myname, status); 905 goto OUT; 906 } 907 908 /* 909 * Release the control of the TPM after we are done with it 910 * it...so others can also get a chance to send data 911 */ 912 tis_release_locality(tpm, tpm->locality, 0); 913 914 OUT: 915 tpm_set_ready(tpm); 916 tis_release_locality(tpm, tpm->locality, 0); 917 return (size); 918 } 919 920 /* 921 * Send the data (TPM commands) to the Data IO register 922 */ 923 static int 924 tis_send_data(tpm_state_t *tpm, uint8_t *buf, size_t bufsiz) { 925 int ret; 926 uint8_t status; 927 uint16_t burstcnt; 928 uint32_t ordinal; 929 size_t count = 0; 930 char *myname = "tis_send_data"; 931 932 ASSERT(tpm != NULL && buf != NULL); 933 934 if (bufsiz == 0) { 935 cmn_err(CE_WARN, "%s: passed in argument bufsize is zero", 936 myname); 937 return (DDI_FAILURE); 938 } 939 940 /* Put the TPM in ready state */ 941 status = tis_get_status(tpm); 942 943 if (!(status & TPM_STS_CMD_READY)) { 944 tpm_set_ready(tpm); 945 ret = tpm_wait_for_stat(tpm, TPM_STS_CMD_READY, tpm->timeout_b); 946 if (ret != DDI_SUCCESS) { 947 cmn_err(CE_WARN, "%s: could not put the TPM " 948 "in the command ready state:" 949 "tpm_wait_for_stat returned error", 950 myname); 951 goto FAIL; 952 } 953 } 954 955 /* 956 * Now we are ready to send command 957 * TPM's burstcount dictates how many bytes we can write at a time 958 * Burstcount is dynamic if INTF_CAPABILITY for static burstcount is 959 * not set. 960 */ 961 while (count < bufsiz - 1) { 962 burstcnt = tpm_get_burstcount(tpm); 963 if (burstcnt == 0) { 964 cmn_err(CE_WARN, "%s: tpm_get_burstcnt returned error", 965 myname); 966 ret = DDI_FAILURE; 967 goto FAIL; 968 } 969 970 for (; burstcnt > 0 && count < bufsiz - 1; burstcnt--) { 971 tpm_put8(tpm, TPM_DATA_FIFO, buf[count]); 972 count++; 973 } 974 /* Wait for TPM to indicate that it is ready for more data */ 975 ret = tpm_wait_for_stat(tpm, 976 (TPM_STS_VALID | TPM_STS_DATA_EXPECT), tpm->timeout_c); 977 if (ret != DDI_SUCCESS) { 978 cmn_err(CE_WARN, "%s: TPM didn't enter stsvalid " 979 "state after sending the data:", myname); 980 goto FAIL; 981 } 982 } 983 /* We can't exit the loop above unless we wrote bufsiz-1 bytes */ 984 985 /* Write last byte */ 986 tpm_put8(tpm, TPM_DATA_FIFO, buf[count]); 987 count++; 988 989 /* Wait for the TPM to enter Valid State */ 990 ret = tpm_wait_for_stat(tpm, TPM_STS_VALID, tpm->timeout_c); 991 if (ret == DDI_FAILURE) { 992 cmn_err(CE_WARN, "%s: tpm didn't enter Valid state", myname); 993 goto FAIL; 994 } 995 996 status = tis_get_status(tpm); 997 /* The TPM should NOT be expecing more data at this point */ 998 if ((status & TPM_STS_DATA_EXPECT) != 0) { 999 cmn_err(CE_WARN, "%s: DATA_EXPECT is set (shouldn't be) after " 1000 "writing the last byte: status=0x%08X", myname, status); 1001 ret = DDI_FAILURE; 1002 goto FAIL; 1003 } 1004 1005 /* 1006 * Final step: Writing TPM_STS_GO to TPM_STS 1007 * register will actually send the command. 1008 */ 1009 tpm_put8(tpm, TPM_STS, TPM_STS_GO); 1010 1011 /* Ordinal/Command_code is located in buf[6..9] */ 1012 ordinal = load32(buf, TPM_COMMAND_CODE_OFFSET); 1013 1014 ret = tpm_wait_for_stat(tpm, TPM_STS_DATA_AVAIL | TPM_STS_VALID, 1015 tpm_get_ordinal_duration(tpm, ordinal)); 1016 if (ret == DDI_FAILURE) { 1017 status = tis_get_status(tpm); 1018 if (!(status & TPM_STS_DATA_AVAIL) || 1019 !(status & TPM_STS_VALID)) { 1020 cmn_err(CE_WARN, "%s: TPM not ready or valid " 1021 "(ordinal = %d timeout = %ld)", 1022 myname, ordinal, 1023 tpm_get_ordinal_duration(tpm, ordinal)); 1024 } else { 1025 cmn_err(CE_WARN, "%s: tpm_wait_for_stat " 1026 "(DATA_AVAIL | VALID) failed: STS = 0x%0X", 1027 myname, status); 1028 } 1029 goto FAIL; 1030 } 1031 return (DDI_SUCCESS); 1032 1033 FAIL: 1034 tpm_set_ready(tpm); 1035 tis_release_locality(tpm, tpm->locality, 0); 1036 return (ret); 1037 } 1038 1039 /* 1040 * Clear XrequestUse and Xactivelocality, where X is the current locality 1041 */ 1042 static void 1043 tis_release_locality(tpm_state_t *tpm, char locality, int force) { 1044 ASSERT(tpm != NULL && locality >= 0 && locality < 5); 1045 1046 if (force || 1047 (tpm_get8(tpm, TPM_ACCESS) & 1048 (TPM_ACCESS_REQUEST_PENDING | TPM_ACCESS_VALID)) == 1049 (TPM_ACCESS_REQUEST_PENDING | TPM_ACCESS_VALID)) { 1050 /* 1051 * Writing 1 to active locality bit in TPM_ACCESS 1052 * register reliquishes the control of the locality 1053 */ 1054 tpm_put8(tpm, TPM_ACCESS, TPM_ACCESS_ACTIVE_LOCALITY); 1055 } 1056 } 1057 1058 /* 1059 * Checks whether the given locality is active 1060 * Use TPM_ACCESS register and the masks TPM_ACCESS_VALID,TPM_ACTIVE_LOCALITY 1061 */ 1062 static int 1063 tis_check_active_locality(tpm_state_t *tpm, char locality) { 1064 uint8_t access_bits; 1065 uint8_t old_locality; 1066 1067 ASSERT(tpm != NULL && locality >= 0 && locality < 5); 1068 1069 old_locality = tpm->locality; 1070 tpm->locality = locality; 1071 1072 /* Just check to see if the requested locality works */ 1073 access_bits = tpm_get8(tpm, TPM_ACCESS); 1074 access_bits &= (TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID); 1075 1076 /* this was just a check, not a request to switch */ 1077 tpm->locality = old_locality; 1078 1079 if (access_bits == (TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID)) { 1080 return (DDI_SUCCESS); 1081 } else { 1082 return (DDI_FAILURE); 1083 } 1084 } 1085 1086 /* Request the TPM to be in the given locality */ 1087 static int 1088 tis_request_locality(tpm_state_t *tpm, char locality) { 1089 clock_t timeout; 1090 int ret; 1091 char *myname = "tis_request_locality"; 1092 1093 ASSERT(tpm != NULL && locality >= 0 && locality < 5); 1094 1095 ret = tis_check_active_locality(tpm, locality); 1096 1097 if (ret == DDI_SUCCESS) { 1098 /* Locality is already active */ 1099 tpm->locality = locality; 1100 return (DDI_SUCCESS); 1101 } 1102 1103 tpm_put8(tpm, TPM_ACCESS, TPM_ACCESS_REQUEST_USE); 1104 timeout = ddi_get_lbolt() + tpm->timeout_a; 1105 1106 /* Using polling */ 1107 while (tis_check_active_locality(tpm, locality) 1108 != DDI_SUCCESS) { 1109 if (ddi_get_lbolt() >= timeout) { 1110 cmn_err(CE_WARN, "%s (interrupt-disabled) " 1111 "tis_request_locality timed out (timeout_a = %ld)", 1112 myname, tpm->timeout_a); 1113 return (DDI_FAILURE); 1114 } 1115 delay(tpm->timeout_poll); 1116 } 1117 1118 tpm->locality = locality; 1119 return (DDI_SUCCESS); 1120 } 1121 1122 /* Read the status register */ 1123 static uint8_t 1124 tis_get_status(tpm_state_t *tpm) { 1125 return (tpm_get8(tpm, TPM_STS)); 1126 } 1127 1128 static int 1129 tpm_wait_for_stat(tpm_state_t *tpm, uint8_t mask, clock_t timeout) { 1130 char *myname = "tpm_wait_for_stat"; 1131 clock_t absolute_timeout = ddi_get_lbolt() + timeout; 1132 1133 /* Using polling */ 1134 while ((tis_get_status(tpm) & mask) != mask) { 1135 if (ddi_get_lbolt() >= absolute_timeout) { 1136 /* Timeout reached */ 1137 cmn_err(CE_WARN, "%s: using " 1138 "polling - reached timeout (%ld usecs)", 1139 myname, drv_hztousec(timeout)); 1140 return (DDI_FAILURE); 1141 } 1142 delay(tpm->timeout_poll); 1143 } 1144 return (DDI_SUCCESS); 1145 } 1146 1147 /* 1148 * Initialize TPM device 1149 * 1. Find out supported interrupt capabilities 1150 * 2. Set up interrupt handler if supported (some BIOSes don't support 1151 * interrupts for TPMS, in which case we set up polling) 1152 * 3. Determine timeouts and commands duration 1153 */ 1154 static int 1155 tis_init(tpm_state_t *tpm) { 1156 uint32_t intf_caps; 1157 int ret; 1158 char *myname = "tis_init"; 1159 1160 /* 1161 * Temporarily set up timeouts before we get the real timeouts 1162 * by issuing TPM_CAP commands (but to issue TPM_CAP commands, 1163 * you need TIMEOUTs defined...chicken and egg problem here. 1164 * TPM timeouts: Convert the milliseconds to clock cycles 1165 */ 1166 tpm->timeout_a = drv_usectohz(TIS_TIMEOUT_A); 1167 tpm->timeout_b = drv_usectohz(TIS_TIMEOUT_B); 1168 tpm->timeout_c = drv_usectohz(TIS_TIMEOUT_C); 1169 tpm->timeout_d = drv_usectohz(TIS_TIMEOUT_D); 1170 /* 1171 * Do the same with the duration (real duration will be filled out 1172 * when we call TPM_GetCapability to get the duration values from 1173 * the TPM itself). 1174 */ 1175 tpm->duration[TPM_SHORT] = drv_usectohz(TPM_DEFAULT_DURATION); 1176 tpm->duration[TPM_MEDIUM] = drv_usectohz(TPM_DEFAULT_DURATION); 1177 tpm->duration[TPM_LONG] = drv_usectohz(TPM_DEFAULT_DURATION); 1178 tpm->duration[TPM_UNDEFINED] = drv_usectohz(TPM_DEFAULT_DURATION); 1179 1180 /* Find out supported capabilities */ 1181 intf_caps = tpm_get32(tpm, TPM_INTF_CAP); 1182 1183 /* Upper 3 bytes should always return 0 */ 1184 if (intf_caps & 0x7FFFFF00) { 1185 #ifdef DEBUG 1186 cmn_err(CE_WARN, "%s: bad intf_caps value 0x%0X", 1187 myname, intf_caps); 1188 #endif 1189 return (DDI_FAILURE); 1190 } 1191 1192 /* These two interrupts are mandatory */ 1193 if (!(intf_caps & TPM_INTF_INT_LOCALITY_CHANGE_INT)) { 1194 cmn_err(CE_WARN, "%s: Mandatory capability Locality Change Int " 1195 "not supported", myname); 1196 return (DDI_FAILURE); 1197 } 1198 if (!(intf_caps & TPM_INTF_INT_DATA_AVAIL_INT)) { 1199 cmn_err(CE_WARN, "%s: Mandatory capability Data Available Int " 1200 "not supported", myname); 1201 return (DDI_FAILURE); 1202 } 1203 1204 /* 1205 * Before we start writing anything to TPM's registers, 1206 * make sure we are in locality 0 1207 */ 1208 ret = tis_request_locality(tpm, DEFAULT_LOCALITY); 1209 if (ret != DDI_SUCCESS) { 1210 cmn_err(CE_WARN, "%s: Unable to request locality %d", myname, 1211 DEFAULT_LOCALITY); 1212 return (DDI_FAILURE); 1213 } /* Now we can refer to the locality as tpm->locality */ 1214 1215 tpm->timeout_poll = drv_usectohz(TPM_POLLING_TIMEOUT); 1216 tpm->intr_enabled = 0; 1217 1218 /* Get the real timeouts from the TPM */ 1219 ret = tpm_get_timeouts(tpm); 1220 if (ret != DDI_SUCCESS) { 1221 cmn_err(CE_WARN, "%s: tpm_get_timeouts error", myname); 1222 return (DDI_FAILURE); 1223 } 1224 1225 ret = tpm_get_duration(tpm); 1226 if (ret != DDI_SUCCESS) { 1227 cmn_err(CE_WARN, "%s: tpm_get_duration error", myname); 1228 return (DDI_FAILURE); 1229 } 1230 1231 /* This gets the TPM version information */ 1232 ret = tpm_get_version(tpm); 1233 if (ret != DDI_SUCCESS) { 1234 cmn_err(CE_WARN, "%s: tpm_get_version error", myname); 1235 return (DDI_FAILURE); 1236 } 1237 1238 /* 1239 * Unless the TPM completes the test of its commands, 1240 * it can return an error when the untested commands are called 1241 */ 1242 ret = tpm_continue_selftest(tpm); 1243 if (ret != DDI_SUCCESS) { 1244 cmn_err(CE_WARN, "%s: tpm_continue_selftest error", myname); 1245 return (DDI_FAILURE); 1246 } 1247 return (DDI_SUCCESS); 1248 } 1249 1250 /* 1251 * Module Entry points 1252 */ 1253 int 1254 _init(void) 1255 { 1256 int ret; 1257 1258 ret = ddi_soft_state_init(&statep, sizeof (tpm_state_t), 1); 1259 if (ret) 1260 { 1261 cmn_err(CE_WARN, "ddi_soft_state_init failed: %d", ret); 1262 return (ret); 1263 } 1264 ret = mod_install(&tpm_ml); 1265 if (ret != 0) { 1266 cmn_err(CE_WARN, "_init: mod_install returned non-zero"); 1267 ddi_soft_state_fini(&statep); 1268 return (ret); 1269 } 1270 1271 return (ret); 1272 } 1273 1274 int 1275 _info(struct modinfo *modinfop) 1276 { 1277 int ret; 1278 ret = mod_info(&tpm_ml, modinfop); 1279 if (ret == 0) 1280 cmn_err(CE_WARN, "mod_info failed: %d", ret); 1281 1282 return (ret); 1283 } 1284 1285 int 1286 _fini() 1287 { 1288 int ret; 1289 1290 ret = mod_remove(&tpm_ml); 1291 if (ret != 0) 1292 return (ret); 1293 1294 ddi_soft_state_fini(&statep); 1295 1296 return (ret); 1297 } 1298 /* End of driver configuration functions */ 1299 1300 static int 1301 tpm_resume(tpm_state_t *tpm) 1302 { 1303 mutex_enter(&tpm->pm_mutex); 1304 if (!tpm->suspended) { 1305 mutex_exit(&tpm->pm_mutex); 1306 return (DDI_FAILURE); 1307 } 1308 tpm->suspended = 0; 1309 cv_broadcast(&tpm->suspend_cv); 1310 mutex_exit(&tpm->pm_mutex); 1311 1312 return (DDI_SUCCESS); 1313 } 1314 1315 #ifdef sun4v 1316 static uint64_t hsvc_tpm_minor = 0; 1317 static hsvc_info_t hsvc_tpm = { 1318 HSVC_REV_1, NULL, HSVC_GROUP_TPM, 1, 0, NULL 1319 }; 1320 #endif 1321 1322 /* 1323 * Sun DDI/DDK entry points 1324 */ 1325 static int 1326 tpm_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) 1327 { 1328 int ret; 1329 int instance; 1330 #ifndef sun4v 1331 int idx, nregs; 1332 #endif 1333 char *myname = "tpm_attach"; 1334 tpm_state_t *tpm = NULL; 1335 1336 ASSERT(dip != NULL); 1337 1338 instance = ddi_get_instance(dip); 1339 if (instance < 0) 1340 return (DDI_FAILURE); 1341 1342 /* Nothing out of ordinary here */ 1343 switch (cmd) { 1344 case DDI_ATTACH: 1345 if (ddi_soft_state_zalloc(statep, instance) == DDI_SUCCESS) { 1346 tpm = ddi_get_soft_state(statep, instance); 1347 if (tpm == NULL) { 1348 cmn_err(CE_WARN, 1349 "%s: cannot get state information.", 1350 myname); 1351 return (DDI_FAILURE); 1352 } 1353 tpm->dip = dip; 1354 } else { 1355 cmn_err(CE_WARN, 1356 "%s: cannot allocate state information.", 1357 myname); 1358 return (DDI_FAILURE); 1359 } 1360 break; 1361 case DDI_RESUME: 1362 tpm = ddi_get_soft_state(statep, instance); 1363 if (tpm == NULL) { 1364 cmn_err(CE_WARN, "%s: cannot get state information.", 1365 myname); 1366 return (DDI_FAILURE); 1367 } 1368 return (tpm_resume(tpm)); 1369 default: 1370 cmn_err(CE_WARN, "%s: cmd %d is not implemented", myname, cmd); 1371 ret = DDI_FAILURE; 1372 goto FAIL; 1373 } 1374 1375 /* Zeroize the flag, which is used to keep track of what is allocated */ 1376 tpm->flags = 0; 1377 1378 #ifdef sun4v 1379 ret = hsvc_register(&hsvc_tpm, &hsvc_tpm_minor); 1380 if (ret != 0) { 1381 cmn_err(CE_WARN, "%s: failed to register with " 1382 "hypervisor: 0x%0x", myname, ret); 1383 goto FAIL; 1384 } 1385 tpm->flags |= TPM_HSVC_REGISTERED; 1386 #else 1387 tpm->accattr.devacc_attr_version = DDI_DEVICE_ATTR_V0; 1388 tpm->accattr.devacc_attr_endian_flags = DDI_NEVERSWAP_ACC; 1389 tpm->accattr.devacc_attr_dataorder = DDI_STRICTORDER_ACC; 1390 1391 idx = 0; 1392 ret = ddi_dev_nregs(tpm->dip, &nregs); 1393 if (ret != DDI_SUCCESS) 1394 goto FAIL; 1395 1396 /* 1397 * TPM vendors put the TPM registers in different 1398 * slots in their register lists. They are not always 1399 * the 1st set of registers, for instance. 1400 * Loop until we find the set that matches the expected 1401 * register size (0x5000). 1402 */ 1403 for (idx = 0; idx < nregs; idx++) { 1404 off_t regsize; 1405 1406 if ((ret = ddi_dev_regsize(tpm->dip, idx, ®size)) != 1407 DDI_SUCCESS) 1408 goto FAIL; 1409 /* The TIS spec says the TPM registers must be 0x5000 bytes */ 1410 if (regsize == 0x5000) 1411 break; 1412 } 1413 if (idx == nregs) 1414 return (DDI_FAILURE); 1415 1416 ret = ddi_regs_map_setup(tpm->dip, idx, (caddr_t *)&tpm->addr, 1417 (offset_t)0, (offset_t)0x5000, 1418 &tpm->accattr, &tpm->handle); 1419 1420 if (ret != DDI_SUCCESS) { 1421 goto FAIL; 1422 } 1423 tpm->flags |= TPM_DIDREGSMAP; 1424 #endif 1425 /* Enable TPM device according to the TIS specification */ 1426 ret = tis_init(tpm); 1427 if (ret != DDI_SUCCESS) { 1428 cmn_err(CE_WARN, "%s: tis_init() failed with error %d", 1429 myname, ret); 1430 1431 /* We need to clean up the ddi_regs_map_setup call */ 1432 if (tpm->flags & TPM_DIDREGSMAP) { 1433 ddi_regs_map_free(&tpm->handle); 1434 tpm->handle = NULL; 1435 tpm->flags &= ~TPM_DIDREGSMAP; 1436 } 1437 goto FAIL; 1438 } 1439 1440 /* Initialize the inter-process lock */ 1441 mutex_init(&tpm->dev_lock, NULL, MUTEX_DRIVER, NULL); 1442 mutex_init(&tpm->pm_mutex, NULL, MUTEX_DRIVER, NULL); 1443 cv_init(&tpm->suspend_cv, NULL, CV_DRIVER, NULL); 1444 1445 /* Set the suspend/resume property */ 1446 (void) ddi_prop_update_string(DDI_DEV_T_NONE, dip, 1447 "pm-hardware-state", "needs-suspend-resume"); 1448 1449 mutex_enter(&tpm->pm_mutex); 1450 tpm->suspended = 0; 1451 mutex_exit(&tpm->pm_mutex); 1452 1453 tpm->flags |= TPM_DID_MUTEX; 1454 1455 /* Initialize the buffer and the lock associated with it */ 1456 tpm->bufsize = TPM_IO_BUF_SIZE; 1457 tpm->iobuf = kmem_zalloc((sizeof (uint8_t))*(tpm->bufsize), KM_SLEEP); 1458 tpm->flags |= TPM_DID_IO_ALLOC; 1459 1460 mutex_init(&tpm->iobuf_lock, NULL, MUTEX_DRIVER, NULL); 1461 tpm->flags |= TPM_DID_IO_MUTEX; 1462 1463 cv_init(&tpm->iobuf_cv, NULL, CV_DRIVER, NULL); 1464 tpm->flags |= TPM_DID_IO_CV; 1465 1466 /* Create minor node */ 1467 ret = ddi_create_minor_node(dip, "tpm", S_IFCHR, ddi_get_instance(dip), 1468 DDI_PSEUDO, 0); 1469 if (ret != DDI_SUCCESS) { 1470 cmn_err(CE_WARN, "%s: ddi_create_minor_node failed", myname); 1471 goto FAIL; 1472 } 1473 tpm->flags |= TPM_DIDMINOR; 1474 1475 #ifdef KCF_TPM_RNG_PROVIDER 1476 /* register RNG with kcf */ 1477 if (tpmrng_register(tpm) != DDI_SUCCESS) 1478 cmn_err(CE_WARN, "%s: tpm RNG failed to register with kcf", 1479 myname); 1480 #endif 1481 1482 return (DDI_SUCCESS); 1483 FAIL: 1484 cmn_err(CE_WARN, "%s: tpm failed to attach", myname); 1485 if (tpm != NULL) { 1486 tpm_cleanup(dip, tpm); 1487 ddi_soft_state_free(statep, instance); 1488 tpm = NULL; 1489 } 1490 1491 return (DDI_FAILURE); 1492 } 1493 1494 /* 1495 * Called by tpm_detach and tpm_attach (only on failure) 1496 * Free up the resources that are allocated 1497 */ 1498 static void 1499 tpm_cleanup(dev_info_t *dip, tpm_state_t *tpm) 1500 { 1501 if (tpm == NULL) 1502 return; 1503 1504 #ifdef KCF_TPM_RNG_PROVIDER 1505 (void) tpmrng_unregister(tpm); 1506 #endif 1507 1508 #ifdef sun4v 1509 if (tpm->flags & TPM_HSVC_REGISTERED) { 1510 (void) hsvc_unregister(&hsvc_tpm); 1511 tpm->flags &= ~(TPM_HSVC_REGISTERED); 1512 } 1513 #endif 1514 if (tpm->flags & TPM_DID_MUTEX) { 1515 mutex_destroy(&tpm->dev_lock); 1516 tpm->flags &= ~(TPM_DID_MUTEX); 1517 } 1518 if (tpm->flags & TPM_DID_IO_ALLOC) { 1519 ASSERT(tpm->iobuf != NULL); 1520 kmem_free(tpm->iobuf, (sizeof (uint8_t))*(tpm->bufsize)); 1521 tpm->flags &= ~(TPM_DID_IO_ALLOC); 1522 } 1523 if (tpm->flags & TPM_DID_IO_MUTEX) { 1524 mutex_destroy(&tpm->iobuf_lock); 1525 tpm->flags &= ~(TPM_DID_IO_MUTEX); 1526 } 1527 if (tpm->flags & TPM_DID_IO_CV) { 1528 cv_destroy(&tpm->iobuf_cv); 1529 tpm->flags &= ~(TPM_DID_IO_CV); 1530 } 1531 if (tpm->flags & TPM_DIDREGSMAP) { 1532 /* Free the mapped addresses */ 1533 if (tpm->handle != NULL) 1534 ddi_regs_map_free(&tpm->handle); 1535 tpm->flags &= ~(TPM_DIDREGSMAP); 1536 } 1537 if (tpm->flags & TPM_DIDMINOR) { 1538 /* Remove minor node */ 1539 ddi_remove_minor_node(dip, NULL); 1540 tpm->flags &= ~(TPM_DIDMINOR); 1541 } 1542 } 1543 1544 static int 1545 tpm_suspend(tpm_state_t *tpm) 1546 { 1547 if (tpm == NULL) 1548 return (DDI_FAILURE); 1549 mutex_enter(&tpm->pm_mutex); 1550 if (tpm->suspended) { 1551 mutex_exit(&tpm->pm_mutex); 1552 return (DDI_SUCCESS); 1553 } 1554 tpm->suspended = 1; 1555 mutex_exit(&tpm->pm_mutex); 1556 1557 return (DDI_SUCCESS); 1558 } 1559 1560 static int 1561 tpm_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) 1562 { 1563 char *myname = "tpm_detach"; 1564 int instance; 1565 tpm_state_t *tpm; 1566 1567 ASSERT(dip != NULL); 1568 1569 instance = ddi_get_instance(dip); 1570 if (instance < 0) 1571 return (DDI_FAILURE); 1572 1573 if ((tpm = ddi_get_soft_state(statep, instance)) == NULL) { 1574 cmn_err(CE_WARN, "%s: stored pointer to tpm state is NULL", 1575 myname); 1576 return (ENXIO); 1577 } 1578 1579 switch (cmd) { 1580 case DDI_DETACH: 1581 /* Body is after the switch stmt */ 1582 break; 1583 case DDI_SUSPEND: 1584 return (tpm_suspend(tpm)); 1585 default: 1586 cmn_err(CE_WARN, "%s: case %d not implemented", myname, cmd); 1587 return (DDI_FAILURE); 1588 } 1589 1590 /* Since we are freeing tpm structure, we need to gain the lock */ 1591 1592 tpm_cleanup(dip, tpm); 1593 1594 mutex_destroy(&tpm->pm_mutex); 1595 cv_destroy(&tpm->suspend_cv); 1596 1597 /* Free the soft state */ 1598 ddi_soft_state_free(statep, instance); 1599 tpm = NULL; 1600 1601 return (DDI_SUCCESS); 1602 } 1603 1604 /*ARGSUSED*/ 1605 static int 1606 tpm_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg, void **resultp) 1607 { 1608 char *myname = "tpm_getinfo"; 1609 int instance; 1610 tpm_state_t *tpm; 1611 1612 instance = ddi_get_instance(dip); 1613 if ((tpm = ddi_get_soft_state(statep, instance)) == NULL) { 1614 cmn_err(CE_WARN, "%s: stored pointer to tpm state is NULL", 1615 myname); 1616 return (DDI_FAILURE); 1617 } 1618 1619 switch (cmd) { 1620 case DDI_INFO_DEVT2DEVINFO: 1621 *resultp = tpm->dip; 1622 break; 1623 case DDI_INFO_DEVT2INSTANCE: 1624 *resultp = 0; 1625 break; 1626 default: 1627 cmn_err(CE_WARN, "%s: cmd %d is not implemented", myname, cmd); 1628 return (DDI_FAILURE); 1629 } 1630 return (DDI_SUCCESS); 1631 } 1632 1633 /* 1634 * Driver entry points 1635 */ 1636 1637 /*ARGSUSED*/ 1638 static int 1639 tpm_open(dev_t *devp, int flag, int otyp, cred_t *cred) 1640 { 1641 char *myname = "tpm_open"; 1642 int instance; 1643 tpm_state_t *tpm; 1644 1645 ASSERT(devp != NULL); 1646 1647 instance = getminor(*devp); 1648 if ((tpm = ddi_get_soft_state(statep, instance)) == NULL) { 1649 cmn_err(CE_WARN, "%s: stored pointer to tpm state is NULL", 1650 myname); 1651 return (ENXIO); 1652 } 1653 if (otyp != OTYP_CHR) { 1654 cmn_err(CE_WARN, "%s: otyp(%d) != OTYP_CHR(%d)", 1655 myname, otyp, OTYP_CHR); 1656 return (EINVAL); 1657 } 1658 TPM_EXCLUSIVE_LOCK(tpm); 1659 1660 mutex_enter(&tpm->dev_lock); 1661 if (tpm->dev_held) { 1662 cmn_err(CE_WARN, "%s: the device is already being used", 1663 myname); 1664 mutex_exit(&tpm->dev_lock); 1665 return (EBUSY); 1666 } 1667 1668 /* The device is free so mark it busy */ 1669 tpm->dev_held = 1; 1670 mutex_exit(&tpm->dev_lock); 1671 1672 return (0); 1673 } 1674 1675 /*ARGSUSED*/ 1676 static int 1677 tpm_close(dev_t dev, int flag, int otyp, cred_t *cred) 1678 { 1679 char *myname = "tpm_close"; 1680 int instance; 1681 tpm_state_t *tpm; 1682 1683 instance = getminor(dev); 1684 if ((tpm = ddi_get_soft_state(statep, instance)) == NULL) { 1685 cmn_err(CE_WARN, "%s: stored pointer to tpm state is NULL", 1686 myname); 1687 return (ENXIO); 1688 } 1689 if (otyp != OTYP_CHR) { 1690 cmn_err(CE_WARN, "%s: otyp(%d) != OTYP_CHR(%d)", 1691 myname, otyp, OTYP_CHR); 1692 return (EINVAL); 1693 } 1694 TPM_EXCLUSIVE_LOCK(tpm); 1695 1696 ASSERT(tpm->dev_held); 1697 1698 mutex_enter(&tpm->dev_lock); 1699 ASSERT(mutex_owned(&tpm->dev_lock)); 1700 tpm->dev_held = 0; 1701 mutex_exit(&tpm->dev_lock); 1702 1703 return (0); 1704 } 1705 1706 /*ARGSUSED*/ 1707 static int 1708 tpm_read(dev_t dev, struct uio *uiop, cred_t *credp) 1709 { 1710 int ret; 1711 uint32_t size; 1712 char *myname = "tpm_read"; 1713 int instance; 1714 tpm_state_t *tpm; 1715 1716 instance = getminor(dev); 1717 if ((tpm = ddi_get_soft_state(statep, instance)) == NULL) { 1718 cmn_err(CE_WARN, "%s: stored pointer to tpm state is NULL", 1719 myname); 1720 return (ENXIO); 1721 } 1722 if (uiop == NULL) { 1723 cmn_err(CE_WARN, "%s: passed in uiop is NULL", myname); 1724 return (EFAULT); 1725 } 1726 1727 TPM_EXCLUSIVE_LOCK(tpm); 1728 1729 /* Receive the data after requiring the lock */ 1730 ret = tpm_io_lock(tpm); 1731 1732 /* Timeout reached */ 1733 if (ret) 1734 return (ret); 1735 1736 if (uiop->uio_resid > tpm->bufsize) { 1737 cmn_err(CE_WARN, "%s: read_in data is bigger " 1738 "than tpm->bufsize:read in:%d, bufsiz:%d", 1739 myname, (int)uiop->uio_resid, (int)tpm->bufsize); 1740 ret = EIO; 1741 goto OUT; 1742 } 1743 1744 ret = tis_recv_data(tpm, tpm->iobuf, tpm->bufsize); 1745 if (ret < TPM_HEADER_SIZE) { 1746 cmn_err(CE_WARN, "%s: tis_recv_data returned error", myname); 1747 ret = EIO; 1748 goto OUT; 1749 } 1750 1751 size = load32(tpm->iobuf, 2); 1752 if (ret != size) { 1753 cmn_err(CE_WARN, "%s: tis_recv_data:" 1754 "expected size=%d, actually read=%d", 1755 myname, size, ret); 1756 ret = EIO; 1757 goto OUT; 1758 } 1759 1760 /* Send the buffer from the kernel to the userspace */ 1761 ret = uiomove(tpm->iobuf, size, UIO_READ, uiop); 1762 if (ret) { 1763 cmn_err(CE_WARN, "%s: uiomove returned error", myname); 1764 goto OUT; 1765 } 1766 1767 /* Zeroize the buffer... */ 1768 bzero(tpm->iobuf, tpm->bufsize); 1769 ret = DDI_SUCCESS; 1770 OUT: 1771 /* We are done now: wake up the waiting threads */ 1772 tpm_unlock(tpm); 1773 1774 return (ret); 1775 } 1776 1777 /*ARGSUSED*/ 1778 static int 1779 tpm_write(dev_t dev, struct uio *uiop, cred_t *credp) 1780 { 1781 int ret; 1782 size_t len; 1783 uint32_t size; 1784 char *myname = "tpm_write"; 1785 int instance; 1786 tpm_state_t *tpm; 1787 1788 instance = getminor(dev); 1789 if ((tpm = ddi_get_soft_state(statep, instance)) == NULL) { 1790 cmn_err(CE_WARN, "%s: stored pointer to tpm state is NULL", 1791 myname); 1792 return (ENXIO); 1793 } 1794 1795 if (uiop == NULL) { 1796 cmn_err(CE_WARN, "%s: passed in uiop is NULL", myname); 1797 return (EFAULT); 1798 } 1799 1800 TPM_EXCLUSIVE_LOCK(tpm); 1801 1802 len = uiop->uio_resid; 1803 if (len == 0) { 1804 cmn_err(CE_WARN, "%s: requested read of len 0", myname); 1805 return (0); 1806 } 1807 1808 /* Get the lock for using iobuf */ 1809 ret = tpm_io_lock(tpm); 1810 /* Timeout Reached */ 1811 if (ret) 1812 return (ret); 1813 1814 /* Copy the header and parse the structure to find out the size... */ 1815 ret = uiomove(tpm->iobuf, TPM_HEADER_SIZE, UIO_WRITE, uiop); 1816 if (ret) { 1817 cmn_err(CE_WARN, "%s: uiomove returned error" 1818 "while getting the the header", 1819 myname); 1820 goto OUT; 1821 } 1822 1823 /* Get the buffersize from the command buffer structure */ 1824 size = load32(tpm->iobuf, TPM_PARAMSIZE_OFFSET); 1825 1826 /* Copy the command to the contiguous buffer */ 1827 if (size > tpm->bufsize) { 1828 cmn_err(CE_WARN, "%s: size %d is greater than " 1829 "the tpm's input buffer size %d", 1830 myname, (int)size, (int)tpm->bufsize); 1831 ret = ENXIO; 1832 goto OUT; 1833 } 1834 1835 /* Copy the buffer from the userspace to kernel */ 1836 ret = uiomove(tpm->iobuf+TPM_HEADER_SIZE, size-TPM_HEADER_SIZE, 1837 UIO_WRITE, uiop); 1838 1839 if (ret) { 1840 cmn_err(CE_WARN, "%s: uiomove returned error" 1841 "while getting the rest of the command", myname); 1842 goto OUT; 1843 } 1844 1845 /* Send the command */ 1846 ret = tis_send_data(tpm, tpm->iobuf, size); 1847 if (ret != DDI_SUCCESS) { 1848 cmn_err(CE_WARN, "%s: tis_send_data returned error", myname); 1849 ret = EFAULT; 1850 goto OUT; 1851 } 1852 1853 /* Zeroize the buffer... */ 1854 bzero(tpm->iobuf, tpm->bufsize); 1855 ret = DDI_SUCCESS; 1856 OUT: 1857 tpm_unlock(tpm); 1858 return (ret); 1859 } 1860 1861 /* 1862 * This is to deal with the contentions for the iobuf 1863 */ 1864 static inline int 1865 tpm_io_lock(tpm_state_t *tpm) 1866 { 1867 int ret; 1868 clock_t timeout; 1869 1870 mutex_enter(&tpm->iobuf_lock); 1871 ASSERT(mutex_owned(&tpm->iobuf_lock)); 1872 1873 timeout = ddi_get_lbolt() + drv_usectohz(TPM_IO_TIMEOUT); 1874 1875 /* Wait until the iobuf becomes free with the timeout */ 1876 while (tpm->iobuf_inuse) { 1877 ret = cv_timedwait(&tpm->iobuf_cv, &tpm->iobuf_lock, timeout); 1878 if (ret <= 0) { 1879 /* Timeout reached */ 1880 mutex_exit(&tpm->iobuf_lock); 1881 #ifdef DEBUG 1882 cmn_err(CE_WARN, "tpm_io_lock:iorequest timed out"); 1883 #endif 1884 return (ETIME); 1885 } 1886 } 1887 tpm->iobuf_inuse = 1; 1888 mutex_exit(&tpm->iobuf_lock); 1889 return (0); 1890 } 1891 1892 /* 1893 * This is to deal with the contentions for the iobuf 1894 */ 1895 static inline void 1896 tpm_unlock(tpm_state_t *tpm) 1897 { 1898 /* Wake up the waiting threads */ 1899 mutex_enter(&tpm->iobuf_lock); 1900 ASSERT(tpm->iobuf_inuse == 1 && mutex_owned(&tpm->iobuf_lock)); 1901 tpm->iobuf_inuse = 0; 1902 cv_broadcast(&tpm->iobuf_cv); 1903 mutex_exit(&tpm->iobuf_lock); 1904 } 1905 1906 #ifdef KCF_TPM_RNG_PROVIDER 1907 /* 1908 * Random number generator entry points 1909 */ 1910 static void 1911 strncpy_spacepad(uchar_t *s1, char *s2, int n) 1912 { 1913 int s2len = strlen(s2); 1914 (void) strncpy((char *)s1, s2, n); 1915 if (s2len < n) 1916 (void) memset(s1 + s2len, ' ', n - s2len); 1917 } 1918 1919 /*ARGSUSED*/ 1920 static int 1921 tpmrng_ext_info(crypto_provider_handle_t prov, 1922 crypto_provider_ext_info_t *ext_info, 1923 crypto_req_handle_t cfreq) 1924 { 1925 tpm_state_t *tpm = (tpm_state_t *)prov; 1926 char buf[64]; 1927 1928 if (tpm == NULL) 1929 return (DDI_FAILURE); 1930 1931 strncpy_spacepad(ext_info->ei_manufacturerID, 1932 (char *)tpm->vers_info.tpmVendorID, 1933 sizeof (ext_info->ei_manufacturerID)); 1934 1935 strncpy_spacepad(ext_info->ei_model, "0", 1936 sizeof (ext_info->ei_model)); 1937 strncpy_spacepad(ext_info->ei_serial_number, "0", 1938 sizeof (ext_info->ei_serial_number)); 1939 1940 ext_info->ei_flags = CRYPTO_EXTF_RNG | CRYPTO_EXTF_SO_PIN_LOCKED; 1941 ext_info->ei_max_session_count = CRYPTO_EFFECTIVELY_INFINITE; 1942 ext_info->ei_max_pin_len = 0; 1943 ext_info->ei_min_pin_len = 0; 1944 ext_info->ei_total_public_memory = CRYPTO_UNAVAILABLE_INFO; 1945 ext_info->ei_free_public_memory = CRYPTO_UNAVAILABLE_INFO; 1946 ext_info->ei_total_private_memory = CRYPTO_UNAVAILABLE_INFO; 1947 ext_info->ei_free_public_memory = CRYPTO_UNAVAILABLE_INFO; 1948 ext_info->ei_time[0] = 0; 1949 1950 ext_info->ei_hardware_version.cv_major = tpm->vers_info.version.major; 1951 ext_info->ei_hardware_version.cv_minor = tpm->vers_info.version.minor; 1952 ext_info->ei_firmware_version.cv_major = 1953 tpm->vers_info.version.revMajor; 1954 ext_info->ei_firmware_version.cv_minor = 1955 tpm->vers_info.version.revMinor; 1956 1957 (void) snprintf(buf, sizeof (buf), "tpmrng TPM RNG"); 1958 1959 strncpy_spacepad(ext_info->ei_label, buf, 1960 sizeof (ext_info->ei_label)); 1961 #undef BUFSZ 1962 return (CRYPTO_SUCCESS); 1963 1964 } 1965 1966 static int 1967 tpmrng_register(tpm_state_t *tpm) 1968 { 1969 int ret; 1970 char ID[64]; 1971 crypto_mech_name_t *rngmech; 1972 1973 ASSERT(tpm != NULL); 1974 1975 (void) snprintf(ID, sizeof (ID), "tpmrng %s", IDENT_TPMRNG); 1976 1977 tpmrng_prov_info.pi_provider_description = ID; 1978 tpmrng_prov_info.pi_provider_dev.pd_hw = tpm->dip; 1979 tpmrng_prov_info.pi_provider_handle = tpm; 1980 1981 ret = crypto_register_provider(&tpmrng_prov_info, &tpm->n_prov); 1982 if (ret != CRYPTO_SUCCESS) { 1983 tpm->n_prov = NULL; 1984 return (DDI_FAILURE); 1985 } 1986 1987 crypto_provider_notification(tpm->n_prov, CRYPTO_PROVIDER_READY); 1988 1989 rngmech = kmem_zalloc(strlen("random") + 1, KM_SLEEP); 1990 (void) memcpy(rngmech, "random", 6); 1991 ret = crypto_load_dev_disabled("tpm", ddi_get_instance(tpm->dip), 1992 1, rngmech); 1993 if (ret != CRYPTO_SUCCESS) { 1994 cmn_err(CE_WARN, "crypto_load_dev_disabled failed (%d)", ret); 1995 } 1996 return (DDI_SUCCESS); 1997 } 1998 1999 static int 2000 tpmrng_unregister(tpm_state_t *tpm) 2001 { 2002 int ret; 2003 ASSERT(tpm != NULL); 2004 if (tpm->n_prov) { 2005 ret = crypto_unregister_provider(tpm->n_prov); 2006 tpm->n_prov = NULL; 2007 if (ret != CRYPTO_SUCCESS) 2008 return (DDI_FAILURE); 2009 } 2010 return (DDI_SUCCESS); 2011 } 2012 2013 /*ARGSUSED*/ 2014 static void 2015 tpmrng_provider_status(crypto_provider_handle_t provider, uint_t *status) 2016 { 2017 *status = CRYPTO_PROVIDER_READY; 2018 } 2019 2020 /*ARGSUSED*/ 2021 static int 2022 tpmrng_seed_random(crypto_provider_handle_t provider, crypto_session_id_t sid, 2023 uchar_t *buf, size_t len, uint_t entropy_est, uint32_t flags, 2024 crypto_req_handle_t req) 2025 { 2026 int ret; 2027 tpm_state_t *tpm; 2028 uint32_t len32; 2029 /* Max length of seed is 256 bytes, add 14 for header. */ 2030 uint8_t cmdbuf[270] = { 2031 0, 193, /* TPM_TAG_RQU COMMAND */ 2032 0, 0, 0, 0x0A, /* paramsize in bytes */ 2033 0, 0, 0, TPM_ORD_StirRandom, 2034 0, 0, 0, 0 /* number of input bytes (< 256) */ 2035 }; 2036 uint32_t buflen; 2037 2038 if (len == 0 || len > 255 || buf == NULL) 2039 return (CRYPTO_ARGUMENTS_BAD); 2040 2041 tpm = (tpm_state_t *)provider; 2042 if (tpm == NULL) 2043 return (CRYPTO_INVALID_CONTEXT); 2044 2045 /* Acquire lock for exclusive use of TPM */ 2046 TPM_EXCLUSIVE_LOCK(tpm); 2047 2048 ret = tpm_io_lock(tpm); 2049 /* Timeout reached */ 2050 if (ret) 2051 return (CRYPTO_BUSY); 2052 2053 /* TPM only handles 32 bit length, so truncate if too big. */ 2054 len32 = (uint32_t)len; 2055 buflen = len32 + 14; 2056 2057 /* The length must be in network order */ 2058 buflen = htonl(buflen); 2059 bcopy(&buflen, cmdbuf + 2, sizeof (uint32_t)); 2060 2061 /* Convert it back */ 2062 buflen = ntohl(buflen); 2063 2064 /* length must be in network order */ 2065 len32 = htonl(len32); 2066 bcopy(&len32, cmdbuf + 10, sizeof (uint32_t)); 2067 2068 /* convert it back */ 2069 len32 = ntohl(len32); 2070 2071 bcopy(buf, cmdbuf + 14, len32); 2072 2073 ret = itpm_command(tpm, cmdbuf, buflen); 2074 tpm_unlock(tpm); 2075 2076 if (ret != DDI_SUCCESS) { 2077 #ifdef DEBUG 2078 cmn_err(CE_WARN, "tpmrng_seed_random failed"); 2079 #endif 2080 return (CRYPTO_FAILED); 2081 } 2082 2083 return (CRYPTO_SUCCESS); 2084 } 2085 2086 /* ARGSUSED */ 2087 static int 2088 tpmrng_generate_random(crypto_provider_handle_t provider, 2089 crypto_session_id_t sid, uchar_t *buf, size_t len, crypto_req_handle_t req) 2090 { 2091 int ret; 2092 tpm_state_t *tpm; 2093 uint8_t hdr[14] = { 2094 0, 193, /* TPM_TAG_RQU COMMAND */ 2095 0, 0, 0, 14, /* paramsize in bytes */ 2096 0, 0, 0, TPM_ORD_GetRandom, 2097 0, 0, 0, 0 2098 }; 2099 uint8_t *cmdbuf = NULL; 2100 uint32_t len32 = (uint32_t)len; 2101 uint32_t buflen = len32 + sizeof (hdr); 2102 2103 if (len == 0 || buf == NULL) 2104 return (CRYPTO_ARGUMENTS_BAD); 2105 2106 tpm = (tpm_state_t *)provider; 2107 if (tpm == NULL) 2108 return (CRYPTO_INVALID_CONTEXT); 2109 2110 TPM_EXCLUSIVE_LOCK(tpm); 2111 2112 ret = tpm_io_lock(tpm); 2113 /* Timeout reached */ 2114 if (ret) 2115 return (CRYPTO_BUSY); 2116 2117 cmdbuf = kmem_zalloc(buflen, KM_SLEEP); 2118 bcopy(hdr, cmdbuf, sizeof (hdr)); 2119 2120 /* Length is written in network byte order */ 2121 len32 = htonl(len32); 2122 bcopy(&len32, cmdbuf + 10, sizeof (uint32_t)); 2123 2124 ret = itpm_command(tpm, cmdbuf, buflen); 2125 if (ret != DDI_SUCCESS) { 2126 #ifdef DEBUG 2127 cmn_err(CE_WARN, "tpmrng_generate_random failed"); 2128 #endif 2129 kmem_free(cmdbuf, buflen); 2130 tpm_unlock(tpm); 2131 return (CRYPTO_FAILED); 2132 } 2133 2134 /* Find out how many bytes were really returned */ 2135 len32 = load32(cmdbuf, 10); 2136 2137 /* Copy the random bytes back to the callers buffer */ 2138 bcopy(cmdbuf + 14, buf, len32); 2139 2140 kmem_free(cmdbuf, buflen); 2141 tpm_unlock(tpm); 2142 2143 return (CRYPTO_SUCCESS); 2144 } 2145 #endif /* KCF_TPM_RNG_PROVIDER */ 2146