]> git.ipfire.org Git - thirdparty/ipxe.git/log
thirdparty/ipxe.git
3 months ago[uaccess] Remove redundant userptr_add() and userptr_diff()
Michael Brown [Sun, 20 Apr 2025 17:45:55 +0000 (18:45 +0100)] 
[uaccess] Remove redundant userptr_add() and userptr_diff()

The userptr_add() and userptr_diff() functions are now just
straightforward wrappers around addition and subtraction.

Remove these redundant wrappers.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
3 months ago[uaccess] Change userptr_t to be a pointer type
Michael Brown [Sun, 20 Apr 2025 16:26:48 +0000 (17:26 +0100)] 
[uaccess] Change userptr_t to be a pointer type

The original motivation for the userptr_t type was to be able to
support a pure 16-bit real-mode memory model in which a segment:offset
value could be encoded as an unsigned long, with corresponding
copy_from_user() and copy_to_user() functions used to perform
real-mode segmented memory accesses.

Since this memory model was first created almost twenty years ago, no
serious effort has been made to support a pure 16-bit mode of
operation for iPXE.  The constraints imposed by the memory model are
becoming increasingly cumbersome to work within: for example, the
parsing of devicetree structures is hugely simplified by being able to
use and return direct pointers to the names and property values.  The
devicetree code therefore relies upon virt_to_user(), which is
nominally illegal under the userptr_t memory model.

Drop support for the concept of a memory location that cannot be
reached through a straightforward pointer dereference, by redefining
userptr_t to be a simple pointer type.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
3 months ago[uaccess] Add explicit casts to and from userptr_t where needed
Michael Brown [Sun, 20 Apr 2025 12:39:32 +0000 (13:39 +0100)] 
[uaccess] Add explicit casts to and from userptr_t where needed

Allow for the possibility of userptr_t becoming a pointer type by
adding explicit casts where necessary.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
3 months ago[uaccess] Rename userptr_sub() to userptr_diff()
Michael Brown [Sun, 20 Apr 2025 16:18:06 +0000 (17:18 +0100)] 
[uaccess] Rename userptr_sub() to userptr_diff()

Clarify the intended usage of userptr_sub() by renaming it to
userptr_diff() (to avoid confusion with userptr_add()), and fix the
existing call sites that erroneously use userptr_sub() to subtract an
offset from a userptr_t value.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
3 months ago[time] Use currticks() to provide the null system time
Michael Brown [Sat, 19 Apr 2025 12:35:23 +0000 (13:35 +0100)] 
[time] Use currticks() to provide the null system time

For platforms with no real-time clock (such as RISC-V SBI) we use the
null time source, which currently just returns a constant zero.

Switch to using currticks() to provide a clock that does not represent
the real current time, but does at least advance at approximately the
correct rate.  In conjunction with the "ntp" command, this allows
these platforms to use time-dependent features such as X.509
certificate verification for HTTPS connections.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
3 months ago[riscv] Map DEL to backspace on the SBI debug console
Michael Brown [Sat, 19 Apr 2025 11:18:53 +0000 (12:18 +0100)] 
[riscv] Map DEL to backspace on the SBI debug console

Signed-off-by: Michael Brown <mcb30@ipxe.org>
3 months ago[cgem] Add a driver for the Cadence GEM NIC
Michael Brown [Sat, 19 Apr 2025 10:54:08 +0000 (11:54 +0100)] 
[cgem] Add a driver for the Cadence GEM NIC

Add a basic driver for the Cadence GEM network interface as emulated
by QEMU when using the RISC-V "sifive_u" machine type.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
3 months ago[undi] Work around broken ASUSTeK KNPA-U16 server PXE ROM
Michael Brown [Thu, 17 Apr 2025 14:53:28 +0000 (15:53 +0100)] 
[undi] Work around broken ASUSTeK KNPA-U16 server PXE ROM

Signed-off-by: Michael Brown <mcb30@ipxe.org>
3 months ago[efi] Inhibit calls to Shutdown() for wireless SNP devices
Michael Brown [Wed, 16 Apr 2025 23:29:41 +0000 (00:29 +0100)] 
[efi] Inhibit calls to Shutdown() for wireless SNP devices

The UEFI model for wireless network configuration is somewhat
underdefined.  At the time of writing, the EDK2 "UEFI WiFi Connection
Manager" driver provides only one way to configure wireless network
credentials, which is to enter them interactively via an HII form.
Credentials are not stored (or exposed via any protocol interface),
and so any temporary disconnection from the wireless network will
inevitably leave the interface in an unusable state that cannot be
recovered without user intervention.

Experimentation shows that at least some wireless network drivers
(observed with an HP Elitebook 840 G10) will disconnect from the
wireless network when the SNP Shutdown() method is called, or if the
device is not polled sufficiently frequently to maintain its
association to the network.  We therefore inhibit calls to Shutdown()
and Stop() for any such SNP protocol interfaces, and mark our network
device as insomniac so that it will be polled even when closed.

Note that we need to inhibit not only our own calls to Shutdown() and
Stop(), but also those that will be attempted by MnpDxe when we
disconnect it from the SNP handle.  We do this by patching the
installed SNP protocol interface structure to modify the Shutdown()
and Stop() method pointers, which is ugly but unavoidable.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
3 months ago[netdevice] Add the concept of an insomniac network device
Michael Brown [Wed, 16 Apr 2025 23:27:13 +0000 (00:27 +0100)] 
[netdevice] Add the concept of an insomniac network device

Some network devices (observed with the SNP interface to the wireless
network card on an HP Elitebook 840 G10) will stop working if they are
left for too long without being polled.

Add the concept of an insomniac network device, that must continue to
be polled even when closed.

Note that drivers are already permitted to call netdev_rx() et al even
when closed: this will already be happening for USB devices since
polling operates at the level of the whole USB bus, rather than at the
level of individual USB devices.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
3 months ago[efi] Allow for custom methods for disconnecting existing drivers
Michael Brown [Wed, 16 Apr 2025 20:26:45 +0000 (21:26 +0100)] 
[efi] Allow for custom methods for disconnecting existing drivers

Allow for greater control over the process used to disconnect existing
drivers from a device handle, by converting the "exclude" field from a
simple protocol GUID to a per-driver method.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
3 months ago[dt] Provide dt_ioremap() to map device registers
Michael Brown [Tue, 15 Apr 2025 19:19:17 +0000 (20:19 +0100)] 
[dt] Provide dt_ioremap() to map device registers

Devicetree devices encode register address ranges within the "reg"
property, with the number of cells used for addresses and for sizes
determined by the #address-cells and #size-cells properties of the
immediate parent device.

Record the number of address and size cells for each device, and
provide a dt_ioremap() function to allow drivers to map a specified
range without having to directly handle the "reg" property.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
3 months ago[fdt] Add fdt_cells() to read cell-based properties such as "reg"
Michael Brown [Tue, 15 Apr 2025 19:14:03 +0000 (20:14 +0100)] 
[fdt] Add fdt_cells() to read cell-based properties such as "reg"

Add fdt_cells() to read scalar values encoded within a cell array,
reimplement fdt_u64() as a wrapper around this, and add fdt_u32() for
completeness.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
3 months ago[netdevice] Add missing bus type identifier for devicetree devices
Michael Brown [Tue, 15 Apr 2025 13:02:14 +0000 (14:02 +0100)] 
[netdevice] Add missing bus type identifier for devicetree devices

Signed-off-by: Michael Brown <mcb30@ipxe.org>
3 months ago[crypto] Allow for explicit control of external trust sources
Michael Brown [Tue, 15 Apr 2025 12:11:48 +0000 (13:11 +0100)] 
[crypto] Allow for explicit control of external trust sources

We currently disable all external trust sources (such as the UEFI
TlsCaCertificate variable) if an explicit TRUST=... parameter is
provided on the build command line.

Define an explicit TRUST_EXT build parameter that can be used to
explicitly disable external trust sources even if no TRUST=...
parameter is provided, or to explicitly enable external trust sources
even if an explicit TRUST=... parameter is provided.  For example:

   # Default trusted root certificate, disable external sources
   make TRUST_EXT=0

   # Explicit trusted root certificate, enable external sources
   make TRUST=custom.crt TRUST_EXT=1

If no TRUST_EXT parameter is specified, then continue to default to
disabling external trust sources if an explicit TRUST=... parameter is
provided, to maintain backwards compatibility with existing build
command lines.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
3 months ago[dt] Add basic concept of a devicetree bus
Michael Brown [Mon, 14 Apr 2025 10:34:20 +0000 (11:34 +0100)] 
[dt] Add basic concept of a devicetree bus

Add a basic model for devices instantiated by parsing the system
flattened device tree, with drivers matched via the "compatible"
property for any non-root node.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
3 months ago[fdt] Remove concept of a device tree cursor
Michael Brown [Mon, 14 Apr 2025 10:33:27 +0000 (11:33 +0100)] 
[fdt] Remove concept of a device tree cursor

Refactor device tree traversal to operate on the basis of describing
the token at a given offset, with no separate notion of a device tree
cursor.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
3 months ago[fdt] Add basic tests for reading values from a flattened device tree
Michael Brown [Mon, 14 Apr 2025 12:40:31 +0000 (13:40 +0100)] 
[fdt] Add basic tests for reading values from a flattened device tree

Signed-off-by: Michael Brown <mcb30@ipxe.org>
3 months ago[fdt] Avoid temporarily modifying path during path lookup
Michael Brown [Mon, 14 Apr 2025 12:41:55 +0000 (13:41 +0100)] 
[fdt] Avoid temporarily modifying path during path lookup

Signed-off-by: Michael Brown <mcb30@ipxe.org>
3 months ago[fdt] Provide fdt_strings() to read string list properties
Michael Brown [Mon, 14 Apr 2025 10:32:17 +0000 (11:32 +0100)] 
[fdt] Provide fdt_strings() to read string list properties

Signed-off-by: Michael Brown <mcb30@ipxe.org>
3 months ago[fdt] Allow for trailing slashes in path lookups
Michael Brown [Mon, 14 Apr 2025 10:26:49 +0000 (11:26 +0100)] 
[fdt] Allow for trailing slashes in path lookups

Using fdt_path() to find the root node "/" currently fails, since it
will attempt to find a child node with the empty name "" within the
root node.

Fix by changing fdt_path() to ignore any trailing slashes in a device
tree path.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
3 months ago[crypto] Switch to using python-asn1crypto instead of python-asn1
Michael Brown [Fri, 11 Apr 2025 11:36:45 +0000 (12:36 +0100)] 
[crypto] Switch to using python-asn1crypto instead of python-asn1

Version 3.0.0 of python-asn1 has a serious defect that causes it to
generate invalid DER.

Fix by switching to the asn1crypto module, which also allows for
simpler code to be used.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
4 months ago[fdt] Populate boot arguments in constructed device tree
Michael Brown [Tue, 1 Apr 2025 15:53:02 +0000 (16:53 +0100)] 
[fdt] Populate boot arguments in constructed device tree

When creating a device tree to pass to a booted operating system,
ensure that the "chosen" node exists, and populate the "bootargs"
property with the image command line.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
4 months ago[fdt] Identify free space (if any) at end of parsed tree
Michael Brown [Tue, 1 Apr 2025 12:04:10 +0000 (13:04 +0100)] 
[fdt] Identify free space (if any) at end of parsed tree

Signed-off-by: Michael Brown <mcb30@ipxe.org>
4 months ago[x509] Ensure certificate remains valid during x509_append()
Michael Brown [Mon, 31 Mar 2025 16:44:59 +0000 (17:44 +0100)] 
[x509] Ensure certificate remains valid during x509_append()

The allocation of memory for the certificate chain link may cause the
certificate itself to be freed by the cache discarder, if the only
current reference to the certificate is held by the certificate store
and the system runs out of memory during the call to malloc().

Ensure that this cannot happen by taking out a temporary additional
reference to the certificate within x509_append(), rather than
requiring the caller to do so.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
4 months ago[tls] Support fragmentation of transmitted records
Michael Brown [Mon, 31 Mar 2025 15:36:33 +0000 (16:36 +0100)] 
[tls] Support fragmentation of transmitted records

Large transmitted records may arise if we have long client certificate
chains or if a client sends a large block of data (such as a large
HTTP POST payload).  Fragment records as needed to comply with the
value that we advertise via the max_fragment_length extension.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
4 months ago[tls] Send an empty client certificate chain if we have no certificate 1437/head
Michael Brown [Mon, 31 Mar 2025 13:25:41 +0000 (14:25 +0100)] 
[tls] Send an empty client certificate chain if we have no certificate

RFC5246 states that "a client MAY send no certificates if it does not
have an appropriate certificate to send in response to the server's
authentication request".  This use case may arise when the server is
using optional client certificate verification and iPXE has not been
provided with a client certificate to use.

Treat the absence of a suitable client certificate as a non-fatal
condition and send a Certificate message containing no certificates as
permitted by RFC5246.

Reported-by: Alexandre Ravey <alexandre@voilab.ch>
Originally-implemented-by: Alexandre Ravey <alexandre@voilab.ch>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
4 months ago[iobuf] Limit automatic I/O buffer alignment to page size
Michael Brown [Mon, 31 Mar 2025 12:33:44 +0000 (13:33 +0100)] 
[iobuf] Limit automatic I/O buffer alignment to page size

Without any explicit alignment requirement, we will currently allocate
I/O buffers on their own size rounded up to the nearest power of two.
This is done to simplify driver transmit code paths, which can assume
that a standard Ethernet frame lies within a single physical page and
therefore does not need to be split even for devices with DMA engines
that cannot cross page boundaries.

Limit this automatic alignment to a maximum of the page size, to avoid
requiring excessive alignment for unusually large buffers (such as a
buffer allocated for an HTTP POST with a large parameter list).

Signed-off-by: Michael Brown <mcb30@ipxe.org>
4 months ago[tls] Encrypt data in place to reduce memory usage
Michael Brown [Sun, 30 Mar 2025 23:15:27 +0000 (00:15 +0100)] 
[tls] Encrypt data in place to reduce memory usage

Provide a custom xfer_alloc_iob() handler to ensure that transmit I/O
buffers contain sufficient headroom for the TLS record header and
record initialisation vector, and sufficient tailroom for the MAC,
block cipher padding, and authentication tag.  This allows us to use
in-place encryption for the actual data within the I/O buffer, which
essentially halves the amount of memory that needs to be allocated for
a TLS data transmission.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
4 months ago[xfer] Use xfer_alloc_iob() for transmit I/O buffers on stream sockets
Michael Brown [Sun, 30 Mar 2025 20:47:34 +0000 (21:47 +0100)] 
[xfer] Use xfer_alloc_iob() for transmit I/O buffers on stream sockets

Datagram sockets such as UDP, ICMP, and fibre channel tend to provide
a custom xfer_alloc_iob() handler to ensure that transmit I/O buffers
contain sufficient headroom to accommodate any required protocol
headers.

Stream sockets such as TCP and TLS do not typically provide a custom
xfer_alloc_iob() handler at present.  The default handler simply calls
alloc_iob(), and so stream socket consumers can therefore get away
with using alloc_iob() rather than xfer_alloc_iob().

Fix the HTTP and ONC RPC protocols to use xfer_alloc_iob() where
relevant, in order to operate correctly if the underlying stream
socket chooses to provide a custom xfer_alloc_iob() handler.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
4 months ago[isa] Disable legacy ISA device probing by default
Michael Brown [Sat, 29 Mar 2025 23:01:21 +0000 (23:01 +0000)] 
[isa] Disable legacy ISA device probing by default

Legacy ISA device probing involves poking at various I/O addresses to
guess whether or not a particular device is present.

Actual legacy ISA cards are essentially nonexistent by now, but the
probed I/O addresses have a habit of being reused for various
OEM-specific functions.  This can cause some very undesirable side
effects.  For example, probing for the "ne2k_isa" driver on an HP
Elitebook 840 G10 will cause the system to lock up in a way that
requires two cold reboots to recover.

Enable ISA_PROBE_ONLY in config/isa.h by default.  This limits ISA
probing to use only the addresses specified in ISA_PROBE_ADDRS, which
is empty by default, and so effectively disables ISA probing.  The
vanishingly small number of users who require ISA probing can simply
adjust this configuration in config/local/isa.h.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
4 months ago[efi] Allow for fact that SNP device may be removed by executed image
Michael Brown [Sat, 29 Mar 2025 21:28:53 +0000 (21:28 +0000)] 
[efi] Allow for fact that SNP device may be removed by executed image

The executed image may call DisconnectController() to remove our
network device.  This will leave the net device unregistered but not
yet freed (since our installed PXE base code protocol retains a
reference to the net device).

Unregistration will cause the network upper-layer driver removal
functions to be called, which will free the SNP device structure.
When the image returns from StartImage(), the snpdev pointer may
therefore no longer be valid.

The SNP device structure is not reference counted, and so we cannot
simply take out a reference to ensure that it remains valid across the
call to StartImage().  However, the code path following the call to
StartImage() doesn't actually require the SNP device pointer, only the
EFI device handle.

Store the device handle in a local variable and ensure that snpdev is
invalidated before the call to StartImage() so that future code cannot
accidentally reintroduce this issue.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
4 months ago[efi] Check correct return value from efi_pxe_find()
Michael Brown [Sat, 29 Mar 2025 22:03:32 +0000 (22:03 +0000)] 
[efi] Check correct return value from efi_pxe_find()

Signed-off-by: Michael Brown <mcb30@ipxe.org>
4 months ago[efi] Disconnect existing drivers on a per-protocol basis
Michael Brown [Sat, 29 Mar 2025 14:57:16 +0000 (14:57 +0000)] 
[efi] Disconnect existing drivers on a per-protocol basis

UEFI does not provide a direct method to disconnect the existing
driver of a specific protocol from a handle.  We currently use
DisconnectController() to remove all drivers from a handle that we
want to drive ourselves, and then rely on recursion in the call to
ConnectController() to reconnect any drivers that did not need to be
disconnected in the first place.

Experience shows that OEMs tend not to ever test the disconnection
code paths in their UEFI drivers, and it is common to find drivers
that refuse to disconnect, fail to close opened handles, fail to
function correctly after reconnection, or lock up the entire system.

Implement a more selective form of disconnection, in which we use
OpenProtocolInformation() to identify the driver associated with a
specific protocol, and then disconnect only that driver.

Perform disconnections in reverse order of attachment priority, since
this is the order likely to minimise the number of cascaded implicit
disconnections.

This allows our MNP driver to avoid performing any disconnections at
all, since it does not require exclusive access to the MNP protocol.
It also avoids performing unnecessary disconnections and reconnections
of unrelated drivers such as the "UEFI WiFi Connection Manager" that
attaches to wireless network interfaces in order to manage wireless
network associations.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
4 months ago[efi] Define an attachment priority order for EFI drivers
Michael Brown [Sat, 29 Mar 2025 15:28:19 +0000 (15:28 +0000)] 
[efi] Define an attachment priority order for EFI drivers

Define an ordering for internal EFI drivers on the basis of how close
the driver is to the hardware, and attempt to start drivers in this
order.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
4 months ago[efi] Show all drivers claiming support for a handle in debug messages
Michael Brown [Sat, 29 Mar 2025 15:11:57 +0000 (15:11 +0000)] 
[efi] Show all drivers claiming support for a handle in debug messages

UEFI assumes in several places that an image installs only a single
driver binding protocol instance, and that this is installed on the
image handle itself.  We therefore provide a single driver binding
protocol instance, which delegates to the various internal drivers
(for EFI_PCI_IO_PROTOCOL, EFI_USB_IO_PROTOCOL, etc) as appropriate.

The debug messages produced by our Supported() method can end up
slightly misleading, since they will report only the first internal
driver that claims support for a device.  In the common case of the
all-drivers build, there may be multiple drivers that claim support
for the same handle: for example, the PCI, NII, SNP, and MNP drivers
are all likely to initially find the protocols that they need on the
same device handle.

Report all internal drivers that claim support for a device, to avoid
confusing debug messages.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
4 months ago[efi] Return success from Stop() if driver is already stopped
Michael Brown [Sat, 29 Mar 2025 18:41:01 +0000 (18:41 +0000)] 
[efi] Return success from Stop() if driver is already stopped

Return success if asked to stop driving a device that we are not
currently driving.  This avoids propagating spurious errors to an
external caller of DisconnectController().

Signed-off-by: Michael Brown <mcb30@ipxe.org>
4 months ago[efi] Add various well-known GUIDs encountered in WiFi boot
Michael Brown [Fri, 28 Mar 2025 21:01:42 +0000 (21:01 +0000)] 
[efi] Add various well-known GUIDs encountered in WiFi boot

Signed-off-by: Michael Brown <mcb30@ipxe.org>
4 months ago[efi] Install a device tree for the booted OS, if available
Michael Brown [Fri, 28 Mar 2025 14:20:44 +0000 (14:20 +0000)] 
[efi] Install a device tree for the booted OS, if available

If we have a device tree available (e.g. because the user has
explicitly downloaded a device tree using the "fdt" command), then
provide it to the booted operating system as an EFI configuration
table.

Since x86 does not typically use device trees, we create weak symbols
for efi_fdt_install() and efi_fdt_uninstall() to avoid dragging FDT
support into all x86 UEFI binaries.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
4 months ago[fdt] Provide the ability to create a device tree for a booted OS
Michael Brown [Fri, 28 Mar 2025 14:17:29 +0000 (14:17 +0000)] 
[fdt] Provide the ability to create a device tree for a booted OS

