Commit Graph

7283 Commits

Author SHA1 Message Date
Michael Brown
30948987fd [build] Mark existing files as explicitly forbidden for Secure Boot
The third-party 802.11 stack and NFS protocol code are known to
include multiple potential vulnerabilities and are explicitly
forbidden from being included in Secure Boot signed builds.  This is
currently handled at the per-directory level by defining a list of
source directories (SRCDIRS_INSEC) that are to be excluded from Secure
Boot builds.

Annotate all files in these directories with FILE_SECBOOT() to convey
this information to the new per-file Secure Boot permissibility check,
and remove the old separation between SRCDIRS and SRCDIRS_INSEC.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2026-01-13 15:18:16 +00:00
Michael Brown
b09af00fab [efi] Mark imported EDK2 headers as permitted for Secure Boot
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2026-01-13 15:18:16 +00:00
Michael Brown
c5ae9ec99c [efi] Update to current EDK2 headers
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2026-01-13 13:58:17 +00:00
Michael Brown
e61c636bf3 [build] Define a mechanism for marking Secure Boot permissibility
Not all files within the iPXE codebase are allowed to be included in
UEFI Secure Boot signed builds.

Following the pattern used by the existing FILE_LICENCE() macro and
licensing check: define a FILE_SECBOOT() macro that can be used to
declare a file as being permitted (or forbidden) in a UEFI Secure Boot
signed build, and a corresponding build target to perform the check.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2026-01-13 13:49:27 +00:00
Michael Brown
9c01c5a5da [neighbour] Treat delayed transmissions as pending operations
Treat each delayed transmission as a pending operation, so that the
"sync" command can be used to ensure that all delayed packets have
been transmitted.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2026-01-10 14:43:24 +00:00
Michael Brown
2110afb351 [tcp] Report TCP statistics via the "ipstat" command
Gather some basic statistics on TCP connections to allow out-of-order
packets and duplicate packets to be observed even in non-debug builds.

Report these statistics via the existing "ipstat" command, rather than
introducing a separate "tcpstat" command, on the basis that we do not
need the additional overhead of a separate command.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2026-01-09 16:36:52 +00:00
Michael Brown
a8c89276cc [malloc] Increase heap size to 4MB
Commit 2d180ce ("[tcp] Update maximum window size to 2MB") increased
the TCP window size to avoid filling the TCP window on typical modern
links.

The total heap size is only 512kB.  Given that RX I/O buffers are
typically subject to alignment constraints, it is plausible that we
may be able to actually buffer only 256kB of data before having to
discard queued out-of-order packets.

On a low latency network, this behaviour is not a problem: the sender
will rapidly retransmit the lost or discarded packets.  On a high
latency network, the sender's congestion control algorithm will end up
calculating a congestion window that is substantially smaller than our
advertised 2MB, which will result in a drastic reduction in actual
throughput.

We do not want to increase the heap size arbitrarily, since we still
have the constraint that memory used by iPXE may be permanently lost
to the operating system (depending on how the operating system is
booted).  However, the cost of keeping the heap size down to 512kB is
no longer acceptable given that large downloads over high-speed
wide-area networks are now routine.

Increase the heap size from 512kB to 4MB.  This should be sufficient
to hold an entire 2MB TCP window for a single connection under most
sensible conditions.  For example:

  * 1460-byte MSS => 1436 packets => 2872kB of 2kB RX I/O buffers

  * 8960-byte MSS => 234 packets => 3744kB of 16kB RX I/O buffers

The notable exception is that of a network where jumbo frames are in
use, but the TCP connection ends up using a standard 1460-byte MSS.
If this is found to be an issue in practice, then one possible
solution would be to shrink (or reallocate) I/O buffers for
out-of-order queued data.

Experimentation shows that before this change, an induced latency of
25ms (representative of a typical connection to a public cloud
provider) would cause the download speed to vary unpredictably between
2MB/s and 25MB/s.  After this change, the speed in this test scenario
remains consistently high at 25MB/s.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2026-01-09 15:20:25 +00:00
Michael Brown
8e557f1ab0 [tcp] Discard packets that lie immediately before the receive window
We will currently enqueue (rather than discard) retransmitted packets
that lie immediately before the current receive window.  These packets
will be harmlessly discarded when the receive queue is processed
immediately afterwards, but cause confusion when attempting to debug
TCP performance issues.

Fix by adjusting the comparison so that packets that lie immediately
before the receive window will be discarded immediately and never
enqueued.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2026-01-09 13:18:20 +00:00
Michael Brown
ff6d612e72 [neighbour] Add the ability to artificially delay outbound packets
Add a fault-injection mechanism that allows an arbitrary delay
(configured via config/fault.h) to be added to any packets transmitted
via the neighbour resolution mechanism, as a way of reproducing
symptoms that occur only on high-latency connections such as a
satellite uplink.

The neighbour discovery mechanism is not a natural conceptual fit for
this artficial delay, since neighbour discovery has nothing to do with
transmit latency.  However, the neighbour discovery mechanism happens
to already include a deferred transmission queue that can be (ab)used
to implement this artifical delay in a minimally intrusive way.  In
particular, there is zero code size impact on a standard build with no
artificial delay configured.

Implementing the delay only for packets transmitted via neighbour
resolution has the side effect that broadcast packets (such as DHCP
and ARP) are unaffected.  This is likely in practice to produce a
better emulation of a high-latency uplink scenario, where local
network traffic such as DHCP and ARP will complete quickly and only
the subsequent TCP/UDP traffic will experience delays.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2026-01-06 15:38:50 +00:00
Michael Brown
33c832b0d9 [neighbour] Split out deferred transmission from discovery completion
Split out the logic for transmitting any deferred packets as a
separate function, as a precursor to supporting the ability to add
deliberate latency to transmitted packets.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2026-01-06 15:19:20 +00:00
Michael Brown
aabfb8a94d [neighbour] Use discovery protocol field to identify incomplete neighbours
Use the discovery protocol pointer field (rather than the running
state of the discovery timer) to determine whether or not neighbour
discovery is ongoing, as a precursor to allowing the timer to be
(ab)used for adding deliberate latency to transmitted packets.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2026-01-06 15:19:15 +00:00
Michael Brown
d0e01bb3fc [neighbour] Always use network device's own link-layer address
The API for neighbour_tx() allows for an explicit source link-layer
address, but this will be ignored if the packet is deferred for
transmission after completion of neighbour discovery.  The network
device's own link-layer address will always be used when sending
neighbour discovery packets, and when sending any deferred packets
after discovery completes.

All callers pass in the network device's own link-layer address as the
source address anyway, and so this explicit source link-layer address
is never used for any meaningful purpose.

Simplify the neighbour_tx() API by removing the ability to pass in an
explicit source link-layer address.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2026-01-05 14:22:16 +00:00
Michael Brown
7c39c04a53 [crypto] Allow for zero-length big integer literals
Ensure that zero-length big integer literals are treated as containing
a zero value.  Avoid tests on every big integer arithmetic operation
by ensuring that bigint_required_size() always returns a non-zero
value: the zero-length tests can therefore be restricted to only
bigint_init() and bigint_done().

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-12-29 14:01:46 +00:00
Michael Brown
01038893a3 [test] Update big integer tests to use okx()
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-12-29 13:18:10 +00:00
Michael Brown
3832147944 [crypto] Fix identification of non-wrapped elliptic curve identifiers
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-12-22 16:14:06 +00:00
Michael Brown
5aab6b7a31 [crypto] Add ECDSA-based TLS cipher suites
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-12-19 18:18:45 +00:00
Michael Brown
f1e23b53a7 [test] Add test cases for X.509 certificates with ECDSA signatures
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-12-19 15:26:29 +00:00
Michael Brown
d6eeb9039f [crypto] Add OID-identified algorithms for ECDSA with SHA2 hash family
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-12-19 15:26:29 +00:00
Michael Brown
d14066e924 [crypto] Allow ecPublicKey to be identified as a public-key algorithm
Add a public-key algorithm to the definition of the "ecPublicKey"
OID-identified algorithm, and move this definition to ecdsa.c to avoid
unconditionally dragging in ECDSA support.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-12-19 15:26:29 +00:00
Michael Brown
f3147b42a1 [test] Ensure OID-identified algorithms are present for X.509 tests
The algorithms required for the X.509 tests are accessed indirectly
via their OID-identified algorithms, rather than directly via symbols.
Ensure that the required OID-identified algorithm definitions are
included regardless of the configuration in config/crypto.h.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-12-19 14:24:27 +00:00
Michael Brown
aa247f6e38 [x509] Correct debug message
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-12-19 13:54:24 +00:00
Michael Brown
4e3cbeef83 [crypto] Add support for ECDSA signatures
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-12-19 10:06:50 +00:00
Michael Brown
948677fe5e [test] Test verification of constructed signature
Some signature schemes (such as ECDSA) allow for non-deterministic
signatures.  Provide more information in test results by performing
verification of the constructed signature even when it does not match
the expected test case result: this allows us to distinguish between a
bug that is generating invalid signatures and a bug that is generating
valid but non-canonical signatures.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-12-18 23:10:57 +00:00
Michael Brown
cfbf0da93c [crypto] Allow for an explicit representation of point at infinity
ECDSA requires the ability to add two arbitrary curve points, either
of which may legitimately be the point at infinity.

Update the API so that curves must choose an explicit affine
representation for the point at infinity, and provide a method to test
for this representation.  Multiplication and addition will now allow
this representation to be provided as an input, and will not fail if
the result is the point at infinity.  Callers must explicitly check
for the point at infinity where needed (e.g. after computing the ECDHE
shared secret curve point).

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-12-18 15:47:29 +00:00
Michael Brown
af99310f55 [test] Test signature verification independently of signing
Copy and modify the signature defined within the test case for
verification tests, rather than relying on the modifiable signature
constructed by the signing portion of the same test.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-12-17 20:38:21 +00:00
Christian I. Nilsson
3d5cd3d79e [intel] Add PCI ID for I219-V and -LM 24
Signed-off-by: Christian I. Nilsson <nikize@gmail.com>
2025-12-15 21:47:19 +01:00
Michael Brown
86c40a8b1e [efi] Retry calls to GetRNG() as needed
The UEFI specification allows GetRNG() to return EFI_NOT_READY, which
is not a particularly helpful error status since there is nothing that
can sensibly be done except to retry immediately.

Retry failed calls to GetRNG() up to a maximum number of attempts.

Debugged-by: Stoo Davies <sdavies@nvidia.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-12-12 07:33:55 +00:00
Michael Brown
fb1188936c [crypto] Generalise rsa_parse_integer() to asn1_enter_unsigned()
ECDSA signature values and private keys are fixed-length unsigned
integers modulo N (the group order of the elliptic curve) and are
therefore most naturally represented in ASN.1 using ASN1_OCTET_STRING.

Private key representations do use ASN1_OCTET_STRING, but signature
values tend to use ASN1_INTEGER, which adds no value but does ensure
that the encoding becomes variable-length and requires handling a
pointless extra zero byte if the MSB of the unsigned value happens to
be set.

RSA also makes use of ASN1_INTEGER for modulus and exponent values.
Generalise the existing rsa_parse_integer() to asn1_enter_unsigned()
to allow this code to be reused for ECDSA.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-12-11 15:09:58 +00:00
Michael Brown
c7f129fede [crypto] Allow for addition of arbitrary Weierstrass curve points
ECDSA verification requires the ability to add two arbitrary curve
points (as well as the ability to multiply a curve point by a scalar).

Add an elliptic curve method to perform arbitrary point addition.
Pass in curve points as affine coordinates: this will require some
redundant conversions between affine coorfinates and the internal
representation as projective coordinates in Montgomery form, but keeps
the API as simple as possible.  Since we do not expect to perform a
high volume of ECDSA signature verifications, these redundant
calculations are an acceptable cost for keeping the code simple.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-12-08 14:24:24 +00:00
Michael Brown
1e353ff361 [crypto] Split out Weierstrass point initialisation and finalisation
Prepare for adding an operation to add arbitrary curve points by
splitting out initialisation and finalisation from the multiplication
operation.

Pass explicit temporary buffer pointers to weierstrass_init() and
weierstrass_done(), to ensure that stack consumption does not increase
as a result of splitting out this functionality.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-12-05 16:13:02 +00:00
Michael Brown
d3adea8380 [crypto] Expose the (prime) group order as an elliptic curve property
ECDSA requires knowledge of the group order of the base point, and is
defined only for curves with a prime group order (e.g. the NIST
curves).

Add the group order as an explicit property of an elliptic curve, and
add tests to verify that the order is correct.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-12-05 15:10:22 +00:00
Michael Brown
80e98dc0d1 [crypto] Verify that weierstrass_multiply() result is not point at infinity
The point at infinity cannot be represented in affine coordinates, and
so cannot be returned as a valid result from weierstrass_multiply().

The implementation uses projective coordinates internally, in which a
point at infinity is represented by a zero Z-coordinate.  Treat a zero
Z-coordinate as an invalid result.

The projective coordinates are calculated modulo 4N, and so a zero
value may be represented as 0, N, 2N, or 3N.  To minimise code size,
defer the test until after inverting the Z co-ordinate via Fermat's
little theorem via bigint_mod_exp_ladder() (which will calculate the
inverse of zero as zero, and will always produce a result strictly
modulo N).

Defer the test further until after converting the result back to
affine coordinates, to allow the debug message showing the
multiplication result to be printed.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-12-05 15:10:22 +00:00
Michael Brown
b362f77bdf [test] Allow for elliptic curve tests other than multiplication
Rename elliptic_ok() to elliptic_multiply_ok() etc, to create
namespace for tests of other elliptic curve operations.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-12-05 13:19:05 +00:00
Michael Brown
e50e30a7f8 [crypto] Expose the base point as an explicit elliptic curve property
Add the generator base point as an explicit property of an elliptic
curve, and remove the ability to pass a NULL to elliptic_multiply() to
imply the use of the generator base point.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-12-05 13:09:07 +00:00
Michael Brown
88c3e68dfb [http] Abort connections after a long period of inactivity
Once an HTTP download has started (i.e. once all request headers have
been sent), we generally have no more data to transmit.  If an HTTP
connection dies silently (e.g. due to a network failure, a NIC driver
bug, or a server crash) then there is no mechanism that will currently
detect this situation by default.

We do send TCP keep-alives (to maintain state in intermediate routers
and firewalls), but we do not attempt to elicit a response from the
server.  RFC 9293 explicitly states that the absence of a response to
a TCP keep-alive probe must not be interpreted as indicating a dead
connection, since TCP cannot guarantee reliable delivery of packets
that do not advance the sequence number.

