#include "botan-1.6/include/eng_def.h"
#include "botan-1.6/include/parsing.h"
#include "botan-1.6/include/filters.h"
#include "botan-1.6/include/lookup.h"
#include "botan-1.6/include/ecb.h"
#include "botan-1.6/include/cbc.h"
namespace Enctain {
namespace Botan {
Keyed_Filter* Default_Engine::get_cipher(const std::string& algo_spec,
Cipher_Dir direction)
{
std::vector<std::string> algo_parts = split_on(algo_spec, '/');
if(algo_parts.empty())
throw Invalid_Algorithm_Name(algo_spec);
const std::string cipher = algo_parts[0];
if(have_stream_cipher(cipher))
{
if(algo_parts.size() == 1)
return new StreamCipher_Filter(cipher);
return 0;
}
else if(have_block_cipher(cipher))
{
if(algo_parts.size() != 2 && algo_parts.size() != 3)
return 0;
std::string mode = algo_parts[1];
u32bit bits = 0;
if(mode.find("CFB") != std::string::npos ||
mode.find("EAX") != std::string::npos)
{
std::vector<std::string> algo_info = parse_algorithm_name(mode);
mode = algo_info[0];
if(algo_info.size() == 1)
bits = 8*block_size_of(cipher);
else if(algo_info.size() == 2)
bits = to_u32bit(algo_info[1]);
else
throw Invalid_Algorithm_Name(algo_spec);
}
std::string padding;
if(algo_parts.size() == 3)
padding = algo_parts[2];
else
padding = (mode == "CBC") ? "PKCS7" : "NoPadding";
if(mode == "ECB" && padding == "CTS")
return 0;
else if((mode != "CBC" && mode != "ECB") && padding != "NoPadding")
throw Invalid_Algorithm_Name(algo_spec);
if(mode == "ECB" || mode == "CBC"
)
{
if(mode == "ECB")
{
if(direction == ENCRYPTION)
return new ECB_Encryption(cipher, padding);
else
return new ECB_Decryption(cipher, padding);
}
else if(mode == "CBC")
{
if(direction == ENCRYPTION)
return new CBC_Encryption(cipher, padding);
else
return new CBC_Decryption(cipher, padding);
}
else
throw Internal_Error("get_mode: " + cipher + "/"
+ mode + "/" + padding);
}
else
return 0;
}
return 0;
}
}
}