Cryptoki: a cryptographic Token Interface



Download 360.55 Kb.
Page121/196
Date22.12.2023
Size360.55 Kb.
#63026
1   ...   117   118   119   120   121   122   123   124   ...   196
v201-95
pkcs11-base-v2.40-cos01

C_DecryptVerifyUpdate


CK_DEFINE_FUNCTION(CK_RV, C_DecryptVerifyUpdate)(
CK_SESSION_HANDLE hSession,
CK_BYTE_PTR pEncryptedPart,
CK_ULONG ulEncryptedPartLen,
CK_BYTE_PTR pPart,
CK_ULONG_PTR pulPartLen
);
C_DecryptVerifyUpdate continues a multiple-part combined decryption and verification operation, processing another data part. hSession is the session’s handle; pEncryptedPart points to the encrypted data; ulEncryptedPartLen is the length of the encrypted data; pPart points to the location that receives the recovered data; and pulPartLen points to the location that holds the length of the recovered data.
C_DecryptVerifyUpdate uses the convention described in Section on producing output. If a C_DecryptVerifyUpdate call does not produce decrypted output (because an error occurs, or because pPart has the value NULL_PTR, or because pulPartLen is too small to hold the entire encrypted part output), then no plaintext is passed to the active verification operation.
Decryption and signature operations must both be active (they must have been initialized with C_DecryptInit and C_VerifyInit, respectively). This function may be called any number of times in succession, and may be interspersed with C_DecryptUpdate and C_VerifyUpdate calls.
Use of C_DecryptVerifyUpdate involves a pipelining issue that does not arise when using C_SignEncryptUpdate, the “inverse function” of C_DecryptVerifyUpdate. This is because when C_SignEncryptUpdate is called, precisely the same input is passed to both the active signing operation and the active encryption operation; however, when C_DecryptVerifyUpdate is called, the input passed to the active verifying operation is the output of the active decryption operation. This issue comes up only when the mechanism used for decryption performs padding.
In particular, envision a 24-byte ciphertext which was obtained by encrypting an 18-byte plaintext with DES in CBC mode with PKCS padding. Consider an application which will simultaneously decrypt this ciphertext and verify a signature on the original plaintext thereby obtained.
After initializing decryption and verification operations, the application passes the 24-byte ciphertext (3 DES blocks) into C_DecryptVerifyUpdate. C_DecryptVerifyUpdate returns exactly 16 bytes of plaintext, since at this point, Cryptoki doesn’t know if there’s more ciphertext coming, or if the last block of ciphertext held any padding. These 16 bytes of plaintext are passed into the active verification operation.
Since there is no more ciphertext, the application calls C_DecryptFinal. This tells Cryptoki that there’s no more ciphertext coming, and the call returns the last 2 bytes of plaintext. However, since the active decryption and verification operations are linked only through the C_DecryptVerifyUpdate call, these 2 bytes of plaintext are not passed on to the verification mechanism.
A call to C_VerifyFinal, therefore, would verify whether or not the signature supplied is a valid signature on the first 16 bytes of the plaintext, not on the entire plaintext. It is crucial that, before C_VerifyFinal is called, the last 2 bytes of plaintext get passed into the active verification operation via a C_VerifyUpdate call.
Because of this, it is critical that when an application uses a padded decryption mechanism with C_DecryptVerifyUpdate, it knows exactly how much plaintext has been passed into the active verification operation. Extreme caution is warranted when using a padded decryption mechanism with C_DecryptVerifyUpdate.
Return values: CKR_BUFFER_TOO_SMALL, CKR_CRYPTOKI_NOT_INITIALIZED, CKR_DATA_LEN_RANGE, CKR_DEVICE_ERROR, CKR_DEVICE_MEMORY, CKR_DEVICE_REMOVED, CKR_ENCRYPTED_DATA_INVALID, CKR_ENCRYPTED_DATA_LEN_RANGE, CKR_FUNCTION_CANCELED, CKR_FUNCTION_FAILED, CKR_GENERAL_ERROR, CKR_HOST_MEMORY, CKR_OK, CKR_OPERATION_NOT_INITIALIZED, CKR_SESSION_CLOSED, CKR_SESSION_HANDLE_INVALID.
Example:
#define BUF_SZ 512

CK_SESSION_HANDLE hSession;


CK_OBJECT_HANDLE hDecryptionKey, hMacKey;
CK_BYTE iv[8];
CK_MECHANISM decryptionMechanism = {
CKM_DES_ECB, iv, sizeof(iv)
};
CK_MECHANISM verifyMechanism = {
CKM_DES_MAC, NULL_PTR, 0
};
CK_BYTE encryptedData[(2*BUF_SZ)+8];
CK_BYTE MAC[4];
CK_ULONG ulMacLen;
CK_BYTE data[BUF_SZ];
CK_ULONG ulDataLen, ulLastUpdateSize;
CK_RV rv;

.
.
.


memset(iv, 0, sizeof(iv));
memset(encryptedData, ‘A’, ((2*BUF_SZ)+8));
rv = C_DecryptInit(hSession, &decryptionMechanism, hDecryptionKey);
if (rv != CKR_OK) {
.
.
.
}
rv = C_VerifyInit(hSession, &verifyMechanism, hMacKey);
if (rv != CKR_OK){
.
.
.
}

ulDataLen = sizeof(data);


rv = C_DecryptVerifyUpdate(
hSession,
&encryptedData[0], BUF_SZ,
data, &ulDataLen);
.
.
.
ulDataLen = sizeof(data);
rv = C_DecryptVerifyUpdate(
hSession,
&encryptedData[BUF_SZ], BUF_SZ,
data, &uldataLen);
.
.
.

/*
* The last portion of the buffer needs to be handled with


* separate calls to deal with padding issues in ECB mode
*/

/* First, complete the decryption of the buffer */


ulLastUpdateSize = sizeof(data);
rv = C_DecryptUpdate(
hSession,
&encryptedData[BUF_SZ*2], 8,
data, &ulLastUpdateSize);
.
.
.
/* Get last little piece of plaintext. Should have length 0 */
ulDataLen = sizeof(data)-ulLastUpdateSize;
rv = C_DecryptFinal(hSession, &data[ulLastUpdateSize], &ulDataLen);
if (rv != CKR_OK) {
.
.
.
}

/* Send last bit of plaintext to verification operation */


rv = C_VerifyUpdate(hSession, &data[BUF_SZ*2], 5);
if (rv != CKR_OK) {
.
.
.
}
rv = C_VerifyFinal(hSession, MAC, ulMacLen);
if (rv == CKR_SIGNATURE_INVALID) {
.
.
.
}

Download 360.55 Kb.

Share with your friends:
1   ...   117   118   119   120   121   122   123   124   ...   196




The database is protected by copyright ©ininet.org 2024
send message

    Main page