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

#define LOG_TAG "EicOpsImpl"

#include <optional>
#include <tuple>
#include <vector>

#include <android-base/logging.h>
#include <android-base/stringprintf.h>
#include <string.h>

#include <android/hardware/identity/support/IdentityCredentialSupport.h>

#include <openssl/sha.h>

#include <openssl/aes.h>
#include <openssl/bn.h>
#include <openssl/crypto.h>
#include <openssl/ec.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/hkdf.h>
#include <openssl/hmac.h>
#include <openssl/objects.h>
#include <openssl/pem.h>
#include <openssl/pkcs12.h>
#include <openssl/rand.h>
#include <openssl/x509.h>
#include <openssl/x509_vfy.h>

#include "EicOps.h"

using ::std::map;
using ::std::optional;
using ::std::string;
using ::std::tuple;
using ::std::vector;

void* eicMemSet(void* s, int c, size_t n) { return memset(s, c, n); }

void* eicMemCpy(void* dest, const void* src, size_t n) {
  return memcpy(dest, src, n);
}

size_t eicStrLen(const char* s) { return strlen(s); }

int eicCryptoMemCmp(const void* s1, const void* s2, size_t n) {
  return CRYPTO_memcmp(s1, s2, n);
}

void eicOpsHmacSha256Init(EicHmacSha256Ctx* ctx, const uint8_t* key,
                          size_t keySize) {
  HMAC_CTX* realCtx = (HMAC_CTX*)ctx;
  HMAC_CTX_init(realCtx);
  if (HMAC_Init_ex(realCtx, key, keySize, EVP_sha256(), nullptr /* impl */) !=
      1) {
    LOG(ERROR) << "Error initializing HMAC_CTX";
  }
}

void eicOpsHmacSha256Update(EicHmacSha256Ctx* ctx, const uint8_t* data,
                            size_t len) {
  HMAC_CTX* realCtx = (HMAC_CTX*)ctx;
  if (HMAC_Update(realCtx, data, len) != 1) {
    LOG(ERROR) << "Error updating HMAC_CTX";
  }
}

void eicOpsHmacSha256Final(EicHmacSha256Ctx* ctx,
                           uint8_t digest[EIC_SHA256_DIGEST_SIZE]) {
  HMAC_CTX* realCtx = (HMAC_CTX*)ctx;
  unsigned int size = 0;
  if (HMAC_Final(realCtx, digest, &size) != 1) {
    LOG(ERROR) << "Error finalizing HMAC_CTX";
  }
  if (size != EIC_SHA256_DIGEST_SIZE) {
    LOG(ERROR) << "Expected 32 bytes from HMAC_Final, got " << size;
  }
}

void eicOpsSha256Init(EicSha256Ctx* ctx) {
  SHA256_CTX* realCtx = (SHA256_CTX*)ctx;
  SHA256_Init(realCtx);
}

void eicOpsSha256Update(EicSha256Ctx* ctx, const uint8_t* data, size_t len) {
  SHA256_CTX* realCtx = (SHA256_CTX*)ctx;
  SHA256_Update(realCtx, data, len);
}

void eicOpsSha256Final(EicSha256Ctx* ctx,
                       uint8_t digest[EIC_SHA256_DIGEST_SIZE]) {
  SHA256_CTX* realCtx = (SHA256_CTX*)ctx;
  SHA256_Final(digest, realCtx);
}

bool eicOpsRandom(uint8_t* buf, size_t numBytes) {
  optional<vector<uint8_t>> bytes =
      ::android::hardware::identity::support::getRandom(numBytes);
  if (!bytes.has_value()) {
    return false;
  }
  memcpy(buf, bytes.value().data(), numBytes);
  return true;
}

