Botan 3.6.1
Crypto and TLS for C&
Botan::AlignmentBuffer< T, BLOCK_SIZE, FINAL_BLOCK_STRATEGY > Class Template Reference

Alignment buffer helper. More...

#include <alignment_buffer.h>

Public Member Functions

std::tuple< std::span< const uint8_t >, size_t > aligned_data_to_process (BufferSlicer &slicer) const
 
 AlignmentBuffer ()
 
 AlignmentBuffer (AlignmentBuffer &&other) noexcept=default
 
 AlignmentBuffer (const AlignmentBuffer &other)=default
 
void append (std::span< const T > elements)
 
void clear ()
 
std::span< const Tconsume ()
 
std::span< const Tconsume_partial ()
 
constexpr bool defers_final_block () const
 
std::span< Tdirectly_modify_first (size_t elements)
 
std::span< Tdirectly_modify_last (size_t elements)
 
size_t elements_in_buffer () const
 
size_t elements_until_alignment () const
 
void fill_up_with_zeros ()
 
std::optional< std::span< const T > > handle_unaligned_data (BufferSlicer &slicer)
 
bool in_alignment () const
 
std::optional< std::span< const uint8_t > > next_aligned_block_to_process (BufferSlicer &slicer) const
 
AlignmentBufferoperator= (AlignmentBuffer &&other) noexcept=default
 
AlignmentBufferoperator= (const AlignmentBuffer &other)=default
 
bool ready_to_consume () const
 
constexpr size_t size () const
 
 ~AlignmentBuffer ()
 

Detailed Description

template<typename T, size_t BLOCK_SIZE, AlignmentBufferFinalBlock FINAL_BLOCK_STRATEGY = AlignmentBufferFinalBlock::is_not_special>
requires (BLOCK_SIZE > 0)
class Botan::AlignmentBuffer< T, BLOCK_SIZE, FINAL_BLOCK_STRATEGY >

Alignment buffer helper.

Many algorithms have an intrinsic block size in which they consume input data. When streaming arbitrary data chunks to such algorithms we must store some data intermittently to honor the algorithm's alignment requirements.

This helper encapsulates such an alignment buffer. The API of this class is designed to minimize user errors in the algorithm implementations. Therefore, it is strongly opinionated on its use case. Don't try to use it for anything but the described circumstance.

Template Parameters
Tthe element type of the internal buffer
BLOCK_SIZEthe buffer size to use for the alignment buffer
FINAL_BLOCK_STRATEGYdefines whether the final input data block is retained in handle_unaligned_data() and must be manually consumed

Definition at line 61 of file alignment_buffer.h.

Constructor & Destructor Documentation

◆ AlignmentBuffer() [1/3]

template<typename T , size_t BLOCK_SIZE, AlignmentBufferFinalBlock FINAL_BLOCK_STRATEGY = AlignmentBufferFinalBlock::is_not_special>
Botan::AlignmentBuffer< T, BLOCK_SIZE, FINAL_BLOCK_STRATEGY >::AlignmentBuffer ( )
inline

Definition at line 63 of file alignment_buffer.h.

63: m_position(0) {}

◆ ~AlignmentBuffer()

template<typename T , size_t BLOCK_SIZE, AlignmentBufferFinalBlock FINAL_BLOCK_STRATEGY = AlignmentBufferFinalBlock::is_not_special>
Botan::AlignmentBuffer< T, BLOCK_SIZE, FINAL_BLOCK_STRATEGY >::~AlignmentBuffer ( )
inline

Definition at line 65 of file alignment_buffer.h.

65{ secure_scrub_memory(m_buffer.data(), m_buffer.size()); }
void secure_scrub_memory(void *ptr, size_t n)
Definition os_utils.cpp:83

References Botan::secure_scrub_memory().

◆ AlignmentBuffer() [2/3]

