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