Botan 3.13.0
Crypto and TLS for C&
Botan::Salsa20 Class Referencefinal

#include <salsa20.h>

Inheritance diagram for Botan::Salsa20:
Botan::StreamCipher Botan::SymmetricAlgorithm

Public Member Functions

size_t buffer_size () const override
void cipher (const uint8_t in[], uint8_t out[], size_t len)
void cipher (std::span< const uint8_t > in, std::span< uint8_t > out)
void cipher1 (std::span< uint8_t > buf)
void cipher1 (uint8_t buf[], size_t len)
void clear () override
StreamCipherclone () const
void decrypt (std::span< uint8_t > inout)
size_t default_iv_length () const override
void encipher (std::span< uint8_t > inout)
void encrypt (std::span< uint8_t > inout)
bool has_keying_material () const override
Key_Length_Specification key_spec () const override
template<concepts::resizable_byte_buffer T = secure_vector<uint8_t>>
keystream_bytes (size_t bytes)
size_t maximum_keylength () const
size_t minimum_keylength () const
std::string name () const override
std::unique_ptr< StreamCiphernew_object () const override
std::string provider () const override
std::optional< uint64_t > remaining_keystream_bytes () const override
void seek (uint64_t offset) override
void set_iv (const uint8_t iv[], size_t iv_len)
void set_iv (std::span< const uint8_t > iv)
void set_key (const OctetString &key)
void set_key (const uint8_t key[], size_t length)
void set_key (std::span< const uint8_t > key)
bool supports_seek () const override
bool valid_iv_length (size_t iv_len) const override
bool valid_keylength (size_t length) const
void write_keystream (std::span< uint8_t > out)
void write_keystream (uint8_t out[], size_t len)

Static Public Member Functions

static std::unique_ptr< StreamCiphercreate (std::string_view algo_spec, std::string_view provider="")
static std::unique_ptr< StreamCiphercreate_or_throw (std::string_view algo_spec, std::string_view provider="")
static void hsalsa20 (uint32_t output[8], const uint32_t input[16])
static std::vector< std::string > providers (std::string_view algo_spec)
static void salsa_core (uint8_t output[64], const uint32_t input[16], size_t rounds)

Protected Member Functions

void assert_key_material_set () const
void assert_key_material_set (bool predicate) const
void cipher_bytes (const uint8_t in[], uint8_t out[], size_t length) override
void generate_keystream (uint8_t out[], size_t len) override
void set_iv_bytes (const uint8_t iv[], size_t iv_len) override

Detailed Description

DJB's Salsa20 (and XSalsa20)

Definition at line 18 of file salsa20.h.

Member Function Documentation

◆ assert_key_material_set() [1/2]

◆ assert_key_material_set() [2/2]

void Botan::SymmetricAlgorithm::assert_key_material_set ( bool predicate) const
inlineprotectedinherited

Throw Key_Not_Set unless the predicate holds

Parameters
predicateif false, a Key_Not_Set exception is thrown

Definition at line 186 of file sym_algo.h.

186 {
187 if(!predicate) {
188 throw_key_not_set_error();
189 }
190 }

◆ buffer_size()

size_t Botan::Salsa20::buffer_size ( ) const
overridevirtual

Return the optimium buffer size to use with this cipher

Most stream ciphers internally produce blocks of bytes. This function returns that block size. Aligning buffer sizes to a multiple of this size may improve performance by reducing internal buffering overhead.

Note the return value of this function may change for any particular algorithm due to changes in the implementation from release to release, or changes in the runtime environment (such as CPUID indicating availability of an optimized implementation). It is not intrinsic to the algorithm; it is just a suggestion for gaining best performance.

Implements Botan::StreamCipher.

Definition at line 298 of file salsa20.cpp.

298 {
299 return 64;
300}

◆ cipher() [1/2]

void Botan::StreamCipher::cipher ( const uint8_t in[],
uint8_t out[],
size_t len )
inlineinherited

Encrypt or decrypt a message

Processes all bytes plain/ciphertext from in and writes the result to out.

Parameters
inthe plaintext
outthe byte array to hold the output, i.e. the ciphertext
lenthe length of both in and out in bytes

Definition at line 61 of file stream_cipher.h.

61{ cipher_bytes(in, out, len); }
virtual void cipher_bytes(const uint8_t in[], uint8_t out[], size_t len)=0

