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 "nativeCrypto.h" 32#include "nativeFunc.h" 33 34 35extern void throwOutOfMemoryError(JNIEnv *env, const char *msg); 36extern jbyte* getBytes(JNIEnv *env, jbyteArray bytes, int offset, int len); 37 38/////////////////////////////////////////////////////// 39// SPECIAL ENTRIES FOR JVM JNI-BYPASSING OPTIMIZATION 40//////////////////////////////////////////////////////// 41jlong JavaCritical_com_oracle_security_ucrypto_NativeDigestMD_nativeInit(jint mech) { 42 void *pContext = NULL; 43 44 switch (mech) { 45 case com_oracle_security_ucrypto_NativeDigestMD_MECH_SHA1: 46 pContext = malloc(sizeof(SHA1_CTX)); 47 if (pContext != NULL) { 48 (*ftab->sha1Init)((SHA1_CTX *)pContext); 49 } 50 break; 51 case com_oracle_security_ucrypto_NativeDigestMD_MECH_MD5: 52 pContext = malloc(sizeof(MD5_CTX)); 53 if (pContext != NULL) { 54 (*ftab->md5Init)((MD5_CTX *)pContext); 55 } 56 break; 57 case com_oracle_security_ucrypto_NativeDigestMD_MECH_SHA256: 58 pContext = malloc(sizeof(SHA2_CTX)); 59 if (pContext != NULL) { 60 (*ftab->sha2Init)(SHA256, (SHA2_CTX *)pContext); 61 } 62 break; 63 case com_oracle_security_ucrypto_NativeDigestMD_MECH_SHA384: 64 pContext = malloc(sizeof(SHA2_CTX)); 65 if (pContext != NULL) { 66 (*ftab->sha2Init)(SHA384, (SHA2_CTX *)pContext); 67 } 68 break; 69 case com_oracle_security_ucrypto_NativeDigestMD_MECH_SHA512: 70 pContext = malloc(sizeof(SHA2_CTX)); 71 if (pContext != NULL) { 72 (*ftab->sha2Init)(SHA512, (SHA2_CTX *)pContext); 73 } 74 break; 75 default: 76 if (J2UC_DEBUG) printf("ERROR: Unsupported mech %i\n", mech); 77 } 78 return (jlong) pContext; 79} 80 81jint JavaCritical_com_oracle_security_ucrypto_NativeDigestMD_nativeUpdate 82 (jint mech, jlong pContext, int notUsed, unsigned char* in, jint ofs, jint len) { 83 if (mech == com_oracle_security_ucrypto_NativeDigestMD_MECH_SHA1) { 84 (*ftab->sha1Update)((SHA1_CTX*)pContext, (unsigned char*)(in+ofs), len); 85 } else if (mech == com_oracle_security_ucrypto_NativeDigestMD_MECH_MD5) { 86 (*ftab->md5Update)((MD5_CTX*)pContext, (unsigned char*)(in+ofs), len); 87 } else { // SHA-2 family 88 (*ftab->sha2Update)((SHA2_CTX*)pContext, (unsigned char*)(in+ofs), len); 89 } 90 return 0; 91} 92 93// Do digest and free the context immediately 94jint JavaCritical_com_oracle_security_ucrypto_NativeDigestMD_nativeDigest 95 (jint mech, jlong pContext, int notUsed, unsigned char* out, jint ofs, jint digestLen) { 96 97 if (mech == com_oracle_security_ucrypto_NativeDigestMD_MECH_SHA1) { 98 (*ftab->sha1Final)((unsigned char*)(out + ofs), (SHA1_CTX *)pContext); 99 free((SHA1_CTX *)pContext); 100 } else if (mech == com_oracle_security_ucrypto_NativeDigestMD_MECH_MD5) { 101 (*ftab->md5Final)((unsigned char*)(out + ofs), (MD5_CTX *)pContext); 102 free((MD5_CTX *)pContext); 103 } else { // SHA-2 family 104 (*ftab->sha2Final)((unsigned char*)(out + ofs), (SHA2_CTX *)pContext); 105 free((SHA2_CTX *)pContext); 106 } 107 return 0; 108} 109 110jlong JavaCritical_com_oracle_security_ucrypto_NativeDigestMD_nativeClone 111 (jint mech, jlong pContext) { 112 void *copy = NULL; 113 size_t len = 0; 114 115 if (mech == com_oracle_security_ucrypto_NativeDigestMD_MECH_SHA1) { 116 len = sizeof(SHA1_CTX); 117 } else if (mech == com_oracle_security_ucrypto_NativeDigestMD_MECH_MD5) { 118 len = sizeof(MD5_CTX); 119 } else { // SHA-2 family 120 len = sizeof(SHA2_CTX); 121 } 122 copy = malloc(len); 123 if (copy != NULL) { 124 bcopy((void *)pContext, copy, len); 125 } 126 return (jlong) copy; 127} 128 129void JavaCritical_com_oracle_security_ucrypto_NativeDigestMD_nativeFree 130 (jint mech, jlong pContext) { 131 if (mech == com_oracle_security_ucrypto_NativeDigestMD_MECH_SHA1) { 132 free((SHA1_CTX*) pContext); 133 } else if (mech == com_oracle_security_ucrypto_NativeDigestMD_MECH_MD5) { 134 free((MD5_CTX*) pContext); 135 } else { // SHA-2 family 136 free((SHA2_CTX*) pContext); 137 } 138} 139 140 141/* 142 * Class: com_oracle_security_ucrypto_NativeDigestMD 143 * Method: nativeInit 144 * Signature: (I)J 145 */ 146JNIEXPORT jlong JNICALL Java_com_oracle_security_ucrypto_NativeDigestMD_nativeInit 147 (JNIEnv *env, jclass jcls, jint mech) { 148 jlong result = JavaCritical_com_oracle_security_ucrypto_NativeDigestMD_nativeInit(mech); 149 if (result == NULL) { 150 throwOutOfMemoryError(env, NULL); 151 } 152 return result; 153} 154 155/* 156 * Class: com_oracle_security_ucrypto_NativeDigestMD 157 * Method: nativeUpdate 158 * Signature: (IJ[BII)I 159 */ 160JNIEXPORT jint JNICALL Java_com_oracle_security_ucrypto_NativeDigestMD_nativeUpdate 161 (JNIEnv *env, jclass jcls, jint mech, jlong pContext, jbyteArray jIn, jint jOfs, jint jLen) { 162 unsigned char *bufIn; 163 164 bufIn = (unsigned char *) getBytes(env, jIn, jOfs, jLen); 165 if (!(*env)->ExceptionCheck(env)) { 166 JavaCritical_com_oracle_security_ucrypto_NativeDigestMD_nativeUpdate(mech, pContext, jLen, bufIn, 0, jLen); 167 free(bufIn); 168 } 169 return 0; 170} 171 172/* 173 * Class: com_oracle_security_ucrypto_NativeDigestMD 174 * Method: nativeDigest 175 * Signature: (IJ[BII)I 176 */ 177JNIEXPORT jint JNICALL Java_com_oracle_security_ucrypto_NativeDigestMD_nativeDigest 178 (JNIEnv *env, jclass jcls, jint mech, jlong pContext, jbyteArray jOut, jint jOutOfs, jint digestLen) { 179 unsigned char *bufOut; 180 181 bufOut = (unsigned char *) malloc(digestLen); 182 if (bufOut == NULL) { 183 throwOutOfMemoryError(env, NULL); 184 return 0; 185 } 186 187 JavaCritical_com_oracle_security_ucrypto_NativeDigestMD_nativeDigest(mech, pContext, digestLen, bufOut, 0, digestLen); 188 189 (*env)->SetByteArrayRegion(env, jOut, jOutOfs, digestLen, (jbyte *) bufOut); 190 free(bufOut); 191 return 0; 192} 193 194/* 195 * Class: com_oracle_security_ucrypto_NativeDigestMD 196 * Method: nativeClone 197 * Signature: (IJ)J 198 */ 199JNIEXPORT jlong JNICALL Java_com_oracle_security_ucrypto_NativeDigestMD_nativeClone 200 (JNIEnv *env, jclass jcls, jint mech, jlong pContext) { 201 return JavaCritical_com_oracle_security_ucrypto_NativeDigestMD_nativeClone(mech, pContext); 202} 203 204/* 205 * Class: com_oracle_security_ucrypto_NativeDigestMD 206 * Method: nativeFree 207 * Signature: (IJ)V 208 */ 209JNIEXPORT void JNICALL Java_com_oracle_security_ucrypto_NativeDigestMD_nativeFree 210 (JNIEnv *env, jclass jcls, jint mech, jlong pContext) { 211 JavaCritical_com_oracle_security_ucrypto_NativeDigestMD_nativeFree(mech, pContext); 212} 213 214