OASIS Mailing List ArchivesView the OASIS mailing list archive below
or browse/search using MarkMail.


Help: OASIS Mailing Lists Help | MarkMail Help

pkcs11-comment message

[Date Prev] | [Thread Prev] | [Thread Next] | [Date Next] -- [Date Index] | [Thread Index] | [List Home]

Subject: C_Decrypt / C_DecryptFinal behavior

In attempting to fix a bug in a PKCS#11 implementation, Iâve come across a somewhat hairy scenario that Iâm hoping someone can provide some guidance: ÂThe base specification section 5.2 describes the behavior when dealing with variable sized buffer arguments:

1.ÂÂÂÂÂIfÂpBufÂis NULL_PTR, then all that the function does is return (in *pulBufLen) a number of bytes which would suffice to hold the cryptographic output produced from the input to the function. This number may somewhat exceed the precise number of bytes needed, but should not exceed it by a large amount. CKR_OK is returned by the function.

2.ÂÂÂÂÂIfÂpBufÂis not NULL_PTR, then *pulBufLenÂMUST contain the size in bytes of the buffer pointed to byÂpBuf. If that buffer is large enough to hold the cryptographic output produced from the input to the function, then that cryptographic output is placed there, and CKR_OK is returned by the function. If the buffer is not large enough, then CKR_BUFFER_TOO_SMALL is returned. In either case, *pulBufLenÂis set to hold theÂexactÂnumber of bytes needed to hold the cryptographic output produced from the input to the function.

For the definition of C_Decrypt() and C_DecryptFinal(), it also indicates that an error of CKR_BUFFER_TOO_SMALL doesnât terminate the ongoing operation, implying that even with the output buffer in the call isnât NULL, the functions can be called again (without calling C_DecryptInit() again) to retrieve the plaintext. For most mechanisms, this isnât a problem. However some mechanisms (such as CKM_AES_CBC_PAD) require decrypted the entire input ciphertext before the actual plaintext size is known, and satisfying the pBuf != NULL and allowing retries when CKR_BUFFER_TOO_SMALL is returned seems problematic to satisfy both behaviors. For example:

CK_BYTE ciphertext[AES_BLOCK_LEN * 4000] = { â };
CK_BYTE_PTR *plaintext;
CK_MECHANISM mech = { CKM_AES_CBC_PAD, iv, ivlen };

/* Note that plaintext is << ciphertext */
plaintext = malloc(AES_BLOCK_LEN * 2);
len = AES_BLOCK_LEN * 2;

C_DecryptInit(handle, &mech, keyHandle);

Â* This should return CKR_BUFFER_TOO_SMALL, however to set len appropriately,
Â* the entire contents of ciphertext must be decrypted, and the resulting ciphertext
Â* must be saved internally as part of the operation, or the decryption operation state
Â* must support some sort of rollback or snapshot to perform the full decryption
Â* each time C_Decrypt() is called without the current operation terminating.
C_Decrypt(hSession, ciphertext, sizeof (ciphertext), plaintext, &len);

Iâm not really sure what the best thing to do here â Iâm not aware of any AES-CBC mechanisms that really support any sort of checkpoint/rollback â one could duplicate the current decryption state on each C_Decrypt/C_DecryptUpdate/C_DecryptFinal call until itâs determined the copy is no longer needed, but that seems clunky. I havenât found anything that seems like it would take precedence over the two behaviors â did I just miss it (I looked at both the 2.40 w/ errata as well as the draft 3.0 and didnât see anything that looked like it might), or would it be worth clarifying the behavior in such a situation?

[Date Prev] | [Thread Prev] | [Thread Next] | [Date Next] -- [Date Index] | [Thread Index] | [List Home]