I suspect a question which is going to be asked at some point is "Why are you @*#$& idiots rolling your own crypto?", which is actually a pretty fair question. Now we can just point them at this. :) After things are finalized we'll have to document the protocol, at least the crypto primitives in use and the kex method, so we can point people at that so they can decide if we're too broken or not. To meet certain design goals (in particular, supporting voice and video well), we have to use UDP. TCP's ordering constraints often cause too much latency to be usable, especially when other services are also using up lots of bandwidth (games, etc). Thus, SSL/TLS is out. As of today (mid 2004) the only even remotely acceptable UDP-based encryption system is DTLS. However, there are major problems with using DTLS in Cutlass, including: *) It has not been standardized yet, and probably won't make RFC for at least a year, if not much longer. Rescorla is the main point of contact, which may well speed it up, but the IETF works in mysterious ways. *) DTLS follows the TLS authentication model, which is not particularly appropriate for Cutlass. While we could 'force' it to work by requiring client authentication and treating X.509 certs as just a bag of bits that happens to have a public key in it, this still has some problems with it. That said, it may turn out that the best thing to do is to use DTLS, but for now we're rolling our own. If we do decide to go with DTLS at some point, it may be worthwhile to re-examine Cutlass's use of the crypto layer, and see if we can take advantage of some of DTLS's features/misfeatures (X.509, etc). Here is some comments from crypto.h. I've put them into here, because a header file is not a good place to store design conversations Also, it reduced the size of crypto.h from 273 lines to 143. :) /* It's entirely possible the following cipher/MAC type macros don't need to be public at all. We might want to have something like construct_kex_packet() which returns a pre-formatted packet for the network code to send off to whowever we're wanting to negotiate a connection with, in which case it can choose what it wants to support, and the two sides can negotiate for a mutually supported algorithm. One thing that would be good is to make sure that stronger algorithms have higher numbers. Thus, two sides can negotiate shared algorithms by just choosing the highest set bit in the AND of their supported algorithms. I see little reason to choose to support weaker algorithms than what we've got right now, we don't have to deal with export regs anymore (thank Goddess). */ /* I think initially there is little point in supporting anything but 128-bit AES; hell according to the NSA it is sufficient for protecting secret classified data (have to use 192 or 256 bits keys for top secret). In any case, it's unlikely we will need any ciphers but these three anytime at all soon. Cutlass will probably be obsolete before AES-256 is broken. I think just supporting 128 and 256 bit AES is sufficient. 192 bit AES isn't buying us much, though it is a bit faster than 256 bit AES. Given the choice between breaking even 128-bit AES, and finding and exploiting a flaw in our implementation (or users), anyone with an ounce of sense will just ignore the ciphers and attack the code or people. HMAC(SHA-1) should be OK to use for at least a few more years. */ /* TODD: Where are public and private keys stored? What format are public keys transferred in? */ /* * Good questions! I'd assume binary for public key transferring, no * need to be human-readable here. Dunno on storage loc. -Todd */ /* OK, so private keys out of a file (I guess?) and public keys from raw binary. */ /* * The files themselves can be raw binary or human readable, but the * packets should be raw binary. Whatever's easiest for you to work with, * but minimize bandwidth consumption in kex. */ /* TODD: what arguments does this take beyond the keyset (which is the set of cryptovariables and other state information for the connection in question). I presume some packet structs, but I don't see anything obvious in cutlass.h .... */ /* * My thoughts below in the modified declarations. -Todd */ /* Are these actually structs? If not, how do I know the length, and the offsets for nonce/MAC/etc... */ /* * You'll overlay the packets with structs. It'll go a little something * like this: * * void * encrypt_packet(cutlass_keyset keys, uint8_t *in_pkt, uint8_t *out_pkt) * { * struct cutlass_packet_hdr *encrypted_packet; * struct cutlass_packet_hdr *cleartext_packet; * * encrypted_packet = (struct cutlass_packet_hdr *)out_pkt; * cleartext_packet = (struct cutlass_packet_hdr *)in_pkt; * gen_rand_bytes(CUT_NONCE_LEN, &(encrypted_packet->nonce)); * * and so on... * * That OK? Packet header definitions are in cutlass.h. Feel free to * modify them if you feel the need, just let me know. * * Use the cutlass_packet_hdr's length field to determine how long the * cleartext is. Ignore the cleartext packet's nonce field. * * Also, the way I declare it now, I give you the memory already allocated. * I don't know if you want to allocate the memory yourself. (Probably * easier for me to do it, I can just do it on the stack of whatever * calls encrypt_packet). */ /* Perform a keyexchange with the remote host. Presumably we want some more arguments here, I don't know what they should be, though. Currently this function just returns a NULL struct. TODD: What kind of arguments will this need? I imagine it will be used in handshake.c -- if you could give me a sense *how* it will be used, and what it is expected to do, that would help. This will end up being the most complicated function in the crypto layer, I suspect. */ /* * We're not going to be able to do a single do_kex function, since * we're not able to segregate connections that way. We'll have to * break it down into each step, updating the cutlass_connection * conn_state each time. * * -Todd */ /* Crap crap crap. Does this mean we'll need wrappers for doing each individual operation (RSA sign, RSA encrypt, DH op, KDF, etc)... */ /* * Hope not! But we'll need a wrapper to generate and interpret each kex * packet type, for sure. * * We should either save these discussions off to the cutlass.code file, * or cc them to the list, as I'm sure we'll lose this knowledge otherwise. * ^_^;; */