diff options
author | lloyd <[email protected]> | 2015-02-16 20:12:38 +0000 |
---|---|---|
committer | lloyd <[email protected]> | 2015-02-16 20:12:38 +0000 |
commit | 3b9a0c1535e40f8f9fc4cfbc734144ee229df65d (patch) | |
tree | 30c1d4363b4c85561204d26344f40de3e78f6d9d /src/lib | |
parent | 85caef829c9eeb7c224ad3b2e3ffbcfe981c2428 (diff) |
Add new module `ffi` which provides a plain C interface, plus a new
ctypes Python wrapper that uses it. The API is intentionally designed
to have a very simple ABI (extern "C", all structs are opaque, no
memory ownership passing the FFI boundary, limited set of simple types
as args) so the ctypes wrapper is quite simple.
Currently ffi provides ciphers, hashes, MACs, RNGs, PBKDF, KDF,
bcrypt, and most public key operations.
Remove the old boost.python wrapper and all the build code for it.
Diffstat (limited to 'src/lib')
-rw-r--r-- | src/lib/base/buf_comp.h | 7 | ||||
-rw-r--r-- | src/lib/ffi/ffi.cpp | 1099 | ||||
-rw-r--r-- | src/lib/ffi/ffi.h | 342 | ||||
-rw-r--r-- | src/lib/ffi/info.txt | 12 | ||||
-rw-r--r-- | src/lib/kdf/hkdf/hkdf.cpp (renamed from src/lib/misc/hkdf/hkdf.cpp) | 9 | ||||
-rw-r--r-- | src/lib/kdf/hkdf/hkdf.h (renamed from src/lib/misc/hkdf/hkdf.h) | 1 | ||||
-rw-r--r-- | src/lib/kdf/hkdf/info.txt (renamed from src/lib/misc/hkdf/info.txt) | 0 | ||||
-rw-r--r-- | src/lib/misc/pbes2/pbes2.cpp | 4 | ||||
-rw-r--r-- | src/lib/pbkdf/pbkdf2/pbkdf2.cpp | 2 | ||||
-rw-r--r-- | src/lib/pubkey/pubkey.cpp | 2 | ||||
-rw-r--r-- | src/lib/pubkey/pubkey.h | 3 | ||||
-rw-r--r-- | src/lib/tls/tls_exceptn.h | 6 |
12 files changed, 1476 insertions, 11 deletions
diff --git a/src/lib/base/buf_comp.h b/src/lib/base/buf_comp.h index 5d11fdb73..564da2262 100644 --- a/src/lib/base/buf_comp.h +++ b/src/lib/base/buf_comp.h @@ -101,6 +101,13 @@ class BOTAN_DLL Buffered_Computation return output; } + template<typename Alloc> + void final(std::vector<byte, Alloc>& out) + { + out.resize(output_length()); + final_result(&out[0]); + } + /** * Update and finalize computation. Does the same as calling update() * and final() consecutively. diff --git a/src/lib/ffi/ffi.cpp b/src/lib/ffi/ffi.cpp new file mode 100644 index 000000000..937423c69 --- /dev/null +++ b/src/lib/ffi/ffi.cpp @@ -0,0 +1,1099 @@ +/* +* (C) 2015 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include <botan/ffi.h> +#include <botan/system_rng.h> +#include <botan/auto_rng.h> +#include <botan/lookup.h> +#include <botan/aead.h> +#include <botan/hash.h> +#include <botan/mac.h> +#include <botan/pbkdf.h> +#include <botan/version.h> +#include <botan/pubkey.h> +#include <botan/data_src.h> +#include <botan/mem_ops.h> +#include <cstring> +#include <memory> + +#if defined(BOTAN_HAS_RSA) + #include <botan/rsa.h> +#endif + +#if defined(BOTAN_HAS_ECDSA) + #include <botan/ecdsa.h> +#endif + +#if defined(BOTAN_HAS_ECDH) + #include <botan/ecdh.h> +#endif + +#if defined(BOTAN_HAS_BCRYPT) + #include <botan/bcrypt.h> +#endif + +namespace { + +#define BOTAN_ASSERT_ARG_NON_NULL(p) \ + do { if(!p) throw std::invalid_argument("Argument " #p " is null"); } while(0) + +template<typename T, uint32_t MAGIC> +struct botan_struct + { + public: + botan_struct(T* obj) : m_magic(MAGIC), m_obj(obj) {} + ~botan_struct() { m_magic = 0; m_obj.reset(); } + + T* get() const + { + BOTAN_ASSERT_EQUAL(m_magic, MAGIC, "Bad magic value - memory corruption?"); + return m_obj.get(); + } + private: + uint32_t m_magic = 0; + std::unique_ptr<T> m_obj; + }; + +void log_exception(const char* func_name, const char* what) + { + printf("botan ffi %s: %s\n", func_name, what); + } + +template<typename T, uint32_t M> +T& safe_get(botan_struct<T,M>* p) + { + if(!p) + throw std::runtime_error("Null pointer argument"); + if(T* t = p->get()) + return *t; + throw std::runtime_error("Invalid object pointer"); + } + +template<typename T, uint32_t M, typename F> +int apply_fn(botan_struct<T, M>* o, const char* func_name, F func) + { + try + { + if(!o) + throw std::runtime_error("Null object to " + std::string(func_name)); + if(T* t = o->get()) + return func(*t); + } + catch(std::exception& e) + { + log_exception(func_name, e.what()); + return -1; + } + catch(...) + { + log_exception(func_name, "unknown exception type"); + return -2; + } + + return -1; + } + +template<typename Alloc> +int write_output(uint8_t out[], size_t* out_len, const std::vector<uint8_t, Alloc>& buf) + { + Botan::clear_mem(out, *out_len); + const size_t avail = *out_len; + *out_len = buf.size(); + if(avail >= buf.size()) + { + Botan::copy_mem(out, &buf[0], buf.size()); + return 0; + } + return -1; + } + +#define BOTAN_FFI_DO(T, obj, block) apply_fn(obj, BOTAN_CURRENT_FUNCTION, [=](T& obj) { do { block } while(0); return 0; }) + +} + +extern "C" { + +struct botan_rng_struct : public botan_struct<Botan::RandomNumberGenerator, 0x4901F9C1> + { + using botan_struct::botan_struct; + }; + +struct botan_hash_struct : public botan_struct<Botan::HashFunction, 0x1F0A4F84> + { + using botan_struct::botan_struct; + }; + +struct botan_mac_struct : public botan_struct<Botan::MessageAuthenticationCode, 0xA06E8FC1> + { + using botan_struct::botan_struct; + }; + +struct botan_cipher_struct : public botan_struct<Botan::Cipher_Mode, 0xB4A2BF9C> + { + using botan_struct::botan_struct; + Botan::secure_vector<uint8_t> m_buf; + }; + +struct botan_pubkey_struct : public botan_struct<Botan::Public_Key, 0x2C286519> + { + using botan_struct::botan_struct; + }; + +struct botan_privkey_struct : public botan_struct<Botan::Private_Key, 0x7F96385E> + { + using botan_struct::botan_struct; + }; + +struct botan_pk_op_encrypt_struct : public botan_struct<Botan::PK_Encryptor, 0x891F3FC3> + { + using botan_struct::botan_struct; + }; + +struct botan_pk_op_decrypt_struct : public botan_struct<Botan::PK_Decryptor, 0x912F3C37> + { + using botan_struct::botan_struct; + }; + +struct botan_pk_op_sign_struct : public botan_struct<Botan::PK_Signer, 0x1AF0C39F> + { + using botan_struct::botan_struct; + }; + +struct botan_pk_op_verify_struct : public botan_struct<Botan::PK_Verifier, 0x2B91F936> + { + using botan_struct::botan_struct; + }; + +struct botan_pk_op_ka_struct : public botan_struct<Botan::PK_Key_Agreement, 0x2939CAB1> + { + using botan_struct::botan_struct; + }; + +/* +* Versioning +*/ +uint32_t botan_ffi_api_version() + { + return 20150210; // should match value in info.txt + } + +const char* botan_version_string() + { + return Botan::version_cstr(); + } + +uint32_t botan_version_major() { return Botan::version_major(); } +uint32_t botan_version_minor() { return Botan::version_minor(); } +uint32_t botan_version_patch() { return Botan::version_patch(); } +uint32_t botan_version_datestamp() { return Botan::version_datestamp(); } + +int botan_rng_init(botan_rng_t* rng_out, const char* rng_type) + { + // Just gives unique_ptr something to delete, really + class RNG_Wrapper : public Botan::RandomNumberGenerator + { + public: + RNG_Wrapper(Botan::RandomNumberGenerator& rng) : m_rng(rng) {} + void randomize(Botan::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 { return m_rng.name(); } + void reseed(size_t poll_bits = 256) { m_rng.reseed(poll_bits); } + void add_entropy(const Botan::byte in[], size_t len) { m_rng.add_entropy(in, len); } + private: + Botan::RandomNumberGenerator& m_rng; + }; + + try + { + BOTAN_ASSERT_ARG_NON_NULL(rng_out); + + if(rng_type == nullptr || *rng_type == 0) + rng_type = "system"; + + const std::string rng_type_s(rng_type); + + std::unique_ptr<Botan::RandomNumberGenerator> rng; + + if(rng_type_s == "system") + rng.reset(new RNG_Wrapper(Botan::system_rng())); + else if(rng_type_s == "user") + rng.reset(new Botan::AutoSeeded_RNG); + + if(rng) + { + *rng_out = new botan_rng_struct(rng.release()); + return 0; + } + } + catch(std::exception& e) + { + log_exception(BOTAN_CURRENT_FUNCTION, e.what()); + } + catch(...) + { + log_exception(BOTAN_CURRENT_FUNCTION, "unknown"); + } + + return -1; + } + +int botan_rng_destroy(botan_rng_t rng) + { + delete rng; + return 0; + } + +int botan_rng_get(botan_rng_t rng, uint8_t* out, size_t out_len) + { + return BOTAN_FFI_DO(Botan::RandomNumberGenerator, rng, { rng.randomize(out, out_len); }); + } + +int botan_rng_reseed(botan_rng_t rng, size_t bits) + { + return BOTAN_FFI_DO(Botan::RandomNumberGenerator, rng, { rng.reseed(bits); }); + } + +int botan_hash_init(botan_hash_t* hash, const char* hash_name, uint32_t flags) + { + try + { + if(!hash || !hash_name || flags != 0) + return -1; + + if(auto h = Botan::get_hash_function(hash_name)) + { + *hash = new botan_hash_struct(h); + return 0; + } + } + catch(std::exception& e) + { + log_exception(BOTAN_CURRENT_FUNCTION, e.what()); + } + catch(...) + { + log_exception(BOTAN_CURRENT_FUNCTION, "unknown"); + } + + return -2; + } + +int botan_hash_destroy(botan_hash_t hash) + { + delete hash; + return 0; + } + +int botan_hash_output_length(botan_hash_t hash, size_t* out) + { + return BOTAN_FFI_DO(Botan::HashFunction, hash, { *out = hash.output_length(); }); + } + +int botan_hash_clear(botan_hash_t hash) + { + return BOTAN_FFI_DO(Botan::HashFunction, hash, { hash.clear(); }); + } + +int botan_hash_update(botan_hash_t hash, const uint8_t* buf, size_t len) + { + return BOTAN_FFI_DO(Botan::HashFunction, hash, { hash.update(buf, len); }); + } + +int botan_hash_final(botan_hash_t hash, uint8_t out[]) + { + return BOTAN_FFI_DO(Botan::HashFunction, hash, { hash.final(out); }); + } + +int botan_mac_init(botan_mac_t* mac, const char* mac_name, uint32_t flags) + { + try + { + if(!mac || !mac_name || flags != 0) + return -1; + + if(auto m = Botan::get_mac(mac_name)) + { + *mac = new botan_mac_struct(m); + return 0; + } + } + catch(std::exception& e) + { + log_exception(BOTAN_CURRENT_FUNCTION, e.what()); + } + catch(...) + { + log_exception(BOTAN_CURRENT_FUNCTION, "unknown"); + } + + return -2; + } + +int botan_mac_destroy(botan_mac_t mac) + { + delete mac; + return 0; + } + +int botan_mac_set_key(botan_mac_t mac, const uint8_t* key, size_t key_len) + { + return BOTAN_FFI_DO(Botan::MessageAuthenticationCode, mac, { mac.set_key(key, key_len); }); + } + +int botan_mac_output_length(botan_mac_t mac, size_t* out) + { + return BOTAN_FFI_DO(Botan::MessageAuthenticationCode, mac, { *out = mac.output_length(); }); + } + +int botan_mac_clear(botan_mac_t mac) + { + return BOTAN_FFI_DO(Botan::MessageAuthenticationCode, mac, { mac.clear(); }); + } + +int botan_mac_update(botan_mac_t mac, const uint8_t* buf, size_t len) + { + return BOTAN_FFI_DO(Botan::MessageAuthenticationCode, mac, { mac.update(buf, len); }); + } + +int botan_mac_final(botan_mac_t mac, uint8_t out[]) + { + return BOTAN_FFI_DO(Botan::MessageAuthenticationCode, mac, { mac.final(out); }); + } + +int botan_cipher_init(botan_cipher_t* cipher, const char* cipher_name, uint32_t flags) + { + try + { + Botan::Cipher_Dir dir = (flags & 0) ? Botan::DECRYPTION : Botan::ENCRYPTION; + std::unique_ptr<Botan::Cipher_Mode> mode(Botan::get_cipher_mode(cipher_name, dir)); + if(!mode) + return -1; + *cipher = new botan_cipher_struct(mode.release()); + return 0; + } + catch(std::exception& e) + { + log_exception(BOTAN_CURRENT_FUNCTION, e.what()); + } + catch(...) + { + log_exception(BOTAN_CURRENT_FUNCTION, "unknown"); + } + + return -1; + } + +int botan_cipher_destroy(botan_cipher_t cipher) + { + delete cipher; + return 0; + } + +int botan_cipher_clear(botan_cipher_t cipher) + { + return BOTAN_FFI_DO(Botan::Cipher_Mode, cipher, { cipher.clear(); }); + } + +int botan_cipher_set_key(botan_cipher_t cipher, + const uint8_t* key, size_t key_len) + { + return BOTAN_FFI_DO(Botan::Cipher_Mode, cipher, { cipher.set_key(key, key_len); }); + } + +int botan_cipher_start(botan_cipher_t cipher_obj, + const uint8_t* nonce, size_t nonce_len) + { + try + { + Botan::Cipher_Mode& cipher = safe_get(cipher_obj); + BOTAN_ASSERT(cipher.start(nonce, nonce_len).empty(), "Ciphers have no prefix"); + cipher_obj->m_buf.reserve(cipher.update_granularity()); + return 0; + } + catch(std::exception& e) + { + log_exception(BOTAN_CURRENT_FUNCTION, e.what()); + } + + return -1; + } + +int botan_cipher_update(botan_cipher_t cipher_obj, + uint32_t flags, + uint8_t output[], + size_t output_size, + size_t* output_written, + const uint8_t input[], + size_t input_size, + size_t* input_consumed) + { + using namespace Botan; + + try + { + Cipher_Mode& cipher = safe_get(cipher_obj); + secure_vector<uint8_t>& mbuf = cipher_obj->m_buf; + + const bool final_input = (flags & BOTAN_CIPHER_UPDATE_FLAG_FINAL); + + if(final_input) + { + mbuf.assign(input, input + input_size); + *input_consumed = input_size; + + try + { + cipher.finish(mbuf); + } + catch(Integrity_Failure& e) + { + log_exception(BOTAN_CURRENT_FUNCTION, e.what()); + return -2; + } + + *output_written = mbuf.size(); + + if(mbuf.size() <= output_size) + { + copy_mem(output, &mbuf[0], mbuf.size()); + mbuf.clear(); + return 0; + } + + return -1; + } + + if(input_size == 0) + { + // Currently must take entire buffer in this case + *output_written = mbuf.size(); + if(output_size >= mbuf.size()) + { + copy_mem(output, &mbuf[0], mbuf.size()); + mbuf.clear(); + return 0; + } + + return -1; + } + + const size_t ud = cipher.update_granularity(); + BOTAN_ASSERT(cipher.update_granularity() > cipher.minimum_final_size(), "logic error"); + +#if 0 + // Avoiding double copy: + if(Online_Cipher_Mode* ocm = dynamic_cast<Online_Cipher_Mode*>(&cipher)) + { + const size_t taken = round_down(input_size, ud); + *input_consumed = taken; + *output_size = taken; + copy_mem(&output[0], input, taken); + ocm->update_in_place(output, taken); + return 0; + } +#endif + + mbuf.resize(ud); + size_t taken = 0, written = 0; + + while(input_size >= ud && output_size >= ud) + { + copy_mem(&mbuf[0], input, ud); + cipher.update(mbuf); + + input_size -= ud; + input += ud; + taken += ud; + + output_size -= ud; + output += ud; + written += ud; + } + + *output_written = written; + *input_consumed = taken; + + } + catch(std::exception& e) + { + log_exception(BOTAN_CURRENT_FUNCTION, e.what()); + } + + return -1; + } + +int botan_cipher_set_associated_data(botan_cipher_t cipher, + const uint8_t* ad, + size_t ad_len) + { + return BOTAN_FFI_DO(Botan::Cipher_Mode, cipher, { + if(Botan::AEAD_Mode* aead = dynamic_cast<Botan::AEAD_Mode*>(&cipher)) + { + aead->set_associated_data(ad, ad_len); + return 0; + } + return -1; + }); + } + +int botan_cipher_valid_nonce_length(botan_cipher_t cipher, size_t nl) + { + return BOTAN_FFI_DO(Botan::Cipher_Mode, cipher, { return cipher.valid_nonce_length(nl) ? 1 : 0; }); + } + +int botan_cipher_get_default_nonce_length(botan_cipher_t cipher, size_t* nl) + { + return BOTAN_FFI_DO(Botan::Cipher_Mode, cipher, { *nl = cipher.default_nonce_length(); }); + } + +int botan_cipher_get_tag_length(botan_cipher_t cipher, size_t* tl) + { + return BOTAN_FFI_DO(Botan::Cipher_Mode, cipher, { *tl = cipher.tag_size(); }); + } + +int botan_pbkdf(const char* pbkdf_algo, uint8_t out[], size_t out_len, + const char* pass, const uint8_t salt[], size_t salt_len, + size_t iterations) + { + try + { + std::unique_ptr<Botan::PBKDF> pbkdf(Botan::get_pbkdf(pbkdf_algo)); + + auto r = pbkdf->derive_key(out_len, pass, salt, salt_len, iterations).bits_of(); + + if(r.size() != out_len) + throw std::runtime_error(std::string(pbkdf_algo) + " produced " + + std::to_string(r.size()) + " asked for " + + std::to_string(out_len)); + + Botan::copy_mem(out, &r[0], out_len); + } + catch(std::exception& e) + { + log_exception(BOTAN_CURRENT_FUNCTION, e.what()); + } + + return -1; + } + +int botan_pbkdf_timed(const char* pbkdf_algo, + uint8_t out[], size_t out_len, + const char* password, + const uint8_t salt[], size_t salt_len, + size_t ms_to_run, + size_t* iterations_used) + { + try + { + std::unique_ptr<Botan::PBKDF> pbkdf(Botan::get_pbkdf(pbkdf_algo)); + + auto r = pbkdf->derive_key(out_len, password, salt, salt_len, + std::chrono::milliseconds(ms_to_run), + *iterations_used).bits_of(); + + if(r.size() != out_len) + throw std::runtime_error(std::string(pbkdf_algo) + " produced " + + std::to_string(r.size()) + " asked for " + + std::to_string(out_len)); + + Botan::copy_mem(out, &r[0], out_len); + } + catch(std::exception& e) + { + log_exception(BOTAN_CURRENT_FUNCTION, e.what()); + } + + return -1; + } + +int botan_kdf(const char* kdf_algo, + uint8_t out[], size_t out_len, + const uint8_t secret[], size_t secret_len, + const uint8_t salt[], size_t salt_len) + { + try + { + std::unique_ptr<Botan::KDF> kdf(Botan::get_kdf(kdf_algo)); + auto r = kdf->derive_key(out_len, secret, secret_len, salt, salt_len); + if(r.size() != out_len) + throw std::runtime_error(std::string(kdf_algo) + " produced " + + std::to_string(r.size()) + " asked for " + + std::to_string(out_len)); + Botan::copy_mem(out, &r[0], out_len); + } + catch(std::exception& e) + { + log_exception(BOTAN_CURRENT_FUNCTION, e.what()); + } + + return -1; + } + +#if defined(BOTAN_HAS_BCRYPT) +int botan_bcrypt_generate(char* out, size_t out_len, const char* pass, + botan_rng_t rng_obj, size_t wf) + { + try + { + BOTAN_ASSERT_ARG_NON_NULL(out); + BOTAN_ASSERT_ARG_NON_NULL(pass); + + if(wf < 2 || wf > 30) + throw std::runtime_error("Bad bcrypt work factor " + std::to_string(wf)); + + Botan::RandomNumberGenerator& rng = safe_get(rng_obj); + + std::memset(out, 0, out_len); + const std::string c = Botan::generate_bcrypt(pass, rng, wf); + if(out_len <= c.size()) + return ENOMEM; + std::memcpy(out, c.c_str(), c.size()); + return 0; + } + catch(std::exception& e) + { + log_exception(BOTAN_CURRENT_FUNCTION, e.what()); + } + catch(...) + { + log_exception(BOTAN_CURRENT_FUNCTION, "unknown"); + } + + return -1; + } + +int botan_bcrypt_is_valid(const char* pass, const char* hash) + { + try + { + if(Botan::check_bcrypt(pass, hash)) + return 0; // success + return 1; + } + catch(std::exception& e) + { + log_exception(BOTAN_CURRENT_FUNCTION, e.what()); + } + catch(...) + { + log_exception(BOTAN_CURRENT_FUNCTION, "unknown"); + } + + return -1; + } + +#endif + +int botan_privkey_create_rsa(botan_privkey_t* key, botan_rng_t rng_obj, size_t n_bits) + { + try + { + *key = nullptr; + +#if defined(BOTAN_HAS_RSA) + Botan::RandomNumberGenerator& rng = safe_get(rng_obj); + std::unique_ptr<Botan::RSA_PrivateKey> rsa(new Botan::RSA_PrivateKey(rng, n_bits)); + *key = new botan_privkey_struct(rsa.release()); + return 0; +#endif + } + catch(std::exception& e) + { + log_exception(BOTAN_CURRENT_FUNCTION, e.what()); + } + + return -1; + } + + +int botan_privkey_create_ecdsa(botan_privkey_t* key, botan_rng_t rng_obj, const char* params) + { + try + { +#if defined(BOTAN_HAS_ECDSA) + Botan::RandomNumberGenerator& rng = safe_get(rng_obj); + Botan::EC_Group grp(params); + std::unique_ptr<Botan::ECDSA_PrivateKey> ecdsa(new Botan::ECDSA_PrivateKey(rng, grp)); + *key = new botan_privkey_struct(ecdsa.release()); + return 0; +#endif + } + catch(std::exception& e) + { + log_exception(BOTAN_CURRENT_FUNCTION, e.what()); + } + + return -1; + } + +int botan_privkey_create_ecdh(botan_privkey_t* key, botan_rng_t rng_obj, const char* params) + { + try + { +#if defined(BOTAN_HAS_ECDH) + Botan::RandomNumberGenerator& rng = safe_get(rng_obj); + Botan::EC_Group grp(params); + std::unique_ptr<Botan::ECDH_PrivateKey> ecdh(new Botan::ECDH_PrivateKey(rng, grp)); + *key = new botan_privkey_struct(ecdh.release()); + return 0; +#endif + } + catch(std::exception& e) + { + log_exception(BOTAN_CURRENT_FUNCTION, e.what()); + } + + return -1; + } + +int botan_privkey_load(botan_privkey_t* key, botan_rng_t rng_obj, + const uint8_t bits[], size_t len, + const char* password) + { + try + { + Botan::DataSource_Memory src(bits, len); + + if(password == nullptr) + password = ""; + + Botan::RandomNumberGenerator& rng = safe_get(rng_obj); + + std::unique_ptr<Botan::PKCS8_PrivateKey> pkcs8; + pkcs8.reset(Botan::PKCS8::load_key(src, rng, password)); + + if(pkcs8) + { + *key = new botan_privkey_struct(pkcs8.release()); + return 0; + } + } + catch(std::exception& e) + { + log_exception(BOTAN_CURRENT_FUNCTION, e.what()); + } + + return -1; + *key = nullptr; + return -1; + } + +int botan_privkey_destroy(botan_privkey_t key) + { + delete key; + return 0; + } + +int botan_pubkey_destroy(botan_privkey_t key) + { + delete key; + return 0; + } + +int botan_privkey_export_pubkey(botan_pubkey_t* pubout, botan_privkey_t key_obj) + { + try + { + std::unique_ptr<Botan::Public_Key> pubkey( + Botan::X509::load_key( + Botan::X509::BER_encode(safe_get(key_obj)))); + *pubout = new botan_pubkey_struct(pubkey.release()); + return 0; + } + catch(std::exception& e) + { + log_exception(BOTAN_CURRENT_FUNCTION, e.what()); + } + + return -1; + } + +int botan_pubkey_algo_name(botan_pubkey_t key, char out[], size_t* out_len) + { + return apply_fn(key, BOTAN_CURRENT_FUNCTION, + [out,out_len](Botan::Public_Key& k) + { + const std::string name = k.algo_name(); + const size_t avail = *out_len; + *out_len = name.size() + 1; + if(avail > 1 + name.size()) + { + Botan::copy_mem(out, name.data(), name.size()); + out[name.size()] = 0; + return 0; + } + return -1; + }); + } + +int botan_pubkey_export(botan_pubkey_t key, uint8_t out[], size_t* out_len, uint32_t flags) + { + return BOTAN_FFI_DO(Botan::Public_Key, key, { + return write_output(out, out_len, Botan::X509::BER_encode(key)); + }); + } + +int botan_privkey_export(botan_privkey_t key, uint8_t out[], size_t* out_len, uint32_t flags) + { + return BOTAN_FFI_DO(Botan::Private_Key, key, { + return write_output(out, out_len, Botan::PKCS8::BER_encode(key)); + }); + } + +int botan_privkey_export_encrypted(botan_privkey_t key, + uint8_t out[], size_t* out_len, + botan_rng_t rng_obj, + const char* passphrase, + const char* encryption_algo, + uint32_t flags) + { + return BOTAN_FFI_DO(Botan::Private_Key, key, { + auto ber = Botan::PKCS8::BER_encode(key, safe_get(rng_obj), passphrase, + std::chrono::milliseconds(300), + encryption_algo); + return write_output(out, out_len, ber); + }); + } + +int botan_pubkey_estimated_strength(botan_pubkey_t key, size_t* estimate) + { + return BOTAN_FFI_DO(Botan::Public_Key, key, { *estimate = key.estimated_strength(); }); + } + +int botan_pubkey_fingerprint(botan_pubkey_t key, const char* hash_fn, + uint8_t out[], size_t* out_len) + { + return apply_fn(key, BOTAN_CURRENT_FUNCTION, + [hash_fn,out,out_len](Botan::Public_Key& k) + { + std::unique_ptr<Botan::HashFunction> h(Botan::get_hash(hash_fn)); + auto z = h->process(k.x509_subject_public_key()); + *out_len = std::min(z.size(), *out_len); + Botan::copy_mem(out, &z[0], *out_len); + return 0; + }); + *out_len = 0; + return -1; + } + +int botan_pk_op_encrypt_create(botan_pk_op_encrypt_t* op, + botan_pubkey_t key_obj, + const char* padding, + uint32_t flags) + { + try + { + BOTAN_ASSERT_NONNULL(op); + + if(flags != 0) + return -2; + + std::unique_ptr<Botan::PK_Encryptor> pk(new Botan::PK_Encryptor_EME(safe_get(key_obj), padding)); + *op = new botan_pk_op_encrypt_struct(pk.release()); + return 0; + } + catch(std::exception& e) + { + log_exception(BOTAN_CURRENT_FUNCTION, e.what()); + } + + return -1; + } + +int botan_pk_op_encrypt_destroy(botan_pk_op_encrypt_t op) + { + delete op; + return 0; + } + +int botan_pk_op_encrypt(botan_pk_op_encrypt_t op, + botan_rng_t rng_obj, + uint8_t out[], size_t* out_len, + const uint8_t plaintext[], size_t plaintext_len) + { + return BOTAN_FFI_DO(Botan::PK_Encryptor, op, { + return write_output(out, out_len, op.encrypt(plaintext, plaintext_len, safe_get(rng_obj))); + }); + } + +/* +* Public Key Decryption +*/ +int botan_pk_op_decrypt_create(botan_pk_op_decrypt_t* op, + botan_privkey_t key_obj, + const char* padding, + uint32_t flags) + { + try + { + BOTAN_ASSERT_NONNULL(op); + + if(flags != 0) + return -2; + + std::unique_ptr<Botan::PK_Decryptor> pk(new Botan::PK_Decryptor_EME(safe_get(key_obj), padding)); + *op = new botan_pk_op_decrypt_struct(pk.release()); + return 0; + } + catch(std::exception& e) + { + log_exception(BOTAN_CURRENT_FUNCTION, e.what()); + } + + return -1; + } + +int botan_pk_op_decrypt_destroy(botan_pk_op_decrypt_t op) + { + delete op; + return 0; + } + +int botan_pk_op_decrypt(botan_pk_op_decrypt_t op, + uint8_t out[], size_t* out_len, + uint8_t ciphertext[], size_t ciphertext_len) + { + return BOTAN_FFI_DO(Botan::PK_Decryptor, op, { + return write_output(out, out_len, op.decrypt(ciphertext, ciphertext_len)); + }); + } + +/* +* Signature Generation +*/ +int botan_pk_op_sign_create(botan_pk_op_sign_t* op, + botan_privkey_t key_obj, + const char* hash, + uint32_t flags) + { + try + { + BOTAN_ASSERT_NONNULL(op); + + if(flags != 0) + return -2; + + std::unique_ptr<Botan::PK_Signer> pk(new Botan::PK_Signer(safe_get(key_obj), hash)); + *op = new botan_pk_op_sign_struct(pk.release()); + return 0; + } + catch(std::exception& e) + { + log_exception(BOTAN_CURRENT_FUNCTION, e.what()); + } + + return -1; + } + +int botan_pk_op_sign_destroy(botan_pk_op_sign_t op) + { + delete op; + return 0; + } + +int botan_pk_op_sign_update(botan_pk_op_sign_t op, const uint8_t in[], size_t in_len) + { + return BOTAN_FFI_DO(Botan::PK_Signer, op, { op.update(in, in_len); }); + } + +int botan_pk_op_sign_finish(botan_pk_op_sign_t op, botan_rng_t rng_obj, uint8_t out[], size_t* out_len) + { + return BOTAN_FFI_DO(Botan::PK_Signer, op, { + return write_output(out, out_len, op.signature(safe_get(rng_obj))); + }); + } + +int botan_pk_op_verify_create(botan_pk_op_verify_t* op, + botan_pubkey_t key_obj, + const char* hash, + uint32_t flags) + { + try + { + BOTAN_ASSERT_NONNULL(op); + + if(flags != 0) + return -2; + + std::unique_ptr<Botan::PK_Verifier> pk(new Botan::PK_Verifier(safe_get(key_obj), hash)); + *op = new botan_pk_op_verify_struct(pk.release()); + return 0; + } + catch(std::exception& e) + { + log_exception(BOTAN_CURRENT_FUNCTION, e.what()); + } + + return -1; + } + +int botan_pk_op_verify_destroy(botan_pk_op_verify_t op) + { + delete op; + return 0; + } + +int botan_pk_op_verify_update(botan_pk_op_verify_t op, const uint8_t in[], size_t in_len) + { + return BOTAN_FFI_DO(Botan::PK_Verifier, op, { op.update(in, in_len); }); + } + +int botan_pk_op_verify_finish(botan_pk_op_verify_t op, const uint8_t sig[], size_t sig_len) + { + return BOTAN_FFI_DO(Botan::PK_Verifier, op, { + const bool legit = op.check_signature(sig, sig_len); + + if(legit) + return 0; + else + return 1; + }); + } + +int botan_pk_op_key_agreement_create(botan_pk_op_ka_t* op, + botan_privkey_t key_obj, + const char* kdf, + uint32_t flags) + { + try + { + BOTAN_ASSERT_NONNULL(op); + + if(flags != 0) + return -2; + + std::unique_ptr<Botan::PK_Key_Agreement> pk(new Botan::PK_Key_Agreement(safe_get(key_obj), kdf)); + *op = new botan_pk_op_ka_struct(pk.release()); + return 0; + } + catch(std::exception& e) + { + log_exception(BOTAN_CURRENT_FUNCTION, e.what()); + } + + return -1; + } + +int botan_pk_op_key_agreement_destroy(botan_pk_op_ka_t op) + { + delete op; + return 0; + } + +int botan_pk_op_key_agreement(botan_pk_op_ka_t op, + uint8_t out[], size_t* out_len, + const uint8_t other_key[], size_t other_key_len, + const uint8_t salt[], size_t salt_len) + { + return BOTAN_FFI_DO(Botan::PK_Key_Agreement, op, { + auto k = op.derive_key(*out_len, other_key, other_key_len, salt, salt_len).bits_of(); + return write_output(out, out_len, k); + }); + } + +} + diff --git a/src/lib/ffi/ffi.h b/src/lib/ffi/ffi.h new file mode 100644 index 000000000..cda2c1480 --- /dev/null +++ b/src/lib/ffi/ffi.h @@ -0,0 +1,342 @@ +/* +* (C) 2015 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_FFI_H__ +#define BOTAN_FFI_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <botan/build.h> +#include <stdint.h> +#include <stddef.h> + +/* +* TODO: +* - Better error reporting +* - User callback for exception logging +* - Doxygen comments for all functions/params +* - X.509 certs and PKIX path validation goo +* - TLS +*/ + +/* +* Versioning +*/ +BOTAN_DLL uint32_t botan_ffi_api_version(); + +BOTAN_DLL const char* botan_version_string(); +BOTAN_DLL uint32_t botan_version_major(); +BOTAN_DLL uint32_t botan_version_minor(); +BOTAN_DLL uint32_t botan_version_patch(); +BOTAN_DLL uint32_t botan_version_datestamp(); + +/* +* Error handling +*/ +//const char* botan_error_description(int err); + +/* +* Utility +*/ +BOTAN_DLL int botan_same_mem(const uint8_t* x, const uint8_t* y, size_t len); + +/* +* RNG +*/ +typedef struct botan_rng_struct* botan_rng_t; + +BOTAN_DLL int botan_rng_init(botan_rng_t* rng, const char* rng_type); +BOTAN_DLL int botan_rng_destroy(botan_rng_t rng); + +BOTAN_DLL int botan_rng_get(botan_rng_t rng, uint8_t* out, size_t out_len); +BOTAN_DLL int botan_rng_reseed(botan_rng_t rng, size_t bits); + +/* +* Hashing +*/ +typedef struct botan_hash_struct* botan_hash_t; + +BOTAN_DLL int botan_hash_init(botan_hash_t* hash, const char* hash_name, uint32_t flags); +BOTAN_DLL int botan_hash_destroy(botan_hash_t hash); +BOTAN_DLL int botan_hash_clear(botan_hash_t hash); + +BOTAN_DLL int botan_hash_update(botan_hash_t hash, const uint8_t* in, size_t in_len); +BOTAN_DLL int botan_hash_final(botan_hash_t hash, uint8_t out[]); +BOTAN_DLL int botan_hash_output_length(botan_hash_t hash, size_t* output_length); + +/* +* Message Authentication +*/ +typedef struct botan_mac_struct* botan_mac_t; + +BOTAN_DLL int botan_mac_init(botan_mac_t* mac, const char* mac_name, uint32_t flags); +BOTAN_DLL int botan_mac_destroy(botan_mac_t mac); +BOTAN_DLL int botan_mac_clear(botan_mac_t hash); + +BOTAN_DLL int botan_mac_set_key(botan_mac_t mac, const uint8_t* key, size_t key_len); +BOTAN_DLL int botan_mac_update(botan_mac_t mac, const uint8_t* buf, size_t len); +BOTAN_DLL int botan_mac_final(botan_mac_t mac, uint8_t out[]); +BOTAN_DLL int botan_mac_output_length(botan_mac_t mac, size_t* output_length); + +/* +* Cipher modes +*/ +typedef struct botan_cipher_struct* botan_cipher_t; + +BOTAN_DLL int botan_cipher_init(botan_cipher_t* cipher, const char* name, uint32_t flags); +BOTAN_DLL int botan_cipher_destroy(botan_cipher_t cipher); +BOTAN_DLL int botan_cipher_clear(botan_cipher_t hash); + +BOTAN_DLL int botan_cipher_valid_nonce_length(botan_cipher_t cipher, size_t nl); +BOTAN_DLL int botan_cipher_get_tag_length(botan_cipher_t cipher, size_t* tag_size); +BOTAN_DLL int botan_cipher_get_default_nonce_length(botan_cipher_t cipher, size_t* nl); + +BOTAN_DLL int botan_cipher_set_key(botan_cipher_t cipher, + const uint8_t* key, size_t key_len); + +BOTAN_DLL int botan_cipher_set_associated_data(botan_cipher_t cipher, + const uint8_t* ad, size_t ad_len); + +BOTAN_DLL int botan_cipher_start(botan_cipher_t cipher, + const uint8_t* nonce, size_t nonce_len); + +#define BOTAN_CIPHER_UPDATE_FLAG_FINAL (1U << 0) + +BOTAN_DLL int botan_cipher_update(botan_cipher_t cipher, + uint32_t flags, + uint8_t output[], + size_t output_size, + size_t* output_written, + const uint8_t input_bytes[], + size_t input_size, + size_t* input_consumed); + + +/* +* PBKDF +*/ +BOTAN_DLL int botan_pbkdf(const char* pbkdf_algo, + uint8_t out[], size_t out_len, + const char* password, + const uint8_t salt[], size_t salt_len, + size_t iterations); + +BOTAN_DLL int botan_pbkdf_timed(const char* pbkdf_algo, + uint8_t out[], size_t out_len, + const char* password, + const uint8_t salt[], size_t salt_len, + size_t milliseconds_to_run, + size_t* out_iterations_used); + +/* +* KDF +*/ +BOTAN_DLL int botan_kdf(const char* kdf_algo, + uint8_t out[], size_t out_len, + const uint8_t secret[], size_t secret_len, + const uint8_t salt[], size_t salt_len); + +/* +* Bcrypt +*/ +#if defined(BOTAN_HAS_BCRYPT) + +BOTAN_DLL int botan_bcrypt_generate(char* out, size_t out_len, + const char* pass, + botan_rng_t rng, + size_t work_factor); + +/** +* Returns 0 if if this password/hash combination is valid +* Returns 1 if the combination is not valid +* Returns -1 on error +*/ +BOTAN_DLL int botan_bcrypt_is_valid(const char* pass, const char* hash); + +#endif + +/* +* Public/private key creation, import, ... +*/ +typedef struct botan_pubkey_struct* botan_pubkey_t; +typedef struct botan_privkey_struct* botan_privkey_t; + +BOTAN_DLL int botan_privkey_create_rsa(botan_privkey_t* key, botan_rng_t rng, size_t n_bits); +//BOTAN_DLL int botan_privkey_create_dsa(botan_privkey_t* key, botan_rng_t rng, size_t p_bits, size_t q_bits); +//BOTAN_DLL int botan_privkey_create_dh(botan_privkey_t* key, botan_rng_t rng, size_t p_bits); +BOTAN_DLL int botan_privkey_create_ecdsa(botan_privkey_t* key, botan_rng_t rng, const char* params); +BOTAN_DLL int botan_privkey_create_ecdh(botan_privkey_t* key, botan_rng_t rng, const char* params); +//BOTAN_DLL int botan_privkey_create_mceliece(botan_privkey_t* key, botan_rng_t rng, size_t n, size_t t); + +/* +* Input currently assumed to be PKCS #8 structure; +*/ +BOTAN_DLL int botan_privkey_load(botan_privkey_t* key, botan_rng_t rng, + const uint8_t bits[], size_t len, + const char* password); +BOTAN_DLL int botan_pubkey_load(botan_privkey_t* key, + const uint8_t bits[], size_t len, + const char* password); + +BOTAN_DLL int botan_privkey_export_pubkey(botan_pubkey_t* out, botan_privkey_t in); + +BOTAN_DLL int botan_pubkey_destroy(botan_privkey_t key); +BOTAN_DLL int botan_privkey_destroy(botan_privkey_t key); + +#define BOTAN_PRIVKEY_EXPORT_FLAG_DER 0 +#define BOTAN_PRIVKEY_EXPORT_FLAG_PEM 1 + +/* +* On input *out_len is number of bytes in out[] +* On output *out_len is number of bytes written (or required) +* If out is not big enough no output is written, *out_len is set and 1 is returned +* Returns 0 on success and sets +* If some other error occurs a negative integer is returned. +*/ +BOTAN_DLL int botan_pubkey_export(botan_pubkey_t key, uint8_t out[], size_t* out_len, uint32_t flags); +BOTAN_DLL int botan_privkey_export(botan_privkey_t key, uint8_t out[], size_t* out_len, uint32_t flags); + +/* +* Set encryption_algo to NULL to have the library choose a default (recommended) +*/ +BOTAN_DLL int botan_privkey_export_encrypted(botan_privkey_t key, + uint8_t out[], size_t* out_len, + botan_rng_t rng, + const char* passphrase, + const char* encryption_algo, + uint32_t flags); + +BOTAN_DLL int botan_pubkey_algo_name(botan_pubkey_t key, char out[], size_t* out_len); + +BOTAN_DLL int botan_pubkey_estimated_strength(botan_pubkey_t key, size_t* estimate); + +BOTAN_DLL int botan_pubkey_fingerprint(botan_pubkey_t key, const char* hash, + uint8_t out[], size_t* out_len); + +/* +* Public Key Encryption +*/ +typedef struct botan_pk_op_encrypt_struct* botan_pk_op_encrypt_t; + +BOTAN_DLL int botan_pk_op_encrypt_create(botan_pk_op_encrypt_t* op, + botan_pubkey_t key, + const char* padding, + uint32_t flags); + +BOTAN_DLL int botan_pk_op_encrypt_destroy(botan_pk_op_encrypt_t op); + +BOTAN_DLL int botan_pk_op_encrypt(botan_pk_op_encrypt_t op, + botan_rng_t rng, + uint8_t out[], size_t* out_len, + const uint8_t plaintext[], size_t plaintext_len); + +/* +* Public Key Decryption +*/ +typedef struct botan_pk_op_decrypt_struct* botan_pk_op_decrypt_t; + +BOTAN_DLL int botan_pk_op_decrypt_create(botan_pk_op_decrypt_t* op, + botan_privkey_t key, + const char* padding, + uint32_t flags); +BOTAN_DLL int botan_pk_op_decrypt_destroy(botan_pk_op_decrypt_t op); + +BOTAN_DLL int botan_pk_op_decrypt(botan_pk_op_decrypt_t op, + uint8_t out[], size_t* out_len, + uint8_t ciphertext[], size_t ciphertext_len); + +/* +* Signature Generation +*/ +typedef struct botan_pk_op_sign_struct* botan_pk_op_sign_t; + +BOTAN_DLL int botan_pk_op_sign_create(botan_pk_op_sign_t* op, + botan_privkey_t key, + const char* hash_and_padding, + uint32_t flags); +BOTAN_DLL int botan_pk_op_sign_destroy(botan_pk_op_sign_t op); + +BOTAN_DLL int botan_pk_op_sign_update(botan_pk_op_sign_t op, const uint8_t in[], size_t in_len); +BOTAN_DLL int botan_pk_op_sign_finish(botan_pk_op_sign_t op, botan_rng_t rng, + uint8_t sig[], size_t* sig_len); + +/* +* Signature Verification +*/ +typedef struct botan_pk_op_verify_struct* botan_pk_op_verify_t; + +BOTAN_DLL int botan_pk_op_verify_create(botan_pk_op_verify_t* op, + botan_pubkey_t key, + const char* hash_and_padding, + uint32_t flags); +BOTAN_DLL int botan_pk_op_verify_destroy(botan_pk_op_verify_t op); + +BOTAN_DLL int botan_pk_op_verify_update(botan_pk_op_verify_t op, const uint8_t in[], size_t in_len); +BOTAN_DLL int botan_pk_op_verify_finish(botan_pk_op_verify_t op, const uint8_t sig[], size_t sig_len); + +/* +* Key Agreement +*/ +typedef struct botan_pk_op_ka_struct* botan_pk_op_ka_t; + +BOTAN_DLL int botan_pk_op_key_agreement_create(botan_pk_op_ka_t* op, + botan_privkey_t key, + const char* kdf, + uint32_t flags); +BOTAN_DLL int botan_pk_op_key_agreement_destroy(botan_pk_op_ka_t op); + +BOTAN_DLL int botan_pk_op_key_agreement(botan_pk_op_ka_t op, + uint8_t out[], size_t* out_len, + const uint8_t other_key[], size_t other_key_len, + const uint8_t salt[], size_t salt_len); + +/* +* TLS (not yet implemented) +*/ +#if defined(BOTAN_HAS_TLS) && 0 + +typedef struct botan_tls_session_struct* botan_tls_session_t; + +// TODO: getters on session_t + +typedef struct botan_tls_channel_struct* botan_tls_channel_t; + +typedef void (*botan_tls_channel_output_fn)(void, const uin8_t*, size_t); +typedef void (*botan_tls_channel_data_cb)(void, const uin8_t*, size_t); +typedef void (*botan_tls_channel_alert_cb)(void, u16bit, const char*); +typedef void (*botan_tls_channel_session_established)(void, botan_tls_session_t); + +BOTAN_DLL int botan_tls_channel_init_client(botan_tls_channel_t* channel, + botan_tls_channel_output_fn output_fn, + botan_tls_channel_data_cb data_cb, + botan_tls_channel_alert_cb alert_cb, + botan_tls_channel_session_established session_cb, + const char* server_name); + +BOTAN_DLL int botan_tls_channel_init_server(botan_tls_channel_t* channel, + botan_tls_channel_output_fn output_fn, + botan_tls_channel_data_cb data_cb, + botan_tls_channel_alert_cb alert_cb, + botan_tls_channel_session_established session_cb); + +BOTAN_DLL int botan_tls_channel_received_data(botan_tls_channel_t chan, + const uint8_t input[], size_t len); + +BOTAN_DLL int botan_tls_channel_send(botan_tls_channel_t chan, + const uint8_t input[], size_t len); + +BOTAN_DLL int botan_tls_channel_send_alert(botan_tls_channel_t chan, + uint16_t alert, bool fatal); + +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/lib/ffi/info.txt b/src/lib/ffi/info.txt new file mode 100644 index 000000000..94a804ba0 --- /dev/null +++ b/src/lib/ffi/info.txt @@ -0,0 +1,12 @@ +define FFI 20150210 + +<requires> +aead +filters +kdf +pbkdf +pubkey +auto_rng +system_rng +</requires> + diff --git a/src/lib/misc/hkdf/hkdf.cpp b/src/lib/kdf/hkdf/hkdf.cpp index 49fa7e256..28f97cadb 100644 --- a/src/lib/misc/hkdf/hkdf.cpp +++ b/src/lib/kdf/hkdf/hkdf.cpp @@ -11,7 +11,12 @@ namespace Botan { std::string HKDF::name() const { - return "HKDF(" + m_prf->name() + ")"; + const std::string prf = m_prf->name(); + const std::string ext = m_extractor->name(); + + if(prf == ext) + return "HKDF(" + prf + ")"; + return "HKDF(" + ext + "," + prf + ")"; } void HKDF::clear() @@ -50,7 +55,7 @@ void HKDF::expand(byte output[], size_t output_len, m_prf->update(T); m_prf->update(info, info_len); m_prf->update(counter++); - T = m_prf->final(); + m_prf->final(T); const size_t to_write = std::min(T.size(), output_len); copy_mem(&output[0], &T[0], to_write); diff --git a/src/lib/misc/hkdf/hkdf.h b/src/lib/kdf/hkdf/hkdf.h index 6bc68796b..f1ae61453 100644 --- a/src/lib/misc/hkdf/hkdf.h +++ b/src/lib/kdf/hkdf/hkdf.h @@ -10,6 +10,7 @@ #include <botan/mac.h> #include <botan/hash.h> +#include <botan/kdf.h> namespace Botan { diff --git a/src/lib/misc/hkdf/info.txt b/src/lib/kdf/hkdf/info.txt index 7389e5bb1..7389e5bb1 100644 --- a/src/lib/misc/hkdf/info.txt +++ b/src/lib/kdf/hkdf/info.txt diff --git a/src/lib/misc/pbes2/pbes2.cpp b/src/lib/misc/pbes2/pbes2.cpp index 17f14170d..e46286906 100644 --- a/src/lib/misc/pbes2/pbes2.cpp +++ b/src/lib/misc/pbes2/pbes2.cpp @@ -80,7 +80,7 @@ pbes2_encrypt(const secure_vector<byte>& key_bits, if(cipher_spec[1] != "CBC" && cipher_spec[1] != "GCM") throw Decoding_Error("PBE-PKCS5 v2.0: Don't know param format for " + cipher); - std::unique_ptr<Keyed_Transform> enc(get_cipher_mode(cipher, ENCRYPTION)); + std::unique_ptr<Cipher_Mode> enc(get_cipher_mode(cipher, ENCRYPTION)); PKCS5_PBKDF2 pbkdf(Algo_Registry<MessageAuthenticationCode>::global_registry().make(prf)); @@ -153,7 +153,7 @@ pbes2_decrypt(const secure_vector<byte>& key_bits, const std::string prf = OIDS::lookup(prf_algo.oid); PKCS5_PBKDF2 pbkdf(Algo_Registry<MessageAuthenticationCode>::global_registry().make(prf)); - std::unique_ptr<Keyed_Transform> dec(get_cipher_mode(cipher, DECRYPTION)); + std::unique_ptr<Cipher_Mode> dec(get_cipher_mode(cipher, DECRYPTION)); if(key_length == 0) key_length = dec->key_spec().maximum_keylength(); diff --git a/src/lib/pbkdf/pbkdf2/pbkdf2.cpp b/src/lib/pbkdf/pbkdf2/pbkdf2.cpp index fedf036a3..146dd15b0 100644 --- a/src/lib/pbkdf/pbkdf2/pbkdf2.cpp +++ b/src/lib/pbkdf/pbkdf2/pbkdf2.cpp @@ -96,7 +96,7 @@ PKCS5_PBKDF2::key_derivation(size_t key_len, avoids confusion, and likely some broken implementations break on getting completely randomly distributed values */ - if(iterations % 10000 == 0) + if(iterations % 1000 == 0) { auto time_taken = std::chrono::high_resolution_clock::now() - start; auto usec_taken = std::chrono::duration_cast<std::chrono::microseconds>(time_taken); diff --git a/src/lib/pubkey/pubkey.cpp b/src/lib/pubkey/pubkey.cpp index 82797094a..cea065a66 100644 --- a/src/lib/pubkey/pubkey.cpp +++ b/src/lib/pubkey/pubkey.cpp @@ -324,7 +324,7 @@ bool PK_Verifier::validate_signature(const secure_vector<byte>& msg, /* * PK_Key_Agreement Constructor */ -PK_Key_Agreement::PK_Key_Agreement(const PK_Key_Agreement_Key& key, +PK_Key_Agreement::PK_Key_Agreement(const Private_Key& key, const std::string& kdf_name) { m_op.reset(get_pk_op<PK_Ops::Key_Agreement>(key, kdf_name)); diff --git a/src/lib/pubkey/pubkey.h b/src/lib/pubkey/pubkey.h index 55afbf0fa..7341cb9c8 100644 --- a/src/lib/pubkey/pubkey.h +++ b/src/lib/pubkey/pubkey.h @@ -381,8 +381,7 @@ class BOTAN_DLL PK_Key_Agreement * @param key the key to use * @param kdf name of the KDF to use (or 'Raw' for no KDF) */ - PK_Key_Agreement(const PK_Key_Agreement_Key& key, - const std::string& kdf); + PK_Key_Agreement(const Private_Key& key, const std::string& kdf); private: std::unique_ptr<PK_Ops::Key_Agreement> m_op; std::unique_ptr<KDF> m_kdf; diff --git a/src/lib/tls/tls_exceptn.h b/src/lib/tls/tls_exceptn.h index ae601b60b..509226094 100644 --- a/src/lib/tls/tls_exceptn.h +++ b/src/lib/tls/tls_exceptn.h @@ -21,14 +21,14 @@ namespace TLS { class BOTAN_DLL TLS_Exception : public Exception { public: - Alert::Type type() const noexcept { return alert_type; } + Alert::Type type() const { return m_alert_type; } TLS_Exception(Alert::Type type, const std::string& err_msg = "Unknown error") : - Exception(err_msg), alert_type(type) {} + Exception(err_msg), m_alert_type(type) {} private: - Alert::Type alert_type; + Alert::Type m_alert_type; }; /** |