How does the SSH server know the length of data encrypted? In am learning the SSH RFC


  An encryption algorithm and a key will be negotiated during the key
     exchange.  When encryption is in effect, the packet length, padding
     length, payload, and padding fields of each packet MUST be encrypted
     with the given algorithm.


So the structure of the packet would be like that. How does the SSH server or client know the real length of the encrypted data?


                                  payload
                 [byte[packet_length - padding_length - 1]]
                                     ^
                                     |
       packet_length                 |             mac (Message Authentication Code - MAC)
          [uint32]                   |                        [byte[mac_length]]
             ^                       |                                ^
             |                       |                                |
             |                       |                                |
+-------+--------------------------------------------------------------------+
|       |    |                       |   ssh                          |      |
|       | +----------------------------------------------------------------+ |
|       | |-----------------------------------------------------|     |    | |
|       | || |  |   |                |               |         ||     |    | |
|  tcp  | || |  |   |                |               |         ||     |    | |
|       | || +  | + |            +   +               |    +    ||     +    | |
|       | ||    | | |            |                   |    |    ||          | |
|       | |-----------------------------------------------------|          | |
|       | |----------------------------------------------------------------+ |
+-------+--------------------------------------------------------------------+
                  |              |                        |
                  |              |                        |
                  |              |                        |
                  v              |                        v
               [byte]            |              [byte[padding_length]]
            padding_length       |                  random padding
                                 |
                                 |
                                 |
                                 |
                                 |
                                 |
                                 |
                                 v
                           encrypted_data
Quoting the SSH protocol:


  "Note that the 'packet_length' field is also encrypted, and processing it requires special care when sending or receiving packets."


Generally ciphers process bytes from left to right. This means that the packet length can be available before the encryption is ended (or before all the information is received, for that matter).

This is a horrible protocol decision because it means you have to interleave between the packet decoding and decryption layer, and you will get the message length before it is authenticated. Still, it is practically doable.

There is probably one advantage: you can add more padding to avoid some side channel attacks that use the length of the send packages. However, this advantage is hard to use, because you'd now also have to mix the application and encryption code.

Note that the other sizes - such as MAC length - are determined by the protocol and protocol configuration during the handshake.