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  * Copyright 2018, Joyent, Inc.
25  */
26 
27 /*
28  * Encryption and Decryption Functions
29  * (as defined in PKCS#11 spec sections 11.8 and 11.9)
30  */
31 
32 #include "metaGlobal.h"
33 
34 
35 /*
36  * meta_EncryptInit
37  *
38  */
39 CK_RV
meta_EncryptInit(CK_SESSION_HANDLE hSession,CK_MECHANISM_PTR pMechanism,CK_OBJECT_HANDLE hKey)40 meta_EncryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
41     CK_OBJECT_HANDLE hKey)
42 {
43 	CK_RV rv;
44 	meta_session_t *session;
45 	meta_object_t *key;
46 
47 	if (pMechanism == NULL)
48 		return (CKR_ARGUMENTS_BAD);
49 
50 	rv = meta_handle2session(hSession, &session);
51 	if (rv != CKR_OK)
52 		return (rv);
53 
54 	rv = meta_handle2object(hKey, &key);
55 	if (rv != CKR_OK) {
56 		REFRELEASE(session);
57 		return (rv);
58 	}
59 
60 	rv = meta_operation_init_defer(CKF_ENCRYPT, session, pMechanism, key);
61 
62 	OBJRELEASE(key);
63 	REFRELEASE(session);
64 
65 	return (rv);
66 }
67 
68 
69 /*
70  * meta_Encrypt
71  *
72  */
73 CK_RV
meta_Encrypt(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pData,CK_ULONG ulDataLen,CK_BYTE_PTR pEncryptedData,CK_ULONG_PTR pulEncryptedDataLen)74 meta_Encrypt(CK_SESSION_HANDLE hSession,
75     CK_BYTE_PTR pData, CK_ULONG ulDataLen,
76     CK_BYTE_PTR pEncryptedData, CK_ULONG_PTR pulEncryptedDataLen)
77 {
78 	CK_RV rv;
79 	meta_session_t *session;
80 
81 	rv = meta_handle2session(hSession, &session);
82 	if (rv != CKR_OK)
83 		return (rv);
84 
85 	if (pulEncryptedDataLen == NULL) {
86 		meta_operation_cleanup(session, CKF_ENCRYPT, FALSE);
87 		REFRELEASE(session);
88 		return (CKR_ARGUMENTS_BAD);
89 	}
90 
91 	/*
92 	 * Allow pData to be NULL as long as the length is 0 in order to
93 	 * support ciphers that permit 0 byte inputs (e.g. combined mode
94 	 * ciphers), otherwise consider pData being NULL as invalid.
95 	 */
96 	if (pData == NULL && ulDataLen != 0) {
97 		meta_operation_cleanup(session, CKF_ENCRYPT, FALSE);
98 		REFRELEASE(session);
99 		return (CKR_ARGUMENTS_BAD);
100 	}
101 
102 	rv = meta_do_operation(CKF_ENCRYPT, MODE_SINGLE, session, NULL,
103 	    pData, ulDataLen, pEncryptedData, pulEncryptedDataLen);
104 
105 	REFRELEASE(session);
106 
107 	return (rv);
108 }
109 
110 
111 /*
112  * meta_EncryptUpdate
113  *
114  */
115 CK_RV
meta_EncryptUpdate(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pPart,CK_ULONG ulPartLen,CK_BYTE_PTR pEncryptedPart,CK_ULONG_PTR pulEncryptedPartLen)116 meta_EncryptUpdate(CK_SESSION_HANDLE hSession,
117     CK_BYTE_PTR pPart, CK_ULONG ulPartLen,
118     CK_BYTE_PTR pEncryptedPart, CK_ULONG_PTR pulEncryptedPartLen)
119 {
120 	CK_RV rv;
121 	meta_session_t *session;
122 
123 	rv = meta_handle2session(hSession, &session);
124 	if (rv != CKR_OK)
125 		return (rv);
126 
127 	if (pPart == NULL || pulEncryptedPartLen == NULL) {
128 		meta_operation_cleanup(session, CKF_ENCRYPT, FALSE);
129 		REFRELEASE(session);
130 		return (CKR_ARGUMENTS_BAD);
131 	}
132 
133 	rv = meta_do_operation(CKF_ENCRYPT, MODE_UPDATE, session, NULL,
134 	    pPart, ulPartLen, pEncryptedPart, pulEncryptedPartLen);
135 
136 	REFRELEASE(session);
137 
138 	return (rv);
139 }
140 
141 
142 /*
143  * meta_EncryptFinal
144  *
145  */
146 CK_RV
meta_EncryptFinal(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pLastEncryptedPart,CK_ULONG_PTR pulLastEncryptedPartLen)147 meta_EncryptFinal(CK_SESSION_HANDLE hSession,
148     CK_BYTE_PTR pLastEncryptedPart, CK_ULONG_PTR pulLastEncryptedPartLen)
149 {
150 	CK_RV rv;
151 	meta_session_t *session;
152 
153 	rv = meta_handle2session(hSession, &session);
154 	if (rv != CKR_OK)
155 		return (rv);
156 
157 	if (pulLastEncryptedPartLen == NULL) {
158 		meta_operation_cleanup(session, CKF_ENCRYPT, FALSE);
159 		REFRELEASE(session);
160 		return (CKR_ARGUMENTS_BAD);
161 	}
162 
163 	rv = meta_do_operation(CKF_ENCRYPT, MODE_FINAL, session, NULL,
164 	    NULL, 0, pLastEncryptedPart, pulLastEncryptedPartLen);
165 
166 	REFRELEASE(session);
167 
168 	return (rv);
169 }
170 
171 
172 /*
173  * meta_DecryptInit
174  *
175  */
176 CK_RV
meta_DecryptInit(CK_SESSION_HANDLE hSession,CK_MECHANISM_PTR pMechanism,CK_OBJECT_HANDLE hKey)177 meta_DecryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
178     CK_OBJECT_HANDLE hKey)
179 {
180 	CK_RV rv;
181 	meta_session_t *session;
182 	meta_object_t *key;
183 
184 	if (pMechanism == NULL)
185 		return (CKR_ARGUMENTS_BAD);
186 
187 	rv = meta_handle2session(hSession, &session);
188 	if (rv != CKR_OK)
189 		return (rv);
190 
191 	rv = meta_handle2object(hKey, &key);
192 	if (rv != CKR_OK) {
193 		REFRELEASE(session);
194 		return (rv);
195 	}
196 
197 	rv = meta_operation_init_defer(CKF_DECRYPT, session, pMechanism, key);
198 
199 	OBJRELEASE(key);
200 	REFRELEASE(session);
201 
202 	return (rv);
203 }
204 
205 
206 /*
207  * meta_Decrypt
208  *
209  */
210 CK_RV
meta_Decrypt(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pEncryptedData,CK_ULONG ulEncryptedDataLen,CK_BYTE_PTR pData,CK_ULONG_PTR pulDataLen)211 meta_Decrypt(CK_SESSION_HANDLE hSession,
212     CK_BYTE_PTR pEncryptedData, CK_ULONG ulEncryptedDataLen,
213     CK_BYTE_PTR pData, CK_ULONG_PTR pulDataLen)
214 {
215 	CK_RV rv;
216 	meta_session_t *session;
217 
218 	rv = meta_handle2session(hSession, &session);
219 	if (rv != CKR_OK)
220 		return (rv);
221 
222 	if (pEncryptedData == NULL || pulDataLen == NULL) {
223 		meta_operation_cleanup(session, CKF_DECRYPT, FALSE);
224 		REFRELEASE(session);
225 		return (CKR_ARGUMENTS_BAD);
226 	}
227 
228 	rv = meta_do_operation(CKF_DECRYPT, MODE_SINGLE, session, NULL,
229 	    pEncryptedData, ulEncryptedDataLen, pData, pulDataLen);
230 
231 	REFRELEASE(session);
232 
233 	return (rv);
234 }
235 
236 
237 /*
238  * meta_DecryptUpdate
239  *
240  */
241 CK_RV
meta_DecryptUpdate(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pEncryptedPart,CK_ULONG ulEncryptedPartLen,CK_BYTE_PTR pPart,CK_ULONG_PTR pulPartLen)242 meta_DecryptUpdate(CK_SESSION_HANDLE hSession,
243     CK_BYTE_PTR pEncryptedPart, CK_ULONG ulEncryptedPartLen,
244     CK_BYTE_PTR pPart, CK_ULONG_PTR pulPartLen)
245 {
246 	CK_RV rv;
247 	meta_session_t *session;
248 
249 	rv = meta_handle2session(hSession, &session);
250 	if (rv != CKR_OK)
251 		return (rv);
252 
253 	if (pEncryptedPart == NULL || pulPartLen == NULL) {
254 		meta_operation_cleanup(session, CKF_DECRYPT, FALSE);
255 		REFRELEASE(session);
256 		return (CKR_ARGUMENTS_BAD);
257 	}
258 
259 	rv = meta_do_operation(CKF_DECRYPT, MODE_UPDATE, session, NULL,
260 	    pEncryptedPart, ulEncryptedPartLen, pPart, pulPartLen);
261 
262 	REFRELEASE(session);
263 
264 	return (rv);
265 }
266 
267 
268 /*
269  * meta_DecryptFinal
270  *
271  */
272 CK_RV
meta_DecryptFinal(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pLastPart,CK_ULONG_PTR pulLastPartLen)273 meta_DecryptFinal(CK_SESSION_HANDLE hSession,
274     CK_BYTE_PTR pLastPart, CK_ULONG_PTR pulLastPartLen)
275 {
276 	CK_RV rv;
277 	meta_session_t *session;
278 
279 	rv = meta_handle2session(hSession, &session);
280 	if (rv != CKR_OK)
281 		return (rv);
282 
283 	if (pulLastPartLen == NULL) {
284 		meta_operation_cleanup(session, CKF_DECRYPT, FALSE);
285 		REFRELEASE(session);
286 		return (CKR_ARGUMENTS_BAD);
287 	}
288 
289 	rv = meta_do_operation(CKF_DECRYPT, MODE_FINAL, session, NULL,
290 	    NULL, 0, pLastPart, pulLastPartLen);
291 
292 	REFRELEASE(session);
293 
294 	return (rv);
295 }
296