diff options
author | Jack Lloyd <[email protected]> | 2017-02-26 15:48:35 -0500 |
---|---|---|
committer | Jack Lloyd <[email protected]> | 2017-02-26 15:48:35 -0500 |
commit | 8bbec86f8984b52b5d0cce8cd1309563d2b294cc (patch) | |
tree | 3c7b7c6aa275b66d3f3ae7c67e24ba64222591a4 /src/lib/pubkey/pbes2 | |
parent | 70d9d062d095242bcfe8df25fc57fb88eadec3a9 (diff) |
Add ability to specify iterations when encrypting a private key
GH #896
Diffstat (limited to 'src/lib/pubkey/pbes2')
-rw-r--r-- | src/lib/pubkey/pbes2/pbes2.cpp | 79 | ||||
-rw-r--r-- | src/lib/pubkey/pbes2/pbes2.h | 37 |
2 files changed, 104 insertions, 12 deletions
diff --git a/src/lib/pubkey/pbes2/pbes2.cpp b/src/lib/pubkey/pbes2/pbes2.cpp index 01bab76bb..b0a7f336d 100644 --- a/src/lib/pubkey/pbes2/pbes2.cpp +++ b/src/lib/pubkey/pbes2/pbes2.cpp @@ -55,18 +55,17 @@ std::vector<uint8_t> encode_pbes2_params(const std::string& cipher, .get_contents_unlocked(); } -} - /* -* PKCS#5 v2.0 PBE Constructor +* PKCS#5 v2.0 PBE Encryption */ std::pair<AlgorithmIdentifier, std::vector<uint8_t>> -pbes2_encrypt(const secure_vector<uint8_t>& key_bits, - const std::string& passphrase, - std::chrono::milliseconds msec, - const std::string& cipher, - const std::string& digest, - RandomNumberGenerator& rng) +pbes2_encrypt_shared(const secure_vector<uint8_t>& key_bits, + const std::string& passphrase, + size_t* msec_in_iterations_out, + size_t iterations_if_msec_null, + const std::string& cipher, + const std::string& digest, + RandomNumberGenerator& rng) { const std::string prf = "HMAC(" + digest + ")"; @@ -87,12 +86,22 @@ pbes2_encrypt(const secure_vector<uint8_t>& key_bits, std::unique_ptr<PBKDF> pbkdf(get_pbkdf("PBKDF2(" + prf + ")")); const size_t key_length = enc->key_spec().maximum_keylength(); - size_t iterations = 0; + secure_vector<uint8_t> iv = rng.random_vec(enc->default_nonce_length()); - enc->set_key(pbkdf->derive_key(key_length, passphrase, salt.data(), salt.size(), - msec, iterations).bits_of()); + size_t iterations = iterations_if_msec_null; + + if(msec_in_iterations_out) + { + std::chrono::milliseconds msec(*msec_in_iterations_out); + enc->set_key(pbkdf->derive_key(key_length, passphrase, salt.data(), salt.size(), msec, iterations).bits_of()); + *msec_in_iterations_out = iterations; + } + else + { + enc->set_key(pbkdf->pbkdf_iterations(key_length, passphrase, salt.data(), salt.size(), iterations)); + } enc->start(iv); secure_vector<uint8_t> buf = key_bits; @@ -105,6 +114,52 @@ pbes2_encrypt(const secure_vector<uint8_t>& key_bits, return std::make_pair(id, unlock(buf)); } + +} + +std::pair<AlgorithmIdentifier, std::vector<uint8_t>> +pbes2_encrypt(const secure_vector<uint8_t>& key_bits, + const std::string& passphrase, + std::chrono::milliseconds msec, + const std::string& cipher, + const std::string& digest, + RandomNumberGenerator& rng) + { + size_t msec_in_iterations_out = msec.count(); + return pbes2_encrypt_shared(key_bits, passphrase, &msec_in_iterations_out, 0, cipher, digest, rng); + // return value msec_in_iterations_out discarded + } + +std::pair<AlgorithmIdentifier, std::vector<uint8_t>> +pbes2_encrypt_msec(const secure_vector<uint8_t>& key_bits, + const std::string& passphrase, + std::chrono::milliseconds msec, + size_t* out_iterations_if_nonnull, + const std::string& cipher, + const std::string& digest, + RandomNumberGenerator& rng) + { + size_t msec_in_iterations_out = msec.count(); + + auto ret = pbes2_encrypt_shared(key_bits, passphrase, &msec_in_iterations_out, 0, cipher, digest, rng); + + if(out_iterations_if_nonnull) + *out_iterations_if_nonnull = msec_in_iterations_out; + + return ret; + } + +std::pair<AlgorithmIdentifier, std::vector<uint8_t>> +pbes2_encrypt_iter(const secure_vector<uint8_t>& key_bits, + const std::string& passphrase, + size_t pbkdf_iter, + const std::string& cipher, + const std::string& digest, + RandomNumberGenerator& rng) + { + return pbes2_encrypt_shared(key_bits, passphrase, nullptr, pbkdf_iter, cipher, digest, rng); + } + secure_vector<uint8_t> pbes2_decrypt(const secure_vector<uint8_t>& key_bits, const std::string& passphrase, diff --git a/src/lib/pubkey/pbes2/pbes2.h b/src/lib/pubkey/pbes2/pbes2.h index e50896c6d..951ba3178 100644 --- a/src/lib/pubkey/pbes2/pbes2.h +++ b/src/lib/pubkey/pbes2/pbes2.h @@ -32,6 +32,43 @@ BOTAN_DLL pbes2_encrypt(const secure_vector<uint8_t>& key_bits, RandomNumberGenerator& rng); /** +* Encrypt with PBES2 from PKCS #5 v2.0 +* @param key_bits the input +* @param passphrase the passphrase to use for encryption +* @param msec how many milliseconds to run PBKDF2 +* @param out_iterations_if_nonnull if not null, set to the number +* of PBKDF iterations used +* @param cipher specifies the block cipher to use to encrypt +* @param digest specifies the PRF to use with PBKDF2 (eg "HMAC(SHA-1)") +* @param rng a random number generator +*/ +std::pair<AlgorithmIdentifier, std::vector<uint8_t>> +BOTAN_DLL pbes2_encrypt_msec(const secure_vector<uint8_t>& key_bits, + const std::string& passphrase, + std::chrono::milliseconds msec, + size_t* out_iterations_if_nonnull, + const std::string& cipher, + const std::string& digest, + RandomNumberGenerator& rng); + +/** +* Encrypt with PBES2 from PKCS #5 v2.0 +* @param key_bits the input +* @param passphrase the passphrase to use for encryption +* @param iterations how many iterations to run PBKDF2 +* @param cipher specifies the block cipher to use to encrypt +* @param digest specifies the PRF to use with PBKDF2 (eg "HMAC(SHA-1)") +* @param rng a random number generator +*/ +std::pair<AlgorithmIdentifier, std::vector<uint8_t>> +BOTAN_DLL pbes2_encrypt_iter(const secure_vector<uint8_t>& key_bits, + const std::string& passphrase, + size_t iterations, + const std::string& cipher, + const std::string& digest, + RandomNumberGenerator& rng); + +/** * Decrypt a PKCS #5 v2.0 encrypted stream * @param key_bits the input * @param passphrase the passphrase to use for decryption |