Previous: , Up: Developer manual  


Handshake protocol

     ┌──────┐                                  ┌──────┐                         
     │Client│                                  │Server│                         
     └──┬───┘                                  └──┬───┘                         
        │────┐                                    │                             
        │    │ R=rand(64bit)                      │                             
        │<───┘                                    │                             
        │                                         │                             
        │────┐                                    │                             
        │    │ CPrivKey=rand(256bit)              │                             
        │<───┘                                    │                             
        │                                         │                             
        │         R, enc(PSK, R, CPubKey)         │                             
        │ ────────────────────────────────────────>                             
        │                                         │                             
        │                                         │────┐                        
        │                                         │    │ SPrivKey=rand(256bit)  
        │                                         │<───┘                        
        │                                         │                             
        │                                         │────┐                        
        │                                         │    │ K=DH(SPrivKey, CPubKey)
        │                                         │<───┘                        
        │                                         │                             
        │                                         │────┐                        
        │                                         │    │ RS=rand(64bit)         
        │                                         │<───┘                        
        │                                         │                             
        │                                         │────┐                        
        │                                         │    │ SS=rand(256bit)        
        │                                         │<───┘                        
        │                                         │                             
        │ enc(PSK, R+1, SPubKey); enc(K, R, RS+SS)│                             
        │ <────────────────────────────────────────                             
        │                                         │                             
        │────┐                                    │                             
        │    │ K=DH(CPrivKey, SPubKey)            │                             
        │<───┘                                    │                             
        │                                         │                             
        │────┐                                    │                             
        │    │ RC=rand(64bit); SC=rand(256bit)    │                             
        │<───┘                                    │                             
        │                                         │                             
        │          enc(K, R+1, RS+RC+SC)          │                             
        │ ────────────────────────────────────────>                             
        │                                         │                             
        │                                         │────┐                        
        │                                         │    │ compare(RS)            
        │                                         │<───┘                        
        │                                         │                             
        │                                         │────┐                        
        │                                         │    │ MasterKey=SS XOR SC    
        │                                         │<───┘                        
        │                                         │                             
        │             enc(K, 0x00, RC)            │                             
        │ <────────────────────────────────────────                             
        │                                         │                             
        │────┐                                    │                             
        │    │ compare(RC)                        │                             
        │<───┘                                    │                             
        │                                         │                             
        │────┐                                    │                             
        │    │ MasterKey=SS XOR SC                │                             
        │<───┘                                    │                             
     ┌──┴───┐                                  ┌──┴───┐                         
     │Client│                                  │Server│                         
     └──────┘                                  └──────┘                         

Each handshake message ends with so called IDtag: it is an XTEA encrypted first 64 bits of each message with client’s identity as a key. It is used to transmit identity and to mark packet as handshake message. Server can determine used identity by trying all possible known to him keys. It consumes resources, but XTEA is rather fast algorithm and handshake messages checking is seldom enough event.

  1. client generates CPubKey, random 64bit R that is used as a nonce for encryption
  2. R + enc(PSK, R, CPubKey) + IDtag -> Server [48 bytes]
  3. server remembers clients address, decrypt CPubKey, generates SPrivKey/SPubKey, computes common shared key K (based on CPubKey and SPrivKey), generates 64bit random number RS and 256bit random SS. PSK-encryption uses incremented R (from previous message) for nonce
  4. enc(PSK, R+1, SPubKey) + enc(K, R, RS + SS) + IDtag -> Client [80 bytes]
  5. client decrypt SPubKey, computes K, decrypts RS, SS with key K, remembers SS, generates 64bit random number RC and 256bit random SC,
  6. enc(K, R+1, RS + RC + SC) + IDtag -> Server [56 bytes]
  7. server decrypt RS, RC, SC with key K, compares RS with it’s own one send before, computes final main encryption key S = SS XOR SC
  8. ENC(K, 0, RC) + IDtag -> Client [16 bytes]
  9. server switches to the new client
  10. client decrypts RC and compares with it’s own generated one, computes final main encryption key S

Where PSK is 256bit pre-shared key. R* are required for handshake randomization and two-way authentication. K key is used only during handshake. DH public keys can be trivially derived from private ones.


Previous: , Up: Developer manual