Coverage Report

Created: 2020-06-30 13:58

/src/botan/src/lib/stream/stream_cipher.cpp
Line
Count
Source (jump to first uncovered line)
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
36
#if defined(BOTAN_HAS_OPENSSL)
37
  #include <botan/internal/openssl.h>
38
#endif
39
40
namespace Botan {
41
42
std::unique_ptr<StreamCipher> StreamCipher::create(const std::string& algo_spec,
43
                                                   const std::string& provider)
44
147
   {
45
147
   const SCAN_Name req(algo_spec);
46
147
47
147
#if defined(BOTAN_HAS_CTR_BE)
48
147
   if((req.algo_name() == "CTR-BE" || req.algo_name() == "CTR") && req.arg_count_between(1,2))
49
0
      {
50
0
      if(provider.empty() || provider == "base")
51
0
         {
52
0
         auto cipher = BlockCipher::create(req.arg(0));
53
0
         if(cipher)
54
0
            {
55
0
            size_t ctr_size = req.arg_as_integer(1, cipher->block_size());
56
0
            return std::unique_ptr<StreamCipher>(new CTR_BE(cipher.release(), ctr_size));
57
0
            }
58
147
         }
59
0
      }
60
147
#endif
61
147
62
147
#if defined(BOTAN_HAS_CHACHA)
63
147
   if(req.algo_name() == "ChaCha")
64
147
      {
65
147
      if(provider.empty() || provider == "base")
66
147
         return std::unique_ptr<StreamCipher>(new ChaCha(req.arg_as_integer(0, 20)));
67
0
      }
68
0
69
0
   if(req.algo_name() == "ChaCha20")
70
0
      {
71
0
      if(provider.empty() || provider == "base")
72
0
         return std::unique_ptr<StreamCipher>(new ChaCha(20));
73
0
      }
74
0
#endif
75
0
76
0
#if defined(BOTAN_HAS_SALSA20)
77
0
   if(req.algo_name() == "Salsa20")
78
0
      {
79
0
      if(provider.empty() || provider == "base")
80
0
         return std::unique_ptr<StreamCipher>(new Salsa20);
81
0
      }
82
0
#endif
83
0
84
0
#if defined(BOTAN_HAS_SHAKE_CIPHER)
85
0
   if(req.algo_name() == "SHAKE-128" || req.algo_name() == "SHAKE-128-XOF")
86
0
      {
87
0
      if(provider.empty() || provider == "base")
88
0
         return std::unique_ptr<StreamCipher>(new SHAKE_128_Cipher);
89
0
      }
90
0
#endif
91
0
92
0
#if defined(BOTAN_HAS_OFB)
93
0
   if(req.algo_name() == "OFB" && req.arg_count() == 1)
94
0
      {
95
0
      if(provider.empty() || provider == "base")
96
0
         {
97
0
         if(auto c = BlockCipher::create(req.arg(0)))
98
0
            return std::unique_ptr<StreamCipher>(new OFB(c.release()));
99
0
         }
100
0
      }
101
0
#endif
102
0
103
0
#if defined(BOTAN_HAS_RC4)
104
0
105
0
   if(req.algo_name() == "RC4" ||
106
0
      req.algo_name() == "ARC4" ||
107
0
      req.algo_name() == "MARK-4")
108
0
      {
109
0
      const size_t skip = (req.algo_name() == "MARK-4") ? 256 : req.arg_as_integer(0, 0);
110
0
111
#if defined(BOTAN_HAS_OPENSSL)
112
      if(provider.empty() || provider == "openssl")
113
         {
114
         return std::unique_ptr<StreamCipher>(make_openssl_rc4(skip));
115
         }
116
#endif
117
118
0
      if(provider.empty() || provider == "base")
119
0
         {
120
0
         return std::unique_ptr<StreamCipher>(new RC4(skip));
121
0
         }
122
0
      }
123
0
124
0
#endif
125
0
126
0
   BOTAN_UNUSED(req);
127
0
   BOTAN_UNUSED(provider);
128
0
129
0
   return nullptr;
130
0
   }
131
132
//static
133
std::unique_ptr<StreamCipher>
134
StreamCipher::create_or_throw(const std::string& algo,
135
                             const std::string& provider)
136
7
   {
137
7
   if(auto sc = StreamCipher::create(algo, provider))
138
7
      {
139
7
      return sc;
140
7
      }
141
0
   throw Lookup_Error("Stream cipher", algo, provider);
142
0
   }
143
144
std::vector<std::string> StreamCipher::providers(const std::string& algo_spec)
145
0
   {
146
0
   return probe_providers_of<StreamCipher>(algo_spec, {"base", "openssl"});
147
0
   }
148
149
}