aboutsummaryrefslogtreecommitdiffstats
path: root/src/tests/kat_ocb.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/tests/kat_ocb.cpp')
-rw-r--r--src/tests/kat_ocb.cpp142
1 files changed, 142 insertions, 0 deletions
diff --git a/src/tests/kat_ocb.cpp b/src/tests/kat_ocb.cpp
new file mode 100644
index 000000000..b2bd296e0
--- /dev/null
+++ b/src/tests/kat_ocb.cpp
@@ -0,0 +1,142 @@
+
+#include "tests.h"
+
+#include <botan/ocb.h>
+#include <botan/hex.h>
+#include <botan/sha2_32.h>
+#include <botan/aes.h>
+#include <iostream>
+//#include <botan/selftest.h>
+
+using namespace Botan;
+
+// something like this should be in the library
+namespace {
+
+std::vector<byte> ocb_decrypt(const SymmetricKey& key,
+ const std::vector<byte>& nonce,
+ const byte ct[], size_t ct_len,
+ const byte ad[], size_t ad_len)
+ {
+ OCB_Decryption ocb(new AES_128);
+
+ ocb.set_key(key);
+ ocb.set_associated_data(ad, ad_len);
+
+ ocb.start(&nonce[0], nonce.size());
+
+ secure_vector<byte> buf(ct, ct+ct_len);
+ ocb.finish(buf, 0);
+
+ return unlock(buf);
+ }
+
+std::vector<byte> ocb_encrypt(const SymmetricKey& key,
+ const std::vector<byte>& nonce,
+ const byte pt[], size_t pt_len,
+ const byte ad[], size_t ad_len)
+ {
+ OCB_Encryption ocb(new AES_128);
+
+ ocb.set_key(key);
+ ocb.set_associated_data(ad, ad_len);
+
+ ocb.start(&nonce[0], nonce.size());
+
+ secure_vector<byte> buf(pt, pt+pt_len);
+ ocb.finish(buf, 0);
+
+ try
+ {
+ std::vector<byte> pt2 = ocb_decrypt(key, nonce, &buf[0], buf.size(), ad, ad_len);
+ if(pt_len != pt2.size() || !same_mem(pt, &pt2[0], pt_len))
+ std::cout << "OCB failed to decrypt correctly\n";
+ }
+ catch(std::exception& e)
+ {
+ std::cout << "OCB round trip error - " << e.what() << "\n";
+ }
+
+ return unlock(buf);
+ }
+
+template<typename Alloc, typename Alloc2>
+std::vector<byte> ocb_encrypt(const SymmetricKey& key,
+ const std::vector<byte>& nonce,
+ const std::vector<byte, Alloc>& pt,
+ const std::vector<byte, Alloc2>& ad)
+ {
+ return ocb_encrypt(key, nonce, &pt[0], pt.size(), &ad[0], ad.size());
+ }
+
+template<typename Alloc, typename Alloc2>
+std::vector<byte> ocb_decrypt(const SymmetricKey& key,
+ const std::vector<byte>& nonce,
+ const std::vector<byte, Alloc>& pt,
+ const std::vector<byte, Alloc2>& ad)
+ {
+ return ocb_decrypt(key, nonce, &pt[0], pt.size(), &ad[0], ad.size());
+ }
+
+std::vector<byte> ocb_encrypt(OCB_Encryption& ocb,
+ const std::vector<byte>& nonce,
+ const std::vector<byte>& pt,
+ const std::vector<byte>& ad)
+ {
+ ocb.set_associated_data(&ad[0], ad.size());
+
+ ocb.start(&nonce[0], nonce.size());
+
+ secure_vector<byte> buf(pt.begin(), pt.end());
+ ocb.finish(buf, 0);
+
+ return unlock(buf);
+ }
+
+size_t test_ocb_long(size_t taglen, const std::string &expected)
+ {
+ OCB_Encryption ocb(new AES_128, taglen/8);
+
+ ocb.set_key(SymmetricKey("00000000000000000000000000000000"));
+
+ const std::vector<byte> empty;
+ std::vector<byte> N(12);
+ std::vector<byte> C;
+
+ for(size_t i = 0; i != 128; ++i)
+ {
+ const std::vector<byte> S(i);
+ N[11] = i;
+
+ C += ocb_encrypt(ocb, N, S, S);
+ C += ocb_encrypt(ocb, N, S, empty);
+ C += ocb_encrypt(ocb, N, empty, S);
+ }
+
+ N[11] = 0;
+ const std::vector<byte> cipher = ocb_encrypt(ocb, N, empty, C);
+
+ const std::string cipher_hex = hex_encode(cipher);
+
+ if(cipher_hex != expected)
+ {
+ std::cout << "OCB AES-128 long test mistmatch " << cipher_hex << " != " << expected << "\n";
+ return 1;
+ }
+
+ return 0;
+ }
+
+}
+
+size_t test_ocb()
+ {
+ size_t fails = 0;
+ fails += test_ocb_long(128, "B2B41CBF9B05037DA7F16C24A35C1C94");
+ fails += test_ocb_long(96, "1A4F0654277709A5BDA0D380");
+ fails += test_ocb_long(64, "B7ECE9D381FE437F");
+ test_report("OCB long", 3, fails);
+ return fails;
+ }
+
+