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

randombit / botan / 5079590438

25 May 2023 12:28PM UTC coverage: 92.228% (+0.5%) from 91.723%
5079590438

Pull #3502

github

Pull Request #3502: Apply clang-format to the codebase

75589 of 81959 relevant lines covered (92.23%)

12139530.51 hits per line

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

90.68
/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
               if(seek != 0)
3,537✔
145
                  cipher->seek(seek);
626✔
146
               std::vector<uint8_t> buf = input;
3,537✔
147
               cipher->encrypt(buf);
3,537✔
148
               result.test_eq(provider, "encrypt 2", buf, expected);
7,074✔
149
            }
×
150

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

160
            {
3,537✔
161
               cipher->set_key(key);
3,537✔
162

163
               cipher->set_iv(nonce.data(), nonce.size());
3,537✔
164

165
               if(seek != 0)
3,537✔
166
                  cipher->seek(seek);
626✔
167

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

170
               uint8_t* buf_ptr = buf.data();
3,537✔
171
               size_t buf_len = buf.size();
3,537✔
172

173
               while(buf_len > 0) {
8,918✔
174
                  size_t next = std::min<size_t>(buf_len, rng().next_byte());
5,381✔
175
                  cipher->write_keystream(buf_ptr, next);
5,381✔
176
                  buf_ptr += next;
5,381✔
177
                  buf_len -= next;
5,381✔
178
               }
179

180
               for(size_t i = 0; i != input.size(); ++i)
340,721✔
181
                  buf[i] ^= input[i];
337,184✔
182
               result.test_eq(provider, "write_keystream", buf, expected);
7,074✔
183
            }
×
184

185
            result.test_eq("key set", cipher->has_keying_material(), true);
3,537✔
186
            cipher->clear();
3,537✔
187
            result.test_eq("key not set", cipher->has_keying_material(), false);
3,537✔
188

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

198
         return result;
199
      }
15,321✔
200
};
201

202
BOTAN_REGISTER_SERIALIZED_SMOKE_TEST("stream", "stream_ciphers", Stream_Cipher_Tests);
203

204
#endif
205

206
}
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