# Which ECB ciphertext stealing scheme is this?

I am stuck with identifying ciphertext stealing method with the following properties:

• mode of operation is ECB;
• recommended padding scheme for this application is PKCS#7, but apparently it is not used;
• all blocks except the last one are encrypted / decrypted as usual;
• the last block is not padded, but still encrypted / decrypted somehow.

For example, with Blowfish cipher and key 72E9DD9D29:

encrypted: A4 3F 83 8D CE D2 54 2E | 4F
decrypted: 82 DD 00 00 00 01 03 FF | 1E


I cannot figure out how that last (incomplete) block is encrypted / decrypted, so that if it is ignored and not processed, the penultimate block would be the same, — that does not look similar to ECB ciphertext stealing method described in Wikipedia, as block contents is not exchanged. This may seem obvious to an expert, but I already ran out of ideas.

• Perhaps something CFB or OFB like. – CodesInChaos Sep 30 '15 at 19:15
• @CodesInChaos Strangely enough, I could not find any description of “CFB ciphertext stealing” or “OFB ciphertext stealing” — not even any references to such methods. Could you please provide a link to some source? – Anton Samsonov Oct 1 '15 at 16:38
• I meant that it might use one of those stream cipher modes for the last block, instead of ciphertext stealing. OCB mode uses a similar technique to handle its last block. – CodesInChaos Oct 1 '15 at 16:43

## 1 Answer

This may sound crazy and absurd, but it seems that this scheme is simply broken:

1. on encryption, the last block is somehow padded (the exact method is not really relevant, but perhaps the trailing bytes of penultimate plaintext block are copied) and encrypted, then finally ciphertext is trimmed to match plaintext size;
2. on decryption, the same buffer is reused for each block, so the last ciphertext block is naturally padded with the trailing bytes of penultimate ciphertext block, then decrypted, and finally plaintext is trimmed to match ciphertext size.

Obviously, such an “encryption” irreversibly corrupts the last block, resulting in garbage being output on decryption. However, application software appears to ignore bad data silently, discarding the last record, absence of which is not evident to user, unless he specifically looks for it.

Well, I am not totally sure about this, as I only analyzed (OllyDbg to the rescue!) the decryption stage and header parsing, while object records are parsed on later stages of a quite-high-level processing, but it looks improbable to me that those high-level routines could perform a custom non-trivial restoration of the last block, — the more so that the last record appears to be missing, unless plaintext is guessed by hand (guessing is possible due to the highly predictable nature of plaintext, especially in the last block). However, if I am terribly mistaken, and such a scheme with properties specified in question is theoretically feasible, it would be interesting to know about it.