Remove byte* conversion operators from llarp::AlignedBuffer

pull/190/head
Michael 6 years ago
parent 58364a01c8
commit 1410d0a0cf
No known key found for this signature in database
GPG Key ID: 2D51757B47E2434C

@ -201,11 +201,6 @@ namespace llarp
return as_array().data();
}
operator byte_t*()
{
return as_array().data();
}
typename Data::iterator
begin()
{

@ -40,49 +40,122 @@ static constexpr uint32_t PATHIDSIZE = 16;
namespace llarp
{
using SharedSecret = AlignedBuffer< SHAREDKEYSIZE >;
using KeyExchangeNonce = AlignedBuffer< 32 >;
struct PubKey final : public AlignedBuffer< PUBKEYSIZE >
{
PubKey() : AlignedBuffer< SIZE >()
{
}
PubKey(const byte_t *ptr) : AlignedBuffer< SIZE >(ptr)
{
}
PubKey(const Data &data) : AlignedBuffer< SIZE >(data)
{
}
std::string
ToString() const;
bool
FromString(const std::string &str);
friend std::ostream &
operator<<(std::ostream &out, const PubKey &k)
{
return out << k.ToString();
}
operator RouterID() const
{
return RouterID(as_array());
}
PubKey &
operator=(const byte_t *ptr)
{
std::copy(ptr, ptr + SIZE, as_array().begin());
return *this;
}
};
struct SecretKey final : public AlignedBuffer< SECKEYSIZE >
{
friend std::ostream &
operator<<(std::ostream &out, const SecretKey &)
{
// make sure we never print out secret keys
return out << "[secretkey]";
}
bool
LoadFromFile(const char *fname);
bool
SaveToFile(const char *fname) const;
SecretKey &
operator=(const byte_t *ptr)
{
std::copy(ptr, ptr + SIZE, as_array().begin());
return *this;
}
};
using ShortHash = AlignedBuffer< SHORTHASHSIZE >;
using Signature = AlignedBuffer< SIGSIZE >;
using TunnelNonce = AlignedBuffer< TUNNONCESIZE >;
using SymmNonce = AlignedBuffer< NONCESIZE >;
using SymmKey = AlignedBuffer< 32 >;
using PQCipherBlock = AlignedBuffer< PQ_CIPHERTEXTSIZE + 1 >;
using PQPubKey = AlignedBuffer< PQ_PUBKEYSIZE >;
using PQKeyPair = AlignedBuffer< PQ_KEYPAIRSIZE >;
/// label functors
/// PKE(result, publickey, secretkey, nonce)
using path_dh_func = std::function< bool(byte_t *, const byte_t *,
using path_dh_func = std::function< bool(SharedSecret &, const PubKey &,
const byte_t *, const byte_t *) >;
/// TKE(result, publickey, secretkey, nonce)
using transport_dh_func = std::function< bool(
byte_t *, const byte_t *, const byte_t *, const byte_t *) >;
SharedSecret &, const PubKey &, const byte_t *, const byte_t *) >;
/// SD/SE(buffer, key, nonce)
using sym_cipher_func =
std::function< bool(llarp_buffer_t, const byte_t *, const byte_t *) >;
/// SD/SE(dst, src, key, nonce)
using sym_ciper_alt_func = std::function< bool(
using sym_cipher_alt_func = std::function< bool(
llarp_buffer_t, llarp_buffer_t, const byte_t *, const byte_t *) >;
/// H(result, body)
using hash_func = std::function< bool(byte_t *, llarp_buffer_t) >;
/// SH(result, body)
using shorthash_func = std::function< bool(byte_t *, llarp_buffer_t) >;
using shorthash_func = std::function< bool(ShortHash &, llarp_buffer_t) >;
/// MDS(result, body, shared_secret)
using hmac_func =
std::function< bool(byte_t *, llarp_buffer_t, const byte_t *) >;
std::function< bool(byte_t *, llarp_buffer_t, const SharedSecret &) >;
/// S(sig, secretkey, body)
using sign_func =
std::function< bool(byte_t *, const byte_t *, llarp_buffer_t) >;
std::function< bool(Signature &, const SecretKey &, llarp_buffer_t) >;
/// V(pubkey, body, sig)
using verify_func =
std::function< bool(const byte_t *, llarp_buffer_t, const byte_t *) >;
std::function< bool(const PubKey &, llarp_buffer_t, const byte_t *) >;
/// library crypto configuration
struct Crypto
{
/// xchacha symettric cipher
/// xchacha symmetric cipher
sym_cipher_func xchacha20;
/// xchacha symettric cipher (multibuffer)
sym_ciper_alt_func xchacha20_alt;
/// xchacha symmetric cipher (multibuffer)
sym_cipher_alt_func xchacha20_alt;
/// path dh creator's side
path_dh_func dh_client;
/// path dh relay side
@ -106,15 +179,17 @@ namespace llarp
/// randomizer memory
std::function< void(void *, size_t) > randbytes;
/// generate signing keypair
std::function< void(byte_t *) > identity_keygen;
std::function< void(SecretKey &) > identity_keygen;
/// generate encryption keypair
std::function< void(byte_t *) > encryption_keygen;
std::function< void(SecretKey &) > encryption_keygen;
/// generate post quantum encrytion key
std::function< void(byte_t *) > pqe_keygen;
std::function< void(PQKeyPair &) > pqe_keygen;
/// post quantum decrypt (buffer, sharedkey_dst, sec)
std::function< bool(const byte_t *, byte_t *, const byte_t *) > pqe_decrypt;
std::function< bool(const PQCipherBlock &, SharedSecret &, const byte_t *) >
pqe_decrypt;
/// post quantum encrypt (buffer, sharedkey_dst, pub)
std::function< bool(byte_t *, byte_t *, const byte_t *) > pqe_encrypt;
std::function< bool(PQCipherBlock &, SharedSecret &, const byte_t *) >
pqe_encrypt;
// Give a basic type tag for the constructor to pick libsodium
struct sodium
@ -137,73 +212,6 @@ namespace llarp
const byte_t *
pq_keypair_to_secret(const byte_t *keypair);
using SharedSecret = AlignedBuffer< SHAREDKEYSIZE >;
using KeyExchangeNonce = AlignedBuffer< 32 >;
struct PubKey final : public AlignedBuffer< PUBKEYSIZE >
{
PubKey() : AlignedBuffer< SIZE >(){}
PubKey(const byte_t *ptr) : AlignedBuffer< SIZE >(ptr){}
PubKey(const Data& data) : AlignedBuffer< SIZE >(data){}
std::string
ToString() const;
bool
FromString(const std::string &str);
friend std::ostream &
operator<<(std::ostream &out, const PubKey &k)
{
return out << k.ToString();
}
operator RouterID() const
{
return RouterID(as_array());
}
PubKey &
operator=(const byte_t *ptr)
{
std::copy(ptr, ptr + SIZE, as_array().begin());
return *this;
}
};
struct SecretKey final : public AlignedBuffer< SECKEYSIZE >
{
friend std::ostream &
operator<<(std::ostream &out, const SecretKey &)
{
// make sure we never print out secret keys
return out << "[secretkey]";
}
bool
LoadFromFile(const char *fname);
bool
SaveToFile(const char *fname) const;
SecretKey &
operator=(const byte_t *ptr)
{
std::copy(ptr, ptr + SIZE, as_array().begin());
return *this;
}
};
using ShortHash = AlignedBuffer< SHORTHASHSIZE >;
using Signature = AlignedBuffer< SIGSIZE >;
using TunnelNonce = AlignedBuffer< TUNNONCESIZE >;
using SymmNonce = AlignedBuffer< NONCESIZE >;
using SymmKey = AlignedBuffer< 32 >;
using PQCipherBlock = AlignedBuffer< PQ_CIPHERTEXTSIZE + 1 >;
using PQPubKey = AlignedBuffer< PQ_PUBKEYSIZE >;
using PQKeyPair = AlignedBuffer< PQ_KEYPAIRSIZE >;
} // namespace llarp
#endif

@ -34,32 +34,33 @@ namespace llarp
}
static bool
dh(uint8_t *out, const uint8_t *client_pk, const uint8_t *server_pk,
const uint8_t *themPub, const uint8_t *usSec)
dh(llarp::SharedSecret &out, const PubKey &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))
if(crypto_scalarmult_curve25519(shared.as_array().data(), usSec, themPub))
return false;
crypto_generichash_blake2b_init(&h, nullptr, 0U, outsz);
crypto_generichash_blake2b_update(&h, client_pk, 32);
crypto_generichash_blake2b_update(&h, client_pk.as_array().data(), 32);
crypto_generichash_blake2b_update(&h, server_pk, 32);
crypto_generichash_blake2b_update(&h, shared, 32);
crypto_generichash_blake2b_final(&h, out, outsz);
crypto_generichash_blake2b_final(&h, out.as_array().data(), outsz);
return true;
}
static bool
dh_client(uint8_t *shared, const uint8_t *pk, const uint8_t *sk,
dh_client(llarp::SharedSecret &shared, const PubKey &pk, const uint8_t *sk,
const uint8_t *n)
{
llarp::SharedSecret dh_result;
if(dh(dh_result, llarp::seckey_topublic(sk), pk, pk, sk))
{
return crypto_generichash_blake2b(shared, 32, n, 32, dh_result, 32)
return crypto_generichash_blake2b(shared.as_array().data(), 32, n, 32,
dh_result, 32)
!= -1;
}
llarp::LogWarn("crypto::dh_client - dh failed");
@ -67,13 +68,14 @@ namespace llarp
}
static bool
dh_server(uint8_t *shared, const uint8_t *pk, const uint8_t *sk,
dh_server(llarp::SharedSecret &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_blake2b(shared, 32, n, 32, dh_result, 32)
return crypto_generichash_blake2b(shared.as_array().data(), 32, n, 32,
dh_result, 32)
!= -1;
}
llarp::LogWarn("crypto::dh_server - dh failed");
@ -89,32 +91,36 @@ namespace llarp
}
static bool
shorthash(uint8_t *result, llarp_buffer_t buff)
shorthash(ShortHash &result, llarp_buffer_t buff)
{
return crypto_generichash_blake2b(result, SHORTHASHSIZE, buff.base,
buff.sz, nullptr, 0)
return crypto_generichash_blake2b(result.as_array().data(),
ShortHash::SIZE, buff.base, buff.sz,
nullptr, 0)
!= -1;
}
static bool
hmac(uint8_t *result, llarp_buffer_t buff, const uint8_t *secret)
hmac(byte_t *result, llarp_buffer_t buff, const SharedSecret &secret)
{
return crypto_generichash_blake2b(result, HMACSIZE, buff.base, buff.sz,
secret, HMACSECSIZE)
secret.as_array().data(), HMACSECSIZE)
!= -1;
}
static bool
sign(uint8_t *result, const uint8_t *secret, llarp_buffer_t buff)
sign(Signature &result, const SecretKey &secret, llarp_buffer_t buff)
{
return crypto_sign_detached(result, nullptr, buff.base, buff.sz, secret)
return crypto_sign_detached(result.as_array().begin(), nullptr, buff.base,
buff.sz, secret.as_array().begin())
!= -1;
}
static bool
verify(const uint8_t *pub, llarp_buffer_t buff, const uint8_t *sig)
verify(const PubKey &pub, llarp_buffer_t buff, const uint8_t *sig)
{
return crypto_sign_verify_detached(sig, buff.base, buff.sz, pub) != -1;
return crypto_sign_verify_detached(sig, buff.base, buff.sz,
pub.as_array().data())
!= -1;
}
static void
@ -130,16 +136,18 @@ namespace llarp
}
static void
sigkeygen(uint8_t *keys)
sigkeygen(llarp::SecretKey &keys)
{
crypto_sign_keypair(keys + 32, keys);
auto d = keys.as_array().data();
crypto_sign_keypair(d + 32, d);
}
static void
enckeygen(uint8_t *keys)
enckeygen(llarp::SecretKey &keys)
{
randombytes(keys, 32);
crypto_scalarmult_curve25519_base(keys + 32, keys);
auto d = keys.as_array().data();
randombytes(d, 32);
crypto_scalarmult_curve25519_base(d + 32, d);
}
} // namespace sodium
@ -152,21 +160,27 @@ namespace llarp
namespace pq
{
bool
encrypt(byte_t *ciphertext, byte_t *sharedkey, const byte_t *pubkey)
encrypt(PQCipherBlock &ciphertext, SharedSecret &sharedkey,
const byte_t *pubkey)
{
return crypto_kem_enc(ciphertext, sharedkey, pubkey) != -1;
return crypto_kem_enc(ciphertext.as_array().data(),
sharedkey.as_array().data(), pubkey)
!= -1;
}
bool
decrypt(const byte_t *ciphertext, byte_t *sharedkey,
decrypt(const PQCipherBlock &ciphertext, SharedSecret &sharedkey,
const byte_t *secretkey)
{
return crypto_kem_dec(sharedkey, ciphertext, secretkey) != -1;
return crypto_kem_dec(sharedkey.as_array().data(),
ciphertext.as_array().data(), secretkey)
!= -1;
}
void
keygen(byte_t *keypair)
keygen(PQKeyPair &keypair)
{
crypto_kem_keypair(keypair + PQ_SECRETKEYSIZE, keypair);
auto d = keypair.as_array().data();
crypto_kem_keypair(d + PQ_SECRETKEYSIZE, d);
}
} // namespace pq

@ -14,16 +14,4 @@ namespace llarp
return input - 'a' + 10;
return 0;
}
bool
HexDecode(const char* src, uint8_t* target, size_t sz)
{
while(*src && src[1] && sz)
{
*(target++) = char2int(*src) * 16 + char2int(src[1]);
src += 2;
--sz;
}
return sz == 0;
}
} // namespace llarp

@ -133,8 +133,19 @@ namespace llarp
int
char2int(char input);
template < typename OutputIt >
bool
HexDecode(const char* src, uint8_t* target, size_t sz);
HexDecode(const char* src, OutputIt target, size_t sz)
{
while(*src && src[1] && sz)
{
*(target++) = char2int(*src) * 16 + char2int(src[1]);
src += 2;
--sz;
}
return sz == 0;
}
} // namespace llarp
#endif

@ -58,7 +58,7 @@ namespace llarp
if(!MDS(hash, buf, shared))
{
llarp::LogError("Failed to generate messgae auth");
llarp::LogError("Failed to generate message auth");
return false;
}
return true;
@ -79,7 +79,7 @@ namespace llarp
byte_t* otherPubkey = nonce + TUNNONCESIZE;
byte_t* body = otherPubkey + PUBKEYSIZE;
// use dh_server becuase we are not the creator of this message
// use dh_server because we are not the creator of this message
auto DH = crypto->dh_server;
auto Decrypt = crypto->xchacha20;
auto MDS = crypto->hmac;
@ -98,7 +98,7 @@ namespace llarp
return false;
}
if(!MDS(digest, buf, shared))
if(!MDS(digest.as_array().data(), buf, shared))
{
llarp::LogError("Digest failed");
return false;

@ -35,10 +35,12 @@ namespace llarp
// check 30 seconds into the future and see if we need more paths
const llarp_time_t future = now + (30 * 1000);
if(NumPathsExistingAt(future) < expect)
return llarp::randint() % 4 == 0; // 25% chance for build if we will run out soon
// if we don't have the expended number of paths right now try building some if the cooldown timer isn't hit
return llarp::randint() % 4
== 0; // 25% chance for build if we will run out soon
// if we don't have the expended number of paths right now try building
// some if the cooldown timer isn't hit
if(AvailablePaths(llarp::path::ePathRoleExit) < expect)
return !path::Builder::BuildCooldownHit(now);
return !path::Builder::BuildCooldownHit(now);
// maintain regular number of paths
return path::Builder::ShouldBuildMore(now);
}

@ -59,7 +59,7 @@ namespace llarp
{
llarp::RouterID exitRouter;
if(!(exitRouter.FromString(v)
|| HexDecode(v.c_str(), exitRouter, exitRouter.size())))
|| HexDecode(v.c_str(), exitRouter.begin(), exitRouter.size())))
{
llarp::LogError(Name(), " bad exit router key: ", v);
return false;

@ -140,7 +140,7 @@ namespace llarp
}
// K = TKE(a.p, B_a.e, sk, t_h)
if(!dh(K, other, secret, t_h))
if(!dh(K, other, secret, t_h.as_array().data()))
{
llarp::LogError("key exchange with ", other, " failed");
return false;

@ -52,7 +52,7 @@ namespace llarp
return m_Router->logic;
}
byte_t*
llarp::SecretKey&
PathContext::EncryptionSecretKey()
{
return m_Router->encryption;

@ -660,7 +660,7 @@ namespace llarp
llarp::Router*
Router();
byte_t*
llarp::SecretKey&
EncryptionSecretKey();
const byte_t*

@ -32,7 +32,7 @@ namespace llarp
if(now - timestamp > (uint64_t(extendedLifetime) * 1000))
return false;
byte_t digest[SHORTHASHSIZE];
ShortHash digest;
byte_t tmp[MaxSize];
auto buf = llarp::StackBuffer< decltype(tmp) >(tmp);
// encode

@ -123,7 +123,7 @@ llarp_router_try_connect(llarp::Router *router,
bool
llarp_findOrCreateIdentity(llarp::Crypto *crypto, const char *fpath,
byte_t *secretkey)
llarp::SecretKey &secretkey)
{
llarp::LogDebug("find or create ", fpath);
fs::path path(fpath);
@ -135,13 +135,14 @@ llarp_findOrCreateIdentity(llarp::Crypto *crypto, const char *fpath,
std::ofstream f(path.string(), std::ios::binary);
if(f.is_open())
{
f.write((char *)secretkey, SECKEYSIZE);
f.write(reinterpret_cast< char * >(secretkey.as_array().data()),
SECKEYSIZE);
}
}
std::ifstream f(path.string(), std::ios::binary);
if(f.is_open())
{
f.read((char *)secretkey, SECKEYSIZE);
f.read(reinterpret_cast< char * >(secretkey.as_array().data()), SECKEYSIZE);
return true;
}
llarp::LogInfo("failed to get identity key");

@ -37,8 +37,8 @@ llarp_findOrCreateEncryption(llarp::Crypto *crypto, const char *fpath,
llarp::SecretKey &encryption);
bool
llarp_findOrCreateIdentity(struct llarp::Crypto *crypto, const char *path,
byte_t *secretkey);
llarp_findOrCreateIdentity(llarp::Crypto *crypto, const char *path,
llarp::SecretKey &secretkey);
struct TryConnectJob;
@ -357,11 +357,12 @@ namespace llarp
llarp::ILinkLayer *
GetLinkWithSessionByPubkey(const llarp::RouterID &remote);
/// parse a routing message in a buffer and handle it with a handler if successful parsing
/// return true on parse and handle success otherwise return false
/// parse a routing message in a buffer and handle it with a handler if
/// successful parsing return true on parse and handle success otherwise
/// return false
bool
ParseRoutingMessageBuffer(llarp_buffer_t buf, routing::IMessageHandler * h, PathID_t rxid);
ParseRoutingMessageBuffer(llarp_buffer_t buf, routing::IMessageHandler *h,
PathID_t rxid);
void
ConnectToRandomRouters(int N);

@ -200,7 +200,9 @@ namespace llarp
RouterContact::SetNick(const std::string &nick)
{
nickname.Zero();
memcpy(nickname, nick.c_str(), std::min(nick.size(), nickname.size()));
std::copy(nick.begin(),
nick.begin() + std::min(nick.size(), nickname.size()),
nickname.begin());
}
bool

@ -220,14 +220,14 @@ namespace llarp
}
bool
Identity::KeyExchange(path_dh_func dh, byte_t* result,
Identity::KeyExchange(path_dh_func dh, SharedSecret& result,
const ServiceInfo& other, const byte_t* N) const
{
return dh(result, other.EncryptionPublicKey(), enckey, N);
}
bool
Identity::Sign(llarp::Crypto* c, byte_t* sig, llarp_buffer_t buf) const
Identity::Sign(Crypto* c, Signature& sig, llarp_buffer_t buf) const
{
return c->sign(sig, signkey, buf);
}

@ -40,7 +40,7 @@ namespace llarp
EnsureKeys(const std::string& fpath, llarp::Crypto* c);
bool
KeyExchange(llarp::path_dh_func dh, byte_t* sharedkey,
KeyExchange(llarp::path_dh_func dh, SharedSecret& sharedkey,
const ServiceInfo& other, const byte_t* N) const;
bool
@ -50,7 +50,7 @@ namespace llarp
SignIntroSet(IntroSet& i, llarp::Crypto* c, llarp_time_t now) const;
bool
Sign(llarp::Crypto*, byte_t* sig, llarp_buffer_t buf) const;
Sign(llarp::Crypto*, Signature& sig, llarp_buffer_t buf) const;
};
} // namespace service
} // namespace llarp

@ -1468,18 +1468,24 @@ namespace llarp
AsyncKeyExchange* self = static_cast< AsyncKeyExchange* >(user);
// derive ntru session key component
SharedSecret K;
self->crypto->pqe_encrypt(self->frame.C, K, self->introPubKey);
self->crypto->pqe_encrypt(self->frame.C, K,
self->introPubKey.as_array().data());
// randomize Nounce
self->frame.N.Randomize();
// compure post handshake session key
byte_t tmp[64];
// K
memcpy(tmp, K, 32);
// PKE (A, B, N)
if(!self->m_LocalIdentity.KeyExchange(self->crypto->dh_client, tmp + 32,
self->remote, self->frame.N))
SharedSecret sharedSecret;
if(!self->m_LocalIdentity.KeyExchange(self->crypto->dh_client,
sharedSecret, self->remote,
self->frame.N))
{
llarp::LogError("failed to derive x25519 shared key component");
}
std::array< byte_t, 64 > tmp;
// K
std::copy(K.begin(), K.end(), tmp.begin());
// H (K + PKE(A, B, N))
std::copy(sharedSecret.begin(), sharedSecret.end(), tmp.begin() + 32);
self->crypto->shorthash(self->sharedKey,
llarp::StackBuffer< decltype(tmp) >(tmp));
// set tag
@ -1560,7 +1566,7 @@ namespace llarp
llarp::LogError("Failed to send frame on path");
}
else
llarp::LogError("cannot send becuase we have no path to ",
llarp::LogError("cannot send because we have no path to ",
remoteIntro.router);
}

@ -266,11 +266,9 @@ namespace llarp
delete self;
return;
}
byte_t tmp[64];
// K
memcpy(tmp, K, 32);
// PKE (A, B, N)
if(!self->m_LocalIdentity.KeyExchange(crypto->dh_server, tmp + 32,
SharedSecret sharedSecret;
if(!self->m_LocalIdentity.KeyExchange(crypto->dh_server, sharedSecret,
self->msg->sender, self->frame.N))
{
llarp::LogError("x25519 key exchange failed");
@ -279,7 +277,11 @@ namespace llarp
delete self;
return;
}
std::array< byte_t, 64 > tmp;
// K
std::copy(K.begin(), K.end(), tmp.begin());
// S = HS( K + PKE( A, B, N))
std::copy(sharedSecret.begin(), sharedSecret.end(), tmp.begin() + 32);
crypto->shorthash(sharedKey, StackBuffer< decltype(tmp) >(tmp));
self->handler->PutIntroFor(self->msg->tag, self->msg->introReply);

@ -6,11 +6,10 @@ namespace llarp
{
struct PQCryptoTest : public ::testing::Test
{
llarp::Crypto crypto;
llarp::Crypto crypto;
PQKeyPair keys;
PQCryptoTest()
: crypto(llarp::Crypto::sodium{})
PQCryptoTest() : crypto(llarp::Crypto::sodium{})
{
}

Loading…
Cancel
Save