Provide fdt_create() to create a device tree to be passed to a booted
operating system.  The device tree will be created from the FDT image
(if present), falling back to the system device tree (if present).

Signed-off-by: Michael Brown <mcb30@ipxe.org>
4 months ago[efi] Create a copy of the system flattened device tree, if present
Michael Brown [Fri, 28 Mar 2025 14:10:55 +0000 (14:10 +0000)] 
[efi] Create a copy of the system flattened device tree, if present

EFI configuration tables may be freed at any time, and there is no way
to be notified when the table becomes invalidated.  Create a copy of
the system flattened device tree (if present), so that we do not risk
being left with an invalid pointer.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
4 months ago[fdt] Allow for parsing device trees where the length is known in advance
Michael Brown [Fri, 28 Mar 2025 14:08:18 +0000 (14:08 +0000)] 
[fdt] Allow for parsing device trees where the length is known in advance

Allow for parsing device trees where an external factor (such as a
downloaded image length) determines the maximum length, which must be
validated against the length within the device tree header.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
4 months ago[fdt] Allow for the existence of multiple device trees
Michael Brown [Fri, 28 Mar 2025 12:42:30 +0000 (12:42 +0000)] 
[fdt] Allow for the existence of multiple device trees

When running on a platform that uses FDT as its hardware description
mechanism, we are likely to have multiple device tree structures.  At
a minimum, there will be the device tree passed to us from the
previous boot stage (e.g. OpenSBI), and the device tree that we
construct to be passed to the booted operating system.

Update the internal FDT API to include an FDT pointer in all function
parameter lists.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
4 months ago[fdt] Add the "fdt" command
Michael Brown [Thu, 27 Mar 2025 11:36:35 +0000 (11:36 +0000)] 
[fdt] Add the "fdt" command

Allow a Flattened Device Tree blob (DTB) to be provided to a booted
operating system using a script such as:

  #!ipxe
  kernel /images/vmlinuz console=ttyAMA0
  initrd /images/initrd.img
  fdt /images/rk3566-radxa-zero-3e.dtb
  boot

Signed-off-by: Michael Brown <mcb30@ipxe.org>
4 months ago[fdt] Add the concept of an FDT image
Michael Brown [Thu, 27 Mar 2025 11:30:27 +0000 (11:30 +0000)] 
[fdt] Add the concept of an FDT image

Define the concept of an "FDT" image, representing a Flattened Device
Tree blob that has been downloaded in order to be provided to a kernel
or other executable image.  FDT images are represented using an image
tag (as with other special-purpose images such as the UEFI shim), and
are similarly marked as hidden so that they will not be included in a
generated magic initrd or show up in a virtual filesystem directory
listing.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
4 months ago[efi] Add support for installing EFI configuration tables
Michael Brown [Thu, 27 Mar 2025 14:45:12 +0000 (14:45 +0000)] 
[efi] Add support for installing EFI configuration tables

Add the ability to install and uninstall arbitrary EFI configuration
tables.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
4 months ago[efi] Add flattened device tree header and GUID definitions
Michael Brown [Thu, 27 Mar 2025 12:49:58 +0000 (12:49 +0000)] 
[efi] Add flattened device tree header and GUID definitions

Signed-off-by: Michael Brown <mcb30@ipxe.org>
4 months ago[efi] Add ACPI and SMBIOS tables as well-known GUIDs
Michael Brown [Thu, 27 Mar 2025 12:48:05 +0000 (12:48 +0000)] 
[efi] Add ACPI and SMBIOS tables as well-known GUIDs

Signed-off-by: Michael Brown <mcb30@ipxe.org>
4 months ago[undi] Ensure forward progress is made even if UNDI IRQ is stuck
Michael Brown [Wed, 26 Mar 2025 13:58:22 +0000 (13:58 +0000)] 
[undi] Ensure forward progress is made even if UNDI IRQ is stuck

If the UNDI interrupt remains constantly asserted (e.g. because the
BIOS has enabled interrupts for an unrelated device sharing the same
IRQ, or because of bugs in the OEM UNDI driver), then we may get stuck
in an interrupt storm.

We cannot safely chain to the previous interrupt handler (which could
plausibly handle an unrelated device interrupt) since there is no
well-defined behaviour for previous interrupt handlers.  We have
observed BIOSes to provide default interrupt handlers that variously
do nothing, send EOI, disable the IRQ, or crash the system.

Fix by disabling the UNDI interrupt whenever our handler is triggered,
and rearm it as needed when polling the network device.  This ensures
that forward progress continues to be made even if something causes
the interrupt to be constantly asserted.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
4 months ago[pxeprefix] Ensure that UNDI IRQ is disabled before starting iPXE
Michael Brown [Wed, 26 Mar 2025 14:49:08 +0000 (14:49 +0000)] 
[pxeprefix] Ensure that UNDI IRQ is disabled before starting iPXE

When using the undionly.kkpxe binary (which is never recommended), the
UNDI interrupt may still be enabled when iPXE starts up.  If the PXE
base code interrupt handler is not well-behaved, this can result in
undefined behaviour when interrupts are first enabled (e.g. for
entropy gathering, or for allowing the timer tick to occur).

Fix by detecting and disabling the UNDI interrupt during the prefix
code.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
4 months ago[pxeprefix] Work around missing type values from PXENV_UNDI_GET_NIC_TYPE
Michael Brown [Wed, 26 Mar 2025 11:35:48 +0000 (11:35 +0000)] 
[pxeprefix] Work around missing type values from PXENV_UNDI_GET_NIC_TYPE

The implementation of PXENV_UNDI_GET_NIC_TYPE in some PXE ROMs
(observed with an Intel X710 ROM in a Dell PowerEdge R6515) will fail
to write the NicType byte, leaving it uninitialised.

Prepopulate the NicType byte with a highly unlikely value as a
sentinel to allow us to detect this, and assume that any such devices
are overwhelmingly likely to be PCI devices.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
4 months ago[efi] Allow use of typed pointers for efi_open() et al
Michael Brown [Mon, 24 Mar 2025 14:24:47 +0000 (14:24 +0000)] 
[efi] Allow use of typed pointers for efi_open() et al

Provide wrapper macros to allow efi_open() and related functions to
accept a pointer to any pointer type as the "interface" argument, in
order to allow a substantial amount of type adjustment boilerplate to
be removed.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
4 months ago[efi] Eliminate uses of HandleProtocol()
Michael Brown [Mon, 24 Mar 2025 14:22:54 +0000 (14:22 +0000)] 
[efi] Eliminate uses of HandleProtocol()

It is now simpler to use efi_open() than to use HandleProtocol() to
obtain an ephemeral protocol instance.  Remove all remaining uses of
HandleProtocol() to simplify the code.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
4 months ago[efi] Use efi_open() for all ephemeral protocol opens
Michael Brown [Sun, 23 Mar 2025 19:11:13 +0000 (19:11 +0000)] 
[efi] Use efi_open() for all ephemeral protocol opens

Signed-off-by: Michael Brown <mcb30@ipxe.org>
4 months ago[efi] Use efi_open_unsafe() for all explicitly unsafe protocol opens
Michael Brown [Sun, 23 Mar 2025 19:38:14 +0000 (19:38 +0000)] 
[efi] Use efi_open_unsafe() for all explicitly unsafe protocol opens

