C = DESK3 {DES-1K2{DESK1(P)}}
DES (or any block cipher) forms a basic building block, which en/decrypts a fixed sized block of data. However to use these in practise, we usually need to handle arbitrary amounts of data, which may be available in advance (in which case a block mode is appropriate), and may only be available a bit/byte at a time (in which case a tream mode is used).
Ci = DESK1 (Pi)
ECB is the simplest of the modes, used when only a single block of info needs to be sent (eg. a session key encrypted using a master key)
ECB is not appropriate for any quantity of data, since repetitions can be seen, esp. with graphics, and because the blocks can be shuffled/inserted without affecting the encryption.
Ci = DESK1(Pi XOR Ci-1) C-1 = IV
To overcome the problems of repetitions and order independence in ECB, want some way of making the ciphertext dependent on all blocks before it. This is what CBC gives us, by combining the previous ciphertext block with the current message block before encrypting. To start the process, use an Initial Value (IV), which is usually wellknown (often all 0's), or otherwise is sent, ECB encrypted, just before starting CBC use. CBC mode is applicable whenever large amounts of data need to be sent securely, provided that its available in advance (eg email, FTP, web etc)
One issue is how to handle the last block, which may well not be complete. In general have to pad this block (typically with 0's), and then must recognise padding at other end - may be obvious (eg in text the 0 value should usually not occur), or otherwise must explicitly have the last byte as a count of how much padding was used (including the count). Note that if this is done, if the last block IS an even multiple of 8 bytes, will have to add an extra block, all padding so as to have a count in the last byte.
Ci = Pi XOR DESK1 (Ci-1) C-1 = IV
If the data is only available a bit/byte at a time (eg. terminal session, sensor value etc), then must use some other approach to encrypting it, so as not to delay the info. Idea here is to use the block cipher essentially as a pseudo-random number generator (see stream cipher lecture later) and to combine these "random" bits with the message. Note as mentioned before, XOR is an easily inverted operator (just XOR with same thing again to undo). Again start with an IV to get things going, then use the ciphertext as the next input. As originally defined, idea was to "consume" as much of the "random" output as needed for each message unit (bit/byte) before "bumping" bits out of the buffer and re-encrypting. This is wasteful though, and slows the encrpytion down as more encrpytions are needed. An alternate way to think of it is to generate a block of "random" bits, consume them as message bits/bytes arrive, and when they're used up, only then feed a full block of ciphertext back. This is CFB-64 mode, the most efficient. This is the usual choice for quantities of stream oriented data, and for authentication use.
CFB is the usual stream mode. As long as can keep up with the input, doing encryptions every 8 bytes. A possible problem is that if its used over a "noisy" link, then any corrupted bit will distroy values in the current and next blocks (since the current block feeds as input to create the random bits for the next). So either must use over a reliable network transport layer (pretty usual) or use OFB.
Ci = Pi XOR Oi Oi = DESK1(Oi-1) O-1 = IV
The alternative to CFB is OFB. Here the generation of the "random" bits is independent of the message being encrypted. The advantage is that firslty, they can be computed in advance, good fro bursty traffic, and secondly, any bit error only affects a single bit. Thus this is good for noisy links (eg satellite TV transmissions etc)
Because the "random" bits are independent of the message, they must never ever be used more than once (otherwise the 2 ciphertexts canbe combined, cancelling these bits, and leaving a "book" cipher to solve). Also, as noted, should only ever use afull block feedback ie OFB-64 mode.