Botan 2.13.0 Crypto and TLS for C++11

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

cipher_mode.cpp
Go to the documentation of this file.
1 /*
2 * Cipher Modes
3 * (C) 2015 Jack Lloyd
4 *
5 * Botan is released under the Simplified BSD License (see license.txt)
6 */
7
8 #include <botan/cipher_mode.h>
9 #include <botan/stream_mode.h>
10 #include <botan/scan_name.h>
11 #include <botan/parsing.h>
12 #include <sstream>
13
14 #if defined(BOTAN_HAS_BLOCK_CIPHER)
15 #include <botan/block_cipher.h>
16 #endif
17
18 #if defined(BOTAN_HAS_AEAD_MODES)
19 #include <botan/aead.h>
20 #endif
21
22 #if defined(BOTAN_HAS_MODE_CBC)
23 #include <botan/cbc.h>
24 #endif
25
26 #if defined(BOTAN_HAS_MODE_CFB)
27 #include <botan/cfb.h>
28 #endif
29
30 #if defined(BOTAN_HAS_MODE_XTS)
31 #include <botan/xts.h>
32 #endif
33
34 #if defined(BOTAN_HAS_OPENSSL)
35 #include <botan/internal/openssl.h>
36 #endif
37
38 #if defined(BOTAN_HAS_COMMONCRYPTO)
39 #include <botan/internal/commoncrypto.h>
40 #endif
41
42 namespace Botan {
43
44 std::unique_ptr<Cipher_Mode> Cipher_Mode::create_or_throw(const std::string& algo,
45 Cipher_Dir direction,
46 const std::string& provider)
47 {
48 if(auto mode = Cipher_Mode::create(algo, direction, provider))
49 return mode;
50
51 throw Lookup_Error("Cipher mode", algo, provider);
52 }
53
54 std::unique_ptr<Cipher_Mode> Cipher_Mode::create(const std::string& algo,
55 Cipher_Dir direction,
56 const std::string& provider)
57 {
58 #if defined(BOTAN_HAS_COMMONCRYPTO)
59 if(provider.empty() || provider == "commoncrypto")
60 {
61 std::unique_ptr<Cipher_Mode> commoncrypto_cipher(make_commoncrypto_cipher_mode(algo, direction));
62
63 if(commoncrypto_cipher)
64 return commoncrypto_cipher;
65
66 if(!provider.empty())
67 return std::unique_ptr<Cipher_Mode>();
68 }
69 #endif
70
71 #if defined(BOTAN_HAS_OPENSSL)
72 if(provider.empty() || provider == "openssl")
73 {
74 std::unique_ptr<Cipher_Mode> openssl_cipher(make_openssl_cipher_mode(algo, direction));
75
76 if(openssl_cipher)
77 return openssl_cipher;
78
79 if(!provider.empty())
80 return std::unique_ptr<Cipher_Mode>();
81 }
82 #endif
83
84 #if defined(BOTAN_HAS_STREAM_CIPHER)
85 if(auto sc = StreamCipher::create(algo))
86 {
87 return std::unique_ptr<Cipher_Mode>(new Stream_Cipher_Mode(sc.release()));
88 }
89 #endif
90
91 #if defined(BOTAN_HAS_AEAD_MODES)
92 if(auto aead = AEAD_Mode::create(algo, direction))
93 {
94 return std::unique_ptr<Cipher_Mode>(aead.release());
95 }
96 #endif
97
98 if(algo.find('/') != std::string::npos)
99 {
100 const std::vector<std::string> algo_parts = split_on(algo, '/');
101 const std::string cipher_name = algo_parts[0];
102 const std::vector<std::string> mode_info = parse_algorithm_name(algo_parts[1]);
103
104 if(mode_info.empty())
105 return std::unique_ptr<Cipher_Mode>();
106
107 std::ostringstream alg_args;
108
109 alg_args << '(' << cipher_name;
110 for(size_t i = 1; i < mode_info.size(); ++i)
111 alg_args << ',' << mode_info[i];
112 for(size_t i = 2; i < algo_parts.size(); ++i)
113 alg_args << ',' << algo_parts[i];
114 alg_args << ')';
115
116 const std::string mode_name = mode_info[0] + alg_args.str();
117 return Cipher_Mode::create(mode_name, direction, provider);
118 }
119
120 #if defined(BOTAN_HAS_BLOCK_CIPHER)
121
122 SCAN_Name spec(algo);
123
124 if(spec.arg_count() == 0)
125 {
126 return std::unique_ptr<Cipher_Mode>();
127 }
128
129 std::unique_ptr<BlockCipher> bc(BlockCipher::create(spec.arg(0), provider));
130
131 if(!bc)
132 {
133 return std::unique_ptr<Cipher_Mode>();
134 }
135
136 #if defined(BOTAN_HAS_MODE_CBC)
137 if(spec.algo_name() == "CBC")
138 {
139 const std::string padding = spec.arg(1, "PKCS7");
140
141 if(padding == "CTS")
142 {
143 if(direction == ENCRYPTION)
144 return std::unique_ptr<Cipher_Mode>(new CTS_Encryption(bc.release()));
145 else
146 return std::unique_ptr<Cipher_Mode>(new CTS_Decryption(bc.release()));
147 }
148 else
149 {
150 std::unique_ptr<BlockCipherModePaddingMethod> pad(get_bc_pad(padding));
151
152 if(pad)
153 {
154 if(direction == ENCRYPTION)
155 return std::unique_ptr<Cipher_Mode>(new CBC_Encryption(bc.release(), pad.release()));
156 else
157 return std::unique_ptr<Cipher_Mode>(new CBC_Decryption(bc.release(), pad.release()));
158 }
159 }
160 }
161 #endif
162
163 #if defined(BOTAN_HAS_MODE_XTS)
164 if(spec.algo_name() == "XTS")
165 {
166 if(direction == ENCRYPTION)
167 return std::unique_ptr<Cipher_Mode>(new XTS_Encryption(bc.release()));
168 else
169 return std::unique_ptr<Cipher_Mode>(new XTS_Decryption(bc.release()));
170 }
171 #endif
172
173 #if defined(BOTAN_HAS_MODE_CFB)
174 if(spec.algo_name() == "CFB")
175 {
176 const size_t feedback_bits = spec.arg_as_integer(1, 8*bc->block_size());
177 if(direction == ENCRYPTION)
178 return std::unique_ptr<Cipher_Mode>(new CFB_Encryption(bc.release(), feedback_bits));
179 else
180 return std::unique_ptr<Cipher_Mode>(new CFB_Decryption(bc.release(), feedback_bits));
181 }
182 #endif
183
184 #endif
185
186 return std::unique_ptr<Cipher_Mode>();
187 }
188
189 //static
190 std::vector<std::string> Cipher_Mode::providers(const std::string& algo_spec)
191 {
192 const std::vector<std::string>& possible = { "base", "openssl", "commoncrypto" };
193 std::vector<std::string> providers;
194 for(auto&& prov : possible)
195 {
196 std::unique_ptr<Cipher_Mode> mode = Cipher_Mode::create(algo_spec, ENCRYPTION, prov);
197 if(mode)
198 {
199 providers.push_back(prov); // available
200 }
201 }
202 return providers;
203 }
204
205 }
Botan::SCAN_Name::arg
std::string arg(size_t i) const
Definition: scan_name.cpp:124
Botan::Lookup_Error
Definition: exceptn.h:247
Botan::split_on
std::vector< std::string > split_on(const std::string &str, char delim)
Definition: parsing.cpp:148
Botan::XTS_Encryption
Definition: xts.h:68
Botan::XTS_Decryption
Definition: xts.h:86
Botan::SCAN_Name::arg_count
size_t arg_count() const
Definition: scan_name.h:56
Botan::CTS_Decryption
Definition: cbc.h:140
Botan::make_openssl_cipher_mode
Cipher_Mode * make_openssl_cipher_mode(const std::string &name, Cipher_Dir direction)
Definition: openssl_mode.cpp:215
Botan::CTS_Encryption
Definition: cbc.h:93
Botan::CBC_Decryption
Definition: cbc.h:113
Botan::CBC_Encryption
Definition: cbc.h:71
Botan::Cipher_Mode::provider
virtual std::string provider() const
Definition: cipher_mode.h:180
Botan::Usage_Type::ENCRYPTION
Botan::AEAD_Mode::create
static std::unique_ptr< AEAD_Mode > create(const std::string &algo, Cipher_Dir direction, const std::string &provider="")
Definition: aead.cpp:52
Botan::SCAN_Name::arg_as_integer
size_t arg_as_integer(size_t i, size_t def_value) const
Definition: scan_name.cpp:139
Botan::parse_algorithm_name
std::vector< std::string > parse_algorithm_name(const std::string &namex)
Definition: parsing.cpp:95
Botan
Definition: alg_id.cpp:13
Botan::SCAN_Name
Definition: scan_name.h:23
Botan::BlockCipher::create
static std::unique_ptr< BlockCipher > create(const std::string &algo_spec, const std::string &provider="")
Definition: block_cipher.cpp:108
Botan::Cipher_Mode::create
static std::unique_ptr< Cipher_Mode > create(const std::string &algo, Cipher_Dir direction, const std::string &provider="")
Definition: cipher_mode.cpp:54
Botan::SCAN_Name::algo_name
const std::string & algo_name() const
Definition: scan_name.h:51
Botan::Cipher_Dir
Cipher_Dir
Definition: cipher_mode.h:23
Botan::Cipher_Mode::providers
static std::vector< std::string > providers(const std::string &algo_spec)
Definition: cipher_mode.cpp:190
Botan::StreamCipher::create
static std::unique_ptr< StreamCipher > create(const std::string &algo_spec, const std::string &provider="")
Definition: stream_cipher.cpp:42
Botan::CFB_Decryption
Definition: cfb.h:87
Botan::Cipher_Mode::create_or_throw
static std::unique_ptr< Cipher_Mode > create_or_throw(const std::string &algo, Cipher_Dir direction, const std::string &provider="")
Definition: cipher_mode.cpp:44
Botan::CFB_Encryption
Definition: cfb.h:67
Botan::make_commoncrypto_cipher_mode
Cipher_Mode * make_commoncrypto_cipher_mode(const std::string &name, Cipher_Dir direction)
Definition: commoncrypto_mode.cpp:235
Botan::get_bc_pad
BlockCipherModePaddingMethod * get_bc_pad(const std::string &algo_spec)
Definition: mode_pad.cpp:18