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