nativeCryptoMD.c revision 14434:9db62c197dcd
1/*
2 * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.  Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26#include <stdlib.h>
27#include <string.h>
28#include <strings.h>
29#include <jni.h>
30#include "jni_util.h"
31#include <libsoftcrypto.h>
32#include "nativeCrypto.h"
33#include "nativeFunc.h"
34
35
36extern void throwOutOfMemoryError(JNIEnv *env, const char *msg);
37extern jbyte* getBytes(JNIEnv *env, jbyteArray bytes, int offset, int len);
38
39///////////////////////////////////////////////////////
40// SPECIAL ENTRIES FOR JVM JNI-BYPASSING OPTIMIZATION
41////////////////////////////////////////////////////////
42jlong JavaCritical_com_oracle_security_ucrypto_NativeDigestMD_nativeInit(jint mech) {
43  void *pContext = NULL;
44
45  switch (mech) {
46  case com_oracle_security_ucrypto_NativeDigestMD_MECH_SHA1:
47    pContext = malloc(sizeof(SHA1_CTX));
48    if (pContext != NULL) {
49      (*ftab->sha1Init)((SHA1_CTX *)pContext);
50    }
51    break;
52  case com_oracle_security_ucrypto_NativeDigestMD_MECH_MD5:
53    pContext = malloc(sizeof(MD5_CTX));
54    if (pContext != NULL) {
55      (*ftab->md5Init)((MD5_CTX *)pContext);
56    }
57    break;
58  case com_oracle_security_ucrypto_NativeDigestMD_MECH_SHA256:
59    pContext = malloc(sizeof(SHA2_CTX));
60    if (pContext != NULL) {
61      (*ftab->sha2Init)(SHA256, (SHA2_CTX *)pContext);
62    }
63    break;
64  case com_oracle_security_ucrypto_NativeDigestMD_MECH_SHA384:
65    pContext = malloc(sizeof(SHA2_CTX));
66    if (pContext != NULL) {
67      (*ftab->sha2Init)(SHA384, (SHA2_CTX *)pContext);
68    }
69    break;
70  case com_oracle_security_ucrypto_NativeDigestMD_MECH_SHA512:
71    pContext = malloc(sizeof(SHA2_CTX));
72    if (pContext != NULL) {
73      (*ftab->sha2Init)(SHA512, (SHA2_CTX *)pContext);
74    }
75    break;
76  default:
77    if (DEBUG) printf("ERROR: Unsupported mech %i\n", mech);
78  }
79  return (jlong) pContext;
80}
81
82jint JavaCritical_com_oracle_security_ucrypto_NativeDigestMD_nativeUpdate
83  (jint mech, jlong pContext, int notUsed, unsigned char* in, jint ofs, jint len) {
84  if (mech == com_oracle_security_ucrypto_NativeDigestMD_MECH_SHA1) {
85    (*ftab->sha1Update)((SHA1_CTX*)pContext, (unsigned char*)(in+ofs), len);
86  } else if (mech == com_oracle_security_ucrypto_NativeDigestMD_MECH_MD5) {
87    (*ftab->md5Update)((MD5_CTX*)pContext, (unsigned char*)(in+ofs), len);
88  } else { // SHA-2 family
89    (*ftab->sha2Update)((SHA2_CTX*)pContext, (unsigned char*)(in+ofs), len);
90  }
91  return 0;
92}
93
94// Do digest and free the context immediately
95jint JavaCritical_com_oracle_security_ucrypto_NativeDigestMD_nativeDigest
96  (jint mech, jlong pContext, int notUsed, unsigned char* out, jint ofs, jint digestLen) {
97
98  if (mech == com_oracle_security_ucrypto_NativeDigestMD_MECH_SHA1) {
99    (*ftab->sha1Final)((unsigned char*)(out + ofs), (SHA1_CTX *)pContext);
100    free((SHA1_CTX *)pContext);
101  } else if (mech == com_oracle_security_ucrypto_NativeDigestMD_MECH_MD5) {
102    (*ftab->md5Final)((unsigned char*)(out + ofs), (MD5_CTX *)pContext);
103    free((MD5_CTX *)pContext);
104  } else { // SHA-2 family
105    (*ftab->sha2Final)((unsigned char*)(out + ofs), (SHA2_CTX *)pContext);
106    free((SHA2_CTX *)pContext);
107  }
108  return 0;
109}
110
111jlong JavaCritical_com_oracle_security_ucrypto_NativeDigestMD_nativeClone
112  (jint mech, jlong pContext) {
113  void *copy = NULL;
114  size_t len = 0;
115
116  if (mech == com_oracle_security_ucrypto_NativeDigestMD_MECH_SHA1) {
117    len = sizeof(SHA1_CTX);
118  } else if (mech == com_oracle_security_ucrypto_NativeDigestMD_MECH_MD5) {
119    len = sizeof(MD5_CTX);
120  } else { // SHA-2 family
121    len = sizeof(SHA2_CTX);
122  }
123  copy = malloc(len);
124  if (copy != NULL) {
125    bcopy((void *)pContext, copy, len);
126  }
127  return (jlong) copy;
128}
129
130void JavaCritical_com_oracle_security_ucrypto_NativeDigestMD_nativeFree
131  (jint mech, jlong pContext) {
132  if (mech == com_oracle_security_ucrypto_NativeDigestMD_MECH_SHA1) {
133    free((SHA1_CTX*) pContext);
134  } else if (mech == com_oracle_security_ucrypto_NativeDigestMD_MECH_MD5) {
135    free((MD5_CTX*) pContext);
136  } else { // SHA-2 family
137    free((SHA2_CTX*) pContext);
138  }
139}
140
141
142/*
143 * Class:     com_oracle_security_ucrypto_NativeDigestMD
144 * Method:    nativeInit
145 * Signature: (I)J
146 */
147JNIEXPORT jlong JNICALL Java_com_oracle_security_ucrypto_NativeDigestMD_nativeInit
148  (JNIEnv *env, jclass jcls, jint mech) {
149  jlong result = JavaCritical_com_oracle_security_ucrypto_NativeDigestMD_nativeInit(mech);
150  if (result == NULL) {
151     throwOutOfMemoryError(env, NULL);
152  }
153  return result;
154}
155
156/*
157 * Class:     com_oracle_security_ucrypto_NativeDigestMD
158 * Method:    nativeUpdate
159 * Signature: (IJ[BII)I
160 */
161JNIEXPORT jint JNICALL Java_com_oracle_security_ucrypto_NativeDigestMD_nativeUpdate
162  (JNIEnv *env, jclass jcls, jint mech, jlong pContext, jbyteArray jIn, jint jOfs, jint jLen) {
163  unsigned char *bufIn;
164
165  bufIn = (unsigned char *) getBytes(env, jIn, jOfs, jLen);
166  if (!(*env)->ExceptionCheck(env)) {
167    JavaCritical_com_oracle_security_ucrypto_NativeDigestMD_nativeUpdate(mech, pContext, jLen, bufIn, 0, jLen);
168    free(bufIn);
169  }
170  return 0;
171}
172
173/*
174 * Class:     com_oracle_security_ucrypto_NativeDigestMD
175 * Method:    nativeDigest
176 * Signature: (IJ[BII)I
177 */
178JNIEXPORT jint JNICALL Java_com_oracle_security_ucrypto_NativeDigestMD_nativeDigest
179  (JNIEnv *env, jclass jcls, jint mech, jlong pContext, jbyteArray jOut, jint jOutOfs, jint digestLen) {
180  unsigned char *bufOut;
181
182  bufOut = (unsigned char *) malloc(digestLen);
183  if (bufOut == NULL) {
184    throwOutOfMemoryError(env, NULL);
185    return 0;
186  }
187
188  JavaCritical_com_oracle_security_ucrypto_NativeDigestMD_nativeDigest(mech, pContext, digestLen, bufOut, 0, digestLen);
189
190  (*env)->SetByteArrayRegion(env, jOut, jOutOfs, digestLen, (jbyte *) bufOut);
191  free(bufOut);
192  return 0;
193}
194
195/*
196 * Class:     com_oracle_security_ucrypto_NativeDigestMD
197 * Method:    nativeClone
198 * Signature: (IJ)J
199 */
200JNIEXPORT jlong JNICALL Java_com_oracle_security_ucrypto_NativeDigestMD_nativeClone
201  (JNIEnv *env, jclass jcls, jint mech, jlong pContext) {
202  return JavaCritical_com_oracle_security_ucrypto_NativeDigestMD_nativeClone(mech, pContext);
203}
204
205/*
206 * Class:     com_oracle_security_ucrypto_NativeDigestMD
207 * Method:    nativeFree
208 * Signature: (IJ)V
209 */
210JNIEXPORT void JNICALL Java_com_oracle_security_ucrypto_NativeDigestMD_nativeFree
211  (JNIEnv *env, jclass jcls, jint mech, jlong pContext) {
212  JavaCritical_com_oracle_security_ucrypto_NativeDigestMD_nativeFree(mech, pContext);
213}
214
215