Skip to content

Commit 3cef1fd

Browse files
committed
Add verify cert callback function for DiceTcbInfo.
Refer the spec https://trustedcomputinggroup.org/resource/dice-attestation-architecture/ add verify cert callback function for Cert extentison DiceTcbInfo check. Signed-off-by: Wenxing Hou <[email protected]>
1 parent 828ef62 commit 3cef1fd

File tree

6 files changed

+463
-0
lines changed

6 files changed

+463
-0
lines changed

Diff for: CMakeLists.txt

+10
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ SET(CRYPTO ${CRYPTO} CACHE STRING "Choose the crypto of build: mbedtls openssl"
1919
SET(GCOV ${GCOV} CACHE STRING "Choose the target of Gcov: ON OFF, and default is OFF" FORCE)
2020
SET(STACK_USAGE ${STACK_USAGE} CACHE STRING "Choose the target of STACK_USAGE: ON OFF, and default is OFF" FORCE)
2121
SET(BUILD_LINUX_SHARED_LIB ${BUILD_LINUX_SHARED_LIB} CACHE STRING "Choose if libspdm shared library should be built for linux: ON OFF, and default is OFF" FORCE)
22+
SET(X509_IGNORE_CRITICAL ${X509_IGNORE_CRITICAL} CACHE STRING "Choose if libspdm ignore unhandled critical cert extensions : ON OFF, and default is OFF" FORCE)
2223

2324
if(NOT GCOV)
2425
SET(GCOV "OFF")
@@ -32,6 +33,10 @@ if(NOT BUILD_LINUX_SHARED_LIB)
3233
SET(BUILD_LINUX_SHARED_LIB "OFF")
3334
endif()
3435

36+
if(NOT X509_IGNORE_CRITICAL)
37+
SET(X509_IGNORE_CRITICAL "OFF")
38+
endif()
39+
3540
SET(LIBSPDM_DIR ${PROJECT_SOURCE_DIR})
3641

3742
#
@@ -164,6 +169,10 @@ else()
164169
MESSAGE(FATAL_ERROR "Unknown CRYPTO")
165170
endif()
166171

172+
if ((X509_IGNORE_CRITICAL STREQUAL "ON") AND (CRYPTO STREQUAL "openssl"))
173+
add_definitions(-DOPENSSL_IGNORE_CRITICAL=1)
174+
endif()
175+
167176
if(ENABLE_BINARY_BUILD STREQUAL "1")
168177
if(NOT CRYPTO STREQUAL "openssl")
169178
MESSAGE(FATAL_ERROR "enabling binary build not supported for non-openssl")
@@ -940,6 +949,7 @@ else()
940949
ADD_SUBDIRECTORY(unit_test/test_spdm_fips)
941950
ADD_SUBDIRECTORY(unit_test/test_spdm_secured_message)
942951
ADD_SUBDIRECTORY(unit_test/test_spdm_vendor_cmds)
952+
ADD_SUBDIRECTORY(unit_test/test_spdm_callback)
943953
endif()
944954

945955
if((NOT TOOLCHAIN STREQUAL "ARM_DS2022") AND (NOT TOOLCHAIN STREQUAL "RISCV_XPACK"))

Diff for: os_stub/cryptlib_openssl/pk/x509.c

+5
Original file line numberDiff line numberDiff line change
@@ -1879,6 +1879,11 @@ bool libspdm_x509_verify_cert(const uint8_t *cert, size_t cert_size,
18791879
*/
18801880

18811881
X509_STORE_set_flags(cert_store, X509_V_FLAG_PARTIAL_CHAIN);
1882+
1883+
#if OPENSSL_IGNORE_CRITICAL
1884+
X509_STORE_set_flags(cert_store, X509_V_FLAG_IGNORE_CRITICAL);
1885+
#endif
1886+
18821887
#ifndef OPENSSL_CHECK_TIME
18831888
X509_STORE_set_flags(cert_store, X509_V_FLAG_NO_CHECK_TIME);
18841889
#endif

Diff for: unit_test/spdm_unit_test_common/spdm_unit_test.h

+6
Original file line numberDiff line numberDiff line change
@@ -161,4 +161,10 @@ typedef enum
161161
void libspdm_force_error (libspdm_error_target_t target);
162162
void libspdm_release_error (libspdm_error_target_t target);
163163

164+
bool libspdm_verify_spdm_cert_chain_with_dice(void *spdm_context, uint8_t slot_id,
165+
size_t cert_chain_size, const void *cert_chain,
166+
const void **trust_anchor,
167+
size_t *trust_anchor_size);
168+
169+
bool libspdm_verify_cert_dicetcbinfo(const void *cert, size_t cert_size);
164170
#endif

Diff for: unit_test/test_spdm_callback/CMakeLists.txt

+59
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
cmake_minimum_required(VERSION 2.8.12)
2+
3+
INCLUDE_DIRECTORIES(${LIBSPDM_DIR}/include
4+
${LIBSPDM_DIR}/unit_test/include
5+
${LIBSPDM_DIR}/os_stub/spdm_device_secret_lib_sample
6+
${LIBSPDM_DIR}/unit_test/cmockalib/cmocka/include
7+
${LIBSPDM_DIR}/unit_test/cmockalib/cmocka/include/cmockery
8+
${LIBSPDM_DIR}/unit_test/spdm_unit_test_common
9+
${LIBSPDM_DIR}/os_stub/include
10+
${LIBSPDM_DIR}/os_stub
11+
)
12+
13+
if(CMAKE_SYSTEM_NAME MATCHES "Windows")
14+
if((TOOLCHAIN STREQUAL "VS2015") OR (TOOLCHAIN STREQUAL "VS2019") OR (TOOLCHAIN STREQUAL "VS2022"))
15+
ADD_COMPILE_OPTIONS(/wd4819)
16+
endif()
17+
endif()
18+
19+
SET(src_test_spdm_callback
20+
test_spdm_callback.c
21+
spdm_cert_verify_callback.c
22+
${LIBSPDM_DIR}/unit_test/spdm_unit_test_common/support.c
23+
${LIBSPDM_DIR}/unit_test/spdm_unit_test_common/algo.c
24+
)
25+
26+
SET(test_spdm_callback_LIBRARY
27+
memlib
28+
debuglib
29+
spdm_crypt_lib
30+
${CRYPTO_LIB_PATHS}
31+
cryptlib_${CRYPTO}
32+
rnglib
33+
malloclib
34+
cmockalib
35+
spdm_device_secret_lib_sample
36+
spdm_crypt_ext_lib
37+
spdm_common_lib
38+
spdm_secured_message_lib
39+
)
40+
41+
if(TOOLCHAIN STREQUAL "ARM_DS2022")
42+
SET(test_spdm_callback_LIBRARY ${test_spdm_callback_LIBRARY} armbuild_lib)
43+
endif()
44+
45+
if((TOOLCHAIN STREQUAL "KLEE") OR (TOOLCHAIN STREQUAL "CBMC"))
46+
ADD_EXECUTABLE(test_spdm_callback
47+
${src_test_spdm_callback}
48+
$<TARGET_OBJECTS:memlib>
49+
$<TARGET_OBJECTS:debuglib>
50+
$<TARGET_OBJECTS:spdm_crypt_lib>
51+
$<TARGET_OBJECTS:${CRYPTO_LIB_PATHS}>
52+
$<TARGET_OBJECTS:rnglib>
53+
$<TARGET_OBJECTS:cryptlib_${CRYPTO}>
54+
$<TARGET_OBJECTS:malloclib>
55+
)
56+
else()
57+
ADD_EXECUTABLE(test_spdm_callback ${src_test_spdm_callback})
58+
TARGET_LINK_LIBRARIES(test_spdm_callback ${test_spdm_callback_LIBRARY})
59+
endif()
+250
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,250 @@
1+
/**
2+
* Copyright Notice:
3+
* Copyright 2024 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 "spdm_unit_test.h"
8+
#include "library/spdm_common_lib.h"
9+
#include "spdm_crypt_ext_lib/spdm_crypt_ext_lib.h"
10+
11+
/**
12+
* tcg-dice-TcbInfo OID: 2.23.133.5.4.1
13+
* https://trustedcomputinggroup.org/wp-content/uploads/DICE-Attestation-Architecture-Version-1.1-Revision-18_pub.pdf
14+
**/
15+
uint8_t m_libspdm_tcg_dice_tcbinfo_oid[] = {0x67, 0x81, 0x05, 0x05, 0x04, 0x01};
16+
17+
bool m_libspdm_must_have_dice_tcb_info = false;
18+
19+
/*reference DiceTcbinfo*/
20+
21+
/*vendor: INTC*/
22+
uint8_t m_libspdm_dice_tcbinfo_vendor[] = {0x49, 0x4E, 0x54, 0x43};
23+
/*model: S3M GNR*/
24+
uint8_t m_libspdm_dice_tcbinfo_model[] = {0x53, 0x33, 0x4D, 0x20, 0x47, 0x4E, 0x52};
25+
/*version: 000200000000008B*/
26+
uint8_t m_libspdm_dice_tcbinfo_version[] = {0x30, 0x30, 0x30, 0x32, 0x30, 0x30, 0x30, 0x30, 0x30,
27+
0x30, 0x30, 0x30, 0x30, 0x30, 0x38, 0x42};
28+
/*svn*/
29+
uint8_t m_libspdm_dice_tcbinfo_svn[] = {0x01};
30+
/*layer*/
31+
uint8_t m_libspdm_dice_tcbinfo_layer[] = {0x01};
32+
/*fwids*/
33+
uint8_t m_libspdm_dice_tcbinfo_fwids[] = {0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04,
34+
0x02, 0x02, 0x04, 0x30, 0x6B, 0x44, 0x7B, 0x5E, 0x99, 0x21, 0x0A, 0x58, 0x8A, 0x7B, 0x31,
35+
0x7D, 0xBA, 0x2D, 0x4A, 0x7F, 0x75, 0xE6, 0x97, 0xF2, 0x07, 0xE0, 0xC2, 0x99, 0x78, 0xF3,
36+
0xF6, 0x2B, 0x53, 0xF5, 0xBE, 0xEB, 0x73, 0xF0, 0x37, 0xB8, 0x79, 0xC1, 0xFF, 0x76, 0x2A,
37+
0x3A, 0x39, 0xCA, 0xE2, 0x8C, 0xF0, 0x56};
38+
/*type*/
39+
uint8_t m_libspdm_dice_tcbinfo_type[] = {0x46, 0x69, 0x72, 0x6D, 0x77, 0x61, 0x72, 0x65, 0x20,
40+
0x44, 0x69, 0x67, 0x65, 0x73, 0x74};
41+
42+
/*verify cert DiceTcbInfo extension*/
43+
bool libspdm_verify_cert_dicetcbinfo(const void *cert, size_t cert_size) {
44+
bool result;
45+
uint8_t spdm_dice_tcb_info[256];
46+
size_t spdm_dice_tcb_info_size;
47+
uint8_t *ptr;
48+
int32_t length;
49+
size_t obj_len;
50+
uint8_t *end;
51+
52+
spdm_dice_tcb_info_size = 256;
53+
result = libspdm_x509_get_extension_data(cert, cert_size,
54+
m_libspdm_tcg_dice_tcbinfo_oid,
55+
sizeof(m_libspdm_tcg_dice_tcbinfo_oid),
56+
spdm_dice_tcb_info, &spdm_dice_tcb_info_size);
57+
if (!result) {
58+
return false;
59+
} else if (spdm_dice_tcb_info_size == 0) {
60+
if (m_libspdm_must_have_dice_tcb_info) {
61+
return false;
62+
} else {
63+
return true;
64+
}
65+
}
66+
67+
length = (int32_t)spdm_dice_tcb_info_size;
68+
ptr = (uint8_t*)(size_t)spdm_dice_tcb_info;
69+
obj_len = 0;
70+
end = ptr + length;
71+
72+
/*get DiceTcbInfo*/
73+
result = libspdm_asn1_get_tag(&ptr, end, &obj_len,
74+
LIBSPDM_CRYPTO_ASN1_SEQUENCE | LIBSPDM_CRYPTO_ASN1_CONSTRUCTED);
75+
if (!result) {
76+
return false;
77+
}
78+
result = libspdm_asn1_get_tag(&ptr, end, &obj_len,
79+
LIBSPDM_CRYPTO_ASN1_SEQUENCE | LIBSPDM_CRYPTO_ASN1_CONSTRUCTED);
80+
if (!result) {
81+
return false;
82+
}
83+
84+
/*vendor*/
85+
result = libspdm_asn1_get_tag(&ptr, end, &obj_len,
86+
LIBSPDM_CRYPTO_ASN1_CONTEXT_SPECIFIC);
87+
if (result) {
88+
if ((obj_len != sizeof(m_libspdm_dice_tcbinfo_vendor)) ||
89+
(!libspdm_consttime_is_mem_equal(ptr, m_libspdm_dice_tcbinfo_vendor, obj_len))) {
90+
return false;
91+
}
92+
ptr += obj_len;
93+
}
94+
/*model*/
95+
result = libspdm_asn1_get_tag(&ptr, end, &obj_len,
96+
LIBSPDM_CRYPTO_ASN1_CONTEXT_SPECIFIC + 1);
97+
if (result) {
98+
if ((obj_len != sizeof(m_libspdm_dice_tcbinfo_model)) ||
99+
(!libspdm_consttime_is_mem_equal(ptr, m_libspdm_dice_tcbinfo_model, obj_len))) {
100+
return false;
101+
}
102+
ptr += obj_len;
103+
}
104+
/*version*/
105+
result = libspdm_asn1_get_tag(&ptr, end, &obj_len,
106+
LIBSPDM_CRYPTO_ASN1_CONTEXT_SPECIFIC + 2);
107+
if (result) {
108+
if ((obj_len != sizeof(m_libspdm_dice_tcbinfo_version)) ||
109+
(!libspdm_consttime_is_mem_equal(ptr, m_libspdm_dice_tcbinfo_version, obj_len))) {
110+
return false;
111+
}
112+
ptr += obj_len;
113+
}
114+
/*svn*/
115+
result = libspdm_asn1_get_tag(&ptr, end, &obj_len,
116+
LIBSPDM_CRYPTO_ASN1_CONTEXT_SPECIFIC + 3);
117+
if (result) {
118+
if ((obj_len != sizeof(m_libspdm_dice_tcbinfo_svn)) ||
119+
(!libspdm_consttime_is_mem_equal(ptr, m_libspdm_dice_tcbinfo_svn, obj_len))) {
120+
return false;
121+
}
122+
ptr += obj_len;
123+
}
124+
/*layer*/
125+
result = libspdm_asn1_get_tag(&ptr, end, &obj_len,
126+
LIBSPDM_CRYPTO_ASN1_CONTEXT_SPECIFIC + 4);
127+
if (result) {
128+
if ((obj_len != sizeof(m_libspdm_dice_tcbinfo_layer)) ||
129+
(!libspdm_consttime_is_mem_equal(ptr, m_libspdm_dice_tcbinfo_layer, obj_len))) {
130+
return false;
131+
}
132+
ptr += obj_len;
133+
}
134+
/*index*/
135+
result = libspdm_asn1_get_tag(&ptr, end, &obj_len,
136+
LIBSPDM_CRYPTO_ASN1_CONTEXT_SPECIFIC + 5);
137+
if (result) {
138+
ptr += obj_len;
139+
}
140+
/*fwids*/
141+
result = libspdm_asn1_get_tag(&ptr, end, &obj_len,
142+
LIBSPDM_CRYPTO_ASN1_CONTEXT_SPECIFIC |
143+
LIBSPDM_CRYPTO_ASN1_CONSTRUCTED + 6);
144+
if (result) {
145+
if ((obj_len != sizeof(m_libspdm_dice_tcbinfo_fwids)) ||
146+
(!libspdm_consttime_is_mem_equal(ptr, m_libspdm_dice_tcbinfo_fwids, obj_len))) {
147+
return false;
148+
}
149+
ptr += obj_len;
150+
}
151+
/*flags*/
152+
result = libspdm_asn1_get_tag(&ptr, end, &obj_len,
153+
LIBSPDM_CRYPTO_ASN1_CONTEXT_SPECIFIC + 7);
154+
if (result) {
155+
ptr += obj_len;
156+
}
157+
/*vendorInfo*/
158+
result = libspdm_asn1_get_tag(&ptr, end, &obj_len,
159+
LIBSPDM_CRYPTO_ASN1_CONTEXT_SPECIFIC + 8);
160+
if (result) {
161+
ptr += obj_len;
162+
}
163+
/*type*/
164+
result = libspdm_asn1_get_tag(&ptr, end, &obj_len,
165+
LIBSPDM_CRYPTO_ASN1_CONTEXT_SPECIFIC + 9);
166+
if (result) {
167+
if ((obj_len != sizeof(m_libspdm_dice_tcbinfo_type)) ||
168+
(!libspdm_consttime_is_mem_equal(ptr, m_libspdm_dice_tcbinfo_type, obj_len))) {
169+
return false;
170+
}
171+
ptr += obj_len;
172+
}
173+
/*flagMask*/
174+
result = libspdm_asn1_get_tag(&ptr, end, &obj_len,
175+
LIBSPDM_CRYPTO_ASN1_CONTEXT_SPECIFIC + 10);
176+
if (result) {
177+
ptr += obj_len;
178+
}
179+
180+
if (ptr == end) {
181+
return true;
182+
} else {
183+
return false;
184+
}
185+
}
186+
187+
/*callback function for verifying cert_chain DiceTcbInfo extension*/
188+
bool libspdm_verify_spdm_cert_chain_with_dice(void *spdm_context, uint8_t slot_id,
189+
size_t cert_chain_size, const void *cert_chain,
190+
const void **trust_anchor,
191+
size_t *trust_anchor_size)
192+
{
193+
bool result;
194+
libspdm_context_t *context;
195+
const uint8_t *cert_chain_data;
196+
size_t cert_chain_data_size;
197+
size_t hash_size;
198+
uint8_t *ptr;
199+
uint8_t *tem_ptr;
200+
int32_t length;
201+
size_t obj_len;
202+
uint8_t *end;
203+
204+
/*verify peer cert chain integrity*/
205+
result = libspdm_verify_peer_cert_chain_buffer_integrity(spdm_context, cert_chain,
206+
cert_chain_size);
207+
if (!result) {
208+
return false;
209+
}
210+
211+
/*verify peer cert chain authority*/
212+
result = libspdm_verify_peer_cert_chain_buffer_authority(spdm_context, cert_chain,
213+
cert_chain_size, trust_anchor,
214+
trust_anchor_size);
215+
if (!result) {
216+
return false;
217+
}
218+
219+
context = spdm_context;
220+
hash_size = libspdm_get_hash_size(context->connection_info.algorithm.base_hash_algo);
221+
222+
cert_chain_data = (const uint8_t *)cert_chain + sizeof(spdm_cert_chain_t) + hash_size;
223+
cert_chain_data_size = cert_chain_size - sizeof(spdm_cert_chain_t) - hash_size;
224+
225+
length = (int32_t)cert_chain_data_size;
226+
ptr = (uint8_t*)(size_t)cert_chain_data;
227+
obj_len = 0;
228+
end = ptr + length;
229+
230+
while (ptr < end) {
231+
tem_ptr = ptr;
232+
result = libspdm_asn1_get_tag(&ptr, end, &obj_len,
233+
LIBSPDM_CRYPTO_ASN1_SEQUENCE | LIBSPDM_CRYPTO_ASN1_CONSTRUCTED);
234+
if (result) {
235+
/*verify Dice TCB info*/
236+
result = libspdm_verify_cert_dicetcbinfo(tem_ptr, obj_len + (ptr - tem_ptr));
237+
if (!result) {
238+
return false;
239+
}
240+
/* Move to next cert*/
241+
ptr += obj_len;
242+
}
243+
}
244+
245+
if (ptr == end) {
246+
return true;
247+
} else {
248+
return false;
249+
}
250+
}

0 commit comments

Comments
 (0)