Subversion Repositories Kolibri OS

Rev

Rev 9071 | Rev 9987 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 9071 Rev 9106
Line 1... Line 1...
1
;    ssh_transport.inc - SSH transport layer
1
;    sshlib_transport.inc - SSH transport layer
2
;
2
;
3
;    Copyright (C) 2016-2021 Jeffrey Amelynck
3
;    Copyright (C) 2016-2021 Jeffrey Amelynck
4
;
4
;
5
;    This program is free software: you can redistribute it and/or modify
5
;    This program is free software: you can redistribute it and/or modify
6
;    it under the terms of the GNU General Public License as published by
6
;    it under the terms of the GNU General Public License as published by
Line 14... Line 14...
14
;
14
;
15
;    You should have received a copy of the GNU General Public License
15
;    You should have received a copy of the GNU General Public License
16
;    along with this program.  If not, see .
16
;    along with this program.  If not, see .
Line 17... Line 17...
17
 
17
 
18
 
-
 
19
struct  ssh_packet_header
-
 
20
        packet_length   dd ?    ; The length of the packet in bytes, not including 'mac' or the
-
 
Line 21... Line 18...
21
                                ; 'packet_length' field itself.
18
 
-
 
19
proc sshlib_padd_null
-
 
20
 
22
        padding_length  db ?    ; Length of 'random padding' (bytes).
21
        xor     eax, eax
Line -... Line 22...
-
 
22
        ret
-
 
23
 
23
 
24
endp
Line 24... Line -...
24
        message_code    db ?    ; First byte of payload
-
 
25
ends
25
 
Line 26... Line 26...
26
 
26
proc sshlib_crypt_null ctx, src, dst
Line 27... Line 27...
27
proc padding_zero
27
 
Line 28... Line 28...
28
 
28
; Assume src == dst !
29
        xor     eax, eax
29
 
30
        ret
-
 
31
 
30
        ret
Line 32... Line 31...
32
endp
31
 
33
 
32
endp
34
proc ssh_recv_packet connection, flags
33
 
35
 
34
proc sshlib_recv_packet con_ptr, flags
36
locals
35
 
37
        data_length     dd ?    ; Total length of packet without MAC
36
locals
38
        socket_error    dd ?
37
        data_length     dd ?    ; Total length of packet without MAC
39
endl
38
endl
-
 
39
 
40
 
40
        DEBUGF  3, "> "
-
 
41
; Receive first block (Read length, padding length, message code)
41
        DEBUGF  2, "> "
42
        mov     ebx, [con_ptr]
42
; Receive first block (Read length, padding length, message code)
43
        mov     ecx, [ebx+sshlib_connection.socketnum]
43
        mov     ebx, [connection]
44
        mov     esi, [ebx+sshlib_connection.rx_crypt_blocksize]
44
        mov     ecx, [ebx+ssh_connection.socketnum]
45
        lea     edx, [ebx+sshlib_connection.rx_buffer]
Line 45... Line 46...
45
        mov     esi, [ebx+ssh_connection.rx_crypt_blocksize]
46
        mov     edi, [flags]
46
        lea     edx, [ebx+ssh_connection.rx_buffer]
-
 
47
        mov     edi, [flags]
-
 
48
        mcall   recv
47
        mcall   recv
49
        mov     [socket_error], ebx
48
        cmp     eax, 0
50
        DEBUGF  1, "chunk = %u ", eax
49
        jle     .sock_fail
51
        mov     ebx, [connection]
50
        sub     [ssh_chan.rcv_wnd], eax  ;;; FIXME
52
        cmp     eax, [ebx+ssh_connection.rx_crypt_blocksize]
-
 
Line 53... Line 51...
53
        jne     .fail
51
        DEBUGF  1, "chunk = %u ", eax
54
 
52
        mov     ebx, [con_ptr]
55
; Decrypt first block
53
        cmp     eax, [ebx+sshlib_connection.rx_crypt_blocksize]
56
        cmp     [ebx+ssh_connection.rx_crypt_proc], 0
54
        jne     .proto_fail     ; TODO: handle receives of 1, 2, and 3 bytes correctly
57
        je      @f
55
 
58
        pusha
56
; Decrypt first block
59
        lea     esi, [ebx+ssh_connection.rx_buffer]
57
        pusha
Line 60... Line 58...
60
        stdcall [ebx+ssh_connection.rx_crypt_proc], [ebx+ssh_connection.rx_crypt_ctx_ptr], esi, esi
58
        lea     esi, [ebx+sshlib_connection.rx_buffer]
61
        popa
59
        stdcall [ebx+sshlib_connection.rx_crypt_proc], [ebx+sshlib_connection.rx_crypt_ctx_ptr], esi, esi
62
  @@:
60
        popa
63
 
61
 
64
; Check data length
62
; Check data length
Line 65... Line 63...
65
        mov     esi, [ebx+ssh_connection.rx_buffer.packet_length]
63
        mov     esi, [ebx + sshlib_connection.rx_buffer.packet_length]
66
        bswap   esi                                             ; convert length to little endian
64
        bswap   esi                                             ; convert length to little endian
67
        mov     [ebx+ssh_connection.rx_buffer.packet_length], esi
65
        mov     [ebx+sshlib_connection.rx_buffer.packet_length], esi
68
        DEBUGF  1, "packet length=%u ", esi
66
        DEBUGF  1, "packet length=%u ", esi
69
        cmp     esi, BUFFERSIZE
67
        cmp     esi, BUFFERSIZE
70
        ja      .fail                                           ; packet is too large
68
        ja      .proto_fail                                     ; packet is too large
-
 
69
 
71
 
70
; Calculate amount of remaining data
72
; Calculate amount of remaining data
-
 
73
        add     esi, 4                                          ; Packet length field itself is not included in the count
71
        add     esi, 4                                          ; Packet length field itself is not included in the count
74
        sub     esi, [ebx+ssh_connection.rx_crypt_blocksize]    ; Already received this amount of data
72
        sub     esi, [ebx+sshlib_connection.rx_crypt_blocksize]    ; Already received this amount of data
-
 
73
        add     esi, [ebx+sshlib_connection.rx_mac_length]
-
 
74
        jz      .packet_complete
75
        add     esi, [ebx+ssh_connection.rx_mac_length]
75
 
76
        jz      .got_all_data
76
; Receive remaining data
77
 
77
        lea     edx, [ebx+sshlib_connection.rx_buffer]
Line 78... Line 78...
78
; Receive remaining data
78
        add     edx, [ebx+sshlib_connection.rx_crypt_blocksize]
79
        lea     edx, [ebx+ssh_connection.rx_buffer]
79
        mov     ecx, [ebx+sshlib_connection.socketnum]
80
        add     edx, [ebx+ssh_connection.rx_crypt_blocksize]
-
 
81
        mov     ecx, [ebx+ssh_connection.socketnum]
-
 
82
        mov     edi, [flags]
80
        mov     edi, [flags]
83
  .receive_loop:
81
  .receive_loop:
84
        mcall   recv
82
        DEBUGF  3, "want %d bytes.. ", esi
85
        DEBUGF  1, "chunk = %u ", eax
83
        mcall   recv
Line 86... Line 84...
86
        cmp     eax, 0
84
        cmp     eax, 0
87
        jbe     .fail
85
        jle     .sock_fail
88
        add     edx, eax
86
        sub     [ssh_chan.rcv_wnd], eax             ;;; FIXME
89
        sub     esi, eax
87
        DEBUGF  3, "got %d bytes\n", eax
90
        jnz     .receive_loop
88
        add     edx, eax
91
 
89
        sub     esi, eax
92
; Decrypt data
90
        jnz     .receive_loop
93
        mov     ebx, [connection]
91
 
94
        cmp     [ebx+ssh_connection.rx_crypt_proc], 0
92
; Decrypt data
95
        je      .decrypt_complete
93
        mov     ebx, [con_ptr]
Line 96... Line 94...
96
        mov     ecx, [ebx+ssh_connection.rx_buffer.packet_length]
94
        mov     ecx, [ebx + sshlib_connection.rx_buffer.packet_length]
97
        add     ecx, 4                                          ; Packet_length field itself
95
        add     ecx, 4                                          ; Packet_length field itself
98
        sub     ecx, [ebx+ssh_connection.rx_crypt_blocksize]    ; Already decrypted this amount of data
96
        sub     ecx, [ebx+sshlib_connection.rx_crypt_blocksize]    ; Already decrypted this amount of data
99
        jz      .decrypt_complete
97
        jz      .decrypt_complete
100
 
98
 
101
        lea     esi, [ebx+ssh_connection.rx_buffer]
99
        lea     esi, [ebx+sshlib_connection.rx_buffer]
102
        add     esi, [ebx+ssh_connection.rx_crypt_blocksize]
100
        add     esi, [ebx+sshlib_connection.rx_crypt_blocksize]
-
 
101
  .decrypt_loop:
103
  .decrypt_loop:
102
        pusha
104
        pusha
103
        stdcall [ebx+sshlib_connection.rx_crypt_proc], [ebx+sshlib_connection.rx_crypt_ctx_ptr], esi, esi
105
        stdcall [ebx+ssh_connection.rx_crypt_proc], [ebx+ssh_connection.rx_crypt_ctx_ptr], esi, esi
104
        popa
106
        popa
105
        add     esi, [ebx+sshlib_connection.rx_crypt_blocksize]
-
 
106
        sub     ecx, [ebx+sshlib_connection.rx_crypt_blocksize]
107
        add     esi, [ebx+ssh_connection.rx_crypt_blocksize]
107
        jnz     .decrypt_loop
108
        sub     ecx, [ebx+ssh_connection.rx_crypt_blocksize]
108
  .decrypt_complete:
109
        jnz     .decrypt_loop
109
 
Line 110... Line 110...
110
  .decrypt_complete:
110
; Authenticate message
111
 
111
        cmp     [ebx+sshlib_connection.rx_mac_proc], 0
112
; Authenticate message
112
        je      .mac_complete
113
        cmp     [ebx+ssh_connection.rx_mac_proc], 0
-
 
114
        je      .mac_complete
113
        lea     esi, [ebx+sshlib_connection.rx_mac_seqnr]
115
        lea     esi, [ebx+ssh_connection.rx_seq]
114
        mov     ecx, [ebx+sshlib_connection.rx_buffer.packet_length]
116
        mov     ecx, [ebx+ssh_connection.rx_buffer.packet_length]
115
        add     ecx, 8                                          ; packet_length field itself + sequence number
117
        add     ecx, 8                                          ; packet_length field itself + sequence number
116
        lea     eax, [ebx+sshlib_connection.rx_mac_ctx]
118
        lea     eax, [ebx+ssh_connection.rx_mac_ctx]
117
;        push    [ebx+sshlib_connection.rx_buffer.packet_length]
119
        mov     edx, [ebx+ssh_connection.rx_buffer.packet_length]
118
        mov     edx, [ebx+sshlib_connection.rx_buffer.packet_length]
120
        bswap   edx                                             ; convert length to big endian
119
        bswap   edx                                             ; convert length to big endian
121
        mov     [ebx+ssh_connection.rx_buffer.packet_length], edx
120
        mov     [ebx+sshlib_connection.rx_buffer.packet_length], edx
122
        stdcall [ebx+ssh_connection.rx_mac_proc], eax, esi, ecx
121
        stdcall [ebx+sshlib_connection.rx_mac_proc], eax, esi, ecx
Line 123... Line 122...
123
        mov     edx, [ebx+ssh_connection.rx_buffer.packet_length]
122
;        pop     [ebx+sshlib_connection.rx_buffer.packet_length]
124
        bswap   edx                                             ; convert length to little endian
123
        mov     edx, [ebx+sshlib_connection.rx_buffer.packet_length]
125
        mov     [ebx+ssh_connection.rx_buffer.packet_length], edx
124
        bswap   edx                                             ; convert length to little endian
126
 
125
        mov     [ebx+sshlib_connection.rx_buffer.packet_length], edx
127
        lea     esi, [ebx+ssh_connection.rx_mac_ctx]
126
 
128
        lea     edi, [ebx+ssh_connection.rx_buffer]
127
        lea     esi, [ebx+sshlib_connection.rx_mac_ctx]
129
        add     edi, [ebx+ssh_connection.rx_buffer.packet_length]
128
        lea     edi, [ebx+sshlib_connection.rx_buffer+4]
Line 130... Line 129...
130
        add     edi, 4
129
        add     edi, [ebx+sshlib_connection.rx_buffer.packet_length]
131
        mov     ecx, [ebx+ssh_connection.rx_mac_length]
130
        mov     ecx, [ebx+sshlib_connection.rx_mac_length]
132
        shr     ecx, 2
131
        shr     ecx, 2
-
 
132
        repe cmpsd
-
 
133
        jne     .mac_fail
-
 
134
  .mac_complete:
-
 
135
        add     byte[ebx+sshlib_connection.rx_mac_seqnr+3], 1      ; Update sequence counter
-
 
136
        adc     byte[ebx+sshlib_connection.rx_mac_seqnr+2], 0
133
        repe cmpsd
137
        adc     byte[ebx+sshlib_connection.rx_mac_seqnr+1], 0
134
        jne     .mac_failed
138
        adc     byte[ebx+sshlib_connection.rx_mac_seqnr+0], 0
Line 135... Line 139...
135
  .mac_complete:
139
 
136
        add     byte[ebx+ssh_connection.rx_seq+3], 1            ; Update sequence counter
140
; Return useful data length to the caller via eax register
137
        adc     byte[ebx+ssh_connection.rx_seq+2], 0
141
  .packet_complete:
138
        adc     byte[ebx+ssh_connection.rx_seq+1], 0
142
        mov     eax, [ebx+sshlib_connection.rx_buffer.packet_length]
139
        adc     byte[ebx+ssh_connection.rx_seq+0], 0
143
        movzx   ebx, [ebx+sshlib_connection.rx_buffer.padding_length]
Line 140... Line 144...
140
 
144
        sub     eax, ebx
Line 141... Line 145...
141
; Return useful data length to the caller via eax register
145
        DEBUGF  1, "useful data length=%u\n", eax
Line 142... Line 146...
142
  .got_all_data:
146
        ret
143
        mov     eax, [ebx+ssh_connection.rx_buffer.packet_length]
147
 
144
        movzx   ebx, [ebx+ssh_connection.rx_buffer.padding_length]
148
  .sock_fail:
145
        sub     eax, ebx
149
        DEBUGF  3, "ssh_recv_packet failed!\n"
Line 172... Line 176...
172
        mov     eax, [payload_size]
176
        mov     eax, [payload_size]
173
        inc     eax                     ; padding length byte
177
        inc     eax                     ; padding length byte
174
        lea     edx, [eax+4]            ; total packet size (without padding and MAC)
178
        lea     edx, [eax+4]            ; total packet size (without padding and MAC)
175
        mov     [packet_size], edx
179
        mov     [packet_size], edx
Line 176... Line 180...
176
 
180
 
177
        mov     ecx, [connection]
181
        mov     ecx, [con_ptr]
178
        mov     ebx, [ecx+ssh_connection.tx_pad_size]
182
        mov     ebx, [ecx+sshlib_connection.tx_pad_size]
179
        dec     ebx
183
        dec     ebx
180
        and     edx, ebx
184
        and     edx, ebx
181
        neg     edx
185
        neg     edx
182
        add     edx, [ecx+ssh_connection.tx_pad_size]
186
        add     edx, [ecx+sshlib_connection.tx_pad_size]
183
        add     edx, [ecx+ssh_connection.tx_pad_size]
187
        add     edx, [ecx+sshlib_connection.tx_pad_size]
184
        DEBUGF  1, "padding %u bytes ", edx
188
        DEBUGF  1, "padding %u bytes ", edx
Line 185... Line 189...
185
        add     [packet_size], edx      ; total packet size with padding
189
        add     [packet_size], edx      ; total packet size with padding
186
 
190
 
187
; Start building the packet
191
; Start building the packet
188
; First comes the packet length, in network byte order ofcourse.
192
; First comes the packet length, in network byte order ofcourse.
189
        add     eax, edx
193
        add     eax, edx
190
        DEBUGF  1, "total size: %u ", eax
194
        DEBUGF  1, "total size: %u ", eax
191
        bswap   eax
195
        bswap   eax
192
        lea     edi, [ecx+ssh_connection.tx_buffer]
196
        lea     edi, [ecx+sshlib_connection.tx_buffer]
193
        stosd
197
        stosd
194
; Then the padding length
198
; Then the padding length
195
        mov     al, dl
199
        mov     al, dl
Line 206... Line 210...
206
        mov     esi, edx
210
        mov     esi, edx
207
        shr     esi, 2          ; number dwords
211
        shr     esi, 2          ; number dwords
208
        mov     ebx, edx
212
        mov     ebx, edx
209
        and     ebx, 3
213
        and     ebx, 3
210
        inc     ebx             ; number bytes in first write (1-4)
214
        inc     ebx             ; number bytes in first write (1-4)
211
        mov     edx, [connection]
215
        mov     edx, [con_ptr]
212
        call    [edx+ssh_connection.tx_pad_proc]
216
        call    [edx+sshlib_connection.tx_pad_proc]
213
        mov     dword[edi], eax
217
        mov     dword[edi], eax
214
        add     edi, ebx
218
        add     edi, ebx
215
; Then, do as many aligned writes as nescessary
219
; Then, do as many aligned writes as nescessary
216
        mov     ebx, [connection]
220
        mov     ebx, [con_ptr]
217
  @@:
221
  @@:
218
        call    [ebx+ssh_connection.tx_pad_proc]
222
        call    [ebx+sshlib_connection.tx_pad_proc]
219
        stosd
223
        stosd
220
        dec     esi
224
        dec     esi
221
        jnz     @r
225
        jnz     @r
Line 222... Line 226...
222
 
226
 
223
; Append the packet with Message Authentication Code
227
; Append the packet with Message Authentication Code
224
        mov     edx, [connection]
228
        mov     edx, [con_ptr]
225
        cmp     [edx+ssh_connection.tx_mac_proc], 0
229
        cmp     [edx+sshlib_connection.tx_mac_proc], 0
226
        je      .mac_complete
230
        je      .mac_complete
227
        DEBUGF  1, "MAC sequence number: 0x%x\n", [edx+ssh_connection.tx_seq]
231
        DEBUGF  1, "MAC sequence number: 0x%x\n", [edx+sshlib_connection.tx_mac_seqnr]
228
        lea     esi, [edx+ssh_connection.tx_seq]
232
        lea     esi, [edx+sshlib_connection.tx_mac_seqnr]
229
        mov     ecx, [packet_size]
233
        mov     ecx, [packet_size]
230
        add     ecx, 4                                          ; Sequence number length
234
        add     ecx, 4                                          ; Sequence number length
231
        lea     eax, [edx+ssh_connection.tx_mac_ctx]
235
        lea     eax, [edx+sshlib_connection.tx_mac_ctx]
Line 232... Line 236...
232
        stdcall [edx+ssh_connection.tx_mac_proc], eax, esi, ecx
236
        stdcall [edx+sshlib_connection.tx_mac_proc], eax, esi, ecx
233
 
237
 
234
        lea     esi, [edx+ssh_connection.tx_mac_ctx]
238
        lea     esi, [edx+sshlib_connection.tx_mac_ctx]
235
        lea     edi, [edx+ssh_connection.tx_buffer]
239
        lea     edi, [edx+sshlib_connection.tx_buffer]
236
        add     edi, [packet_size]
240
        add     edi, [packet_size]
237
        mov     ecx, [edx+ssh_connection.tx_mac_length]
241
        mov     ecx, [edx+sshlib_connection.tx_mac_length]
238
        shr     ecx, 2
242
        shr     ecx, 2
239
        rep movsd
243
        rep movsd
240
  .mac_complete:
244
  .mac_complete:
241
        add     byte[edx+ssh_connection.tx_seq+3], 1            ; Update sequence counter
245
        add     byte[edx+sshlib_connection.tx_mac_seqnr+3], 1      ; Update sequence counter
242
        adc     byte[edx+ssh_connection.tx_seq+2], 0
246
        adc     byte[edx+sshlib_connection.tx_mac_seqnr+2], 0
Line 243... Line 247...
243
        adc     byte[edx+ssh_connection.tx_seq+1], 0
247
        adc     byte[edx+sshlib_connection.tx_mac_seqnr+1], 0
244
        adc     byte[edx+ssh_connection.tx_seq+0], 0
-
 
245
 
-
 
246
; Now, encrypt everything but MAC
248
        adc     byte[edx+sshlib_connection.tx_mac_seqnr+0], 0
247
        cmp     [edx+ssh_connection.tx_crypt_proc], 0
249
 
248
        je      .encrypt_complete
250
; Now, encrypt everything but MAC
249
        lea     esi, [edx+ssh_connection.tx_buffer]
251
        lea     esi, [edx+sshlib_connection.tx_buffer]
250
        mov     ecx, [packet_size]
252
        mov     ecx, [packet_size]
251
  .encrypt_loop:
253
  .encrypt_loop:
252
        pusha
254
        pusha
253
        stdcall [edx+ssh_connection.tx_crypt_proc], [edx+ssh_connection.tx_crypt_ctx_ptr], esi, esi
255
        stdcall [edx+sshlib_connection.tx_crypt_proc], [edx+sshlib_connection.tx_crypt_ctx_ptr], esi, esi
254
        popa
256
        popa
255
        add     esi, [edx+ssh_connection.tx_crypt_blocksize]
-
 
Line 256... Line 257...
256
        sub     ecx, [edx+ssh_connection.tx_crypt_blocksize]
257
        add     esi, [edx+sshlib_connection.tx_crypt_blocksize]
257
        jnz     .encrypt_loop
258
        sub     ecx, [edx+sshlib_connection.tx_crypt_blocksize]
258
  .encrypt_complete:
259
        jnz     .encrypt_loop
259
 
260
 
260
; Send the packet
261
; Send the packet
261
        mov     ebx, [connection]
262
        mov     ebx, [con_ptr]
262
        mov     ecx, [ebx+ssh_connection.socketnum]
263
        mov     ecx, [ebx+sshlib_connection.socketnum]
263
        lea     edx, [ebx+ssh_connection.tx_buffer]
264
        lea     edx, [ebx+sshlib_connection.tx_buffer]
Line 264... Line 265...
264
        mov     esi, [packet_size]
265
        mov     esi, [packet_size]