Implemented TCG PTS Simple Evidence Final and Request File Measurement attributes
[strongswan.git] / src / libimcv / tcg / tcg_pts_attr_simple_evid_final.c
1 /*
2 * Copyright (C) 2011 Sansar Choinyambuu
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 "tcg_pts_attr_simple_evid_final.h"
17
18 #include <pa_tnc/pa_tnc_msg.h>
19 #include <bio/bio_writer.h>
20 #include <bio/bio_reader.h>
21 #include <debug.h>
22
23 typedef struct private_tcg_pts_attr_simple_evid_final_t private_tcg_pts_attr_simple_evid_final_t;
24
25 /**
26 * Simple Evidence Final (see section 3.15.2 of PTS Protocol: Binding to TNC IF-M Specification)
27 *
28 * 1 2 3
29 * 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
30 *
31 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
32 * | Flags | Reserved | Optional Composite Hash Alg |
33 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
34 * | Optional TPM PCR Composite Length |
35 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
36 * ~ Optional TPM PCR Composite (Variable Length) ~
37 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
38 * | Optional TPM Quote Signature Length |
39 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
40 * ~ Optional TPM Quote Signature (Variable Length) ~
41 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
42 * ~ Optional Evidence Signature (Variable Length) ~
43 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
44 */
45
46 #define PTS_SIMPLE_EVID_FINAL_SIZE 4
47 #define PTS_SIMPLE_EVID_FINAL_RESERVED 0x00
48
49 /**
50 * Private data of an tcg_pts_attr_simple_evid_final_t object.
51 */
52 struct private_tcg_pts_attr_simple_evid_final_t {
53
54 /**
55 * Public members of tcg_pts_attr_simple_evid_final_t
56 */
57 tcg_pts_attr_simple_evid_final_t public;
58
59 /**
60 * Attribute vendor ID
61 */
62 pen_t vendor_id;
63
64 /**
65 * Attribute type
66 */
67 u_int32_t type;
68
69 /**
70 * Attribute value
71 */
72 chunk_t value;
73
74 /**
75 * Noskip flag
76 */
77 bool noskip_flag;
78
79 /**
80 * Set of flags for Simple Evidence Final
81 */
82 pts_attr_simple_evid_final_flag_t flags;
83
84 /**
85 * Optional Composite Hash Algorithm
86 */
87 pts_attr_meas_algorithms_t comp_hash_algorithm;
88
89 /**
90 * Optional TPM PCR Composite
91 */
92 chunk_t pcr_comp;
93
94 /**
95 * Optional TPM Quote Signature
96 */
97 chunk_t tpm_quote_sign;
98
99 /**
100 * Optional Evidence Signature
101 */
102 chunk_t evid_sign;
103
104 };
105
106 METHOD(pa_tnc_attr_t, get_vendor_id, pen_t,
107 private_tcg_pts_attr_simple_evid_final_t *this)
108 {
109 return this->vendor_id;
110 }
111
112 METHOD(pa_tnc_attr_t, get_type, u_int32_t,
113 private_tcg_pts_attr_simple_evid_final_t *this)
114 {
115 return this->type;
116 }
117
118 METHOD(pa_tnc_attr_t, get_value, chunk_t,
119 private_tcg_pts_attr_simple_evid_final_t *this)
120 {
121 return this->value;
122 }
123
124 METHOD(pa_tnc_attr_t, get_noskip_flag, bool,
125 private_tcg_pts_attr_simple_evid_final_t *this)
126 {
127 return this->noskip_flag;
128 }
129
130 METHOD(pa_tnc_attr_t, set_noskip_flag,void,
131 private_tcg_pts_attr_simple_evid_final_t *this, bool noskip)
132 {
133 this->noskip_flag = noskip;
134 }
135
136 METHOD(pa_tnc_attr_t, build, void,
137 private_tcg_pts_attr_simple_evid_final_t *this)
138 {
139 bio_writer_t *writer;
140 u_int8_t flags = 0;
141 u_int16_t algorithm = 0;
142
143 writer = bio_writer_create(PTS_SIMPLE_EVID_FINAL_SIZE);
144
145 /* Determine the flags to set*/
146 if(this->flags & PTS_SIMPLE_EVID_FINAL_FLAG_TPM_QUOTE_INFO) flags += 64;
147 else if(this->flags & PTS_SIMPLE_EVID_FINAL_FLAG_TPM_QUOTE_INFO2) flags += 128;
148 else if(this->flags & PTS_SIMPLE_EVID_FINAL_FLAG_TPM_QUOTE_INFO2_CAP_VER) flags += 192;
149
150 if(this->flags & PTS_SIMPLE_EVID_FINAL_FLAG_EVID) flags += 32;
151
152 writer->write_uint8(writer, flags);
153 writer->write_uint8(writer, PTS_SIMPLE_EVID_FINAL_RESERVED);
154
155 /* Determine the hash algorithm to set*/
156 if(this->comp_hash_algorithm & PTS_MEAS_ALGO_SHA384) algorithm = 8192;
157 else if(this->comp_hash_algorithm & PTS_MEAS_ALGO_SHA256) algorithm = 16384;
158 else if(this->comp_hash_algorithm & PTS_MEAS_ALGO_SHA1) algorithm = 32768;
159 writer->write_uint16(writer, algorithm);
160
161 /* Optional fields */
162 if(this->pcr_comp.ptr && this->pcr_comp.len > 0)
163 {
164 writer->write_uint32 (writer, this->pcr_comp.len);
165 writer->write_data (writer, this->pcr_comp);
166 }
167 if(this->tpm_quote_sign.ptr && this->tpm_quote_sign.len > 0)
168 {
169 writer->write_uint32 (writer, this->tpm_quote_sign.len);
170 writer->write_data (writer, this->tpm_quote_sign);
171 }
172 if(this->evid_sign.ptr && this->evid_sign.len > 0)
173 {
174 writer->write_data (writer, this->evid_sign);
175 }
176
177 this->value = chunk_clone(writer->get_buf(writer));
178 writer->destroy(writer);
179 }
180
181 METHOD(pa_tnc_attr_t, process, status_t,
182 private_tcg_pts_attr_simple_evid_final_t *this, u_int32_t *offset)
183 {
184 bio_reader_t *reader;
185 u_int8_t flags;
186 u_int8_t reserved;
187 u_int16_t algorithm;
188
189 if (this->value.len < PTS_SIMPLE_EVID_FINAL_SIZE)
190 {
191 DBG1(DBG_TNC, "insufficient data for Simple Evidence Final");
192 *offset = 0;
193 return FAILED;
194 }
195 reader = bio_reader_create(this->value);
196
197 reader->read_uint8(reader, &flags);
198
199 /* Determine the flags to set*/
200 if(!((flags >> 7) & 1) && !((flags >> 6) & 1))
201 this->flags |= PTS_SIMPLE_EVID_FINAL_FLAG_NO;
202 else if(!((flags >> 7) & 1) && ((flags >> 6) & 1))
203 this->flags |= PTS_SIMPLE_EVID_FINAL_FLAG_TPM_QUOTE_INFO;
204 else if(((flags >> 7) & 1) && !((flags >> 6) & 1))
205 this->flags |= PTS_SIMPLE_EVID_FINAL_FLAG_TPM_QUOTE_INFO2;
206 else if(((flags >> 7) & 1) && ((flags >> 6) & 1))
207 this->flags |= PTS_SIMPLE_EVID_FINAL_FLAG_TPM_QUOTE_INFO2_CAP_VER;
208
209 if((flags >> 5) & 1) this->flags |= PTS_SIMPLE_EVID_FINAL_FLAG_EVID;
210
211 reader->read_uint8(reader, &reserved);
212 reader->read_uint16(reader, &algorithm);
213
214 if((algorithm >> 13) & 1) this->comp_hash_algorithm = PTS_MEAS_ALGO_SHA384;
215 else if((algorithm >> 14) & 1) this->comp_hash_algorithm = PTS_MEAS_ALGO_SHA256;
216 else if((algorithm >> 15) & 1) this->comp_hash_algorithm = PTS_MEAS_ALGO_SHA1;
217
218 /* Optional TPM PCR Composite field is included */
219 if(!(this->flags & PTS_SIMPLE_EVID_FINAL_FLAG_NO))
220 {
221 u_int32_t pcr_comp_len;
222 u_int32_t tpm_quote_sign_len;
223 reader->read_uint32(reader, &pcr_comp_len);
224 reader->read_data(reader, pcr_comp_len, &this->pcr_comp);
225 reader->read_uint32(reader, &tpm_quote_sign_len);
226 reader->read_data(reader, tpm_quote_sign_len, &this->tpm_quote_sign);
227 }
228
229 /* Optional Evidence Signature field is included */
230 if(this->flags & PTS_SIMPLE_EVID_FINAL_FLAG_EVID)
231 {
232 u_int32_t evid_sign_len = reader->remaining(reader);
233 reader->read_data(reader, evid_sign_len, &this->evid_sign);
234 }
235
236 reader->destroy(reader);
237 return SUCCESS;
238 }
239
240 METHOD(pa_tnc_attr_t, destroy, void,
241 private_tcg_pts_attr_simple_evid_final_t *this)
242 {
243 free(this->value.ptr);
244 free(this->pcr_comp.ptr);
245 free(this->tpm_quote_sign.ptr);
246 free(this->evid_sign.ptr);
247 free(this);
248 }
249
250 METHOD(tcg_pts_attr_simple_evid_final_t, get_flags, pts_attr_simple_evid_final_flag_t,
251 private_tcg_pts_attr_simple_evid_final_t *this)
252 {
253 return this->flags;
254 }
255
256 METHOD(tcg_pts_attr_simple_evid_final_t, set_flags, void,
257 private_tcg_pts_attr_simple_evid_final_t *this, pts_attr_simple_evid_final_flag_t flags)
258 {
259 this->flags = flags;
260 }
261
262 METHOD(tcg_pts_attr_simple_evid_final_t, get_comp_hash_algorithm, pts_attr_meas_algorithms_t,
263 private_tcg_pts_attr_simple_evid_final_t *this)
264 {
265 return this->comp_hash_algorithm;
266 }
267
268 METHOD(tcg_pts_attr_simple_evid_final_t, set_comp_hash_algorithm, void,
269 private_tcg_pts_attr_simple_evid_final_t *this, pts_attr_meas_algorithms_t comp_hash_algorithm)
270 {
271 this->comp_hash_algorithm = comp_hash_algorithm;
272 }
273
274 METHOD(tcg_pts_attr_simple_evid_final_t, get_comp_pcr_len, u_int32_t,
275 private_tcg_pts_attr_simple_evid_final_t *this)
276 {
277 if(this->pcr_comp.ptr && this->pcr_comp.len > 0)
278 return this->pcr_comp.len;
279 else return 0;
280 }
281
282 METHOD(tcg_pts_attr_simple_evid_final_t, get_pcr_comp, chunk_t,
283 private_tcg_pts_attr_simple_evid_final_t *this)
284 {
285 return this->pcr_comp;
286 }
287
288 METHOD(tcg_pts_attr_simple_evid_final_t, set_pcr_comp, void,
289 private_tcg_pts_attr_simple_evid_final_t *this, chunk_t pcr_comp)
290 {
291 this->pcr_comp = pcr_comp;
292 }
293
294 METHOD(tcg_pts_attr_simple_evid_final_t, get_tpm_quote_sign_len, u_int32_t,
295 private_tcg_pts_attr_simple_evid_final_t *this)
296 {
297 if(this->tpm_quote_sign.ptr && this->tpm_quote_sign.len > 0)
298 return this->tpm_quote_sign.len;
299 else return 0;
300 }
301
302 METHOD(tcg_pts_attr_simple_evid_final_t, get_tpm_quote_sign, chunk_t,
303 private_tcg_pts_attr_simple_evid_final_t *this)
304 {
305 return this->tpm_quote_sign;
306 }
307
308 METHOD(tcg_pts_attr_simple_evid_final_t, set_tpm_quote_sign, void,
309 private_tcg_pts_attr_simple_evid_final_t *this, chunk_t tpm_quote_sign)
310 {
311 this->tpm_quote_sign = tpm_quote_sign;
312 }
313
314 METHOD(tcg_pts_attr_simple_evid_final_t, get_evid_sign, chunk_t,
315 private_tcg_pts_attr_simple_evid_final_t *this)
316 {
317 return this->evid_sign;
318 }
319
320 METHOD(tcg_pts_attr_simple_evid_final_t, set_evid_sign, void,
321 private_tcg_pts_attr_simple_evid_final_t *this, chunk_t evid_sign)
322 {
323 this->evid_sign = evid_sign;
324 }
325
326 /**
327 * Described in header.
328 */
329 pa_tnc_attr_t *tcg_pts_attr_simple_evid_final_create(
330 pts_attr_simple_evid_final_flag_t flags,
331 pts_attr_meas_algorithms_t comp_hash_algorithm,
332 chunk_t pcr_comp,
333 chunk_t tpm_quote_sign,
334 chunk_t evid_sign)
335 {
336 private_tcg_pts_attr_simple_evid_final_t *this;
337
338 INIT(this,
339 .public = {
340 .pa_tnc_attribute = {
341 .get_vendor_id = _get_vendor_id,
342 .get_type = _get_type,
343 .get_value = _get_value,
344 .get_noskip_flag = _get_noskip_flag,
345 .set_noskip_flag = _set_noskip_flag,
346 .build = _build,
347 .process = _process,
348 .destroy = _destroy,
349 },
350 .get_flags= _get_flags,
351 .set_flags= _set_flags,
352 .get_comp_hash_algorithm = _get_comp_hash_algorithm,
353 .set_comp_hash_algorithm = _set_comp_hash_algorithm,
354 .get_comp_pcr_len = _get_comp_pcr_len,
355 .get_pcr_comp = _get_pcr_comp,
356 .set_pcr_comp = _set_pcr_comp,
357 .get_tpm_quote_sign_len = _get_tpm_quote_sign_len,
358 .get_tpm_quote_sign = _get_tpm_quote_sign,
359 .set_tpm_quote_sign = _set_tpm_quote_sign,
360 .get_evid_sign = _get_evid_sign,
361 .set_evid_sign = _set_evid_sign,
362 },
363 .vendor_id = PEN_TCG,
364 .type = TCG_PTS_SIMPLE_EVID_FINAL,
365 .flags = flags,
366 .comp_hash_algorithm = comp_hash_algorithm,
367 .pcr_comp = pcr_comp,
368 .tpm_quote_sign = tpm_quote_sign,
369 .evid_sign = evid_sign,
370 );
371
372 return &this->public.pa_tnc_attribute;
373 }
374
375
376 /**
377 * Described in header.
378 */
379 pa_tnc_attr_t *tcg_pts_attr_simple_evid_final_create_from_data(chunk_t data)
380 {
381 private_tcg_pts_attr_simple_evid_final_t *this;
382
383 INIT(this,
384 .public = {
385 .pa_tnc_attribute = {
386 .get_vendor_id = _get_vendor_id,
387 .get_type = _get_type,
388 .get_value = _get_value,
389 .get_noskip_flag = _get_noskip_flag,
390 .set_noskip_flag = _set_noskip_flag,
391 .build = _build,
392 .process = _process,
393 .destroy = _destroy,
394 },
395 .get_flags= _get_flags,
396 .set_flags= _set_flags,
397 .get_comp_hash_algorithm = _get_comp_hash_algorithm,
398 .set_comp_hash_algorithm = _set_comp_hash_algorithm,
399 .get_comp_pcr_len = _get_comp_pcr_len,
400 .get_pcr_comp = _get_pcr_comp,
401 .set_pcr_comp = _set_pcr_comp,
402 .get_tpm_quote_sign_len = _get_tpm_quote_sign_len,
403 .get_tpm_quote_sign = _get_tpm_quote_sign,
404 .set_tpm_quote_sign = _set_tpm_quote_sign,
405 .get_evid_sign = _get_evid_sign,
406 .set_evid_sign = _set_evid_sign,
407 },
408 .vendor_id = PEN_TCG,
409 .type = TCG_PTS_SIMPLE_EVID_FINAL,
410 .value = chunk_clone(data),
411 );
412
413 return &this->public.pa_tnc_attribute;
414 }