1 /* 2 * Copyright (c) 2014, 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 <jni.h> 27 #include <stdio.h> 28 #include <stdlib.h> 29 #include <dlfcn.h> 30 #include <link.h> 31 #include "nativeFunc.h" 32 33 /* standard md5/md/softcrypto method names (ordering is from mapfile) */ 34 static const char MD5_INIT[] = "MD5Init"; 35 static const char MD5_UPDATE[] = "MD5Update"; 36 static const char MD5_FINAL[] = "MD5Final"; 37 static const char SHA1_INIT[] = "SHA1Init"; 38 static const char SHA1_UPDATE[] = "SHA1Update"; 39 static const char SHA1_FINAL[] = "SHA1Final"; 40 static const char SHA2_INIT[] = "SHA2Init"; 41 static const char SHA2_UPDATE[] = "SHA2Update"; 42 static const char SHA2_FINAL[] = "SHA2Final"; 43 static const char UCRYPTO_VERSION[] = "ucrypto_version"; 44 static const char UCRYPTO_GET_MECHLIST[] = "ucrypto_get_mechlist"; 45 46 static const char UCRYPTO_ENCRYPT_INIT[] = "ucrypto_encrypt_init"; 47 static const char UCRYPTO_ENCRYPT_UPDATE[] = "ucrypto_encrypt_update"; 48 static const char UCRYPTO_ENCRYPT_FINAL[] = "ucrypto_encrypt_final"; 49 static const char UCRYPTO_ENCRYPT[] = "ucrypto_encrypt"; 50 51 static const char UCRYPTO_DECRYPT_INIT[] = "ucrypto_decrypt_init"; 52 static const char UCRYPTO_DECRYPT_UPDATE[] = "ucrypto_decrypt_update"; 53 static const char UCRYPTO_DECRYPT_FINAL[] = "ucrypto_decrypt_final"; 54 static const char UCRYPTO_DECRYPT[] = "ucrypto_decrypt"; 55 56 static const char UCRYPTO_SIGN_INIT[] = "ucrypto_sign_init"; 57 static const char UCRYPTO_SIGN_UPDATE[] = "ucrypto_sign_update"; 58 static const char UCRYPTO_SIGN_FINAL[] = "ucrypto_sign_final"; 59 60 static const char UCRYPTO_VERIFY_INIT[] = "ucrypto_verify_init"; 61 static const char UCRYPTO_VERIFY_UPDATE[] = "ucrypto_verify_update"; 62 static const char UCRYPTO_VERIFY_FINAL[] = "ucrypto_verify_final"; 63 64 static const char UCRYPTO_DIGEST_INIT[] = "ucrypto_digest_init"; 65 static const char UCRYPTO_DIGEST_UPDATE[] = "ucrypto_digest_update"; 66 static const char UCRYPTO_DIGEST_FINAL[] = "ucrypto_digest_final"; 67 68 static const char UCRYPTO_FREE_CONTEXT[] = "ucrypto_free_context"; 69 70 static const char UCRYPTO_STRERROR[] = "ucrypto_strerror"; 71 72 /** 73 * Initialize native T4 crypto function pointers 74 */ 75 jboolean* loadNative() { 76 77 jboolean* buf; 78 void *lib; 79 80 buf = malloc(2 * sizeof(jboolean)); 81 buf[0] = buf[1] = JNI_FALSE; 82 ftab = (T4CRYPTO_FUNCTION_TABLE_PTR) calloc(1, sizeof(T4CRYPTO_FUNCTION_TABLE)); 83 if (ftab == NULL) { 84 free(buf); 85 return NULL; 86 } 87 88 lib = dlopen("libsoftcrypto.so", RTLD_NOW); 89 if (lib != NULL) { 90 // These APIs aren't available for v0 lib on Solaris 10 91 ftab->ucryptoVersion = (UCRYPTO_VERSION_FN_PTR) 92 dlsym(lib, UCRYPTO_VERSION); 93 ftab->ucryptoGetMechList = (UCRYPTO_GET_MECHLIST_FN_PTR) 94 dlsym(lib, UCRYPTO_GET_MECHLIST); 95 ftab->ucryptoSignInit = (UCRYPTO_SIGN_INIT_FN_PTR) 96 dlsym(lib, UCRYPTO_SIGN_INIT); 97 ftab->ucryptoSignUpdate = (UCRYPTO_SIGN_UPDATE_FN_PTR) 98 dlsym(lib, UCRYPTO_SIGN_UPDATE); 99 ftab->ucryptoSignFinal = (UCRYPTO_SIGN_FINAL_FN_PTR) 100 dlsym(lib, UCRYPTO_SIGN_FINAL); 101 ftab->ucryptoVerifyInit = (UCRYPTO_VERIFY_INIT_FN_PTR) 102 dlsym(lib, UCRYPTO_VERIFY_INIT); 103 ftab->ucryptoVerifyUpdate = (UCRYPTO_VERIFY_UPDATE_FN_PTR) 104 dlsym(lib, UCRYPTO_VERIFY_UPDATE); 105 ftab->ucryptoVerifyFinal = (UCRYPTO_VERIFY_FINAL_FN_PTR) 106 dlsym(lib, UCRYPTO_VERIFY_FINAL); 107 108 // These APS are added starting S12 109 ftab->ucryptoDigestInit = (UCRYPTO_DIGEST_INIT_FN_PTR) 110 dlsym(lib, UCRYPTO_DIGEST_INIT); 111 ftab->ucryptoDigestUpdate = (UCRYPTO_DIGEST_UPDATE_FN_PTR) 112 dlsym(lib, UCRYPTO_DIGEST_UPDATE); 113 ftab->ucryptoDigestFinal = (UCRYPTO_DIGEST_FINAL_FN_PTR) 114 dlsym(lib, UCRYPTO_DIGEST_FINAL); 115 116 ftab->ucryptoFreeContext = (UCRYPTO_FREE_CONTEXT_FN_PTR) 117 dlsym(lib, UCRYPTO_FREE_CONTEXT); 118 119 ftab->ucryptoStrerror = (UCRYPTO_STRERROR_FN_PTR) 120 dlsym(lib, UCRYPTO_STRERROR); 121 122 123 // These should be avilable for all libsoftcrypto libs 124 ftab->ucryptoEncryptInit = (UCRYPTO_ENCRYPT_INIT_FN_PTR) 125 dlsym(lib, UCRYPTO_ENCRYPT_INIT); 126 ftab->ucryptoEncryptUpdate = (UCRYPTO_ENCRYPT_UPDATE_FN_PTR) 127 dlsym(lib, UCRYPTO_ENCRYPT_UPDATE); 128 ftab->ucryptoEncryptFinal = (UCRYPTO_ENCRYPT_FINAL_FN_PTR) 129 dlsym(lib, UCRYPTO_ENCRYPT_FINAL); 130 ftab->ucryptoEncrypt = (UCRYPTO_ENCRYPT_FN_PTR) 131 dlsym(lib, UCRYPTO_ENCRYPT); 132 133 ftab->ucryptoDecryptInit = (UCRYPTO_DECRYPT_INIT_FN_PTR) 134 dlsym(lib, UCRYPTO_DECRYPT_INIT); 135 ftab->ucryptoDecryptUpdate = (UCRYPTO_DECRYPT_UPDATE_FN_PTR) 136 dlsym(lib, UCRYPTO_DECRYPT_UPDATE); 137 ftab->ucryptoDecryptFinal = (UCRYPTO_DECRYPT_FINAL_FN_PTR) 138 dlsym(lib, UCRYPTO_DECRYPT_FINAL); 139 ftab->ucryptoDecrypt = (UCRYPTO_DECRYPT_FN_PTR) 140 dlsym(lib, UCRYPTO_DECRYPT); 141 142 if (ftab->ucryptoEncryptInit != NULL && 143 ftab->ucryptoEncryptUpdate != NULL && 144 ftab->ucryptoEncryptFinal != NULL && 145 ftab->ucryptoEncrypt != NULL && 146 ftab->ucryptoDecryptInit != NULL && 147 ftab->ucryptoDecryptUpdate != NULL && 148 ftab->ucryptoDecryptFinal != NULL && 149 ftab->ucryptoDecrypt != NULL) { 150 buf[1] = JNI_TRUE; 151 } else { 152 dlclose(lib); 153 } 154 155 // proceed with libmd when libucrypto does not support digest operations 156 if (ftab->ucryptoDigestInit == NULL || 157 ftab->ucryptoDigestUpdate == NULL || 158 ftab->ucryptoDigestFinal == NULL) { 159 160 lib = dlopen("libmd.so", RTLD_NOW); 161 if (lib != NULL) { 162 ftab->md5Init = (MD5INIT_FN_PTR) dlsym(lib, MD5_INIT); 163 ftab->md5Update = (MD5UPDATE_FN_PTR) dlsym(lib, MD5_UPDATE); 164 ftab->md5Final = (MD5FINAL_FN_PTR) dlsym(lib, MD5_FINAL); 165 ftab->sha1Init = (SHA1INIT_FN_PTR) dlsym(lib, SHA1_INIT); 166 ftab->sha1Update = (SHA1UPDATE_FN_PTR) dlsym(lib, SHA1_UPDATE); 167 ftab->sha1Final = (SHA1FINAL_FN_PTR) dlsym(lib, SHA1_FINAL); 168 ftab->sha2Init = (SHA2INIT_FN_PTR) dlsym(lib, SHA2_INIT); 169 ftab->sha2Update = (SHA2UPDATE_FN_PTR) dlsym(lib, SHA2_UPDATE); 170 ftab->sha2Final = (SHA2FINAL_FN_PTR) dlsym(lib, SHA2_FINAL); 171 if (ftab->md5Init != NULL && ftab->md5Update != NULL && 172 ftab->md5Final != NULL && ftab->sha1Init != NULL && 173 ftab->sha1Update != NULL && ftab->sha1Final != NULL && 174 ftab->sha2Init != NULL && ftab->sha2Update != NULL && 175 ftab->sha2Final != NULL) { 176 buf[0] = JNI_TRUE; 177 } else { 178 dlclose(lib); 179 } 180 } 181 } 182 } 183 184 return buf; 185 }