summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnotherTest <ali.mpfard@gmail.com>2020-04-23 03:03:05 +0430
committerAndreas Kling <kling@serenityos.org>2020-05-02 12:24:10 +0200
commit05e2c7d9cf529c4b635f762fc1b5683c076cb00e (patch)
treeaa1ade0b6aca6a662be6ac731f2d4c0e590513e9
parenta1e15705529e9edaa4c67ed8683e7f987c4e473c (diff)
downloadserenity-05e2c7d9cf529c4b635f762fc1b5683c076cb00e.zip
LibCrypto+LibTLS: Reformat everything
I have no idea how I'll squash _this_ one...
-rw-r--r--Libraries/LibCrypto/ASN1/ASN1.h139
-rw-r--r--Libraries/LibCrypto/ASN1/DER.h8
-rw-r--r--Libraries/LibCrypto/Authentication/HMAC.h166
-rw-r--r--Libraries/LibCrypto/Hash/HashFunction.h32
-rw-r--r--Libraries/LibCrypto/Hash/MD5.cpp281
-rw-r--r--Libraries/LibCrypto/Hash/MD5.h165
-rw-r--r--Libraries/LibCrypto/Hash/SHA2.cpp400
-rw-r--r--Libraries/LibCrypto/Hash/SHA2.h310
-rw-r--r--Libraries/LibCrypto/NumberTheory/ModularFunctions.h272
-rw-r--r--Libraries/LibCrypto/PK/Code/Code.h46
-rw-r--r--Libraries/LibCrypto/PK/Code/EMSA_PSS.h217
-rw-r--r--Libraries/LibCrypto/PK/PK.h48
-rw-r--r--Libraries/LibCrypto/PK/RSA.cpp444
-rw-r--r--Libraries/LibCrypto/PK/RSA.h392
14 files changed, 1464 insertions, 1456 deletions
diff --git a/Libraries/LibCrypto/ASN1/ASN1.h b/Libraries/LibCrypto/ASN1/ASN1.h
index 96be0f896e..42429f1a7f 100644
--- a/Libraries/LibCrypto/ASN1/ASN1.h
+++ b/Libraries/LibCrypto/ASN1/ASN1.h
@@ -32,80 +32,81 @@
namespace Crypto {
namespace ASN1 {
- enum class Kind {
- Eol,
- Boolean,
- Integer,
- ShortInteger,
- BitString,
- OctetString,
- Null,
- ObjectIdentifier,
- IA5String,
- PrintableString,
- Utf8String,
- UTCTime,
- Choice,
- Sequence,
- Set,
- SetOf
- };
- static StringView kind_name(Kind kind)
- {
- switch (kind) {
- case Kind::Eol:
- return "EndOfList";
- case Kind::Boolean:
- return "Boolean";
- case Kind::Integer:
- return "Integer";
- case Kind::ShortInteger:
- return "ShortInteger";
- case Kind::BitString:
- return "BitString";
- case Kind::OctetString:
- return "OctetString";
- case Kind::Null:
- return "Null";
- case Kind::ObjectIdentifier:
- return "ObjectIdentifier";
- case Kind::IA5String:
- return "IA5String";
- case Kind::PrintableString:
- return "PrintableString";
- case Kind::Utf8String:
- return "UTF8String";
- case Kind::UTCTime:
- return "UTCTime";
- case Kind::Choice:
- return "Choice";
- case Kind::Sequence:
- return "Sequence";
- case Kind::Set:
- return "Set";
- case Kind::SetOf:
- return "SetOf";
- }
+enum class Kind {
+ Eol,
+ Boolean,
+ Integer,
+ ShortInteger,
+ BitString,
+ OctetString,
+ Null,
+ ObjectIdentifier,
+ IA5String,
+ PrintableString,
+ Utf8String,
+ UTCTime,
+ Choice,
+ Sequence,
+ Set,
+ SetOf
+};
- return "InvalidKind";
+static StringView kind_name(Kind kind)
+{
+ switch (kind) {
+ case Kind::Eol:
+ return "EndOfList";
+ case Kind::Boolean:
+ return "Boolean";
+ case Kind::Integer:
+ return "Integer";
+ case Kind::ShortInteger:
+ return "ShortInteger";
+ case Kind::BitString:
+ return "BitString";
+ case Kind::OctetString:
+ return "OctetString";
+ case Kind::Null:
+ return "Null";
+ case Kind::ObjectIdentifier:
+ return "ObjectIdentifier";
+ case Kind::IA5String:
+ return "IA5String";
+ case Kind::PrintableString:
+ return "PrintableString";
+ case Kind::Utf8String:
+ return "UTF8String";
+ case Kind::UTCTime:
+ return "UTCTime";
+ case Kind::Choice:
+ return "Choice";
+ case Kind::Sequence:
+ return "Sequence";
+ case Kind::Set:
+ return "Set";
+ case Kind::SetOf:
+ return "SetOf";
}
- struct List {
- Kind kind;
- void* data;
- size_t size;
- bool used;
- List *prev, *next, *child, *parent;
- };
+ return "InvalidKind";
+}
- static constexpr void set(List& list, Kind type, void* data, size_t size)
- {
- list.kind = type;
- list.data = data;
- list.size = size;
- list.used = false;
- }
+struct List {
+ Kind kind;
+ void* data;
+ size_t size;
+ bool used;
+ List *prev, *next, *child, *parent;
+};
+
+static constexpr void set(List& list, Kind type, void* data, size_t size)
+{
+ list.kind = type;
+ list.data = data;
+ list.size = size;
+ list.used = false;
+}
}
}
diff --git a/Libraries/LibCrypto/ASN1/DER.h b/Libraries/LibCrypto/ASN1/DER.h
index 3cf8c55a06..32552c21f7 100644
--- a/Libraries/LibCrypto/ASN1/DER.h
+++ b/Libraries/LibCrypto/ASN1/DER.h
@@ -376,7 +376,7 @@ static bool der_decode_sequence(const u8* in, size_t in_length, ASN1::List* list
return true;
}
-template <size_t element_count>
+template<size_t element_count>
struct der_decode_sequence_many_base {
constexpr void set(size_t index, ASN1::Kind kind, size_t size, void* data)
{
@@ -399,10 +399,10 @@ protected:
size_t m_in_length;
};
-template <size_t element_count>
+template<size_t element_count>
struct der_decode_sequence_many : public der_decode_sequence_many_base<element_count> {
- template <typename ElementType, typename... Args>
+ template<typename ElementType, typename... Args>
constexpr void construct(size_t index, ASN1::Kind kind, size_t size, ElementType data, Args... args)
{
der_decode_sequence_many_base<element_count>::set(index, kind, size, (void*)data);
@@ -414,7 +414,7 @@ struct der_decode_sequence_many : public der_decode_sequence_many_base<element_c
ASSERT(index == element_count);
}
- template <typename... Args>
+ template<typename... Args>
constexpr der_decode_sequence_many(const u8* in, size_t in_length, Args... args)
: der_decode_sequence_many_base<element_count>(in, in_length)
{
diff --git a/Libraries/LibCrypto/Authentication/HMAC.h b/Libraries/LibCrypto/Authentication/HMAC.h
index acf906f25b..25fccba310 100644
--- a/Libraries/LibCrypto/Authentication/HMAC.h
+++ b/Libraries/LibCrypto/Authentication/HMAC.h
@@ -38,97 +38,99 @@ constexpr static auto OPAD = 0x5c;
namespace Crypto {
namespace Authentication {
- template <typename HashT>
- class HMAC {
- public:
- using HashType = HashT;
- using TagType = typename HashType::DigestType;
- static constexpr size_t BlockSize = HashType::BlockSize;
- static constexpr size_t DigestSize = HashType::DigestSize;
-
- template <typename KeyBufferType, typename... Args>
- HMAC(KeyBufferType key, Args... args)
- : m_inner_hasher(args...)
- , m_outer_hasher(args...)
- {
- derive_key(key);
- reset();
- }
- TagType process(const u8* message, size_t length)
- {
- reset();
- update(message, length);
- return digest();
- }
+template<typename HashT>
+class HMAC {
+public:
+ using HashType = HashT;
+ using TagType = typename HashType::DigestType;
+ static constexpr size_t BlockSize = HashType::BlockSize;
+ static constexpr size_t DigestSize = HashType::DigestSize;
- void update(const u8* message, size_t length)
- {
- m_inner_hasher.update(message, length);
- }
+ template<typename KeyBufferType, typename... Args>
+ HMAC(KeyBufferType key, Args... args)
+ : m_inner_hasher(args...)
+ , m_outer_hasher(args...)
+ {
+ derive_key(key);
+ reset();
+ }
- TagType process(const ByteBuffer& buffer) { return process(buffer.data(), buffer.size()); }
- TagType process(const StringView& string) { return process((const u8*)string.characters_without_null_termination(), string.length()); }
- void update(const ByteBuffer& buffer) { return update(buffer.data(), buffer.size()); }
- void update(const StringView& string) { return update((const u8*)string.characters_without_null_termination(), string.length()); }
-
- TagType digest()
- {
- m_outer_hasher.update(m_inner_hasher.digest().data, m_inner_hasher.DigestSize);
- auto result = m_outer_hasher.digest();
- reset();
- return result;
- }
+ TagType process(const u8* message, size_t length)
+ {
+ reset();
+ update(message, length);
+ return digest();
+ }
- void reset()
- {
- m_inner_hasher.reset();
- m_outer_hasher.reset();
- m_inner_hasher.update(m_key_data, BlockSize);
- m_outer_hasher.update(m_key_data + BlockSize, BlockSize);
- }
+ void update(const u8* message, size_t length)
+ {
+ m_inner_hasher.update(message, length);
+ }
- String class_name() const
- {
- StringBuilder builder;
- builder.append("HMAC-");
- builder.append(m_inner_hasher.class_name());
- return builder.build();
+ TagType process(const ByteBuffer& buffer) { return process(buffer.data(), buffer.size()); }
+ TagType process(const StringView& string) { return process((const u8*)string.characters_without_null_termination(), string.length()); }
+ void update(const ByteBuffer& buffer) { return update(buffer.data(), buffer.size()); }
+ void update(const StringView& string) { return update((const u8*)string.characters_without_null_termination(), string.length()); }
+
+ TagType digest()
+ {
+ m_outer_hasher.update(m_inner_hasher.digest().data, m_inner_hasher.DigestSize);
+ auto result = m_outer_hasher.digest();
+ reset();
+ return result;
+ }
+
+ void reset()
+ {
+ m_inner_hasher.reset();
+ m_outer_hasher.reset();
+ m_inner_hasher.update(m_key_data, BlockSize);
+ m_outer_hasher.update(m_key_data + BlockSize, BlockSize);
+ }
+
+ String class_name() const
+ {
+ StringBuilder builder;
+ builder.append("HMAC-");
+ builder.append(m_inner_hasher.class_name());
+ return builder.build();
+ }
+
+private:
+ void derive_key(const u8* key, size_t length)
+ {
+ u8 v_key[BlockSize];
+ __builtin_memset(v_key, 0, BlockSize);
+ ByteBuffer key_buffer = ByteBuffer::wrap(v_key, BlockSize);
+ // m_key_data is zero'd, so copying the data in
+ // the first few bytes leaves the rest zero, which
+ // is exactly what we want (zero padding)
+ if (length > BlockSize) {
+ m_inner_hasher.update(key, length);
+ auto digest = m_inner_hasher.digest();
+ // FIXME: should we check if the hash function creates more data than its block size?
+ key_buffer.overwrite(0, digest.data, sizeof(TagType));
+ } else {
+ key_buffer.overwrite(0, key, length);
}
- private:
- void derive_key(const u8* key, size_t length)
- {
- u8 v_key[BlockSize];
- __builtin_memset(v_key, 0, BlockSize);
- ByteBuffer key_buffer = ByteBuffer::wrap(v_key, BlockSize);
- // m_key_data is zero'd, so copying the data in
- // the first few bytes leaves the rest zero, which
- // is exactly what we want (zero padding)
- if (length > BlockSize) {
- m_inner_hasher.update(key, length);
- auto digest = m_inner_hasher.digest();
- // FIXME: should we check if the hash function creates more data than its block size?
- key_buffer.overwrite(0, digest.data, sizeof(TagType));
- } else {
- key_buffer.overwrite(0, key, length);
- }
-
- // fill out the inner and outer padded keys
- auto* i_key = m_key_data;
- auto* o_key = m_key_data + BlockSize;
- for (size_t i = 0; i < BlockSize; ++i) {
- auto key_byte = key_buffer[i];
- i_key[i] = key_byte ^ IPAD;
- o_key[i] = key_byte ^ OPAD;
- }
+ // fill out the inner and outer padded keys
+ auto* i_key = m_key_data;
+ auto* o_key = m_key_data + BlockSize;
+ for (size_t i = 0; i < BlockSize; ++i) {
+ auto key_byte = key_buffer[i];
+ i_key[i] = key_byte ^ IPAD;
+ o_key[i] = key_byte ^ OPAD;
}
+ }
+
+ void derive_key(const ByteBuffer& key) { derive_key(key.data(), key.size()); }
+ void derive_key(const StringView& key) { derive_key((const u8*)key.characters_without_null_termination(), key.length()); }
- void derive_key(const ByteBuffer& key) { derive_key(key.data(), key.size()); }
- void derive_key(const StringView& key) { derive_key((const u8*)key.characters_without_null_termination(), key.length()); }
+ HashType m_inner_hasher, m_outer_hasher;
+ u8 m_key_data[BlockSize * 2];
+};
- HashType m_inner_hasher, m_outer_hasher;
- u8 m_key_data[BlockSize * 2];
- };
}
}
diff --git a/Libraries/LibCrypto/Hash/HashFunction.h b/Libraries/LibCrypto/Hash/HashFunction.h
index 0d626fcc48..19c2f0db05 100644
--- a/Libraries/LibCrypto/Hash/HashFunction.h
+++ b/Libraries/LibCrypto/Hash/HashFunction.h
@@ -33,27 +33,27 @@
namespace Crypto {
namespace Hash {
- template <size_t BlockS, typename DigestT>
- class HashFunction {
- public:
- static constexpr auto BlockSize = BlockS / 8;
- static constexpr auto DigestSize = sizeof(DigestT);
+template<size_t BlockS, typename DigestT>
+class HashFunction {
+public:
+ static constexpr auto BlockSize = BlockS / 8;
+ static constexpr auto DigestSize = sizeof(DigestT);
- using DigestType = DigestT;
+ using DigestType = DigestT;
- static size_t block_size() { return BlockSize; };
- static size_t digest_size() { return DigestSize; };
+ static size_t block_size() { return BlockSize; };
+ static size_t digest_size() { return DigestSize; };
- virtual void update(const u8*, size_t) = 0;
- virtual void update(const ByteBuffer& buffer) = 0;
- virtual void update(const StringView& string) = 0;
+ virtual void update(const u8*, size_t) = 0;
+ virtual void update(const ByteBuffer& buffer) = 0;
+ virtual void update(const StringView& string) = 0;
- virtual DigestType peek() = 0;
- virtual DigestType digest() = 0;
+ virtual DigestType peek() = 0;
+ virtual DigestType digest() = 0;
- virtual void reset() = 0;
+ virtual void reset() = 0;
- virtual String class_name() const = 0;
- };
+ virtual String class_name() const = 0;
+};
}
}
diff --git a/Libraries/LibCrypto/Hash/MD5.cpp b/Libraries/LibCrypto/Hash/MD5.cpp
index 2a44efb1fb..0cde62d29d 100644
--- a/Libraries/LibCrypto/Hash/MD5.cpp
+++ b/Libraries/LibCrypto/Hash/MD5.cpp
@@ -67,158 +67,159 @@ static constexpr inline void round_4(u32& a, u32 b, u32 c, u32 d, u32 x, u32 s,
namespace Crypto {
namespace Hash {
- void MD5::update(const u8* input, size_t length)
- {
- auto index = (u32)(m_count[0] >> 3) & 0x3f;
- size_t offset { 0 };
- m_count[0] += (u32)length << 3;
- if (m_count[0] < ((u32)length << 3)) {
- ++m_count[1];
- }
- m_count[1] += (u32)length >> 29;
-
- auto part_length = 64 - index;
- if (length >= part_length) {
- m_buffer.overwrite(index, input, part_length);
- transform(m_buffer.data());
-
- for (offset = part_length; offset + 63 < length; offset += 64)
- transform(&input[offset]);
-
- index = 0;
- }
- ASSERT(length < part_length || length - offset <= 64);
- m_buffer.overwrite(index, &input[offset], length - offset);
+void MD5::update(const u8* input, size_t length)
+{
+ auto index = (u32)(m_count[0] >> 3) & 0x3f;
+ size_t offset { 0 };
+ m_count[0] += (u32)length << 3;
+ if (m_count[0] < ((u32)length << 3)) {
+ ++m_count[1];
}
- MD5::DigestType MD5::digest()
- {
- auto digest = peek();
- reset();
- return digest;
+ m_count[1] += (u32)length >> 29;
+
+ auto part_length = 64 - index;
+ if (length >= part_length) {
+ m_buffer.overwrite(index, input, part_length);
+ transform(m_buffer.data());
+
+ for (offset = part_length; offset + 63 < length; offset += 64)
+ transform(&input[offset]);
+
+ index = 0;
}
- MD5::DigestType MD5::peek()
- {
- DigestType digest;
- u8 bits[8];
+ ASSERT(length < part_length || length - offset <= 64);
+ m_buffer.overwrite(index, &input[offset], length - offset);
+}
+MD5::DigestType MD5::digest()
+{
+ auto digest = peek();
+ reset();
+ return digest;
+}
- encode(m_count, bits, 8);
+MD5::DigestType MD5::peek()
+{
+ DigestType digest;
+ u8 bits[8];
- // pad the data to 56%64
- u32 index = (u32)((m_count[0] >> 3) & 0x3f);
- u32 pad_length = index < 56 ? 56 - index : 120 - index;
- update(MD5Constants::PADDING, pad_length);
+ encode(m_count, bits, 8);
- // append length
- update(bits, 8);
+ // pad the data to 56%64
+ u32 index = (u32)((m_count[0] >> 3) & 0x3f);
+ u32 pad_length = index < 56 ? 56 - index : 120 - index;
+ update(MD5Constants::PADDING, pad_length);
- // store state (4 registers ABCD)
- encode(&m_A, digest.data, 4 * sizeof(m_A));
+ // append length
+ update(bits, 8);
- return digest;
- }
+ // store state (4 registers ABCD)
+ encode(&m_A, digest.data, 4 * sizeof(m_A));
- void MD5::encode(const u32* from, u8* to, size_t length)
- {
- for (size_t i = 0, j = 0; j < length; ++i, j += 4) {
- to[j] = (u8)(from[i] & 0xff);
- to[j + 1] = (u8)((from[i] >> 8) & 0xff);
- to[j + 2] = (u8)((from[i] >> 16) & 0xff);
- to[j + 3] = (u8)((from[i] >> 24) & 0xff);
- }
- }
+ return digest;
+}
- void MD5::decode(const u8* from, u32* to, size_t length)
- {
- for (size_t i = 0, j = 0; j < length; ++i, j += 4)
- to[i] = (((u32)from[j]) | (((u32)from[j + 1]) << 8) | (((u32)from[j + 2]) << 16) | (((u32)from[j + 3]) << 24));
+void MD5::encode(const u32* from, u8* to, size_t length)
+{
+ for (size_t i = 0, j = 0; j < length; ++i, j += 4) {
+ to[j] = (u8)(from[i] & 0xff);
+ to[j + 1] = (u8)((from[i] >> 8) & 0xff);
+ to[j + 2] = (u8)((from[i] >> 16) & 0xff);
+ to[j + 3] = (u8)((from[i] >> 24) & 0xff);
}
+}
- void MD5::transform(const u8* block)
- {
- auto a = m_A;
- auto b = m_B;
- auto c = m_C;
- auto d = m_D;
- u32 x[16];
-
- decode(block, x, 64);
-
- round_1(a, b, c, d, x[0], MD5Constants::S11, 0xd76aa478); // 1
- round_1(d, a, b, c, x[1], MD5Constants::S12, 0xe8c7b756); // 2
- round_1(c, d, a, b, x[2], MD5Constants::S13, 0x242070db); // 3
- round_1(b, c, d, a, x[3], MD5Constants::S14, 0xc1bdceee); // 4
- round_1(a, b, c, d, x[4], MD5Constants::S11, 0xf57c0faf); // 5
- round_1(d, a, b, c, x[5], MD5Constants::S12, 0x4787c62a); // 6
- round_1(c, d, a, b, x[6], MD5Constants::S13, 0xa8304613); // 7
- round_1(b, c, d, a, x[7], MD5Constants::S14, 0xfd469501); // 8
- round_1(a, b, c, d, x[8], MD5Constants::S11, 0x698098d8); // 9
- round_1(d, a, b, c, x[9], MD5Constants::S12, 0x8b44f7af); // 10
- round_1(c, d, a, b, x[10], MD5Constants::S13, 0xffff5bb1); // 11
- round_1(b, c, d, a, x[11], MD5Constants::S14, 0x895cd7be); // 12
- round_1(a, b, c, d, x[12], MD5Constants::S11, 0x6b901122); // 13
- round_1(d, a, b, c, x[13], MD5Constants::S12, 0xfd987193); // 14
- round_1(c, d, a, b, x[14], MD5Constants::S13, 0xa679438e); // 15
- round_1(b, c, d, a, x[15], MD5Constants::S14, 0x49b40821); // 16
-
- round_2(a, b, c, d, x[1], MD5Constants::S21, 0xf61e2562); // 17
- round_2(d, a, b, c, x[6], MD5Constants::S22, 0xc040b340); // 18
- round_2(c, d, a, b, x[11], MD5Constants::S23, 0x265e5a51); // 19
- round_2(b, c, d, a, x[0], MD5Constants::S24, 0xe9b6c7aa); // 20
- round_2(a, b, c, d, x[5], MD5Constants::S21, 0xd62f105d); // 21
- round_2(d, a, b, c, x[10], MD5Constants::S22, 0x2441453); // 22
- round_2(c, d, a, b, x[15], MD5Constants::S23, 0xd8a1e681); // 23
- round_2(b, c, d, a, x[4], MD5Constants::S24, 0xe7d3fbc8); // 24
- round_2(a, b, c, d, x[9], MD5Constants::S21, 0x21e1cde6); // 25
- round_2(d, a, b, c, x[14], MD5Constants::S22, 0xc33707d6); // 26
- round_2(c, d, a, b, x[3], MD5Constants::S23, 0xf4d50d87); // 27
- round_2(b, c, d, a, x[8], MD5Constants::S24, 0x455a14ed); // 28
- round_2(a, b, c, d, x[13], MD5Constants::S21, 0xa9e3e905); // 29
- round_2(d, a, b, c, x[2], MD5Constants::S22, 0xfcefa3f8); // 30
- round_2(c, d, a, b, x[7], MD5Constants::S23, 0x676f02d9); // 31
- round_2(b, c, d, a, x[12], MD5Constants::S24, 0x8d2a4c8a); // 32
-
- round_3(a, b, c, d, x[5], MD5Constants::S31, 0xfffa3942); // 33
- round_3(d, a, b, c, x[8], MD5Constants::S32, 0x8771f681); // 34
- round_3(c, d, a, b, x[11], MD5Constants::S33, 0x6d9d6122); // 35
- round_3(b, c, d, a, x[14], MD5Constants::S34, 0xfde5380c); // 36
- round_3(a, b, c, d, x[1], MD5Constants::S31, 0xa4beea44); // 37
- round_3(d, a, b, c, x[4], MD5Constants::S32, 0x4bdecfa9); // 38
- round_3(c, d, a, b, x[7], MD5Constants::S33, 0xf6bb4b60); // 39
- round_3(b, c, d, a, x[10], MD5Constants::S34, 0xbebfbc70); // 40
- round_3(a, b, c, d, x[13], MD5Constants::S31, 0x289b7ec6); // 41
- round_3(d, a, b, c, x[0], MD5Constants::S32, 0xeaa127fa); // 42
- round_3(c, d, a, b, x[3], MD5Constants::S33, 0xd4ef3085); // 43
- round_3(b, c, d, a, x[6], MD5Constants::S34, 0x4881d05); // 44
- round_3(a, b, c, d, x[9], MD5Constants::S31, 0xd9d4d039); // 45
- round_3(d, a, b, c, x[12], MD5Constants::S32, 0xe6db99e5); // 46
- round_3(c, d, a, b, x[15], MD5Constants::S33, 0x1fa27cf8); // 47
- round_3(b, c, d, a, x[2], MD5Constants::S34, 0xc4ac5665); // 48
-
- round_4(a, b, c, d, x[0], MD5Constants::S41, 0xf4292244); // 49
- round_4(d, a, b, c, x[7], MD5Constants::S42, 0x432aff97); // 50
- round_4(c, d, a, b, x[14], MD5Constants::S43, 0xab9423a7); // 51
- round_4(b, c, d, a, x[5], MD5Constants::S44, 0xfc93a039); // 52
- round_4(a, b, c, d, x[12], MD5Constants::S41, 0x655b59c3); // 53
- round_4(d, a, b, c, x[3], MD5Constants::S42, 0x8f0ccc92); // 54
- round_4(c, d, a, b, x[10], MD5Constants::S43, 0xffeff47d); // 55
- round_4(b, c, d, a, x[1], MD5Constants::S44, 0x85845dd1); // 56
- round_4(a, b, c, d, x[8], MD5Constants::S41, 0x6fa87e4f); // 57
- round_4(d, a, b, c, x[15], MD5Constants::S42, 0xfe2ce6e0); // 58
- round_4(c, d, a, b, x[6], MD5Constants::S43, 0xa3014314); // 59
- round_4(b, c, d, a, x[13], MD5Constants::S44, 0x4e0811a1); // 60
- round_4(a, b, c, d, x[4], MD5Constants::S41, 0xf7537e82); // 61
- round_4(d, a, b, c, x[11], MD5Constants::S42, 0xbd3af235); // 62
- round_4(c, d, a, b, x[2], MD5Constants::S43, 0x2ad7d2bb); // 63
- round_4(b, c, d, a, x[9], MD5Constants::S44, 0xeb86d391); // 64
-
- m_A += a;
- m_B += b;
- m_C += c;
- m_D += d;
-
- __builtin_memset(x, 0, sizeof(x));
- }
+void MD5::decode(const u8* from, u32* to, size_t length)
+{
+ for (size_t i = 0, j = 0; j < length; ++i, j += 4)
+ to[i] = (((u32)from[j]) | (((u32)from[j + 1]) << 8) | (((u32)from[j + 2]) << 16) | (((u32)from[j + 3]) << 24));
+}
+
+void MD5::transform(const u8* block)
+{
+ auto a = m_A;
+ auto b = m_B;
+ auto c = m_C;
+ auto d = m_D;
+ u32 x[16];
+
+ decode(block, x, 64);
+
+ round_1(a, b, c, d, x[0], MD5Constants::S11, 0xd76aa478); // 1
+ round_1(d, a, b, c, x[1], MD5Constants::S12, 0xe8c7b756); // 2
+ round_1(c, d, a, b, x[2], MD5Constants::S13, 0x242070db); // 3
+ round_1(b, c, d, a, x[3], MD5Constants::S14, 0xc1bdceee); // 4
+ round_1(a, b, c, d, x[4], MD5Constants::S11, 0xf57c0faf); // 5
+ round_1(d, a, b, c, x[5], MD5Constants::S12, 0x4787c62a); // 6
+ round_1(c, d, a, b, x[6], MD5Constants::S13, 0xa8304613); // 7
+ round_1(b, c, d, a, x[7], MD5Constants::S14, 0xfd469501); // 8
+ round_1(a, b, c, d, x[8], MD5Constants::S11, 0x698098d8); // 9
+ round_1(d, a, b, c, x[9], MD5Constants::S12, 0x8b44f7af); // 10
+ round_1(c, d, a, b, x[10], MD5Constants::S13, 0xffff5bb1); // 11
+ round_1(b, c, d, a, x[11], MD5Constants::S14, 0x895cd7be); // 12
+ round_1(a, b, c, d, x[12], MD5Constants::S11, 0x6b901122); // 13
+ round_1(d, a, b, c, x[13], MD5Constants::S12, 0xfd987193); // 14
+ round_1(c, d, a, b, x[14], MD5Constants::S13, 0xa679438e); // 15
+ round_1(b, c, d, a, x[15], MD5Constants::S14, 0x49b40821); // 16
+
+ round_2(a, b, c, d, x[1], MD5Constants::S21, 0xf61e2562); // 17
+ round_2(d, a, b, c, x[6], MD5Constants::S22, 0xc040b340); // 18
+ round_2(c, d, a, b, x[11], MD5Constants::S23, 0x265e5a51); // 19
+ round_2(b, c, d, a, x[0], MD5Constants::S24, 0xe9b6c7aa); // 20
+ round_2(a, b, c, d, x[5], MD5Constants::S21, 0xd62f105d); // 21
+ round_2(d, a, b, c, x[10], MD5Constants::S22, 0x2441453); // 22
+ round_2(c, d, a, b, x[15], MD5Constants::S23, 0xd8a1e681); // 23
+ round_2(b, c, d, a, x[4], MD5Constants::S24, 0xe7d3fbc8); // 24
+ round_2(a, b, c, d, x[9], MD5Constants::S21, 0x21e1cde6); // 25
+ round_2(d, a, b, c, x[14], MD5Constants::S22, 0xc33707d6); // 26
+ round_2(c, d, a, b, x[3], MD5Constants::S23, 0xf4d50d87); // 27
+ round_2(b, c, d, a, x[8], MD5Constants::S24, 0x455a14ed); // 28
+ round_2(a, b, c, d, x[13], MD5Constants::S21, 0xa9e3e905); // 29
+ round_2(d, a, b, c, x[2], MD5Constants::S22, 0xfcefa3f8); // 30
+ round_2(c, d, a, b, x[7], MD5Constants::S23, 0x676f02d9); // 31
+ round_2(b, c, d, a, x[12], MD5Constants::S24, 0x8d2a4c8a); // 32
+
+ round_3(a, b, c, d, x[5], MD5Constants::S31, 0xfffa3942); // 33
+ round_3(d, a, b, c, x[8], MD5Constants::S32, 0x8771f681); // 34
+ round_3(c, d, a, b, x[11], MD5Constants::S33, 0x6d9d6122); // 35
+ round_3(b, c, d, a, x[14], MD5Constants::S34, 0xfde5380c); // 36
+ round_3(a, b, c, d, x[1], MD5Constants::S31, 0xa4beea44); // 37
+ round_3(d, a, b, c, x[4], MD5Constants::S32, 0x4bdecfa9); // 38
+ round_3(c, d, a, b, x[7], MD5Constants::S33, 0xf6bb4b60); // 39
+ round_3(b, c, d, a, x[10], MD5Constants::S34, 0xbebfbc70); // 40
+ round_3(a, b, c, d, x[13], MD5Constants::S31, 0x289b7ec6); // 41
+ round_3(d, a, b, c, x[0], MD5Constants::S32, 0xeaa127fa); // 42
+ round_3(c, d, a, b, x[3], MD5Constants::S33, 0xd4ef3085); // 43
+ round_3(b, c, d, a, x[6], MD5Constants::S34, 0x4881d05); // 44
+ round_3(a, b, c, d, x[9], MD5Constants::S31, 0xd9d4d039); // 45
+ round_3(d, a, b, c, x[12], MD5Constants::S32, 0xe6db99e5); // 46
+ round_3(c, d, a, b, x[15], MD5Constants::S33, 0x1fa27cf8); // 47
+ round_3(b, c, d, a, x[2], MD5Constants::S34, 0xc4ac5665); // 48
+
+ round_4(a, b, c, d, x[0], MD5Constants::S41, 0xf4292244); // 49
+ round_4(d, a, b, c, x[7], MD5Constants::S42, 0x432aff97); // 50
+ round_4(c, d, a, b, x[14], MD5Constants::S43, 0xab9423a7); // 51
+ round_4(b, c, d, a, x[5], MD5Constants::S44, 0xfc93a039); // 52
+ round_4(a, b, c, d, x[12], MD5Constants::S41, 0x655b59c3); // 53
+ round_4(d, a, b, c, x[3], MD5Constants::S42, 0x8f0ccc92); // 54
+ round_4(c, d, a, b, x[10], MD5Constants::S43, 0xffeff47d); // 55
+ round_4(b, c, d, a, x[1], MD5Constants::S44, 0x85845dd1); // 56
+ round_4(a, b, c, d, x[8], MD5Constants::S41, 0x6fa87e4f); // 57
+ round_4(d, a, b, c, x[15], MD5Constants::S42, 0xfe2ce6e0); // 58
+ round_4(c, d, a, b, x[6], MD5Constants::S43, 0xa3014314); // 59
+ round_4(b, c, d, a, x[13], MD5Constants::S44, 0x4e0811a1); // 60
+ round_4(a, b, c, d, x[4], MD5Constants::S41, 0xf7537e82); // 61
+ round_4(d, a, b, c, x[11], MD5Constants::S42, 0xbd3af235); // 62
+ round_4(c, d, a, b, x[2], MD5Constants::S43, 0x2ad7d2bb); // 63
+ round_4(b, c, d, a, x[9], MD5Constants::S44, 0xeb86d391); // 64
+
+ m_A += a;
+ m_B += b;
+ m_C += c;
+ m_D += d;
+
+ __builtin_memset(x, 0, sizeof(x));
+}
}
}
diff --git a/Libraries/LibCrypto/Hash/MD5.h b/Libraries/LibCrypto/Hash/MD5.h
index 12da7c84dc..883029527c 100644
--- a/Libraries/LibCrypto/Hash/MD5.h
+++ b/Libraries/LibCrypto/Hash/MD5.h
@@ -33,90 +33,91 @@
namespace Crypto {
namespace Hash {
- struct MD5Digest {
- u8 data[16];
- };
-
- namespace MD5Constants {
-
- constexpr u32 init_A = 0x67452301;
- constexpr u32 init_B = 0xefcdab89;
- constexpr u32 init_C = 0x98badcfe;
- constexpr u32 init_D = 0x10325476;
- constexpr u32 S11 = 7;
- constexpr u32 S12 = 12;
- constexpr u32 S13 = 17;
- constexpr u32 S14 = 22;
- constexpr u32 S21 = 5;
- constexpr u32 S22 = 9;
- constexpr u32 S23 = 14;
- constexpr u32 S24 = 20;
- constexpr u32 S31 = 4;
- constexpr u32 S32 = 11;
- constexpr u32 S33 = 16;
- constexpr u32 S34 = 23;
- constexpr u32 S41 = 6;
- constexpr u32 S42 = 10;
- constexpr u32 S43 = 15;
- constexpr u32 S44 = 21;
- constexpr u8 PADDING[] = {
- 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0
- };
+struct MD5Digest {
+ u8 data[16];
+};
+
+namespace MD5Constants {
+
+constexpr u32 init_A = 0x67452301;
+constexpr u32 init_B = 0xefcdab89;
+constexpr u32 init_C = 0x98badcfe;
+constexpr u32 init_D = 0x10325476;
+constexpr u32 S11 = 7;
+constexpr u32 S12 = 12;
+constexpr u32 S13 = 17;
+constexpr u32 S14 = 22;
+constexpr u32 S21 = 5;
+constexpr u32 S22 = 9;
+constexpr u32 S23 = 14;
+constexpr u32 S24 = 20;
+constexpr u32 S31 = 4;
+constexpr u32 S32 = 11;
+constexpr u32 S33 = 16;
+constexpr u32 S34 = 23;
+constexpr u32 S41 = 6;
+constexpr u32 S42 = 10;
+constexpr u32 S43 = 15;
+constexpr u32 S44 = 21;
+constexpr u8 PADDING[] = {
+ 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0
+};
+
+}
+
+class MD5 final : public HashFunction<512, MD5Digest> {
+public:
+ MD5()
+ {
+ m_buffer = ByteBuffer::wrap(m_data_buffer, sizeof(m_data_buffer));
+ }
+
+ virtual void update(const u8*, size_t) override;
+ virtual void update(const ByteBuffer& buffer) override { update(buffer.data(), buffer.size()); };
+ virtual void update(const StringView& string) override { update((const u8*)string.characters_without_null_termination(), string.length()); };
+ virtual DigestType digest() override;
+ virtual DigestType peek() override;
+
+ virtual String class_name() const override { return "MD5"; }
+
+ inline static DigestType hash(const u8* data, size_t length)
+ {
+ MD5 md5;
+ md5.update(data, length);
+ return md5.digest();
}
- class MD5 final : public HashFunction<512, MD5Digest> {
- public:
- MD5()
- {
- m_buffer = ByteBuffer::wrap(m_data_buffer, sizeof(m_data_buffer));
- }
-
- virtual void update(const u8*, size_t) override;
- virtual void update(const ByteBuffer& buffer) override { update(buffer.data(), buffer.size()); };
- virtual void update(const StringView& string) override { update((const u8*)string.characters_without_null_termination(), string.length()); };
- virtual DigestType digest() override;
- virtual DigestType peek() override;
-
- virtual String class_name() const override { return "MD5"; }
-
- inline static DigestType hash(const u8* data, size_t length)
- {
- MD5 md5;
- md5.update(data, length);
- return md5.digest();
- }
-
- inline static DigestType hash(const ByteBuffer& buffer) { return hash(buffer.data(), buffer.size()); }
- inline static DigestType hash(const StringView& buffer) { return hash((const u8*)buffer.characters_without_null_termination(), buffer.length()); }
- inline virtual void reset() override
- {
- m_A = MD5Constants::init_A;
- m_B = MD5Constants::init_B;
- m_C = MD5Constants::init_C;
- m_D = MD5Constants::init_D;
-
- m_count[0] = 0;
- m_count[1] = 0;
-
- __builtin_memset(m_data_buffer, 0, sizeof(m_data_buffer));
- }
-
- private:
- inline void transform(const u8*);
-
- static void encode(const u32* from, u8* to, size_t length);
- static void decode(const u8* from, u32* to, size_t length);
-
- u32 m_A { MD5Constants::init_A }, m_B { MD5Constants::init_B }, m_C { MD5Constants::init_C }, m_D { MD5Constants::init_D };
- u32 m_count[2] { 0, 0 };
- ByteBuffer m_buffer;
-
- u8 m_data_buffer[64];
- };
+ inline static DigestType hash(const ByteBuffer& buffer) { return hash(buffer.data(), buffer.size()); }
+ inline static DigestType hash(const StringView& buffer) { return hash((const u8*)buffer.characters_without_null_termination(), buffer.length()); }
+ inline virtual void reset() override
+ {
+ m_A = MD5Constants::init_A;
+ m_B = MD5Constants::init_B;
+ m_C = MD5Constants::init_C;
+ m_D = MD5Constants::init_D;
+
+ m_count[0] = 0;
+ m_count[1] = 0;
+
+ __builtin_memset(m_data_buffer, 0, sizeof(m_data_buffer));
+ }
+
+private:
+ inline void transform(const u8*);
+
+ static void encode(const u32* from, u8* to, size_t length);
+ static void decode(const u8* from, u32* to, size_t length);
+
+ u32 m_A { MD5Constants::init_A }, m_B { MD5Constants::init_B }, m_C { MD5Constants::init_C }, m_D { MD5Constants::init_D };
+ u32 m_count[2] { 0, 0 };
+ ByteBuffer m_buffer;
+
+ u8 m_data_buffer[64];
+};
}
diff --git a/Libraries/LibCrypto/Hash/SHA2.cpp b/Libraries/LibCrypto/Hash/SHA2.cpp
index 6073276b41..a0fb9de78a 100644
--- a/Libraries/LibCrypto/Hash/SHA2.cpp
+++ b/Libraries/LibCrypto/Hash/SHA2.cpp
@@ -29,236 +29,236 @@
namespace Crypto {
namespace Hash {
- constexpr inline static auto ROTRIGHT(u32 a, size_t b) { return (a >> b) | (a << (32 - b)); }
- constexpr inline static auto CH(u32 x, u32 y, u32 z) { return (x & y) ^ (z & ~x); }
- constexpr inline static auto MAJ(u32 x, u32 y, u32 z) { return (x & y) ^ (x & z) ^ (y & z); }
- constexpr inline static auto EP0(u32 x) { return ROTRIGHT(x, 2) ^ ROTRIGHT(x, 13) ^ ROTRIGHT(x, 22); }
- constexpr inline static auto EP1(u32 x) { return ROTRIGHT(x, 6) ^ ROTRIGHT(x, 11) ^ ROTRIGHT(x, 25); }
- constexpr inline static auto SIGN0(u32 x) { return ROTRIGHT(x, 7) ^ ROTRIGHT(x, 18) ^ (x >> 3); }
- constexpr inline static auto SIGN1(u32 x) { return ROTRIGHT(x, 17) ^ ROTRIGHT(x, 19) ^ (x >> 10); }
-
- constexpr inline static auto ROTRIGHT(u64 a, size_t b) { return (a >> b) | (a << (64 - b)); }
- constexpr inline static auto CH(u64 x, u64 y, u64 z) { return (x & y) ^ (z & ~x); }
- constexpr inline static auto MAJ(u64 x, u64 y, u64 z) { return (x & y) ^ (x & z) ^ (y & z); }
- constexpr inline static auto EP0(u64 x) { return ROTRIGHT(x, 28) ^ ROTRIGHT(x, 34) ^ ROTRIGHT(x, 39); }
- constexpr inline static auto EP1(u64 x) { return ROTRIGHT(x, 14) ^ ROTRIGHT(x, 18) ^ ROTRIGHT(x, 41); }
- constexpr inline static auto SIGN0(u64 x) { return ROTRIGHT(x, 1) ^ ROTRIGHT(x, 8) ^ (x >> 7); }
- constexpr inline static auto SIGN1(u64 x) { return ROTRIGHT(x, 19) ^ ROTRIGHT(x, 61) ^ (x >> 6); }
-
- inline void SHA256::transform(const u8* data)
- {
- u32 m[64];
-
- size_t i = 0;
- for (size_t j = 0; i < 16; ++i, j += 4) {
- m[i] = (data[j] << 24) | (data[j + 1] << 16) | (data[j + 2] << 8) | data[j + 3];
- }
-
- for (; i < BlockSize; ++i) {
- m[i] = SIGN1(m[i - 2]) + m[i - 7] + SIGN0(m[i - 15]) + m[i - 16];
- }
-
- auto a = m_state[0], b = m_state[1],
- c = m_state[2], d = m_state[3],
- e = m_state[4], f = m_state[5],
- g = m_state[6], h = m_state[7];
-
- for (size_t i = 0; i < Rounds; ++i) {
- auto temp0 = h + EP1(e) + CH(e, f, g) + SHA256Constants::RoundConstants[i] + m[i];
- auto temp1 = EP0(a) + MAJ(a, b, c);
- h = g;
- g = f;
- f = e;
- e = d + temp0;
- d = c;
- c = b;
- b = a;
- a = temp0 + temp1;
- }
-
- m_state[0] += a;
- m_state[1] += b;
- m_state[2] += c;
- m_state[3] += d;
- m_state[4] += e;
- m_state[5] += f;
- m_state[6] += g;
- m_state[7] += h;
+constexpr inline static auto ROTRIGHT(u32 a, size_t b) { return (a >> b) | (a << (32 - b)); }
+constexpr inline static auto CH(u32 x, u32 y, u32 z) { return (x & y) ^ (z & ~x); }
+constexpr inline static auto MAJ(u32 x, u32 y, u32 z) { return (x & y) ^ (x & z) ^ (y & z); }
+constexpr inline static auto EP0(u32 x) { return ROTRIGHT(x, 2) ^ ROTRIGHT(x, 13) ^ ROTRIGHT(x, 22); }
+constexpr inline static auto EP1(u32 x) { return ROTRIGHT(x, 6) ^ ROTRIGHT(x, 11) ^ ROTRIGHT(x, 25); }
+constexpr inline static auto SIGN0(u32 x) { return ROTRIGHT(x, 7) ^ ROTRIGHT(x, 18) ^ (x >> 3); }
+constexpr inline static auto SIGN1(u32 x) { return ROTRIGHT(x, 17) ^ ROTRIGHT(x, 19) ^ (x >> 10); }
+
+constexpr inline static auto ROTRIGHT(u64 a, size_t b) { return (a >> b) | (a << (64 - b)); }
+constexpr inline static auto CH(u64 x, u64 y, u64 z) { return (x & y) ^ (z & ~x); }
+constexpr inline static auto MAJ(u64 x, u64 y, u64 z) { return (x & y) ^ (x & z) ^ (y & z); }
+constexpr inline static auto EP0(u64 x) { return ROTRIGHT(x, 28) ^ ROTRIGHT(x, 34) ^ ROTRIGHT(x, 39); }
+constexpr inline static auto EP1(u64 x) { return ROTRIGHT(x, 14) ^ ROTRIGHT(x, 18) ^ ROTRIGHT(x, 41); }
+constexpr inline static auto SIGN0(u64 x) { return ROTRIGHT(x, 1) ^ ROTRIGHT(x, 8) ^ (x >> 7); }
+constexpr inline static auto SIGN1(u64 x) { return ROTRIGHT(x, 19) ^ ROTRIGHT(x, 61) ^ (x >> 6); }
+
+inline void SHA256::transform(const u8* data)
+{
+ u32 m[64];
+
+ size_t i = 0;
+ for (size_t j = 0; i < 16; ++i, j += 4) {
+ m[i] = (data[j] << 24) | (data[j + 1] << 16) | (data[j + 2] << 8) | data[j + 3];
}
- void SHA256::update(const u8* message, size_t length)
- {
- for (size_t i = 0; i < length; ++i) {
- if (m_data_length == BlockSize) {
- transform(m_data_buffer);
- m_bit_length += 512;
- m_data_length = 0;
- }
- m_data_buffer[m_data_length++] = message[i];
- }
+ for (; i < BlockSize; ++i) {
+ m[i] = SIGN1(m[i - 2]) + m[i - 7] + SIGN0(m[i - 15]) + m[i - 16];
}
- SHA256::DigestType SHA256::digest()
- {
- auto digest = peek();
- reset();
- return digest;
+ auto a = m_state[0], b = m_state[1],
+ c = m_state[2], d = m_state[3],
+ e = m_state[4], f = m_state[5],
+ g = m_state[6], h = m_state[7];
+
+ for (size_t i = 0; i < Rounds; ++i) {
+ auto temp0 = h + EP1(e) + CH(e, f, g) + SHA256Constants::RoundConstants[i] + m[i];
+ auto temp1 = EP0(a) + MAJ(a, b, c);
+ h = g;
+ g = f;
+ f = e;
+ e = d + temp0;
+ d = c;
+ c = b;
+ b = a;
+ a = temp0 + temp1;
}
- SHA256::DigestType SHA256::peek()
- {
- DigestType digest;
- size_t i = m_data_length;
-
- if (m_data_length < FinalBlockDataSize) {
- m_data_buffer[i++] = 0x80;
- while (i < FinalBlockDataSize)
- m_data_buffer[i++] = 0x00;
-
- } else {
- m_data_buffer[i++] = 0x80;
- while (i < BlockSize)
- m_data_buffer[i++] = 0x00;
+ m_state[0] += a;
+ m_state[1] += b;
+ m_state[2] += c;
+ m_state[3] += d;
+ m_state[4] += e;
+ m_state[5] += f;
+ m_state[6] += g;
+ m_state[7] += h;
+}
+void SHA256::update(const u8* message, size_t length)
+{
+ for (size_t i = 0; i < length; ++i) {
+ if (m_data_length == BlockSize) {
transform(m_data_buffer);
- __builtin_memset(m_data_buffer, 0, FinalBlockDataSize);
+ m_bit_length += 512;
+ m_data_length = 0;
}
-
- // append total message length
- m_bit_length += m_data_length * 8;
- m_data_buffer[BlockSize - 1] = m_bit_length;
- m_data_buffer[BlockSize - 2] = m_bit_length >> 8;
- m_data_buffer[BlockSize - 3] = m_bit_length >> 16;
- m_data_buffer[BlockSize - 4] = m_bit_length >> 24;
- m_data_buffer[BlockSize - 5] = m_bit_length >> 32;
- m_data_buffer[BlockSize - 6] = m_bit_length >> 40;
- m_data_buffer[BlockSize - 7] = m_bit_length >> 48;
- m_data_buffer[BlockSize - 8] = m_bit_length >> 56;
-
- transform(m_data_buffer);
-
- // SHA uses big-endian and we assume little-endian
- // FIXME: looks like a thing for AK::NetworkOrdered,
- // but he doesn't support shifting operations
- for (size_t i = 0; i < 4; ++i) {
- digest.data[i + 0] = (m_state[0] >> (24 - i * 8)) & 0x000000ff;
- digest.data[i + 4] = (m_state[1] >> (24 - i * 8)) & 0x000000ff;
- digest.data[i + 8] = (m_state[2] >> (24 - i * 8)) & 0x000000ff;
- digest.data[i + 12] = (m_state[3] >> (24 - i * 8)) & 0x000000ff;
- digest.data[i + 16] = (m_state[4] >> (24 - i * 8)) & 0x000000ff;
- digest.data[i + 20] = (m_state[5] >> (24 - i * 8)) & 0x000000ff;
- digest.data[i + 24] = (m_state[6] >> (24 - i * 8)) & 0x000000ff;
- digest.data[i + 28] = (m_state[7] >> (24 - i * 8)) & 0x000000ff;
- }
- return digest;
+ m_data_buffer[m_data_length++] = message[i];
}
+}
- inline void SHA512::transform(const u8* data)
- {
- u64 m[80];
+SHA256::DigestType SHA256::digest()
+{
+ auto digest = peek();
+ reset();
+ return digest;
+}
- size_t i = 0;
- for (size_t j = 0; i < 16; ++i, j += 8) {
- m[i] = ((u64)data[j] << 56) | ((u64)data[j + 1] << 48) | ((u64)data[j + 2] << 40) | ((u64)data[j + 3] << 32) | ((u64)data[j + 4] << 24) | ((u64)data[j + 5] << 16) | ((u64)data[j + 6] << 8) | (u64)data[j + 7];
- }
+SHA256::DigestType SHA256::peek()
+{
+ DigestType digest;
+ size_t i = m_data_length;
- for (; i < Rounds; ++i) {
- m[i] = SIGN1(m[i - 2]) + m[i - 7] + SIGN0(m[i - 15]) + m[i - 16];
- }
+ if (m_data_length < FinalBlockDataSize) {
+ m_data_buffer[i++] = 0x80;
+ while (i < FinalBlockDataSize)
+ m_data_buffer[i++] = 0x00;
- auto a = m_state[0], b = m_state[1],
- c = m_state[2], d = m_state[3],
- e = m_state[4], f = m_state[5],
- g = m_state[6], h = m_state[7];
-
- for (size_t i = 0; i < Rounds; ++i) {
- auto temp0 = h + EP1(e) + CH(e, f, g) + SHA512Constants::RoundConstants[i] + m[i];
- auto temp1 = EP0(a) + MAJ(a, b, c);
- h = g;
- g = f;
- f = e;
- e = d + temp0;
- d = c;
- c = b;
- b = a;
- a = temp0 + temp1;
- }
+ } else {
+ m_data_buffer[i++] = 0x80;
+ while (i < BlockSize)
+ m_data_buffer[i++] = 0x00;
- m_state[0] += a;
- m_state[1] += b;
- m_state[2] += c;
- m_state[3] += d;
- m_state[4] += e;
- m_state[5] += f;
- m_state[6] += g;
- m_state[7] += h;
+ transform(m_data_buffer);
+ __builtin_memset(m_data_buffer, 0, FinalBlockDataSize);
}
- void SHA512::update(const u8* message, size_t length)
- {
- for (size_t i = 0; i < length; ++i) {
- if (m_data_length == BlockSize) {
- transform(m_data_buffer);
- m_bit_length += 1024;
- m_data_length = 0;
- }
- m_data_buffer[m_data_length++] = message[i];
- }
+ // append total message length
+ m_bit_length += m_data_length * 8;
+ m_data_buffer[BlockSize - 1] = m_bit_length;
+ m_data_buffer[BlockSize - 2] = m_bit_length >> 8;
+ m_data_buffer[BlockSize - 3] = m_bit_length >> 16;
+ m_data_buffer[BlockSize - 4] = m_bit_length >> 24;
+ m_data_buffer[BlockSize - 5] = m_bit_length >> 32;
+ m_data_buffer[BlockSize - 6] = m_bit_length >> 40;
+ m_data_buffer[BlockSize - 7] = m_bit_length >> 48;
+ m_data_buffer[BlockSize - 8] = m_bit_length >> 56;
+
+ transform(m_data_buffer);
+
+ // SHA uses big-endian and we assume little-endian
+ // FIXME: looks like a thing for AK::NetworkOrdered,
+ // but he doesn't support shifting operations
+ for (size_t i = 0; i < 4; ++i) {
+ digest.data[i + 0] = (m_state[0] >> (24 - i * 8)) & 0x000000ff;
+ digest.data[i + 4] = (m_state[1] >> (24 - i * 8)) & 0x000000ff;
+ digest.data[i + 8] = (m_state[2] >> (24 - i * 8)) & 0x000000ff;
+ digest.data[i + 12] = (m_state[3] >> (24 - i * 8)) & 0x000000ff;
+ digest.data[i + 16] = (m_state[4] >> (24 - i * 8)) & 0x000000ff;
+ digest.data[i + 20] = (m_state[5] >> (24 - i * 8)) & 0x000000ff;
+ digest.data[i + 24] = (m_state[6] >> (24 - i * 8)) & 0x000000ff;
+ digest.data[i + 28] = (m_state[7] >> (24 - i * 8)) & 0x000000ff;
}
+ return digest;
+}
- SHA512::DigestType SHA512::digest()
- {
- auto digest = peek();
- reset();
- return digest;
+inline void SHA512::transform(const u8* data)
+{
+ u64 m[80];
+
+ size_t i = 0;
+ for (size_t j = 0; i < 16; ++i, j += 8) {
+ m[i] = ((u64)data[j] << 56) | ((u64)data[j + 1] << 48) | ((u64)data[j + 2] << 40) | ((u64)data[j + 3] << 32) | ((u64)data[j + 4] << 24) | ((u64)data[j + 5] << 16) | ((u64)data[j + 6] << 8) | (u64)data[j + 7];
}
- SHA512::DigestType SHA512::peek()
- {
- DigestType digest;
- size_t i = m_data_length;
+ for (; i < Rounds; ++i) {
+ m[i] = SIGN1(m[i - 2]) + m[i - 7] + SIGN0(m[i - 15]) + m[i - 16];
+ }
- if (m_data_length < FinalBlockDataSize) {
- m_data_buffer[i++] = 0x80;
- while (i < FinalBlockDataSize)
- m_data_buffer[i++] = 0x00;
+ auto a = m_state[0], b = m_state[1],
+ c = m_state[2], d = m_state[3],
+ e = m_state[4], f = m_state[5],
+ g = m_state[6], h = m_state[7];
+
+ for (size_t i = 0; i < Rounds; ++i) {
+ auto temp0 = h + EP1(e) + CH(e, f, g) + SHA512Constants::RoundConstants[i] + m[i];
+ auto temp1 = EP0(a) + MAJ(a, b, c);
+ h = g;
+ g = f;
+ f = e;
+ e = d + temp0;
+ d = c;
+ c = b;
+ b = a;
+ a = temp0 + temp1;
+ }
- } else {
- m_data_buffer[i++] = 0x80;
- while (i < BlockSize)
- m_data_buffer[i++] = 0x00;
+ m_state[0] += a;
+ m_state[1] += b;
+ m_state[2] += c;
+ m_state[3] += d;
+ m_state[4] += e;
+ m_state[5] += f;
+ m_state[6] += g;
+ m_state[7] += h;
+}
+void SHA512::update(const u8* message, size_t length)
+{
+ for (size_t i = 0; i < length; ++i) {
+ if (m_data_length == BlockSize) {
transform(m_data_buffer);
- __builtin_memset(m_data_buffer, 0, FinalBlockDataSize);
+ m_bit_length += 1024;
+ m_data_length = 0;
}
+ m_data_buffer[m_data_length++] = message[i];
+ }
+}
+
+SHA512::DigestType SHA512::digest()
+{
+ auto digest = peek();
+ reset();
+ return digest;
+}
+
+SHA512::DigestType SHA512::peek()
+{
+ DigestType digest;
+ size_t i = m_data_length;
- // append total message length
- m_bit_length += m_data_length * 8;
- m_data_buffer[BlockSize - 1] = m_bit_length;
- m_data_buffer[BlockSize - 2] = m_bit_length >> 8;
- m_data_buffer[BlockSize - 3] = m_bit_length >> 16;
- m_data_buffer[BlockSize - 4] = m_bit_length >> 24;
- m_data_buffer[BlockSize - 5] = m_bit_length >> 32;
- m_data_buffer[BlockSize - 6] = m_bit_length >> 40;
- m_data_buffer[BlockSize - 7] = m_bit_length >> 48;
- m_data_buffer[BlockSize - 8] = m_bit_length >> 56;
+ if (m_data_length < FinalBlockDataSize) {
+ m_data_buffer[i++] = 0x80;
+ while (i < FinalBlockDataSize)
+ m_data_buffer[i++] = 0x00;
+
+ } else {
+ m_data_buffer[i++] = 0x80;
+ while (i < BlockSize)
+ m_data_buffer[i++] = 0x00;
transform(m_data_buffer);
+ __builtin_memset(m_data_buffer, 0, FinalBlockDataSize);
+ }
- // SHA uses big-endian and we assume little-endian
- // FIXME: looks like a thing for AK::NetworkOrdered,
- // but he doesn't support shifting operations
- for (size_t i = 0; i < 8; ++i) {
- digest.data[i + 0] = (m_state[0] >> (56 - i * 8)) & 0x000000ff;
- digest.data[i + 8] = (m_state[1] >> (56 - i * 8)) & 0x000000ff;
- digest.data[i + 16] = (m_state[2] >> (56 - i * 8)) & 0x000000ff;
- digest.data[i + 24] = (m_state[3] >> (56 - i * 8)) & 0x000000ff;
- digest.data[i + 32] = (m_state[4] >> (56 - i * 8)) & 0x000000ff;
- digest.data[i + 40] = (m_state[5] >> (56 - i * 8)) & 0x000000ff;
- digest.data[i + 48] = (m_state[6] >> (56 - i * 8)) & 0x000000ff;
- digest.data[i + 56] = (m_state[7] >> (56 - i * 8)) & 0x000000ff;
- }
- return digest;
+ // append total message length
+ m_bit_length += m_data_length * 8;
+ m_data_buffer[BlockSize - 1] = m_bit_length;
+ m_data_buffer[BlockSize - 2] = m_bit_length >> 8;
+ m_data_buffer[BlockSize - 3] = m_bit_length >> 16;
+ m_data_buffer[BlockSize - 4] = m_bit_length >> 24;
+ m_data_buffer[BlockSize - 5] = m_bit_length >> 32;
+ m_data_buffer[BlockSize - 6] = m_bit_length >> 40;
+ m_data_buffer[BlockSize - 7] = m_bit_length >> 48;
+ m_data_buffer[BlockSize - 8] = m_bit_length >> 56;
+
+ transform(m_data_buffer);
+
+ // SHA uses big-endian and we assume little-endian
+ // FIXME: looks like a thing for AK::NetworkOrdered,
+ // but he doesn't support shifting operations
+ for (size_t i = 0; i < 8; ++i) {
+ digest.data[i + 0] = (m_state[0] >> (56 - i * 8)) & 0x000000ff;
+ digest.data[i + 8] = (m_state[1] >> (56 - i * 8)) & 0x000000ff;
+ digest.data[i + 16] = (m_state[2] >> (56 - i * 8)) & 0x000000ff;
+ digest.data[i + 24] = (m_state[3] >> (56 - i * 8)) & 0x000000ff;
+ digest.data[i + 32] = (m_state[4] >> (56 - i * 8)) & 0x000000ff;
+ digest.data[i + 40] = (m_state[5] >> (56 - i * 8)) & 0x000000ff;
+ digest.data[i + 48] = (m_state[6] >> (56 - i * 8)) & 0x000000ff;
+ digest.data[i + 56] = (m_state[7] >> (56 - i * 8)) & 0x000000ff;
}
+ return digest;
+}
}
}
diff --git a/Libraries/LibCrypto/Hash/SHA2.h b/Libraries/LibCrypto/Hash/SHA2.h
index bedc3a7941..2437cc17cc 100644
--- a/Libraries/LibCrypto/Hash/SHA2.h
+++ b/Libraries/LibCrypto/Hash/SHA2.h
@@ -33,169 +33,169 @@
namespace Crypto {
namespace Hash {
- namespace SHA256Constants {
- constexpr static u32 RoundConstants[64] {
- 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
- 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
- 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
- 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
- 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
- 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
- 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
- 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
- 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
- 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
- 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
- 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
- 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
- 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
- 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
- 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
- };
-
- constexpr static u32 InitializationHashes[8] = {
- 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
- 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
- };
+namespace SHA256Constants {
+constexpr static u32 RoundConstants[64] {
+ 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
+ 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
+ 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
+ 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
+ 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
+ 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
+ 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
+ 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
+ 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
+ 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
+ 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
+ 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
+ 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
+ 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
+ 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
+ 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
+};
+
+constexpr static u32 InitializationHashes[8] = {
+ 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
+ 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
+};
+}
+
+namespace SHA512Constants {
+constexpr static u64 RoundConstants[80] {
+ 0x428a2f98d728ae22, 0x7137449123ef65cd, 0xb5c0fbcfec4d3b2f, 0xe9b5dba58189dbbc, 0x3956c25bf348b538,
+ 0x59f111f1b605d019, 0x923f82a4af194f9b, 0xab1c5ed5da6d8118, 0xd807aa98a3030242, 0x12835b0145706fbe,
+ 0x243185be4ee4b28c, 0x550c7dc3d5ffb4e2, 0x72be5d74f27b896f, 0x80deb1fe3b1696b1, 0x9bdc06a725c71235,
+ 0xc19bf174cf692694, 0xe49b69c19ef14ad2, 0xefbe4786384f25e3, 0x0fc19dc68b8cd5b5, 0x240ca1cc77ac9c65,
+ 0x2de92c6f592b0275, 0x4a7484aa6ea6e483, 0x5cb0a9dcbd41fbd4, 0x76f988da831153b5, 0x983e5152ee66dfab,
+ 0xa831c66d2db43210, 0xb00327c898fb213f, 0xbf597fc7beef0ee4, 0xc6e00bf33da88fc2, 0xd5a79147930aa725,
+ 0x06ca6351e003826f, 0x142929670a0e6e70, 0x27b70a8546d22ffc, 0x2e1b21385c26c926, 0x4d2c6dfc5ac42aed,
+ 0x53380d139d95b3df, 0x650a73548baf63de, 0x766a0abb3c77b2a8, 0x81c2c92e47edaee6, 0x92722c851482353b,
+ 0xa2bfe8a14cf10364, 0xa81a664bbc423001, 0xc24b8b70d0f89791, 0xc76c51a30654be30, 0xd192e819d6ef5218,
+ 0xd69906245565a910, 0xf40e35855771202a, 0x106aa07032bbd1b8, 0x19a4c116b8d2d0c8, 0x1e376c085141ab53,
+ 0x2748774cdf8eeb99, 0x34b0bcb5e19b48a8, 0x391c0cb3c5c95a63, 0x4ed8aa4ae3418acb, 0x5b9cca4f7763e373,
+ 0x682e6ff3d6b2b8a3, 0x748f82ee5defb2fc, 0x78a5636f43172f60, 0x84c87814a1f0ab72, 0x8cc702081a6439ec,
+ 0x90befffa23631e28, 0xa4506cebde82bde9, 0xbef9a3f7b2c67915, 0xc67178f2e372532b, 0xca273eceea26619c,
+ 0xd186b8c721c0c207, 0xeada7dd6cde0eb1e, 0xf57d4f7fee6ed178, 0x06f067aa72176fba, 0x0a637dc5a2c898a6,
+ 0x113f9804bef90dae, 0x1b710b35131c471b, 0x28db77f523047d84, 0x32caab7b40c72493, 0x3c9ebe0a15c9bebc,
+ 0x431d67c49c100d4c, 0x4cc5d4becb3e42b6, 0x597f299cfc657e2a, 0x5fcb6fab3ad6faec, 0x6c44198c4a475817
+};
+
+constexpr static u64 InitializationHashes[8] = {
+ 0x6a09e667f3bcc908, 0xbb67ae8584caa73b, 0x3c6ef372fe94f82b, 0xa54ff53a5f1d36f1,
+ 0x510e527fade682d1, 0x9b05688c2b3e6c1f, 0x1f83d9abfb41bd6b, 0x5be0cd19137e2179
+};
+}
+
+template<size_t Bytes>
+struct SHA2Digest {
+ u8 data[Bytes];
+};
+
+// FIXME: I want template<size_t BlockSize> but the compiler gets confused
+class SHA256 final : public HashFunction<512, SHA2Digest<256 / 8>> {
+public:
+ SHA256()
+ {
+ reset();
}
- namespace SHA512Constants {
- constexpr static u64 RoundConstants[80] {
- 0x428a2f98d728ae22, 0x7137449123ef65cd, 0xb5c0fbcfec4d3b2f, 0xe9b5dba58189dbbc, 0x3956c25bf348b538,
- 0x59f111f1b605d019, 0x923f82a4af194f9b, 0xab1c5ed5da6d8118, 0xd807aa98a3030242, 0x12835b0145706fbe,
- 0x243185be4ee4b28c, 0x550c7dc3d5ffb4e2, 0x72be5d74f27b896f, 0x80deb1fe3b1696b1, 0x9bdc06a725c71235,
- 0xc19bf174cf692694, 0xe49b69c19ef14ad2, 0xefbe4786384f25e3, 0x0fc19dc68b8cd5b5, 0x240ca1cc77ac9c65,
- 0x2de92c6f592b0275, 0x4a7484aa6ea6e483, 0x5cb0a9dcbd41fbd4, 0x76f988da831153b5, 0x983e5152ee66dfab,
- 0xa831c66d2db43210, 0xb00327c898fb213f, 0xbf597fc7beef0ee4, 0xc6e00bf33da88fc2, 0xd5a79147930aa725,
- 0x06ca6351e003826f, 0x142929670a0e6e70, 0x27b70a8546d22ffc, 0x2e1b21385c26c926, 0x4d2c6dfc5ac42aed,
- 0x53380d139d95b3df, 0x650a73548baf63de, 0x766a0abb3c77b2a8, 0x81c2c92e47edaee6, 0x92722c851482353b,
- 0xa2bfe8a14cf10364, 0xa81a664bbc423001, 0xc24b8b70d0f89791, 0xc76c51a30654be30, 0xd192e819d6ef5218,
- 0xd69906245565a910, 0xf40e35855771202a, 0x106aa07032bbd1b8, 0x19a4c116b8d2d0c8, 0x1e376c085141ab53,
- 0x2748774cdf8eeb99, 0x34b0bcb5e19b48a8, 0x391c0cb3c5c95a63, 0x4ed8aa4ae3418acb, 0x5b9cca4f7763e373,
- 0x682e6ff3d6b2b8a3, 0x748f82ee5defb2fc, 0x78a5636f43172f60, 0x84c87814a1f0ab72, 0x8cc702081a6439ec,
- 0x90befffa23631e28, 0xa4506cebde82bde9, 0xbef9a3f7b2c67915, 0xc67178f2e372532b, 0xca273eceea26619c,
- 0xd186b8c721c0c207, 0xeada7dd6cde0eb1e, 0xf57d4f7fee6ed178, 0x06f067aa72176fba, 0x0a637dc5a2c898a6,
- 0x113f9804bef90dae, 0x1b710b35131c471b, 0x28db77f523047d84, 0x32caab7b40c72493, 0x3c9ebe0a15c9bebc,
- 0x431d67c49c100d4c, 0x4cc5d4becb3e42b6, 0x597f299cfc657e2a, 0x5fcb6fab3ad6faec, 0x6c44198c4a475817
- };
-
- constexpr static u64 InitializationHashes[8] = {
- 0x6a09e667f3bcc908, 0xbb67ae8584caa73b, 0x3c6ef372fe94f82b, 0xa54ff53a5f1d36f1,
- 0x510e527fade682d1, 0x9b05688c2b3e6c1f, 0x1f83d9abfb41bd6b, 0x5be0cd19137e2179
- };
+ virtual void update(const u8*, size_t) override;
+
+ virtual void update(const ByteBuffer& buffer) override { update(buffer.data(), buffer.size()); };
+ virtual void update(const StringView& string) override { update((const u8*)string.characters_without_null_termination(), string.length()); };
+
+ virtual DigestType digest() override;
+ virtual DigestType peek() override;
+
+ inline static DigestType hash(const u8* data, size_t length)
+ {
+ SHA256 sha;
+ sha.update(data, length);
+ return sha.digest();
}
- template <size_t Bytes>
- struct SHA2Digest {
- u8 data[Bytes];
- };
+ inline static DigestType hash(const ByteBuffer& buffer) { return hash(buffer.data(), buffer.size()); }
+ inline static DigestType hash(const StringView& buffer) { return hash((const u8*)buffer.characters_without_null_termination(), buffer.length()); }
- // FIXME: I want template<size_t BlockSize> but the compiler gets confused
- class SHA256 final : public HashFunction<512, SHA2Digest<256 / 8>> {
- public:
- SHA256()
- {
- reset();
- }
-
- virtual void update(const u8*, size_t) override;
-
- virtual void update(const ByteBuffer& buffer) override { update(buffer.data(), buffer.size()); };
- virtual void update(const StringView& string) override { update((const u8*)string.characters_without_null_termination(), string.length()); };
-
- virtual DigestType digest() override;
- virtual DigestType peek() override;
-
- inline static DigestType hash(const u8* data, size_t length)
- {
- SHA256 sha;
- sha.update(data, length);
- return sha.digest();
- }
-
- inline static DigestType hash(const ByteBuffer& buffer) { return hash(buffer.data(), buffer.size()); }
- inline static DigestType hash(const StringView& buffer) { return hash((const u8*)buffer.characters_without_null_termination(), buffer.length()); }
-
- virtual String class_name() const override
- {
- StringBuilder builder;
- builder.append("SHA");
- builder.appendf("%zu", this->DigestSize * 8);
- return builder.build();
- };
- inline virtual void reset() override
- {
- m_data_length = 0;
- m_bit_length = 0;
- for (size_t i = 0; i < 8; ++i)
- m_state[i] = SHA256Constants::InitializationHashes[i];
- }
-
- private:
- inline void transform(const u8*);
-
- u8 m_data_buffer[BlockSize];
- size_t m_data_length { 0 };
-
- u64 m_bit_length { 0 };
- u32 m_state[8];
-
- constexpr static auto FinalBlockDataSize = BlockSize - 8;
- constexpr static auto Rounds = 64;
+ virtual String class_name() const override
+ {
+ StringBuilder builder;
+ builder.append("SHA");
+ builder.appendf("%zu", this->DigestSize * 8);
+ return builder.build();
};
+ inline virtual void reset() override
+ {
+ m_data_length = 0;
+ m_bit_length = 0;
+ for (size_t i = 0; i < 8; ++i)
+ m_state[i] = SHA256Constants::InitializationHashes[i];
+ }
+
+private:
+ inline void transform(const u8*);
+
+ u8 m_data_buffer[BlockSize];
+ size_t m_data_length { 0 };
+
+ u64 m_bit_length { 0 };
+ u32 m_state[8];
+
+ constexpr static auto FinalBlockDataSize = BlockSize - 8;
+ constexpr static auto Rounds = 64;
+};
- class SHA512 final : public HashFunction<1024, SHA2Digest<512 / 8>> {
- public:
- SHA512()
- {
- reset();
- }
-
- virtual void update(const u8*, size_t) override;
-
- virtual void update(const ByteBuffer& buffer) override { update(buffer.data(), buffer.size()); };
- virtual void update(const StringView& string) override { update((const u8*)string.characters_without_null_termination(), string.length()); };
-
- virtual DigestType digest() override;
- virtual DigestType peek() override;
-
- inline static DigestType hash(const u8* data, size_t length)
- {
- SHA512 sha;
- sha.update(data, length);
- return sha.digest();
- }
-
- inline static DigestType hash(const ByteBuffer& buffer) { return hash(buffer.data(), buffer.size()); }
- inline static DigestType hash(const StringView& buffer) { return hash((const u8*)buffer.characters_without_null_termination(), buffer.length()); }
-
- virtual String class_name() const override
- {
- StringBuilder builder;
- builder.append("SHA");
- builder.appendf("%zu", this->DigestSize * 8);
- return builder.build();
- };
- inline virtual void reset() override
- {
- m_data_length = 0;
- m_bit_length = 0;
- for (size_t i = 0; i < 8; ++i)
- m_state[i] = SHA512Constants::InitializationHashes[i];
- }
-
- private:
- inline void transform(const u8*);
-
- u8 m_data_buffer[BlockSize];
- size_t m_data_length { 0 };
-
- u64 m_bit_length { 0 };
- u64 m_state[8];
-
- constexpr static auto FinalBlockDataSize = BlockSize - 8;
- constexpr static auto Rounds = 80;
+class SHA512 final : public HashFunction<1024, SHA2Digest<512 / 8>> {
+public:
+ SHA512()
+ {
+ reset();
+ }
+
+ virtual void update(const u8*, size_t) override;
+
+ virtual void update(const ByteBuffer& buffer) override { update(buffer.data(), buffer.size()); };
+ virtual void update(const StringView& string) override { update((const u8*)string.characters_without_null_termination(), string.length()); };
+
+ virtual DigestType digest() override;
+ virtual DigestType peek() override;
+
+ inline static DigestType hash(const u8* data, size_t length)
+ {
+ SHA512 sha;
+ sha.update(data, length);
+ return sha.digest();
+ }
+
+ inline static DigestType hash(const ByteBuffer& buffer) { return hash(buffer.data(), buffer.size()); }
+ inline static DigestType hash(const StringView& buffer) { return hash((const u8*)buffer.characters_without_null_termination(), buffer.length()); }
+
+ virtual String class_name() const override
+ {
+ StringBuilder builder;
+ builder.append("SHA");
+ builder.appendf("%zu", this->DigestSize * 8);
+ return builder.build();
};
+ inline virtual void reset() override
+ {
+ m_data_length = 0;
+ m_bit_length = 0;
+ for (size_t i = 0; i < 8; ++i)
+ m_state[i] = SHA512Constants::InitializationHashes[i];
+ }
+
+private:
+ inline void transform(const u8*);
+
+ u8 m_data_buffer[BlockSize];
+ size_t m_data_length { 0 };
+
+ u64 m_bit_length { 0 };
+ u64 m_state[8];
+
+ constexpr static auto FinalBlockDataSize = BlockSize - 8;
+ constexpr static auto Rounds = 80;
+};
}
}
diff --git a/Libraries/LibCrypto/NumberTheory/ModularFunctions.h b/Libraries/LibCrypto/NumberTheory/ModularFunctions.h
index 2f19dc7147..59d2122eb0 100644
--- a/Libraries/LibCrypto/NumberTheory/ModularFunctions.h
+++ b/Libraries/LibCrypto/NumberTheory/ModularFunctions.h
@@ -32,171 +32,173 @@
namespace Crypto {
namespace NumberTheory {
- static auto ModularInverse(const UnsignedBigInteger& a_, const UnsignedBigInteger& b) -> UnsignedBigInteger
- {
- if (b == 1)
- return { 1 };
-
- auto a = a_;
- auto u = a;
- if (a.words()[0] % 2 == 0)
- u = u.add(b);
-
- auto v = b;
- auto x = UnsignedBigInteger { 0 };
- auto d = b.sub(1);
-
- while (!(v == 1)) {
- while (v < u) {
- u = u.sub(v);
- d = d.add(x);
- while (u.words()[0] % 2 == 0) {
- if (d.words()[0] % 2 == 1) {
- d = d.add(b);
- }
- u = u.divide(2).quotient;
- d = d.divide(2).quotient;
+
+static auto ModularInverse(const UnsignedBigInteger& a_, const UnsignedBigInteger& b) -> UnsignedBigInteger
+{
+ if (b == 1)
+ return { 1 };
+
+ auto a = a_;
+ auto u = a;
+ if (a.words()[0] % 2 == 0)
+ u = u.add(b);
+
+ auto v = b;
+ auto x = UnsignedBigInteger { 0 };
+ auto d = b.sub(1);
+
+ while (!(v == 1)) {
+ while (v < u) {
+ u = u.sub(v);
+ d = d.add(x);
+ while (u.words()[0] % 2 == 0) {
+ if (d.words()[0] % 2 == 1) {
+ d = d.add(b);
}
+ u = u.divide(2).quotient;
+ d = d.divide(2).quotient;
}
- v = v.sub(u);
- x = x.add(d);
- while (v.words()[0] % 2 == 0) {
- if (x.words()[0] % 2 == 1) {
- x = x.add(b);
- }
- v = v.divide(2).quotient;
- x = x.divide(2).quotient;
+ }
+ v = v.sub(u);
+ x = x.add(d);
+ while (v.words()[0] % 2 == 0) {
+ if (x.words()[0] % 2 == 1) {
+ x = x.add(b);
}
+ v = v.divide(2).quotient;
+ x = x.divide(2).quotient;
}
- return x.divide(b).remainder;
}
+ return x.divide(b).remainder;
+}
- static auto ModularPower(const UnsignedBigInteger& b, const UnsignedBigInteger& e, const UnsignedBigInteger& m) -> UnsignedBigInteger
- {
- if (m == 1)
- return 0;
+static auto ModularPower(const UnsignedBigInteger& b, const UnsignedBigInteger& e, const UnsignedBigInteger& m) -> UnsignedBigInteger
+{
+ if (m == 1)
+ return 0;
- UnsignedBigInteger ep { e };
- UnsignedBigInteger base { b };
- UnsignedBigInteger exp { 1 };
+ UnsignedBigInteger ep { e };
+ UnsignedBigInteger base { b };
+ UnsignedBigInteger exp { 1 };
- while (!(ep < 1)) {
+ while (!(ep < 1)) {
#ifdef NT_DEBUG
- dbg() << ep.to_base10();
+ dbg() << ep.to_base10();
#endif
- if (ep.words()[0] % 2 == 1) {
- exp = exp.multiply(base).divide(m).remainder;
- }
- ep = ep.divide(2).quotient;
- base = base.multiply(base).divide(m).remainder;
+ if (ep.words()[0] % 2 == 1) {
+ exp = exp.multiply(base).divide(m).remainder;
}
- return exp;
+ ep = ep.divide(2).quotient;
+ base = base.multiply(base).divide(m).remainder;
}
+ return exp;
+}
- static auto GCD(const UnsignedBigInteger& a, const UnsignedBigInteger& b) -> UnsignedBigInteger
- {
- UnsignedBigInteger a_ { a }, b_ { b };
- for (;;) {
- if (a_ == 0)
- return b_;
- b_ = b_.divide(a_).remainder;
- if (b_ == 0)
- return a_;
- a_ = a_.divide(b_).remainder;
- }
+static auto GCD(const UnsignedBigInteger& a, const UnsignedBigInteger& b) -> UnsignedBigInteger
+{
+ UnsignedBigInteger a_ { a }, b_ { b };
+ for (;;) {
+ if (a_ == 0)
+ return b_;
+ b_ = b_.divide(a_).remainder;
+ if (b_ == 0)
+ return a_;
+ a_ = a_.divide(b_).remainder;
}
+}
- static auto LCM(const UnsignedBigInteger& a, const UnsignedBigInteger& b) -> UnsignedBigInteger
- {
- auto temp = GCD(a, b);
+static auto LCM(const UnsignedBigInteger& a, const UnsignedBigInteger& b) -> UnsignedBigInteger
+{
+ auto temp = GCD(a, b);
- auto div = a.divide(temp);
+ auto div = a.divide(temp);
#ifdef NT_DEBUG
- dbg() << "quot: " << div.quotient << " rem: " << div.remainder;
+ dbg() << "quot: " << div.quotient << " rem: " << div.remainder;
#endif
- return temp == 0 ? 0 : (a.divide(temp).quotient.multiply(b));
- }
+ return temp == 0 ? 0 : (a.divide(temp).quotient.multiply(b));
+}
- template <size_t test_count>
- static bool MR_primality_test(UnsignedBigInteger n, const Vector<UnsignedBigInteger, test_count>& tests)
- {
- auto prev = n.sub({ 1 });
- auto b = prev;
- auto r = 0;
-
- auto div_result = b.divide(2);
- while (div_result.quotient == 0) {
- div_result = b.divide(2);
- b = div_result.quotient;
- ++r;
- }
+template<size_t test_count>
+static bool MR_primality_test(UnsignedBigInteger n, const Vector<UnsignedBigInteger, test_count>& tests)
+{
+ auto prev = n.sub({ 1 });
+ auto b = prev;
+ auto r = 0;
+
+ auto div_result = b.divide(2);
+ while (div_result.quotient == 0) {
+ div_result = b.divide(2);
+ b = div_result.quotient;
+ ++r;
+ }
- for (size_t i = 0; i < tests.size(); ++i) {
- auto return_ = true;
- if (n < tests[i])
- continue;
- auto x = ModularPower(tests[i], b, n);
- if (x == 1 || x == prev)
- continue;
- for (auto d = r - 1; d != 0; --d) {
- x = ModularPower(x, 2, n);
- if (x == 1)
- return false;
- if (x == prev) {
- return_ = false;
- break;
- }
- }
- if (return_)
+ for (size_t i = 0; i < tests.size(); ++i) {
+ auto return_ = true;
+ if (n < tests[i])
+ continue;
+ auto x = ModularPower(tests[i], b, n);
+ if (x == 1 || x == prev)
+ continue;
+ for (auto d = r - 1; d != 0; --d) {
+ x = ModularPower(x, 2, n);
+ if (x == 1)
return false;
+ if (x == prev) {
+ return_ = false;
+ break;
+ }
}
-
- return true;
+ if (return_)
+ return false;
}
- static UnsignedBigInteger random_number(const UnsignedBigInteger& min, const UnsignedBigInteger& max)
- {
- ASSERT(min < max);
- auto range = max.minus(min);
- UnsignedBigInteger base;
- // FIXME: Need a cryptographically secure rng
- auto size = range.trimmed_length() * sizeof(u32);
- u8 buf[size];
- arc4random_buf(buf, size);
- Vector<u32> vec;
- for (size_t i = 0; i < size / sizeof(u32); ++i) {
- vec.append(*(u32*)buf + i);
- }
- UnsignedBigInteger offset { move(vec) };
- return offset.add(min);
+ return true;
+}
+
+static UnsignedBigInteger random_number(const UnsignedBigInteger& min, const UnsignedBigInteger& max)
+{
+ ASSERT(min < max);
+ auto range = max.minus(min);
+ UnsignedBigInteger base;
+ // FIXME: Need a cryptographically secure rng
+ auto size = range.trimmed_length() * sizeof(u32);
+ u8 buf[size];
+ arc4random_buf(buf, size);
+ Vector<u32> vec;
+ for (size_t i = 0; i < size / sizeof(u32); ++i) {
+ vec.append(*(u32*)buf + i);
}
+ UnsignedBigInteger offset { move(vec) };
+ return offset.add(min);
+}
- static bool is_probably_prime(const UnsignedBigInteger& p)
- {
- if (p == 2 || p == 3 || p == 5)
- return true;
- if (p < 49)
- return true;
+static bool is_probably_prime(const UnsignedBigInteger& p)
+{
+ if (p == 2 || p == 3 || p == 5)
+ return true;
+ if (p < 49)
+ return true;
- Vector<UnsignedBigInteger, 256> tests;
- UnsignedBigInteger seven { 7 };
- for (size_t i = 0; i < tests.size(); ++i)
- tests.append(random_number(seven, p.sub(2)));
+ Vector<UnsignedBigInteger, 256> tests;
+ UnsignedBigInteger seven { 7 };
+ for (size_t i = 0; i < tests.size(); ++i)
+ tests.append(random_number(seven, p.sub(2)));
- return MR_primality_test(p, tests);
- }
+ return MR_primality_test(p, tests);
+}
- static UnsignedBigInteger random_big_prime(size_t bits)
- {
- ASSERT(bits >= 33);
- UnsignedBigInteger min = UnsignedBigInteger::from_base10("6074001000").shift_left(bits - 33);
- UnsignedBigInteger max = UnsignedBigInteger { 1 }.shift_left(bits).sub(1);
- for (;;) {
- auto p = random_number(min, max);
- if (is_probably_prime(p))
- return p;
- }
+static UnsignedBigInteger random_big_prime(size_t bits)
+{
+ ASSERT(bits >= 33);
+ UnsignedBigInteger min = UnsignedBigInteger::from_base10("6074001000").shift_left(bits - 33);
+ UnsignedBigInteger max = UnsignedBigInteger { 1 }.shift_left(bits).sub(1);
+ for (;;) {
+ auto p = random_number(min, max);
+ if (is_probably_prime(p))
+ return p;
}
}
+
+}
}
diff --git a/Libraries/LibCrypto/PK/Code/Code.h b/Libraries/LibCrypto/PK/Code/Code.h
index 8b6b02da13..b35c1be551 100644
--- a/Libraries/LibCrypto/PK/Code/Code.h
+++ b/Libraries/LibCrypto/PK/Code/Code.h
@@ -31,29 +31,29 @@
namespace Crypto {
namespace PK {
- enum class VerificationConsistency {
- Consistent,
- Inconsistent
- };
-
- template <typename HashFunction>
- class Code {
- public:
- template <typename... Args>
- Code(Args... args)
- : m_hasher(args...)
- {
- }
-
- virtual void encode(const ByteBuffer& in, ByteBuffer& out, size_t em_bits) = 0;
- virtual VerificationConsistency verify(const ByteBuffer& msg, const ByteBuffer& emsg, size_t em_bits) = 0;
-
- const HashFunction& hasher() const { return m_hasher; }
- HashFunction& hasher() { return m_hasher; }
-
- protected:
- HashFunction m_hasher;
- };
+enum class VerificationConsistency {
+ Consistent,
+ Inconsistent
+};
+
+template<typename HashFunction>
+class Code {
+public:
+ template<typename... Args>
+ Code(Args... args)
+ : m_hasher(args...)
+ {
+ }
+
+ virtual void encode(const ByteBuffer& in, ByteBuffer& out, size_t em_bits) = 0;
+ virtual VerificationConsistency verify(const ByteBuffer& msg, const ByteBuffer& emsg, size_t em_bits) = 0;
+
+ const HashFunction& hasher() const { return m_hasher; }
+ HashFunction& hasher() { return m_hasher; }
+
+protected:
+ HashFunction m_hasher;
+};
}
}
diff --git a/Libraries/LibCrypto/PK/Code/EMSA_PSS.h b/Libraries/LibCrypto/PK/Code/EMSA_PSS.h
index 0bfe544715..c5de7a9c71 100644
--- a/Libraries/LibCrypto/PK/Code/EMSA_PSS.h
+++ b/Libraries/LibCrypto/PK/Code/EMSA_PSS.h
@@ -33,147 +33,148 @@ static constexpr u8 zeros[] { 0, 0, 0, 0, 0, 0, 0, 0 };
namespace Crypto {
namespace PK {
- template <typename HashFunction, size_t SaltSize>
- class EMSA_PSS : public Code<HashFunction> {
- public:
- template <typename... Args>
- EMSA_PSS(Args... args)
- : Code<HashFunction>(args...)
- {
- m_buffer = ByteBuffer::wrap(m_data_buffer, sizeof(m_data_buffer));
+template<typename HashFunction, size_t SaltSize>
+class EMSA_PSS : public Code<HashFunction> {
+public:
+ template<typename... Args>
+ EMSA_PSS(Args... args)
+ : Code<HashFunction>(args...)
+ {
+ m_buffer = ByteBuffer::wrap(m_data_buffer, sizeof(m_data_buffer));
+ }
+
+ static constexpr auto SaltLength = SaltSize;
+
+ virtual void encode(const ByteBuffer& in, ByteBuffer& out, size_t em_bits) override
+ {
+ // FIXME: we're supposed to check if in.size() > HashFunction::input_limitation
+ // however, all of our current hash functions can hash unlimited blocks
+ auto& hash_fn = this->hasher();
+ hash_fn.update(in);
+ auto message_hash = hash_fn.digest();
+ auto hash_length = hash_fn.DigestSize;
+ auto em_length = (em_bits + 7) / 8;
+ u8 salt[SaltLength];
+
+ arc4random_buf(salt, SaltLength);
+
+ if (em_length < hash_length + SaltLength + 2) {
+ dbg() << "Ooops...encoding error";
+ return;
}
- static constexpr auto SaltLength = SaltSize;
+ m_buffer.overwrite(0, zeros, 8);
+ m_buffer.overwrite(8, message_hash.data, HashFunction::DigestSize);
+ m_buffer.overwrite(8 + HashFunction::DigestSize, salt, SaltLength);
- virtual void encode(const ByteBuffer& in, ByteBuffer& out, size_t em_bits) override
- {
- // FIXME: we're supposed to check if in.size() > HashFunction::input_limitation
- // however, all of our current hash functions can hash unlimited blocks
- auto& hash_fn = this->hasher();
- hash_fn.update(in);
- auto message_hash = hash_fn.digest();
- auto hash_length = hash_fn.DigestSize;
- auto em_length = (em_bits + 7) / 8;
- u8 salt[SaltLength];
+ hash_fn.update(m_buffer);
+ auto hash = hash_fn.digest();
- arc4random_buf(salt, SaltLength);
+ u8 DB_data[em_length - HashFunction::DigestSize - 1];
+ auto DB = ByteBuffer::wrap(DB_data, em_length - HashFunction::DigestSize - 1);
+ auto DB_offset = 0;
- if (em_length < hash_length + SaltLength + 2) {
- dbg() << "Ooops...encoding error";
- return;
- }
+ for (size_t i = 0; i < em_length - SaltLength - HashFunction::DigestSize - 2; ++i)
+ DB[DB_offset++] = 0;
- m_buffer.overwrite(0, zeros, 8);
- m_buffer.overwrite(8, message_hash.data, HashFunction::DigestSize);
- m_buffer.overwrite(8 + HashFunction::DigestSize, salt, SaltLength);
+ DB[DB_offset++] = 0x01;
- hash_fn.update(m_buffer);
- auto hash = hash_fn.digest();
+ DB.overwrite(DB_offset, salt, SaltLength);
- u8 DB_data[em_length - HashFunction::DigestSize - 1];
- auto DB = ByteBuffer::wrap(DB_data, em_length - HashFunction::DigestSize - 1);
- auto DB_offset = 0;
+ auto mask_length = em_length - HashFunction::DigestSize - 1;
- for (size_t i = 0; i < em_length - SaltLength - HashFunction::DigestSize - 2; ++i)
- DB[DB_offset++] = 0;
+ u8 DB_mask[mask_length];
+ auto DB_mask_buffer = ByteBuffer::wrap(DB_mask, mask_length);
+ // FIXME: we should probably allow reading from u8*
+ auto hash_buffer = ByteBuffer::wrap(hash.data, HashFunction::DigestSize);
+ MGF1(hash_buffer, mask_length, DB_mask_buffer);
- DB[DB_offset++] = 0x01;
+ for (size_t i = 0; i < DB.size(); ++i)
+ DB_data[i] ^= DB_mask[i];
- DB.overwrite(DB_offset, salt, SaltLength);
+ auto count = (8 - (em_length * 8 - em_bits));
+ DB_data[0] &= (0xff >> count) << count;
- auto mask_length = em_length - HashFunction::DigestSize - 1;
+ out.overwrite(0, DB.data(), DB.size());
+ out.overwrite(DB.size(), hash.data, hash_fn.DigestSize);
+ out[DB.size() + hash_fn.DigestSize] = 0xbc;
+ }
- u8 DB_mask[mask_length];
- auto DB_mask_buffer = ByteBuffer::wrap(DB_mask, mask_length);
- // FIXME: we should probably allow reading from u8*
- auto hash_buffer = ByteBuffer::wrap(hash.data, HashFunction::DigestSize);
- MGF1(hash_buffer, mask_length, DB_mask_buffer);
+ virtual VerificationConsistency verify(const ByteBuffer& msg, const ByteBuffer& emsg, size_t em_bits) override
+ {
+ auto& hash_fn = this->hasher();
+ hash_fn.update(msg);
+ auto message_hash = hash_fn.digest();
- for (size_t i = 0; i < DB.size(); ++i)
- DB_data[i] ^= DB_mask[i];
+ if (emsg.size() < HashFunction::DigestSize + SaltLength + 2)
+ return VerificationConsistency::Inconsistent;
- auto count = (8 - (em_length * 8 - em_bits));
- DB_data[0] &= (0xff >> count) << count;
+ if (emsg[emsg.size() - 1] != 0xbc)
+ return VerificationConsistency::Inconsistent;
- out.overwrite(0, DB.data(), DB.size());
- out.overwrite(DB.size(), hash.data, hash_fn.DigestSize);
- out[DB.size() + hash_fn.DigestSize] = 0xbc;
- }
-
- virtual VerificationConsistency verify(const ByteBuffer& msg, const ByteBuffer& emsg, size_t em_bits) override
- {
- auto& hash_fn = this->hasher();
- hash_fn.update(msg);
- auto message_hash = hash_fn.digest();
-
- if (emsg.size() < HashFunction::DigestSize + SaltLength + 2)
- return VerificationConsistency::Inconsistent;
+ auto mask_length = emsg.size() - HashFunction::DigestSize - 1;
+ auto masked_DB = emsg.slice_view(0, mask_length);
+ auto H = emsg.slice_view(mask_length, HashFunction::DigestSize);
- if (emsg[emsg.size() - 1] != 0xbc)
+ auto length_to_check = 8 * emsg.size() - em_bits;
+ auto octet = masked_DB[0];
+ for (size_t i = 0; i < length_to_check; ++i)
+ if ((octet >> (8 - i)) & 0x01)
return VerificationConsistency::Inconsistent;
- auto mask_length = emsg.size() - HashFunction::DigestSize - 1;
- auto masked_DB = emsg.slice_view(0, mask_length);
- auto H = emsg.slice_view(mask_length, HashFunction::DigestSize);
-
- auto length_to_check = 8 * emsg.size() - em_bits;
- auto octet = masked_DB[0];
- for (size_t i = 0; i < length_to_check; ++i)
- if ((octet >> (8 - i)) & 0x01)
- return VerificationConsistency::Inconsistent;
-
- u8 DB_mask[mask_length];
- auto DB_mask_buffer = ByteBuffer::wrap(DB_mask, mask_length);
- MGF1(H, mask_length, DB_mask_buffer);
+ u8 DB_mask[mask_length];
+ auto DB_mask_buffer = ByteBuffer::wrap(DB_mask, mask_length);
+ MGF1(H, mask_length, DB_mask_buffer);
- u8 DB[mask_length];
+ u8 DB[mask_length];
- for (size_t i = 0; i < mask_length; ++i)
- DB[i] = masked_DB[i] ^ DB_mask[i];
+ for (size_t i = 0; i < mask_length; ++i)
+ DB[i] = masked_DB[i] ^ DB_mask[i];
- DB[0] &= 0xff >> (8 - length_to_check);
+ DB[0] &= 0xff >> (8 - length_to_check);
- auto check_octets = emsg.size() - HashFunction::DigestSize - SaltLength - 2;
- for (size_t i = 0; i < check_octets; ++i)
- if (DB[i])
- return VerificationConsistency::Inconsistent;
-
- if (DB[check_octets + 1] != 0x01)
+ auto check_octets = emsg.size() - HashFunction::DigestSize - SaltLength - 2;
+ for (size_t i = 0; i < check_octets; ++i) {
+ if (DB[i])
return VerificationConsistency::Inconsistent;
+ }
- auto* salt = DB + mask_length - SaltLength;
- u8 m_prime[8 + HashFunction::DigestSize + SaltLength] { 0, 0, 0, 0, 0, 0, 0, 0 };
+ if (DB[check_octets + 1] != 0x01)
+ return VerificationConsistency::Inconsistent;
- auto m_prime_buffer = ByteBuffer::wrap(m_prime, sizeof(m_prime));
+ auto* salt = DB + mask_length - SaltLength;
+ u8 m_prime[8 + HashFunction::DigestSize + SaltLength] { 0, 0, 0, 0, 0, 0, 0, 0 };
- m_prime_buffer.overwrite(8, message_hash.data, HashFunction::DigestSize);
- m_prime_buffer.overwrite(8 + HashFunction::DigestSize, salt, SaltLength);
+ auto m_prime_buffer = ByteBuffer::wrap(m_prime, sizeof(m_prime));
- hash_fn.update(m_prime_buffer);
- auto H_prime = hash_fn.digest();
+ m_prime_buffer.overwrite(8, message_hash.data, HashFunction::DigestSize);
+ m_prime_buffer.overwrite(8 + HashFunction::DigestSize, salt, SaltLength);
- if (__builtin_memcmp(message_hash.data, H_prime.data, HashFunction::DigestSize))
- return VerificationConsistency::Inconsistent;
+ hash_fn.update(m_prime_buffer);
+ auto H_prime = hash_fn.digest();
- return VerificationConsistency::Consistent;
- }
+ if (__builtin_memcmp(message_hash.data, H_prime.data, HashFunction::DigestSize))
+ return VerificationConsistency::Inconsistent;
+
+ return VerificationConsistency::Consistent;
+ }
- void MGF1(const ByteBuffer& seed, size_t length, ByteBuffer& out)
- {
- auto& hash_fn = this->hasher();
- ByteBuffer T = ByteBuffer::create_zeroed(0);
- for (size_t counter = 0; counter < length / HashFunction::DigestSize - 1; ++counter) {
- hash_fn.update(seed);
- hash_fn.update((u8*)&counter, 4);
- T.append(hash_fn.digest().data, HashFunction::DigestSize);
- }
- out.overwrite(0, T.data(), length);
+ void MGF1(const ByteBuffer& seed, size_t length, ByteBuffer& out)
+ {
+ auto& hash_fn = this->hasher();
+ ByteBuffer T = ByteBuffer::create_zeroed(0);
+ for (size_t counter = 0; counter < length / HashFunction::DigestSize - 1; ++counter) {
+ hash_fn.update(seed);
+ hash_fn.update((u8*)&counter, 4);
+ T.append(hash_fn.digest().data, HashFunction::DigestSize);
}
+ out.overwrite(0, T.data(), length);
+ }
- private:
- u8 m_data_buffer[8 + HashFunction::DigestSize + SaltLength];
- ByteBuffer m_buffer;
- };
+private:
+ u8 m_data_buffer[8 + HashFunction::DigestSize + SaltLength];
+ ByteBuffer m_buffer;
+};
}
}
diff --git a/Libraries/LibCrypto/PK/PK.h b/Libraries/LibCrypto/PK/PK.h
index fd729da01b..e2b6817a22 100644
--- a/Libraries/LibCrypto/PK/PK.h
+++ b/Libraries/LibCrypto/PK/PK.h
@@ -32,37 +32,37 @@
namespace Crypto {
namespace PK {
- // FIXME: Fixing name up for grabs
- template <typename PrivKeyT, typename PubKeyT>
- class PKSystem {
- public:
- using PublicKeyType = PubKeyT;
- using PrivateKeyType = PrivKeyT;
+// FIXME: Fixing name up for grabs
+template<typename PrivKeyT, typename PubKeyT>
+class PKSystem {
+public:
+ using PublicKeyType = PubKeyT;
+ using PrivateKeyType = PrivKeyT;
- PKSystem(PublicKeyType& pubkey, PrivateKeyType& privkey)
- : m_public_key(pubkey)
- , m_private_key(privkey)
- {
- }
+ PKSystem(PublicKeyType& pubkey, PrivateKeyType& privkey)
+ : m_public_key(pubkey)
+ , m_private_key(privkey)
+ {
+ }
- PKSystem()
- {
- }
+ PKSystem()
+ {
+ }
- virtual void encrypt(const ByteBuffer& in, ByteBuffer& out) = 0;
- virtual void decrypt(const ByteBuffer& in, ByteBuffer& out) = 0;
+ virtual void encrypt(const ByteBuffer& in, ByteBuffer& out) = 0;
+ virtual void decrypt(const ByteBuffer& in, ByteBuffer& out) = 0;
- virtual void sign(const ByteBuffer& in, ByteBuffer& out) = 0;
- virtual void verify(const ByteBuffer& in, ByteBuffer& out) = 0;
+ virtual void sign(const ByteBuffer& in, ByteBuffer& out) = 0;
+ virtual void verify(const ByteBuffer& in, ByteBuffer& out) = 0;
- virtual String class_name() const = 0;
+ virtual String class_name() const = 0;
- virtual size_t output_size() const = 0;
+ virtual size_t output_size() const = 0;
- protected:
- PublicKeyType m_public_key;
- PrivateKeyType m_private_key;
- };
+protected:
+ PublicKeyType m_public_key;
+ PrivateKeyType m_private_key;
+};
}
}
diff --git a/Libraries/LibCrypto/PK/RSA.cpp b/Libraries/LibCrypto/PK/RSA.cpp
index 8d4552dd3d..90e0d8098e 100644
--- a/Libraries/LibCrypto/PK/RSA.cpp
+++ b/Libraries/LibCrypto/PK/RSA.cpp
@@ -32,272 +32,272 @@
namespace Crypto {
namespace PK {
- RSA::KeyPairType RSA::parse_rsa_key(const ByteBuffer& in)
- {
- // we are going to assign to at least one of these
- KeyPairType keypair;
- // TODO: move ASN parsing logic out
- u64 t, x, y, z, tmp_oid[16];
- u8 tmp_buf[4096] { 0 };
- UnsignedBigInteger n, e, d;
- ASN1::List pubkey_hash_oid[2], pubkey[2];
-
- ASN1::set(pubkey_hash_oid[0], ASN1::Kind::ObjectIdentifier, tmp_oid, sizeof(tmp_oid) / sizeof(tmp_oid[0]));
- ASN1::set(pubkey_hash_oid[1], ASN1::Kind::Null, nullptr, 0);
-
- // DER is weird in that it stores pubkeys as bitstrings
- // we must first extract that crap
- ASN1::set(pubkey[0], ASN1::Kind::Sequence, &pubkey_hash_oid, 2);
- ASN1::set(pubkey[1], ASN1::Kind::Null, nullptr, 0);
-
- dbg() << "we were offered " << in.size() << " bytes of input";
-
- if (der_decode_sequence(in.data(), in.size(), pubkey, 2)) {
- // yay, now we have to reassemble the bitstring to a bytestring
- t = 0;
- y = 0;
- z = 0;
- x = 0;
- for (; x < pubkey[1].size; ++x) {
- y = (y << 1) | tmp_buf[x];
- if (++z == 8) {
- tmp_buf[t++] = (u8)y;
- y = 0;
- z = 0;
- }
+RSA::KeyPairType RSA::parse_rsa_key(const ByteBuffer& in)
+{
+ // we are going to assign to at least one of these
+ KeyPairType keypair;
+ // TODO: move ASN parsing logic out
+ u64 t, x, y, z, tmp_oid[16];
+ u8 tmp_buf[4096] { 0 };
+ UnsignedBigInteger n, e, d;
+ ASN1::List pubkey_hash_oid[2], pubkey[2];
+
+ ASN1::set(pubkey_hash_oid[0], ASN1::Kind::ObjectIdentifier, tmp_oid, sizeof(tmp_oid) / sizeof(tmp_oid[0]));
+ ASN1::set(pubkey_hash_oid[1], ASN1::Kind::Null, nullptr, 0);
+
+ // DER is weird in that it stores pubkeys as bitstrings
+ // we must first extract that crap
+ ASN1::set(pubkey[0], ASN1::Kind::Sequence, &pubkey_hash_oid, 2);
+ ASN1::set(pubkey[1], ASN1::Kind::Null, nullptr, 0);
+
+ dbg() << "we were offered " << in.size() << " bytes of input";
+
+ if (der_decode_sequence(in.data(), in.size(), pubkey, 2)) {
+ // yay, now we have to reassemble the bitstring to a bytestring
+ t = 0;
+ y = 0;
+ z = 0;
+ x = 0;
+ for (; x < pubkey[1].size; ++x) {
+ y = (y << 1) | tmp_buf[x];
+ if (++z == 8) {
+ tmp_buf[t++] = (u8)y;
+ y = 0;
+ z = 0;
}
- // now the buffer is correct (Sequence { Integer, Integer })
- if (!der_decode_sequence_many<2>(tmp_buf, t,
- ASN1::Kind::Integer, 1, &n,
- ASN1::Kind::Integer, 1, &e)) {
- // something was fucked up
- dbg() << "bad pubkey: " << e << " in " << n;
- return keypair;
- }
- // correct public key
- keypair.public_key.set(n, e);
- return keypair;
}
-
- // could be a private key
- if (!der_decode_sequence_many<1>(in.data(), in.size(),
- ASN1::Kind::Integer, 1, &n)) {
- // that's no key
- // that's a death star
- dbg() << "that's a death star";
+ // now the buffer is correct (Sequence { Integer, Integer })
+ if (!der_decode_sequence_many<2>(tmp_buf, t,
+ ASN1::Kind::Integer, 1, &n,
+ ASN1::Kind::Integer, 1, &e)) {
+ // something was fucked up
+ dbg() << "bad pubkey: " << e << " in " << n;
return keypair;
}
+ // correct public key
+ keypair.public_key.set(n, e);
+ return keypair;
+ }
- if (n == 0) {
- // it is a private key
- UnsignedBigInteger zero;
- if (!der_decode_sequence_many<4>(in.data(), in.size(),
- ASN1::Kind::Integer, 1, &zero,
- ASN1::Kind::Integer, 1, &n,
- ASN1::Kind::Integer, 1, &e,
- ASN1::Kind::Integer, 1, &d)) {
- dbg() << "bad privkey " << n << " " << e << " " << d;
- return keypair;
- }
- keypair.private_key.set(n, d, e);
- return keypair;
- }
- if (n == 1) {
- // multiprime key, we don't know how to deal with this
- dbg() << "Unsupported key type";
+ // could be a private key
+ if (!der_decode_sequence_many<1>(in.data(), in.size(),
+ ASN1::Kind::Integer, 1, &n)) {
+ // that's no key
+ // that's a death star
+ dbg() << "that's a death star";
+ return keypair;
+ }
+
+ if (n == 0) {
+ // it is a private key
+ UnsignedBigInteger zero;
+ if (!der_decode_sequence_many<4>(in.data(), in.size(),
+ ASN1::Kind::Integer, 1, &zero,
+ ASN1::Kind::Integer, 1, &n,
+ ASN1::Kind::Integer, 1, &e,
+ ASN1::Kind::Integer, 1, &d)) {
+ dbg() << "bad privkey " << n << " " << e << " " << d;
return keypair;
}
- // it's a broken public key
- keypair.public_key.set(n, 65537);
+ keypair.private_key.set(n, d, e);
return keypair;
}
+ if (n == 1) {
+ // multiprime key, we don't know how to deal with this
+ dbg() << "Unsupported key type";
+ return keypair;
+ }
+ // it's a broken public key
+ keypair.public_key.set(n, 65537);
+ return keypair;
+}
- void RSA::encrypt(const ByteBuffer& in, ByteBuffer& out)
- {
- dbg() << "in size: " << in.size();
- auto in_integer = UnsignedBigInteger::import_data(in.data(), in.size());
- if (!(in_integer < m_public_key.modulus())) {
- dbg() << "value too large for key";
- out.clear();
- return;
- }
- auto exp = NumberTheory::ModularPower(in_integer, m_public_key.public_exponent(), m_public_key.modulus());
- auto size = exp.export_data(out);
- // FIXME: We should probably not do this...
- if (size != out.size())
- out = out.slice(out.size() - size, size);
+void RSA::encrypt(const ByteBuffer& in, ByteBuffer& out)
+{
+ dbg() << "in size: " << in.size();
+ auto in_integer = UnsignedBigInteger::import_data(in.data(), in.size());
+ if (!(in_integer < m_public_key.modulus())) {
+ dbg() << "value too large for key";
+ out.clear();
+ return;
}
+ auto exp = NumberTheory::ModularPower(in_integer, m_public_key.public_exponent(), m_public_key.modulus());
+ auto size = exp.export_data(out);
+ // FIXME: We should probably not do this...
+ if (size != out.size())
+ out = out.slice(out.size() - size, size);
+}
- void RSA::decrypt(const ByteBuffer& in, ByteBuffer& out)
- {
- // FIXME: Actually use the private key properly
+void RSA::decrypt(const ByteBuffer& in, ByteBuffer& out)
+{
+ // FIXME: Actually use the private key properly
- auto in_integer = UnsignedBigInteger::import_data(in.data(), in.size());
- auto exp = NumberTheory::ModularPower(in_integer, m_private_key.private_exponent(), m_private_key.modulus());
- auto size = exp.export_data(out);
+ auto in_integer = UnsignedBigInteger::import_data(in.data(), in.size());
+ auto exp = NumberTheory::ModularPower(in_integer, m_private_key.private_exponent(), m_private_key.modulus());
+ auto size = exp.export_data(out);
- auto align = m_private_key.length();
- auto aligned_size = (size + align - 1) / align * align;
+ auto align = m_private_key.length();
+ auto aligned_size = (size + align - 1) / align * align;
- for (auto i = size; i < aligned_size; ++i)
- out[out.size() - i - 1] = 0; // zero the non-aligned values
- out = out.slice(out.size() - aligned_size, aligned_size);
- }
+ for (auto i = size; i < aligned_size; ++i)
+ out[out.size() - i - 1] = 0; // zero the non-aligned values
+ out = out.slice(out.size() - aligned_size, aligned_size);
+}
- void RSA::sign(const ByteBuffer& in, ByteBuffer& out)
- {
- auto in_integer = UnsignedBigInteger::import_data(in.data(), in.size());
- auto exp = NumberTheory::ModularPower(in_integer, m_private_key.private_exponent(), m_private_key.modulus());
- auto size = exp.export_data(out);
- out = out.slice(out.size() - size, size);
- }
+void RSA::sign(const ByteBuffer& in, ByteBuffer& out)
+{
+ auto in_integer = UnsignedBigInteger::import_data(in.data(), in.size());
+ auto exp = NumberTheory::ModularPower(in_integer, m_private_key.private_exponent(), m_private_key.modulus());
+ auto size = exp.export_data(out);
+ out = out.slice(out.size() - size, size);
+}
- void RSA::verify(const ByteBuffer& in, ByteBuffer& out)
- {
- auto in_integer = UnsignedBigInteger::import_data(in.data(), in.size());
- auto exp = NumberTheory::ModularPower(in_integer, m_public_key.public_exponent(), m_public_key.modulus());
- auto size = exp.export_data(out);
- out = out.slice(out.size() - size, size);
- }
+void RSA::verify(const ByteBuffer& in, ByteBuffer& out)
+{
+ auto in_integer = UnsignedBigInteger::import_data(in.data(), in.size());
+ auto exp = NumberTheory::ModularPower(in_integer, m_public_key.public_exponent(), m_public_key.modulus());
+ auto size = exp.export_data(out);
+ out = out.slice(out.size() - size, size);
+}
- void RSA::import_private_key(const ByteBuffer& buffer, bool pem)
- {
- // so gods help me, I hate DER
- auto decoded_buffer = pem ? decode_pem(buffer) : buffer;
- auto key = parse_rsa_key(decoded_buffer);
- if (!key.private_key.length()) {
- dbg() << "We expected to see a private key, but we found none";
- ASSERT_NOT_REACHED();
- }
- m_private_key = key.private_key;
+void RSA::import_private_key(const ByteBuffer& buffer, bool pem)
+{
+ // so gods help me, I hate DER
+ auto decoded_buffer = pem ? decode_pem(buffer) : buffer;
+ auto key = parse_rsa_key(decoded_buffer);
+ if (!key.private_key.length()) {
+ dbg() << "We expected to see a private key, but we found none";
+ ASSERT_NOT_REACHED();
}
+ m_private_key = key.private_key;
+}
- void RSA::import_public_key(const ByteBuffer& buffer, bool pem)
- {
- // so gods help me, I hate DER
- auto decoded_buffer = pem ? decode_pem(buffer) : buffer;
- auto key = parse_rsa_key(decoded_buffer);
- if (!key.public_key.length()) {
- dbg() << "We expected to see a public key, but we found none";
- ASSERT_NOT_REACHED();
- }
- m_public_key = key.public_key;
+void RSA::import_public_key(const ByteBuffer& buffer, bool pem)
+{
+ // so gods help me, I hate DER
+ auto decoded_buffer = pem ? decode_pem(buffer) : buffer;
+ auto key = parse_rsa_key(decoded_buffer);
+ if (!key.public_key.length()) {
+ dbg() << "We expected to see a public key, but we found none";
+ ASSERT_NOT_REACHED();
}
+ m_public_key = key.public_key;
+}
- template <typename HashFunction>
- void RSA_EMSA_PSS<HashFunction>::sign(const ByteBuffer& in, ByteBuffer& out)
- {
- // -- encode via EMSA_PSS
- auto mod_bits = m_rsa.private_key().modulus().trimmed_length() * sizeof(u32) * 8;
+template<typename HashFunction>
+void RSA_EMSA_PSS<HashFunction>::sign(const ByteBuffer& in, ByteBuffer& out)
+{
+ // -- encode via EMSA_PSS
+ auto mod_bits = m_rsa.private_key().modulus().trimmed_length() * sizeof(u32) * 8;
- u8 EM[mod_bits];
- auto EM_buf = ByteBuffer::wrap(EM, mod_bits);
- m_emsa_pss.encode(in, EM_buf, mod_bits - 1);
+ u8 EM[mod_bits];
+ auto EM_buf = ByteBuffer::wrap(EM, mod_bits);
+ m_emsa_pss.encode(in, EM_buf, mod_bits - 1);
- // -- sign via RSA
- m_rsa.sign(EM_buf, out);
- }
+ // -- sign via RSA
+ m_rsa.sign(EM_buf, out);
+}
- template <typename HashFunction>
- VerificationConsistency RSA_EMSA_PSS<HashFunction>::verify(const ByteBuffer& in)
- {
- auto mod_bytes = m_rsa.public_key().modulus().trimmed_length() * sizeof(u32);
- if (in.size() != mod_bytes)
- return VerificationConsistency::Inconsistent;
+template<typename HashFunction>
+VerificationConsistency RSA_EMSA_PSS<HashFunction>::verify(const ByteBuffer& in)
+{
+ auto mod_bytes = m_rsa.public_key().modulus().trimmed_length() * sizeof(u32);
+ if (in.size() != mod_bytes)
+ return VerificationConsistency::Inconsistent;
- u8 EM[mod_bytes];
- auto EM_buf = ByteBuffer::wrap(EM, mod_bytes);
+ u8 EM[mod_bytes];
+ auto EM_buf = ByteBuffer::wrap(EM, mod_bytes);
- // -- verify via RSA
- m_rsa.verify(in, EM_buf);
+ // -- verify via RSA
+ m_rsa.verify(in, EM_buf);
- // -- verify via EMSA_PSS
- return m_emsa_pss.verify(in, EM, mod_bytes * 8 - 1);
- }
+ // -- verify via EMSA_PSS
+ return m_emsa_pss.verify(in, EM, mod_bytes * 8 - 1);
+}
- void RSA_PKCS1_EME::encrypt(const ByteBuffer& in, ByteBuffer& out)
- {
- auto mod_len = (m_public_key.modulus().trimmed_length() * sizeof(u32) * 8 + 7) / 8;
- dbg() << "key size: " << mod_len;
- if (in.size() > mod_len - 11) {
- dbg() << "message too long :(";
- out.trim(0);
- return;
- }
- if (out.size() < mod_len) {
- dbg() << "output buffer too small";
- return;
- }
+void RSA_PKCS1_EME::encrypt(const ByteBuffer& in, ByteBuffer& out)
+{
+ auto mod_len = (m_public_key.modulus().trimmed_length() * sizeof(u32) * 8 + 7) / 8;
+ dbg() << "key size: " << mod_len;
+ if (in.size() > mod_len - 11) {
+ dbg() << "message too long :(";
+ out.trim(0);
+ return;
+ }
+ if (out.size() < mod_len) {
+ dbg() << "output buffer too small";
+ return;
+ }
- auto ps_length = mod_len - in.size() - 3;
- u8 ps[ps_length];
+ auto ps_length = mod_len - in.size() - 3;
+ u8 ps[ps_length];
- arc4random_buf(ps, ps_length);
- u8 paddings[] { 0x00, 0x02 };
+ arc4random_buf(ps, ps_length);
+ u8 paddings[] { 0x00, 0x02 };
- out.overwrite(0, paddings, 2);
- out.overwrite(2, ps, ps_length);
- out.overwrite(2 + ps_length, paddings, 1);
- out.overwrite(3 + ps_length, in.data(), in.size());
- out.trim(3 + ps_length + in.size()); // should be a single block
+ out.overwrite(0, paddings, 2);
+ out.overwrite(2, ps, ps_length);
+ out.overwrite(2 + ps_length, paddings, 1);
+ out.overwrite(3 + ps_length, in.data(), in.size());
+ out.trim(3 + ps_length + in.size()); // should be a single block
- dbg() << "padded output size: " << 3 + ps_length + in.size() << " buffer size: " << out.size();
+ dbg() << "padded output size: " << 3 + ps_length + in.size() << " buffer size: " << out.size();
- RSA::encrypt(out, out);
+ RSA::encrypt(out, out);
+}
+void RSA_PKCS1_EME::decrypt(const ByteBuffer& in, ByteBuffer& out)
+{
+ auto mod_len = (m_public_key.modulus().trimmed_length() * sizeof(u32) * 8 + 7) / 8;
+ if (in.size() != mod_len) {
+ dbg() << "decryption error: wrong amount of data: " << in.size();
+ out.trim(0);
+ return;
}
- void RSA_PKCS1_EME::decrypt(const ByteBuffer& in, ByteBuffer& out)
- {
- auto mod_len = (m_public_key.modulus().trimmed_length() * sizeof(u32) * 8 + 7) / 8;
- if (in.size() != mod_len) {
- dbg() << "decryption error: wrong amount of data: " << in.size();
- out.trim(0);
- return;
- }
-
- RSA::decrypt(in, out);
- if (out.size() < RSA::output_size()) {
- dbg() << "decryption error: not enough data after decryption: " << out.size();
- out.trim(0);
- return;
- }
-
- if (out[0] != 0x00) {
- dbg() << "invalid padding byte 0 : " << out[0];
- return;
- }
+ RSA::decrypt(in, out);
- if (out[1] != 0x02) {
- dbg() << "invalid padding byte 1" << out[1];
- return;
- }
+ if (out.size() < RSA::output_size()) {
+ dbg() << "decryption error: not enough data after decryption: " << out.size();
+ out.trim(0);
+ return;
+ }
- size_t offset = 2;
- while (offset < out.size() && out[offset])
- ++offset;
+ if (out[0] != 0x00) {
+ dbg() << "invalid padding byte 0 : " << out[0];
+ return;
+ }
- if (offset == out.size()) {
- dbg() << "garbage data, no zero to split padding";
- return;
- }
+ if (out[1] != 0x02) {
+ dbg() << "invalid padding byte 1" << out[1];
+ return;
+ }
+ size_t offset = 2;
+ while (offset < out.size() && out[offset])
++offset;
- if (offset - 3 < 8) {
- dbg() << "PS too small";
- return;
- }
-
- out = out.slice(offset, out.size() - offset);
+ if (offset == out.size()) {
+ dbg() << "garbage data, no zero to split padding";
+ return;
}
- void RSA_PKCS1_EME::sign(const ByteBuffer&, ByteBuffer&)
- {
- dbg() << "FIXME: RSA_PKCS_EME::sign";
- }
- void RSA_PKCS1_EME::verify(const ByteBuffer&, ByteBuffer&)
- {
- dbg() << "FIXME: RSA_PKCS_EME::verify";
+ ++offset;
+
+ if (offset - 3 < 8) {
+ dbg() << "PS too small";
+ return;
}
+
+ out = out.slice(offset, out.size() - offset);
+}
+
+void RSA_PKCS1_EME::sign(const ByteBuffer&, ByteBuffer&)
+{
+ dbg() << "FIXME: RSA_PKCS_EME::sign";
+}
+void RSA_PKCS1_EME::verify(const ByteBuffer&, ByteBuffer&)
+{
+ dbg() << "FIXME: RSA_PKCS_EME::verify";
+}
}
}
diff --git a/Libraries/LibCrypto/PK/RSA.h b/Libraries/LibCrypto/PK/RSA.h
index ece8a5aa00..b0fcdba160 100644
--- a/Libraries/LibCrypto/PK/RSA.h
+++ b/Libraries/LibCrypto/PK/RSA.h
@@ -34,201 +34,201 @@
namespace Crypto {
namespace PK {
- template <typename Integer = u64>
- class RSAPublicKey {
- public:
- RSAPublicKey(const Integer& n, const Integer& e)
- : m_modulus(n)
- , m_public_exponent(e)
- {
- }
-
- RSAPublicKey()
- : m_modulus(0)
- , m_public_exponent(0)
- {
- }
-
- //--stuff it should do
-
- const Integer& modulus() const { return m_modulus; }
- const Integer& public_exponent() const { return m_public_exponent; }
- size_t length() const { return m_length; }
- void set_length(size_t length) { m_length = length; }
-
- void set(const Integer& n, const Integer& e)
- {
- m_modulus = n;
- m_public_exponent = e;
- m_length = (n.trimmed_length() * sizeof(u32));
- }
-
- private:
- Integer m_modulus;
- Integer m_public_exponent;
- size_t m_length { 0 };
- };
-
- template <typename Integer = UnsignedBigInteger>
- class RSAPrivateKey {
- public:
- RSAPrivateKey(const Integer& n, const Integer& d, const Integer& e)
- : m_modulus(n)
- , m_private_exponent(d)
- , m_public_exponent(e)
- {
- }
-
- RSAPrivateKey()
- {
- }
-
- //--stuff it should do
- const Integer& modulus() const { return m_modulus; }
- const Integer& private_exponent() const { return m_private_exponent; }
- const Integer& public_exponent() const { return m_public_exponent; }
- size_t length() const { return m_length; }
- void set_length(size_t length) { m_length = length; }
-
- void set(const Integer& n, const Integer& d, const Integer& e)
- {
- m_modulus = n;
- m_private_exponent = d;
- m_public_exponent = e;
- m_length = (n.length() * sizeof(u32));
- }
-
- private:
- Integer m_modulus;
- Integer m_private_exponent;
- Integer m_public_exponent;
- size_t m_length { 0 };
- };
-
- template <typename PubKey, typename PrivKey>
- struct RSAKeyPair {
- PubKey public_key;
- PrivKey private_key;
- };
-
- using IntegerType = UnsignedBigInteger;
- class RSA : public PKSystem<RSAPrivateKey<IntegerType>, RSAPublicKey<IntegerType>> {
- template <typename T>
- friend class RSA_EMSA_PSS;
-
- public:
- using KeyPairType = RSAKeyPair<PublicKeyType, PrivateKeyType>;
-
- static KeyPairType parse_rsa_key(const ByteBuffer&);
- static KeyPairType generate_key_pair(size_t bits = 256)
- {
- IntegerType e { 65537 }; // :P
- IntegerType p, q;
- IntegerType lambda;
-
- do {
- p = NumberTheory::random_big_prime(bits / 2);
- q = NumberTheory::random_big_prime(bits / 2);
- lambda = NumberTheory::LCM(p.sub(1), q.sub(1));
- dbg() << "checking combination p=" << p << ", q=" << q << ", lambda=" << lambda.length();
- } while (!(NumberTheory::GCD(e, lambda) == 1));
-
- auto n = p.multiply(q);
-
- auto d = NumberTheory::ModularInverse(e, lambda);
- dbg() << "Your keys are Pub{n=" << n << ", e=" << e << "} and Priv{n=" << n << ", d=" << d << "}";
- RSAKeyPair<PublicKeyType, PrivateKeyType> keys {
- { n, e },
- { n, d, e }
- };
- keys.public_key.set_length(bits / 2 / 8);
- keys.private_key.set_length(bits / 2 / 8);
- return keys;
- }
-
- RSA(IntegerType n, IntegerType d, IntegerType e)
- {
- m_public_key.set(n, e);
- m_private_key.set(n, d, e);
- }
-
- RSA(PublicKeyType& pubkey, PrivateKeyType& privkey)
- : PKSystem<RSAPrivateKey<IntegerType>, RSAPublicKey<IntegerType>>(pubkey, privkey)
- {
- }
-
- RSA(const ByteBuffer& publicKeyPEM, const ByteBuffer& privateKeyPEM)
- {
- import_public_key(publicKeyPEM);
- import_private_key(privateKeyPEM);
- }
-
- RSA(const StringView& privKeyPEM)
- {
- import_private_key(ByteBuffer::wrap(privKeyPEM.characters_without_null_termination(), privKeyPEM.length()));
- m_public_key.set(m_private_key.modulus(), m_private_key.public_exponent());
- }
-
- // create our own keys
- RSA()
- {
- auto pair = generate_key_pair();
- m_public_key = pair.public_key;
- m_private_key = pair.private_key;
- }
-
- virtual void encrypt(const ByteBuffer& in, ByteBuffer& out) override;
- virtual void decrypt(const ByteBuffer& in, ByteBuffer& out) override;
-
- virtual void sign(const ByteBuffer& in, ByteBuffer& out) override;
- virtual void verify(const ByteBuffer& in, ByteBuffer& out) override;
-
- virtual String class_name() const override { return "RSA"; }
-
- virtual size_t output_size() const override { return m_public_key.length(); }
-
- void import_public_key(const ByteBuffer& buffer, bool pem = true);
- void import_private_key(const ByteBuffer& buffer, bool pem = true);
-
- const PrivateKeyType& private_key() const { return m_private_key; }
- const PublicKeyType& public_key() const { return m_public_key; }
- };
-
- template <typename HashFunction>
- class RSA_EMSA_PSS {
- public:
- RSA_EMSA_PSS(RSA& rsa)
- : m_rsa(rsa)
- {
- }
-
- void sign(const ByteBuffer& in, ByteBuffer& out);
- VerificationConsistency verify(const ByteBuffer& in);
-
- private:
- EMSA_PSS<HashFunction, HashFunction::DigestSize> m_emsa_pss;
- RSA m_rsa;
- };
-
- class RSA_PKCS1_EME : public RSA {
- public:
- // forward all constructions to RSA
- template <typename... Args>
- RSA_PKCS1_EME(Args... args)
- : RSA(args...)
- {
- }
-
- ~RSA_PKCS1_EME() {}
-
- virtual void encrypt(const ByteBuffer& in, ByteBuffer& out) override;
- virtual void decrypt(const ByteBuffer& in, ByteBuffer& out) override;
-
- virtual void sign(const ByteBuffer&, ByteBuffer&) override;
- virtual void verify(const ByteBuffer&, ByteBuffer&) override;
-
- virtual String class_name() const override { return "RSA_PKCS1-EME"; }
- virtual size_t output_size() const override { return m_public_key.length(); }
- };
+template<typename Integer = u64>
+class RSAPublicKey {
+public:
+ RSAPublicKey(const Integer& n, const Integer& e)
+ : m_modulus(n)
+ , m_public_exponent(e)
+ {
+ }
+
+ RSAPublicKey()
+ : m_modulus(0)
+ , m_public_exponent(0)
+ {
+ }
+
+ //--stuff it should do
+
+ const Integer& modulus() const { return m_modulus; }
+ const Integer& public_exponent() const { return m_public_exponent; }
+ size_t length() const { return m_length; }
+ void set_length(size_t length) { m_length = length; }
+
+ void set(const Integer& n, const Integer& e)
+ {
+ m_modulus = n;
+ m_public_exponent = e;
+ m_length = (n.trimmed_length() * sizeof(u32));
+ }
+
+private:
+ Integer m_modulus;
+ Integer m_public_exponent;
+ size_t m_length { 0 };
+};
+
+template<typename Integer = UnsignedBigInteger>
+class RSAPrivateKey {
+public:
+ RSAPrivateKey(const Integer& n, const Integer& d, const Integer& e)
+ : m_modulus(n)
+ , m_private_exponent(d)
+ , m_public_exponent(e)
+ {
+ }
+
+ RSAPrivateKey()
+ {
+ }
+
+ //--stuff it should do
+ const Integer& modulus() const { return m_modulus; }
+ const Integer& private_exponent() const { return m_private_exponent; }
+ const Integer& public_exponent() const { return m_public_exponent; }
+ size_t length() const { return m_length; }
+ void set_length(size_t length) { m_length = length; }
+
+ void set(const Integer& n, const Integer& d, const Integer& e)
+ {
+ m_modulus = n;
+ m_private_exponent = d;
+ m_public_exponent = e;
+ m_length = (n.length() * sizeof(u32));
+ }
+
+private:
+ Integer m_modulus;
+ Integer m_private_exponent;
+ Integer m_public_exponent;
+ size_t m_length { 0 };
+};
+
+template<typename PubKey, typename PrivKey>
+struct RSAKeyPair {
+ PubKey public_key;
+ PrivKey private_key;
+};
+
+using IntegerType = UnsignedBigInteger;
+class RSA : public PKSystem<RSAPrivateKey<IntegerType>, RSAPublicKey<IntegerType>> {
+ template<typename T>
+ friend class RSA_EMSA_PSS;
+
+public:
+ using KeyPairType = RSAKeyPair<PublicKeyType, PrivateKeyType>;
+
+ static KeyPairType parse_rsa_key(const ByteBuffer&);
+ static KeyPairType generate_key_pair(size_t bits = 256)
+ {
+ IntegerType e { 65537 }; // :P
+ IntegerType p, q;
+ IntegerType lambda;
+
+ do {
+ p = NumberTheory::random_big_prime(bits / 2);
+ q = NumberTheory::random_big_prime(bits / 2);
+ lambda = NumberTheory::LCM(p.sub(1), q.sub(1));
+ dbg() << "checking combination p=" << p << ", q=" << q << ", lambda=" << lambda.length();
+ } while (!(NumberTheory::GCD(e, lambda) == 1));
+
+ auto n = p.multiply(q);
+
+ auto d = NumberTheory::ModularInverse(e, lambda);
+ dbg() << "Your keys are Pub{n=" << n << ", e=" << e << "} and Priv{n=" << n << ", d=" << d << "}";
+ RSAKeyPair<PublicKeyType, PrivateKeyType> keys {
+ { n, e },
+ { n, d, e }
+ };
+ keys.public_key.set_length(bits / 2 / 8);
+ keys.private_key.set_length(bits / 2 / 8);
+ return keys;
+ }
+
+ RSA(IntegerType n, IntegerType d, IntegerType e)
+ {
+ m_public_key.set(n, e);
+ m_private_key.set(n, d, e);
+ }
+
+ RSA(PublicKeyType& pubkey, PrivateKeyType& privkey)
+ : PKSystem<RSAPrivateKey<IntegerType>, RSAPublicKey<IntegerType>>(pubkey, privkey)
+ {
+ }
+
+ RSA(const ByteBuffer& publicKeyPEM, const ByteBuffer& privateKeyPEM)
+ {
+ import_public_key(publicKeyPEM);
+ import_private_key(privateKeyPEM);
+ }
+
+ RSA(const StringView& privKeyPEM)
+ {
+ import_private_key(ByteBuffer::wrap(privKeyPEM.characters_without_null_termination(), privKeyPEM.length()));
+ m_public_key.set(m_private_key.modulus(), m_private_key.public_exponent());
+ }
+
+ // create our own keys
+ RSA()
+ {
+ auto pair = generate_key_pair();
+ m_public_key = pair.public_key;
+ m_private_key = pair.private_key;
+ }
+
+ virtual void encrypt(const ByteBuffer& in, ByteBuffer& out) override;
+ virtual void decrypt(const ByteBuffer& in, ByteBuffer& out) override;
+
+ virtual void sign(const ByteBuffer& in, ByteBuffer& out) override;
+ virtual void verify(const ByteBuffer& in, ByteBuffer& out) override;
+
+ virtual String class_name() const override { return "RSA"; }
+
+ virtual size_t output_size() const override { return m_public_key.length(); }
+
+ void import_public_key(const ByteBuffer& buffer, bool pem = true);
+ void import_private_key(const ByteBuffer& buffer, bool pem = true);
+
+ const PrivateKeyType& private_key() const { return m_private_key; }
+ const PublicKeyType& public_key() const { return m_public_key; }
+};
+
+template<typename HashFunction>
+class RSA_EMSA_PSS {
+public:
+ RSA_EMSA_PSS(RSA& rsa)
+ : m_rsa(rsa)
+ {
+ }
+
+ void sign(const ByteBuffer& in, ByteBuffer& out);
+ VerificationConsistency verify(const ByteBuffer& in);
+
+private:
+ EMSA_PSS<HashFunction, HashFunction::DigestSize> m_emsa_pss;
+ RSA m_rsa;
+};
+
+class RSA_PKCS1_EME : public RSA {
+public:
+ // forward all constructions to RSA
+ template<typename... Args>
+ RSA_PKCS1_EME(Args... args)
+ : RSA(args...)
+ {
+ }
+
+ ~RSA_PKCS1_EME() {}
+
+ virtual void encrypt(const ByteBuffer& in, ByteBuffer& out) override;
+ virtual void decrypt(const ByteBuffer& in, ByteBuffer& out) override;
+
+ virtual void sign(const ByteBuffer&, ByteBuffer&) override;
+ virtual void verify(const ByteBuffer&, ByteBuffer&) override;
+
+ virtual String class_name() const override { return "RSA_PKCS1-EME"; }
+ virtual size_t output_size() const override { return m_public_key.length(); }
+};
}
}