Subversion Repositories Kolibri OS

Rev

Rev 6419 | Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

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