*No, not cryptanalysis (although that **would* be such a nice name for it). This is an encryption mode, or rather a tweak to an encryption mode. And it's actually quite safe -- you even get back the ciphertext at the end.

The CBC mode of operation for block ciphers only works on a whole number of blocks. Thus padding the message is required. Some modes -- e.g. CTR -- can be used without such padding. Ciphertext "stealing" or CTS is a hack which allows CBC mode without padding.

Assumptions:

- Length of plaintext is at least 1 block.
- Length of plaintext is known (e.g. by passing it at the start of the message)

Note that the second assumption is anyway required for minimal

security (or an

adversary can tack

garbage onto the

end of the

decrypted message by tacking on anything at the end of the

encrypted message!).

When the message length isn't a whole number of blocks, what we'd *like* to do is truncate the last block. But CBC doesn't let us do that, because we *must* know all bits of a block to decrypt. The sneaky idea behind ciphertext stealing is to "steal" the appropriate number of bits from the penultimate ciphertext block!

To encrypt in CBC mode with ciphertext stealing, pretend to pad the last plaintext block with 0s, to fill it up to a whole block size:

... aaaaaaaa bbbbbbbb ccc00000

Now CBC encrypt the whole thing:

... AAAAAAAA BBBBBBBB CCCCCCCC

(note that we cannot assume anything about the "last" bits of

`CCCCCCCC`

; in particular, they're very probably

*not* zeroes!).

Then the encrypted blocks are:

BBBBBBBB = E_{K}(bbbbbbbb⊕AAAAAAAA)
CCCCCCCC = E_{K}(ccc00000⊕BBBBBBBB)

So if we know

*all* bits of

`CCCCCCCC`

, we can decrypt it to get the last bits of

`BBBBBBBB`

-- we

XORed them with 0's. Bearing this in mind, we

transmit the

bits

... AAAAAAAA CCCCCCCC BBB

The first thing to notice is that we transmitted only as many bits as were in the message -- we transmitted the same number of full blocks, and as many bits of the penultimate ciphertext block `BBBBBBBB`

as there were bits of the last plaintext block `ccc`

.

To decrypt, we decrypt all blocks up to `AAAAAAAA`

(inclusive) as usual for CBC. We now decrypt the last block-and-a-bit:

D_{K}(CCCCCCCC) = ccc00000⊕BBBBBBBB = xxxBBBBB
ccc????? = D_{K}(CCCCCCCC)⊕BBB?????

We get the last bits of the plaintext by

XORing

`xxx`

with the partial last ciphertext block

`BBB`

; this gives us the partial last plaintext block

`ccc`

. The remaining bits are

*exactly* the bits

missing from the ciphertext block

`BBBBBBBB`

. So we put them together to get the full block, and

compute as usual

D_{K}(BBBBBBBB) = AAAAAAAA⊕bbbbbbbb
bbbbbbbb = D_{K}(BBBBBBBB)⊕AAAAAAAA

Ciphertext stealing lets us pass a partial final block, securely (note that no proof was given here!) and without increasing the message size. You still need to authenticate the message to avoid tampering (i.e. use some MAC). And you still need to specify the message length. The implementation is more complex, for a relatively small saving of space -- even for AES, at most 15 bytes will be saved. And you *still* cannot transfer really short messages, which fit in less than one full block.

Is it worth it? Usually *not*. But if your application requires it -- say if you have many messages of length between 1 block and 2 blocks -- it *might* be worth remembering this hack.