Scripts may use the "--timeout" option to impose an overall time limit
on downloads, but this mechanism is off by default and requires
additional thought and configuration by the user (which goes against
iPXE's general philosophy of being as automatic as possible).

Add an idle connection watchdog timer which will cause the HTTP
download to abort after 120 seconds of inactivity.  Activity is
defined as an I/O buffer being delivered to the HTTP transaction's
upstream data transfer interface.

Downloads over HTTPS may experience a substantial delay until the
first recorded activity, since all TLS negotiation (including
cross-chained certificate downloads and OCSP checks) must complete
before any application data can be sent.  We choose to not reset the
watchdog timer during TLS negotiation, on the basis that 120 seconds
is already an unreasonably long time for a TLS negotiation to take to
complete.  If necessary, resetting the watchdog timer could be
accomplished by having the TLS layer deliver zero-length I/O buffers
(via xfer_seek()) to indicate forward progress being made.

When using PeerDist content encoding, the downloaded content
information is not passed through to the content-decoded interface and
so will not be classed as activity.  Any activity in the individual
PeerDist block downloads (either from peers or as range requests from
the origin server) will be classed as activity in the overall
download, since individual block downloads do not buffer data but
instead pass it through directly via the PeerDist download
multiplexer.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-12-04 14:47:45 +00:00
Michael Brown
1a789c1daa [http] Rename connection retry timer
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-12-04 14:47:45 +00:00
Michael Brown
64f936d5df [crypto] Allow for OID-identified elliptic curve algorithms
Elliptic curves in X.509 certificates are identified via the
id-ecPublicKey object identifier (1.2.840.10045.2.1), with the
specific elliptic curve identified via a second OID in the algorithm
parameters.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-12-03 15:45:14 +00:00
Michael Brown
e6610b793a [test] Include key matching in existing public-key tests
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-12-03 15:29:33 +00:00
Michael Brown
3e566818f7 [crypto] Remove obsolete maximum output length method
Now that public-key algorithms use ASN.1 builders to dynamically
allocate the output data, there is no further need for callers to be
able to determine the maximum output length.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-12-02 13:13:01 +00:00
Michael Brown
1ccc320ee9 [crypto] Construct asymmetric ciphered data using ASN.1 builders
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-12-02 13:12:25 +00:00
Michael Brown
d4258272c6 [crypto] Construct signatures using ASN.1 builders
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-12-01 16:02:54 +00:00
Michael Brown
8cd963ab96 [crypto] Pass signatures for verification as ASN.1 cursors
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-12-01 14:50:54 +00:00
Michael Brown
c9c0282594 [crypto] Restructure handling of ASN.1 bit strings
Signature values in ASN.1 tend to be encoded as bit strings rather
than octet strings.  In practice, no existent signature scheme uses a
non-integral number of bytes.

Switch to using a standard ASN.1 cursor to hold signature values, to
simplify consuming code.  Restructure the API to treat entering an
ASN.1 bit string in the same way as entering any other ASN.1 type.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-12-01 13:09:45 +00:00
Bert Ezendam
d73981aece [intel] Add PCI IDs for I225 and I226 chipsets
Identifiers are taken from the pci.ids database.

Signed-off-by: Bert Ezendam <bert.ezendam@alliander.com>
2025-11-26 14:14:02 +00:00
Michael Brown
19dffdc836 [efi] Allow for creating devices with no EFI parent device
On some systems (observed on an AWS m8g.medium instance in eu-west-2),
the UEFI firmware fails to enumerate some of the underlying hardware
devices.  On these systems, we cannot comply with the UEFI device
model by adding our SNP device as a child of the hardware device and
appending to the parent hardware device path, since no parent hardware
device has been created.

Work around these systems by allowing for the creation of SNP devices
with no parent device.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-11-25 12:04:43 +00:00
Michael Brown
dfea3bbfad [pci] Use runtime selectable PCI I/O API for EFI cloud builds
On some systems (observed on an AWS m8g.medium instance in eu-west-2),
the UEFI firmware omits the PCI host bridge drivers for all but the
first PCI bus.  The observable result is that any devices on other PCI
buses (such as the ENA network device) are not enumerated by the UEFI
firmware and are therefore unusable by iPXE.

Support these systems by switching to using PCIAPI_CLOUD for EFI cloud
builds, trying the EFI PCI I/O API first and falling back to direct
access (via ECAM) for devices that the UEFI firmware has failed to
enumerate itself.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-11-24 23:25:31 +00:00
Michael Brown
9c1ac48bcf [pci] Allow probing permission to vary by range
Make pci_can_probe() part of the runtime selectable PCI I/O API, and
defer this check to the per-range API.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-11-24 23:16:32 +00:00
Michael Brown
ff1a17dc7e [pci] Use linker tables for runtime selectable PCI APIs
Use the linker table mechanism to enumerate the underlying PCI I/O
APIs, to allow PCIAPI_CLOUD to become architecture-independent code.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-11-24 20:54:01 +00:00
Michael Brown
0cf2f8028c [pci] Allow PCI configuration space access mechanism to vary by range
On some systems (observed on an AWS EC2 c7a.medium instance in
eu-west-2), there is no single PCI configuration space access
mechanism that covers all PCI devices.  For example: the ECAM may
provide access only to bus 01 and above, with type 1 accesses required
to access bus 00.

Allow the choice of PCI configuration space access mechanism to be
made on a per-range basis, rather than being made just once in an
initialisation function.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-11-24 19:10:49 +00:00
Michael Brown
81496315f2 [arm] Avoid unaligned accesses for memcpy() and memset()
iPXE runs only in environments that support unaligned accesses to RAM.
However, memcpy() and memset() are also used to write to graphical
framebuffer memory, which may support only aligned accesses on some
CPU architectures such as ARM.

Restructure the 64-bit ARM memcpy() and memset() routines along the
lines of the RISC-V implementations, which split the region into
pre-aligned, aligned, and post-aligned sections.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-11-19 22:20:38 +00:00