1 /* 2 * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 #include <stdlib.h> 27 #include <string.h> 28 #include <strings.h> 29 #include <jni.h> 30 #include "jni_util.h" 31 #include <libsoftcrypto.h> 32 #include "nativeCrypto.h" 33 #include "nativeFunc.h" 34 35 /* 36 * Dumps out byte array in hex with and name and length info 37 */ 38 void printBytes(char* header, unsigned char* bytes, int len) { 39 int i; 40 41 printf("%s", header); 42 printf("len=%d {", len); 43 for (i = 0; i < len; i++) { 44 if (i > 0) printf(":"); 45 printf("%02X", bytes[i]); 46 } 47 printf("}\n"); 48 } 49 50 /* 51 * Throws java.lang.OutOfMemoryError 52 */ 53 void throwOutOfMemoryError(JNIEnv *env, const char *msg) 54 { 55 jclass jExClass = (*env)->FindClass(env, "java/lang/OutOfMemoryError"); 56 if (jExClass != 0) /* Otherwise an exception has already been thrown */ { 57 (*env)->ThrowNew(env, jExClass, msg); 58 } 59 /* free the local ref */ 60 (*env)->DeleteLocalRef(env, jExClass); 61 } 62 63 JNIEXPORT jint JNICALL DEF_JNI_OnLoad(JavaVM *vm, void *reserved) { 64 return JNI_VERSION_1_4; 65 } 66 67 /* 68 * Class: com_oracle_security_ucrypto_UcryptoProvider 69 * Method: loadLibraries 70 * Signature: ()[Z 71 */ 72 JNIEXPORT jbooleanArray JNICALL Java_com_oracle_security_ucrypto_UcryptoProvider_loadLibraries 73 (JNIEnv *env, jclass jcls) { 74 jbooleanArray jResult; 75 jboolean *result; 76 jResult = (*env)->NewBooleanArray(env, 2); 77 78 if (jResult != NULL) { 79 result = loadNative(); 80 (*env)->SetBooleanArrayRegion(env, jResult, 0, 2, result); 81 free(result); 82 } 83 return jResult; 84 } 85 86 /* 87 * Class: com_oracle_security_ucrypto_UcryptoProvider 88 * Method: getMechList 89 * Signature: ()Ljava/lang/String; 90 */ 91 JNIEXPORT jstring JNICALL Java_com_oracle_security_ucrypto_UcryptoProvider_getMechList 92 (JNIEnv *env, jclass jcls) { 93 jstring jResult; 94 char* result; 95 int length; 96 97 jResult = NULL; 98 if (ftab->ucryptoVersion != NULL && ftab->ucryptoGetMechList != NULL) { 99 length = (*ftab->ucryptoGetMechList)(NULL); 100 if (DEBUG) printf("mech list length: %d\n", length); 101 result = malloc(length); 102 if (result == NULL) { 103 throwOutOfMemoryError(env, NULL); 104 return NULL; 105 } 106 length = (*ftab->ucryptoGetMechList)(result); 107 if (DEBUG) printf("mech list: %s\n", result); 108 jResult = (*env)->NewStringUTF(env, result); 109 free(result); 110 } else { 111 // version 0 on Solaris 10 112 result = "CRYPTO_AES_ECB,CRYPTO_AES_CBC,CRYPTO_AES_CFB128,"; 113 jResult = (*env)->NewStringUTF(env, result); 114 } 115 return jResult; 116 } 117 118 /* 119 * Utility function for throwing a UcryptoException when rv is not CRYPTO_OK(0) 120 */ 121 void throwUCExceptionUsingRV(JNIEnv *env, int rv) { 122 jclass jExClass; 123 jmethodID jConstructor; 124 jthrowable jException; 125 126 if ((*env)->ExceptionCheck(env)) return; 127 128 jExClass = (*env)->FindClass(env, "com/oracle/security/ucrypto/UcryptoException"); 129 /* if jExClass is NULL, an exception has already been thrown */ 130 if (jExClass != NULL) { 131 jConstructor = (*env)->GetMethodID(env, jExClass, "<init>", "(I)V"); 132 if (jConstructor != NULL) { 133 jException = (jthrowable) (*env)->NewObject(env, jExClass, jConstructor, rv); 134 if (jException != NULL) { 135 (*env)->Throw(env, jException); 136 } 137 } 138 } 139 /* free the local ref */ 140 (*env)->DeleteLocalRef(env, jExClass); 141 } 142 143 /* 144 * Utility function for duplicating a byte array from jbyteArray 145 * If anything went wrong, no memory will be allocated. 146 * NOTE: caller is responsible for freeing the allocated memory 147 * once this method returned successfully. 148 */ 149 jbyte* getBytes(JNIEnv *env, jbyteArray bytes, int offset, int len) { 150 jbyte* result = NULL; 151 152 if (!(*env)->ExceptionCheck(env)) { 153 result = (jbyte*) calloc(len, sizeof(char)); 154 if (result == NULL) { 155 throwOutOfMemoryError(env, NULL); 156 return NULL; 157 } 158 (*env)->GetByteArrayRegion(env, bytes, offset, len, result); 159 if ((*env)->ExceptionCheck(env)) { 160 // free allocated memory if error occurred 161 free(result); 162 return NULL; 163 } 164 } 165 return result; 166 } 167 168 169 int 170 CipherInit(crypto_ctx_t *context, int encrypt, ucrypto_mech_t mech, 171 unsigned char *jKey, int jKeyLen, unsigned char *jIv, int jIvLen, 172 int tagLen, unsigned char *jAad, int jAadLen) 173 174 { 175 int rv = 0; 176 void *iv; 177 size_t ivLen; 178 179 if (DEBUG) printf("CipherInit: mech %i, key %i(%i), iv %i(%i) tagLen %i, aad %i(%i)\n", 180 mech, jKey, jKeyLen, jIv, jIvLen, tagLen, jAad, jAadLen); 181 if (mech == CRYPTO_AES_CTR) { 182 ivLen = sizeof(CK_AES_CTR_PARAMS); 183 iv = (CK_AES_CTR_PARAMS*) malloc(ivLen); 184 if (iv == NULL) return -1; 185 186 ((CK_AES_CTR_PARAMS*)iv)->ulCounterBits = 32; 187 memcpy(((CK_AES_CTR_PARAMS*)iv)->cb, jIv, 16); 188 } else if (mech == CRYPTO_AES_GCM) { 189 ivLen = sizeof(CK_AES_GCM_PARAMS); 190 iv = (CK_AES_GCM_PARAMS*) malloc(ivLen); 191 if (iv == NULL) return -1; 192 193 ((CK_AES_GCM_PARAMS*)iv)->pIv = (uchar_t *)jIv; 194 ((CK_AES_GCM_PARAMS*)iv)->ulIvLen = (ulong_t)jIvLen; 195 ((CK_AES_GCM_PARAMS*)iv)->ulIvBits = 96; 196 ((CK_AES_GCM_PARAMS*)iv)->pAAD = (uchar_t *)jAad; 197 ((CK_AES_GCM_PARAMS*)iv)->ulAADLen = (ulong_t)jAadLen; 198 ((CK_AES_GCM_PARAMS*)iv)->ulTagBits = (ulong_t)tagLen; 199 } else { 200 // normal bytes 201 iv = jIv; 202 ivLen = jIvLen; 203 } 204 if (encrypt) { 205 rv = (*ftab->ucryptoEncryptInit)(context, mech, jKey, (size_t)jKeyLen, iv, ivLen); 206 if (rv != 0 && DEBUG) printf("ucryptoEncryptInit: ret = 0x%x\n", rv); 207 } else { 208 rv =(*ftab->ucryptoDecryptInit)(context, mech, jKey, (size_t)jKeyLen, iv, ivLen); 209 if (rv != 0 && DEBUG) printf("ucryptoDecryptInit: ret = 0x%x\n", rv); 210 } 211 212 if (iv != jIv) { 213 if (mech == CRYPTO_AES_CTR) { 214 free((CK_AES_CTR_PARAMS*)iv); 215 } else { 216 free((CK_AES_GCM_PARAMS*)iv); 217 } 218 } 219 220 return rv; 221 } 222 223 int 224 CipherUpdate(crypto_ctx_t *context, int encrypt, unsigned char *bufIn, int inOfs, 225 int inLen, unsigned char *bufOut, int outOfs, int *outLen) 226 { 227 int rv = 0; 228 size_t outLength; 229 230 outLength = (size_t) *outLen; 231 if (DEBUG) { 232 printf("CipherUpdate: Inofs %i, InLen %i, OutOfs %i, OutLen %i\n", inOfs, inLen, outOfs, *outLen); 233 printBytes("BufIn=", (unsigned char*)(bufIn+inOfs), inLen); 234 } 235 if (encrypt) { 236 rv = (*ftab->ucryptoEncryptUpdate)(context, (unsigned char*)(bufIn+inOfs), (size_t)inLen, (unsigned char*)(bufOut+outOfs), &outLength); 237 if (rv != 0) { 238 if (DEBUG) printf("ucryptoEncryptUpdate: ret = 0x%x\n", rv); 239 } else { 240 *outLen = (int)outLength; 241 } 242 } else { 243 rv = (*ftab->ucryptoDecryptUpdate)(context, (unsigned char*)(bufIn+inOfs), (size_t)inLen, (unsigned char*)(bufOut+outOfs), &outLength); 244 if (rv != 0) { 245 if (DEBUG) printf("ucryptoDecryptUpdate: ret = 0x%x\n", rv); 246 } else { 247 if (DEBUG) printBytes("BufOut=", (unsigned char*)(bufOut+outOfs), outLength); 248 *outLen = (int)outLength; 249 } 250 } 251 252 return rv; 253 } 254 255 int 256 CipherFinal(crypto_ctx_t *context, int encrypt, unsigned char *bufOut, int outOfs, int *outLen) 257 { 258 int rv = 0; 259 size_t outLength; 260 261 outLength = (size_t)*outLen; 262 263 if (DEBUG) printf("CipherFinal: OutOfs %i, outLen %i\n", outOfs, *outLen); 264 if (encrypt) { 265 rv = (*ftab->ucryptoEncryptFinal)(context, (unsigned char*)(bufOut+outOfs), &outLength); 266 if (rv != 0) { 267 if (DEBUG) printf("ucryptoDecryptFinal: ret = 0x%x\n", rv); 268 } else { 269 if (DEBUG) printBytes("BufOut=", (unsigned char*)(bufOut+outOfs), outLength); 270 *outLen = (int)outLength; 271 } 272 } else { 273 rv = (*ftab->ucryptoDecryptFinal)(context, (unsigned char*)(bufOut+outOfs), &outLength); 274 if (rv != 0) { 275 if (DEBUG) printf("ucryptoDecryptFinal: ret = 0x%x\n", rv); 276 } else { 277 if (DEBUG) printBytes("BufOut=", (unsigned char*)(bufOut+outOfs), outLength); 278 *outLen = (int)outLength; 279 } 280 } 281 return rv; 282 } 283 284 //////////////////////////////////////////////////////// 285 // SPECIAL ENTRIES FOR JVM JNI-BYPASSING OPTIMIZATION 286 //////////////////////////////////////////////////////// 287 jlong JavaCritical_com_oracle_security_ucrypto_NativeDigest_nativeInit(jint mech) { 288 void *pContext = NULL; 289 290 switch (mech) { 291 case com_oracle_security_ucrypto_NativeDigest_MECH_SHA1: 292 pContext = (SHA1_CTX *) malloc(sizeof(SHA1_CTX)); 293 if (pContext != NULL) { 294 (*ftab->sha1Init)((SHA1_CTX *)pContext); 295 } 296 break; 297 case com_oracle_security_ucrypto_NativeDigest_MECH_MD5: 298 pContext = (MD5_CTX *) malloc(sizeof(MD5_CTX)); 299 if (pContext != NULL) { 300 (*ftab->md5Init)((MD5_CTX *)pContext); 301 } 302 break; 303 case com_oracle_security_ucrypto_NativeDigest_MECH_SHA256: 304 pContext = (SHA2_CTX *) malloc(sizeof(SHA2_CTX)); 305 if (pContext != NULL) { 306 (*ftab->sha2Init)(SHA256, (SHA2_CTX *)pContext); 307 } 308 break; 309 case com_oracle_security_ucrypto_NativeDigest_MECH_SHA384: 310 pContext = (SHA2_CTX *) malloc(sizeof(SHA2_CTX)); 311 if (pContext != NULL) { 312 (*ftab->sha2Init)(SHA384, (SHA2_CTX *)pContext); 313 } 314 break; 315 case com_oracle_security_ucrypto_NativeDigest_MECH_SHA512: 316 pContext = (SHA2_CTX *) malloc(sizeof(SHA2_CTX)); 317 if (pContext != NULL) { 318 (*ftab->sha2Init)(SHA512, (SHA2_CTX *)pContext); 319 } 320 break; 321 default: 322 if (DEBUG) printf("ERROR: Unsupported mech %i\n", mech); 323 } 324 return (jlong) pContext; 325 } 326 327 jint JavaCritical_com_oracle_security_ucrypto_NativeDigest_nativeUpdate 328 (jint mech, jlong pContext, int notUsed, unsigned char* in, jint ofs, jint len) { 329 if (mech == com_oracle_security_ucrypto_NativeDigest_MECH_SHA1) { 330 (*ftab->sha1Update)((SHA1_CTX*)pContext, (unsigned char*)(in+ofs), len); 331 } else if (mech == com_oracle_security_ucrypto_NativeDigest_MECH_MD5) { 332 (*ftab->md5Update)((MD5_CTX*)pContext, (unsigned char*)(in+ofs), len); 333 } else { // SHA-2 family 334 (*ftab->sha2Update)((SHA2_CTX*)pContext, (unsigned char*)(in+ofs), len); 335 } 336 return 0; 337 } 338 339 // Do digest and free the context immediately 340 jint JavaCritical_com_oracle_security_ucrypto_NativeDigest_nativeDigest 341 (jint mech, jlong pContext, int notUsed, unsigned char* out, jint ofs, jint digestLen) { 342 343 if (mech == com_oracle_security_ucrypto_NativeDigest_MECH_SHA1) { 344 (*ftab->sha1Final)((unsigned char*)(out + ofs), (SHA1_CTX *)pContext); 345 free((SHA1_CTX *)pContext); 346 } else if (mech == com_oracle_security_ucrypto_NativeDigest_MECH_MD5) { 347 (*ftab->md5Final)((unsigned char*)(out + ofs), (MD5_CTX *)pContext); 348 free((MD5_CTX *)pContext); 349 } else { // SHA-2 family 350 (*ftab->sha2Final)((unsigned char*)(out + ofs), (SHA2_CTX *)pContext); 351 free((SHA2_CTX *)pContext); 352 } 353 return 0; 354 } 355 356 jlong JavaCritical_com_oracle_security_ucrypto_NativeDigest_nativeClone 357 (jint mech, jlong pContext) { 358 void *copy = NULL; 359 size_t len = 0; 360 361 if (mech == com_oracle_security_ucrypto_NativeDigest_MECH_SHA1) { 362 len = sizeof(SHA1_CTX); 363 } else if (mech == com_oracle_security_ucrypto_NativeDigest_MECH_MD5) { 364 len = sizeof(MD5_CTX); 365 } else { // SHA-2 family 366 len = sizeof(SHA2_CTX); 367 } 368 copy = (void*) malloc(len); 369 if (copy != NULL) { 370 bcopy((void *)pContext, copy, len); 371 } 372 return (jlong) copy; 373 } 374 375 void JavaCritical_com_oracle_security_ucrypto_NativeDigest_nativeFree 376 (jint mech, jlong pContext) { 377 if (mech == com_oracle_security_ucrypto_NativeDigest_MECH_SHA1) { 378 free((SHA1_CTX*) pContext); 379 } else if (mech == com_oracle_security_ucrypto_NativeDigest_MECH_MD5) { 380 free((MD5_CTX*) pContext); 381 } else { // SHA-2 family 382 free((SHA2_CTX*) pContext); 383 } 384 } 385 386 // AES 387 jlong JavaCritical_com_oracle_security_ucrypto_NativeCipher_nativeInit 388 (jint mech, jboolean encrypt, int keyLen, unsigned char* bufKey, 389 int ivLen, unsigned char* bufIv, jint tagLen, int aadLen, unsigned char* bufAad) { 390 crypto_ctx_t *context = NULL; 391 int rv; 392 393 context = malloc(sizeof(crypto_ctx_t)); 394 if (context != NULL) { 395 rv = CipherInit(context, encrypt, (ucrypto_mech_t) mech, bufKey, keyLen, 396 bufIv, ivLen, tagLen, bufAad, aadLen); 397 if (rv) { 398 free(context); 399 return 0L; 400 } 401 } 402 return (jlong)context; 403 } 404 405 /* 406 * Class: com_oracle_security_ucrypto_NativeCipher 407 * Method: nativeUpdate 408 * Signature: (JZ[BII[BI)I 409 */ 410 jint JavaCritical_com_oracle_security_ucrypto_NativeCipher_nativeUpdate 411 (jlong pContext, jboolean encrypt, int notUsed, jbyte* bufIn, jint inOfs, jint inLen, 412 int outCapacity, jbyte* bufOut, jint outOfs) { 413 crypto_ctx_t *context; 414 int rv = 0; 415 int outLen = outCapacity - outOfs; // recalculate the real out length 416 417 context = (crypto_ctx_t *) pContext; 418 rv = CipherUpdate(context, encrypt, (unsigned char*)bufIn, inOfs, inLen, (unsigned char*)bufOut, outOfs, &outLen); 419 if (rv) { 420 free(context); 421 context = 0; 422 return -rv; // use negative value to indicate error! 423 } 424 425 return outLen; 426 } 427 428 /* 429 * Class: com_oracle_security_ucrypto_NativeCipher 430 * Method: nativeFinal 431 * Signature: (JZ[BI)I 432 */ 433 jint JavaCritical_com_oracle_security_ucrypto_NativeCipher_nativeFinal 434 (jlong pContext, jboolean encrypt, int outLen, jbyte* out, jint outOfs) { 435 crypto_ctx_t *context; 436 int rv = 0; 437 unsigned char* bufOut = (unsigned char*) out; 438 439 context = (crypto_ctx_t *) pContext; 440 // Avoid null output buffer to workaround Solaris bug21481818 (fixed in S12) 441 if (bufOut == NULL) { 442 bufOut = (unsigned char*)(&outLen); 443 outLen = 0; 444 } 445 rv = CipherFinal(context, encrypt, bufOut, outOfs, &outLen); 446 free(context); 447 if (rv) { 448 return -rv; // use negative value to indicate error! 449 } 450 451 return outLen; 452 } 453 454 455 456 /* 457 * Class: com_oracle_security_ucrypto_NativeDigest 458 * Method: nativeInit 459 * Signature: (I)J 460 */ 461 JNIEXPORT jlong JNICALL Java_com_oracle_security_ucrypto_NativeDigest_nativeInit 462 (JNIEnv *env, jclass jcls, jint mech) { 463 jlong result = JavaCritical_com_oracle_security_ucrypto_NativeDigest_nativeInit(mech); 464 if (result == NULL) { 465 throwOutOfMemoryError(env, NULL); 466 } 467 return result; 468 } 469 470 /* 471 * Class: com_oracle_security_ucrypto_NativeDigest 472 * Method: nativeUpdate 473 * Signature: (IJ[BII)I 474 */ 475 JNIEXPORT jint JNICALL Java_com_oracle_security_ucrypto_NativeDigest_nativeUpdate 476 (JNIEnv *env, jclass jcls, jint mech, jlong pContext, jbyteArray jIn, jint jOfs, jint jLen) { 477 unsigned char *bufIn; 478 479 bufIn = (unsigned char *) getBytes(env, jIn, jOfs, jLen); 480 if (!(*env)->ExceptionCheck(env)) { 481 JavaCritical_com_oracle_security_ucrypto_NativeDigest_nativeUpdate(mech, pContext, jLen, bufIn, 0, jLen); 482 free(bufIn); 483 } 484 return 0; 485 } 486 487 /* 488 * Class: com_oracle_security_ucrypto_NativeDigest 489 * Method: nativeDigest 490 * Signature: (IJ[BII)I 491 */ 492 JNIEXPORT jint JNICALL Java_com_oracle_security_ucrypto_NativeDigest_nativeDigest 493 (JNIEnv *env, jclass jcls, jint mech, jlong pContext, jbyteArray jOut, jint jOutOfs, jint digestLen) { 494 unsigned char *bufOut; 495 496 bufOut = (unsigned char *) malloc(digestLen); 497 if (bufOut == NULL) { 498 throwOutOfMemoryError(env, NULL); 499 return 0; 500 } 501 502 JavaCritical_com_oracle_security_ucrypto_NativeDigest_nativeDigest(mech, pContext, digestLen, bufOut, 0, digestLen); 503 504 (*env)->SetByteArrayRegion(env, jOut, jOutOfs, digestLen, (jbyte *) bufOut); 505 free(bufOut); 506 return 0; 507 } 508 509 /* 510 * Class: com_oracle_security_ucrypto_NativeDigest 511 * Method: nativeClone 512 * Signature: (IJ)J 513 */ 514 JNIEXPORT jlong JNICALL Java_com_oracle_security_ucrypto_NativeDigest_nativeClone 515 (JNIEnv *env, jclass jcls, jint mech, jlong pContext) { 516 return JavaCritical_com_oracle_security_ucrypto_NativeDigest_nativeClone(mech, pContext); 517 } 518 519 /* 520 * Class: com_oracle_security_ucrypto_NativeDigest 521 * Method: nativeFree 522 * Signature: (IJ)V 523 */ 524 JNIEXPORT void JNICALL Java_com_oracle_security_ucrypto_NativeDigest_nativeFree 525 (JNIEnv *env, jclass jcls, jint mech, jlong pContext) { 526 JavaCritical_com_oracle_security_ucrypto_NativeDigest_nativeFree(mech, pContext); 527 } 528 529 /* 530 * Class: com_oracle_security_ucrypto_NativeCipher 531 * Method: nativeInit 532 * Signature: (IZ[B[BI[B)J 533 */ 534 JNIEXPORT jlong JNICALL Java_com_oracle_security_ucrypto_NativeCipher_nativeInit 535 (JNIEnv *env, jclass jcls, jint mech, jboolean encrypt, jbyteArray jKey, 536 jbyteArray jIv, jint tagLen, jbyteArray jAad) { 537 538 crypto_ctx_t *context; 539 unsigned char *bufKey; 540 unsigned char *bufIv; 541 unsigned char *bufAad; 542 int keyLen, ivLen, aadLen, rv = 0; 543 jlong result = 0L; 544 545 bufKey = bufIv = bufAad = NULL; 546 keyLen = ivLen = aadLen = 0; 547 context = malloc(sizeof(crypto_ctx_t)); 548 if (context == NULL) { 549 throwOutOfMemoryError(env, NULL); 550 return 0L; 551 } 552 553 // jKey MUST NOT BE NULL; 554 keyLen = (*env)->GetArrayLength(env, jKey); 555 bufKey = (unsigned char *) (*env)->GetByteArrayElements(env, jKey, NULL); 556 if (bufKey == NULL) { 557 goto cleanup; 558 } 559 560 if (jIv != NULL) { 561 ivLen = (*env)->GetArrayLength(env, jIv); 562 bufIv = (unsigned char *) (*env)->GetByteArrayElements(env, jIv, NULL); 563 if (bufIv == NULL) { 564 goto cleanup; 565 } 566 } 567 568 if (jAad != NULL) { 569 aadLen = (*env)->GetArrayLength(env, jAad); 570 bufAad = (unsigned char *) (*env)->GetByteArrayElements(env, jAad, NULL); 571 if (bufAad == NULL) { 572 goto cleanup; 573 } 574 } 575 576 rv = CipherInit(context, encrypt, mech, bufKey, keyLen, bufIv, ivLen, tagLen, bufAad, aadLen); 577 if (rv != 0) { 578 throwUCExceptionUsingRV(env, rv); 579 } else { 580 result = (jlong) context; 581 } 582 583 cleanup: 584 if ((result == 0L) && (context != NULL)) { 585 free(context); 586 } 587 if (bufKey != NULL) { 588 (*env)->ReleaseByteArrayElements(env, jKey, (jbyte *)bufKey, 0); 589 } 590 if (bufIv != NULL) { 591 (*env)->ReleaseByteArrayElements(env, jIv, (jbyte *)bufIv, 0); 592 } 593 if (bufAad != NULL) { 594 (*env)->ReleaseByteArrayElements(env, jAad, (jbyte *)bufAad, 0); 595 } 596 597 return result; 598 } 599 600 /* 601 * Class: com_oracle_security_ucrypto_NativeCipher 602 * Method: nativeUpdate 603 * Signature: (JZ[BII[BI)I 604 */ 605 JNIEXPORT jint JNICALL Java_com_oracle_security_ucrypto_NativeCipher_nativeUpdate 606 (JNIEnv *env, jclass jcls, jlong contextID, jboolean encrypt, 607 jbyteArray jIn, jint inOfs, jint inLen, jbyteArray jOut, jint outOfs) { 608 crypto_ctx_t *context; 609 unsigned char *bufIn; 610 unsigned char *bufOut; 611 int outLen, rv = 0; 612 613 context = (crypto_ctx_t *) contextID; 614 bufIn = (unsigned char *) getBytes(env, jIn, inOfs, inLen); 615 if ((*env)->ExceptionCheck(env)) { 616 return 0; 617 } 618 619 outLen = (*env)->GetArrayLength(env, jOut) - outOfs; 620 bufOut = calloc(outLen, sizeof(char)); 621 if (bufOut == NULL) { 622 free(bufIn); 623 throwOutOfMemoryError(env, NULL); 624 return 0; 625 } 626 627 rv = CipherUpdate(context, encrypt, bufIn, 0, inLen, bufOut, 0, &outLen); 628 if (rv) { 629 free(context); 630 free(bufIn); 631 free(bufOut); 632 return -rv; 633 } else { 634 (*env)->SetByteArrayRegion(env, jOut, outOfs, outLen, (jbyte *)bufOut); 635 free(bufIn); 636 free(bufOut); 637 return outLen; 638 } 639 } 640 641 /* 642 * Class: com_oracle_security_ucrypto_NativeCipher 643 * Method: nativeFinal 644 * Signature: (JZ[BI)I 645 */ 646 JNIEXPORT jint JNICALL Java_com_oracle_security_ucrypto_NativeCipher_nativeFinal 647 (JNIEnv *env, jclass jCls, jlong contextID, jboolean encrypt, 648 jbyteArray out, jint outOfs) { 649 crypto_ctx_t *context; 650 unsigned char *bufIn; 651 unsigned char *bufOut; 652 int outLen, rv = 0; 653 jint rc; 654 655 context = (crypto_ctx_t *) contextID; 656 657 // out is null when nativeFinal() is called solely for resource clean up 658 if (out == NULL) { 659 // Avoid null output buffer to workaround Solaris bug21481818 (fixed in S12) 660 bufOut = (unsigned char *)(&outLen); 661 outLen = 0; 662 } else { 663 outLen = (*env)->GetArrayLength(env, out) - outOfs; 664 bufOut = calloc(outLen, sizeof(char)); 665 if (bufOut == NULL) { 666 throwOutOfMemoryError(env, NULL); 667 return 0; 668 } 669 } 670 rv = CipherFinal(context, encrypt, bufOut, 0, &outLen); 671 if (rv) { 672 rc = -rv; 673 } else { 674 if (outLen > 0) { 675 (*env)->SetByteArrayRegion(env, out, outOfs, outLen, (jbyte *)bufOut); 676 } 677 rc = outLen; 678 } 679 free(context); 680 if (bufOut != (unsigned char *)(&outLen)) { 681 free(bufOut); 682 } 683 return rc; 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 }