PKCS#11 CKM_AES_CBC_PAD decryption can fail
Upstream of Joyent OS-7839 and OS-7955.
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.
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.
Updated by Electric Monk over 2 years ago
- Status changed from New to Closed
- % Done changed from 0 to 100
commit 8d91e49dd95381d46f9364f5de9e9027a11e1118 Author: Jason King <email@example.com> Date: 2019-11-12T16:26:32.000Z 11825 PKCS#11 CKM_AES_CBC_PAD decryption can fail Reviewed by: Dan McDonald <firstname.lastname@example.org> Approved by: Gordon Ross <email@example.com>