bool eicOpsEncryptAes128Gcm(
    const uint8_t* key,    // Must be 16 bytes
    const uint8_t* nonce,  // Must be 12 bytes
    const uint8_t* data,   // May be NULL if size is 0
    size_t dataSize,
    const uint8_t* additionalAuthenticationData,  // May be NULL if size is 0
    size_t additionalAuthenticationDataSize, uint8_t* encryptedData) {
  vector<uint8_t> cppKey;
  cppKey.resize(16);
  memcpy(cppKey.data(), key, 16);

  vector<uint8_t> cppData;
  cppData.resize(dataSize);
  if (dataSize > 0) {
    memcpy(cppData.data(), data, dataSize);
  }

  vector<uint8_t> cppAAD;
  cppAAD.resize(additionalAuthenticationDataSize);
  if (additionalAuthenticationDataSize > 0) {
    memcpy(cppAAD.data(), additionalAuthenticationData,
           additionalAuthenticationDataSize);
  }

  vector<uint8_t> cppNonce;
  cppNonce.resize(12);
  memcpy(cppNonce.data(), nonce, 12);

  optional<vector<uint8_t>> cppEncryptedData =
      android::hardware::identity::support::encryptAes128Gcm(cppKey, cppNonce,
                                                             cppData, cppAAD);
  if (!cppEncryptedData.has_value()) {
    return false;
  }

  memcpy(encryptedData, cppEncryptedData.value().data(),
         cppEncryptedData.value().size());
  return true;
}

// Decrypts |encryptedData| using |key| and |additionalAuthenticatedData|,
// returns resulting plaintext in |data| must be of size |encryptedDataSize|
// - 28.
//
// The format of |encryptedData| must be as specified in the
// encryptAes128Gcm() function.
bool eicOpsDecryptAes128Gcm(const uint8_t* key,  // Must be 16 bytes
                            const uint8_t* encryptedData,
                            size_t encryptedDataSize,
                            const uint8_t* additionalAuthenticationData,
                            size_t additionalAuthenticationDataSize,
                            uint8_t* data) {
  vector<uint8_t> keyVec;
  keyVec.resize(16);
  memcpy(keyVec.data(), key, 16);

  vector<uint8_t> encryptedDataVec;
  encryptedDataVec.resize(encryptedDataSize);
  if (encryptedDataSize > 0) {
    memcpy(encryptedDataVec.data(), encryptedData, encryptedDataSize);
  }

  vector<uint8_t> aadVec;
  aadVec.resize(additionalAuthenticationDataSize);
  if (additionalAuthenticationDataSize > 0) {
    memcpy(aadVec.data(), additionalAuthenticationData,
           additionalAuthenticationDataSize);
  }

  optional<vector<uint8_t>> decryptedDataVec =
      android::hardware::identity::support::decryptAes128Gcm(
          keyVec, encryptedDataVec, aadVec);
  if (!decryptedDataVec.has_value()) {
    eicDebug("Error decrypting data");
    return false;
  }
  if (decryptedDataVec.value().size() != encryptedDataSize - 28) {
    eicDebug("Decrypted data is size %zd, expected %zd",
             decryptedDataVec.value().size(), encryptedDataSize - 28);
    return false;
  }

  if (decryptedDataVec.value().size() > 0) {
    memcpy(data, decryptedDataVec.value().data(),
           decryptedDataVec.value().size());
  }
  return true;
}

bool eicOpsCreateEcKey(uint8_t privateKey[EIC_P256_PRIV_KEY_SIZE],
                       uint8_t publicKey[EIC_P256_PUB_KEY_SIZE]) {
  optional<vector<uint8_t>> keyPair =
      android::hardware::identity::support::createEcKeyPair();
  if (!keyPair) {
    eicDebug("Error creating EC keypair");
    return false;
  }
  optional<vector<uint8_t>> privKey =
      android::hardware::identity::support::ecKeyPairGetPrivateKey(
          keyPair.value());
  if (!privKey) {
    eicDebug("Error extracting private key");
    return false;
  }
  if (privKey.value().size() != EIC_P256_PRIV_KEY_SIZE) {
    eicDebug("Private key is %zd bytes, expected %zd", privKey.value().size(),
             (size_t)EIC_P256_PRIV_KEY_SIZE);
    return false;
  }

  optional<vector<uint8_t>> pubKey =
      android::hardware::identity::support::ecKeyPairGetPublicKey(
          keyPair.value());
  if (!pubKey) {
    eicDebug("Error extracting public key");
    return false;
  }
  // ecKeyPairGetPublicKey() returns 0x04 | x | y, we don't want the leading
  // 0x04.
  if (pubKey.value().size() != EIC_P256_PUB_KEY_SIZE + 1) {
    eicDebug("Public key is %zd bytes long, expected %zd",
             pubKey.value().size(), (size_t)EIC_P256_PRIV_KEY_SIZE + 1);
    return false;
  }

  memcpy(privateKey, privKey.value().data(), EIC_P256_PRIV_KEY_SIZE);
  memcpy(publicKey, pubKey.value().data() + 1, EIC_P256_PUB_KEY_SIZE);

  return true;
}

