aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorlloyd <[email protected]>2013-12-31 19:01:37 +0000
committerlloyd <[email protected]>2013-12-31 19:01:37 +0000
commitc0ce45696f6d00e7496634c233410d264d0e9d42 (patch)
tree35392692a6cc59b00ed6d4b7d71c5619889f034e
parent7ec00d6a7bfe94f628a6c5118f3a0e8ed7938f99 (diff)
Make eax_test example (which reads LTC's EAX test file) an actual
test. Update to new AEAD api. Currently requires boost_regex (for tests only), done via hardcoding in makefile template.
-rw-r--r--checks/eax.cpp (renamed from doc/examples/eax_test.cpp)128
-rw-r--r--checks/eax.vec (renamed from doc/examples/eax_vecs.txt)0
-rw-r--r--checks/tests.h1
-rw-r--r--checks/validate.cpp1
-rw-r--r--doc/examples/row_encryptor.cpp171
-rw-r--r--src/build-data/makefile/unix_shr.in2
6 files changed, 57 insertions, 246 deletions
diff --git a/doc/examples/eax_test.cpp b/checks/eax.cpp
index 228ece286..e44adaa6a 100644
--- a/doc/examples/eax_test.cpp
+++ b/checks/eax.cpp
@@ -4,13 +4,15 @@
* Distributed under the terms of the Botan license
*/
+#include "tests.h"
#include <fstream>
#include <iostream>
#include <sstream>
#include <boost/regex.hpp>
-#include <botan/botan.h>
#include <botan/eax.h>
+#include <botan/hex.h>
+#include <botan/lookup.h>
using namespace Botan;
@@ -42,81 +44,61 @@ std::string seq(unsigned n)
return s;
}
-void eax_test(const std::string& algo,
- const std::string& key_str,
- const std::string& nonce_str,
- const std::string& header_str,
- const std::string& tag_str,
- const std::string& plaintext_str,
- const std::string& ciphertext)
+size_t eax_test(const std::string& algo,
+ const std::string& key_str,
+ const std::string& nonce_str,
+ const std::string& header_str,
+ const std::string& tag_str,
+ const std::string& plaintext_str,
+ const std::string& ciphertext)
{
- /*
- printf("EAX(algo=%s key=%s nonce=%s header=%s tag=%s pt=%s ct=%s)\n",
- algo.c_str(), key_str.c_str(), nonce_str.c_str(), header_str.c_str(), tag_str.c_str(),
- plaintext_str.c_str(), ciphertext.c_str());
- */
+ size_t fail = 0;
- SymmetricKey key(key_str);
- InitializationVector iv(nonce_str);
-
- EAX_Encryption* enc;
-
- Pipe pipe(new Hex_Decoder,
- enc = new EAX_Encryption(get_block_cipher(algo)),
- new Hex_Encoder);
-
- enc->set_key(key);
- enc->set_iv(iv);
-
- OctetString header(header_str);
-
- enc->set_header(header.begin(), header.length());
+ try
+ {
+ EAX_Encryption enc(get_block_cipher(algo));
+ EAX_Decryption dec(get_block_cipher(algo));
- pipe.start_msg();
- pipe.write(plaintext_str);
- pipe.end_msg();
+ enc.set_key(hex_decode(key_str));
+ dec.set_key(hex_decode(key_str));
- std::string out = pipe.read_all_as_string();
+ enc.set_associated_data_vec(hex_decode(header_str));
+ dec.set_associated_data_vec(hex_decode(header_str));
- if(out != ciphertext + tag_str)
- {
- printf("BAD enc %s '%s' != '%s%s'\n", algo.c_str(),
- out.c_str(), ciphertext.c_str(), tag_str.c_str());
- }
- else
- printf("OK enc %s\n", algo.c_str());
+ secure_vector<byte> text = hex_decode_locked(plaintext_str);
+ enc.start_vec(hex_decode(nonce_str));
+ enc.finish(text);
- try
- {
- EAX_Decryption* dec;
- Pipe pipe2(new Hex_Decoder,
- dec = new EAX_Decryption(get_block_cipher(algo)),
- new Hex_Encoder);
+ const std::string produced = hex_encode(text);
- dec->set_key(key);
- dec->set_iv(iv);
+ if(produced != ciphertext + tag_str)
+ {
+ std::cout << "EAX " << algo << " " << produced << " != expected " << ciphertext << tag_str << "\n";
+ ++fail;
+ }
- dec->set_header(header.begin(), header.length());
+ text.clear();
+ text = hex_decode_locked(ciphertext);
+ text += hex_decode_locked(tag_str);
- pipe2.start_msg();
- pipe2.write(ciphertext);
- pipe2.write(tag_str);
- pipe2.end_msg();
+ dec.start_vec(hex_decode(nonce_str));
+ dec.finish(text);
- std::string out2 = pipe2.read_all_as_string();
+ const std::string decrypted = hex_encode(text);
- if(out2 != plaintext_str)
+ if(decrypted != plaintext_str)
{
- printf("BAD decrypt %s '%s'\n", algo.c_str(), out2.c_str());
+ std::cout << "EAX " << algo << " " << decrypted << " != expected " << plaintext_str << "\n";
+ ++fail;
}
- else
- printf("OK decrypt %s\n", algo.c_str());
}
catch(std::exception& e)
{
- printf("%s\n", e.what());
+ std::cout << "Exception during EAX test " << e.what() << "\n";
+ ++fail;
}
+ return fail;
}
std::pair<std::string, int> translate_algo(const std::string& in)
@@ -181,11 +163,14 @@ std::string rep(const std::string& s_in, unsigned n)
return s_out;
}
-void run_tests(std::istream& in)
+size_t eax_tests(std::istream& in)
{
std::string algo;
std::string key;
+ size_t fails = 0;
+ size_t tests = 0;
+
while(in.good())
{
std::string line;
@@ -219,31 +204,26 @@ void run_tests(std::istream& in)
std::string header = seq(n);
std::string nonce = seq(n);
- eax_test(algo, key, nonce, header, tag,
- plaintext, ciphertext);
+ tests += 1;
+
+ fails += eax_test(algo, key, nonce, header, tag,
+ plaintext, ciphertext);
key = rep(tag, key.size()); // repeat as needed
}
}
}
+ test_report("EAX", tests, fails);
+ return fails;
}
}
-int main()
+size_t test_eax()
{
- std::ifstream in("eax_vecs.txt");
-
- Botan::LibraryInitializer init;
-
- if(!in)
- {
- std::cerr << "Couldn't read input file\n";
- return 1;
- }
-
- run_tests(in);
-
+ // Uses a set of tests created for libtomcrypt
+ std::ifstream in("checks/eax.vec");
+ return eax_tests(in);
}
diff --git a/doc/examples/eax_vecs.txt b/checks/eax.vec
index 95cd7c1ab..95cd7c1ab 100644
--- a/doc/examples/eax_vecs.txt
+++ b/checks/eax.vec
diff --git a/checks/tests.h b/checks/tests.h
index db92a5d3d..e1f59c501 100644
--- a/checks/tests.h
+++ b/checks/tests.h
@@ -37,6 +37,7 @@ size_t test_transform();
// One off tests
size_t test_ocb();
+size_t test_eax();
size_t test_keywrap();
size_t test_bcrypt();
size_t test_passhash9();
diff --git a/checks/validate.cpp b/checks/validate.cpp
index cb15325ef..bcb949a79 100644
--- a/checks/validate.cpp
+++ b/checks/validate.cpp
@@ -188,6 +188,7 @@ u32bit do_validation_tests(const std::string& filename,
std::vector<test_fn> all_tests;
all_tests.push_back(test_aead);
all_tests.push_back(test_ocb);
+ all_tests.push_back(test_eax);
all_tests.push_back(test_pbkdf);
all_tests.push_back(test_kdf);
diff --git a/doc/examples/row_encryptor.cpp b/doc/examples/row_encryptor.cpp
deleted file mode 100644
index b512025b6..000000000
--- a/doc/examples/row_encryptor.cpp
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
-* (C) 2009 Jack Lloyd
-*
-* Distributed under the terms of the Botan license
-*/
-
-#include <string>
-#include <memory>
-#include <sstream>
-#include <iostream>
-#include <stdexcept>
-
-#include <botan/botan.h>
-#include <botan/filters.h>
-#include <botan/eax.h>
-
-using namespace Botan;
-
-/*
-* Encrypt and decrypt small rows
-*/
-class Row_Encryptor
- {
- public:
- Row_Encryptor(const std::string& passphrase,
- RandomNumberGenerator& rng);
-
- Row_Encryptor(const std::string& passphrase,
- const std::vector<byte>& salt);
-
- std::string encrypt(const std::string& input,
- const std::vector<byte>& salt);
-
- std::string decrypt(const std::string& input,
- const std::vector<byte>& salt);
-
- std::vector<byte> get_pbkdf_salt() const { return pbkdf_salt; }
- private:
- void init(const std::string& passphrase);
-
- Row_Encryptor(const Row_Encryptor&) {}
- Row_Encryptor& operator=(const Row_Encryptor&) { return (*this); }
-
- std::vector<byte> pbkdf_salt;
- Pipe enc_pipe, dec_pipe;
- EAX_Encryption* eax_enc; // owned by enc_pipe
- EAX_Decryption* eax_dec; // owned by dec_pipe;
- };
-
-Row_Encryptor::Row_Encryptor(const std::string& passphrase,
- RandomNumberGenerator& rng)
- {
- pbkdf_salt.resize(10); // 80 bits
- rng.randomize(&pbkdf_salt[0], pbkdf_salt.size());
- init(passphrase);
- }
-
-Row_Encryptor::Row_Encryptor(const std::string& passphrase,
- const std::vector<byte>& salt)
- {
- pbkdf_salt = salt;
- init(passphrase);
- }
-
-void Row_Encryptor::init(const std::string& passphrase)
- {
- std::auto_ptr<PBKDF> pbkdf(get_pbkdf("PBKDF2(SHA-160)"));
-
- secure_vector<byte> key = pbkdf->derive_key(32, passphrase,
- &pbkdf_salt[0], pbkdf_salt.size(),
- 10000).bits_of();
-
- /*
- Save pointers to the EAX objects so we can change the IV as needed
- */
-
- Algorithm_Factory& af = global_state().algorithm_factory();
-
- const BlockCipher* proto = af.prototype_block_cipher("Serpent");
-
- if(!proto)
- throw std::runtime_error("Could not get a Serpent proto object");
-
- enc_pipe.append(eax_enc = new EAX_Encryption(proto->clone()));
- dec_pipe.append(eax_dec = new EAX_Decryption(proto->clone()));
-
- eax_enc->set_key(key);
- eax_dec->set_key(key);
- }
-
-std::string Row_Encryptor::encrypt(const std::string& input,
- const std::vector<byte>& salt)
- {
- eax_enc->set_iv(salt);
- enc_pipe.process_msg(input);
- return enc_pipe.read_all_as_string(Pipe::LAST_MESSAGE);
- }
-
-std::string Row_Encryptor::decrypt(const std::string& input,
- const std::vector<byte>& salt)
- {
- eax_dec->set_iv(salt);
- dec_pipe.process_msg(input);
- return dec_pipe.read_all_as_string(Pipe::LAST_MESSAGE);
- }
-
-/*
-* Test code follows:
-*/
-
-int main()
- {
- Botan::LibraryInitializer init;
-
- AutoSeeded_RNG rng;
-
- const std::string secret_passphrase = "secret passphrase";
-
- Row_Encryptor encryptor("secret passphrase", rng);
-
- std::vector<std::string> original_inputs;
-
- for(u32bit i = 0; i != 50000; ++i)
- {
- std::ostringstream out;
-
- u32bit output_bytes = rng.next_byte();
-
- for(u32bit j = 0; j != output_bytes; ++j)
- out << std::hex << (int)rng.next_byte();
-
- original_inputs.push_back(out.str());
- }
-
- std::vector<std::string> encrypted_values;
- std::vector<byte> salt(4);
-
- for(u32bit i = 0; i != original_inputs.size(); ++i)
- {
- std::string input = original_inputs[i];
-
- for(u32bit j = 0; j != 4; ++j)
- salt[j] = (i >> 8) & 0xFF;
-
- encrypted_values.push_back(encryptor.encrypt(input, salt));
- }
-
- for(u32bit i = 0; i != encrypted_values.size(); ++i)
- {
- std::string ciphertext = encrypted_values[i];
-
- // NOTE: same salt value as previous loop (index value)
- for(u32bit j = 0; j != 4; ++j)
- salt[j] = (i >> 8) & 0xFF;
-
- std::string output = encryptor.decrypt(ciphertext, salt);
-
- if(output != original_inputs[i])
- std::cout << "BOOM " << i << "\n";
- }
-
- Row_Encryptor test_pbkdf_salt_copy(secret_passphrase,
- encryptor.get_pbkdf_salt());
-
- zeroise(salt);
- std::string test = test_pbkdf_salt_copy.decrypt(encrypted_values[0], salt);
- if(test != original_inputs[0])
- std::cout << "PBKDF salt copy failed to decrypt properly\n";
-
- return 0;
- }
diff --git a/src/build-data/makefile/unix_shr.in b/src/build-data/makefile/unix_shr.in
index c412a94fd..610367dc5 100644
--- a/src/build-data/makefile/unix_shr.in
+++ b/src/build-data/makefile/unix_shr.in
@@ -71,7 +71,7 @@ CHECKOBJS = %{check_objs}
# Link Commands
$(CHECK): $(LIBRARIES) $(CHECKOBJS)
- $(CXX) $(LDFLAGS) $(CHECKOBJS) $(SHARED_LIB) $(LINK_TO) -o $(CHECK)
+ $(CXX) $(LDFLAGS) $(CHECKOBJS) $(SHARED_LIB) $(LINK_TO) -lboost_regex -o $(CHECK)
$(STATIC_LIB): $(LIBOBJS)
$(RM) $(STATIC_LIB)