diff options
Diffstat (limited to 'src/aead/gcm')
-rw-r--r-- | src/aead/gcm/gcm.cpp | 45 | ||||
-rw-r--r-- | src/aead/gcm/gcm.h | 8 |
2 files changed, 32 insertions, 21 deletions
diff --git a/src/aead/gcm/gcm.cpp b/src/aead/gcm/gcm.cpp index a5ccee927..665fc4472 100644 --- a/src/aead/gcm/gcm.cpp +++ b/src/aead/gcm/gcm.cpp @@ -182,16 +182,20 @@ secure_vector<byte> GCM_Mode::start(const byte nonce[], size_t nonce_len) return secure_vector<byte>(); } -void GCM_Encryption::update(secure_vector<byte>& buffer) +void GCM_Encryption::update(secure_vector<byte>& buffer, size_t offset) { - m_ctr->cipher(&buffer[0], &buffer[0], buffer.size()); - ghash_update(m_H, m_mac, &buffer[0], buffer.size()); - m_text_len += buffer.size(); + BOTAN_ASSERT(buffer.size() >= offset, "Offset is sane"); + const size_t sz = buffer.size() - offset; + byte* buf = &buffer[offset]; + + m_ctr->cipher(buf, buf, sz); + ghash_update(m_H, m_mac, buf, sz); + m_text_len += sz; } -void GCM_Encryption::finish(secure_vector<byte>& buffer) +void GCM_Encryption::finish(secure_vector<byte>& buffer, size_t offset) { - update(buffer); + update(buffer, offset); ghash_finalize(m_H, m_mac, m_ad_len, m_text_len); @@ -200,25 +204,32 @@ void GCM_Encryption::finish(secure_vector<byte>& buffer) buffer += std::make_pair(&m_mac[0], tag_size()); } -void GCM_Decryption::update(secure_vector<byte>& buffer) +void GCM_Decryption::update(secure_vector<byte>& buffer, size_t offset) { - ghash_update(m_H, m_mac, &buffer[0], buffer.size()); - m_ctr->cipher(&buffer[0], &buffer[0], buffer.size()); - m_text_len += buffer.size(); + BOTAN_ASSERT(buffer.size() >= offset, "Offset is sane"); + const size_t sz = buffer.size() - offset; + byte* buf = &buffer[offset]; + + ghash_update(m_H, m_mac, buf, sz); + m_ctr->cipher(buf, buf, sz); + m_text_len += sz; } -void GCM_Decryption::finish(secure_vector<byte>& buffer) +void GCM_Decryption::finish(secure_vector<byte>& buffer, size_t offset) { - BOTAN_ASSERT(buffer.size() >= tag_size(), - "Have the tag as part of final input"); + BOTAN_ASSERT(buffer.size() >= offset, "Offset is sane"); + const size_t sz = buffer.size() - offset; + byte* buf = &buffer[offset]; + + BOTAN_ASSERT(sz >= tag_size(), "Have the tag as part of final input"); - const size_t remaining = buffer.size() - tag_size(); + const size_t remaining = sz - tag_size(); // handle any final input before the tag if(remaining) { - ghash_update(m_H, m_mac, &buffer[0], remaining); - m_ctr->cipher(&buffer[0], &buffer[0], remaining); + ghash_update(m_H, m_mac, buf, remaining); + m_ctr->cipher(buf, buf, remaining); m_text_len += remaining; } @@ -231,7 +242,7 @@ void GCM_Decryption::finish(secure_vector<byte>& buffer) if(!same_mem(&m_mac[0], included_tag, tag_size())) throw Integrity_Failure("GCM tag check failed"); - buffer.resize(remaining); + buffer.resize(offset + remaining); } } diff --git a/src/aead/gcm/gcm.h b/src/aead/gcm/gcm.h index cf7d94ced..bc7eaae20 100644 --- a/src/aead/gcm/gcm.h +++ b/src/aead/gcm/gcm.h @@ -70,9 +70,9 @@ class BOTAN_DLL GCM_Encryption : public GCM_Mode size_t minimum_final_size() const override { return 0; } - void update(secure_vector<byte>& blocks) override; + void update(secure_vector<byte>& blocks, size_t offset) override; - void finish(secure_vector<byte>& final_block) override; + void finish(secure_vector<byte>& final_block, size_t offset) override; }; /** @@ -90,9 +90,9 @@ class BOTAN_DLL GCM_Decryption : public GCM_Mode size_t minimum_final_size() const override { return tag_size(); } - void update(secure_vector<byte>& blocks) override; + void update(secure_vector<byte>& blocks, size_t offset) override; - void finish(secure_vector<byte>& final_block) override; + void finish(secure_vector<byte>& final_block, size_t offset) override; }; } |