bool eicOpsCreateCredentialKey(uint8_t privateKey[EIC_P256_PRIV_KEY_SIZE],
                               const uint8_t* challenge, size_t challengeSize,
                               const uint8_t* applicationId,
                               size_t applicationIdSize, bool testCredential,
                               uint8_t* cert, size_t* certSize) {
  vector<uint8_t> challengeVec(challengeSize);
  memcpy(challengeVec.data(), challenge, challengeSize);

  vector<uint8_t> applicationIdVec(applicationIdSize);
  memcpy(applicationIdVec.data(), applicationId, applicationIdSize);

  optional<std::pair<vector<uint8_t>, vector<vector<uint8_t>>>> ret =
      android::hardware::identity::support::createEcKeyPairAndAttestation(
          challengeVec, applicationIdVec, testCredential);
  if (!ret) {
    eicDebug("Error generating CredentialKey and attestation");
    return false;
  }

  // Extract certificate chain.
  vector<uint8_t> flatChain =
      android::hardware::identity::support::certificateChainJoin(
          ret.value().second);
  if (*certSize < flatChain.size()) {
    eicDebug("Buffer for certificate is only %zd bytes long, need %zd bytes",
             *certSize, flatChain.size());
    return false;
  }
  memcpy(cert, flatChain.data(), flatChain.size());
  *certSize = flatChain.size();

  // Extract private key.
  optional<vector<uint8_t>> privKey =
      android::hardware::identity::support::ecKeyPairGetPrivateKey(
          ret.value().first);
  if (!privKey) {
    eicDebug("Error extracting private key");
    return false;
  }
  if (privKey.value().size() != EIC_P256_PRIV_KEY_SIZE) {
    eicDebug("Private key is %zd bytes, expected %zd", privKey.value().size(),
             (size_t)EIC_P256_PRIV_KEY_SIZE);
    return false;
  }

  memcpy(privateKey, privKey.value().data(), EIC_P256_PRIV_KEY_SIZE);

  return true;
}

bool eicOpsSignEcKey(const uint8_t publicKey[EIC_P256_PUB_KEY_SIZE],
                     const uint8_t signingKey[EIC_P256_PRIV_KEY_SIZE],
                     unsigned int serial, const char* issuerName,
                     const char* subjectName, time_t validityNotBefore,
                     time_t validityNotAfter, const uint8_t* proofOfBinding,
                     size_t proofOfBindingSize, uint8_t* cert,
                     size_t* certSize) {  // inout
  vector<uint8_t> signingKeyVec(EIC_P256_PRIV_KEY_SIZE);
  memcpy(signingKeyVec.data(), signingKey, EIC_P256_PRIV_KEY_SIZE);

  vector<uint8_t> pubKeyVec(EIC_P256_PUB_KEY_SIZE + 1);
  pubKeyVec[0] = 0x04;
  memcpy(pubKeyVec.data() + 1, publicKey, EIC_P256_PUB_KEY_SIZE);

  string serialDecimal = android::base::StringPrintf("%d", serial);

  map<string, vector<uint8_t>> extensions;
  if (proofOfBinding != nullptr) {
    vector<uint8_t> proofOfBindingVec(proofOfBinding,
                                      proofOfBinding + proofOfBindingSize);
    extensions["1.3.6.1.4.1.11129.2.1.26"] = proofOfBindingVec;
  }

  optional<vector<uint8_t>> certVec =
      android::hardware::identity::support::ecPublicKeyGenerateCertificate(
          pubKeyVec, signingKeyVec, serialDecimal, issuerName, subjectName,
          validityNotBefore, validityNotAfter, extensions);
  if (!certVec) {
    eicDebug("Error generating certificate");
    return false;
  }

  if (*certSize < certVec.value().size()) {
    eicDebug("Buffer for certificate is only %zd bytes long, need %zd bytes",
             *certSize, certVec.value().size());
    return false;
  }
  memcpy(cert, certVec.value().data(), certVec.value().size());
  *certSize = certVec.value().size();

  return true;
}

bool eicOpsEcDsa(const uint8_t privateKey[EIC_P256_PRIV_KEY_SIZE],
                 const uint8_t digestOfData[EIC_SHA256_DIGEST_SIZE],
                 uint8_t signature[EIC_ECDSA_P256_SIGNATURE_SIZE]) {
  vector<uint8_t> privKeyVec(EIC_P256_PRIV_KEY_SIZE);
  memcpy(privKeyVec.data(), privateKey, EIC_P256_PRIV_KEY_SIZE);

  vector<uint8_t> digestVec(EIC_SHA256_DIGEST_SIZE);
  memcpy(digestVec.data(), digestOfData, EIC_SHA256_DIGEST_SIZE);

  optional<vector<uint8_t>> derSignature =
      android::hardware::identity::support::signEcDsaDigest(privKeyVec,
                                                            digestVec);
  if (!derSignature) {
    eicDebug("Error signing data");
    return false;
  }

  ECDSA_SIG* sig;
  const unsigned char* p = derSignature.value().data();
  sig = d2i_ECDSA_SIG(nullptr, &p, derSignature.value().size());
  if (sig == nullptr) {
    eicDebug("Error decoding DER signature");
    return false;
  }

  if (BN_bn2binpad(sig->r, signature, 32) != 32) {
    eicDebug("Error encoding r");
    return false;
  }
  if (BN_bn2binpad(sig->s, signature + 32, 32) != 32) {
    eicDebug("Error encoding s");
    return false;
  }

  return true;
}

static const uint8_t hbkTest[16] = {0};
static const uint8_t hbkReal[16] = {0, 1, 2,  3,  4,  5,  6,  7,
                                    8, 9, 10, 11, 12, 13, 14, 15};

const uint8_t* eicOpsGetHardwareBoundKey(bool testCredential) {
  if (testCredential) {
    return hbkTest;
  }
  return hbkReal;
}

bool eicOpsValidateAuthToken(uint64_t /* challenge */,
                             uint64_t /* secureUserId */,
                             uint64_t /* authenticatorId */,
                             int /* hardwareAuthenticatorType */,
                             uint64_t /* timeStamp */, const uint8_t* /* mac */,
                             size_t /* macSize */,
                             uint64_t /* verificationTokenChallenge */,
                             uint64_t /* verificationTokenTimeStamp */,
                             int /* verificationTokenSecurityLevel */,
                             const uint8_t* /* verificationTokenMac */,
                             size_t /* verificationTokenMacSize */) {
  // Here's where we would validate the passed-in |authToken| to assure
  // ourselves that it comes from the e.g. biometric hardware and wasn't made up
  // by an attacker.
  //
  // However this involves calculating the MAC which requires access to the to
  // a pre-shared key which we don't have...
  //
  return true;
}

bool eicOpsX509GetPublicKey(const uint8_t* x509Cert, size_t x509CertSize,
                            uint8_t* publicKey, size_t* publicKeySize) {
  vector<uint8_t> chain;
  chain.resize(x509CertSize);
  memcpy(chain.data(), x509Cert, x509CertSize);
  optional<vector<uint8_t>> res =
      android::hardware::identity::support::certificateChainGetTopMostKey(
          chain);
  if (!res) {
    return false;
  }
  if (res.value().size() > *publicKeySize) {
    eicDebug("Public key size is %zd but buffer only has room for %zd bytes",
             res.value().size(), *publicKeySize);
    return false;
  }
  *publicKeySize = res.value().size();
  memcpy(publicKey, res.value().data(), *publicKeySize);
  eicDebug("Extracted %zd bytes public key from %zd bytes X.509 cert",
           *publicKeySize, x509CertSize);
  return true;
}

bool eicOpsX509CertSignedByPublicKey(const uint8_t* x509Cert,
                                     size_t x509CertSize,
                                     const uint8_t* publicKey,
                                     size_t publicKeySize) {
  vector<uint8_t> certVec(x509Cert, x509Cert + x509CertSize);
  vector<uint8_t> publicKeyVec(publicKey, publicKey + publicKeySize);
  return android::hardware::identity::support::certificateSignedByPublicKey(
      certVec, publicKeyVec);
}

