Botan  1.11.15
src/lib/filters/transform_filter.cpp
Go to the documentation of this file.
00001 /*
00002 * Filter interface for Transforms
00003 * (C) 2013,2014 Jack Lloyd
00004 *
00005 * Botan is released under the Simplified BSD License (see license.txt)
00006 */
00007 
00008 #include <botan/transform_filter.h>
00009 #include <botan/internal/rounding.h>
00010 
00011 namespace Botan {
00012 
00013 namespace {
00014 
00015 size_t choose_update_size(size_t update_granularity)
00016    {
00017    const size_t target_size = 1024;
00018 
00019    if(update_granularity >= target_size)
00020       return update_granularity;
00021 
00022    return round_up(target_size, update_granularity);
00023    }
00024 
00025 }
00026 
00027 Transform_Filter::Transform_Filter(Transform* transform) :
00028    Buffered_Filter(choose_update_size(transform->update_granularity()),
00029                    transform->minimum_final_size()),
00030    m_nonce(transform->default_nonce_length() == 0),
00031    m_transform(transform),
00032    m_buffer(m_transform->update_granularity())
00033    {
00034    }
00035 
00036 std::string Transform_Filter::name() const
00037    {
00038    return m_transform->name();
00039    }
00040 
00041 void Transform_Filter::Nonce_State::update(const InitializationVector& iv)
00042    {
00043    m_nonce = unlock(iv.bits_of());
00044    m_fresh_nonce = true;
00045    }
00046 
00047 std::vector<byte> Transform_Filter::Nonce_State::get()
00048    {
00049    BOTAN_ASSERT(m_fresh_nonce, "The nonce is fresh for this message");
00050 
00051    if(!m_nonce.empty())
00052       m_fresh_nonce = false;
00053    return m_nonce;
00054    }
00055 
00056 void Transform_Filter::set_iv(const InitializationVector& iv)
00057    {
00058    m_nonce.update(iv);
00059    }
00060 
00061 void Transform_Filter::set_key(const SymmetricKey& key)
00062    {
00063    if(Keyed_Transform* keyed = dynamic_cast<Keyed_Transform*>(m_transform.get()))
00064       keyed->set_key(key);
00065    else if(key.length() != 0)
00066       throw std::runtime_error("Transform " + name() + " does not accept keys");
00067    }
00068 
00069 Key_Length_Specification Transform_Filter::key_spec() const
00070    {
00071    if(Keyed_Transform* keyed = dynamic_cast<Keyed_Transform*>(m_transform.get()))
00072       return keyed->key_spec();
00073    return Key_Length_Specification(0);
00074    }
00075 
00076 bool Transform_Filter::valid_iv_length(size_t length) const
00077    {
00078    return m_transform->valid_nonce_length(length);
00079    }
00080 
00081 void Transform_Filter::write(const byte input[], size_t input_length)
00082    {
00083    Buffered_Filter::write(input, input_length);
00084    }
00085 
00086 void Transform_Filter::end_msg()
00087    {
00088    Buffered_Filter::end_msg();
00089    }
00090 
00091 void Transform_Filter::start_msg()
00092    {
00093    send(m_transform->start(m_nonce.get()));
00094    }
00095 
00096 void Transform_Filter::buffered_block(const byte input[], size_t input_length)
00097    {
00098    while(input_length)
00099       {
00100       const size_t take = std::min(m_transform->update_granularity(), input_length);
00101 
00102       m_buffer.assign(input, input + take);
00103       m_transform->update(m_buffer);
00104 
00105       send(m_buffer);
00106 
00107       input += take;
00108       input_length -= take;
00109       }
00110    }
00111 
00112 void Transform_Filter::buffered_final(const byte input[], size_t input_length)
00113    {
00114    secure_vector<byte> buf(input, input + input_length);
00115    m_transform->finish(buf);
00116    send(buf);
00117    }
00118 
00119 }