• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

randombit / botan / 21768358452

06 Feb 2026 10:35PM UTC coverage: 90.064% (-0.003%) from 90.067%
21768358452

Pull #5289

github

web-flow
Merge f589db195 into 8ea0ca252
Pull Request #5289: Further misc header reductions, forward declarations, etc

102238 of 113517 relevant lines covered (90.06%)

11357432.36 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

97.1
/src/lib/modes/cipher_mode.cpp
1
/*
2
* Cipher Modes
3
* (C) 2015 Jack Lloyd
4
*
5
* Botan is released under the Simplified BSD License (see license.txt)
6
*/
7

8
#include <botan/cipher_mode.h>
9

10
#include <botan/exceptn.h>
11
#include <botan/internal/parsing.h>
12
#include <botan/internal/scan_name.h>
13
#include <botan/internal/stream_mode.h>
14
#include <memory>
15
#include <sstream>
16
#include <utility>
17

18
#if defined(BOTAN_HAS_BLOCK_CIPHER)
19
   #include <botan/block_cipher.h>
20
#endif
21

22
#if defined(BOTAN_HAS_AEAD_MODES)
23
   #include <botan/aead.h>
24
#endif
25

26
#if defined(BOTAN_HAS_MODE_CBC)
27
   #include <botan/internal/cbc.h>
28
#endif
29

30
#if defined(BOTAN_HAS_MODE_CFB)
31
   #include <botan/internal/cfb.h>
32
#endif
33

34
#if defined(BOTAN_HAS_MODE_XTS)
35
   #include <botan/internal/xts.h>
36
#endif
37

38
#if defined(BOTAN_HAS_COMMONCRYPTO)
39
   #include <botan/internal/commoncrypto.h>
40
#endif
41

