"Refactor" aka delete Crypto/CryptoManager

- Get rid of CryptoManager.
- Get rid of Crypto.
- Move all the Crypto instance methods to llarp::crypto functions.
  (None of them needed to be methods at all, so this is simple).
- Move sodium/ntru initialization into static initialization.
- Add llarp::csrng, which is an available llarp::CSRNG instance which is
  a bit easier than needing to construct a `CSRNG rng{};` in various
  places.
- Various related small simplifications/cleanups.
pull/2213/head
Jason Rhinelander 7 months ago committed by dr7ana
parent e710cfea47
commit f4f5ab0109

@ -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> crypto = nullptr;
std::shared_ptr<CryptoManager> cryptoManager = nullptr;
std::shared_ptr<Router> router = nullptr;
std::shared_ptr<EventLoop> loop = nullptr;
std::shared_ptr<NodeDB> nodedb = nullptr;

@ -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;

@ -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<time_point_t::duration>(fseconds(TESTING_INTERVAL(rng)));
next_general_test = now
+ std::chrono::duration_cast<time_point_t::duration>(
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<time_point_t::duration>(
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;

@ -67,9 +67,6 @@ namespace llarp
loop = EventLoop::create(jobQueueSize);
}
crypto = std::make_shared<Crypto>();
cryptoManager = std::make_shared<CryptoManager>(crypto.get());
router = makeRouter(loop);
nodedb = makeNodeDB();

@ -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<unsigned char*>(&seed), sizeof(seed));
srand(seed);
}
std::optional<AlignedBuffer<32>>
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<crypto_sign_SEEDBYTES> 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

@ -15,12 +15,8 @@ namespace llarp
-
*/
struct Crypto
namespace crypto
{
Crypto();
~Crypto() = default;
/// decrypt cipherText given the key generated from name
std::optional<AlignedBuffer<32>>
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<uint64_t>::min();
};
}
static constexpr uint64_t
max()
{
return std::numeric_limits<uint64_t>::max();
};
}
uint64_t
operator()()
{
return llarp::randint();
};
}
};
extern CSRNG csrng;
} // namespace llarp

@ -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;

@ -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&)>;
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&)>;
bool(*)(SharedSecret&, const PubKey&, const SecretKey&, const TunnelNonce&);
/// SH(result, body)
using shorthash_func = std::function<bool(ShortHash&, const llarp_buffer_t&)>;
using shorthash_func = bool(*)(ShortHash&, const llarp_buffer_t&);
} // namespace llarp
namespace std

@ -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;

@ -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<unsigned char*>(frame.data()),
frame.size(),
@ -1157,7 +1155,7 @@ namespace llarp
}
// decrypt frame with our hop info
if (!crypto->xchacha20(
if (!crypto::xchacha20(
reinterpret_cast<unsigned char*>(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<path::Path>(
_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<path::Path>(
_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)

@ -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))

@ -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<uint8_t*>(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<uint8_t*>(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<uint8_t*>(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<uint8_t*>(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<uint8_t*>(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<uint8_t*>(sig.data()), sk, to_usv(btdp.view())))
throw std::runtime_error{
"Error: CloseExitMessage response failed to sign and serialize contents!"};

@ -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<unsigned char*>(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<uint8_t*>(hash.data()),
reinterpret_cast<uint8_t*>(hashed_data.data()),
hashed_data.size(),

@ -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)
{

@ -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<unsigned char*>(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<unsigned char*>(buf.data()) + payload.size(), PAD_SIZE - payload.size());
}
log::debug(path_cat, "Sending {}B routing message to {}", buf.size(), Endpoint());

@ -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<uint8_t*>(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<uint8_t*>(hash.data()),
reinterpret_cast<uint8_t*>(hashed_data.data()),
hashed_data.size(),

@ -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<size_t>{0, chosen.size() - 1}(llarp::csrng)];
}
Path_ptr

@ -77,7 +77,7 @@ namespace llarp::path
{
dlt = PAD_SIZE - dlt;
// randomize padding
CryptoManager::instance()->randbytes(reinterpret_cast<uint8_t*>(payload.data()), dlt);
crypto::randbytes(reinterpret_cast<uint8_t*>(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;

@ -31,7 +31,7 @@ namespace llarp
auto buf = bt_encode();
// hash
if (!CryptoManager::instance()->shorthash(
if (!crypto::shorthash(
digest, reinterpret_cast<uint8_t*>(buf.data()), buf.size()))
return false;
// check bytes required

@ -117,7 +117,8 @@ namespace llarp
std::unordered_set<RouterID> 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()))

@ -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);
}

@ -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()))

@ -364,7 +364,7 @@ namespace llarp
signed_bt_dict = bencode_signed_section();
return CryptoManager::instance()->sign(
return crypto::sign(
signature,
secretkey,
reinterpret_cast<uint8_t*>(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<uint8_t*>(bte.data()), bte.size(), signature);
}

@ -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()};
}

@ -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<uint8_t*>(buf.data()), buf.size());
crypto::shorthash(self->sharedKey, reinterpret_cast<uint8_t*>(buf.data()), buf.size());
// set tag
self->msg.tag = self->tag;

@ -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;

@ -874,7 +874,7 @@ namespace llarp::service
// pick up to max_unique_lns_endpoints random paths to do lookups from
std::vector<path::Path_ptr> 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)

@ -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<VanityNonce> 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<uint8_t*>(bte.data()), bte.size(), k, encrypted.nounce);
std::memcpy(encrypted.introsetPayload.data(), bte.data(), bte.size());

@ -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

@ -123,7 +123,7 @@ namespace llarp::service
std::string payload{
reinterpret_cast<const char*>(introsetPayload.data()), introsetPayload.size()};
CryptoManager::instance()->xchacha20(
crypto::xchacha20(
reinterpret_cast<uint8_t*>(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<uint8_t*>(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<uint8_t*>(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<uint8_t*>(key.data()),
reinterpret_cast<uint8_t*>(introset.data()),
introset.size(),

@ -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;

@ -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<size_t>{0, introset.intros.size() - 1}(rng);
}
next_intro = *it;
next_intro = *std::next(
introset.intros.begin(),
std::uniform_int_distribution<size_t>{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<unsigned char*>(buf.data()), buf.size());
crypto::randomize(reinterpret_cast<unsigned char*>(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

@ -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<uint8_t*>(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<AsyncFrameDecrypt> 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<MAX_PROTOCOL_MESSAGE_SIZE>(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<ProtocolMessage> msg = std::move(self->msg);
path::Path_ptr path = std::move(self->path);

@ -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<Data, std::string>)
hash(llarp_buffer_t{reinterpret_cast<const byte_t*>(data.data()), data.size()});

@ -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<std::string> valid_hashes;
// UNIX DES

@ -1,4 +1,3 @@
#include "llarp_test.hpp"
#include "test_util.hpp"
#include <llarp/config/key_manager.hpp>
@ -14,7 +13,7 @@
using namespace ::llarp;
struct KeyManagerTest : public test::LlarpTest<llarp::sodium::CryptoLibSodium>
struct KeyManagerTest
{
// paranoid file guards for anything KeyManager might touch
test::FileGuard m_rcFileGuard;

@ -1,30 +0,0 @@
#pragma once
#include <llarp/crypto/crypto_libsodium.hpp>
#include <catch2/catch.hpp>
namespace llarp::test
{
template <typename CryptoImpl = llarp::sodium::CryptoLibSodium>
class LlarpTest
{
protected:
CryptoImpl m_crypto;
CryptoManager cm;
LlarpTest() : cm(&m_crypto)
{
static_assert(std::is_base_of<Crypto, CryptoImpl>::value, "");
}
~LlarpTest()
{}
};
template <>
inline LlarpTest<llarp::sodium::CryptoLibSodium>::~LlarpTest()
{
} // namespace test
}

@ -1,4 +1,3 @@
#include "llarp_test.hpp"
#include <llarp/exit/exit_messages.hpp>
#include <llarp/crypto/crypto.hpp>
#include <llarp/crypto/crypto_libsodium.hpp>
@ -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();

@ -7,7 +7,6 @@
#include <llarp/service/intro_set.hpp>
#include <llarp/util/time.hpp>
#include "test_util.hpp"
#include <catch2/catch.hpp>
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);
}

@ -1,5 +1,5 @@
#include "catch2/catch.hpp"
#include <llarp/crypto/crypto_libsodium.hpp>
#include <llarp/crypto/crypto.hpp>
#include <llarp/service/name.hpp>
#include <oxenc/hex.h>
@ -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<const char *>(ciphertext.data()), ciphertext.size()}, n, "jason.loki");
const auto maybe = llarp::crypto::maybe_decrypt_name(std::string_view{reinterpret_cast<const char *>(ciphertext.data()), ciphertext.size()}, n, "jason.loki");
CHECK(maybe.has_value());
const llarp::service::Address addr{*maybe};
CHECK(addr.ToString() == "azfoj73snr9f3neh5c6sf7rtbaeabyxhr1m4un5aydsmsrxo964o.loki");

@ -2,7 +2,6 @@
#include "test_util.hpp"
#include <llarp/crypto/encrypted_frame.hpp>
#include <llarp/crypto/crypto.hpp>
#include <llarp/crypto/crypto_libsodium.hpp>
#include <llarp/messages/relay_commit.hpp>
#include <catch2/catch.hpp>
@ -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;

@ -1,17 +1,10 @@
#include <catch2/catch.hpp>
#include <llarp/crypto/crypto.hpp>
#include <llarp/crypto/crypto_libsodium.hpp>
#include <llarp/router_contact.hpp>
#include <llarp/net/net_int.hpp>
#include <llarp/util/time.hpp>
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();

Loading…
Cancel
Save