# Why not put MAC in fixed position and cover padding for MAC-then-encrypt?

The biggest problem with using MtE with a mode where it's known to be secure (CBC) is with the padding, where you can't retrieve the authentication until you know where it is by looking at the padding bytes.

Instead, why not just place the MAC at the very end of the last block, and include the padding bytes in the calculation of the MAC? Verify the MAC before even looking at the padding or anything else in the message (other than to calculate the MAC, of course).

The padding algorithm would simply have an argument telling it how much space to reserve after the padding for a MAC, either 0 if using EtM, or the space for the tag if using MtE.

Then process the MAC over the message plus added padding, and store it in the reserved area. Are there any padding schemes which do this?

The reason it isn't used is probably that padding oracle attacks weren't known when CBC schemes were initially defined and now that they are known, there doesn't seem to be a convincing use case for CBC. Other modes have advantages over CBC anyway (no requirement for unpredictable IV, easier parallelizability). If you do need CBC for some reason (like backwards compatibility), you can just use encrypt-then-MAC which is simple and well understood.

I.e. rather than asking why it is not used, you should be asking what the advantage is over other safe schemes.

The biggest reason is probably that padding is only required for CBC mode encryption.

What you are doing here is to mix the cipher mode used for confidentiality with the MAC required for authentication. By doing this you are decoupling the padding from the decryption:

1. CBC-decrypt;
2. verify authentication tag;

This may not be a problem to create as a separate module, but it would require a separate padding/unpadding mechanism. That padding mechanism also needs to take the authentication tag size (MAC size) as parameter. This is not something that can easily be created using existing API's. Many of those may only contain CBC with PKCS#7 compatible padding which means that the API has to be refactored.

If this is implemented as a separate module then you have created an authenticated cipher mode. There are already quite a few of them out there. Most of them however use CTR mode with an authentication over the ciphertext. CTR doesn't require padding at all, so the problem does not occur in the first place.

One good reason to perform verification before decryption is handling of the plaintext. Decrypted text may have to be handled directly, otherwise it needs to be buffered. In your case you have the added difficulty that you need to store the padding bytes as well, while these are not required for further operation.

So even though your mode may well be secure, it's not very practical compared to many AEAD (authenticated) schemes. There are much easier modes to implement, with CTR / stream ciphers followed by a MAC being the most popular within AEAD ciphers.

• So more because of tradition, then? I think of padding as just another primitive. A padding mode that included a MAC (or a MAC that included padding) would have solved all those issues with SSL/TLS, e.g. just change the order of the block-ciphered struct in the SSL/TLS RFC's so that the MAC is at the end and defined to cover the padding bytes/len as well. Something that only does PKCS#7 padding already won't work with TLS. – Steve Peltz Jun 2 '15 at 16:19
• What you say is kind of true. A (H)MAC is a primitive, and as such a primitive, already pads ... for calculating the MAC value. Why would it pad the cipher? That's not it's raison d'etre. Same goes for the padding mechanism. A padding mechanism pads - usually only depending on how many bytes are left in the buffer - why would it need to be configured with a MAC? Yes, TLS currently has a horrible padding specification; that's an awful good reason to deprecate it and use AEAD ciphers instead in TLS 1.3. – Maarten Bodewes Jun 2 '15 at 17:18
• I guess I just don't see much difference between giving a padding algorithm a length, or giving it two lengths, or adding in the length of the padding when calling the MAC routine. The whole thing (MtE, padding, chaining mode) is itself a mode of operation, maybe MtE is irrevocably dumb, but if you're going to do it, the padding should be included, and the MAC should be in a fixed location independent of the padding. I'm just wondering if it's ever been used, and if using MtE, wouldn't the improved security vastly outweigh any perceived inconvenience of slightly changing the primitives? – Steve Peltz Jun 2 '15 at 17:43
• IMHO you should not build a protocol out of non-standardized algorithms. The current MtE is not the best and very vulnerable, but it largely consists of standardized algorithms. You are creating a protocol by significantly altering and mixing algorithms. Even if it would be secure, it would be hard to implement and thus error prone. Currently we are in a position that we have MtE, and we are trying to get rid of it by applying well defined AEAD ciphers that don't need any padding and verify before decryption. – Maarten Bodewes Jun 2 '15 at 18:14

How can you both "include the padding bytes in the calculation of the MAC? Verify the MAC before even looking at the padding"

It sounds like your construction is trying to be

Encryption:


Decryption and Verification:

1. Decrypt entire message
2. Extract MAC = final 128/192/256 bits of message
3. Delete all the 0 bits at the end of the message
4. What we now have is a properly formatted message || padding
5. If bad MAC, throw bottom
• It seems to pretty clearly be m0 || m1 || m2 || padding || MAC of m0+m1+m2+padding, $\hspace{.17 in}$ where padding is chosen to make the length of that concatenation an integer multiple of the block size. $\hspace{.1 in}$ – user991 Jun 1 '15 at 2:53