Coverage Report

Created: 2022-06-23 06:44

/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
66
   {
41
66
   const SCAN_Name req(algo_spec);
42
43
66
#if defined(BOTAN_HAS_CTR_BE)
44
66
   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
66
#endif
57
58
66
#if defined(BOTAN_HAS_CHACHA)
59
66
   if(req.algo_name() == "ChaCha")
60
66
      {
61
66
      if(provider.empty() || provider == "base")
62
66
         return std::make_unique<ChaCha>(req.arg_as_integer(0, 20));
63
66
      }
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
0
#endif
87
88
0
#if defined(BOTAN_HAS_OFB)
89
0
   if(req.algo_name() == "OFB" && req.arg_count() == 1)
90
0
      {
91
0
      if(provider.empty() || provider == "base")
92
0
         {
93
0
         if(auto cipher = BlockCipher::create(req.arg(0)))
94
0
            return std::make_unique<OFB>(std::move(cipher));
95
0
         }
96
0
      }
97
0
#endif
98
99
0
#if defined(BOTAN_HAS_RC4)
100
101
0
   if(req.algo_name() == "RC4" ||
102
0
      req.algo_name() == "ARC4" ||
103
0
      req.algo_name() == "MARK-4")
104
0
      {
105
0
      const size_t skip = (req.algo_name() == "MARK-4") ? 256 : req.arg_as_integer(0, 0);
106
107
0
      if(provider.empty() || provider == "base")
108
0
         {
109
0
         return std::make_unique<RC4>(skip);
110
0
         }
111
0
      }
112
113
0
#endif
114
115
0
   BOTAN_UNUSED(req);
116
0
   BOTAN_UNUSED(provider);
117
118
0
   return nullptr;
119
0
   }
120
121
//static
122
std::unique_ptr<StreamCipher>
123
StreamCipher::create_or_throw(const std::string& algo,
124
                             const std::string& provider)
125
7
   {
126
7
   if(auto sc = StreamCipher::create(algo, provider))
127
7
      {
128
7
      return sc;
129
7
      }
130
0
   throw Lookup_Error("Stream cipher", algo, provider);
131
7
   }
132
133
std::vector<std::string> StreamCipher::providers(const std::string& algo_spec)
134
0
   {
135
0
   return probe_providers_of<StreamCipher>(algo_spec);
136
0
   }
137
138
}