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

randombit / botan / 5356326050

23 Jun 2023 01:05PM UTC coverage: 91.728% (-0.008%) from 91.736%
5356326050

Pull #3595

github

web-flow
Merge a5b917599 into 92171c524
Pull Request #3595: Improve clang-tidy coverage

78163 of 85212 relevant lines covered (91.73%)

12690161.35 hits per line

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

91.09
/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/internal/fmt.h>
12
#endif
13

14
namespace Botan_Tests {
15

16
#if defined(BOTAN_HAS_BLOCK_CIPHER)
17

18
class Block_Cipher_Tests final : public Text_Based_Test {
×
19
   public:
20
      Block_Cipher_Tests() : Text_Based_Test("block", "Key,In,Out", "Tweak,Iterations") {}
3✔
21

22
      std::vector<std::string> possible_providers(const std::string& algo) override {
14,022✔
23
         return provider_filter(Botan::BlockCipher::providers(algo));
14,022✔
24
      }
25

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

33
         Test::Result result(algo);
28,044✔
34

35
         if(iterations > 1 && run_long_tests() == false) {
14,022✔
36
            return result;
37
         }
38

39
         const std::vector<std::string> providers = possible_providers(algo);
14,022✔
40

41
         if(providers.empty()) {
14,022✔
42
            result.note_missing("block cipher " + algo);
×
43
            return result;
×
44
         }
45

46
         for(const auto& provider_ask : providers) {
28,044✔
47
            auto cipher = Botan::BlockCipher::create(algo, provider_ask);
14,022✔
48

49
            if(!cipher) {
14,022✔
50
               result.test_failure(Botan::fmt("Cipher {} supported by {} but not found", algo, provider_ask));
×
51
               continue;
×
52
            }
53

54
            const std::string provider(cipher->provider());
14,022✔
55
            result.test_is_nonempty("provider", provider);
14,022✔
56
            result.test_eq(provider, cipher->name(), algo);
14,022✔
57
            result.test_gte(provider, cipher->parallelism(), 1);
14,022✔
58
            result.test_gte(provider, cipher->block_size(), 8);
14,022✔
59
            result.test_gte(provider, cipher->parallel_bytes(), cipher->block_size() * cipher->parallelism());
14,022✔
60

61
            result.test_eq("no key set", cipher->has_keying_material(), false);
14,022✔
62

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

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

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

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

96
            cipher->set_key(key);
14,022✔
97
            result.test_eq("key set", cipher->has_keying_material(), true);
14,022✔
98

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

108
            // Test that clone works and does not affect parent object
109
            auto clone = cipher->new_object();
14,022✔
110
            result.confirm("Clone has different pointer", cipher.get() != clone.get());
28,044✔
111
            result.test_eq("Clone has same name", cipher->name(), clone->name());
28,079✔
112
            clone->set_key(Test::rng().random_vec(cipher->maximum_keylength()));
14,022✔
113

114
            // have called set_key on clone: process input values
115
            std::vector<uint8_t> buf = input;
14,022✔
116

117
            for(size_t i = 0; i != iterations; ++i) {
1,028,043✔
118
               cipher->encrypt(buf);
2,028,042✔
119
            }
120

121
            result.test_eq(provider, "encrypt", buf, expected);
14,022✔
122

123
            // always decrypt expected ciphertext vs what we produced above
124
            buf = expected;
14,022✔
125

126
            for(size_t i = 0; i != iterations; ++i) {
1,028,043✔
127
               cipher->decrypt(buf);
2,028,042✔
128
            }
129

130
            result.test_eq(provider, "decrypt", buf, input);
14,022✔
131

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

137
            for(size_t i = 0; i != iterations; ++i) {
1,028,043✔
138
               cipher->encrypt_n(buf.data() + 1, buf.data() + 1, blocks);
1,014,021✔
139
            }
140

141
            result.test_eq(provider.c_str(),
14,022✔
142
                           "encrypt misaligned",
143
                           buf.data() + 1,
14,022✔
144
                           buf.size() - 1,
14,022✔
145
                           expected.data(),
146
                           expected.size());
147

148
            // always decrypt expected ciphertext vs what we produced above
149
            Botan::copy_mem(buf.data() + 1, expected.data(), expected.size());
14,022✔
150

151
            for(size_t i = 0; i != iterations; ++i) {
1,028,043✔
152
               cipher->decrypt_n(buf.data() + 1, buf.data() + 1, blocks);
1,014,021✔
153
            }
154

155
            result.test_eq(
14,022✔
156
               provider.c_str(), "decrypt misaligned", buf.data() + 1, buf.size() - 1, input.data(), input.size());
28,044✔
157

158
            result.test_eq("key set", cipher->has_keying_material(), true);
14,022✔
159
            cipher->clear();
14,022✔
160
            result.test_eq("key set", cipher->has_keying_material(), false);
14,022✔
161

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

170
            try {
14,022✔
171
               std::vector<uint8_t> block(cipher->block_size());
14,022✔
172
               cipher->decrypt(block);
14,022✔
173
               result.test_failure("Was able to decrypt without a key being set");
14,022✔
174
            } catch(Botan::Invalid_State&) {
14,022✔
175
               result.test_success("Trying to decrypt with no key set (after clear) fails");
14,022✔
176
            }
14,022✔
177
         }
56,088✔
178

179
         return result;
180
      }
70,110✔
181
};
182

183
BOTAN_REGISTER_SERIALIZED_SMOKE_TEST("block", "block_ciphers", Block_Cipher_Tests);
184

185
#endif
186

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