Signed-off-by: Michael Brown <mcb30@ipxe.org>
4 months ago[efi] Use efi_open_by_driver() for all by-driver protocol opens
Michael Brown [Sun, 23 Mar 2025 18:06:15 +0000 (18:06 +0000)] 
[efi] Use efi_open_by_driver() for all by-driver protocol opens

Signed-off-by: Michael Brown <mcb30@ipxe.org>
4 months ago[efi] Use efi_open_by_child() for all by-child protocol opens
Michael Brown [Sun, 23 Mar 2025 17:49:39 +0000 (17:49 +0000)] 
[efi] Use efi_open_by_child() for all by-child protocol opens

Signed-off-by: Michael Brown <mcb30@ipxe.org>
4 months ago[efi] Create safe wrappers for OpenProtocol() and CloseProtocol()
Michael Brown [Sun, 23 Mar 2025 17:21:36 +0000 (17:21 +0000)] 
[efi] Create safe wrappers for OpenProtocol() and CloseProtocol()

The UEFI model for opening and closing protocols is broken by design
and cannot be repaired.

Calling OpenProtocol() to obtain a protocol interface pointer does
not, in general, provide any guarantees about the lifetime of that
pointer.  It is theoretically possible that the pointer has already
become invalid by the time that OpenProtocol() returns the pointer to
its caller.  (This can happen when a USB device is physically removed,
for example.)

Various UEFI design flaws make it occasionally necessary to hold on to
a protocol interface pointer despite the total lack of guarantees that
the pointer will remain valid.

The UEFI driver model overloads the semantics of OpenProtocol() to
accommodate the use cases of recording a driver attachment (which is
modelled as opening a protocol with EFI_OPEN_PROTOCOL_BY_DRIVER
attributes) and recording the existence of a related child controller
(which is modelled as opening a protocol with
EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER attributes).

The parameters defined for CloseProtocol() are not sufficient to allow
the implementation to precisely identify the matching call to
OpenProtocol().  While the UEFI model appears to allow for matched
open and close pairs, this is merely an illusion.  Calling
CloseProtocol() will delete *all* matching records in the protocol
open information tables.

Since the parameters defined for CloseProtocol() do not include the
attributes passed to OpenProtocol(), this means that a matched
open/close pair using EFI_OPEN_PROTOCOL_GET_PROTOCOL can inadvertently
end up deleting the record that defines a driver attachment or the
existence of a child controller.  This in turn can cause some very
unexpected side effects, such as allowing other UEFI drivers to start
controlling hardware to which iPXE believes it has exclusive access.
This rarely ends well.

To prevent this kind of inadvertent deletion, we establish a
convention for four different types of protocol opening:

- ephemeral opens: always opened with ControllerHandle = NULL

- unsafe opens: always opened with ControllerHandle = AgentHandle

- by-driver opens: always opened with ControllerHandle = Handle

- by-child opens: always opened with ControllerHandle != Handle

This convention ensures that the four types of open never overlap
within the set of parameters defined for CloseProtocol(), and so a
close of one type cannot inadvertently delete the record corresponding
to a different type.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
4 months ago[efi] Remove the efipci_open() and efipci_close() wrappers
Michael Brown [Mon, 24 Mar 2025 11:11:44 +0000 (11:11 +0000)] 
[efi] Remove the efipci_open() and efipci_close() wrappers

In preparation for formalising the way that EFI protocols are opened
across the codebase, remove the efipci_open() wrapper.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
4 months ago[efi] Avoid function name near-collision
Michael Brown [Sun, 23 Mar 2025 19:37:21 +0000 (19:37 +0000)] 
[efi] Avoid function name near-collision

We currently have both efipci_info() and efi_pci_info() serving
different but related purposes.  Rename the latter to reduce
confusion.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
4 months ago[efi] Remove spurious close of SNP device parent's device path
Michael Brown [Sun, 23 Mar 2025 18:22:00 +0000 (18:22 +0000)] 
[efi] Remove spurious close of SNP device parent's device path

Commit e727f57 ("[efi] Include a copy of the device path within struct
efi_device") neglected to delete the closure of the parent's device
path from the success code path in efi_snp_probe().

Reduce confusion by removing this (harmless) additional close.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
4 months ago[efi] Use driver name only from driver binding handles in debug messages
Michael Brown [Fri, 21 Mar 2025 16:58:03 +0000 (16:58 +0000)] 
[efi] Use driver name only from driver binding handles in debug messages

Some non-driver handles may have an installed component name protocol.
In particular, iPXE itself installs these protocols on its SNP device
handles, to simplify the process of delegating GetControllerName()
from our single-instance driver binding protocol to whatever child
controllers the relevant EFI driver may have installed.

For non-driver handles, the device path is more useful as debugging
information than the driver name.  Limit the use of the component name
protocols to handles with a driver binding protocol installed, so that
we will end up using the device path for non-driver handles such as
the SNP device.

Continue to prefer the driver name to the device path for handles with
a driver binding protocol installed, since these will generally map to
things we are likely to conceptualise as drivers rather than as
devices.

Note that we deliberately do not use GetControllerName() to attempt to
get a human-readable name for a controller handle.  In the normal
course of events, iPXE is likely to disconnect at least some existing
drivers from their controller handles.  This would cause the name
obtained via GetControllerName() to change.  By using the device path
instead, we ensure that the debug message name remains the same even
when the driver controlling the handle is changed.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
4 months ago[efi] Get veto candidate driver name via either component name protocol
Michael Brown [Thu, 20 Mar 2025 14:38:20 +0000 (14:38 +0000)] 
[efi] Get veto candidate driver name via either component name protocol

Attempt to get the veto candidate driver name from both the current
and obsolete versions of the component name protocol.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
4 months ago[efi] Get veto candidate driver name from image handle
Michael Brown [Thu, 20 Mar 2025 14:35:11 +0000 (14:35 +0000)] 
[efi] Get veto candidate driver name from image handle

Allow for drivers that do not install the driver binding protocol on
the image handle by opening the component name protocol on the driver
binding's ImageHandle rather than on the driver handle itself.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
4 months ago[efi] Show image address range in veto debug messages
Michael Brown [Thu, 20 Mar 2025 14:30:34 +0000 (14:30 +0000)] 
[efi] Show image address range in veto debug messages

When hunting down a misbehaving OEM driver to add it to the veto list,
it can be very useful to know the address ranges used by each driver.
Add this information to the verbose debug messages.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
4 months ago[efi] Prefer driver name to device path for debug messages
Michael Brown [Thu, 20 Mar 2025 14:20:57 +0000 (14:20 +0000)] 
[efi] Prefer driver name to device path for debug messages

The driver name is usually more informative for debug messages than
the device path from which a driver was loaded.  Try using the various
mechanisms for obtaining a driver name before trying the device path.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
4 months ago[efi] Attempt to retrieve driver name from image handle for debug messages
Michael Brown [Thu, 20 Mar 2025 14:18:02 +0000 (14:18 +0000)] 
[efi] Attempt to retrieve driver name from image handle for debug messages

Not all drivers will install the driver binding protocol on the image
handle.  Accommodate these drivers by attempting to retrieve the
driver name via the component name protocol(s) located on the driver
binding's ImageHandle, as well as on the driver handle itself.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
4 months ago[efi] Allow wrapping the global boot services table in situ
Michael Brown [Thu, 20 Mar 2025 12:25:26 +0000 (12:25 +0000)] 
[efi] Allow wrapping the global boot services table in situ

When DEBUG=efi_wrap is enabled, we construct a patched copy of the
boot services table and patch the global system table to point to this
copy.  This ensures that any subsequently loaded EFI binaries will
call our wrappers.

Previously loaded EFI binaries will typically have cached the boot
services table pointer (in the gBS variable used by EDK2 code), and
therefore will not pick up the updated pointer and so will not call
our wrappers.  In most cases, this is what we want to happen: we are
interested in tracing the calls issued by the newly loaded binary and
we do not want to be distracted by the high volume of boot services
calls issued by existing UEFI drivers.

In some circumstances (such as when a badly behaved OEM driver is
causing the system to lock up during the ExitBootServices() call), it
can be very useful to be able to patch the global boot services table
in situ, so that we can trace calls issued by existing drivers.

Restructure the wrapping code to allow wrapping to be enabled or
disabled at any time, and to allow for patching the global boot
services table in situ.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
4 months ago[efi] Fix debug wrappers for CloseEvent() and CheckEvent()
Michael Brown [Wed, 19 Mar 2025 16:20:27 +0000 (16:20 +0000)] 
[efi] Fix debug wrappers for CloseEvent() and CheckEvent()

The debug wrappers for CloseEvent() and CheckEvent() are currently
both calling SignalEvent() instead (presumably due to copy-paste
errors).  Astonishingly, this has generally not prevented a successful
boot in the (very rare) case that DEBUG=efi_wrap is enabled.

Fix the wrappers to call the intended functions.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
4 months ago[efi] Ignore path separator characters in virtual filenames
Michael Brown [Tue, 18 Mar 2025 16:13:55 +0000 (16:13 +0000)] 
[efi] Ignore path separator characters in virtual filenames

The virtual filesystem that we provide to expose downloaded images
will erroneously interpret filenames with redundant path separators
such as ".\filename" as an attempt to open the directory, rather than
an attempt to open "filename".

This shows up most obviously when chainloading from one iPXE into
another iPXE, when the inner iPXE may end up attempting to open
".\autoexec.ipxe" from the outer iPXE's virtual filesystem.  (The
erroneously opened file will have a zero length and will therefore be
ignored, but is still confusing.)

