mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-21 23:20:20 +00:00
LibCrypto: Do not trim leading zeros in export_data by default
This fixes the issue with the exported data having a leading zero, causing RSA::encrypt to trim the block down, and ruining the encryption. Fixes #2691 :^)
This commit is contained in:
parent
180207062c
commit
b00ffc860b
Notes:
sideshowbarker
2024-07-19 04:26:38 +09:00
Author: https://github.com/alimpfard Commit: https://github.com/SerenityOS/serenity/commit/b00ffc860b9 Pull-request: https://github.com/SerenityOS/serenity/pull/2929 Issue: https://github.com/SerenityOS/serenity/issues/2691
6 changed files with 27 additions and 19 deletions
|
@ -36,11 +36,15 @@ SignedBigInteger SignedBigInteger::import_data(const u8* ptr, size_t length)
|
|||
return { move(unsigned_data), sign };
|
||||
}
|
||||
|
||||
size_t SignedBigInteger::export_data(Bytes data) const
|
||||
size_t SignedBigInteger::export_data(Bytes data, bool remove_leading_zeros) const
|
||||
{
|
||||
// FIXME: Support this:
|
||||
// m <0XX> -> m <XX> (if remove_leading_zeros)
|
||||
ASSERT(!remove_leading_zeros);
|
||||
|
||||
data[0] = m_sign;
|
||||
auto bytes_view = data.slice(1, data.size() - 1);
|
||||
return m_unsigned_data.export_data(bytes_view) + 1;
|
||||
return m_unsigned_data.export_data(bytes_view, remove_leading_zeros) + 1;
|
||||
}
|
||||
|
||||
SignedBigInteger SignedBigInteger::from_base10(StringView str)
|
||||
|
|
|
@ -67,7 +67,7 @@ public:
|
|||
static SignedBigInteger import_data(const AK::StringView& data) { return import_data((const u8*)data.characters_without_null_termination(), data.length()); }
|
||||
static SignedBigInteger import_data(const u8* ptr, size_t length);
|
||||
|
||||
size_t export_data(Bytes) const;
|
||||
size_t export_data(Bytes, bool remove_leading_zeros = false) const;
|
||||
|
||||
static SignedBigInteger from_base10(StringView str);
|
||||
String to_base10() const;
|
||||
|
|
|
@ -55,21 +55,23 @@ UnsignedBigInteger UnsignedBigInteger::create_invalid()
|
|||
return invalid;
|
||||
}
|
||||
|
||||
size_t UnsignedBigInteger::export_data(Bytes data) const
|
||||
size_t UnsignedBigInteger::export_data(Bytes data, bool remove_leading_zeros) const
|
||||
{
|
||||
size_t word_count = trimmed_length();
|
||||
size_t out = 0;
|
||||
if (word_count > 0) {
|
||||
ssize_t leading_zeros = -1;
|
||||
u32 word = m_words[word_count - 1];
|
||||
for (size_t i = 0; i < sizeof(u32); i++) {
|
||||
u8 byte = (u8)(word >> ((sizeof(u32) - i - 1) * 8));
|
||||
data[out++] = byte;
|
||||
if (leading_zeros < 0 && byte != 0)
|
||||
leading_zeros = (int)i;
|
||||
if (remove_leading_zeros) {
|
||||
u32 word = m_words[word_count - 1];
|
||||
for (size_t i = 0; i < sizeof(u32); i++) {
|
||||
u8 byte = (u8)(word >> ((sizeof(u32) - i - 1) * 8));
|
||||
data[out++] = byte;
|
||||
if (leading_zeros < 0 && byte != 0)
|
||||
leading_zeros = (int)i;
|
||||
}
|
||||
}
|
||||
for (size_t i = word_count - 1; i > 0; i--) {
|
||||
word = m_words[i - 1];
|
||||
for (size_t i = word_count - (remove_leading_zeros ? 1 : 0); i > 0; i--) {
|
||||
auto word = m_words[i - 1];
|
||||
data[out++] = (u8)(word >> 24);
|
||||
data[out++] = (u8)(word >> 16);
|
||||
data[out++] = (u8)(word >> 8);
|
||||
|
|
|
@ -59,7 +59,7 @@ public:
|
|||
return UnsignedBigInteger(ptr, length);
|
||||
}
|
||||
|
||||
size_t export_data(Bytes) const;
|
||||
size_t export_data(Bytes, bool remove_leading_zeros = false) const;
|
||||
|
||||
static UnsignedBigInteger from_base10(const String& str);
|
||||
String to_base10() const;
|
||||
|
|
|
@ -126,9 +126,11 @@ void RSA::encrypt(const ByteBuffer& in, ByteBuffer& out)
|
|||
}
|
||||
auto exp = NumberTheory::ModularPower(in_integer, m_public_key.public_exponent(), m_public_key.modulus());
|
||||
auto size = exp.export_data(out.span());
|
||||
// FIXME: We should probably not do this...
|
||||
if (size != out.size())
|
||||
out = out.slice(out.size() - size, size);
|
||||
auto outsize = out.size();
|
||||
if (size != outsize) {
|
||||
dbg() << "POSSIBLE RSA BUG!!! Size mismatch: " << outsize << " requested but " << size << " bytes generated";
|
||||
out = out.slice(outsize - size, size);
|
||||
}
|
||||
}
|
||||
|
||||
void RSA::decrypt(const ByteBuffer& in, ByteBuffer& out)
|
||||
|
@ -252,8 +254,8 @@ void RSA_PKCS1_EME::encrypt(const ByteBuffer& in, ByteBuffer& out)
|
|||
// since arc4random can create zeros (shocking!)
|
||||
// we have to go through and un-zero the zeros
|
||||
for (size_t i = 0; i < ps_length; ++i)
|
||||
if (!ps[i])
|
||||
ps[i] = 0xfe;
|
||||
while (!ps[i])
|
||||
AK::fill_with_random(ps + i, 1);
|
||||
|
||||
u8 paddings[] { 0x00, 0x02 };
|
||||
|
||||
|
|
|
@ -1933,7 +1933,7 @@ void bigint_import_export()
|
|||
I_TEST((BigInteger | BigEndian Export));
|
||||
auto number = "448378203247"_bigint;
|
||||
char exported[8] { 0 };
|
||||
auto exported_length = number.export_data({ exported, 8 });
|
||||
auto exported_length = number.export_data({ exported, 8 }, true);
|
||||
if (exported_length == 5 && memcmp(exported + 3, "hello", 5) == 0) {
|
||||
PASS;
|
||||
} else {
|
||||
|
|
Loading…
Reference in a new issue