|
@@ -46,6 +46,13 @@ static int (*dlsym_EVP_CipherUpdate)(EVP_CIPHER_CTX *, unsigned char *, \
|
|
static int (*dlsym_EVP_CipherFinal_ex)(EVP_CIPHER_CTX *, unsigned char *, int *);
|
|
static int (*dlsym_EVP_CipherFinal_ex)(EVP_CIPHER_CTX *, unsigned char *, int *);
|
|
static EVP_CIPHER * (*dlsym_EVP_aes_256_ctr)(void);
|
|
static EVP_CIPHER * (*dlsym_EVP_aes_256_ctr)(void);
|
|
static EVP_CIPHER * (*dlsym_EVP_aes_128_ctr)(void);
|
|
static EVP_CIPHER * (*dlsym_EVP_aes_128_ctr)(void);
|
|
|
|
+#if OPENSSL_VERSION_NUMBER >= 0x10100001L
|
|
|
|
+static EVP_CIPHER * (*dlsym_EVP_sm4_ctr)(void);
|
|
|
|
+static int (*dlsym_OPENSSL_init_crypto)(uint64_t opts, \
|
|
|
|
+ const OPENSSL_INIT_SETTINGS *settings);
|
|
|
|
+static ENGINE * (*dlsym_ENGINE_by_id)(const char *id);
|
|
|
|
+static int (*dlsym_ENGINE_free)(ENGINE *);
|
|
|
|
+#endif
|
|
static void *openssl;
|
|
static void *openssl;
|
|
#endif
|
|
#endif
|
|
|
|
|
|
@@ -84,6 +91,18 @@ static __dlsym_EVP_CipherUpdate dlsym_EVP_CipherUpdate;
|
|
static __dlsym_EVP_CipherFinal_ex dlsym_EVP_CipherFinal_ex;
|
|
static __dlsym_EVP_CipherFinal_ex dlsym_EVP_CipherFinal_ex;
|
|
static __dlsym_EVP_aes_256_ctr dlsym_EVP_aes_256_ctr;
|
|
static __dlsym_EVP_aes_256_ctr dlsym_EVP_aes_256_ctr;
|
|
static __dlsym_EVP_aes_128_ctr dlsym_EVP_aes_128_ctr;
|
|
static __dlsym_EVP_aes_128_ctr dlsym_EVP_aes_128_ctr;
|
|
|
|
+#if OPENSSL_VERSION_NUMBER >= 0x10101001L
|
|
|
|
+typedef EVP_CIPHER * (__cdecl *__dlsym_EVP_sm4_ctr)(void);
|
|
|
|
+typedef int (__cdecl *__dlsym_OPENSSL_init_crypto)(uint64_t opts, \
|
|
|
|
+ const OPENSSL_INIT_SETTINGS *settings);
|
|
|
|
+typedef ENGINE * (__cdecl *__dlsym_ENGINE_by_id)(const char *id);
|
|
|
|
+typedef int (__cdecl *__dlsym_ENGINE_free)(ENGINE *e);
|
|
|
|
+
|
|
|
|
+static __dlsym_EVP_sm4_ctr dlsym_EVP_sm4_ctr;
|
|
|
|
+static __dlsym_OPENSSL_init_crypto dlsym_OPENSSL_init_crypto;
|
|
|
|
+static __dlsym_ENGINE_by_id dlsym_ENGINE_by_id;
|
|
|
|
+static __dlsym_ENGINE_free dlsym_ENGINE_free;
|
|
|
|
+#endif
|
|
static HMODULE openssl;
|
|
static HMODULE openssl;
|
|
#endif
|
|
#endif
|
|
|
|
|
|
@@ -102,6 +121,15 @@ static void loadAesCtr(JNIEnv *env)
|
|
#endif
|
|
#endif
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static void loadSm4Ctr(JNIEnv *env)
|
|
|
|
+{
|
|
|
|
+#ifdef UNIX
|
|
|
|
+#if OPENSSL_VERSION_NUMBER >= 0x10101001L
|
|
|
|
+ LOAD_DYNAMIC_SYMBOL(dlsym_EVP_sm4_ctr, env, openssl, "EVP_sm4_ctr");
|
|
|
|
+#endif
|
|
|
|
+#endif
|
|
|
|
+}
|
|
|
|
+
|
|
JNIEXPORT void JNICALL Java_org_apache_hadoop_crypto_OpensslCipher_initIDs
|
|
JNIEXPORT void JNICALL Java_org_apache_hadoop_crypto_OpensslCipher_initIDs
|
|
(JNIEnv *env, jclass clazz)
|
|
(JNIEnv *env, jclass clazz)
|
|
{
|
|
{
|
|
@@ -153,6 +181,14 @@ JNIEXPORT void JNICALL Java_org_apache_hadoop_crypto_OpensslCipher_initIDs
|
|
"EVP_CipherUpdate");
|
|
"EVP_CipherUpdate");
|
|
LOAD_DYNAMIC_SYMBOL(dlsym_EVP_CipherFinal_ex, env, openssl, \
|
|
LOAD_DYNAMIC_SYMBOL(dlsym_EVP_CipherFinal_ex, env, openssl, \
|
|
"EVP_CipherFinal_ex");
|
|
"EVP_CipherFinal_ex");
|
|
|
|
+#if OPENSSL_VERSION_NUMBER >= 0x10101001L
|
|
|
|
+ LOAD_DYNAMIC_SYMBOL(dlsym_OPENSSL_init_crypto, env, openssl, \
|
|
|
|
+ "OPENSSL_init_crypto");
|
|
|
|
+ LOAD_DYNAMIC_SYMBOL(dlsym_ENGINE_by_id, env, openssl, \
|
|
|
|
+ "ENGINE_by_id");
|
|
|
|
+ LOAD_DYNAMIC_SYMBOL(dlsym_ENGINE_free, env, openssl, \
|
|
|
|
+ "ENGINE_free");
|
|
|
|
+#endif
|
|
#endif
|
|
#endif
|
|
|
|
|
|
#ifdef WINDOWS
|
|
#ifdef WINDOWS
|
|
@@ -185,14 +221,31 @@ JNIEXPORT void JNICALL Java_org_apache_hadoop_crypto_OpensslCipher_initIDs
|
|
env, openssl, "EVP_CipherUpdate");
|
|
env, openssl, "EVP_CipherUpdate");
|
|
LOAD_DYNAMIC_SYMBOL(__dlsym_EVP_CipherFinal_ex, dlsym_EVP_CipherFinal_ex, \
|
|
LOAD_DYNAMIC_SYMBOL(__dlsym_EVP_CipherFinal_ex, dlsym_EVP_CipherFinal_ex, \
|
|
env, openssl, "EVP_CipherFinal_ex");
|
|
env, openssl, "EVP_CipherFinal_ex");
|
|
|
|
+#if OPENSSL_VERSION_NUMBER >= 0x10101001L
|
|
|
|
+ LOAD_DYNAMIC_SYMBOL(__dlsym_OPENSSL_init_crypto, dlsym_OPENSSL_init_crypto, \
|
|
|
|
+ env, openssl, "OPENSSL_init_crypto");
|
|
|
|
+ LOAD_DYNAMIC_SYMBOL(__dlsym_ENGINE_by_id, dlsym_ENGINE_by_id, \
|
|
|
|
+ env, openssl, "ENGINE_by_id");
|
|
|
|
+ LOAD_DYNAMIC_SYMBOL(__dlsym_ENGINE_free, dlsym_ENGINE_free, \
|
|
|
|
+ env, openssl, "ENGINE_by_free");
|
|
|
|
+#endif
|
|
#endif
|
|
#endif
|
|
|
|
|
|
loadAesCtr(env);
|
|
loadAesCtr(env);
|
|
|
|
+ loadSm4Ctr(env);
|
|
|
|
+#if OPENSSL_VERSION_NUMBER >= 0x10101001L
|
|
|
|
+ int ret = dlsym_OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CONFIG, NULL);
|
|
|
|
+ if(!ret) {
|
|
|
|
+ THROW(env, "java/lang/UnsatisfiedLinkError", \
|
|
|
|
+ "Openssl init crypto failed");
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+#endif
|
|
jthrowable jthr = (*env)->ExceptionOccurred(env);
|
|
jthrowable jthr = (*env)->ExceptionOccurred(env);
|
|
if (jthr) {
|
|
if (jthr) {
|
|
(*env)->DeleteLocalRef(env, jthr);
|
|
(*env)->DeleteLocalRef(env, jthr);
|
|
THROW(env, "java/lang/UnsatisfiedLinkError", \
|
|
THROW(env, "java/lang/UnsatisfiedLinkError", \
|
|
- "Cannot find AES-CTR support, is your version of Openssl new enough?");
|
|
|
|
|
|
+ "Cannot find AES-CTR/SM4-CTR support, is your version of Openssl new enough?");
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -200,7 +253,7 @@ JNIEXPORT void JNICALL Java_org_apache_hadoop_crypto_OpensslCipher_initIDs
|
|
JNIEXPORT jlong JNICALL Java_org_apache_hadoop_crypto_OpensslCipher_initContext
|
|
JNIEXPORT jlong JNICALL Java_org_apache_hadoop_crypto_OpensslCipher_initContext
|
|
(JNIEnv *env, jclass clazz, jint alg, jint padding)
|
|
(JNIEnv *env, jclass clazz, jint alg, jint padding)
|
|
{
|
|
{
|
|
- if (alg != AES_CTR) {
|
|
|
|
|
|
+ if (alg != AES_CTR && alg != SM4_CTR) {
|
|
THROW(env, "java/security/NoSuchAlgorithmException", NULL);
|
|
THROW(env, "java/security/NoSuchAlgorithmException", NULL);
|
|
return (jlong)0;
|
|
return (jlong)0;
|
|
}
|
|
}
|
|
@@ -209,11 +262,27 @@ JNIEXPORT jlong JNICALL Java_org_apache_hadoop_crypto_OpensslCipher_initContext
|
|
return (jlong)0;
|
|
return (jlong)0;
|
|
}
|
|
}
|
|
|
|
|
|
- if (dlsym_EVP_aes_256_ctr == NULL || dlsym_EVP_aes_128_ctr == NULL) {
|
|
|
|
|
|
+ if (alg == AES_CTR && (dlsym_EVP_aes_256_ctr == NULL || dlsym_EVP_aes_128_ctr == NULL)) {
|
|
THROW(env, "java/security/NoSuchAlgorithmException", \
|
|
THROW(env, "java/security/NoSuchAlgorithmException", \
|
|
"Doesn't support AES CTR.");
|
|
"Doesn't support AES CTR.");
|
|
return (jlong)0;
|
|
return (jlong)0;
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ if (alg == SM4_CTR) {
|
|
|
|
+ int ret = 0;
|
|
|
|
+#if OPENSSL_VERSION_NUMBER >= 0x10101001L
|
|
|
|
+ if (dlsym_EVP_sm4_ctr == NULL) {
|
|
|
|
+ ret = 1;
|
|
|
|
+ }
|
|
|
|
+#else
|
|
|
|
+ ret = 1;
|
|
|
|
+#endif
|
|
|
|
+ if (ret) {
|
|
|
|
+ THROW(env, "java/security/NoSuchAlgorithmException", \
|
|
|
|
+ "Doesn't support SM4 CTR.");
|
|
|
|
+ return (jlong)0;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
|
|
// Create and initialize a EVP_CIPHER_CTX
|
|
// Create and initialize a EVP_CIPHER_CTX
|
|
EVP_CIPHER_CTX *context = dlsym_EVP_CIPHER_CTX_new();
|
|
EVP_CIPHER_CTX *context = dlsym_EVP_CIPHER_CTX_new();
|
|
@@ -225,7 +294,29 @@ JNIEXPORT jlong JNICALL Java_org_apache_hadoop_crypto_OpensslCipher_initContext
|
|
return JLONG(context);
|
|
return JLONG(context);
|
|
}
|
|
}
|
|
|
|
|
|
-// Only supports AES-CTR currently
|
|
|
|
|
|
+JNIEXPORT jlong JNICALL Java_org_apache_hadoop_crypto_OpensslCipher_initEngine
|
|
|
|
+ (JNIEnv *env, jclass clazz, jstring engineId)
|
|
|
|
+{
|
|
|
|
+ ENGINE *e = NULL;
|
|
|
|
+
|
|
|
|
+#if OPENSSL_VERSION_NUMBER >= 0x10101001L
|
|
|
|
+ if (engineId != NULL) {
|
|
|
|
+ const char *id = (*env)->GetStringUTFChars(env, engineId, NULL);
|
|
|
|
+ if (id != NULL) {
|
|
|
|
+ e = dlsym_ENGINE_by_id(id);
|
|
|
|
+ (*env)->ReleaseStringUTFChars(env, engineId, id);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+#endif
|
|
|
|
+
|
|
|
|
+ if (e == NULL) {
|
|
|
|
+ return (jlong)0;
|
|
|
|
+ } else {
|
|
|
|
+ return JLONG(e);
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+// Only supports AES-CTR & SM4-CTR currently
|
|
static EVP_CIPHER * getEvpCipher(int alg, int keyLen)
|
|
static EVP_CIPHER * getEvpCipher(int alg, int keyLen)
|
|
{
|
|
{
|
|
EVP_CIPHER *cipher = NULL;
|
|
EVP_CIPHER *cipher = NULL;
|
|
@@ -235,13 +326,19 @@ static EVP_CIPHER * getEvpCipher(int alg, int keyLen)
|
|
} else if (keyLen == KEY_LENGTH_128) {
|
|
} else if (keyLen == KEY_LENGTH_128) {
|
|
cipher = dlsym_EVP_aes_128_ctr();
|
|
cipher = dlsym_EVP_aes_128_ctr();
|
|
}
|
|
}
|
|
|
|
+ } else if (alg == SM4_CTR) {
|
|
|
|
+ if (keyLen == KEY_LENGTH_128) {
|
|
|
|
+#if OPENSSL_VERSION_NUMBER >= 0x10101001L
|
|
|
|
+ cipher = dlsym_EVP_sm4_ctr();
|
|
|
|
+#endif
|
|
|
|
+ }
|
|
}
|
|
}
|
|
return cipher;
|
|
return cipher;
|
|
}
|
|
}
|
|
|
|
|
|
JNIEXPORT jlong JNICALL Java_org_apache_hadoop_crypto_OpensslCipher_init
|
|
JNIEXPORT jlong JNICALL Java_org_apache_hadoop_crypto_OpensslCipher_init
|
|
(JNIEnv *env, jobject object, jlong ctx, jint mode, jint alg, jint padding,
|
|
(JNIEnv *env, jobject object, jlong ctx, jint mode, jint alg, jint padding,
|
|
- jbyteArray key, jbyteArray iv)
|
|
|
|
|
|
+ jbyteArray key, jbyteArray iv, jlong engine)
|
|
{
|
|
{
|
|
int jKeyLen = (*env)->GetArrayLength(env, key);
|
|
int jKeyLen = (*env)->GetArrayLength(env, key);
|
|
int jIvLen = (*env)->GetArrayLength(env, iv);
|
|
int jIvLen = (*env)->GetArrayLength(env, iv);
|
|
@@ -275,9 +372,10 @@ JNIEXPORT jlong JNICALL Java_org_apache_hadoop_crypto_OpensslCipher_init
|
|
THROW(env, "java/lang/InternalError", "Cannot get bytes array for iv.");
|
|
THROW(env, "java/lang/InternalError", "Cannot get bytes array for iv.");
|
|
return (jlong)0;
|
|
return (jlong)0;
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
|
|
+ ENGINE *e = LONG_TO_ENGINE(engine);
|
|
int rc = dlsym_EVP_CipherInit_ex(context, getEvpCipher(alg, jKeyLen), \
|
|
int rc = dlsym_EVP_CipherInit_ex(context, getEvpCipher(alg, jKeyLen), \
|
|
- NULL, (unsigned char *)jKey, (unsigned char *)jIv, mode == ENCRYPT_MODE);
|
|
|
|
|
|
+ e, (unsigned char *)jKey, (unsigned char *)jIv, mode == ENCRYPT_MODE);
|
|
(*env)->ReleaseByteArrayElements(env, key, jKey, 0);
|
|
(*env)->ReleaseByteArrayElements(env, key, jKey, 0);
|
|
(*env)->ReleaseByteArrayElements(env, iv, jIv, 0);
|
|
(*env)->ReleaseByteArrayElements(env, iv, jIv, 0);
|
|
if (rc == 0) {
|
|
if (rc == 0) {
|
|
@@ -406,12 +504,17 @@ JNIEXPORT jint JNICALL Java_org_apache_hadoop_crypto_OpensslCipher_doFinal
|
|
}
|
|
}
|
|
|
|
|
|
JNIEXPORT void JNICALL Java_org_apache_hadoop_crypto_OpensslCipher_clean
|
|
JNIEXPORT void JNICALL Java_org_apache_hadoop_crypto_OpensslCipher_clean
|
|
- (JNIEnv *env, jobject object, jlong ctx)
|
|
|
|
|
|
+ (JNIEnv *env, jobject object, jlong ctx, jlong engine)
|
|
{
|
|
{
|
|
EVP_CIPHER_CTX *context = CONTEXT(ctx);
|
|
EVP_CIPHER_CTX *context = CONTEXT(ctx);
|
|
if (context) {
|
|
if (context) {
|
|
dlsym_EVP_CIPHER_CTX_free(context);
|
|
dlsym_EVP_CIPHER_CTX_free(context);
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ ENGINE *e = LONG_TO_ENGINE(engine);
|
|
|
|
+ if (e) {
|
|
|
|
+ dlsym_ENGINE_free(e);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
JNIEXPORT jstring JNICALL Java_org_apache_hadoop_crypto_OpensslCipher_getLibraryName
|
|
JNIEXPORT jstring JNICALL Java_org_apache_hadoop_crypto_OpensslCipher_getLibraryName
|