1*12720SWyllys.Ingersoll@Sun.COM /*
2*12720SWyllys.Ingersoll@Sun.COM * CDDL HEADER START
3*12720SWyllys.Ingersoll@Sun.COM *
4*12720SWyllys.Ingersoll@Sun.COM * The contents of this file are subject to the terms of the
5*12720SWyllys.Ingersoll@Sun.COM * Common Development and Distribution License (the "License").
6*12720SWyllys.Ingersoll@Sun.COM * You may not use this file except in compliance with the License.
7*12720SWyllys.Ingersoll@Sun.COM *
8*12720SWyllys.Ingersoll@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*12720SWyllys.Ingersoll@Sun.COM * or http://www.opensolaris.org/os/licensing.
10*12720SWyllys.Ingersoll@Sun.COM * See the License for the specific language governing permissions
11*12720SWyllys.Ingersoll@Sun.COM * and limitations under the License.
12*12720SWyllys.Ingersoll@Sun.COM *
13*12720SWyllys.Ingersoll@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each
14*12720SWyllys.Ingersoll@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*12720SWyllys.Ingersoll@Sun.COM * If applicable, add the following below this CDDL HEADER, with the
16*12720SWyllys.Ingersoll@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying
17*12720SWyllys.Ingersoll@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner]
18*12720SWyllys.Ingersoll@Sun.COM *
19*12720SWyllys.Ingersoll@Sun.COM * CDDL HEADER END
20*12720SWyllys.Ingersoll@Sun.COM *
21*12720SWyllys.Ingersoll@Sun.COM * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
22*12720SWyllys.Ingersoll@Sun.COM */
23*12720SWyllys.Ingersoll@Sun.COM
24*12720SWyllys.Ingersoll@Sun.COM #include <string.h>
25*12720SWyllys.Ingersoll@Sun.COM #include <strings.h>
26*12720SWyllys.Ingersoll@Sun.COM #include <security/cryptoki.h>
27*12720SWyllys.Ingersoll@Sun.COM #include "kmsGlobal.h"
28*12720SWyllys.Ingersoll@Sun.COM #include "kmsCrypt.h"
29*12720SWyllys.Ingersoll@Sun.COM
30*12720SWyllys.Ingersoll@Sun.COM static CK_RV
kms_encrypt_init(kms_session_t * session_p,CK_MECHANISM_PTR pMechanism,kms_object_t * key_p)31*12720SWyllys.Ingersoll@Sun.COM kms_encrypt_init(kms_session_t *session_p, CK_MECHANISM_PTR pMechanism,
32*12720SWyllys.Ingersoll@Sun.COM kms_object_t *key_p)
33*12720SWyllys.Ingersoll@Sun.COM {
34*12720SWyllys.Ingersoll@Sun.COM CK_RV rv = CKR_OK;
35*12720SWyllys.Ingersoll@Sun.COM kms_aes_ctx_t *kms_aes_ctx;
36*12720SWyllys.Ingersoll@Sun.COM
37*12720SWyllys.Ingersoll@Sun.COM if (pMechanism->mechanism != CKM_AES_CBC &&
38*12720SWyllys.Ingersoll@Sun.COM pMechanism->mechanism != CKM_AES_CBC_PAD)
39*12720SWyllys.Ingersoll@Sun.COM return (CKR_MECHANISM_INVALID);
40*12720SWyllys.Ingersoll@Sun.COM
41*12720SWyllys.Ingersoll@Sun.COM if (key_p->key_type != CKK_AES) {
42*12720SWyllys.Ingersoll@Sun.COM return (CKR_KEY_TYPE_INCONSISTENT);
43*12720SWyllys.Ingersoll@Sun.COM }
44*12720SWyllys.Ingersoll@Sun.COM
45*12720SWyllys.Ingersoll@Sun.COM if ((pMechanism->pParameter == NULL) ||
46*12720SWyllys.Ingersoll@Sun.COM (pMechanism->ulParameterLen != AES_BLOCK_LEN)) {
47*12720SWyllys.Ingersoll@Sun.COM return (CKR_MECHANISM_PARAM_INVALID);
48*12720SWyllys.Ingersoll@Sun.COM }
49*12720SWyllys.Ingersoll@Sun.COM
50*12720SWyllys.Ingersoll@Sun.COM rv = kms_aes_crypt_init_common(session_p, pMechanism,
51*12720SWyllys.Ingersoll@Sun.COM key_p, B_TRUE);
52*12720SWyllys.Ingersoll@Sun.COM
53*12720SWyllys.Ingersoll@Sun.COM if (rv != CKR_OK)
54*12720SWyllys.Ingersoll@Sun.COM return (rv);
55*12720SWyllys.Ingersoll@Sun.COM
56*12720SWyllys.Ingersoll@Sun.COM (void) pthread_mutex_lock(&session_p->session_mutex);
57*12720SWyllys.Ingersoll@Sun.COM
58*12720SWyllys.Ingersoll@Sun.COM kms_aes_ctx = (kms_aes_ctx_t *)session_p->encrypt.context;
59*12720SWyllys.Ingersoll@Sun.COM /* Copy Initialization Vector (IV) into the context. */
60*12720SWyllys.Ingersoll@Sun.COM
61*12720SWyllys.Ingersoll@Sun.COM (void) memcpy(kms_aes_ctx->ivec, pMechanism->pParameter,
62*12720SWyllys.Ingersoll@Sun.COM AES_BLOCK_LEN);
63*12720SWyllys.Ingersoll@Sun.COM
64*12720SWyllys.Ingersoll@Sun.COM /* Allocate a context for AES cipher-block chaining. */
65*12720SWyllys.Ingersoll@Sun.COM kms_aes_ctx->aes_cbc = (void *)aes_cbc_ctx_init(
66*12720SWyllys.Ingersoll@Sun.COM kms_aes_ctx->key_sched, kms_aes_ctx->keysched_len,
67*12720SWyllys.Ingersoll@Sun.COM kms_aes_ctx->ivec);
68*12720SWyllys.Ingersoll@Sun.COM
69*12720SWyllys.Ingersoll@Sun.COM if (kms_aes_ctx->aes_cbc == NULL) {
70*12720SWyllys.Ingersoll@Sun.COM bzero(kms_aes_ctx->key_sched,
71*12720SWyllys.Ingersoll@Sun.COM kms_aes_ctx->keysched_len);
72*12720SWyllys.Ingersoll@Sun.COM free(kms_aes_ctx->key_sched);
73*12720SWyllys.Ingersoll@Sun.COM free(session_p->encrypt.context);
74*12720SWyllys.Ingersoll@Sun.COM session_p->encrypt.context = NULL;
75*12720SWyllys.Ingersoll@Sun.COM rv = CKR_HOST_MEMORY;
76*12720SWyllys.Ingersoll@Sun.COM }
77*12720SWyllys.Ingersoll@Sun.COM
78*12720SWyllys.Ingersoll@Sun.COM (void) pthread_mutex_unlock(&session_p->session_mutex);
79*12720SWyllys.Ingersoll@Sun.COM
80*12720SWyllys.Ingersoll@Sun.COM return (rv);
81*12720SWyllys.Ingersoll@Sun.COM }
82*12720SWyllys.Ingersoll@Sun.COM
83*12720SWyllys.Ingersoll@Sun.COM void
kms_crypt_cleanup(kms_session_t * session_p,boolean_t encrypt,boolean_t lock_held)84*12720SWyllys.Ingersoll@Sun.COM kms_crypt_cleanup(kms_session_t *session_p, boolean_t encrypt,
85*12720SWyllys.Ingersoll@Sun.COM boolean_t lock_held)
86*12720SWyllys.Ingersoll@Sun.COM {
87*12720SWyllys.Ingersoll@Sun.COM kms_active_op_t *active_op;
88*12720SWyllys.Ingersoll@Sun.COM boolean_t lock_true = B_TRUE;
89*12720SWyllys.Ingersoll@Sun.COM kms_aes_ctx_t *kms_aes_ctx;
90*12720SWyllys.Ingersoll@Sun.COM aes_ctx_t *aes_ctx;
91*12720SWyllys.Ingersoll@Sun.COM
92*12720SWyllys.Ingersoll@Sun.COM if (!lock_held)
93*12720SWyllys.Ingersoll@Sun.COM (void) pthread_mutex_lock(&session_p->session_mutex);
94*12720SWyllys.Ingersoll@Sun.COM
95*12720SWyllys.Ingersoll@Sun.COM active_op = (encrypt) ? &(session_p->encrypt) : &(session_p->decrypt);
96*12720SWyllys.Ingersoll@Sun.COM if (active_op->mech.mechanism != CKM_AES_CBC &&
97*12720SWyllys.Ingersoll@Sun.COM active_op->mech.mechanism != CKM_AES_CBC_PAD)
98*12720SWyllys.Ingersoll@Sun.COM return;
99*12720SWyllys.Ingersoll@Sun.COM
100*12720SWyllys.Ingersoll@Sun.COM kms_aes_ctx = (kms_aes_ctx_t *)active_op->context;
101*12720SWyllys.Ingersoll@Sun.COM
102*12720SWyllys.Ingersoll@Sun.COM if (kms_aes_ctx != NULL) {
103*12720SWyllys.Ingersoll@Sun.COM aes_ctx = (aes_ctx_t *)kms_aes_ctx->aes_cbc;
104*12720SWyllys.Ingersoll@Sun.COM if (aes_ctx != NULL) {
105*12720SWyllys.Ingersoll@Sun.COM bzero(aes_ctx->ac_keysched, aes_ctx->ac_keysched_len);
106*12720SWyllys.Ingersoll@Sun.COM free(kms_aes_ctx->aes_cbc);
107*12720SWyllys.Ingersoll@Sun.COM bzero(kms_aes_ctx->key_sched,
108*12720SWyllys.Ingersoll@Sun.COM kms_aes_ctx->keysched_len);
109*12720SWyllys.Ingersoll@Sun.COM free(kms_aes_ctx->key_sched);
110*12720SWyllys.Ingersoll@Sun.COM }
111*12720SWyllys.Ingersoll@Sun.COM }
112*12720SWyllys.Ingersoll@Sun.COM if (active_op->context != NULL) {
113*12720SWyllys.Ingersoll@Sun.COM free(active_op->context);
114*12720SWyllys.Ingersoll@Sun.COM active_op->context = NULL;
115*12720SWyllys.Ingersoll@Sun.COM }
116*12720SWyllys.Ingersoll@Sun.COM active_op->flags = 0;
117*12720SWyllys.Ingersoll@Sun.COM if (!lock_held)
118*12720SWyllys.Ingersoll@Sun.COM REFRELE(session_p, lock_true);
119*12720SWyllys.Ingersoll@Sun.COM }
120*12720SWyllys.Ingersoll@Sun.COM
121*12720SWyllys.Ingersoll@Sun.COM CK_RV
C_EncryptInit(CK_SESSION_HANDLE hSession,CK_MECHANISM_PTR pMechanism,CK_OBJECT_HANDLE hKey)122*12720SWyllys.Ingersoll@Sun.COM C_EncryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
123*12720SWyllys.Ingersoll@Sun.COM CK_OBJECT_HANDLE hKey)
124*12720SWyllys.Ingersoll@Sun.COM {
125*12720SWyllys.Ingersoll@Sun.COM CK_RV rv;
126*12720SWyllys.Ingersoll@Sun.COM kms_session_t *session_p;
127*12720SWyllys.Ingersoll@Sun.COM kms_object_t *key_p;
128*12720SWyllys.Ingersoll@Sun.COM boolean_t lock_held = B_FALSE;
129*12720SWyllys.Ingersoll@Sun.COM
130*12720SWyllys.Ingersoll@Sun.COM if (!kms_initialized)
131*12720SWyllys.Ingersoll@Sun.COM return (CKR_CRYPTOKI_NOT_INITIALIZED);
132*12720SWyllys.Ingersoll@Sun.COM
133*12720SWyllys.Ingersoll@Sun.COM /* Obtain the session pointer. */
134*12720SWyllys.Ingersoll@Sun.COM rv = handle2session(hSession, &session_p);
135*12720SWyllys.Ingersoll@Sun.COM if (rv != CKR_OK)
136*12720SWyllys.Ingersoll@Sun.COM return (rv);
137*12720SWyllys.Ingersoll@Sun.COM
138*12720SWyllys.Ingersoll@Sun.COM if (pMechanism == NULL) {
139*12720SWyllys.Ingersoll@Sun.COM rv = CKR_ARGUMENTS_BAD;
140*12720SWyllys.Ingersoll@Sun.COM goto clean_exit;
141*12720SWyllys.Ingersoll@Sun.COM }
142*12720SWyllys.Ingersoll@Sun.COM
143*12720SWyllys.Ingersoll@Sun.COM if (pMechanism->mechanism != CKM_AES_CBC &&
144*12720SWyllys.Ingersoll@Sun.COM pMechanism->mechanism != CKM_AES_CBC_PAD)
145*12720SWyllys.Ingersoll@Sun.COM return (CKR_MECHANISM_INVALID);
146*12720SWyllys.Ingersoll@Sun.COM
147*12720SWyllys.Ingersoll@Sun.COM /* Obtain the object pointer. */
148*12720SWyllys.Ingersoll@Sun.COM HANDLE2OBJECT(hKey, key_p, rv);
149*12720SWyllys.Ingersoll@Sun.COM if (rv != CKR_OK)
150*12720SWyllys.Ingersoll@Sun.COM goto clean_exit;
151*12720SWyllys.Ingersoll@Sun.COM
152*12720SWyllys.Ingersoll@Sun.COM /* Check to see if key object allows for encryption. */
153*12720SWyllys.Ingersoll@Sun.COM if (!(key_p->bool_attr_mask & ENCRYPT_BOOL_ON)) {
154*12720SWyllys.Ingersoll@Sun.COM rv = CKR_KEY_FUNCTION_NOT_PERMITTED;
155*12720SWyllys.Ingersoll@Sun.COM goto clean_exit1;
156*12720SWyllys.Ingersoll@Sun.COM }
157*12720SWyllys.Ingersoll@Sun.COM
158*12720SWyllys.Ingersoll@Sun.COM (void) pthread_mutex_lock(&session_p->session_mutex);
159*12720SWyllys.Ingersoll@Sun.COM lock_held = B_TRUE;
160*12720SWyllys.Ingersoll@Sun.COM
161*12720SWyllys.Ingersoll@Sun.COM /* Check to see if encrypt operation is already active. */
162*12720SWyllys.Ingersoll@Sun.COM if (session_p->encrypt.flags & CRYPTO_OPERATION_ACTIVE) {
163*12720SWyllys.Ingersoll@Sun.COM /* free the memory to avoid memory leak */
164*12720SWyllys.Ingersoll@Sun.COM kms_crypt_cleanup(session_p, B_TRUE, lock_held);
165*12720SWyllys.Ingersoll@Sun.COM }
166*12720SWyllys.Ingersoll@Sun.COM
167*12720SWyllys.Ingersoll@Sun.COM /*
168*12720SWyllys.Ingersoll@Sun.COM * This active flag will remain ON until application calls either
169*12720SWyllys.Ingersoll@Sun.COM * C_Encrypt or C_EncryptFinal to actually obtain the final piece
170*12720SWyllys.Ingersoll@Sun.COM * of ciphertext.
171*12720SWyllys.Ingersoll@Sun.COM */
172*12720SWyllys.Ingersoll@Sun.COM session_p->encrypt.flags = CRYPTO_OPERATION_ACTIVE;
173*12720SWyllys.Ingersoll@Sun.COM
174*12720SWyllys.Ingersoll@Sun.COM (void) pthread_mutex_unlock(&session_p->session_mutex);
175*12720SWyllys.Ingersoll@Sun.COM lock_held = B_FALSE;
176*12720SWyllys.Ingersoll@Sun.COM
177*12720SWyllys.Ingersoll@Sun.COM rv = kms_encrypt_init(session_p, pMechanism, key_p);
178*12720SWyllys.Ingersoll@Sun.COM
179*12720SWyllys.Ingersoll@Sun.COM if (rv != CKR_OK) {
180*12720SWyllys.Ingersoll@Sun.COM (void) pthread_mutex_lock(&session_p->session_mutex);
181*12720SWyllys.Ingersoll@Sun.COM session_p->encrypt.flags &= ~CRYPTO_OPERATION_ACTIVE;
182*12720SWyllys.Ingersoll@Sun.COM lock_held = B_TRUE;
183*12720SWyllys.Ingersoll@Sun.COM }
184*12720SWyllys.Ingersoll@Sun.COM
185*12720SWyllys.Ingersoll@Sun.COM clean_exit1:
186*12720SWyllys.Ingersoll@Sun.COM OBJ_REFRELE(key_p);
187*12720SWyllys.Ingersoll@Sun.COM clean_exit:
188*12720SWyllys.Ingersoll@Sun.COM REFRELE(session_p, lock_held);
189*12720SWyllys.Ingersoll@Sun.COM return (rv);
190*12720SWyllys.Ingersoll@Sun.COM }
191*12720SWyllys.Ingersoll@Sun.COM
192*12720SWyllys.Ingersoll@Sun.COM
193*12720SWyllys.Ingersoll@Sun.COM CK_RV
C_Encrypt(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pData,CK_ULONG ulDataLen,CK_BYTE_PTR pEncryptedData,CK_ULONG_PTR pulEncryptedDataLen)194*12720SWyllys.Ingersoll@Sun.COM C_Encrypt(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen,
195*12720SWyllys.Ingersoll@Sun.COM CK_BYTE_PTR pEncryptedData, CK_ULONG_PTR pulEncryptedDataLen)
196*12720SWyllys.Ingersoll@Sun.COM {
197*12720SWyllys.Ingersoll@Sun.COM CK_RV rv;
198*12720SWyllys.Ingersoll@Sun.COM kms_session_t *session_p;
199*12720SWyllys.Ingersoll@Sun.COM boolean_t lock_held = B_FALSE;
200*12720SWyllys.Ingersoll@Sun.COM
201*12720SWyllys.Ingersoll@Sun.COM if (!kms_initialized)
202*12720SWyllys.Ingersoll@Sun.COM return (CKR_CRYPTOKI_NOT_INITIALIZED);
203*12720SWyllys.Ingersoll@Sun.COM
204*12720SWyllys.Ingersoll@Sun.COM /* Obtain the session pointer. */
205*12720SWyllys.Ingersoll@Sun.COM rv = handle2session(hSession, &session_p);
206*12720SWyllys.Ingersoll@Sun.COM if (rv != CKR_OK)
207*12720SWyllys.Ingersoll@Sun.COM return (rv);
208*12720SWyllys.Ingersoll@Sun.COM
209*12720SWyllys.Ingersoll@Sun.COM /*
210*12720SWyllys.Ingersoll@Sun.COM * Only check if input buffer is null. How to handle zero input
211*12720SWyllys.Ingersoll@Sun.COM * length depends on the mechanism in use. For secret key mechanisms,
212*12720SWyllys.Ingersoll@Sun.COM * unpadded ones yield zero length output, but padded ones always
213*12720SWyllys.Ingersoll@Sun.COM * result in greater than zero length output.
214*12720SWyllys.Ingersoll@Sun.COM */
215*12720SWyllys.Ingersoll@Sun.COM if (pData == NULL) {
216*12720SWyllys.Ingersoll@Sun.COM rv = CKR_ARGUMENTS_BAD;
217*12720SWyllys.Ingersoll@Sun.COM goto clean_exit;
218*12720SWyllys.Ingersoll@Sun.COM }
219*12720SWyllys.Ingersoll@Sun.COM
220*12720SWyllys.Ingersoll@Sun.COM /*
221*12720SWyllys.Ingersoll@Sun.COM * Only check if pulEncryptedDataLen is NULL.
222*12720SWyllys.Ingersoll@Sun.COM * No need to check if pEncryptedData is NULL because
223*12720SWyllys.Ingersoll@Sun.COM * application might just ask for the length of buffer to hold
224*12720SWyllys.Ingersoll@Sun.COM * the ciphertext.
225*12720SWyllys.Ingersoll@Sun.COM */
226*12720SWyllys.Ingersoll@Sun.COM if (pulEncryptedDataLen == NULL) {
227*12720SWyllys.Ingersoll@Sun.COM rv = CKR_ARGUMENTS_BAD;
228*12720SWyllys.Ingersoll@Sun.COM goto clean_exit;
229*12720SWyllys.Ingersoll@Sun.COM }
230*12720SWyllys.Ingersoll@Sun.COM
231*12720SWyllys.Ingersoll@Sun.COM (void) pthread_mutex_lock(&session_p->session_mutex);
232*12720SWyllys.Ingersoll@Sun.COM lock_held = B_TRUE;
233*12720SWyllys.Ingersoll@Sun.COM
234*12720SWyllys.Ingersoll@Sun.COM /* Application must call C_EncryptInit before calling C_Encrypt. */
235*12720SWyllys.Ingersoll@Sun.COM if (!(session_p->encrypt.flags & CRYPTO_OPERATION_ACTIVE)) {
236*12720SWyllys.Ingersoll@Sun.COM REFRELE(session_p, lock_held);
237*12720SWyllys.Ingersoll@Sun.COM return (CKR_OPERATION_NOT_INITIALIZED);
238*12720SWyllys.Ingersoll@Sun.COM }
239*12720SWyllys.Ingersoll@Sun.COM
240*12720SWyllys.Ingersoll@Sun.COM /*
241*12720SWyllys.Ingersoll@Sun.COM * C_Encrypt must be called without intervening C_EncryptUpdate
242*12720SWyllys.Ingersoll@Sun.COM * calls.
243*12720SWyllys.Ingersoll@Sun.COM */
244*12720SWyllys.Ingersoll@Sun.COM if (session_p->encrypt.flags & CRYPTO_OPERATION_UPDATE) {
245*12720SWyllys.Ingersoll@Sun.COM /*
246*12720SWyllys.Ingersoll@Sun.COM * C_Encrypt can not be used to terminate a multi-part
247*12720SWyllys.Ingersoll@Sun.COM * operation, so we'll leave the active encrypt operation
248*12720SWyllys.Ingersoll@Sun.COM * flag on and let the application continue with the
249*12720SWyllys.Ingersoll@Sun.COM * encrypt update operation.
250*12720SWyllys.Ingersoll@Sun.COM */
251*12720SWyllys.Ingersoll@Sun.COM REFRELE(session_p, lock_held);
252*12720SWyllys.Ingersoll@Sun.COM return (CKR_FUNCTION_FAILED);
253*12720SWyllys.Ingersoll@Sun.COM }
254*12720SWyllys.Ingersoll@Sun.COM
255*12720SWyllys.Ingersoll@Sun.COM (void) pthread_mutex_unlock(&session_p->session_mutex);
256*12720SWyllys.Ingersoll@Sun.COM lock_held = B_FALSE;
257*12720SWyllys.Ingersoll@Sun.COM
258*12720SWyllys.Ingersoll@Sun.COM rv = kms_aes_encrypt_common(session_p, pData, ulDataLen, pEncryptedData,
259*12720SWyllys.Ingersoll@Sun.COM pulEncryptedDataLen, 0);
260*12720SWyllys.Ingersoll@Sun.COM
261*12720SWyllys.Ingersoll@Sun.COM if ((rv == CKR_BUFFER_TOO_SMALL) ||
262*12720SWyllys.Ingersoll@Sun.COM (pEncryptedData == NULL && rv == CKR_OK)) {
263*12720SWyllys.Ingersoll@Sun.COM /*
264*12720SWyllys.Ingersoll@Sun.COM * We will not terminate the active encrypt operation flag,
265*12720SWyllys.Ingersoll@Sun.COM * when the application-supplied buffer is too small, or
266*12720SWyllys.Ingersoll@Sun.COM * the application asks for the length of buffer to hold
267*12720SWyllys.Ingersoll@Sun.COM * the ciphertext.
268*12720SWyllys.Ingersoll@Sun.COM */
269*12720SWyllys.Ingersoll@Sun.COM REFRELE(session_p, lock_held);
270*12720SWyllys.Ingersoll@Sun.COM return (rv);
271*12720SWyllys.Ingersoll@Sun.COM }
272*12720SWyllys.Ingersoll@Sun.COM
273*12720SWyllys.Ingersoll@Sun.COM clean_exit:
274*12720SWyllys.Ingersoll@Sun.COM /* Clear context, free key, and release session counter */
275*12720SWyllys.Ingersoll@Sun.COM kms_crypt_cleanup(session_p, B_TRUE, B_FALSE);
276*12720SWyllys.Ingersoll@Sun.COM return (rv);
277*12720SWyllys.Ingersoll@Sun.COM }
278*12720SWyllys.Ingersoll@Sun.COM
279*12720SWyllys.Ingersoll@Sun.COM CK_RV
C_EncryptUpdate(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pPart,CK_ULONG ulPartLen,CK_BYTE_PTR pEncryptedPart,CK_ULONG_PTR pulEncryptedPartLen)280*12720SWyllys.Ingersoll@Sun.COM C_EncryptUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart,
281*12720SWyllys.Ingersoll@Sun.COM CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart,
282*12720SWyllys.Ingersoll@Sun.COM CK_ULONG_PTR pulEncryptedPartLen)
283*12720SWyllys.Ingersoll@Sun.COM {
284*12720SWyllys.Ingersoll@Sun.COM
285*12720SWyllys.Ingersoll@Sun.COM CK_RV rv;
286*12720SWyllys.Ingersoll@Sun.COM kms_session_t *session_p;
287*12720SWyllys.Ingersoll@Sun.COM boolean_t lock_held = B_FALSE;
288*12720SWyllys.Ingersoll@Sun.COM
289*12720SWyllys.Ingersoll@Sun.COM if (!kms_initialized)
290*12720SWyllys.Ingersoll@Sun.COM return (CKR_CRYPTOKI_NOT_INITIALIZED);
291*12720SWyllys.Ingersoll@Sun.COM
292*12720SWyllys.Ingersoll@Sun.COM /* Obtain the session pointer. */
293*12720SWyllys.Ingersoll@Sun.COM rv = handle2session(hSession, &session_p);
294*12720SWyllys.Ingersoll@Sun.COM if (rv != CKR_OK)
295*12720SWyllys.Ingersoll@Sun.COM return (rv);
296*12720SWyllys.Ingersoll@Sun.COM
297*12720SWyllys.Ingersoll@Sun.COM /*
298*12720SWyllys.Ingersoll@Sun.COM * Only check if input buffer is null. How to handle zero input
299*12720SWyllys.Ingersoll@Sun.COM * length depends on the mechanism in use. For secret key mechanisms,
300*12720SWyllys.Ingersoll@Sun.COM * unpadded ones yeild zero length output, but padded ones always
301*12720SWyllys.Ingersoll@Sun.COM * result in greater than zero length output.
302*12720SWyllys.Ingersoll@Sun.COM */
303*12720SWyllys.Ingersoll@Sun.COM if (pPart == NULL) {
304*12720SWyllys.Ingersoll@Sun.COM rv = CKR_ARGUMENTS_BAD;
305*12720SWyllys.Ingersoll@Sun.COM goto clean_exit;
306*12720SWyllys.Ingersoll@Sun.COM }
307*12720SWyllys.Ingersoll@Sun.COM
308*12720SWyllys.Ingersoll@Sun.COM /*
309*12720SWyllys.Ingersoll@Sun.COM * Only check if pulEncryptedPartLen is NULL.
310*12720SWyllys.Ingersoll@Sun.COM * No need to check if pEncryptedPart is NULL because
311*12720SWyllys.Ingersoll@Sun.COM * application might just ask for the length of buffer to hold
312*12720SWyllys.Ingersoll@Sun.COM * the ciphertext.
313*12720SWyllys.Ingersoll@Sun.COM */
314*12720SWyllys.Ingersoll@Sun.COM if (pulEncryptedPartLen == NULL) {
315*12720SWyllys.Ingersoll@Sun.COM rv = CKR_ARGUMENTS_BAD;
316*12720SWyllys.Ingersoll@Sun.COM goto clean_exit;
317*12720SWyllys.Ingersoll@Sun.COM }
318*12720SWyllys.Ingersoll@Sun.COM
319*12720SWyllys.Ingersoll@Sun.COM (void) pthread_mutex_lock(&session_p->session_mutex);
320*12720SWyllys.Ingersoll@Sun.COM lock_held = B_TRUE;
321*12720SWyllys.Ingersoll@Sun.COM
322*12720SWyllys.Ingersoll@Sun.COM /*
323*12720SWyllys.Ingersoll@Sun.COM * Application must call C_EncryptInit before calling
324*12720SWyllys.Ingersoll@Sun.COM * C_EncryptUpdate.
325*12720SWyllys.Ingersoll@Sun.COM */
326*12720SWyllys.Ingersoll@Sun.COM if (!(session_p->encrypt.flags & CRYPTO_OPERATION_ACTIVE)) {
327*12720SWyllys.Ingersoll@Sun.COM REFRELE(session_p, lock_held);
328*12720SWyllys.Ingersoll@Sun.COM return (CKR_OPERATION_NOT_INITIALIZED);
329*12720SWyllys.Ingersoll@Sun.COM }
330*12720SWyllys.Ingersoll@Sun.COM
331*12720SWyllys.Ingersoll@Sun.COM session_p->encrypt.flags |= CRYPTO_OPERATION_UPDATE;
332*12720SWyllys.Ingersoll@Sun.COM
333*12720SWyllys.Ingersoll@Sun.COM (void) pthread_mutex_unlock(&session_p->session_mutex);
334*12720SWyllys.Ingersoll@Sun.COM lock_held = B_FALSE;
335*12720SWyllys.Ingersoll@Sun.COM
336*12720SWyllys.Ingersoll@Sun.COM rv = kms_aes_encrypt_common(session_p, pPart, ulPartLen,
337*12720SWyllys.Ingersoll@Sun.COM pEncryptedPart, pulEncryptedPartLen, B_TRUE);
338*12720SWyllys.Ingersoll@Sun.COM
339*12720SWyllys.Ingersoll@Sun.COM /*
340*12720SWyllys.Ingersoll@Sun.COM * If CKR_OK or CKR_BUFFER_TOO_SMALL, don't terminate the
341*12720SWyllys.Ingersoll@Sun.COM * current encryption operation.
342*12720SWyllys.Ingersoll@Sun.COM */
343*12720SWyllys.Ingersoll@Sun.COM if ((rv == CKR_OK) || (rv == CKR_BUFFER_TOO_SMALL)) {
344*12720SWyllys.Ingersoll@Sun.COM REFRELE(session_p, lock_held);
345*12720SWyllys.Ingersoll@Sun.COM return (rv);
346*12720SWyllys.Ingersoll@Sun.COM }
347*12720SWyllys.Ingersoll@Sun.COM
348*12720SWyllys.Ingersoll@Sun.COM clean_exit:
349*12720SWyllys.Ingersoll@Sun.COM /*
350*12720SWyllys.Ingersoll@Sun.COM * After an error occurred, terminate the current encrypt
351*12720SWyllys.Ingersoll@Sun.COM * operation by resetting the active and update flags.
352*12720SWyllys.Ingersoll@Sun.COM */
353*12720SWyllys.Ingersoll@Sun.COM kms_crypt_cleanup(session_p, B_TRUE, lock_held);
354*12720SWyllys.Ingersoll@Sun.COM
355*12720SWyllys.Ingersoll@Sun.COM return (rv);
356*12720SWyllys.Ingersoll@Sun.COM }
357*12720SWyllys.Ingersoll@Sun.COM
358*12720SWyllys.Ingersoll@Sun.COM
359*12720SWyllys.Ingersoll@Sun.COM CK_RV
C_EncryptFinal(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pLastEncryptedPart,CK_ULONG_PTR pulLastEncryptedPartLen)360*12720SWyllys.Ingersoll@Sun.COM C_EncryptFinal(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pLastEncryptedPart,
361*12720SWyllys.Ingersoll@Sun.COM CK_ULONG_PTR pulLastEncryptedPartLen)
362*12720SWyllys.Ingersoll@Sun.COM {
363*12720SWyllys.Ingersoll@Sun.COM
364*12720SWyllys.Ingersoll@Sun.COM CK_RV rv;
365*12720SWyllys.Ingersoll@Sun.COM kms_session_t *session_p;
366*12720SWyllys.Ingersoll@Sun.COM boolean_t lock_held = B_FALSE;
367*12720SWyllys.Ingersoll@Sun.COM
368*12720SWyllys.Ingersoll@Sun.COM if (!kms_initialized)
369*12720SWyllys.Ingersoll@Sun.COM return (CKR_CRYPTOKI_NOT_INITIALIZED);
370*12720SWyllys.Ingersoll@Sun.COM
371*12720SWyllys.Ingersoll@Sun.COM /* Obtain the session pointer. */
372*12720SWyllys.Ingersoll@Sun.COM rv = handle2session(hSession, &session_p);
373*12720SWyllys.Ingersoll@Sun.COM if (rv != CKR_OK)
374*12720SWyllys.Ingersoll@Sun.COM return (rv);
375*12720SWyllys.Ingersoll@Sun.COM
376*12720SWyllys.Ingersoll@Sun.COM if (pulLastEncryptedPartLen == NULL) {
377*12720SWyllys.Ingersoll@Sun.COM rv = CKR_ARGUMENTS_BAD;
378*12720SWyllys.Ingersoll@Sun.COM goto clean_exit;
379*12720SWyllys.Ingersoll@Sun.COM }
380*12720SWyllys.Ingersoll@Sun.COM
381*12720SWyllys.Ingersoll@Sun.COM (void) pthread_mutex_lock(&session_p->session_mutex);
382*12720SWyllys.Ingersoll@Sun.COM lock_held = B_TRUE;
383*12720SWyllys.Ingersoll@Sun.COM
384*12720SWyllys.Ingersoll@Sun.COM /*
385*12720SWyllys.Ingersoll@Sun.COM * Application must call C_EncryptInit before calling
386*12720SWyllys.Ingersoll@Sun.COM * C_EncryptFinal.
387*12720SWyllys.Ingersoll@Sun.COM */
388*12720SWyllys.Ingersoll@Sun.COM if (!(session_p->encrypt.flags & CRYPTO_OPERATION_ACTIVE)) {
389*12720SWyllys.Ingersoll@Sun.COM REFRELE(session_p, lock_held);
390*12720SWyllys.Ingersoll@Sun.COM return (CKR_OPERATION_NOT_INITIALIZED);
391*12720SWyllys.Ingersoll@Sun.COM }
392*12720SWyllys.Ingersoll@Sun.COM
393*12720SWyllys.Ingersoll@Sun.COM (void) pthread_mutex_unlock(&session_p->session_mutex);
394*12720SWyllys.Ingersoll@Sun.COM lock_held = B_FALSE;
395*12720SWyllys.Ingersoll@Sun.COM
396*12720SWyllys.Ingersoll@Sun.COM rv = kms_aes_encrypt_final(session_p, pLastEncryptedPart,
397*12720SWyllys.Ingersoll@Sun.COM pulLastEncryptedPartLen);
398*12720SWyllys.Ingersoll@Sun.COM
399*12720SWyllys.Ingersoll@Sun.COM if ((rv == CKR_BUFFER_TOO_SMALL) ||
400*12720SWyllys.Ingersoll@Sun.COM (pLastEncryptedPart == NULL && rv == CKR_OK)) {
401*12720SWyllys.Ingersoll@Sun.COM /*
402*12720SWyllys.Ingersoll@Sun.COM * We will not terminate the active encrypt operation flag,
403*12720SWyllys.Ingersoll@Sun.COM * when the application-supplied buffer is too small, or
404*12720SWyllys.Ingersoll@Sun.COM * the application asks for the length of buffer to hold
405*12720SWyllys.Ingersoll@Sun.COM * the ciphertext.
406*12720SWyllys.Ingersoll@Sun.COM */
407*12720SWyllys.Ingersoll@Sun.COM REFRELE(session_p, lock_held);
408*12720SWyllys.Ingersoll@Sun.COM return (rv);
409*12720SWyllys.Ingersoll@Sun.COM }
410*12720SWyllys.Ingersoll@Sun.COM
411*12720SWyllys.Ingersoll@Sun.COM /* Terminates the active encrypt operation. */
412*12720SWyllys.Ingersoll@Sun.COM (void) pthread_mutex_lock(&session_p->session_mutex);
413*12720SWyllys.Ingersoll@Sun.COM session_p->encrypt.flags = 0;
414*12720SWyllys.Ingersoll@Sun.COM lock_held = B_TRUE;
415*12720SWyllys.Ingersoll@Sun.COM REFRELE(session_p, lock_held);
416*12720SWyllys.Ingersoll@Sun.COM
417*12720SWyllys.Ingersoll@Sun.COM return (rv);
418*12720SWyllys.Ingersoll@Sun.COM
419*12720SWyllys.Ingersoll@Sun.COM clean_exit:
420*12720SWyllys.Ingersoll@Sun.COM /* Terminates the active encrypt operation. */
421*12720SWyllys.Ingersoll@Sun.COM kms_crypt_cleanup(session_p, B_TRUE, lock_held);
422*12720SWyllys.Ingersoll@Sun.COM
423*12720SWyllys.Ingersoll@Sun.COM return (rv);
424*12720SWyllys.Ingersoll@Sun.COM }
425