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
|
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
|
||||||
@@:
|
@@:
|
||||||
|
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 '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:
|
||||||
|
@ -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]
|
||||||
|
Loading…
Reference in New Issue
Block a user