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