Fix by discarding any dot or backslash characters after a potential
initial backslash.  This is very liberal and will accept some
syntactically invalid paths, but this is acceptable since our virtual
filesystem does not implement directories anyway.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
4 months ago[efi] Prescroll the display after a failed wrapped ExitBootServices() call
Michael Brown [Tue, 18 Mar 2025 13:50:11 +0000 (13:50 +0000)] 
[efi] Prescroll the display after a failed wrapped ExitBootServices() call

On some systems (observed with an HP Elitebook 840 G10), writing
console output that happens to cause the display to scroll will modify
the system memory map.  This causes builds with DEBUG=efi_wrap to
typically fail to boot, since the debug output from the wrapped
ExitBootServices() call itself is sufficient to change the memory map
and therefore cause ExitBootServices() to fail due to an invalid
memory map key.

Work around these UEFI firmware bugs by prescrolling the display after
a failed ExitBootServices() attempt, in order to minimise the chance
that further scrolling will happen during the subsequent attempt.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
4 months ago[efi] Add EFI_RNG_PROTOCOL_GUID as a well-known GUID
Michael Brown [Tue, 18 Mar 2025 12:49:19 +0000 (12:49 +0000)] 
[efi] Add EFI_RNG_PROTOCOL_GUID as a well-known GUID

Signed-off-by: Michael Brown <mcb30@ipxe.org>
4 months ago[crypto] Update cmsdetach to work with python-asn1 version 3.0.0
Michael Brown [Mon, 17 Mar 2025 11:39:41 +0000 (11:39 +0000)] 
[crypto] Update cmsdetach to work with python-asn1 version 3.0.0

The python-asn1 documentation indicates that end of file may be
detected either by obtaining a True value from .eof() or by obtaining
a None value from .peek(), but does not mention any way to detect the
end of a constructed tag (rather than the end of the overall file).
We currently use .eof() to detect the end of a constructed tag, based
on the observed behaviour of the library.

The behaviour of .eof() changed between versions 2.8.0 and 3.0.0, such
that .eof() no longer returns True at the end of a constructed tag.

Switch to testing for a None value returned from .peek() to determine
when we have reached the end of a constructed tag, since this works on
both newer and older versions.

Continue to treat .eof() as a necessary but not sufficient condition
for reaching the overall end of file, to maintain compatibility with
older versions.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
4 months ago[rng] Restore state of IRQ 8 and PIE when disabling entropy gathering
Michael Brown [Fri, 14 Mar 2025 14:11:48 +0000 (14:11 +0000)] 
[rng] Restore state of IRQ 8 and PIE when disabling entropy gathering

Legacy IRQ 8 appears to be enabled by default on some platforms.  If
iPXE selects the RTC entropy source, this will currently result in the
RTC IRQ 8 being unconditionally disabled.  This can break assumptions
made by BIOSes or subsequent bootloaders: in particular, the FreeBSD
loader may lock up at the point of starting its default 10-second
countdown when it calls INT 15,86.

Fix by restoring the previous state of IRQ 8 instead of disabling it
unconditionally.  Note that we do not need to disable IRQ 8 around the
point of hooking (or unhooking) the ISR, since this code will be
executing in iPXE's normal state of having interrupts disabled anyway.

Also restore the previous state of the RTC periodic interrupt enable,
rather than disabling it unconditionally.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
4 months ago[pic8259] Return previous state when enabling or disabling IRQs
Michael Brown [Fri, 14 Mar 2025 14:09:26 +0000 (14:09 +0000)] 
[pic8259] Return previous state when enabling or disabling IRQs

Return the previous interrupt enabled state from enable_irq() and
disable_irq(), to allow callers to more easily restore this state.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
4 months ago[contrib] Update bochsrc.txt to work with current versions
Michael Brown [Fri, 14 Mar 2025 12:46:02 +0000 (12:46 +0000)] 
[contrib] Update bochsrc.txt to work with current versions

Signed-off-by: Michael Brown <mcb30@ipxe.org>
4 months ago[efi] Accept and trust CA certificates in the TlsCaCertificates variable
Michael Brown [Thu, 13 Mar 2025 14:04:26 +0000 (14:04 +0000)] 
[efi] Accept and trust CA certificates in the TlsCaCertificates variable

UEFI's built-in HTTPS boot mechanism requires the trusted CA
certificates to be provided via the TlsCaCertificates variable.
(There is no equivalent of the iPXE cross-signing mechanism, so it is
not possible for UEFI to automatically use public CA certificates.)

Users who have configured UEFI HTTPS boot to use a custom root of
trust (e.g. a private CA certificate) may find it useful to have iPXE
automatically pick up and use this same root of trust, so that iPXE
can seamlessly fetch files via HTTPS from the same servers that were
trusted by UEFI HTTPS boot, in addition to servers that iPXE can
validate through other means such as cross-signed certificates.

Parse the TlsCaCertificates variable at startup, add any certificates
to the certificate store, and mark these certificates as trusted.

There are no access restrictions on modifying the TlsCaCertificates
variable: anybody with access to write UEFI variables is permitted to
change the root of trust.  The UEFI security model assumes that anyone
with access to run code prior to ExitBootServices() or with access to
modify UEFI variables from within a loaded operating system is
supposed to be able to change the system's root of trust for TLS.

Any certificates parsed from TlsCaCertificates will show up in the
output of "certstat", and may be discarded using "certfree" if
unwanted.

Support for parsing TlsCaCertificates is enabled by default in EFI
builds, but may be disabled in config/general.h if needed.

As with the ${trust} setting, the contents of the TlsCaCertificates
variable will be ignored if iPXE has been compiled with an explicit
root of trust by specifying TRUST=... on the build command line.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
4 months ago[efi] Add TLS authentication header and GUID definitions
Michael Brown [Thu, 13 Mar 2025 13:40:16 +0000 (13:40 +0000)] 
[efi] Add TLS authentication header and GUID definitions

Add the TlsAuthentication.h header from EDK2's NetworkPkg, along with
a GUID definition for EFI_TLS_CA_CERTIFICATE_GUID.

It is unclear whether or not the TlsCaCertificate variable is intended
to be a UEFI standard.  Its presence in NetworkPkg (rather than
MdePkg) suggests not, but the choice of EFI_TLS_CA_CERTIFICATE_GUID
(rather than e.g. EDKII_TLS_CA_CERTIFICATE_GUID) suggests that it is
intended to be included in future versions of the standard.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
4 months ago[efi] Add EFI_GLOBAL_VARIABLE as a well-known GUID
Michael Brown [Thu, 13 Mar 2025 13:56:27 +0000 (13:56 +0000)] 
[efi] Add EFI_GLOBAL_VARIABLE as a well-known GUID

Signed-off-by: Michael Brown <mcb30@ipxe.org>
4 months ago[cpio] Allow for the construction of pure directories
Michael Brown [Wed, 12 Mar 2025 14:25:05 +0000 (14:25 +0000)] 
[cpio] Allow for the construction of pure directories

Allow for the possibility of creating empty directories (without
having to include a dummy file inside the directory) using a
zero-length image and a CPIO filename with a trailing slash, such as:

  initrd emptyfile /usr/share/oem/

Signed-off-by: Michael Brown <mcb30@ipxe.org>
4 months ago[cpio] Fix calculation of name lengths in CPIO headers
Michael Brown [Wed, 12 Mar 2025 14:15:16 +0000 (14:15 +0000)] 
[cpio] Fix calculation of name lengths in CPIO headers

Commit 12ea8c4 ("[cpio] Allow for construction of parent directories
as needed") introduced a regression in constructing CPIO archive
headers for relative paths (e.g. simple filenames with no leading
slash).

Fix by counting the number of path components rather than the number
of path separators, and add some test cases to cover CPIO header
construction.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
4 months ago[crypto] Support extracting certificates from EFI signature list images
Michael Brown [Tue, 11 Mar 2025 11:58:28 +0000 (11:58 +0000)] 
[crypto] Support extracting certificates from EFI signature list images

Add support for the EFI signature list image format (as produced by
tools such as efisecdb).

The parsing code does not require any EFI boot services functions and
so may be enabled even in non-EFI builds.  We default to enabling it
only for EFI builds.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
4 months ago[crypto] Allow for parsing of DER data separate from DER images
Michael Brown [Tue, 11 Mar 2025 11:55:15 +0000 (11:55 +0000)] 
[crypto] Allow for parsing of DER data separate from DER images

We currently provide pem_asn1() to allow for parsing of PEM data that
is not necessarily contained in an image.  Provide an equivalent
function der_asn1() to allow for similar parsing of DER data.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
4 months ago[efi] Allow efi_guid_ntoa() to be used in non-EFI builds
Michael Brown [Tue, 11 Mar 2025 11:52:37 +0000 (11:52 +0000)] 
[efi] Allow efi_guid_ntoa() to be used in non-EFI builds

The debug message transcription of well-known EFI GUIDs does not
require any EFI boot services calls.  Move this code from efi_debug.c
to efi_guid.c, to allow it to be linked in to non-EFI builds.

We continue to rely on linker garbage collection to ensure that the
code is omitted completely from any non-debug builds.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
4 months ago[efi] Add EFI_SIGNATURE_LIST header and GUID definitions
Michael Brown [Mon, 10 Mar 2025 11:20:15 +0000 (11:20 +0000)] 
[efi] Add EFI_SIGNATURE_LIST header and GUID definitions

Signed-off-by: Michael Brown <mcb30@ipxe.org>
4 months ago[efi] Update to current EDK2 headers
Michael Brown [Mon, 10 Mar 2025 11:19:26 +0000 (11:19 +0000)] 
[efi] Update to current EDK2 headers

Signed-off-by: Michael Brown <mcb30@ipxe.org>
4 months ago[build] Use -fshort-wchar when building EFI host utilities
Michael Brown [Mon, 10 Mar 2025 12:23:02 +0000 (12:23 +0000)] 
[build] Use -fshort-wchar when building EFI host utilities

The EFI host utilities (such as elf2efi64, efirom, etc) include the
EDK2 headers, which include static assertions to ensure that they are
built with -fshort-wchar enabled.  When building the host utilities,
we currently bypass these assertions by defining MDE_CPU_EBC.  The EBC
compiler apparently does not support static assertions, and defining
MDE_CPU_EBC therefore causes EDK2's Base.h to define STATIC_ASSERT()
as a no-op.

Newer versions of the EDK2 headers omit the check for MDE_CPU_EBC (and
will presumably therefore fail to build with the EBC compiler).  This
causes our host utility builds to fail since the static assertion now
detects that we are building with the host's default ABI (i.e. without
enabling -fshort-wchar).

Fix by enabling -fshort-wchar when building EFI host utilities.  This
produces binaries that are technically incompatible with the host ABI.
However, since our host utilities never handle any wide-character
strings, this nominal ABI incompatiblity has no effect.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
4 months ago[efi] Mark UsbHostController.h as a non-imported header
Michael Brown [Mon, 10 Mar 2025 11:15:04 +0000 (11:15 +0000)] 
[efi] Mark UsbHostController.h as a non-imported header

The UsbHostController.h header has been removed from the EDK2 codebase
since it was never defined in a released UEFI specification.  However,
we may still encounter it in the wild and so it is useful to retain
the GUID and the corresponding protocol name for debug messages.

Add an iPXE include guard to this file so that the EDK2 header import
script will no longer attempt to import it from the EDK2 tree.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
5 months ago[lkrnprefix] Support a longer version string
Michael Brown [Fri, 28 Feb 2025 11:27:21 +0000 (11:27 +0000)] 
[lkrnprefix] Support a longer version string

The bzImage specification allows two bytes for the setup code jump
instruction at offset 0x200, which limits its relative offset to +0x7f
bytes.  This currently imposes an upper limit on the length of the
version string, which currently precedes the setup code.

Fix by moving the version string to the .prefix.data section, so that
it no longer affects the placement of the setup code.

Originally-fixed-by: Miao Wang <shankerwangmiao@gmail.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
5 months ago[cpio] Allow for construction of parent directories as needed
Michael Brown [Mon, 24 Feb 2025 14:04:06 +0000 (14:04 +0000)] 
[cpio] Allow for construction of parent directories as needed

