Changeset 91005 in vbox for trunk/src/VBox
- Timestamp:
- Aug 30, 2021 4:32:25 PM (3 years ago)
- Location:
- trunk/src/VBox/Devices/Security
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Security/DevTpm.cpp
r90996 r91005 48 48 /** Default revision ID. */ 49 49 #define TPM_RID_DEFAULT 0x01 50 /** Maximum size of the data buffer in bytes. */ 51 #define TPM_DATA_BUFFER_SIZE_MAX 3968 50 52 51 53 /** The TPM MMIO base default as defined in chapter 5.2. */ … … 418 420 /** Locality data buffer. */ 419 421 #define TPM_CRB_LOCALITY_REG_DATA_BUFFER 0x80 420 /** Size of the data buffer. */421 #define TPM_CRB_LOCALITY_REG_DATA_BUFFER_SIZE 3968422 422 /** @} */ 423 423 … … 507 507 TPMVERSION enmTpmVers; 508 508 509 /** Size of the command/response buffer. */ 510 uint32_t cbCmdResp; 509 511 /** Offset into the Command/Response buffer. */ 510 512 uint32_t offCmdResp; 511 513 /** Command/Response buffer. */ 512 uint8_t abCmdResp[TPM_ CRB_LOCALITY_REG_DATA_BUFFER_SIZE];514 uint8_t abCmdResp[TPM_DATA_BUFFER_SIZE_MAX]; 513 515 } DEVTPM; 514 516 /** Pointer to the shared TPM device state. */ … … 683 685 && pThis->enmState == DEVTPMSTATE_CMD_COMPLETION) 684 686 { 685 if (pThis->offCmdResp <= sizeof(pThis->abCmdResp)- cb)687 if (pThis->offCmdResp <= pThis->cbCmdResp - cb) 686 688 { 687 689 memcpy(pu64, &pThis->abCmdResp[pThis->offCmdResp], cb); … … 810 812 { 811 813 pThis->enmState = DEVTPMSTATE_CMD_RECEPTION; 812 if (pThis->offCmdResp <= sizeof(pThis->abCmdResp)- cb)814 if (pThis->offCmdResp <= pThis->cbCmdResp - cb) 813 815 { 814 816 memcpy(&pThis->abCmdResp[pThis->offCmdResp], &u64, cb); … … 935 937 /* Special path for the data buffer. */ 936 938 if ( uReg >= TPM_CRB_LOCALITY_REG_DATA_BUFFER 937 && uReg < TPM_CRB_LOCALITY_REG_DATA_BUFFER + TPM_CRB_LOCALITY_REG_DATA_BUFFER_SIZE939 && uReg < TPM_CRB_LOCALITY_REG_DATA_BUFFER + pThis->cbCmdResp 938 940 && bLoc == pThis->bLoc 939 941 && pThis->enmState == DEVTPMSTATE_CMD_COMPLETION) … … 1026 1028 case TPM_CRB_LOCALITY_REG_CTRL_CMD_SZ: 1027 1029 case TPM_CRB_LOCALITY_REG_CTRL_RSP_SZ: 1028 u64 = TPM_CRB_LOCALITY_REG_DATA_BUFFER_SIZE;1030 u64 = pThis->cbCmdResp; 1029 1031 break; 1030 1032 case TPM_CRB_LOCALITY_REG_CTRL_RSP_ADDR: … … 1064 1066 /* Special path for the data buffer. */ 1065 1067 if ( uReg >= TPM_CRB_LOCALITY_REG_DATA_BUFFER 1066 && uReg < TPM_CRB_LOCALITY_REG_DATA_BUFFER + TPM_CRB_LOCALITY_REG_DATA_BUFFER_SIZE1068 && uReg < TPM_CRB_LOCALITY_REG_DATA_BUFFER + pThis->cbCmdResp 1067 1069 && bLoc == pThis->bLoc 1068 1070 && ( pThis->enmState == DEVTPMSTATE_READY … … 1510 1512 AssertLogRelMsgReturn(pThisCC->pDrvTpm, ("TPM#%d: Driver is missing the TPM interface.\n", iInstance), VERR_PDM_MISSING_INTERFACE); 1511 1513 1514 pThis->fLocChangeSup = pThisCC->pDrvTpm->pfnGetLocalityMax(pThisCC->pDrvTpm) > 0; 1515 pThis->cbCmdResp = RT_MIN(pThisCC->pDrvTpm->pfnGetBufferSize(pThisCC->pDrvTpm), TPM_DATA_BUFFER_SIZE_MAX); 1516 1512 1517 /* Startup the TPM here instead of in the power on callback as we can convey errors here to the upper layer. */ 1513 rc = pThisCC->pDrvTpm->pfnStartup(pThisCC->pDrvTpm , sizeof(pThis->abCmdResp));1518 rc = pThisCC->pDrvTpm->pfnStartup(pThisCC->pDrvTpm); 1514 1519 if (RT_FAILURE(rc)) 1515 1520 return PDMDEV_SET_ERROR(pDevIns, rc, N_("Failed to startup the TPM")); … … 1518 1523 if (pThis->enmTpmVers == TPMVERSION_UNKNOWN) 1519 1524 return PDMDEV_SET_ERROR(pDevIns, VERR_NOT_SUPPORTED, N_("The emulated TPM version is not supported")); 1520 1521 pThis->fLocChangeSup = pThisCC->pDrvTpm->pfnGetLocalityMax(pThisCC->pDrvTpm) > 0;1522 1525 } 1523 1526 else if (rc == VERR_PDM_NO_ATTACHED_DRIVER) -
trunk/src/VBox/Devices/Security/DrvTpmEmu.cpp
r90996 r91005 235 235 { 236 236 /** The locality resetting trying to reset the established bit. */ 237 uint8_t bLoc;237 uint8_t bLoc; 238 238 } SWTPMCMDRSTEST; 239 239 /** Pointer to a response data struct for SWTPMCMD_GET_TPMESTABLISHED. */ … … 241 241 /** Pointer to a const response data struct for SWTPMCMD_GET_TPMESTABLISHED. */ 242 242 typedef const SWTPMCMDRSTEST *PCSWTPMCMDRSTEST; 243 244 245 /** 246 * Additional command data for SWTPMCMD_SET_BUFFERSIZE. 247 */ 248 typedef struct SWTPMCMDSETBUFSZ 249 { 250 /** The buffer size to set, 0 to query for the currently used buffer size. */ 251 uint32_t cbBuffer; 252 } SWTPMCMDSETBUFSZ; 253 /** Pointer to a command data struct for SWTPMCMD_SET_BUFFERSIZE. */ 254 typedef SWTPMCMDSETBUFSZ *PSWTPMCMDSETBUFSZ; 255 /** Pointer to a const command data struct for SWTPMCMD_SET_BUFFERSIZE. */ 256 typedef const SWTPMCMDSETBUFSZ *PCSWTPMCMDSETBUFSZ; 257 258 259 /** 260 * Response data for a SWTPMCMD_SET_BUFFERSIZE command. 261 */ 262 typedef struct SWTPMRESPSETBUFSZ 263 { 264 /** Buffer size in use. */ 265 uint32_t cbBuffer; 266 /** Minimum supported buffer size. */ 267 uint32_t cbBufferMin; 268 /** Maximum supported buffer size. */ 269 uint32_t cbBufferMax; 270 } SWTPMRESPSETBUFSZ; 271 /** Pointer to a response data struct for SWTPMCMD_SET_BUFFERSIZE. */ 272 typedef SWTPMRESPSETBUFSZ *PSWTPMRESPSETBUFSZ; 273 /** Pointer to a const response data struct for SWTPMCMD_SET_BUFFERSIZE. */ 274 typedef const SWTPMRESPSETBUFSZ *PCSWTPMRESPSETBUFSZ; 243 275 244 276 … … 281 313 /** Capabilities offered by the TPM emulator. */ 282 314 uint32_t fCaps; 315 /** Buffer size for the emulated TPM. */ 316 uint32_t cbBuffer; 283 317 } DRVTPMEMU; 284 318 /** Pointer to the TPM emulator instance data. */ … … 537 571 538 572 /** 573 * Queries the maximum supported buffer size by the emulation. 574 * 575 * @returns VBox status code. 576 * @param pThis Pointer to the TPM emulator driver instance data. 577 * @param pcbBufferMax Where to store the maximum supported buffer size on success. 578 */ 579 static int drvTpmEmuQueryBufferSzMax(PDRVTPMEMU pThis, uint32_t *pcbBufferMax) 580 { 581 SWTPMCMDSETBUFSZ Cmd; 582 SWTPMRESPSETBUFSZ Resp; 583 uint32_t u32Resp = 0; 584 585 RT_ZERO(Cmd); RT_ZERO(Resp); 586 Cmd.cbBuffer = RT_H2BE_U32(0); 587 int rc = drvTpmEmuExecCtrlCmdEx(pThis, SWTPMCMD_SET_BUFFERSIZE, &Cmd, sizeof(Cmd), &u32Resp, 588 &Resp, sizeof(Resp), RT_MS_10SEC); 589 if (RT_SUCCESS(rc)) 590 { 591 if (u32Resp == 0) 592 *pcbBufferMax = RT_BE2H_U32(Resp.cbBufferMax); 593 else 594 rc = VERR_NET_IO_ERROR; 595 } 596 597 return rc; 598 } 599 600 601 /** 602 * Queries the maximum supported buffer size by the emulation. 603 * 604 * @returns VBox status code. 605 * @param pThis Pointer to the TPM emulator driver instance data. 606 * @param cbBuffer The buffer size to set. 607 */ 608 static int drvTpmEmuSetBufferSz(PDRVTPMEMU pThis, uint32_t cbBuffer) 609 { 610 SWTPMCMDSETBUFSZ Cmd; 611 SWTPMRESPSETBUFSZ Resp; 612 uint32_t u32Resp = 0; 613 614 RT_ZERO(Cmd); RT_ZERO(Resp); 615 Cmd.cbBuffer = RT_H2BE_U32(cbBuffer); 616 int rc = drvTpmEmuExecCtrlCmdEx(pThis, SWTPMCMD_SET_BUFFERSIZE, &Cmd, sizeof(Cmd), &u32Resp, 617 &Resp, sizeof(Resp), RT_MS_10SEC); 618 if ( RT_SUCCESS(rc) 619 && u32Resp != 0) 620 rc = VERR_NET_IO_ERROR; 621 622 return rc; 623 } 624 625 626 /** 539 627 * Sets the given locality for the emulated TPM. 540 628 * … … 562 650 563 651 /** @interface_method_impl{PDMITPMCONNECTOR,pfnStartup} */ 564 static DECLCALLBACK(int) drvTpmEmuStartup(PPDMITPMCONNECTOR pInterface, size_t cbCmdResp) 565 { 566 RT_NOREF(cbCmdResp); 652 static DECLCALLBACK(int) drvTpmEmuStartup(PPDMITPMCONNECTOR pInterface) 653 { 567 654 PDRVTPMEMU pThis = RT_FROM_MEMBER(pInterface, DRVTPMEMU, ITpmConnector); 568 655 … … 607 694 RT_NOREF(pInterface); 608 695 return 4; 696 } 697 698 699 /** @interface_method_impl{PDMITPMCONNECTOR,pfnGetBufferSize} */ 700 static DECLCALLBACK(uint32_t) drvTpmEmuGetBufferSize(PPDMITPMCONNECTOR pInterface) 701 { 702 PDRVTPMEMU pThis = RT_FROM_MEMBER(pInterface, DRVTPMEMU, ITpmConnector); 703 return pThis->cbBuffer; 609 704 } 610 705 … … 804 899 pThis->ITpmConnector.pfnGetVersion = drvTpmEmuGetVersion; 805 900 pThis->ITpmConnector.pfnGetLocalityMax = drvTpmEmuGetLocalityMax; 901 pThis->ITpmConnector.pfnGetBufferSize = drvTpmEmuGetBufferSize; 806 902 pThis->ITpmConnector.pfnGetEstablishedFlag = drvTpmEmuGetEstablishedFlag; 807 903 pThis->ITpmConnector.pfnResetEstablishedFlag = drvTpmEmuResetEstablishedFlag; … … 812 908 * Validate and read the configuration. 813 909 */ 814 PDMDRV_VALIDATE_CONFIG_RETURN(pDrvIns, "Location ", "");910 PDMDRV_VALIDATE_CONFIG_RETURN(pDrvIns, "Location|BufferSize", ""); 815 911 816 912 char szLocation[_1K]; … … 919 1015 N_("DrvTpmEmu#%d Emulated TPM version of %s does not offer required set of capabilities (%#x requested vs. %#x offered)"), 920 1016 pDrvIns->iInstance, szLocation, fCapsReq, pThis->fCaps); 1017 1018 uint32_t cbBufferMax = 0; 1019 rc = drvTpmEmuQueryBufferSzMax(pThis, &cbBufferMax); 1020 if (RT_FAILURE(rc)) 1021 return PDMDrvHlpVMSetError(pDrvIns, rc, RT_SRC_POS, 1022 N_("DrvTpmEmu#%d failed to query maximum buffer size from %s"), 1023 pDrvIns->iInstance, szLocation); 1024 1025 /* Configure the buffer size. */ 1026 rc = CFGMR3QueryU32Def(pCfg, "BufferSize", &pThis->cbBuffer, cbBufferMax); 1027 if (RT_FAILURE(rc)) 1028 return PDMDrvHlpVMSetError(pDrvIns, rc, RT_SRC_POS, 1029 N_("Configuration error: querying \"BufferSize\" resulted in %Rrc"), rc); 1030 1031 /* Set the buffer size. */ 1032 rc = drvTpmEmuSetBufferSz(pThis, pThis->cbBuffer); 1033 if (RT_FAILURE(rc)) 1034 return PDMDrvHlpVMSetError(pDrvIns, rc, RT_SRC_POS, 1035 N_("DrvTpmEmu#%d failed to set buffer size to %u for %s"), 1036 pDrvIns->iInstance, pThis->cbBuffer, szLocation); 921 1037 922 1038 /* Connect the data channel now. */ -
trunk/src/VBox/Devices/Security/DrvTpmHost.cpp
r90996 r91005 45 45 46 46 /** 47 * TPM 1.2 buffer size capability response. 48 */ 49 #pragma pack(1) 50 typedef struct TPMRESPGETBUFSZ 51 { 52 TPMRESPHDR Hdr; 53 uint32_t u32Length; 54 uint32_t cbBuf; 55 } TPMRESPGETBUFSZ; 56 #pragma pack() 57 typedef TPMRESPGETBUFSZ *PTPMRESPGETBUFSZ; 58 typedef const TPMRESPGETBUFSZ *PCTPMRESPGETBUFSZ; 59 60 61 /** 62 * TPM 2.0 buffer size capability response. 63 */ 64 #pragma pack(1) 65 typedef struct TPM2RESPGETBUFSZ 66 { 67 TPMRESPHDR Hdr; 68 uint8_t fMore; 69 uint32_t u32Cap; 70 uint32_t u32Count; 71 uint32_t u32Prop; 72 uint32_t u32Value; 73 } TPM2RESPGETBUFSZ; 74 #pragma pack() 75 typedef TPM2RESPGETBUFSZ *PTPM2RESPGETBUFSZ; 76 typedef const TPM2RESPGETBUFSZ *PCTPM2RESPGETBUFSZ; 77 78 79 /** 47 80 * TPM Host driver instance data. 48 81 * … … 58 91 /** Handle to the host TPM. */ 59 92 RTTPM hTpm; 60 93 /** Cached TPM version. */ 94 TPMVERSION enmTpmVersion; 95 /** Cached buffer size of the host TPM. */ 96 uint32_t cbBuffer; 61 97 } DRVTPMHOST; 62 98 /** Pointer to the TPM emulator instance data. */ … … 68 104 *********************************************************************************************************************************/ 69 105 106 /** 107 * Queries the buffer size of the host TPM. 108 * 109 * @returns VBox status code. 110 * @param pThis The host TPM driver instance data. 111 */ 112 static int drvTpmHostQueryBufferSize(PDRVTPMHOST pThis) 113 { 114 uint8_t abResp[_1K]; 115 int rc = VINF_SUCCESS; 116 117 switch (pThis->enmTpmVersion) 118 { 119 case TPMVERSION_1_2: 120 { 121 TPMREQGETCAPABILITY Req; 122 123 Req.Hdr.u16Tag = RT_H2BE_U16(TPM_TAG_RQU_COMMAND); 124 Req.Hdr.cbReq = RT_H2BE_U32(sizeof(Req)); 125 Req.Hdr.u32Ordinal = RT_H2BE_U32(TPM_ORD_GETCAPABILITY); 126 Req.u32Cap = RT_H2BE_U32(TPM_CAP_PROPERTY); 127 Req.u32Length = RT_H2BE_U32(sizeof(uint32_t)); 128 Req.u32SubCap = RT_H2BE_U32(TPM_CAP_PROP_INPUT_BUFFER); 129 rc = RTTpmReqExec(pThis->hTpm, 0 /*bLoc*/, &Req, sizeof(Req), &abResp[0], sizeof(abResp), NULL /*pcbResp*/); 130 break; 131 } 132 case TPMVERSION_2_0: 133 { 134 TPM2REQGETCAPABILITY Req; 135 136 Req.Hdr.u16Tag = RT_H2BE_U16(TPM2_ST_NO_SESSIONS); 137 Req.Hdr.cbReq = RT_H2BE_U32(sizeof(Req)); 138 Req.Hdr.u32Ordinal = RT_H2BE_U32(TPM2_CC_GET_CAPABILITY); 139 Req.u32Cap = RT_H2BE_U32(TPM2_CAP_TPM_PROPERTIES); 140 Req.u32Property = RT_H2BE_U32(TPM2_PT_INPUT_BUFFER); 141 Req.u32Count = RT_H2BE_U32(1); 142 rc = RTTpmReqExec(pThis->hTpm, 0 /*bLoc*/, &Req, sizeof(Req), &abResp[0], sizeof(abResp), NULL /*pcbResp*/); 143 break; 144 } 145 default: 146 AssertFailed(); 147 } 148 149 if (RT_SUCCESS(rc)) 150 { 151 switch (pThis->enmTpmVersion) 152 { 153 case TPMVERSION_1_2: 154 { 155 PCTPMRESPGETBUFSZ pResp = (PCTPMRESPGETBUFSZ)&abResp[0]; 156 157 if ( RTTpmRespGetSz(&pResp->Hdr) == sizeof(*pResp) 158 && RT_BE2H_U32(pResp->u32Length) == sizeof(uint32_t)) 159 pThis->cbBuffer = RT_BE2H_U32(pResp->cbBuf); 160 else 161 rc = VERR_INVALID_PARAMETER; 162 break; 163 } 164 case TPMVERSION_2_0: 165 { 166 PCTPM2RESPGETBUFSZ pResp = (PCTPM2RESPGETBUFSZ)&abResp[0]; 167 168 if ( RTTpmRespGetSz(&pResp->Hdr) == sizeof(*pResp) 169 && RT_BE2H_U32(pResp->u32Count) == 1) 170 pThis->cbBuffer = RT_BE2H_U32(pResp->u32Value); 171 else 172 rc = VERR_INVALID_PARAMETER; 173 break; 174 } 175 default: 176 AssertFailed(); 177 } 178 } 179 180 return rc; 181 } 182 183 70 184 /** @interface_method_impl{PDMITPMCONNECTOR,pfnStartup} */ 71 static DECLCALLBACK(int) drvTpmHostStartup(PPDMITPMCONNECTOR pInterface , size_t cbCmdResp)72 { 73 RT_NOREF(pInterface , cbCmdResp);185 static DECLCALLBACK(int) drvTpmHostStartup(PPDMITPMCONNECTOR pInterface) 186 { 187 RT_NOREF(pInterface); 74 188 return VINF_SUCCESS; 75 189 } … … 96 210 { 97 211 PDRVTPMHOST pThis = RT_FROM_MEMBER(pInterface, DRVTPMHOST, ITpmConnector); 98 RTTPMVERSION enmVersion = RTTpmGetVersion(pThis->hTpm); 99 100 switch (enmVersion) 101 { 102 case RTTPMVERSION_1_2: 103 return TPMVERSION_1_2; 104 case RTTPMVERSION_2_0: 105 return TPMVERSION_2_0; 106 case RTTPMVERSION_UNKNOWN: 107 default: 108 return TPMVERSION_UNKNOWN; 109 } 110 111 AssertFailed(); /* Shouldn't get here. */ 112 return TPMVERSION_UNKNOWN; 212 return pThis->enmTpmVersion; 113 213 } 114 214 … … 119 219 PDRVTPMHOST pThis = RT_FROM_MEMBER(pInterface, DRVTPMHOST, ITpmConnector); 120 220 return RTTpmGetLocalityMax(pThis->hTpm); 221 } 222 223 224 /** @interface_method_impl{PDMITPMCONNECTOR,pfnGetBufferSize} */ 225 static DECLCALLBACK(uint32_t) drvTpmHostGetBufferSize(PPDMITPMCONNECTOR pInterface) 226 { 227 PDRVTPMHOST pThis = RT_FROM_MEMBER(pInterface, DRVTPMHOST, ITpmConnector); 228 return pThis->cbBuffer; 121 229 } 122 230 … … 209 317 pThis->ITpmConnector.pfnGetVersion = drvTpmHostGetVersion; 210 318 pThis->ITpmConnector.pfnGetLocalityMax = drvTpmHostGetLocalityMax; 319 pThis->ITpmConnector.pfnGetBufferSize = drvTpmHostGetBufferSize; 211 320 pThis->ITpmConnector.pfnGetEstablishedFlag = drvTpmHostGetEstablishedFlag; 212 321 pThis->ITpmConnector.pfnResetEstablishedFlag = drvTpmHostResetEstablishedFlag; … … 228 337 if (RT_FAILURE(rc)) 229 338 return PDMDrvHlpVMSetError(pDrvIns, rc, RT_SRC_POS, 230 N_("DrvTpmHost%d: Opening TPM with id %u failed with %Rrc"), idTpm, rc); 339 N_("DrvTpmHost%d: Opening TPM with id %u failed with %Rrc"), pDrvIns->iInstance, idTpm, rc); 340 341 RTTPMVERSION enmVersion = RTTpmGetVersion(pThis->hTpm); 342 343 switch (enmVersion) 344 { 345 case RTTPMVERSION_1_2: 346 pThis->enmTpmVersion = TPMVERSION_1_2; 347 break; 348 case RTTPMVERSION_2_0: 349 pThis->enmTpmVersion = TPMVERSION_2_0; 350 break; 351 case RTTPMVERSION_UNKNOWN: 352 default: 353 return PDMDrvHlpVMSetError(pDrvIns, VERR_NOT_SUPPORTED, RT_SRC_POS, 354 N_("DrvTpmHost%d: TPM version %u of TPM id %u is not supported"), 355 pDrvIns->iInstance, enmVersion, idTpm); 356 } 357 358 rc = drvTpmHostQueryBufferSize(pThis); 359 if (RT_FAILURE(rc)) 360 return PDMDrvHlpVMSetError(pDrvIns, rc, RT_SRC_POS, 361 N_("DrvTpmHost%d: Querying input buffer size of TPM with id %u failed with %Rrc"), idTpm, rc); 231 362 232 363 LogRel(("DrvTpmHost#%d: Connected to TPM %u.\n", pDrvIns->iInstance, idTpm));
Note:
See TracChangeset
for help on using the changeset viewer.