// Copyright 2022 Google LLC
//
// 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
//
//     https://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.

// This is an implementation of the crypto operations that uses boringssl. The
// algorithms used are SHA512, HKDF-SHA512, and ECDSA P384-SHA384.

#include "dice/boringssl_ecdsa_utils.h"

#include <stdint.h>
#include <stdio.h>
#include <string.h>

#include "openssl/bn.h"
#include "openssl/crypto.h"
#include "openssl/ec.h"
#include "openssl/ec_key.h"
#include "openssl/ecdsa.h"
#include "openssl/evp.h"
#include "openssl/hkdf.h"
#include "openssl/hmac.h"
#include "openssl/is_boringssl.h"
#include "openssl/sha.h"

static int hmac(uint8_t k[64], uint8_t in[64], uint8_t *out,
                unsigned int out_len) {
  int ret = 0;

  if (out_len != 64) {
    goto out;
  }
  HMAC_CTX ctx;
  HMAC_CTX_init(&ctx);
  if (1 != HMAC_Init_ex(&ctx, k, 64, EVP_sha512(), NULL /* impl */)) {
    goto out;
  }
  if (1 != HMAC_Update(&ctx, in, 64)) {
    goto out;
  }
  ret = HMAC_Final(&ctx, out, &out_len);
  HMAC_CTX_cleanup(&ctx);

out:
  return ret;
}

static int hmac3(uint8_t k[64], uint8_t in1[64], uint8_t in2,
                  const uint8_t *in3, unsigned int in3_len, uint8_t out[64]) {
  int ret = 0;

  HMAC_CTX ctx;
  HMAC_CTX_init(&ctx);
  if (1 != HMAC_Init_ex(&ctx, k, 64, EVP_sha512(), NULL /* impl */)) {
    goto out;
  }
  if (1 != HMAC_Update(&ctx, in1, 64)) {
    goto out;
  }
  if (1 != HMAC_Update(&ctx, &in2, 1)) {
    goto out;
  }
  if (in3 != NULL && in3_len > 0) {
    if (1 != HMAC_Update(&ctx, in3, in3_len)) {
      goto out;
    }
  }
  unsigned int out_len = 64;
  ret = HMAC_Final(&ctx, out, &out_len);
  HMAC_CTX_cleanup(&ctx);

out:
  return ret;
}

// Algorithm from section 3.2 of IETF RFC6979; limited to generating up to 64
// byte private keys.
static BIGNUM *derivePrivateKey(const EC_GROUP *group, const uint8_t *seed,
                                size_t seed_size, size_t private_key_len) {
  BIGNUM *candidate = NULL;
  uint8_t v[64];
  uint8_t k[64];
  uint8_t temp[64];
  memset(v, 1, 64);
  memset(k, 0, 64);
  memset(temp, 0, 64);

  if (private_key_len > 64) {
    goto err;
  }

  if (1 != hmac3(k, v, 0x00, seed, (unsigned int)seed_size, k)) {
    goto err;
  }
  if (1 != hmac(k, v, v, sizeof(v))) {
    goto err;
  }
  if (1 != hmac3(k, v, 0x01, seed, (unsigned int)seed_size, k)) {
    goto err;
  }
  do {
    if (1 != hmac(k, v, v, sizeof(v))) {
      goto err;
    }
    if (1 != hmac(k, v, temp, sizeof(temp))) {
      goto err;
    }
    if (1 != hmac3(k, v, 0x00, NULL, 0, k)) {
      goto err;
    }
    candidate = BN_bin2bn(temp, private_key_len, NULL);
    if (!candidate) {
      goto err;
    }
  } while (BN_cmp(candidate, EC_GROUP_get0_order(group)) >= 0 ||
           BN_is_zero(candidate));
  goto out;

err:
  BN_clear_free(candidate);
  candidate = NULL;
out:
  return candidate;
}

