IpSecAlgorithm.java revision 330e1089da80cddcd68758512370d217b19f8890
1/* 2 * Copyright (C) 2017 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 */ 16package android.net; 17 18import android.annotation.StringDef; 19import android.os.Parcel; 20import android.os.Parcelable; 21import java.lang.annotation.Retention; 22import java.lang.annotation.RetentionPolicy; 23 24/** 25 * IpSecAlgorithm specifies a single algorithm that can be applied to an IpSec Transform. Refer to 26 * RFC 4301. 27 */ 28public final class IpSecAlgorithm implements Parcelable { 29 30 /** 31 * AES-CBC Encryption/Ciphering Algorithm. 32 * 33 * <p>Valid lengths for this key are {128, 192, 256}. 34 */ 35 public static final String ALGO_CRYPT_AES_CBC = "cbc(aes)"; 36 37 /** 38 * MD5 HMAC Authentication/Integrity Algorithm. This algorithm is not recommended for use in new 39 * applications and is provided for legacy compatibility with 3gpp infrastructure. 40 * 41 * <p>Valid truncation lengths are multiples of 8 bits from 96 to (default) 128. 42 */ 43 public static final String ALGO_AUTH_HMAC_MD5 = "hmac(md5)"; 44 45 /** 46 * SHA1 HMAC Authentication/Integrity Algorithm. This algorithm is not recommended for use in 47 * new applications and is provided for legacy compatibility with 3gpp infrastructure. 48 * 49 * <p>Valid truncation lengths are multiples of 8 bits from 96 to (default) 160. 50 */ 51 public static final String ALGO_AUTH_HMAC_SHA1 = "hmac(sha1)"; 52 53 /** 54 * SHA256 HMAC Authentication/Integrity Algorithm. 55 * 56 * <p>Valid truncation lengths are multiples of 8 bits from 96 to (default) 256. 57 */ 58 public static final String ALGO_AUTH_HMAC_SHA256 = "hmac(sha256)"; 59 60 /** 61 * SHA384 HMAC Authentication/Integrity Algorithm. 62 * 63 * <p>Valid truncation lengths are multiples of 8 bits from 192 to (default) 384. 64 */ 65 public static final String ALGO_AUTH_HMAC_SHA384 = "hmac(sha384)"; 66 /** 67 * SHA512 HMAC Authentication/Integrity Algorithm 68 * 69 * <p>Valid truncation lengths are multiples of 8 bits from 256 to (default) 512. 70 */ 71 public static final String ALGO_AUTH_HMAC_SHA512 = "hmac(sha512)"; 72 73 /** @hide */ 74 @StringDef({ 75 ALGO_CRYPT_AES_CBC, 76 ALGO_AUTH_HMAC_MD5, 77 ALGO_AUTH_HMAC_SHA1, 78 ALGO_AUTH_HMAC_SHA256, 79 ALGO_AUTH_HMAC_SHA512 80 }) 81 @Retention(RetentionPolicy.SOURCE) 82 public @interface AlgorithmName {} 83 84 private final String mName; 85 private final byte[] mKey; 86 private final int mTruncLenBits; 87 88 /** 89 * Specify a IpSecAlgorithm of one of the supported types including the truncation length of the 90 * algorithm 91 * 92 * @param algorithm type for IpSec. 93 * @param key non-null Key padded to a multiple of 8 bits. 94 */ 95 public IpSecAlgorithm(String algorithm, byte[] key) { 96 this(algorithm, key, key.length * 8); 97 } 98 99 /** 100 * Specify a IpSecAlgorithm of one of the supported types including the truncation length of the 101 * algorithm 102 * 103 * @param algoName precise name of the algorithm to be used. 104 * @param key non-null Key padded to a multiple of 8 bits. 105 * @param truncLenBits the number of bits of output hash to use; only meaningful for 106 * Authentication. 107 */ 108 public IpSecAlgorithm(@AlgorithmName String algoName, byte[] key, int truncLenBits) { 109 if (!isTruncationLengthValid(algoName, truncLenBits)) { 110 throw new IllegalArgumentException("Unknown algorithm or invalid length"); 111 } 112 mName = algoName; 113 mKey = key.clone(); 114 mTruncLenBits = Math.min(truncLenBits, key.length * 8); 115 } 116 117 /** Retrieve the algorithm name */ 118 public String getName() { 119 return mName; 120 } 121 122 /** Retrieve the key for this algorithm */ 123 public byte[] getKey() { 124 return mKey.clone(); 125 } 126 127 /** 128 * Retrieve the truncation length, in bits, for the key in this algo. By default this will be 129 * the length in bits of the key. 130 */ 131 public int getTruncationLengthBits() { 132 return mTruncLenBits; 133 } 134 135 /* Parcelable Implementation */ 136 public int describeContents() { 137 return 0; 138 } 139 140 /** Write to parcel */ 141 public void writeToParcel(Parcel out, int flags) { 142 out.writeString(mName); 143 out.writeByteArray(mKey); 144 out.writeInt(mTruncLenBits); 145 } 146 147 /** Parcelable Creator */ 148 public static final Parcelable.Creator<IpSecAlgorithm> CREATOR = 149 new Parcelable.Creator<IpSecAlgorithm>() { 150 public IpSecAlgorithm createFromParcel(Parcel in) { 151 return new IpSecAlgorithm(in); 152 } 153 154 public IpSecAlgorithm[] newArray(int size) { 155 return new IpSecAlgorithm[size]; 156 } 157 }; 158 159 private IpSecAlgorithm(Parcel in) { 160 mName = in.readString(); 161 mKey = in.createByteArray(); 162 mTruncLenBits = in.readInt(); 163 } 164 165 private static boolean isTruncationLengthValid(String algo, int truncLenBits) { 166 switch (algo) { 167 case ALGO_AUTH_HMAC_MD5: 168 return (truncLenBits >= 96 && truncLenBits <= 128); 169 case ALGO_AUTH_HMAC_SHA1: 170 return (truncLenBits >= 96 && truncLenBits <= 160); 171 case ALGO_AUTH_HMAC_SHA256: 172 return (truncLenBits >= 96 && truncLenBits <= 256); 173 case ALGO_AUTH_HMAC_SHA384: 174 return (truncLenBits >= 192 && truncLenBits <= 384); 175 case ALGO_AUTH_HMAC_SHA512: 176 return (truncLenBits >= 256 && truncLenBits <= 512); 177 default: 178 return false; 179 } 180 } 181}; 182