xref: /illumos-gate/usr/src/lib/pkcs11/pkcs11_softtoken/common/softARCFourCrypt.c (revision 581cede61ac9c14d8d4ea452562a567189eead78)
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 2003 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 <security/pkcs11.h>
36 #include <arcfour.h>
37 #include "softSession.h"
38 #include "softObject.h"
39 #include "softCrypt.h"
40 
41 
42 /*
43  * Allocate the ARCFour key stream for the active encryption or decryption
44  * operation.
45  */
46 CK_RV
47 soft_arcfour_crypt_init(soft_session_t *session_p, CK_MECHANISM_PTR pMechanism,
48     soft_object_t *key_p, boolean_t encrypt)
49 {
50 
51 	uint8_t *keyval;
52 	int keyvallen;
53 	ARCFour_key *keystream;
54 	crypto_active_op_t *active_op;
55 
56 #ifdef	__sparcv9
57 	/* LINTED */
58 	keyvallen = (int)OBJ_SEC_VALUE_LEN(key_p);
59 #else	/* !__sparcv9 */
60 	keyvallen = OBJ_SEC_VALUE_LEN(key_p);
61 #endif	/* __sparcv9 */
62 
63 	if ((keyvallen < ARCFOUR_MIN_KEY_BYTES) ||
64 	    (keyvallen > ARCFOUR_MAX_KEY_BYTES))
65 		return (CKR_KEY_SIZE_RANGE);
66 
67 	keyval = OBJ_SEC_VALUE(key_p);
68 
69 	if (keyval == NULL)
70 		return (CKR_KEY_TYPE_INCONSISTENT);
71 
72 	keystream = malloc(sizeof (ARCFour_key));
73 	if (keystream == NULL) {
74 		return (CKR_HOST_MEMORY);
75 	}
76 	arcfour_key_init(keystream, keyval, keyvallen);
77 
78 	(void) pthread_mutex_lock(&session_p->session_mutex);
79 	active_op = (encrypt) ? &(session_p->encrypt) : &(session_p->decrypt);
80 	active_op->context = keystream;
81 	active_op->mech.mechanism = pMechanism->mechanism;
82 	(void) pthread_mutex_unlock(&session_p->session_mutex);
83 
84 	return (CKR_OK);
85 }
86 
87 
88 /*
89  * soft_arcfour_crypt()
90  *
91  * Arguments:
92  *      active_op:	pointer to the actiove operation in the session
93  *	input:		pointer to the input data to be transformed
94  *	inputlen:	length of the input.
95  *	output:		pointer to the output storage.
96  *	outputlenp:	pointer to the length of the output
97  *
98  * Description:
99  *      Encrypts/Decrypts the 'input' and gets the result in the 'output'
100  *
101  * Returns:
102  *      CKR_OK: success
103  *      CKR_BUFFER_TOO_SMALL: the output buffer provided by application
104  *			      is too small
105  */
106 CK_RV
107 soft_arcfour_crypt(crypto_active_op_t *active_op, CK_BYTE_PTR input,
108     CK_ULONG inputlen, CK_BYTE_PTR output, CK_ULONG_PTR outputlenp)
109 {
110 	ARCFour_key *keystream = active_op->context;
111 
112 	/*
113 	 * If application asks for the length of the output buffer
114 	 * to hold the transformed text
115 	 */
116 	if (output == NULL) {
117 		*outputlenp = inputlen;
118 		return (CKR_OK);
119 	}
120 
121 	/* Is the application-supplied buffer large enough? */
122 	if (*outputlenp < inputlen) {
123 		*outputlenp = inputlen;
124 		return (CKR_BUFFER_TOO_SMALL);
125 	}
126 	arcfour_crypt(keystream, input, output, inputlen);
127 	*outputlenp = inputlen;
128 
129 	return (CKR_OK);
130 }
131