Botan  2.6.0
Crypto and TLS for C++11
stream_cipher.cpp
Go to the documentation of this file.
1 /*
2 * Stream Ciphers
3 * (C) 2015,2016 Jack Lloyd
4 *
5 * Botan is released under the Simplified BSD License (see license.txt)
6 */
7 
8 #include <botan/stream_cipher.h>
9 #include <botan/scan_name.h>
10 
11 #if defined(BOTAN_HAS_CHACHA)
12  #include <botan/chacha.h>
13 #endif
14 
15 #if defined(BOTAN_HAS_SALSA20)
16  #include <botan/salsa20.h>
17 #endif
18 
19 #if defined(BOTAN_HAS_SHAKE_CIPHER)
20  #include <botan/shake_cipher.h>
21 #endif
22 
23 #if defined(BOTAN_HAS_CTR_BE)
24  #include <botan/ctr.h>
25 #endif
26 
27 #if defined(BOTAN_HAS_OFB)
28  #include <botan/ofb.h>
29 #endif
30 
31 #if defined(BOTAN_HAS_RC4)
32  #include <botan/rc4.h>
33 #endif
34 
35 #if defined(BOTAN_HAS_OPENSSL)
36  #include <botan/internal/openssl.h>
37 #endif
38 
39 namespace Botan {
40 
41 std::unique_ptr<StreamCipher> StreamCipher::create(const std::string& algo_spec,
42  const std::string& provider)
43  {
44  const SCAN_Name req(algo_spec);
45 
46 #if defined(BOTAN_HAS_CTR_BE)
47  if((req.algo_name() == "CTR-BE" || req.algo_name() == "CTR") && req.arg_count_between(1,2))
48  {
49  if(provider.empty() || provider == "base")
50  {
51  auto cipher = BlockCipher::create(req.arg(0));
52  if(cipher)
53  {
54  size_t ctr_size = req.arg_as_integer(1, cipher->block_size());
55  return std::unique_ptr<StreamCipher>(new CTR_BE(cipher.release(), ctr_size));
56  }
57  }
58  }
59 #endif
60 
61 #if defined(BOTAN_HAS_CHACHA)
62  if(req.algo_name() == "ChaCha")
63  {
64  if(provider.empty() || provider == "base")
65  return std::unique_ptr<StreamCipher>(new ChaCha(req.arg_as_integer(0, 20)));
66  }
67 
68  if(req.algo_name() == "ChaCha20")
69  {
70  if(provider.empty() || provider == "base")
71  return std::unique_ptr<StreamCipher>(new ChaCha(20));
72  }
73 #endif
74 
75 #if defined(BOTAN_HAS_SALSA20)
76  if(req.algo_name() == "Salsa20")
77  {
78  if(provider.empty() || provider == "base")
79  return std::unique_ptr<StreamCipher>(new Salsa20);
80  }
81 #endif
82 
83 #if defined(BOTAN_HAS_SHAKE_CIPHER)
84  if(req.algo_name() == "SHAKE-128")
85  {
86  if(provider.empty() || provider == "base")
87  return std::unique_ptr<StreamCipher>(new SHAKE_128_Cipher);
88  }
89 #endif
90 
91 #if defined(BOTAN_HAS_OFB)
92  if(req.algo_name() == "OFB" && req.arg_count() == 1)
93  {
94  if(provider.empty() || provider == "base")
95  {
96  if(auto c = BlockCipher::create(req.arg(0)))
97  return std::unique_ptr<StreamCipher>(new OFB(c.release()));
98  }
99  }
100 #endif
101 
102 #if defined(BOTAN_HAS_RC4)
103 
104  if(req.algo_name() == "RC4" ||
105  req.algo_name() == "ARC4" ||
106  req.algo_name() == "MARK-4")
107  {
108  const size_t skip = (req.algo_name() == "MARK-4") ? 256 : req.arg_as_integer(0, 0);
109 
110 #if defined(BOTAN_HAS_OPENSSL)
111  if(provider.empty() || provider == "openssl")
112  {
113  return std::unique_ptr<StreamCipher>(make_openssl_rc4(skip));
114  }
115 #endif
116 
117  if(provider.empty() || provider == "base")
118  {
119  return std::unique_ptr<StreamCipher>(new RC4(skip));
120  }
121  }
122 
123 #endif
124 
125  BOTAN_UNUSED(req);
127 
128  return nullptr;
129  }
130 
131 //static
132 std::unique_ptr<StreamCipher>
133 StreamCipher::create_or_throw(const std::string& algo,
134  const std::string& provider)
135  {
136  if(auto sc = StreamCipher::create(algo, provider))
137  {
138  return sc;
139  }
140  throw Lookup_Error("Stream cipher", algo, provider);
141  }
142 
143 std::vector<std::string> StreamCipher::providers(const std::string& algo_spec)
144  {
145  return probe_providers_of<StreamCipher>(algo_spec, {"base", "openssl"});
146  }
147 
148 }
size_t arg_count() const
Definition: scan_name.h:49
static std::unique_ptr< StreamCipher > create_or_throw(const std::string &algo_spec, const std::string &provider="")
Definition: ofb.h:19
size_t arg_as_integer(size_t i, size_t def_value) const
Definition: scan_name.cpp:137
virtual void cipher(const uint8_t in[], uint8_t out[], size_t len)=0
virtual std::string provider() const
std::string arg(size_t i) const
Definition: scan_name.cpp:122
Definition: rc4.h:19
Definition: alg_id.cpp:13
static std::vector< std::string > providers(const std::string &algo_spec)
#define BOTAN_UNUSED(...)
Definition: assert.h:117
static std::unique_ptr< BlockCipher > create(const std::string &algo_spec, const std::string &provider="")
const std::string & algo_name() const
Definition: scan_name.h:44
bool arg_count_between(size_t lower, size_t upper) const
Definition: scan_name.h:56
static std::unique_ptr< StreamCipher > create(const std::string &algo_spec, const std::string &provider="")