Simple Encryption for XMPP (alt: Strawman Encrypted eXchange)

Goal: low-complexity minimal E2EE library for modern XMPP use cases

Design decisions:

Notation: [b64-xyz] is the url-safe base64 encoding of xyz

1:1 Message Encryption

Input:

<message from="bare" to="bare">
  <delay .../>
  <body>Look at my yak!</body>
  <oob url="...yakpic..."/>
</message>

Encryption:

  1. Create nonce: nonce = randombytes_buf(sizeof nonce)
  2. Encrypt message: box = crypto_box(msg, nonce, recipient_pk, my_sk)
  3. Send
<message to="recipient">
  <box xmlns="urn:xmpp:sex:0" nonce="[b64-nonce]">
    [b64-box]
  </box>
</message>

Decryption:

  1. Decrypt payload XML: msg = crypto_box_open(box,nonce,sender_pk,my_sk)

1:N Message Encryption

Encryption:

  1. Create nonce: nonce = randombytes_buf(sizeof nonce)
  2. Create symmetric key: key = crypto_secretbox_keygen()
  3. Encrypt message: sbox = crypto_secretbox_easy(msg, nonce, key)
  4. Encrypt key for each recipient:
  5. Send
<message to="groupchat">
  <multibox xmlns="urn:xmpp:sex:0">
    <keybox nonce="[b64-keynonce[0]]">[b64-keybox[0]]</keybox>
    ...
    <keybox nonce="[b64-keynonce[N]]">[b64-keybox[N]]</keybox>
    <box nonce="[b64-nonce]">
      [b64-sbox]
    </box>
  </multibox>
</message>

Decryption:

TODO

Key Exchange (optional)

The key exchange is an optional protocol to reliably transmit a given secret token between two devices. A possible use case is “masturbation”: synchronize your private key from one of your devices to another (have SEX with yourself).

Goal:

There are two entities, “client” and “server” (in libsodium parlance):

Protocol flow:

  1. Server creates key pair: crypto_kx_keypair(server_pk, server_sk)
  2. Client creates key pair: crypto_kx_keypair(client_pk, client_sk)
  3. Server displays QR code: xmpp:serveruser@domain/resource;sex=[b64-server_pk]
  4. Client scans QR code
  5. Client performs handshake: crypto_kx_client_session_keys(client_rx, client_tx, client_pk, client_sk, server_pk)
  6. Client encrypts own public key with symmetric secret key:
  7. Client sends SEX-KEX (key exchange) message:
<iq to="serveruser@domain/resource" id="f00">
  <sexkex xmlns="urn:xmpp:sex:0">
    <keybox nonce="[b64-keynonce]" pubkey="[b64-client_pk]">[b64-keybox]</keybox>
  </sexkex>
</iq>