Botan
1.11.15
|
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 }