Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 9990 → Rev 9991

/programs/network/ssh/ssh.asm
478,7 → 478,7
ssh_ident_ha:
dd_n (ssh_msg_ident.length-2)
ssh_msg_ident:
db "SSH-2.0-KolibriOS_SSH_0.11",13,10
db "SSH-2.0-KolibriOS_SSH_0.12",13,10
.length = $ - ssh_msg_ident
 
 
491,13 → 491,13
.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,chacha20-poly1305@openssh.com" ;aes192-ctr,aes192-cbc,aes128-ctr,aes128-cbc ?
str "chacha20-poly1305@openssh.com,aes256-ctr,aes256-cbc" ;aes192-ctr,aes192-cbc,aes128-ctr,aes128-cbc ?
.encryption_algorithms_server_to_client:
str "aes256-ctr";,aes256-cbc,chacha20-poly1305@openssh.com" ;aes192-ctr,aes192-cbc,aes128-ctr,aes128-cbc ?
str "chacha20-poly1305@openssh.com,aes256-ctr,aes256-cbc" ;aes192-ctr,aes192-cbc,aes128-ctr,aes128-cbc ?
.mac_algorithms_client_to_server:
str "hmac-sha2-256-etm@openssh.com";,hmac-sha2-512-etm@openssh.com,hmac-sha2-256,hmac-sha2-512"
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-etm@openssh.com";,hmac-sha2-512-etm@openssh.com,hmac-sha2-256,hmac-sha2-512"
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 ?
.compression_algorithms_server_to_client:
/programs/network/ssh/sshlib.inc
1,6 → 1,6
; sshlib.inc - SSHlib constants
;
; 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
28,6 → 28,7
SSHLIB_ERR_HKEY_VERIFY_FAIL = -8
SSHLIB_ERR_HKEY_SIGNATURE = -9
SSHLIB_ERR_HKEY_PUBLIC_KEY = -10
SSHLIB_ERR_NO_ALGO = -11
 
; Channel status codes
 
44,30 → 45,90
 
; Algorithm identifier codes
 
SSHLIB_ALGO_NONE = 0
SSHLIB_ALGO_FAIL = 0
SSHLIB_ALGO_NONE = 1
 
SSHLIB_KEX_DH_SHA256 = 1 ; diffie-hellman-group-exchange-sha256
SSHLIB_KEX_DH_SHA256 = 2
 
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_HOSTKEY_DSS = 2
SSHLIB_HOSTKEY_RSA_SHA1 = 3
SSHLIB_HOSTKEY_RSA_SHA2_256 = 4
SSHLIB_HOSTKEY_RSA_SHA2_512 = 5
 
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_CRYPT_AES128_CTR = 2
SSHLIB_CRYPT_AES128_CBC = 3
SSHLIB_CRYPT_AES192_CTR = 4
SSHLIB_CRYPT_AES192_CBC = 5
SSHLIB_CRYPT_AES256_CTR = 6
SSHLIB_CRYPT_AES256_CBC = 7
SSHLIB_CRYPT_CHACHA20_POLY1305 = 8
 
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_MAC_HMAC_SHA2_256 = 2
SSHLIB_MAC_HMAC_SHA2_512 = 3
SSHLIB_MAC_HMAC_SHA2_256_ETM = 4
SSHLIB_MAC_HMAC_SHA2_512_ETM = 5
 
SSHLIB_COMPR_ZLIB = 1 ; zlib
SSHLIB_COMPR_NONE = 2
SSHLIB_COMPR_ZLIB = 3
 
iglobal
algorithms_kex:
dd SSHLIB_KEX_DH_SHA256
db "diffie-hellman-group-exchange-sha256", 0
dd 0
 
algorithms_hostkey:
dd SSHLIB_HOSTKEY_DSS
db "ssh-dss", 0
dd SSHLIB_HOSTKEY_RSA_SHA1
db "ssh-rsa ", 0
dd SSHLIB_HOSTKEY_RSA_SHA2_256
db "rsa-sha2-256", 0
dd SSHLIB_HOSTKEY_RSA_SHA2_512
db "rsa-sha2-512", 0
dd 0
 
algorithms_crypt:
;dd SSHLIB_CRYPT_AES128_CTR
;db "aes128-ctr", 0
;dd SSHLIB_CRYPT_AES128_CBC
;db "aes128-cbc", 0
;dd SSHLIB_CRYPT_AES192_CTR
;db "aes192-cbc", 0
;dd SSHLIB_CRYPT_AES192_CBC
;db "aes192-ctr", 0
dd SSHLIB_CRYPT_AES256_CTR
db "aes256-ctr", 0
dd SSHLIB_CRYPT_AES256_CBC
db "aes256-cbc", 0
dd SSHLIB_CRYPT_CHACHA20_POLY1305
db "chacha20-poly1305@openssh.com", 0
dd 0
 
algorithms_mac:
dd SSHLIB_MAC_HMAC_SHA2_256
db "hmac-sha2-256", 0
dd SSHLIB_MAC_HMAC_SHA2_512
db "hmac-sha2-512", 0
dd SSHLIB_MAC_HMAC_SHA2_256_ETM
db "hmac-sha2-256-etm@openssh.com", 0
dd SSHLIB_MAC_HMAC_SHA2_512_ETM
db "hmac-sha2-512-etm@openssh.com", 0
dd 0
 
algorithms_compression:
dd SSHLIB_COMPR_NONE
db "none"
;dd SSHLIB_COMPR_ZLIB
;db "zlib@openssh.com", 0
dd 0
 
languages:
dd 0
db 0
 
endg
 
; Hostkey
 
SSHLIB_HOSTKEY_PROBLEM_UNKNOWN = 0
/programs/network/ssh/sshlib_connection.inc
202,67 → 202,69
cmp eax, -1
je .err_sock
 
mov esi, [con_ptr]
cmp [esi + sshlib_connection.rx_buffer.message_code], SSH_MSG_KEXINIT
mov ebx, [con_ptr]
cmp [ebx + sshlib_connection.rx_buffer.message_code], SSH_MSG_KEXINIT
jne .err_proto
DEBUGF 2, "Received KEX init\n"
lea esi, [ebx + sshlib_connection.rx_buffer + sizeof.ssh_packet_header + 16]
 
lea esi, [esi + sshlib_connection.rx_buffer + sizeof.ssh_packet_header + 16]
lodsd
bswap eax
DEBUGF 1, "kex_algorithms: %s\n", esi
add esi, eax
lodsd
bswap eax
DEBUGF 1, "server_host_key_algorithms: %s\n", esi
add esi, eax
lodsd
bswap eax
DEBUGF 1, "encryption_algorithms_client_to_server: %s\n", esi
add esi, eax
lodsd
bswap eax
DEBUGF 1, "encryption_algorithms_server_to_client: %s\n", esi
add esi, eax
lodsd
bswap eax
DEBUGF 1, "mac_algorithms_client_to_server: %s\n", esi
add esi, eax
lodsd
bswap eax
DEBUGF 1, "mac_algorithms_server_to_client: %s\n", esi
add esi, eax
lodsd
bswap eax
DEBUGF 1, "compression_algorithms_client_to_server: %s\n", esi
add esi, eax
lodsd
bswap eax
DEBUGF 1, "compression_algorithms_server_to_client: %s\n", esi
add esi, eax
lodsd
bswap eax
DEBUGF 1, "languages_client_to_server: %s\n", esi
add esi, eax
lodsd
bswap eax
DEBUGF 1, "languages_server_to_client: %s\n", esi
add esi, eax
DEBUGF 2, "kex_algorithm "
stdcall sshlib_algo_find_match, ssh_msg_kex.kex_algorithms, algorithms_kex
test eax, eax
jz .err_no_algo
mov [ebx + sshlib_connection.algo_kex], eax
 
DEBUGF 2, "server_host_key_algorithm "
stdcall sshlib_algo_find_match, ssh_msg_kex.server_host_key_algorithms, algorithms_hostkey
test eax, eax
jz .err_no_algo
mov [ebx + sshlib_connection.algo_hostkey], eax
 
DEBUGF 2, "encryption_algorithm_client_to_server "
stdcall sshlib_algo_find_match, ssh_msg_kex.encryption_algorithms_client_to_server, algorithms_crypt
test eax, eax
jz .err_no_algo
mov [ebx + sshlib_connection.algo_crypt_tx], eax
 
DEBUGF 2, "encryption_algorithm_server_to_client ",
stdcall sshlib_algo_find_match, ssh_msg_kex.encryption_algorithms_server_to_client, algorithms_crypt
test eax, eax
jz .err_no_algo
mov [ebx + sshlib_connection.algo_crypt_rx], eax
 
DEBUGF 2, "mac_algorithm_client_to_server "
stdcall sshlib_algo_find_match, ssh_msg_kex.mac_algorithms_client_to_server, algorithms_mac
test eax, eax
jz .err_no_algo
mov [ebx + sshlib_connection.algo_mac_tx], eax
 
DEBUGF 2, "mac_algorithm_server_to_client "
stdcall sshlib_algo_find_match, ssh_msg_kex.mac_algorithms_server_to_client, algorithms_mac
test eax, eax
jz .err_no_algo
mov [ebx + sshlib_connection.algo_mac_rx], eax
 
DEBUGF 2, "compression_algorithm_client_to_server "
stdcall sshlib_algo_find_match, ssh_msg_kex.compression_algorithms_client_to_server, algorithms_compression
test eax, eax
jz .err_no_algo
mov [ebx + sshlib_connection.algo_compr_tx], eax
 
DEBUGF 2, "compression_algorithm_server_to_client "
stdcall sshlib_algo_find_match, ssh_msg_kex.compression_algorithms_server_to_client, algorithms_compression
test eax, eax
jz .err_no_algo
mov [ebx + sshlib_connection.algo_compr_rx], eax
 
DEBUGF 2, "language_client_to_server "
stdcall sshlib_algo_find_match, ssh_msg_kex.languages_client_to_server, languages
 
DEBUGF 2, "language_server_to_client "
stdcall sshlib_algo_find_match, ssh_msg_kex.languages_server_to_client, languages
 
lodsb
DEBUGF 1, "KEX First Packet Follows: %u\n", al
DEBUGF 2, "KEX First Packet Follows: %u\n", al
 
; TODO: parse this structure and set algorithm codes accordingly
; FIXME: hardcoded for now
mov esi, [con_ptr]
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 ; 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]
mov eax, [esi+sshlib_connection.rx_buffer.packet_length]
277,6 → 279,10
 
; Exchange keys with the server
 
mov ebx, [con_ptr]
cmp [ebx + sshlib_connection.algo_kex], SSHLIB_KEX_DH_SHA256 ; only kex algo supported for now
jne .err_no_algo
 
stdcall sshlib_dh_gex, [con_ptr]
test eax, eax
jnz .err
323,13 → 329,13
 
 
.have_rx_crypt:
cmp [ebx + sshlib_connection.algo_mac_rx], SSHLIB_HMAC_SHA2_256
cmp [ebx + sshlib_connection.algo_mac_rx], SSHLIB_MAC_HMAC_SHA2_256
je .rx_hmac_sha2_256
cmp [ebx + sshlib_connection.algo_mac_rx], SSHLIB_HMAC_SHA2_512
cmp [ebx + sshlib_connection.algo_mac_rx], SSHLIB_MAC_HMAC_SHA2_512
je .rx_hmac_sha2_512
cmp [ebx + sshlib_connection.algo_mac_rx], SSHLIB_HMAC_SHA2_256_ETM
cmp [ebx + sshlib_connection.algo_mac_rx], SSHLIB_MAC_HMAC_SHA2_256_ETM
je .rx_hmac_sha2_256_etm
cmp [ebx + sshlib_connection.algo_mac_rx], SSHLIB_HMAC_SHA2_512_ETM
cmp [ebx + sshlib_connection.algo_mac_rx], SSHLIB_MAC_HMAC_SHA2_512_ETM
je .rx_hmac_sha2_512_etm
 
jmp .err_proto
403,13 → 409,13
 
 
.have_tx_crypt:
cmp [ebx + sshlib_connection.algo_mac_tx], SSHLIB_HMAC_SHA2_256
cmp [ebx + sshlib_connection.algo_mac_tx], SSHLIB_MAC_HMAC_SHA2_256
je .tx_hmac_sha2_256
cmp [ebx + sshlib_connection.algo_mac_tx], SSHLIB_HMAC_SHA2_512
cmp [ebx + sshlib_connection.algo_mac_tx], SSHLIB_MAC_HMAC_SHA2_512
je .tx_hmac_sha2_512
cmp [ebx + sshlib_connection.algo_mac_tx], SSHLIB_HMAC_SHA2_256_ETM
cmp [ebx + sshlib_connection.algo_mac_tx], SSHLIB_MAC_HMAC_SHA2_256_ETM
je .tx_hmac_sha2_256_etm
cmp [ebx + sshlib_connection.algo_mac_tx], SSHLIB_HMAC_SHA2_512_ETM
cmp [ebx + sshlib_connection.algo_mac_tx], SSHLIB_MAC_HMAC_SHA2_512_ETM
je .tx_hmac_sha2_512_etm
 
jmp .err_proto
445,7 → 451,6
 
.have_tx_crypt_and_mac:
 
 
; Re-seed RNG for padding bytes
 
call create_seed
454,6 → 459,10
xor eax, eax
ret
 
.err_no_algo:
mov eax, SSHLIB_ERR_NO_ALGO
ret
 
.err_hostname:
mov eax, SSHLIB_ERR_HOSTNAME
ret
473,7 → 482,145
 
 
 
proc sshlib_algo_find_match uses ebx ecx edx edi, client_str, algo_list
 
locals
server_str dd ?
next_str dd ?
current dd ?
endl
 
lodsd
mov [server_str], esi
bswap eax
lea ecx, [esi + eax]
mov [next_str], ecx
 
mov edi, [client_str]
mov edx, dword[edi]
bswap edx
add edi, 4
add edx, edi ; end of string
 
.go:
mov [current], edi
.cmp:
cmp esi, ecx
jae .end_of_s
mov al, byte[esi]
inc esi
.cmp_1:
cmp edi, edx
jae .end_of_c
mov bl, byte[edi]
inc edi
.cmp_2:
cmp al, bl
jne .mismatch
 
cmp al, ','
jne .cmp
 
; algo matches, print it to debug board
DEBUGF 2, "= "
mov edi, [current]
@@:
cmp edi, edx
jae @f
mov cl, byte[edi]
cmp cl, ','
je @f
mcall 63, 1
inc edi
jmp @r
@@:
; mcall 63, 1, 10 ; print newline
 
; and now find it in algo list
mov esi, [algo_list]
.algo_loop:
mov edi, [current]
lodsd
mov ebx, eax ; algo code
test eax, eax
jz .no_match
 
.algo_charloop:
lodsb
test al, al
jz .check_end
cmp al, byte[edi]
jne .next_algo
inc edi
cmp edi, edx
jb .algo_charloop
; we reached end of input, check end of algo token
cmp byte[esi], 0
je .algo_match
jmp .next_algo
; we reached end of algo token, check end of input
.check_end:
cmp byte[edi], ','
je .algo_match
 
.next_algo_loop:
lodsb
.next_algo:
test al, al
jnz .next_algo_loop
jmp .algo_loop
 
.algo_match:
mov eax, ebx
mov esi, [next_str]
DEBUGF 2," (%u)\n", eax
ret
 
.end_of_s:
mov al, ','
jmp .cmp_1
 
.end_of_c:
mov bl, ','
jmp .cmp_2
 
.mismatch:
; character mismatch, reset client str and go to next server token
mov edi, [current]
@@:
mov al, byte[esi]
inc esi
 
cmp al, ','
je .cmp
 
cmp esi, ecx
jb @r
 
; end of server str, reset it and go to next client token
mov esi, [server_str]
@@:
mov bl, byte[edi]
inc edi
 
cmp bl, ','
je .go
 
cmp edi, edx
jb @r
 
; end of client str, no match found
.no_match:
xor eax, eax
mov esi, [next_str]
DEBUGF 2," (%u)\n", eax
ret
 
endp
 
 
 
 
; Handle common messages and return to caller for specific ones
proc sshlib_msg_handler, con_ptr, flags
 
/programs/network/ssh/sshlib_dh_gex.inc
87,7 → 87,7
;----------------------------------------------
; >> Send Diffie-Hellman Group Exchange Request
 
DEBUGF 2, "Sending GEX\n"
DEBUGF 2, "Sending DH group exchange request\n"
stdcall sshlib_send_packet, [con_ptr], ssh_msg_gex_req, ssh_msg_gex_req.length, 0
cmp eax, 0
jl .err
102,7 → 102,7
mov ebx, [con_ptr]
cmp [ebx + sshlib_connection.rx_buffer.message_code], SSH_MSG_KEX_DH_GEX_GROUP
jne .err_proto
DEBUGF 2, "Received GEX group\n"
DEBUGF 2, "Received DH group\n"
 
lea esi, [ebx + sshlib_connection.rx_buffer + sizeof.ssh_packet_header]
stdcall mpint_to_little_endian, [mpint_p], esi
151,7 → 151,7
stdcall mpint_to_big_endian, edi, [mpint_e]
 
DEBUGF 2, "Sending GEX init\n"
mov ecx, dword[ebx + sshlib_connection.tx_buffer.message_code+1] ;;;; dword[edi]
mov ecx, dword[ebx + sshlib_connection.tx_buffer.message_code+1]
bswap ecx
add ecx, 5
lea esi, [ebx + sshlib_connection.tx_buffer.message_code]
263,7 → 263,7
; If first KEX, verify host public key
stdcall sshlib_host_verify, [con_ptr], [str_K_S], [str_s_of_H], [H], SHA2_256_LEN
test eax, eax
jnz .err
jnz .err_hostkey_verification
 
mov eax, [con_ptr]
mov esi, [H]
280,6 → 280,8
;-------------------------------------
; << Parse Diffie-Hellman New Keys MSG
 
DEBUGF 2, "Expecting New Keys message\n"
 
stdcall sshlib_recv_packet, [con_ptr], 0
cmp eax, 0
jl .err
458,6 → 460,10
pop eax
ret
 
.err_hostkey_verification:
DEBUGF 3, "Hostkey verification failed!\n"
jmp .err
 
.err_nomem:
DEBUGF 3, "Out of memory during key exchange!\n"
mov eax, SSHLIB_ERR_NOMEM
/programs/network/ssh/sshlib_host.inc
1,6 → 1,6
; sshlib_host.inc - SSH remote host authentication
;
; Copyright (C) 2021 Jeffrey Amelynck
; Copyright (C) 2021-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
30,17 → 30,22
current_hk64_end dd ?
endl
 
DEBUGF 2, "Verifying host key\n"
 
mov eax, [con_ptr]
lea ebx, [eax + sshlib_connection.hostname_sz]
mov [hostname_sz], ebx
cmp [eax+sshlib_connection.algo_hostkey], SSHLIB_HOSTKEY_RSA
cmp [eax+sshlib_connection.algo_hostkey], SSHLIB_HOSTKEY_RSA_SHA1
je .rsa
; ..add more here
cmp [eax+sshlib_connection.algo_hostkey], SSHLIB_HOSTKEY_RSA_SHA2_256
je .rsa
cmp [eax+sshlib_connection.algo_hostkey], SSHLIB_HOSTKEY_RSA_SHA2_512
je .rsa
mov eax, SSHLIB_ERR_HKEY_NO_ALGO
ret
 
.rsa:
stdcall sshlib_host_verify_rsa, [str_host_key], [str_signature], [message], [message_len]
stdcall sshlib_host_verify_rsa, [con_ptr], [str_host_key], [str_signature], [message], [message_len]
test eax, eax
jnz .err
mov [key_name_sz], ssh_rsa_sz
82,7 → 87,6
ret
 
.mismatch:
int3
lea eax, [current_hkb64]
stdcall sshlib_callback_hostkey_problem, [con_ptr], SSHLIB_HOSTKEY_PROBLEM_MISMATCH, eax
cmp eax, SSHLIB_HOSTKEY_ACCEPT
112,7 → 116,7
 
; https://datatracker.ietf.org/doc/html/rfc3447#section-8.2.2
; RSASSA-PKCS1-V1_5-VERIFY
proc sshlib_host_verify_rsa str_host_key, str_signature, M, message_len
proc sshlib_host_verify_rsa con_ptr, str_host_key, str_signature, M, message_len
 
locals
h_ctx dd ?
204,6 → 208,10
jmp .err_signature
 
.sha1:
mov eax, [con_ptr]
cmp [eax + sshlib_connection.algo_hostkey], SSHLIB_HOSTKEY_RSA_SHA1
jne .err_signature
 
DEBUGF 3, "SSH: Using RSA with SHA1 hash\n"
add esi, 4+4+7
push esi
238,6 → 246,9
jmp .rsa
 
.sha2_256:
mov eax, [con_ptr]
cmp [eax + sshlib_connection.algo_hostkey], SSHLIB_HOSTKEY_RSA_SHA2_256
jne .err_signature
DEBUGF 3, "SSH: Using RSA with SHA2-256 hash\n"
add esi, 4+4+12
push esi
272,6 → 283,9
jmp .rsa
 
.sha2_512:
mov eax, [con_ptr]
cmp [eax + sshlib_connection.algo_hostkey], SSHLIB_HOSTKEY_RSA_SHA2_512
jne .err_signature
DEBUGF 3, "SSH: Using RSA with SHA2-512 hash\n"
add esi, 4+4+12
push esi