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 #ifdef DEBUG 1356 cmn_err(CE_WARN, 1357 "%s: cannot allocate state information.", 1358 myname); 1359 #endif 1360 return (DDI_FAILURE); 1361 } 1362 break; 1363 case DDI_RESUME: 1364 tpm = ddi_get_soft_state(statep, instance); 1365 if (tpm == NULL) { 1366 cmn_err(CE_WARN, "%s: cannot get state information.", 1367 myname); 1368 return (DDI_FAILURE); 1369 } 1370 return (tpm_resume(tpm)); 1371 default: 1372 cmn_err(CE_WARN, "%s: cmd %d is not implemented", myname, cmd); 1373 ret = DDI_FAILURE; 1374 goto FAIL; 1375 } 1376 1377 /* Zeroize the flag, which is used to keep track of what is allocated */ 1378 tpm->flags = 0; 1379 1380 #ifdef sun4v 1381 ret = hsvc_register(&hsvc_tpm, &hsvc_tpm_minor); 1382 if (ret != 0) { 1383 cmn_err(CE_WARN, "%s: failed to register with " 1384 "hypervisor: 0x%0x", myname, ret); 1385 goto FAIL; 1386 } 1387 tpm->flags |= TPM_HSVC_REGISTERED; 1388 #else 1389 tpm->accattr.devacc_attr_version = DDI_DEVICE_ATTR_V0; 1390 tpm->accattr.devacc_attr_endian_flags = DDI_NEVERSWAP_ACC; 1391 tpm->accattr.devacc_attr_dataorder = DDI_STRICTORDER_ACC; 1392 1393 idx = 0; 1394 ret = ddi_dev_nregs(tpm->dip, &nregs); 1395 if (ret != DDI_SUCCESS) 1396 goto FAIL; 1397 1398 /* 1399 * TPM vendors put the TPM registers in different 1400 * slots in their register lists. They are not always 1401 * the 1st set of registers, for instance. 1402 * Loop until we find the set that matches the expected 1403 * register size (0x5000). 1404 */ 1405 for (idx = 0; idx < nregs; idx++) { 1406 off_t regsize; 1407 1408 if ((ret = ddi_dev_regsize(tpm->dip, idx, ®size)) != 1409 DDI_SUCCESS) 1410 goto FAIL; 1411 /* The TIS spec says the TPM registers must be 0x5000 bytes */ 1412 if (regsize == 0x5000) 1413 break; 1414 } 1415 if (idx == nregs) { 1416 ret = DDI_FAILURE; 1417 goto FAIL; 1418 } 1419 1420 ret = ddi_regs_map_setup(tpm->dip, idx, (caddr_t *)&tpm->addr, 1421 (offset_t)0, (offset_t)0x5000, 1422 &tpm->accattr, &tpm->handle); 1423 1424 if (ret != DDI_SUCCESS) { 1425 goto FAIL; 1426 } 1427 tpm->flags |= TPM_DIDREGSMAP; 1428 #endif 1429 /* Enable TPM device according to the TIS specification */ 1430 ret = tis_init(tpm); 1431 if (ret != DDI_SUCCESS) { 1432 cmn_err(CE_WARN, "%s: tis_init() failed with error %d", 1433 myname, ret); 1434 1435 /* We need to clean up the ddi_regs_map_setup call */ 1436 if (tpm->flags & TPM_DIDREGSMAP) { 1437 ddi_regs_map_free(&tpm->handle); 1438 tpm->handle = NULL; 1439 tpm->flags &= ~TPM_DIDREGSMAP; 1440 } 1441 goto FAIL; 1442 } 1443 1444 /* Initialize the inter-process lock */ 1445 mutex_init(&tpm->dev_lock, NULL, MUTEX_DRIVER, NULL); 1446 mutex_init(&tpm->pm_mutex, NULL, MUTEX_DRIVER, NULL); 1447 cv_init(&tpm->suspend_cv, NULL, CV_DRIVER, NULL); 1448 1449 /* Set the suspend/resume property */ 1450 (void) ddi_prop_update_string(DDI_DEV_T_NONE, dip, 1451 "pm-hardware-state", "needs-suspend-resume"); 1452 1453 mutex_enter(&tpm->pm_mutex); 1454 tpm->suspended = 0; 1455 mutex_exit(&tpm->pm_mutex); 1456 1457 tpm->flags |= TPM_DID_MUTEX; 1458 1459 /* Initialize the buffer and the lock associated with it */ 1460 tpm->bufsize = TPM_IO_BUF_SIZE; 1461 tpm->iobuf = kmem_zalloc((sizeof (uint8_t))*(tpm->bufsize), KM_SLEEP); 1462 tpm->flags |= TPM_DID_IO_ALLOC; 1463 1464 mutex_init(&tpm->iobuf_lock, NULL, MUTEX_DRIVER, NULL); 1465 tpm->flags |= TPM_DID_IO_MUTEX; 1466 1467 cv_init(&tpm->iobuf_cv, NULL, CV_DRIVER, NULL); 1468 tpm->flags |= TPM_DID_IO_CV; 1469 1470 /* Create minor node */ 1471 ret = ddi_create_minor_node(dip, "tpm", S_IFCHR, ddi_get_instance(dip), 1472 DDI_PSEUDO, 0); 1473 if (ret != DDI_SUCCESS) { 1474 cmn_err(CE_WARN, "%s: ddi_create_minor_node failed", myname); 1475 goto FAIL; 1476 } 1477 tpm->flags |= TPM_DIDMINOR; 1478 1479 #ifdef KCF_TPM_RNG_PROVIDER 1480 /* register RNG with kcf */ 1481 if (tpmrng_register(tpm) != DDI_SUCCESS) 1482 cmn_err(CE_WARN, "%s: tpm RNG failed to register with kcf", 1483 myname); 1484 #endif 1485 1486 return (DDI_SUCCESS); 1487 FAIL: 1488 if (tpm != NULL) { 1489 tpm_cleanup(dip, tpm); 1490 ddi_soft_state_free(statep, instance); 1491 tpm = NULL; 1492 } 1493 1494 return (DDI_FAILURE); 1495 } 1496 1497 /* 1498 * Called by tpm_detach and tpm_attach (only on failure) 1499 * Free up the resources that are allocated 1500 */ 1501 static void 1502 tpm_cleanup(dev_info_t *dip, tpm_state_t *tpm) 1503 { 1504 if (tpm == NULL) 1505 return; 1506 1507 #ifdef KCF_TPM_RNG_PROVIDER 1508 (void) tpmrng_unregister(tpm); 1509 #endif 1510 1511 #ifdef sun4v 1512 if (tpm->flags & TPM_HSVC_REGISTERED) { 1513 (void) hsvc_unregister(&hsvc_tpm); 1514 tpm->flags &= ~(TPM_HSVC_REGISTERED); 1515 } 1516 #endif 1517 if (tpm->flags & TPM_DID_MUTEX) { 1518 mutex_destroy(&tpm->dev_lock); 1519 mutex_destroy(&tpm->pm_mutex); 1520 cv_destroy(&tpm->suspend_cv); 1521 tpm->flags &= ~(TPM_DID_MUTEX); 1522 } 1523 if (tpm->flags & TPM_DID_IO_ALLOC) { 1524 ASSERT(tpm->iobuf != NULL); 1525 kmem_free(tpm->iobuf, (sizeof (uint8_t))*(tpm->bufsize)); 1526 tpm->flags &= ~(TPM_DID_IO_ALLOC); 1527 } 1528 if (tpm->flags & TPM_DID_IO_MUTEX) { 1529 mutex_destroy(&tpm->iobuf_lock); 1530 tpm->flags &= ~(TPM_DID_IO_MUTEX); 1531 } 1532 if (tpm->flags & TPM_DID_IO_CV) { 1533 cv_destroy(&tpm->iobuf_cv); 1534 tpm->flags &= ~(TPM_DID_IO_CV); 1535 } 1536 if (tpm->flags & TPM_DIDREGSMAP) { 1537 /* Free the mapped addresses */ 1538 if (tpm->handle != NULL) 1539 ddi_regs_map_free(&tpm->handle); 1540 tpm->flags &= ~(TPM_DIDREGSMAP); 1541 } 1542 if (tpm->flags & TPM_DIDMINOR) { 1543 /* Remove minor node */ 1544 ddi_remove_minor_node(dip, NULL); 1545 tpm->flags &= ~(TPM_DIDMINOR); 1546 } 1547 } 1548 1549 static int 1550 tpm_suspend(tpm_state_t *tpm) 1551 { 1552 if (tpm == NULL) 1553 return (DDI_FAILURE); 1554 mutex_enter(&tpm->pm_mutex); 1555 if (tpm->suspended) { 1556 mutex_exit(&tpm->pm_mutex); 1557 return (DDI_SUCCESS); 1558 } 1559 tpm->suspended = 1; 1560 mutex_exit(&tpm->pm_mutex); 1561 1562 return (DDI_SUCCESS); 1563 } 1564 1565 static int 1566 tpm_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) 1567 { 1568 char *myname = "tpm_detach"; 1569 int instance; 1570 tpm_state_t *tpm; 1571 1572 ASSERT(dip != NULL); 1573 1574 instance = ddi_get_instance(dip); 1575 if (instance < 0) 1576 return (DDI_FAILURE); 1577 1578 if ((tpm = ddi_get_soft_state(statep, instance)) == NULL) { 1579 cmn_err(CE_WARN, "%s: stored pointer to tpm state is NULL", 1580 myname); 1581 return (ENXIO); 1582 } 1583 1584 switch (cmd) { 1585 case DDI_DETACH: 1586 /* Body is after the switch stmt */ 1587 break; 1588 case DDI_SUSPEND: 1589 return (tpm_suspend(tpm)); 1590 default: 1591 cmn_err(CE_WARN, "%s: case %d not implemented", myname, cmd); 1592 return (DDI_FAILURE); 1593 } 1594 1595 /* Since we are freeing tpm structure, we need to gain the lock */ 1596 1597 tpm_cleanup(dip, tpm); 1598 1599 mutex_destroy(&tpm->pm_mutex); 1600 cv_destroy(&tpm->suspend_cv); 1601 1602 /* Free the soft state */ 1603 ddi_soft_state_free(statep, instance); 1604 tpm = NULL; 1605 1606 return (DDI_SUCCESS); 1607 } 1608 1609 /*ARGSUSED*/ 1610 static int 1611 tpm_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg, void **resultp) 1612 { 1613 char *myname = "tpm_getinfo"; 1614 int instance; 1615 tpm_state_t *tpm; 1616 1617 instance = ddi_get_instance(dip); 1618 if ((tpm = ddi_get_soft_state(statep, instance)) == NULL) { 1619 cmn_err(CE_WARN, "%s: stored pointer to tpm state is NULL", 1620 myname); 1621 return (DDI_FAILURE); 1622 } 1623 1624 switch (cmd) { 1625 case DDI_INFO_DEVT2DEVINFO: 1626 *resultp = tpm->dip; 1627 break; 1628 case DDI_INFO_DEVT2INSTANCE: 1629 *resultp = 0; 1630 break; 1631 default: 1632 cmn_err(CE_WARN, "%s: cmd %d is not implemented", myname, cmd); 1633 return (DDI_FAILURE); 1634 } 1635 return (DDI_SUCCESS); 1636 } 1637 1638 /* 1639 * Driver entry points 1640 */ 1641 1642 /*ARGSUSED*/ 1643 static int 1644 tpm_open(dev_t *devp, int flag, int otyp, cred_t *cred) 1645 { 1646 char *myname = "tpm_open"; 1647 int instance; 1648 tpm_state_t *tpm; 1649 1650 ASSERT(devp != NULL); 1651 1652 instance = getminor(*devp); 1653 if ((tpm = ddi_get_soft_state(statep, instance)) == NULL) { 1654 cmn_err(CE_WARN, "%s: stored pointer to tpm state is NULL", 1655 myname); 1656 return (ENXIO); 1657 } 1658 if (otyp != OTYP_CHR) { 1659 cmn_err(CE_WARN, "%s: otyp(%d) != OTYP_CHR(%d)", 1660 myname, otyp, OTYP_CHR); 1661 return (EINVAL); 1662 } 1663 TPM_EXCLUSIVE_LOCK(tpm); 1664 1665 mutex_enter(&tpm->dev_lock); 1666 if (tpm->dev_held) { 1667 cmn_err(CE_WARN, "%s: the device is already being used", 1668 myname); 1669 mutex_exit(&tpm->dev_lock); 1670 return (EBUSY); 1671 } 1672 1673 /* The device is free so mark it busy */ 1674 tpm->dev_held = 1; 1675 mutex_exit(&tpm->dev_lock); 1676 1677 return (0); 1678 } 1679 1680 /*ARGSUSED*/ 1681 static int 1682 tpm_close(dev_t dev, int flag, int otyp, cred_t *cred) 1683 { 1684 char *myname = "tpm_close"; 1685 int instance; 1686 tpm_state_t *tpm; 1687 1688 instance = getminor(dev); 1689 if ((tpm = ddi_get_soft_state(statep, instance)) == NULL) { 1690 cmn_err(CE_WARN, "%s: stored pointer to tpm state is NULL", 1691 myname); 1692 return (ENXIO); 1693 } 1694 if (otyp != OTYP_CHR) { 1695 cmn_err(CE_WARN, "%s: otyp(%d) != OTYP_CHR(%d)", 1696 myname, otyp, OTYP_CHR); 1697 return (EINVAL); 1698 } 1699 TPM_EXCLUSIVE_LOCK(tpm); 1700 1701 ASSERT(tpm->dev_held); 1702 1703 mutex_enter(&tpm->dev_lock); 1704 ASSERT(mutex_owned(&tpm->dev_lock)); 1705 tpm->dev_held = 0; 1706 mutex_exit(&tpm->dev_lock); 1707 1708 return (0); 1709 } 1710 1711 /*ARGSUSED*/ 1712 static int 1713 tpm_read(dev_t dev, struct uio *uiop, cred_t *credp) 1714 { 1715 int ret; 1716 uint32_t size; 1717 char *myname = "tpm_read"; 1718 int instance; 1719 tpm_state_t *tpm; 1720 1721 instance = getminor(dev); 1722 if ((tpm = ddi_get_soft_state(statep, instance)) == NULL) { 1723 cmn_err(CE_WARN, "%s: stored pointer to tpm state is NULL", 1724 myname); 1725 return (ENXIO); 1726 } 1727 if (uiop == NULL) { 1728 cmn_err(CE_WARN, "%s: passed in uiop is NULL", myname); 1729 return (EFAULT); 1730 } 1731 1732 TPM_EXCLUSIVE_LOCK(tpm); 1733 1734 /* Receive the data after requiring the lock */ 1735 ret = tpm_io_lock(tpm); 1736 1737 /* Timeout reached */ 1738 if (ret) 1739 return (ret); 1740 1741 if (uiop->uio_resid > tpm->bufsize) { 1742 cmn_err(CE_WARN, "%s: read_in data is bigger " 1743 "than tpm->bufsize:read in:%d, bufsiz:%d", 1744 myname, (int)uiop->uio_resid, (int)tpm->bufsize); 1745 ret = EIO; 1746 goto OUT; 1747 } 1748 1749 ret = tis_recv_data(tpm, tpm->iobuf, tpm->bufsize); 1750 if (ret < TPM_HEADER_SIZE) { 1751 cmn_err(CE_WARN, "%s: tis_recv_data returned error", myname); 1752 ret = EIO; 1753 goto OUT; 1754 } 1755 1756 size = load32(tpm->iobuf, 2); 1757 if (ret != size) { 1758 cmn_err(CE_WARN, "%s: tis_recv_data:" 1759 "expected size=%d, actually read=%d", 1760 myname, size, ret); 1761 ret = EIO; 1762 goto OUT; 1763 } 1764 1765 /* Send the buffer from the kernel to the userspace */ 1766 ret = uiomove(tpm->iobuf, size, UIO_READ, uiop); 1767 if (ret) { 1768 cmn_err(CE_WARN, "%s: uiomove returned error", myname); 1769 goto OUT; 1770 } 1771 1772 /* Zeroize the buffer... */ 1773 bzero(tpm->iobuf, tpm->bufsize); 1774 ret = DDI_SUCCESS; 1775 OUT: 1776 /* We are done now: wake up the waiting threads */ 1777 tpm_unlock(tpm); 1778 1779 return (ret); 1780 } 1781 1782 /*ARGSUSED*/ 1783 static int 1784 tpm_write(dev_t dev, struct uio *uiop, cred_t *credp) 1785 { 1786 int ret; 1787 size_t len; 1788 uint32_t size; 1789 char *myname = "tpm_write"; 1790 int instance; 1791 tpm_state_t *tpm; 1792 1793 instance = getminor(dev); 1794 if ((tpm = ddi_get_soft_state(statep, instance)) == NULL) { 1795 cmn_err(CE_WARN, "%s: stored pointer to tpm state is NULL", 1796 myname); 1797 return (ENXIO); 1798 } 1799 1800 if (uiop == NULL) { 1801 cmn_err(CE_WARN, "%s: passed in uiop is NULL", myname); 1802 return (EFAULT); 1803 } 1804 1805 TPM_EXCLUSIVE_LOCK(tpm); 1806 1807 len = uiop->uio_resid; 1808 if (len == 0) { 1809 cmn_err(CE_WARN, "%s: requested read of len 0", myname); 1810 return (0); 1811 } 1812 1813 /* Get the lock for using iobuf */ 1814 ret = tpm_io_lock(tpm); 1815 /* Timeout Reached */ 1816 if (ret) 1817 return (ret); 1818 1819 /* Copy the header and parse the structure to find out the size... */ 1820 ret = uiomove(tpm->iobuf, TPM_HEADER_SIZE, UIO_WRITE, uiop); 1821 if (ret) { 1822 cmn_err(CE_WARN, "%s: uiomove returned error" 1823 "while getting the the header", 1824 myname); 1825 goto OUT; 1826 } 1827 1828 /* Get the buffersize from the command buffer structure */ 1829 size = load32(tpm->iobuf, TPM_PARAMSIZE_OFFSET); 1830 1831 /* Copy the command to the contiguous buffer */ 1832 if (size > tpm->bufsize) { 1833 cmn_err(CE_WARN, "%s: size %d is greater than " 1834 "the tpm's input buffer size %d", 1835 myname, (int)size, (int)tpm->bufsize); 1836 ret = ENXIO; 1837 goto OUT; 1838 } 1839 1840 /* Copy the buffer from the userspace to kernel */ 1841 ret = uiomove(tpm->iobuf+TPM_HEADER_SIZE, size-TPM_HEADER_SIZE, 1842 UIO_WRITE, uiop); 1843 1844 if (ret) { 1845 cmn_err(CE_WARN, "%s: uiomove returned error" 1846 "while getting the rest of the command", myname); 1847 goto OUT; 1848 } 1849 1850 /* Send the command */ 1851 ret = tis_send_data(tpm, tpm->iobuf, size); 1852 if (ret != DDI_SUCCESS) { 1853 cmn_err(CE_WARN, "%s: tis_send_data returned error", myname); 1854 ret = EFAULT; 1855 goto OUT; 1856 } 1857 1858 /* Zeroize the buffer... */ 1859 bzero(tpm->iobuf, tpm->bufsize); 1860 ret = DDI_SUCCESS; 1861 OUT: 1862 tpm_unlock(tpm); 1863 return (ret); 1864 } 1865 1866 /* 1867 * This is to deal with the contentions for the iobuf 1868 */ 1869 static inline int 1870 tpm_io_lock(tpm_state_t *tpm) 1871 { 1872 int ret; 1873 clock_t timeout; 1874 1875 mutex_enter(&tpm->iobuf_lock); 1876 ASSERT(mutex_owned(&tpm->iobuf_lock)); 1877 1878 timeout = ddi_get_lbolt() + drv_usectohz(TPM_IO_TIMEOUT); 1879 1880 /* Wait until the iobuf becomes free with the timeout */ 1881 while (tpm->iobuf_inuse) { 1882 ret = cv_timedwait(&tpm->iobuf_cv, &tpm->iobuf_lock, timeout); 1883 if (ret <= 0) { 1884 /* Timeout reached */ 1885 mutex_exit(&tpm->iobuf_lock); 1886 #ifdef DEBUG 1887 cmn_err(CE_WARN, "tpm_io_lock:iorequest timed out"); 1888 #endif 1889 return (ETIME); 1890 } 1891 } 1892 tpm->iobuf_inuse = 1; 1893 mutex_exit(&tpm->iobuf_lock); 1894 return (0); 1895 } 1896 1897 /* 1898 * This is to deal with the contentions for the iobuf 1899 */ 1900 static inline void 1901 tpm_unlock(tpm_state_t *tpm) 1902 { 1903 /* Wake up the waiting threads */ 1904 mutex_enter(&tpm->iobuf_lock); 1905 ASSERT(tpm->iobuf_inuse == 1 && mutex_owned(&tpm->iobuf_lock)); 1906 tpm->iobuf_inuse = 0; 1907 cv_broadcast(&tpm->iobuf_cv); 1908 mutex_exit(&tpm->iobuf_lock); 1909 } 1910 1911 #ifdef KCF_TPM_RNG_PROVIDER 1912 /* 1913 * Random number generator entry points 1914 */ 1915 static void 1916 strncpy_spacepad(uchar_t *s1, char *s2, int n) 1917 { 1918 int s2len = strlen(s2); 1919 (void) strncpy((char *)s1, s2, n); 1920 if (s2len < n) 1921 (void) memset(s1 + s2len, ' ', n - s2len); 1922 } 1923 1924 /*ARGSUSED*/ 1925 static int 1926 tpmrng_ext_info(crypto_provider_handle_t prov, 1927 crypto_provider_ext_info_t *ext_info, 1928 crypto_req_handle_t cfreq) 1929 { 1930 tpm_state_t *tpm = (tpm_state_t *)prov; 1931 char buf[64]; 1932 1933 if (tpm == NULL) 1934 return (DDI_FAILURE); 1935 1936 strncpy_spacepad(ext_info->ei_manufacturerID, 1937 (char *)tpm->vers_info.tpmVendorID, 1938 sizeof (ext_info->ei_manufacturerID)); 1939 1940 strncpy_spacepad(ext_info->ei_model, "0", 1941 sizeof (ext_info->ei_model)); 1942 strncpy_spacepad(ext_info->ei_serial_number, "0", 1943 sizeof (ext_info->ei_serial_number)); 1944 1945 ext_info->ei_flags = CRYPTO_EXTF_RNG | CRYPTO_EXTF_SO_PIN_LOCKED; 1946 ext_info->ei_max_session_count = CRYPTO_EFFECTIVELY_INFINITE; 1947 ext_info->ei_max_pin_len = 0; 1948 ext_info->ei_min_pin_len = 0; 1949 ext_info->ei_total_public_memory = CRYPTO_UNAVAILABLE_INFO; 1950 ext_info->ei_free_public_memory = CRYPTO_UNAVAILABLE_INFO; 1951 ext_info->ei_total_private_memory = CRYPTO_UNAVAILABLE_INFO; 1952 ext_info->ei_free_public_memory = CRYPTO_UNAVAILABLE_INFO; 1953 ext_info->ei_time[0] = 0; 1954 1955 ext_info->ei_hardware_version.cv_major = tpm->vers_info.version.major; 1956 ext_info->ei_hardware_version.cv_minor = tpm->vers_info.version.minor; 1957 ext_info->ei_firmware_version.cv_major = 1958 tpm->vers_info.version.revMajor; 1959 ext_info->ei_firmware_version.cv_minor = 1960 tpm->vers_info.version.revMinor; 1961 1962 (void) snprintf(buf, sizeof (buf), "tpmrng TPM RNG"); 1963 1964 strncpy_spacepad(ext_info->ei_label, buf, 1965 sizeof (ext_info->ei_label)); 1966 #undef BUFSZ 1967 return (CRYPTO_SUCCESS); 1968 1969 } 1970 1971 static int 1972 tpmrng_register(tpm_state_t *tpm) 1973 { 1974 int ret; 1975 char ID[64]; 1976 crypto_mech_name_t *rngmech; 1977 1978 ASSERT(tpm != NULL); 1979 1980 (void) snprintf(ID, sizeof (ID), "tpmrng %s", IDENT_TPMRNG); 1981 1982 tpmrng_prov_info.pi_provider_description = ID; 1983 tpmrng_prov_info.pi_provider_dev.pd_hw = tpm->dip; 1984 tpmrng_prov_info.pi_provider_handle = tpm; 1985 1986 ret = crypto_register_provider(&tpmrng_prov_info, &tpm->n_prov); 1987 if (ret != CRYPTO_SUCCESS) { 1988 tpm->n_prov = NULL; 1989 return (DDI_FAILURE); 1990 } 1991 1992 crypto_provider_notification(tpm->n_prov, CRYPTO_PROVIDER_READY); 1993 1994 rngmech = kmem_zalloc(strlen("random") + 1, KM_SLEEP); 1995 (void) memcpy(rngmech, "random", 6); 1996 ret = crypto_load_dev_disabled("tpm", ddi_get_instance(tpm->dip), 1997 1, rngmech); 1998 if (ret != CRYPTO_SUCCESS) { 1999 cmn_err(CE_WARN, "crypto_load_dev_disabled failed (%d)", ret); 2000 } 2001 return (DDI_SUCCESS); 2002 } 2003 2004 static int 2005 tpmrng_unregister(tpm_state_t *tpm) 2006 { 2007 int ret; 2008 ASSERT(tpm != NULL); 2009 if (tpm->n_prov) { 2010 ret = crypto_unregister_provider(tpm->n_prov); 2011 tpm->n_prov = NULL; 2012 if (ret != CRYPTO_SUCCESS) 2013 return (DDI_FAILURE); 2014 } 2015 return (DDI_SUCCESS); 2016 } 2017 2018 /*ARGSUSED*/ 2019 static void 2020 tpmrng_provider_status(crypto_provider_handle_t provider, uint_t *status) 2021 { 2022 *status = CRYPTO_PROVIDER_READY; 2023 } 2024 2025 /*ARGSUSED*/ 2026 static int 2027 tpmrng_seed_random(crypto_provider_handle_t provider, crypto_session_id_t sid, 2028 uchar_t *buf, size_t len, uint_t entropy_est, uint32_t flags, 2029 crypto_req_handle_t req) 2030 { 2031 int ret; 2032 tpm_state_t *tpm; 2033 uint32_t len32; 2034 /* Max length of seed is 256 bytes, add 14 for header. */ 2035 uint8_t cmdbuf[270] = { 2036 0, 193, /* TPM_TAG_RQU COMMAND */ 2037 0, 0, 0, 0x0A, /* paramsize in bytes */ 2038 0, 0, 0, TPM_ORD_StirRandom, 2039 0, 0, 0, 0 /* number of input bytes (< 256) */ 2040 }; 2041 uint32_t buflen; 2042 2043 if (len == 0 || len > 255 || buf == NULL) 2044 return (CRYPTO_ARGUMENTS_BAD); 2045 2046 tpm = (tpm_state_t *)provider; 2047 if (tpm == NULL) 2048 return (CRYPTO_INVALID_CONTEXT); 2049 2050 /* Acquire lock for exclusive use of TPM */ 2051 TPM_EXCLUSIVE_LOCK(tpm); 2052 2053 ret = tpm_io_lock(tpm); 2054 /* Timeout reached */ 2055 if (ret) 2056 return (CRYPTO_BUSY); 2057 2058 /* TPM only handles 32 bit length, so truncate if too big. */ 2059 len32 = (uint32_t)len; 2060 buflen = len32 + 14; 2061 2062 /* The length must be in network order */ 2063 buflen = htonl(buflen); 2064 bcopy(&buflen, cmdbuf + 2, sizeof (uint32_t)); 2065 2066 /* Convert it back */ 2067 buflen = ntohl(buflen); 2068 2069 /* length must be in network order */ 2070 len32 = htonl(len32); 2071 bcopy(&len32, cmdbuf + 10, sizeof (uint32_t)); 2072 2073 /* convert it back */ 2074 len32 = ntohl(len32); 2075 2076 bcopy(buf, cmdbuf + 14, len32); 2077 2078 ret = itpm_command(tpm, cmdbuf, buflen); 2079 tpm_unlock(tpm); 2080 2081 if (ret != DDI_SUCCESS) { 2082 #ifdef DEBUG 2083 cmn_err(CE_WARN, "tpmrng_seed_random failed"); 2084 #endif 2085 return (CRYPTO_FAILED); 2086 } 2087 2088 return (CRYPTO_SUCCESS); 2089 } 2090 2091 /* ARGSUSED */ 2092 static int 2093 tpmrng_generate_random(crypto_provider_handle_t provider, 2094 crypto_session_id_t sid, uchar_t *buf, size_t len, crypto_req_handle_t req) 2095 { 2096 int ret; 2097 tpm_state_t *tpm; 2098 uint8_t hdr[14] = { 2099 0, 193, /* TPM_TAG_RQU COMMAND */ 2100 0, 0, 0, 14, /* paramsize in bytes */ 2101 0, 0, 0, TPM_ORD_GetRandom, 2102 0, 0, 0, 0 2103 }; 2104 uint8_t *cmdbuf = NULL; 2105 uint32_t len32 = (uint32_t)len; 2106 uint32_t buflen = len32 + sizeof (hdr); 2107 2108 if (len == 0 || buf == NULL) 2109 return (CRYPTO_ARGUMENTS_BAD); 2110 2111 tpm = (tpm_state_t *)provider; 2112 if (tpm == NULL) 2113 return (CRYPTO_INVALID_CONTEXT); 2114 2115 TPM_EXCLUSIVE_LOCK(tpm); 2116 2117 ret = tpm_io_lock(tpm); 2118 /* Timeout reached */ 2119 if (ret) 2120 return (CRYPTO_BUSY); 2121 2122 cmdbuf = kmem_zalloc(buflen, KM_SLEEP); 2123 bcopy(hdr, cmdbuf, sizeof (hdr)); 2124 2125 /* Length is written in network byte order */ 2126 len32 = htonl(len32); 2127 bcopy(&len32, cmdbuf + 10, sizeof (uint32_t)); 2128 2129 ret = itpm_command(tpm, cmdbuf, buflen); 2130 if (ret != DDI_SUCCESS) { 2131 #ifdef DEBUG 2132 cmn_err(CE_WARN, "tpmrng_generate_random failed"); 2133 #endif 2134 kmem_free(cmdbuf, buflen); 2135 tpm_unlock(tpm); 2136 return (CRYPTO_FAILED); 2137 } 2138 2139 /* Find out how many bytes were really returned */ 2140 len32 = load32(cmdbuf, 10); 2141 2142 /* Copy the random bytes back to the callers buffer */ 2143 bcopy(cmdbuf + 14, buf, len32); 2144 2145 kmem_free(cmdbuf, buflen); 2146 tpm_unlock(tpm); 2147 2148 return (CRYPTO_SUCCESS); 2149 } 2150 #endif /* KCF_TPM_RNG_PROVIDER */ 2151