Commit Graph

16 Commits

Author SHA1 Message Date
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 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
Michael Brown 4dc99fc040 [crypto] Provide X25519 as a generic key exchange algorithm
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>
2026-06-05 16:57:00 +01:00
Michael Brown adcaaf9b93 [build] Mark known reviewed files as permitted for UEFI Secure Boot
Some past security reviews carried out for UEFI Secure Boot signing
submissions have covered specific drivers or functional areas of iPXE.
Mark all of the files comprising these areas as permitted for UEFI
Secure Boot.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2026-01-14 16:10:29 +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 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 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 1e3fb1b37e [init] Show initialisation function names in debug messages
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-07-15 14:10:33 +01:00
Michael Brown c9291bc5c7 [tls] Allow for NIST elliptic curve point formats
The elliptic curve point representation for the x25519 curve includes
only the X value, since the curve is designed such that the Montgomery
ladder does not need to ever know or calculate a Y value.  There is no
curve point format byte: the public key data is simply the X value.
The pre-master secret is also simply the X value of the shared secret
curve point.

The point representation for the NIST curves includes both X and Y
values, and a single curve point format byte that must indicate that
the format is uncompressed.  The pre-master secret for the NIST curves
does not include both X and Y values: only the X value is used.

Extend the definition of an elliptic curve to allow the point size to
be specified separately from the key size, and extend the definition
of a TLS named curve to include an optional curve point format byte
and a pre-master secret length.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-01-21 15:55:33 +00:00
Michael Brown 167a08f089 [crypto] Expose carry flag from big integer addition and subtraction
Expose the effective carry (or borrow) out flag from big integer
addition and subtraction, and use this to elide an explicit bit test
when performing x25519 reduction.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2024-11-26 12:55:13 +00:00
Michael Brown da6da6eb3b [crypto] Add bigint_msb_is_set() to clarify code
Add a dedicated bigint_msb_is_set() to reduce the amount of open
coding required in the common case of testing the sign of a two's
complement big integer.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2024-11-20 14:39:49 +00:00
Michael Brown 3f4f843920 [crypto] Eliminate temporary carry space for big integer multiplication
An n-bit multiplication product may be added to up to two n-bit
integers without exceeding the range of a (2n)-bit integer:

  (2^n - 1)*(2^n - 1) + (2^n - 1) + (2^n - 1) = 2^(2n) - 1

Exploit this to perform big integer multiplication in constant time
without requiring the caller to provide temporary carry space.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2024-09-27 13:51:24 +01:00
Michael Brown 3def13265d [crypto] Use constant-time big integer multiplication
Big integer multiplication currently performs immediate carry
propagation from each step of the long multiplication, relying on the
fact that the overall result has a known maximum value to minimise the
number of carries performed without ever needing to explicitly check
against the result buffer size.

This is not a constant-time algorithm, since the number of carries
performed will be a function of the input values.  We could make it
constant-time by always continuing to propagate the carry until
reaching the end of the result buffer, but this would introduce a
large number of redundant zero carries.

Require callers of bigint_multiply() to provide a temporary carry
storage buffer, of the same size as the result buffer.  This allows
the carry-out from the accumulation of each double-element product to
be accumulated in the temporary carry space, and then added in via a
single call to bigint_add() after the multiplication is complete.

Since the structure of big integer multiplication is identical across
all current CPU architectures, provide a single shared implementation
of bigint_multiply().  The architecture-specific operation then
becomes the multiplication of two big integer elements and the
accumulation of the double-element product.

Note that any intermediate carry arising from accumulating the lower
half of the double-element product may be added to the upper half of
the double-element product without risk of overflow, since the result
of multiplying two n-bit integers can never have all n bits set in its
upper half.  This simplifies the carry calculations for architectures
such as RISC-V and LoongArch64 that do not have a carry flag.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2024-09-23 13:19:58 +01:00
Michael Brown 17135c83fb [crypto] Add an abstraction of an elliptic curve
Define an abstraction of an elliptic curve with a fixed generator and
one supported operation (scalar multiplication of a curve point).

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2024-01-30 13:26:36 +00:00
Michael Brown 27398f1360 [crypto] Check for all-zeros result from X25519 key exchange
RFC7748 states that it is entirely optional for X25519 Diffie-Hellman
implementations to check whether or not the result is the all-zero
value (indicating that an attacker sent a malicious public key with a
small order).  RFC8422 states that implementations in TLS must abort
the handshake if the all-zero value is obtained.

Return an error if the all-zero value is obtained, so that the TLS
code will not require knowledge specific to the X25519 curve.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2024-01-30 13:21:01 +00:00
Michael Brown 2eea04c02c [crypto] Add X25519 key exchange algorithm
Add an implementation of the X25519 key exchange algorithm as defined
in RFC7748.

This implementation is inspired by and partially based upon the paper
"Implementing Curve25519/X25519: A Tutorial on Elliptic Curve
Cryptography" by Martin Kleppmann, available for download from
https://www.cl.cam.ac.uk/teaching/2122/Crypto/curve25519.pdf

The underlying modular addition, subtraction, and multiplication
operations are completely redesigned for substantially improved
efficiency compared to the TweetNaCl implementation studied in that
paper (approximately 5x-10x faster and with 70% less memory usage).

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2024-01-19 16:44:30 +00:00