Commit f1c49e7f authored by xpetrak2's avatar xpetrak2
Browse files

New crypto functions, macro wrappers

Encrypt/decrypt message
Hash message
Hash check
Public/secret key and signature bytes macros simplification
parent 229ccd19
......@@ -21,6 +21,96 @@
#include <string.h>
#include "crypto.h"
#include "log.h"
/**
* Decrypt a message into a parameter that is dynamically allocated in here.
*
* @param message The message to be decrypted.
* @param public_key The public key used for decryption.
* @param secret_key The secret key used for decryption.
* @param decrypted Dynamically allocated decrypted message.
*
* @return 0 Successfully decrypted.
* @return 1 Failure.
*/
int decrypt_message(const char *message,
const unsigned char public_key[PUBLIC_KEY_SIZE],
const unsigned char secret_key[SECRET_KEY_SIZE],
char **decrypted)
{
size_t decrypted_len;
size_t msg_len;
int res;
msg_len = strlen(message);
decrypted_len = msg_len - crypto_box_SEALBYTES;
*decrypted = (char *) malloc((decrypted_len + 1) * sizeof(char));
if (!*decrypted) {
log_error("Allocation of a decrypted message");
return 1;
}
if (!(res = crypto_box_seal_open((unsigned char *) *decrypted,
(const unsigned char *) message,
msg_len,
public_key,
secret_key))) {
decrypted[decrypted_len] = '\0';
} else {
free(decrypted);
}
return res;
}
/**
* Encrypt a message into a parameter that is dynamically allocated in here.
*
* @param message The message to be encrypted.
* @param public_key The public key used for encryption.
* @param encrypted Dynamically allocated encrypted message.
*
* @return 0 Successfully encrypted.
* @return 1 Failure.
*/
int encrypt_message(const char *message,
const unsigned char public_key[PUBLIC_KEY_SIZE],
char **encrypted)
{
size_t encrypted_len;
size_t msg_len;
msg_len = strlen(message);
encrypted_len = crypto_box_SEALBYTES + msg_len;
*encrypted = (char *) malloc((encrypted_len + 1) * sizeof(char));
if (!*encrypted) {
log_error("Allocation of an encrypted message");
return 1;
}
crypto_box_seal((unsigned char *) *encrypted,
(const unsigned char *) message,
msg_len,
public_key);
(*encrypted)[encrypted_len] = '\0';
return 0;
}
/**
* Fetch random value.
*
* @param value Store the random value in here.
* @param value_size Size of the value in bytes.
*/
void fetch_random_value(void *value, size_t value_size)
{
randombytes_buf(value, value_size);
}
/**
* Generate a keypair.
......@@ -60,28 +150,54 @@ uint64_t get_random_uint64_t(void)
}
/**
* Create a hash of a string.
* Check hash of a message.
*
* @param string_message Create a hash of this string.
* @param hash Store the hash in here.
* @param type Hashing function.
* @param hash Hash to be checked.
* @param message Hash of this message.
* @param message_size Size of the message.
*
* @return 0 Hash successfully created.
* @return -1 Hashing failed.
* @return 0 The hashes match.
* @return 1 The hashes don't match.
*/
int hash_message(const char *string_message,
unsigned char hash[crypto_generichash_BYTES])
int hash_check(enum hash_type type,
const unsigned char *hash,
const unsigned char *message,
size_t message_size)
{
/* from libsodium doc: 'key can be NULL and keylen can be 0. In this
* case, a message will always have the same fingerprint, similar to
* the MD5 or SHA-1 functions for which crypto_generichash() is a
* faster and more secure alternative.'
*/
return crypto_generichash(hash,
crypto_generichash_BYTES,
(const unsigned char *) string_message,
strlen(string_message),
NULL,
0);
/* TODO: Implement using wolfssl */
switch (type) {
case HT_SHA3_256:
break;
case HT_RIPEMD_160:
break;
}
return 0;
}
/**
* Hash a message.
*
* @param type Hashing function.
* @param message Hash this message.
* @param message_size Size of the message.
* @param hash The result hash.
*/
void hash_message(enum hash_type type,
const unsigned char *message,
size_t message_size,
unsigned char *hash)
{
/* TODO: Implement using wolfssl */
switch (type) {
case HT_SHA3_256:
break;
case HT_RIPEMD_160:
break;
}
}
/**
......@@ -92,8 +208,8 @@ int hash_message(const char *string_message,
* @param signature Store the result in here.
*/
void sign_message(const char *string_message,
const unsigned char secret_key[crypto_box_SECRETKEYBYTES],
unsigned char signature[crypto_sign_BYTES])
const unsigned char secret_key[SECRET_KEY_SIZE],
unsigned char signature[SIGNATURE_SIZE])
{
/* from libsodium doc: It is safe to ignore siglen and always consider
* a signature as crypto_sign_BYTES bytes long: shorter signatures
......@@ -117,8 +233,8 @@ void sign_message(const char *string_message,
* @param 1 Invalid signature.
*/
int verify_signature(const char *string_message,
const unsigned char public_key[crypto_box_PUBLICKEYBYTES],
const unsigned char signature[crypto_sign_BYTES])
const unsigned char public_key[PUBLIC_KEY_SIZE],
const unsigned char signature[SIGNATURE_SIZE])
{
return crypto_sign_verify_detached(signature,
(const unsigned char *) string_message,
......
......@@ -22,27 +22,56 @@
#include <sodium.h>
#include <stdint.h>
#define PUBLIC_KEY_SIZE crypto_box_PUBLICKEYBYTES
#define SECRET_KEY_SIZE crypto_box_SECRETKEYBYTES
#define SIGNATURE_SIZE crypto_sign_BYTES
/* TODO: replace with macros from wolfssl */
#define RIPEMD_160_SIZE 20
#define SHA3_256_SIZE 32
/** A Pair of public and secret key. */
typedef struct s_keypair {
/** Public key. */
unsigned char public_key[crypto_box_PUBLICKEYBYTES];
unsigned char public_key[PUBLIC_KEY_SIZE];
/** Secret key. */
unsigned char secret_key[crypto_box_SECRETKEYBYTES];
unsigned char secret_key[SECRET_KEY_SIZE];
} keypair_t;
enum hash_type {
HT_RIPEMD_160,
HT_SHA3_256
};
int decrypt_message(const char *message,
const unsigned char public_key[PUBLIC_KEY_SIZE],
const unsigned char secret_key[SECRET_KEY_SIZE],
char **decrypted);
int encrypt_message(const char *message,
const unsigned char public_key[PUBLIC_KEY_SIZE],
char **encrypted);
void fetch_random_value(void *value, size_t value_size);
void generate_keypair(keypair_t *keypair);
uint32_t get_random_uint32_t(uint32_t upper_bound);
uint64_t get_random_uint64_t(void);
int hash_message(const char *string_message,
unsigned char hash[crypto_generichash_BYTES]);
void sign_message(const char *string_message,
const unsigned char secret_key[crypto_box_SECRETKEYBYTES],
unsigned char signature[crypto_sign_BYTES]);
int hash_check(enum hash_type type,
const unsigned char *hash,
const unsigned char *value,
size_t value_size);
void hash_message(enum hash_type type,
const unsigned char *message,
size_t message_size,
unsigned char *hash);
void sign_message(const char *string_message,
const unsigned char secret_key[SECRET_KEY_SIZE],
unsigned char signature[SIGNATURE_SIZE]);
int verify_signature(const char *string_message,
const unsigned char public_key[crypto_box_PUBLICKEYBYTES],
const unsigned char signature[crypto_sign_BYTES]);
const unsigned char public_key[PUBLIC_KEY_SIZE],
const unsigned char signature[SIGNATURE_SIZE]);
#endif /* CRYPTO_H */
......@@ -16,11 +16,11 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <sodium.h>
#include <stdlib.h>
#include <string.h>
#include "autoconfig.h"
#include "crypto.h"
#include "daemon_messages.h"
#include "hosts.h"
#include "log.h"
......@@ -188,7 +188,7 @@ int create_p2p_route_sol(message_t *message, const unsigned char *target)
return 1;
}
memcpy(route_sol->target, target, crypto_box_PUBLICKEYBYTES);
memcpy(route_sol->target, target, PUBLIC_KEY_SIZE);
message->body.type = P2P_ROUTE_SOL;
message->body.data = route_sol;
......
......@@ -22,6 +22,7 @@
#include <sodium.h>
#include <stdint.h>
#include "crypto.h"
#include "linkedlist.h"
/** Current version of coincer daemon protocol. */
......@@ -62,14 +63,14 @@ typedef struct s_p2p_peers_adv {
*/
typedef struct s_p2p_route_sol {
/** The peer's identifier. */
unsigned char target[crypto_box_PUBLICKEYBYTES];
unsigned char target[PUBLIC_KEY_SIZE];
} p2p_route_sol_t;
/**
* Internal message body representation.
*/
typedef struct s_message_body {
unsigned char to[crypto_box_PUBLICKEYBYTES]; /**< Destination. */
unsigned char to[PUBLIC_KEY_SIZE]; /**< Destination. */
enum message_type type; /**< Message type. */
void *data; /**< Message content. */
uint64_t nonce; /**< Message's nonce. */
......@@ -80,9 +81,9 @@ typedef struct s_message_body {
*/
typedef struct s_message {
int version; /**< Protocol version. */
unsigned char from[crypto_box_PUBLICKEYBYTES]; /**< Sender. */
unsigned char from[PUBLIC_KEY_SIZE]; /**< Sender. */
message_body_t body; /**< Message body. */
unsigned char sig[crypto_sign_BYTES]; /**< Signature. */
unsigned char sig[SIGNATURE_SIZE]; /**< Signature. */
} message_t;
int create_p2p_bye(message_t *message);
......
......@@ -236,7 +236,7 @@ static enum process_message_result
* the message should be a broadcast (we will check later) */
if (memcmp(message->from,
sender->pseudonym.identifier,
crypto_box_PUBLICKEYBYTES)) {
PUBLIC_KEY_SIZE)) {
/* process the broadcast with the true identity */
identity = global_state->true_identity;
/* otherwise it is a n2n message */
......@@ -247,16 +247,14 @@ static enum process_message_result
/* for later parity check */
cmp_val = memcmp(message->from,
identity->keypair.public_key,
crypto_box_PUBLICKEYBYTES);
PUBLIC_KEY_SIZE);
}
/* the message is of type p2p */
} else {
/* identity will be NULL if the message is not meant for us */
identity = identity_find(identities, msg_body->to);
/* for later parity check */
cmp_val = memcmp(message->from,
msg_body->to,
crypto_box_PUBLICKEYBYTES);
cmp_val = memcmp(message->from, msg_body->to, PUBLIC_KEY_SIZE);
}
/* nonce parity check; the message must have:
......@@ -494,9 +492,7 @@ static int process_p2p_hello(const message_t *message,
sender->host->port = hello->port;
}
memcpy(sender->pseudonym.identifier,
message->from,
crypto_box_PUBLICKEYBYTES);
memcpy(sender->pseudonym.identifier, message->from, PUBLIC_KEY_SIZE);
set_neighbour_flags(sender, NEIGHBOUR_ACTIVE);
......
......@@ -35,11 +35,9 @@
* @return 1 The identifier is empty.
* @return 0 The identifier is not empty.
*/
int identifier_empty(const unsigned char id[crypto_box_PUBLICKEYBYTES])
int identifier_empty(const unsigned char id[PUBLIC_KEY_SIZE])
{
return id[0] == 0x0 && !memcmp(id,
id + 1,
crypto_box_PUBLICKEYBYTES - 1);
return id[0] == 0x0 && !memcmp(id, id + 1, PUBLIC_KEY_SIZE - 1);
}
/**
......@@ -66,7 +64,7 @@ identity_t *identity_find(const linkedlist_t *identities,
/* if the identifier represents one of our identities */
if (!memcmp(identity->keypair.public_key,
identifier,
crypto_box_PUBLICKEYBYTES)) {
PUBLIC_KEY_SIZE)) {
return identity;
}
......@@ -333,9 +331,7 @@ peer_t *peer_find(const linkedlist_t *peers,
node = linkedlist_get_first(peers);
while (node) {
peer = (peer_t *) node->data;
if (!memcmp(peer->identifier,
identifier,
crypto_box_PUBLICKEYBYTES)) {
if (!memcmp(peer->identifier, identifier, PUBLIC_KEY_SIZE)) {
return peer;
}
node = linkedlist_get_next(peers, node);
......@@ -365,7 +361,7 @@ peer_t *peer_store(linkedlist_t *peers,
}
linkedlist_init(&new_peer->nonces);
memcpy(new_peer->identifier, identifier, crypto_box_PUBLICKEYBYTES);
memcpy(new_peer->identifier, identifier, PUBLIC_KEY_SIZE);
memset(&new_peer->presence_nonce, 0x0, sizeof(nonce_t));
if (!(new_peer->node = linkedlist_append(peers, new_peer))) {
......
......@@ -43,7 +43,7 @@ typedef struct s_nonce {
/** Peer representation. */
typedef struct s_peer {
/** Peer's public key. */
unsigned char identifier[crypto_box_PUBLICKEYBYTES];
unsigned char identifier[PUBLIC_KEY_SIZE];
/** A sorted list of nonces tied to this peer. */
linkedlist_t nonces;
/** The last known 'announcement of presence' nonce of this peer. */
......@@ -64,7 +64,7 @@ typedef struct s_identity {
uint64_t nonce_value;
} identity_t;
int identifier_empty(const unsigned char id[crypto_box_PUBLICKEYBYTES]);
int identifier_empty(const unsigned char id[PUBLIC_KEY_SIZE]);
identity_t *identity_find(const linkedlist_t *identities,
const unsigned char *identifier);
......
......@@ -170,19 +170,19 @@ static int message_finalize(message_t *message,
message->version = PROTOCOL_VERSION;
memcpy(message->from,
from->keypair.public_key,
crypto_box_PUBLICKEYBYTES);
PUBLIC_KEY_SIZE);
if (dest_vis == DV_HIDDEN) {
memset(message->body.to, 0x0, crypto_box_PUBLICKEYBYTES);
memset(message->body.to, 0x0, PUBLIC_KEY_SIZE);
} else {
memcpy(message->body.to, to, crypto_box_PUBLICKEYBYTES);
memcpy(message->body.to, to, PUBLIC_KEY_SIZE);
}
nonce_value = from->nonce_value + 1;
cmp_val = memcmp(message->from,
message->body.to,
crypto_box_PUBLICKEYBYTES);
PUBLIC_KEY_SIZE);
/* from ID > to ID => odd nonce; from ID < to ID => even nonce */
if ((cmp_val > 0 && !(nonce_value & 0x01)) ||
(cmp_val < 0 && (nonce_value & 0x01))) {
......@@ -359,7 +359,7 @@ static int message_trace_store(linkedlist_t *msg_traces,
msg_trace->sender = sender;
msg_trace->nonce_value = nonce_value;
msg_trace->creation = time(NULL);
memcpy(msg_trace->from, from, crypto_box_PUBLICKEYBYTES);
memcpy(msg_trace->from, from, PUBLIC_KEY_SIZE);
if (!linkedlist_append(msg_traces, msg_trace)) {
log_error("Storing a message trace");
......@@ -459,7 +459,7 @@ route_t *route_find(const linkedlist_t *routing_table,
route = (route_t *) node->data;
id = route->destination->identifier;
if (!memcmp(id, dest_id, crypto_box_PUBLICKEYBYTES)) {
if (!memcmp(id, dest_id, PUBLIC_KEY_SIZE)) {
return route;
}
......@@ -579,7 +579,7 @@ int routing_loop_detect(const linkedlist_t *msg_traces,
/* the same message but different neighbour => routing loop */
if (msg_trace->nonce_value == nonce_value &&
msg_trace->sender != neighbour &&
!memcmp(msg_trace->from, from, crypto_box_PUBLICKEYBYTES)) {
!memcmp(msg_trace->from, from, PUBLIC_KEY_SIZE)) {
return 1;
}
......
......@@ -39,7 +39,7 @@ typedef struct s_message_trace {
/** Message's nonce value. */
uint64_t nonce_value;
/** Identifier of the sender. */
char from[crypto_box_PUBLICKEYBYTES];
char from[PUBLIC_KEY_SIZE];
/** Neighbour who's sent us the message */
const neighbour_t *sender;
/** Creation timestamp. */
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment