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