mirror of
https://github.com/acidanthera/audk.git
synced 2025-07-20 04:04:27 +02:00
SecurityPkg: add DeviceSecurity support
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 <jiewen.yao@intel.com> Signed-off-by: Wenxing Hou <wenxing.hou@intel.com> Reviewed-by: Jiewen Yao <jiewen.yao@intel.com>
This commit is contained in:
parent
c3f615a1bd
commit
750d763623
@ -0,0 +1,970 @@
|
||||
/** @file
|
||||
EDKII Device Security library for SPDM device.
|
||||
It follows the SPDM Specification.
|
||||
|
||||
Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
**/
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/BaseCryptLib.h>
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
#include <Library/MemoryAllocationLib.h>
|
||||
#include "hal/base.h"
|
||||
#include "hal/library/cryptlib.h"
|
||||
|
||||
void *
|
||||
libspdm_sha256_new (
|
||||
void
|
||||
)
|
||||
{
|
||||
size_t CtxSize;
|
||||
void *HashCtx;
|
||||
|
||||
HashCtx = NULL;
|
||||
CtxSize = Sha256GetContextSize ();
|
||||
HashCtx = AllocatePool (CtxSize);
|
||||
|
||||
return HashCtx;
|
||||
}
|
||||
|
||||
void
|
||||
libspdm_sha256_free (
|
||||
void *Sha256Ctx
|
||||
)
|
||||
{
|
||||
if (Sha256Ctx != NULL) {
|
||||
FreePool (Sha256Ctx);
|
||||
Sha256Ctx = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
libspdm_sha256_init (
|
||||
void *Sha256Ctx
|
||||
)
|
||||
{
|
||||
return Sha256Init (Sha256Ctx);
|
||||
}
|
||||
|
||||
bool
|
||||
libspdm_sha256_duplicate (
|
||||
const void *Sha256Context,
|
||||
void *NewSha256Context
|
||||
)
|
||||
{
|
||||
return Sha256Duplicate (Sha256Context, NewSha256Context);
|
||||
}
|
||||
|
||||
bool
|
||||
libspdm_sha256_update (
|
||||
void *Sha256Context,
|
||||
const void *Data,
|
||||
size_t DataSize
|
||||
)
|
||||
{
|
||||
return Sha256Update (Sha256Context, Data, DataSize);
|
||||
}
|
||||
|
||||
bool
|
||||
libspdm_sha256_final (
|
||||
void *sha256_context,
|
||||
uint8_t *hash_value
|
||||
)
|
||||
{
|
||||
return Sha256Final (sha256_context, hash_value);
|
||||
}
|
||||
|
||||
bool
|
||||
libspdm_sha256_hash_all (
|
||||
const void *data,
|
||||
size_t data_size,
|
||||
uint8_t *hash_value
|
||||
)
|
||||
{
|
||||
return Sha256HashAll (data, data_size, hash_value);
|
||||
}
|
||||
|
||||
void *
|
||||
libspdm_sha384_new (
|
||||
void
|
||||
)
|
||||
{
|
||||
size_t CtxSize;
|
||||
void *HashCtx;
|
||||
|
||||
HashCtx = NULL;
|
||||
CtxSize = Sha384GetContextSize ();
|
||||
HashCtx = AllocatePool (CtxSize);
|
||||
|
||||
return HashCtx;
|
||||
}
|
||||
|
||||
void
|
||||
libspdm_sha384_free (
|
||||
void *Sha384Ctx
|
||||
)
|
||||
{
|
||||
if (Sha384Ctx != NULL) {
|
||||
FreePool (Sha384Ctx);
|
||||
Sha384Ctx = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
libspdm_sha384_init (
|
||||
void *sha384_context
|
||||
)
|
||||
{
|
||||
return Sha384Init (sha384_context);
|
||||
}
|
||||
|
||||
bool
|
||||
libspdm_sha384_duplicate (
|
||||
const void *sha384_context,
|
||||
void *new_sha384_context
|
||||
)
|
||||
{
|
||||
return Sha384Duplicate (sha384_context, new_sha384_context);
|
||||
}
|
||||
|
||||
bool
|
||||
libspdm_sha384_update (
|
||||
void *sha384_context,
|
||||
const void *data,
|
||||
size_t data_size
|
||||
)
|
||||
{
|
||||
return Sha384Update (sha384_context, data, data_size);
|
||||
}
|
||||
|
||||
bool
|
||||
libspdm_sha384_final (
|
||||
void *sha384_context,
|
||||
uint8_t *hash_value
|
||||
)
|
||||
{
|
||||
return Sha384Final (sha384_context, hash_value);
|
||||
}
|
||||
|
||||
bool
|
||||
libspdm_sha384_hash_all (
|
||||
const void *data,
|
||||
size_t data_size,
|
||||
uint8_t *hash_value
|
||||
)
|
||||
{
|
||||
return Sha384HashAll (data, data_size, hash_value);
|
||||
}
|
||||
|
||||
void *
|
||||
libspdm_hmac_sha256_new (
|
||||
void
|
||||
)
|
||||
{
|
||||
return HmacSha256New ();
|
||||
}
|
||||
|
||||
void
|
||||
libspdm_hmac_sha256_free (
|
||||
void *hmac_sha256_ctx
|
||||
)
|
||||
{
|
||||
HmacSha256Free (hmac_sha256_ctx);
|
||||
}
|
||||
|
||||
bool
|
||||
libspdm_hmac_sha256_set_key (
|
||||
void *hmac_sha256_ctx,
|
||||
const uint8_t *key,
|
||||
size_t key_size
|
||||
)
|
||||
{
|
||||
return HmacSha256SetKey (hmac_sha256_ctx, key, key_size);
|
||||
}
|
||||
|
||||
bool
|
||||
libspdm_hmac_sha256_duplicate (
|
||||
const void *hmac_sha256_ctx,
|
||||
void *new_hmac_sha256_ctx
|
||||
)
|
||||
{
|
||||
return HmacSha256Duplicate (hmac_sha256_ctx, new_hmac_sha256_ctx);
|
||||
}
|
||||
|
||||
bool
|
||||
libspdm_hmac_sha256_update (
|
||||
void *hmac_sha256_ctx,
|
||||
const void *data,
|
||||
size_t data_size
|
||||
)
|
||||
{
|
||||
return HmacSha256Update (hmac_sha256_ctx, data, data_size);
|
||||
}
|
||||
|
||||
bool
|
||||
libspdm_hmac_sha256_final (
|
||||
void *hmac_sha256_ctx,
|
||||
uint8_t *hmac_value
|
||||
)
|
||||
{
|
||||
return HmacSha256Final (hmac_sha256_ctx, hmac_value);
|
||||
}
|
||||
|
||||
bool
|
||||
libspdm_hmac_sha256_all (
|
||||
const void *data,
|
||||
size_t data_size,
|
||||
const uint8_t *key,
|
||||
size_t key_size,
|
||||
uint8_t *hmac_value
|
||||
)
|
||||
{
|
||||
return HmacSha256All (data, data_size, key, key_size, hmac_value);
|
||||
}
|
||||
|
||||
void *
|
||||
libspdm_hmac_sha384_new (
|
||||
void
|
||||
)
|
||||
{
|
||||
return HmacSha384New ();
|
||||
}
|
||||
|
||||
void
|
||||
libspdm_hmac_sha384_free (
|
||||
void *hmac_sha384_ctx
|
||||
)
|
||||
{
|
||||
HmacSha384Free (hmac_sha384_ctx);
|
||||
}
|
||||
|
||||
bool
|
||||
libspdm_hmac_sha384_set_key (
|
||||
void *hmac_sha384_ctx,
|
||||
const uint8_t *key,
|
||||
size_t key_size
|
||||
)
|
||||
{
|
||||
return HmacSha384SetKey (hmac_sha384_ctx, key, key_size);
|
||||
}
|
||||
|
||||
bool
|
||||
libspdm_hmac_sha384_duplicate (
|
||||
const void *hmac_sha384_ctx,
|
||||
void *new_hmac_sha384_ctx
|
||||
)
|
||||
{
|
||||
return HmacSha384Duplicate (hmac_sha384_ctx, new_hmac_sha384_ctx);
|
||||
}
|
||||
|
||||
bool
|
||||
libspdm_hmac_sha384_update (
|
||||
void *hmac_sha384_ctx,
|
||||
const void *data,
|
||||
size_t data_size
|
||||
)
|
||||
{
|
||||
return HmacSha384Update (hmac_sha384_ctx, data, data_size);
|
||||
}
|
||||
|
||||
bool
|
||||
libspdm_hmac_sha384_final (
|
||||
void *hmac_sha384_ctx,
|
||||
uint8_t *hmac_value
|
||||
)
|
||||
{
|
||||
return HmacSha384Final (hmac_sha384_ctx, hmac_value);
|
||||
}
|
||||
|
||||
bool
|
||||
libspdm_hmac_sha384_all (
|
||||
const void *data,
|
||||
size_t data_size,
|
||||
const uint8_t *key,
|
||||
size_t key_size,
|
||||
uint8_t *hmac_value
|
||||
)
|
||||
{
|
||||
return HmacSha384All (data, data_size, key, key_size, hmac_value);
|
||||
}
|
||||
|
||||
bool
|
||||
libspdm_aead_aes_gcm_encrypt (
|
||||
const uint8_t *key,
|
||||
size_t key_size,
|
||||
const uint8_t *iv,
|
||||
size_t iv_size,
|
||||
const uint8_t *a_data,
|
||||
size_t a_data_size,
|
||||
const uint8_t *data_in,
|
||||
size_t data_in_size,
|
||||
uint8_t *tag_out,
|
||||
size_t tag_size,
|
||||
uint8_t *data_out,
|
||||
size_t *data_out_size
|
||||
)
|
||||
{
|
||||
return AeadAesGcmEncrypt (
|
||||
key,
|
||||
key_size,
|
||||
iv,
|
||||
iv_size,
|
||||
a_data,
|
||||
a_data_size,
|
||||
data_in,
|
||||
data_in_size,
|
||||
tag_out,
|
||||
tag_size,
|
||||
data_out,
|
||||
data_out_size
|
||||
);
|
||||
}
|
||||
|
||||
bool
|
||||
libspdm_aead_aes_gcm_decrypt (
|
||||
const uint8_t *key,
|
||||
size_t key_size,
|
||||
const uint8_t *iv,
|
||||
size_t iv_size,
|
||||
const uint8_t *a_data,
|
||||
size_t a_data_size,
|
||||
const uint8_t *data_in,
|
||||
size_t data_in_size,
|
||||
const uint8_t *tag,
|
||||
size_t tag_size,
|
||||
uint8_t *data_out,
|
||||
size_t *data_out_size
|
||||
)
|
||||
{
|
||||
return AeadAesGcmDecrypt (
|
||||
key,
|
||||
key_size,
|
||||
iv,
|
||||
iv_size,
|
||||
a_data,
|
||||
a_data_size,
|
||||
data_in,
|
||||
data_in_size,
|
||||
tag,
|
||||
tag_size,
|
||||
data_out,
|
||||
data_out_size
|
||||
);
|
||||
}
|
||||
|
||||
void
|
||||
libspdm_rsa_free (
|
||||
void *rsa_context
|
||||
)
|
||||
{
|
||||
RsaFree (rsa_context);
|
||||
}
|
||||
|
||||
bool
|
||||
libspdm_rsa_pkcs1_sign_with_nid (
|
||||
void *rsa_context,
|
||||
size_t hash_nid,
|
||||
const uint8_t *message_hash,
|
||||
size_t hash_size,
|
||||
uint8_t *signature,
|
||||
size_t *sig_size
|
||||
)
|
||||
{
|
||||
switch (hash_nid) {
|
||||
case CRYPTO_NID_SHA256:
|
||||
if (hash_size != SHA256_DIGEST_SIZE) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case CRYPTO_NID_SHA384:
|
||||
if (hash_size != SHA384_DIGEST_SIZE) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case CRYPTO_NID_SHA512:
|
||||
if (hash_size != SHA512_DIGEST_SIZE) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return RsaPkcs1Sign (
|
||||
rsa_context,
|
||||
message_hash,
|
||||
hash_size,
|
||||
signature,
|
||||
sig_size
|
||||
);
|
||||
}
|
||||
|
||||
bool
|
||||
libspdm_rsa_pkcs1_verify_with_nid (
|
||||
void *rsa_context,
|
||||
size_t hash_nid,
|
||||
const uint8_t *message_hash,
|
||||
size_t hash_size,
|
||||
const uint8_t *signature,
|
||||
size_t sig_size
|
||||
)
|
||||
{
|
||||
switch (hash_nid) {
|
||||
case CRYPTO_NID_SHA256:
|
||||
if (hash_size != SHA256_DIGEST_SIZE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case CRYPTO_NID_SHA384:
|
||||
if (hash_size != SHA384_DIGEST_SIZE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case CRYPTO_NID_SHA512:
|
||||
if (hash_size != SHA512_DIGEST_SIZE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
return RsaPkcs1Verify (
|
||||
rsa_context,
|
||||
message_hash,
|
||||
hash_size,
|
||||
signature,
|
||||
sig_size
|
||||
);
|
||||
}
|
||||
|
||||
bool
|
||||
libspdm_rsa_get_private_key_from_pem (
|
||||
const uint8_t *pem_data,
|
||||
size_t pem_size,
|
||||
const char *password,
|
||||
void **rsa_context
|
||||
)
|
||||
{
|
||||
return RsaGetPrivateKeyFromPem (pem_data, pem_size, password, rsa_context);
|
||||
}
|
||||
|
||||
bool
|
||||
libspdm_rsa_get_public_key_from_x509 (
|
||||
const uint8_t *cert,
|
||||
size_t cert_size,
|
||||
void **rsa_context
|
||||
)
|
||||
{
|
||||
return RsaGetPublicKeyFromX509 (cert, cert_size, rsa_context);
|
||||
}
|
||||
|
||||
bool
|
||||
libspdm_ec_get_public_key_from_der (
|
||||
const uint8_t *der_data,
|
||||
size_t der_size,
|
||||
void **ec_context
|
||||
)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
libspdm_rsa_get_public_key_from_der (
|
||||
const uint8_t *der_data,
|
||||
size_t der_size,
|
||||
void **rsa_context
|
||||
)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
libspdm_ec_get_private_key_from_pem (
|
||||
const uint8_t *pem_data,
|
||||
size_t pem_size,
|
||||
const char *password,
|
||||
void **ec_context
|
||||
)
|
||||
{
|
||||
return EcGetPrivateKeyFromPem (pem_data, pem_size, password, ec_context);
|
||||
}
|
||||
|
||||
bool
|
||||
libspdm_ec_get_public_key_from_x509 (
|
||||
const uint8_t *cert,
|
||||
size_t cert_size,
|
||||
void **ec_context
|
||||
)
|
||||
{
|
||||
return EcGetPublicKeyFromX509 (cert, cert_size, ec_context);
|
||||
}
|
||||
|
||||
bool
|
||||
libspdm_asn1_get_tag (
|
||||
uint8_t **ptr,
|
||||
const uint8_t *end,
|
||||
size_t *length,
|
||||
uint32_t tag
|
||||
)
|
||||
{
|
||||
return Asn1GetTag (ptr, end, length, tag);
|
||||
}
|
||||
|
||||
bool
|
||||
libspdm_x509_get_subject_name (
|
||||
const uint8_t *cert,
|
||||
size_t cert_size,
|
||||
uint8_t *cert_subject,
|
||||
size_t *subject_size
|
||||
)
|
||||
{
|
||||
return X509GetSubjectName (cert, cert_size, cert_subject, subject_size);
|
||||
}
|
||||
|
||||
bool
|
||||
libspdm_x509_get_common_name (
|
||||
const uint8_t *cert,
|
||||
size_t cert_size,
|
||||
char *common_name,
|
||||
size_t *common_name_size
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
||||
Status = X509GetCommonName (cert, cert_size, common_name, common_name_size);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
libspdm_x509_get_organization_name (
|
||||
const uint8_t *cert,
|
||||
size_t cert_size,
|
||||
char *name_buffer,
|
||||
size_t *name_buffer_size
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
||||
Status = X509GetOrganizationName (cert, cert_size, name_buffer, name_buffer_size);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
libspdm_x509_get_version (
|
||||
const uint8_t *cert,
|
||||
size_t cert_size,
|
||||
size_t *version
|
||||
)
|
||||
{
|
||||
return X509GetVersion (cert, cert_size, version);
|
||||
}
|
||||
|
||||
bool
|
||||
libspdm_x509_get_serial_number (
|
||||
const uint8_t *cert,
|
||||
size_t cert_size,
|
||||
uint8_t *serial_number,
|
||||
size_t *serial_number_size
|
||||
)
|
||||
{
|
||||
return X509GetSerialNumber (cert, cert_size, serial_number, serial_number_size);
|
||||
}
|
||||
|
||||
bool
|
||||
libspdm_x509_get_issuer_name (
|
||||
const uint8_t *cert,
|
||||
size_t cert_size,
|
||||
uint8_t *cert_issuer,
|
||||
size_t *issuer_size
|
||||
)
|
||||
{
|
||||
return X509GetIssuerName (cert, cert_size, cert_issuer, issuer_size);
|
||||
}
|
||||
|
||||
bool
|
||||
libspdm_x509_get_signature_algorithm (
|
||||
const uint8_t *cert,
|
||||
size_t cert_size,
|
||||
uint8_t *oid,
|
||||
size_t *oid_size
|
||||
)
|
||||
{
|
||||
return X509GetSignatureAlgorithm (cert, cert_size, oid, oid_size);
|
||||
}
|
||||
|
||||
bool
|
||||
libspdm_x509_get_extension_data (
|
||||
const uint8_t *cert,
|
||||
size_t cert_size,
|
||||
const uint8_t *oid,
|
||||
size_t oid_size,
|
||||
uint8_t *extension_data,
|
||||
size_t *extension_data_size
|
||||
)
|
||||
{
|
||||
return X509GetExtensionData (
|
||||
cert,
|
||||
cert_size,
|
||||
oid,
|
||||
oid_size,
|
||||
extension_data,
|
||||
extension_data_size
|
||||
);
|
||||
}
|
||||
|
||||
bool
|
||||
libspdm_x509_get_validity (
|
||||
const uint8_t *cert,
|
||||
size_t cert_size,
|
||||
uint8_t *from,
|
||||
size_t *from_size,
|
||||
uint8_t *to,
|
||||
size_t *to_size
|
||||
)
|
||||
{
|
||||
return X509GetValidity (cert, cert_size, from, from_size, to, to_size);
|
||||
}
|
||||
|
||||
bool
|
||||
libspdm_x509_set_date_time (
|
||||
const char *date_time_str,
|
||||
void *date_time,
|
||||
size_t *date_time_size
|
||||
)
|
||||
{
|
||||
return X509FormatDateTime (date_time_str, date_time, date_time_size);
|
||||
}
|
||||
|
||||
int32_t
|
||||
libspdm_x509_compare_date_time (
|
||||
const void *date_time1,
|
||||
const void *date_time2
|
||||
)
|
||||
{
|
||||
return X509CompareDateTime (date_time1, date_time2);
|
||||
}
|
||||
|
||||
bool
|
||||
libspdm_x509_get_key_usage (
|
||||
const uint8_t *cert,
|
||||
size_t cert_size,
|
||||
size_t *usage
|
||||
)
|
||||
{
|
||||
return X509GetKeyUsage (cert, cert_size, usage);
|
||||
}
|
||||
|
||||
bool
|
||||
libspdm_x509_get_extended_key_usage (
|
||||
const uint8_t *cert,
|
||||
size_t cert_size,
|
||||
uint8_t *usage,
|
||||
size_t *usage_size
|
||||
)
|
||||
{
|
||||
return X509GetExtendedKeyUsage (cert, cert_size, usage, usage_size);
|
||||
}
|
||||
|
||||
bool
|
||||
libspdm_x509_verify_cert (
|
||||
const uint8_t *cert,
|
||||
size_t cert_size,
|
||||
const uint8_t *ca_cert,
|
||||
size_t ca_cert_size
|
||||
)
|
||||
{
|
||||
return X509VerifyCert (cert, cert_size, ca_cert, ca_cert_size);
|
||||
}
|
||||
|
||||
bool
|
||||
libspdm_x509_verify_cert_chain (
|
||||
const uint8_t *root_cert,
|
||||
size_t root_cert_length,
|
||||
const uint8_t *cert_chain,
|
||||
size_t cert_chain_length
|
||||
)
|
||||
{
|
||||
return X509VerifyCertChain (root_cert, root_cert_length, cert_chain, cert_chain_length);
|
||||
}
|
||||
|
||||
bool
|
||||
libspdm_x509_get_cert_from_cert_chain (
|
||||
const uint8_t *cert_chain,
|
||||
size_t cert_chain_length,
|
||||
const int32_t cert_index,
|
||||
const uint8_t **cert,
|
||||
size_t *cert_length
|
||||
)
|
||||
{
|
||||
return X509GetCertFromCertChain (
|
||||
cert_chain,
|
||||
cert_chain_length,
|
||||
cert_index,
|
||||
cert,
|
||||
cert_length
|
||||
);
|
||||
}
|
||||
|
||||
bool
|
||||
libspdm_x509_construct_certificate (
|
||||
const uint8_t *cert,
|
||||
size_t cert_size,
|
||||
uint8_t **single_x509_cert
|
||||
)
|
||||
{
|
||||
return X509ConstructCertificate (cert, cert_size, single_x509_cert);
|
||||
}
|
||||
|
||||
bool
|
||||
libspdm_x509_get_extended_basic_constraints (
|
||||
const uint8_t *cert,
|
||||
size_t cert_size,
|
||||
uint8_t *basic_constraints,
|
||||
size_t *basic_constraints_size
|
||||
)
|
||||
{
|
||||
return X509GetExtendedBasicConstraints (
|
||||
cert,
|
||||
cert_size,
|
||||
basic_constraints,
|
||||
basic_constraints_size
|
||||
);
|
||||
}
|
||||
|
||||
void *
|
||||
libspdm_ec_new_by_nid (
|
||||
size_t nid
|
||||
)
|
||||
{
|
||||
return EcNewByNid (nid);
|
||||
}
|
||||
|
||||
void
|
||||
libspdm_ec_free (
|
||||
void *ec_context
|
||||
)
|
||||
{
|
||||
EcFree (ec_context);
|
||||
}
|
||||
|
||||
bool
|
||||
libspdm_ec_generate_key (
|
||||
void *ec_context,
|
||||
uint8_t *public_data,
|
||||
size_t *public_size
|
||||
)
|
||||
{
|
||||
return EcGenerateKey (ec_context, public_data, public_size);
|
||||
}
|
||||
|
||||
bool
|
||||
libspdm_ec_compute_key (
|
||||
void *ec_context,
|
||||
const uint8_t *peer_public,
|
||||
size_t peer_public_size,
|
||||
uint8_t *key,
|
||||
size_t *key_size
|
||||
)
|
||||
{
|
||||
return EcDhComputeKey (ec_context, peer_public, peer_public_size, NULL, key, key_size);
|
||||
}
|
||||
|
||||
bool
|
||||
libspdm_ecdsa_sign (
|
||||
void *ec_context,
|
||||
size_t hash_nid,
|
||||
const uint8_t *message_hash,
|
||||
size_t hash_size,
|
||||
uint8_t *signature,
|
||||
size_t *sig_size
|
||||
)
|
||||
{
|
||||
return EcDsaSign (
|
||||
ec_context,
|
||||
hash_nid,
|
||||
message_hash,
|
||||
hash_size,
|
||||
signature,
|
||||
sig_size
|
||||
);
|
||||
}
|
||||
|
||||
bool
|
||||
libspdm_ecdsa_verify (
|
||||
void *ec_context,
|
||||
size_t hash_nid,
|
||||
const uint8_t *message_hash,
|
||||
size_t hash_size,
|
||||
const uint8_t *signature,
|
||||
size_t sig_size
|
||||
)
|
||||
{
|
||||
return EcDsaVerify (
|
||||
ec_context,
|
||||
hash_nid,
|
||||
message_hash,
|
||||
hash_size,
|
||||
signature,
|
||||
sig_size
|
||||
);
|
||||
}
|
||||
|
||||
bool
|
||||
libspdm_random_bytes (
|
||||
uint8_t *output,
|
||||
size_t size
|
||||
)
|
||||
{
|
||||
return RandomBytes (output, size);
|
||||
}
|
||||
|
||||
bool
|
||||
libspdm_hkdf_sha256_extract_and_expand (
|
||||
const uint8_t *key,
|
||||
size_t key_size,
|
||||
const uint8_t *salt,
|
||||
size_t salt_size,
|
||||
const uint8_t *info,
|
||||
size_t info_size,
|
||||
uint8_t *out,
|
||||
size_t out_size
|
||||
)
|
||||
{
|
||||
return HkdfSha256ExtractAndExpand (
|
||||
key,
|
||||
key_size,
|
||||
salt,
|
||||
salt_size,
|
||||
info,
|
||||
info_size,
|
||||
out,
|
||||
out_size
|
||||
);
|
||||
}
|
||||
|
||||
bool
|
||||
libspdm_hkdf_sha256_extract (
|
||||
const uint8_t *key,
|
||||
size_t key_size,
|
||||
const uint8_t *salt,
|
||||
size_t salt_size,
|
||||
uint8_t *prk_out,
|
||||
size_t prk_out_size
|
||||
)
|
||||
{
|
||||
return HkdfSha256Extract (
|
||||
key,
|
||||
key_size,
|
||||
salt,
|
||||
salt_size,
|
||||
prk_out,
|
||||
prk_out_size
|
||||
);
|
||||
}
|
||||
|
||||
bool
|
||||
libspdm_hkdf_sha256_expand (
|
||||
const uint8_t *prk,
|
||||
size_t prk_size,
|
||||
const uint8_t *info,
|
||||
size_t info_size,
|
||||
uint8_t *out,
|
||||
size_t out_size
|
||||
)
|
||||
{
|
||||
return HkdfSha256Expand (
|
||||
prk,
|
||||
prk_size,
|
||||
info,
|
||||
info_size,
|
||||
out,
|
||||
out_size
|
||||
);
|
||||
}
|
||||
|
||||
bool
|
||||
libspdm_hkdf_sha384_extract_and_expand (
|
||||
const uint8_t *key,
|
||||
size_t key_size,
|
||||
const uint8_t *salt,
|
||||
size_t salt_size,
|
||||
const uint8_t *info,
|
||||
size_t info_size,
|
||||
uint8_t *out,
|
||||
size_t out_size
|
||||
)
|
||||
{
|
||||
return HkdfSha384ExtractAndExpand (
|
||||
key,
|
||||
key_size,
|
||||
salt,
|
||||
salt_size,
|
||||
info,
|
||||
info_size,
|
||||
out,
|
||||
out_size
|
||||
);
|
||||
}
|
||||
|
||||
bool
|
||||
libspdm_hkdf_sha384_extract (
|
||||
const uint8_t *key,
|
||||
size_t key_size,
|
||||
const uint8_t *salt,
|
||||
size_t salt_size,
|
||||
uint8_t *prk_out,
|
||||
size_t prk_out_size
|
||||
)
|
||||
{
|
||||
return HkdfSha384Extract (
|
||||
key,
|
||||
key_size,
|
||||
salt,
|
||||
salt_size,
|
||||
prk_out,
|
||||
prk_out_size
|
||||
);
|
||||
}
|
||||
|
||||
bool
|
||||
libspdm_hkdf_sha384_expand (
|
||||
const uint8_t *prk,
|
||||
size_t prk_size,
|
||||
const uint8_t *info,
|
||||
size_t info_size,
|
||||
uint8_t *out,
|
||||
size_t out_size
|
||||
)
|
||||
{
|
||||
return HkdfSha384Expand (
|
||||
prk,
|
||||
prk_size,
|
||||
info,
|
||||
info_size,
|
||||
out,
|
||||
out_size
|
||||
);
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
## @file
|
||||
# SPDM library.
|
||||
#
|
||||
# Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
|
||||
#
|
||||
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
#
|
||||
##
|
||||
|
||||
[Defines]
|
||||
INF_VERSION = 0x00010005
|
||||
BASE_NAME = CryptlibWrapper
|
||||
FILE_GUID = 156C1B1B-6C2F-496a-496A-0548D1A9ED5B
|
||||
MODULE_TYPE = BASE
|
||||
VERSION_STRING = 1.0
|
||||
LIBRARY_CLASS = CryptlibWrapper
|
||||
|
||||
#
|
||||
# The following information is for reference only and not required by the build tools.
|
||||
#
|
||||
# VALID_ARCHITECTURES = IA32 X64 AARCH64
|
||||
#
|
||||
|
||||
[Sources]
|
||||
CryptlibWrapper.c
|
||||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
SecurityPkg/SecurityPkg.dec
|
||||
CryptoPkg/CryptoPkg.dec
|
||||
|
||||
[LibraryClasses]
|
||||
BaseLib
|
||||
BaseMemoryLib
|
||||
MemoryAllocationLib
|
||||
DebugLib
|
||||
BaseCryptLib
|
||||
RngLib
|
177
SecurityPkg/DeviceSecurity/OsStub/MemLibWrapper/MemLibWrapper.c
Normal file
177
SecurityPkg/DeviceSecurity/OsStub/MemLibWrapper/MemLibWrapper.c
Normal file
@ -0,0 +1,177 @@
|
||||
/** @file
|
||||
EDKII Device Security library for SPDM device.
|
||||
It follows the SPDM Specification.
|
||||
|
||||
Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
**/
|
||||
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
#include "hal/base.h"
|
||||
#include "hal/library/memlib.h"
|
||||
|
||||
/**
|
||||
* Copies bytes from a source buffer to a destination buffer.
|
||||
*
|
||||
* This function copies "src_len" bytes from "src_buf" to "dst_buf".
|
||||
*
|
||||
* Asserts and returns a non-zero value if any of the following are true:
|
||||
* 1) "src_buf" or "dst_buf" are NULL.
|
||||
* 2) "src_len" or "dst_len" is greater than (SIZE_MAX >> 1).
|
||||
* 3) "src_len" is greater than "dst_len".
|
||||
* 4) "src_buf" and "dst_buf" overlap.
|
||||
*
|
||||
* If any of these cases fail, a non-zero value is returned. Additionally if
|
||||
* "dst_buf" points to a non-NULL value and "dst_len" is valid, then "dst_len"
|
||||
* bytes of "dst_buf" are zeroed.
|
||||
*
|
||||
* This function follows the C11 cppreference description of memcpy_s.
|
||||
* https://en.cppreference.com/w/c/string/byte/memcpy
|
||||
* The cppreferece description does NOT allow the source or destination
|
||||
* buffers to be NULL.
|
||||
*
|
||||
* This function differs from the Microsoft and Safeclib memcpy_s implementations
|
||||
* in that the Microsoft and Safeclib implementations allow for NULL source and
|
||||
* destinations pointers when the number of bytes to copy (src_len) is zero.
|
||||
*
|
||||
* In addition the Microsoft and Safeclib memcpy_s functions return different
|
||||
* negative values on error. For best support, clients should generally check
|
||||
* against zero for success or failure.
|
||||
*
|
||||
* @param dst_buf Destination buffer to copy to.
|
||||
* @param dst_len Maximum length in bytes of the destination buffer.
|
||||
* @param src_buf Source buffer to copy from.
|
||||
* @param src_len The number of bytes to copy from the source buffer.
|
||||
*
|
||||
* @return 0 on success. non-zero on error.
|
||||
*
|
||||
**/
|
||||
void
|
||||
libspdm_copy_mem (
|
||||
void *dst_buf,
|
||||
size_t dst_len,
|
||||
const void *src_buf,
|
||||
size_t src_len
|
||||
)
|
||||
{
|
||||
volatile uint8_t *dst;
|
||||
const volatile uint8_t *src;
|
||||
|
||||
dst = (volatile uint8_t *)dst_buf;
|
||||
src = (const volatile uint8_t *)src_buf;
|
||||
|
||||
/* Check for case where "dst" or "dst_len" may be invalid.
|
||||
* Do not zero "dst" in this case. */
|
||||
if ((dst == NULL) || (dst_len > (SIZE_MAX >> 1))) {
|
||||
ASSERT (0);
|
||||
}
|
||||
|
||||
/* Gaurd against invalid source. Zero "dst" in this case. */
|
||||
if (src == NULL) {
|
||||
ZeroMem (dst_buf, dst_len);
|
||||
ASSERT (0);
|
||||
}
|
||||
|
||||
/* Guard against overlap case. Zero "dst" in these cases. */
|
||||
if (((src < dst) && (src + src_len > dst)) || ((dst < src) && (dst + src_len > src))) {
|
||||
ZeroMem (dst_buf, dst_len);
|
||||
ASSERT (0);
|
||||
}
|
||||
|
||||
/* Guard against invalid lengths. Zero "dst" in these cases. */
|
||||
if ((src_len > dst_len) ||
|
||||
(src_len > (SIZE_MAX >> 1)))
|
||||
{
|
||||
ZeroMem (dst_buf, dst_len);
|
||||
ASSERT (0);
|
||||
}
|
||||
|
||||
while (src_len-- != 0) {
|
||||
*(dst++) = *(src++);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fills a target buffer with a byte value, and returns the target buffer.
|
||||
*
|
||||
* This function fills length bytes of buffer with value, and returns buffer.
|
||||
*
|
||||
* If length is greater than (MAX_ADDRESS - buffer + 1), then ASSERT().
|
||||
*
|
||||
* @param buffer The memory to set.
|
||||
* @param length The number of bytes to set.
|
||||
* @param value The value with which to fill length bytes of buffer.
|
||||
*
|
||||
* @return buffer.
|
||||
*
|
||||
**/
|
||||
void
|
||||
libspdm_set_mem (
|
||||
void *buffer,
|
||||
size_t length,
|
||||
uint8_t value
|
||||
)
|
||||
{
|
||||
SetMem (buffer, length, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fills a target buffer with zeros, and returns the target buffer.
|
||||
*
|
||||
* This function fills length bytes of buffer with zeros, and returns buffer.
|
||||
*
|
||||
* If length > 0 and buffer is NULL, then ASSERT().
|
||||
* If length is greater than (MAX_ADDRESS - buffer + 1), then ASSERT().
|
||||
*
|
||||
* @param buffer The pointer to the target buffer to fill with zeros.
|
||||
* @param length The number of bytes in buffer to fill with zeros.
|
||||
*
|
||||
* @return buffer.
|
||||
*
|
||||
**/
|
||||
void
|
||||
libspdm_zero_mem (
|
||||
void *buffer,
|
||||
size_t length
|
||||
)
|
||||
{
|
||||
ZeroMem (buffer, length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares the contents of two buffers in const time.
|
||||
*
|
||||
* This function compares length bytes of source_buffer to length bytes of destination_buffer.
|
||||
* If all length bytes of the two buffers are identical, then 0 is returned. Otherwise, the
|
||||
* value returned is the first mismatched byte in source_buffer subtracted from the first
|
||||
* mismatched byte in destination_buffer.
|
||||
*
|
||||
* If length > 0 and destination_buffer is NULL, then ASSERT().
|
||||
* If length > 0 and source_buffer is NULL, then ASSERT().
|
||||
* If length is greater than (MAX_ADDRESS - destination_buffer + 1), then ASSERT().
|
||||
* If length is greater than (MAX_ADDRESS - source_buffer + 1), then ASSERT().
|
||||
*
|
||||
* @param destination_buffer A pointer to the destination buffer to compare.
|
||||
* @param source_buffer A pointer to the source buffer to compare.
|
||||
* @param length The number of bytes to compare.
|
||||
*
|
||||
* @return 0 All length bytes of the two buffers are identical.
|
||||
* @retval Non-zero There is mismatched between source_buffer and destination_buffer.
|
||||
*
|
||||
**/
|
||||
bool
|
||||
libspdm_consttime_is_mem_equal (
|
||||
const void *destination_buffer,
|
||||
const void *source_buffer,
|
||||
size_t length
|
||||
)
|
||||
{
|
||||
if (CompareMem (destination_buffer, source_buffer, length) == 0) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
## @file
|
||||
# SPDM library.
|
||||
#
|
||||
# Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
|
||||
#
|
||||
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
#
|
||||
##
|
||||
|
||||
[Defines]
|
||||
INF_VERSION = 0x00010005
|
||||
BASE_NAME = MemLibWrapper
|
||||
FILE_GUID = d97bb726-6640-47dc-ae00-0cf2fbfb60f0
|
||||
MODULE_TYPE = BASE
|
||||
VERSION_STRING = 1.0
|
||||
LIBRARY_CLASS = MemLibWrapper
|
||||
|
||||
#
|
||||
# The following information is for reference only and not required by the build tools.
|
||||
#
|
||||
# VALID_ARCHITECTURES = IA32 X64 AARCH64
|
||||
#
|
||||
|
||||
[Sources]
|
||||
MemLibWrapper.c
|
||||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
SecurityPkg/SecurityPkg.dec
|
||||
|
||||
[LibraryClasses]
|
||||
BaseLib
|
||||
DebugLib
|
@ -0,0 +1,85 @@
|
||||
/** @file
|
||||
EDKII Device Security library for SPDM device.
|
||||
It follows the SPDM Specification.
|
||||
|
||||
Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
**/
|
||||
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
#include "hal/base.h"
|
||||
|
||||
/**
|
||||
* Suspends the execution of the current thread until the time-out interval elapses.
|
||||
*
|
||||
* @param milliseconds The time interval for which execution is to be suspended, in milliseconds.
|
||||
*
|
||||
**/
|
||||
void
|
||||
libspdm_sleep (
|
||||
uint64_t milliseconds
|
||||
)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Suspends the execution of the current thread until the time-out interval elapses.
|
||||
*
|
||||
* @param microseconds The time interval for which execution is to be suspended, in milliseconds.
|
||||
*
|
||||
**/
|
||||
void
|
||||
libspdm_sleep_in_us (
|
||||
uint64_t microseconds
|
||||
)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* If no heartbeat arrives in seconds, the watchdog timeout event
|
||||
* should terminate the session.
|
||||
*
|
||||
* @param session_id Indicate the SPDM session ID.
|
||||
* @param seconds heartbeat period, in seconds.
|
||||
*
|
||||
**/
|
||||
bool
|
||||
libspdm_start_watchdog (
|
||||
uint32_t session_id,
|
||||
uint16_t seconds
|
||||
)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* stop watchdog.
|
||||
*
|
||||
* @param session_id Indicate the SPDM session ID.
|
||||
*
|
||||
**/
|
||||
bool
|
||||
libspdm_stop_watchdog (
|
||||
uint32_t session_id
|
||||
)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the watchdog in heartbeat response.
|
||||
*
|
||||
* @param session_id Indicate the SPDM session ID.
|
||||
*
|
||||
**/
|
||||
bool
|
||||
libspdm_reset_watchdog (
|
||||
uint32_t session_id
|
||||
)
|
||||
{
|
||||
return true;
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
## @file
|
||||
# SPDM library.
|
||||
#
|
||||
# Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
|
||||
#
|
||||
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
#
|
||||
##
|
||||
|
||||
[Defines]
|
||||
INF_VERSION = 0x00010005
|
||||
BASE_NAME = PlatformLibWrapper
|
||||
FILE_GUID = 2f8979d1-f9f0-4d51-9cbd-4f41dee59057
|
||||
MODULE_TYPE = BASE
|
||||
VERSION_STRING = 1.0
|
||||
LIBRARY_CLASS = PlatformLibWrapper
|
||||
|
||||
#
|
||||
# The following information is for reference only and not required by the build tools.
|
||||
#
|
||||
# VALID_ARCHITECTURES = IA32 X64 AARCH64
|
||||
#
|
||||
|
||||
[Sources]
|
||||
PlatformLibWrapper.c
|
||||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
SecurityPkg/SecurityPkg.dec
|
||||
|
||||
[LibraryClasses]
|
||||
BaseLib
|
||||
DebugLib
|
347
SecurityPkg/DeviceSecurity/SpdmLib/Include/Stub/SpdmLibStub.h
Normal file
347
SecurityPkg/DeviceSecurity/SpdmLib/Include/Stub/SpdmLibStub.h
Normal file
@ -0,0 +1,347 @@
|
||||
/** @file
|
||||
|
||||
Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
**/
|
||||
|
||||
#ifndef __LIBSPDM_STUB_H__
|
||||
#define __LIBSPDM_STUB_H__
|
||||
|
||||
#include <library/spdm_common_lib.h>
|
||||
#include <library/spdm_return_status.h>
|
||||
#include <library/spdm_crypt_lib.h>
|
||||
#include <library/spdm_requester_lib.h>
|
||||
#include <library/spdm_responder_lib.h>
|
||||
#include <library/spdm_transport_pcidoe_lib.h>
|
||||
|
||||
#pragma pack(1)
|
||||
|
||||
/* The layout of SPDM_RETURN is
|
||||
* [31:28] - Severity
|
||||
* [27:24] - Reserved
|
||||
* [23:16] - Source
|
||||
* [15:00] - Code
|
||||
*/
|
||||
typedef UINT32 SPDM_RETURN;
|
||||
|
||||
/*Interface of spdm.h*/
|
||||
/* SPDM message header*/
|
||||
typedef struct {
|
||||
UINT8 SPDMVersion;
|
||||
UINT8 RequestResponseCode;
|
||||
UINT8 Param1;
|
||||
UINT8 Param2;
|
||||
} SPDM_MESSAGE_HEADER;
|
||||
|
||||
/* SPDM VERSION structure
|
||||
* Bit[15:12] MajorVersion
|
||||
* Bit[11:8] MinorVersion
|
||||
* Bit[7:4] UpdateVersionNumber
|
||||
* Bit[3:0] Alpha*/
|
||||
typedef UINT16 SPDM_VERSION_NUMBER;
|
||||
|
||||
typedef struct {
|
||||
/* Total length of the certificate chain, in bytes,
|
||||
* including all fields in this table.*/
|
||||
|
||||
UINT16 Length;
|
||||
UINT16 Reserved;
|
||||
|
||||
/* digest of the Root Certificate.
|
||||
* Note that Root Certificate is ASN.1 DER-encoded for this digest.
|
||||
* The hash size is determined by the SPDM device.*/
|
||||
|
||||
/*UINT8 RootHash[HashSize];*/
|
||||
|
||||
/* One or more ASN.1 DER-encoded X509v3 certificates where the first certificate is signed by the Root
|
||||
* Certificate or is the Root Certificate itself and each subsequent certificate is signed by the preceding
|
||||
* certificate. The last certificate is the Leaf Certificate.*/
|
||||
|
||||
/*UINT8 Certificates[length - 4 - HashSize];*/
|
||||
} SPDM_CERT_CHAIN;
|
||||
|
||||
/* SPDM MEASUREMENTS block common header */
|
||||
typedef struct {
|
||||
UINT8 Index;
|
||||
UINT8 MeasurementSpecification;
|
||||
UINT16 MeasurementSize;
|
||||
/*UINT8 Measurement[MeasurementSize];*/
|
||||
} SPDM_MEASUREMENT_BLOCK_COMMON_HEADER;
|
||||
|
||||
/* SPDM MEASUREMENTS block DMTF header */
|
||||
typedef struct {
|
||||
UINT8 DMTFSpecMeasurementValueType;
|
||||
UINT16 DMTFSpecMeasurementValueSize;
|
||||
/*UINT8 DMTFSpecMeasurementValue[DMTFSpecMeasurementValueSize];*/
|
||||
} SPDM_MEASUREMENT_BLOCK_DMTF_HEADER;
|
||||
|
||||
typedef struct {
|
||||
SPDM_MEASUREMENT_BLOCK_COMMON_HEADER MeasurementBlockCommonHeader;
|
||||
SPDM_MEASUREMENT_BLOCK_DMTF_HEADER MeasurementBlockDmtfHeader;
|
||||
/*UINT8 HashValue[HashSize];*/
|
||||
} SPDM_MEASUREMENT_BLOCK_DMTF;
|
||||
|
||||
#define SPDM_DATA_PARAMETER libspdm_data_parameter_t
|
||||
|
||||
typedef enum {
|
||||
//
|
||||
// SPDM parameter
|
||||
//
|
||||
SpdmDataSpdmVersion,
|
||||
SpdmDataSecuredMessageVersion,
|
||||
//
|
||||
// SPDM capability
|
||||
//
|
||||
SpdmDataCapabilityFlags,
|
||||
SpdmDataCapabilityCTExponent,
|
||||
SpdmDataCapabilityRttUs,
|
||||
SpdmDataCapabilityDataTransferSize,
|
||||
SpdmDataCapabilityMaxSpdmMsgSize,
|
||||
SpdmDataCapabilitySenderDataTransferSize,
|
||||
|
||||
//
|
||||
// SPDM Algorithm setting
|
||||
//
|
||||
SpdmDataMeasurementSpec,
|
||||
SpdmDataMeasurementHashAlgo,
|
||||
SpdmDataBaseAsymAlgo,
|
||||
SpdmDataBaseHashAlgo,
|
||||
SpdmDataDHENameGroup,
|
||||
SpdmDataAEADCipherSuite,
|
||||
SpdmDataReqBaseAsymAlg,
|
||||
SpdmDataKeySchedule,
|
||||
SpdmDataOtherParamsSupport,
|
||||
SpdmDataMelSpec,
|
||||
|
||||
//
|
||||
// Connection State
|
||||
//
|
||||
SpdmDataConnectionState,
|
||||
//
|
||||
// ResponseState
|
||||
//
|
||||
SpdmDataResponseState,
|
||||
//
|
||||
// Certificate info
|
||||
//
|
||||
SpdmDataLocalPublicCertChain,
|
||||
SpdmDataPeerPublicRootCert,
|
||||
SpdmDataPeerPublicKey,
|
||||
SpdmDataLocalPublicKey,
|
||||
SpdmDataLocalSupportedSlotMask,
|
||||
SpdmDataLocalKeyPairId,
|
||||
SpdmDataLocalCertInfo,
|
||||
SpdmDataLocalKeyUsageBitMask,
|
||||
|
||||
SpdmDataBasicMutAuthRequested,
|
||||
SpdmDataMutAuthRequested,
|
||||
SpdmDataHeartBeatPeriod,
|
||||
//
|
||||
// Negotiated result
|
||||
//
|
||||
SpdmDataPeerUsedCertChainBuffer,
|
||||
SpdmDataPeerSlotMask,
|
||||
SpdmDataPeerProvisionedSlotMask = SpdmDataPeerSlotMask,
|
||||
SpdmDataPeerSupportedSlotMask,
|
||||
SpdmDataPeerTotalDigestBuffer,
|
||||
SpdmDataPeerKeyPairId,
|
||||
SpdmDataPeerCertInfo,
|
||||
SpdmDataPeerKeyUsageBitMask,
|
||||
|
||||
//
|
||||
// Pre-shared Key Hint
|
||||
// If PSK is present, then PSK_EXCHANGE is used.
|
||||
// Otherwise, the KEY_EXCHANGE is used.
|
||||
//
|
||||
SpdmDataPskHint,
|
||||
//
|
||||
// SessionData
|
||||
//
|
||||
SpdmDataSessionUsePsk,
|
||||
SpdmDataSessionMutAuthRequested,
|
||||
SpdmDataSessionEndSessionAttributes,
|
||||
SpdmDataSessionPolicy,
|
||||
|
||||
SpdmDataAppContextData,
|
||||
|
||||
SpdmDataHandleErrorReturnPolicy,
|
||||
|
||||
/* VCA cached for CACHE_CAP in 1.2 for transcript.*/
|
||||
SpdmDataVcaCache,
|
||||
|
||||
/* if the context is for a requester. It only needs to be set in VCA cache.*/
|
||||
SpdmDataIsRequester,
|
||||
|
||||
// If the Responder replies with a Busy `ERROR` response to a request
|
||||
// then the Requester is free to retry sending the request.
|
||||
// This value specifies the maximum number of times libspdm will retry
|
||||
// sending the request before returning an error.
|
||||
// If its value is 0 then libspdm will not send any retry requests.
|
||||
SpdmDataRequestRetryTimes,
|
||||
|
||||
// If the Responder replies with a Busy `ERROR` response to a request
|
||||
// then the Requester is free to retry sending the request.
|
||||
// This value specifies the delay time in microseconds between each retry requests.
|
||||
// If its value is 0 then libspdm will send retry request immediately.
|
||||
SpdmDataRequestRetryDelayTime,
|
||||
|
||||
/* limit the number of DHE session and PSK session separately.*/
|
||||
SpdmDataMaxDheSessionConut,
|
||||
SpdmDataMaxPskSessionConut,
|
||||
|
||||
SpdmDataSessionSequenceNumberRspDir,
|
||||
SpdmDataSessionSequenceNumberReqDir,
|
||||
SpdmDataMaxSessionSequenceNumber,
|
||||
|
||||
/* For SPDM 1.0 and 1.1, allow signature verification in big, little, or both endians. */
|
||||
SpdmDataSpdmVersion1011VerifySigatureEndian,
|
||||
|
||||
SpdmDataSequenceNumberEndian,
|
||||
SpdmDataSessionSequenceNumberEndian,
|
||||
|
||||
SpdmDataMultiKeyConnReq,
|
||||
SpdmDataMultiKeyConnRsp,
|
||||
//
|
||||
// MAX
|
||||
//
|
||||
SpdmDataMax,
|
||||
} SPDM_DATA_TYPE;
|
||||
|
||||
typedef enum {
|
||||
SpdmDataLocationLocal,
|
||||
SpdmDataLocationConnection,
|
||||
SpdmDataLocationSession,
|
||||
SpdmDataLocationMax,
|
||||
} SPDM_DATA_LOCATION;
|
||||
|
||||
typedef enum {
|
||||
//
|
||||
// Before GET_VERSION/VERSION
|
||||
//
|
||||
SpdmConnectionStateNotStarted,
|
||||
//
|
||||
// After GET_VERSION/VERSION
|
||||
//
|
||||
SpdmConnectionStateAfterVersion,
|
||||
//
|
||||
// After GET_CAPABILITIES/CAPABILITIES
|
||||
//
|
||||
SpdmConnectionStateAfterCapabilities,
|
||||
//
|
||||
// After NEGOTIATE_ALGORITHMS/ALGORITHMS
|
||||
//
|
||||
SpdmConnectionStateNegotiated,
|
||||
//
|
||||
// After GET_DIGESTS/DIGESTS
|
||||
//
|
||||
SpdmConnectionStateAfterDigests,
|
||||
//
|
||||
// After GET_CERTIFICATE/CERTIFICATE
|
||||
//
|
||||
SpdmConnectionStateAfterCertificate,
|
||||
//
|
||||
// After CHALLENGE/CHALLENGE_AUTH, and ENCAP CALLENGE/CHALLENG_AUTH if MUT_AUTH is enabled.
|
||||
//
|
||||
SpdmConnectionStateAuthenticated,
|
||||
//
|
||||
// MAX
|
||||
//
|
||||
SpdmConnectionStateMax,
|
||||
} SPDM_CONNECTION_STATE;
|
||||
|
||||
typedef enum {
|
||||
//
|
||||
// Normal response.
|
||||
//
|
||||
SpdmResponseStateNormal,
|
||||
//
|
||||
// Other component is busy.
|
||||
//
|
||||
SpdmResponseStateBusy,
|
||||
#if LIBSPDM_RESPOND_IF_READY_SUPPORT
|
||||
//
|
||||
// Hardware is not ready.
|
||||
//
|
||||
SpdmResponseStateNotReady,
|
||||
#endif /* LIBSPDM_RESPOND_IF_READY_SUPPORT */
|
||||
//
|
||||
// Firmware Update is done. Need resync.
|
||||
//
|
||||
SpdmResponseStateNeedResync,
|
||||
//
|
||||
// Processing Encapsulated message.
|
||||
//
|
||||
SpdmResponseStateProcessingEncap,
|
||||
//
|
||||
// MAX
|
||||
//
|
||||
SpdmResponseStateMax,
|
||||
} SPDM_RESPONSE_STATE;
|
||||
|
||||
/* DOE header*/
|
||||
|
||||
typedef struct {
|
||||
UINT16 VendorId;
|
||||
UINT8 DataObjectType;
|
||||
UINT8 Reserved;
|
||||
|
||||
/* length of the data object being transfered in number of DW, including the header (2 DW)
|
||||
* It only includes bit[0~17], bit[18~31] are reserved.
|
||||
* A value of 00000h indicate 2^18 DW == 2^20 byte.*/
|
||||
UINT32 Length;
|
||||
/*UINT32 DataObjectDw[Length];*/
|
||||
} PCI_DOE_DATA_OBJECT_HEADER;
|
||||
|
||||
#pragma pack()
|
||||
|
||||
/* FUNCTION */
|
||||
#define SpdmSetData libspdm_set_data
|
||||
#define SpdmGetData libspdm_get_data
|
||||
#define SpdmInitContext libspdm_init_context
|
||||
#define SpdmGetContextSize libspdm_get_context_size
|
||||
#define SpdmRegisterDeviceIoFunc libspdm_register_device_io_func
|
||||
#define SpdmRegisterTransportLayerFunc libspdm_register_transport_layer_func
|
||||
#define SpdmGetSizeofRequiredScratchBuffer libspdm_get_sizeof_required_scratch_buffer
|
||||
#define SpdmRegisterDeviceBufferFunc libspdm_register_device_buffer_func
|
||||
#define SpdmSetScratchBuffer libspdm_set_scratch_buffer
|
||||
|
||||
#define SpdmGetHashSize libspdm_get_hash_size
|
||||
#define SpdmHashAll libspdm_hash_all
|
||||
#define SpdmGetMeasurementHashSize libspdm_get_measurement_hash_size
|
||||
#define SpdmMeasurementHashAll libspdm_measurement_hash_all
|
||||
#define SpdmHmacAll libspdm_hmac_all
|
||||
#define SpdmHkdfExpand libspdm_hkdf_expand
|
||||
#define SpdmAsymFree libspdm_asym_free
|
||||
#define SpdmAsymGetPrivateKeyFromPem libspdm_asym_get_private_key_from_pem
|
||||
#define SpdmAsymSign libspdm_asym_sign
|
||||
#define SpdmAsymSignHash libspdm_asym_sign_hash
|
||||
|
||||
#define SpdmInitConnection libspdm_init_connection
|
||||
#define SpdmGetDigest libspdm_get_digest
|
||||
#define SpdmGetCertificate libspdm_get_certificate
|
||||
#define SpdmGetCertificateEx libspdm_get_certificate_ex
|
||||
#define SpdmChallenge libspdm_challenge
|
||||
#define SpdmChallengeEx libspdm_challenge_ex
|
||||
#define SpdmGetMeasurement libspdm_get_measurement
|
||||
#define SpdmGetMeasurementEx libspdm_get_measurement_ex
|
||||
#define SpdmStartSession libspdm_start_session
|
||||
#define SpdmStopSession libspdm_stop_session
|
||||
#define SpdmSendReceiveData libspdm_send_receive_data
|
||||
#define SpdmRegisterGetResponseFunc libspdm_register_get_response_func
|
||||
#define SpdmProcessRequest libspdm_process_request
|
||||
#define SpdmBuildResponse libspdm_build_response
|
||||
#define SpdmGenerateErrorResponse libspdm_generate_error_response
|
||||
#define SpdmTransportPciDoeEncodeMessage libspdm_transport_pci_doe_encode_message
|
||||
#define SpdmTransportPciDoeDecodeMessage libspdm_transport_pci_doe_decode_message
|
||||
|
||||
#define SpdmMeasurementCollectionFunc libspdm_measurement_collection
|
||||
#define SpdmRequesterDataSignFunc libspdm_requester_data_sign
|
||||
#define SpdmResponderDataSignFunc libspdm_responder_data_sign
|
||||
#define SpdmGenerateMeasurementSummaryHash libspdm_generate_measurement_summary_hash
|
||||
#define SpdmPskMasterSecretHkdfExpandFunc libspdm_psk_master_secret_hkdf_expand
|
||||
#define SpdmPskHandshakeSecretHkdfExpandFunc libspdm_psk_handshake_secret_hkdf_expand
|
||||
#define SpdmMeasurementOpaqueData libspdm_measurement_opaque_data
|
||||
#define SpdmChallengeOpaqueData libspdm_challenge_opaque_data
|
||||
|
||||
#endif
|
@ -0,0 +1,23 @@
|
||||
/** @file
|
||||
EDKII Device Security library for SPDM device.
|
||||
It follows the SPDM Specification.
|
||||
|
||||
Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
**/
|
||||
|
||||
#ifndef LIBSPDM_STDBOOL_ALT_H
|
||||
#define LIBSPDM_STDBOOL_ALT_H
|
||||
|
||||
typedef BOOLEAN bool;
|
||||
|
||||
#ifndef true
|
||||
#define true TRUE
|
||||
#endif
|
||||
|
||||
#ifndef false
|
||||
#define false FALSE
|
||||
#endif
|
||||
|
||||
#endif /* LIBSPDM_STDBOOL_ALT */
|
@ -0,0 +1,16 @@
|
||||
/** @file
|
||||
EDKII Device Security library for SPDM device.
|
||||
It follows the SPDM Specification.
|
||||
|
||||
Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
**/
|
||||
|
||||
#ifndef LIBSPDM_STD_DEF_ALT_H
|
||||
#define LIBSPDM_STD_DEF_ALT_H
|
||||
|
||||
typedef UINTN size_t;
|
||||
#define offsetof(type, member) OFFSET_OF(type,member)
|
||||
|
||||
#endif /* LIBSPDM_STDDEF_ALT */
|
@ -0,0 +1,25 @@
|
||||
/** @file
|
||||
EDKII Device Security library for SPDM device.
|
||||
It follows the SPDM Specification.
|
||||
|
||||
Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
**/
|
||||
|
||||
#ifndef LIBSPDM_STD_INT_ALT_H
|
||||
#define LIBSPDM_STD_INT_ALT_H
|
||||
|
||||
typedef UINT64 uint64_t;
|
||||
typedef INT64 int64_t;
|
||||
typedef UINT32 uint32_t;
|
||||
typedef INT32 int32_t;
|
||||
typedef UINT16 uint16_t;
|
||||
typedef INT16 int16_t;
|
||||
typedef UINT8 uint8_t;
|
||||
|
||||
#ifndef SIZE_MAX
|
||||
#define SIZE_MAX MAX_UINTN
|
||||
#endif
|
||||
|
||||
#endif /* LIBSPDM_STDINT_ALT */
|
94
SecurityPkg/DeviceSecurity/SpdmLib/Include/hal/base.h
Normal file
94
SecurityPkg/DeviceSecurity/SpdmLib/Include/hal/base.h
Normal file
@ -0,0 +1,94 @@
|
||||
/** @file
|
||||
EDKII Device Security library for SPDM device.
|
||||
It follows the SPDM Specification.
|
||||
|
||||
Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
**/
|
||||
|
||||
#ifndef BASE_H
|
||||
#define BASE_H
|
||||
|
||||
#define LIBSPDM_STDINT_ALT "hal/LibspdmStdIntAlt.h"
|
||||
#define LIBSPDM_STDBOOL_ALT "hal/LibspdmStdBoolAlt.h"
|
||||
#define LIBSPDM_STDDEF_ALT "hal/LibspdmStdDefAlt.h"
|
||||
|
||||
#ifndef LIBSPDM_STDINT_ALT
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/* LIBSPDM_OPENSSL_STDINT_WORKAROUND */
|
||||
|
||||
/* This is a workaround for OpenSSL compilation problems when used with <stdint.h>
|
||||
* on Windows platforms built with Visual Studio. Including <stdint.h> pulls in
|
||||
* <vcruntime.h>, which causes the type size_t to be defined. The size_t type
|
||||
* depends on if _WIN32 or _WIN64 is defined. The default if neither is defined
|
||||
* is the 32-bit version of size_t. */
|
||||
|
||||
/* Our OpenSSL compilation requires _WIN32 and _WIN64 to NOT be defined.
|
||||
* This will force the <vcruntime.h> to use the wrong 32-bit definition of size_t
|
||||
* if we are compiling as 64-bit. This 32-bit definition then does not agree with
|
||||
* the 64-bit definition defined in libspdm and generates compile errors. */
|
||||
|
||||
/* To workaround this issue, LIBSPDM_OPENSSL_STDINT_WORKAROUND was created
|
||||
* that is only defined for compilation via tha makefile of the OpenSSL library
|
||||
* portion of libspdm. */
|
||||
|
||||
/* This will lead to _WIN32 and _WIN64 to be NOT defined when reaching the OpenSSL
|
||||
* portions of a compilation unit (header files + c file), thus meeting the
|
||||
* no Win32/Win64 requirement for OpenSSL, but will still be defined when compiling
|
||||
* the <vcruntime.h> file in the compilation unit (and getting the right size_t). */
|
||||
|
||||
/* In the future libspdm intends to use the Windows native compilation flags and defines,
|
||||
* in place of the UEFI profile / personality. */
|
||||
|
||||
#ifdef LIBSPDM_OPENSSL_STDINT_WORKAROUND
|
||||
#undef _WIN32
|
||||
#undef _WIN64
|
||||
#endif
|
||||
|
||||
#else /* LIBSPDM_STDINT_ALT */
|
||||
#include LIBSPDM_STDINT_ALT
|
||||
#endif /* LIBSPDM_STDINT_ALT */
|
||||
|
||||
#ifndef LIBSPDM_STDBOOL_ALT
|
||||
#include <stdbool.h>
|
||||
#else
|
||||
#include LIBSPDM_STDBOOL_ALT
|
||||
#endif
|
||||
|
||||
#ifndef LIBSPDM_STDDEF_ALT
|
||||
#include <stddef.h>
|
||||
#else
|
||||
#include LIBSPDM_STDDEF_ALT
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Return the minimum of two operands.
|
||||
*
|
||||
* This macro returns the minimal of two operand specified by a and b.
|
||||
* Both a and b must be the same numerical types, signed or unsigned.
|
||||
*
|
||||
* @param a The first operand with any numerical type.
|
||||
* @param b The second operand. It should be the same any numerical type with a.
|
||||
*
|
||||
* @return Minimum of two operands.
|
||||
*
|
||||
**/
|
||||
#define LIBSPDM_MIN(a, b) (((a) < (b)) ? (a) : (b))
|
||||
|
||||
/**
|
||||
* Return the number of elements in an array.
|
||||
*
|
||||
* @param array An object of array type. Array is only used as an argument to
|
||||
* the sizeof operator, therefore Array is never evaluated. The
|
||||
* caller is responsible for ensuring that Array's type is not
|
||||
* incomplete; that is, Array must have known constant size.
|
||||
*
|
||||
* @return The number of elements in Array. The result has type size_t.
|
||||
*
|
||||
**/
|
||||
#define LIBSPDM_ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0]))
|
||||
|
||||
#endif /* BASE_H */
|
@ -0,0 +1,39 @@
|
||||
/** @file
|
||||
EDKII Device Security library for SPDM device.
|
||||
It follows the SPDM Specification.
|
||||
|
||||
Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
**/
|
||||
|
||||
/** @file
|
||||
Provides services to print debug and assert messages to a debug output device.
|
||||
|
||||
The Debug library supports debug print and asserts based on a combination of macros and code.
|
||||
The debug library can be turned on and off so that the debug code does not increase the size of an image.
|
||||
|
||||
Note that a reserved macro named MDEPKG_NDEBUG is introduced for the intention
|
||||
of size reduction when compiler optimization is disabled. If MDEPKG_NDEBUG is
|
||||
defined, then debug and assert related macros wrapped by it are the NULL implementations.
|
||||
**/
|
||||
|
||||
#ifndef DEBUG_LIB_H
|
||||
#define DEBUG_LIB_H
|
||||
|
||||
#include <Library/DebugLib.h>
|
||||
|
||||
#define LIBSPDM_DEBUG_INFO DEBUG_INFO
|
||||
#define LIBSPDM_DEBUG_VERBOSE DEBUG_VERBOSE
|
||||
#define LIBSPDM_DEBUG_ERROR DEBUG_ERROR
|
||||
|
||||
#define LIBSPDM_DEBUG DEBUG
|
||||
#define LIBSPDM_ASSERT ASSERT
|
||||
#define LIBSPDM_ASSERT_RETURN_ERROR ASSERT_RETURN_ERROR
|
||||
|
||||
#define LIBSPDM_DEBUG_CODE_BEGIN DEBUG_CODE_BEGIN
|
||||
#define LIBSPDM_DEBUG_CODE_END DEBUG_CODE_END
|
||||
|
||||
#define LIBSPDM_DEBUG_CODE DEBUG_CODE
|
||||
|
||||
#endif /* DEBUG_LIB_H */
|
@ -0,0 +1,394 @@
|
||||
/** @file
|
||||
EDKII Device Security library for SPDM device.
|
||||
It follows the SPDM Specification.
|
||||
|
||||
Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
**/
|
||||
|
||||
#ifndef SPDM_LIB_CONFIG_H
|
||||
#define SPDM_LIB_CONFIG_H
|
||||
|
||||
/* Enables assertions and debug printing. When `LIBSPDM_DEBUG_ENABLE` is defined it overrides or
|
||||
* sets the values of `LIBSPDM_DEBUG_PRINT_ENABLE`, `LIBSPDM_DEBUG_ASSERT_ENABLE`, and
|
||||
* `LIBSPDM_BLOCK_ENABLE` to the value of `LIBSPDM_DEBUG_ENABLE`.
|
||||
*
|
||||
* Note that if this file is used with CMake and `DTARGET=Release` is defined, then all debugging
|
||||
* is disabled.
|
||||
*/
|
||||
#ifndef LIBSPDM_DEBUG_ENABLE
|
||||
#define LIBSPDM_DEBUG_ENABLE 1
|
||||
#endif
|
||||
|
||||
/* The SPDM specification allows a Responder to return up to 256 version entries in the `VERSION`
|
||||
* response to the Requester, including duplicate entries. For a Requester this value specifies the
|
||||
* maximum number of entries that libspdm will tolerate in a `VERSION` response before returning an
|
||||
* error. A similiar macro, `SPDM_MAX_VERSION_COUNT`, exists for the Responder. However this macro
|
||||
* is not meant to be configured by the integrator.
|
||||
*/
|
||||
#ifndef LIBSPDM_MAX_VERSION_COUNT
|
||||
#define LIBSPDM_MAX_VERSION_COUNT 5
|
||||
#endif
|
||||
|
||||
/* This value specifies the maximum size, in bytes, of the `PSK_EXCHANGE.RequesterContext` and,
|
||||
* if supported by the Responder, `PSK_EXCHANGE_RSP.ResponderContext` fields. The fields are
|
||||
* typically random or monotonically increasing numbers.
|
||||
*/
|
||||
#ifndef LIBSPDM_PSK_CONTEXT_LENGTH
|
||||
#define LIBSPDM_PSK_CONTEXT_LENGTH LIBSPDM_MAX_HASH_SIZE
|
||||
#endif
|
||||
/* This value specifies the maximum size, in bytes, of the `PSK_EXCHANGE.PSKHint` field.*/
|
||||
#ifndef LIBSPDM_PSK_MAX_HINT_LENGTH
|
||||
#define LIBSPDM_PSK_MAX_HINT_LENGTH 16
|
||||
#endif
|
||||
|
||||
/* libspdm allows an integrator to specify multiple root certificates as trust anchors when
|
||||
* verifying certificate chains from an endpoint. This value specifies the maximum number of root
|
||||
* certificates that libspdm can support.
|
||||
*/
|
||||
#ifndef LIBSPDM_MAX_ROOT_CERT_SUPPORT
|
||||
#define LIBSPDM_MAX_ROOT_CERT_SUPPORT 10
|
||||
#endif
|
||||
|
||||
/* If the Responder supports it a Requester is allowed to establish multiple secure sessions with
|
||||
* the Responder. This value specifies the maximum number of sessions libspdm can support.
|
||||
*/
|
||||
#ifndef LIBSPDM_MAX_SESSION_COUNT
|
||||
#define LIBSPDM_MAX_SESSION_COUNT 4
|
||||
#endif
|
||||
|
||||
/* This value specifies the maximum size, in bytes, of a certificate chain that can be stored in a
|
||||
* libspdm context.
|
||||
*/
|
||||
#ifndef LIBSPDM_MAX_CERT_CHAIN_SIZE
|
||||
#define LIBSPDM_MAX_CERT_CHAIN_SIZE 0x1000
|
||||
#endif
|
||||
#ifndef LIBSPDM_MAX_MEASUREMENT_RECORD_SIZE
|
||||
#define LIBSPDM_MAX_MEASUREMENT_RECORD_SIZE 0x1000
|
||||
#endif
|
||||
|
||||
/* Partial certificates can be retrieved from a Requester or Responder and through multiple messages
|
||||
* the complete certificate chain can be constructed. This value specifies the maximum size,
|
||||
* in bytes, of a partial certificate that can be sent or received.
|
||||
*/
|
||||
#ifndef LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN
|
||||
#define LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN 1024
|
||||
#endif
|
||||
|
||||
/* To ensure integrity in communication between the Requester and the Responder libspdm calculates
|
||||
* cryptographic digests and signatures over multiple requests and responses. This value specifies
|
||||
* whether libspdm will use a running calculation over the transcript, where requests and responses
|
||||
* are discarded as they are cryptographically consumed, or whether libspdm will buffer the entire
|
||||
* transcript before calculating the digest or signature.
|
||||
*/
|
||||
#ifndef LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
|
||||
#define LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT 0
|
||||
#endif
|
||||
|
||||
/* Cryptography Configuration
|
||||
* In each category, at least one should be selected.
|
||||
* NOTE: Not all combination can be supported. E.g. Don't mix NIST algo with SMx.*/
|
||||
|
||||
#ifndef LIBSPDM_RSA_SSA_2048_SUPPORT
|
||||
#define LIBSPDM_RSA_SSA_2048_SUPPORT 1
|
||||
#endif
|
||||
#ifndef LIBSPDM_RSA_SSA_3072_SUPPORT
|
||||
#define LIBSPDM_RSA_SSA_3072_SUPPORT 1
|
||||
#endif
|
||||
#ifndef LIBSPDM_RSA_SSA_4096_SUPPORT
|
||||
#define LIBSPDM_RSA_SSA_4096_SUPPORT 1
|
||||
#endif
|
||||
|
||||
#ifndef LIBSPDM_RSA_PSS_2048_SUPPORT
|
||||
#define LIBSPDM_RSA_PSS_2048_SUPPORT 0
|
||||
#endif
|
||||
#ifndef LIBSPDM_RSA_PSS_3072_SUPPORT
|
||||
#define LIBSPDM_RSA_PSS_3072_SUPPORT 0
|
||||
#endif
|
||||
#ifndef LIBSPDM_RSA_PSS_4096_SUPPORT
|
||||
#define LIBSPDM_RSA_PSS_4096_SUPPORT 0
|
||||
#endif
|
||||
|
||||
#ifndef LIBSPDM_ECDSA_P256_SUPPORT
|
||||
#define LIBSPDM_ECDSA_P256_SUPPORT 1
|
||||
#endif
|
||||
#ifndef LIBSPDM_ECDSA_P384_SUPPORT
|
||||
#define LIBSPDM_ECDSA_P384_SUPPORT 1
|
||||
#endif
|
||||
#ifndef LIBSPDM_ECDSA_P521_SUPPORT
|
||||
#define LIBSPDM_ECDSA_P521_SUPPORT 1
|
||||
#endif
|
||||
|
||||
#ifndef LIBSPDM_SM2_DSA_P256_SUPPORT
|
||||
#define LIBSPDM_SM2_DSA_P256_SUPPORT 0
|
||||
#endif
|
||||
|
||||
#ifndef LIBSPDM_EDDSA_ED25519_SUPPORT
|
||||
#define LIBSPDM_EDDSA_ED25519_SUPPORT 0
|
||||
#endif
|
||||
#ifndef LIBSPDM_EDDSA_ED448_SUPPORT
|
||||
#define LIBSPDM_EDDSA_ED448_SUPPORT 0
|
||||
#endif
|
||||
|
||||
#ifndef LIBSPDM_FFDHE_2048_SUPPORT
|
||||
#define LIBSPDM_FFDHE_2048_SUPPORT 0
|
||||
#endif
|
||||
#ifndef LIBSPDM_FFDHE_3072_SUPPORT
|
||||
#define LIBSPDM_FFDHE_3072_SUPPORT 0
|
||||
#endif
|
||||
#ifndef LIBSPDM_FFDHE_4096_SUPPORT
|
||||
#define LIBSPDM_FFDHE_4096_SUPPORT 0
|
||||
#endif
|
||||
|
||||
#ifndef LIBSPDM_ECDHE_P256_SUPPORT
|
||||
#define LIBSPDM_ECDHE_P256_SUPPORT 1
|
||||
#endif
|
||||
#ifndef LIBSPDM_ECDHE_P384_SUPPORT
|
||||
#define LIBSPDM_ECDHE_P384_SUPPORT 1
|
||||
#endif
|
||||
#ifndef LIBSPDM_ECDHE_P521_SUPPORT
|
||||
#define LIBSPDM_ECDHE_P521_SUPPORT 1
|
||||
#endif
|
||||
|
||||
#ifndef LIBSPDM_SM2_KEY_EXCHANGE_P256_SUPPORT
|
||||
#define LIBSPDM_SM2_KEY_EXCHANGE_P256_SUPPORT 0
|
||||
#endif
|
||||
|
||||
#ifndef LIBSPDM_AEAD_AES_128_GCM_SUPPORT
|
||||
#define LIBSPDM_AEAD_AES_128_GCM_SUPPORT 1
|
||||
#endif
|
||||
#ifndef LIBSPDM_AEAD_AES_256_GCM_SUPPORT
|
||||
#define LIBSPDM_AEAD_AES_256_GCM_SUPPORT 1
|
||||
#endif
|
||||
|
||||
#ifndef LIBSPDM_AEAD_CHACHA20_POLY1305_SUPPORT
|
||||
#define LIBSPDM_AEAD_CHACHA20_POLY1305_SUPPORT 0
|
||||
#endif
|
||||
|
||||
#ifndef LIBSPDM_AEAD_SM4_128_GCM_SUPPORT
|
||||
#define LIBSPDM_AEAD_SM4_128_GCM_SUPPORT 0
|
||||
#endif
|
||||
|
||||
#ifndef LIBSPDM_SHA256_SUPPORT
|
||||
#define LIBSPDM_SHA256_SUPPORT 1
|
||||
#endif
|
||||
#ifndef LIBSPDM_SHA384_SUPPORT
|
||||
#define LIBSPDM_SHA384_SUPPORT 1
|
||||
#endif
|
||||
#ifndef LIBSPDM_SHA512_SUPPORT
|
||||
#define LIBSPDM_SHA512_SUPPORT 0
|
||||
#endif
|
||||
|
||||
#ifndef LIBSPDM_SHA3_256_SUPPORT
|
||||
#define LIBSPDM_SHA3_256_SUPPORT 0
|
||||
#endif
|
||||
#ifndef LIBSPDM_SHA3_384_SUPPORT
|
||||
#define LIBSPDM_SHA3_384_SUPPORT 0
|
||||
#endif
|
||||
#ifndef LIBSPDM_SHA3_512_SUPPORT
|
||||
#define LIBSPDM_SHA3_512_SUPPORT 0
|
||||
#endif
|
||||
|
||||
#ifndef LIBSPDM_SM3_256_SUPPORT
|
||||
#define LIBSPDM_SM3_256_SUPPORT 0
|
||||
#endif
|
||||
|
||||
/* This can be set to 0 for the device which does not need X509 parser.*/
|
||||
#ifndef LIBSPDM_CERT_PARSE_SUPPORT
|
||||
#define LIBSPDM_CERT_PARSE_SUPPORT 1
|
||||
#endif
|
||||
|
||||
/* Code space optimization for Optional request/response messages.*/
|
||||
|
||||
/* Consumers of libspdm may wish to not fully implement all of the optional
|
||||
* SPDM request/response messages. Therefore we have provided these
|
||||
* SPDM_ENABLE_CAPABILITY_***_CAP compile time switches as an optimization
|
||||
* disable the code (#if 0) related to said optional capability, thereby
|
||||
* reducing the code space used in the image.*/
|
||||
|
||||
/* A single switch may enable/disable a single capability or group of related
|
||||
* capabilities.*/
|
||||
|
||||
/* LIBSPDM_ENABLE_CAPABILITY_CERT_CAP - Enable/Disable single CERT capability.
|
||||
* LIBSPDM_ENABLE_CAPABILITY_CHAL_CAP - Enable/Disable single CHAL capability.
|
||||
* LIBSPDM_ENABLE_CAPABILITY_MEAS_CAP - Enable/Disables multiple MEAS capabilities:
|
||||
* (MEAS_CAP_NO_SIG, MEAS_CAP_SIG, MEAS_FRESH_CAP)*/
|
||||
|
||||
/* LIBSPDM_ENABLE_CAPABILITY_KEY_EX_CAP - Enable/Disable single Key Exchange capability.
|
||||
* LIBSPDM_ENABLE_CAPABILITY_PSK_EX_CAP - Enable/Disable PSK_EX and PSK_FINISH.*/
|
||||
|
||||
/* LIBSPDM_ENABLE_CAPABILITY_MUT_AUTH_CAP - Enable/Disable mutual authentication.
|
||||
* LIBSPDM_ENABLE_CAPABILITY_ENCAP_CAP - Enable/Disable encapsulated message.*/
|
||||
|
||||
/* LIBSPDM_ENABLE_CAPABILITY_CSR_CAP - Enable/Disable get csr capability.
|
||||
* LIBSPDM_ENABLE_CAPABILITY_SET_CERT_CAP - Enable/Disable set certificate capability. */
|
||||
|
||||
#ifndef LIBSPDM_ENABLE_CAPABILITY_CERT_CAP
|
||||
#define LIBSPDM_ENABLE_CAPABILITY_CERT_CAP 1
|
||||
#endif
|
||||
#ifndef LIBSPDM_ENABLE_CAPABILITY_CHAL_CAP
|
||||
#define LIBSPDM_ENABLE_CAPABILITY_CHAL_CAP 1
|
||||
#endif
|
||||
#ifndef LIBSPDM_ENABLE_CAPABILITY_MEAS_CAP
|
||||
#define LIBSPDM_ENABLE_CAPABILITY_MEAS_CAP 1
|
||||
#endif
|
||||
|
||||
#ifndef LIBSPDM_ENABLE_CAPABILITY_KEY_EX_CAP
|
||||
#define LIBSPDM_ENABLE_CAPABILITY_KEY_EX_CAP 0
|
||||
#endif
|
||||
#ifndef LIBSPDM_ENABLE_CAPABILITY_PSK_EX_CAP
|
||||
#define LIBSPDM_ENABLE_CAPABILITY_PSK_EX_CAP 0
|
||||
#endif
|
||||
|
||||
#ifndef LIBSPDM_ENABLE_CAPABILITY_HBEAT_CAP
|
||||
#define LIBSPDM_ENABLE_CAPABILITY_HBEAT_CAP 0
|
||||
#endif
|
||||
|
||||
#ifndef LIBSPDM_ENABLE_CAPABILITY_MUT_AUTH_CAP
|
||||
#define LIBSPDM_ENABLE_CAPABILITY_MUT_AUTH_CAP 0
|
||||
#endif
|
||||
|
||||
#ifndef LIBSPDM_ENABLE_CAPABILITY_ENCAP_CAP
|
||||
#define LIBSPDM_ENABLE_CAPABILITY_ENCAP_CAP 0
|
||||
#endif
|
||||
|
||||
#ifndef LIBSPDM_ENABLE_CAPABILITY_CSR_CAP
|
||||
#define LIBSPDM_ENABLE_CAPABILITY_CSR_CAP 0
|
||||
#endif
|
||||
|
||||
#ifndef LIBSPDM_ENABLE_CAPABILITY_SET_CERT_CAP
|
||||
#define LIBSPDM_ENABLE_CAPABILITY_SET_CERT_CAP 0
|
||||
#endif
|
||||
|
||||
#ifndef LIBSPDM_ENABLE_CAPABILITY_CHUNK_CAP
|
||||
#define LIBSPDM_ENABLE_CAPABILITY_CHUNK_CAP 0
|
||||
#endif
|
||||
|
||||
/* If 1 then endpoint supports sending GET_CERTIFICATE and GET_DIGESTS requests.
|
||||
* If enabled and endpoint is a Responder then LIBSPDM_ENABLE_CAPABILITY_ENCAP_CAP
|
||||
* must also be enabled.
|
||||
*/
|
||||
#ifndef LIBSPDM_SEND_GET_CERTIFICATE_SUPPORT
|
||||
#define LIBSPDM_SEND_GET_CERTIFICATE_SUPPORT 1
|
||||
#endif
|
||||
|
||||
/* If 1 then endpoint supports sending CHALLENGE request.
|
||||
* If enabled and endpoint is a Responder then LIBSPDM_ENABLE_CAPABILITY_ENCAP_CAP
|
||||
* must also be enabled.
|
||||
*/
|
||||
#ifndef LIBSPDM_SEND_CHALLENGE_SUPPORT
|
||||
#define LIBSPDM_SEND_CHALLENGE_SUPPORT 1
|
||||
#endif
|
||||
|
||||
/* When LIBSPDM_RESPOND_IF_READY_SUPPORT is 0 then
|
||||
* - For a Requester, if the Responder sends a ResponseNotReady ERROR response then the error
|
||||
* is immediately returned to the Integrator. The Requester cannot send a RESPOND_IF_READY
|
||||
* request.
|
||||
* - For a Responder, it cannot send a RESPOND_IF_READY ERROR response and does not support
|
||||
* RESPOND_IF_READY.
|
||||
* When LIBSPDM_RESPOND_IF_READY_SUPPORT is 1 then
|
||||
* - For a Requester, if the Responder sends a ResponseNotReady ERROR response then libspdm
|
||||
* waits an amount of time, as specified by the RDTExponent parameter, before sending
|
||||
* RESPOND_IF_READY.
|
||||
* - For a Responder, if its response state is NOT_READY then it will send a ResponseNotReady
|
||||
* ERROR response to the Requester, and will accept a subsequent RESPOND_IF_READY request.
|
||||
*/
|
||||
#ifndef LIBSPDM_RESPOND_IF_READY_SUPPORT
|
||||
#define LIBSPDM_RESPOND_IF_READY_SUPPORT 1
|
||||
#endif
|
||||
|
||||
/*
|
||||
* MinDataTransferSize = 42
|
||||
*
|
||||
* H = HashLen = HmacLen = [32, 64]
|
||||
* S = SigLen = [64, 512]
|
||||
* D = ExchangeDataLen = [64, 512]
|
||||
* R = RequesterContextLen >= 32
|
||||
* R = ResponderContextLen >= 0
|
||||
* O = OpaqueDataLen <= 1024
|
||||
*
|
||||
* Max Chunk No = 1, if (message size <= 42)
|
||||
* Max Chunk No = [(message size + 4) / 30] roundup, if (message size > 42)
|
||||
*
|
||||
* +==========================+==========================================+=========+
|
||||
* | Command | Size |MaxChunk |
|
||||
* +==========================+==========================================+=========+
|
||||
* | GET_VERSION | 4 | 1 |
|
||||
* | VERSION {1.0, 1.1, 1.2} | 6 + 2 * 3 = 12 | 1 |
|
||||
* +--------------------------+------------------------------------------+---------+
|
||||
* | GET_CAPABILITIES 1.2 | 20 | 1 |
|
||||
* | CAPABILITIES 1.2 | 20 | 1 |
|
||||
* +--------------------------+------------------------------------------+---------+
|
||||
* | ERROR | 4 | 1 |
|
||||
* | ERROR(ResponseTooLarge) | 4 + 4 = 8 | 1 |
|
||||
* | ERROR(LargeResponse) | 4 + 1 = 5 | 1 |
|
||||
* | ERROR(ResponseNotReady) | 4 + 4 = 8 | 1 |
|
||||
* +--------------------------+------------------------------------------+---------+
|
||||
* | CHUNK_SEND header | 12 + L0 (0 or 4) | 1 |
|
||||
* | CHUNK_RESPONSE header | 12 + L0 (0 or 4) | 1 |
|
||||
* +==========================+==========================================+=========+
|
||||
* | NEGOTIATE_ALGORITHMS 1.2 | 32 + 4 * 4 = 48 | 2 |
|
||||
* | ALGORITHMS 1.2 | 36 + 4 * 4 = 52 | 2 |
|
||||
* +--------------------------+------------------------------------------+---------+
|
||||
* | GET_DIGESTS 1.2 | 4 | 1 |
|
||||
* | DIGESTS 1.2 | 4 + H * SlotNum = [36, 516] | [1, 18] |
|
||||
* +--------------------------+------------------------------------------+---------+
|
||||
* | GET_CERTIFICATE 1.2 | 8 | 1 |
|
||||
* | CERTIFICATE 1.2 | 8 + PortionLen | [1, ] |
|
||||
* +--------------------------+------------------------------------------+---------+
|
||||
* | CHALLENGE 1.2 | 40 | 1 |
|
||||
* | CHALLENGE_AUTH 1.2 | 38 + H * 2 + S [+ O] = [166, 678] | [6, 23] |
|
||||
* +--------------------------+------------------------------------------+---------+
|
||||
* | GET_MEASUREMENTS 1.2 | 5 + Nonce (0 or 32) | 1 |
|
||||
* | MEASUREMENTS 1.2 | 42 + MeasRecLen (+ S) [+ O] = [106, 554] | [4, 19] |
|
||||
* +--------------------------+------------------------------------------+---------+
|
||||
* | KEY_EXCHANGE 1.2 | 42 + D [+ O] = [106, 554] | [4, 19] |
|
||||
* | KEY_EXCHANGE_RSP 1.2 | 42 + D + H + S (+ H) [+ O] = [234, 1194] | [8, 40] |
|
||||
* +--------------------------+------------------------------------------+---------+
|
||||
* | FINISH 1.2 | 4 (+ S) + H = [100, 580] | [4, 20] |
|
||||
* | FINISH_RSP 1.2 | 4 (+ H) = [36, 69] | [1, 3] |
|
||||
* +--------------------------+------------------------------------------+---------+
|
||||
* | PSK_EXCHANGE 1.2 | 12 [+ PSKHint] + R [+ O] = 44 | 2 |
|
||||
* | PSK_EXCHANGE_RSP 1.2 | 12 + R + H (+ H) [+ O] = [108, 172] | [4, 6] |
|
||||
* +--------------------------+------------------------------------------+---------+
|
||||
* | PSK_FINISH 1.2 | 4 + H = [36, 68] | [1, 3] |
|
||||
* | PSK_FINISH_RSP 1.2 | 4 | 1 |
|
||||
* +--------------------------+------------------------------------------+---------+
|
||||
* | GET_CSR 1.2 | 8 + RequesterInfoLen [+ O] | [1, ] |
|
||||
* | CSR 1.2 | 8 + CSRLength | [1, ] |
|
||||
* +--------------------------+------------------------------------------+---------+
|
||||
* | SET_CERTIFICATE 1.2 | 4 + CertChainLen | [1, ] |
|
||||
* | SET_CERTIFICATE_RSP 1.2 | 4 | 1 |
|
||||
* +==========================+==========================================+=========+
|
||||
*/
|
||||
|
||||
/* Required sender/receive buffer in device io.
|
||||
* NOTE: This is transport specific. Below configuration is just an example.
|
||||
* +-------+--------+---------------------------+------+--+------+---+--------+-----+
|
||||
* | TYPE |TransHdr| EncryptionHeader |AppHdr| |Random|MAC|AlignPad|FINAL|
|
||||
* | | |SessionId|SeqNum|Len|AppLen| | | | | | |
|
||||
* +-------+--------+---------------------------+------+ +------+---+--------+-----+
|
||||
* | MCTP | 1 | 4 | 2 | 2 | 2 | 1 | | 32 | 12| 0 | 56 |
|
||||
* |PCI_DOE| 8 | 4 | 0 | 2 | 2 | 0 | | 0 | 12| 3 | 31 |
|
||||
* +-------+--------+---------------------------+------+--+------+---+--------+-----+
|
||||
*/
|
||||
|
||||
/* Enable message logging.
|
||||
* See https://github.com/DMTF/libspdm/blob/main/doc/user_guide.md#message-logging
|
||||
* for more information */
|
||||
#ifndef LIBSPDM_ENABLE_MSG_LOG
|
||||
#define LIBSPDM_ENABLE_MSG_LOG 1
|
||||
#endif
|
||||
|
||||
/* Enable macro checking during compilation. */
|
||||
#ifndef LIBSPDM_CHECK_MACRO
|
||||
#define LIBSPDM_CHECK_MACRO 0
|
||||
#endif
|
||||
|
||||
/* Enable checks to the SPDM context during runtime. */
|
||||
#ifndef LIBSPDM_CHECK_SPDM_CONTEXT
|
||||
#define LIBSPDM_CHECK_SPDM_CONTEXT 1
|
||||
#endif
|
||||
|
||||
#endif /* SPDM_LIB_CONFIG_H */
|
47
SecurityPkg/DeviceSecurity/SpdmLib/SpdmCommonLib.inf
Normal file
47
SecurityPkg/DeviceSecurity/SpdmLib/SpdmCommonLib.inf
Normal file
@ -0,0 +1,47 @@
|
||||
## @file
|
||||
# SPDM library.
|
||||
#
|
||||
# Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
|
||||
#
|
||||
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
#
|
||||
##
|
||||
|
||||
[Defines]
|
||||
INF_VERSION = 0x00010005
|
||||
BASE_NAME = SpdmCommonLib
|
||||
FILE_GUID = 4D42800D-2197-46EC-8E04-6B41BFD60687
|
||||
MODULE_TYPE = BASE
|
||||
VERSION_STRING = 1.0
|
||||
LIBRARY_CLASS = SpdmCommonLib
|
||||
|
||||
#
|
||||
# The following information is for reference only and not required by the build tools.
|
||||
#
|
||||
# VALID_ARCHITECTURES = IA32 X64 AARCH64
|
||||
#
|
||||
|
||||
[Sources]
|
||||
libspdm/library/spdm_common_lib/libspdm_com_context_data.c
|
||||
libspdm/library/spdm_common_lib/libspdm_com_context_data_session.c
|
||||
libspdm/library/spdm_common_lib/libspdm_com_crypto_service.c
|
||||
libspdm/library/spdm_common_lib/libspdm_com_crypto_service_session.c
|
||||
libspdm/library/spdm_common_lib/libspdm_com_opaque_data.c
|
||||
libspdm/library/spdm_common_lib/libspdm_com_support.c
|
||||
libspdm/library/spdm_common_lib/libspdm_com_msg_log.c
|
||||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
SecurityPkg/SecurityPkg.dec
|
||||
CryptoPkg/CryptoPkg.dec
|
||||
|
||||
[LibraryClasses]
|
||||
BaseLib
|
||||
BaseMemoryLib
|
||||
DebugLib
|
||||
BaseCryptLib
|
||||
RngLib
|
||||
SpdmCryptLib
|
||||
SpdmDeviceSecretLib
|
||||
MemLibWrapper
|
||||
CryptlibWrapper
|
45
SecurityPkg/DeviceSecurity/SpdmLib/SpdmCryptLib.inf
Normal file
45
SecurityPkg/DeviceSecurity/SpdmLib/SpdmCryptLib.inf
Normal file
@ -0,0 +1,45 @@
|
||||
## @file
|
||||
# SPDM library.
|
||||
#
|
||||
# Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
|
||||
#
|
||||
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
#
|
||||
##
|
||||
|
||||
[Defines]
|
||||
INF_VERSION = 0x00010005
|
||||
BASE_NAME = SpdmCryptLib
|
||||
FILE_GUID = 2FF3E7F6-D95A-48A2-B418-9B6D585C1D7E
|
||||
MODULE_TYPE = BASE
|
||||
VERSION_STRING = 1.0
|
||||
LIBRARY_CLASS = SpdmCryptLib
|
||||
|
||||
#
|
||||
# The following information is for reference only and not required by the build tools.
|
||||
#
|
||||
# VALID_ARCHITECTURES = IA32 X64 AARCH64
|
||||
#
|
||||
|
||||
[Sources]
|
||||
libspdm/library/spdm_crypt_lib/libspdm_crypt_aead.c
|
||||
libspdm/library/spdm_crypt_lib/libspdm_crypt_asym.c
|
||||
libspdm/library/spdm_crypt_lib/libspdm_crypt_cert.c
|
||||
libspdm/library/spdm_crypt_lib/libspdm_crypt_dhe.c
|
||||
libspdm/library/spdm_crypt_lib/libspdm_crypt_hash.c
|
||||
libspdm/library/spdm_crypt_lib/libspdm_crypt_hkdf.c
|
||||
libspdm/library/spdm_crypt_lib/libspdm_crypt_hmac.c
|
||||
libspdm/library/spdm_crypt_lib/libspdm_crypt_rng.c
|
||||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
SecurityPkg/SecurityPkg.dec
|
||||
CryptoPkg/CryptoPkg.dec
|
||||
|
||||
[LibraryClasses]
|
||||
BaseLib
|
||||
BaseMemoryLib
|
||||
DebugLib
|
||||
BaseCryptLib
|
||||
RngLib
|
||||
MemLibWrapper
|
@ -0,0 +1,36 @@
|
||||
## @file
|
||||
# SPDM library.
|
||||
#
|
||||
# Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
|
||||
#
|
||||
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
#
|
||||
##
|
||||
|
||||
[Defines]
|
||||
INF_VERSION = 0x00010005
|
||||
BASE_NAME = SpdmDeviceSecretLibNull
|
||||
FILE_GUID = E2FFA5F9-CD19-4B63-AE3E-7EA288243EED
|
||||
MODULE_TYPE = BASE
|
||||
VERSION_STRING = 1.0
|
||||
LIBRARY_CLASS = SpdmDeviceSecretLib
|
||||
|
||||
#
|
||||
# The following information is for reference only and not required by the build tools.
|
||||
#
|
||||
# VALID_ARCHITECTURES = IA32 X64 AARCH64
|
||||
#
|
||||
|
||||
[Sources]
|
||||
libspdm/os_stub/spdm_device_secret_lib_null/lib.c
|
||||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
SecurityPkg/SecurityPkg.dec
|
||||
CryptoPkg/CryptoPkg.dec
|
||||
|
||||
[LibraryClasses]
|
||||
BaseLib
|
||||
BaseMemoryLib
|
||||
DebugLib
|
||||
MemLibWrapper
|
59
SecurityPkg/DeviceSecurity/SpdmLib/SpdmRequesterLib.inf
Normal file
59
SecurityPkg/DeviceSecurity/SpdmLib/SpdmRequesterLib.inf
Normal file
@ -0,0 +1,59 @@
|
||||
## @file
|
||||
# SPDM library.
|
||||
#
|
||||
# Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
|
||||
#
|
||||
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
#
|
||||
##
|
||||
|
||||
[Defines]
|
||||
INF_VERSION = 0x00010005
|
||||
BASE_NAME = SpdmRequesterLib
|
||||
FILE_GUID = 8B6024A3-270A-410F-91AB-9E99F05C2A58
|
||||
MODULE_TYPE = BASE
|
||||
VERSION_STRING = 1.0
|
||||
LIBRARY_CLASS = SpdmRequesterLib
|
||||
|
||||
#
|
||||
# The following information is for reference only and not required by the build tools.
|
||||
#
|
||||
# VALID_ARCHITECTURES = IA32 X64 AARCH64
|
||||
#
|
||||
|
||||
[Sources]
|
||||
libspdm/library/spdm_requester_lib/libspdm_req_challenge.c
|
||||
libspdm/library/spdm_requester_lib/libspdm_req_common.c
|
||||
libspdm/library/spdm_requester_lib/libspdm_req_communication.c
|
||||
libspdm/library/spdm_requester_lib/libspdm_req_encap_certificate.c
|
||||
libspdm/library/spdm_requester_lib/libspdm_req_encap_challenge_auth.c
|
||||
libspdm/library/spdm_requester_lib/libspdm_req_encap_digests.c
|
||||
libspdm/library/spdm_requester_lib/libspdm_req_encap_error.c
|
||||
libspdm/library/spdm_requester_lib/libspdm_req_encap_key_update.c
|
||||
libspdm/library/spdm_requester_lib/libspdm_req_encap_request.c
|
||||
libspdm/library/spdm_requester_lib/libspdm_req_end_session.c
|
||||
libspdm/library/spdm_requester_lib/libspdm_req_finish.c
|
||||
libspdm/library/spdm_requester_lib/libspdm_req_get_capabilities.c
|
||||
libspdm/library/spdm_requester_lib/libspdm_req_get_certificate.c
|
||||
libspdm/library/spdm_requester_lib/libspdm_req_get_digests.c
|
||||
libspdm/library/spdm_requester_lib/libspdm_req_get_measurements.c
|
||||
libspdm/library/spdm_requester_lib/libspdm_req_get_version.c
|
||||
libspdm/library/spdm_requester_lib/libspdm_req_handle_error_response.c
|
||||
libspdm/library/spdm_requester_lib/libspdm_req_heartbeat.c
|
||||
libspdm/library/spdm_requester_lib/libspdm_req_key_exchange.c
|
||||
libspdm/library/spdm_requester_lib/libspdm_req_key_update.c
|
||||
libspdm/library/spdm_requester_lib/libspdm_req_negotiate_algorithms.c
|
||||
libspdm/library/spdm_requester_lib/libspdm_req_psk_exchange.c
|
||||
libspdm/library/spdm_requester_lib/libspdm_req_psk_finish.c
|
||||
libspdm/library/spdm_requester_lib/libspdm_req_send_receive.c
|
||||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
SecurityPkg/SecurityPkg.dec
|
||||
CryptoPkg/CryptoPkg.dec
|
||||
|
||||
[LibraryClasses]
|
||||
SpdmCommonLib
|
||||
SpdmSecuredMessageLib
|
||||
PlatformLibWrapper
|
||||
MemLibWrapper
|
61
SecurityPkg/DeviceSecurity/SpdmLib/SpdmResponderLib.inf
Normal file
61
SecurityPkg/DeviceSecurity/SpdmLib/SpdmResponderLib.inf
Normal file
@ -0,0 +1,61 @@
|
||||
## @file
|
||||
# SPDM library.
|
||||
#
|
||||
# Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
|
||||
#
|
||||
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
#
|
||||
##
|
||||
|
||||
[Defines]
|
||||
INF_VERSION = 0x00010005
|
||||
BASE_NAME = SpdmResponderLib
|
||||
FILE_GUID = 9005B3A3-45F1-4DE9-93FF-2512D4B9CCFA
|
||||
MODULE_TYPE = BASE
|
||||
VERSION_STRING = 1.0
|
||||
LIBRARY_CLASS = SpdmResponderLib
|
||||
|
||||
#
|
||||
# The following information is for reference only and not required by the build tools.
|
||||
#
|
||||
# VALID_ARCHITECTURES = IA32 X64 AARCH64
|
||||
#
|
||||
|
||||
[Sources]
|
||||
libspdm/library/spdm_responder_lib/libspdm_rsp_algorithms.c
|
||||
libspdm/library/spdm_responder_lib/libspdm_rsp_capabilities.c
|
||||
libspdm/library/spdm_responder_lib/libspdm_rsp_certificate.c
|
||||
libspdm/library/spdm_responder_lib/libspdm_rsp_challenge_auth.c
|
||||
libspdm/library/spdm_responder_lib/libspdm_rsp_common.c
|
||||
libspdm/library/spdm_responder_lib/libspdm_rsp_communication.c
|
||||
libspdm/library/spdm_responder_lib/libspdm_rsp_digests.c
|
||||
libspdm/library/spdm_responder_lib/libspdm_rsp_encap_challenge.c
|
||||
libspdm/library/spdm_responder_lib/libspdm_rsp_encap_get_certificate.c
|
||||
libspdm/library/spdm_responder_lib/libspdm_rsp_encap_get_digests.c
|
||||
libspdm/library/spdm_responder_lib/libspdm_rsp_encap_key_update.c
|
||||
libspdm/library/spdm_responder_lib/libspdm_rsp_encap_response.c
|
||||
libspdm/library/spdm_responder_lib/libspdm_rsp_end_session.c
|
||||
libspdm/library/spdm_responder_lib/libspdm_rsp_error.c
|
||||
libspdm/library/spdm_responder_lib/libspdm_rsp_finish.c
|
||||
libspdm/library/spdm_responder_lib/libspdm_rsp_handle_response_state.c
|
||||
libspdm/library/spdm_responder_lib/libspdm_rsp_heartbeat.c
|
||||
libspdm/library/spdm_responder_lib/libspdm_rsp_key_exchange.c
|
||||
libspdm/library/spdm_responder_lib/libspdm_rsp_key_update.c
|
||||
libspdm/library/spdm_responder_lib/libspdm_rsp_measurements.c
|
||||
libspdm/library/spdm_responder_lib/libspdm_rsp_psk_exchange.c
|
||||
libspdm/library/spdm_responder_lib/libspdm_rsp_psk_finish.c
|
||||
libspdm/library/spdm_responder_lib/libspdm_rsp_receive_send.c
|
||||
libspdm/library/spdm_responder_lib/libspdm_rsp_respond_if_ready.c
|
||||
libspdm/library/spdm_responder_lib/libspdm_rsp_version.c
|
||||
libspdm/library/spdm_responder_lib/libspdm_rsp_csr.c
|
||||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
SecurityPkg/SecurityPkg.dec
|
||||
CryptoPkg/CryptoPkg.dec
|
||||
|
||||
[LibraryClasses]
|
||||
SpdmCommonLib
|
||||
SpdmSecuredMessageLib
|
||||
PlatformLibWrapper
|
||||
MemLibWrapper
|
44
SecurityPkg/DeviceSecurity/SpdmLib/SpdmSecuredMessageLib.inf
Normal file
44
SecurityPkg/DeviceSecurity/SpdmLib/SpdmSecuredMessageLib.inf
Normal file
@ -0,0 +1,44 @@
|
||||
## @file
|
||||
# SPDM library.
|
||||
#
|
||||
# Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
|
||||
#
|
||||
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
#
|
||||
##
|
||||
|
||||
[Defines]
|
||||
INF_VERSION = 0x00010005
|
||||
BASE_NAME = SpdmSecuredMessageLib
|
||||
FILE_GUID = C5E91542-9B57-4BC4-988C-2DEB0B17D381
|
||||
MODULE_TYPE = BASE
|
||||
VERSION_STRING = 1.0
|
||||
LIBRARY_CLASS = SpdmSecuredMessageLib
|
||||
|
||||
#
|
||||
# The following information is for reference only and not required by the build tools.
|
||||
#
|
||||
# VALID_ARCHITECTURES = IA32 X64 AARCH64
|
||||
#
|
||||
|
||||
[Sources]
|
||||
libspdm/library/spdm_secured_message_lib/libspdm_secmes_context_data.c
|
||||
libspdm/library/spdm_secured_message_lib/libspdm_secmes_encode_decode.c
|
||||
libspdm/library/spdm_secured_message_lib/libspdm_secmes_encode_decode.c
|
||||
libspdm/library/spdm_secured_message_lib/libspdm_secmes_key_exchange.c
|
||||
libspdm/library/spdm_secured_message_lib/libspdm_secmes_session.c
|
||||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
SecurityPkg/SecurityPkg.dec
|
||||
CryptoPkg/CryptoPkg.dec
|
||||
|
||||
[LibraryClasses]
|
||||
BaseLib
|
||||
BaseMemoryLib
|
||||
DebugLib
|
||||
BaseCryptLib
|
||||
RngLib
|
||||
SpdmCryptLib
|
||||
SpdmDeviceSecretLib
|
||||
MemLibWrapper
|
38
SecurityPkg/DeviceSecurity/SpdmLib/SpdmTransportMctpLib.inf
Normal file
38
SecurityPkg/DeviceSecurity/SpdmLib/SpdmTransportMctpLib.inf
Normal file
@ -0,0 +1,38 @@
|
||||
## @file
|
||||
# SPDM library.
|
||||
#
|
||||
# Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
|
||||
#
|
||||
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
#
|
||||
##
|
||||
|
||||
[Defines]
|
||||
INF_VERSION = 0x00010005
|
||||
BASE_NAME = SpdmTransportMctpLib
|
||||
FILE_GUID = C6ED3DB8-852A-40A8-8099-9D87D93669C4
|
||||
MODULE_TYPE = BASE
|
||||
VERSION_STRING = 1.0
|
||||
LIBRARY_CLASS = SpdmTransportMctpLib
|
||||
|
||||
#
|
||||
# The following information is for reference only and not required by the build tools.
|
||||
#
|
||||
# VALID_ARCHITECTURES = IA32 X64 AARCH64
|
||||
#
|
||||
|
||||
[Sources]
|
||||
libspdm/library/spdm_transport_mctp_lib/libspdm_mctp_common.c
|
||||
libspdm/library/spdm_transport_mctp_lib/libspdm_mctp_mctp.c
|
||||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
SecurityPkg/SecurityPkg.dec
|
||||
CryptoPkg/CryptoPkg.dec
|
||||
|
||||
[LibraryClasses]
|
||||
BaseLib
|
||||
BaseMemoryLib
|
||||
DebugLib
|
||||
SpdmSecuredMessageLib
|
||||
MemLibWrapper
|
@ -0,0 +1,38 @@
|
||||
## @file
|
||||
# SPDM library.
|
||||
#
|
||||
# Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
|
||||
#
|
||||
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
#
|
||||
##
|
||||
|
||||
[Defines]
|
||||
INF_VERSION = 0x00010005
|
||||
BASE_NAME = SpdmTransportPciDoeLib
|
||||
FILE_GUID = 21094151-1A91-4261-8EB7-C94453491FF8
|
||||
MODULE_TYPE = BASE
|
||||
VERSION_STRING = 1.0
|
||||
LIBRARY_CLASS = SpdmTransportPciDoeLib
|
||||
|
||||
#
|
||||
# The following information is for reference only and not required by the build tools.
|
||||
#
|
||||
# VALID_ARCHITECTURES = IA32 X64 AARCH64
|
||||
#
|
||||
|
||||
[Sources]
|
||||
libspdm/library/spdm_transport_pcidoe_lib/libspdm_doe_common.c
|
||||
libspdm/library/spdm_transport_pcidoe_lib/libspdm_doe_pcidoe.c
|
||||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
SecurityPkg/SecurityPkg.dec
|
||||
CryptoPkg/CryptoPkg.dec
|
||||
|
||||
[LibraryClasses]
|
||||
BaseLib
|
||||
BaseMemoryLib
|
||||
DebugLib
|
||||
SpdmSecuredMessageLib
|
||||
MemLibWrapper
|
697
SecurityPkg/DeviceSecurity/SpdmSecurityLib/SpdmAuthentication.c
Normal file
697
SecurityPkg/DeviceSecurity/SpdmSecurityLib/SpdmAuthentication.c
Normal file
@ -0,0 +1,697 @@
|
||||
/** @file
|
||||
EDKII Device Security library for SPDM device.
|
||||
It follows the SPDM Specification.
|
||||
|
||||
Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
**/
|
||||
|
||||
#include "SpdmSecurityLibInternal.h"
|
||||
|
||||
/**
|
||||
Measure and log an EFI variable, and extend the measurement result into a specific PCR.
|
||||
|
||||
@param[in] PcrIndex PCR Index.
|
||||
@param[in] EventType Event type.
|
||||
@param[in] VarName A Null-terminated string that is the name of the vendor's variable.
|
||||
@param[in] VendorGuid A unique identifier for the vendor.
|
||||
@param[in] VarData The content of the variable data.
|
||||
@param[in] VarSize The size of the variable data.
|
||||
|
||||
@retval EFI_SUCCESS Operation completed successfully.
|
||||
@retval EFI_OUT_OF_RESOURCES Out of memory.
|
||||
@retval EFI_DEVICE_ERROR The operation was unsuccessful.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
MeasureVariable (
|
||||
IN UINT32 PcrIndex,
|
||||
IN UINT32 EventType,
|
||||
IN CHAR16 *VarName,
|
||||
IN EFI_GUID *VendorGuid,
|
||||
IN VOID *VarData,
|
||||
IN UINTN VarSize
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINTN VarNameLength;
|
||||
UEFI_VARIABLE_DATA *VarLog;
|
||||
UINT32 VarLogSize;
|
||||
|
||||
if (!(((VarSize == 0) && (VarData == NULL)) || ((VarSize != 0) && (VarData != NULL)))) {
|
||||
ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
VarNameLength = StrLen (VarName);
|
||||
VarLogSize = (UINT32)(sizeof (*VarLog) + VarNameLength * sizeof (*VarName) + VarSize
|
||||
- sizeof (VarLog->UnicodeName) - sizeof (VarLog->VariableData));
|
||||
|
||||
VarLog = (UEFI_VARIABLE_DATA *)AllocateZeroPool (VarLogSize);
|
||||
if (VarLog == NULL) {
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
CopyMem (&VarLog->VariableName, VendorGuid, sizeof (VarLog->VariableName));
|
||||
VarLog->UnicodeNameLength = VarNameLength;
|
||||
VarLog->VariableDataLength = VarSize;
|
||||
CopyMem (
|
||||
VarLog->UnicodeName,
|
||||
VarName,
|
||||
VarNameLength * sizeof (*VarName)
|
||||
);
|
||||
if (VarSize != 0) {
|
||||
CopyMem (
|
||||
(CHAR16 *)VarLog->UnicodeName + VarNameLength,
|
||||
VarData,
|
||||
VarSize
|
||||
);
|
||||
}
|
||||
|
||||
DEBUG ((DEBUG_INFO, "VariableDxe: MeasureVariable (Pcr - %x, EventType - %x, ", (UINTN)PcrIndex, (UINTN)EventType));
|
||||
DEBUG ((DEBUG_INFO, "VariableName - %s, VendorGuid - %g)\n", VarName, VendorGuid));
|
||||
|
||||
Status = TpmMeasureAndLogData (
|
||||
PcrIndex,
|
||||
EventType,
|
||||
VarLog,
|
||||
VarLogSize,
|
||||
VarLog,
|
||||
VarLogSize
|
||||
);
|
||||
FreePool (VarLog);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
Extend Certicate and auth state to NV Index and measure trust anchor to PCR.
|
||||
|
||||
@param[in] SpdmDeviceContext The SPDM context for the device.
|
||||
@param[in] AuthState The auth state of this deice.
|
||||
@param[in] CertChainSize The size of cert chain.
|
||||
@param[in] CertChain A pointer to a destination buffer to store the certificate chain.
|
||||
@param[in] TrustAnchor A buffer to hold the trust_anchor which is used to validate the peer
|
||||
certificate, if not NULL.
|
||||
@param[in] TrustAnchorSize A buffer to hold the trust_anchor_size, if not NULL..
|
||||
@param[in] SlotId The number of slot for the certificate chain.
|
||||
@param[out] SecurityState A pointer to the security state of the requester.
|
||||
|
||||
@retval EFI_SUCCESS Operation completed successfully.
|
||||
@retval EFI_OUT_OF_RESOURCES Out of memory.
|
||||
@retval EFI_DEVICE_ERROR The operation was unsuccessful.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
ExtendCertificate (
|
||||
IN SPDM_DEVICE_CONTEXT *SpdmDeviceContext,
|
||||
IN UINT8 AuthState,
|
||||
IN UINTN CertChainSize,
|
||||
IN UINT8 *CertChain,
|
||||
IN VOID *TrustAnchor,
|
||||
IN UINTN TrustAnchorSize,
|
||||
IN UINT8 SlotId,
|
||||
OUT EDKII_DEVICE_SECURITY_STATE *SecurityState
|
||||
)
|
||||
{
|
||||
VOID *EventLog;
|
||||
UINT32 EventLogSize;
|
||||
UINT8 *EventLogPtr;
|
||||
TCG_NV_INDEX_INSTANCE_EVENT_LOG_STRUCT *NvIndexInstance;
|
||||
TCG_DEVICE_SECURITY_EVENT_DATA_HEADER2 *EventData2;
|
||||
TCG_DEVICE_SECURITY_EVENT_DATA_SUB_HEADER_SPDM_CERT_CHAIN *TcgSpdmCertChain;
|
||||
VOID *DeviceContext;
|
||||
UINTN DeviceContextSize;
|
||||
EFI_STATUS Status;
|
||||
UINTN DevicePathSize;
|
||||
UINT32 BaseHashAlgo;
|
||||
UINTN DataSize;
|
||||
VOID *SpdmContext;
|
||||
SPDM_DATA_PARAMETER Parameter;
|
||||
EFI_SIGNATURE_DATA *SignatureData;
|
||||
UINTN SignatureDataSize;
|
||||
|
||||
SpdmContext = SpdmDeviceContext->SpdmContext;
|
||||
|
||||
EventLog = NULL;
|
||||
ZeroMem (&Parameter, sizeof (Parameter));
|
||||
Parameter.location = SpdmDataLocationConnection;
|
||||
DataSize = sizeof (BaseHashAlgo);
|
||||
Status = SpdmGetData (SpdmContext, SpdmDataBaseHashAlgo, &Parameter, &BaseHashAlgo, &DataSize);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
DeviceContextSize = GetDeviceMeasurementContextSize (SpdmDeviceContext);
|
||||
DevicePathSize = GetDevicePathSize (SpdmDeviceContext->DevicePath);
|
||||
|
||||
switch (AuthState) {
|
||||
case TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_AUTH_STATE_SUCCESS:
|
||||
case TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_AUTH_STATE_NO_AUTH:
|
||||
case TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_AUTH_STATE_NO_BINDING:
|
||||
EventLogSize = (UINT32)(sizeof (TCG_NV_INDEX_INSTANCE_EVENT_LOG_STRUCT) +
|
||||
sizeof (TCG_DEVICE_SECURITY_EVENT_DATA_HEADER2) +
|
||||
sizeof (UINT64) + DevicePathSize +
|
||||
sizeof (TCG_DEVICE_SECURITY_EVENT_DATA_SUB_HEADER_SPDM_CERT_CHAIN) +
|
||||
CertChainSize +
|
||||
DeviceContextSize);
|
||||
EventLog = AllocatePool (EventLogSize);
|
||||
if (EventLog == NULL) {
|
||||
SecurityState->AuthenticationState = EDKII_DEVICE_SECURITY_STATE_ERROR_UEFI_OUT_OF_RESOURCE;
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
EventLogPtr = EventLog;
|
||||
|
||||
NvIndexInstance = (VOID *)EventLogPtr;
|
||||
CopyMem (NvIndexInstance->Signature, TCG_NV_EXTEND_INDEX_FOR_INSTANCE_SIGNATURE, sizeof (TCG_NV_EXTEND_INDEX_FOR_INSTANCE_SIGNATURE));
|
||||
NvIndexInstance->Version = TCG_NV_INDEX_INSTANCE_EVENT_LOG_STRUCT_VERSION;
|
||||
ZeroMem (NvIndexInstance->Reserved, sizeof (NvIndexInstance->Reserved));
|
||||
EventLogPtr += sizeof (TCG_NV_INDEX_INSTANCE_EVENT_LOG_STRUCT);
|
||||
|
||||
EventData2 = (VOID *)EventLogPtr;
|
||||
CopyMem (EventData2->Signature, TCG_DEVICE_SECURITY_EVENT_DATA_SIGNATURE_2, sizeof (EventData2->Signature));
|
||||
EventData2->Version = TCG_DEVICE_SECURITY_EVENT_DATA_VERSION_2;
|
||||
EventData2->AuthState = AuthState;
|
||||
EventData2->Reserved = 0;
|
||||
EventData2->Length = (UINT32)EventLogSize;
|
||||
EventData2->DeviceType = GetSpdmDeviceType (SpdmDeviceContext);
|
||||
|
||||
EventData2->SubHeaderType = TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_SUB_HEADER_TYPE_SPDM_CERT_CHAIN;
|
||||
EventData2->SubHeaderLength = (UINT32)(sizeof (TCG_DEVICE_SECURITY_EVENT_DATA_SUB_HEADER_SPDM_CERT_CHAIN) + CertChainSize);
|
||||
EventData2->SubHeaderUID = SpdmDeviceContext->DeviceUID;
|
||||
|
||||
EventLogPtr = (VOID *)(EventData2 + 1);
|
||||
|
||||
*(UINT64 *)EventLogPtr = (UINT64)DevicePathSize;
|
||||
EventLogPtr += sizeof (UINT64);
|
||||
CopyMem (EventLogPtr, SpdmDeviceContext->DevicePath, DevicePathSize);
|
||||
EventLogPtr += DevicePathSize;
|
||||
|
||||
TcgSpdmCertChain = (VOID *)EventLogPtr;
|
||||
TcgSpdmCertChain->SpdmVersion = SpdmDeviceContext->SpdmVersion;
|
||||
TcgSpdmCertChain->SpdmSlotId = SlotId;
|
||||
TcgSpdmCertChain->Reserved = 0;
|
||||
TcgSpdmCertChain->SpdmHashAlgo = BaseHashAlgo;
|
||||
EventLogPtr += sizeof (TCG_DEVICE_SECURITY_EVENT_DATA_SUB_HEADER_SPDM_CERT_CHAIN);
|
||||
|
||||
CopyMem (EventLogPtr, CertChain, CertChainSize);
|
||||
EventLogPtr += CertChainSize;
|
||||
|
||||
if (DeviceContextSize != 0) {
|
||||
DeviceContext = (VOID *)EventLogPtr;
|
||||
Status = CreateDeviceMeasurementContext (SpdmDeviceContext, DeviceContext, DeviceContextSize);
|
||||
if (Status != EFI_SUCCESS) {
|
||||
SecurityState->AuthenticationState = EDKII_DEVICE_SECURITY_STATE_ERROR_DEVICE_ERROR;
|
||||
Status = EFI_DEVICE_ERROR;
|
||||
goto Exit;
|
||||
}
|
||||
}
|
||||
|
||||
Status = TpmMeasureAndLogData (
|
||||
TCG_NV_EXTEND_INDEX_FOR_INSTANCE,
|
||||
EV_NO_ACTION,
|
||||
EventLog,
|
||||
EventLogSize,
|
||||
EventLog,
|
||||
EventLogSize
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
SecurityState->AuthenticationState = EDKII_DEVICE_SECURITY_STATE_ERROR_TCG_EXTEND_TPM_PCR;
|
||||
}
|
||||
|
||||
DEBUG ((DEBUG_INFO, "TpmMeasureAndLogData (Instance) - %r\n", Status));
|
||||
|
||||
break;
|
||||
case TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_AUTH_STATE_FAIL_INVALID:
|
||||
EventLogSize = (UINT32)(sizeof (TCG_NV_INDEX_INSTANCE_EVENT_LOG_STRUCT) +
|
||||
sizeof (TCG_DEVICE_SECURITY_EVENT_DATA_HEADER2) +
|
||||
sizeof (UINT64) + DevicePathSize +
|
||||
sizeof (TCG_DEVICE_SECURITY_EVENT_DATA_SUB_HEADER_SPDM_CERT_CHAIN) +
|
||||
DeviceContextSize);
|
||||
EventLog = AllocatePool (EventLogSize);
|
||||
if (EventLog == NULL) {
|
||||
SecurityState->AuthenticationState = EDKII_DEVICE_SECURITY_STATE_ERROR_UEFI_OUT_OF_RESOURCE;
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
EventLogPtr = EventLog;
|
||||
|
||||
NvIndexInstance = (VOID *)EventLogPtr;
|
||||
CopyMem (NvIndexInstance->Signature, TCG_NV_EXTEND_INDEX_FOR_INSTANCE_SIGNATURE, sizeof (TCG_NV_EXTEND_INDEX_FOR_INSTANCE_SIGNATURE));
|
||||
NvIndexInstance->Version = TCG_NV_INDEX_INSTANCE_EVENT_LOG_STRUCT_VERSION;
|
||||
ZeroMem (NvIndexInstance->Reserved, sizeof (NvIndexInstance->Reserved));
|
||||
EventLogPtr += sizeof (TCG_NV_INDEX_INSTANCE_EVENT_LOG_STRUCT);
|
||||
|
||||
EventData2 = (VOID *)EventLogPtr;
|
||||
CopyMem (EventData2->Signature, TCG_DEVICE_SECURITY_EVENT_DATA_SIGNATURE_2, sizeof (EventData2->Signature));
|
||||
EventData2->Version = TCG_DEVICE_SECURITY_EVENT_DATA_VERSION_2;
|
||||
EventData2->AuthState = AuthState;
|
||||
EventData2->Reserved = 0;
|
||||
EventData2->Length = (UINT32)EventLogSize;
|
||||
EventData2->DeviceType = GetSpdmDeviceType (SpdmDeviceContext);
|
||||
|
||||
EventData2->SubHeaderType = TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_SUB_HEADER_TYPE_SPDM_CERT_CHAIN;
|
||||
EventData2->SubHeaderLength = sizeof (TCG_DEVICE_SECURITY_EVENT_DATA_SUB_HEADER_SPDM_CERT_CHAIN);
|
||||
EventData2->SubHeaderUID = SpdmDeviceContext->DeviceUID;
|
||||
|
||||
EventLogPtr = (VOID *)(EventData2 + 1);
|
||||
|
||||
*(UINT64 *)EventLogPtr = (UINT64)DevicePathSize;
|
||||
EventLogPtr += sizeof (UINT64);
|
||||
CopyMem (EventLogPtr, SpdmDeviceContext->DevicePath, DevicePathSize);
|
||||
EventLogPtr += DevicePathSize;
|
||||
|
||||
TcgSpdmCertChain = (VOID *)EventLogPtr;
|
||||
TcgSpdmCertChain->SpdmVersion = SpdmDeviceContext->SpdmVersion;
|
||||
TcgSpdmCertChain->SpdmSlotId = SlotId;
|
||||
TcgSpdmCertChain->Reserved = 0;
|
||||
TcgSpdmCertChain->SpdmHashAlgo = BaseHashAlgo;
|
||||
EventLogPtr += sizeof (TCG_DEVICE_SECURITY_EVENT_DATA_SUB_HEADER_SPDM_CERT_CHAIN);
|
||||
|
||||
if (DeviceContextSize != 0) {
|
||||
DeviceContext = (VOID *)EventLogPtr;
|
||||
Status = CreateDeviceMeasurementContext (SpdmDeviceContext, DeviceContext, DeviceContextSize);
|
||||
if (Status != EFI_SUCCESS) {
|
||||
SecurityState->AuthenticationState = EDKII_DEVICE_SECURITY_STATE_ERROR_DEVICE_ERROR;
|
||||
Status = EFI_DEVICE_ERROR;
|
||||
goto Exit;
|
||||
}
|
||||
}
|
||||
|
||||
Status = TpmMeasureAndLogData (
|
||||
TCG_NV_EXTEND_INDEX_FOR_INSTANCE,
|
||||
EV_NO_ACTION,
|
||||
EventLog,
|
||||
EventLogSize,
|
||||
EventLog,
|
||||
EventLogSize
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
SecurityState->AuthenticationState = EDKII_DEVICE_SECURITY_STATE_ERROR_TCG_EXTEND_TPM_PCR;
|
||||
}
|
||||
|
||||
DEBUG ((DEBUG_INFO, "TpmMeasureAndLogData (Instance) - %r\n", Status));
|
||||
|
||||
goto Exit;
|
||||
case TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_AUTH_STATE_FAIL_NO_SIG:
|
||||
case TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_AUTH_STATE_NO_SPDM:
|
||||
EventLogSize = (UINT32)(sizeof (TCG_NV_INDEX_INSTANCE_EVENT_LOG_STRUCT) +
|
||||
sizeof (TCG_DEVICE_SECURITY_EVENT_DATA_HEADER2) +
|
||||
sizeof (UINT64) + DevicePathSize +
|
||||
DeviceContextSize);
|
||||
EventLog = AllocatePool (EventLogSize);
|
||||
if (EventLog == NULL) {
|
||||
SecurityState->AuthenticationState = EDKII_DEVICE_SECURITY_STATE_ERROR_UEFI_OUT_OF_RESOURCE;
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
EventLogPtr = EventLog;
|
||||
|
||||
NvIndexInstance = (VOID *)EventLogPtr;
|
||||
CopyMem (NvIndexInstance->Signature, TCG_NV_EXTEND_INDEX_FOR_INSTANCE_SIGNATURE, sizeof (TCG_NV_EXTEND_INDEX_FOR_INSTANCE_SIGNATURE));
|
||||
NvIndexInstance->Version = TCG_NV_INDEX_INSTANCE_EVENT_LOG_STRUCT_VERSION;
|
||||
ZeroMem (NvIndexInstance->Reserved, sizeof (NvIndexInstance->Reserved));
|
||||
EventLogPtr += sizeof (TCG_NV_INDEX_INSTANCE_EVENT_LOG_STRUCT);
|
||||
|
||||
EventData2 = (VOID *)EventLogPtr;
|
||||
CopyMem (EventData2->Signature, TCG_DEVICE_SECURITY_EVENT_DATA_SIGNATURE_2, sizeof (EventData2->Signature));
|
||||
EventData2->Version = TCG_DEVICE_SECURITY_EVENT_DATA_VERSION_2;
|
||||
EventData2->AuthState = AuthState;
|
||||
EventData2->Reserved = 0;
|
||||
EventData2->Length = (UINT32)EventLogSize;
|
||||
EventData2->DeviceType = GetSpdmDeviceType (SpdmDeviceContext);
|
||||
|
||||
EventData2->SubHeaderType = TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_SUB_HEADER_TYPE_SPDM_CERT_CHAIN;
|
||||
EventData2->SubHeaderLength = 0;
|
||||
EventData2->SubHeaderUID = SpdmDeviceContext->DeviceUID;
|
||||
|
||||
EventLogPtr = (VOID *)(EventData2 + 1);
|
||||
|
||||
*(UINT64 *)EventLogPtr = (UINT64)DevicePathSize;
|
||||
EventLogPtr += sizeof (UINT64);
|
||||
CopyMem (EventLogPtr, SpdmDeviceContext->DevicePath, DevicePathSize);
|
||||
EventLogPtr += DevicePathSize;
|
||||
|
||||
if (DeviceContextSize != 0) {
|
||||
DeviceContext = (VOID *)EventLogPtr;
|
||||
Status = CreateDeviceMeasurementContext (SpdmDeviceContext, DeviceContext, DeviceContextSize);
|
||||
if (Status != EFI_SUCCESS) {
|
||||
SecurityState->AuthenticationState = EDKII_DEVICE_SECURITY_STATE_ERROR_DEVICE_ERROR;
|
||||
Status = EFI_DEVICE_ERROR;
|
||||
goto Exit;
|
||||
}
|
||||
}
|
||||
|
||||
Status = TpmMeasureAndLogData (
|
||||
TCG_NV_EXTEND_INDEX_FOR_INSTANCE,
|
||||
EV_NO_ACTION,
|
||||
EventLog,
|
||||
EventLogSize,
|
||||
EventLog,
|
||||
EventLogSize
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
SecurityState->AuthenticationState = EDKII_DEVICE_SECURITY_STATE_ERROR_TCG_EXTEND_TPM_PCR;
|
||||
}
|
||||
|
||||
DEBUG ((DEBUG_INFO, "TpmMeasureAndLogData (Instance) - %r\n", Status));
|
||||
|
||||
goto Exit;
|
||||
default:
|
||||
SecurityState->AuthenticationState = EDKII_DEVICE_SECURITY_STATE_ERROR_UEFI_UNSUPPORTED;
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
if ((TrustAnchor != NULL) && (TrustAnchorSize != 0)) {
|
||||
SignatureDataSize = sizeof (EFI_GUID) + TrustAnchorSize;
|
||||
SignatureData = AllocateZeroPool (SignatureDataSize);
|
||||
if (SignatureData == NULL) {
|
||||
ASSERT (SignatureData != NULL);
|
||||
SecurityState->AuthenticationState = EDKII_DEVICE_SECURITY_STATE_ERROR_UEFI_OUT_OF_RESOURCE;
|
||||
Status = EFI_OUT_OF_RESOURCES;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
CopyGuid (&SignatureData->SignatureOwner, &gEfiCallerIdGuid);
|
||||
CopyMem (
|
||||
(UINT8 *)SignatureData + sizeof (EFI_GUID),
|
||||
TrustAnchor,
|
||||
TrustAnchorSize
|
||||
);
|
||||
|
||||
MeasureVariable (
|
||||
PCR_INDEX_FOR_SIGNATURE_DB,
|
||||
EV_EFI_SPDM_DEVICE_AUTHORITY,
|
||||
EFI_DEVICE_SECURITY_DATABASE,
|
||||
&gEfiDeviceSignatureDatabaseGuid,
|
||||
SignatureData,
|
||||
SignatureDataSize
|
||||
);
|
||||
FreePool (SignatureData);
|
||||
}
|
||||
|
||||
Exit:
|
||||
if (EventLog != NULL) {
|
||||
FreePool (EventLog);
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
Measure and log Auth state and Requester and responder Nonce into NV Index.
|
||||
|
||||
@param[in] SpdmDeviceContext The SPDM context for the device.
|
||||
@param[in] AuthState The auth state of this deice.
|
||||
@param[in] RequesterNonce A buffer to hold the requester nonce (32 bytes), if not NULL.
|
||||
@param[in] ResponderNonce A buffer to hold the responder nonce (32 bytes), if not NULL.
|
||||
@param[out] SecurityState A pointer to the security state of the requester.
|
||||
|
||||
@retval EFI_SUCCESS Operation completed successfully.
|
||||
@retval EFI_OUT_OF_RESOURCES Out of memory.
|
||||
@retval EFI_DEVICE_ERROR The operation was unsuccessful.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
ExtendAuthentication (
|
||||
IN SPDM_DEVICE_CONTEXT *SpdmDeviceContext,
|
||||
IN UINT8 AuthState,
|
||||
IN UINT8 *RequesterNonce,
|
||||
IN UINT8 *ResponderNonce,
|
||||
OUT EDKII_DEVICE_SECURITY_STATE *SecurityState
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
||||
{
|
||||
TCG_NV_INDEX_DYNAMIC_EVENT_LOG_STRUCT_SPDM_CHALLENGE DynamicEventLogSpdmChallengeEvent;
|
||||
TCG_NV_INDEX_DYNAMIC_EVENT_LOG_STRUCT_SPDM_CHALLENGE_AUTH DynamicEventLogSpdmChallengeAuthEvent;
|
||||
|
||||
CopyMem (DynamicEventLogSpdmChallengeEvent.Header.Signature, TCG_NV_EXTEND_INDEX_FOR_DYNAMIC_SIGNATURE, sizeof (TCG_NV_EXTEND_INDEX_FOR_DYNAMIC_SIGNATURE));
|
||||
DynamicEventLogSpdmChallengeEvent.Header.Version = TCG_NV_INDEX_DYNAMIC_EVENT_LOG_STRUCT_VERSION;
|
||||
ZeroMem (DynamicEventLogSpdmChallengeEvent.Header.Reserved, sizeof (DynamicEventLogSpdmChallengeEvent.Header.Reserved));
|
||||
DynamicEventLogSpdmChallengeEvent.Header.Uid = SpdmDeviceContext->DeviceUID;
|
||||
DynamicEventLogSpdmChallengeEvent.DescriptionSize = sizeof (TCG_SPDM_CHALLENGE_DESCRIPTION);
|
||||
CopyMem (DynamicEventLogSpdmChallengeEvent.Description, TCG_SPDM_CHALLENGE_DESCRIPTION, sizeof (TCG_SPDM_CHALLENGE_DESCRIPTION));
|
||||
DynamicEventLogSpdmChallengeEvent.DataSize = SPDM_NONCE_SIZE;
|
||||
CopyMem (DynamicEventLogSpdmChallengeEvent.Data, RequesterNonce, SPDM_NONCE_SIZE);
|
||||
|
||||
Status = TpmMeasureAndLogData (
|
||||
TCG_NV_EXTEND_INDEX_FOR_DYNAMIC,
|
||||
EV_NO_ACTION,
|
||||
&DynamicEventLogSpdmChallengeEvent,
|
||||
sizeof (DynamicEventLogSpdmChallengeEvent),
|
||||
&DynamicEventLogSpdmChallengeEvent,
|
||||
sizeof (DynamicEventLogSpdmChallengeEvent)
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
SecurityState->AuthenticationState = EDKII_DEVICE_SECURITY_STATE_ERROR_TCG_EXTEND_TPM_PCR;
|
||||
}
|
||||
|
||||
DEBUG ((DEBUG_INFO, "TpmMeasureAndLogData (Dynamic) - %r\n", Status));
|
||||
|
||||
CopyMem (DynamicEventLogSpdmChallengeAuthEvent.Header.Signature, TCG_NV_EXTEND_INDEX_FOR_DYNAMIC_SIGNATURE, sizeof (TCG_NV_EXTEND_INDEX_FOR_DYNAMIC_SIGNATURE));
|
||||
DynamicEventLogSpdmChallengeAuthEvent.Header.Version = TCG_NV_INDEX_DYNAMIC_EVENT_LOG_STRUCT_VERSION;
|
||||
ZeroMem (DynamicEventLogSpdmChallengeAuthEvent.Header.Reserved, sizeof (DynamicEventLogSpdmChallengeAuthEvent.Header.Reserved));
|
||||
DynamicEventLogSpdmChallengeAuthEvent.Header.Uid = SpdmDeviceContext->DeviceUID;
|
||||
DynamicEventLogSpdmChallengeAuthEvent.DescriptionSize = sizeof (TCG_SPDM_CHALLENGE_AUTH_DESCRIPTION);
|
||||
CopyMem (DynamicEventLogSpdmChallengeAuthEvent.Description, TCG_SPDM_CHALLENGE_AUTH_DESCRIPTION, sizeof (TCG_SPDM_CHALLENGE_AUTH_DESCRIPTION));
|
||||
DynamicEventLogSpdmChallengeAuthEvent.DataSize = SPDM_NONCE_SIZE;
|
||||
CopyMem (DynamicEventLogSpdmChallengeAuthEvent.Data, ResponderNonce, SPDM_NONCE_SIZE);
|
||||
|
||||
Status = TpmMeasureAndLogData (
|
||||
TCG_NV_EXTEND_INDEX_FOR_DYNAMIC,
|
||||
EV_NO_ACTION,
|
||||
&DynamicEventLogSpdmChallengeAuthEvent,
|
||||
sizeof (DynamicEventLogSpdmChallengeAuthEvent),
|
||||
&DynamicEventLogSpdmChallengeAuthEvent,
|
||||
sizeof (DynamicEventLogSpdmChallengeAuthEvent)
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
SecurityState->AuthenticationState = EDKII_DEVICE_SECURITY_STATE_ERROR_TCG_EXTEND_TPM_PCR;
|
||||
}
|
||||
|
||||
DEBUG ((DEBUG_INFO, "TpmMeasureAndLogData (Dynamic) - %r\n", Status));
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
This function gets SPDM digest and certificates.
|
||||
|
||||
@param[in] SpdmDeviceContext The SPDM context for the device.
|
||||
@param[out] AuthState The auth state of the devices.
|
||||
@param[out] ValidSlotId The number of slot for the certificate chain.
|
||||
@param[out] SecurityState The security state of the requester.
|
||||
@param[out] IsValidCertChain The validity of the certificate chain.
|
||||
@param[out] RootCertMatch The authority of the certificate chain.
|
||||
|
||||
@retval EFI_SUCCESS Operation completed successfully.
|
||||
@retval EFI_OUT_OF_RESOURCES Out of memory.
|
||||
@retval EFI_DEVICE_ERROR The operation was unsuccessful.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
DoDeviceCertificate (
|
||||
IN SPDM_DEVICE_CONTEXT *SpdmDeviceContext,
|
||||
OUT UINT8 *AuthState,
|
||||
OUT UINT8 *ValidSlotId,
|
||||
OUT EDKII_DEVICE_SECURITY_STATE *SecurityState,
|
||||
OUT BOOLEAN *IsValidCertChain,
|
||||
OUT BOOLEAN *RootCertMatch
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
SPDM_RETURN SpdmReturn;
|
||||
VOID *SpdmContext;
|
||||
UINT32 CapabilityFlags;
|
||||
UINTN DataSize;
|
||||
SPDM_DATA_PARAMETER Parameter;
|
||||
UINT8 SlotMask;
|
||||
UINT8 TotalDigestBuffer[LIBSPDM_MAX_HASH_SIZE * SPDM_MAX_SLOT_COUNT];
|
||||
UINTN CertChainSize;
|
||||
UINT8 CertChain[LIBSPDM_MAX_CERT_CHAIN_SIZE];
|
||||
VOID *TrustAnchor;
|
||||
UINTN TrustAnchorSize;
|
||||
UINT8 SlotId;
|
||||
|
||||
SpdmContext = SpdmDeviceContext->SpdmContext;
|
||||
|
||||
ZeroMem (&Parameter, sizeof (Parameter));
|
||||
Parameter.location = SpdmDataLocationConnection;
|
||||
DataSize = sizeof (CapabilityFlags);
|
||||
SpdmReturn = SpdmGetData (SpdmContext, SpdmDataCapabilityFlags, &Parameter, &CapabilityFlags, &DataSize);
|
||||
if (LIBSPDM_STATUS_IS_ERROR (SpdmReturn)) {
|
||||
SecurityState->AuthenticationState = EDKII_DEVICE_SECURITY_STATE_ERROR_DEVICE_ERROR;
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
*IsValidCertChain = FALSE;
|
||||
*RootCertMatch = FALSE;
|
||||
CertChainSize = sizeof (CertChain);
|
||||
ZeroMem (CertChain, sizeof (CertChain));
|
||||
TrustAnchor = NULL;
|
||||
TrustAnchorSize = 0;
|
||||
|
||||
//
|
||||
// Init *ValidSlotId to invalid slot_id
|
||||
//
|
||||
*ValidSlotId = SPDM_MAX_SLOT_COUNT;
|
||||
|
||||
if ((CapabilityFlags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP) == 0) {
|
||||
*AuthState = TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_AUTH_STATE_FAIL_NO_SIG;
|
||||
SecurityState->AuthenticationState = EDKII_DEVICE_SECURITY_STATE_ERROR_DEVICE_NO_CAPABILITIES;
|
||||
Status = ExtendCertificate (SpdmDeviceContext, *AuthState, 0, NULL, NULL, 0, 0, SecurityState);
|
||||
return Status;
|
||||
} else {
|
||||
ZeroMem (TotalDigestBuffer, sizeof (TotalDigestBuffer));
|
||||
SpdmReturn = SpdmGetDigest (SpdmContext, NULL, &SlotMask, TotalDigestBuffer);
|
||||
if ((LIBSPDM_STATUS_IS_ERROR (SpdmReturn)) || ((SlotMask & 0x01) == 0)) {
|
||||
*AuthState = TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_AUTH_STATE_FAIL_INVALID;
|
||||
SecurityState->AuthenticationState = EDKII_DEVICE_SECURITY_STATE_ERROR_CERTIFIACTE_FAILURE;
|
||||
SlotId = 0;
|
||||
Status = ExtendCertificate (SpdmDeviceContext, *AuthState, 0, NULL, NULL, 0, SlotId, SecurityState);
|
||||
return Status;
|
||||
}
|
||||
|
||||
for (SlotId = 0; SlotId < SPDM_MAX_SLOT_COUNT; SlotId++) {
|
||||
if (((SlotMask >> SlotId) & 0x01) == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
CertChainSize = sizeof (CertChain);
|
||||
ZeroMem (CertChain, sizeof (CertChain));
|
||||
SpdmReturn = SpdmGetCertificateEx (SpdmContext, NULL, SlotId, &CertChainSize, CertChain, (CONST VOID **)&TrustAnchor, &TrustAnchorSize);
|
||||
if (LIBSPDM_STATUS_IS_SUCCESS (SpdmReturn)) {
|
||||
*IsValidCertChain = TRUE;
|
||||
break;
|
||||
} else if (SpdmReturn == LIBSPDM_STATUS_VERIF_FAIL) {
|
||||
*IsValidCertChain = FALSE;
|
||||
*AuthState = TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_AUTH_STATE_FAIL_INVALID;
|
||||
SecurityState->AuthenticationState = EDKII_DEVICE_SECURITY_STATE_ERROR_CERTIFIACTE_FAILURE;
|
||||
Status = ExtendCertificate (SpdmDeviceContext, *AuthState, 0, NULL, NULL, 0, SlotId, SecurityState);
|
||||
} else if (SpdmReturn == LIBSPDM_STATUS_VERIF_NO_AUTHORITY) {
|
||||
*IsValidCertChain = TRUE;
|
||||
*AuthState = TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_AUTH_STATE_NO_AUTH;
|
||||
SecurityState->AuthenticationState = EDKII_DEVICE_SECURITY_STATE_ERROR_CERTIFIACTE_FAILURE;
|
||||
*ValidSlotId = SlotId;
|
||||
}
|
||||
}
|
||||
|
||||
if ((SlotId >= SPDM_MAX_SLOT_COUNT) && (*ValidSlotId == SPDM_MAX_SLOT_COUNT)) {
|
||||
SecurityState->AuthenticationState = EDKII_DEVICE_SECURITY_STATE_ERROR_DEVICE_ERROR;
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
if (TrustAnchor != NULL) {
|
||||
*RootCertMatch = TRUE;
|
||||
*ValidSlotId = SlotId;
|
||||
} else {
|
||||
*ValidSlotId = 0;
|
||||
}
|
||||
|
||||
DEBUG ((DEBUG_INFO, "SpdmGetCertificateEx - SpdmReturn %p, TrustAnchorSize 0x%x, RootCertMatch %d\n", SpdmReturn, TrustAnchorSize, *RootCertMatch));
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
This function does authentication.
|
||||
|
||||
@param[in] SpdmDeviceContext The SPDM context for the device.
|
||||
@param[out] AuthState The auth state of the devices.
|
||||
@param[in] ValidSlotId The number of slot for the certificate chain.
|
||||
@param[in] IsValidCertChain Indicate the validity of CertChain
|
||||
@param[in] RootCertMatch Indicate the match or mismatch for Rootcert
|
||||
@param[out] SecurityState The security state of the requester.
|
||||
|
||||
@retval EFI_SUCCESS Operation completed successfully.
|
||||
@retval EFI_OUT_OF_RESOURCES Out of memory.
|
||||
@retval EFI_DEVICE_ERROR The operation was unsuccessful.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
DoDeviceAuthentication (
|
||||
IN SPDM_DEVICE_CONTEXT *SpdmDeviceContext,
|
||||
OUT UINT8 *AuthState,
|
||||
IN UINT8 ValidSlotId,
|
||||
IN BOOLEAN IsValidCertChain,
|
||||
IN BOOLEAN RootCertMatch,
|
||||
OUT EDKII_DEVICE_SECURITY_STATE *SecurityState
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
SPDM_RETURN SpdmReturn;
|
||||
VOID *SpdmContext;
|
||||
UINT32 CapabilityFlags;
|
||||
UINTN DataSize;
|
||||
SPDM_DATA_PARAMETER Parameter;
|
||||
UINTN CertChainSize;
|
||||
UINT8 CertChain[LIBSPDM_MAX_CERT_CHAIN_SIZE];
|
||||
UINT8 RequesterNonce[SPDM_NONCE_SIZE];
|
||||
UINT8 ResponderNonce[SPDM_NONCE_SIZE];
|
||||
VOID *TrustAnchor;
|
||||
UINTN TrustAnchorSize;
|
||||
BOOLEAN IsValidChallengeAuthSig;
|
||||
|
||||
SpdmContext = SpdmDeviceContext->SpdmContext;
|
||||
|
||||
ZeroMem (&Parameter, sizeof (Parameter));
|
||||
Parameter.location = SpdmDataLocationConnection;
|
||||
DataSize = sizeof (CapabilityFlags);
|
||||
SpdmReturn = SpdmGetData (SpdmContext, SpdmDataCapabilityFlags, &Parameter, &CapabilityFlags, &DataSize);
|
||||
if (LIBSPDM_STATUS_IS_ERROR (SpdmReturn)) {
|
||||
SecurityState->AuthenticationState = EDKII_DEVICE_SECURITY_STATE_ERROR_DEVICE_ERROR;
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
IsValidChallengeAuthSig = FALSE;
|
||||
|
||||
// get the valid CertChain
|
||||
CertChainSize = sizeof (CertChain);
|
||||
ZeroMem (CertChain, sizeof (CertChain));
|
||||
SpdmReturn = SpdmGetCertificateEx (SpdmContext, NULL, ValidSlotId, &CertChainSize, CertChain, (CONST VOID **)&TrustAnchor, &TrustAnchorSize);
|
||||
if ((!LIBSPDM_STATUS_IS_SUCCESS (SpdmReturn)) && (!(SpdmReturn == LIBSPDM_STATUS_VERIF_NO_AUTHORITY))) {
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
if ((CapabilityFlags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CHAL_CAP) == 0) {
|
||||
*AuthState = TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_AUTH_STATE_NO_BINDING;
|
||||
SecurityState->AuthenticationState = EDKII_DEVICE_SECURITY_STATE_ERROR_DEVICE_NO_CAPABILITIES;
|
||||
Status = ExtendCertificate (SpdmDeviceContext, *AuthState, CertChainSize, CertChain, NULL, 0, ValidSlotId, SecurityState);
|
||||
return Status;
|
||||
} else {
|
||||
ZeroMem (RequesterNonce, sizeof (RequesterNonce));
|
||||
ZeroMem (ResponderNonce, sizeof (ResponderNonce));
|
||||
SpdmReturn = SpdmChallengeEx (SpdmContext, NULL, ValidSlotId, SPDM_CHALLENGE_REQUEST_NO_MEASUREMENT_SUMMARY_HASH, NULL, NULL, NULL, RequesterNonce, ResponderNonce, NULL, 0);
|
||||
if (SpdmReturn == LIBSPDM_STATUS_SUCCESS) {
|
||||
IsValidChallengeAuthSig = TRUE;
|
||||
} else if ((LIBSPDM_STATUS_IS_ERROR (SpdmReturn))) {
|
||||
IsValidChallengeAuthSig = FALSE;
|
||||
*AuthState = TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_AUTH_STATE_FAIL_INVALID;
|
||||
SecurityState->AuthenticationState = EDKII_DEVICE_SECURITY_STATE_ERROR_CHALLENGE_FAILURE;
|
||||
Status = ExtendCertificate (SpdmDeviceContext, *AuthState, 0, NULL, NULL, 0, ValidSlotId, SecurityState);
|
||||
return Status;
|
||||
} else {
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
if (IsValidCertChain && IsValidChallengeAuthSig && !RootCertMatch) {
|
||||
*AuthState = TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_AUTH_STATE_NO_AUTH;
|
||||
SecurityState->AuthenticationState = EDKII_DEVICE_SECURITY_STATE_ERROR_NO_CERT_PROVISION;
|
||||
Status = ExtendCertificate (SpdmDeviceContext, *AuthState, CertChainSize, CertChain, NULL, 0, ValidSlotId, SecurityState);
|
||||
} else if (IsValidCertChain && IsValidChallengeAuthSig && RootCertMatch) {
|
||||
*AuthState = TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_AUTH_STATE_SUCCESS;
|
||||
SecurityState->AuthenticationState = EDKII_DEVICE_SECURITY_STATE_SUCCESS;
|
||||
Status = ExtendCertificate (SpdmDeviceContext, *AuthState, CertChainSize, CertChain, TrustAnchor, TrustAnchorSize, ValidSlotId, SecurityState);
|
||||
}
|
||||
|
||||
Status = ExtendAuthentication (SpdmDeviceContext, *AuthState, RequesterNonce, ResponderNonce, SecurityState);
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
481
SecurityPkg/DeviceSecurity/SpdmSecurityLib/SpdmConnectionInit.c
Normal file
481
SecurityPkg/DeviceSecurity/SpdmSecurityLib/SpdmConnectionInit.c
Normal file
@ -0,0 +1,481 @@
|
||||
/** @file
|
||||
EDKII Device Security library for SPDM device.
|
||||
It follows the SPDM Specification.
|
||||
|
||||
Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
**/
|
||||
|
||||
#include "SpdmSecurityLibInternal.h"
|
||||
|
||||
LIST_ENTRY mSpdmDeviceContextList = INITIALIZE_LIST_HEAD_VARIABLE (mSpdmDeviceContextList);
|
||||
|
||||
#define CONNECTUIN_FAILURE_GET_SPDM_UID_FAILED "Fail to get Spdm Uid"
|
||||
#define CONNECTUIN_FAILURE_STGNATURE_DB_FUL_STRING "The Signature database devdb is full"
|
||||
|
||||
/**
|
||||
record Spdm Io protocol into the context list.
|
||||
|
||||
@param[in] SpdmDeviceContext The SPDM context of the device.
|
||||
|
||||
**/
|
||||
VOID
|
||||
RecordSpdmDeviceContextInList (
|
||||
IN SPDM_DEVICE_CONTEXT *SpdmDeviceContext
|
||||
)
|
||||
{
|
||||
SPDM_DEVICE_CONTEXT_INSTANCE *NewSpdmDeviceContext;
|
||||
LIST_ENTRY *SpdmDeviceContextList;
|
||||
|
||||
SpdmDeviceContextList = &mSpdmDeviceContextList;
|
||||
|
||||
NewSpdmDeviceContext = AllocateZeroPool (sizeof (*NewSpdmDeviceContext));
|
||||
if (NewSpdmDeviceContext == NULL) {
|
||||
ASSERT (NewSpdmDeviceContext != NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
NewSpdmDeviceContext->Signature = SPDM_DEVICE_CONTEXT_INSTANCE_SIGNATURE;
|
||||
NewSpdmDeviceContext->SpdmDeviceContext = SpdmDeviceContext;
|
||||
|
||||
InsertTailList (SpdmDeviceContextList, &NewSpdmDeviceContext->Link);
|
||||
}
|
||||
|
||||
/**
|
||||
get Spdm Io protocol from Context list via spdm context.
|
||||
|
||||
@param[in] SpdmContext The SPDM context of the requester.
|
||||
|
||||
return a pointer to the Spdm Io protocol.
|
||||
|
||||
**/
|
||||
VOID *
|
||||
EFIAPI
|
||||
GetSpdmIoProtocolViaSpdmContext (
|
||||
IN VOID *SpdmContext
|
||||
)
|
||||
{
|
||||
LIST_ENTRY *Link;
|
||||
SPDM_DEVICE_CONTEXT_INSTANCE *CurrentSpdmDeviceContext;
|
||||
LIST_ENTRY *SpdmDeviceContextList;
|
||||
|
||||
SpdmDeviceContextList = &mSpdmDeviceContextList;
|
||||
|
||||
Link = GetFirstNode (SpdmDeviceContextList);
|
||||
while (!IsNull (SpdmDeviceContextList, Link)) {
|
||||
CurrentSpdmDeviceContext = SPDM_DEVICE_CONTEXT_INSTANCE_FROM_LINK (Link);
|
||||
|
||||
if (CurrentSpdmDeviceContext->SpdmDeviceContext->SpdmContext == SpdmContext) {
|
||||
return CurrentSpdmDeviceContext->SpdmDeviceContext->SpdmIoProtocol;
|
||||
}
|
||||
|
||||
Link = GetNextNode (SpdmDeviceContextList, Link);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
creates and returns Spdm Uid from the volatile variable.
|
||||
|
||||
@param[in] SpdmUid A pointer to Spdm Uid.
|
||||
|
||||
@retval EFI_SUCCESS Operation completed successfully.
|
||||
@retval EFI_OUT_OF_RESOURCES Out of memory.
|
||||
@retval EFI_DEVICE_ERROR The operation was unsuccessful.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
GetSpdmUid (
|
||||
UINT64 *SpdmUid
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINTN VarSize;
|
||||
UINT64 Uid;
|
||||
|
||||
VarSize = sizeof (*SpdmUid);
|
||||
Status = gRT->GetVariable (
|
||||
L"SpdmUid",
|
||||
&gEfiDeviceSecuritySpdmUidGuid,
|
||||
NULL,
|
||||
&VarSize,
|
||||
&Uid
|
||||
);
|
||||
if (Status == EFI_NOT_FOUND) {
|
||||
Uid = 0;
|
||||
} else if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
*SpdmUid = Uid++;
|
||||
Status = gRT->SetVariable (
|
||||
L"SpdmUid",
|
||||
&gEfiDeviceSecuritySpdmUidGuid,
|
||||
EFI_VARIABLE_BOOTSERVICE_ACCESS,
|
||||
sizeof (Uid),
|
||||
&Uid
|
||||
);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
Record and log the connection failure string to PCR1.
|
||||
|
||||
@param[in] FailureString The failure string.
|
||||
@param[in] StringLen The length of the string.
|
||||
|
||||
@retval EFI_SUCCESS Operation completed successfully.
|
||||
@retval EFI_OUT_OF_RESOURCES Out of memory.
|
||||
@retval EFI_DEVICE_ERROR The operation was unsuccessful.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
RecordConnectionFailureStatus (
|
||||
IN CHAR8 *FailureString,
|
||||
IN UINT32 StringLen
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
||||
Status = TpmMeasureAndLogData (
|
||||
1,
|
||||
EV_PLATFORM_CONFIG_FLAGS,
|
||||
FailureString,
|
||||
StringLen,
|
||||
FailureString,
|
||||
StringLen
|
||||
);
|
||||
DEBUG ((DEBUG_INFO, "RecordConnectionFailureStatus %r\n", Status));
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
This function creates the spdm device context and init connection to the
|
||||
responder with the device info.
|
||||
|
||||
@param[in] SpdmDeviceInfo A pointer to device info.
|
||||
@param[out] SecurityState A pointer to the security state of the requester.
|
||||
|
||||
@return the spdm device conext after the init connection succeeds.
|
||||
|
||||
**/
|
||||
SPDM_DEVICE_CONTEXT *
|
||||
EFIAPI
|
||||
CreateSpdmDeviceContext (
|
||||
IN EDKII_SPDM_DEVICE_INFO *SpdmDeviceInfo,
|
||||
OUT EDKII_DEVICE_SECURITY_STATE *SecurityState
|
||||
)
|
||||
{
|
||||
SPDM_DEVICE_CONTEXT *SpdmDeviceContext;
|
||||
VOID *SpdmContext;
|
||||
UINTN SpdmContextSize;
|
||||
VOID *ScratchBuffer;
|
||||
UINTN ScratchBufferSize;
|
||||
EFI_STATUS Status;
|
||||
SPDM_RETURN SpdmReturn;
|
||||
EFI_SIGNATURE_LIST *DbList;
|
||||
EFI_SIGNATURE_DATA *Cert;
|
||||
UINTN CertCount;
|
||||
UINTN Index;
|
||||
UINTN SiglistHeaderSize;
|
||||
UINTN DbSize;
|
||||
VOID *Data;
|
||||
UINTN DataSize;
|
||||
SPDM_DATA_PARAMETER Parameter;
|
||||
UINT8 Data8;
|
||||
UINT16 Data16;
|
||||
UINT32 Data32;
|
||||
UINT8 AuthState;
|
||||
|
||||
SpdmDeviceContext = AllocateZeroPool (sizeof (*SpdmDeviceContext));
|
||||
if (SpdmDeviceContext == NULL) {
|
||||
ASSERT (SpdmDeviceContext != NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SpdmDeviceContext->Signature = SPDM_DEVICE_CONTEXT_SIGNATURE;
|
||||
CopyMem (&SpdmDeviceContext->DeviceId, SpdmDeviceInfo->DeviceId, sizeof (EDKII_DEVICE_IDENTIFIER));
|
||||
SpdmDeviceContext->IsEmbeddedDevice = SpdmDeviceInfo->IsEmbeddedDevice;
|
||||
|
||||
SpdmContextSize = SpdmGetContextSize ();
|
||||
SpdmContext = AllocateZeroPool (SpdmContextSize);
|
||||
if (SpdmContext == NULL) {
|
||||
ASSERT (SpdmContext != NULL);
|
||||
goto Error;
|
||||
}
|
||||
|
||||
SpdmReturn = SpdmInitContext (SpdmContext);
|
||||
if (LIBSPDM_STATUS_IS_ERROR (SpdmReturn)) {
|
||||
goto Error;
|
||||
}
|
||||
|
||||
SpdmRegisterDeviceIoFunc (
|
||||
SpdmContext,
|
||||
SpdmDeviceInfo->SendMessage,
|
||||
SpdmDeviceInfo->ReceiveMessage
|
||||
);
|
||||
SpdmRegisterTransportLayerFunc (
|
||||
SpdmContext,
|
||||
SpdmDeviceInfo->MaxSpdmMsgSize,
|
||||
SpdmDeviceInfo->TransportHeaderSize,
|
||||
SpdmDeviceInfo->TransportTailSize,
|
||||
SpdmDeviceInfo->TransportEncodeMessage,
|
||||
SpdmDeviceInfo->TransportDecodeMessage
|
||||
);
|
||||
|
||||
SpdmRegisterDeviceBufferFunc (
|
||||
SpdmContext,
|
||||
SpdmDeviceInfo->SenderBufferSize,
|
||||
SpdmDeviceInfo->ReceiverBufferSize,
|
||||
SpdmDeviceInfo->AcquireSenderBuffer,
|
||||
SpdmDeviceInfo->ReleaseSenderBuffer,
|
||||
SpdmDeviceInfo->AcquireReceiverBuffer,
|
||||
SpdmDeviceInfo->ReleaseReceiverBuffer
|
||||
);
|
||||
|
||||
ScratchBufferSize = SpdmGetSizeofRequiredScratchBuffer (SpdmContext);
|
||||
ScratchBuffer = AllocateZeroPool (ScratchBufferSize);
|
||||
if (ScratchBuffer == NULL) {
|
||||
ASSERT (ScratchBuffer != NULL);
|
||||
goto Error;
|
||||
}
|
||||
|
||||
SpdmSetScratchBuffer (SpdmContext, ScratchBuffer, ScratchBufferSize);
|
||||
|
||||
SpdmDeviceContext->SpdmContextSize = SpdmContextSize;
|
||||
SpdmDeviceContext->SpdmContext = SpdmContext;
|
||||
SpdmDeviceContext->ScratchBufferSize = ScratchBufferSize;
|
||||
SpdmDeviceContext->ScratchBuffer = ScratchBuffer;
|
||||
|
||||
Status = gBS->HandleProtocol (
|
||||
SpdmDeviceContext->DeviceId.DeviceHandle,
|
||||
&gEfiDevicePathProtocolGuid,
|
||||
(VOID **)&SpdmDeviceContext->DevicePath
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((DEBUG_ERROR, "Locate - DevicePath - %r\n", Status));
|
||||
goto Error;
|
||||
}
|
||||
|
||||
Status = gBS->HandleProtocol (
|
||||
SpdmDeviceContext->DeviceId.DeviceHandle,
|
||||
&SpdmDeviceContext->DeviceId.DeviceType,
|
||||
(VOID **)&SpdmDeviceContext->DeviceIo
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((DEBUG_ERROR, "Locate - DeviceIo - %r\n", Status));
|
||||
// This is optional, only check known device type later.
|
||||
}
|
||||
|
||||
if (SpdmDeviceInfo->SpdmIoProtocolGuid != NULL) {
|
||||
Status = gBS->HandleProtocol (
|
||||
SpdmDeviceContext->DeviceId.DeviceHandle,
|
||||
SpdmDeviceInfo->SpdmIoProtocolGuid,
|
||||
(VOID **)&SpdmDeviceContext->SpdmIoProtocol
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((DEBUG_ERROR, "Locate - SpdmIoProtocol - %r\n", Status));
|
||||
goto Error;
|
||||
}
|
||||
}
|
||||
|
||||
if (CompareGuid (&SpdmDeviceContext->DeviceId.DeviceType, &gEdkiiDeviceIdentifierTypePciGuid)) {
|
||||
if (SpdmDeviceContext->DeviceIo == NULL) {
|
||||
DEBUG ((DEBUG_ERROR, "Locate - PciIo - %r\n", Status));
|
||||
goto Error;
|
||||
}
|
||||
}
|
||||
|
||||
Status = GetSpdmUid (&SpdmDeviceContext->DeviceUID);
|
||||
if (EFI_ERROR (Status)) {
|
||||
Status = RecordConnectionFailureStatus (
|
||||
CONNECTUIN_FAILURE_GET_SPDM_UID_FAILED,
|
||||
sizeof (CONNECTUIN_FAILURE_GET_SPDM_UID_FAILED)
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto Error;
|
||||
}
|
||||
|
||||
ASSERT (FALSE);
|
||||
DEBUG ((DEBUG_ERROR, "Fail to get UID - %r\n", Status));
|
||||
goto Error;
|
||||
}
|
||||
|
||||
RecordSpdmDeviceContextInList (SpdmDeviceContext);
|
||||
|
||||
Status = GetVariable2 (
|
||||
EFI_DEVICE_SECURITY_DATABASE,
|
||||
&gEfiDeviceSignatureDatabaseGuid,
|
||||
(VOID **)&SpdmDeviceContext->SignatureList,
|
||||
&SpdmDeviceContext->SignatureListSize
|
||||
);
|
||||
if ((!EFI_ERROR (Status)) && (SpdmDeviceContext->SignatureList != NULL)) {
|
||||
DbList = SpdmDeviceContext->SignatureList;
|
||||
DbSize = SpdmDeviceContext->SignatureListSize;
|
||||
while ((DbSize > 0) && (SpdmDeviceContext->SignatureListSize >= DbList->SignatureListSize)) {
|
||||
if (DbList->SignatureListSize == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
if ( (!CompareGuid (&DbList->SignatureType, &gEfiCertX509Guid))
|
||||
|| (DbList->SignatureHeaderSize != 0)
|
||||
|| (DbList->SignatureSize < sizeof (EFI_SIGNATURE_DATA)))
|
||||
{
|
||||
DbSize -= DbList->SignatureListSize;
|
||||
DbList = (EFI_SIGNATURE_LIST *)((UINT8 *)DbList + DbList->SignatureListSize);
|
||||
continue;
|
||||
}
|
||||
|
||||
SiglistHeaderSize = sizeof (EFI_SIGNATURE_LIST) + DbList->SignatureHeaderSize;
|
||||
Cert = (EFI_SIGNATURE_DATA *)((UINT8 *)DbList + SiglistHeaderSize);
|
||||
CertCount = (DbList->SignatureListSize - SiglistHeaderSize) / DbList->SignatureSize;
|
||||
|
||||
for (Index = 0; Index < CertCount; Index++) {
|
||||
Data = Cert->SignatureData;
|
||||
DataSize = DbList->SignatureSize - sizeof (EFI_GUID);
|
||||
|
||||
ZeroMem (&Parameter, sizeof (Parameter));
|
||||
Parameter.location = SpdmDataLocationLocal;
|
||||
SpdmReturn = SpdmSetData (SpdmContext, SpdmDataPeerPublicRootCert, &Parameter, Data, DataSize);
|
||||
if (LIBSPDM_STATUS_IS_ERROR (SpdmReturn)) {
|
||||
if (SpdmReturn == LIBSPDM_STATUS_BUFFER_FULL) {
|
||||
Status = RecordConnectionFailureStatus (
|
||||
CONNECTUIN_FAILURE_STGNATURE_DB_FUL_STRING,
|
||||
sizeof (CONNECTUIN_FAILURE_STGNATURE_DB_FUL_STRING)
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto Error;
|
||||
}
|
||||
|
||||
ASSERT (FALSE);
|
||||
}
|
||||
|
||||
goto Error;
|
||||
}
|
||||
|
||||
Cert = (EFI_SIGNATURE_DATA *)((UINT8 *)Cert + DbList->SignatureSize);
|
||||
}
|
||||
|
||||
DbSize -= DbList->SignatureListSize;
|
||||
DbList = (EFI_SIGNATURE_LIST *)((UINT8 *)DbList + DbList->SignatureListSize);
|
||||
}
|
||||
}
|
||||
|
||||
Data8 = 0;
|
||||
ZeroMem (&Parameter, sizeof (Parameter));
|
||||
Parameter.location = SpdmDataLocationLocal;
|
||||
SpdmReturn = SpdmSetData (SpdmContext, SpdmDataCapabilityCTExponent, &Parameter, &Data8, sizeof (Data8));
|
||||
if (LIBSPDM_STATUS_IS_ERROR (SpdmReturn)) {
|
||||
ASSERT (FALSE);
|
||||
goto Error;
|
||||
}
|
||||
|
||||
Data32 = 0;
|
||||
SpdmReturn = SpdmSetData (SpdmContext, SpdmDataCapabilityFlags, &Parameter, &Data32, sizeof (Data32));
|
||||
if (LIBSPDM_STATUS_IS_ERROR (SpdmReturn)) {
|
||||
ASSERT (FALSE);
|
||||
goto Error;
|
||||
}
|
||||
|
||||
Data8 = SPDM_MEASUREMENT_SPECIFICATION_DMTF;
|
||||
SpdmReturn = SpdmSetData (SpdmContext, SpdmDataMeasurementSpec, &Parameter, &Data8, sizeof (Data8));
|
||||
if (LIBSPDM_STATUS_IS_ERROR (SpdmReturn)) {
|
||||
ASSERT (FALSE);
|
||||
goto Error;
|
||||
}
|
||||
|
||||
if (SpdmDeviceInfo->BaseAsymAlgo != 0) {
|
||||
Data32 = SpdmDeviceInfo->BaseAsymAlgo;
|
||||
} else {
|
||||
Data32 = SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_2048 |
|
||||
SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_3072 |
|
||||
SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_4096 |
|
||||
SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P256 |
|
||||
SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P384 |
|
||||
SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P521;
|
||||
}
|
||||
|
||||
SpdmReturn = SpdmSetData (SpdmContext, SpdmDataBaseAsymAlgo, &Parameter, &Data32, sizeof (Data32));
|
||||
if (LIBSPDM_STATUS_IS_ERROR (SpdmReturn)) {
|
||||
ASSERT (FALSE);
|
||||
goto Error;
|
||||
}
|
||||
|
||||
if (SpdmDeviceInfo->BaseHashAlgo != 0) {
|
||||
Data32 = SpdmDeviceInfo->BaseHashAlgo;
|
||||
} else {
|
||||
Data32 = SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA_256 |
|
||||
SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA_384 |
|
||||
SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA_512;
|
||||
}
|
||||
|
||||
SpdmReturn = SpdmSetData (SpdmContext, SpdmDataBaseHashAlgo, &Parameter, &Data32, sizeof (Data32));
|
||||
if (LIBSPDM_STATUS_IS_ERROR (SpdmReturn)) {
|
||||
ASSERT (FALSE);
|
||||
goto Error;
|
||||
}
|
||||
|
||||
SpdmReturn = SpdmInitConnection (SpdmContext, FALSE);
|
||||
if (LIBSPDM_STATUS_IS_ERROR (SpdmReturn)) {
|
||||
DEBUG ((DEBUG_ERROR, "SpdmInitConnection - %p\n", SpdmReturn));
|
||||
|
||||
AuthState = TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_AUTH_STATE_NO_SPDM;
|
||||
SecurityState->AuthenticationState = EDKII_DEVICE_SECURITY_STATE_ERROR_DEVICE_NO_CAPABILITIES;
|
||||
Status = ExtendCertificate (SpdmDeviceContext, AuthState, 0, NULL, NULL, 0, 0, SecurityState);
|
||||
if (Status != EFI_SUCCESS) {
|
||||
DEBUG ((DEBUG_ERROR, "ExtendCertificate AUTH_STATE_NO_SPDM failed\n"));
|
||||
}
|
||||
|
||||
goto Error;
|
||||
}
|
||||
|
||||
ZeroMem (&Parameter, sizeof (Parameter));
|
||||
Parameter.location = SpdmDataLocationConnection;
|
||||
DataSize = sizeof (Data16);
|
||||
SpdmReturn = SpdmGetData (SpdmContext, SpdmDataSpdmVersion, &Parameter, &Data16, &DataSize);
|
||||
if (LIBSPDM_STATUS_IS_ERROR (SpdmReturn)) {
|
||||
DEBUG ((DEBUG_ERROR, "SpdmGetData - %p\n", SpdmReturn));
|
||||
goto Error;
|
||||
}
|
||||
|
||||
SpdmDeviceContext->SpdmVersion = (Data16 >> SPDM_VERSION_NUMBER_SHIFT_BIT);
|
||||
|
||||
return SpdmDeviceContext;
|
||||
Error:
|
||||
DestroySpdmDeviceContext (SpdmDeviceContext);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
This function destories the spdm device context.
|
||||
|
||||
@param[in] SpdmDeviceContext A pointer to device info.
|
||||
|
||||
**/
|
||||
VOID
|
||||
EFIAPI
|
||||
DestroySpdmDeviceContext (
|
||||
IN SPDM_DEVICE_CONTEXT *SpdmDeviceContext
|
||||
)
|
||||
{
|
||||
// need zero memory in case of secret in memory.
|
||||
if (SpdmDeviceContext->SpdmContext != NULL) {
|
||||
ZeroMem (SpdmDeviceContext->SpdmContext, SpdmDeviceContext->SpdmContextSize);
|
||||
FreePool (SpdmDeviceContext->SpdmContext);
|
||||
}
|
||||
|
||||
if (SpdmDeviceContext->ScratchBuffer != NULL) {
|
||||
ZeroMem (SpdmDeviceContext->ScratchBuffer, SpdmDeviceContext->ScratchBufferSize);
|
||||
FreePool (SpdmDeviceContext->ScratchBuffer);
|
||||
}
|
||||
|
||||
if (SpdmDeviceContext->SignatureList != NULL) {
|
||||
ZeroMem (SpdmDeviceContext->SignatureList, SpdmDeviceContext->SignatureListSize);
|
||||
FreePool (SpdmDeviceContext->SignatureList);
|
||||
}
|
||||
|
||||
FreePool (SpdmDeviceContext);
|
||||
}
|
714
SecurityPkg/DeviceSecurity/SpdmSecurityLib/SpdmMeasurement.c
Normal file
714
SecurityPkg/DeviceSecurity/SpdmSecurityLib/SpdmMeasurement.c
Normal file
@ -0,0 +1,714 @@
|
||||
/** @file
|
||||
EDKII Device Security library for SPDM device.
|
||||
It follows the SPDM Specification.
|
||||
|
||||
Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
**/
|
||||
|
||||
#include "SpdmSecurityLibInternal.h"
|
||||
|
||||
/**
|
||||
This function returns the SPDM device type for TCG SPDM event.
|
||||
|
||||
@param[in] SpdmDeviceContext The SPDM context for the device.
|
||||
|
||||
@return TCG SPDM device type
|
||||
**/
|
||||
UINT32
|
||||
EFIAPI
|
||||
GetSpdmDeviceType (
|
||||
IN SPDM_DEVICE_CONTEXT *SpdmDeviceContext
|
||||
)
|
||||
{
|
||||
if (CompareGuid (&SpdmDeviceContext->DeviceId.DeviceType, &gEdkiiDeviceIdentifierTypePciGuid)) {
|
||||
return TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_TYPE_PCI;
|
||||
}
|
||||
|
||||
if (CompareGuid (&SpdmDeviceContext->DeviceId.DeviceType, &gEdkiiDeviceIdentifierTypeUsbGuid)) {
|
||||
return TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_TYPE_USB;
|
||||
}
|
||||
|
||||
return TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_TYPE_NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
This function returns the SPDM device measurement context size for TCG SPDM event.
|
||||
|
||||
@param[in] SpdmDeviceContext The SPDM context for the device.
|
||||
|
||||
@return TCG SPDM device measurement context size
|
||||
**/
|
||||
UINTN
|
||||
EFIAPI
|
||||
GetDeviceMeasurementContextSize (
|
||||
IN SPDM_DEVICE_CONTEXT *SpdmDeviceContext
|
||||
)
|
||||
{
|
||||
if (CompareGuid (&SpdmDeviceContext->DeviceId.DeviceType, &gEdkiiDeviceIdentifierTypePciGuid)) {
|
||||
return sizeof (TCG_DEVICE_SECURITY_EVENT_DATA_PCI_CONTEXT);
|
||||
}
|
||||
|
||||
if (CompareGuid (&SpdmDeviceContext->DeviceId.DeviceType, &gEdkiiDeviceIdentifierTypeUsbGuid)) {
|
||||
// TBD - usb context
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
This function creates the SPDM PCI device measurement context for TCG SPDM event.
|
||||
|
||||
@param[in] SpdmDeviceContext The SPDM context for the device.
|
||||
@param[in, out] DeviceContext The TCG SPDM PCI device measurement context.
|
||||
@param[in] DeviceContextSize The size of TCG SPDM PCI device measurement context.
|
||||
|
||||
@retval EFI_SUCCESS The TCG SPDM PCI device measurement context is returned.
|
||||
**/
|
||||
EFI_STATUS
|
||||
CreatePciDeviceMeasurementContext (
|
||||
IN SPDM_DEVICE_CONTEXT *SpdmDeviceContext,
|
||||
IN OUT VOID *DeviceContext,
|
||||
IN UINTN DeviceContextSize
|
||||
)
|
||||
{
|
||||
TCG_DEVICE_SECURITY_EVENT_DATA_PCI_CONTEXT *PciContext;
|
||||
PCI_TYPE00 PciData;
|
||||
EFI_PCI_IO_PROTOCOL *PciIo;
|
||||
EFI_STATUS Status;
|
||||
|
||||
if (DeviceContextSize != sizeof (*PciContext)) {
|
||||
return EFI_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
PciIo = SpdmDeviceContext->DeviceIo;
|
||||
Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint8, 0, sizeof (PciData), &PciData);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
PciContext = DeviceContext;
|
||||
PciContext->Version = TCG_DEVICE_SECURITY_EVENT_DATA_PCI_CONTEXT_VERSION;
|
||||
PciContext->Length = sizeof (*PciContext);
|
||||
PciContext->VendorId = PciData.Hdr.VendorId;
|
||||
PciContext->DeviceId = PciData.Hdr.DeviceId;
|
||||
PciContext->RevisionID = PciData.Hdr.RevisionID;
|
||||
PciContext->ClassCode[0] = PciData.Hdr.ClassCode[0];
|
||||
PciContext->ClassCode[1] = PciData.Hdr.ClassCode[1];
|
||||
PciContext->ClassCode[2] = PciData.Hdr.ClassCode[2];
|
||||
if ((PciData.Hdr.HeaderType & HEADER_LAYOUT_CODE) == HEADER_TYPE_DEVICE) {
|
||||
PciContext->SubsystemVendorID = PciData.Device.SubsystemVendorID;
|
||||
PciContext->SubsystemID = PciData.Device.SubsystemID;
|
||||
} else {
|
||||
PciContext->SubsystemVendorID = 0;
|
||||
PciContext->SubsystemID = 0;
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
This function creates the SPDM device measurement context for TCG SPDM event.
|
||||
|
||||
@param[in] SpdmDeviceContext The SPDM context for the device.
|
||||
@param[in, out] DeviceContext The TCG SPDM device measurement context.
|
||||
@param[in] DeviceContextSize The size of TCG SPDM device measurement context.
|
||||
|
||||
@retval EFI_SUCCESS The TCG SPDM device measurement context is returned.
|
||||
@retval EFI_UNSUPPORTED The TCG SPDM device measurement context is unsupported.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
CreateDeviceMeasurementContext (
|
||||
IN SPDM_DEVICE_CONTEXT *SpdmDeviceContext,
|
||||
IN OUT VOID *DeviceContext,
|
||||
IN UINTN DeviceContextSize
|
||||
)
|
||||
{
|
||||
if (CompareGuid (&SpdmDeviceContext->DeviceId.DeviceType, &gEdkiiDeviceIdentifierTypePciGuid)) {
|
||||
return CreatePciDeviceMeasurementContext (SpdmDeviceContext, DeviceContext, DeviceContextSize);
|
||||
}
|
||||
|
||||
if (CompareGuid (&SpdmDeviceContext->DeviceId.DeviceType, &gEdkiiDeviceIdentifierTypeUsbGuid)) {
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
/**
|
||||
This function dumps data.
|
||||
|
||||
@param[in] Data A pointer to Data.
|
||||
@param[in] Size The size of Data.
|
||||
|
||||
**/
|
||||
VOID
|
||||
EFIAPI
|
||||
InternalDumpData (
|
||||
CONST UINT8 *Data,
|
||||
UINTN Size
|
||||
)
|
||||
{
|
||||
UINTN Index;
|
||||
|
||||
for (Index = 0; Index < Size; Index++) {
|
||||
DEBUG ((DEBUG_INFO, "%02x ", (UINTN)Data[Index]));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
This function extend the PCI digest from the DvSec register.
|
||||
|
||||
@param[in] SpdmDeviceContext The SPDM context for the device.
|
||||
@param[in] AuthState The auth state of the device.
|
||||
@param[in] MeasurementRecordLength The length of the SPDM measurement record
|
||||
@param[in] MeasurementRecord The SPDM measurement record
|
||||
@param[in] RequesterNonce A buffer to hold the requester nonce (32 bytes), if not NULL.
|
||||
@param[in] ResponderNonce A buffer to hold the responder nonce (32 bytes), if not NULL.
|
||||
@param[out] SecurityState The Device Security state associated with the device.
|
||||
|
||||
@retval EFI_SUCCESS Operation completed successfully.
|
||||
@retval EFI_OUT_OF_RESOURCES Out of memory.
|
||||
@retval EFI_DEVICE_ERROR The operation was unsuccessful.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
ExtendMeasurement (
|
||||
IN SPDM_DEVICE_CONTEXT *SpdmDeviceContext,
|
||||
IN UINT8 AuthState,
|
||||
IN UINT32 MeasurementRecordLength,
|
||||
IN UINT8 *MeasurementRecord,
|
||||
IN UINT8 *RequesterNonce,
|
||||
IN UINT8 *ResponderNonce,
|
||||
OUT EDKII_DEVICE_SECURITY_STATE *SecurityState
|
||||
)
|
||||
{
|
||||
UINT32 PcrIndex;
|
||||
UINT32 EventType;
|
||||
VOID *EventLog;
|
||||
UINT32 EventLogSize;
|
||||
UINT8 *EventLogPtr;
|
||||
|
||||
TCG_DEVICE_SECURITY_EVENT_DATA_HEADER2 *EventData2;
|
||||
TCG_DEVICE_SECURITY_EVENT_DATA_SUB_HEADER_SPDM_MEASUREMENT_BLOCK *TcgSpdmMeasurementBlock;
|
||||
VOID *DeviceContext;
|
||||
UINTN DeviceContextSize;
|
||||
EFI_STATUS Status;
|
||||
SPDM_MEASUREMENT_BLOCK_COMMON_HEADER *SpdmMeasurementBlockCommonHeader;
|
||||
SPDM_MEASUREMENT_BLOCK_DMTF_HEADER *SpdmMeasurementBlockDmtfHeader;
|
||||
VOID *Digest;
|
||||
UINTN DigestSize;
|
||||
UINTN DevicePathSize;
|
||||
UINT32 MeasurementHashAlgo;
|
||||
UINTN DataSize;
|
||||
VOID *SpdmContext;
|
||||
SPDM_DATA_PARAMETER Parameter;
|
||||
|
||||
SpdmContext = SpdmDeviceContext->SpdmContext;
|
||||
|
||||
EventLog = NULL;
|
||||
ZeroMem (&Parameter, sizeof (Parameter));
|
||||
Parameter.location = SpdmDataLocationConnection;
|
||||
DataSize = sizeof (MeasurementHashAlgo);
|
||||
Status = SpdmGetData (SpdmContext, SpdmDataMeasurementHashAlgo, &Parameter, &MeasurementHashAlgo, &DataSize);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
if (MeasurementRecord != NULL) {
|
||||
SpdmMeasurementBlockCommonHeader = (VOID *)MeasurementRecord;
|
||||
SpdmMeasurementBlockDmtfHeader = (VOID *)(SpdmMeasurementBlockCommonHeader + 1);
|
||||
Digest = (SpdmMeasurementBlockDmtfHeader + 1);
|
||||
DigestSize = MeasurementRecordLength - sizeof (SPDM_MEASUREMENT_BLOCK_DMTF);
|
||||
|
||||
DEBUG ((DEBUG_INFO, "SpdmMeasurementBlockCommonHeader\n"));
|
||||
DEBUG ((DEBUG_INFO, " Index - 0x%02x\n", SpdmMeasurementBlockCommonHeader->Index));
|
||||
DEBUG ((DEBUG_INFO, " MeasurementSpecification - 0x%02x\n", SpdmMeasurementBlockCommonHeader->MeasurementSpecification));
|
||||
DEBUG ((DEBUG_INFO, " MeasurementSize - 0x%04x\n", SpdmMeasurementBlockCommonHeader->MeasurementSize));
|
||||
DEBUG ((DEBUG_INFO, "SpdmMeasurementBlockDmtfHeader\n"));
|
||||
DEBUG ((DEBUG_INFO, " DMTFSpecMeasurementValueType - 0x%02x\n", SpdmMeasurementBlockDmtfHeader->DMTFSpecMeasurementValueType));
|
||||
DEBUG ((DEBUG_INFO, " DMTFSpecMeasurementValueSize - 0x%04x\n", SpdmMeasurementBlockDmtfHeader->DMTFSpecMeasurementValueSize));
|
||||
DEBUG ((DEBUG_INFO, "Measurement - "));
|
||||
InternalDumpData (Digest, DigestSize);
|
||||
DEBUG ((DEBUG_INFO, "\n"));
|
||||
if (MeasurementRecordLength <= sizeof (SPDM_MEASUREMENT_BLOCK_COMMON_HEADER) + sizeof (SPDM_MEASUREMENT_BLOCK_DMTF_HEADER)) {
|
||||
SecurityState->MeasurementState = EDKII_DEVICE_SECURITY_STATE_ERROR_MEASUREMENT_AUTH_FAILURE;
|
||||
return EFI_SECURITY_VIOLATION;
|
||||
}
|
||||
|
||||
if ((SpdmMeasurementBlockCommonHeader->MeasurementSpecification & SPDM_MEASUREMENT_SPECIFICATION_DMTF) == 0) {
|
||||
SecurityState->MeasurementState = EDKII_DEVICE_SECURITY_STATE_ERROR_MEASUREMENT_AUTH_FAILURE;
|
||||
return EFI_SECURITY_VIOLATION;
|
||||
}
|
||||
|
||||
if (SpdmMeasurementBlockCommonHeader->MeasurementSize != MeasurementRecordLength - sizeof (SPDM_MEASUREMENT_BLOCK_COMMON_HEADER)) {
|
||||
SecurityState->MeasurementState = EDKII_DEVICE_SECURITY_STATE_ERROR_MEASUREMENT_AUTH_FAILURE;
|
||||
return EFI_SECURITY_VIOLATION;
|
||||
}
|
||||
|
||||
if (SpdmMeasurementBlockDmtfHeader->DMTFSpecMeasurementValueSize != SpdmMeasurementBlockCommonHeader->MeasurementSize - sizeof (SPDM_MEASUREMENT_BLOCK_DMTF_HEADER)) {
|
||||
SecurityState->MeasurementState = EDKII_DEVICE_SECURITY_STATE_ERROR_MEASUREMENT_AUTH_FAILURE;
|
||||
return EFI_SECURITY_VIOLATION;
|
||||
}
|
||||
|
||||
//
|
||||
// Use PCR 2 for Firmware Blob code.
|
||||
//
|
||||
switch (SpdmMeasurementBlockDmtfHeader->DMTFSpecMeasurementValueType & 0x7F) {
|
||||
case SPDM_MEASUREMENT_BLOCK_MEASUREMENT_TYPE_IMMUTABLE_ROM:
|
||||
case SPDM_MEASUREMENT_BLOCK_MEASUREMENT_TYPE_MUTABLE_FIRMWARE:
|
||||
case SPDM_MEASUREMENT_BLOCK_MEASUREMENT_TYPE_VERSION:
|
||||
case SPDM_MEASUREMENT_BLOCK_MEASUREMENT_TYPE_SECURE_VERSION_NUMBER:
|
||||
if (SpdmDeviceContext->IsEmbeddedDevice) {
|
||||
PcrIndex = 0;
|
||||
} else {
|
||||
PcrIndex = 2;
|
||||
}
|
||||
|
||||
EventType = EV_EFI_SPDM_FIRMWARE_BLOB;
|
||||
break;
|
||||
case SPDM_MEASUREMENT_BLOCK_MEASUREMENT_TYPE_HARDWARE_CONFIGURATION:
|
||||
case SPDM_MEASUREMENT_BLOCK_MEASUREMENT_TYPE_FIRMWARE_CONFIGURATION:
|
||||
case SPDM_MEASUREMENT_BLOCK_MEASUREMENT_TYPE_DEVICE_MODE:
|
||||
if (SpdmDeviceContext->IsEmbeddedDevice) {
|
||||
PcrIndex = 1;
|
||||
} else {
|
||||
PcrIndex = 3;
|
||||
}
|
||||
|
||||
EventType = EV_EFI_SPDM_FIRMWARE_CONFIG;
|
||||
break;
|
||||
case SPDM_MEASUREMENT_BLOCK_MEASUREMENT_TYPE_MEASUREMENT_MANIFEST:
|
||||
// skip manifest, because manifest doesn't belong to the EV_EFI_SPDM_FIRMWARE_BLOB and EV_EFI_SPDM_FIRMWARE_CONFIG
|
||||
default:
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
} else {
|
||||
if (SpdmDeviceContext->IsEmbeddedDevice) {
|
||||
PcrIndex = 0;
|
||||
} else {
|
||||
PcrIndex = 2;
|
||||
}
|
||||
|
||||
EventType = EV_EFI_SPDM_FIRMWARE_BLOB;
|
||||
}
|
||||
|
||||
DeviceContextSize = GetDeviceMeasurementContextSize (SpdmDeviceContext);
|
||||
DevicePathSize = GetDevicePathSize (SpdmDeviceContext->DevicePath);
|
||||
|
||||
switch (AuthState) {
|
||||
case TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_AUTH_STATE_SUCCESS:
|
||||
EventLogSize = (UINT32)(sizeof (TCG_DEVICE_SECURITY_EVENT_DATA_HEADER2) +
|
||||
sizeof (UINT64) + DevicePathSize +
|
||||
sizeof (TCG_DEVICE_SECURITY_EVENT_DATA_SUB_HEADER_SPDM_MEASUREMENT_BLOCK) +
|
||||
MeasurementRecordLength +
|
||||
DeviceContextSize);
|
||||
EventLog = AllocatePool (EventLogSize);
|
||||
if (EventLog == NULL) {
|
||||
SecurityState->MeasurementState = EDKII_DEVICE_SECURITY_STATE_ERROR_UEFI_OUT_OF_RESOURCE;
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
EventLogPtr = EventLog;
|
||||
|
||||
EventData2 = (VOID *)EventLogPtr;
|
||||
CopyMem (EventData2->Signature, TCG_DEVICE_SECURITY_EVENT_DATA_SIGNATURE_2, sizeof (EventData2->Signature));
|
||||
EventData2->Version = TCG_DEVICE_SECURITY_EVENT_DATA_VERSION_2;
|
||||
EventData2->AuthState = AuthState;
|
||||
EventData2->Reserved = 0;
|
||||
EventData2->Length = (UINT32)EventLogSize;
|
||||
EventData2->DeviceType = GetSpdmDeviceType (SpdmDeviceContext);
|
||||
|
||||
EventData2->SubHeaderType = TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_SUB_HEADER_TYPE_SPDM_MEASUREMENT_BLOCK;
|
||||
EventData2->SubHeaderLength = sizeof (TCG_DEVICE_SECURITY_EVENT_DATA_SUB_HEADER_SPDM_MEASUREMENT_BLOCK) + MeasurementRecordLength;
|
||||
EventData2->SubHeaderUID = SpdmDeviceContext->DeviceUID;
|
||||
|
||||
EventLogPtr = (VOID *)(EventData2 + 1);
|
||||
|
||||
*(UINT64 *)EventLogPtr = (UINT64)DevicePathSize;
|
||||
EventLogPtr += sizeof (UINT64);
|
||||
CopyMem (EventLogPtr, SpdmDeviceContext->DevicePath, DevicePathSize);
|
||||
EventLogPtr += DevicePathSize;
|
||||
|
||||
TcgSpdmMeasurementBlock = (VOID *)EventLogPtr;
|
||||
TcgSpdmMeasurementBlock->SpdmVersion = SpdmDeviceContext->SpdmVersion;
|
||||
TcgSpdmMeasurementBlock->SpdmMeasurementBlockCount = 1;
|
||||
TcgSpdmMeasurementBlock->Reserved = 0;
|
||||
TcgSpdmMeasurementBlock->SpdmMeasurementHashAlgo = MeasurementHashAlgo;
|
||||
EventLogPtr += sizeof (TCG_DEVICE_SECURITY_EVENT_DATA_SUB_HEADER_SPDM_MEASUREMENT_BLOCK);
|
||||
|
||||
if ((MeasurementRecord != NULL) && (MeasurementRecordLength != 0)) {
|
||||
CopyMem (EventLogPtr, MeasurementRecord, MeasurementRecordLength);
|
||||
EventLogPtr += MeasurementRecordLength;
|
||||
}
|
||||
|
||||
if (DeviceContextSize != 0) {
|
||||
DeviceContext = (VOID *)EventLogPtr;
|
||||
Status = CreateDeviceMeasurementContext (SpdmDeviceContext, DeviceContext, DeviceContextSize);
|
||||
if (Status != EFI_SUCCESS) {
|
||||
SecurityState->MeasurementState = EDKII_DEVICE_SECURITY_STATE_ERROR_DEVICE_ERROR;
|
||||
Status = EFI_DEVICE_ERROR;
|
||||
goto Exit;
|
||||
}
|
||||
}
|
||||
|
||||
Status = TpmMeasureAndLogData (
|
||||
PcrIndex,
|
||||
EventType,
|
||||
EventLog,
|
||||
EventLogSize,
|
||||
EventLog,
|
||||
EventLogSize
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
SecurityState->MeasurementState = EDKII_DEVICE_SECURITY_STATE_ERROR_TCG_EXTEND_TPM_PCR;
|
||||
}
|
||||
|
||||
DEBUG ((DEBUG_INFO, "TpmMeasureAndLogData (Measurement) - %r\n", Status));
|
||||
break;
|
||||
case TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_AUTH_STATE_FAIL_INVALID:
|
||||
EventLogSize = (UINT32)(sizeof (TCG_DEVICE_SECURITY_EVENT_DATA_HEADER2) +
|
||||
sizeof (UINT64) + DevicePathSize +
|
||||
DeviceContextSize);
|
||||
EventLog = AllocatePool (EventLogSize);
|
||||
if (EventLog == NULL) {
|
||||
SecurityState->MeasurementState = EDKII_DEVICE_SECURITY_STATE_ERROR_UEFI_OUT_OF_RESOURCE;
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
EventLogPtr = EventLog;
|
||||
|
||||
EventData2 = (VOID *)EventLogPtr;
|
||||
CopyMem (EventData2->Signature, TCG_DEVICE_SECURITY_EVENT_DATA_SIGNATURE_2, sizeof (EventData2->Signature));
|
||||
EventData2->Version = TCG_DEVICE_SECURITY_EVENT_DATA_VERSION_2;
|
||||
EventData2->AuthState = AuthState;
|
||||
EventData2->Reserved = 0;
|
||||
EventData2->Length = (UINT32)EventLogSize;
|
||||
EventData2->DeviceType = GetSpdmDeviceType (SpdmDeviceContext);
|
||||
|
||||
EventData2->SubHeaderType = TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_SUB_HEADER_TYPE_SPDM_MEASUREMENT_BLOCK;
|
||||
EventData2->SubHeaderLength = 0;
|
||||
EventData2->SubHeaderUID = SpdmDeviceContext->DeviceUID;
|
||||
|
||||
EventLogPtr = (VOID *)(EventData2 + 1);
|
||||
|
||||
*(UINT64 *)EventLogPtr = (UINT64)DevicePathSize;
|
||||
EventLogPtr += sizeof (UINT64);
|
||||
CopyMem (EventLogPtr, SpdmDeviceContext->DevicePath, DevicePathSize);
|
||||
EventLogPtr += DevicePathSize;
|
||||
|
||||
if (DeviceContextSize != 0) {
|
||||
DeviceContext = (VOID *)EventLogPtr;
|
||||
Status = CreateDeviceMeasurementContext (SpdmDeviceContext, DeviceContext, DeviceContextSize);
|
||||
if (Status != EFI_SUCCESS) {
|
||||
SecurityState->MeasurementState = EDKII_DEVICE_SECURITY_STATE_ERROR_DEVICE_ERROR;
|
||||
Status = EFI_DEVICE_ERROR;
|
||||
goto Exit;
|
||||
}
|
||||
}
|
||||
|
||||
Status = TpmMeasureAndLogData (
|
||||
PcrIndex,
|
||||
EventType,
|
||||
EventLog,
|
||||
EventLogSize,
|
||||
EventLog,
|
||||
EventLogSize
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
SecurityState->MeasurementState = EDKII_DEVICE_SECURITY_STATE_ERROR_TCG_EXTEND_TPM_PCR;
|
||||
}
|
||||
|
||||
DEBUG ((DEBUG_INFO, "TpmMeasureAndLogData (Measurement) - %r\n", Status));
|
||||
goto Exit;
|
||||
default:
|
||||
SecurityState->MeasurementState = EDKII_DEVICE_SECURITY_STATE_ERROR_UEFI_UNSUPPORTED;
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
if (RequesterNonce != NULL) {
|
||||
TCG_NV_INDEX_DYNAMIC_EVENT_LOG_STRUCT_SPDM_GET_MEASUREMENTS DynamicEventLogSpdmGetMeasurementsEvent;
|
||||
|
||||
CopyMem (DynamicEventLogSpdmGetMeasurementsEvent.Header.Signature, TCG_NV_EXTEND_INDEX_FOR_DYNAMIC_SIGNATURE, sizeof (TCG_NV_EXTEND_INDEX_FOR_DYNAMIC_SIGNATURE));
|
||||
DynamicEventLogSpdmGetMeasurementsEvent.Header.Version = TCG_NV_INDEX_DYNAMIC_EVENT_LOG_STRUCT_VERSION;
|
||||
ZeroMem (DynamicEventLogSpdmGetMeasurementsEvent.Header.Reserved, sizeof (DynamicEventLogSpdmGetMeasurementsEvent.Header.Reserved));
|
||||
DynamicEventLogSpdmGetMeasurementsEvent.Header.Uid = SpdmDeviceContext->DeviceUID;
|
||||
DynamicEventLogSpdmGetMeasurementsEvent.DescriptionSize = sizeof (TCG_SPDM_GET_MEASUREMENTS_DESCRIPTION);
|
||||
CopyMem (DynamicEventLogSpdmGetMeasurementsEvent.Description, TCG_SPDM_GET_MEASUREMENTS_DESCRIPTION, sizeof (TCG_SPDM_GET_MEASUREMENTS_DESCRIPTION));
|
||||
DynamicEventLogSpdmGetMeasurementsEvent.DataSize = SPDM_NONCE_SIZE;
|
||||
CopyMem (DynamicEventLogSpdmGetMeasurementsEvent.Data, RequesterNonce, SPDM_NONCE_SIZE);
|
||||
|
||||
Status = TpmMeasureAndLogData (
|
||||
TCG_NV_EXTEND_INDEX_FOR_DYNAMIC,
|
||||
EV_NO_ACTION,
|
||||
&DynamicEventLogSpdmGetMeasurementsEvent,
|
||||
sizeof (DynamicEventLogSpdmGetMeasurementsEvent),
|
||||
&DynamicEventLogSpdmGetMeasurementsEvent,
|
||||
sizeof (DynamicEventLogSpdmGetMeasurementsEvent)
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
SecurityState->MeasurementState = EDKII_DEVICE_SECURITY_STATE_ERROR_TCG_EXTEND_TPM_PCR;
|
||||
}
|
||||
|
||||
DEBUG ((DEBUG_INFO, "TpmMeasureAndLogData (Dynamic) - %r\n", Status));
|
||||
}
|
||||
|
||||
if (ResponderNonce != NULL) {
|
||||
TCG_NV_INDEX_DYNAMIC_EVENT_LOG_STRUCT_SPDM_MEASUREMENTS DynamicEventLogSpdmMeasurementsEvent;
|
||||
|
||||
CopyMem (DynamicEventLogSpdmMeasurementsEvent.Header.Signature, TCG_NV_EXTEND_INDEX_FOR_DYNAMIC_SIGNATURE, sizeof (TCG_NV_EXTEND_INDEX_FOR_DYNAMIC_SIGNATURE));
|
||||
DynamicEventLogSpdmMeasurementsEvent.Header.Version = TCG_NV_INDEX_DYNAMIC_EVENT_LOG_STRUCT_VERSION;
|
||||
ZeroMem (DynamicEventLogSpdmMeasurementsEvent.Header.Reserved, sizeof (DynamicEventLogSpdmMeasurementsEvent.Header.Reserved));
|
||||
DynamicEventLogSpdmMeasurementsEvent.Header.Uid = SpdmDeviceContext->DeviceUID;
|
||||
DynamicEventLogSpdmMeasurementsEvent.DescriptionSize = sizeof (TCG_SPDM_MEASUREMENTS_DESCRIPTION);
|
||||
CopyMem (DynamicEventLogSpdmMeasurementsEvent.Description, TCG_SPDM_MEASUREMENTS_DESCRIPTION, sizeof (TCG_SPDM_MEASUREMENTS_DESCRIPTION));
|
||||
DynamicEventLogSpdmMeasurementsEvent.DataSize = SPDM_NONCE_SIZE;
|
||||
CopyMem (DynamicEventLogSpdmMeasurementsEvent.Data, ResponderNonce, SPDM_NONCE_SIZE);
|
||||
|
||||
Status = TpmMeasureAndLogData (
|
||||
TCG_NV_EXTEND_INDEX_FOR_DYNAMIC,
|
||||
EV_NO_ACTION,
|
||||
&DynamicEventLogSpdmMeasurementsEvent,
|
||||
sizeof (DynamicEventLogSpdmMeasurementsEvent),
|
||||
&DynamicEventLogSpdmMeasurementsEvent,
|
||||
sizeof (DynamicEventLogSpdmMeasurementsEvent)
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
SecurityState->MeasurementState = EDKII_DEVICE_SECURITY_STATE_ERROR_TCG_EXTEND_TPM_PCR;
|
||||
}
|
||||
|
||||
DEBUG ((DEBUG_INFO, "TpmMeasureAndLogData (Dynamic) - %r\n", Status));
|
||||
}
|
||||
|
||||
Exit:
|
||||
if (EventLog != NULL) {
|
||||
FreePool (EventLog);
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
This function gets SPDM measurement and extend to TPM.
|
||||
|
||||
@param[in] SpdmDeviceContext The SPDM context for the device.
|
||||
@param[in] SlotId The number of slot id of the certificate.
|
||||
@param[out] SecurityState A poniter to security state of the requester.
|
||||
|
||||
@retval EFI_SUCCESS Operation completed successfully.
|
||||
@retval EFI_OUT_OF_RESOURCES Out of memory.
|
||||
@retval EFI_DEVICE_ERROR The operation was unsuccessful.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
DoDeviceMeasurement (
|
||||
IN SPDM_DEVICE_CONTEXT *SpdmDeviceContext,
|
||||
IN UINT8 SlotId,
|
||||
OUT EDKII_DEVICE_SECURITY_STATE *SecurityState
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
SPDM_RETURN SpdmReturn;
|
||||
VOID *SpdmContext;
|
||||
UINT32 CapabilityFlags;
|
||||
UINTN DataSize;
|
||||
SPDM_DATA_PARAMETER Parameter;
|
||||
UINT8 NumberOfBlocks;
|
||||
UINT32 MeasurementRecordLength;
|
||||
UINT8 MeasurementRecord[LIBSPDM_MAX_MEASUREMENT_RECORD_SIZE];
|
||||
UINT8 Index;
|
||||
UINT8 RequesterNonce[SPDM_NONCE_SIZE];
|
||||
UINT8 ResponderNonce[SPDM_NONCE_SIZE];
|
||||
UINT8 RequestAttribute;
|
||||
UINT32 MeasurementsBlockSize;
|
||||
SPDM_MEASUREMENT_BLOCK_DMTF *MeasurementBlock;
|
||||
UINT8 NumberOfBlock;
|
||||
UINT8 ReceivedNumberOfBlock;
|
||||
UINT8 AuthState;
|
||||
UINT8 ContentChanged;
|
||||
UINT8 ContentChangedCount;
|
||||
|
||||
SpdmContext = SpdmDeviceContext->SpdmContext;
|
||||
|
||||
ZeroMem (&Parameter, sizeof (Parameter));
|
||||
Parameter.location = SpdmDataLocationConnection;
|
||||
DataSize = sizeof (CapabilityFlags);
|
||||
SpdmGetData (SpdmContext, SpdmDataCapabilityFlags, &Parameter, &CapabilityFlags, &DataSize);
|
||||
|
||||
if ((CapabilityFlags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MEAS_CAP_SIG) == 0) {
|
||||
AuthState = TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_AUTH_STATE_FAIL_NO_SIG;
|
||||
Status = ExtendCertificate (SpdmDeviceContext, AuthState, 0, NULL, NULL, 0, 0, SecurityState);
|
||||
SecurityState->MeasurementState = EDKII_DEVICE_SECURITY_STATE_ERROR_DEVICE_NO_CAPABILITIES;
|
||||
if (Status != EFI_SUCCESS) {
|
||||
return Status;
|
||||
} else {
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
}
|
||||
|
||||
RequestAttribute = 0;
|
||||
RequestAttribute |= SPDM_GET_MEASUREMENTS_REQUEST_ATTRIBUTES_GENERATE_SIGNATURE;
|
||||
|
||||
MeasurementRecordLength = sizeof (MeasurementRecord);
|
||||
ZeroMem (RequesterNonce, sizeof (RequesterNonce));
|
||||
ZeroMem (ResponderNonce, sizeof (ResponderNonce));
|
||||
|
||||
//
|
||||
// get all measurement once, with signature.
|
||||
//
|
||||
SpdmReturn = SpdmGetMeasurementEx (
|
||||
SpdmContext,
|
||||
NULL,
|
||||
RequestAttribute,
|
||||
SPDM_GET_MEASUREMENTS_REQUEST_MEASUREMENT_OPERATION_ALL_MEASUREMENTS,
|
||||
SlotId,
|
||||
NULL,
|
||||
&NumberOfBlocks,
|
||||
&MeasurementRecordLength,
|
||||
MeasurementRecord,
|
||||
NULL,
|
||||
RequesterNonce,
|
||||
ResponderNonce,
|
||||
NULL,
|
||||
0
|
||||
);
|
||||
if (LIBSPDM_STATUS_IS_SUCCESS (SpdmReturn)) {
|
||||
DEBUG ((DEBUG_INFO, "NumberOfBlocks %d\n", NumberOfBlocks));
|
||||
|
||||
MeasurementBlock = (VOID *)MeasurementRecord;
|
||||
for (Index = 0; Index < NumberOfBlocks; Index++) {
|
||||
MeasurementsBlockSize =
|
||||
sizeof (SPDM_MEASUREMENT_BLOCK_DMTF) +
|
||||
MeasurementBlock
|
||||
->MeasurementBlockDmtfHeader
|
||||
.DMTFSpecMeasurementValueSize;
|
||||
|
||||
AuthState = TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_AUTH_STATE_SUCCESS;
|
||||
SecurityState->MeasurementState = EDKII_DEVICE_SECURITY_STATE_SUCCESS;
|
||||
if (Index == NumberOfBlocks - 1) {
|
||||
Status = ExtendMeasurement (SpdmDeviceContext, AuthState, MeasurementsBlockSize, (UINT8 *)MeasurementBlock, RequesterNonce, ResponderNonce, SecurityState);
|
||||
} else {
|
||||
Status = ExtendMeasurement (SpdmDeviceContext, AuthState, MeasurementsBlockSize, (UINT8 *)MeasurementBlock, NULL, NULL, SecurityState);
|
||||
}
|
||||
|
||||
MeasurementBlock = (VOID *)((size_t)MeasurementBlock + MeasurementsBlockSize);
|
||||
if (Status != EFI_SUCCESS) {
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
} else if (SpdmReturn == LIBSPDM_STATUS_VERIF_FAIL) {
|
||||
AuthState = TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_AUTH_STATE_FAIL_INVALID;
|
||||
SecurityState->MeasurementState = EDKII_DEVICE_SECURITY_STATE_ERROR_MEASUREMENT_AUTH_FAILURE;
|
||||
Status = ExtendMeasurement (SpdmDeviceContext, AuthState, 0, NULL, NULL, NULL, SecurityState);
|
||||
return Status;
|
||||
} else {
|
||||
ContentChangedCount = 0;
|
||||
ContentChangedFlag:
|
||||
RequestAttribute = 0;
|
||||
ContentChanged = SPDM_MEASUREMENTS_RESPONSE_CONTENT_NO_CHANGE_DETECTED;
|
||||
ReceivedNumberOfBlock = 0;
|
||||
|
||||
//
|
||||
// 1. Query the total number of measurements available.
|
||||
//
|
||||
SpdmReturn = SpdmGetMeasurement (
|
||||
SpdmContext,
|
||||
NULL,
|
||||
RequestAttribute,
|
||||
SPDM_GET_MEASUREMENTS_REQUEST_MEASUREMENT_OPERATION_TOTAL_NUMBER_OF_MEASUREMENTS,
|
||||
SlotId,
|
||||
NULL,
|
||||
&NumberOfBlocks,
|
||||
NULL,
|
||||
NULL
|
||||
);
|
||||
if (LIBSPDM_STATUS_IS_ERROR (SpdmReturn)) {
|
||||
SecurityState->MeasurementState = EDKII_DEVICE_SECURITY_STATE_ERROR_DEVICE_ERROR;
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
DEBUG ((DEBUG_INFO, "NumberOfBlocks - 0x%x\n", NumberOfBlocks));
|
||||
|
||||
ReceivedNumberOfBlock = 0;
|
||||
for (Index = 1; Index <= 0xFE; Index++) {
|
||||
if (ReceivedNumberOfBlock == NumberOfBlocks) {
|
||||
break;
|
||||
}
|
||||
|
||||
DEBUG ((DEBUG_INFO, "Index - 0x%x\n", Index));
|
||||
//
|
||||
// 2. query measurement one by one
|
||||
// get signature in last message only.
|
||||
//
|
||||
if (ReceivedNumberOfBlock == NumberOfBlocks - 1) {
|
||||
RequestAttribute |= SPDM_GET_MEASUREMENTS_REQUEST_ATTRIBUTES_GENERATE_SIGNATURE;
|
||||
}
|
||||
|
||||
MeasurementRecordLength = sizeof (MeasurementRecord);
|
||||
ZeroMem (RequesterNonce, sizeof (RequesterNonce));
|
||||
ZeroMem (ResponderNonce, sizeof (ResponderNonce));
|
||||
SpdmReturn = SpdmGetMeasurementEx (
|
||||
SpdmContext,
|
||||
NULL,
|
||||
RequestAttribute,
|
||||
Index,
|
||||
SlotId,
|
||||
&ContentChanged,
|
||||
&NumberOfBlock,
|
||||
&MeasurementRecordLength,
|
||||
MeasurementRecord,
|
||||
NULL,
|
||||
RequesterNonce,
|
||||
ResponderNonce,
|
||||
NULL,
|
||||
0
|
||||
);
|
||||
if (LIBSPDM_STATUS_IS_ERROR (SpdmReturn)) {
|
||||
if (SpdmReturn == LIBSPDM_STATUS_VERIF_FAIL) {
|
||||
AuthState = TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_AUTH_STATE_FAIL_INVALID;
|
||||
SecurityState->MeasurementState = EDKII_DEVICE_SECURITY_STATE_ERROR_DEVICE_ERROR;
|
||||
Status = ExtendMeasurement (SpdmDeviceContext, AuthState, 0, NULL, NULL, NULL, SecurityState);
|
||||
return Status;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if ((ReceivedNumberOfBlock == NumberOfBlocks - 1) &&
|
||||
(ContentChanged == SPDM_MEASUREMENTS_RESPONSE_CONTENT_CHANGE_DETECTED))
|
||||
{
|
||||
if (ContentChangedCount == 0) {
|
||||
ContentChangedCount++;
|
||||
goto ContentChangedFlag;
|
||||
} else {
|
||||
AuthState = TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_AUTH_STATE_FAIL_INVALID;
|
||||
SecurityState->MeasurementState = EDKII_DEVICE_SECURITY_STATE_ERROR_DEVICE_ERROR;
|
||||
Status = ExtendMeasurement (SpdmDeviceContext, AuthState, 0, NULL, NULL, NULL, SecurityState);
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
|
||||
DEBUG ((DEBUG_INFO, "ExtendMeasurement...\n"));
|
||||
AuthState = TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_AUTH_STATE_SUCCESS;
|
||||
SecurityState->MeasurementState = EDKII_DEVICE_SECURITY_STATE_SUCCESS;
|
||||
if (ReceivedNumberOfBlock == NumberOfBlocks - 1) {
|
||||
Status = ExtendMeasurement (SpdmDeviceContext, AuthState, MeasurementRecordLength, MeasurementRecord, RequesterNonce, ResponderNonce, SecurityState);
|
||||
} else {
|
||||
Status = ExtendMeasurement (SpdmDeviceContext, AuthState, MeasurementRecordLength, MeasurementRecord, NULL, ResponderNonce, SecurityState);
|
||||
}
|
||||
|
||||
if (Status != EFI_SUCCESS) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
ReceivedNumberOfBlock += 1;
|
||||
}
|
||||
|
||||
if (ReceivedNumberOfBlock != NumberOfBlocks) {
|
||||
SecurityState->MeasurementState = EDKII_DEVICE_SECURITY_STATE_ERROR_MEASUREMENT_AUTH_FAILURE;
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
148
SecurityPkg/DeviceSecurity/SpdmSecurityLib/SpdmSecurityLib.c
Normal file
148
SecurityPkg/DeviceSecurity/SpdmSecurityLib/SpdmSecurityLib.c
Normal file
@ -0,0 +1,148 @@
|
||||
/** @file
|
||||
EDKII Device Security library for SPDM device.
|
||||
It follows the SPDM Specification.
|
||||
|
||||
Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
**/
|
||||
|
||||
#include "SpdmSecurityLibInternal.h"
|
||||
|
||||
/**
|
||||
Helper function to quickly determine whether device authentication boot is enabled.
|
||||
|
||||
@retval TRUE device authentication boot is verifiably enabled.
|
||||
@retval FALSE device authentication boot is either disabled or an error prevented checking.
|
||||
|
||||
**/
|
||||
BOOLEAN
|
||||
EFIAPI
|
||||
IsDeviceAuthBootEnabled (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINT8 *DeviceAuthBootMode;
|
||||
|
||||
DeviceAuthBootMode = NULL;
|
||||
|
||||
Status = GetEfiGlobalVariable2 (EFI_DEVICE_AUTH_BOOT_MODE_NAME, (VOID **)&DeviceAuthBootMode, NULL);
|
||||
//
|
||||
// Skip verification if DeviceAuthBootMode variable doesn't exist.
|
||||
//
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((DEBUG_ERROR, "Cannot check DeviceAuthBootMode variable %r \n ", Status));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//
|
||||
// Skip verification if DeviceAuthBootMode is disabled but not AuditMode
|
||||
//
|
||||
if (*DeviceAuthBootMode == DEVICE_AUTH_BOOT_MODE_DISABLE) {
|
||||
FreePool (DeviceAuthBootMode);
|
||||
return FALSE;
|
||||
} else {
|
||||
FreePool (DeviceAuthBootMode);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
The device driver uses this service to authenticate and measure an SPDM device.
|
||||
|
||||
@param[in] SpdmDeviceInfo The SPDM context for the device.
|
||||
@param[in] SecurityPolicy The security policy of this device.
|
||||
@param[out] SecurityState A pointer to security state if this device.
|
||||
|
||||
@retval EFI_SUCCESS The TCG SPDM device measurement context is returned.
|
||||
@retval EFI_UNSUPPORTED The TCG SPDM device measurement context is unsupported.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
SpdmDeviceAuthenticationAndMeasurement (
|
||||
IN EDKII_SPDM_DEVICE_INFO *SpdmDeviceInfo,
|
||||
IN EDKII_DEVICE_SECURITY_POLICY *SecurityPolicy,
|
||||
OUT EDKII_DEVICE_SECURITY_STATE *SecurityState
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
SPDM_DEVICE_CONTEXT *SpdmDeviceContext;
|
||||
UINT8 AuthState;
|
||||
UINT8 SlotId;
|
||||
BOOLEAN IsValidCertChain;
|
||||
BOOLEAN RootCertMatch;
|
||||
|
||||
if ((PcdGet32 (PcdTcgPfpMeasurementRevision) < TCG_EfiSpecIDEventStruct_SPEC_ERRATA_TPM2_REV_106) ||
|
||||
(PcdGet8 (PcdEnableSpdmDeviceAuthentication) == 0))
|
||||
{
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
SpdmDeviceContext = CreateSpdmDeviceContext (SpdmDeviceInfo, SecurityState);
|
||||
if (SpdmDeviceContext == NULL) {
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
Status = EFI_SUCCESS;
|
||||
AuthState = TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_AUTH_STATE_SUCCESS;
|
||||
SlotId = 0;
|
||||
IsValidCertChain = FALSE;
|
||||
RootCertMatch = FALSE;
|
||||
|
||||
if (((SecurityPolicy->AuthenticationPolicy & EDKII_DEVICE_AUTHENTICATION_REQUIRED) != 0) ||
|
||||
((SecurityPolicy->MeasurementPolicy & EDKII_DEVICE_MEASUREMENT_REQUIRED) != 0))
|
||||
{
|
||||
Status = DoDeviceCertificate (SpdmDeviceContext, &AuthState, &SlotId, SecurityState, &IsValidCertChain, &RootCertMatch);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((DEBUG_ERROR, "DoDeviceCertificate failed - %r\n", Status));
|
||||
goto Ret;
|
||||
} else if ((AuthState == TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_AUTH_STATE_FAIL_NO_SIG) ||
|
||||
(AuthState == TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_AUTH_STATE_FAIL_INVALID))
|
||||
{
|
||||
goto Ret;
|
||||
}
|
||||
}
|
||||
|
||||
if (((SecurityPolicy->AuthenticationPolicy & EDKII_DEVICE_AUTHENTICATION_REQUIRED) != 0) && (IsDeviceAuthBootEnabled ())) {
|
||||
Status = DoDeviceAuthentication (SpdmDeviceContext, &AuthState, SlotId, IsValidCertChain, RootCertMatch, SecurityState);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((DEBUG_ERROR, "DoDeviceAuthentication failed - %r\n", Status));
|
||||
goto Ret;
|
||||
} else if ((AuthState == TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_AUTH_STATE_FAIL_NO_SIG) ||
|
||||
(AuthState == TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_AUTH_STATE_FAIL_INVALID))
|
||||
{
|
||||
goto Ret;
|
||||
}
|
||||
}
|
||||
|
||||
if ((SecurityPolicy->MeasurementPolicy & EDKII_DEVICE_MEASUREMENT_REQUIRED) != 0) {
|
||||
Status = DoDeviceMeasurement (SpdmDeviceContext, SlotId, SecurityState);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((DEBUG_ERROR, "DoDeviceMeasurement failed - %r\n", Status));
|
||||
}
|
||||
}
|
||||
|
||||
Ret:
|
||||
DestroySpdmDeviceContext (SpdmDeviceContext);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
This function will get SpdmIoProtocol via Context.
|
||||
|
||||
@param[in] SpdmContext The SPDM context for the device.
|
||||
|
||||
return the pointer of Spdm Io protocol
|
||||
|
||||
**/
|
||||
VOID *
|
||||
EFIAPI
|
||||
SpdmGetIoProtocolViaSpdmContext (
|
||||
IN VOID *SpdmContext
|
||||
)
|
||||
{
|
||||
return GetSpdmIoProtocolViaSpdmContext (SpdmContext);
|
||||
}
|
@ -0,0 +1,54 @@
|
||||
## @file
|
||||
# SPDM library.
|
||||
#
|
||||
# Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
|
||||
#
|
||||
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
#
|
||||
##
|
||||
|
||||
[Defines]
|
||||
INF_VERSION = 0x00010005
|
||||
BASE_NAME = SpdmSecurityLib
|
||||
FILE_GUID = 77D7770D-158E-4354-B813-B8792A0E982D
|
||||
MODULE_TYPE = BASE
|
||||
VERSION_STRING = 1.0
|
||||
LIBRARY_CLASS = SpdmSecurityLib
|
||||
|
||||
#
|
||||
# The following information is for reference only and not required by the build tools.
|
||||
#
|
||||
# VALID_ARCHITECTURES = IA32 X64 AARCH64
|
||||
#
|
||||
|
||||
[Sources]
|
||||
SpdmSecurityLibInternal.h
|
||||
SpdmSecurityLib.c
|
||||
SpdmConnectionInit.c
|
||||
SpdmMeasurement.c
|
||||
SpdmAuthentication.c
|
||||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
MdeModulePkg/MdeModulePkg.dec
|
||||
SecurityPkg/SecurityPkg.dec
|
||||
CryptoPkg/CryptoPkg.dec
|
||||
|
||||
[LibraryClasses]
|
||||
BaseLib
|
||||
BaseMemoryLib
|
||||
DebugLib
|
||||
BaseCryptLib
|
||||
RngLib
|
||||
TpmMeasurementLib
|
||||
SpdmRequesterLib
|
||||
SpdmCommonLib
|
||||
|
||||
[Guids]
|
||||
gEfiDeviceSignatureDatabaseGuid ## CONSUMES
|
||||
gEfiCertX509Guid ## CONSUMES
|
||||
gEfiDeviceSecuritySpdmUidGuid ## PRODUCES AND CONSUMES
|
||||
|
||||
[Pcd]
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdTcgPfpMeasurementRevision ## CONSUMES
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdEnableSpdmDeviceAuthentication ## CONSUMES
|
@ -0,0 +1,250 @@
|
||||
/** @file
|
||||
EDKII Device Security library for SPDM device.
|
||||
It follows the SPDM Specification.
|
||||
|
||||
Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
**/
|
||||
|
||||
#ifndef SPDM_SECURITY_LIB_INTERNAL_H_
|
||||
#define SPDM_SECURITY_LIB_INTERNAL_H_
|
||||
|
||||
#include <Uefi.h>
|
||||
#include <hal/base.h>
|
||||
#include <Stub/SpdmLibStub.h>
|
||||
#include <industry_standard/spdm.h>
|
||||
#include <industry_standard/spdm_secured_message.h>
|
||||
#include <IndustryStandard/Pci.h>
|
||||
#include <IndustryStandard/Tpm20.h>
|
||||
#include <IndustryStandard/UefiTcgPlatform.h>
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
#include <Library/UefiBootServicesTableLib.h>
|
||||
#include <Library/UefiRuntimeServicesTableLib.h>
|
||||
#include <Library/MemoryAllocationLib.h>
|
||||
#include <Library/DevicePathLib.h>
|
||||
#include <Library/UefiLib.h>
|
||||
#include <Library/TpmMeasurementLib.h>
|
||||
#include <Library/RngLib.h>
|
||||
#include <Library/BaseCryptLib.h>
|
||||
#include <library/spdm_requester_lib.h>
|
||||
|
||||
#include <Guid/DeviceAuthentication.h>
|
||||
#include <Guid/ImageAuthentication.h>
|
||||
|
||||
#include <Protocol/PciIo.h>
|
||||
#include <Library/SpdmSecurityLib.h>
|
||||
#include "library/spdm_crypt_lib.h"
|
||||
|
||||
#define SPDM_DEVICE_CONTEXT_SIGNATURE SIGNATURE_32 ('S', 'P', 'D', 'C')
|
||||
|
||||
typedef struct {
|
||||
UINT32 Signature;
|
||||
// UEFI Context
|
||||
EDKII_DEVICE_IDENTIFIER DeviceId;
|
||||
BOOLEAN IsEmbeddedDevice;
|
||||
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
|
||||
VOID *DeviceIo;
|
||||
UINT64 DeviceUID;
|
||||
// SPDM Context
|
||||
UINTN SpdmContextSize;
|
||||
VOID *SpdmContext;
|
||||
UINTN ScratchBufferSize;
|
||||
VOID *ScratchBuffer;
|
||||
UINT8 SpdmVersion;
|
||||
VOID *SpdmIoProtocol;
|
||||
EFI_SIGNATURE_LIST *SignatureList;
|
||||
UINTN SignatureListSize;
|
||||
} SPDM_DEVICE_CONTEXT;
|
||||
|
||||
typedef struct {
|
||||
UINTN Signature;
|
||||
LIST_ENTRY Link;
|
||||
SPDM_DEVICE_CONTEXT *SpdmDeviceContext;
|
||||
} SPDM_DEVICE_CONTEXT_INSTANCE;
|
||||
|
||||
#define SPDM_DEVICE_CONTEXT_INSTANCE_SIGNATURE SIGNATURE_32 ('S', 'D', 'C', 'S')
|
||||
#define SPDM_DEVICE_CONTEXT_INSTANCE_FROM_LINK(a) CR (a, SPDM_DEVICE_CONTEXT_INSTANCE, Link, SPDM_DEVICE_CONTEXT_INSTANCE_SIGNATURE)
|
||||
|
||||
VOID *
|
||||
EFIAPI
|
||||
GetSpdmIoProtocolViaSpdmContext (
|
||||
IN VOID *SpdmContext
|
||||
);
|
||||
|
||||
/**
|
||||
This function creates the spdm device context and init connection to the
|
||||
responder with the device info.
|
||||
|
||||
@param[in] SpdmDeviceInfo A pointer to device info.
|
||||
@param[out] SecurityState A pointer to the security state of the requester.
|
||||
|
||||
@return the spdm device conext after the init connection succeeds.
|
||||
|
||||
**/
|
||||
SPDM_DEVICE_CONTEXT *
|
||||
EFIAPI
|
||||
CreateSpdmDeviceContext (
|
||||
IN EDKII_SPDM_DEVICE_INFO *SpdmDeviceInfo,
|
||||
OUT EDKII_DEVICE_SECURITY_STATE *SecurityState
|
||||
);
|
||||
|
||||
VOID
|
||||
EFIAPI
|
||||
DestroySpdmDeviceContext (
|
||||
IN SPDM_DEVICE_CONTEXT *SpdmDeviceContext
|
||||
);
|
||||
|
||||
/**
|
||||
This function returns the SPDM device type for TCG SPDM event.
|
||||
|
||||
@param[in] SpdmDeviceContext The SPDM context for the device.
|
||||
|
||||
@return TCG SPDM device type
|
||||
**/
|
||||
UINT32
|
||||
EFIAPI
|
||||
GetSpdmDeviceType (
|
||||
IN SPDM_DEVICE_CONTEXT *SpdmDeviceContext
|
||||
);
|
||||
|
||||
/**
|
||||
This function returns the SPDM device measurement context size for TCG SPDM event.
|
||||
|
||||
@param[in] SpdmDeviceContext The SPDM context for the device.
|
||||
|
||||
@return TCG SPDM device measurement context size
|
||||
**/
|
||||
UINTN
|
||||
EFIAPI
|
||||
GetDeviceMeasurementContextSize (
|
||||
IN SPDM_DEVICE_CONTEXT *SpdmDeviceContext
|
||||
);
|
||||
|
||||
/**
|
||||
This function creates the SPDM device measurement context for TCG SPDM event.
|
||||
|
||||
@param[in] SpdmDeviceContext The SPDM context for the device.
|
||||
@param[in, OUT] DeviceContext The TCG SPDM device measurement context.
|
||||
@param[in] DeviceContextSize The size of TCG SPDM device measurement context.
|
||||
|
||||
@retval EFI_SUCCESS The TCG SPDM device measurement context is returned.
|
||||
@retval EFI_UNSUPPORTED The TCG SPDM device measurement context is unsupported.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
CreateDeviceMeasurementContext (
|
||||
IN SPDM_DEVICE_CONTEXT *SpdmDeviceContext,
|
||||
IN OUT VOID *DeviceContext,
|
||||
IN UINTN DeviceContextSize
|
||||
);
|
||||
|
||||
/**
|
||||
Extend Certicate and auth state to NV Index and measure trust anchor to PCR.
|
||||
|
||||
@param[in] SpdmDeviceContext The SPDM context for the device.
|
||||
@param[in] AuthState The auth state of this deice.
|
||||
@param[in] CertChainSize The size of cert chain.
|
||||
@param[in] CertChain A pointer to a destination buffer to store the certificate chain.
|
||||
@param[in] TrustAnchor A buffer to hold the trust_anchor which is used to validate the peer
|
||||
certificate, if not NULL.
|
||||
@param[in] TrustAnchorSize A buffer to hold the trust_anchor_size, if not NULL..
|
||||
@param[in] SlotId The number of slot for the certificate chain.
|
||||
@param[out] SecurityState A pointer to the security state of the requester.
|
||||
|
||||
@retval EFI_SUCCESS Operation completed successfully.
|
||||
@retval EFI_OUT_OF_RESOURCES Out of memory.
|
||||
@retval EFI_DEVICE_ERROR The operation was unsuccessful.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
ExtendCertificate (
|
||||
IN SPDM_DEVICE_CONTEXT *SpdmDeviceContext,
|
||||
IN UINT8 AuthState,
|
||||
IN UINTN CertChainSize,
|
||||
IN UINT8 *CertChain,
|
||||
IN VOID *TrustAnchor,
|
||||
IN UINTN TrustAnchorSize,
|
||||
IN UINT8 SlotId,
|
||||
OUT EDKII_DEVICE_SECURITY_STATE *SecurityState
|
||||
);
|
||||
|
||||
/**
|
||||
This function executes SPDM measurement and extend to TPM.
|
||||
|
||||
@param[in] SpdmDeviceContext The SPDM context for the device.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
DoDeviceMeasurement (
|
||||
IN SPDM_DEVICE_CONTEXT *SpdmDeviceContext,
|
||||
IN UINT8 SlotId,
|
||||
OUT EDKII_DEVICE_SECURITY_STATE *SecurityState
|
||||
);
|
||||
|
||||
/**
|
||||
This function gets SPDM digest and certificates.
|
||||
|
||||
@param[in] SpdmDeviceContext The SPDM context for the device.
|
||||
@param[out] AuthState The auth state of the devices.
|
||||
@param[out] ValidSlotId The number of slot for the certificate chain.
|
||||
@param[out] SecurityState The security state of the requester.
|
||||
@param[out] IsValidCertChain The validity of the certificate chain.
|
||||
@param[out] RootCertMatch The authority of the certificate chain.
|
||||
|
||||
@retval EFI_SUCCESS Operation completed successfully.
|
||||
@retval EFI_OUT_OF_RESOURCES Out of memory.
|
||||
@retval EFI_DEVICE_ERROR The operation was unsuccessful.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
DoDeviceCertificate (
|
||||
IN SPDM_DEVICE_CONTEXT *SpdmDeviceContext,
|
||||
OUT UINT8 *AuthState,
|
||||
OUT UINT8 *ValidSlotId,
|
||||
OUT EDKII_DEVICE_SECURITY_STATE *SecurityState,
|
||||
OUT BOOLEAN *IsValidCertChain,
|
||||
OUT BOOLEAN *RootCertMatch
|
||||
);
|
||||
|
||||
/**
|
||||
This function does authentication.
|
||||
|
||||
@param[in] SpdmDeviceContext The SPDM context for the device.
|
||||
@param[out] AuthState The auth state of the devices.
|
||||
@param[in] ValidSlotId The number of slot for the certificate chain.
|
||||
@param[out] SecurityState The security state of the requester.
|
||||
|
||||
@retval EFI_SUCCESS Operation completed successfully.
|
||||
@retval EFI_OUT_OF_RESOURCES Out of memory.
|
||||
@retval EFI_DEVICE_ERROR The operation was unsuccessful.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
DoDeviceAuthentication (
|
||||
IN SPDM_DEVICE_CONTEXT *SpdmDeviceContext,
|
||||
OUT UINT8 *AuthState,
|
||||
IN UINT8 ValidSlotId,
|
||||
IN BOOLEAN IsValidCertChain,
|
||||
IN BOOLEAN RootCertMatch,
|
||||
OUT EDKII_DEVICE_SECURITY_STATE *SecurityState
|
||||
);
|
||||
|
||||
/**
|
||||
* This function dump raw data.
|
||||
*
|
||||
* @param data raw data
|
||||
* @param size raw data size
|
||||
**/
|
||||
VOID
|
||||
EFIAPI
|
||||
InternalDumpData (
|
||||
CONST UINT8 *Data,
|
||||
UINTN Size
|
||||
);
|
||||
|
||||
#endif
|
437
SecurityPkg/Include/Library/SpdmSecurityLib.h
Normal file
437
SecurityPkg/Include/Library/SpdmSecurityLib.h
Normal file
@ -0,0 +1,437 @@
|
||||
/** @file
|
||||
EDKII Device Security library for SPDM device.
|
||||
It follows the SPDM Specification.
|
||||
|
||||
Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
**/
|
||||
|
||||
#ifndef SPDM_SECURITY_LIB_H_
|
||||
#define SPDM_SECURITY_LIB_H_
|
||||
|
||||
#include <Protocol/DeviceSecurity.h>
|
||||
#include <Protocol/DeviceSecurityPolicy.h>
|
||||
|
||||
/**
|
||||
* Send an SPDM transport layer message to a device.
|
||||
*
|
||||
* The message is an SPDM message with transport layer wrapper,
|
||||
* or a secured SPDM message with transport layer wrapper.
|
||||
*
|
||||
* For requester, the message is a transport layer SPDM request.
|
||||
* For responder, the message is a transport layer SPDM response.
|
||||
*
|
||||
* @param spdm_context A pointer to the SPDM context.
|
||||
* @param message_size size in bytes of the message data buffer.
|
||||
* @param message A pointer to a destination buffer to store the message.
|
||||
* The caller is responsible for having
|
||||
* either implicit or explicit ownership of the buffer.
|
||||
* The message pointer shall be inside of
|
||||
* [msg_buf_ptr, msg_buf_ptr + max_msg_size] from
|
||||
* acquired sender_buffer.
|
||||
* @param timeout The timeout, in 100ns units, to use for the execution
|
||||
* of the message. A timeout value of 0
|
||||
* means that this function will wait indefinitely for the
|
||||
* message to execute. If timeout is greater
|
||||
* than zero, then this function will return RETURN_TIMEOUT if the
|
||||
* time required to execute the message is greater
|
||||
* than timeout.
|
||||
*
|
||||
* @retval RETURN_SUCCESS The SPDM message is sent successfully.
|
||||
* @retval RETURN_DEVICE_ERROR A device error occurs when the SPDM message is sent to the device.
|
||||
* @retval RETURN_INVALID_PARAMETER The message is NULL or the message_size is zero.
|
||||
* @retval RETURN_TIMEOUT A timeout occurred while waiting for the SPDM message
|
||||
* to execute.
|
||||
**/
|
||||
typedef
|
||||
SPDM_RETURN
|
||||
(*SPDM_DEVICE_SEND_MESSAGE_FUNC)(
|
||||
IN VOID *SpdmContext,
|
||||
IN UINTN MessageSize,
|
||||
IN OUT CONST VOID *Message,
|
||||
IN UINT64 Timeout
|
||||
);
|
||||
|
||||
/**
|
||||
* Receive an SPDM transport layer message from a device.
|
||||
*
|
||||
* The message is an SPDM message with transport layer wrapper,
|
||||
* or a secured SPDM message with transport layer wrapper.
|
||||
*
|
||||
* For requester, the message is a transport layer SPDM response.
|
||||
* For responder, the message is a transport layer SPDM request.
|
||||
*
|
||||
* @param spdm_context A pointer to the SPDM context.
|
||||
* @param message_size size in bytes of the message data buffer.
|
||||
* @param message A pointer to a destination buffer to store the message.
|
||||
* The caller is responsible for having
|
||||
* either implicit or explicit ownership of the buffer.
|
||||
* On input, the message pointer shall be msg_buf_ptr from
|
||||
* acquired receiver_buffer.
|
||||
* On output, the message pointer shall be inside of
|
||||
* [msg_buf_ptr, msg_buf_ptr + max_msg_size] from
|
||||
* acquired receiver_buffer.
|
||||
* @param timeout The timeout, in 100ns units, to use for the execution
|
||||
* of the message. A timeout value of 0
|
||||
* means that this function will wait indefinitely for the
|
||||
* message to execute. If timeout is greater
|
||||
* than zero, then this function will return RETURN_TIMEOUT if the
|
||||
* time required to execute the message is greater
|
||||
* than timeout.
|
||||
*
|
||||
* @retval RETURN_SUCCESS The SPDM message is received successfully.
|
||||
* @retval RETURN_DEVICE_ERROR A device error occurs when the SPDM message is received from the device.
|
||||
* @retval RETURN_INVALID_PARAMETER The message is NULL, message_size is NULL or
|
||||
* the *message_size is zero.
|
||||
* @retval RETURN_TIMEOUT A timeout occurred while waiting for the SPDM message
|
||||
* to execute.
|
||||
**/
|
||||
typedef
|
||||
SPDM_RETURN
|
||||
(*SPDM_DEVICE_RECEIVE_MESSAGE_FUNC)(
|
||||
IN VOID *SpdmContext,
|
||||
IN OUT UINTN *MessageSize,
|
||||
IN OUT VOID **Message,
|
||||
IN UINT64 Timeout
|
||||
);
|
||||
|
||||
/**
|
||||
* Encode an SPDM or APP message to a transport layer message.
|
||||
*
|
||||
* For normal SPDM message, it adds the transport layer wrapper.
|
||||
* For secured SPDM message, it encrypts a secured message then adds the transport layer wrapper.
|
||||
* For secured APP message, it encrypts a secured message then adds the transport layer wrapper.
|
||||
*
|
||||
* The APP message is encoded to a secured message directly in SPDM session.
|
||||
* The APP message format is defined by the transport layer.
|
||||
* Take MCTP as example: APP message == MCTP header (MCTP_MESSAGE_TYPE_SPDM) + SPDM message
|
||||
*
|
||||
* @param spdm_context A pointer to the SPDM context.
|
||||
* @param session_id Indicates if it is a secured message protected via SPDM session.
|
||||
* If session_id is NULL, it is a normal message.
|
||||
* If session_id is NOT NULL, it is a secured message.
|
||||
* @param is_app_message Indicates if it is an APP message or SPDM message.
|
||||
* @param is_requester Indicates if it is a requester message.
|
||||
* @param message_size size in bytes of the message data buffer.
|
||||
* @param message A pointer to a source buffer to store the message.
|
||||
* For normal message, it shall point to the acquired sender buffer.
|
||||
* For secured message, it shall point to the scratch buffer in spdm_context.
|
||||
* @param transport_message_size size in bytes of the transport message data buffer.
|
||||
* @param transport_message A pointer to a destination buffer to store the transport message.
|
||||
* On input, it shall be msg_buf_ptr from sender buffer.
|
||||
* On output, it will point to acquired sender buffer.
|
||||
*
|
||||
* @retval RETURN_SUCCESS The message is encoded successfully.
|
||||
* @retval RETURN_INVALID_PARAMETER The message is NULL or the message_size is zero.
|
||||
**/
|
||||
typedef
|
||||
SPDM_RETURN
|
||||
(*SPDM_TRANSPORT_ENCODE_MESSAGE_FUNC)(
|
||||
IN VOID *SpdmContext,
|
||||
IN OUT CONST UINT32 *SessionId,
|
||||
IN BOOLEAN IsAppMessage,
|
||||
IN BOOLEAN IsRequester,
|
||||
IN UINTN MessageSize,
|
||||
IN OUT VOID *Message,
|
||||
IN OUT UINTN *TransportMessageSize,
|
||||
IN VOID **TransportMessage
|
||||
);
|
||||
|
||||
/**
|
||||
* Decode an SPDM or APP message from a transport layer message.
|
||||
*
|
||||
* For normal SPDM message, it removes the transport layer wrapper,
|
||||
* For secured SPDM message, it removes the transport layer wrapper, then decrypts and verifies a secured message.
|
||||
* For secured APP message, it removes the transport layer wrapper, then decrypts and verifies a secured message.
|
||||
*
|
||||
* The APP message is decoded from a secured message directly in SPDM session.
|
||||
* The APP message format is defined by the transport layer.
|
||||
* Take MCTP as example: APP message == MCTP header (MCTP_MESSAGE_TYPE_SPDM) + SPDM message
|
||||
*
|
||||
* @param spdm_context A pointer to the SPDM context.
|
||||
* @param session_id Indicates if it is a secured message protected via SPDM session.
|
||||
* If *session_id is NULL, it is a normal message.
|
||||
* If *session_id is NOT NULL, it is a secured message.
|
||||
* @param is_app_message Indicates if it is an APP message or SPDM message.
|
||||
* @param is_requester Indicates if it is a requester message.
|
||||
* @param transport_message_size size in bytes of the transport message data buffer.
|
||||
* @param transport_message A pointer to a source buffer to store the transport message.
|
||||
* For normal message or secured message, it shall point to acquired receiver buffer.
|
||||
* @param message_size size in bytes of the message data buffer.
|
||||
* @param message A pointer to a destination buffer to store the message.
|
||||
* On input, it shall point to the scratch buffer in spdm_context.
|
||||
* On output, for normal message, it will point to the original receiver buffer.
|
||||
* On output, for secured message, it will point to the scratch buffer in spdm_context.
|
||||
*
|
||||
* @retval RETURN_SUCCESS The message is decoded successfully.
|
||||
* @retval RETURN_INVALID_PARAMETER The message is NULL or the message_size is zero.
|
||||
* @retval RETURN_UNSUPPORTED The transport_message is unsupported.
|
||||
**/
|
||||
typedef
|
||||
SPDM_RETURN
|
||||
(*SPDM_TRANSPORT_DECODE_MESSAGE_FUNC)(
|
||||
IN VOID *SpdmContext,
|
||||
IN OUT UINT32 **SessionId,
|
||||
IN BOOLEAN *IsAppMessage,
|
||||
IN BOOLEAN IsRequester,
|
||||
IN UINTN TransportMessageSize,
|
||||
IN OUT VOID *TransportMessage,
|
||||
IN OUT UINTN *MessageSize,
|
||||
IN OUT VOID **Message
|
||||
);
|
||||
|
||||
/**
|
||||
* Acquire a device sender buffer for transport layer message.
|
||||
*
|
||||
* The max_msg_size must be larger than
|
||||
* MAX (non-secure Transport Message Header Size +
|
||||
* SPDM_CAPABILITIES.DataTransferSize +
|
||||
* max alignment pad size (transport specific),
|
||||
* secure Transport Message Header Size +
|
||||
* sizeof(spdm_secured_message_a_data_header1_t) +
|
||||
* length of sequence_number (transport specific) +
|
||||
* sizeof(spdm_secured_message_a_data_header2_t) +
|
||||
* sizeof(spdm_secured_message_cipher_header_t) +
|
||||
* App Message Header Size (transport specific) +
|
||||
* SPDM_CAPABILITIES.DataTransferSize +
|
||||
* maximum random data size (transport specific) +
|
||||
* AEAD MAC size (16) +
|
||||
* max alignment pad size (transport specific))
|
||||
*
|
||||
* For MCTP,
|
||||
* Transport Message Header Size = sizeof(mctp_message_header_t)
|
||||
* length of sequence_number = 2
|
||||
* App Message Header Size = sizeof(mctp_message_header_t)
|
||||
* maximum random data size = MCTP_MAX_RANDOM_NUMBER_COUNT
|
||||
* max alignment pad size = 0
|
||||
* For PCI_DOE,
|
||||
* Transport Message Header Size = sizeof(pci_doe_data_object_header_t)
|
||||
* length of sequence_number = 0
|
||||
* App Message Header Size = 0
|
||||
* maximum random data size = 0
|
||||
* max alignment pad size = 3
|
||||
*
|
||||
* @param context A pointer to the SPDM context.
|
||||
* @param max_msg_size size in bytes of the maximum size of sender buffer.
|
||||
* @param msg_buf_ptr A pointer to a sender buffer.
|
||||
*
|
||||
* @retval RETURN_SUCCESS The sender buffer is acquired.
|
||||
**/
|
||||
typedef
|
||||
SPDM_RETURN
|
||||
(*SPDM_DEVICE_ACQUIRE_SENDER_BUFFER_FUNC)(
|
||||
IN VOID *SpdmContext,
|
||||
IN OUT VOID **MsgBufPtr
|
||||
);
|
||||
|
||||
/**
|
||||
* Release a device sender buffer for transport layer message.
|
||||
*
|
||||
* @param context A pointer to the SPDM context.
|
||||
* @param msg_buf_ptr A pointer to a sender buffer.
|
||||
*
|
||||
* @retval RETURN_SUCCESS The sender buffer is Released.
|
||||
**/
|
||||
typedef
|
||||
VOID
|
||||
(*SPDM_DEVICE_RELEASE_SENDER_BUFFER_FUNC)(
|
||||
IN VOID *SpdmContext,
|
||||
IN CONST VOID *MsgBufPtr
|
||||
);
|
||||
|
||||
/**
|
||||
* Acquire a device receiver buffer for transport layer message.
|
||||
*
|
||||
* The max_msg_size must be larger than
|
||||
* MAX (non-secure Transport Message Header Size +
|
||||
* SPDM_CAPABILITIES.DataTransferSize +
|
||||
* max alignment pad size (transport specific),
|
||||
* secure Transport Message Header Size +
|
||||
* sizeof(spdm_secured_message_a_data_header1_t) +
|
||||
* length of sequence_number (transport specific) +
|
||||
* sizeof(spdm_secured_message_a_data_header2_t) +
|
||||
* sizeof(spdm_secured_message_cipher_header_t) +
|
||||
* App Message Header Size (transport specific) +
|
||||
* SPDM_CAPABILITIES.DataTransferSize +
|
||||
* maximum random data size (transport specific) +
|
||||
* AEAD MAC size (16) +
|
||||
* max alignment pad size (transport specific))
|
||||
*
|
||||
* For MCTP,
|
||||
* Transport Message Header Size = sizeof(mctp_message_header_t)
|
||||
* length of sequence_number = 2
|
||||
* App Message Header Size = sizeof(mctp_message_header_t)
|
||||
* maximum random data size = MCTP_MAX_RANDOM_NUMBER_COUNT
|
||||
* max alignment pad size = 0
|
||||
* For PCI_DOE,
|
||||
* Transport Message Header Size = sizeof(pci_doe_data_object_header_t)
|
||||
* length of sequence_number = 0
|
||||
* App Message Header Size = 0
|
||||
* maximum random data size = 0
|
||||
* max alignment pad size = 3
|
||||
*
|
||||
* @param context A pointer to the SPDM context.
|
||||
* @param max_msg_size size in bytes of the maximum size of receiver buffer.
|
||||
* @param msg_buf_pt A pointer to a receiver buffer.
|
||||
*
|
||||
* @retval RETURN_SUCCESS The receiver buffer is acquired.
|
||||
**/
|
||||
typedef
|
||||
SPDM_RETURN
|
||||
(*SPDM_DEVICE_ACQUIRE_RECEIVER_BUFFER_FUNC)(
|
||||
IN VOID *SpdmContext,
|
||||
IN OUT VOID **MsgBufPtr
|
||||
);
|
||||
|
||||
/**
|
||||
* Release a device receiver buffer for transport layer message.
|
||||
*
|
||||
* @param context A pointer to the SPDM context.
|
||||
* @param msg_buf_ptr A pointer to a receiver buffer.
|
||||
*
|
||||
* @retval RETURN_SUCCESS The receiver buffer is Released.
|
||||
**/
|
||||
typedef
|
||||
VOID
|
||||
(*SPDM_DEVICE_RELEASE_RECEIVER_BUFFER_FUNC)(
|
||||
IN VOID *SpdmContext,
|
||||
IN CONST VOID *MsgBufPtr
|
||||
);
|
||||
|
||||
typedef struct {
|
||||
UINT32 Version;
|
||||
//
|
||||
// DeviceType is used to create TCG event log context_data.
|
||||
// DeviceHandle is used to create TCG event log device_path information.
|
||||
//
|
||||
EDKII_DEVICE_IDENTIFIER *DeviceId;
|
||||
|
||||
//
|
||||
// TRUE means to use PCR 0 (code) / 1 (config).
|
||||
// FALSE means to use PCR 2 (code) / 3 (config).
|
||||
//
|
||||
BOOLEAN IsEmbeddedDevice;
|
||||
|
||||
//
|
||||
// Below 9 APIs are used to send/receive SPDM request/response.
|
||||
//
|
||||
// The request flow is:
|
||||
// |<--- SenderBufferSize --->|
|
||||
// |<--- TransportRequestBufferSize --->|
|
||||
// |<---MaxHeaderSize--->|<-SpdmRequestBufferSize ->|
|
||||
// +--+------------------+==========================+----------------+--+
|
||||
// | | Transport Header | SPDM Message | Transport Tail | |
|
||||
// +--+------------------+==========================+----------------+--+
|
||||
// ^ ^ ^
|
||||
// | | | SpdmRequestBuffer
|
||||
// | | TransportRequestBuffer
|
||||
// | SenderBuffer
|
||||
//
|
||||
// AcquireSenderBuffer (&SenderBuffer, &SenderBufferSize);
|
||||
// SpdmRequestBuffer = SenderBuffer + TransportHeaderSize;
|
||||
// /* build SPDM request in SpdmRequestBuffer */
|
||||
// TransportEncodeMessage (SpdmRequestBuffer, SpdmRequestBufferSize,
|
||||
// &TransportRequestBuffer, &TransportRequestBufferSize);
|
||||
// SendMessage (TransportRequestBuffer, TransportRequestBufferSize);
|
||||
// ReleaseSenderBuffer (SenderBuffer);
|
||||
//
|
||||
// The response flow is:
|
||||
// |<--- ReceiverBufferSize --->|
|
||||
// |<--- TransportResponseBufferSize --->|
|
||||
// |<-SpdmResponseBufferSize->|
|
||||
// +--+------------------+==========================+----------------+--+
|
||||
// | | Transport Header | SPDM Message | Transport Tail | |
|
||||
// +--+------------------+==========================+----------------+--+
|
||||
// ^ ^ ^
|
||||
// | | | SpdmResponseBuffer
|
||||
// | | TransportResponseBuffer
|
||||
// | ReceiverBuffer
|
||||
//
|
||||
// AcquireReceiverBuffer (&ReceiverBuffer, &ReceiverBufferSize);
|
||||
// TransportResponseBuffer = ReceiverBuffer;
|
||||
// ReceiveMessage (&TransportResponseBuffer, &TransportResponseBufferSize);
|
||||
// TransportDecodeMessage (TransportResponseBuffer, TransportResponseBufferSize,
|
||||
// &SpdmResponseBuffer, &SpdmResponseBufferSize);
|
||||
// /* process SPDM response in SpdmResponseBuffer */
|
||||
// ReleaseReceiverBuffer (ReceiverBuffer);
|
||||
//
|
||||
|
||||
//
|
||||
// API required by SpdmRegisterDeviceIoFunc in libspdm
|
||||
// It is used to send/receive transport message (SPDM + transport header).
|
||||
//
|
||||
SPDM_DEVICE_SEND_MESSAGE_FUNC SendMessage;
|
||||
SPDM_DEVICE_RECEIVE_MESSAGE_FUNC ReceiveMessage;
|
||||
//
|
||||
// API required by SpdmRegisterTransportLayerFunc in libspdm
|
||||
// It is used to add/remove transport header for SPDM.
|
||||
//
|
||||
SPDM_TRANSPORT_ENCODE_MESSAGE_FUNC TransportEncodeMessage;
|
||||
SPDM_TRANSPORT_DECODE_MESSAGE_FUNC TransportDecodeMessage;
|
||||
//
|
||||
// API required by SpdmRegisterDeviceBufferFunc in libspdm
|
||||
// It is used to get the sender/receiver buffer for transport message (SPDM + transport header).
|
||||
// The size MUST be big enough to send or receive one transport message (SPDM + transport header).
|
||||
// Tthe sender/receiver buffer MAY be overlapped.
|
||||
//
|
||||
SPDM_DEVICE_ACQUIRE_SENDER_BUFFER_FUNC AcquireSenderBuffer;
|
||||
SPDM_DEVICE_RELEASE_SENDER_BUFFER_FUNC ReleaseSenderBuffer;
|
||||
SPDM_DEVICE_ACQUIRE_RECEIVER_BUFFER_FUNC AcquireReceiverBuffer;
|
||||
SPDM_DEVICE_RELEASE_RECEIVER_BUFFER_FUNC ReleaseReceiverBuffer;
|
||||
|
||||
//
|
||||
// Preferred Algorithm List for SPDM negotiation.
|
||||
// If it is none zero, it will be used directly.
|
||||
// If it is zero, then the SpdmSecurityLib will set the default value.
|
||||
//
|
||||
UINT32 BaseHashAlgo;
|
||||
UINT32 BaseAsymAlgo;
|
||||
|
||||
//
|
||||
// transfer size
|
||||
//
|
||||
UINT32 MaxSpdmMsgSize;
|
||||
UINT32 TransportHeaderSize;
|
||||
UINT32 TransportTailSize;
|
||||
UINT32 SenderBufferSize;
|
||||
UINT32 ReceiverBufferSize;
|
||||
|
||||
EFI_GUID *SpdmIoProtocolGuid;
|
||||
} EDKII_SPDM_DEVICE_INFO;
|
||||
|
||||
/**
|
||||
This function will send SPDM VCA, GET_CERTIFICATE, CHALLENGE, GET_MEASUREMENT,
|
||||
The certificate and measurement will be extended to TPM PCR/NvIndex.
|
||||
**/
|
||||
RETURN_STATUS
|
||||
EFIAPI
|
||||
SpdmDeviceAuthenticationAndMeasurement (
|
||||
IN EDKII_SPDM_DEVICE_INFO *SpdmDeviceInfo,
|
||||
IN EDKII_DEVICE_SECURITY_POLICY *SecurityPolicy,
|
||||
OUT EDKII_DEVICE_SECURITY_STATE *SecurityState
|
||||
);
|
||||
|
||||
/**
|
||||
This function will get SpdmIoProtocol via Context.
|
||||
**/
|
||||
VOID *
|
||||
EFIAPI
|
||||
SpdmGetIoProtocolViaSpdmContext (
|
||||
IN VOID *SpdmContext
|
||||
);
|
||||
|
||||
/**
|
||||
Helper function to quickly determine whether device authentication boot is enabled.
|
||||
|
||||
@retval TRUE device authentication boot is verifiably enabled.
|
||||
@retval FALSE device authentication boot is either disabled or an error prevented checking.
|
||||
|
||||
**/
|
||||
BOOLEAN
|
||||
EFIAPI
|
||||
IsDeviceAuthBootEnabled (
|
||||
VOID
|
||||
);
|
||||
|
||||
#endif
|
133
SecurityPkg/Include/Protocol/DeviceSecurityPolicy.h
Normal file
133
SecurityPkg/Include/Protocol/DeviceSecurityPolicy.h
Normal file
@ -0,0 +1,133 @@
|
||||
/** @file
|
||||
Platform Device Security Policy Protocol definition
|
||||
|
||||
Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
**/
|
||||
|
||||
#ifndef EDKII_DEVICE_SECURITY_POLICY_PROTOCOL_H_
|
||||
#define EDKII_DEVICE_SECURITY_POLICY_PROTOCOL_H_
|
||||
|
||||
#include <Uefi.h>
|
||||
#include <Protocol/DeviceSecurity.h>
|
||||
|
||||
typedef struct _EDKII_DEVICE_SECURITY_POLICY_PROTOCOL EDKII_DEVICE_SECURITY_POLICY_PROTOCOL;
|
||||
|
||||
//
|
||||
// Revision The revision to which the DEVICE_SECURITY_POLICY protocol interface adheres.
|
||||
// All future revisions must be backwards compatible.
|
||||
// If a future version is not back wards compatible it is not the same GUID.
|
||||
//
|
||||
#define EDKII_DEVICE_SECURITY_POLICY_PROTOCOL_REVISION 0x00010000
|
||||
|
||||
//
|
||||
// Revision The revision to which the DEVICE_SECURITY_POLICY structure adheres.
|
||||
// All future revisions must be backwards compatible.
|
||||
//
|
||||
#define EDKII_DEVICE_SECURITY_POLICY_REVISION 0x00010000
|
||||
|
||||
///
|
||||
/// The macro for the policy defined in EDKII_DEVICE_SECURITY_POLICY
|
||||
///
|
||||
#define EDKII_DEVICE_MEASUREMENT_REQUIRED BIT0
|
||||
#define EDKII_DEVICE_AUTHENTICATION_REQUIRED BIT0
|
||||
|
||||
///
|
||||
/// The device security policy data structure
|
||||
///
|
||||
typedef struct {
|
||||
UINT32 Revision;
|
||||
UINT32 MeasurementPolicy;
|
||||
UINT32 AuthenticationPolicy;
|
||||
} EDKII_DEVICE_SECURITY_POLICY;
|
||||
|
||||
//
|
||||
// Revision The revision to which the DEVICE_SECURITY_STATE structure adheres.
|
||||
// All future revisions must be backwards compatible.
|
||||
//
|
||||
#define EDKII_DEVICE_SECURITY_STATE_REVISION 0x00010000
|
||||
|
||||
///
|
||||
/// The macro for the state defined in EDKII_DEVICE_SECURITY_STATE
|
||||
///
|
||||
#define EDKII_DEVICE_SECURITY_STATE_SUCCESS 0
|
||||
#define EDKII_DEVICE_SECURITY_STATE_ERROR BIT31
|
||||
#define EDKII_DEVICE_SECURITY_STATE_ERROR_UEFI_UNSUPPORTED (EDKII_DEVICE_SECURITY_STATE_ERROR + 0x0)
|
||||
#define EDKII_DEVICE_SECURITY_STATE_ERROR_UEFI_GET_POLICY_PROTOCOL (EDKII_DEVICE_SECURITY_STATE_ERROR + 0x1)
|
||||
#define EDKII_DEVICE_SECURITY_STATE_ERROR_UEFI_OUT_OF_RESOURCE (EDKII_DEVICE_SECURITY_STATE_ERROR + 0x2)
|
||||
#define EDKII_DEVICE_SECURITY_STATE_ERROR_DEVICE_NO_CAPABILITIES (EDKII_DEVICE_SECURITY_STATE_ERROR + 0x10)
|
||||
#define EDKII_DEVICE_SECURITY_STATE_ERROR_DEVICE_ERROR (EDKII_DEVICE_SECURITY_STATE_ERROR + 0x11)
|
||||
#define EDKII_DEVICE_SECURITY_STATE_ERROR_TCG_EXTEND_TPM_PCR (EDKII_DEVICE_SECURITY_STATE_ERROR + 0x20)
|
||||
#define EDKII_DEVICE_SECURITY_STATE_ERROR_MEASUREMENT_AUTH_FAILURE (EDKII_DEVICE_SECURITY_STATE_ERROR + 0x21)
|
||||
#define EDKII_DEVICE_SECURITY_STATE_ERROR_CHALLENGE_FAILURE (EDKII_DEVICE_SECURITY_STATE_ERROR + 0x30)
|
||||
#define EDKII_DEVICE_SECURITY_STATE_ERROR_CERTIFIACTE_FAILURE (EDKII_DEVICE_SECURITY_STATE_ERROR + 0x31)
|
||||
#define EDKII_DEVICE_SECURITY_STATE_ERROR_NO_CERT_PROVISION (EDKII_DEVICE_SECURITY_STATE_ERROR + 0x32)
|
||||
|
||||
///
|
||||
/// The device security state data structure
|
||||
///
|
||||
typedef struct {
|
||||
UINT32 Revision;
|
||||
UINT32 MeasurementState;
|
||||
UINT32 AuthenticationState;
|
||||
} EDKII_DEVICE_SECURITY_STATE;
|
||||
|
||||
/**
|
||||
This function returns the device security policy associated with the device.
|
||||
|
||||
The device security driver may call this interface to get the platform policy
|
||||
for the specific device and determine if the measurement or authentication
|
||||
is required.
|
||||
|
||||
@param[in] This The protocol instance pointer.
|
||||
@param[in] DeviceId The Identifier for the device.
|
||||
@param[out] DeviceSecurityPolicy The Device Security Policy associated with the device.
|
||||
|
||||
@retval EFI_SUCCESS The device security policy is returned
|
||||
@retval EFI_UNSUPPORTED The function is unsupported for the specific Device.
|
||||
**/
|
||||
typedef
|
||||
EFI_STATUS
|
||||
(EFIAPI *EDKII_DEVICE_SECURITY_GET_DEVICE_POLICY)(
|
||||
IN EDKII_DEVICE_SECURITY_POLICY_PROTOCOL *This,
|
||||
IN EDKII_DEVICE_IDENTIFIER *DeviceId,
|
||||
OUT EDKII_DEVICE_SECURITY_POLICY *DeviceSecurityPolicy
|
||||
);
|
||||
|
||||
/**
|
||||
This function sets the device state based upon the authentication result.
|
||||
|
||||
The device security driver may call this interface to give the platform
|
||||
a notify based upon the measurement or authentication result.
|
||||
If the authentication or measurement fails, the platform may choose:
|
||||
1) Do nothing.
|
||||
2) Disable this device or slot temporarily and continue boot.
|
||||
3) Reset the platform and retry again.
|
||||
4) Disable this device or slot permanently.
|
||||
5) Any other platform specific action.
|
||||
|
||||
@param[in] This The protocol instance pointer.
|
||||
@param[in] DeviceId The Identifier for the device.
|
||||
@param[in] DeviceSecurityState The Device Security state associated with the device.
|
||||
|
||||
@retval EFI_SUCCESS The device state is set.
|
||||
@retval EFI_UNSUPPORTED The function is unsupported for the specific Device.
|
||||
**/
|
||||
typedef
|
||||
EFI_STATUS
|
||||
(EFIAPI *EDKII_DEVICE_SECURITY_NOTIFY_DEVICE_STATE)(
|
||||
IN EDKII_DEVICE_SECURITY_POLICY_PROTOCOL *This,
|
||||
IN EDKII_DEVICE_IDENTIFIER *DeviceId,
|
||||
IN EDKII_DEVICE_SECURITY_STATE *DeviceSecurityState
|
||||
);
|
||||
|
||||
struct _EDKII_DEVICE_SECURITY_POLICY_PROTOCOL {
|
||||
UINT32 Revision;
|
||||
EDKII_DEVICE_SECURITY_GET_DEVICE_POLICY GetDevicePolicy;
|
||||
EDKII_DEVICE_SECURITY_NOTIFY_DEVICE_STATE NotifyDeviceState;
|
||||
};
|
||||
|
||||
extern EFI_GUID gEdkiiDeviceSecurityPolicyProtocolGuid;
|
||||
|
||||
#endif
|
@ -2,12 +2,14 @@
|
||||
# CI configuration for SecurityPkg
|
||||
#
|
||||
# Copyright (c) Microsoft Corporation
|
||||
# Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
|
||||
# Copyright (c) 2020 - 2024, Intel Corporation. All rights reserved.<BR>
|
||||
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
##
|
||||
{
|
||||
"LicenseCheck": {
|
||||
"IgnoreFiles": []
|
||||
"IgnoreFiles": [
|
||||
"DeviceSecurity/SpdmLib/Include",
|
||||
]
|
||||
},
|
||||
"EccCheck": {
|
||||
## Exception sample looks like below:
|
||||
@ -23,7 +25,10 @@
|
||||
"IgnoreFiles": [
|
||||
"Library/TcgStorageCoreLib/TcgStorageUtil.c",
|
||||
"Library/TcgStorageCoreLib/TcgStorageCore.c",
|
||||
"Library/Tpm2CommandLib/Tpm2NVStorage.c"
|
||||
"Library/Tpm2CommandLib/Tpm2NVStorage.c",
|
||||
"DeviceSecurity/SpdmLib/Include",
|
||||
"DeviceSecurity/SpdmLib/libspdm",
|
||||
"DeviceSecurity/OsStub"
|
||||
]
|
||||
},
|
||||
"CompilerPlugin": {
|
||||
@ -69,7 +74,11 @@
|
||||
]
|
||||
},
|
||||
"LibraryClassCheck": {
|
||||
"IgnoreHeaderFile": []
|
||||
"IgnoreHeaderFile": [
|
||||
"DeviceSecurity/SpdmLib/Include/library",
|
||||
"DeviceSecurity/SpdmLib/libspdm/include/library",
|
||||
],
|
||||
"skip": True
|
||||
},
|
||||
|
||||
## options defined ci/Plugin/SpellCheck
|
||||
|
@ -5,7 +5,7 @@
|
||||
# It also provides the definitions(including PPIs/PROTOCOLs/GUIDs and library classes)
|
||||
# and libraries instances, which are used for those features.
|
||||
#
|
||||
# Copyright (c) 2009 - 2020, Intel Corporation. All rights reserved.<BR>
|
||||
# Copyright (c) 2009 - 2024, Intel Corporation. All rights reserved.<BR>
|
||||
# (C) Copyright 2015 Hewlett Packard Enterprise Development LP <BR>
|
||||
# Copyright (c) Microsoft Corporation.<BR>
|
||||
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
@ -23,6 +23,10 @@
|
||||
Include
|
||||
Test/Mock/Include
|
||||
|
||||
[Includes.Common.Private]
|
||||
DeviceSecurity/SpdmLib/Include
|
||||
DeviceSecurity/SpdmLib/libspdm/include
|
||||
|
||||
[LibraryClasses]
|
||||
## @libraryclass Provides hash interfaces from different implementations.
|
||||
#
|
||||
@ -97,6 +101,10 @@
|
||||
#
|
||||
PlatformPKProtectionLib|Include/Library/PlatformPKProtectionLib.h
|
||||
|
||||
## @libraryclass Perform SPDM (following SPDM spec) and measure data to TPM (following TCG PFP spec).
|
||||
##
|
||||
SpdmSecurityLib|Include/Library/SpdmSecurityLib.h
|
||||
|
||||
[Guids]
|
||||
## Security package token space guid.
|
||||
# Include/Guid/SecurityPkgTokenSpace.h
|
||||
@ -219,6 +227,9 @@
|
||||
## GUID used to specify section with default dbt content
|
||||
gDefaultdbtFileGuid = { 0x36c513ee, 0xa338, 0x4976, { 0xa0, 0xfb, 0x6d, 0xdb, 0xa3, 0xda, 0xfe, 0x87 } }
|
||||
|
||||
## GUID used to generate Spdm Uid
|
||||
gEfiDeviceSecuritySpdmUidGuid = {0xe37b5665, 0x5ef9, 0x4e7e, {0xb4, 0x91, 0xd6, 0x78, 0xab, 0xff, 0xfb, 0xcb }}
|
||||
|
||||
[Ppis]
|
||||
## The PPI GUID for that TPM physical presence should be locked.
|
||||
# Include/Ppi/LockPhysicalPresence.h
|
||||
|
@ -1,7 +1,7 @@
|
||||
## @file
|
||||
# Security Module Package for All Architectures.
|
||||
#
|
||||
# Copyright (c) 2009 - 2021, Intel Corporation. All rights reserved.<BR>
|
||||
# Copyright (c) 2009 - 2024, Intel Corporation. All rights reserved.<BR>
|
||||
# (C) Copyright 2015-2020 Hewlett Packard Enterprise Development LP<BR>
|
||||
# Copyright (c) 2022, Loongson Technology Corporation Limited. All rights reserved.<BR>
|
||||
# Copyright (c) 2021 - 2022, Arm Limited. All rights reserved.<BR>
|
||||
@ -76,6 +76,19 @@
|
||||
TdxLib|MdePkg/Library/TdxLib/TdxLib.inf
|
||||
VariablePolicyHelperLib|MdeModulePkg/Library/VariablePolicyHelperLib/VariablePolicyHelperLib.inf
|
||||
|
||||
SpdmSecurityLib|SecurityPkg/DeviceSecurity/SpdmSecurityLib/SpdmSecurityLib.inf
|
||||
SpdmDeviceSecretLib|SecurityPkg/DeviceSecurity/SpdmLib/SpdmDeviceSecretLibNull.inf
|
||||
SpdmCryptLib|SecurityPkg/DeviceSecurity/SpdmLib/SpdmCryptLib.inf
|
||||
SpdmCommonLib|SecurityPkg/DeviceSecurity/SpdmLib/SpdmCommonLib.inf
|
||||
SpdmRequesterLib|SecurityPkg/DeviceSecurity/SpdmLib/SpdmRequesterLib.inf
|
||||
SpdmResponderLib|SecurityPkg/DeviceSecurity/SpdmLib/SpdmResponderLib.inf
|
||||
SpdmSecuredMessageLib|SecurityPkg/DeviceSecurity/SpdmLib/SpdmSecuredMessageLib.inf
|
||||
SpdmTransportMctpLib|SecurityPkg/DeviceSecurity/SpdmLib/SpdmTransportMctpLib.inf
|
||||
SpdmTransportPciDoeLib|SecurityPkg/DeviceSecurity/SpdmLib/SpdmTransportPciDoeLib.inf
|
||||
CryptlibWrapper|SecurityPkg/DeviceSecurity/OsStub/CryptlibWrapper/CryptlibWrapper.inf
|
||||
PlatformLibWrapper|SecurityPkg/DeviceSecurity/OsStub/PlatformLibWrapper/PlatformLibWrapper.inf
|
||||
MemLibWrapper|SecurityPkg/DeviceSecurity/OsStub/MemLibWrapper/MemLibWrapper.inf
|
||||
|
||||
[LibraryClasses.ARM, LibraryClasses.AARCH64]
|
||||
#
|
||||
# It is not possible to prevent the ARM compiler for generic intrinsic functions.
|
||||
@ -287,6 +300,22 @@
|
||||
#
|
||||
SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf
|
||||
|
||||
#
|
||||
# SPDM
|
||||
#
|
||||
SecurityPkg/DeviceSecurity/SpdmSecurityLib/SpdmSecurityLib.inf
|
||||
SecurityPkg/DeviceSecurity/SpdmLib/SpdmDeviceSecretLibNull.inf
|
||||
SecurityPkg/DeviceSecurity/SpdmLib/SpdmCryptLib.inf
|
||||
SecurityPkg/DeviceSecurity/SpdmLib/SpdmCommonLib.inf
|
||||
SecurityPkg/DeviceSecurity/SpdmLib/SpdmRequesterLib.inf
|
||||
SecurityPkg/DeviceSecurity/SpdmLib/SpdmResponderLib.inf
|
||||
SecurityPkg/DeviceSecurity/SpdmLib/SpdmSecuredMessageLib.inf
|
||||
SecurityPkg/DeviceSecurity/SpdmLib/SpdmTransportMctpLib.inf
|
||||
SecurityPkg/DeviceSecurity/SpdmLib/SpdmTransportPciDoeLib.inf
|
||||
SecurityPkg/DeviceSecurity/OsStub/CryptlibWrapper/CryptlibWrapper.inf
|
||||
SecurityPkg/DeviceSecurity/OsStub/PlatformLibWrapper/PlatformLibWrapper.inf
|
||||
SecurityPkg/DeviceSecurity/OsStub/MemLibWrapper/MemLibWrapper.inf
|
||||
|
||||
[Components.IA32, Components.X64]
|
||||
SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user