Skip to content

Commit

Permalink
refactor: Use structs for public key and secret key in NGC.
Browse files Browse the repository at this point in the history
  • Loading branch information
iphydf committed Feb 28, 2024
1 parent ed2b60c commit dd18ec3
Show file tree
Hide file tree
Showing 20 changed files with 386 additions and 387 deletions.
4 changes: 2 additions & 2 deletions toxcore/Messenger.c
Original file line number Diff line number Diff line change
Expand Up @@ -2594,8 +2594,8 @@ static bool self_announce_group(const Messenger *m, GC_Chat *chat, Onion_Friend
memcpy(&announce.base_announce.ip_port, &chat->self_ip_port, sizeof(IP_Port));
}

memcpy(announce.base_announce.peer_public_key, chat->self_public_key.enc, ENC_PUBLIC_KEY_SIZE);
memcpy(announce.chat_public_key, get_chat_id(&chat->chat_public_key), ENC_PUBLIC_KEY_SIZE);
announce.base_announce.peer_public_key = chat->self_public_key.enc;
announce.chat_public_key = chat->chat_public_key.enc;

uint8_t gc_data[GCA_MAX_DATA_LENGTH];
const int length = gca_pack_public_announce(m->log, gc_data, GCA_MAX_DATA_LENGTH, &announce);
Expand Down
24 changes: 12 additions & 12 deletions toxcore/crypto_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,41 +50,41 @@ bool create_extended_keypair(Extended_Public_Key *pk, Extended_Secret_Key *sk, c
/* create signature key pair */
uint8_t seed[crypto_sign_SEEDBYTES];
random_bytes(rng, seed, crypto_sign_SEEDBYTES);
crypto_sign_seed_keypair(pk->sig, sk->sig, seed);
crypto_sign_seed_keypair(pk->sig.data, sk->sig.data, seed);
crypto_memzero(seed, crypto_sign_SEEDBYTES);

/* convert public signature key to public encryption key */
const int res1 = crypto_sign_ed25519_pk_to_curve25519(pk->enc, pk->sig);
const int res1 = crypto_sign_ed25519_pk_to_curve25519(pk->enc.data, pk->sig.data);

/* convert secret signature key to secret encryption key */
const int res2 = crypto_sign_ed25519_sk_to_curve25519(sk->enc, sk->sig);
const int res2 = crypto_sign_ed25519_sk_to_curve25519(sk->enc.data, sk->sig.data);

return res1 == 0 && res2 == 0;
}

const uint8_t *get_enc_key(const Extended_Public_Key *key)
{
return key->enc;
return key->enc.data;
}

const uint8_t *get_sig_pk(const Extended_Public_Key *key)
{
return key->sig;
return key->sig.data;
}

void set_sig_pk(Extended_Public_Key *key, const uint8_t *sig_pk)
{
memcpy(key->sig, sig_pk, SIG_PUBLIC_KEY_SIZE);
memcpy(key->sig.data, sig_pk, SIG_PUBLIC_KEY_SIZE);
}

const uint8_t *get_sig_sk(const Extended_Secret_Key *key)
{
return key->sig;
return key->sig.data;
}

const uint8_t *get_chat_id(const Extended_Public_Key *key)
{
return key->sig;
return key->sig.data;
}

#if !defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION)
Expand Down Expand Up @@ -210,16 +210,16 @@ uint32_t random_range_u32(const Random *rng, uint32_t upper_bound)

bool crypto_signature_create(uint8_t signature[CRYPTO_SIGNATURE_SIZE],
const uint8_t *message, uint64_t message_length,
const uint8_t secret_key[SIG_SECRET_KEY_SIZE])
const Sign_Secret_Key *secret_key)
{
return crypto_sign_detached(signature, nullptr, message, message_length, secret_key) == 0;
return crypto_sign_detached(signature, nullptr, message, message_length, secret_key->data) == 0;
}

bool crypto_signature_verify(const uint8_t signature[CRYPTO_SIGNATURE_SIZE],
const uint8_t *message, uint64_t message_length,
const uint8_t public_key[SIG_PUBLIC_KEY_SIZE])
const Sign_Public_Key *public_key)
{
return crypto_sign_verify_detached(signature, message, message_length, public_key) == 0;
return crypto_sign_verify_detached(signature, message, message_length, public_key->data) == 0;
}

