xref: /titanic_50/usr/src/lib/pkcs11/pkcs11_softtoken/common/softSignUtil.c (revision bdfc6d18da790deeec2e0eb09c625902defe2498)
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