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

randombit / botan / 5123321399

30 May 2023 04:06PM UTC coverage: 92.213% (+0.004%) from 92.209%
5123321399

Pull #3558

github

web-flow
Merge dd72f7389 into 057bcbc35
Pull Request #3558: Add braces around all if/else statements

75602 of 81986 relevant lines covered (92.21%)

11859779.3 hits per line

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

90.6
/src/tests/test_stream.cpp
1
/*
2
* (C) 2014,2015,2016 Jack Lloyd
3
*
4
* Botan is released under the Simplified BSD License (see license.txt)
5
*/
6

7
#include "tests.h"
8

9
#if defined(BOTAN_HAS_STREAM_CIPHER)
10
   #include <botan/stream_cipher.h>
11
#endif
12

13
namespace Botan_Tests {
14

15
#if defined(BOTAN_HAS_STREAM_CIPHER)
16

17
class Stream_Cipher_Tests final : public Text_Based_Test {
×
18
   public:
19
      Stream_Cipher_Tests() : Text_Based_Test("stream", "Key,Out", "In,Nonce,Seek") {}
2✔
20

21
      Test::Result run_one_test(const std::string& algo, const VarMap& vars) override {
3,538✔
22
         const std::vector<uint8_t> key = vars.get_req_bin("Key");
3,538✔
23
         const std::vector<uint8_t> expected = vars.get_req_bin("Out");
3,538✔
24
         const std::vector<uint8_t> nonce = vars.get_opt_bin("Nonce");
3,538✔
25
         const uint64_t seek = vars.get_opt_u64("Seek", 0);
3,538✔
26
         std::vector<uint8_t> input = vars.get_opt_bin("In");
3,538✔
27

28
         if(input.empty()) {
3,538✔
29
            input.resize(expected.size());
2,664✔
30
         }
31

32
         Test::Result result(algo);
7,076✔
33

34
         const std::vector<std::string> providers = provider_filter(Botan::StreamCipher::providers(algo));
3,538✔
35

36
         if(providers.empty()) {
3,538✔
37
            result.note_missing("stream cipher " + algo);
1✔
38
            return result;
1✔
39
         }
40

41
         for(const auto& provider_ask : providers) {
7,074✔
42
            auto cipher = Botan::StreamCipher::create(algo, provider_ask);
3,537✔
43

44
            if(!cipher) {
3,537✔
45
               result.test_failure("Stream " + algo + " supported by " + provider_ask + " but not found");
×
46
               continue;
×
47
            }
48

49
            const std::string provider(cipher->provider());
3,537✔
50
            result.test_is_nonempty("provider", provider);
3,537✔
51
            result.test_eq(provider, cipher->name(), algo);
3,537✔
52

53
            result.confirm("default iv length is valid", cipher->valid_iv_length(cipher->default_iv_length()));
7,074✔
54

55
            result.confirm("advertised buffer size is > 0", cipher->buffer_size() > 0);
7,074✔
56

57
            if(cipher->default_iv_length() == 0) {
3,537✔
58
               result.confirm("if default iv length is zero, no iv supported", nonce.empty());
4,730✔
59

60
               // This should still succeed
61
               cipher->set_iv(nullptr, 0);
2,365✔
62
            }
63

64
            try {
3,537✔
65
               std::vector<uint8_t> buf(128);
3,537✔
66
               cipher->cipher1(buf.data(), buf.size());
3,537✔
67
               result.test_failure("Was able to encrypt without a key being set");
3,537✔
68
            } catch(Botan::Invalid_State&) { result.test_success("Trying to encrypt with no key set fails"); }
7,074✔
69

70
            try {
3,537✔
71
               cipher->seek(0);
3,537✔
72
               result.test_failure("Was able to seek without a key being set");
×
73
            } catch(Botan::Invalid_State&) {
3,537✔
74
               result.test_success("Trying to seek with no key set fails");
1,155✔
75
            } catch(Botan::Not_Implemented&) { result.test_success("Trying to seek failed because not implemented"); }
5,919✔
76

77
            if(!cipher->valid_iv_length(nonce.size())) {
3,537✔
78
               throw Test_Error("Invalid nonce for " + algo);
×
79
            }
80

81
            bool accepted_nonce_early = false;
3,537✔
82
            if(!nonce.empty()) {
3,537✔
83
               try {
1,168✔
84
                  cipher->set_iv(nonce.data(), nonce.size());
1,168✔
85
                  accepted_nonce_early = true;
86
               } catch(Botan::Invalid_State&) {}
1,168✔
87
            }
88

89
            /*
90
            * Different providers may have additional restrictions on key sizes.
91
            * Avoid testing the cipher with a key size that it does not natively support.
92
            */
93
            if(!cipher->valid_keylength(key.size())) {
3,537✔
94
               result.test_note("Skipping test with provider " + provider + " as it does not support key length " +
×
95
                                std::to_string(key.size()));
×
96
               continue;
×
97
            }
98

99
            result.test_eq("key not set", cipher->has_keying_material(), false);
3,537✔
100
            cipher->set_key(key);
3,537✔
101
            result.test_eq("key set", cipher->has_keying_material(), true);
3,537✔
102

103
            /*
104
            Test invalid nonce sizes. this assumes no implemented cipher supports a nonce of 65000
105
            */
106
            const size_t large_nonce_size = 65000;
3,537✔
107
            result.confirm("Stream cipher does not support very large nonce",
7,074✔
108
                           cipher->valid_iv_length(large_nonce_size) == false);
3,537✔
109

110
            result.test_throws("Throws if invalid nonce size given",
7,074✔
111
                               [&]() { cipher->set_iv(nullptr, large_nonce_size); });
3,537✔
112

113
            /*
114
            If the set_nonce call earlier succeded, then we require that it also
115
            worked (ie saved the nonce for later use) even though the key was
116
            not set. So, don't set the nonce now, to ensure the previous call
117
            had an effect.
118
            */
119
            if(!nonce.empty() && accepted_nonce_early == false) {
3,537✔
120
               cipher->set_iv(nonce.data(), nonce.size());
1,168✔
121
            }
122

123
            if(seek != 0) {
3,537✔
124
               cipher->seek(seek);
626✔
125
            }
126

127
            // Test that clone works and does not affect parent object
128
            auto clone = cipher->new_object();
3,537✔
129
            result.confirm("Clone has different pointer", cipher.get() != clone.get());
7,074✔
130
            result.test_eq("Clone has same name", cipher->name(), clone->name());
7,292✔
131
            clone->set_key(Test::rng().random_vec(cipher->maximum_keylength()));
3,537✔
132

133
            {
3,537✔
134
               std::vector<uint8_t> buf = input;
3,537✔
135
               cipher->encrypt(buf);
3,537✔
136
               result.test_eq(provider, "encrypt", buf, expected);
7,074✔
137
            }
×
138

139
            {
3,537✔
140
               if(nonce.empty()) {
3,537✔
141
                  cipher->set_key(key);
2,369✔
142
               } else {
143
                  cipher->set_iv(nonce.data(), nonce.size());
1,168✔
144
               }
145
               if(seek != 0) {
3,537✔
146
                  cipher->seek(seek);
626✔
147
               }
148
               std::vector<uint8_t> buf = input;
3,537✔
149
               cipher->encrypt(buf);
3,537✔
150
               result.test_eq(provider, "encrypt 2", buf, expected);
7,074✔
151
            }
×
152

153
            if(!nonce.empty()) {
3,537✔
154
               cipher->set_iv(nonce.data(), nonce.size());
1,168✔
155
               if(seek != 0) {
1,168✔
156
                  cipher->seek(seek);
626✔
157
               }
158
               std::vector<uint8_t> buf = input;
1,168✔
159
               cipher->encrypt(buf);
1,168✔
160
               result.test_eq(provider, "second encrypt", buf, expected);
2,336✔
161
            }
1,168✔
162

163
            {
3,537✔
164
               cipher->set_key(key);
3,537✔
165

166
               cipher->set_iv(nonce.data(), nonce.size());
3,537✔
167

168
               if(seek != 0) {
3,537✔
169
                  cipher->seek(seek);
626✔
170
               }
171

172
               std::vector<uint8_t> buf(input.size(), 0xAB);
3,537✔
173

174
               uint8_t* buf_ptr = buf.data();
175
               size_t buf_len = buf.size();
3,537✔
176

177
               while(buf_len > 0) {
8,981✔
178
                  size_t next = std::min<size_t>(buf_len, rng().next_byte());
5,444✔
179
                  cipher->write_keystream(buf_ptr, next);
5,444✔
180
                  buf_ptr += next;
5,444✔
181
                  buf_len -= next;
5,444✔
182
               }
183

184
               for(size_t i = 0; i != input.size(); ++i) {
340,721✔
185
                  buf[i] ^= input[i];
337,184✔
186
               }
187
               result.test_eq(provider, "write_keystream", buf, expected);
7,074✔
188
            }
×
189

190
            result.test_eq("key set", cipher->has_keying_material(), true);
3,537✔
191
            cipher->clear();
3,537✔
192
            result.test_eq("key not set", cipher->has_keying_material(), false);
3,537✔
193

194
            try {
3,537✔
195
               std::vector<uint8_t> buf(128);
3,537✔
196
               cipher->cipher1(buf.data(), buf.size());
3,537✔
197
               result.test_failure("Was able to encrypt without a key being set (after clear)");
3,537✔
198
            } catch(Botan::Invalid_State&) {
3,537✔
199
               result.test_success("Trying to encrypt with no key set (after clear) fails");
3,537✔
200
            }
3,537✔
201
         }
7,074✔
202

203
         return result;
204
      }
15,321✔
205
};
206

207
BOTAN_REGISTER_SERIALIZED_SMOKE_TEST("stream", "stream_ciphers", Stream_Cipher_Tests);
208

209
#endif
210

211
}  // namespace Botan_Tests
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