#include #include #include #include #include #include "mem.hpp" namespace llarp { namespace sodium { static bool xchacha20(llarp_buffer_t buff, const byte_t *k, const byte_t *n) { return crypto_stream_xchacha20_xor(buff.base, buff.base, buff.sz, n, k) == 0; } static bool dh(uint8_t *out, const uint8_t *client_pk, const uint8_t *server_pk, const uint8_t *themPub, const uint8_t *usSec) { llarp::SharedSecret shared; crypto_generichash_state h; const size_t outsz = SHAREDKEYSIZE; if(crypto_scalarmult_curve25519(shared, usSec, themPub)) return false; crypto_generichash_init(&h, nullptr, 0U, outsz); crypto_generichash_update(&h, client_pk, 32); crypto_generichash_update(&h, server_pk, 32); crypto_generichash_update(&h, shared, 32); crypto_generichash_final(&h, out, outsz); return true; } static bool dh_client(uint8_t *shared, const uint8_t *pk, const uint8_t *sk, const uint8_t *n) { llarp::SharedSecret dh_result; char ftmpPk[68] = {0}; const char *hexPk = llarp::HexEncode< llarp::PubKey, decltype(ftmpPk) >(pk, ftmpPk); llarp::LogDebug("PK :", hexPk); char ftmpSk[68] = {0}; const char *hexSk = llarp::HexEncode< llarp::PubKey, decltype(ftmpSk) >(sk, ftmpSk); llarp::LogDebug("SK :", hexSk); char ftmpSkPub[68] = {0}; const char *hexSkPub = llarp::HexEncode< llarp::PubKey, decltype(ftmpSkPub) >( llarp::seckey_topublic(sk), ftmpSkPub); llarp::LogDebug("SK pub :", hexSkPub); if(dh(dh_result, llarp::seckey_topublic(sk), pk, pk, sk)) { char ftmpResult[68] = {0}; const char *hexResult = llarp::HexEncode< llarp::SharedSecret, decltype(ftmpResult) >( dh_result, ftmpResult); llarp::LogDebug("Result :", hexResult); bool res = crypto_generichash(shared, 32, n, 32, dh_result, 32) != -1; char ftmpShared[68] = {0}; const char *hexShared = llarp::HexEncode< llarp::SharedSecret, decltype(ftmpShared) >( shared, ftmpShared); llarp::LogDebug("Shared :", hexShared); return res; } llarp::LogWarn("crypto::dh_client - dh failed"); return false; } static bool dh_server(uint8_t *shared, const uint8_t *pk, const uint8_t *sk, const uint8_t *n) { llarp::SharedSecret dh_result; if(dh(dh_result, pk, llarp::seckey_topublic(sk), pk, sk)) { return crypto_generichash(shared, 32, n, 32, dh_result, 32) != -1; } llarp::LogWarn("crypto::dh_server - dh failed"); return false; } static bool hash(uint8_t *result, llarp_buffer_t buff) { return crypto_generichash(result, HASHSIZE, buff.base, buff.sz, nullptr, 0) != -1; } static bool shorthash(uint8_t *result, llarp_buffer_t buff) { return crypto_generichash(result, SHORTHASHSIZE, buff.base, buff.sz, nullptr, 0) != -1; } static bool hmac(uint8_t *result, llarp_buffer_t buff, const uint8_t *secret) { return crypto_generichash(result, HMACSIZE, buff.base, buff.sz, secret, HMACSECSIZE) != -1; } static bool sign(uint8_t *result, const uint8_t *secret, llarp_buffer_t buff) { return crypto_sign_detached(result, nullptr, buff.base, buff.sz, secret) != -1; } static bool verify(const uint8_t *pub, llarp_buffer_t buff, const uint8_t *sig) { return crypto_sign_verify_detached(sig, buff.base, buff.sz, pub) != -1; } static void randomize(llarp_buffer_t buff) { randombytes((unsigned char *)buff.base, buff.sz); } static inline void randbytes(void *ptr, size_t sz) { randombytes((unsigned char *)ptr, sz); } static void sigkeygen(uint8_t *keys) { crypto_sign_keypair(keys + 32, keys); } static void enckeygen(uint8_t *keys) { crypto_box_keypair(keys + 32, keys); } } // namespace sodium const byte_t * seckey_topublic(const byte_t *sec) { return sec + 32; } namespace pq { bool encrypt(byte_t *ciphertext, byte_t *sharedkey, const byte_t *pubkey) { return crypto_kem_enc(ciphertext, sharedkey, pubkey) != -1; } bool decrypt(const byte_t *ciphertext, byte_t *sharedkey, const byte_t *secretkey) { return crypto_kem_dec(sharedkey, ciphertext, secretkey) != -1; } void keygen(byte_t *keypair) { crypto_kem_keypair(keypair + PQ_SECRETKEYSIZE, keypair); } } // namespace pq const byte_t * pq_keypair_to_public(const byte_t *k) { return k + PQ_SECRETKEYSIZE; } const byte_t * pq_keypair_to_secret(const byte_t *k) { return k; } } // namespace llarp void llarp_crypto_libsodium_init(struct llarp_crypto *c) { assert(sodium_init() != -1); char *avx2 = getenv("AVX2_FORCE_DISABLE"); if(avx2 && std::string(avx2) == "1") ntru_init(1); else ntru_init(0); c->xchacha20 = llarp::sodium::xchacha20; c->dh_client = llarp::sodium::dh_client; c->dh_server = llarp::sodium::dh_server; c->transport_dh_client = llarp::sodium::dh_client; c->transport_dh_server = llarp::sodium::dh_server; c->hash = llarp::sodium::hash; c->shorthash = llarp::sodium::shorthash; c->hmac = llarp::sodium::hmac; c->sign = llarp::sodium::sign; c->verify = llarp::sodium::verify; c->randomize = llarp::sodium::randomize; c->randbytes = llarp::sodium::randbytes; c->identity_keygen = llarp::sodium::sigkeygen; c->encryption_keygen = llarp::sodium::enckeygen; c->pqe_encrypt = llarp::pq::encrypt; c->pqe_decrypt = llarp::pq::decrypt; c->pqe_keygen = llarp::pq::keygen; int seed; c->randbytes(&seed, sizeof(seed)); srand(seed); } uint64_t llarp_randint() { uint64_t i; randombytes((byte_t *)&i, sizeof(i)); return i; }