Subversion Repositories Kolibri OS

Compare Revisions

No changes between revisions

Regard whitespace Rev 9986 → Rev 9987

/programs/network/ssh/aes256-ctr.inc
File deleted
\ No newline at end of file
/programs/network/ssh/blowfish-ctr.inc
File deleted
\ No newline at end of file
/programs/network/ssh/hmac_md5.inc
File deleted
/programs/network/ssh/aes256-cbc.inc
File deleted
\ No newline at end of file
/programs/network/ssh/hmac_sha256.inc
File deleted
/programs/network/ssh/hmac_sha1.inc
File deleted
/programs/network/ssh/aes256.inc
File deleted
\ No newline at end of file
/programs/network/ssh/blowfish-cbc.inc
File deleted
\ No newline at end of file
/programs/network/ssh/blowfish.inc
File deleted
\ No newline at end of file
/programs/network/ssh/ssh.asm
1,6 → 1,6
; ssh.asm - SSH client for KolibriOS
;
; Copyright (C) 2015-2021 Jeffrey Amelynck
; Copyright (C) 2015-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
104,22 → 104,12
include 'seed.inc'
include 'random.inc'
 
include 'aes256.inc'
include 'aes256-ctr.inc'
include 'aes256-cbc.inc'
 
include 'blowfish.inc'
include 'blowfish-ctr.inc'
include 'blowfish-cbc.inc'
 
include 'hmac_sha256.inc'
include 'hmac_sha1.inc'
include 'hmac_md5.inc'
 
include 'sshlib.inc'
 
include 'sshlib_mcodes.inc'
include 'sshlib_transport.inc'
include 'sshlib_transport_hmac.inc'
include 'sshlib_transport_polychacha.inc'
include 'sshlib_connection.inc'
include 'sshlib_dh_gex.inc'
include 'sshlib_host.inc'
219,7 → 209,7
mcall 18, 7
push eax
; Create thread
mcall 51, 1, con_in_thread, mem - 2048
mcall 51, 1, con_in_thread, mem + 2048
; Activate window with given ID
pop ecx
mcall 18, 3
487,7 → 477,7
ssh_ident_ha:
dd_n (ssh_msg_ident.length-2)
ssh_msg_ident:
db "SSH-2.0-KolibriOS_SSH_0.09",13,10
db "SSH-2.0-KolibriOS_SSH_0.10",13,10
.length = $ - ssh_msg_ident
 
 
500,9 → 490,9
.server_host_key_algorithms:
str "rsa-sha2-512,rsa-sha2-256,ssh-rsa" ;,ssh-dss
.encryption_algorithms_client_to_server:
str "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 "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"
.encryption_algorithms_server_to_client:
str "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 "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"
.mac_algorithms_client_to_server:
str "hmac-sha2-256" ;,hmac-sha1,hmac-sha1-96,hmac-md5"
.mac_algorithms_server_to_client:
630,9 → 620,21
sha1_init, 'sha1_init', \
sha1_update, 'sha1_update', \
sha1_finish, 'sha1_finish', \
md5_init, 'md5_init', \
md5_update, 'md5_update', \
md5_finish, 'md5_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', \
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"
 
import libini, \
ini_get_str, 'ini_get_str', \
644,9 → 646,13
 
IncludeUGlobals
 
align 16
params rb MAX_HOSTNAME_LENGTH
 
align 16
ssh_con sshlib_connection
 
align 16
ssh_chan sshlib_channel
 
keyb_input rb MAX_INPUT_LENGTH
/programs/network/ssh/sshlib.inc
54,19 → 54,20
SSHLIB_HOSTKEY_RSA_SHA2_256 = 3
SSHLIB_HOSTKEY_RSA_SHA2_512 = 4
 
SSHLIB_CRYPT_BLOWFISH_CTR = 1
SSHLIB_CRYPT_BLOWFISH_CBC = 2
SSHLIB_CRYPT_AES128_CTR = 3
SSHLIB_CRYPT_AES128_CBC = 4
SSHLIB_CRYPT_AES192_CTR = 5
SSHLIB_CRYPT_AES192_CBC = 6
SSHLIB_CRYPT_AES256_CTR = 7
SSHLIB_CRYPT_AES256_CBC = 8
;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_HMAC_MD5 = 1
SSHLIB_HMAC_SHA1 = 2
SSHLIB_HMAC_SHA1_96 = 3
SSHLIB_HMAC_SHA2_256 = 4
;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_COMPR_NONE = 1
SSHLIB_COMPR_ZLIB = 2
97,31 → 98,39
struct sshlib_connection
 
status dd ?
 
socketnum dd ?
 
rx_proc dd ?
tx_proc dd ?
 
rx_mac_ctx rb LIBCRASH_CTX_LEN
tx_mac_ctx rb LIBCRASH_CTX_LEN
 
rx_crypt_ctx rb LIBCRASH_CTX_LEN
tx_crypt_ctx rb LIBCRASH_CTX_LEN
 
rx_crypt_proc dd ?
tx_crypt_proc dd ?
rx_crypt_ctx_ptr dd ?
tx_crypt_ctx_ptr dd ?
; rx_crypt_ctx_ptr dd ?
; tx_crypt_ctx_ptr dd ?
rx_crypt_blocksize dd ?
tx_crypt_blocksize dd ?
 
tx_pad_size dd ? ; = Max(8, tx_crypt_blocksize)
tx_pad_proc dd ?
dd ?
 
rx_mac_proc dd ?
tx_mac_proc dd ?
rx_mac_ctx hmac_sha256_context
tx_mac_ctx hmac_sha256_context
 
rx_mac_length dd ?
tx_mac_length dd ?
 
rx_mac_seqnr dd ? ; DO NOT MOVE
rd 3 ; align
rx_mac_seqnr dd ? ; DO NOT MOVE (specific place for HMAC)
rx_buffer ssh_packet_header
rb BUFFERSIZE-sizeof.ssh_packet_header
 
tx_mac_seqnr dd ? ; DO NOT MOVE
tx_mac_seqnr dd ? ; DO NOT MOVE (specific place for HMAC)
tx_buffer ssh_packet_header
rb PACKETSIZE-sizeof.ssh_packet_header
 
139,6 → 148,13
 
hostname_sz rb MAX_HOSTNAME_LENGTH
 
rx_enc_key rb 2*256/8
tx_enc_key rb 2*256/8
rx_int_key rb 2*256/8
tx_int_key rb 2*256/8
rx_iv rb 2*256/8
tx_iv rb 2*256/8
 
ends
 
; SSH channel structure
/programs/network/ssh/sshlib_channel.inc
1,6 → 1,6
; sshlib_channel.inc - SSH channel
;
; Copyright (C) 2016-2021 Jeffrey Amelynck
; 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
20,7 → 20,7
 
; >> Open channel
 
DEBUGF 2, "SSH: Open channel\n"
DEBUGF 2, "SSH: Opening channel\n"
 
mov [ssh_chan.rcv_wnd], BUFFERSIZE
mov [ssh_chan.snd_wnd], 0
38,9 → 38,11
cmp [esi + sshlib_connection.rx_buffer.message_code], SSH_MSG_CHANNEL_OPEN_CONFIRMATION
jne .err_proto
 
DEBUGF 2, "SSH: Channel opened successfully\n"
 
; >> Channel request: pty
 
DEBUGF 2, "SSH: Request pty\n"
DEBUGF 2, "SSH: Requesting PTY\n"
 
stdcall sshlib_send_packet, [con_ptr], ssh_msg_channel_request, ssh_msg_channel_request.length, 0
cmp eax, 0
56,9 → 58,11
cmp [esi + sshlib_connection.rx_buffer.message_code], SSH_MSG_CHANNEL_SUCCESS
jne .err_proto
 
DEBUGF 2, "SSH: PTY opened successfully\n"
 
; >> Channel request: shell
 
DEBUGF 2, "SSH: Request shell\n"
DEBUGF 2, "SSH: Requesting shell\n"
 
stdcall sshlib_send_packet, [con_ptr], ssh_msg_shell_request, ssh_msg_shell_request.length, 0
cmp eax, 0
76,6 → 80,8
cmp [esi + sshlib_connection.rx_buffer.message_code], SSH_MSG_CHANNEL_SUCCESS
jne .wait_success
 
DEBUGF 2, "SSH: Shell opened successfully\n"
 
xor eax, eax
.err:
ret
/programs/network/ssh/sshlib_connection.inc
1,6 → 1,6
; sshlib_connection.inc - SSH connection
;
; Copyright (C) 2016-2021 Jeffrey Amelynck
; 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
15,6 → 15,8
; You should have received a copy of the GNU General Public License
; along with this program. If not, see <http://www.gnu.org/licenses/>.
 
; https://www.ietf.org/rfc/rfc4253.txt
 
proc sshlib_connect con_ptr, hostname_sz
 
locals
157,15 → 159,17
mov [eax + sshlib_connection.tx_mac_seqnr], 0
mov [eax + sshlib_connection.rx_crypt_blocksize], 4 ; minimum blocksize
mov [eax + sshlib_connection.tx_crypt_blocksize], 4
mov [eax + sshlib_connection.rx_crypt_proc], sshlib_crypt_null
mov [eax + sshlib_connection.tx_crypt_proc], sshlib_crypt_null
mov [eax + sshlib_connection.rx_crypt_proc], 0
mov [eax + sshlib_connection.tx_crypt_proc], 0
mov [eax + sshlib_connection.rx_mac_proc], 0
mov [eax + sshlib_connection.tx_mac_proc], 0
mov [eax + sshlib_connection.rx_mac_length], 0
mov [eax + sshlib_connection.tx_mac_length], 0
mov [eax + sshlib_connection.tx_pad_size], 8
mov [eax + sshlib_connection.tx_pad_proc], sshlib_padd_null
 
mov [eax + sshlib_connection.rx_proc], sshlib_recv_packet_clear
mov [eax + sshlib_connection.tx_proc], sshlib_send_packet_clear
 
DEBUGF 2, "Sending KEX init\n"
mov edi, ssh_msg_kex.cookie
call MBRandom
277,6 → 281,45
test eax, eax
jnz .err
 
; Set keys and initialize transport subroutines
 
DEBUGF 2, "SSH: Setting encryption keys\n"
 
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
 