References cipher_bytes().

Referenced by cipher1(), cipher1(), create(), Botan::Sodium::crypto_stream_salsa20_xor_ic(), Botan::Sodium::crypto_stream_xsalsa20_xor_ic(), Botan::CTR_BE::CTR_BE(), Botan::CTR_BE::CTR_BE(), decrypt(), encipher(), encrypt(), and Botan::OFB::OFB().

◆ cipher() [2/2]

void Botan::StreamCipher::cipher ( std::span< const uint8_t > in,
std::span< uint8_t > out )
inherited

Encrypt or decrypt a message

Parameters
inthe plaintext
outthe byte array to hold the output, i.e. the ciphertext with at least the same size as in

Definition at line 133 of file stream_cipher.cpp.

133 {
134 BOTAN_ARG_CHECK(in.size() <= out.size(), "Output buffer of stream cipher must be at least as long as input buffer");
135 cipher_bytes(in.data(), out.data(), in.size());
136}
#define BOTAN_ARG_CHECK(expr, msg)
Definition assert.h:33

References BOTAN_ARG_CHECK, and cipher_bytes().

◆ cipher1() [1/2]

void Botan::StreamCipher::cipher1 ( std::span< uint8_t > buf)
inlineinherited

Encrypt or decrypt a message The message is encrypted/decrypted in place.

Parameters
bufthe plaintext / ciphertext

Definition at line 117 of file stream_cipher.h.

117{ cipher(buf, buf); }
void cipher(const uint8_t in[], uint8_t out[], size_t len)

References cipher().

◆ cipher1() [2/2]

void Botan::StreamCipher::cipher1 ( uint8_t buf[],
size_t len )
inlineinherited

Encrypt or decrypt a message The message is encrypted/decrypted in place.

Parameters
bufthe plaintext / ciphertext
lenthe length of buf in bytes

Definition at line 110 of file stream_cipher.h.

110{ cipher(buf, buf, len); }

References cipher().

Referenced by generate_keystream().

◆ cipher_bytes()

void Botan::Salsa20::cipher_bytes ( const uint8_t in[],
uint8_t out[],
size_t len )
overrideprotectedvirtual

Encrypt or decrypt a message

Implements Botan::StreamCipher.

Definition at line 214 of file salsa20.cpp.

214 {
216
217 while(length >= m_buffer.size() - m_position) {
218 const size_t available = m_buffer.size() - m_position;
219
220 xor_buf(out, in, &m_buffer[m_position], available);
221 salsa20(m_buffer.data(), m_buffer.size() / 64, m_state.data(), 20);
222
223 length -= available;
224 in += available;
225 out += available;
226
227 m_position = 0;
228 }
229
230 xor_buf(out, in, &m_buffer[m_position], length);
231
232 m_position += length;
233}
constexpr void xor_buf(ranges::contiguous_output_range< uint8_t > auto &&out, ranges::contiguous_range< uint8_t > auto &&in)
Definition mem_ops.h:403

References Botan::SymmetricAlgorithm::assert_key_material_set(), and Botan::xor_buf().

◆ clear()

void Botan::Salsa20::clear ( )
overridevirtual

Reset the internal state. This includes not just the key, but any partial message that may have been in process.

Implements Botan::SymmetricAlgorithm.

Definition at line 389 of file salsa20.cpp.

389 {
390 zap(m_key);
391 zap(m_state);
392 zap(m_buffer);
393 m_position = 0;
394}
void zap(std::vector< T, Alloc > &vec)
Definition secmem.h:261

References Botan::zap().

◆ clone()

StreamCipher * Botan::StreamCipher::clone ( ) const
inlineinherited

Create a new uninitialized object of the same type

Returns
a new object representing the same algorithm as *this

Definition at line 198 of file stream_cipher.h.

198{ return this->new_object().release(); }
virtual std::unique_ptr< StreamCipher > new_object() const =0

References new_object().

◆ create()

std::unique_ptr< StreamCipher > Botan::StreamCipher::create ( std::string_view algo_spec,
std::string_view provider = "" )
staticinherited

Create an instance based on a name If provider is empty then best available is chosen.

Parameters
algo_specalgorithm name
providerprovider implementation to use
Returns
a null pointer if the algo/provider combination cannot be found

Definition at line 40 of file stream_cipher.cpp.

40 {
41#if defined(BOTAN_HAS_SHAKE_CIPHER)
42 if(algo_spec == "SHAKE-128" || algo_spec == "SHAKE-128-XOF") {
43 if(provider.empty() || provider == "base") {
44 return std::make_unique<SHAKE_128_Cipher>();
45 }
46 }
47
48 if(algo_spec == "SHAKE-256" || algo_spec == "SHAKE-256-XOF") {
49 if(provider.empty() || provider == "base") {
50 return std::make_unique<SHAKE_256_Cipher>();
51 }
52 }
53#endif
54
55#if defined(BOTAN_HAS_CHACHA)
56 if(algo_spec == "ChaCha20") {
57 if(provider.empty() || provider == "base") {
58 return std::make_unique<ChaCha>(20);
59 }
60 }
61#endif
62
63#if defined(BOTAN_HAS_SALSA20)
64 if(algo_spec == "Salsa20") {
65 if(provider.empty() || provider == "base") {
66 return std::make_unique<Salsa20>();
67 }
68 }
69#endif
70
71 const SCAN_Name req(algo_spec);
72
73#if defined(BOTAN_HAS_CTR_BE)
74 if((req.algo_name() == "CTR-BE" || req.algo_name() == "CTR") && req.arg_count_between(1, 2)) {
75 if(provider.empty() || provider == "base") {
76 auto cipher = BlockCipher::create(req.arg(0));
77 if(cipher) {
78 const size_t ctr_size = req.arg_as_integer(1, cipher->block_size());
79 return std::make_unique<CTR_BE>(std::move(cipher), ctr_size);
80 }
81 }
82 }
83#endif
84
85#if defined(BOTAN_HAS_CHACHA)
86 if(req.algo_name() == "ChaCha") {
87 if(provider.empty() || provider == "base") {
88 return std::make_unique<ChaCha>(req.arg_as_integer(0, 20));
89 }
90 }
91#endif
92
93#if defined(BOTAN_HAS_OFB)
94 if(req.algo_name() == "OFB" && req.arg_count() == 1) {
95 if(provider.empty() || provider == "base") {
96 if(auto cipher = BlockCipher::create(req.arg(0))) {
97 return std::make_unique<OFB>(std::move(cipher));
98 }
99 }
100 }
101#endif
102
103#if defined(BOTAN_HAS_RC4)
104
105 if(req.algo_name() == "RC4" || req.algo_name() == "ARC4" || req.algo_name() == "MARK-4") {
106 const size_t skip = (req.algo_name() == "MARK-4") ? 256 : req.arg_as_integer(0, 0);
107
108 if(provider.empty() || provider == "base") {
109 return std::make_unique<RC4>(skip);
110 }
111 }
112
113#endif
114
115 BOTAN_UNUSED(req);
117
118 return nullptr;
119}
#define BOTAN_UNUSED
Definition assert.h:144
static std::unique_ptr< BlockCipher > create(std::string_view algo_spec, std::string_view provider="")
virtual std::string provider() const

References Botan::SCAN_Name::algo_name(), Botan::SCAN_Name::arg(), Botan::SCAN_Name::arg_as_integer(), Botan::SCAN_Name::arg_count(), Botan::SCAN_Name::arg_count_between(), BOTAN_UNUSED, cipher(), Botan::BlockCipher::create(), and provider().

Referenced by Botan::BlockCipher::create(), Botan::Cipher_Mode::create(), and create_or_throw().

◆ create_or_throw()

std::unique_ptr< StreamCipher > Botan::StreamCipher::create_or_throw ( std::string_view algo_spec,
std::string_view provider = "" )
staticinherited

Create an instance based on a name If provider is empty then best available is chosen.

Parameters
algo_specalgorithm name
providerprovider implementation to use Throws a Lookup_Error if the algo/provider combination cannot be found

Definition at line 122 of file stream_cipher.cpp.

122 {
123 if(auto sc = StreamCipher::create(algo, provider)) {
124 return sc;
125 }
126 throw Lookup_Error("Stream cipher", algo, provider);
127}
static std::unique_ptr< StreamCipher > create(std::string_view algo_spec, std::string_view provider="")

References create(), and provider().

