does not work

pull/1075/head
Jeff Becker 4 years ago
parent 99eb7726ff
commit 0f13591802
No known key found for this signature in database
GPG Key ID: F357B3B42F6F9B05

@ -42,8 +42,8 @@ else()
target_link_directories(${EXE} PRIVATE /usr/local/lib)
target_link_directories(${CTL} PRIVATE /usr/local/lib)
endif()
target_link_libraries(${EXE} PUBLIC ${EXE_LIBS} ${LIBS})
target_link_libraries(${CTL} PUBLIC ${EXE_LIBS} ${LIBS})
target_link_libraries(${EXE} PUBLIC ${EXE_LIBS} ${LIBS} ${CRYPTOGRAPHY_LIB})
target_link_libraries(${CTL} PUBLIC ${EXE_LIBS} ${LIBS} ${CRYPTOGRAPHY_LIB})
if(CURL_FOUND)
target_include_directories(${CTL} PRIVATE ${CURL_INCLUDE_DIRS})

@ -2,8 +2,11 @@
#include <sodium/crypto_generichash.h>
#include <sodium/crypto_sign.h>
#include <sodium/crypto_scalarmult.h>
#include <sodium/crypto_scalarmult_ed25519.h>
#include <sodium/crypto_scalarmult_ristretto255.h>
#include <sodium/crypto_stream_xchacha20.h>
#include <sodium/crypto_core_ed25519.h>
#include <sodium/crypto_core_ristretto255.h>
#include <util/mem.hpp>
#include <util/endian.hpp>
#include <cassert>
@ -181,6 +184,33 @@ namespace llarp
!= -1;
}
/// clamp a 32 byte ec point
static void
clamp_ed25519(byte_t *out)
{
out[0] &= 248;
out[31] &= 127;
out[31] |= 64;
}
template < typename K >
static K
clamp(const K &p)
{
K out = p;
clamp_ed25519(out);
return out;
}
template < typename K >
static bool
is_clamped(const K &key)
{
K other(key);
clamp_ed25519(other.data());
return other == key;
}
template < typename K >
static bool
make_scalar(byte_t *out, const K &k, uint64_t i)
@ -194,48 +224,58 @@ namespace llarp
if(not hash(h.data(), llarp_buffer_t(buf)))
return false;
// return make_point(n)
return crypto_core_ed25519_from_hash(out, h.data()) != -1;
return crypto_core_ed25519_from_uniform(out, h.data()) != -1;
}
static AlignedBuffer< 32 > zero;
bool
CryptoLibSodium::derive_subkey(PubKey &out_k, const PubKey &in_k,
CryptoLibSodium::derive_subkey(PubKey &out_key, const PubKey &root_key,
uint64_t key_n)
{
// scalar p
AlignedBuffer< 32 > p;
// p = H( i || in_k )
if(not make_scalar(p.data(), in_k, key_n))
if(not make_scalar(p.data(), root_key, key_n))
return false;
// out_k = in_k * p % N
crypto_core_ed25519_scalar_mul(out_k.data(), in_k.data(), p.data());
crypto_core_ed25519_scalar_mul(out_key.data(), root_key.data(), p.data());
LogInfo("derive_subkey() scalar = ", p, " root_key = ", root_key,
" derived_key = ", out_key);
return true;
}
bool
CryptoLibSodium::derive_subkey_secret(SecretKey &out_k,
const SecretKey &in_k, uint64_t key_n)
CryptoLibSodium::derive_subkey_secret(SecretKey &out_key,
const SecretKey &in_key,
uint64_t key_n)
{
const PubKey root_key = in_key.toPublic();
// scalar p
AlignedBuffer< 32 > p;
// p = H( i || in_k.pub)
if(not make_scalar(p.data(), in_k.toPublic(), key_n))
// p = H( i || in_key.pub)
if(not make_scalar(p.data(), root_key, key_n))
{
LogError("cannot make scalar");
return false;
}
// a * p * basepoint
crypto_core_ed25519_scalar_mul(out_key.data(), in_key.data(), p.data());
if(not out_key.Recalculate())
return false;
// out_k = in_n * p % N
crypto_core_ed25519_scalar_mul(out_k.data(), in_k.data(), p.data());
// recalculate out_K public component
return out_k.Recalculate();
LogInfo("derive_subkey_secret() scalar = ", p, " root_key = ", root_key,
" derived_key = ", out_key.toPublic(),
" full_derived_key = ", out_key.ToHex());
return true;
}
bool
CryptoLibSodium::seed_to_secretkey(llarp::SecretKey &secret,
const llarp::IdentitySecret &seed)
{
PubKey pk;
return crypto_sign_ed25519_seed_keypair(pk.data(), secret.data(),
return crypto_sign_ed25519_seed_keypair(secret.data() + 32, secret.data(),
seed.data())
!= -1;
}
void
CryptoLibSodium::randomize(const llarp_buffer_t &buff)
{
@ -258,6 +298,8 @@ namespace llarp
assert(pk == sk_pk);
(void)result;
(void)sk_pk;
// encryption_keygen(keys);
}
bool

@ -9,6 +9,7 @@
#include <sodium/crypto_sign.h>
#include <sodium/crypto_sign_ed25519.h>
#include <sodium/crypto_scalarmult_ed25519.h>
namespace llarp
{
@ -57,10 +58,7 @@ namespace llarp
bool
SecretKey::Recalculate()
{
AlignedBuffer< 32 > seed;
if(crypto_sign_ed25519_sk_to_seed(seed.data(), data()) == -1)
return false;
return crypto_sign_seed_keypair(data() + 32, data(), seed.data()) != -1;
return crypto_scalarmult_ed25519_base(data() + 32, data()) != -1;
}
bool

@ -62,7 +62,10 @@ namespace llarp
crypto_sign_ed25519_sk_to_curve25519(enckey.data(), signkey.data());
pub.Update(seckey_topublic(signkey));
crypto->pqe_keygen(pq);
crypto->derive_subkey_secret(derivedSignKey, signkey, 1);
if(not crypto->derive_subkey_secret(derivedSignKey, signkey, 1))
{
LogError("failed to generate derived key");
}
}
bool
@ -176,7 +179,7 @@ namespace llarp
buf.cur = buf.base;
const SharedSecret k(i.A.Addr());
CryptoManager::instance()->xchacha20(buf, k, encrypted.nounce);
encrypted.introsetPayload.reserve(buf.sz);
encrypted.introsetPayload.resize(buf.sz);
std::copy_n(buf.base, buf.sz, encrypted.introsetPayload.data());
if(not encrypted.Sign(derivedSignKey))
return {};

@ -78,7 +78,8 @@ namespace llarp
printer.printAttribute("d", derivedSigningKey);
printer.printAttribute("n", nounce);
printer.printAttribute("s", signedAt);
printer.printAttribute("x", introsetPayload);
printer.printAttribute(
"x", "[" + std::to_string(introsetPayload.size()) + " bytes]");
printer.printAttribute("z", sig);
return out;
}
@ -114,14 +115,15 @@ namespace llarp
return false;
buf.sz = buf.cur - buf.base;
buf.cur = buf.base;
return CryptoManager::instance()->sign(sig, k, buf);
if(not CryptoManager::instance()->sign(sig, k, buf))
return false;
LogInfo("signed encrypted introset: ", *this);
return true;
}
bool
EncryptedIntroSet::Verify(llarp_time_t now) const
{
if(signedAt > now)
return false;
if(IsExpired(now))
return false;
std::array< byte_t, MAX_INTROSET_SIZE + 128 > tmp;
@ -130,6 +132,7 @@ namespace llarp
copy.sig.Zero();
if(not copy.BEncode(&buf))
return false;
LogInfo("verify encrypted introset: ", copy, " sig = ", sig);
buf.sz = buf.cur - buf.base;
buf.cur = buf.base;
return CryptoManager::instance()->verify(derivedSigningKey, buf, sig);

@ -39,6 +39,7 @@ TEST_F(HiddenServiceTest, TestGenerateIntroSet)
EXPECT_CALL(m_crypto, sign(I.Z, _, _)).WillOnce(Return(true));
EXPECT_CALL(m_crypto, verify(_, _, I.Z)).WillOnce(Return(true));
EXPECT_CALL(m_crypto, xchacha20(_, _, _)).WillOnce(Return(true));
const auto maybe = ident.EncryptAndSignIntroSet(I, now);
ASSERT_TRUE(maybe.has_value());
ASSERT_TRUE(maybe->Verify(now));
@ -75,6 +76,9 @@ TEST_F(ServiceIdentityTest, EnsureKeys)
const SecretKey k;
EXPECT_CALL(m_crypto, derive_subkey_secret(_, _, _))
.WillRepeatedly(Return(true));
EXPECT_CALL(m_crypto, identity_keygen(_))
.WillOnce(WithArg< 0 >(FillArg< SecretKey >(0x02)));
@ -121,3 +125,61 @@ TEST_F(ServiceIdentityTest, EnsureKeysBrokenFile)
service::Identity identity;
ASSERT_FALSE(identity.EnsureKeys(p.string(), false));
}
struct RealCryptographyTest : public ::testing::Test
{
std::unique_ptr< CryptoManager > _manager;
void
SetUp()
{
_manager = std::make_unique< CryptoManager >(new sodium::CryptoLibSodium());
}
void
TearDown()
{
_manager.reset();
}
};
TEST_F(RealCryptographyTest, TestGenerateDeriveKey)
{
SecretKey root_key;
SecretKey sub_key;
PubKey sub_pubkey;
auto crypto = CryptoManager::instance();
crypto->identity_keygen(root_key);
ASSERT_TRUE(crypto->derive_subkey_secret(sub_key, root_key, 1));
ASSERT_TRUE(crypto->derive_subkey(sub_pubkey, root_key.toPublic(), 1));
ASSERT_EQ(sub_key.toPublic(), sub_pubkey);
}
TEST_F(RealCryptographyTest, TestEncryptAndSignIntroSet)
{
service::Identity ident;
ident.RegenerateKeys();
service::Address addr;
ASSERT_TRUE(ident.pub.CalculateAddress(addr.as_array()));
service::IntroSet I;
auto now = time_now_ms();
I.T = now;
while(I.I.size() < 10)
{
service::Introduction intro;
intro.expiresAt = now + (path::default_lifetime / 2);
intro.router.Randomize();
intro.pathID.Randomize();
I.I.emplace_back(std::move(intro));
}
const auto maybe = ident.EncryptAndSignIntroSet(I, now);
ASSERT_TRUE(maybe.has_value());
llarp::LogInfo("introset=", maybe.value());
ASSERT_TRUE(maybe->Verify(now));
PubKey blind_key;
const PubKey root_key(addr.as_array());
auto crypto = CryptoManager::instance();
ASSERT_TRUE(crypto->derive_subkey(blind_key, root_key, 1));
ASSERT_EQ(blind_key, root_key);
}

Loading…
Cancel
Save