//
// Copyright (C) 2020 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 "keymaster_responder.h"

#include <android-base/logging.h>
#include <keymaster/android_keymaster_messages.h>

KeymasterResponder::KeymasterResponder(
    cuttlefish::KeymasterChannel& channel, keymaster::AndroidKeymaster& keymaster)
    : channel_(channel), keymaster_(keymaster) {
}

bool KeymasterResponder::ProcessMessage() {
  auto request = channel_.ReceiveMessage();
  if (!request) {
    LOG(ERROR) << "Could not receive message";
    return false;
  }
  const uint8_t* buffer = request->payload;
  const uint8_t* end = request->payload + request->payload_size;
  switch(request->cmd) {
    using namespace keymaster;
#define HANDLE_MESSAGE(ENUM_NAME, METHOD_NAME) \
    case ENUM_NAME: {\
      METHOD_NAME##Request request(keymaster_.message_version()); \
      if (!request.Deserialize(&buffer, end)) { \
        LOG(ERROR) << "Failed to deserialize " #METHOD_NAME "Request"; \
        return false; \
      } \
      METHOD_NAME##Response response(keymaster_.message_version()); \
      keymaster_.METHOD_NAME(request, &response); \
      return channel_.SendResponse(ENUM_NAME, response); \
    }
    HANDLE_MESSAGE(GENERATE_KEY, GenerateKey)
    HANDLE_MESSAGE(BEGIN_OPERATION, BeginOperation)
    HANDLE_MESSAGE(UPDATE_OPERATION, UpdateOperation)
    HANDLE_MESSAGE(FINISH_OPERATION, FinishOperation)
    HANDLE_MESSAGE(ABORT_OPERATION, AbortOperation)
    HANDLE_MESSAGE(IMPORT_KEY, ImportKey)
    HANDLE_MESSAGE(EXPORT_KEY, ExportKey)
    HANDLE_MESSAGE(GET_VERSION, GetVersion)
    HANDLE_MESSAGE(GET_SUPPORTED_ALGORITHMS, SupportedAlgorithms)
    HANDLE_MESSAGE(GET_SUPPORTED_BLOCK_MODES, SupportedBlockModes)
    HANDLE_MESSAGE(GET_SUPPORTED_PADDING_MODES, SupportedPaddingModes)
    HANDLE_MESSAGE(GET_SUPPORTED_DIGESTS, SupportedDigests)
    HANDLE_MESSAGE(GET_SUPPORTED_IMPORT_FORMATS, SupportedImportFormats)
    HANDLE_MESSAGE(GET_SUPPORTED_EXPORT_FORMATS, SupportedExportFormats)
    HANDLE_MESSAGE(GET_KEY_CHARACTERISTICS, GetKeyCharacteristics)
    HANDLE_MESSAGE(ATTEST_KEY, AttestKey)
    HANDLE_MESSAGE(UPGRADE_KEY, UpgradeKey)
    HANDLE_MESSAGE(CONFIGURE, Configure)
    HANDLE_MESSAGE(DELETE_KEY, DeleteKey)
    HANDLE_MESSAGE(DELETE_ALL_KEYS, DeleteAllKeys)
    HANDLE_MESSAGE(IMPORT_WRAPPED_KEY, ImportWrappedKey)
    HANDLE_MESSAGE(GENERATE_TIMESTAMP_TOKEN, GenerateTimestampToken)
#undef HANDLE_MESSAGE
#define HANDLE_MESSAGE_W_RETURN(ENUM_NAME, METHOD_NAME) \
    case ENUM_NAME: {\
    METHOD_NAME##Request request(keymaster_.message_version());     \
      if (!request.Deserialize(&buffer, end)) { \
        LOG(ERROR) << "Failed to deserialize " #METHOD_NAME "Request"; \
        return false; \
      } \
      auto response = keymaster_.METHOD_NAME(request); \
      return channel_.SendResponse(ENUM_NAME, response); \
    }
    HANDLE_MESSAGE_W_RETURN(COMPUTE_SHARED_HMAC, ComputeSharedHmac)
    HANDLE_MESSAGE_W_RETURN(VERIFY_AUTHORIZATION, VerifyAuthorization)
    HANDLE_MESSAGE_W_RETURN(DEVICE_LOCKED, DeviceLocked)
    HANDLE_MESSAGE_W_RETURN(GET_VERSION_2, GetVersion2)
#undef HANDLE_MESSAGE
#define HANDLE_MESSAGE_W_RETURN_NO_ARG(ENUM_NAME, METHOD_NAME) \
    case ENUM_NAME: {\
      auto response = keymaster_.METHOD_NAME(); \
      return channel_.SendResponse(ENUM_NAME, response); \
    }
    HANDLE_MESSAGE_W_RETURN_NO_ARG(GET_HMAC_SHARING_PARAMETERS, GetHmacSharingParameters)
    HANDLE_MESSAGE_W_RETURN_NO_ARG(EARLY_BOOT_ENDED, EarlyBootEnded)
#undef HANDLE_MESSAGE
    case ADD_RNG_ENTROPY: {
      AddEntropyRequest request(keymaster_.message_version());
      if (!request.Deserialize(&buffer, end)) {
        LOG(ERROR) << "Failed to deserialize AddEntropyRequest";
        return false;
      }
      AddEntropyResponse response(keymaster_.message_version());;
      keymaster_.AddRngEntropy(request, &response);
      return channel_.SendResponse(ADD_RNG_ENTROPY, response);
    }
    case DESTROY_ATTESTATION_IDS:
      // Cuttlefish doesn't support ID attestation.
    default:
      LOG(ERROR) << "Unknown request type: " << request->cmd;
      return false;
  }
}