Referenced by Botan::ChaCha_RNG::ChaCha_RNG(), Botan::ChaCha_RNG::ChaCha_RNG(), Botan::ChaCha_RNG::ChaCha_RNG(), Botan::ChaCha_RNG::ChaCha_RNG(), Botan::ChaCha_RNG::ChaCha_RNG(), Botan::Sodium::crypto_secretbox_detached(), Botan::Sodium::crypto_secretbox_open_detached(), Botan::Sodium::crypto_secretbox_xsalsa20poly1305(), Botan::Sodium::crypto_secretbox_xsalsa20poly1305_open(), Botan::Sodium::crypto_stream_chacha20(), Botan::Sodium::crypto_stream_chacha20_ietf(), Botan::Sodium::crypto_stream_chacha20_ietf_xor_ic(), Botan::Sodium::crypto_stream_chacha20_xor_ic(), Botan::Sodium::crypto_stream_xchacha20(), and Botan::Sodium::crypto_stream_xchacha20_xor_ic().

◆ decrypt()

void Botan::StreamCipher::decrypt ( std::span< uint8_t > inout)
inlineinherited

Decrypt a message in place The message is decrypted in place.

Parameters
inoutthe plaintext / ciphertext

Definition at line 138 of file stream_cipher.h.

138{ cipher(inout.data(), inout.data(), inout.size()); }

References cipher().

◆ default_iv_length()

size_t Botan::Salsa20::default_iv_length ( ) const
overridevirtual

Return the default (preferred) nonce length

If this function returns zero, then this cipher does not support nonces; in this case any call to set_iv with a (non-empty) value will fail.

Default implementation returns 0

Reimplemented from Botan::StreamCipher.

Definition at line 370 of file salsa20.cpp.

370 {
371 return 24;
372}

◆ encipher()

void Botan::StreamCipher::encipher ( std::span< uint8_t > inout)
inlineinherited

Encrypt a message The message is encrypted/decrypted in place.

Parameters
inoutthe plaintext / ciphertext

Definition at line 124 of file stream_cipher.h.

124{ cipher(inout.data(), inout.data(), inout.size()); }

References cipher().

◆ encrypt()

void Botan::StreamCipher::encrypt ( std::span< uint8_t > inout)
inlineinherited

Encrypt a message The message is encrypted in place.

Parameters
inoutthe plaintext / ciphertext

Definition at line 131 of file stream_cipher.h.

131{ cipher(inout.data(), inout.data(), inout.size()); }

References cipher().

◆ generate_keystream()

void Botan::Salsa20::generate_keystream ( uint8_t out[],
size_t len )
overrideprotectedvirtual

Write keystream bytes to a buffer

Reimplemented from Botan::StreamCipher.

Definition at line 235 of file salsa20.cpp.

235 {
237
238 while(length >= m_buffer.size() - m_position) {
239 const size_t available = m_buffer.size() - m_position;
240
241 // TODO: this could write directly to the output buffer
242 // instead of bouncing it through m_buffer first
243 copy_mem(out, &m_buffer[m_position], available);
244 salsa20(m_buffer.data(), m_buffer.size() / 64, m_state.data(), 20);
245
246 length -= available;
247 out += available;
248 m_position = 0;
249 }
250
251 copy_mem(out, &m_buffer[m_position], length);
252
253 m_position += length;
254}
constexpr void copy_mem(T *out, const T *in, size_t n)
Definition mem_ops.h:144

References Botan::SymmetricAlgorithm::assert_key_material_set(), and Botan::copy_mem().

◆ has_keying_material()

bool Botan::Salsa20::has_keying_material ( ) const
overridevirtual

Test whether a key has been set on this object

Returns
true if a key has been set on this object

Implements Botan::SymmetricAlgorithm.

Definition at line 294 of file salsa20.cpp.

294 {
295 return !m_state.empty();
296}

◆ hsalsa20()

void Botan::Salsa20::hsalsa20 ( uint32_t output[8],
const uint32_t input[16] )
static

Definition at line 35 of file salsa20.cpp.

35 {
36 uint32_t x00 = input[0];
37 uint32_t x01 = input[1];
38 uint32_t x02 = input[2];
39 uint32_t x03 = input[3];
40 uint32_t x04 = input[4];
41 uint32_t x05 = input[5];
42 uint32_t x06 = input[6];
43 uint32_t x07 = input[7];
44 uint32_t x08 = input[8];
45 uint32_t x09 = input[9];
46 uint32_t x10 = input[10];
47 uint32_t x11 = input[11];
48 uint32_t x12 = input[12];
49 uint32_t x13 = input[13];
50 uint32_t x14 = input[14];
51 uint32_t x15 = input[15];
52
53 for(size_t i = 0; i != 10; ++i) {
54 salsa20_quarter_round(x00, x04, x08, x12);
55 salsa20_quarter_round(x05, x09, x13, x01);
56 salsa20_quarter_round(x10, x14, x02, x06);
57 salsa20_quarter_round(x15, x03, x07, x11);
58
59 salsa20_quarter_round(x00, x01, x02, x03);
60 salsa20_quarter_round(x05, x06, x07, x04);
61 salsa20_quarter_round(x10, x11, x08, x09);
62 salsa20_quarter_round(x15, x12, x13, x14);
63 }
64
65 output[0] = x00;
66 output[1] = x05;
67 output[2] = x10;
68 output[3] = x15;
69 output[4] = x06;
70 output[5] = x07;
71 output[6] = x08;
72 output[7] = x09;
73}

Referenced by Botan::Sodium::crypto_core_hsalsa20(), and set_iv_bytes().

◆ key_spec()

Key_Length_Specification Botan::Salsa20::key_spec ( ) const
overridevirtual

Return the key lengths supported by this algorithm

Returns
object describing limits on key size

Implements Botan::SymmetricAlgorithm.

Definition at line 374 of file salsa20.cpp.

374 {
375 return Key_Length_Specification(16, 32, 16);
376}

◆ keystream_bytes()

template<concepts::resizable_byte_buffer T = secure_vector<uint8_t>>
T Botan::StreamCipher::keystream_bytes ( size_t bytes)
inlineinherited

Get bytes from the keystream

The bytes are written into a continuous byte buffer of your choosing.

Parameters
bytesThe number of bytes to be produced

Definition at line 98 of file stream_cipher.h.

98 {
99 T out(bytes);
100 write_keystream(out);
101 return out;
102 }
void write_keystream(uint8_t out[], size_t len)

References write_keystream().

◆ maximum_keylength()

size_t Botan::SymmetricAlgorithm::maximum_keylength ( ) const
inlineinherited

Return the largest acceptable key length

Returns
maximum allowed key length

Definition at line 130 of file sym_algo.h.

130{ return key_spec().maximum_keylength(); }
size_t maximum_keylength() const
Definition sym_algo.h:58
virtual Key_Length_Specification key_spec() const =0

References key_spec().

◆ minimum_keylength()

size_t Botan::SymmetricAlgorithm::minimum_keylength ( ) const
inlineinherited

Return the smallest acceptable key length

Returns
minimum allowed key length

Definition at line 136 of file sym_algo.h.

136{ return key_spec().minimum_keylength(); }
size_t minimum_keylength() const
Definition sym_algo.h:52

References key_spec().

◆ name()

std::string Botan::Salsa20::name ( ) const
overridevirtual

Return the name of this algorithm

Returns
the algorithm name

Implements Botan::SymmetricAlgorithm.

Definition at line 382 of file salsa20.cpp.

382 {
383 return "Salsa20";
384}

Referenced by set_iv_bytes().

◆ new_object()

std::unique_ptr< StreamCipher > Botan::Salsa20::new_object ( ) const
overridevirtual

Create a new uninitialized object of the same type

Returns
new object representing the same algorithm as *this

Implements Botan::StreamCipher.

Definition at line 378 of file salsa20.cpp.

378 {
379 return std::make_unique<Salsa20>();
380}

◆ provider()

std::string Botan::Salsa20::provider ( ) const
overridevirtual

Return the name of the provider implementing this object

Returns
provider information about this implementation. Default is "base", might also return "sse2", "avx2" or some other arbitrary string.

Reimplemented from Botan::StreamCipher.

Definition at line 145 of file salsa20.cpp.

145 {
146#if defined(BOTAN_HAS_SALSA20_AVX512)
147 if(auto feat = CPUID::check(CPUID::Feature::AVX512)) {
148 return *feat;
149 }
150#endif
151
152#if defined(BOTAN_HAS_SALSA20_AVX2)
153 if(auto feat = CPUID::check(CPUID::Feature::AVX2)) {
154 return *feat;
155 }
156#endif
157
158#if defined(BOTAN_HAS_SALSA20_SIMD32)
159 if(auto feat = CPUID::check(CPUID::Feature::SIMD_4X32)) {
160 return *feat;
161 }
162#endif
163
164 return "base";
165}
static std::optional< std::string > check(CPUID::Feature feat)
Definition cpuid.h:67

References Botan::CPUFeature::AVX2, Botan::CPUFeature::AVX512, Botan::CPUID::check(), and Botan::CPUFeature::SIMD_4X32.

◆ providers()

std::vector< std::string > Botan::StreamCipher::providers ( std::string_view algo_spec)
staticinherited

List the providers available for a given stream cipher

Returns
list of available providers for this algorithm, empty if not available

Definition at line 129 of file stream_cipher.cpp.

129 {
130 return probe_providers_of<StreamCipher>(algo_spec);
131}
std::vector< std::string > probe_providers_of(std::string_view algo_spec, const std::vector< std::string > &possible={"base"})
Definition scan_name.h:99

References Botan::probe_providers_of().

◆ remaining_keystream_bytes()

std::optional< uint64_t > Botan::Salsa20::remaining_keystream_bytes ( ) const
inlineoverridevirtual

Many stream ciphers are internally based on encrypting a counter of some kind. If the counter wraps around, keystream bytes would be repeated.

This function returns the number of keystream bytes that can still be produced under the current key/nonce settings, if that limit fits in a uint64_t. If there is no specific limit (eg due to being based on permutations rather than a counter), or if the limit is at least 2**64 bytes (where consuming the entire keystream is not practically possible), then this function returns nullopt.

Note this returns nullopt if no key is set (there are no keystream bytes at all available, in that state) or potentially if the nonce is not set (as in some cases, such as ChaCha, the available counter bytes vary depending on the size of the nonce used).

Implements Botan::StreamCipher.

Definition at line 33 of file salsa20.h.

33{ return {}; }

◆ salsa_core()

void Botan::Salsa20::salsa_core ( uint8_t output[64],
const uint32_t input[16],
size_t rounds )
static

Definition at line 79 of file salsa20.cpp.

79 {
80 BOTAN_ASSERT_NOMSG(rounds % 2 == 0);
81
82 uint32_t x00 = input[0];
83 uint32_t x01 = input[1];
84 uint32_t x02 = input[2];
85 uint32_t x03 = input[3];
86 uint32_t x04 = input[4];
87 uint32_t x05 = input[5];
88 uint32_t x06 = input[6];
89 uint32_t x07 = input[7];
90 uint32_t x08 = input[8];
91 uint32_t x09 = input[9];
92 uint32_t x10 = input[10];
93 uint32_t x11 = input[11];
94 uint32_t x12 = input[12];
95 uint32_t x13 = input[13];
96 uint32_t x14 = input[14];
97 uint32_t x15 = input[15];
98
99 for(size_t i = 0; i != rounds / 2; ++i) {
100 salsa20_quarter_round(x00, x04, x08, x12);
101 salsa20_quarter_round(x05, x09, x13, x01);
102 salsa20_quarter_round(x10, x14, x02, x06);
103 salsa20_quarter_round(x15, x03, x07, x11);
104
105 salsa20_quarter_round(x00, x01, x02, x03);
106 salsa20_quarter_round(x05, x06, x07, x04);
107 salsa20_quarter_round(x10, x11, x08, x09);
108 salsa20_quarter_round(x15, x12, x13, x14);
109 }
110
111 store_le(x00 + input[0], output + 4 * 0);
112 store_le(x01 + input[1], output + 4 * 1);
113 store_le(x02 + input[2], output + 4 * 2);
114 store_le(x03 + input[3], output + 4 * 3);
115 store_le(x04 + input[4], output + 4 * 4);
116 store_le(x05 + input[5], output + 4 * 5);
117 store_le(x06 + input[6], output + 4 * 6);
118 store_le(x07 + input[7], output + 4 * 7);
119 store_le(x08 + input[8], output + 4 * 8);
120 store_le(x09 + input[9], output + 4 * 9);
121 store_le(x10 + input[10], output + 4 * 10);
122 store_le(x11 + input[11], output + 4 * 11);
123 store_le(x12 + input[12], output + 4 * 12);
124 store_le(x13 + input[13], output + 4 * 13);
125 store_le(x14 + input[14], output + 4 * 14);
126 store_le(x15 + input[15], output + 4 * 15);
127}
#define BOTAN_ASSERT_NOMSG(expr)
Definition assert.h:75
constexpr auto store_le(ParamTs &&... params)
Definition loadstor.h:736

References BOTAN_ASSERT_NOMSG, and Botan::store_le().

◆ seek()

void Botan::Salsa20::seek ( uint64_t offset)
overridevirtual

Set the offset and the state used later to generate the keystream

Sets the state of the stream cipher and keystream according to the passed offset, exactly as if offset bytes had first been encrypted. The key and (if required) the IV have to be set before this can be called.

Note
Not all ciphers support seeking; such objects will throw Not_Implemented in this case. Use supports_seek() to query in advance.
Parameters
offsetthe offset where we begin to generate the keystream

Implements Botan::StreamCipher.

Definition at line 396 of file salsa20.cpp.

396 {
398
399 const uint64_t counter = offset / 64;
400
401 m_state[8] = static_cast<uint32_t>(counter);
402 m_state[9] = static_cast<uint32_t>(counter >> 32);
403
404 salsa20(m_buffer.data(), m_buffer.size() / 64, m_state.data(), 20);
405
406 m_position = offset % 64;
407}

References Botan::SymmetricAlgorithm::assert_key_material_set().

Referenced by Botan::Sodium::crypto_stream_salsa20_xor_ic(), and Botan::Sodium::crypto_stream_xsalsa20_xor_ic().

◆ set_iv() [1/2]

void Botan::StreamCipher::set_iv ( const uint8_t iv[],
size_t iv_len )
inlineinherited

Resync the cipher using the IV

Load IV into the stream cipher state. This should happen after the key is set (set_key()) and before any operation (encrypt(), decrypt() or seek()) is called.

If the cipher does not support IVs, then a call with an empty IV will be accepted and any other length will cause an Invalid_IV_Length exception.

Parameters
ivthe initialization vector
iv_lenthe length of the IV in bytes

Definition at line 168 of file stream_cipher.h.

168{ set_iv_bytes(iv, iv_len); }
virtual void set_iv_bytes(const uint8_t iv[], size_t iv_len)=0

References set_iv_bytes().

Referenced by Botan::Sodium::crypto_stream_salsa20(), Botan::Sodium::crypto_stream_salsa20_xor_ic(), Botan::Sodium::crypto_stream_xsalsa20(), Botan::Sodium::crypto_stream_xsalsa20_xor_ic(), Botan::Sodium::randombytes_buf_deterministic(), and Botan::SIV_Mode::set_ctr_iv().

◆ set_iv() [2/2]

void Botan::StreamCipher::set_iv ( std::span< const uint8_t > iv)
inlineinherited

Resync the cipher using the IV

Parameters
ivthe initialization vector
Exceptions
Invalid_IV_Lengthif an incompatible IV was passed.

Definition at line 175 of file stream_cipher.h.

175{ set_iv_bytes(iv.data(), iv.size()); }

References set_iv_bytes().

◆ set_iv_bytes()

void Botan::Salsa20::set_iv_bytes ( const uint8_t iv[],
size_t iv_len )
overrideprotectedvirtual

Resync the cipher using the IV

Implements Botan::StreamCipher.

Definition at line 320 of file salsa20.cpp.

320 {
322
323 if(!valid_iv_length(length)) {
324 throw Invalid_IV_Length(name(), length);
325 }
326
327 initialize_state();
328
329 if(length == 0) {
330 // Salsa20 null IV
331 m_state[6] = 0;
332 m_state[7] = 0;
333 } else if(length == 8) {
334 // Salsa20
335 m_state[6] = load_le<uint32_t>(iv, 0);
336 m_state[7] = load_le<uint32_t>(iv, 1);
337 } else {
338 // XSalsa20
339 m_state[6] = load_le<uint32_t>(iv, 0);
340 m_state[7] = load_le<uint32_t>(iv, 1);
341 m_state[8] = load_le<uint32_t>(iv, 2);
342 m_state[9] = load_le<uint32_t>(iv, 3);
343
344 secure_vector<uint32_t> hsalsa(8);
345 hsalsa20(hsalsa.data(), m_state.data());
346
347 m_state[1] = hsalsa[0];
348 m_state[2] = hsalsa[1];
349 m_state[3] = hsalsa[2];
350 m_state[4] = hsalsa[3];
351 m_state[6] = load_le<uint32_t>(iv, 4);
352 m_state[7] = load_le<uint32_t>(iv, 5);
353 m_state[11] = hsalsa[4];
354 m_state[12] = hsalsa[5];
355 m_state[13] = hsalsa[6];
356 m_state[14] = hsalsa[7];
357 }
358
359 m_state[8] = 0;
360 m_state[9] = 0;
361
362 salsa20(m_buffer.data(), m_buffer.size() / 64, m_state.data(), 20);
363 m_position = 0;
364}
static void hsalsa20(uint32_t output[8], const uint32_t input[16])
Definition salsa20.cpp:35
bool valid_iv_length(size_t iv_len) const override
Definition salsa20.cpp:366
std::string name() const override
Definition salsa20.cpp:382
constexpr auto load_le(ParamTs &&... params)
Definition loadstor.h:495
std::vector< T, secure_allocator< T > > secure_vector
Definition secmem.h:128

References Botan::SymmetricAlgorithm::assert_key_material_set(), hsalsa20(), Botan::load_le(), name(), and valid_iv_length().

◆ set_key() [1/3]

◆ set_key() [2/3]

void Botan::SymmetricAlgorithm::set_key ( const uint8_t key[],
size_t length )
inlineinherited

Set the symmetric key of this object.

Parameters
keythe to be set as a byte array.
lengthin bytes of key param

Definition at line 162 of file sym_algo.h.

162{ set_key(std::span{key, length}); }

References set_key().

Referenced by set_key().

◆ set_key() [3/3]

void Botan::SymmetricAlgorithm::set_key ( std::span< const uint8_t > key)
inherited

Set the symmetric key of this object.

Parameters
keythe contiguous byte range to be set.

Definition at line 22 of file sym_algo.cpp.

22 {
23 if(!valid_keylength(key.size())) {
24 throw Invalid_Key_Length(name(), key.size());
25 }
26 key_schedule(key);
27}
bool valid_keylength(size_t length) const
Definition sym_algo.h:143
virtual std::string name() const =0

References name(), and valid_keylength().

◆ supports_seek()

bool Botan::Salsa20::supports_seek ( ) const
inlineoverridevirtual

Test whether this cipher supports seeking within the keystream

Returns
true if this cipher implements seek(); false if seek() will throw Not_Implemented for any offset.

Implements Botan::StreamCipher.

Definition at line 30 of file salsa20.h.

30{ return true; }

◆ valid_iv_length()

bool Botan::Salsa20::valid_iv_length ( size_t iv_len) const
overridevirtual

Test if a nonce length is valid for this cipher

Parameters
iv_lenthe length of the IV in bytes
Returns
if the length is valid for this algorithm

Reimplemented from Botan::StreamCipher.

Definition at line 366 of file salsa20.cpp.

366 {
367 return (iv_len == 0 || iv_len == 8 || iv_len == 24);
368}

Referenced by set_iv_bytes().

◆ valid_keylength()

bool Botan::SymmetricAlgorithm::valid_keylength ( size_t length) const
inlineinherited

Check whether a given key length is valid for this algorithm.

Parameters
lengththe key length to be checked.
Returns
true if the key length is valid.

Definition at line 143 of file sym_algo.h.

143{ return key_spec().valid_keylength(length); }
bool valid_keylength(size_t length) const
Definition sym_algo.h:44

References key_spec().

Referenced by set_key().

◆ write_keystream() [1/2]

void Botan::StreamCipher::write_keystream ( std::span< uint8_t > out)
inlineinherited

Fill a given buffer with keystream bytes

The contents of out are ignored/overwritten

Parameters
outthe byte array to hold the keystream

Definition at line 88 of file stream_cipher.h.

88{ generate_keystream(out.data(), out.size()); }
virtual void generate_keystream(uint8_t out[], size_t len)

References generate_keystream().

◆ write_keystream() [2/2]

void Botan::StreamCipher::write_keystream ( uint8_t out[],
size_t len )
inlineinherited

Write keystream bytes to a buffer

The contents of out are ignored/overwritten

Parameters
outthe byte array to hold the keystream
lenthe length of out in bytes

Definition at line 79 of file stream_cipher.h.

79{ generate_keystream(out, len); }

References generate_keystream().

Referenced by Botan::Sodium::crypto_stream_salsa20(), Botan::Sodium::crypto_stream_xsalsa20(), keystream_bytes(), and Botan::Sodium::randombytes_buf_deterministic().


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