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