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

randombit / botan / 13274522654

11 Feb 2025 11:26PM UTC coverage: 91.645% (-0.007%) from 91.652%
13274522654

push

github

web-flow
Merge pull request #4647 from randombit/jack/internal-assert-and-mem-ops

Avoid using mem_ops.h or assert.h in public headers

94854 of 103501 relevant lines covered (91.65%)

11334975.77 hits per line

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

90.74
/src/lib/stream/stream_cipher.cpp
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

10
#include <botan/exceptn.h>
11
#include <botan/mem_ops.h>
12
#include <botan/internal/scan_name.h>
13

14
#if defined(BOTAN_HAS_CHACHA)
15
   #include <botan/internal/chacha.h>
16
#endif
17

18
#if defined(BOTAN_HAS_SALSA20)
19
   #include <botan/internal/salsa20.h>
20
#endif
21

22
#if defined(BOTAN_HAS_SHAKE_CIPHER)
23
   #include <botan/internal/shake_cipher.h>
24
#endif
25

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

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

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

38
namespace Botan {
39

40
std::unique_ptr<StreamCipher> StreamCipher::create(std::string_view algo_spec, std::string_view provider) {
44,206✔
41
#if defined(BOTAN_HAS_SHAKE_CIPHER)
42
   if(algo_spec == "SHAKE-128" || algo_spec == "SHAKE-128-XOF") {
49,756✔
43
      if(provider.empty() || provider == "base") {
4,580✔
44
         return std::make_unique<SHAKE_128_Cipher>();
2,290✔
45
      }
46
   }
47

48
   if(algo_spec == "SHAKE-256" || algo_spec == "SHAKE-256-XOF") {
45,176✔
49
      if(provider.empty() || provider == "base") {
4,580✔
50
         return std::make_unique<SHAKE_256_Cipher>();
2,290✔
51
      }
52
   }
53
#endif
54

55
#if defined(BOTAN_HAS_CHACHA)
56
   if(algo_spec == "ChaCha20") {
39,734✔
57
      if(provider.empty() || provider == "base") {
6✔
58
         return std::make_unique<ChaCha>(20);
3✔
59
      }
60
   }
61
#endif
62

63
#if defined(BOTAN_HAS_SALSA20)
64
   if(algo_spec == "Salsa20") {
39,765✔
65
      if(provider.empty() || provider == "base") {
56✔
66
         return std::make_unique<Salsa20>();
32✔
67
      }
68
   }
69
#endif
70

71
   const SCAN_Name req(algo_spec);
39,591✔
72

73
#if defined(BOTAN_HAS_CTR_BE)
74
   if((req.algo_name() == "CTR-BE" || req.algo_name() == "CTR") && req.arg_count_between(1, 2)) {
39,591✔
75
      if(provider.empty() || provider == "base") {
5,940✔
76
         auto cipher = BlockCipher::create(req.arg(0));
4,301✔
77
         if(cipher) {
4,301✔
78
            size_t ctr_size = req.arg_as_integer(1, cipher->block_size());
4,300✔
79
            return std::make_unique<CTR_BE>(std::move(cipher), ctr_size);
4,300✔
80
         }
81
      }
4,301✔
82
   }
83
#endif
84

85
#if defined(BOTAN_HAS_CHACHA)
86
   if(req.algo_name() == "ChaCha") {
35,291✔
87
      if(provider.empty() || provider == "base") {
16,635✔
88
         return std::make_unique<ChaCha>(req.arg_as_integer(0, 20));
15,987✔
89
      }
90
   }
91
#endif
92

93
#if defined(BOTAN_HAS_OFB)
94
   if(req.algo_name() == "OFB" && req.arg_count() == 1) {
19,304✔
95
      if(provider.empty() || provider == "base") {
68✔
96
         if(auto cipher = BlockCipher::create(req.arg(0))) {
68✔
97
            return std::make_unique<OFB>(std::move(cipher));
34✔
98
         }
34✔
99
      }
100
   }
101
#endif
102

103
#if defined(BOTAN_HAS_RC4)
104

105
   if(req.algo_name() == "RC4" || req.algo_name() == "ARC4" || req.algo_name() == "MARK-4") {
19,270✔
106
      const size_t skip = (req.algo_name() == "MARK-4") ? 256 : req.arg_as_integer(0, 0);
152✔
107

108
      if(provider.empty() || provider == "base") {
302✔
109
         return std::make_unique<RC4>(skip);
152✔
110
      }
111
   }
112

113
#endif
114

115
   BOTAN_UNUSED(req);
19,118✔
116
   BOTAN_UNUSED(provider);
19,118✔
117

118
   return nullptr;
19,118✔
119
}
39,591✔
120

121
//static
122
std::unique_ptr<StreamCipher> StreamCipher::create_or_throw(std::string_view algo, std::string_view provider) {
4,774✔
123
   if(auto sc = StreamCipher::create(algo, provider)) {
4,774✔
124
      return sc;
4,774✔
125
   }
4,774✔
126
   throw Lookup_Error("Stream cipher", algo, provider);
×
127
}
128

129
std::vector<std::string> StreamCipher::providers(std::string_view algo_spec) {
3,547✔
130
   return probe_providers_of<StreamCipher>(algo_spec);
3,547✔
131
}
132

133
void StreamCipher::cipher(std::span<const uint8_t> in, std::span<uint8_t> out) {
×
134
   BOTAN_ARG_CHECK(in.size() <= out.size(), "Output buffer of stream cipher must be at least as long as input buffer");
×
135
   cipher_bytes(in.data(), out.data(), in.size());
×
136
}
×
137

138
size_t StreamCipher::default_iv_length() const {
4,730✔
139
   return 0;
4,730✔
140
}
141

142
void StreamCipher::generate_keystream(uint8_t out[], size_t len) {
386✔
143
   clear_mem(out, len);
386✔
144
   cipher1(out, len);
386✔
145
}
386✔
146

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