From f15cdfc6d954fd3d835a6d1b56632f0b3746b368 Mon Sep 17 00:00:00 2001
From: Philipp Weber
Date: Wed, 27 Apr 2016 15:22:08 +0200
Subject: add kdf1 implementation according to iso-18033 (preparation for
ecies)
---
doc/credits.rst | 6 ++++++
1 file changed, 6 insertions(+)
(limited to 'doc')
diff --git a/doc/credits.rst b/doc/credits.rst
index 6d62b6380..1b97ac3fc 100644
--- a/doc/credits.rst
+++ b/doc/credits.rst
@@ -104,3 +104,9 @@ snail-mail address (S), and Bitcoin address (B).
W: https://www.kullo.net
D: Build system
S: Germany
+
+ N: Philipp Weber
+ E: p.weber@sirrix.com
+ W: https://sirrix.com/
+ D: KDF1-18033
+ S: Saarland, Germany
--
cgit v1.2.3
From 2a58a43264c7994c19a1f05d807e40ffd95644c2 Mon Sep 17 00:00:00 2001
From: Philipp Weber
Date: Wed, 27 Apr 2016 15:39:40 +0200
Subject: add ecies implementation according to iso-18033
---
doc/credits.rst | 2 +-
src/lib/pubkey/ecies/ecies.cpp | 385 ++++++++++++++++++++++++++++++++++
src/lib/pubkey/ecies/ecies.h | 293 ++++++++++++++++++++++++++
src/lib/pubkey/ecies/info.txt | 9 +
src/tests/data/pubkey/ecies-18033.vec | 66 ++++++
src/tests/data/pubkey/ecies.vec | 126 +++++++++++
src/tests/test_ecies.cpp | 246 ++++++++++++++++++++++
7 files changed, 1126 insertions(+), 1 deletion(-)
create mode 100644 src/lib/pubkey/ecies/ecies.cpp
create mode 100644 src/lib/pubkey/ecies/ecies.h
create mode 100644 src/lib/pubkey/ecies/info.txt
create mode 100644 src/tests/data/pubkey/ecies-18033.vec
create mode 100644 src/tests/data/pubkey/ecies.vec
create mode 100644 src/tests/test_ecies.cpp
(limited to 'doc')
diff --git a/doc/credits.rst b/doc/credits.rst
index 1b97ac3fc..d113fc7de 100644
--- a/doc/credits.rst
+++ b/doc/credits.rst
@@ -108,5 +108,5 @@ snail-mail address (S), and Bitcoin address (B).
N: Philipp Weber
E: p.weber@sirrix.com
W: https://sirrix.com/
- D: KDF1-18033
+ D: KDF1-18033, ECIES
S: Saarland, Germany
diff --git a/src/lib/pubkey/ecies/ecies.cpp b/src/lib/pubkey/ecies/ecies.cpp
new file mode 100644
index 000000000..51ba3d172
--- /dev/null
+++ b/src/lib/pubkey/ecies/ecies.cpp
@@ -0,0 +1,385 @@
+/*
+* ECIES
+* (C) 2016 Philipp Weber
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#include
+#include
+#include
+
+#include
+#include
+
+namespace Botan {
+
+namespace {
+
+/**
+* Private key type for ECIES_ECDH_KA_Operation
+*/
+class ECIES_PrivateKey : public EC_PrivateKey, public PK_Key_Agreement_Key
+ {
+ public:
+ explicit ECIES_PrivateKey(const ECDH_PrivateKey& private_key) :
+ EC_PublicKey(private_key),
+ EC_PrivateKey(private_key),
+ PK_Key_Agreement_Key(),
+ m_key(private_key)
+ {
+ }
+
+ std::vector public_value() const override
+ {
+ return m_key.public_value();
+ }
+
+ std::string algo_name() const override
+ {
+ return "ECIES";
+ }
+
+ size_t max_input_bits() const override
+ {
+ return m_key.max_input_bits();
+ }
+
+ private:
+ ECDH_PrivateKey m_key;
+ };
+
+/**
+* Implements ECDH key agreement without using the cofactor mode
+*/
+class ECIES_ECDH_KA_Operation : public PK_Ops::Key_Agreement_with_KDF
+ {
+ public:
+ typedef ECIES_PrivateKey Key_Type;
+
+ ECIES_ECDH_KA_Operation(const ECIES_PrivateKey& private_key, const std::string&) :
+ PK_Ops::Key_Agreement_with_KDF("Raw"),
+ m_key(private_key)
+ {
+ }
+
+ secure_vector raw_agree(const byte w[], size_t w_len) override
+ {
+ const CurveGFp& curve = m_key.domain().get_curve();
+ PointGFp point = OS2ECP(w, w_len, curve);
+ PointGFp S = point * m_key.private_value();
+ BOTAN_ASSERT(S.on_the_curve(), "ECDH agreed value was on the curve");
+ return BigInt::encode_1363(S.get_affine_x(), curve.get_p().bytes());
+ }
+
+ private:
+ ECIES_PrivateKey m_key;
+ };
+
+/**
+* Creates a PK_Key_Agreement instance for the given key and ecies_params
+* Returns either ECIES_ECDH_KA_Operation or the default implementation for the given key,
+* depending on the key and ecies_params
+* @param private_key the private key used for the key agreement
+* @param ecies_params settings for ecies
+* @param for_encryption disable cofactor mode if the secret will be used for encryption
+* (according to ISO 18033 cofactor mode is only used during decryption)
+*/
+PK_Key_Agreement create_key_agreement(const PK_Key_Agreement_Key& private_key, const ECIES_KA_Params& ecies_params,
+ bool for_encryption)
+ {
+ const ECDH_PrivateKey* ecdh_key = dynamic_cast(&private_key);
+
+ if(ecdh_key == nullptr && (ecies_params.cofactor_mode() || ecies_params.old_cofactor_mode()
+ || ecies_params.check_mode()))
+ {
+ // assume we have a private key from an external provider (e.g. pkcs#11):
+ // there is no way to determine or control whether the provider uses cofactor mode or not.
+ // ISO 18033 does not allow cofactor mode in combination with old cofactor mode or check mode
+ // => disable cofactor mode, old cofactor mode and check mode for unknown keys/providers (as a precaution).
+ throw Invalid_Argument("ECIES: cofactor, old cofactor and check mode are only supported for ECDH_PrivateKey");
+ }
+
+ if(ecdh_key && (for_encryption || !ecies_params.cofactor_mode()))
+ {
+ // ECDH_KA_Operation uses cofactor mode: use own key agreement method if cofactor should not be used.
+ return PK_Key_Agreement(ECIES_PrivateKey(*ecdh_key), "Raw");
+ }
+
+ return PK_Key_Agreement(private_key, "Raw"); // use default implementation
+ }
+}
+
+BOTAN_REGISTER_PK_KEY_AGREE_OP("ECIES", ECIES_ECDH_KA_Operation);
+
+ECIES_KA_Operation::ECIES_KA_Operation(const PK_Key_Agreement_Key& private_key, const ECIES_KA_Params& ecies_params,
+ bool for_encryption) :
+ m_ka(create_key_agreement(private_key, ecies_params, for_encryption)),
+ m_params(ecies_params)
+ {
+ }
+
+/**
+* ECIES secret derivation according to ISO 18033-2
+*/
+SymmetricKey ECIES_KA_Operation::derive_secret(const std::vector& eph_public_key_bin,
+ const PointGFp& other_public_key_point) const
+ {
+ if(other_public_key_point.is_zero())
+ {
+ throw Invalid_Argument("ECIES: other public key point is zero");
+ }
+
+ std::unique_ptr kdf = m_params.create_kdf();
+ BOTAN_ASSERT(kdf != nullptr, "KDF is found");
+
+ PointGFp other_point = other_public_key_point;
+
+ // ISO 18033: step b
+ if(m_params.old_cofactor_mode())
+ {
+ other_point *= m_params.domain().get_cofactor();
+ }
+
+ secure_vector derivation_input;
+
+ // ISO 18033: encryption step e / decryption step g
+ if(!m_params.single_hash_mode())
+ {
+ derivation_input += eph_public_key_bin;
+ }
+
+ // ISO 18033: encryption step f / decryption step h
+ secure_vector other_public_key_bin = EC2OSP(other_point, static_cast(m_params.compression_type()));
+ // Note: the argument `m_params.secret_length()` passed for `key_len` will only be used by providers because
+ // "Raw" is passed to the `PK_Key_Agreement` if the implementation of botan is used.
+ const SymmetricKey peh = m_ka.derive_key(m_params.domain().get_order().bytes(), other_public_key_bin.data(), other_public_key_bin.size());
+ derivation_input.insert(derivation_input.end(), peh.begin(), peh.end());
+
+ // ISO 18033: encryption step g / decryption step i
+ return kdf->derive_key(m_params.secret_length(), derivation_input);
+ }
+
+
+ECIES_KA_Params::ECIES_KA_Params(const EC_Group& domain, const std::string& kdf_spec, size_t length,
+ PointGFp::Compression_Type compression_type, ECIES_Flags flags) :
+ m_domain(domain),
+ m_kdf_spec(kdf_spec),
+ m_length(length),
+ m_compression_mode(compression_type),
+ m_flags(flags)
+ {
+ }
+
+std::unique_ptr ECIES_KA_Params::create_kdf() const
+ {
+ std::unique_ptr kdf = Botan::KDF::create(m_kdf_spec);
+ if(kdf == nullptr)
+ {
+ throw Algorithm_Not_Found(m_kdf_spec);
+ }
+ return kdf;
+ }
+
+
+ECIES_System_Params::ECIES_System_Params(const EC_Group& domain, const std::string& kdf_spec,
+ const std::string& dem_algo_spec, size_t dem_key_len,
+ const std::string& mac_spec, size_t mac_key_len,
+ PointGFp::Compression_Type compression_type, ECIES_Flags flags) :
+ ECIES_KA_Params(domain, kdf_spec, dem_key_len + mac_key_len, compression_type, flags),
+ m_dem_spec(dem_algo_spec),
+ m_dem_keylen(dem_key_len),
+ m_mac_spec(mac_spec),
+ m_mac_keylen(mac_key_len)
+ {
+ // ISO 18033: "At most one of CofactorMode, OldCofactorMode, and CheckMode may be 1."
+ if(cofactor_mode() + old_cofactor_mode() + check_mode() > 1)
+ {
+ throw Invalid_Argument("ECIES: only one of cofactor_mode, old_cofactor_mode and check_mode can be set");
+ }
+ }
+
+ECIES_System_Params::ECIES_System_Params(const EC_Group& domain, const std::string& kdf_spec,
+ const std::string& dem_algo_spec, size_t dem_key_len,
+ const std::string& mac_spec, size_t mac_key_len) :
+ ECIES_System_Params(domain, kdf_spec, dem_algo_spec, dem_key_len, mac_spec, mac_key_len, PointGFp::UNCOMPRESSED,
+ ECIES_Flags::NONE)
+ {
+ }
+
+std::unique_ptr ECIES_System_Params::create_mac() const
+ {
+ std::unique_ptr mac = Botan::MessageAuthenticationCode::create(m_mac_spec);
+ if(mac == nullptr)
+ {
+ throw Algorithm_Not_Found(m_mac_spec);
+ }
+ return mac;
+ }
+
+std::unique_ptr ECIES_System_Params::create_cipher(Botan::Cipher_Dir direction) const
+ {
+ Keyed_Filter* cipher = get_cipher(m_dem_spec, direction);
+ if(cipher == nullptr)
+ {
+ throw Algorithm_Not_Found(m_dem_spec);
+ }
+ return std::unique_ptr(cipher);
+ }
+
+
+/*
+* ECIES_Encryptor Constructor
+*/
+ECIES_Encryptor::ECIES_Encryptor(const PK_Key_Agreement_Key& private_key, const ECIES_System_Params& ecies_params) :
+ m_ka(private_key, ecies_params, true),
+ m_params(ecies_params),
+ m_eph_public_key_bin(private_key.public_value()), // returns the uncompressed public key, see conversion below
+ m_iv(),
+ m_other_point(),
+ m_label()
+ {
+ if(ecies_params.compression_type() != PointGFp::UNCOMPRESSED)
+ {
+ // ISO 18033: step d
+ // convert only if necessary; m_eph_public_key_bin has been initialized with the uncompressed format
+ m_eph_public_key_bin = unlock(EC2OSP(OS2ECP(m_eph_public_key_bin, m_params.domain().get_curve()),
+ static_cast(ecies_params.compression_type())));
+ }
+ }
+
+/*
+* ECIES_Encryptor Constructor
+*/
+ECIES_Encryptor::ECIES_Encryptor(RandomNumberGenerator& rng, const ECIES_System_Params& ecies_params) :
+ ECIES_Encryptor(ECDH_PrivateKey(rng, ecies_params.domain()), ecies_params)
+ {
+ }
+
+
+/*
+* ECIES Encryption according to ISO 18033-2
+*/
+std::vector ECIES_Encryptor::enc(const byte data[], size_t length, RandomNumberGenerator&) const
+ {
+ if(m_other_point.is_zero())
+ {
+ throw Invalid_State("ECIES: the other key is zero");
+ }
+
+ const SymmetricKey secret_key = m_ka.derive_secret(m_eph_public_key_bin, m_other_point);
+
+ // encryption
+ std::unique_ptr cipher = m_params.create_cipher(ENCRYPTION);
+ BOTAN_ASSERT(cipher != nullptr, "Cipher is found");
+
+ cipher->set_key(SymmetricKey(secret_key.begin(), m_params.dem_keylen()));
+ if(m_iv.size() != 0)
+ {
+ cipher->set_iv(m_iv);
+ }
+ Pipe pipe(cipher.release());
+ pipe.process_msg(data, length);
+ const secure_vector encrypted_data = pipe.read_all(0);
+
+ // concat elements
+ std::unique_ptr mac = m_params.create_mac();
+ BOTAN_ASSERT(mac != nullptr, "MAC is found");
+
+ secure_vector out(m_eph_public_key_bin.size() + encrypted_data.size() + mac->output_length());
+ buffer_insert(out, 0, m_eph_public_key_bin);
+ buffer_insert(out, m_eph_public_key_bin.size(), encrypted_data);
+
+ // mac
+ mac->set_key(secret_key.begin() + m_params.dem_keylen(), m_params.mac_keylen());
+ mac->update(encrypted_data);
+ if(!m_label.empty())
+ {
+ mac->update(m_label);
+ }
+ mac->final(out.data() + m_eph_public_key_bin.size() + encrypted_data.size());
+
+ return unlock(out);
+ }
+
+
+ECIES_Decryptor::ECIES_Decryptor(const PK_Key_Agreement_Key& key, const ECIES_System_Params& ecies_params) :
+ m_ka(key, ecies_params, false),
+ m_params(ecies_params),
+ m_iv(),
+ m_label()
+ {
+ // ISO 18033: "If v > 1 and CheckMode = 0, then we must have gcd(µ, v) = 1." (v = index, µ = order)
+ if(!ecies_params.check_mode())
+ {
+ Botan::BigInt cofactor = m_params.domain().get_cofactor();
+ if(cofactor > 1 && Botan::gcd(cofactor, m_params.domain().get_order()) != 1)
+ {
+ throw Invalid_Argument("ECIES: gcd of cofactor and order must be 1 if check_mode is 0");
+ }
+ }
+ }
+
+/**
+* ECIES Decryption according to ISO 18033-2
+*/
+secure_vector ECIES_Decryptor::do_decrypt(byte& valid_mask, const byte in[], size_t in_len) const
+ {
+ size_t point_size = m_params.domain().get_curve().get_p().bytes();
+ if(m_params.compression_type() != PointGFp::COMPRESSED)
+ {
+ point_size *= 2; // uncompressed and hybrid contains x AND y
+ }
+ point_size += 1; // format byte
+
+ std::unique_ptr mac = m_params.create_mac();
+ BOTAN_ASSERT(mac != nullptr, "MAC is found");
+
+ if(in_len < point_size + mac->output_length())
+ {
+ throw Decoding_Error("ECIES decryption: ciphertext is too short");
+ }
+
+ // extract data
+ const std::vector other_public_key_bin(in, in + point_size); // the received (ephemeral) public key
+ const std::vector encrypted_data(in + point_size, in + in_len - mac->output_length());
+ const std::vector mac_data(in + in_len - mac->output_length(), in + in_len);
+
+ // ISO 18033: step a
+ PointGFp other_public_key = OS2ECP(other_public_key_bin, m_params.domain().get_curve());
+
+ // ISO 18033: step b
+ if(m_params.check_mode() && !other_public_key.on_the_curve())
+ {
+ throw Decoding_Error("ECIES decryption: received public key is not on the curve");
+ }
+
+ // ISO 18033: step e (and step f because get_affine_x (called by ECDH_KA_Operation::raw_agree)
+ // throws Illegal_Transformation if the point is zero)
+ const SymmetricKey secret_key = m_ka.derive_secret(other_public_key_bin, other_public_key);
+
+ // validate mac
+ mac->set_key(secret_key.begin() + m_params.dem_keylen(), m_params.mac_keylen());
+ mac->update(encrypted_data);
+ if(!m_label.empty())
+ {
+ mac->update(m_label);
+ }
+ const secure_vector calculated_mac = mac->final();
+ valid_mask = CT::expand_mask(same_mem(mac_data.data(), calculated_mac.data(), mac_data.size()));
+
+ // decrypt data
+ std::unique_ptr cipher = m_params.create_cipher(DECRYPTION);
+ BOTAN_ASSERT(cipher != nullptr, "Cipher is found");
+
+ cipher->set_key(SymmetricKey(secret_key.begin(), m_params.dem_keylen()));
+ if(m_iv.size() != 0)
+ {
+ cipher->set_iv(m_iv);
+ }
+ Pipe pipe(cipher.release());
+ pipe.process_msg(encrypted_data);
+ return pipe.read_all(0);
+ }
+
+}
diff --git a/src/lib/pubkey/ecies/ecies.h b/src/lib/pubkey/ecies/ecies.h
new file mode 100644
index 000000000..07937556c
--- /dev/null
+++ b/src/lib/pubkey/ecies/ecies.h
@@ -0,0 +1,293 @@
+/*
+* ECIES
+* (C) 2016 Philipp Weber
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#ifndef BOTAN_ECIES_H__
+#define BOTAN_ECIES_H__
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+namespace Botan {
+
+class RandomNumberGenerator;
+
+enum class ECIES_Flags : uint32_t
+ {
+ NONE = 0,
+
+ /// if set: prefix the input of the (ecdh) key agreement with the encoded (ephemeral) public key
+ SINGLE_HASH_MODE = 1,
+
+ /// (decryption only) if set: use cofactor multiplication during (ecdh) key agreement
+ COFACTOR_MODE = 2,
+
+ /// if set: use ecdhc instead of ecdh
+ OLD_COFACTOR_MODE = 4,
+
+ /// (decryption only) if set: test if the (ephemeral) public key is on the curve
+ CHECK_MODE = 8
+ };
+
+inline ECIES_Flags operator |(ECIES_Flags a, ECIES_Flags b)
+ {
+ return static_cast(static_cast(a) | static_cast(b));
+ }
+
+inline ECIES_Flags operator &(ECIES_Flags a, ECIES_Flags b)
+ {
+ return static_cast(static_cast(a) & static_cast(b));
+ }
+
+/**
+* Parameters for ecies secret derivation
+*/
+class BOTAN_DLL ECIES_KA_Params
+ {
+ public:
+ /**
+ * @param domain ec domain parameters of the involved ec keys
+ * @param kdf_spec name of the key derivation function
+ * @param length length of the secret to be derived
+ * @param compression_type format of encoded keys (affects the secret derivation if single_hash_mode is used)
+ * @param flags options, see documentation of ECIES_Flags
+ */
+ ECIES_KA_Params(const EC_Group& domain, const std::string& kdf_spec, size_t length,
+ PointGFp::Compression_Type compression_type, ECIES_Flags flags);
+
+ virtual ~ECIES_KA_Params() = default;
+
+ std::unique_ptr create_kdf() const;
+
+ inline const EC_Group& domain() const
+ {
+ return m_domain;
+ }
+
+ inline size_t secret_length() const
+ {
+ return m_length;
+ }
+
+ inline bool single_hash_mode() const
+ {
+ return (m_flags & ECIES_Flags::SINGLE_HASH_MODE) == ECIES_Flags::SINGLE_HASH_MODE;
+ }
+
+ inline bool cofactor_mode() const
+ {
+ return (m_flags & ECIES_Flags::COFACTOR_MODE) == ECIES_Flags::COFACTOR_MODE;
+ }
+
+ inline bool old_cofactor_mode() const
+ {
+ return (m_flags & ECIES_Flags::OLD_COFACTOR_MODE) == ECIES_Flags::OLD_COFACTOR_MODE;
+ }
+
+ inline bool check_mode() const
+ {
+ return (m_flags & ECIES_Flags::CHECK_MODE) == ECIES_Flags::CHECK_MODE;
+ }
+
+ inline PointGFp::Compression_Type compression_type() const
+ {
+ return m_compression_mode;
+ }
+
+ private:
+ const EC_Group m_domain;
+ const std::string m_kdf_spec;
+ const size_t m_length;
+ const PointGFp::Compression_Type m_compression_mode;
+ const ECIES_Flags m_flags;
+ };
+
+
+class BOTAN_DLL ECIES_System_Params : public ECIES_KA_Params
+ {
+ public:
+ /**
+ * @param domain ec domain parameters of the involved ec keys
+ * @param kdf_spec name of the key derivation function
+ * @param dem_algo_spec name of the data encryption method
+ * @param dem_key_len length of the key used for the data encryption method
+ * @param mac_spec name of the message authentication code
+ * @param mac_key_len length of the key used for the message authentication code
+ * @param compression_type format of encoded keys (affects the secret derivation if single_hash_mode is used)
+ * @param flags options, see documentation of ECIES_Flags
+ */
+ ECIES_System_Params(const EC_Group& domain, const std::string& kdf_spec, const std::string& dem_algo_spec,
+ size_t dem_key_len, const std::string& mac_spec, size_t mac_key_len);
+
+ /**
+ * @param domain ec domain parameters of the involved ec keys
+ * @param kdf_spec name of the key derivation function
+ * @param dem_algo_spec name of the data encryption method
+ * @param dem_key_len length of the key used for the data encryption method
+ * @param mac_spec name of the message authentication code
+ * @param mac_key_len length of the key used for the message authentication code
+ */
+ ECIES_System_Params(const EC_Group& domain, const std::string& kdf_spec, const std::string& dem_algo_spec,
+ size_t dem_key_len, const std::string& mac_spec, size_t mac_key_len,
+ PointGFp::Compression_Type compression_type, ECIES_Flags flags);
+
+ virtual ~ECIES_System_Params() = default;
+
+ /// creates an instance of the message authentication code
+ std::unique_ptr create_mac() const;
+
+ /// creates an instance of the data encryption method
+ std::unique_ptr create_cipher(Botan::Cipher_Dir direction) const;
+
+ /// returns the length of the key used by the data encryption method
+ inline size_t dem_keylen() const
+ {
+ return m_dem_keylen;
+ }
+
+ /// returns the length of the key used by the message authentication code
+ inline size_t mac_keylen() const
+ {
+ return m_mac_keylen;
+ }
+
+ private:
+ const std::string m_dem_spec;
+ const size_t m_dem_keylen;
+ const std::string m_mac_spec;
+ const size_t m_mac_keylen;
+ };
+
+
+/**
+* ECIES secret derivation according to ISO 18033-2
+*/
+class BOTAN_DLL ECIES_KA_Operation
+ {
+ public:
+ /**
+ * @param private_key the (ephemeral) private key which is used to derive the secret
+ * @param ecies_params settings for ecies
+ * @param for_encryption disable cofactor mode if the secret will be used for encryption
+ * (according to ISO 18033 cofactor mode is only used during decryption)
+ */
+ ECIES_KA_Operation(const PK_Key_Agreement_Key& private_key, const ECIES_KA_Params& ecies_params,
+ bool for_encryption);
+
+ /**
+ * Performs a key agreement with the provided keys and derives the secret from the result
+ * @param eph_public_key_bin the encoded (ephemeral) public key which belongs to the used (ephemeral) private key
+ * @param other_public_key_point public key point of the other party
+ */
+ SymmetricKey derive_secret(const std::vector& eph_public_key_bin,
+ const PointGFp& other_public_key_point) const;
+
+ private:
+ const PK_Key_Agreement m_ka;
+ const ECIES_KA_Params m_params;
+ };
+
+
+/**
+* ECIES Encryption according to ISO 18033-2
+*/
+class BOTAN_DLL ECIES_Encryptor : public PK_Encryptor
+ {
+ public:
+ /**
+ * @param private_key the (ephemeral) private key which is used for the key agreement
+ * @param ecies_params settings for ecies
+ */
+ ECIES_Encryptor(const PK_Key_Agreement_Key& private_key, const ECIES_System_Params& ecies_params);
+
+ /**
+ * Creates an ephemeral private key which is used for the key agreement
+ * @param rng random generator used during private key generation
+ * @param ecies_params settings for ecies
+ */
+ ECIES_Encryptor(RandomNumberGenerator& rng, const ECIES_System_Params& ecies_params);
+
+ /// Set the public key of the other party
+ inline void set_other_key(const Botan::PointGFp& public_point)
+ {
+ m_other_point = public_point;
+ }
+
+ /// Set the initialization vector for the data encryption method
+ inline void set_initialization_vector(const InitializationVector& iv)
+ {
+ m_iv = iv;
+ }
+
+ /// Set the label which is appended to the input for the message authentication code
+ inline void set_label(const std::string& label)
+ {
+ m_label = std::vector(label.begin(), label.end());
+ }
+
+ private:
+ std::vector enc(const byte data[], size_t length, RandomNumberGenerator&) const override;
+
+ inline size_t maximum_input_size() const override
+ {
+ return std::numeric_limits::max();
+ }
+
+ const ECIES_KA_Operation m_ka;
+ const ECIES_System_Params m_params;
+ std::vector m_eph_public_key_bin;
+ InitializationVector m_iv;
+ PointGFp m_other_point;
+ std::vector m_label;
+ };
+
+
+/**
+* ECIES Decryption according to ISO 18033-2
+*/
+class BOTAN_DLL ECIES_Decryptor : public PK_Decryptor
+ {
+ public:
+ /**
+ * @param private_key the private key which is used for the key agreement
+ * @param ecies_params settings for ecies
+ */
+ ECIES_Decryptor(const PK_Key_Agreement_Key& private_key, const ECIES_System_Params& ecies_params);
+
+ /// Set the initialization vector for the data encryption method
+ inline void set_initialization_vector(const InitializationVector& iv)
+ {
+ m_iv = iv;
+ }
+
+ /// Set the label which is appended to the input for the message authentication code
+ inline void set_label(const std::string& label)
+ {
+ m_label = std::vector(label.begin(), label.end());
+ }
+
+ private:
+ secure_vector do_decrypt(byte& valid_mask, const byte in[], size_t in_len) const;
+
+ const ECIES_KA_Operation m_ka;
+ const ECIES_System_Params m_params;
+ InitializationVector m_iv;
+ std::vector m_label;
+ };
+
+}
+
+#endif
diff --git a/src/lib/pubkey/ecies/info.txt b/src/lib/pubkey/ecies/info.txt
new file mode 100644
index 000000000..dacefc88a
--- /dev/null
+++ b/src/lib/pubkey/ecies/info.txt
@@ -0,0 +1,9 @@
+define ECIES 20160128
+
+
+kdf
+mac
+ecdh
+modes
+filters
+
\ No newline at end of file
diff --git a/src/tests/data/pubkey/ecies-18033.vec b/src/tests/data/pubkey/ecies-18033.vec
new file mode 100644
index 000000000..8937abd2c
--- /dev/null
+++ b/src/tests/data/pubkey/ecies-18033.vec
@@ -0,0 +1,66 @@
+# ISO/IEC 18033-2 2006
+# ECIES-KEM test vectors for ECModp-Group
+
+# ----------------------------------------------------------------------------------------------------
+
+# C.2.2
+# Kdf=Kdf1(Hash=Sha1())
+# Keylen=128
+# CofactorMode=0
+# OldCofactorMode=0
+# CheckMode=0
+# SingleHashMode=0
+
+format = uncompressed
+
+p = 0xfffffffffffffffffffffffffffffffeffffffffffffffff
+a = 0xfffffffffffffffffffffffffffffffefffffffffffffffc
+b = 0x64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1
+mu = 0xffffffffffffffffffffffff99def836146bc9b1b4d22831
+nu = 0x01
+gx = 0x188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012
+gy = 0x07192b95ffc8da78631011ed6b24cdd573f977a11e794811
+
+# Public Key
+hx = 0x1cbc74a41b4e84a1509f935e2328a0bb06104d8dbb8d2130
+hy = 0x7b2ab1f10d76fde1ea046a4ad5fb903734190151bb30cec2
+
+# Private Key
+x = 0xb67048c28d2d26a73f713d5ebb994ac92588464e7fe7d3f3
+
+# Encoding format = uncompressed_fmt
+r = 0x083d4ac64f1960a9836a84f91ca211a185814fa43a2c8f21
+C0 = 04ccc9ea07b8b71d25646b22b0e251362a3fa9e993042315df047b2e07dd2ffb89359945f3d22ca8757874be2536e0f924
+K = 9a709adeb6c7590ccfc7d594670dd2d74fcdda3f8622f2dbcf0f0c02966d5d9002db578c989bf4a5cc896d2a11d74e0c51efc1f8ee784897ab9b865a7232b5661b7cac87cf4150bdf23b015d7b525b797cf6d533e9f6ad49a4c6de5e7089724c9cadf0adf13ee51b41be6713653fc1cb2c95a1d1b771cc7429189861d7a829f3
+
+# ----------------------------------------------------------------------------------------------------
+
+# C.2.3
+# Kdf=Kdf1(Hash=Sha1())
+# Keylen=128
+# CofactorMode=0
+# OldCofactorMode=0
+# CheckMode=0
+# SingleHashMode=0
+
+format = compressed
+
+p = 0xfffffffffffffffffffffffffffffffeffffffffffffffff
+a = 0xfffffffffffffffffffffffffffffffefffffffffffffffc
+b = 0x64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1
+mu = 0xffffffffffffffffffffffff99def836146bc9b1b4d22831
+nu = 0x01
+gx = 0x188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012
+gy = 0x07192b95ffc8da78631011ed6b24cdd573f977a11e794811
+
+# Public Key
+hx = 0x1cbc74a41b4e84a1509f935e2328a0bb06104d8dbb8d2130
+hy = 0x7b2ab1f10d76fde1ea046a4ad5fb903734190151bb30cec2
+
+# Private Key
+x = 0xb67048c28d2d26a73f713d5ebb994ac92588464e7fe7d3f3
+
+# Encoding format = compressed_fmt
+r = 0x083d4ac64f1960a9836a84f91ca211a185814fa43a2c8f21
+C0 = 02ccc9ea07b8b71d25646b22b0e251362a3fa9e993042315df
+K = 8fbe0903fac2fa05df02278fe162708fb432f3cbf9bb14138d22be1d279f74bfb94f0843a153b708fcc8d9446c76f00e4ccabef85228195f732f4aedc5e48efcf2968c3a46f2df6f2afcbdf5ef79c958f233c6d208f3a7496e08f505d1c792b314b45ff647237b0aa186d0cdbab47a00fb4065d62cfc18f8a8d12c78ecbee3fd
diff --git a/src/tests/data/pubkey/ecies.vec b/src/tests/data/pubkey/ecies.vec
new file mode 100644
index 000000000..fcf0baf62
--- /dev/null
+++ b/src/tests/data/pubkey/ecies.vec
@@ -0,0 +1,126 @@
+# random keys created by botan
+
+# ciphertext created with bouncycastle 1.54. example:
+# public static void main( String[] args )
+# throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidCipherTextException
+# {
+# X9ECParameters spec = SECNamedCurves.getByName( "secp160r1" );
+# ECDomainParameters ecDomain = new ECDomainParameters( spec.getCurve(), spec.getG(), spec.getN() );
+#
+# ECPrivateKeyParameters alice = new ECPrivateKeyParameters( new BigInteger( "1239488582848888730519239446720775754920686817364", 10 ), ecDomain );
+# ECPrivateKeyParameters bob = new ECPrivateKeyParameters( new BigInteger( "1255825134563225934367124570783723166851629196761", 10 ), ecDomain );
+# ECPublicKeyParameters alicePublicKey = new ECPublicKeyParameters( alice.getParameters().getG().multiply( alice.getD() ), alice.getParameters() );
+# ECPublicKeyParameters bobPublicKey = new ECPublicKeyParameters( bob.getParameters().getG().multiply( bob.getD() ), bob.getParameters() );
+#
+# byte[] d = new byte[ 0 ];
+# byte[] e = new byte[ 0 ];
+# byte[] iv = new byte[ 16 ];
+# CipherParameters p = new ParametersWithIV( new IESWithCipherParameters( d, e, 160, 256 ), iv );
+#
+# IESEngine ecies =
+# new IESEngine( new ECDHBasicAgreement(), new KDF2BytesGenerator( new SHA1Digest() ), new HMac( new SHA256Digest() ), new PaddedBufferedBlockCipher( new CBCBlockCipher(
+# new AESEngine() ) ) );
+# ecies.init( true, alice, bobPublicKey, p );
+#
+# byte[] message = Hex.decode( "00" );
+# byte[] result = ecies.processBlock( message, 0, message.length );
+#
+# byte[] ephPublicKey = alicePublicKey.getQ().getEncoded( true );
+# byte[] out = Arrays.concatenate( ephPublicKey, result );
+#
+# System.out.println( Hex.toHexString( out ) );
+# }
+
+Curve = secp160r1
+PrivateKey = 1239488582848888730519239446720775754920686817364
+OtherPrivateKey = 1255825134563225934367124570783723166851629196761
+Kdf = KDF2(SHA-1)
+Dem = AES-256/CBC
+DemKeyLen = 32
+Iv = 00000000000000000000000000000000
+Mac = HMAC(SHA-256)
+MacKeyLen = 20
+Format = compressed
+CofactorMode = 0
+OldCofactorMode = 0
+CheckMode = 0
+SingleHashMode = 1
+Label =
+Plaintext = 00
+Ciphertext = 02b26eafa6b51a39790c32a75c2f10b3e8e89d698a6da2667af153734225c8922800db5e10b73975848cceac0fc78cef589b2e93a81cc204dbc7b9b901cbaa4509e61141d7
+
+Curve = secp521r1
+PrivateKey = 4050298667054381376040649773970530311598264897556821662677634075002761777100287880684822948852132235484464537021197213998300006547176718172344447619746779823
+OtherPrivateKey = 2294226772740614508941417891614236736606752960073669253551166842586609531509032791476032516821966982891507407145617606630445744825404691681749451640151380153
+Kdf = KDF2(SHA-1)
+Dem = Camellia-128/CBC
+DemKeyLen = 16
+Iv = FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+Mac = HMAC(SHA-256)
+MacKeyLen = 16
+Format = uncompressed
+CofactorMode = 0
+OldCofactorMode = 0
+CheckMode = 0
+SingleHashMode = 1
+Label = Test
+Plaintext = 000102030405060708090A0B0C0D0E0F
+Ciphertext = 0401519eaa0489ff9d51e98e4c22349463e2001cd06f8ce47d81d4007a79acf98e92c814686477cea666efc277dc84e15fc95e38aff8e16d478a44cd5c5f1517f8b1f300000591317f261c3d04a7207f01eae3ec70f23600f82c53cc0b85be7ac9f6ce79ef2ab416e5934d61ba9d346385d7545c57f77c7ea7c58e18c70cbfb0a24ae1b994eda8dbc666713558717077dde021d9252b7f68eef0bc369086f6a6cb991fcc2fbcac3671a122ba18541790974cef7420cb53e7d6f30d1b808dddd58a63413f7b
+
+# use secp112r2 - curve with cofactor != 1
+Curve = -----BEGIN EC PARAMETERS-----MHMCAQEwGgYHKoZIzj0BAQIPANt8Kr9i415mgHa+rSCLMCAEDmEnwkwF84oKqvZcDvAsBA5R3vGBXbXtdPzDTIXXCQQdBEujCrXokrThZJ3QkoZDrc1G9YguN0fe826VbpcCDjbfCq/YuNdZfKEFINBLAgEE-----END EC PARAMETERS-----
+PrivateKey = 656008468895526658474428975817604
+OtherPrivateKey = 563449446384594847151017584539074
+Kdf = KDF2(SHA-1)
+Dem = Camellia-128/CBC
+DemKeyLen = 16
+Iv = FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+Mac = HMAC(SHA-256)
+MacKeyLen = 16
+Format = uncompressed
+CofactorMode = 0
+OldCofactorMode = 1
+CheckMode = 0
+SingleHashMode = 1
+Label = Test
+Plaintext = 000102030405060708090A0B0C0D0E0F
+Ciphertext = 048c40bda0986dadeb651178b4a8e64b7735fb02f43e621151849ea761a0f79fbb500b76e4eb9cd65281b804406536d04059b60689ed286490afcbf8f7f32dfefff8d37d29d335cb11aef3cc5d65f87571e3c8799974038f9d377a2683
+
+# use secp112r2 - curve with cofactor != 1
+Curve = -----BEGIN EC PARAMETERS-----MHMCAQEwGgYHKoZIzj0BAQIPANt8Kr9i415mgHa+rSCLMCAEDmEnwkwF84oKqvZcDvAsBA5R3vGBXbXtdPzDTIXXCQQdBEujCrXokrThZJ3QkoZDrc1G9YguN0fe826VbpcCDjbfCq/YuNdZfKEFINBLAgEE-----END EC PARAMETERS-----
+PrivateKey = 656008468895526658474428975817604
+OtherPrivateKey = 563449446384594847151017584539074
+Kdf = KDF2(SHA-1)
+Dem = Camellia-128/CBC
+DemKeyLen = 16
+Iv = FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+Mac = HMAC(SHA-256)
+MacKeyLen = 16
+Format = uncompressed
+CofactorMode = 1
+OldCofactorMode = 0
+CheckMode = 0
+SingleHashMode = 1
+Label = Test
+Plaintext = 000102030405060708090A0B0C0D0E0F
+Ciphertext = 048c40bda0986dadeb651178b4a8e64b7735fb02f43e621151849ea761230f2bddf1ffa3262673bcb3f468dd8b92c31a32e23935cfd27dfcc123928a18bbc82bdcada733be6d42119d3fb968ac4b77fff9a47d336fa025bfad3ee54286
+
+# bouncycastle does not support aead ciphers with IESEngine -> empty ciphertext; the test suite asserts that the plaintext can be encrypted and decrypted properly
+
+Curve = brainpool512r1
+PrivateKey = 7978796978847894400103470063598909318992754342406974939475470191530421638356103244921001321651015274653183103561457607601257178840534133802655904526250737
+OtherPrivateKey = 2308129338363763325603164530220543667351108423592731601992535938718831256964324847657313285466745344259451280420400800014583532495130674675477133156417282
+Kdf = KDF2(SHA-1)
+Dem = Twofish/GCM
+DemKeyLen = 32
+Iv = 00000000000000000000000000000000
+Mac = HMAC(SHA-512)
+MacKeyLen = 64
+Format = compressed
+CofactorMode = 0
+OldCofactorMode = 0
+CheckMode = 0
+SingleHashMode = 0
+Label = Test
+Plaintext = 00
+Ciphertext =
diff --git a/src/tests/test_ecies.cpp b/src/tests/test_ecies.cpp
new file mode 100644
index 000000000..2fba6c93f
--- /dev/null
+++ b/src/tests/test_ecies.cpp
@@ -0,0 +1,246 @@
+/*
+* (C) 2016 Philipp Weber
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#include "tests.h"
+
+
+#if defined(BOTAN_HAS_ECIES)
+ #include "test_pubkey.h"
+ #include
+ #include
+ #include
+#endif
+
+namespace Botan_Tests {
+
+namespace {
+
+#if defined(BOTAN_HAS_ECIES)
+
+using byte = Botan::byte;
+using Flags = Botan::ECIES_Flags;
+
+Botan::PointGFp::Compression_Type get_compression_type(const std::string& format)
+ {
+ if(format == "uncompressed")
+ {
+ return Botan::PointGFp::UNCOMPRESSED;
+ }
+ else if(format == "compressed")
+ {
+ return Botan::PointGFp::COMPRESSED;
+ }
+ else if(format == "hybrid")
+ {
+ return Botan::PointGFp::HYBRID;
+ }
+ throw Botan::Invalid_Argument("invalid compression format");
+ }
+
+Flags ecies_flags(bool cofactor_mode, bool old_cofactor_mode, bool check_mode, bool single_hash_mode)
+ {
+ return (cofactor_mode ? Flags::COFACTOR_MODE : Flags::NONE)
+ | (single_hash_mode ? Flags::SINGLE_HASH_MODE : Flags::NONE)
+ | (old_cofactor_mode ? Flags::OLD_COFACTOR_MODE : Flags::NONE)
+ | (check_mode ? Flags::CHECK_MODE : Flags::NONE);
+ }
+
+void check_encrypt_decrypt(Test::Result& result, const Botan::ECDH_PrivateKey& private_key,
+ const Botan::ECDH_PrivateKey& other_private_key,
+ const Botan::ECIES_System_Params& ecies_params,
+ const Botan::InitializationVector& iv, const std::string& label,
+ const std::vector& plaintext, const std::vector& ciphertext)
+ {
+ Botan::ECIES_Encryptor ecies_enc(private_key, ecies_params);
+ ecies_enc.set_other_key(other_private_key.public_point());
+ Botan::ECIES_Decryptor ecies_dec(other_private_key, ecies_params);
+ if(!iv.bits_of().empty())
+ {
+ ecies_enc.set_initialization_vector(iv);
+ ecies_dec.set_initialization_vector(iv);
+ }
+ if(!label.empty())
+ {
+ ecies_enc.set_label(label);
+ ecies_dec.set_label(label);
+ }
+
+ try
+ {
+ const std::vector encrypted = ecies_enc.encrypt(plaintext, Test::rng());
+ if(!ciphertext.empty())
+ {
+ result.test_eq("encrypted data", encrypted, ciphertext);
+ }
+ const Botan::secure_vector decrypted = ecies_dec.decrypt(encrypted);
+ result.test_eq("decrypted data equals plaintext", decrypted, plaintext);
+ }
+ catch(Botan::Lookup_Error& e)
+ {
+ result.test_note(std::string("Test not executed: ") + e.what());
+ }
+ }
+
+void check_encrypt_decrypt(Test::Result& result, const Botan::ECDH_PrivateKey& private_key,
+ const Botan::ECDH_PrivateKey& other_private_key,
+ const Botan::ECIES_System_Params& ecies_params, size_t iv_length = 0)
+ {
+ static std::vector Plaintext { 1, 2, 3 };
+ check_encrypt_decrypt(result, private_key, other_private_key, ecies_params, std::vector(iv_length, 0), "",
+ Plaintext, std::vector());
+ }
+
+class ECIES_ISO_Tests : public Text_Based_Test
+ {
+ public:
+ ECIES_ISO_Tests() : Text_Based_Test(
+ "pubkey/ecies-18033.vec",
+ { "format", "p", "a", "b", "mu", "nu", "gx", "gy", "hx", "hy", "x", "r", "C0", "K" })
+ {
+ }
+
+ Test::Result run_one_test(const std::string&, const VarMap& vars) override
+ {
+ Test::Result result("ECIES-ISO");
+
+ // get test vectors defined by ISO 18033
+ const Botan::PointGFp::Compression_Type compression_type = get_compression_type(get_req_str(vars, "format"));
+ const Botan::BigInt p = get_req_bn(vars, "p");
+ const Botan::BigInt a = get_req_bn(vars, "a");
+ const Botan::BigInt b = get_req_bn(vars, "b");
+ const Botan::BigInt mu = get_req_bn(vars, "mu"); // order
+ const Botan::BigInt nu = get_req_bn(vars, "nu"); // cofactor
+ const Botan::BigInt gx = get_req_bn(vars, "gx"); // base point x
+ const Botan::BigInt gy = get_req_bn(vars, "gy"); // base point y
+ const Botan::BigInt hx = get_req_bn(vars, "hx"); // x of public point of bob
+ const Botan::BigInt hy = get_req_bn(vars, "hy"); // y of public point of bob
+ const Botan::BigInt x = get_req_bn(vars, "x"); // private key of bob
+ const Botan::BigInt r = get_req_bn(vars, "r"); // (ephemeral) private key of alice
+ const std::vector c0 = get_req_bin(vars, "C0"); // expected encoded (ephemeral) public key
+ const std::vector k = get_req_bin(vars, "K"); // expected derived secret
+
+ const Botan::CurveGFp curve(p, a, b);
+ const Botan::EC_Group domain(curve, Botan::PointGFp(curve, gx, gy), mu, nu);
+
+ // keys of bob
+ const Botan::ECDH_PrivateKey other_private_key(Test::rng(), domain, x);
+ const Botan::PointGFp other_public_key_point(curve, hx, hy);
+ const Botan::ECDH_PublicKey other_public_key(domain, other_public_key_point);
+
+ // (ephemeral) keys of alice
+ const Botan::ECDH_PrivateKey eph_private_key(Test::rng(), domain, r);
+ const Botan::PointGFp eph_public_key_point = eph_private_key.public_point();
+ const std::vector eph_public_key_bin = Botan::unlock(
+ Botan::EC2OSP(eph_public_key_point, compression_type));
+ result.test_eq("encoded (ephemeral) public key", eph_public_key_bin, c0);
+
+ // test secret derivation: ISO 18033 test vectors use KDF1 from ISO 18033
+ // no cofactor-/oldcofactor-/singlehash-/check-mode and 128 byte secret length
+ Botan::ECIES_KA_Params ka_params(eph_private_key.domain(), "KDF1-18033(SHA-1)", 128, compression_type,
+ Flags::NONE);
+ const Botan::ECIES_KA_Operation ka(eph_private_key, ka_params, true);
+ const Botan::SymmetricKey secret_key = ka.derive_secret(eph_public_key_bin, other_public_key_point);
+ result.test_eq("derived secret key", secret_key.bits_of(), k);
+
+ // test encryption / decryption
+ for(int i_cofactor_mode = 0; i_cofactor_mode < 2; ++i_cofactor_mode)
+ {
+ for(int i_single_hash_mode = 0; i_single_hash_mode < 2; ++i_single_hash_mode)
+ {
+ for(int i_old_cofactor_mode = 0; i_old_cofactor_mode < 2; ++i_old_cofactor_mode)
+ {
+ for(int i_check_mode = 0; i_check_mode < 2; ++i_check_mode)
+ {
+ for(int i_compression_type = 0; i_compression_type < 3; ++i_compression_type)
+ {
+ const bool cofactor_mode = i_cofactor_mode != 0;
+ const bool single_hash_mode = i_single_hash_mode != 0;
+ const bool old_cofactor_mode = i_old_cofactor_mode != 0;
+ const bool check_mode = i_check_mode != 0;
+ const Botan::PointGFp::Compression_Type compression_type =
+ static_cast(i_compression_type);
+
+ Flags flags = ecies_flags(cofactor_mode, old_cofactor_mode, check_mode, single_hash_mode);
+
+ if(cofactor_mode + check_mode + old_cofactor_mode > 1)
+ {
+ result.test_throws("throw on invalid ECIES_Flags", [&]
+ {
+ Botan::ECIES_System_Params(eph_private_key.domain(), "KDF2(SHA-1)", "AES-256/CBC",
+ 32, "HMAC(SHA-1)", 20, compression_type, flags);
+ });
+ continue;
+ }
+
+ Botan::ECIES_System_Params ecies_params(eph_private_key.domain(), "KDF2(SHA-1)", "AES-256/CBC",
+ 32, "HMAC(SHA-1)", 20, compression_type, flags);
+ check_encrypt_decrypt(result, eph_private_key, other_private_key, ecies_params, 16);
+ }
+ }
+ }
+ }
+ }
+
+ return result;
+ }
+ };
+
+BOTAN_REGISTER_TEST("ecies-iso", ECIES_ISO_Tests);
+
+
+class ECIES_Tests : public Text_Based_Test
+ {
+ public:
+ ECIES_Tests() : Text_Based_Test(
+ "pubkey/ecies.vec",
+ { "Curve", "PrivateKey", "OtherPrivateKey", "Kdf", "Dem", "DemKeyLen", "Iv", "Mac", "MacKeyLen", "Format",
+ "CofactorMode", "OldCofactorMode", "CheckMode", "SingleHashMode", "Label", "Plaintext", "Ciphertext" })
+ {
+ }
+
+ Test::Result run_one_test(const std::string&, const VarMap& vars) override
+ {
+ Test::Result result("ECIES");
+
+ const std::string curve = get_req_str(vars, "Curve");
+ const Botan::BigInt private_key_value = get_req_bn(vars, "PrivateKey");
+ const Botan::BigInt other_private_key_value = get_req_bn(vars, "OtherPrivateKey");
+ const std::string kdf = get_req_str(vars, "Kdf");
+ const std::string dem = get_req_str(vars, "Dem");
+ const size_t dem_key_len = get_req_sz(vars, "DemKeyLen");
+ const std::vector iv = get_req_bin(vars, "Iv");
+ const std::string mac = get_req_str(vars, "Mac");
+ const size_t mac_key_len = get_req_sz(vars, "MacKeyLen");
+ const Botan::PointGFp::Compression_Type compression_type = get_compression_type(get_req_str(vars, "Format"));
+ const bool cofactor_mode = get_req_sz(vars, "CofactorMode") != 0;
+ const bool old_cofactor_mode = get_req_sz(vars, "OldCofactorMode") != 0;
+ const bool check_mode = get_req_sz(vars, "CheckMode") != 0;
+ const bool single_hash_mode = get_req_sz(vars, "SingleHashMode") != 0;
+ const std::string label = get_req_str(vars, "Label");
+ const std::vector plaintext = get_req_bin(vars, "Plaintext");
+ const std::vector ciphertext = get_req_bin(vars, "Ciphertext");
+
+ const Flags flags = ecies_flags(cofactor_mode, old_cofactor_mode, check_mode, single_hash_mode);
+ const Botan::EC_Group domain(curve);
+ const Botan::ECDH_PrivateKey private_key(Test::rng(), domain, private_key_value);
+ const Botan::ECDH_PrivateKey other_private_key(Test::rng(), domain, other_private_key_value);
+
+ const Botan::ECIES_System_Params ecies_params(private_key.domain(), kdf, dem, dem_key_len, mac, mac_key_len,
+ compression_type, flags);
+ check_encrypt_decrypt(result, private_key, other_private_key, ecies_params, iv, label, plaintext, ciphertext);
+
+ return result;
+ }
+
+ };
+
+BOTAN_REGISTER_TEST("ecies", ECIES_Tests);
+
+#endif
+
+}
+
+}
--
cgit v1.2.3
From 4f04a39d104a65d55762b6d03cf7ec21aac02ffa Mon Sep 17 00:00:00 2001
From: Jack Lloyd
Date: Mon, 23 May 2016 11:40:11 -0400
Subject: Fix GCM counter increment
GCM is defined as having a 32-bit counter, but CTR_BE incremented the
counter across the entire block. This caused incorrect results if
a very large message (2**39 bits) was processed, or if the GHASH
derived nonce ended up having a counter field near to 2**32
Thanks to Juraj Somorovsky for the bug report and repro.
---
doc/news.rst | 13 ++++++++++++-
src/lib/modes/aead/gcm/gcm.cpp | 2 +-
src/lib/stream/ctr/ctr.cpp | 17 +++++++++++++++--
src/lib/stream/ctr/ctr.h | 3 +++
src/tests/data/aead/gcm.vec | 23 +++++++++++++++++++++++
5 files changed, 54 insertions(+), 4 deletions(-)
(limited to 'doc')
diff --git a/doc/news.rst b/doc/news.rst
index 2a9fe53a6..0087782d3 100644
--- a/doc/news.rst
+++ b/doc/news.rst
@@ -9,6 +9,17 @@ Version 1.11.30, Not Yet Released
a MAC failure. Records like this are used by OpenSSL in TLS 1.0
connections in order to randomize the IV.
+* A bug in GCM caused incorrect results if the 32-bit counter field
+ overflowed. With a 96-bit nonce, this could only occur if 2**32
+ 128-bit blocks were encrypted. This actually exceeds the maximum
+ allowable length of a GCM plaintext.
+
+ However if a GCM nonce of any other size is used, the bug triggers
+ randomly, with increasing probability on longer messages. For
+ instance when encrypting 256 MiB of data under a random 128 bit
+ nonce, an incorrect result would be produced about 1/256 of the
+ time. With 1 MiB texts, the probability of error reduced to 1/65536.
+
* The Transform and Keyed_Transform interfaces has been removed. The
two concrete implementations of these interfaces were Cipher_Mode
and the Compressor_tkk. The Cipher_Mode interface remains unchanged
@@ -37,7 +48,7 @@ Version 1.11.30, Not Yet Released
* X509_CRL previously had an option to cause it to ignore unknown
critical extensions. This has been removed.
-
+
* Added support for ChaCha stream cipher with 12 rounds.
* Add ECGDSA signature algorithm (GH #479)
diff --git a/src/lib/modes/aead/gcm/gcm.cpp b/src/lib/modes/aead/gcm/gcm.cpp
index 1dc5efe4f..e23551cb4 100644
--- a/src/lib/modes/aead/gcm/gcm.cpp
+++ b/src/lib/modes/aead/gcm/gcm.cpp
@@ -168,7 +168,7 @@ GCM_Mode::GCM_Mode(BlockCipher* cipher, size_t tag_size) :
m_ghash.reset(new GHASH);
- m_ctr.reset(new CTR_BE(cipher)); // CTR_BE takes ownership of cipher
+ m_ctr.reset(new CTR_BE(cipher, 4)); // CTR_BE takes ownership of cipher
if(m_tag_size != 8 && m_tag_size != 16)
throw Invalid_Argument(name() + ": Bad tag size " + std::to_string(m_tag_size));
diff --git a/src/lib/stream/ctr/ctr.cpp b/src/lib/stream/ctr/ctr.cpp
index 88c7a8d8e..f5301c099 100644
--- a/src/lib/stream/ctr/ctr.cpp
+++ b/src/lib/stream/ctr/ctr.cpp
@@ -23,10 +23,23 @@ CTR_BE::CTR_BE(BlockCipher* ciph) :
m_cipher(ciph),
m_counter(m_cipher->parallel_bytes()),
m_pad(m_counter.size()),
+ m_ctr_size(m_cipher->block_size()),
m_pad_pos(0)
{
}
+CTR_BE::CTR_BE(BlockCipher* cipher, size_t ctr_size) :
+ m_cipher(cipher),
+ m_counter(m_cipher->parallel_bytes()),
+ m_pad(m_counter.size()),
+ m_ctr_size(ctr_size),
+ m_pad_pos(0)
+ {
+ //BOTAN_CHECK_ARG(m_ctr_size > 0 && m_ctr_size <= cipher->block_size(), "Invalid CTR size");
+ if(m_ctr_size == 0 || m_ctr_size > m_cipher->block_size())
+ throw Invalid_Argument("Invalid CTR-BE counter size");
+ }
+
void CTR_BE::clear()
{
m_cipher->clear();
@@ -79,7 +92,7 @@ void CTR_BE::set_iv(const byte iv[], size_t iv_len)
{
buffer_insert(m_counter, i*bs, &m_counter[(i-1)*bs], bs);
- for(size_t j = 0; j != bs; ++j)
+ for(size_t j = 0; j != m_ctr_size; ++j)
if(++m_counter[i*bs + (bs - 1 - j)])
break;
}
@@ -99,7 +112,7 @@ void CTR_BE::increment_counter()
for(size_t i = 0; i != n_wide; ++i)
{
uint16_t carry = static_cast(n_wide);
- for(size_t j = 0; carry && j != bs; ++j)
+ for(size_t j = 0; carry && j != m_ctr_size; ++j)
{
const size_t off = i*bs + (bs-1-j);
const uint16_t cnt = static_cast(m_counter[off]) + carry;
diff --git a/src/lib/stream/ctr/ctr.h b/src/lib/stream/ctr/ctr.h
index 8e931605c..003297b92 100644
--- a/src/lib/stream/ctr/ctr.h
+++ b/src/lib/stream/ctr/ctr.h
@@ -44,12 +44,15 @@ class BOTAN_DLL CTR_BE final : public StreamCipher
* @param cipher the underlying block cipher to use
*/
explicit CTR_BE(BlockCipher* cipher);
+
+ CTR_BE(BlockCipher* cipher, size_t ctr_size);
private:
void key_schedule(const byte key[], size_t key_len) override;
void increment_counter();
std::unique_ptr m_cipher;
secure_vector m_counter, m_pad;
+ size_t m_ctr_size;
size_t m_pad_pos;
};
diff --git a/src/tests/data/aead/gcm.vec b/src/tests/data/aead/gcm.vec
index 21bc3a53e..516e828ec 100644
--- a/src/tests/data/aead/gcm.vec
+++ b/src/tests/data/aead/gcm.vec
@@ -38,6 +38,29 @@ In = D9313225F88406E5A55909C5AFF5269A86A7A9531534F7DA2E4C303D8A318A721C3C0C9
AD = FEEDFACEDEADBEEFFEEDFACEDEADBEEFABADDAD2
Out = 8CE24998625615B603A033ACA13FB894BE9112A5C3A211A8BA262A3CCA7E2CA701E4A9A4FBA43C90CCDCB281D48C7C6FD62875D2ACA417034C34AEE5619CC5AEFFFE0BFA462AF43C1699D050
+# GCM vectors generated by OpenSSL via Python cryptography
+#
+# These GCM nonces are not 96 bits and so are hashed with GHASH to
+# produce the counter value. For these inputs the CTR value is
+# very near 2^32, which exposed a bug in GCM when the counter overflowed
+
+Key = 00000000000000000000000000000000
+Nonce = 0AAC82F3E53C2756034F7BD5827C9EDD
+In = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+Out = 38C21B6430D9A3E4BC6749405765653AE91051E96CE0D076141DD7B515EC150FDB8A65EE988D206C9F64874664CDBF61257FFAE521B9A5EB5B35E3745F4232025B269A6CD7DCFE19153ECF7341CE2C6A6A87F95F2109841350DA3D24EEED4E4E32D2BED880737670FFE8ED76DB890FD72A0076300E50914984A777C9F2BC843977396C602B24E7A045F04D15CD2EAC01AD8808064CFE5A2DC1AE9FFFA4BF0A6F0C07668097DEEB9C5CA5EC1F9A52F96A403B73FEA2DBBF44473D355553EE7FB1B4D6630777DAF67804BE213089B9F78652CE970C582FD813F87FF0ECBACCE1CA46247E20D09F3E0B4EF6BFCD13244C6877F25E6646252CAD6EB7DBBA3476AAAC83BC3285FF70B50D6CDEDC8E5921944A
+
+Key = 00000000000000000000000000000000
+Nonce = 63ADFF969337DB7AAA3D862A8A827558
+In = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+Out = E7813D2279516D5EE54E03371B0192FE2B66EF4BF3C7F741D2B8E1809CA5C1805908ADEFE6C5884736DF98B7EBCB08110B58C384E4A2FF25644CDFEAA2104FA3B33F00B689319EF7F09B2F066AEC96DC
+
+Key = 00000000000000000000000000000000
+Nonce = E60108DFED8198FB286E0A77E699DA7B
+In = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+Out = A833DCC2EC04BEF5ED9E7E7FB08D61244CD795C21FEE194E7AAF7D9BD66B324F39FFC46DB5A7B9E1D6703F95290027DE6AC274CAE11C632F16261B71CE97EEA6CBE8A82B4F55F5A8B5CE1B268A7B35D8
+
+
+
[AES-192/GCM]
# Nist | Test Case 7
Key = 000000000000000000000000000000000000000000000000
--
cgit v1.2.3
From 9eda1f09887b8b1ba5d60e1e432ebf7d828726db Mon Sep 17 00:00:00 2001
From: Jack Lloyd
Date: Fri, 3 Jun 2016 09:39:09 -0400
Subject: Update release notes
[ci skip]
---
doc/news.rst | 49 ++++++++++++++++++++++++++++++++++++++++---------
doc/todo.rst | 1 +
2 files changed, 41 insertions(+), 9 deletions(-)
(limited to 'doc')
diff --git a/doc/news.rst b/doc/news.rst
index 0087782d3..38c6c797b 100644
--- a/doc/news.rst
+++ b/doc/news.rst
@@ -10,15 +10,35 @@ Version 1.11.30, Not Yet Released
connections in order to randomize the IV.
* A bug in GCM caused incorrect results if the 32-bit counter field
- overflowed. With a 96-bit nonce, this could only occur if 2**32
- 128-bit blocks were encrypted. This actually exceeds the maximum
- allowable length of a GCM plaintext.
-
- However if a GCM nonce of any other size is used, the bug triggers
- randomly, with increasing probability on longer messages. For
- instance when encrypting 256 MiB of data under a random 128 bit
- nonce, an incorrect result would be produced about 1/256 of the
- time. With 1 MiB texts, the probability of error reduced to 1/65536.
+ overflowed. This bug has no implications on the security but affects
+ interoperability.
+
+ With a 96-bit nonce, this could only occur if at least 2**32 128-bit
+ blocks (64 GiB) were encrypted. This actually exceeds the maximum
+ allowable length of a GCM plaintext; when messages longer than
+ 2**32 - 2 blocks are encrypted, GCM loses its security properties.
+
+ In addition to 96-bit nonces, GCM also supports nonces of arbitrary
+ length using a different method which hashes the provided nonce
+ under the authentication key. When using such a nonce, the last 4
+ bytes of the resulting CTR input might be near the overflow
+ boundary, with the probability of incorrect overflow increasing with
+ longer messages. when encrypting 256 MiB of data under a random 128
+ bit nonce, an incorrect result would be produced about 1/256 of the
+ time. With 1 MiB texts, the probability of error is reduced to 1/65536.
+
+ Since TLS uses GCM with 96 bit nonces and limits the length of any
+ record to far less than 64 GiB, TLS GCM ciphersuites are not
+ affected by this bug.
+
+ Reported by Juraj Somorovsky, described also in "Nonce-Disrespecting
+ Adversaries: Practical Forgery Attacks on GCM in TLS"
+ (https://eprint.iacr.org/2016/475.pdf)
+
+* Previously when generating a new self-signed certificate or PKCS #10
+ request, the subject DN was required to contain both common name
+ (CN) and country (C) fields. These restrictions have been removed.
+ GH #496
* The Transform and Keyed_Transform interfaces has been removed. The
two concrete implementations of these interfaces were Cipher_Mode
@@ -67,6 +87,17 @@ Version 1.11.30, Not Yet Released
* Fix bcrypt function under Python 3 (GH #461)
+* The ``unix_procs`` entropy source is deprecated and will be removed
+ in a future release. This entropy source attempts to get entropy by
+ running Unix programs like ``arp``, ``netstat``, and ``dmesg`` which
+ produce information which may be difficult for a remote attacker to
+ guess. This exists primarily as a last-ditch for Unix systems
+ without ``/dev/random``. But at this point such systems effectively
+ no longer exist, and the use of ``fork`` and ``exec`` by the library
+ complicates effective application sandboxing.
+
+* Changes to avoid implicit cast warnings in Visual C++ (GH #484)
+
Version 1.10.13, 2016-04-23
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/doc/todo.rst b/doc/todo.rst
index 930c23fbd..a66c97f4f 100644
--- a/doc/todo.rst
+++ b/doc/todo.rst
@@ -101,6 +101,7 @@ Public Key Crypto, Math
* XMSS (draft-irtf-cfrg-xmss-hash-based-signatures)
* SPHINCS-256
+* NEWHOPE RLWE scheme + BoringSSL compatible TLS cipher suites
* EdDSA (GH #283)
* Ed448-Goldilocks
* FHMQV
--
cgit v1.2.3
From 70a61c082408a22b516fbe0f3a81441c6c5f165e Mon Sep 17 00:00:00 2001
From: René Korthaus
Date: Tue, 14 Jun 2016 17:50:00 +0200
Subject: Add entry to credits
---
doc/credits.rst | 7 +++++++
1 file changed, 7 insertions(+)
(limited to 'doc')
diff --git a/doc/credits.rst b/doc/credits.rst
index 6d62b6380..bd70890ff 100644
--- a/doc/credits.rst
+++ b/doc/credits.rst
@@ -104,3 +104,10 @@ snail-mail address (S), and Bitcoin address (B).
W: https://www.kullo.net
D: Build system
S: Germany
+
+ N: René Korthaus
+ E: r.korthaus@sirrix.com
+ W: https://www.sirrix.com
+ P: C196 FF9D 3DDC A5E7 F98C E745 9AD0 F9FA 587E 74D6
+ D: CI, ECGDSA, ECKCDSA
+ S: Bochum, Germany
--
cgit v1.2.3
From 00337c4ea2af6b1727be0bdf9b719c98760a14fd Mon Sep 17 00:00:00 2001
From: SimCog
Date: Tue, 14 Jun 2016 18:21:10 +0200
Subject: Adding StreamCipher::seek interface, supporting seek in ChaCha, and
also adding ChaCha8 support
---
doc/credits.rst | 7 +
doc/license.txt | 1 +
src/lib/prov/openssl/openssl_rc4.cpp | 5 +
src/lib/stream/chacha/chacha.cpp | 28 +-
src/lib/stream/chacha/chacha.h | 4 +-
src/lib/stream/ctr/ctr.cpp | 4 +
src/lib/stream/ctr/ctr.h | 2 +
src/lib/stream/ofb/ofb.cpp | 5 +
src/lib/stream/ofb/ofb.h | 2 +
src/lib/stream/rc4/rc4.cpp | 4 +
src/lib/stream/rc4/rc4.h | 2 +
src/lib/stream/salsa20/salsa20.cpp | 4 +
src/lib/stream/salsa20/salsa20.h | 2 +
src/lib/stream/stream_cipher.h | 6 +
src/tests/data/stream/chacha.vec | 506 +++++++++++++++++++++++++++++++++++
src/tests/test_stream.cpp | 6 +-
16 files changed, 583 insertions(+), 5 deletions(-)
(limited to 'doc')
diff --git a/doc/credits.rst b/doc/credits.rst
index 6d62b6380..af78680a4 100644
--- a/doc/credits.rst
+++ b/doc/credits.rst
@@ -104,3 +104,10 @@ snail-mail address (S), and Bitcoin address (B).
W: https://www.kullo.net
D: Build system
S: Germany
+
+ N: Simon Cogliani
+ E: simon.cogliani@tanker.io
+ W: https://www.tanker.io/
+ P: EA73 D0AF 5A81 A61A 8931 C2CA C9AB F2E4 3820 4F25
+ D: Getting keystream of ChaCha
+ S: Paris, France
diff --git a/doc/license.txt b/doc/license.txt
index ef0b97ac1..fd4fd0a7b 100644
--- a/doc/license.txt
+++ b/doc/license.txt
@@ -29,6 +29,7 @@ Copyright (C) 1999-2013,2014,2015,2016 Jack Lloyd
2015,2016 Daniel Neus
2015 Uri Blumenthal
2015,2016 Kai Michaelis
+ 2016 Simon Cogliani
All rights reserved.
Redistribution and use in source and binary forms, with or without
diff --git a/src/lib/prov/openssl/openssl_rc4.cpp b/src/lib/prov/openssl/openssl_rc4.cpp
index e36535e08..070cdb14d 100644
--- a/src/lib/prov/openssl/openssl_rc4.cpp
+++ b/src/lib/prov/openssl/openssl_rc4.cpp
@@ -45,6 +45,11 @@ class OpenSSL_RC4 : public StreamCipher
explicit OpenSSL_RC4(size_t skip = 0) : m_skip(skip) { clear(); }
~OpenSSL_RC4() { clear(); }
+
+ void seek(u64bit) override
+ {
+ throw Exception("RC4 does not support seeking");
+ }
private:
void cipher(const byte in[], byte out[], size_t length) override
{
diff --git a/src/lib/stream/chacha/chacha.cpp b/src/lib/stream/chacha/chacha.cpp
index ac81fd70d..40da93029 100644
--- a/src/lib/stream/chacha/chacha.cpp
+++ b/src/lib/stream/chacha/chacha.cpp
@@ -12,8 +12,8 @@ namespace Botan {
ChaCha::ChaCha(size_t rounds) : m_rounds(rounds)
{
- if(m_rounds != 12 && m_rounds != 20)
- throw Invalid_Argument("ChaCha only supports 12 or 20 rounds");
+ if(m_rounds != 8 && m_rounds != 12 && m_rounds != 20)
+ throw Invalid_Argument("ChaCha only supports 8, 12 or 20 rounds");
}
namespace {
@@ -67,7 +67,6 @@ void chacha(byte output[64], const u32bit input[16], size_t rounds)
store_le(x14 + input[14], output + 4 * 14);
store_le(x15 + input[15], output + 4 * 15);
}
-
}
/*
@@ -173,4 +172,27 @@ std::string ChaCha::name() const
return "ChaCha(" + std::to_string(m_rounds) + ")";
}
+void ChaCha::seek(u64bit offset)
+ {
+ if (m_state.size() == 0 && m_buffer.size() == 0)
+ {
+ throw Invalid_State("You have to setup the stream cipher (key and iv)");
+ }
+
+ m_position = offset % m_buffer.size();
+
+ u64bit counter = offset / m_buffer.size();
+
+ byte out[8];
+
+ store_le(counter, out);
+
+ m_state[12] = load_le(out, 0);
+ m_state[13] += load_le(out, 1);
+
+ chacha(m_buffer.data(), m_state.data(), m_rounds);
+
+ ++m_state[12];
+ m_state[13] += (m_state[12] == 0);
+ }
}
diff --git a/src/lib/stream/chacha/chacha.h b/src/lib/stream/chacha/chacha.h
index ba93d6260..f8f42e41d 100644
--- a/src/lib/stream/chacha/chacha.h
+++ b/src/lib/stream/chacha/chacha.h
@@ -21,7 +21,7 @@ class BOTAN_DLL ChaCha final : public StreamCipher
StreamCipher* clone() const override { return new ChaCha(m_rounds); }
/**
- * Currently only 12 or 20 rounds are supported, all others
+ * Currently only 8, 12 or 20 rounds are supported, all others
* will throw an exception
*/
ChaCha(size_t rounds);
@@ -42,6 +42,8 @@ class BOTAN_DLL ChaCha final : public StreamCipher
std::string name() const override;
+ void seek(u64bit offset) override;
+
private:
void key_schedule(const byte key[], size_t key_len) override;
diff --git a/src/lib/stream/ctr/ctr.cpp b/src/lib/stream/ctr/ctr.cpp
index f5301c099..43609ba2d 100644
--- a/src/lib/stream/ctr/ctr.cpp
+++ b/src/lib/stream/ctr/ctr.cpp
@@ -125,4 +125,8 @@ void CTR_BE::increment_counter()
m_pad_pos = 0;
}
+void CTR_BE::seek(u64bit)
+ {
+ throw Not_Implemented("CTR_BE::seek");
+ }
}
diff --git a/src/lib/stream/ctr/ctr.h b/src/lib/stream/ctr/ctr.h
index 003297b92..5d5556254 100644
--- a/src/lib/stream/ctr/ctr.h
+++ b/src/lib/stream/ctr/ctr.h
@@ -46,6 +46,8 @@ class BOTAN_DLL CTR_BE final : public StreamCipher
explicit CTR_BE(BlockCipher* cipher);
CTR_BE(BlockCipher* cipher, size_t ctr_size);
+
+ void seek(u64bit offset) override;
private:
void key_schedule(const byte key[], size_t key_len) override;
void increment_counter();
diff --git a/src/lib/stream/ofb/ofb.cpp b/src/lib/stream/ofb/ofb.cpp
index e8cb463db..3337a0c14 100644
--- a/src/lib/stream/ofb/ofb.cpp
+++ b/src/lib/stream/ofb/ofb.cpp
@@ -73,4 +73,9 @@ void OFB::set_iv(const byte iv[], size_t iv_len)
m_buf_pos = 0;
}
+
+void OFB::seek(u64bit)
+ {
+ throw Exception("OFB does not support seeking");
+ }
}
diff --git a/src/lib/stream/ofb/ofb.h b/src/lib/stream/ofb/ofb.h
index fecd47d9d..127a06578 100644
--- a/src/lib/stream/ofb/ofb.h
+++ b/src/lib/stream/ofb/ofb.h
@@ -44,6 +44,8 @@ class BOTAN_DLL OFB final : public StreamCipher
* @param cipher the underlying block cipher to use
*/
explicit OFB(BlockCipher* cipher);
+
+ void seek(u64bit offset) override;
private:
void key_schedule(const byte key[], size_t key_len) override;
diff --git a/src/lib/stream/rc4/rc4.cpp b/src/lib/stream/rc4/rc4.cpp
index 895f38091..a4dea9e2b 100644
--- a/src/lib/stream/rc4/rc4.cpp
+++ b/src/lib/stream/rc4/rc4.cpp
@@ -113,4 +113,8 @@ void RC4::clear()
*/
RC4::RC4(size_t s) : m_SKIP(s) {}
+void RC4::seek(u64bit)
+ {
+ throw Exception("RC4 does not support seeking");
+ }
}
diff --git a/src/lib/stream/rc4/rc4.h b/src/lib/stream/rc4/rc4.h
index f166a2772..88798fae6 100644
--- a/src/lib/stream/rc4/rc4.h
+++ b/src/lib/stream/rc4/rc4.h
@@ -39,6 +39,8 @@ class BOTAN_DLL RC4 final : public StreamCipher
explicit RC4(size_t skip = 0);
~RC4() { clear(); }
+
+ void seek(u64bit offset) override;
private:
void key_schedule(const byte[], size_t) override;
void generate();
diff --git a/src/lib/stream/salsa20/salsa20.cpp b/src/lib/stream/salsa20/salsa20.cpp
index 1d3fe3d28..f11fe5e59 100644
--- a/src/lib/stream/salsa20/salsa20.cpp
+++ b/src/lib/stream/salsa20/salsa20.cpp
@@ -227,4 +227,8 @@ void Salsa20::clear()
m_position = 0;
}
+void Salsa20::seek(u64bit)
+ {
+ throw Not_Implemented("Salsa20::seek");
+ }
}
diff --git a/src/lib/stream/salsa20/salsa20.h b/src/lib/stream/salsa20/salsa20.h
index 7e75470da..8256ea4db 100644
--- a/src/lib/stream/salsa20/salsa20.h
+++ b/src/lib/stream/salsa20/salsa20.h
@@ -33,6 +33,8 @@ class BOTAN_DLL Salsa20 final : public StreamCipher
void clear() override;
std::string name() const override;
StreamCipher* clone() const override { return new Salsa20; }
+
+ void seek(u64bit offset) override;
private:
void key_schedule(const byte key[], size_t key_len) override;
diff --git a/src/lib/stream/stream_cipher.h b/src/lib/stream/stream_cipher.h
index bff1fd1a6..56bd2d5d9 100644
--- a/src/lib/stream/stream_cipher.h
+++ b/src/lib/stream/stream_cipher.h
@@ -80,6 +80,12 @@ class BOTAN_DLL StreamCipher : public SymmetricAlgorithm
*/
virtual StreamCipher* clone() const = 0;
+ /**
+ * Set the offset and the state used later to generate the keystream
+ * @param offset the offset where we begin to generate the keystream
+ */
+ virtual void seek(u64bit offset) = 0;
+
StreamCipher();
virtual ~StreamCipher();
};
diff --git a/src/tests/data/stream/chacha.vec b/src/tests/data/stream/chacha.vec
index 1c3c18c7c..f51ff0812 100644
--- a/src/tests/data/stream/chacha.vec
+++ b/src/tests/data/stream/chacha.vec
@@ -1,3 +1,104 @@
+[ChaCha(8)]
+
+# Tests got from the original implementation of Daniel J. Bernstein
+
+Key = 00000000000000000000000000000000
+Nonce = 0000000000000000
+In = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+Out = E28A5FA4A67F8C5DEFED3E6FB7303486AA8427D31419A729572D777953491120B64AB8E72B8DEB85CD6AEA7CB6089A101824BEEB08814A428AAB1FA2C816081B
+
+Key = 0000000000000000000000000000000000000000000000000000000000000000
+Nonce = 000000000000000000000002
+In = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+Out = FD74BC4D822E344ACA041ACB39789BDA359D16B7709A7676B03B0F06117685B33B5E1E7DB844BE88ACCFC8370C808FB4BFBFDE831358476F09E34F2045AE61C0AC4120E44862548D3E5B577C695005115CFB158B9B6341BFC0561B9EAEE34D114583FB5FC901D5EA85019EAD2D4F618A5FC97954A5913576CD6BA32E710DA15A52D9A5B74B6E2F1D333C6405A5D6F64E2B1CED579A5FFBEB390A756755FED56AF37061CCC3A1D4DF6421F7A4D7811919F95A7F8533826DAB256A09E58CBFC5A04F83B063BBB169D2B05AFA6C8B3EC5880DB3346193860671AFFB3F9A5B56F771231393330816FFBD0E66F6D6B598178461CF5BE424A84A8D426DDB4B88FCB275
+
+Key = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F
+Nonce = 000102030405060708090A0B
+In = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+Out = 2E214501D03825E75AC476151531939D6DB48E04588D91CB6CAC080F87CDF6A95C6A0245E0333A970BB8E8C373A0CA81E2592224712B8002D3AA52835DF513F5D4CCCD346E24968A9BBE43C770EF563968821B21FDF26583F51D9F3ED89EBA912B2EC460C460BE062B8AE3604569FDFD0B1312F7705E9D7A33DCBE720D69308CD89AC06C58545C47148BD68C1E61A838DD3BFB88A5ADC721DEAB8147B9EC16A77FC8466C0B791D29AC2068769D8AA54A5D15A11580FA9A375F2D0072E1FB8EF5A27EF31B7710E196B3D061C911FFA93D067364D23B1FE69EA1318202BF94C8718CB44F4383D678C493A5C5502F02A9BA861534DD2BDC9559587BFEED4A08F5C3
+
+# Test vector in a draft "Test Vectors for the Stream Cipher ChaCha draft-strombergson-chacha-test-vectors-00" available at the following link: http://tools.ietf.org/html/draft-strombergson-chacha-test-vectors-00.
+# The document links a github repo where you can find all the vectors https://github.com/secworks/chacha_testvectors/
+
+Key = 00000000000000000000000000000000
+Nonce = 0000000000000000
+In = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+Out = E28A5FA4A67F8C5DEFED3E6FB7303486AA8427D31419A729572D777953491120B64AB8E72B8DEB85CD6AEA7CB6089A101824BEEB08814A428AAB1FA2C816081B8A26AF448A1BA906368FD8C83831C18CEC8CED811A028E675B8D2BE8FCE081165CEAE9F1D1B7A975497749480569CEB83DE6A0A587D4984F19925F5D338E430D
+
+Key = 0000000000000000000000000000000000000000000000000000000000000000
+Nonce = 0000000000000000
+In = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+Out = 3E00EF2F895F40D67F5BB8E81F09A5A12C840EC3CE9A7F3B181BE188EF711A1E984CE172B9216F419F445367456D5619314A42A3DA86B001387BFDB80E0CFE42D2AEFA0DEAA5C151BF0ADB6C01F2A5ADC0FD581259F9A2AADCF20F8FD566A26B5032EC38BBC5DA98EE0C6F568B872A65A08ABF251DEB21BB4B56E5D8821E68AA
+
+Key = 01000000000000000000000000000000
+Nonce = 0000000000000000
+In = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+Out = 03A7669888605A0765E8357475E58673F94FC8161DA76C2A3AA2F3CAF9FE5449E0FCF38EB882656AF83D430D410927D55C972AC4C92AB9DA3713E19F761EAA147138C25C8A7CE3D5E7546746FFD2E3515CE6A4B1B2D3F380138668ED39FA92F8A1AEE36258E05FAE6F566673511765FDB59E05163D55A708C5F9BC45045124CB
+
+Key = 0100000000000000000000000000000000000000000000000000000000000000
+Nonce = 0000000000000000
+In = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+Out = CF5EE9A0494AA9613E05D5ED725B804B12F4A465EE635ACC3A311DE8740489EA289D04F43C7518DB56EB4433E498A1238CD8464D3763DDBB9222EE3BD8FAE3C8B4355A7D93DD8867089EE643558B95754EFA2BD1A8A1E2D75BCDB32015542638291941FEB49965587C4FDFE219CF0EC132A6CD4DC067392E67982FE53278C0B4
+
+Key = 00000000000000000000000000000000
+Nonce = 0100000000000000
+In = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+Out = 25F5BEC6683916FF44BCCD12D102E692176663F4CAC53E719509CA74B6B2EEC85DA4236FB29902012ADC8F0D86C8187D25CD1C486966930D0204C4EE88A6AB355A6C9976C7BC6E78BAF3108C5364EF42B93B35D2694D2DDF72A4FC7ECDB968FCFE16BEDB8D48102FB54F1CE3636E914C0E2DADC7CAA2AB1929733A9263325E72
+
+Key = 0000000000000000000000000000000000000000000000000000000000000000
+Nonce = 0100000000000000
+In = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+Out = 2B8F4BB3798306CA5130D47C4F8D4ED13AA0EDCCC1BE6942090FAEECA0D7599B7FF0FE616BB25AA0153AD6FDC88B954903C22426D478B97B22B8F9B1DB00CF06470BDFFBC488A8B7C701EBF4061D75C5969186497C95367809AFA80BD843B040A79ABC6E73A91757F1DB73C8EACFA543B38F289D065AB2F3032D377B8C37FE46
+
+Key = FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+Nonce = FFFFFFFFFFFFFFFF
+In = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+Out = 2204D5B81CE662193E00966034F91302F14A3FB047F58B6E6EF0D721132304163E0FB640D76FF9C3B9CD99996E6E38FAD13F0E31C82244D33ABBC1B11E8BF12D9A81D78E9E56604DDFAE136921F51C9D81AE15119DB8E756DD28024493EE571D363AE4BBCD6E7D300F99D2673AEB92CCFC6E43A38DC31BACD66B28F17B22B28A
+
+Key = FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+Nonce = FFFFFFFFFFFFFFFF
+In = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+Out = E163BBF8C9A739D18925EE8362DAD2CDC973DF05225AFB2AA26396F2A9849A4A445E0547D31C1623C537DF4BA85C70A9884A35BCBF3DFAB077E98B0F68135F5481D4933F8B322AC0CD762C27235CE2B31534E0244A9A2F1FD5E94498D47FF108790C009CF9E1A348032A7694CB28024CD96D3498361EDB1785AF752D187AB54B
+
+Key = 55555555555555555555555555555555
+Nonce = 5555555555555555
+In = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+Out = F0A23BC36270E18ED0691DC384374B9B2C5CB60110A03F56FA48A9FBBAD961AA6BAB4D892E96261B6F1A0919514AE56F86E066E17C71A4176AC684AF1C931996950F754E728BD061D176ECF571C62A5EA5C776697B3193D3EA94CF17D7F0A14E504859D1A67C248AB298BE3BB7EDED3A23F61B6C5BD1A5A4CFC84BFC3D295AC5
+
+Key = 5555555555555555555555555555555555555555555555555555555555555555
+Nonce = 5555555555555555
+In = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+Out = 7CB78214E4D3465B6DC62CF7A1538C88996952B4FB72CB6105F1243CE3442E2975A59EBCD2B2A598290D7538491FE65BDBFEFD060D88798120A70D049DC2677DD48FF5A2513E497A5D54802D7484C4F1083944D8D0D14D6482CE09F7E5EBF20B29807D62C31874D02F5D3CC85381A745ECBC60525205E300A76961BFE51AC07C
+
+Key = AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+Nonce = AAAAAAAAAAAAAAAA
+In = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+Out = 312D95C0BC38EFF4942DB2D50BDC500A30641EF7132DB1A8AE838B3BEA3A7AB03815D7A4CC09DBF5882A3433D743ACED48136EBAB73299506855C0F5437A36C6EF5AD3D6A4F6C35D9D66C2E34005B91BBBE3099E135A00CE2F700745BE6253195824D4B19F69731B6177E624358C7977E67552F519B470E3F7A8EC965DC3BEDA
+
+Key = AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+Nonce = AAAAAAAAAAAAAAAA
+In = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+Out = 40F9AB86C8F9A1A0CDC05A75E5531B612D71EF7F0CF9E387DF6ED6972F0AAE21311AA581F816C90E8A99DE990B6B95AAC92450F4E112712667B804C99E9C6EDAF8D144F560C8C0EA36880D3B77874C9A9103D147F6DED386284801A4EE158E5EA4F9C093FC55FD344C33349DC5B699E21DC83B4296F92EE3ECABF3D51F95FE3F
+
+Key = 00112233445566778899AABBCCDDEEFF
+Nonce = 0F1E2D3C4B5A6978
+In = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+Out = 29560D280B4528400A8F4B795369FB3A01105599E9F1ED58279CFC9ECE2DC5F99F1C2E52C98238F542A5C0A881D850B615D3ACD9FBDB026E9368565DA50E0D49DD5BE8EF74248B3E251D965D8FCB21E7CFE204D4007806FBEE3CE94C74BFBAD2C11C621BA048147C5CAA94D182CCFF6FD5CF44ADF96E3D68281BB49676AF87E7
+
+Key = 00112233445566778899AABBCCDDEEFFFFEEDDCCBBAA99887766554433221100
+Nonce = 0F1E2D3C4B5A6978
+In = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+Out = DB43AD9D1E842D1272E4530E276B3F568F8859B3F7CF6D9D2C74FA53808CB5157A8EBF46AD3DCC4B6C7DADDE131784B0120E0E22F6D5F9FFA7407D4A21B695D9C5DD30BF55612FAB9BDD118920C19816470C7F5DCD42325DBBED8C57A56281C144CB0F03E81B3004624E0650A1CE5AFAF9A7CD8163F6DBD72602257DD96E471E
+
+Key = C46EC1B18CE8A878725A37E780DFB735
+Nonce = 1ADA31D5CF688221
+In = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+Out = 6A870108859F679118F3E205E2A56A6826EF5A60A4102AC8D4770059FCB7C7BAE02F5CE004A6BFBBEA53014DD82107C0AA1C7CE11B7D78F2D50BD3602BBD25940560BB6A84289E0B38F5DD21D6EF6D7737E3EC0FB772DA2C71C2397762E5DBBBF449E3D1639CCBFA3E069C4D871ED6395B22AAF35C8DA6DE2DEC3D77880DA8E8
+
+Key = C46EC1B18CE8A878725A37E780DFB7351F68ED2E194C79FBC6AEBEE1A667975D
+Nonce = 1ADA31D5CF688221
+In = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+Out = 838751B42D8DDD8A3D77F48825A2BA752CF4047CB308A5978EF274973BE374C96AD848065871417B08F034E681FE46A93F7D5C61D1306614D4AAF257A7CFF08B16F2FDA170CC18A4B58A2667ED962774AF792A6E7F3C77992540711A7A136D7E8A2F8D3F93816709D45A3FA5F8CE72FDE15BE7B841ACBA3A2ABD557228D9FE4F
[ChaCha(12)]
@@ -43,8 +144,413 @@ In = 00000000000000000000000000000000000000000000000000000000000000000000000000
Out = F798A189F195E66982105FFB640BB7757F579DA31602FC93EC01AC56F85AC3C134A4547B733B46413042C9440049176905D3BE59EA1C53F15916155C2BE8241A38008B9A26BC35941E2444177C8ADE6689DE95264986D95889FB60E84629C9BD9A5ACB1CC118BE563EB9B3A4A472F82E09A7E778492B562EF7130E88DFE031C79DB9D4F7C7A899151B9A475032B63FC385245FE054E3DD5A97A5F576FE064025D3CE042C566AB2C507B138DB853E3D6959660996546CC9C4A6EAFDC777C040D70EAF46F76DAD3979E5C5360C3317166A1C894C94A371876A94DF7628FE4EAAF2CCB27D5AAAE0AD7AD0F9D4B6AD3B54098746D4524D38407A6DEB
# From draft-irtf-cfrg-chacha20-poly1305-03
+#
Key = 0000000000000000000000000000000000000000000000000000000000000000
Nonce = 000000000000000000000002
In = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
Out = C2C64D378CD536374AE204B9EF933FCD1A8B2288B3DFA49672AB765B54EE27C78A970E0E955C14F3A88E741B97C286F75F8FC299E8148362FA198A39531BED6D
+# Test seek offset
+# Tests got from the original implementation of Daniel J. Bernstein
+#
+Seek = 0
+Key = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F
+Nonce = 000102030405060708090A0B
+In = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+Out = 103AF111C18B549D39248FB07D60C29A95D1DB88D892F7B4AF709A5FD47A9E4BD5FF9A658DD52C708BEF1F0F622B3747040FA3551300B1F293150A88620D5FED
+
+Seek = 1
+Key = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F
+Nonce = 000102030405060708090A0B
+In = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+Out = 3AF111C18B549D39248FB07D60C29A95D1DB88D892F7B4AF709A5FD47A9E4BD5FF9A658DD52C708BEF1F0F622B3747040FA3551300B1F293150A88620D5FED89
+
+Seek = 2
+Key = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F
+Nonce = 000102030405060708090A0B
+In = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+Out = F111C18B549D39248FB07D60C29A95D1DB88D892F7B4AF709A5FD47A9E4BD5FF9A658DD52C708BEF1F0F622B3747040FA3551300B1F293150A88620D5FED89FB
+
+Seek = 3
+Key = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F
+Nonce = 000102030405060708090A0B
+In = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+Out = 11C18B549D39248FB07D60C29A95D1DB88D892F7B4AF709A5FD47A9E4BD5FF9A658DD52C708BEF1F0F622B3747040FA3551300B1F293150A88620D5FED89FB08
+
+Seek = 4
+Key = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F
+Nonce = 000102030405060708090A0B
+In = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+Out = C18B549D39248FB07D60C29A95D1DB88D892F7B4AF709A5FD47A9E4BD5FF9A658DD52C708BEF1F0F622B3747040FA3551300B1F293150A88620D5FED89FB0800
+
+Seek = 5
+Key = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F
+Nonce = 000102030405060708090A0B
+In = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+Out = 8B549D39248FB07D60C29A95D1DB88D892F7B4AF709A5FD47A9E4BD5FF9A658DD52C708BEF1F0F622B3747040FA3551300B1F293150A88620D5FED89FB080029
+
+Seek = 6
+Key = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F
+Nonce = 000102030405060708090A0B
+In = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+Out = 549D39248FB07D60C29A95D1DB88D892F7B4AF709A5FD47A9E4BD5FF9A658DD52C708BEF1F0F622B3747040FA3551300B1F293150A88620D5FED89FB08002917
+
+Seek = 7
+Key = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F
+Nonce = 000102030405060708090A0B
+In = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+Out = 9D39248FB07D60C29A95D1DB88D892F7B4AF709A5FD47A9E4BD5FF9A658DD52C708BEF1F0F622B3747040FA3551300B1F293150A88620D5FED89FB08002917A5
+
+Seek = 8
+Key = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F
+Nonce = 000102030405060708090A0B
+In = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+Out = 39248FB07D60C29A95D1DB88D892F7B4AF709A5FD47A9E4BD5FF9A658DD52C708BEF1F0F622B3747040FA3551300B1F293150A88620D5FED89FB08002917A540
+
+Seek = 9
+Key = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F
+Nonce = 000102030405060708090A0B
+In = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+Out = 248FB07D60C29A95D1DB88D892F7B4AF709A5FD47A9E4BD5FF9A658DD52C708BEF1F0F622B3747040FA3551300B1F293150A88620D5FED89FB08002917A540B7
+
+Seek = 10
+Key = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F
+Nonce = 000102030405060708090A0B
+In = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+Out = 8FB07D60C29A95D1DB88D892F7B4AF709A5FD47A9E4BD5FF9A658DD52C708BEF1F0F622B3747040FA3551300B1F293150A88620D5FED89FB08002917A540B783
+
+Seek = 11
+Key = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F
+Nonce = 000102030405060708090A0B
+In = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+Out = B07D60C29A95D1DB88D892F7B4AF709A5FD47A9E4BD5FF9A658DD52C708BEF1F0F622B3747040FA3551300B1F293150A88620D5FED89FB08002917A540B7833F
+
+Seek = 12
+Key = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F
+Nonce = 000102030405060708090A0B
+In = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+Out = 7D60C29A95D1DB88D892F7B4AF709A5FD47A9E4BD5FF9A658DD52C708BEF1F0F622B3747040FA3551300B1F293150A88620D5FED89FB08002917A540B7833FF3
+
+Seek = 13
+Key = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F
+Nonce = 000102030405060708090A0B
+In = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+Out = 60C29A95D1DB88D892F7B4AF709A5FD47A9E4BD5FF9A658DD52C708BEF1F0F622B3747040FA3551300B1F293150A88620D5FED89FB08002917A540B7833FF398
+
+Seek = 14
+Key = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F
+Nonce = 000102030405060708090A0B
+In = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+Out = C29A95D1DB88D892F7B4AF709A5FD47A9E4BD5FF9A658DD52C708BEF1F0F622B3747040FA3551300B1F293150A88620D5FED89FB08002917A540B7833FF3981D
+
+Seek = 15
+Key = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F
+Nonce = 000102030405060708090A0B
+In = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+Out = 9A95D1DB88D892F7B4AF709A5FD47A9E4BD5FF9A658DD52C708BEF1F0F622B3747040FA3551300B1F293150A88620D5FED89FB08002917A540B7833FF3981D0E
+
+Seek = 16
+Key = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F
+Nonce = 000102030405060708090A0B
+In = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+Out = 95D1DB88D892F7B4AF709A5FD47A9E4BD5FF9A658DD52C708BEF1F0F622B3747040FA3551300B1F293150A88620D5FED89FB08002917A540B7833FF3981D0E63
+
+Seek = 17
+Key = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F
+Nonce = 000102030405060708090A0B
+In = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+Out = D1DB88D892F7B4AF709A5FD47A9E4BD5FF9A658DD52C708BEF1F0F622B3747040FA3551300B1F293150A88620D5FED89FB08002917A540B7833FF3981D0E63C9
+
+Seek = 18
+Key = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F
+Nonce = 000102030405060708090A0B
+In = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+Out = DB88D892F7B4AF709A5FD47A9E4BD5FF9A658DD52C708BEF1F0F622B3747040FA3551300B1F293150A88620D5FED89FB08002917A540B7833FF3981D0E63C970
+
+Seek = 19
+Key = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F
+Nonce = 000102030405060708090A0B
+In = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+Out = 88D892F7B4AF709A5FD47A9E4BD5FF9A658DD52C708BEF1F0F622B3747040FA3551300B1F293150A88620D5FED89FB08002917A540B7833FF3981D0E63C970B2
+
+Seek = 20
+Key = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F
+Nonce = 000102030405060708090A0B
+In = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+Out = D892F7B4AF709A5FD47A9E4BD5FF9A658DD52C708BEF1F0F622B3747040FA3551300B1F293150A88620D5FED89FB08002917A540B7833FF3981D0E63C970B2E7
+
+Seek = 21
+Key = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F
+Nonce = 000102030405060708090A0B
+In = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+Out = 92F7B4AF709A5FD47A9E4BD5FF9A658DD52C708BEF1F0F622B3747040FA3551300B1F293150A88620D5FED89FB08002917A540B7833FF3981D0E63C970B2E751
+
+Seek = 22
+Key = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F
+Nonce = 000102030405060708090A0B
+In = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+Out = F7B4AF709A5FD47A9E4BD5FF9A658DD52C708BEF1F0F622B3747040FA3551300B1F293150A88620D5FED89FB08002917A540B7833FF3981D0E63C970B2E75174
+
+Seek = 23
+Key = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F
+Nonce = 000102030405060708090A0B
+In = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+Out = B4AF709A5FD47A9E4BD5FF9A658DD52C708BEF1F0F622B3747040FA3551300B1F293150A88620D5FED89FB08002917A540B7833FF3981D0E63C970B2E75174AD
+
+Seek = 24
+Key = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F
+Nonce = 000102030405060708090A0B
+In = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+Out = AF709A5FD47A9E4BD5FF9A658DD52C708BEF1F0F622B3747040FA3551300B1F293150A88620D5FED89FB08002917A540B7833FF3981D0E63C970B2E75174ADB9
+
+Seek = 25
+Key = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F
+Nonce = 000102030405060708090A0B
+In = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+Out = 709A5FD47A9E4BD5FF9A658DD52C708BEF1F0F622B3747040FA3551300B1F293150A88620D5FED89FB08002917A540B7833FF3981D0E63C970B2E75174ADB9E6
+
+Seek = 26
+Key = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F
+Nonce = 000102030405060708090A0B
+In = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+Out = 9A5FD47A9E4BD5FF9A658DD52C708BEF1F0F622B3747040FA3551300B1F293150A88620D5FED89FB08002917A540B7833FF3981D0E63C970B2E75174ADB9E697
+
+Seek = 27
+Key = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F
+Nonce = 000102030405060708090A0B
+In = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+Out = 5FD47A9E4BD5FF9A658DD52C708BEF1F0F622B3747040FA3551300B1F293150A88620D5FED89FB08002917A540B7833FF3981D0E63C970B2E75174ADB9E6972F
+
+Seek = 28
+Key = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F
+Nonce = 000102030405060708090A0B
+In = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+Out = D47A9E4BD5FF9A658DD52C708BEF1F0F622B3747040FA3551300B1F293150A88620D5FED89FB08002917A540B7833FF3981D0E63C970B2E75174ADB9E6972FC5
+
+Seek = 29
+Key = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F
+Nonce = 000102030405060708090A0B
+In = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+Out = 7A9E4BD5FF9A658DD52C708BEF1F0F622B3747040FA3551300B1F293150A88620D5FED89FB08002917A540B7833FF3981D0E63C970B2E75174ADB9E6972FC575
+
+Seek = 30
+Key = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F
+Nonce = 000102030405060708090A0B
+In = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+Out = 9E4BD5FF9A658DD52C708BEF1F0F622B3747040FA3551300B1F293150A88620D5FED89FB08002917A540B7833FF3981D0E63C970B2E75174ADB9E6972FC575C0
+
+Seek = 31
+Key = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F
+Nonce = 000102030405060708090A0B
+In = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+Out = 4BD5FF9A658DD52C708BEF1F0F622B3747040FA3551300B1F293150A88620D5FED89FB08002917A540B7833FF3981D0E63C970B2E75174ADB9E6972FC575C0A6
+
+Seek = 32
+Key = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F
+Nonce = 000102030405060708090A0B
+In = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+Out = D5FF9A658DD52C708BEF1F0F622B3747040FA3551300B1F293150A88620D5FED89FB08002917A540B7833FF3981D0E63C970B2E75174ADB9E6972FC575C0A63C
+
+Seek = 33
+Key = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F
+Nonce = 000102030405060708090A0B
+In = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+Out = FF9A658DD52C708BEF1F0F622B3747040FA3551300B1F293150A88620D5FED89FB08002917A540B7833FF3981D0E63C970B2E75174ADB9E6972FC575C0A63CEC
+
+Seek = 34
+Key = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F
+Nonce = 000102030405060708090A0B
+In = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+Out = 9A658DD52C708BEF1F0F622B3747040FA3551300B1F293150A88620D5FED89FB08002917A540B7833FF3981D0E63C970B2E75174ADB9E6972FC575C0A63CEC80
+
+Seek = 35
+Key = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F
+Nonce = 000102030405060708090A0B
+In = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+Out = 658DD52C708BEF1F0F622B3747040FA3551300B1F293150A88620D5FED89FB08002917A540B7833FF3981D0E63C970B2E75174ADB9E6972FC575C0A63CEC802C
+
+Seek = 36
+Key = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F
+Nonce = 000102030405060708090A0B
+In = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+Out = 8DD52C708BEF1F0F622B3747040FA3551300B1F293150A88620D5FED89FB08002917A540B7833FF3981D0E63C970B2E75174ADB9E6972FC575C0A63CEC802CF3
+
+Seek = 37
+Key = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F
+Nonce = 000102030405060708090A0B
+In = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+Out = D52C708BEF1F0F622B3747040FA3551300B1F293150A88620D5FED89FB08002917A540B7833FF3981D0E63C970B2E75174ADB9E6972FC575C0A63CEC802CF3E6
+
+Seek = 38
+Key = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F
+Nonce = 000102030405060708090A0B
+In = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+Out = 2C708BEF1F0F622B3747040FA3551300B1F293150A88620D5FED89FB08002917A540B7833FF3981D0E63C970B2E75174ADB9E6972FC575C0A63CEC802CF3E61E
+
+Seek = 39
+Key = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F
+Nonce = 000102030405060708090A0B
+In = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+Out = 708BEF1F0F622B3747040FA3551300B1F293150A88620D5FED89FB08002917A540B7833FF3981D0E63C970B2E75174ADB9E6972FC575C0A63CEC802CF3E61EB1
+
+Seek = 40
+Key = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F
+Nonce = 000102030405060708090A0B
+In = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+Out = 8BEF1F0F622B3747040FA3551300B1F293150A88620D5FED89FB08002917A540B7833FF3981D0E63C970B2E75174ADB9E6972FC575C0A63CEC802CF3E61EB198
+
+Seek = 41
+Key = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F
+Nonce = 000102030405060708090A0B
+In = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+Out = EF1F0F622B3747040FA3551300B1F293150A88620D5FED89FB08002917A540B7833FF3981D0E63C970B2E75174ADB9E6972FC575C0A63CEC802CF3E61EB19837
+
+Seek = 42
+Key = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F
+Nonce = 000102030405060708090A0B
+In = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+Out = 1F0F622B3747040FA3551300B1F293150A88620D5FED89FB08002917A540B7833FF3981D0E63C970B2E75174ADB9E6972FC575C0A63CEC802CF3E61EB1983732
+
+Seek = 43
+Key = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F
+Nonce = 000102030405060708090A0B
+In = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+Out = 0F622B3747040FA3551300B1F293150A88620D5FED89FB08002917A540B7833FF3981D0E63C970B2E75174ADB9E6972FC575C0A63CEC802CF3E61EB198373276
+
+Seek = 44
+Key = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F
+Nonce = 000102030405060708090A0B
+In = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+Out = 622B3747040FA3551300B1F293150A88620D5FED89FB08002917A540B7833FF3981D0E63C970B2E75174ADB9E6972FC575C0A63CEC802CF3E61EB198373276D8
+
+Seek = 45
+Key = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F
+Nonce = 000102030405060708090A0B
+In = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+Out = 2B3747040FA3551300B1F293150A88620D5FED89FB08002917A540B7833FF3981D0E63C970B2E75174ADB9E6972FC575C0A63CEC802CF3E61EB198373276D865
+
+Seek = 46
+Key = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F
+Nonce = 000102030405060708090A0B
+In = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+Out = 3747040FA3551300B1F293150A88620D5FED89FB08002917A540B7833FF3981D0E63C970B2E75174ADB9E6972FC575C0A63CEC802CF3E61EB198373276D86594
+
+Seek = 47
+Key = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F
+Nonce = 000102030405060708090A0B
+In = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+Out = 47040FA3551300B1F293150A88620D5FED89FB08002917A540B7833FF3981D0E63C970B2E75174ADB9E6972FC575C0A63CEC802CF3E61EB198373276D865948F
+
+Seek = 48
+Key = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F
+Nonce = 000102030405060708090A0B
+In = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+Out = 040FA3551300B1F293150A88620D5FED89FB08002917A540B7833FF3981D0E63C970B2E75174ADB9E6972FC575C0A63CEC802CF3E61EB198373276D865948F23
+
+Seek = 49
+Key = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F
+Nonce = 000102030405060708090A0B
+In = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+Out = 0FA3551300B1F293150A88620D5FED89FB08002917A540B7833FF3981D0E63C970B2E75174ADB9E6972FC575C0A63CEC802CF3E61EB198373276D865948F237E
+
+Seek = 50
+Key = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F
+Nonce = 000102030405060708090A0B
+In = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+Out = A3551300B1F293150A88620D5FED89FB08002917A540B7833FF3981D0E63C970B2E75174ADB9E6972FC575C0A63CEC802CF3E61EB198373276D865948F237E84
+
+Seek = 51
+Key = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F
+Nonce = 000102030405060708090A0B
+In = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+Out = 551300B1F293150A88620D5FED89FB08002917A540B7833FF3981D0E63C970B2E75174ADB9E6972FC575C0A63CEC802CF3E61EB198373276D865948F237E84A9
+
+Seek = 52
+Key = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F
+Nonce = 000102030405060708090A0B
+In = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+Out = 1300B1F293150A88620D5FED89FB08002917A540B7833FF3981D0E63C970B2E75174ADB9E6972FC575C0A63CEC802CF3E61EB198373276D865948F237E84A974
+
+Seek = 53
+Key = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F
+Nonce = 000102030405060708090A0B
+In = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+Out = 00B1F293150A88620D5FED89FB08002917A540B7833FF3981D0E63C970B2E75174ADB9E6972FC575C0A63CEC802CF3E61EB198373276D865948F237E84A974FD
+
+Seek = 54
+Key = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F
+Nonce = 000102030405060708090A0B
+In = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+Out = B1F293150A88620D5FED89FB08002917A540B7833FF3981D0E63C970B2E75174ADB9E6972FC575C0A63CEC802CF3E61EB198373276D865948F237E84A974FD28
+
+Seek = 55
+Key = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F
+Nonce = 000102030405060708090A0B
+In = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+Out = F293150A88620D5FED89FB08002917A540B7833FF3981D0E63C970B2E75174ADB9E6972FC575C0A63CEC802CF3E61EB198373276D865948F237E84A974FD28B8
+
+Seek = 56
+Key = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F
+Nonce = 000102030405060708090A0B
+In = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+Out = 93150A88620D5FED89FB08002917A540B7833FF3981D0E63C970B2E75174ADB9E6972FC575C0A63CEC802CF3E61EB198373276D865948F237E84A974FD28B89B
+
+Seek = 57
+Key = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F
+Nonce = 000102030405060708090A0B
+In = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+Out = 150A88620D5FED89FB08002917A540B7833FF3981D0E63C970B2E75174ADB9E6972FC575C0A63CEC802CF3E61EB198373276D865948F237E84A974FD28B89B12
+
+Seek = 58
+Key = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F
+Nonce = 000102030405060708090A0B
+In = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+Out = 0A88620D5FED89FB08002917A540B7833FF3981D0E63C970B2E75174ADB9E6972FC575C0A63CEC802CF3E61EB198373276D865948F237E84A974FD28B89B12B8
+
+Seek = 59
+Key = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F
+Nonce = 000102030405060708090A0B
+In = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+Out = 88620D5FED89FB08002917A540B7833FF3981D0E63C970B2E75174ADB9E6972FC575C0A63CEC802CF3E61EB198373276D865948F237E84A974FD28B89B12B8D9
+
+Seek = 60
+Key = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F
+Nonce = 000102030405060708090A0B
+In = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+Out = 620D5FED89FB08002917A540B7833FF3981D0E63C970B2E75174ADB9E6972FC575C0A63CEC802CF3E61EB198373276D865948F237E84A974FD28B89B12B8D907
+
+Seek = 61
+Key = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F
+Nonce = 000102030405060708090A0B
+In = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+Out = 0D5FED89FB08002917A540B7833FF3981D0E63C970B2E75174ADB9E6972FC575C0A63CEC802CF3E61EB198373276D865948F237E84A974FD28B89B12B8D90790
+
+Seek = 62
+Key = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F
+Nonce = 000102030405060708090A0B
+In = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+Out = 5FED89FB08002917A540B7833FF3981D0E63C970B2E75174ADB9E6972FC575C0A63CEC802CF3E61EB198373276D865948F237E84A974FD28B89B12B8D907904F
+
+Seek = 63
+Key = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F
+Nonce = 000102030405060708090A0B
+In = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+Out = ED89FB08002917A540B7833FF3981D0E63C970B2E75174ADB9E6972FC575C0A63CEC802CF3E61EB198373276D865948F237E84A974FD28B89B12B8D907904F9E
+
+Seek = 64
+Key = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F
+Nonce = 000102030405060708090A0B
+In = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+Out = 89FB08002917A540B7833FF3981D0E63C970B2E75174ADB9E6972FC575C0A63CEC802CF3E61EB198373276D865948F237E84A974FD28B89B12B8D907904F9ED6
+
+Seek = 65
+Key = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F
+Nonce = 000102030405060708090A0B
+In = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+Out = FB08002917A540B7833FF3981D0E63C970B2E75174ADB9E6972FC575C0A63CEC802CF3E61EB198373276D865948F237E84A974FD28B89B12B8D907904F9ED679
+
+Seek = 4294967232
+Key = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F
+Nonce = 000102030405060708090A0B
+In = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+Out = DBF81BB406517BE1A54F4740E5DDDF2B7965747B757FA9D5B7EDD6B27FEDDB89D5D47F9B24E57DF393017A5079F61852CD8B86859884120AF867D25D3B259E2B
diff --git a/src/tests/test_stream.cpp b/src/tests/test_stream.cpp
index 232fdcdd9..d3d83c26c 100644
--- a/src/tests/test_stream.cpp
+++ b/src/tests/test_stream.cpp
@@ -18,7 +18,7 @@ class Stream_Cipher_Tests : public Text_Based_Test
{
public:
Stream_Cipher_Tests(): Text_Based_Test("stream",
- {"Key", "In", "Out"}, {"Nonce"}) {}
+ {"Key", "In", "Out"}, {"Nonce", "Seek"}) {}
Test::Result run_one_test(const std::string& algo, const VarMap& vars) override
{
@@ -26,6 +26,7 @@ class Stream_Cipher_Tests : public Text_Based_Test
const std::vector input = get_req_bin(vars, "In");
const std::vector expected = get_req_bin(vars, "Out");
const std::vector nonce = get_opt_bin(vars, "Nonce");
+ const size_t seek = get_opt_sz(vars, "Seek", 0);
Test::Result result(algo);
@@ -53,6 +54,9 @@ class Stream_Cipher_Tests : public Text_Based_Test
if(nonce.size())
cipher->set_iv(nonce.data(), nonce.size());
+ if (seek != 0)
+ cipher->seek(seek);
+
std::vector buf = input;
cipher->encrypt(buf);
--
cgit v1.2.3
From 6975d0d59bb51f42d6cca3e23c5f5646ef2f24b2 Mon Sep 17 00:00:00 2001
From: Mouse
Date: Fri, 17 Jun 2016 22:35:47 -0400
Subject: Fix bug that prevents LaTeX documentation from being built
---
doc/manual/srp.rst | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
(limited to 'doc')
diff --git a/doc/manual/srp.rst b/doc/manual/srp.rst
index e3aace5ff..74b67d890 100644
--- a/doc/manual/srp.rst
+++ b/doc/manual/srp.rst
@@ -10,7 +10,7 @@ This verifier is based on a password, but the password cannot be
easily derived from the verifier. Later, the client and server can
perform an SRP exchange, in which
- .. warning::
+.. warning::
While knowledge of the verifier does not easily allow an attacker
to get the raw password, they could still use the verifier to
--
cgit v1.2.3
From 25a83f8a35f9a02de85b5d66474a92ab34a88c3b Mon Sep 17 00:00:00 2001
From: Jack Lloyd
Date: Sat, 18 Jun 2016 10:07:09 -0400
Subject: Update release notes
[ci skip]
---
doc/news.rst | 15 ++++++++++++---
1 file changed, 12 insertions(+), 3 deletions(-)
(limited to 'doc')
diff --git a/doc/news.rst b/doc/news.rst
index 38c6c797b..eaf0c872b 100644
--- a/doc/news.rst
+++ b/doc/news.rst
@@ -42,14 +42,15 @@ Version 1.11.30, Not Yet Released
* The Transform and Keyed_Transform interfaces has been removed. The
two concrete implementations of these interfaces were Cipher_Mode
- and the Compressor_tkk. The Cipher_Mode interface remains unchanged
+ and Compressor_Transform. The Cipher_Mode interface remains unchanged
as the Transform and Keyed_Transform signatures have moved to it;
no changes to Cipher_Mode usage should be necessary. Any uses of
Transform& or Keyed_Transform& to refer to a cipher should be replaced
by Cipher_Mode&. The compression algorithm interface has changed; the start
function now takes the per-message compression ratio to use. Previously the
compression level to use had to be set once, at creation time, and
- the required `secure_vector` argument to start was required to be empty.
+ the required ``secure_vector`` argument to ``start`` was required to be empty.
+ The new API is documented in `compression.rst` in the manual.
* Add IETF versions of the ChaCha20Poly1305 TLS ciphersuites from
draft-ietf-tls-chacha20-poly1305-04. The previously implemented
@@ -69,12 +70,20 @@ Version 1.11.30, Not Yet Released
* X509_CRL previously had an option to cause it to ignore unknown
critical extensions. This has been removed.
-* Added support for ChaCha stream cipher with 12 rounds.
+* Added StreamCipher::seek allowing seeking to arbitrary position
+ in the key stream. Currently only implemented for ChaCha. (GH #497)
+
+* Added support for ChaCha stream cipher with 8 or 12 rounds.
* Add ECGDSA signature algorithm (GH #479)
+* Add support for label argument to KDFs (GH #495)
+
* Add NIST SP800-108 and 56C KDFs (GH #481)
+* Support for Card Verifiable Certificates and the obsolete EMSA1_BSI
+ signature padding scheme have been removed. (GH #487)
+
* A bug in the IETF version of ChaCha20Poly1305 (with 96 bit nonces)
caused incorrect computation when the plaintext or AAD was exactly
a multiple of 16 bytes.
--
cgit v1.2.3
From 0b6d2a853638206dfa43420d5419e8b719505cc7 Mon Sep 17 00:00:00 2001
From: Jack Lloyd
Date: Sun, 19 Jun 2016 00:24:30 -0400
Subject: Update for 1.11.30 release
---
doc/news.rst | 2 +-
readme.rst | 6 +++---
2 files changed, 4 insertions(+), 4 deletions(-)
(limited to 'doc')
diff --git a/doc/news.rst b/doc/news.rst
index eaf0c872b..c5b99a12e 100644
--- a/doc/news.rst
+++ b/doc/news.rst
@@ -1,7 +1,7 @@
Release Notes
========================================
-Version 1.11.30, Not Yet Released
+Version 1.11.30, 2016-06-19
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
* In 1.11.23 a bug was introduced such that CBC-encrypted TLS packets
diff --git a/readme.rst b/readme.rst
index 0fe50df7c..d79da637f 100644
--- a/readme.rst
+++ b/readme.rst
@@ -97,9 +97,9 @@ Versions 1.11 and later require a working C++11 compiler; GCC 4.8 and
later, Clang 3.4 and later, and MSVC 2013 are regularly tested.
The latest development release is
-`1.11.29 `_
-`(sig) `_
-released on 2016-03-20
+`1.11.30 `_
+`(sig) `_
+released on 2016-06-19
Old Stable Series (1.10)
----------------------------------------
--
cgit v1.2.3
From 4bff0f41baa6c61d7b3f648dfeb97ac955993970 Mon Sep 17 00:00:00 2001
From: Jack Lloyd
Date: Sun, 19 Jun 2016 01:22:33 -0400
Subject: Tick to 1.11.31
[ci skip]
---
botan_version.py | 2 +-
doc/news.rst | 3 +++
2 files changed, 4 insertions(+), 1 deletion(-)
(limited to 'doc')
diff --git a/botan_version.py b/botan_version.py
index e5e2b811a..c737e21a0 100644
--- a/botan_version.py
+++ b/botan_version.py
@@ -1,7 +1,7 @@
release_major = 1
release_minor = 11
-release_patch = 30
+release_patch = 31
release_so_abi_rev = release_patch
# These are set by the distribution script
diff --git a/doc/news.rst b/doc/news.rst
index c5b99a12e..e9069565a 100644
--- a/doc/news.rst
+++ b/doc/news.rst
@@ -1,6 +1,9 @@
Release Notes
========================================
+Version 1.11.31, Not Yet Released
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
Version 1.11.30, 2016-06-19
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
--
cgit v1.2.3
From 0414a4f46c090e3e61d2f26d27bf5979f6d80ba9 Mon Sep 17 00:00:00 2001
From: Jack Lloyd
Date: Mon, 4 Jul 2016 18:54:49 -0400
Subject: Update news.rst with changes so far for 1.11.31
[ci skip]
---
doc/news.rst | 11 +++++++++++
1 file changed, 11 insertions(+)
(limited to 'doc')
diff --git a/doc/news.rst b/doc/news.rst
index e9069565a..bf2ae4d6a 100644
--- a/doc/news.rst
+++ b/doc/news.rst
@@ -4,6 +4,17 @@ Release Notes
Version 1.11.31, Not Yet Released
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+* Add PKCS #11 support (GH #507)
+
+* Add ECIES encryption system (GH #483)
+
+* Add ECKCDSA signature algorithm (#504)
+
+* Add KDF1 from ISO 18033 (GH #483)
+
+* Fixes for FreeBSD (GH #517) and OpenBSD (GH #523)
+
+
Version 1.11.30, 2016-06-19
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
--
cgit v1.2.3
From b3bc80dfdb28aee0900b6ed92dff5ba8c5e4daf9 Mon Sep 17 00:00:00 2001
From: Jack Lloyd
Date: Mon, 11 Jul 2016 13:18:43 -0400
Subject: Deprecate EGD
---
doc/news.rst | 4 ++++
1 file changed, 4 insertions(+)
(limited to 'doc')
diff --git a/doc/news.rst b/doc/news.rst
index bf2ae4d6a..8c4db8b09 100644
--- a/doc/news.rst
+++ b/doc/news.rst
@@ -14,6 +14,10 @@ Version 1.11.31, Not Yet Released
* Fixes for FreeBSD (GH #517) and OpenBSD (GH #523)
+* Support for getting entropy from EGD is deprecated, and will be removed in
+ a future release. The developers believe that it is unlikely that any modern
+ system requires EGD and so the code is now dead weight. If you rely on EGD
+ support, you should contact the developers by email or GitHub ASAP.
Version 1.11.30, 2016-06-19
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
--
cgit v1.2.3
From 2c8799b3d91e12b21eb3789f5cedc8a4fb7aaec1 Mon Sep 17 00:00:00 2001
From: Daniel Neus
Date: Mon, 11 Jul 2016 14:13:00 +0200
Subject: DLIES rework
With these fixes the implementation is now compatible with bouncycastle and it should operate
as it is specified in "DHIES: An encryption scheme based on Diffie-Hellman Problem" or in BSI
technical guideline TR-02102-1.
In addition to the already present XOR-encrypion/decryption mode it's now possible to use DLIES with a block cipher.
Previously the input to the KDF was the concatenation of the (ephemeral) public key
and the secret value derived by the key agreement operation:
```
secure_vector vz(m_my_key.begin(), m_my_key.end());
vz += m_ka.derive_key(0, m_other_key).bits_of();
const size_t K_LENGTH = length + m_mac_keylen;
secure_vector K = m_kdf->derive_key(K_LENGTH, vz);
```
I don't know why this was implemented like this. But now the input to the KDF is only the secret value obtained by the key agreement operation.
Furthermore the order of the output was changed from {public key, tag, ciphertext} to {public key, ciphertext, tag}.
Multiple test vectors added that were generated with bouncycastle and some with botan itself.
---
doc/credits.rst | 6 +
doc/license.txt | 1 +
doc/news.rst | 11 +
src/lib/pubkey/dlies/dlies.cpp | 257 ++++++----
src/lib/pubkey/dlies/dlies.h | 101 +++-
src/lib/pubkey/dlies/info.txt | 3 +-
src/tests/data/pubkey/dlies.vec | 1000 +++++++++++++++++++++++++++++++++++++--
src/tests/test_dlies.cpp | 151 +++++-
8 files changed, 1381 insertions(+), 149 deletions(-)
(limited to 'doc')
diff --git a/doc/credits.rst b/doc/credits.rst
index d9d7f2c71..290067491 100644
--- a/doc/credits.rst
+++ b/doc/credits.rst
@@ -124,3 +124,9 @@ snail-mail address (S), and Bitcoin address (B).
W: https://sirrix.com/
D: KDF1-18033, ECIES
S: Saarland, Germany
+
+ N: Daniel Neus
+ E: d.neus@sirrix.com
+ W: https://sirrix.com/
+ D: CI, PKCS#11, RdSeed, BSI module policy
+ S: Bochum, Germany
diff --git a/doc/license.txt b/doc/license.txt
index fd4fd0a7b..b097646e8 100644
--- a/doc/license.txt
+++ b/doc/license.txt
@@ -30,6 +30,7 @@ Copyright (C) 1999-2013,2014,2015,2016 Jack Lloyd
2015 Uri Blumenthal
2015,2016 Kai Michaelis
2016 Simon Cogliani
+ 2015,2016 Rohde & Schwarz Cybersecurity
All rights reserved.
Redistribution and use in source and binary forms, with or without
diff --git a/doc/news.rst b/doc/news.rst
index 8c4db8b09..e6ab279cf 100644
--- a/doc/news.rst
+++ b/doc/news.rst
@@ -18,6 +18,17 @@ Version 1.11.31, Not Yet Released
a future release. The developers believe that it is unlikely that any modern
system requires EGD and so the code is now dead weight. If you rely on EGD
support, you should contact the developers by email or GitHub ASAP.
+
+* Changes in DLIES: Previously the input to the KDF was the concatenation
+ of the (ephemeral) public key and the secret value derived by the key
+ agreement operation. Now the input is only the secret value obtained
+ by the key agreement operation. That's how it is specified in the original
+ paper "DHIES: An encryption scheme based on Diffie-Hellman Problem" or in BSI
+ technical guideline TR-02102-1 for example. In addition to the already present
+ XOR-encrypion/decryption mode it's now possible to use DLIES with a block cipher.
+ Furthermore the order of the output was changed from {public key, tag, ciphertext}
+ to {public key, ciphertext, tag}. Both modes are compatible with bouncycastle.
+
Version 1.11.30, 2016-06-19
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/lib/pubkey/dlies/dlies.cpp b/src/lib/pubkey/dlies/dlies.cpp
index 2c98966b0..9666a1c23 100644
--- a/src/lib/pubkey/dlies/dlies.cpp
+++ b/src/lib/pubkey/dlies/dlies.cpp
@@ -1,6 +1,7 @@
/*
* DLIES
* (C) 1999-2007 Jack Lloyd
+* (C) 2016 Daniel Neus, Rohde & Schwarz Cybersecurity
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
@@ -10,128 +11,204 @@
namespace Botan {
-/*
-* DLIES_Encryptor Constructor
-*/
-DLIES_Encryptor::DLIES_Encryptor(const PK_Key_Agreement_Key& key,
- KDF* kdf_obj,
- MessageAuthenticationCode* mac_obj,
- size_t mac_kl) :
- m_ka(key, "Raw"),
- m_kdf(kdf_obj),
- m_mac(mac_obj),
- m_mac_keylen(mac_kl)
+DLIES_Encryptor::DLIES_Encryptor(const DH_PrivateKey& own_priv_key,
+ KDF* kdf,
+ MessageAuthenticationCode* mac,
+ size_t mac_key_length) :
+ DLIES_Encryptor(own_priv_key, kdf, nullptr, 0, mac, mac_key_length)
{
- BOTAN_ASSERT_NONNULL(kdf_obj);
- BOTAN_ASSERT_NONNULL(mac_obj);
- m_my_key = key.public_value();
}
-/*
-* DLIES Encryption
-*/
+DLIES_Encryptor::DLIES_Encryptor(const DH_PrivateKey& own_priv_key,
+ KDF* kdf,
+ Cipher_Mode* cipher,
+ size_t cipher_key_len,
+ MessageAuthenticationCode* mac,
+ size_t mac_key_length) :
+ m_other_pub_key(),
+ m_own_pub_key(own_priv_key.public_value()),
+ m_ka(own_priv_key, "Raw"),
+ m_kdf(kdf),
+ m_cipher(cipher),
+ m_cipher_key_len(cipher_key_len),
+ m_mac(mac),
+ m_mac_keylen(mac_key_length),
+ m_iv()
+ {
+ BOTAN_ASSERT_NONNULL(kdf);
+ BOTAN_ASSERT_NONNULL(mac);
+ }
+
std::vector DLIES_Encryptor::enc(const byte in[], size_t length,
RandomNumberGenerator&) const
{
- if(length > maximum_input_size())
- throw Invalid_Argument("DLIES: Plaintext too large");
- if(m_other_key.empty())
+ if(m_other_pub_key.empty())
+ {
throw Invalid_State("DLIES: The other key was never set");
+ }
- secure_vector out(m_my_key.size() + length + m_mac->output_length());
- buffer_insert(out, 0, m_my_key);
- buffer_insert(out, m_my_key.size(), in, length);
+ // calculate secret value
+ const SymmetricKey secret_value = m_ka.derive_key(0, m_other_pub_key);
- secure_vector vz(m_my_key.begin(), m_my_key.end());
- vz += m_ka.derive_key(0, m_other_key).bits_of();
+ // derive secret key from secret value
+ const size_t required_key_length = m_cipher ? m_cipher_key_len + m_mac_keylen : length + m_mac_keylen;
+ const secure_vector secret_keys = m_kdf->derive_key(required_key_length, secret_value.bits_of());
- const size_t K_LENGTH = length + m_mac_keylen;
- secure_vector K = m_kdf->derive_key(K_LENGTH, vz);
-
- if(K.size() != K_LENGTH)
+ if(secret_keys.size() != required_key_length)
+ {
throw Encoding_Error("DLIES: KDF did not provide sufficient output");
- byte* C = &out[m_my_key.size()];
-
- m_mac->set_key(K.data(), m_mac_keylen);
- xor_buf(C, &K[m_mac_keylen], length);
-
- m_mac->update(C, length);
- for(size_t j = 0; j != 8; ++j)
- m_mac->update(0);
-
- m_mac->final(C + length);
+ }
+
+ secure_vector ciphertext(in, in + length);
+ const size_t cipher_key_len = m_cipher ? m_cipher_key_len : length;
+
+ if(m_cipher)
+ {
+ SymmetricKey enc_key(secret_keys.data(), cipher_key_len);
+ m_cipher->set_key(enc_key);
+
+ if(m_iv.size())
+ {
+ m_cipher->start(m_iv.bits_of());
+ }
+
+ m_cipher->finish(ciphertext);
+ }
+ else
+ {
+ xor_buf(ciphertext, secret_keys, cipher_key_len);
+ }
+
+ // calculate MAC
+ m_mac->set_key(secret_keys.data() + cipher_key_len, m_mac_keylen);
+ secure_vector tag = m_mac->process(ciphertext);
+
+ // out = (ephemeral) public key + ciphertext + tag
+ secure_vector out(m_own_pub_key.size() + ciphertext.size() + tag.size());
+ buffer_insert(out, 0, m_own_pub_key);
+ buffer_insert(out, 0 + m_own_pub_key.size(), ciphertext);
+ buffer_insert(out, 0 + m_own_pub_key.size() + ciphertext.size(), tag);
return unlock(out);
}
-/*
-* Set the other parties public key
-*/
-void DLIES_Encryptor::set_other_key(const std::vector& ok)
- {
- m_other_key = ok;
- }
-
-/*
+/**
* Return the max size, in bytes, of a message
+* Not_Implemented if DLIES is used in XOR encryption mode
*/
size_t DLIES_Encryptor::maximum_input_size() const
{
- return 32;
+ if(m_cipher)
+ {
+ // no limit in block cipher mode
+ return std::numeric_limits::max();
+ }
+ else
+ {
+ // No way to determine if the KDF will output enough bits for XORing with the plaintext?!
+ throw Not_Implemented("Not implemented for XOR encryption mode");
+ }
}
-/*
-* DLIES_Decryptor Constructor
-*/
-DLIES_Decryptor::DLIES_Decryptor(const PK_Key_Agreement_Key& key,
- KDF* kdf_obj,
- MessageAuthenticationCode* mac_obj,
- size_t mac_kl) :
- m_ka(key, "Raw"),
- m_kdf(kdf_obj),
- m_mac(mac_obj),
- m_mac_keylen(mac_kl)
+DLIES_Decryptor::DLIES_Decryptor(const DH_PrivateKey& own_priv_key,
+ KDF* kdf,
+ Cipher_Mode* cipher,
+ size_t cipher_key_len,
+ MessageAuthenticationCode* mac,
+ size_t mac_key_length) :
+ m_pub_key_size(own_priv_key.public_value().size()),
+ m_ka(own_priv_key, "Raw"),
+ m_kdf(kdf),
+ m_cipher(cipher),
+ m_cipher_key_len(cipher_key_len),
+ m_mac(mac),
+ m_mac_keylen(mac_key_length),
+ m_iv()
{
- m_my_key = key.public_value();
+ BOTAN_ASSERT_NONNULL(kdf);
+ BOTAN_ASSERT_NONNULL(mac);
}
-/*
-* DLIES Decryption
-*/
+DLIES_Decryptor::DLIES_Decryptor(const DH_PrivateKey& own_priv_key,
+ KDF* kdf,
+ MessageAuthenticationCode* mac,
+ size_t mac_key_length) :
+ DLIES_Decryptor(own_priv_key, kdf, nullptr, 0, mac, mac_key_length)
+ {}
+
secure_vector DLIES_Decryptor::do_decrypt(byte& valid_mask,
- const byte msg[], size_t length) const
+ const byte msg[], size_t length) const
{
- if(length < m_my_key.size() + m_mac->output_length())
+ if(length < m_pub_key_size + m_mac->output_length())
+ {
throw Decoding_Error("DLIES decryption: ciphertext is too short");
+ }
- const size_t CIPHER_LEN = length - m_my_key.size() - m_mac->output_length();
-
- std::vector v(msg, msg + m_my_key.size());
+ // calculate secret value
+ std::vector other_pub_key(msg, msg + m_pub_key_size);
+ const SymmetricKey secret_value = m_ka.derive_key(0, other_pub_key);
- secure_vector C(msg + m_my_key.size(), msg + m_my_key.size() + CIPHER_LEN);
+ const size_t ciphertext_len = length - m_pub_key_size - m_mac->output_length();
+ size_t cipher_key_len = m_cipher ? m_cipher_key_len : ciphertext_len;
- secure_vector T(msg + m_my_key.size() + CIPHER_LEN,
- msg + m_my_key.size() + CIPHER_LEN + m_mac->output_length());
+ // derive secret key from secret value
+ const size_t required_key_length = cipher_key_len + m_mac_keylen;
+ secure_vector secret_keys = m_kdf->derive_key(required_key_length, secret_value.bits_of());
- secure_vector vz(msg, msg + m_my_key.size());
- vz += m_ka.derive_key(0, v).bits_of();
-
- const size_t K_LENGTH = C.size() + m_mac_keylen;
- secure_vector K = m_kdf->derive_key(K_LENGTH, vz);
- if(K.size() != K_LENGTH)
+ if(secret_keys.size() != required_key_length)
+ {
throw Encoding_Error("DLIES: KDF did not provide sufficient output");
-
- m_mac->set_key(K.data(), m_mac_keylen);
- m_mac->update(C);
- for(size_t j = 0; j != 8; ++j)
- m_mac->update(0);
- secure_vector T2 = m_mac->final();
-
- valid_mask = CT::expand_mask(same_mem(T.data(), T2.data(), T.size()));
-
- xor_buf(C, K.data() + m_mac_keylen, C.size());
-
- return C;
+ }
+
+ secure_vector ciphertext(msg + m_pub_key_size, msg + m_pub_key_size + ciphertext_len);
+
+ // calculate MAC
+ m_mac->set_key(secret_keys.data() + cipher_key_len, m_mac_keylen);
+ secure_vector calculated_tag = m_mac->process(ciphertext);
+
+ // calculated tag == received tag ?
+ secure_vector tag(msg + m_pub_key_size + ciphertext_len,
+ msg + m_pub_key_size + ciphertext_len + m_mac->output_length());
+
+ valid_mask = CT::expand_mask(same_mem(tag.data(), calculated_tag.data(), tag.size()));
+
+ // decrypt
+ if(m_cipher)
+ {
+ if(valid_mask)
+ {
+ SymmetricKey dec_key(secret_keys.data(), cipher_key_len);
+ m_cipher->set_key(dec_key);
+
+ try
+ {
+ // the decryption can fail:
+ // e.g. Integrity_Failure is thrown if GCM is used and the message does not have a valid tag
+
+ if(m_iv.size())
+ {
+ m_cipher->start(m_iv.bits_of());
+ }
+
+ m_cipher->finish(ciphertext);
+ }
+ catch(...)
+ {
+ valid_mask = 0;
+ }
+
+ }
+ else
+ {
+ return secure_vector();
+ }
+ }
+ else
+ {
+ xor_buf(ciphertext, secret_keys.data(), cipher_key_len);
+ }
+
+ return ciphertext;
}
}
diff --git a/src/lib/pubkey/dlies/dlies.h b/src/lib/pubkey/dlies/dlies.h
index 10471048d..5f7251d03 100644
--- a/src/lib/pubkey/dlies/dlies.h
+++ b/src/lib/pubkey/dlies/dlies.h
@@ -1,6 +1,7 @@
/*
* DLIES
* (C) 1999-2007 Jack Lloyd
+* (C) 2016 Daniel Neus, Rohde & Schwarz Cybersecurity
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
@@ -11,6 +12,8 @@
#include
#include
#include
+#include
+#include
namespace Botan {
@@ -20,24 +23,67 @@ namespace Botan {
class BOTAN_DLL DLIES_Encryptor : public PK_Encryptor
{
public:
- DLIES_Encryptor(const PK_Key_Agreement_Key&,
+ /**
+ * Stream mode: use KDF to provide a stream of bytes to xor with the message
+ *
+ * @param own_priv_key own (ephemeral) DH private key
+ * @param kdf the KDF that should be used
+ * @param mac the MAC function that should be used
+ * @param mac_key_len key length of the MAC function. Default = 20 bytes
+ *
+ * output = (ephemeral) public key + ciphertext + tag
+ */
+ DLIES_Encryptor(const DH_PrivateKey& own_priv_key,
KDF* kdf,
MessageAuthenticationCode* mac,
size_t mac_key_len = 20);
- void set_other_key(const std::vector&);
+ /**
+ * Block cipher mode
+ *
+ * @param own_priv_key own (ephemeral) DH private key
+ * @param kdf the KDF that should be used
+ * @param cipher the block cipher that should be used
+ * @param cipher_key_len the key length of the block cipher
+ * @param mac the MAC function that should be used
+ * @param mac_key_len key length of the MAC function. Default = 20 bytes
+ *
+ * output = (ephemeral) public key + ciphertext + tag
+ */
+ DLIES_Encryptor(const DH_PrivateKey& own_priv_key,
+ KDF* kdf,
+ Cipher_Mode* cipher,
+ size_t cipher_key_len,
+ MessageAuthenticationCode* mac,
+ size_t mac_key_len = 20);
+
+ // Set the other parties public key
+ inline void set_other_key(const std::vector& other_pub_key)
+ {
+ m_other_pub_key = other_pub_key;
+ }
+
+ /// Set the initialization vector for the data encryption method
+ inline void set_initialization_vector(const InitializationVector& iv)
+ {
+ m_iv = iv;
+ }
+
private:
std::vector enc(const byte[], size_t,
RandomNumberGenerator&) const override;
size_t maximum_input_size() const override;
- std::vector m_other_key, m_my_key;
-
+ std::vector m_other_pub_key;
+ std::vector m_own_pub_key;
PK_Key_Agreement m_ka;
std::unique_ptr m_kdf;
+ std::unique_ptr m_cipher;
+ const size_t m_cipher_key_len;
std::unique_ptr m_mac;
- size_t m_mac_keylen;
+ const size_t m_mac_keylen;
+ InitializationVector m_iv;
};
/**
@@ -46,21 +92,58 @@ class BOTAN_DLL DLIES_Encryptor : public PK_Encryptor
class BOTAN_DLL DLIES_Decryptor : public PK_Decryptor
{
public:
- DLIES_Decryptor(const PK_Key_Agreement_Key&,
+ /**
+ * Stream mode: use KDF to provide a stream of bytes to xor with the message
+ *
+ * @param own_priv_key own (ephemeral) DH private key
+ * @param kdf the KDF that should be used
+ * @param mac the MAC function that should be used
+ * @param mac_key_len key length of the MAC function. Default = 20 bytes
+ *
+ * input = (ephemeral) public key + ciphertext + tag
+ */
+ DLIES_Decryptor(const DH_PrivateKey& own_priv_key,
KDF* kdf,
MessageAuthenticationCode* mac,
size_t mac_key_len = 20);
+ /**
+ * Block cipher mode
+ *
+ * @param own_priv_key own (ephemeral) DH private key
+ * @param kdf the KDF that should be used
+ * @param cipher the block cipher that should be used
+ * @param cipher_key_len the key length of the block cipher
+ * @param mac the MAC function that should be used
+ * @param mac_key_len key length of the MAC function. Default = 20 bytes
+ *
+ * input = (ephemeral) public key + ciphertext + tag
+ */
+ DLIES_Decryptor(const DH_PrivateKey& own_priv_key,
+ KDF* kdf,
+ Cipher_Mode* cipher,
+ size_t cipher_key_len,
+ MessageAuthenticationCode* mac,
+ size_t mac_key_len = 20);
+
+ /// Set the initialization vector for the data decryption method
+ inline void set_initialization_vector(const InitializationVector& iv)
+ {
+ m_iv = iv;
+ }
+
private:
secure_vector do_decrypt(byte& valid_mask,
const byte in[], size_t in_len) const override;
- std::vector m_my_key;
-
+ const size_t m_pub_key_size;
PK_Key_Agreement m_ka;
std::unique_ptr m_kdf;
+ std::unique_ptr m_cipher;
+ const size_t m_cipher_key_len;
std::unique_ptr m_mac;
- size_t m_mac_keylen;
+ const size_t m_mac_keylen;
+ InitializationVector m_iv;
};
}
diff --git a/src/lib/pubkey/dlies/info.txt b/src/lib/pubkey/dlies/info.txt
index ec1bac803..30362ad78 100644
--- a/src/lib/pubkey/dlies/info.txt
+++ b/src/lib/pubkey/dlies/info.txt
@@ -1,6 +1,7 @@
-define DLIES 20131128
+define DLIES 20160713
kdf
mac
+block
diff --git a/src/tests/data/pubkey/dlies.vec b/src/tests/data/pubkey/dlies.vec
index d0546b4e0..245cdeddc 100644
--- a/src/tests/data/pubkey/dlies.vec
+++ b/src/tests/data/pubkey/dlies.vec
@@ -1,42 +1,982 @@
+########################### Test vectors created with bouncycastle 1.54 ###########################
-P = 179769313486231590770839156793787453197860296048756011706444423684197180216158519368947833795864925541502180565485980503646440548199239100050792877003355816639229553136239076508735759914822574862575007425302077447712589550957937778424442426617334727629299387668709205606050270810842907692932019128194467627007
+########### Block cipher mode ###########
+
+#public static void main(String[] args) throws InvalidCipherTextException {
+# // 2048-bit MODP Group. RFC3526
+# BigInteger g = new BigInteger( "2", 10 );
+# BigInteger p = new BigInteger( "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A0879"
+# + "8E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED"
+# + "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F"
+# + "83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B"
+# + "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA0510"
+# + "15728E5A8AACAA68FFFFFFFFFFFFFFFF", 16 );
+#
+# DHParameters dhParams = new DHParameters( p, g );
+#
+# // alice priv key
+# BigInteger xAlice = new BigInteger( "A01E167DE1013D6859E6CB068B7BF272C1D49DC764AD7676BFA0D85177", 16 );
+# DHPrivateKeyParameters alicePriv = new DHPrivateKeyParameters( xAlice, dhParams );
+#
+# // alice pub key
+# BigInteger yAlice = g.modPow(xAlice, p);
+# DHPublicKeyParameters alicePub = new DHPublicKeyParameters( yAlice, dhParams );
+#
+# // bob priv key
+# BigInteger xBob = new BigInteger( "8DD88BDC19AC1403A3FC3A0FC63D360F1062E3494177DC27F7EBCBD4A7", 16 );
+#
+# // bob pub key
+# BigInteger yBob = g.modPow(xBob, p);
+# DHPublicKeyParameters bobPub = new DHPublicKeyParameters( yBob, dhParams );
+#
+# // DLIES
+# byte[] d = new byte[ 0 ]; // the derivation parameter for the KDF function
+# byte[] e = new byte[ 0 ]; // the encoding parameter for the KDF function
+# int macKeySize = 256;
+# int cipherKeySize = 256;
+# byte[] iv = new byte[ 16 ];
+# CipherParameters cipherParams = new ParametersWithIV( new IESWithCipherParameters( d, e, macKeySize, cipherKeySize ), iv );
+#
+# IESEngine dlies =
+# new IESEngine( new DHBasicAgreement(), new KDF2BytesGenerator( new SHA256Digest() ), new HMac( new SHA256Digest() ), new PaddedBufferedBlockCipher( new CBCBlockCipher(
+# new AESEngine() ) ) );
+# dlies.init( true, alicePriv, bobPub, cipherParams );
+#
+# byte[] message = Hex.decode( "00" );
+# byte[] result = dlies.processBlock( message, 0, message.length );
+#
+# byte[] ephPublicKey = alicePub.getY().toByteArray();
+# byte[] out = Arrays.concatenate( ephPublicKey, result );
+#
+# System.out.println( Hex.toHexString( out ) );
+
+####### KDF2
+
+Kdf = KDF2(SHA-512)
+Mac = HMAC(SHA-512)
+MacKeyLen = 64
+Cipher = AES-256/CBC
+CipherKeyLen = 32
+IV = 00000000000000000000000000000000
+P = 32317006071311007300338913926423828248817941241140239112842009751400741706634354222619689417363569347117901737909704191754605873209195028853758986185622153212175412514901774520270235796078236248884246189477587641105928646099411723245426622522193230540919037680524235519125679715870117001058055877651038861847280257976054903569732561526167081339361799541336476559160368317896729073178384589680639671900977202194168647225871031411336429319536193471636533209717077448227988588565369208645296636077250268955505928362751121174096972998068410554359584866583291642136218231078990999448652468262416972035911852507045361090559
+G = 2
+X1 = 4316760088048858173826993660634587631078362099236037980378049883427191
+X2 = 3824157470039532100357278938102046076290169354062923298804711018976423
+Msg = 75dad921764736e389c4224daf7b278ec291e682044742e2e9c7a025b54dd62f
+Ciphertext = 57dfafa0d81ac3aaca2570ad13cccd127239f4ee04843bb738234588f0daea53ccd8af65a5a00ed19fbb6f2eb57779ff2e38e3d5d27986253a1193dabf14d2402e1a33527866fa21f23f7abbee5f454aad762fc90139c8377bf6cc77af7f982404baea5ca4831dd8ed28babf2d43b1f65eff42167b82f020dfd4928d8e96dcb7845ecf8f560fbbf5646fae5bc4eda6d978e5fb333843a1f4525cfbdde756842a1e353f4de1503738eec6c9d901a78cdefedf8daaa49631da674b44cab2193c778bf29766730a656b42e96f84698f77913c718067048263034cf2a2f34572ab662e4b1c5b04cd71183433c591abd5613820544d46f7462bea57e44f23ab06e0fb7c5f222b4215cd1b1c197fe8cfa2a252ad4c61a599ade3c8e8d0442b93afc626405fbe7bb1d103bdd8ce9468071a013f0f627c2cdcd61a253bbf81feb5ae6093aee4a5bd71f2a2f20764615d0e70561903de24a46cfbc9340f4fe5ce209ad48c97a4e3a3c5c75186a020f4b44008f270
+
+Kdf = KDF2(SHA-512)
+Mac = HMAC(SHA-512)
+MacKeyLen = 32
+Cipher = AES-256/CBC
+CipherKeyLen = 32
+IV = 00000000000000000000000000000000
+P = 32317006071311007300338913926423828248817941241140239112842009751400741706634354222619689417363569347117901737909704191754605873209195028853758986185622153212175412514901774520270235796078236248884246189477587641105928646099411723245426622522193230540919037680524235519125679715870117001058055877651038861847280257976054903569732561526167081339361799541336476559160368317896729073178384589680639671900977202194168647225871031411336429319536193471636533209717077448227988588565369208645296636077250268955505928362751121174096972998068410554359584866583291642136218231078990999448652468262416972035911852507045361090559
+G = 2
+X1 = 4316760088048858173826993660634587631078362099236037980378049883427191
+X2 = 3824157470039532100357278938102046076290169354062923298804711018976423
+Msg = 75dad921764736e389c4224daf7b278ec291e682044742e2e9c7a025b54dd62f
+Ciphertext = 57dfafa0d81ac3aaca2570ad13cccd127239f4ee04843bb738234588f0daea53ccd8af65a5a00ed19fbb6f2eb57779ff2e38e3d5d27986253a1193dabf14d2402e1a33527866fa21f23f7abbee5f454aad762fc90139c8377bf6cc77af7f982404baea5ca4831dd8ed28babf2d43b1f65eff42167b82f020dfd4928d8e96dcb7845ecf8f560fbbf5646fae5bc4eda6d978e5fb333843a1f4525cfbdde756842a1e353f4de1503738eec6c9d901a78cdefedf8daaa49631da674b44cab2193c778bf29766730a656b42e96f84698f77913c718067048263034cf2a2f34572ab662e4b1c5b04cd71183433c591abd5613820544d46f7462bea57e44f23ab06e0fb7c5f222b4215cd1b1c197fe8cfa2a252ad4c61a599ade3c8e8d0442b93afc626405fbe7bb1d103bdd8ce9468071a013f5be4a46a387f09e11d75b5d21993f4eeb287410282007dba329b59a588d84888dd6f6c8d74047ae9b82097e64da28721e70adb43526752aac237f565cdebf0be
+
+Kdf = KDF2(SHA-512)
+Mac = HMAC(SHA-512)
+MacKeyLen = 20
+Cipher = AES-256/CBC
+CipherKeyLen = 32
+IV = 00000000000000000000000000000000
+P = 32317006071311007300338913926423828248817941241140239112842009751400741706634354222619689417363569347117901737909704191754605873209195028853758986185622153212175412514901774520270235796078236248884246189477587641105928646099411723245426622522193230540919037680524235519125679715870117001058055877651038861847280257976054903569732561526167081339361799541336476559160368317896729073178384589680639671900977202194168647225871031411336429319536193471636533209717077448227988588565369208645296636077250268955505928362751121174096972998068410554359584866583291642136218231078990999448652468262416972035911852507045361090559
+G = 2
+X1 = 4316760088048858173826993660634587631078362099236037980378049883427191
+X2 = 3824157470039532100357278938102046076290169354062923298804711018976423
+Msg = 75dad921764736e389c4224daf7b278ec291e682044742e2e9c7a025b54dd62f
+Ciphertext = 57dfafa0d81ac3aaca2570ad13cccd127239f4ee04843bb738234588f0daea53ccd8af65a5a00ed19fbb6f2eb57779ff2e38e3d5d27986253a1193dabf14d2402e1a33527866fa21f23f7abbee5f454aad762fc90139c8377bf6cc77af7f982404baea5ca4831dd8ed28babf2d43b1f65eff42167b82f020dfd4928d8e96dcb7845ecf8f560fbbf5646fae5bc4eda6d978e5fb333843a1f4525cfbdde756842a1e353f4de1503738eec6c9d901a78cdefedf8daaa49631da674b44cab2193c778bf29766730a656b42e96f84698f77913c718067048263034cf2a2f34572ab662e4b1c5b04cd71183433c591abd5613820544d46f7462bea57e44f23ab06e0fb7c5f222b4215cd1b1c197fe8cfa2a252ad4c61a599ade3c8e8d0442b93afc626405fbe7bb1d103bdd8ce9468071a013ff78712a17c1894f458195e0fff798d995090d935e3deb25e13fedb9abbce760da4f49b70ae6e0b6c6261a182386b687873e03f24ac64dd74ce841a4ab04a2bb6
+
+Kdf = KDF2(SHA-512)
+Mac = HMAC(SHA-512)
+MacKeyLen = 64
+Cipher = AES-256/CBC
+CipherKeyLen = 32
+IV = 00112233445566778899aabbccddeeff
+P = 32317006071311007300338913926423828248817941241140239112842009751400741706634354222619689417363569347117901737909704191754605873209195028853758986185622153212175412514901774520270235796078236248884246189477587641105928646099411723245426622522193230540919037680524235519125679715870117001058055877651038861847280257976054903569732561526167081339361799541336476559160368317896729073178384589680639671900977202194168647225871031411336429319536193471636533209717077448227988588565369208645296636077250268955505928362751121174096972998068410554359584866583291642136218231078990999448652468262416972035911852507045361090559
+G = 2
+X1 = 4316760088048858173826993660634587631078362099236037980378049883427191
+X2 = 3824157470039532100357278938102046076290169354062923298804711018976423
+Msg = 75dad921764736e389c4224daf7b278ec291e682044742e2e9c7a025b54dd62f
+Ciphertext = 57dfafa0d81ac3aaca2570ad13cccd127239f4ee04843bb738234588f0daea53ccd8af65a5a00ed19fbb6f2eb57779ff2e38e3d5d27986253a1193dabf14d2402e1a33527866fa21f23f7abbee5f454aad762fc90139c8377bf6cc77af7f982404baea5ca4831dd8ed28babf2d43b1f65eff42167b82f020dfd4928d8e96dcb7845ecf8f560fbbf5646fae5bc4eda6d978e5fb333843a1f4525cfbdde756842a1e353f4de1503738eec6c9d901a78cdefedf8daaa49631da674b44cab2193c778bf29766730a656b42e96f84698f77913c718067048263034cf2a2f34572ab662e4b1c5b04cd71183433c591abd5613820544d46f7462bea57e44f23ab06e0fbe0004a18072d33b7a7ac09362953dec57197a78ccdac0f1aa98d2a2eb6580a48053b0df23dfe2518253813dc1d1e6651cfefdaa03d8a2bd25201f40abbae203d1487b0d79c57aef0c5d2fb05f9f86f8fa2806eb3cec40a46b9bf7589142ef680bea0cf197e28dd4615c6f921418a4f54
+
+Kdf = KDF2(SHA-512)
+Mac = HMAC(SHA-512)
+MacKeyLen = 32
+Cipher = AES-256/CBC
+CipherKeyLen = 32
+IV = 00112233445566778899aabbccddeeff
+P = 32317006071311007300338913926423828248817941241140239112842009751400741706634354222619689417363569347117901737909704191754605873209195028853758986185622153212175412514901774520270235796078236248884246189477587641105928646099411723245426622522193230540919037680524235519125679715870117001058055877651038861847280257976054903569732561526167081339361799541336476559160368317896729073178384589680639671900977202194168647225871031411336429319536193471636533209717077448227988588565369208645296636077250268955505928362751121174096972998068410554359584866583291642136218231078990999448652468262416972035911852507045361090559
+G = 2
+X1 = 4316760088048858173826993660634587631078362099236037980378049883427191
+X2 = 3824157470039532100357278938102046076290169354062923298804711018976423
+Msg = 75dad921764736e389c4224daf7b278ec291e682044742e2e9c7a025b54dd62f
+Ciphertext = 57dfafa0d81ac3aaca2570ad13cccd127239f4ee04843bb738234588f0daea53ccd8af65a5a00ed19fbb6f2eb57779ff2e38e3d5d27986253a1193dabf14d2402e1a33527866fa21f23f7abbee5f454aad762fc90139c8377bf6cc77af7f982404baea5ca4831dd8ed28babf2d43b1f65eff42167b82f020dfd4928d8e96dcb7845ecf8f560fbbf5646fae5bc4eda6d978e5fb333843a1f4525cfbdde756842a1e353f4de1503738eec6c9d901a78cdefedf8daaa49631da674b44cab2193c778bf29766730a656b42e96f84698f77913c718067048263034cf2a2f34572ab662e4b1c5b04cd71183433c591abd5613820544d46f7462bea57e44f23ab06e0fbe0004a18072d33b7a7ac09362953dec57197a78ccdac0f1aa98d2a2eb6580a48053b0df23dfe2518253813dc1d1e6651457da847bc1f337d1219222f97d75fb2ae68938e7f28d7e9595b87627d07d0bed859d0fb0077655b1c36ec12024cfedb4f8db121fd82e3029c27f8bac0c6ba1e
+
+Kdf = KDF2(SHA-512)
+Mac = HMAC(SHA-512)
+MacKeyLen = 20
+Cipher = AES-256/CBC
+CipherKeyLen = 32
+IV = 00112233445566778899aabbccddeeff
+P = 32317006071311007300338913926423828248817941241140239112842009751400741706634354222619689417363569347117901737909704191754605873209195028853758986185622153212175412514901774520270235796078236248884246189477587641105928646099411723245426622522193230540919037680524235519125679715870117001058055877651038861847280257976054903569732561526167081339361799541336476559160368317896729073178384589680639671900977202194168647225871031411336429319536193471636533209717077448227988588565369208645296636077250268955505928362751121174096972998068410554359584866583291642136218231078990999448652468262416972035911852507045361090559
+G = 2
+X1 = 4316760088048858173826993660634587631078362099236037980378049883427191
+X2 = 3824157470039532100357278938102046076290169354062923298804711018976423
+Msg = 75dad921764736e389c4224daf7b278ec291e682044742e2e9c7a025b54dd62f
+Ciphertext = 57dfafa0d81ac3aaca2570ad13cccd127239f4ee04843bb738234588f0daea53ccd8af65a5a00ed19fbb6f2eb57779ff2e38e3d5d27986253a1193dabf14d2402e1a33527866fa21f23f7abbee5f454aad762fc90139c8377bf6cc77af7f982404baea5ca4831dd8ed28babf2d43b1f65eff42167b82f020dfd4928d8e96dcb7845ecf8f560fbbf5646fae5bc4eda6d978e5fb333843a1f4525cfbdde756842a1e353f4de1503738eec6c9d901a78cdefedf8daaa49631da674b44cab2193c778bf29766730a656b42e96f84698f77913c718067048263034cf2a2f34572ab662e4b1c5b04cd71183433c591abd5613820544d46f7462bea57e44f23ab06e0fbe0004a18072d33b7a7ac09362953dec57197a78ccdac0f1aa98d2a2eb6580a48053b0df23dfe2518253813dc1d1e66513c34a7effee403da2137493cd7f3e55b77a0cdd894c7126cea1d50956297e9316ca319ae00b59f45fdc781d0569825835376d3ad8876d1e5351c958cc858de25
+
+Kdf = KDF2(SHA-256)
+Mac = HMAC(SHA-256)
+MacKeyLen = 32
+Cipher = AES-256/CBC
+CipherKeyLen = 32
+IV = 00000000000000000000000000000000
+P = 32317006071311007300338913926423828248817941241140239112842009751400741706634354222619689417363569347117901737909704191754605873209195028853758986185622153212175412514901774520270235796078236248884246189477587641105928646099411723245426622522193230540919037680524235519125679715870117001058055877651038861847280257976054903569732561526167081339361799541336476559160368317896729073178384589680639671900977202194168647225871031411336429319536193471636533209717077448227988588565369208645296636077250268955505928362751121174096972998068410554359584866583291642136218231078990999448652468262416972035911852507045361090559
+G = 2
+X1 = 4316760088048858173826993660634587631078362099236037980378049883427191
+X2 = 3824157470039532100357278938102046076290169354062923298804711018976423
+Msg = 75dad921764736e389c4224daf7b278ec291e682044742e2e9c7a025b54dd62f
+Ciphertext = 57dfafa0d81ac3aaca2570ad13cccd127239f4ee04843bb738234588f0daea53ccd8af65a5a00ed19fbb6f2eb57779ff2e38e3d5d27986253a1193dabf14d2402e1a33527866fa21f23f7abbee5f454aad762fc90139c8377bf6cc77af7f982404baea5ca4831dd8ed28babf2d43b1f65eff42167b82f020dfd4928d8e96dcb7845ecf8f560fbbf5646fae5bc4eda6d978e5fb333843a1f4525cfbdde756842a1e353f4de1503738eec6c9d901a78cdefedf8daaa49631da674b44cab2193c778bf29766730a656b42e96f84698f77913c718067048263034cf2a2f34572ab662e4b1c5b04cd71183433c591abd5613820544d46f7462bea57e44f23ab06e0fb97f3ed7829ec1c4b6d22646252e19a267df9b0100f47f6a376c9b9d9c35a446d1eb7b12fe7f6d6e659d9c83c3c9b3c2a51405729857b99429f910de4fd993092b037a8270bbedcc5168f821167a256e4
+
+Kdf = KDF2(SHA-256)
+Mac = HMAC(SHA-256)
+MacKeyLen = 16
+Cipher = AES-256/CBC
+CipherKeyLen = 32
+IV = 00000000000000000000000000000000
+P = 32317006071311007300338913926423828248817941241140239112842009751400741706634354222619689417363569347117901737909704191754605873209195028853758986185622153212175412514901774520270235796078236248884246189477587641105928646099411723245426622522193230540919037680524235519125679715870117001058055877651038861847280257976054903569732561526167081339361799541336476559160368317896729073178384589680639671900977202194168647225871031411336429319536193471636533209717077448227988588565369208645296636077250268955505928362751121174096972998068410554359584866583291642136218231078990999448652468262416972035911852507045361090559
+G = 2
+X1 = 4316760088048858173826993660634587631078362099236037980378049883427191
+X2 = 3824157470039532100357278938102046076290169354062923298804711018976423
+Msg = 75dad921764736e389c4224daf7b278ec291e682044742e2e9c7a025b54dd62f
+Ciphertext = 57dfafa0d81ac3aaca2570ad13cccd127239f4ee04843bb738234588f0daea53ccd8af65a5a00ed19fbb6f2eb57779ff2e38e3d5d27986253a1193dabf14d2402e1a33527866fa21f23f7abbee5f454aad762fc90139c8377bf6cc77af7f982404baea5ca4831dd8ed28babf2d43b1f65eff42167b82f020dfd4928d8e96dcb7845ecf8f560fbbf5646fae5bc4eda6d978e5fb333843a1f4525cfbdde756842a1e353f4de1503738eec6c9d901a78cdefedf8daaa49631da674b44cab2193c778bf29766730a656b42e96f84698f77913c718067048263034cf2a2f34572ab662e4b1c5b04cd71183433c591abd5613820544d46f7462bea57e44f23ab06e0fb97f3ed7829ec1c4b6d22646252e19a267df9b0100f47f6a376c9b9d9c35a446d1eb7b12fe7f6d6e659d9c83c3c9b3c2a3878d585b4501ae07e88d18b5ebb87b028347a4dd9a4624b849ab5b9bf18daf8
+
+Kdf = KDF2(SHA-256)
+Mac = HMAC(SHA-256)
+MacKeyLen = 32
+Cipher = AES-256/CBC
+CipherKeyLen = 32
+IV = 00112233445566778899aabbccddeeff
+P = 32317006071311007300338913926423828248817941241140239112842009751400741706634354222619689417363569347117901737909704191754605873209195028853758986185622153212175412514901774520270235796078236248884246189477587641105928646099411723245426622522193230540919037680524235519125679715870117001058055877651038861847280257976054903569732561526167081339361799541336476559160368317896729073178384589680639671900977202194168647225871031411336429319536193471636533209717077448227988588565369208645296636077250268955505928362751121174096972998068410554359584866583291642136218231078990999448652468262416972035911852507045361090559
+G = 2
+X1 = 4316760088048858173826993660634587631078362099236037980378049883427191
+X2 = 3824157470039532100357278938102046076290169354062923298804711018976423
+Msg = 75dad921764736e389c4224daf7b278ec291e682044742e2e9c7a025b54dd62f
+Ciphertext = 57dfafa0d81ac3aaca2570ad13cccd127239f4ee04843bb738234588f0daea53ccd8af65a5a00ed19fbb6f2eb57779ff2e38e3d5d27986253a1193dabf14d2402e1a33527866fa21f23f7abbee5f454aad762fc90139c8377bf6cc77af7f982404baea5ca4831dd8ed28babf2d43b1f65eff42167b82f020dfd4928d8e96dcb7845ecf8f560fbbf5646fae5bc4eda6d978e5fb333843a1f4525cfbdde756842a1e353f4de1503738eec6c9d901a78cdefedf8daaa49631da674b44cab2193c778bf29766730a656b42e96f84698f77913c718067048263034cf2a2f34572ab662e4b1c5b04cd71183433c591abd5613820544d46f7462bea57e44f23ab06e0fb41ca8e7f448450d7c6ff6b7e61e0a4fba8f40c2944183f9c7c8a46bc7eb2d468aa5fb1cd9739320e6a60909994fb459b5515c49b1eb4a33015aa908886ec3bd26b57ad9158dbac9a8ede364fb763f5c2
+
+Kdf = KDF2(SHA-256)
+Mac = HMAC(SHA-256)
+MacKeyLen = 20
+Cipher = AES-256/CBC
+CipherKeyLen = 32
+IV = 00112233445566778899aabbccddeeff
+P = 32317006071311007300338913926423828248817941241140239112842009751400741706634354222619689417363569347117901737909704191754605873209195028853758986185622153212175412514901774520270235796078236248884246189477587641105928646099411723245426622522193230540919037680524235519125679715870117001058055877651038861847280257976054903569732561526167081339361799541336476559160368317896729073178384589680639671900977202194168647225871031411336429319536193471636533209717077448227988588565369208645296636077250268955505928362751121174096972998068410554359584866583291642136218231078990999448652468262416972035911852507045361090559
+G = 2
+X1 = 4316760088048858173826993660634587631078362099236037980378049883427191
+X2 = 3824157470039532100357278938102046076290169354062923298804711018976423
+Msg = 75dad921764736e389c4224daf7b278ec291e682044742e2e9c7a025b54dd62f
+Ciphertext = 57dfafa0d81ac3aaca2570ad13cccd127239f4ee04843bb738234588f0daea53ccd8af65a5a00ed19fbb6f2eb57779ff2e38e3d5d27986253a1193dabf14d2402e1a33527866fa21f23f7abbee5f454aad762fc90139c8377bf6cc77af7f982404baea5ca4831dd8ed28babf2d43b1f65eff42167b82f020dfd4928d8e96dcb7845ecf8f560fbbf5646fae5bc4eda6d978e5fb333843a1f4525cfbdde756842a1e353f4de1503738eec6c9d901a78cdefedf8daaa49631da674b44cab2193c778bf29766730a656b42e96f84698f77913c718067048263034cf2a2f34572ab662e4b1c5b04cd71183433c591abd5613820544d46f7462bea57e44f23ab06e0fb41ca8e7f448450d7c6ff6b7e61e0a4fba8f40c2944183f9c7c8a46bc7eb2d468aa5fb1cd9739320e6a60909994fb459b06287932b21dbe518b9cb87a6147cbddfc72ec35f96ddf262271267bcfff1bdd
+
+Kdf = KDF2(SHA-1)
+Mac = HMAC(SHA-1)
+MacKeyLen = 20
+Cipher = AES-256/CBC
+CipherKeyLen = 32
+IV = 00000000000000000000000000000000
+P = 32317006071311007300338913926423828248817941241140239112842009751400741706634354222619689417363569347117901737909704191754605873209195028853758986185622153212175412514901774520270235796078236248884246189477587641105928646099411723245426622522193230540919037680524235519125679715870117001058055877651038861847280257976054903569732561526167081339361799541336476559160368317896729073178384589680639671900977202194168647225871031411336429319536193471636533209717077448227988588565369208645296636077250268955505928362751121174096972998068410554359584866583291642136218231078990999448652468262416972035911852507045361090559
+G = 2
+X1 = 4316760088048858173826993660634587631078362099236037980378049883427191
+X2 = 3824157470039532100357278938102046076290169354062923298804711018976423
+Msg = 75dad921764736e389c4224daf7b278ec291e682044742e2e9c7a025b54dd62f
+Ciphertext = 57dfafa0d81ac3aaca2570ad13cccd127239f4ee04843bb738234588f0daea53ccd8af65a5a00ed19fbb6f2eb57779ff2e38e3d5d27986253a1193dabf14d2402e1a33527866fa21f23f7abbee5f454aad762fc90139c8377bf6cc77af7f982404baea5ca4831dd8ed28babf2d43b1f65eff42167b82f020dfd4928d8e96dcb7845ecf8f560fbbf5646fae5bc4eda6d978e5fb333843a1f4525cfbdde756842a1e353f4de1503738eec6c9d901a78cdefedf8daaa49631da674b44cab2193c778bf29766730a656b42e96f84698f77913c718067048263034cf2a2f34572ab662e4b1c5b04cd71183433c591abd5613820544d46f7462bea57e44f23ab06e0fb9378fd44585fabeac1d9f2941fa7fd229d2353130ecf210c7926c388c5e1e5438b3c6ba20f7551ef03d769e0d1c04587983fa4707e64dbe643d21f3a98267a3f5f14e7f3
+
+Kdf = KDF2(SHA-1)
+Mac = HMAC(SHA-1)
+MacKeyLen = 16
+Cipher = AES-256/CBC
+CipherKeyLen = 32
+IV = 00000000000000000000000000000000
+P = 32317006071311007300338913926423828248817941241140239112842009751400741706634354222619689417363569347117901737909704191754605873209195028853758986185622153212175412514901774520270235796078236248884246189477587641105928646099411723245426622522193230540919037680524235519125679715870117001058055877651038861847280257976054903569732561526167081339361799541336476559160368317896729073178384589680639671900977202194168647225871031411336429319536193471636533209717077448227988588565369208645296636077250268955505928362751121174096972998068410554359584866583291642136218231078990999448652468262416972035911852507045361090559
+G = 2
+X1 = 4316760088048858173826993660634587631078362099236037980378049883427191
+X2 = 3824157470039532100357278938102046076290169354062923298804711018976423
+Msg = 75dad921764736e389c4224daf7b278ec291e682044742e2e9c7a025b54dd62f
+Ciphertext = 57dfafa0d81ac3aaca2570ad13cccd127239f4ee04843bb738234588f0daea53ccd8af65a5a00ed19fbb6f2eb57779ff2e38e3d5d27986253a1193dabf14d2402e1a33527866fa21f23f7abbee5f454aad762fc90139c8377bf6cc77af7f982404baea5ca4831dd8ed28babf2d43b1f65eff42167b82f020dfd4928d8e96dcb7845ecf8f560fbbf5646fae5bc4eda6d978e5fb333843a1f4525cfbdde756842a1e353f4de1503738eec6c9d901a78cdefedf8daaa49631da674b44cab2193c778bf29766730a656b42e96f84698f77913c718067048263034cf2a2f34572ab662e4b1c5b04cd71183433c591abd5613820544d46f7462bea57e44f23ab06e0fb9378fd44585fabeac1d9f2941fa7fd229d2353130ecf210c7926c388c5e1e5438b3c6ba20f7551ef03d769e0d1c0458758b34c3789b3a3200b293ada094ea99522362b81
+
+Kdf = KDF2(SHA-1)
+Mac = HMAC(SHA-1)
+MacKeyLen = 20
+Cipher = AES-256/CBC
+CipherKeyLen = 32
+IV = 00112233445566778899aabbccddeeff
+P = 32317006071311007300338913926423828248817941241140239112842009751400741706634354222619689417363569347117901737909704191754605873209195028853758986185622153212175412514901774520270235796078236248884246189477587641105928646099411723245426622522193230540919037680524235519125679715870117001058055877651038861847280257976054903569732561526167081339361799541336476559160368317896729073178384589680639671900977202194168647225871031411336429319536193471636533209717077448227988588565369208645296636077250268955505928362751121174096972998068410554359584866583291642136218231078990999448652468262416972035911852507045361090559
+G = 2
+X1 = 4316760088048858173826993660634587631078362099236037980378049883427191
+X2 = 3824157470039532100357278938102046076290169354062923298804711018976423
+Msg = 75dad921764736e389c4224daf7b278ec291e682044742e2e9c7a025b54dd62f
+Ciphertext = 57dfafa0d81ac3aaca2570ad13cccd127239f4ee04843bb738234588f0daea53ccd8af65a5a00ed19fbb6f2eb57779ff2e38e3d5d27986253a1193dabf14d2402e1a33527866fa21f23f7abbee5f454aad762fc90139c8377bf6cc77af7f982404baea5ca4831dd8ed28babf2d43b1f65eff42167b82f020dfd4928d8e96dcb7845ecf8f560fbbf5646fae5bc4eda6d978e5fb333843a1f4525cfbdde756842a1e353f4de1503738eec6c9d901a78cdefedf8daaa49631da674b44cab2193c778bf29766730a656b42e96f84698f77913c718067048263034cf2a2f34572ab662e4b1c5b04cd71183433c591abd5613820544d46f7462bea57e44f23ab06e0fbc220747adc100278b830f636b942d0daf1651e218ea592e01cd5a4a4234974a61b4a71ff4d1f19a5892d417fab9c21898ec74ba98720d2c72422e9214a68a9f4065d2a73
+
+Kdf = KDF2(SHA-1)
+Mac = HMAC(SHA-1)
+MacKeyLen = 16
+Cipher = AES-256/CBC
+CipherKeyLen = 32
+IV = 00112233445566778899aabbccddeeff
+P = 32317006071311007300338913926423828248817941241140239112842009751400741706634354222619689417363569347117901737909704191754605873209195028853758986185622153212175412514901774520270235796078236248884246189477587641105928646099411723245426622522193230540919037680524235519125679715870117001058055877651038861847280257976054903569732561526167081339361799541336476559160368317896729073178384589680639671900977202194168647225871031411336429319536193471636533209717077448227988588565369208645296636077250268955505928362751121174096972998068410554359584866583291642136218231078990999448652468262416972035911852507045361090559
+G = 2
+X1 = 4316760088048858173826993660634587631078362099236037980378049883427191
+X2 = 3824157470039532100357278938102046076290169354062923298804711018976423
+Msg = 75dad921764736e389c4224daf7b278ec291e682044742e2e9c7a025b54dd62f
+Ciphertext = 57dfafa0d81ac3aaca2570ad13cccd127239f4ee04843bb738234588f0daea53ccd8af65a5a00ed19fbb6f2eb57779ff2e38e3d5d27986253a1193dabf14d2402e1a33527866fa21f23f7abbee5f454aad762fc90139c8377bf6cc77af7f982404baea5ca4831dd8ed28babf2d43b1f65eff42167b82f020dfd4928d8e96dcb7845ecf8f560fbbf5646fae5bc4eda6d978e5fb333843a1f4525cfbdde756842a1e353f4de1503738eec6c9d901a78cdefedf8daaa49631da674b44cab2193c778bf29766730a656b42e96f84698f77913c718067048263034cf2a2f34572ab662e4b1c5b04cd71183433c591abd5613820544d46f7462bea57e44f23ab06e0fbc220747adc100278b830f636b942d0daf1651e218ea592e01cd5a4a4234974a61b4a71ff4d1f19a5892d417fab9c2189cb14a54612e3a980d73c1e0ad972deb25753eb75
+
+Kdf = KDF2(SHA-512)
+Mac = CMAC(AES-256)
+MacKeyLen = 32
+Cipher = AES-256/CBC
+CipherKeyLen = 32
+IV = 00000000000000000000000000000000
+P = 32317006071311007300338913926423828248817941241140239112842009751400741706634354222619689417363569347117901737909704191754605873209195028853758986185622153212175412514901774520270235796078236248884246189477587641105928646099411723245426622522193230540919037680524235519125679715870117001058055877651038861847280257976054903569732561526167081339361799541336476559160368317896729073178384589680639671900977202194168647225871031411336429319536193471636533209717077448227988588565369208645296636077250268955505928362751121174096972998068410554359584866583291642136218231078990999448652468262416972035911852507045361090559
+G = 2
+X1 = 4316760088048858173826993660634587631078362099236037980378049883427191
+X2 = 3824157470039532100357278938102046076290169354062923298804711018976423
+Msg = 75dad921764736e389c4224daf7b278ec291e682044742e2e9c7a025b54dd62f
+Ciphertext = 57dfafa0d81ac3aaca2570ad13cccd127239f4ee04843bb738234588f0daea53ccd8af65a5a00ed19fbb6f2eb57779ff2e38e3d5d27986253a1193dabf14d2402e1a33527866fa21f23f7abbee5f454aad762fc90139c8377bf6cc77af7f982404baea5ca4831dd8ed28babf2d43b1f65eff42167b82f020dfd4928d8e96dcb7845ecf8f560fbbf5646fae5bc4eda6d978e5fb333843a1f4525cfbdde756842a1e353f4de1503738eec6c9d901a78cdefedf8daaa49631da674b44cab2193c778bf29766730a656b42e96f84698f77913c718067048263034cf2a2f34572ab662e4b1c5b04cd71183433c591abd5613820544d46f7462bea57e44f23ab06e0fb7c5f222b4215cd1b1c197fe8cfa2a252ad4c61a599ade3c8e8d0442b93afc626405fbe7bb1d103bdd8ce9468071a013fa0beb8264a28536dd671864fa73bf1d4
+
+Kdf = KDF2(SHA-512)
+Mac = CMAC(AES-256)
+MacKeyLen = 32
+Cipher = AES-256/CBC
+CipherKeyLen = 32
+IV = 00112233445566778899aabbccddeeff
+P = 32317006071311007300338913926423828248817941241140239112842009751400741706634354222619689417363569347117901737909704191754605873209195028853758986185622153212175412514901774520270235796078236248884246189477587641105928646099411723245426622522193230540919037680524235519125679715870117001058055877651038861847280257976054903569732561526167081339361799541336476559160368317896729073178384589680639671900977202194168647225871031411336429319536193471636533209717077448227988588565369208645296636077250268955505928362751121174096972998068410554359584866583291642136218231078990999448652468262416972035911852507045361090559
+G = 2
+X1 = 4316760088048858173826993660634587631078362099236037980378049883427191
+X2 = 3824157470039532100357278938102046076290169354062923298804711018976423
+Msg = 75dad921764736e389c4224daf7b278ec291e682044742e2e9c7a025b54dd62f
+Ciphertext = 57dfafa0d81ac3aaca2570ad13cccd127239f4ee04843bb738234588f0daea53ccd8af65a5a00ed19fbb6f2eb57779ff2e38e3d5d27986253a1193dabf14d2402e1a33527866fa21f23f7abbee5f454aad762fc90139c8377bf6cc77af7f982404baea5ca4831dd8ed28babf2d43b1f65eff42167b82f020dfd4928d8e96dcb7845ecf8f560fbbf5646fae5bc4eda6d978e5fb333843a1f4525cfbdde756842a1e353f4de1503738eec6c9d901a78cdefedf8daaa49631da674b44cab2193c778bf29766730a656b42e96f84698f77913c718067048263034cf2a2f34572ab662e4b1c5b04cd71183433c591abd5613820544d46f7462bea57e44f23ab06e0fbe0004a18072d33b7a7ac09362953dec57197a78ccdac0f1aa98d2a2eb6580a48053b0df23dfe2518253813dc1d1e6651825183042643dcaf2dc69700e29396d8
+
+Kdf = KDF2(SHA-256)
+Mac = CMAC(AES-256)
+MacKeyLen = 32
+Cipher = AES-256/CBC
+CipherKeyLen = 32
+IV = 00000000000000000000000000000000
+P = 32317006071311007300338913926423828248817941241140239112842009751400741706634354222619689417363569347117901737909704191754605873209195028853758986185622153212175412514901774520270235796078236248884246189477587641105928646099411723245426622522193230540919037680524235519125679715870117001058055877651038861847280257976054903569732561526167081339361799541336476559160368317896729073178384589680639671900977202194168647225871031411336429319536193471636533209717077448227988588565369208645296636077250268955505928362751121174096972998068410554359584866583291642136218231078990999448652468262416972035911852507045361090559
+G = 2
+X1 = 4316760088048858173826993660634587631078362099236037980378049883427191
+X2 = 3824157470039532100357278938102046076290169354062923298804711018976423
+Msg = 75dad921764736e389c4224daf7b278ec291e682044742e2e9c7a025b54dd62f
+Ciphertext = 57dfafa0d81ac3aaca2570ad13cccd127239f4ee04843bb738234588f0daea53ccd8af65a5a00ed19fbb6f2eb57779ff2e38e3d5d27986253a1193dabf14d2402e1a33527866fa21f23f7abbee5f454aad762fc90139c8377bf6cc77af7f982404baea5ca4831dd8ed28babf2d43b1f65eff42167b82f020dfd4928d8e96dcb7845ecf8f560fbbf5646fae5bc4eda6d978e5fb333843a1f4525cfbdde756842a1e353f4de1503738eec6c9d901a78cdefedf8daaa49631da674b44cab2193c778bf29766730a656b42e96f84698f77913c718067048263034cf2a2f34572ab662e4b1c5b04cd71183433c591abd5613820544d46f7462bea57e44f23ab06e0fb97f3ed7829ec1c4b6d22646252e19a267df9b0100f47f6a376c9b9d9c35a446d1eb7b12fe7f6d6e659d9c83c3c9b3c2a203a3d53a802d02c1be57381a72fa28c
+
+Kdf = KDF2(SHA-256)
+Mac = CMAC(AES-256)
+MacKeyLen = 32
+Cipher = AES-256/CBC
+CipherKeyLen = 32
+IV = 00112233445566778899aabbccddeeff
+P = 32317006071311007300338913926423828248817941241140239112842009751400741706634354222619689417363569347117901737909704191754605873209195028853758986185622153212175412514901774520270235796078236248884246189477587641105928646099411723245426622522193230540919037680524235519125679715870117001058055877651038861847280257976054903569732561526167081339361799541336476559160368317896729073178384589680639671900977202194168647225871031411336429319536193471636533209717077448227988588565369208645296636077250268955505928362751121174096972998068410554359584866583291642136218231078990999448652468262416972035911852507045361090559
+G = 2
+X1 = 4316760088048858173826993660634587631078362099236037980378049883427191
+X2 = 3824157470039532100357278938102046076290169354062923298804711018976423
+Msg = 75dad921764736e389c4224daf7b278ec291e682044742e2e9c7a025b54dd62f
+Ciphertext = 57dfafa0d81ac3aaca2570ad13cccd127239f4ee04843bb738234588f0daea53ccd8af65a5a00ed19fbb6f2eb57779ff2e38e3d5d27986253a1193dabf14d2402e1a33527866fa21f23f7abbee5f454aad762fc90139c8377bf6cc77af7f982404baea5ca4831dd8ed28babf2d43b1f65eff42167b82f020dfd4928d8e96dcb7845ecf8f560fbbf5646fae5bc4eda6d978e5fb333843a1f4525cfbdde756842a1e353f4de1503738eec6c9d901a78cdefedf8daaa49631da674b44cab2193c778bf29766730a656b42e96f84698f77913c718067048263034cf2a2f34572ab662e4b1c5b04cd71183433c591abd5613820544d46f7462bea57e44f23ab06e0fb41ca8e7f448450d7c6ff6b7e61e0a4fba8f40c2944183f9c7c8a46bc7eb2d468aa5fb1cd9739320e6a60909994fb459bee03ba55e204037119a97f02f1a8cb9b
+
+
+Kdf = KDF2(SHA-1)
+Mac = CMAC(AES-256)
+MacKeyLen = 32
+Cipher = AES-256/CBC
+CipherKeyLen = 32
+IV = 00000000000000000000000000000000
+P = 32317006071311007300338913926423828248817941241140239112842009751400741706634354222619689417363569347117901737909704191754605873209195028853758986185622153212175412514901774520270235796078236248884246189477587641105928646099411723245426622522193230540919037680524235519125679715870117001058055877651038861847280257976054903569732561526167081339361799541336476559160368317896729073178384589680639671900977202194168647225871031411336429319536193471636533209717077448227988588565369208645296636077250268955505928362751121174096972998068410554359584866583291642136218231078990999448652468262416972035911852507045361090559
+G = 2
+X1 = 4316760088048858173826993660634587631078362099236037980378049883427191
+X2 = 3824157470039532100357278938102046076290169354062923298804711018976423
+Msg = 75dad921764736e389c4224daf7b278ec291e682044742e2e9c7a025b54dd62f
+Ciphertext = 57dfafa0d81ac3aaca2570ad13cccd127239f4ee04843bb738234588f0daea53ccd8af65a5a00ed19fbb6f2eb57779ff2e38e3d5d27986253a1193dabf14d2402e1a33527866fa21f23f7abbee5f454aad762fc90139c8377bf6cc77af7f982404baea5ca4831dd8ed28babf2d43b1f65eff42167b82f020dfd4928d8e96dcb7845ecf8f560fbbf5646fae5bc4eda6d978e5fb333843a1f4525cfbdde756842a1e353f4de1503738eec6c9d901a78cdefedf8daaa49631da674b44cab2193c778bf29766730a656b42e96f84698f77913c718067048263034cf2a2f34572ab662e4b1c5b04cd71183433c591abd5613820544d46f7462bea57e44f23ab06e0fb9378fd44585fabeac1d9f2941fa7fd229d2353130ecf210c7926c388c5e1e5438b3c6ba20f7551ef03d769e0d1c04587d25c8b9b56026ae8187f6c667c3bf57b
+
+Kdf = KDF2(SHA-1)
+Mac = CMAC(AES-256)
+MacKeyLen = 32
+Cipher = AES-256/CBC
+CipherKeyLen = 32
+IV = 00112233445566778899aabbccddeeff
+P = 32317006071311007300338913926423828248817941241140239112842009751400741706634354222619689417363569347117901737909704191754605873209195028853758986185622153212175412514901774520270235796078236248884246189477587641105928646099411723245426622522193230540919037680524235519125679715870117001058055877651038861847280257976054903569732561526167081339361799541336476559160368317896729073178384589680639671900977202194168647225871031411336429319536193471636533209717077448227988588565369208645296636077250268955505928362751121174096972998068410554359584866583291642136218231078990999448652468262416972035911852507045361090559
+G = 2
+X1 = 4316760088048858173826993660634587631078362099236037980378049883427191
+X2 = 3824157470039532100357278938102046076290169354062923298804711018976423
+Msg = 75dad921764736e389c4224daf7b278ec291e682044742e2e9c7a025b54dd62f
+Ciphertext = 57dfafa0d81ac3aaca2570ad13cccd127239f4ee04843bb738234588f0daea53ccd8af65a5a00ed19fbb6f2eb57779ff2e38e3d5d27986253a1193dabf14d2402e1a33527866fa21f23f7abbee5f454aad762fc90139c8377bf6cc77af7f982404baea5ca4831dd8ed28babf2d43b1f65eff42167b82f020dfd4928d8e96dcb7845ecf8f560fbbf5646fae5bc4eda6d978e5fb333843a1f4525cfbdde756842a1e353f4de1503738eec6c9d901a78cdefedf8daaa49631da674b44cab2193c778bf29766730a656b42e96f84698f77913c718067048263034cf2a2f34572ab662e4b1c5b04cd71183433c591abd5613820544d46f7462bea57e44f23ab06e0fbc220747adc100278b830f636b942d0daf1651e218ea592e01cd5a4a4234974a61b4a71ff4d1f19a5892d417fab9c2189abcc03fbf5fdaa8d101408b13fe9cea3
+
+####### KDF1-18033
+
+Kdf = KDF1-18033(SHA-512)
+Mac = HMAC(SHA-512)
+MacKeyLen = 64
+Cipher = AES-256/CBC
+CipherKeyLen = 32
+IV = 00000000000000000000000000000000
+P = 32317006071311007300338913926423828248817941241140239112842009751400741706634354222619689417363569347117901737909704191754605873209195028853758986185622153212175412514901774520270235796078236248884246189477587641105928646099411723245426622522193230540919037680524235519125679715870117001058055877651038861847280257976054903569732561526167081339361799541336476559160368317896729073178384589680639671900977202194168647225871031411336429319536193471636533209717077448227988588565369208645296636077250268955505928362751121174096972998068410554359584866583291642136218231078990999448652468262416972035911852507045361090559
+G = 2
+X1 = 4316760088048858173826993660634587631078362099236037980378049883427191
+X2 = 3824157470039532100357278938102046076290169354062923298804711018976423
+Msg = 75dad921764736e389c4224daf7b278ec291e682044742e2e9c7a025b54dd62f
+Ciphertext = 57dfafa0d81ac3aaca2570ad13cccd127239f4ee04843bb738234588f0daea53ccd8af65a5a00ed19fbb6f2eb57779ff2e38e3d5d27986253a1193dabf14d2402e1a33527866fa21f23f7abbee5f454aad762fc90139c8377bf6cc77af7f982404baea5ca4831dd8ed28babf2d43b1f65eff42167b82f020dfd4928d8e96dcb7845ecf8f560fbbf5646fae5bc4eda6d978e5fb333843a1f4525cfbdde756842a1e353f4de1503738eec6c9d901a78cdefedf8daaa49631da674b44cab2193c778bf29766730a656b42e96f84698f77913c718067048263034cf2a2f34572ab662e4b1c5b04cd71183433c591abd5613820544d46f7462bea57e44f23ab06e0fbd02e423bcbfd01b23c12d332dbd5f4748de89e038bc0841f254509c4119eb62d80013e6b6ea63ef00904494377677137449fbbe79ebe11c57a32e88d7b44ced4614eef8a4f1c8f061f1f60413af7ed6eddd9120d650ac9fd8216b12a6af8f1594ab117fd3536f2a44f70654330809ddc
+
+Kdf = KDF1-18033(SHA-512)
+Mac = HMAC(SHA-512)
+MacKeyLen = 32
+Cipher = AES-256/CBC
+CipherKeyLen = 32
+IV = 00000000000000000000000000000000
+P = 32317006071311007300338913926423828248817941241140239112842009751400741706634354222619689417363569347117901737909704191754605873209195028853758986185622153212175412514901774520270235796078236248884246189477587641105928646099411723245426622522193230540919037680524235519125679715870117001058055877651038861847280257976054903569732561526167081339361799541336476559160368317896729073178384589680639671900977202194168647225871031411336429319536193471636533209717077448227988588565369208645296636077250268955505928362751121174096972998068410554359584866583291642136218231078990999448652468262416972035911852507045361090559
+G = 2
+X1 = 4316760088048858173826993660634587631078362099236037980378049883427191
+X2 = 3824157470039532100357278938102046076290169354062923298804711018976423
+Msg = 75dad921764736e389c4224daf7b278ec291e682044742e2e9c7a025b54dd62f
+Ciphertext = 57dfafa0d81ac3aaca2570ad13cccd127239f4ee04843bb738234588f0daea53ccd8af65a5a00ed19fbb6f2eb57779ff2e38e3d5d27986253a1193dabf14d2402e1a33527866fa21f23f7abbee5f454aad762fc90139c8377bf6cc77af7f982404baea5ca4831dd8ed28babf2d43b1f65eff42167b82f020dfd4928d8e96dcb7845ecf8f560fbbf5646fae5bc4eda6d978e5fb333843a1f4525cfbdde756842a1e353f4de1503738eec6c9d901a78cdefedf8daaa49631da674b44cab2193c778bf29766730a656b42e96f84698f77913c718067048263034cf2a2f34572ab662e4b1c5b04cd71183433c591abd5613820544d46f7462bea57e44f23ab06e0fbd02e423bcbfd01b23c12d332dbd5f4748de89e038bc0841f254509c4119eb62d80013e6b6ea63ef009044943776771378743bfaff20afd91f48a78f4af831e42335aff26ffa98c1bf74ef0e1437b6eba839de9dfca32869fa021fe19dbabbd1d6d3da10b1e4f434bf760da236666b10d
+
+Kdf = KDF1-18033(SHA-512)
+Mac = HMAC(SHA-512)
+MacKeyLen = 20
+Cipher = AES-256/CBC
+CipherKeyLen = 32
+IV = 00000000000000000000000000000000
+P = 32317006071311007300338913926423828248817941241140239112842009751400741706634354222619689417363569347117901737909704191754605873209195028853758986185622153212175412514901774520270235796078236248884246189477587641105928646099411723245426622522193230540919037680524235519125679715870117001058055877651038861847280257976054903569732561526167081339361799541336476559160368317896729073178384589680639671900977202194168647225871031411336429319536193471636533209717077448227988588565369208645296636077250268955505928362751121174096972998068410554359584866583291642136218231078990999448652468262416972035911852507045361090559
+G = 2
+X1 = 4316760088048858173826993660634587631078362099236037980378049883427191
+X2 = 3824157470039532100357278938102046076290169354062923298804711018976423
+Msg = 75dad921764736e389c4224daf7b278ec291e682044742e2e9c7a025b54dd62f
+Ciphertext = 57dfafa0d81ac3aaca2570ad13cccd127239f4ee04843bb738234588f0daea53ccd8af65a5a00ed19fbb6f2eb57779ff2e38e3d5d27986253a1193dabf14d2402e1a33527866fa21f23f7abbee5f454aad762fc90139c8377bf6cc77af7f982404baea5ca4831dd8ed28babf2d43b1f65eff42167b82f020dfd4928d8e96dcb7845ecf8f560fbbf5646fae5bc4eda6d978e5fb333843a1f4525cfbdde756842a1e353f4de1503738eec6c9d901a78cdefedf8daaa49631da674b44cab2193c778bf29766730a656b42e96f84698f77913c718067048263034cf2a2f34572ab662e4b1c5b04cd71183433c591abd5613820544d46f7462bea57e44f23ab06e0fbd02e423bcbfd01b23c12d332dbd5f4748de89e038bc0841f254509c4119eb62d80013e6b6ea63ef00904494377677137edf4f8a39d3d8c791b3945f242ef5f321ea69a270bc6c2b24a55f3e65b67db24b7e9a8a270eb3f175b49461982a2c2d53b48fd296818f696454d13c10c7b1cc6
+
+Kdf = KDF1-18033(SHA-512)
+Mac = HMAC(SHA-512)
+MacKeyLen = 64
+Cipher = AES-256/CBC
+CipherKeyLen = 32
+IV = 00112233445566778899aabbccddeeff
+P = 32317006071311007300338913926423828248817941241140239112842009751400741706634354222619689417363569347117901737909704191754605873209195028853758986185622153212175412514901774520270235796078236248884246189477587641105928646099411723245426622522193230540919037680524235519125679715870117001058055877651038861847280257976054903569732561526167081339361799541336476559160368317896729073178384589680639671900977202194168647225871031411336429319536193471636533209717077448227988588565369208645296636077250268955505928362751121174096972998068410554359584866583291642136218231078990999448652468262416972035911852507045361090559
+G = 2
+X1 = 4316760088048858173826993660634587631078362099236037980378049883427191
+X2 = 3824157470039532100357278938102046076290169354062923298804711018976423
+Msg = 75dad921764736e389c4224daf7b278ec291e682044742e2e9c7a025b54dd62f
+Ciphertext = 57dfafa0d81ac3aaca2570ad13cccd127239f4ee04843bb738234588f0daea53ccd8af65a5a00ed19fbb6f2eb57779ff2e38e3d5d27986253a1193dabf14d2402e1a33527866fa21f23f7abbee5f454aad762fc90139c8377bf6cc77af7f982404baea5ca4831dd8ed28babf2d43b1f65eff42167b82f020dfd4928d8e96dcb7845ecf8f560fbbf5646fae5bc4eda6d978e5fb333843a1f4525cfbdde756842a1e353f4de1503738eec6c9d901a78cdefedf8daaa49631da674b44cab2193c778bf29766730a656b42e96f84698f77913c718067048263034cf2a2f34572ab662e4b1c5b04cd71183433c591abd5613820544d46f7462bea57e44f23ab06e0fb8ab1751efd5cda04c715d94f0dc7f21058ddd90215a6dbb5f3029121c80ce39692acef02ecc5e5deb71352b45682de7ada1f4ec465be2f5fbe25776c3c03baa2c62cc3b44fa762798f3efb687a5281b7063fa71fdfc483e53dc0bfabe2853510fecb29b110b75d2292567eab1c86cb24
+
+Kdf = KDF1-18033(SHA-512)
+Mac = HMAC(SHA-512)
+MacKeyLen = 32
+Cipher = AES-256/CBC
+CipherKeyLen = 32
+IV = 00112233445566778899aabbccddeeff
+P = 32317006071311007300338913926423828248817941241140239112842009751400741706634354222619689417363569347117901737909704191754605873209195028853758986185622153212175412514901774520270235796078236248884246189477587641105928646099411723245426622522193230540919037680524235519125679715870117001058055877651038861847280257976054903569732561526167081339361799541336476559160368317896729073178384589680639671900977202194168647225871031411336429319536193471636533209717077448227988588565369208645296636077250268955505928362751121174096972998068410554359584866583291642136218231078990999448652468262416972035911852507045361090559
+G = 2
+X1 = 4316760088048858173826993660634587631078362099236037980378049883427191
+X2 = 3824157470039532100357278938102046076290169354062923298804711018976423
+Msg = 75dad921764736e389c4224daf7b278ec291e682044742e2e9c7a025b54dd62f
+Ciphertext = 57dfafa0d81ac3aaca2570ad13cccd127239f4ee04843bb738234588f0daea53ccd8af65a5a00ed19fbb6f2eb57779ff2e38e3d5d27986253a1193dabf14d2402e1a33527866fa21f23f7abbee5f454aad762fc90139c8377bf6cc77af7f982404baea5ca4831dd8ed28babf2d43b1f65eff42167b82f020dfd4928d8e96dcb7845ecf8f560fbbf5646fae5bc4eda6d978e5fb333843a1f4525cfbdde756842a1e353f4de1503738eec6c9d901a78cdefedf8daaa49631da674b44cab2193c778bf29766730a656b42e96f84698f77913c718067048263034cf2a2f34572ab662e4b1c5b04cd71183433c591abd5613820544d46f7462bea57e44f23ab06e0fb8ab1751efd5cda04c715d94f0dc7f21058ddd90215a6dbb5f3029121c80ce39692acef02ecc5e5deb71352b45682de7aeba22adf488a429ce9bff1b51a916e917fb39d0a4719a6d3eadbfa1f5dbf93ada69056d0ba459693c9329446ceed6ab09bbd73a4651faa9107f56d132dd62072
+
+Kdf = KDF1-18033(SHA-512)
+Mac = HMAC(SHA-512)
+MacKeyLen = 20
+Cipher = AES-256/CBC
+CipherKeyLen = 32
+IV = 00112233445566778899aabbccddeeff
+P = 32317006071311007300338913926423828248817941241140239112842009751400741706634354222619689417363569347117901737909704191754605873209195028853758986185622153212175412514901774520270235796078236248884246189477587641105928646099411723245426622522193230540919037680524235519125679715870117001058055877651038861847280257976054903569732561526167081339361799541336476559160368317896729073178384589680639671900977202194168647225871031411336429319536193471636533209717077448227988588565369208645296636077250268955505928362751121174096972998068410554359584866583291642136218231078990999448652468262416972035911852507045361090559
+G = 2
+X1 = 4316760088048858173826993660634587631078362099236037980378049883427191
+X2 = 3824157470039532100357278938102046076290169354062923298804711018976423
+Msg = 75dad921764736e389c4224daf7b278ec291e682044742e2e9c7a025b54dd62f
+Ciphertext = 57dfafa0d81ac3aaca2570ad13cccd127239f4ee04843bb738234588f0daea53ccd8af65a5a00ed19fbb6f2eb57779ff2e38e3d5d27986253a1193dabf14d2402e1a33527866fa21f23f7abbee5f454aad762fc90139c8377bf6cc77af7f982404baea5ca4831dd8ed28babf2d43b1f65eff42167b82f020dfd4928d8e96dcb7845ecf8f560fbbf5646fae5bc4eda6d978e5fb333843a1f4525cfbdde756842a1e353f4de1503738eec6c9d901a78cdefedf8daaa49631da674b44cab2193c778bf29766730a656b42e96f84698f77913c718067048263034cf2a2f34572ab662e4b1c5b04cd71183433c591abd5613820544d46f7462bea57e44f23ab06e0fb8ab1751efd5cda04c715d94f0dc7f21058ddd90215a6dbb5f3029121c80ce39692acef02ecc5e5deb71352b45682de7a21a5db0631ab9bf0f14e60f819a5bc7d2559531bce85fc466d9fdf6f3ce9cadaa60b5f833dc881deb143630b7e8a267a16144d926038ec3c2359b0f092935d22
+
+Kdf = KDF1-18033(SHA-256)
+Mac = HMAC(SHA-256)
+MacKeyLen = 32
+Cipher = AES-256/CBC
+CipherKeyLen = 32
+IV = 00000000000000000000000000000000
+P = 32317006071311007300338913926423828248817941241140239112842009751400741706634354222619689417363569347117901737909704191754605873209195028853758986185622153212175412514901774520270235796078236248884246189477587641105928646099411723245426622522193230540919037680524235519125679715870117001058055877651038861847280257976054903569732561526167081339361799541336476559160368317896729073178384589680639671900977202194168647225871031411336429319536193471636533209717077448227988588565369208645296636077250268955505928362751121174096972998068410554359584866583291642136218231078990999448652468262416972035911852507045361090559
+G = 2
+X1 = 4316760088048858173826993660634587631078362099236037980378049883427191
+X2 = 3824157470039532100357278938102046076290169354062923298804711018976423
+Msg = 75dad921764736e389c4224daf7b278ec291e682044742e2e9c7a025b54dd62f
+Ciphertext = 57dfafa0d81ac3aaca2570ad13cccd127239f4ee04843bb738234588f0daea53ccd8af65a5a00ed19fbb6f2eb57779ff2e38e3d5d27986253a1193dabf14d2402e1a33527866fa21f23f7abbee5f454aad762fc90139c8377bf6cc77af7f982404baea5ca4831dd8ed28babf2d43b1f65eff42167b82f020dfd4928d8e96dcb7845ecf8f560fbbf5646fae5bc4eda6d978e5fb333843a1f4525cfbdde756842a1e353f4de1503738eec6c9d901a78cdefedf8daaa49631da674b44cab2193c778bf29766730a656b42e96f84698f77913c718067048263034cf2a2f34572ab662e4b1c5b04cd71183433c591abd5613820544d46f7462bea57e44f23ab06e0fb20faa6b9b8e36197a44df7ee04a6eb517621c0c25b54004b8c18da9d307743e2f75e0a106b1cd8d275ed146f0ea2d66342511e50f37a91ad3eb5efce92a858a95458a9484f9a9c939bc8ab8a028bbf22
+
+Kdf = KDF1-18033(SHA-256)
+Mac = HMAC(SHA-256)
+MacKeyLen = 20
+Cipher = AES-256/CBC
+CipherKeyLen = 32
+IV = 00000000000000000000000000000000
+P = 32317006071311007300338913926423828248817941241140239112842009751400741706634354222619689417363569347117901737909704191754605873209195028853758986185622153212175412514901774520270235796078236248884246189477587641105928646099411723245426622522193230540919037680524235519125679715870117001058055877651038861847280257976054903569732561526167081339361799541336476559160368317896729073178384589680639671900977202194168647225871031411336429319536193471636533209717077448227988588565369208645296636077250268955505928362751121174096972998068410554359584866583291642136218231078990999448652468262416972035911852507045361090559
+G = 2
+X1 = 4316760088048858173826993660634587631078362099236037980378049883427191
+X2 = 3824157470039532100357278938102046076290169354062923298804711018976423
+Msg = 75dad921764736e389c4224daf7b278ec291e682044742e2e9c7a025b54dd62f
+Ciphertext = 57dfafa0d81ac3aaca2570ad13cccd127239f4ee04843bb738234588f0daea53ccd8af65a5a00ed19fbb6f2eb57779ff2e38e3d5d27986253a1193dabf14d2402e1a33527866fa21f23f7abbee5f454aad762fc90139c8377bf6cc77af7f982404baea5ca4831dd8ed28babf2d43b1f65eff42167b82f020dfd4928d8e96dcb7845ecf8f560fbbf5646fae5bc4eda6d978e5fb333843a1f4525cfbdde756842a1e353f4de1503738eec6c9d901a78cdefedf8daaa49631da674b44cab2193c778bf29766730a656b42e96f84698f77913c718067048263034cf2a2f34572ab662e4b1c5b04cd71183433c591abd5613820544d46f7462bea57e44f23ab06e0fb20faa6b9b8e36197a44df7ee04a6eb517621c0c25b54004b8c18da9d307743e2f75e0a106b1cd8d275ed146f0ea2d66355baba71e14d2826cf99292581db0e3f6356280965ebfa456093b75a50089f7c
+
+Kdf = KDF1-18033(SHA-256)
+Mac = HMAC(SHA-256)
+MacKeyLen = 16
+Cipher = AES-256/CBC
+CipherKeyLen = 32
+IV = 00000000000000000000000000000000
+P = 32317006071311007300338913926423828248817941241140239112842009751400741706634354222619689417363569347117901737909704191754605873209195028853758986185622153212175412514901774520270235796078236248884246189477587641105928646099411723245426622522193230540919037680524235519125679715870117001058055877651038861847280257976054903569732561526167081339361799541336476559160368317896729073178384589680639671900977202194168647225871031411336429319536193471636533209717077448227988588565369208645296636077250268955505928362751121174096972998068410554359584866583291642136218231078990999448652468262416972035911852507045361090559
+G = 2
+X1 = 4316760088048858173826993660634587631078362099236037980378049883427191
+X2 = 3824157470039532100357278938102046076290169354062923298804711018976423
+Msg = 75dad921764736e389c4224daf7b278ec291e682044742e2e9c7a025b54dd62f
+Ciphertext = 57dfafa0d81ac3aaca2570ad13cccd127239f4ee04843bb738234588f0daea53ccd8af65a5a00ed19fbb6f2eb57779ff2e38e3d5d27986253a1193dabf14d2402e1a33527866fa21f23f7abbee5f454aad762fc90139c8377bf6cc77af7f982404baea5ca4831dd8ed28babf2d43b1f65eff42167b82f020dfd4928d8e96dcb7845ecf8f560fbbf5646fae5bc4eda6d978e5fb333843a1f4525cfbdde756842a1e353f4de1503738eec6c9d901a78cdefedf8daaa49631da674b44cab2193c778bf29766730a656b42e96f84698f77913c718067048263034cf2a2f34572ab662e4b1c5b04cd71183433c591abd5613820544d46f7462bea57e44f23ab06e0fb20faa6b9b8e36197a44df7ee04a6eb517621c0c25b54004b8c18da9d307743e2f75e0a106b1cd8d275ed146f0ea2d663fa3df2c346fec36f0181aafdde052872c021aeae057298c72068ea9271d19a30
+
+Kdf = KDF1-18033(SHA-256)
+Mac = HMAC(SHA-256)
+MacKeyLen = 32
+Cipher = AES-256/CBC
+CipherKeyLen = 32
+IV = 00112233445566778899aabbccddeeff
+P = 32317006071311007300338913926423828248817941241140239112842009751400741706634354222619689417363569347117901737909704191754605873209195028853758986185622153212175412514901774520270235796078236248884246189477587641105928646099411723245426622522193230540919037680524235519125679715870117001058055877651038861847280257976054903569732561526167081339361799541336476559160368317896729073178384589680639671900977202194168647225871031411336429319536193471636533209717077448227988588565369208645296636077250268955505928362751121174096972998068410554359584866583291642136218231078990999448652468262416972035911852507045361090559
+G = 2
+X1 = 4316760088048858173826993660634587631078362099236037980378049883427191
+X2 = 3824157470039532100357278938102046076290169354062923298804711018976423
+Msg = 75dad921764736e389c4224daf7b278ec291e682044742e2e9c7a025b54dd62f
+Ciphertext = 57dfafa0d81ac3aaca2570ad13cccd127239f4ee04843bb738234588f0daea53ccd8af65a5a00ed19fbb6f2eb57779ff2e38e3d5d27986253a1193dabf14d2402e1a33527866fa21f23f7abbee5f454aad762fc90139c8377bf6cc77af7f982404baea5ca4831dd8ed28babf2d43b1f65eff42167b82f020dfd4928d8e96dcb7845ecf8f560fbbf5646fae5bc4eda6d978e5fb333843a1f4525cfbdde756842a1e353f4de1503738eec6c9d901a78cdefedf8daaa49631da674b44cab2193c778bf29766730a656b42e96f84698f77913c718067048263034cf2a2f34572ab662e4b1c5b04cd71183433c591abd5613820544d46f7462bea57e44f23ab06e0fb5905e1af473bff629d6559e6dfae76dd176135417ec1f8bd56da34e604f3cba3edfe626868e6a6f5706454cc808394ae979dbb099676e3e61f12de47d87eb2c68101edce237b18b3ba41eca6c8d4a2c6
+
+Kdf = KDF1-18033(SHA-256)
+Mac = HMAC(SHA-256)
+MacKeyLen = 20
+Cipher = AES-256/CBC
+CipherKeyLen = 32
+IV = 00112233445566778899aabbccddeeff
+P = 32317006071311007300338913926423828248817941241140239112842009751400741706634354222619689417363569347117901737909704191754605873209195028853758986185622153212175412514901774520270235796078236248884246189477587641105928646099411723245426622522193230540919037680524235519125679715870117001058055877651038861847280257976054903569732561526167081339361799541336476559160368317896729073178384589680639671900977202194168647225871031411336429319536193471636533209717077448227988588565369208645296636077250268955505928362751121174096972998068410554359584866583291642136218231078990999448652468262416972035911852507045361090559
+G = 2
+X1 = 4316760088048858173826993660634587631078362099236037980378049883427191
+X2 = 3824157470039532100357278938102046076290169354062923298804711018976423
+Msg = 75dad921764736e389c4224daf7b278ec291e682044742e2e9c7a025b54dd62f
+Ciphertext = 57dfafa0d81ac3aaca2570ad13cccd127239f4ee04843bb738234588f0daea53ccd8af65a5a00ed19fbb6f2eb57779ff2e38e3d5d27986253a1193dabf14d2402e1a33527866fa21f23f7abbee5f454aad762fc90139c8377bf6cc77af7f982404baea5ca4831dd8ed28babf2d43b1f65eff42167b82f020dfd4928d8e96dcb7845ecf8f560fbbf5646fae5bc4eda6d978e5fb333843a1f4525cfbdde756842a1e353f4de1503738eec6c9d901a78cdefedf8daaa49631da674b44cab2193c778bf29766730a656b42e96f84698f77913c718067048263034cf2a2f34572ab662e4b1c5b04cd71183433c591abd5613820544d46f7462bea57e44f23ab06e0fb5905e1af473bff629d6559e6dfae76dd176135417ec1f8bd56da34e604f3cba3edfe626868e6a6f5706454cc808394ae08f8d798a81ef521ab83d5d63127c8df21bbeb596ca63fe3789c28091805f8eb
+
+Kdf = KDF1-18033(SHA-256)
+Mac = HMAC(SHA-256)
+MacKeyLen = 16
+Cipher = AES-256/CBC
+CipherKeyLen = 32
+IV = 00112233445566778899aabbccddeeff
+P = 32317006071311007300338913926423828248817941241140239112842009751400741706634354222619689417363569347117901737909704191754605873209195028853758986185622153212175412514901774520270235796078236248884246189477587641105928646099411723245426622522193230540919037680524235519125679715870117001058055877651038861847280257976054903569732561526167081339361799541336476559160368317896729073178384589680639671900977202194168647225871031411336429319536193471636533209717077448227988588565369208645296636077250268955505928362751121174096972998068410554359584866583291642136218231078990999448652468262416972035911852507045361090559
+G = 2
+X1 = 4316760088048858173826993660634587631078362099236037980378049883427191
+X2 = 3824157470039532100357278938102046076290169354062923298804711018976423
+Msg = 75dad921764736e389c4224daf7b278ec291e682044742e2e9c7a025b54dd62f
+Ciphertext = 57dfafa0d81ac3aaca2570ad13cccd127239f4ee04843bb738234588f0daea53ccd8af65a5a00ed19fbb6f2eb57779ff2e38e3d5d27986253a1193dabf14d2402e1a33527866fa21f23f7abbee5f454aad762fc90139c8377bf6cc77af7f982404baea5ca4831dd8ed28babf2d43b1f65eff42167b82f020dfd4928d8e96dcb7845ecf8f560fbbf5646fae5bc4eda6d978e5fb333843a1f4525cfbdde756842a1e353f4de1503738eec6c9d901a78cdefedf8daaa49631da674b44cab2193c778bf29766730a656b42e96f84698f77913c718067048263034cf2a2f34572ab662e4b1c5b04cd71183433c591abd5613820544d46f7462bea57e44f23ab06e0fb5905e1af473bff629d6559e6dfae76dd176135417ec1f8bd56da34e604f3cba3edfe626868e6a6f5706454cc808394aeed35c9fcb24b2a440873264c97aadc860dc89e8b95a4e644c5ac2bb5f19c2c5e
+
+Kdf = KDF1-18033(SHA-1)
+Mac = HMAC(SHA-1)
+MacKeyLen = 20
+Cipher = AES-256/CBC
+CipherKeyLen = 32
+IV = 00000000000000000000000000000000
+P = 32317006071311007300338913926423828248817941241140239112842009751400741706634354222619689417363569347117901737909704191754605873209195028853758986185622153212175412514901774520270235796078236248884246189477587641105928646099411723245426622522193230540919037680524235519125679715870117001058055877651038861847280257976054903569732561526167081339361799541336476559160368317896729073178384589680639671900977202194168647225871031411336429319536193471636533209717077448227988588565369208645296636077250268955505928362751121174096972998068410554359584866583291642136218231078990999448652468262416972035911852507045361090559
+G = 2
+X1 = 4316760088048858173826993660634587631078362099236037980378049883427191
+X2 = 3824157470039532100357278938102046076290169354062923298804711018976423
+Msg = 75dad921764736e389c4224daf7b278ec291e682044742e2e9c7a025b54dd62f
+Ciphertext = 57dfafa0d81ac3aaca2570ad13cccd127239f4ee04843bb738234588f0daea53ccd8af65a5a00ed19fbb6f2eb57779ff2e38e3d5d27986253a1193dabf14d2402e1a33527866fa21f23f7abbee5f454aad762fc90139c8377bf6cc77af7f982404baea5ca4831dd8ed28babf2d43b1f65eff42167b82f020dfd4928d8e96dcb7845ecf8f560fbbf5646fae5bc4eda6d978e5fb333843a1f4525cfbdde756842a1e353f4de1503738eec6c9d901a78cdefedf8daaa49631da674b44cab2193c778bf29766730a656b42e96f84698f77913c718067048263034cf2a2f34572ab662e4b1c5b04cd71183433c591abd5613820544d46f7462bea57e44f23ab06e0fb780aefcb510dadc91fb23e93c1dc3ab67515904c394001d13c57cc4e8f14120d8b5d102f8a0af143ac4ae59d8358714e71a4b9ae7881296a1f8e4fd7695a9cdc00613360
+
+Kdf = KDF1-18033(SHA-1)
+Mac = HMAC(SHA-1)
+MacKeyLen = 16
+Cipher = AES-256/CBC
+CipherKeyLen = 32
+IV = 00000000000000000000000000000000
+P = 32317006071311007300338913926423828248817941241140239112842009751400741706634354222619689417363569347117901737909704191754605873209195028853758986185622153212175412514901774520270235796078236248884246189477587641105928646099411723245426622522193230540919037680524235519125679715870117001058055877651038861847280257976054903569732561526167081339361799541336476559160368317896729073178384589680639671900977202194168647225871031411336429319536193471636533209717077448227988588565369208645296636077250268955505928362751121174096972998068410554359584866583291642136218231078990999448652468262416972035911852507045361090559
+G = 2
+X1 = 4316760088048858173826993660634587631078362099236037980378049883427191
+X2 = 3824157470039532100357278938102046076290169354062923298804711018976423
+Msg = 75dad921764736e389c4224daf7b278ec291e682044742e2e9c7a025b54dd62f
+Ciphertext = 57dfafa0d81ac3aaca2570ad13cccd127239f4ee04843bb738234588f0daea53ccd8af65a5a00ed19fbb6f2eb57779ff2e38e3d5d27986253a1193dabf14d2402e1a33527866fa21f23f7abbee5f454aad762fc90139c8377bf6cc77af7f982404baea5ca4831dd8ed28babf2d43b1f65eff42167b82f020dfd4928d8e96dcb7845ecf8f560fbbf5646fae5bc4eda6d978e5fb333843a1f4525cfbdde756842a1e353f4de1503738eec6c9d901a78cdefedf8daaa49631da674b44cab2193c778bf29766730a656b42e96f84698f77913c718067048263034cf2a2f34572ab662e4b1c5b04cd71183433c591abd5613820544d46f7462bea57e44f23ab06e0fb780aefcb510dadc91fb23e93c1dc3ab67515904c394001d13c57cc4e8f14120d8b5d102f8a0af143ac4ae59d8358714e666ffa3f0881093199f6ab5e1f2bca9658b29114
+
+Kdf = KDF1-18033(SHA-1)
+Mac = HMAC(SHA-1)
+MacKeyLen = 20
+Cipher = AES-256/CBC
+CipherKeyLen = 32
+IV = 00112233445566778899aabbccddeeff
+P = 32317006071311007300338913926423828248817941241140239112842009751400741706634354222619689417363569347117901737909704191754605873209195028853758986185622153212175412514901774520270235796078236248884246189477587641105928646099411723245426622522193230540919037680524235519125679715870117001058055877651038861847280257976054903569732561526167081339361799541336476559160368317896729073178384589680639671900977202194168647225871031411336429319536193471636533209717077448227988588565369208645296636077250268955505928362751121174096972998068410554359584866583291642136218231078990999448652468262416972035911852507045361090559
+G = 2
+X1 = 4316760088048858173826993660634587631078362099236037980378049883427191
+X2 = 3824157470039532100357278938102046076290169354062923298804711018976423
+Msg = 75dad921764736e389c4224daf7b278ec291e682044742e2e9c7a025b54dd62f
+Ciphertext = 57dfafa0d81ac3aaca2570ad13cccd127239f4ee04843bb738234588f0daea53ccd8af65a5a00ed19fbb6f2eb57779ff2e38e3d5d27986253a1193dabf14d2402e1a33527866fa21f23f7abbee5f454aad762fc90139c8377bf6cc77af7f982404baea5ca4831dd8ed28babf2d43b1f65eff42167b82f020dfd4928d8e96dcb7845ecf8f560fbbf5646fae5bc4eda6d978e5fb333843a1f4525cfbdde756842a1e353f4de1503738eec6c9d901a78cdefedf8daaa49631da674b44cab2193c778bf29766730a656b42e96f84698f77913c718067048263034cf2a2f34572ab662e4b1c5b04cd71183433c591abd5613820544d46f7462bea57e44f23ab06e0fb79d5d8fcd4cec89c61a875f1f44b76f2c6561450ec419bce39d5c18a83174866408ddcc61780820295438b12371cb6b77aa52d217e6b8f9bc0c940eee9f18827bfc42958
+
+Kdf = KDF1-18033(SHA-1)
+Mac = HMAC(SHA-1)
+MacKeyLen = 16
+Cipher = AES-256/CBC
+CipherKeyLen = 32
+IV = 00112233445566778899aabbccddeeff
+P = 32317006071311007300338913926423828248817941241140239112842009751400741706634354222619689417363569347117901737909704191754605873209195028853758986185622153212175412514901774520270235796078236248884246189477587641105928646099411723245426622522193230540919037680524235519125679715870117001058055877651038861847280257976054903569732561526167081339361799541336476559160368317896729073178384589680639671900977202194168647225871031411336429319536193471636533209717077448227988588565369208645296636077250268955505928362751121174096972998068410554359584866583291642136218231078990999448652468262416972035911852507045361090559
+G = 2
+X1 = 4316760088048858173826993660634587631078362099236037980378049883427191
+X2 = 3824157470039532100357278938102046076290169354062923298804711018976423
+Msg = 75dad921764736e389c4224daf7b278ec291e682044742e2e9c7a025b54dd62f
+Ciphertext = 57dfafa0d81ac3aaca2570ad13cccd127239f4ee04843bb738234588f0daea53ccd8af65a5a00ed19fbb6f2eb57779ff2e38e3d5d27986253a1193dabf14d2402e1a33527866fa21f23f7abbee5f454aad762fc90139c8377bf6cc77af7f982404baea5ca4831dd8ed28babf2d43b1f65eff42167b82f020dfd4928d8e96dcb7845ecf8f560fbbf5646fae5bc4eda6d978e5fb333843a1f4525cfbdde756842a1e353f4de1503738eec6c9d901a78cdefedf8daaa49631da674b44cab2193c778bf29766730a656b42e96f84698f77913c718067048263034cf2a2f34572ab662e4b1c5b04cd71183433c591abd5613820544d46f7462bea57e44f23ab06e0fb79d5d8fcd4cec89c61a875f1f44b76f2c6561450ec419bce39d5c18a83174866408ddcc61780820295438b12371cb6b76f5a4cb193769a1cc3cabac1ef709ad5cd903113
+
+Kdf = KDF1-18033(SHA-512)
+Mac = CMAC(AES-256)
+MacKeyLen = 32
+Cipher = AES-256/CBC
+CipherKeyLen = 32
+IV = 00112233445566778899aabbccddeeff
+P = 32317006071311007300338913926423828248817941241140239112842009751400741706634354222619689417363569347117901737909704191754605873209195028853758986185622153212175412514901774520270235796078236248884246189477587641105928646099411723245426622522193230540919037680524235519125679715870117001058055877651038861847280257976054903569732561526167081339361799541336476559160368317896729073178384589680639671900977202194168647225871031411336429319536193471636533209717077448227988588565369208645296636077250268955505928362751121174096972998068410554359584866583291642136218231078990999448652468262416972035911852507045361090559
+G = 2
+X1 = 4316760088048858173826993660634587631078362099236037980378049883427191
+X2 = 3824157470039532100357278938102046076290169354062923298804711018976423
+Msg = 75dad921764736e389c4224daf7b278ec291e682044742e2e9c7a025b54dd62f
+Ciphertext = 57dfafa0d81ac3aaca2570ad13cccd127239f4ee04843bb738234588f0daea53ccd8af65a5a00ed19fbb6f2eb57779ff2e38e3d5d27986253a1193dabf14d2402e1a33527866fa21f23f7abbee5f454aad762fc90139c8377bf6cc77af7f982404baea5ca4831dd8ed28babf2d43b1f65eff42167b82f020dfd4928d8e96dcb7845ecf8f560fbbf5646fae5bc4eda6d978e5fb333843a1f4525cfbdde756842a1e353f4de1503738eec6c9d901a78cdefedf8daaa49631da674b44cab2193c778bf29766730a656b42e96f84698f77913c718067048263034cf2a2f34572ab662e4b1c5b04cd71183433c591abd5613820544d46f7462bea57e44f23ab06e0fb8ab1751efd5cda04c715d94f0dc7f21058ddd90215a6dbb5f3029121c80ce39692acef02ecc5e5deb71352b45682de7a0b65f9aea49d094a71b64333211e3349
+
+Kdf = KDF1-18033(SHA-512)
+Mac = CMAC(AES-256)
+MacKeyLen = 32
+Cipher = AES-256/CBC
+CipherKeyLen = 32
+IV = 00000000000000000000000000000000
+P = 32317006071311007300338913926423828248817941241140239112842009751400741706634354222619689417363569347117901737909704191754605873209195028853758986185622153212175412514901774520270235796078236248884246189477587641105928646099411723245426622522193230540919037680524235519125679715870117001058055877651038861847280257976054903569732561526167081339361799541336476559160368317896729073178384589680639671900977202194168647225871031411336429319536193471636533209717077448227988588565369208645296636077250268955505928362751121174096972998068410554359584866583291642136218231078990999448652468262416972035911852507045361090559
+G = 2
+X1 = 4316760088048858173826993660634587631078362099236037980378049883427191
+X2 = 3824157470039532100357278938102046076290169354062923298804711018976423
+Msg = 75dad921764736e389c4224daf7b278ec291e682044742e2e9c7a025b54dd62f
+Ciphertext = 57dfafa0d81ac3aaca2570ad13cccd127239f4ee04843bb738234588f0daea53ccd8af65a5a00ed19fbb6f2eb57779ff2e38e3d5d27986253a1193dabf14d2402e1a33527866fa21f23f7abbee5f454aad762fc90139c8377bf6cc77af7f982404baea5ca4831dd8ed28babf2d43b1f65eff42167b82f020dfd4928d8e96dcb7845ecf8f560fbbf5646fae5bc4eda6d978e5fb333843a1f4525cfbdde756842a1e353f4de1503738eec6c9d901a78cdefedf8daaa49631da674b44cab2193c778bf29766730a656b42e96f84698f77913c718067048263034cf2a2f34572ab662e4b1c5b04cd71183433c591abd5613820544d46f7462bea57e44f23ab06e0fbd02e423bcbfd01b23c12d332dbd5f4748de89e038bc0841f254509c4119eb62d80013e6b6ea63ef00904494377677137c1b3b063d80fea08ce2cb5d846b4d6bc
+
+Kdf = KDF1-18033(SHA-256)
+Mac = CMAC(AES-256)
+MacKeyLen = 32
+Cipher = AES-256/CBC
+CipherKeyLen = 32
+IV = 00112233445566778899aabbccddeeff
+P = 32317006071311007300338913926423828248817941241140239112842009751400741706634354222619689417363569347117901737909704191754605873209195028853758986185622153212175412514901774520270235796078236248884246189477587641105928646099411723245426622522193230540919037680524235519125679715870117001058055877651038861847280257976054903569732561526167081339361799541336476559160368317896729073178384589680639671900977202194168647225871031411336429319536193471636533209717077448227988588565369208645296636077250268955505928362751121174096972998068410554359584866583291642136218231078990999448652468262416972035911852507045361090559
+G = 2
+X1 = 4316760088048858173826993660634587631078362099236037980378049883427191
+X2 = 3824157470039532100357278938102046076290169354062923298804711018976423
+Msg = 75dad921764736e389c4224daf7b278ec291e682044742e2e9c7a025b54dd62f
+Ciphertext = 57dfafa0d81ac3aaca2570ad13cccd127239f4ee04843bb738234588f0daea53ccd8af65a5a00ed19fbb6f2eb57779ff2e38e3d5d27986253a1193dabf14d2402e1a33527866fa21f23f7abbee5f454aad762fc90139c8377bf6cc77af7f982404baea5ca4831dd8ed28babf2d43b1f65eff42167b82f020dfd4928d8e96dcb7845ecf8f560fbbf5646fae5bc4eda6d978e5fb333843a1f4525cfbdde756842a1e353f4de1503738eec6c9d901a78cdefedf8daaa49631da674b44cab2193c778bf29766730a656b42e96f84698f77913c718067048263034cf2a2f34572ab662e4b1c5b04cd71183433c591abd5613820544d46f7462bea57e44f23ab06e0fb5905e1af473bff629d6559e6dfae76dd176135417ec1f8bd56da34e604f3cba3edfe626868e6a6f5706454cc808394aef9fe22486b2f76c889d1d4d4903128f2
+
+Kdf = KDF1-18033(SHA-256)
+Mac = CMAC(AES-256)
+MacKeyLen = 32
+Cipher = AES-256/CBC
+CipherKeyLen = 32
+IV = 00000000000000000000000000000000
+P = 32317006071311007300338913926423828248817941241140239112842009751400741706634354222619689417363569347117901737909704191754605873209195028853758986185622153212175412514901774520270235796078236248884246189477587641105928646099411723245426622522193230540919037680524235519125679715870117001058055877651038861847280257976054903569732561526167081339361799541336476559160368317896729073178384589680639671900977202194168647225871031411336429319536193471636533209717077448227988588565369208645296636077250268955505928362751121174096972998068410554359584866583291642136218231078990999448652468262416972035911852507045361090559
+G = 2
+X1 = 4316760088048858173826993660634587631078362099236037980378049883427191
+X2 = 3824157470039532100357278938102046076290169354062923298804711018976423
+Msg = 75dad921764736e389c4224daf7b278ec291e682044742e2e9c7a025b54dd62f
+Ciphertext = 57dfafa0d81ac3aaca2570ad13cccd127239f4ee04843bb738234588f0daea53ccd8af65a5a00ed19fbb6f2eb57779ff2e38e3d5d27986253a1193dabf14d2402e1a33527866fa21f23f7abbee5f454aad762fc90139c8377bf6cc77af7f982404baea5ca4831dd8ed28babf2d43b1f65eff42167b82f020dfd4928d8e96dcb7845ecf8f560fbbf5646fae5bc4eda6d978e5fb333843a1f4525cfbdde756842a1e353f4de1503738eec6c9d901a78cdefedf8daaa49631da674b44cab2193c778bf29766730a656b42e96f84698f77913c718067048263034cf2a2f34572ab662e4b1c5b04cd71183433c591abd5613820544d46f7462bea57e44f23ab06e0fb20faa6b9b8e36197a44df7ee04a6eb517621c0c25b54004b8c18da9d307743e2f75e0a106b1cd8d275ed146f0ea2d6635d54b68cd4f7e34845f8a658b2a1cc80
+
+Kdf = KDF1-18033(SHA-1)
+Mac = CMAC(AES-256)
+MacKeyLen = 32
+Cipher = AES-256/CBC
+CipherKeyLen = 32
+IV = 00112233445566778899aabbccddeeff
+P = 32317006071311007300338913926423828248817941241140239112842009751400741706634354222619689417363569347117901737909704191754605873209195028853758986185622153212175412514901774520270235796078236248884246189477587641105928646099411723245426622522193230540919037680524235519125679715870117001058055877651038861847280257976054903569732561526167081339361799541336476559160368317896729073178384589680639671900977202194168647225871031411336429319536193471636533209717077448227988588565369208645296636077250268955505928362751121174096972998068410554359584866583291642136218231078990999448652468262416972035911852507045361090559
+G = 2
+X1 = 4316760088048858173826993660634587631078362099236037980378049883427191
+X2 = 3824157470039532100357278938102046076290169354062923298804711018976423
+Msg = 75dad921764736e389c4224daf7b278ec291e682044742e2e9c7a025b54dd62f
+Ciphertext = 57dfafa0d81ac3aaca2570ad13cccd127239f4ee04843bb738234588f0daea53ccd8af65a5a00ed19fbb6f2eb57779ff2e38e3d5d27986253a1193dabf14d2402e1a33527866fa21f23f7abbee5f454aad762fc90139c8377bf6cc77af7f982404baea5ca4831dd8ed28babf2d43b1f65eff42167b82f020dfd4928d8e96dcb7845ecf8f560fbbf5646fae5bc4eda6d978e5fb333843a1f4525cfbdde756842a1e353f4de1503738eec6c9d901a78cdefedf8daaa49631da674b44cab2193c778bf29766730a656b42e96f84698f77913c718067048263034cf2a2f34572ab662e4b1c5b04cd71183433c591abd5613820544d46f7462bea57e44f23ab06e0fb79d5d8fcd4cec89c61a875f1f44b76f2c6561450ec419bce39d5c18a83174866408ddcc61780820295438b12371cb6b7846bbcb1320b46d3857d683c68754868
+
+Kdf = KDF1-18033(SHA-1)
+Mac = CMAC(AES-256)
+MacKeyLen = 32
+Cipher = AES-256/CBC
+CipherKeyLen = 32
+IV = 00000000000000000000000000000000
+P = 32317006071311007300338913926423828248817941241140239112842009751400741706634354222619689417363569347117901737909704191754605873209195028853758986185622153212175412514901774520270235796078236248884246189477587641105928646099411723245426622522193230540919037680524235519125679715870117001058055877651038861847280257976054903569732561526167081339361799541336476559160368317896729073178384589680639671900977202194168647225871031411336429319536193471636533209717077448227988588565369208645296636077250268955505928362751121174096972998068410554359584866583291642136218231078990999448652468262416972035911852507045361090559
+G = 2
+X1 = 4316760088048858173826993660634587631078362099236037980378049883427191
+X2 = 3824157470039532100357278938102046076290169354062923298804711018976423
+Msg = 75dad921764736e389c4224daf7b278ec291e682044742e2e9c7a025b54dd62f
+Ciphertext = 57dfafa0d81ac3aaca2570ad13cccd127239f4ee04843bb738234588f0daea53ccd8af65a5a00ed19fbb6f2eb57779ff2e38e3d5d27986253a1193dabf14d2402e1a33527866fa21f23f7abbee5f454aad762fc90139c8377bf6cc77af7f982404baea5ca4831dd8ed28babf2d43b1f65eff42167b82f020dfd4928d8e96dcb7845ecf8f560fbbf5646fae5bc4eda6d978e5fb333843a1f4525cfbdde756842a1e353f4de1503738eec6c9d901a78cdefedf8daaa49631da674b44cab2193c778bf29766730a656b42e96f84698f77913c718067048263034cf2a2f34572ab662e4b1c5b04cd71183433c591abd5613820544d46f7462bea57e44f23ab06e0fb780aefcb510dadc91fb23e93c1dc3ab67515904c394001d13c57cc4e8f14120d8b5d102f8a0af143ac4ae59d8358714e63cd5edcce32a71dfa645223fdc8249d
+
+########### Stream mode (XOR enc/dec) ###########
+
+#public static void main(String[] args) throws InvalidCipherTextException {
+# // 2048-bit MODP Group. RFC3526
+# BigInteger g = new BigInteger( "2", 10 );
+# BigInteger p = new BigInteger( "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A0879"
+# + "8E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED"
+# + "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F"
+# + "83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B"
+# + "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA0510"
+# + "15728E5A8AACAA68FFFFFFFFFFFFFFFF", 16 );
+#
+# DHParameters dhParams = new DHParameters( p, g );
+#
+# // alice priv key
+# BigInteger xAlice = new BigInteger( "A01E167DE1013D6859E6CB068B7BF272C1D49DC764AD7676BFA0D85177", 16 );
+# DHPrivateKeyParameters alicePriv = new DHPrivateKeyParameters( xAlice, dhParams );
+#
+# // alice pub key
+# BigInteger yAlice = g.modPow(xAlice, p);
+# DHPublicKeyParameters alicePub = new DHPublicKeyParameters( yAlice, dhParams );
+#
+# // bob priv key
+# BigInteger xBob = new BigInteger( "8DD88BDC19AC1403A3FC3A0FC63D360F1062E3494177DC27F7EBCBD4A7", 16 );
+#
+# // bob pub key
+# BigInteger yBob = g.modPow(xBob, p);
+# DHPublicKeyParameters bobPub = new DHPublicKeyParameters( yBob, dhParams );
+#
+# // DLIES
+# byte[] d = new byte[ 0 ]; // the derivation parameter for the KDF function
+# byte[] e = new byte[ 0 ]; // the encoding parameter for the KDF function
+# int macKeySize = 160;
+# int cipherKeySize = 256;
+# byte[] iv = new byte[ 16 ];
+# CipherParameters cipherParams = new ParametersWithIV( new IESWithCipherParameters( d, e, macKeySize, cipherKeySize ), iv );
+#
+# IESEngine dlies =
+# new IESEngine( new DHBasicAgreement(), new KDF2BytesGenerator( new SHA256Digest() ), new HMac( new SHA256Digest() ) );
+# dlies.init( true, alicePriv, bobPub, cipherParams );
+#
+# byte[] message = Hex.decode( "00" );
+# byte[] result = dlies.processBlock( message, 0, message.length );
+#
+# byte[] ephPublicKey = alicePub.getY().toByteArray();
+# byte[] out = Arrays.concatenate( ephPublicKey, result );
+#
+# System.out.println( Hex.toHexString( out ) );
+# }
+
+####### KDF2
+
+Kdf = KDF2(SHA-512)
+Mac = HMAC(SHA-512)
+MacKeyLen = 64
+P = 32317006071311007300338913926423828248817941241140239112842009751400741706634354222619689417363569347117901737909704191754605873209195028853758986185622153212175412514901774520270235796078236248884246189477587641105928646099411723245426622522193230540919037680524235519125679715870117001058055877651038861847280257976054903569732561526167081339361799541336476559160368317896729073178384589680639671900977202194168647225871031411336429319536193471636533209717077448227988588565369208645296636077250268955505928362751121174096972998068410554359584866583291642136218231078990999448652468262416972035911852507045361090559
+G = 2
+X1 = 4316760088048858173826993660634587631078362099236037980378049883427191
+X2 = 3824157470039532100357278938102046076290169354062923298804711018976423
+Msg = 75dad921764736e389c4224daf7b278ec291e682044742e2e9c7a025b54dd62f
+Ciphertext = 57dfafa0d81ac3aaca2570ad13cccd127239f4ee04843bb738234588f0daea53ccd8af65a5a00ed19fbb6f2eb57779ff2e38e3d5d27986253a1193dabf14d2402e1a33527866fa21f23f7abbee5f454aad762fc90139c8377bf6cc77af7f982404baea5ca4831dd8ed28babf2d43b1f65eff42167b82f020dfd4928d8e96dcb7845ecf8f560fbbf5646fae5bc4eda6d978e5fb333843a1f4525cfbdde756842a1e353f4de1503738eec6c9d901a78cdefedf8daaa49631da674b44cab2193c778bf29766730a656b42e96f84698f77913c718067048263034cf2a2f34572ab662e4b1c5b04cd71183433c591abd5613820544d46f7462bea57e44f23ab06e0fb9b311515aa49918497c0c52f8c09e2cf6b3bc0343131a552b3d72ec4ee73f9628310a5d278a69c52f5a76c68031365e2504ef4abfa6e105f359e6d57c60a5beaf94a156544baba53139a3e90dd6218e504e58e1c8992df4565e68ec611c286bd
+
+Kdf = KDF2(SHA-512)
+Mac = HMAC(SHA-512)
+MacKeyLen = 32
+P = 32317006071311007300338913926423828248817941241140239112842009751400741706634354222619689417363569347117901737909704191754605873209195028853758986185622153212175412514901774520270235796078236248884246189477587641105928646099411723245426622522193230540919037680524235519125679715870117001058055877651038861847280257976054903569732561526167081339361799541336476559160368317896729073178384589680639671900977202194168647225871031411336429319536193471636533209717077448227988588565369208645296636077250268955505928362751121174096972998068410554359584866583291642136218231078990999448652468262416972035911852507045361090559
+G = 2
+X1 = 4316760088048858173826993660634587631078362099236037980378049883427191
+X2 = 3824157470039532100357278938102046076290169354062923298804711018976423
+Msg = 75dad921764736e389c4224daf7b278ec291e682044742e2e9c7a025b54dd62f
+Ciphertext = 57dfafa0d81ac3aaca2570ad13cccd127239f4ee04843bb738234588f0daea53ccd8af65a5a00ed19fbb6f2eb57779ff2e38e3d5d27986253a1193dabf14d2402e1a33527866fa21f23f7abbee5f454aad762fc90139c8377bf6cc77af7f982404baea5ca4831dd8ed28babf2d43b1f65eff42167b82f020dfd4928d8e96dcb7845ecf8f560fbbf5646fae5bc4eda6d978e5fb333843a1f4525cfbdde756842a1e353f4de1503738eec6c9d901a78cdefedf8daaa49631da674b44cab2193c778bf29766730a656b42e96f84698f77913c718067048263034cf2a2f34572ab662e4b1c5b04cd71183433c591abd5613820544d46f7462bea57e44f23ab06e0fb9b311515aa49918497c0c52f8c09e2cf6b3bc0343131a552b3d72ec4ee73f962baa771f5b54bef678412dfd3ea7380a42014b50aec4cc55d841b2ae20a168b3d5e51da011736d60e6ad446adc72f60e41f7f25c9d2e76badc473c110b7fc67b8
+
+Kdf = KDF2(SHA-512)
+Mac = HMAC(SHA-512)
+MacKeyLen = 20
+P = 32317006071311007300338913926423828248817941241140239112842009751400741706634354222619689417363569347117901737909704191754605873209195028853758986185622153212175412514901774520270235796078236248884246189477587641105928646099411723245426622522193230540919037680524235519125679715870117001058055877651038861847280257976054903569732561526167081339361799541336476559160368317896729073178384589680639671900977202194168647225871031411336429319536193471636533209717077448227988588565369208645296636077250268955505928362751121174096972998068410554359584866583291642136218231078990999448652468262416972035911852507045361090559
+G = 2
+X1 = 4316760088048858173826993660634587631078362099236037980378049883427191
+X2 = 3824157470039532100357278938102046076290169354062923298804711018976423
+Msg = 75dad921764736e389c4224daf7b278ec291e682044742e2e9c7a025b54dd62f
+Ciphertext = 57dfafa0d81ac3aaca2570ad13cccd127239f4ee04843bb738234588f0daea53ccd8af65a5a00ed19fbb6f2eb57779ff2e38e3d5d27986253a1193dabf14d2402e1a33527866fa21f23f7abbee5f454aad762fc90139c8377bf6cc77af7f982404baea5ca4831dd8ed28babf2d43b1f65eff42167b82f020dfd4928d8e96dcb7845ecf8f560fbbf5646fae5bc4eda6d978e5fb333843a1f4525cfbdde756842a1e353f4de1503738eec6c9d901a78cdefedf8daaa49631da674b44cab2193c778bf29766730a656b42e96f84698f77913c718067048263034cf2a2f34572ab662e4b1c5b04cd71183433c591abd5613820544d46f7462bea57e44f23ab06e0fb9b311515aa49918497c0c52f8c09e2cf6b3bc0343131a552b3d72ec4ee73f96262aa912053ba6ece87a75b8e2c1cf4fc49c5b03f7c433feaf8386ccc44e48375dc7d2a6fa59403a0e44fc268e7fb88eaa9faa66f120ca4f133631f5aace793e1
+
+Kdf = KDF2(SHA-256)
+Mac = HMAC(SHA-256)
+MacKeyLen = 32
+P = 32317006071311007300338913926423828248817941241140239112842009751400741706634354222619689417363569347117901737909704191754605873209195028853758986185622153212175412514901774520270235796078236248884246189477587641105928646099411723245426622522193230540919037680524235519125679715870117001058055877651038861847280257976054903569732561526167081339361799541336476559160368317896729073178384589680639671900977202194168647225871031411336429319536193471636533209717077448227988588565369208645296636077250268955505928362751121174096972998068410554359584866583291642136218231078990999448652468262416972035911852507045361090559
+G = 2
+X1 = 4316760088048858173826993660634587631078362099236037980378049883427191
+X2 = 3824157470039532100357278938102046076290169354062923298804711018976423
+Msg = 75dad921764736e389c4224daf7b278ec291e682044742e2e9c7a025b54dd62f
+Ciphertext = 57dfafa0d81ac3aaca2570ad13cccd127239f4ee04843bb738234588f0daea53ccd8af65a5a00ed19fbb6f2eb57779ff2e38e3d5d27986253a1193dabf14d2402e1a33527866fa21f23f7abbee5f454aad762fc90139c8377bf6cc77af7f982404baea5ca4831dd8ed28babf2d43b1f65eff42167b82f020dfd4928d8e96dcb7845ecf8f560fbbf5646fae5bc4eda6d978e5fb333843a1f4525cfbdde756842a1e353f4de1503738eec6c9d901a78cdefedf8daaa49631da674b44cab2193c778bf29766730a656b42e96f84698f77913c718067048263034cf2a2f34572ab662e4b1c5b04cd71183433c591abd5613820544d46f7462bea57e44f23ab06e0fbfdeb30b4378e3a6583da338d50cc23086dc8c3b33bc8e6d5612a44a2e1f0c5cbb8dbdb9d5c1e326f78df5beb66336ce5d95cd9f7cf349218874524519c2b5977
+
+Kdf = KDF2(SHA-256)
+Mac = HMAC(SHA-256)
+MacKeyLen = 20
+P = 32317006071311007300338913926423828248817941241140239112842009751400741706634354222619689417363569347117901737909704191754605873209195028853758986185622153212175412514901774520270235796078236248884246189477587641105928646099411723245426622522193230540919037680524235519125679715870117001058055877651038861847280257976054903569732561526167081339361799541336476559160368317896729073178384589680639671900977202194168647225871031411336429319536193471636533209717077448227988588565369208645296636077250268955505928362751121174096972998068410554359584866583291642136218231078990999448652468262416972035911852507045361090559
+G = 2
+X1 = 4316760088048858173826993660634587631078362099236037980378049883427191
+X2 = 3824157470039532100357278938102046076290169354062923298804711018976423
+Msg = 75dad921764736e389c4224daf7b278ec291e682044742e2e9c7a025b54dd62f
+Ciphertext = 57dfafa0d81ac3aaca2570ad13cccd127239f4ee04843bb738234588f0daea53ccd8af65a5a00ed19fbb6f2eb57779ff2e38e3d5d27986253a1193dabf14d2402e1a33527866fa21f23f7abbee5f454aad762fc90139c8377bf6cc77af7f982404baea5ca4831dd8ed28babf2d43b1f65eff42167b82f020dfd4928d8e96dcb7845ecf8f560fbbf5646fae5bc4eda6d978e5fb333843a1f4525cfbdde756842a1e353f4de1503738eec6c9d901a78cdefedf8daaa49631da674b44cab2193c778bf29766730a656b42e96f84698f77913c718067048263034cf2a2f34572ab662e4b1c5b04cd71183433c591abd5613820544d46f7462bea57e44f23ab06e0fbfdeb30b4378e3a6583da338d50cc23086dc8c3b33bc8e6d5612a44a2e1f0c5cbf1a5cfd4cf6a4a507d8151956d5573f94713d848517c37657f9d278b0c1f927e
+
+Kdf = KDF2(SHA-256)
+Mac = HMAC(SHA-256)
+MacKeyLen = 16
+P = 32317006071311007300338913926423828248817941241140239112842009751400741706634354222619689417363569347117901737909704191754605873209195028853758986185622153212175412514901774520270235796078236248884246189477587641105928646099411723245426622522193230540919037680524235519125679715870117001058055877651038861847280257976054903569732561526167081339361799541336476559160368317896729073178384589680639671900977202194168647225871031411336429319536193471636533209717077448227988588565369208645296636077250268955505928362751121174096972998068410554359584866583291642136218231078990999448652468262416972035911852507045361090559
+G = 2
+X1 = 4316760088048858173826993660634587631078362099236037980378049883427191
+X2 = 3824157470039532100357278938102046076290169354062923298804711018976423
+Msg = 75dad921764736e389c4224daf7b278ec291e682044742e2e9c7a025b54dd62f
+Ciphertext = 57dfafa0d81ac3aaca2570ad13cccd127239f4ee04843bb738234588f0daea53ccd8af65a5a00ed19fbb6f2eb57779ff2e38e3d5d27986253a1193dabf14d2402e1a33527866fa21f23f7abbee5f454aad762fc90139c8377bf6cc77af7f982404baea5ca4831dd8ed28babf2d43b1f65eff42167b82f020dfd4928d8e96dcb7845ecf8f560fbbf5646fae5bc4eda6d978e5fb333843a1f4525cfbdde756842a1e353f4de1503738eec6c9d901a78cdefedf8daaa49631da674b44cab2193c778bf29766730a656b42e96f84698f77913c718067048263034cf2a2f34572ab662e4b1c5b04cd71183433c591abd5613820544d46f7462bea57e44f23ab06e0fbfdeb30b4378e3a6583da338d50cc23086dc8c3b33bc8e6d5612a44a2e1f0c5cb0bdbd16fedfb41e28e6e52c6fc073a7f51d2951976602430a4788d9dcf94f40e
+
+Kdf = KDF2(SHA-1)
+Mac = HMAC(SHA-1)
+MacKeyLen = 20
+P = 32317006071311007300338913926423828248817941241140239112842009751400741706634354222619689417363569347117901737909704191754605873209195028853758986185622153212175412514901774520270235796078236248884246189477587641105928646099411723245426622522193230540919037680524235519125679715870117001058055877651038861847280257976054903569732561526167081339361799541336476559160368317896729073178384589680639671900977202194168647225871031411336429319536193471636533209717077448227988588565369208645296636077250268955505928362751121174096972998068410554359584866583291642136218231078990999448652468262416972035911852507045361090559
+G = 2
+X1 = 4316760088048858173826993660634587631078362099236037980378049883427191
+X2 = 3824157470039532100357278938102046076290169354062923298804711018976423
+Msg = 75dad921764736e389c4224daf7b278ec291e682044742e2e9c7a025b54dd62f
+Ciphertext = 57dfafa0d81ac3aaca2570ad13cccd127239f4ee04843bb738234588f0daea53ccd8af65a5a00ed19fbb6f2eb57779ff2e38e3d5d27986253a1193dabf14d2402e1a33527866fa21f23f7abbee5f454aad762fc90139c8377bf6cc77af7f982404baea5ca4831dd8ed28babf2d43b1f65eff42167b82f020dfd4928d8e96dcb7845ecf8f560fbbf5646fae5bc4eda6d978e5fb333843a1f4525cfbdde756842a1e353f4de1503738eec6c9d901a78cdefedf8daaa49631da674b44cab2193c778bf29766730a656b42e96f84698f77913c718067048263034cf2a2f34572ab662e4b1c5b04cd71183433c591abd5613820544d46f7462bea57e44f23ab06e0fb070d66995d816ed81c1877398dbc56744848d0af4b63c374925eeeab5d99f55c3efe5a434f886c377d175a52798bc6edbb968932
+
+Kdf = KDF2(SHA-1)
+Mac = HMAC(SHA-1)
+MacKeyLen = 16
+P = 32317006071311007300338913926423828248817941241140239112842009751400741706634354222619689417363569347117901737909704191754605873209195028853758986185622153212175412514901774520270235796078236248884246189477587641105928646099411723245426622522193230540919037680524235519125679715870117001058055877651038861847280257976054903569732561526167081339361799541336476559160368317896729073178384589680639671900977202194168647225871031411336429319536193471636533209717077448227988588565369208645296636077250268955505928362751121174096972998068410554359584866583291642136218231078990999448652468262416972035911852507045361090559
+G = 2
+X1 = 4316760088048858173826993660634587631078362099236037980378049883427191
+X2 = 3824157470039532100357278938102046076290169354062923298804711018976423
+Msg = 75dad921764736e389c4224daf7b278ec291e682044742e2e9c7a025b54dd62f
+Ciphertext = 57dfafa0d81ac3aaca2570ad13cccd127239f4ee04843bb738234588f0daea53ccd8af65a5a00ed19fbb6f2eb57779ff2e38e3d5d27986253a1193dabf14d2402e1a33527866fa21f23f7abbee5f454aad762fc90139c8377bf6cc77af7f982404baea5ca4831dd8ed28babf2d43b1f65eff42167b82f020dfd4928d8e96dcb7845ecf8f560fbbf5646fae5bc4eda6d978e5fb333843a1f4525cfbdde756842a1e353f4de1503738eec6c9d901a78cdefedf8daaa49631da674b44cab2193c778bf29766730a656b42e96f84698f77913c718067048263034cf2a2f34572ab662e4b1c5b04cd71183433c591abd5613820544d46f7462bea57e44f23ab06e0fb070d66995d816ed81c1877398dbc56744848d0af4b63c374925eeeab5d99f55cda95ccfde6fdb8159f286781e3abb3b0d8252f7d
+
+Kdf = KDF2(SHA-512)
+Mac = CMAC(AES-256)
+MacKeyLen = 32
+P = 32317006071311007300338913926423828248817941241140239112842009751400741706634354222619689417363569347117901737909704191754605873209195028853758986185622153212175412514901774520270235796078236248884246189477587641105928646099411723245426622522193230540919037680524235519125679715870117001058055877651038861847280257976054903569732561526167081339361799541336476559160368317896729073178384589680639671900977202194168647225871031411336429319536193471636533209717077448227988588565369208645296636077250268955505928362751121174096972998068410554359584866583291642136218231078990999448652468262416972035911852507045361090559
+G = 2
+X1 = 4316760088048858173826993660634587631078362099236037980378049883427191
+X2 = 3824157470039532100357278938102046076290169354062923298804711018976423
+Msg = 75dad921764736e389c4224daf7b278ec291e682044742e2e9c7a025b54dd62f
+Ciphertext = 57dfafa0d81ac3aaca2570ad13cccd127239f4ee04843bb738234588f0daea53ccd8af65a5a00ed19fbb6f2eb57779ff2e38e3d5d27986253a1193dabf14d2402e1a33527866fa21f23f7abbee5f454aad762fc90139c8377bf6cc77af7f982404baea5ca4831dd8ed28babf2d43b1f65eff42167b82f020dfd4928d8e96dcb7845ecf8f560fbbf5646fae5bc4eda6d978e5fb333843a1f4525cfbdde756842a1e353f4de1503738eec6c9d901a78cdefedf8daaa49631da674b44cab2193c778bf29766730a656b42e96f84698f77913c718067048263034cf2a2f34572ab662e4b1c5b04cd71183433c591abd5613820544d46f7462bea57e44f23ab06e0fb9b311515aa49918497c0c52f8c09e2cf6b3bc0343131a552b3d72ec4ee73f9626e83627fdb17b36f71a61d52eb663564
+
+Kdf = KDF2(SHA-256)
+Mac = CMAC(AES-256)
+MacKeyLen = 32
+P = 32317006071311007300338913926423828248817941241140239112842009751400741706634354222619689417363569347117901737909704191754605873209195028853758986185622153212175412514901774520270235796078236248884246189477587641105928646099411723245426622522193230540919037680524235519125679715870117001058055877651038861847280257976054903569732561526167081339361799541336476559160368317896729073178384589680639671900977202194168647225871031411336429319536193471636533209717077448227988588565369208645296636077250268955505928362751121174096972998068410554359584866583291642136218231078990999448652468262416972035911852507045361090559
+G = 2
+X1 = 4316760088048858173826993660634587631078362099236037980378049883427191
+X2 = 3824157470039532100357278938102046076290169354062923298804711018976423
+Msg = 75dad921764736e389c4224daf7b278ec291e682044742e2e9c7a025b54dd62f
+Ciphertext = 57dfafa0d81ac3aaca2570ad13cccd127239f4ee04843bb738234588f0daea53ccd8af65a5a00ed19fbb6f2eb57779ff2e38e3d5d27986253a1193dabf14d2402e1a33527866fa21f23f7abbee5f454aad762fc90139c8377bf6cc77af7f982404baea5ca4831dd8ed28babf2d43b1f65eff42167b82f020dfd4928d8e96dcb7845ecf8f560fbbf5646fae5bc4eda6d978e5fb333843a1f4525cfbdde756842a1e353f4de1503738eec6c9d901a78cdefedf8daaa49631da674b44cab2193c778bf29766730a656b42e96f84698f77913c718067048263034cf2a2f34572ab662e4b1c5b04cd71183433c591abd5613820544d46f7462bea57e44f23ab06e0fbfdeb30b4378e3a6583da338d50cc23086dc8c3b33bc8e6d5612a44a2e1f0c5cbe4f06420b4e196e8d31a1667b2b50355
+
+Kdf = KDF2(SHA-1)
+Mac = CMAC(AES-256)
+MacKeyLen = 32
+P = 32317006071311007300338913926423828248817941241140239112842009751400741706634354222619689417363569347117901737909704191754605873209195028853758986185622153212175412514901774520270235796078236248884246189477587641105928646099411723245426622522193230540919037680524235519125679715870117001058055877651038861847280257976054903569732561526167081339361799541336476559160368317896729073178384589680639671900977202194168647225871031411336429319536193471636533209717077448227988588565369208645296636077250268955505928362751121174096972998068410554359584866583291642136218231078990999448652468262416972035911852507045361090559
+G = 2
+X1 = 4316760088048858173826993660634587631078362099236037980378049883427191
+X2 = 3824157470039532100357278938102046076290169354062923298804711018976423
+Msg = 75dad921764736e389c4224daf7b278ec291e682044742e2e9c7a025b54dd62f
+Ciphertext = 57dfafa0d81ac3aaca2570ad13cccd127239f4ee04843bb738234588f0daea53ccd8af65a5a00ed19fbb6f2eb57779ff2e38e3d5d27986253a1193dabf14d2402e1a33527866fa21f23f7abbee5f454aad762fc90139c8377bf6cc77af7f982404baea5ca4831dd8ed28babf2d43b1f65eff42167b82f020dfd4928d8e96dcb7845ecf8f560fbbf5646fae5bc4eda6d978e5fb333843a1f4525cfbdde756842a1e353f4de1503738eec6c9d901a78cdefedf8daaa49631da674b44cab2193c778bf29766730a656b42e96f84698f77913c718067048263034cf2a2f34572ab662e4b1c5b04cd71183433c591abd5613820544d46f7462bea57e44f23ab06e0fb070d66995d816ed81c1877398dbc56744848d0af4b63c374925eeeab5d99f55cdeb9fc82441056058543f4240b7e5ebf
+
+####### KDF1-18033
+
+Kdf = KDF1-18033(SHA-512)
+Mac = HMAC(SHA-512)
+MacKeyLen = 64
+P = 32317006071311007300338913926423828248817941241140239112842009751400741706634354222619689417363569347117901737909704191754605873209195028853758986185622153212175412514901774520270235796078236248884246189477587641105928646099411723245426622522193230540919037680524235519125679715870117001058055877651038861847280257976054903569732561526167081339361799541336476559160368317896729073178384589680639671900977202194168647225871031411336429319536193471636533209717077448227988588565369208645296636077250268955505928362751121174096972998068410554359584866583291642136218231078990999448652468262416972035911852507045361090559
+G = 2
+X1 = 4316760088048858173826993660634587631078362099236037980378049883427191
+X2 = 3824157470039532100357278938102046076290169354062923298804711018976423
+Msg = 75dad921764736e389c4224daf7b278ec291e682044742e2e9c7a025b54dd62f
+Ciphertext = 57dfafa0d81ac3aaca2570ad13cccd127239f4ee04843bb738234588f0daea53ccd8af65a5a00ed19fbb6f2eb57779ff2e38e3d5d27986253a1193dabf14d2402e1a33527866fa21f23f7abbee5f454aad762fc90139c8377bf6cc77af7f982404baea5ca4831dd8ed28babf2d43b1f65eff42167b82f020dfd4928d8e96dcb7845ecf8f560fbbf5646fae5bc4eda6d978e5fb333843a1f4525cfbdde756842a1e353f4de1503738eec6c9d901a78cdefedf8daaa49631da674b44cab2193c778bf29766730a656b42e96f84698f77913c718067048263034cf2a2f34572ab662e4b1c5b04cd71183433c591abd5613820544d46f7462bea57e44f23ab06e0fb068191059703df1b4b140329d94c796cd2e90d295c13bbdf475e08373bc7a22aec8bda0985f4cda3c620e9a2bfa0767d8ecfc5179cfe11c19672b1bef866e374a14a7ab51e90bbeaac8913d1b650e2addabe7f64debc1fb3a8110e6e58050817
+
+Kdf = KDF1-18033(SHA-512)
+Mac = HMAC(SHA-512)
+MacKeyLen = 32
+P = 32317006071311007300338913926423828248817941241140239112842009751400741706634354222619689417363569347117901737909704191754605873209195028853758986185622153212175412514901774520270235796078236248884246189477587641105928646099411723245426622522193230540919037680524235519125679715870117001058055877651038861847280257976054903569732561526167081339361799541336476559160368317896729073178384589680639671900977202194168647225871031411336429319536193471636533209717077448227988588565369208645296636077250268955505928362751121174096972998068410554359584866583291642136218231078990999448652468262416972035911852507045361090559
+G = 2
+X1 = 4316760088048858173826993660634587631078362099236037980378049883427191
+X2 = 3824157470039532100357278938102046076290169354062923298804711018976423
+Msg = 75dad921764736e389c4224daf7b278ec291e682044742e2e9c7a025b54dd62f
+Ciphertext = 57dfafa0d81ac3aaca2570ad13cccd127239f4ee04843bb738234588f0daea53ccd8af65a5a00ed19fbb6f2eb57779ff2e38e3d5d27986253a1193dabf14d2402e1a33527866fa21f23f7abbee5f454aad762fc90139c8377bf6cc77af7f982404baea5ca4831dd8ed28babf2d43b1f65eff42167b82f020dfd4928d8e96dcb7845ecf8f560fbbf5646fae5bc4eda6d978e5fb333843a1f4525cfbdde756842a1e353f4de1503738eec6c9d901a78cdefedf8daaa49631da674b44cab2193c778bf29766730a656b42e96f84698f77913c718067048263034cf2a2f34572ab662e4b1c5b04cd71183433c591abd5613820544d46f7462bea57e44f23ab06e0fb068191059703df1b4b140329d94c796cd2e90d295c13bbdf475e08373bc7a22a43de2dfe50e0fb98b3e06e6df77d84eac49ac9f273b4c5a64ce5656f706a8df07e6ca7a88d26a28f3d4df96ae5b1146fa2709a87e70659bcf1ef9d0d531ba167
+
+Kdf = KDF1-18033(SHA-512)
+Mac = HMAC(SHA-512)
+MacKeyLen = 20
+P = 32317006071311007300338913926423828248817941241140239112842009751400741706634354222619689417363569347117901737909704191754605873209195028853758986185622153212175412514901774520270235796078236248884246189477587641105928646099411723245426622522193230540919037680524235519125679715870117001058055877651038861847280257976054903569732561526167081339361799541336476559160368317896729073178384589680639671900977202194168647225871031411336429319536193471636533209717077448227988588565369208645296636077250268955505928362751121174096972998068410554359584866583291642136218231078990999448652468262416972035911852507045361090559
+G = 2
+X1 = 4316760088048858173826993660634587631078362099236037980378049883427191
+X2 = 3824157470039532100357278938102046076290169354062923298804711018976423
+Msg = 75dad921764736e389c4224daf7b278ec291e682044742e2e9c7a025b54dd62f
+Ciphertext = 57dfafa0d81ac3aaca2570ad13cccd127239f4ee04843bb738234588f0daea53ccd8af65a5a00ed19fbb6f2eb57779ff2e38e3d5d27986253a1193dabf14d2402e1a33527866fa21f23f7abbee5f454aad762fc90139c8377bf6cc77af7f982404baea5ca4831dd8ed28babf2d43b1f65eff42167b82f020dfd4928d8e96dcb7845ecf8f560fbbf5646fae5bc4eda6d978e5fb333843a1f4525cfbdde756842a1e353f4de1503738eec6c9d901a78cdefedf8daaa49631da674b44cab2193c778bf29766730a656b42e96f84698f77913c718067048263034cf2a2f34572ab662e4b1c5b04cd71183433c591abd5613820544d46f7462bea57e44f23ab06e0fb068191059703df1b4b140329d94c796cd2e90d295c13bbdf475e08373bc7a22a48f09818c5b240b402b40f080b9fd0f8103490c6592f8e56ae20ad10662f13415ada188324cb478888bab0b267ae5c05ba8acd20adc24beae6042b2d37541a77
+
+Kdf = KDF1-18033(SHA-256)
+Mac = HMAC(SHA-256)
+MacKeyLen = 32
+P = 32317006071311007300338913926423828248817941241140239112842009751400741706634354222619689417363569347117901737909704191754605873209195028853758986185622153212175412514901774520270235796078236248884246189477587641105928646099411723245426622522193230540919037680524235519125679715870117001058055877651038861847280257976054903569732561526167081339361799541336476559160368317896729073178384589680639671900977202194168647225871031411336429319536193471636533209717077448227988588565369208645296636077250268955505928362751121174096972998068410554359584866583291642136218231078990999448652468262416972035911852507045361090559
+G = 2
+X1 = 4316760088048858173826993660634587631078362099236037980378049883427191
+X2 = 3824157470039532100357278938102046076290169354062923298804711018976423
+Msg = 75dad921764736e389c4224daf7b278ec291e682044742e2e9c7a025b54dd62f
+Ciphertext = 57dfafa0d81ac3aaca2570ad13cccd127239f4ee04843bb738234588f0daea53ccd8af65a5a00ed19fbb6f2eb57779ff2e38e3d5d27986253a1193dabf14d2402e1a33527866fa21f23f7abbee5f454aad762fc90139c8377bf6cc77af7f982404baea5ca4831dd8ed28babf2d43b1f65eff42167b82f020dfd4928d8e96dcb7845ecf8f560fbbf5646fae5bc4eda6d978e5fb333843a1f4525cfbdde756842a1e353f4de1503738eec6c9d901a78cdefedf8daaa49631da674b44cab2193c778bf29766730a656b42e96f84698f77913c718067048263034cf2a2f34572ab662e4b1c5b04cd71183433c591abd5613820544d46f7462bea57e44f23ab06e0fb536ba065e41dad66225d9469433a5dc53362280c1979818a3349c170060c3ace16137afc5f0642407ba3db6717c739bfff83d3195da75b6c7a82f78169742573
+
+Kdf = KDF1-18033(SHA-256)
+Mac = HMAC(SHA-256)
+MacKeyLen = 20
+P = 32317006071311007300338913926423828248817941241140239112842009751400741706634354222619689417363569347117901737909704191754605873209195028853758986185622153212175412514901774520270235796078236248884246189477587641105928646099411723245426622522193230540919037680524235519125679715870117001058055877651038861847280257976054903569732561526167081339361799541336476559160368317896729073178384589680639671900977202194168647225871031411336429319536193471636533209717077448227988588565369208645296636077250268955505928362751121174096972998068410554359584866583291642136218231078990999448652468262416972035911852507045361090559
+G = 2
+X1 = 4316760088048858173826993660634587631078362099236037980378049883427191
+X2 = 3824157470039532100357278938102046076290169354062923298804711018976423
+Msg = 75dad921764736e389c4224daf7b278ec291e682044742e2e9c7a025b54dd62f
+Ciphertext = 57dfafa0d81ac3aaca2570ad13cccd127239f4ee04843bb738234588f0daea53ccd8af65a5a00ed19fbb6f2eb57779ff2e38e3d5d27986253a1193dabf14d2402e1a33527866fa21f23f7abbee5f454aad762fc90139c8377bf6cc77af7f982404baea5ca4831dd8ed28babf2d43b1f65eff42167b82f020dfd4928d8e96dcb7845ecf8f560fbbf5646fae5bc4eda6d978e5fb333843a1f4525cfbdde756842a1e353f4de1503738eec6c9d901a78cdefedf8daaa49631da674b44cab2193c778bf29766730a656b42e96f84698f77913c718067048263034cf2a2f34572ab662e4b1c5b04cd71183433c591abd5613820544d46f7462bea57e44f23ab06e0fb536ba065e41dad66225d9469433a5dc53362280c1979818a3349c170060c3acef0d102d22c4291474cd83749e499c1c65d179f1ec0cd27a3c995317597a135cc
+
+Kdf = KDF1-18033(SHA-256)
+Mac = HMAC(SHA-256)
+MacKeyLen = 16
+P = 32317006071311007300338913926423828248817941241140239112842009751400741706634354222619689417363569347117901737909704191754605873209195028853758986185622153212175412514901774520270235796078236248884246189477587641105928646099411723245426622522193230540919037680524235519125679715870117001058055877651038861847280257976054903569732561526167081339361799541336476559160368317896729073178384589680639671900977202194168647225871031411336429319536193471636533209717077448227988588565369208645296636077250268955505928362751121174096972998068410554359584866583291642136218231078990999448652468262416972035911852507045361090559
+G = 2
+X1 = 4316760088048858173826993660634587631078362099236037980378049883427191
+X2 = 3824157470039532100357278938102046076290169354062923298804711018976423
+Msg = 75dad921764736e389c4224daf7b278ec291e682044742e2e9c7a025b54dd62f
+Ciphertext = 57dfafa0d81ac3aaca2570ad13cccd127239f4ee04843bb738234588f0daea53ccd8af65a5a00ed19fbb6f2eb57779ff2e38e3d5d27986253a1193dabf14d2402e1a33527866fa21f23f7abbee5f454aad762fc90139c8377bf6cc77af7f982404baea5ca4831dd8ed28babf2d43b1f65eff42167b82f020dfd4928d8e96dcb7845ecf8f560fbbf5646fae5bc4eda6d978e5fb333843a1f4525cfbdde756842a1e353f4de1503738eec6c9d901a78cdefedf8daaa49631da674b44cab2193c778bf29766730a656b42e96f84698f77913c718067048263034cf2a2f34572ab662e4b1c5b04cd71183433c591abd5613820544d46f7462bea57e44f23ab06e0fb536ba065e41dad66225d9469433a5dc53362280c1979818a3349c170060c3ace166abeaf1fa00a4815e47011090e272206df8c8f6362869c04eb0e704b625a87
+
+Kdf = KDF1-18033(SHA-1)
+Mac = HMAC(SHA-1)
+MacKeyLen = 20
+P = 32317006071311007300338913926423828248817941241140239112842009751400741706634354222619689417363569347117901737909704191754605873209195028853758986185622153212175412514901774520270235796078236248884246189477587641105928646099411723245426622522193230540919037680524235519125679715870117001058055877651038861847280257976054903569732561526167081339361799541336476559160368317896729073178384589680639671900977202194168647225871031411336429319536193471636533209717077448227988588565369208645296636077250268955505928362751121174096972998068410554359584866583291642136218231078990999448652468262416972035911852507045361090559
+G = 2
+X1 = 4316760088048858173826993660634587631078362099236037980378049883427191
+X2 = 3824157470039532100357278938102046076290169354062923298804711018976423
+Msg = 75dad921764736e389c4224daf7b278ec291e682044742e2e9c7a025b54dd62f
+Ciphertext = 57dfafa0d81ac3aaca2570ad13cccd127239f4ee04843bb738234588f0daea53ccd8af65a5a00ed19fbb6f2eb57779ff2e38e3d5d27986253a1193dabf14d2402e1a33527866fa21f23f7abbee5f454aad762fc90139c8377bf6cc77af7f982404baea5ca4831dd8ed28babf2d43b1f65eff42167b82f020dfd4928d8e96dcb7845ecf8f560fbbf5646fae5bc4eda6d978e5fb333843a1f4525cfbdde756842a1e353f4de1503738eec6c9d901a78cdefedf8daaa49631da674b44cab2193c778bf29766730a656b42e96f84698f77913c718067048263034cf2a2f34572ab662e4b1c5b04cd71183433c591abd5613820544d46f7462bea57e44f23ab06e0fb96e324a74d5941d71563b32059bba36cd6990ee07690fd5ac201f81e2091835b9e0d6e486f279855a6b4e4855bd12e030367e698
+
+Kdf = KDF1-18033(SHA-1)
+Mac = HMAC(SHA-1)
+MacKeyLen = 16
+P = 32317006071311007300338913926423828248817941241140239112842009751400741706634354222619689417363569347117901737909704191754605873209195028853758986185622153212175412514901774520270235796078236248884246189477587641105928646099411723245426622522193230540919037680524235519125679715870117001058055877651038861847280257976054903569732561526167081339361799541336476559160368317896729073178384589680639671900977202194168647225871031411336429319536193471636533209717077448227988588565369208645296636077250268955505928362751121174096972998068410554359584866583291642136218231078990999448652468262416972035911852507045361090559
+G = 2
+X1 = 4316760088048858173826993660634587631078362099236037980378049883427191
+X2 = 3824157470039532100357278938102046076290169354062923298804711018976423
+Msg = 75dad921764736e389c4224daf7b278ec291e682044742e2e9c7a025b54dd62f
+Ciphertext = 57dfafa0d81ac3aaca2570ad13cccd127239f4ee04843bb738234588f0daea53ccd8af65a5a00ed19fbb6f2eb57779ff2e38e3d5d27986253a1193dabf14d2402e1a33527866fa21f23f7abbee5f454aad762fc90139c8377bf6cc77af7f982404baea5ca4831dd8ed28babf2d43b1f65eff42167b82f020dfd4928d8e96dcb7845ecf8f560fbbf5646fae5bc4eda6d978e5fb333843a1f4525cfbdde756842a1e353f4de1503738eec6c9d901a78cdefedf8daaa49631da674b44cab2193c778bf29766730a656b42e96f84698f77913c718067048263034cf2a2f34572ab662e4b1c5b04cd71183433c591abd5613820544d46f7462bea57e44f23ab06e0fb96e324a74d5941d71563b32059bba36cd6990ee07690fd5ac201f81e2091835b30500fea11b5dfc1b60b691f3326c4d109970142
+
+Kdf = KDF1-18033(SHA-512)
+Mac = CMAC(AES-256)
+MacKeyLen = 32
+P = 32317006071311007300338913926423828248817941241140239112842009751400741706634354222619689417363569347117901737909704191754605873209195028853758986185622153212175412514901774520270235796078236248884246189477587641105928646099411723245426622522193230540919037680524235519125679715870117001058055877651038861847280257976054903569732561526167081339361799541336476559160368317896729073178384589680639671900977202194168647225871031411336429319536193471636533209717077448227988588565369208645296636077250268955505928362751121174096972998068410554359584866583291642136218231078990999448652468262416972035911852507045361090559
+G = 2
+X1 = 4316760088048858173826993660634587631078362099236037980378049883427191
+X2 = 3824157470039532100357278938102046076290169354062923298804711018976423
+Msg = 75dad921764736e389c4224daf7b278ec291e682044742e2e9c7a025b54dd62f
+Ciphertext = 57dfafa0d81ac3aaca2570ad13cccd127239f4ee04843bb738234588f0daea53ccd8af65a5a00ed19fbb6f2eb57779ff2e38e3d5d27986253a1193dabf14d2402e1a33527866fa21f23f7abbee5f454aad762fc90139c8377bf6cc77af7f982404baea5ca4831dd8ed28babf2d43b1f65eff42167b82f020dfd4928d8e96dcb7845ecf8f560fbbf5646fae5bc4eda6d978e5fb333843a1f4525cfbdde756842a1e353f4de1503738eec6c9d901a78cdefedf8daaa49631da674b44cab2193c778bf29766730a656b42e96f84698f77913c718067048263034cf2a2f34572ab662e4b1c5b04cd71183433c591abd5613820544d46f7462bea57e44f23ab06e0fb068191059703df1b4b140329d94c796cd2e90d295c13bbdf475e08373bc7a22a6cfc28a4b15599d72666d18cb8a65e19
+
+Kdf = KDF1-18033(SHA-256)
+Mac = CMAC(AES-256)
+MacKeyLen = 32
+P = 32317006071311007300338913926423828248817941241140239112842009751400741706634354222619689417363569347117901737909704191754605873209195028853758986185622153212175412514901774520270235796078236248884246189477587641105928646099411723245426622522193230540919037680524235519125679715870117001058055877651038861847280257976054903569732561526167081339361799541336476559160368317896729073178384589680639671900977202194168647225871031411336429319536193471636533209717077448227988588565369208645296636077250268955505928362751121174096972998068410554359584866583291642136218231078990999448652468262416972035911852507045361090559
+G = 2
+X1 = 4316760088048858173826993660634587631078362099236037980378049883427191
+X2 = 3824157470039532100357278938102046076290169354062923298804711018976423
+Msg = 75dad921764736e389c4224daf7b278ec291e682044742e2e9c7a025b54dd62f
+Ciphertext = 57dfafa0d81ac3aaca2570ad13cccd127239f4ee04843bb738234588f0daea53ccd8af65a5a00ed19fbb6f2eb57779ff2e38e3d5d27986253a1193dabf14d2402e1a33527866fa21f23f7abbee5f454aad762fc90139c8377bf6cc77af7f982404baea5ca4831dd8ed28babf2d43b1f65eff42167b82f020dfd4928d8e96dcb7845ecf8f560fbbf5646fae5bc4eda6d978e5fb333843a1f4525cfbdde756842a1e353f4de1503738eec6c9d901a78cdefedf8daaa49631da674b44cab2193c778bf29766730a656b42e96f84698f77913c718067048263034cf2a2f34572ab662e4b1c5b04cd71183433c591abd5613820544d46f7462bea57e44f23ab06e0fb536ba065e41dad66225d9469433a5dc53362280c1979818a3349c170060c3aceb5f786c722ea79e5c262c8b8b8f0f2f5
+
+Kdf = KDF1-18033(SHA-1)
+Mac = CMAC(AES-256)
+MacKeyLen = 32
+P = 32317006071311007300338913926423828248817941241140239112842009751400741706634354222619689417363569347117901737909704191754605873209195028853758986185622153212175412514901774520270235796078236248884246189477587641105928646099411723245426622522193230540919037680524235519125679715870117001058055877651038861847280257976054903569732561526167081339361799541336476559160368317896729073178384589680639671900977202194168647225871031411336429319536193471636533209717077448227988588565369208645296636077250268955505928362751121174096972998068410554359584866583291642136218231078990999448652468262416972035911852507045361090559
+G = 2
+X1 = 4316760088048858173826993660634587631078362099236037980378049883427191
+X2 = 3824157470039532100357278938102046076290169354062923298804711018976423
+Msg = 75dad921764736e389c4224daf7b278ec291e682044742e2e9c7a025b54dd62f
+Ciphertext = 57dfafa0d81ac3aaca2570ad13cccd127239f4ee04843bb738234588f0daea53ccd8af65a5a00ed19fbb6f2eb57779ff2e38e3d5d27986253a1193dabf14d2402e1a33527866fa21f23f7abbee5f454aad762fc90139c8377bf6cc77af7f982404baea5ca4831dd8ed28babf2d43b1f65eff42167b82f020dfd4928d8e96dcb7845ecf8f560fbbf5646fae5bc4eda6d978e5fb333843a1f4525cfbdde756842a1e353f4de1503738eec6c9d901a78cdefedf8daaa49631da674b44cab2193c778bf29766730a656b42e96f84698f77913c718067048263034cf2a2f34572ab662e4b1c5b04cd71183433c591abd5613820544d46f7462bea57e44f23ab06e0fb96e324a74d5941d71563b32059bba36cd6990ee07690fd5ac201f81e2091835b29651165a98cf6ea7f18f6638151094a
+
+########################### Test vectors created with botan for AES-GCM tests ###########################
+
+Kdf = KDF2(SHA-512)
+Mac = HMAC(SHA-512)
+MacKeyLen = 64
+Cipher = AES-256/GCM
+CipherKeyLen = 32
+IV = 00000000000000000000000000000000
+P = 32317006071311007300338913926423828248817941241140239112842009751400741706634354222619689417363569347117901737909704191754605873209195028853758986185622153212175412514901774520270235796078236248884246189477587641105928646099411723245426622522193230540919037680524235519125679715870117001058055877651038861847280257976054903569732561526167081339361799541336476559160368317896729073178384589680639671900977202194168647225871031411336429319536193471636533209717077448227988588565369208645296636077250268955505928362751121174096972998068410554359584866583291642136218231078990999448652468262416972035911852507045361090559
+G = 2
+X1 = 4316760088048858173826993660634587631078362099236037980378049883427191
+X2 = 3824157470039532100357278938102046076290169354062923298804711018976423
+Msg = 75dad921764736e389c4224daf7b278ec291e682044742e2e9c7a025b54dd62f
+Ciphertext = 57DFAFA0D81AC3AACA2570AD13CCCD127239F4EE04843BB738234588F0DAEA53CCD8AF65A5A00ED19FBB6F2EB57779FF2E38E3D5D27986253A1193DABF14D2402E1A33527866FA21F23F7ABBEE5F454AAD762FC90139C8377BF6CC77AF7F982404BAEA5CA4831DD8ED28BABF2D43B1F65EFF42167B82F020DFD4928D8E96DCB7845ECF8F560FBBF5646FAE5BC4EDA6D978E5FB333843A1F4525CFBDDE756842A1E353F4DE1503738EEC6C9D901A78CDEFEDF8DAAA49631DA674B44CAB2193C778BF29766730A656B42E96F84698F77913C718067048263034CF2A2F34572AB662E4B1C5B04CD71183433C591ABD5613820544D46F7462BEA57E44F23AB06E0FB142440A4B10508DB7E61E326B749F1B332A624C5DDF9E989A5D3A1FEC6FC5651A4FFBBC673A52C0B440DEFB8B3EEBB828A46DF1737A3E8DA67A3840041994D34C78D552A09423A4301F513CFF526D476C16C09D0C0F9D978B64A6AF8F883EBE704B412C72C91CE93B9DF82721ACFA6F3
+
+Kdf = KDF2(SHA-512)
+Mac = HMAC(SHA-512)
+MacKeyLen = 64
+Cipher = AES-256/GCM
+CipherKeyLen = 32
+IV = 00112233445566778899aabbccddeeff
+P = 32317006071311007300338913926423828248817941241140239112842009751400741706634354222619689417363569347117901737909704191754605873209195028853758986185622153212175412514901774520270235796078236248884246189477587641105928646099411723245426622522193230540919037680524235519125679715870117001058055877651038861847280257976054903569732561526167081339361799541336476559160368317896729073178384589680639671900977202194168647225871031411336429319536193471636533209717077448227988588565369208645296636077250268955505928362751121174096972998068410554359584866583291642136218231078990999448652468262416972035911852507045361090559
+G = 2
+X1 = 4316760088048858173826993660634587631078362099236037980378049883427191
+X2 = 3824157470039532100357278938102046076290169354062923298804711018976423
+Msg = 75dad921764736e389c4224daf7b278ec291e682044742e2e9c7a025b54dd62f
+Ciphertext = 57DFAFA0D81AC3AACA2570AD13CCCD127239F4EE04843BB738234588F0DAEA53CCD8AF65A5A00ED19FBB6F2EB57779FF2E38E3D5D27986253A1193DABF14D2402E1A33527866FA21F23F7ABBEE5F454AAD762FC90139C8377BF6CC77AF7F982404BAEA5CA4831DD8ED28BABF2D43B1F65EFF42167B82F020DFD4928D8E96DCB7845ECF8F560FBBF5646FAE5BC4EDA6D978E5FB333843A1F4525CFBDDE756842A1E353F4DE1503738EEC6C9D901A78CDEFEDF8DAAA49631DA674B44CAB2193C778BF29766730A656B42E96F84698F77913C718067048263034CF2A2F34572AB662E4B1C5B04CD71183433C591ABD5613820544D46F7462BEA57E44F23AB06E0FB72CE0E99275D750433D9D8115E9F4FF5A91A341E1A3E73F64D8DBE1BFEC7FFA1D2CD8DEF2C0664017A337303455BCF37D076564864E0733DF29D910E8BF0308DCA81A064FEE96811A34B4D0E4BBA45BED459E7BE4FCA58918633F2C6CC34871759BE982DC459AB39F989E42113E0F0A2
+
+Kdf = KDF2(SHA-512)
+Mac = CMAC(AES-256)
+MacKeyLen = 32
+Cipher = AES-256/GCM
+CipherKeyLen = 32
+IV = 00000000000000000000000000000000
+P = 32317006071311007300338913926423828248817941241140239112842009751400741706634354222619689417363569347117901737909704191754605873209195028853758986185622153212175412514901774520270235796078236248884246189477587641105928646099411723245426622522193230540919037680524235519125679715870117001058055877651038861847280257976054903569732561526167081339361799541336476559160368317896729073178384589680639671900977202194168647225871031411336429319536193471636533209717077448227988588565369208645296636077250268955505928362751121174096972998068410554359584866583291642136218231078990999448652468262416972035911852507045361090559
G = 2
-X1 = 3895469730603000759730584760913911891226712505433061
-X2 = 3202115124466487737101087673031994924801994092564435
-Msg = AB5BBE0D
-Ciphertext = 538F9C9CAC3EEB460B6D40B4AC331EBD3E2F3065E515177F47A083D1AC71533BF3B2931F52D71A99CA0804A633E1948F3B286453EA6CF0DD83C6DD1D2BD93B20F4942D9679CFDE5856DD81E152E1E5ADD023324B945CE68425B025AE5D0CF86C0D33244A60AF6045BD57018FFE5F84A9BF82193242FF32A64691586AAA298FE531CF06A56412DFEC3AD1F50FF8CD296310E5BB4D06E15AB0
+X1 = 4316760088048858173826993660634587631078362099236037980378049883427191
+X2 = 3824157470039532100357278938102046076290169354062923298804711018976423
+Msg = 75dad921764736e389c4224daf7b278ec291e682044742e2e9c7a025b54dd62f
+Ciphertext = 57DFAFA0D81AC3AACA2570AD13CCCD127239F4EE04843BB738234588F0DAEA53CCD8AF65A5A00ED19FBB6F2EB57779FF2E38E3D5D27986253A1193DABF14D2402E1A33527866FA21F23F7ABBEE5F454AAD762FC90139C8377BF6CC77AF7F982404BAEA5CA4831DD8ED28BABF2D43B1F65EFF42167B82F020DFD4928D8E96DCB7845ECF8F560FBBF5646FAE5BC4EDA6D978E5FB333843A1F4525CFBDDE756842A1E353F4DE1503738EEC6C9D901A78CDEFEDF8DAAA49631DA674B44CAB2193C778BF29766730A656B42E96F84698F77913C718067048263034CF2A2F34572AB662E4B1C5B04CD71183433C591ABD5613820544D46F7462BEA57E44F23AB06E0FB142440A4B10508DB7E61E326B749F1B332A624C5DDF9E989A5D3A1FEC6FC5651A4FFBBC673A52C0B440DEFB8B3EEBB82EAB5098B4E55338B28863B299D77FD6E
-P = 179769313486231590770839156793787453197860296048756011706444423684197180216158519368947833795864925541502180565485980503646440548199239100050792877003355816639229553136239076508735759914822574862575007425302077447712589550957937778424442426617334727629299387668709205606050270810842907692932019128194467627007
+Kdf = KDF2(SHA-512)
+Mac = CMAC(AES-256)
+MacKeyLen = 32
+Cipher = AES-256/GCM
+CipherKeyLen = 32
+IV = 00112233445566778899aabbccddeeff
+P = 32317006071311007300338913926423828248817941241140239112842009751400741706634354222619689417363569347117901737909704191754605873209195028853758986185622153212175412514901774520270235796078236248884246189477587641105928646099411723245426622522193230540919037680524235519125679715870117001058055877651038861847280257976054903569732561526167081339361799541336476559160368317896729073178384589680639671900977202194168647225871031411336429319536193471636533209717077448227988588565369208645296636077250268955505928362751121174096972998068410554359584866583291642136218231078990999448652468262416972035911852507045361090559
G = 2
-X1 = 4556286536649761359339945350124531773703491905870156
-X2 = 4102583277207195475485889175414309483746012144669284
-Msg = C43BB390
-Ciphertext = C04F6BD6D1BFBDE74E775FB391A29B2D6FB7EE84C13D2061291DBA8708E406B0A6788F69F7DFEBE4CA35B31917EACD7D36CDBEBDCC51567ADF3F287F57592A0F73E1C990B807E0A67ACAE3F07361DF123C59E0A95CFCA9DEB3C7CCDC47C925F975AF0948B3DE9EC1E34EED30391FD4080D77DD07F091E3D5D89BC158A96485B28477AA95D62EFB9FA1D2B44A38A698F81C9518355BAE8B74
+X1 = 4316760088048858173826993660634587631078362099236037980378049883427191
+X2 = 3824157470039532100357278938102046076290169354062923298804711018976423
+Msg = 75dad921764736e389c4224daf7b278ec291e682044742e2e9c7a025b54dd62f
+Ciphertext = 57DFAFA0D81AC3AACA2570AD13CCCD127239F4EE04843BB738234588F0DAEA53CCD8AF65A5A00ED19FBB6F2EB57779FF2E38E3D5D27986253A1193DABF14D2402E1A33527866FA21F23F7ABBEE5F454AAD762FC90139C8377BF6CC77AF7F982404BAEA5CA4831DD8ED28BABF2D43B1F65EFF42167B82F020DFD4928D8E96DCB7845ECF8F560FBBF5646FAE5BC4EDA6D978E5FB333843A1F4525CFBDDE756842A1E353F4DE1503738EEC6C9D901A78CDEFEDF8DAAA49631DA674B44CAB2193C778BF29766730A656B42E96F84698F77913C718067048263034CF2A2F34572AB662E4B1C5B04CD71183433C591ABD5613820544D46F7462BEA57E44F23AB06E0FB72CE0E99275D750433D9D8115E9F4FF5A91A341E1A3E73F64D8DBE1BFEC7FFA1D2CD8DEF2C0664017A337303455BCF37845E0B4A59D925366D35D40C344FE6BD
-P = 1552518092300708935130918131258481755631334049434514313202351194902966239949102107258669453876591642442910007680288864229150803718918046342632727613031282983744380820890196288509170691316593175367469551763119843371637221007210577919
+Kdf = KDF1-18033(SHA-512)
+Mac = HMAC(SHA-512)
+MacKeyLen = 64
+Cipher = AES-256/GCM
+CipherKeyLen = 32
+IV = 00112233445566778899aabbccddeeff
+P = 32317006071311007300338913926423828248817941241140239112842009751400741706634354222619689417363569347117901737909704191754605873209195028853758986185622153212175412514901774520270235796078236248884246189477587641105928646099411723245426622522193230540919037680524235519125679715870117001058055877651038861847280257976054903569732561526167081339361799541336476559160368317896729073178384589680639671900977202194168647225871031411336429319536193471636533209717077448227988588565369208645296636077250268955505928362751121174096972998068410554359584866583291642136218231078990999448652468262416972035911852507045361090559
G = 2
-X1 = 1054639601167296898572220004033907486000310327029
-X2 = 1342657759849572617856127220396675041367757265787
-Msg = 3B06E0705DC9DBA971AA624393984D5B
-Ciphertext = 2AB9B180CEF08E761EDB4D7B7C538FBA0FD37BACE9416789A0DD6551F2DDC6025C76A663F1AAD5000EC03418A6220ABA6D3DC5EA82D7340E2FFCB5665AD3A2223CDFF9C39889CBE31E44CD31BCFDCEFCF2A9916FD39E2720A7B826F7E6998F734F251C71DC970AF3FB12949C14AA759966733BFC976CAD0BE71FC5DBE285200E75647C62
+X1 = 4316760088048858173826993660634587631078362099236037980378049883427191
+X2 = 3824157470039532100357278938102046076290169354062923298804711018976423
+Msg = 75dad921764736e389c4224daf7b278ec291e682044742e2e9c7a025b54dd62f
+Ciphertext = 57DFAFA0D81AC3AACA2570AD13CCCD127239F4EE04843BB738234588F0DAEA53CCD8AF65A5A00ED19FBB6F2EB57779FF2E38E3D5D27986253A1193DABF14D2402E1A33527866FA21F23F7ABBEE5F454AAD762FC90139C8377BF6CC77AF7F982404BAEA5CA4831DD8ED28BABF2D43B1F65EFF42167B82F020DFD4928D8E96DCB7845ECF8F560FBBF5646FAE5BC4EDA6D978E5FB333843A1F4525CFBDDE756842A1E353F4DE1503738EEC6C9D901A78CDEFEDF8DAAA49631DA674B44CAB2193C778BF29766730A656B42E96F84698F77913C718067048263034CF2A2F34572AB662E4B1C5B04CD71183433C591ABD5613820544D46F7462BEA57E44F23AB06E0FB9A0B0CAB5C285FB0CB1F788213B6B82A2C2E485C1D514BAEF7FC241D57DB031D9E80361C55B562232759A660C89E0DE0E11BB8C807142C1C98C07C9BD08BFC7A3D9977133AD07DDED60728B46D668444A74BC001CFBFB8E8FE0BACF6A4078DD4212DC7CDC3291CB3F02AC0B7CDF6E65D
-P = 1552518092300708935130918131258481755631334049434514313202351194902966239949102107258669453876591642442910007680288864229150803718918046342632727613031282983744380820890196288509170691316593175367469551763119843371637221007210577919
+Kdf = KDF1-18033(SHA-512)
+Mac = HMAC(SHA-512)
+MacKeyLen = 64
+Cipher = AES-256/GCM
+CipherKeyLen = 32
+IV = 00000000000000000000000000000000
+P = 32317006071311007300338913926423828248817941241140239112842009751400741706634354222619689417363569347117901737909704191754605873209195028853758986185622153212175412514901774520270235796078236248884246189477587641105928646099411723245426622522193230540919037680524235519125679715870117001058055877651038861847280257976054903569732561526167081339361799541336476559160368317896729073178384589680639671900977202194168647225871031411336429319536193471636533209717077448227988588565369208645296636077250268955505928362751121174096972998068410554359584866583291642136218231078990999448652468262416972035911852507045361090559
G = 2
-X1 = 1019791127804545295775858763356184757983418129858
-X2 = 791304855263120499982139573682243365135340447126
-Msg = DD92A05E19BBAD4A33CEFFA0FA2727E9
-Ciphertext = 3F0300C53C0BB02A3EF2EFCC751EE5D98AE991730C1C2FE39D11A74D32D892AD63A9EECA09BBBE606FB426E03BBD480FD224E09712BB85FE649D543CBC23113A39F9102C65D31DF330ADF233735C1D60D1BCDE22744392D2D9DE50393984F276A33DD85F763ED1226B88DF1662554AD27820F66A995FE1481189A2B8C3071D0C32EE9960
+X1 = 4316760088048858173826993660634587631078362099236037980378049883427191
+X2 = 3824157470039532100357278938102046076290169354062923298804711018976423
+Msg = 75dad921764736e389c4224daf7b278ec291e682044742e2e9c7a025b54dd62f
+Ciphertext = 57DFAFA0D81AC3AACA2570AD13CCCD127239F4EE04843BB738234588F0DAEA53CCD8AF65A5A00ED19FBB6F2EB57779FF2E38E3D5D27986253A1193DABF14D2402E1A33527866FA21F23F7ABBEE5F454AAD762FC90139C8377BF6CC77AF7F982404BAEA5CA4831DD8ED28BABF2D43B1F65EFF42167B82F020DFD4928D8E96DCB7845ECF8F560FBBF5646FAE5BC4EDA6D978E5FB333843A1F4525CFBDDE756842A1E353F4DE1503738EEC6C9D901A78CDEFEDF8DAAA49631DA674B44CAB2193C778BF29766730A656B42E96F84698F77913C718067048263034CF2A2F34572AB662E4B1C5B04CD71183433C591ABD5613820544D46F7462BEA57E44F23AB06E0FB7177BE14E602FEB0274B170E41879977CA357CD99EC7FF096964C0FE4AA7D39DC90D24DC433C695D3B2B4A7B88BF08B2099F5321322A66A5377C14FF3F7FF6C96FC72DA82DADAB8064248F0751EAEFC62ADFD4FA782D11EA953FA2FE924FFD7CB7310531D2A9A0091F23E0E195DAAB3E
-P = 1552518092300708935130918131258481755631334049434514313202351194902966239949102107258669453876591642442910007680288864229150803718918046342632727613031282983744380820890196288509170691316593175367469551763119843371637221007210577919
+Kdf = KDF1-18033(SHA-512)
+Mac = CMAC(AES-256)
+MacKeyLen = 32
+Cipher = AES-256/GCM
+CipherKeyLen = 32
+IV = 00000000000000000000000000000000
+P = 32317006071311007300338913926423828248817941241140239112842009751400741706634354222619689417363569347117901737909704191754605873209195028853758986185622153212175412514901774520270235796078236248884246189477587641105928646099411723245426622522193230540919037680524235519125679715870117001058055877651038861847280257976054903569732561526167081339361799541336476559160368317896729073178384589680639671900977202194168647225871031411336429319536193471636533209717077448227988588565369208645296636077250268955505928362751121174096972998068410554359584866583291642136218231078990999448652468262416972035911852507045361090559
G = 2
-X1 = 1127072655127804554962850771491034708297993164117
-X2 = 909338501771729516589244957544435828677252574269
-Msg = 174E756AF8FFB51990BF3C69688D3A7F0B388F2BCE62A095BC12CD6DA2C2AD65
-Ciphertext = B99BBBC64F6320060200E6FFE7D1FE6E5EEA79DF142111AF88D377037BD9186341B7A7A27F2AE8BB77282B8EA13D821DD77186412CA3B9B5E1650A0D20687B1C8D556FD7D547D475F71BBD7D6417311F535A9A6D95CEA8AFD1146B1A1741828E8AD46B058507A67111CB62132350EEAC1212D90535677855E17B1DA9DC4CE790C4B917B1359123226FE62DCCE5475721F09CEA23
+X1 = 4316760088048858173826993660634587631078362099236037980378049883427191
+X2 = 3824157470039532100357278938102046076290169354062923298804711018976423
+Msg = 75dad921764736e389c4224daf7b278ec291e682044742e2e9c7a025b54dd62f
+Ciphertext = 57DFAFA0D81AC3AACA2570AD13CCCD127239F4EE04843BB738234588F0DAEA53CCD8AF65A5A00ED19FBB6F2EB57779FF2E38E3D5D27986253A1193DABF14D2402E1A33527866FA21F23F7ABBEE5F454AAD762FC90139C8377BF6CC77AF7F982404BAEA5CA4831DD8ED28BABF2D43B1F65EFF42167B82F020DFD4928D8E96DCB7845ECF8F560FBBF5646FAE5BC4EDA6D978E5FB333843A1F4525CFBDDE756842A1E353F4DE1503738EEC6C9D901A78CDEFEDF8DAAA49631DA674B44CAB2193C778BF29766730A656B42E96F84698F77913C718067048263034CF2A2F34572AB662E4B1C5B04CD71183433C591ABD5613820544D46F7462BEA57E44F23AB06E0FB7177BE14E602FEB0274B170E41879977CA357CD99EC7FF096964C0FE4AA7D39DC90D24DC433C695D3B2B4A7B88BF08B299019BFDC4ABE7BBED415937E9F58B9D
-P = 1552518092300708935130918131258481755631334049434514313202351194902966239949102107258669453876591642442910007680288864229150803718918046342632727613031282983744380820890196288509170691316593175367469551763119843371637221007210577919
+Kdf = KDF1-18033(SHA-512)
+Mac = CMAC(AES-256)
+MacKeyLen = 32
+Cipher = AES-256/GCM
+CipherKeyLen = 32
+IV = 00112233445566778899aabbccddeeff
+P = 32317006071311007300338913926423828248817941241140239112842009751400741706634354222619689417363569347117901737909704191754605873209195028853758986185622153212175412514901774520270235796078236248884246189477587641105928646099411723245426622522193230540919037680524235519125679715870117001058055877651038861847280257976054903569732561526167081339361799541336476559160368317896729073178384589680639671900977202194168647225871031411336429319536193471636533209717077448227988588565369208645296636077250268955505928362751121174096972998068410554359584866583291642136218231078990999448652468262416972035911852507045361090559
G = 2
-X1 = 1400390629906877310807893670888997072266707870316
-X2 = 1409894924299088894270577337460879151312883489271
-Msg = 75DAD921764736E389C4224DAF7B278EC291E682044742E2E9C7A025B54DD62F
-Ciphertext = C591E27A2C12742A959652F5F341F558CA0C7DAF2E6B5ACE32DCAAF459553BA23EF0235EAFD86A7F2D70587239D858484E5CD36122C2B9F6E410C7A9C307B2A2A084BB1B634A15AC9F09E38EAF421D14C5A07B6EB5EDE6915E8DE9D3D9D01DBD8822FBD79BA7FF3DF921B5451BBD9A12AB41FD4DAB829599BC2736B23753063C0C5FFCBA7DB06DE26D3C441D126FC1A46531F593
+X1 = 4316760088048858173826993660634587631078362099236037980378049883427191
+X2 = 3824157470039532100357278938102046076290169354062923298804711018976423
+Msg = 75dad921764736e389c4224daf7b278ec291e682044742e2e9c7a025b54dd62f
+Ciphertext = 57DFAFA0D81AC3AACA2570AD13CCCD127239F4EE04843BB738234588F0DAEA53CCD8AF65A5A00ED19FBB6F2EB57779FF2E38E3D5D27986253A1193DABF14D2402E1A33527866FA21F23F7ABBEE5F454AAD762FC90139C8377BF6CC77AF7F982404BAEA5CA4831DD8ED28BABF2D43B1F65EFF42167B82F020DFD4928D8E96DCB7845ECF8F560FBBF5646FAE5BC4EDA6D978E5FB333843A1F4525CFBDDE756842A1E353F4DE1503738EEC6C9D901A78CDEFEDF8DAAA49631DA674B44CAB2193C778BF29766730A656B42E96F84698F77913C718067048263034CF2A2F34572AB662E4B1C5B04CD71183433C591ABD5613820544D46F7462BEA57E44F23AB06E0FB9A0B0CAB5C285FB0CB1F788213B6B82A2C2E485C1D514BAEF7FC241D57DB031D9E80361C55B562232759A660C89E0DE0FB884998AEFEF7CE84F114928423F7E2
diff --git a/src/tests/test_dlies.cpp b/src/tests/test_dlies.cpp
index ba8142dcb..75d751eaa 100644
--- a/src/tests/test_dlies.cpp
+++ b/src/tests/test_dlies.cpp
@@ -1,5 +1,6 @@
/*
* (C) 2014,2015 Jack Lloyd
+* (C) 2016 Daniel Neus, Rohde & Schwarz Cybersecurity
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
@@ -24,7 +25,7 @@ class DLIES_KAT_Tests : public Text_Based_Test
public:
DLIES_KAT_Tests() : Text_Based_Test(
"pubkey/dlies.vec",
- {"P", "G", "X1", "X2", "Msg", "Ciphertext"})
+ {"Kdf", "Mac", "MacKeyLen", "Cipher", "CipherKeyLen", "IV", "P", "G", "X1", "X2", "Msg", "Ciphertext"})
{}
Test::Result run_one_test(const std::string&, const VarMap& vars) override
@@ -37,35 +38,52 @@ class DLIES_KAT_Tests : public Text_Based_Test
const std::vector input = get_req_bin(vars, "Msg");
const std::vector expected = get_req_bin(vars, "Ciphertext");
- Botan::DL_Group domain(p, g);
-
- Botan::DH_PrivateKey from(Test::rng(), domain, x1);
- Botan::DH_PrivateKey to(Test::rng(), domain, x2);
+ const std::string kdf_algo = get_req_str(vars, "Kdf");
+ const std::string mac_algo = get_req_str(vars, "Mac");
+ const size_t mac_key_len = get_req_sz(vars, "MacKeyLen");
- const std::string kdf_algo = "KDF2(SHA-1)";
- const std::string mac_algo = "HMAC(SHA-1)";
- const size_t mac_key_len = 16;
+ const std::string cipher_algo = get_opt_str(vars, "Cipher", "");
+ const size_t cipher_key_len = get_opt_sz(vars, "CipherKeyLen", 0);
+ const std::vector iv = get_opt_bin(vars, "IV");
Test::Result result("DLIES");
std::unique_ptr kdf(Botan::KDF::create(kdf_algo));
- std::unique_ptr mac(Botan::MAC::create(mac_algo));
+ if(!kdf)
+ {
+ result.test_note("Skipping due to missing KDF: " + kdf_algo);
+ return result;
+ }
- if(!kdf || !mac)
+ std::unique_ptr mac(Botan::MAC::create(mac_algo));
+ if(!mac)
{
- result.test_note("Skipping due to missing KDF or MAC algo");
+ result.test_note("Skipping due to missing MAC: " + mac_algo);
return result;
}
- Botan::DLIES_Encryptor encryptor(from,
- kdf->clone(),
- mac->clone(),
- mac_key_len);
+ std::unique_ptr enc;
+ std::unique_ptr dec;
+
+ if(! cipher_algo.empty())
+ {
+ enc.reset(Botan::get_cipher_mode(cipher_algo, Botan::ENCRYPTION));
+ dec.reset(Botan::get_cipher_mode(cipher_algo, Botan::DECRYPTION));
+ }
+
+ Botan::DL_Group domain(p, g);
+
+ Botan::DH_PrivateKey from(Test::rng(), domain, x1);
+ Botan::DH_PrivateKey to(Test::rng(), domain, x2);
- Botan::DLIES_Decryptor decryptor(to,
- kdf.release(),
- mac.release(),
- mac_key_len);
+ Botan::DLIES_Encryptor encryptor(from, kdf->clone(), enc.release(), cipher_key_len, mac->clone(), mac_key_len);
+ Botan::DLIES_Decryptor decryptor(to, kdf.release(), dec.release(), cipher_key_len, mac.release(), mac_key_len);
+
+ if(!iv.empty())
+ {
+ encryptor.set_initialization_vector(iv);
+ decryptor.set_initialization_vector(iv);
+ }
encryptor.set_other_key(to.public_value());
@@ -80,6 +98,101 @@ class DLIES_KAT_Tests : public Text_Based_Test
BOTAN_REGISTER_TEST("dlies", DLIES_KAT_Tests);
+Test::Result test_xor()
+ {
+ Test::Result result("DLIES XOR");
+
+ std::vector kdfs = { "KDF2(SHA-512)", "KDF1-18033(SHA-512)" };
+ std::vector macs = { "HMAC(SHA-512)", "CMAC(AES-128)" };
+
+ const size_t mac_key_len = 16;
+
+ std::unique_ptr kdf;
+ std::unique_ptr mac;
+
+ Botan::DH_PrivateKey alice(Test::rng(), Botan::DL_Group("modp/ietf/2048"));
+ Botan::DH_PrivateKey bob(Test::rng(), Botan::DL_Group("modp/ietf/2048"));
+
+ for(const auto& kfunc : kdfs)
+ {
+ kdf = Botan::KDF::create(kfunc);
+
+ if(!kdf)
+ {
+ result.test_note("Skipping due to missing KDF: " + kfunc);
+ continue;
+ }
+
+ for(const auto& mfunc : macs)
+ {
+ mac = Botan::MAC::create(mfunc);
+
+ if(!mac)
+ {
+ result.test_note("Skipping due to missing MAC: " + mfunc);
+ continue;
+ }
+
+ Botan::DLIES_Encryptor encryptor(alice, kdf->clone(), mac->clone(), mac_key_len);
+
+ // negative test: other pub key not set
+ Botan::secure_vector plaintext = Test::rng().random_vec(32);
+
+ result.test_throws("encrypt not possible without setting other public key", [&encryptor, &plaintext]()
+ {
+ encryptor.encrypt(plaintext, Test::rng());
+ });
+
+ encryptor.set_other_key(bob.public_value());
+ std::vector ciphertext = encryptor.encrypt(plaintext, Test::rng());
+
+ Botan::DLIES_Decryptor decryptor(bob, kdf->clone(), mac->clone(), mac_key_len);
+
+ // negative test: ciphertext too short
+ result.test_throws("ciphertext too short", [ &decryptor ]()
+ {
+ decryptor.decrypt(std::vector(2));
+ });
+
+ result.test_eq("decryption", decryptor.decrypt(ciphertext), plaintext);
+
+ check_invalid_ciphertexts(result, decryptor, unlock(plaintext), ciphertext);
+ }
+ }
+
+ return result;
+ }
+
+class DLIES_Unit_Tests : public Test
+ {
+ public:
+ std::vector run() override
+ {
+ std::vector results;
+
+ std::vector> fns =
+ {
+ test_xor
+ };
+
+ for(size_t i = 0; i != fns.size(); ++i)
+ {
+ try
+ {
+ results.push_back(fns[ i ]());
+ }
+ catch(std::exception& e)
+ {
+ results.push_back(Test::Result::Failure("DLIES unit tests " + std::to_string(i), e.what()));
+ }
+ }
+
+ return results;
+ }
+ };
+
+BOTAN_REGISTER_TEST("dlies-unit", DLIES_Unit_Tests);
+
#endif
}
--
cgit v1.2.3
From e9d99201b1629d6042387084d2e49025f4f5352c Mon Sep 17 00:00:00 2001
From: René Korthaus
Date: Wed, 13 Jul 2016 11:07:47 +0200
Subject: Update changelog with ANSI X9.23 padding bugfix
---
doc/news.rst | 3 +++
1 file changed, 3 insertions(+)
(limited to 'doc')
diff --git a/doc/news.rst b/doc/news.rst
index 8c4db8b09..2d19dcf3f 100644
--- a/doc/news.rst
+++ b/doc/news.rst
@@ -19,6 +19,9 @@ Version 1.11.31, Not Yet Released
system requires EGD and so the code is now dead weight. If you rely on EGD
support, you should contact the developers by email or GitHub ASAP.
+* Fix a bug in ANSI X9.23 padding mode, which returned one byte more
+ than the given block size (GH #529).
+
Version 1.11.30, 2016-06-19
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
--
cgit v1.2.3
From a24e9a6ca4e2bc68cf8fbc82b8d72d35c7f93a71 Mon Sep 17 00:00:00 2001
From: Jack Lloyd
Date: Fri, 15 Jul 2016 14:37:37 -0400
Subject: Fix undefined behavior in donna128 type
Caused Curve25519 tests to fail when compiled by Clang on ARM, may have
affected other 32-bit platforms.
GH #532
---
doc/news.rst | 4 ++++
src/lib/utils/donna128.h | 18 ++++++++++++------
2 files changed, 16 insertions(+), 6 deletions(-)
(limited to 'doc')
diff --git a/doc/news.rst b/doc/news.rst
index 8c4db8b09..a5f6cba72 100644
--- a/doc/news.rst
+++ b/doc/news.rst
@@ -12,6 +12,10 @@ Version 1.11.31, Not Yet Released
* Add KDF1 from ISO 18033 (GH #483)
+* Fix undefined behavior in Curve25519 on platforms without a native 128-bit
+ integer type. This was known to produce incorrect results on 32-bit ARM
+ under Clang. GH #532
+
* Fixes for FreeBSD (GH #517) and OpenBSD (GH #523)
* Support for getting entropy from EGD is deprecated, and will be removed in
diff --git a/src/lib/utils/donna128.h b/src/lib/utils/donna128.h
index c2a3e0d2e..2a2d1e339 100644
--- a/src/lib/utils/donna128.h
+++ b/src/lib/utils/donna128.h
@@ -23,18 +23,24 @@ class donna128
friend donna128 operator>>(const donna128& x, size_t shift)
{
donna128 z = x;
- const u64bit carry = z.h << (64 - shift);
- z.h = (z.h >> shift);
- z.l = (z.l >> shift) | carry;
+ if(shift > 0)
+ {
+ const u64bit carry = z.h << (64 - shift);
+ z.h = (z.h >> shift);
+ z.l = (z.l >> shift) | carry;
+ }
return z;
}
friend donna128 operator<<(const donna128& x, size_t shift)
{
donna128 z = x;
- const u64bit carry = z.l >> (64 - shift);
- z.l = (z.l << shift);
- z.h = (z.h << shift) | carry;
+ if(shift > 0)
+ {
+ const u64bit carry = z.l >> (64 - shift);
+ z.l = (z.l << shift);
+ z.h = (z.h << shift) | carry;
+ }
return z;
}
--
cgit v1.2.3
From 93922f20f04058ec624f7db3c74d8aa5a3d06440 Mon Sep 17 00:00:00 2001
From: Jack Lloyd
Date: Thu, 30 Jun 2016 13:15:30 -0400
Subject: Add Stateful_RNG
Handles fork checking for HMAC_RNG and HMAC_DRBG
AutoSeeded_RNG change - switch to HMAC_DRBG as default.
Start removing the io buffer from entropy poller.
Update default RNG poll bits to 256.
Fix McEliece test, was using wrong RNG API.
Update docs.
---
doc/manual/rng.rst | 133 ++++++++-------------
src/build-data/buildh.in | 15 ++-
src/build-data/policy/bsi.txt | 1 -
src/build-data/policy/modern.txt | 2 +-
src/cli/speed.cpp | 6 +-
.../entropy/darwin_secrandom/darwin_secrandom.cpp | 6 +-
.../entropy/darwin_secrandom/darwin_secrandom.h | 2 +
src/lib/entropy/dev_random/dev_random.cpp | 75 ++++++++----
src/lib/entropy/dev_random/dev_random.h | 6 +-
src/lib/prov/tpm/tpm.h | 5 +-
src/lib/rng/auto_rng.h | 47 ++++++++
src/lib/rng/auto_rng/auto_rng.h | 45 -------
src/lib/rng/auto_rng/info.txt | 9 --
src/lib/rng/hmac_drbg/hmac_drbg.cpp | 14 ++-
src/lib/rng/hmac_drbg/hmac_drbg.h | 10 +-
src/lib/rng/hmac_rng/hmac_rng.cpp | 109 ++++++-----------
src/lib/rng/hmac_rng/hmac_rng.h | 14 ++-
src/lib/rng/rng.cpp | 59 +++++----
src/lib/rng/rng.h | 46 ++++---
src/tests/test_mceliece.cpp | 2 +-
src/tests/test_rng.cpp | 51 +++-----
21 files changed, 320 insertions(+), 337 deletions(-)
create mode 100644 src/lib/rng/auto_rng.h
delete mode 100644 src/lib/rng/auto_rng/auto_rng.h
delete mode 100644 src/lib/rng/auto_rng/info.txt
(limited to 'doc')
diff --git a/doc/manual/rng.rst b/doc/manual/rng.rst
index 300570c3a..7eb229a5e 100644
--- a/doc/manual/rng.rst
+++ b/doc/manual/rng.rst
@@ -3,108 +3,77 @@
Random Number Generators
========================================
-The random number generators provided in Botan are meant for creating
-keys, IVs, padding, nonces, and anything else that requires 'random'
-data. It is important to remember that the output of these classes
-will vary, even if they are supplied with the same seed (ie, two
-``Randpool`` objects with similar initial states will not produce the
-same output, because the value of high resolution timers is added to
-the state at various points).
-
-To create a random number generator, instantiate a ``AutoSeeded_RNG``
-object. This object will handle choosing the right algorithms from the
-set of enabled ones and doing seeding using OS specific
-routines. The main service a RandomNumberGenerator provides is, of
-course, random numbers:
+The base class ``RandomNumberGenerator`` is in the header ``botan/rng.h``.
-.. cpp:function:: byte RandomNumberGenerator::next_byte()
+The major interfaces are
+
+.. cpp:function:: void RandomNumberGenerator::randomize(byte* output_array, size_t length)
- Generates a single random byte and returns it
+ Places *length* random bytes into the provided buffer.
-.. cpp:function:: void RandomNumberGenerator::randomize(byte* data, size_t length)
+.. cpp:function:: void RandomNumberGenerator::add_entropy(const byte* data, size_t length)
- Places *length* bytes into the array pointed to by *data*
+ Incorporates provided data into the state of the PRNG, if at all
+ possible. This works for most RNG types, including the system and
+ TPM RNGs. But if the RNG doesn't support this operation, the data is
+ dropped, no error is indicated.
-To ensure good quality output, a PRNG needs to be seeded with truly
-random data. Normally this is done for you. However it may happen that
-your application has access to data that is potentially unpredictable
-to an attacker. If so, use
+.. cpp:function:: void RandomNumberGenerator::randomize_with_input(byte* data, size_t length, \
+ const byte* ad, size_t ad_len)
-.. cpp:function:: void RandomNumberGenerator::add_entropy(const byte* data, \
- size_t length)
+ Like randomize, but first incorporates the additional input field
+ into the state of the RNG. The additional input could be anything which
+ parameterizes this request.
-which incorporates the data into the current randomness state. Don't
-worry about filtering the data or doing any kind of cryptographic
-preprocessing (such as hashing); the RNG objects in botan are designed
-such that you can feed them any arbitrary non-random or even
-maliciously chosen data - as long as at some point some of the seed
-data was good the output will be secure.
+.. cpp:function:: byte RandomNumberGenerator::next_byte()
+ Generates a single random byte and returns it. Note that calling this
+ function several times is much slower than calling ``randomize`` once
+ to produce multiple bytes at a time.
-Implementation Notes
+RNG Types
----------------------------------------
-Randpool
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+The following RNG types are included
+
+HMAC_DRBG
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+HMAC DRBG is a random number generator designed by NIST and specified
+in SP 800-90A. It can be instantiated with any hash function but is
+typically used with SHA-256, SHA-384, or SHA-512.
-``Randpool`` is the primary PRNG within Botan. In recent versions all
-uses of it have been wrapped by an implementation of the X9.31 PRNG
-(see below). If for some reason you should have cause to create a PRNG
-instead of using the "global" one owned by the library, it would be
-wise to consider the same on the grounds of general caution; while
-``Randpool`` is designed with known attacks and PRNG weaknesses in
-mind, it is not an standard/official PRNG. The remainder of this
-section is a (fairly technical, though high-level) description of the
-algorithms used in this PRNG. Unless you have a specific interest in
-this subject, the rest of this section might prove somewhat
-uninteresting.
-
-``Randpool`` has an internal state called pool, which is 512 bytes
-long. This is where entropy is mixed into and extracted from. There is also a
-small output buffer (called buffer), which holds the data which has already
-been generated but has just not been output yet.
-
-It is based around a MAC and a block cipher (which are currently
-HMAC(SHA-256) and AES-256). Where a specific size is mentioned, it
-should be taken as a multiple of the cipher's block size. For example,
-if a 256-bit block cipher were used instead of AES, all the sizes
-internally would double. Every time some new output is needed, we
-compute the MAC of a counter and a high resolution timer. The
-resulting MAC is XORed into the output buffer (wrapping as needed),
-and the output buffer is then encrypted with AES, producing 16 bytes
-of output.
-
-After 8 blocks (or 128 bytes) have been produced, we mix the pool. To
-do this, we first rekey both the MAC and the cipher; the new MAC key
-is the MAC of the current pool under the old MAC key, while the new
-cipher key is the MAC of the current pool under the just-chosen MAC
-key. We then encrypt the entire pool in CBC mode, using the current
-(unused) output buffer as the IV. We then generate a new output
-buffer, using the mechanism described in the previous paragraph.
-
-To add randomness to the PRNG, we compute the MAC of the input and XOR
-the output into the start of the pool. Then we remix the pool and
-produce a new output buffer. The initial MAC operation should make it
-very hard for chosen inputs to harm the security of ``Randpool``, and
-as HMAC should be able to hold roughly 256 bits of state, it is
-unlikely that we are wasting much input entropy (or, if we are, it
-doesn't matter, because we have a very abundant supply).
+HMAC DRBG seems to be the most conservative generator of the NIST
+approved options.
+
+System_RNG
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+In ``system_rng.h``, objects of ``System_RNG`` reference a single
+(process global) reference to the system PRNG (/dev/urandom or
+CryptGenRandom).
+
+AutoSeeded_RNG
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+This instantiates a new instance of a userspace PRNG, seeds it with
+a default entropy pool.
ANSI X9.31
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+This generator is deprecated and will be removed in a future release.
+
``ANSI_X931_PRNG`` is the standard issue X9.31 Appendix A.2.4 PRNG,
though using AES-256 instead of 3DES as the block cipher. This PRNG
implementation has been checked against official X9.31 test vectors.
-Internally, the PRNG holds a pointer to another PRNG (typically
-Randpool). This internal PRNG generates the key and seed used by the
-X9.31 algorithm, as well as the date/time vectors. Each time an X9.31
-PRNG object receives entropy, it passes it along to the PRNG it is
-holding, and then pulls out some random bits to generate a new key and
-seed. This PRNG considers itself seeded as soon as the internal PRNG
-is seeded.
-
+Internally, the PRNG holds a pointer to another RNG object. This
+internal PRNG generates the key and seed used by the X9.31 algorithm,
+as well as the date/time vectors. Each time an X9.31 PRNG object
+receives entropy, it passes it along to the PRNG it is holding, and
+then pulls out some random bits to generate a new key and seed. This
+PRNG considers itself seeded as soon as the internal PRNG is seeded.
Entropy Sources
---------------------------------
diff --git a/src/build-data/buildh.in b/src/build-data/buildh.in
index bd8cb6899..82a4ecd50 100644
--- a/src/build-data/buildh.in
+++ b/src/build-data/buildh.in
@@ -99,13 +99,20 @@
/*
* RNGs will automatically poll the system for additional seed material
-* after producing this many bytes of output.
+* after producing this many bytes of output. Set to zero to disable
+* automatic reseeding.
*/
-#define BOTAN_RNG_MAX_OUTPUT_BEFORE_RESEED 4096
-#define BOTAN_RNG_RESEED_POLL_BITS 128
+#define BOTAN_RNG_MAX_OUTPUT_BEFORE_RESEED 16384
+#define BOTAN_RNG_RESEED_POLL_BITS 256
#define BOTAN_RNG_AUTO_RESEED_TIMEOUT std::chrono::milliseconds(10)
#define BOTAN_RNG_RESEED_DEFAULT_TIMEOUT std::chrono::milliseconds(50)
-#define BOTAN_AUTO_RNG_DRBG_HASH_FUNCTION "SHA-384"
+
+/**
+* Controls how AutoSeeded_RNG is instantiated
+*/
+#define BOTAN_AUTO_RNG_DRBG HMAC_DRBG
+#define BOTAN_AUTO_RNG_HASH "SHA-256"
+#define BOTAN_AUTO_RNG_ENTROPY_TARGET 256
/*
* Specifies (in order) the list of entropy sources that will be used
diff --git a/src/build-data/policy/bsi.txt b/src/build-data/policy/bsi.txt
index 5e3c5b921..2ae2ac3b2 100644
--- a/src/build-data/policy/bsi.txt
+++ b/src/build-data/policy/bsi.txt
@@ -41,7 +41,6 @@ eckcdsa
ecdh
# rng
-auto_rng
hmac_rng
hmac_drbg
diff --git a/src/build-data/policy/modern.txt b/src/build-data/policy/modern.txt
index f0b6934f0..5a8a2f126 100644
--- a/src/build-data/policy/modern.txt
+++ b/src/build-data/policy/modern.txt
@@ -38,8 +38,8 @@ eme_oaep
emsa_pssr
emsa1
-auto_rng
hmac_rng
+hmac_drbg
ffi
diff --git a/src/cli/speed.cpp b/src/cli/speed.cpp
index c6149bf68..1fc0d7343 100644
--- a/src/cli/speed.cpp
+++ b/src/cli/speed.cpp
@@ -427,12 +427,10 @@ class Speed final : public Command
#if defined(BOTAN_HAS_HMAC_DRBG)
for(std::string hash : { "SHA-256", "SHA-384", "SHA-512" })
{
-
- auto hmac = Botan::MessageAuthenticationCode::create("HMAC(" + hash + ")");
- Botan::HMAC_DRBG hmac_drbg(hmac->clone());
+ Botan::HMAC_DRBG hmac_drbg(hash);
bench_rng(hmac_drbg, hmac_drbg.name(), msec, buf_size);
- Botan::HMAC_RNG hmac_rng(hmac->clone(), hmac->clone());
+ Botan::HMAC_RNG hmac_rng(hash);
bench_rng(hmac_rng, hmac_rng.name(), msec, buf_size);
}
#endif
diff --git a/src/lib/entropy/darwin_secrandom/darwin_secrandom.cpp b/src/lib/entropy/darwin_secrandom/darwin_secrandom.cpp
index 0a6b85955..7dde17155 100644
--- a/src/lib/entropy/darwin_secrandom/darwin_secrandom.cpp
+++ b/src/lib/entropy/darwin_secrandom/darwin_secrandom.cpp
@@ -16,11 +16,11 @@ namespace Botan {
*/
void Darwin_SecRandom::poll(Entropy_Accumulator& accum)
{
- secure_vector& buf = accum.get_io_buf(BOTAN_SYSTEM_RNG_POLL_REQUEST);
+ m_io_buf.resize(BOTAN_SYSTEM_RNG_POLL_REQUEST);
- if(0 == SecRandomCopyBytes(kSecRandomDefault, buf.size(), buf.data()))
+ if(0 == SecRandomCopyBytes(kSecRandomDefault, m_io_buf.size(), m_io_buf.data()))
{
- accum.add(buf.data(), buf.size(), BOTAN_ENTROPY_ESTIMATE_STRONG_RNG);
+ accum.add(m_io_buf.data(), m_io_buf.size(), BOTAN_ENTROPY_ESTIMATE_STRONG_RNG);
}
}
diff --git a/src/lib/entropy/darwin_secrandom/darwin_secrandom.h b/src/lib/entropy/darwin_secrandom/darwin_secrandom.h
index 09cdc208d..267d177f0 100644
--- a/src/lib/entropy/darwin_secrandom/darwin_secrandom.h
+++ b/src/lib/entropy/darwin_secrandom/darwin_secrandom.h
@@ -21,6 +21,8 @@ class Darwin_SecRandom final : public Entropy_Source
std::string name() const override { return "darwin_secrandom"; }
void poll(Entropy_Accumulator& accum) override;
+ private:
+ secure_vector m_io_buf;
};
}
diff --git a/src/lib/entropy/dev_random/dev_random.cpp b/src/lib/entropy/dev_random/dev_random.cpp
index aca161d64..ff746f34e 100644
--- a/src/lib/entropy/dev_random/dev_random.cpp
+++ b/src/lib/entropy/dev_random/dev_random.cpp
@@ -6,6 +6,7 @@
*/
#include
+#include
#include
#include
@@ -31,15 +32,39 @@ Device_EntropySource::Device_EntropySource(const std::vector& fsnam
const int flags = O_RDONLY | O_NONBLOCK | O_NOCTTY;
+ m_max_fd = 0;
+
for(auto fsname : fsnames)
{
- fd_type fd = ::open(fsname.c_str(), flags);
+ int fd = ::open(fsname.c_str(), flags);
- if(fd >= 0 && fd < FD_SETSIZE)
- m_devices.push_back(fd);
- else if(fd >= 0)
- ::close(fd);
+ if(fd > 0)
+ {
+ if(fd > FD_SETSIZE)
+ {
+ ::close(fd);
+ throw Exception("Open of OS RNG succeeded but fd is too large for fd_set");
+ }
+
+ m_dev_fds.push_back(fd);
+ m_max_fd = std::max(m_max_fd, fd);
+ }
+ else
+ {
+ /*
+ ENOENT or EACCES is normal as some of the named devices may not exist
+ on this system. But any other errno value probably indicates
+ either a bug in the application or file descriptor exhaustion.
+ */
+ if(errno != ENOENT && errno != EACCES)
+ {
+ throw Exception("Opening OS RNG device failed with errno " +
+ std::to_string(errno));
+ }
+ }
}
+
+ m_io_buf.resize(BOTAN_SYSTEM_RNG_POLL_REQUEST);
}
/**
@@ -47,8 +72,11 @@ Device_EntropySource destructor: close all open devices
*/
Device_EntropySource::~Device_EntropySource()
{
- for(size_t i = 0; i != m_devices.size(); ++i)
- ::close(m_devices[i]);
+ for(int fd : m_dev_fds)
+ {
+ // ignoring return value here, can't throw in destructor anyway
+ ::close(fd);
+ }
}
/**
@@ -56,35 +84,36 @@ Device_EntropySource::~Device_EntropySource()
*/
void Device_EntropySource::poll(Entropy_Accumulator& accum)
{
- if(m_devices.empty())
+ if(m_dev_fds.empty())
return;
- fd_type max_fd = m_devices[0];
fd_set read_set;
FD_ZERO(&read_set);
- for(size_t i = 0; i != m_devices.size(); ++i)
+
+ for(int dev_fd : m_dev_fds)
{
- FD_SET(m_devices[i], &read_set);
- max_fd = std::max(m_devices[i], max_fd);
+ FD_SET(dev_fd, &read_set);
}
struct ::timeval timeout;
-
timeout.tv_sec = (BOTAN_SYSTEM_RNG_POLL_TIMEOUT_MS / 1000);
timeout.tv_usec = (BOTAN_SYSTEM_RNG_POLL_TIMEOUT_MS % 1000) * 1000;
- if(::select(max_fd + 1, &read_set, nullptr, nullptr, &timeout) < 0)
- return;
-
- secure_vector& buf = accum.get_io_buf(BOTAN_SYSTEM_RNG_POLL_REQUEST);
-
- for(size_t i = 0; i != m_devices.size(); ++i)
+ if(::select(m_max_fd + 1, &read_set, nullptr, nullptr, &timeout) > 0)
{
- if(FD_ISSET(m_devices[i], &read_set))
+ for(int dev_fd : m_dev_fds)
{
- const ssize_t got = ::read(m_devices[i], buf.data(), buf.size());
- if(got > 0)
- accum.add(buf.data(), got, BOTAN_ENTROPY_ESTIMATE_STRONG_RNG);
+ if(FD_ISSET(dev_fd, &read_set))
+ {
+ const ssize_t got = ::read(dev_fd, m_io_buf.data(), m_io_buf.size());
+
+ if(got > 0)
+ {
+ accum.add(m_io_buf.data(),
+ static_cast(got),
+ BOTAN_ENTROPY_ESTIMATE_STRONG_RNG);
+ }
+ }
}
}
}
diff --git a/src/lib/entropy/dev_random/dev_random.h b/src/lib/entropy/dev_random/dev_random.h
index 1f29b2f64..05b36f3eb 100644
--- a/src/lib/entropy/dev_random/dev_random.h
+++ b/src/lib/entropy/dev_random/dev_random.h
@@ -25,10 +25,12 @@ class Device_EntropySource final : public Entropy_Source
void poll(Entropy_Accumulator& accum) override;
Device_EntropySource(const std::vector& fsnames);
+
~Device_EntropySource();
private:
- typedef int fd_type;
- std::vector m_devices;
+ secure_vector m_io_buf;
+ std::vector m_dev_fds;
+ int m_max_fd;
};
}
diff --git a/src/lib/prov/tpm/tpm.h b/src/lib/prov/tpm/tpm.h
index 15bc216ab..b8093518c 100644
--- a/src/lib/prov/tpm/tpm.h
+++ b/src/lib/prov/tpm/tpm.h
@@ -1,3 +1,4 @@
+
/*
* TPM 1.2 interface
* (C) 2015 Jack Lloyd
@@ -71,7 +72,7 @@ class BOTAN_DLL TPM_Context
TSS_HTPM m_tpm;
};
-class BOTAN_DLL TPM_RNG : public RandomNumberGenerator
+class BOTAN_DLL TPM_RNG : public Hardware_RNG
{
public:
TPM_RNG(TPM_Context& ctx) : m_ctx(ctx) {}
@@ -90,7 +91,7 @@ class BOTAN_DLL TPM_RNG : public RandomNumberGenerator
bool is_seeded() const override { return true; }
- void clear() const override {}
+ void clear() override {}
private:
TPM_Context& m_ctx;
diff --git a/src/lib/rng/auto_rng.h b/src/lib/rng/auto_rng.h
new file mode 100644
index 000000000..b51390ae2
--- /dev/null
+++ b/src/lib/rng/auto_rng.h
@@ -0,0 +1,47 @@
+/*
+* Auto Seeded RNG
+* (C) 2008 Jack Lloyd
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#ifndef BOTAN_AUTO_SEEDING_RNG_H__
+#define BOTAN_AUTO_SEEDING_RNG_H__
+
+#include
+
+namespace Botan {
+
+class BOTAN_DLL AutoSeeded_RNG final : public RandomNumberGenerator
+ {
+ public:
+ void randomize(byte out[], size_t len) override;
+
+ void randomize_with_input(byte output[], size_t output_len,
+ const byte input[], size_t input_len) override;
+
+ bool is_seeded() const override { return m_rng->is_seeded(); }
+
+ void clear() override { m_rng->clear(); m_counter = 0; }
+
+ std::string name() const override { return m_rng->name(); }
+
+ size_t reseed_with_sources(Entropy_Sources& srcs,
+ size_t poll_bits,
+ std::chrono::milliseconds poll_timeout) override
+ {
+ return m_rng->reseed_with_sources(srcs, poll_bits, poll_timeout);
+ }
+
+ void add_entropy(const byte in[], size_t len) override
+ { m_rng->add_entropy(in, len); }
+
+ AutoSeeded_RNG(size_t bytes_before_reseed = BOTAN_RNG_MAX_OUTPUT_BEFORE_RESEED);
+ private:
+ std::unique_ptr m_rng;
+ uint32_t m_counter = 0;
+ };
+
+}
+
+#endif
diff --git a/src/lib/rng/auto_rng/auto_rng.h b/src/lib/rng/auto_rng/auto_rng.h
deleted file mode 100644
index 72ea88d3e..000000000
--- a/src/lib/rng/auto_rng/auto_rng.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
-* Auto Seeded RNG
-* (C) 2008 Jack Lloyd
-*
-* Botan is released under the Simplified BSD License (see license.txt)
-*/
-
-#ifndef BOTAN_AUTO_SEEDING_RNG_H__
-#define BOTAN_AUTO_SEEDING_RNG_H__
-
-#include
-#include
-
-namespace Botan {
-
-class AutoSeeded_RNG : public RandomNumberGenerator
- {
- public:
- void randomize(byte out[], size_t len) override
- { m_rng->randomize(out, len); }
-
- bool is_seeded() const override { return m_rng->is_seeded(); }
-
- void clear() override { m_rng->clear(); }
-
- std::string name() const override { return m_rng->name(); }
-
- size_t reseed_with_sources(Entropy_Sources& srcs,
- size_t poll_bits,
- std::chrono::milliseconds poll_timeout) override
- {
- return m_rng->reseed_with_sources(srcs, poll_bits, poll_timeout);
- }
-
- void add_entropy(const byte in[], size_t len) override
- { m_rng->add_entropy(in, len); }
-
- AutoSeeded_RNG() : m_rng(RandomNumberGenerator::make_rng()) {}
- private:
- std::unique_ptr m_rng;
- };
-
-}
-
-#endif
diff --git a/src/lib/rng/auto_rng/info.txt b/src/lib/rng/auto_rng/info.txt
deleted file mode 100644
index 4f48f484b..000000000
--- a/src/lib/rng/auto_rng/info.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-define AUTO_SEEDING_RNG 20131128
-
-
-hmac_rng
-hmac
-sha2_32
-sha2_64
-#dev_random|cryptoapi_rng|unix_procs|proc_walk
-
diff --git a/src/lib/rng/hmac_drbg/hmac_drbg.cpp b/src/lib/rng/hmac_drbg/hmac_drbg.cpp
index 201a9f39b..6fdd7daf9 100644
--- a/src/lib/rng/hmac_drbg/hmac_drbg.cpp
+++ b/src/lib/rng/hmac_drbg/hmac_drbg.cpp
@@ -10,9 +10,14 @@
namespace Botan {
-HMAC_DRBG::HMAC_DRBG(const std::string& hmac_hash) :
- HMAC_DRBG(hmac_hash, BOTAN_RNG_MAX_OUTPUT_BEFORE_RESEED)
- {}
+HMAC_DRBG::HMAC_DRBG(MessageAuthenticationCode* hmac,
+ size_t max_bytes_before_reseed) :
+ Stateful_RNG(max_bytes_before_reseed),
+ m_mac(hmac)
+ {
+ m_V.resize(m_mac->output_length());
+ clear();
+ }
HMAC_DRBG::HMAC_DRBG(const std::string& hmac_hash,
size_t max_bytes_before_reseed) :
@@ -27,12 +32,13 @@ HMAC_DRBG::HMAC_DRBG(const std::string& hmac_hash,
}
m_V.resize(m_mac->output_length());
-
clear();
}
void HMAC_DRBG::clear()
{
+ Stateful_RNG::clear();
+
for(size_t i = 0; i != m_V.size(); ++i)
m_V[i] = 0x01;
m_mac->set_key(std::vector(m_mac->output_length(), 0x00));
diff --git a/src/lib/rng/hmac_drbg/hmac_drbg.h b/src/lib/rng/hmac_drbg/hmac_drbg.h
index f52ae9de1..8ee598470 100644
--- a/src/lib/rng/hmac_drbg/hmac_drbg.h
+++ b/src/lib/rng/hmac_drbg/hmac_drbg.h
@@ -19,10 +19,14 @@ namespace Botan {
class BOTAN_DLL HMAC_DRBG final : public Stateful_RNG
{
public:
- HMAC_DRBG(const std::string& hmac_hash);
-
+ /**
+ * Initialize an HMAC_DRBG instance with the given hash function
+ */
HMAC_DRBG(const std::string& hmac_hash,
- size_t max_bytes_before_reseed);
+ size_t max_bytes_before_reseed = BOTAN_RNG_MAX_OUTPUT_BEFORE_RESEED);
+
+ HMAC_DRBG(MessageAuthenticationCode* hmac,
+ size_t max_bytes_before_reseed = BOTAN_RNG_MAX_OUTPUT_BEFORE_RESEED);
std::string name() const override;
diff --git a/src/lib/rng/hmac_rng/hmac_rng.cpp b/src/lib/rng/hmac_rng/hmac_rng.cpp
index 7a9e4dbc5..410e3040a 100644
--- a/src/lib/rng/hmac_rng/hmac_rng.cpp
+++ b/src/lib/rng/hmac_rng/hmac_rng.cpp
@@ -9,15 +9,35 @@
#include
#include
#include
-#include
namespace Botan {
+HMAC_RNG::HMAC_RNG(const std::string& hash, size_t max_before_reseed) :
+ Stateful_RNG(max_before_reseed)
+ {
+ m_extractor = MAC::create("HMAC(" + hash + ")");
+ if(!m_extractor)
+ throw Invalid_Argument("HMAC_RNG hash not found");
+
+ m_prf.reset(m_extractor->clone());
+
+ if(!m_prf->valid_keylength(m_extractor->output_length()) ||
+ !m_extractor->valid_keylength(m_prf->output_length()))
+ {
+ throw Invalid_Argument("HMAC_RNG: Bad algo combination " +
+ m_extractor->name() + " and " +
+ m_prf->name());
+ }
+
+ this->clear();
+ }
+
/*
* HMAC_RNG Constructor
*/
HMAC_RNG::HMAC_RNG(MessageAuthenticationCode* extractor,
MessageAuthenticationCode* prf) :
+ Stateful_RNG(BOTAN_RNG_MAX_OUTPUT_BEFORE_RESEED),
m_extractor(extractor), m_prf(prf)
{
if(!m_prf->valid_keylength(m_extractor->output_length()) ||
@@ -33,7 +53,7 @@ HMAC_RNG::HMAC_RNG(MessageAuthenticationCode* extractor,
void HMAC_RNG::clear()
{
- m_collected_entropy_estimate = 0;
+ Stateful_RNG::clear();
m_counter = 0;
// First PRF inputs are all zero, as specified in section 2
@@ -71,7 +91,7 @@ void HMAC_RNG::clear()
void HMAC_RNG::new_K_value(byte label)
{
m_prf->update(m_K);
- m_prf->update_be(m_pid);
+ m_prf->update_be(last_pid());
m_prf->update_be(OS::get_processor_timestamp());
m_prf->update_be(OS::get_system_timestamp_ns());
m_prf->update_be(m_counter++);
@@ -84,76 +104,38 @@ void HMAC_RNG::new_K_value(byte label)
*/
void HMAC_RNG::randomize(byte out[], size_t length)
{
- if(!is_seeded() || m_pid != OS::get_process_id())
- {
- reseed(256);
- if(!is_seeded())
- throw PRNG_Unseeded(name());
- }
-
- const size_t max_per_prf_iter = m_prf->output_length() / 2;
-
- m_output_since_reseed += length;
-
- if(m_output_since_reseed >= BOTAN_RNG_MAX_OUTPUT_BEFORE_RESEED)
- {
- reseed_with_sources(Entropy_Sources::global_sources(),
- BOTAN_RNG_RESEED_POLL_BITS,
- BOTAN_RNG_AUTO_RESEED_TIMEOUT);
- }
+ reseed_check(length);
- /*
- HMAC KDF as described in E-t-E, using a CTXinfo of "rng"
- */
while(length)
{
new_K_value(Running);
- const size_t copied = std::min(length, max_per_prf_iter);
+ const size_t copied = std::min(length, m_prf->output_length());
copy_mem(out, m_K.data(), copied);
out += copied;
length -= copied;
}
+
+ new_K_value(BlockFinished);
}
size_t HMAC_RNG::reseed_with_sources(Entropy_Sources& srcs,
size_t poll_bits,
std::chrono::milliseconds timeout)
{
+ new_K_value(Reseed);
+ m_extractor->update(m_K); // m_K is the PRF output
+
/*
- Using the terminology of E-t-E, XTR is the MAC function (normally
- HMAC) seeded with XTS (below) and we form SKM, the key material, by
- polling as many sources as we think needed to reach our polling
- goal. We then also include feedback of the current PRK so that
- a bad poll doesn't wipe us out.
+ * This ends up calling add_entropy which provides input to the extractor
*/
-
- typedef std::chrono::system_clock clock;
- auto deadline = clock::now() + timeout;
-
- double bits_collected = 0;
-
- Entropy_Accumulator accum([&](const byte in[], size_t in_len, double entropy_estimate) {
- m_extractor->update(in, in_len);
- bits_collected += entropy_estimate;
- return (bits_collected >= poll_bits || clock::now() > deadline);
- });
-
- srcs.poll(accum);
+ size_t bits_collected = Stateful_RNG::reseed_with_sources(srcs, poll_bits, timeout);
/*
- * It is necessary to feed forward poll data. Otherwise, a good poll
- * (collecting a large amount of conditional entropy) followed by a
- * bad one (collecting little) would be unsafe. Do this by
- * generating new PRF outputs using the previous key and feeding
- * them into the extractor function.
+ Now derive the new PRK using everything that has been fed into
+ the extractor, and set the PRF key to that
*/
- new_K_value(Reseed);
- m_extractor->update(m_K); // K is the CTXinfo=reseed PRF output
-
- /* Now derive the new PRK using everything that has been fed into
- the extractor, and set the PRF key to that */
m_prf->set_key(m_extractor->final());
// Now generate a new PRF output to use as the XTS extractor salt
@@ -164,32 +146,17 @@ size_t HMAC_RNG::reseed_with_sources(Entropy_Sources& srcs,
zeroise(m_K);
m_counter = 0;
- m_collected_entropy_estimate =
- std::min(m_collected_entropy_estimate + static_cast(bits_collected),
- m_extractor->output_length() * 8);
-
- m_output_since_reseed = 0;
- m_pid = OS::get_process_id();
-
- return static_cast(bits_collected);
- }
-
-bool HMAC_RNG::is_seeded() const
- {
- return (m_collected_entropy_estimate >= 256);
+ return bits_collected;
}
/*
-* Add user-supplied entropy to the extractor input then reseed
-* to incorporate it into the state
+* Add user-supplied entropy to the extractor input then set remaining
+* output length to for a reseed on next use.
*/
void HMAC_RNG::add_entropy(const byte input[], size_t length)
{
m_extractor->update(input, length);
-
- reseed_with_sources(Entropy_Sources::global_sources(),
- BOTAN_RNG_RESEED_POLL_BITS,
- BOTAN_RNG_RESEED_DEFAULT_TIMEOUT);
+ force_reseed();
}
/*
diff --git a/src/lib/rng/hmac_rng/hmac_rng.h b/src/lib/rng/hmac_rng/hmac_rng.h
index 95ae25e39..f2f8a610d 100644
--- a/src/lib/rng/hmac_rng/hmac_rng.h
+++ b/src/lib/rng/hmac_rng/hmac_rng.h
@@ -24,11 +24,10 @@ namespace Botan {
* Krawczyk's paper), for instance one could use HMAC(SHA-512) as the
* extractor and CMAC(AES-256) as the PRF.
*/
-class BOTAN_DLL HMAC_RNG : public RandomNumberGenerator
+class BOTAN_DLL HMAC_RNG : public Stateful_RNG
{
public:
void randomize(byte buf[], size_t len) override;
- bool is_seeded() const override;
void clear() override;
std::string name() const override;
@@ -44,23 +43,26 @@ class BOTAN_DLL HMAC_RNG : public RandomNumberGenerator
*/
HMAC_RNG(MessageAuthenticationCode* extractor,
MessageAuthenticationCode* prf);
+
+ /**
+ * Use the specified hash for both the extractor and PRF functions
+ */
+ HMAC_RNG(const std::string& hash,
+ size_t max_before_reseed = BOTAN_RNG_MAX_OUTPUT_BEFORE_RESEED);
private:
std::unique_ptr m_extractor;
std::unique_ptr m_prf;
enum HMAC_PRF_Label {
Running,
+ BlockFinished,
Reseed,
ExtractorSeed,
};
void new_K_value(byte label);
- size_t m_collected_entropy_estimate = 0;
- size_t m_output_since_reseed = 0;
-
secure_vector m_K;
u32bit m_counter = 0;
- u32bit m_pid = 0;
};
}
diff --git a/src/lib/rng/rng.cpp b/src/lib/rng/rng.cpp
index 526693561..8144ac293 100644
--- a/src/lib/rng/rng.cpp
+++ b/src/lib/rng/rng.cpp
@@ -6,12 +6,18 @@
*/
#include
-#include
#include
#include
#include
#include
-#include
+
+#if defined(BOTAN_HAS_HMAC_DRBG)
+ #include
+#endif
+
+#if defined(BOTAN_HAS_HMAC_RNG)
+ #include
+#endif
namespace Botan {
@@ -50,9 +56,15 @@ size_t RandomNumberGenerator::reseed_with_sources(Entropy_Sources& srcs,
return bits_collected;
}
-Stateful_RNG::Stateful_RNG(size_t bytes_before_reseed) :
- m_max_bytes_before_reseed_required(bytes_before_reseed)
+Stateful_RNG::Stateful_RNG(size_t bytes_before_reseed) : m_bytes_before_reseed(bytes_before_reseed)
+ {
+ }
+
+void Stateful_RNG::clear()
{
+ m_successful_initialization = false;
+ m_bytes_since_reseed = 0;
+ m_last_pid = 0;
}
size_t Stateful_RNG::reseed_with_sources(Entropy_Sources& srcs,
@@ -81,10 +93,9 @@ void Stateful_RNG::reseed_check(size_t bytes_requested)
{
this->reseed(BOTAN_RNG_RESEED_POLL_BITS);
}
- else if(m_max_bytes_before_reseed_required > 0 &&
- m_bytes_since_reseed >= m_max_bytes_before_reseed_required)
+ else if(m_bytes_before_reseed > 0 && m_bytes_since_reseed >= m_bytes_before_reseed)
{
- this->reseed_with_timeout(BOTAN_RNG_AUTO_RESEED_POLL_BITS,
+ this->reseed_with_timeout(BOTAN_RNG_RESEED_POLL_BITS,
BOTAN_RNG_AUTO_RESEED_TIMEOUT);
}
@@ -112,8 +123,10 @@ RandomNumberGenerator* RandomNumberGenerator::make_rng()
AutoSeeded_RNG::AutoSeeded_RNG(size_t max_bytes_before_reseed)
{
- m_rng.reset(new HMAC_DRBG(BOTAN_AUTO_RNG_DRBG_HASH_FUNCTION, max_bytes_before_reseed));
- size_t bits = m_rng->reseed(384);
+ m_rng.reset(new BOTAN_AUTO_RNG_DRBG(BOTAN_AUTO_RNG_HASH, max_bytes_before_reseed));
+
+ size_t bits = m_rng->reseed(BOTAN_AUTO_RNG_ENTROPY_TARGET);
+
if(!m_rng->is_seeded())
{
throw Exception("AutoSeeded_RNG failed to gather enough entropy only got " +
@@ -124,24 +137,22 @@ AutoSeeded_RNG::AutoSeeded_RNG(size_t max_bytes_before_reseed)
void AutoSeeded_RNG::randomize(byte output[], size_t output_len)
{
/*
- This data is not secret so skipping a vector/secure_vector allows
- avoiding an allocation.
+ Form additional input which is provided to the PRNG implementation
+ to paramaterize the KDF output.
*/
- typedef std::chrono::high_resolution_clock clock;
-
- byte nonce_buf[16] = { 0 };
- const uint32_t cur_ctr = m_counter++;
- const uint32_t cur_pid = OS::get_process_id();
- const uint64_t cur_time = clock::now().time_since_epoch().count();
-
- store_le(cur_ctr, nonce_buf);
- store_le(cur_pid, nonce_buf + 4);
- store_le(cur_time, nonce_buf + 8);
+ byte additional_input[24] = { 0 };
+ store_le(OS::get_system_timestamp_ns(), additional_input);
+ store_le(OS::get_processor_timestamp(), additional_input + 8);
+ store_le(OS::get_process_id(), additional_input + 16);
+ store_le(m_counter++, additional_input + 20);
- m_rng->randomize_with_input(output, output_len,
- nonce_buf, sizeof(nonce_buf));
+ randomize_with_input(output, output_len, additional_input, sizeof(additional_input));
+ }
- ++m_counter;
+void AutoSeeded_RNG::randomize_with_input(byte output[], size_t output_len,
+ const byte ad[], size_t ad_len)
+ {
+ m_rng->randomize_with_input(output, output_len, ad, ad_len);
}
}
diff --git a/src/lib/rng/rng.h b/src/lib/rng/rng.h
index 2e08ce553..d5fae0261 100644
--- a/src/lib/rng/rng.h
+++ b/src/lib/rng/rng.h
@@ -154,7 +154,7 @@ class BOTAN_DLL RandomNumberGenerator
* bytes have been output.
*
* Not implemented by RNGs which access an external RNG, such as the
-* system PRNG or an hardware RNG.
+* system PRNG or a hardware RNG.
*/
class BOTAN_DLL Stateful_RNG : public RandomNumberGenerator
{
@@ -182,15 +182,36 @@ class BOTAN_DLL Stateful_RNG : public RandomNumberGenerator
protected:
void reseed_check(size_t bytes_requested);
+ void clear() override;
+
+ /**
+ * Mark state as requiring a reseed on next use
+ */
+ void force_reseed() { m_bytes_since_reseed = m_bytes_before_reseed; }
+
+ uint32_t last_pid() const { return m_last_pid; }
+
+ mutable std::mutex m_mutex;
+
private:
- const size_t m_max_bytes_before_reseed_required;
+ const size_t m_bytes_before_reseed;
size_t m_bytes_since_reseed = 0;
uint32_t m_last_pid = 0;
bool m_successful_initialization = false;
};
+/**
+* Convenience typedef
+*/
typedef RandomNumberGenerator RNG;
+/**
+* Hardware RNG has no members but exists to tag hardware RNG types
+*/
+class BOTAN_DLL Hardware_RNG : public RandomNumberGenerator
+ {
+ };
+
/**
* Null/stub RNG - fails if you try to use it for anything
* This is not generally useful except for in certain tests
@@ -212,7 +233,6 @@ class BOTAN_DLL Null_RNG final : public RandomNumberGenerator
std::string name() const override { return "Null_RNG"; }
};
-
/**
* Wraps access to a RNG in a mutex
*/
@@ -225,20 +245,6 @@ class BOTAN_DLL Serialized_RNG final : public RandomNumberGenerator
m_rng->randomize(out, len);
}
- void randomize_with_input(byte output[], size_t output_length,
- const byte input[], size_t input_length) override
- {
- std::lock_guard lock(m_mutex);
- m_rng->randomize_with_input(output, output_length,
- input, input_length);
- }
-
- void add_entropy(const byte in[], size_t len) override
- {
- std::lock_guard lock(m_mutex);
- m_rng->add_entropy(in, len);
- }
-
bool is_seeded() const override
{
std::lock_guard lock(m_mutex);
@@ -265,6 +271,12 @@ class BOTAN_DLL Serialized_RNG final : public RandomNumberGenerator
return m_rng->reseed_with_sources(src, bits, msec);
}
+ void add_entropy(const byte in[], size_t len) override
+ {
+ std::lock_guard lock(m_mutex);
+ m_rng->add_entropy(in, len);
+ }
+
Serialized_RNG() : m_rng(RandomNumberGenerator::make_rng()) {}
explicit Serialized_RNG(RandomNumberGenerator* rng) : m_rng(rng) {}
private:
diff --git a/src/tests/test_mceliece.cpp b/src/tests/test_mceliece.cpp
index 8c0ad4564..8658bf5e6 100644
--- a/src/tests/test_mceliece.cpp
+++ b/src/tests/test_mceliece.cpp
@@ -77,7 +77,7 @@ class McEliece_Keygen_Encrypt_Test : public Text_Based_Test
result.test_eq("private key fingerprint", hash_bytes(mce_priv.pkcs8_private_key()), fprint_priv);
rng.clear();
- rng.add_entropy(encrypt_seed.data(), encrypt_seed.size());
+ rng.initialize_with(encrypt_seed.data(), encrypt_seed.size());
try
{
diff --git a/src/tests/test_rng.cpp b/src/tests/test_rng.cpp
index 7f1c1f123..d8c10bf55 100644
--- a/src/tests/test_rng.cpp
+++ b/src/tests/test_rng.cpp
@@ -21,37 +21,10 @@ namespace {
Botan::RandomNumberGenerator* get_rng(const std::string& algo_str, const std::vector& ikm)
{
- class AllOnce_RNG : public Fixed_Output_RNG
- {
- public:
- explicit AllOnce_RNG(const std::vector& in) : Fixed_Output_RNG(in) {}
-
- Botan::secure_vector random_vec(size_t) override
- {
- Botan::secure_vector vec(this->remaining());
- this->randomize(vec.data(), vec.size());
- return vec;
- }
- };
-
const std::vector algo_name = Botan::parse_algorithm_name(algo_str);
const std::string rng_name = algo_name[0];
-#if defined(BOTAN_HAS_HMAC_DRBG)
- if(rng_name == "HMAC_DRBG")
- {
- auto mac = Botan::MessageAuthenticationCode::create("HMAC(" + algo_name[1] + ")");
-
- if(!mac)
- {
- return nullptr;
- }
-
- return new Botan::HMAC_DRBG(mac.release(), new AllOnce_RNG(ikm));
- }
-
-#endif
#if defined(BOTAN_HAS_X931_RNG)
if(rng_name == "X9.31-RNG")
@@ -110,7 +83,8 @@ class HMAC_DRBG_Tests : public Text_Based_Test
{
public:
HMAC_DRBG_Tests() : Text_Based_Test("hmac_drbg.vec",
- {"EntropyInput", "EntropyInputReseed", "Out"}) {}
+ {"EntropyInput", "EntropyInputReseed", "Out"},
+ {"AdditionalInput1", "AdditionalInput2"}) {}
Test::Result run_one_test(const std::string& algo, const VarMap& vars) override
{
@@ -118,23 +92,30 @@ class HMAC_DRBG_Tests : public Text_Based_Test
const std::vector reseed_input = get_req_bin(vars, "EntropyInputReseed");
const std::vector expected = get_req_bin(vars, "Out");
- Test::Result result(algo);
+ const std::vector ad1 = get_opt_bin(vars, "AdditionalInput1");
+ const std::vector ad2 = get_opt_bin(vars, "AdditionalInput2");
- std::unique_ptr rng(get_rng(algo, seed_input));
- if(!rng)
+ Test::Result result("HMAC_DRBG(" + algo + ")");
+
+ auto mac = Botan::MessageAuthenticationCode::create("HMAC(" + algo + ")");
+ if(!mac)
{
- result.note_missing("RNG " + algo);
+ result.note_missing("HMAC(" + algo + ")");
return result;
}
- rng->reseed(0); // force initialization
+ std::unique_ptr rng(new Botan::HMAC_DRBG(mac.release(), 0));
+ rng->initialize_with(seed_input.data(), seed_input.size());
// now reseed
rng->add_entropy(reseed_input.data(), reseed_input.size());
- rng->random_vec(expected.size()); // discard 1st block
+ std::vector out(expected.size());
+ // first block is discarded
+ rng->randomize_with_input(out.data(), out.size(), ad1.data(), ad1.size());
+ rng->randomize_with_input(out.data(), out.size(), ad2.data(), ad2.size());
- result.test_eq("rng", rng->random_vec(expected.size()), expected);
+ result.test_eq("rng", out, expected);
return result;
}
--
cgit v1.2.3
From 3404b86897748307457f16a32dd7492e39564365 Mon Sep 17 00:00:00 2001
From: Jack Lloyd
Date: Mon, 18 Jul 2016 16:51:04 -0400
Subject: Update news
[ci skip]
---
doc/news.rst | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
(limited to 'doc')
diff --git a/doc/news.rst b/doc/news.rst
index 6edc34e62..67f458fec 100644
--- a/doc/news.rst
+++ b/doc/news.rst
@@ -12,6 +12,10 @@ Version 1.11.31, Not Yet Released
* Add KDF1 from ISO 18033 (GH #483)
+* RNG changes: NIST SP900-80's HMAC_DRBG is now the default generator
+ for userspace RNG (AutoSeeded_RNG). HMAC_DRBG now attempts to detect
+ use of fork (via pid checks)
+
* Fix undefined behavior in Curve25519 on platforms without a native 128-bit
integer type. This was known to produce incorrect results on 32-bit ARM
under Clang. GH #532
@@ -22,7 +26,7 @@ Version 1.11.31, Not Yet Released
a future release. The developers believe that it is unlikely that any modern
system requires EGD and so the code is now dead weight. If you rely on EGD
support, you should contact the developers by email or GitHub ASAP.
-
+
* Changes in DLIES: Previously the input to the KDF was the concatenation
of the (ephemeral) public key and the secret value derived by the key
agreement operation. Now the input is only the secret value obtained
@@ -33,7 +37,6 @@ Version 1.11.31, Not Yet Released
Furthermore the order of the output was changed from {public key, tag, ciphertext}
to {public key, ciphertext, tag}. Both modes are compatible with bouncycastle.
-
* Fix a bug in ANSI X9.23 padding mode, which returned one byte more
than the given block size (GH #529).
--
cgit v1.2.3
From a22a54fd962f4aafa7ea3d6a888d8d4ab779f1ba Mon Sep 17 00:00:00 2001
From: Jack Lloyd
Date: Fri, 12 Aug 2016 12:36:36 -0400
Subject: Changes to TLS::Callbacks for GH PR #457
Make TLS::Channel::m_callbacks a reference, so deriving from TLS::Callbacks works
Split out the compat (std::function) based interface to Compat_Callbacks.
This avoids the overhead of empty std::functions when using the virtual
interface, and ensures the virtual interface works since there is no
callback path that does not involve a vtable lookup.
Rename the TLS::Callback functions. Since the idea is that often an owning
class will pass *this as the callbacks argument, it is good to namespace
the virtual functions so as not to conflict with other names chosen by
the class. Specifically, prefixes all cb functions with tls_
Revert changes to use the old style alert callback (with no longer used data/len
params) so no API changes are required for old code. The new Callbacks interface
continues to just receive the alert code itself.
Switch to virtual function interface in CLI tls_client for testing.
Inline tls_server_handshake_state.h - only used in tls_server.cpp
Fix tests - test looked like it was creating a new client object but it
was not actually being used. And when enabled, it failed because the queues
were not being emptied in between. So, fix that.
---
doc/manual/tls.rst | 144 +++++++++++++++----------------
src/cli/tls_client.cpp | 38 ++++----
src/cli/tls_proxy.cpp | 17 ++--
src/cli/tls_server.cpp | 12 ++-
src/lib/tls/info.txt | 1 -
src/lib/tls/tls_blocking.cpp | 8 +-
src/lib/tls/tls_blocking.h | 2 +
src/lib/tls/tls_callbacks.h | 106 ++++++++++++++++-------
src/lib/tls/tls_channel.cpp | 31 +++----
src/lib/tls/tls_channel.h | 23 ++---
src/lib/tls/tls_client.cpp | 9 +-
src/lib/tls/tls_client.h | 57 +++++++++---
src/lib/tls/tls_handshake_state.cpp | 10 ++-
src/lib/tls/tls_handshake_state.h | 14 +--
src/lib/tls/tls_record.h | 4 -
src/lib/tls/tls_server.cpp | 36 ++++++--
src/lib/tls/tls_server.h | 23 ++++-
src/lib/tls/tls_server_handshake_state.h | 48 -----------
src/tests/unit_tls.cpp | 93 ++++++++++++--------
19 files changed, 376 insertions(+), 300 deletions(-)
delete mode 100644 src/lib/tls/tls_server_handshake_state.h
(limited to 'doc')
diff --git a/doc/manual/tls.rst b/doc/manual/tls.rst
index a10a4280c..7210fc092 100644
--- a/doc/manual/tls.rst
+++ b/doc/manual/tls.rst
@@ -22,44 +22,52 @@ instance, by reading from a network socket) it passes that information
to TLS using :cpp:func:`TLS::Channel::received_data`. If the data
passed in results in some change in the state, such as a handshake
completing, or some data or an alert being received from the other
-side, then a user provided callback will be invoked. If the reader is
-familiar with OpenSSL's BIO layer, it might be analagous to saying the
-only way of interacting with Botan's TLS is via a `BIO_mem` I/O
+side, then the appropriate user provided callback will be invoked.
+
+If the reader is familiar with OpenSSL's BIO layer, it might be analagous
+to saying the only way of interacting with Botan's TLS is via a `BIO_mem` I/O
abstraction. This makes the library completely agnostic to how you
write your network layer, be it blocking sockets, libevent, asio, a
-message queue, etc.
+message queue, lwIP on RTOS, some carrier pidgeons, etc.
-The callbacks for TLS have the signatures
+Starting in 1.11.31, the application callbacks are encapsulated as the class
+``TLS::Callbacks`` with the following members. The first four (``tls_emit_data``,
+``tls_record_received``, ``tls_alert``, and ``tls_session_established``) are
+mandatory for using TLS, all others are optional and provide additional
+information about the connection.
- .. cpp:function:: void output_fn(const byte data[], size_t data_len)
+ .. cpp:function:: void tls_emit_data(const byte data[], size_t data_len)
- TLS requests that all bytes of *data* be queued up to send to the
- counterparty. After this function returns, *data* will be
- overwritten, so a copy of the input must be made if the callback
+ The TLS stack requests that all bytes of *data* be queued up to send to the
+ counterparty. After this function returns, the buffer containing *data* will
+ be overwritten, so a copy of the input must be made if the callback
cannot send the data immediately.
- .. cpp:function:: void data_cb(const byte data[], size_t data_len)
+ The write can be deferred but for TLS all writes must occur *in order*.
+ For DTLS this is not strictly required, but is still recommended.
+
+ .. cpp:function:: void tls_record_received(uint64_t rec_no, const byte data[], size_t data_len)
+
+ Called once for each application_data record which is received, with the
+ matching (TLS level) record sequence number.
- Called whenever application data is received from the other side
- of the connection, in which case *data* and *data_len* specify
- the data received. This array will be overwritten sometime after
- the callback returns, so again a copy should be made if need be.
+ Currently empty records are ignored and do not instigate a callback,
+ but this may change in a future release.
- .. cpp:function:: void alert_cb(Alert alert, const byte data[], size_t data_len)
+ As with ``tls_emit_data``, the array will be overwritten sometime after
+ the callback returns, so a copy should be made if needed.
- Called when an alert is received. Normally, data is null and
- data_len is 0, as most alerts have no associated data. However,
- if TLS heartbeats (see :rfc:`6520`) were negotiated, and we
- initiated a heartbeat, then if/when the other party responds,
- ``alert_cb`` will be called with whatever data was included in
- the heartbeat response (if any) along with a psuedo-alert value
- of ``HEARTBEAT_PAYLOAD``.
+ .. cpp:function:: void tls_alert(Alert alert)
- .. cpp:function:: bool handshake_cb(const TLS::Session& session)
+ Called when an alert is received from the peer. Note that alerts
+ received before the handshake is complete are not authenticated and
+ could have been inserted by a MITM attacker.
+
+ .. cpp:function:: bool tls_session_established(const TLS::Session& session)
Called whenever a negotiation completes. This can happen more
- than once on any connection. The *session* parameter provides
- information about the session which was established.
+ than once on any connection, if renegotiation occurs. The *session* parameter
+ provides information about the session which was just established.
If this function returns false, the session will not be cached
for later resumption.
@@ -68,8 +76,22 @@ The callbacks for TLS have the signatures
exception which will send a close message to the counterparty and
reset the connection state.
-You can of course use tools like ``std::bind`` to bind additional
-parameters to your callback functions.
+ .. cpp:function:: void tls_inspect_handshake_msg(const Handshake_Message&)
+
+ This callback is optional, and can be used to inspect all handshake messages
+ while the session establishment occurs.
+
+ .. cpp:function:: void tls_log_debug(const char*)
+
+ This callback is for exerimental purposes and currently unused. It may be
+ removed or modified in a future release.
+
+Versions from 1.11.0 to 1.11.30 did not have ``TLS::Callbacks` and instead
+used independent std::functions to pass the various callback functions.
+This interface is currently still included but is deprecated and will be removed
+in a future release. For the documentation for this interface, please check
+the docs in 1.11.30. This version of the manual only documents the new interface
+added in 1.11.31.
TLS Channels
----------------------------------------
@@ -80,16 +102,6 @@ available:
.. cpp:class:: TLS::Channel
- .. cpp:type:: std::function output_fn
-
- .. cpp:type:: std::function data_cb
-
- .. cpp:type:: std::function alert_cb
-
- .. cpp:type:: std::function handshake_cb
-
- Typedefs used in the code for the functions described above
-
.. cpp:function:: size_t received_data(const byte buf[], size_t buf_size)
.. cpp:function:: size_t received_data(const std::vector& buf)
@@ -194,10 +206,7 @@ TLS Clients
.. cpp:class:: TLS::Client
.. cpp:function:: Client( \
- output_fn out, \
- data_cb app_data_cb, \
- alert_cb alert_cb, \
- handshake_cb hs_cb, \
+ Callbacks& callbacks,
Session_Manager& session_manager, \
Credentials_Manager& creds, \
const Policy& policy, \
@@ -211,29 +220,8 @@ TLS Clients
Initialize a new TLS client. The constructor will immediately
initiate a new session.
- The *output_fn* callback will be called with output that
- should be sent to the counterparty. For instance this will be
- called immediately from the constructor after the client hello
- message is constructed. An implementation of *output_fn* is
- allowed to defer the write (for instance if writing when the
- callback occurs would block), but should eventually write the data
- to the counterparty *in order*.
-
- The *data_cb* will be called with data sent by the counterparty
- after it has been processed. The byte array and size_t represent
- the plaintext value and size.
-
- The *alert_cb* will be called when a protocol alert is received,
- commonly with a close alert during connection teardown.
-
- The *handshake_cb* function is called when a handshake
- (either initial or renegotiation) is completed. The return value of
- the callback specifies if the session should be cached for later
- resumption. If the function for some reason desires to prevent the
- connection from completing, it should throw an exception
- (preferably a TLS::Exception, which can provide more specific alert
- information to the counterparty). The :cpp:class:`TLS::Session`
- provides information about the session that was just established.
+ The *callbacks* parameter specifies the various application callbacks
+ which pertain to this particular client connection.
The *session_manager* is an interface for storing TLS sessions,
which allows for session resumption upon reconnecting to a server.
@@ -285,10 +273,7 @@ TLS Servers
.. cpp:class:: TLS::Server
.. cpp:function:: Server( \
- output_fn output, \
- data_cb data_cb, \
- alert_cb alert_cb, \
- handshake_cb handshake_cb, \
+ Callbacks& callbacks,
Session_Manager& session_manager, \
Credentials_Manager& creds, \
const Policy& policy, \
@@ -298,11 +283,11 @@ TLS Servers
size_t reserved_io_buffer_size = 16*1024 \
)
-The first 8 arguments as well as the final argument
+The first 5 arguments as well as the final argument
*reserved_io_buffer_size*, are treated similiarly to the :ref:`client
`.
-The (optional) argument, *proto_chooser*, is a function called if the
+The (optional) argument, *next_proto*, is a function called if the
client sent the ALPN extension to negotiate an application
protocol. In that case, the function should choose a protocol to use
and return it. Alternately it can throw an exception to abort the
@@ -312,7 +297,7 @@ should be of type `NO_APPLICATION_PROTOCOL`.
The optional argument *is_datagram* specifies if this is a TLS or DTLS
server; unlike clients, which know what type of protocol (TLS vs DTLS)
they are negotiating from the start via the *offer_version*, servers
-would not until they actually received a hello without this parameter.
+would not until they actually received a client hello.
Code for a TLS server using asio is in `src/cli/tls_proxy.cpp`.
@@ -516,7 +501,7 @@ policy settings from a file.
Values without an explicit mode use old-style CBC with HMAC encryption.
Default value: "AES-256/GCM", "AES-128/GCM", "ChaCha20Poly1305",
- "AES-256/CCM", "AES-128/CCM", "AES-256/CCM-8", "AES-128/CCM-8",
+ "AES-256/CCM", "AES-128/CCM", "AES-256/CCM(8)", "AES-128/CCM(8)",
"AES-256", "AES-128"
Also allowed: "Camellia-256/GCM", "Camellia-128/GCM",
@@ -529,15 +514,18 @@ policy settings from a file.
.. note::
- The current ChaCha20Poly1305 ciphersuites are non-standard but
- as of 2015 were implemented and deployed by Google and
- elsewhere. Support will be changed to using IETF standard
- ChaCha20Poly1305 ciphersuites when those are defined.
+ Before 1.11.30 only the non-standard ChaCha20Poly1305 ciphersuite
+ was implemented. The RFC 7905 ciphersuites are supported in 1.11.30
+ onwards.
.. note::
Support for the broken RC4 cipher was removed in 1.11.17
+ .. note::
+
+ SEED and 3DES are deprecated and will be removed in a future release.
+
.. cpp:function:: std::vector allowed_macs() const
Returns the list of algorithms we are willing to use for
@@ -577,6 +565,10 @@ policy settings from a file.
Also allowed (disabled by default): "" (meaning anonymous)
+ .. note::
+
+ DSA authentication is deprecated and will be removed in a future release.
+
.. cpp:function:: std::vector allowed_ecc_curves() const
Return a list of ECC curves we are willing to use, in order of preference.
diff --git a/src/cli/tls_client.cpp b/src/cli/tls_client.cpp
index e2fc1f027..082daf4ac 100644
--- a/src/cli/tls_client.cpp
+++ b/src/cli/tls_client.cpp
@@ -36,7 +36,7 @@
namespace Botan_CLI {
-class TLS_Client final : public Command
+class TLS_Client final : public Command, public Botan::TLS::Callbacks
{
public:
TLS_Client() : Command("tls_client host --port=443 --print-certs --policy= "
@@ -99,15 +99,10 @@ class TLS_Client final : public Command
const std::vector protocols_to_offer = Botan::split_on("next-protocols", ',');
- int sockfd = connect_to_host(host, port, use_tcp);
+ m_sockfd = connect_to_host(host, port, use_tcp);
using namespace std::placeholders;
- auto socket_write =
- use_tcp ?
- std::bind(stream_socket_write, sockfd, _1, _2) :
- std::bind(dgram_socket_write, sockfd, _1, _2);
-
auto version = policy->latest_supported_version(!use_tcp);
if(flag_set("tls1.0"))
@@ -119,11 +114,7 @@ class TLS_Client final : public Command
version = Botan::TLS::Protocol_Version::TLS_V11;
}
- Botan::TLS::Client client(Botan::TLS::Callbacks(
- socket_write,
- std::bind(&TLS_Client::process_data, this, _1, _2),
- std::bind(&TLS_Client::alert_received, this, _1),
- std::bind(&TLS_Client::handshake_complete, this, _1)),
+ Botan::TLS::Client client(*this,
*session_mgr,
creds,
*policy,
@@ -138,7 +129,7 @@ class TLS_Client final : public Command
{
fd_set readfds;
FD_ZERO(&readfds);
- FD_SET(sockfd, &readfds);
+ FD_SET(m_sockfd, &readfds);
if(client.is_active())
{
@@ -154,13 +145,13 @@ class TLS_Client final : public Command
struct timeval timeout = { 1, 0 };
- ::select(sockfd + 1, &readfds, nullptr, nullptr, &timeout);
+ ::select(m_sockfd + 1, &readfds, nullptr, nullptr, &timeout);
- if(FD_ISSET(sockfd, &readfds))
+ if(FD_ISSET(m_sockfd, &readfds))
{
uint8_t buf[4*1024] = { 0 };
- ssize_t got = ::read(sockfd, buf, sizeof(buf));
+ ssize_t got = ::read(m_sockfd, buf, sizeof(buf));
if(got == 0)
{
@@ -218,7 +209,7 @@ class TLS_Client final : public Command
}
}
- ::close(sockfd);
+ ::close(m_sockfd);
}
private:
@@ -258,7 +249,7 @@ class TLS_Client final : public Command
return fd;
}
- bool handshake_complete(const Botan::TLS::Session& session)
+ bool tls_session_established(const Botan::TLS::Session& session) override
{
output() << "Handshake complete, " << session.version().to_string()
<< " using " << session.ciphersuite().to_string() << "\n";
@@ -292,13 +283,13 @@ class TLS_Client final : public Command
throw CLI_Error("Socket write failed errno=" + std::to_string(errno));
}
- static void stream_socket_write(int sockfd, const uint8_t buf[], size_t length)
+ void tls_emit_data(const uint8_t buf[], size_t length) override
{
size_t offset = 0;
while(length)
{
- ssize_t sent = ::send(sockfd, (const char*)buf + offset,
+ ssize_t sent = ::send(m_sockfd, (const char*)buf + offset,
length, MSG_NOSIGNAL);
if(sent == -1)
@@ -314,16 +305,19 @@ class TLS_Client final : public Command
}
}
- void alert_received(Botan::TLS::Alert alert)
+ void tls_alert(Botan::TLS::Alert alert)
{
output() << "Alert: " << alert.type_string() << "\n";
}
- void process_data(const uint8_t buf[], size_t buf_size)
+ void tls_record_received(uint64_t seq_no, const uint8_t buf[], size_t buf_size)
{
for(size_t i = 0; i != buf_size; ++i)
output() << buf[i];
}
+
+ private:
+ int m_sockfd;
};
BOTAN_REGISTER_COMMAND("tls_client", TLS_Client);
diff --git a/src/cli/tls_proxy.cpp b/src/cli/tls_proxy.cpp
index d52a67631..5140654de 100644
--- a/src/cli/tls_proxy.cpp
+++ b/src/cli/tls_proxy.cpp
@@ -60,7 +60,7 @@ void log_text_message(const char* where, const uint8_t buf[], size_t buf_len)
//std::cout << where << ' ' << std::string(c, c + buf_len) << std::endl;
}
-class tls_proxy_session : public boost::enable_shared_from_this
+class tls_proxy_session : public boost::enable_shared_from_this, public Botan::TLS::Callbacks
{
public:
enum { readbuf_size = 4 * 1024 };
@@ -112,10 +112,7 @@ class tls_proxy_session : public boost::enable_shared_from_this 0)
m_p2c_pending.insert(m_p2c_pending.end(), buf, buf + buf_len);
@@ -269,7 +266,7 @@ class tls_proxy_session : public boost::enable_shared_from_this
diff --git a/src/lib/tls/tls_blocking.cpp b/src/lib/tls/tls_blocking.cpp
index 3910d242c..34ebc6c91 100644
--- a/src/lib/tls/tls_blocking.cpp
+++ b/src/lib/tls/tls_blocking.cpp
@@ -24,12 +24,13 @@ Blocking_Client::Blocking_Client(read_fn reader,
const Protocol_Version& offer_version,
const std::vector& next) :
m_read(reader),
- m_channel(TLS::Callbacks(
+ m_callbacks(new TLS::Compat_Callbacks(
writer,
std::bind(&Blocking_Client::data_cb, this, _1, _2),
- std::bind(&Blocking_Client::alert_cb, this, _1),
+ std::function(std::bind(&Blocking_Client::alert_cb, this, _1)),
std::bind(&Blocking_Client::handshake_cb, this, _1)
- ),
+ )),
+ m_channel(*m_callbacks.get(),
session_manager,
creds,
policy,
@@ -38,6 +39,7 @@ Blocking_Client::Blocking_Client(read_fn reader,
offer_version,
next)
{
+ printf("hi\n");
}
bool Blocking_Client::handshake_cb(const Session& session)
diff --git a/src/lib/tls/tls_blocking.h b/src/lib/tls/tls_blocking.h
index cba44b524..0f2986710 100644
--- a/src/lib/tls/tls_blocking.h
+++ b/src/lib/tls/tls_blocking.h
@@ -33,6 +33,7 @@ class BOTAN_DLL Blocking_Client
typedef std::function read_fn;
typedef std::function write_fn;
+ BOTAN_DEPRECATED("Use the regular TLS::Client interface")
Blocking_Client(read_fn reader,
write_fn writer,
Session_Manager& session_manager,
@@ -93,6 +94,7 @@ class BOTAN_DLL Blocking_Client
void alert_cb(const Alert& alert);
read_fn m_read;
+ std::unique_ptr m_callbacks;
TLS::Client m_channel;
secure_vector m_plaintext;
};
diff --git a/src/lib/tls/tls_callbacks.h b/src/lib/tls/tls_callbacks.h
index 216c58ce2..db1b70693 100644
--- a/src/lib/tls/tls_callbacks.h
+++ b/src/lib/tls/tls_callbacks.h
@@ -1,6 +1,7 @@
/*
* TLS Callbacks
* (C) 2016 Matthias Gierlings
+* 2016 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
@@ -14,33 +15,76 @@ namespace Botan {
namespace TLS {
-class Handshake_State;
class Handshake_Message;
/**
-* Virtual Interface for TLS-Channel related callback handling. The default
-* implementations involving std::function are only provided for compatibility
-* purposes. New implementations should override the virtual member methods
-* out_fn(), app_data(), alert(), handshake() and handshake_msg() instead.
-*
+* Encapsulates the callbacks that a TLS channel will make which are due to
+* channel specific operations.
*/
class BOTAN_DLL Callbacks
+ {
+ public:
+ virtual ~Callbacks() {}
+
+ /**
+ * Mandatory callback: output function
+ * The channel will call this with data which needs to be sent to the peer
+ * (eg, over a socket or some other form of IPC). The array will be overwritten
+ * when the function returns so a copy must be made if the data cannot be
+ * sent immediately.
+ */
+ virtual void tls_emit_data(const uint8_t data[], size_t size) = 0;
+
+ /**
+ * Mandatory callback: process application data
+ * Called when application data record is received from the peer.
+ * Again the array is overwritten immediately after the function returns.
+ * seq_no is the underlying TLS/DTLS record sequence number.
+ */
+ virtual void tls_record_received(u64bit seq_no, const uint8_t data[], size_t size) = 0;
+
+ /**
+ * Mandary callback: alert received
+ * Called when an alert is received from the peer
+ * If fatal, the connection is closing. If not fatal, the connection may
+ * still be closing (depending on the error and the peer).
+ */
+ virtual void tls_alert(Alert alert) = 0;
+
+ /**
+ * Mandatory callback: session established
+ * Called when a session is established. Throw an exception to abort
+ * the connection. Return false to prevent the session from being cached.
+ * Return true to cache the session in the configured session manager.
+ */
+ virtual bool tls_session_established(const Session& session) = 0;
+
+ /**
+ * Optional callback: inspect handshake message
+ */
+ virtual void tls_inspect_handshake_msg(const Handshake_Message&) {}
+
+ /**
+ * Optional callback: debug logging. (not currently used)
+ */
+ virtual bool tls_log_debug(const char*) { return false; }
+ };
+
+/**
+* TLS::Callbacks using std::function for compatability with the old API signatures.
+* This type is only provided for backward compatibility.
+* New implementations should derive from TLS::Callbacks instead.
+*/
+class BOTAN_DLL Compat_Callbacks final : public Callbacks
{
public:
typedef std::function output_fn;
typedef std::function data_cb;
- typedef std::function