Mercurial > dropbear
comparison common-kex.c @ 1672:3a97f14c0235
Add Chacha20-Poly1305, AES128-GCM and AES256-GCM support (#93)
* Add Chacha20-Poly1305 authenticated encryption
* Add general AEAD approach.
* Add [email protected] 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 [email protected] and [email protected] 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
author | Vladislav Grishenko <themiron@users.noreply.github.com> |
---|---|
date | Mon, 25 May 2020 20:50:25 +0500 |
parents | d32bcb5c557d |
children | 41bf8f216644 |
comparison
equal
deleted
inserted
replaced
1671:5c8913b7464c | 1672:3a97f14c0235 |
---|---|
327 hashkeys(S2C_IV, sizeof(S2C_IV), &hs, 'B'); | 327 hashkeys(S2C_IV, sizeof(S2C_IV), &hs, 'B'); |
328 hashkeys(C2S_key, sizeof(C2S_key), &hs, 'C'); | 328 hashkeys(C2S_key, sizeof(C2S_key), &hs, 'C'); |
329 hashkeys(S2C_key, sizeof(S2C_key), &hs, 'D'); | 329 hashkeys(S2C_key, sizeof(S2C_key), &hs, 'D'); |
330 | 330 |
331 if (ses.newkeys->recv.algo_crypt->cipherdesc != NULL) { | 331 if (ses.newkeys->recv.algo_crypt->cipherdesc != NULL) { |
332 int recv_cipher = find_cipher(ses.newkeys->recv.algo_crypt->cipherdesc->name); | 332 int recv_cipher = -1; |
333 if (recv_cipher < 0) | 333 if (ses.newkeys->recv.algo_crypt->cipherdesc->name != NULL) { |
334 dropbear_exit("Crypto error"); | 334 recv_cipher = find_cipher(ses.newkeys->recv.algo_crypt->cipherdesc->name); |
335 if (recv_cipher < 0) | |
336 dropbear_exit("Crypto error"); | |
337 } | |
335 if (ses.newkeys->recv.crypt_mode->start(recv_cipher, | 338 if (ses.newkeys->recv.crypt_mode->start(recv_cipher, |
336 recv_IV, recv_key, | 339 recv_IV, recv_key, |
337 ses.newkeys->recv.algo_crypt->keysize, 0, | 340 ses.newkeys->recv.algo_crypt->keysize, 0, |
338 &ses.newkeys->recv.cipher_state) != CRYPT_OK) { | 341 &ses.newkeys->recv.cipher_state) != CRYPT_OK) { |
339 dropbear_exit("Crypto error"); | 342 dropbear_exit("Crypto error"); |
340 } | 343 } |
341 } | 344 } |
342 | 345 |
343 if (ses.newkeys->trans.algo_crypt->cipherdesc != NULL) { | 346 if (ses.newkeys->trans.algo_crypt->cipherdesc != NULL) { |
344 int trans_cipher = find_cipher(ses.newkeys->trans.algo_crypt->cipherdesc->name); | 347 int trans_cipher = -1; |
345 if (trans_cipher < 0) | 348 if (ses.newkeys->trans.algo_crypt->cipherdesc->name != NULL) { |
346 dropbear_exit("Crypto error"); | 349 trans_cipher = find_cipher(ses.newkeys->trans.algo_crypt->cipherdesc->name); |
350 if (trans_cipher < 0) | |
351 dropbear_exit("Crypto error"); | |
352 } | |
347 if (ses.newkeys->trans.crypt_mode->start(trans_cipher, | 353 if (ses.newkeys->trans.crypt_mode->start(trans_cipher, |
348 trans_IV, trans_key, | 354 trans_IV, trans_key, |
349 ses.newkeys->trans.algo_crypt->keysize, 0, | 355 ses.newkeys->trans.algo_crypt->keysize, 0, |
350 &ses.newkeys->trans.cipher_state) != CRYPT_OK) { | 356 &ses.newkeys->trans.cipher_state) != CRYPT_OK) { |
351 dropbear_exit("Crypto error"); | 357 dropbear_exit("Crypto error"); |
866 } | 872 } |
867 TRACE(("enc s2c is %s", s2c_cipher_algo->name)) | 873 TRACE(("enc s2c is %s", s2c_cipher_algo->name)) |
868 | 874 |
869 /* mac_algorithms_client_to_server */ | 875 /* mac_algorithms_client_to_server */ |
870 c2s_hash_algo = buf_match_algo(ses.payload, sshhashes, NULL, NULL); | 876 c2s_hash_algo = buf_match_algo(ses.payload, sshhashes, NULL, NULL); |
877 #if DROPBEAR_AEAD_MODE | |
878 if (((struct dropbear_cipher_mode*)c2s_cipher_algo->mode)->aead_crypt != NULL) { | |
879 c2s_hash_algo = NULL; | |
880 } else | |
881 #endif | |
871 if (c2s_hash_algo == NULL) { | 882 if (c2s_hash_algo == NULL) { |
872 erralgo = "mac c->s"; | 883 erralgo = "mac c->s"; |
873 goto error; | 884 goto error; |
874 } | 885 } |
875 TRACE(("hash c2s is %s", c2s_hash_algo->name)) | 886 TRACE(("hash c2s is %s", c2s_hash_algo ? c2s_hash_algo->name : "<implicit>")) |
876 | 887 |
877 /* mac_algorithms_server_to_client */ | 888 /* mac_algorithms_server_to_client */ |
878 s2c_hash_algo = buf_match_algo(ses.payload, sshhashes, NULL, NULL); | 889 s2c_hash_algo = buf_match_algo(ses.payload, sshhashes, NULL, NULL); |
890 #if DROPBEAR_AEAD_MODE | |
891 if (((struct dropbear_cipher_mode*)s2c_cipher_algo->mode)->aead_crypt != NULL) { | |
892 s2c_hash_algo = NULL; | |
893 } else | |
894 #endif | |
879 if (s2c_hash_algo == NULL) { | 895 if (s2c_hash_algo == NULL) { |
880 erralgo = "mac s->c"; | 896 erralgo = "mac s->c"; |
881 goto error; | 897 goto error; |
882 } | 898 } |
883 TRACE(("hash s2c is %s", s2c_hash_algo->name)) | 899 TRACE(("hash s2c is %s", s2c_hash_algo ? s2c_hash_algo->name : "<implicit>")) |
884 | 900 |
885 /* compression_algorithms_client_to_server */ | 901 /* compression_algorithms_client_to_server */ |
886 c2s_comp_algo = buf_match_algo(ses.payload, ses.compress_algos, NULL, NULL); | 902 c2s_comp_algo = buf_match_algo(ses.payload, ses.compress_algos, NULL, NULL); |
887 if (c2s_comp_algo == NULL) { | 903 if (c2s_comp_algo == NULL) { |
888 erralgo = "comp c->s"; | 904 erralgo = "comp c->s"; |
923 ses.newkeys->recv.crypt_mode = | 939 ses.newkeys->recv.crypt_mode = |
924 (struct dropbear_cipher_mode*)s2c_cipher_algo->mode; | 940 (struct dropbear_cipher_mode*)s2c_cipher_algo->mode; |
925 ses.newkeys->trans.crypt_mode = | 941 ses.newkeys->trans.crypt_mode = |
926 (struct dropbear_cipher_mode*)c2s_cipher_algo->mode; | 942 (struct dropbear_cipher_mode*)c2s_cipher_algo->mode; |
927 ses.newkeys->recv.algo_mac = | 943 ses.newkeys->recv.algo_mac = |
944 #if DROPBEAR_AEAD_MODE | |
945 s2c_hash_algo == NULL ? ses.newkeys->recv.crypt_mode->aead_mac : | |
946 #endif | |
928 (struct dropbear_hash*)s2c_hash_algo->data; | 947 (struct dropbear_hash*)s2c_hash_algo->data; |
929 ses.newkeys->trans.algo_mac = | 948 ses.newkeys->trans.algo_mac = |
949 #if DROPBEAR_AEAD_MODE | |
950 c2s_hash_algo == NULL ? ses.newkeys->trans.crypt_mode->aead_mac : | |
951 #endif | |
930 (struct dropbear_hash*)c2s_hash_algo->data; | 952 (struct dropbear_hash*)c2s_hash_algo->data; |
931 ses.newkeys->recv.algo_comp = s2c_comp_algo->val; | 953 ses.newkeys->recv.algo_comp = s2c_comp_algo->val; |
932 ses.newkeys->trans.algo_comp = c2s_comp_algo->val; | 954 ses.newkeys->trans.algo_comp = c2s_comp_algo->val; |
933 } else { | 955 } else { |
934 /* SERVER */ | 956 /* SERVER */ |
939 ses.newkeys->recv.crypt_mode = | 961 ses.newkeys->recv.crypt_mode = |
940 (struct dropbear_cipher_mode*)c2s_cipher_algo->mode; | 962 (struct dropbear_cipher_mode*)c2s_cipher_algo->mode; |
941 ses.newkeys->trans.crypt_mode = | 963 ses.newkeys->trans.crypt_mode = |
942 (struct dropbear_cipher_mode*)s2c_cipher_algo->mode; | 964 (struct dropbear_cipher_mode*)s2c_cipher_algo->mode; |
943 ses.newkeys->recv.algo_mac = | 965 ses.newkeys->recv.algo_mac = |
966 #if DROPBEAR_AEAD_MODE | |
967 c2s_hash_algo == NULL ? ses.newkeys->recv.crypt_mode->aead_mac : | |
968 #endif | |
944 (struct dropbear_hash*)c2s_hash_algo->data; | 969 (struct dropbear_hash*)c2s_hash_algo->data; |
945 ses.newkeys->trans.algo_mac = | 970 ses.newkeys->trans.algo_mac = |
971 #if DROPBEAR_AEAD_MODE | |
972 s2c_hash_algo == NULL ? ses.newkeys->trans.crypt_mode->aead_mac : | |
973 #endif | |
946 (struct dropbear_hash*)s2c_hash_algo->data; | 974 (struct dropbear_hash*)s2c_hash_algo->data; |
947 ses.newkeys->recv.algo_comp = c2s_comp_algo->val; | 975 ses.newkeys->recv.algo_comp = c2s_comp_algo->val; |
948 ses.newkeys->trans.algo_comp = s2c_comp_algo->val; | 976 ses.newkeys->trans.algo_comp = s2c_comp_algo->val; |
949 } | 977 } |
950 | 978 |