42
namespace Botan {
43

44
std::unique_ptr<Cipher_Mode> Cipher_Mode::create_or_throw(std::string_view algo,
163✔
45
                                                          Cipher_Dir direction,
46
                                                          std::string_view provider) {
47
   if(auto mode = Cipher_Mode::create(algo, direction, provider)) {
163✔
48
      return mode;
162✔
49
   }
162✔
50

51
   throw Lookup_Error("Cipher mode", algo, provider);
1✔
52
}
53

54
std::unique_ptr<Cipher_Mode> Cipher_Mode::create(std::string_view algo,
13,889✔
55
                                                 Cipher_Dir direction,
56
                                                 std::string_view provider) {
57
#if defined(BOTAN_HAS_COMMONCRYPTO)
58
   if(provider.empty() || provider == "commoncrypto") {
59
      if(auto cm = make_commoncrypto_cipher_mode(algo, direction))
60
         return cm;
61

62
      if(!provider.empty())
63
         return nullptr;
64
   }
65
#endif
66

67
   if(provider != "base" && !provider.empty()) {
21,365✔
68
      return nullptr;
1,250✔
69
   }
70

71
#if defined(BOTAN_HAS_STREAM_CIPHER)
72
   if(auto sc = StreamCipher::create(algo)) {
12,639✔
73
      return std::make_unique<Stream_Cipher_Mode>(std::move(sc));
51✔
74
   }
51✔
75
#endif
76

77
#if defined(BOTAN_HAS_AEAD_MODES)
78
   if(auto aead = AEAD_Mode::create(algo, direction)) {
12,588✔
79
      return aead;
631✔
80
   }
631✔
81
#endif
82

83
   if(algo.find('/') != std::string::npos) {
11,957✔
84
      const std::vector<std::string> algo_parts = split_on(algo, '/');
5,845✔
85
      const std::string_view cipher_name = algo_parts[0];
5,845✔
86
      const std::vector<std::string> mode_info = parse_algorithm_name(algo_parts[1]);
5,845✔
87

88
      if(mode_info.empty()) {
5,845✔
89
         return std::unique_ptr<Cipher_Mode>();
×
90
      }
91

92
      std::ostringstream mode_name;
5,845✔
93

94
      mode_name << mode_info[0] << '(' << cipher_name;
5,845✔
95
      for(size_t i = 1; i < mode_info.size(); ++i) {
6,077✔
96
         mode_name << ',' << mode_info[i];
232✔
97
      }
98
      for(size_t i = 2; i < algo_parts.size(); ++i) {
7,213✔
99
         mode_name << ',' << algo_parts[i];
1,368✔
100
      }
101
      mode_name << ')';
5,845✔
102

103
      return Cipher_Mode::create(mode_name.str(), direction, provider);
5,845✔
104
   }
5,845✔
105

106
#if defined(BOTAN_HAS_BLOCK_CIPHER)
107

108
   const SCAN_Name spec(algo);
6,112✔
109

110
   if(spec.arg_count() == 0) {
6,112✔
111
      return std::unique_ptr<Cipher_Mode>();
1✔
112
   }
113

114
   auto bc = BlockCipher::create(spec.arg(0), provider);
6,111✔
115

116
   if(!bc) {
6,111✔
117
      return std::unique_ptr<Cipher_Mode>();
2✔
118
   }
119

120
   #if defined(BOTAN_HAS_MODE_CBC)
121
   if(spec.algo_name() == "CBC") {
6,109✔
122
      const std::string padding = spec.arg(1, "PKCS7");
2,582✔
123

124
      if(padding == "CTS") {
2,582✔
125
         if(direction == Cipher_Dir::Encryption) {
218✔
126
            return std::make_unique<CTS_Encryption>(std::move(bc));
133✔
127
         } else {
128
            return std::make_unique<CTS_Decryption>(std::move(bc));
85✔
129
         }
130
      } else {
131
         auto pad = BlockCipherModePaddingMethod::create(padding);
2,364✔
132

133
         if(pad) {
2,364✔
134
            if(direction == Cipher_Dir::Encryption) {
2,364✔
135
               return std::make_unique<CBC_Encryption>(std::move(bc), std::move(pad));
1,347✔
136
            } else {
137
               return std::make_unique<CBC_Decryption>(std::move(bc), std::move(pad));
1,017✔
138
            }
139
         }
140
      }
2,364✔
141
   }
2,582✔
142
   #endif
143

144
   #if defined(BOTAN_HAS_MODE_XTS)
145
   if(spec.algo_name() == "XTS") {
3,527✔
146
      if(direction == Cipher_Dir::Encryption) {
2,822✔
147
         return std::make_unique<XTS_Encryption>(std::move(bc));
1,829✔
148
      } else {
149
         return std::make_unique<XTS_Decryption>(std::move(bc));
993✔
150
      }
151
   }
152
   #endif
153

154
   #if defined(BOTAN_HAS_MODE_CFB)
155
   if(spec.algo_name() == "CFB") {
705✔
156
      const size_t feedback_bits = spec.arg_as_integer(1, 8 * bc->block_size());
705✔
157
      if(direction == Cipher_Dir::Encryption) {
705✔
158
         return std::make_unique<CFB_Encryption>(std::move(bc), feedback_bits);
340✔
159
      } else {
160
         return std::make_unique<CFB_Decryption>(std::move(bc), feedback_bits);
365✔
161
      }
162
   }
163
   #endif
164

165
#endif
166

167
   return std::unique_ptr<Cipher_Mode>();
×
168
}
6,112✔
169

170
//static
171
std::vector<std::string> Cipher_Mode::providers(std::string_view algo_spec) {
1,250✔
172
   const std::vector<std::string>& possible = {"base", "commoncrypto"};
1,250✔
173
   std::vector<std::string> providers;
1,250✔
174
   for(auto&& prov : possible) {
3,750✔
175
      auto mode = Cipher_Mode::create(algo_spec, Cipher_Dir::Encryption, prov);
2,500✔
176
      if(mode) {
2,500✔
177
         providers.push_back(prov);  // available
1,248✔
178
      }
179
   }
2,500✔
180
   return providers;
1,250✔
181
}
1,250✔
182

183
}  // namespace Botan
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc