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:
hidnplayr 2021-07-21 10:53:13 +00:00
parent 66f0a0e45d
commit 4f24fcab0f
4 changed files with 138 additions and 45 deletions

View File

@ -36,7 +36,6 @@ endg
proc init_random proc init_random
mcall 26, 10 ; seed
xor ecx, ecx xor ecx, ecx
; make random numbers and put them into buffer ; make random numbers and put them into buffer
@@: @@:

View 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

View File

@ -51,6 +51,7 @@ include 'ssh_transport.inc'
include 'dh_gex.inc' include 'dh_gex.inc'
include 'mpint.inc' include 'mpint.inc'
include 'seed.inc'
include 'random.inc' include 'random.inc'
include 'aes256.inc' include 'aes256.inc'
@ -118,8 +119,11 @@ struct ssh_connection
rx_crypt_blocksize dd ? rx_crypt_blocksize dd ?
tx_crypt_blocksize dd ? tx_crypt_blocksize dd ?
rx_padsize dd ? ; = Max(8, rx_crypt_blocksize) ; Padding
tx_padsize dd ? ; = Max(8, tx_crypt_blocksize)
; rx_padsize dd ? ; = Max(8, rx_crypt_blocksize)
tx_pad_size dd ? ; = Max(8, tx_crypt_blocksize)
tx_pad_proc dd ?
; Message authentication ; Message authentication
@ -189,6 +193,7 @@ start:
jnz exit jnz exit
DEBUGF 2, "SSH: Init PRNG\n" DEBUGF 2, "SSH: Init PRNG\n"
call create_seed
call init_random call init_random
DEBUGF 2, "SSH: Init Console\n" DEBUGF 2, "SSH: Init Console\n"
@ -335,8 +340,9 @@ resolve:
mov [con.tx_mac_proc], 0 mov [con.tx_mac_proc], 0
mov [con.rx_mac_length], 0 mov [con.rx_mac_length], 0
mov [con.tx_mac_length], 0 mov [con.tx_mac_length], 0
mov [con.rx_padsize], 8 ; minimum padsize ; mov [con.rx_padsize], 8 ; minimum padsize
mov [con.tx_padsize], 8 mov [con.tx_pad_size], 8
mov [con.tx_pad_proc], padding_zero
DEBUGF 2, "Sending KEX init\n" DEBUGF 2, "Sending KEX init\n"
mov edi, ssh_kex.cookie mov edi, ssh_kex.cookie
@ -436,7 +442,7 @@ resolve:
test eax, eax test eax, eax
jnz exit jnz exit
; Set keys ; Set keys and initialize transport subroutines
DEBUGF 2, "SSH: Setting encryption keys\n" DEBUGF 2, "SSH: Setting encryption keys\n"
@ -446,7 +452,7 @@ resolve:
stdcall aes256_set_encrypt_key, eax, con.rx_enc_key stdcall aes256_set_encrypt_key, eax, con.rx_enc_key
mov [con.rx_crypt_proc], aes256_ctr_crypt mov [con.rx_crypt_proc], aes256_ctr_crypt
mov [con.rx_crypt_blocksize], AES256_BLOCKSIZE 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 stdcall aes256_ctr_init, con.tx_iv
mov [con.tx_crypt_ctx_ptr], eax mov [con.tx_crypt_ctx_ptr], eax
@ -454,7 +460,9 @@ resolve:
stdcall aes256_set_encrypt_key, eax, con.tx_enc_key stdcall aes256_set_encrypt_key, eax, con.tx_enc_key
mov [con.tx_crypt_proc], aes256_ctr_crypt mov [con.tx_crypt_proc], aes256_ctr_crypt
mov [con.tx_crypt_blocksize], AES256_BLOCKSIZE 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 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_proc], hmac_sha256
@ -464,6 +472,10 @@ resolve:
mov [con.tx_mac_proc], hmac_sha256 mov [con.tx_mac_proc], hmac_sha256
mov [con.tx_mac_length], SHA256_HASH_SIZE 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 ; TODO: erase all keys from memory and free the memory
; >> Request service (user-auth) ; >> Request service (user-auth)
@ -778,7 +790,7 @@ str14 db 10, 27, '[?25h', 27, '[0m', 0
ssh_ident_ha: ssh_ident_ha:
dd_n (ssh_ident.length-2) dd_n (ssh_ident.length-2)
ssh_ident: 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 .length = $ - ssh_ident
ssh_kex: ssh_kex:

View File

@ -24,6 +24,12 @@ struct ssh_packet_header
message_code db ? ; First byte of payload message_code db ? ; First byte of payload
ends ends
proc padding_zero
xor eax, eax
ret
endp
proc ssh_recv_packet connection, flags proc ssh_recv_packet connection, flags
@ -127,14 +133,10 @@ endl
repe cmpsd repe cmpsd
jne .mac_failed jne .mac_failed
.mac_complete: .mac_complete:
inc byte[ebx+ssh_connection.rx_seq+3] ; Update sequence counter add byte[ebx+ssh_connection.rx_seq+3], 1 ; Update sequence counter
jnc @f adc byte[ebx+ssh_connection.rx_seq+2], 0
inc byte[ebx+ssh_connection.rx_seq+2] adc byte[ebx+ssh_connection.rx_seq+1], 0
jnc @f adc byte[ebx+ssh_connection.rx_seq+0], 0
inc byte[ebx+ssh_connection.rx_seq+1]
jnc @f
inc byte[ebx+ssh_connection.rx_seq+0]
@@:
; Return useful data length to the caller via eax register ; Return useful data length to the caller via eax register
.got_all_data: .got_all_data:
@ -166,56 +168,63 @@ locals
endl endl
DEBUGF 2, "< " DEBUGF 2, "< "
; Pad the packet with random data ; Check how many bytes we should pad
mov eax, [payload_size] mov eax, [payload_size]
inc eax ; padding length byte inc eax ; padding length byte
lea edx, [eax+4] ; total packet size (without padding and MAC) lea edx, [eax+4] ; total packet size (without padding and MAC)
mov [packet_size], edx mov [packet_size], edx
mov ecx, [connection] mov ecx, [connection]
mov ebx, [ecx+ssh_connection.tx_padsize] mov ebx, [ecx+ssh_connection.tx_pad_size]
dec ebx dec ebx
and edx, ebx and edx, ebx
neg edx neg edx
add edx, [ecx+ssh_connection.tx_padsize] add edx, [ecx+ssh_connection.tx_pad_size]
cmp edx, 4 ; minimum padding size add edx, [ecx+ssh_connection.tx_pad_size]
jae @f
add edx, [ecx+ssh_connection.tx_padsize]
@@:
DEBUGF 1, "padding %u bytes ", edx 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 add eax, edx
DEBUGF 1, "total size: %u ", eax DEBUGF 1, "total size: %u ", eax
bswap eax bswap eax
lea edi, [ecx+ssh_connection.tx_buffer] lea edi, [ecx+ssh_connection.tx_buffer]
stosd ; packet_length stosd
; Then the padding length
mov al, dl mov al, dl
stosb ; padding_length stosb
; And the actual payload bytes
mov esi, [buf] mov esi, [buf]
mov ecx, [payload_size] mov ecx, [payload_size]
rep movsb 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 mov esi, edx
shr esi, 2 ; number dwords
mov ebx, edx
and ebx, 3 and ebx, 3
jz @f inc ebx ; number bytes in first write (1-4)
call MBRandom mov edx, [connection]
call [edx+ssh_connection.tx_pad_proc]
mov dword[edi], eax mov dword[edi], eax
add edi, ebx add edi, ebx
; Then, do as many aligned writes as nescessary
mov ebx, [connection]
@@: @@:
call [ebx+ssh_connection.tx_pad_proc]
shr esi, 2
@@:
call MBRandom
stosd stosd
dec esi dec esi
jnz @r jnz @r
; Message authentication ; Append the packet with Message Authentication Code
mov edx, [connection] mov edx, [connection]
cmp [edx+ssh_connection.tx_mac_proc], 0 cmp [edx+ssh_connection.tx_mac_proc], 0
je .mac_complete 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] lea esi, [edx+ssh_connection.tx_seq]
mov ecx, [packet_size] mov ecx, [packet_size]
add ecx, 4 ; Sequence number length add ecx, 4 ; Sequence number length
@ -229,16 +238,12 @@ endl
shr ecx, 2 shr ecx, 2
rep movsd rep movsd
.mac_complete: .mac_complete:
inc byte[edx+ssh_connection.tx_seq+3] ; Update sequence counter add byte[edx+ssh_connection.tx_seq+3], 1 ; Update sequence counter
jnc @f adc byte[edx+ssh_connection.tx_seq+2], 0
inc byte[edx+ssh_connection.tx_seq+2] adc byte[edx+ssh_connection.tx_seq+1], 0
jnc @f adc byte[edx+ssh_connection.tx_seq+0], 0
inc byte[edx+ssh_connection.tx_seq+1]
jnc @f
inc byte[edx+ssh_connection.tx_seq+0]
@@:
; Encrypt data ; Now, encrypt everything but MAC
cmp [edx+ssh_connection.tx_crypt_proc], 0 cmp [edx+ssh_connection.tx_crypt_proc], 0
je .encrypt_complete je .encrypt_complete
lea esi, [edx+ssh_connection.tx_buffer] lea esi, [edx+ssh_connection.tx_buffer]