Bug #11825

PKCS#11 CKM_AES_CBC_PAD decryption can fail

Added by Jason King about 1 year ago. Updated about 1 year ago.

lib - userland libraries
Start date:
Due date:
% Done:


Estimated time:
Gerrit CR:


Upstream of Joyent OS-7839 and OS-7955.

From OS-7839:

When decrypting data using AES_CKM_CBC_PAD (AES cbc with PKCS#7 padding) using the pkcs11_softtoken PKCS#11 provider, if the input ciphertext is exactly a multiple of AES_BLOCK_LEN, C_DecryptFinal will fail with CKR_BUFFER_TOO_SMALL unless the caller supplies a buffer at least AES_BLOCK_LEN (16 bytes) long.
However, C_DecryptFinal is being overly restrictive – the final block of plaintext could be 0-AES_BLOCK_LEN - 1 bytes long, and C_DecryptFinal should only error if the buffer is too small to hold the decrypted final result.

From OS-7955:
While OS-7839 fixed most of the CKM_AES_CBC_PAD issues, there was one scenario that was not caught – when doing a multi-part decryption with more than one full block of data (i.e. C_DecryptUpdate() is called with an input size that's exactly a multiple of AES_BLOCK_LEN (16 bytes) greater than 1 – 32, 64, 80, etc), it decrypts all of the blocks given in the call. It should instead save the final block of cipher text and defer decryption to the next C_DecryptUpdate() call or the subsequent C_DecryptFinal() call. C_DecryptFinal() needs a full block of cipher text that's been deferred in order to properly remove the padding added during encryption.
When a non-exact multiple of AES_BLOCK_LEN bytes is given to C_DecryptFinal() (33, 55, 12345, etc) things are buffered correctly, and the C_DecryptFinal() will have a full block of data to decrypt as expected. Unfortunately due to OS-7954, this was not caught because it's multi-part tests only ever call C_DecryptUpdate with a single byte of ciphertext at a time, thus not triggering the error.

Related issues

Related to illumos gate - Feature #12864: Have pkcs11_softtoken's DES[3]_CBC_PAD mechanism use the cbc_pad modeNewJason King


Also available in: Atom PDF