Skip to content

Commit 5fb242b

Browse files
Wenxing-houjyao1
authored andcommitted
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 ddfd7a1 commit 5fb242b

File tree

7 files changed

+600
-0
lines changed

7 files changed

+600
-0
lines changed

CMakeLists.txt

+3
Original file line numberDiff line numberDiff line change
@@ -900,6 +900,7 @@ if(ENABLE_CODEQL STREQUAL "ON")
900900
ADD_SUBDIRECTORY(os_stub/malloclib)
901901
ADD_SUBDIRECTORY(os_stub/spdm_device_secret_lib_sample)
902902
ADD_SUBDIRECTORY(os_stub/spdm_device_secret_lib_null)
903+
ADD_SUBDIRECTORY(os_stub/spdm_cert_verify_callback_sample)
903904
ADD_SUBDIRECTORY(os_stub/cryptlib_null)
904905
ADD_SUBDIRECTORY(os_stub/cryptlib_mbedtls)
905906
ADD_SUBDIRECTORY(os_stub/cryptlib_openssl)
@@ -936,6 +937,7 @@ else()
936937
ADD_SUBDIRECTORY(os_stub/malloclib)
937938
ADD_SUBDIRECTORY(os_stub/spdm_device_secret_lib_sample)
938939
ADD_SUBDIRECTORY(os_stub/spdm_device_secret_lib_null)
940+
ADD_SUBDIRECTORY(os_stub/spdm_cert_verify_callback_sample)
939941

940942
if(NOT DISABLE_TESTS STREQUAL "1")
941943
ADD_SUBDIRECTORY(unit_test/spdm_transport_test_lib)
@@ -952,6 +954,7 @@ else()
952954
ADD_SUBDIRECTORY(unit_test/test_spdm_crypt)
953955
ADD_SUBDIRECTORY(unit_test/test_spdm_fips)
954956
ADD_SUBDIRECTORY(unit_test/test_spdm_secured_message)
957+
ADD_SUBDIRECTORY(unit_test/test_spdm_sample)
955958
endif()
956959

957960
if((NOT TOOLCHAIN STREQUAL "ARM_DS2022") AND (NOT TOOLCHAIN STREQUAL "RISCV_XPACK"))
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
cmake_minimum_required(VERSION 2.8.12)
2+
3+
INCLUDE_DIRECTORIES(${LIBSPDM_DIR}/os_stub/spdm_cert_verify_callback_sample
4+
${LIBSPDM_DIR}/include
5+
${LIBSPDM_DIR}/include/hal
6+
${LIBSPDM_DIR}/os_stub
7+
)
8+
9+
SET(src_spdm_cert_verify_callback_sample
10+
spdm_cert_verify_callback.c
11+
)
12+
13+
if ((ARCH STREQUAL "arm") OR (ARCH STREQUAL "aarch64"))
14+
ADD_COMPILE_OPTIONS(-DLIBSPDM_CPU_ARM)
15+
endif()
16+
17+
ADD_LIBRARY(spdm_cert_verify_callback_sample STATIC ${src_spdm_cert_verify_callback_sample})
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
## This is reference implementation to verify CertChain DiceTcbInfo extension.
2+
3+
### DiceTcbInfo extension Spec
4+
[DICE Attestation Architecture](https://trustedcomputinggroup.org/wp-content/uploads/DICE-Attestation-Architecture-Version-1.1-Revision-18_pub.pdf)
5+
6+
### Implementation Assumption
7+
1) **Reference TcbInfo.**
8+
9+
- Only one reference TcbInfo entry is provided by the integrator. (Multiple reference TcbInfo is NOT supported in this Implementation.)
10+
2) **Reported TcbInfo**
11+
12+
- The number of reported TcbInfo must match the number of reference TcbInfo.
13+
3) **TcbInfo Matching**
14+
15+
- Each of the reported TcbInfo must fully match each of the reference TcbInfo with same order.
16+
4) **TcbInfo Field**
17+
18+
- The reported TcbInfo must include all fields in the reference TcbInfo. If a field in the reference TcbInfo does not exist in the reported TcbInfo, the verification must fail.
19+
- The reported TcbInfo could include more fields which do not exist in the reference TcbInfo. The extra fields in the reported TcbInfo must be ignored and NOT validated, and they must not impact the final result.
20+
21+
22+
### Note
23+
1) To verify the CertChain DiceTcbInfo extension, please use the following command to build.
24+
```
25+
cmake -G"NMake Makefiles" -DARCH=x64 -DTOOLCHAIN=VS2019 -DTARGET=Debug -DCRYPTO=openssl -DX509_IGNORE_CRITICAL=ON ..
26+
```
27+
28+
```
29+
cmake -G"NMake Makefiles" -DARCH=x64 -DTOOLCHAIN=VS2019 -DTARGET=Release -DCRYPTO=openssl -DX509_IGNORE_CRITICAL=ON ..
30+
```
31+
```
32+
cmake -G"NMake Makefiles" -DARCH=x64 -DTOOLCHAIN=VS2019 -DTARGET=Debug -DCRYPTO=mbedtls -DX509_IGNORE_CRITICAL=ON ..
33+
```
34+
35+
```
36+
cmake -G"NMake Makefiles" -DARCH=x64 -DTOOLCHAIN=VS2019 -DTARGET=Release -DCRYPTO=mbedtls -DX509_IGNORE_CRITICAL=ON ..
37+
```
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,295 @@
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 <base.h>
8+
#include "spdm_cert_verify_callback_internal.h"
9+
10+
/**
11+
* tcg-dice-TcbInfo OID: 2.23.133.5.4.1
12+
* https://trustedcomputinggroup.org/wp-content/uploads/DICE-Attestation-Architecture-Version-1.1-Revision-18_pub.pdf
13+
**/
14+
uint8_t m_libspdm_tcg_dice_tcbinfo_oid[] = {0x67, 0x81, 0x05, 0x05, 0x04, 0x01};
15+
16+
/*the cert chain must have a or more cert with DiceTcbInfo extension*/
17+
bool m_libspdm_must_have_dice_tcb_info = true;
18+
19+
/*the reference cert number with DiceTcbinfo in the cert chain*/
20+
uint8_t m_libspdm_dice_tcb_info_number = 1;
21+
22+
/*reference DiceTcbinfo*/
23+
24+
/*vendor: INTC*/
25+
uint8_t m_libspdm_dice_tcbinfo_vendor[] = {0x49, 0x4E, 0x54, 0x43};
26+
/*model: S3M GNR*/
27+
uint8_t m_libspdm_dice_tcbinfo_model[] = {0x53, 0x33, 0x4D, 0x20, 0x47, 0x4E, 0x52};
28+
/*version: 000200000000008B*/
29+
uint8_t m_libspdm_dice_tcbinfo_version[] = {0x30, 0x30, 0x30, 0x32, 0x30, 0x30, 0x30, 0x30, 0x30,
30+
0x30, 0x30, 0x30, 0x30, 0x30, 0x38, 0x42};
31+
/*svn*/
32+
uint8_t m_libspdm_dice_tcbinfo_svn[] = {0x01};
33+
/*layer*/
34+
uint8_t m_libspdm_dice_tcbinfo_layer[] = {0x01};
35+
/*fwids*/
36+
uint8_t m_libspdm_dice_tcbinfo_fwids[] = {0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04,
37+
0x02, 0x02, 0x04, 0x30, 0x6B, 0x44, 0x7B, 0x5E, 0x99,
38+
0x21, 0x0A, 0x58, 0x8A, 0x7B, 0x31, 0x7D, 0xBA, 0x2D,
39+
0x4A, 0x7F, 0x75, 0xE6, 0x97, 0xF2, 0x07, 0xE0, 0xC2,
40+
0x99, 0x78, 0xF3, 0xF6, 0x2B, 0x53, 0xF5, 0xBE, 0xEB,
41+
0x73, 0xF0, 0x37, 0xB8, 0x79, 0xC1, 0xFF, 0x76, 0x2A,
42+
0x3A, 0x39, 0xCA, 0xE2, 0x8C, 0xF0, 0x56};
43+
/*type*/
44+
uint8_t m_libspdm_dice_tcbinfo_type[] = {0x46, 0x69, 0x72, 0x6D, 0x77, 0x61, 0x72, 0x65, 0x20,
45+
0x44, 0x69, 0x67, 0x65, 0x73, 0x74};
46+
47+
/*verify cert DiceTcbInfo extension*/
48+
bool libspdm_verify_cert_dicetcbinfo(const void *cert, size_t cert_size,
49+
size_t *spdm_get_dice_tcb_info_size) {
50+
bool result;
51+
uint8_t spdm_dice_tcb_info[256];
52+
size_t spdm_dice_tcb_info_size;
53+
uint8_t *ptr;
54+
int32_t length;
55+
size_t obj_len;
56+
uint8_t *end;
57+
58+
spdm_dice_tcb_info_size = 256;
59+
*spdm_get_dice_tcb_info_size = 0;
60+
result = libspdm_x509_get_extension_data(cert, cert_size,
61+
m_libspdm_tcg_dice_tcbinfo_oid,
62+
sizeof(m_libspdm_tcg_dice_tcbinfo_oid),
63+
spdm_dice_tcb_info, &spdm_dice_tcb_info_size);
64+
if (!result) {
65+
return false;
66+
} else if (spdm_dice_tcb_info_size == 0) {
67+
return true;
68+
}
69+
70+
*spdm_get_dice_tcb_info_size = spdm_dice_tcb_info_size;
71+
length = (int32_t)spdm_dice_tcb_info_size;
72+
ptr = (uint8_t*)(size_t)spdm_dice_tcb_info;
73+
obj_len = 0;
74+
end = ptr + length;
75+
76+
/*get DiceTcbInfo*/
77+
result = libspdm_asn1_get_tag(&ptr, end, &obj_len,
78+
LIBSPDM_CRYPTO_ASN1_SEQUENCE | LIBSPDM_CRYPTO_ASN1_CONSTRUCTED);
79+
if (!result) {
80+
*spdm_get_dice_tcb_info_size = 0;
81+
return false;
82+
}
83+
result = libspdm_asn1_get_tag(&ptr, end, &obj_len,
84+
LIBSPDM_CRYPTO_ASN1_SEQUENCE | LIBSPDM_CRYPTO_ASN1_CONSTRUCTED);
85+
if (!result) {
86+
*spdm_get_dice_tcb_info_size = 0;
87+
return false;
88+
}
89+
90+
/*vendor*/
91+
result = libspdm_asn1_get_tag(&ptr, end, &obj_len,
92+
LIBSPDM_CRYPTO_ASN1_CONTEXT_SPECIFIC);
93+
if (result) {
94+
if ((obj_len != sizeof(m_libspdm_dice_tcbinfo_vendor)) ||
95+
(!libspdm_consttime_is_mem_equal(ptr, m_libspdm_dice_tcbinfo_vendor, obj_len))) {
96+
return false;
97+
}
98+
ptr += obj_len;
99+
} else {
100+
return false;
101+
}
102+
/*model*/
103+
result = libspdm_asn1_get_tag(&ptr, end, &obj_len,
104+
LIBSPDM_CRYPTO_ASN1_CONTEXT_SPECIFIC + 1);
105+
if (result) {
106+
if ((obj_len != sizeof(m_libspdm_dice_tcbinfo_model)) ||
107+
(!libspdm_consttime_is_mem_equal(ptr, m_libspdm_dice_tcbinfo_model, obj_len))) {
108+
return false;
109+
}
110+
ptr += obj_len;
111+
} else {
112+
return false;
113+
}
114+
/*version*/
115+
result = libspdm_asn1_get_tag(&ptr, end, &obj_len,
116+
LIBSPDM_CRYPTO_ASN1_CONTEXT_SPECIFIC + 2);
117+
if (result) {
118+
if ((obj_len != sizeof(m_libspdm_dice_tcbinfo_version)) ||
119+
(!libspdm_consttime_is_mem_equal(ptr, m_libspdm_dice_tcbinfo_version, obj_len))) {
120+
return false;
121+
}
122+
ptr += obj_len;
123+
} else {
124+
return false;
125+
}
126+
/*svn*/
127+
result = libspdm_asn1_get_tag(&ptr, end, &obj_len,
128+
LIBSPDM_CRYPTO_ASN1_CONTEXT_SPECIFIC + 3);
129+
if (result) {
130+
if ((obj_len != sizeof(m_libspdm_dice_tcbinfo_svn)) ||
131+
(!libspdm_consttime_is_mem_equal(ptr, m_libspdm_dice_tcbinfo_svn, obj_len))) {
132+
return false;
133+
}
134+
ptr += obj_len;
135+
} else {
136+
return false;
137+
}
138+
/*layer*/
139+
result = libspdm_asn1_get_tag(&ptr, end, &obj_len,
140+
LIBSPDM_CRYPTO_ASN1_CONTEXT_SPECIFIC + 4);
141+
if (result) {
142+
if ((obj_len != sizeof(m_libspdm_dice_tcbinfo_layer)) ||
143+
(!libspdm_consttime_is_mem_equal(ptr, m_libspdm_dice_tcbinfo_layer, obj_len))) {
144+
return false;
145+
}
146+
ptr += obj_len;
147+
}
148+
/*index*/
149+
result = libspdm_asn1_get_tag(&ptr, end, &obj_len,
150+
LIBSPDM_CRYPTO_ASN1_CONTEXT_SPECIFIC + 5);
151+
if (result) {
152+
ptr += obj_len;
153+
}
154+
/*fwids*/
155+
result = libspdm_asn1_get_tag(&ptr, end, &obj_len,
156+
(LIBSPDM_CRYPTO_ASN1_CONTEXT_SPECIFIC |
157+
LIBSPDM_CRYPTO_ASN1_CONSTRUCTED) + 6);
158+
if (result) {
159+
if ((obj_len != sizeof(m_libspdm_dice_tcbinfo_fwids)) ||
160+
(!libspdm_consttime_is_mem_equal(ptr, m_libspdm_dice_tcbinfo_fwids, obj_len))) {
161+
return false;
162+
}
163+
ptr += obj_len;
164+
} else {
165+
return false;
166+
}
167+
/*flags*/
168+
result = libspdm_asn1_get_tag(&ptr, end, &obj_len,
169+
LIBSPDM_CRYPTO_ASN1_CONTEXT_SPECIFIC + 7);
170+
if (result) {
171+
ptr += obj_len;
172+
}
173+
/*vendorInfo*/
174+
result = libspdm_asn1_get_tag(&ptr, end, &obj_len,
175+
LIBSPDM_CRYPTO_ASN1_CONTEXT_SPECIFIC + 8);
176+
if (result) {
177+
ptr += obj_len;
178+
}
179+
/*type*/
180+
result = libspdm_asn1_get_tag(&ptr, end, &obj_len,
181+
LIBSPDM_CRYPTO_ASN1_CONTEXT_SPECIFIC + 9);
182+
if (result) {
183+
if ((obj_len != sizeof(m_libspdm_dice_tcbinfo_type)) ||
184+
(!libspdm_consttime_is_mem_equal(ptr, m_libspdm_dice_tcbinfo_type, obj_len))) {
185+
return false;
186+
}
187+
ptr += obj_len;
188+
} else {
189+
return false;
190+
}
191+
/*flagMask*/
192+
result = libspdm_asn1_get_tag(&ptr, end, &obj_len,
193+
LIBSPDM_CRYPTO_ASN1_CONTEXT_SPECIFIC + 10);
194+
if (result) {
195+
ptr += obj_len;
196+
}
197+
198+
if (ptr == end) {
199+
return true;
200+
} else {
201+
return false;
202+
}
203+
}
204+
205+
/*callback function for verifying cert_chain DiceTcbInfo extension*/
206+
bool libspdm_verify_spdm_cert_chain_with_dice(void *spdm_context, uint8_t slot_id,
207+
size_t cert_chain_size, const void *cert_chain,
208+
const void **trust_anchor,
209+
size_t *trust_anchor_size)
210+
{
211+
bool result;
212+
libspdm_context_t *context;
213+
const uint8_t *cert_chain_data;
214+
size_t cert_chain_data_size;
215+
size_t hash_size;
216+
uint8_t *ptr;
217+
uint8_t *tem_ptr;
218+
int32_t length;
219+
size_t obj_len;
220+
uint8_t *end;
221+
size_t cert_dice_tcb_info_size;
222+
bool cert_chain_have_matched_dice;
223+
uint8_t number_dice_tcb_info;
224+
225+
/*verify peer cert chain integrity*/
226+
result = libspdm_verify_peer_cert_chain_buffer_integrity(spdm_context, cert_chain,
227+
cert_chain_size);
228+
if (!result) {
229+
return false;
230+
}
231+
232+
/*verify peer cert chain authority*/
233+
result = libspdm_verify_peer_cert_chain_buffer_authority(spdm_context, cert_chain,
234+
cert_chain_size, trust_anchor,
235+
trust_anchor_size);
236+
if (!result) {
237+
return false;
238+
}
239+
240+
context = spdm_context;
241+
hash_size = libspdm_get_hash_size(context->connection_info.algorithm.base_hash_algo);
242+
243+
cert_chain_data = (const uint8_t *)cert_chain + sizeof(spdm_cert_chain_t) + hash_size;
244+
cert_chain_data_size = cert_chain_size - sizeof(spdm_cert_chain_t) - hash_size;
245+
246+
length = (int32_t)cert_chain_data_size;
247+
ptr = (uint8_t*)(size_t)cert_chain_data;
248+
obj_len = 0;
249+
end = ptr + length;
250+
cert_chain_have_matched_dice = false;
251+
number_dice_tcb_info = 0;
252+
253+
while (ptr < end) {
254+
cert_dice_tcb_info_size = 0;
255+
tem_ptr = ptr;
256+
result = libspdm_asn1_get_tag(&ptr, end, &obj_len,
257+
LIBSPDM_CRYPTO_ASN1_SEQUENCE |
258+
LIBSPDM_CRYPTO_ASN1_CONSTRUCTED);
259+
if (result) {
260+
/*verify Dice TCB info*/
261+
result = libspdm_verify_cert_dicetcbinfo(tem_ptr, obj_len + (ptr - tem_ptr),
262+
&cert_dice_tcb_info_size);
263+
if (!result) {
264+
if (cert_dice_tcb_info_size == 0) {
265+
return false;
266+
}
267+
number_dice_tcb_info++;
268+
} else {
269+
if (cert_dice_tcb_info_size != 0) {
270+
cert_chain_have_matched_dice = true;
271+
number_dice_tcb_info++;
272+
}
273+
}
274+
/* Move to next cert*/
275+
ptr += obj_len;
276+
} else {
277+
return false;
278+
}
279+
}
280+
281+
if (m_libspdm_must_have_dice_tcb_info && !cert_chain_have_matched_dice) {
282+
return false;
283+
}
284+
285+
/*check the number of cert with DiceTcbinfo in cert chain*/
286+
if (number_dice_tcb_info != m_libspdm_dice_tcb_info_number) {
287+
return false;
288+
}
289+
290+
if (ptr == end) {
291+
return true;
292+
} else {
293+
return false;
294+
}
295+
}

0 commit comments

Comments
 (0)