KeyDerivationParams.java revision fd4ae0b2ddd58f6acbb19632f20e40024e3d85b1
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 */
16
17package android.security.keystore.recovery;
18
19import android.annotation.IntDef;
20import android.annotation.NonNull;
21import android.annotation.SystemApi;
22import android.os.Parcel;
23import android.os.Parcelable;
24
25import com.android.internal.util.Preconditions;
26
27import java.lang.annotation.Retention;
28import java.lang.annotation.RetentionPolicy;
29
30/**
31 * Collection of parameters which define a key derivation function.
32 * Currently only supports salted SHA-256.
33 *
34 * @hide
35 */
36@SystemApi
37public final class KeyDerivationParams implements Parcelable {
38    private final int mAlgorithm;
39    private final byte[] mSalt;
40    private final int mMemoryDifficulty;
41
42    /** @hide */
43    @Retention(RetentionPolicy.SOURCE)
44    @IntDef(prefix = {"ALGORITHM_"}, value = {ALGORITHM_SHA256, ALGORITHM_SCRYPT})
45    public @interface KeyDerivationAlgorithm {
46    }
47
48    /**
49     * Salted SHA256.
50     */
51    public static final int ALGORITHM_SHA256 = 1;
52
53    /**
54     * SCRYPT.
55     */
56    public static final int ALGORITHM_SCRYPT = 2;
57
58    /**
59     * Creates instance of the class to to derive keys using salted SHA256 hash.
60     *
61     * <p>The salted SHA256 hash is computed over the concatenation of four byte strings, salt_len +
62     * salt + key_material_len + key_material, where salt_len and key_material_len are one-byte, and
63     * denote the number of bytes for salt and key_material, respectively.
64     */
65    public static @NonNull KeyDerivationParams createSha256Params(@NonNull byte[] salt) {
66        return new KeyDerivationParams(ALGORITHM_SHA256, salt);
67    }
68
69    /**
70     * Creates instance of the class to to derive keys using the password hashing algorithm SCRYPT.
71     *
72     * <p>We expose only one tuning parameter of SCRYPT, which is the memory cost parameter (i.e. N
73     * in <a href="https://www.tarsnap.com/scrypt/scrypt.pdf">the SCRYPT paper</a>). Regular/default
74     * values are used for the other parameters, to keep the overall running time low. Specifically,
75     * the parallelization parameter p is 1, the block size parameter r is 8, and the hashing output
76     * length is 32-byte.
77     */
78    public static @NonNull KeyDerivationParams createScryptParams(
79            @NonNull byte[] salt, int memoryDifficulty) {
80        return new KeyDerivationParams(ALGORITHM_SCRYPT, salt, memoryDifficulty);
81    }
82
83    /**
84     * @hide
85     */
86    private KeyDerivationParams(@KeyDerivationAlgorithm int algorithm, @NonNull byte[] salt) {
87        this(algorithm, salt, /*memoryDifficulty=*/ -1);
88    }
89
90    /**
91     * @hide
92     */
93    KeyDerivationParams(@KeyDerivationAlgorithm int algorithm, @NonNull byte[] salt,
94            int memoryDifficulty) {
95        mAlgorithm = algorithm;
96        mSalt = Preconditions.checkNotNull(salt);
97        mMemoryDifficulty = memoryDifficulty;
98    }
99
100    /**
101     * Gets algorithm.
102     */
103    public @KeyDerivationAlgorithm int getAlgorithm() {
104        return mAlgorithm;
105    }
106
107    /**
108     * Gets salt.
109     */
110    public @NonNull byte[] getSalt() {
111        return mSalt;
112    }
113
114    /**
115     * Gets the memory difficulty parameter for the hashing algorithm.
116     *
117     * <p>The effect of this parameter depends on the algorithm in use. For example, please see
118     * {@link #createScryptParams(byte[], int)} for choosing the parameter for SCRYPT.
119     *
120     * <p>If the specific algorithm does not support such a memory difficulty parameter, its value
121     * should be -1.
122     */
123    public int getMemoryDifficulty() {
124        return mMemoryDifficulty;
125    }
126
127    public static final Parcelable.Creator<KeyDerivationParams> CREATOR =
128            new Parcelable.Creator<KeyDerivationParams>() {
129        public KeyDerivationParams createFromParcel(Parcel in) {
130                return new KeyDerivationParams(in);
131        }
132
133        public KeyDerivationParams[] newArray(int length) {
134            return new KeyDerivationParams[length];
135        }
136    };
137
138    @Override
139    public void writeToParcel(Parcel out, int flags) {
140        out.writeInt(mAlgorithm);
141        out.writeByteArray(mSalt);
142        out.writeInt(mMemoryDifficulty);
143    }
144
145    /**
146     * @hide
147     */
148    protected KeyDerivationParams(Parcel in) {
149        mAlgorithm = in.readInt();
150        mSalt = in.createByteArray();
151        mMemoryDifficulty = in.readInt();
152    }
153
154    @Override
155    public int describeContents() {
156        return 0;
157    }
158}
159