template<typename T , size_t BLOCK_SIZE, AlignmentBufferFinalBlock FINAL_BLOCK_STRATEGY = AlignmentBufferFinalBlock::is_not_special>
Botan::AlignmentBuffer< T, BLOCK_SIZE, FINAL_BLOCK_STRATEGY >::AlignmentBuffer ( const AlignmentBuffer< T, BLOCK_SIZE, FINAL_BLOCK_STRATEGY > & other)
default

◆ AlignmentBuffer() [3/3]

template<typename T , size_t BLOCK_SIZE, AlignmentBufferFinalBlock FINAL_BLOCK_STRATEGY = AlignmentBufferFinalBlock::is_not_special>
Botan::AlignmentBuffer< T, BLOCK_SIZE, FINAL_BLOCK_STRATEGY >::AlignmentBuffer ( AlignmentBuffer< T, BLOCK_SIZE, FINAL_BLOCK_STRATEGY > && other)
defaultnoexcept

Member Function Documentation

◆ aligned_data_to_process()

template<typename T , size_t BLOCK_SIZE, AlignmentBufferFinalBlock FINAL_BLOCK_STRATEGY = AlignmentBufferFinalBlock::is_not_special>
std::tuple< std::span< const uint8_t >, size_t > Botan::AlignmentBuffer< T, BLOCK_SIZE, FINAL_BLOCK_STRATEGY >::aligned_data_to_process ( BufferSlicer & slicer) const
inlinenodiscard

Once the buffer reached alignment, this can be used to consume as many input bytes from the given slider as possible. The output always contains data elements that are a multiple of the intrinsic block size.

Returns
a view onto the aligned data from slicer and the number of full blocks that are represented by this view.

Definition at line 127 of file alignment_buffer.h.

127 {
129
130 // When the final block is to be deferred, the last block must not be
131 // selected for processing if there is no (unaligned) extra input data.
132 const size_t defer = (defers_final_block()) ? 1 : 0;
133 const size_t full_blocks_to_process = (slicer.remaining() - defer) / m_buffer.size();
134 return {slicer.take(full_blocks_to_process * m_buffer.size()), full_blocks_to_process};
135 }
#define BOTAN_ASSERT_NOMSG(expr)
Definition assert.h:59
constexpr bool defers_final_block() const

References BOTAN_ASSERT_NOMSG, Botan::BufferSlicer::remaining(), and Botan::BufferSlicer::take().

Referenced by Botan::BLAKE2b::add_data(), and Botan::MerkleDamgard_Hash< MD >::update().

◆ append()

template<typename T , size_t BLOCK_SIZE, AlignmentBufferFinalBlock FINAL_BLOCK_STRATEGY = AlignmentBufferFinalBlock::is_not_special>
void Botan::AlignmentBuffer< T, BLOCK_SIZE, FINAL_BLOCK_STRATEGY >::append ( std::span< const T > elements)
inline

Appends the provided elements to the buffer. The user has to make sure that elements fits in the remaining capacity of the buffer.

Definition at line 91 of file alignment_buffer.h.

91 {
92 BOTAN_ASSERT_NOMSG(elements.size() <= elements_until_alignment());
93 std::copy(elements.begin(), elements.end(), m_buffer.begin() + m_position);
94 m_position += elements.size();
95 }
size_t elements_until_alignment() const

References BOTAN_ASSERT_NOMSG.

Referenced by Botan::Streebog::final_result().

◆ clear()

template<typename T , size_t BLOCK_SIZE, AlignmentBufferFinalBlock FINAL_BLOCK_STRATEGY = AlignmentBufferFinalBlock::is_not_special>
void Botan::AlignmentBuffer< T, BLOCK_SIZE, FINAL_BLOCK_STRATEGY >::clear ( )
inline

Definition at line 72 of file alignment_buffer.h.

72 {
73 clear_mem(m_buffer.data(), m_buffer.size());
74 m_position = 0;
75 }
constexpr void clear_mem(T *ptr, size_t n)
Definition mem_ops.h:120

References Botan::clear_mem().

Referenced by Botan::BLAKE2b::clear(), Botan::GMAC::clear(), Botan::GOST_34_11::clear(), Botan::MerkleDamgard_Hash< MD >::clear(), Botan::Poly1305::clear(), Botan::Skein_512::clear(), and Botan::Streebog::clear().

