1/*
2 * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
3 */
4
5/* Copyright (c) 2002 Graz University of Technology. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright notice,
11 * this list of conditions and the following disclaimer.
12 *
13 * 2. Redistributions in binary form must reproduce the above copyright notice,
14 * this list of conditions and the following disclaimer in the documentation
15 * and/or other materials provided with the distribution.
16 *
17 * 3. The end-user documentation included with the redistribution, if any, must
18 * include the following acknowledgment:
19 *
20 * "This product includes software developed by IAIK of Graz University of
21 * Technology."
22 *
23 * Alternately, this acknowledgment may appear in the software itself, if
24 * and wherever such third-party acknowledgments normally appear.
25 *
26 * 4. The names "Graz University of Technology" and "IAIK of Graz University of
27 * Technology" must not be used to endorse or promote products derived from
28 * this software without prior written permission.
29 *
30 * 5. Products derived from this software may not be called
31 * "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
32 * written permission of Graz University of Technology.
33 *
34 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
35 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
36 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
37 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
38 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
39 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
40 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
41 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
42 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
43 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
44 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
45 * POSSIBILITY OF SUCH DAMAGE.
46 * ===========================================================================
47 */
48
49#include "pkcs11wrapper.h"
50
51#include <stdio.h>
52#include <stdlib.h>
53#include <string.h>
54#include <assert.h>
55
56#include "sun_security_pkcs11_wrapper_PKCS11.h"
57
58#ifdef P11_ENABLE_C_ENCRYPTINIT
59/*
60 * Class: sun_security_pkcs11_wrapper_PKCS11
61 * Method: C_EncryptInit
62 * Signature: (JLsun/security/pkcs11/wrapper/CK_MECHANISM;J)V
63 * Parametermapping: *PKCS11*
64 * @param jlong jSessionHandle CK_SESSION_HANDLE hSession
65 * @param jobject jMechanism CK_MECHANISM_PTR pMechanism
66 * @param jlong jKeyHandle CK_OBJECT_HANDLE hKey
67 */
68JNIEXPORT void JNICALL
69Java_sun_security_pkcs11_wrapper_PKCS11_C_1EncryptInit
70(JNIEnv *env, jobject obj, jlong jSessionHandle,
71 jobject jMechanism, jlong jKeyHandle)
72{
73 CK_SESSION_HANDLE ckSessionHandle;
74 CK_MECHANISM_PTR ckpMechanism = NULL;
75 CK_OBJECT_HANDLE ckKeyHandle;
76 CK_RV rv;
77
78 CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
79 if (ckpFunctions == NULL) { return; }
80
81 ckSessionHandle = jLongToCKULong(jSessionHandle);
82 ckKeyHandle = jLongToCKULong(jKeyHandle);
83 ckpMechanism = jMechanismToCKMechanismPtr(env, jMechanism);
84 if ((*env)->ExceptionCheck(env)) { return; }
85
86 rv = (*ckpFunctions->C_EncryptInit)(ckSessionHandle, ckpMechanism,
87 ckKeyHandle);
88
89 // if OAEP, then cannot free here
90 freeCKMechanismPtr(ckpMechanism);
91
92 if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
93}
94#endif
95
96#ifdef P11_ENABLE_C_ENCRYPT
97/*
98 * Class: sun_security_pkcs11_wrapper_PKCS11
99 * Method: C_Encrypt
100 * Signature: (JJ[BIIJ[BII)I
101 * Parametermapping: *PKCS11*
102 * @param jlong jSessionHandle CK_SESSION_HANDLE hSession
103 * @param jlong directIn CK_BYTE_PTR pData
104 * @param jbyteArray jData CK_BYTE_PTR pData
105 * CK_ULONG ulDataLen
106 * @param jlong directOut CK_BYTE_PTR pEncryptedData
107 * @return jint encryptedDataLen CK_BYTE_PTR pEncryptedData
108 * CK_ULONG_PTR pulEncryptedDataLen
109 */
110JNIEXPORT jint JNICALL
111Java_sun_security_pkcs11_wrapper_PKCS11_C_1Encrypt
112(JNIEnv *env, jobject obj, jlong jSessionHandle,
113 jlong directIn, jbyteArray jIn, jint jInOfs, jint jInLen,
114 jlong directOut, jbyteArray jOut, jint jOutOfs, jint jOutLen)
115{
116 CK_SESSION_HANDLE ckSessionHandle;
117 CK_RV rv;
118
119 CK_BYTE_PTR inBufP;
120 CK_BYTE_PTR outBufP;
121 CK_ULONG ckEncryptedLen = 0;
122
123 CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
124 if (ckpFunctions == NULL) { return 0; }
125
126 ckSessionHandle = jLongToCKULong(jSessionHandle);
127
128 if (directIn != 0) {
129 inBufP = (CK_BYTE_PTR) jlong_to_ptr(directIn);
130 } else {
131 inBufP = (*env)->GetPrimitiveArrayCritical(env, jIn, NULL);
132 if (inBufP == NULL) { return 0; }
133 }
134
135 if (directOut != 0) {
136 outBufP = (CK_BYTE_PTR) jlong_to_ptr(directOut);
137 } else {
138 outBufP = (*env)->GetPrimitiveArrayCritical(env, jOut, NULL);
139 if (outBufP == NULL) {
140 goto cleanup;
141 }
142 }
143
144 ckEncryptedLen = jOutLen;
145
146 rv = (*ckpFunctions->C_Encrypt)(ckSessionHandle,
147 (CK_BYTE_PTR)(inBufP + jInOfs), jInLen,
148 (CK_BYTE_PTR)(outBufP + jOutOfs),
149 &ckEncryptedLen);
150
151 ckAssertReturnValueOK(env, rv);
152
153cleanup:
154 if (directIn == 0 && inBufP != NULL) {
155 (*env)->ReleasePrimitiveArrayCritical(env, jIn, inBufP, JNI_ABORT);
156 }
157 if (directOut == 0 && outBufP != NULL) {
158 (*env)->ReleasePrimitiveArrayCritical(env, jOut, outBufP, JNI_COMMIT);
159 }
160 return ckEncryptedLen;
161}
162#endif
163
164#ifdef P11_ENABLE_C_ENCRYPTUPDATE
165/*
166 * Class: sun_security_pkcs11_wrapper_PKCS11
167 * Method: C_EncryptUpdate
168 * Signature: (J[BII[BII)I
169 * Parametermapping: *PKCS11*
170 * @param jlong jSessionHandle CK_SESSION_HANDLE hSession
171 * @param jbyteArray jPart CK_BYTE_PTR pPart
172 * CK_ULONG ulPartLen
173 * @return jbyteArray jEncryptedPart CK_BYTE_PTR pEncryptedPart
174 * CK_ULONG_PTR pulEncryptedPartLen
175 */
176JNIEXPORT jint JNICALL
177Java_sun_security_pkcs11_wrapper_PKCS11_C_1EncryptUpdate
178(JNIEnv *env, jobject obj, jlong jSessionHandle,
179 jlong directIn, jbyteArray jIn, jint jInOfs, jint jInLen,
180 jlong directOut, jbyteArray jOut, jint jOutOfs, jint jOutLen)
181{
182 CK_SESSION_HANDLE ckSessionHandle;
183 CK_RV rv;
184
185 CK_BYTE_PTR inBufP;
186 CK_BYTE_PTR outBufP;
187 CK_ULONG ckEncryptedPartLen = 0;
188
189 CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
190 if (ckpFunctions == NULL) { return 0; }
191
192 ckSessionHandle = jLongToCKULong(jSessionHandle);
193
194 if (directIn != 0) {
195 inBufP = (CK_BYTE_PTR) jlong_to_ptr(directIn);
196 } else {
197 inBufP = (*env)->GetPrimitiveArrayCritical(env, jIn, NULL);
198 if (inBufP == NULL) { return 0; }
199 }
200
201 if (directOut != 0) {
202 outBufP = (CK_BYTE_PTR) jlong_to_ptr(directOut);
203 } else {
204 outBufP = (*env)->GetPrimitiveArrayCritical(env, jOut, NULL);
205 if (outBufP == NULL) {
206 goto cleanup;
207 }
208 }
209
210 ckEncryptedPartLen = jOutLen;
211
212 rv = (*ckpFunctions->C_EncryptUpdate)(ckSessionHandle,
213 (CK_BYTE_PTR)(inBufP + jInOfs), jInLen,
214 (CK_BYTE_PTR)(outBufP + jOutOfs),
215 &ckEncryptedPartLen);
216
217 ckAssertReturnValueOK(env, rv);
218
219cleanup:
220 if (directIn == 0 && inBufP != NULL) {
221 (*env)->ReleasePrimitiveArrayCritical(env, jIn, inBufP, JNI_ABORT);
222 }
223 if (directOut == 0 && outBufP != NULL) {
224 (*env)->ReleasePrimitiveArrayCritical(env, jOut, outBufP, JNI_COMMIT);
225 }
226 return ckEncryptedPartLen;
227}
228#endif
229
230#ifdef P11_ENABLE_C_ENCRYPTFINAL
231/*
232 * Class: sun_security_pkcs11_wrapper_PKCS11
233 * Method: C_EncryptFinal
234 * Signature: (J[BII)I
235 * Parametermapping: *PKCS11*
236 * @param jlong jSessionHandle CK_SESSION_HANDLE hSession
237 * @return jbyteArray jLastEncryptedPart CK_BYTE_PTR pLastEncryptedDataPart
238 * CK_ULONG_PTR pulLastEncryptedDataPartLen
239 */
240JNIEXPORT jint JNICALL
241Java_sun_security_pkcs11_wrapper_PKCS11_C_1EncryptFinal
242(JNIEnv *env, jobject obj, jlong jSessionHandle,
243 jlong directOut, jbyteArray jOut, jint jOutOfs, jint jOutLen)
244{
245 CK_SESSION_HANDLE ckSessionHandle;
246 CK_RV rv;
247 CK_BYTE_PTR outBufP;
248 CK_ULONG ckLastEncryptedPartLen;
249
250 CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
251 if (ckpFunctions == NULL) { return 0; }
252
253 ckSessionHandle = jLongToCKULong(jSessionHandle);
254
255 if (directOut != 0) {
256 outBufP = (CK_BYTE_PTR) jlong_to_ptr(directOut);
257 } else {
258 outBufP = (*env)->GetPrimitiveArrayCritical(env, jOut, NULL);
259 if (outBufP == NULL) { return 0; }
260 }
261
262 ckLastEncryptedPartLen = jOutLen;
263
264 rv = (*ckpFunctions->C_EncryptFinal)(ckSessionHandle,
265 (CK_BYTE_PTR)(outBufP + jOutOfs),
266 &ckLastEncryptedPartLen);
267
268 if (directOut == 0) {
269 (*env)->ReleasePrimitiveArrayCritical(env, jOut, outBufP, JNI_COMMIT);
270 }
271
272 ckAssertReturnValueOK(env, rv);
273
274 return ckLastEncryptedPartLen;
275}
276#endif
277
278#ifdef P11_ENABLE_C_DECRYPTINIT
279/*
280 * Class: sun_security_pkcs11_wrapper_PKCS11
281 * Method: C_DecryptInit
282 * Signature: (JLsun/security/pkcs11/wrapper/CK_MECHANISM;J)V
283 * Parametermapping: *PKCS11*
284 * @param jlong jSessionHandle CK_SESSION_HANDLE hSession
285 * @param jobject jMechanism CK_MECHANISM_PTR pMechanism
286 * @param jlong jKeyHandle CK_OBJECT_HANDLE hKey
287 */
288JNIEXPORT void JNICALL
289Java_sun_security_pkcs11_wrapper_PKCS11_C_1DecryptInit
290(JNIEnv *env, jobject obj, jlong jSessionHandle,
291 jobject jMechanism, jlong jKeyHandle)
292{
293 CK_SESSION_HANDLE ckSessionHandle;
294 CK_MECHANISM_PTR ckpMechanism = NULL;
295 CK_OBJECT_HANDLE ckKeyHandle;
296 CK_RV rv;
297
298 CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
299 if (ckpFunctions == NULL) { return; }
300
301 ckSessionHandle = jLongToCKULong(jSessionHandle);
302 ckKeyHandle = jLongToCKULong(jKeyHandle);
303 ckpMechanism = jMechanismToCKMechanismPtr(env, jMechanism);
304 if ((*env)->ExceptionCheck(env)) { return; }
305
306 rv = (*ckpFunctions->C_DecryptInit)(ckSessionHandle, ckpMechanism,
307 ckKeyHandle);
308
309 // if OAEP, then cannot free here
310 freeCKMechanismPtr(ckpMechanism);
311
312 if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
313}
314#endif
315
316#ifdef P11_ENABLE_C_DECRYPT
317/*
318 * Class: sun_security_pkcs11_wrapper_PKCS11
319 * Method: C_Decrypt
320 * Signature: (JJ[BIIJ[BII)I
321 * Parametermapping: *PKCS11*
322 * @param jlong jSessionHandle CK_SESSION_HANDLE hSession
323 * @param jbyteArray jEncryptedData CK_BYTE_PTR pEncryptedData
324 * CK_ULONG ulEncryptedDataLen
325 * @return jbyteArray jData CK_BYTE_PTR pData
326 * CK_ULONG_PTR pulDataLen
327 */
328JNIEXPORT jint JNICALL
329Java_sun_security_pkcs11_wrapper_PKCS11_C_1Decrypt
330(JNIEnv *env, jobject obj, jlong jSessionHandle,
331 jlong directIn, jbyteArray jIn, jint jInOfs, jint jInLen,
332 jlong directOut, jbyteArray jOut, jint jOutOfs, jint jOutLen)
333{
334 CK_SESSION_HANDLE ckSessionHandle;
335 CK_RV rv;
336
337 CK_BYTE_PTR inBufP;
338 CK_BYTE_PTR outBufP;
339 CK_ULONG ckOutLen = 0;
340
341 CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
342 if (ckpFunctions == NULL) { return 0; }
343
344 ckSessionHandle = jLongToCKULong(jSessionHandle);
345
346 if (directIn != 0) {
347 inBufP = (CK_BYTE_PTR) jlong_to_ptr(directIn);
348 } else {
349 inBufP = (*env)->GetPrimitiveArrayCritical(env, jIn, NULL);
350 if (inBufP == NULL) { return 0; }
351 }
352
353 if (directOut != 0) {
354 outBufP = (CK_BYTE_PTR) jlong_to_ptr(directOut);
355 } else {
356 outBufP = (*env)->GetPrimitiveArrayCritical(env, jOut, NULL);
357 if (outBufP == NULL) {
358 goto cleanup;
359 }
360 }
361 ckOutLen = jOutLen;
362
363 rv = (*ckpFunctions->C_Decrypt)(ckSessionHandle,
364 (CK_BYTE_PTR)(inBufP + jInOfs), jInLen,
365 (CK_BYTE_PTR)(outBufP + jOutOfs),
366 &ckOutLen);
367
368 ckAssertReturnValueOK(env, rv);
369
370cleanup:
371 if (directIn == 0 && inBufP != NULL) {
372 (*env)->ReleasePrimitiveArrayCritical(env, jIn, inBufP, JNI_ABORT);
373 }
374 if (directOut == 0 && outBufP != NULL) {
375 (*env)->ReleasePrimitiveArrayCritical(env, jOut, outBufP, JNI_COMMIT);
376 }
377 return ckOutLen;
378}
379#endif
380
381#ifdef P11_ENABLE_C_DECRYPTUPDATE
382/*
383 * Class: sun_security_pkcs11_wrapper_PKCS11
384 * Method: C_DecryptUpdate
385 * Signature: (J[BII[BII)I
386 * Parametermapping: *PKCS11*
387 * @param jlong jSessionHandle CK_SESSION_HANDLE hSession
388 * @param jbyteArray jEncryptedPart CK_BYTE_PTR pEncryptedPart
389 * CK_ULONG ulEncryptedPartLen
390 * @return jbyteArray jPart CK_BYTE_PTR pPart
391 * CK_ULONG_PTR pulPartLen
392 */
393JNIEXPORT jint JNICALL
394Java_sun_security_pkcs11_wrapper_PKCS11_C_1DecryptUpdate
395(JNIEnv *env, jobject obj, jlong jSessionHandle,
396 jlong directIn, jbyteArray jIn, jint jInOfs, jint jInLen,
397 jlong directOut, jbyteArray jOut, jint jOutOfs, jint jOutLen)
398{
399 CK_SESSION_HANDLE ckSessionHandle;
400 CK_RV rv;
401
402 CK_BYTE_PTR inBufP;
403 CK_BYTE_PTR outBufP;
404 CK_ULONG ckDecryptedPartLen = 0;
405
406 CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
407 if (ckpFunctions == NULL) { return 0; }
408
409 ckSessionHandle = jLongToCKULong(jSessionHandle);
410
411 if (directIn != 0) {
412 inBufP = (CK_BYTE_PTR) jlong_to_ptr(directIn);
413 } else {
414 inBufP = (*env)->GetPrimitiveArrayCritical(env, jIn, NULL);
415 if (inBufP == NULL) { return 0; }
416 }
417
418 if (directOut != 0) {
419 outBufP = (CK_BYTE_PTR) jlong_to_ptr(directOut);
420 } else {
421 outBufP = (*env)->GetPrimitiveArrayCritical(env, jOut, NULL);
422 if (outBufP == NULL) {
423 goto cleanup;
424 }
425 }
426
427 ckDecryptedPartLen = jOutLen;
428 rv = (*ckpFunctions->C_DecryptUpdate)(ckSessionHandle,
429 (CK_BYTE_PTR)(inBufP + jInOfs), jInLen,
430 (CK_BYTE_PTR)(outBufP + jOutOfs),
431 &ckDecryptedPartLen);
432 ckAssertReturnValueOK(env, rv);
433
434cleanup:
435 if (directIn == 0 && inBufP != NULL) {
436 (*env)->ReleasePrimitiveArrayCritical(env, jIn, inBufP, JNI_ABORT);
437 }
438 if (directOut == 0 && outBufP != NULL) {
439 (*env)->ReleasePrimitiveArrayCritical(env, jOut, outBufP, JNI_COMMIT);
440 }
441 return ckDecryptedPartLen;
442}
443
444#endif
445
446#ifdef P11_ENABLE_C_DECRYPTFINAL
447/*
448 * Class: sun_security_pkcs11_wrapper_PKCS11
449 * Method: C_DecryptFinal
450 * Signature: (J[BII)I
451 * Parametermapping: *PKCS11*
452 * @param jlong jSessionHandle CK_SESSION_HANDLE hSession
453 * @return jbyteArray jLastPart CK_BYTE_PTR pLastPart
454 * CK_ULONG_PTR pulLastPartLen
455 */
456JNIEXPORT jint JNICALL
457Java_sun_security_pkcs11_wrapper_PKCS11_C_1DecryptFinal
458(JNIEnv *env, jobject obj, jlong jSessionHandle,
459 jlong directOut, jbyteArray jOut, jint jOutOfs, jint jOutLen)
460{
461 CK_SESSION_HANDLE ckSessionHandle;
462 CK_RV rv;
463 CK_BYTE_PTR outBufP;
464 CK_ULONG ckLastPartLen;
465
466 CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
467 if (ckpFunctions == NULL) { return 0; }
468
469 ckSessionHandle = jLongToCKULong(jSessionHandle);
470
471 if (directOut != 0) {
472 outBufP = (CK_BYTE_PTR) jlong_to_ptr(directOut);
473 } else {
474 outBufP = (*env)->GetPrimitiveArrayCritical(env, jOut, NULL);
475 if (outBufP == NULL) { return 0; }
476 }
477
478 ckLastPartLen = jOutLen;
479
480 rv = (*ckpFunctions->C_DecryptFinal)(ckSessionHandle,
481 (CK_BYTE_PTR)(outBufP + jOutOfs),
482 &ckLastPartLen);
483
484 if (directOut == 0) {
485 (*env)->ReleasePrimitiveArrayCritical(env, jOut, outBufP, JNI_COMMIT);
486
487 }
488
489 ckAssertReturnValueOK(env, rv);
490
491 return ckLastPartLen;
492}
493#endif
494