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