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 2003 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 <string.h> 31 #include <strings.h> 32 #include <sys/types.h> 33 #include <security/cryptoki.h> 34 #include "softObject.h" 35 #include "softOps.h" 36 #include "softSession.h" 37 #include "softMAC.h" 38 #include "softRSA.h" 39 #include "softDSA.h" 40 #include "softCrypt.h" 41 42 /* 43 * soft_verify_init() 44 * 45 * Arguments: 46 * session_p: pointer to soft_session_t struct 47 * pMechanism: pointer to CK_MECHANISM struct provided by application 48 * key_p: pointer to key soft_object_t struct 49 * 50 * Description: 51 * called by C_VerifyInit(). This function calls the corresponding 52 * verify init routine based on the mechanism. 53 * 54 */ 55 CK_RV 56 soft_verify_init(soft_session_t *session_p, CK_MECHANISM_PTR pMechanism, 57 soft_object_t *key_p) 58 { 59 60 switch (pMechanism->mechanism) { 61 62 case CKM_SSL3_MD5_MAC: 63 case CKM_SSL3_SHA1_MAC: 64 case CKM_MD5_HMAC_GENERAL: 65 case CKM_MD5_HMAC: 66 case CKM_SHA_1_HMAC_GENERAL: 67 case CKM_SHA_1_HMAC: 68 69 return (soft_hmac_sign_verify_init_common(session_p, 70 pMechanism, key_p, B_FALSE)); 71 72 case CKM_RSA_X_509: 73 case CKM_RSA_PKCS: 74 case CKM_MD5_RSA_PKCS: 75 case CKM_SHA1_RSA_PKCS: 76 77 return (soft_rsa_sign_verify_init_common(session_p, pMechanism, 78 key_p, B_FALSE)); 79 80 case CKM_DSA: 81 case CKM_DSA_SHA1: 82 83 return (soft_dsa_sign_verify_init_common(session_p, pMechanism, 84 key_p, B_FALSE)); 85 86 case CKM_DES_MAC_GENERAL: 87 case CKM_DES_MAC: 88 89 return (soft_des_sign_verify_init_common(session_p, pMechanism, 90 key_p, B_FALSE)); 91 92 default: 93 return (CKR_MECHANISM_INVALID); 94 } 95 96 } 97 98 99 /* 100 * soft_verify() 101 * 102 * Arguments: 103 * session_p: pointer to soft_session_t struct 104 * pData: pointer to the input data 105 * ulDataLen: length of the input data 106 * pSignature: pointer to the signature 107 * ulSignatureLen: length of the signature 108 * 109 * Description: 110 * called by C_Verify(). This function calls the corresponding 111 * verify routine based on the mechanism. 112 * 113 */ 114 CK_RV 115 soft_verify(soft_session_t *session_p, CK_BYTE_PTR pData, 116 CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, 117 CK_ULONG ulSignatureLen) 118 { 119 120 CK_MECHANISM_TYPE mechanism = session_p->verify.mech.mechanism; 121 CK_RV rv = CKR_OK; 122 123 switch (mechanism) { 124 125 case CKM_SSL3_MD5_MAC: 126 case CKM_SSL3_SHA1_MAC: 127 case CKM_MD5_HMAC_GENERAL: 128 case CKM_MD5_HMAC: 129 case CKM_SHA_1_HMAC_GENERAL: 130 case CKM_SHA_1_HMAC: 131 { 132 CK_ULONG len; 133 CK_BYTE hmac[SHA1_HASH_SIZE]; /* use the maximum size */ 134 soft_hmac_ctx_t *hmac_ctx; 135 136 hmac_ctx = (soft_hmac_ctx_t *)session_p->verify.context; 137 len = hmac_ctx->hmac_len; 138 139 rv = soft_hmac_sign_verify_common(session_p, pData, 140 ulDataLen, hmac, &len, B_FALSE); 141 142 if (rv == CKR_OK) { 143 if (len != ulSignatureLen) { 144 rv = CKR_SIGNATURE_LEN_RANGE; 145 } 146 147 if (memcmp(hmac, pSignature, len) != 0) { 148 rv = CKR_SIGNATURE_INVALID; 149 } 150 } 151 152 return (rv); 153 } 154 case CKM_DES_MAC_GENERAL: 155 case CKM_DES_MAC: 156 { 157 CK_ULONG len; 158 CK_BYTE signature[DES_BLOCK_LEN]; /* use the maximum size */ 159 soft_des_ctx_t *des_ctx; 160 161 des_ctx = (soft_des_ctx_t *)session_p->verify.context; 162 len = des_ctx->mac_len; 163 164 /* Pass local buffer to avoid overflow. */ 165 rv = soft_des_sign_verify_common(session_p, pData, 166 ulDataLen, signature, &len, B_FALSE, B_FALSE); 167 168 if (rv == CKR_OK) { 169 if (len != ulSignatureLen) { 170 rv = CKR_SIGNATURE_LEN_RANGE; 171 } 172 173 if (memcmp(signature, pSignature, len) != 0) { 174 rv = CKR_SIGNATURE_INVALID; 175 } 176 } 177 178 return (rv); 179 } 180 case CKM_RSA_X_509: 181 case CKM_RSA_PKCS: 182 183 return (soft_rsa_verify_common(session_p, pData, ulDataLen, 184 pSignature, ulSignatureLen, mechanism)); 185 186 case CKM_MD5_RSA_PKCS: 187 case CKM_SHA1_RSA_PKCS: 188 189 return (soft_rsa_digest_verify_common(session_p, pData, 190 ulDataLen, pSignature, ulSignatureLen, mechanism, B_FALSE)); 191 192 case CKM_DSA: 193 194 return (soft_dsa_verify(session_p, pData, ulDataLen, 195 pSignature, ulSignatureLen)); 196 197 case CKM_DSA_SHA1: 198 199 return (soft_dsa_digest_verify_common(session_p, pData, 200 ulDataLen, pSignature, ulSignatureLen, B_FALSE)); 201 202 default: 203 return (CKR_MECHANISM_INVALID); 204 } 205 } 206 207 208 /* 209 * soft_verify_update() 210 * 211 * Arguments: 212 * session_p: pointer to soft_session_t struct 213 * pPart: pointer to the input data 214 * ulPartLen: length of the input data 215 * 216 * Description: 217 * called by C_VerifyUpdate(). This function calls the corresponding 218 * verify update routine based on the mechanism. 219 * 220 */ 221 CK_RV 222 soft_verify_update(soft_session_t *session_p, CK_BYTE_PTR pPart, 223 CK_ULONG ulPartLen) 224 { 225 CK_MECHANISM_TYPE mechanism = session_p->verify.mech.mechanism; 226 227 switch (mechanism) { 228 229 case CKM_SSL3_MD5_MAC: 230 case CKM_SSL3_SHA1_MAC: 231 case CKM_MD5_HMAC_GENERAL: 232 case CKM_MD5_HMAC: 233 case CKM_SHA_1_HMAC_GENERAL: 234 case CKM_SHA_1_HMAC: 235 236 return (soft_hmac_sign_verify_update(session_p, pPart, 237 ulPartLen, B_FALSE)); 238 239 case CKM_DES_MAC_GENERAL: 240 case CKM_DES_MAC: 241 242 return (soft_des_mac_sign_verify_update(session_p, pPart, 243 ulPartLen)); 244 245 case CKM_MD5_RSA_PKCS: 246 case CKM_SHA1_RSA_PKCS: 247 /* 248 * The MD5/SHA1 digest value is accumulated in the context 249 * of the multiple-part digesting operation. In the final 250 * operation, the digest is encoded and then perform RSA 251 * verification. 252 */ 253 case CKM_DSA_SHA1: 254 255 return (soft_digest_update(session_p, pPart, ulPartLen)); 256 257 default: 258 /* PKCS11: The mechanism only supports single-part operation. */ 259 return (CKR_MECHANISM_INVALID); 260 } 261 } 262 263 264 /* 265 * soft_verify_final() 266 * 267 * Arguments: 268 * session_p: pointer to soft_session_t struct 269 * pSignature: pointer to the signature 270 * ulSignatureLen: length of the signature 271 * 272 * Description: 273 * called by C_VerifyFinal(). This function calls the corresponding 274 * verify final routine based on the mechanism. 275 * 276 */ 277 CK_RV 278 soft_verify_final(soft_session_t *session_p, CK_BYTE_PTR pSignature, 279 CK_ULONG ulSignatureLen) 280 { 281 282 CK_MECHANISM_TYPE mechanism = session_p->verify.mech.mechanism; 283 CK_RV rv = CKR_OK; 284 285 switch (mechanism) { 286 287 case CKM_SSL3_MD5_MAC: 288 case CKM_SSL3_SHA1_MAC: 289 case CKM_MD5_HMAC_GENERAL: 290 case CKM_MD5_HMAC: 291 case CKM_SHA_1_HMAC_GENERAL: 292 case CKM_SHA_1_HMAC: 293 { 294 CK_ULONG len; 295 CK_BYTE hmac[SHA1_HASH_SIZE]; 296 soft_hmac_ctx_t *hmac_ctx; 297 298 hmac_ctx = (soft_hmac_ctx_t *)session_p->verify.context; 299 len = hmac_ctx->hmac_len; 300 301 rv = soft_hmac_sign_verify_common(session_p, NULL, 0, 302 hmac, &len, B_FALSE); 303 304 if (rv == CKR_OK) { 305 if (len != ulSignatureLen) { 306 rv = CKR_SIGNATURE_LEN_RANGE; 307 } 308 309 if (memcmp(hmac, pSignature, len) != 0) { 310 rv = CKR_SIGNATURE_INVALID; 311 } 312 } 313 314 return (rv); 315 } 316 case CKM_DES_MAC_GENERAL: 317 case CKM_DES_MAC: 318 { 319 CK_ULONG len; 320 CK_BYTE signature[DES_BLOCK_LEN]; /* use the maximum size */ 321 soft_des_ctx_t *des_ctx; 322 323 des_ctx = (soft_des_ctx_t *)session_p->verify.context; 324 len = des_ctx->mac_len; 325 326 /* Pass local buffer to avoid overflow. */ 327 rv = soft_des_sign_verify_common(session_p, NULL, 0, 328 signature, &len, B_FALSE, B_TRUE); 329 330 if (rv == CKR_OK) { 331 if (len != ulSignatureLen) { 332 rv = CKR_SIGNATURE_LEN_RANGE; 333 } 334 335 if (memcmp(signature, pSignature, len) != 0) { 336 rv = CKR_SIGNATURE_INVALID; 337 } 338 } 339 340 return (rv); 341 } 342 case CKM_MD5_RSA_PKCS: 343 case CKM_SHA1_RSA_PKCS: 344 345 return (soft_rsa_digest_verify_common(session_p, NULL, 0, 346 pSignature, ulSignatureLen, mechanism, B_TRUE)); 347 348 case CKM_DSA_SHA1: 349 350 return (soft_dsa_digest_verify_common(session_p, NULL, 0, 351 pSignature, ulSignatureLen, B_TRUE)); 352 353 default: 354 /* PKCS11: The mechanism only supports single-part operation. */ 355 return (CKR_MECHANISM_INVALID); 356 357 } 358 } 359 360 361 CK_RV 362 soft_verify_recover_init(soft_session_t *session_p, CK_MECHANISM_PTR pMechanism, 363 soft_object_t *key_p) 364 { 365 366 switch (pMechanism->mechanism) { 367 368 case CKM_RSA_X_509: 369 case CKM_RSA_PKCS: 370 371 return (soft_rsa_sign_verify_init_common(session_p, pMechanism, 372 key_p, B_FALSE)); 373 374 default: 375 return (CKR_MECHANISM_INVALID); 376 } 377 } 378 379 380 CK_RV 381 soft_verify_recover(soft_session_t *session_p, CK_BYTE_PTR pSignature, 382 CK_ULONG ulSignatureLen, CK_BYTE_PTR pData, CK_ULONG_PTR pulDataLen) 383 { 384 385 CK_MECHANISM_TYPE mechanism = session_p->verify.mech.mechanism; 386 387 switch (mechanism) { 388 389 case CKM_RSA_X_509: 390 case CKM_RSA_PKCS: 391 392 return (soft_rsa_verify_recover(session_p, pSignature, 393 ulSignatureLen, pData, pulDataLen)); 394 395 default: 396 return (CKR_MECHANISM_INVALID); 397 } 398 } 399