◆ consume()

template<typename T , size_t BLOCK_SIZE, AlignmentBufferFinalBlock FINAL_BLOCK_STRATEGY = AlignmentBufferFinalBlock::is_not_special>
std::span< const T > Botan::AlignmentBuffer< T, BLOCK_SIZE, FINAL_BLOCK_STRATEGY >::consume ( )
inlinenodiscard

Explicitly consume the currently collected block. It is the caller's responsibility to ensure that the buffer is filled fully. After consumption, the buffer is cleared and ready to collect new data.

Definition at line 201 of file alignment_buffer.h.

201 {
203 m_position = 0;
204 return m_buffer;
205 }

References BOTAN_ASSERT_NOMSG.

Referenced by Botan::BLAKE2b::final_result(), and Botan::Streebog::final_result().

◆ consume_partial()

template<typename T , size_t BLOCK_SIZE, AlignmentBufferFinalBlock FINAL_BLOCK_STRATEGY = AlignmentBufferFinalBlock::is_not_special>
std::span< const T > Botan::AlignmentBuffer< T, BLOCK_SIZE, FINAL_BLOCK_STRATEGY >::consume_partial ( )
inlinenodiscard

Explicitly consumes however many bytes are currently stored in the buffer. After consumption, the buffer is cleared and ready to collect new data.

Definition at line 212 of file alignment_buffer.h.

212 {
213 const auto elements = elements_in_buffer();
214 m_position = 0;
215 return std::span(m_buffer).first(elements);
216 }
size_t elements_in_buffer() const

◆ defers_final_block()

template<typename T , size_t BLOCK_SIZE, AlignmentBufferFinalBlock FINAL_BLOCK_STRATEGY = AlignmentBufferFinalBlock::is_not_special>
bool Botan::AlignmentBuffer< T, BLOCK_SIZE, FINAL_BLOCK_STRATEGY >::defers_final_block ( ) const
inlineconstexpr

Definition at line 234 of file alignment_buffer.h.

234 {
235 return FINAL_BLOCK_STRATEGY == AlignmentBufferFinalBlock::must_be_deferred;
236 }

References Botan::must_be_deferred.

◆ directly_modify_first()

template<typename T , size_t BLOCK_SIZE, AlignmentBufferFinalBlock FINAL_BLOCK_STRATEGY = AlignmentBufferFinalBlock::is_not_special>
std::span< T > Botan::AlignmentBuffer< T, BLOCK_SIZE, FINAL_BLOCK_STRATEGY >::directly_modify_first ( size_t elements)
inline

Allows direct modification of the first elements in the buffer. This is a low-level accessor that neither takes the buffer's current capacity into account nor does it change the internal cursor. Beware not to overwrite unconsumed bytes.

Definition at line 103 of file alignment_buffer.h.

103 {
104 BOTAN_ASSERT_NOMSG(size() >= elements);
105 return std::span(m_buffer).first(elements);
106 }
constexpr size_t size() const

References BOTAN_ASSERT_NOMSG.

Referenced by Botan::Streebog::final_result().

◆ directly_modify_last()

template<typename T , size_t BLOCK_SIZE, AlignmentBufferFinalBlock FINAL_BLOCK_STRATEGY = AlignmentBufferFinalBlock::is_not_special>
std::span< T > Botan::AlignmentBuffer< T, BLOCK_SIZE, FINAL_BLOCK_STRATEGY >::directly_modify_last ( size_t elements)
inline

Allows direct modification of the last elements in the buffer. This is a low-level accessor that neither takes the buffer's current capacity into account nor does it change the internal cursor. Beware not to overwrite unconsumed bytes.

Definition at line 114 of file alignment_buffer.h.

114 {
115 BOTAN_ASSERT_NOMSG(size() >= elements);
116 return std::span(m_buffer).last(elements);
117 }

References BOTAN_ASSERT_NOMSG.

◆ elements_in_buffer()