int P384KeypairFromSeed(uint8_t public_key[P384_PUBLIC_KEY_SIZE],
                        uint8_t private_key[P384_PRIVATE_KEY_SIZE],
                        const uint8_t seed[DICE_PRIVATE_KEY_SEED_SIZE]) {
  int ret = 0;
  EC_POINT *publicKey = NULL;
  BIGNUM *pD = NULL;
  BIGNUM *x = NULL;
  BIGNUM *y = NULL;

  EC_KEY *key = EC_KEY_new_by_curve_name(NID_secp384r1);
  if (!key) {
    goto out;
  }
  const EC_GROUP *group = EC_KEY_get0_group(key);
  if (!group) {
    goto out;
  }
  publicKey = EC_POINT_new(group);
  if (!publicKey) {
    goto out;
  }

  pD = derivePrivateKey(group, seed, DICE_PRIVATE_KEY_SEED_SIZE, P384_PRIVATE_KEY_SIZE);
  if (!pD) {
    goto out;
  }
  if (1 != BN_bn2bin_padded(private_key, P384_PRIVATE_KEY_SIZE, pD)) {
    goto out;
  }
  if (1 != EC_KEY_set_private_key(key, pD)) {
    goto out;
  }
  if (1 != EC_POINT_mul(group, publicKey, pD, NULL, NULL, NULL)) {
    goto out;
  }
  x = BN_new();
  if (!x) {
    goto out;
  }
  y = BN_new();
  if (!y) {
    goto out;
  }
  if (1 != EC_POINT_get_affine_coordinates_GFp(group, publicKey, x, y, NULL)) {
    goto out;
  }
  if (BN_num_bytes(x) > P384_PRIVATE_KEY_SIZE) {
    goto out;
  }
  BN_bn2bin(x, &public_key[0]);
  if (BN_num_bytes(y) > P384_PRIVATE_KEY_SIZE) {
    goto out;
  }
  BN_bn2bin(y, &public_key[P384_PRIVATE_KEY_SIZE]);
  ret = 1;

out:
  EC_POINT_free(publicKey);
  BN_clear_free(x);
  BN_clear_free(y);
  EC_KEY_free(key);
  BN_clear_free(pD);

  return ret;
}

int P384Sign(uint8_t signature[P384_SIGNATURE_SIZE], const uint8_t *message,
             size_t message_size,
             const uint8_t private_key[P384_PRIVATE_KEY_SIZE]) {
  int ret = 0;
  BIGNUM *pD = NULL;
  EC_KEY *key = NULL;
  uint8_t output[48];
  ECDSA_SIG *sig = NULL;

  pD = BN_bin2bn(private_key, P384_PRIVATE_KEY_SIZE, NULL);
  if (!pD) {
    goto out;
  }
  key = EC_KEY_new_by_curve_name(NID_secp384r1);
  if (!key) {
    goto out;
  }
  if (1 != EC_KEY_set_private_key(key, pD)) {
    goto out;
  }
  SHA384(message, message_size, output);
  sig = ECDSA_do_sign(output, 48, key);
  if (!sig) {
    goto out;
  }

  if (BN_num_bytes(sig->r) > P384_PRIVATE_KEY_SIZE) {
    goto out;
  }
  BN_bn2bin(sig->r, &signature[0]);
  if (BN_num_bytes(sig->s) > P384_PRIVATE_KEY_SIZE) {
    goto out;
  }
  BN_bn2bin(sig->s, &signature[P384_PRIVATE_KEY_SIZE]);
  ret = 1;

out:
  EC_KEY_free(key);
  BN_clear_free(pD);
  ECDSA_SIG_free(sig);
  return ret;
}

int P384Verify(const uint8_t *message, size_t message_size,
               const uint8_t signature[P384_SIGNATURE_SIZE],
               const uint8_t public_key[P384_PUBLIC_KEY_SIZE]) {
  int ret = 0;
  uint8_t output[48];
  EC_KEY *key = NULL;
  BIGNUM *bn_ret = NULL;
  BIGNUM *x = NULL;
  BIGNUM *y = NULL;
  ECDSA_SIG *sig = NULL;

  SHA384(message, message_size, output);
  key = EC_KEY_new_by_curve_name(NID_secp384r1);
  if (!key) {
    goto out;
  }
  x = BN_new();
  if (!x) {
    goto out;
  }
  bn_ret = BN_bin2bn(&public_key[0], P384_PUBLIC_KEY_SIZE / 2, x);
  if (!bn_ret) {
    goto out;
  }
  y = BN_new();
  if (!y) {
    goto out;
  }
  bn_ret = BN_bin2bn(&public_key[P384_PUBLIC_KEY_SIZE / 2], P384_PUBLIC_KEY_SIZE / 2, y);
  if (!bn_ret) {
    goto out;
  }
  if (1 != EC_KEY_set_public_key_affine_coordinates(key, x, y)) {
    goto out;
  }


  sig = ECDSA_SIG_new();
  if (!sig) {
    goto out;
  }
  bn_ret = BN_bin2bn(&signature[0], P384_SIGNATURE_SIZE / 2, sig->r);
  if (!bn_ret) {
    goto out;
  }
  bn_ret = BN_bin2bn(&signature[P384_SIGNATURE_SIZE / 2], P384_SIGNATURE_SIZE / 2,
            sig->s);
  if (!bn_ret) {
    goto out;
  }
  ret = ECDSA_do_verify(output, 48, sig, key);

out:
  BN_clear_free(y);
  BN_clear_free(x);
  EC_KEY_free(key);
  ECDSA_SIG_free(sig);
  return ret;
}
