diff options
author | Jack Lloyd <[email protected]> | 2020-10-31 08:32:34 -0400 |
---|---|---|
committer | Jack Lloyd <[email protected]> | 2020-10-31 08:32:34 -0400 |
commit | 27a3c76ba6a24f0031a2cb592a1468e9df997c89 (patch) | |
tree | 56949a9e729aae2365efc48f666ac3de0b0dbe5a | |
parent | 96934dda6128e913c54381454f0f737aba074213 (diff) | |
parent | 776975a5eed16d3ca49c954e4ff337ec42148df0 (diff) |
Merge GH #2440 Support multiple associated data on AEAD_mode interface
-rw-r--r-- | src/lib/modes/aead/aead.cpp | 8 | ||||
-rw-r--r-- | src/lib/modes/aead/aead.h | 26 | ||||
-rw-r--r-- | src/lib/modes/aead/siv/siv.cpp | 7 | ||||
-rw-r--r-- | src/lib/modes/aead/siv/siv.h | 4 | ||||
-rw-r--r-- | src/tests/test_siv.cpp | 13 |
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) |