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