As I'm using HMAC to ensure integrity and authenticity of the ciphertext, is there any additional security benefit to verifying PKCS#7 padding when decrypting using AES CBC?

A previous question asked Why verify Padding at all? Part of the accepted answer was:

In general, use a cryptographic MAC to protect your ciphertext, and verify it first. Emit those errors. Then padding errors should not occur at all.

But I note the qualifier "in general" and I also know a number of cryptography libraries do validate the padding.

  • $\begingroup$ It depends. How do you use the HMAC? On the plaintext or on the ciphertext? $\endgroup$ – SEJPM Mar 6 '16 at 14:21
  • $\begingroup$ On the ciphertext. Sorry I didn't make that clear. $\endgroup$ – ChrisD Mar 6 '16 at 14:24
  • 2
    $\begingroup$ I'd verify the whole padding, to ensure my communication partner doesn't have a bug in their padding creation code. If you let a protocol violation pass, allowing that violation effectively becomes part of the protocol. $\endgroup$ – CodesInChaos Mar 6 '16 at 15:18
  • $\begingroup$ @CodesInChaos Changed my answer accordingly, I would agree with that particular sentiment. I've added another reason: the possibility of creating a covert channel within the padding bytes as well. $\endgroup$ – Maarten Bodewes Mar 6 '16 at 15:23
  • 1
    $\begingroup$ Related question: Why verify padding at all? $\endgroup$ – CodesInChaos Mar 22 '16 at 10:23

In general, use a cryptographic MAC to protect your ciphertext, and verify it first. Emit those errors. Then padding errors should not occur at all.

The "in general" seems to have been used to show that commonly is performed or should be performed. I don't think it had anything to do with the security of the scheme itself.

PKCS#7 compatible padding can range from 1 to 16 bytes for block ciphers such as AES. If your plaintext always happens to be $n * 16 + 15$ bytes in size then your padding would consist of a single byte. A single byte is never enough to guarantee integrity of the plaintext.

Padding isn't a checksum. It doesn't say anything about the value of the plaintext. It tells you only something about the size of the plaintext.

Even if you would be able to use padding as an integrity check then you shouldn't use it for transport protocol security. Padding checks allow padding oracle attacks to be performed. For instance OpenSSL uses sign-then-encrypt and requires special care to avoid padding oracle attacks.

Note that modern protocols often allow modes such as CTR or authenticated ciphers. Almost all authenticated ciphers based on block ciphers are based on CTR (i.e. CCM, GCM and EAX mode are all based on CTR mode to provide confidentiality). CTR doesn't use padding at all. So you can often avoid the use of padding pretty entirely.

This also shows that padding mode is not a requirement to validate the correctness of the plaintext. If it was, all current authenticated ciphers would fail.

Padding should not be used for verifying correctness period. It should just be used for determining the length of the plaintext.

[CHANGED] After verifying the integrity you should check all the padding bytes, if just to verify the correctness of the implementation. Another reason to check the other bytes is to avoid worrying about subliminal (covert) channels. A slight disadvantage would be that you couldn't use the same unpadding code to handle PKCS#7 and the withdrawn ISO 10126 padding (and you should make sure you don't break anything if you change existing code with that in mind).

It does make sense to check if the value isn't out of range, i.e. between 1 and the block size. You don't want to handle issues with index-out-of-range or partial information in the code surrounding the cryptographic routine.

An even better solution would be to use a mode that doesn't require padding at all. A good candidate would be the aforementioned CTR mode of operation which turns AES into a stream cipher or one of the authenticated (AEAD) ciphers.

  • $\begingroup$ So in the case where you have absolute control over the encryption process in addition to the decryption you could skip verifying the padding but in every other case it is better to check for the correctness of the protocol, being careful to account for timing attacks? $\endgroup$ – ChrisD Mar 6 '16 at 17:33
  • 1
    $\begingroup$ @ChrisD Yes, if you have full control over the process you could skip verifying the bytes, but in that case you might as well validate all the padding bytes. The padding oracle attacks - which include timing attacks - you should avoid by first checking the (H)MAC. Note that checking the authentication value is prone to timing attacks as well. $\endgroup$ – Maarten Bodewes Mar 6 '16 at 18:23
  • $\begingroup$ Please offer reasons and/or sources when adding in unsolicited advice such as preferring to "forfeit CBC mode altogether." Even though it may seem like common sense, it may not be to those reading this answer less familiar with it. $\endgroup$ – d1str0 Mar 7 '16 at 9:24
  • $\begingroup$ Rewrote last sentence. $\endgroup$ – Maarten Bodewes Mar 7 '16 at 9:59
  • $\begingroup$ Even if the mode doesn't require padding, you might want to add padding to reduce the information leak through ciphertext length. Once you do, you have the same choice of fully validating the padding, or not. $\endgroup$ – CodesInChaos Mar 7 '16 at 11:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.