summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXin Li <delphij@google.com>2024-03-06 09:30:11 -0800
committerXin Li <delphij@google.com>2024-03-06 18:58:26 -0800
commit5f57fe08e747fcd1a412eb5c267d24ed72f57d2f (patch)
tree836b3110194878c625c0eb0e931c331cfba14d80
parent792a63cc312aebbbb05d0dec01d71b0e003ecf7f (diff)
parent22c3b71cea50647ef284d96927f5cf6397e92b82 (diff)
downloadIwlan-5f57fe08e747fcd1a412eb5c267d24ed72f57d2f.tar.gz
Merge Android 14 QPR2 to AOSP main
Bug: 319669529 Merged-In: I08485045eb01b813ca311adc8795f8d06a103c2f Change-Id: I7d53385b8b55b492d6a0e838eafeb25f9f5522a2
-rw-r--r--flags/main.aconfig18
-rw-r--r--src/com/google/android/iwlan/epdg/EpdgChildSaProposal.java79
-rw-r--r--src/com/google/android/iwlan/epdg/EpdgIkeSaProposal.java117
-rw-r--r--src/com/google/android/iwlan/epdg/EpdgSaProposal.java329
-rw-r--r--src/com/google/android/iwlan/epdg/EpdgSelector.java3
-rw-r--r--src/com/google/android/iwlan/epdg/EpdgTunnelManager.java289
-rw-r--r--test/com/google/android/iwlan/epdg/EpdgTunnelManagerTest.java204
7 files changed, 1037 insertions, 2 deletions
diff --git a/flags/main.aconfig b/flags/main.aconfig
index 795ffbd..57b0527 100644
--- a/flags/main.aconfig
+++ b/flags/main.aconfig
@@ -8,6 +8,24 @@ flag {
bug: "278788983"
}
flag {
+ name: "aead_algos_enabled"
+ namespace: "iwlan_telephony"
+ description: "Add AES_GCM algorithm support in IWLAN."
+ bug: "306119890"
+}
+flag {
+ name: "multiple_sa_proposals"
+ namespace: "iwlan_telephony"
+ description: "Add multiple proposals of IKE SA and Child SA"
+ bug: "287296642"
+}
+flag {
+ name: "high_secure_transforms_prioritized"
+ namespace: "iwlan_telephony"
+ description: "Reorder IKE and Child SA security transforms with high secured as prioritized"
+ bug: "306323917"
+}
+flag {
name: "epdg_selection_exclude_failed_ip_address"
namespace: "iwlan_telephony"
description: "Exclude the failed ip address in epdg selection until tunnel establish successfully or all ip address candidates are failed"
diff --git a/src/com/google/android/iwlan/epdg/EpdgChildSaProposal.java b/src/com/google/android/iwlan/epdg/EpdgChildSaProposal.java
new file mode 100644
index 0000000..d85e322
--- /dev/null
+++ b/src/com/google/android/iwlan/epdg/EpdgChildSaProposal.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2020 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.
+ */
+
+package com.google.android.iwlan.epdg;
+
+import android.net.ipsec.ike.ChildSaProposal;
+import android.util.Pair;
+
+public class EpdgChildSaProposal extends EpdgSaProposal {
+ /**
+ * Builds {@link ChildSaProposal} of carrier proposed encryption algorithms (non-AEAD) cipher
+ * suit.
+ */
+ public ChildSaProposal buildProposedChildSaProposal() {
+ return buildProposal(false, true);
+ }
+
+ /** Builds {@link ChildSaProposal} of carrier proposed AEAD algorithms cipher suit. */
+ public ChildSaProposal buildProposedChildSaAeadProposal() {
+ return buildProposal(true, true);
+ }
+
+ /**
+ * Builds {@link ChildSaProposal} of Iwlan supported encryption algorithms (non-AEAD) cipher
+ * suit.
+ */
+ public ChildSaProposal buildSupportedChildSaProposal() {
+ return buildProposal(false, false);
+ }
+
+ /** Builds {@link ChildSaProposal} of Iwlan supported AEAD algorithms cipher suit. */
+ public ChildSaProposal buildSupportedChildSaAeadProposal() {
+ return buildProposal(true, false);
+ }
+
+ private ChildSaProposal buildProposal(boolean isAead, boolean isProposed) {
+ ChildSaProposal.Builder saProposalBuilder = new ChildSaProposal.Builder();
+
+ int[] dhGroups = getDhGroups();
+ for (int dhGroup : dhGroups) {
+ saProposalBuilder.addDhGroup(dhGroup);
+ }
+
+ Pair<Integer, Integer>[] encrAlgos;
+
+ if (isAead) {
+ encrAlgos = (isProposed) ? getAeadAlgos() : getSupportedAeadAlgos();
+ } else {
+ encrAlgos = (isProposed) ? getEncryptionAlgos() : getSupportedEncryptionAlgos();
+ }
+
+ for (Pair<Integer, Integer> encrAlgo : encrAlgos) {
+ saProposalBuilder.addEncryptionAlgorithm(encrAlgo.first, encrAlgo.second);
+ }
+
+ if (!isAead) {
+ int[] integrityAlgos =
+ (isProposed) ? getIntegrityAlgos() : getSupportedIntegrityAlgos();
+ for (int integrityAlgo : integrityAlgos) {
+ saProposalBuilder.addIntegrityAlgorithm(integrityAlgo);
+ }
+ }
+
+ return saProposalBuilder.build();
+ }
+}
diff --git a/src/com/google/android/iwlan/epdg/EpdgIkeSaProposal.java b/src/com/google/android/iwlan/epdg/EpdgIkeSaProposal.java
new file mode 100644
index 0000000..f4d6d56
--- /dev/null
+++ b/src/com/google/android/iwlan/epdg/EpdgIkeSaProposal.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright 2020 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.
+ */
+
+package com.google.android.iwlan.epdg;
+
+import android.net.ipsec.ike.IkeSaProposal;
+import android.util.Pair;
+
+import java.util.LinkedHashSet;
+
+public class EpdgIkeSaProposal extends EpdgSaProposal {
+ protected final LinkedHashSet<Integer> mProposedPrfAlgos = new LinkedHashSet<>();
+
+ /**
+ * Add proposed PRF algorithms by the carrier.
+ *
+ * @param prfAlgos proposed PRF algorithms
+ */
+ public void addProposedPrfAlgorithm(int[] prfAlgos) {
+ for (int prfAlgo : prfAlgos) {
+ if (validateConfig(prfAlgo, VALID_PRF_ALGOS, CONFIG_TYPE_PRF_ALGO)) {
+ mProposedPrfAlgos.add(prfAlgo);
+ }
+ }
+ }
+
+ private int[] getPrfAlgos() {
+ if (isSaferProposalsPrioritized()) {
+ return mProposedPrfAlgos.stream()
+ .sorted(
+ (item1, item2) ->
+ compareTransformPriority(VALID_PRF_ALGOS, item1, item2))
+ .mapToInt(Integer::intValue)
+ .toArray();
+ }
+
+ return mProposedPrfAlgos.stream().mapToInt(Integer::intValue).toArray();
+ }
+
+ private int[] getSupportedPrfAlgos() {
+ return VALID_PRF_ALGOS.stream().mapToInt(Integer::intValue).toArray();
+ }
+
+ /**
+ * Builds {@link IkeSaProposal} of carrier proposed encryption algorithms (non-AEAD) cipher
+ * suit.
+ */
+ public IkeSaProposal buildProposedIkeSaProposal() {
+ return buildProposal(false, true);
+ }
+
+ /** Builds {@link IkeSaProposal} of carrier proposed AEAD algorithms cipher suit. */
+ public IkeSaProposal buildProposedIkeSaAeadProposal() {
+ return buildProposal(true, true);
+ }
+
+ /**
+ * Builds {@link IkeSaProposal} of Iwlan supported encryption algorithms (non-AEAD) cipher suit.
+ */
+ public IkeSaProposal buildSupportedIkeSaProposal() {
+ return buildProposal(false, false);
+ }
+
+ /** Builds {@link IkeSaProposal} of Iwlan supported AEAD algorithms cipher suit. */
+ public IkeSaProposal buildSupportedIkeSaAeadProposal() {
+ return buildProposal(true, false);
+ }
+
+ private IkeSaProposal buildProposal(boolean isAead, boolean isProposed) {
+ IkeSaProposal.Builder saProposalBuilder = new IkeSaProposal.Builder();
+
+ int[] dhGroups = isProposed ? getDhGroups() : getSupportedDhGroups();
+ for (int dhGroup : dhGroups) {
+ saProposalBuilder.addDhGroup(dhGroup);
+ }
+
+ Pair<Integer, Integer>[] encrAlgos;
+
+ if (isAead) {
+ encrAlgos = (isProposed) ? getAeadAlgos() : getSupportedAeadAlgos();
+ } else {
+ encrAlgos = (isProposed) ? getEncryptionAlgos() : getSupportedEncryptionAlgos();
+ }
+
+ for (Pair<Integer, Integer> encrAlgo : encrAlgos) {
+ saProposalBuilder.addEncryptionAlgorithm(encrAlgo.first, encrAlgo.second);
+ }
+
+ if (!isAead) {
+ int[] integrityAlgos =
+ (isProposed) ? getIntegrityAlgos() : getSupportedIntegrityAlgos();
+ for (int integrityAlgo : integrityAlgos) {
+ saProposalBuilder.addIntegrityAlgorithm(integrityAlgo);
+ }
+ }
+
+ int[] prfAlgos = (isProposed) ? getPrfAlgos() : getSupportedPrfAlgos();
+ for (int prfAlgo : prfAlgos) {
+ saProposalBuilder.addPseudorandomFunction(prfAlgo);
+ }
+
+ return saProposalBuilder.build();
+ }
+}
diff --git a/src/com/google/android/iwlan/epdg/EpdgSaProposal.java b/src/com/google/android/iwlan/epdg/EpdgSaProposal.java
new file mode 100644
index 0000000..871cc5c
--- /dev/null
+++ b/src/com/google/android/iwlan/epdg/EpdgSaProposal.java
@@ -0,0 +1,329 @@
+/*
+ * Copyright 2020 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.
+ */
+
+package com.google.android.iwlan.epdg;
+
+import android.net.ipsec.ike.SaProposal;
+import android.util.Log;
+import android.util.Pair;
+
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
+
+abstract class EpdgSaProposal {
+ private static final String TAG = EpdgSaProposal.class.getSimpleName();
+ private static final Set<Integer> VALID_DH_GROUPS;
+ private static final Set<Integer> VALID_KEY_LENGTHS;
+ protected static final Set<Integer> VALID_PRF_ALGOS;
+ private static final Set<Integer> VALID_INTEGRITY_ALGOS;
+ private static final Set<Integer> VALID_ENCRYPTION_ALGOS;
+ private static final Set<Integer> VALID_AEAD_ALGOS;
+
+ private static final String CONFIG_TYPE_DH_GROUP = "dh group";
+ private static final String CONFIG_TYPE_KEY_LEN = "algorithm key length";
+ protected static final String CONFIG_TYPE_PRF_ALGO = "prf algorithm";
+ private static final String CONFIG_TYPE_INTEGRITY_ALGO = "integrity algorithm";
+ private static final String CONFIG_TYPE_ENCRYPT_ALGO = "encryption algorithm";
+ private static final String CONFIG_TYPE_AEAD_ALGO = "AEAD algorithm";
+
+ private boolean mSaferAlgosPrioritized = false;
+
+ /*
+ * Each transform below filled with high secured order and index of each value
+ * represents the priority.
+ * Safer transform has high priority and proposals will be orders based on
+ * the priority order.
+ * For example, DH Group 4096 has more priority compare to 3072, and 3072
+ * has more priority than 2048.
+ * With reference to 3GPP TS 33.210 and RFC 8221, high secured transforms
+ * are prioritized in IKE and CHILD SA proposals.
+ */
+ static {
+ VALID_DH_GROUPS =
+ Collections.unmodifiableSet(
+ new LinkedHashSet<Integer>(
+ List.of(
+ SaProposal.DH_GROUP_4096_BIT_MODP,
+ SaProposal.DH_GROUP_3072_BIT_MODP,
+ SaProposal.DH_GROUP_2048_BIT_MODP,
+ SaProposal.DH_GROUP_1536_BIT_MODP,
+ SaProposal.DH_GROUP_1024_BIT_MODP)));
+
+ VALID_KEY_LENGTHS =
+ Collections.unmodifiableSet(
+ new LinkedHashSet<Integer>(
+ List.of(
+ SaProposal.KEY_LEN_AES_256,
+ SaProposal.KEY_LEN_AES_192,
+ SaProposal.KEY_LEN_AES_128)));
+
+ VALID_ENCRYPTION_ALGOS =
+ Collections.unmodifiableSet(
+ new LinkedHashSet<Integer>(
+ List.of(
+ SaProposal.ENCRYPTION_ALGORITHM_AES_CBC,
+ SaProposal.ENCRYPTION_ALGORITHM_AES_CTR)));
+
+ VALID_INTEGRITY_ALGOS =
+ Collections.unmodifiableSet(
+ new LinkedHashSet<Integer>(
+ List.of(
+ SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA2_512_256,
+ SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA2_384_192,
+ SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA2_256_128,
+ SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA1_96,
+ SaProposal.INTEGRITY_ALGORITHM_AES_XCBC_96)));
+
+ VALID_AEAD_ALGOS =
+ Collections.unmodifiableSet(
+ new LinkedHashSet<Integer>(
+ List.of(
+ SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_16,
+ SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_12,
+ SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_8)));
+
+ VALID_PRF_ALGOS =
+ Collections.unmodifiableSet(
+ new LinkedHashSet<Integer>(
+ List.of(
+ SaProposal.PSEUDORANDOM_FUNCTION_SHA2_512,
+ SaProposal.PSEUDORANDOM_FUNCTION_SHA2_384,
+ SaProposal.PSEUDORANDOM_FUNCTION_SHA2_256,
+ SaProposal.PSEUDORANDOM_FUNCTION_HMAC_SHA1,
+ SaProposal.PSEUDORANDOM_FUNCTION_AES128_XCBC)));
+ }
+
+ protected final LinkedHashSet<Integer> mProposedDhGroups = new LinkedHashSet<>();
+ protected final LinkedHashSet<Integer> mProposedIntegrityAlgos = new LinkedHashSet<>();
+ protected final LinkedHashSet<Pair<Integer, Integer>> mProposedEncryptAlgos =
+ new LinkedHashSet<>();
+ protected final LinkedHashSet<Pair<Integer, Integer>> mProposedAeadAlgos =
+ new LinkedHashSet<>();
+
+ /**
+ * Add proposed DH groups by the carrier.
+ *
+ * @param dhGroups proposed DH groups
+ */
+ public void addProposedDhGroups(int[] dhGroups) {
+ for (int dhGroup : dhGroups) {
+ if (validateConfig(dhGroup, VALID_DH_GROUPS, CONFIG_TYPE_DH_GROUP)) {
+ mProposedDhGroups.add(dhGroup);
+ }
+ }
+ }
+
+ /**
+ * Add proposed integrity algorithms by the carrier.
+ *
+ * @param integrityAlgos proposed integrity algorithms
+ */
+ public void addProposedIntegrityAlgorithm(int[] integrityAlgos) {
+ for (int integrityAlgo : integrityAlgos) {
+ if (validateConfig(integrityAlgo, VALID_INTEGRITY_ALGOS, CONFIG_TYPE_INTEGRITY_ALGO)) {
+ mProposedIntegrityAlgos.add(integrityAlgo);
+ }
+ }
+ }
+
+ /**
+ * Add proposed encryption algorithms and respective key lengths by the carrier.
+ *
+ * @param encryptionAlgo proposed encryption algorithm
+ * @param keyLens proposed key lengths for the encryption algorithm
+ */
+ public void addProposedEncryptionAlgorithm(int encryptionAlgo, int[] keyLens) {
+ if (validateConfig(encryptionAlgo, VALID_ENCRYPTION_ALGOS, CONFIG_TYPE_ENCRYPT_ALGO)) {
+ for (int keyLen : keyLens) {
+ if (validateConfig(keyLen, VALID_KEY_LENGTHS, CONFIG_TYPE_KEY_LEN)) {
+ mProposedEncryptAlgos.add(new Pair<Integer, Integer>(encryptionAlgo, keyLen));
+ }
+ }
+ }
+ }
+
+ /**
+ * Add proposed AEAD algorithms and respective key lengths by the carrier.
+ *
+ * @param aeadAlgo proposed AEAD algorithm
+ * @param keyLens proposed key lengths for the encryption algorithm
+ */
+ public void addProposedAeadAlgorithm(int aeadAlgo, int[] keyLens) {
+ if (validateConfig(aeadAlgo, VALID_AEAD_ALGOS, CONFIG_TYPE_AEAD_ALGO)) {
+ for (int keyLen : keyLens) {
+ if (validateConfig(keyLen, VALID_KEY_LENGTHS, CONFIG_TYPE_KEY_LEN)) {
+ mProposedAeadAlgos.add(new Pair<Integer, Integer>(aeadAlgo, keyLen));
+ }
+ }
+ }
+ }
+
+ /** Enable to reorder proposals with safer ciphers prioritized. */
+ public void enableReorderingSaferProposals() {
+ mSaferAlgosPrioritized = true;
+ }
+
+ /**
+ * Disable to reorder proposals with safer ciphers prioritized.Follows default configured order.
+ */
+ public void disableReorderingSaferProposals() {
+ mSaferAlgosPrioritized = false;
+ }
+
+ protected boolean isSaferProposalsPrioritized() {
+ return mSaferAlgosPrioritized;
+ }
+
+ protected int getIndexOf(Set<Integer> set, int value) {
+ Iterator<Integer> itr = set.iterator();
+ int index = 0;
+
+ while (itr.hasNext()) {
+ if (itr.next().equals(value)) {
+ return index;
+ }
+ index++;
+ }
+
+ return -1;
+ }
+
+ /**
+ * Compares the priority of the transforms.
+ */
+ protected int compareTransformPriority(Set<Integer> transformGroup, int item1, int item2) {
+ return getIndexOf(transformGroup, item1) - getIndexOf(transformGroup, item2);
+ }
+
+ /**
+ * Compares the priority of the encryption/AEAD transforms.
+ * First value in pair is encryption/AEAD algorithm and
+ * second value in pair is key length of that algorithm.
+ * If Algorithms are same then compare the priotity of the key lengths else compare
+ * the priority of the algorithms.
+ */
+ protected int compareEncryptionTransformPriority(
+ Set<Integer> algos,
+ Set<Integer> keyLens,
+ Pair<Integer, Integer> item1,
+ Pair<Integer, Integer> item2) {
+ return item1.first.equals(item2.first)
+ ? getIndexOf(keyLens, item1.second) - getIndexOf(keyLens, item2.second)
+ : getIndexOf(algos, item1.first) - getIndexOf(algos, item2.first);
+ }
+
+ protected int[] getDhGroups() {
+ if (isSaferProposalsPrioritized()) {
+ return mProposedDhGroups.stream()
+ .sorted(
+ (item1, item2) ->
+ compareTransformPriority(VALID_DH_GROUPS, item1, item2))
+ .mapToInt(Integer::intValue)
+ .toArray();
+ }
+
+ return mProposedDhGroups.stream().mapToInt(Integer::intValue).toArray();
+ }
+
+ protected int[] getSupportedDhGroups() {
+ return VALID_DH_GROUPS.stream().mapToInt(Integer::intValue).toArray();
+ }
+
+ protected int[] getIntegrityAlgos() {
+ if (isSaferProposalsPrioritized()) {
+ return mProposedIntegrityAlgos.stream()
+ .sorted(
+ (item1, item2) ->
+ compareTransformPriority(VALID_INTEGRITY_ALGOS, item1, item2))
+ .mapToInt(Integer::intValue)
+ .toArray();
+ }
+
+ return mProposedIntegrityAlgos.stream().mapToInt(Integer::intValue).toArray();
+ }
+
+ protected int[] getSupportedIntegrityAlgos() {
+ return VALID_INTEGRITY_ALGOS.stream().mapToInt(Integer::intValue).toArray();
+ }
+
+ protected Pair<Integer, Integer>[] getEncryptionAlgos() {
+ if (isSaferProposalsPrioritized()) {
+ return mProposedEncryptAlgos.stream()
+ .sorted(
+ (item1, item2) ->
+ compareEncryptionTransformPriority(
+ VALID_ENCRYPTION_ALGOS,
+ VALID_KEY_LENGTHS,
+ item1,
+ item2))
+ .toArray(Pair[]::new);
+ }
+
+ return mProposedEncryptAlgos.toArray(new Pair[mProposedEncryptAlgos.size()]);
+ }
+
+ protected Pair<Integer, Integer>[] getSupportedEncryptionAlgos() {
+ Pair<Integer, Integer>[] encrAlgos =
+ new Pair[VALID_ENCRYPTION_ALGOS.size() * VALID_KEY_LENGTHS.size()];
+ int index = 0;
+ for (int algo : VALID_ENCRYPTION_ALGOS) {
+ for (int len : VALID_KEY_LENGTHS) {
+ encrAlgos[index++] = new Pair(algo, len);
+ }
+ }
+
+ return encrAlgos;
+ }
+
+ protected Pair<Integer, Integer>[] getAeadAlgos() {
+ if (isSaferProposalsPrioritized()) {
+ return mProposedAeadAlgos.stream()
+ .sorted(
+ (item1, item2) ->
+ compareEncryptionTransformPriority(
+ VALID_AEAD_ALGOS, VALID_KEY_LENGTHS, item1, item2))
+ .toArray(Pair[]::new);
+ }
+
+ return mProposedAeadAlgos.toArray(new Pair[mProposedAeadAlgos.size()]);
+ }
+
+ protected Pair<Integer, Integer>[] getSupportedAeadAlgos() {
+ Pair<Integer, Integer>[] aeadAlgos =
+ new Pair[VALID_AEAD_ALGOS.size() * VALID_KEY_LENGTHS.size()];
+ int index = 0;
+ for (int algo : VALID_AEAD_ALGOS) {
+ for (int len : VALID_KEY_LENGTHS) {
+ aeadAlgos[index++] = new Pair(algo, len);
+ }
+ }
+
+ return aeadAlgos;
+ }
+
+ protected static boolean validateConfig(
+ int config, Set<Integer> validConfigValues, String configType) {
+ if (validConfigValues.contains(config)) {
+ return true;
+ }
+
+ Log.e(TAG, "Invalid config value for " + configType + ":" + config);
+ return false;
+ }
+}
diff --git a/src/com/google/android/iwlan/epdg/EpdgSelector.java b/src/com/google/android/iwlan/epdg/EpdgSelector.java
index 3590a7e..dc2c364 100644
--- a/src/com/google/android/iwlan/epdg/EpdgSelector.java
+++ b/src/com/google/android/iwlan/epdg/EpdgSelector.java
@@ -155,6 +155,9 @@ public class EpdgSelector {
mV4PcoData = new ArrayList<>();
mV6PcoData = new ArrayList<>();
+ mV4PcoData = new ArrayList<>();
+ mV6PcoData = new ArrayList<>();
+
mErrorPolicyManager = ErrorPolicyManager.getInstance(mContext, mSlotId);
mTemporaryExcludedAddresses = new HashSet<>();
diff --git a/src/com/google/android/iwlan/epdg/EpdgTunnelManager.java b/src/com/google/android/iwlan/epdg/EpdgTunnelManager.java
index c350525..8b53ee1 100644
--- a/src/com/google/android/iwlan/epdg/EpdgTunnelManager.java
+++ b/src/com/google/android/iwlan/epdg/EpdgTunnelManager.java
@@ -76,6 +76,7 @@ import android.util.Log;
import com.android.internal.annotations.VisibleForTesting;
import com.google.android.iwlan.ErrorPolicyManager;
+import com.google.android.iwlan.IwlanCarrierConfig;
import com.google.android.iwlan.IwlanError;
import com.google.android.iwlan.IwlanHelper;
import com.google.android.iwlan.IwlanTunnelMetricsImpl;
@@ -187,6 +188,7 @@ public class EpdgTunnelManager {
private static final Set<Integer> VALID_PRF_ALGOS;
private static final Set<Integer> VALID_INTEGRITY_ALGOS;
private static final Set<Integer> VALID_ENCRYPTION_ALGOS;
+ private static final Set<Integer> VALID_AEAD_ALGOS;
private static final String CONFIG_TYPE_DH_GROUP = "dh group";
private static final String CONFIG_TYPE_KEY_LEN = "algorithm key length";
@@ -221,6 +223,12 @@ public class EpdgTunnelManager {
SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA2_384_192,
SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA2_512_256);
+ VALID_AEAD_ALGOS =
+ Set.of(
+ SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_8,
+ SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_12,
+ SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_16);
+
VALID_PRF_ALGOS =
Set.of(
SaProposal.PSEUDORANDOM_FUNCTION_HMAC_SHA1,
@@ -918,7 +926,35 @@ public class EpdgTunnelManager {
new TunnelModeChildSessionParams.Builder()
.setLifetimeSeconds(hardTimeSeconds, softTimeSeconds);
- childSessionParamsBuilder.addChildSaProposal(buildChildSaProposal());
+ if (mFeatureFlags.multipleSaProposals()
+ && IwlanCarrierConfig.getConfigBoolean(
+ mContext,
+ mSlotId,
+ CarrierConfigManager.Iwlan
+ .KEY_SUPPORTS_CHILD_SESSION_MULTIPLE_SA_PROPOSALS_BOOL)) {
+ EpdgChildSaProposal epdgChildSaProposal = createEpdgChildSaProposal();
+
+ if (mFeatureFlags.highSecureTransformsPrioritized()) {
+ epdgChildSaProposal.enableReorderingSaferProposals();
+ }
+
+ if (isChildSessionAeadAlgosAvailable()) {
+ childSessionParamsBuilder.addChildSaProposal(
+ epdgChildSaProposal.buildProposedChildSaAeadProposal());
+ }
+ childSessionParamsBuilder.addChildSaProposal(
+ epdgChildSaProposal.buildProposedChildSaProposal());
+ childSessionParamsBuilder.addChildSaProposal(
+ epdgChildSaProposal.buildSupportedChildSaAeadProposal());
+ childSessionParamsBuilder.addChildSaProposal(
+ epdgChildSaProposal.buildSupportedChildSaProposal());
+ } else {
+ if (mFeatureFlags.aeadAlgosEnabled() && isChildSessionAeadAlgosAvailable()) {
+ childSessionParamsBuilder.addChildSaProposal(buildAeadChildSaProposal());
+ } else {
+ childSessionParamsBuilder.addChildSaProposal(buildChildSaProposal());
+ }
+ }
boolean handoverIPv4Present = setupRequest.srcIpv4Address().isPresent();
boolean handoverIPv6Present = setupRequest.srcIpv6Address().isPresent();
@@ -1047,7 +1083,6 @@ public class EpdgTunnelManager {
.setLocalIdentification(getLocalIdentification())
.setRemoteIdentification(getId(setupRequest.apnName(), false))
.setAuthEap(null, getEapConfig())
- .addIkeSaProposal(buildIkeSaProposal())
.setNetwork(mDefaultNetwork)
.addIkeOption(IkeSessionParams.IKE_OPTION_ACCEPT_ANY_REMOTE_ID)
.addIkeOption(IkeSessionParams.IKE_OPTION_MOBIKE)
@@ -1056,6 +1091,32 @@ public class EpdgTunnelManager {
.setRetransmissionTimeoutsMillis(getRetransmissionTimeoutsFromConfig())
.setDpdDelaySeconds(getDpdDelayFromConfig());
+ if (mFeatureFlags.multipleSaProposals()
+ && IwlanCarrierConfig.getConfigBoolean(
+ mContext,
+ mSlotId,
+ CarrierConfigManager.Iwlan
+ .KEY_SUPPORTS_IKE_SESSION_MULTIPLE_SA_PROPOSALS_BOOL)) {
+ EpdgIkeSaProposal epdgIkeSaProposal = createEpdgIkeSaProposal();
+
+ if (mFeatureFlags.highSecureTransformsPrioritized()) {
+ epdgIkeSaProposal.enableReorderingSaferProposals();
+ }
+
+ if (isIkeSessionAeadAlgosAvailable()) {
+ builder.addIkeSaProposal(epdgIkeSaProposal.buildProposedIkeSaAeadProposal());
+ }
+ builder.addIkeSaProposal(epdgIkeSaProposal.buildProposedIkeSaProposal());
+ builder.addIkeSaProposal(epdgIkeSaProposal.buildSupportedIkeSaAeadProposal());
+ builder.addIkeSaProposal(epdgIkeSaProposal.buildSupportedIkeSaProposal());
+ } else {
+ if (mFeatureFlags.aeadAlgosEnabled() && isIkeSessionAeadAlgosAvailable()) {
+ builder.addIkeSaProposal(buildIkeSaAeadProposal());
+ } else {
+ builder.addIkeSaProposal(buildIkeSaProposal());
+ }
+ }
+
if (numPdnTunnels() == 0) {
builder.addIkeOption(IkeSessionParams.IKE_OPTION_INITIAL_CONTACT);
Log.d(TAG, "IKE_OPTION_INITIAL_CONTACT");
@@ -1120,6 +1181,32 @@ public class EpdgTunnelManager {
builder3gppParams.build(), new TmIke3gppCallback(apnName, token));
}
+ private boolean isChildSessionAeadAlgosAvailable() {
+ int[] encryptionAlgos =
+ getConfig(
+ CarrierConfigManager.Iwlan
+ .KEY_SUPPORTED_CHILD_SESSION_AEAD_ALGORITHMS_INT_ARRAY);
+ for (int encryptionAlgo : encryptionAlgos) {
+ if (validateConfig(encryptionAlgo, VALID_AEAD_ALGOS, CONFIG_TYPE_ENCRYPT_ALGO)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private boolean isIkeSessionAeadAlgosAvailable() {
+ int[] encryptionAlgos =
+ getConfig(
+ CarrierConfigManager.Iwlan
+ .KEY_SUPPORTED_IKE_SESSION_AEAD_ALGORITHMS_INT_ARRAY);
+ for (int encryptionAlgo : encryptionAlgos) {
+ if (validateConfig(encryptionAlgo, VALID_AEAD_ALGOS, CONFIG_TYPE_ENCRYPT_ALGO)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
private boolean isValidChildSessionLifetime(int hardLifetimeSeconds, int softLifetimeSeconds) {
return hardLifetimeSeconds >= CHILD_HARD_LIFETIME_SEC_MINIMUM
&& hardLifetimeSeconds <= CHILD_HARD_LIFETIME_SEC_MAXIMUM
@@ -1138,6 +1225,124 @@ public class EpdgTunnelManager {
return IwlanHelper.getConfig(configKey, mContext, mSlotId);
}
+ private void createEpdgSaProposal(EpdgSaProposal epdgSaProposal, boolean isChildProposal) {
+ epdgSaProposal.addProposedDhGroups(
+ IwlanCarrierConfig.getConfigIntArray(
+ mContext,
+ mSlotId,
+ CarrierConfigManager.Iwlan.KEY_DIFFIE_HELLMAN_GROUPS_INT_ARRAY));
+
+ int[] encryptionAlgos =
+ isChildProposal
+ ? IwlanCarrierConfig.getConfigIntArray(
+ mContext,
+ mSlotId,
+ CarrierConfigManager.Iwlan
+ .KEY_SUPPORTED_CHILD_SESSION_ENCRYPTION_ALGORITHMS_INT_ARRAY)
+ : IwlanCarrierConfig.getConfigIntArray(
+ mContext,
+ mSlotId,
+ CarrierConfigManager.Iwlan
+ .KEY_SUPPORTED_IKE_SESSION_ENCRYPTION_ALGORITHMS_INT_ARRAY);
+
+ for (int encryptionAlgo : encryptionAlgos) {
+ if (encryptionAlgo == SaProposal.ENCRYPTION_ALGORITHM_AES_CBC) {
+ int[] aesCbcKeyLens =
+ isChildProposal
+ ? IwlanCarrierConfig.getConfigIntArray(
+ mContext,
+ mSlotId,
+ CarrierConfigManager.Iwlan
+ .KEY_CHILD_SESSION_AES_CBC_KEY_SIZE_INT_ARRAY)
+ : IwlanCarrierConfig.getConfigIntArray(
+ mContext,
+ mSlotId,
+ CarrierConfigManager.Iwlan
+ .KEY_IKE_SESSION_AES_CBC_KEY_SIZE_INT_ARRAY);
+ epdgSaProposal.addProposedEncryptionAlgorithm(encryptionAlgo, aesCbcKeyLens);
+ }
+
+ if (encryptionAlgo == SaProposal.ENCRYPTION_ALGORITHM_AES_CTR) {
+ int[] aesCtrKeyLens =
+ isChildProposal
+ ? IwlanCarrierConfig.getConfigIntArray(
+ mContext,
+ mSlotId,
+ CarrierConfigManager.Iwlan
+ .KEY_CHILD_SESSION_AES_CTR_KEY_SIZE_INT_ARRAY)
+ : IwlanCarrierConfig.getConfigIntArray(
+ mContext,
+ mSlotId,
+ CarrierConfigManager.Iwlan
+ .KEY_IKE_SESSION_AES_CTR_KEY_SIZE_INT_ARRAY);
+ epdgSaProposal.addProposedEncryptionAlgorithm(encryptionAlgo, aesCtrKeyLens);
+ }
+ }
+
+ if (encryptionAlgos.length > 0) {
+ epdgSaProposal.addProposedIntegrityAlgorithm(
+ IwlanCarrierConfig.getConfigIntArray(
+ mContext,
+ mSlotId,
+ CarrierConfigManager.Iwlan
+ .KEY_SUPPORTED_INTEGRITY_ALGORITHMS_INT_ARRAY));
+ }
+
+ int[] aeadAlgos =
+ isChildProposal
+ ? IwlanCarrierConfig.getConfigIntArray(
+ mContext,
+ mSlotId,
+ CarrierConfigManager.Iwlan
+ .KEY_SUPPORTED_CHILD_SESSION_AEAD_ALGORITHMS_INT_ARRAY)
+ : IwlanCarrierConfig.getConfigIntArray(
+ mContext,
+ mSlotId,
+ CarrierConfigManager.Iwlan
+ .KEY_SUPPORTED_IKE_SESSION_AEAD_ALGORITHMS_INT_ARRAY);
+ for (int aeadAlgo : aeadAlgos) {
+ if (!validateConfig(aeadAlgo, VALID_AEAD_ALGOS, CONFIG_TYPE_ENCRYPT_ALGO)) {
+ continue;
+ }
+ if ((aeadAlgo == SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_8)
+ || (aeadAlgo == SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_12)
+ || (aeadAlgo == SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_16)) {
+ int[] aesGcmKeyLens =
+ isChildProposal
+ ? IwlanCarrierConfig.getConfigIntArray(
+ mContext,
+ mSlotId,
+ CarrierConfigManager.Iwlan
+ .KEY_CHILD_SESSION_AES_GCM_KEY_SIZE_INT_ARRAY)
+ : IwlanCarrierConfig.getConfigIntArray(
+ mContext,
+ mSlotId,
+ CarrierConfigManager.Iwlan
+ .KEY_IKE_SESSION_AES_GCM_KEY_SIZE_INT_ARRAY);
+ epdgSaProposal.addProposedAeadAlgorithm(aeadAlgo, aesGcmKeyLens);
+ }
+ }
+ }
+
+ private EpdgChildSaProposal createEpdgChildSaProposal() {
+ EpdgChildSaProposal epdgChildSaProposal = new EpdgChildSaProposal();
+ createEpdgSaProposal(epdgChildSaProposal, true);
+ return epdgChildSaProposal;
+ }
+
+ private EpdgIkeSaProposal createEpdgIkeSaProposal() {
+ EpdgIkeSaProposal epdgIkeSaProposal = new EpdgIkeSaProposal();
+
+ createEpdgSaProposal(epdgIkeSaProposal, false);
+
+ epdgIkeSaProposal.addProposedPrfAlgorithm(
+ IwlanCarrierConfig.getConfigIntArray(
+ mContext,
+ mSlotId,
+ CarrierConfigManager.Iwlan.KEY_SUPPORTED_PRF_ALGORITHMS_INT_ARRAY));
+ return epdgIkeSaProposal;
+ }
+
private IkeSaProposal buildIkeSaProposal() {
IkeSaProposal.Builder saProposalBuilder = new IkeSaProposal.Builder();
@@ -1199,6 +1404,50 @@ public class EpdgTunnelManager {
return saProposalBuilder.build();
}
+ private IkeSaProposal buildIkeSaAeadProposal() {
+ IkeSaProposal.Builder saProposalBuilder = new IkeSaProposal.Builder();
+
+ int[] dhGroups = getConfig(CarrierConfigManager.Iwlan.KEY_DIFFIE_HELLMAN_GROUPS_INT_ARRAY);
+ for (int dhGroup : dhGroups) {
+ if (validateConfig(dhGroup, VALID_DH_GROUPS, CONFIG_TYPE_DH_GROUP)) {
+ saProposalBuilder.addDhGroup(dhGroup);
+ }
+ }
+
+ int[] encryptionAlgos =
+ getConfig(
+ CarrierConfigManager.Iwlan
+ .KEY_SUPPORTED_IKE_SESSION_AEAD_ALGORITHMS_INT_ARRAY);
+ for (int encryptionAlgo : encryptionAlgos) {
+ if (!validateConfig(encryptionAlgo, VALID_AEAD_ALGOS, CONFIG_TYPE_ENCRYPT_ALGO)) {
+ continue;
+ }
+ if ((encryptionAlgo == SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_8)
+ || (encryptionAlgo == SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_12)
+ || (encryptionAlgo == SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_16)) {
+ int[] aesGcmKeyLens =
+ getConfig(
+ CarrierConfigManager.Iwlan
+ .KEY_IKE_SESSION_AES_GCM_KEY_SIZE_INT_ARRAY);
+ for (int aesGcmKeyLen : aesGcmKeyLens) {
+ if (validateConfig(aesGcmKeyLen, VALID_KEY_LENGTHS, CONFIG_TYPE_KEY_LEN)) {
+ saProposalBuilder.addEncryptionAlgorithm(encryptionAlgo, aesGcmKeyLen);
+ }
+ }
+ }
+ }
+
+ int[] prfAlgos =
+ getConfig(CarrierConfigManager.Iwlan.KEY_SUPPORTED_PRF_ALGORITHMS_INT_ARRAY);
+ for (int prfAlgo : prfAlgos) {
+ if (validateConfig(prfAlgo, VALID_PRF_ALGOS, CONFIG_TYPE_PRF_ALGO)) {
+ saProposalBuilder.addPseudorandomFunction(prfAlgo);
+ }
+ }
+
+ return saProposalBuilder.build();
+ }
+
private boolean validateConfig(int config, Set<Integer> validConfigValues, String configType) {
if (validConfigValues.contains(config)) {
return true;
@@ -1278,6 +1527,42 @@ public class EpdgTunnelManager {
return saProposalBuilder.build();
}
+ private ChildSaProposal buildAeadChildSaProposal() {
+ ChildSaProposal.Builder saProposalBuilder = new ChildSaProposal.Builder();
+
+ int[] dhGroups = getConfig(CarrierConfigManager.Iwlan.KEY_DIFFIE_HELLMAN_GROUPS_INT_ARRAY);
+ for (int dhGroup : dhGroups) {
+ if (validateConfig(dhGroup, VALID_DH_GROUPS, CONFIG_TYPE_DH_GROUP)) {
+ saProposalBuilder.addDhGroup(dhGroup);
+ }
+ }
+
+ int[] encryptionAlgos =
+ getConfig(
+ CarrierConfigManager.Iwlan
+ .KEY_SUPPORTED_CHILD_SESSION_AEAD_ALGORITHMS_INT_ARRAY);
+ for (int encryptionAlgo : encryptionAlgos) {
+ if (!validateConfig(encryptionAlgo, VALID_AEAD_ALGOS, CONFIG_TYPE_ENCRYPT_ALGO)) {
+ continue;
+ }
+ if ((encryptionAlgo == SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_8)
+ || (encryptionAlgo == SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_12)
+ || (encryptionAlgo == SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_16)) {
+ int[] aesGcmKeyLens =
+ getConfig(
+ CarrierConfigManager.Iwlan
+ .KEY_CHILD_SESSION_AES_GCM_KEY_SIZE_INT_ARRAY);
+ for (int aesGcmKeyLen : aesGcmKeyLens) {
+ if (validateConfig(aesGcmKeyLen, VALID_KEY_LENGTHS, CONFIG_TYPE_KEY_LEN)) {
+ saProposalBuilder.addEncryptionAlgorithm(encryptionAlgo, aesGcmKeyLen);
+ }
+ }
+ }
+ }
+
+ return saProposalBuilder.build();
+ }
+
private IkeIdentification getLocalIdentification() throws IwlanSimNotReadyException {
String nai;
diff --git a/test/com/google/android/iwlan/epdg/EpdgTunnelManagerTest.java b/test/com/google/android/iwlan/epdg/EpdgTunnelManagerTest.java
index 1829047..05ab0bc 100644
--- a/test/com/google/android/iwlan/epdg/EpdgTunnelManagerTest.java
+++ b/test/com/google/android/iwlan/epdg/EpdgTunnelManagerTest.java
@@ -28,6 +28,7 @@ import static org.mockito.Mockito.any;
import static org.mockito.Mockito.anyBoolean;
import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.anyLong;
+import static org.mockito.Mockito.anyString;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.doReturn;
@@ -74,6 +75,7 @@ import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.telephony.data.ApnSetting;
+import android.util.Pair;
import com.google.android.iwlan.IwlanError;
import com.google.android.iwlan.IwlanTunnelMetricsImpl;
@@ -545,6 +547,207 @@ public class EpdgTunnelManagerTest {
}
@Test
+ public void testAeadSaProposals() throws Exception {
+ when(mFakeFeatureFlags.aeadAlgosEnabled()).thenReturn(true);
+ final String apnName = "ims";
+ int[] aeadAlgos = {
+ SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_8,
+ SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_12,
+ SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_16,
+ };
+ int[] aeadAlgosKeyLens = {
+ SaProposal.KEY_LEN_AES_128, SaProposal.KEY_LEN_AES_192, SaProposal.KEY_LEN_AES_256,
+ };
+
+ PersistableBundle bundle = new PersistableBundle();
+ bundle.putIntArray(
+ CarrierConfigManager.Iwlan.KEY_SUPPORTED_IKE_SESSION_AEAD_ALGORITHMS_INT_ARRAY,
+ aeadAlgos);
+ bundle.putIntArray(
+ CarrierConfigManager.Iwlan.KEY_IKE_SESSION_AES_GCM_KEY_SIZE_INT_ARRAY,
+ aeadAlgosKeyLens);
+ bundle.putIntArray(
+ CarrierConfigManager.Iwlan.KEY_SUPPORTED_CHILD_SESSION_AEAD_ALGORITHMS_INT_ARRAY,
+ aeadAlgos);
+ bundle.putIntArray(
+ CarrierConfigManager.Iwlan.KEY_CHILD_SESSION_AES_GCM_KEY_SIZE_INT_ARRAY,
+ aeadAlgosKeyLens);
+
+ setupMockForGetConfig(bundle);
+
+ IkeSessionArgumentCaptors tunnelArgumentCaptors =
+ verifyBringUpTunnelWithDnsQuery(apnName, mMockDefaultNetwork);
+
+ IkeSessionParams ikeTunnelParams = tunnelArgumentCaptors.mIkeSessionParamsCaptor.getValue();
+
+ List<Pair<Integer, Integer>> ikeEncrAlgos =
+ ikeTunnelParams.getIkeSaProposals().get(0).getEncryptionAlgorithms();
+
+ assertTrue(ikeEncrAlgos.contains(new Pair(aeadAlgos[0], aeadAlgosKeyLens[0])));
+ assertEquals(
+ "IKE AEAD algorithms mismatch",
+ (long) aeadAlgos.length * aeadAlgosKeyLens.length,
+ (long) ikeEncrAlgos.size());
+
+ ChildSessionParams childTunnelParams =
+ tunnelArgumentCaptors.mChildSessionParamsCaptor.getValue();
+
+ List<Pair<Integer, Integer>> childEncrAlgos =
+ childTunnelParams.getChildSaProposals().get(0).getEncryptionAlgorithms();
+
+ assertTrue(childEncrAlgos.contains(new Pair(aeadAlgos[0], aeadAlgosKeyLens[0])));
+ assertEquals(
+ "Child AEAD algorithms mismatch",
+ (long) aeadAlgos.length * aeadAlgosKeyLens.length,
+ (long) childEncrAlgos.size());
+ }
+
+ @Test
+ public void testMultipleSaProposals() throws Exception {
+ when(mFakeFeatureFlags.multipleSaProposals()).thenReturn(true);
+ final String apnName = "ims";
+ PersistableBundle bundle = new PersistableBundle();
+
+ int[] aeadAlgos = {
+ SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_12,
+ };
+ int[] aeadAlgosKeyLens = {
+ SaProposal.KEY_LEN_AES_192, SaProposal.KEY_LEN_AES_256,
+ };
+
+ bundle.putIntArray(
+ CarrierConfigManager.Iwlan.KEY_SUPPORTED_IKE_SESSION_AEAD_ALGORITHMS_INT_ARRAY,
+ aeadAlgos);
+ bundle.putIntArray(
+ CarrierConfigManager.Iwlan.KEY_IKE_SESSION_AES_GCM_KEY_SIZE_INT_ARRAY,
+ aeadAlgosKeyLens);
+ bundle.putIntArray(
+ CarrierConfigManager.Iwlan.KEY_SUPPORTED_CHILD_SESSION_AEAD_ALGORITHMS_INT_ARRAY,
+ aeadAlgos);
+ bundle.putIntArray(
+ CarrierConfigManager.Iwlan.KEY_CHILD_SESSION_AES_GCM_KEY_SIZE_INT_ARRAY,
+ aeadAlgosKeyLens);
+
+ bundle.putBoolean(
+ CarrierConfigManager.Iwlan.KEY_SUPPORTS_IKE_SESSION_MULTIPLE_SA_PROPOSALS_BOOL,
+ true);
+ bundle.putBoolean(
+ CarrierConfigManager.Iwlan.KEY_SUPPORTS_CHILD_SESSION_MULTIPLE_SA_PROPOSALS_BOOL,
+ true);
+
+ setupMockForGetConfig(bundle);
+
+ IkeSessionArgumentCaptors tunnelArgumentCaptors =
+ verifyBringUpTunnelWithDnsQuery(apnName, mMockDefaultNetwork);
+
+ IkeSessionParams ikeTunnelParams = tunnelArgumentCaptors.mIkeSessionParamsCaptor.getValue();
+
+ assertTrue(ikeTunnelParams.getIkeSaProposals().size() > 1);
+
+ List<Pair<Integer, Integer>> ikeAeadAlgos =
+ ikeTunnelParams.getIkeSaProposals().get(0).getEncryptionAlgorithms();
+ assertEquals(
+ "Reorder higher AEAD in IKE SA mismatch",
+ (long) SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_12,
+ (long) ikeAeadAlgos.get(0).first);
+
+ ChildSessionParams childTunnelParams =
+ tunnelArgumentCaptors.mChildSessionParamsCaptor.getValue();
+
+ assertTrue(childTunnelParams.getChildSaProposals().size() > 1);
+
+ List<Pair<Integer, Integer>> childAeadAlgos =
+ childTunnelParams.getChildSaProposals().get(0).getEncryptionAlgorithms();
+ assertEquals(
+ "Reorder higher AEAD in Child SA mismatch",
+ (long) SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_12,
+ (long) childAeadAlgos.get(0).first);
+ }
+
+ @Test
+ public void testSaProposalsReorder() throws Exception {
+ when(mFakeFeatureFlags.aeadAlgosEnabled()).thenReturn(true);
+ when(mFakeFeatureFlags.multipleSaProposals()).thenReturn(true);
+ when(mFakeFeatureFlags.highSecureTransformsPrioritized()).thenReturn(true);
+
+ final String apnName = "ims";
+ int[] aeadAlgos = {
+ SaProposal.ENCRYPTION_ALGORITHM_AES_CBC,
+ };
+ int[] aeadAlgosKeyLens = {
+ SaProposal.KEY_LEN_AES_128, SaProposal.KEY_LEN_AES_192, SaProposal.KEY_LEN_AES_256,
+ };
+
+ PersistableBundle bundle = new PersistableBundle();
+
+ bundle.putIntArray(
+ CarrierConfigManager.Iwlan
+ .KEY_SUPPORTED_IKE_SESSION_ENCRYPTION_ALGORITHMS_INT_ARRAY,
+ aeadAlgos);
+ bundle.putIntArray(
+ CarrierConfigManager.Iwlan.KEY_IKE_SESSION_AES_CBC_KEY_SIZE_INT_ARRAY,
+ aeadAlgosKeyLens);
+ bundle.putIntArray(
+ CarrierConfigManager.Iwlan
+ .KEY_SUPPORTED_CHILD_SESSION_ENCRYPTION_ALGORITHMS_INT_ARRAY,
+ aeadAlgos);
+ bundle.putIntArray(
+ CarrierConfigManager.Iwlan.KEY_CHILD_SESSION_AES_CBC_KEY_SIZE_INT_ARRAY,
+ aeadAlgosKeyLens);
+
+ bundle.putBoolean(
+ CarrierConfigManager.Iwlan.KEY_SUPPORTS_IKE_SESSION_MULTIPLE_SA_PROPOSALS_BOOL,
+ true);
+ bundle.putBoolean(
+ CarrierConfigManager.Iwlan.KEY_SUPPORTS_CHILD_SESSION_MULTIPLE_SA_PROPOSALS_BOOL,
+ true);
+
+ setupMockForGetConfig(bundle);
+
+ IkeSessionArgumentCaptors tunnelArgumentCaptors =
+ verifyBringUpTunnelWithDnsQuery(apnName, mMockDefaultNetwork);
+
+ IkeSessionParams ikeTunnelParams = tunnelArgumentCaptors.mIkeSessionParamsCaptor.getValue();
+
+ assertTrue(ikeTunnelParams.getIkeSaProposals().size() > 1);
+
+ List<Pair<Integer, Integer>> ikeEncrAlgos =
+ ikeTunnelParams.getIkeSaProposals().get(0).getEncryptionAlgorithms();
+
+ assertEquals(
+ "Reorder bigger key length in IKE SA mismatch",
+ (long) SaProposal.KEY_LEN_AES_256,
+ (long) ikeEncrAlgos.get(0).second);
+
+ List<Pair<Integer, Integer>> ikeAeadAlgos =
+ ikeTunnelParams.getIkeSaProposals().get(1).getEncryptionAlgorithms();
+ assertEquals(
+ "Reorder higher AEAD in IKE SA mismatch",
+ (long) SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_16,
+ (long) ikeAeadAlgos.get(0).first);
+
+ ChildSessionParams childTunnelParams =
+ tunnelArgumentCaptors.mChildSessionParamsCaptor.getValue();
+
+ assertTrue(childTunnelParams.getChildSaProposals().size() > 1);
+
+ List<Pair<Integer, Integer>> childEncrAlgos =
+ childTunnelParams.getChildSaProposals().get(0).getEncryptionAlgorithms();
+
+ assertEquals(
+ "Reorder bigger key length in Child SA mismatch",
+ (long) SaProposal.KEY_LEN_AES_256,
+ (long) childEncrAlgos.get(0).second);
+
+ List<Pair<Integer, Integer>> childAeadAlgos =
+ childTunnelParams.getChildSaProposals().get(1).getEncryptionAlgorithms();
+ assertEquals(
+ "Reorder higher AEAD in Child SA mismatch",
+ (long) SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_16,
+ (long) childAeadAlgos.get(0).first);
+ }
+
+ @Test
public void testCloseTunnelWithNoTunnelForApn() throws Exception {
String testApnName = "www.xyz.com";
doReturn(0L)
@@ -1158,6 +1361,7 @@ public class EpdgTunnelManagerTest {
when(mMockTelephonyManager.createForSubscriptionId(DEFAULT_SUBID))
.thenReturn(mMockTelephonyManager);
when(mMockCarrierConfigManager.getConfigForSubId(DEFAULT_SLOT_INDEX)).thenReturn(bundle);
+ when(mMockCarrierConfigManager.getConfigForSubId(anyInt(), anyString())).thenReturn(bundle);
}
private void setVariable(Object target, String variableName, Object value) throws Exception {