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, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 #include <stdlib.h> 30 #include <strings.h> 31 #include <sys/types.h> 32 #include <security/cryptoki.h> 33 #include "softObject.h" 34 #include "softOps.h" 35 #include "softSession.h" 36 #include "softMAC.h" 37 #include "softRSA.h" 38 #include "softDSA.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 68 return (soft_hmac_sign_verify_init_common(session_p, 69 pMechanism, key_p, B_TRUE)); 70 71 case CKM_RSA_X_509: 72 case CKM_RSA_PKCS: 73 case CKM_MD5_RSA_PKCS: 74 case CKM_SHA1_RSA_PKCS: 75 76 return (soft_rsa_sign_verify_init_common(session_p, pMechanism, 77 key_p, B_TRUE)); 78 79 case CKM_DSA: 80 case CKM_DSA_SHA1: 81 82 return (soft_dsa_sign_verify_init_common(session_p, pMechanism, 83 key_p, B_TRUE)); 84 85 case CKM_DES_MAC_GENERAL: 86 case CKM_DES_MAC: 87 88 return (soft_des_sign_verify_init_common(session_p, pMechanism, 89 key_p, B_TRUE)); 90 91 default: 92 return (CKR_MECHANISM_INVALID); 93 } 94 95 } 96 97 98 /* 99 * soft_sign() 100 * 101 * Arguments: 102 * session_p: pointer to soft_session_t struct 103 * pData: pointer to the input data to be signed 104 * ulDataLen: length of the input data 105 * pSignature: pointer to the signature after signing 106 * pulSignatureLen: pointer to the length of the signature 107 * 108 * Description: 109 * called by C_Sign(). This function calls the corresponding 110 * sign routine based on the mechanism. 111 * 112 */ 113 CK_RV 114 soft_sign(soft_session_t *session_p, CK_BYTE_PTR pData, 115 CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, 116 CK_ULONG_PTR pulSignatureLen) 117 { 118 119 CK_MECHANISM_TYPE mechanism = session_p->sign.mech.mechanism; 120 CK_RV rv = CKR_OK; 121 122 switch (mechanism) { 123 124 case CKM_SSL3_MD5_MAC: 125 case CKM_SSL3_SHA1_MAC: 126 case CKM_MD5_HMAC_GENERAL: 127 case CKM_MD5_HMAC: 128 case CKM_SHA_1_HMAC_GENERAL: 129 case CKM_SHA_1_HMAC: 130 { 131 CK_BYTE hmac[SHA1_HASH_SIZE]; /* use the maximum size */ 132 133 if (pSignature != NULL) { 134 /* Pass local buffer to avoid overflow. */ 135 rv = soft_hmac_sign_verify_common(session_p, pData, 136 ulDataLen, hmac, pulSignatureLen, B_TRUE); 137 } else { 138 /* Pass original pSignature, let callee to handle it. */ 139 rv = soft_hmac_sign_verify_common(session_p, pData, 140 ulDataLen, pSignature, pulSignatureLen, B_TRUE); 141 } 142 143 if ((rv == CKR_OK) && (pSignature != NULL)) 144 (void) memcpy(pSignature, hmac, *pulSignatureLen); 145 146 return (rv); 147 } 148 case CKM_DES_MAC_GENERAL: 149 case CKM_DES_MAC: 150 { 151 CK_BYTE signature[DES_BLOCK_LEN]; /* use the maximum size */ 152 153 if (pSignature != NULL) { 154 /* Pass local buffer to avoid overflow. */ 155 rv = soft_des_sign_verify_common(session_p, pData, 156 ulDataLen, signature, pulSignatureLen, B_TRUE, 157 B_FALSE); 158 } else { 159 /* Pass NULL, let callee to handle it. */ 160 rv = soft_des_sign_verify_common(session_p, pData, 161 ulDataLen, NULL, pulSignatureLen, B_TRUE, 162 B_FALSE); 163 } 164 165 if ((rv == CKR_OK) && (pSignature != NULL)) 166 (void) memcpy(pSignature, signature, *pulSignatureLen); 167 168 return (rv); 169 } 170 case CKM_RSA_X_509: 171 case CKM_RSA_PKCS: 172 173 return (soft_rsa_sign_common(session_p, pData, ulDataLen, 174 pSignature, pulSignatureLen, mechanism)); 175 176 case CKM_MD5_RSA_PKCS: 177 case CKM_SHA1_RSA_PKCS: 178 179 return (soft_rsa_digest_sign_common(session_p, pData, ulDataLen, 180 pSignature, pulSignatureLen, mechanism, B_FALSE)); 181 182 case CKM_DSA: 183 184 return (soft_dsa_sign(session_p, pData, ulDataLen, 185 pSignature, pulSignatureLen)); 186 187 case CKM_DSA_SHA1: 188 189 return (soft_dsa_digest_sign_common(session_p, pData, ulDataLen, 190 pSignature, pulSignatureLen, B_FALSE)); 191 192 default: 193 return (CKR_MECHANISM_INVALID); 194 } 195 } 196 197 198 /* 199 * soft_sign_update() 200 * 201 * Arguments: 202 * session_p: pointer to soft_session_t struct 203 * pPart: pointer to the input data to be signed 204 * ulPartLen: length of the input data 205 * 206 * Description: 207 * called by C_SignUpdate(). This function calls the corresponding 208 * sign update routine based on the mechanism. 209 * 210 */ 211 CK_RV 212 soft_sign_update(soft_session_t *session_p, CK_BYTE_PTR pPart, 213 CK_ULONG ulPartLen) 214 { 215 CK_MECHANISM_TYPE mechanism = session_p->sign.mech.mechanism; 216 217 switch (mechanism) { 218 219 case CKM_SSL3_MD5_MAC: 220 case CKM_SSL3_SHA1_MAC: 221 case CKM_MD5_HMAC_GENERAL: 222 case CKM_MD5_HMAC: 223 case CKM_SHA_1_HMAC_GENERAL: 224 case CKM_SHA_1_HMAC: 225 226 return (soft_hmac_sign_verify_update(session_p, pPart, 227 ulPartLen, B_TRUE)); 228 229 case CKM_DES_MAC_GENERAL: 230 case CKM_DES_MAC: 231 232 return (soft_des_mac_sign_verify_update(session_p, pPart, 233 ulPartLen)); 234 235 case CKM_MD5_RSA_PKCS: 236 case CKM_SHA1_RSA_PKCS: 237 /* 238 * The MD5/SHA1 digest value is accumulated in the context 239 * of the multiple-part digesting operation. In the final 240 * operation, the digest is encoded and then perform RSA 241 * signing. 242 */ 243 case CKM_DSA_SHA1: 244 245 return (soft_digest_update(session_p, pPart, ulPartLen)); 246 247 default: 248 /* PKCS11: The mechanism only supports single-part operation. */ 249 return (CKR_MECHANISM_INVALID); 250 } 251 } 252 253 254 /* 255 * soft_sign_final() 256 * 257 * Arguments: 258 * session_p: pointer to soft_session_t struct 259 * pSignature: pointer to the signature after signing 260 * pulSignatureLen: pointer to the length of the signature 261 * 262 * Description: 263 * called by C_SignFinal(). This function calls the corresponding 264 * sign final routine based on the mechanism. 265 * 266 */ 267 CK_RV 268 soft_sign_final(soft_session_t *session_p, CK_BYTE_PTR pSignature, 269 CK_ULONG_PTR pulSignatureLen) 270 { 271 272 CK_MECHANISM_TYPE mechanism = session_p->sign.mech.mechanism; 273 CK_RV rv = CKR_OK; 274 275 switch (mechanism) { 276 277 case CKM_SSL3_MD5_MAC: 278 case CKM_SSL3_SHA1_MAC: 279 case CKM_MD5_HMAC_GENERAL: 280 case CKM_MD5_HMAC: 281 case CKM_SHA_1_HMAC_GENERAL: 282 case CKM_SHA_1_HMAC: 283 { 284 CK_BYTE hmac[SHA1_HASH_SIZE]; /* use the maximum size */ 285 286 if (pSignature != NULL) { 287 /* Pass local buffer to avoid overflow */ 288 rv = soft_hmac_sign_verify_common(session_p, NULL, 289 0, hmac, pulSignatureLen, B_TRUE); 290 } else { 291 /* Pass original pSignature, let callee to handle it. */ 292 rv = soft_hmac_sign_verify_common(session_p, NULL, 293 0, pSignature, pulSignatureLen, B_TRUE); 294 } 295 296 if ((rv == CKR_OK) && (pSignature != NULL)) 297 (void) memcpy(pSignature, hmac, *pulSignatureLen); 298 299 return (rv); 300 } 301 case CKM_DES_MAC_GENERAL: 302 case CKM_DES_MAC: 303 { 304 CK_BYTE signature[DES_BLOCK_LEN]; /* use the maximum size */ 305 306 if (pSignature != NULL) { 307 /* Pass local buffer to avoid overflow. */ 308 rv = soft_des_sign_verify_common(session_p, NULL, 0, 309 signature, pulSignatureLen, B_TRUE, B_TRUE); 310 } else { 311 /* Pass NULL, let callee to handle it. */ 312 rv = soft_des_sign_verify_common(session_p, NULL, 0, 313 NULL, pulSignatureLen, B_TRUE, B_TRUE); 314 } 315 316 if ((rv == CKR_OK) && (pSignature != NULL)) 317 (void) memcpy(pSignature, signature, *pulSignatureLen); 318 319 return (rv); 320 } 321 case CKM_MD5_RSA_PKCS: 322 case CKM_SHA1_RSA_PKCS: 323 324 return (soft_rsa_digest_sign_common(session_p, NULL, 0, 325 pSignature, pulSignatureLen, mechanism, B_TRUE)); 326 327 case CKM_DSA_SHA1: 328 329 return (soft_dsa_digest_sign_common(session_p, NULL, 0, 330 pSignature, pulSignatureLen, B_TRUE)); 331 332 default: 333 /* PKCS11: The mechanism only supports single-part operation. */ 334 return (CKR_MECHANISM_INVALID); 335 } 336 } 337 338 339 CK_RV 340 soft_sign_recover_init(soft_session_t *session_p, CK_MECHANISM_PTR pMechanism, 341 soft_object_t *key_p) 342 { 343 344 switch (pMechanism->mechanism) { 345 346 case CKM_RSA_X_509: 347 case CKM_RSA_PKCS: 348 349 return (soft_rsa_sign_verify_init_common(session_p, pMechanism, 350 key_p, B_TRUE)); 351 352 default: 353 return (CKR_MECHANISM_INVALID); 354 } 355 } 356 357 358 CK_RV 359 soft_sign_recover(soft_session_t *session_p, CK_BYTE_PTR pData, 360 CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, 361 CK_ULONG_PTR pulSignatureLen) 362 { 363 364 CK_MECHANISM_TYPE mechanism = session_p->sign.mech.mechanism; 365 366 switch (mechanism) { 367 368 case CKM_RSA_X_509: 369 case CKM_RSA_PKCS: 370 371 return (soft_rsa_sign_common(session_p, pData, ulDataLen, 372 pSignature, pulSignatureLen, mechanism)); 373 374 default: 375 return (CKR_MECHANISM_INVALID); 376 } 377 } 378 379 /* 380 * This function frees the allocated active crypto context. 381 * It is only called by the first tier of sign/verify routines 382 * and the caller of this function may or may not hold the session mutex. 383 */ 384 void 385 soft_sign_verify_cleanup(soft_session_t *session_p, boolean_t sign, 386 boolean_t lock_held) 387 { 388 389 crypto_active_op_t *active_op; 390 boolean_t lock_true = B_TRUE; 391 392 if (!lock_held) 393 (void) pthread_mutex_lock(&session_p->session_mutex); 394 395 active_op = (sign) ? &(session_p->sign) : &(session_p->verify); 396 397 switch (active_op->mech.mechanism) { 398 399 case CKM_MD5_RSA_PKCS: 400 case CKM_SHA1_RSA_PKCS: 401 case CKM_DSA_SHA1: 402 if (session_p->digest.context != NULL) { 403 free(session_p->digest.context); 404 session_p->digest.context = NULL; 405 session_p->digest.flags = 0; 406 } 407 break; 408 409 case CKM_RSA_PKCS: 410 case CKM_RSA_X_509: 411 case CKM_DSA: 412 break; 413 414 case CKM_SSL3_MD5_MAC: 415 case CKM_SSL3_SHA1_MAC: 416 case CKM_MD5_HMAC_GENERAL: 417 case CKM_MD5_HMAC: 418 case CKM_SHA_1_HMAC_GENERAL: 419 case CKM_SHA_1_HMAC: 420 if (active_op->context != NULL) 421 bzero(active_op->context, sizeof (soft_hmac_ctx_t)); 422 break; 423 case CKM_DES_MAC_GENERAL: 424 case CKM_DES_MAC: 425 if (session_p->encrypt.context != NULL) { 426 free(session_p->encrypt.context); 427 session_p->encrypt.context = NULL; 428 session_p->encrypt.flags = 0; 429 } 430 if (active_op->context != NULL) 431 bzero(active_op->context, sizeof (soft_des_ctx_t)); 432 break; 433 434 } 435 436 if (active_op->context != NULL) { 437 free(active_op->context); 438 active_op->context = NULL; 439 } 440 441 active_op->flags = 0; 442 443 if (!lock_held) 444 SES_REFRELE(session_p, lock_true); 445 } 446