/src/libtpms/src/tpm_tpm12_interface.c
Line | Count | Source (jump to first uncovered line) |
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 | | |
41 | | #define _GNU_SOURCE |
42 | | #include <assert.h> |
43 | | #include <stdio.h> |
44 | | #include <stdlib.h> |
45 | | #include <string.h> |
46 | | #include <stdbool.h> |
47 | | |
48 | | #include "tpm_debug.h" |
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" |
54 | | #include "tpm12/tpm_global.h" |
55 | | #include "tpm12/tpm_permanent.h" |
56 | | #include "tpm_nvfile.h" |
57 | | |
58 | | static TPM_RESULT TPM12_MainInit(void) |
59 | 0 | { |
60 | 0 | return TPM_MainInit(); |
61 | 0 | } |
62 | | |
63 | | static void TPM12_Terminate(void) |
64 | 0 | { |
65 | 0 | TPM_Global_Delete(tpm_instances[0]); |
66 | 0 | free(tpm_instances[0]); |
67 | 0 | tpm_instances[0] = NULL; |
68 | 0 | } |
69 | | |
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) |
73 | 0 | { |
74 | 0 | *resp_size = 0; |
75 | 0 | return TPM_ProcessA(respbuffer, resp_size, respbufsize, |
76 | 0 | command, command_size); |
77 | 0 | } |
78 | | |
79 | | static TPM_RESULT TPM12_VolatileAllStore(unsigned char **buffer, |
80 | | uint32_t *buflen) |
81 | 0 | { |
82 | 0 | TPM_RESULT rc; |
83 | 0 | TPM_STORE_BUFFER tsb; |
84 | 0 | TPM_Sbuffer_Init(&tsb); |
85 | 0 | uint32_t total; |
86 | |
|
87 | | #ifdef TPM_DEBUG |
88 | | assert(tpm_instances[0] != NULL); |
89 | | #endif |
90 | |
|
91 | 0 | rc = TPM_VolatileAll_Store(&tsb, tpm_instances[0]); |
92 | |
|
93 | 0 | if (rc == TPM_SUCCESS) { |
94 | | /* caller now owns the buffer and needs to free it */ |
95 | 0 | TPM_Sbuffer_GetAll(&tsb, buffer, buflen, &total); |
96 | 0 | } else { |
97 | 0 | TPM_Sbuffer_Delete(&tsb); |
98 | 0 | *buflen = 0; |
99 | 0 | *buffer = NULL; |
100 | 0 | } |
101 | |
|
102 | 0 | return rc; |
103 | 0 | } |
104 | | |
105 | | static TPM_RESULT TPM12_CancelCommand(void) |
106 | 0 | { |
107 | 0 | return TPM_FAIL; /* not supported */ |
108 | 0 | } |
109 | | |
110 | | |
111 | | static TPM_RESULT TPM12_GetTPMProperty(enum TPMLIB_TPMProperty prop, |
112 | | int *result) |
113 | 0 | { |
114 | 0 | switch (prop) { |
115 | 0 | case TPMPROP_TPM_RSA_KEY_LENGTH_MAX: |
116 | 0 | *result = TPM_RSA_KEY_LENGTH_MAX; |
117 | 0 | break; |
118 | | |
119 | 0 | case TPMPROP_TPM_KEY_HANDLES: |
120 | 0 | *result = TPM_KEY_HANDLES; |
121 | 0 | break; |
122 | | |
123 | 0 | case TPMPROP_TPM_OWNER_EVICT_KEY_HANDLES: |
124 | 0 | *result = TPM_OWNER_EVICT_KEY_HANDLES; |
125 | 0 | break; |
126 | | |
127 | 0 | case TPMPROP_TPM_MIN_AUTH_SESSIONS: |
128 | 0 | *result = TPM_MIN_AUTH_SESSIONS; |
129 | 0 | break; |
130 | | |
131 | 0 | case TPMPROP_TPM_MIN_TRANS_SESSIONS: |
132 | 0 | *result = TPM_MIN_TRANS_SESSIONS; |
133 | 0 | break; |
134 | | |
135 | 0 | case TPMPROP_TPM_MIN_DAA_SESSIONS: |
136 | 0 | *result = TPM_MIN_DAA_SESSIONS; |
137 | 0 | break; |
138 | | |
139 | 0 | case TPMPROP_TPM_MIN_SESSION_LIST: |
140 | 0 | *result = TPM_MIN_SESSION_LIST; |
141 | 0 | break; |
142 | | |
143 | 0 | case TPMPROP_TPM_MIN_COUNTERS: |
144 | 0 | *result = TPM_MIN_COUNTERS; |
145 | 0 | break; |
146 | | |
147 | 0 | case TPMPROP_TPM_NUM_FAMILY_TABLE_ENTRY_MIN: |
148 | 0 | *result = TPM_NUM_FAMILY_TABLE_ENTRY_MIN; |
149 | 0 | break; |
150 | | |
151 | 0 | case TPMPROP_TPM_NUM_DELEGATE_TABLE_ENTRY_MIN: |
152 | 0 | *result = TPM_NUM_DELEGATE_TABLE_ENTRY_MIN; |
153 | 0 | break; |
154 | | |
155 | 0 | case TPMPROP_TPM_SPACE_SAFETY_MARGIN: |
156 | 0 | *result = TPM_SPACE_SAFETY_MARGIN; |
157 | 0 | break; |
158 | | |
159 | 0 | 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 | 0 | *result = ROUNDUP(TPM_MAX_NV_SPACE, 20 * 1024); |
163 | 0 | break; |
164 | | |
165 | 0 | case TPMPROP_TPM_MAX_SAVESTATE_SPACE: |
166 | 0 | *result = TPM_MAX_SAVESTATE_SPACE; |
167 | 0 | break; |
168 | | |
169 | 0 | case TPMPROP_TPM_MAX_VOLATILESTATE_SPACE: |
170 | 0 | *result = TPM_MAX_VOLATILESTATE_SPACE; |
171 | 0 | break; |
172 | | |
173 | 0 | default: |
174 | 0 | return TPM_FAIL; |
175 | 0 | } |
176 | | |
177 | 0 | return TPM_SUCCESS; |
178 | 0 | } |
179 | | |
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 | | */ |
187 | | static char *TPM12_GetInfo(enum TPMLIB_InfoFlags flags) |
188 | 0 | { |
189 | 0 | const char *tpmspec = |
190 | 0 | "\"TPMSpecification\":{" |
191 | 0 | "\"family\":\"1.2\"," |
192 | 0 | "\"level\":2," |
193 | 0 | "\"revision\":116" |
194 | 0 | "}"; |
195 | 0 | const char *tpmattrs = |
196 | 0 | "\"TPMAttributes\":{" |
197 | 0 | "\"manufacturer\":\"id:00001014\"," |
198 | 0 | "\"version\":\"id:00740001\"," /* 146.1 */ |
199 | 0 | "\"model\":\"swtpm\"" |
200 | 0 | "}"; |
201 | 0 | char *fmt = NULL, *buffer; |
202 | 0 | bool printed = false; |
203 | |
|
204 | 0 | if (!(buffer = strdup("{%s%s%s}"))) |
205 | 0 | return NULL; |
206 | | |
207 | 0 | if ((flags & TPMLIB_INFO_TPMSPECIFICATION)) { |
208 | 0 | fmt = buffer; |
209 | 0 | buffer = NULL; |
210 | 0 | if (asprintf(&buffer, fmt, "", tpmspec, "%s%s%s") < 0) |
211 | 0 | goto error; |
212 | 0 | free(fmt); |
213 | 0 | printed = true; |
214 | 0 | } |
215 | 0 | if ((flags & TPMLIB_INFO_TPMATTRIBUTES)) { |
216 | 0 | fmt = buffer; |
217 | 0 | buffer = NULL; |
218 | 0 | if (asprintf(&buffer, fmt, printed ? "," : "", |
219 | 0 | tpmattrs, "%s%s%s") < 0) |
220 | 0 | goto error; |
221 | 0 | free(fmt); |
222 | 0 | printed = true; |
223 | 0 | } |
224 | | |
225 | | /* nothing else to add */ |
226 | 0 | fmt = buffer; |
227 | 0 | buffer = NULL; |
228 | 0 | if (asprintf(&buffer, fmt, "", "", "") < 0) |
229 | 0 | goto error; |
230 | 0 | free(fmt); |
231 | |
|
232 | 0 | return buffer; |
233 | | |
234 | 0 | error: |
235 | 0 | free(fmt); |
236 | 0 | free(buffer); |
237 | |
|
238 | 0 | return NULL; |
239 | 0 | } |
240 | | |
241 | | static uint32_t tpm12_buffersize = TPM_BUFFER_MAX; |
242 | | |
243 | | static uint32_t TPM12_SetBufferSize(uint32_t wanted_size, |
244 | | uint32_t *min_size, |
245 | | uint32_t *max_size) |
246 | 0 | { |
247 | 0 | if (min_size) |
248 | 0 | *min_size = TPM_BUFFER_MIN; |
249 | 0 | if (max_size) |
250 | 0 | *max_size = TPM_BUFFER_MAX; |
251 | |
|
252 | 0 | if (wanted_size == 0) |
253 | 0 | return tpm12_buffersize; |
254 | | |
255 | 0 | if (wanted_size > TPM_BUFFER_MAX) |
256 | 0 | wanted_size = TPM_BUFFER_MAX; |
257 | 0 | else if (wanted_size < TPM_BUFFER_MIN) |
258 | 0 | wanted_size = TPM_BUFFER_MIN; |
259 | |
|
260 | 0 | tpm12_buffersize = wanted_size; |
261 | |
|
262 | 0 | return tpm12_buffersize; |
263 | 0 | } |
264 | | |
265 | | uint32_t TPM12_GetBufferSize(void) |
266 | 0 | { |
267 | 0 | return TPM12_SetBufferSize(0, NULL, NULL); |
268 | 0 | } |
269 | | |
270 | | static TPM_RESULT TPM12_ValidateState(enum TPMLIB_StateType st, |
271 | | unsigned int flags LIBTPMS_ATTR_UNUSED) |
272 | 0 | { |
273 | 0 | TPM_RESULT ret = TPM_SUCCESS; |
274 | 0 | tpm_state_t tpm_state; |
275 | 0 | enum TPMLIB_StateType sts[] = { |
276 | 0 | TPMLIB_STATE_PERMANENT, |
277 | 0 | TPMLIB_STATE_VOLATILE, |
278 | 0 | TPMLIB_STATE_SAVE_STATE, |
279 | 0 | 0, |
280 | 0 | }; |
281 | 0 | enum TPMLIB_StateType c_st; |
282 | 0 | unsigned i; |
283 | |
|
284 | 0 | #ifdef TPM_LIBTPMS_CALLBACKS |
285 | 0 | struct libtpms_callbacks *cbs = TPMLIB_GetCallbacks(); |
286 | |
|
287 | 0 | if (cbs->tpm_nvram_init) { |
288 | 0 | ret = cbs->tpm_nvram_init(); |
289 | 0 | if (ret != TPM_SUCCESS) |
290 | 0 | return ret; |
291 | 0 | } |
292 | 0 | #endif |
293 | | |
294 | 0 | ret = TPM_Global_Init(&tpm_state); |
295 | 0 | tpm_state.tpm_number = 0; |
296 | |
|
297 | 0 | if (ret == TPM_SUCCESS) { |
298 | | /* permanent state needs to be there and loaded first */ |
299 | 0 | ret = TPM_PermanentAll_NVLoad(&tpm_state); |
300 | 0 | } |
301 | |
|
302 | 0 | for (i = 0; sts[i] && ret == TPM_SUCCESS; i++) { |
303 | 0 | c_st = st & sts[i]; |
304 | | |
305 | | /* 'cached' state is known to 'work', so skip it */ |
306 | 0 | if (!c_st || HasCachedState(c_st)) |
307 | 0 | continue; |
308 | | |
309 | 0 | switch (c_st) { |
310 | 0 | case TPMLIB_STATE_PERMANENT: |
311 | 0 | break; |
312 | 0 | case TPMLIB_STATE_VOLATILE: |
313 | 0 | ret = TPM_VolatileAll_NVLoad(&tpm_state); |
314 | 0 | break; |
315 | 0 | case TPMLIB_STATE_SAVE_STATE: |
316 | 0 | ret = TPM_SaveState_NVLoad(&tpm_state); |
317 | 0 | break; |
318 | 0 | } |
319 | 0 | } |
320 | | |
321 | 0 | TPM_Global_Delete(&tpm_state); |
322 | |
|
323 | 0 | return ret; |
324 | 0 | } |
325 | | |
326 | | static TPM_RESULT _TPM_PermanentAll_Store(TPM_STORE_BUFFER *sbuffer, |
327 | | tpm_state_t *tpm_state) |
328 | 0 | { |
329 | 0 | const unsigned char *buffer = NULL; |
330 | 0 | uint32_t buflen; |
331 | |
|
332 | 0 | return TPM_PermanentAll_Store(sbuffer, &buffer, &buflen, tpm_state); |
333 | 0 | } |
334 | | |
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 | 0 | { |
346 | 0 | TPM_RESULT ret; |
347 | 0 | unsigned char *buffer = NULL; |
348 | 0 | uint32_t buffer_len; |
349 | 0 | bool is_empty_buffer; |
350 | |
|
351 | 0 | ret = CopyCachedState(TPMLIB_STATE_PERMANENT, |
352 | 0 | &buffer, &buffer_len, &is_empty_buffer); |
353 | 0 | if (ret == TPM_SUCCESS) { |
354 | 0 | ret = TPM_PermanentAll_NVLoad(tpm_state); |
355 | | |
356 | | /* restore a previous empty buffer or any valid buffer */ |
357 | 0 | if (is_empty_buffer || buffer != NULL) |
358 | 0 | SetCachedState(TPMLIB_STATE_PERMANENT, buffer, buffer_len); |
359 | 0 | } |
360 | |
|
361 | 0 | return ret; |
362 | 0 | } |
363 | | |
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 | | */ |
370 | | static TPM_RESULT TPM12_GetState(enum TPMLIB_StateType st, |
371 | | unsigned char **buffer, uint32_t *buflen) |
372 | 0 | { |
373 | 0 | TPM_RESULT ret = TPM_FAIL; |
374 | 0 | TPM_STORE_BUFFER tsb; |
375 | 0 | uint32_t total; |
376 | | |
377 | | /* TPM not running ? */ |
378 | 0 | if (tpm_instances[0] == NULL) { |
379 | 0 | struct libtpms_callbacks *cbs = TPMLIB_GetCallbacks(); |
380 | 0 | bool is_empty_buffer; |
381 | | |
382 | | /* try cached blob before file */ |
383 | 0 | ret = CopyCachedState(st, buffer, buflen, &is_empty_buffer); |
384 | 0 | if (ret != TPM_SUCCESS || *buffer != NULL || is_empty_buffer) |
385 | 0 | return ret; |
386 | | |
387 | 0 | if (cbs->tpm_nvram_init) { |
388 | 0 | ret = cbs->tpm_nvram_init(); |
389 | 0 | if (ret != TPM_SUCCESS) |
390 | 0 | return ret; |
391 | | |
392 | 0 | ret = TPM_NVRAM_LoadData(buffer, buflen, 0, |
393 | 0 | TPMLIB_StateTypeToName(st)); |
394 | 0 | } else { |
395 | 0 | ret = TPM_FAIL; |
396 | 0 | } |
397 | 0 | return ret; |
398 | 0 | } |
399 | | |
400 | 0 | TPM_Sbuffer_Init(&tsb); |
401 | |
|
402 | 0 | switch (st) { |
403 | 0 | case TPMLIB_STATE_PERMANENT: |
404 | 0 | ret = _TPM_PermanentAll_Store(&tsb, tpm_instances[0]); |
405 | 0 | break; |
406 | 0 | case TPMLIB_STATE_VOLATILE: |
407 | 0 | ret = TPM_VolatileAll_Store(&tsb, tpm_instances[0]); |
408 | 0 | break; |
409 | 0 | case TPMLIB_STATE_SAVE_STATE: |
410 | 0 | ret = TPM_SaveState_Store(&tsb, tpm_instances[0]); |
411 | 0 | break; |
412 | 0 | } |
413 | | |
414 | 0 | if (ret == TPM_SUCCESS) { |
415 | | /* caller now owns the buffer and needs to free it */ |
416 | 0 | TPM_Sbuffer_GetAll(&tsb, buffer, buflen, &total); |
417 | 0 | } else { |
418 | 0 | TPM_Sbuffer_Delete(&tsb); |
419 | 0 | *buflen = 0; |
420 | 0 | *buffer = NULL; |
421 | 0 | } |
422 | |
|
423 | 0 | return ret; |
424 | 0 | } |
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 | | */ |
436 | | static TPM_RESULT TPM12_SetState(enum TPMLIB_StateType st, |
437 | | const unsigned char *buffer, uint32_t buflen) |
438 | 0 | { |
439 | 0 | TPM_RESULT ret = TPM_SUCCESS; |
440 | 0 | unsigned char *stream = NULL, *orig_stream = NULL; |
441 | 0 | uint32_t stream_size = buflen; |
442 | 0 | tpm_state_t *tpm_state = NULL; |
443 | |
|
444 | 0 | if (buffer == NULL) { |
445 | 0 | SetCachedState(st, NULL, 0); |
446 | 0 | return TPM_SUCCESS; |
447 | 0 | } |
448 | | |
449 | 0 | if (tpm_instances[0]) |
450 | 0 | return TPM_INVALID_POSTINIT; |
451 | | |
452 | 0 | if (ret == TPM_SUCCESS) { |
453 | 0 | stream = malloc(buflen); |
454 | 0 | if (!stream) { |
455 | 0 | TPMLIB_LogError("Could not allocate %u bytes.\n", buflen); |
456 | 0 | ret = TPM_SIZE; |
457 | 0 | } |
458 | 0 | } |
459 | |
|
460 | 0 | if (ret == TPM_SUCCESS) { |
461 | 0 | orig_stream = stream; |
462 | 0 | memcpy(stream, buffer, buflen); |
463 | |
|
464 | 0 | tpm_state = malloc(sizeof(tpm_state_t)); |
465 | 0 | if (!tpm_state) { |
466 | 0 | TPMLIB_LogError("Could not allocated %zu bytes.\n", |
467 | 0 | sizeof(tpm_state_t)); |
468 | 0 | ret = TPM_SIZE; |
469 | 0 | } |
470 | 0 | } |
471 | |
|
472 | 0 | if (ret == TPM_SUCCESS) { |
473 | 0 | ret = TPM_Global_Init(tpm_state); |
474 | 0 | } |
475 | | |
476 | | /* test whether we can accept the blob */ |
477 | 0 | if (ret == TPM_SUCCESS) { |
478 | 0 | tpm_state->tpm_number = 0; |
479 | |
|
480 | 0 | switch (st) { |
481 | 0 | case TPMLIB_STATE_PERMANENT: |
482 | 0 | ret = TPM_PermanentAll_Load(tpm_state, &stream, &stream_size); |
483 | 0 | break; |
484 | 0 | case TPMLIB_STATE_VOLATILE: |
485 | | /* permanent state needs to be there and loaded first */ |
486 | 0 | ret = TPM_PermanentAll_NVLoad_Preserve(tpm_state); |
487 | 0 | if (ret == TPM_SUCCESS) |
488 | 0 | ret = TPM_VolatileAll_Load(tpm_state, &stream, &stream_size); |
489 | 0 | break; |
490 | 0 | case TPMLIB_STATE_SAVE_STATE: |
491 | 0 | ret = TPM_PermanentAll_NVLoad_Preserve(tpm_state); |
492 | 0 | if (ret == TPM_SUCCESS) |
493 | 0 | ret = TPM_SaveState_Load(tpm_state, &stream, &stream_size); |
494 | 0 | break; |
495 | 0 | } |
496 | 0 | if (ret) |
497 | 0 | ClearAllCachedState(); |
498 | 0 | } |
499 | | |
500 | | /* cache the blob for the TPM_MainInit() to pick it up */ |
501 | 0 | if (ret == TPM_SUCCESS) { |
502 | 0 | SetCachedState(st, orig_stream, buflen); |
503 | 0 | } else { |
504 | 0 | free(orig_stream); |
505 | 0 | } |
506 | |
|
507 | 0 | TPM_Global_Delete(tpm_state); |
508 | 0 | free(tpm_state); |
509 | |
|
510 | 0 | return ret; |
511 | 0 | } |
512 | | |
513 | | static TPM_RESULT TPM12_SetProfile(const char *profile) |
514 | 0 | { |
515 | 0 | return TPM_FAIL; |
516 | 0 | } |
517 | | |
518 | | static TPM_BOOL TPM12_WasManufactured(void) |
519 | 0 | { |
520 | 0 | return FALSE; |
521 | 0 | } |
522 | | |
523 | | const struct tpm_interface TPM12Interface = { |
524 | | .MainInit = TPM12_MainInit, |
525 | | .Terminate = TPM12_Terminate, |
526 | | .Process = TPM12_Process, |
527 | | .VolatileAllStore = TPM12_VolatileAllStore, |
528 | | .CancelCommand = TPM12_CancelCommand, |
529 | | .GetTPMProperty = TPM12_GetTPMProperty, |
530 | | .GetInfo = TPM12_GetInfo, |
531 | | .TpmEstablishedGet = TPM12_IO_TpmEstablished_Get, |
532 | | .TpmEstablishedReset = TPM12_IO_TpmEstablished_Reset, |
533 | | .HashStart = TPM12_IO_Hash_Start, |
534 | | .HashData = TPM12_IO_Hash_Data, |
535 | | .HashEnd = TPM12_IO_Hash_End, |
536 | | .SetBufferSize = TPM12_SetBufferSize, |
537 | | .ValidateState = TPM12_ValidateState, |
538 | | .SetState = TPM12_SetState, |
539 | | .GetState = TPM12_GetState, |
540 | | .SetProfile = TPM12_SetProfile, |
541 | | .WasManufactured = TPM12_WasManufactured, |
542 | | }; |