From f82b0a78eff1d79472d084ca327b30051df58487 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Sat, 19 Dec 2020 15:56:15 +0100 Subject: [PATCH] LibTLS+LibCrypto: More ByteBuffer -> Span conversion --- AK/Span.h | 7 +++++++ Libraries/LibCrypto/Authentication/HMAC.h | 12 +++++------- Libraries/LibCrypto/Hash/HashFunction.h | 7 +++++-- Libraries/LibCrypto/Hash/HashManager.h | 4 ++-- Libraries/LibCrypto/Hash/MD5.h | 8 ++++---- Libraries/LibCrypto/Hash/SHA1.h | 5 ++--- Libraries/LibCrypto/Hash/SHA2.h | 10 ++++------ Libraries/LibCrypto/PK/Code/EMSA_PSS.h | 14 +++++++------- Libraries/LibCrypto/PK/RSA.cpp | 2 +- Libraries/LibTLS/Exchange.cpp | 8 ++++---- Libraries/LibTLS/TLSv12.cpp | 2 +- Libraries/LibTLS/TLSv12.h | 2 +- Userland/test-crypto.cpp | 4 ++-- 13 files changed, 45 insertions(+), 40 deletions(-) diff --git a/AK/Span.h b/AK/Span.h index f8d0028934..e3c9a3eefe 100644 --- a/AK/Span.h +++ b/AK/Span.h @@ -156,6 +156,13 @@ public: return this->m_values + start; } + ALWAYS_INLINE constexpr void overwrite(size_t offset, const void* data, size_t data_size) + { + // make sure we're not told to write past the end + ASSERT(offset + data_size <= size()); + __builtin_memcpy(this->data() + offset, data, data_size); + } + ALWAYS_INLINE constexpr size_t copy_to(Span::Type> other) const { ASSERT(other.size() >= size()); diff --git a/Libraries/LibCrypto/Authentication/HMAC.h b/Libraries/LibCrypto/Authentication/HMAC.h index 8b0ba343cd..ef49bc06b7 100644 --- a/Libraries/LibCrypto/Authentication/HMAC.h +++ b/Libraries/LibCrypto/Authentication/HMAC.h @@ -68,12 +68,10 @@ public: m_inner_hasher.update(message, length); } - TagType process(const ReadonlyBytes& span) { return process(span.data(), span.size()); } - TagType process(const ByteBuffer& buffer) { return process(buffer.data(), buffer.size()); } + TagType process(ReadonlyBytes span) { return process(span.data(), span.size()); } TagType process(const StringView& string) { return process((const u8*)string.characters_without_null_termination(), string.length()); } - void update(const ReadonlyBytes& span) { return update(span.data(), span.size()); } - void update(const ByteBuffer& buffer) { return update(buffer.data(), buffer.size()); } + void update(ReadonlyBytes span) { return update(span.data(), span.size()); } void update(const StringView& string) { return update((const u8*)string.characters_without_null_termination(), string.length()); } TagType digest() @@ -106,7 +104,7 @@ private: auto block_size = m_inner_hasher.block_size(); u8 v_key[block_size]; __builtin_memset(v_key, 0, block_size); - ByteBuffer key_buffer = ByteBuffer::wrap(v_key, block_size); + auto key_buffer = Bytes { v_key, block_size }; // 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) @@ -129,8 +127,8 @@ private: } } - 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(ReadonlyBytes key) { derive_key(key.data(), key.size()); } + void derive_key(const StringView& key) { derive_key(key.bytes()); } HashType m_inner_hasher, m_outer_hasher; u8 m_key_data[2048]; diff --git a/Libraries/LibCrypto/Hash/HashFunction.h b/Libraries/LibCrypto/Hash/HashFunction.h index e6d5887484..3529615f50 100644 --- a/Libraries/LibCrypto/Hash/HashFunction.h +++ b/Libraries/LibCrypto/Hash/HashFunction.h @@ -45,8 +45,11 @@ public: static size_t digest_size() { return DigestSize; }; virtual void update(const u8*, size_t) = 0; - virtual void update(const ByteBuffer& buffer) { update(buffer.data(), buffer.size()); }; - virtual void update(const StringView& string) { update((const u8*)string.characters_without_null_termination(), string.length()); }; + + void update(const Bytes& buffer) { update(buffer.data(), buffer.size()); }; + void update(const ReadonlyBytes& buffer) { update(buffer.data(), buffer.size()); }; + void update(const ByteBuffer& buffer) { update(buffer.data(), buffer.size()); }; + void update(const StringView& string) { update((const u8*)string.characters_without_null_termination(), string.length()); }; virtual DigestType peek() = 0; virtual DigestType digest() = 0; diff --git a/Libraries/LibCrypto/Hash/HashManager.h b/Libraries/LibCrypto/Hash/HashManager.h index 94e3b7f375..9b47149602 100644 --- a/Libraries/LibCrypto/Hash/HashManager.h +++ b/Libraries/LibCrypto/Hash/HashManager.h @@ -117,6 +117,8 @@ struct MultiHashDigestVariant { class Manager final : public HashFunction<0, MultiHashDigestVariant> { public: + using HashFunction::update; + Manager() { m_pre_init_buffer = ByteBuffer::create_zeroed(0); @@ -142,8 +144,6 @@ public: m_md5 = nullptr; } - 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()); }; inline size_t digest_size() const { switch (m_kind) { diff --git a/Libraries/LibCrypto/Hash/MD5.h b/Libraries/LibCrypto/Hash/MD5.h index 3219cb9260..0ff01ba756 100644 --- a/Libraries/LibCrypto/Hash/MD5.h +++ b/Libraries/LibCrypto/Hash/MD5.h @@ -75,14 +75,14 @@ constexpr u8 PADDING[] = { class MD5 final : public HashFunction<512, MD5Digest> { public: + using HashFunction::update; + MD5() { - m_buffer = ByteBuffer::wrap(m_data_buffer, sizeof(m_data_buffer)); + m_buffer = Bytes { 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; @@ -118,7 +118,7 @@ private: 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; + Bytes m_buffer; u8 m_data_buffer[64]; }; diff --git a/Libraries/LibCrypto/Hash/SHA1.h b/Libraries/LibCrypto/Hash/SHA1.h index 594172f3e7..98ff61e17d 100644 --- a/Libraries/LibCrypto/Hash/SHA1.h +++ b/Libraries/LibCrypto/Hash/SHA1.h @@ -56,6 +56,8 @@ struct SHA1Digest { class SHA1 final : public HashFunction<512, SHA1Digest<160 / 8>> { public: + using HashFunction::update; + SHA1() { reset(); @@ -63,9 +65,6 @@ public: 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; diff --git a/Libraries/LibCrypto/Hash/SHA2.h b/Libraries/LibCrypto/Hash/SHA2.h index ebb38d9888..a67729e9a3 100644 --- a/Libraries/LibCrypto/Hash/SHA2.h +++ b/Libraries/LibCrypto/Hash/SHA2.h @@ -96,6 +96,8 @@ struct SHA2Digest { // FIXME: I want template but the compiler gets confused class SHA256 final : public HashFunction<512, SHA2Digest<256 / 8>> { public: + using HashFunction::update; + SHA256() { reset(); @@ -103,9 +105,6 @@ public: 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; @@ -149,6 +148,8 @@ private: class SHA512 final : public HashFunction<1024, SHA2Digest<512 / 8>> { public: + using HashFunction::update; + SHA512() { reset(); @@ -156,9 +157,6 @@ public: 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; diff --git a/Libraries/LibCrypto/PK/Code/EMSA_PSS.h b/Libraries/LibCrypto/PK/Code/EMSA_PSS.h index f484717ead..d12ff058b0 100644 --- a/Libraries/LibCrypto/PK/Code/EMSA_PSS.h +++ b/Libraries/LibCrypto/PK/Code/EMSA_PSS.h @@ -41,7 +41,7 @@ public: EMSA_PSS(Args... args) : Code(args...) { - m_buffer = ByteBuffer::wrap(m_data_buffer, sizeof(m_data_buffer)); + m_buffer = Bytes { m_data_buffer, sizeof(m_data_buffer) }; } static constexpr auto SaltLength = SaltSize; @@ -72,7 +72,7 @@ public: auto hash = hash_fn.digest(); u8 DB_data[em_length - HashFunction::DigestSize - 1]; - auto DB = ByteBuffer::wrap(DB_data, em_length - HashFunction::DigestSize - 1); + auto DB = Bytes { DB_data, em_length - HashFunction::DigestSize - 1 }; auto DB_offset = 0; for (size_t i = 0; i < em_length - SaltLength - HashFunction::DigestSize - 2; ++i) @@ -85,7 +85,7 @@ public: auto mask_length = em_length - HashFunction::DigestSize - 1; u8 DB_mask[mask_length]; - auto DB_mask_buffer = ByteBuffer::wrap(DB_mask, mask_length); + auto DB_mask_buffer = Bytes { DB_mask, mask_length }; // FIXME: we should probably allow reading from u8* MGF1(ReadonlyBytes { hash.data, HashFunction::DigestSize }, mask_length, DB_mask_buffer); @@ -123,7 +123,7 @@ public: return VerificationConsistency::Inconsistent; u8 DB_mask[mask_length]; - auto DB_mask_buffer = ByteBuffer::wrap(DB_mask, mask_length); + auto DB_mask_buffer = Bytes { DB_mask, mask_length }; MGF1(H, mask_length, DB_mask_buffer); u8 DB[mask_length]; @@ -145,7 +145,7 @@ public: auto* salt = DB + mask_length - SaltLength; u8 m_prime[8 + HashFunction::DigestSize + SaltLength] { 0, 0, 0, 0, 0, 0, 0, 0 }; - auto m_prime_buffer = ByteBuffer::wrap(m_prime, sizeof(m_prime)); + auto m_prime_buffer = Bytes { m_prime, sizeof(m_prime) }; m_prime_buffer.overwrite(8, message_hash.data, HashFunction::DigestSize); m_prime_buffer.overwrite(8 + HashFunction::DigestSize, salt, SaltLength); @@ -159,7 +159,7 @@ public: return VerificationConsistency::Consistent; } - void MGF1(ReadonlyBytes seed, size_t length, ByteBuffer& out) + void MGF1(ReadonlyBytes seed, size_t length, Bytes out) { auto& hash_fn = this->hasher(); ByteBuffer T = ByteBuffer::create_zeroed(0); @@ -173,7 +173,7 @@ public: private: u8 m_data_buffer[8 + HashFunction::DigestSize + SaltLength]; - ByteBuffer m_buffer; + Bytes m_buffer; }; } diff --git a/Libraries/LibCrypto/PK/RSA.cpp b/Libraries/LibCrypto/PK/RSA.cpp index 4ffaff54e8..4422e36e6d 100644 --- a/Libraries/LibCrypto/PK/RSA.cpp +++ b/Libraries/LibCrypto/PK/RSA.cpp @@ -204,7 +204,7 @@ void RSA_EMSA_PSS::sign(ReadonlyBytes in, ByteBuffer& out) 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); + auto EM_buf = Bytes { EM, mod_bits }; m_emsa_pss.encode(in, EM_buf, mod_bits - 1); // -- sign via RSA diff --git a/Libraries/LibTLS/Exchange.cpp b/Libraries/LibTLS/Exchange.cpp index 403617e9e1..f13484976c 100644 --- a/Libraries/LibTLS/Exchange.cpp +++ b/Libraries/LibTLS/Exchange.cpp @@ -33,7 +33,7 @@ namespace TLS { bool TLSv12::expand_key() { u8 key[192]; // soooooooo many constants - auto key_buffer = ByteBuffer::wrap(key, 192); + auto key_buffer = Bytes { key, sizeof(key) }; auto is_aead = this->is_aead(); @@ -108,7 +108,7 @@ bool TLSv12::expand_key() return true; } -void TLSv12::pseudorandom_function(ByteBuffer& output, ReadonlyBytes secret, const u8* label, size_t label_length, ReadonlyBytes seed, ReadonlyBytes seed_b) +void TLSv12::pseudorandom_function(Bytes output, ReadonlyBytes secret, const u8* label, size_t label_length, ReadonlyBytes seed, ReadonlyBytes seed_b) { if (!secret.size()) { dbg() << "null secret"; @@ -124,7 +124,7 @@ void TLSv12::pseudorandom_function(ByteBuffer& output, ReadonlyBytes secret, con auto l_seed_size = label_length + seed.size() + seed_b.size(); u8 l_seed[l_seed_size]; - auto label_seed_buffer = ByteBuffer::wrap(l_seed, l_seed_size); + auto label_seed_buffer = Bytes { l_seed, l_seed_size }; label_seed_buffer.overwrite(0, label, label_length); label_seed_buffer.overwrite(label_length, seed.data(), seed.size()); label_seed_buffer.overwrite(label_length + seed.size(), seed_b.data(), seed_b.size()); @@ -133,7 +133,7 @@ void TLSv12::pseudorandom_function(ByteBuffer& output, ReadonlyBytes secret, con u8 digest[digest_size]; - auto digest_0 = ByteBuffer::wrap(digest, digest_size); + auto digest_0 = Bytes { digest, digest_size }; digest_0.overwrite(0, hmac.process(label_seed_buffer).immutable_data(), digest_size); diff --git a/Libraries/LibTLS/TLSv12.cpp b/Libraries/LibTLS/TLSv12.cpp index eb4471486f..41a4c7156f 100644 --- a/Libraries/LibTLS/TLSv12.cpp +++ b/Libraries/LibTLS/TLSv12.cpp @@ -644,7 +644,7 @@ void TLSv12::ensure_hmac(size_t digest_size, bool local) break; } - auto hmac = make>(ByteBuffer::wrap(local ? m_context.crypto.local_mac : m_context.crypto.remote_mac, digest_size), hash_kind); + auto hmac = make>(ReadonlyBytes { local ? m_context.crypto.local_mac : m_context.crypto.remote_mac, digest_size }, hash_kind); if (local) m_hmac_local = move(hmac); else diff --git a/Libraries/LibTLS/TLSv12.h b/Libraries/LibTLS/TLSv12.h index 072540d3e4..ea335f070e 100644 --- a/Libraries/LibTLS/TLSv12.h +++ b/Libraries/LibTLS/TLSv12.h @@ -375,7 +375,7 @@ private: size_t asn1_length(ReadonlyBytes, size_t* octets); - void pseudorandom_function(ByteBuffer& output, ReadonlyBytes secret, const u8* label, size_t label_length, ReadonlyBytes seed, ReadonlyBytes seed_b); + void pseudorandom_function(Bytes output, ReadonlyBytes secret, const u8* label, size_t label_length, ReadonlyBytes seed, ReadonlyBytes seed_b); size_t key_length() const { diff --git a/Userland/test-crypto.cpp b/Userland/test-crypto.cpp index 861fc13daf..633ffe122a 100644 --- a/Userland/test-crypto.cpp +++ b/Userland/test-crypto.cpp @@ -1449,7 +1449,7 @@ static void hmac_sha1_test_process() { I_TEST((HMAC - SHA1 | Basic)); u8 key[] { 0xc8, 0x52, 0xe5, 0x4a, 0x2c, 0x03, 0x2b, 0xc9, 0x63, 0xd3, 0xc2, 0x79, 0x0f, 0x76, 0x43, 0xef, 0x36, 0xc3, 0x7a, 0xca }; - Crypto::Authentication::HMAC hmac(ByteBuffer::wrap(key, 20)); + Crypto::Authentication::HMAC hmac(ReadonlyBytes { key, sizeof(key) }); u8 result[] { 0x2c, 0x57, 0x32, 0x61, 0x3b, 0xa7, 0x84, 0x87, 0x0e, 0x4f, 0x42, 0x07, 0x2f, 0xf0, 0xe7, 0x41, 0xd7, 0x15, 0xf4, 0x56 }; @@ -1466,7 +1466,7 @@ static void hmac_sha1_test_process() { I_TEST((HMAC - SHA1 | Reuse)); u8 key[] { 0xc8, 0x52, 0xe5, 0x4a, 0x2c, 0x03, 0x2b, 0xc9, 0x63, 0xd3, 0xc2, 0x79, 0x0f, 0x76, 0x43, 0xef, 0x36, 0xc3, 0x7a, 0xca }; - Crypto::Authentication::HMAC hmac(ByteBuffer::wrap(key, 20)); + Crypto::Authentication::HMAC hmac(ReadonlyBytes { key, sizeof(key) }); u8 result[] { 0x2c, 0x57, 0x32, 0x61, 0x3b, 0xa7, 0x84, 0x87, 0x0e, 0x4f, 0x42, 0x07, 0x2f, 0xf0, 0xe7, 0x41, 0xd7, 0x15, 0xf4, 0x56 };