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 }