Branch data Line data Source code
1 : : /**
2 : : * Copyright Notice:
3 : : * Copyright 2021-2026 DMTF. All rights reserved.
4 : : * License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/libspdm/blob/main/LICENSE.md
5 : : **/
6 : :
7 : : #include "internal/libspdm_requester_lib.h"
8 : :
9 : : #if LIBSPDM_ENABLE_CAPABILITY_MEAS_CAP
10 : :
11 : 24 : bool libspdm_verify_measurement_signature(libspdm_context_t *spdm_context,
12 : : libspdm_session_info_t *session_info,
13 : : uint8_t slot_id,
14 : : const void *sign_data,
15 : : size_t sign_data_size)
16 : : {
17 : : bool result;
18 : : void *context;
19 : : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
20 : : libspdm_l1l2_managed_buffer_t l1l2;
21 : : uint8_t *l1l2_buffer;
22 : : size_t l1l2_buffer_size;
23 : : const uint8_t *cert_chain_data;
24 : : size_t cert_chain_data_size;
25 : : const uint8_t *cert_buffer;
26 : : size_t cert_buffer_size;
27 : : #else
28 : : uint8_t l1l2_hash[LIBSPDM_MAX_HASH_SIZE];
29 : : size_t l1l2_hash_size;
30 : : #endif
31 : :
32 [ + + - + ]: 24 : LIBSPDM_ASSERT((slot_id < SPDM_MAX_SLOT_COUNT) || (slot_id == 0xF));
33 : :
34 : : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
35 : : result = libspdm_calculate_l1l2(spdm_context, session_info, &l1l2);
36 : : l1l2_buffer = libspdm_get_managed_buffer(&l1l2);
37 : : l1l2_buffer_size = libspdm_get_managed_buffer_size(&l1l2);
38 : : #else
39 : 24 : l1l2_hash_size = sizeof(l1l2_hash);
40 : 24 : result = libspdm_calculate_l1l2_hash(spdm_context, session_info, &l1l2_hash_size, l1l2_hash);
41 : : #endif
42 : :
43 : 24 : libspdm_reset_message_m(spdm_context, session_info);
44 [ - + ]: 24 : if (!result) {
45 : 0 : return false;
46 : : }
47 : :
48 [ + + ]: 24 : if (slot_id == 0xF) {
49 [ - + ]: 1 : if (spdm_context->connection_info.algorithm.pqc_asym_algo != 0) {
50 : 0 : result = libspdm_pqc_asym_get_public_key_from_der(
51 : : spdm_context->connection_info.algorithm.pqc_asym_algo,
52 : 0 : spdm_context->local_context.peer_public_key_provision,
53 : : spdm_context->local_context.peer_public_key_provision_size,
54 : : &context);
55 : : } else {
56 : 1 : result = libspdm_asym_get_public_key_from_der(
57 : : spdm_context->connection_info.algorithm.base_asym_algo,
58 : 1 : spdm_context->local_context.peer_public_key_provision,
59 : : spdm_context->local_context.peer_public_key_provision_size,
60 : : &context);
61 : : }
62 [ - + ]: 1 : if (!result) {
63 : 0 : return false;
64 : : }
65 : : } else {
66 : : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
67 : : libspdm_get_peer_cert_chain_data(
68 : : spdm_context, slot_id, (const void **)&cert_chain_data, &cert_chain_data_size);
69 : :
70 : : /* Get leaf cert from cert chain*/
71 : : result = libspdm_x509_get_cert_from_cert_chain(cert_chain_data,
72 : : cert_chain_data_size, -1,
73 : : &cert_buffer, &cert_buffer_size);
74 : : if (!result) {
75 : : return false;
76 : : }
77 : :
78 : : if (spdm_context->connection_info.algorithm.pqc_asym_algo != 0) {
79 : : result = libspdm_pqc_asym_get_public_key_from_x509(
80 : : spdm_context->connection_info.algorithm.pqc_asym_algo,
81 : : cert_buffer, cert_buffer_size, &context);
82 : : } else {
83 : : result = libspdm_asym_get_public_key_from_x509(
84 : : spdm_context->connection_info.algorithm.base_asym_algo,
85 : : cert_buffer, cert_buffer_size, &context);
86 : : }
87 : : if (!result) {
88 : : return false;
89 : : }
90 : : #else
91 : 23 : context = spdm_context->connection_info.peer_used_cert_chain[slot_id].leaf_cert_public_key;
92 [ - + ]: 23 : LIBSPDM_ASSERT(context != NULL);
93 : : #endif
94 : : }
95 : :
96 : : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
97 : : if (spdm_context->connection_info.algorithm.pqc_asym_algo != 0) {
98 : : result = libspdm_pqc_asym_verify(
99 : : spdm_context->connection_info.version, SPDM_MEASUREMENTS,
100 : : spdm_context->connection_info.algorithm.pqc_asym_algo,
101 : : spdm_context->connection_info.algorithm.base_hash_algo,
102 : : context, l1l2_buffer, l1l2_buffer_size, sign_data, sign_data_size);
103 : : libspdm_pqc_asym_free(spdm_context->connection_info.algorithm.pqc_asym_algo, context);
104 : : } else {
105 : : result = libspdm_asym_verify_ex(
106 : : spdm_context->connection_info.version, SPDM_MEASUREMENTS,
107 : : spdm_context->connection_info.algorithm.base_asym_algo,
108 : : spdm_context->connection_info.algorithm.base_hash_algo,
109 : : context, l1l2_buffer, l1l2_buffer_size, sign_data, sign_data_size,
110 : : &spdm_context->spdm_10_11_verify_signature_endian);
111 : : libspdm_asym_free(spdm_context->connection_info.algorithm.base_asym_algo, context);
112 : : }
113 : : #else
114 [ - + ]: 24 : if (spdm_context->connection_info.algorithm.pqc_asym_algo != 0) {
115 : 0 : result = libspdm_pqc_asym_verify_hash(
116 : 0 : spdm_context->connection_info.version, SPDM_MEASUREMENTS,
117 : : spdm_context->connection_info.algorithm.pqc_asym_algo,
118 : : spdm_context->connection_info.algorithm.base_hash_algo,
119 : : context, l1l2_hash, l1l2_hash_size, sign_data, sign_data_size);
120 [ # # ]: 0 : if (slot_id == 0xF) {
121 : 0 : libspdm_pqc_asym_free(spdm_context->connection_info.algorithm.pqc_asym_algo, context);
122 : : }
123 : : } else {
124 : 24 : result = libspdm_asym_verify_hash_ex(
125 : 24 : spdm_context->connection_info.version, SPDM_MEASUREMENTS,
126 : : spdm_context->connection_info.algorithm.base_asym_algo,
127 : : spdm_context->connection_info.algorithm.base_hash_algo,
128 : : context, l1l2_hash, l1l2_hash_size, sign_data, sign_data_size,
129 : : &spdm_context->spdm_10_11_verify_signature_endian);
130 [ + + ]: 24 : if (slot_id == 0xF) {
131 : 1 : libspdm_asym_free(spdm_context->connection_info.algorithm.base_asym_algo, context);
132 : : }
133 : : }
134 : : #endif
135 [ + + ]: 24 : if (!result) {
136 : 9 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_ERROR, "!!! verify_measurement_signature - FAIL !!!\n"));
137 : 9 : return false;
138 : : }
139 : :
140 : 15 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "!!! verify_measurement_signature - PASS !!!\n"));
141 : 15 : return true;
142 : : }
143 : :
144 : : /**
145 : : * This function sends GET_MEASUREMENTS to get measurements from the device.
146 : : * If the signature is requested this function verifies the signature of the measurement.
147 : : *
148 : : * @param spdm_context A pointer to the SPDM context.
149 : : * @param session_id Indicates if it is a secured message protected via SPDM session.
150 : : * If session_id is NULL, it is a normal message.
151 : : * If session_id is not NULL, it is a secured message.
152 : : * @param request_attribute The request attribute of the request message.
153 : : * @param measurement_operation The measurement operation of the request message.
154 : : * @param slot_id_param The number of slot for the certificate chain.
155 : : * @param requester_context If not NULL, a buffer to hold the requester context (8 bytes).
156 : : * It is used only if the negotiated version >= 1.3.
157 : : * @param content_changed The measurement content changed output param.
158 : : * @param number_of_blocks The number of blocks of the measurement record.
159 : : * @param measurement_record_length On input, indicate the size in bytes of the destination buffer
160 : : * to store the measurement record.
161 : : * On output, indicate the size in bytes of the measurement record.
162 : : * @param measurement_record A pointer to a destination buffer to store the measurement record.
163 : : * @param requester_nonce_in If not NULL, a buffer that holds the requester nonce (32 bytes)
164 : : * @param requester_nonce If not NULL, a buffer to hold the requester nonce (32 bytes).
165 : : * @param responder_nonce If not NULL, a buffer to hold the responder nonce (32 bytes).
166 : : *
167 : : **/
168 : 311 : static libspdm_return_t libspdm_try_get_measurement(libspdm_context_t *spdm_context,
169 : : const uint32_t *session_id,
170 : : uint8_t request_attribute,
171 : : uint8_t measurement_operation,
172 : : uint8_t slot_id_param,
173 : : const void *requester_context,
174 : : uint8_t *content_changed,
175 : : uint8_t *number_of_blocks,
176 : : uint32_t *measurement_record_length,
177 : : void *measurement_record,
178 : : const void *requester_nonce_in,
179 : : void *requester_nonce,
180 : : void *responder_nonce,
181 : : void *opaque_data,
182 : : size_t *opaque_data_size)
183 : : {
184 : : bool result;
185 : : libspdm_return_t status;
186 : : spdm_get_measurements_request_t *spdm_request;
187 : : size_t spdm_request_size;
188 : : spdm_measurements_response_t *spdm_response;
189 : : size_t spdm_response_size;
190 : : uint32_t measurement_record_data_length;
191 : : uint8_t *measurement_record_data;
192 : : spdm_measurement_block_common_header_t *measurement_block_header;
193 : : uint32_t measurement_block_size;
194 : : uint8_t measurement_block_count;
195 : : uint8_t *ptr;
196 : : void *nonce;
197 : : uint16_t opaque_length;
198 : : void *signature;
199 : : size_t signature_size;
200 : : libspdm_session_info_t *session_info;
201 : : libspdm_session_state_t session_state;
202 : : uint8_t *message;
203 : : size_t message_size;
204 : : size_t transport_header_size;
205 : :
206 : : /* -=[Check Parameters Phase]=- */
207 [ + + - + ]: 311 : LIBSPDM_ASSERT((slot_id_param < SPDM_MAX_SLOT_COUNT) || (slot_id_param == 0xF));
208 [ + + - + ]: 311 : LIBSPDM_ASSERT((slot_id_param != 0xf) ||
209 : : (spdm_context->local_context.peer_public_key_provision_size != 0));
210 : :
211 : : /* -=[Verify State Phase]=- */
212 [ + + ]: 311 : if (!libspdm_is_capabilities_flag_supported(
213 : : spdm_context, true, 0,
214 : : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MEAS_CAP)) {
215 : 1 : return LIBSPDM_STATUS_UNSUPPORTED_CAP;
216 : : }
217 : :
218 [ - + ]: 310 : LIBSPDM_ASSERT(spdm_context->local_context.algorithm.measurement_spec != 0);
219 : :
220 [ + + ]: 310 : if (spdm_context->connection_info.connection_state < LIBSPDM_CONNECTION_STATE_NEGOTIATED) {
221 : 2 : return LIBSPDM_STATUS_INVALID_STATE_LOCAL;
222 : : }
223 : :
224 [ + + ]: 308 : if (session_id == NULL) {
225 : 306 : session_info = NULL;
226 : : } else {
227 : 2 : session_info = libspdm_get_session_info_via_session_id(spdm_context, *session_id);
228 [ - + ]: 2 : if (session_info == NULL) {
229 : 0 : return LIBSPDM_STATUS_INVALID_STATE_LOCAL;
230 : : }
231 : 2 : session_state = libspdm_secured_message_get_session_state(
232 : : session_info->secured_message_context);
233 [ - + ]: 2 : if (session_state != LIBSPDM_SESSION_STATE_ESTABLISHED) {
234 : 0 : return LIBSPDM_STATUS_INVALID_STATE_LOCAL;
235 : : }
236 : : }
237 : :
238 [ + + ]: 308 : if (libspdm_is_capabilities_flag_supported(
239 : : spdm_context, true, 0,
240 : 3 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MEAS_CAP_NO_SIG) &&
241 [ + + ]: 3 : ((request_attribute & SPDM_GET_MEASUREMENTS_REQUEST_ATTRIBUTES_GENERATE_SIGNATURE) != 0)) {
242 : 1 : return LIBSPDM_STATUS_INVALID_PARAMETER;
243 : : }
244 : :
245 [ + + ]: 307 : if ((request_attribute & SPDM_GET_MEASUREMENTS_REQUEST_ATTRIBUTES_GENERATE_SIGNATURE) != 0) {
246 [ - + ]: 76 : if (spdm_context->connection_info.algorithm.pqc_asym_algo != 0) {
247 : 0 : signature_size = libspdm_get_pqc_asym_signature_size(
248 : : spdm_context->connection_info.algorithm.pqc_asym_algo);
249 : : } else {
250 : 76 : signature_size = libspdm_get_asym_signature_size(
251 : : spdm_context->connection_info.algorithm.base_asym_algo);
252 : : }
253 : : } else {
254 : 231 : signature_size = 0;
255 : : }
256 : :
257 : 307 : libspdm_reset_message_buffer_via_request_code(spdm_context, NULL, SPDM_GET_MEASUREMENTS);
258 : :
259 : : /* -=[Construct Request Phase]=- */
260 : 307 : transport_header_size = spdm_context->local_context.capability.transport_header_size;
261 : 307 : status = libspdm_acquire_sender_buffer (spdm_context, &message_size, (void **)&message);
262 [ + + ]: 307 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
263 : 1 : return status;
264 : : }
265 [ - + ]: 306 : LIBSPDM_ASSERT (message_size >= transport_header_size +
266 : : spdm_context->local_context.capability.transport_tail_size);
267 : 306 : spdm_request = (void *)(message + transport_header_size);
268 : 306 : spdm_request_size = message_size - transport_header_size -
269 : 306 : spdm_context->local_context.capability.transport_tail_size;
270 : :
271 [ - + ]: 306 : LIBSPDM_ASSERT (spdm_request_size >= sizeof(spdm_request->header));
272 : 306 : spdm_request->header.spdm_version = libspdm_get_connection_version (spdm_context);
273 : 306 : spdm_request->header.request_response_code = SPDM_GET_MEASUREMENTS;
274 : 306 : spdm_request->header.param1 = request_attribute;
275 : 306 : spdm_request->header.param2 = measurement_operation;
276 [ + + ]: 306 : if ((request_attribute & SPDM_GET_MEASUREMENTS_REQUEST_ATTRIBUTES_GENERATE_SIGNATURE) != 0) {
277 [ - + ]: 76 : if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_13) {
278 [ # # ]: 0 : LIBSPDM_ASSERT (spdm_request_size >= sizeof(spdm_get_measurements_request_t) +
279 : : SPDM_REQ_CONTEXT_SIZE);
280 : 0 : spdm_request_size = sizeof(spdm_get_measurements_request_t) + SPDM_REQ_CONTEXT_SIZE;
281 [ + - ]: 76 : } else if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_11) {
282 [ - + ]: 76 : LIBSPDM_ASSERT (spdm_request_size >= sizeof(spdm_get_measurements_request_t));
283 : 76 : spdm_request_size = sizeof(spdm_get_measurements_request_t);
284 : : } else {
285 [ # # ]: 0 : LIBSPDM_ASSERT (spdm_request_size >= sizeof(spdm_get_measurements_request_t) -
286 : : sizeof(spdm_request->slot_id_param));
287 : 0 : spdm_request_size = sizeof(spdm_get_measurements_request_t) -
288 : : sizeof(spdm_request->slot_id_param);
289 : : }
290 : :
291 [ + + ]: 76 : if (requester_nonce_in == NULL) {
292 [ - + ]: 74 : if (!libspdm_get_random_number(SPDM_NONCE_SIZE, spdm_request->nonce)) {
293 : 0 : libspdm_release_sender_buffer (spdm_context);
294 : 0 : return LIBSPDM_STATUS_LOW_ENTROPY;
295 : : }
296 : : } else {
297 : 2 : libspdm_copy_mem(spdm_request->nonce, sizeof(spdm_request->nonce),
298 : : requester_nonce_in, SPDM_NONCE_SIZE);
299 : : }
300 : 76 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "RequesterNonce - "));
301 : 76 : LIBSPDM_INTERNAL_DUMP_DATA(spdm_request->nonce, SPDM_NONCE_SIZE);
302 : 76 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "\n"));
303 : 76 : spdm_request->slot_id_param = slot_id_param;
304 : :
305 [ + + ]: 76 : if (requester_nonce != NULL) {
306 : 2 : libspdm_copy_mem(requester_nonce, SPDM_NONCE_SIZE,
307 : 2 : spdm_request->nonce, SPDM_NONCE_SIZE);
308 : : }
309 : : } else {
310 [ + + ]: 230 : if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_13) {
311 [ - + ]: 2 : LIBSPDM_ASSERT (spdm_request_size >= sizeof(spdm_request->header) +
312 : : SPDM_REQ_CONTEXT_SIZE);
313 : 2 : spdm_request_size = sizeof(spdm_request->header) + SPDM_REQ_CONTEXT_SIZE;
314 : : } else {
315 : 228 : spdm_request_size = sizeof(spdm_request->header);
316 : : }
317 : :
318 [ - + ]: 230 : if (requester_nonce != NULL) {
319 : 0 : libspdm_zero_mem (requester_nonce, SPDM_NONCE_SIZE);
320 : : }
321 : : }
322 [ + + ]: 306 : if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_13) {
323 [ - + ]: 2 : if (requester_context == NULL) {
324 : 0 : libspdm_zero_mem((uint8_t *)spdm_request + spdm_request_size - SPDM_REQ_CONTEXT_SIZE,
325 : : SPDM_REQ_CONTEXT_SIZE);
326 : : } else {
327 : 2 : libspdm_copy_mem((uint8_t *)spdm_request + spdm_request_size - SPDM_REQ_CONTEXT_SIZE,
328 : : SPDM_REQ_CONTEXT_SIZE,
329 : : requester_context, SPDM_REQ_CONTEXT_SIZE);
330 : : }
331 : 2 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "RequesterContext - "));
332 : 2 : LIBSPDM_INTERNAL_DUMP_DATA((uint8_t *)spdm_request + spdm_request_size -
333 : : SPDM_REQ_CONTEXT_SIZE,
334 : : SPDM_REQ_CONTEXT_SIZE);
335 : 2 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "\n"));
336 : : }
337 : :
338 : : /* -=[Send Request Phase]=- */
339 : 306 : status = libspdm_send_spdm_request(spdm_context, session_id, spdm_request_size, spdm_request);
340 [ + + ]: 306 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
341 : 2 : libspdm_release_sender_buffer (spdm_context);
342 : 2 : return status;
343 : : }
344 : 304 : libspdm_release_sender_buffer (spdm_context);
345 : 304 : spdm_request = (void *)spdm_context->last_spdm_request;
346 : :
347 : : /* -=[Receive Response Phase]=- */
348 : 304 : status = libspdm_acquire_receiver_buffer (spdm_context, &message_size, (void **)&message);
349 [ + + ]: 304 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
350 : 1 : return status;
351 : : }
352 [ - + ]: 303 : LIBSPDM_ASSERT (message_size >= transport_header_size);
353 : 303 : spdm_response = (void *)(message);
354 : 303 : spdm_response_size = message_size;
355 : :
356 : 303 : status = libspdm_receive_spdm_response(
357 : : spdm_context, session_id, &spdm_response_size, (void **)&spdm_response);
358 [ + + ]: 303 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
359 : 1 : goto receive_done;
360 : : }
361 : :
362 : : /* -=[Validate Response Phase]=- */
363 [ - + ]: 302 : if (spdm_response_size < sizeof(spdm_message_header_t)) {
364 : 0 : status = LIBSPDM_STATUS_INVALID_MSG_SIZE;
365 : 0 : goto receive_done;
366 : : }
367 [ + + ]: 302 : if (spdm_response->header.request_response_code == SPDM_ERROR) {
368 : 46 : status = libspdm_handle_error_response_main(
369 : : spdm_context, session_id,
370 : : &spdm_response_size, (void **)&spdm_response,
371 : : SPDM_GET_MEASUREMENTS, SPDM_MEASUREMENTS);
372 [ + + ]: 46 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
373 : 45 : goto receive_done;
374 : : }
375 [ + + ]: 256 : } else if (spdm_response->header.request_response_code != SPDM_MEASUREMENTS) {
376 : 2 : status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
377 : 2 : goto receive_done;
378 : : }
379 [ + + ]: 255 : if (spdm_response->header.spdm_version != spdm_request->header.spdm_version) {
380 : 1 : status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
381 : 1 : goto receive_done;
382 : : }
383 [ - + ]: 254 : if (spdm_response_size < sizeof(spdm_measurements_response_t)) {
384 : 0 : status = LIBSPDM_STATUS_INVALID_MSG_SIZE;
385 : 0 : goto receive_done;
386 : : }
387 [ + + ]: 254 : if (measurement_operation ==
388 : : SPDM_GET_MEASUREMENTS_REQUEST_MEASUREMENT_OPERATION_TOTAL_NUMBER_OF_MEASUREMENTS) {
389 [ + + ]: 8 : if (spdm_response->number_of_blocks != 0) {
390 : 4 : status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
391 : 4 : goto receive_done;
392 : : }
393 [ + + ]: 246 : } else if (measurement_operation ==
394 : : SPDM_GET_MEASUREMENTS_REQUEST_MEASUREMENT_OPERATION_ALL_MEASUREMENTS) {
395 [ + - - + ]: 3 : if ((spdm_response->number_of_blocks == 0) || (spdm_response->number_of_blocks == 0xff)) {
396 : 0 : status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
397 : 0 : goto receive_done;
398 : : }
399 : : } else {
400 [ - + ]: 243 : if (spdm_response->number_of_blocks != 1) {
401 : 0 : status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
402 : 0 : goto receive_done;
403 : : }
404 : : }
405 : :
406 : 250 : measurement_record_data_length = libspdm_read_uint24(spdm_response->measurement_record_length);
407 [ + + ]: 250 : if (measurement_operation ==
408 : : SPDM_GET_MEASUREMENTS_REQUEST_MEASUREMENT_OPERATION_TOTAL_NUMBER_OF_MEASUREMENTS) {
409 [ + + ]: 4 : if (measurement_record_data_length != 0) {
410 : 2 : status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
411 : 2 : goto receive_done;
412 : : }
413 : : } else {
414 : 246 : if (spdm_response_size <
415 [ - + ]: 246 : sizeof(spdm_measurements_response_t) +
416 : : measurement_record_data_length) {
417 : 0 : status = LIBSPDM_STATUS_INVALID_MSG_SIZE;
418 : 0 : goto receive_done;
419 : : }
420 : 246 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "measurement_record_length - 0x%06x\n",
421 : : measurement_record_data_length));
422 : : }
423 : :
424 : 248 : measurement_record_data = (void *)(spdm_response + 1);
425 : :
426 [ + + ]: 248 : if ((request_attribute & SPDM_GET_MEASUREMENTS_REQUEST_ATTRIBUTES_GENERATE_SIGNATURE) != 0) {
427 : 26 : if (spdm_response_size <
428 : : sizeof(spdm_measurements_response_t) +
429 [ - + ]: 26 : measurement_record_data_length + SPDM_NONCE_SIZE + sizeof(uint16_t)) {
430 : 0 : status = LIBSPDM_STATUS_INVALID_MSG_SIZE;
431 : 0 : goto receive_done;
432 : : }
433 [ + - ]: 26 : if ((spdm_response->header.spdm_version >= SPDM_MESSAGE_VERSION_11) &&
434 : 26 : ((spdm_response->header.param2 & SPDM_MEASUREMENTS_RESPONSE_SLOT_ID_MASK)
435 [ + + ]: 26 : != slot_id_param)) {
436 : 3 : status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
437 : 3 : goto receive_done;
438 : : }
439 : 23 : ptr = measurement_record_data + measurement_record_data_length;
440 : 23 : nonce = ptr;
441 : 23 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "nonce (0x%x) - ", SPDM_NONCE_SIZE));
442 : 23 : LIBSPDM_INTERNAL_DUMP_DATA(nonce, SPDM_NONCE_SIZE);
443 : 23 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "\n"));
444 : 23 : ptr += SPDM_NONCE_SIZE;
445 [ + + ]: 23 : if (responder_nonce != NULL) {
446 : 2 : libspdm_copy_mem(responder_nonce, SPDM_NONCE_SIZE, nonce, SPDM_NONCE_SIZE);
447 : : }
448 : :
449 : 23 : opaque_length = libspdm_read_uint16((const uint8_t *)ptr);
450 [ - + ]: 23 : if (opaque_length > SPDM_MAX_OPAQUE_DATA_SIZE) {
451 : 0 : status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
452 : 0 : goto receive_done;
453 : : }
454 [ + + ]: 23 : if (spdm_response->header.spdm_version >= SPDM_MESSAGE_VERSION_12) {
455 [ + + ]: 3 : if (((spdm_context->connection_info.algorithm.other_params_support &
456 : : SPDM_ALGORITHMS_OPAQUE_DATA_FORMAT_MASK) ==
457 : : SPDM_ALGORITHMS_OPAQUE_DATA_FORMAT_NONE)
458 [ - + ]: 2 : && (opaque_length != 0)) {
459 : 0 : status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
460 : 0 : goto receive_done;
461 : : }
462 : : }
463 : 23 : ptr += sizeof(uint16_t);
464 : 23 : if (spdm_response_size <
465 : : sizeof(spdm_measurements_response_t) + measurement_record_data_length +
466 [ + + ]: 23 : SPDM_NONCE_SIZE + sizeof(uint16_t) + opaque_length) {
467 : 2 : status = LIBSPDM_STATUS_INVALID_MSG_SIZE;
468 : 2 : goto receive_done;
469 : : }
470 [ + + ]: 21 : if (opaque_length != 0) {
471 : 7 : result = libspdm_process_general_opaque_data_check(spdm_context, opaque_length, ptr);
472 [ - + ]: 7 : if (!result) {
473 : 0 : status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
474 : 0 : goto receive_done;
475 : : }
476 : : }
477 : :
478 [ - + ]: 21 : if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_13) {
479 : 0 : if (spdm_response_size <
480 : : sizeof(spdm_measurements_response_t) +
481 : : measurement_record_data_length + SPDM_NONCE_SIZE +
482 [ # # ]: 0 : sizeof(uint16_t) + opaque_length + SPDM_REQ_CONTEXT_SIZE + signature_size) {
483 : 0 : status = LIBSPDM_STATUS_INVALID_MSG_SIZE;
484 : 0 : goto receive_done;
485 : : }
486 : 0 : spdm_response_size = sizeof(spdm_measurements_response_t) +
487 : : measurement_record_data_length +
488 : 0 : SPDM_NONCE_SIZE + sizeof(uint16_t) +
489 : 0 : opaque_length + SPDM_REQ_CONTEXT_SIZE + signature_size;
490 : : } else {
491 : 21 : if (spdm_response_size <
492 : : sizeof(spdm_measurements_response_t) +
493 : : measurement_record_data_length + SPDM_NONCE_SIZE +
494 [ + + ]: 21 : sizeof(uint16_t) + opaque_length + signature_size) {
495 : 4 : status = LIBSPDM_STATUS_INVALID_MSG_SIZE;
496 : 4 : goto receive_done;
497 : : }
498 : 17 : spdm_response_size = sizeof(spdm_measurements_response_t) +
499 : : measurement_record_data_length +
500 : 17 : SPDM_NONCE_SIZE + sizeof(uint16_t) +
501 : 17 : opaque_length + signature_size;
502 : : }
503 : :
504 [ + + + - ]: 17 : if ((opaque_data != NULL) && (opaque_data_size != NULL)) {
505 [ - + ]: 2 : if (opaque_length >= *opaque_data_size) {
506 : 0 : status = LIBSPDM_STATUS_BUFFER_TOO_SMALL;
507 : 0 : goto receive_done;
508 : : }
509 : 2 : libspdm_copy_mem(opaque_data, *opaque_data_size, ptr, opaque_length);
510 : 2 : *opaque_data_size = opaque_length;
511 : : }
512 : 17 : ptr += opaque_length;
513 [ - + ]: 17 : if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_13) {
514 : 0 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "RequesterContext - "));
515 : 0 : LIBSPDM_INTERNAL_DUMP_DATA(ptr, SPDM_REQ_CONTEXT_SIZE);
516 : 0 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "\n"));
517 [ # # ]: 0 : if (!libspdm_consttime_is_mem_equal((uint8_t *)spdm_request +
518 : 0 : spdm_request_size - SPDM_REQ_CONTEXT_SIZE,
519 : : ptr, SPDM_REQ_CONTEXT_SIZE)) {
520 : 0 : status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
521 : 0 : goto receive_done;
522 : : }
523 : 0 : ptr += SPDM_REQ_CONTEXT_SIZE;
524 : : }
525 : :
526 : : /* -=[Process Response Phase]=- */
527 : 17 : status = libspdm_append_message_m(spdm_context, session_info, spdm_request,
528 : : spdm_request_size);
529 [ - + ]: 17 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
530 : 0 : goto receive_done;
531 : : }
532 : :
533 : 17 : status = libspdm_append_message_m(spdm_context, session_info, spdm_response,
534 : : spdm_response_size - signature_size);
535 [ - + ]: 17 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
536 : 0 : goto receive_done;
537 : : }
538 : :
539 : 17 : signature = ptr;
540 : 17 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "signature (0x%zx):\n", signature_size));
541 : 17 : LIBSPDM_INTERNAL_DUMP_HEX(signature, signature_size);
542 : :
543 : 17 : result = libspdm_verify_measurement_signature(
544 : : spdm_context, session_info, slot_id_param, signature, signature_size);
545 [ + + ]: 17 : if (!result) {
546 : 7 : status = LIBSPDM_STATUS_VERIF_FAIL;
547 : 7 : goto receive_done;
548 : : }
549 : :
550 : 10 : libspdm_reset_message_m(spdm_context, session_info);
551 : : } else {
552 : 222 : if (spdm_response_size <
553 : : sizeof(spdm_measurements_response_t) +
554 [ - + ]: 222 : measurement_record_data_length + SPDM_NONCE_SIZE + sizeof(uint16_t)) {
555 : 0 : status = LIBSPDM_STATUS_INVALID_MSG_SIZE;
556 : 0 : goto receive_done;
557 : : }
558 : 222 : ptr = measurement_record_data + measurement_record_data_length;
559 : :
560 : 222 : nonce = ptr;
561 : 222 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "nonce (0x%x) - ", SPDM_NONCE_SIZE));
562 : 222 : LIBSPDM_INTERNAL_DUMP_DATA(nonce, SPDM_NONCE_SIZE);
563 : 222 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "\n"));
564 : 222 : ptr += SPDM_NONCE_SIZE;
565 [ - + ]: 222 : if (responder_nonce != NULL) {
566 : 0 : libspdm_copy_mem(responder_nonce, SPDM_NONCE_SIZE, nonce, SPDM_NONCE_SIZE);
567 : : }
568 : :
569 : 222 : opaque_length = libspdm_read_uint16((const uint8_t *)ptr);
570 [ + + ]: 222 : if (opaque_length > SPDM_MAX_OPAQUE_DATA_SIZE) {
571 : 2 : status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
572 : 2 : goto receive_done;
573 : : }
574 : 220 : ptr += sizeof(uint16_t);
575 : 220 : if (spdm_response_size <
576 : : sizeof(spdm_measurements_response_t) + measurement_record_data_length +
577 [ - + ]: 220 : SPDM_NONCE_SIZE + sizeof(uint16_t) + opaque_length) {
578 : 0 : status = LIBSPDM_STATUS_INVALID_MSG_SIZE;
579 : 0 : goto receive_done;
580 : : }
581 [ + + ]: 220 : if (opaque_length != 0) {
582 : 3 : result = libspdm_process_general_opaque_data_check(spdm_context, opaque_length, ptr);
583 [ - + ]: 3 : if (!result) {
584 : 0 : status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
585 : 0 : goto receive_done;
586 : : }
587 : : }
588 : :
589 [ + + ]: 220 : if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_13) {
590 : 2 : if (spdm_response_size <
591 : : sizeof(spdm_measurements_response_t) +
592 : : measurement_record_data_length + SPDM_NONCE_SIZE +
593 [ - + ]: 2 : sizeof(uint16_t) + opaque_length + SPDM_REQ_CONTEXT_SIZE) {
594 : 0 : status = LIBSPDM_STATUS_INVALID_MSG_SIZE;
595 : 0 : goto receive_done;
596 : : }
597 : 2 : spdm_response_size = sizeof(spdm_measurements_response_t) +
598 : : measurement_record_data_length +
599 : 2 : SPDM_NONCE_SIZE + sizeof(uint16_t) +
600 : 2 : opaque_length + SPDM_REQ_CONTEXT_SIZE;
601 : : } else {
602 : 218 : if (spdm_response_size <
603 : : sizeof(spdm_measurements_response_t) +
604 : : measurement_record_data_length + SPDM_NONCE_SIZE +
605 [ - + ]: 218 : sizeof(uint16_t) + opaque_length) {
606 : 0 : status = LIBSPDM_STATUS_INVALID_MSG_SIZE;
607 : 0 : goto receive_done;
608 : : }
609 : 218 : spdm_response_size = sizeof(spdm_measurements_response_t) +
610 : : measurement_record_data_length +
611 : 218 : SPDM_NONCE_SIZE + sizeof(uint16_t) +
612 : : opaque_length;
613 : : }
614 : :
615 [ + + + - ]: 220 : if ((opaque_data != NULL) && (opaque_data_size != NULL)) {
616 [ - + ]: 1 : if (opaque_length >= *opaque_data_size) {
617 : 0 : status = LIBSPDM_STATUS_BUFFER_TOO_SMALL;
618 : 0 : goto receive_done;
619 : : }
620 : 1 : libspdm_copy_mem(opaque_data, *opaque_data_size, ptr, opaque_length);
621 : 1 : *opaque_data_size = opaque_length;
622 : : }
623 : 220 : ptr += opaque_length;
624 [ + + ]: 220 : if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_13) {
625 : 2 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "RequesterContext - "));
626 : 2 : LIBSPDM_INTERNAL_DUMP_DATA(ptr, SPDM_REQ_CONTEXT_SIZE);
627 : 2 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "\n"));
628 [ + + ]: 2 : if (!libspdm_consttime_is_mem_equal((uint8_t *)spdm_request +
629 : 2 : spdm_request_size - SPDM_REQ_CONTEXT_SIZE,
630 : : ptr, SPDM_REQ_CONTEXT_SIZE)) {
631 : 1 : status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
632 : 1 : goto receive_done;
633 : : }
634 : 1 : ptr += SPDM_REQ_CONTEXT_SIZE;
635 : : }
636 : :
637 : : /* If a signature is not requested then content_changed must be 0. */
638 [ + + ]: 219 : if (spdm_response->header.spdm_version >= SPDM_MESSAGE_VERSION_12) {
639 [ + + ]: 4 : if ((spdm_response->header.param2 & SPDM_MEASUREMENTS_RESPONSE_CONTENT_CHANGE_MASK)
640 : : != 0) {
641 : 1 : status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
642 : 1 : goto receive_done;
643 : : }
644 : : }
645 : :
646 : 218 : status = libspdm_append_message_m(spdm_context, session_info, spdm_request,
647 : : spdm_request_size);
648 [ - + ]: 218 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
649 : 0 : goto receive_done;
650 : : }
651 : :
652 : 218 : status = libspdm_append_message_m(spdm_context, session_info, spdm_response,
653 : : spdm_response_size);
654 [ - + ]: 218 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
655 : 0 : goto receive_done;
656 : : }
657 : : }
658 : :
659 [ - + ]: 228 : if (content_changed != NULL) {
660 : 0 : *content_changed = 0;
661 [ # # ]: 0 : if ((spdm_response->header.spdm_version >= SPDM_MESSAGE_VERSION_12) &&
662 [ # # ]: 0 : ((request_attribute &
663 : : SPDM_GET_MEASUREMENTS_REQUEST_ATTRIBUTES_GENERATE_SIGNATURE) != 0)) {
664 : 0 : *content_changed =
665 : 0 : (spdm_response->header.param2 & SPDM_MEASUREMENTS_RESPONSE_CONTENT_CHANGE_MASK);
666 : : }
667 : : }
668 [ + + ]: 228 : if (measurement_operation ==
669 : : SPDM_GET_MEASUREMENTS_REQUEST_MEASUREMENT_OPERATION_TOTAL_NUMBER_OF_MEASUREMENTS) {
670 : 2 : *number_of_blocks = spdm_response->header.param1;
671 [ - + ]: 2 : if (*number_of_blocks == 0xFF) {
672 : : /* the number of block cannot be 0xFF, because index 0xFF will brings confusing.*/
673 : 0 : status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
674 : 0 : goto receive_done;
675 : : }
676 [ - + ]: 2 : if (*number_of_blocks == 0x0) {
677 : : /* the number of block cannot be 0x0, because a responder without measurement should clear capability flags.*/
678 : 0 : status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
679 : 0 : goto receive_done;
680 : : }
681 : : } else {
682 : 226 : *number_of_blocks = spdm_response->number_of_blocks;
683 [ - + ]: 226 : if (*measurement_record_length < measurement_record_data_length) {
684 : 0 : status = LIBSPDM_STATUS_BUFFER_TOO_SMALL;
685 : 0 : goto receive_done;
686 : : }
687 [ - + ]: 226 : if (measurement_record_data_length < sizeof(spdm_measurement_block_common_header_t)) {
688 : 0 : status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
689 : 0 : goto receive_done;
690 : : }
691 : :
692 : 226 : measurement_block_size = 0;
693 : 226 : measurement_block_count = 1;
694 [ + + ]: 448 : while (measurement_block_size < measurement_record_data_length) {
695 : 228 : measurement_block_header =
696 : 228 : (spdm_measurement_block_common_header_t *)&measurement_record_data
697 : : [measurement_block_size];
698 : 228 : if (measurement_block_header->measurement_size >
699 : 228 : measurement_record_data_length -
700 [ - + ]: 228 : ((uint8_t *)measurement_block_header -
701 : : (uint8_t *)measurement_record_data)) {
702 : 0 : status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
703 : 0 : goto receive_done;
704 : : }
705 [ + - ]: 228 : if (measurement_block_header->measurement_specification == 0 ||
706 : 228 : (measurement_block_header->measurement_specification &
707 [ + + ]: 228 : (measurement_block_header->measurement_specification - 1))) {
708 : 4 : status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
709 : 4 : goto receive_done;
710 : : }
711 : 224 : if (measurement_block_header->measurement_specification !=
712 [ + + ]: 224 : spdm_context->connection_info.algorithm.measurement_spec) {
713 : 2 : status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
714 : 2 : goto receive_done;
715 : : }
716 [ + - - + ]: 222 : if (measurement_block_header->index == 0 || measurement_block_header->index == 0xFF) {
717 : 0 : status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
718 : 0 : goto receive_done;
719 : : }
720 [ + + ]: 222 : if (measurement_operation !=
721 : : SPDM_GET_MEASUREMENTS_REQUEST_MEASUREMENT_OPERATION_ALL_MEASUREMENTS) {
722 [ - + ]: 217 : if (measurement_block_header->index != measurement_operation) {
723 : 0 : status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
724 : 0 : goto receive_done;
725 : : }
726 : : }
727 [ - + ]: 222 : if (measurement_block_count > *number_of_blocks) {
728 : 0 : status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
729 : 0 : goto receive_done;
730 : : }
731 : 222 : measurement_block_count++;
732 : 222 : measurement_block_size = (uint32_t)(
733 : : measurement_block_size +
734 : 222 : sizeof(spdm_measurement_block_common_header_t) +
735 : 222 : measurement_block_header->measurement_size);
736 : : }
737 : :
738 [ - + ]: 220 : if (measurement_block_size != measurement_record_data_length) {
739 : 0 : status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
740 : 0 : goto receive_done;
741 : : }
742 : :
743 : 220 : *measurement_record_length = measurement_record_data_length;
744 : 220 : libspdm_copy_mem(measurement_record,
745 : : measurement_record_data_length,
746 : : measurement_record_data,
747 : : measurement_record_data_length);
748 : : }
749 : :
750 : 222 : status = LIBSPDM_STATUS_SUCCESS;
751 : :
752 : : /* -=[Log Message Phase]=- */
753 : : #if LIBSPDM_ENABLE_MSG_LOG
754 : 222 : libspdm_append_msg_log(spdm_context, spdm_response, spdm_response_size);
755 : : #endif /* LIBSPDM_ENABLE_MSG_LOG */
756 : :
757 : 303 : receive_done:
758 [ + + + + ]: 303 : if ((status != LIBSPDM_STATUS_SUCCESS) &&
759 : : (status != LIBSPDM_STATUS_NOT_READY_PEER)) {
760 : 79 : libspdm_reset_message_m(spdm_context, session_info);
761 : : }
762 : 303 : libspdm_release_receiver_buffer (spdm_context);
763 : 303 : return status;
764 : : }
765 : :
766 : 304 : libspdm_return_t libspdm_get_measurement(void *spdm_context, const uint32_t *session_id,
767 : : uint8_t request_attribute,
768 : : uint8_t measurement_operation,
769 : : uint8_t slot_id_param,
770 : : uint8_t *content_changed,
771 : : uint8_t *number_of_blocks,
772 : : uint32_t *measurement_record_length,
773 : : void *measurement_record)
774 : : {
775 : : libspdm_context_t *context;
776 : : size_t retry;
777 : : uint64_t retry_delay_time;
778 : : libspdm_return_t status;
779 : :
780 : 304 : context = spdm_context;
781 : 304 : context->crypto_request = true;
782 : 304 : retry = context->retry_times;
783 : 304 : retry_delay_time = context->retry_delay_time;
784 : : do {
785 : 305 : status = libspdm_try_get_measurement(
786 : : context, session_id, request_attribute,
787 : : measurement_operation, slot_id_param, NULL, content_changed, number_of_blocks,
788 : : measurement_record_length, measurement_record,
789 : : NULL, NULL, NULL, NULL, NULL);
790 [ + + ]: 305 : if (status != LIBSPDM_STATUS_BUSY_PEER) {
791 : 302 : return status;
792 : : }
793 : :
794 : 3 : libspdm_sleep(retry_delay_time);
795 [ + + ]: 3 : } while (retry-- != 0);
796 : :
797 : 2 : return status;
798 : : }
799 : :
800 : 4 : libspdm_return_t libspdm_get_measurement_ex(void *spdm_context, const uint32_t *session_id,
801 : : uint8_t request_attribute,
802 : : uint8_t measurement_operation,
803 : : uint8_t slot_id_param,
804 : : uint8_t *content_changed,
805 : : uint8_t *number_of_blocks,
806 : : uint32_t *measurement_record_length,
807 : : void *measurement_record,
808 : : const void *requester_nonce_in,
809 : : void *requester_nonce,
810 : : void *responder_nonce,
811 : : void *opaque_data,
812 : : size_t *opaque_data_size)
813 : : {
814 : : libspdm_context_t *context;
815 : : size_t retry;
816 : : uint64_t retry_delay_time;
817 : : libspdm_return_t status;
818 : :
819 : 4 : context = spdm_context;
820 : 4 : context->crypto_request = true;
821 : 4 : retry = context->retry_times;
822 : 4 : retry_delay_time = context->retry_delay_time;
823 : : do {
824 : 4 : status = libspdm_try_get_measurement(
825 : : context, session_id, request_attribute,
826 : : measurement_operation, slot_id_param, NULL, content_changed, number_of_blocks,
827 : : measurement_record_length, measurement_record,
828 : : requester_nonce_in,
829 : : requester_nonce, responder_nonce,
830 : : opaque_data, opaque_data_size);
831 [ + - ]: 4 : if (status != LIBSPDM_STATUS_BUSY_PEER) {
832 : 4 : return status;
833 : : }
834 : :
835 : 0 : libspdm_sleep(retry_delay_time);
836 [ # # ]: 0 : } while (retry-- != 0);
837 : :
838 : 0 : return status;
839 : : }
840 : :
841 : 2 : libspdm_return_t libspdm_get_measurement_ex2(void *spdm_context, const uint32_t *session_id,
842 : : uint8_t request_attribute,
843 : : uint8_t measurement_operation,
844 : : uint8_t slot_id_param,
845 : : const void *requester_context,
846 : : uint8_t *content_changed,
847 : : uint8_t *number_of_blocks,
848 : : uint32_t *measurement_record_length,
849 : : void *measurement_record,
850 : : const void *requester_nonce_in,
851 : : void *requester_nonce,
852 : : void *responder_nonce,
853 : : void *opaque_data,
854 : : size_t *opaque_data_size)
855 : : {
856 : : libspdm_context_t *context;
857 : : size_t retry;
858 : : uint64_t retry_delay_time;
859 : : libspdm_return_t status;
860 : :
861 : 2 : context = spdm_context;
862 : 2 : context->crypto_request = true;
863 : 2 : retry = context->retry_times;
864 : 2 : retry_delay_time = context->retry_delay_time;
865 : : do {
866 : 2 : status = libspdm_try_get_measurement(
867 : : context, session_id, request_attribute,
868 : : measurement_operation, slot_id_param, requester_context,
869 : : content_changed, number_of_blocks,
870 : : measurement_record_length, measurement_record,
871 : : requester_nonce_in,
872 : : requester_nonce, responder_nonce,
873 : : opaque_data, opaque_data_size);
874 [ + - ]: 2 : if (status != LIBSPDM_STATUS_BUSY_PEER) {
875 : 2 : return status;
876 : : }
877 : :
878 : 0 : libspdm_sleep(retry_delay_time);
879 [ # # ]: 0 : } while (retry-- != 0);
880 : :
881 : 0 : return status;
882 : : }
883 : :
884 : : #endif /* LIBSPDM_ENABLE_CAPABILITY_MEAS_CAP*/
|