Annotation of embedaddon/strongswan/src/libtpmtss/tpm_tss_quote_info.c, revision 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>