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