bool public_key_valid(const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE])
Expand Down
40 changes: 28 additions & 12 deletions toxcore/crypto_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,32 @@ const Random *os_random(void);
*/
#define CRYPTO_HMAC_KEY_SIZE 32

typedef struct Public_Key {
uint8_t data[CRYPTO_PUBLIC_KEY_SIZE];
} Public_Key;

typedef struct Secret_Key {
uint8_t data[CRYPTO_SECRET_KEY_SIZE];
} Secret_Key;

typedef struct Sign_Public_Key {
uint8_t data[CRYPTO_SIGN_PUBLIC_KEY_SIZE];
} Sign_Public_Key;

typedef struct Sign_Secret_Key {
uint8_t data[CRYPTO_SIGN_SECRET_KEY_SIZE];
} Sign_Secret_Key;

typedef struct Extended_Public_Key {
Public_Key enc;
Sign_Public_Key sig;
} Extended_Public_Key;

typedef struct Extended_Secret_Key {
Secret_Key enc;
Sign_Secret_Key sig;
} Extended_Secret_Key;

/**
* @brief A `bzero`-like function which won't be optimised away by the compiler.
*
Expand Down Expand Up @@ -285,7 +311,7 @@ uint32_t random_range_u32(const Random *rng, uint32_t upper_bound);
non_null()
bool crypto_signature_create(uint8_t signature[CRYPTO_SIGNATURE_SIZE],
const uint8_t *message, uint64_t message_length,
const uint8_t secret_key[SIG_SECRET_KEY_SIZE]);
const Sign_Secret_Key *secret_key);

/** @brief Verifies that the given signature was produced by a given message and public key.
*
Expand All @@ -300,7 +326,7 @@ bool crypto_signature_create(uint8_t signature[CRYPTO_SIGNATURE_SIZE],
non_null()
bool crypto_signature_verify(const uint8_t signature[CRYPTO_SIGNATURE_SIZE],
const uint8_t *message, uint64_t message_length,
const uint8_t public_key[SIG_PUBLIC_KEY_SIZE]);
const Sign_Public_Key *public_key);

/**
* @brief Fill the given nonce with random bytes.
Expand All @@ -324,16 +350,6 @@ void random_bytes(const Random *rng, uint8_t *bytes, size_t length);
non_null()
bool public_key_valid(const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE]);

typedef struct Extended_Public_Key {
uint8_t enc[CRYPTO_PUBLIC_KEY_SIZE];
uint8_t sig[CRYPTO_SIGN_PUBLIC_KEY_SIZE];
} Extended_Public_Key;

typedef struct Extended_Secret_Key {
uint8_t enc[CRYPTO_SECRET_KEY_SIZE];
uint8_t sig[CRYPTO_SIGN_SECRET_KEY_SIZE];
} Extended_Secret_Key;

/**
* @brief Creates an extended keypair: curve25519 and ed25519 for encryption and signing
* respectively. The Encryption keys are derived from the signature keys.
Expand Down
20 changes: 10 additions & 10 deletions toxcore/crypto_core_pack.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,21 +15,21 @@
bool pack_extended_public_key(const Extended_Public_Key *key, Bin_Pack *bp)
{
uint8_t ext_key[EXT_PUBLIC_KEY_SIZE];
static_assert(sizeof(ext_key) == sizeof(key->enc) + sizeof(key->sig),
static_assert(sizeof(ext_key) == sizeof(key->enc.data) + sizeof(key->sig.data),
"extended secret key size is not the sum of the encryption and sign secret key sizes");
memcpy(ext_key, key->enc, sizeof(key->enc));
memcpy(&ext_key[sizeof(key->enc)], key->sig, sizeof(key->sig));
memcpy(ext_key, key->enc.data, sizeof(key->enc.data));
memcpy(&ext_key[sizeof(key->enc.data)], key->sig.data, sizeof(key->sig.data));

return bin_pack_bin(bp, ext_key, sizeof(ext_key));
}

bool pack_extended_secret_key(const Extended_Secret_Key *key, Bin_Pack *bp)
{
uint8_t ext_key[EXT_SECRET_KEY_SIZE];
static_assert(sizeof(ext_key) == sizeof(key->enc) + sizeof(key->sig),
static_assert(sizeof(ext_key) == sizeof(key->enc.data) + sizeof(key->sig.data),
"extended secret key size is not the sum of the encryption and sign secret key sizes");
memcpy(ext_key, key->enc, sizeof(key->enc));
memcpy(&ext_key[sizeof(key->enc)], key->sig, sizeof(key->sig));
memcpy(ext_key, key->enc.data, sizeof(key->enc.data));
memcpy(&ext_key[sizeof(key->enc.data)], key->sig.data, sizeof(key->sig.data));

const bool result = bin_pack_bin(bp, ext_key, sizeof(ext_key));
crypto_memzero(ext_key, sizeof(ext_key));
Expand All @@ -44,8 +44,8 @@ bool unpack_extended_public_key(Extended_Public_Key *key, Bin_Unpack *bu)
return false;
}

memcpy(key->enc, ext_key, sizeof(key->enc));
memcpy(key->sig, &ext_key[sizeof(key->enc)], sizeof(key->sig));
memcpy(key->enc.data, ext_key, sizeof(key->enc.data));
memcpy(key->sig.data, &ext_key[sizeof(key->enc.data)], sizeof(key->sig.data));

return true;
}
Expand All @@ -58,8 +58,8 @@ bool unpack_extended_secret_key(Extended_Secret_Key *key, Bin_Unpack *bu)
return false;
}

memcpy(key->enc, ext_key, sizeof(key->enc));
memcpy(key->sig, &ext_key[sizeof(key->enc)], sizeof(key->sig));
memcpy(key->enc.data, ext_key, sizeof(key->enc.data));
memcpy(key->sig.data, &ext_key[sizeof(key->enc.data)], sizeof(key->sig.data));
crypto_memzero(ext_key, sizeof(ext_key));

return true;
Expand Down
8 changes: 4 additions & 4 deletions toxcore/crypto_core_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -81,10 +81,10 @@ TEST(CryptoCore, Signatures)
// Try a few different sizes, including empty 0 length message.
for (uint8_t i = 0; i < 100; ++i) {
Signature signature;
EXPECT_TRUE(crypto_signature_create(
signature.data(), message.data(), message.size(), get_sig_sk(&sk)));
EXPECT_TRUE(crypto_signature_verify(
signature.data(), message.data(), message.size(), get_sig_pk(&pk)));
EXPECT_TRUE(
crypto_signature_create(signature.data(), message.data(), message.size(), &sk.sig));
EXPECT_TRUE(
crypto_signature_verify(signature.data(), message.data(), message.size(), &pk.sig));

message.push_back(random_u08(rng));
}
Expand Down
24 changes: 12 additions & 12 deletions toxcore/group_announce.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,12 @@ static void remove_announces(GC_Announces_List *gc_announces_list, GC_Announces
* Returns null if no announce is found.
*/
non_null()
static GC_Announces *get_announces_by_chat_id(const GC_Announces_List *gc_announces_list, const uint8_t *chat_id)
static GC_Announces *get_announces_by_chat_id(const GC_Announces_List *gc_announces_list, const Public_Key *chat_id)
{
GC_Announces *announces = gc_announces_list->root_announces;

while (announces != nullptr) {
if (memcmp(announces->chat_id, chat_id, CHAT_ID_SIZE) == 0) {
if (memcmp(&announces->chat_id, chat_id, CHAT_ID_SIZE) == 0) {
return announces;
}

Expand All @@ -60,7 +60,7 @@ static GC_Announces *get_announces_by_chat_id(const GC_Announces_List *gc_announ
}

int gca_get_announces(const GC_Announces_List *gc_announces_list, GC_Announce *gc_announces, uint8_t max_nodes,
const uint8_t *chat_id, const uint8_t *except_public_key)
const Public_Key *chat_id, const Public_Key *except_public_key)
{
if (gc_announces == nullptr || gc_announces_list == nullptr || chat_id == nullptr || max_nodes == 0
|| except_public_key == nullptr) {
Expand All @@ -78,15 +78,15 @@ int gca_get_announces(const GC_Announces_List *gc_announces_list, GC_Announce *g
for (size_t i = 0; i < announces->index && i < GCA_MAX_SAVED_ANNOUNCES_PER_GC && added_count < max_nodes; ++i) {
const size_t index = i % GCA_MAX_SAVED_ANNOUNCES_PER_GC;

if (memcmp(except_public_key, announces->peer_announces[index].base_announce.peer_public_key,
if (memcmp(except_public_key, &announces->peer_announces[index].base_announce.peer_public_key,
ENC_PUBLIC_KEY_SIZE) == 0) {
continue;
}

bool already_added = false;

for (size_t j = 0; j < added_count; ++j) {
if (memcmp(gc_announces[j].peer_public_key, announces->peer_announces[index].base_announce.peer_public_key,
if (memcmp(&gc_announces[j].peer_public_key, &announces->peer_announces[index].base_announce.peer_public_key,
ENC_PUBLIC_KEY_SIZE) == 0) {
already_added = true;
break;
Expand Down Expand Up @@ -125,7 +125,7 @@ int gca_pack_announce(const Logger *log, uint8_t *data, uint16_t length, const G
}

uint16_t offset = 0;
memcpy(data + offset, announce->peer_public_key, ENC_PUBLIC_KEY_SIZE);
memcpy(data + offset, announce->peer_public_key.data, ENC_PUBLIC_KEY_SIZE);
offset += ENC_PUBLIC_KEY_SIZE;

data[offset] = announce->ip_port_is_set ? 1 : 0;
Expand Down Expand Up @@ -186,7 +186,7 @@ static int gca_unpack_announce(const Logger *log, const uint8_t *data, uint16_t
}

uint16_t offset = 0;
memcpy(announce->peer_public_key, data + offset, ENC_PUBLIC_KEY_SIZE);
memcpy(announce->peer_public_key.data, data + offset, ENC_PUBLIC_KEY_SIZE);
offset += ENC_PUBLIC_KEY_SIZE;

net_unpack_bool(&data[offset], &announce->ip_port_is_set);
Expand Down Expand Up @@ -233,7 +233,7 @@ int gca_pack_public_announce(const Logger *log, uint8_t *data, uint16_t length,
return -1;
}

memcpy(data, public_announce->chat_public_key, CHAT_ID_SIZE);
memcpy(data, public_announce->chat_public_key.data, CHAT_ID_SIZE);

const int packed_size = gca_pack_announce(log, data + CHAT_ID_SIZE, length - CHAT_ID_SIZE,
&public_announce->base_announce);
Expand Down Expand Up @@ -264,7 +264,7 @@ int gca_unpack_public_announce(const Logger *log, const uint8_t *data, uint16_t
return -1;
}

memcpy(public_announce->chat_public_key, data, CHAT_ID_SIZE);
memcpy(public_announce->chat_public_key.data, data, CHAT_ID_SIZE);

const int base_announce_size = gca_unpack_announce(log, data + ENC_PUBLIC_KEY_SIZE, length - ENC_PUBLIC_KEY_SIZE,
&public_announce->base_announce);
Expand Down Expand Up @@ -361,7 +361,7 @@ static GC_Announces *gca_new_announces(

announces->next_announce = gc_announces_list->root_announces;
gc_announces_list->root_announces = announces;
memcpy(announces->chat_id, public_announce->chat_public_key, CHAT_ID_SIZE);
announces->chat_id = public_announce->chat_public_key;

return announces;
}
Expand All @@ -373,7 +373,7 @@ GC_Peer_Announce *gca_add_announce(const Mono_Time *mono_time, GC_Announces_List
return nullptr;
}

GC_Announces *announces = get_announces_by_chat_id(gc_announces_list, public_announce->chat_public_key);
GC_Announces *announces = get_announces_by_chat_id(gc_announces_list, &public_announce->chat_public_key);

// No entry for this chat_id exists so we create one
if (announces == nullptr) {
Expand Down Expand Up @@ -464,7 +464,7 @@ void do_gca(const Mono_Time *mono_time, GC_Announces_List *gc_announces_list)
}
}

void cleanup_gca(GC_Announces_List *gc_announces_list, const uint8_t *chat_id)
void cleanup_gca(GC_Announces_List *gc_announces_list, const Public_Key *chat_id)
{
if (gc_announces_list == nullptr || chat_id == nullptr) {
return;
Expand Down
10 changes: 5 additions & 5 deletions toxcore/group_announce.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ struct GC_Announce {
uint8_t tcp_relays_count;
bool ip_port_is_set;
IP_Port ip_port;
uint8_t peer_public_key[ENC_PUBLIC_KEY_SIZE];
Public_Key peer_public_key;
};

/* Peer announce for specific group. */
Expand All @@ -62,12 +62,12 @@ struct GC_Peer_Announce {
/* Used for announces in public groups. */
struct GC_Public_Announce {
GC_Announce base_announce;
uint8_t chat_public_key[ENC_PUBLIC_KEY_SIZE];
Public_Key chat_public_key;
};

/* A linked list that holds all announces for a particular group. */
struct GC_Announces {
uint8_t chat_id[CHAT_ID_SIZE];
Public_Key chat_id;
uint64_t index;
uint64_t last_announce_received_timestamp;

Expand Down Expand Up @@ -109,7 +109,7 @@ void do_gca(const Mono_Time *mono_time, GC_Announces_List *gc_announces_list);
* @param chat_id The chat ID that designates the entry we want to remove.
*/
non_null()
void cleanup_gca(GC_Announces_List *gc_announces_list, const uint8_t *chat_id);
void cleanup_gca(GC_Announces_List *gc_announces_list, const Public_Key *chat_id);

/** @brief Puts a set of announces from the announces list in supplied list.
*
Expand All @@ -124,7 +124,7 @@ void cleanup_gca(GC_Announces_List *gc_announces_list, const uint8_t *chat_id);
*/
non_null()
int gca_get_announces(const GC_Announces_List *gc_announces_list, GC_Announce *gc_announces, uint8_t max_nodes,
const uint8_t *chat_id, const uint8_t *except_public_key);
const Public_Key *chat_id, const Public_Key *except_public_key);

/** @brief Adds a public_announce to list of announces.
*
Expand Down
19 changes: 14 additions & 5 deletions toxcore/group_announce_fuzz_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -87,16 +87,25 @@ void TestDoGca(Fuzz_Data &input)
CONSUME1_OR_RETURN(const uint8_t, max_nodes, input);
// Always allocate at least something to avoid passing nullptr to functions below.
std::vector<GC_Announce> gc_announces(max_nodes + 1);
CONSUME_OR_RETURN(const uint8_t *chat_id, input, CHAT_ID_SIZE);
CONSUME_OR_RETURN(const uint8_t *except_public_key, input, ENC_PUBLIC_KEY_SIZE);

CONSUME_OR_RETURN(const uint8_t *chat_id_data, input, CHAT_ID_SIZE);
Public_Key chat_id;
memcpy(chat_id.data, chat_id_data, CHAT_ID_SIZE);

CONSUME_OR_RETURN(const uint8_t *except_public_key_data, input, ENC_PUBLIC_KEY_SIZE);
Public_Key except_public_key;
memcpy(except_public_key.data, except_public_key_data, ENC_PUBLIC_KEY_SIZE);

gca_get_announces(
gca.get(), gc_announces.data(), max_nodes, chat_id, except_public_key);
gca.get(), gc_announces.data(), max_nodes, &chat_id, &except_public_key);
break;
}
case 3: {
// Remove a chat.
CONSUME_OR_RETURN(const uint8_t *chat_id, input, CHAT_ID_SIZE);
cleanup_gca(gca.get(), chat_id);
CONSUME_OR_RETURN(const uint8_t *chat_id_data, input, CHAT_ID_SIZE);
Public_Key chat_id;
memcpy(chat_id.data, chat_id_data, CHAT_ID_SIZE);
cleanup_gca(gca.get(), &chat_id);
break;
}
}
Expand Down
Loading

0 comments on commit dd18ec3

Please sign in to comment.