iPXE
Functions
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. More...
 
int efisig_asn1 (const void *data, size_t len, size_t offset, struct asn1_cursor **cursor)
 Extract ASN.1 object from EFI signature list. More...
 
static int efisig_image_probe (struct image *image)
 Probe EFI signature list image. More...
 
static int efisig_image_asn1 (struct image *image, size_t offset, struct asn1_cursor **cursor)
 Extract ASN.1 object from EFI signature list image. More...
 
struct image_type efisig_image_type __image_type (PROBE_NORMAL)
 EFI signature list image type. More...
 

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()

static 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 < (*lhdr)->SignatureListSize ) {
78  DBGC ( data, "EFISIG [%#zx,%#zx) truncated list at "
79  "+%#zx\n", *start, len, offset );
80  return -EINVAL;
81  }
82  remaining = (*lhdr)->SignatureListSize;
83 
84  /* Get length of each signature in list */
85  dlen = (*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  (*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 ) + (*lhdr)->SignatureHeaderSize );
101  offset += skip;
102  remaining -= skip;
103 
104  /* Read signatures */
105  for ( ; remaining ; offset += dlen, remaining -= dlen ) {
106 
107  /* Check length */
108  if ( remaining < dlen ) {
109  DBGC ( data, "EFISIG [%#zx,%#zx) truncated "
110  "at +%#zx\n", *start, len, offset );
111  return -EINVAL;
112  }
113 
114  /* Continue until we find the requested signature */
115  if ( offset < *start )
116  continue;
117 
118  /* Read data header */
119  *dhdr = ( data + offset );
120  DBGC2 ( data, "EFISIG [%#zx,%#zx) %s ",
121  offset, ( offset + dlen ),
122  efi_guid_ntoa ( &(*lhdr)->SignatureType ) );
123  DBGC2 ( data, "owner %s\n",
124  efi_guid_ntoa ( &(*dhdr)->SignatureOwner ) );
125  *start = offset;
126  return 0;
127  }
128  }
129 }
#define EINVAL
Invalid argument.
Definition: errno.h:429
#define DBGC(...)
Definition: compiler.h:505
uint32_t start
Starting offset.
Definition: netvsc.h:12
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
ring len
Length.
Definition: dwmac.h:231
const char * efi_guid_ntoa(CONST EFI_GUID *guid)
Convert GUID to a printable string.
Definition: efi_guid.c:726
#define DBGC2(...)
Definition: compiler.h:522
uint8_t data[48]
Additional event data.
Definition: ena.h:22
uint16_t offset
Offset to command line.
Definition: bzimage.h:8

References assert(), data, DBGC, DBGC2, efi_guid_ntoa(), EINVAL, 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 143 of file efi_siglist.c.

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

References image_type::asn1, ASN1_SEQUENCE, data, DBGC, DBGC2, der_asn1(), efisig_find(), EINVAL, free, 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()

static 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 194 of file efi_siglist.c.

194  {
195  const EFI_SIGNATURE_LIST *lhdr;
196  const EFI_SIGNATURE_DATA *dhdr;
197  size_t offset = 0;
198  unsigned int count = 0;
199  int rc;
200 
201  /* Check file is a well-formed signature list */
202  while ( 1 ) {
203 
204  /* Find next signature list entry */
205  if ( ( rc = efisig_find ( image->data, image->len, &offset,
206  &lhdr, &dhdr ) ) != 0 ) {
207  return rc;
208  }
209 
210  /* Skip this entry */
211  offset += lhdr->SignatureSize;
212  count++;
213 
214  /* Check if we have reached end of the image */
215  if ( offset == image->len ) {
216  DBGC ( image, "EFISIG %s contains %d signatures\n",
217  image->name, count );
218  return 0;
219  }
220  }
221 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
UINT32 SignatureSize
Size of each signature.
const void * data
Read-only data.
Definition: image.h:51
#define DBGC(...)
Definition: compiler.h:505
An executable image.
Definition: image.h:24
static unsigned int count
Number of entries.
Definition: dwmac.h:225
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
size_t len
Length of raw file image.
Definition: image.h:56
The format of a signature database.
uint16_t offset
Offset to command line.
Definition: bzimage.h:8
char * name
Name.
Definition: image.h:38

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

◆ efisig_image_asn1()

static 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 234 of file efi_siglist.c.

235  {
236  int next;
237  int rc;
238 
239  /* Extract ASN.1 object */
240  if ( ( next = efisig_asn1 ( image->data, image->len, offset,
241  cursor ) ) < 0 ) {
242  rc = next;
243  DBGC ( image, "EFISIG %s could not extract ASN.1: %s\n",
244  image->name, strerror ( rc ) );
245  return rc;
246  }
247 
248  return next;
249 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
const void * data
Read-only data.
Definition: image.h:51
#define DBGC(...)
Definition: compiler.h:505
An executable image.
Definition: image.h:24
int efisig_asn1(const void *data, size_t len, size_t offset, struct asn1_cursor **cursor)
Extract ASN.1 object from EFI signature list.
Definition: efi_siglist.c:143
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:79
size_t len
Length of raw file image.
Definition: image.h:56
uint32_t next
Next descriptor address.
Definition: dwmac.h:22
uint16_t offset
Offset to command line.
Definition: bzimage.h:8
char * name
Name.
Definition: image.h:38

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

◆ __image_type()

struct image_type efisig_image_type __image_type ( PROBE_NORMAL  )

EFI signature list image type.