iPXE
efi_siglist.c File Reference

EFI signature lists. More...

#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <ipxe/asn1.h>
#include <ipxe/der.h>
#include <ipxe/pem.h>
#include <ipxe/image.h>
#include <ipxe/efi/efi.h>
#include <ipxe/efi/Guid/ImageAuthentication.h>
#include <ipxe/efi/efi_siglist.h>

Go to the source code of this file.

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
 FILE_SECBOOT (PERMITTED)
static int efisig_find (const void *data, size_t len, size_t *start, const EFI_SIGNATURE_LIST **lhdr, const EFI_SIGNATURE_DATA **dhdr)
 Find EFI signature list entry.
int efisig_asn1 (const void *data, size_t len, size_t offset, struct asn1_cursor **cursor)
 Extract ASN.1 object from EFI signature list.
static int efisig_image_probe (struct image *image)
 Probe EFI signature list image.
static int efisig_image_asn1 (struct image *image, size_t offset, struct asn1_cursor **cursor)
 Extract ASN.1 object from EFI signature list image.
struct image_type efisig_image_type __image_type (PROBE_NORMAL)
 EFI signature list image type.

Detailed Description

EFI signature lists.

Definition in file efi_siglist.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )

◆ FILE_SECBOOT()

FILE_SECBOOT ( PERMITTED )

◆ efisig_find()

int efisig_find ( const void * data,
size_t len,
size_t * start,
const EFI_SIGNATURE_LIST ** lhdr,
const EFI_SIGNATURE_DATA ** dhdr )
static

Find EFI signature list entry.

Parameters
dataEFI signature list
lenLength of EFI signature list
startStarting offset to update
lhdrSignature list header to fill in
dhdrSignature data header to fill in
Return values
rcReturn status code

Definition at line 54 of file efi_siglist.c.

56 {
57 size_t offset;
58 size_t remaining;
59 size_t skip;
60 size_t dlen;
61
62 /* Scan through signature list */
63 offset = 0;
64 while ( 1 ) {
65
66 /* Read list header */
67 assert ( offset <= len );
68 remaining = ( len - offset );
69 if ( remaining < sizeof ( **lhdr ) ) {
70 DBGC ( data, "EFISIG [%#zx,%#zx) truncated header "
71 "at +%#zx\n", *start, len, offset );
72 return -EINVAL;
73 }
74 *lhdr = ( data + offset );
75
76 /* Get length of this signature list */
77 if ( remaining < le32_to_cpu ( (*lhdr)->SignatureListSize ) ) {
78 DBGC ( data, "EFISIG [%#zx,%#zx) truncated list at "
79 "+%#zx\n", *start, len, offset );
80 return -EINVAL;
81 }
82 remaining = le32_to_cpu ( (*lhdr)->SignatureListSize );
83
84 /* Get length of each signature in list */
85 dlen = le32_to_cpu ( (*lhdr)->SignatureSize );
86 if ( dlen < sizeof ( **dhdr ) ) {
87 DBGC ( data, "EFISIG [%#zx,%#zx) underlength "
88 "signatures at +%#zx\n", *start, len, offset );
89 return -EINVAL;
90 }
91
92 /* Strip list header (including variable portion) */
93 if ( ( remaining < sizeof ( **lhdr ) ) ||
94 ( ( remaining - sizeof ( **lhdr ) ) <
95 le32_to_cpu ( (*lhdr)->SignatureHeaderSize ) ) ) {
96 DBGC ( data, "EFISIG [%#zx,%#zx) malformed header at "
97 "+%#zx\n", *start, len, offset );
98 return -EINVAL;
99 }
100 skip = ( sizeof ( **lhdr ) +
101 le32_to_cpu ( (*lhdr)->SignatureHeaderSize ) );
102 offset += skip;
103 remaining -= skip;
104
105 /* Read signatures */
106 for ( ; remaining ; offset += dlen, remaining -= dlen ) {
107
108 /* Check length */
109 if ( remaining < dlen ) {
110 DBGC ( data, "EFISIG [%#zx,%#zx) truncated "
111 "at +%#zx\n", *start, len, offset );
112 return -EINVAL;
113 }
114
115 /* Continue until we find the requested signature */
116 if ( offset < *start )
117 continue;
118
119 /* Read data header */
120 *dhdr = ( data + offset );
121 DBGC2 ( data, "EFISIG [%#zx,%#zx) %s ",
122 offset, ( offset + dlen ),
123 efi_guid_ntoa ( &(*lhdr)->SignatureType ) );
124 DBGC2 ( data, "owner %s\n",
125 efi_guid_ntoa ( &(*dhdr)->SignatureOwner ) );
126 *start = offset;
127 return 0;
128 }
129 }
130}
#define assert(condition)
Assert a condition at run-time.
Definition assert.h:61
uint16_t offset
Offset to command line.
Definition bzimage.h:3
ring len
Length.
Definition dwmac.h:226
const char * efi_guid_ntoa(CONST EFI_GUID *guid)
Convert GUID to a printable string.
Definition efi_guid.c:733
uint8_t data[48]
Additional event data.
Definition ena.h:11
#define DBGC2(...)
Definition compiler.h:547
#define DBGC(...)
Definition compiler.h:530
uint32_t start
Starting offset.
Definition netvsc.h:1
#define EINVAL
Invalid argument.
Definition errno.h:472
#define le32_to_cpu(value)
Definition byteswap.h:114

