1
$\begingroup$

The PKCS#7 padding is defined in rfc5652#section-6.3

Some content-encryption algorithms assume the input length is a multiple of k octets, where k is greater than one. For such algorithms, the input shall be padded at the trailing end with k-(lth mod k) octets all having value k-(lth mod k), where lth is the length of the input. In other words, the input is padded at the trailing end with one of the following strings:

               01 -- if lth mod k = k-1
            02 02 -- if lth mod k = k-2
                 .
                 .
                 .
       k k ... k k -- if lth mod k = 0

As we can see, the padding bytes can contain a series of01,02,...,or,16 for a 16-byte sized block cipher. While reading

I've seen that they gave an example as;

The second block contains the remaining 9 HMAC bytes and 7 bytes of padding 0x06, see Figure 1. Note that the encryptor can also choose longer padding and append 23, 39, ...or 247 padding bytes (while setting the value of the padding bytes accordingly).

This is not PKCS#7 padding. So, I've looked at TLS 1.2's RFC 5246 and see almost the same pattern;

If the padding length were the minimum necessary, 6, the padding would be 6 bytes, each containing the value 6. Thus, the last 8 octets of the GenericBlockCipher before block encryption would be xx 06 06 06 06 06 06 06, where xx is the last octet of the MAC.

To be compatible with PKCS#7 padding, the above should be ( couldn't see an errata)

If the padding length were the minimum necessary, 7, the padding would be 7 bytes, each containing the value 7. Thus, the last 8 octets of the GenericBlockCipher before block encryption would be xx 07 07 07 07 07 07 07, where xx is the last octet of the MAC.

and the article has a mistake there, too.

As far as I know, these two resources are incorrect. Is there something that I've missed about the different designs/usages of PKCS#7 padding rules?

$\endgroup$
2

1 Answer 1

3
$\begingroup$

The padding used for CBC cipher suites in SSLv3 through TLS 1.2 is not PKCS#5/PKCS#7 padding. It's the padding used in SSL/TLS, which I haven't seen anywhere else.

The padding in TLS 1.0, TLS 1.1 and TLS 1.2 can be from 1 to 256 bytes, so it can fill multiple blocks. In the predecessor protocol SSL 3.0, it must complete exactly one block. In all versions, the last byte must be the length of the padding, excluding that last byte. The preceding bytes can take any value in SSL 3.0, and must be the padding length in TLS 1.0 through 1.2. For a block cipher with $B$-byte blocks:

Specification Total length Blocks Content
PKCS#7 $n \in [1, B]$ bytes $1$ $(n, \ldots, n)$
SSL 3.0 $n \in [1, B]$ bytes $1$ $(?, \ldots, ?, (n-1))$
TLS 1.0–1.2 $n \in [1, 256]$ bytes $1$ to $\lceil 256/B \rceil$ $((n-1), \ldots, (n-1))$

As you can see, PKCS#7 fills the padding with the total padding length, whereas TLS 1.0–1.2 fills the padding with the total padding length minus one. The reason for this seemingly odd choice is that it's an adaptation of the SSL 3.0 padding, in which the last byte is a length byte which is not including in what the SSL specification calls the “padding”, and the “padding” proper can have arbitrary content.

The examples you cite from RFC 5246 and from Merget et al. are correct. If adding 7 bytes brings the plaintext to a multiple of the block size, then 06 06 06 06 06 06 06 is a possible TLS padding (as are 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16, etc.).

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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