mov [ebx + sshlib_connection.rx_proc], sshlib_recv_packet_poly1305chacha20
mov [ebx + sshlib_connection.tx_proc], sshlib_send_packet_poly1305chacha20
 
; Re-seed RNG for padding bytes
 
call create_seed
327,7 → 370,7
mov esi, [con_ptr]
lea esi, [esi + sshlib_connection.rx_buffer]
mov al, [esi + ssh_packet_header.message_code]
inc esi
add esi, sizeof.ssh_packet_header
 
cmp al, SSH_MSG_DISCONNECT
je .disc
346,6 → 389,8
cmp al, SSH_MSG_CHANNEL_CLOSE
je .chan_close
 
DEBUGF 3, "SSH: Message type: %u\n", al
 
.ret:
ret
 
364,7 → 409,8
jmp .recv
 
.glob_req:
DEBUGF 3, "SSH: Global MSG received\n"
add esi, 4
DEBUGF 3, "SSH: Global MSG received: %s\n", esi
;TODO
jmp .recv
 
/programs/network/ssh/sshlib_dh_gex.inc
34,14 → 34,6
temp_ctx dd ?
 
H dd ? ; exchange hash
 
rx_iv dd ? ; Rx initialisation vector
tx_iv dd ? ; Tx initialisation vector
rx_enc_key dd ? ; Rx encryption key
tx_enc_key dd ? ; Tx encryption key
rx_int_key dd ? ; Rx integrity key
tx_int_key dd ? ; Tx integrity key
 
K_length dd ?
 
session_id_x rb SHA2_256_LEN+1
54,7 → 46,7
 
; Allocate memory for temp variables
 
mov ecx, 7*(MAX_BITS/8+4) + 7*SHA2_256_LEN + 2*LIBCRASH_CTX_LEN
mov ecx, 7*(MAX_BITS/8+4) + 2*LIBCRASH_CTX_LEN + 1*SHA2_256_LEN
mcall 68, 12
test eax, eax
jz .err_nomem
83,18 → 75,6
 
mov [H], eax
add eax, SHA2_256_LEN
mov [rx_iv], eax
add eax, SHA2_256_LEN
mov [tx_iv], eax
add eax, SHA2_256_LEN
mov [rx_enc_key], eax
add eax, SHA2_256_LEN
mov [tx_enc_key], eax
add eax, SHA2_256_LEN
mov [rx_int_key], eax
add eax, SHA2_256_LEN
mov [tx_int_key], eax
; add eax, SHA2_256_LEN
 
; Copy the partial exchange hash to our temporary one
 
297,7 → 277,26
mov ecx, SHA2_256_LEN/4
rep movsd
 
;-------------------------------------
; << Parse Diffie-Hellman New Keys MSG
 
stdcall sshlib_recv_packet, [con_ptr], 0
cmp eax, 0
jl .err
 
mov ebx, [con_ptr]
cmp [ebx + sshlib_connection.rx_buffer.message_code], SSH_MSG_NEWKEYS
jne .err_proto
 
DEBUGF 2, "Received New Keys\n"
 
;----------------------------------------------------
; >> Reply with New Keys message (Using the old keys)
 
stdcall sshlib_send_packet, [con_ptr], ssh_msg_new_keys, ssh_msg_new_keys.length, 0
cmp eax, 0
jl .err
 
;---------------
; Calculate keys
 
321,14 → 320,12
mov byte[edx], 'A'
invoke sha2_256_update, [temp_ctx], edx, SHA2_256_LEN+1
invoke sha2_256_finish, [temp_ctx]
mov edi, [tx_iv]
mov ebx, [con_ptr]
lea edi, [ebx + sshlib_connection.tx_iv]
mov esi, [temp_ctx]
mov ecx, SHA2_256_LEN/4
rep movsd
 
DEBUGF 1, "Remote IV: "
stdcall dump_hex, [tx_iv], SHA2_256_LEN/4
 
;---------------------------------------------------------------
; Initial IV server to client: HASH(K || H || "B" || session_id)
 
340,14 → 337,12
mov byte[edx], 'B'
invoke sha2_256_update, [temp_ctx], edx, SHA2_256_LEN+1
invoke sha2_256_finish, [temp_ctx]
mov edi, [rx_iv]
mov ebx, [con_ptr]
lea edi, [ebx + sshlib_connection.rx_iv]
mov esi, [temp_ctx]
mov ecx, SHA2_256_LEN/4
rep movsd
 
DEBUGF 1, "Local IV: "
stdcall dump_hex, [rx_iv], SHA2_256_LEN/4
 
;-------------------------------------------------------------------
; Encryption key client to server: HASH(K || H || "C" || session_id)
 
359,14 → 354,28
mov byte[edx], 'C'
invoke sha2_256_update, [temp_ctx], edx, SHA2_256_LEN+1
invoke sha2_256_finish, [temp_ctx]
mov edi, [tx_enc_key]
 
mov ebx, [con_ptr]
lea edi, [ebx+sshlib_connection.tx_enc_key]
mov esi, [temp_ctx]
mov ecx, SHA2_256_LEN/4
rep movsd
 
DEBUGF 1, "Remote key: "
stdcall dump_hex, [tx_enc_key], SHA2_256_LEN/4
mov esi, [k_h_ctx]
mov edi, [temp_ctx]
mov ecx, LIBCRASH_CTX_LEN/4
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]
 
mov ebx, [con_ptr]
add edi, 256/8
mov esi, [temp_ctx]
mov ecx, SHA2_256_LEN/4
rep movsd
 
;-------------------------------------------------------------------
; Encryption key server to client: HASH(K || H || "D" || session_id)
 
378,14 → 387,28
mov byte[edx], 'D'
invoke sha2_256_update, [temp_ctx], edx, SHA2_256_LEN+1
invoke sha2_256_finish, [temp_ctx]
mov edi, [rx_enc_key]
 
mov ebx, [con_ptr]
lea edi, [ebx+sshlib_connection.rx_enc_key]
mov esi, [temp_ctx]
mov ecx, SHA2_256_LEN/4
rep movsd
 
DEBUGF 1, "Local key: "
stdcall dump_hex, [rx_enc_key], SHA2_256_LEN/4
mov esi, [k_h_ctx]
mov edi, [temp_ctx]
mov ecx, LIBCRASH_CTX_LEN/4
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]
 
mov ebx, [con_ptr]
add edi, 256/8
mov esi, [temp_ctx]
mov ecx, SHA2_256_LEN/4
rep movsd
 
;------------------------------------------------------------------
; Integrity key client to server: HASH(K || H || "E" || session_id)
 
397,14 → 420,12
mov byte[edx], 'E'
invoke sha2_256_update, [temp_ctx], edx, SHA2_256_LEN+1
invoke sha2_256_finish, [temp_ctx]
mov edi, [tx_int_key]
mov ebx, [con_ptr]
lea edi, [ebx + sshlib_connection.tx_int_key]
mov esi, [temp_ctx]
mov ecx, SHA2_256_LEN/4
rep movsd
 
DEBUGF 1, "Remote Integrity key: "
stdcall dump_hex, [tx_int_key], SHA2_256_LEN/4
 
;------------------------------------------------------------------
; Integrity key server to client: HASH(K || H || "F" || session_id)
 
416,69 → 437,13
mov byte[edx], 'F'
invoke sha2_256_update, [temp_ctx], edx, SHA2_256_LEN+1
invoke sha2_256_finish, [temp_ctx]
mov edi, [rx_int_key]
mov ebx, [con_ptr]
lea edi, [ebx + sshlib_connection.rx_int_key]
mov esi, [temp_ctx]
mov ecx, SHA2_256_LEN/4
rep movsd
 
DEBUGF 1, "Local Integrity key: "
stdcall dump_hex, [rx_int_key] , SHA2_256_LEN/4
 
;-------------------------------------
; << Parse Diffie-Hellman New Keys MSG
 
stdcall sshlib_recv_packet, [con_ptr], 0
cmp eax, 0
jl .err
 
mov ebx, [con_ptr]
cmp [ebx + sshlib_connection.rx_buffer.message_code], SSH_MSG_NEWKEYS
jne .err_proto
 
DEBUGF 2, "Received New Keys\n"
 
;-------------------------------
; >> Reply with New Keys message
 
stdcall sshlib_send_packet, [con_ptr], ssh_msg_new_keys, ssh_msg_new_keys.length, 0
cmp eax, 0
jl .err
 
;----------------------------------------------
; Set keys and initialize transport subroutines
 
DEBUGF 2, "SSH: Setting encryption keys\n"
 
mov ebx, [con_ptr]
stdcall aes256_ctr_init, [rx_iv]
test eax, eax
jz .err_nomem
mov [ebx + sshlib_connection.rx_crypt_ctx_ptr], eax
stdcall aes256_set_encrypt_key, eax, [rx_enc_key]
mov [ebx + sshlib_connection.rx_crypt_proc], aes256_ctr_crypt
mov [ebx + sshlib_connection.rx_crypt_blocksize], AES256_BLOCKSIZE
 
stdcall aes256_ctr_init, [tx_iv]
test eax, eax
jz .err_nomem
mov [ebx + sshlib_connection.tx_crypt_ctx_ptr], eax
stdcall aes256_set_encrypt_key, eax, [tx_enc_key]
mov [ebx + sshlib_connection.tx_crypt_proc], aes256_ctr_crypt
mov [ebx + sshlib_connection.tx_crypt_blocksize], AES256_BLOCKSIZE
 
mov [ebx + sshlib_connection.tx_pad_size], AES256_BLOCKSIZE
mov [ebx + sshlib_connection.tx_pad_proc], MBRandom
 
lea ecx, [ebx + sshlib_connection.rx_mac_ctx]
stdcall hmac_sha256_setkey, ecx, [rx_int_key], SHA2_256_LEN
mov [ebx + sshlib_connection.rx_mac_proc], hmac_sha256
mov [ebx + sshlib_connection.rx_mac_length], SHA2_256_LEN
 
lea ecx, [ebx + sshlib_connection.tx_mac_ctx]
stdcall hmac_sha256_setkey, ecx, [tx_int_key], SHA2_256_LEN
mov [ebx + sshlib_connection.tx_mac_proc], hmac_sha256
mov [ebx + sshlib_connection.tx_mac_length], SHA2_256_LEN
 
mov [ebx + sshlib_connection.status], SSHLIB_CON_STAT_KEX_DONE
xor eax, eax
 
485,7 → 450,7
.err:
push eax
xor eax, eax
mov ecx, (7*(MAX_BITS/8+4) + 7*SHA2_256_LEN + 2*LIBCRASH_CTX_LEN)/4
mov ecx, (7*(MAX_BITS/8+4) + 2*LIBCRASH_CTX_LEN + 1*SHA2_256_LEN )/4
mov edi, [mpint_tmp]
rep stosd
 
/programs/network/ssh/sshlib_mcodes.inc
30,4 → 30,20
SSH_MSG_CHANNEL_CLOSE = 97
SSH_MSG_CHANNEL_REQUEST = 98
SSH_MSG_CHANNEL_SUCCESS = 99
SSH_MSG_CHANNEL_FAILURE = 100
SSH_MSG_CHANNEL_FAILURE = 100
 
SSH_DISCONNECT_HOST_NOT_ALLOWED_TO_CONNECT = 1
SSH_DISCONNECT_PROTOCOL_ERROR = 2
SSH_DISCONNECT_KEY_EXCHANGE_FAILED = 3
SSH_DISCONNECT_RESERVED = 4
SSH_DISCONNECT_MAC_ERROR = 5
SSH_DISCONNECT_COMPRESSION_ERROR = 6
SSH_DISCONNECT_SERVICE_NOT_AVAILABLE = 7
SSH_DISCONNECT_PROTOCOL_VERSION_NOT_SUPPORTED = 8
SSH_DISCONNECT_HOST_KEY_NOT_VERIFIABLE = 9
SSH_DISCONNECT_CONNECTION_LOST = 10
SSH_DISCONNECT_BY_APPLICATION = 11
SSH_DISCONNECT_TOO_MANY_CONNECTIONS = 12
SSH_DISCONNECT_AUTH_CANCELLED_BY_USER = 13
SSH_DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE = 14
SSH_DISCONNECT_ILLEGAL_USER_NAME = 15
/programs/network/ssh/sshlib_transport.inc
1,6 → 1,6
; sshlib_transport.inc - SSH transport layer
;
; Copyright (C) 2016-2021 Jeffrey Amelynck
; 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
16,23 → 16,22
; along with this program. If not, see <http://www.gnu.org/licenses/>.
 
 
proc sshlib_padd_null
align 16
sshlib_recv_packet: ; con_ptr, flags
 
xor eax, eax
ret
mov eax, [esp+4]
jmp [eax+sshlib_connection.rx_proc]
 
endp
align 16
sshlib_send_packet: ; con_ptr, flags
 
proc sshlib_crypt_null ctx, src, dst
mov eax, [esp+4]
jmp [eax+sshlib_connection.tx_proc]
 
; Assume src == dst !
 
ret
align 16
proc sshlib_recv_packet_clear con_ptr, flags
 
endp
 
proc sshlib_recv_packet con_ptr, flags
 
locals
data_length dd ? ; Total length of packet without MAC
endl
41,7 → 40,7
; Receive first block (Read length, padding length, message code)
mov ebx, [con_ptr]
mov ecx, [ebx+sshlib_connection.socketnum]
mov esi, [ebx+sshlib_connection.rx_crypt_blocksize]
mov esi, 4
lea edx, [ebx+sshlib_connection.rx_buffer]
mov edi, [flags]
mcall recv
50,15 → 49,9
sub [ssh_chan.rcv_wnd], eax ;;; FIXME
DEBUGF 1, "chunk = %u ", eax
mov ebx, [con_ptr]
cmp eax, [ebx+sshlib_connection.rx_crypt_blocksize]
cmp eax, 4
jne .proto_fail ; TODO: handle receives of 1, 2, and 3 bytes correctly
 
; Decrypt first block
pusha
lea esi, [ebx+sshlib_connection.rx_buffer]
stdcall [ebx+sshlib_connection.rx_crypt_proc], [ebx+sshlib_connection.rx_crypt_ctx_ptr], esi, esi
popa
 
; Check data length
mov esi, [ebx + sshlib_connection.rx_buffer.packet_length]
bswap esi ; convert length to little endian
66,16 → 59,12
DEBUGF 1, "packet length=%u ", esi
cmp esi, BUFFERSIZE
ja .proto_fail ; packet is too large
test ecx, ecx
jz .proto_fail
 
; Calculate amount of remaining data
add esi, 4 ; Packet length field itself is not included in the count
sub esi, [ebx+sshlib_connection.rx_crypt_blocksize] ; Already received this amount of data
add esi, [ebx+sshlib_connection.rx_mac_length]
jz .packet_complete
 
; Receive remaining data
lea edx, [ebx+sshlib_connection.rx_buffer]
add edx, [ebx+sshlib_connection.rx_crypt_blocksize]
add edx, 4
mov ecx, [ebx+sshlib_connection.socketnum]
mov edi, [flags]
.receive_loop:
88,60 → 77,21
add edx, eax
sub esi, eax
jnz .receive_loop
.packet_complete:
 
; Decrypt data
; Return useful data length to the caller via eax register
mov ebx, [con_ptr]
mov ecx, [ebx + sshlib_connection.rx_buffer.packet_length]
add ecx, 4 ; Packet_length field itself
sub ecx, [ebx+sshlib_connection.rx_crypt_blocksize] ; Already decrypted this amount of data
jz .decrypt_complete
mov eax, [ebx + sshlib_connection.rx_buffer.packet_length]
movzx ebx, [ebx + sshlib_connection.rx_buffer.padding_length]
sub eax, ebx
 
lea esi, [ebx+sshlib_connection.rx_buffer]
add esi, [ebx+sshlib_connection.rx_crypt_blocksize]
.decrypt_loop:
pusha
stdcall [ebx+sshlib_connection.rx_crypt_proc], [ebx+sshlib_connection.rx_crypt_ctx_ptr], esi, esi
popa
add esi, [ebx+sshlib_connection.rx_crypt_blocksize]
sub ecx, [ebx+sshlib_connection.rx_crypt_blocksize]
jnz .decrypt_loop
.decrypt_complete:
 
; Authenticate message
cmp [ebx+sshlib_connection.rx_mac_proc], 0
je .mac_complete
lea esi, [ebx+sshlib_connection.rx_mac_seqnr]
mov ecx, [ebx+sshlib_connection.rx_buffer.packet_length]
add ecx, 8 ; packet_length field itself + sequence number
lea eax, [ebx+sshlib_connection.rx_mac_ctx]
; push [ebx+sshlib_connection.rx_buffer.packet_length]
mov edx, [ebx+sshlib_connection.rx_buffer.packet_length]
bswap edx ; convert length to big endian
mov [ebx+sshlib_connection.rx_buffer.packet_length], edx
stdcall [ebx+sshlib_connection.rx_mac_proc], eax, esi, ecx
; pop [ebx+sshlib_connection.rx_buffer.packet_length]
mov edx, [ebx+sshlib_connection.rx_buffer.packet_length]
bswap edx ; convert length to little endian
mov [ebx+sshlib_connection.rx_buffer.packet_length], edx
 
lea esi, [ebx+sshlib_connection.rx_mac_ctx]
lea edi, [ebx+sshlib_connection.rx_buffer+4]
add edi, [ebx+sshlib_connection.rx_buffer.packet_length]
mov ecx, [ebx+sshlib_connection.rx_mac_length]
shr ecx, 2
repe cmpsd
jne .mac_fail
.mac_complete:
add byte[ebx+sshlib_connection.rx_mac_seqnr+3], 1 ; Update sequence counter
; Update sequence counter
mov ebx, [con_ptr]
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
.packet_complete:
mov eax, [ebx+sshlib_connection.rx_buffer.packet_length]
movzx ebx, [ebx+sshlib_connection.rx_buffer.padding_length]
sub eax, ebx
DEBUGF 1, "useful data length=%u\n", eax
ret
 
150,12 → 100,6
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
165,7 → 109,8
endp
 
 
proc sshlib_send_packet con_ptr, buf, payload_size, flags
align 16
proc sshlib_send_packet_clear con_ptr, buf, payload_size, flags
 
locals
packet_size dd ?
191,7 → 136,7
; Start building the packet
; First comes the packet length, in network byte order ofcourse.
add eax, edx
DEBUGF 1, "total size: %u ", eax
DEBUGF 2, "total size: %u ", eax
bswap eax
lea edi, [ecx+sshlib_connection.tx_buffer]
stosd
212,63 → 157,32
mov ebx, edx
and ebx, 3
inc ebx ; number bytes in first write (1-4)
mov edx, [con_ptr]
call [edx+sshlib_connection.tx_pad_proc]
mov dword[edi], eax
mov dword[edi], 0
add edi, ebx
; Then, do as many aligned writes as nescessary
mov ebx, [con_ptr]
xor eax, eax
@@:
call [ebx+sshlib_connection.tx_pad_proc]
stosd
dec esi
jnz @r
 
; Append the packet with Message Authentication Code
mov edx, [con_ptr]
cmp [edx+sshlib_connection.tx_mac_proc], 0
je .mac_complete
DEBUGF 1, "MAC sequence number: 0x%x\n", [edx+sshlib_connection.tx_mac_seqnr]
lea esi, [edx+sshlib_connection.tx_mac_seqnr]
mov ecx, [packet_size]
add ecx, 4 ; Sequence number length
lea eax, [edx+sshlib_connection.tx_mac_ctx]
stdcall [edx+sshlib_connection.tx_mac_proc], eax, esi, ecx
 
lea esi, [edx+sshlib_connection.tx_mac_ctx]
lea edi, [edx+sshlib_connection.tx_buffer]
add edi, [packet_size]
mov ecx, [edx+sshlib_connection.tx_mac_length]
shr ecx, 2
rep movsd
.mac_complete:
add byte[edx+sshlib_connection.tx_mac_seqnr+3], 1 ; Update sequence counter
adc byte[edx+sshlib_connection.tx_mac_seqnr+2], 0
adc byte[edx+sshlib_connection.tx_mac_seqnr+1], 0
adc byte[edx+sshlib_connection.tx_mac_seqnr+0], 0
 
; Now, encrypt everything but MAC
lea esi, [edx+sshlib_connection.tx_buffer]
mov ecx, [packet_size]
.encrypt_loop:
pusha
stdcall [edx+sshlib_connection.tx_crypt_proc], [edx+sshlib_connection.tx_crypt_ctx_ptr], esi, esi
popa
add esi, [edx+sshlib_connection.tx_crypt_blocksize]
sub ecx, [edx+sshlib_connection.tx_crypt_blocksize]
jnz .encrypt_loop
 
; Send the packet
mov ebx, [con_ptr]
mov ecx, [ebx+sshlib_connection.socketnum]
lea edx, [ebx+sshlib_connection.tx_buffer]
mov esi, [packet_size]
add esi, [ebx+sshlib_connection.tx_mac_length]
mov edi, [flags]
mcall send
 
DEBUGF 1, "\n"
; Update sequence counter
mov ebx, [con_ptr]
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
 
DEBUGF 2, "\n"
 
ret
 
endp
/programs/network/ssh/sshlib_transport_hmac.inc
0,0 → 1,257
; 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 <http://www.gnu.org/licenses/>.
 
 
align 16
proc sshlib_recv_packet_hmac con_ptr, flags
 
locals
data_length dd ? ; Total length of packet without MAC
endl
 
DEBUGF 3, "> "
; Receive first block
mov ebx, [con_ptr]
mov ecx, [ebx + sshlib_connection.socketnum]
mov esi, [ebx + sshlib_connection.rx_crypt_blocksize]
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 2, "chunk = %u ", eax
 
mov ebx, [con_ptr]
cmp eax, [ebx + sshlib_connection.rx_crypt_blocksize]
jne .proto_fail ; TODO: handle receives of 1, 2, and 3 bytes correctly
 
; Decrypt first block
pusha
lea esi, [ebx + sshlib_connection.rx_buffer]
lea ecx, [ebx + sshlib_connection.rx_crypt_ctx]
stdcall [ebx + sshlib_connection.rx_crypt_proc], ecx, esi, eax, esi
popa
 
; Check data length
mov esi, [ebx + sshlib_connection.rx_buffer.packet_length]
bswap esi ; convert length to little endian
mov [ebx + sshlib_connection.rx_buffer.packet_length], esi
DEBUGF 2, "packet length=%u ", esi
cmp esi, BUFFERSIZE
ja .proto_fail ; packet is too large
 
; Calculate amount of remaining data
add esi, 4 ; Packet length field itself is not included in the count
sub esi, [ebx + sshlib_connection.rx_crypt_blocksize] ; Already received this amount of data
add esi, [ebx + sshlib_connection.rx_mac_length]
jz .packet_complete
 
; Receive remaining data
lea edx, [ebx + sshlib_connection.rx_buffer]
add edx, [ebx + sshlib_connection.rx_crypt_blocksize]
mov ecx, [ebx + sshlib_connection.socketnum]
mov edi, [flags]
.receive_loop:
DEBUGF 3, "want %d bytes.. ", esi
mcall recv
cmp eax, 0
jle .sock_fail
sub [ssh_chan.rcv_wnd], eax ;;; FIXME
DEBUGF 3, "got %d bytes\n", eax
add edx, eax
sub esi, eax
jnz .receive_loop
.packet_complete:
 
; Decrypt data
mov ebx, [con_ptr]
mov ecx, [ebx + sshlib_connection.rx_buffer.packet_length]
add ecx, 4 ; Packet_length field itself
sub ecx, [ebx + sshlib_connection.rx_crypt_blocksize] ; Already decrypted this amount of data
jz .decrypt_complete
 
lea esi, [ebx + sshlib_connection.rx_buffer]
add esi, [ebx + sshlib_connection.rx_crypt_blocksize]
pusha
lea eax, [ebx + sshlib_connection.rx_crypt_ctx]
stdcall [ebx + sshlib_connection.rx_crypt_proc], eax, esi, ecx, esi
popa
.decrypt_complete:
 
; Authenticate message
lea esi, [ebx + sshlib_connection.rx_mac_seqnr]
mov ecx, [ebx + sshlib_connection.rx_buffer.packet_length]
add ecx, 8 ; packet_length field itself + sequence number
lea eax, [ebx + sshlib_connection.rx_mac_ctx]
mov edx, [ebx + sshlib_connection.rx_buffer.packet_length]
bswap edx ; convert length to big endian
mov [ebx + sshlib_connection.rx_buffer.packet_length], edx
lea edx, [ebx + sshlib_connection.rx_int_key]
stdcall [ebx + sshlib_connection.rx_mac_proc], eax, esi, ecx, edx, SHA2_256_LEN
mov edx, [ebx + sshlib_connection.rx_buffer.packet_length]
bswap edx ; convert length to little endian
mov [ebx + sshlib_connection.rx_buffer.packet_length], edx
 
lea esi, [ebx + sshlib_connection.rx_mac_ctx]
lea edi, [ebx + sshlib_connection.rx_buffer+4]
add edi, [ebx + sshlib_connection.rx_buffer.packet_length]
mov ecx, [ebx + sshlib_connection.rx_mac_length]
shr ecx, 2
repe cmpsd ; TODO: constant time
jne .mac_fail
 
; Return useful data length to the caller via eax register
mov eax, [ebx + sshlib_connection.rx_buffer.packet_length]
movzx ebx, [ebx + sshlib_connection.rx_buffer.padding_length]
sub eax, ebx
 
; Update sequence counter
mov ebx, [con_ptr]
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
 
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 con_ptr, buf, payload_size, flags
 
