@@ -128,10 +128,17 @@ size_t EAX_Encryption::process_msg(uint8_t buf[], size_t sz) {
128128 return sz;
129129}
130130
131- void EAX_Encryption::finish_msg (secure_vector <uint8_t >& buffer, size_t offset ) {
131+ size_t EAX_Encryption::finish_msg (std::span <uint8_t > buffer, size_t input_bytes ) {
132132 BOTAN_STATE_CHECK (!m_nonce_mac.empty ());
133- update (buffer, offset);
134133
134+ const size_t tag_length = tag_size ();
135+
136+ BOTAN_ASSERT_NOMSG (input_bytes + tag_length == buffer.size ());
137+
138+ const auto payload = buffer.first (input_bytes);
139+ const auto tag = buffer.last (tag_length);
140+
141+ process (payload);
135142 secure_vector<uint8_t > data_mac = m_cmac->final ();
136143 xor_buf (data_mac, m_nonce_mac, data_mac.size ());
137144
@@ -141,9 +148,11 @@ void EAX_Encryption::finish_msg(secure_vector<uint8_t>& buffer, size_t offset) {
141148
142149 xor_buf (data_mac, m_ad_mac, data_mac.size ());
143150
144- buffer += std::make_pair ( data_mac. data (), tag_size ( ));
151+ copy_mem (tag, std::span{ data_mac}. first (tag_length ));
145152
146153 m_nonce_mac.clear ();
154+
155+ return buffer.size ();
147156}
148157
149158size_t EAX_Decryption::process_msg (uint8_t buf[], size_t sz) {
@@ -153,40 +162,37 @@ size_t EAX_Decryption::process_msg(uint8_t buf[], size_t sz) {
153162 return sz;
154163}
155164
156- void EAX_Decryption::finish_msg (secure_vector<uint8_t >& buffer, size_t offset) {
157- BOTAN_ARG_CHECK (buffer.size () >= offset, " Offset is out of range" );
158- const size_t sz = buffer.size () - offset;
159- uint8_t * buf = buffer.data () + offset;
165+ size_t EAX_Decryption::finish_msg (std::span<uint8_t > buffer, size_t input_bytes) {
166+ const size_t tag_length = tag_size ();
160167
161- BOTAN_ARG_CHECK (sz >= tag_size (), " input did not include the tag" );
168+ BOTAN_ASSERT_NOMSG (buffer.size () == input_bytes);
169+ BOTAN_ASSERT_NOMSG (buffer.size () >= tag_length);
162170
163- const size_t remaining = sz - tag_size ();
171+ const auto remaining = buffer.first (buffer.size () - tag_length);
172+ const auto tag = buffer.last (tag_length);
164173
165- if (remaining) {
166- m_cmac->update (buf, remaining);
167- m_ctr->cipher (buf, buf, remaining);
174+ if (!remaining.empty ()) {
175+ process (remaining);
168176 }
169177
170- const uint8_t * included_tag = &buf[remaining];
171-
172- secure_vector<uint8_t > mac = m_cmac->final ();
173- mac ^= m_nonce_mac;
178+ auto mac = m_cmac->final ();
179+ xor_buf (mac, m_nonce_mac);
174180
175181 if (m_ad_mac.empty ()) {
176182 m_ad_mac = eax_prf (1 , block_size (), *m_cmac, nullptr , 0 );
177183 }
178184
179- mac ^= m_ad_mac;
180-
181- const bool accept_mac = CT::is_equal (mac.data (), included_tag, tag_size ()).as_bool ();
185+ xor_buf (mac, m_ad_mac);
182186
183- buffer. resize (offset + remaining );
187+ const bool accept_mac = CT::is_equal (mac. data (), tag. data (), tag_length). as_bool ( );
184188
185189 m_nonce_mac.clear ();
186190
187191 if (!accept_mac) {
188192 throw Invalid_Authentication_Tag (" EAX tag check failed" );
189193 }
194+
195+ return remaining.size ();
190196}
191197
192198} // namespace Botan
0 commit comments