TianoCore EDK2 master
Loading...
Searching...
No Matches
SpdmMeasurement.c
Go to the documentation of this file.
1
11
19UINT32
20EFIAPI
22 IN SPDM_DEVICE_CONTEXT *SpdmDeviceContext
23 )
24{
25 if (CompareGuid (&SpdmDeviceContext->DeviceId.DeviceType, &gEdkiiDeviceIdentifierTypePciGuid)) {
26 return TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_TYPE_PCI;
27 }
28
29 if (CompareGuid (&SpdmDeviceContext->DeviceId.DeviceType, &gEdkiiDeviceIdentifierTypeUsbGuid)) {
30 return TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_TYPE_USB;
31 }
32
33 return TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_TYPE_NULL;
34}
35
44EFIAPI
46 IN SPDM_DEVICE_CONTEXT *SpdmDeviceContext
47 )
48{
49 if (CompareGuid (&SpdmDeviceContext->DeviceId.DeviceType, &gEdkiiDeviceIdentifierTypePciGuid)) {
51 }
52
53 if (CompareGuid (&SpdmDeviceContext->DeviceId.DeviceType, &gEdkiiDeviceIdentifierTypeUsbGuid)) {
54 // TBD - usb context
55 return 0;
56 }
57
58 return 0;
59}
60
72 IN SPDM_DEVICE_CONTEXT *SpdmDeviceContext,
73 IN OUT VOID *DeviceContext,
74 IN UINTN DeviceContextSize
75 )
76{
78 PCI_TYPE00 PciData;
80 EFI_STATUS Status;
81
82 if (DeviceContextSize != sizeof (*PciContext)) {
83 return EFI_BUFFER_TOO_SMALL;
84 }
85
86 PciIo = SpdmDeviceContext->DeviceIo;
87 Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint8, 0, sizeof (PciData), &PciData);
88 ASSERT_EFI_ERROR (Status);
89
90 PciContext = DeviceContext;
91 PciContext->Version = TCG_DEVICE_SECURITY_EVENT_DATA_PCI_CONTEXT_VERSION;
92 PciContext->Length = sizeof (*PciContext);
93 PciContext->VendorId = PciData.Hdr.VendorId;
94 PciContext->DeviceId = PciData.Hdr.DeviceId;
95 PciContext->RevisionID = PciData.Hdr.RevisionID;
96 PciContext->ClassCode[0] = PciData.Hdr.ClassCode[0];
97 PciContext->ClassCode[1] = PciData.Hdr.ClassCode[1];
98 PciContext->ClassCode[2] = PciData.Hdr.ClassCode[2];
99 if ((PciData.Hdr.HeaderType & HEADER_LAYOUT_CODE) == HEADER_TYPE_DEVICE) {
100 PciContext->SubsystemVendorID = PciData.Device.SubsystemVendorID;
101 PciContext->SubsystemID = PciData.Device.SubsystemID;
102 } else {
103 PciContext->SubsystemVendorID = 0;
104 PciContext->SubsystemID = 0;
105 }
106
107 return EFI_SUCCESS;
108}
109
121EFIAPI
123 IN SPDM_DEVICE_CONTEXT *SpdmDeviceContext,
124 IN OUT VOID *DeviceContext,
125 IN UINTN DeviceContextSize
126 )
127{
128 if (CompareGuid (&SpdmDeviceContext->DeviceId.DeviceType, &gEdkiiDeviceIdentifierTypePciGuid)) {
129 return CreatePciDeviceMeasurementContext (SpdmDeviceContext, DeviceContext, DeviceContextSize);
130 }
131
132 if (CompareGuid (&SpdmDeviceContext->DeviceId.DeviceType, &gEdkiiDeviceIdentifierTypeUsbGuid)) {
133 return EFI_UNSUPPORTED;
134 }
135
136 return EFI_UNSUPPORTED;
137}
138
146VOID
147EFIAPI
149 CONST UINT8 *Data,
150 UINTN Size
151 )
152{
153 UINTN Index;
154
155 for (Index = 0; Index < Size; Index++) {
156 DEBUG ((DEBUG_INFO, "%02x ", (UINTN)Data[Index]));
157 }
158}
159
178 IN SPDM_DEVICE_CONTEXT *SpdmDeviceContext,
179 IN UINT8 AuthState,
180 IN UINT32 MeasurementRecordLength,
181 IN UINT8 *MeasurementRecord,
182 IN UINT8 *RequesterNonce,
183 IN UINT8 *ResponderNonce,
184 OUT EDKII_DEVICE_SECURITY_STATE *SecurityState
185 )
186{
187 UINT32 PcrIndex;
188 UINT32 EventType;
189 VOID *EventLog;
190 UINT32 EventLogSize;
191 UINT8 *EventLogPtr;
192
195 VOID *DeviceContext;
196 UINTN DeviceContextSize;
197 EFI_STATUS Status;
198 SPDM_MEASUREMENT_BLOCK_COMMON_HEADER *SpdmMeasurementBlockCommonHeader;
199 SPDM_MEASUREMENT_BLOCK_DMTF_HEADER *SpdmMeasurementBlockDmtfHeader;
200 VOID *Digest;
201 UINTN DigestSize;
202 UINTN DevicePathSize;
203 UINT32 MeasurementHashAlgo;
204 UINTN DataSize;
205 VOID *SpdmContext;
206 SPDM_DATA_PARAMETER Parameter;
207
208 SpdmContext = SpdmDeviceContext->SpdmContext;
209
210 EventLog = NULL;
211 ZeroMem (&Parameter, sizeof (Parameter));
212 Parameter.location = SpdmDataLocationConnection;
213 DataSize = sizeof (MeasurementHashAlgo);
214 Status = SpdmGetData (SpdmContext, SpdmDataMeasurementHashAlgo, &Parameter, &MeasurementHashAlgo, &DataSize);
215 ASSERT_EFI_ERROR (Status);
216
217 if (MeasurementRecord != NULL) {
218 SpdmMeasurementBlockCommonHeader = (VOID *)MeasurementRecord;
219 SpdmMeasurementBlockDmtfHeader = (VOID *)(SpdmMeasurementBlockCommonHeader + 1);
220 Digest = (SpdmMeasurementBlockDmtfHeader + 1);
221 DigestSize = MeasurementRecordLength - sizeof (SPDM_MEASUREMENT_BLOCK_DMTF);
222
223 DEBUG ((DEBUG_INFO, "SpdmMeasurementBlockCommonHeader\n"));
224 DEBUG ((DEBUG_INFO, " Index - 0x%02x\n", SpdmMeasurementBlockCommonHeader->Index));
225 DEBUG ((DEBUG_INFO, " MeasurementSpecification - 0x%02x\n", SpdmMeasurementBlockCommonHeader->MeasurementSpecification));
226 DEBUG ((DEBUG_INFO, " MeasurementSize - 0x%04x\n", SpdmMeasurementBlockCommonHeader->MeasurementSize));
227 DEBUG ((DEBUG_INFO, "SpdmMeasurementBlockDmtfHeader\n"));
228 DEBUG ((DEBUG_INFO, " DMTFSpecMeasurementValueType - 0x%02x\n", SpdmMeasurementBlockDmtfHeader->DMTFSpecMeasurementValueType));
229 DEBUG ((DEBUG_INFO, " DMTFSpecMeasurementValueSize - 0x%04x\n", SpdmMeasurementBlockDmtfHeader->DMTFSpecMeasurementValueSize));
230 DEBUG ((DEBUG_INFO, "Measurement - "));
231 InternalDumpData (Digest, DigestSize);
232 DEBUG ((DEBUG_INFO, "\n"));
233 if (MeasurementRecordLength <= sizeof (SPDM_MEASUREMENT_BLOCK_COMMON_HEADER) + sizeof (SPDM_MEASUREMENT_BLOCK_DMTF_HEADER)) {
234 SecurityState->MeasurementState = EDKII_DEVICE_SECURITY_STATE_ERROR_MEASUREMENT_AUTH_FAILURE;
235 return EFI_SECURITY_VIOLATION;
236 }
237
238 if ((SpdmMeasurementBlockCommonHeader->MeasurementSpecification & SPDM_MEASUREMENT_SPECIFICATION_DMTF) == 0) {
239 SecurityState->MeasurementState = EDKII_DEVICE_SECURITY_STATE_ERROR_MEASUREMENT_AUTH_FAILURE;
240 return EFI_SECURITY_VIOLATION;
241 }
242
243 if (SpdmMeasurementBlockCommonHeader->MeasurementSize != MeasurementRecordLength - sizeof (SPDM_MEASUREMENT_BLOCK_COMMON_HEADER)) {
244 SecurityState->MeasurementState = EDKII_DEVICE_SECURITY_STATE_ERROR_MEASUREMENT_AUTH_FAILURE;
245 return EFI_SECURITY_VIOLATION;
246 }
247
248 if (SpdmMeasurementBlockDmtfHeader->DMTFSpecMeasurementValueSize != SpdmMeasurementBlockCommonHeader->MeasurementSize - sizeof (SPDM_MEASUREMENT_BLOCK_DMTF_HEADER)) {
249 SecurityState->MeasurementState = EDKII_DEVICE_SECURITY_STATE_ERROR_MEASUREMENT_AUTH_FAILURE;
250 return EFI_SECURITY_VIOLATION;
251 }
252
253 //
254 // Use PCR 2 for Firmware Blob code.
255 //
256 switch (SpdmMeasurementBlockDmtfHeader->DMTFSpecMeasurementValueType & 0x7F) {
258 case SPDM_MEASUREMENT_BLOCK_MEASUREMENT_TYPE_MUTABLE_FIRMWARE:
259 case SPDM_MEASUREMENT_BLOCK_MEASUREMENT_TYPE_VERSION:
260 case SPDM_MEASUREMENT_BLOCK_MEASUREMENT_TYPE_SECURE_VERSION_NUMBER:
261 if (SpdmDeviceContext->IsEmbeddedDevice) {
262 PcrIndex = 0;
263 } else {
264 PcrIndex = 2;
265 }
266
267 EventType = EV_EFI_SPDM_FIRMWARE_BLOB;
268 break;
269 case SPDM_MEASUREMENT_BLOCK_MEASUREMENT_TYPE_HARDWARE_CONFIGURATION:
270 case SPDM_MEASUREMENT_BLOCK_MEASUREMENT_TYPE_FIRMWARE_CONFIGURATION:
271 case SPDM_MEASUREMENT_BLOCK_MEASUREMENT_TYPE_DEVICE_MODE:
272 if (SpdmDeviceContext->IsEmbeddedDevice) {
273 PcrIndex = 1;
274 } else {
275 PcrIndex = 3;
276 }
277
278 EventType = EV_EFI_SPDM_FIRMWARE_CONFIG;
279 break;
280 case SPDM_MEASUREMENT_BLOCK_MEASUREMENT_TYPE_MEASUREMENT_MANIFEST:
281 // skip manifest, because manifest doesn't belong to the EV_EFI_SPDM_FIRMWARE_BLOB and EV_EFI_SPDM_FIRMWARE_CONFIG
282 default:
283 return EFI_SUCCESS;
284 }
285 } else {
286 if (SpdmDeviceContext->IsEmbeddedDevice) {
287 PcrIndex = 0;
288 } else {
289 PcrIndex = 2;
290 }
291
292 EventType = EV_EFI_SPDM_FIRMWARE_BLOB;
293 }
294
295 DeviceContextSize = GetDeviceMeasurementContextSize (SpdmDeviceContext);
296 DevicePathSize = GetDevicePathSize (SpdmDeviceContext->DevicePath);
297
298 switch (AuthState) {
299 case TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_AUTH_STATE_SUCCESS:
300 EventLogSize = (UINT32)(sizeof (TCG_DEVICE_SECURITY_EVENT_DATA_HEADER2) +
301 sizeof (UINT64) + DevicePathSize +
303 MeasurementRecordLength +
304 DeviceContextSize);
305 EventLog = AllocatePool (EventLogSize);
306 if (EventLog == NULL) {
307 SecurityState->MeasurementState = EDKII_DEVICE_SECURITY_STATE_ERROR_UEFI_OUT_OF_RESOURCE;
308 return EFI_OUT_OF_RESOURCES;
309 }
310
311 EventLogPtr = EventLog;
312
313 EventData2 = (VOID *)EventLogPtr;
314 CopyMem (EventData2->Signature, TCG_DEVICE_SECURITY_EVENT_DATA_SIGNATURE_2, sizeof (EventData2->Signature));
315 EventData2->Version = TCG_DEVICE_SECURITY_EVENT_DATA_VERSION_2;
316 EventData2->AuthState = AuthState;
317 EventData2->Reserved = 0;
318 EventData2->Length = (UINT32)EventLogSize;
319 EventData2->DeviceType = GetSpdmDeviceType (SpdmDeviceContext);
320
321 EventData2->SubHeaderType = TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_SUB_HEADER_TYPE_SPDM_MEASUREMENT_BLOCK;
322 EventData2->SubHeaderLength = sizeof (TCG_DEVICE_SECURITY_EVENT_DATA_SUB_HEADER_SPDM_MEASUREMENT_BLOCK) + MeasurementRecordLength;
323 EventData2->SubHeaderUID = SpdmDeviceContext->DeviceUID;
324
325 EventLogPtr = (VOID *)(EventData2 + 1);
326
327 *(UINT64 *)EventLogPtr = (UINT64)DevicePathSize;
328 EventLogPtr += sizeof (UINT64);
329 CopyMem (EventLogPtr, SpdmDeviceContext->DevicePath, DevicePathSize);
330 EventLogPtr += DevicePathSize;
331
332 TcgSpdmMeasurementBlock = (VOID *)EventLogPtr;
333 TcgSpdmMeasurementBlock->SpdmVersion = SpdmDeviceContext->SpdmVersion;
334 TcgSpdmMeasurementBlock->SpdmMeasurementBlockCount = 1;
335 TcgSpdmMeasurementBlock->Reserved = 0;
336 TcgSpdmMeasurementBlock->SpdmMeasurementHashAlgo = MeasurementHashAlgo;
338
339 if ((MeasurementRecord != NULL) && (MeasurementRecordLength != 0)) {
340 CopyMem (EventLogPtr, MeasurementRecord, MeasurementRecordLength);
341 EventLogPtr += MeasurementRecordLength;
342 }
343
344 if (DeviceContextSize != 0) {
345 DeviceContext = (VOID *)EventLogPtr;
346 Status = CreateDeviceMeasurementContext (SpdmDeviceContext, DeviceContext, DeviceContextSize);
347 if (Status != EFI_SUCCESS) {
348 SecurityState->MeasurementState = EDKII_DEVICE_SECURITY_STATE_ERROR_DEVICE_ERROR;
349 Status = EFI_DEVICE_ERROR;
350 goto Exit;
351 }
352 }
353
354 Status = TpmMeasureAndLogData (
355 PcrIndex,
356 EventType,
357 EventLog,
358 EventLogSize,
359 EventLog,
360 EventLogSize
361 );
362 if (EFI_ERROR (Status)) {
363 SecurityState->MeasurementState = EDKII_DEVICE_SECURITY_STATE_ERROR_TCG_EXTEND_TPM_PCR;
364 }
365
366 DEBUG ((DEBUG_INFO, "TpmMeasureAndLogData (Measurement) - %r\n", Status));
367 break;
368 case TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_AUTH_STATE_FAIL_INVALID:
369 EventLogSize = (UINT32)(sizeof (TCG_DEVICE_SECURITY_EVENT_DATA_HEADER2) +
370 sizeof (UINT64) + DevicePathSize +
371 DeviceContextSize);
372 EventLog = AllocatePool (EventLogSize);
373 if (EventLog == NULL) {
374 SecurityState->MeasurementState = EDKII_DEVICE_SECURITY_STATE_ERROR_UEFI_OUT_OF_RESOURCE;
375 return EFI_OUT_OF_RESOURCES;
376 }
377
378 EventLogPtr = EventLog;
379
380 EventData2 = (VOID *)EventLogPtr;
381 CopyMem (EventData2->Signature, TCG_DEVICE_SECURITY_EVENT_DATA_SIGNATURE_2, sizeof (EventData2->Signature));
382 EventData2->Version = TCG_DEVICE_SECURITY_EVENT_DATA_VERSION_2;
383 EventData2->AuthState = AuthState;
384 EventData2->Reserved = 0;
385 EventData2->Length = (UINT32)EventLogSize;
386 EventData2->DeviceType = GetSpdmDeviceType (SpdmDeviceContext);
387
388 EventData2->SubHeaderType = TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_SUB_HEADER_TYPE_SPDM_MEASUREMENT_BLOCK;
389 EventData2->SubHeaderLength = 0;
390 EventData2->SubHeaderUID = SpdmDeviceContext->DeviceUID;
391
392 EventLogPtr = (VOID *)(EventData2 + 1);
393
394 *(UINT64 *)EventLogPtr = (UINT64)DevicePathSize;
395 EventLogPtr += sizeof (UINT64);
396 CopyMem (EventLogPtr, SpdmDeviceContext->DevicePath, DevicePathSize);
397 EventLogPtr += DevicePathSize;
398
399 if (DeviceContextSize != 0) {
400 DeviceContext = (VOID *)EventLogPtr;
401 Status = CreateDeviceMeasurementContext (SpdmDeviceContext, DeviceContext, DeviceContextSize);
402 if (Status != EFI_SUCCESS) {
403 SecurityState->MeasurementState = EDKII_DEVICE_SECURITY_STATE_ERROR_DEVICE_ERROR;
404 Status = EFI_DEVICE_ERROR;
405 goto Exit;
406 }
407 }
408
409 Status = TpmMeasureAndLogData (
410 PcrIndex,
411 EventType,
412 EventLog,
413 EventLogSize,
414 EventLog,
415 EventLogSize
416 );
417 if (EFI_ERROR (Status)) {
418 SecurityState->MeasurementState = EDKII_DEVICE_SECURITY_STATE_ERROR_TCG_EXTEND_TPM_PCR;
419 }
420
421 DEBUG ((DEBUG_INFO, "TpmMeasureAndLogData (Measurement) - %r\n", Status));
422 goto Exit;
423 default:
424 SecurityState->MeasurementState = EDKII_DEVICE_SECURITY_STATE_ERROR_UEFI_UNSUPPORTED;
425 return EFI_UNSUPPORTED;
426 }
427
428 if (RequesterNonce != NULL) {
429 TCG_NV_INDEX_DYNAMIC_EVENT_LOG_STRUCT_SPDM_GET_MEASUREMENTS DynamicEventLogSpdmGetMeasurementsEvent;
430
431 CopyMem (DynamicEventLogSpdmGetMeasurementsEvent.Header.Signature, TCG_NV_EXTEND_INDEX_FOR_DYNAMIC_SIGNATURE, sizeof (TCG_NV_EXTEND_INDEX_FOR_DYNAMIC_SIGNATURE));
432 DynamicEventLogSpdmGetMeasurementsEvent.Header.Version = TCG_NV_INDEX_DYNAMIC_EVENT_LOG_STRUCT_VERSION;
433 ZeroMem (DynamicEventLogSpdmGetMeasurementsEvent.Header.Reserved, sizeof (DynamicEventLogSpdmGetMeasurementsEvent.Header.Reserved));
434 DynamicEventLogSpdmGetMeasurementsEvent.Header.Uid = SpdmDeviceContext->DeviceUID;
435 DynamicEventLogSpdmGetMeasurementsEvent.DescriptionSize = sizeof (TCG_SPDM_GET_MEASUREMENTS_DESCRIPTION);
436 CopyMem (DynamicEventLogSpdmGetMeasurementsEvent.Description, TCG_SPDM_GET_MEASUREMENTS_DESCRIPTION, sizeof (TCG_SPDM_GET_MEASUREMENTS_DESCRIPTION));
437 DynamicEventLogSpdmGetMeasurementsEvent.DataSize = SPDM_NONCE_SIZE;
438 CopyMem (DynamicEventLogSpdmGetMeasurementsEvent.Data, RequesterNonce, SPDM_NONCE_SIZE);
439
440 Status = TpmMeasureAndLogData (
441 TCG_NV_EXTEND_INDEX_FOR_DYNAMIC,
442 EV_NO_ACTION,
443 &DynamicEventLogSpdmGetMeasurementsEvent,
444 sizeof (DynamicEventLogSpdmGetMeasurementsEvent),
445 &DynamicEventLogSpdmGetMeasurementsEvent,
446 sizeof (DynamicEventLogSpdmGetMeasurementsEvent)
447 );
448 if (EFI_ERROR (Status)) {
449 SecurityState->MeasurementState = EDKII_DEVICE_SECURITY_STATE_ERROR_TCG_EXTEND_TPM_PCR;
450 }
451
452 DEBUG ((DEBUG_INFO, "TpmMeasureAndLogData (Dynamic) - %r\n", Status));
453 }
454
455 if (ResponderNonce != NULL) {
456 TCG_NV_INDEX_DYNAMIC_EVENT_LOG_STRUCT_SPDM_MEASUREMENTS DynamicEventLogSpdmMeasurementsEvent;
457
458 CopyMem (DynamicEventLogSpdmMeasurementsEvent.Header.Signature, TCG_NV_EXTEND_INDEX_FOR_DYNAMIC_SIGNATURE, sizeof (TCG_NV_EXTEND_INDEX_FOR_DYNAMIC_SIGNATURE));
459 DynamicEventLogSpdmMeasurementsEvent.Header.Version = TCG_NV_INDEX_DYNAMIC_EVENT_LOG_STRUCT_VERSION;
460 ZeroMem (DynamicEventLogSpdmMeasurementsEvent.Header.Reserved, sizeof (DynamicEventLogSpdmMeasurementsEvent.Header.Reserved));
461 DynamicEventLogSpdmMeasurementsEvent.Header.Uid = SpdmDeviceContext->DeviceUID;
462 DynamicEventLogSpdmMeasurementsEvent.DescriptionSize = sizeof (TCG_SPDM_MEASUREMENTS_DESCRIPTION);
463 CopyMem (DynamicEventLogSpdmMeasurementsEvent.Description, TCG_SPDM_MEASUREMENTS_DESCRIPTION, sizeof (TCG_SPDM_MEASUREMENTS_DESCRIPTION));
464 DynamicEventLogSpdmMeasurementsEvent.DataSize = SPDM_NONCE_SIZE;
465 CopyMem (DynamicEventLogSpdmMeasurementsEvent.Data, ResponderNonce, SPDM_NONCE_SIZE);
466
467 Status = TpmMeasureAndLogData (
468 TCG_NV_EXTEND_INDEX_FOR_DYNAMIC,
469 EV_NO_ACTION,
470 &DynamicEventLogSpdmMeasurementsEvent,
471 sizeof (DynamicEventLogSpdmMeasurementsEvent),
472 &DynamicEventLogSpdmMeasurementsEvent,
473 sizeof (DynamicEventLogSpdmMeasurementsEvent)
474 );
475 if (EFI_ERROR (Status)) {
476 SecurityState->MeasurementState = EDKII_DEVICE_SECURITY_STATE_ERROR_TCG_EXTEND_TPM_PCR;
477 }
478
479 DEBUG ((DEBUG_INFO, "TpmMeasureAndLogData (Dynamic) - %r\n", Status));
480 }
481
482Exit:
483 if (EventLog != NULL) {
484 FreePool (EventLog);
485 }
486
487 return Status;
488}
489
503EFIAPI
505 IN SPDM_DEVICE_CONTEXT *SpdmDeviceContext,
506 IN UINT8 SlotId,
507 OUT EDKII_DEVICE_SECURITY_STATE *SecurityState
508 )
509{
510 EFI_STATUS Status;
511 SPDM_RETURN SpdmReturn;
512 VOID *SpdmContext;
513 UINT32 CapabilityFlags;
514 UINTN DataSize;
515 SPDM_DATA_PARAMETER Parameter;
516 UINT8 NumberOfBlocks;
517 UINT32 MeasurementRecordLength;
518 UINT8 MeasurementRecord[LIBSPDM_MAX_MEASUREMENT_RECORD_SIZE];
519 UINT8 Index;
520 UINT8 RequesterNonce[SPDM_NONCE_SIZE];
521 UINT8 ResponderNonce[SPDM_NONCE_SIZE];
522 UINT8 RequestAttribute;
523 UINT32 MeasurementsBlockSize;
524 SPDM_MEASUREMENT_BLOCK_DMTF *MeasurementBlock;
525 UINT8 NumberOfBlock;
526 UINT8 ReceivedNumberOfBlock;
527 UINT8 AuthState;
528 UINT8 ContentChanged;
529 UINT8 ContentChangedCount;
530
531 SpdmContext = SpdmDeviceContext->SpdmContext;
532
533 ZeroMem (&Parameter, sizeof (Parameter));
534 Parameter.location = SpdmDataLocationConnection;
535 DataSize = sizeof (CapabilityFlags);
536 SpdmGetData (SpdmContext, SpdmDataCapabilityFlags, &Parameter, &CapabilityFlags, &DataSize);
537
538 if ((CapabilityFlags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MEAS_CAP_SIG) == 0) {
539 AuthState = TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_AUTH_STATE_FAIL_NO_SIG;
540 Status = ExtendCertificate (SpdmDeviceContext, AuthState, 0, NULL, NULL, 0, 0, SecurityState);
541 SecurityState->MeasurementState = EDKII_DEVICE_SECURITY_STATE_ERROR_DEVICE_NO_CAPABILITIES;
542 if (Status != EFI_SUCCESS) {
543 return Status;
544 } else {
545 return EFI_UNSUPPORTED;
546 }
547 }
548
549 RequestAttribute = 0;
551
552 MeasurementRecordLength = sizeof (MeasurementRecord);
553 ZeroMem (RequesterNonce, sizeof (RequesterNonce));
554 ZeroMem (ResponderNonce, sizeof (ResponderNonce));
555
556 //
557 // get all measurement once, with signature.
558 //
559 SpdmReturn = SpdmGetMeasurementEx (
560 SpdmContext,
561 NULL,
562 RequestAttribute,
564 SlotId,
565 NULL,
566 &NumberOfBlocks,
567 &MeasurementRecordLength,
568 MeasurementRecord,
569 NULL,
570 RequesterNonce,
571 ResponderNonce,
572 NULL,
573 0
574 );
575 if (LIBSPDM_STATUS_IS_SUCCESS (SpdmReturn)) {
576 DEBUG ((DEBUG_INFO, "NumberOfBlocks %d\n", NumberOfBlocks));
577
578 MeasurementBlock = (VOID *)MeasurementRecord;
579 for (Index = 0; Index < NumberOfBlocks; Index++) {
580 MeasurementsBlockSize =
582 MeasurementBlock
583 ->MeasurementBlockDmtfHeader
584 .DMTFSpecMeasurementValueSize;
585
586 AuthState = TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_AUTH_STATE_SUCCESS;
587 SecurityState->MeasurementState = EDKII_DEVICE_SECURITY_STATE_SUCCESS;
588 if (Index == NumberOfBlocks - 1) {
589 Status = ExtendMeasurement (SpdmDeviceContext, AuthState, MeasurementsBlockSize, (UINT8 *)MeasurementBlock, RequesterNonce, ResponderNonce, SecurityState);
590 } else {
591 Status = ExtendMeasurement (SpdmDeviceContext, AuthState, MeasurementsBlockSize, (UINT8 *)MeasurementBlock, NULL, NULL, SecurityState);
592 }
593
594 MeasurementBlock = (VOID *)((size_t)MeasurementBlock + MeasurementsBlockSize);
595 if (Status != EFI_SUCCESS) {
596 return Status;
597 }
598 }
599 } else if (SpdmReturn == LIBSPDM_STATUS_VERIF_FAIL) {
600 AuthState = TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_AUTH_STATE_FAIL_INVALID;
601 SecurityState->MeasurementState = EDKII_DEVICE_SECURITY_STATE_ERROR_MEASUREMENT_AUTH_FAILURE;
602 Status = ExtendMeasurement (SpdmDeviceContext, AuthState, 0, NULL, NULL, NULL, SecurityState);
603 return Status;
604 } else {
605 ContentChangedCount = 0;
606ContentChangedFlag:
607 RequestAttribute = 0;
608 ContentChanged = SPDM_MEASUREMENTS_RESPONSE_CONTENT_NO_CHANGE_DETECTED;
609 ReceivedNumberOfBlock = 0;
610
611 //
612 // 1. Query the total number of measurements available.
613 //
614 SpdmReturn = SpdmGetMeasurement (
615 SpdmContext,
616 NULL,
617 RequestAttribute,
619 SlotId,
620 NULL,
621 &NumberOfBlocks,
622 NULL,
623 NULL
624 );
625 if (LIBSPDM_STATUS_IS_ERROR (SpdmReturn)) {
626 SecurityState->MeasurementState = EDKII_DEVICE_SECURITY_STATE_ERROR_DEVICE_ERROR;
627 return EFI_DEVICE_ERROR;
628 }
629
630 DEBUG ((DEBUG_INFO, "NumberOfBlocks - 0x%x\n", NumberOfBlocks));
631
632 ReceivedNumberOfBlock = 0;
633 for (Index = 1; Index <= 0xFE; Index++) {
634 if (ReceivedNumberOfBlock == NumberOfBlocks) {
635 break;
636 }
637
638 DEBUG ((DEBUG_INFO, "Index - 0x%x\n", Index));
639 //
640 // 2. query measurement one by one
641 // get signature in last message only.
642 //
643 if (ReceivedNumberOfBlock == NumberOfBlocks - 1) {
645 }
646
647 MeasurementRecordLength = sizeof (MeasurementRecord);
648 ZeroMem (RequesterNonce, sizeof (RequesterNonce));
649 ZeroMem (ResponderNonce, sizeof (ResponderNonce));
650 SpdmReturn = SpdmGetMeasurementEx (
651 SpdmContext,
652 NULL,
653 RequestAttribute,
654 Index,
655 SlotId,
656 &ContentChanged,
657 &NumberOfBlock,
658 &MeasurementRecordLength,
659 MeasurementRecord,
660 NULL,
661 RequesterNonce,
662 ResponderNonce,
663 NULL,
664 0
665 );
666 if (LIBSPDM_STATUS_IS_ERROR (SpdmReturn)) {
667 if (SpdmReturn == LIBSPDM_STATUS_VERIF_FAIL) {
668 AuthState = TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_AUTH_STATE_FAIL_INVALID;
669 SecurityState->MeasurementState = EDKII_DEVICE_SECURITY_STATE_ERROR_DEVICE_ERROR;
670 Status = ExtendMeasurement (SpdmDeviceContext, AuthState, 0, NULL, NULL, NULL, SecurityState);
671 return Status;
672 } else {
673 continue;
674 }
675 }
676
677 if ((ReceivedNumberOfBlock == NumberOfBlocks - 1) &&
678 (ContentChanged == SPDM_MEASUREMENTS_RESPONSE_CONTENT_CHANGE_DETECTED))
679 {
680 if (ContentChangedCount == 0) {
681 ContentChangedCount++;
682 goto ContentChangedFlag;
683 } else {
684 AuthState = TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_AUTH_STATE_FAIL_INVALID;
685 SecurityState->MeasurementState = EDKII_DEVICE_SECURITY_STATE_ERROR_DEVICE_ERROR;
686 Status = ExtendMeasurement (SpdmDeviceContext, AuthState, 0, NULL, NULL, NULL, SecurityState);
687 return Status;
688 }
689 }
690
691 DEBUG ((DEBUG_INFO, "ExtendMeasurement...\n"));
692 AuthState = TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_AUTH_STATE_SUCCESS;
693 SecurityState->MeasurementState = EDKII_DEVICE_SECURITY_STATE_SUCCESS;
694 if (ReceivedNumberOfBlock == NumberOfBlocks - 1) {
695 Status = ExtendMeasurement (SpdmDeviceContext, AuthState, MeasurementRecordLength, MeasurementRecord, RequesterNonce, ResponderNonce, SecurityState);
696 } else {
697 Status = ExtendMeasurement (SpdmDeviceContext, AuthState, MeasurementRecordLength, MeasurementRecord, NULL, ResponderNonce, SecurityState);
698 }
699
700 if (Status != EFI_SUCCESS) {
701 return Status;
702 }
703
704 ReceivedNumberOfBlock += 1;
705 }
706
707 if (ReceivedNumberOfBlock != NumberOfBlocks) {
708 SecurityState->MeasurementState = EDKII_DEVICE_SECURITY_STATE_ERROR_MEASUREMENT_AUTH_FAILURE;
709 return EFI_DEVICE_ERROR;
710 }
711 }
712
713 return EFI_SUCCESS;
714}
UINT64 UINTN
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
BOOLEAN EFIAPI CompareGuid(IN CONST GUID *Guid1, IN CONST GUID *Guid2)
Definition: MemLibGuid.c:73
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
UINTN EFIAPI GetDevicePathSize(IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath)
EFI_GUID gEdkiiDeviceIdentifierTypePciGuid
#define EDKII_DEVICE_SECURITY_STATE_SUCCESS
VOID EFIAPI FreePool(IN VOID *Buffer)
#define NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define ASSERT_EFI_ERROR(StatusParameter)
Definition: DebugLib.h:462
#define DEBUG(Expression)
Definition: DebugLib.h:434
VOID *EFIAPI AllocatePool(IN UINTN AllocationSize)
#define SPDM_MEASUREMENT_BLOCK_MEASUREMENT_TYPE_IMMUTABLE_ROM
Definition: Spdm.h:671
#define SPDM_GET_MEASUREMENTS_REQUEST_MEASUREMENT_OPERATION_TOTAL_NUMBER_OF_MEASUREMENTS
Definition: Spdm.h:629
#define SPDM_GET_MEASUREMENTS_REQUEST_MEASUREMENT_OPERATION_ALL_MEASUREMENTS
Definition: Spdm.h:634
#define SPDM_GET_MEASUREMENTS_REQUEST_ATTRIBUTES_GENERATE_SIGNATURE
Definition: Spdm.h:622
EFI_STATUS ExtendCertificate(IN SPDM_DEVICE_CONTEXT *SpdmDeviceContext, IN UINT8 AuthState, IN UINTN CertChainSize, IN UINT8 *CertChain, IN VOID *TrustAnchor, IN UINTN TrustAnchorSize, IN UINT8 SlotId, OUT EDKII_DEVICE_SECURITY_STATE *SecurityState)
VOID EFIAPI InternalDumpData(CONST UINT8 *Data, UINTN Size)
EFI_STATUS EFIAPI CreateDeviceMeasurementContext(IN SPDM_DEVICE_CONTEXT *SpdmDeviceContext, IN OUT VOID *DeviceContext, IN UINTN DeviceContextSize)
EFI_STATUS ExtendMeasurement(IN SPDM_DEVICE_CONTEXT *SpdmDeviceContext, IN UINT8 AuthState, IN UINT32 MeasurementRecordLength, IN UINT8 *MeasurementRecord, IN UINT8 *RequesterNonce, IN UINT8 *ResponderNonce, OUT EDKII_DEVICE_SECURITY_STATE *SecurityState)
EFI_STATUS EFIAPI DoDeviceMeasurement(IN SPDM_DEVICE_CONTEXT *SpdmDeviceContext, IN UINT8 SlotId, OUT EDKII_DEVICE_SECURITY_STATE *SecurityState)
EFI_STATUS CreatePciDeviceMeasurementContext(IN SPDM_DEVICE_CONTEXT *SpdmDeviceContext, IN OUT VOID *DeviceContext, IN UINTN DeviceContextSize)
UINT32 EFIAPI GetSpdmDeviceType(IN SPDM_DEVICE_CONTEXT *SpdmDeviceContext)
UINTN EFIAPI GetDeviceMeasurementContextSize(IN SPDM_DEVICE_CONTEXT *SpdmDeviceContext)
EFI_STATUS EFIAPI TpmMeasureAndLogData(IN UINT32 PcrIndex, IN UINT32 EventType, IN VOID *EventLog, IN UINT32 LogLen, IN VOID *HashData, IN UINT64 HashDataLen)
VOID EFIAPI Exit(IN EFI_STATUS Status)
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_PCI_IO_PROTOCOL_CONFIG Read
Definition: PciIo.h:232