Some websites actually provide a SECP384 certificate which is signed
using a SHA256 hash. We assumed that SECP384 always used a SHA384 hash,
but this is not the case.
This implementation is basically a copy-paste of the SECP256r1
implementation with all "256" replaced with "384".
In the future it might be nice to make this generic, instead of having
two almost identical copies of code.
Instead of building the REDUCE_PRIME constant on the fly from the carry
flag, we now simply use the constant in combination with select. This
improves the readablility of the functions significantly.
Instead of having a large list of magical constants, we now only have
the curve prime, a, b, and order, which are all taken from the
specification. All the other helper constants are now calculated from
the curve paramters.
When building for AArch64 with UBSan enabled, GCC 13.1 reports a false
"array out of bounds" error on access to offset `1 * sizeof(u64)`.
Changing the order of the stores seems to silence it.
Rather than the very C-like API we currently have, accepting a void* and
a length, let's take a Bytes object instead. In almost all existing
cases, the compiler figures out the length.
We have a new, improved string type coming up in AK (OOM aware, no null
state), and while it's going to use UTF-8, the name UTF8String is a
mouthful - so let's free up the String name by renaming the existing
class.
Making the old one have an annoying name will hopefully also help with
quick adoption :^)
All the elliptic curve implementations had a long list of private
methods which were all stored in a single .cpp file. Now we simply use
static methods instead.
Add the required methods to SECP256r1 to conform to the EllipticCurve
virtual base class. Using this updated version of SECP256r1, support in
LibTLS is implemented.
These changes generalize the interface with an elliptic curve
implementation. This allows LibTLS to support elliptic curves generally
without needing the specifics of elliptic curve implementations.
This should allow for easier addition of other elliptic curves.
This implementation of the secp256r1 elliptic curve uses two techniques
to improve the performance of the operations.
1. All coordinates are stored in Jacobian form, (X/Z^2, Y/Z^3, Z), which
removes the need for division operations during point addition or
doubling. The points are converted at the start of the computation,
and converted back at the end.
2. All values are transformed to Montgomery form, to allow for faster
modular multiplication using the Montgomery modular multiplication
method. This means that all coordinates have to be converted into
this form, and back out of this form before returning them.