Merge "Add CTS for requestModemActivityInfo"
diff --git a/tests/tests/keystore/Android.bp b/tests/tests/keystore/Android.bp
index b464826..dc2ec67 100644
--- a/tests/tests/keystore/Android.bp
+++ b/tests/tests/keystore/Android.bp
@@ -33,6 +33,21 @@
     platform_apis: true,
 }
 
+java_library {
+    name: "cts-keystore-test-util",
+
+    srcs: ["src/android/keystore/cts/util/**/*.java"],
+
+    libs: [
+        "android.test.base",
+        "android.test.runner",
+        "androidx.test.rules",
+        "junit",
+    ],
+
+    platform_apis: true,
+}
+
 android_test {
     name: "CtsKeystoreTestCases",
     defaults: ["cts_defaults"],
@@ -50,6 +65,7 @@
         "androidx.test.rules",
         "compatibility-device-util-axt",
         "core-tests-support",
+        "cts-keystore-test-util",
         "cts-keystore-user-auth-helper-library",
         "cts-security-test-support-library",
         "cts-wm-util",
@@ -60,7 +76,7 @@
         "platformprotosnano",
         "testng",
     ],
-    srcs: ["src/android/keystore/**/*.java"],
+    srcs: ["src/android/keystore/cts/**/*.java"],
     // Can't use public/test API only because some tests use hidden API
     // (e.g. device-provided Bouncy Castle).
     //
@@ -71,3 +87,33 @@
     // sdk_version: "current"
     platform_apis: true,
 }
+
+android_test {
+    name: "CtsKeystorePerformanceTestCases",
+    defaults: ["cts_defaults"],
+    manifest: "CtsKeystorePerformanceTestManifest.xml",
+    test_config: "CtsKeystorePerformanceTestConfig.xml",
+    // Tag this module as a cts test artifact
+    test_suites: [
+        "cts",
+        "general-tests",
+    ],
+    libs: [
+        "android.test.base",
+        "android.test.runner",
+    ],
+    static_libs: [
+        "androidx.test.rules",
+        "compatibility-device-util-axt",
+        "core-tests-support",
+        "cts-keystore-test-util",
+        "ctstestrunner-axt",
+        "junit",
+        "platformprotosnano",
+    ],
+    srcs: [
+        "src/android/keystore/cts/performance/**/*.java",
+    ],
+    // sdk_version: "test_current",
+    platform_apis: true,
+}
diff --git a/tests/tests/keystore/CtsKeystorePerformanceTestConfig.xml b/tests/tests/keystore/CtsKeystorePerformanceTestConfig.xml
new file mode 100644
index 0000000..8e15dcd
--- /dev/null
+++ b/tests/tests/keystore/CtsKeystorePerformanceTestConfig.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 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.
+-->
+<configuration description="Config for CTS Keystore performance tests">
+    <option name="test-suite-tag" value="cts" />
+    <option name="config-descriptor:metadata" key="component" value="security" />
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
+    <option name="config-descriptor:metadata" key="parameter" value="secondary_user" />
+    <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsKeystorePerformanceTestCases.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.keystore.cts.performance" />
+        <option name="runtime-hint" value="17m" />
+        <option name="test-timeout" value="34m" />
+        <option name="hidden-api-checks" value="false" />
+        <option name="isolated-storage" value="false" />
+    </test>
+</configuration>
diff --git a/tests/tests/keystore/CtsKeystorePerformanceTestManifest.xml b/tests/tests/keystore/CtsKeystorePerformanceTestManifest.xml
new file mode 100644
index 0000000..f7d7bd6
--- /dev/null
+++ b/tests/tests/keystore/CtsKeystorePerformanceTestManifest.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright 2013 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.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="android.keystore.cts.performance">
+
+    <application>
+        <uses-library android:name="android.test.runner" />
+    </application>
+
+    <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
+                     android:targetPackage="android.keystore.cts.performance"
+                     android:label="CTS tests of android.keystore.cts.performance">
+        <meta-data android:name="listener"
+            android:value="com.android.cts.runner.CtsTestRunListener" />
+    </instrumentation>
+
+</manifest>
+
diff --git a/tests/tests/keystore/TEST_MAPPING b/tests/tests/keystore/TEST_MAPPING
index 0511967..08d89dc 100644
--- a/tests/tests/keystore/TEST_MAPPING
+++ b/tests/tests/keystore/TEST_MAPPING
@@ -10,15 +10,6 @@
           "exclude-filter": "android.keystore.cts.SignatureTest"
         },
         {
-          "exclude-filter": "android.keystore.cts.RsaSignaturePerformanceTest"
-        },
-        {
-          "exclude-filter": "android.keystore.cts.RsaKeyGenPerformanceTest"
-        },
-        {
-          "exclude-filter": "android.keystore.cts.RsaCipherPerformanceTest"
-        },
-        {
           "exclude-filter": "android.keystore.cts.MacTest#testLargeMsgKat"
         },
         {
@@ -28,30 +19,12 @@
           "exclude-filter": "android.keystore.cts.KeyGeneratorTest#testHmacKeySupportedSizes"
         },
         {
-          "exclude-filter": "android.keystore.cts.HmacMacPerformanceTest"
-        },
-        {
-          "exclude-filter": "android.keystore.cts.EcdsaSignaturePerformanceTest"
-        },
-        {
-          "exclude-filter": "android.keystore.cts.EcKeyGenPerformanceTest"
-        },
-        {
-          "exclude-filter": "android.keystore.cts.DesCipherPerformanceTest"
-        },
-        {
           "exclude-filter": "android.keystore.cts.CipherTest"
         },
         {
-          "exclude-filter": "android.keystore.cts.AttestationPerformanceTest"
-        },
-        {
           "exclude-filter": "android.keystore.cts.AndroidKeyStoreTest"
         },
         {
-          "exclude-filter": "android.keystore.cts.AesCipherPerformanceTest"
-        },
-        {
           "exclude-filter": "android.keystore.cts.AESCipherNistCavpKatTest"
         },
         {
@@ -69,6 +42,9 @@
   "postsubmit": [
     {
       "name": "CtsKeystoreTestCases"
+    },
+    {
+      "name": "CtsKeystorePerformanceTestCases"
     }
   ]
 }
diff --git a/tests/tests/keystore/src/android/keystore/cts/AES128CBCNoPaddingCipherTest.java b/tests/tests/keystore/src/android/keystore/cts/AES128CBCNoPaddingCipherTest.java
index e56049c..cbd6a4f 100644
--- a/tests/tests/keystore/src/android/keystore/cts/AES128CBCNoPaddingCipherTest.java
+++ b/tests/tests/keystore/src/android/keystore/cts/AES128CBCNoPaddingCipherTest.java
@@ -46,4 +46,7 @@
     protected byte[] getKatCiphertext() {
         return KAT_CIPHERTEXT.clone();
     }
+
+    @Override
+    protected boolean isStrongbox() { return false; }
 }
diff --git a/tests/tests/keystore/src/android/keystore/cts/AES128CBCPKCS7PaddingCipherTest.java b/tests/tests/keystore/src/android/keystore/cts/AES128CBCPKCS7PaddingCipherTest.java
index d8254c1..4953fde 100644
--- a/tests/tests/keystore/src/android/keystore/cts/AES128CBCPKCS7PaddingCipherTest.java
+++ b/tests/tests/keystore/src/android/keystore/cts/AES128CBCPKCS7PaddingCipherTest.java
@@ -46,4 +46,7 @@
     protected byte[] getKatCiphertext() {
         return KAT_CIPHERTEXT.clone();
     }
+
+    @Override
+    protected boolean isStrongbox() { return false; }
 }
diff --git a/tests/tests/keystore/src/android/keystore/cts/AES128CTRNoPaddingCipherTest.java b/tests/tests/keystore/src/android/keystore/cts/AES128CTRNoPaddingCipherTest.java
index 7ffca13..23600f0 100644
--- a/tests/tests/keystore/src/android/keystore/cts/AES128CTRNoPaddingCipherTest.java
+++ b/tests/tests/keystore/src/android/keystore/cts/AES128CTRNoPaddingCipherTest.java
@@ -22,10 +22,10 @@
     private static final byte[] KAT_IV = HexEncoding.decode("ebfa19b0ebf3d57feabd4c4bd04bea01");
     private static final byte[] KAT_PLAINTEXT = HexEncoding.decode(
             "6d2c07e1fc86f99c6e2a8f6567828b4262a9c23d0f3ed8ab32482283c79796f0adba1bcd3736084996452a"
-            +"917fae98005aebe61f9e91c3");
+                    + "917fae98005aebe61f9e91c3");
     private static final byte[] KAT_CIPHERTEXT = HexEncoding.decode(
             "345deb1d67b95e600e05cad4c32ec381aadb3e2c1ec7e0fb956dc38e6860cf0553535566e1b12fa9f87d29"
-            + "266ca26df427233df035df28");
+                    + "266ca26df427233df035df28");
 
     @Override
     protected byte[] getKatKey() {
@@ -46,4 +46,7 @@
     protected byte[] getKatCiphertext() {
         return KAT_CIPHERTEXT.clone();
     }
+
+    @Override
+    protected boolean isStrongbox() { return false; }
 }
diff --git a/tests/tests/keystore/src/android/keystore/cts/AES128ECBNoPaddingCipherTest.java b/tests/tests/keystore/src/android/keystore/cts/AES128ECBNoPaddingCipherTest.java
index 100700c..5ed2ab3 100644
--- a/tests/tests/keystore/src/android/keystore/cts/AES128ECBNoPaddingCipherTest.java
+++ b/tests/tests/keystore/src/android/keystore/cts/AES128ECBNoPaddingCipherTest.java
@@ -45,4 +45,7 @@
     protected byte[] getKatCiphertext() {
         return KAT_CIPHERTEXT.clone();
     }
+
+    @Override
+    protected boolean isStrongbox() { return false; }
 }
diff --git a/tests/tests/keystore/src/android/keystore/cts/AES128ECBPKCS7PaddingCipherTest.java b/tests/tests/keystore/src/android/keystore/cts/AES128ECBPKCS7PaddingCipherTest.java
index c834ddf..61b7f0b 100644
--- a/tests/tests/keystore/src/android/keystore/cts/AES128ECBPKCS7PaddingCipherTest.java
+++ b/tests/tests/keystore/src/android/keystore/cts/AES128ECBPKCS7PaddingCipherTest.java
@@ -45,4 +45,7 @@
     protected byte[] getKatCiphertext() {
         return KAT_CIPHERTEXT.clone();
     }
+
+    @Override
+    protected boolean isStrongbox() { return false; }
 }
diff --git a/tests/tests/keystore/src/android/keystore/cts/AES128GCMNoPaddingCipherTest.java b/tests/tests/keystore/src/android/keystore/cts/AES128GCMNoPaddingCipherTest.java
index ed9c2b1..8c180a3 100644
--- a/tests/tests/keystore/src/android/keystore/cts/AES128GCMNoPaddingCipherTest.java
+++ b/tests/tests/keystore/src/android/keystore/cts/AES128GCMNoPaddingCipherTest.java
@@ -61,4 +61,7 @@
     protected byte[] getKatCiphertextWhenKatAadPresent() {
         return KAT_CIPHERTEXT_WITH_AAD.clone();
     }
+
+    @Override
+    protected boolean isStrongbox() { return false; }
 }
diff --git a/tests/tests/keystore/src/android/keystore/cts/AES192CBCNoPaddingCipherTest.java b/tests/tests/keystore/src/android/keystore/cts/AES192CBCNoPaddingCipherTest.java
index f49c7c3..5af8fba 100644
--- a/tests/tests/keystore/src/android/keystore/cts/AES192CBCNoPaddingCipherTest.java
+++ b/tests/tests/keystore/src/android/keystore/cts/AES192CBCNoPaddingCipherTest.java
@@ -47,4 +47,7 @@
     protected byte[] getKatCiphertext() {
         return KAT_CIPHERTEXT.clone();
     }
+
+    @Override
+    protected boolean isStrongbox() { return false; }
 }
diff --git a/tests/tests/keystore/src/android/keystore/cts/AES192CBCPKCS7PaddingCipherTest.java b/tests/tests/keystore/src/android/keystore/cts/AES192CBCPKCS7PaddingCipherTest.java
index b17befc..005808b 100644
--- a/tests/tests/keystore/src/android/keystore/cts/AES192CBCPKCS7PaddingCipherTest.java
+++ b/tests/tests/keystore/src/android/keystore/cts/AES192CBCPKCS7PaddingCipherTest.java
@@ -46,4 +46,7 @@
     protected byte[] getKatCiphertext() {
         return KAT_CIPHERTEXT.clone();
     }
+
+    @Override
+    protected boolean isStrongbox() { return false; }
 }
diff --git a/tests/tests/keystore/src/android/keystore/cts/AES192CTRNoPaddingCipherTest.java b/tests/tests/keystore/src/android/keystore/cts/AES192CTRNoPaddingCipherTest.java
index d4a4143..f2a8d11 100644
--- a/tests/tests/keystore/src/android/keystore/cts/AES192CTRNoPaddingCipherTest.java
+++ b/tests/tests/keystore/src/android/keystore/cts/AES192CTRNoPaddingCipherTest.java
@@ -45,4 +45,7 @@
     protected byte[] getKatCiphertext() {
         return KAT_CIPHERTEXT.clone();
     }
+
+    @Override
+    protected boolean isStrongbox() { return false; }
 }
