nativeCrypto.c revision 12684:ca461a33aa8b
1218792Snp/* 2218792Snp * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved. 3218792Snp * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4218792Snp * 5218792Snp * This code is free software; you can redistribute it and/or modify it 6218792Snp * under the terms of the GNU General Public License version 2 only, as 7218792Snp * published by the Free Software Foundation. Oracle designates this 8218792Snp * particular file as subject to the "Classpath" exception as provided 9218792Snp * by Oracle in the LICENSE file that accompanied this code. 10218792Snp * 11218792Snp * This code is distributed in the hope that it will be useful, but WITHOUT 12218792Snp * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13218792Snp * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14218792Snp * version 2 for more details (a copy is included in the LICENSE file that 15218792Snp * accompanied this code). 16218792Snp * 17218792Snp * You should have received a copy of the GNU General Public License version 18218792Snp * 2 along with this work; if not, write to the Free Software Foundation, 19218792Snp * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20218792Snp * 21218792Snp * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22218792Snp * or visit www.oracle.com if you need additional information or have any 23218792Snp * questions. 24218792Snp */ 25218792Snp 26218792Snp#include <stdlib.h> 27218792Snp#include <string.h> 28218792Snp#include <strings.h> 29218792Snp#include <jni.h> 30218792Snp#include <libsoftcrypto.h> 31218792Snp#include "nativeCrypto.h" 32218792Snp#include "nativeFunc.h" 33218792Snp 34218792Snp/* 35218792Snp * Dumps out byte array in hex with and name and length info 36218792Snp */ 37219286Snpvoid printBytes(char* header, unsigned char* bytes, int len) { 38219286Snp int i; 39219286Snp 40218792Snp printf("%s", header); 41231093Snp printf("len=%d {", len); 42218792Snp for (i = 0; i < len; i++) { 43218792Snp if (i > 0) printf(":"); 44218792Snp printf("%02X", bytes[i]); 45218792Snp } 46218792Snp printf("}\n"); 47218792Snp} 48218792Snp 49218792Snp/* 50218792Snp * Throws java.lang.OutOfMemoryError 51218792Snp */ 52218792Snpvoid throwOutOfMemoryError(JNIEnv *env, const char *msg) 53218792Snp{ 54231093Snp jclass jExClass = (*env)->FindClass(env, "java/lang/OutOfMemoryError"); 55218792Snp if (jExClass != 0) /* Otherwise an exception has already been thrown */ { 56218792Snp (*env)->ThrowNew(env, jExClass, msg); 57218792Snp } 58218792Snp /* free the local ref */ 59218792Snp (*env)->DeleteLocalRef(env, jExClass); 60218792Snp} 61218792Snp 62219392SnpJNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) { 63219392Snp return JNI_VERSION_1_4; 64219392Snp} 65218792Snp 66218792Snp/* 67218792Snp * Class: com_oracle_security_ucrypto_UcryptoProvider 68218792Snp * Method: loadLibraries 69218792Snp * Signature: ()[Z 70218792Snp */ 71218792SnpJNIEXPORT jbooleanArray JNICALL Java_com_oracle_security_ucrypto_UcryptoProvider_loadLibraries 72218792Snp(JNIEnv *env, jclass jcls) { 73218792Snp jbooleanArray jResult; 74218792Snp jboolean *result; 75218792Snp jResult = (*env)->NewBooleanArray(env, 2); 76218792Snp 77218792Snp if (jResult != NULL) { 78218792Snp result = loadNative(); 79218792Snp (*env)->SetBooleanArrayRegion(env, jResult, 0, 2, result); 80218792Snp free(result); 81218792Snp } 82218792Snp return jResult; 83218792Snp} 84218792Snp 85218792Snp/* 86218792Snp * Class: com_oracle_security_ucrypto_UcryptoProvider 87218792Snp * Method: getMechList 88218792Snp * Signature: ()Ljava/lang/String; 89218792Snp */ 90218792SnpJNIEXPORT jstring JNICALL Java_com_oracle_security_ucrypto_UcryptoProvider_getMechList 91218792Snp(JNIEnv *env, jclass jcls) { 92218792Snp jstring jResult; 93218792Snp char* result; 94218792Snp int length; 95231093Snp 96231093Snp jResult = NULL; 97231093Snp if (ftab->ucryptoVersion != NULL && ftab->ucryptoGetMechList != NULL) { 98231093Snp length = (*ftab->ucryptoGetMechList)(NULL); 99218792Snp if (DEBUG) printf("mech list length: %d\n", length); 100231093Snp result = malloc(length); 101231093Snp if (result == NULL) { 102231093Snp throwOutOfMemoryError(env, NULL); 103231093Snp return NULL; 104218792Snp } 105218792Snp length = (*ftab->ucryptoGetMechList)(result); 106218792Snp if (DEBUG) printf("mech list: %s\n", result); 107218792Snp jResult = (*env)->NewStringUTF(env, result); 108218792Snp free(result); 109222085Snp } else { 110218792Snp // version 0 on Solaris 10 111231093Snp result = "CRYPTO_AES_ECB,CRYPTO_AES_CBC,CRYPTO_AES_CFB128,"; 112231093Snp jResult = (*env)->NewStringUTF(env, result); 113231093Snp } 114231093Snp return jResult; 115231093Snp} 116231093Snp 117218792Snp/* 118231093Snp * Utility function for throwing a UcryptoException when rv is not CRYPTO_OK(0) 119231093Snp */ 120231093Snpvoid throwUCExceptionUsingRV(JNIEnv *env, int rv) { 121231093Snp jclass jExClass; 122231093Snp jmethodID jConstructor; 123231093Snp jthrowable jException; 124231093Snp 125231093Snp if ((*env)->ExceptionCheck(env)) return; 126231093Snp 127231093Snp jExClass = (*env)->FindClass(env, "com/oracle/security/ucrypto/UcryptoException"); 128231093Snp /* if jExClass is NULL, an exception has already been thrown */ 129231093Snp if (jExClass != NULL) { 130231093Snp jConstructor = (*env)->GetMethodID(env, jExClass, "<init>", "(I)V"); 131231093Snp if (jConstructor != NULL) { 132231093Snp jException = (jthrowable) (*env)->NewObject(env, jExClass, jConstructor, rv); 133231093Snp if (jException != NULL) { 134231093Snp (*env)->Throw(env, jException); 135218792Snp } 136218792Snp } 137218792Snp } 138218792Snp /* free the local ref */ 139218792Snp (*env)->DeleteLocalRef(env, jExClass); 140231093Snp} 141231093Snp 142218792Snp/* 143218792Snp * Utility function for duplicating a byte array from jbyteArray 144218792Snp * If anything went wrong, no memory will be allocated. 145231093Snp * NOTE: caller is responsible for freeing the allocated memory 146218792Snp * once this method returned successfully. 147218792Snp */ 148218792Snpjbyte* getBytes(JNIEnv *env, jbyteArray bytes, int offset, int len) { 149218792Snp jbyte* result = NULL; 150218792Snp 151218792Snp if (!(*env)->ExceptionCheck(env)) { 152218792Snp result = (jbyte*) calloc(len, sizeof(char)); 153218792Snp if (result == NULL) { 154218792Snp throwOutOfMemoryError(env, NULL); 155218792Snp return NULL; 156218792Snp } 157218792Snp (*env)->GetByteArrayRegion(env, bytes, offset, len, result); 158220873Snp if ((*env)->ExceptionCheck(env)) { 159219292Snp // free allocated memory if error occurred 160220873Snp free(result); 161218792Snp return NULL; 162218792Snp } 163231093Snp } 164231093Snp return result; 165231093Snp} 166231093Snp 167218792Snp 168222510Snpint 169220873SnpCipherInit(crypto_ctx_t *context, int encrypt, ucrypto_mech_t mech, 170219392Snp unsigned char *jKey, int jKeyLen, unsigned char *jIv, int jIvLen, 171219392Snp int tagLen, unsigned char *jAad, int jAadLen) 172219392Snp 173219392Snp{ 174219392Snp int rv = 0; 175219392Snp void *iv; 176219392Snp size_t ivLen; 177219392Snp 178219392Snp if (DEBUG) printf("CipherInit: mech %i, key %i(%i), iv %i(%i) tagLen %i, aad %i(%i)\n", 179219392Snp mech, jKey, jKeyLen, jIv, jIvLen, tagLen, jAad, jAadLen); 180219392Snp if (mech == CRYPTO_AES_CTR) { 181219392Snp ivLen = sizeof(CK_AES_CTR_PARAMS); 182219392Snp iv = (CK_AES_CTR_PARAMS*) malloc(ivLen); 183219392Snp if (iv == NULL) return -1; 184219392Snp 185219392Snp ((CK_AES_CTR_PARAMS*)iv)->ulCounterBits = 32; 186219392Snp memcpy(((CK_AES_CTR_PARAMS*)iv)->cb, jIv, 16); 187219392Snp } else if (mech == CRYPTO_AES_GCM) { 188219392Snp ivLen = sizeof(CK_AES_GCM_PARAMS); 189219392Snp iv = (CK_AES_GCM_PARAMS*) malloc(ivLen); 190219392Snp if (iv == NULL) return -1; 191219392Snp 192219392Snp ((CK_AES_GCM_PARAMS*)iv)->pIv = (uchar_t *)jIv; 193218792Snp ((CK_AES_GCM_PARAMS*)iv)->ulIvLen = (ulong_t)jIvLen; 194218792Snp ((CK_AES_GCM_PARAMS*)iv)->ulIvBits = 96; 195218792Snp ((CK_AES_GCM_PARAMS*)iv)->pAAD = (uchar_t *)jAad; 196218792Snp ((CK_AES_GCM_PARAMS*)iv)->ulAADLen = (ulong_t)jAadLen; 197218792Snp ((CK_AES_GCM_PARAMS*)iv)->ulTagBits = (ulong_t)tagLen; 198218792Snp } else { 199218792Snp // normal bytes 200218792Snp iv = jIv; 201231093Snp ivLen = jIvLen; 202218792Snp } 203218792Snp if (encrypt) { 204218792Snp rv = (*ftab->ucryptoEncryptInit)(context, mech, jKey, (size_t)jKeyLen, iv, ivLen); 205231093Snp if (rv != 0 && DEBUG) printf("ucryptoEncryptInit: ret = 0x%x\n", rv); 206231093Snp } else { 207218792Snp rv =(*ftab->ucryptoDecryptInit)(context, mech, jKey, (size_t)jKeyLen, iv, ivLen); 208231093Snp if (rv != 0 && DEBUG) printf("ucryptoDecryptInit: ret = 0x%x\n", rv); 209231093Snp } 210231093Snp 211231093Snp if (iv != jIv) { 212231093Snp if (mech == CRYPTO_AES_CTR) { 213231093Snp free((CK_AES_CTR_PARAMS*)iv); 214218792Snp } else { 215231093Snp free((CK_AES_GCM_PARAMS*)iv); 216231093Snp } 217231093Snp } 218231093Snp 219231093Snp return rv; 220231093Snp} 221231093Snp 222231093Snpint 223231093SnpCipherUpdate(crypto_ctx_t *context, int encrypt, unsigned char *bufIn, int inOfs, 224231093Snp int inLen, unsigned char *bufOut, int outOfs, int *outLen) 225231093Snp{ 226231093Snp int rv = 0; 227231093Snp size_t outLength; 228231093Snp 229231093Snp outLength = (size_t) *outLen; 230231093Snp if (DEBUG) { 231231093Snp printf("CipherUpdate: Inofs %i, InLen %i, OutOfs %i, OutLen %i\n", inOfs, inLen, outOfs, *outLen); 232231093Snp printBytes("BufIn=", (unsigned char*)(bufIn+inOfs), inLen); 233231093Snp } 234231093Snp if (encrypt) { 235231093Snp rv = (*ftab->ucryptoEncryptUpdate)(context, (unsigned char*)(bufIn+inOfs), (size_t)inLen, (unsigned char*)(bufOut+outOfs), &outLength); 236231093Snp if (rv != 0) { 237231093Snp if (DEBUG) printf("ucryptoEncryptUpdate: ret = 0x%x\n", rv); 238231093Snp } else { 239231093Snp *outLen = (int)outLength; 240231093Snp } 241231093Snp } else { 242231093Snp rv = (*ftab->ucryptoDecryptUpdate)(context, (unsigned char*)(bufIn+inOfs), (size_t)inLen, (unsigned char*)(bufOut+outOfs), &outLength); 243231093Snp if (rv != 0) { 244231093Snp if (DEBUG) printf("ucryptoDecryptUpdate: ret = 0x%x\n", rv); 245231093Snp } else { 246231093Snp if (DEBUG) printBytes("BufOut=", (unsigned char*)(bufOut+outOfs), outLength); 247231093Snp *outLen = (int)outLength; 248231093Snp } 249231093Snp } 250231093Snp 251231093Snp return rv; 252231093Snp} 253231093Snp 254231093Snpint 255231093SnpCipherFinal(crypto_ctx_t *context, int encrypt, unsigned char *bufOut, int outOfs, int *outLen) 256231093Snp{ 257231093Snp int rv = 0; 258231093Snp size_t outLength; 259231093Snp 260231093Snp outLength = (size_t)*outLen; 261231093Snp 262231093Snp if (DEBUG) printf("CipherFinal: OutOfs %i, outLen %i\n", outOfs, *outLen); 263231093Snp if (encrypt) { 264218792Snp rv = (*ftab->ucryptoEncryptFinal)(context, (unsigned char*)(bufOut+outOfs), &outLength); 265231093Snp if (rv != 0) { 266231093Snp if (DEBUG) printf("ucryptoDecryptFinal: ret = 0x%x\n", rv); 267231093Snp } else { 268231093Snp if (DEBUG) printBytes("BufOut=", (unsigned char*)(bufOut+outOfs), outLength); 269231093Snp *outLen = (int)outLength; 270231093Snp } 271218792Snp } else { 272218792Snp rv = (*ftab->ucryptoDecryptFinal)(context, (unsigned char*)(bufOut+outOfs), &outLength); 273231093Snp if (rv != 0) { 274231093Snp if (DEBUG) printf("ucryptoDecryptFinal: ret = 0x%x\n", rv); 275222701Snp } else { 276231093Snp if (DEBUG) printBytes("BufOut=", (unsigned char*)(bufOut+outOfs), outLength); 277231093Snp *outLen = (int)outLength; 278231093Snp } 279231093Snp } 280231093Snp return rv; 281218792Snp} 282231093Snp 283231093Snp//////////////////////////////////////////////////////// 284231093Snp// SPECIAL ENTRIES FOR JVM JNI-BYPASSING OPTIMIZATION 285231093Snp//////////////////////////////////////////////////////// 286231093Snpjlong JavaCritical_com_oracle_security_ucrypto_NativeDigest_nativeInit(jint mech) { 287231093Snp void *pContext = NULL; 288231093Snp 289231093Snp switch (mech) { 290231093Snp case com_oracle_security_ucrypto_NativeDigest_MECH_SHA1: 291231093Snp pContext = (SHA1_CTX *) malloc(sizeof(SHA1_CTX)); 292231093Snp if (pContext != NULL) { 293231093Snp (*ftab->sha1Init)((SHA1_CTX *)pContext); 294231093Snp } 295231093Snp break; 296231093Snp case com_oracle_security_ucrypto_NativeDigest_MECH_MD5: 297231093Snp pContext = (MD5_CTX *) malloc(sizeof(MD5_CTX)); 298218792Snp if (pContext != NULL) { 299218792Snp (*ftab->md5Init)((MD5_CTX *)pContext); 300218792Snp } 301218792Snp break; 302218792Snp case com_oracle_security_ucrypto_NativeDigest_MECH_SHA256: 303218792Snp pContext = (SHA2_CTX *) malloc(sizeof(SHA2_CTX)); 304218792Snp if (pContext != NULL) { 305218792Snp (*ftab->sha2Init)(SHA256, (SHA2_CTX *)pContext); 306218792Snp } 307218792Snp break; 308218792Snp case com_oracle_security_ucrypto_NativeDigest_MECH_SHA384: 309218792Snp pContext = (SHA2_CTX *) malloc(sizeof(SHA2_CTX)); 310218792Snp if (pContext != NULL) { 311218792Snp (*ftab->sha2Init)(SHA384, (SHA2_CTX *)pContext); 312218792Snp } 313218792Snp break; 314218792Snp case com_oracle_security_ucrypto_NativeDigest_MECH_SHA512: 315218792Snp pContext = (SHA2_CTX *) malloc(sizeof(SHA2_CTX)); 316218792Snp if (pContext != NULL) { 317218792Snp (*ftab->sha2Init)(SHA512, (SHA2_CTX *)pContext); 318218792Snp } 319218792Snp break; 320218792Snp default: 321218792Snp if (DEBUG) printf("ERROR: Unsupported mech %i\n", mech); 322218792Snp } 323218792Snp return (jlong) pContext; 324218792Snp} 325218792Snp 326218792Snpjint JavaCritical_com_oracle_security_ucrypto_NativeDigest_nativeUpdate 327231093Snp (jint mech, jlong pContext, int notUsed, unsigned char* in, jint ofs, jint len) { 328218792Snp if (mech == com_oracle_security_ucrypto_NativeDigest_MECH_SHA1) { 329218792Snp (*ftab->sha1Update)((SHA1_CTX*)pContext, (unsigned char*)(in+ofs), len); 330218792Snp } else if (mech == com_oracle_security_ucrypto_NativeDigest_MECH_MD5) { 331218792Snp (*ftab->md5Update)((MD5_CTX*)pContext, (unsigned char*)(in+ofs), len); 332218792Snp } else { // SHA-2 family 333220873Snp (*ftab->sha2Update)((SHA2_CTX*)pContext, (unsigned char*)(in+ofs), len); 334218792Snp } 335231093Snp return 0; 336218792Snp} 337218792Snp 338218792Snp// Do digest and free the context immediately 339231093Snpjint JavaCritical_com_oracle_security_ucrypto_NativeDigest_nativeDigest 340231093Snp (jint mech, jlong pContext, int notUsed, unsigned char* out, jint ofs, jint digestLen) { 341220873Snp 342222510Snp if (mech == com_oracle_security_ucrypto_NativeDigest_MECH_SHA1) { 343222510Snp (*ftab->sha1Final)((unsigned char*)(out + ofs), (SHA1_CTX *)pContext); 344222510Snp free((SHA1_CTX *)pContext); 345231093Snp } else if (mech == com_oracle_security_ucrypto_NativeDigest_MECH_MD5) { 346218792Snp (*ftab->md5Final)((unsigned char*)(out + ofs), (MD5_CTX *)pContext); 347218792Snp free((MD5_CTX *)pContext); 348218792Snp } else { // SHA-2 family 349220873Snp (*ftab->sha2Final)((unsigned char*)(out + ofs), (SHA2_CTX *)pContext); 350218792Snp free((SHA2_CTX *)pContext); 351218792Snp } 352220873Snp return 0; 353231093Snp} 354231093Snp 355220873Snpjlong JavaCritical_com_oracle_security_ucrypto_NativeDigest_nativeClone 356231093Snp (jint mech, jlong pContext) { 357231093Snp void *copy = NULL; 358231093Snp size_t len = 0; 359231093Snp 360231093Snp if (mech == com_oracle_security_ucrypto_NativeDigest_MECH_SHA1) { 361220873Snp len = sizeof(SHA1_CTX); 362220873Snp } else if (mech == com_oracle_security_ucrypto_NativeDigest_MECH_MD5) { 363218792Snp len = sizeof(MD5_CTX); 364218792Snp } else { // SHA-2 family 365218792Snp len = sizeof(SHA2_CTX); 366218792Snp } 367218792Snp copy = (void*) malloc(len); 368218792Snp if (copy != NULL) { 369218792Snp bcopy((void *)pContext, copy, len); 370220873Snp } 371218792Snp return (jlong) copy; 372218792Snp} 373218792Snp 374218792Snpvoid JavaCritical_com_oracle_security_ucrypto_NativeDigest_nativeFree 375231093Snp (jint mech, jlong pContext) { 376231093Snp if (mech == com_oracle_security_ucrypto_NativeDigest_MECH_SHA1) { 377220873Snp free((SHA1_CTX*) pContext); 378231093Snp } else if (mech == com_oracle_security_ucrypto_NativeDigest_MECH_MD5) { 379220873Snp free((MD5_CTX*) pContext); 380220873Snp } else { // SHA-2 family 381231093Snp free((SHA2_CTX*) pContext); 382231093Snp } 383220873Snp} 384231093Snp 385231093Snp// AES 386222510Snpjlong JavaCritical_com_oracle_security_ucrypto_NativeCipher_nativeInit 387231093Snp (jint mech, jboolean encrypt, int keyLen, unsigned char* bufKey, 388231093Snp int ivLen, unsigned char* bufIv, jint tagLen, int aadLen, unsigned char* bufAad) { 389231093Snp crypto_ctx_t *context = NULL; 390231093Snp int rv; 391231093Snp 392231093Snp context = malloc(sizeof(crypto_ctx_t)); 393231093Snp if (context != NULL) { 394231093Snp rv = CipherInit(context, encrypt, (ucrypto_mech_t) mech, bufKey, keyLen, 395231093Snp bufIv, ivLen, tagLen, bufAad, aadLen); 396231093Snp if (rv) { 397231093Snp free(context); 398231093Snp return 0L; 399231093Snp } 400231093Snp } 401231093Snp return (jlong)context; 402231093Snp} 403231093Snp 404231093Snp/* 405231093Snp * Class: com_oracle_security_ucrypto_NativeCipher 406231093Snp * Method: nativeUpdate 407231093Snp * Signature: (JZ[BII[BI)I 408231093Snp */ 409231093Snpjint JavaCritical_com_oracle_security_ucrypto_NativeCipher_nativeUpdate 410231093Snp (jlong pContext, jboolean encrypt, int notUsed, jbyte* bufIn, jint inOfs, jint inLen, 411231093Snp int outCapacity, jbyte* bufOut, jint outOfs) { 412231093Snp crypto_ctx_t *context; 413231093Snp int rv = 0; 414231093Snp int outLen = outCapacity - outOfs; // recalculate the real out length 415231093Snp 416231093Snp context = (crypto_ctx_t *) pContext; 417218792Snp rv = CipherUpdate(context, encrypt, (unsigned char*)bufIn, inOfs, inLen, (unsigned char*)bufOut, outOfs, &outLen); 418218792Snp if (rv) { 419231093Snp free(context); 420218792Snp context = 0; 421218792Snp return -rv; // use negative value to indicate error! 422231093Snp } 423231093Snp 424231093Snp return outLen; 425231093Snp} 426231093Snp 427231093Snp/* 428231093Snp * Class: com_oracle_security_ucrypto_NativeCipher 429231093Snp * Method: nativeFinal 430231093Snp * Signature: (JZ[BI)I 431231093Snp */ 432231093Snpjint JavaCritical_com_oracle_security_ucrypto_NativeCipher_nativeFinal 433231093Snp (jlong pContext, jboolean encrypt, int outLen, jbyte* bufOut, jint outOfs) { 434231093Snp crypto_ctx_t *context; 435231093Snp int rv = 0; 436231093Snp 437231093Snp context = (crypto_ctx_t *) pContext; 438231093Snp // Avoid null output buffer to workaround Solaris bug21481818 (fixed in S12) 439231093Snp if (bufOut == NULL) { 440231093Snp bufOut = (unsigned char *)(&outLen); 441231093Snp outLen = 0; 442231093Snp } 443231093Snp rv = CipherFinal(context, encrypt, (unsigned char*)bufOut, outOfs, &outLen); 444231093Snp free(context); 445231093Snp if (rv) { 446231093Snp return -rv; // use negative value to indicate error! 447231093Snp } 448231093Snp 449231093Snp return outLen; 450231093Snp} 451231093Snp 452231093Snp 453231093Snp 454231093Snp/* 455231093Snp * Class: com_oracle_security_ucrypto_NativeDigest 456231093Snp * Method: nativeInit 457231093Snp * Signature: (I)J 458231093Snp */ 459231093SnpJNIEXPORT jlong JNICALL Java_com_oracle_security_ucrypto_NativeDigest_nativeInit 460231093Snp (JNIEnv *env, jclass jcls, jint mech) { 461231093Snp jlong result = JavaCritical_com_oracle_security_ucrypto_NativeDigest_nativeInit(mech); 462231093Snp if (result == NULL) { 463231093Snp throwOutOfMemoryError(env, NULL); 464231093Snp } 465231093Snp return result; 466231093Snp} 467231093Snp 468231093Snp/* 469231093Snp * Class: com_oracle_security_ucrypto_NativeDigest 470231093Snp * Method: nativeUpdate 471218792Snp * Signature: (IJ[BII)I 472231093Snp */ 473218792SnpJNIEXPORT jint JNICALL Java_com_oracle_security_ucrypto_NativeDigest_nativeUpdate 474231093Snp (JNIEnv *env, jclass jcls, jint mech, jlong pContext, jbyteArray jIn, jint jOfs, jint jLen) { 475218792Snp unsigned char *bufIn; 476218792Snp 477231093Snp bufIn = (unsigned char *) getBytes(env, jIn, jOfs, jLen); 478231093Snp if (!(*env)->ExceptionCheck(env)) { 479231093Snp JavaCritical_com_oracle_security_ucrypto_NativeDigest_nativeUpdate(mech, pContext, jLen, bufIn, 0, jLen); 480231093Snp free(bufIn); 481231093Snp } 482218792Snp return 0; 483218792Snp} 484231093Snp 485231093Snp/* 486218792Snp * Class: com_oracle_security_ucrypto_NativeDigest 487231093Snp * Method: nativeDigest 488231093Snp * Signature: (IJ[BII)I 489218792Snp */ 490231093SnpJNIEXPORT jint JNICALL Java_com_oracle_security_ucrypto_NativeDigest_nativeDigest 491231093Snp (JNIEnv *env, jclass jcls, jint mech, jlong pContext, jbyteArray jOut, jint jOutOfs, jint digestLen) { 492231093Snp unsigned char *bufOut; 493231093Snp 494231093Snp bufOut = (unsigned char *) malloc(digestLen); 495218792Snp if (bufOut == NULL) { 496231093Snp throwOutOfMemoryError(env, NULL); 497218792Snp return 0; 498231093Snp } 499231093Snp 500231093Snp JavaCritical_com_oracle_security_ucrypto_NativeDigest_nativeDigest(mech, pContext, digestLen, bufOut, 0, digestLen); 501231093Snp 502231093Snp (*env)->SetByteArrayRegion(env, jOut, jOutOfs, digestLen, (jbyte *) bufOut); 503231093Snp free(bufOut); 504231093Snp return 0; 505231093Snp} 506218792Snp 507218792Snp/* 508218792Snp * Class: com_oracle_security_ucrypto_NativeDigest 509218792Snp * Method: nativeClone 510231093Snp * Signature: (IJ)J 511231093Snp */ 512218792SnpJNIEXPORT jlong JNICALL Java_com_oracle_security_ucrypto_NativeDigest_nativeClone 513218792Snp (JNIEnv *env, jclass jcls, jint mech, jlong pContext) { 514218792Snp return JavaCritical_com_oracle_security_ucrypto_NativeDigest_nativeClone(mech, pContext); 515231093Snp} 516218792Snp 517231093Snp/* 518231093Snp * Class: com_oracle_security_ucrypto_NativeDigest 519231093Snp * Method: nativeFree 520231093Snp * Signature: (IJ)V 521231093Snp */ 522231093SnpJNIEXPORT void JNICALL Java_com_oracle_security_ucrypto_NativeDigest_nativeFree 523231093Snp (JNIEnv *env, jclass jcls, jint mech, jlong pContext) { 524231093Snp JavaCritical_com_oracle_security_ucrypto_NativeDigest_nativeFree(mech, pContext); 525231093Snp} 526231093Snp 527231093Snp/* 528231093Snp * Class: com_oracle_security_ucrypto_NativeCipher 529218792Snp * Method: nativeInit 530231093Snp * Signature: (IZ[B[BI[B)J 531231093Snp */ 532231093SnpJNIEXPORT jlong JNICALL Java_com_oracle_security_ucrypto_NativeCipher_nativeInit 533231093Snp(JNIEnv *env, jclass jcls, jint mech, jboolean encrypt, jbyteArray jKey, 534231093Snp jbyteArray jIv, jint tagLen, jbyteArray jAad) { 535231093Snp 536231093Snp crypto_ctx_t *context; 537231093Snp unsigned char *bufKey; 538231093Snp unsigned char *bufIv; 539231093Snp unsigned char *bufAad; 540231093Snp int keyLen, ivLen, aadLen, rv = 0; 541231093Snp jlong result = 0L; 542231093Snp 543231093Snp bufKey = bufIv = bufAad = NULL; 544231093Snp keyLen = ivLen = aadLen = 0; 545231093Snp context = malloc(sizeof(crypto_ctx_t)); 546231093Snp if (context == NULL) { 547231093Snp throwOutOfMemoryError(env, NULL); 548231093Snp return 0L; 549231093Snp } 550231093Snp 551231093Snp // jKey MUST NOT BE NULL; 552231093Snp keyLen = (*env)->GetArrayLength(env, jKey); 553231093Snp bufKey = (unsigned char *) (*env)->GetByteArrayElements(env, jKey, NULL); 554231093Snp if (bufKey == NULL) { 555231093Snp goto cleanup; 556231093Snp } 557231093Snp 558231093Snp if (jIv != NULL) { 559231093Snp ivLen = (*env)->GetArrayLength(env, jIv); 560231093Snp bufIv = (unsigned char *) (*env)->GetByteArrayElements(env, jIv, NULL); 561231093Snp if (bufIv == NULL) { 562231093Snp goto cleanup; 563231093Snp } 564231093Snp } 565218792Snp 566218792Snp if (jAad != NULL) { 567231093Snp aadLen = (*env)->GetArrayLength(env, jAad); 568218792Snp bufAad = (unsigned char *) (*env)->GetByteArrayElements(env, jAad, NULL); 569218792Snp if (bufAad == NULL) { 570231093Snp goto cleanup; 571231093Snp } 572231093Snp } 573231093Snp 574231093Snp rv = CipherInit(context, encrypt, mech, bufKey, keyLen, bufIv, ivLen, tagLen, bufAad, aadLen); 575231093Snp if (rv != 0) { 576231093Snp throwUCExceptionUsingRV(env, rv); 577231093Snp } else { 578231093Snp result = (jlong) context; 579231093Snp } 580231093Snp 581231093Snpcleanup: 582231093Snp if ((result == 0L) && (context != NULL)) { 583231093Snp free(context); 584231093Snp } 585231093Snp if (bufKey != NULL) { 586231093Snp (*env)->ReleaseByteArrayElements(env, jKey, (jbyte *)bufKey, 0); 587231093Snp } 588231093Snp if (bufIv != NULL) { 589231093Snp (*env)->ReleaseByteArrayElements(env, jIv, (jbyte *)bufIv, 0); 590218792Snp } 591231093Snp if (bufAad != NULL) { 592218792Snp (*env)->ReleaseByteArrayElements(env, jAad, (jbyte *)bufAad, 0); 593231093Snp } 594231093Snp 595218792Snp return result; 596218792Snp} 597231093Snp 598231093Snp/* 599218792Snp * Class: com_oracle_security_ucrypto_NativeCipher 600231093Snp * Method: nativeUpdate 601218792Snp * Signature: (JZ[BII[BI)I 602218792Snp */ 603231093SnpJNIEXPORT jint JNICALL Java_com_oracle_security_ucrypto_NativeCipher_nativeUpdate 604218792Snp (JNIEnv *env, jclass jcls, jlong contextID, jboolean encrypt, 605218792Snp jbyteArray jIn, jint inOfs, jint inLen, jbyteArray jOut, jint outOfs) { 606231093Snp crypto_ctx_t *context; 607231093Snp unsigned char *bufIn; 608231093Snp unsigned char *bufOut; 609231093Snp int outLen, rv = 0; 610231093Snp 611231093Snp context = (crypto_ctx_t *) contextID; 612231093Snp bufIn = (unsigned char *) getBytes(env, jIn, inOfs, inLen); 613231093Snp if ((*env)->ExceptionCheck(env)) { 614231093Snp return 0; 615231093Snp } 616231093Snp 617231093Snp outLen = (*env)->GetArrayLength(env, jOut) - outOfs; 618231093Snp bufOut = calloc(outLen, sizeof(char)); 619231093Snp if (bufOut == NULL) { 620231093Snp free(bufIn); 621231093Snp throwOutOfMemoryError(env, NULL); 622231093Snp return 0; 623231093Snp } 624231093Snp 625231093Snp rv = CipherUpdate(context, encrypt, bufIn, 0, inLen, bufOut, 0, &outLen); 626231093Snp if (rv) { 627231093Snp free(context); 628231093Snp free(bufIn); 629231093Snp free(bufOut); 630231093Snp return -rv; 631231093Snp } else { 632231093Snp (*env)->SetByteArrayRegion(env, jOut, outOfs, outLen, (jbyte *)bufOut); 633231093Snp free(bufIn); 634231093Snp free(bufOut); 635231093Snp return outLen; 636231093Snp } 637231093Snp} 638231093Snp 639231093Snp/* 640231093Snp * Class: com_oracle_security_ucrypto_NativeCipher 641218792Snp * Method: nativeFinal 642218792Snp * Signature: (JZ[BI)I 643231093Snp */ 644218792SnpJNIEXPORT jint JNICALL Java_com_oracle_security_ucrypto_NativeCipher_nativeFinal 645218792Snp (JNIEnv *env, jclass jCls, jlong contextID, jboolean encrypt, 646218792Snp jbyteArray out, jint outOfs) { 647218792Snp crypto_ctx_t *context; 648218792Snp unsigned char *bufIn; 649218792Snp unsigned char *bufOut; 650218792Snp int outLen, rv = 0; 651218792Snp 652231093Snp context = (crypto_ctx_t *) contextID; 653218792Snp 654218792Snp // out is null when nativeFinal() is called solely for resource clean up 655231093Snp if (out == NULL) { 656218792Snp // Avoid null output buffer to workaround Solaris bug21481818 (fixed in S12) 657218792Snp bufOut = (unsigned char *)(&outLen); 658231093Snp outLen = 0; 659231093Snp } else { 660231093Snp outLen = (*env)->GetArrayLength(env, out) - outOfs; 661231093Snp bufOut = calloc(outLen, sizeof(char)); 662218792Snp if (bufOut == NULL) { 663218792Snp throwOutOfMemoryError(env, NULL); 664231093Snp return 0; 665218792Snp } 666231093Snp } 667218792Snp rv = CipherFinal(context, encrypt, bufOut, 0, &outLen); 668218792Snp if (rv) { 669231093Snp free(context); 670231093Snp if (outLen != 0) { 671231093Snp free(bufOut); 672231093Snp } 673231093Snp return -rv; 674231093Snp } else { 675231093Snp if (bufOut != NULL && outLen != 0) { 676218792Snp (*env)->SetByteArrayRegion(env, out, outOfs, outLen, (jbyte *)bufOut); 677218792Snp free(bufOut); 678218792Snp } 679218792Snp free(context); 680231093Snp return outLen; 681231093Snp } 682231093Snp} 683231093Snp 684231093Snp 685231093Snp/* 686231093Snp * Class: com_oracle_security_ucrypto_NativeKey 687231093Snp * Method: nativeFree 688231093Snp * Signature: (JI)V 689231093Snp */ 690231093Snpvoid JavaCritical_com_oracle_security_ucrypto_NativeKey_nativeFree 691218792Snp (jlong id, jint numOfComponents) { 692231093Snp crypto_object_attribute_t* pKey; 693231093Snp int i; 694218792Snp 695218792Snp pKey = (crypto_object_attribute_t*) id; 696231093Snp for (i = 0; i < numOfComponents; i++) { 697231093Snp free(pKey[i].oa_value); 698231093Snp } 699231093Snp free(pKey); 700231093Snp} 701231093Snp 702231093SnpJNIEXPORT void JNICALL Java_com_oracle_security_ucrypto_NativeKey_nativeFree 703231093Snp (JNIEnv *env, jclass jCls, jlong id, jint numOfComponents) { 704231093Snp JavaCritical_com_oracle_security_ucrypto_NativeKey_nativeFree(id, numOfComponents); 705231093Snp} 706231093Snp 707231093Snp/* 708231093Snp * Class: com_oracle_security_ucrypto_NativeKey_RSAPrivate 709231093Snp * Method: nativeInit 710231093Snp * Signature: ([B[B)J 711231093Snp */ 712231093Snpjlong JavaCritical_com_oracle_security_ucrypto_NativeKey_00024RSAPrivate_nativeInit 713231093Snp(int modLen, jbyte* jMod, int privLen, jbyte* jPriv) { 714231093Snp 715231093Snp unsigned char *mod, *priv; 716231093Snp crypto_object_attribute_t* pKey = NULL; 717231093Snp 718231093Snp pKey = calloc(2, sizeof(crypto_object_attribute_t)); 719218792Snp if (pKey == NULL) { 720218792Snp return 0L; 721218792Snp } 722231093Snp mod = priv = NULL; 723231093Snp mod = malloc(modLen); 724231093Snp priv = malloc(privLen); 725231093Snp if (mod == NULL || priv == NULL) { 726218792Snp free(pKey); 727218792Snp free(mod); 728218792Snp free(priv); 729218792Snp return 0L; 730231093Snp } else { 731218792Snp memcpy(mod, jMod, modLen); 732218792Snp memcpy(priv, jPriv, privLen); 733231093Snp } 734231093Snp 735231093Snp // NOTE: numOfComponents should be 2 736218792Snp pKey[0].oa_type = SUN_CKA_MODULUS; 737218792Snp pKey[0].oa_value = (char*) mod; 738218792Snp pKey[0].oa_value_len = (size_t) modLen; 739218792Snp pKey[1].oa_type = SUN_CKA_PRIVATE_EXPONENT; 740218792Snp pKey[1].oa_value = (char*) priv; 741218792Snp pKey[1].oa_value_len = (size_t) privLen; 742218792Snp 743218792Snp return (jlong) pKey; 744218792Snp} 745222510Snp 746218792SnpJNIEXPORT jlong JNICALL 747218792SnpJava_com_oracle_security_ucrypto_NativeKey_00024RSAPrivate_nativeInit 748218792Snp (JNIEnv *env, jclass jCls, jbyteArray jMod, jbyteArray jPriv) { 749218792Snp 750218792Snp int modLen, privLen; 751218792Snp jbyte *bufMod, *bufPriv; 752218792Snp crypto_object_attribute_t* pKey = NULL; 753220649Snp 754231093Snp bufMod = bufPriv = NULL; 755231093Snp 756231093Snp modLen = (*env)->GetArrayLength(env, jMod); 757222510Snp bufMod = getBytes(env, jMod, 0, modLen); 758220649Snp if ((*env)->ExceptionCheck(env)) goto cleanup; 759220649Snp 760231093Snp privLen = (*env)->GetArrayLength(env, jPriv); 761231093Snp bufPriv = getBytes(env, jPriv, 0, privLen); 762220649Snp if ((*env)->ExceptionCheck(env)) goto cleanup; 763220649Snp 764231093Snp // proceed if no error; otherwise free allocated memory 765231093Snp pKey = calloc(2, sizeof(crypto_object_attribute_t)); 766231093Snp if (pKey == NULL) { 767231093Snp throwOutOfMemoryError(env, NULL); 768231093Snp goto cleanup; 769231093Snp } 770231093Snp 771231093Snp // NOTE: numOfComponents should be 2 772231093Snp pKey[0].oa_type = SUN_CKA_MODULUS; 773231093Snp pKey[0].oa_value = (char*) bufMod; 774231093Snp pKey[0].oa_value_len = (size_t) modLen; 775231093Snp pKey[1].oa_type = SUN_CKA_PRIVATE_EXPONENT; 776231093Snp pKey[1].oa_value = (char*) bufPriv; 777231093Snp pKey[1].oa_value_len = (size_t) privLen; 778231093Snp return (jlong) pKey; 779231093Snp 780218792Snpcleanup: 781218792Snp free(bufMod); 782231093Snp free(bufPriv); 783231093Snp 784231093Snp return 0L; 785231093Snp} 786231093Snp 787231093Snp/* 788218792Snp * Class: com_oracle_security_ucrypto_NativeKey_RSAPrivateCrt 789231093Snp * Method: nativeInit 790218792Snp * Signature: ([B[B[B[B[B[B[B[B)J 791231093Snp */ 792218792Snpjlong JavaCritical_com_oracle_security_ucrypto_NativeKey_00024RSAPrivateCrt_nativeInit 793231093Snp(int modLen, jbyte* jMod, int pubLen, jbyte* jPub, int privLen, jbyte* jPriv, 794231093Snp int pLen, jbyte* jP, int qLen, jbyte* jQ, int expPLen, jbyte* jExpP, 795231093Snp int expQLen, jbyte* jExpQ, int crtCoeffLen, jbyte* jCrtCoeff) { 796231093Snp 797231093Snp unsigned char *mod, *pub, *priv, *p, *q, *expP, *expQ, *crtCoeff; 798231093Snp crypto_object_attribute_t* pKey = NULL; 799218792Snp 800231093Snp pKey = calloc(8, sizeof(crypto_object_attribute_t)); 801218792Snp if (pKey == NULL) { 802231093Snp return 0L; 803231093Snp } 804231093Snp mod = pub = priv = p = q = expP = expQ = crtCoeff = NULL; 805231093Snp mod = malloc(modLen); 806218792Snp pub = malloc(pubLen); 807231093Snp priv = malloc(privLen); 808231093Snp p = malloc(pLen); 809231093Snp q = malloc(qLen); 810231093Snp expP = malloc(expPLen); 811231093Snp expQ = malloc(expQLen); 812231093Snp crtCoeff = malloc(crtCoeffLen); 813231093Snp if (mod == NULL || pub == NULL || priv == NULL || p == NULL || 814231093Snp q == NULL || expP == NULL || expQ == NULL || crtCoeff == NULL) { 815231093Snp free(pKey); 816231093Snp free(mod); 817231093Snp free(pub); 818231093Snp free(priv); 819231093Snp free(p); 820231093Snp free(q); 821231093Snp free(expP); 822231093Snp free(expQ); 823231093Snp free(crtCoeff); 824231093Snp return 0L; 825231093Snp } else { 826231093Snp memcpy(mod, jMod, modLen); 827231093Snp memcpy(pub, jPub, pubLen); 828231093Snp memcpy(priv, jPriv, privLen); 829231093Snp memcpy(p, jP, pLen); 830231093Snp memcpy(q, jQ, qLen); 831231093Snp memcpy(expP, jExpP, expPLen); 832231093Snp memcpy(expQ, jExpQ, expQLen); 833231093Snp memcpy(crtCoeff, jCrtCoeff, crtCoeffLen); 834231093Snp } 835231093Snp 836231093Snp // NOTE: numOfComponents should be 8 837231093Snp pKey[0].oa_type = SUN_CKA_MODULUS; 838231093Snp pKey[0].oa_value = (char*) mod; 839231093Snp pKey[0].oa_value_len = (size_t) modLen; 840231093Snp pKey[1].oa_type = SUN_CKA_PUBLIC_EXPONENT; 841231093Snp pKey[1].oa_value = (char*) pub; 842231093Snp pKey[1].oa_value_len = (size_t) pubLen; 843231093Snp pKey[2].oa_type = SUN_CKA_PRIVATE_EXPONENT; 844231093Snp pKey[2].oa_value = (char*) priv; 845231093Snp pKey[2].oa_value_len = (size_t) privLen; 846231093Snp pKey[3].oa_type = SUN_CKA_PRIME_1; 847231093Snp pKey[3].oa_value = (char*) p; 848231093Snp pKey[3].oa_value_len = (size_t) pLen; 849231093Snp pKey[4].oa_type = SUN_CKA_PRIME_2; 850231093Snp pKey[4].oa_value = (char*) q; 851231093Snp pKey[4].oa_value_len = (size_t) qLen; 852231093Snp pKey[5].oa_type = SUN_CKA_EXPONENT_1; 853231093Snp pKey[5].oa_value = (char*) expP; 854231093Snp pKey[5].oa_value_len = (size_t) expPLen; 855231093Snp pKey[6].oa_type = SUN_CKA_EXPONENT_2; 856231093Snp pKey[6].oa_value = (char*) expQ; 857231093Snp pKey[6].oa_value_len = (size_t) expQLen; 858231093Snp pKey[7].oa_type = SUN_CKA_COEFFICIENT; 859231093Snp pKey[7].oa_value = (char*) crtCoeff; 860231093Snp pKey[7].oa_value_len = (size_t) crtCoeffLen; 861231093Snp 862231093Snp return (jlong) pKey; 863231093Snp} 864231093Snp 865231093Snp 866231093SnpJNIEXPORT jlong JNICALL 867231093SnpJava_com_oracle_security_ucrypto_NativeKey_00024RSAPrivateCrt_nativeInit 868231093Snp (JNIEnv *env, jclass jCls, jbyteArray jMod, jbyteArray jPub, jbyteArray jPriv, 869231093Snp jbyteArray jP, jbyteArray jQ, jbyteArray jExpP, jbyteArray jExpQ, 870231093Snp jbyteArray jCrtCoeff) { 871231093Snp 872231093Snp int modLen, pubLen, privLen, pLen, qLen, expPLen, expQLen, crtCoeffLen; 873231093Snp jbyte *bufMod, *bufPub, *bufPriv, *bufP, *bufQ, *bufExpP, *bufExpQ, *bufCrtCoeff; 874231093Snp crypto_object_attribute_t* pKey = NULL; 875231093Snp 876231093Snp bufMod = bufPub = bufPriv = bufP = bufQ = bufExpP = bufExpQ = bufCrtCoeff = NULL; 877231093Snp 878231093Snp modLen = (*env)->GetArrayLength(env, jMod); 879231093Snp bufMod = getBytes(env, jMod, 0, modLen); 880231093Snp if ((*env)->ExceptionCheck(env)) goto cleanup; 881231093Snp 882231093Snp pubLen = (*env)->GetArrayLength(env, jPub); 883231093Snp bufPub = getBytes(env, jPub, 0, pubLen); 884231093Snp if ((*env)->ExceptionCheck(env)) goto cleanup; 885231093Snp 886231093Snp privLen = (*env)->GetArrayLength(env, jPriv); 887218792Snp bufPriv = getBytes(env, jPriv, 0, privLen); 888222510Snp if ((*env)->ExceptionCheck(env)) goto cleanup; 889231093Snp 890231093Snp pLen = (*env)->GetArrayLength(env, jP); 891231093Snp bufP = getBytes(env, jP, 0, pLen); 892231093Snp if ((*env)->ExceptionCheck(env)) goto cleanup; 893231093Snp 894231093Snp qLen = (*env)->GetArrayLength(env, jQ); 895231093Snp bufQ = getBytes(env, jQ, 0, qLen); 896231093Snp if ((*env)->ExceptionCheck(env)) goto cleanup; 897231093Snp 898231093Snp expPLen = (*env)->GetArrayLength(env, jExpP); 899231093Snp bufExpP = getBytes(env, jExpP, 0, expPLen); 900231093Snp if ((*env)->ExceptionCheck(env)) goto cleanup; 901231093Snp 902218792Snp expQLen = (*env)->GetArrayLength(env, jExpQ); 903218792Snp bufExpQ = getBytes(env, jExpQ, 0, expQLen); 904231093Snp if ((*env)->ExceptionCheck(env)) goto cleanup; 905231093Snp 906231093Snp crtCoeffLen = (*env)->GetArrayLength(env, jCrtCoeff); 907231093Snp bufCrtCoeff = getBytes(env, jCrtCoeff, 0, crtCoeffLen); 908231093Snp if ((*env)->ExceptionCheck(env)) goto cleanup; 909231093Snp 910231093Snp // proceed if no error; otherwise free allocated memory 911231093Snp pKey = calloc(8, sizeof(crypto_object_attribute_t)); 912231093Snp if (pKey == NULL) { 913231093Snp throwOutOfMemoryError(env, NULL); 914231093Snp goto cleanup; 915231093Snp } 916231093Snp 917231093Snp // NOTE: numOfComponents should be 8 918231093Snp pKey[0].oa_type = SUN_CKA_MODULUS; 919231093Snp pKey[0].oa_value = (char*) bufMod; 920231093Snp pKey[0].oa_value_len = (size_t) modLen; 921231093Snp pKey[1].oa_type = SUN_CKA_PUBLIC_EXPONENT; 922231093Snp pKey[1].oa_value = (char*) bufPub; 923231093Snp pKey[1].oa_value_len = (size_t) pubLen; 924231093Snp pKey[2].oa_type = SUN_CKA_PRIVATE_EXPONENT; 925231093Snp pKey[2].oa_value = (char*) bufPriv; 926231093Snp pKey[2].oa_value_len = (size_t) privLen; 927231093Snp pKey[3].oa_type = SUN_CKA_PRIME_1; 928231093Snp pKey[3].oa_value = (char*) bufP; 929231093Snp pKey[3].oa_value_len = (size_t) pLen; 930231093Snp pKey[4].oa_type = SUN_CKA_PRIME_2; 931231093Snp pKey[4].oa_value = (char*) bufQ; 932218792Snp pKey[4].oa_value_len = (size_t) qLen; 933218792Snp pKey[5].oa_type = SUN_CKA_EXPONENT_1; 934231093Snp pKey[5].oa_value = (char*) bufExpP; 935221477Snp pKey[5].oa_value_len = (size_t) expPLen; 936221477Snp pKey[6].oa_type = SUN_CKA_EXPONENT_2; 937221477Snp pKey[6].oa_value = (char*) bufExpQ; 938221477Snp pKey[6].oa_value_len = (size_t) expQLen; 939221477Snp pKey[7].oa_type = SUN_CKA_COEFFICIENT; 940221477Snp pKey[7].oa_value = (char*) bufCrtCoeff; 941231093Snp pKey[7].oa_value_len = (size_t) crtCoeffLen; 942231093Snp return (jlong) pKey; 943231093Snp 944218792Snpcleanup: 945218792Snp free(bufMod); 946231093Snp free(bufPub); 947231093Snp free(bufPriv); 948218792Snp free(bufP); 949231093Snp free(bufQ); 950231093Snp free(bufExpP); 951231093Snp free(bufExpQ); 952231093Snp free(bufCrtCoeff); 953231093Snp 954231093Snp return 0L; 955231093Snp} 956231093Snp 957219290Snp/* 958231093Snp * Class: com_oracle_security_ucrypto_NativeKey_RSAPublic 959231093Snp * Method: nativeInit 960231093Snp * Signature: ([B[B)J 961218792Snp */ 962231093Snp 963231093Snpjlong JavaCritical_com_oracle_security_ucrypto_NativeKey_00024RSAPublic_nativeInit 964218792Snp(int modLen, jbyte* jMod, int pubLen, jbyte* jPub) { 965231093Snp unsigned char *mod, *pub; 966231093Snp crypto_object_attribute_t* pKey = NULL; 967231093Snp 968231093Snp pKey = calloc(2, sizeof(crypto_object_attribute_t)); 969231093Snp if (pKey == NULL) { 970231093Snp return 0L; 971218792Snp } 972231093Snp mod = pub = NULL; 973231093Snp mod = malloc(modLen); 974231093Snp pub = malloc(pubLen); 975231093Snp if (mod == NULL || pub == NULL) { 976231093Snp free(pKey); 977231093Snp free(mod); 978231093Snp free(pub); 979231093Snp return 0L; 980231093Snp } else { 981231093Snp memcpy(mod, jMod, modLen); 982231093Snp memcpy(pub, jPub, pubLen); 983218792Snp } 984231093Snp 985231093Snp if (DEBUG) { 986231093Snp printf("RSAPublicKey Init: keyValue=%ld, keyLen=2\n", pKey); 987231093Snp printBytes("RSA PublicKey mod: ", (unsigned char*) mod, modLen); 988231093Snp printBytes("RSA PublicKey pubExp: ", (unsigned char*) pub, pubLen); 989218792Snp } 990231093Snp 991231093Snp pKey[0].oa_type = SUN_CKA_MODULUS; 992231093Snp pKey[0].oa_value = (char*) mod; 993219290Snp pKey[0].oa_value_len = (size_t) modLen; 994231093Snp pKey[1].oa_type = SUN_CKA_PUBLIC_EXPONENT; 995231093Snp pKey[1].oa_value = (char*) pub; 996219290Snp pKey[1].oa_value_len = (size_t) pubLen; 997231093Snp 998219290Snp return (jlong) pKey; 999219290Snp} 1000219290Snp 1001218792SnpJNIEXPORT jlong JNICALL 1002231093SnpJava_com_oracle_security_ucrypto_NativeKey_00024RSAPublic_nativeInit 1003231093Snp(JNIEnv *env, jclass jCls, jbyteArray jMod, jbyteArray jPub) { 1004231093Snp int modLen, pubLen; 1005231093Snp jbyte *bufMod, *bufPub; 1006219290Snp crypto_object_attribute_t* pKey = NULL; 1007231093Snp 1008231093Snp bufMod = bufPub = NULL; 1009231093Snp 1010219290Snp modLen = (*env)->GetArrayLength(env, jMod); 1011231093Snp bufMod = getBytes(env, jMod, 0, modLen); 1012218792Snp if ((*env)->ExceptionCheck(env)) { 1013218792Snp return 0L; 1014231093Snp } 1015231093Snp 1016231093Snp pubLen = (*env)->GetArrayLength(env, jPub); 1017231093Snp bufPub = getBytes(env, jPub, 0, pubLen); 1018218792Snp if ((*env)->ExceptionCheck(env)) { 1019218792Snp free(bufMod); 1020231093Snp return 0L; 1021231093Snp } 1022231093Snp 1023218792Snp // proceed if no error; otherwise free allocated memory 1024231093Snp pKey = calloc(2, sizeof(crypto_object_attribute_t)); 1025219290Snp if (pKey != NULL) { 1026231093Snp // NOTE: numOfComponents should be 2 1027231093Snp pKey[0].oa_type = SUN_CKA_MODULUS; 1028218792Snp pKey[0].oa_value = (char*) bufMod; 1029231093Snp pKey[0].oa_value_len = (size_t) modLen; 1030231093Snp pKey[1].oa_type = SUN_CKA_PUBLIC_EXPONENT; 1031231093Snp pKey[1].oa_value = (char*) bufPub; 1032231093Snp pKey[1].oa_value_len = (size_t) pubLen; 1033231093Snp return (jlong) pKey; 1034231093Snp } else { 1035231093Snp free(bufMod); 1036231093Snp free(bufPub); 1037231093Snp throwOutOfMemoryError(env, NULL); 1038219290Snp return 0L; 1039231093Snp } 1040231093Snp} 1041219290Snp 1042231093Snp//////////////////////// 1043231093Snp// NativeRSASignature 1044231093Snp//////////////////////// 1045219290Snp 1046231093Snpint 1047231093SnpSignatureInit(crypto_ctx_t *context, jint mechVal, jboolean sign, 1048231093Snp uchar_t *pKey, size_t keyLength) { 1049219290Snp ucrypto_mech_t mech; 1050231093Snp int rv = 0; 1051231093Snp 1052231093Snp mech = (ucrypto_mech_t) mechVal; 1053231093Snp 1054231093Snp if (sign) { 1055231093Snp rv = (*ftab->ucryptoSignInit)(context, mech, pKey, keyLength, 1056231093Snp NULL, 0); 1057231093Snp } else { 1058231093Snp rv = (*ftab->ucryptoVerifyInit)(context, mech, pKey, keyLength, 1059231093Snp NULL, 0); 1060219290Snp } 1061231093Snp if (DEBUG) { 1062231093Snp printf("SignatureInit: context=%ld, mech=%d, sign=%d, keyValue=%ld, keyLength=%d\n", 1063231093Snp context, mech, sign, pKey, keyLength); 1064231093Snp printf("SignatureInit, ret => 0x%x\n", rv); 1065231093Snp } 1066219290Snp return rv; 1067218792Snp} 1068231093Snp 1069231093Snp/* 1070231093Snp * Class: com_oracle_security_ucrypto_NativeRSASignature 1071231093Snp * Method: nativeInit 1072231093Snp * Signature: (IZJI[B)J 1073218792Snp */ 1074231093Snpjlong JavaCritical_com_oracle_security_ucrypto_NativeRSASignature_nativeInit 1075218792Snp(jint mech, jboolean sign, jlong jKey, jint keyLength) { 1076231093Snp crypto_ctx_t *context; 1077231093Snp int rv; 1078218792Snp uchar_t *pKey; 1079231093Snp 1080231093Snp context = malloc(sizeof(crypto_ctx_t)); 1081231093Snp if (context != NULL) { 1082231093Snp pKey = (uchar_t *) jKey; 1083231093Snp rv = SignatureInit(context, mech, sign, pKey, (size_t)keyLength); 1084222510Snp if (rv) { 1085231093Snp free(context); 1086231093Snp return 0L; 1087231093Snp } 1088231093Snp } 1089231093Snp return (jlong)context; 1090231093Snp} 1091231093Snp 1092231093SnpJNIEXPORT jlong JNICALL Java_com_oracle_security_ucrypto_NativeRSASignature_nativeInit 1093231093Snp(JNIEnv *env, jclass jCls, jint mech, jboolean sign, jlong jKey, jint keyLength) { 1094231093Snp crypto_ctx_t *context; 1095231093Snp int rv = 0; 1096231093Snp uchar_t *pKey; 1097231093Snp 1098231093Snp context = malloc(sizeof(crypto_ctx_t)); 1099231093Snp if (context == NULL) { 1100231093Snp throwOutOfMemoryError(env, NULL); 1101231093Snp return 0L; 1102231093Snp } 1103231093Snp 1104231093Snp pKey = (uchar_t *) jKey; 1105231093Snp rv = SignatureInit(context, mech, sign, pKey, (size_t)keyLength); 1106231093Snp if (rv) { 1107231093Snp free(context); 1108231093Snp throwUCExceptionUsingRV(env, rv); 1109218792Snp return 0L; 1110218792Snp } 1111231093Snp 1112231093Snp return (jlong)context; 1113231093Snp} 1114231093Snp 1115231093Snp/* 1116231093Snp * Class: com_oracle_security_ucrypto_NativeRSASignature 1117218792Snp * Method: nativeUpdate 1118231093Snp * Signature: (JZ[BII)I 1119231093Snp */ 1120231093Snpjint JavaCritical_com_oracle_security_ucrypto_NativeRSASignature_nativeUpdate__JZ_3BII 1121231093Snp(jlong pCtxt, jboolean sign, int notUsed, jbyte* jIn, jint jInOfs, jint jInLen) { 1122231093Snp crypto_ctx_t *context; 1123231093Snp int rv = 0; 1124231093Snp 1125231093Snp context = (crypto_ctx_t *) pCtxt; 1126231093Snp if (DEBUG) { 1127231093Snp printf("Signature update: context=%ld, sign=%d, jIn=%ld, jInOfs=%d, jInLen=%d\n", 1128231093Snp context, sign, jIn, jInOfs, jInLen); 1129231093Snp } 1130231093Snp if (sign) { 1131231093Snp rv = (*ftab->ucryptoSignUpdate)(context, (uchar_t *) (jIn + jInOfs), (size_t) jInLen); 1132231093Snp } else { 1133231093Snp rv = (*ftab->ucryptoVerifyUpdate)(context, (uchar_t *) (jIn + jInOfs), (size_t) jInLen); 1134231093Snp } 1135231093Snp if (DEBUG) printf("Signature update, ret => 0x%x\n", rv); 1136231093Snp if (rv) { 1137231093Snp free(context); 1138231093Snp return -rv; // use negative value to indicate error! 1139231093Snp } 1140231093Snp 1141231093Snp return 0; 1142231093Snp} 1143218792Snp 1144231093SnpJNIEXPORT jint JNICALL Java_com_oracle_security_ucrypto_NativeRSASignature_nativeUpdate__JZ_3BII 1145218792Snp(JNIEnv *env, jclass jCls, jlong pCtxt, jboolean sign, jbyteArray jIn, jint inOfs, jint inLen) { 1146231093Snp int rv = 0; 1147231093Snp jbyte* bufIn; 1148231093Snp 1149231093Snp bufIn = getBytes(env, jIn, inOfs, inLen); 1150231093Snp if ((*env)->ExceptionCheck(env)) { 1151231093Snp return -1; // use negative value to indicate error! 1152218792Snp } 1153231093Snp 1154231093Snp if (DEBUG) printBytes("Update w/ data: ", (unsigned char*)bufIn, (size_t) inLen); 1155231093Snp 1156218792Snp rv = JavaCritical_com_oracle_security_ucrypto_NativeRSASignature_nativeUpdate__JZ_3BII 1157231093Snp (pCtxt, sign, inLen, bufIn, 0, inLen); 1158231093Snp 1159231093Snp free(bufIn); 1160231093Snp return rv; 1161231093Snp} 1162231093Snp 1163231093Snp/* 1164231093Snp * Class: com_oracle_security_ucrypto_NativeRSASignature 1165231093Snp * Method: nativeUpdate 1166231093Snp * Signature: (JZJI)I 1167231093Snp */ 1168231093Snpjint JavaCritical_com_oracle_security_ucrypto_NativeRSASignature_nativeUpdate__JZJI 1169231093Snp(jlong pCtxt, jboolean sign, jlong inAddr, jint inLen) { 1170231093Snp 1171231093Snp return JavaCritical_com_oracle_security_ucrypto_NativeRSASignature_nativeUpdate__JZ_3BII 1172231093Snp (pCtxt, sign, inLen, (jbyte*)inAddr, 0, inLen); 1173231093Snp} 1174231093Snp 1175231093SnpJNIEXPORT jint JNICALL Java_com_oracle_security_ucrypto_NativeRSASignature_nativeUpdate__JZJI 1176231093Snp(JNIEnv *env, jclass jCls, jlong pCtxt, jboolean sign, jlong inAddr, jint inLen) { 1177231093Snp 1178231093Snp return JavaCritical_com_oracle_security_ucrypto_NativeRSASignature_nativeUpdate__JZ_3BII 1179231093Snp (pCtxt, sign, inLen, (jbyte*)inAddr, 0, inLen); 1180231093Snp} 1181231093Snp 1182231093Snp/* 1183231093Snp * Class: com_oracle_security_ucrypto_NativeRSASignature 1184231093Snp * Method: nativeFinal 1185231093Snp * Signature: (JZ[BII)I 1186231093Snp */ 1187231093Snpjint JavaCritical_com_oracle_security_ucrypto_NativeRSASignature_nativeFinal 1188231093Snp(jlong pCtxt, jboolean sign, int notUsed, jbyte* bufSig, jint sigOfs, jint jSigLen) { 1189231093Snp 1190231093Snp crypto_ctx_t *context; 1191231093Snp int rv = 0; 1192231093Snp size_t sigLength = (size_t) jSigLen; 1193231093Snp 1194231093Snp context = (crypto_ctx_t *) pCtxt; 1195220873Snp if (DEBUG) { 1196220873Snp printf("Signature final: context=%ld, sign=%d, bufSig=%ld, sigOfs=%d, sigLen=%d\n", 1197218792Snp context, sign, bufSig, sigOfs, jSigLen); 1198218792Snp printBytes("Before Final: SigBytes ", (unsigned char*) (bufSig + sigOfs), jSigLen); 1199218792Snp } 1200218792Snp if (sign) { 1201218792Snp rv = (*ftab->ucryptoSignFinal)(context, (uchar_t *) (bufSig + sigOfs), &sigLength); 1202218792Snp } else { 1203218792Snp rv = (*ftab->ucryptoVerifyFinal)(context, (uchar_t *) (bufSig + sigOfs), &sigLength); 1204218792Snp } 1205218792Snp 1206218792Snp if (DEBUG) { 1207218792Snp printf("Signature nativeFinal, ret => 0x%x\n", rv); 1208218792Snp if (sigLength != jSigLen) { 1209218792Snp printf("SIG actual output len=%d\n", sigLength); 1210218792Snp } 1211218792Snp if (sign) { 1212218792Snp printBytes("After nativeFinal: ", (unsigned char*) (bufSig + sigOfs), jSigLen); 1213218792Snp } 1214218792Snp } 1215218792Snp 1216218792Snp free(context); 1217218792Snp if (rv) { 1218218792Snp return -rv; 1219218792Snp } else return 0; 1220218792Snp} 1221218792Snp 1222218792SnpJNIEXPORT jint JNICALL Java_com_oracle_security_ucrypto_NativeRSASignature_nativeFinal 1223218792Snp(JNIEnv *env, jclass jCls, jlong pCtxt, jboolean sign, jbyteArray jSig, jint jSigOfs, jint jSigLen) { 1224218792Snp int rv = 0; 1225218792Snp jbyte* bufSig = NULL; 1226218792Snp 1227218792Snp if (jSigLen != 0) { 1228220873Snp bufSig = calloc(jSigLen, sizeof(char)); 1229218792Snp if (bufSig == NULL) { 1230219292Snp throwOutOfMemoryError(env, NULL); 1231218792Snp return 0; 1232218792Snp } 1233218792Snp if (!sign) { 1234218792Snp // need to copy over the to-be-verified signature bytes 1235218792Snp (*env)->GetByteArrayRegion(env, jSig, jSigOfs, jSigLen, (jbyte *)bufSig); 1236231093Snp } 1237231093Snp } 1238218792Snp 1239219292Snp if (!(*env)->ExceptionCheck(env)) { 1240220873Snp // Frees context + converts rv to negative if error occurred 1241219292Snp rv = JavaCritical_com_oracle_security_ucrypto_NativeRSASignature_nativeFinal 1242218792Snp (pCtxt, sign, jSigLen, bufSig, 0, jSigLen); 1243218792Snp 1244218792Snp if (rv == 0 && sign) { 1245231093Snp // need to copy the generated signature bytes to the java bytearray 1246231093Snp (*env)->SetByteArrayRegion(env, jSig, jSigOfs, jSigLen, (jbyte *)bufSig); 1247231093Snp } 1248231093Snp } else { 1249231093Snp // set rv to negative to indicate error 1250231093Snp rv = -1; 1251231093Snp } 1252231093Snp 1253231093Snp free(bufSig); 1254218792Snp 1255231093Snp return rv; 1256231093Snp} 1257231093Snp 1258231093Snp/* 1259231093Snp * Class: com_oracle_security_ucrypto_NativeRSACipher 1260231093Snp * Method: nativeAtomic 1261231093Snp * Signature: (IZJI[BI[BII)I 1262231093Snp */ 1263231093Snpjint JavaCritical_com_oracle_security_ucrypto_NativeRSACipher_nativeAtomic 1264231093Snp (jint mech, jboolean encrypt, jlong keyValue, jint keyLength, 1265218792Snp int notUsed1, jbyte* bufIn, jint jInLen, 1266218792Snp int notUsed2, jbyte* bufOut, jint jOutOfs, jint jOutLen) { 1267218792Snp 1268218792Snp uchar_t *pKey; 1269218792Snp crypto_object_attribute_t* pKey2; 1270218792Snp int rv = 0; 1271218792Snp size_t outLength = (size_t) jOutLen; 1272218792Snp 1273218792Snp pKey = (uchar_t *) keyValue; 1274218792Snp if (DEBUG) { 1275218792Snp printf("Cipher nativeAtomic: mech=%d, encrypt=%d, pKey=%ld, keyLength=%d\n", 1276218792Snp mech, encrypt, pKey, keyLength); 1277218792Snp printBytes("Before nativeAtomic: in: ", (unsigned char*) bufIn, jInLen); 1278218792Snp printBytes("Before nativeAtomic: out: ", (unsigned char*) (bufOut + jOutOfs), jOutLen); 1279218792Snp } 1280218792Snp 1281218792Snp if (encrypt) { 1282218792Snp rv = (*ftab->ucryptoEncrypt)((ucrypto_mech_t)mech, pKey, (size_t)keyLength, 1283218792Snp NULL, 0, (uchar_t *)bufIn, (size_t)jInLen, 1284218792Snp (uchar_t *)(bufOut + jOutOfs), &outLength); 1285218792Snp } else { 1286218792Snp rv = (*ftab->ucryptoDecrypt)((ucrypto_mech_t)mech, pKey, (size_t)keyLength, 1287218792Snp NULL, 0, (uchar_t *)bufIn, (size_t)jInLen, 1288218792Snp (uchar_t *)(bufOut + jOutOfs), &outLength); 1289218792Snp } 1290218792Snp if (DEBUG) { 1291218792Snp printf("Cipher nativeAtomic, ret => 0x%x\n", rv); 1292218792Snp if (outLength != jOutLen) { 1293218792Snp printf("CIP actual output len=%d\n", outLength); 1294218792Snp } 1295218792Snp printBytes("After nativeAtomic: ", (unsigned char*) (bufOut + jOutOfs), outLength); 1296218792Snp } 1297218792Snp 1298218792Snp if (rv) { 1299218792Snp return -rv; 1300218792Snp } else return outLength; 1301218792Snp} 1302218792Snp 1303218792SnpJNIEXPORT jint JNICALL Java_com_oracle_security_ucrypto_NativeRSACipher_nativeAtomic 1304218792Snp (JNIEnv *env, jclass jCls, jint mech, jboolean encrypt, 1305218792Snp jlong keyValue, jint keyLength, jbyteArray jIn, jint jInLen, 1306218792Snp jbyteArray jOut, jint jOutOfs, jint jOutLen) { 1307218792Snp int rv = 0; 1308218792Snp jbyte *bufIn = NULL; 1309218792Snp jbyte *bufOut = NULL; 1310218792Snp 1311218792Snp if (jInLen != 0) { 1312218792Snp bufIn = (*env)->GetByteArrayElements(env, jIn, NULL); 1313218792Snp if (bufIn == NULL) { 1314218792Snp return 0; 1315218792Snp } 1316218792Snp } 1317218792Snp bufOut = calloc(jOutLen, sizeof(jbyte)); 1318218792Snp if (bufOut == NULL) { 1319220873Snp (*env)->ReleaseByteArrayElements(env, jIn, bufIn, 0); 1320218792Snp throwOutOfMemoryError(env, NULL); 1321218792Snp return 0; 1322218792Snp } 1323218792Snp 1324218792Snp // rv: output length or error code (if negative) 1325218792Snp rv = JavaCritical_com_oracle_security_ucrypto_NativeRSACipher_nativeAtomic 1326218792Snp (mech, encrypt, keyValue, keyLength, jInLen, bufIn, jInLen, 1327218792Snp jOutLen, bufOut, 0, jOutLen); 1328218792Snp 1329218792Snp if (rv > 0) { 1330218792Snp (*env)->SetByteArrayRegion(env, jOut, jOutOfs, rv, (jbyte *)bufOut); 1331218792Snp } 1332218792Snp 1333218792Snp if (bufIn != NULL) { 1334218792Snp (*env)->ReleaseByteArrayElements(env, jIn, bufIn, 0); 1335218792Snp } 1336218792Snp free(bufOut); 1337218792Snp return rv; 1338218792Snp} 1339218792Snp