locals
packet_size dd ?
endl
DEBUGF 2, "< "
 
; Check how many bytes we should pad
mov eax, [payload_size]
inc eax ; padding length byte
lea edx, [eax+4] ; total packet size (without padding and MAC)
mov [packet_size], edx
 
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 1, "padding %u bytes ", edx
add [packet_size], edx ; total packet size with padding
 
; Start building the packet
; First comes the packet length, in network byte order ofcourse.
add eax, edx
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
 
; 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, [packet_size]
add ecx, 4 ; Sequence number length
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]
add edi, [packet_size]
mov ecx, [ebx + sshlib_connection.tx_mac_length]
shr ecx, 2
rep movsd
 
; Now, encrypt everything but MAC
lea esi, [ebx + sshlib_connection.tx_buffer]
lea eax, [ebx + sshlib_connection.tx_crypt_ctx]
stdcall [ebx + sshlib_connection.tx_crypt_proc], eax, esi, [packet_size], esi
 
; Send the packet
mov ebx, [con_ptr]
mov ecx, [ebx + sshlib_connection.socketnum]
lea edx, [ebx + sshlib_connection.tx_buffer]
mov esi, [packet_size]
add esi, [ebx + sshlib_connection.tx_mac_length]
mov edi, [flags]
mcall send
 
; Update sequence counter
mov ebx, [con_ptr]
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
 
DEBUGF 2, "\n"
 
ret
 
endp
 
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/programs/network/ssh/sshlib_transport_polychacha.inc
0,0 → 1,290
; 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 <http://www.gnu.org/licenses/>.
 
iglobal
 
align 16
null_bytes: times 64 db 0
 
endg
 
 
align 16
proc sshlib_recv_packet_poly1305chacha20 con_ptr, flags
 
locals
data_length dd ? ; Total length of packet without MAC
mac_otk rb 64 ;256/8
iv rd 4
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
 
; Decrypt data length
mov ebx, [con_ptr]
 
lea eax, [iv]
mov dword[eax+0], 0
mov dword[eax+4], 0
mov dword[eax+8], 0
push [ebx+sshlib_connection.rx_mac_seqnr]
pop dword[eax+12]
 
lea ecx, [ebx+sshlib_connection.rx_crypt_ctx]
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
 
mov eax, [data_length]
bswap eax
mov [data_length], eax
DEBUGF 2, "decrypted packet length=%u\n", [data_length]
 
cmp eax, BUFFERSIZE-4-128/8
ja .proto_fail
 
; Receive remaining data
lea edx, [ebx+sshlib_connection.rx_buffer+4]
mov ecx, [ebx+sshlib_connection.socketnum]
mov edi, [flags]
lea esi, [eax + 128/8] ; We already got 4 bytes but they are not counted, MAC is also not counted so add that
.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
 
; Calculate the OTK
mov ebx, [con_ptr]
lea eax, [ebx+sshlib_connection.rx_crypt_ctx]
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
 
; Calculate the MAC
lea esi, [ebx+sshlib_connection.rx_mac_ctx]
lea edi, [ebx+sshlib_connection.rx_buffer]
mov ecx, [data_length]
add ecx, 4
lea edx, [mac_otk]
push ecx
invoke poly1305_oneshot, esi, edi, ecx, edx, 256/8
pop ecx
 
; Compare in constant time
add edi, ecx
cmpsd
lahf
mov edx, eax
cmpsd
lahf
and edx, eax
cmpsd
lahf
and edx, eax
cmpsd
lahf
and eax, edx
sahf
jne .mac_fail
 
; 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
 
; Put decrypted length in rx buffer
push [data_length]
pop dword[ebx+sshlib_connection.rx_buffer]
 
; 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
;;; .packet_complete:
mov eax, [ebx+sshlib_connection.rx_buffer.packet_length]
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_poly1305chacha20 con_ptr, buf, payload_size, flags
 
locals
packet_size dd ?
mac_otk rb 64 ;256/8
iv rd 4
endl
DEBUGF 2, "< "
 
; Check how many bytes we should pad
mov eax, [payload_size]
inc eax ; padding length byte
lea edx, [eax+4] ; total packet size without padding and MAC
mov [packet_size], edx
 
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 [packet_size], edx ; total packet size with padding, without MAC
 
; Start building the packet
; First comes the packet length, in network byte order ofcourse.
add eax, edx
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)
mov edx, [con_ptr]
call MBRandom
mov dword[edi], eax
add edi, ebx
; Then, do as many aligned writes as nescessary
mov ebx, [con_ptr]
@@:
call MBRandom
stosd
dec esi
jnz @r
 
; Encrypt data length
lea eax, [iv]
mov dword[eax+0], 0
mov dword[eax+4], 0
mov dword[eax+8], 0
push [ebx+sshlib_connection.tx_mac_seqnr]
pop dword[eax+12]
 
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
 
; 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
 
; 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
 
; 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
 
; Write it to the send buffer
add edi, [packet_size]
movsd
movsd
movsd
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, [packet_size]
add esi, 16 ;[ebx+sshlib_connection.tx_mac_length]
mov edi, [flags]
mcall send
 
DEBUGF 2, "\n"
 
ret
 
endp
 
Property changes:
Added: svn:executable
+*
\ No newline at end of property