Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,20 @@ set(DEVICE ${DEVICE} CACHE STRING "Choose the test device: sample tpm, and defau

option(LIBSPDM_TPM_SUPPORT "Add TPM support in crypt_ext" OFF)

# TPM Handle Configuration Options (slot-based configuration)
# Root and leaf certificates are extracted from certificate chains
# Requester handles
set(LIBSPDM_TPM_HANDLE_REQUESTER_HANDLE_SLOT_0 "handle:0x81000011" CACHE STRING "TPM Requester Handle String Slot 0")
set(LIBSPDM_TPM_HANDLE_REQUESTER_CERTCHAIN_SLOT_0 "0x1500011" CACHE STRING "TPM Requester Certificate Chain NV Index Slot 0")
set(LIBSPDM_TPM_HANDLE_REQUESTER_HANDLE_SLOT_1 "handle:0x81000012" CACHE STRING "TPM Requester Handle String Slot 1")
set(LIBSPDM_TPM_HANDLE_REQUESTER_CERTCHAIN_SLOT_1 "0x1500012" CACHE STRING "TPM Requester Certificate Chain NV Index Slot 1")

# Responder handles
set(LIBSPDM_TPM_HANDLE_RESPONDER_HANDLE_SLOT_0 "handle:0x81000021" CACHE STRING "TPM Responder Handle String Slot 0")
set(LIBSPDM_TPM_HANDLE_RESPONDER_CERTCHAIN_SLOT_0 "0x1500021" CACHE STRING "TPM Responder Certificate Chain NV Index Slot 0")
set(LIBSPDM_TPM_HANDLE_RESPONDER_HANDLE_SLOT_1 "handle:0x81000022" CACHE STRING "TPM Responder Handle String Slot 1")
set(LIBSPDM_TPM_HANDLE_RESPONDER_CERTCHAIN_SLOT_1 "0x1500031" CACHE STRING "TPM Responder Certificate Chain NV Index Slot 1")

if(NOT GCOV)
set(GCOV "OFF")
endif()
Expand Down
8 changes: 8 additions & 0 deletions os_stub/spdm_device_secret_lib_tpm/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,9 +1,17 @@
cmake_minimum_required(VERSION 3.5)

# Configure keys.h from template with CMake variables
configure_file(
${CMAKE_CURRENT_SOURCE_DIR}/keys.h.in
${CMAKE_CURRENT_BINARY_DIR}/keys.h
@ONLY
)

add_library(spdm_device_secret_lib_tpm STATIC "")

target_include_directories(spdm_device_secret_lib_tpm
PRIVATE
${CMAKE_CURRENT_BINARY_DIR}
${LIBSPDM_DIR}/os_stub/spdm_device_secret_lib_tpm
${LIBSPDM_DIR}/include
${LIBSPDM_DIR}/include/hal
Expand Down
16 changes: 13 additions & 3 deletions os_stub/spdm_device_secret_lib_tpm/csr.c
Original file line number Diff line number Diff line change
Expand Up @@ -117,17 +117,27 @@ bool libspdm_gen_csr_without_reset(uint32_t base_hash_algo, uint32_t base_asym_a

void *cert;
void *x509_ca_cert;
size_t x509_ca_cert_len;
int8_t cert_count;
size_t cert_size;

if (!libspdm_tpm_get_pvt_key_handle(TPM_RESP_HANDLE, &context)) {
if (!libspdm_tpm_get_pvt_key_handle(LIBSPDM_TPM_HANDLE_RESPONDER_HANDLE_SLOT_0, &context)) {
return false;
}

if (!libspdm_tpm_read_nv(TPM_RESP_CERT, &cert, &cert_size)) {
if (!libspdm_tpm_read_nv(LIBSPDM_TPM_HANDLE_RESPONDER_CERTCHAIN_SLOT_1, &cert, &cert_size)) {
return false;
}

if (!libspdm_x509_construct_certificate(cert, cert_size, (uint8_t**)&x509_ca_cert)) {
cert_count = libspdm_x509_get_cert_from_cert_chain(cert, cert_size, -1, NULL, NULL);
if (cert_count <= 0) {
free(cert);
return false;
}

if (!libspdm_x509_get_cert_from_cert_chain(cert, cert_size, cert_count-1, (const uint8_t**) &x509_ca_cert,
&x509_ca_cert_len)) {
free(cert);
return false;
}

Expand Down
25 changes: 0 additions & 25 deletions os_stub/spdm_device_secret_lib_tpm/keys.h

This file was deleted.

28 changes: 28 additions & 0 deletions os_stub/spdm_device_secret_lib_tpm/keys.h.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/**
* Copyright Notice:
* Copyright 2024-2025 DMTF. All rights reserved.
* License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/libspdm/blob/main/LICENSE.md
**/

#pragma once

/* TPM Requester Handles - Slot 0 */
#cmakedefine LIBSPDM_TPM_HANDLE_REQUESTER_HANDLE_SLOT_0 "@LIBSPDM_TPM_HANDLE_REQUESTER_HANDLE_SLOT_0@"
#cmakedefine LIBSPDM_TPM_HANDLE_REQUESTER_CERTCHAIN_SLOT_0 @LIBSPDM_TPM_HANDLE_REQUESTER_CERTCHAIN_SLOT_0@

/* TPM Requester Handles - Slot 1 */
#cmakedefine LIBSPDM_TPM_HANDLE_REQUESTER_HANDLE_SLOT_1 "@LIBSPDM_TPM_HANDLE_REQUESTER_HANDLE_SLOT_1@"
#cmakedefine LIBSPDM_TPM_HANDLE_REQUESTER_CERTCHAIN_SLOT_1 @LIBSPDM_TPM_HANDLE_REQUESTER_CERTCHAIN_SLOT_1@

/* TPM Responder Handles - Slot 0 */
#cmakedefine LIBSPDM_TPM_HANDLE_RESPONDER_HANDLE_SLOT_0 "@LIBSPDM_TPM_HANDLE_RESPONDER_HANDLE_SLOT_0@"
#cmakedefine LIBSPDM_TPM_HANDLE_RESPONDER_CERT_SLOT_0 @LIBSPDM_TPM_HANDLE_RESPONDER_CERT_SLOT_0@
#cmakedefine LIBSPDM_TPM_HANDLE_RESPONDER_CERTCHAIN_SLOT_0 @LIBSPDM_TPM_HANDLE_RESPONDER_CERTCHAIN_SLOT_0@

/* TPM Responder Handles - Slot 1 */
#cmakedefine LIBSPDM_TPM_HANDLE_RESPONDER_HANDLE_SLOT_1 "@LIBSPDM_TPM_HANDLE_RESPONDER_HANDLE_SLOT_1@"
#cmakedefine LIBSPDM_TPM_HANDLE_RESPONDER_CERT_SLOT_1 @LIBSPDM_TPM_HANDLE_RESPONDER_CERT_SLOT_1@
#cmakedefine LIBSPDM_TPM_HANDLE_RESPONDER_CERTCHAIN_SLOT_1 @LIBSPDM_TPM_HANDLE_RESPONDER_CERTCHAIN_SLOT_1@

/* TPM Root Certificate (shared across slots) */
#cmakedefine LIBSPDM_TPM_HANDLE_ROOT_CERT @LIBSPDM_TPM_HANDLE_ROOT_CERT@
132 changes: 94 additions & 38 deletions os_stub/spdm_device_secret_lib_tpm/read_pub_cert.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,58 +20,115 @@
#include "library/spdm_crypt_ext_lib.h"
#include "keys.h"

static bool get_certificate(uint32_t index, uint32_t base_hash_algo, uint32_t base_asym_algo, void **data,
size_t *size, void **hash, size_t *hash_size)
static bool get_root_certificate_from_chain(uint32_t chain_index, uint32_t base_hash_algo,
uint32_t base_asym_algo, void **data,
size_t *size, void **hash, size_t *hash_size)
{
bool result;
void *cert;
size_t cert_size;
spdm_cert_chain_t *cert_chain;
void *cert_chain_data;
size_t cert_chain_size;
const uint8_t *root_cert;
size_t root_cert_len;
spdm_cert_chain_t *cert_chain;
size_t output_cert_chain_size;
size_t digest_size;

if (!libspdm_tpm_device_init())
return false;

result = libspdm_tpm_read_nv(index, &cert, &cert_size);
result = libspdm_tpm_read_nv(chain_index, &cert_chain_data, &cert_chain_size);
if (!result)
return false;

/* Extract root certificate from chain */
result = libspdm_x509_get_cert_from_cert_chain(cert_chain_data, cert_chain_size, 0,
&root_cert, &root_cert_len);
if (!result) {
free(cert_chain_data);
return false;
}

digest_size = libspdm_get_hash_size(base_hash_algo);

cert_chain_size = sizeof(spdm_cert_chain_t) + digest_size + cert_size;
cert_chain = (void *)malloc(cert_chain_size);
/* Create cert chain with just root cert */
output_cert_chain_size = sizeof(spdm_cert_chain_t) + digest_size + root_cert_len;
cert_chain = (void *)malloc(output_cert_chain_size);
if (cert_chain == NULL){
result = false;
goto cleanup_cert;
free(cert_chain_data);
return false;
}
cert_chain->length = (uint32_t)cert_chain_size;
cert_chain->length = (uint32_t)output_cert_chain_size;

result = libspdm_hash_all(base_hash_algo, cert, cert_size,
result = libspdm_hash_all(base_hash_algo, root_cert, root_cert_len,
(uint8_t *)(cert_chain + 1));
if (!result){
result = false;
free(cert_chain);
goto cleanup_cert;
free(cert_chain_data);
return false;
}

libspdm_copy_mem((uint8_t *)cert_chain + sizeof(spdm_cert_chain_t) + digest_size,
cert_chain_size - (sizeof(spdm_cert_chain_t) + digest_size),
cert, cert_size);
output_cert_chain_size - (sizeof(spdm_cert_chain_t) + digest_size),
root_cert, root_cert_len);

*data = cert_chain;
*size = cert_chain_size;
*size = output_cert_chain_size;

if (hash != NULL)
*hash = (cert_chain + 1);

if (hash_size != NULL)
*hash_size = digest_size;

cleanup_cert:
free(cert);
free(cert_chain_data);
return true;
}

return result;
static bool get_leaf_certificate_from_chain(uint32_t chain_index, uint32_t base_asym_algo,
void **data, size_t *size)
{
bool result;
void *cert_chain_data;
size_t cert_chain_size;
const uint8_t *leaf_cert;
size_t leaf_cert_len;
int32_t cert_count;

if (!libspdm_tpm_device_init())
return false;

result = libspdm_tpm_read_nv(chain_index, &cert_chain_data, &cert_chain_size);
if (!result)
return false;

/* Get certificate count */
cert_count = libspdm_x509_get_cert_from_cert_chain(cert_chain_data, cert_chain_size, -1,
NULL, NULL);
if (cert_count <= 0) {
free(cert_chain_data);
return false;
}

/* Extract leaf certificate (last in chain) */
result = libspdm_x509_get_cert_from_cert_chain(cert_chain_data, cert_chain_size,
cert_count - 1, &leaf_cert, &leaf_cert_len);
if (!result) {
free(cert_chain_data);
return false;
}

/* Allocate and copy leaf cert */
*data = malloc(leaf_cert_len);
if (*data == NULL) {
free(cert_chain_data);
return false;
}

libspdm_copy_mem(*data, leaf_cert_len, leaf_cert, leaf_cert_len);
*size = leaf_cert_len;

free(cert_chain_data);
return true;
}

static bool get_certificate_chain(uint32_t index, uint32_t base_hash_algo, uint32_t base_asym_algo, void **data,
Expand Down Expand Up @@ -149,37 +206,29 @@ bool libspdm_read_requester_root_public_certificate(uint32_t base_hash_algo,
void **hash,
size_t *hash_size)
{
return get_certificate(TPM_ROOT_CERT, base_hash_algo, base_asym_algo, data, size, hash, hash_size);
return get_root_certificate_from_chain(LIBSPDM_TPM_HANDLE_REQUESTER_CERTCHAIN_SLOT_0,
base_hash_algo, base_asym_algo, data, size, hash, hash_size);
}

bool libspdm_read_requester_public_certificate_chain(
uint32_t base_hash_algo, uint16_t req_base_asym_alg, void **data,
size_t *size, void **hash, size_t *hash_size)
{
return get_certificate_chain(TPM_REQU_CERT_CHAIN, base_hash_algo, req_base_asym_alg, data, size, hash,
return get_certificate_chain(LIBSPDM_TPM_HANDLE_REQUESTER_CERTCHAIN_SLOT_0, base_hash_algo, req_base_asym_alg, data,
size, hash,
hash_size, false, true);
}

bool libspdm_read_responder_certificate(uint32_t base_asym_algo,
void **data, size_t *size)
{
bool result;
void *cert;
size_t cert_size;

if (base_asym_algo != SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P256){
LIBSPDM_DEBUG((LIBSPDM_DEBUG_ERROR, "unsupported asym algo %d\n", base_asym_algo));
return false;
}

if (!libspdm_tpm_device_init())
return false;

result = libspdm_tpm_read_nv(TPM_RESP_CERT, &cert, &cert_size);
if (!result)
return false;

return true;
return get_leaf_certificate_from_chain(LIBSPDM_TPM_HANDLE_RESPONDER_CERTCHAIN_SLOT_0,
base_asym_algo, data, size);
}

bool libspdm_read_responder_root_public_certificate(uint32_t base_hash_algo,
Expand All @@ -188,14 +237,16 @@ bool libspdm_read_responder_root_public_certificate(uint32_t base_hash_algo,
void **hash,
size_t *hash_size)
{
return get_certificate(TPM_ROOT_CERT, base_hash_algo, base_asym_algo, data, size, hash, hash_size);
return get_root_certificate_from_chain(LIBSPDM_TPM_HANDLE_RESPONDER_CERTCHAIN_SLOT_0,
base_hash_algo, base_asym_algo, data, size, hash, hash_size);
}

bool libspdm_read_responder_public_certificate_chain(
uint32_t base_hash_algo, uint32_t base_asym_algo, void **data,
size_t *size, void **hash, size_t *hash_size)
{
return get_certificate_chain(TPM_RESP_CERT_CHAIN, base_hash_algo, base_asym_algo, data, size, hash, hash_size,
return get_certificate_chain(LIBSPDM_TPM_HANDLE_RESPONDER_CERTCHAIN_SLOT_0, base_hash_algo, base_asym_algo, data,
size, hash, hash_size,
false, true);
}

Expand All @@ -206,14 +257,19 @@ bool libspdm_read_responder_root_public_certificate_slot(uint8_t slot_id,
void **hash,
size_t *hash_size)
{
return get_certificate(TPM_ROOT_CERT, base_hash_algo, base_asym_algo, data, size, hash, hash_size);
uint32_t chain_index = (slot_id == 0) ? LIBSPDM_TPM_HANDLE_RESPONDER_CERTCHAIN_SLOT_0
: LIBSPDM_TPM_HANDLE_RESPONDER_CERTCHAIN_SLOT_1;
return get_root_certificate_from_chain(chain_index, base_hash_algo, base_asym_algo,
data, size, hash, hash_size);
}

bool libspdm_read_responder_public_certificate_chain_per_slot(
uint8_t slot_id, uint32_t base_hash_algo, uint32_t base_asym_algo,
void **data, size_t *size, void **hash, size_t *hash_size)
{
return get_certificate_chain(TPM_RESP_CERT_CHAIN, base_hash_algo, base_asym_algo, data, size, hash, hash_size,
uint32_t chain_index = (slot_id == 0) ? LIBSPDM_TPM_HANDLE_RESPONDER_CERTCHAIN_SLOT_0
: LIBSPDM_TPM_HANDLE_RESPONDER_CERTCHAIN_SLOT_1;
return get_certificate_chain(chain_index, base_hash_algo, base_asym_algo, data, size, hash, hash_size,
false, true);
}

Expand Down
4 changes: 2 additions & 2 deletions os_stub/spdm_device_secret_lib_tpm/sign.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ bool libspdm_requester_data_sign(

LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "Loading TPM device"));
libspdm_tpm_device_init();
result = libspdm_tpm_get_pvt_key_handle(TPM_REQU_HANDLE, &context);
result = libspdm_tpm_get_pvt_key_handle(LIBSPDM_TPM_HANDLE_REQUESTER_HANDLE_SLOT_0, &context);
if (!result){
LIBSPDM_DEBUG((LIBSPDM_DEBUG_ERROR, "Failed to load requester handle"));
return false;
Expand Down Expand Up @@ -70,7 +70,7 @@ bool libspdm_responder_data_sign(
bool result = false;

libspdm_tpm_device_init();
result = libspdm_tpm_get_pvt_key_handle(TPM_RESP_HANDLE, &context);
result = libspdm_tpm_get_pvt_key_handle(LIBSPDM_TPM_HANDLE_RESPONDER_HANDLE_SLOT_0, &context);
if (!result){
LIBSPDM_DEBUG((LIBSPDM_DEBUG_ERROR, "Failed to load responder handle"));
return false;
Expand Down
Loading