|
|
|
@ -17,6 +17,8 @@
|
|
|
|
|
|
|
|
|
|
#include <boost/assign/list_of.hpp>
|
|
|
|
|
#include <boost/test/unit_test.hpp>
|
|
|
|
|
#include <openssl/aes.h>
|
|
|
|
|
#include <openssl/evp.h>
|
|
|
|
|
|
|
|
|
|
BOOST_FIXTURE_TEST_SUITE(crypto_tests, BasicTestingSetup)
|
|
|
|
|
|
|
|
|
@ -103,6 +105,88 @@ void TestAES256(const std::string &hexkey, const std::string &hexin, const std::
|
|
|
|
|
BOOST_CHECK(buf == in);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void TestAES128CBC(const std::string &hexkey, const std::string &hexiv, bool pad, const std::string &hexin, const std::string &hexout)
|
|
|
|
|
{
|
|
|
|
|
std::vector<unsigned char> key = ParseHex(hexkey);
|
|
|
|
|
std::vector<unsigned char> iv = ParseHex(hexiv);
|
|
|
|
|
std::vector<unsigned char> in = ParseHex(hexin);
|
|
|
|
|
std::vector<unsigned char> correctout = ParseHex(hexout);
|
|
|
|
|
std::vector<unsigned char> realout(in.size() + AES_BLOCKSIZE);
|
|
|
|
|
|
|
|
|
|
// Encrypt the plaintext and verify that it equals the cipher
|
|
|
|
|
AES128CBCEncrypt enc(&key[0], &iv[0], pad);
|
|
|
|
|
int size = enc.Encrypt(&in[0], in.size(), &realout[0]);
|
|
|
|
|
realout.resize(size);
|
|
|
|
|
BOOST_CHECK(realout.size() == correctout.size());
|
|
|
|
|
BOOST_CHECK_MESSAGE(realout == correctout, HexStr(realout) + std::string(" != ") + hexout);
|
|
|
|
|
|
|
|
|
|
// Decrypt the cipher and verify that it equals the plaintext
|
|
|
|
|
std::vector<unsigned char> decrypted(correctout.size());
|
|
|
|
|
AES128CBCDecrypt dec(&key[0], &iv[0], pad);
|
|
|
|
|
size = dec.Decrypt(&correctout[0], correctout.size(), &decrypted[0]);
|
|
|
|
|
decrypted.resize(size);
|
|
|
|
|
BOOST_CHECK(decrypted.size() == in.size());
|
|
|
|
|
BOOST_CHECK_MESSAGE(decrypted == in, HexStr(decrypted) + std::string(" != ") + hexin);
|
|
|
|
|
|
|
|
|
|
// Encrypt and re-decrypt substrings of the plaintext and verify that they equal each-other
|
|
|
|
|
for(std::vector<unsigned char>::iterator i(in.begin()); i != in.end(); ++i)
|
|
|
|
|
{
|
|
|
|
|
std::vector<unsigned char> sub(i, in.end());
|
|
|
|
|
std::vector<unsigned char> subout(sub.size() + AES_BLOCKSIZE);
|
|
|
|
|
int size = enc.Encrypt(&sub[0], sub.size(), &subout[0]);
|
|
|
|
|
if (size != 0)
|
|
|
|
|
{
|
|
|
|
|
subout.resize(size);
|
|
|
|
|
std::vector<unsigned char> subdecrypted(subout.size());
|
|
|
|
|
size = dec.Decrypt(&subout[0], subout.size(), &subdecrypted[0]);
|
|
|
|
|
subdecrypted.resize(size);
|
|
|
|
|
BOOST_CHECK(decrypted.size() == in.size());
|
|
|
|
|
BOOST_CHECK_MESSAGE(subdecrypted == sub, HexStr(subdecrypted) + std::string(" != ") + HexStr(sub));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void TestAES256CBC(const std::string &hexkey, const std::string &hexiv, bool pad, const std::string &hexin, const std::string &hexout)
|
|
|
|
|
{
|
|
|
|
|
std::vector<unsigned char> key = ParseHex(hexkey);
|
|
|
|
|
std::vector<unsigned char> iv = ParseHex(hexiv);
|
|
|
|
|
std::vector<unsigned char> in = ParseHex(hexin);
|
|
|
|
|
std::vector<unsigned char> correctout = ParseHex(hexout);
|
|
|
|
|
std::vector<unsigned char> realout(in.size() + AES_BLOCKSIZE);
|
|
|
|
|
|
|
|
|
|
// Encrypt the plaintext and verify that it equals the cipher
|
|
|
|
|
AES256CBCEncrypt enc(&key[0], &iv[0], pad);
|
|
|
|
|
int size = enc.Encrypt(&in[0], in.size(), &realout[0]);
|
|
|
|
|
realout.resize(size);
|
|
|
|
|
BOOST_CHECK(realout.size() == correctout.size());
|
|
|
|
|
BOOST_CHECK_MESSAGE(realout == correctout, HexStr(realout) + std::string(" != ") + hexout);
|
|
|
|
|
|
|
|
|
|
// Decrypt the cipher and verify that it equals the plaintext
|
|
|
|
|
std::vector<unsigned char> decrypted(correctout.size());
|
|
|
|
|
AES256CBCDecrypt dec(&key[0], &iv[0], pad);
|
|
|
|
|
size = dec.Decrypt(&correctout[0], correctout.size(), &decrypted[0]);
|
|
|
|
|
decrypted.resize(size);
|
|
|
|
|
BOOST_CHECK(decrypted.size() == in.size());
|
|
|
|
|
BOOST_CHECK_MESSAGE(decrypted == in, HexStr(decrypted) + std::string(" != ") + hexin);
|
|
|
|
|
|
|
|
|
|
// Encrypt and re-decrypt substrings of the plaintext and verify that they equal each-other
|
|
|
|
|
for(std::vector<unsigned char>::iterator i(in.begin()); i != in.end(); ++i)
|
|
|
|
|
{
|
|
|
|
|
std::vector<unsigned char> sub(i, in.end());
|
|
|
|
|
std::vector<unsigned char> subout(sub.size() + AES_BLOCKSIZE);
|
|
|
|
|
int size = enc.Encrypt(&sub[0], sub.size(), &subout[0]);
|
|
|
|
|
if (size != 0)
|
|
|
|
|
{
|
|
|
|
|
subout.resize(size);
|
|
|
|
|
std::vector<unsigned char> subdecrypted(subout.size());
|
|
|
|
|
size = dec.Decrypt(&subout[0], subout.size(), &subdecrypted[0]);
|
|
|
|
|
subdecrypted.resize(size);
|
|
|
|
|
BOOST_CHECK(decrypted.size() == in.size());
|
|
|
|
|
BOOST_CHECK_MESSAGE(subdecrypted == sub, HexStr(subdecrypted) + std::string(" != ") + HexStr(sub));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::string LongTestString(void) {
|
|
|
|
|
std::string ret;
|
|
|
|
|
for (int i=0; i<200000; i++) {
|
|
|
|
@ -304,4 +388,55 @@ BOOST_AUTO_TEST_CASE(aes_testvectors) {
|
|
|
|
|
TestAES256("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4", "f69f2445df4f9b17ad2b417be66c3710", "23304b7a39f9f3ff067d8d8f9e24ecc7");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOST_AUTO_TEST_CASE(aes_cbc_testvectors) {
|
|
|
|
|
|
|
|
|
|
// NIST AES CBC 128-bit encryption test-vectors
|
|
|
|
|
TestAES128CBC("2b7e151628aed2a6abf7158809cf4f3c", "000102030405060708090A0B0C0D0E0F", false, \
|
|
|
|
|
"6bc1bee22e409f96e93d7e117393172a", "7649abac8119b246cee98e9b12e9197d");
|
|
|
|
|
TestAES128CBC("2b7e151628aed2a6abf7158809cf4f3c", "7649ABAC8119B246CEE98E9B12E9197D", false, \
|
|
|
|
|
"ae2d8a571e03ac9c9eb76fac45af8e51", "5086cb9b507219ee95db113a917678b2");
|
|
|
|
|
TestAES128CBC("2b7e151628aed2a6abf7158809cf4f3c", "5086cb9b507219ee95db113a917678b2", false, \
|
|
|
|
|
"30c81c46a35ce411e5fbc1191a0a52ef", "73bed6b8e3c1743b7116e69e22229516");
|
|
|
|
|
TestAES128CBC("2b7e151628aed2a6abf7158809cf4f3c", "73bed6b8e3c1743b7116e69e22229516", false, \
|
|
|
|
|
"f69f2445df4f9b17ad2b417be66c3710", "3ff1caa1681fac09120eca307586e1a7");
|
|
|
|
|
|
|
|
|
|
// The same vectors with padding enabled
|
|
|
|
|
TestAES128CBC("2b7e151628aed2a6abf7158809cf4f3c", "000102030405060708090A0B0C0D0E0F", true, \
|
|
|
|
|
"6bc1bee22e409f96e93d7e117393172a", "7649abac8119b246cee98e9b12e9197d8964e0b149c10b7b682e6e39aaeb731c");
|
|
|
|
|
TestAES128CBC("2b7e151628aed2a6abf7158809cf4f3c", "7649ABAC8119B246CEE98E9B12E9197D", true, \
|
|
|
|
|
"ae2d8a571e03ac9c9eb76fac45af8e51", "5086cb9b507219ee95db113a917678b255e21d7100b988ffec32feeafaf23538");
|
|
|
|
|
TestAES128CBC("2b7e151628aed2a6abf7158809cf4f3c", "5086cb9b507219ee95db113a917678b2", true, \
|
|
|
|
|
"30c81c46a35ce411e5fbc1191a0a52ef", "73bed6b8e3c1743b7116e69e22229516f6eccda327bf8e5ec43718b0039adceb");
|
|
|
|
|
TestAES128CBC("2b7e151628aed2a6abf7158809cf4f3c", "73bed6b8e3c1743b7116e69e22229516", true, \
|
|
|
|
|
"f69f2445df4f9b17ad2b417be66c3710", "3ff1caa1681fac09120eca307586e1a78cb82807230e1321d3fae00d18cc2012");
|
|
|
|
|
|
|
|
|
|
// NIST AES CBC 256-bit encryption test-vectors
|
|
|
|
|
TestAES256CBC("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4", \
|
|
|
|
|
"000102030405060708090A0B0C0D0E0F", false, "6bc1bee22e409f96e93d7e117393172a", \
|
|
|
|
|
"f58c4c04d6e5f1ba779eabfb5f7bfbd6");
|
|
|
|
|
TestAES256CBC("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4", \
|
|
|
|
|
"F58C4C04D6E5F1BA779EABFB5F7BFBD6", false, "ae2d8a571e03ac9c9eb76fac45af8e51", \
|
|
|
|
|
"9cfc4e967edb808d679f777bc6702c7d");
|
|
|
|
|
TestAES256CBC("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4", \
|
|
|
|
|
"9CFC4E967EDB808D679F777BC6702C7D", false, "30c81c46a35ce411e5fbc1191a0a52ef",
|
|
|
|
|
"39f23369a9d9bacfa530e26304231461");
|
|
|
|
|
TestAES256CBC("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4", \
|
|
|
|
|
"39F23369A9D9BACFA530E26304231461", false, "f69f2445df4f9b17ad2b417be66c3710", \
|
|
|
|
|
"b2eb05e2c39be9fcda6c19078c6a9d1b");
|
|
|
|
|
|
|
|
|
|
// The same vectors with padding enabled
|
|
|
|
|
TestAES256CBC("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4", \
|
|
|
|
|
"000102030405060708090A0B0C0D0E0F", true, "6bc1bee22e409f96e93d7e117393172a", \
|
|
|
|
|
"f58c4c04d6e5f1ba779eabfb5f7bfbd6485a5c81519cf378fa36d42b8547edc0");
|
|
|
|
|
TestAES256CBC("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4", \
|
|
|
|
|
"F58C4C04D6E5F1BA779EABFB5F7BFBD6", true, "ae2d8a571e03ac9c9eb76fac45af8e51", \
|
|
|
|
|
"9cfc4e967edb808d679f777bc6702c7d3a3aa5e0213db1a9901f9036cf5102d2");
|
|
|
|
|
TestAES256CBC("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4", \
|
|
|
|
|
"9CFC4E967EDB808D679F777BC6702C7D", true, "30c81c46a35ce411e5fbc1191a0a52ef",
|
|
|
|
|
"39f23369a9d9bacfa530e263042314612f8da707643c90a6f732b3de1d3f5cee");
|
|
|
|
|
TestAES256CBC("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4", \
|
|
|
|
|
"39F23369A9D9BACFA530E26304231461", true, "f69f2445df4f9b17ad2b417be66c3710", \
|
|
|
|
|
"b2eb05e2c39be9fcda6c19078c6a9d1b3f461796d6b0d6b2e0c2a72b4d80e644");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOST_AUTO_TEST_SUITE_END()
|
|
|
|
|