forked from KolibriOS/kolibrios
SSH client part 1: Diffie hellman group exchange.
git-svn-id: svn://kolibrios.org@6419 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
parent
7abeb6e7e3
commit
f119560b2d
2
programs/network/ssh/Tupfile.lua
Normal file
2
programs/network/ssh/Tupfile.lua
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
if tup.getconfig("NO_FASM") ~= "" then return end
|
||||||
|
tup.rule("ssh.asm", "fasm %f %o " .. tup.getconfig("KPACK_CMD"), "ssh")
|
123
programs/network/ssh/aes256-cbc.inc
Normal file
123
programs/network/ssh/aes256-cbc.inc
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
; aes256-cbc.inc - AES256 Cipher Block Chaining
|
||||||
|
;
|
||||||
|
; Copyright (C) 2016 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/>.
|
||||||
|
|
||||||
|
struct aes256_cbc_context aes256_context
|
||||||
|
vector rb 16
|
||||||
|
ends
|
||||||
|
|
||||||
|
|
||||||
|
proc aes256_cbc_init _vector
|
||||||
|
push ebx esi edi
|
||||||
|
|
||||||
|
mcall 68, 12, sizeof.aes256_cbc_context
|
||||||
|
; handle errors
|
||||||
|
mov ecx, 16/4
|
||||||
|
mov esi, [_vector]
|
||||||
|
lea edi, [eax + aes256_cbc_context.vector]
|
||||||
|
rep movsd
|
||||||
|
; rep movsd is slow, but we don't care while init
|
||||||
|
|
||||||
|
pop edi esi ebx
|
||||||
|
ret
|
||||||
|
endp
|
||||||
|
|
||||||
|
proc aes256_cbc_encrypt _ctx, _in, _out
|
||||||
|
push ebx esi edi
|
||||||
|
|
||||||
|
DEBUGF 1,'plain : '
|
||||||
|
stdcall dump_128bit_hex, [_in]
|
||||||
|
DEBUGF 1,'\n'
|
||||||
|
|
||||||
|
mov edi, [_ctx]
|
||||||
|
lea edi, [edi + aes256_cbc_context.vector]
|
||||||
|
mov esi, [_in]
|
||||||
|
lodsd
|
||||||
|
xor eax, [edi]
|
||||||
|
stosd
|
||||||
|
lodsd
|
||||||
|
xor eax, [edi]
|
||||||
|
stosd
|
||||||
|
lodsd
|
||||||
|
xor eax, [edi]
|
||||||
|
stosd
|
||||||
|
lodsd
|
||||||
|
xor eax, [edi]
|
||||||
|
stosd
|
||||||
|
|
||||||
|
mov esi, [_ctx]
|
||||||
|
lea eax, [esi + aes256_cbc_context.key]
|
||||||
|
lea ebx, [esi + aes256_cbc_context.vector]
|
||||||
|
stdcall aes256_encrypt, eax, ebx, [_out] ; Key, in, out
|
||||||
|
|
||||||
|
mov esi, [_out]
|
||||||
|
mov eax, [_ctx]
|
||||||
|
lea edi, [eax + aes256_cbc_context.vector]
|
||||||
|
movsd
|
||||||
|
movsd
|
||||||
|
movsd
|
||||||
|
movsd
|
||||||
|
|
||||||
|
DEBUGF 1,'cipher : '
|
||||||
|
stdcall dump_128bit_hex, [_out]
|
||||||
|
DEBUGF 1,'\n\n'
|
||||||
|
|
||||||
|
pop edi esi ebx
|
||||||
|
ret
|
||||||
|
endp
|
||||||
|
|
||||||
|
proc aes256_cbc_decrypt _ctx, _in, _out
|
||||||
|
push ebx esi edi
|
||||||
|
|
||||||
|
DEBUGF 1,'cipher : '
|
||||||
|
stdcall dump_128bit_hex, [_in]
|
||||||
|
DEBUGF 1,'\n'
|
||||||
|
|
||||||
|
mov esi, [_ctx]
|
||||||
|
lea eax, [esi + aes256_cbc_context.key]
|
||||||
|
stdcall aes256_decrypt, eax, [_in], [_out] ; Key, in, out
|
||||||
|
|
||||||
|
mov esi, [_ctx]
|
||||||
|
lea esi, [esi + aes256_cbc_context.vector]
|
||||||
|
mov edi, [_out]
|
||||||
|
lodsd
|
||||||
|
xor eax, [edi]
|
||||||
|
stosd
|
||||||
|
lodsd
|
||||||
|
xor eax, [edi]
|
||||||
|
stosd
|
||||||
|
lodsd
|
||||||
|
xor eax, [edi]
|
||||||
|
stosd
|
||||||
|
lodsd
|
||||||
|
xor eax, [edi]
|
||||||
|
stosd
|
||||||
|
|
||||||
|
mov esi, [_in]
|
||||||
|
mov edi, [_ctx]
|
||||||
|
lea edi, [edi + aes256_cbc_context.vector]
|
||||||
|
movsd
|
||||||
|
movsd
|
||||||
|
movsd
|
||||||
|
movsd
|
||||||
|
|
||||||
|
DEBUGF 1,'plain : '
|
||||||
|
stdcall dump_128bit_hex, [_out]
|
||||||
|
DEBUGF 1,'\n\n'
|
||||||
|
|
||||||
|
pop edi esi ebx
|
||||||
|
ret
|
||||||
|
endp
|
109
programs/network/ssh/aes256-ctr.inc
Normal file
109
programs/network/ssh/aes256-ctr.inc
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
; aes256-ctr.inc - AES256 Counter Mode
|
||||||
|
;
|
||||||
|
; Copyright (C) 2016 Ivan Baravy (dunkaist)
|
||||||
|
;
|
||||||
|
; 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/>.
|
||||||
|
|
||||||
|
struct aes256_ctr_context aes256_context
|
||||||
|
counter rb 16
|
||||||
|
output rb 16 ; counter after aes_crypt
|
||||||
|
ends
|
||||||
|
|
||||||
|
|
||||||
|
proc aes256_ctr_init _counter
|
||||||
|
push ebx esi edi
|
||||||
|
|
||||||
|
mcall 68, 12, sizeof.aes256_ctr_context
|
||||||
|
; handle errors
|
||||||
|
mov ecx, 16/4
|
||||||
|
mov esi, [_counter]
|
||||||
|
lea edi, [eax + aes256_ctr_context.counter]
|
||||||
|
rep movsd
|
||||||
|
; rep movsd is slow, but we don't care while init
|
||||||
|
|
||||||
|
pop edi esi ebx
|
||||||
|
ret
|
||||||
|
endp
|
||||||
|
|
||||||
|
|
||||||
|
proc aes256_ctr_crypt _ctx, _in, _out
|
||||||
|
|
||||||
|
push ebx esi edi
|
||||||
|
|
||||||
|
DEBUGF 1,'plain : '
|
||||||
|
stdcall dump_128bit_hex, [_in]
|
||||||
|
DEBUGF 1,'\n'
|
||||||
|
|
||||||
|
mov esi, [_ctx]
|
||||||
|
lea eax, [esi + aes256_ctr_context.key]
|
||||||
|
lea ebx, [esi + aes256_ctr_context.counter]
|
||||||
|
lea ecx, [esi + aes256_ctr_context.output]
|
||||||
|
|
||||||
|
stdcall aes256_encrypt, eax, ebx, ecx ; Key, in, out
|
||||||
|
|
||||||
|
mov ebx, [_ctx]
|
||||||
|
mov esi, [_in]
|
||||||
|
mov edi, [_out]
|
||||||
|
|
||||||
|
mov eax, [esi + 4*0]
|
||||||
|
xor eax, dword[ebx + aes256_ctr_context.output + 4*0]
|
||||||
|
mov [edi + 4*0], eax
|
||||||
|
|
||||||
|
mov eax, [esi + 4*1]
|
||||||
|
xor eax, dword[ebx + aes256_ctr_context.output + 4*1]
|
||||||
|
mov [edi + 4*1], eax
|
||||||
|
|
||||||
|
mov eax, [esi + 4*2]
|
||||||
|
xor eax, dword[ebx + aes256_ctr_context.output + 4*2]
|
||||||
|
mov [edi + 4*2], eax
|
||||||
|
|
||||||
|
mov eax, [esi + 4*3]
|
||||||
|
xor eax, dword[ebx + aes256_ctr_context.output + 4*3]
|
||||||
|
mov [edi + 4*3], eax
|
||||||
|
|
||||||
|
; Increment counter
|
||||||
|
mov esi, [_ctx]
|
||||||
|
|
||||||
|
mov eax, dword[esi + aes256_ctr_context.counter + 4*0]
|
||||||
|
mov ebx, dword[esi + aes256_ctr_context.counter + 4*1]
|
||||||
|
mov ecx, dword[esi + aes256_ctr_context.counter + 4*2]
|
||||||
|
mov edx, dword[esi + aes256_ctr_context.counter + 4*3]
|
||||||
|
|
||||||
|
bswap eax
|
||||||
|
bswap ebx
|
||||||
|
bswap ecx
|
||||||
|
bswap edx
|
||||||
|
|
||||||
|
inc edx
|
||||||
|
adc ecx, 0
|
||||||
|
adc ebx, 0
|
||||||
|
adc eax, 0
|
||||||
|
|
||||||
|
bswap eax
|
||||||
|
bswap ebx
|
||||||
|
bswap ecx
|
||||||
|
bswap edx
|
||||||
|
|
||||||
|
mov dword[esi + aes256_ctr_context.counter + 4*0], eax
|
||||||
|
mov dword[esi + aes256_ctr_context.counter + 4*1], ebx
|
||||||
|
mov dword[esi + aes256_ctr_context.counter + 4*2], ecx
|
||||||
|
mov dword[esi + aes256_ctr_context.counter + 4*3], edx
|
||||||
|
|
||||||
|
DEBUGF 1,'cipher : '
|
||||||
|
stdcall dump_128bit_hex, [_out]
|
||||||
|
DEBUGF 1,'\n\n'
|
||||||
|
|
||||||
|
pop edi esi ebx
|
||||||
|
ret
|
||||||
|
endp
|
1652
programs/network/ssh/aes256.inc
Normal file
1652
programs/network/ssh/aes256.inc
Normal file
File diff suppressed because it is too large
Load Diff
422
programs/network/ssh/dh_gex.inc
Normal file
422
programs/network/ssh/dh_gex.inc
Normal file
@ -0,0 +1,422 @@
|
|||||||
|
; dh_gex.inc - Diffie Hellman Group exchange
|
||||||
|
;
|
||||||
|
; Copyright (C) 2015-2016 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/>.
|
||||||
|
|
||||||
|
; https://www.ietf.org/rfc/rfc4419.txt
|
||||||
|
|
||||||
|
; TODO: dont convert mpints to little endian immediately.
|
||||||
|
; Or maybe even better, not at all.
|
||||||
|
|
||||||
|
proc dh_gex
|
||||||
|
|
||||||
|
;----------------------------------------------
|
||||||
|
; >> Send Diffie-Hellman Group Exchange Request
|
||||||
|
|
||||||
|
DEBUGF 1, "Sending GEX\n"
|
||||||
|
stdcall ssh_send_packet, [socketnum], ssh_gex_req, ssh_gex_req.length, 0
|
||||||
|
cmp eax, -1
|
||||||
|
je .socket_err
|
||||||
|
|
||||||
|
;---------------------------------------------
|
||||||
|
; << Parse Diffie-Hellman Group Exchange Group
|
||||||
|
|
||||||
|
stdcall ssh_recv_packet, [socketnum], rx_buffer, BUFFERSIZE, 0
|
||||||
|
cmp eax, -1
|
||||||
|
je .socket_err
|
||||||
|
|
||||||
|
cmp [rx_buffer+ssh_header.message_code], SSH_MSG_KEX_DH_GEX_GROUP
|
||||||
|
jne proto_err
|
||||||
|
DEBUGF 1, "Received GEX group\n"
|
||||||
|
|
||||||
|
mov esi, rx_buffer+sizeof.ssh_header
|
||||||
|
mov edi, dh_p
|
||||||
|
DEBUGF 1, "DH modulus (p): "
|
||||||
|
call mpint_to_little_endian
|
||||||
|
stdcall mpint_print, dh_p
|
||||||
|
|
||||||
|
DEBUGF 1, "DH base (g): "
|
||||||
|
mov edi, dh_g
|
||||||
|
call mpint_to_little_endian
|
||||||
|
stdcall mpint_print, dh_g
|
||||||
|
|
||||||
|
;-------------------------------------------
|
||||||
|
; >> Send Diffie-Hellman Group Exchange Init
|
||||||
|
|
||||||
|
; generate a random number x, where 1 < x < (p-1)/2
|
||||||
|
mov edi, dh_x+4
|
||||||
|
mov [dh_x], DH_PRIVATE_KEY_SIZE/8
|
||||||
|
mov ecx, DH_PRIVATE_KEY_SIZE/8/4
|
||||||
|
@@:
|
||||||
|
push ecx
|
||||||
|
call MBRandom
|
||||||
|
pop ecx
|
||||||
|
stosd
|
||||||
|
dec ecx
|
||||||
|
jnz @r
|
||||||
|
|
||||||
|
; If the highest bit is set, add a zero byte
|
||||||
|
shl eax, 1
|
||||||
|
jnc @f
|
||||||
|
mov byte[edi], 0
|
||||||
|
inc dword[dh_x]
|
||||||
|
@@:
|
||||||
|
|
||||||
|
; Fill remaining bytes with zeros ; TO BE REMOVED ?
|
||||||
|
if ((MAX_BITS-DH_PRIVATE_KEY_SIZE) > 0)
|
||||||
|
mov ecx, (MAX_BITS-DH_PRIVATE_KEY_SIZE)/8/4
|
||||||
|
xor eax, eax
|
||||||
|
rep stosd
|
||||||
|
end if
|
||||||
|
|
||||||
|
DEBUGF 1, "DH x: "
|
||||||
|
stdcall mpint_length, dh_x;;;;;;;;;;;;;
|
||||||
|
stdcall mpint_print, dh_x
|
||||||
|
|
||||||
|
; Compute e = g^x mod p
|
||||||
|
stdcall mpint_modexp, dh_e, dh_g, dh_x, dh_p
|
||||||
|
stdcall mpint_length, dh_e
|
||||||
|
|
||||||
|
DEBUGF 1, "DH e: "
|
||||||
|
stdcall mpint_print, dh_e
|
||||||
|
|
||||||
|
; Create group exchange init packet
|
||||||
|
mov edi, tx_buffer+ssh_header.message_code
|
||||||
|
mov al, SSH_MSG_KEX_DH_GEX_INIT
|
||||||
|
stosb
|
||||||
|
mov esi, dh_e
|
||||||
|
call mpint_to_big_endian
|
||||||
|
|
||||||
|
DEBUGF 1, "Sending GEX init\n"
|
||||||
|
mov ecx, dword[tx_buffer+ssh_header.message_code+1]
|
||||||
|
bswap ecx
|
||||||
|
add ecx, 5
|
||||||
|
stdcall ssh_send_packet, [socketnum], tx_buffer+ssh_header.message_code, ecx, 0
|
||||||
|
cmp eax, -1
|
||||||
|
je .socket_err
|
||||||
|
|
||||||
|
;---------------------------------------------
|
||||||
|
; << Parse Diffie-Hellman Group Exchange Reply
|
||||||
|
|
||||||
|
stdcall ssh_recv_packet, [socketnum], rx_buffer, BUFFERSIZE, 0
|
||||||
|
cmp eax, -1
|
||||||
|
je .socket_err
|
||||||
|
|
||||||
|
cmp [rx_buffer+ssh_header.message_code], SSH_MSG_KEX_DH_GEX_REPLY
|
||||||
|
jne .proto_err
|
||||||
|
|
||||||
|
DEBUGF 1, "Received GEX Reply\n"
|
||||||
|
|
||||||
|
;--------------------------------
|
||||||
|
; HASH: string K_S, the host key
|
||||||
|
mov esi, rx_buffer+sizeof.ssh_header
|
||||||
|
mov edx, [esi]
|
||||||
|
bswap edx
|
||||||
|
add edx, 4
|
||||||
|
lea ebx, [esi+edx]
|
||||||
|
push ebx
|
||||||
|
call sha256_update
|
||||||
|
|
||||||
|
;--------------------------------------------------------------------------
|
||||||
|
; HASH: uint32 min, minimal size in bits of an acceptable group
|
||||||
|
; uint32 n, preferred size in bits of the group the server will send
|
||||||
|
; uint32 max, maximal size in bits of an acceptable group
|
||||||
|
mov esi, ssh_gex_req+sizeof.ssh_header-ssh_header.message_code
|
||||||
|
mov edx, 12
|
||||||
|
call sha256_update
|
||||||
|
|
||||||
|
;----------------------------
|
||||||
|
; HASH: mpint p, safe prime
|
||||||
|
mov esi, dh_p
|
||||||
|
mov edi, mpint_tmp
|
||||||
|
call mpint_to_big_endian
|
||||||
|
lea edx, [eax+4]
|
||||||
|
mov esi, mpint_tmp
|
||||||
|
call sha256_update
|
||||||
|
|
||||||
|
;----------------------------------------
|
||||||
|
; HASH: mpint g, generator for subgroup
|
||||||
|
mov esi, dh_g
|
||||||
|
mov edi, mpint_tmp
|
||||||
|
call mpint_to_big_endian
|
||||||
|
lea edx, [eax+4]
|
||||||
|
mov esi, mpint_tmp
|
||||||
|
call sha256_update
|
||||||
|
|
||||||
|
;---------------------------------------------------
|
||||||
|
; HASH: mpint e, exchange value sent by the client
|
||||||
|
mov esi, tx_buffer+sizeof.ssh_header
|
||||||
|
mov edx, [esi]
|
||||||
|
bswap edx
|
||||||
|
add edx, 4
|
||||||
|
call sha256_update
|
||||||
|
|
||||||
|
;---------------------------------------------------
|
||||||
|
; HASH: mpint f, exchange value sent by the server
|
||||||
|
mov esi, [esp]
|
||||||
|
mov edx, [esi]
|
||||||
|
bswap edx
|
||||||
|
add edx, 4
|
||||||
|
call sha256_update
|
||||||
|
pop esi
|
||||||
|
|
||||||
|
mov edi, dh_f
|
||||||
|
call mpint_to_little_endian
|
||||||
|
|
||||||
|
DEBUGF 1, "DH f: "
|
||||||
|
stdcall mpint_print, dh_f
|
||||||
|
|
||||||
|
mov edi, dh_signature
|
||||||
|
call mpint_to_little_endian
|
||||||
|
|
||||||
|
DEBUGF 1, "DH signature: "
|
||||||
|
stdcall mpint_print, dh_signature
|
||||||
|
|
||||||
|
;--------------------------------------
|
||||||
|
; Calculate shared secret K = f^x mod p
|
||||||
|
stdcall mpint_modexp, rx_buffer, dh_f, dh_x, dh_p
|
||||||
|
stdcall mpint_length, rx_buffer
|
||||||
|
|
||||||
|
DEBUGF 1, "DH K: "
|
||||||
|
stdcall mpint_print, rx_buffer
|
||||||
|
|
||||||
|
; We always need it in big endian order, so store it as such.
|
||||||
|
mov edi, dh_K
|
||||||
|
mov esi, rx_buffer
|
||||||
|
call mpint_to_big_endian
|
||||||
|
mov [dh_K.length], eax
|
||||||
|
|
||||||
|
;-----------------------------------
|
||||||
|
; HASH: mpint K, the shared secret
|
||||||
|
mov edx, [dh_K.length]
|
||||||
|
add edx, 4
|
||||||
|
mov esi, dh_K
|
||||||
|
call sha256_update
|
||||||
|
|
||||||
|
;-------------------------------
|
||||||
|
; Finalize the exchange hash (H)
|
||||||
|
mov edi, dh_H
|
||||||
|
call sha256_final
|
||||||
|
|
||||||
|
DEBUGF 1, "Exchange hash H: "
|
||||||
|
stdcall dump_256bit_hex, dh_H
|
||||||
|
|
||||||
|
; TODO: skip this block when re-keying
|
||||||
|
mov esi, dh_H
|
||||||
|
mov edi, session_id
|
||||||
|
mov ecx, 32/4
|
||||||
|
rep movsd
|
||||||
|
|
||||||
|
;---------------
|
||||||
|
; Calculate keys
|
||||||
|
|
||||||
|
; TODO: re-use partial hash of K and H
|
||||||
|
|
||||||
|
;---------------------------------------------------------------
|
||||||
|
; Initial IV client to server: HASH(K || H || "A" || session_id)
|
||||||
|
|
||||||
|
call sha256_init
|
||||||
|
mov edx, [dh_K.length]
|
||||||
|
add edx, 4
|
||||||
|
mov esi, dh_K
|
||||||
|
call sha256_update
|
||||||
|
mov edx, 32
|
||||||
|
mov esi, dh_H
|
||||||
|
call sha256_update
|
||||||
|
mov edx, 1
|
||||||
|
mov esi, str_A
|
||||||
|
call sha256_update
|
||||||
|
mov edx, 32
|
||||||
|
mov esi, session_id
|
||||||
|
call sha256_update
|
||||||
|
mov edi, tx_iv
|
||||||
|
call sha256_final
|
||||||
|
|
||||||
|
DEBUGF 1, "Remote IV: "
|
||||||
|
stdcall dump_256bit_hex, tx_iv
|
||||||
|
|
||||||
|
;---------------------------------------------------------------
|
||||||
|
; Initial IV server to client: HASH(K || H || "B" || session_id)
|
||||||
|
|
||||||
|
call sha256_init
|
||||||
|
mov edx, [dh_K.length]
|
||||||
|
add edx, 4
|
||||||
|
mov esi, dh_K
|
||||||
|
call sha256_update
|
||||||
|
mov edx, 32
|
||||||
|
mov esi, dh_H
|
||||||
|
call sha256_update
|
||||||
|
mov edx, 1
|
||||||
|
mov esi, str_B
|
||||||
|
call sha256_update
|
||||||
|
mov edx, 32
|
||||||
|
mov esi, session_id
|
||||||
|
call sha256_update
|
||||||
|
mov edi, rx_iv
|
||||||
|
call sha256_final
|
||||||
|
|
||||||
|
DEBUGF 1, "Local IV: "
|
||||||
|
stdcall dump_256bit_hex, rx_iv
|
||||||
|
|
||||||
|
;-------------------------------------------------------------------
|
||||||
|
; Encryption key client to server: HASH(K || H || "C" || session_id)
|
||||||
|
|
||||||
|
call sha256_init
|
||||||
|
mov edx, [dh_K.length]
|
||||||
|
add edx, 4
|
||||||
|
mov esi, dh_K
|
||||||
|
call sha256_update
|
||||||
|
mov edx, 32
|
||||||
|
mov esi, dh_H
|
||||||
|
call sha256_update
|
||||||
|
mov edx, 1
|
||||||
|
mov esi, str_C
|
||||||
|
call sha256_update
|
||||||
|
mov edx, 32
|
||||||
|
mov esi, session_id
|
||||||
|
call sha256_update
|
||||||
|
mov edi, tx_enc_key
|
||||||
|
call sha256_final
|
||||||
|
|
||||||
|
DEBUGF 1, "Remote key: "
|
||||||
|
stdcall dump_256bit_hex, tx_enc_key
|
||||||
|
|
||||||
|
;-------------------------------------------------------------------
|
||||||
|
; Encryption key server to client: HASH(K || H || "D" || session_id)
|
||||||
|
|
||||||
|
call sha256_init
|
||||||
|
mov edx, [dh_K.length]
|
||||||
|
add edx, 4
|
||||||
|
mov esi, dh_K
|
||||||
|
call sha256_update
|
||||||
|
mov edx, 32
|
||||||
|
mov esi, dh_H
|
||||||
|
call sha256_update
|
||||||
|
mov edx, 1
|
||||||
|
mov esi, str_D
|
||||||
|
call sha256_update
|
||||||
|
mov edx, 32
|
||||||
|
mov esi, session_id
|
||||||
|
call sha256_update
|
||||||
|
mov edi, rx_enc_key
|
||||||
|
call sha256_final
|
||||||
|
|
||||||
|
DEBUGF 1, "Local key: "
|
||||||
|
stdcall dump_256bit_hex, rx_enc_key
|
||||||
|
|
||||||
|
;------------------------------------------------------------------
|
||||||
|
; Integrity key client to server: HASH(K || H || "E" || session_id)
|
||||||
|
|
||||||
|
call sha256_init
|
||||||
|
mov edx, [dh_K.length]
|
||||||
|
add edx, 4
|
||||||
|
mov esi, dh_K
|
||||||
|
call sha256_update
|
||||||
|
mov edx, 32
|
||||||
|
mov esi, dh_H
|
||||||
|
call sha256_update
|
||||||
|
mov edx, 1
|
||||||
|
mov esi, str_E
|
||||||
|
call sha256_update
|
||||||
|
mov edx, 32
|
||||||
|
mov esi, session_id
|
||||||
|
call sha256_update
|
||||||
|
mov edi, tx_int_key
|
||||||
|
call sha256_final
|
||||||
|
|
||||||
|
DEBUGF 1, "Remote Integrity key: "
|
||||||
|
stdcall dump_256bit_hex, tx_int_key
|
||||||
|
|
||||||
|
;------------------------------------------------------------------
|
||||||
|
; Integrity key server to client: HASH(K || H || "F" || session_id)
|
||||||
|
|
||||||
|
call sha256_init
|
||||||
|
mov edx, [dh_K.length]
|
||||||
|
add edx, 4
|
||||||
|
mov esi, dh_K
|
||||||
|
call sha256_update
|
||||||
|
mov edx, 32
|
||||||
|
mov esi, dh_H
|
||||||
|
call sha256_update
|
||||||
|
mov edx, 1
|
||||||
|
mov esi, str_F
|
||||||
|
call sha256_update
|
||||||
|
mov edx, 32
|
||||||
|
mov esi, session_id
|
||||||
|
call sha256_update
|
||||||
|
mov edi, rx_int_key
|
||||||
|
call sha256_final
|
||||||
|
|
||||||
|
DEBUGF 1, "Local Integrity key: "
|
||||||
|
stdcall dump_256bit_hex, rx_int_key
|
||||||
|
|
||||||
|
;-------------------------------------
|
||||||
|
; << Parse Diffie-Hellman New Keys MSG
|
||||||
|
|
||||||
|
stdcall ssh_recv_packet, [socketnum], rx_buffer, BUFFERSIZE, 0
|
||||||
|
cmp eax, -1
|
||||||
|
je .socket_err
|
||||||
|
|
||||||
|
cmp [rx_buffer+ssh_header.message_code], SSH_MSG_NEWKEYS
|
||||||
|
jne .proto_err
|
||||||
|
|
||||||
|
DEBUGF 1, "Received New Keys\n"
|
||||||
|
|
||||||
|
;-------------------------------
|
||||||
|
; >> Reply with New Keys message
|
||||||
|
|
||||||
|
stdcall ssh_send_packet, [socketnum], ssh_new_keys, ssh_new_keys.length, 0
|
||||||
|
|
||||||
|
xor eax, eax
|
||||||
|
ret
|
||||||
|
|
||||||
|
.socket_err:
|
||||||
|
DEBUGF 2, "Socket error during key exchange!\n"
|
||||||
|
mov eax, 1
|
||||||
|
ret
|
||||||
|
|
||||||
|
.proto_err:
|
||||||
|
DEBUGF 2, "Protocol error during key exchange!\n"
|
||||||
|
mov eax, 2
|
||||||
|
ret
|
||||||
|
|
||||||
|
endp
|
||||||
|
|
||||||
|
proc dump_256bit_hex _ptr
|
||||||
|
pushad
|
||||||
|
|
||||||
|
mov esi, [_ptr]
|
||||||
|
mov ecx, 8
|
||||||
|
.next_dword:
|
||||||
|
lodsd
|
||||||
|
bswap eax
|
||||||
|
DEBUGF 1,'%x',eax
|
||||||
|
loop .next_dword
|
||||||
|
DEBUGF 1,'\n'
|
||||||
|
|
||||||
|
popad
|
||||||
|
ret
|
||||||
|
endp
|
||||||
|
|
||||||
|
iglobal
|
||||||
|
|
||||||
|
str_A db 'A'
|
||||||
|
str_B db 'B'
|
||||||
|
str_C db 'C'
|
||||||
|
str_D db 'D'
|
||||||
|
str_E db 'E'
|
||||||
|
str_F db 'F'
|
||||||
|
|
||||||
|
endg
|
32
programs/network/ssh/mcodes.inc
Normal file
32
programs/network/ssh/mcodes.inc
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
|
||||||
|
SSH_MSG_DISCONNECT = 1
|
||||||
|
SSH_MSG_IGNORE = 2
|
||||||
|
SSH_MSG_UNIMPLEMENTED = 3
|
||||||
|
SSH_MSG_DEBUG = 4
|
||||||
|
SSH_MSG_SERVICE_REQUEST = 5
|
||||||
|
SSH_MSG_SERVICE_ACCEPT = 6
|
||||||
|
SSH_MSG_KEXINIT = 20
|
||||||
|
SSH_MSG_NEWKEYS = 21
|
||||||
|
SSH_MSG_KEX_DH_GEX_REQUEST_OLD = 30
|
||||||
|
SSH_MSG_KEX_DH_GEX_GROUP = 31
|
||||||
|
SSH_MSG_KEX_DH_GEX_INIT = 32
|
||||||
|
SSH_MSG_KEX_DH_GEX_REPLY = 33
|
||||||
|
SSH_MSG_KEX_DH_GEX_REQUEST = 34
|
||||||
|
SSH_MSG_USERAUTH_REQUEST = 50
|
||||||
|
SSH_MSG_USERAUTH_FAILURE = 51
|
||||||
|
SSH_MSG_USERAUTH_SUCCESS = 52
|
||||||
|
SSH_MSG_USERAUTH_BANNER = 53
|
||||||
|
SSH_MSG_GLOBAL_REQUEST = 80
|
||||||
|
SSH_MSG_REQUEST_SUCCESS = 81
|
||||||
|
SSH_MSG_REQUEST_FAILURE = 82
|
||||||
|
SSH_MSG_CHANNEL_OPEN = 90
|
||||||
|
SSH_MSG_CHANNEL_OPEN_CONFIRMATION = 91
|
||||||
|
SSH_MSG_CHANNEL_OPEN_FAILURE = 92
|
||||||
|
SSH_MSG_CHANNEL_WINDOW_ADJUST = 93
|
||||||
|
SSH_MSG_CHANNEL_DATA = 94
|
||||||
|
SSH_MSG_CHANNEL_EXTENDED_DATA = 95
|
||||||
|
SSH_MSG_CHANNEL_EOF = 96
|
||||||
|
SSH_MSG_CHANNEL_CLOSE = 97
|
||||||
|
SSH_MSG_CHANNEL_REQUEST = 98
|
||||||
|
SSH_MSG_CHANNEL_SUCCESS = 99
|
||||||
|
SSH_MSG_CHANNEL_FAILURE = 100
|
568
programs/network/ssh/mpint.inc
Normal file
568
programs/network/ssh/mpint.inc
Normal file
@ -0,0 +1,568 @@
|
|||||||
|
; mpint.inc - Multi precision integer procedures
|
||||||
|
;
|
||||||
|
; Copyright (C) 2015-2016 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/>.
|
||||||
|
|
||||||
|
MPINT_MAX_LEN = MAX_BITS/8
|
||||||
|
|
||||||
|
; TODO: make procedures use real number length instead of hardcoded maximum length (MPINT_MAX_LEN)
|
||||||
|
|
||||||
|
mpint_to_little_endian:
|
||||||
|
|
||||||
|
; Load length dword
|
||||||
|
lodsd
|
||||||
|
; Convert to little endian
|
||||||
|
bswap eax
|
||||||
|
stosd
|
||||||
|
test eax, eax
|
||||||
|
jz .zero
|
||||||
|
; Copy data, convert to little endian meanwhile
|
||||||
|
push eax
|
||||||
|
add esi, eax
|
||||||
|
push esi
|
||||||
|
dec esi
|
||||||
|
mov ecx, eax
|
||||||
|
std
|
||||||
|
@@:
|
||||||
|
lodsb
|
||||||
|
mov byte[edi], al
|
||||||
|
inc edi
|
||||||
|
dec ecx
|
||||||
|
jnz @r
|
||||||
|
cld
|
||||||
|
pop esi eax
|
||||||
|
; Fill the rest of the buffer with zeros.
|
||||||
|
.zero:
|
||||||
|
mov ecx, MAX_BITS/8
|
||||||
|
sub ecx, eax
|
||||||
|
xor al, al
|
||||||
|
rep stosb
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
||||||
|
mpint_to_big_endian:
|
||||||
|
|
||||||
|
; Load length dword
|
||||||
|
lodsd
|
||||||
|
test eax, eax
|
||||||
|
jz .zero
|
||||||
|
mov ecx, eax
|
||||||
|
add esi, ecx
|
||||||
|
dec esi
|
||||||
|
test byte[esi], 0x80 ; Is the highest bit set?
|
||||||
|
jz @f
|
||||||
|
inc eax
|
||||||
|
@@:
|
||||||
|
push eax
|
||||||
|
bswap eax
|
||||||
|
stosd
|
||||||
|
; Copy data, convert to big endian meanwhile
|
||||||
|
std
|
||||||
|
; Append zero byte if highest bit is 0
|
||||||
|
test byte[esi], 0x80
|
||||||
|
jz @f
|
||||||
|
mov byte[edi], 0
|
||||||
|
inc edi
|
||||||
|
@@:
|
||||||
|
lodsb
|
||||||
|
mov byte[edi], al
|
||||||
|
inc edi
|
||||||
|
dec ecx
|
||||||
|
jnz @r
|
||||||
|
cld
|
||||||
|
pop eax
|
||||||
|
ret
|
||||||
|
|
||||||
|
.zero:
|
||||||
|
stosd
|
||||||
|
ret
|
||||||
|
|
||||||
|
proc mpint_length uses edi eax ecx, mpint
|
||||||
|
|
||||||
|
mov edi, [mpint]
|
||||||
|
mov ecx, MPINT_MAX_LEN
|
||||||
|
push edi
|
||||||
|
lea edi, [edi + ecx + 4 - 1]
|
||||||
|
xor al, al
|
||||||
|
std
|
||||||
|
repe scasb
|
||||||
|
cld
|
||||||
|
je @f
|
||||||
|
inc ecx
|
||||||
|
@@:
|
||||||
|
pop edi
|
||||||
|
mov [edi], ecx
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
||||||
|
endp
|
||||||
|
|
||||||
|
proc mpint_print uses ecx esi eax, src
|
||||||
|
|
||||||
|
DEBUGF 1, "0x"
|
||||||
|
mov esi, [src]
|
||||||
|
mov ecx, [esi]
|
||||||
|
test ecx, ecx
|
||||||
|
jz .zero
|
||||||
|
lea esi, [esi + ecx + 4 - 1]
|
||||||
|
pushf
|
||||||
|
std
|
||||||
|
.loop:
|
||||||
|
lodsb
|
||||||
|
DEBUGF 1, "%x", eax:2
|
||||||
|
dec ecx
|
||||||
|
jnz .loop
|
||||||
|
DEBUGF 1, "\n"
|
||||||
|
popf
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
||||||
|
.zero:
|
||||||
|
DEBUGF 1, "00\n"
|
||||||
|
ret
|
||||||
|
|
||||||
|
endp
|
||||||
|
|
||||||
|
proc mpint_zero uses edi ecx eax, dst
|
||||||
|
|
||||||
|
mov edi, [dst]
|
||||||
|
xor eax, eax
|
||||||
|
mov ecx, MPINT_MAX_LEN/4+1
|
||||||
|
rep stosd
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
||||||
|
endp
|
||||||
|
|
||||||
|
proc mpint_zero? uses edi ecx eax, dst
|
||||||
|
|
||||||
|
mov edi, [dst]
|
||||||
|
add edi, 4
|
||||||
|
mov ecx, MPINT_MAX_LEN/4
|
||||||
|
xor eax, eax
|
||||||
|
repe scasd
|
||||||
|
ret
|
||||||
|
|
||||||
|
endp
|
||||||
|
|
||||||
|
; return an index number giving the position of the highest order bit
|
||||||
|
proc mpint_hob uses edi ecx, dst
|
||||||
|
|
||||||
|
mov edi, [dst]
|
||||||
|
; start from the high order byte
|
||||||
|
add edi, MPINT_MAX_LEN+4-1
|
||||||
|
mov ecx, MPINT_MAX_LEN
|
||||||
|
xor eax, eax
|
||||||
|
; scan byte by byte for the first non-zero byte
|
||||||
|
std
|
||||||
|
repe scasb
|
||||||
|
cld
|
||||||
|
je .zero
|
||||||
|
; calculate how many bits this is, plus 7
|
||||||
|
lea eax, [ecx*8-1]
|
||||||
|
; load this high order byte into cl
|
||||||
|
mov cl, [edi+1]
|
||||||
|
; shift bits of this byte right, until the byte reaches zero, counting bits meanwhile
|
||||||
|
@@:
|
||||||
|
inc eax
|
||||||
|
shr cl, 1
|
||||||
|
jnz @r
|
||||||
|
.zero:
|
||||||
|
ret
|
||||||
|
|
||||||
|
endp
|
||||||
|
|
||||||
|
proc mpint_cmp uses esi edi ecx, dst, src
|
||||||
|
|
||||||
|
mov esi, [src]
|
||||||
|
mov edi, [dst]
|
||||||
|
; start from the high order byte
|
||||||
|
add esi, MPINT_MAX_LEN+4-4
|
||||||
|
add edi, MPINT_MAX_LEN+4-4
|
||||||
|
mov ecx, MPINT_MAX_LEN/4
|
||||||
|
std
|
||||||
|
repe cmpsd
|
||||||
|
cld
|
||||||
|
ret
|
||||||
|
|
||||||
|
endp
|
||||||
|
|
||||||
|
proc mpint_mov uses esi edi ecx, dst, src
|
||||||
|
|
||||||
|
mov esi, [src]
|
||||||
|
mov edi, [dst]
|
||||||
|
mov ecx, MPINT_MAX_LEN/4+1
|
||||||
|
rep movsd
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
||||||
|
endp
|
||||||
|
|
||||||
|
proc mpint_mov0 uses esi edi ecx eax, dst, src
|
||||||
|
|
||||||
|
mov esi, [src]
|
||||||
|
mov edi, [dst]
|
||||||
|
mov ecx, [esi]
|
||||||
|
mov eax, ecx
|
||||||
|
neg eax
|
||||||
|
add esi, 4
|
||||||
|
add edi, 4
|
||||||
|
rep movsb
|
||||||
|
add eax, MPINT_MAX_LEN
|
||||||
|
jz @f
|
||||||
|
mov ecx, eax
|
||||||
|
xor eax, eax
|
||||||
|
rep stosb
|
||||||
|
@@:
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
||||||
|
endp
|
||||||
|
|
||||||
|
proc mpint_shl1 uses edi ecx eax, dst
|
||||||
|
|
||||||
|
mov edi, [dst]
|
||||||
|
add edi, 4
|
||||||
|
mov ecx, MPINT_MAX_LEN/4-1
|
||||||
|
|
||||||
|
shl dword[edi], 1
|
||||||
|
lahf
|
||||||
|
@@:
|
||||||
|
add edi, 4
|
||||||
|
sahf
|
||||||
|
rcl dword[edi], 1
|
||||||
|
lahf
|
||||||
|
dec ecx
|
||||||
|
jnz @r
|
||||||
|
sahf
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
||||||
|
endp
|
||||||
|
|
||||||
|
proc mpint_shr1 uses edi ecx eax, dst
|
||||||
|
|
||||||
|
mov edi, [dst]
|
||||||
|
add edi, MPINT_MAX_LEN+4-4
|
||||||
|
mov ecx, MPINT_MAX_LEN/4-1
|
||||||
|
|
||||||
|
shr dword[edi], 1
|
||||||
|
lahf
|
||||||
|
@@:
|
||||||
|
sub edi, 4
|
||||||
|
sahf
|
||||||
|
rcr dword[edi], 1
|
||||||
|
lahf
|
||||||
|
dec ecx
|
||||||
|
jnz @r
|
||||||
|
sahf
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
||||||
|
endp
|
||||||
|
|
||||||
|
proc mpint_shl uses eax ebx ecx edx esi edi, dst, shift
|
||||||
|
|
||||||
|
mov ecx, [shift]
|
||||||
|
shr ecx, 3 ; 8 bits in one byte
|
||||||
|
cmp ecx, MPINT_MAX_LEN
|
||||||
|
jge .zero
|
||||||
|
mov esi, [dst]
|
||||||
|
add esi, MPINT_MAX_LEN+4-4
|
||||||
|
mov edi, esi
|
||||||
|
and ecx, not 11b
|
||||||
|
sub esi, ecx
|
||||||
|
mov edx, MPINT_MAX_LEN/4-1
|
||||||
|
shr ecx, 2 ; 4 bytes in one dword
|
||||||
|
push ecx
|
||||||
|
sub edx, ecx
|
||||||
|
mov ecx, [shift]
|
||||||
|
and ecx, 11111b
|
||||||
|
std
|
||||||
|
.loop:
|
||||||
|
lodsd
|
||||||
|
mov ebx, [esi]
|
||||||
|
shld eax, ebx, cl
|
||||||
|
stosd
|
||||||
|
dec edx
|
||||||
|
jnz .loop
|
||||||
|
lodsd
|
||||||
|
shl eax, cl
|
||||||
|
stosd
|
||||||
|
|
||||||
|
; fill the lsb bytes with zeros
|
||||||
|
pop ecx
|
||||||
|
test ecx, ecx
|
||||||
|
jz @f
|
||||||
|
xor eax, eax
|
||||||
|
rep stosd
|
||||||
|
@@:
|
||||||
|
cld
|
||||||
|
ret
|
||||||
|
|
||||||
|
.zero:
|
||||||
|
stdcall mpint_zero, [dst]
|
||||||
|
ret
|
||||||
|
|
||||||
|
endp
|
||||||
|
|
||||||
|
; Left shift and copy
|
||||||
|
proc mpint_shlmov uses eax ebx ecx edx esi edi, dst, src, shift
|
||||||
|
|
||||||
|
mov ecx, [shift]
|
||||||
|
shr ecx, 3 ; 8 bits in one byte
|
||||||
|
cmp ecx, MPINT_MAX_LEN
|
||||||
|
jge .zero
|
||||||
|
mov esi, [src]
|
||||||
|
add esi, MPINT_MAX_LEN+4-4
|
||||||
|
mov edi, [dst]
|
||||||
|
add edi, MPINT_MAX_LEN+4-4
|
||||||
|
and ecx, not 11b
|
||||||
|
sub esi, ecx
|
||||||
|
mov edx, MPINT_MAX_LEN/4-1
|
||||||
|
shr ecx, 2 ; 4 bytes in one dword
|
||||||
|
push ecx
|
||||||
|
sub edx, ecx
|
||||||
|
mov ecx, [shift]
|
||||||
|
and ecx, 11111b
|
||||||
|
std
|
||||||
|
.loop:
|
||||||
|
lodsd
|
||||||
|
mov ebx, [esi]
|
||||||
|
shld eax, ebx, cl
|
||||||
|
stosd
|
||||||
|
dec edx
|
||||||
|
jnz .loop
|
||||||
|
lodsd
|
||||||
|
shl eax, cl
|
||||||
|
stosd
|
||||||
|
|
||||||
|
; fill the lsb bytes with zeros
|
||||||
|
pop ecx
|
||||||
|
test ecx, ecx
|
||||||
|
jz @f
|
||||||
|
xor eax, eax
|
||||||
|
rep stosd
|
||||||
|
@@:
|
||||||
|
cld
|
||||||
|
ret
|
||||||
|
|
||||||
|
.zero:
|
||||||
|
stdcall mpint_zero, [dst]
|
||||||
|
ret
|
||||||
|
|
||||||
|
endp
|
||||||
|
|
||||||
|
proc mpint_add uses esi edi ecx eax, dst, src
|
||||||
|
|
||||||
|
mov esi, [src]
|
||||||
|
add esi, 4
|
||||||
|
mov edi, [dst]
|
||||||
|
add edi, 4
|
||||||
|
mov ecx, MPINT_MAX_LEN/4
|
||||||
|
xor ah, ah ; clear flags (Carry flag most importantly)
|
||||||
|
@@:
|
||||||
|
sahf
|
||||||
|
lodsd
|
||||||
|
adc [edi], eax
|
||||||
|
lahf
|
||||||
|
add edi, 4
|
||||||
|
dec ecx
|
||||||
|
jnz @r
|
||||||
|
sahf
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
||||||
|
endp
|
||||||
|
|
||||||
|
proc mpint_sub uses eax esi edi ecx, dst, src
|
||||||
|
|
||||||
|
mov esi, [src]
|
||||||
|
add esi, 4
|
||||||
|
mov edi, [dst]
|
||||||
|
add edi, 4
|
||||||
|
mov ecx, MPINT_MAX_LEN/4
|
||||||
|
|
||||||
|
; dst = dst + (NOT src) + 1
|
||||||
|
stc ; Setting CF takes care of the +1
|
||||||
|
pushf
|
||||||
|
@@:
|
||||||
|
lodsd
|
||||||
|
not eax
|
||||||
|
popf
|
||||||
|
adc [edi], eax
|
||||||
|
pushf
|
||||||
|
add edi, 4
|
||||||
|
dec ecx
|
||||||
|
jnz @r
|
||||||
|
popf
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
||||||
|
endp
|
||||||
|
|
||||||
|
proc mpint_mul uses esi edi ecx ebx eax, dst, A, B
|
||||||
|
|
||||||
|
stdcall mpint_zero, [dst]
|
||||||
|
|
||||||
|
; first, find the byte in A containing the highest order bit
|
||||||
|
mov ecx, MPINT_MAX_LEN
|
||||||
|
mov edi, [A]
|
||||||
|
add edi, MPINT_MAX_LEN+4-1
|
||||||
|
std
|
||||||
|
xor al, al
|
||||||
|
repe scasb
|
||||||
|
cld
|
||||||
|
je .zero
|
||||||
|
inc ecx
|
||||||
|
mov al, [edi+1]
|
||||||
|
mov esi, edi
|
||||||
|
mov bl, 8
|
||||||
|
@@:
|
||||||
|
shl al, 1
|
||||||
|
jc .first_hit
|
||||||
|
dec bl
|
||||||
|
jnz @r
|
||||||
|
|
||||||
|
; Then, starting from this byte, iterate through the bits in A,
|
||||||
|
; starting from the highest order bit down to the lowest order bit.
|
||||||
|
.next_byte:
|
||||||
|
mov al, [edi]
|
||||||
|
dec edi
|
||||||
|
mov bl, 8
|
||||||
|
.next_bit:
|
||||||
|
stdcall mpint_shl1, [dst]
|
||||||
|
shl al, 1
|
||||||
|
jnc .zero_bit
|
||||||
|
.first_hit:
|
||||||
|
stdcall mpint_add, [dst], [B]
|
||||||
|
.zero_bit:
|
||||||
|
dec bl
|
||||||
|
jnz .next_bit
|
||||||
|
dec ecx
|
||||||
|
jnz .next_byte
|
||||||
|
.zero:
|
||||||
|
ret
|
||||||
|
|
||||||
|
endp
|
||||||
|
|
||||||
|
proc mpint_mod uses eax ecx, dst, mod
|
||||||
|
|
||||||
|
; if mod is zero, return
|
||||||
|
stdcall mpint_zero?, [mod]
|
||||||
|
jz .zero
|
||||||
|
|
||||||
|
stdcall mpint_cmp, [mod], [dst]
|
||||||
|
jb .done ; if dst < mod, dst = dst
|
||||||
|
je .zero ; if dst == mod, dst = 0
|
||||||
|
|
||||||
|
; left shift mod until the high order bits of mod and dst are aligned
|
||||||
|
stdcall mpint_hob, [dst]
|
||||||
|
mov ecx, eax
|
||||||
|
stdcall mpint_hob, [mod]
|
||||||
|
sub ecx, eax
|
||||||
|
stdcall mpint_shlmov, mpint_tmp, [mod], ecx
|
||||||
|
inc ecx
|
||||||
|
|
||||||
|
; For every bit in dst (starting from the high order bit):
|
||||||
|
.loop:
|
||||||
|
; determine if dst is bigger than mpint_tmp
|
||||||
|
stdcall mpint_cmp, [dst], mpint_tmp
|
||||||
|
ja @f
|
||||||
|
; if so, subtract mpint_tmp from dst
|
||||||
|
stdcall mpint_sub, [dst], mpint_tmp
|
||||||
|
@@:
|
||||||
|
dec ecx
|
||||||
|
jz .done
|
||||||
|
; shift mpint_tmp right by 1
|
||||||
|
stdcall mpint_shr1, mpint_tmp
|
||||||
|
jmp .loop
|
||||||
|
|
||||||
|
.zero:
|
||||||
|
stdcall mpint_zero, [dst]
|
||||||
|
.done:
|
||||||
|
ret
|
||||||
|
|
||||||
|
endp
|
||||||
|
|
||||||
|
proc mpint_modexp uses edi eax ebx ecx, dst, base, exp, mod
|
||||||
|
|
||||||
|
; If mod is zero, return
|
||||||
|
stdcall mpint_zero?, [mod]
|
||||||
|
jz .mod_zero
|
||||||
|
|
||||||
|
; Find the highest order byte in exponent
|
||||||
|
mov edi, [exp]
|
||||||
|
mov ecx, [edi]
|
||||||
|
lea edi, [edi + 4 + ecx - 1]
|
||||||
|
; Find the highest order bit in this byte
|
||||||
|
mov al, [edi]
|
||||||
|
test al, al
|
||||||
|
jz .invalid
|
||||||
|
mov bl, 9
|
||||||
|
@@:
|
||||||
|
dec bl
|
||||||
|
shl al, 1
|
||||||
|
jnc @r
|
||||||
|
|
||||||
|
; Initialise result to base, to take care of the highest order bit
|
||||||
|
stdcall mpint_mov0, [dst], [base]
|
||||||
|
dec bl
|
||||||
|
jz .next_byte
|
||||||
|
.bit_loop:
|
||||||
|
; For each bit, square result
|
||||||
|
stdcall mpint_mov, mpint_tmp, [dst]
|
||||||
|
stdcall mpint_mul, [dst], mpint_tmp, mpint_tmp
|
||||||
|
stdcall mpint_mod, [dst], [mod]
|
||||||
|
|
||||||
|
; If the bit is set, multiply result by the base
|
||||||
|
shl al, 1
|
||||||
|
jnc .next_bit
|
||||||
|
stdcall mpint_mov, mpint_tmp, [dst]
|
||||||
|
stdcall mpint_mul, [dst], [base], mpint_tmp
|
||||||
|
stdcall mpint_mod, [dst], [mod]
|
||||||
|
.next_bit:
|
||||||
|
dec bl
|
||||||
|
jnz .bit_loop
|
||||||
|
.next_byte:
|
||||||
|
dec ecx
|
||||||
|
jz .done
|
||||||
|
dec edi
|
||||||
|
mov al, [edi]
|
||||||
|
mov bl, 8
|
||||||
|
jmp .bit_loop
|
||||||
|
.done:
|
||||||
|
ret
|
||||||
|
|
||||||
|
.mod_zero:
|
||||||
|
DEBUGF 1, "modexp with modulo 0\n"
|
||||||
|
; if mod is zero, result = 0
|
||||||
|
stdcall mpint_zero, [dst]
|
||||||
|
ret
|
||||||
|
|
||||||
|
.exp_zero:
|
||||||
|
DEBUGF 1, "modexp with exponent 0\n"
|
||||||
|
; if exponent is zero, result = 1
|
||||||
|
stdcall mpint_zero, [dst]
|
||||||
|
mov eax, [dst]
|
||||||
|
mov byte[eax], 1
|
||||||
|
mov byte[eax+4], 1
|
||||||
|
ret
|
||||||
|
|
||||||
|
.invalid:
|
||||||
|
DEBUGF 1, "modexp: Invalid input!\n"
|
||||||
|
ret
|
||||||
|
|
||||||
|
endp
|
127
programs/network/ssh/random.inc
Normal file
127
programs/network/ssh/random.inc
Normal file
@ -0,0 +1,127 @@
|
|||||||
|
; ----------------------------- MOTHER.ASM -----------------------------
|
||||||
|
; Mother-of-All random number generator by Agner Fog 1998
|
||||||
|
; 32-bit mode version for 80x86 and compatible microprocessors
|
||||||
|
;
|
||||||
|
; MRandom returns a floating point number between 0 and 1.
|
||||||
|
; MRandomInit must be called before the first call to MRandom.
|
||||||
|
;
|
||||||
|
; C++ prototypes:
|
||||||
|
; extern "C" void MRandomInit (int seed);
|
||||||
|
; extern "C" double MRandom (void);
|
||||||
|
; extern "C" int MIRandom (int min, int max);
|
||||||
|
;
|
||||||
|
; © 1998, 2004 Agner Fog.
|
||||||
|
; GNU General Public License www.gnu.org/copyleft/gpl.html
|
||||||
|
; ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
; The MRandom function is optimized for the Pentium microprocessor.
|
||||||
|
|
||||||
|
iglobal
|
||||||
|
mf3 dd 2111111111 ; factors
|
||||||
|
mf2 dd 1492
|
||||||
|
mf1 dd 1776
|
||||||
|
mf0 dd 5115
|
||||||
|
endg
|
||||||
|
|
||||||
|
|
||||||
|
uglobal
|
||||||
|
m0 dd ? ; history buffer
|
||||||
|
m1 dd ?
|
||||||
|
m2 dd ?
|
||||||
|
m3 dd ?
|
||||||
|
mc dd ?
|
||||||
|
temprng dq ? ; used for conversion to float
|
||||||
|
endg
|
||||||
|
|
||||||
|
|
||||||
|
proc init_random
|
||||||
|
|
||||||
|
mcall 26, 10 ; seed
|
||||||
|
xor ecx, ecx
|
||||||
|
; make random numbers and put them into buffer
|
||||||
|
@@:
|
||||||
|
imul eax, 29943829
|
||||||
|
dec eax
|
||||||
|
mov [m0+ecx*4], eax
|
||||||
|
inc ecx
|
||||||
|
cmp ecx, 5
|
||||||
|
jb @r
|
||||||
|
push edi
|
||||||
|
mov edi, 19
|
||||||
|
@@:
|
||||||
|
call MRandom
|
||||||
|
fstp st0
|
||||||
|
dec edi
|
||||||
|
jnz @r
|
||||||
|
pop edi
|
||||||
|
ret
|
||||||
|
|
||||||
|
endp
|
||||||
|
|
||||||
|
|
||||||
|
proc MRandom
|
||||||
|
|
||||||
|
call MBRandom ; random bits
|
||||||
|
mov edx, eax ; fast conversion to float
|
||||||
|
shr eax, 12
|
||||||
|
or eax, 3ff00000h
|
||||||
|
shl edx, 20
|
||||||
|
mov dword[temprng+4], eax
|
||||||
|
mov dword[temprng], edx
|
||||||
|
fld1
|
||||||
|
fld [temprng] ; partial memory stall here
|
||||||
|
fsubr st0, st1
|
||||||
|
ret
|
||||||
|
|
||||||
|
endp
|
||||||
|
|
||||||
|
|
||||||
|
proc MIRandom, max, min ; make random integer in desired interval
|
||||||
|
|
||||||
|
call MBRandom ; make random number
|
||||||
|
mov edx, [max]
|
||||||
|
mov ecx, [min]
|
||||||
|
sub edx, ecx
|
||||||
|
js .error ; max < min
|
||||||
|
inc edx ; max - min + 1
|
||||||
|
mul edx ; multiply random number by interval and truncate
|
||||||
|
lea eax, [edx+ecx] ; add min
|
||||||
|
ret
|
||||||
|
|
||||||
|
.error:
|
||||||
|
mov eax, 80000000h ; error exit
|
||||||
|
ret
|
||||||
|
|
||||||
|
endp
|
||||||
|
|
||||||
|
|
||||||
|
proc MBRandom
|
||||||
|
|
||||||
|
push edi
|
||||||
|
mov eax, [mf3]
|
||||||
|
mul [m3] ; x[n-4]
|
||||||
|
mov ecx, eax
|
||||||
|
mov eax, [m2] ; x[n-3]
|
||||||
|
mov edi, edx
|
||||||
|
mov [m3], eax
|
||||||
|
mul [mf2]
|
||||||
|
add ecx, eax
|
||||||
|
mov eax, [m1] ; x[n-2]
|
||||||
|
adc edi, edx
|
||||||
|
mov [m2], eax
|
||||||
|
mul [mf1]
|
||||||
|
add ecx, eax
|
||||||
|
mov eax, [m0] ; x[n-1]
|
||||||
|
adc edi, edx
|
||||||
|
mov [m1], eax
|
||||||
|
mul [mf0]
|
||||||
|
add eax, ecx
|
||||||
|
adc edx, edi
|
||||||
|
add eax, [mc]
|
||||||
|
adc edx, 0
|
||||||
|
mov [m0], eax
|
||||||
|
mov [mc], edx
|
||||||
|
pop edi
|
||||||
|
ret
|
||||||
|
|
||||||
|
endp
|
578
programs/network/ssh/ssh.asm
Normal file
578
programs/network/ssh/ssh.asm
Normal file
@ -0,0 +1,578 @@
|
|||||||
|
; ssh.asm - SSH client for KolibriOS
|
||||||
|
;
|
||||||
|
; Copyright (C) 2015-2016 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/>.
|
||||||
|
|
||||||
|
format binary as ""
|
||||||
|
|
||||||
|
__DEBUG__ = 1
|
||||||
|
__DEBUG_LEVEL__ = 1
|
||||||
|
|
||||||
|
BUFFERSIZE = 4096
|
||||||
|
MAX_BITS = 8192
|
||||||
|
|
||||||
|
DH_PRIVATE_KEY_SIZE = 256
|
||||||
|
|
||||||
|
use32
|
||||||
|
|
||||||
|
db 'MENUET01' ; signature
|
||||||
|
dd 1 ; header version
|
||||||
|
dd start ; entry point
|
||||||
|
dd i_end ; initialized size
|
||||||
|
dd mem+4096 ; required memory
|
||||||
|
dd mem+4096 ; stack pointer
|
||||||
|
dd hostname ; parameters
|
||||||
|
dd 0 ; path
|
||||||
|
|
||||||
|
include '../../macros.inc'
|
||||||
|
purge mov,add,sub
|
||||||
|
include '../../proc32.inc'
|
||||||
|
include '../../dll.inc'
|
||||||
|
include '../../debug-fdo.inc'
|
||||||
|
include '../../network.inc'
|
||||||
|
;include '../../develop/libraries/libcrash/trunk/libcrash.inc'
|
||||||
|
|
||||||
|
include 'mcodes.inc'
|
||||||
|
include 'ssh_transport.inc'
|
||||||
|
include 'dh_gex.inc'
|
||||||
|
|
||||||
|
include 'mpint.inc'
|
||||||
|
include 'random.inc'
|
||||||
|
include 'aes256.inc'
|
||||||
|
include 'aes256-ctr.inc'
|
||||||
|
include 'aes256-cbc.inc'
|
||||||
|
include '../../fs/kfar/trunk/kfar_arc/sha256.inc'
|
||||||
|
|
||||||
|
; macros for network byte order
|
||||||
|
macro dd_n op {
|
||||||
|
dd 0 or (((op) and 0FF000000h) shr 24) or \
|
||||||
|
(((op) and 000FF0000h) shr 8) or \
|
||||||
|
(((op) and 00000FF00h) shl 8) or \
|
||||||
|
(((op) and 0000000FFh) shl 24)
|
||||||
|
}
|
||||||
|
|
||||||
|
macro dw_n op {
|
||||||
|
dw 0 or (((op) and 0FF00h) shr 8) or \
|
||||||
|
(((op) and 000FFh) shl 8)
|
||||||
|
}
|
||||||
|
|
||||||
|
start:
|
||||||
|
mcall 68, 11 ; Init heap
|
||||||
|
|
||||||
|
DEBUGF 1, "SSH: Loading libraries\n"
|
||||||
|
stdcall dll.Load, @IMPORT
|
||||||
|
test eax, eax
|
||||||
|
jnz exit
|
||||||
|
|
||||||
|
DEBUGF 1, "SSH: Init PRNG\n"
|
||||||
|
call init_random
|
||||||
|
|
||||||
|
DEBUGF 1, "SSH: Init Console\n"
|
||||||
|
invoke con_start, 1
|
||||||
|
invoke con_init, 80, 25, 80, 25, title
|
||||||
|
|
||||||
|
; Check for parameters
|
||||||
|
cmp byte[hostname], 0
|
||||||
|
jne resolve
|
||||||
|
|
||||||
|
main:
|
||||||
|
invoke con_cls
|
||||||
|
; Welcome user
|
||||||
|
invoke con_write_asciiz, str1
|
||||||
|
|
||||||
|
prompt:
|
||||||
|
; write prompt
|
||||||
|
invoke con_write_asciiz, str2
|
||||||
|
; read string
|
||||||
|
mov esi, hostname
|
||||||
|
invoke con_gets, esi, 256
|
||||||
|
; check for exit
|
||||||
|
test eax, eax
|
||||||
|
jz done
|
||||||
|
cmp byte[esi], 10
|
||||||
|
jz done
|
||||||
|
|
||||||
|
resolve:
|
||||||
|
mov [sockaddr1.port], 22 shl 8
|
||||||
|
|
||||||
|
; delete terminating '\n'
|
||||||
|
mov esi, hostname
|
||||||
|
@@:
|
||||||
|
lodsb
|
||||||
|
cmp al, ':'
|
||||||
|
je .do_port
|
||||||
|
cmp al, 0x20
|
||||||
|
ja @r
|
||||||
|
mov byte[esi-1], 0
|
||||||
|
jmp .done
|
||||||
|
|
||||||
|
.do_port:
|
||||||
|
xor eax, eax
|
||||||
|
xor ebx, ebx
|
||||||
|
mov byte[esi-1], 0
|
||||||
|
.portloop:
|
||||||
|
lodsb
|
||||||
|
cmp al, 0x20
|
||||||
|
jbe .port_done
|
||||||
|
sub al, '0'
|
||||||
|
jb hostname_error
|
||||||
|
cmp al, 9
|
||||||
|
ja hostname_error
|
||||||
|
lea ebx, [ebx*4 + ebx]
|
||||||
|
shl ebx, 1
|
||||||
|
add ebx, eax
|
||||||
|
jmp .portloop
|
||||||
|
|
||||||
|
.port_done:
|
||||||
|
xchg bl, bh
|
||||||
|
mov [sockaddr1.port], bx
|
||||||
|
|
||||||
|
.done:
|
||||||
|
|
||||||
|
; resolve name
|
||||||
|
push esp ; reserve stack place
|
||||||
|
push esp
|
||||||
|
invoke getaddrinfo, hostname, 0, 0
|
||||||
|
pop esi
|
||||||
|
; test for error
|
||||||
|
test eax, eax
|
||||||
|
jnz dns_error
|
||||||
|
|
||||||
|
invoke con_cls
|
||||||
|
invoke con_write_asciiz, str3
|
||||||
|
invoke con_write_asciiz, hostname
|
||||||
|
|
||||||
|
; write results
|
||||||
|
invoke con_write_asciiz, str8
|
||||||
|
|
||||||
|
; convert IP address to decimal notation
|
||||||
|
mov eax, [esi+addrinfo.ai_addr]
|
||||||
|
mov eax, [eax+sockaddr_in.sin_addr]
|
||||||
|
mov [sockaddr1.ip], eax
|
||||||
|
invoke inet_ntoa, eax
|
||||||
|
; write result
|
||||||
|
invoke con_write_asciiz, eax
|
||||||
|
; free allocated memory
|
||||||
|
invoke freeaddrinfo, esi
|
||||||
|
|
||||||
|
invoke con_write_asciiz, str9
|
||||||
|
|
||||||
|
mcall 40, EVM_STACK + EVM_KEY
|
||||||
|
invoke con_cls
|
||||||
|
|
||||||
|
; Create socket
|
||||||
|
mcall socket, AF_INET4, SOCK_STREAM, 0
|
||||||
|
cmp eax, -1
|
||||||
|
jz socket_err
|
||||||
|
mov [socketnum], eax
|
||||||
|
|
||||||
|
; Connect
|
||||||
|
mcall connect, [socketnum], sockaddr1, 18
|
||||||
|
test eax, eax
|
||||||
|
jnz socket_err
|
||||||
|
|
||||||
|
; Start calculating hash meanwhile
|
||||||
|
call sha256_init
|
||||||
|
; HASH: string V_C, the client's version string (CR and NL excluded)
|
||||||
|
mov esi, ssh_ident_ha
|
||||||
|
mov edx, ssh_ident.length+4-2
|
||||||
|
call sha256_update
|
||||||
|
|
||||||
|
; Send our identification string
|
||||||
|
DEBUGF 1, "Sending ID string\n"
|
||||||
|
mcall send, [socketnum], ssh_ident, ssh_ident.length, 0
|
||||||
|
cmp eax, -1
|
||||||
|
je socket_err
|
||||||
|
|
||||||
|
; Check protocol version of server
|
||||||
|
mcall recv, [socketnum], rx_buffer, BUFFERSIZE, 0
|
||||||
|
cmp eax, -1
|
||||||
|
je socket_err
|
||||||
|
|
||||||
|
DEBUGF 1, "Received ID string\n"
|
||||||
|
cmp dword[rx_buffer], "SSH-"
|
||||||
|
jne proto_err
|
||||||
|
cmp dword[rx_buffer+4], "2.0-"
|
||||||
|
jne proto_err
|
||||||
|
|
||||||
|
; HASH: string V_S, the server's version string (CR and NL excluded)
|
||||||
|
lea edx, [eax+2]
|
||||||
|
sub eax, 2
|
||||||
|
bswap eax
|
||||||
|
mov [rx_buffer-4], eax
|
||||||
|
mov esi, rx_buffer-4
|
||||||
|
call sha256_update
|
||||||
|
|
||||||
|
; Key Exchange init
|
||||||
|
DEBUGF 1, "Sending KEX init\n"
|
||||||
|
mov edi, ssh_kex.cookie
|
||||||
|
call MBRandom
|
||||||
|
stosd
|
||||||
|
call MBRandom
|
||||||
|
stosd
|
||||||
|
call MBRandom
|
||||||
|
stosd
|
||||||
|
call MBRandom
|
||||||
|
stosd
|
||||||
|
stdcall ssh_send_packet, [socketnum], ssh_kex, ssh_kex.length, 0
|
||||||
|
cmp eax, -1
|
||||||
|
je socket_err
|
||||||
|
|
||||||
|
; HASH: string I_C, the payload of the client's SSH_MSG_KEXINIT
|
||||||
|
mov eax, [tx_buffer+ssh_header.length]
|
||||||
|
bswap eax
|
||||||
|
movzx ebx, [tx_buffer+ssh_header.padding]
|
||||||
|
sub eax, ebx
|
||||||
|
dec eax
|
||||||
|
lea edx, [eax+4]
|
||||||
|
bswap eax
|
||||||
|
mov [tx_buffer+1], eax
|
||||||
|
mov esi, tx_buffer+1
|
||||||
|
call sha256_update
|
||||||
|
|
||||||
|
; Check key exchange init of server
|
||||||
|
stdcall ssh_recv_packet, [socketnum], rx_buffer, BUFFERSIZE, 0
|
||||||
|
cmp eax, -1
|
||||||
|
je socket_err
|
||||||
|
|
||||||
|
cmp [rx_buffer+ssh_header.message_code], SSH_MSG_KEXINIT
|
||||||
|
jne proto_err
|
||||||
|
DEBUGF 1, "Received KEX init\n"
|
||||||
|
|
||||||
|
lea esi, [rx_buffer+sizeof.ssh_header+16]
|
||||||
|
lodsd
|
||||||
|
bswap eax
|
||||||
|
DEBUGF 1, "kex_algorithms: %s\n", esi
|
||||||
|
add esi, eax
|
||||||
|
lodsd
|
||||||
|
bswap eax
|
||||||
|
DEBUGF 1, "server_host_key_algorithms: %s\n", esi
|
||||||
|
add esi, eax
|
||||||
|
lodsd
|
||||||
|
bswap eax
|
||||||
|
DEBUGF 1, "encryption_algorithms_client_to_server: %s\n", esi
|
||||||
|
add esi, eax
|
||||||
|
lodsd
|
||||||
|
bswap eax
|
||||||
|
DEBUGF 1, "encryption_algorithms_server_to_client: %s\n", esi
|
||||||
|
add esi, eax
|
||||||
|
lodsd
|
||||||
|
bswap eax
|
||||||
|
DEBUGF 1, "mac_algorithms_client_to_server: %s\n", esi
|
||||||
|
add esi, eax
|
||||||
|
lodsd
|
||||||
|
bswap eax
|
||||||
|
DEBUGF 1, "mac_algorithms_server_to_client: %s\n", esi
|
||||||
|
add esi, eax
|
||||||
|
lodsd
|
||||||
|
bswap eax
|
||||||
|
DEBUGF 1, "compression_algorithms_client_to_server: %s\n", esi
|
||||||
|
add esi, eax
|
||||||
|
lodsd
|
||||||
|
bswap eax
|
||||||
|
DEBUGF 1, "compression_algorithms_server_to_client: %s\n", esi
|
||||||
|
add esi, eax
|
||||||
|
lodsd
|
||||||
|
bswap eax
|
||||||
|
DEBUGF 1, "languages_client_to_server: %s\n", esi
|
||||||
|
add esi, eax
|
||||||
|
lodsd
|
||||||
|
bswap eax
|
||||||
|
DEBUGF 1, "languages_server_to_client: %s\n", esi
|
||||||
|
add esi, eax
|
||||||
|
lodsb
|
||||||
|
DEBUGF 1, "KEX First Packet Follows: %u\n", al
|
||||||
|
|
||||||
|
; TODO
|
||||||
|
|
||||||
|
; HASH: string I_S, the payload of the servers's SSH_MSG_KEXINIT
|
||||||
|
mov eax, [rx_buffer+ssh_header.length]
|
||||||
|
movzx ebx, [rx_buffer+ssh_header.padding]
|
||||||
|
sub eax, ebx
|
||||||
|
dec eax
|
||||||
|
lea edx, [eax+4]
|
||||||
|
bswap eax
|
||||||
|
mov [rx_buffer+sizeof.ssh_header-5], eax
|
||||||
|
mov esi, rx_buffer+sizeof.ssh_header-5
|
||||||
|
call sha256_update
|
||||||
|
|
||||||
|
; Exchange keys with the server
|
||||||
|
stdcall dh_gex
|
||||||
|
test eax, eax
|
||||||
|
jnz exit
|
||||||
|
|
||||||
|
; Set keys
|
||||||
|
DEBUGF 1, "SSH: Init encryption\n"
|
||||||
|
stdcall aes256_cbc_init, rx_iv
|
||||||
|
mov [rx_context], eax
|
||||||
|
stdcall aes256_set_encrypt_key, [rx_context], rx_enc_key
|
||||||
|
mov [decrypt_proc], aes256_cbc_decrypt
|
||||||
|
mov [rx_blocksize], 32
|
||||||
|
|
||||||
|
DEBUGF 1, "SSH: Init decryption\n"
|
||||||
|
stdcall aes256_cbc_init, tx_iv
|
||||||
|
mov [tx_context], eax
|
||||||
|
stdcall aes256_set_decrypt_key, [tx_context], tx_enc_key
|
||||||
|
mov [encrypt_proc], aes256_cbc_encrypt
|
||||||
|
mov [tx_blocksize], 32
|
||||||
|
|
||||||
|
; Launch network thread
|
||||||
|
mcall 18, 7
|
||||||
|
push eax
|
||||||
|
mcall 51, 1, thread, mem - 2048
|
||||||
|
pop ecx
|
||||||
|
mcall 18, 3
|
||||||
|
|
||||||
|
mainloop:
|
||||||
|
call [con_get_flags]
|
||||||
|
test eax, 0x200 ; con window closed?
|
||||||
|
jnz exit
|
||||||
|
|
||||||
|
stdcall ssh_recv_packet, [socketnum], rx_buffer, BUFFERSIZE, 0
|
||||||
|
cmp eax, -1
|
||||||
|
je closed
|
||||||
|
|
||||||
|
DEBUGF 1, 'SSH: got %u bytes of data !\n', eax
|
||||||
|
|
||||||
|
mov esi, rx_buffer
|
||||||
|
mov ecx, eax
|
||||||
|
pusha
|
||||||
|
@@:
|
||||||
|
lodsb
|
||||||
|
DEBUGF 1, "%x ", eax:2
|
||||||
|
dec ecx
|
||||||
|
jnz @r
|
||||||
|
popa
|
||||||
|
lea edi, [esi + eax]
|
||||||
|
mov byte [edi], 0
|
||||||
|
invoke con_write_asciiz, esi
|
||||||
|
jmp mainloop
|
||||||
|
|
||||||
|
proto_err:
|
||||||
|
DEBUGF 1, "SSH: protocol error\n"
|
||||||
|
invoke con_write_asciiz, str7
|
||||||
|
jmp prompt
|
||||||
|
|
||||||
|
socket_err:
|
||||||
|
DEBUGF 1, "SSH: socket error %d\n", ebx
|
||||||
|
invoke con_write_asciiz, str6
|
||||||
|
jmp prompt
|
||||||
|
|
||||||
|
dns_error:
|
||||||
|
DEBUGF 1, "SSH: DNS error %d\n", eax
|
||||||
|
invoke con_write_asciiz, str5
|
||||||
|
jmp prompt
|
||||||
|
|
||||||
|
hostname_error:
|
||||||
|
invoke con_write_asciiz, str10
|
||||||
|
jmp prompt
|
||||||
|
|
||||||
|
closed:
|
||||||
|
invoke con_write_asciiz, str11
|
||||||
|
jmp prompt
|
||||||
|
|
||||||
|
done:
|
||||||
|
invoke con_exit, 1
|
||||||
|
exit:
|
||||||
|
DEBUGF 1, "SSH: Exiting\n"
|
||||||
|
mcall close, [socketnum]
|
||||||
|
mcall -1
|
||||||
|
|
||||||
|
|
||||||
|
thread:
|
||||||
|
mcall 40, 0
|
||||||
|
.loop:
|
||||||
|
invoke con_getch2
|
||||||
|
mov [send_data], ax
|
||||||
|
xor esi, esi
|
||||||
|
inc esi
|
||||||
|
test al, al
|
||||||
|
jnz @f
|
||||||
|
inc esi
|
||||||
|
@@:
|
||||||
|
stdcall ssh_send_packet, [socketnum], send_data, 0
|
||||||
|
|
||||||
|
invoke con_get_flags
|
||||||
|
test eax, 0x200 ; con window closed?
|
||||||
|
jz .loop
|
||||||
|
mcall -1
|
||||||
|
|
||||||
|
; data
|
||||||
|
title db 'Secure Shell',0
|
||||||
|
str1 db 'SSH client for KolibriOS',10,10,\
|
||||||
|
'Please enter URL of SSH server (host:port)',10,10,0
|
||||||
|
str2 db '> ',0
|
||||||
|
str3 db 'Connecting to ',0
|
||||||
|
str4 db 10,0
|
||||||
|
str5 db 'Name resolution failed.',10,10,0
|
||||||
|
str6 db 'A socket error occured.',10,10,0
|
||||||
|
str7 db 'A protocol error occured.',10,10,0
|
||||||
|
str8 db ' (',0
|
||||||
|
str9 db ')',10,0
|
||||||
|
str10 db 'Invalid hostname.',10,10,0
|
||||||
|
str11 db 10,'Remote host closed the connection.',10,10,0
|
||||||
|
|
||||||
|
sockaddr1:
|
||||||
|
dw AF_INET4
|
||||||
|
.port dw 0
|
||||||
|
.ip dd 0
|
||||||
|
rb 10
|
||||||
|
|
||||||
|
ssh_ident_ha:
|
||||||
|
dd_n (ssh_ident.length-2)
|
||||||
|
ssh_ident:
|
||||||
|
db "SSH-2.0-KolibriOS_SSH_0.01",13,10
|
||||||
|
.length = $ - ssh_ident
|
||||||
|
|
||||||
|
ssh_kex:
|
||||||
|
db SSH_MSG_KEXINIT
|
||||||
|
.cookie:
|
||||||
|
rd 4
|
||||||
|
.kex_algorithms:
|
||||||
|
dd_n .server_host_key_algorithms - .kex_algorithms - 4
|
||||||
|
db "diffie-hellman-group-exchange-sha256" ; diffie-hellman-group-exchange-sha1
|
||||||
|
.server_host_key_algorithms:
|
||||||
|
dd_n .encryption_algorithms_client_to_server - .server_host_key_algorithms - 4
|
||||||
|
db "ssh-rsa" ;,ssh-dss
|
||||||
|
.encryption_algorithms_client_to_server:
|
||||||
|
dd_n .encryption_algorithms_server_to_client - .encryption_algorithms_client_to_server - 4
|
||||||
|
db "aes256-cbc" ;,aes256-ctr,aes256-cbc,rijndael-cbc@lysator.liu.se,aes192-ctr,aes192-cbc,aes128-ctr,aes128-cbc,blowfish-ctr,blowfish-cbc,3des-ctr,3des-cbc,arcfour256,arcfour128"
|
||||||
|
.encryption_algorithms_server_to_client:
|
||||||
|
dd_n .mac_algorithms_client_to_server - .encryption_algorithms_server_to_client - 4
|
||||||
|
db "aes256-cbc" ;,aes256-ctr,aes256-cbc,rijndael-cbc@lysator.liu.se,aes192-ctr,aes192-cbc,aes128-ctr,aes128-cbc,blowfish-ctr,blowfish-cbc,3des-ctr,3des-cbc,arcfour256,arcfour128"
|
||||||
|
.mac_algorithms_client_to_server:
|
||||||
|
dd_n .mac_algorithms_server_to_client - .mac_algorithms_client_to_server - 4
|
||||||
|
db "hmac-sha2-256" ;,hmac-sha1,hmac-sha1-96,hmac-md5"
|
||||||
|
.mac_algorithms_server_to_client:
|
||||||
|
dd_n .compression_algorithms_client_to_server - .mac_algorithms_server_to_client - 4
|
||||||
|
db "hmac-sha2-256" ;,hmac-sha1,hmac-sha1-96,hmac-md5"
|
||||||
|
.compression_algorithms_client_to_server:
|
||||||
|
dd_n .compression_algorithms_server_to_client - .compression_algorithms_client_to_server - 4
|
||||||
|
db "none" ;,zlib"
|
||||||
|
.compression_algorithms_server_to_client:
|
||||||
|
dd_n .languages_client_to_server - .compression_algorithms_server_to_client - 4
|
||||||
|
db "none" ;,zlib"
|
||||||
|
.languages_client_to_server:
|
||||||
|
dd_n .languages_server_to_client - .languages_client_to_server - 4
|
||||||
|
db ""
|
||||||
|
.languages_server_to_client:
|
||||||
|
dd_n .first_kex_packet_follows - .languages_server_to_client - 4
|
||||||
|
db ""
|
||||||
|
.first_kex_packet_follows:
|
||||||
|
db 0
|
||||||
|
.reserved:
|
||||||
|
dd_n 0
|
||||||
|
.length = $ - ssh_kex
|
||||||
|
|
||||||
|
|
||||||
|
ssh_gex_req:
|
||||||
|
db SSH_MSG_KEX_DH_GEX_REQUEST
|
||||||
|
dd_n 128 ; DH GEX min
|
||||||
|
dd_n 256 ; DH GEX number of bits
|
||||||
|
dd_n 512 ; DH GEX Max
|
||||||
|
.length = $ - ssh_gex_req
|
||||||
|
|
||||||
|
|
||||||
|
ssh_new_keys:
|
||||||
|
db SSH_MSG_NEWKEYS
|
||||||
|
.length = $ - ssh_new_keys
|
||||||
|
|
||||||
|
|
||||||
|
include_debug_strings
|
||||||
|
|
||||||
|
|
||||||
|
; import
|
||||||
|
align 4
|
||||||
|
@IMPORT:
|
||||||
|
|
||||||
|
library network, 'network.obj', \
|
||||||
|
console, 'console.obj';, \
|
||||||
|
; libcrash, 'libcrash.obj'
|
||||||
|
|
||||||
|
import network, \
|
||||||
|
getaddrinfo, 'getaddrinfo', \
|
||||||
|
freeaddrinfo, 'freeaddrinfo', \
|
||||||
|
inet_ntoa, 'inet_ntoa'
|
||||||
|
|
||||||
|
import console, \
|
||||||
|
con_start, 'START', \
|
||||||
|
con_init, 'con_init', \
|
||||||
|
con_write_asciiz, 'con_write_asciiz', \
|
||||||
|
con_exit, 'con_exit', \
|
||||||
|
con_gets, 'con_gets', \
|
||||||
|
con_cls, 'con_cls', \
|
||||||
|
con_getch2, 'con_getch2', \
|
||||||
|
con_set_cursor_pos, 'con_set_cursor_pos', \
|
||||||
|
con_write_string, 'con_write_string', \
|
||||||
|
con_get_flags, 'con_get_flags'
|
||||||
|
|
||||||
|
;import libcrash, \
|
||||||
|
; crash.hash, 'crash_hash'
|
||||||
|
|
||||||
|
IncludeIGlobals
|
||||||
|
|
||||||
|
i_end:
|
||||||
|
|
||||||
|
decrypt_proc dd dummy_encrypt
|
||||||
|
encrypt_proc dd dummy_encrypt
|
||||||
|
rx_blocksize dd 4
|
||||||
|
tx_blocksize dd 4
|
||||||
|
rx_context dd ?
|
||||||
|
tx_context dd ?
|
||||||
|
|
||||||
|
IncludeUGlobals
|
||||||
|
|
||||||
|
socketnum dd ?
|
||||||
|
rx_packet_length dd ? ;;;;;
|
||||||
|
rx_buffer: rb BUFFERSIZE+1
|
||||||
|
tx_buffer: rb BUFFERSIZE+1
|
||||||
|
|
||||||
|
send_data dw ?
|
||||||
|
|
||||||
|
hostname rb 1024
|
||||||
|
|
||||||
|
; Diffie Hellman variables
|
||||||
|
dh_p dd ?
|
||||||
|
rb MAX_BITS/8
|
||||||
|
dh_g dd ?
|
||||||
|
rb MAX_BITS/8
|
||||||
|
dh_x dd ?
|
||||||
|
rb MAX_BITS/8
|
||||||
|
dh_e dd ?
|
||||||
|
rb MAX_BITS/8
|
||||||
|
dh_f dd ?
|
||||||
|
rb MAX_BITS/8
|
||||||
|
|
||||||
|
dh_signature dd ?
|
||||||
|
rb MAX_BITS/8
|
||||||
|
|
||||||
|
; Output from key exchange
|
||||||
|
dh_K dd ? ; Shared Secret (Big endian)
|
||||||
|
rb MAX_BITS/8
|
||||||
|
.length dd ? ; Length in little endian
|
||||||
|
|
||||||
|
dh_H rb 32 ; Exchange Hash
|
||||||
|
session_id rb 32
|
||||||
|
rx_iv rb 32 ; Rx initialisation vector
|
||||||
|
tx_iv rb 32 ; Tx initialisation vector
|
||||||
|
rx_enc_key rb 32 ; Rx encryption key
|
||||||
|
tx_enc_key rb 32 ; Tx encryption key
|
||||||
|
rx_int_key rb 32 ; Rx integrity key
|
||||||
|
tx_int_key rb 32 ; Tx integrity key
|
||||||
|
|
||||||
|
; Temporary values ; To be removed
|
||||||
|
mpint_tmp rb MPINT_MAX_LEN+4
|
||||||
|
|
||||||
|
mem:
|
153
programs/network/ssh/ssh_transport.inc
Normal file
153
programs/network/ssh/ssh_transport.inc
Normal file
@ -0,0 +1,153 @@
|
|||||||
|
; ssh_transport.inc - SSH transport layer
|
||||||
|
;
|
||||||
|
; Copyright (C) 2016 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/>.
|
||||||
|
|
||||||
|
struct ssh_header
|
||||||
|
length dd ?
|
||||||
|
padding db ?
|
||||||
|
message_code db ?
|
||||||
|
ends
|
||||||
|
|
||||||
|
proc dummy_encrypt _key, _in, _out
|
||||||
|
|
||||||
|
ret
|
||||||
|
endp
|
||||||
|
|
||||||
|
proc ssh_recv_packet sock, buf, size, flags
|
||||||
|
|
||||||
|
locals
|
||||||
|
bufferptr dd ?
|
||||||
|
remaining dd ?
|
||||||
|
padding dd ?
|
||||||
|
endl
|
||||||
|
|
||||||
|
DEBUGF 1, "ssh_recv_packet\n"
|
||||||
|
; Receive first block (Read length, padding length, message code)
|
||||||
|
mcall recv, [sock], [buf], [rx_blocksize], [flags]
|
||||||
|
DEBUGF 1, "chunk = %u\n", eax
|
||||||
|
cmp eax, [rx_blocksize]
|
||||||
|
jne .fail ;;;;
|
||||||
|
|
||||||
|
; stdcall [decrypt_proc], [rx_context], [buf], [buf]
|
||||||
|
|
||||||
|
mov ebx, [buf]
|
||||||
|
movzx eax, [ebx+ssh_header.padding]
|
||||||
|
mov [padding], eax
|
||||||
|
mov eax, [ebx+ssh_header.length]
|
||||||
|
bswap eax ; length to little endian
|
||||||
|
mov [ebx+ssh_header.length], eax
|
||||||
|
DEBUGF 1, "ssh_recv_packet length = %u\n", eax
|
||||||
|
|
||||||
|
cmp eax, [size]
|
||||||
|
ja .fail ;;;;
|
||||||
|
|
||||||
|
sub eax, [rx_blocksize]
|
||||||
|
add eax, 4
|
||||||
|
mov [remaining], eax
|
||||||
|
add ebx, [rx_blocksize]
|
||||||
|
mov [bufferptr], ebx
|
||||||
|
.receive_loop:
|
||||||
|
mcall recv, [sock], [bufferptr], [remaining], 0
|
||||||
|
DEBUGF 1, "chunk = %u\n", eax
|
||||||
|
cmp eax, 0
|
||||||
|
jbe .fail
|
||||||
|
add [bufferptr], eax
|
||||||
|
sub [remaining], eax
|
||||||
|
ja .receive_loop
|
||||||
|
|
||||||
|
; .decrypt_loop:
|
||||||
|
; stdcall [decrypt_proc], [rx_context], [buf], [buf]
|
||||||
|
; ja .decrypt_loop
|
||||||
|
|
||||||
|
; .hmac_loop:
|
||||||
|
; TODO
|
||||||
|
; ja .hmac_loop
|
||||||
|
|
||||||
|
; Return usefull data length in eax
|
||||||
|
mov eax, [buf]
|
||||||
|
movzx ebx, [eax+ssh_header.padding]
|
||||||
|
mov eax, [eax+ssh_header.length]
|
||||||
|
sub eax, ebx
|
||||||
|
DEBUGF 1, "ssh_recv_packet complete, usefull data length=%u\n", eax
|
||||||
|
ret
|
||||||
|
|
||||||
|
.fail:
|
||||||
|
DEBUGF 1, "ssh_recv_packet failed!\n"
|
||||||
|
mov eax, -1
|
||||||
|
ret
|
||||||
|
|
||||||
|
endp
|
||||||
|
|
||||||
|
|
||||||
|
proc ssh_send_packet sock, buf, payloadsize, flags
|
||||||
|
|
||||||
|
locals
|
||||||
|
size dd ?
|
||||||
|
endl
|
||||||
|
DEBUGF 1, "ssh_send_packet: size=%u\n", [payloadsize]
|
||||||
|
|
||||||
|
mov eax, [payloadsize]
|
||||||
|
inc eax ; padding length byte
|
||||||
|
|
||||||
|
lea edx, [eax+4] ; total packet size (without padding)
|
||||||
|
mov [size], edx
|
||||||
|
mov ebx, [tx_blocksize]
|
||||||
|
dec ebx
|
||||||
|
and edx, ebx
|
||||||
|
neg edx
|
||||||
|
add edx, [tx_blocksize]
|
||||||
|
cmp edx, 4 ; minimum padding size
|
||||||
|
jae @f
|
||||||
|
add edx, [tx_blocksize]
|
||||||
|
@@:
|
||||||
|
DEBUGF 1, "Padding %u bytes\n", edx
|
||||||
|
add [size], edx
|
||||||
|
|
||||||
|
add eax, edx
|
||||||
|
DEBUGF 1, "Total size: %u\n", eax
|
||||||
|
bswap eax
|
||||||
|
mov edi, tx_buffer
|
||||||
|
stosd
|
||||||
|
mov al, dl
|
||||||
|
stosb
|
||||||
|
mov esi, [buf]
|
||||||
|
; cmp esi, edi
|
||||||
|
; je @f
|
||||||
|
mov ecx, [payloadsize]
|
||||||
|
rep movsb
|
||||||
|
; @@:
|
||||||
|
|
||||||
|
mov ebx, edx
|
||||||
|
mov esi, edx
|
||||||
|
and ebx, 3
|
||||||
|
jz @f
|
||||||
|
call MBRandom
|
||||||
|
mov dword[edi], eax
|
||||||
|
add edi, ebx
|
||||||
|
@@:
|
||||||
|
|
||||||
|
shr esi, 2
|
||||||
|
@@:
|
||||||
|
call MBRandom
|
||||||
|
stosd
|
||||||
|
dec esi
|
||||||
|
jnz @r
|
||||||
|
|
||||||
|
mcall send, [sock], tx_buffer, [size], [flags]
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
||||||
|
endp
|
279
programs/network/ssh/test/aestest.asm
Normal file
279
programs/network/ssh/test/aestest.asm
Normal file
@ -0,0 +1,279 @@
|
|||||||
|
; aestest.inc - AES test suite
|
||||||
|
;
|
||||||
|
; Copyright (C) 2016 Ivan Baravy (dunkaist)
|
||||||
|
; Copyright (C) 2016 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/>.
|
||||||
|
|
||||||
|
format binary as ""
|
||||||
|
|
||||||
|
use32
|
||||||
|
org 0x0
|
||||||
|
db 'MENUET01'
|
||||||
|
dd 0x01,start,i_end,e_end,e_end,0,0
|
||||||
|
|
||||||
|
__DEBUG__ = 1
|
||||||
|
__DEBUG_LEVEL__ = 1
|
||||||
|
|
||||||
|
include '../../../proc32.inc'
|
||||||
|
include '../../../macros.inc'
|
||||||
|
include '../../../dll.inc'
|
||||||
|
include '../../../debug-fdo.inc'
|
||||||
|
;include 'libcrash.inc'
|
||||||
|
include '../aes256.inc'
|
||||||
|
include '../aes256-ctr.inc'
|
||||||
|
include '../aes256-cbc.inc'
|
||||||
|
|
||||||
|
; Test vectors are taken from the very end of sp800-38a.pdf
|
||||||
|
|
||||||
|
|
||||||
|
start:
|
||||||
|
mcall 68, 11
|
||||||
|
|
||||||
|
DEBUGF 1,'===========================================\n'
|
||||||
|
DEBUGF 1,'AES256_CTR_CRYPT\n'
|
||||||
|
DEBUGF 1,'\n'
|
||||||
|
DEBUGF 1,'key : '
|
||||||
|
stdcall dump_128bit_hex, key
|
||||||
|
DEBUGF 1,'\n'
|
||||||
|
DEBUGF 1,' '
|
||||||
|
stdcall dump_128bit_hex, key+16
|
||||||
|
DEBUGF 1,'\n'
|
||||||
|
DEBUGF 1,'\n'
|
||||||
|
DEBUGF 1,'counter: '
|
||||||
|
stdcall dump_128bit_hex, counter
|
||||||
|
DEBUGF 1,'\n'
|
||||||
|
DEBUGF 1,'\n'
|
||||||
|
|
||||||
|
stdcall aes256_ctr_init, counter
|
||||||
|
; returns context, save it to ebx
|
||||||
|
mov ebx, eax
|
||||||
|
stdcall aes256_set_encrypt_key, ebx, key
|
||||||
|
|
||||||
|
mov esi, plain
|
||||||
|
mov edi, cipher
|
||||||
|
mov ecx, 4
|
||||||
|
@@:
|
||||||
|
push ecx
|
||||||
|
stdcall aes256_ctr_crypt, ebx, esi, edi
|
||||||
|
pop ecx
|
||||||
|
add esi, 16
|
||||||
|
add edi, 16
|
||||||
|
loop @r
|
||||||
|
|
||||||
|
DEBUGF 1,'===========================================\n'
|
||||||
|
DEBUGF 1,'AES256_CBC_ENCRYPT\n'
|
||||||
|
DEBUGF 1,'\n'
|
||||||
|
DEBUGF 1,'key : '
|
||||||
|
stdcall dump_128bit_hex, key
|
||||||
|
DEBUGF 1,'\n'
|
||||||
|
DEBUGF 1,' '
|
||||||
|
stdcall dump_128bit_hex, key+16
|
||||||
|
DEBUGF 1,'\n'
|
||||||
|
DEBUGF 1,'\n'
|
||||||
|
DEBUGF 1,'IV : '
|
||||||
|
stdcall dump_128bit_hex, iv
|
||||||
|
DEBUGF 1,'\n'
|
||||||
|
DEBUGF 1,'\n'
|
||||||
|
|
||||||
|
stdcall aes256_cbc_init, iv
|
||||||
|
; returns context, save it to ebx
|
||||||
|
mov ebx, eax
|
||||||
|
stdcall aes256_set_encrypt_key, ebx, key
|
||||||
|
|
||||||
|
mov esi, plain
|
||||||
|
mov edi, cipher
|
||||||
|
mov ecx, 4
|
||||||
|
@@:
|
||||||
|
push ecx
|
||||||
|
stdcall aes256_cbc_encrypt, ebx, esi, edi
|
||||||
|
pop ecx
|
||||||
|
add esi, 16
|
||||||
|
add edi, 16
|
||||||
|
loop @r
|
||||||
|
|
||||||
|
DEBUGF 1,'===========================================\n'
|
||||||
|
DEBUGF 1,'AES256_CBC_DECRYPT\n'
|
||||||
|
DEBUGF 1,'\n'
|
||||||
|
DEBUGF 1,'key : '
|
||||||
|
stdcall dump_128bit_hex, key
|
||||||
|
DEBUGF 1,'\n'
|
||||||
|
DEBUGF 1,' '
|
||||||
|
stdcall dump_128bit_hex, key+16
|
||||||
|
DEBUGF 1,'\n'
|
||||||
|
DEBUGF 1,'\n'
|
||||||
|
DEBUGF 1,'IV : '
|
||||||
|
stdcall dump_128bit_hex, iv
|
||||||
|
DEBUGF 1,'\n'
|
||||||
|
DEBUGF 1,'\n'
|
||||||
|
|
||||||
|
stdcall aes256_cbc_init, iv
|
||||||
|
; returns context, save it to ebx
|
||||||
|
mov ebx, eax
|
||||||
|
stdcall aes256_set_decrypt_key, ebx, key
|
||||||
|
|
||||||
|
mov esi, cipher
|
||||||
|
mov edi, plain
|
||||||
|
mov ecx, 4
|
||||||
|
@@:
|
||||||
|
push ecx
|
||||||
|
stdcall aes256_cbc_decrypt, ebx, esi, edi
|
||||||
|
pop ecx
|
||||||
|
add esi, 16
|
||||||
|
add edi, 16
|
||||||
|
loop @r
|
||||||
|
|
||||||
|
quit:
|
||||||
|
DEBUGF 1,'===========================================\n'
|
||||||
|
mcall -1
|
||||||
|
|
||||||
|
|
||||||
|
key db 0x60,0x3d,0xeb,0x10,0x15,0xca,0x71,0xbe,0x2b,0x73,0xae,0xf0,\
|
||||||
|
0x85,0x7d,0x77,0x81,0x1f,0x35,0x2c,0x07,0x3b,0x61,0x08,0xd7,\
|
||||||
|
0x2d,0x98,0x10,0xa3,0x09,0x14,0xdf,0xf4
|
||||||
|
|
||||||
|
iv db 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,\
|
||||||
|
0x0c,0x0d,0x0e,0x0f
|
||||||
|
|
||||||
|
counter db 0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,\
|
||||||
|
0xfc,0xfd,0xfe,0xff
|
||||||
|
|
||||||
|
plain db 0x6b,0xc1,0xbe,0xe2,0x2e,0x40,0x9f,0x96,0xe9,0x3d,0x7e,0x11,\
|
||||||
|
0x73,0x93,0x17,0x2a,0xae,0x2d,0x8a,0x57,0x1e,0x03,0xac,0x9c,\
|
||||||
|
0x9e,0xb7,0x6f,0xac,0x45,0xaf,0x8e,0x51,0x30,0xc8,0x1c,0x46,\
|
||||||
|
0xa3,0x5c,0xe4,0x11,0xe5,0xfb,0xc1,0x19,0x1a,0x0a,0x52,0xef,\
|
||||||
|
0xf6,0x9f,0x24,0x45,0xdf,0x4f,0x9b,0x17,0xad,0x2b,0x41,0x7b,\
|
||||||
|
0xe6,0x6c,0x37,0x10
|
||||||
|
|
||||||
|
cipher rd 16
|
||||||
|
|
||||||
|
; CTR-AES256.Encrypt
|
||||||
|
;
|
||||||
|
; Key 603deb1015ca71be2b73aef0857d7781
|
||||||
|
; 1f352c073b6108d72d9810a30914dff4
|
||||||
|
; Init. Counter f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff
|
||||||
|
;
|
||||||
|
;
|
||||||
|
; Block #1
|
||||||
|
;
|
||||||
|
; Input Block f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff
|
||||||
|
; Output Block 0bdf7df1591716335e9a8b15c860c502
|
||||||
|
; Plaintext 6bc1bee22e409f96e93d7e117393172a
|
||||||
|
; Ciphertext 601ec313775789a5b7a7f504bbf3d228
|
||||||
|
;
|
||||||
|
;
|
||||||
|
; Block #2
|
||||||
|
;
|
||||||
|
; Input Block f0f1f2f3f4f5f6f7f8f9fafbfcfdff00
|
||||||
|
; Output Block 5a6e699d536119065433863c8f657b94
|
||||||
|
; Plaintext ae2d8a571e03ac9c9eb76fac45af8e51
|
||||||
|
; Ciphertext f443e3ca4d62b59aca84e990cacaf5c5
|
||||||
|
;
|
||||||
|
;
|
||||||
|
; Block #3
|
||||||
|
;
|
||||||
|
; Input Block f0f1f2f3f4f5f6f7f8f9fafbfcfdff01
|
||||||
|
; Output Block 1bc12c9c01610d5d0d8bd6a3378eca62
|
||||||
|
; Plaintext 30c81c46a35ce411e5fbc1191a0a52ef
|
||||||
|
; Ciphertext 2b0930daa23de94ce87017ba2d84988d
|
||||||
|
;
|
||||||
|
;
|
||||||
|
; Block #4
|
||||||
|
;
|
||||||
|
; Input Block f0f1f2f3f4f5f6f7f8f9fafbfcfdff02
|
||||||
|
; Output Block 2956e1c8693536b1bee99c73a31576b6
|
||||||
|
; Plaintext f69f2445df4f9b17ad2b417be66c3710
|
||||||
|
; Ciphertext dfc9c58db67aada613c2dd08457941a6
|
||||||
|
|
||||||
|
|
||||||
|
; CBC-AES256.Encrypt
|
||||||
|
; Key 603deb1015ca71be2b73aef0857d7781
|
||||||
|
; 1f352c073b6108d72d9810a30914dff4
|
||||||
|
; IV 000102030405060708090a0b0c0d0e0f
|
||||||
|
;
|
||||||
|
; Block #1
|
||||||
|
;
|
||||||
|
; Plaintext 6bc1bee22e409f96e93d7e117393172a
|
||||||
|
; Input Block 6bc0bce12a459991e134741a7f9e1925
|
||||||
|
; Output Block f58c4c04d6e5f1ba779eabfb5f7bfbd6
|
||||||
|
; Ciphertext f58c4c04d6e5f1ba779eabfb5f7bfbd6
|
||||||
|
;
|
||||||
|
; Block #2
|
||||||
|
;
|
||||||
|
; Plaintext ae2d8a571e03ac9c9eb76fac45af8e51
|
||||||
|
; Input Block 5ba1c653c8e65d26e929c4571ad47587
|
||||||
|
; Output Block 9cfc4e967edb808d679f777bc6702c7d
|
||||||
|
; Ciphertext 9cfc4e967edb808d679f777bc6702c7d
|
||||||
|
;
|
||||||
|
; Block #3
|
||||||
|
;
|
||||||
|
; Plaintext 30c81c46a35ce411e5fbc1191a0a52ef
|
||||||
|
; Input Block ac3452d0dd87649c8264b662dc7a7e92
|
||||||
|
; Output Block 39f23369a9d9bacfa530e26304231461
|
||||||
|
; Ciphertext 39f23369a9d9bacfa530e26304231461
|
||||||
|
;
|
||||||
|
; Block #4
|
||||||
|
;
|
||||||
|
; Plaintext f69f2445df4f9b17ad2b417be66c3710
|
||||||
|
; Input Block cf6d172c769621d8081ba318e24f2371
|
||||||
|
; Output Block b2eb05e2c39be9fcda6c19078c6a9d1b
|
||||||
|
; Ciphertext b2eb05e2c39be9fcda6c19078c6a9d1b
|
||||||
|
|
||||||
|
|
||||||
|
; CBC-AES256.Decrypt
|
||||||
|
; Key 603deb1015ca71be2b73aef0857d7781
|
||||||
|
; 1f352c073b6108d72d9810a30914dff4
|
||||||
|
; IV 000102030405060708090a0b0c0d0e0f
|
||||||
|
;
|
||||||
|
; Block #1
|
||||||
|
;
|
||||||
|
; Ciphertext f58c4c04d6e5f1ba779eabfb5f7bfbd6
|
||||||
|
; Input Block f58c4c04d6e5f1ba779eabfb5f7bfbd6
|
||||||
|
; Output Block 6bc0bce12a459991e134741a7f9e1925
|
||||||
|
; Plaintext 6bc1bee22e409f96e93d7e117393172a
|
||||||
|
;
|
||||||
|
; Block #2
|
||||||
|
;
|
||||||
|
; Ciphertext 9cfc4e967edb808d679f777bc6702c7d
|
||||||
|
; Input Block 9cfc4e967edb808d679f777bc6702c7d
|
||||||
|
; Output Block 5ba1c653c8e65d26e929c4571ad47587
|
||||||
|
; Plaintext ae2d8a571e03ac9c9eb76fac45af8e51
|
||||||
|
;
|
||||||
|
; Block #3
|
||||||
|
;
|
||||||
|
; Ciphertext 39f23369a9d9bacfa530e26304231461
|
||||||
|
; Input Block 39f23369a9d9bacfa530e26304231461
|
||||||
|
; Output Block ac3452d0dd87649c8264b662dc7a7e92
|
||||||
|
; Plaintext 30c81c46a35ce411e5fbc1191a0a52ef
|
||||||
|
;
|
||||||
|
; Block #4
|
||||||
|
;
|
||||||
|
; Ciphertext b2eb05e2c39be9fcda6c19078c6a9d1b
|
||||||
|
; Input Block b2eb05e2c39be9fcda6c19078c6a9d1b
|
||||||
|
; Output Block cf6d172c769621d8081ba318e24f2371
|
||||||
|
; Plaintext f69f2445df4f9b17ad2b417be66c3710
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
include_debug_strings
|
||||||
|
|
||||||
|
IncludeIGlobals
|
||||||
|
|
||||||
|
i_end:
|
||||||
|
|
||||||
|
IncludeUGlobals
|
||||||
|
|
||||||
|
rb 0x1000 ;stack
|
||||||
|
e_end:
|
||||||
|
|
185
programs/network/ssh/test/modexp.asm
Normal file
185
programs/network/ssh/test/modexp.asm
Normal file
@ -0,0 +1,185 @@
|
|||||||
|
; modexp.asm - Modular exponentiation test suite
|
||||||
|
;
|
||||||
|
; Copyright (C) 2015-2016 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/>.
|
||||||
|
|
||||||
|
format binary as ""
|
||||||
|
|
||||||
|
__DEBUG__ = 1
|
||||||
|
__DEBUG_LEVEL__ = 1
|
||||||
|
|
||||||
|
MAX_BITS = 256
|
||||||
|
|
||||||
|
use32
|
||||||
|
|
||||||
|
db 'MENUET01' ; signature
|
||||||
|
dd 1 ; header version
|
||||||
|
dd start ; entry point
|
||||||
|
dd i_end ; initialized size
|
||||||
|
dd mem+4096 ; required memory
|
||||||
|
dd mem+4096 ; stack pointer
|
||||||
|
dd 0 ; parameters
|
||||||
|
dd 0 ; path
|
||||||
|
|
||||||
|
include '../../../macros.inc'
|
||||||
|
purge mov,add,sub
|
||||||
|
include '../../../proc32.inc'
|
||||||
|
include '../../../debug-fdo.inc'
|
||||||
|
|
||||||
|
include '../mpint.inc'
|
||||||
|
|
||||||
|
start:
|
||||||
|
|
||||||
|
DEBUGF 1, "ModExp Test suite\n"
|
||||||
|
|
||||||
|
DEBUGF 1, "mpint_zero\n"
|
||||||
|
stdcall mpint_zero, mpint_A
|
||||||
|
stdcall mpint_print, mpint_A
|
||||||
|
|
||||||
|
mov dword[mpint_A+00], 32
|
||||||
|
mov dword[mpint_A+04], 0xCAFEBABE
|
||||||
|
mov dword[mpint_A+08], 0xDEADBEEF
|
||||||
|
mov dword[mpint_A+12], 0xCAFEBABE
|
||||||
|
mov dword[mpint_A+16], 0xDEADBEEF
|
||||||
|
mov dword[mpint_A+20], 0xCAFEBABE
|
||||||
|
mov dword[mpint_A+24], 0xDEADBEEF
|
||||||
|
mov dword[mpint_A+28], 0xCAFEBABE
|
||||||
|
mov dword[mpint_A+32], 0xDEADBEEF
|
||||||
|
stdcall mpint_print, mpint_A
|
||||||
|
|
||||||
|
DEBUGF 1, "mpint_shl, 3\n"
|
||||||
|
stdcall mpint_shl, mpint_A, 3
|
||||||
|
stdcall mpint_length, mpint_A
|
||||||
|
stdcall mpint_print, mpint_A
|
||||||
|
|
||||||
|
DEBUGF 1, "mpint_shl, 40\n"
|
||||||
|
stdcall mpint_shl, mpint_A, 40
|
||||||
|
stdcall mpint_length, mpint_A
|
||||||
|
stdcall mpint_print, mpint_A
|
||||||
|
|
||||||
|
DEBUGF 1, "8 times mpint_shl1\n"
|
||||||
|
stdcall mpint_shl1, mpint_A
|
||||||
|
stdcall mpint_shl1, mpint_A
|
||||||
|
stdcall mpint_shl1, mpint_A
|
||||||
|
stdcall mpint_shl1, mpint_A
|
||||||
|
stdcall mpint_shl1, mpint_A
|
||||||
|
stdcall mpint_shl1, mpint_A
|
||||||
|
stdcall mpint_shl1, mpint_A
|
||||||
|
stdcall mpint_shl1, mpint_A
|
||||||
|
stdcall mpint_length, mpint_A
|
||||||
|
stdcall mpint_print, mpint_A
|
||||||
|
|
||||||
|
mov dword[mpint_B+00], 32
|
||||||
|
mov dword[mpint_B+04], 0xCAFEBABE
|
||||||
|
mov dword[mpint_B+08], 0xDEADBEEF
|
||||||
|
mov dword[mpint_B+12], 0xCAFEBABE
|
||||||
|
mov dword[mpint_B+16], 0xDEADBEEF
|
||||||
|
mov dword[mpint_B+20], 0xCAFEBABE
|
||||||
|
mov dword[mpint_B+24], 0xDEADBEEF
|
||||||
|
mov dword[mpint_B+28], 0xCAFEBABE
|
||||||
|
mov dword[mpint_B+32], 0xDEADBEEF
|
||||||
|
stdcall mpint_print, mpint_A
|
||||||
|
stdcall mpint_print, mpint_B
|
||||||
|
DEBUGF 1, "mpint_add\n"
|
||||||
|
stdcall mpint_add, mpint_B, mpint_A
|
||||||
|
stdcall mpint_length, mpint_B
|
||||||
|
stdcall mpint_print, mpint_B
|
||||||
|
DEBUGF 1, "mpint_sub\n"
|
||||||
|
stdcall mpint_sub, mpint_B, mpint_A
|
||||||
|
stdcall mpint_length, mpint_B
|
||||||
|
stdcall mpint_print, mpint_B
|
||||||
|
|
||||||
|
mov dword[mpint_B+04], 0xCAFEBABE
|
||||||
|
mov dword[mpint_B+08], 0xDEADBEEF
|
||||||
|
mov dword[mpint_B+12], 0xCAFEBABE
|
||||||
|
mov dword[mpint_B+16], 0xDEADBEEF
|
||||||
|
mov dword[mpint_B+20], 0xCAFEBABE
|
||||||
|
mov dword[mpint_B+24], 0xDEADBEEF
|
||||||
|
mov dword[mpint_B+28], 0x0
|
||||||
|
mov dword[mpint_B+32], 0x0
|
||||||
|
stdcall mpint_print, mpint_A
|
||||||
|
stdcall mpint_print, mpint_B
|
||||||
|
DEBUGF 1, "mpint_mod\n"
|
||||||
|
stdcall mpint_mod, mpint_A, mpint_B
|
||||||
|
stdcall mpint_print, mpint_A
|
||||||
|
|
||||||
|
stdcall mpint_zero, mpint_A
|
||||||
|
mov dword[mpint_A+0], 2
|
||||||
|
mov dword[mpint_A+4], 1936
|
||||||
|
stdcall mpint_zero, mpint_B
|
||||||
|
mov dword[mpint_B+0], 2
|
||||||
|
mov dword[mpint_B+4], 497
|
||||||
|
stdcall mpint_cmp, mpint_A, mpint_B
|
||||||
|
stdcall mpint_mod, mpint_A, mpint_B
|
||||||
|
DEBUGF 1, "1936 mod 497\n"
|
||||||
|
stdcall mpint_print, mpint_A
|
||||||
|
|
||||||
|
stdcall mpint_zero, mpint_A
|
||||||
|
mov dword[mpint_A+00], 32
|
||||||
|
mov dword[mpint_A+04], 0xCAFEBABE
|
||||||
|
mov dword[mpint_A+08], 0xDEADBEEF
|
||||||
|
mov dword[mpint_A+12], 0xCAFEBABE
|
||||||
|
mov dword[mpint_A+16], 0xDEADBEEF
|
||||||
|
mov dword[mpint_A+20], 0xCAFEBABE
|
||||||
|
mov dword[mpint_A+24], 0xDEADBEEF
|
||||||
|
mov dword[mpint_A+28], 0xCAFEBABE
|
||||||
|
mov dword[mpint_A+32], 0xDEADBEEF
|
||||||
|
stdcall mpint_zero, mpint_B
|
||||||
|
mov dword[mpint_B+0], 2
|
||||||
|
mov dword[mpint_B+4], 0x0100
|
||||||
|
stdcall mpint_print, mpint_A
|
||||||
|
stdcall mpint_print, mpint_B
|
||||||
|
DEBUGF 1, "mpint_mul by A*B\n"
|
||||||
|
stdcall mpint_mul, mpint_C, mpint_A, mpint_B
|
||||||
|
stdcall mpint_length, mpint_C
|
||||||
|
stdcall mpint_print, mpint_C
|
||||||
|
stdcall mpint_print, mpint_A
|
||||||
|
stdcall mpint_print, mpint_B
|
||||||
|
DEBUGF 1, "mpint_mul by B*A\n"
|
||||||
|
stdcall mpint_mul, mpint_C, mpint_B, mpint_A
|
||||||
|
stdcall mpint_length, mpint_C
|
||||||
|
stdcall mpint_print, mpint_C
|
||||||
|
|
||||||
|
stdcall mpint_hob, mpint_C
|
||||||
|
DEBUGF 1, "mpint_hob: %u\n", eax
|
||||||
|
|
||||||
|
stdcall mpint_zero, mpint_A
|
||||||
|
stdcall mpint_zero, mpint_B
|
||||||
|
stdcall mpint_zero, mpint_C
|
||||||
|
mov dword[mpint_A+0], 1
|
||||||
|
mov dword[mpint_A+4], 4
|
||||||
|
mov dword[mpint_B+0], 1
|
||||||
|
mov dword[mpint_B+4], 13
|
||||||
|
mov dword[mpint_C+0], 2
|
||||||
|
mov dword[mpint_C+4], 497
|
||||||
|
stdcall mpint_modexp, mpint_D, mpint_A, mpint_B, mpint_C
|
||||||
|
DEBUGF 1, "4**13 mod 497\n"
|
||||||
|
stdcall mpint_length, mpint_D
|
||||||
|
stdcall mpint_print, mpint_D
|
||||||
|
|
||||||
|
mcall -1
|
||||||
|
|
||||||
|
i_end:
|
||||||
|
|
||||||
|
mpint_A rb MPINT_MAX_LEN+4
|
||||||
|
mpint_B rb MPINT_MAX_LEN+4
|
||||||
|
mpint_C rb MPINT_MAX_LEN+4
|
||||||
|
mpint_D rb MPINT_MAX_LEN+4
|
||||||
|
|
||||||
|
mpint_tmp rb MPINT_MAX_LEN+4
|
||||||
|
|
||||||
|
include_debug_strings
|
||||||
|
|
||||||
|
mem:
|
Loading…
Reference in New Issue
Block a user