VirtualBox

source: vbox/trunk/src/VBox/Runtime/common/efi/efisignaturedb.cpp@ 90287

Last change on this file since 90287 was 90287, checked in by vboxsync, 4 years ago

Runtime/efi: Started implementing the functionality to parse, create and modify EFI signature databases, bugref:9580 [build fix]

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 20.8 KB
Line 
1/* $Id: efisignaturedb.cpp 90287 2021-07-22 13:16:15Z vboxsync $ */
2/** @file
3 * IPRT - EFI signature database helpers.
4 */
5
6/*
7 * Copyright (C) 2021 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * The contents of this file may alternatively be used under the terms
18 * of the Common Development and Distribution License Version 1.0
19 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
20 * VirtualBox OSE distribution, in which case the provisions of the
21 * CDDL are applicable instead of those of the GPL.
22 *
23 * You may elect to license modified versions of this file under the
24 * terms and conditions of either the GPL or the CDDL or both.
25 */
26
27
28/*********************************************************************************************************************************
29* Header Files *
30*********************************************************************************************************************************/
31#define LOG_GROUP RTLOGGROUP_DEFAULT
32#include <iprt/efi.h>
33
34#include <iprt/cdefs.h>
35#include <iprt/string.h>
36#include <iprt/list.h>
37#include <iprt/mem.h>
38#include <iprt/sg.h>
39
40#include <iprt/formats/efi-signature.h>
41
42
43/*********************************************************************************************************************************
44* Defined Constants And Macros *
45*********************************************************************************************************************************/
46
47
48/*********************************************************************************************************************************
49* Structures and Typedefs *
50*********************************************************************************************************************************/
51
52/**
53 * EFI signature entry.
54 */
55typedef struct RTEFISIGNATURE
56{
57 /** List node. */
58 RTLISTNODE NdLst;
59 /** The signature owner. */
60 RTUUID UuidOwner;
61 /** Size of the signature data in bytes. */
62 uint32_t cbSignature;
63 /** The signature data (variable in size). */
64 RT_FLEXIBLE_ARRAY_EXTENSION
65 uint8_t abSignature[RT_FLEXIBLE_ARRAY];
66} RTEFISIGNATURE;
67/** Pointer to a EFI signature entry. */
68typedef RTEFISIGNATURE *PRTEFISIGNATURE;
69/** Pointer to a const EFI signature entry. */
70typedef const RTEFISIGNATURE *PCRTEFISIGNATURE;
71
72
73/**
74 * The EFI signature database instance data.
75 */
76typedef struct RTEFISIGDBINT
77{
78 /** List head of the various signature types. */
79 RTLISTANCHOR aLstSigTypes[RTEFISIGTYPE_FIRST_INVALID];
80} RTEFISIGDBINT;
81/** Pointer to the EFI signature database instance data. */
82typedef RTEFISIGDBINT *PRTEFISIGDBINT;
83
84
85/**
86 * Signature type descriptor.
87 */
88typedef struct RTEFISIGDBDESC
89{
90 /** The EFI GUID identifying the signature type. */
91 EFI_GUID GuidSignatureType;
92 /** The additional signature header for this signature type. */
93 uint32_t cbSigHdr;
94 /** Size of the signature data (including EFI_SIGNATURE_DATA),
95 * can be 0 size varies with each signature (X.509 for example). */
96 uint32_t cbSig;
97 /** The internal signature type enum. */
98 RTEFISIGTYPE enmSigType;
99 /** Human readable string of the signature type. */
100 const char *pszName;
101} RTEFISIGDBDESC;
102/** Pointer to a signature type descriptor. */
103typedef RTEFISIGDBDESC *PRTEFISIGDBDESC;
104/** Pointer to a const signature type descriptor. */
105typedef const RTEFISIGDBDESC *PCRTEFISIGDBDESC;
106
107
108/*********************************************************************************************************************************
109* Global Variables *
110*********************************************************************************************************************************/
111
112/**
113 * Mapping of EFI signature GUIDs to their IPRT signature type equivalent.
114 */
115static const RTEFISIGDBDESC g_aGuid2SigTypeMapping[] =
116{
117 { EFI_NULL_GUID, 0, 0, RTEFISIGTYPE_INVALID, "INVALID" },
118 { EFI_SIGNATURE_TYPE_GUID_SHA256, 0, EFI_SIGNATURE_TYPE_SZ_SHA256, RTEFISIGTYPE_SHA256, "SHA-256" },
119 { EFI_SIGNATURE_TYPE_GUID_RSA2048, 0, EFI_SIGNATURE_TYPE_SZ_RSA2048, RTEFISIGTYPE_RSA2048, "RSA-2048" },
120 { EFI_SIGNATURE_TYPE_GUID_RSA2048_SHA256, 0, EFI_SIGNATURE_TYPE_SZ_RSA2048_SHA256, RTEFISIGTYPE_RSA2048_SHA256, "RSA-2048/SHA-256" },
121 { EFI_SIGNATURE_TYPE_GUID_SHA1, 0, EFI_SIGNATURE_TYPE_SZ_SHA1, RTEFISIGTYPE_SHA1, "SHA-1" },
122 { EFI_SIGNATURE_TYPE_GUID_RSA2048_SHA1, 0, EFI_SIGNATURE_TYPE_SZ_RSA2048_SHA1, RTEFISIGTYPE_RSA2048_SHA1, "RSA-2048/SHA-1" },
123 { EFI_SIGNATURE_TYPE_GUID_X509, 0, 0, RTEFISIGTYPE_X509, "X.509" }
124};
125
126
127/*********************************************************************************************************************************
128* Internal Functions *
129*********************************************************************************************************************************/
130
131
132/**
133 * Returns the internal siganture type descriptor for the given EFI GUID.
134 *
135 * @returns Pointer to the descriptor if found or NULL if not.
136 * @param pGuid The EFI signature type GUID to look for.
137 */
138static PCRTEFISIGDBDESC rtEfiSigDbGetDescByGuid(PCEFI_GUID pGuid)
139{
140 for (uint32_t i = 0; i < RT_ELEMENTS(g_aGuid2SigTypeMapping); i++)
141 if (!RTEfiGuidCompare(&g_aGuid2SigTypeMapping[i].GuidSignatureType, pGuid))
142 return &g_aGuid2SigTypeMapping[i];
143
144 return NULL;
145}
146
147
148/**
149 * Validates the given signature lsit header.
150 *
151 * @returns Flag whether the list header is considered valid.
152 * @param pLstHdr The list header to validate.
153 * @param pDesc The descriptor for the signature type of the given list.
154 */
155static bool rtEfiSigDbSigHdrValidate(PCEFI_SIGNATURE_LIST pLstHdr, PCRTEFISIGDBDESC pDesc)
156{
157 uint32_t cbSigLst = RT_LE2H_U32(pLstHdr->cbSigLst);
158 uint32_t cbSigHdr = RT_LE2H_U32(pLstHdr->cbSigHdr);
159 uint32_t cbSig = RT_LE2H_U32(pLstHdr->cbSig);
160
161 if (cbSigHdr != pDesc->cbSigHdr)
162 return false;
163 if (cbSig < sizeof(EFI_SIGNATURE_DATA))
164 return false;
165 if ( pDesc->cbSig
166 && pLstHdr->cbSig != pDesc->cbSig)
167 return false;
168 if ( cbSigLst <= sizeof(*pLstHdr)
169 || cbSigLst <= cbSigHdr
170 || cbSigLst <= cbSig)
171 return false;
172 if ((cbSigLst - sizeof(*pLstHdr) - cbSigHdr) % cbSig)
173 return false;
174
175 return true;
176}
177
178
179/**
180 * Loads a single signature list into the given signature database from the given file.
181 *
182 * @returns IPRT status code.
183 * @param pThis The signature database instance.
184 * @param hVfsFileIn The file to load the signature list from.
185 * @param pcbConsumed Where to store the number of bytes consumed for this signature list on success.
186 */
187static int rtEfiSigDbLoadSigList(PRTEFISIGDBINT pThis, RTVFSFILE hVfsFileIn, uint64_t *pcbConsumed)
188{
189 EFI_SIGNATURE_LIST LstHdr;
190 int rc = RTVfsFileRead(hVfsFileIn, &LstHdr, sizeof(LstHdr), NULL /*pcbRead*/);
191 if (RT_SUCCESS(rc))
192 {
193 PCRTEFISIGDBDESC pDesc = rtEfiSigDbGetDescByGuid(&LstHdr.GuidSigType);
194 if (pDesc)
195 {
196 if (rtEfiSigDbSigHdrValidate(&LstHdr, pDesc))
197 {
198 RTLISTANCHOR LstTmp;
199 uint32_t cbSig = RT_LE2H_U32(LstHdr.cbSig);
200 uint32_t cbSigData = cbSig - sizeof(EFI_SIGNATURE_DATA);
201 uint32_t cSigs = (RT_LE2H_U32(LstHdr.cbSigLst) - RT_LE2H_U32(LstHdr.cbSigHdr)) / cbSig;
202
203 /** @todo Skip/parse signature header if we have to add a type which has this != 0. */
204 RTListInit(&LstTmp);
205 for (uint32_t i = 0; i < cSigs && RT_SUCCESS(rc); i++)
206 {
207 PRTEFISIGNATURE pSig = (PRTEFISIGNATURE)RTMemAllocZ(RT_UOFFSETOF_DYN(RTEFISIGNATURE, abSignature[cbSigData]));
208 if (pSig)
209 {
210 EFI_SIGNATURE_DATA SigData;
211 rc = RTVfsFileRead(hVfsFileIn, &SigData, sizeof(SigData), NULL /*pcbRead*/);
212 if (RT_SUCCESS(rc))
213 rc = RTVfsFileRead(hVfsFileIn, &pSig->abSignature[0], cbSigData, NULL /*pcbRead*/);
214 if (RT_SUCCESS(rc))
215 {
216 RTEfiGuidToUuid(&pSig->UuidOwner, &SigData.GuidOwner);
217 pSig->cbSignature = cbSigData;
218 RTListAppend(&LstTmp, &pSig->NdLst);
219 }
220 else
221 RTMemFree(pSig);
222 }
223 else
224 rc = VERR_NO_MEMORY;
225 }
226
227 if (RT_SUCCESS(rc))
228 {
229 /* Add the signatures to the list. */
230 RTListConcatenate(&pThis->aLstSigTypes[pDesc->enmSigType], &LstTmp);
231 *pcbConsumed = sizeof(LstHdr) + RT_LE2H_U32(LstHdr.cbSigHdr) + cSigs * cbSig;
232 }
233 else
234 {
235 /* Destroy the temporary list. */
236 PRTEFISIGNATURE pIt, pItNext;
237
238 RTListForEachSafe(&LstTmp, pIt, pItNext, RTEFISIGNATURE, NdLst)
239 {
240 RTListNodeRemove(&pIt->NdLst);
241 RTMemFree(pIt);
242 }
243 }
244 }
245 else
246 rc = VERR_NOT_SUPPORTED;
247 }
248 else
249 rc = VERR_NOT_SUPPORTED;
250 }
251
252 return rc;
253}
254
255
256/**
257 * Variant for written a list of signatures where each signature gets its own signature list header
258 * (for types where each signature can differ in size like X.509).
259 *
260 * @returns IPRT status code.
261 * @param pLst The list of signatures to write.
262 * @param pDesc The signature type descriptor.
263 * @param hVfsFileOut The file to write the database to.
264 * @param pcbThisWritten Where to store the number of bytes written for the given signature list.
265 */
266static int rtEfiSigDbWriteListSingle(PRTLISTANCHOR pLst, PCRTEFISIGDBDESC pDesc, RTVFSFILE hVfsFileOut, size_t *pcbThisWritten)
267{
268 int rc = VINF_SUCCESS;
269 size_t cbWritten = 0;
270 PRTEFISIGNATURE pIt;
271
272 RTListForEach(pLst, pIt, RTEFISIGNATURE, NdLst)
273 {
274 EFI_SIGNATURE_LIST LstHdr;
275 LstHdr.GuidSigType = pDesc->GuidSignatureType;
276 LstHdr.cbSigLst = RT_H2LE_U32(sizeof(LstHdr) + pDesc->cbSigHdr + pIt->cbSignature);
277 LstHdr.cbSigHdr = RT_H2LE_U32(pDesc->cbSigHdr);
278 LstHdr.cbSig = RT_H2LE_U32(pIt->cbSignature);
279
280 rc = RTVfsFileWrite(hVfsFileOut, &LstHdr, sizeof(LstHdr), NULL /*pcbWritten*/);
281 if (RT_SUCCESS(rc))
282 {
283 RTSGSEG aSegs[2];
284 RTSGBUF SgBuf;
285 EFI_SIGNATURE_DATA SigData;
286 RTEfiGuidFromUuid(&SigData.GuidOwner, &pIt->UuidOwner);
287
288 Assert(pDesc->cbSig == pIt->cbSignature);
289 aSegs[0].pvSeg = &SigData;
290 aSegs[0].cbSeg = sizeof(SigData);
291 aSegs[1].pvSeg = &pIt->abSignature[0];
292 aSegs[1].cbSeg = pIt->cbSignature;
293 RTSgBufInit(&SgBuf, &aSegs[0], RT_ELEMENTS(aSegs));
294 rc = RTVfsFileSgWrite(hVfsFileOut, -1, &SgBuf, true /*fBlocking*/, NULL /*pcbWritten*/);
295 }
296
297 if (RT_FAILURE(rc))
298 break;
299
300 cbWritten += sizeof(LstHdr) + pDesc->cbSigHdr + pIt->cbSignature;
301 }
302
303 if (RT_SUCCESS(rc))
304 *pcbThisWritten = cbWritten;
305
306 return rc;
307}
308
309
310/**
311 * Writes the given signature list to the database in the given file.
312 *
313 * @returns IPRT status code.
314 * @param pLst The list of signatures to write.
315 * @param pDesc The signature type descriptor.
316 * @param hVfsFileOut The file to write the database to.
317 * @param pcbThisWritten Where to store the number of bytes written for the given signature list.
318 */
319static int rtEfiSigDbWriteList(PRTLISTANCHOR pLst, PCRTEFISIGDBDESC pDesc, RTVFSFILE hVfsFileOut, size_t *pcbThisWritten)
320{
321 /*
322 * For signature lists where each signature can have a different size (X.509 for example)
323 * writing a new list for each signature is required which is done by a dedicated method.
324 */
325 if (!pDesc->cbSig)
326 return rtEfiSigDbWriteListSingle(pLst, pDesc, hVfsFileOut, pcbThisWritten);
327
328
329 /* Count the number of signatures first. */
330 uint32_t cSigs = 0;
331 PRTEFISIGNATURE pIt;
332
333 RTListForEach(pLst, pIt, RTEFISIGNATURE, NdLst)
334 {
335 cSigs++;
336 }
337
338 EFI_SIGNATURE_LIST LstHdr;
339 LstHdr.GuidSigType = pDesc->GuidSignatureType;
340 LstHdr.cbSigLst = RT_H2LE_U32(sizeof(LstHdr) + pDesc->cbSigHdr + cSigs * pDesc->cbSig);
341 LstHdr.cbSigHdr = RT_H2LE_U32(pDesc->cbSigHdr);
342 LstHdr.cbSig = RT_H2LE_U32(pDesc->cbSig);
343
344 int rc = RTVfsFileWrite(hVfsFileOut, &LstHdr, sizeof(LstHdr), NULL /*pcbWritten*/);
345 if (RT_SUCCESS(rc))
346 {
347 RTListForEach(pLst, pIt, RTEFISIGNATURE, NdLst)
348 {
349 RTSGSEG aSegs[2];
350 RTSGBUF SgBuf;
351 EFI_SIGNATURE_DATA SigData;
352 RTEfiGuidFromUuid(&SigData.GuidOwner, &pIt->UuidOwner);
353
354 Assert(pDesc->cbSig == pIt->cbSignature);
355 aSegs[0].pvSeg = &SigData;
356 aSegs[0].cbSeg = sizeof(SigData);
357 aSegs[1].pvSeg = &pIt->abSignature[0];
358 aSegs[1].cbSeg = pIt->cbSignature;
359 RTSgBufInit(&SgBuf, &aSegs[0], RT_ELEMENTS(aSegs));
360 rc = RTVfsFileSgWrite(hVfsFileOut, -1, &SgBuf, true /*fBlocking*/, NULL /*pcbWritten*/);
361 if (RT_FAILURE(rc))
362 break;
363 }
364 }
365
366 if (RT_SUCCESS(rc))
367 *pcbThisWritten = sizeof(LstHdr) + pDesc->cbSigHdr + cSigs * pDesc->cbSig;
368
369 return rc;
370}
371
372
373/**
374 * Allocate a new signature of the given size.
375 *
376 * @returns Pointer to the new signature or NULL if out of memory.
377 * @param pUuidOwner The UUID of the signature owner.
378 * @param cbSig Size of the signature data in bytes.
379 */
380static PRTEFISIGNATURE rtEfiSigDbAllocSignature(PCRTUUID pUuidOwner, uint32_t cbSig)
381{
382 PRTEFISIGNATURE pSig = (PRTEFISIGNATURE)RTMemAllocZ(RT_UOFFSETOF_DYN(RTEFISIGNATURE, abSignature[cbSig]));
383 if (pSig)
384 {
385 pSig->UuidOwner = *pUuidOwner;
386 pSig->cbSignature = cbSig;
387 }
388
389 return pSig;
390}
391
392
393RTDECL(int) RTEfiSigDbCreate(PRTEFISIGDB phEfiSigDb)
394{
395 AssertPtrReturn(phEfiSigDb, VERR_INVALID_POINTER);
396
397 PRTEFISIGDBINT pThis = (PRTEFISIGDBINT)RTMemAllocZ(sizeof(*pThis));
398 if (RT_LIKELY(pThis))
399 {
400 for (uint32_t i = 0; i < RT_ELEMENTS(pThis->aLstSigTypes); i++)
401 RTListInit(&pThis->aLstSigTypes[i]);
402 *phEfiSigDb = pThis;
403 return VINF_SUCCESS;
404 }
405
406 return VERR_NO_MEMORY;
407}
408
409
410RTDECL(int) RTEfiSigDbDestroy(RTEFISIGDB hEfiSigDb)
411{
412 PRTEFISIGDBINT pThis = hEfiSigDb;
413 AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
414
415 for (uint32_t i = 0; i < RT_ELEMENTS(pThis->aLstSigTypes); i++)
416 {
417 PRTEFISIGNATURE pIt, pItNext;
418
419 RTListForEachSafe(&pThis->aLstSigTypes[i], pIt, pItNext, RTEFISIGNATURE, NdLst)
420 {
421 RTListNodeRemove(&pIt->NdLst);
422 RTMemFree(pIt);
423 }
424 }
425
426 RTMemFree(pThis);
427 return VINF_SUCCESS;
428}
429
430
431RTDECL(int) RTEfiSigDbAddFromExistingDb(RTEFISIGDB hEfiSigDb, RTVFSFILE hVfsFileIn)
432{
433 PRTEFISIGDBINT pThis = hEfiSigDb;
434 AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
435
436 uint64_t cbFile;
437 int rc = RTVfsFileQuerySize(hVfsFileIn, &cbFile);
438 if (RT_SUCCESS(rc))
439 {
440 do
441 {
442 uint64_t cbConsumed = 0;
443 rc = rtEfiSigDbLoadSigList(pThis, hVfsFileIn, &cbConsumed);
444 cbFile -= cbConsumed;
445 } while ( RT_SUCCESS(rc)
446 && cbFile);
447 }
448
449 return rc;
450}
451
452
453RTDECL(int) RTEfiSigDbAddSignatureFromFile(RTEFISIGDB hEfiSigDb, RTEFISIGTYPE enmSigType, PCRTUUID pUuidOwner, RTVFSFILE hVfsFileIn)
454{
455 PRTEFISIGDBINT pThis = hEfiSigDb;
456 AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
457 AssertReturn(enmSigType >= RTEFISIGTYPE_FIRST_VALID && enmSigType < RTEFISIGTYPE_FIRST_INVALID, VERR_INVALID_PARAMETER);
458 AssertPtrReturn(pUuidOwner, VERR_INVALID_POINTER);
459
460 PCRTEFISIGDBDESC pDesc = &g_aGuid2SigTypeMapping[enmSigType];
461 uint64_t cbSig = 0;
462 int rc = RTVfsFileQuerySize(hVfsFileIn, &cbSig);
463 if (RT_SUCCESS(rc))
464 {
465 if ( ( !pDesc->cbSig
466 || pDesc->cbSig - sizeof(EFI_SIGNATURE_DATA) == cbSig)
467 && cbSig < UINT32_MAX)
468 {
469 PRTEFISIGNATURE pSig = rtEfiSigDbAllocSignature(pUuidOwner, (uint32_t)cbSig);
470 if (pSig)
471 {
472 rc = RTVfsFileRead(hVfsFileIn, &pSig->abSignature[0], (size_t)cbSig, NULL /*pcbRead*/);
473 if (RT_SUCCESS(rc))
474 RTListAppend(&pThis->aLstSigTypes[enmSigType], &pSig->NdLst);
475 else
476 RTMemFree(pSig);
477 }
478 else
479 rc = VERR_NO_MEMORY;
480 }
481 else
482 rc = VERR_INVALID_PARAMETER;
483 }
484
485 return rc;
486}
487
488
489RTDECL(int) RTEfiSigDbAddSignatureFromBuf(RTEFISIGDB hEfiSigDb, RTEFISIGTYPE enmSigType, PCRTUUID pUuidOwner,
490 const void *pvBuf, size_t cbBuf)
491{
492 PRTEFISIGDBINT pThis = hEfiSigDb;
493 AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
494 AssertReturn(enmSigType >= RTEFISIGTYPE_FIRST_VALID && enmSigType < RTEFISIGTYPE_FIRST_INVALID, VERR_INVALID_PARAMETER);
495 AssertPtrReturn(pUuidOwner, VERR_INVALID_POINTER);
496 AssertPtrReturn(pvBuf, VERR_INVALID_POINTER);
497 AssertReturn(cbBuf && cbBuf < UINT32_MAX, VERR_INVALID_PARAMETER);
498
499 int rc = VINF_SUCCESS;
500 PCRTEFISIGDBDESC pDesc = &g_aGuid2SigTypeMapping[enmSigType];
501 if ( !pDesc->cbSig
502 || pDesc->cbSig - sizeof(EFI_SIGNATURE_DATA) == cbBuf)
503 {
504 PRTEFISIGNATURE pSig = rtEfiSigDbAllocSignature(pUuidOwner, (uint32_t)cbBuf);
505 if (pSig)
506 {
507 memcpy(&pSig->abSignature[0], pvBuf, cbBuf);
508 RTListAppend(&pThis->aLstSigTypes[enmSigType], &pSig->NdLst);
509 }
510 else
511 rc = VERR_NO_MEMORY;
512 }
513 else
514 rc = VERR_INVALID_PARAMETER;
515
516 return rc;
517}
518
519
520RTDECL(int) RTEfiSigDbWriteToFile(RTEFISIGDB hEfiSigDb, RTVFSFILE hVfsFileOut)
521{
522 PRTEFISIGDBINT pThis = hEfiSigDb;
523 AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
524
525 int rc = VINF_SUCCESS;
526 size_t cbSigDb = 0;
527 for (uint32_t i = RTEFISIGTYPE_FIRST_VALID; i < RT_ELEMENTS(pThis->aLstSigTypes) && RT_SUCCESS(rc); i++)
528 {
529 if (!RTListIsEmpty(&pThis->aLstSigTypes[i]))
530 {
531 size_t cbThisWritten = 0;
532 rc = rtEfiSigDbWriteList(&pThis->aLstSigTypes[i], &g_aGuid2SigTypeMapping[i], hVfsFileOut, &cbThisWritten);
533 if (RT_SUCCESS(rc))
534 cbSigDb += cbThisWritten;
535 }
536 }
537
538 if (RT_SUCCESS(rc))
539 rc = RTVfsFileSetSize(hVfsFileOut, cbSigDb, RTVFSFILE_SIZE_F_NORMAL);
540
541 return rc;
542}
543
544
545RTDECL(int) RTEfiSigDbEnum(RTEFISIGDB hEfiSigDb, PFNRTEFISIGDBENUMSIG pfnEnumSig, void *pvUser)
546{
547 PRTEFISIGDBINT pThis = hEfiSigDb;
548 AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
549
550 for (uint32_t i = RTEFISIGTYPE_FIRST_VALID; i < RT_ELEMENTS(pThis->aLstSigTypes); i++)
551 {
552 PRTEFISIGNATURE pIt;
553
554 RTListForEach(&pThis->aLstSigTypes[i], pIt, RTEFISIGNATURE, NdLst)
555 {
556 int rc = pfnEnumSig(pThis, (RTEFISIGTYPE)i, &pIt->UuidOwner, &pIt->abSignature[0], pIt->cbSignature, pvUser);
557 if (rc != VINF_SUCCESS)
558 return rc;
559 }
560 }
561
562 return VINF_SUCCESS;
563}
564
565
566RTDECL(const char *) RTEfiSigDbTypeStringify(RTEFISIGTYPE enmSigType)
567{
568 AssertReturn(enmSigType < RTEFISIGTYPE_FIRST_INVALID, NULL);
569 return g_aGuid2SigTypeMapping[enmSigType].pszName;
570}
571
572
573RTDECL(PCEFI_GUID) RTEfiSigDbTypeGetGuid(RTEFISIGTYPE enmSigType)
574{
575 AssertReturn(enmSigType < RTEFISIGTYPE_FIRST_INVALID, NULL);
576 return &g_aGuid2SigTypeMapping[enmSigType].GuidSignatureType;
577}
578
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette