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