template<typename T , size_t BLOCK_SIZE, AlignmentBufferFinalBlock FINAL_BLOCK_STRATEGY = AlignmentBufferFinalBlock::is_not_special>
size_t Botan::AlignmentBuffer< T, BLOCK_SIZE, FINAL_BLOCK_STRATEGY >::elements_in_buffer ( ) const
inline

Definition at line 220 of file alignment_buffer.h.

220{ return m_position; }

Referenced by Botan::BLAKE2b::final_result(), and Botan::Streebog::final_result().

◆ elements_until_alignment()

template<typename T , size_t BLOCK_SIZE, AlignmentBufferFinalBlock FINAL_BLOCK_STRATEGY = AlignmentBufferFinalBlock::is_not_special>
size_t Botan::AlignmentBuffer< T, BLOCK_SIZE, FINAL_BLOCK_STRATEGY >::elements_until_alignment ( ) const
inline

Definition at line 222 of file alignment_buffer.h.

222{ return m_buffer.size() - m_position; }

◆ fill_up_with_zeros()

template<typename T , size_t BLOCK_SIZE, AlignmentBufferFinalBlock FINAL_BLOCK_STRATEGY = AlignmentBufferFinalBlock::is_not_special>
void Botan::AlignmentBuffer< T, BLOCK_SIZE, FINAL_BLOCK_STRATEGY >::fill_up_with_zeros ( )
inline

Fills the currently unused bytes of the buffer with zero bytes

Definition at line 80 of file alignment_buffer.h.

80 {
81 if(!ready_to_consume()) {
82 clear_mem(&m_buffer[m_position], elements_until_alignment());
83 m_position = m_buffer.size();
84 }
85 }

References Botan::clear_mem().

Referenced by Botan::BLAKE2b::final_result(), and Botan::Streebog::final_result().

◆ handle_unaligned_data()

template<typename T , size_t BLOCK_SIZE, AlignmentBufferFinalBlock FINAL_BLOCK_STRATEGY = AlignmentBufferFinalBlock::is_not_special>
std::optional< std::span< const T > > Botan::AlignmentBuffer< T, BLOCK_SIZE, FINAL_BLOCK_STRATEGY >::handle_unaligned_data ( BufferSlicer & slicer)
inlinenodiscard

Intermittently buffers potentially unaligned data provided in slicer. If the internal buffer already contains some elements, data is appended. Once a full block is collected, it is returned to the caller for processing.

Parameters
slicerthe input data source to be (partially) consumed
Returns
a view onto a full block once enough data was collected, or std::nullopt if no full block is available yet

Definition at line 167 of file alignment_buffer.h.

167 {
168 // When the final block is to be deferred, we would need to store and
169 // hold a buffer that contains exactly one block until more data is
170 // passed or it is explicitly consumed.
171 const size_t defer = (defers_final_block()) ? 1 : 0;
172
173 if(in_alignment() && slicer.remaining() >= m_buffer.size() + defer) {
174 // We are currently in alignment and the passed-in data source
175 // contains enough data to benefit from aligned processing.
176 // Therefore, we don't copy anything into the intermittent buffer.
177 return std::nullopt;
178 }
179
180 // Fill the buffer with as much input data as needed to reach alignment
181 // or until the input source is depleted.
182 const auto elements_to_consume = std::min(m_buffer.size() - m_position, slicer.remaining());
183 append(slicer.take(elements_to_consume));
184
185 // If we collected enough data, we push out one full block. When
186 // deferring the final block is enabled, we additionally check that
187 // more input data is available to continue processing a consecutive
188 // block.
189 if(ready_to_consume() && (!defers_final_block() || !slicer.empty())) {
190 return consume();
191 } else {
192 return std::nullopt;
193 }
194 }
void append(std::span< const T > elements)
std::span< const T > consume()

References Botan::BufferSlicer::empty(), Botan::BufferSlicer::remaining(), and Botan::BufferSlicer::take().

Referenced by Botan::BLAKE2b::add_data(), Botan::Streebog::add_data(), and Botan::MerkleDamgard_Hash< MD >::update().

