예제 #1
0
/* return 1 on success.
 * return 0 if could not send packet.
 * return -1 on failure (connection must be killed).
 */
static int write_packet_TCP_secure_connection(TCP_Secure_Connection *con, uint8_t *data, uint16_t length)
{
    if (length + crypto_box_MACBYTES > MAX_PACKET_SIZE)
        return -1;

    if (send_pending_data(con) == -1)
        return 0;

    uint8_t packet[sizeof(uint16_t) + length + crypto_box_MACBYTES];

    uint16_t c_length = htons(length + crypto_box_MACBYTES);
    memcpy(packet, &c_length, sizeof(uint16_t));
    int len = encrypt_data_fast(con->shared_key, con->sent_nonce, data, length, packet + sizeof(uint16_t));

    if ((unsigned int)len != (sizeof(packet) - sizeof(uint16_t)))
        return -1;

    increment_nonce(con->sent_nonce);

    len = send(con->sock, packet, sizeof(packet), MSG_NOSIGNAL);

    if ((unsigned int)len == sizeof(packet))
        return 1;

    if (len <= 0)
        return 0;

    memcpy(con->last_packet, packet, length);
    con->last_packet_length = sizeof(packet);
    con->last_packet_sent = len;
    return 1;
}
예제 #2
0
/*  return 0 if data could not be put in packet queue.
 *  return 1 if data was put into the queue.
 */
int write_cryptpacket(Net_Crypto *c, int crypt_connection_id, uint8_t *data, uint32_t length)
{
    if (crypt_connection_id_not_valid(c, crypt_connection_id))
        return 0;

    if (length - crypto_box_BOXZEROBYTES + crypto_box_ZEROBYTES > MAX_DATA_SIZE - 1)
        return 0;

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

    uint8_t temp_data[MAX_DATA_SIZE];
    int len = encrypt_data_fast(c->crypto_connections[crypt_connection_id].shared_key,
                                c->crypto_connections[crypt_connection_id].sent_nonce,
                                data, length, temp_data + 1);

    if (len == -1)
        return 0;

    temp_data[0] = 3;

    if (write_packet(c->lossless_udp, c->crypto_connections[crypt_connection_id].number, temp_data, len + 1) == 0)
        return 0;

    increment_nonce(c->crypto_connections[crypt_connection_id].sent_nonce);
    return 1;
}
예제 #3
0
int encrypt_data(uint8_t *public_key, uint8_t *secret_key, uint8_t *nonce,
                 uint8_t *plain, uint32_t length, uint8_t *encrypted)
{
    uint8_t k[crypto_box_BEFORENMBYTES];
    encrypt_precompute(public_key, secret_key, k);
    return encrypt_data_fast(k, nonce, plain, length, encrypted);
}
예제 #4
0
/* return 1 on success.
 * return 0 if could not send packet.
 * return -1 on failure (connection must be killed).
 */
static int write_packet_TCP_secure_connection(TCP_Secure_Connection *con, uint8_t *data, uint16_t length)
{
    if (length + crypto_box_MACBYTES > MAX_PACKET_SIZE)
        return -1;

    uint8_t packet[sizeof(uint16_t) + length + crypto_box_MACBYTES];

    length = htons(length);
    memcpy(packet, &length, sizeof(uint16_t));
    uint32_t len = encrypt_data_fast(con->shared_key, con->sent_nonce, data, length, packet + sizeof(uint16_t));

    if (len != (sizeof(packet) - sizeof(uint16_t)))
        return -1;

    increment_nonce(con->sent_nonce);

    len = send(con->sock, packet, sizeof(packet), 0);

    if (len == sizeof(packet))
        return 1;

    if (len <= 0)
        return 0;

    return -1;
}
예제 #5
0
/* return 0 if data could not be put in packet queue
   return 1 if data was put into the queue */
int write_cryptpacket(int crypt_connection_id, uint8_t *data, uint32_t length)
{
    if (crypt_connection_id < 0 || crypt_connection_id >= MAX_CRYPTO_CONNECTIONS)
        return 0;
    if (length - crypto_box_BOXZEROBYTES + crypto_box_ZEROBYTES > MAX_DATA_SIZE - 1)
        return 0;
    if (crypto_connections[crypt_connection_id].status != CONN_ESTABLISHED)
        return 0;
    uint8_t temp_data[MAX_DATA_SIZE];
    int len = encrypt_data_fast(crypto_connections[crypt_connection_id].shared_key,
                                crypto_connections[crypt_connection_id].sent_nonce, 
                                data, length, temp_data + 1);
    if (len == -1)
        return 0;
    temp_data[0] = 3;
    if (write_packet(crypto_connections[crypt_connection_id].number, temp_data, len + 1) == 0)
        return 0;
    increment_nonce(crypto_connections[crypt_connection_id].sent_nonce);
    return 1;
}
예제 #6
0
/* 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;
}