Botan 3.13.0
Crypto and TLS for C&
tls_null.cpp
Go to the documentation of this file.
1/*
2* TLS Null Cipher Handling
3* (C) 2024 Sebastian Ahrens, Dirk Dobkowitz, André Schomburg (Volkswagen AG)
4* (C) 2024 Lars Dürkop (CARIAD SE)
5*
6* Botan is released under the Simplified BSD License (see license.txt)
7*/
8
9#include <botan/internal/tls_null.h>
10
11#include <botan/assert.h>
12#include <botan/tls_alert.h>
13#include <botan/tls_exceptn.h>
14#include <botan/internal/fmt.h>
15#include <botan/internal/int_utils.h>
16#include <botan/internal/loadstor.h>
17
18namespace Botan::TLS {
19
20/*
21* TLS_NULL_HMAC_AEAD_Mode Constructor
22*/
23TLS_NULL_HMAC_AEAD_Mode::TLS_NULL_HMAC_AEAD_Mode(std::unique_ptr<MessageAuthenticationCode> mac, size_t mac_keylen) :
24 m_mac_name(mac->name()), m_mac_keylen(mac_keylen), m_tag_size(mac->output_length()), m_mac(std::move(mac)) {}
25
27 m_key.clear();
28 m_ad.clear();
29 mac().clear();
30}
31
33 m_ad.clear();
34 // The base AEAD_Mode contract permits reset() before the first key has
35 // been set; only re-key the MAC if there is a key to re-key with.
36 if(!m_key.empty()) {
37 mac().set_key(m_key);
38 }
39}
40
41std::string TLS_NULL_HMAC_AEAD_Mode::name() const {
42 return fmt("TLS_NULL({})", m_mac_name);
43}
44
46 return 1;
47}
48
50 return 1;
51}
52
54 return nl == 0;
55}
56
60
64
66 return m_mac_keylen;
67}
68
73
74void TLS_NULL_HMAC_AEAD_Mode::key_schedule(std::span<const uint8_t> key) {
75 if(key.size() != m_mac_keylen) {
76 throw Invalid_Key_Length(name(), key.size());
77 }
78 m_key.assign(key.begin(), key.end());
79 reset();
80}
81
82void TLS_NULL_HMAC_AEAD_Mode::start_msg(const uint8_t nonce[], size_t nonce_len) {
83 BOTAN_UNUSED(nonce);
84
85 if(!valid_nonce_length(nonce_len)) {
86 throw Invalid_IV_Length(name(), nonce_len);
87 }
88
89 m_processed = false;
90
91 // AEAD_Mode contract: AD set via set_associated_data persists across
92 // messages until reset. finish_msg calls mac().final() which clears the
93 // internal state, so we re-feed the cached AD at the start of each
94 // message rather than once at set_associated_data time.
95 if(!m_ad.empty()) {
96 mac().update(m_ad);
97 }
98}
99
100size_t TLS_NULL_HMAC_AEAD_Mode::process_msg(uint8_t buf[], size_t sz) {
101 // The TLS record code path MACs each record in a single call (via
102 // finish_msg -> process). A second invocation between start_msg and
103 // finish_msg would feed additional bytes into the same HMAC instance,
104 // producing a tag covering more than the intended record body.
105 BOTAN_ASSERT_NOMSG(!m_processed);
106 m_processed = true;
107
108 mac().update(buf, sz);
109 return sz;
110}
111
112void TLS_NULL_HMAC_AEAD_Mode::set_associated_data_n(size_t idx, std::span<const uint8_t> ad) {
113 BOTAN_ARG_CHECK(idx == 0, "TLS 1.2 NULL/HMAC: cannot handle non-zero index in set_associated_data_n");
114 BOTAN_ARG_CHECK(ad.size() == 13, "TLS 1.2 NULL/HMAC: invalid TLS AEAD associated data length");
115
116 // Cache the AD; the actual MAC update happens at start_msg so the AD
117 // persists across messages per the AEAD_Mode contract.
118 m_ad.assign(ad.begin(), ad.end());
119}
120
121void TLS_NULL_HMAC_AEAD_Encryption::set_associated_data_n(size_t idx, std::span<const uint8_t> ad) {
123}
124
125size_t TLS_NULL_HMAC_AEAD_Encryption::output_length(size_t input_length) const {
126 return add_or_throw(input_length, tag_size(), "TLS NULL input too large");
127}
128
129void TLS_NULL_HMAC_AEAD_Encryption::finish_msg(secure_vector<uint8_t>& buffer, size_t offset) {
130 process(std::span{buffer}.subspan(offset));
131 const size_t output_size = add_or_throw(buffer.size(), tag_size(), "TLS NULL input too large");
132 buffer.resize(output_size);
133 mac().final(std::span{buffer}.last(tag_size()));
134}
135
136size_t TLS_NULL_HMAC_AEAD_Decryption::output_length(size_t input_length) const {
137 BOTAN_ARG_CHECK(input_length >= tag_size(), "Message too short to be valid");
138 return input_length - tag_size();
139}
140
142 BOTAN_ARG_CHECK(buffer.size() >= tag_size() + offset,
143 "TLS_NULL_HMAC_AEAD_Decryption needs at least tag_size() bytes in final buffer");
144
145 const auto data_and_tag = std::span{buffer}.subspan(offset);
146 const auto data = data_and_tag.first(data_and_tag.size() - tag_size());
147 const auto tag = data_and_tag.subspan(data.size());
148
149 process(data);
150 if(!mac().verify_mac(tag)) {
151 throw TLS_Exception(Alert::BadRecordMac, "Message authentication failure");
152 }
153
154 buffer.resize(buffer.size() - tag_size());
155}
156
157} // namespace Botan::TLS
#define BOTAN_UNUSED
Definition assert.h:144
#define BOTAN_ASSERT_NOMSG(expr)
Definition assert.h:75
#define BOTAN_ASSERT_NONNULL(ptr)
Definition assert.h:114
#define BOTAN_ARG_CHECK(expr, msg)
Definition assert.h:33
void update(const uint8_t in[], size_t length)
Definition buf_comp.h:35
void final(uint8_t out[])
Definition buf_comp.h:97
size_t process(std::span< uint8_t > msg)
virtual size_t output_length(size_t input_length) const =0
virtual bool has_keying_material() const =0
virtual void clear()=0
void set_key(const OctetString &key)
Definition sym_algo.cpp:14
void finish_msg(secure_vector< uint8_t > &final_block, size_t offset=0) override
Definition tls_null.cpp:141
size_t output_length(size_t input_length) const override
Definition tls_null.cpp:136
size_t output_length(size_t input_length) const override
Definition tls_null.cpp:125
void set_associated_data_n(size_t idx, std::span< const uint8_t > ad) override
Definition tls_null.cpp:121
size_t update_granularity() const final
Definition tls_null.cpp:45
size_t ideal_granularity() const final
Definition tls_null.cpp:49
void set_associated_data_n(size_t idx, std::span< const uint8_t > ad) override
Definition tls_null.cpp:112
bool has_keying_material() const final
Definition tls_null.cpp:61
MessageAuthenticationCode & mac() const
Definition tls_null.cpp:69
Key_Length_Specification key_spec() const final
Definition tls_null.cpp:57
std::string name() const final
Definition tls_null.cpp:41
bool valid_nonce_length(size_t nl) const final
Definition tls_null.cpp:53
TLS_NULL_HMAC_AEAD_Mode(std::unique_ptr< MessageAuthenticationCode > mac, size_t mac_keylen)
Definition tls_null.cpp:23
size_t tag_size() const final
Definition tls_null.h:35
constexpr T add_or_throw(T a, T b, std::string_view msg)
Definition int_utils.h:66
std::string fmt(std::string_view format, const T &... args)
Definition fmt.h:53
std::vector< T, secure_allocator< T > > secure_vector
Definition secmem.h:128