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

randombit / botan / 11336383167

14 Oct 2024 11:16PM UTC coverage: 91.121% (+0.001%) from 91.12%
11336383167

push

github

web-flow
Merge pull request #4369 from randombit/jack/refactor-speed-algos

Refactor performance testing of symmetric algorithms

90097 of 98876 relevant lines covered (91.12%)

9212419.84 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/internal/parsing.h>
11
#include <botan/internal/scan_name.h>
12
#include <botan/internal/stream_mode.h>
13
#include <sstream>
14

15
#if defined(BOTAN_HAS_BLOCK_CIPHER)
16
   #include <botan/block_cipher.h>
17
#endif
18

19
#if defined(BOTAN_HAS_AEAD_MODES)
20
   #include <botan/aead.h>
21
#endif
22

23
#if defined(BOTAN_HAS_MODE_CBC)
24
   #include <botan/internal/cbc.h>
25
#endif
26

27
#if defined(BOTAN_HAS_MODE_CFB)
28
   #include <botan/internal/cfb.h>
29
#endif
30

31
#if defined(BOTAN_HAS_MODE_XTS)
32
   #include <botan/internal/xts.h>
33
#endif
34

35
#if defined(BOTAN_HAS_COMMONCRYPTO)
36
   #include <botan/internal/commoncrypto.h>
37
#endif
38

39
namespace Botan {
40

41
std::unique_ptr<Cipher_Mode> Cipher_Mode::create_or_throw(std::string_view algo,
165✔
42
                                                          Cipher_Dir direction,
43
                                                          std::string_view provider) {
44
   if(auto mode = Cipher_Mode::create(algo, direction, provider)) {
165✔
45
      return mode;
164✔
46
   }
164✔
47

48
   throw Lookup_Error("Cipher mode", algo, provider);
1✔
49
}
50

51
std::unique_ptr<Cipher_Mode> Cipher_Mode::create(std::string_view algo,
20,074✔
52
                                                 Cipher_Dir direction,
53
                                                 std::string_view provider) {
54
#if defined(BOTAN_HAS_COMMONCRYPTO)
55
   if(provider.empty() || provider == "commoncrypto") {
56
      if(auto cm = make_commoncrypto_cipher_mode(algo, direction))
57
         return cm;
58

59
      if(!provider.empty())
60
         return nullptr;
61
   }
62
#endif
63

64
   if(provider != "base" && !provider.empty()) {
27,544✔
65
      return nullptr;
1,249✔
66
   }
67

68
#if defined(BOTAN_HAS_STREAM_CIPHER)
69
   if(auto sc = StreamCipher::create(algo)) {
18,825✔
70
      return std::make_unique<Stream_Cipher_Mode>(std::move(sc));
51✔
71
   }
51✔
72
#endif
73

74
#if defined(BOTAN_HAS_AEAD_MODES)
75
   if(auto aead = AEAD_Mode::create(algo, direction)) {
18,774✔
76
      return aead;
3,857✔
77
   }
3,857✔
78
#endif
79

80
   if(algo.find('/') != std::string::npos) {
14,917✔
81
      const std::vector<std::string> algo_parts = split_on(algo, '/');
7,331✔
82
      std::string_view cipher_name = algo_parts[0];
7,331✔
83
      const std::vector<std::string> mode_info = parse_algorithm_name(algo_parts[1]);
7,331✔
84

85
      if(mode_info.empty()) {
7,331✔
86
         return std::unique_ptr<Cipher_Mode>();
×
87
      }
88

89
      std::ostringstream mode_name;
7,331✔
90

91
      mode_name << mode_info[0] << '(' << cipher_name;
7,331✔
92
      for(size_t i = 1; i < mode_info.size(); ++i) {
7,563✔
93
         mode_name << ',' << mode_info[i];
232✔
94
      }
95
      for(size_t i = 2; i < algo_parts.size(); ++i) {
8,995✔
96
         mode_name << ',' << algo_parts[i];
1,664✔
97
      }
98
      mode_name << ')';
7,331✔
99

100
      return Cipher_Mode::create(mode_name.str(), direction, provider);
7,331✔
101
   }
7,331✔
102

103
#if defined(BOTAN_HAS_BLOCK_CIPHER)
104

105
   SCAN_Name spec(algo);
7,586✔
106

107
   if(spec.arg_count() == 0) {
7,586✔
108
      return std::unique_ptr<Cipher_Mode>();
1✔
109
   }
110

111
   auto bc = BlockCipher::create(spec.arg(0), provider);
7,585✔
112

113
   if(!bc) {
7,585✔
114
      return std::unique_ptr<Cipher_Mode>();
2✔
115
   }
116

117
   #if defined(BOTAN_HAS_MODE_CBC)
118
   if(spec.algo_name() == "CBC") {
7,583✔
119
      const std::string padding = spec.arg(1, "PKCS7");
2,715✔
120

121
      if(padding == "CTS") {
2,715✔
122
         if(direction == Cipher_Dir::Encryption) {
240✔
123
            return std::make_unique<CTS_Encryption>(std::move(bc));
144✔
124
         } else {
125
            return std::make_unique<CTS_Decryption>(std::move(bc));
96✔
126
         }
127
      } else {
128
         auto pad = BlockCipherModePaddingMethod::create(padding);
2,475✔
129

130
         if(pad) {
2,475✔
131
            if(direction == Cipher_Dir::Encryption) {
2,475✔
132
               return std::make_unique<CBC_Encryption>(std::move(bc), std::move(pad));
1,401✔
133
            } else {
134
               return std::make_unique<CBC_Decryption>(std::move(bc), std::move(pad));
1,074✔
135
            }
136
         }
137
      }
2,475✔
138
   }
2,715✔
139
   #endif
140

141
   #if defined(BOTAN_HAS_MODE_XTS)
142
   if(spec.algo_name() == "XTS") {
4,868✔
143
      if(direction == Cipher_Dir::Encryption) {
4,175✔
144
         return std::make_unique<XTS_Encryption>(std::move(bc));
2,505✔
145
      } else {
146
         return std::make_unique<XTS_Decryption>(std::move(bc));
1,670✔
147
      }
148
   }
149
   #endif
150

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

162
#endif
163

164
   return std::unique_ptr<Cipher_Mode>();
×
165
}
7,586✔
166

167
//static
168
std::vector<std::string> Cipher_Mode::providers(std::string_view algo_spec) {
1,249✔
169
   const std::vector<std::string>& possible = {"base", "commoncrypto"};
1,249✔
170
   std::vector<std::string> providers;
1,249✔
171
   for(auto&& prov : possible) {
3,747✔
172
      auto mode = Cipher_Mode::create(algo_spec, Cipher_Dir::Encryption, prov);
2,498✔
173
      if(mode) {
2,498✔
174
         providers.push_back(prov);  // available
1,247✔
175
      }
176
   }
2,498✔
177
   return providers;
1,249✔
178
}
1,249✔
179

180
}  // 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

© 2025 Coveralls, Inc