Skip to content

Commit be35cca

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 ceb8802 commit be35cca

File tree

7 files changed

+622
-0
lines changed

7 files changed

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

0 commit comments

Comments
 (0)