Annotation of embedaddon/strongswan/src/libtpmtss/tpm_tss_trousers.c, revision 1.1.1.2
1.1 misho 1: /*
1.1.1.2 ! misho 2: * Copyright (C) 2016-2020 Andreas Steffen
1.1 misho 3: * HSR Hochschule fuer Technik Rapperswil
4: *
5: * Copyright (c) 2008 Hal Finney
6: *
7: * Permission is hereby granted, free of charge, to any person obtaining a copy
8: * of this software and associated documentation files (the "Software"), to deal
9: * in the Software without restriction, including without limitation the rights
10: * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11: * copies of the Software, and to permit persons to whom the Software is
12: * furnished to do so, subject to the following conditions:
13: *
14: * The above copyright notice and this permission notice shall be included in
15: * all copies or substantial portions of the Software.
16: *
17: * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18: * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19: * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20: * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21: * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22: * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23: * THE SOFTWARE.
24: */
25:
26: #include "tpm_tss_trousers.h"
27:
28: #ifdef TSS_TROUSERS
29:
30: #ifdef _BASETSD_H_
31: /* MinGW defines _BASETSD_H_, but TSS checks for _BASETSD_H */
32: # define _BASETSD_H
33: #endif
34:
35: #include <trousers/tss.h>
36: #include <trousers/trousers.h>
37:
1.1.1.2 ! misho 38: #include <unistd.h>
! 39:
1.1 misho 40: #define LABEL "TPM 1.2 -"
41:
42: /* size in bytes of a TSS AIK public key blob */
43: #define AIK_PUBKEY_BLOB_SIZE 284
44:
45: /* maximum number of PCR registers */
46: #define PCR_NUM_MAX 24
47:
48: typedef struct private_tpm_tss_trousers_t private_tpm_tss_trousers_t;
49: typedef struct aik_t aik_t;
50:
51: /**
52: * Private data of an tpm_tss_trousers_t object.
53: */
54: struct private_tpm_tss_trousers_t {
55:
56: /**
57: * Public tpm_tss_trousers_t interface.
58: */
59: tpm_tss_trousers_t interface;
60:
61: /**
62: * TSS context
63: */
64: TSS_HCONTEXT hContext;
65:
66: /**
67: * TPM handle
68: */
69: TSS_HTPM hTPM;
70:
71: /**
72: * TPM version info
73: */
74: chunk_t version_info;
75:
76: /**
77: * List of AIKs retrievable by an object handle
78: */
79: linked_list_t *aik_list;
80:
81: };
82:
83: struct aik_t {
84: /** AIK object handle */
85: uint32_t handle;
86:
87: /** AIK private key blob */
88: chunk_t blob;
89:
90: /** AIK public key */
91: chunk_t pubkey;
92: };
93:
94: static void free_aik(aik_t *this)
95: {
96: free(this->blob.ptr);
97: free(this->pubkey.ptr);
98: free(this);
99: }
100:
101: /**
102: * Initialize TSS context
103: *
104: * TPM 1.2 Specification, Part 2 TPM Structures, 21.6 TPM_CAP_VERSION_INFO
105: *
106: * typedef struct tdTPM_VERSION {
107: * TPM_VERSION_BYTE major;
108: * TPM_VERSION_BYTE minor;
109: * BYTE revMajor;
110: * BYTE revMinor;
111: * } TPM_VERSION;
112: *
113: * typedef struct tdTPM_CAP_VERSION_INFO {
114: * TPM_STRUCTURE_TAG tag;
115: * TPM_VERSION version;
116: * UINT16 specLevel;
117: * BYTE errataRev;
118: * BYTE tpmVendorID[4];
119: * UINT16 vendorSpecificSize;
120: * [size_is(vendorSpecificSize)] BYTE* vendorSpecific;
121: * } TPM_CAP_VERSION_INFO;
122: */
123: static bool initialize_context(private_tpm_tss_trousers_t *this)
124: {
125: uint8_t *version_ptr;
126: uint32_t version_len;
127:
128: TSS_RESULT result;
129: TPM_CAP_VERSION_INFO *info;
130:
131: result = Tspi_Context_Create(&this->hContext);
132: if (result != TSS_SUCCESS)
133: {
134: DBG1(DBG_PTS, "%s could not created context: 0x%x",
135: LABEL, result);
136: return FALSE;
137: }
138:
139: result = Tspi_Context_Connect(this->hContext, NULL);
140: if (result != TSS_SUCCESS)
141: {
142: DBG1(DBG_PTS, "%s could not connect with context: 0x%x",
143: LABEL, result);
144: return FALSE;
145: }
146:
147: result = Tspi_Context_GetTpmObject (this->hContext, &this->hTPM);
148: if (result != TSS_SUCCESS)
149: {
150: DBG1(DBG_PTS, "%s could not get TPM object: 0x%x",
151: LABEL, result);
152: return FALSE;
153: }
154:
155: result = Tspi_TPM_GetCapability(this->hTPM, TSS_TPMCAP_VERSION_VAL, 0,
156: NULL, &version_len, &version_ptr);
157: if (result != TSS_SUCCESS)
158: {
159: DBG1(DBG_PTS, "%s Tspi_TPM_GetCapability failed: 0x%x",
160: LABEL, result);
161: return FALSE;
162: }
163:
164: info = (TPM_CAP_VERSION_INFO *)version_ptr;
165: DBG2(DBG_PTS, "TPM Version Info: Chip Version: %u.%u.%u.%u, "
166: "Spec Level: %u, Errata Rev: %u, Vendor ID: %.4s",
167: info->version.major, info->version.minor,
168: info->version.revMajor, info->version.revMinor,
169: untoh16(&info->specLevel), info->errataRev, info->tpmVendorID);
170:
171: this->version_info = chunk_clone(chunk_create(version_ptr, version_len));
172:
173: return TRUE;
174: }
175:
176: /**
177: * Finalize TSS context
178: */
179: static void finalize_context(private_tpm_tss_trousers_t *this)
180: {
181: if (this->hContext)
182: {
183: Tspi_Context_FreeMemory(this->hContext, NULL);
184: Tspi_Context_Close(this->hContext);
185: }
186: }
187:
188: METHOD(tpm_tss_t, get_version, tpm_version_t,
189: private_tpm_tss_trousers_t *this)
190: {
191: return TPM_VERSION_1_2;
192: }
193:
194: METHOD(tpm_tss_t, get_version_info, chunk_t,
195: private_tpm_tss_trousers_t *this)
196: {
197: return this->version_info;
198: }
199:
200: METHOD(tpm_tss_t, generate_aik, bool,
201: private_tpm_tss_trousers_t *this, chunk_t ca_modulus, chunk_t *aik_blob,
202: chunk_t *aik_pubkey, chunk_t *identity_req)
203: {
204: chunk_t aik_pubkey_blob;
205: chunk_t aik_modulus;
206: chunk_t aik_exponent;
207:
208: TSS_RESULT result;
209: TSS_HKEY hSRK;
210: TSS_HKEY hPCAKey;
211: TSS_HPOLICY hSrkPolicy;
212: TSS_HPOLICY hTPMPolicy;
213: TSS_HKEY hIdentKey;
214: TSS_UUID SRK_UUID = TSS_UUID_SRK;
215: BYTE secret[] = TSS_WELL_KNOWN_SECRET;
216: BYTE *IdentityReq;
217: UINT32 IdentityReqLen;
218: BYTE *blob;
219: UINT32 blobLen;
220:
221: /* get SRK plus SRK policy and set SRK secret */
222: result = Tspi_Context_LoadKeyByUUID(this->hContext, TSS_PS_TYPE_SYSTEM,
223: SRK_UUID, &hSRK);
224: if (result != TSS_SUCCESS)
225: {
226: DBG1(DBG_PTS, "%s Tspi_Context_LoadKeyByUUID for SRK failed: 0x%x",
227: LABEL, result);
228: return FALSE;
229: }
230: result = Tspi_GetPolicyObject(hSRK, TSS_POLICY_USAGE, &hSrkPolicy);
231: if (result != TSS_SUCCESS)
232: {
233: DBG1(DBG_PTS, "%s Tspi_GetPolicyObject or SRK failed: 0x%x ",
234: LABEL, result);
235: return FALSE;
236: }
237: result = Tspi_Policy_SetSecret(hSrkPolicy, TSS_SECRET_MODE_SHA1, 20, secret);
238: if (result != TSS_SUCCESS)
239: {
240: DBG1(DBG_PTS, "%s Tspi_Policy_SetSecret for SRK failed: 0x%x ",
241: LABEL, result);
242: return FALSE;
243: }
244:
245: /* get TPM plus TPM policy and set TPM secret */
246: result = Tspi_Context_GetTpmObject (this->hContext, &this->hTPM);
247: if (result != TSS_SUCCESS)
248: {
249: DBG1(DBG_PTS, "%s Tspi_Context_GetTpmObject failed: 0x%x",
250: LABEL, result);
251: return FALSE;
252: }
253: result = Tspi_GetPolicyObject(this->hTPM, TSS_POLICY_USAGE, &hTPMPolicy);
254: if (result != TSS_SUCCESS)
255: {
256: DBG1(DBG_PTS, "%s Tspi_GetPolicyObject for TPM failed: 0x%x",
257: LABEL, result);
258: return FALSE;
259: }
260: result = Tspi_Policy_SetSecret(hTPMPolicy, TSS_SECRET_MODE_SHA1, 20, secret);
261: if (result != TSS_SUCCESS)
262: {
263: DBG1(DBG_PTS,"%s Tspi_Policy_SetSecret for TPM failed: 0x%x",
264: LABEL, result);
265: return FALSE;
266: }
267:
268: /* create context for a 2048 bit AIK */
269: result = Tspi_Context_CreateObject(this->hContext, TSS_OBJECT_TYPE_RSAKEY,
270: TSS_KEY_TYPE_IDENTITY | TSS_KEY_SIZE_2048 |
271: TSS_KEY_VOLATILE | TSS_KEY_NOT_MIGRATABLE, &hIdentKey);
272: if (result != TSS_SUCCESS)
273: {
274: DBG1(DBG_PTS, "%s Tspi_Context_CreateObject for key failed: 0x%x",
275: LABEL, result);
276: return FALSE;
277: }
278:
279: /* create context for the Privacy CA public key and assign modulus */
280: result = Tspi_Context_CreateObject(this->hContext, TSS_OBJECT_TYPE_RSAKEY,
281: TSS_KEY_TYPE_LEGACY|TSS_KEY_SIZE_2048, &hPCAKey);
282: if (result != TSS_SUCCESS)
283: {
284: DBG1(DBG_PTS, "%s Tspi_Context_CreateObject for PCA failed: 0x%x",
285: LABEL, result);
286: return FALSE;
287: }
288: result = Tspi_SetAttribData (hPCAKey, TSS_TSPATTRIB_RSAKEY_INFO,
289: TSS_TSPATTRIB_KEYINFO_RSA_MODULUS, ca_modulus.len,
290: ca_modulus.ptr);
291: if (result != TSS_SUCCESS)
292: {
293: DBG1(DBG_PTS, "%s Tspi_SetAttribData for PCA modulus failed: 0x%x",
294: LABEL, result);
295: return FALSE;
296: }
297: result = Tspi_SetAttribUint32(hPCAKey, TSS_TSPATTRIB_KEY_INFO,
298: TSS_TSPATTRIB_KEYINFO_ENCSCHEME, TSS_ES_RSAESPKCSV15);
299: if (result != TSS_SUCCESS)
300: {
301: DBG1(DBG_PTS,"%s Tspi_SetAttribUint32 for PCA encryption scheme "
302: "failed: 0x%x", LABEL, result);
303: return FALSE;
304: }
305:
306: /* generate AIK */
307: DBG1(DBG_LIB, "Generating identity key...");
308: result = Tspi_TPM_CollateIdentityRequest(this->hTPM, hSRK, hPCAKey, 0, NULL,
309: hIdentKey, TSS_ALG_AES, &IdentityReqLen, &IdentityReq);
310: if (result != TSS_SUCCESS)
311: {
312: DBG1(DBG_PTS, "%s Tspi_TPM_CollateIdentityRequest failed: 0x%x",
313: LABEL, result);
314: return FALSE;
315: }
316: *identity_req = chunk_create(IdentityReq, IdentityReqLen);
317: DBG3(DBG_LIB, "%s Identity Request: %B", LABEL, identity_req);
318:
319: /* load identity key */
320: result = Tspi_Key_LoadKey (hIdentKey, hSRK);
321: if (result != TSS_SUCCESS)
322: {
323: DBG1(DBG_PTS, "%s Tspi_Key_LoadKey for AIK failed: 0x%x",
324: LABEL, result);
325: return FALSE;
326: }
327:
328: /* output AIK private key in TSS blob format */
329: result = Tspi_GetAttribData (hIdentKey, TSS_TSPATTRIB_KEY_BLOB,
330: TSS_TSPATTRIB_KEYBLOB_BLOB, &blobLen, &blob);
331: if (result != TSS_SUCCESS)
332: {
333: DBG1(DBG_PTS, "%s Tspi_GetAttribData for private key blob failed: 0x%x",
334: LABEL, result);
335: return FALSE;
336: }
337: *aik_blob = chunk_create(blob, blobLen);
338: DBG3(DBG_LIB, "%s AIK private key blob: %B", LABEL, aik_blob);
339:
340: /* output AIK Public Key in TSS blob format */
341: result = Tspi_GetAttribData (hIdentKey, TSS_TSPATTRIB_KEY_BLOB,
342: TSS_TSPATTRIB_KEYBLOB_PUBLIC_KEY, &blobLen, &blob);
343: if (result != TSS_SUCCESS)
344: {
345: DBG1(DBG_PTS, "%s Tspi_GetAttribData for public key blob failed: 0x%x",
346: LABEL, result);
347: return FALSE;
348: }
349: aik_pubkey_blob = chunk_create(blob, blobLen);
350: DBG3(DBG_LIB, "%s AIK public key blob: %B", LABEL, &aik_pubkey_blob);
351:
352: /* create a trusted AIK public key */
353: if (aik_pubkey_blob.len != AIK_PUBKEY_BLOB_SIZE)
354: {
355: DBG1(DBG_PTS, "%s AIK public key is not in TSS blob format",
356: LABEL);
357: return FALSE;
358: }
359: aik_modulus = chunk_skip(aik_pubkey_blob, AIK_PUBKEY_BLOB_SIZE - 256);
360: aik_exponent = chunk_from_chars(0x01, 0x00, 0x01);
361:
362: /* output subjectPublicKeyInfo encoding of AIK public key */
363: if (!lib->encoding->encode(lib->encoding, PUBKEY_SPKI_ASN1_DER, NULL,
364: aik_pubkey, CRED_PART_RSA_MODULUS, aik_modulus,
365: CRED_PART_RSA_PUB_EXP, aik_exponent, CRED_PART_END))
366: {
367: DBG1(DBG_PTS, "%s subjectPublicKeyInfo encoding of AIK key failed",
368: LABEL);
369: return FALSE;
370: }
371: return TRUE;
372: }
373:
374: METHOD(tpm_tss_t, get_public, chunk_t,
375: private_tpm_tss_trousers_t *this, uint32_t handle)
376: {
377: enumerator_t *enumerator;
378: chunk_t aik_pubkey = chunk_empty;
379: aik_t *aik;
380:
381: enumerator = this->aik_list->create_enumerator(this->aik_list);
382: while (enumerator->enumerate(enumerator, &aik))
383: {
384: if (aik->handle == handle)
385: {
386: aik_pubkey = chunk_clone(aik->pubkey);
387: break;
388: }
389: }
390: enumerator->destroy(enumerator);
391:
392: return aik_pubkey;
393: }
394:
395: METHOD(tpm_tss_t, supported_signature_schemes, enumerator_t*,
396: private_tpm_tss_trousers_t *this, uint32_t handle)
397: {
398: return enumerator_create_empty();
399: }
400:
1.1.1.2 ! misho 401: METHOD(tpm_tss_t, has_pcr_bank, bool,
! 402: private_tpm_tss_trousers_t *this, hash_algorithm_t alg)
! 403: {
! 404: return alg == HASH_SHA1;
! 405: }
! 406:
1.1 misho 407: METHOD(tpm_tss_t, read_pcr, bool,
408: private_tpm_tss_trousers_t *this, uint32_t pcr_num, chunk_t *pcr_value,
409: hash_algorithm_t alg)
410: {
411: TSS_RESULT result;
412: uint8_t *value;
413: uint32_t len;
414:
1.1.1.2 ! misho 415: if (alg != HASH_SHA1)
! 416: {
! 417: return FALSE;
! 418: }
1.1 misho 419: result = Tspi_TPM_PcrRead(this->hTPM, pcr_num, &len, &value);
420: if (result != TSS_SUCCESS)
421: {
422: DBG1(DBG_PTS, "%s Tspi_TPM_PcrRead failed: 0x%x", LABEL, result);
423: return FALSE;
424: }
425: *pcr_value = chunk_clone(chunk_create(value, len));
426:
427: return TRUE;
428: }
429:
430: METHOD(tpm_tss_t, extend_pcr, bool,
431: private_tpm_tss_trousers_t *this, uint32_t pcr_num, chunk_t *pcr_value,
432: chunk_t data, hash_algorithm_t alg)
433: {
434: TSS_RESULT result;
435: uint32_t pcr_len;
436: uint8_t *pcr_ptr;
437:
1.1.1.2 ! misho 438: if (alg != HASH_SHA1)
! 439: {
! 440: return FALSE;
! 441: }
1.1 misho 442: result = Tspi_TPM_PcrExtend(this->hTPM, pcr_num, data.len, data.ptr,
443: NULL, &pcr_len, &pcr_ptr);
444: if (result != TSS_SUCCESS)
445: {
446: DBG1(DBG_PTS, "%s Tspi_TPM_PcrExtend failed: 0x%x", LABEL, result);
447: return FALSE;
448: }
449: *pcr_value = chunk_clone(chunk_create(pcr_ptr, pcr_len));
450:
451: return TRUE;
452: }
453:
454: METHOD(tpm_tss_t, quote, bool,
455: private_tpm_tss_trousers_t *this, uint32_t aik_handle, uint32_t pcr_sel,
456: hash_algorithm_t alg, chunk_t data, tpm_quote_mode_t *quote_mode,
457: tpm_tss_quote_info_t **quote_info, chunk_t *quote_sig)
458: {
459: TSS_HKEY hAIK;
460: TSS_HKEY hSRK;
461: TSS_HPOLICY srkUsagePolicy;
462: TSS_UUID SRK_UUID = TSS_UUID_SRK;
463: TSS_HPCRS hPcrComposite;
464: TSS_VALIDATION valData;
465: TSS_RESULT result;
466: uint8_t secret[] = TSS_WELL_KNOWN_SECRET;
467: uint8_t *version_info, *comp_hash;
468: uint32_t version_info_size, pcr;
469: aik_t *aik;
470: chunk_t aik_blob = chunk_empty;
471: chunk_t quote_chunk, pcr_digest;
472: enumerator_t *enumerator;
473: bool success = FALSE;
474:
1.1.1.2 ! misho 475: if (alg != HASH_SHA1)
! 476: {
! 477: return FALSE;
! 478: }
! 479:
1.1 misho 480: /* Retrieve SRK from TPM and set the authentication to well known secret*/
481: result = Tspi_Context_LoadKeyByUUID(this->hContext, TSS_PS_TYPE_SYSTEM,
482: SRK_UUID, &hSRK);
483: if (result != TSS_SUCCESS)
484: {
485: DBG1(DBG_PTS, "%s Tspi_Context_LoadKeyByUUID for SRK failed: 0x%x",
486: LABEL, result);
487: return FALSE;
488: }
489: result = Tspi_GetPolicyObject(hSRK, TSS_POLICY_USAGE, &srkUsagePolicy);
490: if (result != TSS_SUCCESS)
491: {
492: DBG1(DBG_PTS, "%s Tspi_GetPolicyObject for SRK failed: 0x%x",
493: LABEL, result);
494: return FALSE;
495: }
496: result = Tspi_Policy_SetSecret(srkUsagePolicy, TSS_SECRET_MODE_SHA1,
497: 20, secret);
498: if (result != TSS_SUCCESS)
499: {
500: DBG1(DBG_PTS, "%s Tspi_Policy_SetSecret for SRK failed: 0x%x",
501: LABEL, result);
502: return FALSE;
503: }
504:
505: /* Retrieve AIK using its handle and load private key into TPM 1.2 */
506: enumerator = this->aik_list->create_enumerator(this->aik_list);
507: while (enumerator->enumerate(enumerator, &aik))
508: {
509: if (aik->handle == aik_handle)
510: {
511: aik_blob = aik->blob;
512: break;
513: }
514: }
515: enumerator->destroy(enumerator);
516:
517: if (aik_blob.len == 0)
518: {
519: DBG1(DBG_PTS, "%s AIK private key for handle 0x%80x not found", LABEL);
520: return FALSE;
521: }
522: result = Tspi_Context_LoadKeyByBlob(this->hContext, hSRK, aik_blob.len,
523: aik_blob.ptr, &hAIK);
524: if (result != TSS_SUCCESS)
525: {
526: DBG1(DBG_PTS, "%s Tspi_Context_LoadKeyByBlob for AIK failed: 0x%x",
527: LABEL, result);
528: return FALSE;
529: }
530:
531: /* Create PCR composite object */
532: result = Tspi_Context_CreateObject(this->hContext, TSS_OBJECT_TYPE_PCRS,
533: (*quote_mode == TPM_QUOTE) ? TSS_PCRS_STRUCT_INFO :
534: TSS_PCRS_STRUCT_INFO_SHORT,
535: &hPcrComposite);
536: if (result != TSS_SUCCESS)
537: {
538: DBG1(DBG_PTS, "%s Tspi_Context_CreateObject for pcrComposite failed: "
539: "0x%x", LABEL, result);
540: goto err1;
541: }
542:
543: /* Select PCRs */
544: for (pcr = 0; pcr < PCR_NUM_MAX; pcr++)
545: {
546: if (pcr_sel & (1 << pcr))
547: {
548: result = (*quote_mode == TPM_QUOTE) ?
549: Tspi_PcrComposite_SelectPcrIndex(hPcrComposite, pcr) :
550: Tspi_PcrComposite_SelectPcrIndexEx(hPcrComposite, pcr,
551: TSS_PCRS_DIRECTION_RELEASE);
552: if (result != TSS_SUCCESS)
553: {
554: DBG1(DBG_PTS, "%s Tspi_PcrComposite_SelectPcrIndex failed: "
555: "0x%x", LABEL, result);
556: goto err2;
557: }
558: }
559: }
560:
561: /* Set the Validation Data */
562: valData.ulExternalDataLength = data.len;
563: valData.rgbExternalData = data.ptr;
564:
565: /* TPM Quote */
566: result = (*quote_mode == TPM_QUOTE) ?
567: Tspi_TPM_Quote (this->hTPM, hAIK, hPcrComposite, &valData) :
568: Tspi_TPM_Quote2(this->hTPM, hAIK,
569: *quote_mode == TPM_QUOTE2_VERSION_INFO,
570: hPcrComposite, &valData, &version_info_size,
571: &version_info);
572: if (result != TSS_SUCCESS)
573: {
574: DBG1(DBG_PTS, "%s Tspi_TPM_Quote%s failed: 0x%x", LABEL,
575: (*quote_mode == TPM_QUOTE) ? "" : "2", result);
576: goto err2;
577: }
578:
579: if (*quote_mode == TPM_QUOTE)
580: {
581: /* TPM_Composite_Hash starts at byte 8 of TPM_Quote_Info structure */
582: comp_hash = valData.rgbData + 8;
583: }
584: else
585: {
586: /* TPM_Composite_Hash is last 20 bytes of TPM_Quote_Info2 structure */
587: comp_hash = valData.rgbData + valData.ulDataLength - version_info_size -
588: HASH_SIZE_SHA1;
589: }
590: pcr_digest = chunk_create(comp_hash, HASH_SIZE_SHA1);
591: DBG2(DBG_PTS, "PCR composite digest: %B", &pcr_digest);
592:
593: quote_chunk = chunk_create(valData.rgbData, valData.ulDataLength);
594: DBG2(DBG_PTS, "TPM Quote Info: %B", "e_chunk);
595:
596: *quote_info = tpm_tss_quote_info_create(*quote_mode, HASH_SHA1, pcr_digest);
597:
598: *quote_sig = chunk_clone(chunk_create(valData.rgbValidationData,
599: valData.ulValidationDataLength));
600: DBG2(DBG_PTS, "TPM Quote Signature: %B", quote_sig);
601:
602: success = TRUE;
603:
604: err2:
605: Tspi_Context_CloseObject(this->hContext, hPcrComposite);
606: err1:
607: Tspi_Context_CloseObject(this->hContext, hAIK);
608:
609: return success;
610: }
611:
612: METHOD(tpm_tss_t, sign, bool,
613: private_tpm_tss_trousers_t *this, uint32_t hierarchy, uint32_t handle,
614: signature_scheme_t scheme, void *params, chunk_t data, chunk_t pin,
615: chunk_t *signature)
616: {
617: return FALSE;
618: }
619:
620: METHOD(tpm_tss_t, get_random, bool,
621: private_tpm_tss_trousers_t *this, size_t bytes, uint8_t *buffer)
622: {
623: return FALSE;
624: }
625:
626: METHOD(tpm_tss_t, get_data, bool,
627: private_tpm_tss_trousers_t *this, uint32_t hierarchy, uint32_t handle,
628: chunk_t pin, chunk_t *data)
629: {
630: return FALSE;
631: }
632:
1.1.1.2 ! misho 633: METHOD(tpm_tss_t, get_event_digest, bool,
! 634: private_tpm_tss_trousers_t *this, int fd, hash_algorithm_t alg,
! 635: chunk_t *digest)
! 636: {
! 637: if (alg != HASH_SHA1)
! 638: {
! 639: return FALSE;
! 640: }
! 641: *digest = chunk_alloc(HASH_SIZE_SHA1);
! 642:
! 643: return read(fd, digest->ptr, digest->len) == digest->len;
! 644: }
! 645:
1.1 misho 646: METHOD(tpm_tss_t, destroy, void,
647: private_tpm_tss_trousers_t *this)
648: {
649: finalize_context(this);
650: this->aik_list->destroy_function(this->aik_list, (void*)free_aik);
651: free(this->version_info.ptr);
652: free(this);
653: }
654:
655: METHOD(tpm_tss_trousers_t, load_aik, void,
656: private_tpm_tss_trousers_t *this, chunk_t blob, chunk_t pubkey,
657: uint32_t handle)
658: {
659: aik_t *item;
660:
661: INIT(item,
662: .handle = handle,
663: .blob = blob,
664: .pubkey = pubkey,
665: );
666:
667: this->aik_list->insert_last(this->aik_list, item);
668: }
669:
670: /**
671: * See header
672: */
673: tpm_tss_t *tpm_tss_trousers_create()
674: {
675: private_tpm_tss_trousers_t *this;
676: bool available;
677:
678: INIT(this,
679: .interface = {
680: .public = {
681: .get_version = _get_version,
682: .get_version_info = _get_version_info,
683: .generate_aik = _generate_aik,
684: .get_public = _get_public,
685: .supported_signature_schemes = _supported_signature_schemes,
1.1.1.2 ! misho 686: .has_pcr_bank = _has_pcr_bank,
1.1 misho 687: .read_pcr = _read_pcr,
688: .extend_pcr = _extend_pcr,
689: .quote = _quote,
690: .sign = _sign,
691: .get_random = _get_random,
692: .get_data = _get_data,
1.1.1.2 ! misho 693: .get_event_digest = _get_event_digest,
1.1 misho 694: .destroy = _destroy,
695: },
696: .load_aik = _load_aik,
697: },
698: .aik_list = linked_list_create(),
699: );
700:
701: available = initialize_context(this);
702: DBG1(DBG_PTS, "TPM 1.2 via TrouSerS %savailable", available ? "" : "not ");
703:
704: if (!available)
705: {
706: destroy(this);
707: return NULL;
708: }
709: return &this->interface.public;
710: }
711:
712: #else /* TSS_TROUSERS */
713:
714: tpm_tss_t *tpm_tss_trousers_create()
715: {
716: return NULL;
717: }
718:
719: #endif /* TSS_TROUSERS */
720:
721:
722:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>