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 * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #pragma ident "%Z%%M% %I% %E% SMI" 27 28 #include <stdlib.h> 29 #include <strings.h> 30 #include <sys/types.h> 31 #include <security/cryptoki.h> 32 #include "softObject.h" 33 #include "softOps.h" 34 #include "softSession.h" 35 #include "softMAC.h" 36 #include "softRSA.h" 37 #include "softDSA.h" 38 #include "softEC.h" 39 #include "softCrypt.h" 40 41 /* 42 * soft_sign_init() 43 * 44 * Arguments: 45 * session_p: pointer to soft_session_t struct 46 * pMechanism: pointer to CK_MECHANISM struct provided by application 47 * key_p: pointer to key soft_object_t struct 48 * 49 * Description: 50 * called by C_SignInit(). This function calls the corresponding 51 * sign init routine based on the mechanism. 52 * 53 */ 54 CK_RV 55 soft_sign_init(soft_session_t *session_p, CK_MECHANISM_PTR pMechanism, 56 soft_object_t *key_p) 57 { 58 59 switch (pMechanism->mechanism) { 60 61 case CKM_SSL3_MD5_MAC: 62 case CKM_SSL3_SHA1_MAC: 63 case CKM_MD5_HMAC_GENERAL: 64 case CKM_MD5_HMAC: 65 case CKM_SHA_1_HMAC_GENERAL: 66 case CKM_SHA_1_HMAC: 67 case CKM_SHA256_HMAC_GENERAL: 68 case CKM_SHA256_HMAC: 69 case CKM_SHA384_HMAC_GENERAL: 70 case CKM_SHA384_HMAC: 71 case CKM_SHA512_HMAC_GENERAL: 72 case CKM_SHA512_HMAC: 73 74 return (soft_hmac_sign_verify_init_common(session_p, 75 pMechanism, key_p, B_TRUE)); 76 77 case CKM_RSA_X_509: 78 case CKM_RSA_PKCS: 79 case CKM_MD5_RSA_PKCS: 80 case CKM_SHA1_RSA_PKCS: 81 case CKM_SHA256_RSA_PKCS: 82 case CKM_SHA384_RSA_PKCS: 83 case CKM_SHA512_RSA_PKCS: 84 85 return (soft_rsa_sign_verify_init_common(session_p, pMechanism, 86 key_p, B_TRUE)); 87 88 case CKM_DSA: 89 case CKM_DSA_SHA1: 90 91 return (soft_dsa_sign_verify_init_common(session_p, pMechanism, 92 key_p, B_TRUE)); 93 94 case CKM_ECDSA: 95 case CKM_ECDSA_SHA1: 96 97 return (soft_ecc_sign_verify_init_common(session_p, pMechanism, 98 key_p, B_TRUE)); 99 100 case CKM_DES_MAC_GENERAL: 101 case CKM_DES_MAC: 102 103 return (soft_des_sign_verify_init_common(session_p, pMechanism, 104 key_p, B_TRUE)); 105 106 default: 107 return (CKR_MECHANISM_INVALID); 108 } 109 110 } 111 112 113 /* 114 * soft_sign() 115 * 116 * Arguments: 117 * session_p: pointer to soft_session_t struct 118 * pData: pointer to the input data to be signed 119 * ulDataLen: length of the input data 120 * pSignature: pointer to the signature after signing 121 * pulSignatureLen: pointer to the length of the signature 122 * 123 * Description: 124 * called by C_Sign(). This function calls the corresponding 125 * sign routine based on the mechanism. 126 * 127 */ 128 CK_RV 129 soft_sign(soft_session_t *session_p, CK_BYTE_PTR pData, 130 CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, 131 CK_ULONG_PTR pulSignatureLen) 132 { 133 134 CK_MECHANISM_TYPE mechanism = session_p->sign.mech.mechanism; 135 CK_RV rv = CKR_OK; 136 137 switch (mechanism) { 138 139 case CKM_SSL3_MD5_MAC: 140 case CKM_SSL3_SHA1_MAC: 141 case CKM_MD5_HMAC_GENERAL: 142 case CKM_MD5_HMAC: 143 case CKM_SHA_1_HMAC_GENERAL: 144 case CKM_SHA_1_HMAC: 145 case CKM_SHA256_HMAC_GENERAL: 146 case CKM_SHA256_HMAC: 147 case CKM_SHA384_HMAC_GENERAL: 148 case CKM_SHA384_HMAC: 149 case CKM_SHA512_HMAC_GENERAL: 150 case CKM_SHA512_HMAC: 151 { 152 CK_BYTE hmac[SHA512_DIGEST_LENGTH]; /* use the maximum size */ 153 154 if (pSignature != NULL) { 155 /* Pass local buffer to avoid overflow. */ 156 rv = soft_hmac_sign_verify_common(session_p, pData, 157 ulDataLen, hmac, pulSignatureLen, B_TRUE); 158 } else { 159 /* Pass original pSignature, let callee to handle it. */ 160 rv = soft_hmac_sign_verify_common(session_p, pData, 161 ulDataLen, pSignature, pulSignatureLen, B_TRUE); 162 } 163 164 if ((rv == CKR_OK) && (pSignature != NULL)) 165 (void) memcpy(pSignature, hmac, *pulSignatureLen); 166 167 return (rv); 168 } 169 case CKM_DES_MAC_GENERAL: 170 case CKM_DES_MAC: 171 { 172 CK_BYTE signature[DES_BLOCK_LEN]; /* use the maximum size */ 173 174 if (pSignature != NULL) { 175 /* Pass local buffer to avoid overflow. */ 176 rv = soft_des_sign_verify_common(session_p, pData, 177 ulDataLen, signature, pulSignatureLen, B_TRUE, 178 B_FALSE); 179 } else { 180 /* Pass NULL, let callee to handle it. */ 181 rv = soft_des_sign_verify_common(session_p, pData, 182 ulDataLen, NULL, pulSignatureLen, B_TRUE, B_FALSE); 183 } 184 185 if ((rv == CKR_OK) && (pSignature != NULL)) 186 (void) memcpy(pSignature, signature, *pulSignatureLen); 187 188 return (rv); 189 } 190 case CKM_RSA_X_509: 191 case CKM_RSA_PKCS: 192 193 return (soft_rsa_sign_common(session_p, pData, ulDataLen, 194 pSignature, pulSignatureLen, mechanism)); 195 196 case CKM_MD5_RSA_PKCS: 197 case CKM_SHA1_RSA_PKCS: 198 case CKM_SHA256_RSA_PKCS: 199 case CKM_SHA384_RSA_PKCS: 200 case CKM_SHA512_RSA_PKCS: 201 202 return (soft_rsa_digest_sign_common(session_p, pData, ulDataLen, 203 pSignature, pulSignatureLen, mechanism, B_FALSE)); 204 205 case CKM_DSA: 206 207 return (soft_dsa_sign(session_p, pData, ulDataLen, 208 pSignature, pulSignatureLen)); 209 210 case CKM_DSA_SHA1: 211 212 return (soft_dsa_digest_sign_common(session_p, pData, ulDataLen, 213 pSignature, pulSignatureLen, B_FALSE)); 214 215 case CKM_ECDSA: 216 217 return (soft_ecc_sign(session_p, pData, ulDataLen, 218 pSignature, pulSignatureLen)); 219 220 case CKM_ECDSA_SHA1: 221 222 return (soft_ecc_digest_sign_common(session_p, pData, ulDataLen, 223 pSignature, pulSignatureLen, B_FALSE)); 224 225 default: 226 return (CKR_MECHANISM_INVALID); 227 } 228 } 229 230 231 /* 232 * soft_sign_update() 233 * 234 * Arguments: 235 * session_p: pointer to soft_session_t struct 236 * pPart: pointer to the input data to be signed 237 * ulPartLen: length of the input data 238 * 239 * Description: 240 * called by C_SignUpdate(). This function calls the corresponding 241 * sign update routine based on the mechanism. 242 * 243 */ 244 CK_RV 245 soft_sign_update(soft_session_t *session_p, CK_BYTE_PTR pPart, 246 CK_ULONG ulPartLen) 247 { 248 CK_MECHANISM_TYPE mechanism = session_p->sign.mech.mechanism; 249 250 switch (mechanism) { 251 252 case CKM_SSL3_MD5_MAC: 253 case CKM_SSL3_SHA1_MAC: 254 case CKM_MD5_HMAC_GENERAL: 255 case CKM_MD5_HMAC: 256 case CKM_SHA_1_HMAC_GENERAL: 257 case CKM_SHA_1_HMAC: 258 case CKM_SHA256_HMAC_GENERAL: 259 case CKM_SHA256_HMAC: 260 case CKM_SHA384_HMAC_GENERAL: 261 case CKM_SHA384_HMAC: 262 case CKM_SHA512_HMAC_GENERAL: 263 case CKM_SHA512_HMAC: 264 265 return (soft_hmac_sign_verify_update(session_p, pPart, 266 ulPartLen, B_TRUE)); 267 268 case CKM_DES_MAC_GENERAL: 269 case CKM_DES_MAC: 270 271 return (soft_des_mac_sign_verify_update(session_p, pPart, 272 ulPartLen)); 273 274 case CKM_MD5_RSA_PKCS: 275 case CKM_SHA1_RSA_PKCS: 276 case CKM_SHA256_RSA_PKCS: 277 case CKM_SHA384_RSA_PKCS: 278 case CKM_SHA512_RSA_PKCS: 279 /* 280 * The MD5/SHA1 digest value is accumulated in the context 281 * of the multiple-part digesting operation. In the final 282 * operation, the digest is encoded and then perform RSA 283 * signing. 284 */ 285 case CKM_DSA_SHA1: 286 case CKM_ECDSA_SHA1: 287 288 return (soft_digest_update(session_p, pPart, ulPartLen)); 289 290 default: 291 /* PKCS11: The mechanism only supports single-part operation. */ 292 return (CKR_MECHANISM_INVALID); 293 } 294 } 295 296 297 /* 298 * soft_sign_final() 299 * 300 * Arguments: 301 * session_p: pointer to soft_session_t struct 302 * pSignature: pointer to the signature after signing 303 * pulSignatureLen: pointer to the length of the signature 304 * 305 * Description: 306 * called by C_SignFinal(). This function calls the corresponding 307 * sign final routine based on the mechanism. 308 * 309 */ 310 CK_RV 311 soft_sign_final(soft_session_t *session_p, CK_BYTE_PTR pSignature, 312 CK_ULONG_PTR pulSignatureLen) 313 { 314 315 CK_MECHANISM_TYPE mechanism = session_p->sign.mech.mechanism; 316 CK_RV rv = CKR_OK; 317 318 switch (mechanism) { 319 320 case CKM_SSL3_MD5_MAC: 321 case CKM_SSL3_SHA1_MAC: 322 case CKM_MD5_HMAC_GENERAL: 323 case CKM_MD5_HMAC: 324 case CKM_SHA_1_HMAC_GENERAL: 325 case CKM_SHA_1_HMAC: 326 case CKM_SHA256_HMAC_GENERAL: 327 case CKM_SHA256_HMAC: 328 case CKM_SHA384_HMAC_GENERAL: 329 case CKM_SHA384_HMAC: 330 case CKM_SHA512_HMAC_GENERAL: 331 case CKM_SHA512_HMAC: 332 { 333 CK_BYTE hmac[SHA512_DIGEST_LENGTH]; /* use the maximum size */ 334 335 if (pSignature != NULL) { 336 /* Pass local buffer to avoid overflow */ 337 rv = soft_hmac_sign_verify_common(session_p, NULL, 338 0, hmac, pulSignatureLen, B_TRUE); 339 } else { 340 /* Pass original pSignature, let callee to handle it. */ 341 rv = soft_hmac_sign_verify_common(session_p, NULL, 342 0, pSignature, pulSignatureLen, B_TRUE); 343 } 344 345 if ((rv == CKR_OK) && (pSignature != NULL)) 346 (void) memcpy(pSignature, hmac, *pulSignatureLen); 347 348 return (rv); 349 } 350 case CKM_DES_MAC_GENERAL: 351 case CKM_DES_MAC: 352 { 353 CK_BYTE signature[DES_BLOCK_LEN]; /* use the maximum size */ 354 355 if (pSignature != NULL) { 356 /* Pass local buffer to avoid overflow. */ 357 rv = soft_des_sign_verify_common(session_p, NULL, 0, 358 signature, pulSignatureLen, B_TRUE, B_TRUE); 359 } else { 360 /* Pass NULL, let callee to handle it. */ 361 rv = soft_des_sign_verify_common(session_p, NULL, 0, 362 NULL, pulSignatureLen, B_TRUE, B_TRUE); 363 } 364 365 if ((rv == CKR_OK) && (pSignature != NULL)) 366 (void) memcpy(pSignature, signature, *pulSignatureLen); 367 368 return (rv); 369 } 370 case CKM_MD5_RSA_PKCS: 371 case CKM_SHA1_RSA_PKCS: 372 case CKM_SHA256_RSA_PKCS: 373 case CKM_SHA384_RSA_PKCS: 374 case CKM_SHA512_RSA_PKCS: 375 376 return (soft_rsa_digest_sign_common(session_p, NULL, 0, 377 pSignature, pulSignatureLen, mechanism, B_TRUE)); 378 379 case CKM_DSA_SHA1: 380 381 return (soft_dsa_digest_sign_common(session_p, NULL, 0, 382 pSignature, pulSignatureLen, B_TRUE)); 383 384 case CKM_ECDSA_SHA1: 385 386 return (soft_ecc_digest_sign_common(session_p, NULL, 0, 387 pSignature, pulSignatureLen, B_TRUE)); 388 389 default: 390 /* PKCS11: The mechanism only supports single-part operation. */ 391 return (CKR_MECHANISM_INVALID); 392 } 393 } 394 395 396 CK_RV 397 soft_sign_recover_init(soft_session_t *session_p, CK_MECHANISM_PTR pMechanism, 398 soft_object_t *key_p) 399 { 400 401 switch (pMechanism->mechanism) { 402 403 case CKM_RSA_X_509: 404 case CKM_RSA_PKCS: 405 406 return (soft_rsa_sign_verify_init_common(session_p, pMechanism, 407 key_p, B_TRUE)); 408 409 default: 410 return (CKR_MECHANISM_INVALID); 411 } 412 } 413 414 415 CK_RV 416 soft_sign_recover(soft_session_t *session_p, CK_BYTE_PTR pData, 417 CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, 418 CK_ULONG_PTR pulSignatureLen) 419 { 420 421 CK_MECHANISM_TYPE mechanism = session_p->sign.mech.mechanism; 422 423 switch (mechanism) { 424 425 case CKM_RSA_X_509: 426 case CKM_RSA_PKCS: 427 428 return (soft_rsa_sign_common(session_p, pData, ulDataLen, 429 pSignature, pulSignatureLen, mechanism)); 430 431 default: 432 return (CKR_MECHANISM_INVALID); 433 } 434 } 435 436 /* 437 * This function frees the allocated active crypto context. 438 * It is only called by the first tier of sign/verify routines 439 * and the caller of this function may or may not hold the session mutex. 440 */ 441 void 442 soft_sign_verify_cleanup(soft_session_t *session_p, boolean_t sign, 443 boolean_t lock_held) 444 { 445 446 crypto_active_op_t *active_op; 447 boolean_t lock_true = B_TRUE; 448 449 if (!lock_held) 450 (void) pthread_mutex_lock(&session_p->session_mutex); 451 452 active_op = (sign) ? &(session_p->sign) : &(session_p->verify); 453 454 switch (active_op->mech.mechanism) { 455 456 case CKM_MD5_RSA_PKCS: 457 case CKM_SHA1_RSA_PKCS: 458 case CKM_SHA256_RSA_PKCS: 459 case CKM_SHA384_RSA_PKCS: 460 case CKM_SHA512_RSA_PKCS: 461 if (session_p->digest.context != NULL) { 462 free(session_p->digest.context); 463 session_p->digest.context = NULL; 464 session_p->digest.flags = 0; 465 } 466 /* FALLTHRU */ 467 468 case CKM_RSA_PKCS: 469 case CKM_RSA_X_509: 470 { 471 soft_rsa_ctx_t *rsa_ctx = 472 (soft_rsa_ctx_t *)active_op->context; 473 474 if (rsa_ctx != NULL && rsa_ctx->key != NULL) { 475 soft_cleanup_object(rsa_ctx->key); 476 free(rsa_ctx->key); 477 } 478 break; 479 480 } 481 case CKM_DSA_SHA1: 482 if (session_p->digest.context != NULL) { 483 free(session_p->digest.context); 484 session_p->digest.context = NULL; 485 session_p->digest.flags = 0; 486 } 487 488 /* FALLTHRU */ 489 case CKM_DSA: 490 { 491 soft_dsa_ctx_t *dsa_ctx = 492 (soft_dsa_ctx_t *)active_op->context; 493 494 if (dsa_ctx != NULL && dsa_ctx->key != NULL) { 495 soft_cleanup_object(dsa_ctx->key); 496 free(dsa_ctx->key); 497 } 498 break; 499 500 } 501 case CKM_SSL3_MD5_MAC: 502 case CKM_SSL3_SHA1_MAC: 503 case CKM_MD5_HMAC_GENERAL: 504 case CKM_MD5_HMAC: 505 case CKM_SHA_1_HMAC_GENERAL: 506 case CKM_SHA_1_HMAC: 507 case CKM_SHA256_HMAC_GENERAL: 508 case CKM_SHA256_HMAC: 509 case CKM_SHA384_HMAC_GENERAL: 510 case CKM_SHA384_HMAC: 511 case CKM_SHA512_HMAC_GENERAL: 512 case CKM_SHA512_HMAC: 513 if (active_op->context != NULL) 514 bzero(active_op->context, sizeof (soft_hmac_ctx_t)); 515 break; 516 case CKM_DES_MAC_GENERAL: 517 case CKM_DES_MAC: 518 if (session_p->encrypt.context != NULL) { 519 free(session_p->encrypt.context); 520 session_p->encrypt.context = NULL; 521 session_p->encrypt.flags = 0; 522 } 523 if (active_op->context != NULL) 524 bzero(active_op->context, sizeof (soft_des_ctx_t)); 525 break; 526 527 } 528 529 if (active_op->context != NULL) { 530 free(active_op->context); 531 active_op->context = NULL; 532 } 533 534 active_op->flags = 0; 535 536 if (!lock_held) 537 SES_REFRELE(session_p, lock_true); 538 } 539