References assert, data, DBGC, DBGC2, efi_guid_ntoa(), EINVAL, le32_to_cpu, len, offset, and start.

Referenced by efisig_asn1(), and efisig_image_probe().

◆ efisig_asn1()

int efisig_asn1 ( const void * data,
size_t len,
size_t offset,
struct asn1_cursor ** cursor )

Extract ASN.1 object from EFI signature list.

Parameters
dataEFI signature list
lenLength of EFI signature list
offsetOffset within image
cursorASN.1 cursor to fill in
Return values
nextOffset to next image, or negative error

The caller is responsible for eventually calling free() on the allocated ASN.1 cursor.

Definition at line 144 of file efi_siglist.c.

145 {
146 const EFI_SIGNATURE_LIST *lhdr;
147 const EFI_SIGNATURE_DATA *dhdr;
148 int ( * asn1 ) ( const void *data, size_t len, size_t offset,
149 struct asn1_cursor **cursor );
150 size_t skip = offsetof ( typeof ( *dhdr ), SignatureData );
151 int next;
152 int rc;
153
154 /* Locate signature list entry */
155 if ( ( rc = efisig_find ( data, len, &offset, &lhdr, &dhdr ) ) != 0 )
156 goto err_entry;
157 len = ( offset + le32_to_cpu ( lhdr->SignatureSize ) );
158
159 /* Parse as PEM or DER based on first character */
160 asn1 = ( ( dhdr->SignatureData[0] == ASN1_SEQUENCE ) ?
161 der_asn1 : pem_asn1 );
162 DBGC2 ( data, "EFISIG [%#zx,%#zx) extracting %s\n", offset, len,
163 ( ( asn1 == der_asn1 ) ? "DER" : "PEM" ) );
164 next = asn1 ( data, len, ( offset + skip ), cursor );
165 if ( next < 0 ) {
166 rc = next;
167 DBGC ( data, "EFISIG [%#zx,%#zx) could not extract ASN.1: "
168 "%s\n", offset, len, strerror ( rc ) );
169 goto err_asn1;
170 }
171
172 /* Check that whole entry was consumed */
173 if ( ( ( unsigned int ) next ) != len ) {
174 DBGC ( data, "EFISIG [%#zx,%#zx) malformed data\n",
175 offset, len );
176 rc = -EINVAL;
177 goto err_whole;
178 }
179
180 return len;
181
182 err_whole:
183 free ( *cursor );
184 err_asn1:
185 err_entry:
186 return rc;
187}
typeof(acpi_finder=acpi_find)
ACPI table finder.
Definition acpi.c:48
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
#define ASN1_SEQUENCE
ASN.1 sequence.
Definition asn1.h:90
int der_asn1(const void *data, size_t len, size_t offset, struct asn1_cursor **cursor)
Extract ASN.1 object from DER data.
Definition der.c:53
uint32_t next
Next descriptor address.
Definition dwmac.h:11
static int efisig_find(const void *data, size_t len, size_t *start, const EFI_SIGNATURE_LIST **lhdr, const EFI_SIGNATURE_DATA **dhdr)
Find EFI signature list entry.
Definition efi_siglist.c:54
int pem_asn1(const void *data, size_t len, size_t offset, struct asn1_cursor **cursor)
Extract ASN.1 object from PEM data.
Definition pem.c:104
static void(* free)(struct refcnt *refcnt))
Definition refcnt.h:55
#define offsetof(type, field)
Get offset of a field within a structure.
Definition stddef.h:25
char * strerror(int errno)
Retrieve string representation of error number.
Definition strerror.c:79
The format of a signature database.
UINT8 SignatureData[1]
The format of the signature is defined by the SignatureType.
UINT32 SignatureSize
Size of each signature.
An ASN.1 object cursor.
Definition asn1.h:21

