/* * Get an EME by name */ EME* get_eme(const std::string& algo_spec) { SCAN_Name request(algo_spec); Algorithm_Factory& af = global_state().algorithm_factory(); if(request.algo_name() == "Raw") return 0; // No padding #if defined(BOTAN_HAS_EME_PKCS1v15) if(request.algo_name() == "PKCS1v15" && request.arg_count() == 0) return new EME_PKCS1v15; #endif #if defined(BOTAN_HAS_EME1) if(request.algo_name() == "EME1" && request.arg_count_between(1, 2)) { if(request.arg_count() == 1 || (request.arg_count() == 2 && request.arg(1) == "MGF1")) { return new EME1(af.make_hash_function(request.arg(0))); } } #endif throw Algorithm_Not_Found(algo_spec); }
/************************************************* * Get an allocator * *************************************************/ Allocator* Allocator::get(bool locking) { std::string type = ""; if(!locking) type = "malloc"; Allocator* alloc = global_state().get_allocator(type); if(alloc) return alloc; throw Exception("Couldn't find an allocator to use in get_allocator"); }
/* * Get an EMSA by name */ EMSA* get_emsa(const std::string& algo_spec) { SCAN_Name request(algo_spec); Algorithm_Factory& af = global_state().algorithm_factory(); #if defined(BOTAN_HAS_EMSA_RAW) if(request.algo_name() == "Raw" && request.arg_count() == 0) return new EMSA_Raw; #endif #if defined(BOTAN_HAS_EMSA1) if(request.algo_name() == "EMSA1" && request.arg_count() == 1) return new EMSA1(af.make_hash_function(request.arg(0))); #endif #if defined(BOTAN_HAS_EMSA1_BSI) if(request.algo_name() == "EMSA1_BSI" && request.arg_count() == 1) return new EMSA1_BSI(af.make_hash_function(request.arg(0))); #endif #if defined(BOTAN_HAS_EMSA2) if(request.algo_name() == "EMSA2" && request.arg_count() == 1) return new EMSA2(af.make_hash_function(request.arg(0))); #endif #if defined(BOTAN_HAS_EMSA3) if(request.algo_name() == "EMSA3" && request.arg_count() == 1) { if(request.arg(0) == "Raw") return new EMSA3_Raw; return new EMSA3(af.make_hash_function(request.arg(0))); } #endif #if defined(BOTAN_HAS_EMSA4) if(request.algo_name() == "EMSA4" && request.arg_count_between(1, 3)) { // 3 args: Hash, MGF, salt size (MGF is hardcoded MGF1 in Botan) if(request.arg_count() == 1) return new EMSA4(af.make_hash_function(request.arg(0))); if(request.arg_count() == 2 && request.arg(1) != "MGF1") return new EMSA4(af.make_hash_function(request.arg(0))); if(request.arg_count() == 3) return new EMSA4(af.make_hash_function(request.arg(0)), request.arg_as_u32bit(2, 0)); } #endif throw Algorithm_Not_Found(algo_spec); }
/* * Library Initialization */ void LibraryInitializer::initialize(const std::string& arg_string) { bool thread_safe = false; const std::vector<std::string> arg_list = split_on(arg_string, ' '); for(u32bit j = 0; j != arg_list.size(); ++j) { if(arg_list[j].size() == 0) continue; std::string name, value; if(arg_list[j].find('=') == std::string::npos) { name = arg_list[j]; value = "true"; } else { std::vector<std::string> name_and_value = split_on(arg_list[j], '='); name = name_and_value[0]; value = name_and_value[1]; } bool is_on = (value == "1" || value == "true" || value == "yes" || value == "on"); if(name == "thread_safe") thread_safe = is_on; } try { /* This two stage initialization process is because Library_State's constructor will implicitly refer to global state through the allocators and so for, so global_state() has to be a valid reference before initialize() can be called. Yeah, gross. */ set_global_state(new Library_State); global_state().initialize(thread_safe); } catch(...) { deinitialize(); throw; } }
/************************************************* * Library Initialization * *************************************************/ void LibraryInitializer::initialize(const InitializerOptions& args, Modules& modules) { try { set_global_state(new Library_State); global_state().initialize(args, modules); } catch(...) { deinitialize(); throw; } }
/* * Decode PKCS#5 PBES2 parameters */ void PBE_PKCS5v20::decode_params(DataSource& source) { AlgorithmIdentifier kdf_algo, enc_algo; BER_Decoder(source) .start_cons(SEQUENCE) .decode(kdf_algo) .decode(enc_algo) .verify_end() .end_cons(); if(kdf_algo.oid == OIDS::lookup("PKCS5.PBKDF2")) { BER_Decoder(kdf_algo.parameters) .start_cons(SEQUENCE) .decode(salt, OCTET_STRING) .decode(iterations) .decode_optional(key_length, INTEGER, UNIVERSAL) .verify_end() .end_cons(); } else throw Decoding_Error("PBE-PKCS5 v2.0: Unknown KDF algorithm " + kdf_algo.oid.as_string()); 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(!known_cipher(cipher_spec[0]) || 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]); hash_function = af.make_hash_function("SHA-160"); 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"); }
BigInt compute_x(const std::string& hash_id, const std::string& identifier, const std::string& password, const MemoryRegion<byte>& salt) { std::auto_ptr<HashFunction> hash_fn( global_state().algorithm_factory().make_hash_function(hash_id)); hash_fn->update(identifier); hash_fn->update(":"); hash_fn->update(password); SecureVector<byte> inner_h = hash_fn->final(); hash_fn->update(salt); hash_fn->update(inner_h); SecureVector<byte> outer_h = hash_fn->final(); return BigInt::decode(outer_h); }
/* * Get a S2K algorithm by name */ S2K* get_s2k(const std::string& algo_spec) { SCAN_Name request(algo_spec); Algorithm_Factory& af = global_state().algorithm_factory(); #if defined(BOTAN_HAS_PBKDF1) if(request.algo_name() == "PBKDF1" && request.arg_count() == 1) return new PKCS5_PBKDF1(af.make_hash_function(request.arg(0))); #endif #if defined(BOTAN_HAS_PBKDF2) if(request.algo_name() == "PBKDF2" && request.arg_count() == 1) return new PKCS5_PBKDF2(new HMAC(af.make_hash_function(request.arg(0)))); #endif #if defined(BOTAN_HAS_PGPS2K) if(request.algo_name() == "OpenPGP-S2K" && request.arg_count() == 1) return new OpenPGP_S2K(af.make_hash_function(request.arg(0))); #endif throw Algorithm_Not_Found(algo_spec); }
/* * Get an KDF by name */ KDF* get_kdf(const std::string& algo_spec) { SCAN_Name request(algo_spec); Algorithm_Factory& af = global_state().algorithm_factory(); if(request.algo_name() == "Raw") return 0; // No KDF #if defined(BOTAN_HAS_KDF1) if(request.algo_name() == "KDF1" && request.arg_count() == 1) return new KDF1(af.make_hash_function(request.arg(0))); #endif #if defined(BOTAN_HAS_KDF2) if(request.algo_name() == "KDF2" && request.arg_count() == 1) return new KDF2(af.make_hash_function(request.arg(0))); #endif #if defined(BOTAN_HAS_X942_PRF) if(request.algo_name() == "X9.42-PRF" && request.arg_count() == 1) return new X942_PRF(request.arg(0)); // OID #endif #if defined(BOTAN_HAS_TLS_V10_PRF) if(request.algo_name() == "TLS-PRF" && request.arg_count() == 0) return new TLS_PRF; #endif #if defined(BOTAN_HAS_SSL_V3_PRF) if(request.algo_name() == "SSL3-PRF" && request.arg_count() == 0) return new SSL3_PRF; #endif throw Algorithm_Not_Found(algo_spec); }
/************************************************* * Pooling_Allocator Constructor * *************************************************/ Pooling_Allocator::Pooling_Allocator(u32bit p_size, bool) : PREF_SIZE(choose_pref_size(p_size)) { mutex = global_state().get_mutex(); last_used = blocks.begin(); }
std::string transcode(const std::string& str, Character_Set to, Character_Set from) { return global_state().transcode(str, to, from); }
SCAN_Name::SCAN_Name(std::string algo_spec) { orig_algo_spec = algo_spec; std::vector<std::pair<size_t, std::string> > name; size_t level = 0; std::pair<size_t, std::string> accum = std::make_pair(level, ""); std::string decoding_error = "Bad SCAN name '" + algo_spec + "': "; algo_spec = global_state().deref_alias(algo_spec); for(size_t i = 0; i != algo_spec.size(); ++i) { char c = algo_spec[i]; if(c == '/' || c == ',' || c == '(' || c == ')') { if(c == '(') ++level; else if(c == ')') { if(level == 0) throw Decoding_Error(decoding_error + "Mismatched parens"); --level; } if(c == '/' && level > 0) accum.second.push_back(c); else { if(accum.second != "") name.push_back(deref_aliases(accum)); accum = std::make_pair(level, ""); } } else accum.second.push_back(c); } if(accum.second != "") name.push_back(deref_aliases(accum)); if(level != 0) throw Decoding_Error(decoding_error + "Missing close paren"); if(name.size() == 0) throw Decoding_Error(decoding_error + "Empty name"); alg_name = name[0].second; bool in_modes = false; for(size_t i = 1; i != name.size(); ++i) { if(name[i].first == 0) { mode_info.push_back(make_arg(name, i)); in_modes = true; } else if(name[i].first == 1 && !in_modes) args.push_back(make_arg(name, i)); } }
DH_KA_Operation::DH_KA_Operation(const DH_PrivateKey& dh) : p(dh.group_p()), powermod_x_p(dh.get_x(), p) { BigInt k(global_state().global_rng(), p.bits() - 1); blinder = Blinder(k, powermod_x_p(inverse_mod(k, p)), p); }