/*
 * 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.
 */

#include "Keystore.h"

#include <android-base/logging.h>

#include <aidl/android/hardware/security/keymint/SecurityLevel.h>
#include <aidl/android/security/maintenance/IKeystoreMaintenance.h>
#include <aidl/android/system/keystore2/Domain.h>
#include <aidl/android/system/keystore2/EphemeralStorageKeyResponse.h>
#include <aidl/android/system/keystore2/KeyDescriptor.h>

// Keep these in sync with system/security/keystore2/src/keystore2_main.rs
static constexpr const char keystore2_service_name[] =
        "android.system.keystore2.IKeystoreService/default";
static constexpr const char maintenance_service_name[] = "android.security.maintenance";

/*
 * Keep this in sync with the description for update() in
 * system/hardware/interfaces/keystore2/aidl/android/system/keystore2/IKeystoreOperation.aidl
 */
static constexpr const size_t UPDATE_INPUT_MAX_SIZE = 32 * 1024;  // 32 KiB

// Keep this in sync with system/sepolicy/private/keystore2_key_contexts
static constexpr const int VOLD_NAMESPACE = 100;

namespace android {
namespace vold {

namespace ks2_maint = ::aidl::android::security::maintenance;

KeystoreOperation::~KeystoreOperation() {
    if (ks2Operation) ks2Operation->abort();
}

static void zeroize_vector(std::vector<uint8_t>& vec) {
    memset_explicit(vec.data(), 0, vec.size());
}

static bool logKeystore2ExceptionIfPresent(::ndk::ScopedAStatus& rc, const std::string& func_name) {
    if (rc.isOk()) return false;

    auto exception_code = rc.getExceptionCode();
    if (exception_code == EX_SERVICE_SPECIFIC) {
        LOG(ERROR) << "keystore2 Keystore " << func_name
                   << " returned service specific error: " << rc.getServiceSpecificError();
    } else {
        LOG(ERROR) << "keystore2 Communication with Keystore " << func_name
                   << " failed error: " << exception_code;
    }
    return true;
}

bool KeystoreOperation::updateCompletely(const char* input, size_t inputLen,
                                         const std::function<void(const char*, size_t)> consumer) {
    if (!ks2Operation) return false;

    while (inputLen != 0) {
        size_t currLen = std::min(inputLen, UPDATE_INPUT_MAX_SIZE);
        std::vector<uint8_t> input_vec(input, input + currLen);
        inputLen -= currLen;
        input += currLen;

        std::optional<std::vector<uint8_t>> output;
        auto rc = ks2Operation->update(input_vec, &output);
        zeroize_vector(input_vec);
        if (logKeystore2ExceptionIfPresent(rc, "update")) {
            ks2Operation = nullptr;
            return false;
        }
        if (output) consumer((const char*)output->data(), output->size());
    }
    return true;
}

bool KeystoreOperation::finish(std::string* output) {
    std::optional<std::vector<uint8_t>> out_vec;

    if (!ks2Operation) return false;

    auto rc = ks2Operation->finish(std::nullopt, std::nullopt, &out_vec);
    if (logKeystore2ExceptionIfPresent(rc, "finish")) {
        ks2Operation = nullptr;
        return false;
    }

    if (output) *output = std::string(out_vec->begin(), out_vec->end());

    return true;
}

Keystore::Keystore() {
    ::ndk::SpAIBinder binder(AServiceManager_waitForService(keystore2_service_name));
    auto keystore2Service = ks2::IKeystoreService::fromBinder(binder);

    if (!keystore2Service) {
        LOG(ERROR) << "Vold unable to connect to keystore2.";
        return;
    }

    /*
     * There are only two options available to vold for the SecurityLevel: TRUSTED_ENVIRONMENT (TEE)
     * and STRONGBOX. We don't use STRONGBOX because if a TEE is present it will have Weaver, which
     * already strengthens CE, so there's no additional benefit from using StrongBox.
     *
     * The picture is slightly more complicated because Keystore2 reports a SOFTWARE instance as
     * a TEE instance when there isn't a TEE instance available, but in that case, a STRONGBOX
     * instance won't be available either, so we'll still be doing the best we can.
     */
    auto rc = keystore2Service->getSecurityLevel(km::SecurityLevel::TRUSTED_ENVIRONMENT,
                                                 &securityLevel);
    if (logKeystore2ExceptionIfPresent(rc, "getSecurityLevel"))
        LOG(ERROR) << "Vold unable to get security level from keystore2.";
}

bool Keystore::generateKey(const km::AuthorizationSet& inParams, std::string* key) {
    ks2::KeyDescriptor in_key = {
            .domain = ks2::Domain::BLOB,
            .alias = std::nullopt,
            .nspace = VOLD_NAMESPACE,
            .blob = std::nullopt,
    };
    ks2::KeyMetadata keyMetadata;
    auto rc = securityLevel->generateKey(in_key, std::nullopt, inParams.vector_data(), 0, {},
                                         &keyMetadata);

    if (logKeystore2ExceptionIfPresent(rc, "generateKey")) return false;

    if (keyMetadata.key.blob == std::nullopt) {
        LOG(ERROR) << "keystore2 generated key blob was null";
        return false;
    }
    if (key) *key = std::string(keyMetadata.key.blob->begin(), keyMetadata.key.blob->end());

    zeroize_vector(keyMetadata.key.blob.value());
    return true;
}

bool Keystore::exportKey(const KeyBuffer& ksKey, std::string* key) {
    bool ret = false;
    ks2::KeyDescriptor storageKey = {
            .domain = ks2::Domain::BLOB,
            .alias = std::nullopt,
            .nspace = VOLD_NAMESPACE,
    };
    storageKey.blob = std::make_optional<std::vector<uint8_t>>(ksKey.begin(), ksKey.end());
    ks2::EphemeralStorageKeyResponse ephemeral_key_response;
    auto rc = securityLevel->convertStorageKeyToEphemeral(storageKey, &ephemeral_key_response);

    if (logKeystore2ExceptionIfPresent(rc, "exportKey")) goto out;
    if (key)
        *key = std::string(ephemeral_key_response.ephemeralKey.begin(),
                           ephemeral_key_response.ephemeralKey.end());

    // vold intentionally ignores ephemeral_key_response.upgradedBlob, since the
    // concept of "upgrading" doesn't make sense for TAG_STORAGE_KEY keys
    // (hardware-wrapped inline encryption keys).  These keys are only meant as
    // a substitute for raw keys; they still go through vold's usual layer of
    // key wrapping, which already handles version binding.  So, vold just keeps
    // using the original blobs for TAG_STORAGE_KEY keys.  If KeyMint "upgrades"
    // them anyway, then they'll just get re-upgraded before each use.

    ret = true;
out:
    zeroize_vector(ephemeral_key_response.ephemeralKey);
    zeroize_vector(storageKey.blob.value());
    return ret;
}

bool Keystore::deleteKey(const std::string& key) {
    ks2::KeyDescriptor keyDesc = {
            .domain = ks2::Domain::BLOB,
            .alias = std::nullopt,
            .nspace = VOLD_NAMESPACE,
    };
    keyDesc.blob =
            std::optional<std::vector<uint8_t>>(std::vector<uint8_t>(key.begin(), key.end()));

    auto rc = securityLevel->deleteKey(keyDesc);
    return !logKeystore2ExceptionIfPresent(rc, "deleteKey");
}

KeystoreOperation Keystore::begin(const std::string& key, const km::AuthorizationSet& inParams,
                                  km::AuthorizationSet* outParams) {
    ks2::KeyDescriptor keyDesc = {
            .domain = ks2::Domain::BLOB,
            .alias = std::nullopt,
            .nspace = VOLD_NAMESPACE,
    };
    keyDesc.blob =
            std::optional<std::vector<uint8_t>>(std::vector<uint8_t>(key.begin(), key.end()));

    ks2::CreateOperationResponse cor;
    auto rc = securityLevel->createOperation(keyDesc, inParams.vector_data(), true, &cor);
    if (logKeystore2ExceptionIfPresent(rc, "createOperation")) {
        if (rc.getExceptionCode() == EX_SERVICE_SPECIFIC)
            return KeystoreOperation((km::ErrorCode)rc.getServiceSpecificError());
        else
            return KeystoreOperation();
    }

    if (!cor.iOperation) {
        LOG(ERROR) << "keystore2 createOperation didn't return an operation";
        return KeystoreOperation();
    }

    if (outParams && cor.parameters) *outParams = cor.parameters->keyParameter;

    return KeystoreOperation(cor.iOperation, cor.upgradedBlob);
}

void Keystore::earlyBootEnded() {
    ::ndk::SpAIBinder binder(AServiceManager_getService(maintenance_service_name));
    auto maint_service = ks2_maint::IKeystoreMaintenance::fromBinder(binder);

    if (!maint_service) {
        LOG(ERROR) << "Unable to connect to keystore2 maintenance service for earlyBootEnded";
        return;
    }

    auto rc = maint_service->earlyBootEnded();
    logKeystore2ExceptionIfPresent(rc, "earlyBootEnded");
}

void Keystore::deleteAllKeys() {
    ::ndk::SpAIBinder binder(AServiceManager_getService(maintenance_service_name));
    auto maint_service = ks2_maint::IKeystoreMaintenance::fromBinder(binder);

    if (!maint_service) {
        LOG(ERROR) << "Unable to connect to keystore2 maintenance service for deleteAllKeys";
        return;
    }

    auto rc = maint_service->deleteAllKeys();
    logKeystore2ExceptionIfPresent(rc, "deleteAllKeys");
}

}  // namespace vold
}  // namespace android
