Re: [pkcs11-comment] Behavior of C_Decrypt in pkcs#11

From
Jason King <>
Date
2019-08-17T00:06:12+00:00
ID
CA+HC60xFEBiTqHagFE=
Thread
Re: [pkcs11-comment] Behavior of C_Decrypt in pkcs#11
I think your understanding is largely correct. The current requirement is when the output buffer is not NULL and CKR_BUFFER_TOO_SMALL is returned, that the _exact_ size of the output plaintext must be returned (as well as allow the C_Decrypt call to be tried again without having to call C_DecryptInit). I would rather see this requirement relaxed so that an implementation can report a less precise value when returning CKR_BUFFER_TOO_SMALL regardless if the output buffer is NULL or not. The output buffer wonât be completely filled, but that already has to happen when calling C_DecryptUpdate.

Using your example, with a 272 byte ciphertext and 256 byte plaintext, even if you call C_Decrypt with a one byte buffer, it still must decrypt the whole ciphertext, strip the padding, set 256 as the plaintext size, and return CKR_BUFFER_TOO_SMALL, all while not terminating the decryption operation so it can be tried again until it succeeds or a different error occurs.  Implementing the correct semantics here is a royal pain (I speak from _very_ recent experience). Iâm guessing the HSMs returning CKR_BUFFER_TOO_SMALL are expecting an output buffer at least as large as the input ciphertext (it makes the implementation significantly simpler).

 

 

From:ÂAmit K <>
Reply:ÂAmit K <>
Date:ÂAugust 16, 2019 at 5:56:25 PM
To:Âpkcs11 <>
Subject:Â [pkcs11-comment] Behavior of C_Decrypt in pkcs#11 

 

Hi all,

I want to suggest that the behavior of theÂC_Decryptfunction
should be more clearly defined in the pkcs#11 standard. My
observation arises from testing with several HSM brands, where I
noticed an inconsistency when using symmetric key mechanisms that
return variable length output, such as theÂCKM_AES_CBC_PADÂmechanism.Â

To illustrate my point I shall give an example: suppose that I have
a 272 bytes long ciphertext, which I know should actually decrypt
to 256 bytes via theÂCKM_AES_CBC_PADÂmechanism,
which means a full block of padding was added. (I know this because
I originally encrypted 256 bytes via the same mechanism).

I know thatÂaccording
to the standardÂwhen invokingÂC_DecryptÂwith
a NULL output buffer the function may return an output length which
is somewhat longer than the actual required length, in particular
when padding is used this is understandable, as the function can't
know how many padding bytes are in the final block without carrying
out the actual decryption. But there's nothing in the standard
states that it is necessary when I *do* know what output length to
expect, which is the use case I am describing.

So what I noticed is that some HSMs will successfully return
exactly 256 bytes back as a response to a C_Decrypt for such a
ciphertext, while others will return aÂCKR_BUFFER_TOO_SMALLÂerror
as a result. I guess that the implementations which return this
error just don't allocate an internal buffer for the final block
which contains the padding, to actually check its contents and how
much padding bytes are there. Without doing that it would be
natural to require more bytes in the output buffer than they may
actually need.Â

So I think that the issue with the standard is that there's no
clear requirement to make a call with a NULL output buffer to
C_Decrypt before invoking it with a real buffer - so that some
implementations seem to assume you have done both while others are
more conservative, resulting in the inconsistency I described.

If this issue can be either clarified (I may be misunderstanding
something about the standard) or perhaps addressed in a future
version of pkcs#11, that would be of great help.

Best Regards,

AmitÂ

Â

P.S. I posted a question with a similar pharsing a while ago in the
SO site:Âhttps://stackoverflow.com/questions/56818371/what-is-the-correct-behavior-of-c-decrypt-in-pkcs11ÂÂ

but so far got no satisfactory answer.