This commit is contained in:
Frank Denis 2015-10-09 13:21:10 +02:00
parent 80a75040a2
commit 17058b59af

View File

@ -51,17 +51,17 @@ init_nonce(unsigned char *nonce, size_t nonce_size)
time_t now; time_t now;
if (nonce_size < 5) { if (nonce_size < 5) {
return -1; return -1;
} }
time(&now); time(&now);
if (now < MINIMUM_DATE) { if (now < MINIMUM_DATE) {
sleep(SLEEP_WHEN_CLOCK_IS_OFF); sleep(SLEEP_WHEN_CLOCK_IS_OFF);
randombytes_buf(nonce, nonce_size); randombytes_buf(nonce, nonce_size);
} else { } else {
randombytes_buf(nonce + 4, nonce_size - 4); randombytes_buf(nonce + 4, nonce_size - 4);
now <<= 2; now <<= 2;
memcpy(nonce, &now, 3); memcpy(nonce, &now, 3);
nonce[3] = (nonce[3] & 0x3) ^ *(((unsigned char *) &now) + 3); nonce[3] = (nonce[3] & 0x3) ^ *(((unsigned char *) &now) + 3);
} }
return 0; return 0;
} }
@ -72,7 +72,7 @@ alloc_encrypt(struct vtun_host *host)
unsigned char *key; unsigned char *key;
if (sodium_init() < 0) { if (sodium_init() < 0) {
return -1; return -1;
} }
key = sodium_malloc(crypto_aead_KEYBYTES); key = sodium_malloc(crypto_aead_KEYBYTES);
ctx.state = sodium_malloc(sizeof *ctx.state); ctx.state = sodium_malloc(sizeof *ctx.state);
@ -81,15 +81,15 @@ alloc_encrypt(struct vtun_host *host)
ctx.nonce = sodium_malloc(crypto_aead_NPUBBYTES); ctx.nonce = sodium_malloc(crypto_aead_NPUBBYTES);
ctx.previous_decrypted_nonce = sodium_malloc(crypto_aead_NPUBBYTES); ctx.previous_decrypted_nonce = sodium_malloc(crypto_aead_NPUBBYTES);
if (key == NULL || ctx.state == NULL || ctx.message == NULL || if (key == NULL || ctx.state == NULL || ctx.message == NULL ||
ctx.ciphertext == NULL || ctx.ciphertext == NULL || ctx.nonce == NULL || ctx.ciphertext == NULL || ctx.ciphertext == NULL || ctx.nonce == NULL ||
ctx.previous_decrypted_nonce == NULL) { ctx.previous_decrypted_nonce == NULL) {
abort(); abort();
} }
if (init_nonce(ctx.nonce, crypto_aead_NPUBBYTES) != 0) { if (init_nonce(ctx.nonce, crypto_aead_NPUBBYTES) != 0) {
return -1; return -1;
} }
if (derive_key(key, crypto_aead_KEYBYTES, host) != 0) { if (derive_key(key, crypto_aead_KEYBYTES, host) != 0) {
return -1; return -1;
} }
crypto_aead_aes256gcm_aesni_beforenm(ctx.state, key); crypto_aead_aes256gcm_aesni_beforenm(ctx.state, key);
sodium_free(key); sodium_free(key);
@ -114,9 +114,9 @@ is_lower_or_equal(const unsigned char *a, const unsigned char *b, size_t size)
size_t i; size_t i;
for (i = 0U; i < size; i++) { for (i = 0U; i < size; i++) {
if (a[i] > b[i]) { if (a[i] > b[i]) {
return 0; return 0;
} }
} }
return 1; return 1;
} }
@ -129,14 +129,14 @@ encrypt_buf(int message_len_, char *message_, char ** const ciphertext_p)
unsigned long long ciphertext_len; unsigned long long ciphertext_len;
if (message_len_ < 0 || message_len > MESSAGE_MAX_SIZE) { if (message_len_ < 0 || message_len > MESSAGE_MAX_SIZE) {
return -1; return -1;
} }
crypto_aead_aes256gcm_aesni_encrypt_afternm(ctx.ciphertext, &ciphertext_len, crypto_aead_aes256gcm_aesni_encrypt_afternm(ctx.ciphertext, &ciphertext_len,
message, message_len, message, message_len,
NULL, 0ULL, NULL, 0ULL,
NULL, ctx.nonce, ctx.state); NULL, ctx.nonce, ctx.state);
memcpy(ctx.ciphertext + message_len + crypto_aead_ABYTES, memcpy(ctx.ciphertext + message_len + crypto_aead_ABYTES,
ctx.nonce, crypto_aead_NPUBBYTES); ctx.nonce, crypto_aead_NPUBBYTES);
sodium_increment(ctx.nonce, crypto_aead_NPUBBYTES); sodium_increment(ctx.nonce, crypto_aead_NPUBBYTES);
*ciphertext_p = (char *) ctx.ciphertext; *ciphertext_p = (char *) ctx.ciphertext;
@ -152,16 +152,16 @@ decrypt_buf(int ciphertext_len_, char *ciphertext_, char ** const message_p)
unsigned long long message_len; unsigned long long message_len;
if (ciphertext_len_ < CIPHERTEXT_ABYTES || if (ciphertext_len_ < CIPHERTEXT_ABYTES ||
ciphertext_len > CIPHERTEXT_MAX_SIZE) { ciphertext_len > CIPHERTEXT_MAX_SIZE) {
return -1; return -1;
} }
ciphertext_len -= crypto_aead_NPUBBYTES; ciphertext_len -= crypto_aead_NPUBBYTES;
nonce = ciphertext + ciphertext_len; nonce = ciphertext + ciphertext_len;
if (is_lower_or_equal(nonce, ctx.previous_decrypted_nonce, crypto_aead_NPUBBYTES) || if (is_lower_or_equal(nonce, ctx.previous_decrypted_nonce, crypto_aead_NPUBBYTES) ||
crypto_aead_aes256gcm_aesni_decrypt_afternm(ctx.message, &message_len, NULL, crypto_aead_aes256gcm_aesni_decrypt_afternm(ctx.message, &message_len, NULL,
ciphertext, ciphertext_len, ciphertext, ciphertext_len,
NULL, 0ULL, nonce, ctx.state) != 0) { NULL, 0ULL, nonce, ctx.state) != 0) {
return -1; return -1;
} }
memcpy(ctx.previous_decrypted_nonce, nonce, crypto_aead_NPUBBYTES); memcpy(ctx.previous_decrypted_nonce, nonce, crypto_aead_NPUBBYTES);
*message_p = (char *) ctx.message; *message_p = (char *) ctx.message;