summaryrefslogtreecommitdiffstats
path: root/comm/third_party/botan/src/lib/base
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 17:32:43 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 17:32:43 +0000
commit6bf0a5cb5034a7e684dcc3500e841785237ce2dd (patch)
treea68f146d7fa01f0134297619fbe7e33db084e0aa /comm/third_party/botan/src/lib/base
parentInitial commit. (diff)
downloadthunderbird-upstream.tar.xz
thunderbird-upstream.zip
Adding upstream version 1:115.7.0.upstream/1%115.7.0upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'comm/third_party/botan/src/lib/base')
-rw-r--r--comm/third_party/botan/src/lib/base/botan.h41
-rw-r--r--comm/third_party/botan/src/lib/base/buf_comp.cpp54
-rw-r--r--comm/third_party/botan/src/lib/base/buf_comp.h178
-rw-r--r--comm/third_party/botan/src/lib/base/info.txt17
-rw-r--r--comm/third_party/botan/src/lib/base/init.h35
-rw-r--r--comm/third_party/botan/src/lib/base/key_spec.h14
-rw-r--r--comm/third_party/botan/src/lib/base/lookup.h179
-rw-r--r--comm/third_party/botan/src/lib/base/scan_name.cpp149
-rw-r--r--comm/third_party/botan/src/lib/base/scan_name.h124
-rw-r--r--comm/third_party/botan/src/lib/base/secmem.h136
-rw-r--r--comm/third_party/botan/src/lib/base/sym_algo.cpp24
-rw-r--r--comm/third_party/botan/src/lib/base/sym_algo.h190
-rw-r--r--comm/third_party/botan/src/lib/base/symkey.cpp134
-rw-r--r--comm/third_party/botan/src/lib/base/symkey.h150
14 files changed, 1425 insertions, 0 deletions
diff --git a/comm/third_party/botan/src/lib/base/botan.h b/comm/third_party/botan/src/lib/base/botan.h
new file mode 100644
index 0000000000..a473e8fbf2
--- /dev/null
+++ b/comm/third_party/botan/src/lib/base/botan.h
@@ -0,0 +1,41 @@
+/*
+* A vague catch all include file for Botan
+* (C) 1999-2007 Jack Lloyd
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#ifndef BOTAN_BOTAN_H_
+#define BOTAN_BOTAN_H_
+
+/*
+* There is no real reason for this header to exist beyond historical
+* reasons. The application should instead include the specific header
+* files that define the interfaces it intends to use.
+*
+* This header file will be removed in Botan 3.x
+*/
+
+#include <botan/lookup.h>
+#include <botan/version.h>
+#include <botan/parsing.h>
+#include <botan/init.h>
+#include <botan/rng.h>
+#include <botan/secmem.h>
+
+#if defined(BOTAN_HAS_AUTO_SEEDING_RNG)
+ #include <botan/auto_rng.h>
+#endif
+
+#if defined(BOTAN_HAS_FILTERS)
+ #include <botan/filters.h>
+#endif
+
+#if defined(BOTAN_HAS_PUBLIC_KEY_CRYPTO)
+ #include <botan/x509_key.h>
+ #include <botan/pkcs8.h>
+#endif
+
+BOTAN_DEPRECATED_HEADER(botan.h)
+
+#endif
diff --git a/comm/third_party/botan/src/lib/base/buf_comp.cpp b/comm/third_party/botan/src/lib/base/buf_comp.cpp
new file mode 100644
index 0000000000..e9a33c9d7f
--- /dev/null
+++ b/comm/third_party/botan/src/lib/base/buf_comp.cpp
@@ -0,0 +1,54 @@
+/*
+* (C) 2019 Jack Lloyd
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#include <botan/buf_comp.h>
+#include <botan/loadstor.h>
+
+namespace Botan {
+
+void Buffered_Computation::update_be(uint16_t val)
+ {
+ uint8_t inb[sizeof(val)];
+ store_be(val, inb);
+ add_data(inb, sizeof(inb));
+ }
+
+void Buffered_Computation::update_be(uint32_t val)
+ {
+ uint8_t inb[sizeof(val)];
+ store_be(val, inb);
+ add_data(inb, sizeof(inb));
+ }
+
+void Buffered_Computation::update_be(uint64_t val)
+ {
+ uint8_t inb[sizeof(val)];
+ store_be(val, inb);
+ add_data(inb, sizeof(inb));
+ }
+
+void Buffered_Computation::update_le(uint16_t val)
+ {
+ uint8_t inb[sizeof(val)];
+ store_le(val, inb);
+ add_data(inb, sizeof(inb));
+ }
+
+void Buffered_Computation::update_le(uint32_t val)
+ {
+ uint8_t inb[sizeof(val)];
+ store_le(val, inb);
+ add_data(inb, sizeof(inb));
+ }
+
+void Buffered_Computation::update_le(uint64_t val)
+ {
+ uint8_t inb[sizeof(val)];
+ store_le(val, inb);
+ add_data(inb, sizeof(inb));
+ }
+
+}
diff --git a/comm/third_party/botan/src/lib/base/buf_comp.h b/comm/third_party/botan/src/lib/base/buf_comp.h
new file mode 100644
index 0000000000..31bf485295
--- /dev/null
+++ b/comm/third_party/botan/src/lib/base/buf_comp.h
@@ -0,0 +1,178 @@
+/*
+* Buffered Computation
+* (C) 1999-2007 Jack Lloyd
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#ifndef BOTAN_BUFFERED_COMPUTATION_H_
+#define BOTAN_BUFFERED_COMPUTATION_H_
+
+#include <botan/secmem.h>
+#include <string>
+
+namespace Botan {
+
+/**
+* This class represents any kind of computation which uses an internal
+* state, such as hash functions or MACs
+*/
+class BOTAN_PUBLIC_API(2,0) Buffered_Computation
+ {
+ public:
+ /**
+ * @return length of the output of this function in bytes
+ */
+ virtual size_t output_length() const = 0;
+
+ /**
+ * Add new input to process.
+ * @param in the input to process as a byte array
+ * @param length of param in in bytes
+ */
+ void update(const uint8_t in[], size_t length) { add_data(in, length); }
+
+ /**
+ * Add new input to process.
+ * @param in the input to process as a secure_vector
+ */
+ void update(const secure_vector<uint8_t>& in)
+ {
+ add_data(in.data(), in.size());
+ }
+
+ /**
+ * Add new input to process.
+ * @param in the input to process as a std::vector
+ */
+ void update(const std::vector<uint8_t>& in)
+ {
+ add_data(in.data(), in.size());
+ }
+
+ void update_be(uint16_t val);
+ void update_be(uint32_t val);
+ void update_be(uint64_t val);
+
+ void update_le(uint16_t val);
+ void update_le(uint32_t val);
+ void update_le(uint64_t val);
+
+ /**
+ * Add new input to process.
+ * @param str the input to process as a std::string. Will be interpreted
+ * as a byte array based on the strings encoding.
+ */
+ void update(const std::string& str)
+ {
+ add_data(cast_char_ptr_to_uint8(str.data()), str.size());
+ }
+
+ /**
+ * Process a single byte.
+ * @param in the byte to process
+ */
+ void update(uint8_t in) { add_data(&in, 1); }
+
+ /**
+ * Complete the computation and retrieve the
+ * final result.
+ * @param out The byte array to be filled with the result.
+ * Must be of length output_length()
+ */
+ void final(uint8_t out[]) { final_result(out); }
+
+ /**
+ * Complete the computation and retrieve the
+ * final result.
+ * @return secure_vector holding the result
+ */
+ secure_vector<uint8_t> final()
+ {
+ secure_vector<uint8_t> output(output_length());
+ final_result(output.data());
+ return output;
+ }
+
+ std::vector<uint8_t> final_stdvec()
+ {
+ std::vector<uint8_t> output(output_length());
+ final_result(output.data());
+ return output;
+ }
+
+ template<typename Alloc>
+ void final(std::vector<uint8_t, Alloc>& out)
+ {
+ out.resize(output_length());
+ final_result(out.data());
+ }
+
+ /**
+ * Update and finalize computation. Does the same as calling update()
+ * and final() consecutively.
+ * @param in the input to process as a byte array
+ * @param length the length of the byte array
+ * @result the result of the call to final()
+ */
+ secure_vector<uint8_t> process(const uint8_t in[], size_t length)
+ {
+ add_data(in, length);
+ return final();
+ }
+
+ /**
+ * Update and finalize computation. Does the same as calling update()
+ * and final() consecutively.
+ * @param in the input to process
+ * @result the result of the call to final()
+ */
+ secure_vector<uint8_t> process(const secure_vector<uint8_t>& in)
+ {
+ add_data(in.data(), in.size());
+ return final();
+ }
+
+ /**
+ * Update and finalize computation. Does the same as calling update()
+ * and final() consecutively.
+ * @param in the input to process
+ * @result the result of the call to final()
+ */
+ secure_vector<uint8_t> process(const std::vector<uint8_t>& in)
+ {
+ add_data(in.data(), in.size());
+ return final();
+ }
+
+ /**
+ * Update and finalize computation. Does the same as calling update()
+ * and final() consecutively.
+ * @param in the input to process as a string
+ * @result the result of the call to final()
+ */
+ secure_vector<uint8_t> process(const std::string& in)
+ {
+ update(in);
+ return final();
+ }
+
+ virtual ~Buffered_Computation() = default;
+ private:
+ /**
+ * Add more data to the computation
+ * @param input is an input buffer
+ * @param length is the length of input in bytes
+ */
+ virtual void add_data(const uint8_t input[], size_t length) = 0;
+
+ /**
+ * Write the final output to out
+ * @param out is an output buffer of output_length()
+ */
+ virtual void final_result(uint8_t out[]) = 0;
+ };
+
+}
+
+#endif
diff --git a/comm/third_party/botan/src/lib/base/info.txt b/comm/third_party/botan/src/lib/base/info.txt
new file mode 100644
index 0000000000..fd3f7b8905
--- /dev/null
+++ b/comm/third_party/botan/src/lib/base/info.txt
@@ -0,0 +1,17 @@
+<header:public>
+botan.h
+buf_comp.h
+init.h
+key_spec.h
+lookup.h
+secmem.h
+scan_name.h
+sym_algo.h
+symkey.h
+</header:public>
+
+<requires>
+hex
+rng
+utils
+</requires>
diff --git a/comm/third_party/botan/src/lib/base/init.h b/comm/third_party/botan/src/lib/base/init.h
new file mode 100644
index 0000000000..668650846b
--- /dev/null
+++ b/comm/third_party/botan/src/lib/base/init.h
@@ -0,0 +1,35 @@
+/*
+* Library Initialization
+* (C) 1999-2008,2015 Jack Lloyd
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#ifndef BOTAN_LIBRARY_INITIALIZER_H_
+#define BOTAN_LIBRARY_INITIALIZER_H_
+
+#include <botan/types.h>
+#include <string>
+
+namespace Botan {
+
+BOTAN_DEPRECATED_HEADER(init.h)
+
+/*
+* Previously botan had state whose lifetime had to be explicitly
+* managed by the application. As of 1.11.14 this is no longer the
+* case, and this class is no longer needed and kept only for backwards
+* compatibility.
+*/
+class BOTAN_PUBLIC_API(2,0) BOTAN_DEPRECATED("LibraryInitializer is no longer required") LibraryInitializer final
+ {
+ public:
+ explicit LibraryInitializer(const std::string& /*ignored*/ = "") { }
+
+ static void initialize(const std::string& /*ignored*/ = "") {}
+ static void deinitialize() {}
+ };
+
+}
+
+#endif
diff --git a/comm/third_party/botan/src/lib/base/key_spec.h b/comm/third_party/botan/src/lib/base/key_spec.h
new file mode 100644
index 0000000000..85dcebe37e
--- /dev/null
+++ b/comm/third_party/botan/src/lib/base/key_spec.h
@@ -0,0 +1,14 @@
+/*
+* Symmetric Key Length Specification
+* (C) 2010 Jack Lloyd
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#ifndef BOTAN_KEY_LEN_SPECIFICATION_H_
+#define BOTAN_KEY_LEN_SPECIFICATION_H_
+
+#include <botan/sym_algo.h>
+BOTAN_DEPRECATED_HEADER(key_spec.h)
+
+#endif
diff --git a/comm/third_party/botan/src/lib/base/lookup.h b/comm/third_party/botan/src/lib/base/lookup.h
new file mode 100644
index 0000000000..4a14230db0
--- /dev/null
+++ b/comm/third_party/botan/src/lib/base/lookup.h
@@ -0,0 +1,179 @@
+/*
+* Algorithm Lookup
+* (C) 1999-2007,2015 Jack Lloyd
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#ifndef BOTAN_LOOKUP_H_
+#define BOTAN_LOOKUP_H_
+
+#include <botan/build.h>
+#include <botan/exceptn.h>
+#include <string>
+#include <vector>
+#include <memory>
+
+#if defined(BOTAN_HAS_BLOCK_CIPHER)
+ #include <botan/block_cipher.h>
+#endif
+
+#if defined(BOTAN_HAS_STREAM_CIPHER)
+ #include <botan/stream_cipher.h>
+#endif
+
+#if defined(BOTAN_HAS_HASH)
+ #include <botan/hash.h>
+#endif
+
+#if defined(BOTAN_HAS_MAC)
+ #include <botan/mac.h>
+#endif
+
+namespace Botan {
+
+BOTAN_DEPRECATED_HEADER(lookup.h)
+
+/*
+* As of 1.11.26 this header is deprecated. Instead use the calls T::create and
+* T::providers (as demonstrated in the implementation below).
+*/
+
+/*
+* Get an algorithm object
+* NOTE: these functions create and return new objects, letting the
+* caller assume ownership of them
+*/
+
+#if defined(BOTAN_HAS_BLOCK_CIPHER)
+
+/**
+* Block cipher factory method.
+*
+* @param algo_spec the name of the desired block cipher
+* @param provider the provider to use
+* @return pointer to the block cipher object
+*/
+BOTAN_DEPRECATED("Use BlockCipher::create")
+inline BlockCipher* get_block_cipher(const std::string& algo_spec,
+ const std::string& provider = "")
+ {
+ return BlockCipher::create(algo_spec, provider).release();
+ }
+
+BOTAN_DEPRECATED("Use BlockCipher::create_or_throw")
+inline std::unique_ptr<BlockCipher> make_block_cipher(const std::string& algo_spec,
+ const std::string& provider = "")
+ {
+ return BlockCipher::create_or_throw(algo_spec, provider);
+ }
+
+BOTAN_DEPRECATED("Use BlockCipher::providers")
+inline std::vector<std::string> get_block_cipher_providers(const std::string& algo_spec)
+ {
+ return BlockCipher::providers(algo_spec);
+ }
+
+#endif
+
+#if defined(BOTAN_HAS_STREAM_CIPHER)
+
+/**
+* Stream cipher factory method.
+*
+* @param algo_spec the name of the desired stream cipher
+* @param provider the provider to use
+* @return pointer to the stream cipher object
+*/
+BOTAN_DEPRECATED("Use StreamCipher::create")
+inline StreamCipher* get_stream_cipher(const std::string& algo_spec,
+ const std::string& provider = "")
+ {
+ return StreamCipher::create(algo_spec, provider).release();
+ }
+
+BOTAN_DEPRECATED("Use StreamCipher::create_or_throw")
+inline std::unique_ptr<StreamCipher> make_stream_cipher(const std::string& algo_spec,
+ const std::string& provider = "")
+ {
+ return StreamCipher::create_or_throw(algo_spec, provider);
+ }
+
+BOTAN_DEPRECATED("Use StreamCipher::providers")
+inline std::vector<std::string> get_stream_cipher_providers(const std::string& algo_spec)
+ {
+ return StreamCipher::providers(algo_spec);
+ }
+
+#endif
+
+#if defined(BOTAN_HAS_HASH)
+
+/**
+* Hash function factory method.
+*
+* @param algo_spec the name of the desired hash function
+* @param provider the provider to use
+* @return pointer to the hash function object
+*/
+BOTAN_DEPRECATED("Use HashFunction::create")
+inline HashFunction* get_hash_function(const std::string& algo_spec,
+ const std::string& provider = "")
+ {
+ return HashFunction::create(algo_spec, provider).release();
+ }
+
+BOTAN_DEPRECATED("Use HashFunction::create_or_throw")
+inline std::unique_ptr<HashFunction> make_hash_function(const std::string& algo_spec,
+ const std::string& provider = "")
+ {
+ return HashFunction::create_or_throw(algo_spec, provider);
+ }
+
+BOTAN_DEPRECATED("Use HashFunction::create")
+inline HashFunction* get_hash(const std::string& algo_spec,
+ const std::string& provider = "")
+ {
+ return HashFunction::create(algo_spec, provider).release();
+ }
+
+BOTAN_DEPRECATED("Use HashFunction::providers")
+inline std::vector<std::string> get_hash_function_providers(const std::string& algo_spec)
+ {
+ return HashFunction::providers(algo_spec);
+ }
+
+#endif
+
+#if defined(BOTAN_HAS_MAC)
+/**
+* MAC factory method.
+*
+* @param algo_spec the name of the desired MAC
+* @param provider the provider to use
+* @return pointer to the MAC object
+*/
+BOTAN_DEPRECATED("MessageAuthenticationCode::create")
+inline MessageAuthenticationCode* get_mac(const std::string& algo_spec,
+ const std::string& provider = "")
+ {
+ return MessageAuthenticationCode::create(algo_spec, provider).release();
+ }
+
+BOTAN_DEPRECATED("MessageAuthenticationCode::create_or_throw")
+inline std::unique_ptr<MessageAuthenticationCode> make_message_auth(const std::string& algo_spec,
+ const std::string& provider = "")
+ {
+ return MessageAuthenticationCode::create(algo_spec, provider);
+ }
+
+BOTAN_DEPRECATED("MessageAuthenticationCode::providers")
+inline std::vector<std::string> get_mac_providers(const std::string& algo_spec)
+ {
+ return MessageAuthenticationCode::providers(algo_spec);
+ }
+#endif
+
+}
+
+#endif
diff --git a/comm/third_party/botan/src/lib/base/scan_name.cpp b/comm/third_party/botan/src/lib/base/scan_name.cpp
new file mode 100644
index 0000000000..f79866ba61
--- /dev/null
+++ b/comm/third_party/botan/src/lib/base/scan_name.cpp
@@ -0,0 +1,149 @@
+/*
+* SCAN Name Abstraction
+* (C) 2008-2009,2015 Jack Lloyd
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#include <botan/scan_name.h>
+#include <botan/parsing.h>
+#include <botan/exceptn.h>
+
+namespace Botan {
+
+namespace {
+
+std::string make_arg(const std::vector<std::pair<size_t, std::string>>& name, size_t start)
+ {
+ std::string output = name[start].second;
+ size_t level = name[start].first;
+
+ size_t paren_depth = 0;
+
+ for(size_t i = start + 1; i != name.size(); ++i)
+ {
+ if(name[i].first <= name[start].first)
+ break;
+
+ if(name[i].first > level)
+ {
+ output += "(" + name[i].second;
+ ++paren_depth;
+ }
+ else if(name[i].first < level)
+ {
+ for (size_t j = name[i].first; j < level; j++) {
+ output += ")";
+ --paren_depth;
+ }
+ output += "," + name[i].second;
+ }
+ else
+ {
+ if(output[output.size() - 1] != '(')
+ output += ",";
+ output += name[i].second;
+ }
+
+ level = name[i].first;
+ }
+
+ for(size_t i = 0; i != paren_depth; ++i)
+ output += ")";
+
+ return output;
+ }
+
+}
+
+SCAN_Name::SCAN_Name(const char* algo_spec) : SCAN_Name(std::string(algo_spec))
+ {
+ }
+
+SCAN_Name::SCAN_Name(std::string algo_spec) : m_orig_algo_spec(algo_spec), m_alg_name(), m_args(), m_mode_info()
+ {
+ if(algo_spec.size() == 0)
+ throw Invalid_Argument("Expected algorithm name, got empty string");
+
+ std::vector<std::pair<size_t, std::string>> name;
+ size_t level = 0;
+ std::pair<size_t, std::string> accum = std::make_pair(level, "");
+
+ const std::string decoding_error = "Bad SCAN name '" + algo_spec + "': ";
+
+ for(size_t i = 0; i != algo_spec.size(); ++i)
+ {
+ char c = algo_spec[i];
+
+ if(c == '/' || c == ',' || c == '(' || c == ')')
+ {
+ if(c == '(')
+ ++level;
+ else if(c == ')')
+ {
+ if(level == 0)
+ throw Decoding_Error(decoding_error + "Mismatched parens");
+ --level;
+ }
+
+ if(c == '/' && level > 0)
+ accum.second.push_back(c);
+ else
+ {
+ if(accum.second != "")
+ name.push_back(accum);
+ accum = std::make_pair(level, "");
+ }
+ }
+ else
+ accum.second.push_back(c);
+ }
+
+ if(accum.second != "")
+ name.push_back(accum);
+
+ if(level != 0)
+ throw Decoding_Error(decoding_error + "Missing close paren");
+
+ if(name.size() == 0)
+ throw Decoding_Error(decoding_error + "Empty name");
+
+ m_alg_name = name[0].second;
+
+ bool in_modes = false;
+
+ for(size_t i = 1; i != name.size(); ++i)
+ {
+ if(name[i].first == 0)
+ {
+ m_mode_info.push_back(make_arg(name, i));
+ in_modes = true;
+ }
+ else if(name[i].first == 1 && !in_modes)
+ m_args.push_back(make_arg(name, i));
+ }
+ }
+
+std::string SCAN_Name::arg(size_t i) const
+ {
+ if(i >= arg_count())
+ throw Invalid_Argument("SCAN_Name::arg " + std::to_string(i) +
+ " out of range for '" + to_string() + "'");
+ return m_args[i];
+ }
+
+std::string SCAN_Name::arg(size_t i, const std::string& def_value) const
+ {
+ if(i >= arg_count())
+ return def_value;
+ return m_args[i];
+ }
+
+size_t SCAN_Name::arg_as_integer(size_t i, size_t def_value) const
+ {
+ if(i >= arg_count())
+ return def_value;
+ return to_u32bit(m_args[i]);
+ }
+
+}
diff --git a/comm/third_party/botan/src/lib/base/scan_name.h b/comm/third_party/botan/src/lib/base/scan_name.h
new file mode 100644
index 0000000000..069783d1bb
--- /dev/null
+++ b/comm/third_party/botan/src/lib/base/scan_name.h
@@ -0,0 +1,124 @@
+/*
+* SCAN Name Abstraction
+* (C) 2008,2015 Jack Lloyd
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#ifndef BOTAN_SCAN_NAME_H_
+#define BOTAN_SCAN_NAME_H_
+
+#include <botan/types.h>
+#include <string>
+#include <vector>
+
+BOTAN_FUTURE_INTERNAL_HEADER(scan_name.h)
+
+namespace Botan {
+
+/**
+A class encapsulating a SCAN name (similar to JCE conventions)
+http://www.users.zetnet.co.uk/hopwood/crypto/scan/
+*/
+class BOTAN_PUBLIC_API(2,0) SCAN_Name final
+ {
+ public:
+ /**
+ * Create a SCAN_Name
+ * @param algo_spec A SCAN-format name
+ */
+ explicit SCAN_Name(const char* algo_spec);
+
+ /**
+ * Create a SCAN_Name
+ * @param algo_spec A SCAN-format name
+ */
+ explicit SCAN_Name(std::string algo_spec);
+
+ /**
+ * @return original input string
+ */
+ const std::string& to_string() const { return m_orig_algo_spec; }
+
+ BOTAN_DEPRECATED("Use SCAN_Name::to_string") const std::string& as_string() const
+ {
+ return this->to_string();
+ }
+
+ /**
+ * @return algorithm name
+ */
+ const std::string& algo_name() const { return m_alg_name; }
+
+ /**
+ * @return number of arguments
+ */
+ size_t arg_count() const { return m_args.size(); }
+
+ /**
+ * @param lower is the lower bound
+ * @param upper is the upper bound
+ * @return if the number of arguments is between lower and upper
+ */
+ bool arg_count_between(size_t lower, size_t upper) const
+ { return ((arg_count() >= lower) && (arg_count() <= upper)); }
+
+ /**
+ * @param i which argument
+ * @return ith argument
+ */
+ std::string arg(size_t i) const;
+
+ /**
+ * @param i which argument
+ * @param def_value the default value
+ * @return ith argument or the default value
+ */
+ std::string arg(size_t i, const std::string& def_value) const;
+
+ /**
+ * @param i which argument
+ * @param def_value the default value
+ * @return ith argument as an integer, or the default value
+ */
+ size_t arg_as_integer(size_t i, size_t def_value) const;
+
+ /**
+ * @return cipher mode (if any)
+ */
+ std::string cipher_mode() const
+ { return (m_mode_info.size() >= 1) ? m_mode_info[0] : ""; }
+
+ /**
+ * @return cipher mode padding (if any)
+ */
+ std::string cipher_mode_pad() const
+ { return (m_mode_info.size() >= 2) ? m_mode_info[1] : ""; }
+
+ private:
+ std::string m_orig_algo_spec;
+ std::string m_alg_name;
+ std::vector<std::string> m_args;
+ std::vector<std::string> m_mode_info;
+ };
+
+// This is unrelated but it is convenient to stash it here
+template<typename T>
+std::vector<std::string> probe_providers_of(const std::string& algo_spec,
+ const std::vector<std::string>& possible)
+ {
+ std::vector<std::string> providers;
+ for(auto&& prov : possible)
+ {
+ std::unique_ptr<T> o(T::create(algo_spec, prov));
+ if(o)
+ {
+ providers.push_back(prov); // available
+ }
+ }
+ return providers;
+ }
+
+}
+
+#endif
diff --git a/comm/third_party/botan/src/lib/base/secmem.h b/comm/third_party/botan/src/lib/base/secmem.h
new file mode 100644
index 0000000000..a5ba5857a9
--- /dev/null
+++ b/comm/third_party/botan/src/lib/base/secmem.h
@@ -0,0 +1,136 @@
+/*
+* Secure Memory Buffers
+* (C) 1999-2007,2012 Jack Lloyd
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#ifndef BOTAN_SECURE_MEMORY_BUFFERS_H_
+#define BOTAN_SECURE_MEMORY_BUFFERS_H_
+
+#include <botan/types.h> // IWYU pragma: export
+#include <botan/mem_ops.h> // IWYU pragma: export
+#include <vector> // IWYU pragma: export
+#include <algorithm>
+#include <deque>
+#include <type_traits>
+
+namespace Botan {
+
+template<typename T>
+class secure_allocator
+ {
+ public:
+ /*
+ * Assert exists to prevent someone from doing something that will
+ * probably crash anyway (like secure_vector<non_POD_t> where ~non_POD_t
+ * deletes a member pointer which was zeroed before it ran).
+ * MSVC in debug mode uses non-integral proxy types in container types
+ * like std::vector, thus we disable the check there.
+ */
+#if !defined(_ITERATOR_DEBUG_LEVEL) || _ITERATOR_DEBUG_LEVEL == 0
+ static_assert(std::is_integral<T>::value, "secure_allocator supports only integer types");
+#endif
+
+ typedef T value_type;
+ typedef std::size_t size_type;
+
+ secure_allocator() noexcept = default;
+ secure_allocator(const secure_allocator&) noexcept = default;
+ secure_allocator& operator=(const secure_allocator&) noexcept = default;
+ ~secure_allocator() noexcept = default;
+
+ template<typename U>
+ secure_allocator(const secure_allocator<U>&) noexcept {}
+
+ T* allocate(std::size_t n)
+ {
+ return static_cast<T*>(allocate_memory(n, sizeof(T)));
+ }
+
+ void deallocate(T* p, std::size_t n)
+ {
+ deallocate_memory(p, n, sizeof(T));
+ }
+ };
+
+template<typename T, typename U> inline bool
+operator==(const secure_allocator<T>&, const secure_allocator<U>&)
+ { return true; }
+
+template<typename T, typename U> inline bool
+operator!=(const secure_allocator<T>&, const secure_allocator<U>&)
+ { return false; }
+
+template<typename T> using secure_vector = std::vector<T, secure_allocator<T>>;
+template<typename T> using secure_deque = std::deque<T, secure_allocator<T>>;
+
+// For better compatibility with 1.10 API
+template<typename T> using SecureVector = secure_vector<T>;
+
+template<typename T>
+std::vector<T> unlock(const secure_vector<T>& in)
+ {
+ return std::vector<T>(in.begin(), in.end());
+ }
+
+template<typename T, typename Alloc, typename Alloc2>
+std::vector<T, Alloc>&
+operator+=(std::vector<T, Alloc>& out,
+ const std::vector<T, Alloc2>& in)
+ {
+ out.reserve(out.size() + in.size());
+ out.insert(out.end(), in.begin(), in.end());
+ return out;
+ }
+
+template<typename T, typename Alloc>
+std::vector<T, Alloc>& operator+=(std::vector<T, Alloc>& out, T in)
+ {
+ out.push_back(in);
+ return out;
+ }
+
+template<typename T, typename Alloc, typename L>
+std::vector<T, Alloc>& operator+=(std::vector<T, Alloc>& out,
+ const std::pair<const T*, L>& in)
+ {
+ out.reserve(out.size() + in.second);
+ out.insert(out.end(), in.first, in.first + in.second);
+ return out;
+ }
+
+template<typename T, typename Alloc, typename L>
+std::vector<T, Alloc>& operator+=(std::vector<T, Alloc>& out,
+ const std::pair<T*, L>& in)
+ {
+ out.reserve(out.size() + in.second);
+ out.insert(out.end(), in.first, in.first + in.second);
+ return out;
+ }
+
+/**
+* Zeroise the values; length remains unchanged
+* @param vec the vector to zeroise
+*/
+template<typename T, typename Alloc>
+void zeroise(std::vector<T, Alloc>& vec)
+ {
+ clear_mem(vec.data(), vec.size());
+ }
+
+/**
+* Zeroise the values then free the memory
+* @param vec the vector to zeroise and free
+*/
+template<typename T, typename Alloc>
+void zap(std::vector<T, Alloc>& vec)
+ {
+ zeroise(vec);
+ vec.clear();
+ vec.shrink_to_fit();
+ }
+
+}
+
+#endif
diff --git a/comm/third_party/botan/src/lib/base/sym_algo.cpp b/comm/third_party/botan/src/lib/base/sym_algo.cpp
new file mode 100644
index 0000000000..fff4afbd14
--- /dev/null
+++ b/comm/third_party/botan/src/lib/base/sym_algo.cpp
@@ -0,0 +1,24 @@
+/*
+* (C) 2018 Jack Lloyd
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#include <botan/sym_algo.h>
+#include <botan/exceptn.h>
+
+namespace Botan {
+
+void SymmetricAlgorithm::throw_key_not_set_error() const
+ {
+ throw Key_Not_Set(name());
+ }
+
+void SymmetricAlgorithm::set_key(const uint8_t key[], size_t length)
+ {
+ if(!valid_keylength(length))
+ throw Invalid_Key_Length(name(), length);
+ key_schedule(key, length);
+ }
+
+}
diff --git a/comm/third_party/botan/src/lib/base/sym_algo.h b/comm/third_party/botan/src/lib/base/sym_algo.h
new file mode 100644
index 0000000000..41d9992927
--- /dev/null
+++ b/comm/third_party/botan/src/lib/base/sym_algo.h
@@ -0,0 +1,190 @@
+/*
+* Symmetric Algorithm Base Class
+* (C) 1999-2007 Jack Lloyd
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#ifndef BOTAN_SYMMETRIC_ALGORITHM_H_
+#define BOTAN_SYMMETRIC_ALGORITHM_H_
+
+#include <botan/symkey.h>
+#include <botan/types.h>
+
+namespace Botan {
+
+/**
+* Represents the length requirements on an algorithm key
+*/
+class BOTAN_PUBLIC_API(2,0) Key_Length_Specification final
+ {
+ public:
+ /**
+ * Constructor for fixed length keys
+ * @param keylen the supported key length
+ */
+ explicit Key_Length_Specification(size_t keylen) :
+ m_min_keylen(keylen),
+ m_max_keylen(keylen),
+ m_keylen_mod(1)
+ {
+ }
+
+ /**
+ * Constructor for variable length keys
+ * @param min_k the smallest supported key length
+ * @param max_k the largest supported key length
+ * @param k_mod the number of bytes the key must be a multiple of
+ */
+ Key_Length_Specification(size_t min_k,
+ size_t max_k,
+ size_t k_mod = 1) :
+ m_min_keylen(min_k),
+ m_max_keylen(max_k ? max_k : min_k),
+ m_keylen_mod(k_mod)
+ {
+ }
+
+ /**
+ * @param length is a key length in bytes
+ * @return true iff this length is a valid length for this algo
+ */
+ bool valid_keylength(size_t length) const
+ {
+ return ((length >= m_min_keylen) &&
+ (length <= m_max_keylen) &&
+ (length % m_keylen_mod == 0));
+ }
+
+ /**
+ * @return minimum key length in bytes
+ */
+ size_t minimum_keylength() const
+ {
+ return m_min_keylen;
+ }
+
+ /**
+ * @return maximum key length in bytes
+ */
+ size_t maximum_keylength() const
+ {
+ return m_max_keylen;
+ }
+
+ /**
+ * @return key length multiple in bytes
+ */
+ size_t keylength_multiple() const
+ {
+ return m_keylen_mod;
+ }
+
+ /*
+ * Multiplies all length requirements with the given factor
+ * @param n the multiplication factor
+ * @return a key length specification multiplied by the factor
+ */
+ Key_Length_Specification multiple(size_t n) const
+ {
+ return Key_Length_Specification(n * m_min_keylen,
+ n * m_max_keylen,
+ n * m_keylen_mod);
+ }
+
+ private:
+ size_t m_min_keylen, m_max_keylen, m_keylen_mod;
+ };
+
+/**
+* This class represents a symmetric algorithm object.
+*/
+class BOTAN_PUBLIC_API(2,0) SymmetricAlgorithm
+ {
+ public:
+ virtual ~SymmetricAlgorithm() = default;
+
+ /**
+ * Reset the state.
+ */
+ virtual void clear() = 0;
+
+ /**
+ * @return object describing limits on key size
+ */
+ virtual Key_Length_Specification key_spec() const = 0;
+
+ /**
+ * @return maximum allowed key length
+ */
+ size_t maximum_keylength() const
+ {
+ return key_spec().maximum_keylength();
+ }
+
+ /**
+ * @return minimum allowed key length
+ */
+ size_t minimum_keylength() const
+ {
+ return key_spec().minimum_keylength();
+ }
+
+ /**
+ * Check whether a given key length is valid for this algorithm.
+ * @param length the key length to be checked.
+ * @return true if the key length is valid.
+ */
+ bool valid_keylength(size_t length) const
+ {
+ return key_spec().valid_keylength(length);
+ }
+
+ /**
+ * Set the symmetric key of this object.
+ * @param key the SymmetricKey to be set.
+ */
+ void set_key(const SymmetricKey& key)
+ {
+ set_key(key.begin(), key.length());
+ }
+
+ template<typename Alloc>
+ void set_key(const std::vector<uint8_t, Alloc>& key)
+ {
+ set_key(key.data(), key.size());
+ }
+
+ /**
+ * Set the symmetric key of this object.
+ * @param key the to be set as a byte array.
+ * @param length in bytes of key param
+ */
+ void set_key(const uint8_t key[], size_t length);
+
+ /**
+ * @return the algorithm name
+ */
+ virtual std::string name() const = 0;
+
+ protected:
+ void verify_key_set(bool cond) const
+ {
+ if(cond == false)
+ throw_key_not_set_error();
+ }
+
+ private:
+ void throw_key_not_set_error() const;
+
+ /**
+ * Run the key schedule
+ * @param key the key
+ * @param length of key
+ */
+ virtual void key_schedule(const uint8_t key[], size_t length) = 0;
+ };
+
+}
+
+#endif
diff --git a/comm/third_party/botan/src/lib/base/symkey.cpp b/comm/third_party/botan/src/lib/base/symkey.cpp
new file mode 100644
index 0000000000..1e1781c675
--- /dev/null
+++ b/comm/third_party/botan/src/lib/base/symkey.cpp
@@ -0,0 +1,134 @@
+/*
+* OctetString
+* (C) 1999-2007 Jack Lloyd
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#include <botan/symkey.h>
+#include <botan/rng.h>
+#include <botan/hex.h>
+#include <algorithm>
+
+namespace Botan {
+
+/*
+* Create an OctetString from RNG output
+*/
+OctetString::OctetString(RandomNumberGenerator& rng,
+ size_t len)
+ {
+ rng.random_vec(m_data, len);
+ }
+
+/*
+* Create an OctetString from a hex string
+*/
+OctetString::OctetString(const std::string& hex_string)
+ {
+ if(!hex_string.empty())
+ {
+ m_data.resize(1 + hex_string.length() / 2);
+ m_data.resize(hex_decode(m_data.data(), hex_string));
+ }
+ }
+
+/*
+* Create an OctetString from a byte string
+*/
+OctetString::OctetString(const uint8_t in[], size_t n)
+ {
+ m_data.assign(in, in + n);
+ }
+
+/*
+* Set the parity of each key byte to odd
+*/
+void OctetString::set_odd_parity()
+ {
+ const uint8_t ODD_PARITY[256] = {
+ 0x01, 0x01, 0x02, 0x02, 0x04, 0x04, 0x07, 0x07, 0x08, 0x08, 0x0B, 0x0B,
+ 0x0D, 0x0D, 0x0E, 0x0E, 0x10, 0x10, 0x13, 0x13, 0x15, 0x15, 0x16, 0x16,
+ 0x19, 0x19, 0x1A, 0x1A, 0x1C, 0x1C, 0x1F, 0x1F, 0x20, 0x20, 0x23, 0x23,
+ 0x25, 0x25, 0x26, 0x26, 0x29, 0x29, 0x2A, 0x2A, 0x2C, 0x2C, 0x2F, 0x2F,
+ 0x31, 0x31, 0x32, 0x32, 0x34, 0x34, 0x37, 0x37, 0x38, 0x38, 0x3B, 0x3B,
+ 0x3D, 0x3D, 0x3E, 0x3E, 0x40, 0x40, 0x43, 0x43, 0x45, 0x45, 0x46, 0x46,
+ 0x49, 0x49, 0x4A, 0x4A, 0x4C, 0x4C, 0x4F, 0x4F, 0x51, 0x51, 0x52, 0x52,
+ 0x54, 0x54, 0x57, 0x57, 0x58, 0x58, 0x5B, 0x5B, 0x5D, 0x5D, 0x5E, 0x5E,
+ 0x61, 0x61, 0x62, 0x62, 0x64, 0x64, 0x67, 0x67, 0x68, 0x68, 0x6B, 0x6B,
+ 0x6D, 0x6D, 0x6E, 0x6E, 0x70, 0x70, 0x73, 0x73, 0x75, 0x75, 0x76, 0x76,
+ 0x79, 0x79, 0x7A, 0x7A, 0x7C, 0x7C, 0x7F, 0x7F, 0x80, 0x80, 0x83, 0x83,
+ 0x85, 0x85, 0x86, 0x86, 0x89, 0x89, 0x8A, 0x8A, 0x8C, 0x8C, 0x8F, 0x8F,
+ 0x91, 0x91, 0x92, 0x92, 0x94, 0x94, 0x97, 0x97, 0x98, 0x98, 0x9B, 0x9B,
+ 0x9D, 0x9D, 0x9E, 0x9E, 0xA1, 0xA1, 0xA2, 0xA2, 0xA4, 0xA4, 0xA7, 0xA7,
+ 0xA8, 0xA8, 0xAB, 0xAB, 0xAD, 0xAD, 0xAE, 0xAE, 0xB0, 0xB0, 0xB3, 0xB3,
+ 0xB5, 0xB5, 0xB6, 0xB6, 0xB9, 0xB9, 0xBA, 0xBA, 0xBC, 0xBC, 0xBF, 0xBF,
+ 0xC1, 0xC1, 0xC2, 0xC2, 0xC4, 0xC4, 0xC7, 0xC7, 0xC8, 0xC8, 0xCB, 0xCB,
+ 0xCD, 0xCD, 0xCE, 0xCE, 0xD0, 0xD0, 0xD3, 0xD3, 0xD5, 0xD5, 0xD6, 0xD6,
+ 0xD9, 0xD9, 0xDA, 0xDA, 0xDC, 0xDC, 0xDF, 0xDF, 0xE0, 0xE0, 0xE3, 0xE3,
+ 0xE5, 0xE5, 0xE6, 0xE6, 0xE9, 0xE9, 0xEA, 0xEA, 0xEC, 0xEC, 0xEF, 0xEF,
+ 0xF1, 0xF1, 0xF2, 0xF2, 0xF4, 0xF4, 0xF7, 0xF7, 0xF8, 0xF8, 0xFB, 0xFB,
+ 0xFD, 0xFD, 0xFE, 0xFE };
+
+ for(size_t j = 0; j != m_data.size(); ++j)
+ m_data[j] = ODD_PARITY[m_data[j]];
+ }
+
+/*
+* Hex encode an OctetString
+*/
+std::string OctetString::to_string() const
+ {
+ return hex_encode(m_data.data(), m_data.size());
+ }
+
+/*
+* XOR Operation for OctetStrings
+*/
+OctetString& OctetString::operator^=(const OctetString& k)
+ {
+ if(&k == this) { zeroise(m_data); return (*this); }
+ xor_buf(m_data.data(), k.begin(), std::min(length(), k.length()));
+ return (*this);
+ }
+
+/*
+* Equality Operation for OctetStrings
+*/
+bool operator==(const OctetString& s1, const OctetString& s2)
+ {
+ return (s1.bits_of() == s2.bits_of());
+ }
+
+/*
+* Unequality Operation for OctetStrings
+*/
+bool operator!=(const OctetString& s1, const OctetString& s2)
+ {
+ return !(s1 == s2);
+ }
+
+/*
+* Append Operation for OctetStrings
+*/
+OctetString operator+(const OctetString& k1, const OctetString& k2)
+ {
+ secure_vector<uint8_t> out;
+ out += k1.bits_of();
+ out += k2.bits_of();
+ return OctetString(out);
+ }
+
+/*
+* XOR Operation for OctetStrings
+*/
+OctetString operator^(const OctetString& k1, const OctetString& k2)
+ {
+ secure_vector<uint8_t> out(std::max(k1.length(), k2.length()));
+
+ copy_mem(out.data(), k1.begin(), k1.length());
+ xor_buf(out.data(), k2.begin(), k2.length());
+ return OctetString(out);
+ }
+
+}
diff --git a/comm/third_party/botan/src/lib/base/symkey.h b/comm/third_party/botan/src/lib/base/symkey.h
new file mode 100644
index 0000000000..69becdd4e0
--- /dev/null
+++ b/comm/third_party/botan/src/lib/base/symkey.h
@@ -0,0 +1,150 @@
+/*
+* OctetString
+* (C) 1999-2007 Jack Lloyd
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#ifndef BOTAN_SYMKEY_H_
+#define BOTAN_SYMKEY_H_
+
+#include <botan/secmem.h>
+#include <string>
+
+namespace Botan {
+
+/**
+* Octet String
+*/
+class BOTAN_PUBLIC_API(2,0) OctetString final
+ {
+ public:
+ /**
+ * @return size of this octet string in bytes
+ */
+ size_t length() const { return m_data.size(); }
+ size_t size() const { return m_data.size(); }
+
+ /**
+ * @return this object as a secure_vector<uint8_t>
+ */
+ secure_vector<uint8_t> bits_of() const { return m_data; }
+
+ /**
+ * @return start of this string
+ */
+ const uint8_t* begin() const { return m_data.data(); }
+
+ /**
+ * @return end of this string
+ */
+ const uint8_t* end() const { return begin() + m_data.size(); }
+
+ /**
+ * @return this encoded as hex
+ */
+ std::string to_string() const;
+
+ std::string BOTAN_DEPRECATED("Use OctetString::to_string") as_string() const
+ {
+ return this->to_string();
+ }
+
+ /**
+ * XOR the contents of another octet string into this one
+ * @param other octet string
+ * @return reference to this
+ */
+ OctetString& operator^=(const OctetString& other);
+
+ /**
+ * Force to have odd parity
+ */
+ void set_odd_parity();
+
+ /**
+ * Create a new OctetString
+ * @param str is a hex encoded string
+ */
+ explicit OctetString(const std::string& str = "");
+
+ /**
+ * Create a new random OctetString
+ * @param rng is a random number generator
+ * @param len is the desired length in bytes
+ */
+ OctetString(class RandomNumberGenerator& rng, size_t len);
+
+ /**
+ * Create a new OctetString
+ * @param in is an array
+ * @param len is the length of in in bytes
+ */
+ OctetString(const uint8_t in[], size_t len);
+
+ /**
+ * Create a new OctetString
+ * @param in a bytestring
+ */
+ OctetString(const secure_vector<uint8_t>& in) : m_data(in) {}
+
+ /**
+ * Create a new OctetString
+ * @param in a bytestring
+ */
+ OctetString(const std::vector<uint8_t>& in) : m_data(in.begin(), in.end()) {}
+
+ private:
+ secure_vector<uint8_t> m_data;
+ };
+
+/**
+* Compare two strings
+* @param x an octet string
+* @param y an octet string
+* @return if x is equal to y
+*/
+BOTAN_PUBLIC_API(2,0) bool operator==(const OctetString& x,
+ const OctetString& y);
+
+/**
+* Compare two strings
+* @param x an octet string
+* @param y an octet string
+* @return if x is not equal to y
+*/
+BOTAN_PUBLIC_API(2,0) bool operator!=(const OctetString& x,
+ const OctetString& y);
+
+/**
+* Concatenate two strings
+* @param x an octet string
+* @param y an octet string
+* @return x concatenated with y
+*/
+BOTAN_PUBLIC_API(2,0) OctetString operator+(const OctetString& x,
+ const OctetString& y);
+
+/**
+* XOR two strings
+* @param x an octet string
+* @param y an octet string
+* @return x XORed with y
+*/
+BOTAN_PUBLIC_API(2,0) OctetString operator^(const OctetString& x,
+ const OctetString& y);
+
+
+/**
+* Alternate name for octet string showing intent to use as a key
+*/
+using SymmetricKey = OctetString;
+
+/**
+* Alternate name for octet string showing intent to use as an IV
+*/
+using InitializationVector = OctetString;
+
+}
+
+#endif