aboutsummaryrefslogtreecommitdiffstats
path: root/src/libs/3rdparty/botan/src/lib/modes
diff options
context:
space:
mode:
Diffstat (limited to 'src/libs/3rdparty/botan/src/lib/modes')
-rw-r--r--src/libs/3rdparty/botan/src/lib/modes/cbc/cbc.cpp20
-rw-r--r--src/libs/3rdparty/botan/src/lib/modes/cbc/cbc.h5
-rw-r--r--src/libs/3rdparty/botan/src/lib/modes/cipher_mode.cpp19
-rw-r--r--src/libs/3rdparty/botan/src/lib/modes/cipher_mode.h69
-rw-r--r--src/libs/3rdparty/botan/src/lib/modes/mode_pad/mode_pad.cpp109
-rw-r--r--src/libs/3rdparty/botan/src/lib/modes/mode_pad/mode_pad.h15
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"; }
};