From cc6df1e3408ceec0d6507952a1a219e661afd9f2 Mon Sep 17 00:00:00 2001 From: hidnplayr Date: Sat, 9 Mar 2024 20:05:21 +0000 Subject: [PATCH] Added support for encrypt-then-mac modes (hmac-sha2-256-etm,hmac-sha2-512-etm) git-svn-id: svn://kolibrios.org@9990 a494cfbc-eb01-0410-851d-a64ba20cac60 --- programs/network/ssh/ssh.asm | 113 ++++++--- programs/network/ssh/sshlib.inc | 41 ++-- programs/network/ssh/sshlib_connection.inc | 204 +++++++++++++--- programs/network/ssh/sshlib_dh_gex.inc | 54 ++--- programs/network/ssh/sshlib_host.inc | 18 +- programs/network/ssh/sshlib_transport.inc | 2 +- .../network/ssh/sshlib_transport_hmac_etm.inc | 224 ++++++++++++++++++ .../ssh/sshlib_transport_polychacha.inc | 16 +- 8 files changed, 536 insertions(+), 136 deletions(-) create mode 100755 programs/network/ssh/sshlib_transport_hmac_etm.inc diff --git a/programs/network/ssh/ssh.asm b/programs/network/ssh/ssh.asm index e339247da8..2e5d8059d8 100644 --- a/programs/network/ssh/ssh.asm +++ b/programs/network/ssh/ssh.asm @@ -109,6 +109,7 @@ include 'sshlib.inc' include 'sshlib_mcodes.inc' include 'sshlib_transport.inc' include 'sshlib_transport_hmac.inc' +include 'sshlib_transport_hmac_etm.inc' include 'sshlib_transport_polychacha.inc' include 'sshlib_connection.inc' include 'sshlib_dh_gex.inc' @@ -477,7 +478,7 @@ str24b db 10, 10, "If you trust this host, press A to accept and store the (new ssh_ident_ha: dd_n (ssh_msg_ident.length-2) ssh_msg_ident: - db "SSH-2.0-KolibriOS_SSH_0.10",13,10 + db "SSH-2.0-KolibriOS_SSH_0.11",13,10 .length = $ - ssh_msg_ident @@ -486,21 +487,21 @@ ssh_msg_kex: .cookie: rd 4 .kex_algorithms: - str "diffie-hellman-group-exchange-sha256" ; diffie-hellman-group-exchange-sha1 + str "diffie-hellman-group-exchange-sha256" .server_host_key_algorithms: - str "rsa-sha2-512,rsa-sha2-256,ssh-rsa" ;,ssh-dss + str "rsa-sha2-512,rsa-sha2-256" ;ssh-rsa,ssh-dss .encryption_algorithms_client_to_server: - str "chacha20-poly1305@openssh.com" ;aes256-ctr,aes256-cbc,aes256-cbc,rijndael-cbc@lysator.liu.se,aes192-ctr,aes192-cbc,aes128-ctr,aes128-cbc,blowfish-ctr,blowfish-cbc,3des-ctr,3des-cbc,arcfour256,arcfour128" + str "aes256-ctr";,aes256-cbc,chacha20-poly1305@openssh.com" ;aes192-ctr,aes192-cbc,aes128-ctr,aes128-cbc ? .encryption_algorithms_server_to_client: - str "chacha20-poly1305@openssh.com" ;aes256-ctr,aes256-cbc,aes256-cbc,rijndael-cbc@lysator.liu.se,aes192-ctr,aes192-cbc,aes128-ctr,aes128-cbc,blowfish-ctr,blowfish-cbc,3des-ctr,3des-cbc,arcfour256,arcfour128" + str "aes256-ctr";,aes256-cbc,chacha20-poly1305@openssh.com" ;aes192-ctr,aes192-cbc,aes128-ctr,aes128-cbc ? .mac_algorithms_client_to_server: - str "hmac-sha2-256" ;,hmac-sha1,hmac-sha1-96,hmac-md5" + str "hmac-sha2-256-etm@openssh.com";,hmac-sha2-512-etm@openssh.com,hmac-sha2-256,hmac-sha2-512" .mac_algorithms_server_to_client: - str "hmac-sha2-256" ;,hmac-sha1,hmac-sha1-96,hmac-md5" + str "hmac-sha2-256-etm@openssh.com";,hmac-sha2-512-etm@openssh.com,hmac-sha2-256,hmac-sha2-512" .compression_algorithms_client_to_server: - str "none" ;,zlib" + str "none" ;zlib ? .compression_algorithms_server_to_client: - str "none" ;,zlib" + str "none" ;zlib ? .languages_client_to_server: str "" .languages_server_to_client: @@ -611,30 +612,84 @@ import console, \ con_get_input, 'con_get_input' import libcrash, \ - sha2_512_init, 'sha2_512_init', \ - sha2_512_update, 'sha2_512_update', \ - sha2_512_finish, 'sha2_512_finish',\ - sha2_256_init, 'sha2_256_init', \ - sha2_256_update, 'sha2_256_update', \ - sha2_256_finish, 'sha2_256_finish',\ - sha1_init, 'sha1_init', \ - sha1_update, 'sha1_update', \ - sha1_finish, 'sha1_finish', \ - chacha20_init, 'chacha20_init' , \ - chacha20_update, 'chacha20_update', \ - chacha20_oneshot, 'chacha20_oneshot', \ - poly1305_init, 'poly1305_init', \ - poly1305_update, 'poly1305_update', \ - poly1305_finish, 'poly1305_finish', \ - poly1305_oneshot, 'poly1305_oneshot', \ + crash.init, "lib_init", \ + crash.hash, "crash_hash", \ + crash.mac, "crash_mac", \ + crash.crypt, "crash_crypt", \ + crash.hash_oneshot, "crash_hash_oneshot", \ + crash.mac_oneshot, "crash_mac_oneshot", \ + crash.crypt_oneshot, "crash_crypt_oneshot", \ + \ + crc32.init, "crc32_init", \ + crc32.update, "crc32_update", \ + crc32.finish, "crc32_finish", \ + crc32.oneshot, "crc32_oneshot", \ + md5.init, "md5_init", \ + md5.update, "md5_update", \ + md5.finish, "md5_finish", \ + md5.oneshot, "md5_oneshot", \ + sha1.init, "sha1_init", \ + sha1.update, "sha1_update", \ + sha1.finish, "sha1_finish", \ + sha1.oneshot, "sha1_oneshot", \ + sha2_224.init, "sha2_224_init", \ + sha2_224.update, "sha2_224_update", \ + sha2_224.finish, "sha2_224_finish", \ + sha2_224.oneshot, "sha2_224_oneshot", \ + sha2_256.init, "sha2_256_init", \ + sha2_256.update, "sha2_256_update", \ + sha2_256.finish, "sha2_256_finish", \ + sha2_256.oneshot, "sha2_256_oneshot", \ + sha2_384.init, "sha2_384_init", \ + sha2_384.update, "sha2_384_update", \ + sha2_384.finish, "sha2_384_finish", \ + sha2_384.oneshot, "sha2_384_oneshot", \ + sha2_512.init, "sha2_512_init", \ + sha2_512.update, "sha2_512_update", \ + sha2_512.finish, "sha2_512_finish", \ + sha2_512.oneshot, "sha2_512_oneshot", \ + sha3_224.init, "sha3_224_init", \ + sha3_224.update, "sha3_224_update", \ + sha3_224.finish, "sha3_224_finish", \ + sha3_224.oneshot, "sha3_224_oneshot", \ + sha3_256.init, "sha3_256_init", \ + sha3_256.update, "sha3_256_update", \ + sha3_256.finish, "sha3_256_finish", \ + sha3_256.oneshot, "sha3_256_oneshot", \ + sha3_384.init, "sha3_384_init", \ + sha3_384.update, "sha3_384_update", \ + sha3_384.finish, "sha3_384_finish", \ + sha3_384.oneshot, "sha3_384_oneshot", \ + sha3_512.init, "sha3_512_init", \ + sha3_512.update, "sha3_512_update", \ + sha3_512.finish, "sha3_512_finish", \ + sha3_512.oneshot, "sha3_512_oneshot", \ + \ + poly1305.init, "poly1305_init", \ + poly1305.update, "poly1305_update", \ + poly1305.finish, "poly1305_finish", \ + poly1305.oneshot, "poly1305_oneshot", \ + hmac_sha2_256.init, "hmac_sha2_256_init", \ + hmac_sha2_256.update, "hmac_sha2_256_update", \ + hmac_sha2_256.finish, "hmac_sha2_256_finish", \ + hmac_sha2_256.oneshot, "hmac_sha2_256_oneshot", \ + hmac_sha2_512.init, "hmac_sha2_512_init", \ + hmac_sha2_512.update, "hmac_sha2_512_update", \ + hmac_sha2_512.finish, "hmac_sha2_512_finish", \ + hmac_sha2_512.oneshot, "hmac_sha2_512_oneshot", \ + \ + chacha20.init, "chacha20_init", \ + chacha20.update, "chacha20_update", \ + chacha20.finish, "chacha20_finish", \ + chacha20.oneshot, "chacha20_oneshot", \ aes256ctr.init, "aes256ctr_init", \ aes256ctr.update, "aes256ctr_update", \ aes256ctr.finish, "aes256ctr_finish", \ aes256ctr.oneshot, "aes256ctr_oneshot", \ - hmac_sha2_256.init_, "hmac_sha2_256_init", \ - hmac_sha2_256.update_, "hmac_sha2_256_update", \ - hmac_sha2_256.finish_, "hmac_sha2_256_finish", \ - hmac_sha2_256.oneshot, "hmac_sha2_256_oneshot" + aes256cbc.init, "aes256cbc_init", \ + aes256cbc.update, "aes256cbc_update", \ + aes256cbc.finish, "aes256cbc_finish", \ + aes256cbc.oneshot, "aes256cbc_oneshot" import libini, \ ini_get_str, 'ini_get_str', \ diff --git a/programs/network/ssh/sshlib.inc b/programs/network/ssh/sshlib.inc index 9466666015..69e60f9732 100644 --- a/programs/network/ssh/sshlib.inc +++ b/programs/network/ssh/sshlib.inc @@ -46,31 +46,27 @@ SSHLIB_CON_STAT_KEX_DONE = 1 SSHLIB_ALGO_NONE = 0 -SSHLIB_KEX_DH_SHA1 = 1 -SSHLIB_KEX_DH_SHA256 = 2 +SSHLIB_KEX_DH_SHA256 = 1 ; diffie-hellman-group-exchange-sha256 -SSHLIB_HOSTKEY_DSS = 1 -SSHLIB_HOSTKEY_RSA = 2 -SSHLIB_HOSTKEY_RSA_SHA2_256 = 3 -SSHLIB_HOSTKEY_RSA_SHA2_512 = 4 +SSHLIB_HOSTKEY_DSS = 1 ; ssh-dss +SSHLIB_HOSTKEY_RSA = 2 ; ssh-rsa +SSHLIB_HOSTKEY_RSA_SHA2_256 = 3 ; rsa-sha2-256 +SSHLIB_HOSTKEY_RSA_SHA2_512 = 4 ; rsa-sha2-512 -;SSHLIB_CRYPT_BLOWFISH_CTR = 1 ; blowfish-ctr -;SSHLIB_CRYPT_BLOWFISH_CBC = 2 ; blowfish-cbc -;SSHLIB_CRYPT_AES128_CTR = 3 ; aes128-ctr -;SSHLIB_CRYPT_AES128_CBC = 4 ; aes128-cbc -;SSHLIB_CRYPT_AES192_CTR = 5 ; aes192-cbc -;SSHLIB_CRYPT_AES192_CBC = 6 ; aes192-ctr -SSHLIB_CRYPT_AES256_CTR = 7 ; aes256-ctr -SSHLIB_CRYPT_AES256_CBC = 8 ; aes256-cbc -SSHLIB_CRYPT_CHACHA20_POLY1305 = 9 ; chacha20-poly1305@openssh.com" +SSHLIB_CRYPT_AES128_CTR = 1 ; aes128-ctr +SSHLIB_CRYPT_AES128_CBC = 2 ; aes128-cbc +SSHLIB_CRYPT_AES192_CTR = 3 ; aes192-cbc +SSHLIB_CRYPT_AES192_CBC = 4 ; aes192-ctr +SSHLIB_CRYPT_AES256_CTR = 5 ; aes256-ctr +SSHLIB_CRYPT_AES256_CBC = 6 ; aes256-cbc +SSHLIB_CRYPT_CHACHA20_POLY1305 = 7 ; chacha20-poly1305@openssh.com -;SSHLIB_HMAC_MD5 = 1 ; hmac-md5 -;SSHLIB_HMAC_SHA1 = 2 ; hmac-sha1 -;SSHLIB_HMAC_SHA1_96 = 3 ; hmac-sha1-96 -SSHLIB_HMAC_SHA2_256 = 4 ; hmac-sha2-256 +SSHLIB_HMAC_SHA2_256 = 1 ; hmac-sha2-256 +SSHLIB_HMAC_SHA2_512 = 2 ; hmac-sha2-512 +SSHLIB_HMAC_SHA2_256_ETM = 3 ; hmac-sha2-256-etm@openssh.com +SSHLIB_HMAC_SHA2_512_ETM = 4 ; hmac-sha2-512-etm@openssh.com -SSHLIB_COMPR_NONE = 1 -SSHLIB_COMPR_ZLIB = 2 +SSHLIB_COMPR_ZLIB = 1 ; zlib ; Hostkey @@ -111,8 +107,7 @@ struct sshlib_connection rx_crypt_proc dd ? tx_crypt_proc dd ? -; rx_crypt_ctx_ptr dd ? -; tx_crypt_ctx_ptr dd ? + rx_crypt_blocksize dd ? tx_crypt_blocksize dd ? diff --git a/programs/network/ssh/sshlib_connection.inc b/programs/network/ssh/sshlib_connection.inc index 2bacdba4ec..102bbdd90c 100644 --- a/programs/network/ssh/sshlib_connection.inc +++ b/programs/network/ssh/sshlib_connection.inc @@ -111,9 +111,9 @@ endl jnz .err_sock ; Start calculating hash - invoke sha2_256_init, [ctx_ptr] + invoke sha2_256.init, [ctx_ptr] ; HASH: string V_C, the client's version string (CR and NL excluded) - invoke sha2_256_update, [ctx_ptr], ssh_ident_ha, ssh_msg_ident.length+4-2 + invoke sha2_256.update, [ctx_ptr], ssh_ident_ha, ssh_msg_ident.length+4-2 ; >> Send our identification string DEBUGF 2, "Sending ID string\n" @@ -140,7 +140,7 @@ endl bswap eax sub edx, 4 mov dword[edx], eax - invoke sha2_256_update, [ctx_ptr], edx, ecx + invoke sha2_256.update, [ctx_ptr], edx, ecx ; >> Key Exchange init mov eax, [con_ptr] @@ -195,7 +195,7 @@ endl bswap eax lea esi, [esi+sshlib_connection.tx_buffer+1] mov dword[esi], eax - invoke sha2_256_update, [ctx_ptr], esi, edx + invoke sha2_256.update, [ctx_ptr], esi, edx ; << Check key exchange init of server stdcall sshlib_recv_packet, [con_ptr], 0 @@ -257,11 +257,11 @@ endl mov [esi+sshlib_connection.algo_kex], SSHLIB_KEX_DH_SHA256 mov [esi+sshlib_connection.algo_hostkey], SSHLIB_HOSTKEY_RSA mov [esi+sshlib_connection.algo_crypt_rx], SSHLIB_CRYPT_AES256_CTR - mov [esi+sshlib_connection.algo_crypt_tx], SSHLIB_CRYPT_AES256_CTR - mov [esi+sshlib_connection.algo_mac_rx], SSHLIB_HMAC_SHA2_256 - mov [esi+sshlib_connection.algo_mac_tx], SSHLIB_HMAC_SHA2_256 - mov [esi+sshlib_connection.algo_compr_rx], SSHLIB_COMPR_NONE - mov [esi+sshlib_connection.algo_compr_tx], SSHLIB_COMPR_NONE + mov [esi+sshlib_connection.algo_crypt_tx], SSHLIB_CRYPT_AES256_CTR ; SSHLIB_CRYPT_CHACHA20_POLY1305 + mov [esi+sshlib_connection.algo_mac_rx], SSHLIB_HMAC_SHA2_256_ETM + mov [esi+sshlib_connection.algo_mac_tx], SSHLIB_HMAC_SHA2_256_ETM + mov [esi+sshlib_connection.algo_compr_rx], SSHLIB_ALGO_NONE + mov [esi+sshlib_connection.algo_compr_tx], SSHLIB_ALGO_NONE ; HASH: string I_S, the payload of the servers's SSH_MSG_KEXINIT mov esi, [con_ptr] @@ -273,7 +273,7 @@ endl bswap eax lea esi, [esi+sshlib_connection.rx_buffer+1] mov dword[esi], eax - invoke sha2_256_update, [ctx_ptr], esi, edx + invoke sha2_256.update, [ctx_ptr], esi, edx ; Exchange keys with the server @@ -287,38 +287,164 @@ endl mov ebx, [con_ptr] -; lea ecx, [ebx + sshlib_connection.rx_crypt_ctx] -; lea edx, [ebx + sshlib_connection.rx_enc_key] -; lea esi, [ebx + sshlib_connection.rx_iv] -; invoke aes256ctr.init, ecx, edx, esi, 0 -; -; push [aes256ctr.update] -; pop [ebx + sshlib_connection.rx_crypt_proc] -; mov [ebx + sshlib_connection.rx_crypt_blocksize], 16 ; AES_BLOCKSIZE -; -; push [hmac_sha2_256.oneshot] -; pop [ebx + sshlib_connection.rx_mac_proc] -; mov [ebx + sshlib_connection.rx_mac_length], SHA2_256_LEN -; -; lea ecx, [ebx + sshlib_connection.tx_crypt_ctx] -; lea edx, [ebx + sshlib_connection.tx_enc_key] -; lea esi, [ebx + sshlib_connection.tx_iv] -; invoke aes256ctr.init, ecx, edx, esi, 0 -; -; push [aes256ctr.update] -; pop [ebx + sshlib_connection.tx_crypt_proc] -; mov [ebx + sshlib_connection.tx_crypt_blocksize], 16 ; AES_BLOCKSIZE -; mov [ebx + sshlib_connection.tx_pad_size], 16 ; AES_BLOCKSIZE -; -; push [hmac_sha2_256.oneshot] -; pop [ebx + sshlib_connection.tx_mac_proc] -; mov [ebx + sshlib_connection.tx_mac_length], SHA2_256_LEN -; -; mov [ebx + sshlib_connection.rx_proc], sshlib_recv_packet_hmac -; mov [ebx + sshlib_connection.tx_proc], sshlib_send_packet_hmac + cmp [ebx + sshlib_connection.algo_crypt_rx], SSHLIB_CRYPT_AES256_CTR + je .rx_crypt_aes256_ctr + cmp [ebx + sshlib_connection.algo_crypt_rx], SSHLIB_CRYPT_AES256_CBC + je .rx_crypt_aes256_cbc + cmp [ebx + sshlib_connection.algo_crypt_rx], SSHLIB_CRYPT_CHACHA20_POLY1305 + je .rx_crypt_poly1305_chacha20 + jmp .err_proto + + .rx_crypt_aes256_ctr: + lea ecx, [ebx + sshlib_connection.rx_crypt_ctx] + lea edx, [ebx + sshlib_connection.rx_enc_key] + lea esi, [ebx + sshlib_connection.rx_iv] + invoke aes256ctr.init, ecx, edx, esi, 0 + push [aes256ctr.update] + pop [ebx + sshlib_connection.rx_crypt_proc] + mov [ebx + sshlib_connection.rx_crypt_blocksize], 16 ; AES_BLOCKSIZE + jmp .have_rx_crypt + + .rx_crypt_aes256_cbc: + lea ecx, [ebx + sshlib_connection.rx_crypt_ctx] + lea edx, [ebx + sshlib_connection.rx_enc_key] + lea esi, [ebx + sshlib_connection.rx_iv] + invoke aes256cbc.init, ecx, edx, esi, 0 + push [aes256cbc.update] + pop [ebx + sshlib_connection.rx_crypt_proc] + mov [ebx + sshlib_connection.rx_crypt_blocksize], 16 ; AES_BLOCKSIZE + jmp .have_rx_crypt + + .rx_crypt_poly1305_chacha20: mov [ebx + sshlib_connection.rx_proc], sshlib_recv_packet_poly1305chacha20 + jmp .have_rx_crypt_and_mac + + + + .have_rx_crypt: + cmp [ebx + sshlib_connection.algo_mac_rx], SSHLIB_HMAC_SHA2_256 + je .rx_hmac_sha2_256 + cmp [ebx + sshlib_connection.algo_mac_rx], SSHLIB_HMAC_SHA2_512 + je .rx_hmac_sha2_512 + cmp [ebx + sshlib_connection.algo_mac_rx], SSHLIB_HMAC_SHA2_256_ETM + je .rx_hmac_sha2_256_etm + cmp [ebx + sshlib_connection.algo_mac_rx], SSHLIB_HMAC_SHA2_512_ETM + je .rx_hmac_sha2_512_etm + + jmp .err_proto + + .rx_hmac_sha2_256: + push [hmac_sha2_256.oneshot] + pop [ebx + sshlib_connection.rx_mac_proc] + mov [ebx + sshlib_connection.rx_mac_length], SHA2_256_LEN + mov [ebx + sshlib_connection.rx_proc], sshlib_recv_packet_hmac + jmp .have_rx_crypt_and_mac + + .rx_hmac_sha2_512: + push [hmac_sha2_512.oneshot] + pop [ebx + sshlib_connection.rx_mac_proc] + mov [ebx + sshlib_connection.rx_mac_length], SHA2_512_LEN + mov [ebx + sshlib_connection.rx_proc], sshlib_recv_packet_hmac + jmp .have_rx_crypt_and_mac + + .rx_hmac_sha2_256_etm: + push [hmac_sha2_256.oneshot] + pop [ebx + sshlib_connection.rx_mac_proc] + mov [ebx + sshlib_connection.rx_mac_length], SHA2_256_LEN + mov [ebx + sshlib_connection.rx_proc], sshlib_recv_packet_hmac_etm + jmp .have_rx_crypt_and_mac + + .rx_hmac_sha2_512_etm: + push [hmac_sha2_512.oneshot] + pop [ebx + sshlib_connection.rx_mac_proc] + mov [ebx + sshlib_connection.rx_mac_length], SHA2_512_LEN + mov [ebx + sshlib_connection.rx_proc], sshlib_recv_packet_hmac_etm + jmp .have_rx_crypt_and_mac + + + .have_rx_crypt_and_mac: + + cmp [ebx + sshlib_connection.algo_crypt_tx], SSHLIB_CRYPT_AES256_CTR + je .tx_crypt_aes256_ctr + cmp [ebx + sshlib_connection.algo_crypt_tx], SSHLIB_CRYPT_AES256_CBC + je .tx_crypt_aes256_cbc + cmp [ebx + sshlib_connection.algo_crypt_tx], SSHLIB_CRYPT_CHACHA20_POLY1305 + je .tx_crypt_poly1305_chacha20 + + jmp .err_proto + + .tx_crypt_aes256_ctr: + lea ecx, [ebx + sshlib_connection.tx_crypt_ctx] + lea edx, [ebx + sshlib_connection.tx_enc_key] + lea esi, [ebx + sshlib_connection.tx_iv] + invoke aes256ctr.init, ecx, edx, esi, 0 + push [aes256ctr.update] + pop [ebx + sshlib_connection.tx_crypt_proc] + mov [ebx + sshlib_connection.tx_crypt_blocksize], 16 ; AES_BLOCKSIZE + mov [ebx + sshlib_connection.tx_pad_size], 16 ; AES_BLOCKSIZE + jmp .have_tx_crypt + + .tx_crypt_aes256_cbc: + lea ecx, [ebx + sshlib_connection.tx_crypt_ctx] + lea edx, [ebx + sshlib_connection.tx_enc_key] + lea esi, [ebx + sshlib_connection.tx_iv] + invoke aes256cbc.init, ecx, edx, esi, 0 + push [aes256cbc.update] + pop [ebx + sshlib_connection.tx_crypt_proc] + mov [ebx + sshlib_connection.tx_crypt_blocksize], 16 ; AES_BLOCKSIZE + mov [ebx + sshlib_connection.tx_pad_size], 16 ; AES_BLOCKSIZE + jmp .have_tx_crypt + + .tx_crypt_poly1305_chacha20: mov [ebx + sshlib_connection.tx_proc], sshlib_send_packet_poly1305chacha20 + jmp .have_tx_crypt_and_mac + + + + .have_tx_crypt: + cmp [ebx + sshlib_connection.algo_mac_tx], SSHLIB_HMAC_SHA2_256 + je .tx_hmac_sha2_256 + cmp [ebx + sshlib_connection.algo_mac_tx], SSHLIB_HMAC_SHA2_512 + je .tx_hmac_sha2_512 + cmp [ebx + sshlib_connection.algo_mac_tx], SSHLIB_HMAC_SHA2_256_ETM + je .tx_hmac_sha2_256_etm + cmp [ebx + sshlib_connection.algo_mac_tx], SSHLIB_HMAC_SHA2_512_ETM + je .tx_hmac_sha2_512_etm + + jmp .err_proto + + .tx_hmac_sha2_256: + push [hmac_sha2_256.oneshot] + pop [ebx + sshlib_connection.tx_mac_proc] + mov [ebx + sshlib_connection.tx_mac_length], SHA2_256_LEN + mov [ebx + sshlib_connection.tx_proc], sshlib_send_packet_hmac + jmp .have_tx_crypt_and_mac + + .tx_hmac_sha2_512: + push [hmac_sha2_512.oneshot] + pop [ebx + sshlib_connection.tx_mac_proc] + mov [ebx + sshlib_connection.tx_mac_length], SHA2_512_LEN + mov [ebx + sshlib_connection.tx_proc], sshlib_send_packet_hmac + jmp .have_tx_crypt_and_mac + + .tx_hmac_sha2_256_etm: + push [hmac_sha2_256.oneshot] + pop [ebx + sshlib_connection.tx_mac_proc] + mov [ebx + sshlib_connection.tx_mac_length], SHA2_256_LEN + mov [ebx + sshlib_connection.tx_proc], sshlib_send_packet_hmac_etm + jmp .have_tx_crypt_and_mac + + .tx_hmac_sha2_512_etm: + push [hmac_sha2_512.oneshot] + pop [ebx + sshlib_connection.tx_mac_proc] + mov [ebx + sshlib_connection.tx_mac_length], SHA2_512_LEN + mov [ebx + sshlib_connection.tx_proc], sshlib_send_packet_hmac_etm + jmp .have_tx_crypt_and_mac + + + .have_tx_crypt_and_mac: + ; Re-seed RNG for padding bytes diff --git a/programs/network/ssh/sshlib_dh_gex.inc b/programs/network/ssh/sshlib_dh_gex.inc index 4fb0a27619..3798bb172a 100644 --- a/programs/network/ssh/sshlib_dh_gex.inc +++ b/programs/network/ssh/sshlib_dh_gex.inc @@ -181,27 +181,27 @@ endl add edx, 4 lea eax, [esi+edx] mov [mpint_f_big], eax - invoke sha2_256_update, [temp_ctx], esi, edx + invoke sha2_256.update, [temp_ctx], esi, edx ;-------------------------------------------------------------------------- ; HASH: uint32 min, minimal size in bits of an acceptable group ; uint32 n, preferred size in bits of the group the server will send ; uint32 max, maximal size in bits of an acceptable group - invoke sha2_256_update, [temp_ctx], ssh_msg_gex_req+sizeof.ssh_packet_header-ssh_packet_header.message_code, 12 + invoke sha2_256.update, [temp_ctx], ssh_msg_gex_req+sizeof.ssh_packet_header-ssh_packet_header.message_code, 12 ;---------------------------- ; HASH: mpint p, safe prime stdcall mpint_shrink, [mpint_p] stdcall mpint_to_big_endian, [mpint_tmp], [mpint_p] add eax, 4 - invoke sha2_256_update, [temp_ctx], [mpint_tmp], eax + invoke sha2_256.update, [temp_ctx], [mpint_tmp], eax ;---------------------------------------- ; HASH: mpint g, generator for subgroup stdcall mpint_shrink, [mpint_g] stdcall mpint_to_big_endian, [mpint_tmp], [mpint_g] add eax, 4 - invoke sha2_256_update, [temp_ctx], [mpint_tmp], eax + invoke sha2_256.update, [temp_ctx], [mpint_tmp], eax ;--------------------------------------------------- ; HASH: mpint e, exchange value sent by the client @@ -210,7 +210,7 @@ endl mov edx, [esi] bswap edx add edx, 4 - invoke sha2_256_update, [temp_ctx], esi, edx + invoke sha2_256.update, [temp_ctx], esi, edx ;--------------------------------------------------- ; HASH: mpint f, exchange value sent by the server @@ -218,7 +218,7 @@ endl mov edx, [esi] bswap edx add edx, 4 - invoke sha2_256_update, [temp_ctx], esi, edx + invoke sha2_256.update, [temp_ctx], esi, edx stdcall mpint_to_little_endian, [mpint_f], [mpint_f_big] mov esi, [mpint_f_big] @@ -240,11 +240,11 @@ endl ;----------------------------------- ; HASH: mpint K, the shared secret add eax, 4 - invoke sha2_256_update, [temp_ctx], [mpint_K_big], eax + invoke sha2_256.update, [temp_ctx], [mpint_K_big], eax ;------------------------------- ; Finalize the exchange hash (H) - invoke sha2_256_finish, [temp_ctx] + invoke sha2_256.finish, [temp_ctx] mov esi, [temp_ctx] mov edi, [H] mov ecx, SHA2_256_LEN/4 @@ -302,12 +302,12 @@ endl ; First, calculate partial hash of K and H so we can re-use it for every key. - invoke sha2_256_init, [k_h_ctx] + invoke sha2_256.init, [k_h_ctx] mov ecx, [K_length] add ecx, 4 - invoke sha2_256_update, [k_h_ctx], [mpint_K_big], ecx - invoke sha2_256_update, [k_h_ctx], [H], SHA2_256_LEN + invoke sha2_256.update, [k_h_ctx], [mpint_K_big], ecx + invoke sha2_256.update, [k_h_ctx], [H], SHA2_256_LEN ;--------------------------------------------------------------- ; Initial IV client to server: HASH(K || H || "A" || session_id) @@ -318,8 +318,8 @@ endl rep movsd lea edx, [session_id_x] mov byte[edx], 'A' - invoke sha2_256_update, [temp_ctx], edx, SHA2_256_LEN+1 - invoke sha2_256_finish, [temp_ctx] + invoke sha2_256.update, [temp_ctx], edx, SHA2_256_LEN+1 + invoke sha2_256.finish, [temp_ctx] mov ebx, [con_ptr] lea edi, [ebx + sshlib_connection.tx_iv] mov esi, [temp_ctx] @@ -335,8 +335,8 @@ endl rep movsd lea edx, [session_id_x] mov byte[edx], 'B' - invoke sha2_256_update, [temp_ctx], edx, SHA2_256_LEN+1 - invoke sha2_256_finish, [temp_ctx] + invoke sha2_256.update, [temp_ctx], edx, SHA2_256_LEN+1 + invoke sha2_256.finish, [temp_ctx] mov ebx, [con_ptr] lea edi, [ebx + sshlib_connection.rx_iv] mov esi, [temp_ctx] @@ -352,8 +352,8 @@ endl rep movsd lea edx, [session_id_x] mov byte[edx], 'C' - invoke sha2_256_update, [temp_ctx], edx, SHA2_256_LEN+1 - invoke sha2_256_finish, [temp_ctx] + invoke sha2_256.update, [temp_ctx], edx, SHA2_256_LEN+1 + invoke sha2_256.finish, [temp_ctx] mov ebx, [con_ptr] lea edi, [ebx+sshlib_connection.tx_enc_key] @@ -367,8 +367,8 @@ endl rep movsd mov ebx, [con_ptr] lea edi, [ebx+sshlib_connection.tx_enc_key] - invoke sha2_256_update, [temp_ctx], edi, SHA2_256_LEN - invoke sha2_256_finish, [temp_ctx] + invoke sha2_256.update, [temp_ctx], edi, SHA2_256_LEN + invoke sha2_256.finish, [temp_ctx] mov ebx, [con_ptr] add edi, 256/8 @@ -385,8 +385,8 @@ endl rep movsd lea edx, [session_id_x] mov byte[edx], 'D' - invoke sha2_256_update, [temp_ctx], edx, SHA2_256_LEN+1 - invoke sha2_256_finish, [temp_ctx] + invoke sha2_256.update, [temp_ctx], edx, SHA2_256_LEN+1 + invoke sha2_256.finish, [temp_ctx] mov ebx, [con_ptr] lea edi, [ebx+sshlib_connection.rx_enc_key] @@ -400,8 +400,8 @@ endl rep movsd mov ebx, [con_ptr] lea edi, [ebx+sshlib_connection.rx_enc_key] - invoke sha2_256_update, [temp_ctx], edi, SHA2_256_LEN - invoke sha2_256_finish, [temp_ctx] + invoke sha2_256.update, [temp_ctx], edi, SHA2_256_LEN + invoke sha2_256.finish, [temp_ctx] mov ebx, [con_ptr] add edi, 256/8 @@ -418,8 +418,8 @@ endl rep movsd lea edx, [session_id_x] mov byte[edx], 'E' - invoke sha2_256_update, [temp_ctx], edx, SHA2_256_LEN+1 - invoke sha2_256_finish, [temp_ctx] + invoke sha2_256.update, [temp_ctx], edx, SHA2_256_LEN+1 + invoke sha2_256.finish, [temp_ctx] mov ebx, [con_ptr] lea edi, [ebx + sshlib_connection.tx_int_key] mov esi, [temp_ctx] @@ -435,8 +435,8 @@ endl rep movsd lea edx, [session_id_x] mov byte[edx], 'F' - invoke sha2_256_update, [temp_ctx], edx, SHA2_256_LEN+1 - invoke sha2_256_finish, [temp_ctx] + invoke sha2_256.update, [temp_ctx], edx, SHA2_256_LEN+1 + invoke sha2_256.finish, [temp_ctx] mov ebx, [con_ptr] lea edi, [ebx + sshlib_connection.rx_int_key] mov esi, [temp_ctx] diff --git a/programs/network/ssh/sshlib_host.inc b/programs/network/ssh/sshlib_host.inc index 151eaadfa7..51a4883f00 100644 --- a/programs/network/ssh/sshlib_host.inc +++ b/programs/network/ssh/sshlib_host.inc @@ -209,9 +209,9 @@ endl push esi ; EMSA-PKCS1-v1_5 - invoke sha1_init, [h_ctx] - invoke sha1_update, [h_ctx], [M], [message_len] - invoke sha1_finish, [h_ctx] + invoke sha1.init, [h_ctx] + invoke sha1.update, [h_ctx], [M], [message_len] + invoke sha1.finish, [h_ctx] mov edi, [EM_accent] mov al, 0x00 @@ -243,9 +243,9 @@ endl push esi ; EMSA-PKCS1-v1_5 - invoke sha2_256_init, [h_ctx] - invoke sha2_256_update, [h_ctx], [M], [message_len] - invoke sha2_256_finish, [h_ctx] + invoke sha2_256.init, [h_ctx] + invoke sha2_256.update, [h_ctx], [M], [message_len] + invoke sha2_256.finish, [h_ctx] mov edi, [EM_accent] mov al, 0x00 @@ -277,9 +277,9 @@ endl push esi ; EMSA-PKCS1-v1_5 - invoke sha2_512_init, [h_ctx] - invoke sha2_512_update, [h_ctx], [M], [message_len] - invoke sha2_512_finish, [h_ctx] + invoke sha2_512.init, [h_ctx] + invoke sha2_512.update, [h_ctx], [M], [message_len] + invoke sha2_512.finish, [h_ctx] mov edi, [EM_accent] mov al, 0x00 diff --git a/programs/network/ssh/sshlib_transport.inc b/programs/network/ssh/sshlib_transport.inc index 377271f580..8c6abc4534 100644 --- a/programs/network/ssh/sshlib_transport.inc +++ b/programs/network/ssh/sshlib_transport.inc @@ -23,7 +23,7 @@ sshlib_recv_packet: ; con_ptr, flags jmp [eax+sshlib_connection.rx_proc] align 16 -sshlib_send_packet: ; con_ptr, flags +sshlib_send_packet: ; con_ptr, buf, payload_size, flags mov eax, [esp+4] jmp [eax+sshlib_connection.tx_proc] diff --git a/programs/network/ssh/sshlib_transport_hmac_etm.inc b/programs/network/ssh/sshlib_transport_hmac_etm.inc new file mode 100755 index 0000000000..fdfc11f538 --- /dev/null +++ b/programs/network/ssh/sshlib_transport_hmac_etm.inc @@ -0,0 +1,224 @@ +; sshlib_transport.inc - SSH transport layer +; +; Copyright (C) 2016-2024 Jeffrey Amelynck +; +; This program is free software: you can redistribute it and/or modify +; it under the terms of the GNU General Public License as published by +; the Free Software Foundation, either version 3 of the License, or +; (at your option) any later version. +; +; This program is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; GNU General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program. If not, see . + +align 16 +proc sshlib_recv_packet_hmac_etm con_ptr, flags + +locals + data_length dd ? ; Total length of packet without MAC +endl + + DEBUGF 3, "> " +; Receive first block (Read length) + mov ebx, [con_ptr] + mov ecx, [ebx+sshlib_connection.socketnum] + mov esi, 4 + lea edx, [ebx+sshlib_connection.rx_buffer] + mov edi, [flags] + mcall recv + cmp eax, 0 + jle .sock_fail + sub [ssh_chan.rcv_wnd], eax ;;; FIXME + DEBUGF 1, "chunk = %u ", eax + mov ebx, [con_ptr] + cmp eax, 4 + jne .proto_fail ; TODO: handle receives of 1, 2, and 3 bytes correctly + + mov eax, [ebx+sshlib_connection.rx_buffer.packet_length] + bswap eax + mov [data_length], eax + DEBUGF 2, "decrypted packet length=%u\n", [data_length] + + add eax, [ebx + sshlib_connection.rx_mac_length] + cmp eax, BUFFERSIZE-4 + ja .proto_fail + +; Receive remaining data + lea edx, [ebx+sshlib_connection.rx_buffer+4] + mov ecx, [ebx+sshlib_connection.socketnum] + mov edi, [flags] + mov esi, eax + .recv_loop: + DEBUGF 3, "want %u bytes.. ", esi + mcall recv + cmp eax, 0 + jle .sock_fail + sub [ssh_chan.rcv_wnd], eax ;;; FIXME + DEBUGF 3, "got %u bytes\n", eax + add edx, eax + sub esi, eax + jnz .recv_loop + +; Authenticate message + mov ebx, [con_ptr] + lea esi, [ebx + sshlib_connection.rx_mac_seqnr] + mov ecx, [data_length] + add ecx, 8 ; packet_length field itself + sequence number + lea eax, [ebx + sshlib_connection.rx_mac_ctx] + lea edx, [ebx + sshlib_connection.rx_int_key] + stdcall [ebx + sshlib_connection.rx_mac_proc], eax, esi, ecx, edx, SHA2_256_LEN + + lea esi, [ebx + sshlib_connection.rx_mac_ctx] + lea edi, [ebx + sshlib_connection.rx_buffer+4] + add edi, [data_length] + mov ecx, [ebx + sshlib_connection.rx_mac_length] + shr ecx, 2 + repe cmpsd ; TODO: constant time + jne .mac_fail + +; Decrypt the payload + lea eax, [ebx+sshlib_connection.rx_crypt_ctx] + lea edi, [ebx+sshlib_connection.rx_buffer+4] + stdcall [ebx + sshlib_connection.rx_crypt_proc], eax, edi, [data_length], edi + +; Update sequence counter + add byte[ebx+sshlib_connection.rx_mac_seqnr+3], 1 + adc byte[ebx+sshlib_connection.rx_mac_seqnr+2], 0 + adc byte[ebx+sshlib_connection.rx_mac_seqnr+1], 0 + adc byte[ebx+sshlib_connection.rx_mac_seqnr+0], 0 + +; Return useful data length to the caller via eax register + mov eax, [data_length] + mov [ebx+sshlib_connection.rx_buffer.packet_length], eax + movzx ebx, [ebx+sshlib_connection.rx_buffer.padding_length] + sub eax, ebx + DEBUGF 1, "useful data length=%u\n", eax + ret + + .sock_fail: + DEBUGF 3, "ssh_recv_packet failed!\n" + mov eax, SSHLIB_ERR_SOCKET + ret + + .mac_fail: + DEBUGF 3, "ssh_recv_packet message authentication failed!\n" + mov eax, SSHLIB_ERR_MAC_VERIFY_FAIL + xor ebx, ebx + ret + + .proto_fail: + DEBUGF 3, "ssh_recv_packet protocol failure!\n" + mov eax, SSHLIB_ERR_PROTOCOL + xor ebx, ebx + ret + +endp + + +align 16 +proc sshlib_send_packet_hmac_etm con_ptr, buf, payload_size, flags + +locals + padded_size dd ? ; payload with padding (without length field or MAC) +endl + DEBUGF 2, "< " + +; Check how many bytes we should pad + mov eax, [payload_size] + inc eax ; padding length byte + + mov ecx, [con_ptr] + mov edx, eax + mov ebx, [ecx + sshlib_connection.tx_pad_size] + dec ebx + and edx, ebx + neg edx + add edx, [ecx + sshlib_connection.tx_pad_size] + add edx, [ecx + sshlib_connection.tx_pad_size] + DEBUGF 2, "padding %u bytes ", edx + add eax, edx + mov [padded_size], eax ; total packet size with padding, without MAC + +; Start building the packet +; First comes the packet length, in network byte order ofcourse. + DEBUGF 2, "total size: %u ", eax + bswap eax + lea edi, [ecx + sshlib_connection.tx_buffer] + stosd +; Then the padding length + mov al, dl + stosb +;;; And the actual payload bytes + mov esi, [buf] + mov ecx, [payload_size] + rep movsb + +; Append the packet with #edx padding bytes. +; Since we must pad at least 8 bytes, we can always use DWORD writes. +; First do an (unaligned) write exactly following the data + dec edx + mov esi, edx + shr esi, 2 ; number dwords + mov ebx, edx + and ebx, 3 + inc ebx ; number bytes in first write (1-4) + call MBRandom + mov dword[edi], eax + add edi, ebx +; Then, do as many aligned writes as nescessary + @@: + call MBRandom + stosd + dec esi + jnz @r + +; Encrypt the payload + mov ebx, [con_ptr] + lea esi, [ebx + sshlib_connection.tx_crypt_ctx] + lea edi, [ebx + sshlib_connection.tx_buffer+4] + stdcall [ebx + sshlib_connection.tx_crypt_proc], esi, edi, [padded_size], edi + +; Append the packet with Message Authentication Code +; mov ebx, [con_ptr] + DEBUGF 1, "MAC sequence number: 0x%x\n", [ebx + sshlib_connection.tx_mac_seqnr] + lea esi, [ebx + sshlib_connection.tx_mac_seqnr] + mov ecx, [padded_size] + add ecx, 8 ; Sequence number length + packet length field + lea eax, [ebx + sshlib_connection.tx_mac_ctx] + lea edx, [ebx + sshlib_connection.tx_int_key] + stdcall [ebx + sshlib_connection.tx_mac_proc], eax, esi, ecx, edx, SHA2_256_LEN + + mov ebx, [con_ptr] + lea esi, [ebx + sshlib_connection.tx_mac_ctx] + lea edi, [ebx + sshlib_connection.tx_buffer+4] + add edi, [padded_size] + mov ecx, [ebx + sshlib_connection.tx_mac_length] + shr ecx, 2 + rep movsd + +; Update sequence counter + add byte[ebx+sshlib_connection.tx_mac_seqnr+3], 1 + adc byte[ebx+sshlib_connection.tx_mac_seqnr+2], 0 + adc byte[ebx+sshlib_connection.tx_mac_seqnr+1], 0 + adc byte[ebx+sshlib_connection.tx_mac_seqnr+0], 0 + +; Send the packet +; mov ebx, [con_ptr] + mov ecx, [ebx+sshlib_connection.socketnum] + lea edx, [ebx+sshlib_connection.tx_buffer] + mov esi, [padded_size] + add esi, 4 + add esi, [ebx+sshlib_connection.tx_mac_length] + mov edi, [flags] + mcall send + + DEBUGF 2, "\n" + + ret + +endp + diff --git a/programs/network/ssh/sshlib_transport_polychacha.inc b/programs/network/ssh/sshlib_transport_polychacha.inc index 5dcfa3ab32..176a1e5cc9 100755 --- a/programs/network/ssh/sshlib_transport_polychacha.inc +++ b/programs/network/ssh/sshlib_transport_polychacha.inc @@ -62,7 +62,7 @@ endl lea edx, [ebx+sshlib_connection.rx_enc_key+256/8] lea esi, [ebx+sshlib_connection.rx_buffer] lea edi, [data_length] - invoke chacha20_oneshot, ecx, edx, eax, 0, esi, 4, edi + invoke chacha20.oneshot, ecx, edx, eax, 0, esi, 4, edi mov eax, [data_length] bswap eax @@ -94,7 +94,7 @@ endl lea esi, [ebx+sshlib_connection.rx_enc_key] lea edx, [mac_otk] lea ecx, [iv] - invoke chacha20_oneshot, eax, esi, ecx, 0, null_bytes, 64, edx + invoke chacha20.oneshot, eax, esi, ecx, 0, null_bytes, 64, edx ; Calculate the MAC lea esi, [ebx+sshlib_connection.rx_mac_ctx] @@ -103,7 +103,7 @@ endl add ecx, 4 lea edx, [mac_otk] push ecx - invoke poly1305_oneshot, esi, edi, ecx, edx, 256/8 + invoke poly1305.oneshot, esi, edi, ecx, edx, 256/8 pop ecx ; Compare in constant time @@ -126,7 +126,7 @@ endl ; Decrypt the payload lea eax, [ebx+sshlib_connection.rx_crypt_ctx] lea edi, [ebx+sshlib_connection.rx_buffer+4] - invoke chacha20_update, eax, edi, [data_length], edi + invoke chacha20.update, eax, edi, [data_length], edi ; Put decrypted length in rx buffer push [data_length] @@ -240,25 +240,25 @@ endl lea esi, [ebx+sshlib_connection.tx_crypt_ctx] lea edx, [ebx+sshlib_connection.tx_enc_key+256/8] lea edi, [ebx+sshlib_connection.tx_buffer] - invoke chacha20_oneshot, esi, edx, eax, 0, edi, 4, edi + invoke chacha20.oneshot, esi, edx, eax, 0, edi, 4, edi ; Calculate the OTK lea eax, [iv] lea edx, [ebx+sshlib_connection.tx_enc_key] lea edi, [mac_otk] - invoke chacha20_oneshot, esi, edx, eax, 0, null_bytes, 64, edi + invoke chacha20.oneshot, esi, edx, eax, 0, null_bytes, 64, edi ; Encrypt the payload lea edi, [ebx+sshlib_connection.tx_buffer+4] mov eax, [packet_size] sub eax, 4 - invoke chacha20_update, esi, edi, eax, edi + invoke chacha20.update, esi, edi, eax, edi ; Calculate the MAC lea esi, [ebx+sshlib_connection.tx_mac_ctx] lea edi, [ebx+sshlib_connection.tx_buffer] lea edx, [mac_otk] - invoke poly1305_oneshot, esi, edi, [packet_size], edx, 256/8 + invoke poly1305.oneshot, esi, edi, [packet_size], edx, 256/8 ; Write it to the send buffer add edi, [packet_size]