/* return length of recieved packet on success.
 * return 0 if could not read any packet.
 * return -1 on failure (connection must be killed).
 */
int read_packet_TCP_secure_connection(sock_t sock, uint16_t *next_packet_length, uint8_t *shared_key,
                                      uint8_t *recv_nonce, uint8_t *data, uint16_t max_len)
{
    if (*next_packet_length == 0) {
        uint16_t len = read_TCP_length(sock);

        if (len == (uint16_t)~0)
            return -1;

        if (len == 0)
            return 0;

        *next_packet_length = len;
    }

    if (max_len + crypto_box_MACBYTES < *next_packet_length)
        return -1;

    uint8_t data_encrypted[*next_packet_length];
    int len_packet = read_TCP_packet(sock, data_encrypted, *next_packet_length);

    if (len_packet != *next_packet_length)
        return 0;

    *next_packet_length = 0;

    int len = decrypt_data_fast(shared_key, recv_nonce, data_encrypted, len_packet, data);

    if (len + crypto_box_MACBYTES != len_packet)
        return -1;

    increment_nonce(recv_nonce);

    return len;
}
Example #2
0
/*  return 0 if there is no received data in the buffer.
 *  return -1  if the packet was discarded.
 *  return length of received data if successful.
 */
int read_cryptpacket(Net_Crypto *c, int crypt_connection_id, uint8_t *data)
{
    if (crypt_connection_id_not_valid(c, crypt_connection_id))
        return 0;

    if (c->crypto_connections[crypt_connection_id].status != CRYPTO_CONN_ESTABLISHED)
        return 0;

    uint8_t temp_data[MAX_DATA_SIZE];
    int length = read_packet(c->lossless_udp, c->crypto_connections[crypt_connection_id].number, temp_data);

    if (length == 0)
        return 0;

    if (temp_data[0] != 3)
        return -1;

    int len = decrypt_data_fast(c->crypto_connections[crypt_connection_id].shared_key,
                                c->crypto_connections[crypt_connection_id].recv_nonce,
                                temp_data + 1, length - 1, data);

    if (len != -1) {
        increment_nonce(c->crypto_connections[crypt_connection_id].recv_nonce);
        return len;
    }

    return -1;
}
Example #3
0
int decrypt_data(uint8_t *public_key, uint8_t *secret_key, uint8_t *nonce,
                 uint8_t *encrypted, uint32_t length, uint8_t *plain)
{
    uint8_t k[crypto_box_BEFORENMBYTES];
    encrypt_precompute(public_key, secret_key, k);
    return decrypt_data_fast(k, nonce, encrypted, length, plain);
}
Example #4
0
/* return length of recieved packet on success.
 * return 0 if could not read any packet.
 * return -1 on failure (connection must be killed).
 */
static int read_packet_TCP_secure_connection(TCP_Secure_Connection *con, uint8_t *data, uint16_t max_len)
{
    if (con->next_packet_length == 0) {
        uint16_t len = read_length(con->sock);

        if (len == (uint16_t)~0)
            return -1;

        if (len == 0)
            return 0;

        con->next_packet_length = len;
    }

    if (max_len + crypto_box_MACBYTES < con->next_packet_length)
        return -1;

    uint8_t data_encrypted[con->next_packet_length];
    int len_packet = read_TCP_packet(con->sock, data_encrypted, con->next_packet_length);

    if (len_packet != con->next_packet_length)
        return 0;

    con->next_packet_length = 0;

    int len = decrypt_data_fast(con->shared_key, con->recv_nonce, data_encrypted, len_packet, data);

    if (len + crypto_box_MACBYTES != len_packet)
        return -1;

    increment_nonce(con->recv_nonce);

    return len;
}
Example #5
0
/* return 0 if there is no received data in the buffer
   return -1  if the packet was discarded.
   return length of received data if successful */
int read_cryptpacket(int crypt_connection_id, uint8_t *data)
{
    if (crypt_connection_id < 0 || crypt_connection_id >= MAX_CRYPTO_CONNECTIONS)
        return 0;
    if (crypto_connections[crypt_connection_id].status != CONN_ESTABLISHED)
        return 0;
    uint8_t temp_data[MAX_DATA_SIZE];
    int length = read_packet(crypto_connections[crypt_connection_id].number, temp_data);
    if (length == 0)
        return 0;
    if (temp_data[0] != 3)
        return -1;
    int len = decrypt_data_fast(crypto_connections[crypt_connection_id].shared_key,
                                crypto_connections[crypt_connection_id].recv_nonce, 
                                temp_data + 1, length - 1, data);
    if (len != -1) {
        increment_nonce(crypto_connections[crypt_connection_id].recv_nonce);
        return len;
    }
    return -1;
}
/* return 1 if everything went well.
 * return -1 if the connection must be killed.
 */
static int handle_TCP_handshake(TCP_Secure_Connection *con, uint8_t *data, uint16_t length, uint8_t *self_secret_key)
{
    if (length != TCP_CLIENT_HANDSHAKE_SIZE)
        return -1;

    if (con->status != TCP_STATUS_CONNECTED)
        return -1;

    uint8_t shared_key[crypto_box_BEFORENMBYTES];
    encrypt_precompute(data, self_secret_key, shared_key);
    uint8_t plain[TCP_HANDSHAKE_PLAIN_SIZE];
    int len = decrypt_data_fast(shared_key, data + crypto_box_PUBLICKEYBYTES,
                                data + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES, TCP_HANDSHAKE_PLAIN_SIZE + crypto_box_MACBYTES, plain);

    if (len != TCP_HANDSHAKE_PLAIN_SIZE)
        return -1;

    memcpy(con->public_key, data, crypto_box_PUBLICKEYBYTES);
    uint8_t temp_secret_key[crypto_box_SECRETKEYBYTES];
    uint8_t resp_plain[TCP_HANDSHAKE_PLAIN_SIZE];
    crypto_box_keypair(resp_plain, temp_secret_key);
    random_nonce(con->sent_nonce);
    memcpy(resp_plain + crypto_box_PUBLICKEYBYTES, con->sent_nonce, crypto_box_NONCEBYTES);
    memcpy(con->recv_nonce, plain + crypto_box_PUBLICKEYBYTES, crypto_box_NONCEBYTES);

    uint8_t response[TCP_SERVER_HANDSHAKE_SIZE];
    new_nonce(response);

    len = encrypt_data_fast(shared_key, response, resp_plain, TCP_HANDSHAKE_PLAIN_SIZE, response + crypto_box_NONCEBYTES);

    if (len != TCP_HANDSHAKE_PLAIN_SIZE + crypto_box_MACBYTES)
        return -1;

    if (TCP_SERVER_HANDSHAKE_SIZE != send(con->sock, response, TCP_SERVER_HANDSHAKE_SIZE, MSG_NOSIGNAL))
        return -1;

    encrypt_precompute(plain, temp_secret_key, con->shared_key);
    con->status = TCP_STATUS_UNCONFIRMED;
    return 1;
}
int main(int argc, char *argv[])
{
    const int numtrials = 10000;

    unsigned char pk1[crypto_box_PUBLICKEYBYTES];
    unsigned char sk1[crypto_box_SECRETKEYBYTES];
    unsigned char pk2[crypto_box_PUBLICKEYBYTES];
    unsigned char sk2[crypto_box_SECRETKEYBYTES];
    unsigned char k1[crypto_box_BEFORENMBYTES];
    unsigned char k2[crypto_box_BEFORENMBYTES];

    unsigned char n[crypto_box_NONCEBYTES];

    unsigned char m[500];
    unsigned char c[sizeof(m) + ENCRYPTION_PADDING];

    unsigned char k[crypto_box_BEFORENMBYTES];

    int trialno;

    double starttime;
    double endtime;
    double slow_time;
    double fast_time;
    double keygen_time;
    double precompute_time;

    // Pregenerate
    crypto_box_keypair(pk1, sk1);
    crypto_box_keypair(pk2, sk2);
    encrypt_precompute(pk1, sk2, k1);
    encrypt_precompute(pk2, sk1, k2);
    rand_bytes(m, sizeof(m));
    rand_bytes(n, sizeof(n));

    printf("starting slow...\n");
    starttime = get_time();

    for (trialno = 0; trialno < numtrials; trialno++) {
        encrypt_data(pk1, sk2, n, m, sizeof(m), c);
        decrypt_data(pk2, sk1, n, c, sizeof(c), m);
    }

    endtime = get_time();
    slow_time = endtime - starttime;

    printf("starting fast...\n");
    starttime = get_time();

    for (trialno = 0; trialno < numtrials; trialno++) {
        encrypt_data_fast(k1, n, m, sizeof(m), c);
        decrypt_data_fast(k2, n, c, sizeof(c), m);
    }

    endtime = get_time();
    fast_time = endtime - starttime;

    printf("starting keygen...\n");
    starttime = get_time();

    for (trialno = 0; trialno < numtrials; trialno++) {
        crypto_box_keypair(pk1, sk1);
        crypto_box_keypair(pk2, sk2);
    }

    endtime = get_time();
    keygen_time = endtime - starttime;

    printf("starting precompute...\n");
    starttime = get_time();

    for (trialno = 0; trialno < numtrials; trialno++) {
        encrypt_precompute(pk1, sk2, k);
        encrypt_precompute(pk2, sk1, k);
    }

    endtime = get_time();
    precompute_time = endtime - starttime;

    printf("\n");
    printf("trials: %i\n", 2 * numtrials);
    printf("\n");
    printf("slow time: %f sec\n", slow_time);
    printf("fast time: %f sec\n", fast_time);
    printf("keygen time: %f sec\n", keygen_time);
    printf("precompute time: %f sec\n", precompute_time);
    printf("\n");
    printf("Speed boost: %.1f%%\n", slow_time * 100 / fast_time);
    printf("\n");
    printf("slow: %.1f per second\n", 2 * numtrials / slow_time);
    printf("fast: %.1f per second\n", 2 * numtrials / fast_time);

    return 0;
}