Coverage Report

Created: 2023-01-25 06:35

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