181ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry/*
281ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry * Copyright (C) 2017 The Android Open Source Project
381ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry *
481ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry * Licensed under the Apache License, Version 2.0 (the "License");
581ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry * you may not use this file except in compliance with the License.
681ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry * You may obtain a copy of the License at
781ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry *
881ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry *      http://www.apache.org/licenses/LICENSE-2.0
981ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry *
1081ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry * Unless required by applicable law or agreed to in writing, software
1181ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry * distributed under the License is distributed on an "AS IS" BASIS,
1281ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1381ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry * See the License for the specific language governing permissions and
1481ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry * limitations under the License.
1581ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry */
1681ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry
1781ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berrypackage android.security.keystore.recovery;
1881ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry
1981ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berryimport android.annotation.IntDef;
2081ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berryimport android.annotation.NonNull;
21f8ae5deba2911b7bc8441df31c0504eaaa687addDmitry Dementyevimport android.annotation.SystemApi;
2281ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berryimport android.os.Parcel;
2381ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berryimport android.os.Parcelable;
2481ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry
2581ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berryimport com.android.internal.util.Preconditions;
2681ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry
2781ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berryimport java.lang.annotation.Retention;
2881ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berryimport java.lang.annotation.RetentionPolicy;
2981ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry
3081ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry/**
3181ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry * Collection of parameters which define a key derivation function.
32c1742e51378c3ec99a0e5df14dc0c77bcca0d16aAseem Kumar * Currently only supports salted SHA-256.
3381ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry *
3481ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry * @hide
3581ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry */
36f8ae5deba2911b7bc8441df31c0504eaaa687addDmitry Dementyev@SystemApi
3781ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berrypublic final class KeyDerivationParams implements Parcelable {
3852c15f1699e60c0701cc21a69847a005efe87bc9Robert Berry
3952c15f1699e60c0701cc21a69847a005efe87bc9Robert Berry    // IMPORTANT! PLEASE READ!
4052c15f1699e60c0701cc21a69847a005efe87bc9Robert Berry    // -----------------------
4152c15f1699e60c0701cc21a69847a005efe87bc9Robert Berry    // If you edit this file (e.g., to add new fields), please MAKE SURE to also do the following:
4252c15f1699e60c0701cc21a69847a005efe87bc9Robert Berry    // - Update the #writeToParcel(Parcel) method below
4352c15f1699e60c0701cc21a69847a005efe87bc9Robert Berry    // - Update the #(Parcel) constructor below
4452c15f1699e60c0701cc21a69847a005efe87bc9Robert Berry    // - Update android.security.keystore.recovery.KeyChainSnapshotTest to make sure nobody
4552c15f1699e60c0701cc21a69847a005efe87bc9Robert Berry    //     accidentally breaks your fields in the Parcel in the future.
4652c15f1699e60c0701cc21a69847a005efe87bc9Robert Berry    // - Update com.android.server.locksettings.recoverablekeystore.serialization
4752c15f1699e60c0701cc21a69847a005efe87bc9Robert Berry    //     .KeyChainSnapshotSerializer to correctly serialize your new field
4852c15f1699e60c0701cc21a69847a005efe87bc9Robert Berry    // - Update com.android.server.locksettings.recoverablekeystore.serialization
4952c15f1699e60c0701cc21a69847a005efe87bc9Robert Berry    //     .KeyChainSnapshotSerializer to correctly deserialize your new field
5052c15f1699e60c0701cc21a69847a005efe87bc9Robert Berry    // - Update com.android.server.locksettings.recoverablekeystore.serialization
5152c15f1699e60c0701cc21a69847a005efe87bc9Robert Berry    //     .KeychainSnapshotSerializerTest to make sure nobody breaks serialization of your field
5252c15f1699e60c0701cc21a69847a005efe87bc9Robert Berry    //     in the future.
5352c15f1699e60c0701cc21a69847a005efe87bc9Robert Berry
5481ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry    private final int mAlgorithm;
55e066a59436579f8d7961e97e4aef6e26e5e1c659Bo Zhu    private final byte[] mSalt;
5640d8a45b23fef543f183bfc2a061ec7d96b6e252Bo Zhu    private final int mMemoryDifficulty;
5781ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry
5881ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry    /** @hide */
5981ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry    @Retention(RetentionPolicy.SOURCE)
60e066a59436579f8d7961e97e4aef6e26e5e1c659Bo Zhu    @IntDef(prefix = {"ALGORITHM_"}, value = {ALGORITHM_SHA256, ALGORITHM_SCRYPT})
6181ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry    public @interface KeyDerivationAlgorithm {
6281ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry    }
6381ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry
6481ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry    /**
65e066a59436579f8d7961e97e4aef6e26e5e1c659Bo Zhu     * Salted SHA256.
6681ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry     */
6781ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry    public static final int ALGORITHM_SHA256 = 1;
6881ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry
6981ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry    /**
70e066a59436579f8d7961e97e4aef6e26e5e1c659Bo Zhu     * SCRYPT.
7181ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry     */
72e066a59436579f8d7961e97e4aef6e26e5e1c659Bo Zhu    public static final int ALGORITHM_SCRYPT = 2;
7381ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry
7481ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry    /**
7540d8a45b23fef543f183bfc2a061ec7d96b6e252Bo Zhu     * Creates instance of the class to to derive keys using salted SHA256 hash.
7640d8a45b23fef543f183bfc2a061ec7d96b6e252Bo Zhu     *
7740d8a45b23fef543f183bfc2a061ec7d96b6e252Bo Zhu     * <p>The salted SHA256 hash is computed over the concatenation of four byte strings, salt_len +
78ba94b9ab002758a19e016f7c06f003def5b61ad4Bo Zhu     * salt + key_material_len + key_material, where salt_len and key_material_len are 4-byte, and
7940d8a45b23fef543f183bfc2a061ec7d96b6e252Bo Zhu     * denote the number of bytes for salt and key_material, respectively.
8081ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry     */
81fd4ae0b2ddd58f6acbb19632f20e40024e3d85b1Dmitry Dementyev    public static @NonNull KeyDerivationParams createSha256Params(@NonNull byte[] salt) {
8281ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry        return new KeyDerivationParams(ALGORITHM_SHA256, salt);
8381ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry    }
8481ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry
85f8ae5deba2911b7bc8441df31c0504eaaa687addDmitry Dementyev    /**
8640d8a45b23fef543f183bfc2a061ec7d96b6e252Bo Zhu     * Creates instance of the class to to derive keys using the password hashing algorithm SCRYPT.
87e066a59436579f8d7961e97e4aef6e26e5e1c659Bo Zhu     *
8840d8a45b23fef543f183bfc2a061ec7d96b6e252Bo Zhu     * <p>We expose only one tuning parameter of SCRYPT, which is the memory cost parameter (i.e. N
8940d8a45b23fef543f183bfc2a061ec7d96b6e252Bo Zhu     * in <a href="https://www.tarsnap.com/scrypt/scrypt.pdf">the SCRYPT paper</a>). Regular/default
9040d8a45b23fef543f183bfc2a061ec7d96b6e252Bo Zhu     * values are used for the other parameters, to keep the overall running time low. Specifically,
9140d8a45b23fef543f183bfc2a061ec7d96b6e252Bo Zhu     * the parallelization parameter p is 1, the block size parameter r is 8, and the hashing output
9240d8a45b23fef543f183bfc2a061ec7d96b6e252Bo Zhu     * length is 32-byte.
93e066a59436579f8d7961e97e4aef6e26e5e1c659Bo Zhu     */
94fd4ae0b2ddd58f6acbb19632f20e40024e3d85b1Dmitry Dementyev    public static @NonNull KeyDerivationParams createScryptParams(
9540d8a45b23fef543f183bfc2a061ec7d96b6e252Bo Zhu            @NonNull byte[] salt, int memoryDifficulty) {
9640d8a45b23fef543f183bfc2a061ec7d96b6e252Bo Zhu        return new KeyDerivationParams(ALGORITHM_SCRYPT, salt, memoryDifficulty);
97e066a59436579f8d7961e97e4aef6e26e5e1c659Bo Zhu    }
98e066a59436579f8d7961e97e4aef6e26e5e1c659Bo Zhu
99e066a59436579f8d7961e97e4aef6e26e5e1c659Bo Zhu    /**
100f8ae5deba2911b7bc8441df31c0504eaaa687addDmitry Dementyev     * @hide
101f8ae5deba2911b7bc8441df31c0504eaaa687addDmitry Dementyev     */
102fd4ae0b2ddd58f6acbb19632f20e40024e3d85b1Dmitry Dementyev    private KeyDerivationParams(@KeyDerivationAlgorithm int algorithm, @NonNull byte[] salt) {
10340d8a45b23fef543f183bfc2a061ec7d96b6e252Bo Zhu        this(algorithm, salt, /*memoryDifficulty=*/ -1);
104e066a59436579f8d7961e97e4aef6e26e5e1c659Bo Zhu    }
105e066a59436579f8d7961e97e4aef6e26e5e1c659Bo Zhu
106e066a59436579f8d7961e97e4aef6e26e5e1c659Bo Zhu    /**
107e066a59436579f8d7961e97e4aef6e26e5e1c659Bo Zhu     * @hide
108e066a59436579f8d7961e97e4aef6e26e5e1c659Bo Zhu     */
10986f5bb1a8cfe2d169767fb723d315955dda3a0e6Dmitry Dementyev    private KeyDerivationParams(@KeyDerivationAlgorithm int algorithm, @NonNull byte[] salt,
11040d8a45b23fef543f183bfc2a061ec7d96b6e252Bo Zhu            int memoryDifficulty) {
11181ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry        mAlgorithm = algorithm;
11281ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry        mSalt = Preconditions.checkNotNull(salt);
11340d8a45b23fef543f183bfc2a061ec7d96b6e252Bo Zhu        mMemoryDifficulty = memoryDifficulty;
11481ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry    }
11581ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry
11681ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry    /**
11781ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry     * Gets algorithm.
11881ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry     */
11981ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry    public @KeyDerivationAlgorithm int getAlgorithm() {
12081ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry        return mAlgorithm;
12181ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry    }
12281ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry
12381ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry    /**
12481ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry     * Gets salt.
12581ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry     */
12681ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry    public @NonNull byte[] getSalt() {
12781ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry        return mSalt;
12881ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry    }
12981ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry
130e066a59436579f8d7961e97e4aef6e26e5e1c659Bo Zhu    /**
13140d8a45b23fef543f183bfc2a061ec7d96b6e252Bo Zhu     * Gets the memory difficulty parameter for the hashing algorithm.
132e066a59436579f8d7961e97e4aef6e26e5e1c659Bo Zhu     *
13340d8a45b23fef543f183bfc2a061ec7d96b6e252Bo Zhu     * <p>The effect of this parameter depends on the algorithm in use. For example, please see
13440d8a45b23fef543f183bfc2a061ec7d96b6e252Bo Zhu     * {@link #createScryptParams(byte[], int)} for choosing the parameter for SCRYPT.
13540d8a45b23fef543f183bfc2a061ec7d96b6e252Bo Zhu     *
13640d8a45b23fef543f183bfc2a061ec7d96b6e252Bo Zhu     * <p>If the specific algorithm does not support such a memory difficulty parameter, its value
13740d8a45b23fef543f183bfc2a061ec7d96b6e252Bo Zhu     * should be -1.
138e066a59436579f8d7961e97e4aef6e26e5e1c659Bo Zhu     */
13940d8a45b23fef543f183bfc2a061ec7d96b6e252Bo Zhu    public int getMemoryDifficulty() {
14040d8a45b23fef543f183bfc2a061ec7d96b6e252Bo Zhu        return mMemoryDifficulty;
141e066a59436579f8d7961e97e4aef6e26e5e1c659Bo Zhu    }
142e066a59436579f8d7961e97e4aef6e26e5e1c659Bo Zhu
1430916e7ca44aba5e6c89d75007da805697fdace9eDmitry Dementyev    public static final Parcelable.Creator<KeyDerivationParams> CREATOR =
1440916e7ca44aba5e6c89d75007da805697fdace9eDmitry Dementyev            new Parcelable.Creator<KeyDerivationParams>() {
14581ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry        public KeyDerivationParams createFromParcel(Parcel in) {
14681ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry                return new KeyDerivationParams(in);
14781ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry        }
14881ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry
14981ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry        public KeyDerivationParams[] newArray(int length) {
15081ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry            return new KeyDerivationParams[length];
15181ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry        }
15281ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry    };
15381ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry
15481ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry    @Override
15581ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry    public void writeToParcel(Parcel out, int flags) {
15681ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry        out.writeInt(mAlgorithm);
15781ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry        out.writeByteArray(mSalt);
15840d8a45b23fef543f183bfc2a061ec7d96b6e252Bo Zhu        out.writeInt(mMemoryDifficulty);
15981ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry    }
16081ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry
16181ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry    /**
16281ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry     * @hide
16381ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry     */
16481ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry    protected KeyDerivationParams(Parcel in) {
16581ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry        mAlgorithm = in.readInt();
16681ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry        mSalt = in.createByteArray();
16740d8a45b23fef543f183bfc2a061ec7d96b6e252Bo Zhu        mMemoryDifficulty = in.readInt();
16881ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry    }
16981ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry
17081ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry    @Override
17181ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry    public int describeContents() {
17281ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry        return 0;
17381ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry    }
17481ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry}
175