diff --git a/.gitignore b/.gitignore index 1cf6c5d69..fbdf3cea6 100644 --- a/.gitignore +++ b/.gitignore @@ -91,3 +91,4 @@ native/mbedtls native/zlib-ng native/zlib-cf native/libdeflate +native/src/main/resources/linux_x86_64/velocity-cipher.so \ No newline at end of file diff --git a/native/compile-linux.sh b/native/compile-linux.sh index db7227d06..6d92b6462 100755 --- a/native/compile-linux.sh +++ b/native/compile-linux.sh @@ -7,16 +7,13 @@ fi echo "Compiling libdeflate..." cd libdeflate || exit -make +CFLAGS="-fPIC -O2" make cd .. -# Modify as you need. -MBEDTLS_ROOT=mbedtls CFLAGS="-O3 -I$JAVA_HOME/include/ -I$JAVA_HOME/include/linux/ -fPIC -shared -Wl,-z,noexecstack" ARCH=$(uname -m) mkdir -p src/main/resources/linux_$ARCH gcc $CFLAGS -Ilibdeflate src/main/c/jni_util.c src/main/c/jni_zlib_deflate.c src/main/c/jni_zlib_inflate.c \ libdeflate/libdeflate.a -o src/main/resources/linux_$ARCH/velocity-compress.so -gcc $CFLAGS -I $MBEDTLS_ROOT/include -shared $MBEDTLS_ROOT/library/aes.c $MBEDTLS_ROOT/library/aesni.c \ - $MBEDTLS_ROOT/library/platform.c $MBEDTLS_ROOT/library/platform_util.c src/main/c/jni_util.c src/main/c/jni_cipher.c \ - -o src/main/resources/linux_$ARCH/velocity-cipher.so \ No newline at end of file +gcc $CFLAGS -I $MBEDTLS_ROOT/include -shared src/main/c/jni_util.c src/main/c/jni_cipher.c \ + -o src/main/resources/linux_$ARCH/velocity-cipher.so -lcrypto \ No newline at end of file diff --git a/native/src/main/c/jni_cipher.c b/native/src/main/c/jni_cipher.c index 2a7b92420..e0b0b84e8 100644 --- a/native/src/main/c/jni_cipher.c +++ b/native/src/main/c/jni_cipher.c @@ -1,81 +1,59 @@ #include #include #include -#include +#include #include "jni_util.h" typedef unsigned char byte; -typedef struct { - mbedtls_aes_context cipher; - byte *key; -} velocity_cipher_context; - JNIEXPORT jlong JNICALL -Java_com_velocitypowered_natives_encryption_MbedtlsAesImpl_init(JNIEnv *env, +Java_com_velocitypowered_natives_encryption_OpenSslCipherImpl_init(JNIEnv *env, jobject obj, - jbyteArray key) + jbyteArray key, + jboolean encrypt) { - velocity_cipher_context *ctx = malloc(sizeof(velocity_cipher_context)); + EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new(); if (ctx == NULL) { - throwException(env, "java/lang/OutOfMemoryError", "cipher allocate context"); + throwException(env, "java/lang/OutOfMemoryError", "allocate cipher"); return 0; } jsize keyLen = (*env)->GetArrayLength(env, key); jbyte* keyBytes = (*env)->GetPrimitiveArrayCritical(env, key, NULL); if (keyBytes == NULL) { - free(ctx); + EVP_CIPHER_CTX_free(ctx); throwException(env, "java/lang/OutOfMemoryError", "cipher get key"); return 0; } - mbedtls_aes_init(&ctx->cipher); - int ret = mbedtls_aes_setkey_enc(&ctx->cipher, (byte*) keyBytes, keyLen * 8); - if (ret != 0) { - (*env)->ReleasePrimitiveArrayCritical(env, key, keyBytes, 0); - mbedtls_aes_free(&ctx->cipher); - free(ctx); - - throwException(env, "java/security/GeneralSecurityException", "mbedtls set aes key"); - return 0; - } - - ctx->key = malloc(keyLen); - if (ctx->key == NULL) { - (*env)->ReleasePrimitiveArrayCritical(env, key, keyBytes, 0); - mbedtls_aes_free(&ctx->cipher); - free(ctx); - - throwException(env, "java/lang/OutOfMemoryError", "cipher copy key"); - return 0; - } - memcpy(ctx->key, keyBytes, keyLen); + int result = EVP_CipherInit(ctx, EVP_aes_128_cfb8(), (byte*) keyBytes, (byte*) keyBytes, + encrypt); + // Release the key byte array now - we won't need it (*env)->ReleasePrimitiveArrayCritical(env, key, keyBytes, 0); + + if (result != 1) { + EVP_CIPHER_CTX_free(ctx); + throwException(env, "java/security/GeneralSecurityException", "openssl initialize cipher"); + return 0; + } return (jlong) ctx; } JNIEXPORT void JNICALL -Java_com_velocitypowered_natives_encryption_MbedtlsAesImpl_free(JNIEnv *env, +Java_com_velocitypowered_natives_encryption_OpenSslCipherImpl_free(JNIEnv *env, jobject obj, jlong ptr) { - velocity_cipher_context *ctx = (velocity_cipher_context*) ptr; - mbedtls_aes_free(&ctx->cipher); - free(ctx->key); - free(ctx); + EVP_CIPHER_CTX_free((EVP_CIPHER_CTX *) ptr); } JNIEXPORT void JNICALL -Java_com_velocitypowered_natives_encryption_MbedtlsAesImpl_process(JNIEnv *env, +Java_com_velocitypowered_natives_encryption_OpenSslCipherImpl_process(JNIEnv *env, jobject obj, jlong ptr, jlong source, jint len, - jlong dest, - jboolean encrypt) + jlong dest) { - velocity_cipher_context *ctx = (velocity_cipher_context*) ptr; - mbedtls_aes_crypt_cfb8(&ctx->cipher, encrypt ? MBEDTLS_AES_ENCRYPT : MBEDTLS_AES_DECRYPT, len, ctx->key, - (byte*) source, (byte*) dest); + EVP_CipherUpdate((EVP_CIPHER_CTX*) ptr, (byte*) dest, &len, (byte*) source, len); } \ No newline at end of file diff --git a/native/src/main/java/com/velocitypowered/natives/encryption/MbedtlsAesImpl.java b/native/src/main/java/com/velocitypowered/natives/encryption/MbedtlsAesImpl.java deleted file mode 100644 index ef57cdaa8..000000000 --- a/native/src/main/java/com/velocitypowered/natives/encryption/MbedtlsAesImpl.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.velocitypowered.natives.encryption; - -import java.security.GeneralSecurityException; - -class MbedtlsAesImpl { - - native long init(byte[] key) throws GeneralSecurityException; - - native void process(long ctx, long sourceAddress, int sourceLength, long destinationAddress, - boolean encrypt); - - native void free(long ptr); -} diff --git a/native/src/main/java/com/velocitypowered/natives/encryption/NativeVelocityCipher.java b/native/src/main/java/com/velocitypowered/natives/encryption/NativeVelocityCipher.java index ee7ab1532..cd0bcbd0a 100644 --- a/native/src/main/java/com/velocitypowered/natives/encryption/NativeVelocityCipher.java +++ b/native/src/main/java/com/velocitypowered/natives/encryption/NativeVelocityCipher.java @@ -3,10 +3,8 @@ package com.velocitypowered.natives.encryption; import com.google.common.base.Preconditions; import com.velocitypowered.natives.util.BufferPreference; import io.netty.buffer.ByteBuf; -import io.netty.channel.ChannelHandlerContext; import java.security.GeneralSecurityException; import javax.crypto.SecretKey; -import javax.crypto.ShortBufferException; public class NativeVelocityCipher implements VelocityCipher { @@ -21,15 +19,13 @@ public class NativeVelocityCipher implements VelocityCipher { return new NativeVelocityCipher(false, key); } }; - private static final MbedtlsAesImpl impl = new MbedtlsAesImpl(); + private static final OpenSslCipherImpl impl = new OpenSslCipherImpl(); private final long ctx; - private final boolean encrypt; private boolean disposed = false; private NativeVelocityCipher(boolean encrypt, SecretKey key) throws GeneralSecurityException { - this.encrypt = encrypt; - this.ctx = impl.init(key.getEncoded()); + this.ctx = impl.init(key.getEncoded(), encrypt); } @Override @@ -40,7 +36,7 @@ public class NativeVelocityCipher implements VelocityCipher { long base = source.memoryAddress() + source.readerIndex(); int len = source.readableBytes(); - impl.process(ctx, base, len, base, encrypt); + impl.process(ctx, base, len, base); } @Override diff --git a/native/src/main/java/com/velocitypowered/natives/encryption/OpenSslCipherImpl.java b/native/src/main/java/com/velocitypowered/natives/encryption/OpenSslCipherImpl.java new file mode 100644 index 000000000..da5fc6b50 --- /dev/null +++ b/native/src/main/java/com/velocitypowered/natives/encryption/OpenSslCipherImpl.java @@ -0,0 +1,12 @@ +package com.velocitypowered.natives.encryption; + +import java.security.GeneralSecurityException; + +class OpenSslCipherImpl { + + native long init(byte[] key, boolean encrypt) throws GeneralSecurityException; + + native void process(long ctx, long source, int len, long dest); + + native void free(long ptr); +} diff --git a/native/src/main/java/com/velocitypowered/natives/util/Natives.java b/native/src/main/java/com/velocitypowered/natives/util/Natives.java index 120ec1ee7..24ff34472 100644 --- a/native/src/main/java/com/velocitypowered/natives/util/Natives.java +++ b/native/src/main/java/com/velocitypowered/natives/util/Natives.java @@ -79,12 +79,18 @@ public class Natives { public static final NativeCodeLoader cipher = new NativeCodeLoader<>( ImmutableList.of( - new NativeCodeLoader.Variant<>(NativeConstraints.LINUX_X86_64, - copyAndLoadNative("/linux_x86_64/velocity-cipher.so"), - "mbed TLS (Linux x86_64)", NativeVelocityCipher.FACTORY), + new NativeCodeLoader.Variant<>(NativeConstraints.LINUX_X86_64, + copyAndLoadNative("/linux_x86_64/velocity-cipher.so"), // Any local version + "OpenSSL local (Linux x86_64)", NativeVelocityCipher.FACTORY), + new NativeCodeLoader.Variant<>(NativeConstraints.LINUX_X86_64, + copyAndLoadNative("/linux_x86_64/velocity-cipher-ossl11x.so"), // Debian 9 + "OpenSSL 1.1.x (Linux x86_64)", NativeVelocityCipher.FACTORY), + new NativeCodeLoader.Variant<>(NativeConstraints.LINUX_X86_64, + copyAndLoadNative("/linux_x86_64/velocity-cipher-ossl10x.so"), // CentOS 7 + "OpenSSL 1.0.x (Linux x86_64)", NativeVelocityCipher.FACTORY), new NativeCodeLoader.Variant<>(NativeConstraints.LINUX_AARCH64, copyAndLoadNative("/linux_aarch64/velocity-cipher.so"), - "mbed TLS (Linux aarch64)", NativeVelocityCipher.FACTORY), + "OpenSSL (Linux aarch64)", NativeVelocityCipher.FACTORY), new NativeCodeLoader.Variant<>(NativeCodeLoader.ALWAYS, () -> { }, "Java", JavaVelocityCipher.FACTORY) ) diff --git a/native/src/main/resources/linux_x86_64/velocity-cipher-ossl10x.so b/native/src/main/resources/linux_x86_64/velocity-cipher-ossl10x.so new file mode 100755 index 000000000..f69edf145 Binary files /dev/null and b/native/src/main/resources/linux_x86_64/velocity-cipher-ossl10x.so differ diff --git a/native/src/main/resources/linux_x86_64/velocity-cipher-ossl11x.so b/native/src/main/resources/linux_x86_64/velocity-cipher-ossl11x.so new file mode 100755 index 000000000..37451294a Binary files /dev/null and b/native/src/main/resources/linux_x86_64/velocity-cipher-ossl11x.so differ diff --git a/native/src/main/resources/linux_x86_64/velocity-compress.so b/native/src/main/resources/linux_x86_64/velocity-compress.so index d72a66bfd..098226822 100755 Binary files a/native/src/main/resources/linux_x86_64/velocity-compress.so and b/native/src/main/resources/linux_x86_64/velocity-compress.so differ diff --git a/native/src/test/java/com/velocitypowered/natives/encryption/VelocityCipherTest.java b/native/src/test/java/com/velocitypowered/natives/encryption/VelocityCipherTest.java index 93ab89117..2c48ca99a 100644 --- a/native/src/test/java/com/velocitypowered/natives/encryption/VelocityCipherTest.java +++ b/native/src/test/java/com/velocitypowered/natives/encryption/VelocityCipherTest.java @@ -30,7 +30,6 @@ class VelocityCipherTest { } @Test - @Disabled void nativeIntegrityCheck() throws GeneralSecurityException { VelocityCipherFactory factory = Natives.cipher.get(); if (factory == JavaVelocityCipher.FACTORY) { @@ -39,11 +38,6 @@ class VelocityCipherTest { check(factory, Unpooled::directBuffer); } - @Test - void javaIntegrityCheckDirect() throws GeneralSecurityException { - check(JavaVelocityCipher.FACTORY, Unpooled::directBuffer); - } - @Test void javaIntegrityCheckHeap() throws GeneralSecurityException { check(JavaVelocityCipher.FACTORY, Unpooled::buffer);