softDecryptUtil.c revision 2786:2d1d57651e47
1213379Shselasky/* 2213379Shselasky * CDDL HEADER START 3213379Shselasky * 4213379Shselasky * The contents of this file are subject to the terms of the 5213379Shselasky * Common Development and Distribution License (the "License"). 6213379Shselasky * You may not use this file except in compliance with the License. 7213379Shselasky * 8213379Shselasky * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9213379Shselasky * or http://www.opensolaris.org/os/licensing. 10213379Shselasky * See the License for the specific language governing permissions 11213379Shselasky * and limitations under the License. 12213379Shselasky * 13213379Shselasky * When distributing Covered Code, include this CDDL HEADER in each 14213379Shselasky * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15213379Shselasky * If applicable, add the following below this CDDL HEADER, with the 16213379Shselasky * fields enclosed by brackets "[]" replaced with your own identifying 17213379Shselasky * information: Portions Copyright [yyyy] [name of copyright owner] 18213379Shselasky * 19213379Shselasky * CDDL HEADER END 20213379Shselasky */ 21213379Shselasky/* 22213379Shselasky * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 23213379Shselasky * Use is subject to license terms. 24213379Shselasky */ 25213379Shselasky 26213379Shselasky#pragma ident "%Z%%M% %I% %E% SMI" 27213379Shselasky 28213379Shselasky#include <pthread.h> 29213379Shselasky#include <stdlib.h> 30213379Shselasky#include <string.h> 31213379Shselasky#include <strings.h> 32213379Shselasky#include <sys/types.h> 33213379Shselasky#include <security/cryptoki.h> 34213379Shselasky#include <des_cbc_crypt.h> 35213379Shselasky#include <aes_cbc_crypt.h> 36213379Shselasky#include <blowfish_cbc_crypt.h> 37213379Shselasky#include <arcfour.h> 38213379Shselasky#include "softSession.h" 39213379Shselasky#include "softObject.h" 40213379Shselasky#include "softOps.h" 41213379Shselasky#include "softCrypt.h" 42213379Shselasky#include "softRSA.h" 43213379Shselasky 44213379Shselasky 45213379Shselasky/* 46213379Shselasky * Remove padding bytes. 47213379Shselasky */ 48213379ShselaskyCK_RV 49213379Shselaskysoft_remove_pkcs7_padding(CK_BYTE *pData, CK_ULONG padded_len, 50213379Shselasky CK_ULONG *pulDataLen, int block_size) 51213379Shselasky{ 52213379Shselasky 53213379Shselasky CK_BYTE pad_value; 54213379Shselasky 55213379Shselasky pad_value = pData[padded_len - 1]; 56213379Shselasky 57213379Shselasky 58213379Shselasky /* Make sure there is a valid padding value. */ 59213379Shselasky if ((pad_value == 0) || (pad_value > block_size)) 60213379Shselasky return (CKR_ENCRYPTED_DATA_INVALID); 61228483Shselasky 62213379Shselasky *pulDataLen = padded_len - pad_value; 63213379Shselasky return (CKR_OK); 64213379Shselasky} 65213379Shselasky 66228483Shselasky 67213379Shselasky/* 68213379Shselasky * soft_decrypt_init() 69213379Shselasky * 70213379Shselasky * Arguments: 71213379Shselasky * session_p: pointer to soft_session_t struct 72213379Shselasky * pMechanism: pointer to CK_MECHANISM struct provided by application 73228483Shselasky * key_p: pointer to key soft_object_t struct 74228483Shselasky * 75228483Shselasky * Description: 76228483Shselasky * called by C_DecryptInit(). This function calls the corresponding 77213379Shselasky * decrypt init routine based on the mechanism. 78227843Smarius * 79213379Shselasky * Returns: 80213379Shselasky * CKR_OK: success 81213379Shselasky * CKR_HOST_MEMORY: run out of system memory 82213379Shselasky * CKR_MECHANISM_PARAM_INVALID: invalid parameters in mechanism 83213379Shselasky * CKR_MECHANISM_INVALID: invalid mechanism type 84213379Shselasky * CKR_KEY_TYPE_INCONSISTENT: incorrect type of key to use 85213379Shselasky * with the specified mechanism 86213379Shselasky */ 87213379ShselaskyCK_RV 88213379Shselaskysoft_decrypt_init(soft_session_t *session_p, CK_MECHANISM_PTR pMechanism, 89290331Shselasky soft_object_t *key_p) 90213379Shselasky{ 91213379Shselasky 92213379Shselasky CK_RV rv; 93213379Shselasky 94213379Shselasky switch (pMechanism->mechanism) { 95238015Smav 96238015Smav case CKM_DES_ECB: 97238015Smav 98297852Smav if (key_p->key_type != CKK_DES) { 99297852Smav return (CKR_KEY_TYPE_INCONSISTENT); 100297852Smav } 101238015Smav 102238015Smav goto ecb_common; 103238015Smav 104289161Skevlo case CKM_DES3_ECB: 105289161Skevlo 106289161Skevlo if ((key_p->key_type != CKK_DES2) && 107249336Smav (key_p->key_type != CKK_DES3)) { 108249336Smav return (CKR_KEY_TYPE_INCONSISTENT); 109290331Shselasky } 110290331Shselasky 111249336Smavecb_common: 112276968Shselasky 113289161Skevlo return (soft_des_crypt_init_common(session_p, pMechanism, 114262364Shselasky key_p, B_FALSE)); 115238015Smav 116238015Smav case CKM_DES_CBC: 117238551Smav case CKM_DES_CBC_PAD: 118238551Smav 119275439Smav if (key_p->key_type != CKK_DES) { 120275439Smav return (CKR_KEY_TYPE_INCONSISTENT); 121297341Smav } 122297341Smav 123290331Shselasky goto cbc_common; 124290331Shselasky 125238015Smav case CKM_DES3_CBC: 126289013Shselasky case CKM_DES3_CBC_PAD: 127289013Shselasky { 128289013Shselasky soft_des_ctx_t *soft_des_ctx; 129238015Smav 130238015Smav if ((key_p->key_type != CKK_DES2) && 131238015Smav (key_p->key_type != CKK_DES3)) { 132238015Smav return (CKR_KEY_TYPE_INCONSISTENT); 133213379Shselasky } 134213379Shselasky 135222018Srucbc_common: 136213379Shselasky if ((pMechanism->pParameter == NULL) || 137213379Shselasky (pMechanism->ulParameterLen != DES_BLOCK_LEN)) { 138213379Shselasky return (CKR_MECHANISM_PARAM_INVALID); 139213379Shselasky } 140213379Shselasky 141213379Shselasky rv = soft_des_crypt_init_common(session_p, pMechanism, 142213379Shselasky key_p, B_FALSE); 143213379Shselasky 144213379Shselasky if (rv != CKR_OK) 145213379Shselasky return (rv); 146213379Shselasky 147213379Shselasky (void) pthread_mutex_lock(&session_p->session_mutex); 148213379Shselasky 149213379Shselasky soft_des_ctx = (soft_des_ctx_t *)session_p->decrypt.context; 150213379Shselasky /* Save Initialization Vector (IV) in the context. */ 151213379Shselasky (void) memcpy(soft_des_ctx->ivec, pMechanism->pParameter, 152213379Shselasky DES_BLOCK_LEN); 153213379Shselasky 154253398Skib /* Allocate a context for DES cipher-block chaining. */ 155253398Skib soft_des_ctx->des_cbc = (void *)des_cbc_ctx_init( 156253398Skib soft_des_ctx->key_sched, soft_des_ctx->keysched_len, 157251499Shselasky soft_des_ctx->ivec, key_p->key_type); 158251499Shselasky 159251499Shselasky if (soft_des_ctx->des_cbc == NULL) { 160251499Shselasky bzero(soft_des_ctx->key_sched, 161251499Shselasky soft_des_ctx->keysched_len); 162251499Shselasky free(soft_des_ctx->key_sched); 163251499Shselasky free(session_p->decrypt.context); 164251499Shselasky session_p->decrypt.context = NULL; 165251499Shselasky (void) pthread_mutex_unlock(&session_p->session_mutex); 166251499Shselasky return (CKR_HOST_MEMORY); 167213379Shselasky } 168255768Shselasky 169255768Shselasky (void) pthread_mutex_unlock(&session_p->session_mutex); 170255768Shselasky 171268884Shselasky return (rv); 172268884Shselasky } 173255768Shselasky case CKM_AES_ECB: 174255768Shselasky 175255768Shselasky if (key_p->key_type != CKK_AES) { 176255768Shselasky return (CKR_KEY_TYPE_INCONSISTENT); 177255768Shselasky } 178255768Shselasky 179255768Shselasky return (soft_aes_crypt_init_common(session_p, pMechanism, 180268604Shselasky key_p, B_FALSE)); 181268884Shselasky 182268884Shselasky case CKM_AES_CBC: 183268604Shselasky case CKM_AES_CBC_PAD: 184268884Shselasky { 185268884Shselasky soft_aes_ctx_t *soft_aes_ctx; 186255768Shselasky 187255768Shselasky if (key_p->key_type != CKK_AES) { 188255768Shselasky return (CKR_KEY_TYPE_INCONSISTENT); 189255768Shselasky } 190255768Shselasky 191255768Shselasky if ((pMechanism->pParameter == NULL) || 192255768Shselasky (pMechanism->ulParameterLen != AES_BLOCK_LEN)) { 193213379Shselasky return (CKR_MECHANISM_PARAM_INVALID); 194213379Shselasky } 195213379Shselasky 196253094Skib rv = soft_aes_crypt_init_common(session_p, pMechanism, 197289161Skevlo key_p, B_FALSE); 198289161Skevlo 199213379Shselasky if (rv != CKR_OK) 200213379Shselasky return (rv); 201213379Shselasky 202213379Shselasky (void) pthread_mutex_lock(&session_p->session_mutex); 203213379Shselasky 204213379Shselasky soft_aes_ctx = (soft_aes_ctx_t *)session_p->decrypt.context; 205278278Shselasky 206213379Shselasky /* Save Initialization Vector (IV) in the context. */ 207213379Shselasky (void) memcpy(soft_aes_ctx->ivec, pMechanism->pParameter, 208213379Shselasky AES_BLOCK_LEN); 209213379Shselasky 210213379Shselasky /* Allocate a context for AES cipher-block chaining. */ 211279693Shselasky soft_aes_ctx->aes_cbc = (void *)aes_cbc_ctx_init( 212279693Shselasky soft_aes_ctx->key_sched, soft_aes_ctx->keysched_len, 213290331Shselasky soft_aes_ctx->ivec); 214290331Shselasky 215279693Shselasky if (soft_aes_ctx->aes_cbc == NULL) { 216279693Shselasky bzero(soft_aes_ctx->key_sched, 217289161Skevlo soft_aes_ctx->keysched_len); 218289161Skevlo free(soft_aes_ctx->key_sched); 219289161Skevlo free(session_p->decrypt.context); 220279693Shselasky session_p->decrypt.context = NULL; 221290331Shselasky (void) pthread_mutex_unlock(&session_p->session_mutex); 222290331Shselasky return (CKR_HOST_MEMORY); 223290331Shselasky } 224290331Shselasky 225290331Shselasky (void) pthread_mutex_unlock(&session_p->session_mutex); 226290331Shselasky 227290331Shselasky return (rv); 228290331Shselasky } 229290331Shselasky 230290331Shselasky case CKM_BLOWFISH_CBC: 231290331Shselasky { 232290331Shselasky soft_blowfish_ctx_t *soft_blowfish_ctx; 233290331Shselasky 234279693Shselasky if (key_p->key_type != CKK_BLOWFISH) 235290331Shselasky return (CKR_KEY_TYPE_INCONSISTENT); 236279693Shselasky 237278278Shselasky if ((pMechanism->pParameter == NULL) || 238278278Shselasky (pMechanism->ulParameterLen != BLOWFISH_BLOCK_LEN)) 239278278Shselasky return (CKR_MECHANISM_PARAM_INVALID); 240278278Shselasky 241278278Shselasky rv = soft_blowfish_crypt_init_common(session_p, pMechanism, 242278278Shselasky key_p, B_FALSE); 243278278Shselasky 244278278Shselasky if (rv != CKR_OK) 245251499Shselasky return (rv); 246251499Shselasky 247276965Shselasky (void) pthread_mutex_lock(&session_p->session_mutex); 248289161Skevlo 249276965Shselasky soft_blowfish_ctx = 250276965Shselasky (soft_blowfish_ctx_t *)session_p->decrypt.context; 251276965Shselasky 252276965Shselasky /* Save Initialization Vector in the context. */ 253276965Shselasky (void) memcpy(soft_blowfish_ctx->ivec, pMechanism->pParameter, 254253094Skib BLOWFISH_BLOCK_LEN); 255253094Skib 256276965Shselasky /* Allocate a context for CBC */ 257276965Shselasky soft_blowfish_ctx->blowfish_cbc = 258213379Shselasky (void *)blowfish_cbc_ctx_init(soft_blowfish_ctx->key_sched, 259276965Shselasky soft_blowfish_ctx->keysched_len, 260213379Shselasky soft_blowfish_ctx->ivec); 261255768Shselasky 262213379Shselasky if (soft_blowfish_ctx->blowfish_cbc == NULL) { 263213379Shselasky bzero(soft_blowfish_ctx->key_sched, 264213379Shselasky soft_blowfish_ctx->keysched_len); 265213379Shselasky free(soft_blowfish_ctx->key_sched); 266213379Shselasky free(session_p->decrypt.context = NULL); 267213379Shselasky (void) pthread_mutex_unlock(&session_p->session_mutex); 268213379Shselasky return (CKR_HOST_MEMORY); 269213379Shselasky } 270213379Shselasky 271213379Shselasky (void) pthread_mutex_unlock(&session_p->session_mutex); 272251499Shselasky return (rv); 273251499Shselasky } 274251499Shselasky 275251499Shselasky case CKM_RC4: 276276965Shselasky 277276965Shselasky if (key_p->key_type != CKK_RC4) { 278276965Shselasky return (CKR_KEY_TYPE_INCONSISTENT); 279276965Shselasky } 280251499Shselasky 281251499Shselasky return (soft_arcfour_crypt_init(session_p, pMechanism, key_p, 282251499Shselasky B_FALSE)); 283213379Shselasky 284276965Shselasky case CKM_RSA_X_509: 285276965Shselasky case CKM_RSA_PKCS: 286276965Shselasky 287276965Shselasky if (key_p->key_type != CKK_RSA) { 288276965Shselasky return (CKR_KEY_TYPE_INCONSISTENT); 289276965Shselasky } 290276965Shselasky 291276965Shselasky return (soft_rsa_crypt_init_common(session_p, pMechanism, 292251499Shselasky key_p, B_FALSE)); 293251499Shselasky 294228483Shselasky default: 295213379Shselasky return (CKR_MECHANISM_INVALID); 296213379Shselasky } 297213379Shselasky} 298213379Shselasky 299213379Shselasky 300213379Shselasky/* 301213379Shselasky * soft_decrypt_common() 302213379Shselasky * 303213379Shselasky * Arguments: 304213379Shselasky * session_p: pointer to soft_session_t struct 305213379Shselasky * pEncrypted: pointer to the encrypted data as input 306213379Shselasky * ulEncryptedLen: length of the input data 307213379Shselasky * pData: pointer to the output data contains plaintext 308213379Shselasky * pulDataLen: pointer to the length of the output data 309213379Shselasky * Update: boolean flag indicates caller is soft_decrypt 310213379Shselasky * or soft_decrypt_update 311213379Shselasky * 312213379Shselasky * Description: 313213379Shselasky * This function calls the corresponding decrypt routine based 314213379Shselasky * on the mechanism. 315213379Shselasky * 316213379Shselasky * Returns: 317213379Shselasky * see soft_decrypt_common(). 318213379Shselasky */ 319213379ShselaskyCK_RV 320213379Shselaskysoft_decrypt_common(soft_session_t *session_p, CK_BYTE_PTR pEncrypted, 321213379Shselasky CK_ULONG ulEncryptedLen, CK_BYTE_PTR pData, 322213379Shselasky CK_ULONG_PTR pulDataLen, boolean_t Update) 323213379Shselasky{ 324213379Shselasky 325213379Shselasky CK_MECHANISM_TYPE mechanism = session_p->decrypt.mech.mechanism; 326213379Shselasky 327227849Shselasky switch (mechanism) { 328213379Shselasky 329278278Shselasky case CKM_DES_ECB: 330278278Shselasky case CKM_DES_CBC: 331251499Shselasky case CKM_DES3_ECB: 332213379Shselasky case CKM_DES3_CBC: 333213379Shselasky 334213379Shselasky if (ulEncryptedLen == 0) { 335213379Shselasky *pulDataLen = 0; 336213379Shselasky return (CKR_OK); 337213379Shselasky } 338213379Shselasky /* FALLTHROUGH */ 339276965Shselasky 340276965Shselasky case CKM_DES_CBC_PAD: 341213379Shselasky case CKM_DES3_CBC_PAD: 342276965Shselasky 343213379Shselasky return (soft_des_decrypt_common(session_p, pEncrypted, 344213379Shselasky ulEncryptedLen, pData, pulDataLen, Update)); 345213379Shselasky 346213379Shselasky case CKM_AES_ECB: 347213379Shselasky case CKM_AES_CBC: 348213379Shselasky 349213379Shselasky if (ulEncryptedLen == 0) { 350213379Shselasky *pulDataLen = 0; 351213379Shselasky return (CKR_OK); 352213379Shselasky } 353213379Shselasky /* FALLTHROUGH */ 354213379Shselasky 355228483Shselasky case CKM_AES_CBC_PAD: 356228483Shselasky 357213379Shselasky return (soft_aes_decrypt_common(session_p, pEncrypted, 358213379Shselasky ulEncryptedLen, pData, pulDataLen, Update)); 359213379Shselasky 360213379Shselasky case CKM_BLOWFISH_CBC: 361213379Shselasky 362213379Shselasky if (ulEncryptedLen == 0) { 363213379Shselasky *pulDataLen = 0; 364213379Shselasky return (CKR_OK); 365213379Shselasky } 366213379Shselasky 367213379Shselasky return (soft_blowfish_decrypt_common(session_p, pEncrypted, 368213379Shselasky ulEncryptedLen, pData, pulDataLen, Update)); 369213379Shselasky 370213379Shselasky case CKM_RC4: 371213379Shselasky 372213379Shselasky if (ulEncryptedLen == 0) { 373213379Shselasky *pulDataLen = 0; 374213379Shselasky return (CKR_OK); 375213379Shselasky } 376213379Shselasky 377213379Shselasky 378213379Shselasky return (soft_arcfour_crypt(&(session_p->decrypt), pEncrypted, 379213379Shselasky ulEncryptedLen, pData, pulDataLen)); 380213379Shselasky 381213379Shselasky case CKM_RSA_X_509: 382213379Shselasky case CKM_RSA_PKCS: 383213379Shselasky 384213379Shselasky return (soft_rsa_decrypt_common(session_p, pEncrypted, 385213379Shselasky ulEncryptedLen, pData, pulDataLen, mechanism)); 386213379Shselasky 387213379Shselasky default: 388213379Shselasky return (CKR_MECHANISM_INVALID); 389213379Shselasky 390213379Shselasky } 391213379Shselasky} 392213379Shselasky 393213379Shselasky 394213379Shselasky/* 395213379Shselasky * soft_decrypt() 396213379Shselasky * 397213379Shselasky * Arguments: 398213379Shselasky * session_p: pointer to soft_session_t struct 399228483Shselasky * pEncryptedData: pointer to the encrypted data as input 400213379Shselasky * ulEncryptedDataLen: length of the input data 401 * pData: pointer to the output data contains plaintext 402 * pulDataLen: pointer to the length of the output data 403 * 404 * Description: 405 * called by C_Decrypt(). This function calls the soft_decrypt_common 406 * routine. 407 * 408 * Returns: 409 * see soft_decrypt_common(). 410 */ 411CK_RV 412soft_decrypt(soft_session_t *session_p, CK_BYTE_PTR pEncryptedData, 413 CK_ULONG ulEncryptedDataLen, CK_BYTE_PTR pData, 414 CK_ULONG_PTR pulDataLen) 415{ 416 417 return (soft_decrypt_common(session_p, pEncryptedData, 418 ulEncryptedDataLen, pData, pulDataLen, B_FALSE)); 419} 420 421 422/* 423 * soft_decrypt_update() 424 * 425 * Arguments: 426 * session_p: pointer to soft_session_t struct 427 * pEncryptedPart: pointer to the encrypted data as input 428 * ulEncryptedPartLen: length of the input data 429 * pPart: pointer to the output data contains plaintext 430 * pulPartLen: pointer to the length of the output data 431 * 432 * Description: 433 * called by C_DecryptUpdate(). This function calls the 434 * soft_decrypt_common routine (with update flag on). 435 * 436 * Returns: 437 * see soft_decrypt_common(). 438 */ 439CK_RV 440soft_decrypt_update(soft_session_t *session_p, CK_BYTE_PTR pEncryptedPart, 441 CK_ULONG ulEncryptedPartLen, CK_BYTE_PTR pPart, 442 CK_ULONG_PTR pulPartLen) 443{ 444 445 CK_MECHANISM_TYPE mechanism = session_p->decrypt.mech.mechanism; 446 447 switch (mechanism) { 448 449 case CKM_DES_ECB: 450 case CKM_DES_CBC: 451 case CKM_DES_CBC_PAD: 452 case CKM_DES3_ECB: 453 case CKM_DES3_CBC: 454 case CKM_DES3_CBC_PAD: 455 case CKM_AES_ECB: 456 case CKM_AES_CBC: 457 case CKM_AES_CBC_PAD: 458 case CKM_BLOWFISH_CBC: 459 case CKM_RC4: 460 461 return (soft_decrypt_common(session_p, pEncryptedPart, 462 ulEncryptedPartLen, pPart, pulPartLen, B_TRUE)); 463 464 default: 465 /* PKCS11: The mechanism only supports single-part operation. */ 466 return (CKR_MECHANISM_INVALID); 467 } 468 469} 470 471 472/* 473 * soft_decrypt_final() 474 * 475 * Arguments: 476 * session_p: pointer to soft_session_t struct 477 * pLastPart: pointer to the last recovered data part 478 * pulLastPartLen: pointer to the length of the last recovered data part 479 * 480 * Description: 481 * called by C_DecryptFinal(). 482 * 483 * Returns: 484 * CKR_OK: success 485 * CKR_FUNCTION_FAILED: decrypt final function failed 486 * CKR_ENCRYPTED_DATA_LEN_RANGE: remaining buffer contains bad length 487 */ 488CK_RV 489soft_decrypt_final(soft_session_t *session_p, CK_BYTE_PTR pLastPart, 490 CK_ULONG_PTR pulLastPartLen) 491{ 492 493 CK_MECHANISM_TYPE mechanism = session_p->decrypt.mech.mechanism; 494 CK_ULONG out_len; 495 CK_RV rv = CKR_OK; 496 int rc; 497 498 (void) pthread_mutex_lock(&session_p->session_mutex); 499 500 if (session_p->decrypt.context == NULL) { 501 rv = CKR_OPERATION_NOT_INITIALIZED; 502 *pulLastPartLen = 0; 503 goto clean2; 504 } 505 switch (mechanism) { 506 507 case CKM_DES_CBC_PAD: 508 case CKM_DES3_CBC_PAD: 509 { 510 511 soft_des_ctx_t *soft_des_ctx; 512 513 soft_des_ctx = (soft_des_ctx_t *)session_p->decrypt.context; 514 515 /* 516 * We should have only one block of data left in the 517 * remaining buffer. 518 */ 519 if (soft_des_ctx->remain_len != DES_BLOCK_LEN) { 520 *pulLastPartLen = 0; 521 rv = CKR_ENCRYPTED_DATA_LEN_RANGE; 522 /* Cleanup memory space. */ 523 free(soft_des_ctx->des_cbc); 524 bzero(soft_des_ctx->key_sched, 525 soft_des_ctx->keysched_len); 526 free(soft_des_ctx->key_sched); 527 528 goto clean1; 529 } 530 531 out_len = DES_BLOCK_LEN; 532 533 /* 534 * If application asks for the length of the output buffer 535 * to hold the plaintext? 536 */ 537 if (pLastPart == NULL) { 538 *pulLastPartLen = out_len; 539 rv = CKR_OK; 540 goto clean2; 541 } else { 542 crypto_data_t out; 543 544 /* Copy remaining data to the output buffer. */ 545 (void) memcpy(pLastPart, soft_des_ctx->data, 546 DES_BLOCK_LEN); 547 548 out.cd_format = CRYPTO_DATA_RAW; 549 out.cd_offset = 0; 550 out.cd_length = DES_BLOCK_LEN; 551 out.cd_raw.iov_base = (char *)pLastPart; 552 out.cd_raw.iov_len = DES_BLOCK_LEN; 553 554 /* Decrypt final block of data. */ 555 rc = des_decrypt_contiguous_blocks( 556 (des_ctx_t *)soft_des_ctx->des_cbc, 557 (char *)pLastPart, DES_BLOCK_LEN, &out); 558 559 if (rc == 0) { 560 /* 561 * Remove padding bytes after decryption of 562 * ciphertext block to produce the original 563 * plaintext. 564 */ 565 rv = soft_remove_pkcs7_padding(pLastPart, 566 DES_BLOCK_LEN, &out_len, DES_BLOCK_LEN); 567 if (rv != CKR_OK) 568 *pulLastPartLen = 0; 569 else 570 *pulLastPartLen = out_len; 571 } else { 572 *pulLastPartLen = 0; 573 rv = CKR_FUNCTION_FAILED; 574 } 575 576 /* Cleanup memory space. */ 577 free(soft_des_ctx->des_cbc); 578 bzero(soft_des_ctx->key_sched, 579 soft_des_ctx->keysched_len); 580 free(soft_des_ctx->key_sched); 581 582 } 583 584 break; 585 } 586 587 case CKM_DES_CBC: 588 case CKM_DES_ECB: 589 case CKM_DES3_CBC: 590 case CKM_DES3_ECB: 591 { 592 593 soft_des_ctx_t *soft_des_ctx; 594 595 soft_des_ctx = (soft_des_ctx_t *)session_p->decrypt.context; 596 /* 597 * CKM_DES_CBC and CKM_DES_ECB does not do any padding, 598 * so when the final is called, the remaining buffer 599 * should not contain any more data. 600 */ 601 *pulLastPartLen = 0; 602 if (soft_des_ctx->remain_len != 0) { 603 rv = CKR_ENCRYPTED_DATA_LEN_RANGE; 604 } else { 605 if (pLastPart == NULL) 606 goto clean2; 607 } 608 609 /* Cleanup memory space. */ 610 free(soft_des_ctx->des_cbc); 611 bzero(soft_des_ctx->key_sched, soft_des_ctx->keysched_len); 612 free(soft_des_ctx->key_sched); 613 614 break; 615 } 616 617 case CKM_AES_CBC_PAD: 618 { 619 620 soft_aes_ctx_t *soft_aes_ctx; 621 622 soft_aes_ctx = (soft_aes_ctx_t *)session_p->decrypt.context; 623 624 /* 625 * We should have only one block of data left in the 626 * remaining buffer. 627 */ 628 if (soft_aes_ctx->remain_len != AES_BLOCK_LEN) { 629 *pulLastPartLen = 0; 630 rv = CKR_ENCRYPTED_DATA_LEN_RANGE; 631 /* Cleanup memory space. */ 632 free(soft_aes_ctx->aes_cbc); 633 bzero(soft_aes_ctx->key_sched, 634 soft_aes_ctx->keysched_len); 635 free(soft_aes_ctx->key_sched); 636 637 goto clean1; 638 } 639 640 out_len = AES_BLOCK_LEN; 641 642 /* 643 * If application asks for the length of the output buffer 644 * to hold the plaintext? 645 */ 646 if (pLastPart == NULL) { 647 *pulLastPartLen = out_len; 648 rv = CKR_OK; 649 goto clean2; 650 } else { 651 crypto_data_t out; 652 653 /* Copy remaining data to the output buffer. */ 654 (void) memcpy(pLastPart, soft_aes_ctx->data, 655 AES_BLOCK_LEN); 656 657 out.cd_format = CRYPTO_DATA_RAW; 658 out.cd_offset = 0; 659 out.cd_length = AES_BLOCK_LEN; 660 out.cd_raw.iov_base = (char *)pLastPart; 661 out.cd_raw.iov_len = AES_BLOCK_LEN; 662 663 /* Decrypt final block of data. */ 664 rc = aes_decrypt_contiguous_blocks( 665 (aes_ctx_t *)soft_aes_ctx->aes_cbc, 666 (char *)pLastPart, AES_BLOCK_LEN, &out); 667 668 if (rc == 0) { 669 /* 670 * Remove padding bytes after decryption of 671 * ciphertext block to produce the original 672 * plaintext. 673 */ 674 rv = soft_remove_pkcs7_padding(pLastPart, 675 AES_BLOCK_LEN, &out_len, AES_BLOCK_LEN); 676 if (rv != CKR_OK) 677 *pulLastPartLen = 0; 678 else 679 *pulLastPartLen = out_len; 680 } else { 681 *pulLastPartLen = 0; 682 rv = CKR_FUNCTION_FAILED; 683 } 684 685 /* Cleanup memory space. */ 686 free(soft_aes_ctx->aes_cbc); 687 bzero(soft_aes_ctx->key_sched, 688 soft_aes_ctx->keysched_len); 689 free(soft_aes_ctx->key_sched); 690 691 } 692 693 break; 694 } 695 696 case CKM_AES_CBC: 697 case CKM_AES_ECB: 698 { 699 soft_aes_ctx_t *soft_aes_ctx; 700 701 soft_aes_ctx = (soft_aes_ctx_t *)session_p->decrypt.context; 702 /* 703 * CKM_AES_CBC and CKM_AES_ECB does not do any padding, 704 * so when the final is called, the remaining buffer 705 * should not contain any more data. 706 */ 707 *pulLastPartLen = 0; 708 if (soft_aes_ctx->remain_len != 0) { 709 rv = CKR_ENCRYPTED_DATA_LEN_RANGE; 710 } else { 711 if (pLastPart == NULL) 712 goto clean2; 713 } 714 715 /* Cleanup memory space. */ 716 free(soft_aes_ctx->aes_cbc); 717 bzero(soft_aes_ctx->key_sched, soft_aes_ctx->keysched_len); 718 free(soft_aes_ctx->key_sched); 719 720 break; 721 } 722 723 case CKM_BLOWFISH_CBC: 724 { 725 soft_blowfish_ctx_t *soft_blowfish_ctx; 726 727 soft_blowfish_ctx = 728 (soft_blowfish_ctx_t *)session_p->decrypt.context; 729 730 *pulLastPartLen = 0; 731 if (soft_blowfish_ctx->remain_len != 0) 732 rv = CKR_ENCRYPTED_DATA_LEN_RANGE; 733 else { 734 if (pLastPart == NULL) 735 goto clean2; 736 } 737 738 free(soft_blowfish_ctx->blowfish_cbc); 739 bzero(soft_blowfish_ctx->key_sched, 740 soft_blowfish_ctx->keysched_len); 741 free(soft_blowfish_ctx->key_sched); 742 743 break; 744 } 745 746 case CKM_RC4: 747 { 748 ARCFour_key *key = (ARCFour_key *)session_p->decrypt.context; 749 bzero(key, sizeof (*key)); 750 *pulLastPartLen = 0; 751 break; 752 } 753 754 default: 755 /* PKCS11: The mechanism only supports single-part operation. */ 756 rv = CKR_MECHANISM_INVALID; 757 break; 758 } 759 760clean1: 761 free(session_p->decrypt.context); 762 session_p->decrypt.context = NULL; 763 764clean2: 765 (void) pthread_mutex_unlock(&session_p->session_mutex); 766 767 return (rv); 768 769} 770