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 <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* out, jint outOfs) { 434 crypto_ctx_t *context; 435 int rv = 0; 436 unsigned char* bufOut = (unsigned char*) out; 437 438 context = (crypto_ctx_t *) pContext; 439 // Avoid null output buffer to workaround Solaris bug21481818 (fixed in S12) 440 if (bufOut == NULL) { 441 bufOut = (unsigned char*)(&outLen); 442 outLen = 0; 443 } 444 rv = CipherFinal(context, encrypt, bufOut, outOfs, &outLen); 445 free(context); 446 if (rv) { 447 return -rv; // use negative value to indicate error! 448 } 449 450 return outLen; 451 } 452 453 454 455 /* 456 * Class: com_oracle_security_ucrypto_NativeDigest 457 * Method: nativeInit 458 * Signature: (I)J 459 */ 460 JNIEXPORT jlong JNICALL Java_com_oracle_security_ucrypto_NativeDigest_nativeInit 461 (JNIEnv *env, jclass jcls, jint mech) { 462 jlong result = JavaCritical_com_oracle_security_ucrypto_NativeDigest_nativeInit(mech); 463 if (result == NULL) { 464 throwOutOfMemoryError(env, NULL); 465 } 466 return result; 467 } 468 469 /* 470 * Class: com_oracle_security_ucrypto_NativeDigest 471 * Method: nativeUpdate 472 * Signature: (IJ[BII)I 473 */ 474 JNIEXPORT jint JNICALL Java_com_oracle_security_ucrypto_NativeDigest_nativeUpdate 475 (JNIEnv *env, jclass jcls, jint mech, jlong pContext, jbyteArray jIn, jint jOfs, jint jLen) { 476 unsigned char *bufIn; 477 478 bufIn = (unsigned char *) getBytes(env, jIn, jOfs, jLen); 479 if (!(*env)->ExceptionCheck(env)) { 480 JavaCritical_com_oracle_security_ucrypto_NativeDigest_nativeUpdate(mech, pContext, jLen, bufIn, 0, jLen); 481 free(bufIn); 482 } 483 return 0; 484 } 485 486 /* 487 * Class: com_oracle_security_ucrypto_NativeDigest 488 * Method: nativeDigest 489 * Signature: (IJ[BII)I 490 */ 491 JNIEXPORT jint JNICALL Java_com_oracle_security_ucrypto_NativeDigest_nativeDigest 492 (JNIEnv *env, jclass jcls, jint mech, jlong pContext, jbyteArray jOut, jint jOutOfs, jint digestLen) { 493 unsigned char *bufOut; 494 495 bufOut = (unsigned char *) malloc(digestLen); 496 if (bufOut == NULL) { 497 throwOutOfMemoryError(env, NULL); 498 return 0; 499 } 500 501 JavaCritical_com_oracle_security_ucrypto_NativeDigest_nativeDigest(mech, pContext, digestLen, bufOut, 0, digestLen); 502 503 (*env)->SetByteArrayRegion(env, jOut, jOutOfs, digestLen, (jbyte *) bufOut); 504 free(bufOut); 505 return 0; 506 } 507 508 /* 509 * Class: com_oracle_security_ucrypto_NativeDigest 510 * Method: nativeClone 511 * Signature: (IJ)J 512 */ 513 JNIEXPORT jlong JNICALL Java_com_oracle_security_ucrypto_NativeDigest_nativeClone 514 (JNIEnv *env, jclass jcls, jint mech, jlong pContext) { 515 return JavaCritical_com_oracle_security_ucrypto_NativeDigest_nativeClone(mech, pContext); 516 } 517 518 /* 519 * Class: com_oracle_security_ucrypto_NativeDigest 520 * Method: nativeFree 521 * Signature: (IJ)V 522 */ 523 JNIEXPORT void JNICALL Java_com_oracle_security_ucrypto_NativeDigest_nativeFree 524 (JNIEnv *env, jclass jcls, jint mech, jlong pContext) { 525 JavaCritical_com_oracle_security_ucrypto_NativeDigest_nativeFree(mech, pContext); 526 } 527 528 /* 529 * Class: com_oracle_security_ucrypto_NativeCipher 530 * Method: nativeInit 531 * Signature: (IZ[B[BI[B)J 532 */ 533 JNIEXPORT jlong JNICALL Java_com_oracle_security_ucrypto_NativeCipher_nativeInit 534 (JNIEnv *env, jclass jcls, jint mech, jboolean encrypt, jbyteArray jKey, 535 jbyteArray jIv, jint tagLen, jbyteArray jAad) { 536 537 crypto_ctx_t *context; 538 unsigned char *bufKey; 539 unsigned char *bufIv; 540 unsigned char *bufAad; 541 int keyLen, ivLen, aadLen, rv = 0; 542 jlong result = 0L; 543 544 bufKey = bufIv = bufAad = NULL; 545 keyLen = ivLen = aadLen = 0; 546 context = malloc(sizeof(crypto_ctx_t)); 547 if (context == NULL) { 548 throwOutOfMemoryError(env, NULL); 549 return 0L; 550 } 551 552 // jKey MUST NOT BE NULL; 553 keyLen = (*env)->GetArrayLength(env, jKey); 554 bufKey = (unsigned char *) (*env)->GetByteArrayElements(env, jKey, NULL); 555 if (bufKey == NULL) { 556 goto cleanup; 557 } 558 559 if (jIv != NULL) { 560 ivLen = (*env)->GetArrayLength(env, jIv); 561 bufIv = (unsigned char *) (*env)->GetByteArrayElements(env, jIv, NULL); 562 if (bufIv == NULL) { 563 goto cleanup; 564 } 565 } 566 567 if (jAad != NULL) { 568 aadLen = (*env)->GetArrayLength(env, jAad); 569 bufAad = (unsigned char *) (*env)->GetByteArrayElements(env, jAad, NULL); 570 if (bufAad == NULL) { 571 goto cleanup; 572 } 573 } 574 575 rv = CipherInit(context, encrypt, mech, bufKey, keyLen, bufIv, ivLen, tagLen, bufAad, aadLen); 576 if (rv != 0) { 577 throwUCExceptionUsingRV(env, rv); 578 } else { 579 result = (jlong) context; 580 } 581 582 cleanup: 583 if ((result == 0L) && (context != NULL)) { 584 free(context); 585 } 586 if (bufKey != NULL) { 587 (*env)->ReleaseByteArrayElements(env, jKey, (jbyte *)bufKey, 0); 588 } 589 if (bufIv != NULL) { 590 (*env)->ReleaseByteArrayElements(env, jIv, (jbyte *)bufIv, 0); 591 } 592 if (bufAad != NULL) { 593 (*env)->ReleaseByteArrayElements(env, jAad, (jbyte *)bufAad, 0); 594 } 595 596 return result; 597 } 598 599 /* 600 * Class: com_oracle_security_ucrypto_NativeCipher 601 * Method: nativeUpdate 602 * Signature: (JZ[BII[BI)I 603 */ 604 JNIEXPORT jint JNICALL Java_com_oracle_security_ucrypto_NativeCipher_nativeUpdate 605 (JNIEnv *env, jclass jcls, jlong contextID, jboolean encrypt, 606 jbyteArray jIn, jint inOfs, jint inLen, jbyteArray jOut, jint outOfs) { 607 crypto_ctx_t *context; 608 unsigned char *bufIn; 609 unsigned char *bufOut; 610 int outLen, rv = 0; 611 612 context = (crypto_ctx_t *) contextID; 613 bufIn = (unsigned char *) getBytes(env, jIn, inOfs, inLen); 614 if ((*env)->ExceptionCheck(env)) { 615 return 0; 616 } 617 618 outLen = (*env)->GetArrayLength(env, jOut) - outOfs; 619 bufOut = calloc(outLen, sizeof(char)); 620 if (bufOut == NULL) { 621 free(bufIn); 622 throwOutOfMemoryError(env, NULL); 623 return 0; 624 } 625 626 rv = CipherUpdate(context, encrypt, bufIn, 0, inLen, bufOut, 0, &outLen); 627 if (rv) { 628 free(context); 629 free(bufIn); 630 free(bufOut); 631 return -rv; 632 } else { 633 (*env)->SetByteArrayRegion(env, jOut, outOfs, outLen, (jbyte *)bufOut); 634 free(bufIn); 635 free(bufOut); 636 return outLen; 637 } 638 } 639 640 /* 641 * Class: com_oracle_security_ucrypto_NativeCipher 642 * Method: nativeFinal 643 * Signature: (JZ[BI)I 644 */ 645 JNIEXPORT jint JNICALL Java_com_oracle_security_ucrypto_NativeCipher_nativeFinal 646 (JNIEnv *env, jclass jCls, jlong contextID, jboolean encrypt, 647 jbyteArray out, jint outOfs) { 648 crypto_ctx_t *context; 649 unsigned char *bufIn; 650 unsigned char *bufOut; 651 int outLen, rv = 0; 652 653 context = (crypto_ctx_t *) contextID; 654 655 // out is null when nativeFinal() is called solely for resource clean up 656 if (out == NULL) { 657 // Avoid null output buffer to workaround Solaris bug21481818 (fixed in S12) 658 bufOut = (unsigned char *)(&outLen); 659 outLen = 0; 660 } else { 661 outLen = (*env)->GetArrayLength(env, out) - outOfs; 662 bufOut = calloc(outLen, sizeof(char)); 663 if (bufOut == NULL) { 664 throwOutOfMemoryError(env, NULL); 665 return 0; 666 } 667 } 668 rv = CipherFinal(context, encrypt, bufOut, 0, &outLen); 669 if (rv) { 670 free(context); 671 if (outLen != 0) { 672 free(bufOut); 673 } 674 return -rv; 675 } else { 676 if (bufOut != NULL && outLen != 0) { 677 (*env)->SetByteArrayRegion(env, out, outOfs, outLen, (jbyte *)bufOut); 678 free(bufOut); 679 } 680 free(context); 681 return outLen; 682 } 683 } 684 685 686 /* 687 * Class: com_oracle_security_ucrypto_NativeKey 688 * Method: nativeFree 689 * Signature: (JI)V 690 */ 691 void JavaCritical_com_oracle_security_ucrypto_NativeKey_nativeFree 692 (jlong id, jint numOfComponents) { 693 crypto_object_attribute_t* pKey; 694 int i; 695 696 pKey = (crypto_object_attribute_t*) id; 697 for (i = 0; i < numOfComponents; i++) { 698 free(pKey[i].oa_value); 699 } 700 free(pKey); 701 } 702 703 JNIEXPORT void JNICALL Java_com_oracle_security_ucrypto_NativeKey_nativeFree 704 (JNIEnv *env, jclass jCls, jlong id, jint numOfComponents) { 705 JavaCritical_com_oracle_security_ucrypto_NativeKey_nativeFree(id, numOfComponents); 706 } 707 708 /* 709 * Class: com_oracle_security_ucrypto_NativeKey_RSAPrivate 710 * Method: nativeInit 711 * Signature: ([B[B)J 712 */ 713 jlong JavaCritical_com_oracle_security_ucrypto_NativeKey_00024RSAPrivate_nativeInit 714 (int modLen, jbyte* jMod, int privLen, jbyte* jPriv) { 715 716 unsigned char *mod, *priv; 717 crypto_object_attribute_t* pKey = NULL; 718 719 pKey = calloc(2, sizeof(crypto_object_attribute_t)); 720 if (pKey == NULL) { 721 return 0L; 722 } 723 mod = priv = NULL; 724 mod = malloc(modLen); 725 priv = malloc(privLen); 726 if (mod == NULL || priv == NULL) { 727 free(pKey); 728 free(mod); 729 free(priv); 730 return 0L; 731 } else { 732 memcpy(mod, jMod, modLen); 733 memcpy(priv, jPriv, privLen); 734 } 735 736 // NOTE: numOfComponents should be 2 737 pKey[0].oa_type = SUN_CKA_MODULUS; 738 pKey[0].oa_value = (char*) mod; 739 pKey[0].oa_value_len = (size_t) modLen; 740 pKey[1].oa_type = SUN_CKA_PRIVATE_EXPONENT; 741 pKey[1].oa_value = (char*) priv; 742 pKey[1].oa_value_len = (size_t) privLen; 743 744 return (jlong) pKey; 745 } 746 747 JNIEXPORT jlong JNICALL 748 Java_com_oracle_security_ucrypto_NativeKey_00024RSAPrivate_nativeInit 749 (JNIEnv *env, jclass jCls, jbyteArray jMod, jbyteArray jPriv) { 750 751 int modLen, privLen; 752 jbyte *bufMod, *bufPriv; 753 crypto_object_attribute_t* pKey = NULL; 754 755 bufMod = bufPriv = NULL; 756 757 modLen = (*env)->GetArrayLength(env, jMod); 758 bufMod = getBytes(env, jMod, 0, modLen); 759 if ((*env)->ExceptionCheck(env)) goto cleanup; 760 761 privLen = (*env)->GetArrayLength(env, jPriv); 762 bufPriv = getBytes(env, jPriv, 0, privLen); 763 if ((*env)->ExceptionCheck(env)) goto cleanup; 764 765 // proceed if no error; otherwise free allocated memory 766 pKey = calloc(2, sizeof(crypto_object_attribute_t)); 767 if (pKey == NULL) { 768 throwOutOfMemoryError(env, NULL); 769 goto cleanup; 770 } 771 772 // NOTE: numOfComponents should be 2 773 pKey[0].oa_type = SUN_CKA_MODULUS; 774 pKey[0].oa_value = (char*) bufMod; 775 pKey[0].oa_value_len = (size_t) modLen; 776 pKey[1].oa_type = SUN_CKA_PRIVATE_EXPONENT; 777 pKey[1].oa_value = (char*) bufPriv; 778 pKey[1].oa_value_len = (size_t) privLen; 779 return (jlong) pKey; 780 781 cleanup: 782 free(bufMod); 783 free(bufPriv); 784 785 return 0L; 786 } 787 788 /* 789 * Class: com_oracle_security_ucrypto_NativeKey_RSAPrivateCrt 790 * Method: nativeInit 791 * Signature: ([B[B[B[B[B[B[B[B)J 792 */ 793 jlong JavaCritical_com_oracle_security_ucrypto_NativeKey_00024RSAPrivateCrt_nativeInit 794 (int modLen, jbyte* jMod, int pubLen, jbyte* jPub, int privLen, jbyte* jPriv, 795 int pLen, jbyte* jP, int qLen, jbyte* jQ, int expPLen, jbyte* jExpP, 796 int expQLen, jbyte* jExpQ, int crtCoeffLen, jbyte* jCrtCoeff) { 797 798 unsigned char *mod, *pub, *priv, *p, *q, *expP, *expQ, *crtCoeff; 799 crypto_object_attribute_t* pKey = NULL; 800 801 pKey = calloc(8, sizeof(crypto_object_attribute_t)); 802 if (pKey == NULL) { 803 return 0L; 804 } 805 mod = pub = priv = p = q = expP = expQ = crtCoeff = NULL; 806 mod = malloc(modLen); 807 pub = malloc(pubLen); 808 priv = malloc(privLen); 809 p = malloc(pLen); 810 q = malloc(qLen); 811 expP = malloc(expPLen); 812 expQ = malloc(expQLen); 813 crtCoeff = malloc(crtCoeffLen); 814 if (mod == NULL || pub == NULL || priv == NULL || p == NULL || 815 q == NULL || expP == NULL || expQ == NULL || crtCoeff == NULL) { 816 free(pKey); 817 free(mod); 818 free(pub); 819 free(priv); 820 free(p); 821 free(q); 822 free(expP); 823 free(expQ); 824 free(crtCoeff); 825 return 0L; 826 } else { 827 memcpy(mod, jMod, modLen); 828 memcpy(pub, jPub, pubLen); 829 memcpy(priv, jPriv, privLen); 830 memcpy(p, jP, pLen); 831 memcpy(q, jQ, qLen); 832 memcpy(expP, jExpP, expPLen); 833 memcpy(expQ, jExpQ, expQLen); 834 memcpy(crtCoeff, jCrtCoeff, crtCoeffLen); 835 } 836 837 // NOTE: numOfComponents should be 8 838 pKey[0].oa_type = SUN_CKA_MODULUS; 839 pKey[0].oa_value = (char*) mod; 840 pKey[0].oa_value_len = (size_t) modLen; 841 pKey[1].oa_type = SUN_CKA_PUBLIC_EXPONENT; 842 pKey[1].oa_value = (char*) pub; 843 pKey[1].oa_value_len = (size_t) pubLen; 844 pKey[2].oa_type = SUN_CKA_PRIVATE_EXPONENT; 845 pKey[2].oa_value = (char*) priv; 846 pKey[2].oa_value_len = (size_t) privLen; 847 pKey[3].oa_type = SUN_CKA_PRIME_1; 848 pKey[3].oa_value = (char*) p; 849 pKey[3].oa_value_len = (size_t) pLen; 850 pKey[4].oa_type = SUN_CKA_PRIME_2; 851 pKey[4].oa_value = (char*) q; 852 pKey[4].oa_value_len = (size_t) qLen; 853 pKey[5].oa_type = SUN_CKA_EXPONENT_1; 854 pKey[5].oa_value = (char*) expP; 855 pKey[5].oa_value_len = (size_t) expPLen; 856 pKey[6].oa_type = SUN_CKA_EXPONENT_2; 857 pKey[6].oa_value = (char*) expQ; 858 pKey[6].oa_value_len = (size_t) expQLen; 859 pKey[7].oa_type = SUN_CKA_COEFFICIENT; 860 pKey[7].oa_value = (char*) crtCoeff; 861 pKey[7].oa_value_len = (size_t) crtCoeffLen; 862 863 return (jlong) pKey; 864 } 865 866 867 JNIEXPORT jlong JNICALL 868 Java_com_oracle_security_ucrypto_NativeKey_00024RSAPrivateCrt_nativeInit 869 (JNIEnv *env, jclass jCls, jbyteArray jMod, jbyteArray jPub, jbyteArray jPriv, 870 jbyteArray jP, jbyteArray jQ, jbyteArray jExpP, jbyteArray jExpQ, 871 jbyteArray jCrtCoeff) { 872 873 int modLen, pubLen, privLen, pLen, qLen, expPLen, expQLen, crtCoeffLen; 874 jbyte *bufMod, *bufPub, *bufPriv, *bufP, *bufQ, *bufExpP, *bufExpQ, *bufCrtCoeff; 875 crypto_object_attribute_t* pKey = NULL; 876 877 bufMod = bufPub = bufPriv = bufP = bufQ = bufExpP = bufExpQ = bufCrtCoeff = NULL; 878 879 modLen = (*env)->GetArrayLength(env, jMod); 880 bufMod = getBytes(env, jMod, 0, modLen); 881 if ((*env)->ExceptionCheck(env)) goto cleanup; 882 883 pubLen = (*env)->GetArrayLength(env, jPub); 884 bufPub = getBytes(env, jPub, 0, pubLen); 885 if ((*env)->ExceptionCheck(env)) goto cleanup; 886 887 privLen = (*env)->GetArrayLength(env, jPriv); 888 bufPriv = getBytes(env, jPriv, 0, privLen); 889 if ((*env)->ExceptionCheck(env)) goto cleanup; 890 891 pLen = (*env)->GetArrayLength(env, jP); 892 bufP = getBytes(env, jP, 0, pLen); 893 if ((*env)->ExceptionCheck(env)) goto cleanup; 894 895 qLen = (*env)->GetArrayLength(env, jQ); 896 bufQ = getBytes(env, jQ, 0, qLen); 897 if ((*env)->ExceptionCheck(env)) goto cleanup; 898 899 expPLen = (*env)->GetArrayLength(env, jExpP); 900 bufExpP = getBytes(env, jExpP, 0, expPLen); 901 if ((*env)->ExceptionCheck(env)) goto cleanup; 902 903 expQLen = (*env)->GetArrayLength(env, jExpQ); 904 bufExpQ = getBytes(env, jExpQ, 0, expQLen); 905 if ((*env)->ExceptionCheck(env)) goto cleanup; 906 907 crtCoeffLen = (*env)->GetArrayLength(env, jCrtCoeff); 908 bufCrtCoeff = getBytes(env, jCrtCoeff, 0, crtCoeffLen); 909 if ((*env)->ExceptionCheck(env)) goto cleanup; 910 911 // proceed if no error; otherwise free allocated memory 912 pKey = calloc(8, sizeof(crypto_object_attribute_t)); 913 if (pKey == NULL) { 914 throwOutOfMemoryError(env, NULL); 915 goto cleanup; 916 } 917 918 // NOTE: numOfComponents should be 8 919 pKey[0].oa_type = SUN_CKA_MODULUS; 920 pKey[0].oa_value = (char*) bufMod; 921 pKey[0].oa_value_len = (size_t) modLen; 922 pKey[1].oa_type = SUN_CKA_PUBLIC_EXPONENT; 923 pKey[1].oa_value = (char*) bufPub; 924 pKey[1].oa_value_len = (size_t) pubLen; 925 pKey[2].oa_type = SUN_CKA_PRIVATE_EXPONENT; 926 pKey[2].oa_value = (char*) bufPriv; 927 pKey[2].oa_value_len = (size_t) privLen; 928 pKey[3].oa_type = SUN_CKA_PRIME_1; 929 pKey[3].oa_value = (char*) bufP; 930 pKey[3].oa_value_len = (size_t) pLen; 931 pKey[4].oa_type = SUN_CKA_PRIME_2; 932 pKey[4].oa_value = (char*) bufQ; 933 pKey[4].oa_value_len = (size_t) qLen; 934 pKey[5].oa_type = SUN_CKA_EXPONENT_1; 935 pKey[5].oa_value = (char*) bufExpP; 936 pKey[5].oa_value_len = (size_t) expPLen; 937 pKey[6].oa_type = SUN_CKA_EXPONENT_2; 938 pKey[6].oa_value = (char*) bufExpQ; 939 pKey[6].oa_value_len = (size_t) expQLen; 940 pKey[7].oa_type = SUN_CKA_COEFFICIENT; 941 pKey[7].oa_value = (char*) bufCrtCoeff; 942 pKey[7].oa_value_len = (size_t) crtCoeffLen; 943 return (jlong) pKey; 944 945 cleanup: 946 free(bufMod); 947 free(bufPub); 948 free(bufPriv); 949 free(bufP); 950 free(bufQ); 951 free(bufExpP); 952 free(bufExpQ); 953 free(bufCrtCoeff); 954 955 return 0L; 956 } 957 958 /* 959 * Class: com_oracle_security_ucrypto_NativeKey_RSAPublic 960 * Method: nativeInit 961 * Signature: ([B[B)J 962 */ 963 964 jlong JavaCritical_com_oracle_security_ucrypto_NativeKey_00024RSAPublic_nativeInit 965 (int modLen, jbyte* jMod, int pubLen, jbyte* jPub) { 966 unsigned char *mod, *pub; 967 crypto_object_attribute_t* pKey = NULL; 968 969 pKey = calloc(2, sizeof(crypto_object_attribute_t)); 970 if (pKey == NULL) { 971 return 0L; 972 } 973 mod = pub = NULL; 974 mod = malloc(modLen); 975 pub = malloc(pubLen); 976 if (mod == NULL || pub == NULL) { 977 free(pKey); 978 free(mod); 979 free(pub); 980 return 0L; 981 } else { 982 memcpy(mod, jMod, modLen); 983 memcpy(pub, jPub, pubLen); 984 } 985 986 if (DEBUG) { 987 printf("RSAPublicKey Init: keyValue=%ld, keyLen=2\n", pKey); 988 printBytes("RSA PublicKey mod: ", (unsigned char*) mod, modLen); 989 printBytes("RSA PublicKey pubExp: ", (unsigned char*) pub, pubLen); 990 } 991 992 pKey[0].oa_type = SUN_CKA_MODULUS; 993 pKey[0].oa_value = (char*) mod; 994 pKey[0].oa_value_len = (size_t) modLen; 995 pKey[1].oa_type = SUN_CKA_PUBLIC_EXPONENT; 996 pKey[1].oa_value = (char*) pub; 997 pKey[1].oa_value_len = (size_t) pubLen; 998 999 return (jlong) pKey; 1000 } 1001 1002 JNIEXPORT jlong JNICALL 1003 Java_com_oracle_security_ucrypto_NativeKey_00024RSAPublic_nativeInit 1004 (JNIEnv *env, jclass jCls, jbyteArray jMod, jbyteArray jPub) { 1005 int modLen, pubLen; 1006 jbyte *bufMod, *bufPub; 1007 crypto_object_attribute_t* pKey = NULL; 1008 1009 bufMod = bufPub = NULL; 1010 1011 modLen = (*env)->GetArrayLength(env, jMod); 1012 bufMod = getBytes(env, jMod, 0, modLen); 1013 if ((*env)->ExceptionCheck(env)) { 1014 return 0L; 1015 } 1016 1017 pubLen = (*env)->GetArrayLength(env, jPub); 1018 bufPub = getBytes(env, jPub, 0, pubLen); 1019 if ((*env)->ExceptionCheck(env)) { 1020 free(bufMod); 1021 return 0L; 1022 } 1023 1024 // proceed if no error; otherwise free allocated memory 1025 pKey = calloc(2, sizeof(crypto_object_attribute_t)); 1026 if (pKey != NULL) { 1027 // NOTE: numOfComponents should be 2 1028 pKey[0].oa_type = SUN_CKA_MODULUS; 1029 pKey[0].oa_value = (char*) bufMod; 1030 pKey[0].oa_value_len = (size_t) modLen; 1031 pKey[1].oa_type = SUN_CKA_PUBLIC_EXPONENT; 1032 pKey[1].oa_value = (char*) bufPub; 1033 pKey[1].oa_value_len = (size_t) pubLen; 1034 return (jlong) pKey; 1035 } else { 1036 free(bufMod); 1037 free(bufPub); 1038 throwOutOfMemoryError(env, NULL); 1039 return 0L; 1040 } 1041 } 1042 1043 //////////////////////// 1044 // NativeRSASignature 1045 //////////////////////// 1046 1047 int 1048 SignatureInit(crypto_ctx_t *context, jint mechVal, jboolean sign, 1049 uchar_t *pKey, size_t keyLength) { 1050 ucrypto_mech_t mech; 1051 int rv = 0; 1052 1053 mech = (ucrypto_mech_t) mechVal; 1054 1055 if (sign) { 1056 rv = (*ftab->ucryptoSignInit)(context, mech, pKey, keyLength, 1057 NULL, 0); 1058 } else { 1059 rv = (*ftab->ucryptoVerifyInit)(context, mech, pKey, keyLength, 1060 NULL, 0); 1061 } 1062 if (DEBUG) { 1063 printf("SignatureInit: context=%ld, mech=%d, sign=%d, keyValue=%ld, keyLength=%d\n", 1064 context, mech, sign, pKey, keyLength); 1065 printf("SignatureInit, ret => 0x%x\n", rv); 1066 } 1067 return rv; 1068 } 1069 1070 /* 1071 * Class: com_oracle_security_ucrypto_NativeRSASignature 1072 * Method: nativeInit 1073 * Signature: (IZJI[B)J 1074 */ 1075 jlong JavaCritical_com_oracle_security_ucrypto_NativeRSASignature_nativeInit 1076 (jint mech, jboolean sign, jlong jKey, jint keyLength) { 1077 crypto_ctx_t *context; 1078 int rv; 1079 uchar_t *pKey; 1080 1081 context = malloc(sizeof(crypto_ctx_t)); 1082 if (context != NULL) { 1083 pKey = (uchar_t *) jKey; 1084 rv = SignatureInit(context, mech, sign, pKey, (size_t)keyLength); 1085 if (rv) { 1086 free(context); 1087 return 0L; 1088 } 1089 } 1090 return (jlong)context; 1091 } 1092 1093 JNIEXPORT jlong JNICALL Java_com_oracle_security_ucrypto_NativeRSASignature_nativeInit 1094 (JNIEnv *env, jclass jCls, jint mech, jboolean sign, jlong jKey, jint keyLength) { 1095 crypto_ctx_t *context; 1096 int rv = 0; 1097 uchar_t *pKey; 1098 1099 context = malloc(sizeof(crypto_ctx_t)); 1100 if (context == NULL) { 1101 throwOutOfMemoryError(env, NULL); 1102 return 0L; 1103 } 1104 1105 pKey = (uchar_t *) jKey; 1106 rv = SignatureInit(context, mech, sign, pKey, (size_t)keyLength); 1107 if (rv) { 1108 free(context); 1109 throwUCExceptionUsingRV(env, rv); 1110 return 0L; 1111 } 1112 1113 return (jlong)context; 1114 } 1115 1116 /* 1117 * Class: com_oracle_security_ucrypto_NativeRSASignature 1118 * Method: nativeUpdate 1119 * Signature: (JZ[BII)I 1120 */ 1121 jint JavaCritical_com_oracle_security_ucrypto_NativeRSASignature_nativeUpdate__JZ_3BII 1122 (jlong pCtxt, jboolean sign, int notUsed, jbyte* jIn, jint jInOfs, jint jInLen) { 1123 crypto_ctx_t *context; 1124 int rv = 0; 1125 1126 context = (crypto_ctx_t *) pCtxt; 1127 if (DEBUG) { 1128 printf("Signature update: context=%ld, sign=%d, jIn=%ld, jInOfs=%d, jInLen=%d\n", 1129 context, sign, jIn, jInOfs, jInLen); 1130 } 1131 if (sign) { 1132 rv = (*ftab->ucryptoSignUpdate)(context, (uchar_t *) (jIn + jInOfs), (size_t) jInLen); 1133 } else { 1134 rv = (*ftab->ucryptoVerifyUpdate)(context, (uchar_t *) (jIn + jInOfs), (size_t) jInLen); 1135 } 1136 if (DEBUG) printf("Signature update, ret => 0x%x\n", rv); 1137 if (rv) { 1138 free(context); 1139 return -rv; // use negative value to indicate error! 1140 } 1141 1142 return 0; 1143 } 1144 1145 JNIEXPORT jint JNICALL Java_com_oracle_security_ucrypto_NativeRSASignature_nativeUpdate__JZ_3BII 1146 (JNIEnv *env, jclass jCls, jlong pCtxt, jboolean sign, jbyteArray jIn, jint inOfs, jint inLen) { 1147 int rv = 0; 1148 jbyte* bufIn; 1149 1150 bufIn = getBytes(env, jIn, inOfs, inLen); 1151 if ((*env)->ExceptionCheck(env)) { 1152 return -1; // use negative value to indicate error! 1153 } 1154 1155 if (DEBUG) printBytes("Update w/ data: ", (unsigned char*)bufIn, (size_t) inLen); 1156 1157 rv = JavaCritical_com_oracle_security_ucrypto_NativeRSASignature_nativeUpdate__JZ_3BII 1158 (pCtxt, sign, inLen, bufIn, 0, inLen); 1159 1160 free(bufIn); 1161 return rv; 1162 } 1163 1164 /* 1165 * Class: com_oracle_security_ucrypto_NativeRSASignature 1166 * Method: nativeUpdate 1167 * Signature: (JZJI)I 1168 */ 1169 jint JavaCritical_com_oracle_security_ucrypto_NativeRSASignature_nativeUpdate__JZJI 1170 (jlong pCtxt, jboolean sign, jlong inAddr, jint inLen) { 1171 1172 return JavaCritical_com_oracle_security_ucrypto_NativeRSASignature_nativeUpdate__JZ_3BII 1173 (pCtxt, sign, inLen, (jbyte*)inAddr, 0, inLen); 1174 } 1175 1176 JNIEXPORT jint JNICALL Java_com_oracle_security_ucrypto_NativeRSASignature_nativeUpdate__JZJI 1177 (JNIEnv *env, jclass jCls, jlong pCtxt, jboolean sign, jlong inAddr, jint inLen) { 1178 1179 return JavaCritical_com_oracle_security_ucrypto_NativeRSASignature_nativeUpdate__JZ_3BII 1180 (pCtxt, sign, inLen, (jbyte*)inAddr, 0, inLen); 1181 } 1182 1183 /* 1184 * Class: com_oracle_security_ucrypto_NativeRSASignature 1185 * Method: nativeFinal 1186 * Signature: (JZ[BII)I 1187 */ 1188 jint JavaCritical_com_oracle_security_ucrypto_NativeRSASignature_nativeFinal 1189 (jlong pCtxt, jboolean sign, int notUsed, jbyte* bufSig, jint sigOfs, jint jSigLen) { 1190 1191 crypto_ctx_t *context; 1192 int rv = 0; 1193 size_t sigLength = (size_t) jSigLen; 1194 1195 context = (crypto_ctx_t *) pCtxt; 1196 if (DEBUG) { 1197 printf("Signature final: context=%ld, sign=%d, bufSig=%ld, sigOfs=%d, sigLen=%d\n", 1198 context, sign, bufSig, sigOfs, jSigLen); 1199 printBytes("Before Final: SigBytes ", (unsigned char*) (bufSig + sigOfs), jSigLen); 1200 } 1201 if (sign) { 1202 rv = (*ftab->ucryptoSignFinal)(context, (uchar_t *) (bufSig + sigOfs), &sigLength); 1203 } else { 1204 rv = (*ftab->ucryptoVerifyFinal)(context, (uchar_t *) (bufSig + sigOfs), &sigLength); 1205 } 1206 1207 if (DEBUG) { 1208 printf("Signature nativeFinal, ret => 0x%x\n", rv); 1209 if (sigLength != jSigLen) { 1210 printf("SIG actual output len=%d\n", sigLength); 1211 } 1212 if (sign) { 1213 printBytes("After nativeFinal: ", (unsigned char*) (bufSig + sigOfs), jSigLen); 1214 } 1215 } 1216 1217 free(context); 1218 if (rv) { 1219 return -rv; 1220 } else return 0; 1221 } 1222 1223 JNIEXPORT jint JNICALL Java_com_oracle_security_ucrypto_NativeRSASignature_nativeFinal 1224 (JNIEnv *env, jclass jCls, jlong pCtxt, jboolean sign, jbyteArray jSig, jint jSigOfs, jint jSigLen) { 1225 int rv = 0; 1226 jbyte* bufSig = NULL; 1227 1228 if (jSigLen != 0) { 1229 bufSig = calloc(jSigLen, sizeof(char)); 1230 if (bufSig == NULL) { 1231 throwOutOfMemoryError(env, NULL); 1232 return 0; 1233 } 1234 if (!sign) { 1235 // need to copy over the to-be-verified signature bytes 1236 (*env)->GetByteArrayRegion(env, jSig, jSigOfs, jSigLen, (jbyte *)bufSig); 1237 } 1238 } 1239 1240 if (!(*env)->ExceptionCheck(env)) { 1241 // Frees context + converts rv to negative if error occurred 1242 rv = JavaCritical_com_oracle_security_ucrypto_NativeRSASignature_nativeFinal 1243 (pCtxt, sign, jSigLen, bufSig, 0, jSigLen); 1244 1245 if (rv == 0 && sign) { 1246 // need to copy the generated signature bytes to the java bytearray 1247 (*env)->SetByteArrayRegion(env, jSig, jSigOfs, jSigLen, (jbyte *)bufSig); 1248 } 1249 } else { 1250 // set rv to negative to indicate error 1251 rv = -1; 1252 } 1253 1254 free(bufSig); 1255 1256 return rv; 1257 } 1258 1259 /* 1260 * Class: com_oracle_security_ucrypto_NativeRSACipher 1261 * Method: nativeAtomic 1262 * Signature: (IZJI[BI[BII)I 1263 */ 1264 jint JavaCritical_com_oracle_security_ucrypto_NativeRSACipher_nativeAtomic 1265 (jint mech, jboolean encrypt, jlong keyValue, jint keyLength, 1266 int notUsed1, jbyte* bufIn, jint jInLen, 1267 int notUsed2, jbyte* bufOut, jint jOutOfs, jint jOutLen) { 1268 1269 uchar_t *pKey; 1270 crypto_object_attribute_t* pKey2; 1271 int rv = 0; 1272 size_t outLength = (size_t) jOutLen; 1273 1274 pKey = (uchar_t *) keyValue; 1275 if (DEBUG) { 1276 printf("Cipher nativeAtomic: mech=%d, encrypt=%d, pKey=%ld, keyLength=%d\n", 1277 mech, encrypt, pKey, keyLength); 1278 printBytes("Before nativeAtomic: in: ", (unsigned char*) bufIn, jInLen); 1279 printBytes("Before nativeAtomic: out: ", (unsigned char*) (bufOut + jOutOfs), jOutLen); 1280 } 1281 1282 if (encrypt) { 1283 rv = (*ftab->ucryptoEncrypt)((ucrypto_mech_t)mech, pKey, (size_t)keyLength, 1284 NULL, 0, (uchar_t *)bufIn, (size_t)jInLen, 1285 (uchar_t *)(bufOut + jOutOfs), &outLength); 1286 } else { 1287 rv = (*ftab->ucryptoDecrypt)((ucrypto_mech_t)mech, pKey, (size_t)keyLength, 1288 NULL, 0, (uchar_t *)bufIn, (size_t)jInLen, 1289 (uchar_t *)(bufOut + jOutOfs), &outLength); 1290 } 1291 if (DEBUG) { 1292 printf("Cipher nativeAtomic, ret => 0x%x\n", rv); 1293 if (outLength != jOutLen) { 1294 printf("CIP actual output len=%d\n", outLength); 1295 } 1296 printBytes("After nativeAtomic: ", (unsigned char*) (bufOut + jOutOfs), outLength); 1297 } 1298 1299 if (rv) { 1300 return -rv; 1301 } else return outLength; 1302 } 1303 1304 JNIEXPORT jint JNICALL Java_com_oracle_security_ucrypto_NativeRSACipher_nativeAtomic 1305 (JNIEnv *env, jclass jCls, jint mech, jboolean encrypt, 1306 jlong keyValue, jint keyLength, jbyteArray jIn, jint jInLen, 1307 jbyteArray jOut, jint jOutOfs, jint jOutLen) { 1308 int rv = 0; 1309 jbyte *bufIn = NULL; 1310 jbyte *bufOut = NULL; 1311 1312 if (jInLen != 0) { 1313 bufIn = (*env)->GetByteArrayElements(env, jIn, NULL); 1314 if (bufIn == NULL) { 1315 return 0; 1316 } 1317 } 1318 bufOut = calloc(jOutLen, sizeof(jbyte)); 1319 if (bufOut == NULL) { 1320 (*env)->ReleaseByteArrayElements(env, jIn, bufIn, 0); 1321 throwOutOfMemoryError(env, NULL); 1322 return 0; 1323 } 1324 1325 // rv: output length or error code (if negative) 1326 rv = JavaCritical_com_oracle_security_ucrypto_NativeRSACipher_nativeAtomic 1327 (mech, encrypt, keyValue, keyLength, jInLen, bufIn, jInLen, 1328 jOutLen, bufOut, 0, jOutLen); 1329 1330 if (rv > 0) { 1331 (*env)->SetByteArrayRegion(env, jOut, jOutOfs, rv, (jbyte *)bufOut); 1332 } 1333 1334 if (bufIn != NULL) { 1335 (*env)->ReleaseByteArrayElements(env, jIn, bufIn, 0); 1336 } 1337 free(bufOut); 1338 return rv; 1339 }