Botan 3.4.0
Crypto and TLS for C&
filters.h
Go to the documentation of this file.
1/*
2* Common Filters
3* (C) 1999-2007,2015 Jack Lloyd
4* (C) 2013 Joel Low
5*
6* Botan is released under the Simplified BSD License (see license.txt)
7*/
8
9#ifndef BOTAN_FILTERS_H_
10#define BOTAN_FILTERS_H_
11
12#include <botan/cipher_mode.h>
13#include <botan/data_snk.h>
14#include <botan/pipe.h>
15#include <botan/secmem.h>
16#include <botan/symkey.h>
17
18#if defined(BOTAN_TARGET_OS_HAS_THREADS)
19 #include <thread>
20#endif
21
22#if defined(BOTAN_HAS_STREAM_CIPHER)
23 #include <botan/stream_cipher.h>
24#endif
25
26#if defined(BOTAN_HAS_HASH)
27 #include <botan/hash.h>
28#endif
29
30#if defined(BOTAN_HAS_MAC)
31 #include <botan/mac.h>
32#endif
33
34namespace Botan {
35
36/**
37* Filter mixin that breaks input into blocks, useful for
38* cipher modes
39*/
41 public:
42 /**
43 * Write bytes into the buffered filter, which will them emit them
44 * in calls to buffered_block in the subclass
45 * @param in the input bytes
46 * @param length of in in bytes
47 */
48 void write(const uint8_t in[], size_t length);
49
50 template <typename Alloc>
51 void write(const std::vector<uint8_t, Alloc>& in, size_t length) {
52 write(in.data(), length);
53 }
54
55 /**
56 * Finish a message, emitting to buffered_block and buffered_final
57 * Will throw an exception if less than final_minimum bytes were
58 * written into the filter.
59 */
60 void end_msg();
61
62 /**
63 * Initialize a Buffered_Filter
64 * @param block_size the function buffered_block will be called
65 * with inputs which are a multiple of this size
66 * @param final_minimum the function buffered_final will be called
67 * with at least this many bytes.
68 */
69 Buffered_Filter(size_t block_size, size_t final_minimum);
70
71 virtual ~Buffered_Filter() = default;
72
73 protected:
74 /**
75 * The block processor, implemented by subclasses
76 * @param input some input bytes
77 * @param length the size of input, guaranteed to be a multiple
78 * of block_size
79 */
80 virtual void buffered_block(const uint8_t input[], size_t length) = 0;
81
82 /**
83 * The final block, implemented by subclasses
84 * @param input some input bytes
85 * @param length the size of input, guaranteed to be at least
86 * final_minimum bytes
87 */
88 virtual void buffered_final(const uint8_t input[], size_t length) = 0;
89
90 /**
91 * @return block size of inputs
92 */
93 size_t buffered_block_size() const { return m_main_block_mod; }
94
95 /**
96 * @return current position in the buffer
97 */
98 size_t current_position() const { return m_buffer_pos; }
99
100 /**
101 * Reset the buffer position
102 */
103 void buffer_reset() { m_buffer_pos = 0; }
104
105 private:
106 size_t m_main_block_mod, m_final_minimum;
107
108 secure_vector<uint8_t> m_buffer;
109 size_t m_buffer_pos;
110};
111
112/**
113* This class represents keyed filters, i.e. filters that have to be
114* fed with a key in order to function.
115*/
117 public:
118 /**
119 * Set the key of this filter
120 * @param key the key to use
121 */
122 virtual void set_key(const SymmetricKey& key) = 0;
123
124 /**
125 * Set the initialization vector of this filter. Note: you should
126 * call set_iv() only after you have called set_key()
127 * @param iv the initialization vector to use
128 */
129 virtual void set_iv(const InitializationVector& iv) {
130 if(iv.length() != 0) {
131 throw Invalid_IV_Length(name(), iv.length());
132 }
133 }
134
135 /**
136 * Check whether a key length is valid for this filter
137 * @param length the key length to be checked for validity
138 * @return true if the key length is valid, false otherwise
139 */
140 bool valid_keylength(size_t length) const { return key_spec().valid_keylength(length); }
141
142 /**
143 * @return object describing limits on key size
144 */
146
147 /**
148 * Check whether an IV length is valid for this filter
149 * @param length the IV length to be checked for validity
150 * @return true if the IV length is valid, false otherwise
151 */
152 virtual bool valid_iv_length(size_t length) const { return (length == 0); }
153};
154
155/**
156* Filter interface for cipher modes
157*/
159 private Buffered_Filter {
160 public:
161 explicit Cipher_Mode_Filter(Cipher_Mode* t);
162
163 explicit Cipher_Mode_Filter(std::unique_ptr<Cipher_Mode> t) : Cipher_Mode_Filter(t.release()) {}
164
165 void set_iv(const InitializationVector& iv) override;
166
167 void set_key(const SymmetricKey& key) override;
168
169 Key_Length_Specification key_spec() const override;
170
171 bool valid_iv_length(size_t length) const override;
172
173 std::string name() const override;
174
175 private:
176 void write(const uint8_t input[], size_t input_length) override;
177 void start_msg() override;
178 void end_msg() override;
179
180 void buffered_block(const uint8_t input[], size_t input_length) override;
181 void buffered_final(const uint8_t input[], size_t input_length) override;
182
183 std::unique_ptr<Cipher_Mode> m_mode;
184 std::vector<uint8_t> m_nonce;
185 secure_vector<uint8_t> m_buffer;
186};
187
188/*
189* Get a cipher object
190*/
191
192/**
193* Factory method for general symmetric cipher filters. No key will be
194* set in the filter.
195*
196* @param algo_spec the name of the desired cipher
197* @param direction determines whether the filter will be an encrypting or
198* decrypting filter
199* @return pointer to the encryption or decryption filter
200*/
201inline Keyed_Filter* get_cipher(std::string_view algo_spec, Cipher_Dir direction) {
202 auto c = Cipher_Mode::create_or_throw(algo_spec, direction);
203 return new Cipher_Mode_Filter(c.release());
204}
205
206/**
207* Factory method for general symmetric cipher filters.
208* @param algo_spec the name of the desired cipher
209* @param key the key to be used for encryption/decryption performed by
210* the filter
211* @param direction determines whether the filter will be an encrypting
212* or decrypting filter
213* @return pointer to the encryption or decryption filter
214*/
215inline Keyed_Filter* get_cipher(std::string_view algo_spec, const SymmetricKey& key, Cipher_Dir direction) {
216 Keyed_Filter* cipher = get_cipher(algo_spec, direction);
217 cipher->set_key(key);
218 return cipher;
219}
220
221/**
222* Factory method for general symmetric cipher filters.
223* @param algo_spec the name of the desired cipher
224* @param key the key to be used for encryption/decryption performed by
225* the filter
226* @param iv the initialization vector to be used
227* @param direction determines whether the filter will be an encrypting
228* or decrypting filter
229* @return pointer to newly allocated encryption or decryption filter
230*/
231inline Keyed_Filter* get_cipher(std::string_view algo_spec,
232 const SymmetricKey& key,
233 const InitializationVector& iv,
234 Cipher_Dir direction) {
235 Keyed_Filter* cipher = get_cipher(algo_spec, key, direction);
236 if(iv.length()) {
237 cipher->set_iv(iv);
238 }
239 return cipher;
240}
241
242#if defined(BOTAN_HAS_STREAM_CIPHER)
243
244/**
245* Stream Cipher Filter
246*/
247class BOTAN_PUBLIC_API(2, 0) StreamCipher_Filter final : public Keyed_Filter {
248 public:
249 std::string name() const override { return m_cipher->name(); }
250
251 /**
252 * Write input data
253 * @param input data
254 * @param input_len length of input in bytes
255 */
256 void write(const uint8_t input[], size_t input_len) override;
257
258 bool valid_iv_length(size_t iv_len) const override { return m_cipher->valid_iv_length(iv_len); }
259
260 /**
261 * Set the initialization vector for this filter.
262 * @param iv the initialization vector to set
263 */
264 void set_iv(const InitializationVector& iv) override { m_cipher->set_iv(iv.begin(), iv.length()); }
265
266 /**
267 * Set the key of this filter.
268 * @param key the key to set
269 */
270 void set_key(const SymmetricKey& key) override { m_cipher->set_key(key); }
271
272 Key_Length_Specification key_spec() const override { return m_cipher->key_spec(); }
273
274 /**
275 * Construct a stream cipher filter.
276 * @param cipher a cipher object to use
277 */
278 explicit StreamCipher_Filter(StreamCipher* cipher);
279
280 /**
281 * Construct a stream cipher filter.
282 * @param cipher a cipher object to use
283 * @param key the key to use inside this filter
284 */
285 StreamCipher_Filter(StreamCipher* cipher, const SymmetricKey& key);
286
287 /**
288 * Construct a stream cipher filter.
289 * @param cipher the name of the desired cipher
290 */
291 explicit StreamCipher_Filter(std::string_view cipher);
292
293 /**
294 * Construct a stream cipher filter.
295 * @param cipher the name of the desired cipher
296 * @param key the key to use inside this filter
297 */
298 StreamCipher_Filter(std::string_view cipher, const SymmetricKey& key);
299
300 private:
301 std::unique_ptr<StreamCipher> m_cipher;
302 secure_vector<uint8_t> m_buffer;
303};
304#endif
305
306#if defined(BOTAN_HAS_HASH)
307
308/**
309* Hash Filter.
310*/
311class BOTAN_PUBLIC_API(2, 0) Hash_Filter final : public Filter {
312 public:
313 void write(const uint8_t input[], size_t len) override { m_hash->update(input, len); }
314
315 void end_msg() override;
316
317 std::string name() const override { return m_hash->name(); }
318
319 /**
320 * Construct a hash filter.
321 * @param hash the hash function to use
322 * @param len the output length of this filter. Leave the default
323 * value 0 if you want to use the full output of the hashfunction
324 * hash. Otherwise, specify a smaller value here so that the
325 * output of the hash algorithm will be cut off.
326 */
327 Hash_Filter(HashFunction* hash, size_t len = 0) : m_hash(hash), m_out_len(len) {}
328
329 /**
330 * Construct a hash filter.
331 * @param request the name of the hash algorithm to use
332 * @param len the output length of this filter. Leave the default
333 * value 0 if you want to use the full output of the hashfunction
334 * hash. Otherwise, specify a smaller value here so that the
335 * output of the hash algorithm will be cut off.
336 */
337 Hash_Filter(std::string_view request, size_t len = 0);
338
339 private:
340 std::unique_ptr<HashFunction> m_hash;
341 const size_t m_out_len;
342};
343#endif
344
345#if defined(BOTAN_HAS_MAC)
346
347/**
348* MessageAuthenticationCode Filter.
349*/
350class BOTAN_PUBLIC_API(2, 0) MAC_Filter final : public Keyed_Filter {
351 public:
352 void write(const uint8_t input[], size_t len) override { m_mac->update(input, len); }
353
354 void end_msg() override;
355
356 std::string name() const override { return m_mac->name(); }
357
358 /**
359 * Set the key of this filter.
360 * @param key the key to set
361 */
362 void set_key(const SymmetricKey& key) override { m_mac->set_key(key); }
363
364 Key_Length_Specification key_spec() const override { return m_mac->key_spec(); }
365
366 /**
367 * Construct a MAC filter. The MAC key will be left empty.
368 * @param mac the MAC to use
369 * @param out_len the output length of this filter. Leave the default
370 * value 0 if you want to use the full output of the
371 * MAC. Otherwise, specify a smaller value here so that the
372 * output of the MAC will be cut off.
373 */
374 MAC_Filter(MessageAuthenticationCode* mac, size_t out_len = 0) : m_mac(mac), m_out_len(out_len) {}
375
376 /**
377 * Construct a MAC filter.
378 * @param mac the MAC to use
379 * @param key the MAC key to use
380 * @param out_len the output length of this filter. Leave the default
381 * value 0 if you want to use the full output of the
382 * MAC. Otherwise, specify a smaller value here so that the
383 * output of the MAC will be cut off.
384 */
385 MAC_Filter(MessageAuthenticationCode* mac, const SymmetricKey& key, size_t out_len = 0) :
386 m_mac(mac), m_out_len(out_len) {
387 m_mac->set_key(key);
388 }
389
390 /**
391 * Construct a MAC filter. The MAC key will be left empty.
392 * @param mac the name of the MAC to use
393 * @param len the output length of this filter. Leave the default
394 * value 0 if you want to use the full output of the
395 * MAC. Otherwise, specify a smaller value here so that the
396 * output of the MAC will be cut off.
397 */
398 MAC_Filter(std::string_view mac, size_t len = 0);
399
400 /**
401 * Construct a MAC filter.
402 * @param mac the name of the MAC to use
403 * @param key the MAC key to use
404 * @param len the output length of this filter. Leave the default
405 * value 0 if you want to use the full output of the
406 * MAC. Otherwise, specify a smaller value here so that the
407 * output of the MAC will be cut off.
408 */
409 MAC_Filter(std::string_view mac, const SymmetricKey& key, size_t len = 0);
410
411 private:
412 std::unique_ptr<MessageAuthenticationCode> m_mac;
413 const size_t m_out_len;
414};
415#endif
416
417#if defined(BOTAN_HAS_COMPRESSION)
418
419class Compression_Algorithm;
420class Decompression_Algorithm;
421
422/**
423* Filter interface for compression
424*/
425class BOTAN_PUBLIC_API(2, 0) Compression_Filter final : public Filter {
426 public:
427 void start_msg() override;
428 void write(const uint8_t input[], size_t input_length) override;
429 void end_msg() override;
430
431 void flush();
432
433 std::string name() const override;
434
435 Compression_Filter(std::string_view type, size_t compression_level, size_t buffer_size = 4096);
436
437 ~Compression_Filter() override;
438
439 private:
440 std::unique_ptr<Compression_Algorithm> m_comp;
441 size_t m_buffersize, m_level;
442 secure_vector<uint8_t> m_buffer;
443};
444
445/**
446* Filter interface for decompression
447*/
448class BOTAN_PUBLIC_API(2, 0) Decompression_Filter final : public Filter {
449 public:
450 void start_msg() override;
451 void write(const uint8_t input[], size_t input_length) override;
452 void end_msg() override;
453
454 std::string name() const override;
455
456 Decompression_Filter(std::string_view type, size_t buffer_size = 4096);
457
458 ~Decompression_Filter() override;
459
460 private:
461 std::unique_ptr<Decompression_Algorithm> m_comp;
462 std::size_t m_buffersize;
463 secure_vector<uint8_t> m_buffer;
464};
465
466#endif
467
468/**
469* This class represents a Base64 encoder.
470*/
472 public:
473 std::string name() const override { return "Base64_Encoder"; }
474
475 /**
476 * Input a part of a message to the encoder.
477 * @param input the message to input as a byte array
478 * @param length the length of the byte array input
479 */
480 void write(const uint8_t input[], size_t length) override;
481
482 /**
483 * Inform the Encoder that the current message shall be closed.
484 */
485 void end_msg() override;
486
487 /**
488 * Create a base64 encoder.
489 * @param line_breaks whether to use line breaks in the output
490 * @param line_length the length of the lines of the output
491 * @param trailing_newline whether to use a trailing newline
492 */
493 Base64_Encoder(bool line_breaks = false, size_t line_length = 72, bool trailing_newline = false);
494
495 private:
496 void encode_and_send(const uint8_t input[], size_t length, bool final_inputs = false);
497 void do_output(const uint8_t output[], size_t length);
498
499 const size_t m_line_length;
500 const bool m_trailing_newline;
501 std::vector<uint8_t> m_in, m_out;
502 size_t m_position, m_out_position;
503};
504
505/**
506* This object represents a Base64 decoder.
507*/
509 public:
510 std::string name() const override { return "Base64_Decoder"; }
511
512 /**
513 * Input a part of a message to the decoder.
514 * @param input the message to input as a byte array
515 * @param length the length of the byte array input
516 */
517 void write(const uint8_t input[], size_t length) override;
518
519 /**
520 * Finish up the current message
521 */
522 void end_msg() override;
523
524 /**
525 * Create a base64 decoder.
526 * @param checking the type of checking that shall be performed by
527 * the decoder
528 */
529 explicit Base64_Decoder(Decoder_Checking checking = NONE);
530
531 private:
532 const Decoder_Checking m_checking;
533 std::vector<uint8_t> m_in, m_out;
534 size_t m_position;
535};
536
537/**
538* Converts arbitrary binary data to hex strings, optionally with
539* newlines inserted
540*/
542 public:
543 /**
544 * Whether to use uppercase or lowercase letters for the encoded string.
545 */
546 enum Case { Uppercase, Lowercase };
547
548 std::string name() const override { return "Hex_Encoder"; }
549
550 void write(const uint8_t in[], size_t length) override;
551 void end_msg() override;
552
553 /**
554 * Create a hex encoder.
555 * @param the_case the case to use in the encoded strings.
556 */
557 explicit Hex_Encoder(Case the_case);
558
559 /**
560 * Create a hex encoder.
561 * @param newlines should newlines be used
562 * @param line_length if newlines are used, how long are lines
563 * @param the_case the case to use in the encoded strings
564 */
565 Hex_Encoder(bool newlines = false, size_t line_length = 72, Case the_case = Uppercase);
566
567 private:
568 void encode_and_send(const uint8_t[], size_t);
569
570 const Case m_casing;
571 const size_t m_line_length;
572 std::vector<uint8_t> m_in, m_out;
573 size_t m_position, m_counter;
574};
575
576/**
577* Converts hex strings to bytes
578*/
580 public:
581 std::string name() const override { return "Hex_Decoder"; }
582
583 void write(const uint8_t[], size_t) override;
584 void end_msg() override;
585
586 /**
587 * Construct a Hex Decoder using the specified
588 * character checking.
589 * @param checking the checking to use during decoding.
590 */
591 explicit Hex_Decoder(Decoder_Checking checking = NONE);
592
593 private:
594 const Decoder_Checking m_checking;
595 std::vector<uint8_t> m_in, m_out;
596 size_t m_position;
597};
598
599/**
600* BitBucket is a filter which simply discards all inputs
601*/
603 public:
604 void write(const uint8_t[], size_t) override { /* discard */
605 }
606
607 std::string name() const override { return "BitBucket"; }
608};
609
610/**
611* This class represents Filter chains. A Filter chain is an ordered
612* concatenation of Filters, the input to a Chain sequentially passes
613* through all the Filters contained in the Chain.
614*/
615
617 public:
618 void write(const uint8_t input[], size_t length) override { send(input, length); }
619
620 std::string name() const override { return "Chain"; }
621
622 /**
623 * Construct a chain of up to four filters. The filters are set
624 * up in the same order as the arguments.
625 */
626 Chain(Filter* = nullptr, Filter* = nullptr, Filter* = nullptr, Filter* = nullptr);
627
628 /**
629 * Construct a chain from range of filters
630 * @param filter_arr the list of filters
631 * @param length how many filters
632 */
633 Chain(Filter* filter_arr[], size_t length);
634};
635
636/**
637* This class represents a fork filter, whose purpose is to fork the
638* flow of data. It causes an input message to result in n messages at
639* the end of the filter, where n is the number of forks.
640*/
641class BOTAN_PUBLIC_API(2, 0) Fork : public Fanout_Filter {
642 public:
643 void write(const uint8_t input[], size_t length) override { send(input, length); }
644
645 void set_port(size_t n) { Fanout_Filter::set_port(n); }
646
647 std::string name() const override { return "Fork"; }
648
649 /**
650 * Construct a Fork filter with up to four forks.
651 */
652 Fork(Filter*, Filter*, Filter* = nullptr, Filter* = nullptr);
653
654 /**
655 * Construct a Fork from range of filters
656 * @param filter_arr the list of filters
657 * @param length how many filters
658 */
659 Fork(Filter* filter_arr[], size_t length);
660};
661
662#if defined(BOTAN_HAS_THREAD_UTILS)
663
664/**
665* This class is a threaded version of the Fork filter. While this uses
666* threads, the class itself is NOT thread-safe. This is meant as a drop-
667* in replacement for Fork where performance gains are possible.
668*/
669class BOTAN_PUBLIC_API(2, 0) Threaded_Fork final : public Fork {
670 public:
671 std::string name() const override;
672
673 /**
674 * Construct a Threaded_Fork filter with up to four forks.
675 */
676 Threaded_Fork(Filter*, Filter*, Filter* = nullptr, Filter* = nullptr);
677
678 /**
679 * Construct a Threaded_Fork from range of filters
680 * @param filter_arr the list of filters
681 * @param length how many filters
682 */
683 Threaded_Fork(Filter* filter_arr[], size_t length);
684
685 ~Threaded_Fork() override;
686
687 private:
688 void set_next(Filter* f[], size_t n);
689 void send(const uint8_t in[], size_t length) override;
690 void thread_delegate_work(const uint8_t input[], size_t length);
691 void thread_entry(Filter* filter);
692
693 std::vector<std::shared_ptr<std::thread>> m_threads;
694 std::unique_ptr<struct Threaded_Fork_Data> m_thread_data;
695};
696#endif
697
698} // namespace Botan
699
700#endif
std::string name() const override
Definition filters.h:510
std::string name() const override
Definition filters.h:473
std::string name() const override
Definition filters.h:607
void write(const uint8_t[], size_t) override
Definition filters.h:604
virtual ~Buffered_Filter()=default
void write(const std::vector< uint8_t, Alloc > &in, size_t length)
Definition filters.h:51
size_t current_position() const
Definition filters.h:98
virtual void buffered_block(const uint8_t input[], size_t length)=0
virtual void buffered_final(const uint8_t input[], size_t length)=0
size_t buffered_block_size() const
Definition filters.h:93
void write(const uint8_t input[], size_t length) override
Definition filters.h:618
std::string name() const override
Definition filters.h:620
Cipher_Mode_Filter(std::unique_ptr< Cipher_Mode > t)
Definition filters.h:163
static std::unique_ptr< Cipher_Mode > create_or_throw(std::string_view algo, Cipher_Dir direction, std::string_view provider="")
std::string name() const override
Definition filters.h:647
void set_port(size_t n)
Definition filters.h:645
void write(const uint8_t input[], size_t length) override
Definition filters.h:643
std::string name() const override
Definition filters.h:581
std::string name() const override
Definition filters.h:548
virtual void set_key(const SymmetricKey &key)=0
bool valid_keylength(size_t length) const
Definition filters.h:140
virtual void set_iv(const InitializationVector &iv)
Definition filters.h:129
virtual bool valid_iv_length(size_t length) const
Definition filters.h:152
virtual Key_Length_Specification key_spec() const =0
size_t length() const
Definition symkey.h:27
std::string name
int(* final)(unsigned char *, CTX *)
#define BOTAN_PUBLIC_API(maj, min)
Definition compiler.h:31
std::vector< T, secure_allocator< T > > secure_vector
Definition secmem.h:61
Decoder_Checking
Definition filter.h:165
Keyed_Filter * get_cipher(std::string_view algo_spec, Cipher_Dir direction)
Definition filters.h:201