aboutsummaryrefslogtreecommitdiffstats
path: root/src/tests
diff options
context:
space:
mode:
authorJack Lloyd <[email protected]>2017-08-14 15:32:55 -0400
committerJack Lloyd <[email protected]>2017-09-10 13:11:46 -0400
commit0f1aaaaf76f737fd0b421af00c49b82fd3d17d5b (patch)
treec07f5503583eacc2339e12907f42c2fb4dcd57a4 /src/tests
parent61c1fd71ba406ba387d7077f203a0fe5223537ca (diff)
Support larger block sizes in OCB
This doesn't match the draft-3 test vectors and may be bogus. [ci skip]
Diffstat (limited to 'src/tests')
-rw-r--r--src/tests/data/aead/ocb.vec8
-rw-r--r--src/tests/data/ocb_wide.vec31
-rw-r--r--src/tests/data/ocb_wide_long.vec12
-rw-r--r--src/tests/test_ocb.cpp216
4 files changed, 267 insertions, 0 deletions
diff --git a/src/tests/data/aead/ocb.vec b/src/tests/data/aead/ocb.vec
index f0fbb3646..176dcb2b8 100644
--- a/src/tests/data/aead/ocb.vec
+++ b/src/tests/data/aead/ocb.vec
@@ -248,3 +248,11 @@ Nonce = BBAA9988776655443322110D
AD = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F2021222324252627
In = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F2021222324252627
Out = 1792A4E31E0755FB03E31B22116E6C2DDF9EFD6E33D536F1A0124B0A55BAE884ED93481529C76B6AD0C515F4D1CDD4FDAC4F02AA
+
+# Generated by Botan, unconfirmed result
+[Threefish-512/OCB(32)]
+Key = 1792A4E31E0755FB03E31B22116E6C2DDF9EFD6E33D536F1A0124B0A55BAE8841792A4E31E0755FB03E31B22116E6C2DDF9EFD6E33D536F1A0124B0A55BAE884
+Nonce = D5CA91748410C1751FF8A2F61825
+AD = C5CD9D1850C141E358649994EE701B68
+In = 2942BFC773BDA23CABC6ACFD9BFD5835BD300F0973
+Out = 45EEFFF01CDA61695EA24B036074491FE61B96C94337F0F947FB4E10E679A9F2A825DF8CEA530A2784E5640A768DE536C76A79157E
diff --git a/src/tests/data/ocb_wide.vec b/src/tests/data/ocb_wide.vec
new file mode 100644
index 000000000..d8cede352
--- /dev/null
+++ b/src/tests/data/ocb_wide.vec
@@ -0,0 +1,31 @@
+
+
+Key = 8182838485868788898A8B8C8D8E8F909192939495969798
+Nonce = F0F1F2F3F4F5F6F7F8F9FAFB
+AD =
+In =
+Out = F00F1A7125DACF8B57D0F50E6B44615C9996D209B50A1ED7
+
+Key = 9192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8
+Nonce = F1F2F3F4F5F6F7F8F9FAFBFC
+AD = 05060708090A0B0C0D0E0F10
+In = 0102030405060708090A0B0C
+Out = 9AFC5E331177D5A4534506C8670BAFC0E4882C6F9E82C72BD79BDF9E5AD6D4C83955F021
+
+Key = A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8
+Nonce = F2F3F4F5F6F7F8F9FAFBFCFD
+AD = 060708090A0B0C0D0E0F101112131415161718191A1B1C1D
+In = 02030405060708090A0B0C0D0E0F10111213141516171819
+Out = 92A7C0C02A1F6E154762A3C3885DAFF1FAED6ACB59EC9E625995C61B5E92C5254F63D449CD41F4F2F6F9EAF61CD08670
+
+Key = B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7C8
+Nonce = F3F4F5F6F7F8F9FAFBFCFDFE
+AD = 0708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A
+In = 030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F20212223242526
+Out = 2070BEDB155997BFA6DE55F27CD45AA8223B16312965A814D347CC7EF551DA09E7BCB1806D9418BB37C64AB851272D0D193F32BCB7B081A149C84723
+
+Key = C1C2C3C4C5C6C7C8C9CACBCCCDCECFD0D1D2D3D4D5D6D7D8
+Nonce = F4F5F6F7F8F9FAFBFCFDFEFF
+AD = 08090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F3031323334353637
+In = 0405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F30313233
+Out = 70E46BCD56C24DCBFC2A280C3C2A26A9AAB9A097AA3EB37352EE799774C85F517E809AF6FEC0D5524972730C09B52555889E94B2D0C6CCF2079291B49B8E86F9D4C7D6EE081E165A
diff --git a/src/tests/data/ocb_wide_long.vec b/src/tests/data/ocb_wide_long.vec
new file mode 100644
index 000000000..7c17f00bf
--- /dev/null
+++ b/src/tests/data/ocb_wide_long.vec
@@ -0,0 +1,12 @@
+
+Blocklen = 128
+Output = 0D099181BE37171BF94582877D6D4693
+
+Blocklen = 192
+Output = C6B3449A7A5C174253720B65198779C0E1758794C023F567
+
+Blocklen = 256
+Output = 87F321F24B0554565BEB6C994AD04F8F95F1A808E67EAFBD60E0E86152AFB37C
+
+Blocklen = 512
+Output = 6748655A0A83543D8AA6287AE9FFC37C9A433332DDFD4E8B42F94D741944D440
diff --git a/src/tests/test_ocb.cpp b/src/tests/test_ocb.cpp
index ede15fb82..cacf9a0d4 100644
--- a/src/tests/test_ocb.cpp
+++ b/src/tests/test_ocb.cpp
@@ -9,6 +9,7 @@
#if defined(BOTAN_HAS_AEAD_OCB)
#include <botan/ocb.h>
#include <botan/loadstor.h>
+ #include <botan/internal/poly_dbl.h>
#endif
namespace Botan_Tests {
@@ -17,6 +18,221 @@ namespace {
#if defined(BOTAN_HAS_AEAD_OCB)
+// Toy cipher used for wide block tests
+
+class OCB_Wide_Test_Block_Cipher : public Botan::BlockCipher
+ {
+ public:
+ OCB_Wide_Test_Block_Cipher(size_t bs) : m_bs(bs) {}
+
+ std::string name() const override { return "OCB_ToyCipher"; }
+ size_t block_size() const override { return m_bs; }
+ void clear() override { m_key.clear(); }
+
+ Botan::BlockCipher* clone() const { return new OCB_Wide_Test_Block_Cipher(m_bs); }
+
+ void key_schedule(const uint8_t key[], size_t length) override
+ {
+ m_key.assign(key, key + length);
+ }
+
+ Botan::Key_Length_Specification key_spec() const override
+ {
+ return Botan::Key_Length_Specification(m_bs);
+ }
+
+ void encrypt_n(const uint8_t in[], uint8_t out[],
+ size_t blocks) const override
+ {
+ while(blocks)
+ {
+ Botan::copy_mem(out, in, m_bs);
+ Botan::poly_double_n(out, m_bs);
+
+ for(size_t i = 0; i != m_bs; ++i)
+ out[i] ^= m_key[i];
+
+ blocks--;
+ in += block_size();
+ out += block_size();
+ }
+ }
+
+ void decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override
+ {
+ while(blocks)
+ {
+ for(size_t i = 0; i != m_bs; ++i)
+ out[i] = in[i] ^ m_key[i];
+
+ const uint8_t bottom_carry = in[m_bs-1] & 0x01;
+
+ if(bottom_carry)
+ {
+ if(m_bs == 16 || m_bs == 24)
+ {
+ out[m_bs-1] ^= 0x87;
+ }
+ else if(m_bs == 32)
+ {
+ out[m_bs-2] ^= 0x4;
+ out[m_bs-1] ^= 0x25;
+ }
+ else if(m_bs == 64)
+ {
+ out[m_bs-2] ^= 0x1;
+ out[m_bs-1] ^= 0x25;
+ }
+ else
+ throw Test_Error("Bad OCB test block size");
+ }
+
+ uint8_t carry = bottom_carry << 7;
+
+ for(size_t i = 0; i != m_bs; ++i)
+ {
+ uint8_t temp = out[i];
+ out[i] = (temp >> 1) | carry;
+ carry = (temp & 0x1) << 7;
+ }
+
+ blocks--;
+ in += block_size();
+ out += block_size();
+ }
+ }
+ private:
+ size_t m_bs;
+ std::vector<uint8_t> m_key;
+ };
+
+class OCB_Wide_KAT_Tests : public Text_Based_Test
+ {
+ public:
+ OCB_Wide_KAT_Tests()
+ : Text_Based_Test("ocb_wide.vec", "Key,Nonce,AD,In,Out") {}
+
+ Test::Result run_one_test(const std::string&, const VarMap& vars) override
+ {
+ Test::Result result("OCB wide block KAT");
+
+ const std::vector<uint8_t> key = get_req_bin(vars, "Key");
+ const std::vector<uint8_t> nonce = get_req_bin(vars, "Nonce");
+ const std::vector<uint8_t> ad = get_req_bin(vars, "AD");
+ const std::vector<uint8_t> input = get_req_bin(vars, "In");
+ const std::vector<uint8_t> expected = get_req_bin(vars, "Out");
+
+ const size_t bs = key.size();
+ Botan::secure_vector<uint8_t> buf(input.begin(), input.end());
+
+ Botan::OCB_Encryption enc(new OCB_Wide_Test_Block_Cipher(bs), std::min<size_t>(bs, 32));
+ enc.set_key(key);
+ enc.set_ad(ad);
+ enc.start(nonce);
+ enc.finish(buf);
+ result.test_eq("Ciphertext matches", buf, expected);
+
+ Botan::OCB_Decryption dec(new OCB_Wide_Test_Block_Cipher(bs), std::min<size_t>(bs, 32));
+ dec.set_key(key);
+ dec.set_ad(ad);
+ dec.start(nonce);
+ dec.finish(buf);
+ result.test_eq("Decryption correct", buf, input);
+
+ return result;
+ }
+ };
+
+BOTAN_REGISTER_TEST("ocb_wide", OCB_Wide_KAT_Tests);
+
+class OCB_Wide_Long_KAT_Tests : public Text_Based_Test
+ {
+ public:
+ OCB_Wide_Long_KAT_Tests()
+ : Text_Based_Test("ocb_wide_long.vec", "Blocklen,Output") {}
+
+ Test::Result run_one_test(const std::string&, const VarMap& vars) override
+ {
+ Test::Result result("OCB wide block long test");
+
+ const size_t bs = get_req_sz(vars, "Blocklen") / 8;
+ const std::vector<uint8_t> expected = get_req_bin(vars, "Output");
+
+ if(bs != 16 && bs != 24 && bs != 32 && bs != 64)
+ throw Test_Error("Unsupported Blocklen in OCB wide block test");
+
+ Botan::OCB_Encryption enc(new OCB_Wide_Test_Block_Cipher(bs), std::min<size_t>(bs, 32));
+
+ /*
+ Y, string of length min(B, 256) bits
+
+ Y is defined as follows.
+
+ K = (0xA0 || 0xA1 || 0xA2 || ...)[1..B]
+ C = <empty string>
+ for i = 0 to 127 do
+ S = (0x50 || 0x51 || 0x52 || ...)[1..8i]
+ N = num2str(3i+1,16)
+ C = C || OCB-ENCRYPT(K,N,S,S)
+ N = num2str(3i+2,16)
+ C = C || OCB-ENCRYPT(K,N,<empty string>,S)
+ N = num2str(3i+3,16)
+ C = C || OCB-ENCRYPT(K,N,S,<empty string>)
+ end for
+ N = num2str(385,16)
+ Y = OCB-ENCRYPT(K,N,C,<empty string>)
+ */
+
+ std::vector<uint8_t> key(bs);
+ for(size_t i = 0; i != bs; ++i)
+ key[i] = 0xA0 + i;
+
+ enc.set_key(key);
+
+ const std::vector<uint8_t> empty;
+ std::vector<uint8_t> N(2);
+ std::vector<uint8_t> C;
+
+ for(size_t i = 0; i != 128; ++i)
+ {
+ const std::vector<uint8_t> S(i);
+
+ Botan::store_be(static_cast<uint32_t>(3 * i + 1), &N[8]);
+
+ ocb_encrypt(result, C, enc, N, S, S);
+ Botan::store_be(static_cast<uint32_t>(3 * i + 2), &N[8]);
+ ocb_encrypt(result, C, enc, N, S, empty);
+ Botan::store_be(static_cast<uint32_t>(3 * i + 3), &N[8]);
+ ocb_encrypt(result, C, enc, N, empty, S);
+ }
+
+ Botan::store_be(static_cast<uint32_t>(385), &N[8]);
+ std::vector<uint8_t> final_result;
+ ocb_encrypt(result, final_result, enc, N, empty, C);
+
+ result.test_eq("correct value", final_result, expected);
+
+ return result;
+ }
+
+ private:
+ void ocb_encrypt(Test::Result& result,
+ std::vector<uint8_t>& output_to,
+ Botan::OCB_Encryption& enc,
+ const std::vector<uint8_t>& nonce,
+ const std::vector<uint8_t>& pt,
+ const std::vector<uint8_t>& ad)
+ {
+ enc.set_associated_data(ad.data(), ad.size());
+ enc.start(nonce.data(), nonce.size());
+ Botan::secure_vector<uint8_t> buf(pt.begin(), pt.end());
+ enc.finish(buf, 0);
+ output_to.insert(output_to.end(), buf.begin(), buf.end());
+ }
+ };
+
+BOTAN_REGISTER_TEST("ocb_long_wide", OCB_Wide_Long_KAT_Tests);
+
class OCB_Long_KAT_Tests : public Text_Based_Test
{
public: