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  */
  68 JNIEXPORT void JNICALL
  69 Java_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  */
 109 JNIEXPORT jint JNICALL
 110 Java_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  */
 164 JNIEXPORT jint JNICALL
 165 Java_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  */
 236 JNIEXPORT jint JNICALL
 237 Java_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  */
 288 JNIEXPORT void JNICALL
 289 Java_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  */
 329 JNIEXPORT jint JNICALL
 330 Java_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  */
 385 JNIEXPORT jint JNICALL
 386 Java_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  */
 452 JNIEXPORT jint JNICALL
 453 Java_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