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 }