Changeset 90580 in vbox
- Timestamp:
- Aug 9, 2021 3:53:16 PM (3 years ago)
- Location:
- trunk/src/VBox/Devices/Security
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Security/DevTpm.cpp
r90512 r90580 875 875 && uReg < TPM_CRB_LOCALITY_REG_DATA_BUFFER + TPM_CRB_LOCALITY_REG_DATA_BUFFER_SIZE 876 876 && bLoc == pThis->bLoc 877 && pThis->enmState == DEVTPMSTATE_CMD_RECEPTION) 877 && ( pThis->enmState == DEVTPMSTATE_READY 878 || pThis->enmState == DEVTPMSTATE_CMD_RECEPTION)) 878 879 { 880 pThis->enmState = DEVTPMSTATE_CMD_RECEPTION; 879 881 memcpy(&pThis->abCmdResp[uReg - TPM_CRB_LOCALITY_REG_DATA_BUFFER], &u64, cb); 880 882 return VINF_SUCCESS; … … 886 888 { 887 889 /* See chapter 6.5.3.2.2.1. */ 890 #if 0 888 891 if (u64 & TPM_CRB_LOCALITY_REG_CTRL_RST_ESTABLISHMENT) 889 892 /** @todo */; 893 #endif 890 894 891 895 /* … … 1083 1087 /** @todo */ 1084 1088 RT_NOREF(pThis, pThisCC); 1089 pThis->enmState = DEVTPMSTATE_CMD_COMPLETION; 1085 1090 } 1086 1091 -
trunk/src/VBox/Devices/Security/DrvTpmEmu.cpp
r90530 r90580 115 115 116 116 117 /** @name Capabilities as returned by SWTPMCMD_INIT. 118 * @{ */ 119 #define SWTPMCMD_INIT_F_DELETE_VOLATILE RT_BIT_32(0); 120 /** @} */ 121 122 117 123 /** 118 124 * Response data for a SWTPMCMD_GET_CAPABILITY command. … … 151 157 152 158 /** 159 * Additional command data for SWTPMCMD_SET_LOCALITY. 160 */ 161 typedef struct SWTPMCMDSETLOCALITY 162 { 163 /** The locality to set */ 164 uint8_t bLoc; 165 } SWTPMCMDSETLOCALITY; 166 /** Pointer to a command data struct for SWTPMCMD_SET_LOCALITY. */ 167 typedef SWTPMCMDSETLOCALITY *PSWTPMCMDSETLOCALITY; 168 /** Pointer to a const command data struct for SWTPMCMD_SET_LOCALITY. */ 169 typedef const SWTPMCMDSETLOCALITY *PCSWTPMCMDSETLOCALITY; 170 171 172 /** 153 173 * Additional command data for SWTPMCMD_GET_CONFIG. 154 174 */ … … 186 206 /** Size of the chunk returned in this response. */ 187 207 uint32_t cbThis; 188 /** The data returned. */189 uint8_t abData[3 * _1K];190 208 } SWTPMRESPGETCONFIG; 191 209 /** Pointer to a response data struct for SWTPMCMD_GET_CONFIG. */ … … 193 211 /** Pointer to a const response data struct for SWTPMCMD_GET_CONFIG. */ 194 212 typedef const SWTPMRESPGETCONFIG *PCSWTPMRESPGETCONFIG; 195 /** @} */ 213 214 215 /** 216 * Response data for a SWTPMCMD_GET_TPMESTABLISHED command. 217 */ 218 typedef struct SWTPMRESPGETTPMEST 219 { 220 /** Flag whether the TPM established bit is set for the TPM. */ 221 uint8_t fEst; 222 } SWTPMRESPGETTPMEST; 223 /** Pointer to a response data struct for SWTPMCMD_GET_TPMESTABLISHED. */ 224 typedef SWTPMRESPGETTPMEST *PSWTPMRESPGETTPMEST; 225 /** Pointer to a const response data struct for SWTPMCMD_GET_TPMESTABLISHED. */ 226 typedef const SWTPMRESPGETTPMEST *PCSWTPMRESPGETTPMEST; 227 228 229 /** 230 * Additional command data for SWTPMCMD_RESET_TPMESTABLISHED. 231 */ 232 typedef struct SWTPMCMDRSTEST 233 { 234 /** The locality resetting trying to reset the established bit. */ 235 uint8_t bLoc; 236 } SWTPMCMDRSTEST; 237 /** Pointer to a response data struct for SWTPMCMD_GET_TPMESTABLISHED. */ 238 typedef SWTPMCMDRSTEST *PSWTPMCMDRSTEST; 239 /** Pointer to a const response data struct for SWTPMCMD_GET_TPMESTABLISHED. */ 240 typedef const SWTPMCMDRSTEST *PCSWTPMCMDRSTEST; 196 241 197 242 … … 224 269 /** Flag to signal whether the thread was woken up from external. */ 225 270 bool volatile fWokenUp; 271 /** Currently set locality. */ 272 uint8_t bLoc; 226 273 227 274 /** TPM version offered by the emulator. */ 228 275 TPMVERSION enmTpmVers; 276 /** Capabilities offered by the TPM emulator. */ 277 uint32_t fCaps; 229 278 } DRVTPMEMU; 230 279 /** Pointer to the TPM emulator instance data. */ 231 280 typedef DRVTPMEMU *PDRVTPMEMU; 281 282 /** The special no current locality selected value. */ 283 #define TPM_NO_LOCALITY_SELECTED 0xff 232 284 233 285 … … 282 334 *pu32Resp = RT_BE2H_U32(u32Resp); 283 335 if (*pu32Resp == 0) 284 rc = RTSocketRead(pThis->hSockCtrl, pvResp, cbResp, NULL /*pcbRead*/); 336 { 337 if (cbResp) 338 rc = RTSocketRead(pThis->hSockCtrl, pvResp, cbResp, NULL /*pcbRead*/); 339 } 340 else 341 rc = VERR_NET_IO_ERROR; 285 342 } 286 343 } 287 344 } 345 346 return rc; 347 } 348 349 350 /** 351 * Continue receiving a response from a previous call of drvTpmEmuExecCtrlCmdEx() or 352 * drvTpmEmuExecCtrlCmdNoPayload(). 353 * 354 * @param pThis Pointer to the TPM emulator driver instance data. 355 * @param enmCmd The command to execute. 356 * @param pvResp Where to store additional resposne data. 357 * @param cbResp Size of the additional response data in bytes. 358 * @param cMillies Number of milliseconds to wait before aborting the receive with a timeout error. 359 */ 360 static int drvTpmEmuExecCtrlCmdRespCont(PDRVTPMEMU pThis, void *pvResp, size_t cbResp, RTMSINTERVAL cMillies) 361 { 362 int rc = RTSocketSelectOne(pThis->hSockCtrl, cMillies); 363 if (RT_SUCCESS(rc)) 364 rc = RTSocketRead(pThis->hSockCtrl, pvResp, cbResp, NULL /*pcbRead*/); 288 365 289 366 return rc; … … 318 395 319 396 /** 397 * Executes the given command over the control connection to the TPM emulator - variant with no response payload other than the result. 398 * 399 * @returns VBox status code. 400 * @retval VERR_NET_IO_ERROR if the executed command returned an error in the response status field. 401 * @param pThis Pointer to the TPM emulator driver instance data. 402 * @param enmCmd The command to execute. 403 * @param pvCmd Additional command data to send. 404 * @param cbCmd Size of the additional command data in bytes. 405 * @param pu32Resp Where to store the response code from the reply. 406 * @param cMillies Number of milliseconds to wait before aborting the command with a timeout error. 407 */ 408 static int drvTpmEmuExecCtrlCmdNoResp(PDRVTPMEMU pThis, SWTPMCMD enmCmd, const void *pvCmd, size_t cbCmd, uint32_t *pu32Resp, 409 RTMSINTERVAL cMillies) 410 { 411 return drvTpmEmuExecCtrlCmdEx(pThis, enmCmd, pvCmd, cbCmd, pu32Resp, 412 NULL /*pvResp*/, 0 /*cbResp*/, cMillies); 413 } 414 415 416 /** 320 417 * Queries the version of the TPM offered by the remote emulator. 321 418 * … … 327 424 SWTPMCMDGETCONFIG Cmd; 328 425 SWTPMRESPGETCONFIG Resp; 426 uint8_t abData[_4K]; 329 427 uint32_t u32Resp = 0; 330 428 … … 332 430 Cmd.u64Flags = RT_H2BE_U64(SWTPM_GET_CONFIG_F_TPM_SPECIFICATION); 333 431 Cmd.u32Offset = 0; 334 int rc = drvTpmEmuExecCtrlCmdEx(pThis, SWTPMCMD_GET_ CONFIG, &Cmd, sizeof(Cmd), &u32Resp,432 int rc = drvTpmEmuExecCtrlCmdEx(pThis, SWTPMCMD_GET_INFO, &Cmd, sizeof(Cmd), &u32Resp, 335 433 &Resp, sizeof(Resp), RT_MS_10SEC); 336 434 if (RT_SUCCESS(rc)) 337 435 { 436 /* 437 * Currently it is not necessary to get the information in chunks, a single 438 * transaction is enough. To fend off future versions of swtpm requiring this 439 * we return an error here if the total length is not equal to the length of the chunk. 440 */ 338 441 if (RT_BE2H_U32(Resp.cbTotal) == RT_BE2H_U32(Resp.cbThis)) 339 442 { 340 RTJSONVAL hJsonVal = NIL_RTJSONVAL;341 rc = RTJsonParseFromBuf(&hJsonVal, &Resp.abData[0], sizeof(Resp.abData), NULL /*pErrInfo*/);443 /* Fetch the response body. */ 444 rc = drvTpmEmuExecCtrlCmdRespCont(pThis, &abData[0], RT_BE2H_U32(Resp.cbThis), RT_MS_10SEC); 342 445 if (RT_SUCCESS(rc)) 343 446 { 344 /** @todo */ 345 RTJsonValueRelease(hJsonVal); 447 RTJSONVAL hJsonVal = NIL_RTJSONVAL; 448 rc = RTJsonParseFromBuf(&hJsonVal, &abData[0], RT_BE2H_U32(Resp.cbThis), NULL /*pErrInfo*/); 449 if (RT_SUCCESS(rc)) 450 { 451 RTJSONVAL hJsonTpmSpec = NIL_RTJSONVAL; 452 rc = RTJsonValueQueryByName(hJsonVal, "TPMSpecification", &hJsonTpmSpec); 453 if (RT_SUCCESS(rc)) 454 { 455 RTJSONVAL hJsonTpmFam = NIL_RTJSONVAL; 456 rc = RTJsonValueQueryByName(hJsonTpmSpec, "family", &hJsonTpmFam); 457 if (RT_SUCCESS(rc)) 458 { 459 const char *pszFam = NULL; 460 rc = RTJsonValueQueryString(hJsonTpmFam, &pszFam); 461 if (RT_SUCCESS(rc)) 462 { 463 if (!RTStrCmp(pszFam, "1.2")) 464 pThis->enmTpmVers = TPMVERSION_1_2; 465 else if (!RTStrCmp(pszFam, "2.0")) 466 pThis->enmTpmVers = TPMVERSION_2_0; 467 else 468 pThis->enmTpmVers = TPMVERSION_UNKNOWN; 469 } 470 471 RTJsonValueRelease(hJsonTpmFam); 472 } 473 474 RTJsonValueRelease(hJsonTpmSpec); 475 } 476 477 RTJsonValueRelease(hJsonVal); 478 } 346 479 } 347 480 } … … 361 494 * @param pThis Pointer to the TPM emulator driver instance data. 362 495 */ 363 static int drvTpmEmuQuery AndValidateCaps(PDRVTPMEMU pThis)496 static int drvTpmEmuQueryCaps(PDRVTPMEMU pThis) 364 497 { 365 498 SWTPMRESPGETCAPABILITY Resp; 366 499 int rc = drvTpmEmuExecCtrlCmdNoPayload(pThis, SWTPMCMD_GET_CAPABILITY, &Resp, sizeof(Resp), RT_MS_10SEC); 367 500 if (RT_SUCCESS(rc)) 368 { 369 /** @todo */ 370 } 501 pThis->fCaps = RT_BE2H_U32(Resp.u32Caps); 502 503 return rc; 504 } 505 506 507 /** 508 * Sets the given locality for the emulated TPM. 509 * 510 * @returns VBox status code. 511 * @param pThis Pointer to the TPM emulator driver instance data. 512 * @param bLoc The locality to set. 513 */ 514 static int drvTpmEmuSetLocality(PDRVTPMEMU pThis, uint8_t bLoc) 515 { 516 SWTPMCMDSETLOCALITY Cmd; 517 uint32_t u32Resp = 0; 518 519 Cmd.bLoc = bLoc; 520 int rc = drvTpmEmuExecCtrlCmdNoResp(pThis, SWTPMCMD_SET_LOCALITY, &Cmd, sizeof(Cmd), &u32Resp, RT_MS_10SEC); 521 if ( RT_SUCCESS(rc) 522 && u32Resp != 0) 523 rc = VERR_NET_IO_ERROR; 371 524 372 525 return rc; … … 377 530 static DECLCALLBACK(int) drvTpmEmuStartup(PPDMITPMCONNECTOR pInterface, size_t cbCmdResp) 378 531 { 379 RT_NOREF(pInterface, cbCmdResp); 380 return VERR_NOT_IMPLEMENTED; 532 RT_NOREF(cbCmdResp); 533 PDRVTPMEMU pThis = RT_FROM_MEMBER(pInterface, DRVTPMEMU, ITpmConnector); 534 535 SWTPMCMDTPMINIT Cmd; 536 uint32_t u32Resp = 0; 537 538 RT_ZERO(Cmd); 539 Cmd.u32Flags = 0; 540 return drvTpmEmuExecCtrlCmdEx(pThis, SWTPMCMD_INIT, &Cmd, sizeof(Cmd), &u32Resp, 541 NULL, 0, RT_MS_10SEC); 381 542 } 382 543 … … 385 546 static DECLCALLBACK(int) drvTpmEmuShutdown(PPDMITPMCONNECTOR pInterface) 386 547 { 548 PDRVTPMEMU pThis = RT_FROM_MEMBER(pInterface, DRVTPMEMU, ITpmConnector); 549 550 return drvTpmEmuExecCtrlCmdNoPayload(pThis, SWTPMCMD_SHUTDOWN, NULL, 0, RT_MS_10SEC); 551 } 552 553 554 /** @interface_method_impl{PDMITPMCONNECTOR,pfnReset} */ 555 static DECLCALLBACK(int) drvTpmEmuReset(PPDMITPMCONNECTOR pInterface) 556 { 387 557 RT_NOREF(pInterface); 388 558 return VERR_NOT_IMPLEMENTED; … … 390 560 391 561 392 /** @interface_method_impl{PDMITPMCONNECTOR,pfnReset} */393 static DECLCALLBACK(int) drvTpmEmuReset(PPDMITPMCONNECTOR pInterface)394 {395 RT_NOREF(pInterface);396 return VERR_NOT_IMPLEMENTED;397 }398 399 400 562 /** @interface_method_impl{PDMITPMCONNECTOR,pfnGetVersion} */ 401 563 static DECLCALLBACK(TPMVERSION) drvTpmEmuGetVersion(PPDMITPMCONNECTOR pInterface) … … 409 571 static DECLCALLBACK(bool) drvTpmEmuGetEstablishedFlag(PPDMITPMCONNECTOR pInterface) 410 572 { 411 RT_NOREF(pInterface); 573 PDRVTPMEMU pThis = RT_FROM_MEMBER(pInterface, DRVTPMEMU, ITpmConnector); 574 575 SWTPMRESPGETTPMEST Resp; 576 int rc = drvTpmEmuExecCtrlCmdNoPayload(pThis, SWTPMCMD_GET_TPMESTABLISHED, &Resp, sizeof(Resp), RT_MS_10SEC); 577 if (RT_SUCCESS(rc) 578 && Resp.fEst != 0) 579 return true; 580 412 581 return false; 413 582 } … … 417 586 static DECLCALLBACK(int) drvTpmEmuResetEstablishedFlag(PPDMITPMCONNECTOR pInterface, uint8_t bLoc) 418 587 { 419 RT_NOREF(pInterface, bLoc); 420 return VERR_NOT_IMPLEMENTED; 588 PDRVTPMEMU pThis = RT_FROM_MEMBER(pInterface, DRVTPMEMU, ITpmConnector); 589 590 SWTPMCMDRSTEST Cmd; 591 uint32_t u32Resp = 0; 592 593 Cmd.bLoc = bLoc; 594 int rc = drvTpmEmuExecCtrlCmdNoResp(pThis, SWTPMCMD_RESET_TPMESTABLISHED, &Cmd, sizeof(Cmd), &u32Resp, RT_MS_10SEC); 595 if ( RT_SUCCESS(rc) 596 && u32Resp != 0) 597 rc = VERR_NET_IO_ERROR; 598 599 return rc; 421 600 } 422 601 … … 425 604 static DECLCALLBACK(int) drvTpmEmuCmdExec(PPDMITPMCONNECTOR pInterface, uint8_t bLoc, const void *pvCmd, size_t cbCmd, void *pvResp, size_t cbResp) 426 605 { 427 RT_NOREF(pInterface, bLoc, pvCmd, cbCmd, pvResp, cbResp); 428 return VERR_NOT_IMPLEMENTED; 606 PDRVTPMEMU pThis = RT_FROM_MEMBER(pInterface, DRVTPMEMU, ITpmConnector); 607 608 int rc = VINF_SUCCESS; 609 if (pThis->bLoc != bLoc) 610 rc = drvTpmEmuSetLocality(pThis, bLoc); 611 612 if (RT_SUCCESS(rc)) 613 { 614 RT_NOREF(pInterface, bLoc, pvCmd, cbCmd, pvResp, cbResp); 615 } 616 617 return rc; 429 618 } 430 619 … … 526 715 pThis->hSockData = NIL_RTSOCKET; 527 716 pThis->enmTpmVers = TPMVERSION_UNKNOWN; 717 pThis->bLoc = TPM_NO_LOCALITY_SELECTED; 528 718 529 719 pThis->hPollSet = NIL_RTPOLLSET; … … 604 794 pDrvIns->iInstance, szLocation); 605 795 796 rc = drvTpmEmuQueryCaps(pThis); 797 if (RT_FAILURE(rc)) 798 return PDMDrvHlpVMSetError(pDrvIns, rc, RT_SRC_POS, 799 N_("DrvTpmEmu#%d failed to query capabilities offered by %s"), 800 pDrvIns->iInstance, szLocation); 801 802 if (!(pThis->fCaps & SWTPM_CAP_GET_CONFIG)) 803 return PDMDrvHlpVMSetError(pDrvIns, VERR_NOT_SUPPORTED, RT_SRC_POS, 804 N_("DrvTpmEmu#%d Emulated TPM misses the GET_CONFIG capability"), 805 pDrvIns->iInstance, szLocation); 806 606 807 rc = drvTpmEmuQueryTpmVersion(pThis); 607 808 if (RT_FAILURE(rc)) … … 610 811 pDrvIns->iInstance, szLocation); 611 812 612 rc = drvTpmEmuQueryAndValidateCaps(pThis); 613 if (RT_FAILURE(rc)) 614 return PDMDrvHlpVMSetError(pDrvIns, rc, RT_SRC_POS, 615 N_("DrvTpmEmu#%d failed to query and validate all capabilities offeres by %s"), 813 if (pThis->enmTpmVers == TPMVERSION_UNKNOWN) 814 return PDMDrvHlpVMSetError(pDrvIns, VERR_NOT_SUPPORTED, RT_SRC_POS, 815 N_("DrvTpmEmu#%d Emulated TPM version of %s is not supported"), 616 816 pDrvIns->iInstance, szLocation); 617 817 618 LogRel(("DrvTpmEmu#%d: Connected to %s\n", pDrvIns->iInstance, szLocation)); 818 const char *pszTpmVers = NULL; 819 uint32_t fCapsReq = SWTPM_CAP_INIT | SWTPM_CAP_SHUTDOWN | SWTPM_CAP_GET_TPMESTABLISHED 820 | SWTPM_CAP_SET_LOCALITY | SWTPM_CAP_CANCEL_TPM_CMD | SWTPM_CAP_GET_STATEBLOB 821 | SWTPM_CAP_SET_STATEBLOB | SWTPM_CAP_STOP | SWTPM_CAP_SET_BUFFERSIZE; 822 switch (pThis->enmTpmVers) 823 { 824 case TPMVERSION_1_2: 825 /* No additional capabilities needed. */ 826 pszTpmVers = "1.2"; 827 break; 828 case TPMVERSION_2_0: 829 fCapsReq |= SWTPM_CAP_RESET_TPMESTABLISHED; 830 pszTpmVers = "2.0"; 831 break; 832 default: 833 AssertLogRelReturn(("DrvTpmEmu#%d Emulated TPM version %d is not correctly handled", pDrvIns->iInstance, pThis->enmTpmVers), 834 VERR_INVALID_STATE); 835 } 836 837 if ((pThis->fCaps & fCapsReq) != fCapsReq) 838 return PDMDrvHlpVMSetError(pDrvIns, VERR_NOT_SUPPORTED, RT_SRC_POS, 839 N_("DrvTpmEmu#%d Emulated TPM version of %s does not offer required set of capabilities (%#x requested vs. %#x offered)"), 840 pDrvIns->iInstance, szLocation, fCapsReq, pThis->fCaps); 841 842 LogRel(("DrvTpmEmu#%d: Connected to %s, emulating TPM version %s\n", pDrvIns->iInstance, szLocation, pszTpmVers)); 619 843 return VINF_SUCCESS; 620 844 }
Note:
See TracChangeset
for help on using the changeset viewer.