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

randombit / botan / 20579846577

29 Dec 2025 06:24PM UTC coverage: 90.415% (+0.2%) from 90.243%
20579846577

push

github

web-flow
Merge pull request #5167 from randombit/jack/src-size-reductions

Changes to reduce unnecessary inclusions

101523 of 112285 relevant lines covered (90.42%)

12817276.56 hits per line

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

87.13
/src/tests/test_block.cpp
1
/*
2
* (C) 2014,2015 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_BLOCK_CIPHER)
10
   #include <botan/block_cipher.h>
11
   #include <botan/mem_ops.h>
12
   #include <botan/rng.h>
13
   #include <botan/internal/fmt.h>
14
#endif
15

16
namespace Botan_Tests {
17

18
#if defined(BOTAN_HAS_BLOCK_CIPHER)
19

20
class Block_Cipher_Tests final : public Text_Based_Test {
×
21
   public:
22
      Block_Cipher_Tests() : Text_Based_Test("block", "Key,In,Out", "Tweak,Iterations") {}
2✔
23

24
      std::vector<std::string> possible_providers(const std::string& algo) override {
17,513✔
25
         return provider_filter(Botan::BlockCipher::providers(algo));
17,513✔
26
      }
27

28
      Test::Result run_one_test(const std::string& algo, const VarMap& vars) override {
17,513✔
29
         const std::vector<uint8_t> key = vars.get_req_bin("Key");
17,513✔
30
         const std::vector<uint8_t> input = vars.get_req_bin("In");
17,513✔
31
         const std::vector<uint8_t> expected = vars.get_req_bin("Out");
17,513✔
32
         const std::vector<uint8_t> tweak = vars.get_opt_bin("Tweak");
17,513✔
33
         const size_t iterations = vars.get_opt_sz("Iterations", 1);
17,513✔
34

35
         Test::Result result(algo);
35,026✔
36

37
         if(iterations > 1 && run_long_tests() == false) {
17,513✔
38
            return result;
39
         }
40

41
         const std::vector<std::string> providers = possible_providers(algo);
17,513✔
42

43
         if(providers.empty()) {
17,513✔
44
            result.note_missing("block cipher " + algo);
×
45
            return result;
×
46
         }
47

48
         for(const auto& provider_ask : providers) {
35,026✔
49
            auto cipher = Botan::BlockCipher::create(algo, provider_ask);
17,513✔
50

51
            if(!cipher) {
17,513✔
52
               result.test_failure(Botan::fmt("Cipher {} supported by {} but not found", algo, provider_ask));
×
53
               continue;
×
54
            }
55

56
            const std::string provider(cipher->provider());
17,513✔
57
            result.test_is_nonempty("provider", provider);
17,513✔
58
            result.test_eq(provider, cipher->name(), algo);
17,513✔
59
            result.test_gte(provider, cipher->parallelism(), 1);
17,513✔
60
            result.test_gte(provider, cipher->block_size(), 8);
17,513✔
61
            result.test_gte(provider, cipher->parallel_bytes(), cipher->block_size() * cipher->parallelism());
35,026✔
62

63
            result.test_eq("no key set", cipher->has_keying_material(), false);
17,513✔
64

65
            // Test that trying to encrypt or decrypt with no key set throws Botan::Invalid_State
66
            try {
17,513✔
67
               std::vector<uint8_t> block(cipher->block_size());
17,513✔
68
               cipher->encrypt(block);
17,513✔
69
               result.test_failure("Was able to encrypt without a key being set");
×
70
            } catch(Botan::Invalid_State&) {
35,026✔
71
               result.test_success("Trying to encrypt with no key set fails");
17,513✔
72
            }
17,513✔
73

74
            try {
17,513✔
75
               std::vector<uint8_t> block(cipher->block_size());
17,513✔
76
               cipher->decrypt(block);
17,513✔
77
               result.test_failure("Was able to decrypt without a key being set");
×
78
            } catch(Botan::Invalid_State&) {
35,026✔
79
               result.test_success("Trying to encrypt with no key set fails");
17,513✔
80
            }
17,513✔
81

82
            // Test to make sure clear() resets what we need it to
83
            cipher->set_key(this->rng().random_vec(cipher->key_spec().maximum_keylength()));
17,513✔
84
            Botan::secure_vector<uint8_t> garbage = this->rng().random_vec(cipher->block_size());
17,513✔
85
            cipher->encrypt(garbage);
17,513✔
86
            cipher->clear();
17,513✔
87

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

98
            cipher->set_key(key);
17,513✔
99
            result.test_eq("key set", cipher->has_keying_material(), true);
17,513✔
100

101
            if(!tweak.empty()) {
17,513✔
102
               Botan::Tweakable_Block_Cipher* tbc = dynamic_cast<Botan::Tweakable_Block_Cipher*>(cipher.get());
2✔
103
               if(tbc == nullptr) {
2✔
104
                  result.test_failure("Tweak set in test data but cipher is not a Tweakable_Block_Cipher");
×
105
               } else {
106
                  tbc->set_tweak(tweak.data(), tweak.size());
2✔
107
               }
108
            }
109

110
            // Test that clone works and does not affect parent object
111
            auto clone = cipher->new_object();
17,513✔
112
            result.confirm("Clone has different pointer", cipher.get() != clone.get());
35,026✔
113
            result.test_eq("Clone has same name", cipher->name(), clone->name());
35,026✔
114
            clone->set_key(this->rng().random_vec(cipher->maximum_keylength()));
17,513✔
115

116
            // have called set_key on clone: process input values
117
            std::vector<uint8_t> buf = input;
17,513✔
118

119
            for(size_t i = 0; i != iterations; ++i) {
1,035,025✔
120
               cipher->encrypt(buf);
2,035,024✔
121
            }
122

123
            result.test_eq(provider, "encrypt", buf, expected);
35,026✔
124

125
            // always decrypt expected ciphertext vs what we produced above
126
            buf = expected;
17,513✔
127

128
            for(size_t i = 0; i != iterations; ++i) {
1,035,025✔
129
               cipher->decrypt(buf);
2,035,024✔
130
            }
131

132
            result.test_eq(provider, "decrypt", buf, input);
35,026✔
133

134
            // Now test misaligned buffers
135
            const size_t blocks = input.size() / cipher->block_size();
17,513✔
136
            buf.resize(input.size() + 1);
17,513✔
137
            Botan::copy_mem(buf.data() + 1, input.data(), input.size());
17,513✔
138

139
            for(size_t i = 0; i != iterations; ++i) {
1,035,025✔
140
               cipher->encrypt_n(buf.data() + 1, buf.data() + 1, blocks);
1,017,512✔
141
            }
142

143
            result.test_eq(provider.c_str(),
17,513✔
144
                           "encrypt misaligned",
145
                           buf.data() + 1,
17,513✔
146
                           buf.size() - 1,
17,513✔
147
                           expected.data(),
148
                           expected.size());
149

150
            // always decrypt expected ciphertext vs what we produced above
151
            Botan::copy_mem(buf.data() + 1, expected.data(), expected.size());
17,513✔
152

153
            for(size_t i = 0; i != iterations; ++i) {
1,035,025✔
154
               cipher->decrypt_n(buf.data() + 1, buf.data() + 1, blocks);
1,017,512✔
155
            }
156

157
            result.test_eq(
17,513✔
158
               provider.c_str(), "decrypt misaligned", buf.data() + 1, buf.size() - 1, input.data(), input.size());
17,513✔
159

160
            result.test_eq("key set", cipher->has_keying_material(), true);
17,513✔
161
            cipher->clear();
17,513✔
162
            result.test_eq("key set", cipher->has_keying_material(), false);
17,513✔
163

164
            try {
17,513✔
165
               std::vector<uint8_t> block(cipher->block_size());
17,513✔
166
               cipher->encrypt(block);
17,513✔
167
               result.test_failure("Was able to encrypt without a key being set");
×
168
            } catch(Botan::Invalid_State&) {
35,026✔
169
               result.test_success("Trying to encrypt with no key set (after clear) fails");
17,513✔
170
            }
17,513✔
171

172
            try {
17,513✔
173
               std::vector<uint8_t> block(cipher->block_size());
17,513✔
174
               cipher->decrypt(block);
17,513✔
175
               result.test_failure("Was able to decrypt without a key being set");
×
176
            } catch(Botan::Invalid_State&) {
35,026✔
177
               result.test_success("Trying to decrypt with no key set (after clear) fails");
17,513✔
178
            }
17,513✔
179
         }
70,052✔
180

181
         return result;
182
      }
17,513✔
183
};
184

185
BOTAN_REGISTER_SERIALIZED_SMOKE_TEST("block", "block_ciphers", Block_Cipher_Tests);
186

187
#endif
188

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

© 2026 Coveralls, Inc