VirtualBox

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

Last change on this file since 91681 was 91431, checked in by vboxsync, 3 years ago

Runtime/efisignaturedb.cpp: Don't fail if the the signature list to load from is empty, bugref:9580

  • 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 91431 2021-09-28 11:36:29Z 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 EFI_SIGNATURE_DATA SigData;
276 LstHdr.GuidSigType = pDesc->GuidSignatureType;
277 LstHdr.cbSigLst = RT_H2LE_U32(sizeof(LstHdr) + sizeof(SigData) + pDesc->cbSigHdr + pIt->cbSignature);
278 LstHdr.cbSigHdr = RT_H2LE_U32(pDesc->cbSigHdr);
279 LstHdr.cbSig = RT_H2LE_U32(pIt->cbSignature + sizeof(SigData));
280 RTEfiGuidFromUuid(&SigData.GuidOwner, &pIt->UuidOwner);
281
282 RTSGSEG aSegs[3];
283 RTSGBUF SgBuf;
284
285 Assert(!pDesc->cbSigHdr);
286 aSegs[0].pvSeg = &LstHdr;
287 aSegs[0].cbSeg = sizeof(LstHdr);
288 aSegs[1].pvSeg = &SigData;
289 aSegs[1].cbSeg = sizeof(SigData);
290 aSegs[2].pvSeg = &pIt->abSignature[0];
291 aSegs[2].cbSeg = pIt->cbSignature;
292 RTSgBufInit(&SgBuf, &aSegs[0], RT_ELEMENTS(aSegs));
293 rc = RTVfsFileSgWrite(hVfsFileOut, -1, &SgBuf, true /*fBlocking*/, NULL /*pcbWritten*/);
294 if (RT_FAILURE(rc))
295 break;
296
297 cbWritten += sizeof(LstHdr) + sizeof(SigData) + pDesc->cbSigHdr + pIt->cbSignature;
298 }
299
300 if (RT_SUCCESS(rc))
301 *pcbThisWritten = cbWritten;
302
303 return rc;
304}
305
306
307/**
308 * Writes the given signature list to the database in the given file.
309 *
310 * @returns IPRT status code.
311 * @param pLst The list of signatures to write.
312 * @param pDesc The signature type descriptor.
313 * @param hVfsFileOut The file to write the database to.
314 * @param pcbThisWritten Where to store the number of bytes written for the given signature list.
315 */
316static int rtEfiSigDbWriteList(PRTLISTANCHOR pLst, PCRTEFISIGDBDESC pDesc, RTVFSFILE hVfsFileOut, size_t *pcbThisWritten)
317{
318 /*
319 * For signature lists where each signature can have a different size (X.509 for example)
320 * writing a new list for each signature is required which is done by a dedicated method.
321 */
322 if (!pDesc->cbSig)
323 return rtEfiSigDbWriteListSingle(pLst, pDesc, hVfsFileOut, pcbThisWritten);
324
325
326 /* Count the number of signatures first. */
327 uint32_t cSigs = 0;
328 PRTEFISIGNATURE pIt;
329
330 RTListForEach(pLst, pIt, RTEFISIGNATURE, NdLst)
331 {
332 cSigs++;
333 }
334
335 EFI_SIGNATURE_LIST LstHdr;
336 LstHdr.GuidSigType = pDesc->GuidSignatureType;
337 LstHdr.cbSigLst = RT_H2LE_U32(sizeof(LstHdr) + pDesc->cbSigHdr + cSigs * pDesc->cbSig);
338 LstHdr.cbSigHdr = RT_H2LE_U32(pDesc->cbSigHdr);
339 LstHdr.cbSig = RT_H2LE_U32(pDesc->cbSig);
340
341 int rc = RTVfsFileWrite(hVfsFileOut, &LstHdr, sizeof(LstHdr), NULL /*pcbWritten*/);
342 if (RT_SUCCESS(rc))
343 {
344 RTListForEach(pLst, pIt, RTEFISIGNATURE, NdLst)
345 {
346 RTSGSEG aSegs[2];
347 RTSGBUF SgBuf;
348 EFI_SIGNATURE_DATA SigData;
349 RTEfiGuidFromUuid(&SigData.GuidOwner, &pIt->UuidOwner);
350
351 Assert(pDesc->cbSig == pIt->cbSignature);
352 aSegs[0].pvSeg = &SigData;
353 aSegs[0].cbSeg = sizeof(SigData);
354 aSegs[1].pvSeg = &pIt->abSignature[0];
355 aSegs[1].cbSeg = pIt->cbSignature;
356 RTSgBufInit(&SgBuf, &aSegs[0], RT_ELEMENTS(aSegs));
357 rc = RTVfsFileSgWrite(hVfsFileOut, -1, &SgBuf, true /*fBlocking*/, NULL /*pcbWritten*/);
358 if (RT_FAILURE(rc))
359 break;
360 }
361 }
362
363 if (RT_SUCCESS(rc))
364 *pcbThisWritten = sizeof(LstHdr) + pDesc->cbSigHdr + cSigs * pDesc->cbSig;
365
366 return rc;
367}
368
369
370/**
371 * Allocate a new signature of the given size.
372 *
373 * @returns Pointer to the new signature or NULL if out of memory.
374 * @param pUuidOwner The UUID of the signature owner.
375 * @param cbSig Size of the signature data in bytes.
376 */
377static PRTEFISIGNATURE rtEfiSigDbAllocSignature(PCRTUUID pUuidOwner, uint32_t cbSig)
378{
379 PRTEFISIGNATURE pSig = (PRTEFISIGNATURE)RTMemAllocZ(RT_UOFFSETOF_DYN(RTEFISIGNATURE, abSignature[cbSig]));
380 if (pSig)
381 {
382 pSig->UuidOwner = *pUuidOwner;
383 pSig->cbSignature = cbSig;
384 }
385
386 return pSig;
387}
388
389
390RTDECL(int) RTEfiSigDbCreate(PRTEFISIGDB phEfiSigDb)
391{
392 AssertPtrReturn(phEfiSigDb, VERR_INVALID_POINTER);
393
394 PRTEFISIGDBINT pThis = (PRTEFISIGDBINT)RTMemAllocZ(sizeof(*pThis));
395 if (RT_LIKELY(pThis))
396 {
397 for (uint32_t i = 0; i < RT_ELEMENTS(pThis->aLstSigTypes); i++)
398 RTListInit(&pThis->aLstSigTypes[i]);
399 *phEfiSigDb = pThis;
400 return VINF_SUCCESS;
401 }
402
403 return VERR_NO_MEMORY;
404}
405
406
407RTDECL(int) RTEfiSigDbDestroy(RTEFISIGDB hEfiSigDb)
408{
409 PRTEFISIGDBINT pThis = hEfiSigDb;
410 AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
411
412 for (uint32_t i = 0; i < RT_ELEMENTS(pThis->aLstSigTypes); i++)
413 {
414 PRTEFISIGNATURE pIt, pItNext;
415
416 RTListForEachSafe(&pThis->aLstSigTypes[i], pIt, pItNext, RTEFISIGNATURE, NdLst)
417 {
418 RTListNodeRemove(&pIt->NdLst);
419 RTMemFree(pIt);
420 }
421 }
422
423 RTMemFree(pThis);
424 return VINF_SUCCESS;
425}
426
427
428RTDECL(int) RTEfiSigDbAddFromExistingDb(RTEFISIGDB hEfiSigDb, RTVFSFILE hVfsFileIn)
429{
430 PRTEFISIGDBINT pThis = hEfiSigDb;
431 AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
432
433 uint64_t cbFile;
434 int rc = RTVfsFileQuerySize(hVfsFileIn, &cbFile);
435 if ( RT_SUCCESS(rc)
436 && cbFile)
437 {
438 do
439 {
440 uint64_t cbConsumed = 0;
441 rc = rtEfiSigDbLoadSigList(pThis, hVfsFileIn, &cbConsumed);
442 cbFile -= cbConsumed;
443 } while ( RT_SUCCESS(rc)
444 && cbFile);
445 }
446
447 return rc;
448}
449
450
451RTDECL(int) RTEfiSigDbAddSignatureFromFile(RTEFISIGDB hEfiSigDb, RTEFISIGTYPE enmSigType, PCRTUUID pUuidOwner, RTVFSFILE hVfsFileIn)
452{
453 PRTEFISIGDBINT pThis = hEfiSigDb;
454 AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
455 AssertReturn(enmSigType >= RTEFISIGTYPE_FIRST_VALID && enmSigType < RTEFISIGTYPE_FIRST_INVALID, VERR_INVALID_PARAMETER);
456 AssertPtrReturn(pUuidOwner, VERR_INVALID_POINTER);
457
458 PCRTEFISIGDBDESC pDesc = &g_aGuid2SigTypeMapping[enmSigType];
459 uint64_t cbSig = 0;
460 int rc = RTVfsFileQuerySize(hVfsFileIn, &cbSig);
461 if (RT_SUCCESS(rc))
462 {
463 if ( ( !pDesc->cbSig
464 || pDesc->cbSig - sizeof(EFI_SIGNATURE_DATA) == cbSig)
465 && cbSig < UINT32_MAX)
466 {
467 PRTEFISIGNATURE pSig = rtEfiSigDbAllocSignature(pUuidOwner, (uint32_t)cbSig);
468 if (pSig)
469 {
470 rc = RTVfsFileRead(hVfsFileIn, &pSig->abSignature[0], (size_t)cbSig, NULL /*pcbRead*/);
471 if (RT_SUCCESS(rc))
472 RTListAppend(&pThis->aLstSigTypes[enmSigType], &pSig->NdLst);
473 else
474 RTMemFree(pSig);
475 }
476 else
477 rc = VERR_NO_MEMORY;
478 }
479 else
480 rc = VERR_INVALID_PARAMETER;
481 }
482
483 return rc;
484}
485
486
487RTDECL(int) RTEfiSigDbAddSignatureFromBuf(RTEFISIGDB hEfiSigDb, RTEFISIGTYPE enmSigType, PCRTUUID pUuidOwner,
488 const void *pvBuf, size_t cbBuf)
489{
490 PRTEFISIGDBINT pThis = hEfiSigDb;
491 AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
492 AssertReturn(enmSigType >= RTEFISIGTYPE_FIRST_VALID && enmSigType < RTEFISIGTYPE_FIRST_INVALID, VERR_INVALID_PARAMETER);
493 AssertPtrReturn(pUuidOwner, VERR_INVALID_POINTER);
494 AssertPtrReturn(pvBuf, VERR_INVALID_POINTER);
495 AssertReturn(cbBuf && cbBuf < UINT32_MAX, VERR_INVALID_PARAMETER);
496
497 int rc = VINF_SUCCESS;
498 PCRTEFISIGDBDESC pDesc = &g_aGuid2SigTypeMapping[enmSigType];
499 if ( !pDesc->cbSig
500 || pDesc->cbSig - sizeof(EFI_SIGNATURE_DATA) == cbBuf)
501 {
502 PRTEFISIGNATURE pSig = rtEfiSigDbAllocSignature(pUuidOwner, (uint32_t)cbBuf);
503 if (pSig)
504 {
505 memcpy(&pSig->abSignature[0], pvBuf, cbBuf);
506 RTListAppend(&pThis->aLstSigTypes[enmSigType], &pSig->NdLst);
507 }
508 else
509 rc = VERR_NO_MEMORY;
510 }
511 else
512 rc = VERR_INVALID_PARAMETER;
513
514 return rc;
515}
516
517
518RTDECL(int) RTEfiSigDbWriteToFile(RTEFISIGDB hEfiSigDb, RTVFSFILE hVfsFileOut)
519{
520 PRTEFISIGDBINT pThis = hEfiSigDb;
521 AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
522
523 int rc = VINF_SUCCESS;
524 size_t cbSigDb = 0;
525 for (uint32_t i = RTEFISIGTYPE_FIRST_VALID; i < RT_ELEMENTS(pThis->aLstSigTypes) && RT_SUCCESS(rc); i++)
526 {
527 if (!RTListIsEmpty(&pThis->aLstSigTypes[i]))
528 {
529 size_t cbThisWritten = 0;
530 rc = rtEfiSigDbWriteList(&pThis->aLstSigTypes[i], &g_aGuid2SigTypeMapping[i], hVfsFileOut, &cbThisWritten);
531 if (RT_SUCCESS(rc))
532 cbSigDb += cbThisWritten;
533 }
534 }
535
536 if (RT_SUCCESS(rc))
537 rc = RTVfsFileSetSize(hVfsFileOut, cbSigDb, RTVFSFILE_SIZE_F_NORMAL);
538
539 return rc;
540}
541
542
543RTDECL(int) RTEfiSigDbEnum(RTEFISIGDB hEfiSigDb, PFNRTEFISIGDBENUMSIG pfnEnumSig, void *pvUser)
544{
545 PRTEFISIGDBINT pThis = hEfiSigDb;
546 AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
547
548 for (uint32_t i = RTEFISIGTYPE_FIRST_VALID; i < RT_ELEMENTS(pThis->aLstSigTypes); i++)
549 {
550 PRTEFISIGNATURE pIt;
551
552 RTListForEach(&pThis->aLstSigTypes[i], pIt, RTEFISIGNATURE, NdLst)
553 {
554 int rc = pfnEnumSig(pThis, (RTEFISIGTYPE)i, &pIt->UuidOwner, &pIt->abSignature[0], pIt->cbSignature, pvUser);
555 if (rc != VINF_SUCCESS)
556 return rc;
557 }
558 }
559
560 return VINF_SUCCESS;
561}
562
563
564RTDECL(const char *) RTEfiSigDbTypeStringify(RTEFISIGTYPE enmSigType)
565{
566 AssertReturn(enmSigType < RTEFISIGTYPE_FIRST_INVALID, NULL);
567 return g_aGuid2SigTypeMapping[enmSigType].pszName;
568}
569
570
571RTDECL(PCEFI_GUID) RTEfiSigDbTypeGetGuid(RTEFISIGTYPE enmSigType)
572{
573 AssertReturn(enmSigType < RTEFISIGTYPE_FIRST_INVALID, NULL);
574 return &g_aGuid2SigTypeMapping[enmSigType].GuidSignatureType;
575}
576
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