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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
Remove any knowledge of elliptic curve point formats from the TLS
layer and use the generic key exchange algorithm abstraction instead.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Provide the Weierstrass curves P-256 and P-384 as generic key exchange
algorithms (independent of the elliptic curve abstraction). Only the
"uncompressed" point format is supported, and the knowledge of the
format byte is internalised within the key exchange algorithm so that
the caller can just treat all values as opaque byte strings.
Add a random selection of the NIST "ECC CDH Primitive (SP800-56A
Section 5.7.1.2)" key exchange test vectors.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Provide X25519 as a generic key exchange algorithm (independent of the
elliptic curve abstraction).
The existing RFC7748 test vectors are not structured in a way amenable
to treatment as a generic key exchange algorithm. Retain these test
vectors unaltered for completeness, add the single "Alice/Bob" key
exchange example presented in RFC7748, and add a selection of test
vectors from Project Wycheproof (including some known edge cases).
Signed-off-by: Michael Brown <mcb30@ipxe.org>
TLS version 1.3 does not use static RSA or parameterized DHE for key
exchange: all key exchange algorithms are identified via a "named
group" enumeration and have predefined group parameters with fixed
input and output sizes.
Add an abstraction of a key exchange algorithm matching this usage
pattern, along with corresponding test support code.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The length calculations in nfs_uri_symlink() omitted space for the
NUL terminator, causing strcpy() to write one byte past the heap
allocation.
Signed-off-by: Theodore Riera <warsang@hotmail.com>
GCC 16 attempts to link against -latomic_asneeded by default, and
expects that this library will be provided by the installed build
toolchain alongside libgcc.
The Fedora cross-gcc packages do not include libatomic, which causes
the build to fail.
We do not require any functions provided by libatomic. Work around
the missing packaged files in Fedora by disabling gcc's implicit
linking via the -fno-link-libatomic build option.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Replace malloc_phys with dma_alloc, free_phys with dma_free, alloc_iob
with alloc_rx_iob, free_iob with free_rx_iob, virt_to_bus with dma or
iob_dma. Replace dma_addr_t with physaddr_t.
Signed-off-by: Joseph Wong <joseph.wong@broadcom.com>
As with most other assembly code in iPXE, LoongArch64 is sufficiently
close to RISC-V that a straightforward transcription of the assembly
language code generally works.
Copy the RISC-V implementation for TCP/IP checksumming, retain the
register names and ABI, and just adjust the syntax to match
LoongArch64 requirements.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Use the tighter provable constraint
carry.2^n + x <= (2^n - 1) + (2^n - 1)
<= 2^n + (2^n - 2)
and so
x + carry <= (2^n - 2) + 1
<= (2^n - 1)
to eliminate some unnecessary folding steps, and hold the folded value
in the most significant bits of the register rather than the least
significant bits so that the final one's complement negation can be
accomplished naturally without requiring an explicit 0xffff constant.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The usage pattern for UEFI Secure Boot on RISC-V 64 and LoongArch64 is
not yet well defined: there is no equivalent on those architectures
for the UEFI shim or the Microsoft signing submission infrastructure.
Include signed binaries for these architectures within the release
artifacts. Users may choose to enrol the iPXE Secure Boot CA
certificate on their own systems in order to use these binaries with
UEFI Secure Boot enabled.
OEMs such as Loongson may choose to include the iPXE Secure Boot CA
certificate within their default enrolled certificate list, or to
issue a cross-signed version of the iPXE Secure Boot CA certificate
(which could then be included within the official iPXE binaries in
future releases).
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The current implementation of the optimised string operations appears
to have been ported from the (old) arm64 implementation, and does not
cleanly match the LoongArch64 instruction set.
Replace with code derived from the riscv64 implementation, modified to
use indexed load and store instructions.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Discarding neighbour cache entries for active connections is known to
be extremely disruptive, and is therefore done only as a last resort
when attempting to free up memory for a new allocation attempt.
There is currently no way to discard the deferred packet queue
separately from discarding the complete neighbour cache entry. Under
some conditions (such as a sustained ICMP echo request packet flood
from an IP address that will never complete neighbour resolution),
this can lead to the deferred packet queue growing without limit,
which will eventually lead to complete neighbour cache entries being
discarded.
Split out the logic in neighbour_destroy() for dropping deferred
packets to a separate neighbour_drop() function, and add a separate
cache discarder that will use this to free up memory without requiring
the complete neighbour cache entry to be discarded.
Reported-by: Daniel Kiper <daniel.kiper@oracle.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The existing virtio network driver has been somewhat hacked together
over the past two decades by multiple contributors, and includes a
substantial amount of logic that is almost but not quite duplicated
between the "legacy" and "modern" code paths.
Rip out the existing driver and replace with a completely new driver
written based on the Virtual I/O Device specification document, not
derived from the Linux kernel driver.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Commit 3d43789 ("[lacp] Detect and ignore erroneously looped back LACP
packets") added protection against LACP packet storms that arise when
our own transmitted packets are somehow looped back to the same port,
but does not protect against a situation in which we have two
different ports that are externally bridged to each other.
This situation is unlikely to arise in practice since a properly
configured link partner should not be both sending and forwarding LACP
packets. Triggering this situation essentially requires our two ports
to be connected to a non-LACP-capable switch, while another port on
the same switch is connected to a separate device that is sending out
LACP packets.
Guard against this situation by using the MAC address of the first
network device as the LACP system identifier, thereby allowing the
loopback detection to reject any packets that were sent from any of
our ports.
Since the system identifier is no longer unique between ports, use the
guaranteed-unique network device scope ID as the group key to indicate
that we do not support aggregation.
Signed-off-by: Michael Brown <mcb30@ipxe.org>