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