diff --git a/include/llarp.hpp b/include/llarp.hpp index 50955b868..0767ff33e 100644 --- a/include/llarp.hpp +++ b/include/llarp.hpp @@ -19,8 +19,6 @@ namespace llarp struct Config; struct RouterContact; struct Config; - struct Crypto; - struct CryptoManager; struct Router; class NodeDB; @@ -38,8 +36,6 @@ namespace llarp struct Context { - std::shared_ptr crypto = nullptr; - std::shared_ptr cryptoManager = nullptr; std::shared_ptr router = nullptr; std::shared_ptr loop = nullptr; std::shared_ptr nodedb = nullptr; diff --git a/llarp/config/key_manager.cpp b/llarp/config/key_manager.cpp index c1968d0a9..ae63a68f5 100644 --- a/llarp/config/key_manager.cpp +++ b/llarp/config/key_manager.cpp @@ -19,9 +19,9 @@ namespace llarp if (not isSNode) { - CryptoManager::instance()->identity_keygen(identityKey); - CryptoManager::instance()->encryption_keygen(encryptionKey); - CryptoManager::instance()->encryption_keygen(transportKey); + crypto::identity_keygen(identityKey); + crypto::encryption_keygen(encryptionKey); + crypto::encryption_keygen(transportKey); return true; } @@ -93,7 +93,7 @@ namespace llarp // load identity key or create if needed auto identityKeygen = [](llarp::SecretKey& key) { // TODO: handle generating from service node seed - llarp::CryptoManager::instance()->identity_keygen(key); + llarp::crypto::identity_keygen(key); }; if (not loadOrCreateKey(m_idKeyPath, identityKey, identityKeygen)) return false; @@ -101,7 +101,7 @@ namespace llarp // load encryption key auto encryptionKeygen = [](llarp::SecretKey& key) { - llarp::CryptoManager::instance()->encryption_keygen(key); + llarp::crypto::encryption_keygen(key); }; if (not loadOrCreateKey(m_encKeyPath, encryptionKey, encryptionKeygen)) return false; @@ -109,7 +109,7 @@ namespace llarp // TODO: transport key (currently done in LinkLayer) auto transportKeygen = [](llarp::SecretKey& key) { key.Zero(); - CryptoManager::instance()->encryption_keygen(key); + crypto::encryption_keygen(key); }; if (not loadOrCreateKey(m_transportKeyPath, transportKey, transportKeygen)) return false; diff --git a/llarp/consensus/reachability_testing.cpp b/llarp/consensus/reachability_testing.cpp index 33f0b9483..adaf82136 100644 --- a/llarp/consensus/reachability_testing.cpp +++ b/llarp/consensus/reachability_testing.cpp @@ -76,9 +76,9 @@ namespace llarp::consensus { if (next_general_test > now) return std::nullopt; - CSRNG rng; - next_general_test = - now + std::chrono::duration_cast(fseconds(TESTING_INTERVAL(rng))); + next_general_test = now + + std::chrono::duration_cast( + fseconds(TESTING_INTERVAL(llarp::csrng))); // Pull the next element off the queue, but skip ourself, any that are no longer registered, and // any that are currently known to be failing (those are queued for testing separately). @@ -107,7 +107,7 @@ namespace llarp::consensus const auto all = router->router_whitelist(); testing_queue.insert(testing_queue.begin(), all.begin(), all.end()); - std::shuffle(testing_queue.begin(), testing_queue.end(), rng); + std::shuffle(testing_queue.begin(), testing_queue.end(), llarp::csrng); // Recurse with the rebuilt list, but don't let it try rebuilding again return next_random(router, now, false); @@ -138,9 +138,8 @@ namespace llarp::consensus if (previous_failures < 0) previous_failures = 0; - CSRNG rng; auto next_test_in = duration_cast( - previous_failures * TESTING_BACKOFF + fseconds{TESTING_INTERVAL(rng)}); + previous_failures * TESTING_BACKOFF + fseconds{TESTING_INTERVAL(llarp::csrng)}); if (next_test_in > TESTING_BACKOFF_MAX) next_test_in = TESTING_BACKOFF_MAX; diff --git a/llarp/context.cpp b/llarp/context.cpp index 4dbb9d709..ec2377844 100644 --- a/llarp/context.cpp +++ b/llarp/context.cpp @@ -67,9 +67,6 @@ namespace llarp loop = EventLoop::create(jobQueueSize); } - crypto = std::make_shared(); - cryptoManager = std::make_shared(crypto.get()); - router = makeRouter(loop); nodedb = makeNodeDB(); diff --git a/llarp/crypto/crypto.cpp b/llarp/crypto/crypto.cpp index 8491f2f18..79b71ab8b 100644 --- a/llarp/crypto/crypto.cpp +++ b/llarp/crypto/crypto.cpp @@ -108,28 +108,8 @@ namespace llarp return false; } - Crypto::Crypto() - { - if (sodium_init() == -1) - { - throw std::runtime_error("sodium_init() returned -1"); - } - char* avx2 = std::getenv("AVX2_FORCE_DISABLE"); - if (avx2 && std::string(avx2) == "1") - { - ntru_init(1); - } - else - { - ntru_init(0); - } - int seed = 0; - randombytes(reinterpret_cast(&seed), sizeof(seed)); - srand(seed); - } - std::optional> - Crypto::maybe_decrypt_name(std::string_view ciphertext, SymmNonce nounce, std::string_view name) + crypto::maybe_decrypt_name(std::string_view ciphertext, SymmNonce nounce, std::string_view name) { const auto payloadsize = ciphertext.size() - crypto_aead_xchacha20poly1305_ietf_ABYTES; if (payloadsize != 32) @@ -162,32 +142,33 @@ namespace llarp } bool - Crypto::xchacha20(uint8_t* buf, size_t size, const SharedSecret& k, const TunnelNonce& n) + crypto::xchacha20(uint8_t* buf, size_t size, const SharedSecret& k, const TunnelNonce& n) { - return crypto_stream_xchacha20_xor(buf, buf, size, n.data(), k.data()) == 0; + return xchacha20(buf, size, n.data(), k.data()); } bool - Crypto::xchacha20(uint8_t* buf, size_t size, const uint8_t* secret, const uint8_t* nonce) + crypto::xchacha20(uint8_t* buf, size_t size, const uint8_t* secret, const uint8_t* nonce) { return crypto_stream_xchacha20_xor(buf, buf, size, nonce, secret) == 0; } bool - Crypto::dh_client( + crypto::dh_client( llarp::SharedSecret& shared, const PubKey& pk, const SecretKey& sk, const TunnelNonce& n) { return dh_client_priv(shared, pk, sk, n); } /// path dh relay side bool - Crypto::dh_server( + crypto::dh_server( llarp::SharedSecret& shared, const PubKey& pk, const SecretKey& sk, const TunnelNonce& n) { return dh_server_priv(shared, pk, sk, n); } + bool - Crypto::dh_server( + crypto::dh_server( uint8_t* shared_secret, const uint8_t* other_pk, const uint8_t* local_pk, @@ -197,27 +178,27 @@ namespace llarp } /// transport dh client side bool - Crypto::transport_dh_client( + crypto::transport_dh_client( llarp::SharedSecret& shared, const PubKey& pk, const SecretKey& sk, const TunnelNonce& n) { return dh_client_priv(shared, pk, sk, n); } /// transport dh server side bool - Crypto::transport_dh_server( + crypto::transport_dh_server( llarp::SharedSecret& shared, const PubKey& pk, const SecretKey& sk, const TunnelNonce& n) { return dh_server_priv(shared, pk, sk, n); } bool - Crypto::shorthash(ShortHash& result, uint8_t* buf, size_t size) + crypto::shorthash(ShortHash& result, uint8_t* buf, size_t size) { return crypto_generichash_blake2b(result.data(), ShortHash::SIZE, buf, size, nullptr, 0) != -1; } bool - Crypto::hmac(uint8_t* result, uint8_t* buf, size_t size, const SharedSecret& secret) + crypto::hmac(uint8_t* result, uint8_t* buf, size_t size, const SharedSecret& secret) { return crypto_generichash_blake2b(result, HMACSIZE, buf, size, secret.data(), HMACSECSIZE) != -1; @@ -230,25 +211,25 @@ namespace llarp } bool - Crypto::sign(Signature& sig, const SecretKey& secret, uint8_t* buf, size_t size) + crypto::sign(Signature& sig, const SecretKey& secret, uint8_t* buf, size_t size) { return crypto_sign_detached(sig.data(), nullptr, buf, size, secret.data()) != -1; } bool - Crypto::sign(uint8_t* sig, uint8_t* sk, uint8_t* buf, size_t size) + crypto::sign(uint8_t* sig, uint8_t* sk, uint8_t* buf, size_t size) { return crypto_sign_detached(sig, nullptr, buf, size, sk) != -1; } bool - Crypto::sign(uint8_t* sig, const SecretKey& sk, ustring_view buf) + crypto::sign(uint8_t* sig, const SecretKey& sk, ustring_view buf) { return crypto_sign_detached(sig, nullptr, buf.data(), buf.size(), sk.data()) != -1; } bool - Crypto::sign(Signature& sig, const PrivateKey& privkey, uint8_t* buf, size_t size) + crypto::sign(Signature& sig, const PrivateKey& privkey, uint8_t* buf, size_t size) { PubKey pubkey; @@ -292,13 +273,13 @@ namespace llarp } bool - Crypto::verify(const PubKey& pub, uint8_t* buf, size_t size, const Signature& sig) + crypto::verify(const PubKey& pub, uint8_t* buf, size_t size, const Signature& sig) { return crypto_sign_verify_detached(sig.data(), buf, size, pub.data()) != -1; } bool - Crypto::verify(ustring_view pub, ustring_view buf, ustring_view sig) + crypto::verify(ustring_view pub, ustring_view buf, ustring_view sig) { return (pub.size() == 32 && sig.size() == 64) ? crypto_sign_verify_detached(sig.data(), buf.data(), buf.size(), pub.data()) != -1 @@ -306,7 +287,7 @@ namespace llarp } bool - Crypto::verify(uint8_t* pub, uint8_t* buf, size_t size, uint8_t* sig) + crypto::verify(uint8_t* pub, uint8_t* buf, size_t size, uint8_t* sig) { return crypto_sign_verify_detached(sig, buf, size, pub) != -1; } @@ -363,7 +344,7 @@ namespace llarp static AlignedBuffer<32> zero; bool - Crypto::derive_subkey( + crypto::derive_subkey( PubKey& out_pubkey, const PubKey& root_pubkey, uint64_t key_n, const AlignedBuffer<32>* hash) { // scalar h = H( BLIND-STRING || root_pubkey || key_n ) @@ -380,7 +361,7 @@ namespace llarp } bool - Crypto::derive_subkey_private( + crypto::derive_subkey_private( PrivateKey& out_key, const SecretKey& root_key, uint64_t key_n, const AlignedBuffer<32>* hash) { // Derives a private subkey from a root key. @@ -447,24 +428,24 @@ namespace llarp } bool - Crypto::seed_to_secretkey(llarp::SecretKey& secret, const llarp::IdentitySecret& seed) + crypto::seed_to_secretkey(llarp::SecretKey& secret, const llarp::IdentitySecret& seed) { return crypto_sign_ed25519_seed_keypair(secret.data() + 32, secret.data(), seed.data()) != -1; } void - Crypto::randomize(uint8_t* buf, size_t len) + crypto::randomize(uint8_t* buf, size_t len) { randombytes(buf, len); } void - Crypto::randbytes(byte_t* ptr, size_t sz) + crypto::randbytes(byte_t* ptr, size_t sz) { randombytes((unsigned char*)ptr, sz); } void - Crypto::identity_keygen(llarp::SecretKey& keys) + crypto::identity_keygen(llarp::SecretKey& keys) { PubKey pk; int result = crypto_sign_keypair(pk.data(), keys.data()); @@ -478,7 +459,7 @@ namespace llarp } bool - Crypto::check_identity_privkey(const llarp::SecretKey& keys) + crypto::check_identity_privkey(const llarp::SecretKey& keys) { AlignedBuffer seed; llarp::PubKey pk; @@ -491,7 +472,7 @@ namespace llarp } void - Crypto::encryption_keygen(llarp::SecretKey& keys) + crypto::encryption_keygen(llarp::SecretKey& keys) { auto d = keys.data(); randbytes(d, 32); @@ -499,26 +480,26 @@ namespace llarp } bool - Crypto::pqe_encrypt(PQCipherBlock& ciphertext, SharedSecret& sharedkey, const PQPubKey& pubkey) + crypto::pqe_encrypt(PQCipherBlock& ciphertext, SharedSecret& sharedkey, const PQPubKey& pubkey) { return crypto_kem_enc(ciphertext.data(), sharedkey.data(), pubkey.data()) != -1; } bool - Crypto::pqe_decrypt( + crypto::pqe_decrypt( const PQCipherBlock& ciphertext, SharedSecret& sharedkey, const byte_t* secretkey) { return crypto_kem_dec(sharedkey.data(), ciphertext.data(), secretkey) != -1; } void - Crypto::pqe_keygen(PQKeyPair& keypair) + crypto::pqe_keygen(PQKeyPair& keypair) { auto d = keypair.data(); crypto_kem_keypair(d + PQ_SECRETKEYSIZE, d); } bool - Crypto::check_passwd_hash(std::string pwhash, std::string challenge) + crypto::check_passwd_hash(std::string pwhash, std::string challenge) { (void)pwhash; (void)challenge; @@ -561,4 +542,23 @@ namespace llarp randombytes((byte_t*)&i, sizeof(i)); return i; } + + // Called during static initialization to initialize libsodium and ntru. (The CSRNG return is not + // useful, but just here to get this called during static initialization of `llarp::csrng`). + static CSRNG + _initialize_crypto() + { + if (sodium_init() == -1) + { + log::critical(log::Cat("initialization"), "sodium_init() failed, unable to continue!"); + std::abort(); + } + char* avx2 = std::getenv("AVX2_FORCE_DISABLE"); + ntru_init(avx2 && avx2 == "1"sv); + + return CSRNG{}; + } + + CSRNG csrng = _initialize_crypto(); + } // namespace llarp diff --git a/llarp/crypto/crypto.hpp b/llarp/crypto/crypto.hpp index 43db0b359..2bb41122c 100644 --- a/llarp/crypto/crypto.hpp +++ b/llarp/crypto/crypto.hpp @@ -15,12 +15,8 @@ namespace llarp - */ - struct Crypto + namespace crypto { - Crypto(); - - ~Crypto() = default; - /// decrypt cipherText given the key generated from name std::optional> maybe_decrypt_name(std::string_view ciphertext, SymmNonce nounce, std::string_view name); @@ -136,39 +132,6 @@ namespace llarp const byte_t* pq_keypair_to_secret(const PQKeyPair& keypair); - struct CryptoManager - { - private: - static Crypto* m_crypto; - - Crypto* m_prevCrypto; - - public: - explicit CryptoManager(Crypto* crypto) : m_prevCrypto(m_crypto) - { - m_crypto = crypto; - } - - ~CryptoManager() - { - m_crypto = m_prevCrypto; - } - - static Crypto* - instance() - { -#ifdef NDEBUG - return m_crypto; -#else - if (m_crypto) - return m_crypto; - - assert(false && "Cryptomanager::instance() was undefined"); - abort(); -#endif - } - }; - /// rng type that uses llarp::randint(), which is cryptographically secure struct CSRNG { @@ -178,19 +141,21 @@ namespace llarp min() { return std::numeric_limits::min(); - }; + } static constexpr uint64_t max() { return std::numeric_limits::max(); - }; + } uint64_t operator()() { return llarp::randint(); - }; + } }; + extern CSRNG csrng; + } // namespace llarp diff --git a/llarp/crypto/encrypted_frame.cpp b/llarp/crypto/encrypted_frame.cpp index f95518313..d8ca8c088 100644 --- a/llarp/crypto/encrypted_frame.cpp +++ b/llarp/crypto/encrypted_frame.cpp @@ -9,8 +9,6 @@ namespace llarp bool EncryptedFrame::DoEncrypt(const SharedSecret& shared, bool noDH) { - auto crypto = CryptoManager::instance(); - uint8_t* hash_ptr = data(); uint8_t* nonce_ptr = hash_ptr + SHORTHASHSIZE; uint8_t* pubkey_ptr = nonce_ptr + TUNNONCESIZE; @@ -18,20 +16,20 @@ namespace llarp if (noDH) { - crypto->randbytes(nonce_ptr, TUNNONCESIZE); - crypto->randbytes(pubkey_ptr, PUBKEYSIZE); + crypto::randbytes(nonce_ptr, TUNNONCESIZE); + crypto::randbytes(pubkey_ptr, PUBKEYSIZE); } TunnelNonce nonce(nonce_ptr); // encrypt body - if (!crypto->xchacha20(body_ptr, size() - EncryptedFrameOverheadSize, shared, nonce)) + if (!crypto::xchacha20(body_ptr, size() - EncryptedFrameOverheadSize, shared, nonce)) { llarp::LogError("encrypt failed"); return false; } - if (!crypto->hmac(hash_ptr, nonce_ptr, size() - SHORTHASHSIZE, shared)) + if (!crypto::hmac(hash_ptr, nonce_ptr, size() - SHORTHASHSIZE, shared)) { llarp::LogError("Failed to generate message auth"); return false; @@ -55,16 +53,14 @@ namespace llarp SharedSecret shared; - auto crypto = CryptoManager::instance(); - // set our pubkey memcpy(pubkey, ourSecretKey.toPublic().data(), PUBKEYSIZE); // randomize nonce - crypto->randbytes(noncePtr, TUNNONCESIZE); + crypto::randbytes(noncePtr, TUNNONCESIZE); TunnelNonce nonce(noncePtr); // derive shared key - if (!crypto->dh_client(shared, otherPubkey, ourSecretKey, nonce)) + if (!crypto::dh_client(shared, otherPubkey, ourSecretKey, nonce)) { llarp::LogError("DH failed"); return false; @@ -76,8 +72,6 @@ namespace llarp bool EncryptedFrame::DoDecrypt(const SharedSecret& shared) { - auto crypto = CryptoManager::instance(); - uint8_t* hash_ptr = data(); uint8_t* nonce_ptr = hash_ptr + SHORTHASHSIZE; uint8_t* body_ptr = hash_ptr + EncryptedFrameOverheadSize; @@ -85,7 +79,7 @@ namespace llarp TunnelNonce nonce(nonce_ptr); ShortHash digest; - if (!crypto->hmac(digest.data(), nonce_ptr, size() - SHORTHASHSIZE, shared)) + if (!crypto::hmac(digest.data(), nonce_ptr, size() - SHORTHASHSIZE, shared)) { llarp::LogError("Digest failed"); return false; @@ -97,7 +91,7 @@ namespace llarp return false; } - if (!crypto->xchacha20(body_ptr, size() - EncryptedFrameOverheadSize, shared, nonce)) + if (!crypto::xchacha20(body_ptr, size() - EncryptedFrameOverheadSize, shared, nonce)) { llarp::LogError("decrypt failed"); return false; @@ -121,10 +115,8 @@ namespace llarp SharedSecret shared; - auto crypto = CryptoManager::instance(); - // use dh_server because we are not the creator of this message - if (!crypto->dh_server(shared, otherPubkey, ourSecretKey, nonce)) + if (!crypto::dh_server(shared, otherPubkey, ourSecretKey, nonce)) { llarp::LogError("DH failed"); return false; diff --git a/llarp/crypto/types.hpp b/llarp/crypto/types.hpp index abc77a106..a20c84fd2 100644 --- a/llarp/crypto/types.hpp +++ b/llarp/crypto/types.hpp @@ -221,14 +221,14 @@ namespace llarp /// PKE(result, publickey, secretkey, nonce) using path_dh_func = - std::function; + bool(*)(SharedSecret&, const PubKey&, const SecretKey&, const TunnelNonce&); /// TKE(result, publickey, secretkey, nonce) using transport_dh_func = - std::function; + bool(*)(SharedSecret&, const PubKey&, const SecretKey&, const TunnelNonce&); /// SH(result, body) - using shorthash_func = std::function; + using shorthash_func = bool(*)(ShortHash&, const llarp_buffer_t&); } // namespace llarp namespace std diff --git a/llarp/exit/session.cpp b/llarp/exit/session.cpp index 9ec25d57b..6920c750c 100644 --- a/llarp/exit/session.cpp +++ b/llarp/exit/session.cpp @@ -24,7 +24,7 @@ namespace llarp::exit , m_BundleRC{false} , m_Parent{parent} { - CryptoManager::instance()->identity_keygen(exit_key); + crypto::identity_keygen(exit_key); } BaseSession::~BaseSession() = default; diff --git a/llarp/link/link_manager.cpp b/llarp/link/link_manager.cpp index dbfabbd3b..d9fe5583b 100644 --- a/llarp/link/link_manager.cpp +++ b/llarp/link/link_manager.cpp @@ -1110,8 +1110,6 @@ namespace llarp ustring other_pubkey, outer_nonce, inner_nonce; uint64_t lifetime; - auto crypto = CryptoManager::instance(); - try { oxenc::bt_list_consumer btlc{payload}; @@ -1128,7 +1126,7 @@ namespace llarp SharedSecret shared; // derive shared secret using ephemeral pubkey and our secret key (and nonce) - if (!crypto->dh_server( + if (!crypto::dh_server( shared.data(), other_pubkey.data(), _router.pubkey(), inner_nonce.data())) { log::info(link_cat, "DH server initialization failed during path build"); @@ -1138,7 +1136,7 @@ namespace llarp // hash data and check against given hash ShortHash digest; - if (!crypto->hmac( + if (!crypto::hmac( digest.data(), reinterpret_cast(frame.data()), frame.size(), @@ -1157,7 +1155,7 @@ namespace llarp } // decrypt frame with our hop info - if (!crypto->xchacha20( + if (!crypto::xchacha20( reinterpret_cast(hop_payload.data()), hop_payload.size(), shared.data(), @@ -1224,7 +1222,7 @@ namespace llarp return; } - if (!crypto->dh_server( + if (!crypto::dh_server( hop->pathKey.data(), other_pubkey.data(), _router.pubkey(), inner_nonce.data())) { log::warning(link_cat, "DH failed during path build."); @@ -1232,7 +1230,7 @@ namespace llarp return; } // generate hash of hop key for nonce mutation - crypto->shorthash(hop->nonceXOR, hop->pathKey.data(), hop->pathKey.size()); + crypto::shorthash(hop->nonceXOR, hop->pathKey.data(), hop->pathKey.size()); // set and check path lifetime hop->lifetime = 1ms * lifetime; @@ -1418,7 +1416,7 @@ namespace llarp const auto rx_id = transit_hop->info.rxID; auto success = - (CryptoManager::instance()->verify(pubkey, to_usv(dict_data), sig) + (crypto::verify(pubkey, to_usv(dict_data), sig) and _router.exitContext().ObtainNewExit(PubKey{pubkey.data()}, rx_id, flag != 0)); m.respond( @@ -1460,7 +1458,7 @@ namespace llarp auto path_ptr = std::static_pointer_cast( _router.path_context().GetByDownstream(_router.pubkey(), PathID_t{to_usv(tx_id).data()})); - if (CryptoManager::instance()->verify(_router.pubkey(), to_usv(dict_data), sig)) + if (crypto::verify(_router.pubkey(), to_usv(dict_data), sig)) path_ptr->enable_exit_traffic(); } catch (const std::exception& e) @@ -1492,7 +1490,7 @@ namespace llarp if (auto exit_ep = _router.exitContext().FindEndpointForPath(PathID_t{to_usv(path_id).data()})) { - if (CryptoManager::instance()->verify(exit_ep->PubKey().data(), to_usv(dict_data), sig)) + if (crypto::verify(exit_ep->PubKey().data(), to_usv(dict_data), sig)) { (exit_ep->UpdateLocalPath(transit_hop->info.rxID)) ? m.respond(UpdateExitMessage::sign_and_serialize_response(_router.identity(), tx_id)) @@ -1537,7 +1535,7 @@ namespace llarp auto path_ptr = std::static_pointer_cast( _router.path_context().GetByDownstream(_router.pubkey(), PathID_t{to_usv(tx_id).data()})); - if (CryptoManager::instance()->verify(_router.pubkey(), to_usv(dict_data), sig)) + if (crypto::verify(_router.pubkey(), to_usv(dict_data), sig)) { if (path_ptr->update_exit(std::stoul(tx_id))) { @@ -1577,7 +1575,7 @@ namespace llarp if (auto exit_ep = router().exitContext().FindEndpointForPath(rx_id)) { - if (CryptoManager::instance()->verify(exit_ep->PubKey().data(), to_usv(dict_data), sig)) + if (crypto::verify(exit_ep->PubKey().data(), to_usv(dict_data), sig)) { exit_ep->Close(); m.respond(CloseExitMessage::sign_and_serialize_response(_router.identity(), tx_id)); @@ -1624,7 +1622,7 @@ namespace llarp _router.path_context().GetByDownstream(_router.pubkey(), PathID_t{to_usv(tx_id).data()})); if (path_ptr->SupportsAnyRoles(path::ePathRoleExit | path::ePathRoleSVC) - and CryptoManager::instance()->verify(_router.pubkey(), to_usv(dict_data), sig)) + and crypto::verify(_router.pubkey(), to_usv(dict_data), sig)) path_ptr->mark_exit_closed(); } catch (const std::exception& e) diff --git a/llarp/lokinet_shared.cpp b/llarp/lokinet_shared.cpp index 5dbd83766..e93303325 100644 --- a/llarp/lokinet_shared.cpp +++ b/llarp/lokinet_shared.cpp @@ -489,8 +489,6 @@ extern "C" if (ctx == nullptr) return -3; auto lock = ctx->acquire(); - // add a temp cryptography implementation here so rc.Verify works - llarp::CryptoManager instance{new llarp::Crypto{}}; if (data[0] == 'l') { if (not ctx->config->bootstrap.routers.BDecode(&buf)) diff --git a/llarp/messages/exit.hpp b/llarp/messages/exit.hpp index e5a77b17f..20d1084eb 100644 --- a/llarp/messages/exit.hpp +++ b/llarp/messages/exit.hpp @@ -27,7 +27,7 @@ namespace llarp btdp.append("E", flag); btdp.append("T", tx_id); - if (not CryptoManager::instance()->sign( + if (not crypto::sign( reinterpret_cast(sig.data()), sk, to_usv(btdp.view()))) throw std::runtime_error{ "Error: ObtainExitMessage failed to sign and serialize contents!"}; @@ -51,7 +51,7 @@ namespace llarp btdp.append("T", tx_id); btdp.append("Y", nonce); - if (CryptoManager::instance()->sign( + if (crypto::sign( reinterpret_cast(sig.data()), sk, to_usv(btdp.view()))) throw std::runtime_error{ "Error: ObtainExitMessage response failed to sign and serialize contents!"}; @@ -80,7 +80,7 @@ namespace llarp btdp.append("P", path_id); btdp.append("T", tx_id); - if (not CryptoManager::instance()->sign( + if (not crypto::sign( reinterpret_cast(sig.data()), sk, to_usv(btdp.view()))) throw std::runtime_error{ "Error: UpdateExitMessage failed to sign and serialize contents!"}; @@ -104,7 +104,7 @@ namespace llarp btdp.append("T", tx_id); btdp.append("Y", nonce); - if (CryptoManager::instance()->sign( + if (crypto::sign( reinterpret_cast(sig.data()), sk, to_usv(btdp.view()))) throw std::runtime_error{ "Error: UpdateExitMessage response failed to sign and serialize contents!"}; @@ -134,7 +134,7 @@ namespace llarp btdp.append("T", tx_id); btdp.append("Y", nonce); - if (not CryptoManager::instance()->sign( + if (not crypto::sign( reinterpret_cast(sig.data()), sk, to_usv(btdp.view()))) throw std::runtime_error{ "Error: CloseExitMessage failed to sign and serialize contents!"}; @@ -158,7 +158,7 @@ namespace llarp btdp.append("T", tx_id); btdp.append("Y", nonce); - if (CryptoManager::instance()->sign( + if (crypto::sign( reinterpret_cast(sig.data()), sk, to_usv(btdp.view()))) throw std::runtime_error{ "Error: CloseExitMessage response failed to sign and serialize contents!"}; diff --git a/llarp/messages/path.hpp b/llarp/messages/path.hpp index c12e7930a..053b96702 100644 --- a/llarp/messages/path.hpp +++ b/llarp/messages/path.hpp @@ -17,21 +17,19 @@ namespace llarp inline static void setup_hop_keys(path::PathHopConfig& hop, const RouterID& nextHop) { - auto crypto = CryptoManager::instance(); - // generate key - crypto->encryption_keygen(hop.commkey); + crypto::encryption_keygen(hop.commkey); hop.nonce.Randomize(); // do key exchange - if (!crypto->dh_client(hop.shared, hop.rc.pubkey, hop.commkey, hop.nonce)) + if (!crypto::dh_client(hop.shared, hop.rc.pubkey, hop.commkey, hop.nonce)) { auto err = fmt::format("Failed to generate shared key for path build!"); log::warning(path_cat, err); throw std::runtime_error{std::move(err)}; } // generate nonceXOR value self->hop->pathKey - crypto->shorthash(hop.nonceXOR, hop.shared.data(), hop.shared.size()); + crypto::shorthash(hop.nonceXOR, hop.shared.data(), hop.shared.size()); hop.upstream = nextHop; } @@ -39,8 +37,6 @@ namespace llarp inline static std::string serialize(const path::PathHopConfig& hop) { - auto crypto = CryptoManager::instance(); - std::string hop_info; { @@ -57,21 +53,21 @@ namespace llarp } SecretKey framekey; - crypto->encryption_keygen(framekey); + crypto::encryption_keygen(framekey); SharedSecret shared; TunnelNonce outer_nonce; outer_nonce.Randomize(); // derive (outer) shared key - if (!crypto->dh_client(shared, hop.rc.pubkey, framekey, outer_nonce)) + if (!crypto::dh_client(shared, hop.rc.pubkey, framekey, outer_nonce)) { log::warning(path_cat, "DH client failed during hop info encryption!"); throw std::runtime_error{"DH failed during hop info encryption"}; } // encrypt hop_info (mutates in-place) - if (!crypto->xchacha20( + if (!crypto::xchacha20( reinterpret_cast(hop_info.data()), hop_info.size(), shared, @@ -96,7 +92,7 @@ namespace llarp std::string hash; hash.reserve(SHORTHASHSIZE); - if (!crypto->hmac( + if (!crypto::hmac( reinterpret_cast(hash.data()), reinterpret_cast(hashed_data.data()), hashed_data.size(), diff --git a/llarp/nodedb.hpp b/llarp/nodedb.hpp index 6404a0430..10eb83613 100644 --- a/llarp/nodedb.hpp +++ b/llarp/nodedb.hpp @@ -97,7 +97,7 @@ namespace llarp for (const auto& entry : entries) entries.push_back(entry); - std::shuffle(entries.begin(), entries.end(), llarp::CSRNG{}); + std::shuffle(entries.begin(), entries.end(), llarp::csrng); for (const auto entry : entries) { diff --git a/llarp/path/path.cpp b/llarp/path/path.cpp index 534ab10eb..75be48791 100644 --- a/llarp/path/path.cpp +++ b/llarp/path/path.cpp @@ -110,7 +110,7 @@ namespace llarp::path for (const auto& hop : hops) { // do a round of chacha for each hop and mutate the nonce with that hop's nonce - CryptoManager::instance()->xchacha20( + crypto::xchacha20( reinterpret_cast(payload.data()), payload.size(), hop.shared, nonce); nonce ^= hop.nonceXOR; @@ -450,7 +450,7 @@ namespace llarp::path for (const auto& hop : hops) { - CryptoManager::instance()->xchacha20(buf, sz, hop.shared, n); + crypto::xchacha20(buf, sz, hop.shared, n); n ^= hop.nonceXOR; } auto& msg = sendmsgs[idx]; @@ -528,7 +528,7 @@ namespace llarp::path for (const auto& hop : hops) { sendMsgs[idx].nonce ^= hop.nonceXOR; - CryptoManager::instance()->xchacha20(buf, sz, hop.shared, sendMsgs[idx].nonce); + crypto::xchacha20(buf, sz, hop.shared, sendMsgs[idx].nonce); } std::memcpy(sendMsgs[idx].enc.data(), buf, sz); @@ -583,7 +583,7 @@ namespace llarp::path if (payload.size() < PAD_SIZE) { // randomize padding - CryptoManager::instance()->randbytes( + crypto::randbytes( reinterpret_cast(buf.data()) + payload.size(), PAD_SIZE - payload.size()); } log::debug(path_cat, "Sending {}B routing message to {}", buf.size(), Endpoint()); diff --git a/llarp/path/pathbuilder.cpp b/llarp/path/pathbuilder.cpp index a9758384e..e3d312c3c 100644 --- a/llarp/path/pathbuilder.cpp +++ b/llarp/path/pathbuilder.cpp @@ -78,21 +78,19 @@ namespace llarp void Builder::setup_hop_keys(path::PathHopConfig& hop, const RouterID& nextHop) { - auto crypto = CryptoManager::instance(); - // generate key - crypto->encryption_keygen(hop.commkey); + crypto::encryption_keygen(hop.commkey); hop.nonce.Randomize(); // do key exchange - if (!crypto->dh_client(hop.shared, hop.rc.pubkey, hop.commkey, hop.nonce)) + if (!crypto::dh_client(hop.shared, hop.rc.pubkey, hop.commkey, hop.nonce)) { auto err = fmt::format("{} failed to generate shared key for path build!", Name()); log::error(path_cat, err); throw std::runtime_error{std::move(err)}; } // generate nonceXOR value self->hop->pathKey - crypto->shorthash(hop.nonceXOR, hop.shared.data(), hop.shared.size()); + crypto::shorthash(hop.nonceXOR, hop.shared.data(), hop.shared.size()); hop.upstream = nextHop; } @@ -100,8 +98,6 @@ namespace llarp std::string Builder::create_hop_info_frame(const path::PathHopConfig& hop) { - auto crypto = CryptoManager::instance(); - std::string hop_info; { @@ -118,21 +114,21 @@ namespace llarp } SecretKey framekey; - crypto->encryption_keygen(framekey); + crypto::encryption_keygen(framekey); SharedSecret shared; TunnelNonce outer_nonce; outer_nonce.Randomize(); // derive (outer) shared key - if (!crypto->dh_client(shared, hop.rc.pubkey, framekey, outer_nonce)) + if (!crypto::dh_client(shared, hop.rc.pubkey, framekey, outer_nonce)) { log::error(path_cat, "DH client failed during hop info encryption!"); throw std::runtime_error{"DH failed during hop info encryption"}; } // encrypt hop_info (mutates in-place) - if (!crypto->xchacha20( + if (!crypto::xchacha20( reinterpret_cast(hop_info.data()), hop_info.size(), shared, outer_nonce)) { log::error(path_cat, "Hop info encryption failed!"); @@ -154,7 +150,7 @@ namespace llarp std::string hash; hash.reserve(SHORTHASHSIZE); - if (!crypto->hmac( + if (!crypto::hmac( reinterpret_cast(hash.data()), reinterpret_cast(hashed_data.data()), hashed_data.size(), diff --git a/llarp/path/pathset.cpp b/llarp/path/pathset.cpp index 7a0427d61..df92ef7c1 100644 --- a/llarp/path/pathset.cpp +++ b/llarp/path/pathset.cpp @@ -211,12 +211,7 @@ namespace llarp::path } if (chosen.empty()) return nullptr; - size_t idx = 0; - if (chosen.size() >= 2) - { - idx = rand() % chosen.size(); - } - return chosen[idx]; + return chosen[std::uniform_int_distribution{0, chosen.size() - 1}(llarp::csrng)]; } Path_ptr diff --git a/llarp/path/transit_hop.cpp b/llarp/path/transit_hop.cpp index bceae78a5..0e681455f 100644 --- a/llarp/path/transit_hop.cpp +++ b/llarp/path/transit_hop.cpp @@ -77,7 +77,7 @@ namespace llarp::path { dlt = PAD_SIZE - dlt; // randomize padding - CryptoManager::instance()->randbytes(reinterpret_cast(payload.data()), dlt); + crypto::randbytes(reinterpret_cast(payload.data()), dlt); } // TODO: relay message along @@ -107,7 +107,7 @@ namespace llarp::path msg.pathid = info.rxID; msg.nonce = ev.second ^ nonceXOR; - CryptoManager::instance()->xchacha20(buf, sz, pathKey, ev.second); + crypto::xchacha20(buf, sz, pathKey, ev.second); std::memcpy(msg.enc.data(), buf, sz); llarp::LogDebug( @@ -137,7 +137,7 @@ namespace llarp::path uint8_t* buf = ev.first.data(); size_t sz = ev.first.size(); - CryptoManager::instance()->xchacha20(buf, sz, pathKey, ev.second); + crypto::xchacha20(buf, sz, pathKey, ev.second); msg.pathid = info.txID; msg.nonce = ev.second ^ nonceXOR; diff --git a/llarp/pow.cpp b/llarp/pow.cpp index 858f2e1a7..5012ec394 100644 --- a/llarp/pow.cpp +++ b/llarp/pow.cpp @@ -31,7 +31,7 @@ namespace llarp auto buf = bt_encode(); // hash - if (!CryptoManager::instance()->shorthash( + if (!crypto::shorthash( digest, reinterpret_cast(buf.data()), buf.size())) return false; // check bytes required diff --git a/llarp/router/rc_gossiper.cpp b/llarp/router/rc_gossiper.cpp index be478e620..429a4b697 100644 --- a/llarp/router/rc_gossiper.cpp +++ b/llarp/router/rc_gossiper.cpp @@ -117,7 +117,8 @@ namespace llarp std::unordered_set keys; // grab the keys we want to use std::sample( - gossipTo.begin(), gossipTo.end(), std::inserter(keys, keys.end()), MaxGossipPeers, CSRNG{}); + gossipTo.begin(), gossipTo.end(), std::inserter(keys, keys.end()), MaxGossipPeers, + llarp::csrng); m_LinkManager->ForEachPeer([&](AbstractLinkSession* peerSession) { if (not(peerSession && peerSession->IsEstablished())) diff --git a/llarp/router/rc_lookup_handler.cpp b/llarp/router/rc_lookup_handler.cpp index 6b36cb743..ac705a88a 100644 --- a/llarp/router/rc_lookup_handler.cpp +++ b/llarp/router/rc_lookup_handler.cpp @@ -328,7 +328,7 @@ namespace llarp if (lookup_routers.size() > LookupPerTick) { - std::shuffle(lookup_routers.begin(), lookup_routers.end(), CSRNG{}); + std::shuffle(lookup_routers.begin(), lookup_routers.end(), llarp::csrng); lookup_routers.resize(LookupPerTick); } diff --git a/llarp/router/router.cpp b/llarp/router/router.cpp index 17680b402..7aad6ca2e 100644 --- a/llarp/router/router.cpp +++ b/llarp/router/router.cpp @@ -1162,8 +1162,8 @@ namespace llarp { // we are a client // regenerate keys and resign rc before everything else - CryptoManager::instance()->identity_keygen(_identity); - CryptoManager::instance()->encryption_keygen(_encryption); + crypto::identity_keygen(_identity); + crypto::encryption_keygen(_encryption); router_contact.pubkey = seckey_topublic(identity()); router_contact.enckey = seckey_topublic(encryption()); if (!router_contact.Sign(identity())) diff --git a/llarp/router_contact.cpp b/llarp/router_contact.cpp index 3b28ee35a..3d5e439be 100644 --- a/llarp/router_contact.cpp +++ b/llarp/router_contact.cpp @@ -364,7 +364,7 @@ namespace llarp signed_bt_dict = bencode_signed_section(); - return CryptoManager::instance()->sign( + return crypto::sign( signature, secretkey, reinterpret_cast(signed_bt_dict.data()), @@ -409,7 +409,7 @@ namespace llarp copy.signature.Zero(); auto bte = copy.bt_encode(); - return CryptoManager::instance()->verify( + return crypto::verify( pubkey, reinterpret_cast(bte.data()), bte.size(), signature); } diff --git a/llarp/service/address.cpp b/llarp/service/address.cpp index fe75cb6c4..704b193c9 100644 --- a/llarp/service/address.cpp +++ b/llarp/service/address.cpp @@ -67,7 +67,7 @@ namespace llarp::service Address::ToKey() const { PubKey k; - CryptoManager::instance()->derive_subkey(k, PubKey(data()), 1); + crypto::derive_subkey(k, PubKey(data()), 1); return dht::Key_t{k.as_array()}; } diff --git a/llarp/service/async_key_exchange.cpp b/llarp/service/async_key_exchange.cpp index 2cfecad42..0def85fac 100644 --- a/llarp/service/async_key_exchange.cpp +++ b/llarp/service/async_key_exchange.cpp @@ -43,24 +43,21 @@ namespace llarp::service { // derive ntru session key component SharedSecret secret; - auto crypto = CryptoManager::instance(); - - crypto->pqe_encrypt(frame->cipher, secret, self->introPubKey); + crypto::pqe_encrypt(frame->cipher, secret, self->introPubKey); + // randomize Nonce frame->nonce.Randomize(); // compute post handshake session key // PKE (A, B, N) SharedSecret sharedSecret; - path_dh_func dh_client = util::memFn(&Crypto::dh_client, crypto); - - if (!self->m_LocalIdentity.KeyExchange(dh_client, sharedSecret, self->m_remote, frame->nonce)) + if (!self->m_LocalIdentity.KeyExchange(crypto::dh_client, sharedSecret, self->m_remote, frame->nonce)) { LogError("failed to derive x25519 shared key component"); } auto buf = secret.bt_encode() + sharedSecret.bt_encode(); // H (K + PKE(A, B, N)) - crypto->shorthash(self->sharedKey, reinterpret_cast(buf.data()), buf.size()); + crypto::shorthash(self->sharedKey, reinterpret_cast(buf.data()), buf.size()); // set tag self->msg.tag = self->tag; diff --git a/llarp/service/auth.cpp b/llarp/service/auth.cpp index 8ef7e5250..f68f9e355 100644 --- a/llarp/service/auth.cpp +++ b/llarp/service/auth.cpp @@ -124,7 +124,7 @@ namespace llarp::service case AuthFileType::eAuthFilePlain: return hash == challenge; case AuthFileType::eAuthFileHashes: - return CryptoManager::instance()->check_passwd_hash( + return crypto::check_passwd_hash( std::move(hash), std::move(challenge)); default: return false; diff --git a/llarp/service/endpoint.cpp b/llarp/service/endpoint.cpp index 2da9031ce..ae124233d 100644 --- a/llarp/service/endpoint.cpp +++ b/llarp/service/endpoint.cpp @@ -874,7 +874,7 @@ namespace llarp::service // pick up to max_unique_lns_endpoints random paths to do lookups from std::vector chosenpaths; chosenpaths.insert(chosenpaths.begin(), paths.begin(), paths.end()); - std::shuffle(chosenpaths.begin(), chosenpaths.end(), CSRNG{}); + std::shuffle(chosenpaths.begin(), chosenpaths.end(), llarp::csrng); chosenpaths.resize(std::min(paths.size(), MAX_ONS_LOOKUP_ENDPOINTS)); for (const auto& path : chosenpaths) diff --git a/llarp/service/identity.cpp b/llarp/service/identity.cpp index cc28f047b..9cfdf45df 100644 --- a/llarp/service/identity.cpp +++ b/llarp/service/identity.cpp @@ -42,12 +42,11 @@ namespace llarp::service void Identity::RegenerateKeys() { - auto crypto = CryptoManager::instance(); - crypto->identity_keygen(signkey); - crypto->encryption_keygen(enckey); + crypto::identity_keygen(signkey); + crypto::encryption_keygen(enckey); pub.Update(seckey_topublic(signkey), seckey_topublic(enckey)); - crypto->pqe_keygen(pq); - if (not crypto->derive_subkey_private(derivedSignKey, signkey, 1)) + crypto::pqe_keygen(pq); + if (not crypto::derive_subkey_private(derivedSignKey, signkey, 1)) { throw std::runtime_error("failed to derive subkey"); } @@ -66,7 +65,7 @@ namespace llarp::service bool Identity::Sign(Signature& sig, uint8_t* buf, size_t size) const { - return CryptoManager::instance()->sign(sig, signkey, buf, size); + return crypto::sign(sig, signkey, buf, size); } void @@ -127,22 +126,21 @@ namespace llarp::service if (!bencode_decode_dict(*this, &buf)) throw std::length_error{"could not decode service identity"}; } - auto crypto = CryptoManager::instance(); // ensure that the encryption key is set if (enckey.IsZero()) - crypto->encryption_keygen(enckey); + crypto::encryption_keygen(enckey); // also ensure the ntru key is set if (pq.IsZero()) - crypto->pqe_keygen(pq); + crypto::pqe_keygen(pq); std::optional van; if (!vanity.IsZero()) van = vanity; // update pubkeys pub.Update(seckey_topublic(signkey), seckey_topublic(enckey), van); - if (not crypto->derive_subkey_private(derivedSignKey, signkey, 1)) + if (not crypto::derive_subkey_private(derivedSignKey, signkey, 1)) { throw std::runtime_error("failed to derive subkey"); } @@ -170,7 +168,7 @@ namespace llarp::service auto bte = i.bt_encode(); const SharedSecret k{i.address_keys.Addr()}; - CryptoManager::instance()->xchacha20( + crypto::xchacha20( reinterpret_cast(bte.data()), bte.size(), k, encrypted.nounce); std::memcpy(encrypted.introsetPayload.data(), bte.data(), bte.size()); diff --git a/llarp/service/info.cpp b/llarp/service/info.cpp index 1f0630cfe..f45f5b93d 100644 --- a/llarp/service/info.cpp +++ b/llarp/service/info.cpp @@ -9,7 +9,7 @@ namespace llarp::service bool ServiceInfo::verify(uint8_t* buf, size_t size, const Signature& sig) const { - return CryptoManager::instance()->verify(signkey, buf, size, sig); + return crypto::verify(signkey, buf, size, sig); } bool diff --git a/llarp/service/intro_set.cpp b/llarp/service/intro_set.cpp index 68f1533ca..11dd6f999 100644 --- a/llarp/service/intro_set.cpp +++ b/llarp/service/intro_set.cpp @@ -123,7 +123,7 @@ namespace llarp::service std::string payload{ reinterpret_cast(introsetPayload.data()), introsetPayload.size()}; - CryptoManager::instance()->xchacha20( + crypto::xchacha20( reinterpret_cast(payload.data()), payload.size(), k, nounce); return IntroSet{payload}; @@ -144,7 +144,7 @@ namespace llarp::service sig.Zero(); auto bte = bt_encode(); - if (not CryptoManager::instance()->sign( + if (not crypto::sign( sig, k, reinterpret_cast(bte.data()), bte.size())) return false; LogDebug("signed encrypted introset: ", *this); @@ -161,20 +161,20 @@ namespace llarp::service copy.sig.Zero(); auto bte = copy.bt_encode(); - return CryptoManager::instance()->verify( + return crypto::verify( derivedSigningKey, reinterpret_cast(bte.data()), bte.size(), sig); } bool EncryptedIntroSet::verify(uint8_t* introset, size_t introset_size, uint8_t* key, uint8_t* sig) { - return CryptoManager::instance()->verify(key, introset, introset_size, sig); + return crypto::verify(key, introset, introset_size, sig); } bool EncryptedIntroSet::verify(std::string introset, std::string key, std::string sig) { - return CryptoManager::instance()->verify( + return crypto::verify( reinterpret_cast(key.data()), reinterpret_cast(introset.data()), introset.size(), diff --git a/llarp/service/name.cpp b/llarp/service/name.cpp index 056c62c23..37c0afb1e 100644 --- a/llarp/service/name.cpp +++ b/llarp/service/name.cpp @@ -9,8 +9,7 @@ namespace llarp::service { if (ciphertext.empty()) return std::nullopt; - const auto crypto = CryptoManager::instance(); - const auto maybe = crypto->maybe_decrypt_name(ciphertext, nonce, name); + const auto maybe = crypto::maybe_decrypt_name(ciphertext, nonce, name); if (maybe.has_value()) return Address{*maybe}; return std::nullopt; diff --git a/llarp/service/outbound_context.cpp b/llarp/service/outbound_context.cpp index d1dcf7416..5588de118 100644 --- a/llarp/service/outbound_context.cpp +++ b/llarp/service/outbound_context.cpp @@ -40,13 +40,9 @@ namespace llarp::service updatingIntroSet = false; // pick random first intro - auto it = introset.intros.begin(); - if (introset.intros.size() > 1) - { - CSRNG rng{}; - it += std::uniform_int_distribution{0, introset.intros.size() - 1}(rng); - } - next_intro = *it; + next_intro = *std::next( + introset.intros.begin(), + std::uniform_int_distribution{0, introset.intros.size() - 1}(llarp::csrng)); current_tag.Randomize(); last_shift = Now(); // add send and connect timeouts to the parent endpoints path alignment timeout @@ -250,7 +246,7 @@ namespace llarp::service { std::string buf(64, '\0'); - CryptoManager::instance()->randomize(reinterpret_cast(buf.data()), buf.size()); + crypto::randomize(reinterpret_cast(buf.data()), buf.size()); send_packet_to_remote(buf); last_keep_alive = Now(); @@ -305,7 +301,7 @@ namespace llarp::service }); if (not otherIntros.empty()) { - std::shuffle(otherIntros.begin(), otherIntros.end(), CSRNG{}); + std::shuffle(otherIntros.begin(), otherIntros.end(), llarp::csrng); remote_intro = otherIntros[0]; } } @@ -403,7 +399,7 @@ namespace llarp::service if (intros.size() > 1) { - std::shuffle(intros.begin(), intros.end(), CSRNG{}); + std::shuffle(intros.begin(), intros.end(), llarp::csrng); } // to find a intro on the same router as before that is newer diff --git a/llarp/service/protocol.cpp b/llarp/service/protocol.cpp index 59fc042e0..a21a4b9b9 100644 --- a/llarp/service/protocol.cpp +++ b/llarp/service/protocol.cpp @@ -178,7 +178,7 @@ namespace llarp::service const SharedSecret& sharedkey, ProtocolMessage& msg) const { Encrypted<2048> tmp = enc; - CryptoManager::instance()->xchacha20(tmp.data(), tmp.size(), sharedkey, nonce); + crypto::xchacha20(tmp.data(), tmp.size(), sharedkey, nonce); return bencode_decode_dict(msg, tmp.Buffer()); } @@ -207,7 +207,7 @@ namespace llarp::service // encode message auto bte1 = msg.bt_encode(); // encrypt - CryptoManager::instance()->xchacha20( + crypto::xchacha20( reinterpret_cast(bte1.data()), bte1.size(), sessionKey, nonce); // put encrypted buffer std::memcpy(enc.data(), bte1.data(), bte1.size()); @@ -252,12 +252,11 @@ namespace llarp::service static void Work(std::shared_ptr self) { - auto crypto = CryptoManager::instance(); SharedSecret K; SharedSecret shared_key; // copy ProtocolFrameMessage frame(self->frame); - if (!crypto->pqe_decrypt( + if (!crypto::pqe_decrypt( self->frame.cipher, K, pq_keypair_to_secret(self->m_LocalIdentity.pq))) { LogError("pqke failed C=", self->frame.cipher); @@ -268,7 +267,7 @@ namespace llarp::service // auto buf = frame.enc.Buffer(); uint8_t* buf = frame.enc.data(); size_t sz = frame.enc.size(); - crypto->xchacha20(buf, sz, K, self->frame.nonce); + crypto::xchacha20(buf, sz, K, self->frame.nonce); auto bte = self->msg->bt_encode(); @@ -304,16 +303,8 @@ namespace llarp::service // PKE (A, B, N) SharedSecret shared_secret; - path_dh_func dh_server = [crypto = CryptoManager::instance()]( - llarp::SharedSecret& shared, - const PubKey& pk, - const SecretKey& sk, - const TunnelNonce& n) -> bool { - return crypto->dh_server(shared, pk, sk, n); - }; - if (!self->m_LocalIdentity.KeyExchange( - dh_server, shared_secret, self->msg->sender, self->frame.nonce)) + crypto::dh_server, shared_secret, self->msg->sender, self->frame.nonce)) { LogError("x25519 key exchange failed"); Dump(self->frame); @@ -326,7 +317,7 @@ namespace llarp::service // S = HS( K + PKE( A, B, N)) std::memcpy(tmp.begin() + 32, shared_secret.begin(), shared_secret.size()); - crypto->shorthash(shared_key, tmp.data(), tmp.size()); + crypto::shorthash(shared_key, tmp.data(), tmp.size()); std::shared_ptr msg = std::move(self->msg); path::Path_ptr path = std::move(self->path); diff --git a/llarp/win32/guid.hpp b/llarp/win32/guid.hpp index 83c926523..40e0cae09 100644 --- a/llarp/win32/guid.hpp +++ b/llarp/win32/guid.hpp @@ -13,7 +13,7 @@ namespace llarp::win32 MakeDeterministicGUID(Data data) { ShortHash h{}; - auto hash = [&h](auto data) { CryptoManager::instance()->shorthash(h, data); }; + auto hash = [&h](auto data) { crypto::shorthash(h, data); }; if constexpr (std::is_same_v) hash(llarp_buffer_t{reinterpret_cast(data.data()), data.size()}); diff --git a/test/crypto/test_llarp_crypto.cpp b/test/crypto/test_llarp_crypto.cpp index b78752375..2eb3b03d9 100644 --- a/test/crypto/test_llarp_crypto.cpp +++ b/test/crypto/test_llarp_crypto.cpp @@ -8,7 +8,6 @@ using namespace llarp; TEST_CASE("Identity key") { - llarp::sodium::CryptoLibSodium crypto; SecretKey secret; crypto.identity_keygen(secret); @@ -35,7 +34,6 @@ TEST_CASE("Identity key") TEST_CASE("PQ crypto") { - llarp::sodium::CryptoLibSodium crypto; PQKeyPair keys; crypto.pqe_keygen(keys); PQCipherBlock block; @@ -52,8 +50,6 @@ TEST_CASE("PQ crypto") TEST_CASE("passwd hash valid") { - llarp::sodium::CryptoLibSodium crypto; - // poggers password hashes std::set valid_hashes; // UNIX DES diff --git a/test/crypto/test_llarp_key_manager.cpp b/test/crypto/test_llarp_key_manager.cpp index 459ed309b..31714e787 100644 --- a/test/crypto/test_llarp_key_manager.cpp +++ b/test/crypto/test_llarp_key_manager.cpp @@ -1,4 +1,3 @@ -#include "llarp_test.hpp" #include "test_util.hpp" #include @@ -14,7 +13,7 @@ using namespace ::llarp; -struct KeyManagerTest : public test::LlarpTest +struct KeyManagerTest { // paranoid file guards for anything KeyManager might touch test::FileGuard m_rcFileGuard; diff --git a/test/llarp_test.hpp b/test/llarp_test.hpp deleted file mode 100644 index 914c4a224..000000000 --- a/test/llarp_test.hpp +++ /dev/null @@ -1,30 +0,0 @@ -#pragma once - -#include -#include - -namespace llarp::test -{ - - template - class LlarpTest - { - protected: - CryptoImpl m_crypto; - CryptoManager cm; - - LlarpTest() : cm(&m_crypto) - { - static_assert(std::is_base_of::value, ""); - } - - ~LlarpTest() - {} - }; - - template <> - inline LlarpTest::~LlarpTest() - { - - } // namespace test -} diff --git a/test/routing/test_llarp_routing_obtainexitmessage.cpp b/test/routing/test_llarp_routing_obtainexitmessage.cpp index 631652072..467519d3f 100644 --- a/test/routing/test_llarp_routing_obtainexitmessage.cpp +++ b/test/routing/test_llarp_routing_obtainexitmessage.cpp @@ -1,4 +1,3 @@ -#include "llarp_test.hpp" #include #include #include @@ -16,10 +15,10 @@ fill(Signature& s) s.Fill(0xFF); } -TEST_CASE_METHOD(LlarpTest<>, "Sign-verify") +TEST_CASE("Sign-verify") { SecretKey alice{}; - CryptoManager::instance()->identity_keygen(alice); + crypto::identity_keygen(alice); REQUIRE(not alice.IsZero()); ObtainExitMessage msg{}; msg.S = randint(); diff --git a/test/service/test_llarp_service_identity.cpp b/test/service/test_llarp_service_identity.cpp index 560754280..5d0bd42be 100644 --- a/test/service/test_llarp_service_identity.cpp +++ b/test/service/test_llarp_service_identity.cpp @@ -7,7 +7,6 @@ #include #include -#include "test_util.hpp" #include using namespace llarp; @@ -44,8 +43,6 @@ TEST_CASE("test service::Identity throws on error") TEST_CASE("test subkey derivation", "[crypto]") { - CryptoManager manager(new sodium::CryptoLibSodium()); - // These values came out of a run of Tor's test code, so that we can confirm we are doing the same // blinding subkey crypto math as Tor. Our hash value is generated differently so we use the hash // from a Tor random test suite run. @@ -79,27 +76,22 @@ TEST_CASE("test subkey derivation", "[crypto]") CHECK(root.toPrivate(root_key)); CHECK(root_key.as_array() == root_key_data.as_array()); - auto crypto = CryptoManager::instance(); - PrivateKey aprime; // a' - CHECK(crypto->derive_subkey_private(aprime, root, 0, &hash)); + CHECK(crypto::derive_subkey_private(aprime, root, 0, &hash)); // We use a different signing hash than Tor // only the private key value (the first 32 bytes) will match: CHECK(std::memcmp(aprime.data(), derived_key_data.data(), 32) == 0); PubKey Aprime; // A' - CHECK(crypto->derive_subkey(Aprime, root.toPublic(), 0, &hash)); + CHECK(crypto::derive_subkey(Aprime, root.toPublic(), 0, &hash)); CHECK(Aprime.as_array() == derived_pub_data.as_array()); } TEST_CASE("test root key signing" , "[crypto]") { - CryptoManager manager(new sodium::CryptoLibSodium()); - - auto crypto = CryptoManager::instance(); SecretKey root_key; - crypto->identity_keygen(root_key); + crypto::identity_keygen(root_key); // We have our own reimplementation of sodium's signing function which can work with derived // private keys (unlike sodium's built-in which requires starting from a seed). This tests that @@ -109,23 +101,20 @@ TEST_CASE("test root key signing" , "[crypto]") llarp_buffer_t nibbs_buf{nibbs.data(), nibbs.size()}; Signature sig_sodium; - CHECK(crypto->sign(sig_sodium, root_key, nibbs_buf)); + CHECK(crypto::sign(sig_sodium, root_key, nibbs_buf)); PrivateKey root_privkey; CHECK(root_key.toPrivate(root_privkey)); Signature sig_ours; - CHECK(crypto->sign(sig_ours, root_privkey, nibbs_buf)); + CHECK(crypto::sign(sig_ours, root_privkey, nibbs_buf)); CHECK(sig_sodium == sig_ours); } TEST_CASE("Test generate derived key", "[crypto]") { - CryptoManager manager(new sodium::CryptoLibSodium()); - - auto crypto = CryptoManager::instance(); SecretKey root_key; - crypto->identity_keygen(root_key); + crypto::identity_keygen(root_key); PrivateKey root_privkey; CHECK(root_key.toPrivate(root_privkey)); @@ -144,10 +133,10 @@ TEST_CASE("Test generate derived key", "[crypto]") } PrivateKey aprime; // a' - CHECK(crypto->derive_subkey_private(aprime, root_key, 1)); + CHECK(crypto::derive_subkey_private(aprime, root_key, 1)); PubKey Aprime; // A' - CHECK(crypto->derive_subkey(Aprime, A, 1)); + CHECK(crypto::derive_subkey(Aprime, A, 1)); // We should also be able to derive A' via a': PubKey Aprime_alt; @@ -158,14 +147,14 @@ TEST_CASE("Test generate derived key", "[crypto]") // Generate using the same constant and make sure we get an identical privkey (including the // signing hash value) PrivateKey aprime_repeat; - CHECK(crypto->derive_subkey_private(aprime_repeat, root_key, 1)); + CHECK(crypto::derive_subkey_private(aprime_repeat, root_key, 1)); CHECK(aprime_repeat == aprime); // Generate another using a different constant and make sure we get something different PrivateKey a2; PubKey A2; - CHECK(crypto->derive_subkey_private(a2, root_key, 2)); - CHECK(crypto->derive_subkey(A2, A, 2)); + CHECK(crypto::derive_subkey_private(a2, root_key, 2)); + CHECK(crypto::derive_subkey(A2, A, 2)); CHECK(A2 != Aprime); CHECK(a2.ToHex().substr(0, 64) != aprime.ToHex().substr(0, 64)); CHECK(a2.ToHex().substr(64) != aprime.ToHex().substr(64)); // The hash should be different too @@ -173,11 +162,8 @@ TEST_CASE("Test generate derived key", "[crypto]") TEST_CASE("Test signing with derived key", "[crypto]") { - CryptoManager manager(new sodium::CryptoLibSodium()); - - auto crypto = CryptoManager::instance(); SecretKey root_key; - crypto->identity_keygen(root_key); + crypto::identity_keygen(root_key); PrivateKey root_privkey; root_key.toPrivate(root_privkey); @@ -188,24 +174,22 @@ TEST_CASE("Test signing with derived key", "[crypto]") a.toPublic(A); PrivateKey aprime; // a' - crypto->derive_subkey_private(aprime, root_key, 1); + crypto::derive_subkey_private(aprime, root_key, 1); PubKey Aprime; // A' - crypto->derive_subkey(Aprime, A, 1); + crypto::derive_subkey(Aprime, A, 1); const std::string s = "Jeff loves one-letter variable names."; llarp_buffer_t buf(s.data(), s.size()); Signature sig; - CHECK(crypto->sign(sig, aprime, buf)); - CHECK(crypto->verify(Aprime, buf, sig)); + CHECK(crypto::sign(sig, aprime, buf)); + CHECK(crypto::verify(Aprime, buf, sig)); } TEST_CASE("Test sign and encrypt introset", "[crypto]") { - CryptoManager manager(new sodium::CryptoLibSodium()); - service::Identity ident; ident.RegenerateKeys(); service::Address addr; @@ -227,7 +211,6 @@ TEST_CASE("Test sign and encrypt introset", "[crypto]") CHECK(maybe->Verify(now)); PubKey blind_key; const PubKey root_key(addr.as_array()); - auto crypto = CryptoManager::instance(); - CHECK(crypto->derive_subkey(blind_key, root_key, 1)); + CHECK(crypto::derive_subkey(blind_key, root_key, 1)); CHECK(blind_key == maybe->derivedSigningKey); } diff --git a/test/service/test_llarp_service_name.cpp b/test/service/test_llarp_service_name.cpp index 86f0324f3..6e0af69ea 100644 --- a/test/service/test_llarp_service_name.cpp +++ b/test/service/test_llarp_service_name.cpp @@ -1,5 +1,5 @@ #include "catch2/catch.hpp" -#include +#include #include #include @@ -7,7 +7,6 @@ using namespace std::literals; TEST_CASE("Test LNS name decrypt", "[lns]") { - llarp::sodium::CryptoLibSodium crypto; constexpr auto recordhex = "0ba76cbfdb6dc8f950da57ae781912f31c8ad0c55dbf86b88cb0391f563261a9656571a817be4092969f8a78ee0fcee260424acb4a1f4bbdd27348b71de006b6152dd04ed11bf3c4"sv; const auto recordbin = oxenc::from_hex(recordhex); CHECK(not recordbin.empty()); @@ -16,7 +15,7 @@ TEST_CASE("Test LNS name decrypt", "[lns]") const auto len = recordbin.size() - n.size(); std::copy_n(recordbin.cbegin() + len, n.size(), n.data()); std::copy_n(recordbin.cbegin(), len, std::back_inserter(ciphertext)); - const auto maybe = crypto.maybe_decrypt_name(std::string_view{reinterpret_cast(ciphertext.data()), ciphertext.size()}, n, "jason.loki"); + const auto maybe = llarp::crypto::maybe_decrypt_name(std::string_view{reinterpret_cast(ciphertext.data()), ciphertext.size()}, n, "jason.loki"); CHECK(maybe.has_value()); const llarp::service::Address addr{*maybe}; CHECK(addr.ToString() == "azfoj73snr9f3neh5c6sf7rtbaeabyxhr1m4un5aydsmsrxo964o.loki"); diff --git a/test/test_llarp_encrypted_frame.cpp b/test/test_llarp_encrypted_frame.cpp index 6648ba9b1..e42a00d80 100644 --- a/test/test_llarp_encrypted_frame.cpp +++ b/test/test_llarp_encrypted_frame.cpp @@ -2,7 +2,6 @@ #include "test_util.hpp" #include #include -#include #include #include @@ -13,14 +12,13 @@ using SecretKey = SecretKey; using PubKey = PubKey; using LRCR = LR_CommitRecord; -class FrameTest : public test::LlarpTest<> +class FrameTest { public: FrameTest() : test::LlarpTest<>{} { - auto crypto = CryptoManager::instance(); - crypto->encryption_keygen(alice); - crypto->encryption_keygen(bob); + crypto::encryption_keygen(alice); + crypto::encryption_keygen(bob); } SecretKey alice, bob; diff --git a/test/test_llarp_router_contact.cpp b/test/test_llarp_router_contact.cpp index f94e7904b..f3a7611e5 100644 --- a/test/test_llarp_router_contact.cpp +++ b/test/test_llarp_router_contact.cpp @@ -1,17 +1,10 @@ #include #include -#include #include #include #include -namespace -{ - llarp::sodium::CryptoLibSodium crypto; - llarp::CryptoManager cmanager(&crypto); -} - namespace llarp { @@ -20,10 +13,10 @@ TEST_CASE("RouterContact Sign and Verify", "[RC][RouterContact][signature][sign] RouterContact rc; SecretKey sign; - cmanager.instance()->identity_keygen(sign); + crypto::identity_keygen(sign); SecretKey encr; - cmanager.instance()->encryption_keygen(encr); + crypto::encryption_keygen(encr); rc.enckey = encr.toPublic(); rc.pubkey = sign.toPublic(); @@ -37,10 +30,10 @@ TEST_CASE("RouterContact Decode Version 1", "[RC][RouterContact][V1]") RouterContact rc; SecretKey sign; - cmanager.instance()->identity_keygen(sign); + crypto::identity_keygen(sign); SecretKey encr; - cmanager.instance()->encryption_keygen(encr); + crypto::encryption_keygen(encr); rc.version = 1; @@ -76,16 +69,16 @@ TEST_CASE("RouterContact Decode Mixed Versions", "[RC][RouterContact]") rc4.version = 1; SecretKey sign1, sign2, sign3, sign4; - cmanager.instance()->identity_keygen(sign1); - cmanager.instance()->identity_keygen(sign2); - cmanager.instance()->identity_keygen(sign3); - cmanager.instance()->identity_keygen(sign4); + crypto::identity_keygen(sign1); + crypto::identity_keygen(sign2); + crypto::identity_keygen(sign3); + crypto::identity_keygen(sign4); SecretKey encr1, encr2, encr3, encr4; - cmanager.instance()->encryption_keygen(encr1); - cmanager.instance()->encryption_keygen(encr2); - cmanager.instance()->encryption_keygen(encr3); - cmanager.instance()->encryption_keygen(encr4); + crypto::encryption_keygen(encr1); + crypto::encryption_keygen(encr2); + crypto::encryption_keygen(encr3); + crypto::encryption_keygen(encr4); rc1.enckey = encr1.toPublic(); rc2.enckey = encr2.toPublic();