Age | Commit message (Collapse) | Author | Files | Lines |
|
Signed-off-by: Michael Brown <mcb30@ipxe.org>
|
|
Many consoles will scroll immediately upon drawing a character in the
rightmost column of the bottom row of the display, in order to be able
to advance the cursor to the next character (even if the cursor is
disabled).
This causes PXE menus to display incorrectly. Specifically, pressing
the down arrow key while already on the last menu item may cause the
whole screen to scroll and the line to be duplicated.
Fix by moving the PXE menu one row up from the bottom of the screen.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
|
|
UEFI has the mildly annoying habit of installing copies of the
EFI_SIMPLE_NETWORK_PROTOCOL instance on the IPv4 and IPv6 child device
handles. This can cause iPXE's SNP driver to attempt to bind to a
copy of the EFI_SIMPLE_NETWORK_PROTOCOL that iPXE itself provided on a
different handle.
Fix by refusing to bind to an SNP (or NII) handle if there exists
another instance of the same protocol further up the device path (on
the basis that we always want to bind to the highest possible device).
Signed-off-by: Michael Brown <mcb30@ipxe.org>
|
|
Extend the functionality of efi_locate_device() to allow callers to
find instances of the protocol that may exist further up the device
path.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
|
|
Signed-off-by: Michael Brown <mcb30@ipxe.org>
|
|
Signed-off-by: Michael Brown <mcb30@ipxe.org>
|
|
Some versions of the 32-bit ARM linker seem to treat the absence of a
.note.GNU-stack section as implying an executable stack, and will
print a warning that this is deprecated behaviour.
Silence the warning by adding a .note.GNU-stack section to each
assembly file and retaining the sections in the Linux linker script.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
|
|
The EFI ABI requires the use of -mfloat-abi=soft, but other platforms
may require -mfloat-abi=hard.
Allow for this by using -mfloat-abi=soft only for EFI builds.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
|
|
The EFI ABI requires the use of -fno-short-enums, and the EDK2 headers
will perform a compile-time check that enums are 32 bits.
The EDK2 headers may be included even in builds for non-EFI platforms,
and so the -fno-short-enums flag must be used in all 32-bit ARM
builds. Fortunately, nothing else currently cares about enum sizes.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
|
|
Add support for building as a Linux userspace binary for AArch64.
This allows the self-test suite to be more easily run for the 64-bit
ARM code. For example:
# On a native AArch64 system:
#
make bin-arm64-efi/tests.linux && ./bin-arm64-efi/tests.linux
# On a non-AArch64 system (e.g. x86_64) via cross-compilation,
# assuming that kernel and glibc headers are present within
# /usr/aarch64-linux-gnu/sys-root/:
#
make bin-arm64-linux/tests.linux CROSS=aarch64-linux-gnu- && \
qemu-aarch64 -L /usr/aarch64-linux-gnu/sys-root/ \
./bin-arm64-linux/tests.linux
Signed-off-by: Michael Brown <mcb30@ipxe.org>
|
|
Move the platform-specific DHCP client architecture definitions to
header files of the form <ipxe/$(PLATFORM)/dhcparch.h>. This
simplifies the directory structure and allows the otherwise unused
arch/$(ARCH)/include/$(PLATFORM) to be removed from the include
directory search path, which avoids the confusing situation in which a
header file may potentially be accessed through more than one path.
For Linux userspace binaries on any architecture, use the EFI values
for that architecture by delegating to the EFI header file. This
avoids the need to explicitly select values for Linux userspace
binaries for each architecture.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
|
|
The requirement to undo the implicit "-Dlinux" is not specific to the
x86 architecture. Move this out of the x86-specific Makefile.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
|
|
Reduce duplication between i386 and x86_64 by providing a single
shared linker script that both architectures can include.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
|
|
We cannot rely on the EDK2 ProcessorBind.h headers when compiling a
binary for execution on the build host itself (e.g. elf2efi), since
the host's CPU architecture may not even be supported by EDK2.
Fix by skipping ProcessorBind.h when building a host binary, and
defining the bare minimum required to allow other EDK2 headers to
compile cleanly.
Reported-by: Michal Suchánek <msuchanek@suse.de>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
|
|
We currently don't allocate an Asynchronous Event Notification Queue
(AENQ) because we don't actually care about any of the events that may
come in.
The ENA firmware found on Graviton instances requires the AENQ to
exist, otherwise all admin queue commands will fail.
Fix by allocating an AENQ and disabling all events (so that we do not
need to include code to acknowledge any events that may arrive).
Signed-off-by: Alexander Graf <graf@amazon.com>
|
|
Ensure that the "${netX/...}" settings mechanism always uses the same
interpretation of the network device corresponding to "netX" as any
other mechanism that performs a name-based lookup of a network device.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
|
|
When chainloading iPXE from an EFI VLAN device, configure the
corresponding iPXE VLAN device to be created automatically.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
|
|
Add the ability to automatically create a VLAN device for a specified
trunk device link-layer address and VLAN tag.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
|
|
When chainloading iPXE from a VLAN device, the MAC address of the
loaded image's device handle will match the MAC address of the trunk
device created by iPXE, and the autoboot process will then erroneously
consider the trunk device to be an autoboot device.
Fix by recording the VLAN tag along with the MAC address, and treating
the VLAN tag as part of the filter used to match the MAC address
against candidate network devices.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
|
|
Many laptops now include the ability to specify a "system-specific MAC
address" (also known as "pass-through MAC"), which is supposed to be
used for both the onboard NIC and for any attached docking station or
other USB NIC. This is intended to simplify interoperability with
software or hardware that relies on a MAC address to recognise an
individual machine: for example, a deployment server may associate the
MAC address with a particular operating system image to be deployed.
This therefore creates legitimate situations in which duplicate MAC
addresses may exist within the same system.
As described in commit 98d09a1 ("[netdevice] Avoid registering
duplicate network devices"), the Xen netfront driver relies on the
rejection of duplicate MAC addresses in order to inhibit registration
of the emulated PCI devices that a Xen PV-HVM guest will create to
shadow each of the paravirtual network devices.
Move the code that rejects duplicate MAC addresses from the network
device core to the Xen netfront driver, to allow for the existence of
duplicate MAC addresses in non-Xen setups.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
|
|
The network device index currently serves two purposes: acting as a
sequential index for network device names ("net0", "net1", etc), and
acting as an opaque unique integer identifier used in socket address
scope IDs.
There is no particular need for these usages to be linked, and it can
lead to situations in which devices are named unexpectedly. For
example: if a system has two network devices "net0" and "net1", a VLAN
is created as "net1-42", and then a USB NIC is connected, then the USB
NIC will be named "net3" rather than the expected "net2" since the
VLAN device "net1-42" will have consumed an index.
Separate the usages: rename the "index" field to "scope_id" (matching
its one and only use case), and assign the name without reference to
the scope ID by finding the first unused name. For consistency,
assign the scope ID by similarly finding the first unused scope ID.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
|
|
Some UNDI drivers (such as the AMI UsbNetworkPkg currently in the
process of being upstreamed into EDK2) have a bug that will prevent
any packets from being received unless at least one attempt has been
made to disable some receive filters.
Work around these buggy drivers by attempting to disable receive
filters before enabling them. Ignore any errors, since we genuinely
do not care whether or not the disabling succeeds.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
|
|
We currently free an unclaimed cached DHCPACK immediately after
startup, in order to free up memory. This prevents the cached DHCPACK
from being applied to a device that is created after startup, such as
a VLAN device created via the "vcreate" command.
Retain any unclaimed DHCPACK after startup to allow it to be matched
against (and applied to) any device that gets created at runtime.
Free the DHCPACK during shutdown if it still remains unclaimed, in
order to exit with memory cleanly freed.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
|
|
When chainloading iPXE from a VLAN device, the MAC address within the
cached DHCPACK will match the MAC address of the trunk device created
by iPXE, and the cached DHCPACK will then end up being erroneously
applied to the trunk device. This tends to break outbound IPv4
routing, since both the trunk and VLAN devices will have the same
assigned IPv4 address.
Fix by recording the VLAN tag along with the cached DHCPACK, and
treating the VLAN tag as part of the filter used to match the cached
DHCPACK against candidate network devices.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
|
|
EFI provides no API for determining the VLAN tag (if any) for a
specified device handle. There is the EFI_VLAN_CONFIG_PROTOCOL, but
that exists only on the trunk device handle (not on the VLAN device
handle), and provides no way to match VLAN tags against the trunk
device's child device handles.
The EDK2 codebase seems to rely solely on the device path to determine
the VLAN tag for a specified device handle: both NetLibGetVlanId() and
BmGetNetworkDescription() will parse the device path to search for a
VLAN_DEVICE_PATH component.
Add efi_path_vlan() which uses the same device path parsing logic to
determine the VLAN tag.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
|
|
Provide a single central implementation of the logic for stepping
through elements of an EFI device path.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
|
|
Signed-off-by: Michael Brown <mcb30@ipxe.org>
|
|
UEFI implements VLAN support within the Managed Network Protocol (MNP)
driver, which may create child VLAN devices automatically based on
stored UEFI variables. These child devices do not themselves provide
a raw-packet interface via EFI_SIMPLE_NETWORK_PROTOCOL, and may be
consumed only via the EFI_MANAGED_NETWORK_PROTOCOL interface.
The device paths constructed for these child devices may conflict with
those for the EFI_SIMPLE_NETWORK_PROTOCOL instances that iPXE attempts
to install for its own VLAN devices. The upshot is that creating an
iPXE VLAN device (e.g. via the "vcreate" command) will fail if the
UEFI Managed Network Protocol has already created a device for the
same VLAN tag.
Fix by providing our own EFI_VLAN_CONFIG_PROTOCOL instance on the same
device handle as EFI_SIMPLE_NETWORK_PROTOCOL. This causes the MNP
driver to treat iPXE's device as supporting hardware VLAN offload, and
it will therefore not attempt to install its own instance of the
protocol.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
|
|
Signed-off-by: Michael Brown <mcb30@ipxe.org>
|
|
The dangling pointer warning introduced in GCC 12 reports false
positives that result in build failures. In particular, storing the
address of a local code label used to record the current state of a
state machine (as done in crypto/deflate.c) is reported as an error.
There seems to be no way to mark the pointer type as being permitted
to hold such a value, so unconditionally disable the warning.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
|
|
The array bounds checker on GCC 12 and newer reports a very large
number of false positives that result in build failures. In
particular, accesses through pointers to zero-length arrays (such as
those used by the linker table mechanism in include/ipxe/tables.h) are
reported as errors, contrary to the GCC documentation.
Work around this GCC issue by unconditionally disabling the warning.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
|
|
Signed-off-by: Christian I. Nilsson <nikize@gmail.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
|
|
The behaviour of PCI devices across a function-level reset seems to be
inconsistent in practice: some devices will preserve PCI BARs, some
will not.
Fix the behaviour of FLR on devices that do not preserve PCI BARs by
backing up and restoring PCI configuration space across the reset.
Preserve only the standard portion of the configuration space, since
there may be registers with unexpected side effects in the remaining
non-standardised space.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
|
|
Signed-off-by: Michael Brown <mcb30@ipxe.org>
|
|
Signed-off-by: Michael Brown <mcb30@ipxe.org>
|
|
TLS relies upon the ability of ciphers to perform in-place decryption,
in order to avoid allocating additional I/O buffers for received data.
Add verification of in-place encryption and decryption to the cipher
self-tests.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
|
|
The hash calculation is currently performed incorrectly when
decrypting in place, since the ciphertext will have been overwritten
with the plaintext before being used to update the hash value.
Restructure the code to allow for in-place encryption and decryption.
Choose to optimise for the decryption case, since we are likely to
decrypt much more data than we encrypt.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
|
|
TLS relies upon the ability to reuse a cipher by resetting only the
initialisation vector while reusing the existing key.
Add verification of resetting the initialisation vector to the cipher
self-tests.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
|
|
Reset the accumulated authentication state when cipher_setiv() is
called, to allow the cipher to be reused without resetting the key.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
|
|
All existing cipher suites use SHA-256 as the TLSv1.2 and above
handshake digest algorithm (even when using SHA-1 as the MAC digest
algorithm). Some GCM cipher suites use SHA-384 as the handshake
digest algorithm.
Allow the cipher suite to specify the handshake (and PRF) digest
algorithm to be used for TLSv1.2 and above.
This requires some restructuring to allow for the fact that the
ClientHello message must be included within the handshake digest, even
though the relevant digest algorithm is not yet known at the point
that the ClientHello is sent. Fortunately, the ClientHello may be
reproduced verbatim at the point of receiving the ServerHello, so we
rely on reconstructing (rather than storing) this message.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
|
|
Always send the maximum supported version in our ClientHello message,
even when performing renegotiation (in which case the current version
may already be lower than the maximum supported version).
This is permitted by the specification, and allows the ClientHello to
be reconstructed verbatim at the point of selecting the handshake
digest algorithm in tls_new_server_hello().
Signed-off-by: Michael Brown <mcb30@ipxe.org>
|
|
Allow for AEAD cipher suites where the MAC length may be zero and the
authentication is instead provided by an authenticating cipher, with
the plaintext authentication tag appended to the ciphertext.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
|
|
Harden against padding oracle attacks by treating invalid block
padding as zero length padding, thereby deferring the failure until
after computing the (incorrect) MAC.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
|
|
Restructure the encryption and decryption operations to allow for the
use of ciphers where the initialisation vector is constructed by
concatenating the fixed IV (derived as part of key expansion) with a
record IV (prepended to the ciphertext).
Signed-off-by: Michael Brown <mcb30@ipxe.org>
|
|
TLS stream and block ciphers use a MAC with a length equal to the
output length of the digest algorithm in use. For AEAD ciphers there
is no MAC, with the equivalent functionality provided by the cipher
algorithm's authentication tag.
Allow for the existence of AEAD cipher suites by making the MAC length
a parameter of the cipher suite.
Assume that the MAC key length is equal to the MAC length, since this
is true for all currently supported cipher suites.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
|
|
All TLS cipher types use a common structure for the per-record data
that is authenticated in addition to the plaintext itself. This data
is used as a prefix in the HMAC calculation for stream and block
ciphers, or as additional authenticated data for AEAD ciphers.
Define a "TLS authentication header" structure to hold this data as a
contiguous block, in order to meet the alignment requirement for AEAD
ciphers such as GCM.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
|
|
Adjust the length of the first received ciphertext data buffer to
ensure that all decryption operations respect the cipher's alignment
size.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
|
|
The GCM cipher mode of operation (in common with other counter-based
modes of operation) has a notion of blocksize that does not neatly
fall into our current abstraction: it does operate in 16-byte blocks
but allows for an arbitrary overall data length (i.e. the final block
may be incomplete).
Model this by adding a concept of alignment size. Each call to
encrypt() or decrypt() must begin at a multiple of the alignment size
from the start of the data stream. This allows us to model GCM by
using a block size of 1 byte and an alignment size of 16 bytes.
As a side benefit, this same concept allows us to neatly model the
fact that raw AES can encrypt only a single 16-byte block, by
specifying an alignment size of zero on this cipher.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
|
|
TLS block ciphers always use CBC (as per RFC 5246 section 6.2.3.2)
with a record initialisation vector length that is equal to the cipher
block size, and no fixed initialisation vector.
The initialisation vector for AEAD ciphers such as GCM is less
straightforward, and requires both a fixed and per-record component.
Extend the definition of a cipher suite to include fixed and record
initialisation vector lengths, and generate the fixed portion (if any)
as part of key expansion.
Do not add explicit calls to cipher_setiv() in tls_assemble_block()
and tls_split_block(), since the constraints imposed by RFC 5246 are
specifically chosen to allow implementations to avoid doing so.
(Instead, add a sanity check that the record initialisation vector
length is equal to the cipher block size.)
Signed-off-by: Michael Brown <mcb30@ipxe.org>
|
|
The TLSv1.0 protocol was deprecated by RFC 8996 (along with TLSv1.1),
and has been disabled by default in iPXE since commit dc785b0fb
("[tls] Default to supporting only TLSv1.1 or above") in June 2020.
While there is value in continuing to support older protocols for
interoperability with older server appliances, the additional
complexity of supporting the implicit initialisation vector for
TLSv1.0 is not worth the cost.
Remove support for the obsolete TLSv1.0 protocol, to reduce complexity
of the implementation and simplify ongoing maintenance.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
|