On Mar 14, 2014, at 5:33 AM, Leon Brits <[email protected]> wrote:

> Hi,
>  
> I have a problem with Thunderbird which works via the cryptoki to our device 
> which makes use of OpenSSL.
>  
> Thunderbird passes ciphertext which falls exactly on the blocksize boundary. 
> I translate the cryptoki DecryptUpdate() call to the OpenSSL DecryptUpdate(). 
> OpenSSL retains the last block of ciphertext and return the first 
> (N-1)*blocksize of plaintext. Next I expect a cryptoki DecryptFinal() call so 
> as to decrypt and return the last block of plaintext. Thunderbird instead 
> expected _all_ the plaintext to be returned from the DecryptUpdate() call (it 
> seems). In a discussion with them, they mention that they determined that the 
> ciphertext is not padded and hence expected this behaviour. There code now 
> fails because the length of the plaintext returned by my OpenSSL 
> DecryptUpdated() does not match the length of the ciphertext send to it.
>  
> Am my understanding of the OpenSSL DecryptUpdate() the wrong: Is it possible 
> to decrypt all the ciphertext and return all the plaintext or must one always 
> call the DecryptFinal() after any and all DecryptUpdate() function calls?

You should always call any final function for encrypting, decrypting, etc.  
That’s true not only of OpenSSL, but of all the toolkits I’ve worked with, 
including NSS.  I once saw some code that skipped the final on both encrypt and 
decrypt because they always passed in blocksize, and nearly a year later, 
discovered that it only “worked” because the last blocksize bytes of the 
original data weren’t needed most of the time for processing.  When they hit a 
case where the last blocksize bytes were needed, the whole thing failed — the 
decrypt side could never work, because it was missing part of the encrypted 
data, and the companies lost several million transactions (worth a few million 
dollars) because the original plain text no longer existed.

If the thunderbird folks think that they’ll never get data from final() just 
because the plain text size is a multiple of blocksize, they’ll eventually bite 
their customers hard for the cases where that’s not true.  Like with your 
device. :)  Most of the cryptoki implementations I’ve used also free memory in 
their final functions — memory that otherwise is never freed.  For some smart 
cards this isn’t so bad, because the library (and all its memory) will be 
released when you pull out the smart card, but in most cases, the library (and 
its allocated memory) remains loaded until the application is closed, and on 
Windows, it may remain loaded until the user reboots.  Additionally, the device 
itself may be allocating memory that is usually freed in the final function, 
and if the device isn’t removable, that’ll stay allocated a very long time, 
too, and may even cause the device to stop working after a while.

In short, while you might be able to get all of the plain text without calling 
final, you might not, and you definitely leave yourself open to memory leak 
problems if you don’t call the final function.

>  
> Thanks for your time
> LJB
______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
Development Mailing List                       [email protected]
Automated List Manager                           [email protected]

Reply via email to