forked from KolibriOS/kolibrios
Pad with 0 bytes before encryption is set, as not to leak any entropy of RNG.
Little improved RNG seeding. Fixed bug in MAC counter for SSH transport. git-svn-id: svn://kolibrios.org@9071 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
parent
66f0a0e45d
commit
4f24fcab0f
@ -36,7 +36,6 @@ endg
|
||||
|
||||
proc init_random
|
||||
|
||||
mcall 26, 10 ; seed
|
||||
xor ecx, ecx
|
||||
; make random numbers and put them into buffer
|
||||
@@:
|
||||
|
77
programs/network/ssh/seed.inc
Normal file
77
programs/network/ssh/seed.inc
Normal file
@ -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
|
@ -51,6 +51,7 @@ include 'ssh_transport.inc'
|
||||
include 'dh_gex.inc'
|
||||
|
||||
include 'mpint.inc'
|
||||
include 'seed.inc'
|
||||
include 'random.inc'
|
||||
|
||||
include 'aes256.inc'
|
||||
@ -118,8 +119,11 @@ struct ssh_connection
|
||||
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
|
||||
|
||||
@ -189,6 +193,7 @@ start:
|
||||
jnz exit
|
||||
|
||||
DEBUGF 2, "SSH: Init PRNG\n"
|
||||
call create_seed
|
||||
call init_random
|
||||
|
||||
DEBUGF 2, "SSH: Init Console\n"
|
||||
@ -335,8 +340,9 @@ resolve:
|
||||
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 @@ resolve:
|
||||
test eax, eax
|
||||
jnz exit
|
||||
|
||||
; Set keys
|
||||
; Set keys and initialize transport subroutines
|
||||
|
||||
DEBUGF 2, "SSH: Setting encryption keys\n"
|
||||
|
||||
@ -446,7 +452,7 @@ resolve:
|
||||
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,7 +460,9 @@ resolve:
|
||||
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
|
||||
@ -464,6 +472,10 @@ resolve:
|
||||
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 @@ str14 db 10, 27, '[?25h', 27, '[0m', 0
|
||||
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:
|
||||
|
@ -24,6 +24,12 @@ struct ssh_packet_header
|
||||
message_code db ? ; First byte of payload
|
||||
ends
|
||||
|
||||
proc padding_zero
|
||||
|
||||
xor eax, eax
|
||||
ret
|
||||
|
||||
endp
|
||||
|
||||
proc ssh_recv_packet connection, flags
|
||||
|
||||
@ -127,14 +133,10 @@ endl
|
||||
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 @@ locals
|
||||
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
|
||||
|
||||
mov ebx, edx
|
||||
; 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
|
||||
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 @@ endl
|
||||
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]
|
||||
|
Loading…
Reference in New Issue
Block a user