1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
  24  * Copyright 2014 Nexenta Systems, Inc.  All rights reserved.
  25  */
  26 
  27 #include <pthread.h>
  28 #include <stdlib.h>
  29 #include <string.h>
  30 #include <strings.h>
  31 #include <sys/types.h>
  32 #include <security/cryptoki.h>
  33 #include <aes_impl.h>
  34 #include "softSession.h"
  35 #include "softObject.h"
  36 #include "softCrypt.h"
  37 #include "softOps.h"
  38 
  39 /*
  40  * Allocate context for the active encryption or decryption operation, and
  41  * generate AES key schedule to speed up the operation.
  42  */
  43 CK_RV
  44 soft_aes_crypt_init_common(soft_session_t *session_p,
  45     CK_MECHANISM_PTR pMechanism, soft_object_t *key_p,
  46     boolean_t encrypt)
  47 {
  48         size_t size;
  49         soft_aes_ctx_t *soft_aes_ctx;
  50 
  51         soft_aes_ctx = calloc(1, sizeof (soft_aes_ctx_t));
  52         if (soft_aes_ctx == NULL) {
  53                 return (CKR_HOST_MEMORY);
  54         }
  55 
  56         soft_aes_ctx->key_sched = aes_alloc_keysched(&size, 0);
  57 
  58         if (soft_aes_ctx->key_sched == NULL) {
  59                 free(soft_aes_ctx);
  60                 return (CKR_HOST_MEMORY);
  61         }
  62 
  63         soft_aes_ctx->keysched_len = size;
  64 
  65         (void) pthread_mutex_lock(&session_p->session_mutex);
  66         if (encrypt) {
  67                 /* Called by C_EncryptInit. */
  68                 session_p->encrypt.context = soft_aes_ctx;
  69                 session_p->encrypt.mech.mechanism = pMechanism->mechanism;
  70         } else {
  71                 /* Called by C_DecryptInit. */
  72                 session_p->decrypt.context = soft_aes_ctx;
  73                 session_p->decrypt.mech.mechanism = pMechanism->mechanism;
  74         }
  75         (void) pthread_mutex_unlock(&session_p->session_mutex);
  76 
  77         /*
  78          * If this is a non-sensitive key and it does NOT have
  79          * a key schedule yet, then allocate one and expand it.
  80          * Otherwise, if it's a non-sensitive key, and it DOES have
  81          * a key schedule already attached to it, just copy the
  82          * pre-expanded schedule to the context and avoid the
  83          * extra key schedule expansion operation.
  84          */
  85         if (!(key_p->bool_attr_mask & SENSITIVE_BOOL_ON)) {
  86                 if (OBJ_KEY_SCHED(key_p) == NULL) {
  87                         void *ks;
  88 
  89                         (void) pthread_mutex_lock(&key_p->object_mutex);
  90                         if (OBJ_KEY_SCHED(key_p) == NULL) {
  91                                 ks = aes_alloc_keysched(&size, 0);
  92                                 if (ks == NULL) {
  93                                         (void) pthread_mutex_unlock(
  94                                             &key_p->object_mutex);
  95                                         free(soft_aes_ctx);
  96                                         return (CKR_HOST_MEMORY);
  97                                 }
  98 #ifdef  __sparcv9
  99                                 /* LINTED */
 100                                 aes_init_keysched(OBJ_SEC_VALUE(key_p), (uint_t)
 101                                     (OBJ_SEC_VALUE_LEN(key_p) * 8), ks);
 102 #else   /* !__sparcv9 */
 103                                 aes_init_keysched(OBJ_SEC_VALUE(key_p),
 104                                     (OBJ_SEC_VALUE_LEN(key_p) * 8), ks);
 105 #endif  /* __sparcv9 */
 106                                 OBJ_KEY_SCHED_LEN(key_p) = size;
 107                                 OBJ_KEY_SCHED(key_p) = ks;
 108                         }
 109                         (void) pthread_mutex_unlock(&key_p->object_mutex);
 110                 }
 111                 (void) memcpy(soft_aes_ctx->key_sched, OBJ_KEY_SCHED(key_p),
 112                     OBJ_KEY_SCHED_LEN(key_p));
 113                 soft_aes_ctx->keysched_len = OBJ_KEY_SCHED_LEN(key_p);
 114         } else {
 115                 /*
 116                  * Initialize key schedule for AES. aes_init_keysched()
 117                  * requires key length in bits.
 118                  */
 119 #ifdef  __sparcv9
 120                 /* LINTED */
 121                 aes_init_keysched(OBJ_SEC_VALUE(key_p), (uint_t)
 122                     (OBJ_SEC_VALUE_LEN(key_p) * 8), soft_aes_ctx->key_sched);
 123 #else   /* !__sparcv9 */
 124                 aes_init_keysched(OBJ_SEC_VALUE(key_p),
 125                     (OBJ_SEC_VALUE_LEN(key_p) * 8), soft_aes_ctx->key_sched);
 126 #endif  /* __sparcv9 */
 127         }
 128         return (CKR_OK);
 129 }
 130 
 131 
 132 /*
 133  * soft_aes_encrypt_common()
 134  *
 135  * Arguments:
 136  *      session_p:      pointer to soft_session_t struct
 137  *      pData:          pointer to the input data to be encrypted
 138  *      ulDataLen:      length of the input data
 139  *      pEncrypted:     pointer to the output data after encryption
 140  *      pulEncryptedLen: pointer to the length of the output data
 141  *      update:         boolean flag indicates caller is soft_encrypt
 142  *                      or soft_encrypt_update
 143  *
 144  * Description:
 145  *      This function calls the corresponding encrypt routine based
 146  *      on the mechanism.
 147  *
 148  * Returns:
 149  *      CKR_OK: success
 150  *      CKR_BUFFER_TOO_SMALL: the output buffer provided by application
 151  *                            is too small
 152  *      CKR_FUNCTION_FAILED: encrypt function failed
 153  *      CKR_DATA_LEN_RANGE: the input data is not a multiple of blocksize
 154  */
 155 CK_RV
 156 soft_aes_encrypt_common(soft_session_t *session_p, CK_BYTE_PTR pData,
 157     CK_ULONG ulDataLen, CK_BYTE_PTR pEncrypted,
 158     CK_ULONG_PTR pulEncryptedLen, boolean_t update)
 159 {
 160 
 161         int rc = 0;
 162         CK_RV rv = CKR_OK;
 163         soft_aes_ctx_t *soft_aes_ctx =
 164             (soft_aes_ctx_t *)session_p->encrypt.context;
 165         aes_ctx_t *aes_ctx;
 166         CK_MECHANISM_TYPE mechanism = session_p->encrypt.mech.mechanism;
 167         CK_BYTE *in_buf = NULL;
 168         CK_BYTE *out_buf = NULL;
 169         CK_ULONG out_len;
 170         CK_ULONG total_len;
 171         CK_ULONG remain;
 172 
 173         if (mechanism == CKM_AES_CTR)
 174                 goto do_encryption;
 175 
 176         /*
 177          * AES only takes input length that is a multiple of blocksize
 178          * for C_Encrypt function with the mechanism CKM_AES_ECB or
 179          * CKM_AES_CBC.
 180          *
 181          * AES allows any input length for C_Encrypt function with the
 182          * mechanism CKM_AES_CBC_PAD and for C_EncryptUpdate function.
 183          */
 184         if ((!update) && (mechanism != CKM_AES_CBC_PAD) &&
 185             (mechanism != CKM_AES_CMAC)) {
 186                 if ((ulDataLen % AES_BLOCK_LEN) != 0) {
 187                         rv = CKR_DATA_LEN_RANGE;
 188                         goto cleanup;
 189                 }
 190         }
 191 
 192         if (!update) {
 193                 /*
 194                  * Called by C_Encrypt
 195                  */
 196                 if (mechanism == CKM_AES_CBC_PAD) {
 197                         /*
 198                          * For CKM_AES_CBC_PAD, compute output length to
 199                          * count for the padding. If the length of input
 200                          * data is a multiple of blocksize, then make output
 201                          * length to be the sum of the input length and
 202                          * one blocksize. Otherwise, output length will
 203                          * be rounded up to the next multiple of blocksize.
 204                          */
 205                         out_len = AES_BLOCK_LEN *
 206                             (ulDataLen / AES_BLOCK_LEN + 1);
 207                 } else if (mechanism == CKM_AES_CMAC) {
 208                         out_len = AES_BLOCK_LEN;
 209                 } else {
 210                         /*
 211                          * For non-padding mode, the output length will
 212                          * be same as the input length.
 213                          */
 214                         out_len = ulDataLen;
 215                 }
 216 
 217                 /*
 218                  * If application asks for the length of the output buffer
 219                  * to hold the ciphertext?
 220                  */
 221                 if (pEncrypted == NULL) {
 222                         *pulEncryptedLen = out_len;
 223                         return (CKR_OK);
 224                 }
 225 
 226                 /* Is the application-supplied buffer large enough? */
 227                 if (*pulEncryptedLen < out_len) {
 228                         *pulEncryptedLen = out_len;
 229                         return (CKR_BUFFER_TOO_SMALL);
 230                 }
 231 
 232                 /* Encrypt pad bytes in a separate operation */
 233                 if (mechanism == CKM_AES_CBC_PAD) {
 234                         out_len -= AES_BLOCK_LEN;
 235                 }
 236 
 237                 in_buf = pData;
 238                 out_buf = pEncrypted;
 239         } else {
 240                 /*
 241                  * Called by C_EncryptUpdate
 242                  *
 243                  * Add the lengths of last remaining data and current
 244                  * plaintext together to get the total input length.
 245                  */
 246                 total_len = soft_aes_ctx->remain_len + ulDataLen;
 247 
 248                 /*
 249                  * If the total input length is less than one blocksize,
 250                  * or if the total input length is just one blocksize and
 251                  * the mechanism is CKM_AES_CBC_PAD, we will need to delay
 252                  * encryption until when more data comes in next
 253                  * C_EncryptUpdate or when C_EncryptFinal is called.
 254                  */
 255                 out_buf = pEncrypted;
 256 
 257                 /*
 258                  * We prefer to let the underlying implementation of CMAC handle
 259                  * the storing of extra bytes, and no data is output until
 260                  * *_final, so skip that part of the following validation.
 261                  */
 262                 if (mechanism == CKM_AES_CMAC) {
 263                         if (pEncrypted == NULL) {
 264                                 *pulEncryptedLen = ulDataLen;
 265                                 return (CKR_OK);
 266                         }
 267 
 268                         remain = 0;
 269                         in_buf = pData;
 270                         goto do_encryption;
 271                 }
 272 
 273                 if ((total_len < AES_BLOCK_LEN) ||
 274                     ((mechanism == CKM_AES_CBC_PAD) &&
 275                     (total_len == AES_BLOCK_LEN))) {
 276                         if (pEncrypted != NULL) {
 277                                 /*
 278                                  * Save input data and its length in
 279                                  * the remaining buffer of AES context.
 280                                  */
 281                                 (void) memcpy(soft_aes_ctx->data +
 282                                     soft_aes_ctx->remain_len, pData, ulDataLen);
 283                                 soft_aes_ctx->remain_len += ulDataLen;
 284                         }
 285 
 286                         /* Set encrypted data length to 0. */
 287                         *pulEncryptedLen = 0;
 288                         return (CKR_OK);
 289                 }
 290 
 291                 /* Compute the length of remaing data. */
 292                 remain = total_len % AES_BLOCK_LEN;
 293 
 294                 /*
 295                  * Make sure that the output length is a multiple of
 296                  * blocksize.
 297                  */
 298                 out_len = total_len - remain;
 299 
 300                 /*
 301                  * If application asks for the length of the output buffer
 302                  * to hold the ciphertext?
 303                  */
 304                 if (pEncrypted == NULL) {
 305                         *pulEncryptedLen = out_len;
 306                         return (CKR_OK);
 307                 }
 308 
 309                 /* Is the application-supplied buffer large enough? */
 310                 if (*pulEncryptedLen < out_len) {
 311                         *pulEncryptedLen = out_len;
 312                         return (CKR_BUFFER_TOO_SMALL);
 313                 }
 314 
 315                 if (soft_aes_ctx->remain_len != 0) {
 316                         /*
 317                          * Copy last remaining data and current input data
 318                          * to the output buffer.
 319                          */
 320                         (void) memmove(pEncrypted + soft_aes_ctx->remain_len,
 321                             pData, out_len - soft_aes_ctx->remain_len);
 322                         (void) memcpy(pEncrypted, soft_aes_ctx->data,
 323                             soft_aes_ctx->remain_len);
 324                         bzero(soft_aes_ctx->data, soft_aes_ctx->remain_len);
 325 
 326                         in_buf = pEncrypted;
 327                 } else {
 328                         in_buf = pData;
 329                 }
 330         }
 331 
 332 do_encryption:
 333         /*
 334          * Begin Encryption now.
 335          */
 336         switch (mechanism) {
 337 
 338         case CKM_AES_ECB:
 339         {
 340 
 341                 ulong_t i;
 342                 uint8_t *tmp_inbuf;
 343                 uint8_t *tmp_outbuf;
 344 
 345                 for (i = 0; i < out_len; i += AES_BLOCK_LEN) {
 346                         tmp_inbuf = &in_buf[i];
 347                         tmp_outbuf = &out_buf[i];
 348                         /* Crunch one block of data for AES. */
 349                         (void) aes_encrypt_block(soft_aes_ctx->key_sched,
 350                             tmp_inbuf, tmp_outbuf);
 351                 }
 352 
 353                 if (update) {
 354                         /*
 355                          * For encrypt update, if there is a remaining
 356                          * data, save it and its length in the context.
 357                          */
 358                         if (remain != 0)
 359                                 (void) memcpy(soft_aes_ctx->data, pData +
 360                                     (ulDataLen - remain), remain);
 361                         soft_aes_ctx->remain_len = remain;
 362                 }
 363 
 364                 *pulEncryptedLen = out_len;
 365 
 366                 break;
 367         }
 368 
 369         case CKM_AES_CMAC:
 370                 out_len = ulDataLen;
 371                 /*FALLTHRU*/
 372         case CKM_AES_CBC:
 373         case CKM_AES_CBC_PAD:
 374         {
 375                 crypto_data_t out;
 376 
 377                 out.cd_format = CRYPTO_DATA_RAW;
 378                 out.cd_offset = 0;
 379                 out.cd_length = out_len;
 380                 out.cd_raw.iov_base = (char *)out_buf;
 381                 out.cd_raw.iov_len = out_len;
 382 
 383                 /* Encrypt multiple blocks of data. */
 384                 rc = aes_encrypt_contiguous_blocks(
 385                     (aes_ctx_t *)soft_aes_ctx->aes_cbc,
 386                     (char *)in_buf, out_len, &out);
 387 
 388                 if (rc != 0)
 389                         goto encrypt_failed;
 390 
 391                 if (update) {
 392                         /*
 393                          * For encrypt update, if there is remaining data,
 394                          * save it and its length in the context.
 395                          */
 396                         if (remain != 0)
 397                                 (void) memcpy(soft_aes_ctx->data, pData +
 398                                     (ulDataLen - remain), remain);
 399                         soft_aes_ctx->remain_len = remain;
 400                 } else if (mechanism == CKM_AES_CBC_PAD) {
 401                         /*
 402                          * Save the remainder of the input
 403                          * block in a temporary block because
 404                          * we dont want to overrun the buffer
 405                          * by tacking on pad bytes.
 406                          */
 407                         CK_BYTE tmpblock[AES_BLOCK_LEN];
 408                         (void) memcpy(tmpblock, in_buf + out_len,
 409                             ulDataLen - out_len);
 410                         soft_add_pkcs7_padding(tmpblock +
 411                             (ulDataLen - out_len),
 412                             AES_BLOCK_LEN, ulDataLen - out_len);
 413 
 414                         out.cd_offset = out_len;
 415                         out.cd_length = AES_BLOCK_LEN;
 416                         out.cd_raw.iov_base = (char *)out_buf;
 417                         out.cd_raw.iov_len = out_len + AES_BLOCK_LEN;
 418 
 419                         /* Encrypt last block containing pad bytes. */
 420                         rc = aes_encrypt_contiguous_blocks(
 421                             (aes_ctx_t *)soft_aes_ctx->aes_cbc,
 422                             (char *)tmpblock, AES_BLOCK_LEN, &out);
 423 
 424                         out_len += AES_BLOCK_LEN;
 425                 } else if (mechanism == CKM_AES_CMAC) {
 426                         out.cd_length = AES_BLOCK_LEN;
 427                         out.cd_raw.iov_base = (char *)out_buf;
 428                         out.cd_raw.iov_len = AES_BLOCK_LEN;
 429 
 430                         rc = cmac_mode_final(soft_aes_ctx->aes_cbc, &out,
 431                             aes_encrypt_block, aes_xor_block);
 432                 }
 433 
 434                 if (rc == 0) {
 435                         *pulEncryptedLen = out_len;
 436                         break;
 437                 }
 438 encrypt_failed:
 439                 *pulEncryptedLen = 0;
 440                 rv = CKR_FUNCTION_FAILED;
 441                 goto cleanup;
 442         }
 443         case CKM_AES_CTR:
 444         {
 445                 crypto_data_t out;
 446 
 447                 out.cd_format = CRYPTO_DATA_RAW;
 448                 out.cd_offset = 0;
 449                 out.cd_length = *pulEncryptedLen;
 450                 out.cd_raw.iov_base = (char *)pEncrypted;
 451                 out.cd_raw.iov_len = *pulEncryptedLen;
 452 
 453                 rc = aes_encrypt_contiguous_blocks(soft_aes_ctx->aes_cbc,
 454                     (char *)pData, ulDataLen, &out);
 455 
 456                 if (rc != 0) {
 457                         *pulEncryptedLen = 0;
 458                         rv = CKR_FUNCTION_FAILED;
 459                         goto cleanup;
 460                 }
 461                 /*
 462                  * Since AES counter mode is a stream cipher, we call
 463                  * aes_counter_final() to pick up any remaining bytes.
 464                  * It is an internal function that does not destroy
 465                  * the context like *normal* final routines.
 466                  */
 467                 if (((aes_ctx_t *)soft_aes_ctx->aes_cbc)->ac_remainder_len > 0)
 468                         rc = ctr_mode_final(soft_aes_ctx->aes_cbc, &out,
 469                             aes_encrypt_block);
 470 
 471                 /*
 472                  * Even though success means we've encrypted all of the input,
 473                  * we should still behave like the other functions and return
 474                  * the encrypted length in pulEncryptedLen
 475                  */
 476                 *pulEncryptedLen = ulDataLen;
 477         }
 478         } /* end switch */
 479 
 480         if (update)
 481                 return (CKR_OK);
 482 
 483         /*
 484          * The following code will be executed if the caller is
 485          * soft_encrypt() or an error occurred. The encryption
 486          * operation will be terminated so we need to do some cleanup.
 487          */
 488 cleanup:
 489         (void) pthread_mutex_lock(&session_p->session_mutex);
 490         aes_ctx = (aes_ctx_t *)soft_aes_ctx->aes_cbc;
 491         if (aes_ctx != NULL) {
 492                 bzero(aes_ctx->ac_keysched, aes_ctx->ac_keysched_len);
 493                 free(soft_aes_ctx->aes_cbc);
 494         }
 495 
 496         bzero(soft_aes_ctx->key_sched, soft_aes_ctx->keysched_len);
 497         free(soft_aes_ctx->key_sched);
 498         free(session_p->encrypt.context);
 499         session_p->encrypt.context = NULL;
 500         (void) pthread_mutex_unlock(&session_p->session_mutex);
 501 
 502         return (rv);
 503 }
 504 
 505 
 506 /*
 507  * soft_aes_decrypt_common()
 508  *
 509  * Arguments:
 510  *      session_p:      pointer to soft_session_t struct
 511  *      pEncrypted:     pointer to the input data to be decrypted
 512  *      ulEncryptedLen: length of the input data
 513  *      pData:          pointer to the output data
 514  *      pulDataLen:     pointer to the length of the output data
 515  *      Update:         boolean flag indicates caller is soft_decrypt
 516  *                      or soft_decrypt_update
 517  *
 518  * Description:
 519  *      This function calls the corresponding decrypt routine based
 520  *      on the mechanism.
 521  *
 522  * Returns:
 523  *      CKR_OK: success
 524  *      CKR_BUFFER_TOO_SMALL: the output buffer provided by application
 525  *                            is too small
 526  *      CKR_ENCRYPTED_DATA_LEN_RANGE: the input data is not a multiple
 527  *                                    of blocksize
 528  *      CKR_FUNCTION_FAILED: decrypt function failed
 529  */
 530 CK_RV
 531 soft_aes_decrypt_common(soft_session_t *session_p, CK_BYTE_PTR pEncrypted,
 532     CK_ULONG ulEncryptedLen, CK_BYTE_PTR pData,
 533     CK_ULONG_PTR pulDataLen, boolean_t update)
 534 {
 535 
 536         int rc = 0;
 537         CK_RV rv = CKR_OK;
 538         soft_aes_ctx_t *soft_aes_ctx =
 539             (soft_aes_ctx_t *)session_p->decrypt.context;
 540         aes_ctx_t *aes_ctx;
 541         CK_MECHANISM_TYPE mechanism = session_p->decrypt.mech.mechanism;
 542         CK_BYTE *in_buf = NULL;
 543         CK_BYTE *out_buf = NULL;
 544         CK_ULONG out_len;
 545         CK_ULONG total_len;
 546         CK_ULONG remain;
 547 
 548         if (mechanism == CKM_AES_CTR)
 549                 goto do_decryption;
 550 
 551         /*
 552          * AES only takes input length that is a multiple of 16 bytes
 553          * for C_Decrypt function with the mechanism CKM_AES_ECB,
 554          * CKM_AES_CBC or CKM_AES_CBC_PAD.
 555          *
 556          * AES allows any input length for C_DecryptUpdate function.
 557          */
 558         if (!update) {
 559                 /*
 560                  * Called by C_Decrypt
 561                  */
 562                 if ((ulEncryptedLen % AES_BLOCK_LEN) != 0) {
 563                         rv = CKR_ENCRYPTED_DATA_LEN_RANGE;
 564                         goto cleanup;
 565                 }
 566 
 567                 /*
 568                  * If application asks for the length of the output buffer
 569                  * to hold the plaintext?
 570                  */
 571                 if (pData == NULL) {
 572                         *pulDataLen = ulEncryptedLen;
 573                         return (CKR_OK);
 574                 }
 575 
 576                 /* Is the application-supplied buffer large enough? */
 577                 if (mechanism != CKM_AES_CBC_PAD) {
 578                         if (*pulDataLen < ulEncryptedLen) {
 579                                 *pulDataLen = ulEncryptedLen;
 580                                 return (CKR_BUFFER_TOO_SMALL);
 581                         }
 582                         out_len = ulEncryptedLen;
 583                 } else {
 584                         /*
 585                          * For CKM_AES_CBC_PAD, we don't know how
 586                          * many bytes for padding at this time, so
 587                          * we'd assume one block was padded.
 588                          */
 589                         if (*pulDataLen < (ulEncryptedLen - AES_BLOCK_LEN)) {
 590                                 *pulDataLen = ulEncryptedLen - AES_BLOCK_LEN;
 591                                 return (CKR_BUFFER_TOO_SMALL);
 592                         }
 593                         out_len = ulEncryptedLen - AES_BLOCK_LEN;
 594                 }
 595                 in_buf = pEncrypted;
 596                 out_buf = pData;
 597         } else {
 598                 /*
 599                  *  Called by C_DecryptUpdate
 600                  *
 601                  * Add the lengths of last remaining data and current
 602                  * input data together to get the total input length.
 603                  */
 604                 total_len = soft_aes_ctx->remain_len + ulEncryptedLen;
 605 
 606                 /*
 607                  * If the total input length is less than one blocksize,
 608                  * or if the total input length is just one blocksize and
 609                  * the mechanism is CKM_AES_CBC_PAD, we will need to delay
 610                  * decryption until when more data comes in next
 611                  * C_DecryptUpdate or when C_DecryptFinal is called.
 612                  */
 613                 if ((total_len < AES_BLOCK_LEN) ||
 614                     ((mechanism == CKM_AES_CBC_PAD) &&
 615                     (total_len == AES_BLOCK_LEN))) {
 616                         if (pData != NULL) {
 617                                 /*
 618                                  * Save input data and its length in
 619                                  * the remaining buffer of AES context.
 620                                  */
 621                                 (void) memcpy(soft_aes_ctx->data +
 622                                     soft_aes_ctx->remain_len,
 623                                     pEncrypted, ulEncryptedLen);
 624                                 soft_aes_ctx->remain_len += ulEncryptedLen;
 625                         }
 626 
 627                         /* Set output data length to 0. */
 628                         *pulDataLen = 0;
 629                         return (CKR_OK);
 630                 }
 631 
 632                 /* Compute the length of remaing data. */
 633                 remain = total_len % AES_BLOCK_LEN;
 634 
 635                 /*
 636                  * Make sure that the output length is a multiple of
 637                  * blocksize.
 638                  */
 639                 out_len = total_len - remain;
 640 
 641                 if (mechanism == CKM_AES_CBC_PAD) {
 642                         /*
 643                          * If the input data length is a multiple of
 644                          * blocksize, then save the last block of input
 645                          * data in the remaining buffer. C_DecryptFinal
 646                          * will handle this last block of data.
 647                          */
 648                         if (remain == 0) {
 649                                 remain = AES_BLOCK_LEN;
 650                                 out_len -= AES_BLOCK_LEN;
 651                         }
 652                 }
 653 
 654                 /*
 655                  * If application asks for the length of the output buffer
 656                  * to hold the plaintext?
 657                  */
 658                 if (pData == NULL) {
 659                         *pulDataLen = out_len;
 660                         return (CKR_OK);
 661                 }
 662 
 663                 /*
 664                  * Is the application-supplied buffer large enough?
 665                  */
 666                 if (*pulDataLen < out_len) {
 667                         *pulDataLen = out_len;
 668                         return (CKR_BUFFER_TOO_SMALL);
 669                 }
 670 
 671                 if (soft_aes_ctx->remain_len != 0) {
 672                         /*
 673                          * Copy last remaining data and current input data
 674                          * to the output buffer.
 675                          */
 676                         (void) memmove(pData + soft_aes_ctx->remain_len,
 677                             pEncrypted, out_len - soft_aes_ctx->remain_len);
 678                         (void) memcpy(pData, soft_aes_ctx->data,
 679                             soft_aes_ctx->remain_len);
 680                         bzero(soft_aes_ctx->data, soft_aes_ctx->remain_len);
 681 
 682                         in_buf = pData;
 683                 } else {
 684                         in_buf = pEncrypted;
 685                 }
 686                 out_buf = pData;
 687         }
 688 
 689 do_decryption:
 690         /*
 691          * Begin Decryption.
 692          */
 693         switch (mechanism) {
 694 
 695         case CKM_AES_ECB:
 696         {
 697 
 698                 ulong_t i;
 699                 uint8_t *tmp_inbuf;
 700                 uint8_t *tmp_outbuf;
 701 
 702                 for (i = 0; i < out_len; i += AES_BLOCK_LEN) {
 703                         tmp_inbuf = &in_buf[i];
 704                         tmp_outbuf = &out_buf[i];
 705                         /* Crunch one block of data for AES. */
 706                         (void) aes_decrypt_block(soft_aes_ctx->key_sched,
 707                             tmp_inbuf, tmp_outbuf);
 708                 }
 709 
 710                 if (update) {
 711                         /*
 712                          * For decrypt update, if there is a remaining
 713                          * data, save it and its length in the context.
 714                          */
 715                         if (remain != 0)
 716                                 (void) memcpy(soft_aes_ctx->data, pEncrypted +
 717                                     (ulEncryptedLen - remain), remain);
 718                         soft_aes_ctx->remain_len = remain;
 719                 }
 720 
 721                 *pulDataLen = out_len;
 722 
 723                 break;
 724         }
 725 
 726         case CKM_AES_CBC:
 727         case CKM_AES_CBC_PAD:
 728         {
 729                 crypto_data_t out;
 730                 CK_ULONG rem_len;
 731                 uint8_t last_block[AES_BLOCK_LEN];
 732 
 733                 out.cd_format = CRYPTO_DATA_RAW;
 734                 out.cd_offset = 0;
 735                 out.cd_length = out_len;
 736                 out.cd_raw.iov_base = (char *)out_buf;
 737                 out.cd_raw.iov_len = out_len;
 738 
 739                 /* Decrypt multiple blocks of data. */
 740                 rc = aes_decrypt_contiguous_blocks(
 741                     (aes_ctx_t *)soft_aes_ctx->aes_cbc,
 742                     (char *)in_buf, out_len, &out);
 743 
 744                 if (rc != 0)
 745                         goto decrypt_failed;
 746 
 747                 if ((mechanism == CKM_AES_CBC_PAD) && (!update)) {
 748                         /* Decrypt last block containing pad bytes. */
 749                         out.cd_offset = 0;
 750                         out.cd_length = AES_BLOCK_LEN;
 751                         out.cd_raw.iov_base = (char *)last_block;
 752                         out.cd_raw.iov_len = AES_BLOCK_LEN;
 753 
 754                         /* Decrypt last block containing pad bytes. */
 755                         rc = aes_decrypt_contiguous_blocks(
 756                             (aes_ctx_t *)soft_aes_ctx->aes_cbc,
 757                             (char *)in_buf + out_len, AES_BLOCK_LEN, &out);
 758 
 759                         if (rc != 0)
 760                                 goto decrypt_failed;
 761 
 762                         /*
 763                          * Remove padding bytes after decryption of
 764                          * ciphertext block to produce the original
 765                          * plaintext.
 766                          */
 767                         rv = soft_remove_pkcs7_padding(last_block,
 768                             AES_BLOCK_LEN, &rem_len);
 769                         if (rv == CKR_OK) {
 770                                 if (rem_len != 0)
 771                                         (void) memcpy(out_buf + out_len,
 772                                             last_block, rem_len);
 773                                 *pulDataLen = out_len + rem_len;
 774                         } else {
 775                                 *pulDataLen = 0;
 776                                 goto cleanup;
 777                         }
 778                 } else {
 779                         *pulDataLen = out_len;
 780                 }
 781 
 782                 if (update) {
 783                         /*
 784                          * For decrypt update, if there is remaining data,
 785                          * save it and its length in the context.
 786                          */
 787                         if (remain != 0)
 788                                 (void) memcpy(soft_aes_ctx->data, pEncrypted +
 789                                     (ulEncryptedLen - remain), remain);
 790                         soft_aes_ctx->remain_len = remain;
 791                 }
 792 
 793                 if (rc == 0)
 794                         break;
 795 decrypt_failed:
 796                 *pulDataLen = 0;
 797                 rv = CKR_FUNCTION_FAILED;
 798                 goto cleanup;
 799         }
 800         case CKM_AES_CTR:
 801         {
 802                 crypto_data_t out;
 803 
 804                 out.cd_format = CRYPTO_DATA_RAW;
 805                 out.cd_offset = 0;
 806                 out.cd_length = *pulDataLen;
 807                 out.cd_raw.iov_base = (char *)pData;
 808                 out.cd_raw.iov_len = *pulDataLen;
 809 
 810                 rc = aes_decrypt_contiguous_blocks(soft_aes_ctx->aes_cbc,
 811                     (char *)pEncrypted, ulEncryptedLen, &out);
 812 
 813                 if (rc != 0) {
 814                         *pulDataLen = 0;
 815                         rv = CKR_FUNCTION_FAILED;
 816                         goto cleanup;
 817                 }
 818 
 819                 /*
 820                  * Since AES counter mode is a stream cipher, we call
 821                  * aes_counter_final() to pick up any remaining bytes.
 822                  * It is an internal function that does not destroy
 823                  * the context like *normal* final routines.
 824                  */
 825                 if (((aes_ctx_t *)soft_aes_ctx->aes_cbc)->ac_remainder_len
 826                     > 0) {
 827                         rc = ctr_mode_final(soft_aes_ctx->aes_cbc, &out,
 828                             aes_encrypt_block);
 829                         if (rc == CRYPTO_DATA_LEN_RANGE)
 830                                 rc = CRYPTO_ENCRYPTED_DATA_LEN_RANGE;
 831                 }
 832 
 833                 /*
 834                  * Even though success means we've decrypted all of the input,
 835                  * we should still behave like the other functions and return
 836                  * the decrypted length in pulDataLen
 837                  */
 838                 *pulDataLen = ulEncryptedLen;
 839 
 840         }
 841         } /* end switch */
 842 
 843         if (update)
 844                 return (CKR_OK);
 845 
 846         /*
 847          * The following code will be executed if the caller is
 848          * soft_decrypt() or an error occurred. The decryption
 849          * operation will be terminated so we need to do some cleanup.
 850          */
 851 cleanup:
 852         (void) pthread_mutex_lock(&session_p->session_mutex);
 853         aes_ctx = (aes_ctx_t *)soft_aes_ctx->aes_cbc;
 854         if (aes_ctx != NULL) {
 855                 bzero(aes_ctx->ac_keysched, aes_ctx->ac_keysched_len);
 856                 free(soft_aes_ctx->aes_cbc);
 857         }
 858 
 859         bzero(soft_aes_ctx->key_sched, soft_aes_ctx->keysched_len);
 860         free(soft_aes_ctx->key_sched);
 861         free(session_p->decrypt.context);
 862         session_p->decrypt.context = NULL;
 863         (void) pthread_mutex_unlock(&session_p->session_mutex);
 864 
 865         return (rv);
 866 }
 867 
 868 
 869 /*
 870  * Allocate and initialize a context for AES CBC mode of operation.
 871  */
 872 void *
 873 aes_cbc_ctx_init(void *key_sched, size_t size, uint8_t *ivec)
 874 {
 875 
 876         cbc_ctx_t *cbc_ctx;
 877 
 878         if ((cbc_ctx = calloc(1, sizeof (cbc_ctx_t))) == NULL)
 879                 return (NULL);
 880 
 881         cbc_ctx->cbc_keysched = key_sched;
 882         cbc_ctx->cbc_keysched_len = size;
 883 
 884         (void) memcpy(&cbc_ctx->cbc_iv[0], ivec, AES_BLOCK_LEN);
 885 
 886         cbc_ctx->cbc_lastp = (uint8_t *)cbc_ctx->cbc_iv;
 887         cbc_ctx->cbc_flags |= CBC_MODE;
 888         cbc_ctx->max_remain = AES_BLOCK_LEN;
 889 
 890         return (cbc_ctx);
 891 }
 892 
 893 void *
 894 aes_cmac_ctx_init(void *key_sched, size_t size)
 895 {
 896 
 897         cbc_ctx_t *cbc_ctx;
 898 
 899         if ((cbc_ctx = calloc(1, sizeof (cbc_ctx_t))) == NULL)
 900                 return (NULL);
 901 
 902         cbc_ctx->cbc_keysched = key_sched;
 903         cbc_ctx->cbc_keysched_len = size;
 904 
 905         cbc_ctx->cbc_lastp = (uint8_t *)cbc_ctx->cbc_iv;
 906         cbc_ctx->cbc_flags |= CMAC_MODE;
 907         cbc_ctx->max_remain = AES_BLOCK_LEN + 1;
 908 
 909         return (cbc_ctx);
 910 }
 911 
 912 /*
 913  * Allocate and initialize a context for AES CTR mode of operation.
 914  */
 915 void *
 916 aes_ctr_ctx_init(void *key_sched, size_t size, uint8_t *param)
 917 {
 918 
 919         ctr_ctx_t *ctr_ctx;
 920         CK_AES_CTR_PARAMS *pp;
 921 
 922         /* LINTED: pointer alignment */
 923         pp = (CK_AES_CTR_PARAMS *)param;
 924 
 925         if ((ctr_ctx = calloc(1, sizeof (ctr_ctx_t))) == NULL)
 926                 return (NULL);
 927 
 928         ctr_ctx->ctr_keysched = key_sched;
 929         ctr_ctx->ctr_keysched_len = size;
 930 
 931         if (ctr_init_ctx(ctr_ctx, pp->ulCounterBits, pp->cb, aes_copy_block)
 932             != CRYPTO_SUCCESS) {
 933                 free(ctr_ctx);
 934                 return (NULL);
 935         }
 936 
 937         return (ctr_ctx);
 938 }
 939 
 940 /*
 941  * Allocate and initialize AES contexts for both signing and encrypting,
 942  * saving both context pointers in the session struct. For general-length AES
 943  * MAC, check the length in the parameter to see if it is in the right range.
 944  */
 945 CK_RV
 946 soft_aes_sign_verify_init_common(soft_session_t *session_p,
 947     CK_MECHANISM_PTR pMechanism, soft_object_t *key_p, boolean_t sign_op)
 948 {
 949         soft_aes_ctx_t  *soft_aes_ctx;
 950         CK_MECHANISM    encrypt_mech;
 951         CK_RV rv;
 952 
 953         if (key_p->key_type != CKK_AES) {
 954                 return (CKR_KEY_TYPE_INCONSISTENT);
 955         }
 956 
 957         /* allocate memory for the sign/verify context */
 958         soft_aes_ctx = malloc(sizeof (soft_aes_ctx_t));
 959         if (soft_aes_ctx == NULL) {
 960                 return (CKR_HOST_MEMORY);
 961         }
 962 
 963         /* initialization vector is zero for AES CMAC */
 964         bzero(soft_aes_ctx->ivec, AES_BLOCK_LEN);
 965 
 966         switch (pMechanism->mechanism) {
 967 
 968         case CKM_AES_CMAC_GENERAL:
 969 
 970                 if (pMechanism->ulParameterLen !=
 971                     sizeof (CK_MAC_GENERAL_PARAMS)) {
 972                         free(soft_aes_ctx);
 973                         return (CKR_MECHANISM_PARAM_INVALID);
 974                 }
 975 
 976                 if (*(CK_MAC_GENERAL_PARAMS *)pMechanism->pParameter >
 977                     AES_BLOCK_LEN) {
 978                         free(soft_aes_ctx);
 979                         return (CKR_MECHANISM_PARAM_INVALID);
 980                 }
 981 
 982                 soft_aes_ctx->mac_len = *((CK_MAC_GENERAL_PARAMS_PTR)
 983                     pMechanism->pParameter);
 984 
 985                 /*FALLTHRU*/
 986         case CKM_AES_CMAC:
 987 
 988                 /*
 989                  * For non-general AES MAC, output is always block size
 990                  */
 991                 if (pMechanism->mechanism == CKM_AES_CMAC) {
 992                         soft_aes_ctx->mac_len = AES_BLOCK_LEN;
 993                 }
 994 
 995                 /* allocate a context for AES encryption */
 996                 encrypt_mech.mechanism = CKM_AES_CMAC;
 997                 encrypt_mech.pParameter = (void *)soft_aes_ctx->ivec;
 998                 encrypt_mech.ulParameterLen = AES_BLOCK_LEN;
 999                 rv = soft_encrypt_init_internal(session_p, &encrypt_mech,
1000                     key_p);
1001                 if (rv != CKR_OK) {
1002                         free(soft_aes_ctx);
1003                         return (rv);
1004                 }
1005 
1006                 (void) pthread_mutex_lock(&session_p->session_mutex);
1007 
1008                 if (sign_op) {
1009                         session_p->sign.context = soft_aes_ctx;
1010                         session_p->sign.mech.mechanism = pMechanism->mechanism;
1011                 } else {
1012                         session_p->verify.context = soft_aes_ctx;
1013                         session_p->verify.mech.mechanism =
1014                             pMechanism->mechanism;
1015                 }
1016 
1017                 (void) pthread_mutex_unlock(&session_p->session_mutex);
1018 
1019                 break;
1020         }
1021         return (CKR_OK);
1022 }
1023 
1024 /*
1025  * Called by soft_sign(), soft_sign_final(), soft_verify() or
1026  * soft_verify_final().
1027  */
1028 CK_RV
1029 soft_aes_sign_verify_common(soft_session_t *session_p, CK_BYTE_PTR pData,
1030     CK_ULONG ulDataLen, CK_BYTE_PTR pSigned, CK_ULONG_PTR pulSignedLen,
1031     boolean_t sign_op, boolean_t Final)
1032 {
1033         soft_aes_ctx_t          *soft_aes_ctx_sign_verify;
1034         CK_RV                   rv;
1035         CK_BYTE                 *pEncrypted = NULL;
1036         CK_ULONG                ulEncryptedLen = AES_BLOCK_LEN;
1037         CK_BYTE                 last_block[AES_BLOCK_LEN];
1038 
1039         if (sign_op) {
1040                 soft_aes_ctx_sign_verify =
1041                     (soft_aes_ctx_t *)session_p->sign.context;
1042 
1043                 if (soft_aes_ctx_sign_verify->mac_len == 0) {
1044                         *pulSignedLen = 0;
1045                         goto clean_exit;
1046                 }
1047 
1048                 /* Application asks for the length of the output buffer. */
1049                 if (pSigned == NULL) {
1050                         *pulSignedLen = soft_aes_ctx_sign_verify->mac_len;
1051                         return (CKR_OK);
1052                 }
1053 
1054                 /* Is the application-supplied buffer large enough? */
1055                 if (*pulSignedLen < soft_aes_ctx_sign_verify->mac_len) {
1056                         *pulSignedLen = soft_aes_ctx_sign_verify->mac_len;
1057                         return (CKR_BUFFER_TOO_SMALL);
1058                 }
1059         } else {
1060                 soft_aes_ctx_sign_verify =
1061                     (soft_aes_ctx_t *)session_p->verify.context;
1062         }
1063 
1064         if (Final) {
1065                 rv = soft_encrypt_final(session_p, last_block,
1066                     &ulEncryptedLen);
1067         } else {
1068                 rv = soft_encrypt(session_p, pData, ulDataLen,
1069                     last_block, &ulEncryptedLen);
1070         }
1071 
1072         if (rv == CKR_OK) {
1073                 *pulSignedLen = soft_aes_ctx_sign_verify->mac_len;
1074 
1075                 /* the leftmost mac_len bytes of last_block is our MAC */
1076                 (void) memcpy(pSigned, last_block, *pulSignedLen);
1077         }
1078 
1079 clean_exit:
1080 
1081         (void) pthread_mutex_lock(&session_p->session_mutex);
1082 
1083         /* soft_encrypt_common() has freed the encrypt context */
1084         if (sign_op) {
1085                 free(session_p->sign.context);
1086                 session_p->sign.context = NULL;
1087         } else {
1088                 free(session_p->verify.context);
1089                 session_p->verify.context = NULL;
1090         }
1091         session_p->encrypt.flags = 0;
1092 
1093         (void) pthread_mutex_unlock(&session_p->session_mutex);
1094 
1095         if (pEncrypted) {
1096                 free(pEncrypted);
1097         }
1098 
1099         return (rv);
1100 }
1101 
1102 /*
1103  * Called by soft_sign_update()
1104  */
1105 CK_RV
1106 soft_aes_mac_sign_verify_update(soft_session_t *session_p, CK_BYTE_PTR pPart,
1107     CK_ULONG ulPartLen)
1108 {
1109         CK_BYTE         buf[AES_BLOCK_LEN];
1110         CK_ULONG        ulEncryptedLen = AES_BLOCK_LEN;
1111         CK_RV           rv;
1112 
1113         rv = soft_encrypt_update(session_p, pPart, ulPartLen,
1114             buf, &ulEncryptedLen);
1115 
1116         return (rv);
1117 }