Annotation of embedaddon/strongswan/src/libtpmtss/tpm_tss_quote_info.c, revision 1.1.1.1

1.1       misho       1: /*
                      2:  * Copyright (C) 2016 Andreas Steffen
                      3:  * HSR Hochschule fuer Technik Rapperswil
                      4:  *
                      5:  * This program is free software; you can redistribute it and/or modify it
                      6:  * under the terms of the GNU General Public License as published by the
                      7:  * Free Software Foundation; either version 2 of the License, or (at your
                      8:  * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
                      9:  *
                     10:  * This program is distributed in the hope that it will be useful, but
                     11:  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
                     12:  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
                     13:  * for more details.
                     14:  */
                     15: 
                     16: #include <tpm_tss_quote_info.h>
                     17: 
                     18: #include <bio/bio_writer.h>
                     19: 
                     20: #ifndef TPM_TAG_QUOTE_INFO2
                     21: #define TPM_TAG_QUOTE_INFO2 0x0036
                     22: #endif
                     23: #ifndef TPM_LOC_ZERO
                     24: #define TPM_LOC_ZERO 0x01
                     25: #endif
                     26: 
                     27: typedef struct private_tpm_tss_quote_info_t private_tpm_tss_quote_info_t;
                     28: 
                     29: /**
                     30:  * Private data of an tpm_tss_quote_info_t object.
                     31:  */
                     32: struct private_tpm_tss_quote_info_t {
                     33: 
                     34:        /**
                     35:         * Public tpm_tss_quote_info_t interface.
                     36:         */
                     37:        tpm_tss_quote_info_t public;
                     38: 
                     39:        /**
                     40:         * TPM Quote Mode
                     41:         */
                     42:        tpm_quote_mode_t quote_mode;
                     43: 
                     44:        /**
                     45:         * TPM Qualified Signer
                     46:         */
                     47:        chunk_t qualified_signer;
                     48: 
                     49:        /**
                     50:         * TPM Clock Info
                     51:         */
                     52:        chunk_t clock_info;
                     53: 
                     54:        /**
                     55:         * TPM Version Info
                     56:         */
                     57:        chunk_t version_info;
                     58: 
                     59:        /**
                     60:         * TPM PCR Selection
                     61:         */
                     62:        chunk_t pcr_select;
                     63: 
                     64:        /**
                     65:         * TPM PCR Composite Hash
                     66:         */
                     67:        chunk_t pcr_digest;
                     68: 
                     69:        /**
                     70:         * TPM PCR Composite Hash algorithm
                     71:         */
                     72:        hash_algorithm_t pcr_digest_alg;
                     73: 
                     74:        /**
                     75:         * Reference count
                     76:         */
                     77:        refcount_t ref;
                     78: 
                     79: };
                     80: 
                     81: METHOD(tpm_tss_quote_info_t, get_quote_mode, tpm_quote_mode_t,
                     82:        private_tpm_tss_quote_info_t *this)
                     83: {
                     84:        return this->quote_mode;
                     85: }
                     86: 
                     87: METHOD(tpm_tss_quote_info_t, get_pcr_digest_alg, hash_algorithm_t,
                     88:        private_tpm_tss_quote_info_t *this)
                     89: {
                     90:        return this->pcr_digest_alg;
                     91: }
                     92: 
                     93: METHOD(tpm_tss_quote_info_t, get_pcr_digest, chunk_t,
                     94:        private_tpm_tss_quote_info_t *this)
                     95: {
                     96:        return this->pcr_digest;
                     97: }
                     98: 
                     99: METHOD(tpm_tss_quote_info_t, get_quote, bool,
                    100:        private_tpm_tss_quote_info_t *this, chunk_t nonce,
                    101:        tpm_tss_pcr_composite_t *composite, chunk_t *quoted)
                    102: {
                    103:        chunk_t pcr_composite, pcr_digest;
                    104:        bio_writer_t *writer;
                    105:        hasher_t *hasher;
                    106:        bool equal_digests;
                    107: 
                    108:        /* Construct PCR Composite */
                    109:        writer = bio_writer_create(32);
                    110: 
                    111:        switch (this->quote_mode)
                    112:        {
                    113:                case TPM_QUOTE:
                    114:                case TPM_QUOTE2:
                    115:                case TPM_QUOTE2_VERSION_INFO:
                    116:                        writer->write_data16(writer, composite->pcr_select);
                    117:                        writer->write_data32(writer, composite->pcr_composite);
                    118: 
                    119:                        break;
                    120:                case TPM_QUOTE_TPM2:
                    121:                        writer->write_data(writer, composite->pcr_composite);
                    122:                        break;
                    123:                case TPM_QUOTE_NONE:
                    124:                        break;
                    125:        }
                    126: 
                    127:        pcr_composite = writer->extract_buf(writer);
                    128:        writer->destroy(writer);
                    129: 
                    130:        DBG2(DBG_PTS, "constructed PCR Composite: %B", &pcr_composite);
                    131: 
                    132:        /* Compute PCR Composite Hash */
                    133:        hasher = lib->crypto->create_hasher(lib->crypto, this->pcr_digest_alg);
                    134:        if (!hasher || !hasher->allocate_hash(hasher, pcr_composite, &pcr_digest))
                    135:        {
                    136:                DESTROY_IF(hasher);
                    137:                chunk_free(&pcr_composite);
                    138:                return FALSE;
                    139:        }
                    140:        hasher->destroy(hasher);
                    141:        chunk_free(&pcr_composite);
                    142: 
                    143:        DBG2(DBG_PTS, "constructed PCR Composite digest: %B", &pcr_digest);
                    144: 
                    145:        equal_digests = chunk_equals(pcr_digest, this->pcr_digest);
                    146: 
                    147:        /* Construct Quote Info */
                    148:        writer = bio_writer_create(32);
                    149: 
                    150:        switch (this->quote_mode)
                    151:        {
                    152:                case TPM_QUOTE:
                    153:                        /* Version number */
                    154:                        writer->write_data(writer, chunk_from_chars(1, 1, 0, 0));
                    155: 
                    156:                        /* Magic QUOT value */
                    157:                        writer->write_data(writer, chunk_from_str("QUOT"));
                    158: 
                    159:                        /* PCR Composite Hash */
                    160:                        writer->write_data(writer, pcr_digest);
                    161: 
                    162:                        /* Secret assessment value 20 bytes (nonce) */
                    163:                        writer->write_data(writer, nonce);
                    164:                        break;
                    165:                case TPM_QUOTE2:
                    166:                case TPM_QUOTE2_VERSION_INFO:
                    167:                        /* TPM Structure Tag */
                    168:                        writer->write_uint16(writer, TPM_TAG_QUOTE_INFO2);
                    169: 
                    170:                        /* Magic QUT2 value */
                    171:                        writer->write_data(writer, chunk_from_str("QUT2"));
                    172: 
                    173:                        /* Secret assessment value 20 bytes (nonce) */
                    174:                        writer->write_data(writer, nonce);
                    175: 
                    176:                        /* PCR selection */
                    177:                        writer->write_data16(writer, composite->pcr_select);
                    178: 
                    179:                        /* TPM Locality Selection */
                    180:                        writer->write_uint8(writer, TPM_LOC_ZERO);
                    181: 
                    182:                        /* PCR Composite Hash */
                    183:                        writer->write_data(writer, pcr_digest);
                    184: 
                    185:                        if (this->quote_mode == TPM_QUOTE2_VERSION_INFO)
                    186:                        {
                    187:                                /* TPM version Info */
                    188:                                writer->write_data(writer, this->version_info);
                    189:                        }
                    190:                        break;
                    191:                case TPM_QUOTE_TPM2:
                    192:                        /* Magic */
                    193:                        writer->write_data(writer, chunk_from_chars(0xff,0x54,0x43,0x47));
                    194: 
                    195:                        /* Type */
                    196:                        writer->write_uint16(writer, 0x8018);
                    197: 
                    198:                        /* Qualified Signer */
                    199:                        writer->write_data16(writer, this->qualified_signer);
                    200: 
                    201:                        /* Extra Data */
                    202:                        writer->write_data16(writer, nonce);
                    203: 
                    204:                        /* Clock Info */
                    205:                        writer->write_data(writer, this->clock_info);
                    206: 
                    207:                        /* Firmware Version */
                    208:                        writer->write_data(writer, this->version_info);
                    209: 
                    210:                        /* PCR Selection */
                    211:                        writer->write_data(writer, this->pcr_select);
                    212: 
                    213:                        /* PCR Composite Hash */
                    214:                        writer->write_data16(writer, pcr_digest);
                    215:                        break;
                    216:                case TPM_QUOTE_NONE:
                    217:                        break;
                    218:        }
                    219:        chunk_free(&pcr_digest);
                    220:        *quoted = writer->extract_buf(writer);
                    221:        writer->destroy(writer);
                    222: 
                    223:        DBG2(DBG_PTS, "constructed TPM Quote Info: %B", quoted);
                    224: 
                    225:        if (!equal_digests)
                    226:        {
                    227:                DBG1(DBG_IMV, "received PCR Composite digest does not match "
                    228:                                          "constructed one");
                    229:                chunk_free(quoted);
                    230:        }
                    231:        return equal_digests;
                    232: }
                    233: 
                    234: METHOD(tpm_tss_quote_info_t, set_version_info, void,
                    235:        private_tpm_tss_quote_info_t *this, chunk_t version_info)
                    236: {
                    237:        chunk_free(&this->version_info);
                    238:        this->version_info = chunk_clone(version_info);
                    239: }
                    240: 
                    241: METHOD(tpm_tss_quote_info_t, get_version_info, chunk_t,
                    242:        private_tpm_tss_quote_info_t *this)
                    243: {
                    244:        return this->version_info;
                    245: }
                    246: 
                    247: METHOD(tpm_tss_quote_info_t, set_tpm2_info, void,
                    248:        private_tpm_tss_quote_info_t *this, chunk_t qualified_signer,
                    249:        chunk_t clock_info, chunk_t pcr_select)
                    250: {
                    251:        chunk_free(&this->qualified_signer);
                    252:        this->qualified_signer = chunk_clone(qualified_signer);
                    253: 
                    254:        chunk_free(&this->clock_info);
                    255:        this->clock_info = chunk_clone(clock_info);
                    256: 
                    257:        chunk_free(&this->pcr_select);
                    258:        this->pcr_select = chunk_clone(pcr_select);
                    259: }
                    260: 
                    261: METHOD(tpm_tss_quote_info_t, get_tpm2_info, void,
                    262:        private_tpm_tss_quote_info_t *this, chunk_t *qualified_signer,
                    263:        chunk_t *clock_info, chunk_t *pcr_select)
                    264: {
                    265:        if (qualified_signer)
                    266:        {
                    267:                *qualified_signer = this->qualified_signer;
                    268:        }
                    269:        if (clock_info)
                    270:        {
                    271:                *clock_info = this->clock_info;
                    272:        }
                    273:        if (pcr_select)
                    274:        {
                    275:                *pcr_select = this->pcr_select;
                    276:        }
                    277: }
                    278: 
                    279: METHOD(tpm_tss_quote_info_t, get_ref, tpm_tss_quote_info_t*,
                    280:        private_tpm_tss_quote_info_t *this)
                    281: {
                    282:        ref_get(&this->ref);
                    283: 
                    284:        return &this->public;
                    285: }
                    286: 
                    287: METHOD(tpm_tss_quote_info_t, destroy, void,
                    288:        private_tpm_tss_quote_info_t *this)
                    289: {
                    290:        if (ref_put(&this->ref))
                    291:        {
                    292:                chunk_free(&this->qualified_signer);
                    293:                chunk_free(&this->clock_info);
                    294:                chunk_free(&this->version_info);
                    295:                chunk_free(&this->pcr_select);
                    296:                chunk_free(&this->pcr_digest);
                    297:                free(this);
                    298:        }
                    299: }
                    300: 
                    301: /**
                    302:  * See header
                    303:  */
                    304: tpm_tss_quote_info_t *tpm_tss_quote_info_create(tpm_quote_mode_t quote_mode,
                    305:                                                hash_algorithm_t pcr_digest_alg, chunk_t pcr_digest)
                    306: 
                    307: {
                    308:        private_tpm_tss_quote_info_t *this;
                    309: 
                    310:        INIT(this,
                    311:                .public = {
                    312:                        .get_quote_mode = _get_quote_mode,
                    313:                        .get_pcr_digest_alg = _get_pcr_digest_alg,
                    314:                        .get_pcr_digest = _get_pcr_digest,
                    315:                        .get_quote = _get_quote,
                    316:                        .set_version_info = _set_version_info,
                    317:                        .get_version_info = _get_version_info,
                    318:                        .set_tpm2_info = _set_tpm2_info,
                    319:                        .get_tpm2_info = _get_tpm2_info,
                    320:                        .get_ref = _get_ref,
                    321:                        .destroy = _destroy,
                    322:                },
                    323:                .quote_mode = quote_mode,
                    324:                .pcr_digest_alg = pcr_digest_alg,
                    325:                .pcr_digest = chunk_clone(pcr_digest),
                    326:                .ref = 1,
                    327:        );
                    328: 
                    329:        return &this->public;
                    330: }

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