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