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