/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.security.keystore.recovery;

import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Objects;

/**
 * Collection of parameters which define a key derivation function.
 * Currently only supports salted SHA-256.
 *
 * @hide
 */
@SystemApi
public final class KeyDerivationParams implements Parcelable {

    // IMPORTANT! PLEASE READ!
    // -----------------------
    // If you edit this file (e.g., to add new fields), please MAKE SURE to also do the following:
    // - Update the #writeToParcel(Parcel) method below
    // - Update the #(Parcel) constructor below
    // - Update android.security.keystore.recovery.KeyChainSnapshotTest to make sure nobody
    //     accidentally breaks your fields in the Parcel in the future.
    // - Update com.android.server.locksettings.recoverablekeystore.serialization
    //     .KeyChainSnapshotSerializer to correctly serialize your new field
    // - Update com.android.server.locksettings.recoverablekeystore.serialization
    //     .KeyChainSnapshotSerializer to correctly deserialize your new field
    // - Update com.android.server.locksettings.recoverablekeystore.serialization
    //     .KeychainSnapshotSerializerTest to make sure nobody breaks serialization of your field
    //     in the future.

    private final int mAlgorithm;
    private final byte[] mSalt;
    private final int mMemoryDifficulty;

    /** @hide */
    @Retention(RetentionPolicy.SOURCE)
    @IntDef(prefix = {"ALGORITHM_"}, value = {ALGORITHM_SHA256, ALGORITHM_SCRYPT})
    public @interface KeyDerivationAlgorithm {
    }

    /**
     * Salted SHA256.
     */
    public static final int ALGORITHM_SHA256 = 1;

    /**
     * SCRYPT.
     */
    public static final int ALGORITHM_SCRYPT = 2;

    /**
     * Creates instance of the class to to derive keys using salted SHA256 hash.
     *
     * <p>The salted SHA256 hash is computed over the concatenation of four byte strings, salt_len +
     * salt + key_material_len + key_material, where salt_len and key_material_len are 4-byte, and
     * denote the number of bytes for salt and key_material, respectively.
     */
    public static @NonNull KeyDerivationParams createSha256Params(@NonNull byte[] salt) {
        return new KeyDerivationParams(ALGORITHM_SHA256, salt);
    }

    /**
     * Creates instance of the class to to derive keys using the password hashing algorithm SCRYPT.
     *
     * <p>We expose only one tuning parameter of SCRYPT, which is the memory cost parameter (i.e. N
     * in <a href="https://www.tarsnap.com/scrypt/scrypt.pdf">the SCRYPT paper</a>). Regular/default
     * values are used for the other parameters, to keep the overall running time low. Specifically,
     * the parallelization parameter p is 1, the block size parameter r is 8, and the hashing output
     * length is 32-byte.
     */
    public static @NonNull KeyDerivationParams createScryptParams(
            @NonNull byte[] salt, int memoryDifficulty) {
        return new KeyDerivationParams(ALGORITHM_SCRYPT, salt, memoryDifficulty);
    }

    /**
     * @hide
     */
    private KeyDerivationParams(@KeyDerivationAlgorithm int algorithm, @NonNull byte[] salt) {
        this(algorithm, salt, /*memoryDifficulty=*/ -1);
    }

    /**
     * @hide
     */
    private KeyDerivationParams(@KeyDerivationAlgorithm int algorithm, @NonNull byte[] salt,
            int memoryDifficulty) {
        mAlgorithm = algorithm;
        mSalt = Objects.requireNonNull(salt);
        mMemoryDifficulty = memoryDifficulty;
    }

    /**
     * Gets algorithm.
     */
    public @KeyDerivationAlgorithm int getAlgorithm() {
        return mAlgorithm;
    }

    /**
     * Gets salt.
     */
    public @NonNull byte[] getSalt() {
        return mSalt;
    }

    /**
     * Gets the memory difficulty parameter for the hashing algorithm.
     *
     * <p>The effect of this parameter depends on the algorithm in use. For example, please see
     * {@link #createScryptParams(byte[], int)} for choosing the parameter for SCRYPT.
     *
     * <p>If the specific algorithm does not support such a memory difficulty parameter, its value
     * should be -1.
     */
    public int getMemoryDifficulty() {
        return mMemoryDifficulty;
    }

    public static final @NonNull Parcelable.Creator<KeyDerivationParams> CREATOR =
            new Parcelable.Creator<KeyDerivationParams>() {
        public KeyDerivationParams createFromParcel(Parcel in) {
                return new KeyDerivationParams(in);
        }

        public KeyDerivationParams[] newArray(int length) {
            return new KeyDerivationParams[length];
        }
    };

    @Override
    public void writeToParcel(Parcel out, int flags) {
        out.writeInt(mAlgorithm);
        out.writeByteArray(mSalt);
        out.writeInt(mMemoryDifficulty);
    }

    /**
     * @hide
     */
    protected KeyDerivationParams(Parcel in) {
        mAlgorithm = in.readInt();
        mSalt = in.createByteArray();
        mMemoryDifficulty = in.readInt();
    }

    @Override
    public int describeContents() {
        return 0;
    }
}