◆ in_alignment()

template<typename T , size_t BLOCK_SIZE, AlignmentBufferFinalBlock FINAL_BLOCK_STRATEGY = AlignmentBufferFinalBlock::is_not_special>
bool Botan::AlignmentBuffer< T, BLOCK_SIZE, FINAL_BLOCK_STRATEGY >::in_alignment ( ) const
inline
Returns
true if the buffer is empty (i.e. contains no unaligned data)

Definition at line 227 of file alignment_buffer.h.

227{ return m_position == 0; }

Referenced by Botan::BLAKE2b::add_data(), Botan::Streebog::add_data(), and Botan::MerkleDamgard_Hash< MD >::update().

◆ next_aligned_block_to_process()

template<typename T , size_t BLOCK_SIZE, AlignmentBufferFinalBlock FINAL_BLOCK_STRATEGY = AlignmentBufferFinalBlock::is_not_special>
std::optional< std::span< const uint8_t > > Botan::AlignmentBuffer< T, BLOCK_SIZE, FINAL_BLOCK_STRATEGY >::next_aligned_block_to_process ( BufferSlicer & slicer) const
inlinenodiscard

Once the buffer reached alignment, this can be used to consume full blocks from the input data represented by slicer.

Returns
a view onto the next full block from slicer or std::nullopt if not enough data is available in slicer.

Definition at line 144 of file alignment_buffer.h.

144 {
146
147 // When the final block is to be deferred, the last block must not be
148 // selected for processing if there is no (unaligned) extra input data.
149 const size_t defer = (defers_final_block()) ? 1 : 0;
150 if(slicer.remaining() < m_buffer.size() + defer) {
151 return std::nullopt;
152 }
153
154 return slicer.take(m_buffer.size());
155 }

References BOTAN_ASSERT_NOMSG, Botan::BufferSlicer::remaining(), and Botan::BufferSlicer::take().

Referenced by Botan::Streebog::add_data().

◆ operator=() [1/2]

template<typename T , size_t BLOCK_SIZE, AlignmentBufferFinalBlock FINAL_BLOCK_STRATEGY = AlignmentBufferFinalBlock::is_not_special>
AlignmentBuffer & Botan::AlignmentBuffer< T, BLOCK_SIZE, FINAL_BLOCK_STRATEGY >::operator= ( AlignmentBuffer< T, BLOCK_SIZE, FINAL_BLOCK_STRATEGY > && other)
defaultnoexcept

◆ operator=() [2/2]

template<typename T , size_t BLOCK_SIZE, AlignmentBufferFinalBlock FINAL_BLOCK_STRATEGY = AlignmentBufferFinalBlock::is_not_special>
AlignmentBuffer & Botan::AlignmentBuffer< T, BLOCK_SIZE, FINAL_BLOCK_STRATEGY >::operator= ( const AlignmentBuffer< T, BLOCK_SIZE, FINAL_BLOCK_STRATEGY > & other)
default

◆ ready_to_consume()

template<typename T , size_t BLOCK_SIZE, AlignmentBufferFinalBlock FINAL_BLOCK_STRATEGY = AlignmentBufferFinalBlock::is_not_special>
bool Botan::AlignmentBuffer< T, BLOCK_SIZE, FINAL_BLOCK_STRATEGY >::ready_to_consume ( ) const
inline
Returns
true if the buffer is full (i.e. a block is ready to be consumed)

Definition at line 232 of file alignment_buffer.h.

232{ return m_position == m_buffer.size(); }

◆ size()

template<typename T , size_t BLOCK_SIZE, AlignmentBufferFinalBlock FINAL_BLOCK_STRATEGY = AlignmentBufferFinalBlock::is_not_special>
size_t Botan::AlignmentBuffer< T, BLOCK_SIZE, FINAL_BLOCK_STRATEGY >::size ( ) const
inlineconstexpr

Definition at line 218 of file alignment_buffer.h.

218{ return m_buffer.size(); }

Referenced by Botan::BLAKE2b::key_schedule().


The documentation for this class was generated from the following file: