1ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward/*
2ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward * Copyright (C) 2012 The Android Open Source Project
3ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward *
4ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward * Licensed under the Apache License, Version 2.0 (the "License");
5ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward * you may not use this file except in compliance with the License.
6ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward * You may obtain a copy of the License at
7ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward *
8ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward *      http://www.apache.org/licenses/LICENSE-2.0
9ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward *
10ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward * Unless required by applicable law or agreed to in writing, software
11ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward * distributed under the License is distributed on an "AS IS" BASIS,
12ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward * See the License for the specific language governing permissions and
14ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward * limitations under the License.
15ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward */
16ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward
17ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Cowardpackage android.content.pm;
18ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward
19d5a5b5a547462f3e7c6315a501909bce2418ba86Jeff Brownimport android.annotation.SystemApi;
20ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Cowardimport android.os.Parcel;
21ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Cowardimport android.os.Parcelable;
22ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Cowardimport android.text.TextUtils;
23ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Cowardimport android.util.Slog;
24ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward
25ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Cowardimport java.security.InvalidAlgorithmParameterException;
26ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Cowardimport java.security.spec.AlgorithmParameterSpec;
27ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Cowardimport java.util.Arrays;
28ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward
29ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Cowardimport javax.crypto.SecretKey;
30ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Cowardimport javax.crypto.spec.IvParameterSpec;
31ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward
32ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward/**
33ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward * Represents encryption parameters used to read a container.
34ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward *
353a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey * @deprecated encrypted containers are legacy.
36ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward * @hide
37ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward */
38d5a5b5a547462f3e7c6315a501909bce2418ba86Jeff Brown@SystemApi
393a44f3f1b446315ef894e01d2ab9b5388c2bd8c4Jeff Sharkey@Deprecated
40ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Cowardpublic class ContainerEncryptionParams implements Parcelable {
41ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward    protected static final String TAG = "ContainerEncryptionParams";
42ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward
43ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward    /** What we print out first when toString() is called. */
44ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward    private static final String TO_STRING_PREFIX = "ContainerEncryptionParams{";
45ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward
46ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward    /**
47ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward     * Parameter type for parceling that indicates the next parameters are
48ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward     * IvParameters.
49ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward     */
50ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward    private static final int ENC_PARAMS_IV_PARAMETERS = 1;
51ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward
52ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward    /** Parameter type for paceling that indicates there are no MAC parameters. */
53ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward    private static final int MAC_PARAMS_NONE = 1;
54ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward
55ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward    /** The encryption algorithm used. */
56ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward    private final String mEncryptionAlgorithm;
57ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward
58ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward    /** The parameter spec to be used for encryption. */
59ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward    private final IvParameterSpec mEncryptionSpec;
60ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward
61ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward    /** Secret key to be used for decryption. */
62ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward    private final SecretKey mEncryptionKey;
63ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward
64ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward    /** Algorithm name for the MAC to be used. */
65ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward    private final String mMacAlgorithm;
66ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward
67ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward    /** The parameter spec to be used for the MAC tag authentication. */
68ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward    private final AlgorithmParameterSpec mMacSpec;
69ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward
70ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward    /** Secret key to be used for MAC tag authentication. */
71ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward    private final SecretKey mMacKey;
72ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward
73ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward    /** MAC tag authenticating the data in the container. */
74ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward    private final byte[] mMacTag;
75ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward
76ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward    /** Offset into file where authenticated (e.g., MAC protected) data begins. */
77103d53005e7a3c2735f4ac76fa9b795a7e7e39d7Kenny Root    private final long mAuthenticatedDataStart;
78ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward
79ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward    /** Offset into file where encrypted data begins. */
80103d53005e7a3c2735f4ac76fa9b795a7e7e39d7Kenny Root    private final long mEncryptedDataStart;
81ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward
82ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward    /**
83ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward     * Offset into file for the end of encrypted data (and, by extension,
84ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward     * authenticated data) in file.
85ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward     */
86103d53005e7a3c2735f4ac76fa9b795a7e7e39d7Kenny Root    private final long mDataEnd;
87ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward
88ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward    public ContainerEncryptionParams(String encryptionAlgorithm,
89ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward            AlgorithmParameterSpec encryptionSpec, SecretKey encryptionKey)
90ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward            throws InvalidAlgorithmParameterException {
91ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        this(encryptionAlgorithm, encryptionSpec, encryptionKey, null, null, null, null, -1, -1,
92ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward                -1);
93ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward    }
94ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward
95ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward    /**
96ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward     * Creates container encryption specifications for installing from encrypted
97ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward     * containers.
98ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward     *
99ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward     * @param encryptionAlgorithm encryption algorithm to use; format matches
100ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward     *            JCE
101ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward     * @param encryptionSpec algorithm parameter specification
102ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward     * @param encryptionKey key used for decryption
103ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward     * @param macAlgorithm MAC algorithm to use; format matches JCE
104ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward     * @param macSpec algorithm parameters specification, may be {@code null}
105ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward     * @param macKey key used for authentication (i.e., for the MAC tag)
106103d53005e7a3c2735f4ac76fa9b795a7e7e39d7Kenny Root     * @param macTag message authentication code (MAC) tag for the authenticated
107103d53005e7a3c2735f4ac76fa9b795a7e7e39d7Kenny Root     *            data
108ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward     * @param authenticatedDataStart offset of start of authenticated data in
109ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward     *            stream
110ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward     * @param encryptedDataStart offset of start of encrypted data in stream
111ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward     * @param dataEnd offset of the end of both the authenticated and encrypted
112ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward     *            data
113ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward     * @throws InvalidAlgorithmParameterException
114ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward     */
115ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward    public ContainerEncryptionParams(String encryptionAlgorithm,
116ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward            AlgorithmParameterSpec encryptionSpec, SecretKey encryptionKey, String macAlgorithm,
117ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward            AlgorithmParameterSpec macSpec, SecretKey macKey, byte[] macTag,
118103d53005e7a3c2735f4ac76fa9b795a7e7e39d7Kenny Root            long authenticatedDataStart, long encryptedDataStart, long dataEnd)
119ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward            throws InvalidAlgorithmParameterException {
120ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        if (TextUtils.isEmpty(encryptionAlgorithm)) {
121ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward            throw new NullPointerException("algorithm == null");
122ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        } else if (encryptionSpec == null) {
123ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward            throw new NullPointerException("encryptionSpec == null");
124ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        } else if (encryptionKey == null) {
125ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward            throw new NullPointerException("encryptionKey == null");
126ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        }
127ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward
128ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        if (!TextUtils.isEmpty(macAlgorithm)) {
129ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward            if (macKey == null) {
130ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward                throw new NullPointerException("macKey == null");
131ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward            }
132ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        }
133ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward
134ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        if (!(encryptionSpec instanceof IvParameterSpec)) {
135ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward            throw new InvalidAlgorithmParameterException(
136ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward                    "Unknown parameter spec class; must be IvParameters");
137ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        }
138ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward
139ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        mEncryptionAlgorithm = encryptionAlgorithm;
140ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        mEncryptionSpec = (IvParameterSpec) encryptionSpec;
141ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        mEncryptionKey = encryptionKey;
142ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward
143ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        mMacAlgorithm = macAlgorithm;
144ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        mMacSpec = macSpec;
145ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        mMacKey = macKey;
146ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        mMacTag = macTag;
147ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward
148ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        mAuthenticatedDataStart = authenticatedDataStart;
149ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        mEncryptedDataStart = encryptedDataStart;
150ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        mDataEnd = dataEnd;
151ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward    }
152ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward
153ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward    public String getEncryptionAlgorithm() {
154ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        return mEncryptionAlgorithm;
155ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward    }
156ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward
157ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward    public AlgorithmParameterSpec getEncryptionSpec() {
158ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        return mEncryptionSpec;
159ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward    }
160ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward
161ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward    public SecretKey getEncryptionKey() {
162ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        return mEncryptionKey;
163ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward    }
164ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward
165ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward    public String getMacAlgorithm() {
166ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        return mMacAlgorithm;
167ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward    }
168ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward
169ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward    public AlgorithmParameterSpec getMacSpec() {
170ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        return mMacSpec;
171ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward    }
172ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward
173ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward    public SecretKey getMacKey() {
174ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        return mMacKey;
175ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward    }
176ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward
177ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward    public byte[] getMacTag() {
178ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        return mMacTag;
179ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward    }
180ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward
181103d53005e7a3c2735f4ac76fa9b795a7e7e39d7Kenny Root    public long getAuthenticatedDataStart() {
182ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        return mAuthenticatedDataStart;
183ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward    }
184ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward
185103d53005e7a3c2735f4ac76fa9b795a7e7e39d7Kenny Root    public long getEncryptedDataStart() {
186ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        return mEncryptedDataStart;
187ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward    }
188ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward
189103d53005e7a3c2735f4ac76fa9b795a7e7e39d7Kenny Root    public long getDataEnd() {
190ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        return mDataEnd;
191ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward    }
192ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward
193ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward    @Override
194ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward    public int describeContents() {
195ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        return 0;
196ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward    }
197ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward
198ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward    @Override
199ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward    public boolean equals(Object o) {
200ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        if (this == o) {
201ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward            return true;
202ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        }
203ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward
204ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        if (!(o instanceof ContainerEncryptionParams)) {
205ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward            return false;
206ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        }
207ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward
208ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        final ContainerEncryptionParams other = (ContainerEncryptionParams) o;
209ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward
210ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        // Primitive comparison
211ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        if ((mAuthenticatedDataStart != other.mAuthenticatedDataStart)
212ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward                || (mEncryptedDataStart != other.mEncryptedDataStart)
213ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward                || (mDataEnd != other.mDataEnd)) {
214ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward            return false;
215ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        }
216ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward
217ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        // String comparison
218ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        if (!mEncryptionAlgorithm.equals(other.mEncryptionAlgorithm)
219ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward                || !mMacAlgorithm.equals(other.mMacAlgorithm)) {
220ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward            return false;
221ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        }
222ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward
223ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        // Object comparison
224ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        if (!isSecretKeyEqual(mEncryptionKey, other.mEncryptionKey)
225ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward                || !isSecretKeyEqual(mMacKey, other.mMacKey)) {
226ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward            return false;
227ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        }
228ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward
229ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        if (!Arrays.equals(mEncryptionSpec.getIV(), other.mEncryptionSpec.getIV())
230ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward                || !Arrays.equals(mMacTag, other.mMacTag) || (mMacSpec != other.mMacSpec)) {
231ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward            return false;
232ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        }
233ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward
234ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        return true;
235ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward    }
236ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward
237ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward    private static final boolean isSecretKeyEqual(SecretKey key1, SecretKey key2) {
238ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        final String keyFormat = key1.getFormat();
239ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        final String otherKeyFormat = key2.getFormat();
240ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward
241ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        if (keyFormat == null) {
242ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward            if (keyFormat != otherKeyFormat) {
243ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward                return false;
244ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward            }
245ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward
246ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward            if (key1.getEncoded() != key2.getEncoded()) {
247ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward                return false;
248ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward            }
249ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        } else {
250ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward            if (!keyFormat.equals(key2.getFormat())) {
251ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward                return false;
252ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward            }
253ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward
254ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward            if (!Arrays.equals(key1.getEncoded(), key2.getEncoded())) {
255ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward                return false;
256ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward            }
257ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        }
258ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward
259ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        return true;
260ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward    }
261ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward
262ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward    @Override
263ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward    public int hashCode() {
264ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        int hash = 3;
265ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward
266ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        hash += 5 * mEncryptionAlgorithm.hashCode();
267ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        hash += 7 * Arrays.hashCode(mEncryptionSpec.getIV());
268ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        hash += 11 * mEncryptionKey.hashCode();
269ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        hash += 13 * mMacAlgorithm.hashCode();
270ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        hash += 17 * mMacKey.hashCode();
271ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        hash += 19 * Arrays.hashCode(mMacTag);
272ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        hash += 23 * mAuthenticatedDataStart;
273ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        hash += 29 * mEncryptedDataStart;
274ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        hash += 31 * mDataEnd;
275ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward
276ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        return hash;
277ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward    }
278ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward
279ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward    @Override
280ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward    public String toString() {
281ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        final StringBuilder sb = new StringBuilder(TO_STRING_PREFIX);
282ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward
283ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        sb.append("mEncryptionAlgorithm=\"");
284ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        sb.append(mEncryptionAlgorithm);
285ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        sb.append("\",");
286ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        sb.append("mEncryptionSpec=");
287ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        sb.append(mEncryptionSpec.toString());
288ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        sb.append("mEncryptionKey=");
289ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        sb.append(mEncryptionKey.toString());
290ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward
291ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        sb.append("mMacAlgorithm=\"");
292ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        sb.append(mMacAlgorithm);
293ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        sb.append("\",");
294ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        sb.append("mMacSpec=");
295ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        sb.append(mMacSpec.toString());
296ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        sb.append("mMacKey=");
297ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        sb.append(mMacKey.toString());
298ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward
299ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        sb.append(",mAuthenticatedDataStart=");
300ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        sb.append(mAuthenticatedDataStart);
301ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        sb.append(",mEncryptedDataStart=");
302ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        sb.append(mEncryptedDataStart);
303ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        sb.append(",mDataEnd=");
304ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        sb.append(mDataEnd);
305ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        sb.append('}');
306ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward
307ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        return sb.toString();
308ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward    }
309ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward
310ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward    @Override
311ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward    public void writeToParcel(Parcel dest, int flags) {
312ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        dest.writeString(mEncryptionAlgorithm);
313ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        dest.writeInt(ENC_PARAMS_IV_PARAMETERS);
314ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        dest.writeByteArray(mEncryptionSpec.getIV());
315ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        dest.writeSerializable(mEncryptionKey);
316ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward
317ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        dest.writeString(mMacAlgorithm);
318ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        dest.writeInt(MAC_PARAMS_NONE);
319ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        dest.writeByteArray(new byte[0]);
320ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        dest.writeSerializable(mMacKey);
321ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward
322ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        dest.writeByteArray(mMacTag);
323ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward
324103d53005e7a3c2735f4ac76fa9b795a7e7e39d7Kenny Root        dest.writeLong(mAuthenticatedDataStart);
325103d53005e7a3c2735f4ac76fa9b795a7e7e39d7Kenny Root        dest.writeLong(mEncryptedDataStart);
326103d53005e7a3c2735f4ac76fa9b795a7e7e39d7Kenny Root        dest.writeLong(mDataEnd);
327ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward    }
328ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward
329ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward    private ContainerEncryptionParams(Parcel source) throws InvalidAlgorithmParameterException {
330ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        mEncryptionAlgorithm = source.readString();
331ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        final int encParamType = source.readInt();
332ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        final byte[] encParamsEncoded = source.createByteArray();
333ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        mEncryptionKey = (SecretKey) source.readSerializable();
334ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward
335ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        mMacAlgorithm = source.readString();
336ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        final int macParamType = source.readInt();
337ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        source.createByteArray(); // byte[] macParamsEncoded
338ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        mMacKey = (SecretKey) source.readSerializable();
339ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward
340ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        mMacTag = source.createByteArray();
341ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward
342103d53005e7a3c2735f4ac76fa9b795a7e7e39d7Kenny Root        mAuthenticatedDataStart = source.readLong();
343103d53005e7a3c2735f4ac76fa9b795a7e7e39d7Kenny Root        mEncryptedDataStart = source.readLong();
344103d53005e7a3c2735f4ac76fa9b795a7e7e39d7Kenny Root        mDataEnd = source.readLong();
345ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward
346ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        switch (encParamType) {
347ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward            case ENC_PARAMS_IV_PARAMETERS:
348ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward                mEncryptionSpec = new IvParameterSpec(encParamsEncoded);
349ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward                break;
350ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward            default:
351ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward                throw new InvalidAlgorithmParameterException("Unknown parameter type "
352ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward                        + encParamType);
353ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        }
354ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward
355ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        switch (macParamType) {
356ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward            case MAC_PARAMS_NONE:
357ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward                mMacSpec = null;
358ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward                break;
359ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward            default:
360ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward                throw new InvalidAlgorithmParameterException("Unknown parameter type "
361ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward                        + macParamType);
362ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        }
363ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward
364ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        if (mEncryptionKey == null) {
365ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward            throw new NullPointerException("encryptionKey == null");
366ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        }
367ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward    }
368ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward
369ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward    public static final Parcelable.Creator<ContainerEncryptionParams> CREATOR =
370ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward            new Parcelable.Creator<ContainerEncryptionParams>() {
371ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        public ContainerEncryptionParams createFromParcel(Parcel source) {
372ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward            try {
373ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward                return new ContainerEncryptionParams(source);
374ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward            } catch (InvalidAlgorithmParameterException e) {
375ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward                Slog.e(TAG, "Invalid algorithm parameters specified", e);
376ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward                return null;
377ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward            }
378ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        }
379ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward
380ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        public ContainerEncryptionParams[] newArray(int size) {
381ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward            return new ContainerEncryptionParams[size];
382ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        }
383ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward    };
384ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward}