Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 9070 → Rev 9071

/programs/network/ssh/random.inc
36,7 → 36,6
 
proc init_random
 
mcall 26, 10 ; seed
xor ecx, ecx
; make random numbers and put them into buffer
@@:
/programs/network/ssh/seed.inc
0,0 → 1,77
; seed.inc - Collect some entropy from KolibriOS system
;
; Copyright (C) 2021 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 4
create_seed:
 
push ebx edx
 
mcall 3 ; System time
xor edx, eax
rol edx, 1
mcall 14 ; Screen size
xor edx, eax
rol edx, 1
mcall 18, 4 ; Idle time counter
xor edx, eax
rol edx, 1
mcall 18, 5 ; CPU clock rate
xor edx, eax
rol edx, 1
mcall 18, 7 ; Active window slot
xor edx, eax
rol edx, 1
mcall 18, 16 ; Free RAM space
xor edx, eax
rol edx, 1
mcall 18, 17 ; Total RAM space
xor edx, eax
rol edx, 1
mcall 18, 21 ; Active window slot
xor edx, eax
rol edx, 1
mcall 26, 10 ; High precision time counter
xor edx, eax
rol edx, 1
xor edx, ebx
rol edx, 1
mcall 37, 0 ; Screen coordinates of the cursor
xor edx, eax
rol edx, 1
mcall 54, 0 ; Number of slots on the clipboard
xor edx, eax
rol edx, 1
mcall 66, 3 ; Status of the keyboard control keys
xor edx, eax
rol edx, 1
mcall 68, 0 ; Task switch counter
xor edx, eax
rol edx, 1
mcall 74, 0x108 ; Network interface 1 TX bytes counter
xor edx, eax
rol edx, 1
mcall 74, 0x109 ; Network interface 1 RX bytes counter
xor edx, eax
rol edx, 1
mcall 76, 0x100 ; Network interface 1 MAC address
xor eax, ebx
xor eax, edx
 
pop edx ebx
 
ret
/programs/network/ssh/ssh.asm
51,6 → 51,7
include 'dh_gex.inc'
 
include 'mpint.inc'
include 'seed.inc'
include 'random.inc'
 
include 'aes256.inc'
118,9 → 119,12
rx_crypt_blocksize dd ?
tx_crypt_blocksize dd ?
 
rx_padsize dd ? ; = Max(8, rx_crypt_blocksize)
tx_padsize dd ? ; = Max(8, tx_crypt_blocksize)
; Padding
 
; rx_padsize dd ? ; = Max(8, rx_crypt_blocksize)
tx_pad_size dd ? ; = Max(8, tx_crypt_blocksize)
tx_pad_proc dd ?
 
; Message authentication
 
rx_mac_proc dd ?
189,6 → 193,7
jnz exit
 
DEBUGF 2, "SSH: Init PRNG\n"
call create_seed
call init_random
 
DEBUGF 2, "SSH: Init Console\n"
335,8 → 340,9
mov [con.tx_mac_proc], 0
mov [con.rx_mac_length], 0
mov [con.tx_mac_length], 0
mov [con.rx_padsize], 8 ; minimum padsize
mov [con.tx_padsize], 8
; mov [con.rx_padsize], 8 ; minimum padsize
mov [con.tx_pad_size], 8
mov [con.tx_pad_proc], padding_zero
 
DEBUGF 2, "Sending KEX init\n"
mov edi, ssh_kex.cookie
436,7 → 442,7
test eax, eax
jnz exit
 
; Set keys
; Set keys and initialize transport subroutines
 
DEBUGF 2, "SSH: Setting encryption keys\n"
 
446,7 → 452,7
stdcall aes256_set_encrypt_key, eax, con.rx_enc_key
mov [con.rx_crypt_proc], aes256_ctr_crypt
mov [con.rx_crypt_blocksize], AES256_BLOCKSIZE
mov [con.rx_padsize], AES256_BLOCKSIZE
; mov [con.rx_pad_size], AES256_BLOCKSIZE
 
stdcall aes256_ctr_init, con.tx_iv
mov [con.tx_crypt_ctx_ptr], eax
454,8 → 460,10
stdcall aes256_set_encrypt_key, eax, con.tx_enc_key
mov [con.tx_crypt_proc], aes256_ctr_crypt
mov [con.tx_crypt_blocksize], AES256_BLOCKSIZE
mov [con.tx_padsize], AES256_BLOCKSIZE
 
mov [con.tx_pad_size], AES256_BLOCKSIZE
mov [con.tx_pad_proc], MBRandom
 
