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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
Allow DEBUG=efi_wrap to trace various runtime services calls as well
as the existing boot services calls.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Support for ARM32 has been removed from the EDK2 codebase. However,
we may as well retain the ability to build iPXE for existing EFI
platforms.
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>
The Ip4Config.h header has been removed from the EDK2 codebase as
obsolete. 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>
The UgaDraw.h header has been removed from the EDK2 codebase as
obsolete. 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>
We currently include the EDK2 RiscV64/ProcessorBind.h header when
building for 32-bit RISC-V, as a placeholder since there is no support
for 32-bit RISC-V in upstream EDK2.
This causes errors when attempting to use the EDK2 VA_START() et al
macros, since RiscV64/ProcessorBind.h ends up defining UINTN with a
size different from the size of a pointer.
Fix by falling back to the generic definitions for UINTN etc (as used
for EFI_HOSTONLY) whenever we don't have an architecture-specific
ProcessorBind.h header available.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Some systems (observed on an AWS EC2 m7i.metal-24xl instance in
eu-south-2) use the newer "16550-compatible with parameters defined in
Generic Address Structure" type value. (There does not appear to be
any particular reason why the newer value needs to be used: the UART
is still a standard 16550 with single-byte registers.)
Accept this additional type value for a 16550-compatible UART.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The BIOS may provide an ACPI Serial Port Console Redirection (SPCR)
table to describe the serial port to be used for early boot messages.
Add support for parsing the SPCR and instantiating a 16550-based UART.
We do not currently attempt to support other types of UART, since iPXE
does not yet have drivers for other types.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
An ACPI Generic Address Structure (GAS) may be used to describe the
location of a peripheral such as an early boot console. Add the
relevant definitions and provide acpi_ioremap() as a helper function
to map a region described using this structure.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Make the current baud rate (if specified) a property of the UART, to
allow the default_serial_console() function to specify the default
baud rate as well as the default UART device.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Use the combined accessors ioread8() and iowrite8() to read and write
16550 UART registers, to allow the decision between using MMIO and
port I/O to be made at runtime.
Minimise the increase in code size for x86 by ignoring the register
shift, since this is essentially used only for non-x86 SoCs.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Some devices (such as a 16550 UART) may be accessed via either MMIO or
port I/O. This is currently forced to be a compile-time decision.
For example: we currently access a 16550 UART via port I/O on x86 and
via MMIO on any other platform.
PCI UARTs with MMIO BARs do exist but are not currently supported in
an x86 build of iPXE. Some AWS EC2 systems (observed on a c6i.metal
instance in eu-west-2) provide only a PCI MMIO UART, and it is
therefore currently impossible to get serial output from iPXE on these
instance types.
Add ioread8(), ioread16(), etc accessors that will select between MMIO
and port I/O at the point of use. For non-x86 platforms where we
currently have no port I/O support, these simply become wrappers
around the corresponding readb(), readw(), etc MMIO accessors. On
x86, we use the fairly well-known trick of treating any 16-bit address
(below 64kB) as a port I/O address.
This trick works even in the i386 BIOS build of iPXE (where virtual
addresses are offset from physical addresses by a runtime constant),
since the first 64kB of the virtual address space will correspond to
the iPXE binary itself (along with its uninitialised-data space), and
so must be RAM rather than a valid MMIO address range.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Provide pci_bar_set() to handle setting the base address for a
potentially 64-bit BAR, and rewrite pci_bar_size() to correctly handle
sizing of 64-bit BARs.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
RFC 7627 section 5.3 states that the client must abort the handshake
if the server attempts to resume a session where the master secret
calculation method stored in the session does not match the method
used for the connection being resumed.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
RFC 7627 defines the Extended Master Secret (EMS) as an alternative
calculation that uses the digest of all handshake messages rather than
just the client and server random bytes.
Add support for negotiating the Extended Master Secret extension and
performing the relevant calculation of the master secret.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Interrupts as such are not used in iPXE, which operates in polling
mode. However, some network cards (such as the Intel 40GbE and 100GbE
NICs) will defer writing out completions until the point of asserting
an MSI-X interrupt.
From the point of view of the PCI device, asserting an MSI-X interrupt
is just a 32-bit DMA write of an opaque value to an opaque target
address. The PCI device has no know to know whether or not the target
address corresponds to a real APIC.
We can therefore trick the PCI device into believing that it is
asserting an MSI-X interrupt, by configuring it to write an opaque
32-bit value to a dummy target address in host memory. This is
sufficient to trigger the associated write of the completions to host
memory.
Allocate a dummy target address when enabling MSI-X on a PCI device,
and map all interrupts to this target address by default.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
An EFI boot option (stored in a BootXXXX variable) comprises an
EFI_LOAD_OPTION structure, which includes some undefined number of EFI
device paths. (The structure is extremely messy and awkward to parse
in C, but that's par for the course with EFI.)
Add a function to extract the first device path from an EFI load
option, along with wrapper functions to read and extract the first
device path from an EFI boot variable.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Many region types (e.g. I2C bus addresses) can only ever contain a
single region with no size cells specified. Provide fdt_reg() to
reduce boilerplate in this common use case.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Commands were originally ordered by functional group (e.g. keeping the
image management commands together), with arrays used to impose a
functionally meaningful order within the group.
As the number of commands and functional groups has expanded over the
years, this has become essentially useless as an organising principle.
Switch to sorting commands alphabetically (using the linker table
mechanism).
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Add "sha256sum", "sha512sum", and similar commands. Include these new
commands only when DIGEST_CMD is enabled in config/general.h and the
corresponding algorithm is enabled in config/crypto.h.
Leave "mdsum" and "sha1sum" included whenever only DIGEST_CMD is
enabled, to avoid potentially breaking backwards compatibility with
builds that disabled MD5 or SHA-1 as a TLS or X.509 digest algorithm,
but would still have expected those commands to be present.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Consumption of phandles will be in the form of locating a functional
device (e.g. a GPIO device, or an I2C device, or a reset controller)
by phandle, rather than locating the device tree node to which the
phandle refers.
Repurpose fdt_phandle() to obtain the phandle value (instead of
searching by phandle), and record this value as the bus location
within the generic device structure.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Add a basic driver for the DesignWare USB3 host controller as found in
the Lichee Pi 4A.
This driver covers only the DesignWare host controller hardware. On
the Lichee Pi 4A, this is sufficient to get the single USB root hub
port (exposed internally via the SODIMM connector) up and running.
The driver does not yet handle the various GPIOs that control power
and signal routing for the Lichee Pi 4A's onboard VL817 USB hub and
the four physical USB-A ports. This therefore leaves the USB hub and
the USB-A ports unpowered, and the USB2 root hub port routed to the
physical USB-C port. Devices plugged in to the USB-A ports will not
be powered up, and a device plugged in to the USB-C port will
enumerate as a USB2 device.
Signed-off-by: Michael Brown <mcb30@ipxe.org>