diff --git a/tests/tests/keystore/src/android/keystore/cts/AES192ECBNoPaddingCipherTest.java b/tests/tests/keystore/src/android/keystore/cts/AES192ECBNoPaddingCipherTest.java
index 0557d03..bdd6f87 100644
--- a/tests/tests/keystore/src/android/keystore/cts/AES192ECBNoPaddingCipherTest.java
+++ b/tests/tests/keystore/src/android/keystore/cts/AES192ECBNoPaddingCipherTest.java
@@ -44,4 +44,7 @@
     protected byte[] getKatCiphertext() {
         return KAT_CIPHERTEXT.clone();
     }
+
+    @Override
+    protected boolean isStrongbox() { return false; }
 }
diff --git a/tests/tests/keystore/src/android/keystore/cts/AES192ECBPKCS7PaddingCipherTest.java b/tests/tests/keystore/src/android/keystore/cts/AES192ECBPKCS7PaddingCipherTest.java
index 1cf193c..ad7f9d8 100644
--- a/tests/tests/keystore/src/android/keystore/cts/AES192ECBPKCS7PaddingCipherTest.java
+++ b/tests/tests/keystore/src/android/keystore/cts/AES192ECBPKCS7PaddingCipherTest.java
@@ -45,4 +45,7 @@
     protected byte[] getKatCiphertext() {
         return KAT_CIPHERTEXT.clone();
     }
+
+    @Override
+    protected boolean isStrongbox() { return false; }
 }
diff --git a/tests/tests/keystore/src/android/keystore/cts/AES192GCMNoPaddingCipherTest.java b/tests/tests/keystore/src/android/keystore/cts/AES192GCMNoPaddingCipherTest.java
index 66b37d3..72844ed 100644
--- a/tests/tests/keystore/src/android/keystore/cts/AES192GCMNoPaddingCipherTest.java
+++ b/tests/tests/keystore/src/android/keystore/cts/AES192GCMNoPaddingCipherTest.java
@@ -61,4 +61,7 @@
     protected byte[] getKatCiphertextWhenKatAadPresent() {
         return KAT_CIPHERTEXT_WITH_AAD.clone();
     }
+
+    @Override
+    protected boolean isStrongbox() { return false; }
 }
diff --git a/tests/tests/keystore/src/android/keystore/cts/AES256CBCNoPaddingCipherTest.java b/tests/tests/keystore/src/android/keystore/cts/AES256CBCNoPaddingCipherTest.java
index b6620ef..828d61b 100644
--- a/tests/tests/keystore/src/android/keystore/cts/AES256CBCNoPaddingCipherTest.java
+++ b/tests/tests/keystore/src/android/keystore/cts/AES256CBCNoPaddingCipherTest.java
@@ -47,4 +47,7 @@
     protected byte[] getKatCiphertext() {
         return KAT_CIPHERTEXT.clone();
     }
+
+    @Override
+    protected boolean isStrongbox() { return false; }
 }
diff --git a/tests/tests/keystore/src/android/keystore/cts/AES256CBCPKCS7PaddingCipherTest.java b/tests/tests/keystore/src/android/keystore/cts/AES256CBCPKCS7PaddingCipherTest.java
index 6613463..5785c38 100644
--- a/tests/tests/keystore/src/android/keystore/cts/AES256CBCPKCS7PaddingCipherTest.java
+++ b/tests/tests/keystore/src/android/keystore/cts/AES256CBCPKCS7PaddingCipherTest.java
@@ -47,4 +47,7 @@
     protected byte[] getKatCiphertext() {
         return KAT_CIPHERTEXT.clone();
     }
+
+    @Override
+    protected boolean isStrongbox() { return false; }
 }
diff --git a/tests/tests/keystore/src/android/keystore/cts/AES256CTRNoPaddingCipherTest.java b/tests/tests/keystore/src/android/keystore/cts/AES256CTRNoPaddingCipherTest.java
index bdcff41..492991f 100644
--- a/tests/tests/keystore/src/android/keystore/cts/AES256CTRNoPaddingCipherTest.java
+++ b/tests/tests/keystore/src/android/keystore/cts/AES256CTRNoPaddingCipherTest.java
@@ -45,4 +45,7 @@
     protected byte[] getKatCiphertext() {
         return KAT_CIPHERTEXT.clone();
     }
+
+    @Override
+    protected boolean isStrongbox() { return false; }
 }
diff --git a/tests/tests/keystore/src/android/keystore/cts/AES256ECBNoPaddingCipherTest.java b/tests/tests/keystore/src/android/keystore/cts/AES256ECBNoPaddingCipherTest.java
index 847a767..e56d578 100644
--- a/tests/tests/keystore/src/android/keystore/cts/AES256ECBNoPaddingCipherTest.java
+++ b/tests/tests/keystore/src/android/keystore/cts/AES256ECBNoPaddingCipherTest.java
@@ -46,4 +46,7 @@
     protected byte[] getKatCiphertext() {
         return KAT_CIPHERTEXT.clone();
     }
+
+    @Override
+    protected boolean isStrongbox() { return false; }
 }
diff --git a/tests/tests/keystore/src/android/keystore/cts/AES256ECBPKCS7PaddingCipherTest.java b/tests/tests/keystore/src/android/keystore/cts/AES256ECBPKCS7PaddingCipherTest.java
index 0faffe9..e9324e5 100644
--- a/tests/tests/keystore/src/android/keystore/cts/AES256ECBPKCS7PaddingCipherTest.java
+++ b/tests/tests/keystore/src/android/keystore/cts/AES256ECBPKCS7PaddingCipherTest.java
@@ -45,4 +45,7 @@
     protected byte[] getKatCiphertext() {
         return KAT_CIPHERTEXT.clone();
     }
+
+    @Override
+    protected boolean isStrongbox() { return false; }
 }
diff --git a/tests/tests/keystore/src/android/keystore/cts/AES256GCMNoPaddingCipherTest.java b/tests/tests/keystore/src/android/keystore/cts/AES256GCMNoPaddingCipherTest.java
index 971e610..2bdfd07 100644
--- a/tests/tests/keystore/src/android/keystore/cts/AES256GCMNoPaddingCipherTest.java
+++ b/tests/tests/keystore/src/android/keystore/cts/AES256GCMNoPaddingCipherTest.java
@@ -62,4 +62,7 @@
     protected byte[] getKatCiphertextWhenKatAadPresent() {
         return KAT_CIPHERTEXT_WITH_AAD.clone();
     }
+
+    @Override
+    protected boolean isStrongbox() { return false; }
 }
diff --git a/tests/tests/keystore/src/android/keystore/cts/AndroidKeyStoreTest.java b/tests/tests/keystore/src/android/keystore/cts/AndroidKeyStoreTest.java
index 4065113..cf6aa83 100644
--- a/tests/tests/keystore/src/android/keystore/cts/AndroidKeyStoreTest.java
+++ b/tests/tests/keystore/src/android/keystore/cts/AndroidKeyStoreTest.java
@@ -17,6 +17,7 @@
 package android.keystore.cts;
 
 import android.content.pm.PackageManager;
+import android.keystore.cts.util.TestUtils;
 import android.security.KeyPairGeneratorSpec;
 import android.security.keystore.KeyProperties;
 import android.security.keystore.KeyProtection;
diff --git a/tests/tests/keystore/src/android/keystore/cts/AttestKeyTest.java b/tests/tests/keystore/src/android/keystore/cts/AttestKeyTest.java
index d5d12f3..0f064b6 100644
--- a/tests/tests/keystore/src/android/keystore/cts/AttestKeyTest.java
+++ b/tests/tests/keystore/src/android/keystore/cts/AttestKeyTest.java
@@ -24,11 +24,11 @@
 import static org.hamcrest.CoreMatchers.is;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.greaterThan;
-import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 import static org.junit.Assume.assumeTrue;
 
 import android.content.pm.PackageManager;
+import android.keystore.cts.util.TestUtils;
 import android.security.keystore.KeyGenParameterSpec;
 import android.util.Log;
 
@@ -51,8 +51,6 @@
 import java.util.Arrays;
 import java.util.stream.Stream;
 
-import javax.security.auth.x500.X500Principal;
-
 public class AttestKeyTest {
     private static final String TAG = AttestKeyTest.class.getSimpleName();
 
@@ -145,7 +143,7 @@
 
     @Test
     public void testAttestKeySecurityLevelMismatch() throws Exception {
-        assumeStrongBox();
+        TestUtils.assumeStrongBox();
 
         final String strongBoxAttestKeyAlias = "nonAttestKey";
         final String attestedKeyAlias = "attestedKey";
@@ -167,13 +165,6 @@
         }
     }
 
-    private void assumeStrongBox() {
-        PackageManager packageManager =
-                InstrumentationRegistry.getInstrumentation().getTargetContext().getPackageManager();
-        assumeTrue("Can only test if we have StrongBox",
-                packageManager.hasSystemFeature(PackageManager.FEATURE_STRONGBOX_KEYSTORE));
-    }
-
     private void assumeAttestKey() {
         PackageManager packageManager =
                 InstrumentationRegistry.getInstrumentation().getTargetContext().getPackageManager();
diff --git a/tests/tests/keystore/src/android/keystore/cts/BlockCipherTestBase.java b/tests/tests/keystore/src/android/keystore/cts/BlockCipherTestBase.java
index 37a29ad..ccbadf9 100644
--- a/tests/tests/keystore/src/android/keystore/cts/BlockCipherTestBase.java
+++ b/tests/tests/keystore/src/android/keystore/cts/BlockCipherTestBase.java
@@ -16,6 +16,8 @@
 
 package android.keystore.cts;
 
+import android.keystore.cts.util.EmptyArray;
+import android.keystore.cts.util.TestUtils;
 import android.security.keystore.KeyProperties;
 import android.security.keystore.KeyProtection;
 import android.test.AndroidTestCase;
@@ -60,6 +62,10 @@
 
     @Override
     protected void setUp() throws Exception {
+        if (isStrongbox()) {
+            TestUtils.assumeStrongBox();
+        }
+
         super.setUp();
         mAndroidKeyStore = KeyStore.getInstance("AndroidKeyStore");
         mAndroidKeyStore.load(null);
@@ -94,6 +100,8 @@
     protected abstract byte[] getIv(AlgorithmParameters params)
             throws InvalidParameterSpecException;
 
+    protected abstract boolean isStrongbox();
+
     private byte[] getKatInput(int opmode) {
         switch (opmode) {
             case Cipher.ENCRYPT_MODE:
@@ -544,13 +552,19 @@
         SecretKey key2 = importKey(katKeyBytes);
 
         init(opmode, key2, getKatAlgorithmParameterSpec());
-        byte[] output2;
+        byte[] output2 = null;
         try {
             output2 = doFinal(input);
         } catch (BadPaddingException expected) {
             // Padding doesn't decode probably because the new key is being used. This can only
             // occur if padding is used.
             return;
+        } catch (IllegalBlockSizeException notExpected) {
+            if (isStrongbox()) {
+                fail("Should throw BadPaddingException (b/194126736)");
+            } else {
+                throw notExpected;
+            }
         }
 
         // Either padding wasn't used or the old key was used.
@@ -662,7 +676,15 @@
 
         // Complete the current block. There are blockSize - 4 bytes left to fill.
         byte[] output = update(new byte[getBlockSize() - 4]);
-        assertEquals(getBlockSize(), output.length);
+
+        try {
+            assertEquals(getBlockSize(), output.length);
+        } catch (NullPointerException e) {
+            if (isStrongbox() && output == null) {
+                fail("b/194134359");
+            }
+            throw e;
+        }
 
         assertEquals(null, update(new byte[1]));
         assertEquals(null, update(new byte[1], 0, 1));
@@ -746,9 +768,13 @@
             for (int plaintextIndex = 0; plaintextIndex < plaintext.length; plaintextIndex++) {
                 byte[] output = update(new byte[] {plaintext[plaintextIndex]});
                 if ((plaintextIndex % blockSize) == blockSize - 1) {
+                    String additionalInformation = "";
+                    if (isStrongbox() && output == null) {
+                        additionalInformation = " (b/194134359)";
+                    }
                     // Cipher.update is expected to have output a new block
                     assertEquals(
-                            "plaintext index: " + plaintextIndex,
+                            "plaintext index: " + plaintextIndex + additionalInformation,
                             subarray(
                                     expectedCiphertext,
                                     ciphertextIndex,
@@ -811,8 +837,12 @@
                         || ((!paddingEnabled) && ((ciphertextIndex % blockSize) == blockSize - 1));
 
                 if (outputExpected) {
+                    String additionalInformation = "";
+                    if (isStrongbox()) {
+                        additionalInformation = " (b/194134040)";
+                    }
                     assertEquals(
-                            "ciphertext index: " + ciphertextIndex,
+                            "ciphertext index: " + ciphertextIndex + additionalInformation,
                             subarray(expectedPlaintext, plaintextIndex, plaintextIndex + blockSize),
                             output);
                 } else {
@@ -1054,6 +1084,13 @@
             doFinal(ciphertext);
             fail();
         } catch (BadPaddingException expected) {}
+        catch (IllegalBlockSizeException e) {
+            if (isStrongbox()) {
+                fail("Should throw BadPaddingException (b/194126736)");
+            } else {
+                fail();
+            }
+        }
     }
 
     public void testDecryptWithMissingPadding() throws Exception {
@@ -1069,6 +1106,13 @@
             doFinal(ciphertext);
             fail();
         } catch (BadPaddingException expected) {}
+        catch (IllegalBlockSizeException e) {
+            if (isStrongbox()) {
+                fail("Should throw BadPaddingException (b/194126736)");
+            } else {
+                fail();
+            }
+        }
     }
 
     public void testUpdateCopySafe() throws Exception {
@@ -1151,7 +1195,11 @@
         System.arraycopy(input, 0, buffer, inputOffsetInBuffer, input.length);
         createCipher();
         initKat(opmode);
-        assertEquals(expectedOutput.length,
+        String additionalInformation = "";
+        if (isStrongbox() && opmode == Cipher.ENCRYPT_MODE) {
+            additionalInformation = "May fail due to b/194134359";
+        }
+        assertEquals(additionalInformation, expectedOutput.length,
                 update(buffer, inputOffsetInBuffer, input.length,
                         buffer, outputOffsetInBuffer));
         assertEquals(expectedOutput,
@@ -1322,6 +1370,7 @@
                             .setBlockModes(getBlockMode())
                             .setEncryptionPaddings(getPadding())
                             .setRandomizedEncryptionRequired(false)
+                            .setIsStrongBoxBacked(isStrongbox())
                             .build());
             return (SecretKey) mAndroidKeyStore.getKey(keyAlias, null);
         } catch (Exception e) {
@@ -1439,8 +1488,13 @@
 
         if (isStreamCipher()) {
             if (outputLength != inputLength) {
-                fail("Output of update (" + outputLength + ") not same size as input ("
-                        + inputLength + ")");
+                if (isStrongbox()) {
+                    fail("Output of update (" + outputLength + ") not same size as input ("
+                                + inputLength + ") b/194123581");
+                } else {
+                    fail("Output of update (" + outputLength + ") not same size as input ("
+                            + inputLength + ")");
+                }
             }
         } else {
             if ((outputLength % getBlockSize()) != 0) {
diff --git a/tests/tests/keystore/src/android/keystore/cts/CipherTest.java b/tests/tests/keystore/src/android/keystore/cts/CipherTest.java
index e80af43..b56c7bf 100644
--- a/tests/tests/keystore/src/android/keystore/cts/CipherTest.java
+++ b/tests/tests/keystore/src/android/keystore/cts/CipherTest.java
@@ -19,6 +19,9 @@
 import android.app.KeyguardManager;
 import android.content.Context;
 import android.content.pm.PackageManager;
+import android.keystore.cts.util.EmptyArray;
+import android.keystore.cts.util.ImportedKey;
+import android.keystore.cts.util.TestUtils;
 import android.os.SystemClock;
 import android.platform.test.annotations.Presubmit;
 import android.security.keystore.KeyProperties;
diff --git a/tests/tests/keystore/src/android/keystore/cts/DESedeCBCNoPaddingCipherTest.java b/tests/tests/keystore/src/android/keystore/cts/DESedeCBCNoPaddingCipherTest.java
index 1564a25..e7815ff 100644
--- a/tests/tests/keystore/src/android/keystore/cts/DESedeCBCNoPaddingCipherTest.java
+++ b/tests/tests/keystore/src/android/keystore/cts/DESedeCBCNoPaddingCipherTest.java
@@ -35,4 +35,7 @@
     protected byte[] getKatIv() {
         return KAT_IV.clone();
     }
+
+    @Override
+    protected boolean isStrongbox() { return false; }
 }
diff --git a/tests/tests/keystore/src/android/keystore/cts/DESedeCBCPKCS7PaddingCipherTest.java b/tests/tests/keystore/src/android/keystore/cts/DESedeCBCPKCS7PaddingCipherTest.java
index a0484ed..a311f0e 100644
--- a/tests/tests/keystore/src/android/keystore/cts/DESedeCBCPKCS7PaddingCipherTest.java
+++ b/tests/tests/keystore/src/android/keystore/cts/DESedeCBCPKCS7PaddingCipherTest.java
@@ -35,4 +35,7 @@
     protected byte[] getKatIv() {
         return KAT_IV.clone();
     }
+
+    @Override
+    protected boolean isStrongbox() { return false; }
 }
diff --git a/tests/tests/keystore/src/android/keystore/cts/DESedeCipherTestBase.java b/tests/tests/keystore/src/android/keystore/cts/DESedeCipherTestBase.java
index d3cbd88..cc3bac1 100644
--- a/tests/tests/keystore/src/android/keystore/cts/DESedeCipherTestBase.java
+++ b/tests/tests/keystore/src/android/keystore/cts/DESedeCipherTestBase.java
@@ -1,5 +1,7 @@
 package android.keystore.cts;
 
+import android.keystore.cts.util.TestUtils;
+
 public abstract class DESedeCipherTestBase extends BlockCipherTestBase {
 
     private static final byte[] KAT_KEY = HexEncoding.decode(
diff --git a/tests/tests/keystore/src/android/keystore/cts/DESedeECBNoPaddingCipherTest.java b/tests/tests/keystore/src/android/keystore/cts/DESedeECBNoPaddingCipherTest.java
index 318dc40..38670a4 100644
--- a/tests/tests/keystore/src/android/keystore/cts/DESedeECBNoPaddingCipherTest.java
+++ b/tests/tests/keystore/src/android/keystore/cts/DESedeECBNoPaddingCipherTest.java
@@ -33,4 +33,7 @@
     protected byte[] getKatIv() {
         return null;
     }
+
+    @Override
+    protected boolean isStrongbox() { return false; }
 }
diff --git a/tests/tests/keystore/src/android/keystore/cts/DESedeECBPKCS7PaddingCipherTest.java b/tests/tests/keystore/src/android/keystore/cts/DESedeECBPKCS7PaddingCipherTest.java
index 22579bd..2030b20 100644
--- a/tests/tests/keystore/src/android/keystore/cts/DESedeECBPKCS7PaddingCipherTest.java
+++ b/tests/tests/keystore/src/android/keystore/cts/DESedeECBPKCS7PaddingCipherTest.java
@@ -33,4 +33,7 @@
     protected byte[] getKatIv() {
         return null;
     }
+
+    @Override
+    protected boolean isStrongbox() { return false; }
 }
diff --git a/tests/tests/keystore/src/android/keystore/cts/ECDSASignatureTest.java b/tests/tests/keystore/src/android/keystore/cts/ECDSASignatureTest.java
index de60e37..0b3c067 100644
--- a/tests/tests/keystore/src/android/keystore/cts/ECDSASignatureTest.java
+++ b/tests/tests/keystore/src/android/keystore/cts/ECDSASignatureTest.java
@@ -17,6 +17,8 @@
 package android.keystore.cts;
 
 import android.content.Context;
+import android.keystore.cts.util.ImportedKey;
+import android.keystore.cts.util.TestUtils;
 import android.security.keystore.KeyProtection;
 import android.test.AndroidTestCase;
 
diff --git a/tests/tests/keystore/src/android/keystore/cts/ImportWrappedKeyTest.java b/tests/tests/keystore/src/android/keystore/cts/ImportWrappedKeyTest.java
index e967438..b30b3d2 100644
--- a/tests/tests/keystore/src/android/keystore/cts/ImportWrappedKeyTest.java
+++ b/tests/tests/keystore/src/android/keystore/cts/ImportWrappedKeyTest.java
@@ -28,6 +28,7 @@
 import static android.security.keystore.KeyProperties.PURPOSE_WRAP_KEY;
 
 import android.content.pm.PackageManager;
+import android.keystore.cts.util.TestUtils;
 import android.os.SystemProperties;
 import android.security.keystore.KeyGenParameterSpec;
 import android.security.keystore.KeyProperties;
diff --git a/tests/tests/keystore/src/android/keystore/cts/KeyAgreementTest.java b/tests/tests/keystore/src/android/keystore/cts/KeyAgreementTest.java
index c8d0eae..1c84c6e 100644
--- a/tests/tests/keystore/src/android/keystore/cts/KeyAgreementTest.java
+++ b/tests/tests/keystore/src/android/keystore/cts/KeyAgreementTest.java
@@ -32,6 +32,7 @@
 import org.junit.Assert;
 
 import android.content.Context;
+import android.keystore.cts.util.TestUtils;
 import android.security.keystore.KeyGenParameterSpec;
 import android.security.keystore.KeyProperties;
 import android.security.keystore.KeyInfo;
diff --git a/tests/tests/keystore/src/android/keystore/cts/KeyAttestationTest.java b/tests/tests/keystore/src/android/keystore/cts/KeyAttestationTest.java
index f06f67e..e0216c8 100644
--- a/tests/tests/keystore/src/android/keystore/cts/KeyAttestationTest.java
+++ b/tests/tests/keystore/src/android/keystore/cts/KeyAttestationTest.java
@@ -58,6 +58,7 @@
 
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
+import android.keystore.cts.util.TestUtils;
 import android.os.Build;
 import android.os.SystemProperties;
 import android.platform.test.annotations.RestrictedBuildTest;
diff --git a/tests/tests/keystore/src/android/keystore/cts/KeyFactoryTest.java b/tests/tests/keystore/src/android/keystore/cts/KeyFactoryTest.java
index fb853c9..d318e24 100644
--- a/tests/tests/keystore/src/android/keystore/cts/KeyFactoryTest.java
+++ b/tests/tests/keystore/src/android/keystore/cts/KeyFactoryTest.java
@@ -16,6 +16,7 @@
 
 package android.keystore.cts;
 
+import android.keystore.cts.util.TestUtils;
 import android.security.keystore.KeyGenParameterSpec;
 import android.security.keystore.KeyInfo;
 import android.security.keystore.KeyProperties;
diff --git a/tests/tests/keystore/src/android/keystore/cts/KeyGeneratorTest.java b/tests/tests/keystore/src/android/keystore/cts/KeyGeneratorTest.java
index 6d9b33a..e213cde 100644
--- a/tests/tests/keystore/src/android/keystore/cts/KeyGeneratorTest.java
+++ b/tests/tests/keystore/src/android/keystore/cts/KeyGeneratorTest.java
@@ -16,6 +16,7 @@
 
 package android.keystore.cts;
 
+import android.keystore.cts.util.TestUtils;
 import android.security.keystore.KeyGenParameterSpec;
 import android.security.keystore.KeyInfo;
 import android.security.keystore.KeyProperties;
diff --git a/tests/tests/keystore/src/android/keystore/cts/KeyPairGeneratorTest.java b/tests/tests/keystore/src/android/keystore/cts/KeyPairGeneratorTest.java
index 5eac878..acf0d48 100644
--- a/tests/tests/keystore/src/android/keystore/cts/KeyPairGeneratorTest.java
+++ b/tests/tests/keystore/src/android/keystore/cts/KeyPairGeneratorTest.java
@@ -16,6 +16,7 @@
 
 package android.keystore.cts;
 
+import android.keystore.cts.util.TestUtils;
 import android.security.KeyPairGeneratorSpec;
 import android.security.keystore.KeyGenParameterSpec;
 import android.security.keystore.KeyInfo;
diff --git a/tests/tests/keystore/src/android/keystore/cts/MacTest.java b/tests/tests/keystore/src/android/keystore/cts/MacTest.java
index c41dcda..0ad28b9 100644
--- a/tests/tests/keystore/src/android/keystore/cts/MacTest.java
+++ b/tests/tests/keystore/src/android/keystore/cts/MacTest.java
@@ -16,6 +16,7 @@
 
 package android.keystore.cts;
 
+import android.keystore.cts.util.TestUtils;
 import android.security.keystore.KeyProperties;
 import android.security.keystore.KeyProtection;
 
@@ -43,9 +44,17 @@
  */
 public class MacTest extends TestCase {
 
+    /**
+     * Override to test Strongbox.
+     * @return false
+     */
+    protected boolean isStrongbox() {
+        return false;
+    }
+
     private static final String EXPECTED_PROVIDER_NAME = TestUtils.EXPECTED_CRYPTO_OP_PROVIDER_NAME;
 
-    private static final String[] EXPECTED_ALGORITHMS = {
+    private static final String[] EXPECTED_ALGORITHMS_TEE = {
         "HmacSHA1",
         "HmacSHA224",
         "HmacSHA256",
@@ -53,6 +62,27 @@
         "HmacSHA512",
     };
 
+    private static final String[] EXPECTED_ALGORITHMS_STRONGBOX = {
+        "HmacSHA256",
+    };
+
+    private String[] expectedAlgorithms() {
+        if (isStrongbox()) {
+            return EXPECTED_ALGORITHMS_STRONGBOX;
+        } else {
+            return EXPECTED_ALGORITHMS_TEE;
+        }
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        if (isStrongbox()) {
+            TestUtils.assumeStrongBox();
+        }
+
+        super.setUp();
+    }
+
     private static final byte[] KAT_KEY = HexEncoding.decode(
             "227b212bebd775493929ef626729a587d3f81b8e18a3ed482d403910e184479b448cfa79b62bd90595efdd"
             + "15f87bd7b2d2dac480c61e969ba90a7b8ceadd3284");
@@ -190,11 +220,16 @@
         // expose at least one Service for such an algorithm, and this Service's algorithm will
         // not be in the expected set.
 
+        // Strongbox does not support HASH functions other than SHA256. But AndroidKeyStore
+        // exposes all hash functions that TEE would support. So this test would always fail
+        // on Strongbox.
+        if (isStrongbox()) return;
+
         Provider provider = Security.getProvider(EXPECTED_PROVIDER_NAME);
         Set<Service> services = provider.getServices();
         Set<String> actualAlgsLowerCase = new HashSet<String>();
         Set<String> expectedAlgsLowerCase = new HashSet<String>(
-                Arrays.asList(TestUtils.toLowerCase(EXPECTED_ALGORITHMS)));
+                Arrays.asList(TestUtils.toLowerCase(expectedAlgorithms())));
         for (Service service : services) {
             if ("Mac".equalsIgnoreCase(service.getType())) {
                 String algLowerCase = service.getAlgorithm().toLowerCase(Locale.US);
@@ -209,7 +244,7 @@
     public void testAndroidKeyStoreKeysHandledByAndroidKeyStoreProvider() throws Exception {
         Provider provider = Security.getProvider(EXPECTED_PROVIDER_NAME);
         assertNotNull(provider);
-        for (String algorithm : EXPECTED_ALGORITHMS) {
+        for (String algorithm : expectedAlgorithms()) {
             try {
                 SecretKey key = importDefaultKatKey(algorithm);
 
@@ -226,7 +261,7 @@
     public void testMacGeneratedForEmptyMessage() throws Exception {
         Provider provider = Security.getProvider(EXPECTED_PROVIDER_NAME);
         assertNotNull(provider);
-        for (String algorithm : EXPECTED_ALGORITHMS) {
+        for (String algorithm : expectedAlgorithms()) {
             try {
                 SecretKey key = importDefaultKatKey(algorithm);
 
@@ -247,7 +282,7 @@
     public void testMacGeneratedByAndroidKeyStoreVerifiesByAndroidKeyStore() throws Exception {
         Provider provider = Security.getProvider(EXPECTED_PROVIDER_NAME);
         assertNotNull(provider);
-        for (String algorithm : EXPECTED_ALGORITHMS) {
+        for (String algorithm : expectedAlgorithms()) {
             try {
                 SecretKey key = importDefaultKatKey(algorithm);
 
@@ -268,7 +303,7 @@
             throws Exception {
         Provider provider = Security.getProvider(EXPECTED_PROVIDER_NAME);
         assertNotNull(provider);
-        for (String algorithm : EXPECTED_ALGORITHMS) {
+        for (String algorithm : expectedAlgorithms()) {
             try {
                 SecretKey key = getDefaultKatKey(algorithm);
                 SecretKey keystoreKey = importDefaultKatKey(algorithm);
@@ -290,7 +325,7 @@
             throws Exception {
         Provider keystoreProvider = Security.getProvider(EXPECTED_PROVIDER_NAME);
         assertNotNull(keystoreProvider);
-        for (String algorithm : EXPECTED_ALGORITHMS) {
+        for (String algorithm : expectedAlgorithms()) {
             Provider signingProvider = null;
             try {
                 SecretKey key = getDefaultKatKey(algorithm);
@@ -315,7 +350,7 @@
     public void testSmallMsgKat() throws Exception {
         byte[] message = SHORT_MSG_KAT_MESSAGE;
 
-        for (String algorithm : EXPECTED_ALGORITHMS) {
+        for (String algorithm : expectedAlgorithms()) {
             for (KatVector testVector : SHORT_MSG_KAT_MACS.get(algorithm)) {
                 byte[] keyBytes = testVector.key;
                 try {
@@ -350,7 +385,7 @@
     public void testLargeMsgKat() throws Exception {
         byte[] message = TestUtils.generateLargeKatMsg(LONG_MSG_KAT_SEED, LONG_MSG_KAT_SIZE_BYTES);
 
-        for (String algorithm : EXPECTED_ALGORITHMS) {
+        for (String algorithm : expectedAlgorithms()) {
             try {
                 SecretKey key = importDefaultKatKey(algorithm);
 
@@ -371,7 +406,7 @@
         int badPurposes = KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT
                 | KeyProperties.PURPOSE_VERIFY;
 
-        for (String algorithm : EXPECTED_ALGORITHMS) {
+        for (String algorithm : expectedAlgorithms()) {
             try {
                 KeyProtection good = getWorkingImportParams(algorithm);
                 assertInitSucceeds(algorithm, good);
@@ -384,22 +419,31 @@
     }
 
     public void testInitFailsWhenDigestNotAuthorized() throws Exception {
-        for (String algorithm : EXPECTED_ALGORITHMS) {
-            try {
-                KeyProtection good = getWorkingImportParams(algorithm);
-                assertInitSucceeds(algorithm, good);
+        // TEE algorithms are used here even if Strongbox is tested because
+        // the outer loop iterates through algorithms that are not to be supported
+        // by the imported key. This may include algorithms that are not even supported
+        // the implementation itself. Also Strongbox only supports a single algorithm,
+        // so the test below would test an empty set if expectedAlgorithms() was used
+        // for outer loop.
+        for (String badRequestedAlgorithm: EXPECTED_ALGORITHMS_TEE) {
+            for (String algorithm : expectedAlgorithms()) {
+                if (badRequestedAlgorithm.equals(algorithm)) {
+                    continue;
+                }
+                try {
+                    KeyProtection good = getWorkingImportParams(algorithm);
+                    assertInitSucceeds(algorithm, good);
 
-                String badKeyAlgorithm = ("HmacSHA256".equalsIgnoreCase(algorithm))
-                        ? "HmacSHA384" : "HmacSHA256";
-                assertInitThrowsInvalidKeyException(algorithm, badKeyAlgorithm, good);
-            } catch (Throwable e) {
-                throw new RuntimeException("Failed for " + algorithm, e);
+                    assertInitThrowsInvalidKeyException(badRequestedAlgorithm, algorithm, good);
+                } catch (Throwable e) {
+                    throw new RuntimeException("Failed for " + algorithm, e);
+                }
             }
         }
     }
 
     public void testInitFailsWhenKeyNotYetValid() throws Exception {
-        for (String algorithm : EXPECTED_ALGORITHMS) {
+        for (String algorithm : expectedAlgorithms()) {
             try {
                 KeyProtection good = TestUtils.buildUpon(getWorkingImportParams(algorithm))
                         .setKeyValidityStart(new Date(System.currentTimeMillis() - DAY_IN_MILLIS))
@@ -416,7 +460,7 @@
     }
 
     public void testInitFailsWhenKeyNoLongerValidForOrigination() throws Exception {
-        for (String algorithm : EXPECTED_ALGORITHMS) {
+        for (String algorithm : expectedAlgorithms()) {
             try {
                 KeyProtection good = TestUtils.buildUpon(getWorkingImportParams(algorithm))
                         .setKeyValidityForOriginationEnd(
@@ -436,11 +480,12 @@
     }
 
     public void testInitIgnoresThatKeyNoLongerValidForConsumption() throws Exception {
-        for (String algorithm : EXPECTED_ALGORITHMS) {
+        for (String algorithm : expectedAlgorithms()) {
             try {
                 KeyProtection good = TestUtils.buildUpon(getWorkingImportParams(algorithm))
                         .setKeyValidityForConsumptionEnd(
                                 new Date(System.currentTimeMillis() + DAY_IN_MILLIS))
+                        .setIsStrongBoxBacked(isStrongbox())
                         .build();
                 assertInitSucceeds(algorithm, good);
 
@@ -588,9 +633,9 @@
                 keyProtection).getKeystoreBackedSecretKey();
     }
 
-    private static KeyProtection getWorkingImportParams(
+    private KeyProtection getWorkingImportParams(
             @SuppressWarnings("unused") String algorithm) {
-        return new KeyProtection.Builder(KeyProperties.PURPOSE_SIGN).build();
+        return new KeyProtection.Builder(KeyProperties.PURPOSE_SIGN).setIsStrongBoxBacked(isStrongbox()).build();
     }
 
     private static class KatVector {
diff --git a/tests/tests/keystore/src/android/keystore/cts/RSACipherTest.java b/tests/tests/keystore/src/android/keystore/cts/RSACipherTest.java
index fbf79ed..8a20cb7 100644
--- a/tests/tests/keystore/src/android/keystore/cts/RSACipherTest.java
+++ b/tests/tests/keystore/src/android/keystore/cts/RSACipherTest.java
@@ -27,6 +27,9 @@
 import javax.crypto.Cipher;
 import javax.crypto.IllegalBlockSizeException;
 
+import android.keystore.cts.util.EmptyArray;
+import android.keystore.cts.util.ImportedKey;
+import android.keystore.cts.util.TestUtils;
 import android.security.keystore.KeyProperties;
 import android.test.AndroidTestCase;
 import android.test.MoreAsserts;
diff --git a/tests/tests/keystore/src/android/keystore/cts/RSASignatureTest.java b/tests/tests/keystore/src/android/keystore/cts/RSASignatureTest.java
index dbabbe2..bf03f28 100644
--- a/tests/tests/keystore/src/android/keystore/cts/RSASignatureTest.java
+++ b/tests/tests/keystore/src/android/keystore/cts/RSASignatureTest.java
@@ -31,6 +31,8 @@
 import android.keystore.cts.R;
 
 import android.content.Context;
+import android.keystore.cts.util.ImportedKey;
+import android.keystore.cts.util.TestUtils;
 import android.security.keystore.KeyProperties;
 import android.security.keystore.KeyProtection;
 import android.test.AndroidTestCase;
diff --git a/tests/tests/keystore/src/android/keystore/cts/SecretKeyFactoryTest.java b/tests/tests/keystore/src/android/keystore/cts/SecretKeyFactoryTest.java
index 70581e1..ae50228 100644
--- a/tests/tests/keystore/src/android/keystore/cts/SecretKeyFactoryTest.java
+++ b/tests/tests/keystore/src/android/keystore/cts/SecretKeyFactoryTest.java
@@ -16,6 +16,7 @@
 
 package android.keystore.cts;
 
+import android.keystore.cts.util.TestUtils;
 import android.security.keystore.KeyGenParameterSpec;
 import android.security.keystore.KeyInfo;
 import android.security.keystore.KeyProperties;
diff --git a/tests/tests/keystore/src/android/keystore/cts/SignatureTest.java b/tests/tests/keystore/src/android/keystore/cts/SignatureTest.java
index cbeb7d7..533f522 100644
--- a/tests/tests/keystore/src/android/keystore/cts/SignatureTest.java
+++ b/tests/tests/keystore/src/android/keystore/cts/SignatureTest.java
@@ -17,6 +17,9 @@
 package android.keystore.cts;
 
 import android.keystore.cts.R;
+import android.keystore.cts.util.EmptyArray;
+import android.keystore.cts.util.ImportedKey;
+import android.keystore.cts.util.TestUtils;
 
 import java.security.InvalidKeyException;
 import java.security.Key;
diff --git a/tests/tests/keystore/src/android/keystore/cts/EmptyArray.java b/tests/tests/keystore/src/android/keystore/cts/StrongboxAES128CBCNoPaddingCipherTest.java
similarity index 72%
copy from tests/tests/keystore/src/android/keystore/cts/EmptyArray.java
copy to tests/tests/keystore/src/android/keystore/cts/StrongboxAES128CBCNoPaddingCipherTest.java
index bf08b73..a791512 100644
--- a/tests/tests/keystore/src/android/keystore/cts/EmptyArray.java
+++ b/tests/tests/keystore/src/android/keystore/cts/StrongboxAES128CBCNoPaddingCipherTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2021 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.
@@ -16,9 +16,9 @@
 
 package android.keystore.cts;
 
-abstract class EmptyArray {
-    private EmptyArray() {}
-
-    public static final byte[] BYTE = new byte[0];
-    public static final String[] STRING = new String[0];
+public class StrongboxAES128CBCNoPaddingCipherTest extends AES128CBCNoPaddingCipherTest {
+    @Override
+    protected boolean isStrongbox() {
+        return true;
+    }
 }
diff --git a/tests/tests/keystore/src/android/keystore/cts/EmptyArray.java b/tests/tests/keystore/src/android/keystore/cts/StrongboxAES128CBCPKCS7PaddingCipherTest.java
similarity index 73%
copy from tests/tests/keystore/src/android/keystore/cts/EmptyArray.java
copy to tests/tests/keystore/src/android/keystore/cts/StrongboxAES128CBCPKCS7PaddingCipherTest.java
index bf08b73..0ca2a15 100644
--- a/tests/tests/keystore/src/android/keystore/cts/EmptyArray.java
+++ b/tests/tests/keystore/src/android/keystore/cts/StrongboxAES128CBCPKCS7PaddingCipherTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2021 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.
@@ -16,9 +16,7 @@
 
 package android.keystore.cts;
 
-abstract class EmptyArray {
-    private EmptyArray() {}
-
-    public static final byte[] BYTE = new byte[0];
-    public static final String[] STRING = new String[0];
+public class StrongboxAES128CBCPKCS7PaddingCipherTest extends AES128CBCPKCS7PaddingCipherTest {
+    @Override
+    protected boolean isStrongbox() { return true; }
 }
diff --git a/tests/tests/keystore/src/android/keystore/cts/EmptyArray.java b/tests/tests/keystore/src/android/keystore/cts/StrongboxAES128CTRNoPaddingCipherTest.java
similarity index 73%
copy from tests/tests/keystore/src/android/keystore/cts/EmptyArray.java
copy to tests/tests/keystore/src/android/keystore/cts/StrongboxAES128CTRNoPaddingCipherTest.java
index bf08b73..2710865 100644
--- a/tests/tests/keystore/src/android/keystore/cts/EmptyArray.java
+++ b/tests/tests/keystore/src/android/keystore/cts/StrongboxAES128CTRNoPaddingCipherTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2021 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.
@@ -16,9 +16,7 @@
 
 package android.keystore.cts;
 
-abstract class EmptyArray {
-    private EmptyArray() {}
-
-    public static final byte[] BYTE = new byte[0];
-    public static final String[] STRING = new String[0];
+public class StrongboxAES128CTRNoPaddingCipherTest extends AES128CTRNoPaddingCipherTest {
+    @Override
+    protected boolean isStrongbox() { return true; }
 }
diff --git a/tests/tests/keystore/src/android/keystore/cts/EmptyArray.java b/tests/tests/keystore/src/android/keystore/cts/StrongboxAES128ECBNoPaddingCipherTest.java
similarity index 73%
copy from tests/tests/keystore/src/android/keystore/cts/EmptyArray.java
copy to tests/tests/keystore/src/android/keystore/cts/StrongboxAES128ECBNoPaddingCipherTest.java
index bf08b73..50a8952 100644
--- a/tests/tests/keystore/src/android/keystore/cts/EmptyArray.java
+++ b/tests/tests/keystore/src/android/keystore/cts/StrongboxAES128ECBNoPaddingCipherTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2021 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.
@@ -16,9 +16,7 @@
 
 package android.keystore.cts;
 
-abstract class EmptyArray {
-    private EmptyArray() {}
-
-    public static final byte[] BYTE = new byte[0];
-    public static final String[] STRING = new String[0];
+public class StrongboxAES128ECBNoPaddingCipherTest extends AES128ECBNoPaddingCipherTest {
+    @Override
+    protected boolean isStrongbox() { return true; }
 }
diff --git a/tests/tests/keystore/src/android/keystore/cts/EmptyArray.java b/tests/tests/keystore/src/android/keystore/cts/StrongboxAES128ECBPKCS7PaddingCipherTest.java
similarity index 73%
copy from tests/tests/keystore/src/android/keystore/cts/EmptyArray.java
copy to tests/tests/keystore/src/android/keystore/cts/StrongboxAES128ECBPKCS7PaddingCipherTest.java
index bf08b73..a6ecdfc 100644
--- a/tests/tests/keystore/src/android/keystore/cts/EmptyArray.java
+++ b/tests/tests/keystore/src/android/keystore/cts/StrongboxAES128ECBPKCS7PaddingCipherTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2021 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.
@@ -16,9 +16,7 @@
 
 package android.keystore.cts;
 
-abstract class EmptyArray {
-    private EmptyArray() {}
-
-    public static final byte[] BYTE = new byte[0];
-    public static final String[] STRING = new String[0];
+public class StrongboxAES128ECBPKCS7PaddingCipherTest extends AES128ECBPKCS7PaddingCipherTest {
+    @Override
+    protected boolean isStrongbox() { return true; }
 }
diff --git a/tests/tests/keystore/src/android/keystore/cts/EmptyArray.java b/tests/tests/keystore/src/android/keystore/cts/StrongboxAES128GCMNoPaddingCipherTest.java
similarity index 73%
copy from tests/tests/keystore/src/android/keystore/cts/EmptyArray.java
copy to tests/tests/keystore/src/android/keystore/cts/StrongboxAES128GCMNoPaddingCipherTest.java
index bf08b73..4d53259 100644
--- a/tests/tests/keystore/src/android/keystore/cts/EmptyArray.java
+++ b/tests/tests/keystore/src/android/keystore/cts/StrongboxAES128GCMNoPaddingCipherTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2021 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.
@@ -16,9 +16,7 @@
 
 package android.keystore.cts;
 
-abstract class EmptyArray {
-    private EmptyArray() {}
-
-    public static final byte[] BYTE = new byte[0];
-    public static final String[] STRING = new String[0];
+public class StrongboxAES128GCMNoPaddingCipherTest extends AES128GCMNoPaddingCipherTest {
+    @Override
+    protected boolean isStrongbox() { return true; }
 }
diff --git a/tests/tests/keystore/src/android/keystore/cts/EmptyArray.java b/tests/tests/keystore/src/android/keystore/cts/StrongboxAES256CBCNoPaddingCipherTest.java
similarity index 73%
copy from tests/tests/keystore/src/android/keystore/cts/EmptyArray.java
copy to tests/tests/keystore/src/android/keystore/cts/StrongboxAES256CBCNoPaddingCipherTest.java
index bf08b73..422bc96 100644
--- a/tests/tests/keystore/src/android/keystore/cts/EmptyArray.java
+++ b/tests/tests/keystore/src/android/keystore/cts/StrongboxAES256CBCNoPaddingCipherTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2021 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.
@@ -16,9 +16,7 @@
 
 package android.keystore.cts;
 
-abstract class EmptyArray {
-    private EmptyArray() {}
-
-    public static final byte[] BYTE = new byte[0];
-    public static final String[] STRING = new String[0];
+public class StrongboxAES256CBCNoPaddingCipherTest extends AES256CBCNoPaddingCipherTest {
+    @Override
+    protected boolean isStrongbox() { return true; }
 }
diff --git a/tests/tests/keystore/src/android/keystore/cts/EmptyArray.java b/tests/tests/keystore/src/android/keystore/cts/StrongboxAES256CBCPKCS7PaddingCipherTest.java
similarity index 73%
copy from tests/tests/keystore/src/android/keystore/cts/EmptyArray.java
copy to tests/tests/keystore/src/android/keystore/cts/StrongboxAES256CBCPKCS7PaddingCipherTest.java
index bf08b73..77ae08e 100644
--- a/tests/tests/keystore/src/android/keystore/cts/EmptyArray.java
+++ b/tests/tests/keystore/src/android/keystore/cts/StrongboxAES256CBCPKCS7PaddingCipherTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2021 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.
@@ -16,9 +16,7 @@
 
 package android.keystore.cts;
 
-abstract class EmptyArray {
-    private EmptyArray() {}
-
-    public static final byte[] BYTE = new byte[0];
-    public static final String[] STRING = new String[0];
+public class StrongboxAES256CBCPKCS7PaddingCipherTest extends AES256CBCPKCS7PaddingCipherTest {
+    @Override
+    protected boolean isStrongbox() { return true; }
 }
diff --git a/tests/tests/keystore/src/android/keystore/cts/EmptyArray.java b/tests/tests/keystore/src/android/keystore/cts/StrongboxAES256CTRNoPaddingCipherTest.java
similarity index 73%
copy from tests/tests/keystore/src/android/keystore/cts/EmptyArray.java
copy to tests/tests/keystore/src/android/keystore/cts/StrongboxAES256CTRNoPaddingCipherTest.java
index bf08b73..4288a53 100644
--- a/tests/tests/keystore/src/android/keystore/cts/EmptyArray.java
+++ b/tests/tests/keystore/src/android/keystore/cts/StrongboxAES256CTRNoPaddingCipherTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2021 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.
@@ -16,9 +16,7 @@
 
 package android.keystore.cts;
 
-abstract class EmptyArray {
-    private EmptyArray() {}
-
-    public static final byte[] BYTE = new byte[0];
-    public static final String[] STRING = new String[0];
+public class StrongboxAES256CTRNoPaddingCipherTest extends AES256CTRNoPaddingCipherTest {
+    @Override
+    protected boolean isStrongbox() { return true; }
 }
diff --git a/tests/tests/keystore/src/android/keystore/cts/EmptyArray.java b/tests/tests/keystore/src/android/keystore/cts/StrongboxAES256ECBNoPaddingCipherTest.java
similarity index 73%
copy from tests/tests/keystore/src/android/keystore/cts/EmptyArray.java
copy to tests/tests/keystore/src/android/keystore/cts/StrongboxAES256ECBNoPaddingCipherTest.java
index bf08b73..0bfd508 100644
--- a/tests/tests/keystore/src/android/keystore/cts/EmptyArray.java
+++ b/tests/tests/keystore/src/android/keystore/cts/StrongboxAES256ECBNoPaddingCipherTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2021 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.
@@ -16,9 +16,7 @@
 
 package android.keystore.cts;
 
-abstract class EmptyArray {
-    private EmptyArray() {}
-
-    public static final byte[] BYTE = new byte[0];
-    public static final String[] STRING = new String[0];
+public class StrongboxAES256ECBNoPaddingCipherTest extends AES256ECBNoPaddingCipherTest {
+    @Override
+    protected boolean isStrongbox() { return true; }
 }
diff --git a/tests/tests/keystore/src/android/keystore/cts/EmptyArray.java b/tests/tests/keystore/src/android/keystore/cts/StrongboxAES256ECBPKCS7PaddingCipherTest.java
similarity index 73%
copy from tests/tests/keystore/src/android/keystore/cts/EmptyArray.java
copy to tests/tests/keystore/src/android/keystore/cts/StrongboxAES256ECBPKCS7PaddingCipherTest.java
index bf08b73..a606187 100644
--- a/tests/tests/keystore/src/android/keystore/cts/EmptyArray.java
+++ b/tests/tests/keystore/src/android/keystore/cts/StrongboxAES256ECBPKCS7PaddingCipherTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2021 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.
@@ -16,9 +16,7 @@
 
 package android.keystore.cts;
 
-abstract class EmptyArray {
-    private EmptyArray() {}
-
-    public static final byte[] BYTE = new byte[0];
-    public static final String[] STRING = new String[0];
+public class StrongboxAES256ECBPKCS7PaddingCipherTest extends AES256ECBPKCS7PaddingCipherTest {
+    @Override
+    protected boolean isStrongbox() { return true; }
 }
diff --git a/tests/tests/keystore/src/android/keystore/cts/EmptyArray.java b/tests/tests/keystore/src/android/keystore/cts/StrongboxAES256GCMNoPaddingCipherTest.java
similarity index 73%
copy from tests/tests/keystore/src/android/keystore/cts/EmptyArray.java
copy to tests/tests/keystore/src/android/keystore/cts/StrongboxAES256GCMNoPaddingCipherTest.java
index bf08b73..cf0aa2d 100644
--- a/tests/tests/keystore/src/android/keystore/cts/EmptyArray.java
+++ b/tests/tests/keystore/src/android/keystore/cts/StrongboxAES256GCMNoPaddingCipherTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2021 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.
@@ -16,9 +16,7 @@
 
 package android.keystore.cts;
 
-abstract class EmptyArray {
-    private EmptyArray() {}
-
-    public static final byte[] BYTE = new byte[0];
-    public static final String[] STRING = new String[0];
+public class StrongboxAES256GCMNoPaddingCipherTest extends AES256GCMNoPaddingCipherTest {
+    @Override
+    protected boolean isStrongbox() { return true; }
 }
diff --git a/tests/tests/keystore/src/android/keystore/cts/EmptyArray.java b/tests/tests/keystore/src/android/keystore/cts/StrongboxDESedeCBCNoPaddingCipherTest.java
similarity index 73%
copy from tests/tests/keystore/src/android/keystore/cts/EmptyArray.java
copy to tests/tests/keystore/src/android/keystore/cts/StrongboxDESedeCBCNoPaddingCipherTest.java
index bf08b73..750c6f2 100644
--- a/tests/tests/keystore/src/android/keystore/cts/EmptyArray.java
+++ b/tests/tests/keystore/src/android/keystore/cts/StrongboxDESedeCBCNoPaddingCipherTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2021 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.
@@ -16,9 +16,7 @@
 
 package android.keystore.cts;
 
-abstract class EmptyArray {
-    private EmptyArray() {}
-
-    public static final byte[] BYTE = new byte[0];
-    public static final String[] STRING = new String[0];
+public class StrongboxDESedeCBCNoPaddingCipherTest extends DESedeCBCNoPaddingCipherTest {
+    @Override
+    protected boolean isStrongbox() { return true; }
 }
diff --git a/tests/tests/keystore/src/android/keystore/cts/EmptyArray.java b/tests/tests/keystore/src/android/keystore/cts/StrongboxDESedeCBCPKCS7PaddingCipherTest.java
similarity index 73%
copy from tests/tests/keystore/src/android/keystore/cts/EmptyArray.java
copy to tests/tests/keystore/src/android/keystore/cts/StrongboxDESedeCBCPKCS7PaddingCipherTest.java
index bf08b73..9215c05 100644
--- a/tests/tests/keystore/src/android/keystore/cts/EmptyArray.java
+++ b/tests/tests/keystore/src/android/keystore/cts/StrongboxDESedeCBCPKCS7PaddingCipherTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2021 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.
@@ -16,9 +16,7 @@
 
 package android.keystore.cts;
 
-abstract class EmptyArray {
-    private EmptyArray() {}
-
-    public static final byte[] BYTE = new byte[0];
-    public static final String[] STRING = new String[0];
+public class StrongboxDESedeCBCPKCS7PaddingCipherTest extends DESedeCBCPKCS7PaddingCipherTest {
+    @Override
+    protected boolean isStrongbox() { return true; }
 }
diff --git a/tests/tests/keystore/src/android/keystore/cts/EmptyArray.java b/tests/tests/keystore/src/android/keystore/cts/StrongboxDESedeECBNoPaddingCipherTest.java
similarity index 62%
copy from tests/tests/keystore/src/android/keystore/cts/EmptyArray.java
copy to tests/tests/keystore/src/android/keystore/cts/StrongboxDESedeECBNoPaddingCipherTest.java
index bf08b73..ed7a790 100644
--- a/tests/tests/keystore/src/android/keystore/cts/EmptyArray.java
+++ b/tests/tests/keystore/src/android/keystore/cts/StrongboxDESedeECBNoPaddingCipherTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2021 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.
@@ -16,9 +16,11 @@
 
 package android.keystore.cts;
 
-abstract class EmptyArray {
-    private EmptyArray() {}
+import java.security.AlgorithmParameters;
+import java.security.spec.AlgorithmParameterSpec;
+import java.security.spec.InvalidParameterSpecException;
 
-    public static final byte[] BYTE = new byte[0];
-    public static final String[] STRING = new String[0];
+public class StrongboxDESedeECBNoPaddingCipherTest extends DESedeECBNoPaddingCipherTest {
+    @Override
+    protected boolean isStrongbox() { return true; }
 }
diff --git a/tests/tests/keystore/src/android/keystore/cts/EmptyArray.java b/tests/tests/keystore/src/android/keystore/cts/StrongboxDESedeECBPKCS7PaddingCipherTest.java
similarity index 73%
copy from tests/tests/keystore/src/android/keystore/cts/EmptyArray.java
copy to tests/tests/keystore/src/android/keystore/cts/StrongboxDESedeECBPKCS7PaddingCipherTest.java
index bf08b73..4e87dd8 100644
--- a/tests/tests/keystore/src/android/keystore/cts/EmptyArray.java
+++ b/tests/tests/keystore/src/android/keystore/cts/StrongboxDESedeECBPKCS7PaddingCipherTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2021 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.
@@ -16,9 +16,7 @@
 
 package android.keystore.cts;
 
-abstract class EmptyArray {
-    private EmptyArray() {}
-
-    public static final byte[] BYTE = new byte[0];
-    public static final String[] STRING = new String[0];
+public class StrongboxDESedeECBPKCS7PaddingCipherTest extends DESedeECBPKCS7PaddingCipherTest {
+    @Override
+    protected boolean isStrongbox() { return true; }
 }
diff --git a/tests/tests/keystore/src/android/keystore/cts/EmptyArray.java b/tests/tests/keystore/src/android/keystore/cts/StrongboxMacTest.java
similarity index 67%
copy from tests/tests/keystore/src/android/keystore/cts/EmptyArray.java
copy to tests/tests/keystore/src/android/keystore/cts/StrongboxMacTest.java
index bf08b73..3584389 100644
--- a/tests/tests/keystore/src/android/keystore/cts/EmptyArray.java
+++ b/tests/tests/keystore/src/android/keystore/cts/StrongboxMacTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright 2021 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.
@@ -16,9 +16,13 @@
 
 package android.keystore.cts;
 
-abstract class EmptyArray {
-    private EmptyArray() {}
+/**
+ * Tests for algorithm-agnostic functionality of MAC implementations backed by Android Keystore.
+ */
+public class StrongboxMacTest extends MacTest {
 
-    public static final byte[] BYTE = new byte[0];
-    public static final String[] STRING = new String[0];
+    @Override
+    protected boolean isStrongbox() {
+        return true;
+    }
 }
diff --git a/tests/tests/keystore/src/android/keystore/cts/AesCipherPerformanceTest.java b/tests/tests/keystore/src/android/keystore/cts/performance/AesCipherPerformanceTest.java
similarity index 98%
rename from tests/tests/keystore/src/android/keystore/cts/AesCipherPerformanceTest.java
rename to tests/tests/keystore/src/android/keystore/cts/performance/AesCipherPerformanceTest.java
index a2598a9..1730607 100644
--- a/tests/tests/keystore/src/android/keystore/cts/AesCipherPerformanceTest.java
+++ b/tests/tests/keystore/src/android/keystore/cts/performance/AesCipherPerformanceTest.java
@@ -14,8 +14,9 @@
  * limitations under the License
  */
 
-package android.keystore.cts;
+package android.keystore.cts.performance;
 
+import android.keystore.cts.util.TestUtils;
 import android.security.keystore.KeyProperties;
 
 import org.junit.Test;
diff --git a/tests/tests/keystore/src/android/keystore/cts/AesKeyGenPerformanceTest.java b/tests/tests/keystore/src/android/keystore/cts/performance/AesKeyGenPerformanceTest.java
similarity index 97%
rename from tests/tests/keystore/src/android/keystore/cts/AesKeyGenPerformanceTest.java
rename to tests/tests/keystore/src/android/keystore/cts/performance/AesKeyGenPerformanceTest.java
index abfea06..3e1b86b 100644
--- a/tests/tests/keystore/src/android/keystore/cts/AesKeyGenPerformanceTest.java
+++ b/tests/tests/keystore/src/android/keystore/cts/performance/AesKeyGenPerformanceTest.java
@@ -14,7 +14,7 @@
  * limitations under the License
  */
 
-package android.keystore.cts;
+package android.keystore.cts.performance;
 
 import android.security.keystore.KeyProperties;
 
diff --git a/tests/tests/keystore/src/android/keystore/cts/AttestationPerformanceTest.java b/tests/tests/keystore/src/android/keystore/cts/performance/AttestationPerformanceTest.java
similarity index 95%
rename from tests/tests/keystore/src/android/keystore/cts/AttestationPerformanceTest.java
rename to tests/tests/keystore/src/android/keystore/cts/performance/AttestationPerformanceTest.java
index 9101f3b..ba3aab4 100644
--- a/tests/tests/keystore/src/android/keystore/cts/AttestationPerformanceTest.java
+++ b/tests/tests/keystore/src/android/keystore/cts/performance/AttestationPerformanceTest.java
@@ -14,9 +14,10 @@
  * limitations under the License
  */
 
-package android.keystore.cts;
+package android.keystore.cts.performance;
 
-import android.keystore.cts.PerformanceTestBase.AndroidKeystoreKeyGenerator;
+import android.keystore.cts.performance.PerformanceTestBase.AndroidKeystoreKeyGenerator;
+import android.keystore.cts.util.TestUtils;
 import android.security.keystore.KeyProperties;
 
 import org.junit.Test;
diff --git a/tests/tests/keystore/src/android/keystore/cts/DesCipherPerformanceTest.java b/tests/tests/keystore/src/android/keystore/cts/performance/DesCipherPerformanceTest.java
similarity index 98%
rename from tests/tests/keystore/src/android/keystore/cts/DesCipherPerformanceTest.java
rename to tests/tests/keystore/src/android/keystore/cts/performance/DesCipherPerformanceTest.java
index 527dee5..498735e 100644
--- a/tests/tests/keystore/src/android/keystore/cts/DesCipherPerformanceTest.java
+++ b/tests/tests/keystore/src/android/keystore/cts/performance/DesCipherPerformanceTest.java
@@ -14,8 +14,9 @@
  * limitations under the License
  */
 
-package android.keystore.cts;
+package android.keystore.cts.performance;
 
+import android.keystore.cts.util.TestUtils;
 import android.security.keystore.KeyProperties;
 
 import java.security.AlgorithmParameters;
diff --git a/tests/tests/keystore/src/android/keystore/cts/DesKeyGenPerformanceTest.java b/tests/tests/keystore/src/android/keystore/cts/performance/DesKeyGenPerformanceTest.java
similarity index 95%
rename from tests/tests/keystore/src/android/keystore/cts/DesKeyGenPerformanceTest.java
rename to tests/tests/keystore/src/android/keystore/cts/performance/DesKeyGenPerformanceTest.java
index 0d9d627..48d3e73 100644
--- a/tests/tests/keystore/src/android/keystore/cts/DesKeyGenPerformanceTest.java
+++ b/tests/tests/keystore/src/android/keystore/cts/performance/DesKeyGenPerformanceTest.java
@@ -14,8 +14,9 @@
  * limitations under the License
  */
 
-package android.keystore.cts;
+package android.keystore.cts.performance;
 
+import android.keystore.cts.util.TestUtils;
 import android.security.keystore.KeyProperties;
 
 public class DesKeyGenPerformanceTest extends PerformanceTestBase {
diff --git a/tests/tests/keystore/src/android/keystore/cts/EcKeyGenPerformanceTest.java b/tests/tests/keystore/src/android/keystore/cts/performance/EcKeyGenPerformanceTest.java
similarity index 97%
rename from tests/tests/keystore/src/android/keystore/cts/EcKeyGenPerformanceTest.java
rename to tests/tests/keystore/src/android/keystore/cts/performance/EcKeyGenPerformanceTest.java
index afedb9f..c6161da 100644
--- a/tests/tests/keystore/src/android/keystore/cts/EcKeyGenPerformanceTest.java
+++ b/tests/tests/keystore/src/android/keystore/cts/performance/EcKeyGenPerformanceTest.java
@@ -14,7 +14,7 @@
  * limitations under the License
  */
 
-package android.keystore.cts;
+package android.keystore.cts.performance;
 
 import android.security.keystore.KeyProperties;
 
diff --git a/tests/tests/keystore/src/android/keystore/cts/EcdsaSignaturePerformanceTest.java b/tests/tests/keystore/src/android/keystore/cts/performance/EcdsaSignaturePerformanceTest.java
similarity index 98%
rename from tests/tests/keystore/src/android/keystore/cts/EcdsaSignaturePerformanceTest.java
rename to tests/tests/keystore/src/android/keystore/cts/performance/EcdsaSignaturePerformanceTest.java
index 179dacc..0609105 100644
--- a/tests/tests/keystore/src/android/keystore/cts/EcdsaSignaturePerformanceTest.java
+++ b/tests/tests/keystore/src/android/keystore/cts/performance/EcdsaSignaturePerformanceTest.java
@@ -14,8 +14,9 @@
  * limitations under the License
  */
 
-package android.keystore.cts;
+package android.keystore.cts.performance;
 
+import android.keystore.cts.util.TestUtils;
 import android.security.keystore.KeyProperties;
 
 import org.junit.Test;
diff --git a/tests/tests/keystore/src/android/keystore/cts/HmacKeyGenPerformanceTest.java b/tests/tests/keystore/src/android/keystore/cts/performance/HmacKeyGenPerformanceTest.java
similarity index 97%
rename from tests/tests/keystore/src/android/keystore/cts/HmacKeyGenPerformanceTest.java
rename to tests/tests/keystore/src/android/keystore/cts/performance/HmacKeyGenPerformanceTest.java
index 544621e..7fb161d 100644
--- a/tests/tests/keystore/src/android/keystore/cts/HmacKeyGenPerformanceTest.java
+++ b/tests/tests/keystore/src/android/keystore/cts/performance/HmacKeyGenPerformanceTest.java
@@ -14,7 +14,7 @@
  * limitations under the License
  */
 
-package android.keystore.cts;
+package android.keystore.cts.performance;
 
 import android.security.keystore.KeyProperties;
 
diff --git a/tests/tests/keystore/src/android/keystore/cts/HmacMacPerformanceTest.java b/tests/tests/keystore/src/android/keystore/cts/performance/HmacMacPerformanceTest.java
similarity index 98%
rename from tests/tests/keystore/src/android/keystore/cts/HmacMacPerformanceTest.java
rename to tests/tests/keystore/src/android/keystore/cts/performance/HmacMacPerformanceTest.java
index dc7de74..2048b26 100644
--- a/tests/tests/keystore/src/android/keystore/cts/HmacMacPerformanceTest.java
+++ b/tests/tests/keystore/src/android/keystore/cts/performance/HmacMacPerformanceTest.java
@@ -14,7 +14,7 @@
  * limitations under the License
  */
 
-package android.keystore.cts;
+package android.keystore.cts.performance;
 
 import android.security.keystore.KeyProperties;
 
diff --git a/tests/tests/keystore/src/android/keystore/cts/PerformanceTestBase.java b/tests/tests/keystore/src/android/keystore/cts/performance/PerformanceTestBase.java
similarity index 98%
rename from tests/tests/keystore/src/android/keystore/cts/PerformanceTestBase.java
rename to tests/tests/keystore/src/android/keystore/cts/performance/PerformanceTestBase.java
index 791435b..396b806 100644
--- a/tests/tests/keystore/src/android/keystore/cts/PerformanceTestBase.java
+++ b/tests/tests/keystore/src/android/keystore/cts/performance/PerformanceTestBase.java
@@ -14,8 +14,9 @@
  * limitations under the License
  */
 
-package android.keystore.cts;
+package android.keystore.cts.performance;
 
+import android.keystore.cts.util.TestUtils;
 import android.os.SystemClock;
 import android.security.keystore.KeyGenParameterSpec;
 import android.test.AndroidTestCase;
@@ -41,7 +42,7 @@
 
     public static final long MS_PER_NS = 1000000L;
     protected static final String TAG = "KeystorePerformanceTest";
-    private static final String REPORT_LOG_NAME = "CtsKeystoreTestCases";
+    private static final String REPORT_LOG_NAME = "CtsKeystorePerformanceTests";
     /**
      * Number of milliseconds to spend repeating a single test.
      *
diff --git a/tests/tests/keystore/src/android/keystore/cts/PerformanceTestResult.java b/tests/tests/keystore/src/android/keystore/cts/performance/PerformanceTestResult.java
similarity index 98%
rename from tests/tests/keystore/src/android/keystore/cts/PerformanceTestResult.java
rename to tests/tests/keystore/src/android/keystore/cts/performance/PerformanceTestResult.java
index 08fdee0..4fb9a9d 100644
--- a/tests/tests/keystore/src/android/keystore/cts/PerformanceTestResult.java
+++ b/tests/tests/keystore/src/android/keystore/cts/performance/PerformanceTestResult.java
@@ -14,7 +14,7 @@
  * limitations under the License
  */
 
-package android.keystore.cts;
+package android.keystore.cts.performance;
 
 import junit.framework.TestCase;
 
diff --git a/tests/tests/keystore/src/android/keystore/cts/RsaCipherPerformanceTest.java b/tests/tests/keystore/src/android/keystore/cts/performance/RsaCipherPerformanceTest.java
similarity index 97%
rename from tests/tests/keystore/src/android/keystore/cts/RsaCipherPerformanceTest.java
rename to tests/tests/keystore/src/android/keystore/cts/performance/RsaCipherPerformanceTest.java
index 6233981..71548a3 100644
--- a/tests/tests/keystore/src/android/keystore/cts/RsaCipherPerformanceTest.java
+++ b/tests/tests/keystore/src/android/keystore/cts/performance/RsaCipherPerformanceTest.java
@@ -14,8 +14,10 @@
  * limitations under the License
  */
 
-package android.keystore.cts;
+package android.keystore.cts.performance;
 
+import android.keystore.cts.util.EmptyArray;
+import android.keystore.cts.util.TestUtils;
 import android.security.keystore.KeyProperties;
 
 import org.junit.Test;
diff --git a/tests/tests/keystore/src/android/keystore/cts/RsaKeyGenPerformanceTest.java b/tests/tests/keystore/src/android/keystore/cts/performance/RsaKeyGenPerformanceTest.java
similarity index 97%
rename from tests/tests/keystore/src/android/keystore/cts/RsaKeyGenPerformanceTest.java
rename to tests/tests/keystore/src/android/keystore/cts/performance/RsaKeyGenPerformanceTest.java
index 1ba1bd02..769d656 100644
--- a/tests/tests/keystore/src/android/keystore/cts/RsaKeyGenPerformanceTest.java
+++ b/tests/tests/keystore/src/android/keystore/cts/performance/RsaKeyGenPerformanceTest.java
@@ -14,7 +14,7 @@
  * limitations under the License
  */
 
-package android.keystore.cts;
+package android.keystore.cts.performance;
 
 import android.security.keystore.KeyProperties;
 
diff --git a/tests/tests/keystore/src/android/keystore/cts/RsaSignaturePerformanceTest.java b/tests/tests/keystore/src/android/keystore/cts/performance/RsaSignaturePerformanceTest.java
similarity index 98%
rename from tests/tests/keystore/src/android/keystore/cts/RsaSignaturePerformanceTest.java
rename to tests/tests/keystore/src/android/keystore/cts/performance/RsaSignaturePerformanceTest.java
index 906693b..28ac330 100644
--- a/tests/tests/keystore/src/android/keystore/cts/RsaSignaturePerformanceTest.java
+++ b/tests/tests/keystore/src/android/keystore/cts/performance/RsaSignaturePerformanceTest.java
@@ -14,8 +14,9 @@
  * limitations under the License
  */
 
-package android.keystore.cts;
+package android.keystore.cts.performance;
 
+import android.keystore.cts.util.TestUtils;
 import android.security.keystore.KeyProperties;
 
 import org.junit.Test;
diff --git a/tests/tests/keystore/src/android/keystore/cts/EmptyArray.java b/tests/tests/keystore/src/android/keystore/cts/util/EmptyArray.java
similarity index 91%
rename from tests/tests/keystore/src/android/keystore/cts/EmptyArray.java
rename to tests/tests/keystore/src/android/keystore/cts/util/EmptyArray.java
index bf08b73..72347cc 100644
--- a/tests/tests/keystore/src/android/keystore/cts/EmptyArray.java
+++ b/tests/tests/keystore/src/android/keystore/cts/util/EmptyArray.java
@@ -14,9 +14,9 @@
  * limitations under the License.
  */
 
-package android.keystore.cts;
+package android.keystore.cts.util;
 
-abstract class EmptyArray {
+public abstract class EmptyArray {
     private EmptyArray() {}
 
     public static final byte[] BYTE = new byte[0];
diff --git a/tests/tests/keystore/src/android/keystore/cts/ImportedKey.java b/tests/tests/keystore/src/android/keystore/cts/util/ImportedKey.java
similarity index 98%
rename from tests/tests/keystore/src/android/keystore/cts/ImportedKey.java
rename to tests/tests/keystore/src/android/keystore/cts/util/ImportedKey.java
index b6c868f..beeb2b9 100644
--- a/tests/tests/keystore/src/android/keystore/cts/ImportedKey.java
+++ b/tests/tests/keystore/src/android/keystore/cts/util/ImportedKey.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package android.keystore.cts;
+package android.keystore.cts.util;
 
 import java.security.Key;
 import java.security.KeyPair;
diff --git a/tests/tests/keystore/src/android/keystore/cts/TestUtils.java b/tests/tests/keystore/src/android/keystore/cts/util/TestUtils.java
similarity index 88%
rename from tests/tests/keystore/src/android/keystore/cts/TestUtils.java
rename to tests/tests/keystore/src/android/keystore/cts/util/TestUtils.java
index aeb3ad6..1782aaa 100644
--- a/tests/tests/keystore/src/android/keystore/cts/TestUtils.java
+++ b/tests/tests/keystore/src/android/keystore/cts/util/TestUtils.java
@@ -14,7 +14,9 @@
  * limitations under the License.
  */
 
-package android.keystore.cts;
+package android.keystore.cts.util;
+
+import static org.junit.Assume.assumeTrue;
 
 import android.content.Context;
 import android.content.pm.PackageManager;
@@ -26,6 +28,8 @@
 import android.security.keystore.KeyProtection;
 import android.test.MoreAsserts;
 
+import androidx.test.platform.app.InstrumentationRegistry;
+
 import com.android.internal.util.HexDump;
 
 import junit.framework.Assert;
@@ -74,18 +78,25 @@
 import javax.crypto.SecretKeyFactory;
 import javax.crypto.spec.SecretKeySpec;
 
-abstract class TestUtils extends Assert {
+abstract public class TestUtils extends Assert {
 
-    static final String EXPECTED_CRYPTO_OP_PROVIDER_NAME = "AndroidKeyStoreBCWorkaround";
-    static final String EXPECTED_PROVIDER_NAME = "AndroidKeyStore";
+    public static final String EXPECTED_CRYPTO_OP_PROVIDER_NAME = "AndroidKeyStoreBCWorkaround";
+    public static final String EXPECTED_PROVIDER_NAME = "AndroidKeyStore";
 
-    static final long DAY_IN_MILLIS = 1000 * 60 * 60 * 24;
+    public static final long DAY_IN_MILLIS = 1000 * 60 * 60 * 24;
 
     private TestUtils() {}
 
+    static public void assumeStrongBox() {
+        PackageManager packageManager =
+                InstrumentationRegistry.getInstrumentation().getTargetContext().getPackageManager();
+        assumeTrue("Can only test if we have StrongBox",
+                packageManager.hasSystemFeature(PackageManager.FEATURE_STRONGBOX_KEYSTORE));
+    }
+
     // Returns 0 if not implemented. Otherwise returns the feature version.
     //
-    static int getFeatureVersionKeystore(Context appContext) {
+    public static int getFeatureVersionKeystore(Context appContext) {
         PackageManager pm = appContext.getPackageManager();
 
         int featureVersionFromPm = 0;
@@ -109,7 +120,7 @@
 
     // Returns 0 if not implemented. Otherwise returns the feature version.
     //
-    static int getFeatureVersionKeystoreStrongBox(Context appContext) {
+    public static int getFeatureVersionKeystoreStrongBox(Context appContext) {
         PackageManager pm = appContext.getPackageManager();
 
         int featureVersionFromPm = 0;
@@ -135,14 +146,14 @@
      * Returns whether 3DES KeyStore tests should run on this device. 3DES support was added in
      * KeyMaster 4.0 and there should be no software fallback on earlier KeyMaster versions.
      */
-    static boolean supports3DES() {
+    public static boolean supports3DES() {
         return "true".equals(SystemProperties.get("ro.hardware.keystore_desede"));
     }
 
     /**
      * Returns whether the device has a StrongBox backed KeyStore.
      */
-    static boolean hasStrongBox(Context context) {
+    public static boolean hasStrongBox(Context context) {
         return context.getPackageManager()
             .hasSystemFeature(PackageManager.FEATURE_STRONGBOX_KEYSTORE);
     }
@@ -151,7 +162,7 @@
      * Asserts the the key algorithm and algorithm-specific parameters of the two keys in the
      * provided pair match.
      */
-    static void assertKeyPairSelfConsistent(KeyPair keyPair) {
+    public static void assertKeyPairSelfConsistent(KeyPair keyPair) {
         assertKeyPairSelfConsistent(keyPair.getPublic(), keyPair.getPrivate());
     }
 
@@ -159,7 +170,7 @@
      * Asserts the the key algorithm and public algorithm-specific parameters of the two provided
      * keys match.
      */
-    static void assertKeyPairSelfConsistent(PublicKey publicKey, PrivateKey privateKey) {
+    public static void assertKeyPairSelfConsistent(PublicKey publicKey, PrivateKey privateKey) {
         assertNotNull(publicKey);
         assertNotNull(privateKey);
         assertEquals(publicKey.getAlgorithm(), privateKey.getAlgorithm());
@@ -188,7 +199,7 @@
         }
     }
 
-    static int getKeySizeBits(Key key) {
+    public static int getKeySizeBits(Key key) {
         if (key instanceof ECKey) {
             return ((ECKey) key).getParams().getCurve().getField().getFieldSize();
         } else if (key instanceof RSAKey) {
@@ -198,7 +209,7 @@
         }
     }
 
-    static void assertKeySize(int expectedSizeBits, KeyPair keyPair) {
+    public static void assertKeySize(int expectedSizeBits, KeyPair keyPair) {
         assertEquals(expectedSizeBits, getKeySizeBits(keyPair.getPrivate()));
         assertEquals(expectedSizeBits, getKeySizeBits(keyPair.getPublic()));
     }
@@ -207,7 +218,7 @@
      * Asserts that the provided key pair is an Android Keystore key pair stored under the provided
      * alias.
      */
-    static void assertKeyStoreKeyPair(KeyStore keyStore, String alias, KeyPair keyPair) {
+    public static void assertKeyStoreKeyPair(KeyStore keyStore, String alias, KeyPair keyPair) {
         assertKeyMaterialExportable(keyPair.getPublic());
         assertKeyMaterialNotExportable(keyPair.getPrivate());
         assertTransparentKey(keyPair.getPublic());
@@ -293,12 +304,12 @@
         }
     }
 
-    static void assertECParameterSpecEqualsIgnoreSeedIfNotPresent(
+    public static void assertECParameterSpecEqualsIgnoreSeedIfNotPresent(
             ECParameterSpec expected, ECParameterSpec actual) {
         assertECParameterSpecEqualsIgnoreSeedIfNotPresent(null, expected, actual);
     }
 
-    static void assertECParameterSpecEqualsIgnoreSeedIfNotPresent(String message,
+    public static void assertECParameterSpecEqualsIgnoreSeedIfNotPresent(String message,
             ECParameterSpec expected, ECParameterSpec actual) {
         EllipticCurve expectedCurve = expected.getCurve();
         EllipticCurve actualCurve = actual.getCurve();
@@ -319,7 +330,7 @@
         }
     }
 
-    static KeyInfo getKeyInfo(Key key) throws InvalidKeySpecException, NoSuchAlgorithmException,
+    public static KeyInfo getKeyInfo(Key key) throws InvalidKeySpecException, NoSuchAlgorithmException,
             NoSuchProviderException {
         if ((key instanceof PrivateKey) || (key instanceof PublicKey)) {
             return KeyFactory.getInstance(key.getAlgorithm(), "AndroidKeyStore")
@@ -332,11 +343,11 @@
         }
     }
 
-    static <T> void assertContentsInAnyOrder(Iterable<T> actual, T... expected) {
+    public static <T> void assertContentsInAnyOrder(Iterable<T> actual, T... expected) {
         assertContentsInAnyOrder(null, actual, expected);
     }
 
-    static <T> void assertContentsInAnyOrder(String message, Iterable<T> actual, T... expected) {
+    public static <T> void assertContentsInAnyOrder(String message, Iterable<T> actual, T... expected) {
         Map<T, Integer> actualFreq = getFrequencyTable(actual);
         Map<T, Integer> expectedFreq = getFrequencyTable(expected);
         if (actualFreq.equals(expectedFreq)) {
@@ -439,7 +450,7 @@
         Collections.sort((List<Comparable>)values);
     }
 
-    static String[] toLowerCase(String... values) {
+    public static String[] toLowerCase(String... values) {
         if (values == null) {
             return null;
         }
@@ -451,7 +462,7 @@
         return result;
     }
 
-    static PrivateKey getRawResPrivateKey(Context context, int resId) throws Exception {
+    public static PrivateKey getRawResPrivateKey(Context context, int resId) throws Exception {
         byte[] pkcs8EncodedForm;
         try (InputStream in = context.getResources().openRawResource(resId)) {
             pkcs8EncodedForm = drain(in);
@@ -469,14 +480,14 @@
         }
     }
 
-    static X509Certificate getRawResX509Certificate(Context context, int resId) throws Exception {
+    public static X509Certificate getRawResX509Certificate(Context context, int resId) throws Exception {
         try (InputStream in = context.getResources().openRawResource(resId)) {
             return (X509Certificate) CertificateFactory.getInstance("X.509")
                     .generateCertificate(in);
         }
     }
 
-    static KeyPair importIntoAndroidKeyStore(
+    public static KeyPair importIntoAndroidKeyStore(
             String alias,
             PrivateKey privateKey,
             Certificate certificate,
@@ -491,7 +502,7 @@
                 (PrivateKey) keyStore.getKey(alias, null));
     }
 
-    static ImportedKey importIntoAndroidKeyStore(
+    public static ImportedKey importIntoAndroidKeyStore(
             String alias,
             SecretKey key,
             KeyProtection keyProtection) throws Exception {
@@ -503,7 +514,7 @@
         return new ImportedKey(alias, key, (SecretKey) keyStore.getKey(alias, null));
     }
 
-    static ImportedKey importIntoAndroidKeyStore(
+    public static ImportedKey importIntoAndroidKeyStore(
             String alias, Context context, int privateResId, int certResId, KeyProtection params)
                     throws Exception {
         Certificate originalCert = TestUtils.getRawResX509Certificate(context, certResId);
@@ -531,7 +542,7 @@
                 keystoreBacked);
     }
 
-    static byte[] drain(InputStream in) throws IOException {
+    public static byte[] drain(InputStream in) throws IOException {
         ByteArrayOutputStream result = new ByteArrayOutputStream();
         byte[] buffer = new byte[16 * 1024];
         int chunkSize;
@@ -541,20 +552,20 @@
         return result.toByteArray();
     }
 
-    static KeyProtection.Builder buildUpon(KeyProtection params) {
+    public static KeyProtection.Builder buildUpon(KeyProtection params) {
         return buildUponInternal(params, null);
     }
 
-    static KeyProtection.Builder buildUpon(KeyProtection params, int newPurposes) {
+    public static KeyProtection.Builder buildUpon(KeyProtection params, int newPurposes) {
         return buildUponInternal(params, newPurposes);
     }
 
-    static KeyProtection.Builder buildUpon(
+    public static KeyProtection.Builder buildUpon(
             KeyProtection.Builder builder) {
         return buildUponInternal(builder.build(), null);
     }
 
-    static KeyProtection.Builder buildUpon(
+    public static KeyProtection.Builder buildUpon(
             KeyProtection.Builder builder, int newPurposes) {
         return buildUponInternal(builder.build(), newPurposes);
     }
@@ -580,20 +591,20 @@
         return result;
     }
 
-    static KeyGenParameterSpec.Builder buildUpon(KeyGenParameterSpec spec) {
+    public static KeyGenParameterSpec.Builder buildUpon(KeyGenParameterSpec spec) {
         return buildUponInternal(spec, null);
     }
 
-    static KeyGenParameterSpec.Builder buildUpon(KeyGenParameterSpec spec, int newPurposes) {
+    public static KeyGenParameterSpec.Builder buildUpon(KeyGenParameterSpec spec, int newPurposes) {
         return buildUponInternal(spec, newPurposes);
     }
 
-    static KeyGenParameterSpec.Builder buildUpon(
+    public static KeyGenParameterSpec.Builder buildUpon(
             KeyGenParameterSpec.Builder builder) {
         return buildUponInternal(builder.build(), null);
     }
 
-    static KeyGenParameterSpec.Builder buildUpon(
+    public static KeyGenParameterSpec.Builder buildUpon(
             KeyGenParameterSpec.Builder builder, int newPurposes) {
         return buildUponInternal(builder.build(), newPurposes);
     }
@@ -629,7 +640,7 @@
         return result;
     }
 
-    static KeyPair getKeyPairForKeyAlgorithm(String keyAlgorithm, Iterable<KeyPair> keyPairs) {
+    public static KeyPair getKeyPairForKeyAlgorithm(String keyAlgorithm, Iterable<KeyPair> keyPairs) {
         for (KeyPair keyPair : keyPairs) {
             if (keyAlgorithm.equalsIgnoreCase(keyPair.getPublic().getAlgorithm())) {
                 return keyPair;
@@ -638,7 +649,7 @@
         throw new IllegalArgumentException("No KeyPair for key algorithm " + keyAlgorithm);
     }
 
-    static Key getKeyForKeyAlgorithm(String keyAlgorithm, Iterable<? extends Key> keys) {
+    public static Key getKeyForKeyAlgorithm(String keyAlgorithm, Iterable<? extends Key> keys) {
         for (Key key : keys) {
             if (keyAlgorithm.equalsIgnoreCase(key.getAlgorithm())) {
                 return key;
@@ -647,7 +658,7 @@
         throw new IllegalArgumentException("No Key for key algorithm " + keyAlgorithm);
     }
 
-    static byte[] generateLargeKatMsg(byte[] seed, int msgSizeBytes) throws Exception {
+    public static byte[] generateLargeKatMsg(byte[] seed, int msgSizeBytes) throws Exception {
         byte[] result = new byte[msgSizeBytes];
         MessageDigest digest = MessageDigest.getInstance("SHA-512");
         int resultOffset = 0;
@@ -662,7 +673,7 @@
         return result;
     }
 
-    static byte[] leftPadWithZeroBytes(byte[] array, int length) {
+    public static byte[] leftPadWithZeroBytes(byte[] array, int length) {
         if (array.length >= length) {
             return array;
         }
@@ -671,7 +682,7 @@
         return result;
     }
 
-    static boolean contains(int[] array, int value) {
+    public static boolean contains(int[] array, int value) {
         for (int element : array) {
             if (element == value) {
                 return true;
@@ -680,11 +691,11 @@
         return false;
     }
 
-    static boolean isHmacAlgorithm(String algorithm) {
+    public static boolean isHmacAlgorithm(String algorithm) {
         return algorithm.toUpperCase(Locale.US).startsWith("HMAC");
     }
 
-    static String getHmacAlgorithmDigest(String algorithm) {
+    public static String getHmacAlgorithmDigest(String algorithm) {
         String algorithmUpperCase = algorithm.toUpperCase(Locale.US);
         if (!algorithmUpperCase.startsWith("HMAC")) {
             return null;
@@ -696,7 +707,7 @@
         return result;
     }
 
-    static String getKeyAlgorithm(String transformation) {
+    public static String getKeyAlgorithm(String transformation) {
         try {
             return getCipherKeyAlgorithm(transformation);
         } catch (IllegalArgumentException e) {
@@ -736,7 +747,7 @@
         throw new IllegalArgumentException("Unsupported transformation: " + transformation);
     }
 
-    static String getCipherKeyAlgorithm(String transformation) {
+    public static String getCipherKeyAlgorithm(String transformation) {
         String transformationUpperCase = transformation.toUpperCase(Locale.US);
         if (transformationUpperCase.startsWith("AES/")) {
             return KeyProperties.KEY_ALGORITHM_AES;
@@ -749,7 +760,7 @@
         }
     }
 
-    static boolean isCipherSymmetric(String transformation) {
+    public static boolean isCipherSymmetric(String transformation) {
         String transformationUpperCase = transformation.toUpperCase(Locale.US);
         if (transformationUpperCase.startsWith("AES/") || transformationUpperCase.startsWith(
                 "DESEDE/")) {
@@ -761,7 +772,7 @@
         }
     }
 
-    static String getCipherDigest(String transformation) {
+    public static String getCipherDigest(String transformation) {
         String transformationUpperCase = transformation.toUpperCase(Locale.US);
         if (transformationUpperCase.contains("/OAEP")) {
             if (transformationUpperCase.endsWith("/OAEPPADDING")) {
@@ -790,7 +801,7 @@
         }
     }
 
-    static String getCipherEncryptionPadding(String transformation) {
+    public static String getCipherEncryptionPadding(String transformation) {
         String transformationUpperCase = transformation.toUpperCase(Locale.US);
         if (transformationUpperCase.endsWith("/NOPADDING")) {
             return KeyProperties.ENCRYPTION_PADDING_NONE;
@@ -805,11 +816,11 @@
         }
     }
 
-    static String getCipherBlockMode(String transformation) {
+    public static String getCipherBlockMode(String transformation) {
         return transformation.split("/")[1].toUpperCase(Locale.US);
     }
 
-    static String getSignatureAlgorithmDigest(String algorithm) {
+    public static String getSignatureAlgorithmDigest(String algorithm) {
         String algorithmUpperCase = algorithm.toUpperCase(Locale.US);
         int withIndex = algorithmUpperCase.indexOf("WITH");
         if (withIndex == -1) {
@@ -822,7 +833,7 @@
         return digest;
     }
 
-    static String getSignatureAlgorithmPadding(String algorithm) {
+    public static String getSignatureAlgorithmPadding(String algorithm) {
         String algorithmUpperCase = algorithm.toUpperCase(Locale.US);
         if (algorithmUpperCase.endsWith("WITHECDSA")) {
             return null;
@@ -835,7 +846,7 @@
         }
     }
 
-    static String getSignatureAlgorithmKeyAlgorithm(String algorithm) {
+    public static String getSignatureAlgorithmKeyAlgorithm(String algorithm) {
         String algorithmUpperCase = algorithm.toUpperCase(Locale.US);
         if (algorithmUpperCase.endsWith("WITHECDSA")) {
             return KeyProperties.KEY_ALGORITHM_EC;
@@ -847,7 +858,7 @@
         }
     }
 
-    static boolean isKeyLongEnoughForSignatureAlgorithm(String algorithm, int keySizeBits) {
+    public static boolean isKeyLongEnoughForSignatureAlgorithm(String algorithm, int keySizeBits) {
         String keyAlgorithm = getSignatureAlgorithmKeyAlgorithm(algorithm);
         if (KeyProperties.KEY_ALGORITHM_EC.equalsIgnoreCase(keyAlgorithm)) {
             // No length restrictions for ECDSA
@@ -878,11 +889,11 @@
         }
     }
 
-    static boolean isKeyLongEnoughForSignatureAlgorithm(String algorithm, Key key) {
+    public static boolean isKeyLongEnoughForSignatureAlgorithm(String algorithm, Key key) {
         return isKeyLongEnoughForSignatureAlgorithm(algorithm, getKeySizeBits(key));
     }
 
-    static int getMaxSupportedPlaintextInputSizeBytes(String transformation, int keySizeBits) {
+    public static int getMaxSupportedPlaintextInputSizeBytes(String transformation, int keySizeBits) {
         String encryptionPadding = getCipherEncryptionPadding(transformation);
         int modulusSizeBytes = (keySizeBits + 7) / 8;
         if (KeyProperties.ENCRYPTION_PADDING_NONE.equalsIgnoreCase(encryptionPadding)) {
@@ -902,7 +913,7 @@
 
     }
 
-    static int getMaxSupportedPlaintextInputSizeBytes(String transformation, Key key) {
+    public static int getMaxSupportedPlaintextInputSizeBytes(String transformation, Key key) {
         String keyAlgorithm = getCipherKeyAlgorithm(transformation);
         if (KeyProperties.KEY_ALGORITHM_AES.equalsIgnoreCase(keyAlgorithm)
                 || KeyProperties.KEY_ALGORITHM_3DES.equalsIgnoreCase(keyAlgorithm)) {
@@ -914,7 +925,7 @@
         }
     }
 
-    static int getDigestOutputSizeBits(String digest) {
+    public static int getDigestOutputSizeBits(String digest) {
         if (KeyProperties.DIGEST_NONE.equals(digest)) {
             return -1;
         } else if (KeyProperties.DIGEST_MD5.equals(digest)) {
@@ -934,12 +945,12 @@
         }
     }
 
-    static byte[] concat(byte[] arr1, byte[] arr2) {
+    public static byte[] concat(byte[] arr1, byte[] arr2) {
         return concat(arr1, 0, (arr1 != null) ? arr1.length : 0,
                 arr2, 0, (arr2 != null) ? arr2.length : 0);
     }
 
-    static byte[] concat(byte[] arr1, int offset1, int len1,
+    public static byte[] concat(byte[] arr1, int offset1, int len1,
             byte[] arr2, int offset2, int len2) {
         if (len1 == 0) {
             return subarray(arr2, offset2, len2);
@@ -956,7 +967,7 @@
         return result;
     }
 
-    static byte[] subarray(byte[] arr, int offset, int len) {
+    public static byte[] subarray(byte[] arr, int offset, int len) {
         if (len == 0) {
             return EmptyArray.BYTE;
         }
@@ -968,7 +979,7 @@
         return result;
     }
 
-    static KeyProtection getMinimalWorkingImportParametersForSigningingWith(
+    public static KeyProtection getMinimalWorkingImportParametersForSigningingWith(
             String signatureAlgorithm) {
         String keyAlgorithm = getSignatureAlgorithmKeyAlgorithm(signatureAlgorithm);
         String digest = getSignatureAlgorithmDigest(signatureAlgorithm);
@@ -988,7 +999,7 @@
         }
     }
 
-    static KeyProtection getMinimalWorkingImportParametersWithLimitedUsageForSigningingWith(
+    public static KeyProtection getMinimalWorkingImportParametersWithLimitedUsageForSigningingWith(
             String signatureAlgorithm, int maxUsageCount) {
         String keyAlgorithm = getSignatureAlgorithmKeyAlgorithm(signatureAlgorithm);
         String digest = getSignatureAlgorithmDigest(signatureAlgorithm);
@@ -1010,18 +1021,18 @@
         }
     }
 
-    static KeyProtection getMinimalWorkingImportParametersForCipheringWith(
+    public static KeyProtection getMinimalWorkingImportParametersForCipheringWith(
             String transformation, int purposes) {
         return getMinimalWorkingImportParametersForCipheringWith(transformation, purposes, false);
     }
 
-    static KeyProtection getMinimalWorkingImportParametersForCipheringWith(
+    public static KeyProtection getMinimalWorkingImportParametersForCipheringWith(
             String transformation, int purposes, boolean ivProvidedWhenEncrypting) {
         return getMinimalWorkingImportParametersForCipheringWith(transformation, purposes,
             ivProvidedWhenEncrypting, false, false);
     }
 
-    static KeyProtection getMinimalWorkingImportParametersForCipheringWith(
+    public static KeyProtection getMinimalWorkingImportParametersForCipheringWith(
             String transformation, int purposes, boolean ivProvidedWhenEncrypting,
             boolean isUnlockedDeviceRequired, boolean isUserAuthRequired) {
         String keyAlgorithm = TestUtils.getCipherKeyAlgorithm(transformation);
@@ -1064,7 +1075,7 @@
         }
     }
 
-    static byte[] getBigIntegerMagnitudeBytes(BigInteger value) {
+    public static byte[] getBigIntegerMagnitudeBytes(BigInteger value) {
         return removeLeadingZeroByteIfPresent(value.toByteArray());
     }
 
@@ -1075,7 +1086,7 @@
         return TestUtils.subarray(value, 1, value.length - 1);
     }
 
-    static byte[] generateRandomMessage(int messageSize) {
+    public static byte[] generateRandomMessage(int messageSize) {
         byte[] message = new byte[messageSize];
         new SecureRandom().nextBytes(message);
         return message;