/*
 * Copyright (C) 2016 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.
 */

#ifndef ANDROID_VOLD_KEYMASTER_H
#define ANDROID_VOLD_KEYMASTER_H

#ifdef __cplusplus

#include <memory>
#include <string>
#include <utility>

#include <android/hardware/keymaster/3.0/IKeymasterDevice.h>
#include <keystore/authorization_set.h>
#include "Utils.h"

namespace android {
namespace vold {
using ::android::hardware::keymaster::V3_0::IKeymasterDevice;
using ::keystore::ErrorCode;
using ::keystore::KeyPurpose;
using ::keystore::AuthorizationSet;

// C++ wrappers to the Keymaster hidl interface.
// This is tailored to the needs of KeyStorage, but could be extended to be
// a more general interface.

// Wrapper for a Keymaster operation handle representing an
// ongoing Keymaster operation.  Aborts the operation
// in the destructor if it is unfinished. Methods log failures
// to LOG(ERROR).
class KeymasterOperation {
  public:
    ~KeymasterOperation();
    // Is this instance valid? This is false if creation fails, and becomes
    // false on finish or if an update fails.
    explicit operator bool() { return mError == ErrorCode::OK; }
    ErrorCode errorCode() { return mError; }
    // Call "update" repeatedly until all of the input is consumed, and
    // concatenate the output. Return true on success.
    bool updateCompletely(const std::string& input, std::string* output);
    // Finish and write the output to this string, unless pointer is null.
    bool finish(std::string* output);
    // Move constructor
    KeymasterOperation(KeymasterOperation&& rhs) {
        mDevice = std::move(rhs.mDevice);
        mOpHandle = std::move(rhs.mOpHandle);
        mError = std::move(rhs.mError);
    }
    // Construct an object in an error state for error returns
    KeymasterOperation()
        : mDevice{nullptr}, mOpHandle{0},
          mError {ErrorCode::UNKNOWN_ERROR} {}
    // Move Assignment
    KeymasterOperation& operator= (KeymasterOperation&& rhs) {
        mDevice = std::move(rhs.mDevice);
        mOpHandle = std::move(rhs.mOpHandle);
        mError = std::move(rhs.mError);
        rhs.mError = ErrorCode::UNKNOWN_ERROR;
        rhs.mOpHandle = 0;
        return *this;
    }

  private:
    KeymasterOperation(const sp<IKeymasterDevice>& d, uint64_t h)
        : mDevice{d}, mOpHandle{h}, mError {ErrorCode::OK} {}
    KeymasterOperation(ErrorCode error)
        : mDevice{nullptr}, mOpHandle{0},
          mError {error} {}
    sp<IKeymasterDevice> mDevice;
    uint64_t mOpHandle;
    ErrorCode mError;
    DISALLOW_COPY_AND_ASSIGN(KeymasterOperation);
    friend class Keymaster;
};

// Wrapper for a Keymaster device for methods that start a KeymasterOperation or are not
// part of one.
class Keymaster {
  public:
    Keymaster();
    // false if we failed to open the keymaster device.
    explicit operator bool() { return mDevice.get() != nullptr; }
    // Generate a key in the keymaster from the given params.
    //bool generateKey(const AuthorizationSet& inParams, std::string* key);
    // If the keymaster supports it, permanently delete a key.
    bool deleteKey(const std::string& key);
    // Replace stored key blob in response to KM_ERROR_KEY_REQUIRES_UPGRADE.
    bool upgradeKey(const std::string& oldKey, const AuthorizationSet& inParams,
                    std::string* newKey);
    // Begin a new cryptographic operation, collecting output parameters if pointer is non-null
    KeymasterOperation begin(KeyPurpose purpose, const std::string& key,
                             const AuthorizationSet& inParams, AuthorizationSet* outParams);
    bool isSecure();

  private:
    sp<hardware::keymaster::V3_0::IKeymasterDevice> mDevice;
    DISALLOW_COPY_AND_ASSIGN(Keymaster);
};

}  // namespace vold
}  // namespace android

#endif // __cplusplus


/*
 * The following functions provide C bindings to keymaster services
 * needed by cryptfs scrypt. The compatibility check checks whether
 * the keymaster implementation is considered secure, i.e., TEE backed.
 * The create_key function generates an RSA key for signing.
 * The sign_object function signes an object with the given keymaster
 * key.
 */
__BEGIN_DECLS

int keymaster_compatibility_cryptfs_scrypt();
/*int keymaster_create_key_for_cryptfs_scrypt(uint32_t rsa_key_size,
                                            uint64_t rsa_exponent,
                                            uint32_t ratelimit,
                                            uint8_t* key_buffer,
                                            uint32_t key_buffer_size,
                                            uint32_t* key_out_size);

int keymaster_sign_object_for_cryptfs_scrypt(const uint8_t* key_blob,
                                             size_t key_blob_size,
                                             uint32_t ratelimit,
                                             const uint8_t* object,
                                             const size_t object_size,
                                             uint8_t** signature_buffer,
                                             size_t* signature_buffer_size);*/

__END_DECLS

#endif
