1 /*
   2  * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 #include <stdlib.h>
  27 #include <string.h>
  28 #include <strings.h>
  29 #include <jni.h>
  30 #include "jni_util.h"
  31 #include "nativeCrypto.h"
  32 #include "nativeFunc.h"
  33 
  34 /*
  35  * Dumps out byte array in hex with and name and length info
  36  */
  37 void printError(char* header, int mech, int rv) {
  38   if (mech != -1) {
  39     printf("%s, mech = %d, rv = 0x%0x\n", header, mech, rv);
  40   } else {
  41     printf("%s, rv = 0x%0x\n", header, rv);
  42   }
  43   if (*ftab->ucryptoStrerror != NULL) {
  44     char * reason = (*ftab->ucryptoStrerror)(rv);
  45     printf("\tcause = %s\n", reason);
  46     free(reason);
  47   }
  48 }
  49 
  50 /*
  51  * Dumps out byte array in hex with and name and length info
  52  */
  53 void printBytes(char* header, unsigned char* bytes, int len) {
  54   int i;
  55 
  56   printf("%s", header);
  57   printf("len=%d {", len);
  58   for (i = 0; i < len; i++) {
  59     if (i > 0) printf(":");
  60     printf("%02X", bytes[i]);
  61   }
  62   printf("}\n");
  63 }
  64 
  65 /*
  66  * Throws java.lang.OutOfMemoryError
  67  */
  68 void throwOutOfMemoryError(JNIEnv *env, const char *msg)
  69 {
  70   jclass jExClass = (*env)->FindClass(env, "java/lang/OutOfMemoryError");
  71   if (jExClass != 0) /* Otherwise an exception has already been thrown */ {
  72     (*env)->ThrowNew(env, jExClass, msg);
  73   }
  74   /* free the local ref */
  75   (*env)->DeleteLocalRef(env, jExClass);
  76 }
  77 
  78 /*
  79  * De-allocates all memory associated with crypto_ctx_t
  80  */
  81 void freeContext(crypto_ctx_t *context) {
  82   if (ftab->ucryptoFreeContext != NULL) {
  83     (*ftab->ucryptoFreeContext)(context);
  84   }
  85   free(context);
  86 }
  87 
  88 JNIEXPORT jint JNICALL DEF_JNI_OnLoad(JavaVM *vm, void *reserved) {
  89     return JNI_VERSION_1_4;
  90 }
  91 
  92 /*
  93  * Class:     com_oracle_security_ucrypto_UcryptoProvider
  94  * Method:    loadLibraries
  95  * Signature: ()[Z
  96  */
  97 JNIEXPORT jbooleanArray JNICALL Java_com_oracle_security_ucrypto_UcryptoProvider_loadLibraries
  98 (JNIEnv *env, jclass jcls) {
  99   jbooleanArray jResult;
 100   jboolean *result;
 101   jResult = (*env)->NewBooleanArray(env, 2);
 102 
 103   if (jResult != NULL) {
 104     result = loadNative();
 105     (*env)->SetBooleanArrayRegion(env, jResult, 0, 2, result);
 106     free(result);
 107   }
 108   return jResult;
 109 }
 110 
 111 /*
 112  * Class:     com_oracle_security_ucrypto_UcryptoProvider
 113  * Method:    getMechList
 114  * Signature: ()Ljava/lang/String;
 115  */
 116 JNIEXPORT jstring JNICALL Java_com_oracle_security_ucrypto_UcryptoProvider_getMechList
 117 (JNIEnv *env, jclass jcls) {
 118   jstring jResult;
 119   char* result;
 120   int length;
 121 
 122   jResult = NULL;
 123   if (ftab->ucryptoVersion != NULL && ftab->ucryptoGetMechList != NULL) {
 124       length = (*ftab->ucryptoGetMechList)(NULL);
 125       if (J2UC_DEBUG) printf("mech list length: %d\n", length);
 126       result = malloc(length);
 127       if (result == NULL) {
 128         throwOutOfMemoryError(env, NULL);
 129         return NULL;
 130       }
 131       length = (*ftab->ucryptoGetMechList)(result);
 132       if (J2UC_DEBUG) printf("mech list: %s\n", result);
 133       jResult = (*env)->NewStringUTF(env, result);
 134       free(result);
 135   } else {
 136       // version 0 on Solaris 10
 137       result = "CRYPTO_AES_ECB,CRYPTO_AES_CBC,CRYPTO_AES_CFB128,";
 138       jResult = (*env)->NewStringUTF(env, result);
 139   }
 140   return jResult;
 141 }
 142 
 143 /*
 144  * Utility function for throwing a UcryptoException when rv is not CRYPTO_OK(0)
 145  */
 146 void throwUCExceptionUsingRV(JNIEnv *env, int rv) {
 147   jclass jExClass;
 148   jmethodID jConstructor;
 149   jthrowable jException;
 150 
 151   if ((*env)->ExceptionCheck(env)) return;
 152 
 153   jExClass = (*env)->FindClass(env, "com/oracle/security/ucrypto/UcryptoException");
 154   /* if jExClass is NULL, an exception has already been thrown */
 155   if (jExClass != NULL) {
 156     jConstructor = (*env)->GetMethodID(env, jExClass, "<init>", "(I)V");
 157     if (jConstructor != NULL) {
 158       jException = (jthrowable) (*env)->NewObject(env, jExClass, jConstructor, rv);
 159       if (jException != NULL) {
 160         (*env)->Throw(env, jException);
 161       }
 162     }
 163   }
 164   /* free the local ref */
 165   (*env)->DeleteLocalRef(env, jExClass);
 166 }
 167 
 168 /*
 169  * Utility function for duplicating a byte array from jbyteArray
 170  * If anything went wrong, no memory will be allocated.
 171  * NOTE: caller is responsible for freeing the allocated memory
 172  * once this method returned successfully.
 173  */
 174 jbyte* getBytes(JNIEnv *env, jbyteArray bytes, int offset, int len) {
 175   jbyte* result = NULL;
 176 
 177   if (!(*env)->ExceptionCheck(env)) {
 178     result = (jbyte*) calloc(len, sizeof(char));
 179     if (result == NULL) {
 180       throwOutOfMemoryError(env, NULL);
 181       return NULL;
 182     }
 183     (*env)->GetByteArrayRegion(env, bytes, offset, len, result);
 184     if ((*env)->ExceptionCheck(env)) {
 185         // free allocated memory if error occurred
 186         free(result);
 187         return NULL;
 188     }
 189   }
 190   return result;
 191 }
 192 
 193 
 194 int
 195 CipherInit(crypto_ctx_t *context, int encrypt, ucrypto_mech_t mech,
 196            unsigned char *jKey, int jKeyLen, unsigned char *jIv, int jIvLen,
 197            int tagLen, unsigned char *jAad, int jAadLen)
 198 
 199 {
 200   int rv = 0;
 201   void *iv;
 202   size_t ivLen;
 203 
 204   if (J2UC_DEBUG) printf("CipherInit: mech %i, key %i(%i), iv %i(%i) tagLen %i, aad %i(%i)\n",
 205                     mech, jKey, jKeyLen, jIv, jIvLen, tagLen, jAad, jAadLen);
 206   if (mech == CRYPTO_AES_CTR) {
 207     ivLen = sizeof(CK_AES_CTR_PARAMS);
 208     iv = (CK_AES_CTR_PARAMS*) malloc(ivLen);
 209     if (iv == NULL) return -1;
 210 
 211     ((CK_AES_CTR_PARAMS*)iv)->ulCounterBits = 32;
 212     memcpy(((CK_AES_CTR_PARAMS*)iv)->cb, jIv, 16);
 213   } else if (mech == CRYPTO_AES_GCM) {
 214     ivLen = sizeof(CK_AES_GCM_PARAMS);
 215     iv = (CK_AES_GCM_PARAMS*) malloc(ivLen);
 216     if (iv == NULL) return -1;
 217 
 218     ((CK_AES_GCM_PARAMS*)iv)->pIv = (uchar_t *)jIv;
 219     ((CK_AES_GCM_PARAMS*)iv)->ulIvLen = (ulong_t)jIvLen;
 220     ((CK_AES_GCM_PARAMS*)iv)->ulIvBits = 96;
 221     ((CK_AES_GCM_PARAMS*)iv)->pAAD = (uchar_t *)jAad;
 222     ((CK_AES_GCM_PARAMS*)iv)->ulAADLen = (ulong_t)jAadLen;
 223     ((CK_AES_GCM_PARAMS*)iv)->ulTagBits = (ulong_t)tagLen;
 224   } else {
 225     // normal bytes
 226     iv = jIv;
 227     ivLen = jIvLen;
 228   }
 229   if (encrypt) {
 230     rv = (*ftab->ucryptoEncryptInit)(context, mech, jKey, (size_t)jKeyLen, iv, ivLen);
 231     if (rv != 0 && J2UC_DEBUG) printError("ucryptoEncryptInit", mech, rv);
 232   } else {
 233     rv =(*ftab->ucryptoDecryptInit)(context, mech, jKey, (size_t)jKeyLen, iv, ivLen);
 234     if (rv != 0 && J2UC_DEBUG) printError("ucryptoDecryptInit", mech, rv);
 235   }
 236 
 237   if (iv != jIv) {
 238     if (mech == CRYPTO_AES_CTR) {
 239       free((CK_AES_CTR_PARAMS*)iv);
 240     } else {
 241       free((CK_AES_GCM_PARAMS*)iv);
 242     }
 243   }
 244 
 245   return rv;
 246 }
 247 
 248 int
 249 CipherUpdate(crypto_ctx_t *context, int encrypt, unsigned char *bufIn, int inOfs,
 250              int inLen, unsigned char *bufOut, int outOfs, int *outLen)
 251 {
 252   int rv = 0;
 253   size_t outLength;
 254 
 255   outLength = (size_t) *outLen;
 256   if (J2UC_DEBUG) {
 257     printf("CipherUpdate: Inofs %i, InLen %i, OutOfs %i, OutLen %i\n", inOfs, inLen, outOfs, *outLen);
 258     printBytes("BufIn=", (unsigned char*)(bufIn+inOfs), inLen);
 259   }
 260   if (encrypt) {
 261     rv = (*ftab->ucryptoEncryptUpdate)(context, (unsigned char*)(bufIn+inOfs), (size_t)inLen, (unsigned char*)(bufOut+outOfs), &outLength);
 262     if (rv) {
 263       if (J2UC_DEBUG) printError("ucryptoEncryptUpdate", -1, rv);
 264     } else {
 265       *outLen = (int)outLength;
 266     }
 267   } else {
 268     rv = (*ftab->ucryptoDecryptUpdate)(context, (unsigned char*)(bufIn+inOfs), (size_t)inLen, (unsigned char*)(bufOut+outOfs), &outLength);
 269     if (rv) {
 270       if (J2UC_DEBUG) printError("ucryptoDecryptUpdate", -1, rv);
 271     } else {
 272       if (J2UC_DEBUG) printBytes("BufOut=", (unsigned char*)(bufOut+outOfs), outLength);
 273       *outLen = (int)outLength;
 274     }
 275   }
 276 
 277   return rv;
 278 }
 279 
 280 int
 281 CipherFinal(crypto_ctx_t *context, int encrypt, unsigned char *bufOut, int outOfs, int *outLen)
 282 {
 283   int rv = 0;
 284   size_t outLength;
 285 
 286   outLength = (size_t)*outLen;
 287 
 288   if (J2UC_DEBUG) printf("CipherFinal: OutOfs %i, outLen %i\n", outOfs, *outLen);
 289   if (encrypt) {
 290     rv = (*ftab->ucryptoEncryptFinal)(context, (unsigned char*)(bufOut+outOfs), &outLength);
 291     if (rv) {
 292       if (J2UC_DEBUG) printError("ucryptoDecryptFinal", -1, rv);
 293     } else {
 294       if (J2UC_DEBUG) printBytes("BufOut=", (unsigned char*)(bufOut+outOfs), outLength);
 295       *outLen = (int)outLength;
 296     }
 297   } else {
 298     rv = (*ftab->ucryptoDecryptFinal)(context, (unsigned char*)(bufOut+outOfs), &outLength);
 299     if (rv) {
 300       if (J2UC_DEBUG) printError("ucryptoDecryptFinal", -1, rv);
 301     } else {
 302       if (J2UC_DEBUG) printBytes("BufOut=", (unsigned char*)(bufOut+outOfs), outLength);
 303       *outLen = (int)outLength;
 304     }
 305   }
 306   return rv;
 307 }
 308 
 309 ////////////////////////////////////////////////////////
 310 // SPECIAL ENTRIES FOR JVM JNI-BYPASSING OPTIMIZATION
 311 ////////////////////////////////////////////////////////
 312 jlong JavaCritical_com_oracle_security_ucrypto_NativeDigest_nativeInit(jint mech) {
 313   crypto_ctx_t *context = NULL;
 314   int rv;
 315 
 316   context = malloc(sizeof(crypto_ctx_t));
 317   if (context != NULL) {
 318     rv = (*ftab->ucryptoDigestInit)(context, (ucrypto_mech_t) mech, NULL, 0);
 319     if (rv) {
 320       freeContext(context);
 321       if (J2UC_DEBUG) printError("ucryptoDigestInit", mech, rv);
 322       return 0L;
 323     }
 324   }
 325   return (jlong) context;
 326 }
 327 
 328 jint JavaCritical_com_oracle_security_ucrypto_NativeDigest_nativeUpdate
 329   (jint mech, jlong pContext, int notUsed, unsigned char* in, jint ofs, jint len) {
 330   crypto_ctx_t *context;
 331   jint rv = 0;
 332 
 333   context = (crypto_ctx_t *) pContext;
 334   rv = (*ftab->ucryptoDigestUpdate)(context, (const unsigned char*)(in + ofs),
 335                                     (size_t) len);
 336 
 337   if (rv) {
 338     freeContext(context);
 339     if (J2UC_DEBUG) printError("ucryptoDigestUpdate", mech, rv);
 340   }
 341 
 342   return -rv; // use negative value to indicate error
 343 }
 344 
 345 jint JavaCritical_com_oracle_security_ucrypto_NativeDigest_nativeDigest
 346   (jint mech, jlong pContext, int notUsed, unsigned char* out, jint ofs, jint digestLen) {
 347   crypto_ctx_t *context;
 348   jint rv = 0;
 349   size_t digest_len = digestLen;
 350 
 351   context = (crypto_ctx_t *) pContext;
 352   rv = (*ftab->ucryptoDigestFinal)(context, (unsigned char*)(out + ofs),
 353                                    &digest_len);
 354   if (rv) {
 355     freeContext(context);
 356     if (J2UC_DEBUG) printError("ucryptoDigestFinal", mech, rv);
 357   }
 358 
 359   return -rv; // use negative value to indicate error
 360 }
 361 
 362 void JavaCritical_com_oracle_security_ucrypto_NativeDigest_nativeFree
 363   (jint mech, jlong pContext) {
 364   crypto_ctx_t *context;
 365 
 366   context = (crypto_ctx_t *) pContext;
 367   freeContext(context);
 368 }
 369 
 370 // AES
 371 jlong JavaCritical_com_oracle_security_ucrypto_NativeCipher_nativeInit
 372   (jint mech, jboolean encrypt, int keyLen, unsigned char* bufKey,
 373    int ivLen, unsigned char* bufIv, jint tagLen, int aadLen, unsigned char* bufAad) {
 374   crypto_ctx_t *context = NULL;
 375   int rv;
 376 
 377   context = malloc(sizeof(crypto_ctx_t));
 378   if (context != NULL) {
 379     rv = CipherInit(context, encrypt, (ucrypto_mech_t) mech, bufKey, keyLen,
 380                     bufIv, ivLen, tagLen, bufAad, aadLen);
 381     if (rv) {
 382       freeContext(context);
 383       return 0L;
 384     }
 385   }
 386   return (jlong)context;
 387 }
 388 
 389 /*
 390  * Class:     com_oracle_security_ucrypto_NativeCipher
 391  * Method:    nativeUpdate
 392  * Signature: (JZ[BII[BI)I
 393  */
 394 jint JavaCritical_com_oracle_security_ucrypto_NativeCipher_nativeUpdate
 395   (jlong pContext, jboolean encrypt, int notUsed, jbyte* bufIn, jint inOfs, jint inLen,
 396    int outCapacity, jbyte* bufOut, jint outOfs) {
 397   crypto_ctx_t *context;
 398   int rv = 0;
 399   int outLen = outCapacity - outOfs; // recalculate the real out length
 400 
 401   context = (crypto_ctx_t *) pContext;
 402   rv = CipherUpdate(context, encrypt, (unsigned char*)bufIn, inOfs, inLen, (unsigned char*)bufOut, outOfs, &outLen);
 403   if (rv) {
 404     freeContext(context);
 405     return -rv; // use negative value to indicate error!
 406   }
 407 
 408   return outLen;
 409 }
 410 
 411 /*
 412  * Class:     com_oracle_security_ucrypto_NativeCipher
 413  * Method:    nativeFinal
 414  * Signature: (JZ[BI)I
 415  */
 416 jint JavaCritical_com_oracle_security_ucrypto_NativeCipher_nativeFinal
 417   (jlong pContext, jboolean encrypt, int outLen, jbyte* out, jint outOfs) {
 418   crypto_ctx_t *context;
 419   int rv = 0;
 420   unsigned char* bufOut = (unsigned char*) out;
 421 
 422   context = (crypto_ctx_t *) pContext;
 423   // Avoid null output buffer to workaround Solaris bug21481818 (fixed in S12)
 424   if (bufOut == NULL) {
 425     bufOut = (unsigned char*)(&outLen);
 426     outLen = 0;
 427   }
 428   rv = CipherFinal(context, encrypt, bufOut, outOfs, &outLen);
 429   freeContext(context);
 430   if (rv) {
 431      return -rv; // use negative value to indicate error!
 432   }
 433 
 434   return outLen;
 435 }
 436 
 437 /*
 438  * Class:     com_oracle_security_ucrypto_NativeDigest
 439  * Method:    nativeInit
 440  * Signature: (I)J
 441  */
 442 JNIEXPORT jlong JNICALL Java_com_oracle_security_ucrypto_NativeDigest_nativeInit
 443   (JNIEnv *env, jclass jcls, jint mech) {
 444   jlong result = JavaCritical_com_oracle_security_ucrypto_NativeDigest_nativeInit(mech);
 445   if (result == NULL) {
 446      throwOutOfMemoryError(env, NULL);
 447   }
 448   return result;
 449 }
 450 
 451 /*
 452  * Class:     com_oracle_security_ucrypto_NativeDigest
 453  * Method:    nativeUpdate
 454  * Signature: (IJ[BII)I
 455  */
 456 JNIEXPORT jint JNICALL Java_com_oracle_security_ucrypto_NativeDigest_nativeUpdate
 457   (JNIEnv *env, jclass jcls, jint mech, jlong pContext, jbyteArray jIn, jint jOfs, jint jLen) {
 458   unsigned char *bufIn;
 459   jint rv = 0;
 460 
 461 
 462   bufIn = (unsigned char *) getBytes(env, jIn, jOfs, jLen);
 463   if (!(*env)->ExceptionCheck(env)) {
 464     rv = JavaCritical_com_oracle_security_ucrypto_NativeDigest_nativeUpdate(mech, pContext, jLen, bufIn, 0, jLen);
 465     free(bufIn);
 466   }
 467   return rv;
 468 }
 469 
 470 /*
 471  * Class:     com_oracle_security_ucrypto_NativeDigest
 472  * Method:    nativeDigest
 473  * Signature: (IJ[BII)I
 474  */
 475 JNIEXPORT jint JNICALL Java_com_oracle_security_ucrypto_NativeDigest_nativeDigest
 476   (JNIEnv *env, jclass jcls, jint mech, jlong pContext, jbyteArray jOut, jint jOutOfs, jint digestLen) {
 477   unsigned char *bufOut;
 478   jint rv = 0;
 479 
 480   bufOut = (unsigned char *) malloc(digestLen);
 481   if (bufOut == NULL) {
 482     throwOutOfMemoryError(env, NULL);
 483     return 0;
 484   }
 485 
 486   rv = JavaCritical_com_oracle_security_ucrypto_NativeDigest_nativeDigest(mech, pContext, digestLen, bufOut, 0, digestLen);
 487   if (rv == 0) {
 488       (*env)->SetByteArrayRegion(env, jOut, jOutOfs, digestLen, (jbyte *) bufOut);
 489   }
 490   free(bufOut);
 491   return rv;
 492 }
 493 
 494 /*
 495  * Class:     com_oracle_security_ucrypto_NativeDigest
 496  * Method:    nativeFree
 497  * Signature: (IJ)V
 498  */
 499 JNIEXPORT void JNICALL Java_com_oracle_security_ucrypto_NativeDigest_nativeFree
 500   (JNIEnv *env, jclass jcls, jint mech, jlong pContext) {
 501   JavaCritical_com_oracle_security_ucrypto_NativeDigest_nativeFree(mech, pContext);
 502 }
 503 
 504 /*
 505  * Class:     com_oracle_security_ucrypto_NativeCipher
 506  * Method:    nativeInit
 507  * Signature: (IZ[B[BI[B)J
 508  */
 509 JNIEXPORT jlong JNICALL Java_com_oracle_security_ucrypto_NativeCipher_nativeInit
 510 (JNIEnv *env, jclass jcls, jint mech, jboolean encrypt, jbyteArray jKey,
 511  jbyteArray jIv, jint tagLen, jbyteArray jAad) {
 512 
 513   crypto_ctx_t *context;
 514   unsigned char *bufKey;
 515   unsigned char *bufIv;
 516   unsigned char *bufAad;
 517   int keyLen, ivLen, aadLen, rv = 0;
 518   jlong result = 0L;
 519 
 520   bufKey = bufIv = bufAad = NULL;
 521   keyLen = ivLen = aadLen = 0;
 522   context = malloc(sizeof(crypto_ctx_t));
 523   if (context == NULL) {
 524     throwOutOfMemoryError(env, NULL);
 525     return 0L;
 526   }
 527 
 528   // jKey MUST NOT BE NULL;
 529   keyLen = (*env)->GetArrayLength(env, jKey);
 530   bufKey = (unsigned char *) (*env)->GetByteArrayElements(env, jKey, NULL);
 531   if (bufKey == NULL) {
 532     goto cleanup;
 533   }
 534 
 535   if (jIv != NULL) {
 536     ivLen = (*env)->GetArrayLength(env, jIv);
 537     bufIv = (unsigned char *) (*env)->GetByteArrayElements(env, jIv, NULL);
 538     if (bufIv == NULL) {
 539       goto cleanup;
 540     }
 541   }
 542 
 543   if (jAad != NULL) {
 544     aadLen = (*env)->GetArrayLength(env, jAad);
 545     bufAad = (unsigned char *) (*env)->GetByteArrayElements(env, jAad, NULL);
 546     if (bufAad == NULL) {
 547       goto cleanup;
 548     }
 549   }
 550 
 551   rv = CipherInit(context, encrypt, mech, bufKey, keyLen, bufIv, ivLen, tagLen, bufAad, aadLen);
 552   if (rv != 0) {
 553     throwUCExceptionUsingRV(env, rv);
 554   } else {
 555      result = (jlong) context;
 556   }
 557 
 558 cleanup:
 559   if ((result == 0L) && (context != NULL)) {
 560     freeContext(context);
 561   }
 562   if (bufKey != NULL) {
 563     (*env)->ReleaseByteArrayElements(env, jKey, (jbyte *)bufKey, 0);
 564   }
 565   if (bufIv != NULL) {
 566     (*env)->ReleaseByteArrayElements(env, jIv, (jbyte *)bufIv, 0);
 567   }
 568   if (bufAad != NULL) {
 569     (*env)->ReleaseByteArrayElements(env, jAad, (jbyte *)bufAad, 0);
 570   }
 571 
 572   return result;
 573 }
 574 
 575 /*
 576  * Class:     com_oracle_security_ucrypto_NativeCipher
 577  * Method:    nativeUpdate
 578  * Signature: (JZ[BII[BI)I
 579  */
 580 JNIEXPORT jint JNICALL Java_com_oracle_security_ucrypto_NativeCipher_nativeUpdate
 581   (JNIEnv *env, jclass jcls, jlong contextID, jboolean encrypt,
 582     jbyteArray jIn, jint inOfs, jint inLen, jbyteArray jOut, jint outOfs) {
 583   crypto_ctx_t *context;
 584   unsigned char *bufIn;
 585   unsigned char *bufOut;
 586   int outLen, rv = 0;
 587 
 588   context = (crypto_ctx_t *) contextID;
 589   bufIn = (unsigned char *) getBytes(env, jIn, inOfs, inLen);
 590   if ((*env)->ExceptionCheck(env)) {
 591     return 0;
 592   }
 593 
 594   outLen = (*env)->GetArrayLength(env, jOut) - outOfs;
 595   bufOut = calloc(outLen, sizeof(char));
 596   if (bufOut == NULL) {
 597     free(bufIn);
 598     throwOutOfMemoryError(env, NULL);
 599     return 0;
 600   }
 601 
 602   rv = CipherUpdate(context, encrypt, bufIn, 0, inLen, bufOut, 0, &outLen);
 603   if (rv) {
 604     freeContext(context);
 605     free(bufIn);
 606     free(bufOut);
 607     return -rv;
 608   } else {
 609     (*env)->SetByteArrayRegion(env, jOut, outOfs, outLen, (jbyte *)bufOut);
 610     free(bufIn);
 611     free(bufOut);
 612     return outLen;
 613   }
 614 }
 615 
 616 /*
 617  * Class:     com_oracle_security_ucrypto_NativeCipher
 618  * Method:    nativeFinal
 619  * Signature: (JZ[BI)I
 620  */
 621 JNIEXPORT jint JNICALL Java_com_oracle_security_ucrypto_NativeCipher_nativeFinal
 622   (JNIEnv *env, jclass jCls, jlong contextID, jboolean encrypt,
 623    jbyteArray out, jint outOfs) {
 624   crypto_ctx_t *context;
 625   unsigned char *bufIn;
 626   unsigned char *bufOut;
 627   int outLen, rv = 0;
 628   jint rc;
 629 
 630   context = (crypto_ctx_t *) contextID;
 631 
 632   // out is null when nativeFinal() is called solely for resource clean up
 633   if (out == NULL) {
 634     // Avoid null output buffer to workaround Solaris bug21481818 (fixed in S12)
 635     bufOut = (unsigned char *)(&outLen);
 636     outLen = 0;
 637   } else {
 638     outLen = (*env)->GetArrayLength(env, out) - outOfs;
 639     bufOut = calloc(outLen, sizeof(char));
 640     if (bufOut == NULL) {
 641       throwOutOfMemoryError(env, NULL);
 642       return 0;
 643     }
 644   }
 645   rv = CipherFinal(context, encrypt, bufOut, 0, &outLen);
 646   if (rv) {
 647     rc = -rv;
 648   } else {
 649     if (outLen > 0) {
 650       (*env)->SetByteArrayRegion(env, out, outOfs, outLen, (jbyte *)bufOut);
 651     }
 652     rc = outLen;
 653   }
 654   free(context);
 655   if (bufOut != (unsigned char *)(&outLen)) {
 656     free(bufOut);
 657   }
 658   return rc;
 659 }
 660 
 661 
 662 /*
 663  * Class:     com_oracle_security_ucrypto_NativeKey
 664  * Method:    nativeFree
 665  * Signature: (JI)V
 666  */
 667 void JavaCritical_com_oracle_security_ucrypto_NativeKey_nativeFree
 668   (jlong id, jint numOfComponents) {
 669   crypto_object_attribute_t* pKey;
 670   int i;
 671 
 672   pKey = (crypto_object_attribute_t*) id;
 673   for (i = 0; i < numOfComponents; i++) {
 674     free(pKey[i].oa_value);
 675   }
 676   free(pKey);
 677 }
 678 
 679 JNIEXPORT void JNICALL Java_com_oracle_security_ucrypto_NativeKey_nativeFree
 680   (JNIEnv *env, jclass jCls, jlong id, jint numOfComponents) {
 681   JavaCritical_com_oracle_security_ucrypto_NativeKey_nativeFree(id, numOfComponents);
 682 }
 683 
 684 /*
 685  * Class:     com_oracle_security_ucrypto_NativeKey_RSAPrivate
 686  * Method:    nativeInit
 687  * Signature: ([B[B)J
 688  */
 689 jlong JavaCritical_com_oracle_security_ucrypto_NativeKey_00024RSAPrivate_nativeInit
 690 (int modLen, jbyte* jMod, int privLen, jbyte* jPriv) {
 691 
 692   unsigned char *mod, *priv;
 693   crypto_object_attribute_t* pKey = NULL;
 694 
 695   pKey = calloc(2, sizeof(crypto_object_attribute_t));
 696   if (pKey == NULL) {
 697     return 0L;
 698   }
 699   mod = priv = NULL;
 700   mod = malloc(modLen);
 701   priv = malloc(privLen);
 702   if (mod == NULL || priv == NULL) {
 703     free(pKey);
 704     free(mod);
 705     free(priv);
 706     return 0L;
 707   } else {
 708     memcpy(mod, jMod, modLen);
 709     memcpy(priv, jPriv, privLen);
 710   }
 711 
 712   // NOTE: numOfComponents should be 2
 713   pKey[0].oa_type = SUN_CKA_MODULUS;
 714   pKey[0].oa_value = (char*) mod;
 715   pKey[0].oa_value_len = (size_t) modLen;
 716   pKey[1].oa_type = SUN_CKA_PRIVATE_EXPONENT;
 717   pKey[1].oa_value = (char*) priv;
 718   pKey[1].oa_value_len = (size_t) privLen;
 719 
 720   return (jlong) pKey;
 721 }
 722 
 723 JNIEXPORT jlong JNICALL
 724 Java_com_oracle_security_ucrypto_NativeKey_00024RSAPrivate_nativeInit
 725   (JNIEnv *env, jclass jCls, jbyteArray jMod, jbyteArray jPriv) {
 726 
 727   int modLen, privLen;
 728   jbyte *bufMod, *bufPriv;
 729   crypto_object_attribute_t* pKey = NULL;
 730 
 731   bufMod = bufPriv = NULL;
 732 
 733   modLen = (*env)->GetArrayLength(env, jMod);
 734   bufMod = getBytes(env, jMod, 0, modLen);
 735   if ((*env)->ExceptionCheck(env)) goto cleanup;
 736 
 737   privLen = (*env)->GetArrayLength(env, jPriv);
 738   bufPriv = getBytes(env, jPriv, 0, privLen);
 739   if ((*env)->ExceptionCheck(env)) goto cleanup;
 740 
 741   // proceed if no error; otherwise free allocated memory
 742   pKey = calloc(2, sizeof(crypto_object_attribute_t));
 743   if (pKey == NULL) {
 744     throwOutOfMemoryError(env, NULL);
 745     goto cleanup;
 746   }
 747 
 748   // NOTE: numOfComponents should be 2
 749   pKey[0].oa_type = SUN_CKA_MODULUS;
 750   pKey[0].oa_value = (char*) bufMod;
 751   pKey[0].oa_value_len = (size_t) modLen;
 752   pKey[1].oa_type = SUN_CKA_PRIVATE_EXPONENT;
 753   pKey[1].oa_value = (char*) bufPriv;
 754   pKey[1].oa_value_len = (size_t) privLen;
 755   return (jlong) pKey;
 756 
 757 cleanup:
 758   free(bufMod);
 759   free(bufPriv);
 760 
 761   return 0L;
 762 }
 763 
 764 /*
 765  * Class:     com_oracle_security_ucrypto_NativeKey_RSAPrivateCrt
 766  * Method:    nativeInit
 767  * Signature: ([B[B[B[B[B[B[B[B)J
 768  */
 769 jlong JavaCritical_com_oracle_security_ucrypto_NativeKey_00024RSAPrivateCrt_nativeInit
 770 (int modLen, jbyte* jMod, int pubLen, jbyte* jPub, int privLen, jbyte* jPriv,
 771  int pLen, jbyte* jP, int qLen, jbyte* jQ, int expPLen, jbyte* jExpP,
 772  int expQLen, jbyte* jExpQ, int crtCoeffLen, jbyte* jCrtCoeff) {
 773 
 774   unsigned char *mod, *pub, *priv, *p, *q, *expP, *expQ, *crtCoeff;
 775   crypto_object_attribute_t* pKey = NULL;
 776 
 777   pKey = calloc(8, sizeof(crypto_object_attribute_t));
 778   if (pKey == NULL) {
 779     return 0L;
 780   }
 781   mod = pub = priv = p = q = expP = expQ = crtCoeff = NULL;
 782   mod = malloc(modLen);
 783   pub = malloc(pubLen);
 784   priv = malloc(privLen);
 785   p = malloc(pLen);
 786   q = malloc(qLen);
 787   expP = malloc(expPLen);
 788   expQ = malloc(expQLen);
 789   crtCoeff = malloc(crtCoeffLen);
 790   if (mod == NULL || pub == NULL || priv == NULL || p == NULL ||
 791       q == NULL || expP == NULL || expQ == NULL || crtCoeff == NULL) {
 792     free(pKey);
 793     free(mod);
 794     free(pub);
 795     free(priv);
 796     free(p);
 797     free(q);
 798     free(expP);
 799     free(expQ);
 800     free(crtCoeff);
 801     return 0L;
 802   } else {
 803     memcpy(mod, jMod, modLen);
 804     memcpy(pub, jPub, pubLen);
 805     memcpy(priv, jPriv, privLen);
 806     memcpy(p, jP, pLen);
 807     memcpy(q, jQ, qLen);
 808     memcpy(expP, jExpP, expPLen);
 809     memcpy(expQ, jExpQ, expQLen);
 810     memcpy(crtCoeff, jCrtCoeff, crtCoeffLen);
 811   }
 812 
 813   // NOTE: numOfComponents should be 8
 814   pKey[0].oa_type = SUN_CKA_MODULUS;
 815   pKey[0].oa_value = (char*) mod;
 816   pKey[0].oa_value_len = (size_t) modLen;
 817   pKey[1].oa_type = SUN_CKA_PUBLIC_EXPONENT;
 818   pKey[1].oa_value = (char*) pub;
 819   pKey[1].oa_value_len = (size_t) pubLen;
 820   pKey[2].oa_type = SUN_CKA_PRIVATE_EXPONENT;
 821   pKey[2].oa_value = (char*) priv;
 822   pKey[2].oa_value_len = (size_t) privLen;
 823   pKey[3].oa_type = SUN_CKA_PRIME_1;
 824   pKey[3].oa_value = (char*) p;
 825   pKey[3].oa_value_len = (size_t) pLen;
 826   pKey[4].oa_type = SUN_CKA_PRIME_2;
 827   pKey[4].oa_value = (char*) q;
 828   pKey[4].oa_value_len = (size_t) qLen;
 829   pKey[5].oa_type = SUN_CKA_EXPONENT_1;
 830   pKey[5].oa_value = (char*) expP;
 831   pKey[5].oa_value_len = (size_t) expPLen;
 832   pKey[6].oa_type = SUN_CKA_EXPONENT_2;
 833   pKey[6].oa_value = (char*) expQ;
 834   pKey[6].oa_value_len = (size_t) expQLen;
 835   pKey[7].oa_type = SUN_CKA_COEFFICIENT;
 836   pKey[7].oa_value = (char*) crtCoeff;
 837   pKey[7].oa_value_len = (size_t) crtCoeffLen;
 838 
 839   return (jlong) pKey;
 840 }
 841 
 842 
 843 JNIEXPORT jlong JNICALL
 844 Java_com_oracle_security_ucrypto_NativeKey_00024RSAPrivateCrt_nativeInit
 845   (JNIEnv *env, jclass jCls, jbyteArray jMod, jbyteArray jPub, jbyteArray jPriv,
 846    jbyteArray jP, jbyteArray jQ, jbyteArray jExpP, jbyteArray jExpQ,
 847    jbyteArray jCrtCoeff) {
 848 
 849   int modLen, pubLen, privLen, pLen, qLen, expPLen, expQLen, crtCoeffLen;
 850   jbyte *bufMod, *bufPub, *bufPriv, *bufP, *bufQ, *bufExpP, *bufExpQ, *bufCrtCoeff;
 851   crypto_object_attribute_t* pKey = NULL;
 852 
 853   bufMod = bufPub = bufPriv = bufP = bufQ = bufExpP = bufExpQ = bufCrtCoeff = NULL;
 854 
 855   modLen = (*env)->GetArrayLength(env, jMod);
 856   bufMod = getBytes(env, jMod, 0, modLen);
 857   if ((*env)->ExceptionCheck(env)) goto cleanup;
 858 
 859   pubLen = (*env)->GetArrayLength(env, jPub);
 860   bufPub = getBytes(env, jPub, 0, pubLen);
 861   if ((*env)->ExceptionCheck(env)) goto cleanup;
 862 
 863   privLen = (*env)->GetArrayLength(env, jPriv);
 864   bufPriv = getBytes(env, jPriv, 0, privLen);
 865   if ((*env)->ExceptionCheck(env)) goto cleanup;
 866 
 867   pLen = (*env)->GetArrayLength(env, jP);
 868   bufP = getBytes(env, jP, 0, pLen);
 869   if ((*env)->ExceptionCheck(env)) goto cleanup;
 870 
 871   qLen = (*env)->GetArrayLength(env, jQ);
 872   bufQ = getBytes(env, jQ, 0, qLen);
 873   if ((*env)->ExceptionCheck(env)) goto cleanup;
 874 
 875   expPLen = (*env)->GetArrayLength(env, jExpP);
 876   bufExpP = getBytes(env, jExpP, 0, expPLen);
 877   if ((*env)->ExceptionCheck(env)) goto cleanup;
 878 
 879   expQLen = (*env)->GetArrayLength(env, jExpQ);
 880   bufExpQ = getBytes(env, jExpQ, 0, expQLen);
 881   if ((*env)->ExceptionCheck(env)) goto cleanup;
 882 
 883   crtCoeffLen = (*env)->GetArrayLength(env, jCrtCoeff);
 884   bufCrtCoeff = getBytes(env, jCrtCoeff, 0, crtCoeffLen);
 885   if ((*env)->ExceptionCheck(env)) goto cleanup;
 886 
 887   // proceed if no error; otherwise free allocated memory
 888   pKey = calloc(8, sizeof(crypto_object_attribute_t));
 889   if (pKey == NULL) {
 890     throwOutOfMemoryError(env, NULL);
 891     goto cleanup;
 892   }
 893 
 894   // NOTE: numOfComponents should be 8
 895   pKey[0].oa_type = SUN_CKA_MODULUS;
 896   pKey[0].oa_value = (char*) bufMod;
 897   pKey[0].oa_value_len = (size_t) modLen;
 898   pKey[1].oa_type = SUN_CKA_PUBLIC_EXPONENT;
 899   pKey[1].oa_value = (char*) bufPub;
 900   pKey[1].oa_value_len = (size_t) pubLen;
 901   pKey[2].oa_type = SUN_CKA_PRIVATE_EXPONENT;
 902   pKey[2].oa_value = (char*) bufPriv;
 903   pKey[2].oa_value_len = (size_t) privLen;
 904   pKey[3].oa_type = SUN_CKA_PRIME_1;
 905   pKey[3].oa_value = (char*) bufP;
 906   pKey[3].oa_value_len = (size_t) pLen;
 907   pKey[4].oa_type = SUN_CKA_PRIME_2;
 908   pKey[4].oa_value = (char*) bufQ;
 909   pKey[4].oa_value_len = (size_t) qLen;
 910   pKey[5].oa_type = SUN_CKA_EXPONENT_1;
 911   pKey[5].oa_value = (char*) bufExpP;
 912   pKey[5].oa_value_len = (size_t) expPLen;
 913   pKey[6].oa_type = SUN_CKA_EXPONENT_2;
 914   pKey[6].oa_value = (char*) bufExpQ;
 915   pKey[6].oa_value_len = (size_t) expQLen;
 916   pKey[7].oa_type = SUN_CKA_COEFFICIENT;
 917   pKey[7].oa_value = (char*) bufCrtCoeff;
 918   pKey[7].oa_value_len = (size_t) crtCoeffLen;
 919   return (jlong) pKey;
 920 
 921 cleanup:
 922   free(bufMod);
 923   free(bufPub);
 924   free(bufPriv);
 925   free(bufP);
 926   free(bufQ);
 927   free(bufExpP);
 928   free(bufExpQ);
 929   free(bufCrtCoeff);
 930 
 931   return 0L;
 932 }
 933 
 934 /*
 935  * Class:     com_oracle_security_ucrypto_NativeKey_RSAPublic
 936  * Method:    nativeInit
 937  * Signature: ([B[B)J
 938  */
 939 
 940 jlong JavaCritical_com_oracle_security_ucrypto_NativeKey_00024RSAPublic_nativeInit
 941 (int modLen, jbyte* jMod, int pubLen, jbyte* jPub) {
 942   unsigned char *mod, *pub;
 943   crypto_object_attribute_t* pKey = NULL;
 944 
 945   pKey = calloc(2, sizeof(crypto_object_attribute_t));
 946   if (pKey == NULL) {
 947     return 0L;
 948   }
 949   mod = pub = NULL;
 950   mod = malloc(modLen);
 951   pub = malloc(pubLen);
 952   if (mod == NULL || pub == NULL) {
 953     free(pKey);
 954     free(mod);
 955     free(pub);
 956     return 0L;
 957   } else {
 958     memcpy(mod, jMod, modLen);
 959     memcpy(pub, jPub, pubLen);
 960   }
 961 
 962   if (J2UC_DEBUG) {
 963     printf("RSAPublicKey.nativeInit: keyValue=%ld, keyLen=2\n", pKey);
 964     printBytes("\tmod: ", (unsigned char*) mod, modLen);
 965     printBytes("\tpubExp: ", (unsigned char*) pub, pubLen);
 966   }
 967 
 968   pKey[0].oa_type = SUN_CKA_MODULUS;
 969   pKey[0].oa_value = (char*) mod;
 970   pKey[0].oa_value_len = (size_t) modLen;
 971   pKey[1].oa_type = SUN_CKA_PUBLIC_EXPONENT;
 972   pKey[1].oa_value = (char*) pub;
 973   pKey[1].oa_value_len = (size_t) pubLen;
 974 
 975   return (jlong) pKey;
 976 }
 977 
 978 JNIEXPORT jlong JNICALL
 979 Java_com_oracle_security_ucrypto_NativeKey_00024RSAPublic_nativeInit
 980 (JNIEnv *env, jclass jCls, jbyteArray jMod, jbyteArray jPub) {
 981   int modLen, pubLen;
 982   jbyte *bufMod, *bufPub;
 983   crypto_object_attribute_t* pKey = NULL;
 984 
 985   bufMod = bufPub = NULL;
 986 
 987   modLen = (*env)->GetArrayLength(env, jMod);
 988   bufMod = getBytes(env, jMod, 0, modLen);
 989   if ((*env)->ExceptionCheck(env)) {
 990     return 0L;
 991   }
 992 
 993   pubLen = (*env)->GetArrayLength(env, jPub);
 994   bufPub = getBytes(env, jPub, 0, pubLen);
 995   if ((*env)->ExceptionCheck(env)) {
 996     free(bufMod);
 997     return 0L;
 998   }
 999 
1000   // proceed if no error; otherwise free allocated memory
1001   pKey = calloc(2, sizeof(crypto_object_attribute_t));
1002   if (pKey != NULL) {
1003     // NOTE: numOfComponents should be 2
1004     pKey[0].oa_type = SUN_CKA_MODULUS;
1005     pKey[0].oa_value = (char*) bufMod;
1006     pKey[0].oa_value_len = (size_t) modLen;
1007     pKey[1].oa_type = SUN_CKA_PUBLIC_EXPONENT;
1008     pKey[1].oa_value = (char*) bufPub;
1009     pKey[1].oa_value_len = (size_t) pubLen;
1010     return (jlong) pKey;
1011   } else {
1012     free(bufMod);
1013     free(bufPub);
1014     throwOutOfMemoryError(env, NULL);
1015     return 0L;
1016   }
1017 }
1018 
1019 ////////////////////////
1020 // NativeRSASignature
1021 ////////////////////////
1022 
1023 int
1024 SignatureInit(crypto_ctx_t *context, jint mechVal, jboolean sign,
1025               uchar_t *pKey, size_t keyLength) {
1026   ucrypto_mech_t mech;
1027   int rv = 0;
1028 
1029   mech = (ucrypto_mech_t) mechVal;
1030 
1031   if (sign) {
1032     rv = (*ftab->ucryptoSignInit)(context, mech, pKey, keyLength,
1033                                   NULL, 0);
1034   } else {
1035     rv = (*ftab->ucryptoVerifyInit)(context, mech, pKey, keyLength,
1036                                     NULL, 0);
1037   }
1038   if (J2UC_DEBUG) {
1039     printf("SignatureInit: context=%ld, mech=%d, sign=%d, keyValue=%ld, keyLength=%d\n",
1040            context, mech, sign, pKey, keyLength);
1041     printError("SignatureInit", mech, rv);
1042   }
1043   return rv;
1044 }
1045 
1046 /*
1047  * Class:     com_oracle_security_ucrypto_NativeRSASignature
1048  * Method:    nativeInit
1049  * Signature: (IZJI[B)J
1050  */
1051 jlong JavaCritical_com_oracle_security_ucrypto_NativeRSASignature_nativeInit
1052 (jint mech, jboolean sign, jlong jKey, jint keyLength) {
1053   crypto_ctx_t *context;
1054   int rv;
1055   uchar_t *pKey;
1056 
1057   context = malloc(sizeof(crypto_ctx_t));
1058   if (context != NULL) {
1059     pKey = (uchar_t *) jKey;
1060     rv = SignatureInit(context, mech, sign, pKey, (size_t)keyLength);
1061     if (rv) {
1062       freeContext(context);
1063       return 0L;
1064     }
1065   }
1066   return (jlong)context;
1067 }
1068 
1069 JNIEXPORT jlong JNICALL Java_com_oracle_security_ucrypto_NativeRSASignature_nativeInit
1070 (JNIEnv *env, jclass jCls, jint mech, jboolean sign, jlong jKey, jint keyLength) {
1071   crypto_ctx_t *context;
1072   int rv = 0;
1073   uchar_t *pKey;
1074 
1075   context = malloc(sizeof(crypto_ctx_t));
1076   if (context == NULL) {
1077     throwOutOfMemoryError(env, NULL);
1078     return 0L;
1079   }
1080 
1081   pKey = (uchar_t *) jKey;
1082   rv = SignatureInit(context, mech, sign, pKey, (size_t)keyLength);
1083   if (rv) {
1084     freeContext(context);
1085     throwUCExceptionUsingRV(env, rv);
1086     return 0L;
1087   }
1088 
1089   return (jlong)context;
1090 }
1091 
1092 /*
1093  * Class:     com_oracle_security_ucrypto_NativeRSASignature
1094  * Method:    nativeUpdate
1095  * Signature: (JZ[BII)I
1096  */
1097 jint JavaCritical_com_oracle_security_ucrypto_NativeRSASignature_nativeUpdate__JZ_3BII
1098 (jlong pCtxt, jboolean sign, int notUsed, jbyte* jIn, jint jInOfs, jint jInLen) {
1099   crypto_ctx_t *context;
1100   int rv = 0;
1101 
1102   context = (crypto_ctx_t *) pCtxt;
1103   if (J2UC_DEBUG) {
1104     printf("NativeRSASignature.nativeUpdate: context=%ld, sign=%d, jIn=%ld, jInOfs=%d, jInLen=%d\n",
1105            context, sign, jIn, jInOfs, jInLen);
1106   }
1107   if (sign) {
1108     rv = (*ftab->ucryptoSignUpdate)(context, (uchar_t *) (jIn + jInOfs), (size_t) jInLen);
1109   } else {
1110     rv = (*ftab->ucryptoVerifyUpdate)(context, (uchar_t *) (jIn + jInOfs), (size_t) jInLen);
1111   }
1112   if (rv) {
1113     freeContext(context);
1114     if (J2UC_DEBUG) printError("NativeRSASignature.nativeUpdate", -1, rv);
1115     return -rv; // use negative value to indicate error!
1116   }
1117 
1118   return 0;
1119 }
1120 
1121 JNIEXPORT jint JNICALL Java_com_oracle_security_ucrypto_NativeRSASignature_nativeUpdate__JZ_3BII
1122 (JNIEnv *env, jclass jCls, jlong pCtxt, jboolean sign, jbyteArray jIn, jint inOfs, jint inLen) {
1123   int rv = 0;
1124   jbyte* bufIn;
1125 
1126   bufIn = getBytes(env, jIn, inOfs, inLen);
1127   if ((*env)->ExceptionCheck(env)) {
1128     return -1; // use negative value to indicate error!
1129   }
1130 
1131   if (J2UC_DEBUG) printBytes("Update w/ data: ", (unsigned char*)bufIn, (size_t) inLen);
1132 
1133   rv = JavaCritical_com_oracle_security_ucrypto_NativeRSASignature_nativeUpdate__JZ_3BII
1134     (pCtxt, sign, inLen, bufIn, 0, inLen);
1135 
1136   free(bufIn);
1137   return rv;
1138 }
1139 
1140 /*
1141  * Class:     com_oracle_security_ucrypto_NativeRSASignature
1142  * Method:    nativeUpdate
1143  * Signature: (JZJI)I
1144  */
1145 jint JavaCritical_com_oracle_security_ucrypto_NativeRSASignature_nativeUpdate__JZJI
1146 (jlong pCtxt, jboolean sign, jlong inAddr, jint inLen) {
1147 
1148   return JavaCritical_com_oracle_security_ucrypto_NativeRSASignature_nativeUpdate__JZ_3BII
1149     (pCtxt, sign, inLen, (jbyte*)inAddr, 0, inLen);
1150 }
1151 
1152 JNIEXPORT jint JNICALL Java_com_oracle_security_ucrypto_NativeRSASignature_nativeUpdate__JZJI
1153 (JNIEnv *env, jclass jCls, jlong pCtxt, jboolean sign, jlong inAddr, jint inLen) {
1154 
1155   return JavaCritical_com_oracle_security_ucrypto_NativeRSASignature_nativeUpdate__JZ_3BII
1156     (pCtxt, sign, inLen, (jbyte*)inAddr, 0, inLen);
1157 }
1158 
1159 /*
1160  * Class:     com_oracle_security_ucrypto_NativeRSASignature
1161  * Method:    nativeFinal
1162  * Signature: (JZ[BII)I
1163  */
1164 jint JavaCritical_com_oracle_security_ucrypto_NativeRSASignature_nativeFinal
1165 (jlong pCtxt, jboolean sign, int notUsed, jbyte* bufSig, jint sigOfs, jint jSigLen) {
1166 
1167   crypto_ctx_t *context;
1168   int rv = 0;
1169   size_t sigLength = (size_t) jSigLen;
1170 
1171   context = (crypto_ctx_t *) pCtxt;
1172   if (J2UC_DEBUG) {
1173       printf("NativeRSASignature.nativeFinal: context=%ld, sign=%d, bufSig=%ld, sigOfs=%d, sigLen=%d\n",
1174              context, sign, bufSig, sigOfs, jSigLen);
1175       printBytes("Before: SigBytes ", (unsigned char*) (bufSig + sigOfs), jSigLen);
1176   }
1177   if (sign) {
1178     rv = (*ftab->ucryptoSignFinal)(context, (uchar_t *) (bufSig + sigOfs), &sigLength);
1179   } else {
1180     rv = (*ftab->ucryptoVerifyFinal)(context, (uchar_t *) (bufSig + sigOfs), &sigLength);
1181   }
1182 
1183   freeContext(context);
1184   if (rv) {
1185     if (J2UC_DEBUG) {
1186       printError("NativeRSASignature.nativeFinal", -1, rv);
1187       if (sigLength != jSigLen) {
1188         printf("NativeRSASignature.nativeFinal out sig len=%d\n", sigLength);
1189       }
1190       if (sign) {
1191         printBytes("After: SigBytes ", (unsigned char*) (bufSig + sigOfs), jSigLen);
1192       }
1193     }
1194     return -rv;
1195   } else return 0;
1196 }
1197 
1198 JNIEXPORT jint JNICALL Java_com_oracle_security_ucrypto_NativeRSASignature_nativeFinal
1199 (JNIEnv *env, jclass jCls, jlong pCtxt, jboolean sign, jbyteArray jSig, jint jSigOfs, jint jSigLen) {
1200   int rv = 0;
1201   jbyte* bufSig = NULL;
1202 
1203   if (jSigLen != 0) {
1204     bufSig = calloc(jSigLen, sizeof(char));
1205     if (bufSig == NULL) {
1206       throwOutOfMemoryError(env, NULL);
1207       return 0;
1208     }
1209     if (!sign) {
1210       // need to copy over the to-be-verified signature bytes
1211       (*env)->GetByteArrayRegion(env, jSig, jSigOfs, jSigLen, (jbyte *)bufSig);
1212     }
1213   }
1214 
1215   if (!(*env)->ExceptionCheck(env)) {
1216     // Frees context + converts rv to negative if error occurred
1217     rv = JavaCritical_com_oracle_security_ucrypto_NativeRSASignature_nativeFinal
1218       (pCtxt, sign, jSigLen, bufSig, 0, jSigLen);
1219 
1220     if (rv == 0 && sign) {
1221       // need to copy the generated signature bytes to the java bytearray
1222       (*env)->SetByteArrayRegion(env, jSig, jSigOfs, jSigLen, (jbyte *)bufSig);
1223     }
1224   } else {
1225     // set rv to negative to indicate error
1226     rv = -1;
1227   }
1228 
1229   free(bufSig);
1230 
1231   return rv;
1232 }
1233 
1234 /*
1235  * Class:     com_oracle_security_ucrypto_NativeRSACipher
1236  * Method:    nativeAtomic
1237  * Signature: (IZJI[BI[BII)I
1238  */
1239 jint JavaCritical_com_oracle_security_ucrypto_NativeRSACipher_nativeAtomic
1240   (jint mech, jboolean encrypt, jlong keyValue, jint keyLength,
1241    int notUsed1, jbyte* bufIn, jint jInLen,
1242    int notUsed2, jbyte* bufOut, jint jOutOfs, jint jOutLen) {
1243 
1244   uchar_t *pKey;
1245   crypto_object_attribute_t* pKey2;
1246   int rv = 0;
1247   size_t outLength = (size_t) jOutLen;
1248 
1249   pKey = (uchar_t *) keyValue;
1250   if (J2UC_DEBUG) {
1251     printf("NativeRSACipher.nativeAtomic: mech=%d, encrypt=%d, pKey=%ld, keyLength=%d\n",
1252            mech, encrypt, pKey, keyLength);
1253     printBytes("Before: in  = ", (unsigned char*) bufIn, jInLen);
1254     printBytes("Before: out = ", (unsigned char*) (bufOut + jOutOfs), jOutLen);
1255   }
1256 
1257   if (encrypt) {
1258     rv = (*ftab->ucryptoEncrypt)((ucrypto_mech_t)mech, pKey, (size_t)keyLength,
1259       NULL, 0, (uchar_t *)bufIn, (size_t)jInLen,
1260       (uchar_t *)(bufOut + jOutOfs), &outLength);
1261   } else {
1262     rv = (*ftab->ucryptoDecrypt)((ucrypto_mech_t)mech, pKey, (size_t)keyLength,
1263       NULL, 0, (uchar_t *)bufIn, (size_t)jInLen,
1264       (uchar_t *)(bufOut + jOutOfs), &outLength);
1265   }
1266   if (J2UC_DEBUG) {
1267     printError("NativeRSACipher.nativeAtomic", mech, rv);
1268     if (outLength != jOutLen) {
1269       printf("NativeRSACipher.nativeAtomic out len=%d\n", outLength);
1270     }
1271     printBytes("After: ", (unsigned char*) (bufOut + jOutOfs), outLength);
1272   }
1273 
1274   if (rv) {
1275     return -rv;
1276   } else return outLength;
1277 }
1278 
1279 JNIEXPORT jint JNICALL Java_com_oracle_security_ucrypto_NativeRSACipher_nativeAtomic
1280   (JNIEnv *env, jclass jCls, jint mech, jboolean encrypt,
1281    jlong keyValue, jint keyLength, jbyteArray jIn, jint jInLen,
1282    jbyteArray jOut, jint jOutOfs, jint jOutLen) {
1283   int rv = 0;
1284   jbyte *bufIn = NULL;
1285   jbyte *bufOut = NULL;
1286 
1287   if (jInLen != 0) {
1288     bufIn = (*env)->GetByteArrayElements(env, jIn, NULL);
1289     if (bufIn == NULL) {
1290       return 0;
1291     }
1292   }
1293   bufOut = calloc(jOutLen, sizeof(jbyte));
1294   if (bufOut == NULL) {
1295     (*env)->ReleaseByteArrayElements(env, jIn, bufIn, 0);
1296     throwOutOfMemoryError(env, NULL);
1297     return 0;
1298   }
1299 
1300   // rv: output length or error code (if negative)
1301   rv = JavaCritical_com_oracle_security_ucrypto_NativeRSACipher_nativeAtomic
1302     (mech, encrypt, keyValue, keyLength, jInLen, bufIn, jInLen,
1303      jOutLen, bufOut, 0, jOutLen);
1304 
1305   if (rv > 0) {
1306     (*env)->SetByteArrayRegion(env, jOut, jOutOfs, rv, (jbyte *)bufOut);
1307   }
1308 
1309   if (bufIn != NULL) {
1310     (*env)->ReleaseByteArrayElements(env, jIn, bufIn, 0);
1311   }
1312   free(bufOut);
1313   return rv;
1314 }