diff options
author | Vladislav Grishenko <themiron@users.noreply.github.com> | 2020-05-25 20:50:25 +0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-05-25 23:50:25 +0800 |
commit | d3d0d60076dd598f1e7aafbe564ff714cc3c19a9 (patch) | |
tree | 334cf2a95ca2df7f82f746836c1a4c6d5a3a95b2 /common-kex.c | |
parent | 91e537e4275a1e0b265074bc73072cc508e18846 (diff) |
Add Chacha20-Poly1305, AES128-GCM and AES256-GCM support (#93)
* Add Chacha20-Poly1305 authenticated encryption
* Add general AEAD approach.
* Add chacha20-poly1305@openssh.com algo using LibTomCrypt chacha and
poly1305 routines.
Chacha20-Poly1305 is generally faster than AES256 on CPU w/o dedicated
AES instructions, having the same key size.
Compiling in will add ~5,5kB to binary size on x86-64.
function old new delta
chacha_crypt - 1397 +1397
_poly1305_block - 608 +608
poly1305_done - 595 +595
dropbear_chachapoly_crypt - 457 +457
.rodata 26976 27392 +416
poly1305_process - 290 +290
poly1305_init - 221 +221
chacha_setup - 218 +218
encrypt_packet 1068 1270 +202
dropbear_chachapoly_getlength - 147 +147
decrypt_packet 756 897 +141
chacha_ivctr64 - 137 +137
read_packet 543 637 +94
dropbear_chachapoly_start - 94 +94
read_kex_algos 792 880 +88
chacha_keystream - 69 +69
dropbear_mode_chachapoly - 48 +48
sshciphers 280 320 +40
dropbear_mode_none 24 48 +24
dropbear_mode_ctr 24 48 +24
dropbear_mode_cbc 24 48 +24
dropbear_chachapoly_mac - 24 +24
dropbear_chachapoly - 24 +24
gen_new_keys 848 854 +6
------------------------------------------------------------------------------
(add/remove: 14/0 grow/shrink: 10/0 up/down: 5388/0) Total: 5388 bytes
* Add AES128-GCM and AES256-GCM authenticated encryption
* Add general AES-GCM mode.
* Add aes128-gcm@openssh.com and aes256-gcm@openssh.com algo using
LibTomCrypt gcm routines.
AES-GCM is combination of AES CTR mode and GHASH, slower than AES-CTR on
CPU w/o dedicated AES/GHASH instructions therefore disabled by default.
Compiling in will add ~6kB to binary size on x86-64.
function old new delta
gcm_process - 1060 +1060
.rodata 26976 27808 +832
gcm_gf_mult - 820 +820
gcm_add_aad - 660 +660
gcm_shift_table - 512 +512
gcm_done - 471 +471
gcm_add_iv - 384 +384
gcm_init - 347 +347
dropbear_gcm_crypt - 309 +309
encrypt_packet 1068 1270 +202
decrypt_packet 756 897 +141
gcm_reset - 118 +118
read_packet 543 637 +94
read_kex_algos 792 880 +88
sshciphers 280 360 +80
gcm_mult_h - 80 +80
dropbear_gcm_start - 62 +62
dropbear_mode_gcm - 48 +48
dropbear_mode_none 24 48 +24
dropbear_mode_ctr 24 48 +24
dropbear_mode_cbc 24 48 +24
dropbear_ghash - 24 +24
dropbear_gcm_getlength - 24 +24
gen_new_keys 848 854 +6
------------------------------------------------------------------------------
(add/remove: 14/0 grow/shrink: 10/0 up/down: 6434/0) Total: 6434 bytes
Diffstat (limited to 'common-kex.c')
-rw-r--r-- | common-kex.c | 44 |
1 files changed, 36 insertions, 8 deletions
diff --git a/common-kex.c b/common-kex.c index 16b7e27..5e2923f 100644 --- a/common-kex.c +++ b/common-kex.c @@ -329,9 +329,12 @@ static void gen_new_keys() { hashkeys(S2C_key, sizeof(S2C_key), &hs, 'D'); if (ses.newkeys->recv.algo_crypt->cipherdesc != NULL) { - int recv_cipher = find_cipher(ses.newkeys->recv.algo_crypt->cipherdesc->name); - if (recv_cipher < 0) - dropbear_exit("Crypto error"); + int recv_cipher = -1; + if (ses.newkeys->recv.algo_crypt->cipherdesc->name != NULL) { + recv_cipher = find_cipher(ses.newkeys->recv.algo_crypt->cipherdesc->name); + if (recv_cipher < 0) + dropbear_exit("Crypto error"); + } if (ses.newkeys->recv.crypt_mode->start(recv_cipher, recv_IV, recv_key, ses.newkeys->recv.algo_crypt->keysize, 0, @@ -341,9 +344,12 @@ static void gen_new_keys() { } if (ses.newkeys->trans.algo_crypt->cipherdesc != NULL) { - int trans_cipher = find_cipher(ses.newkeys->trans.algo_crypt->cipherdesc->name); - if (trans_cipher < 0) - dropbear_exit("Crypto error"); + int trans_cipher = -1; + if (ses.newkeys->trans.algo_crypt->cipherdesc->name != NULL) { + trans_cipher = find_cipher(ses.newkeys->trans.algo_crypt->cipherdesc->name); + if (trans_cipher < 0) + dropbear_exit("Crypto error"); + } if (ses.newkeys->trans.crypt_mode->start(trans_cipher, trans_IV, trans_key, ses.newkeys->trans.algo_crypt->keysize, 0, @@ -868,19 +874,29 @@ static void read_kex_algos() { /* mac_algorithms_client_to_server */ c2s_hash_algo = buf_match_algo(ses.payload, sshhashes, NULL, NULL); +#if DROPBEAR_AEAD_MODE + if (((struct dropbear_cipher_mode*)c2s_cipher_algo->mode)->aead_crypt != NULL) { + c2s_hash_algo = NULL; + } else +#endif if (c2s_hash_algo == NULL) { erralgo = "mac c->s"; goto error; } - TRACE(("hash c2s is %s", c2s_hash_algo->name)) + TRACE(("hash c2s is %s", c2s_hash_algo ? c2s_hash_algo->name : "<implicit>")) /* mac_algorithms_server_to_client */ s2c_hash_algo = buf_match_algo(ses.payload, sshhashes, NULL, NULL); +#if DROPBEAR_AEAD_MODE + if (((struct dropbear_cipher_mode*)s2c_cipher_algo->mode)->aead_crypt != NULL) { + s2c_hash_algo = NULL; + } else +#endif if (s2c_hash_algo == NULL) { erralgo = "mac s->c"; goto error; } - TRACE(("hash s2c is %s", s2c_hash_algo->name)) + TRACE(("hash s2c is %s", s2c_hash_algo ? s2c_hash_algo->name : "<implicit>")) /* compression_algorithms_client_to_server */ c2s_comp_algo = buf_match_algo(ses.payload, ses.compress_algos, NULL, NULL); @@ -925,8 +941,14 @@ static void read_kex_algos() { ses.newkeys->trans.crypt_mode = (struct dropbear_cipher_mode*)c2s_cipher_algo->mode; ses.newkeys->recv.algo_mac = +#if DROPBEAR_AEAD_MODE + s2c_hash_algo == NULL ? ses.newkeys->recv.crypt_mode->aead_mac : +#endif (struct dropbear_hash*)s2c_hash_algo->data; ses.newkeys->trans.algo_mac = +#if DROPBEAR_AEAD_MODE + c2s_hash_algo == NULL ? ses.newkeys->trans.crypt_mode->aead_mac : +#endif (struct dropbear_hash*)c2s_hash_algo->data; ses.newkeys->recv.algo_comp = s2c_comp_algo->val; ses.newkeys->trans.algo_comp = c2s_comp_algo->val; @@ -941,8 +963,14 @@ static void read_kex_algos() { ses.newkeys->trans.crypt_mode = (struct dropbear_cipher_mode*)s2c_cipher_algo->mode; ses.newkeys->recv.algo_mac = +#if DROPBEAR_AEAD_MODE + c2s_hash_algo == NULL ? ses.newkeys->recv.crypt_mode->aead_mac : +#endif (struct dropbear_hash*)c2s_hash_algo->data; ses.newkeys->trans.algo_mac = +#if DROPBEAR_AEAD_MODE + s2c_hash_algo == NULL ? ses.newkeys->trans.crypt_mode->aead_mac : +#endif (struct dropbear_hash*)s2c_hash_algo->data; ses.newkeys->recv.algo_comp = c2s_comp_algo->val; ses.newkeys->trans.algo_comp = s2c_comp_algo->val; |