// 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;
}
