From 507d926da825fbc1d9d74b4517dbab47702c66b9 Mon Sep 17 00:00:00 2001 From: Jack Lloyd Date: Thu, 1 Sep 2016 13:40:26 -0400 Subject: Cipher_Mode API improvements The Cipher_Mode::update API is more general than needed to just support ciphers (this is due to it previously being an API of Transform which before 8b85b780515 was Cipher_Mode's base class) Define a less general interface `process` which either processes the blocks in-place, producing exactly as much output as there was input, or (SIV/CCM case) saves the entire message for processing in `finish`. These two uses cover all current or anticipated cipher modes. Leaves `update` for compatability with existing callers; all that is needed is an inline function forwarding to `process`. Removes the return type from `start` - in all cipher implementations, this always returned an empty vector. Adds BOTAN_ARG_CHECK macro; right now BOTAN_ASSERT is being used for argument checking in some places, which is not right at all. --- src/lib/modes/cfb/cfb.cpp | 32 +++++++++++++------------------- 1 file changed, 13 insertions(+), 19 deletions(-) (limited to 'src/lib/modes/cfb/cfb.cpp') diff --git a/src/lib/modes/cfb/cfb.cpp b/src/lib/modes/cfb/cfb.cpp index 6c9239e73..cc5e9bae7 100644 --- a/src/lib/modes/cfb/cfb.cpp +++ b/src/lib/modes/cfb/cfb.cpp @@ -69,7 +69,7 @@ void CFB_Mode::key_schedule(const byte key[], size_t length) m_cipher->set_key(key, length); } -secure_vector CFB_Mode::start_raw(const byte nonce[], size_t nonce_len) +void CFB_Mode::start_msg(const byte nonce[], size_t nonce_len) { if(!valid_nonce_length(nonce_len)) throw Invalid_IV_Length(name(), nonce_len); @@ -77,24 +77,19 @@ secure_vector CFB_Mode::start_raw(const byte nonce[], size_t nonce_len) m_shift_register.assign(nonce, nonce + nonce_len); m_keystream_buf.resize(m_shift_register.size()); cipher().encrypt(m_shift_register, m_keystream_buf); - - return secure_vector(); } -void CFB_Encryption::update(secure_vector& buffer, size_t offset) +size_t CFB_Encryption::process(uint8_t buf[], size_t sz) { - BOTAN_ASSERT(buffer.size() >= offset, "Offset is sane"); - size_t sz = buffer.size() - offset; - byte* buf = buffer.data() + offset; - const size_t BS = cipher().block_size(); secure_vector& state = shift_register(); const size_t shift = feedback(); + size_t left = sz; - while(sz) + while(left) { - const size_t took = std::min(shift, sz); + const size_t took = std::min(shift, left); xor_buf(buf, &keystream_buf()[0], took); // Assumes feedback-sized block except for last input @@ -106,8 +101,9 @@ void CFB_Encryption::update(secure_vector& buffer, size_t offset) cipher().encrypt(state, keystream_buf()); buf += took; - sz -= took; + left -= took; } + return sz; } void CFB_Encryption::finish(secure_vector& buffer, size_t offset) @@ -115,20 +111,17 @@ void CFB_Encryption::finish(secure_vector& buffer, size_t offset) update(buffer, offset); } -void CFB_Decryption::update(secure_vector& buffer, size_t offset) +size_t CFB_Decryption::process(uint8_t buf[], size_t sz) { - BOTAN_ASSERT(buffer.size() >= offset, "Offset is sane"); - size_t sz = buffer.size() - offset; - byte* buf = buffer.data() + offset; - const size_t BS = cipher().block_size(); secure_vector& state = shift_register(); const size_t shift = feedback(); + size_t left = sz; - while(sz) + while(left) { - const size_t took = std::min(shift, sz); + const size_t took = std::min(shift, left); // first update shift register with ciphertext if (BS - shift > 0) @@ -144,8 +137,9 @@ void CFB_Decryption::update(secure_vector& buffer, size_t offset) cipher().encrypt(state, keystream_buf()); buf += took; - sz -= took; + left -= took; } + return sz; } void CFB_Decryption::finish(secure_vector& buffer, size_t offset) -- cgit v1.2.3