1 /*
   2  * Copyright (c) 2014, 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 static const char UCRYPTO_ENCRYPT_INIT[]         = "ucrypto_encrypt_init";
  46 static const char UCRYPTO_ENCRYPT_UPDATE[]       = "ucrypto_encrypt_update";
  47 static const char UCRYPTO_ENCRYPT_FINAL[]        = "ucrypto_encrypt_final";
  48 static const char UCRYPTO_ENCRYPT[]              = "ucrypto_encrypt";
  49 static const char UCRYPTO_DECRYPT_INIT[]         = "ucrypto_decrypt_init";
  50 static const char UCRYPTO_DECRYPT_UPDATE[]       = "ucrypto_decrypt_update";
  51 static const char UCRYPTO_DECRYPT_FINAL[]        = "ucrypto_decrypt_final";
  52 static const char UCRYPTO_DECRYPT[]              = "ucrypto_decrypt";
  53 static const char UCRYPTO_SIGN_INIT[]            = "ucrypto_sign_init";
  54 static const char UCRYPTO_SIGN_UPDATE[]          = "ucrypto_sign_update";
  55 static const char UCRYPTO_SIGN_FINAL[]           = "ucrypto_sign_final";
  56 static const char UCRYPTO_VERIFY_INIT[]          = "ucrypto_verify_init";
  57 static const char UCRYPTO_VERIFY_UPDATE[]        = "ucrypto_verify_update";
  58 static const char UCRYPTO_VERIFY_FINAL[]         = "ucrypto_verify_final";
  59 
  60 /**
  61  * Initialize native T4 crypto function pointers
  62  */
  63 jboolean* loadNative() {
  64 
  65   jboolean* buf;
  66   void *lib;
  67 
  68   buf = malloc(2 * sizeof(jboolean));
  69   buf[0] = buf[1] = JNI_FALSE;
  70   ftab = (T4CRYPTO_FUNCTION_TABLE_PTR) calloc(1, sizeof(T4CRYPTO_FUNCTION_TABLE));
  71   if (ftab == NULL) {
  72     free(buf);
  73     return NULL;
  74   }
  75 
  76   lib = dlopen("libmd.so", RTLD_NOW);
  77   if (lib != NULL) {
  78     ftab->md5Init = (MD5INIT_FN_PTR) dlsym(lib, MD5_INIT);
  79     ftab->md5Update = (MD5UPDATE_FN_PTR) dlsym(lib, MD5_UPDATE);
  80     ftab->md5Final = (MD5FINAL_FN_PTR) dlsym(lib, MD5_FINAL);
  81     ftab->sha1Init = (SHA1INIT_FN_PTR) dlsym(lib, SHA1_INIT);
  82     ftab->sha1Update = (SHA1UPDATE_FN_PTR) dlsym(lib, SHA1_UPDATE);
  83     ftab->sha1Final = (SHA1FINAL_FN_PTR) dlsym(lib, SHA1_FINAL);
  84     ftab->sha2Init = (SHA2INIT_FN_PTR) dlsym(lib, SHA2_INIT);
  85     ftab->sha2Update = (SHA2UPDATE_FN_PTR) dlsym(lib, SHA2_UPDATE);
  86     ftab->sha2Final = (SHA2FINAL_FN_PTR) dlsym(lib, SHA2_FINAL);
  87     if (ftab->md5Init != NULL && ftab->md5Update != NULL &&
  88         ftab->md5Final != NULL && ftab->sha1Init != NULL &&
  89         ftab->sha1Update != NULL && ftab->sha1Final != NULL &&
  90         ftab->sha2Init != NULL && ftab->sha2Update != NULL &&
  91         ftab->sha2Final != NULL) {
  92       buf[0] = JNI_TRUE;
  93     } else {
  94       dlclose(lib);
  95     }
  96   }
  97 
  98   lib = dlopen("libsoftcrypto.so", RTLD_NOW);
  99   if (lib != NULL) {
 100     // These APIs aren't available for v0 lib on Solaris 10
 101     ftab->ucryptoVersion = (UCRYPTO_VERSION_FN_PTR)
 102       dlsym(lib, UCRYPTO_VERSION);
 103     ftab->ucryptoGetMechList = (UCRYPTO_GET_MECHLIST_FN_PTR)
 104       dlsym(lib, UCRYPTO_GET_MECHLIST);
 105     //??
 106     ftab->ucryptoSignInit = (UCRYPTO_SIGN_INIT_FN_PTR)
 107       dlsym(lib, UCRYPTO_SIGN_INIT);
 108     ftab->ucryptoSignUpdate = (UCRYPTO_SIGN_UPDATE_FN_PTR)
 109       dlsym(lib, UCRYPTO_SIGN_UPDATE);
 110     ftab->ucryptoSignFinal = (UCRYPTO_SIGN_FINAL_FN_PTR)
 111       dlsym(lib, UCRYPTO_SIGN_FINAL);
 112     ftab->ucryptoVerifyInit = (UCRYPTO_VERIFY_INIT_FN_PTR)
 113       dlsym(lib, UCRYPTO_VERIFY_INIT);
 114     ftab->ucryptoVerifyUpdate = (UCRYPTO_VERIFY_UPDATE_FN_PTR)
 115       dlsym(lib, UCRYPTO_VERIFY_UPDATE);
 116     ftab->ucryptoVerifyFinal = (UCRYPTO_VERIFY_FINAL_FN_PTR)
 117       dlsym(lib, UCRYPTO_VERIFY_FINAL);
 118 
 119     // These should be avilable for all libsoftcrypto libs
 120     ftab->ucryptoEncryptInit = (UCRYPTO_ENCRYPT_INIT_FN_PTR)
 121       dlsym(lib, UCRYPTO_ENCRYPT_INIT);
 122     ftab->ucryptoEncryptUpdate = (UCRYPTO_ENCRYPT_UPDATE_FN_PTR)
 123       dlsym(lib, UCRYPTO_ENCRYPT_UPDATE);
 124     ftab->ucryptoEncryptFinal = (UCRYPTO_ENCRYPT_FINAL_FN_PTR)
 125       dlsym(lib, UCRYPTO_ENCRYPT_FINAL);
 126     ftab->ucryptoEncrypt = (UCRYPTO_ENCRYPT_FN_PTR)
 127       dlsym(lib, UCRYPTO_ENCRYPT);
 128 
 129     ftab->ucryptoDecryptInit = (UCRYPTO_DECRYPT_INIT_FN_PTR)
 130       dlsym(lib, UCRYPTO_DECRYPT_INIT);
 131     ftab->ucryptoDecryptUpdate = (UCRYPTO_DECRYPT_UPDATE_FN_PTR)
 132       dlsym(lib, UCRYPTO_DECRYPT_UPDATE);
 133     ftab->ucryptoDecryptFinal = (UCRYPTO_DECRYPT_FINAL_FN_PTR)
 134       dlsym(lib, UCRYPTO_DECRYPT_FINAL);
 135     ftab->ucryptoDecrypt = (UCRYPTO_DECRYPT_FN_PTR)
 136       dlsym(lib, UCRYPTO_DECRYPT);
 137 
 138     if (ftab->ucryptoEncryptInit != NULL &&
 139         ftab->ucryptoEncryptUpdate != NULL &&
 140         ftab->ucryptoEncryptFinal != NULL &&
 141         ftab->ucryptoEncrypt != NULL &&
 142         ftab->ucryptoDecryptInit != NULL &&
 143         ftab->ucryptoDecryptUpdate != NULL &&
 144         ftab->ucryptoDecryptFinal != NULL &&
 145         ftab->ucryptoDecrypt != NULL) {
 146       buf[1] = JNI_TRUE;
 147     } else {
 148       dlclose(lib);
 149     }
 150   }
 151 
 152   return buf;
 153 }