summaryrefslogtreecommitdiff
path: root/SecurityPkg/DeviceSecurity/SpdmSecurityLib/SpdmSecurityLib.c
diff options
context:
space:
mode:
Diffstat (limited to 'SecurityPkg/DeviceSecurity/SpdmSecurityLib/SpdmSecurityLib.c')
-rw-r--r--SecurityPkg/DeviceSecurity/SpdmSecurityLib/SpdmSecurityLib.c148
1 files changed, 148 insertions, 0 deletions
diff --git a/SecurityPkg/DeviceSecurity/SpdmSecurityLib/SpdmSecurityLib.c b/SecurityPkg/DeviceSecurity/SpdmSecurityLib/SpdmSecurityLib.c
new file mode 100644
index 0000000..f438c16
--- /dev/null
+++ b/SecurityPkg/DeviceSecurity/SpdmSecurityLib/SpdmSecurityLib.c
@@ -0,0 +1,148 @@
+/** @file
+ EDKII Device Security library for SPDM device.
+ It follows the SPDM Specification.
+
+Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "SpdmSecurityLibInternal.h"
+
+/**
+ Helper function to quickly determine whether device authentication boot is enabled.
+
+ @retval TRUE device authentication boot is verifiably enabled.
+ @retval FALSE device authentication boot is either disabled or an error prevented checking.
+
+**/
+BOOLEAN
+EFIAPI
+IsDeviceAuthBootEnabled (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ UINT8 *DeviceAuthBootMode;
+
+ DeviceAuthBootMode = NULL;
+
+ Status = GetEfiGlobalVariable2 (EFI_DEVICE_AUTH_BOOT_MODE_NAME, (VOID **)&DeviceAuthBootMode, NULL);
+ //
+ // Skip verification if DeviceAuthBootMode variable doesn't exist.
+ //
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "Cannot check DeviceAuthBootMode variable %r \n ", Status));
+ return FALSE;
+ }
+
+ //
+ // Skip verification if DeviceAuthBootMode is disabled but not AuditMode
+ //
+ if (*DeviceAuthBootMode == DEVICE_AUTH_BOOT_MODE_DISABLE) {
+ FreePool (DeviceAuthBootMode);
+ return FALSE;
+ } else {
+ FreePool (DeviceAuthBootMode);
+ return TRUE;
+ }
+}
+
+/**
+ The device driver uses this service to authenticate and measure an SPDM device.
+
+ @param[in] SpdmDeviceInfo The SPDM context for the device.
+ @param[in] SecurityPolicy The security policy of this device.
+ @param[out] SecurityState A pointer to security state if this device.
+
+ @retval EFI_SUCCESS The TCG SPDM device measurement context is returned.
+ @retval EFI_UNSUPPORTED The TCG SPDM device measurement context is unsupported.
+
+**/
+EFI_STATUS
+EFIAPI
+SpdmDeviceAuthenticationAndMeasurement (
+ IN EDKII_SPDM_DEVICE_INFO *SpdmDeviceInfo,
+ IN EDKII_DEVICE_SECURITY_POLICY *SecurityPolicy,
+ OUT EDKII_DEVICE_SECURITY_STATE *SecurityState
+ )
+{
+ EFI_STATUS Status;
+ SPDM_DEVICE_CONTEXT *SpdmDeviceContext;
+ UINT8 AuthState;
+ UINT8 SlotId;
+ BOOLEAN IsValidCertChain;
+ BOOLEAN RootCertMatch;
+
+ if ((PcdGet32 (PcdTcgPfpMeasurementRevision) < TCG_EfiSpecIDEventStruct_SPEC_ERRATA_TPM2_REV_106) ||
+ (PcdGet8 (PcdEnableSpdmDeviceAuthentication) == 0))
+ {
+ return EFI_UNSUPPORTED;
+ }
+
+ SpdmDeviceContext = CreateSpdmDeviceContext (SpdmDeviceInfo, SecurityState);
+ if (SpdmDeviceContext == NULL) {
+ return EFI_UNSUPPORTED;
+ }
+
+ Status = EFI_SUCCESS;
+ AuthState = TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_AUTH_STATE_SUCCESS;
+ SlotId = 0;
+ IsValidCertChain = FALSE;
+ RootCertMatch = FALSE;
+
+ if (((SecurityPolicy->AuthenticationPolicy & EDKII_DEVICE_AUTHENTICATION_REQUIRED) != 0) ||
+ ((SecurityPolicy->MeasurementPolicy & EDKII_DEVICE_MEASUREMENT_REQUIRED) != 0))
+ {
+ Status = DoDeviceCertificate (SpdmDeviceContext, &AuthState, &SlotId, SecurityState, &IsValidCertChain, &RootCertMatch);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "DoDeviceCertificate failed - %r\n", Status));
+ goto Ret;
+ } else if ((AuthState == TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_AUTH_STATE_FAIL_NO_SIG) ||
+ (AuthState == TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_AUTH_STATE_FAIL_INVALID))
+ {
+ goto Ret;
+ }
+ }
+
+ if (((SecurityPolicy->AuthenticationPolicy & EDKII_DEVICE_AUTHENTICATION_REQUIRED) != 0) && (IsDeviceAuthBootEnabled ())) {
+ Status = DoDeviceAuthentication (SpdmDeviceContext, &AuthState, SlotId, IsValidCertChain, RootCertMatch, SecurityState);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "DoDeviceAuthentication failed - %r\n", Status));
+ goto Ret;
+ } else if ((AuthState == TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_AUTH_STATE_FAIL_NO_SIG) ||
+ (AuthState == TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_AUTH_STATE_FAIL_INVALID))
+ {
+ goto Ret;
+ }
+ }
+
+ if ((SecurityPolicy->MeasurementPolicy & EDKII_DEVICE_MEASUREMENT_REQUIRED) != 0) {
+ Status = DoDeviceMeasurement (SpdmDeviceContext, SlotId, SecurityState);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "DoDeviceMeasurement failed - %r\n", Status));
+ }
+ }
+
+Ret:
+ DestroySpdmDeviceContext (SpdmDeviceContext);
+
+ return Status;
+}
+
+/**
+ This function will get SpdmIoProtocol via Context.
+
+ @param[in] SpdmContext The SPDM context for the device.
+
+ return the pointer of Spdm Io protocol
+
+**/
+VOID *
+EFIAPI
+SpdmGetIoProtocolViaSpdmContext (
+ IN VOID *SpdmContext
+ )
+{
+ return GetSpdmIoProtocolViaSpdmContext (SpdmContext);
+}