Annotation of embedaddon/strongswan/src/libtpmtss/tpm_tss_tss2_v1.c, revision 1.1.1.2

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

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>