aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJack Lloyd <[email protected]>2020-10-31 08:32:34 -0400
committerJack Lloyd <[email protected]>2020-10-31 08:32:34 -0400
commit27a3c76ba6a24f0031a2cb592a1468e9df997c89 (patch)
tree56949a9e729aae2365efc48f666ac3de0b0dbe5a /src
parent96934dda6128e913c54381454f0f737aba074213 (diff)
parent776975a5eed16d3ca49c954e4ff337ec42148df0 (diff)
Merge GH #2440 Support multiple associated data on AEAD_mode interface
Diffstat (limited to 'src')
-rw-r--r--src/lib/modes/aead/aead.cpp8
-rw-r--r--src/lib/modes/aead/aead.h26
-rw-r--r--src/lib/modes/aead/siv/siv.cpp7
-rw-r--r--src/lib/modes/aead/siv/siv.h4
-rw-r--r--src/tests/test_siv.cpp13
5 files changed, 49 insertions, 9 deletions
diff --git a/src/lib/modes/aead/aead.cpp b/src/lib/modes/aead/aead.cpp
index 077e09e5c..9ad550ffd 100644
--- a/src/lib/modes/aead/aead.cpp
+++ b/src/lib/modes/aead/aead.cpp
@@ -39,6 +39,14 @@
namespace Botan {
+void AEAD_Mode::set_associated_data_n(size_t i, const uint8_t ad[], size_t ad_len)
+ {
+ if(i == 0)
+ this->set_associated_data(ad, ad_len);
+ else
+ throw Invalid_Argument("AEAD '" + name() + "' does not support multiple associated data");
+ }
+
std::unique_ptr<AEAD_Mode> AEAD_Mode::create_or_throw(const std::string& algo,
Cipher_Dir dir,
const std::string& provider)
diff --git a/src/lib/modes/aead/aead.h b/src/lib/modes/aead/aead.h
index 92957fb24..442eb8ed7 100644
--- a/src/lib/modes/aead/aead.h
+++ b/src/lib/modes/aead/aead.h
@@ -61,6 +61,32 @@ class BOTAN_PUBLIC_API(2,0) AEAD_Mode : public Cipher_Mode
virtual void set_associated_data(const uint8_t ad[], size_t ad_len) = 0;
/**
+ * Set associated data that is not included in the ciphertext but
+ * that should be authenticated. Must be called after set_key and
+ * before start.
+ *
+ * Unless reset by another call, the associated data is kept
+ * between messages. Thus, if the AD does not change, calling
+ * once (after set_key) is the optimum.
+ *
+ * Some AEADs (namely SIV) support multiple AD inputs. For
+ * all other modes only nominal AD input 0 is supported; all
+ * other values of i will cause an exception.
+ *
+ * @param ad the associated data
+ * @param ad_len length of add in bytes
+ */
+ virtual void set_associated_data_n(size_t i, const uint8_t ad[], size_t ad_len);
+
+ /**
+ * Returns the maximum supported number of associated data inputs which
+ * can be provided to set_associated_data_n
+ *
+ * If returns 0, then no associated data is supported.
+ */
+ virtual size_t maximum_associated_data_inputs() const { return 1; }
+
+ /**
* Most AEADs require the key to be set prior to setting the AD
* A few allow the AD to be set even before the cipher is keyed.
* Such ciphers would return false from this function.
diff --git a/src/lib/modes/aead/siv/siv.cpp b/src/lib/modes/aead/siv/siv.cpp
index 75bdb91c4..8bd82a468 100644
--- a/src/lib/modes/aead/siv/siv.cpp
+++ b/src/lib/modes/aead/siv/siv.cpp
@@ -78,9 +78,14 @@ void SIV_Mode::key_schedule(const uint8_t key[], size_t length)
m_ad_macs.clear();
}
+size_t SIV_Mode::maximum_associated_data_inputs() const
+ {
+ return block_size() * 8 - 2;
+ }
+
void SIV_Mode::set_associated_data_n(size_t n, const uint8_t ad[], size_t length)
{
- const size_t max_ads = block_size() * 8 - 2;
+ const size_t max_ads = maximum_associated_data_inputs();
if(n > max_ads)
throw Invalid_Argument(name() + " allows no more than " + std::to_string(max_ads) + " ADs");
diff --git a/src/lib/modes/aead/siv/siv.h b/src/lib/modes/aead/siv/siv.h
index 44e0a6bf9..c76fd3229 100644
--- a/src/lib/modes/aead/siv/siv.h
+++ b/src/lib/modes/aead/siv/siv.h
@@ -33,7 +33,9 @@ class BOTAN_PUBLIC_API(2,0) SIV_Mode : public AEAD_Mode
* @param ad associated data
* @param ad_len length of associated data in bytes
*/
- void set_associated_data_n(size_t n, const uint8_t ad[], size_t ad_len);
+ void set_associated_data_n(size_t n, const uint8_t ad[], size_t ad_len) override;
+
+ size_t maximum_associated_data_inputs() const override;
void set_associated_data(const uint8_t ad[], size_t ad_len) override
{
diff --git a/src/tests/test_siv.cpp b/src/tests/test_siv.cpp
index 886b817a6..83a936543 100644
--- a/src/tests/test_siv.cpp
+++ b/src/tests/test_siv.cpp
@@ -7,8 +7,7 @@
#include "tests.h"
#if defined(BOTAN_HAS_AEAD_SIV)
- #include <botan/siv.h>
- #include <botan/block_cipher.h>
+ #include <botan/aead.h>
#include <botan/parsing.h>
#endif
@@ -32,18 +31,18 @@ class SIV_Tests final : public Text_Based_Test
const std::vector<std::string> ad_list =
Botan::split_on(vars.get_req_str("ADs"), ',');
- Test::Result result(algo + "/SIV");
+ const std::string siv_name = algo + "/SIV";
- auto cipher = Botan::BlockCipher::create(algo);
+ Test::Result result(siv_name);
- if(!cipher)
+ auto siv = Botan::AEAD_Mode::create(siv_name, Botan::ENCRYPTION);
+
+ if(!siv)
{
result.test_note("Skipping test due to missing cipher");
return result;
}
- std::unique_ptr<Botan::SIV_Mode> siv(new Botan::SIV_Encryption(cipher.release()));
-
siv->set_key(key);
for(size_t i = 0; i != ad_list.size(); ++i)