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