Reputation: 41
I'm using C_EncryptUpdate/C_EncryptFinal
and I don't really understand what is supposed to do C_EncryptFinal
.
My assumption is that C_EncryptFinal
is used to add the padding and last block encryption when the size of the buffer to encrypt is not a multiple of the block size.
Am I correct? Shall C_EncryptFinal
always be called after a C_EncryptUpdate
loop ?
Upvotes: 2
Views: 988
Reputation: 8116
If you want to be sure you have all the ciphertext you should call C_EncryptFinal
.
After calling C_EncryptInit, the application can either call C_Encrypt
to encrypt data in a single part; or call C_EncryptUpdate zero or
more times, followed by C_EncryptFinal, to encrypt data in multiple
parts. The encryption operation is active until the application uses
a call to C_Encrypt or C_EncryptFinal to actually obtain the final
piece of ciphertext. To process additional data (in single or
multiple parts), the application must call C_EncryptInit again.
You can replace calls to C_EncryptUpdate
and C_EncryptFinal
(aka multiple-part operation) with single C_Encrypt
if you have all your plaintext ready in a single buffer (aka single-part operation).
(Beware that some mechanisms might support only single-part operation, e.g. CKM_RSA_X_509
)
EDIT:
The C_EncryptFinal
does not necessarily need to return any data (i.e. the returned encrypted data part length in pulEncryptedPartLen can be zero).
As you say, the CKM_AES_CBC
encryption which was fed with block aligned data (via C_EncryptUpdate
) will probably return no encrypted data part after C_EncryptFinal
for most of the implementations (as they would return the corresponding ciphertext immediately in the C_EncryptUpdate
).
But there might exist an implementation, which internally buffers this block aligned data without encrypting it (thus returning zero length output data part in C_EncryptUpdate
) and which then encrypts all the buffered data at once during the C_EncryptFinal
-- an example might be an implementation backed by a smart card (or a remote host), where it might be a good idea to send data in larger chunks (even if the cryptoki itself receives data in a block sized chunks).
PKCS#11 API allows that and you have to handle it correctly (i.e. check returned lengths, shift your destination pointers/update the space available accordingly).
Think of it as of a universal API which needs to support any imaginable mechanism.
Upvotes: 2