xref: /illumos-gate/usr/src/lib/pkcs11/pkcs11_softtoken/common/softSignUtil.c (revision 0a44ef6d9afbfe052a7e975f55ea0d2954b62a82)
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