iPXE allows individual raw files to be automatically wrapped with
suitable CPIO headers and injected into the magic initrd image as
exposed to a booted Linux kernel.  This feature is currently limited
to placing files within directories that already exist in the initrd
filesystem.

Remove this limitation by adding the ability for iPXE to construct
CPIO headers for parent directories as needed, under control of the
"mkdir=<n>" command-line argument.  For example:

  initrd config.ign /usr/share/oem/config.ign mkdir=1

will create CPIO headers for the "/usr/share/oem" directory as well as
for the "/usr/share/oem/config.ign" file itself.

This simplifies the process of booting operating systems such as
Flatcar Linux, which otherwise require the single "config.ign" file to
be manually wrapped up as a CPIO archive solely in order to create the
relevant parent directory entries.

The value <n> may be used to control the number of parent directory
entries that are created.  For example, "mkdir=2" would cause up to
two parent directories to be created (i.e. "/usr/share" and
"/usr/share/oem" in the above example).  A negative value such as
"mkdir=-1" may be used to create all parent directories up to the root
of the tree.

Do not create any parent directory entries by default, since doing so
would potentially cause the modes and ownership information for
existing directories to be overwritten.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
5 months ago[menu] Allow a post-activity timeout to be defined 1413/head
Michael Brown [Wed, 19 Feb 2025 13:12:29 +0000 (13:12 +0000)] 
[menu] Allow a post-activity timeout to be defined

Allow the "--retimeout" option to be used to specify a timeout value
that will be (re)applied after each keypress activity.  This allows
script authors to ensure that a single (potentially accidental)
keypress will not pause the boot process indefinitely.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
5 months ago[crypto] Start up RBG on demand if needed 1411/head
Michael Brown [Tue, 18 Feb 2025 15:28:55 +0000 (15:28 +0000)] 
[crypto] Start up RBG on demand if needed

The ANS X9.82 specification implicitly assumes that the RBG_Startup
function will be called before it is needed, and includes checks to
make sure that Generate_function fails if this has not happened.
However, there is no well-defined point at which the RBG_Startup
function is to be called: it's just assumed that this happens as part
of system startup.

We currently call RBG_Startup to instantiate the DRBG as an iPXE
startup function, with the corresponding shutdown function
uninstantiating the DRBG.  This works for most use cases, and avoids
an otherwise unexpected user-visible delay when a caller first
attempts to use the DRBG (e.g. by attempting an HTTPS download).

The download of autoexec.ipxe for UEFI is triggered by the EFI root
bus probe in efi_probe().  Both the root bus probe and the RBG startup
function run at STARTUP_NORMAL, so there is no defined ordering
between them.  If the base URI for autoexec.ipxe uses HTTPS, then this
may cause random bits to be requested before the RBG has been started.

Extend the logic in rbg_generate() to automatically start up the RBG
if startup has not already been attempted.  If startup fails
(e.g. because the entropy source is broken), then do not automatically
retry since this could result in extremely long delays waiting for
entropy that will never arrive.

Reported-by: Michael Niehaus <niehaus@live.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
5 months ago[efi] Increase download timeout for autoexec.ipxe
Michael Brown [Mon, 17 Feb 2025 13:11:28 +0000 (13:11 +0000)] 
[efi] Increase download timeout for autoexec.ipxe

In almost all cases, the download timeout for autoexec.ipxe is
irrelevant: the operation will either succeed or fail relatively
quickly (e.g. due to a nonexistent file).  The overall download
timeout exists only to ensure that an unattended or headless system
will not wait indefinitely in the case of a degenerate network
response (e.g. an HTTP server that returns an endless trickle of data
using chunked transfer encoding without ever reaching the end of the
file).

The current download timeout is too short if PeerDist content encoding
is enabled, since the overall download will abort before the first
peer discovery attempt has completed, and without allowing sufficient
time for an origin server range request.

The single timeout value is currently used for both the download
timeout and the sync timeout.  The latter timeout exists only to allow
network communication to be gracefully quiesced before removing the
temporary MNP network device, and may safely be shortened without
affecting functionality.

Fix by increasing the download timeout from two seconds to 30 seconds,
and defining a separate one-second timeout for the sync operation.

Reported-by: Michael Niehaus <niehaus@live.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
5 months ago[crypto] Support direct reduction only for Montgomery constant R^2 mod N
Michael Brown [Thu, 13 Feb 2025 13:35:45 +0000 (13:35 +0000)] 
[crypto] Support direct reduction only for Montgomery constant R^2 mod N

The only remaining use case for direct reduction (outside of the unit
tests) is in calculating the constant R^2 mod N used during Montgomery
multiplication.

The current implementation of direct reduction requires a writable
copy of the modulus (to allow for shifting), and both the modulus and
the result buffer must be padded to be large enough to hold (R^2 - N),
which is twice the size of the actual values involved.

For the special case of reducing R^2 mod N (or any power of two mod
N), we can run the same algorithm without needing either a writable
copy of the modulus or a padded result buffer.  The working state
required is only two bits larger than the result buffer, and these
additional bits may be held in local variables instead.

Rewrite bigint_reduce() to handle only this use case, and remove the
no longer necessary uses of double-sized big integers.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
5 months ago[crypto] Expose shifted out bit from big integer shifts
Michael Brown [Thu, 13 Feb 2025 14:18:15 +0000 (14:18 +0000)] 
[crypto] Expose shifted out bit from big integer shifts

Expose the bit shifted out as a result of shifting a big integer left
or right.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
5 months ago[bnxt] Allocate TX rings with firmware input
Joseph Wong [Thu, 23 Jan 2025 00:06:18 +0000 (16:06 -0800)] 
[bnxt] Allocate TX rings with firmware input

Use queue_id value retrieved from firmware unconditionally when
allocating TX rings.

Signed-off by: Joseph Wong <joseph.wong@broadcom.com>

6 months ago[malloc] Ensure free memory blocks remain aligned
Michael Brown [Mon, 3 Feb 2025 14:43:03 +0000 (14:43 +0000)] 
[malloc] Ensure free memory blocks remain aligned

When allocating memory with a non-zero alignment offset, the free
memory block structure following the allocation may end up improperly
aligned.

Ensure that free memory blocks always remain aligned to the size of
the free memory block structure.

Ensure that the initial heap is also correctly aligned, thereby
allowing the logic for leaking undersized free memory blocks to be
omitted.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
6 months ago[malloc] Clean up debug messages
Michael Brown [Mon, 3 Feb 2025 14:41:35 +0000 (14:41 +0000)] 
[malloc] Clean up debug messages

Signed-off-by: Michael Brown <mcb30@ipxe.org>
6 months ago[crypto] Add definitions and tests for the NIST P-384 elliptic curve
Michael Brown [Thu, 30 Jan 2025 15:35:34 +0000 (15:35 +0000)] 
[crypto] Add definitions and tests for the NIST P-384 elliptic curve

Signed-off-by: Michael Brown <mcb30@ipxe.org>
6 months ago[crypto] Add definitions and tests for the NIST P-256 elliptic curve
Michael Brown [Wed, 22 Jan 2025 13:07:23 +0000 (13:07 +0000)] 
[crypto] Add definitions and tests for the NIST P-256 elliptic curve

Signed-off-by: Michael Brown <mcb30@ipxe.org>