1 /*
2  * Copyright 2020 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.google.android.iwlan.epdg;
18 
19 import android.net.ipsec.ike.IkeSaProposal;
20 import android.util.Pair;
21 
22 import java.util.LinkedHashSet;
23 
24 public class EpdgIkeSaProposal extends EpdgSaProposal {
25     protected final LinkedHashSet<Integer> mProposedPrfAlgos = new LinkedHashSet<>();
26 
27     /**
28      * Add proposed PRF algorithms by the carrier.
29      *
30      * @param prfAlgos proposed PRF algorithms
31      */
addProposedPrfAlgorithm(int[] prfAlgos)32     public void addProposedPrfAlgorithm(int[] prfAlgos) {
33         for (int prfAlgo : prfAlgos) {
34             if (validateConfig(prfAlgo, VALID_PRF_ALGOS, CONFIG_TYPE_PRF_ALGO)) {
35                 mProposedPrfAlgos.add(prfAlgo);
36             }
37         }
38     }
39 
getPrfAlgos()40     private int[] getPrfAlgos() {
41         if (isSaferProposalsPrioritized()) {
42             return mProposedPrfAlgos.stream()
43                     .sorted(
44                             (item1, item2) ->
45                                     compareTransformPriority(VALID_PRF_ALGOS, item1, item2))
46                     .mapToInt(Integer::intValue)
47                     .toArray();
48         }
49 
50         return mProposedPrfAlgos.stream().mapToInt(Integer::intValue).toArray();
51     }
52 
getSupportedPrfAlgos()53     private int[] getSupportedPrfAlgos() {
54         return VALID_PRF_ALGOS.stream().mapToInt(Integer::intValue).toArray();
55     }
56 
57     /**
58      * Builds {@link IkeSaProposal} of carrier proposed encryption algorithms (non-AEAD) cipher
59      * suit.
60      */
buildProposedIkeSaProposal()61     public IkeSaProposal buildProposedIkeSaProposal() {
62         return buildProposal(false, true);
63     }
64 
65     /** Builds {@link IkeSaProposal} of carrier proposed AEAD algorithms cipher suit. */
buildProposedIkeSaAeadProposal()66     public IkeSaProposal buildProposedIkeSaAeadProposal() {
67         return buildProposal(true, true);
68     }
69 
70     /**
71      * Builds {@link IkeSaProposal} of Iwlan supported encryption algorithms (non-AEAD) cipher suit.
72      */
buildSupportedIkeSaProposal()73     public IkeSaProposal buildSupportedIkeSaProposal() {
74         return buildProposal(false, false);
75     }
76 
77     /** Builds {@link IkeSaProposal} of Iwlan supported AEAD algorithms cipher suit. */
buildSupportedIkeSaAeadProposal()78     public IkeSaProposal buildSupportedIkeSaAeadProposal() {
79         return buildProposal(true, false);
80     }
81 
buildProposal(boolean isAead, boolean isProposed)82     private IkeSaProposal buildProposal(boolean isAead, boolean isProposed) {
83         IkeSaProposal.Builder saProposalBuilder = new IkeSaProposal.Builder();
84 
85         int[] dhGroups = isProposed ? getDhGroups() : getSupportedDhGroups();
86         for (int dhGroup : dhGroups) {
87             saProposalBuilder.addDhGroup(dhGroup);
88         }
89 
90         Pair<Integer, Integer>[] encrAlgos;
91 
92         if (isAead) {
93             encrAlgos = (isProposed) ? getAeadAlgos() : getSupportedAeadAlgos();
94         } else {
95             encrAlgos = (isProposed) ? getEncryptionAlgos() : getSupportedEncryptionAlgos();
96         }
97 
98         for (Pair<Integer, Integer> encrAlgo : encrAlgos) {
99             saProposalBuilder.addEncryptionAlgorithm(encrAlgo.first, encrAlgo.second);
100         }
101 
102         if (!isAead) {
103             int[] integrityAlgos =
104                     (isProposed) ? getIntegrityAlgos() : getSupportedIntegrityAlgos();
105             for (int integrityAlgo : integrityAlgos) {
106                 saProposalBuilder.addIntegrityAlgorithm(integrityAlgo);
107             }
108         }
109 
110         int[] prfAlgos = (isProposed) ? getPrfAlgos() : getSupportedPrfAlgos();
111         for (int prfAlgo : prfAlgos) {
112             saProposalBuilder.addPseudorandomFunction(prfAlgo);
113         }
114 
115         return saProposalBuilder.build();
116     }
117 }
118