aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJack Lloyd <[email protected]>2019-01-18 11:37:01 -0500
committerJack Lloyd <[email protected]>2019-01-18 11:37:01 -0500
commitb835fdf8fd3910a79ab408660757d9736f82d14d (patch)
treefbbd8e89d9cf910bc3a9e9ecbfce5ce290b7c8d9
parent9ca22335edcb9800158f4691de20fa5d0f9cc849 (diff)
Rename Integrity_Failure to Invalid_Authentication_Tag
This makes the meaning and usage more clear. Add a specific error type so invalid tags can be distinguished without having to catch that specific type. See also #1813
-rw-r--r--doc/manual/cipher_modes.rst17
-rw-r--r--doc/manual/keywrap.rst4
-rw-r--r--src/lib/ffi/ffi.cpp3
-rw-r--r--src/lib/ffi/ffi_cipher.cpp2
-rw-r--r--src/lib/misc/nist_keywrap/nist_keywrap.cpp8
-rw-r--r--src/lib/modes/aead/ccm/ccm.cpp2
-rw-r--r--src/lib/modes/aead/chacha20poly1305/chacha20poly1305.cpp2
-rw-r--r--src/lib/modes/aead/eax/eax.cpp2
-rw-r--r--src/lib/modes/aead/gcm/gcm.cpp2
-rw-r--r--src/lib/modes/aead/ocb/ocb.cpp2
-rw-r--r--src/lib/modes/aead/siv/siv.cpp2
-rw-r--r--src/lib/psk_db/psk_db.cpp2
-rw-r--r--src/lib/pubkey/dlies/dlies.cpp2
-rw-r--r--src/lib/pubkey/ecies/ecies.cpp2
-rw-r--r--src/lib/pubkey/mceies/mceies.cpp2
-rw-r--r--src/lib/pubkey/xmss/xmss_privatekey.cpp5
-rw-r--r--src/lib/pubkey/xmss/xmss_privatekey.h6
-rw-r--r--src/lib/pubkey/xmss/xmss_publickey.cpp4
-rw-r--r--src/lib/pubkey/xmss/xmss_signature.cpp4
-rw-r--r--src/lib/pubkey/xmss/xmss_verification_operation.cpp2
-rw-r--r--src/lib/tls/tls_channel.cpp2
-rw-r--r--src/lib/utils/exceptn.cpp4
-rw-r--r--src/lib/utils/exceptn.h23
23 files changed, 65 insertions, 39 deletions
diff --git a/doc/manual/cipher_modes.rst b/doc/manual/cipher_modes.rst
index cc04a3750..6e78a2c1b 100644
--- a/doc/manual/cipher_modes.rst
+++ b/doc/manual/cipher_modes.rst
@@ -269,10 +269,19 @@ will be returned by :cpp:func:`get_cipher` if the named cipher is an AEAD mode).
ever calling update is both efficient and convenient.
.. note::
- During decryption, finish will throw an instance of Integrity_Failure
- if the MAC does not validate. If this occurs, all plaintext previously
- output via calls to update must be destroyed and not used in any
- way that an attacker could observe the effects of.
+
+ During decryption, if the supplied authentication tag does not
+ validate, finish will throw an instance of Invalid_Authentication_Tag
+ (aka Integrity_Failure, which was the name for this exception in
+ versions before 2.10, a typedef is included for compatability).
+
+ If this occurs, all plaintext previously output via calls to update
+ must be destroyed and not used in any way that an attacker could
+ observe the effects of. This could be anything from echoing the
+ plaintext back (perhaps in an error message), or by making an external
+ RPC whose destination or contents depend on the plaintext. The only
+ thing you can do is buffer it, and in the event of an invalid tag,
+ erase the previously decrypted content from memory.
One simply way to assure this could never happen is to never
call update, and instead always marshal the entire message
diff --git a/doc/manual/keywrap.rst b/doc/manual/keywrap.rst
index 3116797e5..5c3aac0a3 100644
--- a/doc/manual/keywrap.rst
+++ b/doc/manual/keywrap.rst
@@ -23,7 +23,7 @@ functions with AES, but any 128-bit cipher will do and some other implementation
.. cpp:function:: secure_vector<uint8_t> nist_key_unwrap(const uint8_t input[], \
size_t input_len, const BlockCipher& bc)
- This unwraps the result of nist_key_wrap, or throw Integrity_Failure on error.
+ This unwraps the result of nist_key_wrap, or throw Invalid_Authentication_Tag on error.
.. cpp:function:: std::vector<uint8_t> nist_key_wrap_padded(const uint8_t input[], \
size_t input_len, const BlockCipher& bc)
@@ -33,7 +33,7 @@ functions with AES, but any 128-bit cipher will do and some other implementation
.. cpp:function:: secure_vector<uint8_t> nist_key_unwrap_padded(const uint8_t input[], \
size_t input_len, const BlockCipher& bc)
- This unwraps the result of nist_key_wrap_padded, or throws Integrity_Failure
+ This unwraps the result of nist_key_wrap_padded, or throws Invalid_Authentication_Tag
on error.
RFC 3394 Interface
diff --git a/src/lib/ffi/ffi.cpp b/src/lib/ffi/ffi.cpp
index b0c1f6e71..4fe1d8c71 100644
--- a/src/lib/ffi/ffi.cpp
+++ b/src/lib/ffi/ffi.cpp
@@ -62,6 +62,9 @@ int ffi_map_error_type(Botan::ErrorType err)
case Botan::ErrorType::DecodingFailure:
return BOTAN_FFI_ERROR_INVALID_INPUT;
+ case Botan::ErrorType::InvalidTag:
+ return BOTAN_FFI_ERROR_BAD_MAC;
+
case Botan::ErrorType::InvalidKeyLength:
return BOTAN_FFI_ERROR_INVALID_KEY_LENGTH;
case Botan::ErrorType::LookupError:
diff --git a/src/lib/ffi/ffi_cipher.cpp b/src/lib/ffi/ffi_cipher.cpp
index dc340ea61..3c74a524f 100644
--- a/src/lib/ffi/ffi_cipher.cpp
+++ b/src/lib/ffi/ffi_cipher.cpp
@@ -128,7 +128,7 @@ int botan_cipher_update(botan_cipher_t cipher_obj,
{
cipher.finish(mbuf);
}
- catch(Integrity_Failure&)
+ catch(Invalid_Authentication_Tag&)
{
return BOTAN_FFI_ERROR_BAD_MAC;
}
diff --git a/src/lib/misc/nist_keywrap/nist_keywrap.cpp b/src/lib/misc/nist_keywrap/nist_keywrap.cpp
index 3c673696d..671d31ea4 100644
--- a/src/lib/misc/nist_keywrap/nist_keywrap.cpp
+++ b/src/lib/misc/nist_keywrap/nist_keywrap.cpp
@@ -125,7 +125,7 @@ nist_key_unwrap(const uint8_t input[],
secure_vector<uint8_t> R = raw_nist_key_unwrap(input, input_len, bc, ICV_out);
if(ICV_out != 0xA6A6A6A6A6A6A6A6)
- throw Integrity_Failure("NIST key unwrap failed");
+ throw Invalid_Authentication_Tag("NIST key unwrap failed");
return R;
}
@@ -186,19 +186,19 @@ nist_key_unwrap_padded(const uint8_t input[],
}
if((ICV_out >> 32) != 0xA65959A6)
- throw Integrity_Failure("NIST key unwrap failed");
+ throw Invalid_Authentication_Tag("NIST key unwrap failed");
const size_t len = (ICV_out & 0xFFFFFFFF);
if(R.size() < 8 || len > R.size() || len < R.size() - 8)
- throw Integrity_Failure("NIST key unwrap failed");
+ throw Invalid_Authentication_Tag("NIST key unwrap failed");
const size_t padding = R.size() - len;
for(size_t i = 0; i != padding; ++i)
{
if(R[R.size() - i - 1] != 0)
- throw Integrity_Failure("NIST key unwrap failed");
+ throw Invalid_Authentication_Tag("NIST key unwrap failed");
}
R.resize(R.size() - padding);
diff --git a/src/lib/modes/aead/ccm/ccm.cpp b/src/lib/modes/aead/ccm/ccm.cpp
index f630dc39a..effe3a1ff 100644
--- a/src/lib/modes/aead/ccm/ccm.cpp
+++ b/src/lib/modes/aead/ccm/ccm.cpp
@@ -263,7 +263,7 @@ void CCM_Decryption::finish(secure_vector<uint8_t>& buffer, size_t offset)
T ^= S0;
if(!constant_time_compare(T.data(), buf_end, tag_size()))
- throw Integrity_Failure("CCM tag check failed");
+ throw Invalid_Authentication_Tag("CCM tag check failed");
buffer.resize(buffer.size() - tag_size());
}
diff --git a/src/lib/modes/aead/chacha20poly1305/chacha20poly1305.cpp b/src/lib/modes/aead/chacha20poly1305/chacha20poly1305.cpp
index 8e424ce49..ca0c55184 100644
--- a/src/lib/modes/aead/chacha20poly1305/chacha20poly1305.cpp
+++ b/src/lib/modes/aead/chacha20poly1305/chacha20poly1305.cpp
@@ -160,7 +160,7 @@ void ChaCha20Poly1305_Decryption::finish(secure_vector<uint8_t>& buffer, size_t
m_nonce_len = 0;
if(!constant_time_compare(mac.data(), included_tag, tag_size()))
- throw Integrity_Failure("ChaCha20Poly1305 tag check failed");
+ throw Invalid_Authentication_Tag("ChaCha20Poly1305 tag check failed");
buffer.resize(offset + remaining);
}
diff --git a/src/lib/modes/aead/eax/eax.cpp b/src/lib/modes/aead/eax/eax.cpp
index 00253e405..1a31c3cff 100644
--- a/src/lib/modes/aead/eax/eax.cpp
+++ b/src/lib/modes/aead/eax/eax.cpp
@@ -184,7 +184,7 @@ void EAX_Decryption::finish(secure_vector<uint8_t>& buffer, size_t offset)
mac ^= m_ad_mac;
if(!constant_time_compare(mac.data(), included_tag, tag_size()))
- throw Integrity_Failure("EAX tag check failed");
+ throw Invalid_Authentication_Tag("EAX tag check failed");
buffer.resize(offset + remaining);
diff --git a/src/lib/modes/aead/gcm/gcm.cpp b/src/lib/modes/aead/gcm/gcm.cpp
index 75768d851..d299af35f 100644
--- a/src/lib/modes/aead/gcm/gcm.cpp
+++ b/src/lib/modes/aead/gcm/gcm.cpp
@@ -166,7 +166,7 @@ void GCM_Decryption::finish(secure_vector<uint8_t>& buffer, size_t offset)
const uint8_t* included_tag = &buffer[remaining+offset];
if(!constant_time_compare(mac.data(), included_tag, tag_size()))
- throw Integrity_Failure("GCM tag check failed");
+ throw Invalid_Authentication_Tag("GCM tag check failed");
buffer.resize(offset + remaining);
}
diff --git a/src/lib/modes/aead/ocb/ocb.cpp b/src/lib/modes/aead/ocb/ocb.cpp
index b25abbe6a..87361ef11 100644
--- a/src/lib/modes/aead/ocb/ocb.cpp
+++ b/src/lib/modes/aead/ocb/ocb.cpp
@@ -523,7 +523,7 @@ void OCB_Decryption::finish(secure_vector<uint8_t>& buffer, size_t offset)
const uint8_t* included_tag = &buf[remaining];
if(!constant_time_compare(mac.data(), included_tag, tag_size()))
- throw Integrity_Failure("OCB tag check failed");
+ throw Invalid_Authentication_Tag("OCB tag check failed");
// remove tag from end of message
buffer.resize(remaining + offset);
diff --git a/src/lib/modes/aead/siv/siv.cpp b/src/lib/modes/aead/siv/siv.cpp
index 3a960e0af..75bdb91c4 100644
--- a/src/lib/modes/aead/siv/siv.cpp
+++ b/src/lib/modes/aead/siv/siv.cpp
@@ -198,7 +198,7 @@ void SIV_Decryption::finish(secure_vector<uint8_t>& buffer, size_t offset)
const secure_vector<uint8_t> T = S2V(buffer.data() + offset, buffer.size() - offset - V.size());
if(!constant_time_compare(T.data(), V.data(), T.size()))
- throw Integrity_Failure("SIV tag check failed");
+ throw Invalid_Authentication_Tag("SIV tag check failed");
buffer.resize(buffer.size() - tag_size());
}
diff --git a/src/lib/psk_db/psk_db.cpp b/src/lib/psk_db/psk_db.cpp
index 4851f6bd2..59fa76893 100644
--- a/src/lib/psk_db/psk_db.cpp
+++ b/src/lib/psk_db/psk_db.cpp
@@ -45,7 +45,7 @@ std::set<std::string> Encrypted_PSK_Database::list_names() const
std::string pt_name(cast_uint8_ptr_to_char(name_bits.data()), name_bits.size());
names.insert(pt_name);
}
- catch(Integrity_Failure&)
+ catch(Invalid_Authentication_Tag&)
{
}
}
diff --git a/src/lib/pubkey/dlies/dlies.cpp b/src/lib/pubkey/dlies/dlies.cpp
index aa214fd8b..d24542d0e 100644
--- a/src/lib/pubkey/dlies/dlies.cpp
+++ b/src/lib/pubkey/dlies/dlies.cpp
@@ -192,7 +192,7 @@ secure_vector<uint8_t> DLIES_Decryptor::do_decrypt(uint8_t& valid_mask,
try
{
// the decryption can fail:
- // e.g. Integrity_Failure is thrown if GCM is used and the message does not have a valid tag
+ // e.g. Invalid_Authentication_Tag is thrown if GCM is used and the message does not have a valid tag
if(m_iv.size())
{
diff --git a/src/lib/pubkey/ecies/ecies.cpp b/src/lib/pubkey/ecies/ecies.cpp
index 54055de7a..fb12eaa49 100644
--- a/src/lib/pubkey/ecies/ecies.cpp
+++ b/src/lib/pubkey/ecies/ecies.cpp
@@ -399,7 +399,7 @@ secure_vector<uint8_t> ECIES_Decryptor::do_decrypt(uint8_t& valid_mask, const ui
try
{
// the decryption can fail:
- // e.g. Integrity_Failure is thrown if GCM is used and the message does not have a valid tag
+ // e.g. Invalid_Authentication_Tag is thrown if GCM is used and the message does not have a valid tag
secure_vector<uint8_t> decrypted_data(encrypted_data.begin(), encrypted_data.end());
m_cipher->finish(decrypted_data);
return decrypted_data;
diff --git a/src/lib/pubkey/mceies/mceies.cpp b/src/lib/pubkey/mceies/mceies.cpp
index 3f8562e17..4d62889fe 100644
--- a/src/lib/pubkey/mceies/mceies.cpp
+++ b/src/lib/pubkey/mceies/mceies.cpp
@@ -97,7 +97,7 @@ mceies_decrypt(const McEliece_PrivateKey& privkey,
aead->finish(pt, 0);
return pt;
}
- catch(Integrity_Failure&)
+ catch(Invalid_Authentication_Tag&)
{
throw;
}
diff --git a/src/lib/pubkey/xmss/xmss_privatekey.cpp b/src/lib/pubkey/xmss/xmss_privatekey.cpp
index 05d61981e..9ef2b5c9c 100644
--- a/src/lib/pubkey/xmss/xmss_privatekey.cpp
+++ b/src/lib/pubkey/xmss/xmss_privatekey.cpp
@@ -37,7 +37,7 @@ XMSS_PrivateKey::XMSS_PrivateKey(const secure_vector<uint8_t>& raw_key)
if(raw_key.size() != size())
{
- throw Integrity_Failure("Invalid XMSS private key size detected.");
+ throw Decoding_Error("Invalid XMSS private key size detected.");
}
// extract & copy unused leaf index from raw_key.
@@ -52,8 +52,7 @@ XMSS_PrivateKey::XMSS_PrivateKey(const secure_vector<uint8_t>& raw_key)
if(unused_leaf >= (1ull << XMSS_PublicKey::m_xmss_params.tree_height()))
{
- throw Integrity_Failure("XMSS private key leaf index out of "
- "bounds.");
+ throw Decoding_Error("XMSS private key leaf index out of bounds");
}
begin = end;
diff --git a/src/lib/pubkey/xmss/xmss_privatekey.h b/src/lib/pubkey/xmss/xmss_privatekey.h
index d66933724..e3b41617c 100644
--- a/src/lib/pubkey/xmss/xmss_privatekey.h
+++ b/src/lib/pubkey/xmss/xmss_privatekey.h
@@ -115,8 +115,7 @@ class BOTAN_PUBLIC_API(2,0) XMSS_PrivateKey final : public virtual XMSS_PublicKe
{
if(idx >= (1ull << XMSS_PublicKey::m_xmss_params.tree_height()))
{
- throw Integrity_Failure("XMSS private key leaf index out of "
- "bounds.");
+ throw Decoding_Error("XMSS private key leaf index out of bounds");
}
else
{
@@ -140,8 +139,7 @@ class BOTAN_PUBLIC_API(2,0) XMSS_PrivateKey final : public virtual XMSS_PublicKe
*recover_global_leaf_index())).fetch_add(1);
if(idx >= (1ull << XMSS_PublicKey::m_xmss_params.tree_height()))
{
- throw Integrity_Failure("XMSS private key, one time signatures "
- "exhausted.");
+ throw Decoding_Error("XMSS private key, one time signatures exhaused");
}
return idx;
}
diff --git a/src/lib/pubkey/xmss/xmss_publickey.cpp b/src/lib/pubkey/xmss/xmss_publickey.cpp
index 425c657ca..42fbdb851 100644
--- a/src/lib/pubkey/xmss/xmss_publickey.cpp
+++ b/src/lib/pubkey/xmss/xmss_publickey.cpp
@@ -26,7 +26,7 @@ XMSS_PublicKey::XMSS_PublicKey(const std::vector<uint8_t>& raw_key)
{
if(raw_key.size() < size())
{
- throw Integrity_Failure("Invalid XMSS public key size detected.");
+ throw Decoding_Error("Invalid XMSS public key size detected.");
}
// extract & copy root from raw key.
@@ -49,7 +49,7 @@ XMSS_PublicKey::deserialize_xmss_oid(const std::vector<uint8_t>& raw_key)
{
if(raw_key.size() < 4)
{
- throw Integrity_Failure("XMSS signature OID missing.");
+ throw Decoding_Error("XMSS signature OID missing.");
}
// extract and convert algorithm id to enum type
diff --git a/src/lib/pubkey/xmss/xmss_signature.cpp b/src/lib/pubkey/xmss/xmss_signature.cpp
index f2d1ba4f1..2ba8a1965 100644
--- a/src/lib/pubkey/xmss/xmss_signature.cpp
+++ b/src/lib/pubkey/xmss/xmss_signature.cpp
@@ -19,7 +19,7 @@ XMSS_Signature::XMSS_Signature(XMSS_Parameters::xmss_algorithm_t oid,
if(raw_sig.size() != (xmss_params.len() + xmss_params.tree_height() + 1)
* xmss_params.element_size() + sizeof(m_leaf_idx))
{
- throw Integrity_Failure("XMSS signature size invalid.");
+ throw Decoding_Error("XMSS signature size invalid.");
}
for(size_t i = 0; i < 8; i++)
@@ -27,7 +27,7 @@ XMSS_Signature::XMSS_Signature(XMSS_Parameters::xmss_algorithm_t oid,
if(m_leaf_idx >= (1ull << xmss_params.tree_height()))
{
- throw Integrity_Failure("XMSS signature leaf index out of bounds.");
+ throw Decoding_Error("XMSS signature leaf index out of bounds.");
}
auto begin = raw_sig.begin() + sizeof(m_leaf_idx);
diff --git a/src/lib/pubkey/xmss/xmss_verification_operation.cpp b/src/lib/pubkey/xmss/xmss_verification_operation.cpp
index 6a757633e..2eacc19fd 100644
--- a/src/lib/pubkey/xmss/xmss_verification_operation.cpp
+++ b/src/lib/pubkey/xmss/xmss_verification_operation.cpp
@@ -117,7 +117,7 @@ bool XMSS_Verification_Operation::is_valid_signature(const uint8_t sig[],
m_msg_buf.clear();
return result;
}
- catch(Integrity_Failure&)
+ catch(...)
{
m_msg_buf.clear();
return false;
diff --git a/src/lib/tls/tls_channel.cpp b/src/lib/tls/tls_channel.cpp
index d3d8f899d..e021be518 100644
--- a/src/lib/tls/tls_channel.cpp
+++ b/src/lib/tls/tls_channel.cpp
@@ -359,7 +359,7 @@ size_t Channel::received_data(const uint8_t input[], size_t input_size)
send_fatal_alert(e.type());
throw;
}
- catch(Integrity_Failure&)
+ catch(Invalid_Authentication_Tag&)
{
send_fatal_alert(Alert::BAD_RECORD_MAC);
throw;
diff --git a/src/lib/utils/exceptn.cpp b/src/lib/utils/exceptn.cpp
index b2dff149b..78365f98b 100644
--- a/src/lib/utils/exceptn.cpp
+++ b/src/lib/utils/exceptn.cpp
@@ -93,8 +93,8 @@ Decoding_Error::Decoding_Error(const std::string& msg, const std::exception& e)
Decoding_Error::Decoding_Error(const std::string& name, const char* exception_message) :
Invalid_Argument(name + " failed with exception " + exception_message) {}
-Integrity_Failure::Integrity_Failure(const std::string& msg) :
- Exception("Integrity failure: " + msg)
+Invalid_Authentication_Tag::Invalid_Authentication_Tag(const std::string& msg) :
+ Exception("Invalid authentication tag: " + msg)
{}
Invalid_OID::Invalid_OID(const std::string& oid) :
diff --git a/src/lib/utils/exceptn.h b/src/lib/utils/exceptn.h
index bfff85618..c4934ed04 100644
--- a/src/lib/utils/exceptn.h
+++ b/src/lib/utils/exceptn.h
@@ -51,6 +51,8 @@ enum class ErrorType {
TLSError,
/** An error during an HTTP operation */
HttpError,
+ /** A message with an invalid authentication tag was detected */
+ InvalidTag,
/** An error when calling OpenSSL */
OpenSSLError = 200,
@@ -264,16 +266,24 @@ class BOTAN_PUBLIC_API(2,0) Provider_Not_Found final : public Lookup_Error
/**
* An AEAD or MAC check detected a message modification
+*
+* In versions before 2.10, Invalid_Authentication_Tag was named
+* Integrity_Failure, it was renamed to make its usage more clear.
*/
-class BOTAN_PUBLIC_API(2,0) Integrity_Failure final : public Exception
+class BOTAN_PUBLIC_API(2,0) Invalid_Authentication_Tag final : public Exception
{
public:
- explicit Integrity_Failure(const std::string& msg);
+ explicit Invalid_Authentication_Tag(const std::string& msg);
- ErrorType error_type() const noexcept override { return ErrorType::DecodingFailure; }
+ ErrorType error_type() const noexcept override { return ErrorType::InvalidTag; }
};
/**
+* For compatability with older versions
+*/
+typedef Invalid_Authentication_Tag Integrity_Failure;
+
+/**
* An error occurred while operating on an IO stream
*/
class BOTAN_PUBLIC_API(2,0) Stream_IO_Error final : public Exception
@@ -356,6 +366,8 @@ class BOTAN_PUBLIC_API(2,0) Invalid_OID final : public Decoding_Error
/**
* Self Test Failure Exception
+*
+* This exception is no longer used. It will be removed in a future major release.
*/
class BOTAN_PUBLIC_API(2,0) Self_Test_Failure final : public Internal_Error
{
@@ -365,6 +377,8 @@ class BOTAN_PUBLIC_API(2,0) Self_Test_Failure final : public Internal_Error
/**
* No_Provider_Found Exception
+*
+* This exception is no longer used. It will be removed in a future major release.
*/
class BOTAN_PUBLIC_API(2,0) No_Provider_Found final : public Exception
{
@@ -374,6 +388,8 @@ class BOTAN_PUBLIC_API(2,0) No_Provider_Found final : public Exception
/**
* Policy_Violation Exception
+*
+* This exception is no longer used. It will be removed in a future major release.
*/
class BOTAN_PUBLIC_API(2,0) Policy_Violation final : public Invalid_State
{
@@ -388,6 +404,7 @@ class BOTAN_PUBLIC_API(2,0) Policy_Violation final : public Invalid_State
* It might or might not be valid in another context like a standard.
*
* This exception is no longer used, instead Not_Implemented is thrown.
+* It will be removed in a future major release.
*/
class BOTAN_PUBLIC_API(2,0) Unsupported_Argument final : public Invalid_Argument
{