shortened some type names and enforced encoding rules
[strongswan.git] / src / libimcv / tcg / tcg_pts_attr_meas_algo_selection.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_meas_algo_selection.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_meas_algo_selection_t private_tcg_pts_attr_meas_algo_selection_t;
24
25 /**
26 * PTS Measurement Algorithm Selection
27 * see section 3.9.2 of PTS Protocol: Binding to TNC IF-M Specification
28 *
29 * 1 2 3
30 * 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
31 *
32 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
33 * | Reserved | Hash Algorithm Set |
34 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
35 *
36 */
37
38 /**
39 * Diffie-Hellman Hash Algorithm Values (see section 3.8.5 of PTS Protocol: Binding to TNC IF-M Specification)
40 *
41 * 1
42 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
43 *
44 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
45 * |1|2|3|R|R|R|R|R|R|R|R|R|R|R|R|R|
46 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
47 *
48 */
49
50 #define PTS_MEAS_ALGO_SEL_SIZE 4
51 #define PTS_MEAS_ALGO_SEL_RESERVED 0x00
52
53 /**
54 * Private data of an tcg_pts_attr_meas_algo_selection_t object.
55 */
56 struct private_tcg_pts_attr_meas_algo_selection_t {
57
58 /**
59 * Public members of tcg_pts_attr_meas_algo_selection_t
60 */
61 tcg_pts_attr_meas_algo_selection_t public;
62
63 /**
64 * Attribute vendor ID
65 */
66 pen_t vendor_id;
67
68 /**
69 * Attribute type
70 */
71 u_int32_t type;
72
73 /**
74 * Attribute value
75 */
76 chunk_t value;
77
78 /**
79 * Noskip flag
80 */
81 bool noskip_flag;
82
83 /**
84 * A Selected Measurement Algorithm
85 */
86 pts_meas_algorithms_t algorithm;
87
88 };
89
90 METHOD(pa_tnc_attr_t, get_vendor_id, pen_t,
91 private_tcg_pts_attr_meas_algo_selection_t *this)
92 {
93 return this->vendor_id;
94 }
95
96 METHOD(pa_tnc_attr_t, get_type, u_int32_t,
97 private_tcg_pts_attr_meas_algo_selection_t *this)
98 {
99 return this->type;
100 }
101
102 METHOD(pa_tnc_attr_t, get_value, chunk_t,
103 private_tcg_pts_attr_meas_algo_selection_t *this)
104 {
105 return this->value;
106 }
107
108 METHOD(pa_tnc_attr_t, get_noskip_flag, bool,
109 private_tcg_pts_attr_meas_algo_selection_t *this)
110 {
111 return this->noskip_flag;
112 }
113
114 METHOD(pa_tnc_attr_t, set_noskip_flag,void,
115 private_tcg_pts_attr_meas_algo_selection_t *this, bool noskip)
116 {
117 this->noskip_flag = noskip;
118 }
119
120 METHOD(pa_tnc_attr_t, build, void,
121 private_tcg_pts_attr_meas_algo_selection_t *this)
122 {
123 bio_writer_t *writer;
124 u_int16_t algorithm = 0;
125
126 writer = bio_writer_create(PTS_MEAS_ALGO_SEL_SIZE);
127 writer->write_uint16 (writer, PTS_MEAS_ALGO_SEL_RESERVED);
128
129 /* Determine the hash algorithm to set*/
130 if (this->algorithm & PTS_MEAS_ALGO_SHA384)
131 {
132 algorithm = 8192;
133 }
134 else if (this->algorithm & PTS_MEAS_ALGO_SHA256)
135 {
136 algorithm = 16384;
137 }
138 else if (this->algorithm & PTS_MEAS_ALGO_SHA1)
139 {
140 algorithm = 32768;
141 }
142 writer->write_uint16(writer, algorithm);
143
144 this->value = chunk_clone(writer->get_buf(writer));
145 writer->destroy(writer);
146 }
147
148 METHOD(pa_tnc_attr_t, process, status_t,
149 private_tcg_pts_attr_meas_algo_selection_t *this, u_int32_t *offset)
150 {
151 bio_reader_t *reader;
152 u_int16_t reserved;
153 u_int16_t algorithm;
154
155 if (this->value.len < PTS_MEAS_ALGO_SEL_SIZE)
156 {
157 DBG1(DBG_TNC, "insufficient data for PTS Measurement Algorithm Selection");
158 *offset = 0;
159 return FAILED;
160 }
161 reader = bio_reader_create(this->value);
162 reader->read_uint16 (reader, &reserved);
163 reader->read_uint16(reader, &algorithm);
164
165 if ((algorithm >> 13) & 1)
166 {
167 this->algorithm = PTS_MEAS_ALGO_SHA384;
168 }
169 else if ((algorithm >> 14) & 1)
170 {
171 this->algorithm = PTS_MEAS_ALGO_SHA256;
172 }
173 else if ((algorithm >> 15) & 1)
174 {
175 this->algorithm = PTS_MEAS_ALGO_SHA1;
176 }
177
178 reader->destroy(reader);
179
180 return SUCCESS;
181 }
182
183 METHOD(pa_tnc_attr_t, destroy, void,
184 private_tcg_pts_attr_meas_algo_selection_t *this)
185 {
186 free(this->value.ptr);
187 free(this);
188 }
189
190 METHOD(tcg_pts_attr_meas_algo_selection_t, get_algorithm, pts_meas_algorithms_t,
191 private_tcg_pts_attr_meas_algo_selection_t *this)
192 {
193 return this->algorithm;
194 }
195
196 METHOD(tcg_pts_attr_meas_algo_selection_t, set_algorithm, void,
197 private_tcg_pts_attr_meas_algo_selection_t *this,
198 pts_meas_algorithms_t algorithm)
199 {
200 this->algorithm = algorithm;
201 }
202
203 /**
204 * Described in header.
205 */
206 pa_tnc_attr_t *tcg_pts_attr_meas_algo_selection_create(pts_meas_algorithms_t algorithm)
207 {
208 private_tcg_pts_attr_meas_algo_selection_t *this;
209
210 INIT(this,
211 .public = {
212 .pa_tnc_attribute = {
213 .get_vendor_id = _get_vendor_id,
214 .get_type = _get_type,
215 .get_value = _get_value,
216 .get_noskip_flag = _get_noskip_flag,
217 .set_noskip_flag = _set_noskip_flag,
218 .build = _build,
219 .process = _process,
220 .destroy = _destroy,
221 },
222 .get_algorithm = _get_algorithm,
223 .set_algorithm = _set_algorithm,
224 },
225 .vendor_id = PEN_TCG,
226 .type = TCG_PTS_MEAS_ALGO_SELECTION,
227 .algorithm = algorithm,
228 );
229
230 return &this->public.pa_tnc_attribute;
231 }
232
233
234 /**
235 * Described in header.
236 */
237 pa_tnc_attr_t *tcg_pts_attr_meas_algo_selection_create_from_data(chunk_t data)
238 {
239 private_tcg_pts_attr_meas_algo_selection_t *this;
240
241 INIT(this,
242 .public = {
243 .pa_tnc_attribute = {
244 .get_vendor_id = _get_vendor_id,
245 .get_type = _get_type,
246 .get_value = _get_value,
247 .get_noskip_flag = _get_noskip_flag,
248 .set_noskip_flag = _set_noskip_flag,
249 .build = _build,
250 .process = _process,
251 .destroy = _destroy,
252 },
253 .get_algorithm = _get_algorithm,
254 .set_algorithm = _set_algorithm,
255 },
256 .vendor_id = PEN_TCG,
257 .type = TCG_PTS_MEAS_ALGO_SELECTION,
258 .value = chunk_clone(data),
259 );
260
261 return &this->public.pa_tnc_attribute;
262 }