/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] |