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