Botan  1.11.15
src/lib/modes/cipher_mode.cpp
Go to the documentation of this file.
00001 /*
00002 * Cipher Modes
00003 * (C) 2015 Jack Lloyd
00004 *
00005 * Botan is released under the Simplified BSD License (see license.txt)
00006 */
00007 
00008 #include <botan/cipher_mode.h>
00009 #include <botan/stream_mode.h>
00010 #include <botan/lookup.h>
00011 #include <sstream>
00012 
00013 namespace Botan {
00014 
00015 Cipher_Mode* get_cipher_mode(const std::string& algo_spec, Cipher_Dir direction)
00016    {
00017    const std::string provider = "";
00018 
00019    const char* dir_string = (direction == ENCRYPTION) ? "_Encryption" : "_Decryption";
00020 
00021    std::unique_ptr<Transform> t;
00022 
00023    t.reset(get_transform(algo_spec, provider, dir_string));
00024 
00025    if(Cipher_Mode* cipher = dynamic_cast<Cipher_Mode*>(t.get()))
00026       {
00027       t.release();
00028       return cipher;
00029       }
00030 
00031    const std::vector<std::string> algo_parts = split_on(algo_spec, '/');
00032    if(algo_parts.size() < 2)
00033       return nullptr;
00034 
00035    const std::string cipher_name = algo_parts[0];
00036    const std::vector<std::string> mode_info = parse_algorithm_name(algo_parts[1]);
00037 
00038    if(mode_info.empty())
00039       return nullptr;
00040 
00041    std::ostringstream alg_args;
00042 
00043    alg_args << '(' << cipher_name;
00044    for(size_t i = 1; i < mode_info.size(); ++i)
00045       alg_args << ',' << mode_info[i];
00046    for(size_t i = 2; i < algo_parts.size(); ++i)
00047       alg_args << ',' << algo_parts[i];
00048    alg_args << ')';
00049 
00050    const std::string mode_name = mode_info[0] + alg_args.str();
00051    const std::string mode_name_directional = mode_info[0] + dir_string + alg_args.str();
00052 
00053    t.reset(get_transform(mode_name_directional, provider));
00054 
00055    if(Cipher_Mode* cipher = dynamic_cast<Cipher_Mode*>(t.get()))
00056       {
00057       t.release();
00058       return cipher;
00059       }
00060 
00061    t.reset(get_transform(mode_name, provider));
00062 
00063    if(Cipher_Mode* cipher = dynamic_cast<Cipher_Mode*>(t.get()))
00064       {
00065       t.release();
00066       return cipher;
00067       }
00068 
00069    if(StreamCipher* stream_cipher = get_stream_cipher(mode_name, provider))
00070       return new Stream_Cipher_Mode(stream_cipher);
00071 
00072    return nullptr;
00073    }
00074 
00075 }