Add methods to return supported algorithms

This CL adds methods to return supported crypto algortihms
for IKE and Child SA proposal

Bug: 157577190
Test: FrameworksIkeTests(new tests added)
Change-Id: I5eab8653401b7594e5fa6ba868e3a23f1d8a669f
diff --git a/Android.bp b/Android.bp
index 3ac8f3e..c5adaf4 100644
--- a/Android.bp
+++ b/Android.bp
@@ -85,8 +85,10 @@
         "com.android.ipsec",
         "test_com.android.ipsec",
     ],
-    static_libs: ["bouncycastle_ike_digests"],
-    sdk_version: "core_current",
+    static_libs: [
+        "bouncycastle_ike_digests",
+        "modules-utils-build",],
+    sdk_version: "module_current",
 }
 
 java_library {
diff --git a/jarjar-rules-shared.txt b/jarjar-rules-shared.txt
index 1548696..7d3bea4 100644
--- a/jarjar-rules-shared.txt
+++ b/jarjar-rules-shared.txt
@@ -3,4 +3,5 @@
 rule android.telephony.Annotation* com.android.internal.net.eap.telephony.Annotation@1
 rule com.android.server.vcn.util.PersistableBundleUtils* com.android.internal.net.vcn.util.PersistableBundleUtils@1
 rule com.android.internal.util.** com.android.internal.net.ipsec.ike.utils.@1
+rule com.android.modules.utils.** com.android.internal.net.utils.@1
 rule org.bouncycastle.** com.android.internal.net.org.bouncycastle.@1
diff --git a/src/java/android/net/ipsec/ike/ChildSaProposal.java b/src/java/android/net/ipsec/ike/ChildSaProposal.java
index 1e3af9a..212c5d4 100644
--- a/src/java/android/net/ipsec/ike/ChildSaProposal.java
+++ b/src/java/android/net/ipsec/ike/ChildSaProposal.java
@@ -20,19 +20,25 @@
 
 import android.annotation.NonNull;
 import android.annotation.SuppressLint;
+import android.net.IpSecAlgorithm;
 import android.os.PersistableBundle;
+import android.util.ArraySet;
 
+import com.android.internal.net.ipsec.ike.crypto.IkeCipher;
+import com.android.internal.net.ipsec.ike.crypto.IkeMacIntegrity;
 import com.android.internal.net.ipsec.ike.message.IkePayload;
 import com.android.internal.net.ipsec.ike.message.IkeSaPayload.DhGroupTransform;
 import com.android.internal.net.ipsec.ike.message.IkeSaPayload.EncryptionTransform;
 import com.android.internal.net.ipsec.ike.message.IkeSaPayload.EsnTransform;
 import com.android.internal.net.ipsec.ike.message.IkeSaPayload.IntegrityTransform;
 import com.android.internal.net.ipsec.ike.message.IkeSaPayload.Transform;
+import com.android.modules.utils.build.SdkLevel;
 import com.android.server.vcn.util.PersistableBundleUtils;
 
 import java.util.Arrays;
 import java.util.List;
 import java.util.Objects;
+import java.util.Set;
 
 /**
  * ChildSaProposal represents a proposed configuration to negotiate a Child SA.
@@ -46,6 +52,25 @@
  *     Protocol Version 2 (IKEv2)</a>
  */
 public final class ChildSaProposal extends SaProposal {
+    // Before SDK S, there is no API in IpSecAlgorithm to retrieve supported algorithms. Thus hard
+    // coded these algorithms here.
+    private static final Set<Integer> SUPPORTED_IPSEC_ENCRYPTION_BEFORE_SDK_S;
+    private static final Set<Integer> SUPPORTED_IPSEC_INTEGRITY_BEFORE_SDK_S;
+
+    static {
+        SUPPORTED_IPSEC_ENCRYPTION_BEFORE_SDK_S = new ArraySet<>();
+        SUPPORTED_IPSEC_ENCRYPTION_BEFORE_SDK_S.add(ENCRYPTION_ALGORITHM_AES_CBC);
+        SUPPORTED_IPSEC_ENCRYPTION_BEFORE_SDK_S.add(ENCRYPTION_ALGORITHM_AES_GCM_8);
+        SUPPORTED_IPSEC_ENCRYPTION_BEFORE_SDK_S.add(ENCRYPTION_ALGORITHM_AES_GCM_12);
+        SUPPORTED_IPSEC_ENCRYPTION_BEFORE_SDK_S.add(ENCRYPTION_ALGORITHM_AES_GCM_16);
+
+        SUPPORTED_IPSEC_INTEGRITY_BEFORE_SDK_S = new ArraySet<>();
+        SUPPORTED_IPSEC_INTEGRITY_BEFORE_SDK_S.add(INTEGRITY_ALGORITHM_HMAC_SHA1_96);
+        SUPPORTED_IPSEC_INTEGRITY_BEFORE_SDK_S.add(INTEGRITY_ALGORITHM_HMAC_SHA2_256_128);
+        SUPPORTED_IPSEC_INTEGRITY_BEFORE_SDK_S.add(INTEGRITY_ALGORITHM_HMAC_SHA2_384_192);
+        SUPPORTED_IPSEC_INTEGRITY_BEFORE_SDK_S.add(INTEGRITY_ALGORITHM_HMAC_SHA2_512_256);
+    }
+
     private static final String ESN_KEY = "mEsns";
     private final EsnTransform[] mEsns;
 
@@ -139,6 +164,61 @@
     }
 
     /**
+     * Returns supported encryption algorithms for Child SA proposal negotiation.
+     *
+     * <p>Some algorithms may not be supported on old devices. Callers MUST check if an algorithm is
+     * supported before using it.
+     *
+     * @hide
+     */
+    @NonNull
+    public static Set<Integer> getSupportedEncryptionAlgorithms() {
+        if (SdkLevel.isAtLeastS()) {
+            Set<Integer> algoIds = new ArraySet<>();
+            for (int i = 0; i < SUPPORTED_ENCRYPTION_ALGO_TO_STR.size(); i++) {
+                int ikeAlgoId = SUPPORTED_ENCRYPTION_ALGO_TO_STR.keyAt(i);
+                String ipSecAlgoName = IkeCipher.getIpSecAlgorithmName(ikeAlgoId);
+                if (IpSecAlgorithm.getSupportedAlgorithms().contains(ipSecAlgoName)) {
+                    algoIds.add(ikeAlgoId);
+                }
+            }
+            return algoIds;
+        } else {
+            return SUPPORTED_IPSEC_ENCRYPTION_BEFORE_SDK_S;
+        }
+    }
+
+    /**
+     * Returns supported integrity algorithms for Child SA proposal negotiation.
+     *
+     * <p>Some algorithms may not be supported on old devices. Callers MUST check if an algorithm is
+     * supported before using it.
+     *
+     * @hide
+     */
+    @NonNull
+    public static Set<Integer> getSupportedIntegrityAlgorithms() {
+        Set<Integer> algoIds = new ArraySet<>();
+
+        // Although IpSecAlgorithm does not support INTEGRITY_ALGORITHM_NONE, IKE supports
+        // negotiating it and won't build IpSecAlgorithm with it.
+        algoIds.add(INTEGRITY_ALGORITHM_NONE);
+
+        if (SdkLevel.isAtLeastS()) {
+            for (int i = 0; i < SUPPORTED_INTEGRITY_ALGO_TO_STR.size(); i++) {
+                int ikeAlgoId = SUPPORTED_INTEGRITY_ALGO_TO_STR.keyAt(i);
+                String ipSecAlgoName = IkeMacIntegrity.getIpSecAlgorithmName(ikeAlgoId);
+                if (IpSecAlgorithm.getSupportedAlgorithms().contains(ipSecAlgoName)) {
+                    algoIds.add(ikeAlgoId);
+                }
+            }
+        } else {
+            algoIds.addAll(SUPPORTED_IPSEC_INTEGRITY_BEFORE_SDK_S);
+        }
+        return algoIds;
+    }
+
+    /**
      * Gets all ESN policies.
      *
      * @hide
diff --git a/src/java/android/net/ipsec/ike/IkeSaProposal.java b/src/java/android/net/ipsec/ike/IkeSaProposal.java
index 7b93963..277cdd5 100644
--- a/src/java/android/net/ipsec/ike/IkeSaProposal.java
+++ b/src/java/android/net/ipsec/ike/IkeSaProposal.java
@@ -132,6 +132,36 @@
     }
 
     /**
+     * Returns supported encryption algorithms for IKE SA proposal negotiation.
+     *
+     * @hide
+     */
+    @NonNull
+    public static Set<Integer> getSupportedEncryptionAlgorithms() {
+        return getKeySet(SUPPORTED_ENCRYPTION_ALGO_TO_STR);
+    }
+
+    /**
+     * Returns supported integrity algorithms for IKE SA proposal negotiation.
+     *
+     * @hide
+     */
+    @NonNull
+    public static Set<Integer> getSupportedIntegrityAlgorithms() {
+        return getKeySet(SUPPORTED_INTEGRITY_ALGO_TO_STR);
+    }
+
+    /**
+     * Returns supported pseudorandom functions for IKE SA proposal negotiation.
+     *
+     * @hide
+     */
+    @NonNull
+    public static Set<Integer> getSupportedPseudorandomFunctions() {
+        return getKeySet(SUPPORTED_PRF_TO_STR);
+    }
+
+    /**
      * Gets all proposed Pseudorandom Functions
      *
      * @return A list of the IANA-defined IDs for the proposed Pseudorandom Functions
diff --git a/src/java/android/net/ipsec/ike/SaProposal.java b/src/java/android/net/ipsec/ike/SaProposal.java
index 2669d68..4cc3338 100644
--- a/src/java/android/net/ipsec/ike/SaProposal.java
+++ b/src/java/android/net/ipsec/ike/SaProposal.java
@@ -34,10 +34,12 @@
 import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.HashSet;
 import java.util.LinkedHashSet;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Objects;
+import java.util.Set;
 
 /**
  * SaProposal represents a proposed configuration to negotiate an IKE or Child SA.
@@ -91,7 +93,8 @@
      */
     public static final int ENCRYPTION_ALGORITHM_CHACHA20_POLY1305 = 28;
 
-    private static final SparseArray<String> SUPPORTED_ENCRYPTION_ALGO_TO_STR;
+    /** @hide */
+    protected static final SparseArray<String> SUPPORTED_ENCRYPTION_ALGO_TO_STR;
 
     static {
         SUPPORTED_ENCRYPTION_ALGO_TO_STR = new SparseArray<>();
@@ -141,7 +144,8 @@
     /** HMAC-SHA2-384 Pseudorandom Function. */
     public static final int PSEUDORANDOM_FUNCTION_SHA2_512 = 7;
 
-    private static final SparseArray<String> SUPPORTED_PRF_TO_STR;
+    /** @hide */
+    protected static final SparseArray<String> SUPPORTED_PRF_TO_STR;
 
     static {
         SUPPORTED_PRF_TO_STR = new SparseArray<>();
@@ -177,7 +181,8 @@
     /** HMAC-SHA512 Authentication/Integrity Algorithm with 256-bit truncation. */
     public static final int INTEGRITY_ALGORITHM_HMAC_SHA2_512_256 = 14;
 
-    private static final SparseArray<String> SUPPORTED_INTEGRITY_ALGO_TO_STR;
+    /** @hide */
+    protected static final SparseArray<String> SUPPORTED_INTEGRITY_ALGO_TO_STR;
 
     static {
         SUPPORTED_INTEGRITY_ALGO_TO_STR = new SparseArray<>();
@@ -586,48 +591,24 @@
                 && Arrays.equals(mDhGroups, other.mDhGroups);
     }
 
-    /**
-     * Check if the provided algorithm is a supported encryption algorithm.
-     *
-     * @param algorithm IKE standard encryption algorithm id.
-     * @return true if the provided algorithm is a supported encryption algorithm.
-     * @hide
-     */
-    public static boolean isSupportedEncryptionAlgorithm(@EncryptionAlgorithm int algorithm) {
-        return SUPPORTED_ENCRYPTION_ALGO_TO_STR.get(algorithm) != null;
+    /** @hide */
+    protected static Set<Integer> getKeySet(SparseArray array) {
+        Set<Integer> result = new HashSet<>();
+        for (int i = 0; i < array.size(); i++) {
+            result.add(array.keyAt(i));
+        }
+
+        return result;
     }
 
     /**
-     * Check if the provided algorithm is a supported pseudorandom function.
+     * Returns supported DH groups for IKE and Child SA proposal negotiation.
      *
-     * @param algorithm IKE standard pseudorandom function id.
-     * @return true if the provided algorithm is a supported pseudorandom function.
      * @hide
      */
-    public static boolean isSupportedPseudorandomFunction(@PseudorandomFunction int algorithm) {
-        return SUPPORTED_PRF_TO_STR.get(algorithm) != null;
-    }
-
-    /**
-     * Check if the provided algorithm is a supported integrity algorithm.
-     *
-     * @param algorithm IKE standard integrity algorithm id.
-     * @return true if the provided algorithm is a supported integrity algorithm.
-     * @hide
-     */
-    public static boolean isSupportedIntegrityAlgorithm(@IntegrityAlgorithm int algorithm) {
-        return SUPPORTED_INTEGRITY_ALGO_TO_STR.get(algorithm) != null;
-    }
-
-    /**
-     * Check if the provided group number is for a supported Diffie-Hellman Group.
-     *
-     * @param dhGroup IKE standard DH Group id.
-     * @return true if the provided number is for a supported Diffie-Hellman Group.
-     * @hide
-     */
-    public static boolean isSupportedDhGroup(@DhGroup int dhGroup) {
-        return SUPPORTED_DH_GROUP_TO_STR.get(dhGroup) != null;
+    @NonNull
+    public static Set<Integer> getSupportedDhGroups() {
+        return getKeySet(SUPPORTED_DH_GROUP_TO_STR);
     }
 
     /**
@@ -636,7 +617,7 @@
      * @hide
      */
     public static String getEncryptionAlgorithmString(int algorithm) {
-        if (isSupportedEncryptionAlgorithm(algorithm)) {
+        if (SUPPORTED_ENCRYPTION_ALGO_TO_STR.contains(algorithm)) {
             return SUPPORTED_ENCRYPTION_ALGO_TO_STR.get(algorithm);
         }
         return "ENC_Unknown_" + algorithm;
@@ -648,7 +629,7 @@
      * @hide
      */
     public static String getPseudorandomFunctionString(int algorithm) {
-        if (isSupportedPseudorandomFunction(algorithm)) {
+        if (SUPPORTED_PRF_TO_STR.contains(algorithm)) {
             return SUPPORTED_PRF_TO_STR.get(algorithm);
         }
         return "PRF_Unknown_" + algorithm;
@@ -660,7 +641,7 @@
      * @hide
      */
     public static String getIntegrityAlgorithmString(int algorithm) {
-        if (isSupportedIntegrityAlgorithm(algorithm)) {
+        if (SUPPORTED_PRF_TO_STR.contains(algorithm)) {
             return SUPPORTED_INTEGRITY_ALGO_TO_STR.get(algorithm);
         }
         return "AUTH_Unknown_" + algorithm;
@@ -672,7 +653,7 @@
      * @hide
      */
     public static String getDhGroupString(int dhGroup) {
-        if (isSupportedDhGroup(dhGroup)) {
+        if (SUPPORTED_DH_GROUP_TO_STR.contains(dhGroup)) {
             return SUPPORTED_DH_GROUP_TO_STR.get(dhGroup);
         }
         return "DH_Unknown_" + dhGroup;
diff --git a/src/java/com/android/internal/net/ipsec/ike/message/IkeSaPayload.java b/src/java/com/android/internal/net/ipsec/ike/message/IkeSaPayload.java
index 277d248..7f3529a 100644
--- a/src/java/com/android/internal/net/ipsec/ike/message/IkeSaPayload.java
+++ b/src/java/com/android/internal/net/ipsec/ike/message/IkeSaPayload.java
@@ -1224,7 +1224,8 @@
 
         @Override
         protected boolean isSupportedTransformId(int id) {
-            return SaProposal.isSupportedEncryptionAlgorithm(id);
+            return IkeSaProposal.getSupportedEncryptionAlgorithms().contains(id)
+                    || ChildSaProposal.getSupportedEncryptionAlgorithms().contains(id);
         }
 
         @Override
@@ -1374,7 +1375,7 @@
 
         @Override
         protected boolean isSupportedTransformId(int id) {
-            return SaProposal.isSupportedPseudorandomFunction(id);
+            return IkeSaProposal.getSupportedPseudorandomFunctions().contains(id);
         }
 
         @Override
@@ -1455,7 +1456,8 @@
 
         @Override
         protected boolean isSupportedTransformId(int id) {
-            return SaProposal.isSupportedIntegrityAlgorithm(id);
+            return IkeSaProposal.getSupportedIntegrityAlgorithms().contains(id)
+                    || ChildSaProposal.getSupportedIntegrityAlgorithms().contains(id);
         }
 
         @Override
@@ -1536,7 +1538,7 @@
 
         @Override
         protected boolean isSupportedTransformId(int id) {
-            return SaProposal.isSupportedDhGroup(id);
+            return SaProposal.getSupportedDhGroups().contains(id);
         }
 
         @Override
diff --git a/tests/iketests/src/java/android/net/ipsec/ike/SaProposalTest.java b/tests/iketests/src/java/android/net/ipsec/ike/SaProposalTest.java
index 89d7343..1e91d5e 100644
--- a/tests/iketests/src/java/android/net/ipsec/ike/SaProposalTest.java
+++ b/tests/iketests/src/java/android/net/ipsec/ike/SaProposalTest.java
@@ -17,32 +17,58 @@
 package android.net.ipsec.ike;
 
 import static android.net.ipsec.ike.SaProposal.DH_GROUP_1024_BIT_MODP;
+import static android.net.ipsec.ike.SaProposal.DH_GROUP_1536_BIT_MODP;
 import static android.net.ipsec.ike.SaProposal.DH_GROUP_2048_BIT_MODP;
+import static android.net.ipsec.ike.SaProposal.DH_GROUP_3072_BIT_MODP;
+import static android.net.ipsec.ike.SaProposal.DH_GROUP_4096_BIT_MODP;
+import static android.net.ipsec.ike.SaProposal.DH_GROUP_NONE;
+import static android.net.ipsec.ike.SaProposal.ENCRYPTION_ALGORITHM_3DES;
+import static android.net.ipsec.ike.SaProposal.ENCRYPTION_ALGORITHM_AES_CBC;
+import static android.net.ipsec.ike.SaProposal.ENCRYPTION_ALGORITHM_AES_CTR;
 import static android.net.ipsec.ike.SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_12;
+import static android.net.ipsec.ike.SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_16;
 import static android.net.ipsec.ike.SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_8;
+import static android.net.ipsec.ike.SaProposal.ENCRYPTION_ALGORITHM_CHACHA20_POLY1305;
+import static android.net.ipsec.ike.SaProposal.INTEGRITY_ALGORITHM_AES_XCBC_96;
+import static android.net.ipsec.ike.SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA1_96;
+import static android.net.ipsec.ike.SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA2_256_128;
+import static android.net.ipsec.ike.SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA2_384_192;
+import static android.net.ipsec.ike.SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA2_512_256;
 import static android.net.ipsec.ike.SaProposal.INTEGRITY_ALGORITHM_NONE;
 import static android.net.ipsec.ike.SaProposal.KEY_LEN_AES_128;
 import static android.net.ipsec.ike.SaProposal.KEY_LEN_UNUSED;
 import static android.net.ipsec.ike.SaProposal.PSEUDORANDOM_FUNCTION_AES128_XCBC;
+import static android.net.ipsec.ike.SaProposal.PSEUDORANDOM_FUNCTION_HMAC_SHA1;
 import static android.net.ipsec.ike.SaProposal.PSEUDORANDOM_FUNCTION_SHA2_256;
+import static android.net.ipsec.ike.SaProposal.PSEUDORANDOM_FUNCTION_SHA2_384;
+import static android.net.ipsec.ike.SaProposal.PSEUDORANDOM_FUNCTION_SHA2_512;
 
 import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
+import static org.junit.Assume.assumeFalse;
+import static org.junit.Assume.assumeTrue;
 
+import android.net.IpSecAlgorithm;
 import android.os.PersistableBundle;
 
+import com.android.internal.net.ipsec.ike.crypto.IkeCipher;
+import com.android.internal.net.ipsec.ike.crypto.IkeMacIntegrity;
 import com.android.internal.net.ipsec.ike.message.IkePayload;
 import com.android.internal.net.ipsec.ike.message.IkeSaPayload.DhGroupTransform;
 import com.android.internal.net.ipsec.ike.message.IkeSaPayload.EncryptionTransform;
 import com.android.internal.net.ipsec.ike.message.IkeSaPayload.IntegrityTransform;
 import com.android.internal.net.ipsec.ike.message.IkeSaPayload.PrfTransform;
 import com.android.internal.net.ipsec.ike.message.IkeSaPayload.Transform;
+import com.android.internal.net.utils.build.SdkLevel;
 
 import org.junit.Test;
 
+import java.util.HashSet;
+import java.util.Set;
+
 public final class SaProposalTest {
     private final EncryptionTransform mEncryption3DesTransform;
     private final EncryptionTransform mEncryptionAesGcm8Transform;
@@ -52,6 +78,23 @@
     private final PrfTransform mPrfAes128XCbcTransform;
     private final DhGroupTransform mDhGroup1024Transform;
 
+    private static final Set<Integer> SUPPORTED_IPSEC_ENCRYPTION_BEFORE_SDK_S;
+    private static final Set<Integer> SUPPORTED_IPSEC_INTEGRITY_BEFORE_SDK_S;
+
+    static {
+        SUPPORTED_IPSEC_ENCRYPTION_BEFORE_SDK_S = new HashSet<>();
+        SUPPORTED_IPSEC_ENCRYPTION_BEFORE_SDK_S.add(ENCRYPTION_ALGORITHM_AES_CBC);
+        SUPPORTED_IPSEC_ENCRYPTION_BEFORE_SDK_S.add(ENCRYPTION_ALGORITHM_AES_GCM_8);
+        SUPPORTED_IPSEC_ENCRYPTION_BEFORE_SDK_S.add(ENCRYPTION_ALGORITHM_AES_GCM_12);
+        SUPPORTED_IPSEC_ENCRYPTION_BEFORE_SDK_S.add(ENCRYPTION_ALGORITHM_AES_GCM_16);
+
+        SUPPORTED_IPSEC_INTEGRITY_BEFORE_SDK_S = new HashSet<>();
+        SUPPORTED_IPSEC_INTEGRITY_BEFORE_SDK_S.add(INTEGRITY_ALGORITHM_HMAC_SHA1_96);
+        SUPPORTED_IPSEC_INTEGRITY_BEFORE_SDK_S.add(INTEGRITY_ALGORITHM_HMAC_SHA2_256_128);
+        SUPPORTED_IPSEC_INTEGRITY_BEFORE_SDK_S.add(INTEGRITY_ALGORITHM_HMAC_SHA2_384_192);
+        SUPPORTED_IPSEC_INTEGRITY_BEFORE_SDK_S.add(INTEGRITY_ALGORITHM_HMAC_SHA2_512_256);
+    }
+
     public SaProposalTest() {
         mEncryption3DesTransform =
                 new EncryptionTransform(SaProposal.ENCRYPTION_ALGORITHM_3DES, KEY_LEN_UNUSED);
@@ -387,4 +430,112 @@
 
         assertTrue(respProposal.isNegotiatedFrom(reqProposal));
     }
+
+    @Test
+    public void testGetChildSupportedEncryptionAlgorithmsBeforeSdkS() {
+        assumeFalse(SdkLevel.isAtLeastS());
+
+        assertEquals(
+                SUPPORTED_IPSEC_ENCRYPTION_BEFORE_SDK_S,
+                ChildSaProposal.getSupportedEncryptionAlgorithms());
+    }
+
+    @Test
+    public void testGetChildSupportedEncryptionAlgorithmsAtLeastSdkS() {
+        assumeTrue(SdkLevel.isAtLeastS());
+
+        // It is not feasible to have a hard coded expected supported algorithm set because
+        // supported IPsec algorithms vary on different devices
+        for (int ikeAlgoId : ChildSaProposal.getSupportedEncryptionAlgorithms()) {
+            String ipSecAlgoName = IkeCipher.getIpSecAlgorithmName(ikeAlgoId);
+            assertTrue(IpSecAlgorithm.getSupportedAlgorithms().contains(ipSecAlgoName));
+        }
+
+        assertTrue(
+                ChildSaProposal.getSupportedEncryptionAlgorithms()
+                        .containsAll(SUPPORTED_IPSEC_ENCRYPTION_BEFORE_SDK_S));
+    }
+
+    @Test
+    public void testGetChildSupportedIntegrityAlgorithmsBeforeSdkS() {
+        assumeFalse(SdkLevel.isAtLeastS());
+
+        assertEquals(
+                SUPPORTED_IPSEC_INTEGRITY_BEFORE_SDK_S,
+                ChildSaProposal.getSupportedIntegrityAlgorithms());
+    }
+
+    @Test
+    public void testGetChildSupportedIntegrityAlgorithmsAtLeastSdkS() {
+        assumeTrue(SdkLevel.isAtLeastS());
+
+        // It is not feasible to have a hard coded expected supported algorithm set because
+        // supported IPsec algorithms vary on different devices
+        for (int ikeAlgoId : ChildSaProposal.getSupportedIntegrityAlgorithms()) {
+            if (ikeAlgoId != INTEGRITY_ALGORITHM_NONE) {
+                String ipSecAlgoName = IkeMacIntegrity.getIpSecAlgorithmName(ikeAlgoId);
+                assertTrue(IpSecAlgorithm.getSupportedAlgorithms().contains(ipSecAlgoName));
+            }
+        }
+
+        assertTrue(
+                ChildSaProposal.getSupportedIntegrityAlgorithms()
+                        .containsAll(SUPPORTED_IPSEC_INTEGRITY_BEFORE_SDK_S));
+    }
+
+    @Test
+    public void testGetIkeSupportedEncryptionAlgorithms() {
+        HashSet<Integer> expectedSet = new HashSet<>();
+        expectedSet = new HashSet<>();
+        expectedSet.add(ENCRYPTION_ALGORITHM_3DES);
+        expectedSet.add(ENCRYPTION_ALGORITHM_AES_CBC);
+        expectedSet.add(ENCRYPTION_ALGORITHM_AES_CTR);
+        expectedSet.add(ENCRYPTION_ALGORITHM_AES_GCM_8);
+        expectedSet.add(ENCRYPTION_ALGORITHM_AES_GCM_12);
+        expectedSet.add(ENCRYPTION_ALGORITHM_AES_GCM_16);
+        expectedSet.add(ENCRYPTION_ALGORITHM_CHACHA20_POLY1305);
+
+        assertEquals(expectedSet, IkeSaProposal.getSupportedEncryptionAlgorithms());
+    }
+
+    @Test
+    public void testGetIkeSupportedIntegrityAlgorithms() {
+        HashSet<Integer> expectedSet = new HashSet<>();
+        expectedSet = new HashSet<>();
+        expectedSet.add(INTEGRITY_ALGORITHM_NONE);
+        expectedSet.add(INTEGRITY_ALGORITHM_HMAC_SHA1_96);
+        expectedSet.add(INTEGRITY_ALGORITHM_AES_XCBC_96);
+        expectedSet.add(INTEGRITY_ALGORITHM_HMAC_SHA2_256_128);
+        expectedSet.add(INTEGRITY_ALGORITHM_HMAC_SHA2_384_192);
+        expectedSet.add(INTEGRITY_ALGORITHM_HMAC_SHA2_512_256);
+
+        assertEquals(expectedSet, IkeSaProposal.getSupportedIntegrityAlgorithms());
+    }
+
+    @Test
+    public void testGetIkeSupportedPrfs() {
+        HashSet<Integer> expectedSet = new HashSet<>();
+        expectedSet = new HashSet<>();
+        expectedSet.add(PSEUDORANDOM_FUNCTION_HMAC_SHA1);
+        expectedSet.add(PSEUDORANDOM_FUNCTION_AES128_XCBC);
+        expectedSet.add(PSEUDORANDOM_FUNCTION_SHA2_256);
+        expectedSet.add(PSEUDORANDOM_FUNCTION_SHA2_384);
+        expectedSet.add(PSEUDORANDOM_FUNCTION_SHA2_512);
+
+        assertEquals(expectedSet, IkeSaProposal.getSupportedPseudorandomFunctions());
+    }
+
+    @Test
+    public void testGetSupportedDhGroups() {
+        HashSet<Integer> expectedSet = new HashSet<>();
+        expectedSet = new HashSet<>();
+        expectedSet.add(DH_GROUP_NONE);
+        expectedSet.add(DH_GROUP_1024_BIT_MODP);
+        expectedSet.add(DH_GROUP_1536_BIT_MODP);
+        expectedSet.add(DH_GROUP_2048_BIT_MODP);
+        expectedSet.add(DH_GROUP_3072_BIT_MODP);
+        expectedSet.add(DH_GROUP_4096_BIT_MODP);
+
+        assertEquals(expectedSet, IkeSaProposal.getSupportedDhGroups());
+    }
 }