		Client-to-Client Encryption in ICBM

		Phil Stracchino <alaric@caerllewys.net>



Encrypted ICB Protocol v1.1 (20140407)


Encrypted ICB (EICB) is a protocol for exchanging encrypted private
messages between ICB clients.  This is implemented using the Blowfish
cipher and randomly-generated per-user session keys, shared via
Diffie-Hellman key exchange.

Since the ICB protocol is more or less frozen and not readily extensible,
detection and recognition of encryption traffic currently replies upon a
message flag (here designated EICB_CRYPT_PREFIX) at the beginning of each
message.  This may be followed by either a message type code and possibly
additional data such as public keys, or encrypted body text.  The value of
EICB_CRYPT_PREFIX has been chosen to be unlikely to appear at the start
of a message in normal traffic.

Future versions of this protocol may eliminate the EICB_CRYPT_PREFIX by
using a specific new ICB packet type.  The ICB protocol specification
currently defines packet types 'a' through 'o', of which types 'n' and
'o' are archaic packets no longer in use.  It should hypothetically be
possible to add new packet types, such a type 'p' packet for encrypted
traffic and a type 'q' packet for encryption control messages.


At this time, the following EICB constants are defined:

	EICB_CRYPT_PREFIX	'%%%'
	EICB_DH_INIT		1
	EICB_DH_REPLY		2
	EICB_DH_REPLY2		3
	EICB_SESSION_KEY	4
	EICB_MISSING_KEY	5
	EICB_SESSION_END	6
	EICB_CANNOT_ENCRYPT	9

The encryption system also requires a list of 16 or more 48-bit primes.
The supplied primes file contains a table of 64 such Maurer primes,
generated using the Perl Crypt::Primes module.  Since ICBM uses the
Crypt::DH module to generate Diffie-Hellman keys and Crypt::DH is not
stable with larger primes (in particular, with primes of 64 bits or
larger), it is recommended that primes larger than 48 bits not be used.

It should probably be observed that due to the use of a static primes
table, EICB v1.0 offers only moderate security against a hypothetical
eavesdropper who knows the protocol and algorithm and has a copy of the
primes table.  For this reason, if higher security is desired, a new primes
table should be generated and distributed only to authorized users.  This
will, however, break interoperability with users in the larger ICB world.

(Then again, it might be argued that if you're seriously worried about
eavesdroppers, you probably shouldn't be talking over ICB.)


A session key is bidirectionally valid between a single pair of clients
so long as the user does not sign off or perform a nick change out of
sight of the other client.  Consider a single such pair of clients,
which we shall designate as Alan and Brenda.

To initiate an encryption session with Brenda, Alan sends Brenda a
private message composed of EICB_CRYPT_PREFIX followed by the code
EICB_DH_INIT:

%%%1

If no reply is received to this message, Alan's client does nothing
further.

When Brenda receives this message, if her client does not support ICBM
encryption, it will simply display the message.  Brenda may scratch
her head, or reply with a message such as "WTF?"  However, we will
assume Brenda's client does support encryption.

Upon receiving the EICB_DH_INIT message, Brenda's client does not
display it.  If encryption is for some reason disabled on Brenda's
client (for instance, if her client was unable to load the primes
table), her client replies with an EICB_CANNOT_ENCRYPT message:

%%%9

In response to this message, Alan's client informs him that it was
unable to set up a session key with Brenda, and abandons the attempt.
We assume, however, that Brenda has encryption enabled.  In this case,
Brendfa's client creates a Diffie-Hellman public key as follows:

Lowercase Alan's nick.
					(alan)

Sum the ASCII values of the characters.
					(97+108+97+110 = 412)

Use this value as the g	parameter.

Lowercase Brenda's nick.
					(brenda)

Sum the ASCII values of the characters.
					(98+114+101+110+100+97 = 620)

Calculate the remainder from this sum modulo the number of primes.
					(620 % 64 = 44)

Use this result as an index into the primes table.
					(267332212354279)

Use this value as the p	parameter.

Use this p and g, with a randomly generated private key, to generate
a Diffie-Hellman public key.  Save the public key and the private key.

Send a message to Alan containing the EICB_DH_REPLY code and this key:

%%%2 [Brenda's public key]


When Alan's client receives this message, it saves the attached key
temporarily as Brenda's public key.  It then creates a Diffie-Hellman
public key for Alan using the same algorithm as above, again generating
g from Brenda's nick and p from Alan's (thus ensuring Brenda and Alan
use the same values of p and g) but using a different random private
key.

Alan's client then sends Brenda his public key in an EICB_DH_REPLY2
message:

%%%3 [Alan's public key]

After sending this message, Alan's client uses Alan's and Brenda's
public keys to generate the Diffie-Hellman shared secret.

When Brenda's client receives Alan's DH_REPLY2 message, it saves the
attached key as Alan's public key, and generates its own copy of the
Diffie-Hellman shared secret.  It then uses any desired random source
to generate a session key.  In ICBM's case, this is done by randomly
choosing any single tuple from the log buffer (each tuple of which
contains three fields: the contents of an ICB protocol packet, the type
of packet, and a timestamp of when the packet was received), calculating
an SHA1 hash of the tuple, then Base64 armoring it.  Brenda's client
saves this key as Brenda's shared session key for Alan.

Brenda's client now encrypts this key with the Diffie-Hellman shared secret,
and sends the encrypted key in an EICB_SESSION_KEY message to Alan:

%%%4 [encrypted session key]

Brenda's client now informs Brenda that a session key has been established.

The encryption function performs the following three steps:

    Compress the plaintext using Gzip
    Encrypt the compressed plaintext using Blowfish in CBC mode,
       using the shared secret as a key
    Base64 encode the ciphertext

Alan's client, upon receipt of Brenda's EICB_SESSION_KEY message, saves
the encrypted key, decrypts it using Alan's copy of the Diffie-Hellman
shared secret as a key, and saves the result as Alan's shared session key
for Brenda.  It then informs Alan that a session key has been established.

Once a session key has been established, if Alan or Brenda changes their
nick within sight of each other, ICBM will update the ownership of the
session key accordingly.  However, if one makes a nick change that the
other does not see, the key will become stale.

Now, when Alan sends Brenda a personal message, his client compresses,
encrypts, and Base64 armors the message text as described above, except
using Brenda's session key rather than the Diffie-Hellman shared secret
(which it has by now discarded).  The client then breaks the armored
ciphertext into segments up to the available space in the payload of an
ICB protocol packet, sending each segment in a separate private message 
to Brenda's client preceded with EICB_CRYPT_PREFIX and a single space.
It follows the last segment with a message consisting solely of the
EICB_CRYPT_PREFIX as a terminator.

%%% [Armored message ciphertext segment]
%%% [Armored message ciphertext segment]
%%% [Armored message ciphertext segment]
%%%

Brenda's client, upon receiving these, saves the ciphertext segments and
reassembles the ciphertext, but does not otherwise act on them until it
receives the terminator.  At that point it checks to see whether it has
a valid session key from Alan.  Assuming it does, it reverses the process:

    Base64 decode the ciphertext
    Decrypt the ciphertext using the shared session key
    Uncompress the plaintext

and displays the message to Brenda.

If for some reason Brenda no longer has a valid session key for Alan (for
example: Alan has changed his nick to Alan2, and Brenda's client did not see
the change, or Brenda has quit her ICB session and begun a new one), then
Brenda's client advises Brenda that it received an encrypted message that
it was unable to decrypt for lack of a valid session key, and sends Alan
back an EICB_MISSING_KEY message:

%%%5

Upon receipt of this message, Alan's client informs him that the message
failed because of a stale key, and advises him to negotiate a new session
key with Brenda.

Alan can also opt at any time to revoke his local session key for Brenda,
and send Brenda an EICB_SESSION_END message:

%%%6

Upon receipt of this message, Brenda's client should delete Brenda's 
session key for Alan.
