diff --git a/src/lib/base/buf_comp.h b/src/lib/base/buf_comp.h index c01cea6e2bf..24d998edb05 100644 --- a/src/lib/base/buf_comp.h +++ b/src/lib/base/buf_comp.h @@ -80,26 +80,14 @@ class BOTAN_PUBLIC_API(2,0) Buffered_Computation * final result as a container of your choice. * @return a contiguous container holding the result */ - template - requires(concepts::contiguous_container && - concepts::resizable_container) - T final() + template> + T final() { T output(output_length()); final_result(output.data()); return output; } - /** - * Complete the computation and retrieve the - * final result. - * @return secure_vector holding the result - */ - secure_vector final() - { - return final>(); - } - std::vector final_stdvec() { return final>(); @@ -111,8 +99,8 @@ class BOTAN_PUBLIC_API(2,0) Buffered_Computation final_result(out.data()); } - template - void final(std::vector& out) + template + void final(T& out) { out.resize(output_length()); final_result(out.data()); @@ -125,22 +113,11 @@ class BOTAN_PUBLIC_API(2,0) Buffered_Computation * @param length the length of the byte array * @result the result of the call to final() */ - secure_vector process(const uint8_t in[], size_t length) - { - add_data(in, length); - return final(); - } - - /** - * Update and finalize computation. Does the same as calling update() - * and final() consecutively. - * @param in the input to process - * @result the result of the call to final() - */ - secure_vector process(std::span in) + template> + T process(const uint8_t in[], size_t length) { - add_data(in.data(), in.size()); - return final(); + update(in, length); + return final(); } /** @@ -149,25 +126,24 @@ class BOTAN_PUBLIC_API(2,0) Buffered_Computation * @param in the input to process as a string * @result the result of the call to final() */ - secure_vector process(std::string_view in) + template> + T process(std::string_view in) { update(in); - return final(); + return final(); } /** * Update and finalize computation. Does the same as calling update() * and final() consecutively. - * @param in the input to process as a contiguous container or string-like + * @param in the input to process as a contiguous container * @result the result of the call to final() */ - template - requires(concepts::convertible_to || - concepts::convertible_to>) - OutT process(T in) + template> + T process(std::span in) { update(in); - return final(); + return final(); } virtual ~Buffered_Computation() = default; diff --git a/src/lib/modes/aead/ccm/ccm.cpp b/src/lib/modes/aead/ccm/ccm.cpp index e99c47af55a..41d0649360a 100644 --- a/src/lib/modes/aead/ccm/ccm.cpp +++ b/src/lib/modes/aead/ccm/ccm.cpp @@ -117,7 +117,7 @@ void CCM_Mode::start_msg(const uint8_t nonce[], size_t nonce_len) m_msg_buf.clear(); } -size_t CCM_Mode::process(uint8_t buf[], size_t sz) +size_t CCM_Mode::process_msg(uint8_t buf[], size_t sz) { BOTAN_STATE_CHECK(!m_nonce.empty()); m_msg_buf.insert(m_msg_buf.end(), buf, buf + sz); @@ -174,7 +174,7 @@ secure_vector CCM_Mode::format_c0() return C; } -void CCM_Encryption::finish(secure_vector& buffer, size_t offset) +void CCM_Encryption::finish_msg(secure_vector& buffer, size_t offset) { BOTAN_ARG_CHECK(buffer.size() >= offset, "Offset is out of range"); @@ -227,7 +227,7 @@ void CCM_Encryption::finish(secure_vector& buffer, size_t offset) reset(); } -void CCM_Decryption::finish(secure_vector& buffer, size_t offset) +void CCM_Decryption::finish_msg(secure_vector& buffer, size_t offset) { BOTAN_ARG_CHECK(buffer.size() >= offset, "Offset is out of range"); diff --git a/src/lib/modes/aead/ccm/ccm.h b/src/lib/modes/aead/ccm/ccm.h index ba3f6cfe54b..cf37c0d18fe 100644 --- a/src/lib/modes/aead/ccm/ccm.h +++ b/src/lib/modes/aead/ccm/ccm.h @@ -21,8 +21,6 @@ namespace Botan { class CCM_Mode : public AEAD_Mode { public: - size_t process(uint8_t buf[], size_t sz) override final; - void set_associated_data(const uint8_t ad[], size_t ad_len) override final; bool associated_data_requires_key() const override final { return false; } @@ -67,6 +65,7 @@ class CCM_Mode : public AEAD_Mode secure_vector format_c0(); private: void start_msg(const uint8_t nonce[], size_t nonce_len) override final; + size_t process_msg(uint8_t buf[], size_t sz) override final; void key_schedule(const uint8_t key[], size_t length) override final; @@ -93,12 +92,13 @@ class CCM_Encryption final : public CCM_Mode CCM_Encryption(std::unique_ptr cipher, size_t tag_size = 16, size_t L = 3) : CCM_Mode(std::move(cipher), tag_size, L) {} - void finish(secure_vector& final_block, size_t offset = 0) override; - size_t output_length(size_t input_length) const override { return input_length + tag_size(); } size_t minimum_final_size() const override { return 0; } + + private: + void finish_msg(secure_vector& final_block, size_t offset = 0) override; }; /** @@ -117,8 +117,6 @@ class CCM_Decryption final : public CCM_Mode CCM_Decryption(std::unique_ptr cipher, size_t tag_size = 16, size_t L = 3) : CCM_Mode(std::move(cipher), tag_size, L) {} - void finish(secure_vector& final_block, size_t offset = 0) override; - size_t output_length(size_t input_length) const override { BOTAN_ARG_CHECK(input_length >= tag_size(), "Sufficient input"); @@ -126,6 +124,9 @@ class CCM_Decryption final : public CCM_Mode } size_t minimum_final_size() const override { return tag_size(); } + + private: + void finish_msg(secure_vector& final_block, size_t offset = 0) override; }; } diff --git a/src/lib/modes/aead/chacha20poly1305/chacha20poly1305.cpp b/src/lib/modes/aead/chacha20poly1305/chacha20poly1305.cpp index d5fa9f612f5..88311ec42f3 100644 --- a/src/lib/modes/aead/chacha20poly1305/chacha20poly1305.cpp +++ b/src/lib/modes/aead/chacha20poly1305/chacha20poly1305.cpp @@ -105,7 +105,7 @@ void ChaCha20Poly1305_Mode::start_msg(const uint8_t nonce[], size_t nonce_len) } } -size_t ChaCha20Poly1305_Encryption::process(uint8_t buf[], size_t sz) +size_t ChaCha20Poly1305_Encryption::process_msg(uint8_t buf[], size_t sz) { m_chacha->cipher1(buf, sz); m_poly1305->update(buf, sz); // poly1305 of ciphertext @@ -113,7 +113,7 @@ size_t ChaCha20Poly1305_Encryption::process(uint8_t buf[], size_t sz) return sz; } -void ChaCha20Poly1305_Encryption::finish(secure_vector& buffer, size_t offset) +void ChaCha20Poly1305_Encryption::finish_msg(secure_vector& buffer, size_t offset) { update(buffer, offset); if(cfrg_version()) @@ -133,7 +133,7 @@ void ChaCha20Poly1305_Encryption::finish(secure_vector& buffer, size_t m_nonce_len = 0; } -size_t ChaCha20Poly1305_Decryption::process(uint8_t buf[], size_t sz) +size_t ChaCha20Poly1305_Decryption::process_msg(uint8_t buf[], size_t sz) { m_poly1305->update(buf, sz); // poly1305 of ciphertext m_chacha->cipher1(buf, sz); @@ -141,7 +141,7 @@ size_t ChaCha20Poly1305_Decryption::process(uint8_t buf[], size_t sz) return sz; } -void ChaCha20Poly1305_Decryption::finish(secure_vector& buffer, size_t offset) +void ChaCha20Poly1305_Decryption::finish_msg(secure_vector& buffer, size_t offset) { BOTAN_ARG_CHECK(buffer.size() >= offset, "Offset is out of range"); const size_t sz = buffer.size() - offset; diff --git a/src/lib/modes/aead/chacha20poly1305/chacha20poly1305.h b/src/lib/modes/aead/chacha20poly1305/chacha20poly1305.h index d28686dba48..dd1a3794642 100644 --- a/src/lib/modes/aead/chacha20poly1305/chacha20poly1305.h +++ b/src/lib/modes/aead/chacha20poly1305/chacha20poly1305.h @@ -77,9 +77,9 @@ class ChaCha20Poly1305_Encryption final : public ChaCha20Poly1305_Mode size_t minimum_final_size() const override { return 0; } - size_t process(uint8_t buf[], size_t size) override; - - void finish(secure_vector& final_block, size_t offset = 0) override; + private: + size_t process_msg(uint8_t buf[], size_t size) override; + void finish_msg(secure_vector& final_block, size_t offset = 0) override; }; /** @@ -96,9 +96,9 @@ class ChaCha20Poly1305_Decryption final : public ChaCha20Poly1305_Mode size_t minimum_final_size() const override { return tag_size(); } - size_t process(uint8_t buf[], size_t size) override; - - void finish(secure_vector& final_block, size_t offset = 0) override; + private: + size_t process_msg(uint8_t buf[], size_t size) override; + void finish_msg(secure_vector& final_block, size_t offset = 0) override; }; } diff --git a/src/lib/modes/aead/eax/eax.cpp b/src/lib/modes/aead/eax/eax.cpp index ae878214c1f..c37191d94ef 100644 --- a/src/lib/modes/aead/eax/eax.cpp +++ b/src/lib/modes/aead/eax/eax.cpp @@ -128,7 +128,7 @@ void EAX_Mode::start_msg(const uint8_t nonce[], size_t nonce_len) m_cmac->update(2); } -size_t EAX_Encryption::process(uint8_t buf[], size_t sz) +size_t EAX_Encryption::process_msg(uint8_t buf[], size_t sz) { BOTAN_STATE_CHECK(!m_nonce_mac.empty()); m_ctr->cipher(buf, buf, sz); @@ -136,7 +136,7 @@ size_t EAX_Encryption::process(uint8_t buf[], size_t sz) return sz; } -void EAX_Encryption::finish(secure_vector& buffer, size_t offset) +void EAX_Encryption::finish_msg(secure_vector& buffer, size_t offset) { BOTAN_STATE_CHECK(!m_nonce_mac.empty()); update(buffer, offset); @@ -156,7 +156,7 @@ void EAX_Encryption::finish(secure_vector& buffer, size_t offset) m_nonce_mac.clear(); } -size_t EAX_Decryption::process(uint8_t buf[], size_t sz) +size_t EAX_Decryption::process_msg(uint8_t buf[], size_t sz) { BOTAN_STATE_CHECK(!m_nonce_mac.empty()); m_cmac->update(buf, sz); @@ -164,7 +164,7 @@ size_t EAX_Decryption::process(uint8_t buf[], size_t sz) return sz; } -void EAX_Decryption::finish(secure_vector& buffer, size_t offset) +void EAX_Decryption::finish_msg(secure_vector& buffer, size_t offset) { BOTAN_ARG_CHECK(buffer.size() >= offset, "Offset is out of range"); const size_t sz = buffer.size() - offset; diff --git a/src/lib/modes/aead/eax/eax.h b/src/lib/modes/aead/eax/eax.h index 42a030bb259..d680bd81028 100644 --- a/src/lib/modes/aead/eax/eax.h +++ b/src/lib/modes/aead/eax/eax.h @@ -85,9 +85,9 @@ class EAX_Encryption final : public EAX_Mode size_t minimum_final_size() const override { return 0; } - size_t process(uint8_t buf[], size_t size) override; - - void finish(secure_vector& final_block, size_t offset = 0) override; + private: + size_t process_msg(uint8_t buf[], size_t size) override; + void finish_msg(secure_vector& final_block, size_t offset = 0) override; }; /** @@ -111,9 +111,9 @@ class EAX_Decryption final : public EAX_Mode size_t minimum_final_size() const override { return tag_size(); } - size_t process(uint8_t buf[], size_t size) override; - - void finish(secure_vector& final_block, size_t offset = 0) override; + private: + size_t process_msg(uint8_t buf[], size_t size) override; + void finish_msg(secure_vector& final_block, size_t offset = 0) override; }; } diff --git a/src/lib/modes/aead/gcm/gcm.cpp b/src/lib/modes/aead/gcm/gcm.cpp index ee714177dd4..1ceb73be0eb 100644 --- a/src/lib/modes/aead/gcm/gcm.cpp +++ b/src/lib/modes/aead/gcm/gcm.cpp @@ -128,7 +128,7 @@ void GCM_Mode::start_msg(const uint8_t nonce[], size_t nonce_len) clear_mem(m_y0.data(), m_y0.size()); } -size_t GCM_Encryption::process(uint8_t buf[], size_t sz) +size_t GCM_Encryption::process_msg(uint8_t buf[], size_t sz) { BOTAN_ARG_CHECK(sz % update_granularity() == 0, "Invalid buffer size"); m_ctr->cipher(buf, buf, sz); @@ -136,7 +136,7 @@ size_t GCM_Encryption::process(uint8_t buf[], size_t sz) return sz; } -void GCM_Encryption::finish(secure_vector& buffer, size_t offset) +void GCM_Encryption::finish_msg(secure_vector& buffer, size_t offset) { BOTAN_ARG_CHECK(offset <= buffer.size(), "Invalid offset"); const size_t sz = buffer.size() - offset; @@ -150,7 +150,7 @@ void GCM_Encryption::finish(secure_vector& buffer, size_t offset) buffer += std::make_pair(mac, tag_size()); } -size_t GCM_Decryption::process(uint8_t buf[], size_t sz) +size_t GCM_Decryption::process_msg(uint8_t buf[], size_t sz) { BOTAN_ARG_CHECK(sz % update_granularity() == 0, "Invalid buffer size"); m_ghash->update(buf, sz); @@ -158,7 +158,7 @@ size_t GCM_Decryption::process(uint8_t buf[], size_t sz) return sz; } -void GCM_Decryption::finish(secure_vector& buffer, size_t offset) +void GCM_Decryption::finish_msg(secure_vector& buffer, size_t offset) { BOTAN_ARG_CHECK(offset <= buffer.size(), "Invalid offset"); const size_t sz = buffer.size() - offset; diff --git a/src/lib/modes/aead/gcm/gcm.h b/src/lib/modes/aead/gcm/gcm.h index 4f7c597d241..4cdb838ecae 100644 --- a/src/lib/modes/aead/gcm/gcm.h +++ b/src/lib/modes/aead/gcm/gcm.h @@ -83,9 +83,9 @@ class GCM_Encryption final : public GCM_Mode size_t minimum_final_size() const override { return 0; } - size_t process(uint8_t buf[], size_t size) override; - - void finish(secure_vector& final_block, size_t offset = 0) override; + private: + size_t process_msg(uint8_t buf[], size_t size) override; + void finish_msg(secure_vector& final_block, size_t offset = 0) override; }; /** @@ -109,9 +109,9 @@ class GCM_Decryption final : public GCM_Mode size_t minimum_final_size() const override { return tag_size(); } - size_t process(uint8_t buf[], size_t size) override; - - void finish(secure_vector& final_block, size_t offset = 0) override; + private: + size_t process_msg(uint8_t buf[], size_t size) override; + void finish_msg(secure_vector& final_block, size_t offset = 0) override; }; } diff --git a/src/lib/modes/aead/ocb/ocb.cpp b/src/lib/modes/aead/ocb/ocb.cpp index ec4a5ecb439..7bd0800980e 100644 --- a/src/lib/modes/aead/ocb/ocb.cpp +++ b/src/lib/modes/aead/ocb/ocb.cpp @@ -375,14 +375,14 @@ void OCB_Encryption::encrypt(uint8_t buffer[], size_t blocks) } } -size_t OCB_Encryption::process(uint8_t buf[], size_t sz) +size_t OCB_Encryption::process_msg(uint8_t buf[], size_t sz) { BOTAN_ARG_CHECK(sz % update_granularity() == 0, "Invalid OCB input size"); encrypt(buf, sz / block_size()); return sz; } -void OCB_Encryption::finish(secure_vector& buffer, size_t offset) +void OCB_Encryption::finish_msg(secure_vector& buffer, size_t offset) { assert_key_material_set(); BOTAN_STATE_CHECK(m_L->initialized()); @@ -466,14 +466,14 @@ void OCB_Decryption::decrypt(uint8_t buffer[], size_t blocks) } } -size_t OCB_Decryption::process(uint8_t buf[], size_t sz) +size_t OCB_Decryption::process_msg(uint8_t buf[], size_t sz) { BOTAN_ARG_CHECK(sz % update_granularity() == 0, "Invalid OCB input size"); decrypt(buf, sz / block_size()); return sz; } -void OCB_Decryption::finish(secure_vector& buffer, size_t offset) +void OCB_Decryption::finish_msg(secure_vector& buffer, size_t offset) { assert_key_material_set(); BOTAN_STATE_CHECK(m_L->initialized()); diff --git a/src/lib/modes/aead/ocb/ocb.h b/src/lib/modes/aead/ocb/ocb.h index 0345c422603..f034e78dfb3 100644 --- a/src/lib/modes/aead/ocb/ocb.h +++ b/src/lib/modes/aead/ocb/ocb.h @@ -102,11 +102,10 @@ class BOTAN_TEST_API OCB_Encryption final : public OCB_Mode size_t minimum_final_size() const override { return 0; } - size_t process(uint8_t buf[], size_t size) override; - - void finish(secure_vector& final_block, size_t offset = 0) override; private: void encrypt(uint8_t input[], size_t blocks); + size_t process_msg(uint8_t buf[], size_t size) override; + void finish_msg(secure_vector& final_block, size_t offset = 0) override; }; class BOTAN_TEST_API OCB_Decryption final : public OCB_Mode @@ -127,11 +126,10 @@ class BOTAN_TEST_API OCB_Decryption final : public OCB_Mode size_t minimum_final_size() const override { return tag_size(); } - size_t process(uint8_t buf[], size_t size) override; - - void finish(secure_vector& final_block, size_t offset = 0) override; private: void decrypt(uint8_t input[], size_t blocks); + size_t process_msg(uint8_t buf[], size_t size) override; + void finish_msg(secure_vector& final_block, size_t offset = 0) override; }; } diff --git a/src/lib/modes/aead/siv/siv.cpp b/src/lib/modes/aead/siv/siv.cpp index d206a3f79f3..d2d97ef6a9f 100644 --- a/src/lib/modes/aead/siv/siv.cpp +++ b/src/lib/modes/aead/siv/siv.cpp @@ -116,7 +116,7 @@ void SIV_Mode::start_msg(const uint8_t nonce[], size_t nonce_len) m_msg_buf.clear(); } -size_t SIV_Mode::process(uint8_t buf[], size_t sz) +size_t SIV_Mode::process_msg(uint8_t buf[], size_t sz) { // all output is saved for processing in finish m_msg_buf.insert(m_msg_buf.end(), buf, buf + sz); @@ -164,7 +164,7 @@ void SIV_Mode::set_ctr_iv(secure_vector V) ctr().set_iv(V.data(), V.size()); } -void SIV_Encryption::finish(secure_vector& buffer, size_t offset) +void SIV_Encryption::finish_msg(secure_vector& buffer, size_t offset) { BOTAN_ARG_CHECK(buffer.size() >= offset, "Offset is out of range"); @@ -182,7 +182,7 @@ void SIV_Encryption::finish(secure_vector& buffer, size_t offset) } } -void SIV_Decryption::finish(secure_vector& buffer, size_t offset) +void SIV_Decryption::finish_msg(secure_vector& buffer, size_t offset) { BOTAN_ARG_CHECK(buffer.size() >= offset, "Offset is out of range"); diff --git a/src/lib/modes/aead/siv/siv.h b/src/lib/modes/aead/siv/siv.h index d2e0d8b8400..fd378ad3553 100644 --- a/src/lib/modes/aead/siv/siv.h +++ b/src/lib/modes/aead/siv/siv.h @@ -23,8 +23,6 @@ class MessageAuthenticationCode; class BOTAN_TEST_API SIV_Mode : public AEAD_Mode { public: - size_t process(uint8_t buf[], size_t size) override final; - /** * Sets the nth element of the vector of associated data * @param n index into the AD vector @@ -76,6 +74,7 @@ class BOTAN_TEST_API SIV_Mode : public AEAD_Mode secure_vector S2V(const uint8_t text[], size_t text_len); private: void start_msg(const uint8_t nonce[], size_t nonce_len) override final; + size_t process_msg(uint8_t buf[], size_t size) override final; void key_schedule(const uint8_t key[], size_t length) override final; @@ -100,12 +99,13 @@ class BOTAN_TEST_API SIV_Encryption final : public SIV_Mode explicit SIV_Encryption(std::unique_ptr cipher) : SIV_Mode(std::move(cipher)) {} - void finish(secure_vector& final_block, size_t offset = 0) override; - size_t output_length(size_t input_length) const override { return input_length + tag_size(); } size_t minimum_final_size() const override { return 0; } + + private: + void finish_msg(secure_vector& final_block, size_t offset = 0) override; }; /** @@ -120,8 +120,6 @@ class BOTAN_TEST_API SIV_Decryption final : public SIV_Mode explicit SIV_Decryption(std::unique_ptr cipher) : SIV_Mode(std::move(cipher)) {} - void finish(secure_vector& final_block, size_t offset = 0) override; - size_t output_length(size_t input_length) const override { BOTAN_ASSERT(input_length >= tag_size(), "Sufficient input"); @@ -129,6 +127,9 @@ class BOTAN_TEST_API SIV_Decryption final : public SIV_Mode } size_t minimum_final_size() const override { return tag_size(); } + + private: + void finish_msg(secure_vector& final_block, size_t offset = 0) override; }; } diff --git a/src/lib/modes/cbc/cbc.cpp b/src/lib/modes/cbc/cbc.cpp index 6bc40e286a9..09e09fdbc30 100644 --- a/src/lib/modes/cbc/cbc.cpp +++ b/src/lib/modes/cbc/cbc.cpp @@ -110,7 +110,7 @@ size_t CBC_Encryption::output_length(size_t input_length) const return round_up(input_length, block_size()); } -size_t CBC_Encryption::process(uint8_t buf[], size_t sz) +size_t CBC_Encryption::process_msg(uint8_t buf[], size_t sz) { BOTAN_STATE_CHECK(state().empty() == false); const size_t BS = block_size(); @@ -135,7 +135,7 @@ size_t CBC_Encryption::process(uint8_t buf[], size_t sz) return sz; } -void CBC_Encryption::finish(secure_vector& buffer, size_t offset) +void CBC_Encryption::finish_msg(secure_vector& buffer, size_t offset) { BOTAN_STATE_CHECK(state().empty() == false); BOTAN_ARG_CHECK(buffer.size() >= offset, "Offset is out of range"); @@ -166,7 +166,7 @@ size_t CTS_Encryption::output_length(size_t input_length) const return input_length; // no ciphertext expansion in CTS } -void CTS_Encryption::finish(secure_vector& buffer, size_t offset) +void CTS_Encryption::finish_msg(secure_vector& buffer, size_t offset) { BOTAN_STATE_CHECK(state().empty() == false); BOTAN_ARG_CHECK(buffer.size() >= offset, "Offset is out of range"); @@ -221,7 +221,7 @@ size_t CBC_Decryption::minimum_final_size() const return block_size(); } -size_t CBC_Decryption::process(uint8_t buf[], size_t sz) +size_t CBC_Decryption::process_msg(uint8_t buf[], size_t sz) { BOTAN_STATE_CHECK(state().empty() == false); @@ -249,7 +249,7 @@ size_t CBC_Decryption::process(uint8_t buf[], size_t sz) return sz; } -void CBC_Decryption::finish(secure_vector& buffer, size_t offset) +void CBC_Decryption::finish_msg(secure_vector& buffer, size_t offset) { BOTAN_STATE_CHECK(state().empty() == false); BOTAN_ARG_CHECK(buffer.size() >= offset, "Offset is out of range"); @@ -286,7 +286,7 @@ size_t CTS_Decryption::minimum_final_size() const return block_size() + 1; } -void CTS_Decryption::finish(secure_vector& buffer, size_t offset) +void CTS_Decryption::finish_msg(secure_vector& buffer, size_t offset) { BOTAN_STATE_CHECK(state().empty() == false); BOTAN_ARG_CHECK(buffer.size() >= offset, "Offset is out of range"); diff --git a/src/lib/modes/cbc/cbc.h b/src/lib/modes/cbc/cbc.h index b2567ab3fce..1fe55bc2e85 100644 --- a/src/lib/modes/cbc/cbc.h +++ b/src/lib/modes/cbc/cbc.h @@ -81,13 +81,13 @@ class CBC_Encryption : public CBC_Mode std::unique_ptr padding) : CBC_Mode(std::move(cipher), std::move(padding)) {} - size_t process(uint8_t buf[], size_t size) override; - - void finish(secure_vector& final_block, size_t offset = 0) override; - size_t output_length(size_t input_length) const override; size_t minimum_final_size() const override; + + private: + size_t process_msg(uint8_t buf[], size_t size) override; + void finish_msg(secure_vector& final_block, size_t offset = 0) override; }; /** @@ -105,11 +105,12 @@ class CTS_Encryption final : public CBC_Encryption size_t output_length(size_t input_length) const override; - void finish(secure_vector& final_block, size_t offset = 0) override; - size_t minimum_final_size() const override; bool valid_nonce_length(size_t n) const override; + + private: + void finish_msg(secure_vector& final_block, size_t offset = 0) override; }; /** @@ -128,10 +129,6 @@ class CBC_Decryption : public CBC_Mode m_tempbuf(ideal_granularity()) {} - size_t process(uint8_t buf[], size_t size) override; - - void finish(secure_vector& final_block, size_t offset = 0) override; - size_t output_length(size_t input_length) const override; size_t minimum_final_size() const override; @@ -139,6 +136,9 @@ class CBC_Decryption : public CBC_Mode void reset() override; private: + size_t process_msg(uint8_t buf[], size_t size) override; + void finish_msg(secure_vector& final_block, size_t offset = 0) override; + secure_vector m_tempbuf; }; @@ -155,11 +155,12 @@ class CTS_Decryption final : public CBC_Decryption CBC_Decryption(std::move(cipher), nullptr) {} - void finish(secure_vector& final_block, size_t offset = 0) override; - size_t minimum_final_size() const override; bool valid_nonce_length(size_t n) const override; + + private: + void finish_msg(secure_vector& final_block, size_t offset = 0) override; }; } diff --git a/src/lib/modes/cfb/cfb.cpp b/src/lib/modes/cfb/cfb.cpp index 11a95f06681..4394e319faf 100644 --- a/src/lib/modes/cfb/cfb.cpp +++ b/src/lib/modes/cfb/cfb.cpp @@ -125,7 +125,7 @@ void CFB_Mode::shift_register() m_keystream_pos = 0; } -size_t CFB_Encryption::process(uint8_t buf[], size_t sz) +size_t CFB_Encryption::process_msg(uint8_t buf[], size_t sz) { assert_key_material_set(); BOTAN_STATE_CHECK(m_state.empty() == false); @@ -171,7 +171,7 @@ size_t CFB_Encryption::process(uint8_t buf[], size_t sz) return sz; } -void CFB_Encryption::finish(secure_vector& buffer, size_t offset) +void CFB_Encryption::finish_msg(secure_vector& buffer, size_t offset) { update(buffer, offset); } @@ -190,7 +190,7 @@ inline void xor_copy(uint8_t buf[], uint8_t key_buf[], size_t len) } -size_t CFB_Decryption::process(uint8_t buf[], size_t sz) +size_t CFB_Decryption::process_msg(uint8_t buf[], size_t sz) { assert_key_material_set(); BOTAN_STATE_CHECK(m_state.empty() == false); @@ -232,7 +232,7 @@ size_t CFB_Decryption::process(uint8_t buf[], size_t sz) return sz; } -void CFB_Decryption::finish(secure_vector& buffer, size_t offset) +void CFB_Decryption::finish_msg(secure_vector& buffer, size_t offset) { update(buffer, offset); } diff --git a/src/lib/modes/cfb/cfb.h b/src/lib/modes/cfb/cfb.h index 153e932d2ba..b42f338465c 100644 --- a/src/lib/modes/cfb/cfb.h +++ b/src/lib/modes/cfb/cfb.h @@ -78,9 +78,9 @@ class CFB_Encryption final : public CFB_Mode CFB_Encryption(std::unique_ptr cipher, size_t feedback_bits) : CFB_Mode(std::move(cipher), feedback_bits) {} - size_t process(uint8_t buf[], size_t size) override; - - void finish(secure_vector& final_block, size_t offset = 0) override; + private: + size_t process_msg(uint8_t buf[], size_t size) override; + void finish_msg(secure_vector& final_block, size_t offset = 0) override; }; /** @@ -98,9 +98,9 @@ class CFB_Decryption final : public CFB_Mode CFB_Decryption(std::unique_ptr cipher, size_t feedback_bits) : CFB_Mode(std::move(cipher), feedback_bits) {} - size_t process(uint8_t buf[], size_t size) override; - - void finish(secure_vector& final_block, size_t offset = 0) override; + private: + size_t process_msg(uint8_t buf[], size_t size) override; + void finish_msg(secure_vector& final_block, size_t offset = 0) override; }; } diff --git a/src/lib/modes/cipher_mode.h b/src/lib/modes/cipher_mode.h index c87d9d1dcf4..a88995f8a4a 100644 --- a/src/lib/modes/cipher_mode.h +++ b/src/lib/modes/cipher_mode.h @@ -8,10 +8,12 @@ #ifndef BOTAN_CIPHER_MODE_H_ #define BOTAN_CIPHER_MODE_H_ +#include #include #include #include #include +#include #include namespace Botan { @@ -62,17 +64,29 @@ class BOTAN_PUBLIC_API(2,0) Cipher_Mode : public SymmetricAlgorithm Cipher_Dir direction, const std::string& provider = ""); + protected: /* * Prepare for processing a message under the specified nonce */ virtual void start_msg(const uint8_t nonce[], size_t nonce_len) = 0; + /* + * Process message blocks + * Input must be a multiple of update_granularity. + */ + virtual size_t process_msg(uint8_t msg[], size_t msg_len) = 0; + + /* + * Finishes a message + */ + virtual void finish_msg(secure_vector& final_block, size_t offset = 0) = 0; + + public: /** * Begin processing a message with a fresh nonce. * @param nonce the per message nonce */ - template - void start(const std::vector& nonce) + void start(std::span nonce) { start_msg(nonce.data(), nonce.size()); } @@ -113,22 +127,23 @@ class BOTAN_PUBLIC_API(2,0) Cipher_Mode : public SymmetricAlgorithm * mode requires the entire message be processed in one pass). * * @param msg the message to be processed - * @param msg_len length of the message in bytes + * @return bytes written in-place */ - virtual size_t process(uint8_t msg[], size_t msg_len) = 0; + size_t process(std::span msg) + { return this->process_msg(msg.data(), msg.size()); } + size_t process(uint8_t msg[], size_t msg_len) + { return this->process_msg(msg, msg_len); } /** * Process some data. Input must be in size update_granularity() uint8_t blocks. * @param buffer in/out parameter which will possibly be resized * @param offset an offset into blocks to begin processing */ - void update(secure_vector& buffer, size_t offset = 0) + template + void update(T& buffer, size_t offset = 0) { BOTAN_ASSERT(buffer.size() >= offset, "Offset ok"); - uint8_t* buf = buffer.data() + offset; - const size_t buf_size = buffer.size() - offset; - - const size_t written = process(buf, buf_size); + const size_t written = process(std::span(buffer).subspan(offset)); buffer.resize(offset + written); } @@ -139,7 +154,29 @@ class BOTAN_PUBLIC_API(2,0) Cipher_Mode : public SymmetricAlgorithm * minimum_final_size() bytes, and will be set to any final output * @param offset an offset into final_block to begin processing */ - virtual void finish(secure_vector& final_block, size_t offset = 0) = 0; + void finish(secure_vector& final_block, size_t offset = 0) + { + finish_msg(final_block, offset); + } + + /** + * Complete procession of a message. + * + * Note: Using this overload with anything but a Botan::secure_vector<> + * is copying the bytes in the in/out buffer. + * + * @param final_block in/out parameter which must be at least + * minimum_final_size() bytes, and will be set to any final output + * @param offset an offset into final_block to begin processing + */ + template + void finish(T& final_block, size_t offset = 0) + { + Botan::secure_vector tmp(final_block.begin(), final_block.end()); + finish_msg(tmp, offset); + final_block.resize(tmp.size()); + std::copy(tmp.begin(), tmp.end(), final_block.begin()); + } /** * Returns the size of the output if this transform is used to process a diff --git a/src/lib/modes/stream_mode.h b/src/lib/modes/stream_mode.h index 8738eb044ba..22100f63b86 100644 --- a/src/lib/modes/stream_mode.h +++ b/src/lib/modes/stream_mode.h @@ -27,15 +27,6 @@ class Stream_Cipher_Mode final : public Cipher_Mode explicit Stream_Cipher_Mode(std::unique_ptr cipher) : m_cipher(std::move(cipher)) {} - size_t process(uint8_t buf[], size_t sz) override - { - m_cipher->cipher1(buf, sz); - return sz; - } - - void finish(secure_vector& buf, size_t offset) override - { return update(buf, offset); } - size_t output_length(size_t input_length) const override { return input_length; } size_t update_granularity() const override { return 1; } @@ -74,6 +65,15 @@ class Stream_Cipher_Mode final : public Cipher_Mode } } + size_t process_msg(uint8_t buf[], size_t sz) override + { + m_cipher->cipher1(buf, sz); + return sz; + } + + void finish_msg(secure_vector& buf, size_t offset) override + { return update(buf, offset); } + void key_schedule(const uint8_t key[], size_t length) override { m_cipher->set_key(key, length); diff --git a/src/lib/modes/xts/xts.cpp b/src/lib/modes/xts/xts.cpp index 96e40c156ab..34e190d6964 100644 --- a/src/lib/modes/xts/xts.cpp +++ b/src/lib/modes/xts/xts.cpp @@ -120,7 +120,7 @@ size_t XTS_Encryption::output_length(size_t input_length) const return input_length; } -size_t XTS_Encryption::process(uint8_t buf[], size_t sz) +size_t XTS_Encryption::process_msg(uint8_t buf[], size_t sz) { BOTAN_STATE_CHECK(tweak_set()); const size_t BS = cipher_block_size(); @@ -145,7 +145,7 @@ size_t XTS_Encryption::process(uint8_t buf[], size_t sz) return sz; } -void XTS_Encryption::finish(secure_vector& buffer, size_t offset) +void XTS_Encryption::finish_msg(secure_vector& buffer, size_t offset) { BOTAN_ARG_CHECK(buffer.size() >= offset, "Offset is out of range"); const size_t sz = buffer.size() - offset; @@ -195,7 +195,7 @@ size_t XTS_Decryption::output_length(size_t input_length) const return input_length; } -size_t XTS_Decryption::process(uint8_t buf[], size_t sz) +size_t XTS_Decryption::process_msg(uint8_t buf[], size_t sz) { BOTAN_STATE_CHECK(tweak_set()); const size_t BS = cipher_block_size(); @@ -220,7 +220,7 @@ size_t XTS_Decryption::process(uint8_t buf[], size_t sz) return sz; } -void XTS_Decryption::finish(secure_vector& buffer, size_t offset) +void XTS_Decryption::finish_msg(secure_vector& buffer, size_t offset) { BOTAN_ARG_CHECK(buffer.size() >= offset, "Offset is out of range"); const size_t sz = buffer.size() - offset; diff --git a/src/lib/modes/xts/xts.h b/src/lib/modes/xts/xts.h index 52cddb61216..959fed3c4a7 100644 --- a/src/lib/modes/xts/xts.h +++ b/src/lib/modes/xts/xts.h @@ -78,11 +78,11 @@ class XTS_Encryption final : public XTS_Mode explicit XTS_Encryption(std::unique_ptr cipher) : XTS_Mode(std::move(cipher)) {} - size_t process(uint8_t buf[], size_t size) override; - - void finish(secure_vector& final_block, size_t offset = 0) override; - size_t output_length(size_t input_length) const override; + + private: + size_t process_msg(uint8_t buf[], size_t size) override; + void finish_msg(secure_vector& final_block, size_t offset = 0) override; }; /** @@ -97,11 +97,11 @@ class XTS_Decryption final : public XTS_Mode explicit XTS_Decryption(std::unique_ptr cipher) : XTS_Mode(std::move(cipher)) {} - size_t process(uint8_t buf[], size_t size) override; - - void finish(secure_vector& final_block, size_t offset = 0) override; - size_t output_length(size_t input_length) const override; + + private: + size_t process_msg(uint8_t buf[], size_t size) override; + void finish_msg(secure_vector& final_block, size_t offset = 0) override; }; } diff --git a/src/lib/prov/commoncrypto/commoncrypto_mode.cpp b/src/lib/prov/commoncrypto/commoncrypto_mode.cpp index b1b00fd3998..503b6fd622c 100644 --- a/src/lib/prov/commoncrypto/commoncrypto_mode.cpp +++ b/src/lib/prov/commoncrypto/commoncrypto_mode.cpp @@ -28,9 +28,6 @@ class CommonCrypto_Cipher_Mode final : public Cipher_Mode std::string provider() const override { return "commoncrypto"; } std::string name() const override { return m_mode_name; } - void start_msg(const uint8_t nonce[], size_t nonce_len) override; - size_t process(uint8_t msg[], size_t msg_len) override; - void finish(secure_vector& final_block, size_t offset0) override; size_t output_length(size_t input_length) const override; size_t update_granularity() const override; size_t ideal_granularity() const override; @@ -45,6 +42,10 @@ class CommonCrypto_Cipher_Mode final : public Cipher_Mode private: void key_schedule(const uint8_t key[], size_t length) override; + void start_msg(const uint8_t nonce[], size_t nonce_len) override; + size_t process_msg(uint8_t msg[], size_t msg_len) override; + void finish_msg(secure_vector& final_block, size_t offset0) override; + const std::string m_mode_name; Cipher_Dir m_direction; CommonCryptor_Opts m_opts; @@ -88,7 +89,7 @@ void CommonCrypto_Cipher_Mode::start_msg(const uint8_t nonce[], size_t nonce_len m_nonce_set = true; } -size_t CommonCrypto_Cipher_Mode::process(uint8_t msg[], size_t msg_len) +size_t CommonCrypto_Cipher_Mode::process_msg(uint8_t msg[], size_t msg_len) { assert_key_material_set(); BOTAN_STATE_CHECK(m_nonce_set); @@ -117,8 +118,8 @@ size_t CommonCrypto_Cipher_Mode::process(uint8_t msg[], size_t msg_len) return outl; } -void CommonCrypto_Cipher_Mode::finish(secure_vector& buffer, - size_t offset) +void CommonCrypto_Cipher_Mode::finish_msg(secure_vector& buffer, + size_t offset) { assert_key_material_set(); BOTAN_STATE_CHECK(m_nonce_set); diff --git a/src/lib/pubkey/kyber/kyber_common/kyber.cpp b/src/lib/pubkey/kyber/kyber_common/kyber.cpp index b948f23cda3..7165d454976 100644 --- a/src/lib/pubkey/kyber/kyber_common/kyber.cpp +++ b/src/lib/pubkey/kyber/kyber_common/kyber.cpp @@ -1116,7 +1116,7 @@ class Kyber_PublicKeyInternal m_polynomials(PolynomialVector::from_bytes(polynomials, m_mode)), m_seed(std::move(seed)), m_public_key_bits_raw(concat(m_polynomials.to_bytes>(), m_seed)), - m_H_public_key_bits_raw(unlock(m_mode.H()->process(m_public_key_bits_raw))) + m_H_public_key_bits_raw(m_mode.H()->process>(m_public_key_bits_raw)) { } @@ -1125,7 +1125,7 @@ class Kyber_PublicKeyInternal m_polynomials(std::move(polynomials)), m_seed(std::move(seed)), m_public_key_bits_raw(concat(m_polynomials.to_bytes>(), m_seed)), - m_H_public_key_bits_raw(unlock(m_mode.H()->process(m_public_key_bits_raw))) + m_H_public_key_bits_raw(m_mode.H()->process>(m_public_key_bits_raw)) { } diff --git a/src/lib/rng/rng.h b/src/lib/rng/rng.h index 39c3cc60f20..cb9315af001 100644 --- a/src/lib/rng/rng.h +++ b/src/lib/rng/rng.h @@ -181,10 +181,7 @@ class BOTAN_PUBLIC_API(2,0) RandomNumberGenerator * @param bytes number of random bytes to initialize the container with * @throws Exception if RNG or memory allocation fails */ - template - requires(concepts::contiguous_container && - concepts::resizable_container && - std::same_as) + template void random_vec(T& v, size_t bytes) { v.resize(bytes); @@ -199,11 +196,8 @@ class BOTAN_PUBLIC_API(2,0) RandomNumberGenerator * @return a container of type T with @p bytes random bytes * @throws Exception if RNG or memory allocation fails */ - template> - requires(concepts::contiguous_container && - concepts::resizable_container && - concepts::default_initializable && - std::same_as) + template> + requires concepts::default_initializable T random_vec(size_t bytes) { T result; diff --git a/src/lib/tls/tls12/tls_cbc/tls_cbc.cpp b/src/lib/tls/tls12/tls_cbc/tls_cbc.cpp index 8dceb79b47a..74e16ca497d 100644 --- a/src/lib/tls/tls12/tls_cbc/tls_cbc.cpp +++ b/src/lib/tls/tls12/tls_cbc/tls_cbc.cpp @@ -123,7 +123,7 @@ void TLS_CBC_HMAC_AEAD_Mode::start_msg(const uint8_t nonce[], size_t nonce_len) } } -size_t TLS_CBC_HMAC_AEAD_Mode::process(uint8_t buf[], size_t sz) +size_t TLS_CBC_HMAC_AEAD_Mode::process_msg(uint8_t buf[], size_t sz) { m_msg.insert(m_msg.end(), buf, buf + sz); return 0; @@ -198,7 +198,7 @@ size_t TLS_CBC_HMAC_AEAD_Encryption::output_length(size_t input_length) const (use_encrypt_then_mac() ? tag_size() : 0); } -void TLS_CBC_HMAC_AEAD_Encryption::finish(secure_vector& buffer, size_t offset) +void TLS_CBC_HMAC_AEAD_Encryption::finish_msg(secure_vector& buffer, size_t offset) { update(buffer, offset); @@ -377,7 +377,7 @@ void TLS_CBC_HMAC_AEAD_Decryption::perform_additional_compressions(size_t plen, // we do not need to clear the MAC since the connection is broken anyway } -void TLS_CBC_HMAC_AEAD_Decryption::finish(secure_vector& buffer, size_t offset) +void TLS_CBC_HMAC_AEAD_Decryption::finish_msg(secure_vector& buffer, size_t offset) { update(buffer, offset); buffer.resize(offset); diff --git a/src/lib/tls/tls12/tls_cbc/tls_cbc.h b/src/lib/tls/tls12/tls_cbc/tls_cbc.h index 8b500b12aad..4c44916b099 100644 --- a/src/lib/tls/tls12/tls_cbc/tls_cbc.h +++ b/src/lib/tls/tls12/tls_cbc/tls_cbc.h @@ -25,8 +25,6 @@ namespace TLS { class BOTAN_TEST_API TLS_CBC_HMAC_AEAD_Mode : public AEAD_Mode { public: - size_t process(uint8_t buf[], size_t sz) override final; - std::string name() const override final; void set_associated_data(const uint8_t ad[], size_t ad_len) override; @@ -82,6 +80,7 @@ class BOTAN_TEST_API TLS_CBC_HMAC_AEAD_Mode : public AEAD_Mode private: void start_msg(const uint8_t nonce[], size_t nonce_len) override final; + size_t process_msg(uint8_t buf[], size_t sz) override final; void key_schedule(const uint8_t key[], size_t length) override final; @@ -133,8 +132,8 @@ class BOTAN_TEST_API TLS_CBC_HMAC_AEAD_Encryption final : public TLS_CBC_HMAC_AE size_t minimum_final_size() const override { return 0; } - void finish(secure_vector& final_block, size_t offset = 0) override; private: + void finish_msg(secure_vector& final_block, size_t offset = 0) override; void cbc_encrypt_record(secure_vector& buffer, size_t offset, size_t padding_length); }; @@ -166,9 +165,9 @@ class BOTAN_TEST_API TLS_CBC_HMAC_AEAD_Decryption final : public TLS_CBC_HMAC_AE size_t minimum_final_size() const override { return tag_size(); } - void finish(secure_vector& final_block, size_t offset = 0) override; - private: + void finish_msg(secure_vector& final_block, size_t offset = 0) override; + void cbc_decrypt_record(uint8_t record_contents[], size_t record_len); void perform_additional_compressions(size_t plen, size_t padlen); diff --git a/src/lib/utils/concepts.h b/src/lib/utils/concepts.h index dd172fa0e83..bdbaa917e13 100644 --- a/src/lib/utils/concepts.h +++ b/src/lib/utils/concepts.h @@ -110,6 +110,12 @@ concept resizable_container = c.resize(s); }; +template +concept resizable_byte_buffer = + contiguous_container && + resizable_container && + std::same_as; + template concept streamable = requires(std::ostream& os, T a) { os << a; };