Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. ;    sshlib_transport.inc - SSH transport layer
  2. ;
  3. ;    Copyright (C) 2016-2024 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. align 16
  19. proc sshlib_recv_packet_hmac_etm con_ptr, flags
  20.  
  21. locals
  22.         data_length     dd ?    ; Total length of packet without MAC
  23. endl
  24.  
  25.         DEBUGF  3, "> "
  26. ; Receive first block (Read length)
  27.         mov     ebx, [con_ptr]
  28.         mov     ecx, [ebx+sshlib_connection.socketnum]
  29.         mov     esi, 4
  30.         lea     edx, [ebx+sshlib_connection.rx_buffer]
  31.         mov     edi, [flags]
  32.         mcall   recv
  33.         cmp     eax, 0
  34.         jle     .sock_fail
  35.         sub     [ssh_chan.rcv_wnd], eax  ;;; FIXME
  36.         DEBUGF  1, "chunk = %u ", eax
  37.         mov     ebx, [con_ptr]
  38.         cmp     eax, 4
  39.         jne     .proto_fail     ; TODO: handle receives of 1, 2, and 3 bytes correctly
  40.  
  41.         mov     eax, [ebx+sshlib_connection.rx_buffer.packet_length]
  42.         bswap   eax
  43.         mov     [data_length], eax
  44.         DEBUGF  2, "decrypted packet length=%u\n", [data_length]
  45.  
  46.         add     eax, [ebx + sshlib_connection.rx_mac_length]
  47.         cmp     eax, BUFFERSIZE-4
  48.         ja      .proto_fail
  49.  
  50. ; Receive remaining data
  51.         lea     edx, [ebx+sshlib_connection.rx_buffer+4]
  52.         mov     ecx, [ebx+sshlib_connection.socketnum]
  53.         mov     edi, [flags]
  54.         mov     esi, eax
  55.   .recv_loop:
  56.         DEBUGF  3, "want %u bytes.. ", esi
  57.         mcall   recv
  58.         cmp     eax, 0
  59.         jle     .sock_fail
  60.         sub     [ssh_chan.rcv_wnd], eax             ;;; FIXME
  61.         DEBUGF  3, "got %u bytes\n", eax
  62.         add     edx, eax
  63.         sub     esi, eax
  64.         jnz     .recv_loop
  65.  
  66. ; Authenticate message
  67.         mov     ebx, [con_ptr]
  68.         lea     esi, [ebx + sshlib_connection.rx_mac_seqnr]
  69.         mov     ecx, [data_length]
  70.         add     ecx, 8                                          ; packet_length field itself + sequence number
  71.         lea     eax, [ebx + sshlib_connection.rx_mac_ctx]
  72.         lea     edx, [ebx + sshlib_connection.rx_int_key]
  73.         stdcall [ebx + sshlib_connection.rx_mac_proc], eax, esi, ecx, edx, SHA2_256_LEN
  74.  
  75.         lea     esi, [ebx + sshlib_connection.rx_mac_ctx]
  76.         lea     edi, [ebx + sshlib_connection.rx_buffer+4]
  77.         add     edi, [data_length]
  78.         mov     ecx, [ebx + sshlib_connection.rx_mac_length]
  79.         shr     ecx, 2
  80.         repe cmpsd     ; TODO: constant time
  81.         jne     .mac_fail
  82.  
  83. ; Decrypt the payload
  84.         lea     eax, [ebx+sshlib_connection.rx_crypt_ctx]
  85.         lea     edi, [ebx+sshlib_connection.rx_buffer+4]
  86.         stdcall [ebx + sshlib_connection.rx_crypt_proc], eax, edi, [data_length], edi
  87.  
  88. ; Update sequence counter
  89.         add     byte[ebx+sshlib_connection.rx_mac_seqnr+3], 1
  90.         adc     byte[ebx+sshlib_connection.rx_mac_seqnr+2], 0
  91.         adc     byte[ebx+sshlib_connection.rx_mac_seqnr+1], 0
  92.         adc     byte[ebx+sshlib_connection.rx_mac_seqnr+0], 0
  93.  
  94. ; Return useful data length to the caller via eax register
  95.         mov     eax, [data_length]
  96.         mov     [ebx+sshlib_connection.rx_buffer.packet_length], eax
  97.         movzx   ebx, [ebx+sshlib_connection.rx_buffer.padding_length]
  98.         sub     eax, ebx
  99.         DEBUGF  1, "useful data length=%u\n", eax
  100.         ret
  101.  
  102.   .sock_fail:
  103.         DEBUGF  3, "ssh_recv_packet failed!\n"
  104.         mov     eax, SSHLIB_ERR_SOCKET
  105.         ret
  106.  
  107.   .mac_fail:
  108.         DEBUGF  3, "ssh_recv_packet message authentication failed!\n"
  109.         mov     eax, SSHLIB_ERR_MAC_VERIFY_FAIL
  110.         xor     ebx, ebx
  111.         ret
  112.  
  113.   .proto_fail:
  114.         DEBUGF  3, "ssh_recv_packet protocol failure!\n"
  115.         mov     eax, SSHLIB_ERR_PROTOCOL
  116.         xor     ebx, ebx
  117.         ret
  118.  
  119. endp
  120.  
  121.  
  122. align 16
  123. proc sshlib_send_packet_hmac_etm con_ptr, buf, payload_size, flags
  124.  
  125. locals
  126.         padded_size     dd ?    ; payload with padding (without length field or MAC)
  127. endl
  128.         DEBUGF  2, "< "
  129.  
  130. ; Check how many bytes we should pad
  131.         mov     eax, [payload_size]
  132.         inc     eax                     ; padding length byte
  133.  
  134.         mov     ecx, [con_ptr]
  135.         mov     edx, eax
  136.         mov     ebx, [ecx + sshlib_connection.tx_pad_size]
  137.         dec     ebx
  138.         and     edx, ebx
  139.         neg     edx
  140.         add     edx, [ecx + sshlib_connection.tx_pad_size]
  141.         add     edx, [ecx + sshlib_connection.tx_pad_size]
  142.         DEBUGF  2, "padding %u bytes ", edx
  143.         add     eax, edx
  144.         mov     [padded_size], eax      ; total packet size with padding, without MAC
  145.  
  146. ; Start building the packet
  147. ; First comes the packet length, in network byte order ofcourse.
  148.         DEBUGF  2, "total size: %u ", eax
  149.         bswap   eax
  150.         lea     edi, [ecx + sshlib_connection.tx_buffer]
  151.         stosd
  152. ; Then the padding length
  153.         mov     al, dl
  154.         stosb
  155. ;;; And the actual payload bytes
  156.         mov     esi, [buf]
  157.         mov     ecx, [payload_size]
  158.         rep movsb
  159.  
  160. ; Append the packet with #edx padding bytes.
  161. ; Since we must pad at least 8 bytes, we can always use DWORD writes.
  162. ; First do an (unaligned) write exactly following the data
  163.         dec     edx
  164.         mov     esi, edx
  165.         shr     esi, 2          ; number dwords
  166.         mov     ebx, edx
  167.         and     ebx, 3
  168.         inc     ebx             ; number bytes in first write (1-4)
  169.         call    MBRandom
  170.         mov     dword[edi], eax
  171.         add     edi, ebx
  172. ; Then, do as many aligned writes as nescessary
  173.   @@:
  174.         call    MBRandom
  175.         stosd
  176.         dec     esi
  177.         jnz     @r
  178.  
  179. ; Encrypt the payload
  180.         mov     ebx, [con_ptr]
  181.         lea     esi, [ebx + sshlib_connection.tx_crypt_ctx]
  182.         lea     edi, [ebx + sshlib_connection.tx_buffer+4]
  183.         stdcall [ebx + sshlib_connection.tx_crypt_proc], esi, edi, [padded_size], edi
  184.  
  185. ; Append the packet with Message Authentication Code
  186. ;        mov     ebx, [con_ptr]
  187.         DEBUGF  1, "MAC sequence number: 0x%x\n", [ebx + sshlib_connection.tx_mac_seqnr]
  188.         lea     esi, [ebx + sshlib_connection.tx_mac_seqnr]
  189.         mov     ecx, [padded_size]
  190.         add     ecx, 8                                          ; Sequence number length + packet length field
  191.         lea     eax, [ebx + sshlib_connection.tx_mac_ctx]
  192.         lea     edx, [ebx + sshlib_connection.tx_int_key]
  193.         stdcall [ebx + sshlib_connection.tx_mac_proc], eax, esi, ecx, edx, SHA2_256_LEN
  194.  
  195.         mov     ebx, [con_ptr]
  196.         lea     esi, [ebx + sshlib_connection.tx_mac_ctx]
  197.         lea     edi, [ebx + sshlib_connection.tx_buffer+4]
  198.         add     edi, [padded_size]
  199.         mov     ecx, [ebx + sshlib_connection.tx_mac_length]
  200.         shr     ecx, 2
  201.         rep movsd
  202.  
  203. ; Update sequence counter
  204.         add     byte[ebx+sshlib_connection.tx_mac_seqnr+3], 1
  205.         adc     byte[ebx+sshlib_connection.tx_mac_seqnr+2], 0
  206.         adc     byte[ebx+sshlib_connection.tx_mac_seqnr+1], 0
  207.         adc     byte[ebx+sshlib_connection.tx_mac_seqnr+0], 0
  208.  
  209. ; Send the packet
  210. ;        mov     ebx, [con_ptr]
  211.         mov     ecx, [ebx+sshlib_connection.socketnum]
  212.         lea     edx, [ebx+sshlib_connection.tx_buffer]
  213.         mov     esi, [padded_size]
  214.         add     esi, 4
  215.         add     esi, [ebx+sshlib_connection.tx_mac_length]
  216.         mov     edi, [flags]
  217.         mcall   send
  218.  
  219.         DEBUGF  2, "\n"
  220.  
  221.         ret
  222.  
  223. endp
  224.  
  225.