diff options
Diffstat (limited to 'src/libs/3rdparty/botan/src/lib/modes')
6 files changed, 107 insertions, 130 deletions
diff --git a/src/libs/3rdparty/botan/src/lib/modes/cbc/cbc.cpp b/src/libs/3rdparty/botan/src/lib/modes/cbc/cbc.cpp index c67664a6e7..c01fc43284 100644 --- a/src/libs/3rdparty/botan/src/lib/modes/cbc/cbc.cpp +++ b/src/libs/3rdparty/botan/src/lib/modes/cbc/cbc.cpp @@ -2,6 +2,7 @@ * CBC Mode * (C) 1999-2007,2013,2017 Jack Lloyd * (C) 2016 Daniel Neus, Rohde & Schwarz Cybersecurity +* (C) 2018 Ribose Inc * * Botan is released under the Simplified BSD License (see license.txt) */ @@ -15,9 +16,9 @@ namespace Botan { CBC_Mode::CBC_Mode(BlockCipher* cipher, BlockCipherModePaddingMethod* padding) : m_cipher(cipher), m_padding(padding), - m_state(m_cipher->block_size()) + m_block_size(cipher->block_size()) { - if(m_padding && !m_padding->valid_blocksize(cipher->block_size())) + if(m_padding && !m_padding->valid_blocksize(m_block_size)) throw Invalid_Argument("Padding " + m_padding->name() + " cannot be used with " + cipher->name() + "/CBC"); @@ -31,7 +32,7 @@ void CBC_Mode::clear() void CBC_Mode::reset() { - zeroise(m_state); + m_state.clear(); } std::string CBC_Mode::name() const @@ -65,6 +66,7 @@ bool CBC_Mode::valid_nonce_length(size_t n) const void CBC_Mode::key_schedule(const uint8_t key[], size_t length) { m_cipher->set_key(key, length); + m_state.clear(); } void CBC_Mode::start_msg(const uint8_t nonce[], size_t nonce_len) @@ -79,6 +81,9 @@ void CBC_Mode::start_msg(const uint8_t nonce[], size_t nonce_len) */ if(nonce_len) m_state.assign(nonce, nonce + nonce_len); + else if(m_state.empty()) + m_state.resize(m_cipher->block_size()); + // else leave the state alone } size_t CBC_Encryption::minimum_final_size() const @@ -96,6 +101,7 @@ size_t CBC_Encryption::output_length(size_t input_length) const size_t CBC_Encryption::process(uint8_t buf[], size_t sz) { + BOTAN_STATE_CHECK(state().empty() == false); const size_t BS = block_size(); BOTAN_ASSERT(sz % BS == 0, "CBC input is full blocks"); @@ -120,6 +126,7 @@ size_t CBC_Encryption::process(uint8_t buf[], size_t sz) void CBC_Encryption::finish(secure_vector<uint8_t>& buffer, size_t offset) { + BOTAN_STATE_CHECK(state().empty() == false); BOTAN_ASSERT(buffer.size() >= offset, "Offset is sane"); const size_t BS = block_size(); @@ -151,6 +158,7 @@ size_t CTS_Encryption::output_length(size_t input_length) const void CTS_Encryption::finish(secure_vector<uint8_t>& buffer, size_t offset) { + BOTAN_STATE_CHECK(state().empty() == false); BOTAN_ASSERT(buffer.size() >= offset, "Offset is sane"); uint8_t* buf = buffer.data() + offset; const size_t sz = buffer.size() - offset; @@ -205,6 +213,8 @@ size_t CBC_Decryption::minimum_final_size() const size_t CBC_Decryption::process(uint8_t buf[], size_t sz) { + BOTAN_STATE_CHECK(state().empty() == false); + const size_t BS = block_size(); BOTAN_ASSERT(sz % BS == 0, "Input is full blocks"); @@ -231,6 +241,7 @@ size_t CBC_Decryption::process(uint8_t buf[], size_t sz) void CBC_Decryption::finish(secure_vector<uint8_t>& buffer, size_t offset) { + BOTAN_STATE_CHECK(state().empty() == false); BOTAN_ASSERT(buffer.size() >= offset, "Offset is sane"); const size_t sz = buffer.size() - offset; @@ -251,7 +262,7 @@ void CBC_Decryption::finish(secure_vector<uint8_t>& buffer, size_t offset) void CBC_Decryption::reset() { - zeroise(state()); + CBC_Mode::reset(); zeroise(m_tempbuf); } @@ -267,6 +278,7 @@ size_t CTS_Decryption::minimum_final_size() const void CTS_Decryption::finish(secure_vector<uint8_t>& buffer, size_t offset) { + BOTAN_STATE_CHECK(state().empty() == false); BOTAN_ASSERT(buffer.size() >= offset, "Offset is sane"); const size_t sz = buffer.size() - offset; uint8_t* buf = buffer.data() + offset; diff --git a/src/libs/3rdparty/botan/src/lib/modes/cbc/cbc.h b/src/libs/3rdparty/botan/src/lib/modes/cbc/cbc.h index 65b6395115..aaa4257121 100644 --- a/src/libs/3rdparty/botan/src/lib/modes/cbc/cbc.h +++ b/src/libs/3rdparty/botan/src/lib/modes/cbc/cbc.h @@ -46,9 +46,9 @@ class BOTAN_PUBLIC_API(2,0) CBC_Mode : public Cipher_Mode return *m_padding; } - secure_vector<uint8_t>& state() { return m_state; } + size_t block_size() const { return m_block_size; } - size_t block_size() const { return m_state.size(); } + secure_vector<uint8_t>& state() { return m_state; } uint8_t* state_ptr() { return m_state.data(); } @@ -60,6 +60,7 @@ class BOTAN_PUBLIC_API(2,0) CBC_Mode : public Cipher_Mode std::unique_ptr<BlockCipher> m_cipher; std::unique_ptr<BlockCipherModePaddingMethod> m_padding; secure_vector<uint8_t> m_state; + size_t m_block_size; }; /** diff --git a/src/libs/3rdparty/botan/src/lib/modes/cipher_mode.cpp b/src/libs/3rdparty/botan/src/lib/modes/cipher_mode.cpp index 00d7a4db08..710f16ba22 100644 --- a/src/libs/3rdparty/botan/src/lib/modes/cipher_mode.cpp +++ b/src/libs/3rdparty/botan/src/lib/modes/cipher_mode.cpp @@ -35,6 +35,10 @@ #include <botan/internal/openssl.h> #endif +#if defined(BOTAN_HAS_COMMONCRYPTO) + #include <botan/internal/commoncrypto.h> +#endif + namespace Botan { std::unique_ptr<Cipher_Mode> Cipher_Mode::create_or_throw(const std::string& algo, @@ -51,6 +55,19 @@ std::unique_ptr<Cipher_Mode> Cipher_Mode::create(const std::string& algo, Cipher_Dir direction, const std::string& provider) { +#if defined(BOTAN_HAS_COMMONCRYPTO) + if(provider.empty() || provider == "commoncrypto") + { + std::unique_ptr<Cipher_Mode> commoncrypto_cipher(make_commoncrypto_cipher_mode(algo, direction)); + + if(commoncrypto_cipher) + return commoncrypto_cipher; + + if(!provider.empty()) + return std::unique_ptr<Cipher_Mode>(); + } +#endif + #if defined(BOTAN_HAS_OPENSSL) if(provider.empty() || provider == "openssl") { @@ -172,7 +189,7 @@ std::unique_ptr<Cipher_Mode> Cipher_Mode::create(const std::string& algo, //static std::vector<std::string> Cipher_Mode::providers(const std::string& algo_spec) { - const std::vector<std::string>& possible = { "base", "openssl" }; + const std::vector<std::string>& possible = { "base", "openssl", "commoncrypto" }; std::vector<std::string> providers; for(auto&& prov : possible) { diff --git a/src/libs/3rdparty/botan/src/lib/modes/cipher_mode.h b/src/libs/3rdparty/botan/src/lib/modes/cipher_mode.h index f67e737a43..9bf0b6811e 100644 --- a/src/libs/3rdparty/botan/src/lib/modes/cipher_mode.h +++ b/src/libs/3rdparty/botan/src/lib/modes/cipher_mode.h @@ -9,9 +9,8 @@ #define BOTAN_CIPHER_MODE_H_ #include <botan/secmem.h> -#include <botan/key_spec.h> +#include <botan/sym_algo.h> #include <botan/exceptn.h> -#include <botan/symkey.h> #include <string> #include <vector> @@ -26,11 +25,9 @@ enum Cipher_Dir : int { ENCRYPTION, DECRYPTION }; /** * Interface for cipher modes */ -class BOTAN_PUBLIC_API(2,0) Cipher_Mode +class BOTAN_PUBLIC_API(2,0) Cipher_Mode : public SymmetricAlgorithm { public: - virtual ~Cipher_Mode() = default; - /** * @return list of available providers for this algorithm, empty if not available * @param algo_spec algorithm name @@ -133,8 +130,9 @@ class BOTAN_PUBLIC_API(2,0) Cipher_Mode /** * Returns the size of the output if this transform is used to process a - * message with input_length bytes. Will throw if unable to give a precise - * answer. + * message with input_length bytes. In most cases the answer is precise. + * If it is not possible to precise (namely for CBC decryption) instead a + * lower bound is returned. */ virtual size_t output_length(size_t input_length) const = 0; @@ -159,14 +157,6 @@ class BOTAN_PUBLIC_API(2,0) Cipher_Mode */ virtual bool valid_nonce_length(size_t nonce_len) const = 0; - virtual std::string name() const = 0; - - /** - * Zeroise all state - * See also reset_msg() - */ - virtual void clear() = 0; - /** * Resets just the message specific state and allows encrypting again under the existing key */ @@ -184,59 +174,10 @@ class BOTAN_PUBLIC_API(2,0) Cipher_Mode virtual size_t tag_size() const { return 0; } /** - * @return object describing limits on key size - */ - virtual Key_Length_Specification key_spec() const = 0; - - /** - * Check whether a given key length is valid for this algorithm. - * @param length the key length to be checked. - * @return true if the key length is valid. - */ - bool valid_keylength(size_t length) const - { - return key_spec().valid_keylength(length); - } - - /** - * Set the symmetric key of this transform - * @param key contains the key material - */ - template<typename Alloc> - void set_key(const std::vector<uint8_t, Alloc>& key) - { - set_key(key.data(), key.size()); - } - - /** - * Set the symmetric key of this transform - * @param key contains the key material - */ - void set_key(const SymmetricKey& key) - { - set_key(key.begin(), key.length()); - } - - /** - * Set the symmetric key of this transform - * @param key contains the key material - * @param length in bytes of key param - */ - void set_key(const uint8_t key[], size_t length) - { - if(!valid_keylength(length)) - throw Invalid_Key_Length(name(), length); - key_schedule(key, length); - } - - /** * @return provider information about this implementation. Default is "base", * might also return "sse2", "avx2", "openssl", or some other arbitrary string. */ virtual std::string provider() const { return "base"; } - - private: - virtual void key_schedule(const uint8_t key[], size_t length) = 0; }; /** diff --git a/src/libs/3rdparty/botan/src/lib/modes/mode_pad/mode_pad.cpp b/src/libs/3rdparty/botan/src/lib/modes/mode_pad/mode_pad.cpp index f93b2dcccc..e65114c880 100644 --- a/src/libs/3rdparty/botan/src/lib/modes/mode_pad/mode_pad.cpp +++ b/src/libs/3rdparty/botan/src/lib/modes/mode_pad/mode_pad.cpp @@ -1,6 +1,6 @@ /* * CBC Padding Methods -* (C) 1999-2007,2013 Jack Lloyd +* (C) 1999-2007,2013,2018 Jack Lloyd * (C) 2016 René Korthaus, Rohde & Schwarz Cybersecurity * * Botan is released under the Simplified BSD License (see license.txt) @@ -51,26 +51,27 @@ void PKCS7_Padding::add_padding(secure_vector<uint8_t>& buffer, /* * Unpad with PKCS #7 Method */ -size_t PKCS7_Padding::unpad(const uint8_t block[], size_t size) const +size_t PKCS7_Padding::unpad(const uint8_t input[], size_t input_length) const { - CT::poison(block,size); + if(input_length <= 2) + return input_length; + + CT::poison(input, input_length); size_t bad_input = 0; - const uint8_t last_byte = block[size-1]; + const uint8_t last_byte = input[input_length-1]; - bad_input |= CT::expand_mask<size_t>(last_byte > size); + bad_input |= CT::expand_mask<size_t>(last_byte > input_length); - size_t pad_pos = size - last_byte; - size_t i = size - 2; - while(i) + const size_t pad_pos = input_length - last_byte; + + for(size_t i = 0; i != input_length - 1; ++i) { - bad_input |= (~CT::is_equal(block[i],last_byte)) & CT::expand_mask<uint8_t>(i >= pad_pos); - --i; + const uint8_t in_range = CT::expand_mask<uint8_t>(i >= pad_pos); + bad_input |= in_range & (~CT::is_equal(input[i], last_byte)); } - CT::conditional_copy_mem(bad_input,&pad_pos,&size,&pad_pos,1); - CT::unpoison(block,size); - CT::unpoison(pad_pos); - return pad_pos; + CT::unpoison(input, input_length); + return CT::conditional_return(bad_input, input_length, pad_pos); } /* @@ -92,25 +93,27 @@ void ANSI_X923_Padding::add_padding(secure_vector<uint8_t>& buffer, /* * Unpad with ANSI X9.23 Method */ -size_t ANSI_X923_Padding::unpad(const uint8_t block[], size_t size) const +size_t ANSI_X923_Padding::unpad(const uint8_t input[], size_t input_length) const { - CT::poison(block,size); - size_t bad_input = 0; - const size_t last_byte = block[size-1]; + if(input_length <= 2) + return input_length; - bad_input |= CT::expand_mask<size_t>(last_byte > size); + CT::poison(input, input_length); + const size_t last_byte = input[input_length-1]; - size_t pad_pos = size - last_byte; - size_t i = size - 2; - while(i) + uint8_t bad_input = 0; + bad_input |= CT::expand_mask<uint8_t>(last_byte > input_length); + + const size_t pad_pos = input_length - last_byte; + + for(size_t i = 0; i != input_length - 1; ++i) { - bad_input |= (~CT::is_zero(block[i])) & CT::expand_mask<uint8_t>(i >= pad_pos); - --i; + const uint8_t in_range = CT::expand_mask<uint8_t>(i >= pad_pos); + bad_input |= CT::expand_mask(input[i]) & in_range; } - CT::conditional_copy_mem(bad_input,&pad_pos,&size,&pad_pos,1); - CT::unpoison(block,size); - CT::unpoison(pad_pos); - return pad_pos; + + CT::unpoison(input, input_length); + return CT::conditional_return(bad_input, input_length, pad_pos); } /* @@ -129,28 +132,29 @@ void OneAndZeros_Padding::add_padding(secure_vector<uint8_t>& buffer, /* * Unpad with One and Zeros Method */ -size_t OneAndZeros_Padding::unpad(const uint8_t block[], size_t size) const +size_t OneAndZeros_Padding::unpad(const uint8_t input[], size_t input_length) const { - CT::poison(block, size); + if(input_length <= 2) + return input_length; + + CT::poison(input, input_length); + uint8_t bad_input = 0; uint8_t seen_one = 0; - size_t pad_pos = size - 1; - size_t i = size; + size_t pad_pos = input_length - 1; + size_t i = input_length; while(i) { - seen_one |= CT::is_equal<uint8_t>(block[i-1],0x80); + seen_one |= CT::is_equal<uint8_t>(input[i-1], 0x80); pad_pos -= CT::select<uint8_t>(~seen_one, 1, 0); - bad_input |= ~CT::is_zero<uint8_t>(block[i-1]) & ~seen_one; + bad_input |= ~CT::is_zero<uint8_t>(input[i-1]) & ~seen_one; i--; } bad_input |= ~seen_one; - CT::conditional_copy_mem(size_t(bad_input),&pad_pos,&size,&pad_pos,1); - CT::unpoison(block, size); - CT::unpoison(pad_pos); - - return pad_pos; + CT::unpoison(input, input_length); + return CT::conditional_return(bad_input, input_length, pad_pos); } /* @@ -171,25 +175,28 @@ void ESP_Padding::add_padding(secure_vector<uint8_t>& buffer, /* * Unpad with ESP Padding Method */ -size_t ESP_Padding::unpad(const uint8_t block[], size_t size) const +size_t ESP_Padding::unpad(const uint8_t input[], size_t input_length) const { - CT::poison(block,size); + if(input_length <= 2) + return input_length; - const size_t last_byte = block[size-1]; - size_t bad_input = 0; - bad_input |= CT::expand_mask<size_t>(last_byte > size); + CT::poison(input, input_length); + + const size_t last_byte = input[input_length-1]; + uint8_t bad_input = 0; + bad_input |= CT::is_zero(last_byte) | CT::expand_mask<uint8_t>(last_byte > input_length); - size_t pad_pos = size - last_byte; - size_t i = size - 1; + const size_t pad_pos = input_length - last_byte; + size_t i = input_length - 1; while(i) { - bad_input |= ~CT::is_equal<uint8_t>(size_t(block[i-1]),size_t(block[i])-1) & CT::expand_mask<uint8_t>(i > pad_pos); + const uint8_t in_range = CT::expand_mask<uint8_t>(i > pad_pos); + bad_input |= (~CT::is_equal<uint8_t>(input[i-1], input[i]-1)) & in_range; --i; } - CT::conditional_copy_mem(bad_input,&pad_pos,&size,&pad_pos,1); - CT::unpoison(block, size); - CT::unpoison(pad_pos); - return pad_pos; + + CT::unpoison(input, input_length); + return CT::conditional_return(bad_input, input_length, pad_pos); } diff --git a/src/libs/3rdparty/botan/src/lib/modes/mode_pad/mode_pad.h b/src/libs/3rdparty/botan/src/lib/modes/mode_pad/mode_pad.h index cc196d251b..25e4221af1 100644 --- a/src/libs/3rdparty/botan/src/lib/modes/mode_pad/mode_pad.h +++ b/src/libs/3rdparty/botan/src/lib/modes/mode_pad/mode_pad.h @@ -39,11 +39,10 @@ class BOTAN_PUBLIC_API(2,0) BlockCipherModePaddingMethod /** * Remove padding bytes from block * @param block the last block - * @param size the size of the block in bytes - * @return number of padding bytes + * @param len the size of the block in bytes + * @return number of data bytes, or if the padding is invalid returns len */ - virtual size_t unpad(const uint8_t block[], - size_t size) const = 0; + virtual size_t unpad(const uint8_t block[], size_t len) const = 0; /** * @param block_size of the cipher @@ -74,7 +73,7 @@ class BOTAN_PUBLIC_API(2,0) PKCS7_Padding final : public BlockCipherModePaddingM size_t unpad(const uint8_t[], size_t) const override; - bool valid_blocksize(size_t bs) const override { return (bs > 0 && bs < 256); } + bool valid_blocksize(size_t bs) const override { return (bs > 2 && bs < 256); } std::string name() const override { return "PKCS7"; } }; @@ -91,7 +90,7 @@ class BOTAN_PUBLIC_API(2,0) ANSI_X923_Padding final : public BlockCipherModePadd size_t unpad(const uint8_t[], size_t) const override; - bool valid_blocksize(size_t bs) const override { return (bs > 0 && bs < 256); } + bool valid_blocksize(size_t bs) const override { return (bs > 2 && bs < 256); } std::string name() const override { return "X9.23"; } }; @@ -108,7 +107,7 @@ class BOTAN_PUBLIC_API(2,0) OneAndZeros_Padding final : public BlockCipherModePa size_t unpad(const uint8_t[], size_t) const override; - bool valid_blocksize(size_t bs) const override { return (bs > 0); } + bool valid_blocksize(size_t bs) const override { return (bs > 2); } std::string name() const override { return "OneAndZeros"; } }; @@ -125,7 +124,7 @@ class BOTAN_PUBLIC_API(2,0) ESP_Padding final : public BlockCipherModePaddingMet size_t unpad(const uint8_t[], size_t) const override; - bool valid_blocksize(size_t bs) const override { return (bs > 0); } + bool valid_blocksize(size_t bs) const override { return (bs > 2 && bs < 256); } std::string name() const override { return "ESP"; } }; |