References ASN1_SEQUENCE, data, DBGC, DBGC2, der_asn1(), efisig_find(), EINVAL, free, le32_to_cpu, len, next, offset, offsetof, pem_asn1(), rc, EFI_SIGNATURE_DATA::SignatureData, EFI_SIGNATURE_LIST::SignatureSize, strerror(), and typeof().

Referenced by efi_cacert(), and efisig_image_asn1().

◆ efisig_image_probe()

int efisig_image_probe ( struct image * image)
static

Probe EFI signature list image.

Parameters
imageEFI signature list
Return values
rcReturn status code

Definition at line 195 of file efi_siglist.c.

195 {
196 const EFI_SIGNATURE_LIST *lhdr;
197 const EFI_SIGNATURE_DATA *dhdr;
198 size_t offset = 0;
199 unsigned int count = 0;
200 int rc;
201
202 /* Check file is a well-formed signature list */
203 while ( 1 ) {
204
205 /* Find next signature list entry */
206 if ( ( rc = efisig_find ( image->data, image->len, &offset,
207 &lhdr, &dhdr ) ) != 0 ) {
208 return rc;
209 }
210
211 /* Skip this entry */
212 offset += le32_to_cpu ( lhdr->SignatureSize );
213 count++;
214
215 /* Check if we have reached end of the image */
216 if ( offset == image->len ) {
217 DBGC ( image, "EFISIG %s contains %d signatures\n",
218 image->name, count );
219 return 0;
220 }
221 }
222}
static unsigned int count
Number of entries.
Definition dwmac.h:220
An executable image.
Definition image.h:24
const void * data
Read-only data.
Definition image.h:51
char * name
Name.
Definition image.h:38
size_t len
Length of raw file image.
Definition image.h:63

References count, image::data, DBGC, efisig_find(), le32_to_cpu, image::len, image::name, offset, rc, and EFI_SIGNATURE_LIST::SignatureSize.

Referenced by __image_type().

◆ efisig_image_asn1()

int efisig_image_asn1 ( struct image * image,
size_t offset,
struct asn1_cursor ** cursor )
static

Extract ASN.1 object from EFI signature list image.

Parameters
imageEFI signature list
offsetOffset within image
cursorASN.1 cursor to fill in
Return values
nextOffset to next image, or negative error

The caller is responsible for eventually calling free() on the allocated ASN.1 cursor.

Definition at line 235 of file efi_siglist.c.

236 {
237 int next;
238 int rc;
239
240 /* Extract ASN.1 object */
241 if ( ( next = efisig_asn1 ( image->data, image->len, offset,
242 cursor ) ) < 0 ) {
243 rc = next;
244 DBGC ( image, "EFISIG %s could not extract ASN.1: %s\n",
245 image->name, strerror ( rc ) );
246 return rc;
247 }
248
249 return next;
250}
int efisig_asn1(const void *data, size_t len, size_t offset, struct asn1_cursor **cursor)
Extract ASN.1 object from EFI signature list.

References image::data, DBGC, efisig_asn1(), image::len, image::name, next, offset, rc, and strerror().

Referenced by __image_type().

◆ __image_type()

struct image_type efisig_image_type __image_type ( PROBE_NORMAL )

EFI signature list image type.

References __image_type, efisig_image_asn1(), efisig_image_probe(), and PROBE_NORMAL.