• 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

98.91
/src/lib/modes/aead/eax/eax.cpp
1
/*
2
* EAX Mode Encryption
3
* (C) 1999-2007 Jack Lloyd
4
* (C) 2016 Daniel Neus, Rohde & Schwarz Cybersecurity
5
*
6
* Botan is released under the Simplified BSD License (see license.txt)
7
*/
8

9
#include <botan/internal/eax.h>
10

11
#include <botan/internal/cmac.h>
12
#include <botan/internal/ctr.h>
13
#include <botan/internal/fmt.h>
14

15
namespace Botan {
16

17
namespace {
18

19
/*
20
* EAX MAC-based PRF
21
*/
22
secure_vector<uint8_t> eax_prf(
6,380✔
23
   uint8_t tag, size_t block_size, MessageAuthenticationCode& mac, const uint8_t in[], size_t length) {
24
   for(size_t i = 0; i != block_size - 1; ++i) {
89,584✔
25
      mac.update(0);
83,281✔
26
   }
27
   mac.update(tag);
6,303✔
28
   mac.update(in, length);
6,296✔
29
   return mac.final();
5,853✔
30
}
31

32
}
33

34
/*
35
* EAX_Mode Constructor
36
*/
37
EAX_Mode::EAX_Mode(std::unique_ptr<BlockCipher> cipher, size_t tag_size) :
1,149✔
38
      m_tag_size(tag_size),
1,149✔
39
      m_cipher(std::move(cipher)),
1,149✔
40
      m_ctr(std::make_unique<CTR_BE>(m_cipher->new_object())),
1,149✔
41
      m_cmac(std::make_unique<CMAC>(m_cipher->new_object())) {
2,298✔
42
   if(m_tag_size < 8 || m_tag_size > m_cmac->output_length())
1,149✔
43
      throw Invalid_Argument(fmt("Tag size {} is not allowed for {}", tag_size, name()));
×
44
}
1,149✔
45

46
void EAX_Mode::clear() {
384✔
47
   m_cipher->clear();
384✔
48
   m_ctr->clear();
384✔
49
   m_cmac->clear();
384✔
50
   reset();
384✔
51
}
384✔
52

53
void EAX_Mode::reset() {
2,423✔
54
   m_ad_mac.clear();
2,423✔
55
   m_nonce_mac.clear();
2,423✔
56

57
   // Clear out any data added to the CMAC calculation
58
   try {
2,423✔
59
      m_cmac->final();
4,462✔
60
   } catch(Key_Not_Set&) {}
384✔
61
}
2,423✔
62

63
std::string EAX_Mode::name() const { return (m_cipher->name() + "/EAX"); }
382✔
64

65
size_t EAX_Mode::update_granularity() const { return 1; }
1,329✔
66

67
size_t EAX_Mode::ideal_granularity() const { return m_cipher->parallel_bytes(); }
1,146✔
68

69
Key_Length_Specification EAX_Mode::key_spec() const { return m_ctr->key_spec(); }
775✔
70

71
bool EAX_Mode::has_keying_material() const { return m_ctr->has_keying_material() && m_cmac->has_keying_material(); }
1,337✔
72

73
/*
74
* Set the EAX key
75
*/
76
void EAX_Mode::key_schedule(const uint8_t key[], size_t length) {
770✔
77
   /*
78
   * These could share the key schedule, which is one nice part of EAX,
79
   * but it's much easier to ignore that here...
80
   */
81
   m_ctr->set_key(key, length);
770✔
82
   m_cmac->set_key(key, length);
770✔
83
}
770✔
84

85
/*
86
* Set the EAX associated data
87
*/
88
void EAX_Mode::set_associated_data_n(size_t idx, std::span<const uint8_t> ad) {
3,819✔
89
   BOTAN_ARG_CHECK(idx == 0, "EAX: cannot handle non-zero index in set_associated_data_n");
3,819✔
90
   if(m_nonce_mac.empty() == false)
3,819✔
91
      throw Invalid_State("Cannot set AD for EAX while processing a message");
382✔
92
   m_ad_mac = eax_prf(1, block_size(), *m_cmac, ad.data(), ad.size());
3,437✔
93
}
2,673✔
94

95
void EAX_Mode::start_msg(const uint8_t nonce[], size_t nonce_len) {
2,809✔
96
   if(!valid_nonce_length(nonce_len))
2,809✔
97
      throw Invalid_IV_Length(name(), nonce_len);
98

99
   m_nonce_mac = eax_prf(0, block_size(), *m_cmac, nonce, nonce_len);
2,809✔
100

101
   m_ctr->set_iv(m_nonce_mac.data(), m_nonce_mac.size());
2,809✔
102

103
   for(size_t i = 0; i != block_size() - 1; ++i)
39,712✔
104
      m_cmac->update(0);
36,903✔
105
   m_cmac->update(2);
2,809✔
106
}
2,809✔
107

108
size_t EAX_Encryption::process_msg(uint8_t buf[], size_t sz) {
5,910✔
109
   BOTAN_STATE_CHECK(!m_nonce_mac.empty());
5,910✔
110
   m_ctr->cipher(buf, buf, sz);
5,528✔
111
   m_cmac->update(buf, sz);
5,528✔
112
   return sz;
5,528✔
113
}
114

115
void EAX_Encryption::finish_msg(secure_vector<uint8_t>& buffer, size_t offset) {
1,301✔
116
   BOTAN_STATE_CHECK(!m_nonce_mac.empty());
1,301✔
117
   update(buffer, offset);
728✔
118

119
   secure_vector<uint8_t> data_mac = m_cmac->final();
728✔
120
   xor_buf(data_mac, m_nonce_mac, data_mac.size());
728✔
121

122
   if(m_ad_mac.empty()) {
728✔
123
      m_ad_mac = eax_prf(1, block_size(), *m_cmac, nullptr, 0);
67✔
124
   }
125

126
   xor_buf(data_mac, m_ad_mac, data_mac.size());
728✔
127

128
   buffer += std::make_pair(data_mac.data(), tag_size());
728✔
129

130
   m_nonce_mac.clear();
1,456✔
131
}
728✔
132

133
size_t EAX_Decryption::process_msg(uint8_t buf[], size_t sz) {
5,298✔
134
   BOTAN_STATE_CHECK(!m_nonce_mac.empty());
5,298✔
135
   m_cmac->update(buf, sz);
4,916✔
136
   m_ctr->cipher(buf, buf, sz);
4,916✔
137
   return sz;
4,916✔
138
}
139

140
void EAX_Decryption::finish_msg(secure_vector<uint8_t>& buffer, size_t offset) {
1,888✔
141
   BOTAN_ARG_CHECK(buffer.size() >= offset, "Offset is out of range");
1,888✔
142
   const size_t sz = buffer.size() - offset;
1,888✔
143
   uint8_t* buf = buffer.data() + offset;
1,888✔
144

145
   BOTAN_ARG_CHECK(sz >= tag_size(), "input did not include the tag");
1,888✔
146

147
   const size_t remaining = sz - tag_size();
1,421✔
148

149
   if(remaining) {
1,421✔
150
      m_cmac->update(buf, remaining);
1,002✔
151
      m_ctr->cipher(buf, buf, remaining);
989✔
152
   }
153

154
   const uint8_t* included_tag = &buf[remaining];
1,324✔
155

156
   secure_vector<uint8_t> mac = m_cmac->final();
1,324✔
157
   mac ^= m_nonce_mac;
1,315✔
158

159
   if(m_ad_mac.empty()) {
1,315✔
160
      m_ad_mac = eax_prf(1, block_size(), *m_cmac, nullptr, 0);
67✔
161
   }
162

163
   mac ^= m_ad_mac;
1,315✔
164

165
   bool accept_mac = constant_time_compare(mac.data(), included_tag, tag_size());
1,315✔
166

167
   buffer.resize(offset + remaining);
1,315✔
168

169
   m_nonce_mac.clear();
1,315✔
170

171
   if(!accept_mac)
1,315✔
172
      throw Invalid_Authentication_Tag("EAX tag check failed");
568✔
173
}
747✔
174

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