VirtualBox

source: vbox/trunk/src/VBox/Runtime/r3/win/tpm-win.cpp@ 95084

Last change on this file since 95084 was 93115, checked in by vboxsync, 3 years ago

scm --update-copyright-year

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 9.9 KB
Line 
1/* $Id: tpm-win.cpp 93115 2022-01-01 11:31:46Z vboxsync $ */
2/** @file
3 * IPRT - Trusted Platform Module (TPM) access, Windows variant.
4 */
5
6/*
7 * Copyright (C) 2021-2022 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 * The contents of this file may alternatively be used under the terms
18 * of the Common Development and Distribution License Version 1.0
19 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
20 * VirtualBox OSE distribution, in which case the provisions of the
21 * CDDL are applicable instead of those of the GPL.
22 *
23 * You may elect to license modified versions of this file under the
24 * terms and conditions of either the GPL or the CDDL or both.
25 */
26
27
28/*********************************************************************************************************************************
29* Header Files *
30*********************************************************************************************************************************/
31#define LOG_GROUP RTLOGGROUP_DEFAULT
32#include <iprt/tpm.h>
33
34#include <iprt/assertcompile.h>
35#include <iprt/asm.h>
36#include <iprt/err.h>
37#include <iprt/ldr.h>
38#include <iprt/mem.h>
39#include <iprt/once.h>
40
41#include "internal-r3-win.h"
42
43#include <iprt/win/windows.h>
44
45
46/*********************************************************************************************************************************
47* Defined Constants And Macros *
48*********************************************************************************************************************************/
49/* tbs.dll: */
50typedef struct TBS_CONTEXT_PARAMS2
51{
52 UINT32 version;
53 union
54 {
55 struct
56 {
57 UINT32 requestRaw: 1;
58 UINT32 includeTpm12: 1;
59 UINT32 includeTpm20: 1;
60 } Fields;
61
62 UINT32 asUINT32;
63 } u;
64} TBS_CONTEXT_PARAMS2;
65
66typedef struct TBS_DEVICE_INFO
67{
68 UINT32 structVersion;
69 UINT32 tpmVersion;
70 UINT32 tpmInterfaceType;
71 UINT32 tpmImpRevision;
72} TBS_DEVICE_INFO;
73
74#define TPM_VERSION_12 1
75#define TPM_VERSION_20 2
76
77#define TBS_SUCCESS S_OK
78#define TBS_COMMAND_PRIORITY_NORMAL 200
79
80typedef UINT32 TBS_RESULT;
81typedef void *TBS_HCONTEXT;
82typedef TBS_RESULT (WINAPI *PFNTBSI_CONTEXT_CREATE)(const TBS_CONTEXT_PARAMS2 *, TBS_HCONTEXT *);
83typedef TBS_RESULT (WINAPI *PFNTBSI_CONTEXT_CLOSE)(TBS_HCONTEXT);
84typedef TBS_RESULT (WINAPI *PFNTBSI_GET_DEVICE_INFO)(UINT32, TBS_DEVICE_INFO *);
85typedef TBS_RESULT (WINAPI *PFNTBSI_CANCEL_COMMANDS)(TBS_HCONTEXT);
86typedef TBS_RESULT (WINAPI *PFNTBSI_SUBMIT_COMMANDS)(TBS_HCONTEXT, UINT32, UINT32, const BYTE *, UINT32, PBYTE, PUINT32);
87
88
89/*********************************************************************************************************************************
90* Structures and Typedefs *
91*********************************************************************************************************************************/
92
93/**
94 * Internal TPM instance data.
95 */
96typedef struct RTTPMINT
97{
98 /** Handle to the TPM context. */
99 TBS_HCONTEXT hCtx;
100 /** The deduced TPM version. */
101 RTTPMVERSION enmTpmVers;
102} RTTPMINT;
103/** Pointer to the internal TPM instance data. */
104typedef RTTPMINT *PRTTPMINT;
105
106
107/*********************************************************************************************************************************
108* Global Variables *
109*********************************************************************************************************************************/
110/** Init once structure. */
111static RTONCE g_rtTpmWinInitOnce = RTONCE_INITIALIZER;
112/* tbs.dll: */
113static PFNTBSI_CONTEXT_CREATE g_pfnTbsiContextCreate = NULL;
114static PFNTBSI_CONTEXT_CLOSE g_pfnTbsiContextClose = NULL;
115static PFNTBSI_GET_DEVICE_INFO g_pfnTbsiGetDeviceInfo = NULL;
116static PFNTBSI_CANCEL_COMMANDS g_pfnTbsiCancelCommands = NULL;
117static PFNTBSI_SUBMIT_COMMANDS g_pfnTbsiSubmitCommands = NULL;
118
119
120/*********************************************************************************************************************************
121* Internal Functions *
122*********************************************************************************************************************************/
123
124/**
125 * Initialize the globals.
126 *
127 * @returns IPRT status code.
128 * @param pvUser Ignored.
129 */
130static DECLCALLBACK(int32_t) rtTpmWinInitOnce(void *pvUser)
131{
132 RT_NOREF(pvUser);
133 RTLDRMOD hMod;
134
135 int rc = RTLdrLoadSystem("tbs.dll", true /*fNoUnload*/, &hMod);
136 if (RT_SUCCESS(rc))
137 {
138 rc = RTLdrGetSymbol(hMod, "Tbsi_Context_Create", (void **)&g_pfnTbsiContextCreate);
139 if (RT_FAILURE(rc)) return rc;
140
141 rc = RTLdrGetSymbol(hMod, "Tbsip_Context_Close", (void **)&g_pfnTbsiContextClose);
142 if (RT_FAILURE(rc)) return rc;
143
144 rc = RTLdrGetSymbol(hMod, "Tbsip_Cancel_Commands", (void **)&g_pfnTbsiCancelCommands);
145 if (RT_FAILURE(rc)) return rc;
146
147 rc = RTLdrGetSymbol(hMod, "Tbsip_Submit_Command", (void **)&g_pfnTbsiSubmitCommands);
148 if (RT_FAILURE(rc)) return rc;
149
150 rc = RTLdrGetSymbol(hMod, "Tbsi_GetDeviceInfo", (void **)&g_pfnTbsiGetDeviceInfo);
151 if (RT_FAILURE(rc)) { g_pfnTbsiGetDeviceInfo = NULL; Assert(g_enmWinVer < kRTWinOSType_8); }
152
153 RTLdrClose(hMod);
154 }
155
156 return rc;
157}
158
159
160RTDECL(int) RTTpmOpen(PRTTPM phTpm, uint32_t idTpm)
161{
162 AssertPtrReturn(phTpm, VERR_INVALID_POINTER);
163 if (idTpm == RTTPM_ID_DEFAULT)
164 idTpm = 0;
165
166 AssertReturn(idTpm == 0, VERR_NOT_SUPPORTED);
167
168 /*
169 * Initialize the globals.
170 */
171 int rc = RTOnce(&g_rtTpmWinInitOnce, rtTpmWinInitOnce, NULL);
172 AssertRCReturn(rc, rc);
173
174 PRTTPMINT pThis = (PRTTPMINT)RTMemAllocZ(sizeof(*pThis));
175 if (pThis)
176 {
177 TBS_CONTEXT_PARAMS2 CtxParams; RT_ZERO(CtxParams);
178
179 CtxParams.version = TPM_VERSION_12;
180 if (g_pfnTbsiGetDeviceInfo)
181 {
182 /* TPM2 support is available starting with Win8 which has Tbsi_GetDeviceInfo available. */
183 TBS_DEVICE_INFO DevInfo; RT_ZERO(DevInfo);
184
185 DevInfo.structVersion = TPM_VERSION_20;
186 TBS_RESULT rcTbs = g_pfnTbsiGetDeviceInfo(sizeof(DevInfo), &DevInfo);
187 if (rcTbs == TBS_SUCCESS)
188 {
189 CtxParams.version = TPM_VERSION_20;
190 if (DevInfo.tpmVersion == TPM_VERSION_20)
191 {
192 pThis->enmTpmVers = RTTPMVERSION_2_0;
193 CtxParams.u.Fields.includeTpm20 = 1;
194 }
195 else
196 {
197 Assert(DevInfo.tpmVersion == TPM_VERSION_12);
198 pThis->enmTpmVers = RTTPMVERSION_1_2;
199 CtxParams.u.Fields.includeTpm12 = 1;
200 }
201 }
202 else
203 rc = VERR_NOT_FOUND;
204 }
205 else
206 pThis->enmTpmVers = RTTPMVERSION_1_2;
207
208 if (RT_SUCCESS(rc))
209 {
210 TBS_RESULT rcTbs = g_pfnTbsiContextCreate(&CtxParams, &pThis->hCtx);
211 if (rcTbs == TBS_SUCCESS)
212 {
213 *phTpm = pThis;
214 return VINF_SUCCESS;
215 }
216 else
217 rc = VERR_NOT_FOUND;
218 }
219
220 RTMemFree(pThis);
221 }
222 else
223 rc = VERR_NO_MEMORY;
224
225 return rc;
226}
227
228
229RTDECL(int) RTTpmClose(RTTPM hTpm)
230{
231 PRTTPMINT pThis = hTpm;
232
233 AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
234
235 TBS_RESULT rcTbs = g_pfnTbsiContextClose(pThis->hCtx);
236 Assert(rcTbs == TBS_SUCCESS); RT_NOREF(rcTbs);
237
238 RTMemFree(pThis);
239 return VINF_SUCCESS;
240}
241
242
243RTDECL(RTTPMVERSION) RTTpmGetVersion(RTTPM hTpm)
244{
245 PRTTPMINT pThis = hTpm;
246
247 AssertPtrReturn(pThis, RTTPMVERSION_INVALID);
248 return pThis->enmTpmVers;
249}
250
251
252RTDECL(uint32_t) RTTpmGetLocalityMax(RTTPM hTpm)
253{
254 RT_NOREF(hTpm);
255 return 0; /* Only TPM locality 0 is supported. */
256}
257
258
259RTDECL(int) RTTpmReqCancel(RTTPM hTpm)
260{
261 PRTTPMINT pThis = hTpm;
262
263 AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
264
265 TBS_RESULT rcTbs = g_pfnTbsiCancelCommands(pThis->hCtx);
266 if (rcTbs != TBS_SUCCESS)
267 return VERR_DEV_IO_ERROR;
268
269 return VINF_SUCCESS;
270}
271
272
273RTDECL(int) RTTpmReqExec(RTTPM hTpm, uint8_t bLoc, const void *pvReq, size_t cbReq,
274 void *pvResp, size_t cbRespMax, size_t *pcbResp)
275{
276 PRTTPMINT pThis = hTpm;
277
278 AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
279 AssertPtrReturn(pvReq, VERR_INVALID_POINTER);
280 AssertPtrReturn(pvResp, VERR_INVALID_POINTER);
281 AssertReturn(cbReq && cbRespMax, VERR_INVALID_PARAMETER);
282 AssertReturn(cbReq == (UINT32)cbReq && cbRespMax == (UINT32)cbRespMax, VERR_BUFFER_OVERFLOW);
283 AssertReturn(bLoc == 0, VERR_NOT_SUPPORTED); /* TBS doesn't support another locality than 0. */
284
285 UINT32 cbResult = (UINT32)cbRespMax;
286 TBS_RESULT rcTbs = g_pfnTbsiSubmitCommands(pThis->hCtx, 0 /*Locality*/, TBS_COMMAND_PRIORITY_NORMAL,
287 (const BYTE *)pvReq, (UINT32)cbReq, (BYTE *)pvResp, &cbResult);
288 if (rcTbs == TBS_SUCCESS)
289 {
290 if (pcbResp)
291 *pcbResp = cbResult;
292 return VINF_SUCCESS;
293 }
294
295 return VERR_DEV_IO_ERROR;
296}
297
Note: See TracBrowser for help on using the repository browser.

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