aboutsummaryrefslogtreecommitdiffstats
path: root/src/aead/gcm
diff options
context:
space:
mode:
authorlloyd <[email protected]>2013-03-28 17:30:22 +0000
committerlloyd <[email protected]>2013-03-28 17:30:22 +0000
commit3bd9e5c14a7e244a5c154db3c821e69cad3df08c (patch)
treed28c925861046a647e4d589c3573b59cd1eb6805 /src/aead/gcm
parent55f11acaa300e5d96de593e69cb7e28d612a1959 (diff)
Add an offset to ignore at the start of the buffer in AEAD processing
which makes more complicated packet building easier to do in-place. For instance now update can take a buffer that contains a header and be told to ignore the header.
Diffstat (limited to 'src/aead/gcm')
-rw-r--r--src/aead/gcm/gcm.cpp45
-rw-r--r--src/aead/gcm/gcm.h8
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;
};
}