VirtualBox

source: vbox/trunk/src/VBox/Devices/Security/DrvTpmHost.cpp@ 90946

Last change on this file since 90946 was 90946, checked in by vboxsync, 4 years ago

Security: Start implementing a driver for passing through a host TPM, bugref:10075

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 8.7 KB
Line 
1/* $Id: DrvTpmHost.cpp 90946 2021-08-27 10:55:25Z vboxsync $ */
2/** @file
3 * TPM host access driver.
4 */
5
6/*
7 * Copyright (C) 2021 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18
19/*********************************************************************************************************************************
20* Header Files *
21*********************************************************************************************************************************/
22#define LOG_GROUP LOG_GROUP_DRV_TCP /** @todo */
23#include <VBox/vmm/pdmdrv.h>
24#include <VBox/vmm/pdmtpmifs.h>
25#include <iprt/assert.h>
26#include <iprt/mem.h>
27#include <iprt/string.h>
28#include <iprt/semaphore.h>
29#include <iprt/uuid.h>
30#include <iprt/tpm.h>
31
32#include <iprt/formats/tpm.h>
33
34#include "VBoxDD.h"
35
36
37/*********************************************************************************************************************************
38* Defined Constants And Macros *
39*********************************************************************************************************************************/
40
41
42/*********************************************************************************************************************************
43* Structures and Typedefs *
44*********************************************************************************************************************************/
45
46/**
47 * TPM Host driver instance data.
48 *
49 * @implements PDMITPMCONNECTOR
50 */
51typedef struct DRVTPMHOST
52{
53 /** The stream interface. */
54 PDMITPMCONNECTOR ITpmConnector;
55 /** Pointer to the driver instance. */
56 PPDMDRVINS pDrvIns;
57
58 /** Handle to the host TPM. */
59 RTTPM hTpm;
60
61} DRVTPMHOST;
62/** Pointer to the TPM emulator instance data. */
63typedef DRVTPMHOST *PDRVTPMHOST;
64
65
66/*********************************************************************************************************************************
67* Internal Functions *
68*********************************************************************************************************************************/
69
70/** @interface_method_impl{PDMITPMCONNECTOR,pfnStartup} */
71static DECLCALLBACK(int) drvTpmHostStartup(PPDMITPMCONNECTOR pInterface, size_t cbCmdResp)
72{
73 RT_NOREF(pInterface, cbCmdResp);
74 return VINF_SUCCESS;
75}
76
77
78/** @interface_method_impl{PDMITPMCONNECTOR,pfnShutdown} */
79static DECLCALLBACK(int) drvTpmHostShutdown(PPDMITPMCONNECTOR pInterface)
80{
81 RT_NOREF(pInterface);
82 return VINF_SUCCESS;
83}
84
85
86/** @interface_method_impl{PDMITPMCONNECTOR,pfnReset} */
87static DECLCALLBACK(int) drvTpmHostReset(PPDMITPMCONNECTOR pInterface)
88{
89 RT_NOREF(pInterface);
90 return VINF_SUCCESS;
91}
92
93
94/** @interface_method_impl{PDMITPMCONNECTOR,pfnGetVersion} */
95static DECLCALLBACK(TPMVERSION) drvTpmHostGetVersion(PPDMITPMCONNECTOR pInterface)
96{
97 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(); /* Shouldnb't get here. */
112 return TPMVERSION_UNKNOWN;
113}
114
115
116/** @interface_method_impl{PDMITPMCONNECTOR,pfnGetEstablishedFlag} */
117static DECLCALLBACK(bool) drvTpmHostGetEstablishedFlag(PPDMITPMCONNECTOR pInterface)
118{
119 RT_NOREF(pInterface);
120 return false;
121}
122
123
124/** @interface_method_impl{PDMITPMCONNECTOR,pfnResetEstablishedFlag} */
125static DECLCALLBACK(int) drvTpmHostResetEstablishedFlag(PPDMITPMCONNECTOR pInterface, uint8_t bLoc)
126{
127 RT_NOREF(pInterface, bLoc);
128 return VINF_SUCCESS;
129}
130
131
132/** @interface_method_impl{PDMITPMCONNECTOR,pfnCmdExec} */
133static DECLCALLBACK(int) drvTpmHostCmdExec(PPDMITPMCONNECTOR pInterface, uint8_t bLoc, const void *pvCmd, size_t cbCmd, void *pvResp, size_t cbResp)
134{
135 RT_NOREF(bLoc);
136 PDRVTPMHOST pThis = RT_FROM_MEMBER(pInterface, DRVTPMHOST, ITpmConnector);
137
138 return RTTpmReqExec(pThis->hTpm, 0 /*bLoc*/, pvCmd, cbCmd, pvResp, cbResp, NULL /*pcbResp*/);
139}
140
141
142/** @interface_method_impl{PDMITPMCONNECTOR,pfnCmdCancel} */
143static DECLCALLBACK(int) drvTpmHostCmdCancel(PPDMITPMCONNECTOR pInterface)
144{
145 PDRVTPMHOST pThis = RT_FROM_MEMBER(pInterface, DRVTPMHOST, ITpmConnector);
146
147 return RTTpmReqCancel(pThis->hTpm);
148}
149
150
151/** @interface_method_impl{PDMIBASE,pfnQueryInterface} */
152static DECLCALLBACK(void *) drvTpmHostQueryInterface(PPDMIBASE pInterface, const char *pszIID)
153{
154 PPDMDRVINS pDrvIns = PDMIBASE_2_PDMDRV(pInterface);
155 PDRVTPMHOST pThis = PDMINS_2_DATA(pDrvIns, PDRVTPMHOST);
156 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASE, &pDrvIns->IBase);
157 PDMIBASE_RETURN_INTERFACE(pszIID, PDMITPMCONNECTOR, &pThis->ITpmConnector);
158 return NULL;
159}
160
161
162/* -=-=-=-=- PDMDRVREG -=-=-=-=- */
163
164/** @copydoc FNPDMDRVDESTRUCT */
165static DECLCALLBACK(void) drvTpmHostDestruct(PPDMDRVINS pDrvIns)
166{
167 PDMDRV_CHECK_VERSIONS_RETURN_VOID(pDrvIns);
168
169 PDRVTPMHOST pThis = PDMINS_2_DATA(pDrvIns, PDRVTPMHOST);
170 LogFlow(("%s\n", __FUNCTION__));
171
172 if (pThis->hTpm != NIL_RTTPM)
173 {
174 int rc = RTTpmClose(pThis->hTpm);
175 AssertRC(rc);
176
177 pThis->hTpm = NIL_RTTPM;
178 }
179}
180
181
182/** @copydoc FNPDMDRVCONSTRUCT */
183static DECLCALLBACK(int) drvTpmHostConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, uint32_t fFlags)
184{
185 RT_NOREF(fFlags);
186 PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns);
187 PDRVTPMHOST pThis = PDMINS_2_DATA(pDrvIns, PDRVTPMHOST);
188
189 /*
190 * Init the static parts.
191 */
192 pThis->pDrvIns = pDrvIns;
193 pThis->hTpm = NIL_RTTPM;
194
195 /* IBase */
196 pDrvIns->IBase.pfnQueryInterface = drvTpmHostQueryInterface;
197 /* ITpmConnector */
198 pThis->ITpmConnector.pfnStartup = drvTpmHostStartup;
199 pThis->ITpmConnector.pfnShutdown = drvTpmHostShutdown;
200 pThis->ITpmConnector.pfnReset = drvTpmHostReset;
201 pThis->ITpmConnector.pfnGetVersion = drvTpmHostGetVersion;
202 pThis->ITpmConnector.pfnGetEstablishedFlag = drvTpmHostGetEstablishedFlag;
203 pThis->ITpmConnector.pfnResetEstablishedFlag = drvTpmHostResetEstablishedFlag;
204 pThis->ITpmConnector.pfnCmdExec = drvTpmHostCmdExec;
205 pThis->ITpmConnector.pfnCmdCancel = drvTpmHostCmdCancel;
206
207 /*
208 * Validate and read the configuration.
209 */
210 PDMDRV_VALIDATE_CONFIG_RETURN(pDrvIns, "TpmId", "");
211
212 uint32_t idTpm = RTTPM_ID_DEFAULT;
213 int rc = CFGMR3QueryU32Def(pCfg, "TpmId", &idTpm, RTTPM_ID_DEFAULT);
214 if (RT_FAILURE(rc))
215 return PDMDrvHlpVMSetError(pDrvIns, rc, RT_SRC_POS,
216 N_("Configuration error: querying \"TpmId\" resulted in %Rrc"), rc);
217
218 rc = RTTpmOpen(&pThis->hTpm, idTpm);
219 if (RT_FAILURE(rc))
220 return PDMDrvHlpVMSetError(pDrvIns, rc, RT_SRC_POS,
221 N_("DrvTpmHost%d: Opening TPM with id %u failed with %Rrc"), idTpm, rc);
222
223 LogRel(("DrvTpmHost#%d: Connected to TPM %u.\n", pDrvIns->iInstance, idTpm));
224 return VINF_SUCCESS;
225}
226
227
228/**
229 * TPM host driver registration record.
230 */
231const PDMDRVREG g_DrvTpmHost =
232{
233 /* u32Version */
234 PDM_DRVREG_VERSION,
235 /* szName */
236 "TpmHost",
237 /* szRCMod */
238 "",
239 /* szR0Mod */
240 "",
241 /* pszDescription */
242 "TPM host driver.",
243 /* fFlags */
244 PDM_DRVREG_FLAGS_HOST_BITS_DEFAULT,
245 /* fClass. */
246 PDM_DRVREG_CLASS_STREAM,
247 /* cMaxInstances */
248 ~0U,
249 /* cbInstance */
250 sizeof(DRVTPMHOST),
251 /* pfnConstruct */
252 drvTpmHostConstruct,
253 /* pfnDestruct */
254 drvTpmHostDestruct,
255 /* pfnRelocate */
256 NULL,
257 /* pfnIOCtl */
258 NULL,
259 /* pfnPowerOn */
260 NULL,
261 /* pfnReset */
262 NULL,
263 /* pfnSuspend */
264 NULL,
265 /* pfnResume */
266 NULL,
267 /* pfnAttach */
268 NULL,
269 /* pfnDetach */
270 NULL,
271 /* pfnPowerOff */
272 NULL,
273 /* pfnSoftReset */
274 NULL,
275 /* u32EndVersion */
276 PDM_DRVREG_VERSION
277};
278
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette