softDESCrypt.c revision 726fad2a65f16c200a03969c29cb5c86c2d427db
4126N/A * The contents of this file are subject to the terms of the 4126N/A * Common Development and Distribution License (the "License"). 4126N/A * You may not use this file except in compliance with the License. 4126N/A * See the License for the specific language governing permissions 4126N/A * and limitations under the License. 4126N/A * When distributing Covered Code, include this CDDL HEADER in each 4126N/A * If applicable, add the following below this CDDL HEADER, with the 4126N/A * fields enclosed by brackets "[]" replaced with your own identifying 4126N/A * information: Portions Copyright [yyyy] [name of copyright owner] 4126N/A * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. 4126N/A * Allocate context for the active encryption or decryption operation, and 4126N/A * generate DES or DES3 key schedule to speed up the operation. 4126N/A /* Allocate key schedule for DES or DES3 based on key type. */ 4126N/A /* Called by C_EncryptInit. */ 4126N/A /* Called by C_DecryptInit. */ 4126N/A * If this is a non-sensitive key and it does NOT have 4126N/A * a key schedule yet, then allocate one and expand it. 4126N/A * Otherwise, if its a non-sensitive key, and it DOES have 4126N/A * a key schedule already attached to it, just copy the 4126N/A * pre-expanded schedule to the context and avoid the 4126N/A * extra key schedule expansion operation. 4126N/A /* Initialize key schedule for DES or DES3. */ 4126N/A /* Copy the pre-expanded key schedule from the key object */ 4126N/A /* for sensitive keys, we cannot cache the key schedule */ 4126N/A * soft_des_encrypt_common() 4126N/A * session_p: pointer to soft_session_t struct 4126N/A * pData: pointer to the input data to be encrypted 4126N/A * ulDataLen: length of the input data 4126N/A * pEncrypted: pointer to the output data after encryption 4126N/A * pulEncryptedLen: pointer to the length of the output data 4126N/A * update: boolean flag indicates caller is soft_encrypt 4126N/A * This function calls the corresponding encrypt routine based 4126N/A * CKR_BUFFER_TOO_SMALL: the output buffer provided by application 4126N/A * CKR_FUNCTION_FAILED: encrypt function failed 4126N/A * CKR_DATA_LEN_RANGE: the input data is not a multiple of blocksize 4126N/A * DES only takes input length that is a multiple of blocksize 4126N/A * for C_Encrypt function with the mechanism CKM_DES<n>_ECB or 4126N/A * DES allows any input length for C_Encrypt function with the 4126N/A * mechanism CKM_DES<n>_CBC_PAD and for C_EncryptUpdate function. * For CKM_DES<n>_CBC_PAD, compute output length to * count for the padding. If the length of input * data is a multiple of blocksize, then make output * length to be the sum of the input length and * one blocksize. Otherwise, output length will * be rounded up to the next multiple of blocksize. * For non-padding mode, the output length will * be same as the input length. * If application asks for the length of the output buffer * to hold the ciphertext? /* Is the application-supplied buffer large enough? */ /* Encrypt pad bytes in a separate operation */ * Called by C_EncryptUpdate * Add the lengths of last remaining data and current * plaintext together to get the total input length. * If the total input length is less than one blocksize, * or if the total input length is just one blocksize and * the mechanism is CKM_DES<n>_CBC_PAD, we will need to delay * encryption until when more data comes in next * C_EncryptUpdate or when C_EncryptFinal is called. * Save input data and its length in * the remaining buffer of DES context. /* Set encrypted data length to 0. */ /* Compute the length of remaing data. */ * Make sure that the output length is a multiple of * If application asks for the length of the output buffer * to hold the ciphertext? /* Is the application-supplied buffer large enough? */ * Copy last remaining data and current input data /* Crunch one block of data for DES. */ * For encrypt update, if there is remaining * data, save it and its length in the context. /* Encrypt multiple blocks of data. */ * For encrypt update, if there is remaining data, * save it and its length in the context. * Save the remainder of the input * block in a temporary block because * we don't want to overrun the input buffer * by tacking on pad bytes. /* Encrypt last block containing pad bytes. */ * The following code will be executed if the caller is * soft_encrypt() or an error occurred. The encryption * operation will be terminated so we need to do some cleanup. * soft_des_decrypt_common() * session_p: pointer to soft_session_t struct * pEncrypted: pointer to the input data to be decrypted * ulEncryptedLen: length of the input data * pData: pointer to the output data * pulDataLen: pointer to the length of the output data * Update: boolean flag indicates caller is soft_decrypt * This function calls the corresponding decrypt routine based * CKR_BUFFER_TOO_SMALL: the output buffer provided by application * CKR_ENCRYPTED_DATA_LEN_RANGE: the input data is not a multiple * CKR_FUNCTION_FAILED: decrypt function failed * DES only takes input length that is a multiple of 8 bytes * for C_Decrypt function with the mechanism CKM_DES<n>_ECB, * CKM_DES<n>_CBC or CKM_DES<n>_CBC_PAD. * DES allows any input length for C_DecryptUpdate function. * If application asks for the length of the output buffer /* Is the application-supplied buffer large enough? */ /* Set output length same as input length. */ * For CKM_DES<n>_CBC_PAD, we don't know how * many bytes for padding at this time, so * we'd assume one block was padded. * Called by C_DecryptUpdate * Add the lengths of last remaining data and current * input data together to get the total input length. * If the total input length is less than one blocksize, * or if the total input length is just one blocksize and * the mechanism is CKM_DES<n>_CBC_PAD, we will need to delay * decryption until when more data comes in next * C_DecryptUpdate or when C_DecryptFinal is called. * Save input data and its length in * the remaining buffer of DES context. /* Set output data length to 0. */ /* Compute the length of remaing data. */ * Make sure that the output length is a multiple of * If the input data length is a multiple of * blocksize, then save the last block of input * data in the remaining buffer. C_DecryptFinal * will handle this last block of data. * If application asks for the length of the output buffer * Is the application-supplied buffer large enough? * Copy last remaining data and current input data /* Crunch one block of data for DES. */ * For decrypt update, if there is remaining * data, save it and its length in the context. /* Decrypt multiple blocks of data. */ /* Decrypt last block containing pad bytes. */ /* Decrypt last block containing pad bytes. */ * Remove padding bytes after decryption of * ciphertext block to produce the original * For decrypt update, if there is remaining data, * save it and its length in the context. * The following code will be executed if the caller is * soft_decrypt() or an error occurred. The decryption * operation will be terminated so we need to do some cleanup. * Allocate and initialize a context for DES CBC mode of operation. * Allocate and initialize DES contexts for both signing and encrypting, * saving both context pointers in the session struct. For general-length DES * MAC, check the length in the parameter to see if it is in the right range. /* initialization vector is zero for DES MAC */ * For non-general DES MAC, output is always half as /* allocate a context for DES encryption */ * Called by soft_sign(), soft_sign_final(), soft_verify() or /* Application asks for the length of the output buffer. */ /* Is the application-supplied buffer large enough? */ * If there is data left in the buffer from a previous * SignUpdate() call, pass enough zeroed data to a * soft_sign_update call to pad the remainder * By passing a buffer to soft_encrypt_final, * we force it to pad the remaining block * The last block of enciphered data is stored in: * soft_des_ctx_encrypt->des_cbc->des_ctx->dc_lastp * Copy that data to last_block * Passing a NULL output buffer here * forces the routine to just return. * If the input length is not multiple of block size, then * determine the correct encrypted data length by rounding * Because we always use DES_CBC_PAD mechanism * be padded to the next 8 byte boundary. * Adjust the length fields here accordingly. * Pad the last block with zeros by copying pData into a zeroed * pEncrypted. Then pass pEncrypted into soft_encrypt as input /* the leftmost mac_len bytes of last_block is our MAC */ /* soft_encrypt_common() has freed the encrypt context */ * Called by soft_sign_update() * The DES MAC is calculated by taking the specified number of * left-most bytes within the last block of * encrypted data, while the context of the multi-part * encryption stores the block necessary for XORing with the * input as per cipher block chaining . Therefore, none of the * intermediary encrypted blocks of data are necessary for * the DES MAC, and we can create a placeholder local buffer * for the encrypted data, which is immediately throw away. /* Avoid the malloc if we won't be encrypting any data */ /* round up to the nearest multiple of block size */