Annotation of embedaddon/strongswan/src/libtpmtss/tpm_tss_trousers.c, revision 1.1.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", &quote_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>