Björn Edström February 2009 IRCSRP version 2.0 Copyright Notice This document is placed in the public domain. Abstract This document describes a method for securing IRC group chat. It is an updated version of the first version of IRCSRP [1], fixing some issues in the original specification [2]. IRCSRP is based on the SRP-6 protocol [3] for password-authenticated key agreement. While SRP was originally designed for establishing a secure, authenticated channel between a user and a host, it can be adapted for group communcations, as described in this document. Table of Contents 1. Introduction to IRC 1.1 PRIVMSG and NOTICE commands 1.2 plaintext and ircmessage 2. High level overview 3. Primitives and constants 4. Setup 5. Session key exchange 6. Message encryption 6.1 Chat messages 6.2 Key renewal 7. Acknowledgements 8. References 1. Introduction to IRC Internet Relay Chat (IRC) is a plaintext protocol for multi user communications. Here is a short description of IRC, enough for our purposes. For more details about IRC, refer to RFC 2812. IRC server A machine running IRC server software, or the server software. IRC network One or more IRC servers connected to each other. User Someone connected to an IRC network. IRC client The software employed by users to talk IRC, or the user. Channel A "room" where serveral users talk to each other. Channels are usually identified by a name prefixed by a character. Example: #math Command A specific text string sent between client/servers or servers/ servers according to the IRC protocol. PRIVMSG command A command used for sending chat messages to users or channels. Described below. NOTICE command Similar to PRIVMSG for most purposes. Nickname A character string used to identify a user on an IRC network. Join The concept of "entering" a channel, with the JOIN command. 1.1 PRIVMSG and NOTICE commands We are specifically interested in the PRIVMSG command. Say user Alice with nickname alice joins #math. A PRIVMSG command may look like this (Alice sends to server:) PRIVMSG #math :Hello math geeks!\r\n The servers takes this messages and sends to everyone else in #math: :alice!user@host.com PRIVMSG #math :Hello math geeks!\r\n Alice can also send a message directly to Bob, in a one-to-one conversation. Alice sends to server: PRIVMSG bob :Hi bob!\r\n Server sends to Bob: :alice!user@host.com PRIVMSG bob :Hi bob!\r\n 1.2 plaintext and ircmessage As IRC is a plaintext protocol, enemies can eavesdrop on the conversation without trouble. IRCSRP solves this problem by encrypting the chat message part of the command. Client software implementing the IRCSRP protocol rewrites PRIVMSG commands, encrypting the sensitive part of the command. From here on, we are going to refer to the chat message part of the command as "plaintext" and the rewritten plaintext as "ircmessage". For example: PRIVMSG #math :Hello math geeks!\r\n plaintext = "Hello math geeks!" ircmessage = 2. High level overview Alice, Bob, Carol and Dave want to communicate securely over IRC in their channel #friends. Dave is a trusted, technical user and will act as a "gatekeeper". All messages sent to #friends are encrypted with a random session key generated by Dave. When a user joins #friends, she sets up a secure, authenticated channel with Dave and if trusted gets the session key. Dave will periodically renew the session key, so an attacker can't get access to old conversations if the encryption key is compromised. 3. Primitives and constants N = The prime number from the 2048-bit MODP Group as described in RFC 3526. g = 2. H = the SHA-256 hash algorithm. Depending on context, the hash is either a 32-byte string or said string interpreted as a 256 bit big-endian integer. HM = HMAC-SHA-256 truncated to 16 bytes, i.e. only the first 16 bytes of the hash are used. AES-CBC = AES-256 in CBC mode. Used with 16 byte IV. Base64 = The standard MIME base64 encoding. Base64("abcde") == "YWJjZGU=". IntToBytes = Variable length big endian representation of an integer. IntToBytes(0xABBCC) == "\x0a\xbb\xcc". len = The length of a string. len("\x00\x01") == 2. 4. Setup Some preparation is needed to set up the secure, authenticated channel between Dave and the other users. All users share knowledge of a password with Dave. This is done as follows, for sample user Alice: 1) Alice selects a username I and a password P. The username should be constant and not derived from Alice IRC nickname or host. 2) Alice generates a random salt s then computes the verifier v: s = random 256 bit integer x = H(s || I || P) v = g^x (mod N) 3) Alice gives Dave s and v (in an existing secure channel), which he stores together with Alice username I. From now on, Alice only has to remember I and P. She can and should discard s, x and v. 5. Session key exchange The purpose of the session key exchange is to give Alice key material, both for the authentication and encryption. Dave has a 256 bit session key and also a 256 bit mac key, "sessionkey" and "mackey". For the session key exchange, all ircmessage are sent in a NOTICE command. 1) Alice sends Dave her username I. This initiates the exchange. ircmessage = "+srpa0 " || I 2) Dave looks up Alice information (s, v), computes and sends: b = random integer with 1 < b < N. B = 3v + g^b (mod N) ircmessage = "+srpa1 " || Base64(s || B) 3) Alice asserts B != 0 (mod N), then computes and sends: a = random integer with 1 < a < N. A = g^a (mod N) x = H(s || I || P) u = H(A || B) S = (B - 3g^x)^(a + ux) (mod N) K1 = H(S || "enc") K2 = H(S || "auth") M1 = H(A || B || S) ircmessage = "+srpa2 " || Base64(M1 || IntAsBytes(A)) 4) Dave verifies M1, then if Alice is trusted, computes and sends: u = H(A || B) S = (Av^u)^b (mod N) K1 = H(S || "enc") K2 = H(S || "auth") M2 = H(A || M1 || S) csession = IV || AES-CBC(K1, IV, sessionkey || mackey || M2) cmac = HM(K2, csession) ircmessage = "+srpa3 " || Base64(cmac || csession) 5) Alice verifies M2, and decrypts the session key using K1. If the verification holds, then Dave and the session key are trusted. 6. Message encryption 6.1 Chat messages The messages sent to the IRC network: info = len(username) || username || timestamp ctext = IV || AES-CBC(sessionkey, IV, "M" || info || plaintext) cmac = HM(mackey, ctext) ircmessage = "*" || Base64(cmac || ctext) Implementations may also use these messages wherever a textual message is possible, such as channel topics. 6.2 Key renewal Once in a while Dave changes the session key. This message has the same form as the chat message above, with the following modification: plaintext = "\xffKEY" || new_sessionkey || new_mackey 7. Acknowledgements Everyone who commented on the first draft at sci.crypt [2]: Simon Johnson, Kristian Gjøsteen, Jeffrey Walton, Paul Rubin, Mark Woodling, Ilmari Karonen, Greg Rose. 8. References [1] http://blog.bjrn.se/2009/01/ proposal-for-better-irc-encryption.html [2] sci.crypt "Requesting comments: SRP based IRC encryption" 2009-01-25 [3] http://srp.stanford.edu/doc.html