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 <pthread.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <strings.h>
33 #include <sys/types.h>
34 #include <security/cryptoki.h>
35 #include <des_cbc_crypt.h>
36 #include <aes_cbc_crypt.h>
37 #include <arcfour.h>
38 #include "softSession.h"
39 #include "softObject.h"
40 #include "softOps.h"
41 #include "softCrypt.h"
42 #include "softRSA.h"
43 
44 
45 /*
46  * Remove padding bytes.
47  */
48 CK_RV
49 soft_remove_pkcs7_padding(CK_BYTE *pData, CK_ULONG padded_len,
50     CK_ULONG *pulDataLen, int block_size)
51 {
52 
53 	CK_BYTE  pad_value;
54 
55 	pad_value = pData[padded_len - 1];
56 
57 
58 	/* Make sure there is a valid padding value. */
59 	if ((pad_value == 0) || (pad_value > block_size))
60 	    return (CKR_ENCRYPTED_DATA_INVALID);
61 
62 	*pulDataLen = padded_len - pad_value;
63 	return (CKR_OK);
64 }
65 
66 
67 /*
68  * soft_decrypt_init()
69  *
70  * Arguments:
71  *	session_p:	pointer to soft_session_t struct
72  *	pMechanism:	pointer to CK_MECHANISM struct provided by application
73  *	key_p:		pointer to key soft_object_t struct
74  *
75  * Description:
76  *	called by C_DecryptInit(). This function calls the corresponding
77  *	decrypt init routine based on the mechanism.
78  *
79  * Returns:
80  *	CKR_OK: success
81  *	CKR_HOST_MEMORY: run out of system memory
82  *	CKR_MECHANISM_PARAM_INVALID: invalid parameters in mechanism
83  *	CKR_MECHANISM_INVALID: invalid mechanism type
84  *	CKR_KEY_TYPE_INCONSISTENT: incorrect type of key to use
85  *				   with the specified mechanism
86  */
87 CK_RV
88 soft_decrypt_init(soft_session_t *session_p, CK_MECHANISM_PTR pMechanism,
89     soft_object_t *key_p)
90 {
91 
92 	CK_RV rv;
93 
94 	switch (pMechanism->mechanism) {
95 
96 	case CKM_DES_ECB:
97 
98 		if (key_p->key_type != CKK_DES) {
99 			return (CKR_KEY_TYPE_INCONSISTENT);
100 		}
101 
102 		goto ecb_common;
103 
104 	case CKM_DES3_ECB:
105 
106 		if ((key_p->key_type != CKK_DES2) &&
107 		    (key_p->key_type != CKK_DES3)) {
108 			return (CKR_KEY_TYPE_INCONSISTENT);
109 		}
110 
111 ecb_common:
112 
113 		return (soft_des_crypt_init_common(session_p, pMechanism,
114 		    key_p, B_FALSE));
115 
116 	case CKM_DES_CBC:
117 	case CKM_DES_CBC_PAD:
118 
119 		if (key_p->key_type != CKK_DES) {
120 			return (CKR_KEY_TYPE_INCONSISTENT);
121 		}
122 
123 		goto cbc_common;
124 
125 	case CKM_DES3_CBC:
126 	case CKM_DES3_CBC_PAD:
127 	{
128 		soft_des_ctx_t *soft_des_ctx;
129 
130 		if ((key_p->key_type != CKK_DES2) &&
131 		    (key_p->key_type != CKK_DES3)) {
132 			return (CKR_KEY_TYPE_INCONSISTENT);
133 		}
134 
135 cbc_common:
136 		if ((pMechanism->pParameter == NULL) ||
137 		    (pMechanism->ulParameterLen != DES_BLOCK_LEN)) {
138 			return (CKR_MECHANISM_PARAM_INVALID);
139 		}
140 
141 		rv = soft_des_crypt_init_common(session_p, pMechanism,
142 		    key_p, B_FALSE);
143 
144 		if (rv != CKR_OK)
145 			return (rv);
146 
147 		(void) pthread_mutex_lock(&session_p->session_mutex);
148 
149 		soft_des_ctx = (soft_des_ctx_t *)session_p->decrypt.context;
150 		/* Save Initialization Vector (IV) in the context. */
151 		(void) memcpy(soft_des_ctx->ivec, pMechanism->pParameter,
152 		    DES_BLOCK_LEN);
153 
154 		/* Allocate a context for DES cipher-block chaining. */
155 		soft_des_ctx->des_cbc = (void *)des_cbc_ctx_init(
156 		    soft_des_ctx->key_sched, soft_des_ctx->keysched_len,
157 		    soft_des_ctx->ivec, key_p->key_type);
158 
159 		if (soft_des_ctx->des_cbc == NULL) {
160 			bzero(soft_des_ctx->key_sched,
161 			    soft_des_ctx->keysched_len);
162 			free(soft_des_ctx->key_sched);
163 			free(session_p->decrypt.context);
164 			session_p->decrypt.context = NULL;
165 			(void) pthread_mutex_unlock(&session_p->session_mutex);
166 			return (CKR_HOST_MEMORY);
167 		}
168 
169 		(void) pthread_mutex_unlock(&session_p->session_mutex);
170 
171 		return (rv);
172 	}
173 	case CKM_AES_ECB:
174 
175 		if (key_p->key_type != CKK_AES) {
176 			return (CKR_KEY_TYPE_INCONSISTENT);
177 		}
178 
179 		return (soft_aes_crypt_init_common(session_p, pMechanism,
180 		    key_p, B_FALSE));
181 
182 	case CKM_AES_CBC:
183 	case CKM_AES_CBC_PAD:
184 	{
185 		soft_aes_ctx_t *soft_aes_ctx;
186 
187 		if (key_p->key_type != CKK_AES) {
188 			return (CKR_KEY_TYPE_INCONSISTENT);
189 		}
190 
191 		if ((pMechanism->pParameter == NULL) ||
192 		    (pMechanism->ulParameterLen != AES_BLOCK_LEN)) {
193 			return (CKR_MECHANISM_PARAM_INVALID);
194 		}
195 
196 		rv = soft_aes_crypt_init_common(session_p, pMechanism,
197 		    key_p, B_FALSE);
198 
199 		if (rv != CKR_OK)
200 			return (rv);
201 
202 		(void) pthread_mutex_lock(&session_p->session_mutex);
203 
204 		soft_aes_ctx = (soft_aes_ctx_t *)session_p->decrypt.context;
205 
206 		/* Save Initialization Vector (IV) in the context. */
207 		(void) memcpy(soft_aes_ctx->ivec, pMechanism->pParameter,
208 		    AES_BLOCK_LEN);
209 
210 		/* Allocate a context for AES cipher-block chaining. */
211 		soft_aes_ctx->aes_cbc = (void *)aes_cbc_ctx_init(
212 		    soft_aes_ctx->key_sched, soft_aes_ctx->keysched_len,
213 		    soft_aes_ctx->ivec);
214 
215 		if (soft_aes_ctx->aes_cbc == NULL) {
216 			bzero(soft_aes_ctx->key_sched,
217 			    soft_aes_ctx->keysched_len);
218 			free(soft_aes_ctx->key_sched);
219 			free(session_p->decrypt.context);
220 			session_p->decrypt.context = NULL;
221 			(void) pthread_mutex_unlock(&session_p->session_mutex);
222 			return (CKR_HOST_MEMORY);
223 		}
224 
225 		(void) pthread_mutex_unlock(&session_p->session_mutex);
226 
227 		return (rv);
228 	}
229 
230 	case CKM_RC4:
231 
232 		if (key_p->key_type != CKK_RC4) {
233 			return (CKR_KEY_TYPE_INCONSISTENT);
234 		}
235 
236 		return (soft_arcfour_crypt_init(session_p, pMechanism, key_p,
237 		    B_FALSE));
238 
239 	case CKM_RSA_X_509:
240 	case CKM_RSA_PKCS:
241 
242 		if (key_p->key_type != CKK_RSA) {
243 			return (CKR_KEY_TYPE_INCONSISTENT);
244 		}
245 
246 		return (soft_rsa_crypt_init_common(session_p, pMechanism,
247 		    key_p, B_FALSE));
248 
249 	default:
250 		return (CKR_MECHANISM_INVALID);
251 	}
252 }
253 
254 
255 /*
256  * soft_decrypt_common()
257  *
258  * Arguments:
259  *      session_p:	pointer to soft_session_t struct
260  *	pEncrypted:	pointer to the encrypted data as input
261  *	ulEncryptedLen:	length of the input data
262  *	pData:		pointer to the output data contains plaintext
263  *	pulDataLen:	pointer to the length of the output data
264  *	Update:		boolean flag indicates caller is soft_decrypt
265  *			or soft_decrypt_update
266  *
267  * Description:
268  *      This function calls the corresponding decrypt routine based
269  *	on the mechanism.
270  *
271  * Returns:
272  *	see soft_decrypt_common().
273  */
274 CK_RV
275 soft_decrypt_common(soft_session_t *session_p, CK_BYTE_PTR pEncrypted,
276     CK_ULONG ulEncryptedLen, CK_BYTE_PTR pData,
277     CK_ULONG_PTR pulDataLen, boolean_t Update)
278 {
279 
280 	CK_MECHANISM_TYPE mechanism = session_p->decrypt.mech.mechanism;
281 
282 	switch (mechanism) {
283 
284 	case CKM_DES_ECB:
285 	case CKM_DES_CBC:
286 	case CKM_DES_CBC_PAD:
287 	case CKM_DES3_ECB:
288 	case CKM_DES3_CBC:
289 	case CKM_DES3_CBC_PAD:
290 
291 		return (soft_des_decrypt_common(session_p, pEncrypted,
292 		    ulEncryptedLen, pData, pulDataLen, Update));
293 
294 	case CKM_AES_ECB:
295 	case CKM_AES_CBC:
296 	case CKM_AES_CBC_PAD:
297 
298 		return (soft_aes_decrypt_common(session_p, pEncrypted,
299 		    ulEncryptedLen, pData, pulDataLen, Update));
300 
301 	case CKM_RC4:
302 	{
303 		ARCFour_key *keystream = session_p->decrypt.context;
304 		CK_RV rv;
305 
306 		rv = soft_arcfour_crypt(&(session_p->decrypt), pEncrypted,
307 		    ulEncryptedLen, pData, pulDataLen);
308 
309 		if ((rv == CKR_OK) && (pData != NULL)) {
310 			bzero(keystream, sizeof (*keystream));
311 			free(keystream);
312 			session_p->decrypt.context = NULL;
313 		}
314 		return (rv);
315 	}
316 
317 	case CKM_RSA_X_509:
318 	case CKM_RSA_PKCS:
319 
320 		return (soft_rsa_decrypt_common(session_p, pEncrypted,
321 		    ulEncryptedLen, pData, pulDataLen, mechanism));
322 
323 	default:
324 		return (CKR_MECHANISM_INVALID);
325 
326 	}
327 }
328 
329 
330 /*
331  * soft_decrypt()
332  *
333  * Arguments:
334  *      session_p:	pointer to soft_session_t struct
335  *	pEncryptedData: pointer to the encrypted data as input
336  *	ulEncryptedDataLen: length of the input data
337  *	pData:		pointer to the output data contains plaintext
338  *	pulDataLen:	pointer to the length of the output data
339  *
340  * Description:
341  *      called by C_Decrypt(). This function calls the soft_decrypt_common
342  *	routine.
343  *
344  * Returns:
345  *	see soft_decrypt_common().
346  */
347 CK_RV
348 soft_decrypt(soft_session_t *session_p, CK_BYTE_PTR pEncryptedData,
349     CK_ULONG ulEncryptedDataLen, CK_BYTE_PTR pData,
350     CK_ULONG_PTR pulDataLen)
351 {
352 
353 	return (soft_decrypt_common(session_p, pEncryptedData,
354 	    ulEncryptedDataLen, pData, pulDataLen, B_FALSE));
355 }
356 
357 
358 /*
359  * soft_decrypt_update()
360  *
361  * Arguments:
362  *      session_p:	pointer to soft_session_t struct
363  *	pEncryptedPart: pointer to the encrypted data as input
364  *	ulEncryptedPartLen: length of the input data
365  *	pPart:          pointer to the output data contains plaintext
366  *	pulPartLen:     pointer to the length of the output data
367  *
368  * Description:
369  *      called by C_DecryptUpdate(). This function calls the
370  *	soft_decrypt_common routine (with update flag on).
371  *
372  * Returns:
373  *	see soft_decrypt_common().
374  */
375 CK_RV
376 soft_decrypt_update(soft_session_t *session_p, CK_BYTE_PTR pEncryptedPart,
377 	CK_ULONG ulEncryptedPartLen, CK_BYTE_PTR pPart,
378 	CK_ULONG_PTR pulPartLen)
379 {
380 
381 	CK_MECHANISM_TYPE mechanism = session_p->decrypt.mech.mechanism;
382 
383 	switch (mechanism) {
384 
385 	case CKM_DES_ECB:
386 	case CKM_DES_CBC:
387 	case CKM_DES_CBC_PAD:
388 	case CKM_DES3_ECB:
389 	case CKM_DES3_CBC:
390 	case CKM_DES3_CBC_PAD:
391 	case CKM_AES_ECB:
392 	case CKM_AES_CBC:
393 	case CKM_AES_CBC_PAD:
394 
395 		return (soft_decrypt_common(session_p, pEncryptedPart,
396 		    ulEncryptedPartLen, pPart, pulPartLen, B_TRUE));
397 
398 	case CKM_RC4:
399 
400 		return (soft_arcfour_crypt(&(session_p->decrypt),
401 		    pEncryptedPart, ulEncryptedPartLen, pPart, pulPartLen));
402 
403 	default:
404 		/* PKCS11: The mechanism only supports single-part operation. */
405 		return (CKR_MECHANISM_INVALID);
406 	}
407 
408 }
409 
410 
411 /*
412  * soft_decrypt_final()
413  *
414  * Arguments:
415  *      session_p:	pointer to soft_session_t struct
416  *      pLastPart:	pointer to the last recovered data part
417  *      pulLastPartLen:	pointer to the length of the last recovered data part
418  *
419  * Description:
420  *      called by C_DecryptFinal().
421  *
422  * Returns:
423  *	CKR_OK: success
424  *	CKR_FUNCTION_FAILED: decrypt final function failed
425  *	CKR_ENCRYPTED_DATA_LEN_RANGE: remaining buffer contains bad length
426  */
427 CK_RV
428 soft_decrypt_final(soft_session_t *session_p, CK_BYTE_PTR pLastPart,
429 	CK_ULONG_PTR pulLastPartLen)
430 {
431 
432 	CK_MECHANISM_TYPE mechanism = session_p->decrypt.mech.mechanism;
433 	CK_ULONG out_len;
434 	CK_RV rv = CKR_OK;
435 	int rc;
436 
437 	(void) pthread_mutex_lock(&session_p->session_mutex);
438 
439 	if (session_p->decrypt.context == NULL) {
440 		rv = CKR_OPERATION_NOT_INITIALIZED;
441 		*pulLastPartLen = 0;
442 		goto clean2;
443 	}
444 	switch (mechanism) {
445 
446 	case CKM_DES_CBC_PAD:
447 	case CKM_DES3_CBC_PAD:
448 	{
449 
450 		soft_des_ctx_t *soft_des_ctx;
451 
452 		soft_des_ctx = (soft_des_ctx_t *)session_p->decrypt.context;
453 
454 		/*
455 		 * We should have only one block of data left in the
456 		 * remaining buffer.
457 		 */
458 		if (soft_des_ctx->remain_len != DES_BLOCK_LEN) {
459 			*pulLastPartLen = 0;
460 			rv = CKR_ENCRYPTED_DATA_LEN_RANGE;
461 			/* Cleanup memory space. */
462 			free(soft_des_ctx->des_cbc);
463 			bzero(soft_des_ctx->key_sched,
464 			    soft_des_ctx->keysched_len);
465 			free(soft_des_ctx->key_sched);
466 
467 			goto clean1;
468 		}
469 
470 		out_len = DES_BLOCK_LEN;
471 
472 		/*
473 		 * If application asks for the length of the output buffer
474 		 * to hold the plaintext?
475 		 */
476 		if (pLastPart == NULL) {
477 			*pulLastPartLen = out_len;
478 			rv = CKR_OK;
479 			goto clean2;
480 		} else {
481 			crypto_data_t out;
482 
483 			/* Copy remaining data to the output buffer. */
484 			(void) memcpy(pLastPart, soft_des_ctx->data,
485 			    DES_BLOCK_LEN);
486 
487 			out.cd_format = CRYPTO_DATA_RAW;
488 			out.cd_offset = 0;
489 			out.cd_length = DES_BLOCK_LEN;
490 			out.cd_raw.iov_base = (char *)pLastPart;
491 			out.cd_raw.iov_len = DES_BLOCK_LEN;
492 
493 			/* Decrypt final block of data. */
494 			rc = des_decrypt_contiguous_blocks(
495 			    (des_ctx_t *)soft_des_ctx->des_cbc,
496 			    (char *)pLastPart, DES_BLOCK_LEN, &out);
497 
498 			if (rc == 0) {
499 				/*
500 				 * Remove padding bytes after decryption of
501 				 * ciphertext block to produce the original
502 				 * plaintext.
503 				 */
504 				rv = soft_remove_pkcs7_padding(pLastPart,
505 				    DES_BLOCK_LEN, &out_len, DES_BLOCK_LEN);
506 				if (rv != CKR_OK)
507 					*pulLastPartLen = 0;
508 				else
509 					*pulLastPartLen = out_len;
510 			} else {
511 				*pulLastPartLen = 0;
512 				rv = CKR_FUNCTION_FAILED;
513 			}
514 
515 			/* Cleanup memory space. */
516 			free(soft_des_ctx->des_cbc);
517 			bzero(soft_des_ctx->key_sched,
518 			    soft_des_ctx->keysched_len);
519 			free(soft_des_ctx->key_sched);
520 
521 		}
522 
523 		break;
524 	}
525 
526 	case CKM_DES_CBC:
527 	case CKM_DES_ECB:
528 	case CKM_DES3_CBC:
529 	case CKM_DES3_ECB:
530 	{
531 
532 		soft_des_ctx_t *soft_des_ctx;
533 
534 		soft_des_ctx = (soft_des_ctx_t *)session_p->decrypt.context;
535 		/*
536 		 * CKM_DES_CBC and CKM_DES_ECB does not do any padding,
537 		 * so when the final is called, the remaining buffer
538 		 * should not contain any more data.
539 		 */
540 		*pulLastPartLen = 0;
541 		if (soft_des_ctx->remain_len != 0) {
542 			rv = CKR_ENCRYPTED_DATA_LEN_RANGE;
543 		} else {
544 			if (pLastPart == NULL)
545 				goto clean2;
546 		}
547 
548 		/* Cleanup memory space. */
549 		free(soft_des_ctx->des_cbc);
550 		bzero(soft_des_ctx->key_sched, soft_des_ctx->keysched_len);
551 		free(soft_des_ctx->key_sched);
552 
553 		break;
554 	}
555 
556 	case CKM_AES_CBC_PAD:
557 	{
558 
559 		soft_aes_ctx_t *soft_aes_ctx;
560 
561 		soft_aes_ctx = (soft_aes_ctx_t *)session_p->decrypt.context;
562 
563 		/*
564 		 * We should have only one block of data left in the
565 		 * remaining buffer.
566 		 */
567 		if (soft_aes_ctx->remain_len != AES_BLOCK_LEN) {
568 			*pulLastPartLen = 0;
569 			rv = CKR_ENCRYPTED_DATA_LEN_RANGE;
570 			/* Cleanup memory space. */
571 			free(soft_aes_ctx->aes_cbc);
572 			bzero(soft_aes_ctx->key_sched,
573 			    soft_aes_ctx->keysched_len);
574 			free(soft_aes_ctx->key_sched);
575 
576 			goto clean1;
577 		}
578 
579 		out_len = AES_BLOCK_LEN;
580 
581 		/*
582 		 * If application asks for the length of the output buffer
583 		 * to hold the plaintext?
584 		 */
585 		if (pLastPart == NULL) {
586 			*pulLastPartLen = out_len;
587 			rv = CKR_OK;
588 			goto clean2;
589 		} else {
590 			crypto_data_t out;
591 
592 			/* Copy remaining data to the output buffer. */
593 			(void) memcpy(pLastPart, soft_aes_ctx->data,
594 			    AES_BLOCK_LEN);
595 
596 			out.cd_format = CRYPTO_DATA_RAW;
597 			out.cd_offset = 0;
598 			out.cd_length = AES_BLOCK_LEN;
599 			out.cd_raw.iov_base = (char *)pLastPart;
600 			out.cd_raw.iov_len = AES_BLOCK_LEN;
601 
602 			/* Decrypt final block of data. */
603 			rc = aes_decrypt_contiguous_blocks(
604 			    (aes_ctx_t *)soft_aes_ctx->aes_cbc,
605 			    (char *)pLastPart, AES_BLOCK_LEN, &out);
606 
607 			if (rc == 0) {
608 				/*
609 				 * Remove padding bytes after decryption of
610 				 * ciphertext block to produce the original
611 				 * plaintext.
612 				 */
613 				rv = soft_remove_pkcs7_padding(pLastPart,
614 				    AES_BLOCK_LEN, &out_len, AES_BLOCK_LEN);
615 				if (rv != CKR_OK)
616 					*pulLastPartLen = 0;
617 				else
618 					*pulLastPartLen = out_len;
619 			} else {
620 				*pulLastPartLen = 0;
621 				rv = CKR_FUNCTION_FAILED;
622 			}
623 
624 			/* Cleanup memory space. */
625 			free(soft_aes_ctx->aes_cbc);
626 			bzero(soft_aes_ctx->key_sched,
627 			    soft_aes_ctx->keysched_len);
628 			free(soft_aes_ctx->key_sched);
629 
630 		}
631 
632 		break;
633 	}
634 
635 	case CKM_AES_CBC:
636 	case CKM_AES_ECB:
637 	{
638 		soft_aes_ctx_t *soft_aes_ctx;
639 
640 		soft_aes_ctx = (soft_aes_ctx_t *)session_p->decrypt.context;
641 		/*
642 		 * CKM_AES_CBC and CKM_AES_ECB does not do any padding,
643 		 * so when the final is called, the remaining buffer
644 		 * should not contain any more data.
645 		 */
646 		*pulLastPartLen = 0;
647 		if (soft_aes_ctx->remain_len != 0) {
648 			rv = CKR_ENCRYPTED_DATA_LEN_RANGE;
649 		} else {
650 			if (pLastPart == NULL)
651 				goto clean2;
652 		}
653 
654 		/* Cleanup memory space. */
655 		free(soft_aes_ctx->aes_cbc);
656 		bzero(soft_aes_ctx->key_sched, soft_aes_ctx->keysched_len);
657 		free(soft_aes_ctx->key_sched);
658 
659 		break;
660 	}
661 
662 	case CKM_RC4:
663 	{
664 		ARCFour_key *key = (ARCFour_key *)session_p->decrypt.context;
665 		bzero(key, sizeof (*key));
666 		*pulLastPartLen = 0;
667 		break;
668 	}
669 
670 	default:
671 		/* PKCS11: The mechanism only supports single-part operation. */
672 		rv = CKR_MECHANISM_INVALID;
673 		break;
674 	}
675 
676 clean1:
677 	free(session_p->decrypt.context);
678 	session_p->decrypt.context = NULL;
679 
680 clean2:
681 	(void) pthread_mutex_unlock(&session_p->session_mutex);
682 
683 	return (rv);
684 
685 }
686