]>
Commit | Line | Data |
---|---|---|
39c9604a SB |
1 | /********************************************************************************/ |
2 | /* */ | |
3 | /* LibTPM TPM 1.2 call interface functions */ | |
4 | /* Written by Stefan Berger */ | |
5 | /* IBM Thomas J. Watson Research Center */ | |
6 | /* */ | |
7 | /* (c) Copyright IBM Corporation 2015. */ | |
8 | /* */ | |
9 | /* All rights reserved. */ | |
10 | /* */ | |
11 | /* Redistribution and use in source and binary forms, with or without */ | |
12 | /* modification, are permitted provided that the following conditions are */ | |
13 | /* met: */ | |
14 | /* */ | |
15 | /* Redistributions of source code must retain the above copyright notice, */ | |
16 | /* this list of conditions and the following disclaimer. */ | |
17 | /* */ | |
18 | /* Redistributions in binary form must reproduce the above copyright */ | |
19 | /* notice, this list of conditions and the following disclaimer in the */ | |
20 | /* documentation and/or other materials provided with the distribution. */ | |
21 | /* */ | |
22 | /* Neither the names of the IBM Corporation nor the names of its */ | |
23 | /* contributors may be used to endorse or promote products derived from */ | |
24 | /* this software without specific prior written permission. */ | |
25 | /* */ | |
26 | /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ | |
27 | /* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ | |
28 | /* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR */ | |
29 | /* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */ | |
30 | /* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */ | |
31 | /* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */ | |
32 | /* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, */ | |
33 | /* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY */ | |
34 | /* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */ | |
35 | /* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE */ | |
36 | /* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ | |
37 | /********************************************************************************/ | |
38 | ||
39 | #include <config.h> | |
40 | ||
70547a75 | 41 | #define _GNU_SOURCE |
39c9604a SB |
42 | #include <assert.h> |
43 | #include <stdio.h> | |
44 | #include <stdlib.h> | |
70547a75 | 45 | #include <string.h> |
fe481765 | 46 | #include <stdbool.h> |
39c9604a | 47 | |
e60c35ec | 48 | #include "tpm_debug.h" |
39c9604a SB |
49 | #include "tpm_error.h" |
50 | #include "tpm12/tpm_init.h" | |
51 | #include "tpm_library_intern.h" | |
52 | #include "tpm12/tpm_process.h" | |
53 | #include "tpm12/tpm_startup.h" | |
e11dbf25 SB |
54 | #include "tpm12/tpm_global.h" |
55 | #include "tpm12/tpm_permanent.h" | |
e60c35ec | 56 | #include "tpm_nvfile.h" |
39c9604a | 57 | |
5d7a04c6 | 58 | static TPM_RESULT TPM12_MainInit(void) |
39c9604a SB |
59 | { |
60 | return TPM_MainInit(); | |
61 | } | |
62 | ||
5d7a04c6 | 63 | static void TPM12_Terminate(void) |
39c9604a SB |
64 | { |
65 | TPM_Global_Delete(tpm_instances[0]); | |
66 | free(tpm_instances[0]); | |
67 | tpm_instances[0] = NULL; | |
68 | } | |
69 | ||
5d7a04c6 SB |
70 | static TPM_RESULT TPM12_Process(unsigned char **respbuffer, uint32_t *resp_size, |
71 | uint32_t *respbufsize, | |
72 | unsigned char *command, uint32_t command_size) | |
39c9604a SB |
73 | { |
74 | *resp_size = 0; | |
75 | return TPM_ProcessA(respbuffer, resp_size, respbufsize, | |
76 | command, command_size); | |
77 | } | |
78 | ||
5d7a04c6 SB |
79 | static TPM_RESULT TPM12_VolatileAllStore(unsigned char **buffer, |
80 | uint32_t *buflen) | |
39c9604a SB |
81 | { |
82 | TPM_RESULT rc; | |
83 | TPM_STORE_BUFFER tsb; | |
84 | TPM_Sbuffer_Init(&tsb); | |
85 | uint32_t total; | |
86 | ||
87 | #ifdef TPM_DEBUG | |
88 | assert(tpm_instances[0] != NULL); | |
89 | #endif | |
90 | ||
91 | rc = TPM_VolatileAll_Store(&tsb, tpm_instances[0]); | |
92 | ||
93 | if (rc == TPM_SUCCESS) { | |
94 | /* caller now owns the buffer and needs to free it */ | |
95 | TPM_Sbuffer_GetAll(&tsb, buffer, buflen, &total); | |
96 | } else { | |
97 | TPM_Sbuffer_Delete(&tsb); | |
98 | *buflen = 0; | |
99 | *buffer = NULL; | |
100 | } | |
101 | ||
102 | return rc; | |
103 | } | |
104 | ||
5d7a04c6 | 105 | static TPM_RESULT TPM12_CancelCommand(void) |
3cf528aa SB |
106 | { |
107 | return TPM_FAIL; /* not supported */ | |
108 | } | |
109 | ||
110 | ||
5d7a04c6 | 111 | static TPM_RESULT TPM12_GetTPMProperty(enum TPMLIB_TPMProperty prop, |
39c9604a SB |
112 | int *result) |
113 | { | |
114 | switch (prop) { | |
115 | case TPMPROP_TPM_RSA_KEY_LENGTH_MAX: | |
116 | *result = TPM_RSA_KEY_LENGTH_MAX; | |
117 | break; | |
118 | ||
119 | case TPMPROP_TPM_KEY_HANDLES: | |
120 | *result = TPM_KEY_HANDLES; | |
121 | break; | |
122 | ||
123 | case TPMPROP_TPM_OWNER_EVICT_KEY_HANDLES: | |
124 | *result = TPM_OWNER_EVICT_KEY_HANDLES; | |
125 | break; | |
126 | ||
127 | case TPMPROP_TPM_MIN_AUTH_SESSIONS: | |
128 | *result = TPM_MIN_AUTH_SESSIONS; | |
129 | break; | |
130 | ||
131 | case TPMPROP_TPM_MIN_TRANS_SESSIONS: | |
132 | *result = TPM_MIN_TRANS_SESSIONS; | |
133 | break; | |
134 | ||
135 | case TPMPROP_TPM_MIN_DAA_SESSIONS: | |
136 | *result = TPM_MIN_DAA_SESSIONS; | |
137 | break; | |
138 | ||
139 | case TPMPROP_TPM_MIN_SESSION_LIST: | |
140 | *result = TPM_MIN_SESSION_LIST; | |
141 | break; | |
142 | ||
143 | case TPMPROP_TPM_MIN_COUNTERS: | |
144 | *result = TPM_MIN_COUNTERS; | |
145 | break; | |
146 | ||
147 | case TPMPROP_TPM_NUM_FAMILY_TABLE_ENTRY_MIN: | |
148 | *result = TPM_NUM_FAMILY_TABLE_ENTRY_MIN; | |
149 | break; | |
150 | ||
151 | case TPMPROP_TPM_NUM_DELEGATE_TABLE_ENTRY_MIN: | |
152 | *result = TPM_NUM_DELEGATE_TABLE_ENTRY_MIN; | |
153 | break; | |
154 | ||
155 | case TPMPROP_TPM_SPACE_SAFETY_MARGIN: | |
156 | *result = TPM_SPACE_SAFETY_MARGIN; | |
157 | break; | |
158 | ||
159 | case TPMPROP_TPM_MAX_NV_SPACE: | |
160 | /* fill up 20 kb.; this provides some safety margin (currently | |
161 | >4Kb) for possible future expansion of this blob */ | |
162 | *result = ROUNDUP(TPM_MAX_NV_SPACE, 20 * 1024); | |
163 | break; | |
164 | ||
165 | case TPMPROP_TPM_MAX_SAVESTATE_SPACE: | |
166 | *result = TPM_MAX_SAVESTATE_SPACE; | |
167 | break; | |
168 | ||
169 | case TPMPROP_TPM_MAX_VOLATILESTATE_SPACE: | |
170 | *result = TPM_MAX_VOLATILESTATE_SPACE; | |
171 | break; | |
172 | ||
173 | default: | |
174 | return TPM_FAIL; | |
175 | } | |
176 | ||
177 | return TPM_SUCCESS; | |
178 | } | |
179 | ||
70547a75 SB |
180 | /* |
181 | * TPM12_GetInfo: | |
182 | * | |
183 | * @flags: logical or of flags that query for information | |
184 | * | |
185 | * Return a JSON document with contents queried for by the user's passed flags | |
186 | */ | |
5d7a04c6 | 187 | static char *TPM12_GetInfo(enum TPMLIB_InfoFlags flags) |
70547a75 SB |
188 | { |
189 | const char *tpmspec = | |
190 | "\"TPMSpecification\":{" | |
191 | "\"family\":\"1.2\"," | |
192 | "\"level\":2," | |
193 | "\"revision\":116" | |
194 | "}"; | |
fe481765 SB |
195 | const char *tpmattrs = |
196 | "\"TPMAttributes\":{" | |
197 | "\"manufacturer\":\"id:00001014\"," | |
198 | "\"version\":\"id:00740001\"," /* 146.1 */ | |
199 | "\"model\":\"swtpm\"" | |
200 | "}"; | |
70547a75 | 201 | char *fmt = NULL, *buffer; |
fe481765 | 202 | bool printed = false; |
70547a75 | 203 | |
fe481765 | 204 | if (!(buffer = strdup("{%s%s%s}"))) |
70547a75 SB |
205 | return NULL; |
206 | ||
207 | if ((flags & TPMLIB_INFO_TPMSPECIFICATION)) { | |
208 | fmt = buffer; | |
209 | buffer = NULL; | |
fe481765 SB |
210 | if (asprintf(&buffer, fmt, "", tpmspec, "%s%s%s") < 0) |
211 | goto error; | |
212 | free(fmt); | |
213 | printed = true; | |
214 | } | |
215 | if ((flags & TPMLIB_INFO_TPMATTRIBUTES)) { | |
216 | fmt = buffer; | |
217 | buffer = NULL; | |
218 | if (asprintf(&buffer, fmt, printed ? "," : "", | |
219 | tpmattrs, "%s%s%s") < 0) | |
70547a75 SB |
220 | goto error; |
221 | free(fmt); | |
fe481765 | 222 | printed = true; |
70547a75 SB |
223 | } |
224 | ||
225 | /* nothing else to add */ | |
226 | fmt = buffer; | |
227 | buffer = NULL; | |
fe481765 | 228 | if (asprintf(&buffer, fmt, "", "", "") < 0) |
70547a75 SB |
229 | goto error; |
230 | free(fmt); | |
231 | ||
232 | return buffer; | |
233 | ||
234 | error: | |
235 | free(fmt); | |
236 | free(buffer); | |
237 | ||
238 | return NULL; | |
239 | } | |
240 | ||
ccdf2457 SB |
241 | static uint32_t tpm12_buffersize = TPM_BUFFER_MAX; |
242 | ||
5d7a04c6 SB |
243 | static uint32_t TPM12_SetBufferSize(uint32_t wanted_size, |
244 | uint32_t *min_size, | |
245 | uint32_t *max_size) | |
bc195a34 | 246 | { |
ae3f105a | 247 | if (min_size) |
ccdf2457 | 248 | *min_size = TPM_BUFFER_MIN; |
ae3f105a SB |
249 | if (max_size) |
250 | *max_size = TPM_BUFFER_MAX; | |
ccdf2457 | 251 | |
d77f29d6 SB |
252 | if (wanted_size == 0) |
253 | return tpm12_buffersize; | |
254 | ||
ccdf2457 SB |
255 | if (wanted_size > TPM_BUFFER_MAX) |
256 | wanted_size = TPM_BUFFER_MAX; | |
257 | else if (wanted_size < TPM_BUFFER_MIN) | |
258 | wanted_size = TPM_BUFFER_MIN; | |
259 | ||
260 | tpm12_buffersize = wanted_size; | |
261 | ||
262 | return tpm12_buffersize; | |
263 | } | |
264 | ||
265 | uint32_t TPM12_GetBufferSize(void) | |
266 | { | |
267 | return TPM12_SetBufferSize(0, NULL, NULL); | |
bc195a34 SB |
268 | } |
269 | ||
5d7a04c6 SB |
270 | static TPM_RESULT TPM12_ValidateState(enum TPMLIB_StateType st, |
271 | unsigned int flags) | |
e11dbf25 SB |
272 | { |
273 | TPM_RESULT ret = TPM_SUCCESS; | |
274 | tpm_state_t tpm_state; | |
32387429 SB |
275 | enum TPMLIB_StateType sts[] = { |
276 | TPMLIB_STATE_PERMANENT, | |
277 | TPMLIB_STATE_VOLATILE, | |
278 | TPMLIB_STATE_SAVE_STATE, | |
279 | 0, | |
280 | }; | |
7bbb41a1 | 281 | enum TPMLIB_StateType c_st; |
32387429 | 282 | unsigned i; |
e11dbf25 SB |
283 | |
284 | #ifdef TPM_LIBTPMS_CALLBACKS | |
285 | struct libtpms_callbacks *cbs = TPMLIB_GetCallbacks(); | |
286 | ||
287 | if (cbs->tpm_nvram_init) { | |
288 | ret = cbs->tpm_nvram_init(); | |
289 | if (ret != TPM_SUCCESS) | |
290 | return ret; | |
291 | } | |
292 | #endif | |
293 | ||
294 | ret = TPM_Global_Init(&tpm_state); | |
295 | tpm_state.tpm_number = 0; | |
296 | ||
51f7c2f0 SB |
297 | if (ret == TPM_SUCCESS) { |
298 | /* permanent state needs to be there and loaded first */ | |
299 | ret = TPM_PermanentAll_NVLoad(&tpm_state); | |
300 | } | |
301 | ||
32387429 | 302 | for (i = 0; sts[i] && ret == TPM_SUCCESS; i++) { |
7bbb41a1 SB |
303 | c_st = st & sts[i]; |
304 | ||
305 | /* 'cached' state is known to 'work', so skip it */ | |
51f7c2f0 | 306 | if (!c_st || HasCachedState(c_st)) |
7bbb41a1 SB |
307 | continue; |
308 | ||
309 | switch (c_st) { | |
32387429 | 310 | case TPMLIB_STATE_PERMANENT: |
32387429 SB |
311 | break; |
312 | case TPMLIB_STATE_VOLATILE: | |
313 | ret = TPM_VolatileAll_NVLoad(&tpm_state); | |
314 | break; | |
315 | case TPMLIB_STATE_SAVE_STATE: | |
316 | ret = TPM_SaveState_NVLoad(&tpm_state); | |
317 | break; | |
318 | } | |
e11dbf25 SB |
319 | } |
320 | ||
321 | TPM_Global_Delete(&tpm_state); | |
322 | ||
323 | return ret; | |
324 | } | |
325 | ||
c76f52ef SB |
326 | static TPM_RESULT _TPM_PermanentAll_Store(TPM_STORE_BUFFER *sbuffer, |
327 | tpm_state_t *tpm_state) | |
328 | { | |
329 | const unsigned char *buffer = NULL; | |
330 | uint32_t buflen; | |
331 | ||
332 | return TPM_PermanentAll_Store(sbuffer, &buffer, &buflen, tpm_state); | |
333 | } | |
334 | ||
f031191a SB |
335 | /* |
336 | * TPM_PermanentAll_NVLoad_Preserve | |
337 | * | |
338 | * @tpm_state: The tpm_state to load the permanent state into | |
339 | * | |
340 | * Call TPM_PermanentAll_NVLoad and preserve any cached data that a call | |
341 | * to TPM_PermanentAll_NVLoad (TPM_NVRAM_LoadData) may otherwise consume | |
342 | * and remove if it was available. | |
343 | */ | |
344 | static TPM_RESULT TPM_PermanentAll_NVLoad_Preserve(tpm_state_t *tpm_state) | |
345 | { | |
346 | TPM_RESULT ret; | |
347 | unsigned char *buffer = NULL; | |
348 | uint32_t buffer_len; | |
349 | bool is_empty_buffer; | |
350 | ||
351 | ret = CopyCachedState(TPMLIB_STATE_PERMANENT, | |
352 | &buffer, &buffer_len, &is_empty_buffer); | |
353 | if (ret == TPM_SUCCESS) { | |
354 | ret = TPM_PermanentAll_NVLoad(tpm_state); | |
355 | ||
356 | /* restore a previous empty buffer or any valid buffer */ | |
357 | if (is_empty_buffer || buffer != NULL) | |
358 | SetCachedState(TPMLIB_STATE_PERMANENT, buffer, buffer_len); | |
359 | } | |
360 | ||
361 | return ret; | |
362 | } | |
363 | ||
c76f52ef SB |
364 | /* |
365 | * Get the state blob of the given type. If we TPM is not running, we | |
366 | * get the cached state blobs, if available, otherwise we try to read | |
367 | * it from files. In case the TPM is running, we get it from the running | |
368 | * TPM. | |
369 | */ | |
5d7a04c6 SB |
370 | static TPM_RESULT TPM12_GetState(enum TPMLIB_StateType st, |
371 | unsigned char **buffer, uint32_t *buflen) | |
c76f52ef SB |
372 | { |
373 | TPM_RESULT ret = TPM_FAIL; | |
374 | TPM_STORE_BUFFER tsb; | |
375 | uint32_t total; | |
376 | ||
377 | /* TPM not running ? */ | |
378 | if (tpm_instances[0] == NULL) { | |
379 | struct libtpms_callbacks *cbs = TPMLIB_GetCallbacks(); | |
380 | bool is_empty_buffer; | |
381 | ||
382 | /* try cached blob before file */ | |
383 | ret = CopyCachedState(st, buffer, buflen, &is_empty_buffer); | |
ee69f378 | 384 | if (ret != TPM_SUCCESS || *buffer != NULL || is_empty_buffer) |
c76f52ef SB |
385 | return ret; |
386 | ||
387 | if (cbs->tpm_nvram_init) { | |
388 | ret = cbs->tpm_nvram_init(); | |
389 | if (ret != TPM_SUCCESS) | |
390 | return ret; | |
391 | ||
392 | ret = TPM_NVRAM_LoadData(buffer, buflen, 0, | |
393 | TPMLIB_StateTypeToName(st)); | |
394 | } else { | |
395 | ret = TPM_FAIL; | |
396 | } | |
397 | return ret; | |
398 | } | |
399 | ||
400 | TPM_Sbuffer_Init(&tsb); | |
401 | ||
402 | switch (st) { | |
403 | case TPMLIB_STATE_PERMANENT: | |
404 | ret = _TPM_PermanentAll_Store(&tsb, tpm_instances[0]); | |
405 | break; | |
406 | case TPMLIB_STATE_VOLATILE: | |
407 | ret = TPM_VolatileAll_Store(&tsb, tpm_instances[0]); | |
408 | break; | |
409 | case TPMLIB_STATE_SAVE_STATE: | |
410 | ret = TPM_SaveState_Store(&tsb, tpm_instances[0]); | |
411 | break; | |
412 | } | |
413 | ||
414 | if (ret == TPM_SUCCESS) { | |
415 | /* caller now owns the buffer and needs to free it */ | |
416 | TPM_Sbuffer_GetAll(&tsb, buffer, buflen, &total); | |
417 | } else { | |
418 | TPM_Sbuffer_Delete(&tsb); | |
419 | *buflen = 0; | |
420 | *buffer = NULL; | |
421 | } | |
422 | ||
423 | return ret; | |
424 | } | |
425 | ||
426 | /* | |
427 | * Set the state the TPM 1.2 will use upon next TPM_MainInit(). The TPM 1.2 | |
428 | * must not have been started, yet, or it must have been terminated for this | |
429 | * function to set the state. | |
430 | * | |
431 | * @st: The TPMLIB_StateType describing the type of blob in the buffer | |
432 | * @buffer: pointer to the buffer containing the state blob; NULL pointer clears | |
433 | * previous state | |
434 | * @buflen: length of the buffer | |
435 | */ | |
5d7a04c6 SB |
436 | static TPM_RESULT TPM12_SetState(enum TPMLIB_StateType st, |
437 | const unsigned char *buffer, uint32_t buflen) | |
c76f52ef SB |
438 | { |
439 | TPM_RESULT ret = TPM_SUCCESS; | |
440 | unsigned char *stream = NULL, *orig_stream = NULL; | |
441 | uint32_t stream_size = buflen; | |
442 | tpm_state_t *tpm_state = NULL; | |
443 | ||
444 | if (buffer == NULL) { | |
445 | SetCachedState(st, NULL, 0); | |
446 | return TPM_SUCCESS; | |
447 | } | |
448 | ||
449 | if (tpm_instances[0]) | |
450 | return TPM_INVALID_POSTINIT; | |
451 | ||
452 | if (ret == TPM_SUCCESS) { | |
707a9046 SB |
453 | stream = malloc(buflen); |
454 | if (!stream) { | |
455 | TPMLIB_LogError("Could not allocate %u bytes.\n", buflen); | |
456 | ret = TPM_SIZE; | |
457 | } | |
c76f52ef SB |
458 | } |
459 | ||
460 | if (ret == TPM_SUCCESS) { | |
461 | orig_stream = stream; | |
462 | memcpy(stream, buffer, buflen); | |
463 | ||
707a9046 SB |
464 | tpm_state = malloc(sizeof(tpm_state_t)); |
465 | if (!tpm_state) { | |
466 | TPMLIB_LogError("Could not allocated %zu bytes.\n", | |
467 | sizeof(tpm_state_t)); | |
468 | ret = TPM_SIZE; | |
469 | } | |
c76f52ef SB |
470 | } |
471 | ||
472 | if (ret == TPM_SUCCESS) { | |
473 | ret = TPM_Global_Init(tpm_state); | |
474 | } | |
475 | ||
476 | /* test whether we can accept the blob */ | |
477 | if (ret == TPM_SUCCESS) { | |
f031191a SB |
478 | tpm_state->tpm_number = 0; |
479 | ||
c76f52ef SB |
480 | switch (st) { |
481 | case TPMLIB_STATE_PERMANENT: | |
482 | ret = TPM_PermanentAll_Load(tpm_state, &stream, &stream_size); | |
483 | break; | |
484 | case TPMLIB_STATE_VOLATILE: | |
f031191a SB |
485 | /* permanent state needs to be there and loaded first */ |
486 | ret = TPM_PermanentAll_NVLoad_Preserve(tpm_state); | |
487 | if (ret == TPM_SUCCESS) | |
488 | ret = TPM_VolatileAll_Load(tpm_state, &stream, &stream_size); | |
c76f52ef SB |
489 | break; |
490 | case TPMLIB_STATE_SAVE_STATE: | |
f031191a SB |
491 | ret = TPM_PermanentAll_NVLoad_Preserve(tpm_state); |
492 | if (ret == TPM_SUCCESS) | |
493 | ret = TPM_SaveState_Load(tpm_state, &stream, &stream_size); | |
c76f52ef SB |
494 | break; |
495 | } | |
7071a43b SB |
496 | if (ret) |
497 | ClearAllCachedState(); | |
c76f52ef SB |
498 | } |
499 | ||
500 | /* cache the blob for the TPM_MainInit() to pick it up */ | |
501 | if (ret == TPM_SUCCESS) { | |
502 | SetCachedState(st, orig_stream, buflen); | |
503 | } else { | |
504 | free(orig_stream); | |
505 | } | |
506 | ||
507 | TPM_Global_Delete(tpm_state); | |
508 | free(tpm_state); | |
509 | ||
510 | return ret; | |
511 | } | |
512 | ||
39c9604a SB |
513 | const struct tpm_interface TPM12Interface = { |
514 | .MainInit = TPM12_MainInit, | |
515 | .Terminate = TPM12_Terminate, | |
516 | .Process = TPM12_Process, | |
517 | .VolatileAllStore = TPM12_VolatileAllStore, | |
3cf528aa | 518 | .CancelCommand = TPM12_CancelCommand, |
39c9604a | 519 | .GetTPMProperty = TPM12_GetTPMProperty, |
70547a75 | 520 | .GetInfo = TPM12_GetInfo, |
39c9604a | 521 | .TpmEstablishedGet = TPM12_IO_TpmEstablished_Get, |
3cf528aa | 522 | .TpmEstablishedReset = TPM12_IO_TpmEstablished_Reset, |
39c9604a SB |
523 | .HashStart = TPM12_IO_Hash_Start, |
524 | .HashData = TPM12_IO_Hash_Data, | |
525 | .HashEnd = TPM12_IO_Hash_End, | |
bc195a34 | 526 | .SetBufferSize = TPM12_SetBufferSize, |
e11dbf25 | 527 | .ValidateState = TPM12_ValidateState, |
c76f52ef SB |
528 | .SetState = TPM12_SetState, |
529 | .GetState = TPM12_GetState, | |
39c9604a | 530 | }; |