LibCrypto: Always handle SECPxxxr1 scalars with leading zeros

It may happen that the scalars used by SECPxxxr1 turn out to be slightly
smaller than their actual size when serialized to `UnsignedBigInteger`,
especially for P521. Handle this case by serializing zeros instead of
failing.

Originally discovered as a flaky WPT test.
This commit is contained in:
devgianlu 2025-01-29 11:00:05 +01:00 committed by Jelle Raaijmakers
commit 12ca074671
Notes: github-actions[bot] 2025-01-29 11:47:47 +00:00

View file

@ -30,8 +30,8 @@ struct SECPxxxr1Point {
{ {
auto a_bytes = TRY(ByteBuffer::create_uninitialized(a.byte_length())); auto a_bytes = TRY(ByteBuffer::create_uninitialized(a.byte_length()));
auto a_size = a.export_data(a_bytes.span()); auto a_size = a.export_data(a_bytes.span());
VERIFY(a_size >= size);
if (a_size >= size) {
for (size_t i = 0; i < a_size - size; i++) { for (size_t i = 0; i < a_size - size; i++) {
if (a_bytes[i] != 0) { if (a_bytes[i] != 0) {
return Error::from_string_literal("Scalar is too large for the given size"); return Error::from_string_literal("Scalar is too large for the given size");
@ -41,6 +41,11 @@ struct SECPxxxr1Point {
return a_bytes.slice(a_size - size, size); return a_bytes.slice(a_size - size, size);
} }
auto a_extended_bytes = TRY(ByteBuffer::create_zeroed(size));
a_extended_bytes.overwrite(size - a_size, a_bytes.data(), a_size);
return a_extended_bytes;
}
static ErrorOr<SECPxxxr1Point> from_uncompressed(ReadonlyBytes data) static ErrorOr<SECPxxxr1Point> from_uncompressed(ReadonlyBytes data)
{ {
if (data.size() < 1 || data[0] != 0x04) if (data.size() < 1 || data[0] != 0x04)