mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-22 07:30:19 +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 };
|
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;
|
data[0] = m_sign;
|
||||||
auto bytes_view = data.slice(1, data.size() - 1);
|
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)
|
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 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);
|
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);
|
static SignedBigInteger from_base10(StringView str);
|
||||||
String to_base10() const;
|
String to_base10() const;
|
||||||
|
|
|
@ -55,21 +55,23 @@ UnsignedBigInteger UnsignedBigInteger::create_invalid()
|
||||||
return 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 word_count = trimmed_length();
|
||||||
size_t out = 0;
|
size_t out = 0;
|
||||||
if (word_count > 0) {
|
if (word_count > 0) {
|
||||||
ssize_t leading_zeros = -1;
|
ssize_t leading_zeros = -1;
|
||||||
u32 word = m_words[word_count - 1];
|
if (remove_leading_zeros) {
|
||||||
for (size_t i = 0; i < sizeof(u32); i++) {
|
u32 word = m_words[word_count - 1];
|
||||||
u8 byte = (u8)(word >> ((sizeof(u32) - i - 1) * 8));
|
for (size_t i = 0; i < sizeof(u32); i++) {
|
||||||
data[out++] = byte;
|
u8 byte = (u8)(word >> ((sizeof(u32) - i - 1) * 8));
|
||||||
if (leading_zeros < 0 && byte != 0)
|
data[out++] = byte;
|
||||||
leading_zeros = (int)i;
|
if (leading_zeros < 0 && byte != 0)
|
||||||
|
leading_zeros = (int)i;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
for (size_t i = word_count - 1; i > 0; i--) {
|
for (size_t i = word_count - (remove_leading_zeros ? 1 : 0); i > 0; i--) {
|
||||||
word = m_words[i - 1];
|
auto word = m_words[i - 1];
|
||||||
data[out++] = (u8)(word >> 24);
|
data[out++] = (u8)(word >> 24);
|
||||||
data[out++] = (u8)(word >> 16);
|
data[out++] = (u8)(word >> 16);
|
||||||
data[out++] = (u8)(word >> 8);
|
data[out++] = (u8)(word >> 8);
|
||||||
|
|
|
@ -59,7 +59,7 @@ public:
|
||||||
return UnsignedBigInteger(ptr, length);
|
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);
|
static UnsignedBigInteger from_base10(const String& str);
|
||||||
String to_base10() const;
|
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 exp = NumberTheory::ModularPower(in_integer, m_public_key.public_exponent(), m_public_key.modulus());
|
||||||
auto size = exp.export_data(out.span());
|
auto size = exp.export_data(out.span());
|
||||||
// FIXME: We should probably not do this...
|
auto outsize = out.size();
|
||||||
if (size != out.size())
|
if (size != outsize) {
|
||||||
out = out.slice(out.size() - size, size);
|
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)
|
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!)
|
// since arc4random can create zeros (shocking!)
|
||||||
// we have to go through and un-zero the zeros
|
// we have to go through and un-zero the zeros
|
||||||
for (size_t i = 0; i < ps_length; ++i)
|
for (size_t i = 0; i < ps_length; ++i)
|
||||||
if (!ps[i])
|
while (!ps[i])
|
||||||
ps[i] = 0xfe;
|
AK::fill_with_random(ps + i, 1);
|
||||||
|
|
||||||
u8 paddings[] { 0x00, 0x02 };
|
u8 paddings[] { 0x00, 0x02 };
|
||||||
|
|
||||||
|
|
|
@ -1933,7 +1933,7 @@ void bigint_import_export()
|
||||||
I_TEST((BigInteger | BigEndian Export));
|
I_TEST((BigInteger | BigEndian Export));
|
||||||
auto number = "448378203247"_bigint;
|
auto number = "448378203247"_bigint;
|
||||||
char exported[8] { 0 };
|
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) {
|
if (exported_length == 5 && memcmp(exported + 3, "hello", 5) == 0) {
|
||||||
PASS;
|
PASS;
|
||||||
} else {
|
} else {
|
||||||
|
|
Loading…
Reference in a new issue