/* Copyright 2024 The BoringSSL Authors
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */

#include <openssl/base.h>

#include <assert.h>
#include <string.h>

#include <openssl/bn.h>
#include <openssl/bytestring.h>
#include <openssl/crypto.h>
#include <openssl/ec.h>
#include <openssl/evp.h>
#include <openssl/hkdf.h>
#include <openssl/hmac.h>
#include <openssl/mem.h>
#include <openssl/rand.h>
#include <openssl/sha.h>

#include "../fipsmodule/bn/internal.h"
#include "../fipsmodule/ec/internal.h"
#include "../internal.h"
#include "./internal.h"
#include "openssl/err.h"

BSSL_NAMESPACE_BEGIN
namespace spake2plus {
namespace {

const uint8_t kDefaultAdditionalData[32] = {0};

// https://www.rfc-editor.org/rfc/rfc9383.html#appendix-B
// seed: 1.2.840.10045.3.1.7 point generation seed (M)
// M =
// 02886e2f97ace46e55ba9dd7242579f2993b64e16ef3dcab95afd497333d8fa12f
//
// `M` is interpreted as a X9.62-format compressed point. This is then the
// uncompressed form:
const uint8_t kM_bytes[] = {
    0x04, 0x88, 0x6e, 0x2f, 0x97, 0xac, 0xe4, 0x6e, 0x55, 0xba, 0x9d,
    0xd7, 0x24, 0x25, 0x79, 0xf2, 0x99, 0x3b, 0x64, 0xe1, 0x6e, 0xf3,
    0xdc, 0xab, 0x95, 0xaf, 0xd4, 0x97, 0x33, 0x3d, 0x8f, 0xa1, 0x2f,
    0x5f, 0xf3, 0x55, 0x16, 0x3e, 0x43, 0xce, 0x22, 0x4e, 0x0b, 0x0e,
    0x65, 0xff, 0x02, 0xac, 0x8e, 0x5c, 0x7b, 0xe0, 0x94, 0x19, 0xc7,
    0x85, 0xe0, 0xca, 0x54, 0x7d, 0x55, 0xa1, 0x2e, 0x2d, 0x20};

// https://www.rfc-editor.org/rfc/rfc9383.html#appendix-B
// seed: 1.2.840.10045.3.1.7 point generation seed (N)
// N =
// 03d8bbd6c639c62937b04d997f38c3770719c629d7014d49a24b4f98baa1292b49
//
// `N` is interpreted as a X9.62-format compressed point. This is then the
// uncompressed form:
const uint8_t kN_bytes[] = {
    0x04, 0xd8, 0xbb, 0xd6, 0xc6, 0x39, 0xc6, 0x29, 0x37, 0xb0, 0x4d,
    0x99, 0x7f, 0x38, 0xc3, 0x77, 0x07, 0x19, 0xc6, 0x29, 0xd7, 0x01,
    0x4d, 0x49, 0xa2, 0x4b, 0x4f, 0x98, 0xba, 0xa1, 0x29, 0x2b, 0x49,
    0x07, 0xd6, 0x0a, 0xa6, 0xbf, 0xad, 0xe4, 0x50, 0x08, 0xa6, 0x36,
    0x33, 0x7f, 0x51, 0x68, 0xc6, 0x4d, 0x9b, 0xd3, 0x60, 0x34, 0x80,
    0x8c, 0xd5, 0x64, 0x49, 0x0b, 0x1e, 0x65, 0x6e, 0xdb, 0xe7};

void UpdateWithLengthPrefix(SHA256_CTX *sha, Span<const uint8_t> data) {
  uint8_t len_le[8];
  CRYPTO_store_u64_le(len_le, data.size());
  SHA256_Update(sha, len_le, sizeof(len_le));
  SHA256_Update(sha, data.data(), data.size());
}

void ConstantToJacobian(const EC_GROUP *group, EC_JACOBIAN *out,
                        bssl::Span<const uint8_t> in) {
  EC_AFFINE point;
  BSSL_CHECK(ec_point_from_uncompressed(group, &point, in.data(), in.size()));
  ec_affine_to_jacobian(group, out, &point);
}

void ScalarToSizedBuffer(const EC_GROUP *group, const EC_SCALAR *s,
                         Span<uint8_t> out_buf) {
  size_t out_bytes;
  ec_scalar_to_bytes(group, out_buf.data(), &out_bytes, s);
  BSSL_CHECK(out_bytes == out_buf.size());
}

bool AddLengthPrefixed(CBB *cbb, Span<const uint8_t> bytes) {
  return CBB_add_u64le(cbb, bytes.size()) &&
         CBB_add_bytes(cbb, bytes.data(), bytes.size());
}

void InitTranscriptHash(SHA256_CTX *sha, Span<const uint8_t> context,
                        Span<const uint8_t> id_prover,
                        Span<const uint8_t> id_verifier) {
  SHA256_Init(sha);
  UpdateWithLengthPrefix(sha, context);
  UpdateWithLengthPrefix(sha, id_prover);
  UpdateWithLengthPrefix(sha, id_verifier);
  UpdateWithLengthPrefix(sha, kM_bytes);
  UpdateWithLengthPrefix(sha, kN_bytes);
}

bool ComputeTranscript(uint8_t out_prover_confirm[kConfirmSize],
                       uint8_t out_verifier_confirm[kConfirmSize],
                       uint8_t out_secret[kSecretSize],
                       const uint8_t prover_share[kShareSize],
                       const uint8_t verifier_share[kShareSize],
                       SHA256_CTX *sha, const EC_AFFINE *Z, const EC_AFFINE *V,
                       const EC_SCALAR *w0) {
  const EC_GROUP *group = EC_group_p256();

  uint8_t Z_enc[kShareSize];
  size_t Z_enc_len = ec_point_to_bytes(group, Z, POINT_CONVERSION_UNCOMPRESSED,
                                       Z_enc, sizeof(Z_enc));
  BSSL_CHECK(Z_enc_len == sizeof(Z_enc));

  uint8_t V_enc[kShareSize];
  size_t V_enc_len = ec_point_to_bytes(group, V, POINT_CONVERSION_UNCOMPRESSED,
                                       V_enc, sizeof(V_enc));
  BSSL_CHECK(V_enc_len == sizeof(V_enc));

  uint8_t w0_enc[kVerifierSize];
  ScalarToSizedBuffer(group, w0, w0_enc);

  uint8_t K_main[SHA256_DIGEST_LENGTH];
  UpdateWithLengthPrefix(sha, Span(prover_share, kShareSize));
  UpdateWithLengthPrefix(sha, Span(verifier_share, kShareSize));
  UpdateWithLengthPrefix(sha, Z_enc);
  UpdateWithLengthPrefix(sha, V_enc);
  UpdateWithLengthPrefix(sha, w0_enc);
  SHA256_Final(K_main, sha);

  auto confirmation_str = StringAsBytes("ConfirmationKeys");
  uint8_t keys[kSecretSize * 2];
  if (!HKDF(keys, sizeof(keys), EVP_sha256(), K_main, sizeof(K_main), nullptr,
            0, confirmation_str.data(), confirmation_str.size())) {
    return false;
  }

  auto secret_info_str = StringAsBytes("SharedKey");
  if (!HKDF(out_secret, kSecretSize, EVP_sha256(), K_main, sizeof(K_main),
            nullptr, 0, secret_info_str.data(), secret_info_str.size())) {
    return false;
  }

  unsigned prover_confirm_len;
  if (HMAC(EVP_sha256(), keys, kSecretSize, verifier_share, kShareSize,
           out_prover_confirm, &prover_confirm_len) == nullptr) {
    return false;
  }
  BSSL_CHECK(prover_confirm_len == kConfirmSize);

  unsigned verifier_confirm_len;
  if (HMAC(EVP_sha256(), keys + kSecretSize, kSecretSize, prover_share,
           kShareSize, out_verifier_confirm,
           &verifier_confirm_len) == nullptr) {
    return false;
  }
  BSSL_CHECK(verifier_confirm_len == kConfirmSize);

  return true;
}

}  // namespace

bool Register(Span<uint8_t> out_w0, Span<uint8_t> out_w1,
              Span<uint8_t> out_registration_record,
              Span<const uint8_t> password, Span<const uint8_t> id_prover,
              Span<const uint8_t> id_verifier) {
  if (out_w0.size() != kVerifierSize || out_w1.size() != kVerifierSize ||
      out_registration_record.size() != kRegistrationRecordSize) {
    OPENSSL_PUT_ERROR(CRYPTO, ERR_R_INTERNAL_ERROR);
    return false;
  }

  // Offline registration format from:
  // https://www.rfc-editor.org/rfc/rfc9383.html#section-3.2
  ScopedCBB mhf_input;
  if (!CBB_init(mhf_input.get(), password.size() + id_prover.size() +
                                     id_verifier.size() +
                                     3 * sizeof(uint64_t)) ||  //
      !AddLengthPrefixed(mhf_input.get(), password) ||
      !AddLengthPrefixed(mhf_input.get(), id_prover) ||
      !AddLengthPrefixed(mhf_input.get(), id_verifier) ||
      !CBB_flush(mhf_input.get())) {
    OPENSSL_PUT_ERROR(CRYPTO, ERR_R_INTERNAL_ERROR);
    return false;
  }

  // https://neuromancer.sk/std/nist/P-256
  //   sage: p =
  //   0xffffffff00000001000000000000000000000000ffffffffffffffffffffffff
  //   ....: K = GF(p)
  //   ....: a =
  //   K(0xffffffff00000001000000000000000000000000fffffffffffffffffffffffc)
  //   ....: b =
  //   K(0x5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b)
  //   ....: E = EllipticCurve(K, (a, b))
  //   ....: G =
  //   E(0x6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296,
  //   ....: 0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5)
  //   ....:
  //   E.set_order(0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63
  //   ....: 2551 * 0x1)
  //   sage: k = 64
  //   sage: L = (2 * (ceil(log(p)/log(2)) + k)) / 8

  // RFC 9383 Section 3.2
  constexpr size_t kKDFOutputSize = 80;
  constexpr size_t kKDFOutputWords = kKDFOutputSize / BN_BYTES;

  uint8_t key[kKDFOutputSize];
  if (!EVP_PBE_scrypt((const char *)CBB_data(mhf_input.get()),
                      CBB_len(mhf_input.get()), nullptr, 0,
                      /*N=*/32768, /*r=*/8, /*p=*/1,
                      /*max_mem=*/1024 * 1024 * 33, key, kKDFOutputSize)) {
    OPENSSL_PUT_ERROR(CRYPTO, ERR_R_INTERNAL_ERROR);
    return false;
  }

  const EC_GROUP *group = EC_group_p256();
  BN_ULONG w0_words[kKDFOutputWords / 2];
  bn_big_endian_to_words(w0_words, kKDFOutputWords / 2, key,
                         kKDFOutputSize / 2);
  EC_SCALAR w0;
  ec_scalar_reduce(group, &w0, w0_words, kKDFOutputWords / 2);
  ScalarToSizedBuffer(group, &w0, out_w0);

  BN_ULONG w1_words[kKDFOutputWords / 2];
  bn_big_endian_to_words(w1_words, kKDFOutputWords / 2,
                         key + kKDFOutputSize / 2, kKDFOutputSize / 2);
  EC_SCALAR w1;
  ec_scalar_reduce(group, &w1, w1_words, kKDFOutputWords / 2);
  ScalarToSizedBuffer(group, &w1, out_w1);

  EC_JACOBIAN L_j;
  EC_AFFINE L;
  if (!ec_point_mul_scalar_base(group, &L_j, &w1) ||  //
      !ec_jacobian_to_affine(group, &L, &L_j) ||      //
      !ec_point_to_bytes(group, &L, POINT_CONVERSION_UNCOMPRESSED,
                         out_registration_record.data(),
                         kRegistrationRecordSize)) {
    OPENSSL_PUT_ERROR(CRYPTO, ERR_R_INTERNAL_ERROR);
    return false;
  }

  return true;
}

Prover::Prover() = default;
Prover::~Prover() = default;

bool Prover::Init(Span<const uint8_t> context, Span<const uint8_t> id_prover,
                  Span<const uint8_t> id_verifier, Span<const uint8_t> w0,
                  Span<const uint8_t> w1, Span<const uint8_t> x) {
  const EC_GROUP *group = EC_group_p256();

  if (!ec_scalar_from_bytes(group, &w0_, w0.data(), w0.size()) ||
      !ec_scalar_from_bytes(group, &w1_, w1.data(), w1.size()) ||
      (!x.empty() &&
       !ec_scalar_from_bytes(group, &x_, x.data(), x.size())) ||  //
      (x.empty() && !ec_random_scalar(group, &x_, kDefaultAdditionalData))) {
    OPENSSL_PUT_ERROR(CRYPTO, ERR_R_INTERNAL_ERROR);
    return false;
  }

  InitTranscriptHash(&transcript_hash_, context, id_prover, id_verifier);

  return true;
}

bool Prover::GenerateShare(Span<uint8_t> out_share) {
  if (state_ != State::kInit || out_share.size() != kShareSize) {
    OPENSSL_PUT_ERROR(CRYPTO, ERR_R_INTERNAL_ERROR);
    return false;
  }

  // Compute X = x×P + w0×M.
  // TODO(crbug.com/383778231): This could be sped up with a constant-time,
  // two-point multiplication.
  const EC_GROUP *group = EC_group_p256();
  EC_JACOBIAN l;
  if (!ec_point_mul_scalar_base(group, &l, &x_)) {
    OPENSSL_PUT_ERROR(CRYPTO, ERR_R_INTERNAL_ERROR);
    return false;
  }

  EC_JACOBIAN M_j;
  ConstantToJacobian(group, &M_j, kM_bytes);

  EC_JACOBIAN r;
  if (!ec_point_mul_scalar(group, &r, &M_j, &w0_)) {
    OPENSSL_PUT_ERROR(CRYPTO, ERR_R_INTERNAL_ERROR);
    return false;
  }

  EC_JACOBIAN X_j;
  group->meth->add(group, &X_j, &l, &r);
  if (!ec_jacobian_to_affine(group, &X_, &X_j)) {
    OPENSSL_PUT_ERROR(CRYPTO, ERR_R_INTERNAL_ERROR);
    return false;
  }

  size_t written = ec_point_to_bytes(group, &X_, POINT_CONVERSION_UNCOMPRESSED,
                                     out_share.data(), kShareSize);
  BSSL_CHECK(written == kShareSize);

  memcpy(share_, out_share.data(), kShareSize);
  state_ = State::kShareGenerated;
  return true;
}

bool Prover::ComputeConfirmation(Span<uint8_t> out_confirm,
                                 Span<uint8_t> out_secret,
                                 Span<const uint8_t> peer_share,
                                 Span<const uint8_t> peer_confirm) {
  if (state_ != State::kShareGenerated || out_confirm.size() != kConfirmSize ||
      out_secret.size() != kSecretSize || peer_share.size() != kShareSize ||
      peer_confirm.size() != kConfirmSize) {
    OPENSSL_PUT_ERROR(CRYPTO, ERR_R_INTERNAL_ERROR);
    return false;
  }

  const EC_GROUP *group = EC_group_p256();
  EC_AFFINE Y;
  if (!ec_point_from_uncompressed(group, &Y, peer_share.data(),
                                  peer_share.size())) {
    OPENSSL_PUT_ERROR(CRYPTO, ERR_R_INTERNAL_ERROR);
    return false;
  }

  EC_JACOBIAN N_j;
  ConstantToJacobian(group, &N_j, kN_bytes);

  EC_JACOBIAN r;
  if (!ec_point_mul_scalar(group, &r, &N_j, &w0_)) {
    OPENSSL_PUT_ERROR(CRYPTO, ERR_R_INTERNAL_ERROR);
    return false;
  }

  ec_felem_neg(group, &r.Y, &r.Y);

  EC_JACOBIAN Y_j;
  ec_affine_to_jacobian(group, &Y_j, &Y);

  EC_JACOBIAN t;
  group->meth->add(group, &t, &Y_j, &r);

  EC_JACOBIAN tmp;
  EC_AFFINE Z, V;
  // TODO(crbug.com/383778231): The two affine conversions could be batched
  // together.
  if (!ec_point_mul_scalar(group, &tmp, &t, &x_) ||   //
      !ec_jacobian_to_affine(group, &Z, &tmp) ||      //
      !ec_point_mul_scalar(group, &tmp, &t, &w1_) ||  //
      !ec_jacobian_to_affine(group, &V, &tmp)) {
    return 0;
  }

  uint8_t verifier_confirm[kConfirmSize];
  if (!ComputeTranscript(out_confirm.data(), verifier_confirm,
                         out_secret.data(), share_, peer_share.data(),
                         &transcript_hash_, &Z, &V, &w0_) ||
      CRYPTO_memcmp(verifier_confirm, peer_confirm.data(),
                    sizeof(verifier_confirm)) != 0) {
    return 0;
  }

  state_ = State::kDone;
  return true;
}

Verifier::Verifier() = default;
Verifier::~Verifier() = default;

bool Verifier::Init(Span<const uint8_t> context, Span<const uint8_t> id_prover,
                    Span<const uint8_t> id_verifier, Span<const uint8_t> w0,
                    Span<const uint8_t> registration_record,
                    Span<const uint8_t> y) {
  const EC_GROUP *group = EC_group_p256();

  if (!ec_scalar_from_bytes(group, &w0_, w0.data(), w0.size()) ||
      !ec_point_from_uncompressed(group, &L_, registration_record.data(),
                                  registration_record.size()) ||  //
      (!y.empty() &&
       !ec_scalar_from_bytes(group, &y_, y.data(), y.size())) ||  //
      (y.empty() && !ec_random_scalar(group, &y_, kDefaultAdditionalData))) {
    OPENSSL_PUT_ERROR(CRYPTO, ERR_R_INTERNAL_ERROR);
    return false;
  }

  InitTranscriptHash(&transcript_hash_, context, id_prover, id_verifier);

  return true;
}


bool Verifier::ProcessProverShare(Span<uint8_t> out_share,
                                  Span<uint8_t> out_confirm,
                                  Span<uint8_t> out_secret,
                                  Span<const uint8_t> prover_share) {
  if (state_ != State::kInit ||  //
      out_share.size() != kShareSize || out_confirm.size() != kConfirmSize ||
      out_secret.size() != kSecretSize || prover_share.size() != kShareSize) {
    OPENSSL_PUT_ERROR(CRYPTO, ERR_R_INTERNAL_ERROR);
    return false;
  }

  const EC_GROUP *group = EC_group_p256();
  EC_JACOBIAN l, r, M_j, N_j;
  ConstantToJacobian(group, &M_j, kM_bytes);
  ConstantToJacobian(group, &N_j, kN_bytes);

  // Compute Y = y×P + w0×M.
  // TODO(crbug.com/383778231): This could be sped up with a constant-time,
  // two-point multiplication.
  if (!ec_point_mul_scalar_base(group, &l, &y_) ||
      !ec_point_mul_scalar(group, &r, &N_j, &w0_)) {
    OPENSSL_PUT_ERROR(CRYPTO, ERR_R_INTERNAL_ERROR);
    return false;
  }

  EC_JACOBIAN Y_j;
  EC_AFFINE Y;
  group->meth->add(group, &Y_j, &l, &r);
  if (!ec_jacobian_to_affine(group, &Y, &Y_j)) {
    OPENSSL_PUT_ERROR(CRYPTO, ERR_R_INTERNAL_ERROR);
    return false;
  }

  const size_t written = ec_point_to_bytes(
      group, &Y, POINT_CONVERSION_UNCOMPRESSED, out_share.data(), kShareSize);
  BSSL_CHECK(written == kShareSize);

  EC_JACOBIAN r2;
  EC_AFFINE X;
  if (!ec_point_from_uncompressed(group, &X, prover_share.data(),
                                  prover_share.size()) ||
      !ec_point_mul_scalar(group, &r2, &M_j, &w0_)) {
    OPENSSL_PUT_ERROR(CRYPTO, ERR_R_INTERNAL_ERROR);
    return false;
  }

  ec_felem_neg(group, &r2.Y, &r2.Y);

  EC_JACOBIAN X_j, T;
  ec_affine_to_jacobian(group, &X_j, &X);
  group->meth->add(group, &T, &X_j, &r2);

  // TODO(crbug.com/383778231): The two affine conversions could be batched
  // together.
  EC_JACOBIAN tmp;
  EC_AFFINE Z;
  if (!ec_point_mul_scalar(group, &tmp, &T, &y_) ||  //
      !ec_jacobian_to_affine(group, &Z, &tmp)) {
    OPENSSL_PUT_ERROR(CRYPTO, ERR_R_INTERNAL_ERROR);
    return false;
  }

  EC_JACOBIAN L_j;
  EC_AFFINE V;
  ec_affine_to_jacobian(group, &L_j, &L_);
  if (!ec_point_mul_scalar(group, &tmp, &L_j, &y_) ||  //
      !ec_jacobian_to_affine(group, &V, &tmp)) {
    OPENSSL_PUT_ERROR(CRYPTO, ERR_R_INTERNAL_ERROR);
    return false;
  }

  if (!ComputeTranscript(confirm_, out_confirm.data(), out_secret.data(),
                         prover_share.data(), out_share.data(),
                         &transcript_hash_, &Z, &V, &w0_)) {
    OPENSSL_PUT_ERROR(CRYPTO, ERR_R_INTERNAL_ERROR);
    return false;
  }

  state_ = State::kProverShareSeen;
  return true;
}

bool Verifier::VerifyProverConfirmation(Span<const uint8_t> peer_confirm) {
  if (state_ != State::kProverShareSeen ||    //
      peer_confirm.size() != kConfirmSize ||  //
      CRYPTO_memcmp(confirm_, peer_confirm.data(), sizeof(confirm_)) != 0) {
    OPENSSL_PUT_ERROR(CRYPTO, ERR_R_INTERNAL_ERROR);
    return false;
  }

  state_ = State::kDone;
  return true;
}

}  // namespace spake2plus

BSSL_NAMESPACE_END
