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

randombit / botan / 5134090420

31 May 2023 03:12PM UTC coverage: 91.721% (-0.3%) from 91.995%
5134090420

push

github

randombit
Merge GH #3565 Disable noisy/pointless pylint warnings

76048 of 82912 relevant lines covered (91.72%)

11755290.1 hits per line

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

89.35
/src/tests/test_ocb.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_AEAD_OCB)
10
   #include <botan/block_cipher.h>
11
   #include <botan/internal/loadstor.h>
12
   #include <botan/internal/ocb.h>
13
   #include <botan/internal/poly_dbl.h>
14
#endif
15

16
namespace Botan_Tests {
17

18
namespace {
19

20
#if defined(BOTAN_HAS_AEAD_OCB)
21

22
// Toy cipher used for wide block tests
23

24
class OCB_Wide_Test_Block_Cipher final : public Botan::BlockCipher {
25
   public:
26
      explicit OCB_Wide_Test_Block_Cipher(size_t bs) : m_bs(bs) {}
24✔
27

28
      std::string name() const override { return "OCB_ToyCipher"; }
×
29

30
      size_t block_size() const override { return m_bs; }
11,967✔
31

32
      void clear() override { m_key.clear(); }
×
33

34
      std::unique_ptr<Botan::BlockCipher> new_object() const override {
×
35
         return std::make_unique<OCB_Wide_Test_Block_Cipher>(m_bs);
×
36
      }
37

38
      bool has_keying_material() const override { return !m_key.empty(); }
5,712✔
39

40
      void key_schedule(const uint8_t key[], size_t length) override { m_key.assign(key, key + length); }
24✔
41

42
      Botan::Key_Length_Specification key_spec() const override { return Botan::Key_Length_Specification(m_bs); }
48✔
43

44
      void encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override {
10,257✔
45
         while(blocks) {
21,620✔
46
            Botan::copy_mem(out, in, m_bs);
11,363✔
47
            Botan::poly_double_n(out, m_bs);
11,363✔
48

49
            for(size_t i = 0; i != m_bs; ++i) {
335,667✔
50
               out[i] ^= m_key[i];
324,304✔
51
            }
52

53
            blocks--;
11,363✔
54
            in += block_size();
11,363✔
55
            out += block_size();
11,363✔
56
         }
57
      }
10,257✔
58

59
      void decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override {
6✔
60
         while(blocks) {
14✔
61
            for(size_t i = 0; i != m_bs; ++i) {
200✔
62
               out[i] = in[i] ^ m_key[i];
192✔
63
            }
64

65
            uint8_t carry = in[m_bs - 1] & 0x01;
8✔
66

67
            if(carry) {
8✔
68
               if(m_bs == 16 || m_bs == 24) {
7✔
69
                  out[m_bs - 1] ^= 0x87;
7✔
70
               } else if(m_bs == 32) {
×
71
                  out[m_bs - 2] ^= 0x4;
×
72
                  out[m_bs - 1] ^= 0x25;
×
73
               } else if(m_bs == 64) {
×
74
                  out[m_bs - 2] ^= 0x1;
×
75
                  out[m_bs - 1] ^= 0x25;
×
76
               } else {
77
                  throw Test_Error("Bad OCB test block size");
×
78
               }
79
            }
80

81
            carry <<= 7;
8✔
82

83
            for(size_t i = 0; i != m_bs; ++i) {
200✔
84
               const uint8_t temp = out[i];
192✔
85
               out[i] = (temp >> 1) | carry;
192✔
86
               carry = (temp & 0x1);
192✔
87
               carry <<= 7;
192✔
88
            }
89

90
            blocks--;
8✔
91
            in += block_size();
8✔
92
            out += block_size();
8✔
93
         }
94
      }
6✔
95

96
   private:
97
      size_t m_bs;
98
      std::vector<uint8_t> m_key;
99
};
100

101
class OCB_Wide_KAT_Tests final : public Text_Based_Test {
×
102
   public:
103
      OCB_Wide_KAT_Tests() : Text_Based_Test("ocb/ocb_wide.vec", "Key,Nonce,AD,In,Out") {}
3✔
104

105
      Test::Result run_one_test(const std::string& /*header*/, const VarMap& vars) override {
10✔
106
         Test::Result result("OCB wide block KAT");
10✔
107

108
         const std::vector<uint8_t> key = vars.get_req_bin("Key");
10✔
109
         const std::vector<uint8_t> nonce = vars.get_req_bin("Nonce");
10✔
110
         const std::vector<uint8_t> ad = vars.get_req_bin("AD");
10✔
111
         const std::vector<uint8_t> input = vars.get_req_bin("In");
10✔
112
         const std::vector<uint8_t> expected = vars.get_req_bin("Out");
10✔
113

114
         const size_t bs = key.size();
10✔
115
         Botan::secure_vector<uint8_t> buf(input.begin(), input.end());
10✔
116

117
         Botan::OCB_Encryption enc(std::make_unique<OCB_Wide_Test_Block_Cipher>(bs), std::min<size_t>(bs, 32));
20✔
118
         enc.set_key(key);
10✔
119
         enc.set_associated_data(ad);
10✔
120
         enc.start(nonce);
10✔
121
         enc.finish(buf);
10✔
122
         result.test_eq("Ciphertext matches", buf, expected);
10✔
123

124
         Botan::OCB_Decryption dec(std::make_unique<OCB_Wide_Test_Block_Cipher>(bs), std::min<size_t>(bs, 32));
20✔
125
         dec.set_key(key);
10✔
126
         dec.set_associated_data(ad);
10✔
127
         dec.start(nonce);
10✔
128
         dec.finish(buf);
10✔
129
         result.test_eq("Decryption correct", buf, input);
10✔
130

131
         return result;
10✔
132
      }
70✔
133
};
134

135
BOTAN_REGISTER_TEST("modes", "ocb_wide", OCB_Wide_KAT_Tests);
136

137
class OCB_Wide_Long_KAT_Tests final : public Text_Based_Test {
×
138
   public:
139
      OCB_Wide_Long_KAT_Tests() : Text_Based_Test("ocb/ocb_wide_long.vec", "Output") {}
2✔
140

141
      Test::Result run_one_test(const std::string& algo, const VarMap& vars) override {
5✔
142
         Test::Result result("OCB wide block long test");
5✔
143

144
         const std::vector<uint8_t> expected = vars.get_req_bin("Output");
5✔
145

146
         std::unique_ptr<Botan::BlockCipher> cipher;
5✔
147
         size_t bs = 0;
5✔
148

149
         if(algo == "SHACAL2") {
5✔
150
   #if defined(BOTAN_HAS_SHACAL2)
151
            cipher = Botan::BlockCipher::create_or_throw("SHACAL2");
1✔
152
            bs = 32;
1✔
153
   #else
154
            return {result};
155
   #endif
156
         } else {
157
            if(algo == "Toy128") {
4✔
158
               bs = 16;
1✔
159
            } else if(algo == "Toy192") {
3✔
160
               bs = 24;
1✔
161
            } else if(algo == "Toy256") {
2✔
162
               bs = 32;
1✔
163
            } else if(algo == "Toy512") {
1✔
164
               bs = 64;
1✔
165
            } else {
166
               throw Test_Error("Unknown cipher for OCB wide block long test");
×
167
            }
168
            cipher = std::make_unique<OCB_Wide_Test_Block_Cipher>(bs);
4✔
169
         }
170

171
         Botan::OCB_Encryption enc(std::move(cipher), std::min<size_t>(bs, 32));
6✔
172

173
         /*
174
         Y, string of length min(B, 256) bits
175

176
         Y is defined as follows.
177

178
         K = (0xA0 || 0xA1 || 0xA2 || ...)[1..B]
179
         C = <empty string>
180
         for i = 0 to 127 do
181
           S = (0x50 || 0x51 || 0x52 || ...)[1..8i]
182
           N = num2str(3i+1,16)
183
           C = C || OCB-ENCRYPT(K,N,S,S)
184
           N = num2str(3i+2,16)
185
           C = C || OCB-ENCRYPT(K,N,<empty string>,S)
186
           N = num2str(3i+3,16)
187
           C = C || OCB-ENCRYPT(K,N,S,<empty string>)
188
         end for
189
         N = num2str(385,16)
190
         Y = OCB-ENCRYPT(K,N,C,<empty string>)
191
         */
192

193
         std::vector<uint8_t> key(bs);
5✔
194
         for(size_t i = 0; i != bs; ++i) {
173✔
195
            key[i] = static_cast<uint8_t>(0xA0 + i);
168✔
196
         }
197

198
         enc.set_key(key);
5✔
199

200
         const std::vector<uint8_t> empty;
5✔
201
         std::vector<uint8_t> N(2);
5✔
202
         std::vector<uint8_t> C;
5✔
203

204
         for(size_t i = 0; i != 128; ++i) {
645✔
205
            std::vector<uint8_t> S(i);
640✔
206
            for(size_t j = 0; j != S.size(); ++j) {
41,280✔
207
               S[j] = static_cast<uint8_t>(0x50 + j);
40,640✔
208
            }
209

210
            Botan::store_be(static_cast<uint16_t>(3 * i + 1), &N[0]);
640✔
211

212
            ocb_encrypt(result, C, enc, N, S, S);
640✔
213
            Botan::store_be(static_cast<uint16_t>(3 * i + 2), &N[0]);
640✔
214
            ocb_encrypt(result, C, enc, N, S, empty);
640✔
215
            Botan::store_be(static_cast<uint16_t>(3 * i + 3), &N[0]);
640✔
216
            ocb_encrypt(result, C, enc, N, empty, S);
640✔
217
         }
640✔
218

219
         Botan::store_be(static_cast<uint16_t>(385), &N[0]);
5✔
220
         std::vector<uint8_t> final_result;
5✔
221
         ocb_encrypt(result, final_result, enc, N, empty, C);
5✔
222

223
         result.test_eq("correct value", final_result, expected);
5✔
224

225
         return result;
5✔
226
      }
25✔
227

228
   private:
229
      static void ocb_encrypt(Test::Result& /*result*/,
1,925✔
230
                              std::vector<uint8_t>& output_to,
231
                              Botan::OCB_Encryption& enc,
232
                              const std::vector<uint8_t>& nonce,
233
                              const std::vector<uint8_t>& pt,
234
                              const std::vector<uint8_t>& ad) {
235
         enc.set_associated_data(ad.data(), ad.size());
1,925✔
236
         enc.start(nonce.data(), nonce.size());
1,925✔
237
         Botan::secure_vector<uint8_t> buf(pt.begin(), pt.end());
1,925✔
238
         enc.finish(buf, 0);
1,925✔
239
         output_to.insert(output_to.end(), buf.begin(), buf.end());
1,925✔
240
      }
1,925✔
241
};
242

243
BOTAN_REGISTER_TEST("modes", "ocb_long_wide", OCB_Wide_Long_KAT_Tests);
244

245
   #if defined(BOTAN_HAS_AES)
246

247
class OCB_Long_KAT_Tests final : public Text_Based_Test {
×
248
   public:
249
      OCB_Long_KAT_Tests() : Text_Based_Test("ocb/ocb_long.vec", "Keylen,Taglen,Output") {}
3✔
250

251
      Test::Result run_one_test(const std::string& /*header*/, const VarMap& vars) override {
9✔
252
         const size_t keylen = vars.get_req_sz("Keylen");
9✔
253
         const size_t taglen = vars.get_req_sz("Taglen");
9✔
254
         const std::vector<uint8_t> expected = vars.get_req_bin("Output");
9✔
255

256
         // Test from RFC 7253 Appendix A
257

258
         const std::string algo = "AES-" + std::to_string(keylen);
9✔
259

260
         Test::Result result("OCB long");
9✔
261

262
         auto aes = Botan::BlockCipher::create_or_throw(algo);
9✔
263

264
         Botan::OCB_Encryption enc(aes->new_object(), taglen / 8);
9✔
265
         Botan::OCB_Decryption dec(std::move(aes), taglen / 8);
9✔
266

267
         std::vector<uint8_t> key(keylen / 8);
9✔
268
         key[keylen / 8 - 1] = static_cast<uint8_t>(taglen);
9✔
269

270
         enc.set_key(key);
9✔
271
         dec.set_key(key);
9✔
272

273
         const std::vector<uint8_t> empty;
9✔
274
         std::vector<uint8_t> N(12);
9✔
275
         std::vector<uint8_t> C;
9✔
276

277
         for(size_t i = 0; i != 128; ++i) {
1,161✔
278
            const std::vector<uint8_t> S(i);
1,152✔
279

280
            Botan::store_be(static_cast<uint32_t>(3 * i + 1), &N[8]);
1,152✔
281

282
            ocb_encrypt(result, C, enc, dec, N, S, S);
1,152✔
283
            Botan::store_be(static_cast<uint32_t>(3 * i + 2), &N[8]);
1,152✔
284
            ocb_encrypt(result, C, enc, dec, N, S, empty);
1,152✔
285
            Botan::store_be(static_cast<uint32_t>(3 * i + 3), &N[8]);
1,152✔
286
            ocb_encrypt(result, C, enc, dec, N, empty, S);
1,152✔
287
         }
1,152✔
288

289
         Botan::store_be(static_cast<uint32_t>(385), &N[8]);
9✔
290
         std::vector<uint8_t> final_result;
9✔
291
         ocb_encrypt(result, final_result, enc, dec, N, empty, C);
9✔
292

293
         result.test_eq("correct value", final_result, expected);
9✔
294

295
         return result;
9✔
296
      }
45✔
297

298
   private:
299
      static void ocb_encrypt(Test::Result& result,
3,465✔
300
                              std::vector<uint8_t>& output_to,
301
                              Botan::AEAD_Mode& enc,
302
                              Botan::AEAD_Mode& dec,
303
                              const std::vector<uint8_t>& nonce,
304
                              const std::vector<uint8_t>& pt,
305
                              const std::vector<uint8_t>& ad) {
306
         enc.set_associated_data(ad.data(), ad.size());
3,465✔
307

308
         enc.start(nonce.data(), nonce.size());
3,465✔
309

310
         Botan::secure_vector<uint8_t> buf(pt.begin(), pt.end());
3,465✔
311
         enc.finish(buf, 0);
3,465✔
312
         output_to.insert(output_to.end(), buf.begin(), buf.end());
3,465✔
313

314
         try {
3,465✔
315
            dec.set_associated_data(ad.data(), ad.size());
3,465✔
316

317
            dec.start(nonce.data(), nonce.size());
3,465✔
318

319
            dec.finish(buf, 0);
3,465✔
320

321
            result.test_eq("OCB round tripped", buf, pt);
6,930✔
322
         } catch(std::exception& e) {
×
323
            result.test_failure("OCB round trip error", e.what());
×
324
         }
×
325
      }
3,465✔
326
};
327

328
BOTAN_REGISTER_TEST("modes", "ocb_long", OCB_Long_KAT_Tests);
329

330
   #endif
331

332
#endif
333

334
}  // namespace
335

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