Subversion Repositories Kolibri OS

Rev

Rev 6469 | Rev 9071 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
6419 hidnplayr 1
;    ssh_transport.inc - SSH transport layer
2
;
9070 hidnplayr 3
;    Copyright (C) 2016-2021 Jeffrey Amelynck
6419 hidnplayr 4
;
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
7
;    the Free Software Foundation, either version 3 of the License, or
8
;    (at your option) any later version.
9
;
10
;    This program is distributed in the hope that it will be useful,
11
;    but WITHOUT ANY WARRANTY; without even the implied warranty of
12
;    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
;    GNU General Public License for more details.
14
;
15
;    You should have received a copy of the GNU General Public License
16
;    along with this program.  If not, see .
17
 
6469 hidnplayr 18
 
19
struct  ssh_packet_header
20
        packet_length   dd ?    ; The length of the packet in bytes, not including 'mac' or the
21
                                ; 'packet_length' field itself.
22
        padding_length  db ?    ; Length of 'random padding' (bytes).
23
 
24
        message_code    db ?    ; First byte of payload
6419 hidnplayr 25
ends
26
 
27
 
6469 hidnplayr 28
proc ssh_recv_packet connection, flags
6419 hidnplayr 29
 
30
locals
6469 hidnplayr 31
        data_length     dd ?    ; Total length of packet without MAC
9070 hidnplayr 32
        socket_error    dd ?
6419 hidnplayr 33
endl
34
 
6469 hidnplayr 35
        DEBUGF  2, "> "
6419 hidnplayr 36
; Receive first block (Read length, padding length, message code)
6469 hidnplayr 37
        mov     ebx, [connection]
38
        mov     ecx, [ebx+ssh_connection.socketnum]
39
        mov     esi, [ebx+ssh_connection.rx_crypt_blocksize]
40
        lea     edx, [ebx+ssh_connection.rx_buffer]
41
        mov     edi, [flags]
42
        mcall   recv
9070 hidnplayr 43
        mov     [socket_error], ebx
6469 hidnplayr 44
        DEBUGF  1, "chunk = %u ", eax
45
        mov     ebx, [connection]
46
        cmp     eax, [ebx+ssh_connection.rx_crypt_blocksize]
47
        jne     .fail
6419 hidnplayr 48
 
6469 hidnplayr 49
; Decrypt first block
50
        cmp     [ebx+ssh_connection.rx_crypt_proc], 0
51
        je      @f
52
        pusha
53
        lea     esi, [ebx+ssh_connection.rx_buffer]
54
        stdcall [ebx+ssh_connection.rx_crypt_proc], [ebx+ssh_connection.rx_crypt_ctx_ptr], esi, esi
55
        popa
56
  @@:
6419 hidnplayr 57
 
6469 hidnplayr 58
; Check data length
59
        mov     esi, [ebx+ssh_connection.rx_buffer.packet_length]
60
        bswap   esi                                             ; convert length to little endian
61
        mov     [ebx+ssh_connection.rx_buffer.packet_length], esi
62
        DEBUGF  1, "packet length=%u ", esi
63
        cmp     esi, BUFFERSIZE
64
        ja      .fail                                           ; packet is too large
6419 hidnplayr 65
 
6469 hidnplayr 66
; Calculate amount of remaining data
67
        add     esi, 4                                          ; Packet length field itself is not included in the count
68
        sub     esi, [ebx+ssh_connection.rx_crypt_blocksize]    ; Already received this amount of data
69
        add     esi, [ebx+ssh_connection.rx_mac_length]
70
        jz      .got_all_data
6419 hidnplayr 71
 
6469 hidnplayr 72
; Receive remaining data
73
        lea     edx, [ebx+ssh_connection.rx_buffer]
74
        add     edx, [ebx+ssh_connection.rx_crypt_blocksize]
75
        mov     ecx, [ebx+ssh_connection.socketnum]
76
        mov     edi, [flags]
6419 hidnplayr 77
  .receive_loop:
6469 hidnplayr 78
        mcall   recv
79
        DEBUGF  1, "chunk = %u ", eax
6419 hidnplayr 80
        cmp     eax, 0
81
        jbe     .fail
6469 hidnplayr 82
        add     edx, eax
83
        sub     esi, eax
84
        jnz     .receive_loop
6419 hidnplayr 85
 
6469 hidnplayr 86
; Decrypt data
87
        mov     ebx, [connection]
88
        cmp     [ebx+ssh_connection.rx_crypt_proc], 0
89
        je      .decrypt_complete
90
        mov     ecx, [ebx+ssh_connection.rx_buffer.packet_length]
91
        add     ecx, 4                                          ; Packet_length field itself
92
        sub     ecx, [ebx+ssh_connection.rx_crypt_blocksize]    ; Already decrypted this amount of data
93
        jz      .decrypt_complete
6419 hidnplayr 94
 
6469 hidnplayr 95
        lea     esi, [ebx+ssh_connection.rx_buffer]
96
        add     esi, [ebx+ssh_connection.rx_crypt_blocksize]
97
  .decrypt_loop:
98
        pusha
99
        stdcall [ebx+ssh_connection.rx_crypt_proc], [ebx+ssh_connection.rx_crypt_ctx_ptr], esi, esi
100
        popa
101
        add     esi, [ebx+ssh_connection.rx_crypt_blocksize]
102
        sub     ecx, [ebx+ssh_connection.rx_crypt_blocksize]
103
        jnz     .decrypt_loop
104
  .decrypt_complete:
6419 hidnplayr 105
 
6469 hidnplayr 106
; Authenticate message
107
        cmp     [ebx+ssh_connection.rx_mac_proc], 0
108
        je      .mac_complete
109
        lea     esi, [ebx+ssh_connection.rx_seq]
110
        mov     ecx, [ebx+ssh_connection.rx_buffer.packet_length]
111
        add     ecx, 8                                          ; packet_length field itself + sequence number
112
        lea     eax, [ebx+ssh_connection.rx_mac_ctx]
113
        mov     edx, [ebx+ssh_connection.rx_buffer.packet_length]
114
        bswap   edx                                             ; convert length to big endian
115
        mov     [ebx+ssh_connection.rx_buffer.packet_length], edx
116
        stdcall [ebx+ssh_connection.rx_mac_proc], eax, esi, ecx
117
        mov     edx, [ebx+ssh_connection.rx_buffer.packet_length]
118
        bswap   edx                                             ; convert length to little endian
119
        mov     [ebx+ssh_connection.rx_buffer.packet_length], edx
120
 
121
        lea     esi, [ebx+ssh_connection.rx_mac_ctx]
122
        lea     edi, [ebx+ssh_connection.rx_buffer]
123
        add     edi, [ebx+ssh_connection.rx_buffer.packet_length]
124
        add     edi, 4
125
        mov     ecx, [ebx+ssh_connection.rx_mac_length]
126
        shr     ecx, 2
127
        repe cmpsd
128
        jne     .mac_failed
129
  .mac_complete:
130
        inc     byte[ebx+ssh_connection.rx_seq+3]               ; Update sequence counter
131
        jnc     @f
132
        inc     byte[ebx+ssh_connection.rx_seq+2]
133
        jnc     @f
134
        inc     byte[ebx+ssh_connection.rx_seq+1]
135
        jnc     @f
136
        inc     byte[ebx+ssh_connection.rx_seq+0]
137
  @@:
138
 
139
; Return useful data length to the caller via eax register
140
  .got_all_data:
141
        mov     eax, [ebx+ssh_connection.rx_buffer.packet_length]
142
        movzx   ebx, [ebx+ssh_connection.rx_buffer.padding_length]
6419 hidnplayr 143
        sub     eax, ebx
6469 hidnplayr 144
        DEBUGF  1, "useful data length=%u\n", eax
6419 hidnplayr 145
        ret
146
 
147
  .fail:
6469 hidnplayr 148
        DEBUGF  3, "ssh_recv_packet failed!\n"
6419 hidnplayr 149
        mov     eax, -1
9070 hidnplayr 150
        mov     ebx, [socket_error]
6419 hidnplayr 151
        ret
152
 
6469 hidnplayr 153
  .mac_failed:
154
        DEBUGF  3, "ssh_recv_packet MAC failed!\n"
9070 hidnplayr 155
        mov     eax, -2
156
        mov     ebx, [socket_error]
6469 hidnplayr 157
        ret
158
 
6419 hidnplayr 159
endp
160
 
161
 
6469 hidnplayr 162
proc ssh_send_packet connection, buf, payload_size, flags
6419 hidnplayr 163
 
164
locals
6469 hidnplayr 165
        packet_size    dd ?
6419 hidnplayr 166
endl
6469 hidnplayr 167
        DEBUGF  2, "< "
6419 hidnplayr 168
 
6469 hidnplayr 169
; Pad the packet with random data
170
        mov     eax, [payload_size]
171
        inc     eax                     ; padding length byte
172
        lea     edx, [eax+4]            ; total packet size (without padding and MAC)
173
        mov     [packet_size], edx
174
        mov     ecx, [connection]
9070 hidnplayr 175
        mov     ebx, [ecx+ssh_connection.tx_padsize]
6419 hidnplayr 176
        dec     ebx
177
        and     edx, ebx
178
        neg     edx
9070 hidnplayr 179
        add     edx, [ecx+ssh_connection.tx_padsize]
6469 hidnplayr 180
        cmp     edx, 4                  ; minimum padding size
6419 hidnplayr 181
        jae     @f
9070 hidnplayr 182
        add     edx, [ecx+ssh_connection.tx_padsize]
6419 hidnplayr 183
  @@:
6469 hidnplayr 184
        DEBUGF  1, "padding %u bytes ", edx
185
        add     [packet_size], edx
6419 hidnplayr 186
 
187
        add     eax, edx
6469 hidnplayr 188
        DEBUGF  1, "total size: %u ", eax
6419 hidnplayr 189
        bswap   eax
6469 hidnplayr 190
        lea     edi, [ecx+ssh_connection.tx_buffer]
191
        stosd                           ; packet_length
6419 hidnplayr 192
        mov     al, dl
6469 hidnplayr 193
        stosb                           ; padding_length
6419 hidnplayr 194
        mov     esi, [buf]
6469 hidnplayr 195
        mov     ecx, [payload_size]
6419 hidnplayr 196
        rep movsb
197
 
198
        mov     ebx, edx
199
        mov     esi, edx
200
        and     ebx, 3
201
        jz      @f
202
        call    MBRandom
203
        mov     dword[edi], eax
204
        add     edi, ebx
205
  @@:
206
 
207
        shr     esi, 2
208
  @@:
209
        call    MBRandom
210
        stosd
211
        dec     esi
212
        jnz     @r
213
 
6469 hidnplayr 214
; Message authentication
215
        mov     edx, [connection]
216
        cmp     [edx+ssh_connection.tx_mac_proc], 0
217
        je      .mac_complete
218
;        DEBUGF  1, "MAC sequence number: 0x%x\n", [edx+ssh_connection.tx_seq]
219
        lea     esi, [edx+ssh_connection.tx_seq]
220
        mov     ecx, [packet_size]
221
        add     ecx, 4                                          ; Sequence number length
222
        lea     eax, [edx+ssh_connection.tx_mac_ctx]
223
        stdcall [edx+ssh_connection.tx_mac_proc], eax, esi, ecx
6419 hidnplayr 224
 
6469 hidnplayr 225
        lea     esi, [edx+ssh_connection.tx_mac_ctx]
226
        lea     edi, [edx+ssh_connection.tx_buffer]
227
        add     edi, [packet_size]
228
        mov     ecx, [edx+ssh_connection.tx_mac_length]
229
        shr     ecx, 2
230
        rep movsd
231
  .mac_complete:
232
        inc     byte[edx+ssh_connection.tx_seq+3]               ; Update sequence counter
233
        jnc     @f
234
        inc     byte[edx+ssh_connection.tx_seq+2]
235
        jnc     @f
236
        inc     byte[edx+ssh_connection.tx_seq+1]
237
        jnc     @f
238
        inc     byte[edx+ssh_connection.tx_seq+0]
239
  @@:
240
 
241
; Encrypt data
242
        cmp     [edx+ssh_connection.tx_crypt_proc], 0
243
        je      .encrypt_complete
244
        lea     esi, [edx+ssh_connection.tx_buffer]
245
        mov     ecx, [packet_size]
246
  .encrypt_loop:
247
        pusha
248
        stdcall [edx+ssh_connection.tx_crypt_proc], [edx+ssh_connection.tx_crypt_ctx_ptr], esi, esi
249
        popa
250
        add     esi, [edx+ssh_connection.tx_crypt_blocksize]
251
        sub     ecx, [edx+ssh_connection.tx_crypt_blocksize]
252
        jnz     .encrypt_loop
253
  .encrypt_complete:
254
 
255
; Send the packet
256
        mov     ebx, [connection]
257
        mov     ecx, [ebx+ssh_connection.socketnum]
258
        lea     edx, [ebx+ssh_connection.tx_buffer]
259
        mov     esi, [packet_size]
260
        add     esi, [ebx+ssh_connection.tx_mac_length]
261
        mov     edi, [flags]
262
        mcall   send
263
 
264
        DEBUGF  1, "\n"
265
 
6419 hidnplayr 266
        ret
267
 
6469 hidnplayr 268
endp
269