7538 Commits

Author SHA1 Message Date
Michael Brown e5d0c804ee [s390x] Add support for the PRNO TRNG as an entropy source
The "prno" instruction available on newer CPUs provides a hardware
True Random Number Generator (TRNG) that can be used as an entropy
source, similar to the x86 "rdrand" instruction.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2026-06-28 20:09:23 +01:00
Michael Brown 9f088838bc [s390x] Provide a mechanism for checking installed CPU facilities
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2026-06-28 20:05:55 +01:00
Michael Brown 902014c57a [crypto] Remove redundant DHE algorithm
Remove the now-unused implementation of DHE that requires explicit
group parameters, since we now use a standalone key exchange algorithm
abstraction instead.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2026-06-25 13:45:44 +01:00
Michael Brown cc01b6c3ab [tls] Use generic key exchange algorithm abstraction for DHE
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2026-06-25 13:39:47 +01:00
Michael Brown e50c7cb4de [crypto] Allocate FFDHE temporary space on demand
Now that key exchange algorithms are allowed to fail to construct a
shared public key, we can allocate the temporary working space for
FFDHE calculations on demand rather than using a static buffer.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2026-06-25 12:37:24 +01:00
Michael Brown dd6411065e [crypto] Allow construction of shared public key to return an error
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2026-06-25 12:13:26 +01:00
Michael Brown 0a92256530 [crypto] Correct maximum length of FFDHE prime modulus
Commit 70d63be ("[crypto] Add RFC 3526 FFDHE key exchange algorithms")
defined FFDHE_LEN as a fixed value (rather than deriving it from the
stored length of the Euler constant) and accidentally expressed it as
a bit length rather than a byte length, resulting in substantial
amounts of wasted space.

Fix the maximum length of the modulus and add static assertions to
ensure that the two constants are exactly the required size for this
length.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2026-06-25 12:13:26 +01:00
Michael Brown 327378a764 [crypto] Generalise implementation of Merkle-Damgård hash algorithms
All of our current digest algorithms (MD4, MD5, SHA-1, and the SHA-2
family) use a Merkle-Damgård construction, with only the compression
function, the initial digest values, the field sizes, and the
endianness differing between algorithms.

Provide a common implementation for Merkle-Damgård hash algorithms to
reduce code size.  Values are now held as host-endian quantities, with
any swapping performed byte-by-byte as data is accumulated (using a
compile-time constant that is XORed with the byte index).

For the SHA family of algorithms, the values w[] are now calculated
iteratively as we progress through the main loop: this substantially
reduces the stack space required for the compression function.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2026-06-23 13:24:22 +01:00
Animesh Bhatt 449d2acf3d [aqc1xx] Free outstanding receive I/O buffers on close
atl_close() freed the descriptor rings but left the posted receive I/O
buffers allocated, leaking them and tripping an assertion on the next
open.  Free any outstanding receive I/O buffers in atl_close().

Signed-off-by: Animesh Bhatt <animeshb@marvell.com>
2026-06-23 11:00:49 +01:00
Animesh Bhatt 56347b2612 [aqc1xx] Set netdev->dma for operation with an IOMMU
On AQC113 adapters with an IOMMU (e.g. Intel VT-d) enabled, no packets
are received and DHCP fails: the driver never set netdev->dma, leaving
the transmit buffers unmapped for DMA.  This worked without an IOMMU
because the physical address equals the device address, but with an
IOMMU the unmapped DMA access faults and stalls the receive path.  Set
netdev->dma and a 64-bit DMA mask so that transmit buffers are mapped
through the firmware IOMMU, as done by the other iPXE drivers.

Signed-off-by: Animesh Bhatt <animeshb@marvell.com>
2026-06-23 11:00:36 +01:00
Michael Brown 0daeb3e645 [http] Remove knowledge of MD5 digest context internal structure
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2026-06-23 10:28:37 +01:00
Joseph Wong 781b8d616f [bnxt] Prevent out-of-bounds memory access
Add boundary checks to prevent out-of-bounds memory accesses in RX and
HWRM paths.

Signed-off-by: Joseph Wong <joseph.wong@broadcom.com>
2026-06-22 10:11:56 +01:00
Michael Brown d75a9670be [tls] Centralise pseudorandom data generation
TLS version 1.3 has a formal key schedule based on HKDF, and requires
the client to be able to recall ephemeral secrets at multiple points
within the connection lifecycle.  For example: the ephemeral private
key for X25519 key exchange may be required when constructing
ClientHello (for a TLS version 1.3 key share) or when constructing
ClientKeyExchange (if subsequently falling back to use TLS version
1.2), and again when parsing a ServerHello key share or a
ServerKeyExchange.

Some ephemeral private keys may be large (e.g. for ffdhe4096).  Avoid
the need to store these large (and variably sized) private keys by
instead instantiating a standalone HKDF instance that we seed with
per-connection random data and subsequently use to generate ephemeral
private keys on demand.  (Note that this instance is unrelated to the
HKDF instance defined in the formal key schedule for TLS: we are
choosing to reuse HKDF for this purpose simply because supporting TLS
version 1.3 will already require HKDF support to be present.)

We use the key exchange algorithm name (e.g. "x25519") as additional
information to ensure separation between keys used for different
purposes.  Since the initial random seed is generated afresh for each
connection, and since there can meaningfully be only one ephemeral
private key per key exchange algorithm per connection, this is
sufficient to ensure separation.

Having instantiated this HKDF, we then also use it to generate the
client random bytes (with the label "client random"), to generate the
random portion of the pre-master secret for classic RSA key exchange
(with the label "classic pre-master"), and to generate the random
portion of record IVs (using the authentication header structure,
which is already guaranteed to be unique per record within a
connection).  Doing this allows us to eliminate all other calls to the
RNG, and removes some potential failure paths.

We reset the HKDF on a connection restart and on connection close, to
preserve the property of forward secrecy.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2026-06-20 15:53:39 +01:00
Michael Brown a2eba23ace [crypto] Allow for input keying material to overlap output
Calling hkdf_extract() with no salt and with the input keying material
provided in the same buffer that will hold the output pseudorandom key
is a valid potential use case.  This will currently fail silently
since the input keying material would be overwritten by the
constructed all-zero salt before being consumed.

Fix by using a local buffer for the all-zero salt, rather than
constructing the salt in the output buffer.

Document the permitted behaviour in terms of overlapping input and
output buffers for both hkdf_extract() and hkdf_expand(), and extend
the test cases to verify this behaviour.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2026-06-20 14:43:36 +01:00
Michael Brown 846686325c [crypto] Use private data field for public-key algorithms
Following the example of commit 25072c1 ("[crypto] Use private data
field for key exchange algorithms"), extend the definition of a
public-key algorithm to include an opaque private data field, and use
this to eliminate the wrapper functions for PKCS#1 and RSA-PSS.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2026-06-19 14:54:03 +01:00
Michael Brown 2420211e7f [crypto] Allow cipher_setiv() to return an error
GCM ciphers can accept initialisation vectors of any length.  Move the
responsibility for checking the initialisation vector length from the
caller into the implementation of cipher_setiv().

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2026-06-19 14:11:46 +01:00
Michael Brown 21babfc392 [crypto] Use private data field for cipher algorithms
Following the example of commit 25072c1 ("[crypto] Use private data
field for key exchange algorithms"), extend the definition of a cipher
algorithm to include an opaque private data field, and use this to
eliminate the wrapper functions generated for the various block cipher
modes of operation by ECB_CIPHER(), CBC_CIPHER(), and GCM_CIPHER().

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2026-06-19 13:26:00 +01:00
Michael Brown d7e89f46b4 [crypto] Use private data field for digest algorithms
Following the example of commit 25072c1 ("[crypto] Use private data
field for key exchange algorithms"), extend the definition of a digest
algorithm to include an opaque private data field.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2026-06-18 15:54:19 +01:00
Michael Brown 69e95ae7a5 [crypto] Generalise notion of uncompressed elliptic curve points
With algorithm private data pointers now available, the general
mechanism for key exchange using uncompressed elliptic curve points
can be separated from the Weierstrass curve implementation.

Generalise the mechanism for performing elliptic curve key exchange
using uncompressed affine co-ordinates.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2026-06-18 14:31:29 +01:00
Michael Brown af0e5d529b [crypto] Use private data field for elliptic curve algorithms
Following the example of commit 25072c1 ("[crypto] Use private data
field for key exchange algorithms"), extend the definition of an
elliptic curve to include an opaque private data field, and use this
to eliminate the wrapper functions generated by WEIERSTRASS_CURVE().

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2026-06-18 13:18:18 +01:00
Michael Brown 38fc660d8b [crypto] Use verbs in key exchange method names
Almost all cryptographic algorithm method names are currently verbs
(e.g. pubkey_sign(), cipher_encrypt(), digest_update(), etc).

Rename the two key exchange methods to also use verbs, for the sake of
consistency and to better match the TLS usage of "key_share".

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2026-06-18 12:15:04 +01:00
Michael Brown bbb6477be3 [tls] Accept only explicitly supported FFDHE groups
We do not currently perform any validation on the DHE field prime or
generator.  RFC 7919 defines a family of known-safe finite fields, and
TLS version 1.3 completely removes the ability to provide an explicit
field prime and generator.

Verify that the field prime and generator correspond to one of the
explicitly configured groups.

This may break connections to the (now very rare) TLS servers that use
custom FFDHE groups and that choose to use DHE rather than ECDHE (or
that do not support ECDHE).  We already advertise ECDHE cipher suites
as preferred over DHE cipher suites, and advertise all ECDHE groups as
preferred over all FFDHE groups.  It is therefore very unlikely that
this change will cause any issues in practice.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2026-06-17 16:35:22 +01:00
Michael Brown 241c36a6a2 [crypto] Add TLS named groups for FFDHE key exchange algorithms
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2026-06-17 16:06:56 +01:00
Michael Brown daee5deba8 [tls] Allow for the existence of anonymous named groups
The RFC 3526 FFDHE groups may plausibly be used by TLS servers, but do
not have IANA-assigned codes.

Allow for the existence of TLS named groups that have no code value
(and can therefore be identified only by matching the group parameter
values).

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2026-06-17 16:06:53 +01:00
Michael Brown 416920c656 [tls] Prefer X25519 as a key exchange mechanism
In TLS version 1.3, the expected flow is that the client offers at
least one key share in the initial ClientHello, so that key exchange
can take place as soon as the ServerHello is received (without
requiring a HelloRetryRequest and a second round trip).

We cannot viably offer key shares for all supported groups, since the
FFDHE groups have large public key values.  The most likely approach
will be that we offer a single key share for our most preferred group.

Experiments suggest that X25519 is currently the most widely supported
key exchange group.  Make this the most preferred group to maximise
the chance that a (future) TLS version 1.3 handshake will avoid the
extra round trip for a HelloRetryRequest.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2026-06-17 15:43:54 +01:00
Michael Brown c43c2829ec [crypto] Provide a mechanism to check FFDHE group parameters
Provide is_ffdhe() and ffdhe_has_params() as a way to check if a key
exchange algorithm happens to match against an explicit pair of prime
modulus and generator values.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2026-06-17 13:38:58 +01:00
Michael Brown 25072c1905 [crypto] Use private data field for key exchange algorithms
For historical reasons, TLS versions 1.2 and earlier identify FFDHE
groups by specifying the raw group prime and generator (the "dh_p" and
"dh_g" fields in ServerDHParams), rather than using a numeric code to
identify a named group.

This adds complexity to the process of identifying the internal key
exchange algorithm.  One option would be to extend the definition of
struct tls_key_exchange_algorithm to include the identifying values
for the field prime and generator, but this is undesirable since the
field prime values may be large, and these values are already
available (indirectly) in ffdhe.c.

Extend our definition of a key exchange algorithm to include an opaque
private data field.  This allows us to remove the wrapper functions
currently created by FFDHE_GROUP() and WEIERSTRASS_CURVE(), and opens
up the option of accessing the existing FFDHE field prime and
generator values from within the TLS layer.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2026-06-17 13:38:50 +01:00
Michael Brown 70d63bec94 [crypto] Add RFC 3526 FFDHE key exchange algorithms
The family of finite fields defined in RFC 7919 is almost identical to
that defined in RFC 3526, with the difference being that the older
standard uses the constant "pi" rather than "e".

Extend the definition of an FFDHE group to include a pointer to the
group constant, add the value of "pi", and define the modp2048,
modp3072, and modp4096 FFDHE groups.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2026-06-17 13:38:50 +01:00
Michael Brown cd873a2b5d [crypto] Use inline assembly for bigint_grow() and bigint_shrink()
The bigint_grow() and bigint_shrink() functions are used on the fast
path for big integer calculations (e.g. within the X25519 Montgomery
ladder step).  Use inline assembly implementations of these functions
on all architectures.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2026-06-16 16:07:09 +01:00
Michael Brown 73d437859d [s390x] Use XOR-in-place to zero small fixed-length blocks
The XOR instruction has a storage-and-storage format "xc" that can be
used to zero small blocks of memory without needing to set up the four
registers required for "mvcle".

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2026-06-16 14:40:36 +01:00
Michael Brown 1a0ebb9ba5 [tls] Rename "named curve" to "named group"
RFC 7919 renames the NamedCurve enumeration to NamedGroup, reflecting
its extended usage to handle key exchange groups that are not
constructed using elliptic curves.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2026-06-16 14:21:08 +01:00
Michael Brown fe070bf2de [virtio] Ignore capabilities that describe inaccessible PCI BARs
In some configurations, newer versions of QEMU will end up placing the
modern interface's BAR4 above 4GB, rendering it inaccessible in a
32-bit build of iPXE.  We will currently detect the existence of the
modern interface and attempt to use it, but fail at the point of
attempting to map the PCI BARs.

Fix by ignoring any virtio capabilities that describe an inaccessible
PCI BAR, and thereby allowing iPXE to fall back to using the legacy
interface if the modern interface's BAR cannot be used.

Reported-by: Jan ONDREJ (SAL) <ondrejj@salstar.sk>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2026-06-16 13:17:31 +01:00
Michael Brown 22564dd26b [settings] Allow system time to be modified via builtin/unixtime
Allow the system time offset to be modified by writing a new time
value to builtin/unixtime, e.g.:

  set builtin/unixtime 0x10d1a884

As with the NTP client, this does not attempt to write to the
underlying clock source (e.g. the RTC clock).  Only the internal
system time offset is updated.

Any system time offset may be reset by clearing the setting:

  clear builtin/unixtime

This will reset the system time offset to zero and so can be used to
undo the effect of a previous "set builtin/unixtime" or "ntp" command.

Requested-by: Christian I. Nilsson <ChristianN@2PintSoftware.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2026-06-15 16:12:34 +01:00
Michael Brown 807d933cea [settings] Allow for writable built-in settings
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2026-06-15 16:02:12 +01:00
Michael Brown 06f36026d6 [scsi] Use data-transfer buffers for data-in and data-out
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2026-06-15 14:20:16 +01:00
Michael Brown 13a83f4ab3 [s390x] Add optimised TCP/IP checksumming
Add an S/390 assembly language implementation of TCP/IP checksumming,
using the hardware "cksm" instruction to first calculate the 32-bit
one's complement checksum and then folding down to 16 bits.

Use an inline function since the whole checksum calculation (including
folding) requires only six instructions.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2026-06-14 17:18:05 +01:00
Michael Brown 51e8ffc4f8 [ci] Add s390x self-tests
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2026-06-14 13:39:22 +01:00
Michael Brown aa105c2dc0 [s390x] Add support for the IBM s390x CPU architecture
Add support for building iPXE as a 64-bit s390x binary for the Linux
userspace platform.  For example:

  make CROSS=s390x-linux-gnu- bin-s390x-linux/tests.linux

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2026-06-14 01:05:31 +01:00
Michael Brown 730c122c1d [test] Fix RFC 1071 checksum calculation for big-endian targets
Calculation of the TCP/IP checksum is fundamentally endian-agnostic:
the checksum is designed to be symmetric so that both big-endian and
little-endian systems can use native addition in any word size without
any byte swapping.  The result is then stored into the checksum field
in the packet header as a native-endian value.

The reference algorithm presented in RFC 1071 (and used in our test
suite) is implicitly little-endian: the trailing byte is on a 16-bit
word boundary and is added to the least significant byte of the 16-bit
checksum value.

Fix by shifting the trailing byte by 8 bits on big-endian targets.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2026-06-13 16:22:49 +01:00
Michael Brown 85700526ec [linux] Fix console output on big-endian targets
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2026-06-13 16:12:40 +01:00
Michael Brown e6e9ae9804 [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>
2026-06-13 16:11:29 +01:00
Michael Brown 6476f7c7c5 [peerdist] Fix segment identifier constant on big-endian targets
The "MS_P2P_CACHING" constant (used as part of the HMAC digest
calculation for the segment identifier) is a UTF-16LE string.  On a
big-endian target, a wide-character string literal will have the wrong
endianness.

Fix by using a byte array rather than a wide-character string.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2026-06-13 16:03:33 +01:00
Michael Brown bfdbd1c4e0 [build] Fix building for big-endian targets
Fix build errors that arise when building for a big-endian target such
as s390x.  (Runtime endianness errors may remain: this fixes only
those errors that are detected at build time.)

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2026-06-13 16:02:05 +01:00
Michael Brown e68ca57f46 [crypto] Use generic implementations of slow-path big integer functions
In the original big integer implementation, big integers were entirely
opaque to the caller and only the architecture-dependent code knew any
details of the internal structure.

This has long since ceased to be the case: for the sake of arithmetic
efficiency, many portions of the codebase now presume that big
integers are represented as an array of elements, with each element
being a native-endian unsigned value (with the precise type being
chosen by the architecture-specific header file) and with the least
significant element being first in the array.

The functions bigint_init(), bigint_done(), bigint_is_zero(),
bigint_is_geq(), and bigint_max_bit_set() are never used on fast code
paths, and most architectures use a generic C implementation of these
functions.

Provide generic implementations of these slow-path functions to be
used on all architectures.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2026-06-13 15:53:19 +01:00
Michael Brown 05a459f795 [iscsi] Ensure SCSI sense data is present before parsing
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2026-06-09 15:10:04 +01:00
Michael Brown 95ffbf4745 [crypto] Add RFC 7919 FFDHE key exchange algorithms
We currently support fully parameterized finite field Diffie-Hellman
key exchange, where the peer provides not only its public key but also
the (fully arbitrary) selection of the field prime and generator.

RFC 7919 defines a family of finite fields all constructed from the
natural logarithm constant "e", intended to be used as well-known
fields where the peer simply names the field (e.g. "ffdhe2048") rather
than providing the raw prime and generator values.

Add support for this family of finite fields as key exchange
algorithms, to allow for protocols such as TLS version 1.3 where
parameterized fields are not permitted.

We choose to support only up to ffdhe4096, since this is sufficient to
exceed the security strength of our RNG (128 bits).

Support for ffdhe6144 and ffdhe8192 could trivially be added by simply
extending the "euler" constant and adding the relevant FFDHE_GROUP()
declarations.  Doing so would approximately double the space
requirements for both read-only data (from 0.5kB to 1kB) and for
uninitialised data (from 3.5kB to 7kB).

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2026-06-09 14:00:18 +01:00
Michael Brown 6dcb3b1e67 [test] Allow for large values in key exchange self-tests
Allow for the existence of key exchange algorithms where the public
keys and shared secrets may be too large for a stack allocation.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2026-06-09 13:55:49 +01:00
Michael Brown f2ade220f9 [test] Verify test vector lengths for key exchange self-tests
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2026-06-09 13:51:13 +01:00
Michael Brown 36e8cc28c7 [crypto] Remove redundant ECDHE algorithm
Remove the now-unused implementation of ECDHE that requires an
underlying elliptic curve abstraction, since we now use a standalone
key exchange algorithm abstraction instead.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2026-06-06 16:53:04 +01:00
Michael Brown 5e427326ea [crypto] Remove elliptic curve abstraction for X25519
X25519 is defined as a key exchange algorithm, not as a generic
elliptic curve.  We have never supported arbitrary point addition on
the underlying curve, and we have never supported pure multiplication
(without the clamping defined in RFC7748, which modifies the scalar
multiple).

Now that we have an abstraction for key exchange that exists
independently of the elliptic curve abstraction, there are no further
consumers of the elliptic curve abstraction for X25519.  Remove this
redundant abstraction to simplify the codebase.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2026-06-06 16:53:04 +01:00