TianoCore EDK2 master
Loading...
Searching...
No Matches
SpdmConnectionInit.c
Go to the documentation of this file.
1
11
12LIST_ENTRY mSpdmDeviceContextList = INITIALIZE_LIST_HEAD_VARIABLE (mSpdmDeviceContextList);
13
14#define CONNECTUIN_FAILURE_GET_SPDM_UID_FAILED "Fail to get Spdm Uid"
15#define CONNECTUIN_FAILURE_STGNATURE_DB_FUL_STRING "The Signature database devdb is full"
16
23VOID
25 IN SPDM_DEVICE_CONTEXT *SpdmDeviceContext
26 )
27{
28 SPDM_DEVICE_CONTEXT_INSTANCE *NewSpdmDeviceContext;
29 LIST_ENTRY *SpdmDeviceContextList;
30
31 SpdmDeviceContextList = &mSpdmDeviceContextList;
32
33 NewSpdmDeviceContext = AllocateZeroPool (sizeof (*NewSpdmDeviceContext));
34 if (NewSpdmDeviceContext == NULL) {
35 ASSERT (NewSpdmDeviceContext != NULL);
36 return;
37 }
38
39 NewSpdmDeviceContext->Signature = SPDM_DEVICE_CONTEXT_INSTANCE_SIGNATURE;
40 NewSpdmDeviceContext->SpdmDeviceContext = SpdmDeviceContext;
41
42 InsertTailList (SpdmDeviceContextList, &NewSpdmDeviceContext->Link);
43}
44
53VOID *
54EFIAPI
56 IN VOID *SpdmContext
57 )
58{
59 LIST_ENTRY *Link;
60 SPDM_DEVICE_CONTEXT_INSTANCE *CurrentSpdmDeviceContext;
61 LIST_ENTRY *SpdmDeviceContextList;
62
63 SpdmDeviceContextList = &mSpdmDeviceContextList;
64
65 Link = GetFirstNode (SpdmDeviceContextList);
66 while (!IsNull (SpdmDeviceContextList, Link)) {
67 CurrentSpdmDeviceContext = SPDM_DEVICE_CONTEXT_INSTANCE_FROM_LINK (Link);
68
69 if (CurrentSpdmDeviceContext->SpdmDeviceContext->SpdmContext == SpdmContext) {
70 return CurrentSpdmDeviceContext->SpdmDeviceContext->SpdmIoProtocol;
71 }
72
73 Link = GetNextNode (SpdmDeviceContextList, Link);
74 }
75
76 return NULL;
77}
78
91 UINT64 *SpdmUid
92 )
93{
94 EFI_STATUS Status;
95 UINTN VarSize;
96 UINT64 Uid;
97
98 VarSize = sizeof (*SpdmUid);
99 Status = gRT->GetVariable (
100 L"SpdmUid",
101 &gEfiDeviceSecuritySpdmUidGuid,
102 NULL,
103 &VarSize,
104 &Uid
105 );
106 if (Status == EFI_NOT_FOUND) {
107 Uid = 0;
108 } else if (EFI_ERROR (Status)) {
109 return Status;
110 }
111
112 *SpdmUid = Uid++;
113 Status = gRT->SetVariable (
114 L"SpdmUid",
115 &gEfiDeviceSecuritySpdmUidGuid,
116 EFI_VARIABLE_BOOTSERVICE_ACCESS,
117 sizeof (Uid),
118 &Uid
119 );
120
121 return Status;
122}
123
137 IN CHAR8 *FailureString,
138 IN UINT32 StringLen
139 )
140{
141 EFI_STATUS Status;
142
143 Status = TpmMeasureAndLogData (
144 1,
145 EV_PLATFORM_CONFIG_FLAGS,
146 FailureString,
147 StringLen,
148 FailureString,
149 StringLen
150 );
151 DEBUG ((DEBUG_INFO, "RecordConnectionFailureStatus %r\n", Status));
152 return Status;
153}
154
166EFIAPI
168 IN EDKII_SPDM_DEVICE_INFO *SpdmDeviceInfo,
169 OUT EDKII_DEVICE_SECURITY_STATE *SecurityState
170 )
171{
172 SPDM_DEVICE_CONTEXT *SpdmDeviceContext;
173 VOID *SpdmContext;
174 UINTN SpdmContextSize;
175 VOID *ScratchBuffer;
176 UINTN ScratchBufferSize;
177 EFI_STATUS Status;
178 SPDM_RETURN SpdmReturn;
179 EFI_SIGNATURE_LIST *DbList;
180 EFI_SIGNATURE_DATA *Cert;
181 UINTN CertCount;
182 UINTN Index;
183 UINTN SiglistHeaderSize;
184 UINTN DbSize;
185 VOID *Data;
186 UINTN DataSize;
187 SPDM_DATA_PARAMETER Parameter;
188 UINT8 Data8;
189 UINT16 Data16;
190 UINT32 Data32;
191 UINT8 AuthState;
192
193 SpdmDeviceContext = AllocateZeroPool (sizeof (*SpdmDeviceContext));
194 if (SpdmDeviceContext == NULL) {
195 ASSERT (SpdmDeviceContext != NULL);
196 return NULL;
197 }
198
199 SpdmDeviceContext->Signature = SPDM_DEVICE_CONTEXT_SIGNATURE;
200 CopyMem (&SpdmDeviceContext->DeviceId, SpdmDeviceInfo->DeviceId, sizeof (EDKII_DEVICE_IDENTIFIER));
201 SpdmDeviceContext->IsEmbeddedDevice = SpdmDeviceInfo->IsEmbeddedDevice;
202
203 SpdmContextSize = SpdmGetContextSize ();
204 SpdmContext = AllocateZeroPool (SpdmContextSize);
205 if (SpdmContext == NULL) {
206 ASSERT (SpdmContext != NULL);
207 goto Error;
208 }
209
210 SpdmReturn = SpdmInitContext (SpdmContext);
211 if (LIBSPDM_STATUS_IS_ERROR (SpdmReturn)) {
212 goto Error;
213 }
214
215 SpdmRegisterDeviceIoFunc (
216 SpdmContext,
217 SpdmDeviceInfo->SendMessage,
218 SpdmDeviceInfo->ReceiveMessage
219 );
220 SpdmRegisterTransportLayerFunc (
221 SpdmContext,
222 SpdmDeviceInfo->MaxSpdmMsgSize,
223 SpdmDeviceInfo->TransportHeaderSize,
224 SpdmDeviceInfo->TransportTailSize,
225 SpdmDeviceInfo->TransportEncodeMessage,
226 SpdmDeviceInfo->TransportDecodeMessage
227 );
228
229 SpdmRegisterDeviceBufferFunc (
230 SpdmContext,
231 SpdmDeviceInfo->SenderBufferSize,
232 SpdmDeviceInfo->ReceiverBufferSize,
233 SpdmDeviceInfo->AcquireSenderBuffer,
234 SpdmDeviceInfo->ReleaseSenderBuffer,
235 SpdmDeviceInfo->AcquireReceiverBuffer,
236 SpdmDeviceInfo->ReleaseReceiverBuffer
237 );
238
239 ScratchBufferSize = SpdmGetSizeofRequiredScratchBuffer (SpdmContext);
240 ScratchBuffer = AllocateZeroPool (ScratchBufferSize);
241 if (ScratchBuffer == NULL) {
242 ASSERT (ScratchBuffer != NULL);
243 goto Error;
244 }
245
246 SpdmSetScratchBuffer (SpdmContext, ScratchBuffer, ScratchBufferSize);
247
248 SpdmDeviceContext->SpdmContextSize = SpdmContextSize;
249 SpdmDeviceContext->SpdmContext = SpdmContext;
250 SpdmDeviceContext->ScratchBufferSize = ScratchBufferSize;
251 SpdmDeviceContext->ScratchBuffer = ScratchBuffer;
252
253 Status = gBS->HandleProtocol (
254 SpdmDeviceContext->DeviceId.DeviceHandle,
255 &gEfiDevicePathProtocolGuid,
256 (VOID **)&SpdmDeviceContext->DevicePath
257 );
258 if (EFI_ERROR (Status)) {
259 DEBUG ((DEBUG_ERROR, "Locate - DevicePath - %r\n", Status));
260 goto Error;
261 }
262
263 Status = gBS->HandleProtocol (
264 SpdmDeviceContext->DeviceId.DeviceHandle,
265 &SpdmDeviceContext->DeviceId.DeviceType,
266 (VOID **)&SpdmDeviceContext->DeviceIo
267 );
268 if (EFI_ERROR (Status)) {
269 DEBUG ((DEBUG_ERROR, "Locate - DeviceIo - %r\n", Status));
270 // This is optional, only check known device type later.
271 }
272
273 if (SpdmDeviceInfo->SpdmIoProtocolGuid != NULL) {
274 Status = gBS->HandleProtocol (
275 SpdmDeviceContext->DeviceId.DeviceHandle,
276 SpdmDeviceInfo->SpdmIoProtocolGuid,
277 (VOID **)&SpdmDeviceContext->SpdmIoProtocol
278 );
279 if (EFI_ERROR (Status)) {
280 DEBUG ((DEBUG_ERROR, "Locate - SpdmIoProtocol - %r\n", Status));
281 goto Error;
282 }
283 }
284
285 if (CompareGuid (&SpdmDeviceContext->DeviceId.DeviceType, &gEdkiiDeviceIdentifierTypePciGuid)) {
286 if (SpdmDeviceContext->DeviceIo == NULL) {
287 DEBUG ((DEBUG_ERROR, "Locate - PciIo - %r\n", Status));
288 goto Error;
289 }
290 }
291
292 Status = GetSpdmUid (&SpdmDeviceContext->DeviceUID);
293 if (EFI_ERROR (Status)) {
295 CONNECTUIN_FAILURE_GET_SPDM_UID_FAILED,
296 sizeof (CONNECTUIN_FAILURE_GET_SPDM_UID_FAILED)
297 );
298 if (EFI_ERROR (Status)) {
299 goto Error;
300 }
301
302 ASSERT (FALSE);
303 DEBUG ((DEBUG_ERROR, "Fail to get UID - %r\n", Status));
304 goto Error;
305 }
306
307 RecordSpdmDeviceContextInList (SpdmDeviceContext);
308
309 Status = GetVariable2 (
310 EFI_DEVICE_SECURITY_DATABASE,
311 &gEfiDeviceSignatureDatabaseGuid,
312 (VOID **)&SpdmDeviceContext->SignatureList,
313 &SpdmDeviceContext->SignatureListSize
314 );
315 if ((!EFI_ERROR (Status)) && (SpdmDeviceContext->SignatureList != NULL)) {
316 DbList = SpdmDeviceContext->SignatureList;
317 DbSize = SpdmDeviceContext->SignatureListSize;
318 while ((DbSize > 0) && (SpdmDeviceContext->SignatureListSize >= DbList->SignatureListSize)) {
319 if (DbList->SignatureListSize == 0) {
320 break;
321 }
322
323 if ( (!CompareGuid (&DbList->SignatureType, &gEfiCertX509Guid))
324 || (DbList->SignatureHeaderSize != 0)
325 || (DbList->SignatureSize < sizeof (EFI_SIGNATURE_DATA)))
326 {
327 DbSize -= DbList->SignatureListSize;
328 DbList = (EFI_SIGNATURE_LIST *)((UINT8 *)DbList + DbList->SignatureListSize);
329 continue;
330 }
331
332 SiglistHeaderSize = sizeof (EFI_SIGNATURE_LIST) + DbList->SignatureHeaderSize;
333 Cert = (EFI_SIGNATURE_DATA *)((UINT8 *)DbList + SiglistHeaderSize);
334 CertCount = (DbList->SignatureListSize - SiglistHeaderSize) / DbList->SignatureSize;
335
336 for (Index = 0; Index < CertCount; Index++) {
337 Data = Cert->SignatureData;
338 DataSize = DbList->SignatureSize - sizeof (EFI_GUID);
339
340 ZeroMem (&Parameter, sizeof (Parameter));
341 Parameter.location = SpdmDataLocationLocal;
342 SpdmReturn = SpdmSetData (SpdmContext, SpdmDataPeerPublicRootCert, &Parameter, Data, DataSize);
343 if (LIBSPDM_STATUS_IS_ERROR (SpdmReturn)) {
344 if (SpdmReturn == LIBSPDM_STATUS_BUFFER_FULL) {
346 CONNECTUIN_FAILURE_STGNATURE_DB_FUL_STRING,
347 sizeof (CONNECTUIN_FAILURE_STGNATURE_DB_FUL_STRING)
348 );
349 if (EFI_ERROR (Status)) {
350 goto Error;
351 }
352
353 ASSERT (FALSE);
354 }
355
356 goto Error;
357 }
358
359 Cert = (EFI_SIGNATURE_DATA *)((UINT8 *)Cert + DbList->SignatureSize);
360 }
361
362 DbSize -= DbList->SignatureListSize;
363 DbList = (EFI_SIGNATURE_LIST *)((UINT8 *)DbList + DbList->SignatureListSize);
364 }
365 }
366
367 Data8 = 0;
368 ZeroMem (&Parameter, sizeof (Parameter));
369 Parameter.location = SpdmDataLocationLocal;
370 SpdmReturn = SpdmSetData (SpdmContext, SpdmDataCapabilityCTExponent, &Parameter, &Data8, sizeof (Data8));
371 if (LIBSPDM_STATUS_IS_ERROR (SpdmReturn)) {
372 ASSERT (FALSE);
373 goto Error;
374 }
375
376 Data32 = 0;
377 SpdmReturn = SpdmSetData (SpdmContext, SpdmDataCapabilityFlags, &Parameter, &Data32, sizeof (Data32));
378 if (LIBSPDM_STATUS_IS_ERROR (SpdmReturn)) {
379 ASSERT (FALSE);
380 goto Error;
381 }
382
383 Data8 = SPDM_MEASUREMENT_SPECIFICATION_DMTF;
384 SpdmReturn = SpdmSetData (SpdmContext, SpdmDataMeasurementSpec, &Parameter, &Data8, sizeof (Data8));
385 if (LIBSPDM_STATUS_IS_ERROR (SpdmReturn)) {
386 ASSERT (FALSE);
387 goto Error;
388 }
389
390 if (SpdmDeviceInfo->BaseAsymAlgo != 0) {
391 Data32 = SpdmDeviceInfo->BaseAsymAlgo;
392 } else {
394 SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_3072 |
395 SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_4096 |
396 SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P256 |
397 SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P384 |
398 SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P521;
399 }
400
401 SpdmReturn = SpdmSetData (SpdmContext, SpdmDataBaseAsymAlgo, &Parameter, &Data32, sizeof (Data32));
402 if (LIBSPDM_STATUS_IS_ERROR (SpdmReturn)) {
403 ASSERT (FALSE);
404 goto Error;
405 }
406
407 if (SpdmDeviceInfo->BaseHashAlgo != 0) {
408 Data32 = SpdmDeviceInfo->BaseHashAlgo;
409 } else {
411 SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA_384 |
412 SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA_512;
413 }
414
415 SpdmReturn = SpdmSetData (SpdmContext, SpdmDataBaseHashAlgo, &Parameter, &Data32, sizeof (Data32));
416 if (LIBSPDM_STATUS_IS_ERROR (SpdmReturn)) {
417 ASSERT (FALSE);
418 goto Error;
419 }
420
421 SpdmReturn = SpdmInitConnection (SpdmContext, FALSE);
422 if (LIBSPDM_STATUS_IS_ERROR (SpdmReturn)) {
423 DEBUG ((DEBUG_ERROR, "SpdmInitConnection - %p\n", SpdmReturn));
424
425 AuthState = TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_AUTH_STATE_NO_SPDM;
426 SecurityState->AuthenticationState = EDKII_DEVICE_SECURITY_STATE_ERROR_DEVICE_NO_CAPABILITIES;
427 Status = ExtendCertificate (SpdmDeviceContext, AuthState, 0, NULL, NULL, 0, 0, SecurityState);
428 if (Status != EFI_SUCCESS) {
429 DEBUG ((DEBUG_ERROR, "ExtendCertificate AUTH_STATE_NO_SPDM failed\n"));
430 }
431
432 goto Error;
433 }
434
435 ZeroMem (&Parameter, sizeof (Parameter));
436 Parameter.location = SpdmDataLocationConnection;
437 DataSize = sizeof (Data16);
438 SpdmReturn = SpdmGetData (SpdmContext, SpdmDataSpdmVersion, &Parameter, &Data16, &DataSize);
439 if (LIBSPDM_STATUS_IS_ERROR (SpdmReturn)) {
440 DEBUG ((DEBUG_ERROR, "SpdmGetData - %p\n", SpdmReturn));
441 goto Error;
442 }
443
444 SpdmDeviceContext->SpdmVersion = (Data16 >> SPDM_VERSION_NUMBER_SHIFT_BIT);
445
446 return SpdmDeviceContext;
447Error:
448 DestroySpdmDeviceContext (SpdmDeviceContext);
449 return NULL;
450}
451
458VOID
459EFIAPI
461 IN SPDM_DEVICE_CONTEXT *SpdmDeviceContext
462 )
463{
464 // need zero memory in case of secret in memory.
465 if (SpdmDeviceContext->SpdmContext != NULL) {
466 ZeroMem (SpdmDeviceContext->SpdmContext, SpdmDeviceContext->SpdmContextSize);
467 FreePool (SpdmDeviceContext->SpdmContext);
468 }
469
470 if (SpdmDeviceContext->ScratchBuffer != NULL) {
471 ZeroMem (SpdmDeviceContext->ScratchBuffer, SpdmDeviceContext->ScratchBufferSize);
472 FreePool (SpdmDeviceContext->ScratchBuffer);
473 }
474
475 if (SpdmDeviceContext->SignatureList != NULL) {
476 ZeroMem (SpdmDeviceContext->SignatureList, SpdmDeviceContext->SignatureListSize);
477 FreePool (SpdmDeviceContext->SignatureList);
478 }
479
480 FreePool (SpdmDeviceContext);
481}
UINT64 UINTN
BOOLEAN EFIAPI IsNull(IN CONST LIST_ENTRY *List, IN CONST LIST_ENTRY *Node)
Definition: LinkedList.c:443
LIST_ENTRY *EFIAPI GetNextNode(IN CONST LIST_ENTRY *List, IN CONST LIST_ENTRY *Node)
Definition: LinkedList.c:333
LIST_ENTRY *EFIAPI GetFirstNode(IN CONST LIST_ENTRY *List)
Definition: LinkedList.c:298
#define INITIALIZE_LIST_HEAD_VARIABLE(ListHead)
Definition: BaseLib.h:2904
LIST_ENTRY *EFIAPI InsertTailList(IN OUT LIST_ENTRY *ListHead, IN OUT LIST_ENTRY *Entry)
Definition: LinkedList.c:259
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
BOOLEAN EFIAPI CompareGuid(IN CONST GUID *Guid1, IN CONST GUID *Guid2)
Definition: MemLibGuid.c:73
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
EFI_GUID gEdkiiDeviceIdentifierTypePciGuid
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
EFI_RUNTIME_SERVICES * gRT
#define NULL
Definition: Base.h:319
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define DEBUG(Expression)
Definition: DebugLib.h:434
#define SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_2048
Definition: Spdm.h:327
#define SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA_256
Definition: Spdm.h:347
EFI_STATUS ExtendCertificate(IN SPDM_DEVICE_CONTEXT *SpdmDeviceContext, IN UINT8 AuthState, IN UINTN CertChainSize, IN UINT8 *CertChain, IN VOID *TrustAnchor, IN UINTN TrustAnchorSize, IN UINT8 SlotId, OUT EDKII_DEVICE_SECURITY_STATE *SecurityState)
VOID *EFIAPI GetSpdmIoProtocolViaSpdmContext(IN VOID *SpdmContext)
SPDM_DEVICE_CONTEXT *EFIAPI CreateSpdmDeviceContext(IN EDKII_SPDM_DEVICE_INFO *SpdmDeviceInfo, OUT EDKII_DEVICE_SECURITY_STATE *SecurityState)
VOID EFIAPI DestroySpdmDeviceContext(IN SPDM_DEVICE_CONTEXT *SpdmDeviceContext)
VOID RecordSpdmDeviceContextInList(IN SPDM_DEVICE_CONTEXT *SpdmDeviceContext)
EFI_STATUS RecordConnectionFailureStatus(IN CHAR8 *FailureString, IN UINT32 StringLen)
EFI_STATUS GetSpdmUid(UINT64 *SpdmUid)
EFI_STATUS EFIAPI TpmMeasureAndLogData(IN UINT32 PcrIndex, IN UINT32 EventType, IN VOID *EventLog, IN UINT32 LogLen, IN VOID *HashData, IN UINT64 HashDataLen)
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
GUID EFI_GUID
Definition: UefiBaseType.h:25
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_BOOT_SERVICES * gBS
EFI_STATUS EFIAPI GetVariable2(IN CONST CHAR16 *Name, IN CONST EFI_GUID *Guid, OUT VOID **Value, OUT UINTN *Size OPTIONAL)
Definition: UefiLib.c:1317