1/*
2 * Copyright (c) 2003, 2012, 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 ckMechanism;
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    jMechanismToCKMechanism(env, jMechanism, &ckMechanism);
84    if ((*env)->ExceptionCheck(env)) { return; }
85
86    rv = (*ckpFunctions->C_EncryptInit)(ckSessionHandle, &ckMechanism,
87                                        ckKeyHandle);
88
89    if (ckMechanism.pParameter != NULL_PTR) {
90        free(ckMechanism.pParameter);
91    }
92
93    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
94}
95#endif
96
97#ifdef P11_ENABLE_C_ENCRYPT
98/*
99 * Class:     sun_security_pkcs11_wrapper_PKCS11
100 * Method:    C_Encrypt
101 * Signature: (J[BII[BII)I
102 * Parametermapping:                    *PKCS11*
103 * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
104 * @param   jbyteArray jData            CK_BYTE_PTR pData
105 *                                      CK_ULONG ulDataLen
106 * @return  jbyteArray jEncryptedData   CK_BYTE_PTR pEncryptedData
107 *                                      CK_ULONG_PTR pulEncryptedDataLen
108 */
109JNIEXPORT jint JNICALL
110Java_sun_security_pkcs11_wrapper_PKCS11_C_1Encrypt
111(JNIEnv *env, jobject obj, jlong jSessionHandle,
112 jbyteArray jIn, jint jInOfs, jint jInLen,
113 jbyteArray jOut, jint jOutOfs, jint jOutLen)
114{
115    CK_SESSION_HANDLE ckSessionHandle;
116    CK_RV rv;
117
118    CK_BYTE_PTR inBufP;
119    CK_BYTE_PTR outBufP;
120    CK_ULONG ckEncryptedPartLen;
121
122    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
123    if (ckpFunctions == NULL) { return 0; }
124
125    ckSessionHandle = jLongToCKULong(jSessionHandle);
126
127    inBufP = (*env)->GetPrimitiveArrayCritical(env, jIn, NULL);
128    if (inBufP == NULL) { return 0; }
129
130    outBufP = (*env)->GetPrimitiveArrayCritical(env, jOut, NULL);
131    if (outBufP == NULL) {
132        // Make sure to release inBufP
133        (*env)->ReleasePrimitiveArrayCritical(env, jIn, inBufP, JNI_ABORT);
134        return 0;
135    }
136
137    ckEncryptedPartLen = jOutLen;
138
139    rv = (*ckpFunctions->C_Encrypt)(ckSessionHandle,
140                                    (CK_BYTE_PTR)(inBufP + jInOfs), jInLen,
141                                    (CK_BYTE_PTR)(outBufP + jOutOfs),
142                                    &ckEncryptedPartLen);
143
144    (*env)->ReleasePrimitiveArrayCritical(env, jIn, inBufP, JNI_ABORT);
145    (*env)->ReleasePrimitiveArrayCritical(env, jOut, outBufP, JNI_COMMIT);
146
147    ckAssertReturnValueOK(env, rv);
148    return ckEncryptedPartLen;
149}
150#endif
151
152#ifdef P11_ENABLE_C_ENCRYPTUPDATE
153/*
154 * Class:     sun_security_pkcs11_wrapper_PKCS11
155 * Method:    C_EncryptUpdate
156 * Signature: (J[BII[BII)I
157 * Parametermapping:                    *PKCS11*
158 * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
159 * @param   jbyteArray jPart            CK_BYTE_PTR pPart
160 *                                      CK_ULONG ulPartLen
161 * @return  jbyteArray jEncryptedPart   CK_BYTE_PTR pEncryptedPart
162 *                                      CK_ULONG_PTR pulEncryptedPartLen
163 */
164JNIEXPORT jint JNICALL
165Java_sun_security_pkcs11_wrapper_PKCS11_C_1EncryptUpdate
166(JNIEnv *env, jobject obj, jlong jSessionHandle,
167 jlong directIn, jbyteArray jIn, jint jInOfs, jint jInLen,
168 jlong directOut, jbyteArray jOut, jint jOutOfs, jint jOutLen)
169{
170    CK_SESSION_HANDLE ckSessionHandle;
171    CK_RV rv;
172
173    CK_BYTE_PTR inBufP;
174    CK_BYTE_PTR outBufP;
175    CK_ULONG ckEncryptedPartLen;
176
177    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
178    if (ckpFunctions == NULL) { return 0; }
179
180    ckSessionHandle = jLongToCKULong(jSessionHandle);
181
182    if (directIn != 0) {
183      inBufP = (CK_BYTE_PTR) jlong_to_ptr(directIn);
184    } else {
185      inBufP = (*env)->GetPrimitiveArrayCritical(env, jIn, NULL);
186      if (inBufP == NULL) { return 0; }
187    }
188
189    if (directOut != 0) {
190      outBufP = (CK_BYTE_PTR) jlong_to_ptr(directOut);
191    } else {
192      outBufP = (*env)->GetPrimitiveArrayCritical(env, jOut, NULL);
193      if (outBufP == NULL) {
194          // Make sure to release inBufP
195          (*env)->ReleasePrimitiveArrayCritical(env, jIn, inBufP, JNI_ABORT);
196          return 0;
197      }
198    }
199
200    ckEncryptedPartLen = jOutLen;
201
202    //printf("EU: inBufP=%i, jInOfs=%i, jInLen=%i, outBufP=%i\n",
203    //       inBufP, jInOfs, jInLen, outBufP);
204
205    rv = (*ckpFunctions->C_EncryptUpdate)(ckSessionHandle,
206                                          (CK_BYTE_PTR)(inBufP + jInOfs), jInLen,
207                                          (CK_BYTE_PTR)(outBufP + jOutOfs),
208                                          &ckEncryptedPartLen);
209
210    //printf("EU: ckEncryptedPartLen=%i\n", ckEncryptedPartLen);
211
212    if (directIn == 0) {
213        (*env)->ReleasePrimitiveArrayCritical(env, jIn, inBufP, JNI_ABORT);
214    }
215
216    if (directOut == 0) {
217        (*env)->ReleasePrimitiveArrayCritical(env, jOut, outBufP, JNI_COMMIT);
218    }
219
220    ckAssertReturnValueOK(env, rv);
221
222    return ckEncryptedPartLen;
223}
224#endif
225
226#ifdef P11_ENABLE_C_ENCRYPTFINAL
227/*
228 * Class:     sun_security_pkcs11_wrapper_PKCS11
229 * Method:    C_EncryptFinal
230 * Signature: (J[BII)I
231 * Parametermapping:                        *PKCS11*
232 * @param   jlong jSessionHandle            CK_SESSION_HANDLE hSession
233 * @return  jbyteArray jLastEncryptedPart   CK_BYTE_PTR pLastEncryptedDataPart
234 *                                          CK_ULONG_PTR pulLastEncryptedDataPartLen
235 */
236JNIEXPORT jint JNICALL
237Java_sun_security_pkcs11_wrapper_PKCS11_C_1EncryptFinal
238(JNIEnv *env, jobject obj, jlong jSessionHandle,
239 jlong directOut, jbyteArray jOut, jint jOutOfs, jint jOutLen)
240{
241    CK_SESSION_HANDLE ckSessionHandle;
242    CK_RV rv;
243    CK_BYTE_PTR outBufP;
244    CK_ULONG ckLastEncryptedPartLen;
245
246    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
247    if (ckpFunctions == NULL) { return 0; }
248
249    ckSessionHandle = jLongToCKULong(jSessionHandle);
250
251    if (directOut != 0) {
252      outBufP = (CK_BYTE_PTR) jlong_to_ptr(directOut);
253    } else {
254      outBufP = (*env)->GetPrimitiveArrayCritical(env, jOut, NULL);
255      if (outBufP == NULL) { return 0; }
256    }
257
258    ckLastEncryptedPartLen = jOutLen;
259
260    //printf("EF: outBufP=%i\n", outBufP);
261
262    rv = (*ckpFunctions->C_EncryptFinal)(ckSessionHandle,
263                                         (CK_BYTE_PTR)(outBufP + jOutOfs),
264                                         &ckLastEncryptedPartLen);
265
266    //printf("EF: ckLastEncryptedPartLen=%i", 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 ckMechanism;
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    jMechanismToCKMechanism(env, jMechanism, &ckMechanism);
304    if ((*env)->ExceptionCheck(env)) { return; }
305
306    rv = (*ckpFunctions->C_DecryptInit)(ckSessionHandle, &ckMechanism,
307                                        ckKeyHandle);
308
309    if (ckMechanism.pParameter != NULL_PTR) {
310        free(ckMechanism.pParameter);
311    }
312
313    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
314}
315#endif
316
317#ifdef P11_ENABLE_C_DECRYPT
318/*
319 * Class:     sun_security_pkcs11_wrapper_PKCS11
320 * Method:    C_Decrypt
321 * Signature: (J[BII[BII)I
322 * Parametermapping:                    *PKCS11*
323 * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
324 * @param   jbyteArray jEncryptedData   CK_BYTE_PTR pEncryptedData
325 *                                      CK_ULONG ulEncryptedDataLen
326 * @return  jbyteArray jData            CK_BYTE_PTR pData
327 *                                      CK_ULONG_PTR pulDataLen
328 */
329JNIEXPORT jint JNICALL
330Java_sun_security_pkcs11_wrapper_PKCS11_C_1Decrypt
331(JNIEnv *env, jobject obj, jlong jSessionHandle,
332 jbyteArray jIn, jint jInOfs, jint jInLen,
333 jbyteArray jOut, jint jOutOfs, jint jOutLen)
334{
335    CK_SESSION_HANDLE ckSessionHandle;
336    CK_RV rv;
337
338    CK_BYTE_PTR inBufP;
339    CK_BYTE_PTR outBufP;
340    CK_ULONG ckPartLen;
341
342    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
343    if (ckpFunctions == NULL) { return 0; }
344
345    ckSessionHandle = jLongToCKULong(jSessionHandle);
346
347    inBufP = (*env)->GetPrimitiveArrayCritical(env, jIn, NULL);
348    if (inBufP == NULL) { return 0; }
349
350    outBufP = (*env)->GetPrimitiveArrayCritical(env, jOut, NULL);
351    if (outBufP == NULL) {
352        // Make sure to release inBufP
353        (*env)->ReleasePrimitiveArrayCritical(env, jIn, inBufP, JNI_ABORT);
354        return 0;
355    }
356
357    ckPartLen = jOutLen;
358
359    rv = (*ckpFunctions->C_Decrypt)(ckSessionHandle,
360                                    (CK_BYTE_PTR)(inBufP + jInOfs), jInLen,
361                                    (CK_BYTE_PTR)(outBufP + jOutOfs),
362                                    &ckPartLen);
363
364    (*env)->ReleasePrimitiveArrayCritical(env, jIn, inBufP, JNI_ABORT);
365    (*env)->ReleasePrimitiveArrayCritical(env, jOut, outBufP, JNI_COMMIT);
366
367    ckAssertReturnValueOK(env, rv);
368
369    return ckPartLen;
370}
371#endif
372
373#ifdef P11_ENABLE_C_DECRYPTUPDATE
374/*
375 * Class:     sun_security_pkcs11_wrapper_PKCS11
376 * Method:    C_DecryptUpdate
377 * Signature: (J[BII[BII)I
378 * Parametermapping:                    *PKCS11*
379 * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
380 * @param   jbyteArray jEncryptedPart   CK_BYTE_PTR pEncryptedPart
381 *                                      CK_ULONG ulEncryptedPartLen
382 * @return  jbyteArray jPart            CK_BYTE_PTR pPart
383 *                                      CK_ULONG_PTR pulPartLen
384 */
385JNIEXPORT jint JNICALL
386Java_sun_security_pkcs11_wrapper_PKCS11_C_1DecryptUpdate
387(JNIEnv *env, jobject obj, jlong jSessionHandle,
388 jlong directIn, jbyteArray jIn, jint jInOfs, jint jInLen,
389 jlong directOut, jbyteArray jOut, jint jOutOfs, jint jOutLen)
390{
391    CK_SESSION_HANDLE ckSessionHandle;
392    CK_RV rv;
393
394    CK_BYTE_PTR inBufP;
395    CK_BYTE_PTR outBufP;
396    CK_ULONG ckDecryptedPartLen;
397
398    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
399    if (ckpFunctions == NULL) { return 0; }
400
401    ckSessionHandle = jLongToCKULong(jSessionHandle);
402
403    if (directIn != 0) {
404      inBufP = (CK_BYTE_PTR) jlong_to_ptr(directIn);
405    } else {
406      inBufP = (*env)->GetPrimitiveArrayCritical(env, jIn, NULL);
407      if (inBufP == NULL) { return 0; }
408    }
409
410    if (directOut != 0) {
411      outBufP = (CK_BYTE_PTR) jlong_to_ptr(directOut);
412    } else {
413      outBufP = (*env)->GetPrimitiveArrayCritical(env, jOut, NULL);
414      if (outBufP == NULL) {
415          // Make sure to release inBufP
416          (*env)->ReleasePrimitiveArrayCritical(env, jIn, inBufP, JNI_ABORT);
417          return 0;
418      }
419    }
420
421    ckDecryptedPartLen = jOutLen;
422
423    rv = (*ckpFunctions->C_DecryptUpdate)(ckSessionHandle,
424                                          (CK_BYTE_PTR)(inBufP + jInOfs), jInLen,
425                                          (CK_BYTE_PTR)(outBufP + jOutOfs),
426                                          &ckDecryptedPartLen);
427    if (directIn == 0) {
428        (*env)->ReleasePrimitiveArrayCritical(env, jIn, inBufP, JNI_ABORT);
429    }
430
431    if (directOut == 0) {
432        (*env)->ReleasePrimitiveArrayCritical(env, jOut, outBufP, JNI_COMMIT);
433    }
434
435    ckAssertReturnValueOK(env, rv);
436
437    return ckDecryptedPartLen;
438}
439
440#endif
441
442#ifdef P11_ENABLE_C_DECRYPTFINAL
443/*
444 * Class:     sun_security_pkcs11_wrapper_PKCS11
445 * Method:    C_DecryptFinal
446 * Signature: (J[BII)I
447 * Parametermapping:                    *PKCS11*
448 * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
449 * @return  jbyteArray jLastPart        CK_BYTE_PTR pLastPart
450 *                                      CK_ULONG_PTR pulLastPartLen
451 */
452JNIEXPORT jint JNICALL
453Java_sun_security_pkcs11_wrapper_PKCS11_C_1DecryptFinal
454(JNIEnv *env, jobject obj, jlong jSessionHandle,
455 jlong directOut, jbyteArray jOut, jint jOutOfs, jint jOutLen)
456{
457    CK_SESSION_HANDLE ckSessionHandle;
458    CK_RV rv;
459    CK_BYTE_PTR outBufP;
460    CK_ULONG ckLastPartLen;
461
462    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
463    if (ckpFunctions == NULL) { return 0; }
464
465    ckSessionHandle = jLongToCKULong(jSessionHandle);
466
467    if (directOut != 0) {
468      outBufP = (CK_BYTE_PTR) jlong_to_ptr(directOut);
469    } else {
470      outBufP = (*env)->GetPrimitiveArrayCritical(env, jOut, NULL);
471      if (outBufP == NULL) { return 0; }
472    }
473
474    ckLastPartLen = jOutLen;
475
476    rv = (*ckpFunctions->C_DecryptFinal)(ckSessionHandle,
477                                         (CK_BYTE_PTR)(outBufP + jOutOfs),
478                                         &ckLastPartLen);
479
480    if (directOut == 0) {
481        (*env)->ReleasePrimitiveArrayCritical(env, jOut, outBufP, JNI_COMMIT);
482
483    }
484
485    ckAssertReturnValueOK(env, rv);
486
487    return ckLastPartLen;
488}
489#endif
490