diff options
Diffstat (limited to 'src/aead')
-rw-r--r-- | src/aead/aead.h | 6 | ||||
-rw-r--r-- | src/aead/eax/eax.cpp | 14 | ||||
-rw-r--r-- | src/aead/gcm/gcm.cpp | 18 | ||||
-rw-r--r-- | src/aead/ocb/ocb.cpp | 35 |
4 files changed, 46 insertions, 27 deletions
diff --git a/src/aead/aead.h b/src/aead/aead.h index af6f0e76a..736de85e1 100644 --- a/src/aead/aead.h +++ b/src/aead/aead.h @@ -57,6 +57,12 @@ class AEAD_Mode : public SymmetricAlgorithm */ virtual secure_vector<byte> start(const byte nonce[], size_t nonce_len) = 0; + template<typename Alloc> + secure_vector<byte> start_vec(const std::vector<byte, Alloc>& nonce) + { + return start(&nonce[0], nonce.size()); + } + /** * Update (encrypt or decrypt) some data. Input must be in size * update_granularity() byte blocks. diff --git a/src/aead/eax/eax.cpp b/src/aead/eax/eax.cpp index 8a7287062..fa0496f42 100644 --- a/src/aead/eax/eax.cpp +++ b/src/aead/eax/eax.cpp @@ -119,7 +119,7 @@ void EAX_Encryption::finish(secure_vector<byte>& buffer) xor_buf(data_mac, m_nonce_mac, data_mac.size()); xor_buf(data_mac, m_ad_mac, data_mac.size()); - buffer += data_mac; + buffer += std::make_pair(&data_mac[0], tag_size()); } void EAX_Decryption::update(secure_vector<byte>& buffer) @@ -133,15 +133,15 @@ void EAX_Decryption::finish(secure_vector<byte>& buffer) BOTAN_ASSERT(buffer.size() >= tag_size(), "Have the tag as part of final input"); - const size_t input_length = buffer.size() - tag_size(); + const size_t remaining = buffer.size() - tag_size(); - if(input_length) // handle any remaining input + if(remaining) // handle any remaining input { - m_cmac->update(&buffer[0], buffer.size()); - m_ctr->cipher(&buffer[0], &buffer[0], buffer.size()); + m_cmac->update(&buffer[0], remaining); + m_ctr->cipher(&buffer[0], &buffer[0], remaining); } - const byte* included_tag = &buffer[input_length]; + const byte* included_tag = &buffer[remaining]; secure_vector<byte> mac = m_cmac->final(); mac ^= m_nonce_mac; @@ -149,6 +149,8 @@ void EAX_Decryption::finish(secure_vector<byte>& buffer) if(!same_mem(&mac[0], included_tag, tag_size())) throw Integrity_Failure("EAX tag check failed"); + + buffer.resize(remaining); } } diff --git a/src/aead/gcm/gcm.cpp b/src/aead/gcm/gcm.cpp index 628dcc270..a067d162e 100644 --- a/src/aead/gcm/gcm.cpp +++ b/src/aead/gcm/gcm.cpp @@ -27,6 +27,8 @@ gcm_multiply(const secure_vector<byte>& x, u64bit Z[2] = { 0, 0 }; + // Both CLMUL and SSE2 versions would be useful + for(size_t i = 0; i != 2; ++i) { u64bit X = load_be<u64bit>(&x[0], i); @@ -192,7 +194,7 @@ void GCM_Encryption::finish(secure_vector<byte>& buffer) m_mac ^= m_enc_y0; - buffer += m_mac; + buffer += std::make_pair(&m_mac[0], tag_size()); } void GCM_Decryption::update(secure_vector<byte>& buffer) @@ -207,22 +209,26 @@ void GCM_Decryption::finish(secure_vector<byte>& buffer) BOTAN_ASSERT(buffer.size() >= tag_size(), "Have the tag as part of final input"); + const size_t remaining = buffer.size() - tag_size(); + // handle any final input before the tag - if(size_t input_length = buffer.size() - tag_size()) + if(remaining) { - ghash_update(m_H, m_mac, &buffer[0], input_length); - m_ctr->cipher(&buffer[0], &buffer[0], input_length); - m_text_len += input_length; + ghash_update(m_H, m_mac, &buffer[0], remaining); + m_ctr->cipher(&buffer[0], &buffer[0], remaining); + m_text_len += remaining; } ghash_finalize(m_H, m_mac, m_ad_len, m_text_len); m_mac ^= m_enc_y0; - const byte* included_tag = &buffer[buffer.size() - tag_size()]; + const byte* included_tag = &buffer[remaining]; if(!same_mem(&m_mac[0], included_tag, tag_size())) throw Integrity_Failure("GCM tag check failed"); + + buffer.resize(remaining); } } diff --git a/src/aead/ocb/ocb.cpp b/src/aead/ocb/ocb.cpp index 5bd42766f..50b33960f 100644 --- a/src/aead/ocb/ocb.cpp +++ b/src/aead/ocb/ocb.cpp @@ -11,9 +11,6 @@ #include <botan/internal/bit_ops.h> #include <algorithm> -#include <botan/hex.h> -#include <iostream> - namespace Botan { // Has to be in Botan namespace so unique_ptr can reference it @@ -377,33 +374,34 @@ void OCB_Decryption::finish(secure_vector<byte>& buffer) { BOTAN_ASSERT(buffer.size() >= tag_size(), "We have the tag"); - if(const size_t remaining_ctext = buffer.size() - tag_size()) + const size_t remaining = buffer.size() - tag_size(); + + if(remaining) { - const size_t final_full_blocks = remaining_ctext / BS; - const size_t remainder_bytes = remaining_ctext - (final_full_blocks * BS); + const size_t final_full_blocks = remaining / BS; + const size_t final_bytes = remaining - (final_full_blocks * BS); decrypt(&buffer[0], final_full_blocks); - if(remainder_bytes) + if(final_bytes) { - BOTAN_ASSERT(remainder_bytes < BS, "Only a partial block left"); + BOTAN_ASSERT(final_bytes < BS, "Only a partial block left"); - byte* remainder = &buffer[buffer.size() - remainder_bytes]; + byte* remainder = &buffer[remaining - final_bytes]; m_offset ^= m_L->star(); // Offset_* secure_vector<byte> pad(BS); m_cipher->encrypt(m_offset, pad); // P_* - xor_buf(&remainder[0], &pad[0], remainder_bytes); + xor_buf(&remainder[0], &pad[0], final_bytes); - xor_buf(&m_checksum[0], &remainder[0], remainder_bytes); - m_checksum[remainder_bytes] ^= 0x80; + xor_buf(&m_checksum[0], &remainder[0], final_bytes); + m_checksum[final_bytes] ^= 0x80; } } - const byte* included_tag = &buffer[buffer.size() - tag_size()]; - + // compute the mac secure_vector<byte> mac = m_offset; mac ^= m_checksum; mac ^= m_L->dollar(); @@ -412,12 +410,19 @@ void OCB_Decryption::finish(secure_vector<byte>& buffer) mac ^= m_ad_hash; + // reset state zeroise(m_checksum); zeroise(m_offset); m_block_index = 0; - if(!same_mem(&mac[0], included_tag, m_tag_size)) + // compare mac + const byte* included_tag = &buffer[remaining]; + + if(!same_mem(&mac[0], included_tag, tag_size())) throw Integrity_Failure("OCB tag check failed"); + + // remove tag from end of message + buffer.resize(remaining); } } |