Lines Matching defs:tpm
54 #include <tss/tpm.h> /* from SUNWtss */
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);
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); }
320 tpm_get8(tpm_state_t *tpm, unsigned long offset)
324 ASSERT(tpm != NULL);
325 (void) hcall_tpm_get(tpm->locality, offset, sizeof (uint8_t), &value);
330 tpm_get32(tpm_state_t *tpm, unsigned long offset)
334 ASSERT(tpm != NULL);
335 (void) hcall_tpm_get(tpm->locality, offset, sizeof (uint32_t), &value);
340 tpm_put8(tpm_state_t *tpm, unsigned long offset, uint8_t value)
342 ASSERT(tpm != NULL);
343 (void) hcall_tpm_put(tpm->locality, offset, sizeof (uint8_t), value);
349 tpm_get8(tpm_state_t *tpm, unsigned long offset)
351 ASSERT(tpm != NULL);
353 return (ddi_get8(tpm->handle,
354 (uint8_t *)(TPM_LOCALITY_OFFSET(tpm->locality) |
355 (uintptr_t)tpm->addr + offset)));
359 tpm_get32(tpm_state_t *tpm, unsigned long offset)
361 ASSERT(tpm != NULL);
362 return (ddi_get32(tpm->handle,
363 (uint32_t *)(TPM_LOCALITY_OFFSET(tpm->locality) |
364 (uintptr_t)tpm->addr + offset)));
368 tpm_put8(tpm_state_t *tpm, unsigned long offset, uint8_t value)
370 ASSERT(tpm != NULL);
371 ddi_put8(tpm->handle,
372 (uint8_t *)(TPM_LOCALITY_OFFSET(tpm->locality) |
373 (uintptr_t)tpm->addr + offset), value);
403 tpm_get_timeouts(tpm_state_t *tpm)
420 ASSERT(tpm != NULL);
422 ret = itpm_command(tpm, buf, sizeof (buf));
454 tpm->timeout_a = drv_usectohz(timeout);
463 tpm->timeout_b = drv_usectohz(timeout);
472 tpm->timeout_c = drv_usectohz(timeout);
481 tpm->timeout_d = drv_usectohz(timeout);
492 tpm_get_duration(tpm_state_t *tpm) {
506 ASSERT(tpm != NULL);
508 ret = itpm_command(tpm, buf, sizeof (buf));
539 tpm->duration[TPM_SHORT] = drv_usectohz(duration);
547 tpm->duration[TPM_MEDIUM] = drv_usectohz(duration);
555 tpm->duration[TPM_LONG] = drv_usectohz(duration);
558 tpm->duration[TPM_UNDEFINED] = tpm->duration[TPM_LONG];
569 tpm_get_version(tpm_state_t *tpm) {
583 ASSERT(tpm != NULL);
585 ret = itpm_command(tpm, buf, sizeof (buf));
607 bcopy(buf + TPM_CAP_VERSION_INFO_OFFSET, &tpm->vers_info,
610 bcopy(tpm->vers_info.tpmVendorID, vendorId,
611 sizeof (tpm->vers_info.tpmVendorID));
616 tpm->vers_info.version.major, /* Version */
617 tpm->vers_info.version.minor,
618 tpm->vers_info.version.revMajor, /* Revision */
619 tpm->vers_info.version.revMinor,
620 (int)ntohs(tpm->vers_info.specLevel),
621 tpm->vers_info.errataRev,
627 if (tpm->vers_info.version.major != 1 &&
628 tpm->vers_info.version.minor != 2) {
631 tpm->vers_info.version.major, /* Version */
632 tpm->vers_info.version.minor);
645 tpm_continue_selftest(tpm_state_t *tpm) {
655 ret = itpm_command(tpm, buf, sizeof (buf));
673 tpm_get_ordinal_duration(tpm_state_t *tpm, uint8_t ordinal)
678 ASSERT(tpm != NULL);
711 return (tpm->duration[index]);
720 itpm_command(tpm_state_t *tpm, uint8_t *buf, size_t bufsiz)
726 ASSERT(tpm != NULL && buf != NULL);
740 ret = tis_send_data(tpm, buf, count);
750 * Now receive the data from the tpm
753 ret = tis_recv_data(tpm, buf, bufsiz);
785 tpm_get_burstcount(tpm_state_t *tpm) {
789 ASSERT(tpm != NULL);
795 stop = ddi_get_lbolt() + tpm->timeout_d;
801 burstcnt = tpm_get8(tpm, TPM_STS + 1);
802 burstcnt += tpm_get8(tpm, TPM_STS + 2) << 8;
807 delay(tpm->timeout_poll);
820 tpm_set_ready(tpm_state_t *tpm) {
821 tpm_put8(tpm, TPM_STS, TPM_STS_CMD_READY);
825 receive_data(tpm_state_t *tpm, uint8_t *buf, size_t bufsiz) {
833 ASSERT(tpm != NULL && buf != NULL);
836 (tpm_wait_for_stat(tpm,
838 tpm->timeout_c) == DDI_SUCCESS)) {
844 burstcnt = tpm_get_burstcount(tpm);
846 buf[size++] = tpm_get8(tpm, TPM_DATA_FIFO);
849 stsbits = tis_get_status(tpm);
853 tpm_put8(tpm, TPM_STS, TPM_STS_RESPONSE_RETRY);
865 tis_recv_data(tpm_state_t *tpm, uint8_t *buf, size_t bufsiz) {
872 ASSERT(tpm != NULL && buf != NULL);
885 size = receive_data(tpm, buf, TPM_HEADER_SIZE);
908 size += receive_data(tpm, (uint8_t *)&buf[TPM_HEADER_SIZE],
919 ret = tpm_wait_for_stat(tpm, TPM_STS_VALID, tpm->timeout_c);
921 status = tis_get_status(tpm);
943 tis_release_locality(tpm, tpm->locality, 0);
946 tpm_set_ready(tpm);
947 tis_release_locality(tpm, tpm->locality, 0);
955 tis_send_data(tpm_state_t *tpm, uint8_t *buf, size_t bufsiz) {
963 ASSERT(tpm != NULL && buf != NULL);
973 status = tis_get_status(tpm);
976 tpm_set_ready(tpm);
977 ret = tpm_wait_for_stat(tpm, TPM_STS_CMD_READY, tpm->timeout_b);
996 burstcnt = tpm_get_burstcount(tpm);
1007 tpm_put8(tpm, TPM_DATA_FIFO, buf[count]);
1011 ret = tpm_wait_for_stat(tpm,
1012 (TPM_STS_VALID | TPM_STS_DATA_EXPECT), tpm->timeout_c);
1024 tpm_put8(tpm, TPM_DATA_FIFO, buf[count]);
1028 ret = tpm_wait_for_stat(tpm, TPM_STS_VALID, tpm->timeout_c);
1031 cmn_err(CE_WARN, "!%s: tpm didn't enter STS_VALID state",
1037 status = tis_get_status(tpm);
1052 tpm_put8(tpm, TPM_STS, TPM_STS_GO);
1057 ret = tpm_wait_for_stat(tpm, TPM_STS_DATA_AVAIL | TPM_STS_VALID,
1058 tpm_get_ordinal_duration(tpm, ordinal));
1061 status = tis_get_status(tpm);
1067 tpm_get_ordinal_duration(tpm, ordinal),
1080 tpm_set_ready(tpm);
1081 tis_release_locality(tpm, tpm->locality, 0);
1089 tis_release_locality(tpm_state_t *tpm, char locality, int force) {
1090 ASSERT(tpm != NULL && locality >= 0 && locality < 5);
1093 (tpm_get8(tpm, TPM_ACCESS) &
1100 tpm_put8(tpm, TPM_ACCESS, TPM_ACCESS_ACTIVE_LOCALITY);
1109 tis_check_active_locality(tpm_state_t *tpm, char locality) {
1113 ASSERT(tpm != NULL && locality >= 0 && locality < 5);
1115 old_locality = tpm->locality;
1116 tpm->locality = locality;
1119 access_bits = tpm_get8(tpm, TPM_ACCESS);
1123 tpm->locality = old_locality;
1134 tis_request_locality(tpm_state_t *tpm, char locality) {
1139 ASSERT(tpm != NULL && locality >= 0 && locality < 5);
1141 ret = tis_check_active_locality(tpm, locality);
1145 tpm->locality = locality;
1149 tpm_put8(tpm, TPM_ACCESS, TPM_ACCESS_REQUEST_USE);
1150 timeout = ddi_get_lbolt() + tpm->timeout_a;
1153 while (tis_check_active_locality(tpm, locality)
1159 myname, tpm->timeout_a);
1163 delay(tpm->timeout_poll);
1166 tpm->locality = locality;
1172 tis_get_status(tpm_state_t *tpm) {
1173 return (tpm_get8(tpm, TPM_STS));
1177 tpm_wait_for_stat(tpm_state_t *tpm, uint8_t mask, clock_t timeout) {
1182 while ((tis_get_status(tpm) & mask) != mask) {
1192 delay(tpm->timeout_poll);
1205 tis_init(tpm_state_t *tpm) {
1216 tpm->timeout_a = drv_usectohz(TIS_TIMEOUT_A);
1217 tpm->timeout_b = drv_usectohz(TIS_TIMEOUT_B);
1218 tpm->timeout_c = drv_usectohz(TIS_TIMEOUT_C);
1219 tpm->timeout_d = drv_usectohz(TIS_TIMEOUT_D);
1225 tpm->duration[TPM_SHORT] = drv_usectohz(TPM_DEFAULT_DURATION);
1226 tpm->duration[TPM_MEDIUM] = drv_usectohz(TPM_DEFAULT_DURATION);
1227 tpm->duration[TPM_LONG] = drv_usectohz(TPM_DEFAULT_DURATION);
1228 tpm->duration[TPM_UNDEFINED] = drv_usectohz(TPM_DEFAULT_DURATION);
1231 intf_caps = tpm_get32(tpm, TPM_INTF_CAP);
1257 ret = tis_request_locality(tpm, DEFAULT_LOCALITY);
1262 } /* Now we can refer to the locality as tpm->locality */
1264 tpm->timeout_poll = drv_usectohz(TPM_POLLING_TIMEOUT);
1265 tpm->intr_enabled = 0;
1268 ret = tpm_get_timeouts(tpm);
1274 ret = tpm_get_duration(tpm);
1281 ret = tpm_get_version(tpm);
1291 ret = tpm_continue_selftest(tpm);
1355 tpm_resume(tpm_state_t *tpm)
1357 mutex_enter(&tpm->pm_mutex);
1358 if (!tpm->suspended) {
1359 mutex_exit(&tpm->pm_mutex);
1362 tpm->suspended = 0;
1363 cv_broadcast(&tpm->suspend_cv);
1364 mutex_exit(&tpm->pm_mutex);
1388 tpm_state_t *tpm = NULL;
1400 tpm = ddi_get_soft_state(statep, instance);
1401 if (tpm == NULL) {
1409 tpm->dip = dip;
1420 tpm = ddi_get_soft_state(statep, instance);
1421 if (tpm == NULL) {
1428 return (tpm_resume(tpm));
1438 tpm->flags = 0;
1447 tpm->flags |= TPM_HSVC_REGISTERED;
1449 tpm->accattr.devacc_attr_version = DDI_DEVICE_ATTR_V0;
1450 tpm->accattr.devacc_attr_endian_flags = DDI_NEVERSWAP_ACC;
1451 tpm->accattr.devacc_attr_dataorder = DDI_STRICTORDER_ACC;
1454 ret = ddi_dev_nregs(tpm->dip, &nregs);
1468 if ((ret = ddi_dev_regsize(tpm->dip, idx, ®size)) !=
1480 ret = ddi_regs_map_setup(tpm->dip, idx, (caddr_t *)&tpm->addr,
1482 &tpm->accattr, &tpm->handle);
1487 tpm->flags |= TPM_DIDREGSMAP;
1490 ret = tis_init(tpm);
1498 if (tpm->flags & TPM_DIDREGSMAP) {
1499 ddi_regs_map_free(&tpm->handle);
1500 tpm->handle = NULL;
1501 tpm->flags &= ~TPM_DIDREGSMAP;
1507 mutex_init(&tpm->dev_lock, NULL, MUTEX_DRIVER, NULL);
1508 mutex_init(&tpm->pm_mutex, NULL, MUTEX_DRIVER, NULL);
1509 cv_init(&tpm->suspend_cv, NULL, CV_DRIVER, NULL);
1515 mutex_enter(&tpm->pm_mutex);
1516 tpm->suspended = 0;
1517 mutex_exit(&tpm->pm_mutex);
1519 tpm->flags |= TPM_DID_MUTEX;
1522 tpm->bufsize = TPM_IO_BUF_SIZE;
1523 tpm->iobuf = kmem_zalloc((sizeof (uint8_t))*(tpm->bufsize), KM_SLEEP);
1524 tpm->flags |= TPM_DID_IO_ALLOC;
1526 mutex_init(&tpm->iobuf_lock, NULL, MUTEX_DRIVER, NULL);
1527 tpm->flags |= TPM_DID_IO_MUTEX;
1529 cv_init(&tpm->iobuf_cv, NULL, CV_DRIVER, NULL);
1530 tpm->flags |= TPM_DID_IO_CV;
1533 ret = ddi_create_minor_node(dip, "tpm", S_IFCHR, ddi_get_instance(dip),
1541 tpm->flags |= TPM_DIDMINOR;
1545 if (tpmrng_register(tpm) != DDI_SUCCESS)
1546 cmn_err(CE_WARN, "!%s: tpm RNG failed to register with kcf",
1552 if (tpm != NULL) {
1553 tpm_cleanup(dip, tpm);
1555 tpm = NULL;
1566 tpm_cleanup(dev_info_t *dip, tpm_state_t *tpm)
1568 if (tpm == NULL)
1572 (void) tpmrng_unregister(tpm);
1576 if (tpm->flags & TPM_HSVC_REGISTERED) {
1578 tpm->flags &= ~(TPM_HSVC_REGISTERED);
1581 if (tpm->flags & TPM_DID_MUTEX) {
1582 mutex_destroy(&tpm->dev_lock);
1583 mutex_destroy(&tpm->pm_mutex);
1584 cv_destroy(&tpm->suspend_cv);
1585 tpm->flags &= ~(TPM_DID_MUTEX);
1587 if (tpm->flags & TPM_DID_IO_ALLOC) {
1588 ASSERT(tpm->iobuf != NULL);
1589 kmem_free(tpm->iobuf, (sizeof (uint8_t))*(tpm->bufsize));
1590 tpm->flags &= ~(TPM_DID_IO_ALLOC);
1592 if (tpm->flags & TPM_DID_IO_MUTEX) {
1593 mutex_destroy(&tpm->iobuf_lock);
1594 tpm->flags &= ~(TPM_DID_IO_MUTEX);
1596 if (tpm->flags & TPM_DID_IO_CV) {
1597 cv_destroy(&tpm->iobuf_cv);
1598 tpm->flags &= ~(TPM_DID_IO_CV);
1600 if (tpm->flags & TPM_DIDREGSMAP) {
1602 if (tpm->handle != NULL)
1603 ddi_regs_map_free(&tpm->handle);
1604 tpm->flags &= ~(TPM_DIDREGSMAP);
1606 if (tpm->flags & TPM_DIDMINOR) {
1609 tpm->flags &= ~(TPM_DIDMINOR);
1614 tpm_suspend(tpm_state_t *tpm)
1616 if (tpm == NULL)
1618 mutex_enter(&tpm->pm_mutex);
1619 if (tpm->suspended) {
1620 mutex_exit(&tpm->pm_mutex);
1623 tpm->suspended = 1;
1624 mutex_exit(&tpm->pm_mutex);
1634 tpm_state_t *tpm;
1642 if ((tpm = ddi_get_soft_state(statep, instance)) == NULL) {
1644 cmn_err(CE_WARN, "!%s: stored pointer to tpm state is NULL",
1655 return (tpm_suspend(tpm));
1663 /* Since we are freeing tpm structure, we need to gain the lock */
1664 tpm_cleanup(dip, tpm);
1668 tpm = NULL;
1679 tpm_state_t *tpm;
1682 if ((tpm = ddi_get_soft_state(statep, instance)) == NULL) {
1684 cmn_err(CE_WARN, "!%s: stored pointer to tpm state is NULL",
1692 *resultp = tpm->dip;
1716 tpm_state_t *tpm;
1721 if ((tpm = ddi_get_soft_state(statep, instance)) == NULL) {
1723 cmn_err(CE_WARN, "!%s: stored pointer to tpm state is NULL",
1735 TPM_EXCLUSIVE_LOCK(tpm);
1737 mutex_enter(&tpm->dev_lock);
1738 if (tpm->dev_held) {
1743 mutex_exit(&tpm->dev_lock);
1748 tpm->dev_held = 1;
1749 mutex_exit(&tpm->dev_lock);
1760 tpm_state_t *tpm;
1763 if ((tpm = ddi_get_soft_state(statep, instance)) == NULL) {
1765 cmn_err(CE_WARN, "!%s: stored pointer to tpm state is NULL",
1777 TPM_EXCLUSIVE_LOCK(tpm);
1779 ASSERT(tpm->dev_held);
1781 mutex_enter(&tpm->dev_lock);
1782 ASSERT(mutex_owned(&tpm->dev_lock));
1783 tpm->dev_held = 0;
1784 mutex_exit(&tpm->dev_lock);
1797 tpm_state_t *tpm;
1800 if ((tpm = ddi_get_soft_state(statep, instance)) == NULL) {
1802 cmn_err(CE_WARN, "!%s: stored pointer to tpm state is NULL",
1814 TPM_EXCLUSIVE_LOCK(tpm);
1817 ret = tpm_io_lock(tpm);
1823 if (uiop->uio_resid > tpm->bufsize) {
1826 "than tpm->bufsize:read in:%d, bufsiz:%d",
1827 myname, (int)uiop->uio_resid, (int)tpm->bufsize);
1833 ret = tis_recv_data(tpm, tpm->iobuf, tpm->bufsize);
1842 size = load32(tpm->iobuf, 2);
1854 ret = uiomove(tpm->iobuf, size, UIO_READ, uiop);
1863 bzero(tpm->iobuf, tpm->bufsize);
1867 tpm_unlock(tpm);
1881 tpm_state_t *tpm;
1884 if ((tpm = ddi_get_soft_state(statep, instance)) == NULL) {
1886 cmn_err(CE_WARN, "!%s: stored pointer to tpm state is NULL",
1899 TPM_EXCLUSIVE_LOCK(tpm);
1910 ret = tpm_io_lock(tpm);
1916 ret = uiomove(tpm->iobuf, TPM_HEADER_SIZE, UIO_WRITE, uiop);
1927 size = load32(tpm->iobuf, TPM_PARAMSIZE_OFFSET);
1930 if (size > tpm->bufsize) {
1933 "the tpm input buffer size %d",
1934 myname, (int)size, (int)tpm->bufsize);
1941 ret = uiomove(tpm->iobuf+TPM_HEADER_SIZE, size-TPM_HEADER_SIZE,
1953 ret = tis_send_data(tpm, tpm->iobuf, size);
1963 bzero(tpm->iobuf, tpm->bufsize);
1966 tpm_unlock(tpm);
1974 tpm_io_lock(tpm_state_t *tpm)
1979 mutex_enter(&tpm->iobuf_lock);
1980 ASSERT(mutex_owned(&tpm->iobuf_lock));
1985 while (tpm->iobuf_inuse) {
1986 ret = cv_timedwait(&tpm->iobuf_cv, &tpm->iobuf_lock, timeout);
1989 mutex_exit(&tpm->iobuf_lock);
1996 tpm->iobuf_inuse = 1;
1997 mutex_exit(&tpm->iobuf_lock);
2005 tpm_unlock(tpm_state_t *tpm)
2008 mutex_enter(&tpm->iobuf_lock);
2009 ASSERT(tpm->iobuf_inuse == 1 && mutex_owned(&tpm->iobuf_lock));
2010 tpm->iobuf_inuse = 0;
2011 cv_broadcast(&tpm->iobuf_cv);
2012 mutex_exit(&tpm->iobuf_lock);
2034 tpm_state_t *tpm = (tpm_state_t *)prov;
2037 if (tpm == NULL)
2041 (char *)tpm->vers_info.tpmVendorID,
2059 ext_info->ei_hardware_version.cv_major = tpm->vers_info.version.major;
2060 ext_info->ei_hardware_version.cv_minor = tpm->vers_info.version.minor;
2062 tpm->vers_info.version.revMajor;
2064 tpm->vers_info.version.revMinor;
2076 tpmrng_register(tpm_state_t *tpm)
2082 ASSERT(tpm != NULL);
2087 tpmrng_prov_info.pi_provider_dev.pd_hw = tpm->dip;
2088 tpmrng_prov_info.pi_provider_handle = tpm;
2090 ret = crypto_register_provider(&tpmrng_prov_info, &tpm->n_prov);
2092 tpm->n_prov = NULL;
2096 crypto_provider_notification(tpm->n_prov, CRYPTO_PROVIDER_READY);
2100 ret = crypto_load_dev_disabled("tpm", ddi_get_instance(tpm->dip),
2110 tpmrng_unregister(tpm_state_t *tpm)
2113 ASSERT(tpm != NULL);
2114 if (tpm->n_prov) {
2115 ret = crypto_unregister_provider(tpm->n_prov);
2116 tpm->n_prov = NULL;
2137 tpm_state_t *tpm;
2151 tpm = (tpm_state_t *)provider;
2152 if (tpm == NULL)
2156 TPM_EXCLUSIVE_LOCK(tpm);
2158 ret = tpm_io_lock(tpm);
2183 ret = itpm_command(tpm, cmdbuf, buflen);
2184 tpm_unlock(tpm);
2202 tpm_state_t *tpm;
2216 tpm = (tpm_state_t *)provider;
2217 if (tpm == NULL)
2220 TPM_EXCLUSIVE_LOCK(tpm);
2222 ret = tpm_io_lock(tpm);
2234 ret = itpm_command(tpm, cmdbuf, buflen);
2240 tpm_unlock(tpm);
2251 tpm_unlock(tpm);