summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Priyanka Advani (xWF) <padvani@google.com> 2024-12-02 20:10:49 +0000
committer Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> 2024-12-02 20:10:49 +0000
commit38f65e4c727bb055b99d0470a2f6797837449527 (patch)
tree7a1b8218d1347f2cb8a8967597abe56a355e7f0f
parent0f03f91e3ca0a4b44b6d8677cad8e4470c2c21b4 (diff)
parent924d8b1345cf97ecf7f7905e86d6b16ff72d5b93 (diff)
Merge "Revert "ArrayUtils: add secure zeroization support"" into main am: 761f2c8102 am: 924d8b1345
Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/3387622 Change-Id: I3023a23cff05a5afd4a3b15af32dc313e5893306 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
-rw-r--r--core/java/com/android/internal/util/ArrayUtils.java45
-rw-r--r--core/jni/Android.bp1
-rw-r--r--core/jni/AndroidRuntime.cpp2
-rw-r--r--core/jni/com_android_internal_util_ArrayUtils.cpp122
-rw-r--r--core/tests/utiltests/src/com/android/internal/util/ArrayUtilsTest.java47
5 files changed, 0 insertions, 217 deletions
diff --git a/core/java/com/android/internal/util/ArrayUtils.java b/core/java/com/android/internal/util/ArrayUtils.java
index 9b8551bf134c..1e965c5db7ae 100644
--- a/core/java/com/android/internal/util/ArrayUtils.java
+++ b/core/java/com/android/internal/util/ArrayUtils.java
@@ -85,51 +85,6 @@ public class ArrayUtils {
}
/**
- * This is like <code>new byte[length]</code>, but it allocates the array as non-movable. This
- * prevents copies of the data from being left on the Java heap as a result of heap compaction.
- * Use this when the array will contain sensitive data such as a password or cryptographic key
- * that needs to be wiped from memory when no longer needed. The owner of the array is still
- * responsible for the zeroization; {@link #zeroize(byte[])} should be used to do so.
- *
- * @param length the length of the array to allocate
- * @return the new array
- */
- public static byte[] newNonMovableByteArray(int length) {
- return (byte[]) VMRuntime.getRuntime().newNonMovableArray(byte.class, length);
- }
-
- /**
- * Like {@link #newNonMovableByteArray(int)}, but allocates a char array.
- *
- * @param length the length of the array to allocate
- * @return the new array
- */
- public static char[] newNonMovableCharArray(int length) {
- return (char[]) VMRuntime.getRuntime().newNonMovableArray(char.class, length);
- }
-
- /**
- * Zeroizes a byte array as securely as possible. Use this when the array contains sensitive
- * data such as a password or cryptographic key.
- * <p>
- * This zeroizes the array in a way that is guaranteed to not be optimized out by the compiler.
- * If supported by the architecture, it zeroizes the data not just in the L1 data cache but also
- * in other levels of the memory hierarchy up to and including main memory (but not above that).
- * <p>
- * This works on any <code>byte[]</code>, but to ensure that copies of the array aren't left on
- * the Java heap the array should have been allocated with {@link #newNonMovableByteArray(int)}.
- * Use on other arrays might also introduce performance anomalies.
- *
- * @param array the array to zeroize
- */
- public static native void zeroize(byte[] array);
-
- /**
- * Like {@link #zeroize(byte[])}, but for char arrays.
- */
- public static native void zeroize(char[] array);
-
- /**
* Checks if the beginnings of two byte arrays are equal.
*
* @param array1 the first byte array
diff --git a/core/jni/Android.bp b/core/jni/Android.bp
index 0ffe2f9e6f2b..e22d9587093b 100644
--- a/core/jni/Android.bp
+++ b/core/jni/Android.bp
@@ -92,7 +92,6 @@ cc_library_shared_for_libandroid_runtime {
"android_view_VelocityTracker.cpp",
"android_view_VerifiedKeyEvent.cpp",
"android_view_VerifiedMotionEvent.cpp",
- "com_android_internal_util_ArrayUtils.cpp",
"com_android_internal_util_VirtualRefBasePtr.cpp",
"core_jni_helpers.cpp",
":deviceproductinfoconstants_aidl",
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index 78d69f0714e0..ac187b08f0f1 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -220,7 +220,6 @@ extern int register_com_android_internal_os_Zygote(JNIEnv *env);
extern int register_com_android_internal_os_ZygoteCommandBuffer(JNIEnv *env);
extern int register_com_android_internal_os_ZygoteInit(JNIEnv *env);
extern int register_com_android_internal_security_VerityUtils(JNIEnv* env);
-extern int register_com_android_internal_util_ArrayUtils(JNIEnv* env);
extern int register_com_android_internal_util_VirtualRefBasePtr(JNIEnv *env);
extern int register_android_window_WindowInfosListener(JNIEnv* env);
extern int register_android_window_ScreenCapture(JNIEnv* env);
@@ -1622,7 +1621,6 @@ static const RegJNIRec gRegJNI[] = {
REG_JNI(register_com_android_internal_os_ZygoteCommandBuffer),
REG_JNI(register_com_android_internal_os_ZygoteInit),
REG_JNI(register_com_android_internal_security_VerityUtils),
- REG_JNI(register_com_android_internal_util_ArrayUtils),
REG_JNI(register_com_android_internal_util_VirtualRefBasePtr),
REG_JNI(register_android_hardware_Camera),
REG_JNI(register_android_hardware_camera2_CameraMetadata),
diff --git a/core/jni/com_android_internal_util_ArrayUtils.cpp b/core/jni/com_android_internal_util_ArrayUtils.cpp
deleted file mode 100644
index c69e6c903ee5..000000000000
--- a/core/jni/com_android_internal_util_ArrayUtils.cpp
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "ArrayUtils"
-
-#include <android-base/logging.h>
-#include <jni.h>
-#include <nativehelper/JNIHelp.h>
-#include <string.h>
-#include <unistd.h>
-#include <utils/Log.h>
-
-namespace android {
-
-static size_t GetCacheLineSize() {
- long size = sysconf(_SC_LEVEL1_DCACHE_LINESIZE);
- if (size <= 0) {
- ALOGE("Unable to determine L1 data cache line size. Assuming 32 bytes");
- return 32;
- }
- return size;
-}
-
-#ifdef __aarch64__
-static void CleanDataCache(const uint8_t* p, size_t size, size_t cache_line_size) {
- // Execute 'dc cvac' at least once on each cache line in the memory region.
- //
- // 'dc cvac' stands for "Data Cache line Clean by Virtual Address to point-of-Coherency".
- // It writes the cache line back to the "point-of-coherency", i.e. main memory.
- //
- // Since the memory region is not guaranteed to be cache-line-aligned, we use an "extra"
- // instruction after the loop to make sure the last cache line gets covered.
- for (size_t i = 0; i < size; i += cache_line_size) {
- asm volatile("dc cvac, %0" ::"r"(p + i));
- }
- asm volatile("dc cvac, %0" ::"r"(p + size - 1));
-}
-#elif defined(__i386__) || defined(__x86_64__)
-static void CleanDataCache(const uint8_t* p, size_t size, size_t cache_line_size) {
- for (size_t i = 0; i < size; i += cache_line_size) {
- asm volatile("clflush (%0)" ::"r"(p + i));
- }
- asm volatile("clflush (%0)" ::"r"(p + size - 1));
-}
-#elif defined(__riscv)
-static void CleanDataCache(const uint8_t* p, size_t size, size_t cache_line_size) {
- // This should eventually work, but it is not ready to be enabled yet:
- // 1.) The Android emulator needs to add support for zicbom.
- // 2.) Kernel needs to enable zicbom in usermode.
- // 3.) Android clang needs to add zicbom to the target.
-#if 0
- for (size_t i = 0; i < size; i += cache_line_size) {
- asm volatile("cbo.clean (%0)" ::"r"(p + i));
- }
- asm volatile("cbo.clean (%0)" ::"r"(p + size - 1));
-#endif
-}
-#elif defined(__arm__)
-// arm32 has a cacheflush() syscall, but it is undocumented and only flushes the icache.
-// It is not the same as cacheflush(2) as documented in the Linux man-pages project.
-static void CleanDataCache(const uint8_t* p, size_t size, size_t cache_line_size) {}
-#else
-#error "Unknown architecture"
-#endif
-
-static void ZeroizePrimitiveArray(JNIEnv* env, jclass clazz, jarray array, size_t component_len) {
- static const size_t cache_line_size = GetCacheLineSize();
-
- size_t size = env->GetArrayLength(array) * component_len;
- if (size == 0) {
- return;
- }
-
- // ART guarantees that GetPrimitiveArrayCritical never copies.
- jboolean isCopy;
- void* elems = env->GetPrimitiveArrayCritical(array, &isCopy);
- CHECK(!isCopy);
-
-#ifdef __BIONIC__
- memset_explicit(elems, 0, size);
-#else
- memset(elems, 0, size);
-#endif
- // Clean the data cache so that the data gets zeroized in main memory right away. Without this,
- // it might not be written to main memory until the cache line happens to be evicted.
- CleanDataCache(static_cast<const uint8_t*>(elems), size, cache_line_size);
-
- env->ReleasePrimitiveArrayCritical(array, elems, /* mode= */ 0);
-}
-
-static void ZeroizeByteArray(JNIEnv* env, jclass clazz, jbyteArray array) {
- ZeroizePrimitiveArray(env, clazz, array, sizeof(jbyte));
-}
-
-static void ZeroizeCharArray(JNIEnv* env, jclass clazz, jcharArray array) {
- ZeroizePrimitiveArray(env, clazz, array, sizeof(jchar));
-}
-
-static const JNINativeMethod sMethods[] = {
- {"zeroize", "([B)V", (void*)ZeroizeByteArray},
- {"zeroize", "([C)V", (void*)ZeroizeCharArray},
-};
-
-int register_com_android_internal_util_ArrayUtils(JNIEnv* env) {
- return jniRegisterNativeMethods(env, "com/android/internal/util/ArrayUtils", sMethods,
- NELEM(sMethods));
-}
-
-} // namespace android
diff --git a/core/tests/utiltests/src/com/android/internal/util/ArrayUtilsTest.java b/core/tests/utiltests/src/com/android/internal/util/ArrayUtilsTest.java
index 3c264f15abd3..3b9f35b1eb68 100644
--- a/core/tests/utiltests/src/com/android/internal/util/ArrayUtilsTest.java
+++ b/core/tests/utiltests/src/com/android/internal/util/ArrayUtilsTest.java
@@ -496,51 +496,4 @@ public class ArrayUtilsTest {
// expected
}
}
-
- // Note: the zeroize() tests only test the behavior that can be tested from a Java test.
- // They do not verify that no copy of the data is left anywhere.
-
- @Test
- @SmallTest
- public void testZeroizeNonMovableByteArray() {
- final int length = 10;
- byte[] array = ArrayUtils.newNonMovableByteArray(length);
- assertArrayEquals(array, new byte[length]);
- Arrays.fill(array, (byte) 0xff);
- ArrayUtils.zeroize(array);
- assertArrayEquals(array, new byte[length]);
- }
-
- @Test
- @SmallTest
- public void testZeroizeRegularByteArray() {
- final int length = 10;
- byte[] array = new byte[length];
- assertArrayEquals(array, new byte[length]);
- Arrays.fill(array, (byte) 0xff);
- ArrayUtils.zeroize(array);
- assertArrayEquals(array, new byte[length]);
- }
-
- @Test
- @SmallTest
- public void testZeroizeNonMovableCharArray() {
- final int length = 10;
- char[] array = ArrayUtils.newNonMovableCharArray(length);
- assertArrayEquals(array, new char[length]);
- Arrays.fill(array, (char) 0xff);
- ArrayUtils.zeroize(array);
- assertArrayEquals(array, new char[length]);
- }
-
- @Test
- @SmallTest
- public void testZeroizeRegularCharArray() {
- final int length = 10;
- char[] array = new char[length];
- assertArrayEquals(array, new char[length]);
- Arrays.fill(array, (char) 0xff);
- ArrayUtils.zeroize(array);
- assertArrayEquals(array, new char[length]);
- }
}