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>