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