Skip to content

Commit 89ce60a

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 89ce60a

File tree

6 files changed

+483
-0
lines changed

6 files changed

+483
-0
lines changed

CMakeLists.txt

Lines changed: 10 additions & 0 deletions
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"))

os_stub/cryptlib_openssl/pk/x509.c

Lines changed: 5 additions & 0 deletions
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

unit_test/spdm_unit_test_common/spdm_unit_test.h

Lines changed: 6 additions & 0 deletions
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, size_t *spdm_get_dice_tcb_info_size);
164170
#endif
Lines changed: 59 additions & 0 deletions
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()
Lines changed: 264 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,264 @@
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+
/*the cert chain must have a or more cert with DiceTcbInfo extension*/
18+
bool m_libspdm_must_have_dice_tcb_info = true;
19+
20+
/*reference DiceTcbinfo*/
21+
22+
/*vendor: INTC*/
23+
uint8_t m_libspdm_dice_tcbinfo_vendor[] = {0x49, 0x4E, 0x54, 0x43};
24+
/*model: S3M GNR*/
25+
uint8_t m_libspdm_dice_tcbinfo_model[] = {0x53, 0x33, 0x4D, 0x20, 0x47, 0x4E, 0x52};
26+
/*version: 000200000000008B*/
27+
uint8_t m_libspdm_dice_tcbinfo_version[] = {0x30, 0x30, 0x30, 0x32, 0x30, 0x30, 0x30, 0x30, 0x30,
28+
0x30, 0x30, 0x30, 0x30, 0x30, 0x38, 0x42};
29+
/*svn*/
30+
uint8_t m_libspdm_dice_tcbinfo_svn[] = {0x01};
31+
/*layer*/
32+
uint8_t m_libspdm_dice_tcbinfo_layer[] = {0x01};
33+
/*fwids*/
34+
uint8_t m_libspdm_dice_tcbinfo_fwids[] = {0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04,
35+
0x02, 0x02, 0x04, 0x30, 0x6B, 0x44, 0x7B, 0x5E, 0x99,
36+
0x21, 0x0A, 0x58, 0x8A, 0x7B, 0x31, 0x7D, 0xBA, 0x2D,
37+
0x4A, 0x7F, 0x75, 0xE6, 0x97, 0xF2, 0x07, 0xE0, 0xC2,
38+
0x99, 0x78, 0xF3, 0xF6, 0x2B, 0x53, 0xF5, 0xBE, 0xEB,
39+
0x73, 0xF0, 0x37, 0xB8, 0x79, 0xC1, 0xFF, 0x76, 0x2A,
40+
0x3A, 0x39, 0xCA, 0xE2, 0x8C, 0xF0, 0x56};
41+
/*type*/
42+
uint8_t m_libspdm_dice_tcbinfo_type[] = {0x46, 0x69, 0x72, 0x6D, 0x77, 0x61, 0x72, 0x65, 0x20,
43+
0x44, 0x69, 0x67, 0x65, 0x73, 0x74};
44+
45+
/*verify cert DiceTcbInfo extension*/
46+
bool libspdm_verify_cert_dicetcbinfo(const void *cert, size_t cert_size, size_t *spdm_get_dice_tcb_info_size) {
47+
bool result;
48+
uint8_t spdm_dice_tcb_info[256];
49+
size_t spdm_dice_tcb_info_size;
50+
uint8_t *ptr;
51+
int32_t length;
52+
size_t obj_len;
53+
uint8_t *end;
54+
55+
spdm_dice_tcb_info_size = 256;
56+
*spdm_get_dice_tcb_info_size = 0;
57+
result = libspdm_x509_get_extension_data(cert, cert_size,
58+
m_libspdm_tcg_dice_tcbinfo_oid,
59+
sizeof(m_libspdm_tcg_dice_tcbinfo_oid),
60+
spdm_dice_tcb_info, &spdm_dice_tcb_info_size);
61+
if (!result) {
62+
return false;
63+
} else if (spdm_dice_tcb_info_size == 0) {
64+
return true;
65+
}
66+
67+
*spdm_get_dice_tcb_info_size = spdm_dice_tcb_info_size;
68+
length = (int32_t)spdm_dice_tcb_info_size;
69+
ptr = (uint8_t*)(size_t)spdm_dice_tcb_info;
70+
obj_len = 0;
71+
end = ptr + length;
72+
73+
/*get DiceTcbInfo*/
74+
result = libspdm_asn1_get_tag(&ptr, end, &obj_len,
75+
LIBSPDM_CRYPTO_ASN1_SEQUENCE | LIBSPDM_CRYPTO_ASN1_CONSTRUCTED);
76+
if (!result) {
77+
return false;
78+
}
79+
result = libspdm_asn1_get_tag(&ptr, end, &obj_len,
80+
LIBSPDM_CRYPTO_ASN1_SEQUENCE | LIBSPDM_CRYPTO_ASN1_CONSTRUCTED);
81+
if (!result) {
82+
return false;
83+
}
84+
85+
/*vendor*/
86+
result = libspdm_asn1_get_tag(&ptr, end, &obj_len,
87+
LIBSPDM_CRYPTO_ASN1_CONTEXT_SPECIFIC);
88+
if (result) {
89+
if ((obj_len != sizeof(m_libspdm_dice_tcbinfo_vendor)) ||
90+
(!libspdm_consttime_is_mem_equal(ptr, m_libspdm_dice_tcbinfo_vendor, obj_len))) {
91+
return false;
92+
}
93+
ptr += obj_len;
94+
}
95+
/*model*/
96+
result = libspdm_asn1_get_tag(&ptr, end, &obj_len,
97+
LIBSPDM_CRYPTO_ASN1_CONTEXT_SPECIFIC + 1);
98+
if (result) {
99+
if ((obj_len != sizeof(m_libspdm_dice_tcbinfo_model)) ||
100+
(!libspdm_consttime_is_mem_equal(ptr, m_libspdm_dice_tcbinfo_model, obj_len))) {
101+
return false;
102+
}
103+
ptr += obj_len;
104+
}
105+
/*version*/
106+
result = libspdm_asn1_get_tag(&ptr, end, &obj_len,
107+
LIBSPDM_CRYPTO_ASN1_CONTEXT_SPECIFIC + 2);
108+
if (result) {
109+
if ((obj_len != sizeof(m_libspdm_dice_tcbinfo_version)) ||
110+
(!libspdm_consttime_is_mem_equal(ptr, m_libspdm_dice_tcbinfo_version, obj_len))) {
111+
return false;
112+
}
113+
ptr += obj_len;
114+
}
115+
/*svn*/
116+
result = libspdm_asn1_get_tag(&ptr, end, &obj_len,
117+
LIBSPDM_CRYPTO_ASN1_CONTEXT_SPECIFIC + 3);
118+
if (result) {
119+
if ((obj_len != sizeof(m_libspdm_dice_tcbinfo_svn)) ||
120+
(!libspdm_consttime_is_mem_equal(ptr, m_libspdm_dice_tcbinfo_svn, obj_len))) {
121+
return false;
122+
}
123+
ptr += obj_len;
124+
}
125+
/*layer*/
126+
result = libspdm_asn1_get_tag(&ptr, end, &obj_len,
127+
LIBSPDM_CRYPTO_ASN1_CONTEXT_SPECIFIC + 4);
128+
if (result) {
129+
if ((obj_len != sizeof(m_libspdm_dice_tcbinfo_layer)) ||
130+
(!libspdm_consttime_is_mem_equal(ptr, m_libspdm_dice_tcbinfo_layer, obj_len))) {
131+
return false;
132+
}
133+
ptr += obj_len;
134+
}
135+
/*index*/
136+
result = libspdm_asn1_get_tag(&ptr, end, &obj_len,
137+
LIBSPDM_CRYPTO_ASN1_CONTEXT_SPECIFIC + 5);
138+
if (result) {
139+
ptr += obj_len;
140+
}
141+
/*fwids*/
142+
result = libspdm_asn1_get_tag(&ptr, end, &obj_len,
143+
(LIBSPDM_CRYPTO_ASN1_CONTEXT_SPECIFIC |
144+
LIBSPDM_CRYPTO_ASN1_CONSTRUCTED) + 6);
145+
if (result) {
146+
if ((obj_len != sizeof(m_libspdm_dice_tcbinfo_fwids)) ||
147+
(!libspdm_consttime_is_mem_equal(ptr, m_libspdm_dice_tcbinfo_fwids, obj_len))) {
148+
return false;
149+
}
150+
ptr += obj_len;
151+
}
152+
/*flags*/
153+
result = libspdm_asn1_get_tag(&ptr, end, &obj_len,
154+
LIBSPDM_CRYPTO_ASN1_CONTEXT_SPECIFIC + 7);
155+
if (result) {
156+
ptr += obj_len;
157+
}
158+
/*vendorInfo*/
159+
result = libspdm_asn1_get_tag(&ptr, end, &obj_len,
160+
LIBSPDM_CRYPTO_ASN1_CONTEXT_SPECIFIC + 8);
161+
if (result) {
162+
ptr += obj_len;
163+
}
164+
/*type*/
165+
result = libspdm_asn1_get_tag(&ptr, end, &obj_len,
166+
LIBSPDM_CRYPTO_ASN1_CONTEXT_SPECIFIC + 9);
167+
if (result) {
168+
if ((obj_len != sizeof(m_libspdm_dice_tcbinfo_type)) ||
169+
(!libspdm_consttime_is_mem_equal(ptr, m_libspdm_dice_tcbinfo_type, obj_len))) {
170+
return false;
171+
}
172+
ptr += obj_len;
173+
}
174+
/*flagMask*/
175+
result = libspdm_asn1_get_tag(&ptr, end, &obj_len,
176+
LIBSPDM_CRYPTO_ASN1_CONTEXT_SPECIFIC + 10);
177+
if (result) {
178+
ptr += obj_len;
179+
}
180+
181+
if (ptr == end) {
182+
return true;
183+
} else {
184+
return false;
185+
}
186+
}
187+
188+
/*callback function for verifying cert_chain DiceTcbInfo extension*/
189+
bool libspdm_verify_spdm_cert_chain_with_dice(void *spdm_context, uint8_t slot_id,
190+
size_t cert_chain_size, const void *cert_chain,
191+
const void **trust_anchor,
192+
size_t *trust_anchor_size)
193+
{
194+
bool result;
195+
libspdm_context_t *context;
196+
const uint8_t *cert_chain_data;
197+
size_t cert_chain_data_size;
198+
size_t hash_size;
199+
uint8_t *ptr;
200+
uint8_t *tem_ptr;
201+
int32_t length;
202+
size_t obj_len;
203+
uint8_t *end;
204+
size_t cert_dice_tcb_info_size;
205+
bool cert_chain_have_dice;
206+
207+
/*verify peer cert chain integrity*/
208+
result = libspdm_verify_peer_cert_chain_buffer_integrity(spdm_context, cert_chain,
209+
cert_chain_size);
210+
if (!result) {
211+
return false;
212+
}
213+
214+
/*verify peer cert chain authority*/
215+
result = libspdm_verify_peer_cert_chain_buffer_authority(spdm_context, cert_chain,
216+
cert_chain_size, trust_anchor,
217+
trust_anchor_size);
218+
if (!result) {
219+
return false;
220+
}
221+
222+
context = spdm_context;
223+
hash_size = libspdm_get_hash_size(context->connection_info.algorithm.base_hash_algo);
224+
225+
cert_chain_data = (const uint8_t *)cert_chain + sizeof(spdm_cert_chain_t) + hash_size;
226+
cert_chain_data_size = cert_chain_size - sizeof(spdm_cert_chain_t) - hash_size;
227+
228+
length = (int32_t)cert_chain_data_size;
229+
ptr = (uint8_t*)(size_t)cert_chain_data;
230+
obj_len = 0;
231+
end = ptr + length;
232+
cert_dice_tcb_info_size = 0;
233+
cert_chain_have_dice = false;
234+
235+
while (ptr < end) {
236+
tem_ptr = ptr;
237+
result = libspdm_asn1_get_tag(&ptr, end, &obj_len,
238+
LIBSPDM_CRYPTO_ASN1_SEQUENCE |
239+
LIBSPDM_CRYPTO_ASN1_CONSTRUCTED);
240+
if (result) {
241+
/*verify Dice TCB info*/
242+
result = libspdm_verify_cert_dicetcbinfo(tem_ptr, obj_len + (ptr - tem_ptr), &cert_dice_tcb_info_size);
243+
if (!result) {
244+
return false;
245+
} else {
246+
if (cert_dice_tcb_info_size != 0) {
247+
cert_chain_have_dice = true;
248+
}
249+
}
250+
/* Move to next cert*/
251+
ptr += obj_len;
252+
}
253+
}
254+
255+
if (m_libspdm_must_have_dice_tcb_info && !cert_chain_have_dice) {
256+
return false;
257+
}
258+
259+
if (ptr == end) {
260+
return true;
261+
} else {
262+
return false;
263+
}
264+
}

0 commit comments

Comments
 (0)