Added disclosure field and Back Doors section
Replaced secure field with security field; changed otr field to list-single
Harmonised session termination with the protocol added to XEP-0155; added XML schema; minor clarifications
Added Upgradability requirement; added expires field to offline options; updated in line with latest version of PEP; moved some content to new XEPs (0187, 0188 and 0189)
Modified protocol in line with SIGMA: added Identity Protection requirement, no pre-indication of acceptable keys, send multiple values of e with ESession request, offline options published via SPPS, added LZW compression
Added diagramatic synopses; Added match_resource field; replaced req_mac and kid fields with prev_hash; Alice specifies initial counter (doubles as nonce); many other improvements
Simplified XML normalization; added Synopsis and Efficiency requirement; defined signature formats
Extended termination procedure; added object encryption/signing requirement and special case; clarified expired MAC publishing; added Flexible Offline Message Retrieval to Open Issues.
Added flexibility requirement; added late signature of initial request; added termination MAC.
Added (offline) replay protection; required offline Created header; compression is NOT RECOMMENDED; added second set of offline options for subscribers; added JIDs to session key generation; unencrypted sessions; added secure option; sign whole data form; HMAC whole <encrypted/> element; added ESession termination; option to distribute public keys within session negotiation; added Integrity requirement; several clarifications
Restored status to Experimental; complete rewrite; new Introduction, Background, Requirements and Security Considerations; new OTR-inspired protocol; XEP-0155-based negotiation; counter mode encryption; more secure hashes; offline sessions; re-keying; mac publishing; preliminary key and options publishing protocol.
At the request of the author, changed status to Retracted.
Initial version.
End-to-end encryption is a desirable feature for any communication technology. Ideally, such a technology would design encryption in from the beginning and would forbid unencrypted communications. Realistically, most communication technologies have not been designed in that manner, and Jabber/XMPP technologies are no exception. In particular, the original Jabber technologies developed in 1999 did not include end-to-end encryption by default. PGP-based encryption of message bodies and signing of presence information was added as an extension to the core protocols in the year 2000; this extension is documented in &xep0027;. When the core protocols were formalized within the Internet Standards Process by the IETF's XMPP Working Group in 2003, a different extension was defined using S/MIME-based signing and encryption of CPIM-formatted messages (see &rfc3862;) and PIDF-formatted presence information (see &rfc3863;); this extension is specified in &rfc3923;.
For reasons described in &xep0188;, the foregoing proposals (and others not mentioned) have not been widely implemented and deployed. This is unfortunate, since an open communication protocol needs to enable end-to-end encryption in order to be seriously considered for deployment by a broad range of users.
This proposal describes a different approach to end-to-end encryption for use by entities that communicate using XMPP. The requirements and the consequent cryptographic design that underpin this protocol are described in Cryptographic Design of Encrypted Sessions. The basic concept is that of an encrypted session which acts as a secure tunnel between two endpoints. Once the tunnel is established, the content of each one-to-one XML stanza exchanged between the endpoints will be encrypted and then transmitted within a "wrapper" stanza.
This document introduces two characters to help the reader follow the necessary exchanges:
While Alice and Bob are introduced as "end users", they are simply meant to be examples of Jabber entities. Any directly addressable Jabber entity may participate in an ESession.
Before attempting to engage in an ESession with Bob, Alice MAY discover whether he supports this protocol, using either &xep0030; or the presence-based profile of XEP-0030 specified in &xep0115;.
The normal course of events is for Alice to authenticate with her server, retrieve her roster (see RFC 3921), send initial presence to her server, and then receive presence information from all the contacts in her roster. If the presence information she receives from some contacts does not include capabilities data (per XEP-0115), Alice SHOULD then send a service discovery information ("disco#info") request to each of those contacts (in accordance with XEP-0030). Such initial service discovery stanzas MUST NOT be considered part of encrypted communication sessions for the purposes of this document, since they perform a "bootstrapping" function that is a prerequisite to encrypted communications. The disco#info request sent from Alice to Bob might look as follows:
If Bob sends a disco#info reply and he supports the protocol defined herein, then he MUST include a service discovery feature variable of "http://jabber.org/protocol/esession".
The process for establishing a secure session over an insecure transport is essentially a negotiation of various ESession algorithms and other parameters, combined with a translation into XMPP syntax of the σ approach to key exchange (see Cryptographic Design of Encrypted Sessions).
If Alice believes Bob may be online then she SHOULD use the protocol specified in &xep0155; and in this section to negotiate the ESession options and the keys.
Note: If Alice believes Bob is offline then she SHOULD NOT use this negotiation protocol. However, she MAY use the protocol specified in Offline Encrypted Sessions to establish the ESession options and keys. Alternatively, she MAY send stanzas without encryption - in which case her client MUST make absolutely clear to her that the stanzas will not be protected and give her the option not to send the stanzas.
Note: In any case, Alice MUST NOT initiate a new ESession with Bob if she already has one established with him.
In addition to the "accept", "security", "otr" and "disclosure" fields (see Back Doors) specified in Chat Session Negotiation, Alice MUST send to Bob each of the ESession options (see list below) that she is willing to use, in her order of preference (see Mandatory to Implement Technologies). Note: Alice SHOULD NOT include a "reason" field since Aunt Tillie may not be aware the ESession request is not encrypted.
The list of Modular Exponential (MODP) group numbers (as specified in &rfc2409; or &rfc3526;) that MAY be used for Diffie-Hellman key exchange (valid group numbers include 1,2,3,4,5,14,15,16,17 and 18)
Symmetric block cipher algorithm names
Hash algorithm names
Signature algorithm names
Compression algorithm names
The list of stanza types that MAY be encrypted and decrypted
Whether or not the other entity MUST send the fingerprint of its public signature-verification key instead of the full key
The different versions of this protocol that are supported
The minimum number of stanzas that MUST be exchanged before an entity MAY initiate a key re-exchange (1 - every stanza, 100 - every hundred stanzas). Note: This value MUST be less than &twosup32; (see Re-Keying Limits)
Each MODP group has at least two well known constants: a large prime number p, and a generator g for a subgroup of GF(p). For each MODP group that Alice specifies she MUST perform the following computations to calculate her Diffie-Hellman keys (where n is the number of bits per cipher block for the block cipher algorithm with the largest block size out of those she specified):
Generate a secret random number x (where &twosup2n; < x < p - 1)
Calculate e = &gsupx; mod p
Alice MUST send all her calculated values of e to Bob (in the same order as the associated MODP groups are being sent). She MUST also specify randomly generated Base64 encoded (in accordance with Section 3 of &rfc3548;) value of &NsubA; (her ESession ID).
If Bob does not want to reveal presence to Alice for whatever reason then Bob SHOULD return no response or error.
If Bob supports none of the options for one or more ESession fields, then he SHOULD return a ¬acceptable; error and SHOULD specify the field(s) with unsupported options in a comma-separated list in the XMPP <text/> element:
Either Bob or Alice MAY attempt to initiate a new ESession after any error during the negotiation process. However, both MUST consider the previous negotiation to have failed and MUST discard any information learned through the previous negotiation.
If Bob is unwilling to start an ESession, but he is ready to initiate a one-to-one chat session with Alice (see Chat Session Negotiation), and if Alice included an option for the "security" field with the value "none" or "c2s", then Bob SHOULD accept the Chat Session and terminate the ESession negotiation by specifying "none" or "c2s" for the value of the "security" field in his response.
If Bob supports one or more of each of Alice's ESession options and is willing to start an ESession with Alice, then he MUST select one of the options from each of the ESession fields he received from Alice including one hash algorithm ("HASH"), and one of the MODP groups and Alice's corresponding value of e (see &rfc3766; or RFC 3526 for recommendations regarding balancing the sizes of symmetric cipher blocks and Diffie-Hellman moduli).
Each MODP group has at least two well known constants: a large prime number p, and a generator g for a subgroup of GF(p). Bob SHOULD return a &feature; error unless: 1 < e < p - 1
Bob MUST then perform the following computations (where n is the number of bits per cipher block for the selected block cipher algorithm):
Generate a random number &NsubB; (his ESession ID)
Generate an n-bit random number &CsubA; (the block cipher counter for stanzas sent from Alice to Bob)
Set &CBeCAx2n1; (where &CsubB; is the block counter for stanzas sent from Bob to Alice)
Generate a secret random number y (where &twosup2n; < y < p - 1)
Calculate d = &gsupy; mod p
Calculate K = HASH(&esupy; mod p) (the shared secret)
Bob MUST use the shared secret ("K") and the selected hash algorithm ("HASH") to generate two sets of three keys, one set for each direction of the ESession.
For stanzas that Alice will send to Bob, the keys are calculated as:
Encryption key &KCsubA; = HASH(K, 0)
Integrity key &KMsubA; = HASH(K, 2)
SIGMA key &KSsubA; = HASH(K, 4)
For stanzas that Bob will send to Alice the keys are calculated as:
Encryption key &KCsubB; = HASH(K, 1)
Integrity key &KMsubB; = HASH(K, 3)
SIGMA key &KSsubB; = HASH(K, 5)
Once the sets of keys have been calculated the value of K MUST be securely destroyed.
Note: As many bits of key data as are needed for each key MUST be taken from the least significant bits of the hash output. When negotiating a hash, entities MUST ensure that the hash output is no shorter than the required key data. For algorithms with variable-length keys the maximum length (up to the hash output length) SHOULD be used.
Bob MUST perform the following steps before he can prove his identity to Alice while protecting it from third parties.
Select &pubKeyB;, the public key Alice should use to authenticate his signature with the signature algorithm he selected ("SIGN").
Set &formB; to the Normalized content of the reponse data form he will send back to Alice (including his responses for all the fields he received from Alice).
Bob MUST encapsulate the Base64 encoded values of &CsubA; and Alice's &NsubA; in two new 'counter' and 'nonce' fields and add them to &formB;. He MUST set the 'pk_hash' field to specify whether or not Alice MUST send the fingerprint of her public signature-verification key instead of her full key. He MUST set the value of the 'rekey_freq' field to be less than &twosup32; and greater than or equal to the value specified by Alice. Bob MUST place his Base64 encoded values of &NsubB; and d in the 'my_nonce' and 'keys' fields. Note: Bob MUST NOT return Alice's values of &NsubA; and e in these fields.
Concatenate Alice's ESession ID, Bob's ESession ID, d, &pubKeyB; and &formB;, and calculate the HMAC (as defined in Section 2 of &rfc2104;) of the resulting byte string using the selected hash algorithm ("HASH") and the key &KSsubB;.
&macB; = HMAC(HASH, &KSsubB;, {&NsubA;, &NsubB;, d, &pubKeyB;, &formB;})
Calculate &signB;, the signature of the HMAC result using his private signature key that corresponds to &pubKeyB;
&signB; = SIGN(&signKeyB;, &macB;)
If the value of the 'pk_hash' field that Alice sent Bob was true then Bob SHOULD set &pubKeyB; to the key's fingerprint
if (pk_hash) &pubKeyB; = HASH(&pubKeyB;)
Concatenate &pubKeyB; and &signB; and encrypt the resulting byte string with the agreed algorithm ("CIPHER") in counter mode (see &nistfips800-38a;), using the encryption key &KCsubB; and block counter &CsubB;. Note: &CsubB; MUST be incremented by 1 for each encrypted block or partial block (i.e. &CsubB; = (&CsubB; + 1) mod 2n, where n is the number of bits per cipher block for the agreed block cipher algorithm).
&IDB; = CIPHER(&KCsubB;, &CsubB;, {&pubKeyB;, &signB;})
Calculate the HMAC of the encrypted identity (&IDB;) and the value of Bob's block cipher counter &CsubB; before the encryption above using the selected hash algorithm ("HASH") and the integrity key &KMsubB;.
&MsubB; = HMAC(HASH, &KMsubB;, &CsubB;, &IDB;)
Bob responds to Alice by sending her &formB;.
If Bob prefers the RECOMMENDED 3-message ESession negotiation, where Alice's identity is protected from active attacks instead of his own, then he should encapsulate the Base64 encoded values of &IDB; and &MsubB; in data form fields ('identity' and 'mac'), and append the new fields to &formB; before sending it to Alice.
After Alice receives Bob's response, she MUST use the value of d and the ESession options specified in Bob's response to perform the following steps (where p and g are the constants associated with the selected MODP group, HASH is the selected hash algorithm, and n is the number of bits per cipher block for the agreed block cipher algorithm):
Return a &feature; error to Bob if she is not prepared to support any of the ESession options specified by Bob (if any of the options were not included in her initial ESession request)
Return a &feature; error to Bob unless: 1 < d < p - 1
Set &CBeCAx2n1; (where &CsubB; is the block counter for stanzas sent from Bob to Alice)
Select her values of x and e that correspond to the selected MODP group (from all the values of x and e she calculated previously)
Calculate K = HASH(&dsupx; mod p) (the shared secret)
Generate the session keys (&KCsubA;, &KMsubA;, &KSsubA;, &KCsubB;, &KMsubB; and &KSsubB;) in the same way as Bob did (see Generating Session Keys)
If Bob included 'identity' and 'mac' fields in his response then Alice MUST also perform the following steps:
Calculate the HMAC of the encrypted identity (&IDB;) and the value of Bob's block cipher counter using HASH and the integrity key &KMsubB;.
&MsubB; = HMAC(HASH, &KMsubB;, &CsubB;, &IDB;)
Return a &feature; error to Bob unless the value of &MsubB; she calculated matches the one she received in the 'mac' field
Obtain &pubKeyB; and &signB; by decrypting &IDB; with the agreed symmetric block cipher algorithm ("DECIPHER") in counter mode, using the encryption key &KCsubB; and block counter &CsubB;. Note: &CsubB; MUST be incremented by 1 for each encrypted block or partial block (i.e. &CsubB; = (&CsubB; + 1) mod 2n, where n is the number of bits per cipher block for the agreed block cipher algorithm).
{&pubKeyB;, &signB;} = DECIPHER(&KCsubB;, &CsubB;, &IDB;)
If the value of the 'pk_hash' field she sent to Bob in her ESession Request was true, then Alice SHOULD change the value of &pubKeyB; to be her copy of the public key whose HASH matches the value of &pubKeyB; that she received from Bob. Note: If she cannot find a copy of the public key then Alice MUST terminate the ESession. She MAY then request a new ESession with the 'pk_hash' field set to false.
Return a &feature; error to Bob unless she can confirm (or has previously confirmed) that &pubKeyB; really is Bob's public key, for examples, via secure out-of-band communication, or through a third-party authority (see Verifying Keys).
Set the value of &formB; to be the Normalized content of the form she received from Bob without any 'identity' or 'mac' fields.
Concatenate Alice's ESession ID, Bob's ESession ID, d, &pubKeyB; and &formB;, and calculate the HMAC of the resulting byte string using HASH and the key &KSsubB;.
&macB; = HMAC(HASH, &KSsubB;, {&NsubA;, &NsubB;, d, &pubKeyB;, &formB;})
Return a &feature; error to Bob unless she can use &pubKeyB; with the selected signature verification algorithm ("VERIFY") to confirm that &signB; is the signature of the HMAC result (see Signature Verification).
VERIFY(&signB;, &pubKeyB;, &macB;)
Alice MUST then prove her identity to Bob while protecting it from third parties. She MUST perform the steps equivalent to those Bob performed above (see Hiding Identity for a more detailed description). Alice's calculations are summarised below (pay attention to the order of &NsubB; and &NsubA; when calculating &macA;). Note: &formA; is the Normalized content of the ESession Request data form that she sent to Bob previously.
&macA; = HMAC(HASH, &KSsubA;, {&NsubB;, &NsubA;, e, &pubKeyA;, &formA;})
&signA; = SIGN(&signKeyA;, &macA;)
if (pk_hash) &pubKeyA; = HASH(&pubKeyA;)
&IDA; = CIPHER(&KCsubA;, &CsubA;, {&pubKeyA;, &signA;})
&MsubA; = HMAC(HASH, &KMsubA;, &CsubA;, &IDA;)
Alice MUST send the Base64 encoded values of &NsubB;, &IDA; and &MsubA; to Bob. If Alice has already confirmed Bob's identity (i.e. if Bob included 'identity' and 'mac' fields in his response), then she MAY also send encrypted content (see Exchanging Stanzas) in the same stanza as the proof of her identity.
If Alice also includes a 'terminate' field with its value set to "1" or "true" (see ESession Termination) within the form then the ESession is terminated immediately. Note: This special case, where a single stanza is encrypted and sent in isolation, is equivalent to object encryption (or object signing if no encryption is specified) and offers several significant advantages over non-session approaches - including perfect forward secrecy.
After receiving Alice's identity Bob MUST verify it by performing steps equivalent to those described in the section Verifying Bob's Identity above. Some of Bob's calculations are summarised below (pay attention to the order of &NsubB; and &NsubA; when calculating &macA;). Note: &formA; is the Normalized content of the ESession Request data form (the first form) that Alice sent him. Note: If Bob sends an error to Alice then he SHOULD ignore any encrypted content he received in the stanza.
&MsubA; = HMAC(HASH, &KMsubA;, &CsubA;, &IDA;)
{&pubKeyA;, &signA;} = DECIPHER(&KCsubA;, &CsubA;, &IDA;)
&macA; = HMAC(HASH, &KSsubA;, {&NsubB;, &NsubA;, e, &pubKeyA;, &formA;})
VERIFY(&signA;, &pubKeyA;, &macA;)
If Alice has already confirmed Bob's identity (i.e. if Bob included 'identity' and 'mac' fields in his response above), then the ESession negotiation is complete.
Otherwise, one more step is necessary. Bob MUST send Alice the Base64 encoded values of &NsubA;, &IDB; and &MsubB; that he calculated previously (see Hiding Identity). Note: He MAY also send encrypted content (see Exchanging Stanzas) in the same stanza.
After receiving Bob's identity Alice MUST verify it by performing steps described in the section Verifying Bob's Identity above. Note: If Alice sends an error to Bob then she SHOULD ignore any encrypted content she received in the stanza.
Once ESession negotiation is complete, Alice and Bob MUST exchange only encrypted forms of the one-to-one stanza types they agreed upon (e.g., &MESSAGE; and &IQ; stanzas).
Either Alice or Bob MAY send encrypted stanzas. Here we describe the process where Alice sends Bob an encrypted stanza. She MUST only encrypt the XML content that would normally be ignored by the intermediate servers. She MUST NOT encrypt stanza wrapper elements (only their content), &THREAD; or Advanced Message Processing elements.