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 (c) 2018, Joyent, Inc. 25 * Copyright 2017 Jason King. 26 */ 27 28 #include <pthread.h> 29 #include <stdlib.h> 30 #include <string.h> 31 #include <strings.h> 32 #include <sys/types.h> 33 #include <security/cryptoki.h> 34 #include <modes/modes.h> 35 #include <arcfour.h> 36 #include "softSession.h" 37 #include "softObject.h" 38 #include "softOps.h" 39 #include "softCrypt.h" 40 #include "softRSA.h" 41 42 /* 43 * Remove padding bytes. 44 */ 45 CK_RV 46 soft_remove_pkcs7_padding(CK_BYTE *pData, CK_ULONG padded_len, 47 CK_ULONG *pulDataLen) 48 { 49 CK_RV rv; 50 51 #ifdef __sparcv9 52 if ((rv = pkcs7_decode(pData, (&padded_len))) != CKR_OK) 53 #else /* !__sparcv9 */ 54 if ((rv = pkcs7_decode(pData, (size_t *)(&padded_len))) != CKR_OK) 55 #endif /* __sparcv9 */ 56 return (rv); 57 58 *pulDataLen = padded_len; 59 return (CKR_OK); 60 } 61 62 63 /* 64 * soft_decrypt_init() 65 * 66 * Arguments: 67 * session_p: pointer to soft_session_t struct 68 * pMechanism: pointer to CK_MECHANISM struct provided by application 69 * key_p: pointer to key soft_object_t struct 70 * 71 * Description: 72 * called by C_DecryptInit(). This function calls the corresponding 73 * decrypt init routine based on the mechanism. 74 * 75 * Returns: 76 * CKR_OK: success 77 * CKR_HOST_MEMORY: run out of system memory 78 * CKR_MECHANISM_PARAM_INVALID: invalid parameters in mechanism 79 * CKR_MECHANISM_INVALID: invalid mechanism type 80 * CKR_KEY_TYPE_INCONSISTENT: incorrect type of key to use 81 * with the specified mechanism 82 */ 83 CK_RV 84 soft_decrypt_init(soft_session_t *session_p, CK_MECHANISM_PTR pMechanism, 85 soft_object_t *key_p) 86 { 87 88 CK_RV rv; 89 90 switch (pMechanism->mechanism) { 91 92 case CKM_DES_ECB: 93 94 if (key_p->key_type != CKK_DES) { 95 return (CKR_KEY_TYPE_INCONSISTENT); 96 } 97 98 goto ecb_common; 99 100 case CKM_DES3_ECB: 101 102 if ((key_p->key_type != CKK_DES2) && 103 (key_p->key_type != CKK_DES3)) { 104 return (CKR_KEY_TYPE_INCONSISTENT); 105 } 106 107 ecb_common: 108 109 return (soft_des_crypt_init_common(session_p, pMechanism, 110 key_p, B_FALSE)); 111 112 case CKM_DES_CBC: 113 case CKM_DES_CBC_PAD: 114 115 if (key_p->key_type != CKK_DES) { 116 return (CKR_KEY_TYPE_INCONSISTENT); 117 } 118 119 goto cbc_common; 120 121 case CKM_DES3_CBC: 122 case CKM_DES3_CBC_PAD: 123 { 124 soft_des_ctx_t *soft_des_ctx; 125 126 if ((key_p->key_type != CKK_DES2) && 127 (key_p->key_type != CKK_DES3)) { 128 return (CKR_KEY_TYPE_INCONSISTENT); 129 } 130 131 cbc_common: 132 if ((pMechanism->pParameter == NULL) || 133 (pMechanism->ulParameterLen != DES_BLOCK_LEN)) { 134 return (CKR_MECHANISM_PARAM_INVALID); 135 } 136 137 rv = soft_des_crypt_init_common(session_p, pMechanism, 138 key_p, B_FALSE); 139 140 if (rv != CKR_OK) 141 return (rv); 142 143 (void) pthread_mutex_lock(&session_p->session_mutex); 144 145 soft_des_ctx = (soft_des_ctx_t *)session_p->decrypt.context; 146 /* Save Initialization Vector (IV) in the context. */ 147 (void) memcpy(soft_des_ctx->ivec, pMechanism->pParameter, 148 DES_BLOCK_LEN); 149 150 /* Allocate a context for DES cipher-block chaining. */ 151 soft_des_ctx->des_cbc = (void *)des_cbc_ctx_init( 152 soft_des_ctx->key_sched, soft_des_ctx->keysched_len, 153 soft_des_ctx->ivec, key_p->key_type); 154 155 if (soft_des_ctx->des_cbc == NULL) { 156 freezero(soft_des_ctx->key_sched, 157 soft_des_ctx->keysched_len); 158 freezero(session_p->decrypt.context, 159 sizeof (soft_des_ctx_t)); 160 session_p->decrypt.context = NULL; 161 (void) pthread_mutex_unlock(&session_p->session_mutex); 162 return (CKR_HOST_MEMORY); 163 } 164 165 (void) pthread_mutex_unlock(&session_p->session_mutex); 166 167 return (rv); 168 } 169 case CKM_AES_ECB: 170 case CKM_AES_CBC: 171 case CKM_AES_CBC_PAD: 172 case CKM_AES_CTR: 173 case CKM_AES_GCM: 174 case CKM_AES_CCM: 175 return (soft_aes_crypt_init_common(session_p, pMechanism, 176 key_p, B_FALSE)); 177 178 case CKM_BLOWFISH_CBC: 179 { 180 soft_blowfish_ctx_t *soft_blowfish_ctx; 181 182 if (key_p->key_type != CKK_BLOWFISH) 183 return (CKR_KEY_TYPE_INCONSISTENT); 184 185 if ((pMechanism->pParameter == NULL) || 186 (pMechanism->ulParameterLen != BLOWFISH_BLOCK_LEN)) 187 return (CKR_MECHANISM_PARAM_INVALID); 188 189 rv = soft_blowfish_crypt_init_common(session_p, pMechanism, 190 key_p, B_FALSE); 191 192 if (rv != CKR_OK) 193 return (rv); 194 195 (void) pthread_mutex_lock(&session_p->session_mutex); 196 197 soft_blowfish_ctx = 198 (soft_blowfish_ctx_t *)session_p->decrypt.context; 199 200 /* Save Initialization Vector in the context. */ 201 (void) memcpy(soft_blowfish_ctx->ivec, pMechanism->pParameter, 202 BLOWFISH_BLOCK_LEN); 203 204 /* Allocate a context for CBC */ 205 soft_blowfish_ctx->blowfish_cbc = 206 (void *)blowfish_cbc_ctx_init(soft_blowfish_ctx->key_sched, 207 soft_blowfish_ctx->keysched_len, 208 soft_blowfish_ctx->ivec); 209 210 if (soft_blowfish_ctx->blowfish_cbc == NULL) { 211 freezero(soft_blowfish_ctx->key_sched, 212 soft_blowfish_ctx->keysched_len); 213 freezero(session_p->decrypt.context, 214 sizeof (soft_blowfish_ctx_t)); 215 session_p->decrypt.context = NULL; 216 (void) pthread_mutex_unlock(&session_p->session_mutex); 217 return (CKR_HOST_MEMORY); 218 } 219 220 (void) pthread_mutex_unlock(&session_p->session_mutex); 221 return (rv); 222 } 223 224 case CKM_RC4: 225 226 if (key_p->key_type != CKK_RC4) { 227 return (CKR_KEY_TYPE_INCONSISTENT); 228 } 229 230 return (soft_arcfour_crypt_init(session_p, pMechanism, key_p, 231 B_FALSE)); 232 233 case CKM_RSA_X_509: 234 case CKM_RSA_PKCS: 235 236 if (key_p->key_type != CKK_RSA) { 237 return (CKR_KEY_TYPE_INCONSISTENT); 238 } 239 240 return (soft_rsa_crypt_init_common(session_p, pMechanism, 241 key_p, B_FALSE)); 242 243 default: 244 return (CKR_MECHANISM_INVALID); 245 } 246 } 247 248 249 /* 250 * soft_decrypt_common() 251 * 252 * Arguments: 253 * session_p: pointer to soft_session_t struct 254 * pEncrypted: pointer to the encrypted data as input 255 * ulEncryptedLen: length of the input data 256 * pData: pointer to the output data contains plaintext 257 * pulDataLen: pointer to the length of the output data 258 * Update: boolean flag indicates caller is soft_decrypt 259 * or soft_decrypt_update 260 * 261 * Description: 262 * This function calls the corresponding decrypt routine based 263 * on the mechanism. 264 * 265 * Returns: 266 * see soft_decrypt_common(). 267 */ 268 CK_RV 269 soft_decrypt_common(soft_session_t *session_p, CK_BYTE_PTR pEncrypted, 270 CK_ULONG ulEncryptedLen, CK_BYTE_PTR pData, 271 CK_ULONG_PTR pulDataLen, boolean_t Update) 272 { 273 274 CK_MECHANISM_TYPE mechanism = session_p->decrypt.mech.mechanism; 275 276 switch (mechanism) { 277 278 case CKM_DES_ECB: 279 case CKM_DES_CBC: 280 case CKM_DES3_ECB: 281 case CKM_DES3_CBC: 282 283 if (ulEncryptedLen == 0) { 284 *pulDataLen = 0; 285 return (CKR_OK); 286 } 287 /* FALLTHROUGH */ 288 289 case CKM_DES_CBC_PAD: 290 case CKM_DES3_CBC_PAD: 291 292 return (soft_des_decrypt_common(session_p, pEncrypted, 293 ulEncryptedLen, pData, pulDataLen, Update)); 294 295 case CKM_AES_ECB: 296 case CKM_AES_CBC: 297 case CKM_AES_CTR: 298 case CKM_AES_CCM: 299 case CKM_AES_GCM: 300 case CKM_AES_CBC_PAD: 301 if (Update) { 302 return (soft_aes_decrypt_update(session_p, pEncrypted, 303 ulEncryptedLen, pData, pulDataLen)); 304 } else { 305 return (soft_aes_decrypt(session_p, pEncrypted, 306 ulEncryptedLen, pData, pulDataLen)); 307 } 308 309 case CKM_BLOWFISH_CBC: 310 311 if (ulEncryptedLen == 0) { 312 *pulDataLen = 0; 313 return (CKR_OK); 314 } 315 316 return (soft_blowfish_decrypt_common(session_p, pEncrypted, 317 ulEncryptedLen, pData, pulDataLen, Update)); 318 319 case CKM_RC4: 320 321 if (ulEncryptedLen == 0) { 322 *pulDataLen = 0; 323 return (CKR_OK); 324 } 325 326 327 return (soft_arcfour_crypt(&(session_p->decrypt), pEncrypted, 328 ulEncryptedLen, pData, pulDataLen)); 329 330 case CKM_RSA_X_509: 331 case CKM_RSA_PKCS: 332 333 return (soft_rsa_decrypt_common(session_p, pEncrypted, 334 ulEncryptedLen, pData, pulDataLen, mechanism)); 335 336 default: 337 return (CKR_MECHANISM_INVALID); 338 339 } 340 } 341 342 343 /* 344 * soft_decrypt() 345 * 346 * Arguments: 347 * session_p: pointer to soft_session_t struct 348 * pEncryptedData: pointer to the encrypted data as input 349 * ulEncryptedDataLen: length of the input data 350 * pData: pointer to the output data contains plaintext 351 * pulDataLen: pointer to the length of the output data 352 * 353 * Description: 354 * called by C_Decrypt(). This function calls the soft_decrypt_common 355 * routine. 356 * 357 * Returns: 358 * see soft_decrypt_common(). 359 */ 360 CK_RV 361 soft_decrypt(soft_session_t *session_p, CK_BYTE_PTR pEncryptedData, 362 CK_ULONG ulEncryptedDataLen, CK_BYTE_PTR pData, 363 CK_ULONG_PTR pulDataLen) 364 { 365 366 return (soft_decrypt_common(session_p, pEncryptedData, 367 ulEncryptedDataLen, pData, pulDataLen, B_FALSE)); 368 } 369 370 371 /* 372 * soft_decrypt_update() 373 * 374 * Arguments: 375 * session_p: pointer to soft_session_t struct 376 * pEncryptedPart: pointer to the encrypted data as input 377 * ulEncryptedPartLen: length of the input data 378 * pPart: pointer to the output data contains plaintext 379 * pulPartLen: pointer to the length of the output data 380 * 381 * Description: 382 * called by C_DecryptUpdate(). This function calls the 383 * soft_decrypt_common routine (with update flag on). 384 * 385 * Returns: 386 * see soft_decrypt_common(). 387 */ 388 CK_RV 389 soft_decrypt_update(soft_session_t *session_p, CK_BYTE_PTR pEncryptedPart, 390 CK_ULONG ulEncryptedPartLen, CK_BYTE_PTR pPart, CK_ULONG_PTR pulPartLen) 391 { 392 CK_MECHANISM_TYPE mechanism = session_p->decrypt.mech.mechanism; 393 394 switch (mechanism) { 395 396 case CKM_DES_ECB: 397 case CKM_DES_CBC: 398 case CKM_DES_CBC_PAD: 399 case CKM_DES3_ECB: 400 case CKM_DES3_CBC: 401 case CKM_DES3_CBC_PAD: 402 case CKM_AES_ECB: 403 case CKM_AES_CBC: 404 case CKM_AES_CBC_PAD: 405 case CKM_AES_CTR: 406 case CKM_AES_GCM: 407 case CKM_AES_CCM: 408 case CKM_BLOWFISH_CBC: 409 case CKM_RC4: 410 411 return (soft_decrypt_common(session_p, pEncryptedPart, 412 ulEncryptedPartLen, pPart, pulPartLen, B_TRUE)); 413 414 default: 415 /* PKCS11: The mechanism only supports single-part operation. */ 416 return (CKR_MECHANISM_INVALID); 417 } 418 419 } 420 421 422 /* 423 * soft_decrypt_final() 424 * 425 * Arguments: 426 * session_p: pointer to soft_session_t struct 427 * pLastPart: pointer to the last recovered data part 428 * pulLastPartLen: pointer to the length of the last recovered data part 429 * 430 * Description: 431 * called by C_DecryptFinal(). 432 * 433 * Returns: 434 * CKR_OK: success 435 * CKR_FUNCTION_FAILED: decrypt final function failed 436 * CKR_ENCRYPTED_DATA_LEN_RANGE: remaining buffer contains bad length 437 */ 438 CK_RV 439 soft_decrypt_final(soft_session_t *session_p, CK_BYTE_PTR pLastPart, 440 CK_ULONG_PTR pulLastPartLen) 441 { 442 443 CK_MECHANISM_TYPE mechanism = session_p->decrypt.mech.mechanism; 444 CK_ULONG out_len; 445 CK_RV rv = CKR_OK; 446 int rc; 447 448 (void) pthread_mutex_lock(&session_p->session_mutex); 449 450 if (session_p->decrypt.context == NULL) { 451 rv = CKR_OPERATION_NOT_INITIALIZED; 452 *pulLastPartLen = 0; 453 goto clean2; 454 } 455 switch (mechanism) { 456 457 case CKM_DES_CBC_PAD: 458 case CKM_DES3_CBC_PAD: 459 { 460 461 soft_des_ctx_t *soft_des_ctx; 462 463 soft_des_ctx = (soft_des_ctx_t *)session_p->decrypt.context; 464 465 /* 466 * We should have only one block of data left in the 467 * remaining buffer. 468 */ 469 if (soft_des_ctx->remain_len != DES_BLOCK_LEN) { 470 *pulLastPartLen = 0; 471 rv = CKR_ENCRYPTED_DATA_LEN_RANGE; 472 /* Cleanup memory space. */ 473 free(soft_des_ctx->des_cbc); 474 freezero(soft_des_ctx->key_sched, 475 soft_des_ctx->keysched_len); 476 477 goto clean1; 478 } 479 480 out_len = DES_BLOCK_LEN; 481 482 /* 483 * If application asks for the length of the output buffer 484 * to hold the plaintext? 485 */ 486 if (pLastPart == NULL) { 487 *pulLastPartLen = out_len; 488 rv = CKR_OK; 489 goto clean2; 490 } else { 491 crypto_data_t out; 492 493 /* Copy remaining data to the output buffer. */ 494 (void) memcpy(pLastPart, soft_des_ctx->data, 495 DES_BLOCK_LEN); 496 497 out.cd_format = CRYPTO_DATA_RAW; 498 out.cd_offset = 0; 499 out.cd_length = DES_BLOCK_LEN; 500 out.cd_raw.iov_base = (char *)pLastPart; 501 out.cd_raw.iov_len = DES_BLOCK_LEN; 502 503 /* Decrypt final block of data. */ 504 rc = des_decrypt_contiguous_blocks( 505 (des_ctx_t *)soft_des_ctx->des_cbc, 506 (char *)pLastPart, DES_BLOCK_LEN, &out); 507 508 if (rc == 0) { 509 /* 510 * Remove padding bytes after decryption of 511 * ciphertext block to produce the original 512 * plaintext. 513 */ 514 rv = soft_remove_pkcs7_padding(pLastPart, 515 DES_BLOCK_LEN, &out_len); 516 if (rv != CKR_OK) 517 *pulLastPartLen = 0; 518 else 519 *pulLastPartLen = out_len; 520 } else { 521 *pulLastPartLen = 0; 522 rv = CKR_FUNCTION_FAILED; 523 } 524 525 /* Cleanup memory space. */ 526 free(soft_des_ctx->des_cbc); 527 freezero(soft_des_ctx->key_sched, 528 soft_des_ctx->keysched_len); 529 530 } 531 532 break; 533 } 534 535 case CKM_DES_CBC: 536 case CKM_DES_ECB: 537 case CKM_DES3_CBC: 538 case CKM_DES3_ECB: 539 { 540 541 soft_des_ctx_t *soft_des_ctx; 542 543 soft_des_ctx = (soft_des_ctx_t *)session_p->decrypt.context; 544 /* 545 * CKM_DES_CBC and CKM_DES_ECB does not do any padding, 546 * so when the final is called, the remaining buffer 547 * should not contain any more data. 548 */ 549 *pulLastPartLen = 0; 550 if (soft_des_ctx->remain_len != 0) { 551 rv = CKR_ENCRYPTED_DATA_LEN_RANGE; 552 } else { 553 if (pLastPart == NULL) 554 goto clean2; 555 } 556 557 /* Cleanup memory space. */ 558 free(soft_des_ctx->des_cbc); 559 freezero(soft_des_ctx->key_sched, 560 soft_des_ctx->keysched_len); 561 562 break; 563 } 564 565 case CKM_AES_CBC_PAD: 566 case CKM_AES_CBC: 567 case CKM_AES_ECB: 568 case CKM_AES_CTR: 569 case CKM_AES_CCM: 570 case CKM_AES_GCM: 571 rv = soft_aes_decrypt_final(session_p, pLastPart, 572 pulLastPartLen); 573 break; 574 575 case CKM_BLOWFISH_CBC: 576 { 577 soft_blowfish_ctx_t *soft_blowfish_ctx; 578 579 soft_blowfish_ctx = 580 (soft_blowfish_ctx_t *)session_p->decrypt.context; 581 582 *pulLastPartLen = 0; 583 if (soft_blowfish_ctx->remain_len != 0) 584 rv = CKR_ENCRYPTED_DATA_LEN_RANGE; 585 else { 586 if (pLastPart == NULL) 587 goto clean2; 588 } 589 590 free(soft_blowfish_ctx->blowfish_cbc); 591 freezero(soft_blowfish_ctx->key_sched, 592 soft_blowfish_ctx->keysched_len); 593 594 break; 595 } 596 597 case CKM_RC4: 598 { 599 ARCFour_key *key = (ARCFour_key *)session_p->decrypt.context; 600 explicit_bzero(key, sizeof (*key)); 601 *pulLastPartLen = 0; 602 break; 603 } 604 605 default: 606 /* PKCS11: The mechanism only supports single-part operation. */ 607 rv = CKR_MECHANISM_INVALID; 608 break; 609 } 610 611 clean1: 612 free(session_p->decrypt.context); 613 session_p->decrypt.context = NULL; 614 615 clean2: 616 (void) pthread_mutex_unlock(&session_p->session_mutex); 617 618 return (rv); 619 620 } 621