2 * Copyright (C) 2011 Andreas Steffen
4 * HSR Hochschule fuer Technik Rapperswil
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 #include "ita_comp_tboot.h"
18 #include "ita_comp_func_name.h"
20 #include "pts/components/pts_component.h"
25 typedef struct pts_ita_comp_tboot_t pts_ita_comp_tboot_t
;
28 * Private data of a pts_ita_comp_tboot_t object.
31 struct pts_ita_comp_tboot_t
{
34 * Public pts_component_t interface.
36 pts_component_t
public;
39 * Component Functional Name
41 pts_comp_func_name_t
*name
;
49 * Extended PCR last handled
51 u_int32_t extended_pcr
;
54 * Time of TBOOT measurement
56 time_t measurement_time
;
60 METHOD(pts_component_t
, get_comp_func_name
, pts_comp_func_name_t
*,
61 pts_ita_comp_tboot_t
*this)
66 METHOD(pts_component_t
, get_evidence_flags
, u_int8_t
,
67 pts_ita_comp_tboot_t
*this)
69 return PTS_REQ_FUNC_COMP_EVID_PCR
;
72 METHOD(pts_component_t
, get_depth
, u_int32_t
,
73 pts_ita_comp_tboot_t
*this)
78 METHOD(pts_component_t
, measure
, status_t
,
79 pts_ita_comp_tboot_t
*this, pts_t
*pts
, pts_comp_evidence_t
**evidence
)
81 pts_comp_evidence_t
*evid
;
82 char *meas_hex
, *pcr_before_hex
, *pcr_after_hex
;
83 chunk_t measurement
, pcr_before
, pcr_after
;
84 pts_pcr_transform_t pcr_transform
;
85 pts_meas_algorithms_t hash_algo
;
87 switch (this->extended_pcr
)
90 /* dummy data since currently the TBOOT log is not retrieved */
91 time(&this->measurement_time
);
92 meas_hex
= lib
->settings
->get_str(lib
->settings
,
93 "libimcv.plugins.imc-attestation.pcr17_meas", NULL
);
94 pcr_before_hex
= lib
->settings
->get_str(lib
->settings
,
95 "libimcv.plugins.imc-attestation.pcr17_before", NULL
);
96 pcr_after_hex
= lib
->settings
->get_str(lib
->settings
,
97 "libimcv.plugins.imc-attestation.pcr17_after", NULL
);
98 this->extended_pcr
= PCR_TBOOT_POLICY
;
100 case PCR_TBOOT_POLICY
:
101 /* dummy data since currently the TBOOT log is not retrieved */
102 meas_hex
= lib
->settings
->get_str(lib
->settings
,
103 "libimcv.plugins.imc-attestation.pcr18_meas", NULL
);
104 pcr_before_hex
= lib
->settings
->get_str(lib
->settings
,
105 "libimcv.plugins.imc-attestation.pcr18_before", NULL
);
106 pcr_after_hex
= lib
->settings
->get_str(lib
->settings
,
107 "libimcv.plugins.imc-attestation.pcr18_after", NULL
);
108 this->extended_pcr
= PCR_TBOOT_MLE
;
114 hash_algo
= pts
->get_meas_algorithm(pts
);
117 case PTS_MEAS_ALGO_SHA1
:
118 pcr_transform
= PTS_PCR_TRANSFORM_MATCH
;
119 case PTS_MEAS_ALGO_SHA256
:
120 case PTS_MEAS_ALGO_SHA384
:
121 pcr_transform
= PTS_PCR_TRANSFORM_LONG
;
122 case PTS_MEAS_ALGO_NONE
:
124 pcr_transform
= PTS_PCR_TRANSFORM_NO
;
127 measurement
= chunk_from_hex(
128 chunk_create(meas_hex
, strlen(meas_hex
)), NULL
);
129 pcr_before
= chunk_from_hex(
130 chunk_create(pcr_before_hex
, strlen(pcr_before_hex
)), NULL
);
131 pcr_after
= chunk_from_hex(
132 chunk_create(pcr_after_hex
, strlen(pcr_after_hex
)), NULL
);
134 evid
= *evidence
= pts_comp_evidence_create(this->name
->clone(this->name
),
135 this->depth
, this->extended_pcr
,
136 hash_algo
, pcr_transform
,
137 this->measurement_time
, measurement
);
138 evid
->set_pcr_info(evid
, pcr_before
, pcr_after
);
142 return (this->extended_pcr
== PCR_TBOOT_MLE
) ? SUCCESS
: NEED_MORE
;
145 METHOD(pts_component_t
, verify
, status_t
,
146 pts_ita_comp_tboot_t
*this, pts_t
*pts
, pts_database_t
*pts_db
,
147 pts_comp_evidence_t
*evidence
)
150 u_int32_t extended_pcr
;
151 pts_meas_algorithms_t algo
;
152 pts_pcr_transform_t transform
;
153 time_t measurement_time
;
154 chunk_t measurement
, pcr_before
, pcr_after
;
155 enumerator_t
*enumerator
;
160 platform_info
= pts
->get_platform_info(pts
);
161 if (!pts_db
|| !platform_info
)
163 DBG1(DBG_PTS
, "%s%s%s not available",
164 (pts_db
) ?
"" : "pts database",
165 (!pts_db
&& !platform_info
) ?
"and" : "",
166 (platform_info
) ?
"" : "platform info");
170 switch (this->extended_pcr
)
173 this->extended_pcr
= PCR_TBOOT_POLICY
;
174 file
= "tboot_pcr17";
176 case PCR_TBOOT_POLICY
:
177 this->extended_pcr
= PCR_TBOOT_MLE
;
178 file
= "tboot_pcr18";
184 measurement
= evidence
->get_measurement(evidence
, &extended_pcr
,
185 &algo
, &transform
, &measurement_time
);
186 if (extended_pcr
!= this->extended_pcr
)
191 /* check measurement in database */
192 enumerator
= pts_db
->create_comp_hash_enumerator(pts_db
, file
,
193 platform_info
, this->name
, TRUSTED_HASH_ALGO
);
194 if (!enumerator
->enumerate(enumerator
, &hash
))
196 DBG1(DBG_PTS
, "No Measurement found in database for component:%s ,"
197 " on platform: %s with hashing algorithm: %N",
198 file
, platform_info
, pts_meas_algorithm_names
, TRUSTED_HASH_ALGO
);
200 enumerator
->destroy(enumerator
);
202 enumerator
= pts_db
->create_comp_hash_enumerator(pts_db
, file
,
203 platform_info
, this->name
, TRUSTED_HASH_ALGO
);
204 while (enumerator
->enumerate(enumerator
, &hash
))
206 if (!chunk_equals(hash
, measurement
))
208 DBG1(DBG_PTS
, "Incorrect TBOOT component measurement for PCR %d. "
209 "Expected: %#B, Received: %#B",
210 this->extended_pcr
, &hash
, &measurement
);
215 DBG3(DBG_PTS
, "Matching TBOOT component measurement for PCR %d",
220 enumerator
->destroy(enumerator
);
222 has_pcr_info
= evidence
->get_pcr_info(evidence
, &pcr_before
, &pcr_after
);
225 if (!pts
->add_pcr(pts
, extended_pcr
, pcr_before
, pcr_after
))
231 return (this->extended_pcr
== PCR_TBOOT_MLE
) ? SUCCESS
: NEED_MORE
;
234 METHOD(pts_component_t
, destroy
, void,
235 pts_ita_comp_tboot_t
*this)
237 this->name
->destroy(this->name
);
244 pts_component_t
*pts_ita_comp_tboot_create(u_int8_t qualifier
, u_int32_t depth
)
246 pts_ita_comp_tboot_t
*this;
250 .get_comp_func_name
= _get_comp_func_name
,
251 .get_evidence_flags
= _get_evidence_flags
,
252 .get_depth
= _get_depth
,
257 .name
= pts_comp_func_name_create(PEN_ITA
, PTS_ITA_COMP_FUNC_NAME_TBOOT
,
262 return &this->public;