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