bool eicOpsEcDsaVerifyWithPublicKey(const uint8_t* digest, size_t digestSize,
                                    const uint8_t* signature,
                                    size_t signatureSize,
                                    const uint8_t* publicKey,
                                    size_t publicKeySize) {
  vector<uint8_t> digestVec(digest, digest + digestSize);
  vector<uint8_t> signatureVec(signature, signature + signatureSize);
  vector<uint8_t> publicKeyVec(publicKey, publicKey + publicKeySize);

  vector<uint8_t> derSignature;
  if (!android::hardware::identity::support::ecdsaSignatureCoseToDer(
          signatureVec, derSignature)) {
    LOG(ERROR) << "Error convering signature to DER format";
    return false;
  }

  if (!android::hardware::identity::support::checkEcDsaSignature(
          digestVec, derSignature, publicKeyVec)) {
    LOG(ERROR) << "Signature check failed";
    return false;
  }
  return true;
}

bool eicOpsEcdh(const uint8_t publicKey[EIC_P256_PUB_KEY_SIZE],
                const uint8_t privateKey[EIC_P256_PUB_KEY_SIZE],
                uint8_t sharedSecret[EIC_P256_COORDINATE_SIZE]) {
  vector<uint8_t> pubKeyVec(EIC_P256_PUB_KEY_SIZE + 1);
  pubKeyVec[0] = 0x04;
  memcpy(pubKeyVec.data() + 1, publicKey, EIC_P256_PUB_KEY_SIZE);

  vector<uint8_t> privKeyVec(EIC_P256_PRIV_KEY_SIZE);
  memcpy(privKeyVec.data(), privateKey, EIC_P256_PRIV_KEY_SIZE);

  optional<vector<uint8_t>> shared =
      android::hardware::identity::support::ecdh(pubKeyVec, privKeyVec);
  if (!shared) {
    LOG(ERROR) << "Error performing ECDH";
    return false;
  }
  if (shared.value().size() != EIC_P256_COORDINATE_SIZE) {
    LOG(ERROR) << "Unexpected size of shared secret " << shared.value().size()
               << " expected " << EIC_P256_COORDINATE_SIZE << " bytes";
    return false;
  }
  memcpy(sharedSecret, shared.value().data(), EIC_P256_COORDINATE_SIZE);
  return true;
}

bool eicOpsHkdf(const uint8_t* sharedSecret, size_t sharedSecretSize,
                const uint8_t* salt, size_t saltSize, const uint8_t* info,
                size_t infoSize, uint8_t* output, size_t outputSize) {
  vector<uint8_t> sharedSecretVec(sharedSecretSize);
  memcpy(sharedSecretVec.data(), sharedSecret, sharedSecretSize);
  vector<uint8_t> saltVec(saltSize);
  memcpy(saltVec.data(), salt, saltSize);
  vector<uint8_t> infoVec(infoSize);
  memcpy(infoVec.data(), info, infoSize);

  optional<vector<uint8_t>> result = android::hardware::identity::support::hkdf(
      sharedSecretVec, saltVec, infoVec, outputSize);
  if (!result) {
    LOG(ERROR) << "Error performing HKDF";
    return false;
  }
  if (result.value().size() != outputSize) {
    LOG(ERROR) << "Unexpected size of HKDF " << result.value().size()
               << " expected " << outputSize;
    return false;
  }
  memcpy(output, result.value().data(), outputSize);
  return true;
}

#ifdef EIC_DEBUG

void eicPrint(const char* format, ...) {
  va_list args;
  va_start(args, format);
  vfprintf(stderr, format, args);
  va_end(args);
}

void eicHexdump(const char* message, const uint8_t* data, size_t dataSize) {
  vector<uint8_t> dataVec(dataSize);
  memcpy(dataVec.data(), data, dataSize);
  android::hardware::identity::support::hexdump(message, dataVec);
}

void eicCborPrettyPrint(const uint8_t* cborData, size_t cborDataSize,
                        size_t maxBStrSize) {
  vector<uint8_t> cborDataVec(cborDataSize);
  memcpy(cborDataVec.data(), cborData, cborDataSize);
  string str = android::hardware::identity::support::cborPrettyPrint(
      cborDataVec, maxBStrSize, {});
  fprintf(stderr, "%s\n", str.c_str());
}

#endif  // EIC_DEBUG
