From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail05.groups.io (mail05.groups.io [45.79.224.7]) by spool.mail.gandi.net (Postfix) with ESMTPS id 335027803D7 for ; Thu, 18 Apr 2024 09:28:37 +0000 (UTC) DKIM-Signature: a=rsa-sha256; bh=cKPMdhzl+dRufqaJVN9S55NsQoimsl5ZWR3c8EYMoQc=; c=relaxed/simple; d=groups.io; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References:MIME-Version:Precedence:List-Subscribe:List-Help:Sender:List-Id:Mailing-List:Delivered-To:Resent-Date:Resent-From:Reply-To:List-Unsubscribe-Post:List-Unsubscribe:Content-Transfer-Encoding; s=20240206; t=1713432515; v=1; b=hBCGe/OndEzvaVSxq2k8n2TNrgar9l4QNtU+18bLREVyVsQcb6+IY5LQLQyYQJuDiqpa6g1q 12Jefv2WnHieiNPny2AoyxjkMrpqYY+m+EzJQIJHWSjaY46n2Bqnx0t348sN2XzbMV9jJGmjK4/ bM+LTz/nE1NqS2Hfr3CDpBy2isBfM+vAt1KM7NQ8YPhMY4ljrHnmDGLJDwGcGbNZ39+Sq97JSzl h84XrbWon9HJEh2GZ1lS/cvaFti9LZiAuCuTd+NIV0rm8oXt/G86D7Rxfr52QoBoIz/hEVkr7fr asTIkt+PnkNw4hni8SLFBHyzzTfzTd/Qu9GMynvfqithA== X-Received: by 127.0.0.2 with SMTP id O9DeYY7687511xeH86n5WtyH; Thu, 18 Apr 2024 02:28:35 -0700 X-Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.8]) by mx.groups.io with SMTP id smtpd.web10.8624.1713432504284175070 for ; Thu, 18 Apr 2024 02:28:35 -0700 X-CSE-ConnectionGUID: BkhjLtDVRRu5KZbAmarY8A== X-CSE-MsgGUID: 42JflJwvRiq4MrjdqzK2BA== X-IronPort-AV: E=McAfee;i="6600,9927,11047"; a="26476954" X-IronPort-AV: E=Sophos;i="6.07,211,1708416000"; d="scan'208";a="26476954" X-Received: from fmviesa002.fm.intel.com ([10.60.135.142]) by fmvoesa102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 18 Apr 2024 02:28:34 -0700 X-CSE-ConnectionGUID: yrbPNqoGSWCXo+juissihA== X-CSE-MsgGUID: vAwzqqwnTMCcsYKKziOcmg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.07,211,1708416000"; d="scan'208";a="46210362" X-Received: from shwdejointd777.ccr.corp.intel.com ([10.239.58.116]) by fmviesa002.fm.intel.com with ESMTP; 18 Apr 2024 02:28:32 -0700 From: "Wenxing Hou" To: devel@edk2.groups.io Cc: Jiewen Yao Subject: [edk2-devel] [PATCH v4 06/10] SecurityPkg: add DeviceSecurity support Date: Thu, 18 Apr 2024 17:28:15 +0800 Message-Id: <20240418092819.6570-7-wenxing.hou@intel.com> In-Reply-To: <20240418092819.6570-1-wenxing.hou@intel.com> References: <20240418092819.6570-1-wenxing.hou@intel.com> MIME-Version: 1.0 Precedence: Bulk List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Resent-Date: Thu, 18 Apr 2024 02:28:35 -0700 Resent-From: wenxing.hou@intel.com Reply-To: devel@edk2.groups.io,wenxing.hou@intel.com List-Unsubscribe-Post: List-Unsubscribe=One-Click List-Unsubscribe: X-Gm-Message-State: NeywKbWlayUqzavDsVEhEs7Rx7686176AA= Content-Transfer-Encoding: quoted-printable X-GND-Status: LEGIT Authentication-Results: spool.mail.gandi.net; dkim=pass header.d=groups.io header.s=20240206 header.b="hBCGe/On"; dmarc=fail reason="SPF not aligned (relaxed), DKIM not aligned (relaxed)" header.from=intel.com (policy=none); spf=pass (spool.mail.gandi.net: domain of bounce@groups.io designates 45.79.224.7 as permitted sender) smtp.mailfrom=bounce@groups.io This patch implement the SpdmSecurityLib, which is the core of DeviceSecurity. And the SpdmSecurityLib include Device Authentication and Measurement. The other library is to support SpdmSecurityLib. Cc: Jiewen Yao Signed-off-by: Wenxing Hou Reviewed-by: Jiewen Yao --- .../OsStub/CryptlibWrapper/CryptlibWrapper.c | 970 ++++++++++++++++++ .../CryptlibWrapper/CryptlibWrapper.inf | 38 + .../OsStub/MemLibWrapper/MemLibWrapper.c | 177 ++++ .../OsStub/MemLibWrapper/MemLibWrapper.inf | 33 + .../PlatformLibWrapper/PlatformLibWrapper.c | 85 ++ .../PlatformLibWrapper/PlatformLibWrapper.inf | 33 + .../SpdmLib/Include/Stub/SpdmLibStub.h | 347 +++++++ .../SpdmLib/Include/hal/LibspdmStdBoolAlt.h | 23 + .../SpdmLib/Include/hal/LibspdmStdDefAlt.h | 16 + .../SpdmLib/Include/hal/LibspdmStdIntAlt.h | 25 + .../DeviceSecurity/SpdmLib/Include/hal/base.h | 94 ++ .../SpdmLib/Include/hal/library/debuglib.h | 39 + .../SpdmLib/Include/library/spdm_lib_config.h | 394 +++++++ .../DeviceSecurity/SpdmLib/SpdmCommonLib.inf | 47 + .../DeviceSecurity/SpdmLib/SpdmCryptLib.inf | 45 + .../SpdmLib/SpdmDeviceSecretLibNull.inf | 36 + .../SpdmLib/SpdmRequesterLib.inf | 59 ++ .../SpdmLib/SpdmResponderLib.inf | 61 ++ .../SpdmLib/SpdmSecuredMessageLib.inf | 44 + .../SpdmLib/SpdmTransportMctpLib.inf | 38 + .../SpdmLib/SpdmTransportPciDoeLib.inf | 38 + .../SpdmSecurityLib/SpdmAuthentication.c | 697 +++++++++++++ .../SpdmSecurityLib/SpdmConnectionInit.c | 481 +++++++++ .../SpdmSecurityLib/SpdmMeasurement.c | 714 +++++++++++++ .../SpdmSecurityLib/SpdmSecurityLib.c | 148 +++ .../SpdmSecurityLib/SpdmSecurityLib.inf | 54 + .../SpdmSecurityLib/SpdmSecurityLibInternal.h | 250 +++++ SecurityPkg/Include/Library/SpdmSecurityLib.h | 437 ++++++++ .../Include/Protocol/DeviceSecurityPolicy.h | 133 +++ SecurityPkg/SecurityPkg.ci.yaml | 17 +- SecurityPkg/SecurityPkg.dec | 13 +- SecurityPkg/SecurityPkg.dsc | 31 +- 32 files changed, 5611 insertions(+), 6 deletions(-) create mode 100644 SecurityPkg/DeviceSecurity/OsStub/CryptlibWrapper/Crypt= libWrapper.c create mode 100644 SecurityPkg/DeviceSecurity/OsStub/CryptlibWrapper/Crypt= libWrapper.inf create mode 100644 SecurityPkg/DeviceSecurity/OsStub/MemLibWrapper/MemLibW= rapper.c create mode 100644 SecurityPkg/DeviceSecurity/OsStub/MemLibWrapper/MemLibW= rapper.inf create mode 100644 SecurityPkg/DeviceSecurity/OsStub/PlatformLibWrapper/Pl= atformLibWrapper.c create mode 100644 SecurityPkg/DeviceSecurity/OsStub/PlatformLibWrapper/Pl= atformLibWrapper.inf create mode 100644 SecurityPkg/DeviceSecurity/SpdmLib/Include/Stub/SpdmLib= Stub.h create mode 100644 SecurityPkg/DeviceSecurity/SpdmLib/Include/hal/LibspdmS= tdBoolAlt.h create mode 100644 SecurityPkg/DeviceSecurity/SpdmLib/Include/hal/LibspdmS= tdDefAlt.h create mode 100644 SecurityPkg/DeviceSecurity/SpdmLib/Include/hal/LibspdmS= tdIntAlt.h create mode 100644 SecurityPkg/DeviceSecurity/SpdmLib/Include/hal/base.h create mode 100644 SecurityPkg/DeviceSecurity/SpdmLib/Include/hal/library/= debuglib.h create mode 100644 SecurityPkg/DeviceSecurity/SpdmLib/Include/library/spdm= _lib_config.h create mode 100644 SecurityPkg/DeviceSecurity/SpdmLib/SpdmCommonLib.inf create mode 100644 SecurityPkg/DeviceSecurity/SpdmLib/SpdmCryptLib.inf create mode 100644 SecurityPkg/DeviceSecurity/SpdmLib/SpdmDeviceSecretLibN= ull.inf create mode 100644 SecurityPkg/DeviceSecurity/SpdmLib/SpdmRequesterLib.inf create mode 100644 SecurityPkg/DeviceSecurity/SpdmLib/SpdmResponderLib.inf create mode 100644 SecurityPkg/DeviceSecurity/SpdmLib/SpdmSecuredMessageLi= b.inf create mode 100644 SecurityPkg/DeviceSecurity/SpdmLib/SpdmTransportMctpLib= .inf create mode 100644 SecurityPkg/DeviceSecurity/SpdmLib/SpdmTransportPciDoeL= ib.inf create mode 100644 SecurityPkg/DeviceSecurity/SpdmSecurityLib/SpdmAuthenti= cation.c create mode 100644 SecurityPkg/DeviceSecurity/SpdmSecurityLib/SpdmConnecti= onInit.c create mode 100644 SecurityPkg/DeviceSecurity/SpdmSecurityLib/SpdmMeasurem= ent.c create mode 100644 SecurityPkg/DeviceSecurity/SpdmSecurityLib/SpdmSecurity= Lib.c create mode 100644 SecurityPkg/DeviceSecurity/SpdmSecurityLib/SpdmSecurity= Lib.inf create mode 100644 SecurityPkg/DeviceSecurity/SpdmSecurityLib/SpdmSecurity= LibInternal.h create mode 100644 SecurityPkg/Include/Library/SpdmSecurityLib.h create mode 100644 SecurityPkg/Include/Protocol/DeviceSecurityPolicy.h diff --git a/SecurityPkg/DeviceSecurity/OsStub/CryptlibWrapper/CryptlibWrap= per.c b/SecurityPkg/DeviceSecurity/OsStub/CryptlibWrapper/CryptlibWrapper.c new file mode 100644 index 0000000000..64db9750ff --- /dev/null +++ b/SecurityPkg/DeviceSecurity/OsStub/CryptlibWrapper/CryptlibWrapper.c @@ -0,0 +1,970 @@ +/** @file=0D + EDKII Device Security library for SPDM device.=0D + It follows the SPDM Specification.=0D +=0D +Copyright (c) 2024, Intel Corporation. All rights reserved.
=0D +SPDX-License-Identifier: BSD-2-Clause-Patent=0D +=0D +**/=0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include "hal/base.h"=0D +#include "hal/library/cryptlib.h"=0D +=0D +void *=0D +libspdm_sha256_new (=0D + void=0D + )=0D +{=0D + size_t CtxSize;=0D + void *HashCtx;=0D +=0D + HashCtx =3D NULL;=0D + CtxSize =3D Sha256GetContextSize ();=0D + HashCtx =3D AllocatePool (CtxSize);=0D +=0D + return HashCtx;=0D +}=0D +=0D +void=0D +libspdm_sha256_free (=0D + void *Sha256Ctx=0D + )=0D +{=0D + if (Sha256Ctx !=3D NULL) {=0D + FreePool (Sha256Ctx);=0D + Sha256Ctx =3D NULL;=0D + }=0D +}=0D +=0D +bool=0D +libspdm_sha256_init (=0D + void *Sha256Ctx=0D + )=0D +{=0D + return Sha256Init (Sha256Ctx);=0D +}=0D +=0D +bool=0D +libspdm_sha256_duplicate (=0D + const void *Sha256Context,=0D + void *NewSha256Context=0D + )=0D +{=0D + return Sha256Duplicate (Sha256Context, NewSha256Context);=0D +}=0D +=0D +bool=0D +libspdm_sha256_update (=0D + void *Sha256Context,=0D + const void *Data,=0D + size_t DataSize=0D + )=0D +{=0D + return Sha256Update (Sha256Context, Data, DataSize);=0D +}=0D +=0D +bool=0D +libspdm_sha256_final (=0D + void *sha256_context,=0D + uint8_t *hash_value=0D + )=0D +{=0D + return Sha256Final (sha256_context, hash_value);=0D +}=0D +=0D +bool=0D +libspdm_sha256_hash_all (=0D + const void *data,=0D + size_t data_size,=0D + uint8_t *hash_value=0D + )=0D +{=0D + return Sha256HashAll (data, data_size, hash_value);=0D +}=0D +=0D +void *=0D +libspdm_sha384_new (=0D + void=0D + )=0D +{=0D + size_t CtxSize;=0D + void *HashCtx;=0D +=0D + HashCtx =3D NULL;=0D + CtxSize =3D Sha384GetContextSize ();=0D + HashCtx =3D AllocatePool (CtxSize);=0D +=0D + return HashCtx;=0D +}=0D +=0D +void=0D +libspdm_sha384_free (=0D + void *Sha384Ctx=0D + )=0D +{=0D + if (Sha384Ctx !=3D NULL) {=0D + FreePool (Sha384Ctx);=0D + Sha384Ctx =3D NULL;=0D + }=0D +}=0D +=0D +bool=0D +libspdm_sha384_init (=0D + void *sha384_context=0D + )=0D +{=0D + return Sha384Init (sha384_context);=0D +}=0D +=0D +bool=0D +libspdm_sha384_duplicate (=0D + const void *sha384_context,=0D + void *new_sha384_context=0D + )=0D +{=0D + return Sha384Duplicate (sha384_context, new_sha384_context);=0D +}=0D +=0D +bool=0D +libspdm_sha384_update (=0D + void *sha384_context,=0D + const void *data,=0D + size_t data_size=0D + )=0D +{=0D + return Sha384Update (sha384_context, data, data_size);=0D +}=0D +=0D +bool=0D +libspdm_sha384_final (=0D + void *sha384_context,=0D + uint8_t *hash_value=0D + )=0D +{=0D + return Sha384Final (sha384_context, hash_value);=0D +}=0D +=0D +bool=0D +libspdm_sha384_hash_all (=0D + const void *data,=0D + size_t data_size,=0D + uint8_t *hash_value=0D + )=0D +{=0D + return Sha384HashAll (data, data_size, hash_value);=0D +}=0D +=0D +void *=0D +libspdm_hmac_sha256_new (=0D + void=0D + )=0D +{=0D + return HmacSha256New ();=0D +}=0D +=0D +void=0D +libspdm_hmac_sha256_free (=0D + void *hmac_sha256_ctx=0D + )=0D +{=0D + HmacSha256Free (hmac_sha256_ctx);=0D +}=0D +=0D +bool=0D +libspdm_hmac_sha256_set_key (=0D + void *hmac_sha256_ctx,=0D + const uint8_t *key,=0D + size_t key_size=0D + )=0D +{=0D + return HmacSha256SetKey (hmac_sha256_ctx, key, key_size);=0D +}=0D +=0D +bool=0D +libspdm_hmac_sha256_duplicate (=0D + const void *hmac_sha256_ctx,=0D + void *new_hmac_sha256_ctx=0D + )=0D +{=0D + return HmacSha256Duplicate (hmac_sha256_ctx, new_hmac_sha256_ctx);=0D +}=0D +=0D +bool=0D +libspdm_hmac_sha256_update (=0D + void *hmac_sha256_ctx,=0D + const void *data,=0D + size_t data_size=0D + )=0D +{=0D + return HmacSha256Update (hmac_sha256_ctx, data, data_size);=0D +}=0D +=0D +bool=0D +libspdm_hmac_sha256_final (=0D + void *hmac_sha256_ctx,=0D + uint8_t *hmac_value=0D + )=0D +{=0D + return HmacSha256Final (hmac_sha256_ctx, hmac_value);=0D +}=0D +=0D +bool=0D +libspdm_hmac_sha256_all (=0D + const void *data,=0D + size_t data_size,=0D + const uint8_t *key,=0D + size_t key_size,=0D + uint8_t *hmac_value=0D + )=0D +{=0D + return HmacSha256All (data, data_size, key, key_size, hmac_value);=0D +}=0D +=0D +void *=0D +libspdm_hmac_sha384_new (=0D + void=0D + )=0D +{=0D + return HmacSha384New ();=0D +}=0D +=0D +void=0D +libspdm_hmac_sha384_free (=0D + void *hmac_sha384_ctx=0D + )=0D +{=0D + HmacSha384Free (hmac_sha384_ctx);=0D +}=0D +=0D +bool=0D +libspdm_hmac_sha384_set_key (=0D + void *hmac_sha384_ctx,=0D + const uint8_t *key,=0D + size_t key_size=0D + )=0D +{=0D + return HmacSha384SetKey (hmac_sha384_ctx, key, key_size);=0D +}=0D +=0D +bool=0D +libspdm_hmac_sha384_duplicate (=0D + const void *hmac_sha384_ctx,=0D + void *new_hmac_sha384_ctx=0D + )=0D +{=0D + return HmacSha384Duplicate (hmac_sha384_ctx, new_hmac_sha384_ctx);=0D +}=0D +=0D +bool=0D +libspdm_hmac_sha384_update (=0D + void *hmac_sha384_ctx,=0D + const void *data,=0D + size_t data_size=0D + )=0D +{=0D + return HmacSha384Update (hmac_sha384_ctx, data, data_size);=0D +}=0D +=0D +bool=0D +libspdm_hmac_sha384_final (=0D + void *hmac_sha384_ctx,=0D + uint8_t *hmac_value=0D + )=0D +{=0D + return HmacSha384Final (hmac_sha384_ctx, hmac_value);=0D +}=0D +=0D +bool=0D +libspdm_hmac_sha384_all (=0D + const void *data,=0D + size_t data_size,=0D + const uint8_t *key,=0D + size_t key_size,=0D + uint8_t *hmac_value=0D + )=0D +{=0D + return HmacSha384All (data, data_size, key, key_size, hmac_value);=0D +}=0D +=0D +bool=0D +libspdm_aead_aes_gcm_encrypt (=0D + const uint8_t *key,=0D + size_t key_size,=0D + const uint8_t *iv,=0D + size_t iv_size,=0D + const uint8_t *a_data,=0D + size_t a_data_size,=0D + const uint8_t *data_in,=0D + size_t data_in_size,=0D + uint8_t *tag_out,=0D + size_t tag_size,=0D + uint8_t *data_out,=0D + size_t *data_out_size=0D + )=0D +{=0D + return AeadAesGcmEncrypt (=0D + key,=0D + key_size,=0D + iv,=0D + iv_size,=0D + a_data,=0D + a_data_size,=0D + data_in,=0D + data_in_size,=0D + tag_out,=0D + tag_size,=0D + data_out,=0D + data_out_size=0D + );=0D +}=0D +=0D +bool=0D +libspdm_aead_aes_gcm_decrypt (=0D + const uint8_t *key,=0D + size_t key_size,=0D + const uint8_t *iv,=0D + size_t iv_size,=0D + const uint8_t *a_data,=0D + size_t a_data_size,=0D + const uint8_t *data_in,=0D + size_t data_in_size,=0D + const uint8_t *tag,=0D + size_t tag_size,=0D + uint8_t *data_out,=0D + size_t *data_out_size=0D + )=0D +{=0D + return AeadAesGcmDecrypt (=0D + key,=0D + key_size,=0D + iv,=0D + iv_size,=0D + a_data,=0D + a_data_size,=0D + data_in,=0D + data_in_size,=0D + tag,=0D + tag_size,=0D + data_out,=0D + data_out_size=0D + );=0D +}=0D +=0D +void=0D +libspdm_rsa_free (=0D + void *rsa_context=0D + )=0D +{=0D + RsaFree (rsa_context);=0D +}=0D +=0D +bool=0D +libspdm_rsa_pkcs1_sign_with_nid (=0D + void *rsa_context,=0D + size_t hash_nid,=0D + const uint8_t *message_hash,=0D + size_t hash_size,=0D + uint8_t *signature,=0D + size_t *sig_size=0D + )=0D +{=0D + switch (hash_nid) {=0D + case CRYPTO_NID_SHA256:=0D + if (hash_size !=3D SHA256_DIGEST_SIZE) {=0D + return FALSE;=0D + }=0D +=0D + break;=0D +=0D + case CRYPTO_NID_SHA384:=0D + if (hash_size !=3D SHA384_DIGEST_SIZE) {=0D + return FALSE;=0D + }=0D +=0D + break;=0D +=0D + case CRYPTO_NID_SHA512:=0D + if (hash_size !=3D SHA512_DIGEST_SIZE) {=0D + return FALSE;=0D + }=0D +=0D + break;=0D +=0D + default:=0D + return FALSE;=0D + }=0D +=0D + return RsaPkcs1Sign (=0D + rsa_context,=0D + message_hash,=0D + hash_size,=0D + signature,=0D + sig_size=0D + );=0D +}=0D +=0D +bool=0D +libspdm_rsa_pkcs1_verify_with_nid (=0D + void *rsa_context,=0D + size_t hash_nid,=0D + const uint8_t *message_hash,=0D + size_t hash_size,=0D + const uint8_t *signature,=0D + size_t sig_size=0D + )=0D +{=0D + switch (hash_nid) {=0D + case CRYPTO_NID_SHA256:=0D + if (hash_size !=3D SHA256_DIGEST_SIZE) {=0D + return false;=0D + }=0D +=0D + break;=0D +=0D + case CRYPTO_NID_SHA384:=0D + if (hash_size !=3D SHA384_DIGEST_SIZE) {=0D + return false;=0D + }=0D +=0D + break;=0D +=0D + case CRYPTO_NID_SHA512:=0D + if (hash_size !=3D SHA512_DIGEST_SIZE) {=0D + return false;=0D + }=0D +=0D + break;=0D +=0D + default:=0D + return false;=0D + }=0D +=0D + return RsaPkcs1Verify (=0D + rsa_context,=0D + message_hash,=0D + hash_size,=0D + signature,=0D + sig_size=0D + );=0D +}=0D +=0D +bool=0D +libspdm_rsa_get_private_key_from_pem (=0D + const uint8_t *pem_data,=0D + size_t pem_size,=0D + const char *password,=0D + void **rsa_context=0D + )=0D +{=0D + return RsaGetPrivateKeyFromPem (pem_data, pem_size, password, rsa_contex= t);=0D +}=0D +=0D +bool=0D +libspdm_rsa_get_public_key_from_x509 (=0D + const uint8_t *cert,=0D + size_t cert_size,=0D + void **rsa_context=0D + )=0D +{=0D + return RsaGetPublicKeyFromX509 (cert, cert_size, rsa_context);=0D +}=0D +=0D +bool=0D +libspdm_ec_get_public_key_from_der (=0D + const uint8_t *der_data,=0D + size_t der_size,=0D + void **ec_context=0D + )=0D +{=0D + return false;=0D +}=0D +=0D +bool=0D +libspdm_rsa_get_public_key_from_der (=0D + const uint8_t *der_data,=0D + size_t der_size,=0D + void **rsa_context=0D + )=0D +{=0D + return false;=0D +}=0D +=0D +bool=0D +libspdm_ec_get_private_key_from_pem (=0D + const uint8_t *pem_data,=0D + size_t pem_size,=0D + const char *password,=0D + void **ec_context=0D + )=0D +{=0D + return EcGetPrivateKeyFromPem (pem_data, pem_size, password, ec_context)= ;=0D +}=0D +=0D +bool=0D +libspdm_ec_get_public_key_from_x509 (=0D + const uint8_t *cert,=0D + size_t cert_size,=0D + void **ec_context=0D + )=0D +{=0D + return EcGetPublicKeyFromX509 (cert, cert_size, ec_context);=0D +}=0D +=0D +bool=0D +libspdm_asn1_get_tag (=0D + uint8_t **ptr,=0D + const uint8_t *end,=0D + size_t *length,=0D + uint32_t tag=0D + )=0D +{=0D + return Asn1GetTag (ptr, end, length, tag);=0D +}=0D +=0D +bool=0D +libspdm_x509_get_subject_name (=0D + const uint8_t *cert,=0D + size_t cert_size,=0D + uint8_t *cert_subject,=0D + size_t *subject_size=0D + )=0D +{=0D + return X509GetSubjectName (cert, cert_size, cert_subject, subject_size);= =0D +}=0D +=0D +bool=0D +libspdm_x509_get_common_name (=0D + const uint8_t *cert,=0D + size_t cert_size,=0D + char *common_name,=0D + size_t *common_name_size=0D + )=0D +{=0D + EFI_STATUS Status;=0D +=0D + Status =3D X509GetCommonName (cert, cert_size, common_name, common_name_= size);=0D + if (EFI_ERROR (Status)) {=0D + return false;=0D + } else {=0D + return true;=0D + }=0D +}=0D +=0D +bool=0D +libspdm_x509_get_organization_name (=0D + const uint8_t *cert,=0D + size_t cert_size,=0D + char *name_buffer,=0D + size_t *name_buffer_size=0D + )=0D +{=0D + EFI_STATUS Status;=0D +=0D + Status =3D X509GetOrganizationName (cert, cert_size, name_buffer, name_b= uffer_size);=0D + if (EFI_ERROR (Status)) {=0D + return false;=0D + } else {=0D + return true;=0D + }=0D +}=0D +=0D +bool=0D +libspdm_x509_get_version (=0D + const uint8_t *cert,=0D + size_t cert_size,=0D + size_t *version=0D + )=0D +{=0D + return X509GetVersion (cert, cert_size, version);=0D +}=0D +=0D +bool=0D +libspdm_x509_get_serial_number (=0D + const uint8_t *cert,=0D + size_t cert_size,=0D + uint8_t *serial_number,=0D + size_t *serial_number_size=0D + )=0D +{=0D + return X509GetSerialNumber (cert, cert_size, serial_number, serial_numbe= r_size);=0D +}=0D +=0D +bool=0D +libspdm_x509_get_issuer_name (=0D + const uint8_t *cert,=0D + size_t cert_size,=0D + uint8_t *cert_issuer,=0D + size_t *issuer_size=0D + )=0D +{=0D + return X509GetIssuerName (cert, cert_size, cert_issuer, issuer_size);=0D +}=0D +=0D +bool=0D +libspdm_x509_get_signature_algorithm (=0D + const uint8_t *cert,=0D + size_t cert_size,=0D + uint8_t *oid,=0D + size_t *oid_size=0D + )=0D +{=0D + return X509GetSignatureAlgorithm (cert, cert_size, oid, oid_size);=0D +}=0D +=0D +bool=0D +libspdm_x509_get_extension_data (=0D + const uint8_t *cert,=0D + size_t cert_size,=0D + const uint8_t *oid,=0D + size_t oid_size,=0D + uint8_t *extension_data,=0D + size_t *extension_data_size=0D + )=0D +{=0D + return X509GetExtensionData (=0D + cert,=0D + cert_size,=0D + oid,=0D + oid_size,=0D + extension_data,=0D + extension_data_size=0D + );=0D +}=0D +=0D +bool=0D +libspdm_x509_get_validity (=0D + const uint8_t *cert,=0D + size_t cert_size,=0D + uint8_t *from,=0D + size_t *from_size,=0D + uint8_t *to,=0D + size_t *to_size=0D + )=0D +{=0D + return X509GetValidity (cert, cert_size, from, from_size, to, to_size);= =0D +}=0D +=0D +bool=0D +libspdm_x509_set_date_time (=0D + const char *date_time_str,=0D + void *date_time,=0D + size_t *date_time_size=0D + )=0D +{=0D + return X509FormatDateTime (date_time_str, date_time, date_time_size);=0D +}=0D +=0D +int32_t=0D +libspdm_x509_compare_date_time (=0D + const void *date_time1,=0D + const void *date_time2=0D + )=0D +{=0D + return X509CompareDateTime (date_time1, date_time2);=0D +}=0D +=0D +bool=0D +libspdm_x509_get_key_usage (=0D + const uint8_t *cert,=0D + size_t cert_size,=0D + size_t *usage=0D + )=0D +{=0D + return X509GetKeyUsage (cert, cert_size, usage);=0D +}=0D +=0D +bool=0D +libspdm_x509_get_extended_key_usage (=0D + const uint8_t *cert,=0D + size_t cert_size,=0D + uint8_t *usage,=0D + size_t *usage_size=0D + )=0D +{=0D + return X509GetExtendedKeyUsage (cert, cert_size, usage, usage_size);=0D +}=0D +=0D +bool=0D +libspdm_x509_verify_cert (=0D + const uint8_t *cert,=0D + size_t cert_size,=0D + const uint8_t *ca_cert,=0D + size_t ca_cert_size=0D + )=0D +{=0D + return X509VerifyCert (cert, cert_size, ca_cert, ca_cert_size);=0D +}=0D +=0D +bool=0D +libspdm_x509_verify_cert_chain (=0D + const uint8_t *root_cert,=0D + size_t root_cert_length,=0D + const uint8_t *cert_chain,=0D + size_t cert_chain_length=0D + )=0D +{=0D + return X509VerifyCertChain (root_cert, root_cert_length, cert_chain, cer= t_chain_length);=0D +}=0D +=0D +bool=0D +libspdm_x509_get_cert_from_cert_chain (=0D + const uint8_t *cert_chain,=0D + size_t cert_chain_length,=0D + const int32_t cert_index,=0D + const uint8_t **cert,=0D + size_t *cert_length=0D + )=0D +{=0D + return X509GetCertFromCertChain (=0D + cert_chain,=0D + cert_chain_length,=0D + cert_index,=0D + cert,=0D + cert_length=0D + );=0D +}=0D +=0D +bool=0D +libspdm_x509_construct_certificate (=0D + const uint8_t *cert,=0D + size_t cert_size,=0D + uint8_t **single_x509_cert=0D + )=0D +{=0D + return X509ConstructCertificate (cert, cert_size, single_x509_cert);=0D +}=0D +=0D +bool=0D +libspdm_x509_get_extended_basic_constraints (=0D + const uint8_t *cert,=0D + size_t cert_size,=0D + uint8_t *basic_constraints,=0D + size_t *basic_constraints_size=0D + )=0D +{=0D + return X509GetExtendedBasicConstraints (=0D + cert,=0D + cert_size,=0D + basic_constraints,=0D + basic_constraints_size=0D + );=0D +}=0D +=0D +void *=0D +libspdm_ec_new_by_nid (=0D + size_t nid=0D + )=0D +{=0D + return EcNewByNid (nid);=0D +}=0D +=0D +void=0D +libspdm_ec_free (=0D + void *ec_context=0D + )=0D +{=0D + EcFree (ec_context);=0D +}=0D +=0D +bool=0D +libspdm_ec_generate_key (=0D + void *ec_context,=0D + uint8_t *public_data,=0D + size_t *public_size=0D + )=0D +{=0D + return EcGenerateKey (ec_context, public_data, public_size);=0D +}=0D +=0D +bool=0D +libspdm_ec_compute_key (=0D + void *ec_context,=0D + const uint8_t *peer_public,=0D + size_t peer_public_size,=0D + uint8_t *key,=0D + size_t *key_size=0D + )=0D +{=0D + return EcDhComputeKey (ec_context, peer_public, peer_public_size, NULL, = key, key_size);=0D +}=0D +=0D +bool=0D +libspdm_ecdsa_sign (=0D + void *ec_context,=0D + size_t hash_nid,=0D + const uint8_t *message_hash,=0D + size_t hash_size,=0D + uint8_t *signature,=0D + size_t *sig_size=0D + )=0D +{=0D + return EcDsaSign (=0D + ec_context,=0D + hash_nid,=0D + message_hash,=0D + hash_size,=0D + signature,=0D + sig_size=0D + );=0D +}=0D +=0D +bool=0D +libspdm_ecdsa_verify (=0D + void *ec_context,=0D + size_t hash_nid,=0D + const uint8_t *message_hash,=0D + size_t hash_size,=0D + const uint8_t *signature,=0D + size_t sig_size=0D + )=0D +{=0D + return EcDsaVerify (=0D + ec_context,=0D + hash_nid,=0D + message_hash,=0D + hash_size,=0D + signature,=0D + sig_size=0D + );=0D +}=0D +=0D +bool=0D +libspdm_random_bytes (=0D + uint8_t *output,=0D + size_t size=0D + )=0D +{=0D + return RandomBytes (output, size);=0D +}=0D +=0D +bool=0D +libspdm_hkdf_sha256_extract_and_expand (=0D + const uint8_t *key,=0D + size_t key_size,=0D + const uint8_t *salt,=0D + size_t salt_size,=0D + const uint8_t *info,=0D + size_t info_size,=0D + uint8_t *out,=0D + size_t out_size=0D + )=0D +{=0D + return HkdfSha256ExtractAndExpand (=0D + key,=0D + key_size,=0D + salt,=0D + salt_size,=0D + info,=0D + info_size,=0D + out,=0D + out_size=0D + );=0D +}=0D +=0D +bool=0D +libspdm_hkdf_sha256_extract (=0D + const uint8_t *key,=0D + size_t key_size,=0D + const uint8_t *salt,=0D + size_t salt_size,=0D + uint8_t *prk_out,=0D + size_t prk_out_size=0D + )=0D +{=0D + return HkdfSha256Extract (=0D + key,=0D + key_size,=0D + salt,=0D + salt_size,=0D + prk_out,=0D + prk_out_size=0D + );=0D +}=0D +=0D +bool=0D +libspdm_hkdf_sha256_expand (=0D + const uint8_t *prk,=0D + size_t prk_size,=0D + const uint8_t *info,=0D + size_t info_size,=0D + uint8_t *out,=0D + size_t out_size=0D + )=0D +{=0D + return HkdfSha256Expand (=0D + prk,=0D + prk_size,=0D + info,=0D + info_size,=0D + out,=0D + out_size=0D + );=0D +}=0D +=0D +bool=0D +libspdm_hkdf_sha384_extract_and_expand (=0D + const uint8_t *key,=0D + size_t key_size,=0D + const uint8_t *salt,=0D + size_t salt_size,=0D + const uint8_t *info,=0D + size_t info_size,=0D + uint8_t *out,=0D + size_t out_size=0D + )=0D +{=0D + return HkdfSha384ExtractAndExpand (=0D + key,=0D + key_size,=0D + salt,=0D + salt_size,=0D + info,=0D + info_size,=0D + out,=0D + out_size=0D + );=0D +}=0D +=0D +bool=0D +libspdm_hkdf_sha384_extract (=0D + const uint8_t *key,=0D + size_t key_size,=0D + const uint8_t *salt,=0D + size_t salt_size,=0D + uint8_t *prk_out,=0D + size_t prk_out_size=0D + )=0D +{=0D + return HkdfSha384Extract (=0D + key,=0D + key_size,=0D + salt,=0D + salt_size,=0D + prk_out,=0D + prk_out_size=0D + );=0D +}=0D +=0D +bool=0D +libspdm_hkdf_sha384_expand (=0D + const uint8_t *prk,=0D + size_t prk_size,=0D + const uint8_t *info,=0D + size_t info_size,=0D + uint8_t *out,=0D + size_t out_size=0D + )=0D +{=0D + return HkdfSha384Expand (=0D + prk,=0D + prk_size,=0D + info,=0D + info_size,=0D + out,=0D + out_size=0D + );=0D +}=0D diff --git a/SecurityPkg/DeviceSecurity/OsStub/CryptlibWrapper/CryptlibWrap= per.inf b/SecurityPkg/DeviceSecurity/OsStub/CryptlibWrapper/CryptlibWrapper= .inf new file mode 100644 index 0000000000..0b64ab0f4f --- /dev/null +++ b/SecurityPkg/DeviceSecurity/OsStub/CryptlibWrapper/CryptlibWrapper.inf @@ -0,0 +1,38 @@ +## @file=0D +# SPDM library.=0D +#=0D +# Copyright (c) 2024, Intel Corporation. All rights reserved.
=0D +#=0D +# SPDX-License-Identifier: BSD-2-Clause-Patent=0D +#=0D +##=0D +=0D +[Defines]=0D + INF_VERSION =3D 0x00010005=0D + BASE_NAME =3D CryptlibWrapper=0D + FILE_GUID =3D 156C1B1B-6C2F-496a-496A-0548D1A9ED5B= =0D + MODULE_TYPE =3D BASE=0D + VERSION_STRING =3D 1.0=0D + LIBRARY_CLASS =3D CryptlibWrapper=0D +=0D +#=0D +# The following information is for reference only and not required by the = build tools.=0D +#=0D +# VALID_ARCHITECTURES =3D IA32 X64 AARCH64=0D +#=0D +=0D +[Sources]=0D + CryptlibWrapper.c=0D +=0D +[Packages]=0D + MdePkg/MdePkg.dec=0D + SecurityPkg/SecurityPkg.dec=0D + CryptoPkg/CryptoPkg.dec=0D +=0D +[LibraryClasses]=0D + BaseLib=0D + BaseMemoryLib=0D + MemoryAllocationLib=0D + DebugLib=0D + BaseCryptLib=0D + RngLib=0D diff --git a/SecurityPkg/DeviceSecurity/OsStub/MemLibWrapper/MemLibWrapper.= c b/SecurityPkg/DeviceSecurity/OsStub/MemLibWrapper/MemLibWrapper.c new file mode 100644 index 0000000000..42eeecd68c --- /dev/null +++ b/SecurityPkg/DeviceSecurity/OsStub/MemLibWrapper/MemLibWrapper.c @@ -0,0 +1,177 @@ +/** @file=0D + EDKII Device Security library for SPDM device.=0D + It follows the SPDM Specification.=0D +=0D +Copyright (c) 2024, Intel Corporation. All rights reserved.
=0D +SPDX-License-Identifier: BSD-2-Clause-Patent=0D +=0D +**/=0D +=0D +#include =0D +#include =0D +#include =0D +#include "hal/base.h"=0D +#include "hal/library/memlib.h"=0D +=0D +/**=0D + * Copies bytes from a source buffer to a destination buffer.=0D + *=0D + * This function copies "src_len" bytes from "src_buf" to "dst_buf".=0D + *=0D + * Asserts and returns a non-zero value if any of the following are true:= =0D + * 1) "src_buf" or "dst_buf" are NULL.=0D + * 2) "src_len" or "dst_len" is greater than (SIZE_MAX >> 1).=0D + * 3) "src_len" is greater than "dst_len".=0D + * 4) "src_buf" and "dst_buf" overlap.=0D + *=0D + * If any of these cases fail, a non-zero value is returned. Additionally = if=0D + * "dst_buf" points to a non-NULL value and "dst_len" is valid, then "dst_= len"=0D + * bytes of "dst_buf" are zeroed.=0D + *=0D + * This function follows the C11 cppreference description of memcpy_s.=0D + * https://en.cppreference.com/w/c/string/byte/memcpy=0D + * The cppreferece description does NOT allow the source or destination=0D + * buffers to be NULL.=0D + *=0D + * This function differs from the Microsoft and Safeclib memcpy_s implemen= tations=0D + * in that the Microsoft and Safeclib implementations allow for NULL sourc= e and=0D + * destinations pointers when the number of bytes to copy (src_len) is zer= o.=0D + *=0D + * In addition the Microsoft and Safeclib memcpy_s functions return differ= ent=0D + * negative values on error. For best support, clients should generally ch= eck=0D + * against zero for success or failure.=0D + *=0D + * @param dst_buf Destination buffer to copy to.=0D + * @param dst_len Maximum length in bytes of the destination buffer.= =0D + * @param src_buf Source buffer to copy from.=0D + * @param src_len The number of bytes to copy from the source buffer.= =0D + *=0D + * @return 0 on success. non-zero on error.=0D + *=0D + **/=0D +void=0D +libspdm_copy_mem (=0D + void *dst_buf,=0D + size_t dst_len,=0D + const void *src_buf,=0D + size_t src_len=0D + )=0D +{=0D + volatile uint8_t *dst;=0D + const volatile uint8_t *src;=0D +=0D + dst =3D (volatile uint8_t *)dst_buf;=0D + src =3D (const volatile uint8_t *)src_buf;=0D +=0D + /* Check for case where "dst" or "dst_len" may be invalid.=0D + * Do not zero "dst" in this case. */=0D + if ((dst =3D=3D NULL) || (dst_len > (SIZE_MAX >> 1))) {=0D + ASSERT (0);=0D + }=0D +=0D + /* Gaurd against invalid source. Zero "dst" in this case. */=0D + if (src =3D=3D NULL) {=0D + ZeroMem (dst_buf, dst_len);=0D + ASSERT (0);=0D + }=0D +=0D + /* Guard against overlap case. Zero "dst" in these cases. */=0D + if (((src < dst) && (src + src_len > dst)) || ((dst < src) && (dst + src= _len > src))) {=0D + ZeroMem (dst_buf, dst_len);=0D + ASSERT (0);=0D + }=0D +=0D + /* Guard against invalid lengths. Zero "dst" in these cases. */=0D + if ((src_len > dst_len) ||=0D + (src_len > (SIZE_MAX >> 1)))=0D + {=0D + ZeroMem (dst_buf, dst_len);=0D + ASSERT (0);=0D + }=0D +=0D + while (src_len-- !=3D 0) {=0D + *(dst++) =3D *(src++);=0D + }=0D +}=0D +=0D +/**=0D + * Fills a target buffer with a byte value, and returns the target buffer.= =0D + *=0D + * This function fills length bytes of buffer with value, and returns buff= er.=0D + *=0D + * If length is greater than (MAX_ADDRESS - buffer + 1), then ASSERT().=0D + *=0D + * @param buffer The memory to set.=0D + * @param length The number of bytes to set.=0D + * @param value The value with which to fill length bytes of buffer.= =0D + *=0D + * @return buffer.=0D + *=0D + **/=0D +void=0D +libspdm_set_mem (=0D + void *buffer,=0D + size_t length,=0D + uint8_t value=0D + )=0D +{=0D + SetMem (buffer, length, value);=0D +}=0D +=0D +/**=0D + * Fills a target buffer with zeros, and returns the target buffer.=0D + *=0D + * This function fills length bytes of buffer with zeros, and returns buff= er.=0D + *=0D + * If length > 0 and buffer is NULL, then ASSERT().=0D + * If length is greater than (MAX_ADDRESS - buffer + 1), then ASSERT().=0D + *=0D + * @param buffer The pointer to the target buffer to fill with zeros= .=0D + * @param length The number of bytes in buffer to fill with zeros.=0D + *=0D + * @return buffer.=0D + *=0D + **/=0D +void=0D +libspdm_zero_mem (=0D + void *buffer,=0D + size_t length=0D + )=0D +{=0D + ZeroMem (buffer, length);=0D +}=0D +=0D +/**=0D + * Compares the contents of two buffers in const time.=0D + *=0D + * This function compares length bytes of source_buffer to length bytes of= destination_buffer.=0D + * If all length bytes of the two buffers are identical, then 0 is returne= d. Otherwise, the=0D + * value returned is the first mismatched byte in source_buffer subtracted= from the first=0D + * mismatched byte in destination_buffer.=0D + *=0D + * If length > 0 and destination_buffer is NULL, then ASSERT().=0D + * If length > 0 and source_buffer is NULL, then ASSERT().=0D + * If length is greater than (MAX_ADDRESS - destination_buffer + 1), then = ASSERT().=0D + * If length is greater than (MAX_ADDRESS - source_buffer + 1), then ASSER= T().=0D + *=0D + * @param destination_buffer A pointer to the destination buffer to compa= re.=0D + * @param source_buffer A pointer to the source buffer to compare.=0D + * @param length The number of bytes to compare.=0D + *=0D + * @return 0 All length bytes of the two buffers are ident= ical.=0D + * @retval Non-zero There is mismatched between source_buffer and= destination_buffer.=0D + *=0D + **/=0D +bool=0D +libspdm_consttime_is_mem_equal (=0D + const void *destination_buffer,=0D + const void *source_buffer,=0D + size_t length=0D + )=0D +{=0D + if (CompareMem (destination_buffer, source_buffer, length) =3D=3D 0) {=0D + return true;=0D + } else {=0D + return false;=0D + }=0D +}=0D diff --git a/SecurityPkg/DeviceSecurity/OsStub/MemLibWrapper/MemLibWrapper.= inf b/SecurityPkg/DeviceSecurity/OsStub/MemLibWrapper/MemLibWrapper.inf new file mode 100644 index 0000000000..f5b92aae6b --- /dev/null +++ b/SecurityPkg/DeviceSecurity/OsStub/MemLibWrapper/MemLibWrapper.inf @@ -0,0 +1,33 @@ +## @file=0D +# SPDM library.=0D +#=0D +# Copyright (c) 2024, Intel Corporation. All rights reserved.
=0D +#=0D +# SPDX-License-Identifier: BSD-2-Clause-Patent=0D +#=0D +##=0D +=0D +[Defines]=0D + INF_VERSION =3D 0x00010005=0D + BASE_NAME =3D MemLibWrapper=0D + FILE_GUID =3D d97bb726-6640-47dc-ae00-0cf2fbfb60f0= =0D + MODULE_TYPE =3D BASE=0D + VERSION_STRING =3D 1.0=0D + LIBRARY_CLASS =3D MemLibWrapper=0D +=0D +#=0D +# The following information is for reference only and not required by the = build tools.=0D +#=0D +# VALID_ARCHITECTURES =3D IA32 X64 AARCH64=0D +#=0D +=0D +[Sources]=0D + MemLibWrapper.c=0D +=0D +[Packages]=0D + MdePkg/MdePkg.dec=0D + SecurityPkg/SecurityPkg.dec=0D +=0D +[LibraryClasses]=0D + BaseLib=0D + DebugLib=0D diff --git a/SecurityPkg/DeviceSecurity/OsStub/PlatformLibWrapper/PlatformL= ibWrapper.c b/SecurityPkg/DeviceSecurity/OsStub/PlatformLibWrapper/Platform= LibWrapper.c new file mode 100644 index 0000000000..6e9256e6ea --- /dev/null +++ b/SecurityPkg/DeviceSecurity/OsStub/PlatformLibWrapper/PlatformLibWrapp= er.c @@ -0,0 +1,85 @@ +/** @file=0D + EDKII Device Security library for SPDM device.=0D + It follows the SPDM Specification.=0D +=0D +Copyright (c) 2024, Intel Corporation. All rights reserved.
=0D +SPDX-License-Identifier: BSD-2-Clause-Patent=0D +=0D +**/=0D +=0D +#include =0D +#include =0D +#include "hal/base.h"=0D +=0D +/**=0D + * Suspends the execution of the current thread until the time-out interva= l elapses.=0D + *=0D + * @param milliseconds The time interval for which execution is to be = suspended, in milliseconds.=0D + *=0D + **/=0D +void=0D +libspdm_sleep (=0D + uint64_t milliseconds=0D + )=0D +{=0D + return;=0D +}=0D +=0D +/**=0D + * Suspends the execution of the current thread until the time-out interva= l elapses.=0D + *=0D + * @param microseconds The time interval for which execution is to be = suspended, in milliseconds.=0D + *=0D + **/=0D +void=0D +libspdm_sleep_in_us (=0D + uint64_t microseconds=0D + )=0D +{=0D + return;=0D +}=0D +=0D +/**=0D + * If no heartbeat arrives in seconds, the watchdog timeout event=0D + * should terminate the session.=0D + *=0D + * @param session_id Indicate the SPDM session ID.=0D + * @param seconds heartbeat period, in seconds.=0D + *=0D + **/=0D +bool=0D +libspdm_start_watchdog (=0D + uint32_t session_id,=0D + uint16_t seconds=0D + )=0D +{=0D + return true;=0D +}=0D +=0D +/**=0D + * stop watchdog.=0D + *=0D + * @param session_id Indicate the SPDM session ID.=0D + *=0D + **/=0D +bool=0D +libspdm_stop_watchdog (=0D + uint32_t session_id=0D + )=0D +{=0D + return true;=0D +}=0D +=0D +/**=0D + * Reset the watchdog in heartbeat response.=0D + *=0D + * @param session_id Indicate the SPDM session ID.=0D + *=0D + **/=0D +bool=0D +libspdm_reset_watchdog (=0D + uint32_t session_id=0D + )=0D +{=0D + return true;=0D +}=0D diff --git a/SecurityPkg/DeviceSecurity/OsStub/PlatformLibWrapper/PlatformL= ibWrapper.inf b/SecurityPkg/DeviceSecurity/OsStub/PlatformLibWrapper/Platfo= rmLibWrapper.inf new file mode 100644 index 0000000000..269b4bfbe1 --- /dev/null +++ b/SecurityPkg/DeviceSecurity/OsStub/PlatformLibWrapper/PlatformLibWrapp= er.inf @@ -0,0 +1,33 @@ +## @file=0D +# SPDM library.=0D +#=0D +# Copyright (c) 2024, Intel Corporation. All rights reserved.
=0D +#=0D +# SPDX-License-Identifier: BSD-2-Clause-Patent=0D +#=0D +##=0D +=0D +[Defines]=0D + INF_VERSION =3D 0x00010005=0D + BASE_NAME =3D PlatformLibWrapper=0D + FILE_GUID =3D 2f8979d1-f9f0-4d51-9cbd-4f41dee59057= =0D + MODULE_TYPE =3D BASE=0D + VERSION_STRING =3D 1.0=0D + LIBRARY_CLASS =3D PlatformLibWrapper=0D +=0D +#=0D +# The following information is for reference only and not required by the = build tools.=0D +#=0D +# VALID_ARCHITECTURES =3D IA32 X64 AARCH64=0D +#=0D +=0D +[Sources]=0D + PlatformLibWrapper.c=0D +=0D +[Packages]=0D + MdePkg/MdePkg.dec=0D + SecurityPkg/SecurityPkg.dec=0D +=0D +[LibraryClasses]=0D + BaseLib=0D + DebugLib=0D diff --git a/SecurityPkg/DeviceSecurity/SpdmLib/Include/Stub/SpdmLibStub.h = b/SecurityPkg/DeviceSecurity/SpdmLib/Include/Stub/SpdmLibStub.h new file mode 100644 index 0000000000..8ec6e61675 --- /dev/null +++ b/SecurityPkg/DeviceSecurity/SpdmLib/Include/Stub/SpdmLibStub.h @@ -0,0 +1,347 @@ +/** @file=0D +=0D + Copyright (c) 2024, Intel Corporation. All rights reserved.
=0D + SPDX-License-Identifier: BSD-2-Clause-Patent=0D +=0D +**/=0D +=0D +#ifndef __LIBSPDM_STUB_H__=0D +#define __LIBSPDM_STUB_H__=0D +=0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +=0D +#pragma pack(1)=0D +=0D +/* The layout of SPDM_RETURN is=0D + * [31:28] - Severity=0D + * [27:24] - Reserved=0D + * [23:16] - Source=0D + * [15:00] - Code=0D + */=0D +typedef UINT32 SPDM_RETURN;=0D +=0D +/*Interface of spdm.h*/=0D +/* SPDM message header*/=0D +typedef struct {=0D + UINT8 SPDMVersion;=0D + UINT8 RequestResponseCode;=0D + UINT8 Param1;=0D + UINT8 Param2;=0D +} SPDM_MESSAGE_HEADER;=0D +=0D +/* SPDM VERSION structure=0D + * Bit[15:12] MajorVersion=0D + * Bit[11:8] MinorVersion=0D + * Bit[7:4] UpdateVersionNumber=0D + * Bit[3:0] Alpha*/=0D +typedef UINT16 SPDM_VERSION_NUMBER;=0D +=0D +typedef struct {=0D + /* Total length of the certificate chain, in bytes,=0D + * including all fields in this table.*/=0D +=0D + UINT16 Length;=0D + UINT16 Reserved;=0D +=0D + /* digest of the Root Certificate.=0D + * Note that Root Certificate is ASN.1 DER-encoded for this digest.=0D + * The hash size is determined by the SPDM device.*/=0D +=0D + /*UINT8 RootHash[HashSize];*/=0D +=0D + /* One or more ASN.1 DER-encoded X509v3 certificates where the first cer= tificate is signed by the Root=0D + * Certificate or is the Root Certificate itself and each subsequent cer= tificate is signed by the preceding=0D + * certificate. The last certificate is the Leaf Certificate.*/=0D +=0D + /*UINT8 Certificates[length - 4 - HashSize];*/=0D +} SPDM_CERT_CHAIN;=0D +=0D +/* SPDM MEASUREMENTS block common header */=0D +typedef struct {=0D + UINT8 Index;=0D + UINT8 MeasurementSpecification;=0D + UINT16 MeasurementSize;=0D + /*UINT8 Measurement[MeasurementSize];*/=0D +} SPDM_MEASUREMENT_BLOCK_COMMON_HEADER;=0D +=0D +/* SPDM MEASUREMENTS block DMTF header */=0D +typedef struct {=0D + UINT8 DMTFSpecMeasurementValueType;=0D + UINT16 DMTFSpecMeasurementValueSize;=0D + /*UINT8 DMTFSpecMeasurementValue[DMTFSpecMeasurementValue= Size];*/=0D +} SPDM_MEASUREMENT_BLOCK_DMTF_HEADER;=0D +=0D +typedef struct {=0D + SPDM_MEASUREMENT_BLOCK_COMMON_HEADER MeasurementBlockCommonHeader;=0D + SPDM_MEASUREMENT_BLOCK_DMTF_HEADER MeasurementBlockDmtfHeader;=0D + /*UINT8 HashValue[HashSize];*/=0D +} SPDM_MEASUREMENT_BLOCK_DMTF;=0D +=0D +#define SPDM_DATA_PARAMETER libspdm_data_parameter_t=0D +=0D +typedef enum {=0D + //=0D + // SPDM parameter=0D + //=0D + SpdmDataSpdmVersion,=0D + SpdmDataSecuredMessageVersion,=0D + //=0D + // SPDM capability=0D + //=0D + SpdmDataCapabilityFlags,=0D + SpdmDataCapabilityCTExponent,=0D + SpdmDataCapabilityRttUs,=0D + SpdmDataCapabilityDataTransferSize,=0D + SpdmDataCapabilityMaxSpdmMsgSize,=0D + SpdmDataCapabilitySenderDataTransferSize,=0D +=0D + //=0D + // SPDM Algorithm setting=0D + //=0D + SpdmDataMeasurementSpec,=0D + SpdmDataMeasurementHashAlgo,=0D + SpdmDataBaseAsymAlgo,=0D + SpdmDataBaseHashAlgo,=0D + SpdmDataDHENameGroup,=0D + SpdmDataAEADCipherSuite,=0D + SpdmDataReqBaseAsymAlg,=0D + SpdmDataKeySchedule,=0D + SpdmDataOtherParamsSupport,=0D + SpdmDataMelSpec,=0D +=0D + //=0D + // Connection State=0D + //=0D + SpdmDataConnectionState,=0D + //=0D + // ResponseState=0D + //=0D + SpdmDataResponseState,=0D + //=0D + // Certificate info=0D + //=0D + SpdmDataLocalPublicCertChain,=0D + SpdmDataPeerPublicRootCert,=0D + SpdmDataPeerPublicKey,=0D + SpdmDataLocalPublicKey,=0D + SpdmDataLocalSupportedSlotMask,=0D + SpdmDataLocalKeyPairId,=0D + SpdmDataLocalCertInfo,=0D + SpdmDataLocalKeyUsageBitMask,=0D +=0D + SpdmDataBasicMutAuthRequested,=0D + SpdmDataMutAuthRequested,=0D + SpdmDataHeartBeatPeriod,=0D + //=0D + // Negotiated result=0D + //=0D + SpdmDataPeerUsedCertChainBuffer,=0D + SpdmDataPeerSlotMask,=0D + SpdmDataPeerProvisionedSlotMask =3D SpdmDataPeerSlotMask,=0D + SpdmDataPeerSupportedSlotMask,=0D + SpdmDataPeerTotalDigestBuffer,=0D + SpdmDataPeerKeyPairId,=0D + SpdmDataPeerCertInfo,=0D + SpdmDataPeerKeyUsageBitMask,=0D +=0D + //=0D + // Pre-shared Key Hint=0D + // If PSK is present, then PSK_EXCHANGE is used.=0D + // Otherwise, the KEY_EXCHANGE is used.=0D + //=0D + SpdmDataPskHint,=0D + //=0D + // SessionData=0D + //=0D + SpdmDataSessionUsePsk,=0D + SpdmDataSessionMutAuthRequested,=0D + SpdmDataSessionEndSessionAttributes,=0D + SpdmDataSessionPolicy,=0D +=0D + SpdmDataAppContextData,=0D +=0D + SpdmDataHandleErrorReturnPolicy,=0D +=0D + /* VCA cached for CACHE_CAP in 1.2 for transcript.*/=0D + SpdmDataVcaCache,=0D +=0D + /* if the context is for a requester. It only needs to be set in VCA cac= he.*/=0D + SpdmDataIsRequester,=0D +=0D + // If the Responder replies with a Busy `ERROR` response to a request=0D + // then the Requester is free to retry sending the request.=0D + // This value specifies the maximum number of times libspdm will retry=0D + // sending the request before returning an error.=0D + // If its value is 0 then libspdm will not send any retry requests.=0D + SpdmDataRequestRetryTimes,=0D +=0D + // If the Responder replies with a Busy `ERROR` response to a request=0D + // then the Requester is free to retry sending the request.=0D + // This value specifies the delay time in microseconds between each retr= y requests.=0D + // If its value is 0 then libspdm will send retry request immediately.=0D + SpdmDataRequestRetryDelayTime,=0D +=0D + /* limit the number of DHE session and PSK session separately.*/=0D + SpdmDataMaxDheSessionConut,=0D + SpdmDataMaxPskSessionConut,=0D +=0D + SpdmDataSessionSequenceNumberRspDir,=0D + SpdmDataSessionSequenceNumberReqDir,=0D + SpdmDataMaxSessionSequenceNumber,=0D +=0D + /* For SPDM 1.0 and 1.1, allow signature verification in big, little, or= both endians. */=0D + SpdmDataSpdmVersion1011VerifySigatureEndian,=0D +=0D + SpdmDataSequenceNumberEndian,=0D + SpdmDataSessionSequenceNumberEndian,=0D +=0D + SpdmDataMultiKeyConnReq,=0D + SpdmDataMultiKeyConnRsp,=0D + //=0D + // MAX=0D + //=0D + SpdmDataMax,=0D +} SPDM_DATA_TYPE;=0D +=0D +typedef enum {=0D + SpdmDataLocationLocal,=0D + SpdmDataLocationConnection,=0D + SpdmDataLocationSession,=0D + SpdmDataLocationMax,=0D +} SPDM_DATA_LOCATION;=0D +=0D +typedef enum {=0D + //=0D + // Before GET_VERSION/VERSION=0D + //=0D + SpdmConnectionStateNotStarted,=0D + //=0D + // After GET_VERSION/VERSION=0D + //=0D + SpdmConnectionStateAfterVersion,=0D + //=0D + // After GET_CAPABILITIES/CAPABILITIES=0D + //=0D + SpdmConnectionStateAfterCapabilities,=0D + //=0D + // After NEGOTIATE_ALGORITHMS/ALGORITHMS=0D + //=0D + SpdmConnectionStateNegotiated,=0D + //=0D + // After GET_DIGESTS/DIGESTS=0D + //=0D + SpdmConnectionStateAfterDigests,=0D + //=0D + // After GET_CERTIFICATE/CERTIFICATE=0D + //=0D + SpdmConnectionStateAfterCertificate,=0D + //=0D + // After CHALLENGE/CHALLENGE_AUTH, and ENCAP CALLENGE/CHALLENG_AUTH if M= UT_AUTH is enabled.=0D + //=0D + SpdmConnectionStateAuthenticated,=0D + //=0D + // MAX=0D + //=0D + SpdmConnectionStateMax,=0D +} SPDM_CONNECTION_STATE;=0D +=0D +typedef enum {=0D + //=0D + // Normal response.=0D + //=0D + SpdmResponseStateNormal,=0D + //=0D + // Other component is busy.=0D + //=0D + SpdmResponseStateBusy,=0D + #if LIBSPDM_RESPOND_IF_READY_SUPPORT=0D + //=0D + // Hardware is not ready.=0D + //=0D + SpdmResponseStateNotReady,=0D + #endif /* LIBSPDM_RESPOND_IF_READY_SUPPORT */=0D + //=0D + // Firmware Update is done. Need resync.=0D + //=0D + SpdmResponseStateNeedResync,=0D + //=0D + // Processing Encapsulated message.=0D + //=0D + SpdmResponseStateProcessingEncap,=0D + //=0D + // MAX=0D + //=0D + SpdmResponseStateMax,=0D +} SPDM_RESPONSE_STATE;=0D +=0D +/* DOE header*/=0D +=0D +typedef struct {=0D + UINT16 VendorId;=0D + UINT8 DataObjectType;=0D + UINT8 Reserved;=0D +=0D + /* length of the data object being transfered in number of DW, including= the header (2 DW)=0D + * It only includes bit[0~17], bit[18~31] are reserved.=0D + * A value of 00000h indicate 2^18 DW =3D=3D 2^20 byte.*/=0D + UINT32 Length;=0D + /*UINT32 DataObjectDw[Length];*/=0D +} PCI_DOE_DATA_OBJECT_HEADER;=0D +=0D +#pragma pack()=0D +=0D +/* FUNCTION */=0D +#define SpdmSetData libspdm_set_data=0D +#define SpdmGetData libspdm_get_data=0D +#define SpdmInitContext libspdm_init_context=0D +#define SpdmGetContextSize libspdm_get_context_size=0D +#define SpdmRegisterDeviceIoFunc libspdm_register_device_io_fun= c=0D +#define SpdmRegisterTransportLayerFunc libspdm_register_transport_lay= er_func=0D +#define SpdmGetSizeofRequiredScratchBuffer libspdm_get_sizeof_required_sc= ratch_buffer=0D +#define SpdmRegisterDeviceBufferFunc libspdm_register_device_buffer= _func=0D +#define SpdmSetScratchBuffer libspdm_set_scratch_buffer=0D +=0D +#define SpdmGetHashSize libspdm_get_hash_size=0D +#define SpdmHashAll libspdm_hash_all=0D +#define SpdmGetMeasurementHashSize libspdm_get_measurement_hash_size=0D +#define SpdmMeasurementHashAll libspdm_measurement_hash_all=0D +#define SpdmHmacAll libspdm_hmac_all=0D +#define SpdmHkdfExpand libspdm_hkdf_expand=0D +#define SpdmAsymFree libspdm_asym_free=0D +#define SpdmAsymGetPrivateKeyFromPem libspdm_asym_get_private_key_from_pe= m=0D +#define SpdmAsymSign libspdm_asym_sign=0D +#define SpdmAsymSignHash libspdm_asym_sign_hash=0D +=0D +#define SpdmInitConnection libspdm_init_connection=0D +#define SpdmGetDigest libspdm_get_digest=0D +#define SpdmGetCertificate libspdm_get_certificate=0D +#define SpdmGetCertificateEx libspdm_get_certificate_ex=0D +#define SpdmChallenge libspdm_challenge=0D +#define SpdmChallengeEx libspdm_challenge_ex=0D +#define SpdmGetMeasurement libspdm_get_measurement=0D +#define SpdmGetMeasurementEx libspdm_get_measurement_ex=0D +#define SpdmStartSession libspdm_start_session=0D +#define SpdmStopSession libspdm_stop_session=0D +#define SpdmSendReceiveData libspdm_send_receive_data=0D +#define SpdmRegisterGetResponseFunc libspdm_register_get_response_fu= nc=0D +#define SpdmProcessRequest libspdm_process_request=0D +#define SpdmBuildResponse libspdm_build_response=0D +#define SpdmGenerateErrorResponse libspdm_generate_error_response= =0D +#define SpdmTransportPciDoeEncodeMessage libspdm_transport_pci_doe_encode= _message=0D +#define SpdmTransportPciDoeDecodeMessage libspdm_transport_pci_doe_decode= _message=0D +=0D +#define SpdmMeasurementCollectionFunc libspdm_measurement_collecti= on=0D +#define SpdmRequesterDataSignFunc libspdm_requester_data_sign= =0D +#define SpdmResponderDataSignFunc libspdm_responder_data_sign= =0D +#define SpdmGenerateMeasurementSummaryHash libspdm_generate_measurement= _summary_hash=0D +#define SpdmPskMasterSecretHkdfExpandFunc libspdm_psk_master_secret_hk= df_expand=0D +#define SpdmPskHandshakeSecretHkdfExpandFunc libspdm_psk_handshake_secret= _hkdf_expand=0D +#define SpdmMeasurementOpaqueData libspdm_measurement_opaque_d= ata=0D +#define SpdmChallengeOpaqueData libspdm_challenge_opaque_dat= a=0D +=0D +#endif=0D diff --git a/SecurityPkg/DeviceSecurity/SpdmLib/Include/hal/LibspdmStdBoolA= lt.h b/SecurityPkg/DeviceSecurity/SpdmLib/Include/hal/LibspdmStdBoolAlt.h new file mode 100644 index 0000000000..08af7296d0 --- /dev/null +++ b/SecurityPkg/DeviceSecurity/SpdmLib/Include/hal/LibspdmStdBoolAlt.h @@ -0,0 +1,23 @@ +/** @file=0D + EDKII Device Security library for SPDM device.=0D + It follows the SPDM Specification.=0D +=0D +Copyright (c) 2024, Intel Corporation. All rights reserved.
=0D +SPDX-License-Identifier: BSD-2-Clause-Patent=0D +=0D +**/=0D +=0D +#ifndef LIBSPDM_STDBOOL_ALT_H=0D +#define LIBSPDM_STDBOOL_ALT_H=0D +=0D +typedef BOOLEAN bool;=0D +=0D +#ifndef true=0D +#define true TRUE=0D +#endif=0D +=0D +#ifndef false=0D +#define false FALSE=0D +#endif=0D +=0D +#endif /* LIBSPDM_STDBOOL_ALT */=0D diff --git a/SecurityPkg/DeviceSecurity/SpdmLib/Include/hal/LibspdmStdDefAl= t.h b/SecurityPkg/DeviceSecurity/SpdmLib/Include/hal/LibspdmStdDefAlt.h new file mode 100644 index 0000000000..3b31c23722 --- /dev/null +++ b/SecurityPkg/DeviceSecurity/SpdmLib/Include/hal/LibspdmStdDefAlt.h @@ -0,0 +1,16 @@ +/** @file=0D + EDKII Device Security library for SPDM device.=0D + It follows the SPDM Specification.=0D +=0D +Copyright (c) 2024, Intel Corporation. All rights reserved.
=0D +SPDX-License-Identifier: BSD-2-Clause-Patent=0D +=0D +**/=0D +=0D +#ifndef LIBSPDM_STD_DEF_ALT_H=0D +#define LIBSPDM_STD_DEF_ALT_H=0D +=0D +typedef UINTN size_t;=0D +#define offsetof(type, member) OFFSET_OF(type,member)=0D +=0D +#endif /* LIBSPDM_STDDEF_ALT */=0D diff --git a/SecurityPkg/DeviceSecurity/SpdmLib/Include/hal/LibspdmStdIntAl= t.h b/SecurityPkg/DeviceSecurity/SpdmLib/Include/hal/LibspdmStdIntAlt.h new file mode 100644 index 0000000000..e63e17f8c6 --- /dev/null +++ b/SecurityPkg/DeviceSecurity/SpdmLib/Include/hal/LibspdmStdIntAlt.h @@ -0,0 +1,25 @@ +/** @file=0D + EDKII Device Security library for SPDM device.=0D + It follows the SPDM Specification.=0D +=0D +Copyright (c) 2024, Intel Corporation. All rights reserved.
=0D +SPDX-License-Identifier: BSD-2-Clause-Patent=0D +=0D +**/=0D +=0D +#ifndef LIBSPDM_STD_INT_ALT_H=0D +#define LIBSPDM_STD_INT_ALT_H=0D +=0D +typedef UINT64 uint64_t;=0D +typedef INT64 int64_t;=0D +typedef UINT32 uint32_t;=0D +typedef INT32 int32_t;=0D +typedef UINT16 uint16_t;=0D +typedef INT16 int16_t;=0D +typedef UINT8 uint8_t;=0D +=0D +#ifndef SIZE_MAX=0D +#define SIZE_MAX MAX_UINTN=0D +#endif=0D +=0D +#endif /* LIBSPDM_STDINT_ALT */=0D diff --git a/SecurityPkg/DeviceSecurity/SpdmLib/Include/hal/base.h b/Securi= tyPkg/DeviceSecurity/SpdmLib/Include/hal/base.h new file mode 100644 index 0000000000..09cef567c6 --- /dev/null +++ b/SecurityPkg/DeviceSecurity/SpdmLib/Include/hal/base.h @@ -0,0 +1,94 @@ +/** @file=0D + EDKII Device Security library for SPDM device.=0D + It follows the SPDM Specification.=0D +=0D +Copyright (c) 2024, Intel Corporation. All rights reserved.
=0D +SPDX-License-Identifier: BSD-2-Clause-Patent=0D +=0D +**/=0D +=0D +#ifndef BASE_H=0D +#define BASE_H=0D +=0D +#define LIBSPDM_STDINT_ALT "hal/LibspdmStdIntAlt.h"=0D +#define LIBSPDM_STDBOOL_ALT "hal/LibspdmStdBoolAlt.h"=0D +#define LIBSPDM_STDDEF_ALT "hal/LibspdmStdDefAlt.h"=0D +=0D +#ifndef LIBSPDM_STDINT_ALT=0D +=0D + #include =0D +=0D +/* LIBSPDM_OPENSSL_STDINT_WORKAROUND */=0D +=0D +/* This is a workaround for OpenSSL compilation problems when used with =0D + * on Windows platforms built with Visual Studio. Including pul= ls in=0D + * , which causes the type size_t to be defined. The size_t t= ype=0D + * depends on if _WIN32 or _WIN64 is defined. The default if neither is de= fined=0D + * is the 32-bit version of size_t. */=0D +=0D +/* Our OpenSSL compilation requires _WIN32 and _WIN64 to NOT be defined.=0D + * This will force the to use the wrong 32-bit definition of= size_t=0D + * if we are compiling as 64-bit. This 32-bit definition then does not agr= ee with=0D + * the 64-bit definition defined in libspdm and generates compile errors. = */=0D +=0D +/* To workaround this issue, LIBSPDM_OPENSSL_STDINT_WORKAROUND was created= =0D + * that is only defined for compilation via tha makefile of the OpenSSL li= brary=0D + * portion of libspdm. */=0D +=0D +/* This will lead to _WIN32 and _WIN64 to be NOT defined when reaching the= OpenSSL=0D + * portions of a compilation unit (header files + c file), thus meeting th= e=0D + * no Win32/Win64 requirement for OpenSSL, but will still be defined when = compiling=0D + * the file in the compilation unit (and getting the right s= ize_t). */=0D +=0D +/* In the future libspdm intends to use the Windows native compilation fla= gs and defines,=0D + * in place of the UEFI profile / personality. */=0D +=0D + #ifdef LIBSPDM_OPENSSL_STDINT_WORKAROUND=0D + #undef _WIN32=0D + #undef _WIN64=0D + #endif=0D +=0D +#else /* LIBSPDM_STDINT_ALT */=0D + #include LIBSPDM_STDINT_ALT=0D +#endif /* LIBSPDM_STDINT_ALT */=0D +=0D +#ifndef LIBSPDM_STDBOOL_ALT=0D + #include =0D +#else=0D + #include LIBSPDM_STDBOOL_ALT=0D +#endif=0D +=0D +#ifndef LIBSPDM_STDDEF_ALT=0D + #include =0D +#else=0D + #include LIBSPDM_STDDEF_ALT=0D +#endif=0D +=0D +/**=0D + * Return the minimum of two operands.=0D + *=0D + * This macro returns the minimal of two operand specified by a and b.=0D + * Both a and b must be the same numerical types, signed or unsigned.=0D + *=0D + * @param a The first operand with any numerical type.=0D + * @param b The second operand. It should be the same any numeric= al type with a.=0D + *=0D + * @return Minimum of two operands.=0D + *=0D + **/=0D +#define LIBSPDM_MIN(a, b) (((a) < (b)) ? (a) : (b))=0D +=0D +/**=0D + * Return the number of elements in an array.=0D + *=0D + * @param array An object of array type. Array is only used as an argume= nt to=0D + * the sizeof operator, therefore Array is never evaluated. = The=0D + * caller is responsible for ensuring that Array's type is n= ot=0D + * incomplete; that is, Array must have known constant size.= =0D + *=0D + * @return The number of elements in Array. The result has type size_t.=0D + *=0D + **/=0D +#define LIBSPDM_ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0]))=0D +=0D +#endif /* BASE_H */=0D diff --git a/SecurityPkg/DeviceSecurity/SpdmLib/Include/hal/library/debugli= b.h b/SecurityPkg/DeviceSecurity/SpdmLib/Include/hal/library/debuglib.h new file mode 100644 index 0000000000..9b31df4ad8 --- /dev/null +++ b/SecurityPkg/DeviceSecurity/SpdmLib/Include/hal/library/debuglib.h @@ -0,0 +1,39 @@ +/** @file=0D + EDKII Device Security library for SPDM device.=0D + It follows the SPDM Specification.=0D +=0D +Copyright (c) 2024, Intel Corporation. All rights reserved.
=0D +SPDX-License-Identifier: BSD-2-Clause-Patent=0D +=0D +**/=0D +=0D +/** @file=0D + Provides services to print debug and assert messages to a debug output d= evice.=0D +=0D + The Debug library supports debug print and asserts based on a combinatio= n of macros and code.=0D + The debug library can be turned on and off so that the debug code does n= ot increase the size of an image.=0D +=0D + Note that a reserved macro named MDEPKG_NDEBUG is introduced for the int= ention=0D + of size reduction when compiler optimization is disabled. If MDEPKG_NDEB= UG is=0D + defined, then debug and assert related macros wrapped by it are the NULL= implementations.=0D +**/=0D +=0D +#ifndef DEBUG_LIB_H=0D +#define DEBUG_LIB_H=0D +=0D +#include =0D +=0D +#define LIBSPDM_DEBUG_INFO DEBUG_INFO=0D +#define LIBSPDM_DEBUG_VERBOSE DEBUG_VERBOSE=0D +#define LIBSPDM_DEBUG_ERROR DEBUG_ERROR=0D +=0D +#define LIBSPDM_DEBUG DEBUG=0D +#define LIBSPDM_ASSERT ASSERT=0D +#define LIBSPDM_ASSERT_RETURN_ERROR ASSERT_RETURN_ERROR=0D +=0D +#define LIBSPDM_DEBUG_CODE_BEGIN DEBUG_CODE_BEGIN=0D +#define LIBSPDM_DEBUG_CODE_END DEBUG_CODE_END=0D +=0D +#define LIBSPDM_DEBUG_CODE DEBUG_CODE=0D +=0D +#endif /* DEBUG_LIB_H */=0D diff --git a/SecurityPkg/DeviceSecurity/SpdmLib/Include/library/spdm_lib_co= nfig.h b/SecurityPkg/DeviceSecurity/SpdmLib/Include/library/spdm_lib_config= .h new file mode 100644 index 0000000000..51dfd3c8fc --- /dev/null +++ b/SecurityPkg/DeviceSecurity/SpdmLib/Include/library/spdm_lib_config.h @@ -0,0 +1,394 @@ +/** @file=0D + EDKII Device Security library for SPDM device.=0D + It follows the SPDM Specification.=0D +=0D +Copyright (c) 2024, Intel Corporation. All rights reserved.
=0D +SPDX-License-Identifier: BSD-2-Clause-Patent=0D +=0D +**/=0D +=0D +#ifndef SPDM_LIB_CONFIG_H=0D +#define SPDM_LIB_CONFIG_H=0D +=0D +/* Enables assertions and debug printing. When `LIBSPDM_DEBUG_ENABLE` is d= efined it overrides or=0D + * sets the values of `LIBSPDM_DEBUG_PRINT_ENABLE`, `LIBSPDM_DEBUG_ASSERT_= ENABLE`, and=0D + * `LIBSPDM_BLOCK_ENABLE` to the value of `LIBSPDM_DEBUG_ENABLE`.=0D + *=0D + * Note that if this file is used with CMake and `DTARGET=3DRelease` is de= fined, then all debugging=0D + * is disabled.=0D + */=0D +#ifndef LIBSPDM_DEBUG_ENABLE=0D +#define LIBSPDM_DEBUG_ENABLE 1=0D +#endif=0D +=0D +/* The SPDM specification allows a Responder to return up to 256 version e= ntries in the `VERSION`=0D + * response to the Requester, including duplicate entries. For a Requester= this value specifies the=0D + * maximum number of entries that libspdm will tolerate in a `VERSION` res= ponse before returning an=0D + * error. A similiar macro, `SPDM_MAX_VERSION_COUNT`, exists for the Respo= nder. However this macro=0D + * is not meant to be configured by the integrator.=0D + */=0D +#ifndef LIBSPDM_MAX_VERSION_COUNT=0D +#define LIBSPDM_MAX_VERSION_COUNT 5=0D +#endif=0D +=0D +/* This value specifies the maximum size, in bytes, of the `PSK_EXCHANGE.R= equesterContext` and,=0D + * if supported by the Responder, `PSK_EXCHANGE_RSP.ResponderContext` fiel= ds. The fields are=0D + * typically random or monotonically increasing numbers.=0D + */=0D +#ifndef LIBSPDM_PSK_CONTEXT_LENGTH=0D +#define LIBSPDM_PSK_CONTEXT_LENGTH LIBSPDM_MAX_HASH_SIZE=0D +#endif=0D +/* This value specifies the maximum size, in bytes, of the `PSK_EXCHANGE.P= SKHint` field.*/=0D +#ifndef LIBSPDM_PSK_MAX_HINT_LENGTH=0D +#define LIBSPDM_PSK_MAX_HINT_LENGTH 16=0D +#endif=0D +=0D +/* libspdm allows an integrator to specify multiple root certificates as t= rust anchors when=0D + * verifying certificate chains from an endpoint. This value specifies the= maximum number of root=0D + * certificates that libspdm can support.=0D + */=0D +#ifndef LIBSPDM_MAX_ROOT_CERT_SUPPORT=0D +#define LIBSPDM_MAX_ROOT_CERT_SUPPORT 10=0D +#endif=0D +=0D +/* If the Responder supports it a Requester is allowed to establish multip= le secure sessions with=0D + * the Responder. This value specifies the maximum number of sessions libs= pdm can support.=0D + */=0D +#ifndef LIBSPDM_MAX_SESSION_COUNT=0D +#define LIBSPDM_MAX_SESSION_COUNT 4=0D +#endif=0D +=0D +/* This value specifies the maximum size, in bytes, of a certificate chain= that can be stored in a=0D + * libspdm context.=0D + */=0D +#ifndef LIBSPDM_MAX_CERT_CHAIN_SIZE=0D +#define LIBSPDM_MAX_CERT_CHAIN_SIZE 0x1000=0D +#endif=0D +#ifndef LIBSPDM_MAX_MEASUREMENT_RECORD_SIZE=0D +#define LIBSPDM_MAX_MEASUREMENT_RECORD_SIZE 0x1000=0D +#endif=0D +=0D +/* Partial certificates can be retrieved from a Requester or Responder and= through multiple messages=0D + * the complete certificate chain can be constructed. This value specifies= the maximum size,=0D + * in bytes, of a partial certificate that can be sent or received.=0D + */=0D +#ifndef LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN=0D +#define LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN 1024=0D +#endif=0D +=0D +/* To ensure integrity in communication between the Requester and the Resp= onder libspdm calculates=0D + * cryptographic digests and signatures over multiple requests and respons= es. This value specifies=0D + * whether libspdm will use a running calculation over the transcript, whe= re requests and responses=0D + * are discarded as they are cryptographically consumed, or whether libspd= m will buffer the entire=0D + * transcript before calculating the digest or signature.=0D + */=0D +#ifndef LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT=0D +#define LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT 0=0D +#endif=0D +=0D +/* Cryptography Configuration=0D + * In each category, at least one should be selected.=0D + * NOTE: Not all combination can be supported. E.g. Don't mix NIST algo wi= th SMx.*/=0D +=0D +#ifndef LIBSPDM_RSA_SSA_2048_SUPPORT=0D +#define LIBSPDM_RSA_SSA_2048_SUPPORT 1=0D +#endif=0D +#ifndef LIBSPDM_RSA_SSA_3072_SUPPORT=0D +#define LIBSPDM_RSA_SSA_3072_SUPPORT 1=0D +#endif=0D +#ifndef LIBSPDM_RSA_SSA_4096_SUPPORT=0D +#define LIBSPDM_RSA_SSA_4096_SUPPORT 1=0D +#endif=0D +=0D +#ifndef LIBSPDM_RSA_PSS_2048_SUPPORT=0D +#define LIBSPDM_RSA_PSS_2048_SUPPORT 0=0D +#endif=0D +#ifndef LIBSPDM_RSA_PSS_3072_SUPPORT=0D +#define LIBSPDM_RSA_PSS_3072_SUPPORT 0=0D +#endif=0D +#ifndef LIBSPDM_RSA_PSS_4096_SUPPORT=0D +#define LIBSPDM_RSA_PSS_4096_SUPPORT 0=0D +#endif=0D +=0D +#ifndef LIBSPDM_ECDSA_P256_SUPPORT=0D +#define LIBSPDM_ECDSA_P256_SUPPORT 1=0D +#endif=0D +#ifndef LIBSPDM_ECDSA_P384_SUPPORT=0D +#define LIBSPDM_ECDSA_P384_SUPPORT 1=0D +#endif=0D +#ifndef LIBSPDM_ECDSA_P521_SUPPORT=0D +#define LIBSPDM_ECDSA_P521_SUPPORT 1=0D +#endif=0D +=0D +#ifndef LIBSPDM_SM2_DSA_P256_SUPPORT=0D +#define LIBSPDM_SM2_DSA_P256_SUPPORT 0=0D +#endif=0D +=0D +#ifndef LIBSPDM_EDDSA_ED25519_SUPPORT=0D +#define LIBSPDM_EDDSA_ED25519_SUPPORT 0=0D +#endif=0D +#ifndef LIBSPDM_EDDSA_ED448_SUPPORT=0D +#define LIBSPDM_EDDSA_ED448_SUPPORT 0=0D +#endif=0D +=0D +#ifndef LIBSPDM_FFDHE_2048_SUPPORT=0D +#define LIBSPDM_FFDHE_2048_SUPPORT 0=0D +#endif=0D +#ifndef LIBSPDM_FFDHE_3072_SUPPORT=0D +#define LIBSPDM_FFDHE_3072_SUPPORT 0=0D +#endif=0D +#ifndef LIBSPDM_FFDHE_4096_SUPPORT=0D +#define LIBSPDM_FFDHE_4096_SUPPORT 0=0D +#endif=0D +=0D +#ifndef LIBSPDM_ECDHE_P256_SUPPORT=0D +#define LIBSPDM_ECDHE_P256_SUPPORT 1=0D +#endif=0D +#ifndef LIBSPDM_ECDHE_P384_SUPPORT=0D +#define LIBSPDM_ECDHE_P384_SUPPORT 1=0D +#endif=0D +#ifndef LIBSPDM_ECDHE_P521_SUPPORT=0D +#define LIBSPDM_ECDHE_P521_SUPPORT 1=0D +#endif=0D +=0D +#ifndef LIBSPDM_SM2_KEY_EXCHANGE_P256_SUPPORT=0D +#define LIBSPDM_SM2_KEY_EXCHANGE_P256_SUPPORT 0=0D +#endif=0D +=0D +#ifndef LIBSPDM_AEAD_AES_128_GCM_SUPPORT=0D +#define LIBSPDM_AEAD_AES_128_GCM_SUPPORT 1=0D +#endif=0D +#ifndef LIBSPDM_AEAD_AES_256_GCM_SUPPORT=0D +#define LIBSPDM_AEAD_AES_256_GCM_SUPPORT 1=0D +#endif=0D +=0D +#ifndef LIBSPDM_AEAD_CHACHA20_POLY1305_SUPPORT=0D +#define LIBSPDM_AEAD_CHACHA20_POLY1305_SUPPORT 0=0D +#endif=0D +=0D +#ifndef LIBSPDM_AEAD_SM4_128_GCM_SUPPORT=0D +#define LIBSPDM_AEAD_SM4_128_GCM_SUPPORT 0=0D +#endif=0D +=0D +#ifndef LIBSPDM_SHA256_SUPPORT=0D +#define LIBSPDM_SHA256_SUPPORT 1=0D +#endif=0D +#ifndef LIBSPDM_SHA384_SUPPORT=0D +#define LIBSPDM_SHA384_SUPPORT 1=0D +#endif=0D +#ifndef LIBSPDM_SHA512_SUPPORT=0D +#define LIBSPDM_SHA512_SUPPORT 0=0D +#endif=0D +=0D +#ifndef LIBSPDM_SHA3_256_SUPPORT=0D +#define LIBSPDM_SHA3_256_SUPPORT 0=0D +#endif=0D +#ifndef LIBSPDM_SHA3_384_SUPPORT=0D +#define LIBSPDM_SHA3_384_SUPPORT 0=0D +#endif=0D +#ifndef LIBSPDM_SHA3_512_SUPPORT=0D +#define LIBSPDM_SHA3_512_SUPPORT 0=0D +#endif=0D +=0D +#ifndef LIBSPDM_SM3_256_SUPPORT=0D +#define LIBSPDM_SM3_256_SUPPORT 0=0D +#endif=0D +=0D +/* This can be set to 0 for the device which does not need X509 parser.*/= =0D +#ifndef LIBSPDM_CERT_PARSE_SUPPORT=0D +#define LIBSPDM_CERT_PARSE_SUPPORT 1=0D +#endif=0D +=0D +/* Code space optimization for Optional request/response messages.*/=0D +=0D +/* Consumers of libspdm may wish to not fully implement all of the optiona= l=0D + * SPDM request/response messages. Therefore we have provided these=0D + * SPDM_ENABLE_CAPABILITY_***_CAP compile time switches as an optimization= =0D + * disable the code (#if 0) related to said optional capability, thereby=0D + * reducing the code space used in the image.*/=0D +=0D +/* A single switch may enable/disable a single capability or group of rela= ted=0D + * capabilities.*/=0D +=0D +/* LIBSPDM_ENABLE_CAPABILITY_CERT_CAP - Enable/Disable single CERT capabil= ity.=0D + * LIBSPDM_ENABLE_CAPABILITY_CHAL_CAP - Enable/Disable single CHAL capabil= ity.=0D + * LIBSPDM_ENABLE_CAPABILITY_MEAS_CAP - Enable/Disables multiple MEAS capa= bilities:=0D + * (MEAS_CAP_NO_SIG, MEAS_CAP_SIG, MEAS_F= RESH_CAP)*/=0D +=0D +/* LIBSPDM_ENABLE_CAPABILITY_KEY_EX_CAP - Enable/Disable single Key Exchan= ge capability.=0D + * LIBSPDM_ENABLE_CAPABILITY_PSK_EX_CAP - Enable/Disable PSK_EX and PSK_FI= NISH.*/=0D +=0D +/* LIBSPDM_ENABLE_CAPABILITY_MUT_AUTH_CAP - Enable/Disable mutual authenti= cation.=0D +* LIBSPDM_ENABLE_CAPABILITY_ENCAP_CAP - Enable/Disable encapsulated mes= sage.*/=0D +=0D +/* LIBSPDM_ENABLE_CAPABILITY_CSR_CAP - Enable/Disable get csr capability.= =0D + * LIBSPDM_ENABLE_CAPABILITY_SET_CERT_CAP - Enable/Disable set certificate= capability. */=0D +=0D +#ifndef LIBSPDM_ENABLE_CAPABILITY_CERT_CAP=0D +#define LIBSPDM_ENABLE_CAPABILITY_CERT_CAP 1=0D +#endif=0D +#ifndef LIBSPDM_ENABLE_CAPABILITY_CHAL_CAP=0D +#define LIBSPDM_ENABLE_CAPABILITY_CHAL_CAP 1=0D +#endif=0D +#ifndef LIBSPDM_ENABLE_CAPABILITY_MEAS_CAP=0D +#define LIBSPDM_ENABLE_CAPABILITY_MEAS_CAP 1=0D +#endif=0D +=0D +#ifndef LIBSPDM_ENABLE_CAPABILITY_KEY_EX_CAP=0D +#define LIBSPDM_ENABLE_CAPABILITY_KEY_EX_CAP 0=0D +#endif=0D +#ifndef LIBSPDM_ENABLE_CAPABILITY_PSK_EX_CAP=0D +#define LIBSPDM_ENABLE_CAPABILITY_PSK_EX_CAP 0=0D +#endif=0D +=0D +#ifndef LIBSPDM_ENABLE_CAPABILITY_HBEAT_CAP=0D +#define LIBSPDM_ENABLE_CAPABILITY_HBEAT_CAP 0=0D +#endif=0D +=0D +#ifndef LIBSPDM_ENABLE_CAPABILITY_MUT_AUTH_CAP=0D +#define LIBSPDM_ENABLE_CAPABILITY_MUT_AUTH_CAP 0=0D +#endif=0D +=0D +#ifndef LIBSPDM_ENABLE_CAPABILITY_ENCAP_CAP=0D +#define LIBSPDM_ENABLE_CAPABILITY_ENCAP_CAP 0=0D +#endif=0D +=0D +#ifndef LIBSPDM_ENABLE_CAPABILITY_CSR_CAP=0D +#define LIBSPDM_ENABLE_CAPABILITY_CSR_CAP 0=0D +#endif=0D +=0D +#ifndef LIBSPDM_ENABLE_CAPABILITY_SET_CERT_CAP=0D +#define LIBSPDM_ENABLE_CAPABILITY_SET_CERT_CAP 0=0D +#endif=0D +=0D +#ifndef LIBSPDM_ENABLE_CAPABILITY_CHUNK_CAP=0D +#define LIBSPDM_ENABLE_CAPABILITY_CHUNK_CAP 0=0D +#endif=0D +=0D +/* If 1 then endpoint supports sending GET_CERTIFICATE and GET_DIGESTS req= uests.=0D + * If enabled and endpoint is a Responder then LIBSPDM_ENABLE_CAPABILITY_E= NCAP_CAP=0D + * must also be enabled.=0D + */=0D +#ifndef LIBSPDM_SEND_GET_CERTIFICATE_SUPPORT=0D +#define LIBSPDM_SEND_GET_CERTIFICATE_SUPPORT 1=0D +#endif=0D +=0D +/* If 1 then endpoint supports sending CHALLENGE request.=0D + * If enabled and endpoint is a Responder then LIBSPDM_ENABLE_CAPABILITY_E= NCAP_CAP=0D + * must also be enabled.=0D + */=0D +#ifndef LIBSPDM_SEND_CHALLENGE_SUPPORT=0D +#define LIBSPDM_SEND_CHALLENGE_SUPPORT 1=0D +#endif=0D +=0D +/* When LIBSPDM_RESPOND_IF_READY_SUPPORT is 0 then=0D + * - For a Requester, if the Responder sends a ResponseNotReady ERROR= response then the error=0D + * is immediately returned to the Integrator. The Requester cannot = send a RESPOND_IF_READY=0D + * request.=0D + * - For a Responder, it cannot send a RESPOND_IF_READY ERROR respons= e and does not support=0D + * RESPOND_IF_READY.=0D + * When LIBSPDM_RESPOND_IF_READY_SUPPORT is 1 then=0D + * - For a Requester, if the Responder sends a ResponseNotReady ERROR= response then libspdm=0D + * waits an amount of time, as specified by the RDTExponent paramet= er, before sending=0D + * RESPOND_IF_READY.=0D + * - For a Responder, if its response state is NOT_READY then it will= send a ResponseNotReady=0D + * ERROR response to the Requester, and will accept a subsequent RE= SPOND_IF_READY request.=0D + */=0D +#ifndef LIBSPDM_RESPOND_IF_READY_SUPPORT=0D +#define LIBSPDM_RESPOND_IF_READY_SUPPORT 1=0D +#endif=0D +=0D +/*=0D + * MinDataTransferSize =3D 42=0D + *=0D + * H =3D HashLen =3D HmacLen =3D [32, 64]=0D + * S =3D SigLen =3D [64, 512]=0D + * D =3D ExchangeDataLen =3D [64, 512]=0D + * R =3D RequesterContextLen >=3D 32=0D + * R =3D ResponderContextLen >=3D 0=0D + * O =3D OpaqueDataLen <=3D 1024=0D + *=0D + * Max Chunk No =3D 1, if (message size <=3D 42)=0D + * Max Chunk No =3D [(message size + 4) / 30] roundup, if (message size > = 42)=0D + *=0D + * +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D+=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D+=3D=3D=3D= =3D=3D=3D=3D=3D=3D+=0D + * | Command | Size |= MaxChunk |=0D + * +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D+=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D+=3D=3D=3D= =3D=3D=3D=3D=3D=3D+=0D + * | GET_VERSION | 4 |= 1 |=0D + * | VERSION {1.0, 1.1, 1.2} | 6 + 2 * 3 =3D 12 = | 1 |=0D + * +--------------------------+------------------------------------------+= ---------+=0D + * | GET_CAPABILITIES 1.2 | 20 |= 1 |=0D + * | CAPABILITIES 1.2 | 20 |= 1 |=0D + * +--------------------------+------------------------------------------+= ---------+=0D + * | ERROR | 4 |= 1 |=0D + * | ERROR(ResponseTooLarge) | 4 + 4 =3D 8 = | 1 |=0D + * | ERROR(LargeResponse) | 4 + 1 =3D 5 = | 1 |=0D + * | ERROR(ResponseNotReady) | 4 + 4 =3D 8 = | 1 |=0D + * +--------------------------+------------------------------------------+= ---------+=0D + * | CHUNK_SEND header | 12 + L0 (0 or 4) |= 1 |=0D + * | CHUNK_RESPONSE header | 12 + L0 (0 or 4) |= 1 |=0D + * +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D+=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D+=3D=3D=3D= =3D=3D=3D=3D=3D=3D+=0D + * | NEGOTIATE_ALGORITHMS 1.2 | 32 + 4 * 4 =3D 48 = | 2 |=0D + * | ALGORITHMS 1.2 | 36 + 4 * 4 =3D 52 = | 2 |=0D + * +--------------------------+------------------------------------------+= ---------+=0D + * | GET_DIGESTS 1.2 | 4 |= 1 |=0D + * | DIGESTS 1.2 | 4 + H * SlotNum =3D [36, 516] = | [1, 18] |=0D + * +--------------------------+------------------------------------------+= ---------+=0D + * | GET_CERTIFICATE 1.2 | 8 |= 1 |=0D + * | CERTIFICATE 1.2 | 8 + PortionLen |= [1, ] |=0D + * +--------------------------+------------------------------------------+= ---------+=0D + * | CHALLENGE 1.2 | 40 |= 1 |=0D + * | CHALLENGE_AUTH 1.2 | 38 + H * 2 + S [+ O] =3D [166, 678] = | [6, 23] |=0D + * +--------------------------+------------------------------------------+= ---------+=0D + * | GET_MEASUREMENTS 1.2 | 5 + Nonce (0 or 32) |= 1 |=0D + * | MEASUREMENTS 1.2 | 42 + MeasRecLen (+ S) [+ O] =3D [106, 554]= | [4, 19] |=0D + * +--------------------------+------------------------------------------+= ---------+=0D + * | KEY_EXCHANGE 1.2 | 42 + D [+ O] =3D [106, 554] = | [4, 19] |=0D + * | KEY_EXCHANGE_RSP 1.2 | 42 + D + H + S (+ H) [+ O] =3D [234, 1194]= | [8, 40] |=0D + * +--------------------------+------------------------------------------+= ---------+=0D + * | FINISH 1.2 | 4 (+ S) + H =3D [100, 580] = | [4, 20] |=0D + * | FINISH_RSP 1.2 | 4 (+ H) =3D [36, 69] = | [1, 3] |=0D + * +--------------------------+------------------------------------------+= ---------+=0D + * | PSK_EXCHANGE 1.2 | 12 [+ PSKHint] + R [+ O] =3D 44 = | 2 |=0D + * | PSK_EXCHANGE_RSP 1.2 | 12 + R + H (+ H) [+ O] =3D [108, 172] = | [4, 6] |=0D + * +--------------------------+------------------------------------------+= ---------+=0D + * | PSK_FINISH 1.2 | 4 + H =3D [36, 68] = | [1, 3] |=0D + * | PSK_FINISH_RSP 1.2 | 4 |= 1 |=0D + * +--------------------------+------------------------------------------+= ---------+=0D + * | GET_CSR 1.2 | 8 + RequesterInfoLen [+ O] |= [1, ] |=0D + * | CSR 1.2 | 8 + CSRLength |= [1, ] |=0D + * +--------------------------+------------------------------------------+= ---------+=0D + * | SET_CERTIFICATE 1.2 | 4 + CertChainLen |= [1, ] |=0D + * | SET_CERTIFICATE_RSP 1.2 | 4 |= 1 |=0D + * +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D+=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D+=3D=3D=3D= =3D=3D=3D=3D=3D=3D+=0D + */=0D +=0D +/* Required sender/receive buffer in device io.=0D + * NOTE: This is transport specific. Below configuration is just an exampl= e.=0D + * +-------+--------+---------------------------+------+--+------+---+----= ----+-----+=0D + * | TYPE |TransHdr| EncryptionHeader |AppHdr| |Random|MAC|Alig= nPad|FINAL|=0D + * | | |SessionId|SeqNum|Len|AppLen| | | | | = | |=0D + * +-------+--------+---------------------------+------+ +------+---+----= ----+-----+=0D + * | MCTP | 1 | 4 | 2 | 2 | 2 | 1 | | 32 | 12| 0= | 56 |=0D + * |PCI_DOE| 8 | 4 | 0 | 2 | 2 | 0 | | 0 | 12| 3= | 31 |=0D + * +-------+--------+---------------------------+------+--+------+---+----= ----+-----+=0D + */=0D +=0D +/* Enable message logging.=0D + * See https://github.com/DMTF/libspdm/blob/main/doc/user_guide.md#message= -logging=0D + * for more information */=0D +#ifndef LIBSPDM_ENABLE_MSG_LOG=0D +#define LIBSPDM_ENABLE_MSG_LOG 1=0D +#endif=0D +=0D +/* Enable macro checking during compilation. */=0D +#ifndef LIBSPDM_CHECK_MACRO=0D +#define LIBSPDM_CHECK_MACRO 0=0D +#endif=0D +=0D +/* Enable checks to the SPDM context during runtime. */=0D +#ifndef LIBSPDM_CHECK_SPDM_CONTEXT=0D +#define LIBSPDM_CHECK_SPDM_CONTEXT 1=0D +#endif=0D +=0D +#endif /* SPDM_LIB_CONFIG_H */=0D diff --git a/SecurityPkg/DeviceSecurity/SpdmLib/SpdmCommonLib.inf b/Securit= yPkg/DeviceSecurity/SpdmLib/SpdmCommonLib.inf new file mode 100644 index 0000000000..a0c62bbad0 --- /dev/null +++ b/SecurityPkg/DeviceSecurity/SpdmLib/SpdmCommonLib.inf @@ -0,0 +1,47 @@ +## @file=0D +# SPDM library.=0D +#=0D +# Copyright (c) 2024, Intel Corporation. All rights reserved.
=0D +#=0D +# SPDX-License-Identifier: BSD-2-Clause-Patent=0D +#=0D +##=0D +=0D +[Defines]=0D + INF_VERSION =3D 0x00010005=0D + BASE_NAME =3D SpdmCommonLib=0D + FILE_GUID =3D 4D42800D-2197-46EC-8E04-6B41BFD60687= =0D + MODULE_TYPE =3D BASE=0D + VERSION_STRING =3D 1.0=0D + LIBRARY_CLASS =3D SpdmCommonLib=0D +=0D +#=0D +# The following information is for reference only and not required by the = build tools.=0D +#=0D +# VALID_ARCHITECTURES =3D IA32 X64 AARCH64=0D +#=0D +=0D +[Sources]=0D + libspdm/library/spdm_common_lib/libspdm_com_context_data.c=0D + libspdm/library/spdm_common_lib/libspdm_com_context_data_session.c=0D + libspdm/library/spdm_common_lib/libspdm_com_crypto_service.c=0D + libspdm/library/spdm_common_lib/libspdm_com_crypto_service_session.c=0D + libspdm/library/spdm_common_lib/libspdm_com_opaque_data.c=0D + libspdm/library/spdm_common_lib/libspdm_com_support.c=0D + libspdm/library/spdm_common_lib/libspdm_com_msg_log.c=0D +=0D +[Packages]=0D + MdePkg/MdePkg.dec=0D + SecurityPkg/SecurityPkg.dec=0D + CryptoPkg/CryptoPkg.dec=0D +=0D +[LibraryClasses]=0D + BaseLib=0D + BaseMemoryLib=0D + DebugLib=0D + BaseCryptLib=0D + RngLib=0D + SpdmCryptLib=0D + SpdmDeviceSecretLib=0D + MemLibWrapper=0D + CryptlibWrapper=0D diff --git a/SecurityPkg/DeviceSecurity/SpdmLib/SpdmCryptLib.inf b/Security= Pkg/DeviceSecurity/SpdmLib/SpdmCryptLib.inf new file mode 100644 index 0000000000..5e91968576 --- /dev/null +++ b/SecurityPkg/DeviceSecurity/SpdmLib/SpdmCryptLib.inf @@ -0,0 +1,45 @@ +## @file=0D +# SPDM library.=0D +#=0D +# Copyright (c) 2024, Intel Corporation. All rights reserved.
=0D +#=0D +# SPDX-License-Identifier: BSD-2-Clause-Patent=0D +#=0D +##=0D +=0D +[Defines]=0D + INF_VERSION =3D 0x00010005=0D + BASE_NAME =3D SpdmCryptLib=0D + FILE_GUID =3D 2FF3E7F6-D95A-48A2-B418-9B6D585C1D7E= =0D + MODULE_TYPE =3D BASE=0D + VERSION_STRING =3D 1.0=0D + LIBRARY_CLASS =3D SpdmCryptLib=0D +=0D +#=0D +# The following information is for reference only and not required by the = build tools.=0D +#=0D +# VALID_ARCHITECTURES =3D IA32 X64 AARCH64=0D +#=0D +=0D +[Sources]=0D + libspdm/library/spdm_crypt_lib/libspdm_crypt_aead.c=0D + libspdm/library/spdm_crypt_lib/libspdm_crypt_asym.c=0D + libspdm/library/spdm_crypt_lib/libspdm_crypt_cert.c=0D + libspdm/library/spdm_crypt_lib/libspdm_crypt_dhe.c=0D + libspdm/library/spdm_crypt_lib/libspdm_crypt_hash.c=0D + libspdm/library/spdm_crypt_lib/libspdm_crypt_hkdf.c=0D + libspdm/library/spdm_crypt_lib/libspdm_crypt_hmac.c=0D + libspdm/library/spdm_crypt_lib/libspdm_crypt_rng.c=0D +=0D +[Packages]=0D + MdePkg/MdePkg.dec=0D + SecurityPkg/SecurityPkg.dec=0D + CryptoPkg/CryptoPkg.dec=0D +=0D +[LibraryClasses]=0D + BaseLib=0D + BaseMemoryLib=0D + DebugLib=0D + BaseCryptLib=0D + RngLib=0D + MemLibWrapper=0D diff --git a/SecurityPkg/DeviceSecurity/SpdmLib/SpdmDeviceSecretLibNull.inf= b/SecurityPkg/DeviceSecurity/SpdmLib/SpdmDeviceSecretLibNull.inf new file mode 100644 index 0000000000..47f9fe9fe5 --- /dev/null +++ b/SecurityPkg/DeviceSecurity/SpdmLib/SpdmDeviceSecretLibNull.inf @@ -0,0 +1,36 @@ +## @file=0D +# SPDM library.=0D +#=0D +# Copyright (c) 2024, Intel Corporation. All rights reserved.
=0D +#=0D +# SPDX-License-Identifier: BSD-2-Clause-Patent=0D +#=0D +##=0D +=0D +[Defines]=0D + INF_VERSION =3D 0x00010005=0D + BASE_NAME =3D SpdmDeviceSecretLibNull=0D + FILE_GUID =3D E2FFA5F9-CD19-4B63-AE3E-7EA288243EED= =0D + MODULE_TYPE =3D BASE=0D + VERSION_STRING =3D 1.0=0D + LIBRARY_CLASS =3D SpdmDeviceSecretLib=0D +=0D +#=0D +# The following information is for reference only and not required by the = build tools.=0D +#=0D +# VALID_ARCHITECTURES =3D IA32 X64 AARCH64=0D +#=0D +=0D +[Sources]=0D + libspdm/os_stub/spdm_device_secret_lib_null/lib.c=0D +=0D +[Packages]=0D + MdePkg/MdePkg.dec=0D + SecurityPkg/SecurityPkg.dec=0D + CryptoPkg/CryptoPkg.dec=0D +=0D +[LibraryClasses]=0D + BaseLib=0D + BaseMemoryLib=0D + DebugLib=0D + MemLibWrapper=0D diff --git a/SecurityPkg/DeviceSecurity/SpdmLib/SpdmRequesterLib.inf b/Secu= rityPkg/DeviceSecurity/SpdmLib/SpdmRequesterLib.inf new file mode 100644 index 0000000000..4fcefe32dc --- /dev/null +++ b/SecurityPkg/DeviceSecurity/SpdmLib/SpdmRequesterLib.inf @@ -0,0 +1,59 @@ +## @file=0D +# SPDM library.=0D +#=0D +# Copyright (c) 2024, Intel Corporation. All rights reserved.
=0D +#=0D +# SPDX-License-Identifier: BSD-2-Clause-Patent=0D +#=0D +##=0D +=0D +[Defines]=0D + INF_VERSION =3D 0x00010005=0D + BASE_NAME =3D SpdmRequesterLib=0D + FILE_GUID =3D 8B6024A3-270A-410F-91AB-9E99F05C2A58= =0D + MODULE_TYPE =3D BASE=0D + VERSION_STRING =3D 1.0=0D + LIBRARY_CLASS =3D SpdmRequesterLib=0D +=0D +#=0D +# The following information is for reference only and not required by the = build tools.=0D +#=0D +# VALID_ARCHITECTURES =3D IA32 X64 AARCH64=0D +#=0D +=0D +[Sources]=0D + libspdm/library/spdm_requester_lib/libspdm_req_challenge.c=0D + libspdm/library/spdm_requester_lib/libspdm_req_common.c=0D + libspdm/library/spdm_requester_lib/libspdm_req_communication.c=0D + libspdm/library/spdm_requester_lib/libspdm_req_encap_certificate.c=0D + libspdm/library/spdm_requester_lib/libspdm_req_encap_challenge_auth.c=0D + libspdm/library/spdm_requester_lib/libspdm_req_encap_digests.c=0D + libspdm/library/spdm_requester_lib/libspdm_req_encap_error.c=0D + libspdm/library/spdm_requester_lib/libspdm_req_encap_key_update.c=0D + libspdm/library/spdm_requester_lib/libspdm_req_encap_request.c=0D + libspdm/library/spdm_requester_lib/libspdm_req_end_session.c=0D + libspdm/library/spdm_requester_lib/libspdm_req_finish.c=0D + libspdm/library/spdm_requester_lib/libspdm_req_get_capabilities.c=0D + libspdm/library/spdm_requester_lib/libspdm_req_get_certificate.c=0D + libspdm/library/spdm_requester_lib/libspdm_req_get_digests.c=0D + libspdm/library/spdm_requester_lib/libspdm_req_get_measurements.c=0D + libspdm/library/spdm_requester_lib/libspdm_req_get_version.c=0D + libspdm/library/spdm_requester_lib/libspdm_req_handle_error_response.c=0D + libspdm/library/spdm_requester_lib/libspdm_req_heartbeat.c=0D + libspdm/library/spdm_requester_lib/libspdm_req_key_exchange.c=0D + libspdm/library/spdm_requester_lib/libspdm_req_key_update.c=0D + libspdm/library/spdm_requester_lib/libspdm_req_negotiate_algorithms.c=0D + libspdm/library/spdm_requester_lib/libspdm_req_psk_exchange.c=0D + libspdm/library/spdm_requester_lib/libspdm_req_psk_finish.c=0D + libspdm/library/spdm_requester_lib/libspdm_req_send_receive.c=0D +=0D +[Packages]=0D + MdePkg/MdePkg.dec=0D + SecurityPkg/SecurityPkg.dec=0D + CryptoPkg/CryptoPkg.dec=0D +=0D +[LibraryClasses]=0D + SpdmCommonLib=0D + SpdmSecuredMessageLib=0D + PlatformLibWrapper=0D + MemLibWrapper=0D diff --git a/SecurityPkg/DeviceSecurity/SpdmLib/SpdmResponderLib.inf b/Secu= rityPkg/DeviceSecurity/SpdmLib/SpdmResponderLib.inf new file mode 100644 index 0000000000..61528a80ab --- /dev/null +++ b/SecurityPkg/DeviceSecurity/SpdmLib/SpdmResponderLib.inf @@ -0,0 +1,61 @@ +## @file=0D +# SPDM library.=0D +#=0D +# Copyright (c) 2024, Intel Corporation. All rights reserved.
=0D +#=0D +# SPDX-License-Identifier: BSD-2-Clause-Patent=0D +#=0D +##=0D +=0D +[Defines]=0D + INF_VERSION =3D 0x00010005=0D + BASE_NAME =3D SpdmResponderLib=0D + FILE_GUID =3D 9005B3A3-45F1-4DE9-93FF-2512D4B9CCFA= =0D + MODULE_TYPE =3D BASE=0D + VERSION_STRING =3D 1.0=0D + LIBRARY_CLASS =3D SpdmResponderLib=0D +=0D +#=0D +# The following information is for reference only and not required by the = build tools.=0D +#=0D +# VALID_ARCHITECTURES =3D IA32 X64 AARCH64=0D +#=0D +=0D +[Sources]=0D + libspdm/library/spdm_responder_lib/libspdm_rsp_algorithms.c=0D + libspdm/library/spdm_responder_lib/libspdm_rsp_capabilities.c=0D + libspdm/library/spdm_responder_lib/libspdm_rsp_certificate.c=0D + libspdm/library/spdm_responder_lib/libspdm_rsp_challenge_auth.c=0D + libspdm/library/spdm_responder_lib/libspdm_rsp_common.c=0D + libspdm/library/spdm_responder_lib/libspdm_rsp_communication.c=0D + libspdm/library/spdm_responder_lib/libspdm_rsp_digests.c=0D + libspdm/library/spdm_responder_lib/libspdm_rsp_encap_challenge.c=0D + libspdm/library/spdm_responder_lib/libspdm_rsp_encap_get_certificate.c=0D + libspdm/library/spdm_responder_lib/libspdm_rsp_encap_get_digests.c=0D + libspdm/library/spdm_responder_lib/libspdm_rsp_encap_key_update.c=0D + libspdm/library/spdm_responder_lib/libspdm_rsp_encap_response.c=0D + libspdm/library/spdm_responder_lib/libspdm_rsp_end_session.c=0D + libspdm/library/spdm_responder_lib/libspdm_rsp_error.c=0D + libspdm/library/spdm_responder_lib/libspdm_rsp_finish.c=0D + libspdm/library/spdm_responder_lib/libspdm_rsp_handle_response_state.c=0D + libspdm/library/spdm_responder_lib/libspdm_rsp_heartbeat.c=0D + libspdm/library/spdm_responder_lib/libspdm_rsp_key_exchange.c=0D + libspdm/library/spdm_responder_lib/libspdm_rsp_key_update.c=0D + libspdm/library/spdm_responder_lib/libspdm_rsp_measurements.c=0D + libspdm/library/spdm_responder_lib/libspdm_rsp_psk_exchange.c=0D + libspdm/library/spdm_responder_lib/libspdm_rsp_psk_finish.c=0D + libspdm/library/spdm_responder_lib/libspdm_rsp_receive_send.c=0D + libspdm/library/spdm_responder_lib/libspdm_rsp_respond_if_ready.c=0D + libspdm/library/spdm_responder_lib/libspdm_rsp_version.c=0D + libspdm/library/spdm_responder_lib/libspdm_rsp_csr.c=0D +=0D +[Packages]=0D + MdePkg/MdePkg.dec=0D + SecurityPkg/SecurityPkg.dec=0D + CryptoPkg/CryptoPkg.dec=0D +=0D +[LibraryClasses]=0D + SpdmCommonLib=0D + SpdmSecuredMessageLib=0D + PlatformLibWrapper=0D + MemLibWrapper=0D diff --git a/SecurityPkg/DeviceSecurity/SpdmLib/SpdmSecuredMessageLib.inf b= /SecurityPkg/DeviceSecurity/SpdmLib/SpdmSecuredMessageLib.inf new file mode 100644 index 0000000000..062bf77158 --- /dev/null +++ b/SecurityPkg/DeviceSecurity/SpdmLib/SpdmSecuredMessageLib.inf @@ -0,0 +1,44 @@ +## @file=0D +# SPDM library.=0D +#=0D +# Copyright (c) 2024, Intel Corporation. All rights reserved.
=0D +#=0D +# SPDX-License-Identifier: BSD-2-Clause-Patent=0D +#=0D +##=0D +=0D +[Defines]=0D + INF_VERSION =3D 0x00010005=0D + BASE_NAME =3D SpdmSecuredMessageLib=0D + FILE_GUID =3D C5E91542-9B57-4BC4-988C-2DEB0B17D381= =0D + MODULE_TYPE =3D BASE=0D + VERSION_STRING =3D 1.0=0D + LIBRARY_CLASS =3D SpdmSecuredMessageLib=0D +=0D +#=0D +# The following information is for reference only and not required by the = build tools.=0D +#=0D +# VALID_ARCHITECTURES =3D IA32 X64 AARCH64=0D +#=0D +=0D +[Sources]=0D + libspdm/library/spdm_secured_message_lib/libspdm_secmes_context_data.c=0D + libspdm/library/spdm_secured_message_lib/libspdm_secmes_encode_decode.c= =0D + libspdm/library/spdm_secured_message_lib/libspdm_secmes_encode_decode.c= =0D + libspdm/library/spdm_secured_message_lib/libspdm_secmes_key_exchange.c=0D + libspdm/library/spdm_secured_message_lib/libspdm_secmes_session.c=0D +=0D +[Packages]=0D + MdePkg/MdePkg.dec=0D + SecurityPkg/SecurityPkg.dec=0D + CryptoPkg/CryptoPkg.dec=0D +=0D +[LibraryClasses]=0D + BaseLib=0D + BaseMemoryLib=0D + DebugLib=0D + BaseCryptLib=0D + RngLib=0D + SpdmCryptLib=0D + SpdmDeviceSecretLib=0D + MemLibWrapper=0D diff --git a/SecurityPkg/DeviceSecurity/SpdmLib/SpdmTransportMctpLib.inf b/= SecurityPkg/DeviceSecurity/SpdmLib/SpdmTransportMctpLib.inf new file mode 100644 index 0000000000..a597d35913 --- /dev/null +++ b/SecurityPkg/DeviceSecurity/SpdmLib/SpdmTransportMctpLib.inf @@ -0,0 +1,38 @@ +## @file=0D +# SPDM library.=0D +#=0D +# Copyright (c) 2024, Intel Corporation. All rights reserved.
=0D +#=0D +# SPDX-License-Identifier: BSD-2-Clause-Patent=0D +#=0D +##=0D +=0D +[Defines]=0D + INF_VERSION =3D 0x00010005=0D + BASE_NAME =3D SpdmTransportMctpLib=0D + FILE_GUID =3D C6ED3DB8-852A-40A8-8099-9D87D93669C4= =0D + MODULE_TYPE =3D BASE=0D + VERSION_STRING =3D 1.0=0D + LIBRARY_CLASS =3D SpdmTransportMctpLib=0D +=0D +#=0D +# The following information is for reference only and not required by the = build tools.=0D +#=0D +# VALID_ARCHITECTURES =3D IA32 X64 AARCH64=0D +#=0D +=0D +[Sources]=0D + libspdm/library/spdm_transport_mctp_lib/libspdm_mctp_common.c=0D + libspdm/library/spdm_transport_mctp_lib/libspdm_mctp_mctp.c=0D +=0D +[Packages]=0D + MdePkg/MdePkg.dec=0D + SecurityPkg/SecurityPkg.dec=0D + CryptoPkg/CryptoPkg.dec=0D +=0D +[LibraryClasses]=0D + BaseLib=0D + BaseMemoryLib=0D + DebugLib=0D + SpdmSecuredMessageLib=0D + MemLibWrapper=0D diff --git a/SecurityPkg/DeviceSecurity/SpdmLib/SpdmTransportPciDoeLib.inf = b/SecurityPkg/DeviceSecurity/SpdmLib/SpdmTransportPciDoeLib.inf new file mode 100644 index 0000000000..a0f47d6c7d --- /dev/null +++ b/SecurityPkg/DeviceSecurity/SpdmLib/SpdmTransportPciDoeLib.inf @@ -0,0 +1,38 @@ +## @file=0D +# SPDM library.=0D +#=0D +# Copyright (c) 2024, Intel Corporation. All rights reserved.
=0D +#=0D +# SPDX-License-Identifier: BSD-2-Clause-Patent=0D +#=0D +##=0D +=0D +[Defines]=0D + INF_VERSION =3D 0x00010005=0D + BASE_NAME =3D SpdmTransportPciDoeLib=0D + FILE_GUID =3D 21094151-1A91-4261-8EB7-C94453491FF8= =0D + MODULE_TYPE =3D BASE=0D + VERSION_STRING =3D 1.0=0D + LIBRARY_CLASS =3D SpdmTransportPciDoeLib=0D +=0D +#=0D +# The following information is for reference only and not required by the = build tools.=0D +#=0D +# VALID_ARCHITECTURES =3D IA32 X64 AARCH64=0D +#=0D +=0D +[Sources]=0D + libspdm/library/spdm_transport_pcidoe_lib/libspdm_doe_common.c=0D + libspdm/library/spdm_transport_pcidoe_lib/libspdm_doe_pcidoe.c=0D +=0D +[Packages]=0D + MdePkg/MdePkg.dec=0D + SecurityPkg/SecurityPkg.dec=0D + CryptoPkg/CryptoPkg.dec=0D +=0D +[LibraryClasses]=0D + BaseLib=0D + BaseMemoryLib=0D + DebugLib=0D + SpdmSecuredMessageLib=0D + MemLibWrapper=0D diff --git a/SecurityPkg/DeviceSecurity/SpdmSecurityLib/SpdmAuthentication.= c b/SecurityPkg/DeviceSecurity/SpdmSecurityLib/SpdmAuthentication.c new file mode 100644 index 0000000000..86cf9b225c --- /dev/null +++ b/SecurityPkg/DeviceSecurity/SpdmSecurityLib/SpdmAuthentication.c @@ -0,0 +1,697 @@ +/** @file=0D + EDKII Device Security library for SPDM device.=0D + It follows the SPDM Specification.=0D +=0D +Copyright (c) 2024, Intel Corporation. All rights reserved.
=0D +SPDX-License-Identifier: BSD-2-Clause-Patent=0D +=0D +**/=0D +=0D +#include "SpdmSecurityLibInternal.h"=0D +=0D +/**=0D + Measure and log an EFI variable, and extend the measurement result into = a specific PCR.=0D +=0D + @param[in] PcrIndex PCR Index.=0D + @param[in] EventType Event type.=0D + @param[in] VarName A Null-terminated string that is the name = of the vendor's variable.=0D + @param[in] VendorGuid A unique identifier for the vendor.=0D + @param[in] VarData The content of the variable data.=0D + @param[in] VarSize The size of the variable data.=0D +=0D + @retval EFI_SUCCESS Operation completed successfully.=0D + @retval EFI_OUT_OF_RESOURCES Out of memory.=0D + @retval EFI_DEVICE_ERROR The operation was unsuccessful.=0D +=0D +**/=0D +EFI_STATUS=0D +EFIAPI=0D +MeasureVariable (=0D + IN UINT32 PcrIndex,=0D + IN UINT32 EventType,=0D + IN CHAR16 *VarName,=0D + IN EFI_GUID *VendorGuid,=0D + IN VOID *VarData,=0D + IN UINTN VarSize=0D + )=0D +{=0D + EFI_STATUS Status;=0D + UINTN VarNameLength;=0D + UEFI_VARIABLE_DATA *VarLog;=0D + UINT32 VarLogSize;=0D +=0D + if (!(((VarSize =3D=3D 0) && (VarData =3D=3D NULL)) || ((VarSize !=3D 0)= && (VarData !=3D NULL)))) {=0D + ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);=0D + return EFI_INVALID_PARAMETER;=0D + }=0D +=0D + VarNameLength =3D StrLen (VarName);=0D + VarLogSize =3D (UINT32)(sizeof (*VarLog) + VarNameLength * sizeof (*V= arName) + VarSize=0D + - sizeof (VarLog->UnicodeName) - sizeof (VarLog= ->VariableData));=0D +=0D + VarLog =3D (UEFI_VARIABLE_DATA *)AllocateZeroPool (VarLogSize);=0D + if (VarLog =3D=3D NULL) {=0D + return EFI_OUT_OF_RESOURCES;=0D + }=0D +=0D + CopyMem (&VarLog->VariableName, VendorGuid, sizeof (VarLog->VariableName= ));=0D + VarLog->UnicodeNameLength =3D VarNameLength;=0D + VarLog->VariableDataLength =3D VarSize;=0D + CopyMem (=0D + VarLog->UnicodeName,=0D + VarName,=0D + VarNameLength * sizeof (*VarName)=0D + );=0D + if (VarSize !=3D 0) {=0D + CopyMem (=0D + (CHAR16 *)VarLog->UnicodeName + VarNameLength,=0D + VarData,=0D + VarSize=0D + );=0D + }=0D +=0D + DEBUG ((DEBUG_INFO, "VariableDxe: MeasureVariable (Pcr - %x, EventType -= %x, ", (UINTN)PcrIndex, (UINTN)EventType));=0D + DEBUG ((DEBUG_INFO, "VariableName - %s, VendorGuid - %g)\n", VarName, Ve= ndorGuid));=0D +=0D + Status =3D TpmMeasureAndLogData (=0D + PcrIndex,=0D + EventType,=0D + VarLog,=0D + VarLogSize,=0D + VarLog,=0D + VarLogSize=0D + );=0D + FreePool (VarLog);=0D + return Status;=0D +}=0D +=0D +/**=0D + Extend Certicate and auth state to NV Index and measure trust anchor to = PCR.=0D +=0D + @param[in] SpdmDeviceContext The SPDM context for the device.= =0D + @param[in] AuthState The auth state of this deice.=0D + @param[in] CertChainSize The size of cert chain.=0D + @param[in] CertChain A pointer to a destination buffer= to store the certificate chain.=0D + @param[in] TrustAnchor A buffer to hold the trust_anchor= which is used to validate the peer=0D + certificate, if not NULL.=0D + @param[in] TrustAnchorSize A buffer to hold the trust_anchor= _size, if not NULL..=0D + @param[in] SlotId The number of slot for the certif= icate chain.=0D + @param[out] SecurityState A pointer to the security state o= f the requester.=0D +=0D + @retval EFI_SUCCESS Operation completed successfully.=0D + @retval EFI_OUT_OF_RESOURCES Out of memory.=0D + @retval EFI_DEVICE_ERROR The operation was unsuccessful.=0D +=0D +**/=0D +EFI_STATUS=0D +ExtendCertificate (=0D + IN SPDM_DEVICE_CONTEXT *SpdmDeviceContext,=0D + IN UINT8 AuthState,=0D + IN UINTN CertChainSize,=0D + IN UINT8 *CertChain,=0D + IN VOID *TrustAnchor,=0D + IN UINTN TrustAnchorSize,=0D + IN UINT8 SlotId,=0D + OUT EDKII_DEVICE_SECURITY_STATE *SecurityState=0D + )=0D +{=0D + VOID *EventLog;=0D + UINT32 EventLogSize;= =0D + UINT8 *EventLogPtr;= =0D + TCG_NV_INDEX_INSTANCE_EVENT_LOG_STRUCT *NvIndexInsta= nce;=0D + TCG_DEVICE_SECURITY_EVENT_DATA_HEADER2 *EventData2;= =0D + TCG_DEVICE_SECURITY_EVENT_DATA_SUB_HEADER_SPDM_CERT_CHAIN *TcgSpdmCertC= hain;=0D + VOID *DeviceContex= t;=0D + UINTN DeviceContext= Size;=0D + EFI_STATUS Status;=0D + UINTN DevicePathSiz= e;=0D + UINT32 BaseHashAlgo;= =0D + UINTN DataSize;=0D + VOID *SpdmContext;= =0D + SPDM_DATA_PARAMETER Parameter;=0D + EFI_SIGNATURE_DATA *SignatureDat= a;=0D + UINTN SignatureData= Size;=0D +=0D + SpdmContext =3D SpdmDeviceContext->SpdmContext;=0D +=0D + EventLog =3D NULL;=0D + ZeroMem (&Parameter, sizeof (Parameter));=0D + Parameter.location =3D SpdmDataLocationConnection;=0D + DataSize =3D sizeof (BaseHashAlgo);=0D + Status =3D SpdmGetData (SpdmContext, SpdmDataBaseHashAlgo, &= Parameter, &BaseHashAlgo, &DataSize);=0D + ASSERT_EFI_ERROR (Status);=0D +=0D + DeviceContextSize =3D GetDeviceMeasurementContextSize (SpdmDeviceContext= );=0D + DevicePathSize =3D GetDevicePathSize (SpdmDeviceContext->DevicePath);= =0D +=0D + switch (AuthState) {=0D + case TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_AUTH_STATE_SUCCESS:=0D + case TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_AUTH_STATE_NO_AUTH:=0D + case TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_AUTH_STATE_NO_BINDING:=0D + EventLogSize =3D (UINT32)(sizeof (TCG_NV_INDEX_INSTANCE_EVENT_LOG_ST= RUCT) +=0D + sizeof (TCG_DEVICE_SECURITY_EVENT_DATA_HEADE= R2) +=0D + sizeof (UINT64) + DevicePathSize +=0D + sizeof (TCG_DEVICE_SECURITY_EVENT_DATA_SUB_H= EADER_SPDM_CERT_CHAIN) +=0D + CertChainSize +=0D + DeviceContextSize);=0D + EventLog =3D AllocatePool (EventLogSize);=0D + if (EventLog =3D=3D NULL) {=0D + SecurityState->AuthenticationState =3D EDKII_DEVICE_SECURITY_STATE= _ERROR_UEFI_OUT_OF_RESOURCE;=0D + return EFI_OUT_OF_RESOURCES;=0D + }=0D +=0D + EventLogPtr =3D EventLog;=0D +=0D + NvIndexInstance =3D (VOID *)EventLogPtr;=0D + CopyMem (NvIndexInstance->Signature, TCG_NV_EXTEND_INDEX_FOR_INSTANC= E_SIGNATURE, sizeof (TCG_NV_EXTEND_INDEX_FOR_INSTANCE_SIGNATURE));=0D + NvIndexInstance->Version =3D TCG_NV_INDEX_INSTANCE_EVENT_LOG_STRUCT_= VERSION;=0D + ZeroMem (NvIndexInstance->Reserved, sizeof (NvIndexInstance->Reserve= d));=0D + EventLogPtr +=3D sizeof (TCG_NV_INDEX_INSTANCE_EVENT_LOG_STRUCT);=0D +=0D + EventData2 =3D (VOID *)EventLogPtr;=0D + CopyMem (EventData2->Signature, TCG_DEVICE_SECURITY_EVENT_DATA_SIGNA= TURE_2, sizeof (EventData2->Signature));=0D + EventData2->Version =3D TCG_DEVICE_SECURITY_EVENT_DATA_VERSION_2;= =0D + EventData2->AuthState =3D AuthState;=0D + EventData2->Reserved =3D 0;=0D + EventData2->Length =3D (UINT32)EventLogSize;=0D + EventData2->DeviceType =3D GetSpdmDeviceType (SpdmDeviceContext);=0D +=0D + EventData2->SubHeaderType =3D TCG_DEVICE_SECURITY_EVENT_DATA_DEVIC= E_SUB_HEADER_TYPE_SPDM_CERT_CHAIN;=0D + EventData2->SubHeaderLength =3D (UINT32)(sizeof (TCG_DEVICE_SECURITY= _EVENT_DATA_SUB_HEADER_SPDM_CERT_CHAIN) + CertChainSize);=0D + EventData2->SubHeaderUID =3D SpdmDeviceContext->DeviceUID;=0D +=0D + EventLogPtr =3D (VOID *)(EventData2 + 1);=0D +=0D + *(UINT64 *)EventLogPtr =3D (UINT64)DevicePathSize;=0D + EventLogPtr +=3D sizeof (UINT64);=0D + CopyMem (EventLogPtr, SpdmDeviceContext->DevicePath, DevicePathSize)= ;=0D + EventLogPtr +=3D DevicePathSize;=0D +=0D + TcgSpdmCertChain =3D (VOID *)EventLogPtr;=0D + TcgSpdmCertChain->SpdmVersion =3D SpdmDeviceContext->SpdmVersion;=0D + TcgSpdmCertChain->SpdmSlotId =3D SlotId;=0D + TcgSpdmCertChain->Reserved =3D 0;=0D + TcgSpdmCertChain->SpdmHashAlgo =3D BaseHashAlgo;=0D + EventLogPtr +=3D sizeof (TCG_DEVICE_SECURITY_EVENT= _DATA_SUB_HEADER_SPDM_CERT_CHAIN);=0D +=0D + CopyMem (EventLogPtr, CertChain, CertChainSize);=0D + EventLogPtr +=3D CertChainSize;=0D +=0D + if (DeviceContextSize !=3D 0) {=0D + DeviceContext =3D (VOID *)EventLogPtr;=0D + Status =3D CreateDeviceMeasurementContext (SpdmDeviceContex= t, DeviceContext, DeviceContextSize);=0D + if (Status !=3D EFI_SUCCESS) {=0D + SecurityState->AuthenticationState =3D EDKII_DEVICE_SECURITY_STA= TE_ERROR_DEVICE_ERROR;=0D + Status =3D EFI_DEVICE_ERROR;=0D + goto Exit;=0D + }=0D + }=0D +=0D + Status =3D TpmMeasureAndLogData (=0D + TCG_NV_EXTEND_INDEX_FOR_INSTANCE,=0D + EV_NO_ACTION,=0D + EventLog,=0D + EventLogSize,=0D + EventLog,=0D + EventLogSize=0D + );=0D + if (EFI_ERROR (Status)) {=0D + SecurityState->AuthenticationState =3D EDKII_DEVICE_SECURITY_STATE= _ERROR_TCG_EXTEND_TPM_PCR;=0D + }=0D +=0D + DEBUG ((DEBUG_INFO, "TpmMeasureAndLogData (Instance) - %r\n", Status= ));=0D +=0D + break;=0D + case TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_AUTH_STATE_FAIL_INVALID:=0D + EventLogSize =3D (UINT32)(sizeof (TCG_NV_INDEX_INSTANCE_EVENT_LOG_ST= RUCT) +=0D + sizeof (TCG_DEVICE_SECURITY_EVENT_DATA_HEADE= R2) +=0D + sizeof (UINT64) + DevicePathSize +=0D + sizeof (TCG_DEVICE_SECURITY_EVENT_DATA_SUB_H= EADER_SPDM_CERT_CHAIN) +=0D + DeviceContextSize);=0D + EventLog =3D AllocatePool (EventLogSize);=0D + if (EventLog =3D=3D NULL) {=0D + SecurityState->AuthenticationState =3D EDKII_DEVICE_SECURITY_STATE= _ERROR_UEFI_OUT_OF_RESOURCE;=0D + return EFI_OUT_OF_RESOURCES;=0D + }=0D +=0D + EventLogPtr =3D EventLog;=0D +=0D + NvIndexInstance =3D (VOID *)EventLogPtr;=0D + CopyMem (NvIndexInstance->Signature, TCG_NV_EXTEND_INDEX_FOR_INSTANC= E_SIGNATURE, sizeof (TCG_NV_EXTEND_INDEX_FOR_INSTANCE_SIGNATURE));=0D + NvIndexInstance->Version =3D TCG_NV_INDEX_INSTANCE_EVENT_LOG_STRUCT_= VERSION;=0D + ZeroMem (NvIndexInstance->Reserved, sizeof (NvIndexInstance->Reserve= d));=0D + EventLogPtr +=3D sizeof (TCG_NV_INDEX_INSTANCE_EVENT_LOG_STRUCT);=0D +=0D + EventData2 =3D (VOID *)EventLogPtr;=0D + CopyMem (EventData2->Signature, TCG_DEVICE_SECURITY_EVENT_DATA_SIGNA= TURE_2, sizeof (EventData2->Signature));=0D + EventData2->Version =3D TCG_DEVICE_SECURITY_EVENT_DATA_VERSION_2;= =0D + EventData2->AuthState =3D AuthState;=0D + EventData2->Reserved =3D 0;=0D + EventData2->Length =3D (UINT32)EventLogSize;=0D + EventData2->DeviceType =3D GetSpdmDeviceType (SpdmDeviceContext);=0D +=0D + EventData2->SubHeaderType =3D TCG_DEVICE_SECURITY_EVENT_DATA_DEVIC= E_SUB_HEADER_TYPE_SPDM_CERT_CHAIN;=0D + EventData2->SubHeaderLength =3D sizeof (TCG_DEVICE_SECURITY_EVENT_DA= TA_SUB_HEADER_SPDM_CERT_CHAIN);=0D + EventData2->SubHeaderUID =3D SpdmDeviceContext->DeviceUID;=0D +=0D + EventLogPtr =3D (VOID *)(EventData2 + 1);=0D +=0D + *(UINT64 *)EventLogPtr =3D (UINT64)DevicePathSize;=0D + EventLogPtr +=3D sizeof (UINT64);=0D + CopyMem (EventLogPtr, SpdmDeviceContext->DevicePath, DevicePathSize)= ;=0D + EventLogPtr +=3D DevicePathSize;=0D +=0D + TcgSpdmCertChain =3D (VOID *)EventLogPtr;=0D + TcgSpdmCertChain->SpdmVersion =3D SpdmDeviceContext->SpdmVersion;=0D + TcgSpdmCertChain->SpdmSlotId =3D SlotId;=0D + TcgSpdmCertChain->Reserved =3D 0;=0D + TcgSpdmCertChain->SpdmHashAlgo =3D BaseHashAlgo;=0D + EventLogPtr +=3D sizeof (TCG_DEVICE_SECURITY_EVENT= _DATA_SUB_HEADER_SPDM_CERT_CHAIN);=0D +=0D + if (DeviceContextSize !=3D 0) {=0D + DeviceContext =3D (VOID *)EventLogPtr;=0D + Status =3D CreateDeviceMeasurementContext (SpdmDeviceContex= t, DeviceContext, DeviceContextSize);=0D + if (Status !=3D EFI_SUCCESS) {=0D + SecurityState->AuthenticationState =3D EDKII_DEVICE_SECURITY_STA= TE_ERROR_DEVICE_ERROR;=0D + Status =3D EFI_DEVICE_ERROR;=0D + goto Exit;=0D + }=0D + }=0D +=0D + Status =3D TpmMeasureAndLogData (=0D + TCG_NV_EXTEND_INDEX_FOR_INSTANCE,=0D + EV_NO_ACTION,=0D + EventLog,=0D + EventLogSize,=0D + EventLog,=0D + EventLogSize=0D + );=0D + if (EFI_ERROR (Status)) {=0D + SecurityState->AuthenticationState =3D EDKII_DEVICE_SECURITY_STATE= _ERROR_TCG_EXTEND_TPM_PCR;=0D + }=0D +=0D + DEBUG ((DEBUG_INFO, "TpmMeasureAndLogData (Instance) - %r\n", Status= ));=0D +=0D + goto Exit;=0D + case TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_AUTH_STATE_FAIL_NO_SIG:=0D + case TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_AUTH_STATE_NO_SPDM:=0D + EventLogSize =3D (UINT32)(sizeof (TCG_NV_INDEX_INSTANCE_EVENT_LOG_ST= RUCT) +=0D + sizeof (TCG_DEVICE_SECURITY_EVENT_DATA_HEADE= R2) +=0D + sizeof (UINT64) + DevicePathSize +=0D + DeviceContextSize);=0D + EventLog =3D AllocatePool (EventLogSize);=0D + if (EventLog =3D=3D NULL) {=0D + SecurityState->AuthenticationState =3D EDKII_DEVICE_SECURITY_STATE= _ERROR_UEFI_OUT_OF_RESOURCE;=0D + return EFI_OUT_OF_RESOURCES;=0D + }=0D +=0D + EventLogPtr =3D EventLog;=0D +=0D + NvIndexInstance =3D (VOID *)EventLogPtr;=0D + CopyMem (NvIndexInstance->Signature, TCG_NV_EXTEND_INDEX_FOR_INSTANC= E_SIGNATURE, sizeof (TCG_NV_EXTEND_INDEX_FOR_INSTANCE_SIGNATURE));=0D + NvIndexInstance->Version =3D TCG_NV_INDEX_INSTANCE_EVENT_LOG_STRUCT_= VERSION;=0D + ZeroMem (NvIndexInstance->Reserved, sizeof (NvIndexInstance->Reserve= d));=0D + EventLogPtr +=3D sizeof (TCG_NV_INDEX_INSTANCE_EVENT_LOG_STRUCT);=0D +=0D + EventData2 =3D (VOID *)EventLogPtr;=0D + CopyMem (EventData2->Signature, TCG_DEVICE_SECURITY_EVENT_DATA_SIGNA= TURE_2, sizeof (EventData2->Signature));=0D + EventData2->Version =3D TCG_DEVICE_SECURITY_EVENT_DATA_VERSION_2;= =0D + EventData2->AuthState =3D AuthState;=0D + EventData2->Reserved =3D 0;=0D + EventData2->Length =3D (UINT32)EventLogSize;=0D + EventData2->DeviceType =3D GetSpdmDeviceType (SpdmDeviceContext);=0D +=0D + EventData2->SubHeaderType =3D TCG_DEVICE_SECURITY_EVENT_DATA_DEVIC= E_SUB_HEADER_TYPE_SPDM_CERT_CHAIN;=0D + EventData2->SubHeaderLength =3D 0;=0D + EventData2->SubHeaderUID =3D SpdmDeviceContext->DeviceUID;=0D +=0D + EventLogPtr =3D (VOID *)(EventData2 + 1);=0D +=0D + *(UINT64 *)EventLogPtr =3D (UINT64)DevicePathSize;=0D + EventLogPtr +=3D sizeof (UINT64);=0D + CopyMem (EventLogPtr, SpdmDeviceContext->DevicePath, DevicePathSize)= ;=0D + EventLogPtr +=3D DevicePathSize;=0D +=0D + if (DeviceContextSize !=3D 0) {=0D + DeviceContext =3D (VOID *)EventLogPtr;=0D + Status =3D CreateDeviceMeasurementContext (SpdmDeviceContex= t, DeviceContext, DeviceContextSize);=0D + if (Status !=3D EFI_SUCCESS) {=0D + SecurityState->AuthenticationState =3D EDKII_DEVICE_SECURITY_STA= TE_ERROR_DEVICE_ERROR;=0D + Status =3D EFI_DEVICE_ERROR;=0D + goto Exit;=0D + }=0D + }=0D +=0D + Status =3D TpmMeasureAndLogData (=0D + TCG_NV_EXTEND_INDEX_FOR_INSTANCE,=0D + EV_NO_ACTION,=0D + EventLog,=0D + EventLogSize,=0D + EventLog,=0D + EventLogSize=0D + );=0D + if (EFI_ERROR (Status)) {=0D + SecurityState->AuthenticationState =3D EDKII_DEVICE_SECURITY_STATE= _ERROR_TCG_EXTEND_TPM_PCR;=0D + }=0D +=0D + DEBUG ((DEBUG_INFO, "TpmMeasureAndLogData (Instance) - %r\n", Status= ));=0D +=0D + goto Exit;=0D + default:=0D + SecurityState->AuthenticationState =3D EDKII_DEVICE_SECURITY_STATE_E= RROR_UEFI_UNSUPPORTED;=0D + return EFI_UNSUPPORTED;=0D + }=0D +=0D + if ((TrustAnchor !=3D NULL) && (TrustAnchorSize !=3D 0)) {=0D + SignatureDataSize =3D sizeof (EFI_GUID) + TrustAnchorSize;=0D + SignatureData =3D AllocateZeroPool (SignatureDataSize);=0D + if (SignatureData =3D=3D NULL) {=0D + ASSERT (SignatureData !=3D NULL);=0D + SecurityState->AuthenticationState =3D EDKII_DEVICE_SECURITY_STATE_E= RROR_UEFI_OUT_OF_RESOURCE;=0D + Status =3D EFI_OUT_OF_RESOURCES;=0D + goto Exit;=0D + }=0D +=0D + CopyGuid (&SignatureData->SignatureOwner, &gEfiCallerIdGuid);=0D + CopyMem (=0D + (UINT8 *)SignatureData + sizeof (EFI_GUID),=0D + TrustAnchor,=0D + TrustAnchorSize=0D + );=0D +=0D + MeasureVariable (=0D + PCR_INDEX_FOR_SIGNATURE_DB,=0D + EV_EFI_SPDM_DEVICE_AUTHORITY,=0D + EFI_DEVICE_SECURITY_DATABASE,=0D + &gEfiDeviceSignatureDatabaseGuid,=0D + SignatureData,=0D + SignatureDataSize=0D + );=0D + FreePool (SignatureData);=0D + }=0D +=0D +Exit:=0D + if (EventLog !=3D NULL) {=0D + FreePool (EventLog);=0D + }=0D +=0D + return Status;=0D +}=0D +=0D +/**=0D + Measure and log Auth state and Requester and responder Nonce into NV Ind= ex.=0D +=0D + @param[in] SpdmDeviceContext The SPDM context for the device.=0D + @param[in] AuthState The auth state of this deice.=0D + @param[in] RequesterNonce A buffer to hold the requester nonc= e (32 bytes), if not NULL.=0D + @param[in] ResponderNonce A buffer to hold the responder nonc= e (32 bytes), if not NULL.=0D + @param[out] SecurityState A pointer to the security state of = the requester.=0D +=0D + @retval EFI_SUCCESS Operation completed successfully.=0D + @retval EFI_OUT_OF_RESOURCES Out of memory.=0D + @retval EFI_DEVICE_ERROR The operation was unsuccessful.=0D +=0D +**/=0D +EFI_STATUS=0D +ExtendAuthentication (=0D + IN SPDM_DEVICE_CONTEXT *SpdmDeviceContext,=0D + IN UINT8 AuthState,=0D + IN UINT8 *RequesterNonce,=0D + IN UINT8 *ResponderNonce,=0D + OUT EDKII_DEVICE_SECURITY_STATE *SecurityState=0D + )=0D +{=0D + EFI_STATUS Status;=0D +=0D + {=0D + TCG_NV_INDEX_DYNAMIC_EVENT_LOG_STRUCT_SPDM_CHALLENGE DynamicEven= tLogSpdmChallengeEvent;=0D + TCG_NV_INDEX_DYNAMIC_EVENT_LOG_STRUCT_SPDM_CHALLENGE_AUTH DynamicEven= tLogSpdmChallengeAuthEvent;=0D +=0D + CopyMem (DynamicEventLogSpdmChallengeEvent.Header.Signature, TCG_NV_EX= TEND_INDEX_FOR_DYNAMIC_SIGNATURE, sizeof (TCG_NV_EXTEND_INDEX_FOR_DYNAMIC_S= IGNATURE));=0D + DynamicEventLogSpdmChallengeEvent.Header.Version =3D TCG_NV_INDEX_DYNA= MIC_EVENT_LOG_STRUCT_VERSION;=0D + ZeroMem (DynamicEventLogSpdmChallengeEvent.Header.Reserved, sizeof (Dy= namicEventLogSpdmChallengeEvent.Header.Reserved));=0D + DynamicEventLogSpdmChallengeEvent.Header.Uid =3D SpdmDeviceContex= t->DeviceUID;=0D + DynamicEventLogSpdmChallengeEvent.DescriptionSize =3D sizeof (TCG_SPDM= _CHALLENGE_DESCRIPTION);=0D + CopyMem (DynamicEventLogSpdmChallengeEvent.Description, TCG_SPDM_CHALL= ENGE_DESCRIPTION, sizeof (TCG_SPDM_CHALLENGE_DESCRIPTION));=0D + DynamicEventLogSpdmChallengeEvent.DataSize =3D SPDM_NONCE_SIZE;=0D + CopyMem (DynamicEventLogSpdmChallengeEvent.Data, RequesterNonce, SPDM_= NONCE_SIZE);=0D +=0D + Status =3D TpmMeasureAndLogData (=0D + TCG_NV_EXTEND_INDEX_FOR_DYNAMIC,=0D + EV_NO_ACTION,=0D + &DynamicEventLogSpdmChallengeEvent,=0D + sizeof (DynamicEventLogSpdmChallengeEvent),=0D + &DynamicEventLogSpdmChallengeEvent,=0D + sizeof (DynamicEventLogSpdmChallengeEvent)=0D + );=0D + if (EFI_ERROR (Status)) {=0D + SecurityState->AuthenticationState =3D EDKII_DEVICE_SECURITY_STATE_E= RROR_TCG_EXTEND_TPM_PCR;=0D + }=0D +=0D + DEBUG ((DEBUG_INFO, "TpmMeasureAndLogData (Dynamic) - %r\n", Status));= =0D +=0D + CopyMem (DynamicEventLogSpdmChallengeAuthEvent.Header.Signature, TCG_N= V_EXTEND_INDEX_FOR_DYNAMIC_SIGNATURE, sizeof (TCG_NV_EXTEND_INDEX_FOR_DYNAM= IC_SIGNATURE));=0D + DynamicEventLogSpdmChallengeAuthEvent.Header.Version =3D TCG_NV_INDEX_= DYNAMIC_EVENT_LOG_STRUCT_VERSION;=0D + ZeroMem (DynamicEventLogSpdmChallengeAuthEvent.Header.Reserved, sizeof= (DynamicEventLogSpdmChallengeAuthEvent.Header.Reserved));=0D + DynamicEventLogSpdmChallengeAuthEvent.Header.Uid =3D SpdmDeviceCo= ntext->DeviceUID;=0D + DynamicEventLogSpdmChallengeAuthEvent.DescriptionSize =3D sizeof (TCG_= SPDM_CHALLENGE_AUTH_DESCRIPTION);=0D + CopyMem (DynamicEventLogSpdmChallengeAuthEvent.Description, TCG_SPDM_C= HALLENGE_AUTH_DESCRIPTION, sizeof (TCG_SPDM_CHALLENGE_AUTH_DESCRIPTION));=0D + DynamicEventLogSpdmChallengeAuthEvent.DataSize =3D SPDM_NONCE_SIZE;=0D + CopyMem (DynamicEventLogSpdmChallengeAuthEvent.Data, ResponderNonce, S= PDM_NONCE_SIZE);=0D +=0D + Status =3D TpmMeasureAndLogData (=0D + TCG_NV_EXTEND_INDEX_FOR_DYNAMIC,=0D + EV_NO_ACTION,=0D + &DynamicEventLogSpdmChallengeAuthEvent,=0D + sizeof (DynamicEventLogSpdmChallengeAuthEvent),=0D + &DynamicEventLogSpdmChallengeAuthEvent,=0D + sizeof (DynamicEventLogSpdmChallengeAuthEvent)=0D + );=0D + if (EFI_ERROR (Status)) {=0D + SecurityState->AuthenticationState =3D EDKII_DEVICE_SECURITY_STATE_E= RROR_TCG_EXTEND_TPM_PCR;=0D + }=0D +=0D + DEBUG ((DEBUG_INFO, "TpmMeasureAndLogData (Dynamic) - %r\n", Status));= =0D + }=0D +=0D + return Status;=0D +}=0D +=0D +/**=0D + This function gets SPDM digest and certificates.=0D +=0D + @param[in] SpdmDeviceContext The SPDM context for the device.= =0D + @param[out] AuthState The auth state of the devices.=0D + @param[out] ValidSlotId The number of slot for the certi= ficate chain.=0D + @param[out] SecurityState The security state of the reques= ter.=0D + @param[out] IsValidCertChain The validity of the certificate = chain.=0D + @param[out] RootCertMatch The authority of the certificate= chain.=0D +=0D + @retval EFI_SUCCESS Operation completed successfully.=0D + @retval EFI_OUT_OF_RESOURCES Out of memory.=0D + @retval EFI_DEVICE_ERROR The operation was unsuccessful.=0D +=0D +**/=0D +EFI_STATUS=0D +EFIAPI=0D +DoDeviceCertificate (=0D + IN SPDM_DEVICE_CONTEXT *SpdmDeviceContext,=0D + OUT UINT8 *AuthState,=0D + OUT UINT8 *ValidSlotId,=0D + OUT EDKII_DEVICE_SECURITY_STATE *SecurityState,=0D + OUT BOOLEAN *IsValidCertChain,=0D + OUT BOOLEAN *RootCertMatch=0D + )=0D +{=0D + EFI_STATUS Status;=0D + SPDM_RETURN SpdmReturn;=0D + VOID *SpdmContext;=0D + UINT32 CapabilityFlags;=0D + UINTN DataSize;=0D + SPDM_DATA_PARAMETER Parameter;=0D + UINT8 SlotMask;=0D + UINT8 TotalDigestBuffer[LIBSPDM_MAX_HASH_SIZE * SPDM_MAX_= SLOT_COUNT];=0D + UINTN CertChainSize;=0D + UINT8 CertChain[LIBSPDM_MAX_CERT_CHAIN_SIZE];=0D + VOID *TrustAnchor;=0D + UINTN TrustAnchorSize;=0D + UINT8 SlotId;=0D +=0D + SpdmContext =3D SpdmDeviceContext->SpdmContext;=0D +=0D + ZeroMem (&Parameter, sizeof (Parameter));=0D + Parameter.location =3D SpdmDataLocationConnection;=0D + DataSize =3D sizeof (CapabilityFlags);=0D + SpdmReturn =3D SpdmGetData (SpdmContext, SpdmDataCapabilityFlags= , &Parameter, &CapabilityFlags, &DataSize);=0D + if (LIBSPDM_STATUS_IS_ERROR (SpdmReturn)) {=0D + SecurityState->AuthenticationState =3D EDKII_DEVICE_SECURITY_STATE_ERR= OR_DEVICE_ERROR;=0D + return EFI_DEVICE_ERROR;=0D + }=0D +=0D + *IsValidCertChain =3D FALSE;=0D + *RootCertMatch =3D FALSE;=0D + CertChainSize =3D sizeof (CertChain);=0D + ZeroMem (CertChain, sizeof (CertChain));=0D + TrustAnchor =3D NULL;=0D + TrustAnchorSize =3D 0;=0D +=0D + //=0D + // Init *ValidSlotId to invalid slot_id=0D + //=0D + *ValidSlotId =3D SPDM_MAX_SLOT_COUNT;=0D +=0D + if ((CapabilityFlags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP) = =3D=3D 0) {=0D + *AuthState =3D TCG_DEVICE_SECURITY_EVENT_DATA_= DEVICE_AUTH_STATE_FAIL_NO_SIG;=0D + SecurityState->AuthenticationState =3D EDKII_DEVICE_SECURITY_STATE_ERR= OR_DEVICE_NO_CAPABILITIES;=0D + Status =3D ExtendCertificate (SpdmDeviceCo= ntext, *AuthState, 0, NULL, NULL, 0, 0, SecurityState);=0D + return Status;=0D + } else {=0D + ZeroMem (TotalDigestBuffer, sizeof (TotalDigestBuffer));=0D + SpdmReturn =3D SpdmGetDigest (SpdmContext, NULL, &SlotMask, TotalDiges= tBuffer);=0D + if ((LIBSPDM_STATUS_IS_ERROR (SpdmReturn)) || ((SlotMask & 0x01) =3D= =3D 0)) {=0D + *AuthState =3D TCG_DEVICE_SECURITY_EVENT_DAT= A_DEVICE_AUTH_STATE_FAIL_INVALID;=0D + SecurityState->AuthenticationState =3D EDKII_DEVICE_SECURITY_STATE_E= RROR_CERTIFIACTE_FAILURE;=0D + SlotId =3D 0;=0D + Status =3D ExtendCertificate (SpdmDevice= Context, *AuthState, 0, NULL, NULL, 0, SlotId, SecurityState);=0D + return Status;=0D + }=0D +=0D + for (SlotId =3D 0; SlotId < SPDM_MAX_SLOT_COUNT; SlotId++) {=0D + if (((SlotMask >> SlotId) & 0x01) =3D=3D 0) {=0D + continue;=0D + }=0D +=0D + CertChainSize =3D sizeof (CertChain);=0D + ZeroMem (CertChain, sizeof (CertChain));=0D + SpdmReturn =3D SpdmGetCertificateEx (SpdmContext, NULL, SlotId, &Cer= tChainSize, CertChain, (CONST VOID **)&TrustAnchor, &TrustAnchorSize);=0D + if (LIBSPDM_STATUS_IS_SUCCESS (SpdmReturn)) {=0D + *IsValidCertChain =3D TRUE;=0D + break;=0D + } else if (SpdmReturn =3D=3D LIBSPDM_STATUS_VERIF_FAIL) {=0D + *IsValidCertChain =3D FALSE;=0D + *AuthState =3D TCG_DEVICE_SECURITY_EVENT_D= ATA_DEVICE_AUTH_STATE_FAIL_INVALID;=0D + SecurityState->AuthenticationState =3D EDKII_DEVICE_SECURITY_STATE= _ERROR_CERTIFIACTE_FAILURE;=0D + Status =3D ExtendCertificate (SpdmDevi= ceContext, *AuthState, 0, NULL, NULL, 0, SlotId, SecurityState);=0D + } else if (SpdmReturn =3D=3D LIBSPDM_STATUS_VERIF_NO_AUTHORITY) {=0D + *IsValidCertChain =3D TRUE;=0D + *AuthState =3D TCG_DEVICE_SECURITY_EVENT_D= ATA_DEVICE_AUTH_STATE_NO_AUTH;=0D + SecurityState->AuthenticationState =3D EDKII_DEVICE_SECURITY_STATE= _ERROR_CERTIFIACTE_FAILURE;=0D + *ValidSlotId =3D SlotId;=0D + }=0D + }=0D +=0D + if ((SlotId >=3D SPDM_MAX_SLOT_COUNT) && (*ValidSlotId =3D=3D SPDM_MAX= _SLOT_COUNT)) {=0D + SecurityState->AuthenticationState =3D EDKII_DEVICE_SECURITY_STATE_E= RROR_DEVICE_ERROR;=0D + return EFI_DEVICE_ERROR;=0D + }=0D +=0D + if (TrustAnchor !=3D NULL) {=0D + *RootCertMatch =3D TRUE;=0D + *ValidSlotId =3D SlotId;=0D + } else {=0D + *ValidSlotId =3D 0;=0D + }=0D +=0D + DEBUG ((DEBUG_INFO, "SpdmGetCertificateEx - SpdmReturn %p, TrustAnchor= Size 0x%x, RootCertMatch %d\n", SpdmReturn, TrustAnchorSize, *RootCertMatch= ));=0D +=0D + return EFI_SUCCESS;=0D + }=0D +}=0D +=0D +/**=0D + This function does authentication.=0D +=0D + @param[in] SpdmDeviceContext The SPDM context for the device.= =0D + @param[out] AuthState The auth state of the devices.=0D + @param[in] ValidSlotId The number of slot for the certi= ficate chain.=0D + @param[in] IsValidCertChain Indicate the validity of CertCha= in=0D + @param[in] RootCertMatch Indicate the match or mismatch f= or Rootcert=0D + @param[out] SecurityState The security state of the reques= ter.=0D +=0D + @retval EFI_SUCCESS Operation completed successfully.=0D + @retval EFI_OUT_OF_RESOURCES Out of memory.=0D + @retval EFI_DEVICE_ERROR The operation was unsuccessful.=0D +=0D +**/=0D +EFI_STATUS=0D +EFIAPI=0D +DoDeviceAuthentication (=0D + IN SPDM_DEVICE_CONTEXT *SpdmDeviceContext,=0D + OUT UINT8 *AuthState,=0D + IN UINT8 ValidSlotId,=0D + IN BOOLEAN IsValidCertChain,=0D + IN BOOLEAN RootCertMatch,=0D + OUT EDKII_DEVICE_SECURITY_STATE *SecurityState=0D + )=0D +{=0D + EFI_STATUS Status;=0D + SPDM_RETURN SpdmReturn;=0D + VOID *SpdmContext;=0D + UINT32 CapabilityFlags;=0D + UINTN DataSize;=0D + SPDM_DATA_PARAMETER Parameter;=0D + UINTN CertChainSize;=0D + UINT8 CertChain[LIBSPDM_MAX_CERT_CHAIN_SIZE];=0D + UINT8 RequesterNonce[SPDM_NONCE_SIZE];=0D + UINT8 ResponderNonce[SPDM_NONCE_SIZE];=0D + VOID *TrustAnchor;=0D + UINTN TrustAnchorSize;=0D + BOOLEAN IsValidChallengeAuthSig;=0D +=0D + SpdmContext =3D SpdmDeviceContext->SpdmContext;=0D +=0D + ZeroMem (&Parameter, sizeof (Parameter));=0D + Parameter.location =3D SpdmDataLocationConnection;=0D + DataSize =3D sizeof (CapabilityFlags);=0D + SpdmReturn =3D SpdmGetData (SpdmContext, SpdmDataCapabilityFlags= , &Parameter, &CapabilityFlags, &DataSize);=0D + if (LIBSPDM_STATUS_IS_ERROR (SpdmReturn)) {=0D + SecurityState->AuthenticationState =3D EDKII_DEVICE_SECURITY_STATE_ERR= OR_DEVICE_ERROR;=0D + return EFI_DEVICE_ERROR;=0D + }=0D +=0D + IsValidChallengeAuthSig =3D FALSE;=0D +=0D + // get the valid CertChain=0D + CertChainSize =3D sizeof (CertChain);=0D + ZeroMem (CertChain, sizeof (CertChain));=0D + SpdmReturn =3D SpdmGetCertificateEx (SpdmContext, NULL, ValidSlotId, &Ce= rtChainSize, CertChain, (CONST VOID **)&TrustAnchor, &TrustAnchorSize);=0D + if ((!LIBSPDM_STATUS_IS_SUCCESS (SpdmReturn)) && (!(SpdmReturn =3D=3D LI= BSPDM_STATUS_VERIF_NO_AUTHORITY))) {=0D + return EFI_DEVICE_ERROR;=0D + }=0D +=0D + if ((CapabilityFlags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CHAL_CAP) = =3D=3D 0) {=0D + *AuthState =3D TCG_DEVICE_SECURITY_EVENT_DATA_= DEVICE_AUTH_STATE_NO_BINDING;=0D + SecurityState->AuthenticationState =3D EDKII_DEVICE_SECURITY_STATE_ERR= OR_DEVICE_NO_CAPABILITIES;=0D + Status =3D ExtendCertificate (SpdmDeviceCo= ntext, *AuthState, CertChainSize, CertChain, NULL, 0, ValidSlotId, Security= State);=0D + return Status;=0D + } else {=0D + ZeroMem (RequesterNonce, sizeof (RequesterNonce));=0D + ZeroMem (ResponderNonce, sizeof (ResponderNonce));=0D + SpdmReturn =3D SpdmChallengeEx (SpdmContext, NULL, ValidSlotId, SPDM_C= HALLENGE_REQUEST_NO_MEASUREMENT_SUMMARY_HASH, NULL, NULL, NULL, RequesterNo= nce, ResponderNonce, NULL, 0);=0D + if (SpdmReturn =3D=3D LIBSPDM_STATUS_SUCCESS) {=0D + IsValidChallengeAuthSig =3D TRUE;=0D + } else if ((LIBSPDM_STATUS_IS_ERROR (SpdmReturn))) {=0D + IsValidChallengeAuthSig =3D FALSE;=0D + *AuthState =3D TCG_DEVICE_SECURITY_EVENT_DAT= A_DEVICE_AUTH_STATE_FAIL_INVALID;=0D + SecurityState->AuthenticationState =3D EDKII_DEVICE_SECURITY_STATE_E= RROR_CHALLENGE_FAILURE;=0D + Status =3D ExtendCertificate (SpdmDevice= Context, *AuthState, 0, NULL, NULL, 0, ValidSlotId, SecurityState);=0D + return Status;=0D + } else {=0D + return EFI_DEVICE_ERROR;=0D + }=0D +=0D + if (IsValidCertChain && IsValidChallengeAuthSig && !RootCertMatch) {=0D + *AuthState =3D TCG_DEVICE_SECURITY_EVENT_DAT= A_DEVICE_AUTH_STATE_NO_AUTH;=0D + SecurityState->AuthenticationState =3D EDKII_DEVICE_SECURITY_STATE_E= RROR_NO_CERT_PROVISION;=0D + Status =3D ExtendCertificate (SpdmDevice= Context, *AuthState, CertChainSize, CertChain, NULL, 0, ValidSlotId, Securi= tyState);=0D + } else if (IsValidCertChain && IsValidChallengeAuthSig && RootCertMatc= h) {=0D + *AuthState =3D TCG_DEVICE_SECURITY_EVENT_DAT= A_DEVICE_AUTH_STATE_SUCCESS;=0D + SecurityState->AuthenticationState =3D EDKII_DEVICE_SECURITY_STATE_S= UCCESS;=0D + Status =3D ExtendCertificate (SpdmDevice= Context, *AuthState, CertChainSize, CertChain, TrustAnchor, TrustAnchorSize= , ValidSlotId, SecurityState);=0D + }=0D +=0D + Status =3D ExtendAuthentication (SpdmDeviceContext, *AuthState, Reques= terNonce, ResponderNonce, SecurityState);=0D + }=0D +=0D + return Status;=0D +}=0D diff --git a/SecurityPkg/DeviceSecurity/SpdmSecurityLib/SpdmConnectionInit.= c b/SecurityPkg/DeviceSecurity/SpdmSecurityLib/SpdmConnectionInit.c new file mode 100644 index 0000000000..d61aa01698 --- /dev/null +++ b/SecurityPkg/DeviceSecurity/SpdmSecurityLib/SpdmConnectionInit.c @@ -0,0 +1,481 @@ +/** @file=0D + EDKII Device Security library for SPDM device.=0D + It follows the SPDM Specification.=0D +=0D +Copyright (c) 2024, Intel Corporation. All rights reserved.
=0D +SPDX-License-Identifier: BSD-2-Clause-Patent=0D +=0D +**/=0D +=0D +#include "SpdmSecurityLibInternal.h"=0D +=0D +LIST_ENTRY mSpdmDeviceContextList =3D INITIALIZE_LIST_HEAD_VARIABLE (mSpd= mDeviceContextList);=0D +=0D +#define CONNECTUIN_FAILURE_GET_SPDM_UID_FAILED "Fail to get Spdm Uid"= =0D +#define CONNECTUIN_FAILURE_STGNATURE_DB_FUL_STRING "The Signature databas= e devdb is full"=0D +=0D +/**=0D + record Spdm Io protocol into the context list.=0D +=0D + @param[in] SpdmDeviceContext The SPDM context of the device.=0D +=0D +**/=0D +VOID=0D +RecordSpdmDeviceContextInList (=0D + IN SPDM_DEVICE_CONTEXT *SpdmDeviceContext=0D + )=0D +{=0D + SPDM_DEVICE_CONTEXT_INSTANCE *NewSpdmDeviceContext;=0D + LIST_ENTRY *SpdmDeviceContextList;=0D +=0D + SpdmDeviceContextList =3D &mSpdmDeviceContextList;=0D +=0D + NewSpdmDeviceContext =3D AllocateZeroPool (sizeof (*NewSpdmDeviceContext= ));=0D + if (NewSpdmDeviceContext =3D=3D NULL) {=0D + ASSERT (NewSpdmDeviceContext !=3D NULL);=0D + return;=0D + }=0D +=0D + NewSpdmDeviceContext->Signature =3D SPDM_DEVICE_CONTEXT_INSTANCE= _SIGNATURE;=0D + NewSpdmDeviceContext->SpdmDeviceContext =3D SpdmDeviceContext;=0D +=0D + InsertTailList (SpdmDeviceContextList, &NewSpdmDeviceContext->Link);=0D +}=0D +=0D +/**=0D + get Spdm Io protocol from Context list via spdm context.=0D +=0D + @param[in] SpdmContext The SPDM context of the requester.=0D +=0D + return a pointer to the Spdm Io protocol.=0D +=0D +**/=0D +VOID *=0D +EFIAPI=0D +GetSpdmIoProtocolViaSpdmContext (=0D + IN VOID *SpdmContext=0D + )=0D +{=0D + LIST_ENTRY *Link;=0D + SPDM_DEVICE_CONTEXT_INSTANCE *CurrentSpdmDeviceContext;=0D + LIST_ENTRY *SpdmDeviceContextList;=0D +=0D + SpdmDeviceContextList =3D &mSpdmDeviceContextList;=0D +=0D + Link =3D GetFirstNode (SpdmDeviceContextList);=0D + while (!IsNull (SpdmDeviceContextList, Link)) {=0D + CurrentSpdmDeviceContext =3D SPDM_DEVICE_CONTEXT_INSTANCE_FROM_LINK (L= ink);=0D +=0D + if (CurrentSpdmDeviceContext->SpdmDeviceContext->SpdmContext =3D=3D Sp= dmContext) {=0D + return CurrentSpdmDeviceContext->SpdmDeviceContext->SpdmIoProtocol;= =0D + }=0D +=0D + Link =3D GetNextNode (SpdmDeviceContextList, Link);=0D + }=0D +=0D + return NULL;=0D +}=0D +=0D +/**=0D + creates and returns Spdm Uid from the volatile variable.=0D +=0D + @param[in] SpdmUid A pointer to Spdm Uid.=0D +=0D + @retval EFI_SUCCESS Operation completed successfully.=0D + @retval EFI_OUT_OF_RESOURCES Out of memory.=0D + @retval EFI_DEVICE_ERROR The operation was unsuccessful.=0D +=0D +**/=0D +EFI_STATUS=0D +GetSpdmUid (=0D + UINT64 *SpdmUid=0D + )=0D +{=0D + EFI_STATUS Status;=0D + UINTN VarSize;=0D + UINT64 Uid;=0D +=0D + VarSize =3D sizeof (*SpdmUid);=0D + Status =3D gRT->GetVariable (=0D + L"SpdmUid",=0D + &gEfiDeviceSecuritySpdmUidGuid,=0D + NULL,=0D + &VarSize,=0D + &Uid=0D + );=0D + if (Status =3D=3D EFI_NOT_FOUND) {=0D + Uid =3D 0;=0D + } else if (EFI_ERROR (Status)) {=0D + return Status;=0D + }=0D +=0D + *SpdmUid =3D Uid++;=0D + Status =3D gRT->SetVariable (=0D + L"SpdmUid",=0D + &gEfiDeviceSecuritySpdmUidGuid,=0D + EFI_VARIABLE_BOOTSERVICE_ACCESS,=0D + sizeof (Uid),=0D + &Uid=0D + );=0D +=0D + return Status;=0D +}=0D +=0D +/**=0D + Record and log the connection failure string to PCR1.=0D +=0D + @param[in] FailureString The failure string.=0D + @param[in] StringLen The length of the string.=0D +=0D + @retval EFI_SUCCESS Operation completed successfully.=0D + @retval EFI_OUT_OF_RESOURCES Out of memory.=0D + @retval EFI_DEVICE_ERROR The operation was unsuccessful.=0D +=0D +**/=0D +EFI_STATUS=0D +RecordConnectionFailureStatus (=0D + IN CHAR8 *FailureString,=0D + IN UINT32 StringLen=0D + )=0D +{=0D + EFI_STATUS Status;=0D +=0D + Status =3D TpmMeasureAndLogData (=0D + 1,=0D + EV_PLATFORM_CONFIG_FLAGS,=0D + FailureString,=0D + StringLen,=0D + FailureString,=0D + StringLen=0D + );=0D + DEBUG ((DEBUG_INFO, "RecordConnectionFailureStatus %r\n", Status));=0D + return Status;=0D +}=0D +=0D +/**=0D + This function creates the spdm device context and init connection to the= =0D + responder with the device info.=0D +=0D + @param[in] SpdmDeviceInfo A pointer to device info.=0D + @param[out] SecurityState A pointer to the security state of the= requester.=0D +=0D + @return the spdm device conext after the init connection succeeds.=0D +=0D +**/=0D +SPDM_DEVICE_CONTEXT *=0D +EFIAPI=0D +CreateSpdmDeviceContext (=0D + IN EDKII_SPDM_DEVICE_INFO *SpdmDeviceInfo,=0D + OUT EDKII_DEVICE_SECURITY_STATE *SecurityState=0D + )=0D +{=0D + SPDM_DEVICE_CONTEXT *SpdmDeviceContext;=0D + VOID *SpdmContext;=0D + UINTN SpdmContextSize;=0D + VOID *ScratchBuffer;=0D + UINTN ScratchBufferSize;=0D + EFI_STATUS Status;=0D + SPDM_RETURN SpdmReturn;=0D + EFI_SIGNATURE_LIST *DbList;=0D + EFI_SIGNATURE_DATA *Cert;=0D + UINTN CertCount;=0D + UINTN Index;=0D + UINTN SiglistHeaderSize;=0D + UINTN DbSize;=0D + VOID *Data;=0D + UINTN DataSize;=0D + SPDM_DATA_PARAMETER Parameter;=0D + UINT8 Data8;=0D + UINT16 Data16;=0D + UINT32 Data32;=0D + UINT8 AuthState;=0D +=0D + SpdmDeviceContext =3D AllocateZeroPool (sizeof (*SpdmDeviceContext));=0D + if (SpdmDeviceContext =3D=3D NULL) {=0D + ASSERT (SpdmDeviceContext !=3D NULL);=0D + return NULL;=0D + }=0D +=0D + SpdmDeviceContext->Signature =3D SPDM_DEVICE_CONTEXT_SIGNATURE;=0D + CopyMem (&SpdmDeviceContext->DeviceId, SpdmDeviceInfo->DeviceId, sizeof = (EDKII_DEVICE_IDENTIFIER));=0D + SpdmDeviceContext->IsEmbeddedDevice =3D SpdmDeviceInfo->IsEmbeddedDevice= ;=0D +=0D + SpdmContextSize =3D SpdmGetContextSize ();=0D + SpdmContext =3D AllocateZeroPool (SpdmContextSize);=0D + if (SpdmContext =3D=3D NULL) {=0D + ASSERT (SpdmContext !=3D NULL);=0D + goto Error;=0D + }=0D +=0D + SpdmReturn =3D SpdmInitContext (SpdmContext);=0D + if (LIBSPDM_STATUS_IS_ERROR (SpdmReturn)) {=0D + goto Error;=0D + }=0D +=0D + SpdmRegisterDeviceIoFunc (=0D + SpdmContext,=0D + SpdmDeviceInfo->SendMessage,=0D + SpdmDeviceInfo->ReceiveMessage=0D + );=0D + SpdmRegisterTransportLayerFunc (=0D + SpdmContext,=0D + SpdmDeviceInfo->MaxSpdmMsgSize,=0D + SpdmDeviceInfo->TransportHeaderSize,=0D + SpdmDeviceInfo->TransportTailSize,=0D + SpdmDeviceInfo->TransportEncodeMessage,=0D + SpdmDeviceInfo->TransportDecodeMessage=0D + );=0D +=0D + SpdmRegisterDeviceBufferFunc (=0D + SpdmContext,=0D + SpdmDeviceInfo->SenderBufferSize,=0D + SpdmDeviceInfo->ReceiverBufferSize,=0D + SpdmDeviceInfo->AcquireSenderBuffer,=0D + SpdmDeviceInfo->ReleaseSenderBuffer,=0D + SpdmDeviceInfo->AcquireReceiverBuffer,=0D + SpdmDeviceInfo->ReleaseReceiverBuffer=0D + );=0D +=0D + ScratchBufferSize =3D SpdmGetSizeofRequiredScratchBuffer (SpdmContext);= =0D + ScratchBuffer =3D AllocateZeroPool (ScratchBufferSize);=0D + if (ScratchBuffer =3D=3D NULL) {=0D + ASSERT (ScratchBuffer !=3D NULL);=0D + goto Error;=0D + }=0D +=0D + SpdmSetScratchBuffer (SpdmContext, ScratchBuffer, ScratchBufferSize);=0D +=0D + SpdmDeviceContext->SpdmContextSize =3D SpdmContextSize;=0D + SpdmDeviceContext->SpdmContext =3D SpdmContext;=0D + SpdmDeviceContext->ScratchBufferSize =3D ScratchBufferSize;=0D + SpdmDeviceContext->ScratchBuffer =3D ScratchBuffer;=0D +=0D + Status =3D gBS->HandleProtocol (=0D + SpdmDeviceContext->DeviceId.DeviceHandle,=0D + &gEfiDevicePathProtocolGuid,=0D + (VOID **)&SpdmDeviceContext->DevicePath=0D + );=0D + if (EFI_ERROR (Status)) {=0D + DEBUG ((DEBUG_ERROR, "Locate - DevicePath - %r\n", Status));=0D + goto Error;=0D + }=0D +=0D + Status =3D gBS->HandleProtocol (=0D + SpdmDeviceContext->DeviceId.DeviceHandle,=0D + &SpdmDeviceContext->DeviceId.DeviceType,=0D + (VOID **)&SpdmDeviceContext->DeviceIo=0D + );=0D + if (EFI_ERROR (Status)) {=0D + DEBUG ((DEBUG_ERROR, "Locate - DeviceIo - %r\n", Status));=0D + // This is optional, only check known device type later.=0D + }=0D +=0D + if (SpdmDeviceInfo->SpdmIoProtocolGuid !=3D NULL) {=0D + Status =3D gBS->HandleProtocol (=0D + SpdmDeviceContext->DeviceId.DeviceHandle,=0D + SpdmDeviceInfo->SpdmIoProtocolGuid,=0D + (VOID **)&SpdmDeviceContext->SpdmIoProtocol=0D + );=0D + if (EFI_ERROR (Status)) {=0D + DEBUG ((DEBUG_ERROR, "Locate - SpdmIoProtocol - %r\n", Status));=0D + goto Error;=0D + }=0D + }=0D +=0D + if (CompareGuid (&SpdmDeviceContext->DeviceId.DeviceType, &gEdkiiDeviceI= dentifierTypePciGuid)) {=0D + if (SpdmDeviceContext->DeviceIo =3D=3D NULL) {=0D + DEBUG ((DEBUG_ERROR, "Locate - PciIo - %r\n", Status));=0D + goto Error;=0D + }=0D + }=0D +=0D + Status =3D GetSpdmUid (&SpdmDeviceContext->DeviceUID);=0D + if (EFI_ERROR (Status)) {=0D + Status =3D RecordConnectionFailureStatus (=0D + CONNECTUIN_FAILURE_GET_SPDM_UID_FAILED,=0D + sizeof (CONNECTUIN_FAILURE_GET_SPDM_UID_FAILED)=0D + );=0D + if (EFI_ERROR (Status)) {=0D + goto Error;=0D + }=0D +=0D + ASSERT (FALSE);=0D + DEBUG ((DEBUG_ERROR, "Fail to get UID - %r\n", Status));=0D + goto Error;=0D + }=0D +=0D + RecordSpdmDeviceContextInList (SpdmDeviceContext);=0D +=0D + Status =3D GetVariable2 (=0D + EFI_DEVICE_SECURITY_DATABASE,=0D + &gEfiDeviceSignatureDatabaseGuid,=0D + (VOID **)&SpdmDeviceContext->SignatureList,=0D + &SpdmDeviceContext->SignatureListSize=0D + );=0D + if ((!EFI_ERROR (Status)) && (SpdmDeviceContext->SignatureList !=3D NULL= )) {=0D + DbList =3D SpdmDeviceContext->SignatureList;=0D + DbSize =3D SpdmDeviceContext->SignatureListSize;=0D + while ((DbSize > 0) && (SpdmDeviceContext->SignatureListSize >=3D DbLi= st->SignatureListSize)) {=0D + if (DbList->SignatureListSize =3D=3D 0) {=0D + break;=0D + }=0D +=0D + if ( (!CompareGuid (&DbList->SignatureType, &gEfiCertX509Guid))=0D + || (DbList->SignatureHeaderSize !=3D 0)=0D + || (DbList->SignatureSize < sizeof (EFI_SIGNATURE_DATA)))=0D + {=0D + DbSize -=3D DbList->SignatureListSize;=0D + DbList =3D (EFI_SIGNATURE_LIST *)((UINT8 *)DbList + DbList->Signa= tureListSize);=0D + continue;=0D + }=0D +=0D + SiglistHeaderSize =3D sizeof (EFI_SIGNATURE_LIST) + DbList->Signatur= eHeaderSize;=0D + Cert =3D (EFI_SIGNATURE_DATA *)((UINT8 *)DbList + Sigli= stHeaderSize);=0D + CertCount =3D (DbList->SignatureListSize - SiglistHeaderSize= ) / DbList->SignatureSize;=0D +=0D + for (Index =3D 0; Index < CertCount; Index++) {=0D + Data =3D Cert->SignatureData;=0D + DataSize =3D DbList->SignatureSize - sizeof (EFI_GUID);=0D +=0D + ZeroMem (&Parameter, sizeof (Parameter));=0D + Parameter.location =3D SpdmDataLocationLocal;=0D + SpdmReturn =3D SpdmSetData (SpdmContext, SpdmDataPeerPubli= cRootCert, &Parameter, Data, DataSize);=0D + if (LIBSPDM_STATUS_IS_ERROR (SpdmReturn)) {=0D + if (SpdmReturn =3D=3D LIBSPDM_STATUS_BUFFER_FULL) {=0D + Status =3D RecordConnectionFailureStatus (=0D + CONNECTUIN_FAILURE_STGNATURE_DB_FUL_STRING,=0D + sizeof (CONNECTUIN_FAILURE_STGNATURE_DB_FUL_STRING)= =0D + );=0D + if (EFI_ERROR (Status)) {=0D + goto Error;=0D + }=0D +=0D + ASSERT (FALSE);=0D + }=0D +=0D + goto Error;=0D + }=0D +=0D + Cert =3D (EFI_SIGNATURE_DATA *)((UINT8 *)Cert + DbList->SignatureS= ize);=0D + }=0D +=0D + DbSize -=3D DbList->SignatureListSize;=0D + DbList =3D (EFI_SIGNATURE_LIST *)((UINT8 *)DbList + DbList->Signatu= reListSize);=0D + }=0D + }=0D +=0D + Data8 =3D 0;=0D + ZeroMem (&Parameter, sizeof (Parameter));=0D + Parameter.location =3D SpdmDataLocationLocal;=0D + SpdmReturn =3D SpdmSetData (SpdmContext, SpdmDataCapabilityCTExp= onent, &Parameter, &Data8, sizeof (Data8));=0D + if (LIBSPDM_STATUS_IS_ERROR (SpdmReturn)) {=0D + ASSERT (FALSE);=0D + goto Error;=0D + }=0D +=0D + Data32 =3D 0;=0D + SpdmReturn =3D SpdmSetData (SpdmContext, SpdmDataCapabilityFlags, &Param= eter, &Data32, sizeof (Data32));=0D + if (LIBSPDM_STATUS_IS_ERROR (SpdmReturn)) {=0D + ASSERT (FALSE);=0D + goto Error;=0D + }=0D +=0D + Data8 =3D SPDM_MEASUREMENT_SPECIFICATION_DMTF;=0D + SpdmReturn =3D SpdmSetData (SpdmContext, SpdmDataMeasurementSpec, &Param= eter, &Data8, sizeof (Data8));=0D + if (LIBSPDM_STATUS_IS_ERROR (SpdmReturn)) {=0D + ASSERT (FALSE);=0D + goto Error;=0D + }=0D +=0D + if (SpdmDeviceInfo->BaseAsymAlgo !=3D 0) {=0D + Data32 =3D SpdmDeviceInfo->BaseAsymAlgo;=0D + } else {=0D + Data32 =3D SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_2048 |=0D + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_3072 |=0D + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_4096 |=0D + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P256 |= =0D + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P384 |= =0D + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P521;=0D + }=0D +=0D + SpdmReturn =3D SpdmSetData (SpdmContext, SpdmDataBaseAsymAlgo, &Paramete= r, &Data32, sizeof (Data32));=0D + if (LIBSPDM_STATUS_IS_ERROR (SpdmReturn)) {=0D + ASSERT (FALSE);=0D + goto Error;=0D + }=0D +=0D + if (SpdmDeviceInfo->BaseHashAlgo !=3D 0) {=0D + Data32 =3D SpdmDeviceInfo->BaseHashAlgo;=0D + } else {=0D + Data32 =3D SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA_256 |=0D + SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA_384 |=0D + SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA_512;=0D + }=0D +=0D + SpdmReturn =3D SpdmSetData (SpdmContext, SpdmDataBaseHashAlgo, &Paramete= r, &Data32, sizeof (Data32));=0D + if (LIBSPDM_STATUS_IS_ERROR (SpdmReturn)) {=0D + ASSERT (FALSE);=0D + goto Error;=0D + }=0D +=0D + SpdmReturn =3D SpdmInitConnection (SpdmContext, FALSE);=0D + if (LIBSPDM_STATUS_IS_ERROR (SpdmReturn)) {=0D + DEBUG ((DEBUG_ERROR, "SpdmInitConnection - %p\n", SpdmReturn));=0D +=0D + AuthState =3D TCG_DEVICE_SECURITY_EVENT_DATA_= DEVICE_AUTH_STATE_NO_SPDM;=0D + SecurityState->AuthenticationState =3D EDKII_DEVICE_SECURITY_STATE_ERR= OR_DEVICE_NO_CAPABILITIES;=0D + Status =3D ExtendCertificate (SpdmDeviceCo= ntext, AuthState, 0, NULL, NULL, 0, 0, SecurityState);=0D + if (Status !=3D EFI_SUCCESS) {=0D + DEBUG ((DEBUG_ERROR, "ExtendCertificate AUTH_STATE_NO_SPDM failed\n= "));=0D + }=0D +=0D + goto Error;=0D + }=0D +=0D + ZeroMem (&Parameter, sizeof (Parameter));=0D + Parameter.location =3D SpdmDataLocationConnection;=0D + DataSize =3D sizeof (Data16);=0D + SpdmReturn =3D SpdmGetData (SpdmContext, SpdmDataSpdmVersion, &P= arameter, &Data16, &DataSize);=0D + if (LIBSPDM_STATUS_IS_ERROR (SpdmReturn)) {=0D + DEBUG ((DEBUG_ERROR, "SpdmGetData - %p\n", SpdmReturn));=0D + goto Error;=0D + }=0D +=0D + SpdmDeviceContext->SpdmVersion =3D (Data16 >> SPDM_VERSION_NUMBER_SHIFT_= BIT);=0D +=0D + return SpdmDeviceContext;=0D +Error:=0D + DestroySpdmDeviceContext (SpdmDeviceContext);=0D + return NULL;=0D +}=0D +=0D +/**=0D + This function destories the spdm device context.=0D +=0D + @param[in] SpdmDeviceContext A pointer to device info.=0D +=0D +**/=0D +VOID=0D +EFIAPI=0D +DestroySpdmDeviceContext (=0D + IN SPDM_DEVICE_CONTEXT *SpdmDeviceContext=0D + )=0D +{=0D + // need zero memory in case of secret in memory.=0D + if (SpdmDeviceContext->SpdmContext !=3D NULL) {=0D + ZeroMem (SpdmDeviceContext->SpdmContext, SpdmDeviceContext->SpdmContex= tSize);=0D + FreePool (SpdmDeviceContext->SpdmContext);=0D + }=0D +=0D + if (SpdmDeviceContext->ScratchBuffer !=3D NULL) {=0D + ZeroMem (SpdmDeviceContext->ScratchBuffer, SpdmDeviceContext->ScratchB= ufferSize);=0D + FreePool (SpdmDeviceContext->ScratchBuffer);=0D + }=0D +=0D + if (SpdmDeviceContext->SignatureList !=3D NULL) {=0D + ZeroMem (SpdmDeviceContext->SignatureList, SpdmDeviceContext->Signatur= eListSize);=0D + FreePool (SpdmDeviceContext->SignatureList);=0D + }=0D +=0D + FreePool (SpdmDeviceContext);=0D +}=0D diff --git a/SecurityPkg/DeviceSecurity/SpdmSecurityLib/SpdmMeasurement.c b= /SecurityPkg/DeviceSecurity/SpdmSecurityLib/SpdmMeasurement.c new file mode 100644 index 0000000000..f94ec1e7bf --- /dev/null +++ b/SecurityPkg/DeviceSecurity/SpdmSecurityLib/SpdmMeasurement.c @@ -0,0 +1,714 @@ +/** @file=0D + EDKII Device Security library for SPDM device.=0D + It follows the SPDM Specification.=0D +=0D +Copyright (c) 2024, Intel Corporation. All rights reserved.
=0D +SPDX-License-Identifier: BSD-2-Clause-Patent=0D +=0D +**/=0D +=0D +#include "SpdmSecurityLibInternal.h"=0D +=0D +/**=0D + This function returns the SPDM device type for TCG SPDM event.=0D +=0D + @param[in] SpdmDeviceContext The SPDM context for the device.= =0D +=0D + @return TCG SPDM device type=0D +**/=0D +UINT32=0D +EFIAPI=0D +GetSpdmDeviceType (=0D + IN SPDM_DEVICE_CONTEXT *SpdmDeviceContext=0D + )=0D +{=0D + if (CompareGuid (&SpdmDeviceContext->DeviceId.DeviceType, &gEdkiiDeviceI= dentifierTypePciGuid)) {=0D + return TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_TYPE_PCI;=0D + }=0D +=0D + if (CompareGuid (&SpdmDeviceContext->DeviceId.DeviceType, &gEdkiiDeviceI= dentifierTypeUsbGuid)) {=0D + return TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_TYPE_USB;=0D + }=0D +=0D + return TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_TYPE_NULL;=0D +}=0D +=0D +/**=0D + This function returns the SPDM device measurement context size for TCG S= PDM event.=0D +=0D + @param[in] SpdmDeviceContext The SPDM context for the device.= =0D +=0D + @return TCG SPDM device measurement context size=0D +**/=0D +UINTN=0D +EFIAPI=0D +GetDeviceMeasurementContextSize (=0D + IN SPDM_DEVICE_CONTEXT *SpdmDeviceContext=0D + )=0D +{=0D + if (CompareGuid (&SpdmDeviceContext->DeviceId.DeviceType, &gEdkiiDeviceI= dentifierTypePciGuid)) {=0D + return sizeof (TCG_DEVICE_SECURITY_EVENT_DATA_PCI_CONTEXT);=0D + }=0D +=0D + if (CompareGuid (&SpdmDeviceContext->DeviceId.DeviceType, &gEdkiiDeviceI= dentifierTypeUsbGuid)) {=0D + // TBD - usb context=0D + return 0;=0D + }=0D +=0D + return 0;=0D +}=0D +=0D +/**=0D + This function creates the SPDM PCI device measurement context for TCG SP= DM event.=0D +=0D + @param[in] SpdmDeviceContext The SPDM context for the device= .=0D + @param[in, out] DeviceContext The TCG SPDM PCI device measure= ment context.=0D + @param[in] DeviceContextSize The size of TCG SPDM PCI device= measurement context.=0D +=0D + @retval EFI_SUCCESS The TCG SPDM PCI device measurement context is = returned.=0D +**/=0D +EFI_STATUS=0D +CreatePciDeviceMeasurementContext (=0D + IN SPDM_DEVICE_CONTEXT *SpdmDeviceContext,=0D + IN OUT VOID *DeviceContext,=0D + IN UINTN DeviceContextSize=0D + )=0D +{=0D + TCG_DEVICE_SECURITY_EVENT_DATA_PCI_CONTEXT *PciContext;=0D + PCI_TYPE00 PciData;=0D + EFI_PCI_IO_PROTOCOL *PciIo;=0D + EFI_STATUS Status;=0D +=0D + if (DeviceContextSize !=3D sizeof (*PciContext)) {=0D + return EFI_BUFFER_TOO_SMALL;=0D + }=0D +=0D + PciIo =3D SpdmDeviceContext->DeviceIo;=0D + Status =3D PciIo->Pci.Read (PciIo, EfiPciIoWidthUint8, 0, sizeof (PciDat= a), &PciData);=0D + ASSERT_EFI_ERROR (Status);=0D +=0D + PciContext =3D DeviceContext;=0D + PciContext->Version =3D TCG_DEVICE_SECURITY_EVENT_DATA_PCI_CONTEXT_= VERSION;=0D + PciContext->Length =3D sizeof (*PciContext);=0D + PciContext->VendorId =3D PciData.Hdr.VendorId;=0D + PciContext->DeviceId =3D PciData.Hdr.DeviceId;=0D + PciContext->RevisionID =3D PciData.Hdr.RevisionID;=0D + PciContext->ClassCode[0] =3D PciData.Hdr.ClassCode[0];=0D + PciContext->ClassCode[1] =3D PciData.Hdr.ClassCode[1];=0D + PciContext->ClassCode[2] =3D PciData.Hdr.ClassCode[2];=0D + if ((PciData.Hdr.HeaderType & HEADER_LAYOUT_CODE) =3D=3D HEADER_TYPE_DEV= ICE) {=0D + PciContext->SubsystemVendorID =3D PciData.Device.SubsystemVendorID;=0D + PciContext->SubsystemID =3D PciData.Device.SubsystemID;=0D + } else {=0D + PciContext->SubsystemVendorID =3D 0;=0D + PciContext->SubsystemID =3D 0;=0D + }=0D +=0D + return EFI_SUCCESS;=0D +}=0D +=0D +/**=0D + This function creates the SPDM device measurement context for TCG SPDM e= vent.=0D +=0D + @param[in] SpdmDeviceContext The SPDM context for the device= .=0D + @param[in, out] DeviceContext The TCG SPDM device measurement= context.=0D + @param[in] DeviceContextSize The size of TCG SPDM device mea= surement context.=0D +=0D + @retval EFI_SUCCESS The TCG SPDM device measurement context is retu= rned.=0D + @retval EFI_UNSUPPORTED The TCG SPDM device measurement context is unsu= pported.=0D +**/=0D +EFI_STATUS=0D +EFIAPI=0D +CreateDeviceMeasurementContext (=0D + IN SPDM_DEVICE_CONTEXT *SpdmDeviceContext,=0D + IN OUT VOID *DeviceContext,=0D + IN UINTN DeviceContextSize=0D + )=0D +{=0D + if (CompareGuid (&SpdmDeviceContext->DeviceId.DeviceType, &gEdkiiDeviceI= dentifierTypePciGuid)) {=0D + return CreatePciDeviceMeasurementContext (SpdmDeviceContext, DeviceCon= text, DeviceContextSize);=0D + }=0D +=0D + if (CompareGuid (&SpdmDeviceContext->DeviceId.DeviceType, &gEdkiiDeviceI= dentifierTypeUsbGuid)) {=0D + return EFI_UNSUPPORTED;=0D + }=0D +=0D + return EFI_UNSUPPORTED;=0D +}=0D +=0D +/**=0D + This function dumps data.=0D +=0D + @param[in] Data A pointer to Data.=0D + @param[in] Size The size of Data.=0D +=0D +**/=0D +VOID=0D +EFIAPI=0D +InternalDumpData (=0D + CONST UINT8 *Data,=0D + UINTN Size=0D + )=0D +{=0D + UINTN Index;=0D +=0D + for (Index =3D 0; Index < Size; Index++) {=0D + DEBUG ((DEBUG_INFO, "%02x ", (UINTN)Data[Index]));=0D + }=0D +}=0D +=0D +/**=0D + This function extend the PCI digest from the DvSec register.=0D +=0D + @param[in] SpdmDeviceContext The SPDM context for the device.=0D + @param[in] AuthState The auth state of the device.=0D + @param[in] MeasurementRecordLength The length of the SPDM measurement r= ecord=0D + @param[in] MeasurementRecord The SPDM measurement record=0D + @param[in] RequesterNonce A buffer to hold the requester nonc= e (32 bytes), if not NULL.=0D + @param[in] ResponderNonce A buffer to hold the responder nonc= e (32 bytes), if not NULL.=0D + @param[out] SecurityState The Device Security state associate= d with the device.=0D +=0D + @retval EFI_SUCCESS Operation completed successfully.=0D + @retval EFI_OUT_OF_RESOURCES Out of memory.=0D + @retval EFI_DEVICE_ERROR The operation was unsuccessful.=0D +=0D +**/=0D +EFI_STATUS=0D +ExtendMeasurement (=0D + IN SPDM_DEVICE_CONTEXT *SpdmDeviceContext,=0D + IN UINT8 AuthState,=0D + IN UINT32 MeasurementRecordLength,=0D + IN UINT8 *MeasurementRecord,=0D + IN UINT8 *RequesterNonce,=0D + IN UINT8 *ResponderNonce,=0D + OUT EDKII_DEVICE_SECURITY_STATE *SecurityState=0D + )=0D +{=0D + UINT32 PcrIndex;=0D + UINT32 EventType;=0D + VOID *EventLog;=0D + UINT32 EventLogSize;=0D + UINT8 *EventLogPtr;=0D +=0D + TCG_DEVICE_SECURITY_EVENT_DATA_HEADER2 *Event= Data2;=0D + TCG_DEVICE_SECURITY_EVENT_DATA_SUB_HEADER_SPDM_MEASUREMENT_BLOCK *TcgSp= dmMeasurementBlock;=0D + VOID *Devic= eContext;=0D + UINTN Device= ContextSize;=0D + EFI_STATUS Status= ;=0D + SPDM_MEASUREMENT_BLOCK_COMMON_HEADER *SpdmM= easurementBlockCommonHeader;=0D + SPDM_MEASUREMENT_BLOCK_DMTF_HEADER *SpdmM= easurementBlockDmtfHeader;=0D + VOID *Diges= t;=0D + UINTN Digest= Size;=0D + UINTN Device= PathSize;=0D + UINT32 Measur= ementHashAlgo;=0D + UINTN DataSi= ze;=0D + VOID *SpdmC= ontext;=0D + SPDM_DATA_PARAMETER Parame= ter;=0D +=0D + SpdmContext =3D SpdmDeviceContext->SpdmContext;=0D +=0D + EventLog =3D NULL;=0D + ZeroMem (&Parameter, sizeof (Parameter));=0D + Parameter.location =3D SpdmDataLocationConnection;=0D + DataSize =3D sizeof (MeasurementHashAlgo);=0D + Status =3D SpdmGetData (SpdmContext, SpdmDataMeasurementHash= Algo, &Parameter, &MeasurementHashAlgo, &DataSize);=0D + ASSERT_EFI_ERROR (Status);=0D +=0D + if (MeasurementRecord !=3D NULL) {=0D + SpdmMeasurementBlockCommonHeader =3D (VOID *)MeasurementRecord;=0D + SpdmMeasurementBlockDmtfHeader =3D (VOID *)(SpdmMeasurementBlockComm= onHeader + 1);=0D + Digest =3D (SpdmMeasurementBlockDmtfHeader += 1);=0D + DigestSize =3D MeasurementRecordLength - sizeof = (SPDM_MEASUREMENT_BLOCK_DMTF);=0D +=0D + DEBUG ((DEBUG_INFO, "SpdmMeasurementBlockCommonHeader\n"));=0D + DEBUG ((DEBUG_INFO, " Index - 0x%02x\n", SpdmM= easurementBlockCommonHeader->Index));=0D + DEBUG ((DEBUG_INFO, " MeasurementSpecification - 0x%02x\n", SpdmM= easurementBlockCommonHeader->MeasurementSpecification));=0D + DEBUG ((DEBUG_INFO, " MeasurementSize - 0x%04x\n", SpdmM= easurementBlockCommonHeader->MeasurementSize));=0D + DEBUG ((DEBUG_INFO, "SpdmMeasurementBlockDmtfHeader\n"));=0D + DEBUG ((DEBUG_INFO, " DMTFSpecMeasurementValueType - 0x%02x\n", SpdmM= easurementBlockDmtfHeader->DMTFSpecMeasurementValueType));=0D + DEBUG ((DEBUG_INFO, " DMTFSpecMeasurementValueSize - 0x%04x\n", SpdmM= easurementBlockDmtfHeader->DMTFSpecMeasurementValueSize));=0D + DEBUG ((DEBUG_INFO, "Measurement - "));=0D + InternalDumpData (Digest, DigestSize);=0D + DEBUG ((DEBUG_INFO, "\n"));=0D + if (MeasurementRecordLength <=3D sizeof (SPDM_MEASUREMENT_BLOCK_COMMON= _HEADER) + sizeof (SPDM_MEASUREMENT_BLOCK_DMTF_HEADER)) {=0D + SecurityState->MeasurementState =3D EDKII_DEVICE_SECURITY_STATE_ERRO= R_MEASUREMENT_AUTH_FAILURE;=0D + return EFI_SECURITY_VIOLATION;=0D + }=0D +=0D + if ((SpdmMeasurementBlockCommonHeader->MeasurementSpecification & SPDM= _MEASUREMENT_SPECIFICATION_DMTF) =3D=3D 0) {=0D + SecurityState->MeasurementState =3D EDKII_DEVICE_SECURITY_STATE_ERRO= R_MEASUREMENT_AUTH_FAILURE;=0D + return EFI_SECURITY_VIOLATION;=0D + }=0D +=0D + if (SpdmMeasurementBlockCommonHeader->MeasurementSize !=3D Measurement= RecordLength - sizeof (SPDM_MEASUREMENT_BLOCK_COMMON_HEADER)) {=0D + SecurityState->MeasurementState =3D EDKII_DEVICE_SECURITY_STATE_ERRO= R_MEASUREMENT_AUTH_FAILURE;=0D + return EFI_SECURITY_VIOLATION;=0D + }=0D +=0D + if (SpdmMeasurementBlockDmtfHeader->DMTFSpecMeasurementValueSize !=3D = SpdmMeasurementBlockCommonHeader->MeasurementSize - sizeof (SPDM_MEASUREMEN= T_BLOCK_DMTF_HEADER)) {=0D + SecurityState->MeasurementState =3D EDKII_DEVICE_SECURITY_STATE_ERRO= R_MEASUREMENT_AUTH_FAILURE;=0D + return EFI_SECURITY_VIOLATION;=0D + }=0D +=0D + //=0D + // Use PCR 2 for Firmware Blob code.=0D + //=0D + switch (SpdmMeasurementBlockDmtfHeader->DMTFSpecMeasurementValueType &= 0x7F) {=0D + case SPDM_MEASUREMENT_BLOCK_MEASUREMENT_TYPE_IMMUTABLE_ROM:=0D + case SPDM_MEASUREMENT_BLOCK_MEASUREMENT_TYPE_MUTABLE_FIRMWARE:=0D + case SPDM_MEASUREMENT_BLOCK_MEASUREMENT_TYPE_VERSION:=0D + case SPDM_MEASUREMENT_BLOCK_MEASUREMENT_TYPE_SECURE_VERSION_NUMBER:= =0D + if (SpdmDeviceContext->IsEmbeddedDevice) {=0D + PcrIndex =3D 0;=0D + } else {=0D + PcrIndex =3D 2;=0D + }=0D +=0D + EventType =3D EV_EFI_SPDM_FIRMWARE_BLOB;=0D + break;=0D + case SPDM_MEASUREMENT_BLOCK_MEASUREMENT_TYPE_HARDWARE_CONFIGURATION:= =0D + case SPDM_MEASUREMENT_BLOCK_MEASUREMENT_TYPE_FIRMWARE_CONFIGURATION:= =0D + case SPDM_MEASUREMENT_BLOCK_MEASUREMENT_TYPE_DEVICE_MODE:=0D + if (SpdmDeviceContext->IsEmbeddedDevice) {=0D + PcrIndex =3D 1;=0D + } else {=0D + PcrIndex =3D 3;=0D + }=0D +=0D + EventType =3D EV_EFI_SPDM_FIRMWARE_CONFIG;=0D + break;=0D + case SPDM_MEASUREMENT_BLOCK_MEASUREMENT_TYPE_MEASUREMENT_MANIFEST:=0D + // skip manifest, because manifest doesn't belong to the EV_EFI_SPDM= _FIRMWARE_BLOB and EV_EFI_SPDM_FIRMWARE_CONFIG=0D + default:=0D + return EFI_SUCCESS;=0D + }=0D + } else {=0D + if (SpdmDeviceContext->IsEmbeddedDevice) {=0D + PcrIndex =3D 0;=0D + } else {=0D + PcrIndex =3D 2;=0D + }=0D +=0D + EventType =3D EV_EFI_SPDM_FIRMWARE_BLOB;=0D + }=0D +=0D + DeviceContextSize =3D GetDeviceMeasurementContextSize (SpdmDeviceContext= );=0D + DevicePathSize =3D GetDevicePathSize (SpdmDeviceContext->DevicePath);= =0D +=0D + switch (AuthState) {=0D + case TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_AUTH_STATE_SUCCESS:=0D + EventLogSize =3D (UINT32)(sizeof (TCG_DEVICE_SECURITY_EVENT_DATA_HEA= DER2) +=0D + sizeof (UINT64) + DevicePathSize +=0D + sizeof (TCG_DEVICE_SECURITY_EVENT_DATA_SUB_H= EADER_SPDM_MEASUREMENT_BLOCK) +=0D + MeasurementRecordLength +=0D + DeviceContextSize);=0D + EventLog =3D AllocatePool (EventLogSize);=0D + if (EventLog =3D=3D NULL) {=0D + SecurityState->MeasurementState =3D EDKII_DEVICE_SECURITY_STATE_ER= ROR_UEFI_OUT_OF_RESOURCE;=0D + return EFI_OUT_OF_RESOURCES;=0D + }=0D +=0D + EventLogPtr =3D EventLog;=0D +=0D + EventData2 =3D (VOID *)EventLogPtr;=0D + CopyMem (EventData2->Signature, TCG_DEVICE_SECURITY_EVENT_DATA_SIGNA= TURE_2, sizeof (EventData2->Signature));=0D + EventData2->Version =3D TCG_DEVICE_SECURITY_EVENT_DATA_VERSION_2;= =0D + EventData2->AuthState =3D AuthState;=0D + EventData2->Reserved =3D 0;=0D + EventData2->Length =3D (UINT32)EventLogSize;=0D + EventData2->DeviceType =3D GetSpdmDeviceType (SpdmDeviceContext);=0D +=0D + EventData2->SubHeaderType =3D TCG_DEVICE_SECURITY_EVENT_DATA_DEVIC= E_SUB_HEADER_TYPE_SPDM_MEASUREMENT_BLOCK;=0D + EventData2->SubHeaderLength =3D sizeof (TCG_DEVICE_SECURITY_EVENT_DA= TA_SUB_HEADER_SPDM_MEASUREMENT_BLOCK) + MeasurementRecordLength;=0D + EventData2->SubHeaderUID =3D SpdmDeviceContext->DeviceUID;=0D +=0D + EventLogPtr =3D (VOID *)(EventData2 + 1);=0D +=0D + *(UINT64 *)EventLogPtr =3D (UINT64)DevicePathSize;=0D + EventLogPtr +=3D sizeof (UINT64);=0D + CopyMem (EventLogPtr, SpdmDeviceContext->DevicePath, DevicePathSize)= ;=0D + EventLogPtr +=3D DevicePathSize;=0D +=0D + TcgSpdmMeasurementBlock =3D (VOID *)Event= LogPtr;=0D + TcgSpdmMeasurementBlock->SpdmVersion =3D SpdmDeviceCon= text->SpdmVersion;=0D + TcgSpdmMeasurementBlock->SpdmMeasurementBlockCount =3D 1;=0D + TcgSpdmMeasurementBlock->Reserved =3D 0;=0D + TcgSpdmMeasurementBlock->SpdmMeasurementHashAlgo =3D MeasurementHa= shAlgo;=0D + EventLogPtr +=3D sizeof (TCG_D= EVICE_SECURITY_EVENT_DATA_SUB_HEADER_SPDM_MEASUREMENT_BLOCK);=0D +=0D + if ((MeasurementRecord !=3D NULL) && (MeasurementRecordLength !=3D 0= )) {=0D + CopyMem (EventLogPtr, MeasurementRecord, MeasurementRecordLength);= =0D + EventLogPtr +=3D MeasurementRecordLength;=0D + }=0D +=0D + if (DeviceContextSize !=3D 0) {=0D + DeviceContext =3D (VOID *)EventLogPtr;=0D + Status =3D CreateDeviceMeasurementContext (SpdmDeviceContex= t, DeviceContext, DeviceContextSize);=0D + if (Status !=3D EFI_SUCCESS) {=0D + SecurityState->MeasurementState =3D EDKII_DEVICE_SECURITY_STATE_= ERROR_DEVICE_ERROR;=0D + Status =3D EFI_DEVICE_ERROR;=0D + goto Exit;=0D + }=0D + }=0D +=0D + Status =3D TpmMeasureAndLogData (=0D + PcrIndex,=0D + EventType,=0D + EventLog,=0D + EventLogSize,=0D + EventLog,=0D + EventLogSize=0D + );=0D + if (EFI_ERROR (Status)) {=0D + SecurityState->MeasurementState =3D EDKII_DEVICE_SECURITY_STATE_ER= ROR_TCG_EXTEND_TPM_PCR;=0D + }=0D +=0D + DEBUG ((DEBUG_INFO, "TpmMeasureAndLogData (Measurement) - %r\n", Sta= tus));=0D + break;=0D + case TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_AUTH_STATE_FAIL_INVALID:=0D + EventLogSize =3D (UINT32)(sizeof (TCG_DEVICE_SECURITY_EVENT_DATA_HEA= DER2) +=0D + sizeof (UINT64) + DevicePathSize +=0D + DeviceContextSize);=0D + EventLog =3D AllocatePool (EventLogSize);=0D + if (EventLog =3D=3D NULL) {=0D + SecurityState->MeasurementState =3D EDKII_DEVICE_SECURITY_STATE_ER= ROR_UEFI_OUT_OF_RESOURCE;=0D + return EFI_OUT_OF_RESOURCES;=0D + }=0D +=0D + EventLogPtr =3D EventLog;=0D +=0D + EventData2 =3D (VOID *)EventLogPtr;=0D + CopyMem (EventData2->Signature, TCG_DEVICE_SECURITY_EVENT_DATA_SIGNA= TURE_2, sizeof (EventData2->Signature));=0D + EventData2->Version =3D TCG_DEVICE_SECURITY_EVENT_DATA_VERSION_2;= =0D + EventData2->AuthState =3D AuthState;=0D + EventData2->Reserved =3D 0;=0D + EventData2->Length =3D (UINT32)EventLogSize;=0D + EventData2->DeviceType =3D GetSpdmDeviceType (SpdmDeviceContext);=0D +=0D + EventData2->SubHeaderType =3D TCG_DEVICE_SECURITY_EVENT_DATA_DEVIC= E_SUB_HEADER_TYPE_SPDM_MEASUREMENT_BLOCK;=0D + EventData2->SubHeaderLength =3D 0;=0D + EventData2->SubHeaderUID =3D SpdmDeviceContext->DeviceUID;=0D +=0D + EventLogPtr =3D (VOID *)(EventData2 + 1);=0D +=0D + *(UINT64 *)EventLogPtr =3D (UINT64)DevicePathSize;=0D + EventLogPtr +=3D sizeof (UINT64);=0D + CopyMem (EventLogPtr, SpdmDeviceContext->DevicePath, DevicePathSize)= ;=0D + EventLogPtr +=3D DevicePathSize;=0D +=0D + if (DeviceContextSize !=3D 0) {=0D + DeviceContext =3D (VOID *)EventLogPtr;=0D + Status =3D CreateDeviceMeasurementContext (SpdmDeviceContex= t, DeviceContext, DeviceContextSize);=0D + if (Status !=3D EFI_SUCCESS) {=0D + SecurityState->MeasurementState =3D EDKII_DEVICE_SECURITY_STATE_= ERROR_DEVICE_ERROR;=0D + Status =3D EFI_DEVICE_ERROR;=0D + goto Exit;=0D + }=0D + }=0D +=0D + Status =3D TpmMeasureAndLogData (=0D + PcrIndex,=0D + EventType,=0D + EventLog,=0D + EventLogSize,=0D + EventLog,=0D + EventLogSize=0D + );=0D + if (EFI_ERROR (Status)) {=0D + SecurityState->MeasurementState =3D EDKII_DEVICE_SECURITY_STATE_ER= ROR_TCG_EXTEND_TPM_PCR;=0D + }=0D +=0D + DEBUG ((DEBUG_INFO, "TpmMeasureAndLogData (Measurement) - %r\n", Sta= tus));=0D + goto Exit;=0D + default:=0D + SecurityState->MeasurementState =3D EDKII_DEVICE_SECURITY_STATE_ERRO= R_UEFI_UNSUPPORTED;=0D + return EFI_UNSUPPORTED;=0D + }=0D +=0D + if (RequesterNonce !=3D NULL) {=0D + TCG_NV_INDEX_DYNAMIC_EVENT_LOG_STRUCT_SPDM_GET_MEASUREMENTS DynamicEv= entLogSpdmGetMeasurementsEvent;=0D +=0D + CopyMem (DynamicEventLogSpdmGetMeasurementsEvent.Header.Signature, TCG= _NV_EXTEND_INDEX_FOR_DYNAMIC_SIGNATURE, sizeof (TCG_NV_EXTEND_INDEX_FOR_DYN= AMIC_SIGNATURE));=0D + DynamicEventLogSpdmGetMeasurementsEvent.Header.Version =3D TCG_NV_INDE= X_DYNAMIC_EVENT_LOG_STRUCT_VERSION;=0D + ZeroMem (DynamicEventLogSpdmGetMeasurementsEvent.Header.Reserved, size= of (DynamicEventLogSpdmGetMeasurementsEvent.Header.Reserved));=0D + DynamicEventLogSpdmGetMeasurementsEvent.Header.Uid =3D SpdmDevice= Context->DeviceUID;=0D + DynamicEventLogSpdmGetMeasurementsEvent.DescriptionSize =3D sizeof (TC= G_SPDM_GET_MEASUREMENTS_DESCRIPTION);=0D + CopyMem (DynamicEventLogSpdmGetMeasurementsEvent.Description, TCG_SPDM= _GET_MEASUREMENTS_DESCRIPTION, sizeof (TCG_SPDM_GET_MEASUREMENTS_DESCRIPTIO= N));=0D + DynamicEventLogSpdmGetMeasurementsEvent.DataSize =3D SPDM_NONCE_SIZE;= =0D + CopyMem (DynamicEventLogSpdmGetMeasurementsEvent.Data, RequesterNonce,= SPDM_NONCE_SIZE);=0D +=0D + Status =3D TpmMeasureAndLogData (=0D + TCG_NV_EXTEND_INDEX_FOR_DYNAMIC,=0D + EV_NO_ACTION,=0D + &DynamicEventLogSpdmGetMeasurementsEvent,=0D + sizeof (DynamicEventLogSpdmGetMeasurementsEvent),=0D + &DynamicEventLogSpdmGetMeasurementsEvent,=0D + sizeof (DynamicEventLogSpdmGetMeasurementsEvent)=0D + );=0D + if (EFI_ERROR (Status)) {=0D + SecurityState->MeasurementState =3D EDKII_DEVICE_SECURITY_STATE_ERRO= R_TCG_EXTEND_TPM_PCR;=0D + }=0D +=0D + DEBUG ((DEBUG_INFO, "TpmMeasureAndLogData (Dynamic) - %r\n", Status));= =0D + }=0D +=0D + if (ResponderNonce !=3D NULL) {=0D + TCG_NV_INDEX_DYNAMIC_EVENT_LOG_STRUCT_SPDM_MEASUREMENTS DynamicEventL= ogSpdmMeasurementsEvent;=0D +=0D + CopyMem (DynamicEventLogSpdmMeasurementsEvent.Header.Signature, TCG_NV= _EXTEND_INDEX_FOR_DYNAMIC_SIGNATURE, sizeof (TCG_NV_EXTEND_INDEX_FOR_DYNAMI= C_SIGNATURE));=0D + DynamicEventLogSpdmMeasurementsEvent.Header.Version =3D TCG_NV_INDEX_D= YNAMIC_EVENT_LOG_STRUCT_VERSION;=0D + ZeroMem (DynamicEventLogSpdmMeasurementsEvent.Header.Reserved, sizeof = (DynamicEventLogSpdmMeasurementsEvent.Header.Reserved));=0D + DynamicEventLogSpdmMeasurementsEvent.Header.Uid =3D SpdmDeviceCon= text->DeviceUID;=0D + DynamicEventLogSpdmMeasurementsEvent.DescriptionSize =3D sizeof (TCG_S= PDM_MEASUREMENTS_DESCRIPTION);=0D + CopyMem (DynamicEventLogSpdmMeasurementsEvent.Description, TCG_SPDM_ME= ASUREMENTS_DESCRIPTION, sizeof (TCG_SPDM_MEASUREMENTS_DESCRIPTION));=0D + DynamicEventLogSpdmMeasurementsEvent.DataSize =3D SPDM_NONCE_SIZE;=0D + CopyMem (DynamicEventLogSpdmMeasurementsEvent.Data, ResponderNonce, SP= DM_NONCE_SIZE);=0D +=0D + Status =3D TpmMeasureAndLogData (=0D + TCG_NV_EXTEND_INDEX_FOR_DYNAMIC,=0D + EV_NO_ACTION,=0D + &DynamicEventLogSpdmMeasurementsEvent,=0D + sizeof (DynamicEventLogSpdmMeasurementsEvent),=0D + &DynamicEventLogSpdmMeasurementsEvent,=0D + sizeof (DynamicEventLogSpdmMeasurementsEvent)=0D + );=0D + if (EFI_ERROR (Status)) {=0D + SecurityState->MeasurementState =3D EDKII_DEVICE_SECURITY_STATE_ERRO= R_TCG_EXTEND_TPM_PCR;=0D + }=0D +=0D + DEBUG ((DEBUG_INFO, "TpmMeasureAndLogData (Dynamic) - %r\n", Status));= =0D + }=0D +=0D +Exit:=0D + if (EventLog !=3D NULL) {=0D + FreePool (EventLog);=0D + }=0D +=0D + return Status;=0D +}=0D +=0D +/**=0D + This function gets SPDM measurement and extend to TPM.=0D +=0D + @param[in] SpdmDeviceContext The SPDM context for the device= .=0D + @param[in] SlotId The number of slot id of the ce= rtificate.=0D + @param[out] SecurityState A poniter to security state of = the requester.=0D +=0D + @retval EFI_SUCCESS Operation completed successfully.=0D + @retval EFI_OUT_OF_RESOURCES Out of memory.=0D + @retval EFI_DEVICE_ERROR The operation was unsuccessful.=0D +=0D +**/=0D +EFI_STATUS=0D +EFIAPI=0D +DoDeviceMeasurement (=0D + IN SPDM_DEVICE_CONTEXT *SpdmDeviceContext,=0D + IN UINT8 SlotId,=0D + OUT EDKII_DEVICE_SECURITY_STATE *SecurityState=0D + )=0D +{=0D + EFI_STATUS Status;=0D + SPDM_RETURN SpdmReturn;=0D + VOID *SpdmContext;=0D + UINT32 CapabilityFlags;=0D + UINTN DataSize;=0D + SPDM_DATA_PARAMETER Parameter;=0D + UINT8 NumberOfBlocks;=0D + UINT32 MeasurementRecordLength;=0D + UINT8 MeasurementRecord[LIBSPDM_MAX_MEASUREMENT_R= ECORD_SIZE];=0D + UINT8 Index;=0D + UINT8 RequesterNonce[SPDM_NONCE_SIZE];=0D + UINT8 ResponderNonce[SPDM_NONCE_SIZE];=0D + UINT8 RequestAttribute;=0D + UINT32 MeasurementsBlockSize;=0D + SPDM_MEASUREMENT_BLOCK_DMTF *MeasurementBlock;=0D + UINT8 NumberOfBlock;=0D + UINT8 ReceivedNumberOfBlock;=0D + UINT8 AuthState;=0D + UINT8 ContentChanged;=0D + UINT8 ContentChangedCount;=0D +=0D + SpdmContext =3D SpdmDeviceContext->SpdmContext;=0D +=0D + ZeroMem (&Parameter, sizeof (Parameter));=0D + Parameter.location =3D SpdmDataLocationConnection;=0D + DataSize =3D sizeof (CapabilityFlags);=0D + SpdmGetData (SpdmContext, SpdmDataCapabilityFlags, &Parameter, &Capabili= tyFlags, &DataSize);=0D +=0D + if ((CapabilityFlags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MEAS_CAP_SIG= ) =3D=3D 0) {=0D + AuthState =3D TCG_DEVICE_SECURITY_EVENT_DATA_DEV= ICE_AUTH_STATE_FAIL_NO_SIG;=0D + Status =3D ExtendCertificate (SpdmDeviceConte= xt, AuthState, 0, NULL, NULL, 0, 0, SecurityState);=0D + SecurityState->MeasurementState =3D EDKII_DEVICE_SECURITY_STATE_ERROR_= DEVICE_NO_CAPABILITIES;=0D + if (Status !=3D EFI_SUCCESS) {=0D + return Status;=0D + } else {=0D + return EFI_UNSUPPORTED;=0D + }=0D + }=0D +=0D + RequestAttribute =3D 0;=0D + RequestAttribute |=3D SPDM_GET_MEASUREMENTS_REQUEST_ATTRIBUTES_GENERATE_= SIGNATURE;=0D +=0D + MeasurementRecordLength =3D sizeof (MeasurementRecord);=0D + ZeroMem (RequesterNonce, sizeof (RequesterNonce));=0D + ZeroMem (ResponderNonce, sizeof (ResponderNonce));=0D +=0D + //=0D + // get all measurement once, with signature.=0D + //=0D + SpdmReturn =3D SpdmGetMeasurementEx (=0D + SpdmContext,=0D + NULL,=0D + RequestAttribute,=0D + SPDM_GET_MEASUREMENTS_REQUEST_MEASUREMENT_OPERATION_ALL_M= EASUREMENTS,=0D + SlotId,=0D + NULL,=0D + &NumberOfBlocks,=0D + &MeasurementRecordLength,=0D + MeasurementRecord,=0D + NULL,=0D + RequesterNonce,=0D + ResponderNonce,=0D + NULL,=0D + 0=0D + );=0D + if (LIBSPDM_STATUS_IS_SUCCESS (SpdmReturn)) {=0D + DEBUG ((DEBUG_INFO, "NumberOfBlocks %d\n", NumberOfBlocks));=0D +=0D + MeasurementBlock =3D (VOID *)MeasurementRecord;=0D + for (Index =3D 0; Index < NumberOfBlocks; Index++) {=0D + MeasurementsBlockSize =3D=0D + sizeof (SPDM_MEASUREMENT_BLOCK_DMTF) +=0D + MeasurementBlock=0D + ->MeasurementBlockDmtfHeader=0D + .DMTFSpecMeasurementValueSize;=0D +=0D + AuthState =3D TCG_DEVICE_SECURITY_EVENT_DATA_D= EVICE_AUTH_STATE_SUCCESS;=0D + SecurityState->MeasurementState =3D EDKII_DEVICE_SECURITY_STATE_SUCC= ESS;=0D + if (Index =3D=3D NumberOfBlocks - 1) {=0D + Status =3D ExtendMeasurement (SpdmDeviceContext, AuthState, Measur= ementsBlockSize, (UINT8 *)MeasurementBlock, RequesterNonce, ResponderNonce,= SecurityState);=0D + } else {=0D + Status =3D ExtendMeasurement (SpdmDeviceContext, AuthState, Measur= ementsBlockSize, (UINT8 *)MeasurementBlock, NULL, NULL, SecurityState);=0D + }=0D +=0D + MeasurementBlock =3D (VOID *)((size_t)MeasurementBlock + Measurement= sBlockSize);=0D + if (Status !=3D EFI_SUCCESS) {=0D + return Status;=0D + }=0D + }=0D + } else if (SpdmReturn =3D=3D LIBSPDM_STATUS_VERIF_FAIL) {=0D + AuthState =3D TCG_DEVICE_SECURITY_EVENT_DATA_DEV= ICE_AUTH_STATE_FAIL_INVALID;=0D + SecurityState->MeasurementState =3D EDKII_DEVICE_SECURITY_STATE_ERROR_= MEASUREMENT_AUTH_FAILURE;=0D + Status =3D ExtendMeasurement (SpdmDeviceConte= xt, AuthState, 0, NULL, NULL, NULL, SecurityState);=0D + return Status;=0D + } else {=0D + ContentChangedCount =3D 0;=0D +ContentChangedFlag:=0D + RequestAttribute =3D 0;=0D + ContentChanged =3D SPDM_MEASUREMENTS_RESPONSE_CONTENT_NO_CHANGE= _DETECTED;=0D + ReceivedNumberOfBlock =3D 0;=0D +=0D + //=0D + // 1. Query the total number of measurements available.=0D + //=0D + SpdmReturn =3D SpdmGetMeasurement (=0D + SpdmContext,=0D + NULL,=0D + RequestAttribute,=0D + SPDM_GET_MEASUREMENTS_REQUEST_MEASUREMENT_OPERATION_TOT= AL_NUMBER_OF_MEASUREMENTS,=0D + SlotId,=0D + NULL,=0D + &NumberOfBlocks,=0D + NULL,=0D + NULL=0D + );=0D + if (LIBSPDM_STATUS_IS_ERROR (SpdmReturn)) {=0D + SecurityState->MeasurementState =3D EDKII_DEVICE_SECURITY_STATE_ERRO= R_DEVICE_ERROR;=0D + return EFI_DEVICE_ERROR;=0D + }=0D +=0D + DEBUG ((DEBUG_INFO, "NumberOfBlocks - 0x%x\n", NumberOfBlocks));=0D +=0D + ReceivedNumberOfBlock =3D 0;=0D + for (Index =3D 1; Index <=3D 0xFE; Index++) {=0D + if (ReceivedNumberOfBlock =3D=3D NumberOfBlocks) {=0D + break;=0D + }=0D +=0D + DEBUG ((DEBUG_INFO, "Index - 0x%x\n", Index));=0D + //=0D + // 2. query measurement one by one=0D + // get signature in last message only.=0D + //=0D + if (ReceivedNumberOfBlock =3D=3D NumberOfBlocks - 1) {=0D + RequestAttribute |=3D SPDM_GET_MEASUREMENTS_REQUEST_ATTRIBUTES_GEN= ERATE_SIGNATURE;=0D + }=0D +=0D + MeasurementRecordLength =3D sizeof (MeasurementRecord);=0D + ZeroMem (RequesterNonce, sizeof (RequesterNonce));=0D + ZeroMem (ResponderNonce, sizeof (ResponderNonce));=0D + SpdmReturn =3D SpdmGetMeasurementEx (=0D + SpdmContext,=0D + NULL,=0D + RequestAttribute,=0D + Index,=0D + SlotId,=0D + &ContentChanged,=0D + &NumberOfBlock,=0D + &MeasurementRecordLength,=0D + MeasurementRecord,=0D + NULL,=0D + RequesterNonce,=0D + ResponderNonce,=0D + NULL,=0D + 0=0D + );=0D + if (LIBSPDM_STATUS_IS_ERROR (SpdmReturn)) {=0D + if (SpdmReturn =3D=3D LIBSPDM_STATUS_VERIF_FAIL) {=0D + AuthState =3D TCG_DEVICE_SECURITY_EVENT_DA= TA_DEVICE_AUTH_STATE_FAIL_INVALID;=0D + SecurityState->MeasurementState =3D EDKII_DEVICE_SECURITY_STATE_= ERROR_DEVICE_ERROR;=0D + Status =3D ExtendMeasurement (SpdmDevic= eContext, AuthState, 0, NULL, NULL, NULL, SecurityState);=0D + return Status;=0D + } else {=0D + continue;=0D + }=0D + }=0D +=0D + if ((ReceivedNumberOfBlock =3D=3D NumberOfBlocks - 1) &&=0D + (ContentChanged =3D=3D SPDM_MEASUREMENTS_RESPONSE_CONTENT_CHANGE= _DETECTED))=0D + {=0D + if (ContentChangedCount =3D=3D 0) {=0D + ContentChangedCount++;=0D + goto ContentChangedFlag;=0D + } else {=0D + AuthState =3D TCG_DEVICE_SECURITY_EVENT_DA= TA_DEVICE_AUTH_STATE_FAIL_INVALID;=0D + SecurityState->MeasurementState =3D EDKII_DEVICE_SECURITY_STATE_= ERROR_DEVICE_ERROR;=0D + Status =3D ExtendMeasurement (SpdmDevic= eContext, AuthState, 0, NULL, NULL, NULL, SecurityState);=0D + return Status;=0D + }=0D + }=0D +=0D + DEBUG ((DEBUG_INFO, "ExtendMeasurement...\n"));=0D + AuthState =3D TCG_DEVICE_SECURITY_EVENT_DATA_D= EVICE_AUTH_STATE_SUCCESS;=0D + SecurityState->MeasurementState =3D EDKII_DEVICE_SECURITY_STATE_SUCC= ESS;=0D + if (ReceivedNumberOfBlock =3D=3D NumberOfBlocks - 1) {=0D + Status =3D ExtendMeasurement (SpdmDeviceContext, AuthState, Measur= ementRecordLength, MeasurementRecord, RequesterNonce, ResponderNonce, Secur= ityState);=0D + } else {=0D + Status =3D ExtendMeasurement (SpdmDeviceContext, AuthState, Measur= ementRecordLength, MeasurementRecord, NULL, ResponderNonce, SecurityState);= =0D + }=0D +=0D + if (Status !=3D EFI_SUCCESS) {=0D + return Status;=0D + }=0D +=0D + ReceivedNumberOfBlock +=3D 1;=0D + }=0D +=0D + if (ReceivedNumberOfBlock !=3D NumberOfBlocks) {=0D + SecurityState->MeasurementState =3D EDKII_DEVICE_SECURITY_STATE_ERRO= R_MEASUREMENT_AUTH_FAILURE;=0D + return EFI_DEVICE_ERROR;=0D + }=0D + }=0D +=0D + return EFI_SUCCESS;=0D +}=0D diff --git a/SecurityPkg/DeviceSecurity/SpdmSecurityLib/SpdmSecurityLib.c b= /SecurityPkg/DeviceSecurity/SpdmSecurityLib/SpdmSecurityLib.c new file mode 100644 index 0000000000..f438c16563 --- /dev/null +++ b/SecurityPkg/DeviceSecurity/SpdmSecurityLib/SpdmSecurityLib.c @@ -0,0 +1,148 @@ +/** @file=0D + EDKII Device Security library for SPDM device.=0D + It follows the SPDM Specification.=0D +=0D +Copyright (c) 2024, Intel Corporation. All rights reserved.
=0D +SPDX-License-Identifier: BSD-2-Clause-Patent=0D +=0D +**/=0D +=0D +#include "SpdmSecurityLibInternal.h"=0D +=0D +/**=0D + Helper function to quickly determine whether device authentication boot = is enabled.=0D +=0D + @retval TRUE device authentication boot is verifiably enabled.=0D + @retval FALSE device authentication boot is either disabled or an = error prevented checking.=0D +=0D +**/=0D +BOOLEAN=0D +EFIAPI=0D +IsDeviceAuthBootEnabled (=0D + VOID=0D + )=0D +{=0D + EFI_STATUS Status;=0D + UINT8 *DeviceAuthBootMode;=0D +=0D + DeviceAuthBootMode =3D NULL;=0D +=0D + Status =3D GetEfiGlobalVariable2 (EFI_DEVICE_AUTH_BOOT_MODE_NAME, (VOID = **)&DeviceAuthBootMode, NULL);=0D + //=0D + // Skip verification if DeviceAuthBootMode variable doesn't exist.=0D + //=0D + if (EFI_ERROR (Status)) {=0D + DEBUG ((DEBUG_ERROR, "Cannot check DeviceAuthBootMode variable %r \n "= , Status));=0D + return FALSE;=0D + }=0D +=0D + //=0D + // Skip verification if DeviceAuthBootMode is disabled but not AuditMode= =0D + //=0D + if (*DeviceAuthBootMode =3D=3D DEVICE_AUTH_BOOT_MODE_DISABLE) {=0D + FreePool (DeviceAuthBootMode);=0D + return FALSE;=0D + } else {=0D + FreePool (DeviceAuthBootMode);=0D + return TRUE;=0D + }=0D +}=0D +=0D +/**=0D + The device driver uses this service to authenticate and measure an SPDM = device.=0D +=0D + @param[in] SpdmDeviceInfo The SPDM context for the device.=0D + @param[in] SecurityPolicy The security policy of this device= .=0D + @param[out] SecurityState A pointer to security state if thi= s device.=0D +=0D + @retval EFI_SUCCESS The TCG SPDM device measurement context is returne= d.=0D + @retval EFI_UNSUPPORTED The TCG SPDM device measurement context is unsu= pported.=0D +=0D +**/=0D +EFI_STATUS=0D +EFIAPI=0D +SpdmDeviceAuthenticationAndMeasurement (=0D + IN EDKII_SPDM_DEVICE_INFO *SpdmDeviceInfo,=0D + IN EDKII_DEVICE_SECURITY_POLICY *SecurityPolicy,=0D + OUT EDKII_DEVICE_SECURITY_STATE *SecurityState=0D + )=0D +{=0D + EFI_STATUS Status;=0D + SPDM_DEVICE_CONTEXT *SpdmDeviceContext;=0D + UINT8 AuthState;=0D + UINT8 SlotId;=0D + BOOLEAN IsValidCertChain;=0D + BOOLEAN RootCertMatch;=0D +=0D + if ((PcdGet32 (PcdTcgPfpMeasurementRevision) < TCG_EfiSpecIDEventStruct_= SPEC_ERRATA_TPM2_REV_106) ||=0D + (PcdGet8 (PcdEnableSpdmDeviceAuthentication) =3D=3D 0))=0D + {=0D + return EFI_UNSUPPORTED;=0D + }=0D +=0D + SpdmDeviceContext =3D CreateSpdmDeviceContext (SpdmDeviceInfo, SecurityS= tate);=0D + if (SpdmDeviceContext =3D=3D NULL) {=0D + return EFI_UNSUPPORTED;=0D + }=0D +=0D + Status =3D EFI_SUCCESS;=0D + AuthState =3D TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_AUTH_STATE_SU= CCESS;=0D + SlotId =3D 0;=0D + IsValidCertChain =3D FALSE;=0D + RootCertMatch =3D FALSE;=0D +=0D + if (((SecurityPolicy->AuthenticationPolicy & EDKII_DEVICE_AUTHENTICATION= _REQUIRED) !=3D 0) ||=0D + ((SecurityPolicy->MeasurementPolicy & EDKII_DEVICE_MEASUREMENT_REQUI= RED) !=3D 0))=0D + {=0D + Status =3D DoDeviceCertificate (SpdmDeviceContext, &AuthState, &SlotId= , SecurityState, &IsValidCertChain, &RootCertMatch);=0D + if (EFI_ERROR (Status)) {=0D + DEBUG ((DEBUG_ERROR, "DoDeviceCertificate failed - %r\n", Status));= =0D + goto Ret;=0D + } else if ((AuthState =3D=3D TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_AUT= H_STATE_FAIL_NO_SIG) ||=0D + (AuthState =3D=3D TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_AUT= H_STATE_FAIL_INVALID))=0D + {=0D + goto Ret;=0D + }=0D + }=0D +=0D + if (((SecurityPolicy->AuthenticationPolicy & EDKII_DEVICE_AUTHENTICATION= _REQUIRED) !=3D 0) && (IsDeviceAuthBootEnabled ())) {=0D + Status =3D DoDeviceAuthentication (SpdmDeviceContext, &AuthState, Slot= Id, IsValidCertChain, RootCertMatch, SecurityState);=0D + if (EFI_ERROR (Status)) {=0D + DEBUG ((DEBUG_ERROR, "DoDeviceAuthentication failed - %r\n", Status)= );=0D + goto Ret;=0D + } else if ((AuthState =3D=3D TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_AUT= H_STATE_FAIL_NO_SIG) ||=0D + (AuthState =3D=3D TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_AUT= H_STATE_FAIL_INVALID))=0D + {=0D + goto Ret;=0D + }=0D + }=0D +=0D + if ((SecurityPolicy->MeasurementPolicy & EDKII_DEVICE_MEASUREMENT_REQUIR= ED) !=3D 0) {=0D + Status =3D DoDeviceMeasurement (SpdmDeviceContext, SlotId, SecuritySta= te);=0D + if (EFI_ERROR (Status)) {=0D + DEBUG ((DEBUG_ERROR, "DoDeviceMeasurement failed - %r\n", Status));= =0D + }=0D + }=0D +=0D +Ret:=0D + DestroySpdmDeviceContext (SpdmDeviceContext);=0D +=0D + return Status;=0D +}=0D +=0D +/**=0D + This function will get SpdmIoProtocol via Context.=0D +=0D + @param[in] SpdmContext The SPDM context for the device.=0D +=0D + return the pointer of Spdm Io protocol=0D +=0D +**/=0D +VOID *=0D +EFIAPI=0D +SpdmGetIoProtocolViaSpdmContext (=0D + IN VOID *SpdmContext=0D + )=0D +{=0D + return GetSpdmIoProtocolViaSpdmContext (SpdmContext);=0D +}=0D diff --git a/SecurityPkg/DeviceSecurity/SpdmSecurityLib/SpdmSecurityLib.inf= b/SecurityPkg/DeviceSecurity/SpdmSecurityLib/SpdmSecurityLib.inf new file mode 100644 index 0000000000..4f77020bd8 --- /dev/null +++ b/SecurityPkg/DeviceSecurity/SpdmSecurityLib/SpdmSecurityLib.inf @@ -0,0 +1,54 @@ +## @file=0D +# SPDM library.=0D +#=0D +# Copyright (c) 2024, Intel Corporation. All rights reserved.
=0D +#=0D +# SPDX-License-Identifier: BSD-2-Clause-Patent=0D +#=0D +##=0D +=0D +[Defines]=0D + INF_VERSION =3D 0x00010005=0D + BASE_NAME =3D SpdmSecurityLib=0D + FILE_GUID =3D 77D7770D-158E-4354-B813-B8792A0E982D= =0D + MODULE_TYPE =3D BASE=0D + VERSION_STRING =3D 1.0=0D + LIBRARY_CLASS =3D SpdmSecurityLib=0D +=0D +#=0D +# The following information is for reference only and not required by the = build tools.=0D +#=0D +# VALID_ARCHITECTURES =3D IA32 X64 AARCH64=0D +#=0D +=0D +[Sources]=0D + SpdmSecurityLibInternal.h=0D + SpdmSecurityLib.c=0D + SpdmConnectionInit.c=0D + SpdmMeasurement.c=0D + SpdmAuthentication.c=0D +=0D +[Packages]=0D + MdePkg/MdePkg.dec=0D + MdeModulePkg/MdeModulePkg.dec=0D + SecurityPkg/SecurityPkg.dec=0D + CryptoPkg/CryptoPkg.dec=0D +=0D +[LibraryClasses]=0D + BaseLib=0D + BaseMemoryLib=0D + DebugLib=0D + BaseCryptLib=0D + RngLib=0D + TpmMeasurementLib=0D + SpdmRequesterLib=0D + SpdmCommonLib=0D +=0D +[Guids]=0D + gEfiDeviceSignatureDatabaseGuid ## CONSUMES=0D + gEfiCertX509Guid ## CONSUMES=0D + gEfiDeviceSecuritySpdmUidGuid ## PRODUCES AND CONSUMES=0D +=0D +[Pcd]=0D + gEfiMdeModulePkgTokenSpaceGuid.PcdTcgPfpMeasurementRevision #= # CONSUMES=0D + gEfiMdeModulePkgTokenSpaceGuid.PcdEnableSpdmDeviceAuthentication = ## CONSUMES=0D diff --git a/SecurityPkg/DeviceSecurity/SpdmSecurityLib/SpdmSecurityLibInte= rnal.h b/SecurityPkg/DeviceSecurity/SpdmSecurityLib/SpdmSecurityLibInternal= .h new file mode 100644 index 0000000000..611274cb7d --- /dev/null +++ b/SecurityPkg/DeviceSecurity/SpdmSecurityLib/SpdmSecurityLibInternal.h @@ -0,0 +1,250 @@ +/** @file=0D + EDKII Device Security library for SPDM device.=0D + It follows the SPDM Specification.=0D +=0D +Copyright (c) 2024, Intel Corporation. All rights reserved.
=0D +SPDX-License-Identifier: BSD-2-Clause-Patent=0D +=0D +**/=0D +=0D +#ifndef SPDM_SECURITY_LIB_INTERNAL_H_=0D +#define SPDM_SECURITY_LIB_INTERNAL_H_=0D +=0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +=0D +#include =0D +#include =0D +=0D +#include =0D +#include =0D +#include "library/spdm_crypt_lib.h"=0D +=0D +#define SPDM_DEVICE_CONTEXT_SIGNATURE SIGNATURE_32 ('S', 'P', 'D', 'C')=0D +=0D +typedef struct {=0D + UINT32 Signature;=0D + // UEFI Context=0D + EDKII_DEVICE_IDENTIFIER DeviceId;=0D + BOOLEAN IsEmbeddedDevice;=0D + EFI_DEVICE_PATH_PROTOCOL *DevicePath;=0D + VOID *DeviceIo;=0D + UINT64 DeviceUID;=0D + // SPDM Context=0D + UINTN SpdmContextSize;=0D + VOID *SpdmContext;=0D + UINTN ScratchBufferSize;=0D + VOID *ScratchBuffer;=0D + UINT8 SpdmVersion;=0D + VOID *SpdmIoProtocol;=0D + EFI_SIGNATURE_LIST *SignatureList;=0D + UINTN SignatureListSize;=0D +} SPDM_DEVICE_CONTEXT;=0D +=0D +typedef struct {=0D + UINTN Signature;=0D + LIST_ENTRY Link;=0D + SPDM_DEVICE_CONTEXT *SpdmDeviceContext;=0D +} SPDM_DEVICE_CONTEXT_INSTANCE;=0D +=0D +#define SPDM_DEVICE_CONTEXT_INSTANCE_SIGNATURE SIGNATURE_32 ('S', 'D', 'C= ', 'S')=0D +#define SPDM_DEVICE_CONTEXT_INSTANCE_FROM_LINK(a) CR (a, SPDM_DEVICE_CONT= EXT_INSTANCE, Link, SPDM_DEVICE_CONTEXT_INSTANCE_SIGNATURE)=0D +=0D +VOID *=0D +EFIAPI=0D +GetSpdmIoProtocolViaSpdmContext (=0D + IN VOID *SpdmContext=0D + );=0D +=0D +/**=0D + This function creates the spdm device context and init connection to the= =0D + responder with the device info.=0D +=0D + @param[in] SpdmDeviceInfo A pointer to device info.=0D + @param[out] SecurityState A pointer to the security state of the= requester.=0D +=0D + @return the spdm device conext after the init connection succeeds.=0D +=0D +**/=0D +SPDM_DEVICE_CONTEXT *=0D +EFIAPI=0D +CreateSpdmDeviceContext (=0D + IN EDKII_SPDM_DEVICE_INFO *SpdmDeviceInfo,=0D + OUT EDKII_DEVICE_SECURITY_STATE *SecurityState=0D + );=0D +=0D +VOID=0D +EFIAPI=0D +DestroySpdmDeviceContext (=0D + IN SPDM_DEVICE_CONTEXT *SpdmDeviceContext=0D + );=0D +=0D +/**=0D + This function returns the SPDM device type for TCG SPDM event.=0D +=0D + @param[in] SpdmDeviceContext The SPDM context for the devic= e.=0D +=0D + @return TCG SPDM device type=0D +**/=0D +UINT32=0D +EFIAPI=0D +GetSpdmDeviceType (=0D + IN SPDM_DEVICE_CONTEXT *SpdmDeviceContext=0D + );=0D +=0D +/**=0D + This function returns the SPDM device measurement context size for TCG S= PDM event.=0D +=0D + @param[in] SpdmDeviceContext The SPDM context for the devic= e.=0D +=0D + @return TCG SPDM device measurement context size=0D +**/=0D +UINTN=0D +EFIAPI=0D +GetDeviceMeasurementContextSize (=0D + IN SPDM_DEVICE_CONTEXT *SpdmDeviceContext=0D + );=0D +=0D +/**=0D + This function creates the SPDM device measurement context for TCG SPDM e= vent.=0D +=0D + @param[in] SpdmDeviceContext The SPDM context for the device= .=0D + @param[in, OUT] DeviceContext The TCG SPDM device measurement= context.=0D + @param[in] DeviceContextSize The size of TCG SPDM device mea= surement context.=0D +=0D + @retval EFI_SUCCESS The TCG SPDM device measurement context is retu= rned.=0D + @retval EFI_UNSUPPORTED The TCG SPDM device measurement context is unsu= pported.=0D +**/=0D +EFI_STATUS=0D +EFIAPI=0D +CreateDeviceMeasurementContext (=0D + IN SPDM_DEVICE_CONTEXT *SpdmDeviceContext,=0D + IN OUT VOID *DeviceContext,=0D + IN UINTN DeviceContextSize=0D + );=0D +=0D +/**=0D + Extend Certicate and auth state to NV Index and measure trust anchor to = PCR.=0D +=0D + @param[in] SpdmDeviceContext The SPDM context for the device.= =0D + @param[in] AuthState The auth state of this deice.=0D + @param[in] CertChainSize The size of cert chain.=0D + @param[in] CertChain A pointer to a destination buffer= to store the certificate chain.=0D + @param[in] TrustAnchor A buffer to hold the trust_anchor= which is used to validate the peer=0D + certificate, if not NULL.=0D + @param[in] TrustAnchorSize A buffer to hold the trust_anchor= _size, if not NULL..=0D + @param[in] SlotId The number of slot for the certif= icate chain.=0D + @param[out] SecurityState A pointer to the security state o= f the requester.=0D +=0D + @retval EFI_SUCCESS Operation completed successfully.=0D + @retval EFI_OUT_OF_RESOURCES Out of memory.=0D + @retval EFI_DEVICE_ERROR The operation was unsuccessful.=0D +=0D +**/=0D +EFI_STATUS=0D +ExtendCertificate (=0D + IN SPDM_DEVICE_CONTEXT *SpdmDeviceContext,=0D + IN UINT8 AuthState,=0D + IN UINTN CertChainSize,=0D + IN UINT8 *CertChain,=0D + IN VOID *TrustAnchor,=0D + IN UINTN TrustAnchorSize,=0D + IN UINT8 SlotId,=0D + OUT EDKII_DEVICE_SECURITY_STATE *SecurityState=0D + );=0D +=0D +/**=0D + This function executes SPDM measurement and extend to TPM.=0D +=0D + @param[in] SpdmDeviceContext The SPDM context for the device= .=0D +**/=0D +EFI_STATUS=0D +EFIAPI=0D +DoDeviceMeasurement (=0D + IN SPDM_DEVICE_CONTEXT *SpdmDeviceContext,=0D + IN UINT8 SlotId,=0D + OUT EDKII_DEVICE_SECURITY_STATE *SecurityState=0D + );=0D +=0D +/**=0D + This function gets SPDM digest and certificates.=0D +=0D + @param[in] SpdmDeviceContext The SPDM context for the device.= =0D + @param[out] AuthState The auth state of the devices.=0D + @param[out] ValidSlotId The number of slot for the certi= ficate chain.=0D + @param[out] SecurityState The security state of the reques= ter.=0D + @param[out] IsValidCertChain The validity of the certificate = chain.=0D + @param[out] RootCertMatch The authority of the certificate= chain.=0D +=0D + @retval EFI_SUCCESS Operation completed successfully.=0D + @retval EFI_OUT_OF_RESOURCES Out of memory.=0D + @retval EFI_DEVICE_ERROR The operation was unsuccessful.=0D +=0D +**/=0D +EFI_STATUS=0D +EFIAPI=0D +DoDeviceCertificate (=0D + IN SPDM_DEVICE_CONTEXT *SpdmDeviceContext,=0D + OUT UINT8 *AuthState,=0D + OUT UINT8 *ValidSlotId,=0D + OUT EDKII_DEVICE_SECURITY_STATE *SecurityState,=0D + OUT BOOLEAN *IsValidCertChain,=0D + OUT BOOLEAN *RootCertMatch=0D + );=0D +=0D +/**=0D + This function does authentication.=0D +=0D + @param[in] SpdmDeviceContext The SPDM context for the device.= =0D + @param[out] AuthState The auth state of the devices.=0D + @param[in] ValidSlotId The number of slot for the certi= ficate chain.=0D + @param[out] SecurityState The security state of the reques= ter.=0D +=0D + @retval EFI_SUCCESS Operation completed successfully.=0D + @retval EFI_OUT_OF_RESOURCES Out of memory.=0D + @retval EFI_DEVICE_ERROR The operation was unsuccessful.=0D +=0D +**/=0D +EFI_STATUS=0D +EFIAPI=0D +DoDeviceAuthentication (=0D + IN SPDM_DEVICE_CONTEXT *SpdmDeviceContext,=0D + OUT UINT8 *AuthState,=0D + IN UINT8 ValidSlotId,=0D + IN BOOLEAN IsValidCertChain,=0D + IN BOOLEAN RootCertMatch,=0D + OUT EDKII_DEVICE_SECURITY_STATE *SecurityState=0D + );=0D +=0D +/**=0D + * This function dump raw data.=0D + *=0D + * @param data raw data=0D + * @param size raw data size=0D + **/=0D +VOID=0D +EFIAPI=0D +InternalDumpData (=0D + CONST UINT8 *Data,=0D + UINTN Size=0D + );=0D +=0D +#endif=0D diff --git a/SecurityPkg/Include/Library/SpdmSecurityLib.h b/SecurityPkg/In= clude/Library/SpdmSecurityLib.h new file mode 100644 index 0000000000..96a7841381 --- /dev/null +++ b/SecurityPkg/Include/Library/SpdmSecurityLib.h @@ -0,0 +1,437 @@ +/** @file=0D + EDKII Device Security library for SPDM device.=0D + It follows the SPDM Specification.=0D +=0D +Copyright (c) 2024, Intel Corporation. All rights reserved.
=0D +SPDX-License-Identifier: BSD-2-Clause-Patent=0D +=0D +**/=0D +=0D +#ifndef SPDM_SECURITY_LIB_H_=0D +#define SPDM_SECURITY_LIB_H_=0D +=0D +#include =0D +#include =0D +=0D +/**=0D + * Send an SPDM transport layer message to a device.=0D + *=0D + * The message is an SPDM message with transport layer wrapper,=0D + * or a secured SPDM message with transport layer wrapper.=0D + *=0D + * For requester, the message is a transport layer SPDM request.=0D + * For responder, the message is a transport layer SPDM response.=0D + *=0D + * @param spdm_context A pointer to the SPDM context.=0D + * @param message_size size in bytes of the message data= buffer.=0D + * @param message A pointer to a destination buffer = to store the message.=0D + * The caller is responsible for havin= g=0D + * either implicit or explicit ownersh= ip of the buffer.=0D + * The message pointer shall be inside= of=0D + * [msg_buf_ptr, msg_buf_ptr + max_msg= _size] from=0D + * acquired sender_buffer.=0D + * @param timeout The timeout, in 100ns units, to us= e for the execution=0D + * of the message. A timeout value of = 0=0D + * means that this function will wait = indefinitely for the=0D + * message to execute. If timeout is g= reater=0D + * than zero, then this function will = return RETURN_TIMEOUT if the=0D + * time required to execute the messag= e is greater=0D + * than timeout.=0D + *=0D + * @retval RETURN_SUCCESS The SPDM message is sent successfu= lly.=0D + * @retval RETURN_DEVICE_ERROR A device error occurs when the SPD= M message is sent to the device.=0D + * @retval RETURN_INVALID_PARAMETER The message is NULL or the message= _size is zero.=0D + * @retval RETURN_TIMEOUT A timeout occurred while waiting fo= r the SPDM message=0D + * to execute.=0D + **/=0D +typedef=0D + SPDM_RETURN=0D +(*SPDM_DEVICE_SEND_MESSAGE_FUNC)(=0D + IN VOID *SpdmContext,=0D + IN UINTN MessageSize,=0D + IN OUT CONST VOID *Message,=0D + IN UINT64 Timeout=0D + );=0D +=0D +/**=0D + * Receive an SPDM transport layer message from a device.=0D + *=0D + * The message is an SPDM message with transport layer wrapper,=0D + * or a secured SPDM message with transport layer wrapper.=0D + *=0D + * For requester, the message is a transport layer SPDM response.=0D + * For responder, the message is a transport layer SPDM request.=0D + *=0D + * @param spdm_context A pointer to the SPDM context.=0D + * @param message_size size in bytes of the message data= buffer.=0D + * @param message A pointer to a destination buffer = to store the message.=0D + * The caller is responsible for havin= g=0D + * either implicit or explicit ownersh= ip of the buffer.=0D + * On input, the message pointer shall= be msg_buf_ptr from=0D + * acquired receiver_buffer.=0D + * On output, the message pointer shal= l be inside of=0D + * [msg_buf_ptr, msg_buf_ptr + max_msg= _size] from=0D + * acquired receiver_buffer.=0D + * @param timeout The timeout, in 100ns units, to us= e for the execution=0D + * of the message. A timeout value of = 0=0D + * means that this function will wait = indefinitely for the=0D + * message to execute. If timeout is g= reater=0D + * than zero, then this function will = return RETURN_TIMEOUT if the=0D + * time required to execute the messag= e is greater=0D + * than timeout.=0D + *=0D + * @retval RETURN_SUCCESS The SPDM message is received succe= ssfully.=0D + * @retval RETURN_DEVICE_ERROR A device error occurs when the SPD= M message is received from the device.=0D + * @retval RETURN_INVALID_PARAMETER The message is NULL, message_size = is NULL or=0D + * the *message_size is zero.=0D + * @retval RETURN_TIMEOUT A timeout occurred while waiting fo= r the SPDM message=0D + * to execute.=0D + **/=0D +typedef=0D + SPDM_RETURN=0D +(*SPDM_DEVICE_RECEIVE_MESSAGE_FUNC)(=0D + IN VOID *SpdmContext,=0D + IN OUT UINTN *MessageSize,=0D + IN OUT VOID **Message,=0D + IN UINT64 Timeout=0D + );=0D +=0D +/**=0D + * Encode an SPDM or APP message to a transport layer message.=0D + *=0D + * For normal SPDM message, it adds the transport layer wrapper.=0D + * For secured SPDM message, it encrypts a secured message then adds the t= ransport layer wrapper.=0D + * For secured APP message, it encrypts a secured message then adds the tr= ansport layer wrapper.=0D + *=0D + * The APP message is encoded to a secured message directly in SPDM sessio= n.=0D + * The APP message format is defined by the transport layer.=0D + * Take MCTP as example: APP message =3D=3D MCTP header (MCTP_MESSAGE_TYPE= _SPDM) + SPDM message=0D + *=0D + * @param spdm_context A pointer to the SPDM context.=0D + * @param session_id Indicates if it is a secured mess= age protected via SPDM session.=0D + * If session_id is NULL, it is a norm= al message.=0D + * If session_id is NOT NULL, it is a = secured message.=0D + * @param is_app_message Indicates if it is an APP messag= e or SPDM message.=0D + * @param is_requester Indicates if it is a requester me= ssage.=0D + * @param message_size size in bytes of the message data= buffer.=0D + * @param message A pointer to a source buffer to st= ore the message.=0D + * For normal message, it shall point= to the acquired sender buffer.=0D + * For secured message, it shall poin= t to the scratch buffer in spdm_context.=0D + * @param transport_message_size size in bytes of the transport m= essage data buffer.=0D + * @param transport_message A pointer to a destination buffer= to store the transport message.=0D + * On input, it shall be msg_buf_ptr = from sender buffer.=0D + * On output, it will point to acquir= ed sender buffer.=0D + *=0D + * @retval RETURN_SUCCESS The message is encoded successfull= y.=0D + * @retval RETURN_INVALID_PARAMETER The message is NULL or the message= _size is zero.=0D + **/=0D +typedef=0D + SPDM_RETURN=0D +(*SPDM_TRANSPORT_ENCODE_MESSAGE_FUNC)(=0D + IN VOID *SpdmContext,=0D + IN OUT CONST UINT32 *SessionId,=0D + IN BOOLEAN IsAppMessage,=0D + IN BOOLEAN IsRequester,=0D + IN UINTN MessageSize,=0D + IN OUT VOID *Message,=0D + IN OUT UINTN *TransportMessageSize,=0D + IN VOID **TransportMessage=0D + );=0D +=0D +/**=0D + * Decode an SPDM or APP message from a transport layer message.=0D + *=0D + * For normal SPDM message, it removes the transport layer wrapper,=0D + * For secured SPDM message, it removes the transport layer wrapper, then = decrypts and verifies a secured message.=0D + * For secured APP message, it removes the transport layer wrapper, then d= ecrypts and verifies a secured message.=0D + *=0D + * The APP message is decoded from a secured message directly in SPDM sess= ion.=0D + * The APP message format is defined by the transport layer.=0D + * Take MCTP as example: APP message =3D=3D MCTP header (MCTP_MESSAGE_TYPE= _SPDM) + SPDM message=0D + *=0D + * @param spdm_context A pointer to the SPDM context.=0D + * @param session_id Indicates if it is a secured mess= age protected via SPDM session.=0D + * If *session_id is NULL, it is a nor= mal message.=0D + * If *session_id is NOT NULL, it is a= secured message.=0D + * @param is_app_message Indicates if it is an APP messag= e or SPDM message.=0D + * @param is_requester Indicates if it is a requester me= ssage.=0D + * @param transport_message_size size in bytes of the transport m= essage data buffer.=0D + * @param transport_message A pointer to a source buffer to s= tore the transport message.=0D + * For normal message or secured mess= age, it shall point to acquired receiver buffer.=0D + * @param message_size size in bytes of the message data= buffer.=0D + * @param message A pointer to a destination buffer = to store the message.=0D + * On input, it shall point to the sc= ratch buffer in spdm_context.=0D + * On output, for normal message, it = will point to the original receiver buffer.=0D + * On output, for secured message, it= will point to the scratch buffer in spdm_context.=0D + *=0D + * @retval RETURN_SUCCESS The message is decoded successfull= y.=0D + * @retval RETURN_INVALID_PARAMETER The message is NULL or the message= _size is zero.=0D + * @retval RETURN_UNSUPPORTED The transport_message is unsupport= ed.=0D + **/=0D +typedef=0D + SPDM_RETURN=0D +(*SPDM_TRANSPORT_DECODE_MESSAGE_FUNC)(=0D + IN VOID *SpdmContext,=0D + IN OUT UINT32 **SessionId,=0D + IN BOOLEAN *IsAppMessage,=0D + IN BOOLEAN IsRequester,=0D + IN UINTN TransportMessageSize,=0D + IN OUT VOID *TransportMessage,=0D + IN OUT UINTN *MessageSize,=0D + IN OUT VOID **Message=0D + );=0D +=0D +/**=0D + * Acquire a device sender buffer for transport layer message.=0D + *=0D + * The max_msg_size must be larger than=0D + * MAX (non-secure Transport Message Header Size +=0D + * SPDM_CAPABILITIES.DataTransferSize +=0D + * max alignment pad size (transport specific),=0D + * secure Transport Message Header Size +=0D + * sizeof(spdm_secured_message_a_data_header1_t) +=0D + * length of sequence_number (transport specific) +=0D + * sizeof(spdm_secured_message_a_data_header2_t) +=0D + * sizeof(spdm_secured_message_cipher_header_t) +=0D + * App Message Header Size (transport specific) +=0D + * SPDM_CAPABILITIES.DataTransferSize +=0D + * maximum random data size (transport specific) +=0D + * AEAD MAC size (16) +=0D + * max alignment pad size (transport specific))=0D + *=0D + * For MCTP,=0D + * Transport Message Header Size =3D sizeof(mctp_message_header_t= )=0D + * length of sequence_number =3D 2=0D + * App Message Header Size =3D sizeof(mctp_message_header_t)=0D + * maximum random data size =3D MCTP_MAX_RANDOM_NUMBER_COUNT=0D + * max alignment pad size =3D 0=0D + * For PCI_DOE,=0D + * Transport Message Header Size =3D sizeof(pci_doe_data_object_h= eader_t)=0D + * length of sequence_number =3D 0=0D + * App Message Header Size =3D 0=0D + * maximum random data size =3D 0=0D + * max alignment pad size =3D 3=0D + *=0D + * @param context A pointer to the SPDM context.=0D + * @param max_msg_size size in bytes of the maximum size= of sender buffer.=0D + * @param msg_buf_ptr A pointer to a sender buffer.=0D + *=0D + * @retval RETURN_SUCCESS The sender buffer is acquired.=0D + **/=0D +typedef=0D + SPDM_RETURN=0D +(*SPDM_DEVICE_ACQUIRE_SENDER_BUFFER_FUNC)(=0D + IN VOID *SpdmContext,=0D + IN OUT VOID **MsgBufPtr=0D + );=0D +=0D +/**=0D + * Release a device sender buffer for transport layer message.=0D + *=0D + * @param context A pointer to the SPDM context.=0D + * @param msg_buf_ptr A pointer to a sender buffer.=0D + *=0D + * @retval RETURN_SUCCESS The sender buffer is Released.=0D + **/=0D +typedef=0D + VOID=0D +(*SPDM_DEVICE_RELEASE_SENDER_BUFFER_FUNC)(=0D + IN VOID *SpdmContext,=0D + IN CONST VOID *MsgBufPtr=0D + );=0D +=0D +/**=0D + * Acquire a device receiver buffer for transport layer message.=0D + *=0D + * The max_msg_size must be larger than=0D + * MAX (non-secure Transport Message Header Size +=0D + * SPDM_CAPABILITIES.DataTransferSize +=0D + * max alignment pad size (transport specific),=0D + * secure Transport Message Header Size +=0D + * sizeof(spdm_secured_message_a_data_header1_t) +=0D + * length of sequence_number (transport specific) +=0D + * sizeof(spdm_secured_message_a_data_header2_t) +=0D + * sizeof(spdm_secured_message_cipher_header_t) +=0D + * App Message Header Size (transport specific) +=0D + * SPDM_CAPABILITIES.DataTransferSize +=0D + * maximum random data size (transport specific) +=0D + * AEAD MAC size (16) +=0D + * max alignment pad size (transport specific))=0D + *=0D + * For MCTP,=0D + * Transport Message Header Size =3D sizeof(mctp_message_header_t= )=0D + * length of sequence_number =3D 2=0D + * App Message Header Size =3D sizeof(mctp_message_header_t)=0D + * maximum random data size =3D MCTP_MAX_RANDOM_NUMBER_COUNT=0D + * max alignment pad size =3D 0=0D + * For PCI_DOE,=0D + * Transport Message Header Size =3D sizeof(pci_doe_data_object_h= eader_t)=0D + * length of sequence_number =3D 0=0D + * App Message Header Size =3D 0=0D + * maximum random data size =3D 0=0D + * max alignment pad size =3D 3=0D + *=0D + * @param context A pointer to the SPDM context.=0D + * @param max_msg_size size in bytes of the maximum size= of receiver buffer.=0D + * @param msg_buf_pt A pointer to a receiver buffer.=0D + *=0D + * @retval RETURN_SUCCESS The receiver buffer is acquired.=0D + **/=0D +typedef=0D + SPDM_RETURN=0D +(*SPDM_DEVICE_ACQUIRE_RECEIVER_BUFFER_FUNC)(=0D + IN VOID *SpdmContext,=0D + IN OUT VOID **MsgBufPtr=0D + );=0D +=0D +/**=0D + * Release a device receiver buffer for transport layer message.=0D + *=0D + * @param context A pointer to the SPDM context.=0D + * @param msg_buf_ptr A pointer to a receiver buffer.=0D + *=0D + * @retval RETURN_SUCCESS The receiver buffer is Released.=0D + **/=0D +typedef=0D + VOID=0D +(*SPDM_DEVICE_RELEASE_RECEIVER_BUFFER_FUNC)(=0D + IN VOID *SpdmContext,=0D + IN CONST VOID *MsgBufPtr=0D + );=0D +=0D +typedef struct {=0D + UINT32 Version;=0D + //=0D + // DeviceType is used to create TCG event log context_data.=0D + // DeviceHandle is used to create TCG event log device_path information.= =0D + //=0D + EDKII_DEVICE_IDENTIFIER *DeviceId;=0D +=0D + //=0D + // TRUE means to use PCR 0 (code) / 1 (config).=0D + // FALSE means to use PCR 2 (code) / 3 (config).=0D + //=0D + BOOLEAN IsEmbeddedDevice;=0D +=0D + //=0D + // Below 9 APIs are used to send/receive SPDM request/response.=0D + //=0D + // The request flow is:=0D + // |<--- SenderBufferSize --= ->|=0D + // |<--- TransportRequestBufferSize --->|= =0D + // |<---MaxHeaderSize--->|<-SpdmRequestBufferSize ->|=0D + // +--+------------------+=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D+----------------+--+=0D + // | | Transport Header | SPDM Message | Transport Tail |= |=0D + // +--+------------------+=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D+----------------+--+=0D + // ^ ^ ^=0D + // | | | SpdmRequestBuffer=0D + // | | TransportRequestBuffer=0D + // | SenderBuffer=0D + //=0D + // AcquireSenderBuffer (&SenderBuffer, &SenderBufferSize);=0D + // SpdmRequestBuffer =3D SenderBuffer + TransportHeaderSize;=0D + // /* build SPDM request in SpdmRequestBuffer */=0D + // TransportEncodeMessage (SpdmRequestBuffer, SpdmRequestBufferSize,=0D + // &TransportRequestBuffer, &TransportRequestBufferSize);=0D + // SendMessage (TransportRequestBuffer, TransportRequestBufferSize);=0D + // ReleaseSenderBuffer (SenderBuffer);=0D + //=0D + // The response flow is:=0D + // |<--- ReceiverBufferSize --= ->|=0D + // |<--- TransportResponseBufferSize --->|= =0D + // |<-SpdmResponseBufferSize->|=0D + // +--+------------------+=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D+----------------+--+=0D + // | | Transport Header | SPDM Message | Transport Tail |= |=0D + // +--+------------------+=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D+----------------+--+=0D + // ^ ^ ^=0D + // | | | SpdmResponseBuffer=0D + // | | TransportResponseBuffer=0D + // | ReceiverBuffer=0D + //=0D + // AcquireReceiverBuffer (&ReceiverBuffer, &ReceiverBufferSize);=0D + // TransportResponseBuffer =3D ReceiverBuffer;=0D + // ReceiveMessage (&TransportResponseBuffer, &TransportResponseBufferS= ize);=0D + // TransportDecodeMessage (TransportResponseBuffer, TransportResponseB= ufferSize,=0D + // &SpdmResponseBuffer, &SpdmResponseBufferSize);=0D + // /* process SPDM response in SpdmResponseBuffer */=0D + // ReleaseReceiverBuffer (ReceiverBuffer);=0D + //=0D +=0D + //=0D + // API required by SpdmRegisterDeviceIoFunc in libspdm=0D + // It is used to send/receive transport message (SPDM + transport header= ).=0D + //=0D + SPDM_DEVICE_SEND_MESSAGE_FUNC SendMessage;=0D + SPDM_DEVICE_RECEIVE_MESSAGE_FUNC ReceiveMessage;=0D + //=0D + // API required by SpdmRegisterTransportLayerFunc in libspdm=0D + // It is used to add/remove transport header for SPDM.=0D + //=0D + SPDM_TRANSPORT_ENCODE_MESSAGE_FUNC TransportEncodeMessage;=0D + SPDM_TRANSPORT_DECODE_MESSAGE_FUNC TransportDecodeMessage;=0D + //=0D + // API required by SpdmRegisterDeviceBufferFunc in libspdm=0D + // It is used to get the sender/receiver buffer for transport message (S= PDM + transport header).=0D + // The size MUST be big enough to send or receive one transport message = (SPDM + transport header).=0D + // Tthe sender/receiver buffer MAY be overlapped.=0D + //=0D + SPDM_DEVICE_ACQUIRE_SENDER_BUFFER_FUNC AcquireSenderBuffer;=0D + SPDM_DEVICE_RELEASE_SENDER_BUFFER_FUNC ReleaseSenderBuffer;=0D + SPDM_DEVICE_ACQUIRE_RECEIVER_BUFFER_FUNC AcquireReceiverBuffer;=0D + SPDM_DEVICE_RELEASE_RECEIVER_BUFFER_FUNC ReleaseReceiverBuffer;=0D +=0D + //=0D + // Preferred Algorithm List for SPDM negotiation.=0D + // If it is none zero, it will be used directly.=0D + // If it is zero, then the SpdmSecurityLib will set the default value.=0D + //=0D + UINT32 BaseHashAlgo;=0D + UINT32 BaseAsymAlgo;=0D +=0D + //=0D + // transfer size=0D + //=0D + UINT32 MaxSpdmMsgSize;=0D + UINT32 TransportHeaderSize;=0D + UINT32 TransportTailSize;=0D + UINT32 SenderBufferSize;=0D + UINT32 ReceiverBufferSize;=0D +=0D + EFI_GUID *SpdmIoProtocolGuid;=0D +} EDKII_SPDM_DEVICE_INFO;=0D +=0D +/**=0D + This function will send SPDM VCA, GET_CERTIFICATE, CHALLENGE, GET_MEASUR= EMENT,=0D + The certificate and measurement will be extended to TPM PCR/NvIndex.=0D +**/=0D +RETURN_STATUS=0D +EFIAPI=0D +SpdmDeviceAuthenticationAndMeasurement (=0D + IN EDKII_SPDM_DEVICE_INFO *SpdmDeviceInfo,=0D + IN EDKII_DEVICE_SECURITY_POLICY *SecurityPolicy,=0D + OUT EDKII_DEVICE_SECURITY_STATE *SecurityState=0D + );=0D +=0D +/**=0D + This function will get SpdmIoProtocol via Context.=0D +**/=0D +VOID *=0D +EFIAPI=0D +SpdmGetIoProtocolViaSpdmContext (=0D + IN VOID *SpdmContext=0D + );=0D +=0D +/**=0D + Helper function to quickly determine whether device authentication boot = is enabled.=0D +=0D + @retval TRUE device authentication boot is verifiably enabled.=0D + @retval FALSE device authentication boot is either disabled or an = error prevented checking.=0D +=0D +**/=0D +BOOLEAN=0D +EFIAPI=0D +IsDeviceAuthBootEnabled (=0D + VOID=0D + );=0D +=0D +#endif=0D diff --git a/SecurityPkg/Include/Protocol/DeviceSecurityPolicy.h b/Security= Pkg/Include/Protocol/DeviceSecurityPolicy.h new file mode 100644 index 0000000000..69148badb6 --- /dev/null +++ b/SecurityPkg/Include/Protocol/DeviceSecurityPolicy.h @@ -0,0 +1,133 @@ +/** @file=0D + Platform Device Security Policy Protocol definition=0D +=0D + Copyright (c) 2024, Intel Corporation. All rights reserved.
=0D + SPDX-License-Identifier: BSD-2-Clause-Patent=0D +=0D +**/=0D +=0D +#ifndef EDKII_DEVICE_SECURITY_POLICY_PROTOCOL_H_=0D +#define EDKII_DEVICE_SECURITY_POLICY_PROTOCOL_H_=0D +=0D +#include =0D +#include =0D +=0D +typedef struct _EDKII_DEVICE_SECURITY_POLICY_PROTOCOL EDKII_DEVICE_SECURIT= Y_POLICY_PROTOCOL;=0D +=0D +//=0D +// Revision The revision to which the DEVICE_SECURITY_POLICY protocol inte= rface adheres.=0D +// All future revisions must be backwards compatible.=0D +// If a future version is not back wards compatible it is not the= same GUID.=0D +//=0D +#define EDKII_DEVICE_SECURITY_POLICY_PROTOCOL_REVISION 0x00010000=0D +=0D +//=0D +// Revision The revision to which the DEVICE_SECURITY_POLICY structure adh= eres.=0D +// All future revisions must be backwards compatible.=0D +//=0D +#define EDKII_DEVICE_SECURITY_POLICY_REVISION 0x00010000=0D +=0D +///=0D +/// The macro for the policy defined in EDKII_DEVICE_SECURITY_POLICY=0D +///=0D +#define EDKII_DEVICE_MEASUREMENT_REQUIRED BIT0=0D +#define EDKII_DEVICE_AUTHENTICATION_REQUIRED BIT0=0D +=0D +///=0D +/// The device security policy data structure=0D +///=0D +typedef struct {=0D + UINT32 Revision;=0D + UINT32 MeasurementPolicy;=0D + UINT32 AuthenticationPolicy;=0D +} EDKII_DEVICE_SECURITY_POLICY;=0D +=0D +//=0D +// Revision The revision to which the DEVICE_SECURITY_STATE structure adhe= res.=0D +// All future revisions must be backwards compatible.=0D +//=0D +#define EDKII_DEVICE_SECURITY_STATE_REVISION 0x00010000=0D +=0D +///=0D +/// The macro for the state defined in EDKII_DEVICE_SECURITY_STATE=0D +///=0D +#define EDKII_DEVICE_SECURITY_STATE_SUCCESS 0=0D +#define EDKII_DEVICE_SECURITY_STATE_ERROR BIT31= =0D +#define EDKII_DEVICE_SECURITY_STATE_ERROR_UEFI_UNSUPPORTED (EDKII= _DEVICE_SECURITY_STATE_ERROR + 0x0)=0D +#define EDKII_DEVICE_SECURITY_STATE_ERROR_UEFI_GET_POLICY_PROTOCOL (EDKII= _DEVICE_SECURITY_STATE_ERROR + 0x1)=0D +#define EDKII_DEVICE_SECURITY_STATE_ERROR_UEFI_OUT_OF_RESOURCE (EDKII= _DEVICE_SECURITY_STATE_ERROR + 0x2)=0D +#define EDKII_DEVICE_SECURITY_STATE_ERROR_DEVICE_NO_CAPABILITIES (EDKII= _DEVICE_SECURITY_STATE_ERROR + 0x10)=0D +#define EDKII_DEVICE_SECURITY_STATE_ERROR_DEVICE_ERROR (EDKII= _DEVICE_SECURITY_STATE_ERROR + 0x11)=0D +#define EDKII_DEVICE_SECURITY_STATE_ERROR_TCG_EXTEND_TPM_PCR (EDKII= _DEVICE_SECURITY_STATE_ERROR + 0x20)=0D +#define EDKII_DEVICE_SECURITY_STATE_ERROR_MEASUREMENT_AUTH_FAILURE (EDKII= _DEVICE_SECURITY_STATE_ERROR + 0x21)=0D +#define EDKII_DEVICE_SECURITY_STATE_ERROR_CHALLENGE_FAILURE (EDKII= _DEVICE_SECURITY_STATE_ERROR + 0x30)=0D +#define EDKII_DEVICE_SECURITY_STATE_ERROR_CERTIFIACTE_FAILURE (EDKII= _DEVICE_SECURITY_STATE_ERROR + 0x31)=0D +#define EDKII_DEVICE_SECURITY_STATE_ERROR_NO_CERT_PROVISION (EDKII= _DEVICE_SECURITY_STATE_ERROR + 0x32)=0D +=0D +///=0D +/// The device security state data structure=0D +///=0D +typedef struct {=0D + UINT32 Revision;=0D + UINT32 MeasurementState;=0D + UINT32 AuthenticationState;=0D +} EDKII_DEVICE_SECURITY_STATE;=0D +=0D +/**=0D + This function returns the device security policy associated with the dev= ice.=0D +=0D + The device security driver may call this interface to get the platform p= olicy=0D + for the specific device and determine if the measurement or authenticati= on=0D + is required.=0D +=0D + @param[in] This The protocol instance pointer.=0D + @param[in] DeviceId The Identifier for the device.=0D + @param[out] DeviceSecurityPolicy The Device Security Policy associated= with the device.=0D +=0D + @retval EFI_SUCCESS The device security policy is returne= d=0D + @retval EFI_UNSUPPORTED The function is unsupported for the s= pecific Device.=0D +**/=0D +typedef=0D + EFI_STATUS=0D +(EFIAPI *EDKII_DEVICE_SECURITY_GET_DEVICE_POLICY)(=0D + IN EDKII_DEVICE_SECURITY_POLICY_PROTOCOL *This,=0D + IN EDKII_DEVICE_IDENTIFIER *DeviceId,=0D + OUT EDKII_DEVICE_SECURITY_POLICY *DeviceSecurityPolicy=0D + );=0D +=0D +/**=0D + This function sets the device state based upon the authentication result= .=0D +=0D + The device security driver may call this interface to give the platform= =0D + a notify based upon the measurement or authentication result.=0D + If the authentication or measurement fails, the platform may choose:=0D + 1) Do nothing.=0D + 2) Disable this device or slot temporarily and continue boot.=0D + 3) Reset the platform and retry again.=0D + 4) Disable this device or slot permanently.=0D + 5) Any other platform specific action.=0D +=0D + @param[in] This The protocol instance pointer.=0D + @param[in] DeviceId The Identifier for the device.=0D + @param[in] DeviceSecurityState The Device Security state associated = with the device.=0D +=0D + @retval EFI_SUCCESS The device state is set.=0D + @retval EFI_UNSUPPORTED The function is unsupported for the s= pecific Device.=0D +**/=0D +typedef=0D + EFI_STATUS=0D +(EFIAPI *EDKII_DEVICE_SECURITY_NOTIFY_DEVICE_STATE)(=0D + IN EDKII_DEVICE_SECURITY_POLICY_PROTOCOL *This,=0D + IN EDKII_DEVICE_IDENTIFIER *DeviceId,=0D + IN EDKII_DEVICE_SECURITY_STATE *DeviceSecurityState=0D + );=0D +=0D +struct _EDKII_DEVICE_SECURITY_POLICY_PROTOCOL {=0D + UINT32 Revision;=0D + EDKII_DEVICE_SECURITY_GET_DEVICE_POLICY GetDevicePolicy;=0D + EDKII_DEVICE_SECURITY_NOTIFY_DEVICE_STATE NotifyDeviceState;=0D +};=0D +=0D +extern EFI_GUID gEdkiiDeviceSecurityPolicyProtocolGuid;=0D +=0D +#endif=0D diff --git a/SecurityPkg/SecurityPkg.ci.yaml b/SecurityPkg/SecurityPkg.ci.y= aml index 53e5b1fd8e..2a4cbd3795 100644 --- a/SecurityPkg/SecurityPkg.ci.yaml +++ b/SecurityPkg/SecurityPkg.ci.yaml @@ -2,12 +2,14 @@ # CI configuration for SecurityPkg=0D #=0D # Copyright (c) Microsoft Corporation=0D -# Copyright (c) 2020, Intel Corporation. All rights reserved.
=0D +# Copyright (c) 2020 - 2024, Intel Corporation. All rights reserved.
=0D # SPDX-License-Identifier: BSD-2-Clause-Patent=0D ##=0D {=0D "LicenseCheck": {=0D - "IgnoreFiles": []=0D + "IgnoreFiles": [=0D + "DeviceSecurity/SpdmLib/Include",=0D + ]=0D },=0D "EccCheck": {=0D ## Exception sample looks like below:=0D @@ -23,7 +25,10 @@ "IgnoreFiles": [=0D "Library/TcgStorageCoreLib/TcgStorageUtil.c",=0D "Library/TcgStorageCoreLib/TcgStorageCore.c",=0D - "Library/Tpm2CommandLib/Tpm2NVStorage.c"=0D + "Library/Tpm2CommandLib/Tpm2NVStorage.c",=0D + "DeviceSecurity/SpdmLib/Include",=0D + "DeviceSecurity/SpdmLib/libspdm",=0D + "DeviceSecurity/OsStub"=0D ]=0D },=0D "CompilerPlugin": {=0D @@ -69,7 +74,11 @@ ]=0D },=0D "LibraryClassCheck": {=0D - "IgnoreHeaderFile": []=0D + "IgnoreHeaderFile": [=0D + "DeviceSecurity/SpdmLib/Include/library",=0D + "DeviceSecurity/SpdmLib/libspdm/include/library",=0D + ],=0D + "skip": True=0D },=0D =0D ## options defined ci/Plugin/SpellCheck=0D diff --git a/SecurityPkg/SecurityPkg.dec b/SecurityPkg/SecurityPkg.dec index 00c4ebdbed..a91e3ea028 100644 --- a/SecurityPkg/SecurityPkg.dec +++ b/SecurityPkg/SecurityPkg.dec @@ -5,7 +5,7 @@ # It also provides the definitions(including PPIs/PROTOCOLs/GUIDs and lib= rary classes)=0D # and libraries instances, which are used for those features.=0D #=0D -# Copyright (c) 2009 - 2020, Intel Corporation. All rights reserved.
=0D +# Copyright (c) 2009 - 2024, Intel Corporation. All rights reserved.
=0D # (C) Copyright 2015 Hewlett Packard Enterprise Development LP
=0D # Copyright (c) Microsoft Corporation.
=0D # SPDX-License-Identifier: BSD-2-Clause-Patent=0D @@ -23,6 +23,10 @@ Include=0D Test/Mock/Include=0D =0D +[Includes.Common.Private]=0D + DeviceSecurity/SpdmLib/Include=0D + DeviceSecurity/SpdmLib/libspdm/include=0D +=0D [LibraryClasses]=0D ## @libraryclass Provides hash interfaces from different implementatio= ns.=0D #=0D @@ -97,6 +101,10 @@ #=0D PlatformPKProtectionLib|Include/Library/PlatformPKProtectionLib.h=0D =0D + ## @libraryclass Perform SPDM (following SPDM spec) and measure data to= TPM (following TCG PFP spec).=0D + ##=0D + SpdmSecurityLib|Include/Library/SpdmSecurityLib.h=0D +=0D [Guids]=0D ## Security package token space guid.=0D # Include/Guid/SecurityPkgTokenSpace.h=0D @@ -219,6 +227,9 @@ ## GUID used to specify section with default dbt content=0D gDefaultdbtFileGuid =3D { 0x36c513ee, 0xa338, 0x4976, { 0= xa0, 0xfb, 0x6d, 0xdb, 0xa3, 0xda, 0xfe, 0x87 } }=0D =0D + ## GUID used to generate Spdm Uid=0D + gEfiDeviceSecuritySpdmUidGuid =3D {0xe37b5665, 0x5ef9, 0x4e7e, {0xb4, 0x= 91, 0xd6, 0x78, 0xab, 0xff, 0xfb, 0xcb }}=0D +=0D [Ppis]=0D ## The PPI GUID for that TPM physical presence should be locked.=0D # Include/Ppi/LockPhysicalPresence.h=0D diff --git a/SecurityPkg/SecurityPkg.dsc b/SecurityPkg/SecurityPkg.dsc index 4923d88f79..70981da361 100644 --- a/SecurityPkg/SecurityPkg.dsc +++ b/SecurityPkg/SecurityPkg.dsc @@ -1,7 +1,7 @@ ## @file=0D # Security Module Package for All Architectures.=0D #=0D -# Copyright (c) 2009 - 2021, Intel Corporation. All rights reserved.
=0D +# Copyright (c) 2009 - 2024, Intel Corporation. All rights reserved.
=0D # (C) Copyright 2015-2020 Hewlett Packard Enterprise Development LP
=0D # Copyright (c) 2022, Loongson Technology Corporation Limited. All rights = reserved.
=0D # Copyright (c) 2021 - 2022, Arm Limited. All rights reserved.
=0D @@ -76,6 +76,19 @@ TdxLib|MdePkg/Library/TdxLib/TdxLib.inf=0D VariablePolicyHelperLib|MdeModulePkg/Library/VariablePolicyHelperLib/Var= iablePolicyHelperLib.inf=0D =0D + SpdmSecurityLib|SecurityPkg/DeviceSecurity/SpdmSecurityLib/SpdmSecurityL= ib.inf=0D + SpdmDeviceSecretLib|SecurityPkg/DeviceSecurity/SpdmLib/SpdmDeviceSecretL= ibNull.inf=0D + SpdmCryptLib|SecurityPkg/DeviceSecurity/SpdmLib/SpdmCryptLib.inf=0D + SpdmCommonLib|SecurityPkg/DeviceSecurity/SpdmLib/SpdmCommonLib.inf=0D + SpdmRequesterLib|SecurityPkg/DeviceSecurity/SpdmLib/SpdmRequesterLib.inf= =0D + SpdmResponderLib|SecurityPkg/DeviceSecurity/SpdmLib/SpdmResponderLib.inf= =0D + SpdmSecuredMessageLib|SecurityPkg/DeviceSecurity/SpdmLib/SpdmSecuredMess= ageLib.inf=0D + SpdmTransportMctpLib|SecurityPkg/DeviceSecurity/SpdmLib/SpdmTransportMct= pLib.inf=0D + SpdmTransportPciDoeLib|SecurityPkg/DeviceSecurity/SpdmLib/SpdmTransportP= ciDoeLib.inf=0D + CryptlibWrapper|SecurityPkg/DeviceSecurity/OsStub/CryptlibWrapper/Cryptl= ibWrapper.inf=0D + PlatformLibWrapper|SecurityPkg/DeviceSecurity/OsStub/PlatformLibWrapper/= PlatformLibWrapper.inf=0D + MemLibWrapper|SecurityPkg/DeviceSecurity/OsStub/MemLibWrapper/MemLibWrap= per.inf=0D +=0D [LibraryClasses.ARM, LibraryClasses.AARCH64]=0D #=0D # It is not possible to prevent the ARM compiler for generic intrinsic f= unctions.=0D @@ -287,6 +300,22 @@ #=0D SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf=0D =0D + #=0D + # SPDM=0D + #=0D + SecurityPkg/DeviceSecurity/SpdmSecurityLib/SpdmSecurityLib.inf=0D + SecurityPkg/DeviceSecurity/SpdmLib/SpdmDeviceSecretLibNull.inf=0D + SecurityPkg/DeviceSecurity/SpdmLib/SpdmCryptLib.inf=0D + SecurityPkg/DeviceSecurity/SpdmLib/SpdmCommonLib.inf=0D + SecurityPkg/DeviceSecurity/SpdmLib/SpdmRequesterLib.inf=0D + SecurityPkg/DeviceSecurity/SpdmLib/SpdmResponderLib.inf=0D + SecurityPkg/DeviceSecurity/SpdmLib/SpdmSecuredMessageLib.inf=0D + SecurityPkg/DeviceSecurity/SpdmLib/SpdmTransportMctpLib.inf=0D + SecurityPkg/DeviceSecurity/SpdmLib/SpdmTransportPciDoeLib.inf=0D + SecurityPkg/DeviceSecurity/OsStub/CryptlibWrapper/CryptlibWrapper.inf=0D + SecurityPkg/DeviceSecurity/OsStub/PlatformLibWrapper/PlatformLibWrapper.= inf=0D + SecurityPkg/DeviceSecurity/OsStub/MemLibWrapper/MemLibWrapper.inf=0D +=0D [Components.IA32, Components.X64]=0D SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDx= e.inf=0D =0D --=20 2.26.2.windows.1 -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#117976): https://edk2.groups.io/g/devel/message/117976 Mute This Topic: https://groups.io/mt/105594744/7686176 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io] -=-=-=-=-=-=-=-=-=-=-=-