stdcall hmac_sha256_setkey, con.rx_mac_ctx, con.rx_int_key, SHA256_HASH_SIZE
mov [con.rx_mac_proc], hmac_sha256
mov [con.rx_mac_length], SHA256_HASH_SIZE
464,6 → 472,10
mov [con.tx_mac_proc], hmac_sha256
mov [con.tx_mac_length], SHA256_HASH_SIZE
 
; Re-seed RNG for padding bytes
call create_seed
call init_random
 
; TODO: erase all keys from memory and free the memory
 
; >> Request service (user-auth)
778,7 → 790,7
ssh_ident_ha:
dd_n (ssh_ident.length-2)
ssh_ident:
db "SSH-2.0-KolibriOS_SSH_0.03",13,10
db "SSH-2.0-KolibriOS_SSH_0.04",13,10
.length = $ - ssh_ident
 
ssh_kex:
/programs/network/ssh/ssh_transport.inc
24,7 → 24,13
message_code db ? ; First byte of payload
ends
 
proc padding_zero
 
xor eax, eax
ret
 
endp
 
proc ssh_recv_packet connection, flags
 
locals
127,14 → 133,10
repe cmpsd
jne .mac_failed
.mac_complete:
inc byte[ebx+ssh_connection.rx_seq+3] ; Update sequence counter
jnc @f
inc byte[ebx+ssh_connection.rx_seq+2]
jnc @f
inc byte[ebx+ssh_connection.rx_seq+1]
jnc @f
inc byte[ebx+ssh_connection.rx_seq+0]
@@:
add byte[ebx+ssh_connection.rx_seq+3], 1 ; Update sequence counter
adc byte[ebx+ssh_connection.rx_seq+2], 0
adc byte[ebx+ssh_connection.rx_seq+1], 0
adc byte[ebx+ssh_connection.rx_seq+0], 0
 
; Return useful data length to the caller via eax register
.got_all_data:
166,56 → 168,63
endl
DEBUGF 2, "< "
 
; Pad the packet with random data
; 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, [connection]
mov ebx, [ecx+ssh_connection.tx_padsize]
mov ebx, [ecx+ssh_connection.tx_pad_size]
dec ebx
and edx, ebx
neg edx
add edx, [ecx+ssh_connection.tx_padsize]
cmp edx, 4 ; minimum padding size
jae @f
add edx, [ecx+ssh_connection.tx_padsize]
@@:
add edx, [ecx+ssh_connection.tx_pad_size]
add edx, [ecx+ssh_connection.tx_pad_size]
DEBUGF 1, "padding %u bytes ", edx
add [packet_size], 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 1, "total size: %u ", eax
bswap eax
lea edi, [ecx+ssh_connection.tx_buffer]
stosd ; packet_length
stosd
; Then the padding length
mov al, dl
stosb ; padding_length
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
mov esi, edx
and ebx, 3
jz @f
call MBRandom
inc ebx ; number bytes in first write (1-4)
mov edx, [connection]
call [edx+ssh_connection.tx_pad_proc]
mov dword[edi], eax
add edi, ebx
; Then, do as many aligned writes as nescessary
mov ebx, [connection]
@@:
 
shr esi, 2
@@:
call MBRandom
call [ebx+ssh_connection.tx_pad_proc]
stosd
dec esi
jnz @r
 
; Message authentication
; Append the packet with Message Authentication Code
mov edx, [connection]
cmp [edx+ssh_connection.tx_mac_proc], 0
je .mac_complete
; DEBUGF 1, "MAC sequence number: 0x%x\n", [edx+ssh_connection.tx_seq]
DEBUGF 1, "MAC sequence number: 0x%x\n", [edx+ssh_connection.tx_seq]
lea esi, [edx+ssh_connection.tx_seq]
mov ecx, [packet_size]
add ecx, 4 ; Sequence number length
229,16 → 238,12
shr ecx, 2
rep movsd
.mac_complete:
inc byte[edx+ssh_connection.tx_seq+3] ; Update sequence counter
jnc @f
inc byte[edx+ssh_connection.tx_seq+2]
jnc @f
inc byte[edx+ssh_connection.tx_seq+1]
jnc @f
inc byte[edx+ssh_connection.tx_seq+0]
@@:
add byte[edx+ssh_connection.tx_seq+3], 1 ; Update sequence counter
adc byte[edx+ssh_connection.tx_seq+2], 0
adc byte[edx+ssh_connection.tx_seq+1], 0
adc byte[edx+ssh_connection.tx_seq+0], 0
 
; Encrypt data
; Now, encrypt everything but MAC
cmp [edx+ssh_connection.tx_crypt_proc], 0
je .encrypt_complete
lea esi, [edx+ssh_connection.tx_buffer]