1f66d273dSizick /* 24c21f043Sizick * CDDL HEADER START 34c21f043Sizick * 44c21f043Sizick * The contents of this file are subject to the terms of the 54c21f043Sizick * Common Development and Distribution License (the "License"). 64c21f043Sizick * You may not use this file except in compliance with the License. 74c21f043Sizick * 84c21f043Sizick * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 94c21f043Sizick * or http://www.opensolaris.org/os/licensing. 104c21f043Sizick * See the License for the specific language governing permissions 114c21f043Sizick * and limitations under the License. 124c21f043Sizick * 134c21f043Sizick * When distributing Covered Code, include this CDDL HEADER in each 144c21f043Sizick * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 154c21f043Sizick * If applicable, add the following below this CDDL HEADER, with the 164c21f043Sizick * fields enclosed by brackets "[]" replaced with your own identifying 174c21f043Sizick * information: Portions Copyright [yyyy] [name of copyright owner] 184c21f043Sizick * 194c21f043Sizick * CDDL HEADER END 204c21f043Sizick */ 214c21f043Sizick /* 229627968bSmcpowers * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 23f66d273dSizick * Use is subject to license terms. 24f66d273dSizick */ 25f66d273dSizick 26f66d273dSizick #include <pthread.h> 27f66d273dSizick #include <stdlib.h> 28f66d273dSizick #include <string.h> 29f66d273dSizick #include <strings.h> 30f66d273dSizick #include <sys/types.h> 31f66d273dSizick #include <security/cryptoki.h> 32f66d273dSizick #include "softSession.h" 33f66d273dSizick #include "softObject.h" 34f66d273dSizick #include "softCrypt.h" 3523c57df7Smcpowers #include <blowfish_impl.h> 36f66d273dSizick 37f66d273dSizick CK_RV 38f66d273dSizick soft_blowfish_crypt_init_common(soft_session_t *session_p, 39f66d273dSizick CK_MECHANISM_PTR pMechanism, soft_object_t *key_p, boolean_t encrypt) { 40f66d273dSizick 41f66d273dSizick size_t size; 42f66d273dSizick soft_blowfish_ctx_t *soft_blowfish_ctx; 43f66d273dSizick 44f66d273dSizick soft_blowfish_ctx = calloc(1, sizeof (soft_blowfish_ctx_t)); 45f66d273dSizick if (soft_blowfish_ctx == NULL) { 46f66d273dSizick return (CKR_HOST_MEMORY); 47f66d273dSizick } 48f66d273dSizick 49f66d273dSizick soft_blowfish_ctx->key_sched = blowfish_alloc_keysched(&size, 0); 50f66d273dSizick 51f66d273dSizick if (soft_blowfish_ctx->key_sched == NULL) { 52f66d273dSizick free(soft_blowfish_ctx); 53f66d273dSizick return (CKR_HOST_MEMORY); 54f66d273dSizick } 55f66d273dSizick 56f66d273dSizick soft_blowfish_ctx->keysched_len = size; 57f66d273dSizick 58f66d273dSizick (void) pthread_mutex_lock(&session_p->session_mutex); 59f66d273dSizick if (encrypt) { 60f66d273dSizick /* Called by C_EncryptInit */ 61f66d273dSizick session_p->encrypt.context = soft_blowfish_ctx; 62f66d273dSizick session_p->encrypt.mech.mechanism = pMechanism->mechanism; 63f66d273dSizick } else { 64f66d273dSizick /* Called by C_DecryptInit */ 65f66d273dSizick session_p->decrypt.context = soft_blowfish_ctx; 66f66d273dSizick session_p->decrypt.mech.mechanism = pMechanism->mechanism; 67f66d273dSizick } 68f66d273dSizick (void) pthread_mutex_unlock(&session_p->session_mutex); 69f66d273dSizick 70f66d273dSizick /* 71f66d273dSizick * If this is a non-sensitive key and it does NOT have 72f66d273dSizick * a key schedule yet, then allocate one and expand it. 73f66d273dSizick * Otherwise, if it's a non-sensitive key, and it DOES have 74f66d273dSizick * a key schedule already attached to it, just copy the 75f66d273dSizick * pre-expanded schedule to the context and avoid the 76f66d273dSizick * extra key schedule expansion operation. 77f66d273dSizick */ 78f66d273dSizick if (!(key_p->bool_attr_mask & SENSITIVE_BOOL_ON)) { 799627968bSmcpowers if (OBJ_KEY_SCHED(key_p) == NULL) { 80f66d273dSizick void *ks; 819627968bSmcpowers 829627968bSmcpowers (void) pthread_mutex_lock(&key_p->object_mutex); 839627968bSmcpowers if (OBJ_KEY_SCHED(key_p) == NULL) { 84f66d273dSizick ks = blowfish_alloc_keysched(&size, 0); 85f66d273dSizick if (ks == NULL) { 869627968bSmcpowers (void) pthread_mutex_unlock( 879627968bSmcpowers &key_p->object_mutex); 88f66d273dSizick free(soft_blowfish_ctx); 89f66d273dSizick return (CKR_HOST_MEMORY); 90f66d273dSizick } 91f66d273dSizick 92f66d273dSizick blowfish_init_keysched(OBJ_SEC_VALUE(key_p), 939627968bSmcpowers (OBJ_SEC_VALUE_LEN(key_p) * 8), ks); 949627968bSmcpowers 959627968bSmcpowers OBJ_KEY_SCHED_LEN(key_p) = size; 969627968bSmcpowers OBJ_KEY_SCHED(key_p) = ks; 979627968bSmcpowers } 989627968bSmcpowers (void) pthread_mutex_unlock(&key_p->object_mutex); 99f66d273dSizick } 100f66d273dSizick (void) memcpy(soft_blowfish_ctx->key_sched, 101f66d273dSizick OBJ_KEY_SCHED(key_p), OBJ_KEY_SCHED_LEN(key_p)); 102f66d273dSizick soft_blowfish_ctx->keysched_len = OBJ_KEY_SCHED_LEN(key_p); 103f66d273dSizick 104f66d273dSizick } else { 105f66d273dSizick /* 106f66d273dSizick * Initialize key schedule for Blowfish. 107f66d273dSizick * blowfish_init_keysched() requires key length in bits. 108f66d273dSizick */ 109f66d273dSizick blowfish_init_keysched(OBJ_SEC_VALUE(key_p), 110f66d273dSizick (OBJ_SEC_VALUE_LEN(key_p) * 8), 111f66d273dSizick soft_blowfish_ctx->key_sched); 112f66d273dSizick } 113f66d273dSizick return (CKR_OK); 114f66d273dSizick } 115f66d273dSizick 116f66d273dSizick 117f66d273dSizick /* 118f66d273dSizick * soft_blowfish_encrypt_common() 119f66d273dSizick * 120f66d273dSizick * Arguments: 121f66d273dSizick * session_p: pointer to soft_session_t struct 122f66d273dSizick * pData: pointer to the input data to be encrypted 123f66d273dSizick * ulDataLen: length of the input data 124f66d273dSizick * pEncrypted: pointer to the output data after encryption 125f66d273dSizick * pulEncryptedLen: pointer to the length of the output data 126f66d273dSizick * update: boolean flag indicates caller is soft_encrypt 127f66d273dSizick * or soft_encrypt_update 128f66d273dSizick * 129f66d273dSizick * Description: 130f66d273dSizick * This function calls the corresponding encrypt routine based 131f66d273dSizick * on the mechanism. 132f66d273dSizick * 133f66d273dSizick * Returns: 134f66d273dSizick * CKR_OK: success 135f66d273dSizick * CKR_BUFFER_TOO_SMALL: the output buffer provided by application 136f66d273dSizick * is too small 137f66d273dSizick * CKR_FUNCTION_FAILED: encrypt function failed 138f66d273dSizick * CKR_DATA_LEN_RANGE: the input data is not a multiple of blocksize 139f66d273dSizick */ 140f66d273dSizick CK_RV 141f66d273dSizick soft_blowfish_encrypt_common(soft_session_t *session_p, CK_BYTE_PTR pData, 142f66d273dSizick CK_ULONG ulDataLen, CK_BYTE_PTR pEncrypted, CK_ULONG_PTR pulEncryptedLen, 143f66d273dSizick boolean_t update) { 144f66d273dSizick 145f66d273dSizick int rc = 0; 146f66d273dSizick CK_RV rv = CKR_OK; 147f66d273dSizick soft_blowfish_ctx_t *soft_blowfish_ctx = 148f66d273dSizick (soft_blowfish_ctx_t *)session_p->encrypt.context; 149f66d273dSizick blowfish_ctx_t *blowfish_ctx; 150f66d273dSizick CK_BYTE *in_buf = NULL; 151f66d273dSizick CK_BYTE *out_buf = NULL; 152f66d273dSizick CK_ULONG out_len; 153f66d273dSizick CK_ULONG total_len; 154f66d273dSizick CK_ULONG remain; 155f66d273dSizick crypto_data_t out; 156f66d273dSizick 157f66d273dSizick /* 158f66d273dSizick * Blowfish only takes input length that is a multiple of blocksize 159f66d273dSizick * for C_Encrypt function with the mechanism CKM_BLOWFISH_CBC. 160f66d273dSizick * 161f66d273dSizick */ 162f66d273dSizick if (!update) { 163f66d273dSizick if ((ulDataLen % BLOWFISH_BLOCK_LEN) != 0) { 164f66d273dSizick rv = CKR_DATA_LEN_RANGE; 165f66d273dSizick goto cleanup; 166f66d273dSizick } 167f66d273dSizick 168f66d273dSizick out_len = ulDataLen; 169f66d273dSizick /* 170f66d273dSizick * If application asks for the length of the output buffer 171f66d273dSizick * to hold the ciphertext? 172f66d273dSizick */ 173f66d273dSizick if (pEncrypted == NULL) { 174f66d273dSizick *pulEncryptedLen = out_len; 175f66d273dSizick return (CKR_OK); 176f66d273dSizick } 177f66d273dSizick 178f66d273dSizick /* Is the application-supplied buffer large enough? */ 179f66d273dSizick if (*pulEncryptedLen < out_len) { 180f66d273dSizick *pulEncryptedLen = out_len; 181f66d273dSizick return (CKR_BUFFER_TOO_SMALL); 182f66d273dSizick } 183f66d273dSizick 184f66d273dSizick in_buf = pData; 185f66d273dSizick out_buf = pEncrypted; 186f66d273dSizick } else { 187f66d273dSizick /* 188f66d273dSizick * Called by C_EncryptUpdate 189f66d273dSizick * 190f66d273dSizick * Add the lengths of last remaining data and current 191f66d273dSizick * plaintext together to get the total input length. 192f66d273dSizick */ 193f66d273dSizick total_len = soft_blowfish_ctx->remain_len + ulDataLen; 194f66d273dSizick 195f66d273dSizick /* 196f66d273dSizick * If the total input length is less than one blocksize, 197f66d273dSizick * we will need to delay encryption until when more data 198f66d273dSizick * comes in next C_EncryptUpdate or when C_EncryptFinal 199f66d273dSizick * is called. 200f66d273dSizick */ 201f66d273dSizick if (total_len < BLOWFISH_BLOCK_LEN) { 202f66d273dSizick if (pEncrypted != NULL) { 203f66d273dSizick /* 204f66d273dSizick * Save input data and its length in 205f66d273dSizick * the remaining buffer of BLOWFISH context. 206f66d273dSizick */ 207f66d273dSizick (void) memcpy(soft_blowfish_ctx->data + 208f66d273dSizick soft_blowfish_ctx->remain_len, pData, 209f66d273dSizick ulDataLen); 210f66d273dSizick soft_blowfish_ctx->remain_len += ulDataLen; 211f66d273dSizick } 212f66d273dSizick 213f66d273dSizick /* Set encrypted data length to 0. */ 214f66d273dSizick *pulEncryptedLen = 0; 215f66d273dSizick return (CKR_OK); 216f66d273dSizick } 217f66d273dSizick 218f66d273dSizick /* Compute the length of remaing data. */ 219f66d273dSizick remain = total_len % BLOWFISH_BLOCK_LEN; 220f66d273dSizick 221f66d273dSizick /* 222f66d273dSizick * Make sure that the output length is a multiple of 223f66d273dSizick * blocksize. 224f66d273dSizick */ 225f66d273dSizick out_len = total_len - remain; 226f66d273dSizick 227f66d273dSizick /* 228f66d273dSizick * If application asks for the length of the output buffer 229f66d273dSizick * to hold the ciphertext? 230f66d273dSizick */ 231f66d273dSizick if (pEncrypted == NULL) { 232f66d273dSizick *pulEncryptedLen = out_len; 233f66d273dSizick return (CKR_OK); 234f66d273dSizick } 235f66d273dSizick 236f66d273dSizick /* Is the application-supplied buffer large enough? */ 237f66d273dSizick if (*pulEncryptedLen < out_len) { 238f66d273dSizick *pulEncryptedLen = out_len; 239f66d273dSizick return (CKR_BUFFER_TOO_SMALL); 240f66d273dSizick } 241f66d273dSizick 242f66d273dSizick if (soft_blowfish_ctx->remain_len != 0) { 243f66d273dSizick /* 244f66d273dSizick * Copy last remaining data and current input data 245f66d273dSizick * to the output buffer. 246f66d273dSizick */ 247f66d273dSizick (void) memmove(pEncrypted + 248f66d273dSizick soft_blowfish_ctx->remain_len, 249f66d273dSizick pData, out_len - soft_blowfish_ctx->remain_len); 250f66d273dSizick (void) memcpy(pEncrypted, soft_blowfish_ctx->data, 251f66d273dSizick soft_blowfish_ctx->remain_len); 252f66d273dSizick bzero(soft_blowfish_ctx->data, 253f66d273dSizick soft_blowfish_ctx->remain_len); 254f66d273dSizick 255f66d273dSizick in_buf = pEncrypted; 256f66d273dSizick } else { 257f66d273dSizick in_buf = pData; 258f66d273dSizick } 259f66d273dSizick out_buf = pEncrypted; 260f66d273dSizick } 261f66d273dSizick 262f66d273dSizick /* 263f66d273dSizick * Begin Encryption now. 264f66d273dSizick */ 265f66d273dSizick 266f66d273dSizick out.cd_format = CRYPTO_DATA_RAW; 267f66d273dSizick out.cd_offset = 0; 268f66d273dSizick out.cd_length = out_len; 269f66d273dSizick out.cd_raw.iov_base = (char *)out_buf; 270f66d273dSizick out.cd_raw.iov_len = out_len; 271f66d273dSizick 272f66d273dSizick /* Encrypt multiple blocks of data. */ 273f66d273dSizick rc = blowfish_encrypt_contiguous_blocks( 274f66d273dSizick (blowfish_ctx_t *)soft_blowfish_ctx->blowfish_cbc, 275f66d273dSizick (char *)in_buf, out_len, &out); 276f66d273dSizick 277f66d273dSizick if (rc == 0) { 278f66d273dSizick *pulEncryptedLen = out_len; 279f66d273dSizick if (update) { 280f66d273dSizick /* 281f66d273dSizick * For encrypt update, if there is remaining data, 282f66d273dSizick * save it and it's length in the context. 283f66d273dSizick */ 284f66d273dSizick if (remain != 0) 285f66d273dSizick (void) memcpy(soft_blowfish_ctx->data, pData + 286f66d273dSizick (ulDataLen - remain), remain); 287f66d273dSizick 288f66d273dSizick soft_blowfish_ctx->remain_len = remain; 289f66d273dSizick return (CKR_OK); 290f66d273dSizick } 291f66d273dSizick 2924c21f043Sizick } else { 293f66d273dSizick *pulEncryptedLen = 0; 294f66d273dSizick rv = CKR_FUNCTION_FAILED; 2954c21f043Sizick } 296f66d273dSizick 297f66d273dSizick cleanup: 298f66d273dSizick (void) pthread_mutex_lock(&session_p->session_mutex); 299f66d273dSizick blowfish_ctx = (blowfish_ctx_t *)soft_blowfish_ctx->blowfish_cbc; 300f66d273dSizick if (blowfish_ctx != NULL) { 301f66d273dSizick bzero(blowfish_ctx->bc_keysched, 302f66d273dSizick blowfish_ctx->bc_keysched_len); 303f66d273dSizick free(soft_blowfish_ctx->blowfish_cbc); 304f66d273dSizick } 305f66d273dSizick 306f66d273dSizick bzero(soft_blowfish_ctx->key_sched, soft_blowfish_ctx->keysched_len); 307f66d273dSizick free(soft_blowfish_ctx->key_sched); 308f66d273dSizick free(session_p->encrypt.context); 309f66d273dSizick session_p->encrypt.context = NULL; 310f66d273dSizick (void) pthread_mutex_unlock(&session_p->session_mutex); 311f66d273dSizick 312f66d273dSizick return (rv); 313f66d273dSizick } 314f66d273dSizick 315f66d273dSizick 316f66d273dSizick CK_RV 317f66d273dSizick soft_blowfish_decrypt_common(soft_session_t *session_p, CK_BYTE_PTR pEncrypted, 318f66d273dSizick CK_ULONG ulEncryptedLen, CK_BYTE_PTR pData, CK_ULONG_PTR pulDataLen, 319f66d273dSizick boolean_t update) { 320f66d273dSizick 321f66d273dSizick int rc = 0; 322f66d273dSizick CK_RV rv = CKR_OK; 323f66d273dSizick soft_blowfish_ctx_t *soft_blowfish_ctx = 324f66d273dSizick (soft_blowfish_ctx_t *)session_p->decrypt.context; 325f66d273dSizick blowfish_ctx_t *blowfish_ctx; 326f66d273dSizick CK_BYTE *in_buf = NULL; 327f66d273dSizick CK_BYTE *out_buf = NULL; 328f66d273dSizick CK_ULONG out_len; 329f66d273dSizick CK_ULONG total_len; 330f66d273dSizick CK_ULONG remain; 331f66d273dSizick crypto_data_t out; 332f66d273dSizick 333f66d273dSizick /* 334f66d273dSizick * Blowfish only takes input length that is a multiple of 16 bytes 335f66d273dSizick * for C_Decrypt function using CKM_BLOWFISH_CBC. 336f66d273dSizick */ 337f66d273dSizick 338f66d273dSizick if (!update) { 339f66d273dSizick /* Called by C_Decrypt */ 340f66d273dSizick if ((ulEncryptedLen % BLOWFISH_BLOCK_LEN) != 0) { 341f66d273dSizick rv = CKR_ENCRYPTED_DATA_LEN_RANGE; 342f66d273dSizick goto cleanup; 343f66d273dSizick } 344f66d273dSizick 345f66d273dSizick /* 3464c21f043Sizick * If application asks for the length of the output buffer 347f66d273dSizick * to hold the plaintext? 348f66d273dSizick */ 349f66d273dSizick if (pData == NULL) { 350f66d273dSizick *pulDataLen = ulEncryptedLen; 351f66d273dSizick return (CKR_OK); 352f66d273dSizick } 353f66d273dSizick 354f66d273dSizick /* Is the application-supplied buffer large enough? */ 355f66d273dSizick if (*pulDataLen < ulEncryptedLen) { 356f66d273dSizick *pulDataLen = ulEncryptedLen; 357f66d273dSizick return (CKR_BUFFER_TOO_SMALL); 358f66d273dSizick } 359f66d273dSizick out_len = ulEncryptedLen; 360f66d273dSizick in_buf = pEncrypted; 361f66d273dSizick out_buf = pData; 362f66d273dSizick } else { 363f66d273dSizick /* 364f66d273dSizick * Called by C_DecryptUpdate 365f66d273dSizick * 366f66d273dSizick * Add the lengths of last remaining data and current 367f66d273dSizick * input data together to get the total input length. 368f66d273dSizick */ 369f66d273dSizick total_len = soft_blowfish_ctx->remain_len + ulEncryptedLen; 370f66d273dSizick 371f66d273dSizick if (total_len < BLOWFISH_BLOCK_LEN) { 372f66d273dSizick if (pData != NULL) { 373f66d273dSizick (void) memcpy(soft_blowfish_ctx->data + 374f66d273dSizick soft_blowfish_ctx->remain_len, 375f66d273dSizick pEncrypted, ulEncryptedLen); 376f66d273dSizick 377f66d273dSizick soft_blowfish_ctx->remain_len += ulEncryptedLen; 378f66d273dSizick } 379f66d273dSizick 380f66d273dSizick /* Set output data length to 0. */ 381f66d273dSizick *pulDataLen = 0; 382f66d273dSizick return (CKR_OK); 383f66d273dSizick } 384f66d273dSizick 385f66d273dSizick /* Compute the length of remaining data. */ 386f66d273dSizick remain = total_len % BLOWFISH_BLOCK_LEN; 387f66d273dSizick 388f66d273dSizick /* 389f66d273dSizick * Make sure that the output length is a multiple of 390f66d273dSizick * blocksize. 391f66d273dSizick */ 392f66d273dSizick out_len = total_len - remain; 393f66d273dSizick 394f66d273dSizick /* 395f66d273dSizick * if application asks for the length of the output buffer 396f66d273dSizick * to hold the plaintext? 397f66d273dSizick */ 398f66d273dSizick if (pData == NULL) { 399f66d273dSizick *pulDataLen = out_len; 400f66d273dSizick return (CKR_OK); 401f66d273dSizick } 402f66d273dSizick 403f66d273dSizick /* 404f66d273dSizick * Is the application-supplied buffer large enough? 405f66d273dSizick */ 406f66d273dSizick if (*pulDataLen < out_len) { 407f66d273dSizick *pulDataLen = out_len; 408f66d273dSizick return (CKR_BUFFER_TOO_SMALL); 409f66d273dSizick } 410f66d273dSizick 411f66d273dSizick if (soft_blowfish_ctx->remain_len != 0) { 412f66d273dSizick /* 413f66d273dSizick * Copy last remaining data and current input data 414f66d273dSizick * to the output buffer. 415f66d273dSizick */ 416f66d273dSizick (void) memmove(pData + soft_blowfish_ctx->remain_len, 417f66d273dSizick pEncrypted, 418f66d273dSizick out_len - soft_blowfish_ctx->remain_len); 419f66d273dSizick (void) memcpy(pData, soft_blowfish_ctx->data, 420f66d273dSizick soft_blowfish_ctx->remain_len); 421f66d273dSizick bzero(soft_blowfish_ctx->data, 422f66d273dSizick soft_blowfish_ctx->remain_len); 423f66d273dSizick 424f66d273dSizick 425f66d273dSizick in_buf = pData; 426f66d273dSizick } else { 427f66d273dSizick in_buf = pEncrypted; 428f66d273dSizick } 429f66d273dSizick 430f66d273dSizick out_buf = pData; 431f66d273dSizick } 432f66d273dSizick 433f66d273dSizick out.cd_format = CRYPTO_DATA_RAW; 434f66d273dSizick out.cd_offset = 0; 435f66d273dSizick out.cd_length = out_len; 436f66d273dSizick out.cd_raw.iov_base = (char *)out_buf; 437f66d273dSizick out.cd_raw.iov_len = out_len; 438f66d273dSizick 439f66d273dSizick /* Decrypt multiple blocks of data. */ 440f66d273dSizick rc = blowfish_decrypt_contiguous_blocks( 441f66d273dSizick (blowfish_ctx_t *)soft_blowfish_ctx->blowfish_cbc, 442f66d273dSizick (char *)in_buf, out_len, &out); 443f66d273dSizick 444f66d273dSizick if (rc == 0) { 445f66d273dSizick *pulDataLen = out_len; 446f66d273dSizick if (update) { 447f66d273dSizick /* 448f66d273dSizick * For decrypt update, if there is remaining data, 449f66d273dSizick * save it and its length in the context. 450f66d273dSizick */ 451f66d273dSizick if (remain != 0) 452f66d273dSizick (void) memcpy(soft_blowfish_ctx->data, 453f66d273dSizick pEncrypted + (ulEncryptedLen - remain), 454f66d273dSizick remain); 455f66d273dSizick soft_blowfish_ctx->remain_len = remain; 456f66d273dSizick return (CKR_OK); 457f66d273dSizick } 458f66d273dSizick 459f66d273dSizick 460f66d273dSizick } else { 461f66d273dSizick *pulDataLen = 0; 462f66d273dSizick rv = CKR_FUNCTION_FAILED; 463f66d273dSizick } 464f66d273dSizick 465f66d273dSizick cleanup: 466f66d273dSizick (void) pthread_mutex_lock(&session_p->session_mutex); 467f66d273dSizick blowfish_ctx = (blowfish_ctx_t *)soft_blowfish_ctx->blowfish_cbc; 468f66d273dSizick if (blowfish_ctx != NULL) { 469f66d273dSizick bzero(blowfish_ctx->bc_keysched, 470f66d273dSizick blowfish_ctx->bc_keysched_len); 471f66d273dSizick free(soft_blowfish_ctx->blowfish_cbc); 472f66d273dSizick } 473f66d273dSizick 474f66d273dSizick bzero(soft_blowfish_ctx->key_sched, soft_blowfish_ctx->keysched_len); 475f66d273dSizick free(soft_blowfish_ctx->key_sched); 476f66d273dSizick free(session_p->decrypt.context); 477f66d273dSizick session_p->decrypt.context = NULL; 478f66d273dSizick (void) pthread_mutex_unlock(&session_p->session_mutex); 479f66d273dSizick 480f66d273dSizick return (rv); 481f66d273dSizick } 482f66d273dSizick 483f66d273dSizick /* 484f66d273dSizick * Allocate and initialize a context for BLOWFISH CBC mode of operation. 485f66d273dSizick */ 486f66d273dSizick 487f66d273dSizick void * 488f66d273dSizick blowfish_cbc_ctx_init(void *key_sched, size_t size, uint8_t *ivec) 489f66d273dSizick { 490f66d273dSizick 49123c57df7Smcpowers cbc_ctx_t *cbc_ctx; 492f66d273dSizick 49323c57df7Smcpowers if ((cbc_ctx = calloc(1, sizeof (cbc_ctx_t))) == NULL) 494f66d273dSizick return (NULL); 495f66d273dSizick 496*16239bc8SMark Powers cbc_ctx->cbc_keysched = key_sched; 497f66d273dSizick 498*16239bc8SMark Powers (void) memcpy(&cbc_ctx->cbc_iv[0], ivec, BLOWFISH_BLOCK_LEN); 499f66d273dSizick 500*16239bc8SMark Powers cbc_ctx->cbc_lastp = (uint8_t *)&(cbc_ctx->cbc_iv); 501*16239bc8SMark Powers cbc_ctx->cbc_keysched_len = size; 502*16239bc8SMark Powers cbc_ctx->cbc_flags |= CBC_MODE; 503f66d273dSizick 50423c57df7Smcpowers return (cbc_ctx); 505f66d273dSizick } 506