VirtualBox

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

Last change on this file since 104626 was 98103, checked in by vboxsync, 23 months ago

Copyright year updates by scm.

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