[efi] Fix parsing of EFI signature lists on big-endian targets

Though UEFI is fundamentally little-endian, the EFI signature list
image format is available even on non-EFI platforms (and is covered by
the unit test suite).

Add le32_to_cpu() macros as needed to allow EFI signature lists to be
parsed correctly on big-endian targets.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
This commit is contained in:
Michael Brown
2026-06-13 16:07:41 +01:00
parent 6476f7c7c5
commit e6e9ae9804
+8 -7
View File
@@ -74,15 +74,15 @@ static int efisig_find ( const void *data, size_t len, size_t *start,
*lhdr = ( data + offset ); *lhdr = ( data + offset );
/* Get length of this signature list */ /* Get length of this signature list */
if ( remaining < (*lhdr)->SignatureListSize ) { if ( remaining < le32_to_cpu ( (*lhdr)->SignatureListSize ) ) {
DBGC ( data, "EFISIG [%#zx,%#zx) truncated list at " DBGC ( data, "EFISIG [%#zx,%#zx) truncated list at "
"+%#zx\n", *start, len, offset ); "+%#zx\n", *start, len, offset );
return -EINVAL; return -EINVAL;
} }
remaining = (*lhdr)->SignatureListSize; remaining = le32_to_cpu ( (*lhdr)->SignatureListSize );
/* Get length of each signature in list */ /* Get length of each signature in list */
dlen = (*lhdr)->SignatureSize; dlen = le32_to_cpu ( (*lhdr)->SignatureSize );
if ( dlen < sizeof ( **dhdr ) ) { if ( dlen < sizeof ( **dhdr ) ) {
DBGC ( data, "EFISIG [%#zx,%#zx) underlength " DBGC ( data, "EFISIG [%#zx,%#zx) underlength "
"signatures at +%#zx\n", *start, len, offset ); "signatures at +%#zx\n", *start, len, offset );
@@ -92,12 +92,13 @@ static int efisig_find ( const void *data, size_t len, size_t *start,
/* Strip list header (including variable portion) */ /* Strip list header (including variable portion) */
if ( ( remaining < sizeof ( **lhdr ) ) || if ( ( remaining < sizeof ( **lhdr ) ) ||
( ( remaining - sizeof ( **lhdr ) ) < ( ( remaining - sizeof ( **lhdr ) ) <
(*lhdr)->SignatureHeaderSize ) ) { le32_to_cpu ( (*lhdr)->SignatureHeaderSize ) ) ) {
DBGC ( data, "EFISIG [%#zx,%#zx) malformed header at " DBGC ( data, "EFISIG [%#zx,%#zx) malformed header at "
"+%#zx\n", *start, len, offset ); "+%#zx\n", *start, len, offset );
return -EINVAL; return -EINVAL;
} }
skip = ( sizeof ( **lhdr ) + (*lhdr)->SignatureHeaderSize ); skip = ( sizeof ( **lhdr ) +
le32_to_cpu ( (*lhdr)->SignatureHeaderSize ) );
offset += skip; offset += skip;
remaining -= skip; remaining -= skip;
@@ -153,7 +154,7 @@ int efisig_asn1 ( const void *data, size_t len, size_t offset,
/* Locate signature list entry */ /* Locate signature list entry */
if ( ( rc = efisig_find ( data, len, &offset, &lhdr, &dhdr ) ) != 0 ) if ( ( rc = efisig_find ( data, len, &offset, &lhdr, &dhdr ) ) != 0 )
goto err_entry; goto err_entry;
len = ( offset + lhdr->SignatureSize ); len = ( offset + le32_to_cpu ( lhdr->SignatureSize ) );
/* Parse as PEM or DER based on first character */ /* Parse as PEM or DER based on first character */
asn1 = ( ( dhdr->SignatureData[0] == ASN1_SEQUENCE ) ? asn1 = ( ( dhdr->SignatureData[0] == ASN1_SEQUENCE ) ?
@@ -208,7 +209,7 @@ static int efisig_image_probe ( struct image *image ) {
} }
/* Skip this entry */ /* Skip this entry */
offset += lhdr->SignatureSize; offset += le32_to_cpu ( lhdr->SignatureSize );
count++; count++;
/* Check if we have reached end of the image */ /* Check if we have reached end of the image */