diff --git a/native/compile-native.sh b/native/compile-native.sh index 5b6e54c4..b5c011d8 100755 --- a/native/compile-native.sh +++ b/native/compile-native.sh @@ -2,8 +2,10 @@ set -eu +CWD=$(pwd) + echo "Compiling mbedtls" -(cd mbedtls && make no_test) +(cd mbedtls && CFLAGS="-fPIC -I$CWD/src/main/c -DMBEDTLS_USER_CONFIG_FILE=''" make no_test) echo "Compiling zlib" (cd zlib && CFLAGS=-fPIC ./configure --static && make) diff --git a/native/src/main/c/NativeCipherImpl.c b/native/src/main/c/NativeCipherImpl.c index 727a2f1f..020aaa1d 100644 --- a/native/src/main/c/NativeCipherImpl.c +++ b/native/src/main/c/NativeCipherImpl.c @@ -5,11 +5,15 @@ #include "shared.h" #include "net_md_5_bungee_jni_cipher_NativeCipherImpl.h" +// Hack to keep the compiler from optimizing the memset away +static void *(*const volatile memset_func)(void *, int, size_t) = memset; + typedef unsigned char byte; typedef struct crypto_context { int mode; mbedtls_aes_context cipher; + int keyLen; byte key[]; } crypto_context; @@ -22,6 +26,7 @@ jlong JNICALL Java_net_md_15_bungee_jni_cipher_NativeCipherImpl_init(JNIEnv* env return 0; } + crypto->keyLen = (int) keyLen; (*env)->GetByteArrayRegion(env, key, 0, keyLen, (jbyte*) &crypto->key); mbedtls_aes_init(&crypto->cipher); @@ -36,6 +41,7 @@ void Java_net_md_15_bungee_jni_cipher_NativeCipherImpl_free(JNIEnv* env, jobject crypto_context *crypto = (crypto_context*) ctx; mbedtls_aes_free(&crypto->cipher); + memset_func(crypto->key, 0, (size_t) crypto->keyLen); free(crypto); } diff --git a/native/src/main/c/mbedtls_custom_config.h b/native/src/main/c/mbedtls_custom_config.h new file mode 100644 index 00000000..a32df887 --- /dev/null +++ b/native/src/main/c/mbedtls_custom_config.h @@ -0,0 +1,31 @@ + +// This is a hack to deal with a glitch that happens when mbedtls is compiled against glibc +// but then run on a linux distro that uses musl libc. This implementation of the zeroize +// is compatible with both glibc and musl without requiring the library to be recompiled. + +// I checked with a disassembler and for BungeeCord's usage of the library, implementing +// this function as a static function only resulted in 2 different subroutines referencing +// different versions of memset_func, so we might as well keep things simple and use a +// static function here instead of requiring the mbedtls makefile to be modified to add +// additional source files. + +#ifndef _INCLUDE_MBEDTLS_CUSTOM_CONFIG_H +#define _INCLUDE_MBEDTLS_CUSTOM_CONFIG_H + +#include + +#define MBEDTLS_PLATFORM_ZEROIZE_ALT + +#define mbedtls_platform_zeroize mbedtls_platform_zeroize_impl + +// hack to prevent compilers from optimizing the memset away +static void *(*const volatile memset_func)(void *, int, size_t) = memset; + +static void mbedtls_platform_zeroize_impl(void *buf, size_t len) { + if (len > 0) { + memset_func(buf, 0, len); + } +} + +#endif // _INCLUDE_MBEDTLS_CUSTOM_CONFIG_H + diff --git a/native/src/main/resources/native-cipher.so b/native/src/main/resources/native-cipher.so index 87cc1756..45afa5f8 100755 Binary files a/native/src/main/resources/native-cipher.so and b/native/src/main/resources/native-cipher.so differ