libtpmtss: Add enumeration of supported signature schemes to TSS2 implementations
[strongswan.git] / src / libtpmtss / tpm_tss_tss2_v1.c
1 /*
2 * Copyright (C) 2018 Tobias Brunner
3 * Copyright (C) 2016-2018 Andreas Steffen
4 * HSR Hochschule fuer Technik Rapperswil
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * for more details.
15 */
16
17 #include "tpm_tss_tss2.h"
18 #include "tpm_tss_tss2_names.h"
19
20 #ifdef TSS_TSS2_V1
21
22 #include <asn1/asn1.h>
23 #include <asn1/oid.h>
24 #include <bio/bio_reader.h>
25
26 #include <tpm20.h>
27
28 #ifdef TSS2_TCTI_TABRMD
29 #include <tcti/tcti-tabrmd.h>
30 #endif /* TSS2_TCTI_TABRMD */
31
32 #ifdef TSS2_TCTI_SOCKET
33 #include <tcti_socket.h>
34
35 #define TCTI_SOCKET_DEFAULT_ADDRESS "127.0.0.1"
36 #define TCTI_SOCKET_DEFAULT_PORT 2323
37 #endif /* TSS2_TCTI_SOCKET */
38
39 #define LABEL "TPM 2.0 -"
40
41 typedef struct private_tpm_tss_tss2_t private_tpm_tss_tss2_t;
42
43 /**
44 * Private data of an tpm_tss_tss2_t object.
45 */
46 struct private_tpm_tss_tss2_t {
47
48 /**
49 * Public tpm_tss_tss2_t interface.
50 */
51 tpm_tss_t public;
52
53 /**
54 * TCTI context
55 */
56 TSS2_TCTI_CONTEXT *tcti_context;
57
58 /**
59 * SYS context
60 */
61 TSS2_SYS_CONTEXT *sys_context;
62
63 /**
64 * Number of supported algorithms
65 */
66 size_t supported_algs_count;
67
68 /**
69 * List of supported algorithms
70 */
71 TPM_ALG_ID supported_algs[TPM_PT_ALGORITHM_SET];
72 };
73
74 /**
75 * Some symbols required by libtctisocket
76 */
77 FILE *outFp;
78 uint8_t simulator = 1;
79
80 int TpmClientPrintf (uint8_t type, const char *format, ...)
81 {
82 return 0;
83 }
84
85 /**
86 * Convert hash algorithm to TPM_ALG_ID
87 */
88 static TPM_ALG_ID hash_alg_to_tpm_alg_id(hash_algorithm_t alg)
89 {
90 switch (alg)
91 {
92 case HASH_SHA1:
93 return TPM_ALG_SHA1;
94 case HASH_SHA256:
95 return TPM_ALG_SHA256;
96 case HASH_SHA384:
97 return TPM_ALG_SHA384;
98 case HASH_SHA512:
99 return TPM_ALG_SHA512;
100 default:
101 return TPM_ALG_ERROR;
102 }
103 }
104
105 /**
106 * Convert TPM_ALG_ID to hash algorithm
107 */
108 static hash_algorithm_t hash_alg_from_tpm_alg_id(TPM_ALG_ID alg)
109 {
110 switch (alg)
111 {
112 case TPM_ALG_SHA1:
113 return HASH_SHA1;
114 case TPM_ALG_SHA256:
115 return HASH_SHA256;
116 case TPM_ALG_SHA384:
117 return HASH_SHA384;
118 case TPM_ALG_SHA512:
119 return HASH_SHA512;
120 default:
121 return HASH_UNKNOWN;
122 }
123 }
124
125 /**
126 * Check if an algorithm given by its TPM_ALG_ID is supported by the TPM
127 */
128 static bool is_supported_alg(private_tpm_tss_tss2_t *this, TPM_ALG_ID alg_id)
129 {
130 int i;
131
132 if (alg_id == TPM_ALG_ERROR)
133 {
134 return FALSE;
135 }
136
137 for (i = 0; i < this->supported_algs_count; i++)
138 {
139 if (this->supported_algs[i] == alg_id)
140 {
141 return TRUE;
142 }
143 }
144
145 return FALSE;
146 }
147
148 /**
149 * Get a list of supported algorithms
150 */
151 static bool get_algs_capability(private_tpm_tss_tss2_t *this)
152 {
153 TPMS_CAPABILITY_DATA cap_data;
154 TPMS_TAGGED_PROPERTY tp;
155 TPMI_YES_NO more_data;
156 TPM_ALG_ID alg;
157 uint32_t rval, i, offset, revision = 0, year = 0;
158 size_t len = BUF_LEN;
159 char buf[BUF_LEN], manufacturer[5], vendor_string[17];
160 char *pos = buf;
161 int written;
162
163 /* get fixed properties */
164 rval = Tss2_Sys_GetCapability(this->sys_context, 0, TPM_CAP_TPM_PROPERTIES,
165 PT_FIXED, MAX_TPM_PROPERTIES, &more_data, &cap_data, 0);
166 if (rval != TPM_RC_SUCCESS)
167 {
168 DBG1(DBG_PTS, "%s GetCapability failed for TPM_CAP_TPM_PROPERTIES: 0x%06x",
169 LABEL, rval);
170 return FALSE;
171 }
172 memset(manufacturer, '\0', sizeof(manufacturer));
173 memset(vendor_string, '\0', sizeof(vendor_string));
174
175 /* print fixed properties */
176 for (i = 0; i < cap_data.data.tpmProperties.count; i++)
177 {
178 tp = cap_data.data.tpmProperties.tpmProperty[i];
179 switch (tp.property)
180 {
181 case TPM_PT_REVISION:
182 revision = tp.value;
183 break;
184 case TPM_PT_YEAR:
185 year = tp.value;
186 break;
187 case TPM_PT_MANUFACTURER:
188 htoun32(manufacturer, tp.value);
189 break;
190 case TPM_PT_VENDOR_STRING_1:
191 case TPM_PT_VENDOR_STRING_2:
192 case TPM_PT_VENDOR_STRING_3:
193 case TPM_PT_VENDOR_STRING_4:
194 offset = 4 * (tp.property - TPM_PT_VENDOR_STRING_1);
195 htoun32(vendor_string + offset, tp.value);
196 break;
197 default:
198 break;
199 }
200 }
201 DBG2(DBG_PTS, "%s manufacturer: %s (%s) rev: %05.2f %u", LABEL, manufacturer,
202 vendor_string, (float)revision/100, year);
203
204 /* get supported algorithms */
205 rval = Tss2_Sys_GetCapability(this->sys_context, 0, TPM_CAP_ALGS,
206 0, TPM_PT_ALGORITHM_SET, &more_data, &cap_data, 0);
207 if (rval != TPM_RC_SUCCESS)
208 {
209 DBG1(DBG_PTS, "%s GetCapability failed for TPM_CAP_ALGS: 0x%06x",
210 LABEL, rval);
211 return FALSE;
212 }
213
214 /* Number of supported algorithms */
215 this->supported_algs_count = cap_data.data.algorithms.count;
216
217 /* store and print supported algorithms */
218 for (i = 0; i < this->supported_algs_count; i++)
219 {
220 alg = cap_data.data.algorithms.algProperties[i].alg;
221 this->supported_algs[i] = alg;
222
223 written = snprintf(pos, len, " %N", tpm_alg_id_names, alg);
224 if (written < 0 || written >= len)
225 {
226 break;
227 }
228 pos += written;
229 len -= written;
230 }
231 DBG2(DBG_PTS, "%s algorithms:%s", LABEL, buf);
232
233 /* get supported ECC curves */
234 rval = Tss2_Sys_GetCapability(this->sys_context, 0, TPM_CAP_ECC_CURVES,
235 0, TPM_PT_LOADED_CURVES, &more_data, &cap_data, 0);
236 if (rval != TPM_RC_SUCCESS)
237 {
238 DBG1(DBG_PTS, "%s GetCapability failed for TPM_ECC_CURVES: 0x%06x",
239 LABEL, rval);
240 return FALSE;
241 }
242
243 /* reset print buffer */
244 pos = buf;
245 len = BUF_LEN;
246
247 /* print supported ECC curves */
248 for (i = 0; i < cap_data.data.eccCurves.count; i++)
249 {
250 written = snprintf(pos, len, " %N", tpm_ecc_curve_names,
251 cap_data.data.eccCurves.eccCurves[i]);
252 if (written < 0 || written >= len)
253 {
254 break;
255 }
256 pos += written;
257 len -= written;
258 }
259 DBG2(DBG_PTS, "%s ECC curves:%s", LABEL, buf);
260
261 return TRUE;
262 }
263
264 /**
265 * Initialize TSS2 TCTI TABRMD context
266 */
267 static bool initialize_tcti_tabrmd_context(private_tpm_tss_tss2_t *this)
268 {
269 #ifdef TSS2_TCTI_TABRMD
270 size_t tcti_context_size;
271 uint32_t rval;
272
273 /* determine size of tcti context */
274 rval = tss2_tcti_tabrmd_init(NULL, &tcti_context_size);
275 if (rval != TSS2_RC_SUCCESS)
276 {
277 DBG1(DBG_PTS, "%s could not get tcti_context size: 0x%06x",
278 LABEL, rval);
279 return FALSE;
280 }
281
282 /* allocate and initialize memory for tcti context */
283 this->tcti_context = (TSS2_TCTI_CONTEXT*)malloc(tcti_context_size);
284 memset(this->tcti_context, 0x00, tcti_context_size);
285
286 /* initialize tcti context */
287 rval = tss2_tcti_tabrmd_init(this->tcti_context, &tcti_context_size);
288 if (rval != TSS2_RC_SUCCESS)
289 {
290 DBG1(DBG_PTS, "%s could not get tcti_context: 0x%06x "
291 "via tabrmd interface", LABEL, rval);
292 return FALSE;
293 }
294 return TRUE;
295 #else /* TSS2_TCTI_TABRMD */
296 return FALSE;
297 #endif /* TSS2_TCTI_TABRMD */
298 }
299
300 /**
301 * Initialize TSS2 TCTI Socket context
302 */
303 static bool initialize_tcti_socket_context(private_tpm_tss_tss2_t *this)
304 {
305 #ifdef TSS2_TCTI_SOCKET
306 size_t tcti_context_size;
307 uint32_t rval;
308
309 TCTI_SOCKET_CONF rm_if_config = { TCTI_SOCKET_DEFAULT_ADDRESS,
310 TCTI_SOCKET_DEFAULT_PORT
311 };
312
313 /* determine size of tcti context */
314 rval = InitSocketTcti(NULL, &tcti_context_size, &rm_if_config, 0);
315 if (rval != TSS2_RC_SUCCESS)
316 {
317 DBG1(DBG_PTS, "%s could not get tcti_context size: 0x%06x",
318 LABEL, rval);
319 return FALSE;
320 }
321
322 /* allocate memory for tcti context */
323 this->tcti_context = (TSS2_TCTI_CONTEXT*)malloc(tcti_context_size);
324
325 /* initialize tcti context */
326 rval = InitSocketTcti(this->tcti_context, &tcti_context_size,
327 &rm_if_config, 0);
328 if (rval != TSS2_RC_SUCCESS)
329 {
330 DBG1(DBG_PTS, "%s could not get tcti_context: 0x%06x "
331 "via socket interface", LABEL, rval);
332 return FALSE;
333 }
334 return TRUE;
335 #else /* TSS2_TCTI_SOCKET */
336 return FALSE;
337 #endif /* TSS2_TCTI_SOCKET */
338 }
339
340 /**
341 * Initialize TSS2 Sys context
342 */
343 static bool initialize_sys_context(private_tpm_tss_tss2_t *this)
344 {
345 uint32_t sys_context_size;
346 uint32_t rval;
347
348 TSS2_ABI_VERSION abi_version = { TSSWG_INTEROP,
349 TSS_SAPI_FIRST_FAMILY,
350 TSS_SAPI_FIRST_LEVEL,
351 TSS_SAPI_FIRST_VERSION
352 };
353
354 /* determine size of sys context */
355 sys_context_size = Tss2_Sys_GetContextSize(0);
356
357 /* allocate memory for sys context */
358 this->sys_context = malloc(sys_context_size);
359
360 /* initialize sys context */
361 rval = Tss2_Sys_Initialize(this->sys_context, sys_context_size,
362 this->tcti_context, &abi_version);
363 if (rval != TSS2_RC_SUCCESS)
364 {
365 DBG1(DBG_PTS, "%s could not get sys_context: 0x%06x",
366 LABEL, rval);
367 return FALSE;
368 }
369
370 /* get a list of supported algorithms and ECC curves */
371 return get_algs_capability(this);
372 }
373
374 /**
375 * Finalize TSS context
376 */
377 static void finalize_context(private_tpm_tss_tss2_t *this)
378 {
379 if (this->tcti_context)
380 {
381 tss2_tcti_finalize(this->tcti_context);
382 free(this->tcti_context);
383 }
384 if (this->sys_context)
385 {
386 Tss2_Sys_Finalize(this->sys_context);
387 free(this->sys_context);
388 }
389 }
390
391 METHOD(tpm_tss_t, get_version, tpm_version_t,
392 private_tpm_tss_tss2_t *this)
393 {
394 return TPM_VERSION_2_0;
395 }
396
397 METHOD(tpm_tss_t, get_version_info, chunk_t,
398 private_tpm_tss_tss2_t *this)
399 {
400 return chunk_empty;
401 }
402
403 /**
404 * read the public key portion of a TSS 2.0 AIK key from NVRAM
405 */
406 bool read_public(private_tpm_tss_tss2_t *this, TPMI_DH_OBJECT handle,
407 TPM2B_PUBLIC *public)
408 {
409 uint32_t rval;
410
411 TPM2B_NAME name = { { sizeof(TPM2B_NAME)-2, } };
412 TPM2B_NAME qualified_name = { { sizeof(TPM2B_NAME)-2, } };
413
414 TPMS_AUTH_RESPONSE session_data;
415 TSS2_SYS_RSP_AUTHS sessions_data;
416 TPMS_AUTH_RESPONSE *session_data_array[1];
417
418 session_data_array[0] = &session_data;
419 sessions_data.rspAuths = &session_data_array[0];
420 sessions_data.rspAuthsCount = 1;
421
422 /* read public key for a given object handle from TPM 2.0 NVRAM */
423 rval = Tss2_Sys_ReadPublic(this->sys_context, handle, 0, public, &name,
424 &qualified_name, &sessions_data);
425 if (rval != TPM_RC_SUCCESS)
426 {
427 DBG1(DBG_PTS, "%s could not read public key from handle 0x%08x: 0x%06x",
428 LABEL, handle, rval);
429 return FALSE;
430 }
431 return TRUE;
432 }
433
434 METHOD(tpm_tss_t, generate_aik, bool,
435 private_tpm_tss_tss2_t *this, chunk_t ca_modulus, chunk_t *aik_blob,
436 chunk_t *aik_pubkey, chunk_t *identity_req)
437 {
438 return FALSE;
439 }
440
441 METHOD(tpm_tss_t, get_public, chunk_t,
442 private_tpm_tss_tss2_t *this, uint32_t handle)
443 {
444 TPM2B_PUBLIC public = { { 0, } };
445 TPM_ALG_ID sig_alg, digest_alg;
446 chunk_t aik_blob, aik_pubkey = chunk_empty;
447
448 if (!read_public(this, handle, &public))
449 {
450 return chunk_empty;
451 }
452
453 aik_blob = chunk_create((u_char*)&public, sizeof(public));
454 DBG3(DBG_LIB, "%s AIK public key blob: %B", LABEL, &aik_blob);
455
456 /* convert TSS 2.0 AIK public key blot into PKCS#1 format */
457 switch (public.t.publicArea.type)
458 {
459 case TPM_ALG_RSA:
460 {
461 TPM2B_PUBLIC_KEY_RSA *rsa;
462 TPMT_RSA_SCHEME *scheme;
463 chunk_t aik_exponent, aik_modulus;
464
465 scheme = &public.t.publicArea.parameters.rsaDetail.scheme;
466 sig_alg = scheme->scheme;
467 digest_alg = scheme->details.anySig.hashAlg;
468
469 rsa = &public.t.publicArea.unique.rsa;
470 aik_modulus = chunk_create(rsa->t.buffer, rsa->t.size);
471 aik_exponent = chunk_from_chars(0x01, 0x00, 0x01);
472
473 /* subjectPublicKeyInfo encoding of AIK RSA key */
474 if (!lib->encoding->encode(lib->encoding, PUBKEY_SPKI_ASN1_DER,
475 NULL, &aik_pubkey, CRED_PART_RSA_MODULUS, aik_modulus,
476 CRED_PART_RSA_PUB_EXP, aik_exponent, CRED_PART_END))
477 {
478 DBG1(DBG_PTS, "%s subjectPublicKeyInfo encoding of AIK key "
479 "failed", LABEL);
480 return chunk_empty;
481 }
482 break;
483 }
484 case TPM_ALG_ECC:
485 {
486 TPMS_ECC_POINT *ecc;
487 TPMT_ECC_SCHEME *scheme;
488 chunk_t ecc_point;
489 uint8_t *pos;
490
491 scheme = &public.t.publicArea.parameters.eccDetail.scheme;
492 sig_alg = scheme->scheme;
493 digest_alg = scheme->details.anySig.hashAlg;
494
495 ecc = &public.t.publicArea.unique.ecc;
496
497 /* allocate space for bit string */
498 pos = asn1_build_object(&ecc_point, ASN1_BIT_STRING,
499 2 + ecc->x.t.size + ecc->y.t.size);
500 /* bit string length is a multiple of octets */
501 *pos++ = 0x00;
502 /* uncompressed ECC point format */
503 *pos++ = 0x04;
504 /* copy x coordinate of ECC point */
505 memcpy(pos, ecc->x.t.buffer, ecc->x.t.size);
506 pos += ecc->x.t.size;
507 /* copy y coordinate of ECC point */
508 memcpy(pos, ecc->y.t.buffer, ecc->y.t.size);
509 /* subjectPublicKeyInfo encoding of AIK ECC key */
510 aik_pubkey = asn1_wrap(ASN1_SEQUENCE, "mm",
511 asn1_wrap(ASN1_SEQUENCE, "mm",
512 asn1_build_known_oid(OID_EC_PUBLICKEY),
513 asn1_build_known_oid(ecc->x.t.size == 32 ?
514 OID_PRIME256V1 : OID_SECT384R1)),
515 ecc_point);
516 break;
517 }
518 default:
519 DBG1(DBG_PTS, "%s unsupported AIK key type", LABEL);
520 return chunk_empty;
521 }
522 DBG1(DBG_PTS, "AIK signature algorithm is %N with %N hash",
523 tpm_alg_id_names, sig_alg, tpm_alg_id_names, digest_alg);
524 return aik_pubkey;
525 }
526
527 METHOD(tpm_tss_t, supported_signature_schemes, enumerator_t*,
528 private_tpm_tss_tss2_t *this, uint32_t handle)
529 {
530 TPM2B_PUBLIC public = { { 0, } };
531 hash_algorithm_t digest;
532 signature_params_t supported_scheme;
533
534 if (!read_public(this, handle, &public))
535 {
536 return enumerator_create_empty();
537 }
538
539 switch (public.t.publicArea.type)
540 {
541 case TPM_ALG_RSA:
542 {
543 TPMS_RSA_PARMS *rsa;
544 TPMT_RSA_SCHEME *scheme;
545
546 rsa = &public.t.publicArea.parameters.rsaDetail;
547 scheme = &rsa->scheme;
548 digest = hash_alg_from_tpm_alg_id(scheme->details.anySig.hashAlg);
549
550 switch (scheme->scheme)
551 {
552 case TPM_ALG_RSAPSS:
553 {
554 rsa_pss_params_t pss_params = {
555 .hash = digest,
556 .mgf1_hash = digest,
557 .salt_len = RSA_PSS_SALT_LEN_MAX,
558 };
559 supported_scheme = (signature_params_t){
560 .scheme = SIGN_RSA_EMSA_PSS,
561 .params = &pss_params,
562 };
563 if (!rsa_pss_params_set_salt_len(&pss_params, rsa->keyBits))
564 {
565 return enumerator_create_empty();
566 }
567 break;
568 }
569 case TPM_ALG_RSASSA:
570 supported_scheme = (signature_params_t){
571 .scheme = signature_scheme_from_oid(
572 hasher_signature_algorithm_to_oid(digest,
573 KEY_RSA)),
574 };
575 break;
576 default:
577 return enumerator_create_empty();
578 }
579 break;
580 }
581 case TPM_ALG_ECC:
582 {
583 TPMT_ECC_SCHEME *scheme;
584
585 scheme = &public.t.publicArea.parameters.eccDetail.scheme;
586 digest = hash_alg_from_tpm_alg_id(scheme->details.anySig.hashAlg);
587
588 switch (scheme->scheme)
589 {
590 case TPM_ALG_ECDSA:
591 supported_scheme = (signature_params_t){
592 .scheme = signature_scheme_from_oid(
593 hasher_signature_algorithm_to_oid(digest,
594 KEY_ECDSA)),
595 };
596 break;
597 default:
598 return enumerator_create_empty();
599 }
600 break;
601 }
602 default:
603 DBG1(DBG_PTS, "%s unsupported AIK key type", LABEL);
604 return enumerator_create_empty();
605 }
606 return enumerator_create_single(signature_params_clone(&supported_scheme),
607 (void*)signature_params_destroy);
608 }
609
610 /**
611 * Configure a PCR Selection assuming a maximum of 24 registers
612 */
613 static bool init_pcr_selection(private_tpm_tss_tss2_t *this, uint32_t pcrs,
614 hash_algorithm_t alg, TPML_PCR_SELECTION *pcr_sel)
615 {
616 TPM_ALG_ID alg_id;
617 uint32_t pcr;
618
619 /* check if hash algorithm is supported by TPM */
620 alg_id = hash_alg_to_tpm_alg_id(alg);
621 if (!is_supported_alg(this, alg_id))
622 {
623 DBG1(DBG_PTS, "%s %N hash algorithm not supported by TPM",
624 LABEL, hash_algorithm_short_names, alg);
625 return FALSE;
626 }
627
628 /* initialize the PCR Selection structure,*/
629 pcr_sel->count = 1;
630 pcr_sel->pcrSelections[0].hash = alg_id;
631 pcr_sel->pcrSelections[0].sizeofSelect = 3;
632 pcr_sel->pcrSelections[0].pcrSelect[0] = 0;
633 pcr_sel->pcrSelections[0].pcrSelect[1] = 0;
634 pcr_sel->pcrSelections[0].pcrSelect[2] = 0;
635
636 /* set the selected PCRs */
637 for (pcr = 0; pcr < PLATFORM_PCR; pcr++)
638 {
639 if (pcrs & (1 << pcr))
640 {
641 pcr_sel->pcrSelections[0].pcrSelect[pcr / 8] |= ( 1 << (pcr % 8) );
642 }
643 }
644 return TRUE;
645 }
646
647 METHOD(tpm_tss_t, read_pcr, bool,
648 private_tpm_tss_tss2_t *this, uint32_t pcr_num, chunk_t *pcr_value,
649 hash_algorithm_t alg)
650 {
651 TPML_PCR_SELECTION pcr_selection;
652 TPML_DIGEST pcr_values;
653
654 uint32_t pcr_update_counter, rval;
655 uint8_t *pcr_value_ptr;
656 size_t pcr_value_len;
657
658 if (pcr_num >= PLATFORM_PCR)
659 {
660 DBG1(DBG_PTS, "%s maximum number of supported PCR is %d",
661 LABEL, PLATFORM_PCR);
662 return FALSE;
663 }
664
665 if (!init_pcr_selection(this, (1 << pcr_num), alg, &pcr_selection))
666 {
667 return FALSE;
668 }
669
670 /* initialize the PCR Digest structure */
671 memset(&pcr_values, 0, sizeof(TPML_DIGEST));
672
673 /* read the PCR value */
674 rval = Tss2_Sys_PCR_Read(this->sys_context, 0, &pcr_selection,
675 &pcr_update_counter, &pcr_selection, &pcr_values, 0);
676 if (rval != TPM_RC_SUCCESS)
677 {
678 DBG1(DBG_PTS, "%s PCR bank could not be read: 0x%60x",
679 LABEL, rval);
680 return FALSE;
681 }
682 pcr_value_ptr = (uint8_t *)pcr_values.digests[0].t.buffer;
683 pcr_value_len = (size_t) pcr_values.digests[0].t.size;
684
685 *pcr_value = chunk_clone(chunk_create(pcr_value_ptr, pcr_value_len));
686
687 return TRUE;
688 }
689
690 METHOD(tpm_tss_t, extend_pcr, bool,
691 private_tpm_tss_tss2_t *this, uint32_t pcr_num, chunk_t *pcr_value,
692 chunk_t data, hash_algorithm_t alg)
693 {
694 uint32_t rval;
695 TPM_ALG_ID alg_id;
696 TPML_DIGEST_VALUES digest_values;
697 TPMS_AUTH_COMMAND session_data_cmd;
698 TPMS_AUTH_RESPONSE session_data_rsp;
699 TSS2_SYS_CMD_AUTHS sessions_data_cmd;
700 TSS2_SYS_RSP_AUTHS sessions_data_rsp;
701 TPMS_AUTH_COMMAND *session_data_cmd_array[1];
702 TPMS_AUTH_RESPONSE *session_data_rsp_array[1];
703
704 session_data_cmd_array[0] = &session_data_cmd;
705 session_data_rsp_array[0] = &session_data_rsp;
706
707 sessions_data_cmd.cmdAuths = &session_data_cmd_array[0];
708 sessions_data_rsp.rspAuths = &session_data_rsp_array[0];
709
710 sessions_data_cmd.cmdAuthsCount = 1;
711 sessions_data_rsp.rspAuthsCount = 1;
712
713 session_data_cmd.sessionHandle = TPM_RS_PW;
714 session_data_cmd.hmac.t.size = 0;
715 session_data_cmd.nonce.t.size = 0;
716
717 *( (uint8_t *)((void *)&session_data_cmd.sessionAttributes ) ) = 0;
718
719 /* check if hash algorithm is supported by TPM */
720 alg_id = hash_alg_to_tpm_alg_id(alg);
721 if (!is_supported_alg(this, alg_id))
722 {
723 DBG1(DBG_PTS, "%s %N hash algorithm not supported by TPM",
724 LABEL, hash_algorithm_short_names, alg);
725 return FALSE;
726 }
727
728 digest_values.count = 1;
729 digest_values.digests[0].hashAlg = alg_id;
730
731 switch (alg)
732 {
733 case HASH_SHA1:
734 if (data.len != HASH_SIZE_SHA1)
735 {
736 return FALSE;
737 }
738 memcpy(digest_values.digests[0].digest.sha1, data.ptr,
739 HASH_SIZE_SHA1);
740 break;
741 case HASH_SHA256:
742 if (data.len != HASH_SIZE_SHA256)
743 {
744 return FALSE;
745 }
746 memcpy(digest_values.digests[0].digest.sha256, data.ptr,
747 HASH_SIZE_SHA256);
748 break;
749 case HASH_SHA384:
750 if (data.len != HASH_SIZE_SHA384)
751 {
752 return FALSE;
753 }
754 memcpy(digest_values.digests[0].digest.sha384, data.ptr,
755 HASH_SIZE_SHA384);
756 break;
757 case HASH_SHA512:
758 if (data.len != HASH_SIZE_SHA512)
759 {
760 return FALSE;
761 }
762 memcpy(digest_values.digests[0].digest.sha512, data.ptr,
763 HASH_SIZE_SHA512);
764 break;
765 default:
766 return FALSE;
767 }
768
769 /* extend PCR */
770 rval = Tss2_Sys_PCR_Extend(this->sys_context, pcr_num, &sessions_data_cmd,
771 &digest_values, &sessions_data_rsp);
772 if (rval != TPM_RC_SUCCESS)
773 {
774 DBG1(DBG_PTS, "%s PCR %02u could not be extended: 0x%06x",
775 LABEL, pcr_num, rval);
776 return FALSE;
777 }
778
779 /* get updated PCR value */
780 return read_pcr(this, pcr_num, pcr_value, alg);
781 }
782
783 METHOD(tpm_tss_t, quote, bool,
784 private_tpm_tss_tss2_t *this, uint32_t aik_handle, uint32_t pcr_sel,
785 hash_algorithm_t alg, chunk_t data, tpm_quote_mode_t *quote_mode,
786 tpm_tss_quote_info_t **quote_info, chunk_t *quote_sig)
787 {
788 chunk_t quoted_chunk, qualified_signer, extra_data, clock_info,
789 firmware_version, pcr_select, pcr_digest;
790 hash_algorithm_t pcr_digest_alg;
791 bio_reader_t *reader;
792 uint32_t rval;
793
794 TPM2B_DATA qualifying_data;
795 TPML_PCR_SELECTION pcr_selection;
796 TPM2B_ATTEST quoted = { { sizeof(TPM2B_ATTEST)-2, } };
797 TPMT_SIG_SCHEME scheme;
798 TPMT_SIGNATURE sig;
799 TPMI_ALG_HASH hash_alg;
800 TPMS_AUTH_COMMAND session_data_cmd;
801 TPMS_AUTH_RESPONSE session_data_rsp;
802 TSS2_SYS_CMD_AUTHS sessions_data_cmd;
803 TSS2_SYS_RSP_AUTHS sessions_data_rsp;
804 TPMS_AUTH_COMMAND *session_data_cmd_array[1];
805 TPMS_AUTH_RESPONSE *session_data_rsp_array[1];
806
807 session_data_cmd_array[0] = &session_data_cmd;
808 session_data_rsp_array[0] = &session_data_rsp;
809
810 sessions_data_cmd.cmdAuths = &session_data_cmd_array[0];
811 sessions_data_rsp.rspAuths = &session_data_rsp_array[0];
812
813 sessions_data_cmd.cmdAuthsCount = 1;
814 sessions_data_rsp.rspAuthsCount = 1;
815
816 session_data_cmd.sessionHandle = TPM_RS_PW;
817 session_data_cmd.hmac.t.size = 0;
818 session_data_cmd.nonce.t.size = 0;
819
820 *( (uint8_t *)((void *)&session_data_cmd.sessionAttributes ) ) = 0;
821
822 qualifying_data.t.size = data.len;
823 memcpy(qualifying_data.t.buffer, data.ptr, data.len);
824
825 scheme.scheme = TPM_ALG_NULL;
826 memset(&sig, 0x00, sizeof(sig));
827
828 /* set Quote mode */
829 *quote_mode = TPM_QUOTE_TPM2;
830
831 if (!init_pcr_selection(this, pcr_sel, alg, &pcr_selection))
832 {
833 return FALSE;
834 }
835
836 rval = Tss2_Sys_Quote(this->sys_context, aik_handle, &sessions_data_cmd,
837 &qualifying_data, &scheme, &pcr_selection, &quoted,
838 &sig, &sessions_data_rsp);
839 if (rval != TPM_RC_SUCCESS)
840 {
841 DBG1(DBG_PTS,"%s Tss2_Sys_Quote failed: 0x%06x", LABEL, rval);
842 return FALSE;
843 }
844 quoted_chunk = chunk_create(quoted.t.attestationData, quoted.t.size);
845
846 reader = bio_reader_create(chunk_skip(quoted_chunk, 6));
847 if (!reader->read_data16(reader, &qualified_signer) ||
848 !reader->read_data16(reader, &extra_data) ||
849 !reader->read_data (reader, 17, &clock_info) ||
850 !reader->read_data (reader, 8, &firmware_version) ||
851 !reader->read_data (reader, 10, &pcr_select) ||
852 !reader->read_data16(reader, &pcr_digest))
853 {
854 DBG1(DBG_PTS, "%s parsing of quoted struct failed", LABEL);
855 reader->destroy(reader);
856 return FALSE;
857 }
858 reader->destroy(reader);
859
860 DBG2(DBG_PTS, "PCR Composite digest: %B", &pcr_digest);
861 DBG2(DBG_PTS, "TPM Quote Info: %B", &quoted_chunk);
862 DBG2(DBG_PTS, "qualifiedSigner: %B", &qualified_signer);
863 DBG2(DBG_PTS, "extraData: %B", &extra_data);
864 DBG2(DBG_PTS, "clockInfo: %B", &clock_info);
865 DBG2(DBG_PTS, "firmwareVersion: %B", &firmware_version);
866 DBG2(DBG_PTS, "pcrSelect: %B", &pcr_select);
867
868 /* extract signature */
869 switch (sig.sigAlg)
870 {
871 case TPM_ALG_RSASSA:
872 case TPM_ALG_RSAPSS:
873 *quote_sig = chunk_clone(
874 chunk_create(
875 sig.signature.rsassa.sig.t.buffer,
876 sig.signature.rsassa.sig.t.size));
877 hash_alg = sig.signature.rsassa.hash;
878 break;
879 case TPM_ALG_ECDSA:
880 case TPM_ALG_ECDAA:
881 case TPM_ALG_SM2:
882 case TPM_ALG_ECSCHNORR:
883 *quote_sig = chunk_cat("cc",
884 chunk_create(
885 sig.signature.ecdsa.signatureR.t.buffer,
886 sig.signature.ecdsa.signatureR.t.size),
887 chunk_create(
888 sig.signature.ecdsa.signatureS.t.buffer,
889 sig.signature.ecdsa.signatureS.t.size));
890 hash_alg = sig.signature.ecdsa.hash;
891 break;
892 default:
893 DBG1(DBG_PTS, "%s unsupported %N signature algorithm",
894 LABEL, tpm_alg_id_names, sig.sigAlg);
895 return FALSE;
896 }
897
898 DBG2(DBG_PTS, "PCR digest algorithm is %N", tpm_alg_id_names, hash_alg);
899 pcr_digest_alg = hash_alg_from_tpm_alg_id(hash_alg);
900
901 DBG2(DBG_PTS, "TPM Quote Signature: %B", quote_sig);
902
903 /* Create and initialize Quote Info object */
904 *quote_info = tpm_tss_quote_info_create(*quote_mode, pcr_digest_alg,
905 pcr_digest);
906 (*quote_info)->set_tpm2_info(*quote_info, qualified_signer, clock_info,
907 pcr_select);
908 (*quote_info)->set_version_info(*quote_info, firmware_version);
909
910 return TRUE;
911 }
912
913 METHOD(tpm_tss_t, sign, bool,
914 private_tpm_tss_tss2_t *this, uint32_t hierarchy, uint32_t handle,
915 signature_scheme_t scheme, void *params, chunk_t data, chunk_t pin,
916 chunk_t *signature)
917 {
918 key_type_t key_type;
919 hash_algorithm_t hash_alg;
920 rsa_pss_params_t *rsa_pss_params;
921 uint32_t rval;
922
923 TPM_ALG_ID alg_id;
924 TPM2B_MAX_BUFFER buffer;
925 TPM2B_DIGEST hash = { { sizeof(TPM2B_DIGEST)-2, } };
926 TPMT_TK_HASHCHECK validation;
927 TPM2B_PUBLIC public = { { 0, } };
928 TPMT_SIG_SCHEME sig_scheme;
929 TPMT_SIGNATURE sig;
930 TPMS_AUTH_COMMAND session_data_cmd;
931 TPMS_AUTH_RESPONSE session_data_rsp;
932 TSS2_SYS_CMD_AUTHS sessions_data_cmd;
933 TSS2_SYS_RSP_AUTHS sessions_data_rsp;
934 TPMS_AUTH_COMMAND *session_data_cmd_array[1];
935 TPMS_AUTH_RESPONSE *session_data_rsp_array[1];
936
937 session_data_cmd_array[0] = &session_data_cmd;
938 session_data_rsp_array[0] = &session_data_rsp;
939
940 sessions_data_cmd.cmdAuths = &session_data_cmd_array[0];
941 sessions_data_rsp.rspAuths = &session_data_rsp_array[0];
942
943 sessions_data_cmd.cmdAuthsCount = 1;
944 sessions_data_rsp.rspAuthsCount = 1;
945
946 session_data_cmd.sessionHandle = TPM_RS_PW;
947 session_data_cmd.nonce.t.size = 0;
948 session_data_cmd.hmac.t.size = 0;
949
950 if (pin.len > 0)
951 {
952 session_data_cmd.hmac.t.size = min(sizeof(session_data_cmd.hmac.t) - 2,
953 pin.len);
954 memcpy(session_data_cmd.hmac.t.buffer, pin.ptr,
955 session_data_cmd.hmac.t.size);
956 }
957 *( (uint8_t *)((void *)&session_data_cmd.sessionAttributes ) ) = 0;
958
959 if (scheme == SIGN_RSA_EMSA_PSS)
960 {
961 key_type = KEY_RSA;
962 rsa_pss_params = (rsa_pss_params_t *)params;
963 hash_alg = rsa_pss_params->hash;
964 }
965 else
966 {
967 key_type = key_type_from_signature_scheme(scheme);
968 hash_alg = hasher_from_signature_scheme(scheme, NULL);
969 }
970
971 /* Check if hash algorithm is supported by TPM */
972 alg_id = hash_alg_to_tpm_alg_id(hash_alg);
973 if (!is_supported_alg(this, alg_id))
974 {
975 DBG1(DBG_PTS, "%s %N hash algorithm not supported by TPM",
976 LABEL, hash_algorithm_short_names, hash_alg);
977 return FALSE;
978 }
979
980 /* Get public key */
981 if (!read_public(this, handle, &public))
982 {
983 return FALSE;
984 }
985
986 if (key_type == KEY_RSA && public.t.publicArea.type == TPM_ALG_RSA)
987 {
988 if (scheme == SIGN_RSA_EMSA_PSS)
989 {
990 sig_scheme.scheme = TPM_ALG_RSAPSS;
991 sig_scheme.details.rsapss.hashAlg = alg_id;
992 }
993 else
994 {
995 sig_scheme.scheme = TPM_ALG_RSASSA;
996 sig_scheme.details.rsassa.hashAlg = alg_id;
997 }
998 }
999 else if (key_type == KEY_ECDSA && public.t.publicArea.type == TPM_ALG_ECC)
1000 {
1001 sig_scheme.scheme = TPM_ALG_ECDSA;
1002 sig_scheme.details.ecdsa.hashAlg = alg_id;
1003
1004 }
1005 else
1006 {
1007 DBG1(DBG_PTS, "%s signature scheme %N not supported by TPM key",
1008 LABEL, signature_scheme_names, scheme);
1009 return FALSE;
1010 }
1011
1012 if (data.len <= MAX_DIGEST_BUFFER)
1013 {
1014 memcpy(buffer.t.buffer, data.ptr, data.len);
1015 buffer.t.size = data.len;
1016
1017 rval = Tss2_Sys_Hash(this->sys_context, 0, &buffer, alg_id, hierarchy,
1018 &hash, &validation, 0);
1019 if (rval != TPM_RC_SUCCESS)
1020 {
1021 DBG1(DBG_PTS,"%s Tss2_Sys_Hash failed: 0x%06x", LABEL, rval);
1022 return FALSE;
1023 }
1024 }
1025 else
1026 {
1027 TPMI_DH_OBJECT sequence_handle;
1028 TPM2B_AUTH null_auth;
1029
1030 null_auth.t.size = 0;
1031 rval = Tss2_Sys_HashSequenceStart(this->sys_context, 0, &null_auth,
1032 alg_id, &sequence_handle, 0);
1033 if (rval != TPM_RC_SUCCESS)
1034 {
1035 DBG1(DBG_PTS,"%s Tss2_Sys_HashSequenceStart failed: 0x%06x",
1036 LABEL, rval);
1037 return FALSE;
1038 }
1039
1040 while (data.len > 0)
1041 {
1042 buffer.t.size = min(data.len, MAX_DIGEST_BUFFER);
1043 memcpy(buffer.t.buffer, data.ptr, buffer.t.size);
1044 data.ptr += buffer.t.size;
1045 data.len -= buffer.t.size;
1046
1047 rval = Tss2_Sys_SequenceUpdate(this->sys_context, sequence_handle,
1048 &sessions_data_cmd, &buffer, 0);
1049 if (rval != TPM_RC_SUCCESS)
1050 {
1051 DBG1(DBG_PTS,"%s Tss2_Sys_SequenceUpdate failed: 0x%06x",
1052 LABEL, rval);
1053 return FALSE;
1054 }
1055 }
1056 buffer.t.size = 0;
1057
1058 rval = Tss2_Sys_SequenceComplete(this->sys_context, sequence_handle,
1059 &sessions_data_cmd, &buffer, hierarchy,
1060 &hash, &validation, 0);
1061 if (rval != TPM_RC_SUCCESS)
1062 {
1063 DBG1(DBG_PTS,"%s Tss2_Sys_SequenceComplete failed: 0x%06x",
1064 LABEL, rval);
1065 return FALSE;
1066 }
1067 }
1068
1069 rval = Tss2_Sys_Sign(this->sys_context, handle, &sessions_data_cmd, &hash,
1070 &sig_scheme, &validation, &sig, &sessions_data_rsp);
1071 if (rval != TPM_RC_SUCCESS)
1072 {
1073 DBG1(DBG_PTS,"%s Tss2_Sys_Sign failed: 0x%06x", LABEL, rval);
1074 return FALSE;
1075 }
1076
1077 /* extract signature */
1078 switch (scheme)
1079 {
1080 case SIGN_RSA_EMSA_PKCS1_SHA1:
1081 case SIGN_RSA_EMSA_PKCS1_SHA2_256:
1082 case SIGN_RSA_EMSA_PKCS1_SHA2_384:
1083 case SIGN_RSA_EMSA_PKCS1_SHA2_512:
1084 *signature = chunk_clone(
1085 chunk_create(
1086 sig.signature.rsassa.sig.t.buffer,
1087 sig.signature.rsassa.sig.t.size));
1088 break;
1089 case SIGN_RSA_EMSA_PSS:
1090 *signature = chunk_clone(
1091 chunk_create(
1092 sig.signature.rsapss.sig.t.buffer,
1093 sig.signature.rsapss.sig.t.size));
1094 break;
1095 case SIGN_ECDSA_256:
1096 case SIGN_ECDSA_384:
1097 case SIGN_ECDSA_521:
1098 *signature = chunk_cat("cc",
1099 chunk_create(
1100 sig.signature.ecdsa.signatureR.t.buffer,
1101 sig.signature.ecdsa.signatureR.t.size),
1102 chunk_create(
1103 sig.signature.ecdsa.signatureS.t.buffer,
1104 sig.signature.ecdsa.signatureS.t.size));
1105 break;
1106 case SIGN_ECDSA_WITH_SHA256_DER:
1107 case SIGN_ECDSA_WITH_SHA384_DER:
1108 case SIGN_ECDSA_WITH_SHA512_DER:
1109 *signature = asn1_wrap(ASN1_SEQUENCE, "mm",
1110 asn1_integer("c",
1111 chunk_create(
1112 sig.signature.ecdsa.signatureR.t.buffer,
1113 sig.signature.ecdsa.signatureR.t.size)),
1114 asn1_integer("c",
1115 chunk_create(
1116 sig.signature.ecdsa.signatureS.t.buffer,
1117 sig.signature.ecdsa.signatureS.t.size)));
1118 break;
1119 default:
1120 DBG1(DBG_PTS, "%s unsupported %N signature scheme",
1121 LABEL, signature_scheme_names, scheme);
1122 return FALSE;
1123 }
1124
1125 return TRUE;
1126 }
1127
1128 METHOD(tpm_tss_t, get_random, bool,
1129 private_tpm_tss_tss2_t *this, size_t bytes, uint8_t *buffer)
1130 {
1131 size_t len, random_len= sizeof(TPM2B_DIGEST)-2;
1132 TPM2B_DIGEST random = { { random_len, } };
1133 uint8_t *pos = buffer;
1134 uint32_t rval;
1135
1136 while (bytes > 0)
1137 {
1138 len = min(bytes, random_len);
1139
1140 rval = Tss2_Sys_GetRandom(this->sys_context, NULL, len, &random, NULL);
1141 if (rval != TSS2_RC_SUCCESS)
1142 {
1143 DBG1(DBG_PTS,"%s Tss2_Sys_GetRandom failed: 0x%06x", LABEL, rval);
1144 return FALSE;
1145 }
1146 memcpy(pos, random.t.buffer, random.t.size);
1147 pos += random.t.size;
1148 bytes -= random.t.size;
1149 }
1150
1151 return TRUE;
1152 }
1153
1154 METHOD(tpm_tss_t, get_data, bool,
1155 private_tpm_tss_tss2_t *this, uint32_t hierarchy, uint32_t handle,
1156 chunk_t pin, chunk_t *data)
1157 {
1158 uint16_t max_data_size, nv_size, nv_offset = 0;
1159 uint32_t rval;
1160
1161 TPMS_CAPABILITY_DATA cap_data;
1162 TPMI_YES_NO more_data;
1163 TPM2B_NAME nv_name = { { sizeof(TPM2B_NAME)-2, } };
1164 TPM2B_NV_PUBLIC nv_public = { { 0, } };
1165 TPM2B_MAX_NV_BUFFER nv_data = { { MAX_NV_BUFFER_SIZE, } };
1166 TPMS_AUTH_COMMAND session_data_cmd;
1167 TPMS_AUTH_RESPONSE session_data_rsp;
1168 TSS2_SYS_CMD_AUTHS sessions_data_cmd;
1169 TSS2_SYS_RSP_AUTHS sessions_data_rsp;
1170 TPMS_AUTH_COMMAND *session_data_cmd_array[1];
1171 TPMS_AUTH_RESPONSE *session_data_rsp_array[1];
1172
1173 /* query maximum TPM data transmission size */
1174 rval = Tss2_Sys_GetCapability(this->sys_context, 0, TPM_CAP_TPM_PROPERTIES,
1175 TPM_PT_NV_BUFFER_MAX, 1, &more_data, &cap_data, 0);
1176 if (rval != TPM_RC_SUCCESS)
1177 {
1178 DBG1(DBG_PTS,"%s Tss2_Sys_GetCapability failed for "
1179 "TPM_CAP_TPM_PROPERTIES: 0x%06x", LABEL, rval);
1180 return FALSE;
1181 }
1182 max_data_size = min(cap_data.data.tpmProperties.tpmProperty[0].value,
1183 MAX_NV_BUFFER_SIZE);
1184
1185 /* get size of NV object */
1186 rval = Tss2_Sys_NV_ReadPublic(this->sys_context, handle, 0, &nv_public,
1187 &nv_name, 0);
1188 if (rval != TPM_RC_SUCCESS)
1189 {
1190 DBG1(DBG_PTS,"%s Tss2_Sys_NV_ReadPublic failed: 0x%06x", LABEL, rval);
1191 return FALSE;
1192 }
1193 nv_size = nv_public.t.nvPublic.dataSize;
1194 *data = chunk_alloc(nv_size);
1195
1196 /*prepare NV read session */
1197 session_data_cmd_array[0] = &session_data_cmd;
1198 session_data_rsp_array[0] = &session_data_rsp;
1199
1200 sessions_data_cmd.cmdAuths = &session_data_cmd_array[0];
1201 sessions_data_rsp.rspAuths = &session_data_rsp_array[0];
1202
1203 sessions_data_cmd.cmdAuthsCount = 1;
1204 sessions_data_rsp.rspAuthsCount = 1;
1205
1206 session_data_cmd.sessionHandle = TPM_RS_PW;
1207 session_data_cmd.nonce.t.size = 0;
1208 session_data_cmd.hmac.t.size = 0;
1209
1210 if (pin.len > 0)
1211 {
1212 session_data_cmd.hmac.t.size = min(sizeof(session_data_cmd.hmac.t) - 2,
1213 pin.len);
1214 memcpy(session_data_cmd.hmac.t.buffer, pin.ptr,
1215 session_data_cmd.hmac.t.size);
1216 }
1217 *( (uint8_t *)((void *)&session_data_cmd.sessionAttributes ) ) = 0;
1218
1219 /* read NV data a maximum data size block at a time */
1220 while (nv_size > 0)
1221 {
1222 rval = Tss2_Sys_NV_Read(this->sys_context, hierarchy, handle,
1223 &sessions_data_cmd, min(nv_size, max_data_size),
1224 nv_offset, &nv_data, &sessions_data_rsp);
1225
1226 if (rval != TPM_RC_SUCCESS)
1227 {
1228 DBG1(DBG_PTS,"%s Tss2_Sys_NV_Read failed: 0x%06x", LABEL, rval);
1229 chunk_free(data);
1230 return FALSE;
1231 }
1232 memcpy(data->ptr + nv_offset, nv_data.t.buffer, nv_data.t.size);
1233 nv_offset += nv_data.t.size;
1234 nv_size -= nv_data.t.size;
1235 }
1236
1237 return TRUE;
1238 }
1239
1240 METHOD(tpm_tss_t, destroy, void,
1241 private_tpm_tss_tss2_t *this)
1242 {
1243 finalize_context(this);
1244 free(this);
1245 }
1246
1247 /**
1248 * See header
1249 */
1250 tpm_tss_t *tpm_tss_tss2_create()
1251 {
1252 private_tpm_tss_tss2_t *this;
1253 bool available;
1254
1255 INIT(this,
1256 .public = {
1257 .get_version = _get_version,
1258 .get_version_info = _get_version_info,
1259 .generate_aik = _generate_aik,
1260 .get_public = _get_public,
1261 .supported_signature_schemes = _supported_signature_schemes,
1262 .read_pcr = _read_pcr,
1263 .extend_pcr = _extend_pcr,
1264 .quote = _quote,
1265 .sign = _sign,
1266 .get_random = _get_random,
1267 .get_data = _get_data,
1268 .destroy = _destroy,
1269 },
1270 );
1271
1272 available = initialize_tcti_tabrmd_context(this);
1273 if (!available)
1274 {
1275 available = initialize_tcti_socket_context(this);
1276 }
1277 if (available)
1278 {
1279 available = initialize_sys_context(this);
1280 }
1281 DBG1(DBG_PTS, "TPM 2.0 via TSS2 v1 %savailable", available ? "" : "not ");
1282
1283 if (!available)
1284 {
1285 destroy(this);
1286 return NULL;
1287 }
1288 return &this->public;
1289 }
1290
1291 #else /* TSS_TSS2_V1 */
1292
1293 #ifndef TSS_TSS2_V2
1294 tpm_tss_t *tpm_tss_tss2_create(void)
1295 {
1296 return NULL;
1297 }
1298 #endif /* !TSS_TSS2_V2 */
1299
1300 #endif /* TSS_TSS2_V1 */
1301
1302