VirtualBox

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

Last change on this file since 93283 was 93282, checked in by vboxsync, 3 years ago

Runtime/efi: The endiannes conversion macros in cdefs.h need also asm.h (for big endian architectures).

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