Skip to content

Commit c817b16

Browse files
committed
[WIP]: TPM Support
Signed-off-by: Manjeet Singh <[email protected]>
1 parent dfec15d commit c817b16

File tree

60 files changed

+5574
-260
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

60 files changed

+5574
-260
lines changed
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/**
2+
* Copyright Notice:
3+
* Copyright 2021-2025 DMTF. All rights reserved.
4+
* License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/libspdm/blob/main/LICENSE.md
5+
**/
6+
7+
#ifndef __CRYPTLIB_TPM_H__
8+
#define __CRYPTLIB_TPM_H__
9+
10+
#include <stdbool.h>
11+
12+
bool libspdm_tpm_device_init();
13+
14+
bool libspdm_tpm_get_private_key(void *handle, void **context);
15+
16+
bool libspdm_tpm_get_public_key(void *handle, void **context);
17+
18+
bool libspdm_tpm_get_certificate(void *handle, void **context);
19+
20+
bool libspdm_tpm_dump_certificate(void *context, void **buffer, size_t *size);
21+
22+
#endif

os_stub/cryptlib_openssl/CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,13 @@ target_sources(cryptlib_openssl
4747
pk/x509_pqc.c
4848
rand/rand.c
4949
sys_call/crt_wrapper_host.c
50+
tpm/tpm.c
5051
)
5152

5253
target_compile_options(cryptlib_openssl PRIVATE ${OPENSSL_FLAGS})
5354

5455
target_link_libraries(cryptlib_openssl PUBLIC openssllib memlib)
56+
57+
if (${DEVICE} STREQUAL "tpm")
58+
target_link_libraries(cryptlib_openssl PUBLIC tss2-esys tss2-tctildr)
59+
endif()

os_stub/cryptlib_openssl/pk/ec.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -681,6 +681,13 @@ bool libspdm_ecdsa_sign(void *ec_context, size_t hash_nid,
681681
return false;
682682
}
683683

684+
char buffer[4096];
685+
BIO *bio = BIO_new(BIO_s_mem());
686+
EVP_PKEY_print_public(bio, evp_pkey, 4, NULL);
687+
int len = BIO_read(bio, (void*) buffer, sizeof(buffer));
688+
buffer[len] = '\0';
689+
printf("SIGN PUBLIC KEY: %s\n", buffer);
690+
684691
half_size = evp_pkey_get_half_size(evp_pkey);
685692
if (*sig_size < (size_t)(half_size * 2)) {
686693
*sig_size = half_size * 2;
@@ -828,6 +835,13 @@ bool libspdm_ecdsa_verify(void *ec_context, size_t hash_nid,
828835
return false;
829836
}
830837

838+
char buffer[4096];
839+
BIO *bio = BIO_new(BIO_s_mem());
840+
EVP_PKEY_print_public(bio, evp_pkey, 4, NULL);
841+
int len = BIO_read(bio, (void*) buffer, sizeof(buffer));
842+
buffer[len] = '\0';
843+
printf("VERIFY PUBLIC KEY: %s\n", buffer);
844+
831845
half_size = evp_pkey_get_half_size(evp_pkey);
832846
if (sig_size != (size_t)(half_size * 2)) {
833847
return false;

os_stub/cryptlib_openssl/pk/x509.c

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,26 @@
3535
static const uint8_t m_libspdm_oid_ext_key_usage[] = OID_EXT_KEY_USAGE;
3636
static const uint8_t m_libspdm_oid_basic_constraints[] = OID_BASIC_CONSTRAINTS;
3737

38+
static void dump_hex(const char* id, const unsigned char *buf, long buflen)
39+
{
40+
char buffer[4096];
41+
const unsigned char *p = buf;
42+
X509 *cert = d2i_X509(NULL, &p, buflen);
43+
if (!cert) {
44+
printf("Not an X.509 cert inside this ASN.1 object.\n");
45+
return;
46+
}
47+
48+
/* Print certificate */
49+
BIO *bio = BIO_new(BIO_s_mem());
50+
X509_print(bio, cert);
51+
int s = BIO_read(bio, (void*) buffer, sizeof(buffer));
52+
buffer[s] = '\0';
53+
printf("%s CERT: %s\n", id, buffer);
54+
X509_free(cert);
55+
}
56+
57+
//
3858
/**
3959
* Construct a X509 object from DER-encoded certificate data.
4060
*
@@ -2037,6 +2057,8 @@ bool libspdm_x509_verify_cert_chain(const uint8_t *root_cert, size_t root_cert_l
20372057

20382058
/* Verify current_cert with preceding cert;*/
20392059

2060+
dump_hex("CURRENT", current_cert, current_cert_len);
2061+
dump_hex("PRECEDING", preceding_cert, preceding_cert_len);
20402062
verify_flag =
20412063
libspdm_x509_verify_cert(current_cert, current_cert_len,
20422064
preceding_cert, preceding_cert_len);
@@ -2458,6 +2480,7 @@ bool libspdm_gen_x509_csr_with_pqc(
24582480
X509_NAME *x509_name;
24592481
EVP_PKEY *private_key;
24602482
EVP_PKEY *public_key;
2483+
bool owned_keys = false;
24612484
EVP_MD *md;
24622485
uint8_t *csr_p;
24632486
STACK_OF(X509_EXTENSION) *exts;
@@ -2536,11 +2559,13 @@ bool libspdm_gen_x509_csr_with_pqc(
25362559
EVP_PKEY_free(private_key);
25372560
EVP_PKEY_free(public_key);
25382561

2539-
private_key = EVP_PKEY_dup(ec_pkey);
2540-
public_key = EVP_PKEY_dup(ec_pkey);
2562+
// Can't DUP hardware backed keys
2563+
private_key = ec_pkey;
2564+
public_key = ec_pkey;
25412565
if (private_key == NULL || public_key == NULL) {
25422566
goto free_all;
25432567
}
2568+
owned_keys = true;
25442569
break;
25452570
}
25462571
case LIBSPDM_CRYPTO_NID_SM2_DSA_P256: {
@@ -2763,8 +2788,10 @@ bool libspdm_gen_x509_csr_with_pqc(
27632788
EVP_MD_free((EVP_MD *)md);
27642789
}
27652790
X509_REQ_free(x509_req);
2766-
EVP_PKEY_free(private_key);
2767-
EVP_PKEY_free(public_key);
2791+
if (!owned_keys) {
2792+
EVP_PKEY_free(private_key);
2793+
EVP_PKEY_free(public_key);
2794+
}
27682795

27692796
return (ret != 0);
27702797
}

os_stub/cryptlib_openssl/tpm/tpm.c

Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
/**
2+
* Copyright Notice:
3+
* Copyright 2021-2025 DMTF. All rights reserved.
4+
* License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/libspdm/blob/main/LICENSE.md
5+
**/
6+
7+
#include <complex.h>
8+
#include <openssl/err.h>
9+
#include <tss2/tss2_common.h>
10+
#include <tss2/tss2_esys.h>
11+
#include <tss2/tss2_tctildr.h>
12+
13+
#include <openssl/provider.h>
14+
#include <openssl/store.h>
15+
#include <tss2/tss2_tcti.h>
16+
#include <tss2/tss2_tpm2_types.h>
17+
#include "library/cryptlib/cryptlib_tpm.h"
18+
19+
#include "key_context.h"
20+
21+
bool g_tpm_device_initialized = false;
22+
23+
static libspdm_key_context *create_key_context(EVP_PKEY *pkey)
24+
{
25+
libspdm_key_context *context = (libspdm_key_context *)malloc(sizeof(libspdm_key_context));
26+
context->evp_pkey = pkey;
27+
return context;
28+
}
29+
30+
bool libspdm_tpm_device_init()
31+
{
32+
OSSL_PROVIDER *tpm_provider = NULL;
33+
34+
if (g_tpm_device_initialized)
35+
return true;
36+
37+
tpm_provider = OSSL_PROVIDER_load(NULL, "tpm2");
38+
if (tpm_provider == NULL)
39+
{
40+
LIBSPDM_DEBUG((LIBSPDM_DEBUG_ERROR, "failed to load tpm2\n"));
41+
return false;
42+
}
43+
44+
OSSL_PROVIDER_load(NULL, "default");
45+
OSSL_PROVIDER_load(NULL, "legacy");
46+
47+
g_tpm_device_initialized = true;
48+
return true;
49+
}
50+
51+
static bool get_keyinfo(const char *handle, void **context, int keyinfo_type)
52+
{
53+
OSSL_STORE_CTX *store_ctx = NULL;
54+
OSSL_STORE_INFO *info = NULL;
55+
56+
/* handle must look like: "tpm2tss:0x81010002" */
57+
store_ctx = OSSL_STORE_open_ex(handle, NULL, "provider=tpm2", NULL, NULL, NULL, NULL, NULL);
58+
if (!store_ctx)
59+
{
60+
return false;
61+
}
62+
63+
while ((info = OSSL_STORE_load(store_ctx)) != NULL)
64+
{
65+
if (OSSL_STORE_INFO_get_type(info) == keyinfo_type)
66+
{
67+
switch (keyinfo_type)
68+
{
69+
case OSSL_STORE_INFO_PKEY:
70+
*context = OSSL_STORE_INFO_get1_PKEY(info);
71+
break;
72+
case OSSL_STORE_INFO_PUBKEY:
73+
*context = OSSL_STORE_INFO_get1_PUBKEY(info);
74+
break;
75+
case OSSL_STORE_INFO_CERT:
76+
*context = OSSL_STORE_INFO_get1_CERT(info);
77+
break;
78+
}
79+
break;
80+
}
81+
OSSL_STORE_INFO_free(info);
82+
}
83+
84+
OSSL_STORE_close(store_ctx);
85+
86+
if (*context == NULL)
87+
{
88+
LIBSPDM_DEBUG((LIBSPDM_DEBUG_ERROR, "no keyinfo %d foun on handle %s\n", keyinfo_type, handle));
89+
return false;
90+
}
91+
92+
return true;
93+
}
94+
95+
bool libspdm_tpm_get_private_key(void *handle, void **context)
96+
{
97+
EVP_PKEY *pkey = NULL;
98+
if (!get_keyinfo((const char *)handle, (void **)&pkey, OSSL_STORE_INFO_PKEY))
99+
{
100+
return false;
101+
}
102+
*context = create_key_context(pkey);
103+
return true;
104+
}
105+
106+
bool libspdm_tpm_get_public_key(void *handle, void **context)
107+
{
108+
EVP_PKEY *pkey = NULL;
109+
if (!get_keyinfo((const char *)handle, (void **)&pkey, OSSL_STORE_INFO_PUBKEY))
110+
{
111+
return false;
112+
}
113+
*context = create_key_context(pkey);
114+
return true;
115+
}
116+
117+
bool libspdm_tpm_get_certificate(void *handle, void **context)
118+
{
119+
return get_keyinfo((const char *)handle, context, OSSL_STORE_INFO_CERT);
120+
}
121+
122+
bool libspdm_tpm_dump_certificate(void *context, void **buffer, size_t *size)
123+
{
124+
int len = 0;
125+
len = i2d_X509((X509 *)context, NULL);
126+
if (len < 0)
127+
return false;
128+
129+
void *cert = OPENSSL_malloc(len);
130+
if (cert == NULL)
131+
{
132+
return false;
133+
}
134+
*buffer = cert;
135+
len = i2d_X509((X509 *)context, (unsigned char **)&cert);
136+
if (len < 0)
137+
{
138+
free(*buffer);
139+
*buffer = NULL;
140+
return false;
141+
}
142+
*size = len;
143+
return true;
144+
}
145+
146+
bool libspdm_tpm_read_pcr(uint32_t index, void **buffer, size_t *size)
147+
{
148+
TSS2_RC result;
149+
TSS2_TCTI_CONTEXT *tcti_context = NULL;
150+
ESYS_CONTEXT *context = NULL;
151+
152+
TPML_PCR_SELECTION sel = {
153+
.count = 1,
154+
.pcrSelections = {
155+
{
156+
.hash = TPM2_ALG_SHA256,
157+
.sizeofSelect = 1,
158+
.pcrSelect = {index},
159+
},
160+
}
161+
};
162+
UINT32 uc;
163+
TPML_PCR_SELECTION *out= NULL;
164+
TPML_DIGEST *values = NULL;
165+
166+
if ((result = Tss2_TctiLdr_Initialize(NULL, &tcti_context)) != TSS2_RC_SUCCESS) {
167+
goto finish;
168+
}
169+
170+
// TODO: abi version check
171+
if ((result = Esys_Initialize(&context, tcti_context, NULL)) != TSS2_RC_SUCCESS) {
172+
goto cleanup_tcti;
173+
}
174+
175+
if ((result = Esys_PCR_Read(context, ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE, &sel, &uc, &out, &values)) != TSS2_RC_SUCCESS) {
176+
goto cleanup_esys;
177+
}
178+
179+
cleanup_esys:
180+
Esys_Finalize(&context);
181+
182+
cleanup_tcti:
183+
Tss2_TctiLdr_Finalize(&tcti_context);
184+
185+
finish:
186+
return result == TSS2_RC_SUCCESS;
187+
}

0 commit comments

Comments
 (0)