Botan 3.13.0
Crypto and TLS for C&
trunc_hash.cpp
Go to the documentation of this file.
1/**
2 * Wrapper for truncated hashes
3 * (C) 2023 Jack Lloyd
4 * 2023 René Meusel - Rohde & Schwarz Cybersecurity
5 *
6 * Botan is released under the Simplified BSD License (see license.txt)
7 */
8
9#include <botan/internal/trunc_hash.h>
10
11#include <botan/assert.h>
12#include <botan/exceptn.h>
13#include <botan/mem_ops.h>
14#include <botan/internal/fmt.h>
15#include <algorithm>
16
17namespace Botan {
18
19void Truncated_Hash::add_data(std::span<const uint8_t> input) {
20 m_hash->update(input);
21}
22
23void Truncated_Hash::final_result(std::span<uint8_t> out) {
24 BOTAN_ASSERT_NOMSG(m_hash->output_length() * 8 >= m_output_bits);
25
26 m_hash->final(m_buffer);
27
28 // truncate output to a full number of bytes
29 const auto bytes = output_length();
30 copy_mem(out.data(), m_buffer.data(), bytes);
31 zeroise(m_buffer);
32
33 // mask the unwanted bits in the final byte
34 const uint8_t bits_in_last_byte = ((m_output_bits - 1) % 8) + 1;
35 const uint8_t bitmask = ~((1 << (8 - bits_in_last_byte)) - 1);
36
37 out.back() &= bitmask;
38}
39
41 return (m_output_bits + 7) / 8;
42}
43
45 return std::min(m_output_bits / 2, m_hash->security_level());
46}
47
48std::string Truncated_Hash::name() const {
49 return fmt("Truncated({},{})", m_hash->name(), m_output_bits);
50}
51
52std::unique_ptr<HashFunction> Truncated_Hash::new_object() const {
53 return std::make_unique<Truncated_Hash>(m_hash->new_object(), m_output_bits);
54}
55
56std::unique_ptr<HashFunction> Truncated_Hash::copy_state() const {
57 return std::make_unique<Truncated_Hash>(m_hash->copy_state(), m_output_bits);
58}
59
61 m_hash->clear();
62}
63
64Truncated_Hash::Truncated_Hash(std::unique_ptr<HashFunction> hash, size_t bits) :
65 m_hash(std::move(hash)), m_output_bits(bits) {
67
68 if(m_output_bits == 0) {
69 throw Invalid_Argument("Truncating a hash to 0 does not make sense");
70 }
71
72 const size_t hash_output_length = m_hash->output_length();
73 if(hash_output_length * 8 < m_output_bits) {
74 throw Invalid_Argument("Underlying hash function does not produce enough bytes for truncation");
75 }
76 m_buffer.resize(hash_output_length);
77}
78
79} // namespace Botan
#define BOTAN_ASSERT_NOMSG(expr)
Definition assert.h:75
#define BOTAN_ASSERT_NONNULL(ptr)
Definition assert.h:114
Truncated_Hash(std::unique_ptr< HashFunction > hash, size_t length)
size_t security_level() const override
size_t output_length() const override
std::string name() const override
std::unique_ptr< HashFunction > new_object() const override
std::unique_ptr< HashFunction > copy_state() const override
void clear() override
void zeroise(std::vector< T, Alloc > &vec)
Definition secmem.h:241
std::string fmt(std::string_view format, const T &... args)
Definition fmt.h:53
constexpr void copy_mem(T *out, const T *in, size_t n)
Definition mem_ops.h:144