diff options
Diffstat (limited to 'src/lib/pbe')
-rw-r--r-- | src/lib/pbe/get_pbe.cpp | 140 | ||||
-rw-r--r-- | src/lib/pbe/get_pbe.h | 44 | ||||
-rw-r--r-- | src/lib/pbe/info.txt | 7 | ||||
-rw-r--r-- | src/lib/pbe/pbe.h | 39 | ||||
-rw-r--r-- | src/lib/pbe/pbes1/info.txt | 10 | ||||
-rw-r--r-- | src/lib/pbe/pbes1/pbes1.cpp | 193 | ||||
-rw-r--r-- | src/lib/pbe/pbes1/pbes1.h | 69 | ||||
-rw-r--r-- | src/lib/pbe/pbes2/info.txt | 14 | ||||
-rw-r--r-- | src/lib/pbe/pbes2/pbes2.cpp | 209 | ||||
-rw-r--r-- | src/lib/pbe/pbes2/pbes2.h | 70 |
10 files changed, 795 insertions, 0 deletions
diff --git a/src/lib/pbe/get_pbe.cpp b/src/lib/pbe/get_pbe.cpp new file mode 100644 index 000000000..4ec518776 --- /dev/null +++ b/src/lib/pbe/get_pbe.cpp @@ -0,0 +1,140 @@ +/* +* PBE Retrieval +* (C) 1999-2007 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#include <botan/get_pbe.h> +#include <botan/oids.h> +#include <botan/scan_name.h> +#include <botan/parsing.h> +#include <botan/libstate.h> + +#if defined(BOTAN_HAS_PBE_PKCS_V15) + #include <botan/pbes1.h> +#endif + +#if defined(BOTAN_HAS_PBE_PKCS_V20) + #include <botan/pbes2.h> + #include <botan/hmac.h> +#endif + +namespace Botan { + +/* +* Get an encryption PBE, set new parameters +*/ +PBE* get_pbe(const std::string& algo_spec, + const std::string& passphrase, + std::chrono::milliseconds msec, + RandomNumberGenerator& rng) + { + SCAN_Name request(algo_spec); + + const std::string pbe = request.algo_name(); + std::string digest_name = request.arg(0); + const std::string cipher = request.arg(1); + + std::vector<std::string> cipher_spec = split_on(cipher, '/'); + if(cipher_spec.size() != 2) + throw Invalid_Argument("PBE: Invalid cipher spec " + cipher); + + const std::string cipher_algo = SCAN_Name::deref_alias(cipher_spec[0]); + const std::string cipher_mode = cipher_spec[1]; + + if(cipher_mode != "CBC") + throw Invalid_Argument("PBE: Invalid cipher mode " + cipher); + + Algorithm_Factory& af = global_state().algorithm_factory(); + + const BlockCipher* block_cipher = af.prototype_block_cipher(cipher_algo); + if(!block_cipher) + throw Algorithm_Not_Found(cipher_algo); + + const HashFunction* hash_function = af.prototype_hash_function(digest_name); + if(!hash_function) + throw Algorithm_Not_Found(digest_name); + + if(request.arg_count() != 2) + throw Invalid_Algorithm_Name(algo_spec); + +#if defined(BOTAN_HAS_PBE_PKCS_V15) + if(pbe == "PBE-PKCS5v15") + return new PBE_PKCS5v15(block_cipher->clone(), + hash_function->clone(), + passphrase, + msec, + rng); +#endif + +#if defined(BOTAN_HAS_PBE_PKCS_V20) + if(pbe == "PBE-PKCS5v20") + return new PBE_PKCS5v20(block_cipher->clone(), + new HMAC(hash_function->clone()), + passphrase, + msec, + rng); +#endif + + throw Algorithm_Not_Found(algo_spec); + } + +/* +* Get a decryption PBE, decode parameters +*/ +PBE* get_pbe(const OID& pbe_oid, + const std::vector<byte>& params, + const std::string& passphrase) + { + SCAN_Name request(OIDS::lookup(pbe_oid)); + + const std::string pbe = request.algo_name(); + +#if defined(BOTAN_HAS_PBE_PKCS_V15) + if(pbe == "PBE-PKCS5v15") + { + if(request.arg_count() != 2) + throw Invalid_Algorithm_Name(request.as_string()); + + std::string digest_name = request.arg(0); + const std::string cipher = request.arg(1); + + std::vector<std::string> cipher_spec = split_on(cipher, '/'); + if(cipher_spec.size() != 2) + throw Invalid_Argument("PBE: Invalid cipher spec " + cipher); + + const std::string cipher_algo = SCAN_Name::deref_alias(cipher_spec[0]); + const std::string cipher_mode = cipher_spec[1]; + + if(cipher_mode != "CBC") + throw Invalid_Argument("PBE: Invalid cipher mode " + cipher); + + Algorithm_Factory& af = global_state().algorithm_factory(); + + const BlockCipher* block_cipher = af.prototype_block_cipher(cipher_algo); + if(!block_cipher) + throw Algorithm_Not_Found(cipher_algo); + + const HashFunction* hash_function = + af.prototype_hash_function(digest_name); + + if(!hash_function) + throw Algorithm_Not_Found(digest_name); + + return new PBE_PKCS5v15(block_cipher->clone(), + hash_function->clone(), + params, + passphrase); + } +#endif + +#if defined(BOTAN_HAS_PBE_PKCS_V20) + if(pbe == "PBE-PKCS5v20") + return new PBE_PKCS5v20(params, passphrase); +#endif + + throw Algorithm_Not_Found(pbe_oid.as_string()); + } + +} diff --git a/src/lib/pbe/get_pbe.h b/src/lib/pbe/get_pbe.h new file mode 100644 index 000000000..df87c0547 --- /dev/null +++ b/src/lib/pbe/get_pbe.h @@ -0,0 +1,44 @@ +/* +* PBE Lookup +* (C) 1999-2007 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#ifndef BOTAN_LOOKUP_PBE_H__ +#define BOTAN_LOOKUP_PBE_H__ + +#include <botan/pbe.h> +#include <vector> +#include <string> +#include <chrono> + +namespace Botan { + +/** +* Factory function for PBEs. +* @param algo_spec the name of the PBE algorithm to retrieve +* @param passphrase the passphrase to use for encryption +* @param msec how many milliseconds to run the PBKDF +* @param rng a random number generator +* @return pointer to a PBE with randomly created parameters +*/ +BOTAN_DLL PBE* get_pbe(const std::string& algo_spec, + const std::string& passphrase, + std::chrono::milliseconds msec, + RandomNumberGenerator& rng); + +/** +* Factory function for PBEs. +* @param pbe_oid the oid of the desired PBE +* @param params a DataSource providing the DER encoded parameters to use +* @param passphrase the passphrase to use for decryption +* @return pointer to the PBE with the specified parameters +*/ +BOTAN_DLL PBE* get_pbe(const OID& pbe_oid, + const std::vector<byte>& params, + const std::string& passphrase); + +} + +#endif diff --git a/src/lib/pbe/info.txt b/src/lib/pbe/info.txt new file mode 100644 index 000000000..0436c4efd --- /dev/null +++ b/src/lib/pbe/info.txt @@ -0,0 +1,7 @@ +define PASSWORD_BASED_ENCRYPTION 20131128 + +<requires> +filters +libstate +oid_lookup +</requires> diff --git a/src/lib/pbe/pbe.h b/src/lib/pbe/pbe.h new file mode 100644 index 000000000..45c98e2c8 --- /dev/null +++ b/src/lib/pbe/pbe.h @@ -0,0 +1,39 @@ +/* +* PBE +* (C) 1999-2007 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#ifndef BOTAN_PBE_BASE_H__ +#define BOTAN_PBE_BASE_H__ + +#include <botan/asn1_oid.h> +#include <botan/data_src.h> +#include <botan/filter.h> +#include <botan/rng.h> + +namespace Botan { + +/** +* Password Based Encryption (PBE) Filter. +*/ +class BOTAN_DLL PBE : public Filter + { + public: + /** + * DER encode the params (the number of iterations and the salt value) + * @return encoded params + */ + virtual std::vector<byte> encode_params() const = 0; + + /** + * Get this PBE's OID. + * @return object identifier + */ + virtual OID get_oid() const = 0; + }; + +} + +#endif diff --git a/src/lib/pbe/pbes1/info.txt b/src/lib/pbe/pbes1/info.txt new file mode 100644 index 000000000..36d26ecc9 --- /dev/null +++ b/src/lib/pbe/pbes1/info.txt @@ -0,0 +1,10 @@ +define PBE_PKCS_V15 20131128 + +<requires> +asn1 +block +cbc +filters +hash +pbkdf1 +</requires> diff --git a/src/lib/pbe/pbes1/pbes1.cpp b/src/lib/pbe/pbes1/pbes1.cpp new file mode 100644 index 000000000..a30f10a6c --- /dev/null +++ b/src/lib/pbe/pbes1/pbes1.cpp @@ -0,0 +1,193 @@ +/* +* PKCS #5 PBES1 +* (C) 1999-2007 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#include <botan/pbes1.h> +#include <botan/pbkdf1.h> +#include <botan/der_enc.h> +#include <botan/ber_dec.h> +#include <botan/lookup.h> +#include <algorithm> + +namespace Botan { + +/* +* Encrypt some bytes using PBES1 +*/ +void PBE_PKCS5v15::write(const byte input[], size_t length) + { + m_pipe.write(input, length); + flush_pipe(true); + } + +/* +* Start encrypting with PBES1 +*/ +void PBE_PKCS5v15::start_msg() + { + m_pipe.append(get_cipher(m_block_cipher->name() + "/CBC/PKCS7", + m_key, m_iv, m_direction)); + + m_pipe.start_msg(); + if(m_pipe.message_count() > 1) + m_pipe.set_default_msg(m_pipe.default_msg() + 1); + } + +/* +* Finish encrypting with PBES1 +*/ +void PBE_PKCS5v15::end_msg() + { + m_pipe.end_msg(); + flush_pipe(false); + m_pipe.reset(); + } + +/* +* Flush the pipe +*/ +void PBE_PKCS5v15::flush_pipe(bool safe_to_skip) + { + if(safe_to_skip && m_pipe.remaining() < 64) + return; + + secure_vector<byte> buffer(DEFAULT_BUFFERSIZE); + while(m_pipe.remaining()) + { + size_t got = m_pipe.read(&buffer[0], buffer.size()); + send(buffer, got); + } + } + +/* +* Encode PKCS#5 PBES1 parameters +*/ +std::vector<byte> PBE_PKCS5v15::encode_params() const + { + return DER_Encoder() + .start_cons(SEQUENCE) + .encode(m_salt, OCTET_STRING) + .encode(m_iterations) + .end_cons() + .get_contents_unlocked(); + } + +/* +* Return an OID for this PBES1 type +*/ +OID PBE_PKCS5v15::get_oid() const + { + const OID base_pbes1_oid("1.2.840.113549.1.5"); + + const std::string cipher = m_block_cipher->name(); + const std::string digest = m_hash_function->name(); + + if(cipher == "DES" && digest == "MD2") + return (base_pbes1_oid + 1); + else if(cipher == "DES" && digest == "MD5") + return (base_pbes1_oid + 3); + else if(cipher == "DES" && digest == "SHA-160") + return (base_pbes1_oid + 10); + else if(cipher == "RC2" && digest == "MD2") + return (base_pbes1_oid + 4); + else if(cipher == "RC2" && digest == "MD5") + return (base_pbes1_oid + 6); + else if(cipher == "RC2" && digest == "SHA-160") + return (base_pbes1_oid + 11); + else + throw Internal_Error("PBE-PKCS5 v1.5: get_oid() has run out of options"); + } + +std::string PBE_PKCS5v15::name() const + { + return "PBE-PKCS5v15(" + m_block_cipher->name() + "," + + m_hash_function->name() + ")"; + } + +PBE_PKCS5v15::PBE_PKCS5v15(BlockCipher* cipher, + HashFunction* hash, + const std::string& passphrase, + std::chrono::milliseconds msec, + RandomNumberGenerator& rng) : + m_direction(ENCRYPTION), + m_block_cipher(cipher), + m_hash_function(hash), + m_salt(rng.random_vec(8)) + { + if(cipher->name() != "DES" && cipher->name() != "RC2") + { + throw Invalid_Argument("PBE_PKCS5v1.5: Unknown cipher " + + cipher->name()); + } + + if(hash->name() != "MD2" && hash->name() != "MD5" && + hash->name() != "SHA-160") + { + throw Invalid_Argument("PBE_PKCS5v1.5: Unknown hash " + + hash->name()); + } + + PKCS5_PBKDF1 pbkdf(m_hash_function->clone()); + + secure_vector<byte> key_and_iv = + pbkdf.derive_key(16, passphrase, + &m_salt[0], m_salt.size(), + msec, m_iterations).bits_of(); + + m_key.assign(&key_and_iv[0], &key_and_iv[8]); + m_iv.assign(&key_and_iv[8], &key_and_iv[16]); + + } + +PBE_PKCS5v15::PBE_PKCS5v15(BlockCipher* cipher, + HashFunction* hash, + const std::vector<byte>& params, + const std::string& passphrase) : + m_direction(DECRYPTION), + m_block_cipher(cipher), + m_hash_function(hash) + { + if(cipher->name() != "DES" && cipher->name() != "RC2") + { + throw Invalid_Argument("PBE_PKCS5v1.5: Unknown cipher " + + cipher->name()); + } + + if(hash->name() != "MD2" && hash->name() != "MD5" && + hash->name() != "SHA-160") + { + throw Invalid_Argument("PBE_PKCS5v1.5: Unknown hash " + + hash->name()); + } + + BER_Decoder(params) + .start_cons(SEQUENCE) + .decode(m_salt, OCTET_STRING) + .decode(m_iterations) + .verify_end() + .end_cons(); + + if(m_salt.size() != 8) + throw Decoding_Error("PBES1: Encoded salt is not 8 octets"); + + PKCS5_PBKDF1 pbkdf(m_hash_function->clone()); + + secure_vector<byte> key_and_iv = + pbkdf.derive_key(16, passphrase, + &m_salt[0], m_salt.size(), + m_iterations).bits_of(); + + m_key.assign(&key_and_iv[0], &key_and_iv[8]); + m_iv.assign(&key_and_iv[8], &key_and_iv[16]); + } + +PBE_PKCS5v15::~PBE_PKCS5v15() + { + delete m_block_cipher; + delete m_hash_function; + } + +} diff --git a/src/lib/pbe/pbes1/pbes1.h b/src/lib/pbe/pbes1/pbes1.h new file mode 100644 index 000000000..8d1a6f877 --- /dev/null +++ b/src/lib/pbe/pbes1/pbes1.h @@ -0,0 +1,69 @@ +/* +* PKCS #5 v1.5 PBE +* (C) 1999-2007 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#ifndef BOTAN_PBE_PKCS_V15_H__ +#define BOTAN_PBE_PKCS_V15_H__ + +#include <botan/pbe.h> +#include <botan/block_cipher.h> +#include <botan/hash.h> +#include <botan/pipe.h> +#include <chrono> + +namespace Botan { + +/** +* PKCS #5 v1.5 PBE +*/ +class BOTAN_DLL PBE_PKCS5v15 : public PBE + { + public: + OID get_oid() const; + + std::vector<byte> encode_params() const; + + std::string name() const; + + void write(const byte[], size_t); + void start_msg(); + void end_msg(); + + /** + * @param cipher the block cipher to use (DES or RC2) + * @param hash the hash function to use + * @param passphrase the passphrase to use + * @param msec how many milliseconds to run the PBKDF + * @param rng a random number generator + */ + PBE_PKCS5v15(BlockCipher* cipher, + HashFunction* hash, + const std::string& passphrase, + std::chrono::milliseconds msec, + RandomNumberGenerator& rng); + + PBE_PKCS5v15(BlockCipher* cipher, + HashFunction* hash, + const std::vector<byte>& params, + const std::string& passphrase); + + ~PBE_PKCS5v15(); + private: + + void flush_pipe(bool); + + Cipher_Dir m_direction; + BlockCipher* m_block_cipher; + HashFunction* m_hash_function; + + secure_vector<byte> m_salt, m_key, m_iv; + size_t m_iterations; + Pipe m_pipe; + }; + +} + +#endif diff --git a/src/lib/pbe/pbes2/info.txt b/src/lib/pbe/pbes2/info.txt new file mode 100644 index 000000000..ba7d77774 --- /dev/null +++ b/src/lib/pbe/pbes2/info.txt @@ -0,0 +1,14 @@ +define PBE_PKCS_V20 20131128 + +<requires> +algo_factory +asn1 +block +cbc +filters +hash +hmac +libstate +oid_lookup +pbkdf2 +</requires> diff --git a/src/lib/pbe/pbes2/pbes2.cpp b/src/lib/pbe/pbes2/pbes2.cpp new file mode 100644 index 000000000..d4df1277c --- /dev/null +++ b/src/lib/pbe/pbes2/pbes2.cpp @@ -0,0 +1,209 @@ +/* +* PKCS #5 PBES2 +* (C) 1999-2008 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#include <botan/pbes2.h> +#include <botan/pbkdf2.h> +#include <botan/algo_factory.h> +#include <botan/libstate.h> +#include <botan/der_enc.h> +#include <botan/ber_dec.h> +#include <botan/parsing.h> +#include <botan/alg_id.h> +#include <botan/oids.h> +#include <botan/lookup.h> +#include <algorithm> +#include <memory> + +namespace Botan { + +/* +* Encrypt some bytes using PBES2 +*/ +void PBE_PKCS5v20::write(const byte input[], size_t length) + { + pipe.write(input, length); + flush_pipe(true); + } + +/* +* Start encrypting with PBES2 +*/ +void PBE_PKCS5v20::start_msg() + { + pipe.append(get_cipher(block_cipher->name() + "/CBC/PKCS7", + key, iv, direction)); + + pipe.start_msg(); + if(pipe.message_count() > 1) + pipe.set_default_msg(pipe.default_msg() + 1); + } + +/* +* Finish encrypting with PBES2 +*/ +void PBE_PKCS5v20::end_msg() + { + pipe.end_msg(); + flush_pipe(false); + pipe.reset(); + } + +/* +* Flush the pipe +*/ +void PBE_PKCS5v20::flush_pipe(bool safe_to_skip) + { + if(safe_to_skip && pipe.remaining() < 64) + return; + + secure_vector<byte> buffer(DEFAULT_BUFFERSIZE); + while(pipe.remaining()) + { + const size_t got = pipe.read(&buffer[0], buffer.size()); + send(buffer, got); + } + } + +/* +* Encode PKCS#5 PBES2 parameters +*/ +std::vector<byte> PBE_PKCS5v20::encode_params() const + { + return DER_Encoder() + .start_cons(SEQUENCE) + .encode( + AlgorithmIdentifier("PKCS5.PBKDF2", + DER_Encoder() + .start_cons(SEQUENCE) + .encode(salt, OCTET_STRING) + .encode(iterations) + .encode(key_length) + .encode_if( + m_prf->name() != "HMAC(SHA-160)", + AlgorithmIdentifier(m_prf->name(), + AlgorithmIdentifier::USE_NULL_PARAM)) + .end_cons() + .get_contents_unlocked() + ) + ) + .encode( + AlgorithmIdentifier(block_cipher->name() + "/CBC", + DER_Encoder().encode(iv, OCTET_STRING).get_contents_unlocked() + ) + ) + .end_cons() + .get_contents_unlocked(); + } + +/* +* Return an OID for PBES2 +*/ +OID PBE_PKCS5v20::get_oid() const + { + return OIDS::lookup("PBE-PKCS5v20"); + } + +std::string PBE_PKCS5v20::name() const + { + return "PBE-PKCS5v20(" + block_cipher->name() + "," + + m_prf->name() + ")"; + } + +/* +* PKCS#5 v2.0 PBE Constructor +*/ +PBE_PKCS5v20::PBE_PKCS5v20(BlockCipher* cipher, + MessageAuthenticationCode* mac, + const std::string& passphrase, + std::chrono::milliseconds msec, + RandomNumberGenerator& rng) : + direction(ENCRYPTION), + block_cipher(cipher), + m_prf(mac), + salt(rng.random_vec(12)), + iv(rng.random_vec(block_cipher->block_size())), + iterations(0), + key_length(block_cipher->maximum_keylength()) + { + PKCS5_PBKDF2 pbkdf(m_prf->clone()); + + key = pbkdf.derive_key(key_length, passphrase, + &salt[0], salt.size(), + msec, iterations).bits_of(); + } + +/* +* PKCS#5 v2.0 PBE Constructor +*/ +PBE_PKCS5v20::PBE_PKCS5v20(const std::vector<byte>& params, + const std::string& passphrase) : + direction(DECRYPTION), + block_cipher(nullptr), + m_prf(nullptr) + { + AlgorithmIdentifier kdf_algo, enc_algo; + + BER_Decoder(params) + .start_cons(SEQUENCE) + .decode(kdf_algo) + .decode(enc_algo) + .verify_end() + .end_cons(); + + AlgorithmIdentifier prf_algo; + + if(kdf_algo.oid != OIDS::lookup("PKCS5.PBKDF2")) + throw Decoding_Error("PBE-PKCS5 v2.0: Unknown KDF algorithm " + + kdf_algo.oid.as_string()); + + BER_Decoder(kdf_algo.parameters) + .start_cons(SEQUENCE) + .decode(salt, OCTET_STRING) + .decode(iterations) + .decode_optional(key_length, INTEGER, UNIVERSAL) + .decode_optional(prf_algo, SEQUENCE, CONSTRUCTED, + AlgorithmIdentifier("HMAC(SHA-160)", + AlgorithmIdentifier::USE_NULL_PARAM)) + .verify_end() + .end_cons(); + + Algorithm_Factory& af = global_state().algorithm_factory(); + + std::string cipher = OIDS::lookup(enc_algo.oid); + std::vector<std::string> cipher_spec = split_on(cipher, '/'); + if(cipher_spec.size() != 2) + throw Decoding_Error("PBE-PKCS5 v2.0: Invalid cipher spec " + cipher); + + if(cipher_spec[1] != "CBC") + throw Decoding_Error("PBE-PKCS5 v2.0: Don't know param format for " + + cipher); + + BER_Decoder(enc_algo.parameters).decode(iv, OCTET_STRING).verify_end(); + + block_cipher = af.make_block_cipher(cipher_spec[0]); + m_prf = af.make_mac(OIDS::lookup(prf_algo.oid)); + + if(key_length == 0) + key_length = block_cipher->maximum_keylength(); + + if(salt.size() < 8) + throw Decoding_Error("PBE-PKCS5 v2.0: Encoded salt is too small"); + + PKCS5_PBKDF2 pbkdf(m_prf->clone()); + + key = pbkdf.derive_key(key_length, passphrase, + &salt[0], salt.size(), + iterations).bits_of(); + } + +PBE_PKCS5v20::~PBE_PKCS5v20() + { + delete m_prf; + delete block_cipher; + } + +} diff --git a/src/lib/pbe/pbes2/pbes2.h b/src/lib/pbe/pbes2/pbes2.h new file mode 100644 index 000000000..b7160f575 --- /dev/null +++ b/src/lib/pbe/pbes2/pbes2.h @@ -0,0 +1,70 @@ +/* +* PKCS #5 v2.0 PBE +* (C) 1999-2007 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#ifndef BOTAN_PBE_PKCS_v20_H__ +#define BOTAN_PBE_PKCS_v20_H__ + +#include <botan/pbe.h> +#include <botan/block_cipher.h> +#include <botan/mac.h> +#include <botan/pipe.h> +#include <chrono> + +namespace Botan { + +/** +* PKCS #5 v2.0 PBE +*/ +class BOTAN_DLL PBE_PKCS5v20 : public PBE + { + public: + OID get_oid() const; + + std::vector<byte> encode_params() const; + + std::string name() const; + + void write(const byte buf[], size_t buf_len); + void start_msg(); + void end_msg(); + + /** + * Load a PKCS #5 v2.0 encrypted stream + * @param params the PBES2 parameters + * @param passphrase the passphrase to use for decryption + */ + PBE_PKCS5v20(const std::vector<byte>& params, + const std::string& passphrase); + + /** + * @param cipher the block cipher to use + * @param mac the MAC to use + * @param passphrase the passphrase to use for encryption + * @param msec how many milliseconds to run the PBKDF + * @param rng a random number generator + */ + PBE_PKCS5v20(BlockCipher* cipher, + MessageAuthenticationCode* mac, + const std::string& passphrase, + std::chrono::milliseconds msec, + RandomNumberGenerator& rng); + + ~PBE_PKCS5v20(); + private: + void flush_pipe(bool); + + Cipher_Dir direction; + BlockCipher* block_cipher; + MessageAuthenticationCode* m_prf; + secure_vector<byte> salt, key, iv; + size_t iterations, key_length; + Pipe pipe; + }; + +} + +#endif |