diff options
Diffstat (limited to 'src')
44 files changed, 138 insertions, 95 deletions
diff --git a/src/lib/asn1/asn1_time.cpp b/src/lib/asn1/asn1_time.cpp index 863a064f0..43f94af6a 100644 --- a/src/lib/asn1/asn1_time.cpp +++ b/src/lib/asn1/asn1_time.cpp @@ -37,8 +37,8 @@ X509_Time::X509_Time(const std::string& t_spec, ASN1_Tag tag) void X509_Time::encode_into(DER_Encoder& der) const { - if(m_tag != GENERALIZED_TIME && m_tag != UTC_TIME) - throw Invalid_Argument("X509_Time: Bad encoding tag"); + BOTAN_ARG_CHECK(m_tag == UTC_TIME || m_tag == GENERALIZED_TIME, + "X509_Time: Bad encoding tag"); der.add_object(m_tag, UNIVERSAL, to_string()); } @@ -161,21 +161,17 @@ void X509_Time::set_to(const std::string& t_spec, ASN1_Tag spec_tag) BOTAN_ASSERT(spec_tag == UTC_TIME || spec_tag == GENERALIZED_TIME, "Invalid tag."); - if(t_spec.empty()) - throw Invalid_Argument("Time string must not be empty."); + BOTAN_ARG_CHECK(t_spec.size() > 0, "Time string must not be empty."); - if(t_spec.back() != 'Z') - throw Unsupported_Argument("Botan does not support times with timezones other than Z: " + t_spec); + BOTAN_ARG_CHECK(t_spec.back() == 'Z', "Botan does not support times with timezones other than Z"); if(spec_tag == GENERALIZED_TIME) { - if(t_spec.size() != 15) - throw Invalid_Argument("Invalid GeneralizedTime string: '" + t_spec + "'"); + BOTAN_ARG_CHECK(t_spec.size() == 15, "Invalid GeneralizedTime string"); } else if(spec_tag == UTC_TIME) { - if(t_spec.size() != 13) - throw Invalid_Argument("Invalid UTCTime string: '" + t_spec + "'"); + BOTAN_ARG_CHECK(t_spec.size() == 13, "Invalid UTCTime string"); } const size_t YEAR_SIZE = (spec_tag == UTC_TIME) ? 2 : 4; diff --git a/src/lib/base/sym_algo.cpp b/src/lib/base/sym_algo.cpp new file mode 100644 index 000000000..c6062667b --- /dev/null +++ b/src/lib/base/sym_algo.cpp @@ -0,0 +1,25 @@ +/* +* (C) 2018 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include <botan/sym_algo.h> +#include <botan/exceptn.h> + +namespace Botan { + +void SymmetricAlgorithm::verify_key_set(bool cond) const + { + if(cond == false) + throw Key_Not_Set(name()); + } + +void SymmetricAlgorithm::set_key(const uint8_t key[], size_t length) + { + if(!valid_keylength(length)) + throw Invalid_Key_Length(name(), length); + key_schedule(key, length); + } + +} diff --git a/src/lib/base/sym_algo.h b/src/lib/base/sym_algo.h index a0ebac626..2dff9c40d 100644 --- a/src/lib/base/sym_algo.h +++ b/src/lib/base/sym_algo.h @@ -9,7 +9,6 @@ #define BOTAN_SYMMETRIC_ALGORITHM_H_ #include <botan/key_spec.h> -#include <botan/exceptn.h> #include <botan/symkey.h> #include <botan/types.h> @@ -79,12 +78,7 @@ class BOTAN_PUBLIC_API(2,0) SymmetricAlgorithm * @param key the to be set as a byte array. * @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); - } + void set_key(const uint8_t key[], size_t length); /** * @return the algorithm name @@ -92,11 +86,7 @@ class BOTAN_PUBLIC_API(2,0) SymmetricAlgorithm virtual std::string name() const = 0; protected: - void verify_key_set(bool cond) const - { - if(cond == false) - throw Key_Not_Set(name()); - } + void verify_key_set(bool cond) const; private: /** diff --git a/src/lib/block/aes/aes.cpp b/src/lib/block/aes/aes.cpp index c35bdabaa..403945cc9 100644 --- a/src/lib/block/aes/aes.cpp +++ b/src/lib/block/aes/aes.cpp @@ -337,8 +337,7 @@ void aes_key_schedule(const uint8_t key[], size_t length, const size_t X = length / 4; // Can't happen, but make static analyzers happy - if(X != 4 && X != 6 && X != 8) - throw Invalid_Argument("Invalid AES key size"); + BOTAN_ARG_CHECK(X == 4 || X == 6 || X == 8, "Invalid AES key size"); for(size_t i = 0; i != X; ++i) XEK[i] = load_be<uint32_t>(key, i); diff --git a/src/lib/block/aria/aria.cpp b/src/lib/block/aria/aria.cpp index 4b99d2306..83383cce1 100644 --- a/src/lib/block/aria/aria.cpp +++ b/src/lib/block/aria/aria.cpp @@ -220,9 +220,6 @@ inline void ARIA_FE(uint32_t& T0, uint32_t& T1, uint32_t& T2, uint32_t& T3) void transform(const uint8_t in[], uint8_t out[], size_t blocks, const secure_vector<uint32_t>& KS) { - if(KS.empty()) - throw Invalid_State("ARIA key was not set"); - // Hit every cache line of S1 and S2 const size_t cache_line_size = CPUID::cache_line_size(); @@ -436,31 +433,37 @@ void key_schedule(secure_vector<uint32_t>& ERK, void ARIA_128::encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const { + verify_key_set(m_ERK.size() > 0); ARIA_F::transform(in, out, blocks, m_ERK); } void ARIA_192::encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const { + verify_key_set(m_ERK.size() > 0); ARIA_F::transform(in, out, blocks, m_ERK); } void ARIA_256::encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const { + verify_key_set(m_ERK.size() > 0); ARIA_F::transform(in, out, blocks, m_ERK); } void ARIA_128::decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const { + verify_key_set(m_DRK.size() > 0); ARIA_F::transform(in, out, blocks, m_DRK); } void ARIA_192::decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const { + verify_key_set(m_DRK.size() > 0); ARIA_F::transform(in, out, blocks, m_DRK); } void ARIA_256::decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const { + verify_key_set(m_DRK.size() > 0); ARIA_F::transform(in, out, blocks, m_DRK); } diff --git a/src/lib/block/block_cipher.cpp b/src/lib/block/block_cipher.cpp index 544cbbc36..3ace6cd4f 100644 --- a/src/lib/block/block_cipher.cpp +++ b/src/lib/block/block_cipher.cpp @@ -7,6 +7,7 @@ #include <botan/block_cipher.h> #include <botan/scan_name.h> +#include <botan/exceptn.h> #if defined(BOTAN_HAS_AES) #include <botan/aes.h> diff --git a/src/lib/block/blowfish/blowfish.cpp b/src/lib/block/blowfish/blowfish.cpp index 11a96cdb5..077a6fb81 100644 --- a/src/lib/block/blowfish/blowfish.cpp +++ b/src/lib/block/blowfish/blowfish.cpp @@ -350,12 +350,8 @@ void Blowfish::eks_key_schedule(const uint8_t key[], size_t length, * time being. * Bcrypt allows up to work factor 31 (2^31 iterations) */ - if(workfactor > 18) - throw Invalid_Argument("Requested Bcrypt work factor " + - std::to_string(workfactor) + " too large"); - - if(workfactor < 4) - throw Invalid_Argument("Bcrypt requires work factor at least 4"); + BOTAN_ARG_CHECK(workfactor >= 4 && workfactor <= 18, + "Invalid bcrypt work factor"); if(length > 72) { diff --git a/src/lib/block/gost_28147/gost_28147.cpp b/src/lib/block/gost_28147/gost_28147.cpp index b46d162de..45b23d55f 100644 --- a/src/lib/block/gost_28147/gost_28147.cpp +++ b/src/lib/block/gost_28147/gost_28147.cpp @@ -6,6 +6,7 @@ */ #include <botan/gost_28147.h> +#include <botan/exceptn.h> #include <botan/loadstor.h> namespace Botan { diff --git a/src/lib/block/lion/lion.cpp b/src/lib/block/lion/lion.cpp index cd7d25d9c..c9589a46a 100644 --- a/src/lib/block/lion/lion.cpp +++ b/src/lib/block/lion/lion.cpp @@ -6,6 +6,7 @@ */ #include <botan/lion.h> +#include <botan/exceptn.h> namespace Botan { diff --git a/src/lib/block/threefish_512/threefish_512.cpp b/src/lib/block/threefish_512/threefish_512.cpp index 0e6ba8889..7c368b409 100644 --- a/src/lib/block/threefish_512/threefish_512.cpp +++ b/src/lib/block/threefish_512/threefish_512.cpp @@ -239,8 +239,8 @@ void Threefish_512::decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) void Threefish_512::set_tweak(const uint8_t tweak[], size_t len) { - if(len != 16) - throw Exception("Threefish-512 requires 128 bit tweak"); + BOTAN_ARG_CHECK(len == 16, "Threefish-512 requires 128 bit tweak"); + m_T.resize(3); m_T[0] = load_le<uint64_t>(tweak, 0); m_T[1] = load_le<uint64_t>(tweak, 1); diff --git a/src/lib/hash/sha3/sha3.cpp b/src/lib/hash/sha3/sha3.cpp index cf45e6903..b69ef515a 100644 --- a/src/lib/hash/sha3/sha3.cpp +++ b/src/lib/hash/sha3/sha3.cpp @@ -146,7 +146,7 @@ void SHA_3::finish(size_t bitrate, secure_vector<uint64_t>& S, size_t S_pos, uint8_t init_pad, uint8_t fini_pad) { - BOTAN_ARG_CHECK(bitrate % 64 == 0); + BOTAN_ARG_CHECK(bitrate % 64 == 0, "SHA-3 bitrate must be multiple of 64"); S[S_pos / 8] ^= static_cast<uint64_t>(init_pad) << (8 * (S_pos % 8)); S[(bitrate / 64) - 1] ^= static_cast<uint64_t>(fini_pad) << 56; @@ -158,7 +158,7 @@ void SHA_3::expand(size_t bitrate, secure_vector<uint64_t>& S, uint8_t output[], size_t output_length) { - BOTAN_ARG_CHECK(bitrate % 64 == 0); + BOTAN_ARG_CHECK(bitrate % 64 == 0, "SHA-3 bitrate must be multiple of 64"); const size_t byterate = bitrate / 8; diff --git a/src/lib/kdf/hkdf/hkdf.cpp b/src/lib/kdf/hkdf/hkdf.cpp index 6ccd786c3..4b2ee1b3d 100644 --- a/src/lib/kdf/hkdf/hkdf.cpp +++ b/src/lib/kdf/hkdf/hkdf.cpp @@ -80,18 +80,13 @@ hkdf_expand_label(const std::string& hash_fn, const uint8_t hash_val[], size_t hash_val_len, size_t length) { - if(length > 0xFFFF) - throw Invalid_Argument("HKDF-Expand-Label requested output too large"); - if(label.size() > 0xFF) - throw Invalid_Argument("HKDF-Expand-Label label too long"); - if(hash_val_len > 0xFF) - throw Invalid_Argument("HKDF-Expand-Label hash too long"); + BOTAN_ARG_CHECK(length <= 0xFFFF, "HKDF-Expand-Label requested output too large"); + BOTAN_ARG_CHECK(label.size() <= 0xFF, "HKDF-Expand-Label label too long"); + BOTAN_ARG_CHECK(hash_val_len <= 0xFF, "HKDF-Expand-Label hash too long"); const uint16_t length16 = static_cast<uint16_t>(length); - auto mac = MessageAuthenticationCode::create("HMAC(" + hash_fn + ")"); - if(!mac) - throw Invalid_Argument("HKDF-Expand-Label with HMAC(" + hash_fn + ") not available"); + auto mac = MessageAuthenticationCode::create_or_throw("HMAC(" + hash_fn + ")"); HKDF_Expand hkdf(mac.release()); diff --git a/src/lib/kdf/prf_tls/prf_tls.cpp b/src/lib/kdf/prf_tls/prf_tls.cpp index d914df77e..4fde5ea58 100644 --- a/src/lib/kdf/prf_tls/prf_tls.cpp +++ b/src/lib/kdf/prf_tls/prf_tls.cpp @@ -6,6 +6,7 @@ */ #include <botan/prf_tls.h> +#include <botan/exceptn.h> namespace Botan { diff --git a/src/lib/kdf/sp800_108/sp800_108.cpp b/src/lib/kdf/sp800_108/sp800_108.cpp index 137ade106..990e10386 100644 --- a/src/lib/kdf/sp800_108/sp800_108.cpp +++ b/src/lib/kdf/sp800_108/sp800_108.cpp @@ -6,7 +6,7 @@ */ #include <botan/sp800_108.h> - +#include <botan/exceptn.h> #include <iterator> namespace Botan { diff --git a/src/lib/mac/cmac/cmac.cpp b/src/lib/mac/cmac/cmac.cpp index bd2a53a72..38752471d 100644 --- a/src/lib/mac/cmac/cmac.cpp +++ b/src/lib/mac/cmac/cmac.cpp @@ -6,6 +6,7 @@ */ #include <botan/cmac.h> +#include <botan/exceptn.h> #include <botan/internal/poly_dbl.h> namespace Botan { diff --git a/src/lib/mac/gmac/gmac.cpp b/src/lib/mac/gmac/gmac.cpp index a4e84f57b..27eccdde3 100644 --- a/src/lib/mac/gmac/gmac.cpp +++ b/src/lib/mac/gmac/gmac.cpp @@ -8,6 +8,7 @@ #include <botan/gmac.h> #include <botan/ghash.h> +#include <botan/exceptn.h> #include <botan/block_cipher.h> namespace Botan { diff --git a/src/lib/mac/hmac/hmac.cpp b/src/lib/mac/hmac/hmac.cpp index 532c98274..72c617c5b 100644 --- a/src/lib/mac/hmac/hmac.cpp +++ b/src/lib/mac/hmac/hmac.cpp @@ -100,8 +100,8 @@ MessageAuthenticationCode* HMAC::clone() const */ HMAC::HMAC(HashFunction* hash) : m_hash(hash) { - if(m_hash->hash_block_size() == 0) - throw Invalid_Argument("HMAC cannot be used with " + m_hash->name()); + BOTAN_ARG_CHECK(m_hash->hash_block_size() > 0, + "HMAC is not compatible with this hash function"); } } diff --git a/src/lib/mac/mac.cpp b/src/lib/mac/mac.cpp index 65107470b..4c3fc5230 100644 --- a/src/lib/mac/mac.cpp +++ b/src/lib/mac/mac.cpp @@ -6,6 +6,7 @@ */ #include <botan/mac.h> +#include <botan/exceptn.h> #include <botan/scan_name.h> #include <botan/mem_ops.h> @@ -147,6 +148,13 @@ MessageAuthenticationCode::create_or_throw(const std::string& algo, throw Lookup_Error("MAC", algo, provider); } +void MessageAuthenticationCode::start_msg(const uint8_t nonce[], size_t nonce_len) + { + BOTAN_UNUSED(nonce); + if(nonce_len > 0) + throw Invalid_IV_Length(name(), nonce_len); + } + /* * Default (deterministic) MAC verification operation */ diff --git a/src/lib/mac/mac.h b/src/lib/mac/mac.h index 1e358a4c5..de30b7dbb 100644 --- a/src/lib/mac/mac.h +++ b/src/lib/mac/mac.h @@ -64,12 +64,7 @@ class BOTAN_PUBLIC_API(2,0) MessageAuthenticationCode : public Buffered_Computat * Default implementation simply rejects all non-empty nonces * since most hash/MAC algorithms do not support randomization */ - virtual void start_msg(const uint8_t nonce[], size_t nonce_len) - { - BOTAN_UNUSED(nonce); - if(nonce_len > 0) - throw Invalid_IV_Length(name(), nonce_len); - } + virtual void start_msg(const uint8_t nonce[], size_t nonce_len); /** * Begin processing a message with a nonce diff --git a/src/lib/math/mp/mp_monty.cpp b/src/lib/math/mp/mp_monty.cpp index 5a28526ff..3231c610b 100644 --- a/src/lib/math/mp/mp_monty.cpp +++ b/src/lib/math/mp/mp_monty.cpp @@ -25,8 +25,7 @@ void bigint_monty_redc(word z[], { const size_t z_size = 2*(p_size+1); - if(ws_size < z_size) - throw Invalid_Argument("bigint_monty_redc workspace too small"); + BOTAN_ARG_CHECK(ws_size >= z_size, "workspace too small"); CT::poison(z, z_size); CT::poison(p, p_size); diff --git a/src/lib/misc/hotp/hotp.cpp b/src/lib/misc/hotp/hotp.cpp index f07c11c9f..e4dc6e5e3 100644 --- a/src/lib/misc/hotp/hotp.cpp +++ b/src/lib/misc/hotp/hotp.cpp @@ -6,19 +6,20 @@ */ #include <botan/hotp.h> +#include <botan/exceptn.h> namespace Botan { HOTP::HOTP(const SymmetricKey& key, const std::string& hash_algo, size_t digits) { + BOTAN_ARG_CHECK(digits == 6 || digits == 7 || digits == 8, "Invalid HOTP digits"); + if(digits == 6) m_digit_mod = 1000000; else if(digits == 7) m_digit_mod = 10000000; else if(digits == 8) m_digit_mod = 100000000; - else - throw Invalid_Argument("Invalid HOTP digits"); /* RFC 4228 only supports SHA-1 but TOTP allows SHA-256 and SHA-512 diff --git a/src/lib/misc/hotp/totp.cpp b/src/lib/misc/hotp/totp.cpp index c3203c32a..02bc42aa6 100644 --- a/src/lib/misc/hotp/totp.cpp +++ b/src/lib/misc/hotp/totp.cpp @@ -20,8 +20,7 @@ TOTP::TOTP(const SymmetricKey& key, const std::string& hash_algo, * Technically any time step except 0 is valid, but 30 is typical * and over 5 minutes seems unlikely. */ - if(m_time_step == 0 || m_time_step > 300) - throw Invalid_Argument("Invalid TOTP time step"); + BOTAN_ARG_CHECK(m_time_step > 0 && m_time_step < 300, "Invalid TOTP time step"); } uint32_t TOTP::generate_totp(std::chrono::system_clock::time_point current_time) diff --git a/src/lib/misc/rfc3394/rfc3394.cpp b/src/lib/misc/rfc3394/rfc3394.cpp index 8e69933c7..cb2480998 100644 --- a/src/lib/misc/rfc3394/rfc3394.cpp +++ b/src/lib/misc/rfc3394/rfc3394.cpp @@ -14,8 +14,8 @@ namespace Botan { secure_vector<uint8_t> rfc3394_keywrap(const secure_vector<uint8_t>& key, const SymmetricKey& kek) { - if(kek.size() != 16 && kek.size() != 24 && kek.size() != 32) - throw Invalid_Argument("Bad KEK length " + std::to_string(kek.size()) + " for NIST key wrap"); + BOTAN_ARG_CHECK(kek.size() == 16 || kek.size() == 24 || kek.size() == 32, + "Invalid KEK length for NIST key wrap"); const std::string cipher_name = "AES-" + std::to_string(8*kek.size()); std::unique_ptr<BlockCipher> aes(BlockCipher::create_or_throw(cipher_name)); @@ -28,11 +28,11 @@ secure_vector<uint8_t> rfc3394_keywrap(const secure_vector<uint8_t>& key, secure_vector<uint8_t> rfc3394_keyunwrap(const secure_vector<uint8_t>& key, const SymmetricKey& kek) { - if(key.size() < 16 || key.size() % 8 != 0) - throw Invalid_Argument("Bad input key size for NIST key unwrap"); + BOTAN_ARG_CHECK(kek.size() == 16 || kek.size() == 24 || kek.size() == 32, + "Invalid KEK length for NIST key wrap"); - if(kek.size() != 16 && kek.size() != 24 && kek.size() != 32) - throw Invalid_Argument("Bad KEK length " + std::to_string(kek.size()) + " for NIST key unwrap"); + BOTAN_ARG_CHECK(key.size() >= 16 && key.size() % 8 == 0, + "Bad input key size for NIST key unwrap"); const std::string cipher_name = "AES-" + std::to_string(8*kek.size()); std::unique_ptr<BlockCipher> aes(BlockCipher::create_or_throw(cipher_name)); diff --git a/src/lib/modes/aead/ccm/ccm.cpp b/src/lib/modes/aead/ccm/ccm.cpp index 6149718f0..410bd6910 100644 --- a/src/lib/modes/aead/ccm/ccm.cpp +++ b/src/lib/modes/aead/ccm/ccm.cpp @@ -88,7 +88,7 @@ void CCM_Mode::set_associated_data(const uint8_t ad[], size_t length) if(length) { // FIXME: support larger AD using length encoding rules - BOTAN_ASSERT(length < (0xFFFF - 0xFF), "Supported CCM AD length"); + BOTAN_ARG_CHECK(length < (0xFFFF - 0xFF), "Supported CCM AD length"); m_ad_buf.push_back(get_byte(0, static_cast<uint16_t>(length))); m_ad_buf.push_back(get_byte(1, static_cast<uint16_t>(length))); @@ -160,7 +160,7 @@ secure_vector<uint8_t> CCM_Mode::format_c0() void CCM_Encryption::finish(secure_vector<uint8_t>& buffer, size_t offset) { - BOTAN_ASSERT(buffer.size() >= offset, "Offset is sane"); + BOTAN_ARG_CHECK(buffer.size() >= offset, "Offset is sane"); buffer.insert(buffer.begin() + offset, msg_buf().begin(), msg_buf().end()); @@ -168,7 +168,7 @@ void CCM_Encryption::finish(secure_vector<uint8_t>& buffer, size_t offset) uint8_t* buf = buffer.data() + offset; const secure_vector<uint8_t>& ad = ad_buf(); - BOTAN_ASSERT(ad.size() % CCM_BS == 0, "AD is block size multiple"); + BOTAN_ARG_CHECK(ad.size() % CCM_BS == 0, "AD is block size multiple"); const BlockCipher& E = cipher(); @@ -211,7 +211,7 @@ void CCM_Encryption::finish(secure_vector<uint8_t>& buffer, size_t offset) void CCM_Decryption::finish(secure_vector<uint8_t>& buffer, size_t offset) { - BOTAN_ASSERT(buffer.size() >= offset, "Offset is sane"); + BOTAN_ARG_CHECK(buffer.size() >= offset, "Offset is sane"); buffer.insert(buffer.begin() + offset, msg_buf().begin(), msg_buf().end()); @@ -221,7 +221,7 @@ void CCM_Decryption::finish(secure_vector<uint8_t>& buffer, size_t offset) BOTAN_ASSERT(sz >= tag_size(), "We have the tag"); const secure_vector<uint8_t>& ad = ad_buf(); - BOTAN_ASSERT(ad.size() % CCM_BS == 0, "AD is block size multiple"); + BOTAN_ARG_CHECK(ad.size() % CCM_BS == 0, "AD is block size multiple"); const BlockCipher& E = cipher(); diff --git a/src/lib/modes/aead/gcm/gcm.cpp b/src/lib/modes/aead/gcm/gcm.cpp index b0240eb7f..2bdae3a6f 100644 --- a/src/lib/modes/aead/gcm/gcm.cpp +++ b/src/lib/modes/aead/gcm/gcm.cpp @@ -110,7 +110,7 @@ void GCM_Mode::start_msg(const uint8_t nonce[], size_t nonce_len) size_t GCM_Encryption::process(uint8_t buf[], size_t sz) { - BOTAN_ARG_CHECK(sz % update_granularity() == 0); + BOTAN_ARG_CHECK(sz % update_granularity() == 0, "Invalid buffer size"); m_ctr->cipher(buf, buf, sz); m_ghash->update(buf, sz); return sz; @@ -118,7 +118,7 @@ size_t GCM_Encryption::process(uint8_t buf[], size_t sz) void GCM_Encryption::finish(secure_vector<uint8_t>& buffer, size_t offset) { - BOTAN_ARG_CHECK(offset <= buffer.size()); + BOTAN_ARG_CHECK(offset <= buffer.size(), "Invalid offset"); const size_t sz = buffer.size() - offset; uint8_t* buf = buffer.data() + offset; @@ -130,7 +130,7 @@ void GCM_Encryption::finish(secure_vector<uint8_t>& buffer, size_t offset) size_t GCM_Decryption::process(uint8_t buf[], size_t sz) { - BOTAN_ARG_CHECK(sz % update_granularity() == 0); + BOTAN_ARG_CHECK(sz % update_granularity() == 0, "Invalid buffer size"); m_ghash->update(buf, sz); m_ctr->cipher(buf, buf, sz); return sz; @@ -138,7 +138,7 @@ size_t GCM_Decryption::process(uint8_t buf[], size_t sz) void GCM_Decryption::finish(secure_vector<uint8_t>& buffer, size_t offset) { - BOTAN_ARG_CHECK(offset <= buffer.size()); + BOTAN_ARG_CHECK(offset <= buffer.size(), "Invalid offset"); const size_t sz = buffer.size() - offset; uint8_t* buf = buffer.data() + offset; diff --git a/src/lib/modes/aead/ocb/ocb.cpp b/src/lib/modes/aead/ocb/ocb.cpp index 23af75e8f..317b417b3 100644 --- a/src/lib/modes/aead/ocb/ocb.cpp +++ b/src/lib/modes/aead/ocb/ocb.cpp @@ -171,11 +171,13 @@ OCB_Mode::OCB_Mode(BlockCipher* cipher, size_t tag_size) : * sizes but only 128, 192, 256 and 512 bit are currently supported * by this implementation. */ - if(BS != 16 && BS != 24 && BS != 32 && BS != 64) - throw Invalid_Argument("OCB does not support cipher " + m_cipher->name()); + BOTAN_ARG_CHECK(BS == 16 || BS == 24 || BS == 32 || BS == 64, + "Invalid block size for OCB"); - if(m_tag_size % 4 != 0 || m_tag_size < 8 || m_tag_size > BS || m_tag_size > 32) - throw Invalid_Argument("Invalid OCB tag length"); + BOTAN_ARG_CHECK(m_tag_size % 4 == 0 && + m_tag_size >= 8 && m_tag_size <= BS && + m_tag_size <= 32, + "Invalid OCB tag length"); } OCB_Mode::~OCB_Mode() { /* for unique_ptr destructor */ } diff --git a/src/lib/pbkdf/pbkdf.cpp b/src/lib/pbkdf/pbkdf.cpp index d2dfc3d41..73b482725 100644 --- a/src/lib/pbkdf/pbkdf.cpp +++ b/src/lib/pbkdf/pbkdf.cpp @@ -6,6 +6,7 @@ */ #include <botan/pbkdf.h> +#include <botan/exceptn.h> #include <botan/scan_name.h> #if defined(BOTAN_HAS_PBKDF1) diff --git a/src/lib/pbkdf/pbkdf.h b/src/lib/pbkdf/pbkdf.h index 181195dad..7d3bceffc 100644 --- a/src/lib/pbkdf/pbkdf.h +++ b/src/lib/pbkdf/pbkdf.h @@ -9,7 +9,6 @@ #define BOTAN_PBKDF_H_ #include <botan/symkey.h> -#include <botan/exceptn.h> #include <chrono> namespace Botan { @@ -230,10 +229,7 @@ typedef PBKDF S2K; inline PBKDF* get_pbkdf(const std::string& algo_spec, const std::string& provider = "") { - std::unique_ptr<PBKDF> p(PBKDF::create(algo_spec, provider)); - if(p) - return p.release(); - throw Algorithm_Not_Found(algo_spec); + return PBKDF::create_or_throw(algo_spec, provider).release(); } inline PBKDF* get_s2k(const std::string& algo_spec) diff --git a/src/lib/pbkdf/pbkdf2/pbkdf2.cpp b/src/lib/pbkdf/pbkdf2/pbkdf2.cpp index d4388bd10..cc2982f6e 100644 --- a/src/lib/pbkdf/pbkdf2/pbkdf2.cpp +++ b/src/lib/pbkdf/pbkdf2/pbkdf2.cpp @@ -6,6 +6,7 @@ */ #include <botan/pbkdf2.h> +#include <botan/exceptn.h> #include <botan/internal/rounding.h> namespace Botan { diff --git a/src/lib/pbkdf/pgp_s2k/pgp_s2k.cpp b/src/lib/pbkdf/pgp_s2k/pgp_s2k.cpp index 14f21eae2..df659de3c 100644 --- a/src/lib/pbkdf/pgp_s2k/pgp_s2k.cpp +++ b/src/lib/pbkdf/pgp_s2k/pgp_s2k.cpp @@ -6,6 +6,7 @@ */ #include <botan/pgp_s2k.h> +#include <botan/exceptn.h> namespace Botan { diff --git a/src/lib/psk_db/psk_db.cpp b/src/lib/psk_db/psk_db.cpp index af59d2954..4851f6bd2 100644 --- a/src/lib/psk_db/psk_db.cpp +++ b/src/lib/psk_db/psk_db.cpp @@ -5,6 +5,7 @@ */ #include <botan/psk_db.h> +#include <botan/exceptn.h> #include <botan/nist_keywrap.h> #include <botan/base64.h> #include <botan/mac.h> diff --git a/src/lib/pubkey/ec_group/point_gfp.h b/src/lib/pubkey/ec_group/point_gfp.h index cce2adcc6..39188ba21 100644 --- a/src/lib/pubkey/ec_group/point_gfp.h +++ b/src/lib/pubkey/ec_group/point_gfp.h @@ -11,6 +11,7 @@ #define BOTAN_POINT_GFP_H_ #include <botan/curve_gfp.h> +#include <botan/exceptn.h> #include <vector> namespace Botan { diff --git a/src/lib/stream/chacha/chacha.cpp b/src/lib/stream/chacha/chacha.cpp index 0f1e082cf..acf79cbd9 100644 --- a/src/lib/stream/chacha/chacha.cpp +++ b/src/lib/stream/chacha/chacha.cpp @@ -6,6 +6,7 @@ */ #include <botan/chacha.h> +#include <botan/exceptn.h> #include <botan/loadstor.h> #include <botan/cpuid.h> @@ -13,8 +14,8 @@ namespace Botan { ChaCha::ChaCha(size_t rounds) : m_rounds(rounds) { - if(m_rounds != 8 && m_rounds != 12 && m_rounds != 20) - throw Invalid_Argument("ChaCha only supports 8, 12 or 20 rounds"); + BOTAN_ARG_CHECK(m_rounds == 8 || m_rounds == 12 || m_rounds == 20, + "ChaCha only supports 8, 12 or 20 rounds"); } std::string ChaCha::provider() const diff --git a/src/lib/stream/ctr/ctr.cpp b/src/lib/stream/ctr/ctr.cpp index c63bdebdc..261646344 100644 --- a/src/lib/stream/ctr/ctr.cpp +++ b/src/lib/stream/ctr/ctr.cpp @@ -6,6 +6,7 @@ */ #include <botan/ctr.h> +#include <botan/exceptn.h> #include <botan/loadstor.h> namespace Botan { @@ -30,8 +31,8 @@ CTR_BE::CTR_BE(BlockCipher* cipher, size_t ctr_size) : m_pad(m_counter.size()), m_pad_pos(0) { - if(m_ctr_size < 4 || m_ctr_size > m_block_size) - throw Invalid_Argument("Invalid CTR-BE counter size"); + BOTAN_ARG_CHECK(m_ctr_size >= 4 && m_ctr_size <= m_block_size, + "Invalid CTR-BE counter size"); } void CTR_BE::clear() diff --git a/src/lib/stream/ofb/ofb.cpp b/src/lib/stream/ofb/ofb.cpp index 75b7048aa..ca3971dc2 100644 --- a/src/lib/stream/ofb/ofb.cpp +++ b/src/lib/stream/ofb/ofb.cpp @@ -6,6 +6,7 @@ */ #include <botan/ofb.h> +#include <botan/exceptn.h> namespace Botan { diff --git a/src/lib/stream/salsa20/salsa20.cpp b/src/lib/stream/salsa20/salsa20.cpp index ce22adcb7..46499e69e 100644 --- a/src/lib/stream/salsa20/salsa20.cpp +++ b/src/lib/stream/salsa20/salsa20.cpp @@ -6,6 +6,7 @@ */ #include <botan/salsa20.h> +#include <botan/exceptn.h> #include <botan/loadstor.h> namespace Botan { diff --git a/src/lib/stream/shake_cipher/shake_cipher.cpp b/src/lib/stream/shake_cipher/shake_cipher.cpp index 72a8fd885..f6cac8354 100644 --- a/src/lib/stream/shake_cipher/shake_cipher.cpp +++ b/src/lib/stream/shake_cipher/shake_cipher.cpp @@ -6,6 +6,7 @@ */ #include <botan/shake_cipher.h> +#include <botan/exceptn.h> #include <botan/sha3.h> #include <botan/loadstor.h> diff --git a/src/lib/stream/stream_cipher.cpp b/src/lib/stream/stream_cipher.cpp index 77e68d129..692464723 100644 --- a/src/lib/stream/stream_cipher.cpp +++ b/src/lib/stream/stream_cipher.cpp @@ -7,6 +7,7 @@ #include <botan/stream_cipher.h> #include <botan/scan_name.h> +#include <botan/exceptn.h> #if defined(BOTAN_HAS_CHACHA) #include <botan/chacha.h> diff --git a/src/lib/tls/tls_ciphersuite.cpp b/src/lib/tls/tls_ciphersuite.cpp index d1a509d78..b8a7e70d7 100644 --- a/src/lib/tls/tls_ciphersuite.cpp +++ b/src/lib/tls/tls_ciphersuite.cpp @@ -6,6 +6,7 @@ */ #include <botan/tls_ciphersuite.h> +#include <botan/exceptn.h> #include <botan/parsing.h> #include <botan/block_cipher.h> #include <botan/stream_cipher.h> diff --git a/src/lib/utils/assert.cpp b/src/lib/utils/assert.cpp index d729a8368..cd957e00d 100644 --- a/src/lib/utils/assert.cpp +++ b/src/lib/utils/assert.cpp @@ -1,6 +1,6 @@ /* * Runtime assertion checking -* (C) 2010,2012 Jack Lloyd +* (C) 2010,2012,2018 Jack Lloyd * * Botan is released under the Simplified BSD License (see license.txt) */ @@ -10,6 +10,17 @@ namespace Botan { +void throw_invalid_argument(const char* message, + const char* func, + const char* file) + { + std::ostringstream format; + + format << message << " in " << func << ":" << file; + + throw Invalid_Argument(format.str()); + } + void assertion_failure(const char* expr_str, const char* assertion_made, const char* func, diff --git a/src/lib/utils/assert.h b/src/lib/utils/assert.h index d23558cd0..a12872f2b 100644 --- a/src/lib/utils/assert.h +++ b/src/lib/utils/assert.h @@ -16,6 +16,7 @@ namespace Botan { /** * Called when an assertion fails +* Throws an Exception object */ BOTAN_NORETURN void BOTAN_PUBLIC_API(2,0) assertion_failure(const char* expr_str, @@ -25,6 +26,18 @@ BOTAN_NORETURN void BOTAN_PUBLIC_API(2,0) int line); /** +* Called when an invalid argument is used +* Throws Invalid_Argument +*/ +BOTAN_NORETURN void BOTAN_UNSTABLE_API throw_invalid_argument(const char* message, + const char* func, + const char* file); + + +#define BOTAN_ARG_CHECK(expr, msg) \ + do { if(!(expr)) Botan::throw_invalid_argument(msg, BOTAN_CURRENT_FUNCTION, __FILE__); } while(0) + +/** * Make an assertion */ #define BOTAN_ASSERT(expr, assertion_made) \ diff --git a/src/lib/utils/donna128.h b/src/lib/utils/donna128.h index 90ced395d..ff571906d 100644 --- a/src/lib/utils/donna128.h +++ b/src/lib/utils/donna128.h @@ -82,7 +82,7 @@ class donna128 final inline donna128 operator*(const donna128& x, uint64_t y) { - BOTAN_ASSERT(x.hi() == 0, "High 64 bits of donna128 set to zero during multiply"); + BOTAN_ARG_CHECK(x.hi() == 0, "High 64 bits of donna128 set to zero during multiply"); uint64_t lo = 0, hi = 0; mul64x64_128(x.lo(), y, &lo, &hi); diff --git a/src/lib/utils/exceptn.h b/src/lib/utils/exceptn.h index 2d242339d..f2896aa83 100644 --- a/src/lib/utils/exceptn.h +++ b/src/lib/utils/exceptn.h @@ -38,9 +38,6 @@ class BOTAN_PUBLIC_API(2,0) Invalid_Argument : public Exception explicit Invalid_Argument(const std::string& msg, const std::string& where); }; -#define BOTAN_ARG_CHECK(expr) \ - do { if(!(expr)) throw Invalid_Argument(#expr, BOTAN_CURRENT_FUNCTION); } while(0) - /** * Unsupported_Argument Exception * diff --git a/src/lib/utils/rounding.h b/src/lib/utils/rounding.h index a06626b88..a03e3a4ee 100644 --- a/src/lib/utils/rounding.h +++ b/src/lib/utils/rounding.h @@ -20,7 +20,7 @@ namespace Botan { */ inline size_t round_up(size_t n, size_t align_to) { - BOTAN_ASSERT(align_to != 0, "align_to must not be 0"); + BOTAN_ARG_CHECK(align_to != 0, "align_to must not be 0"); if(n % align_to) n += align_to - (n % align_to); |