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_CCM: 174 case CKM_AES_GCM: 175 case CKM_AES_GMAC: 176 return (soft_aes_crypt_init_common(session_p, pMechanism, 177 key_p, B_FALSE)); 178 179 case CKM_BLOWFISH_CBC: 180 { 181 soft_blowfish_ctx_t *soft_blowfish_ctx; 182 183 if (key_p->key_type != CKK_BLOWFISH) 184 return (CKR_KEY_TYPE_INCONSISTENT); 185 186 if ((pMechanism->pParameter == NULL) || 187 (pMechanism->ulParameterLen != BLOWFISH_BLOCK_LEN)) 188 return (CKR_MECHANISM_PARAM_INVALID); 189 190 rv = soft_blowfish_crypt_init_common(session_p, pMechanism, 191 key_p, B_FALSE); 192 193 if (rv != CKR_OK) 194 return (rv); 195 196 (void) pthread_mutex_lock(&session_p->session_mutex); 197 198 soft_blowfish_ctx = 199 (soft_blowfish_ctx_t *)session_p->decrypt.context; 200 201 /* Save Initialization Vector in the context. */ 202 (void) memcpy(soft_blowfish_ctx->ivec, pMechanism->pParameter, 203 BLOWFISH_BLOCK_LEN); 204 205 /* Allocate a context for CBC */ 206 soft_blowfish_ctx->blowfish_cbc = 207 (void *)blowfish_cbc_ctx_init(soft_blowfish_ctx->key_sched, 208 soft_blowfish_ctx->keysched_len, 209 soft_blowfish_ctx->ivec); 210 211 if (soft_blowfish_ctx->blowfish_cbc == NULL) { 212 freezero(soft_blowfish_ctx->key_sched, 213 soft_blowfish_ctx->keysched_len); 214 freezero(session_p->decrypt.context, 215 sizeof (soft_blowfish_ctx_t)); 216 session_p->decrypt.context = NULL; 217 (void) pthread_mutex_unlock(&session_p->session_mutex); 218 return (CKR_HOST_MEMORY); 219 } 220 221 (void) pthread_mutex_unlock(&session_p->session_mutex); 222 return (rv); 223 } 224 225 case CKM_RC4: 226 227 if (key_p->key_type != CKK_RC4) { 228 return (CKR_KEY_TYPE_INCONSISTENT); 229 } 230 231 return (soft_arcfour_crypt_init(session_p, pMechanism, key_p, 232 B_FALSE)); 233 234 case CKM_RSA_X_509: 235 case CKM_RSA_PKCS: 236 237 if (key_p->key_type != CKK_RSA) { 238 return (CKR_KEY_TYPE_INCONSISTENT); 239 } 240 241 return (soft_rsa_crypt_init_common(session_p, pMechanism, 242 key_p, B_FALSE)); 243 244 default: 245 return (CKR_MECHANISM_INVALID); 246 } 247 } 248 249 250 /* 251 * soft_decrypt_common() 252 * 253 * Arguments: 254 * session_p: pointer to soft_session_t struct 255 * pEncrypted: pointer to the encrypted data as input 256 * ulEncryptedLen: length of the input data 257 * pData: pointer to the output data contains plaintext 258 * pulDataLen: pointer to the length of the output data 259 * Update: boolean flag indicates caller is soft_decrypt 260 * or soft_decrypt_update 261 * 262 * Description: 263 * This function calls the corresponding decrypt routine based 264 * on the mechanism. 265 * 266 * Returns: 267 * see soft_decrypt_common(). 268 */ 269 CK_RV 270 soft_decrypt_common(soft_session_t *session_p, CK_BYTE_PTR pEncrypted, 271 CK_ULONG ulEncryptedLen, CK_BYTE_PTR pData, 272 CK_ULONG_PTR pulDataLen, boolean_t Update) 273 { 274 275 CK_MECHANISM_TYPE mechanism = session_p->decrypt.mech.mechanism; 276 277 switch (mechanism) { 278 279 case CKM_DES_ECB: 280 case CKM_DES_CBC: 281 case CKM_DES3_ECB: 282 case CKM_DES3_CBC: 283 284 if (ulEncryptedLen == 0) { 285 *pulDataLen = 0; 286 return (CKR_OK); 287 } 288 /* FALLTHROUGH */ 289 290 case CKM_DES_CBC_PAD: 291 case CKM_DES3_CBC_PAD: 292 293 return (soft_des_decrypt_common(session_p, pEncrypted, 294 ulEncryptedLen, pData, pulDataLen, Update)); 295 296 case CKM_AES_ECB: 297 case CKM_AES_CBC: 298 case CKM_AES_CBC_PAD: 299 case CKM_AES_CTR: 300 case CKM_AES_CCM: 301 case CKM_AES_GCM: 302 case CKM_AES_GMAC: 303 if (Update) { 304 return (soft_aes_decrypt_update(session_p, pEncrypted, 305 ulEncryptedLen, pData, pulDataLen)); 306 } else { 307 return (soft_aes_decrypt(session_p, pEncrypted, 308 ulEncryptedLen, pData, pulDataLen)); 309 } 310 311 case CKM_BLOWFISH_CBC: 312 313 if (ulEncryptedLen == 0) { 314 *pulDataLen = 0; 315 return (CKR_OK); 316 } 317 318 return (soft_blowfish_decrypt_common(session_p, pEncrypted, 319 ulEncryptedLen, pData, pulDataLen, Update)); 320 321 case CKM_RC4: 322 323 if (ulEncryptedLen == 0) { 324 *pulDataLen = 0; 325 return (CKR_OK); 326 } 327 328 329 return (soft_arcfour_crypt(&(session_p->decrypt), pEncrypted, 330 ulEncryptedLen, pData, pulDataLen)); 331 332 case CKM_RSA_X_509: 333 case CKM_RSA_PKCS: 334 335 return (soft_rsa_decrypt_common(session_p, pEncrypted, 336 ulEncryptedLen, pData, pulDataLen, mechanism)); 337 338 default: 339 return (CKR_MECHANISM_INVALID); 340 341 } 342 } 343 344 345 /* 346 * soft_decrypt() 347 * 348 * Arguments: 349 * session_p: pointer to soft_session_t struct 350 * pEncryptedData: pointer to the encrypted data as input 351 * ulEncryptedDataLen: length of the input data 352 * pData: pointer to the output data contains plaintext 353 * pulDataLen: pointer to the length of the output data 354 * 355 * Description: 356 * called by C_Decrypt(). This function calls the soft_decrypt_common 357 * routine. 358 * 359 * Returns: 360 * see soft_decrypt_common(). 361 */ 362 CK_RV 363 soft_decrypt(soft_session_t *session_p, CK_BYTE_PTR pEncryptedData, 364 CK_ULONG ulEncryptedDataLen, CK_BYTE_PTR pData, 365 CK_ULONG_PTR pulDataLen) 366 { 367 368 return (soft_decrypt_common(session_p, pEncryptedData, 369 ulEncryptedDataLen, pData, pulDataLen, B_FALSE)); 370 } 371 372 373 /* 374 * soft_decrypt_update() 375 * 376 * Arguments: 377 * session_p: pointer to soft_session_t struct 378 * pEncryptedPart: pointer to the encrypted data as input 379 * ulEncryptedPartLen: length of the input data 380 * pPart: pointer to the output data contains plaintext 381 * pulPartLen: pointer to the length of the output data 382 * 383 * Description: 384 * called by C_DecryptUpdate(). This function calls the 385 * soft_decrypt_common routine (with update flag on). 386 * 387 * Returns: 388 * see soft_decrypt_common(). 389 */ 390 CK_RV 391 soft_decrypt_update(soft_session_t *session_p, CK_BYTE_PTR pEncryptedPart, 392 CK_ULONG ulEncryptedPartLen, CK_BYTE_PTR pPart, CK_ULONG_PTR pulPartLen) 393 { 394 CK_MECHANISM_TYPE mechanism = session_p->decrypt.mech.mechanism; 395 396 switch (mechanism) { 397 398 case CKM_DES_ECB: 399 case CKM_DES_CBC: 400 case CKM_DES_CBC_PAD: 401 case CKM_DES3_ECB: 402 case CKM_DES3_CBC: 403 case CKM_DES3_CBC_PAD: 404 case CKM_AES_ECB: 405 case CKM_AES_CBC: 406 case CKM_AES_CBC_PAD: 407 case CKM_AES_CTR: 408 case CKM_AES_CCM: 409 case CKM_AES_GCM: 410 case CKM_AES_GMAC: 411 case CKM_BLOWFISH_CBC: 412 case CKM_RC4: 413 414 return (soft_decrypt_common(session_p, pEncryptedPart, 415 ulEncryptedPartLen, pPart, pulPartLen, B_TRUE)); 416 417 default: 418 /* PKCS11: The mechanism only supports single-part operation. */ 419 return (CKR_MECHANISM_INVALID); 420 } 421 422 } 423 424 425 /* 426 * soft_decrypt_final() 427 * 428 * Arguments: 429 * session_p: pointer to soft_session_t struct 430 * pLastPart: pointer to the last recovered data part 431 * pulLastPartLen: pointer to the length of the last recovered data part 432 * 433 * Description: 434 * called by C_DecryptFinal(). 435 * 436 * Returns: 437 * CKR_OK: success 438 * CKR_FUNCTION_FAILED: decrypt final function failed 439 * CKR_ENCRYPTED_DATA_LEN_RANGE: remaining buffer contains bad length 440 */ 441 CK_RV 442 soft_decrypt_final(soft_session_t *session_p, CK_BYTE_PTR pLastPart, 443 CK_ULONG_PTR pulLastPartLen) 444 { 445 446 CK_MECHANISM_TYPE mechanism = session_p->decrypt.mech.mechanism; 447 CK_ULONG out_len; 448 CK_RV rv = CKR_OK; 449 int rc; 450 451 (void) pthread_mutex_lock(&session_p->session_mutex); 452 453 if (session_p->decrypt.context == NULL) { 454 rv = CKR_OPERATION_NOT_INITIALIZED; 455 *pulLastPartLen = 0; 456 goto clean2; 457 } 458 switch (mechanism) { 459 460 case CKM_DES_CBC_PAD: 461 case CKM_DES3_CBC_PAD: 462 { 463 464 soft_des_ctx_t *soft_des_ctx; 465 466 soft_des_ctx = (soft_des_ctx_t *)session_p->decrypt.context; 467 468 /* 469 * We should have only one block of data left in the 470 * remaining buffer. 471 */ 472 if (soft_des_ctx->remain_len != DES_BLOCK_LEN) { 473 *pulLastPartLen = 0; 474 rv = CKR_ENCRYPTED_DATA_LEN_RANGE; 475 /* Cleanup memory space. */ 476 free(soft_des_ctx->des_cbc); 477 freezero(soft_des_ctx->key_sched, 478 soft_des_ctx->keysched_len); 479 480 goto clean1; 481 } 482 483 out_len = DES_BLOCK_LEN; 484 485 /* 486 * If application asks for the length of the output buffer 487 * to hold the plaintext? 488 */ 489 if (pLastPart == NULL) { 490 *pulLastPartLen = out_len; 491 rv = CKR_OK; 492 goto clean2; 493 } else { 494 crypto_data_t out; 495 496 /* Copy remaining data to the output buffer. */ 497 (void) memcpy(pLastPart, soft_des_ctx->data, 498 DES_BLOCK_LEN); 499 500 out.cd_format = CRYPTO_DATA_RAW; 501 out.cd_offset = 0; 502 out.cd_length = DES_BLOCK_LEN; 503 out.cd_raw.iov_base = (char *)pLastPart; 504 out.cd_raw.iov_len = DES_BLOCK_LEN; 505 506 /* Decrypt final block of data. */ 507 rc = des_decrypt_contiguous_blocks( 508 (des_ctx_t *)soft_des_ctx->des_cbc, 509 (char *)pLastPart, DES_BLOCK_LEN, &out); 510 511 if (rc == 0) { 512 /* 513 * Remove padding bytes after decryption of 514 * ciphertext block to produce the original 515 * plaintext. 516 */ 517 rv = soft_remove_pkcs7_padding(pLastPart, 518 DES_BLOCK_LEN, &out_len); 519 if (rv != CKR_OK) 520 *pulLastPartLen = 0; 521 else 522 *pulLastPartLen = out_len; 523 } else { 524 *pulLastPartLen = 0; 525 rv = CKR_FUNCTION_FAILED; 526 } 527 528 /* Cleanup memory space. */ 529 free(soft_des_ctx->des_cbc); 530 freezero(soft_des_ctx->key_sched, 531 soft_des_ctx->keysched_len); 532 533 } 534 535 break; 536 } 537 538 case CKM_DES_CBC: 539 case CKM_DES_ECB: 540 case CKM_DES3_CBC: 541 case CKM_DES3_ECB: 542 { 543 544 soft_des_ctx_t *soft_des_ctx; 545 546 soft_des_ctx = (soft_des_ctx_t *)session_p->decrypt.context; 547 /* 548 * CKM_DES_CBC and CKM_DES_ECB does not do any padding, 549 * so when the final is called, the remaining buffer 550 * should not contain any more data. 551 */ 552 *pulLastPartLen = 0; 553 if (soft_des_ctx->remain_len != 0) { 554 rv = CKR_ENCRYPTED_DATA_LEN_RANGE; 555 } else { 556 if (pLastPart == NULL) 557 goto clean2; 558 } 559 560 /* Cleanup memory space. */ 561 free(soft_des_ctx->des_cbc); 562 freezero(soft_des_ctx->key_sched, 563 soft_des_ctx->keysched_len); 564 565 break; 566 } 567 568 case CKM_AES_CBC_PAD: 569 case CKM_AES_CBC: 570 case CKM_AES_ECB: 571 case CKM_AES_CTR: 572 case CKM_AES_CCM: 573 case CKM_AES_GCM: 574 case CKM_AES_GMAC: 575 rv = soft_aes_decrypt_final(session_p, pLastPart, 576 pulLastPartLen); 577 break; 578 579 case CKM_BLOWFISH_CBC: 580 { 581 soft_blowfish_ctx_t *soft_blowfish_ctx; 582 583 soft_blowfish_ctx = 584 (soft_blowfish_ctx_t *)session_p->decrypt.context; 585 586 *pulLastPartLen = 0; 587 if (soft_blowfish_ctx->remain_len != 0) 588 rv = CKR_ENCRYPTED_DATA_LEN_RANGE; 589 else { 590 if (pLastPart == NULL) 591 goto clean2; 592 } 593 594 free(soft_blowfish_ctx->blowfish_cbc); 595 freezero(soft_blowfish_ctx->key_sched, 596 soft_blowfish_ctx->keysched_len); 597 598 break; 599 } 600 601 case CKM_RC4: 602 { 603 ARCFour_key *key = (ARCFour_key *)session_p->decrypt.context; 604 explicit_bzero(key, sizeof (*key)); 605 *pulLastPartLen = 0; 606 break; 607 } 608 609 default: 610 /* PKCS11: The mechanism only supports single-part operation. */ 611 rv = CKR_MECHANISM_INVALID; 612 break; 613 } 614 615 clean1: 616 free(session_p->decrypt.context); 617 session_p->decrypt.context = NULL; 618 619 clean2: 620 (void) pthread_mutex_unlock(&session_p->session_mutex); 621 622 return (rv); 623 624 } 625