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

// If no variable length descriptors are used in a DICE certificate, the
// certificate can be constructed from a template instead of using a CBOR
// library. This implementation includes only hashes and inline configuration in
// the DICE extension. For convenience this uses only the lower level curve25519
// implementation in boringssl. This approach may be especially useful in very
// low level components where simplicity is paramount.

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

#include "dice/dice.h"
#include "dice/utils.h"

// A well-formed certificate, but with zeros in all fields to be filled.
static const uint8_t kTemplate[441] = {
    // Constant encoding.
    0x84, 0x43, 0xa1, 0x01, 0x27, 0xa0, 0x59, 0x01, 0x6e,
    // Offset 9: Payload starts here, 366 bytes.
    0xa8, 0x01, 0x78, 0x28,
    // Offset 13: CWT issuer, 40 bytes.
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00,
    // Constant encoding.
    0x02, 0x78, 0x28,
    // Offset 56: CWT subject, 40 bytes.
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00,
    // Constant encoding.
    0x3a, 0x00, 0x47, 0x44, 0x50, 0x58, 0x40,
    // Offset 103: Code hash, 64 bytes.
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00,
    // Constant encoding.
    0x3a, 0x00, 0x47, 0x44, 0x53, 0x58, 0x40,
    // Offset 174: Configuration value, 64 bytes.
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00,
    // Constant encoding.
    0x3a, 0x00, 0x47, 0x44, 0x54, 0x58, 0x40,
    // Offset 245: Authority hash, 64 bytes.
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00,
    // Constant encoding.
    0x3a, 0x00, 0x47, 0x44, 0x56, 0x41,
    // Offset 315: Mode, 1 byte.
    0x00,
    // Constant encoding.
    0x3a, 0x00, 0x47, 0x44, 0x57, 0x58, 0x2d, 0xa5, 0x01, 0x01, 0x03, 0x27,
    0x04, 0x81, 0x02, 0x20, 0x06, 0x21, 0x58, 0x20,
    // Offset 336: Public key, 32 bytes.
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    // Constant encoding (key usage).
    0x3a, 0x00, 0x47, 0x44, 0x58, 0x41, 0x20,
    // Offset 375: Payload ends here.
    // Constant encoding.
    0x58, 0x40,
    // Offset 377: Signature, 64 bytes.
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00};

// The data to be signed is not the certificate, but the payload appended to
// this header. This is the 'Sig_structure' for COSE_Sign1, per RFC 8152.
static const uint8_t kTbsHeader[20] = {0x84, 0x6a, 0x53, 0x69, 0x67, 0x6e, 0x61,
                                       0x74, 0x75, 0x72, 0x65, 0x31, 0x43, 0xa1,
                                       0x01, 0x27, 0x40, 0x59, 0x01, 0x6e};
// 20 bytes of header, 366 bytes of payload.
static const size_t kTbsSize = 386;

static const struct {
  size_t offset;
  size_t length;
} kFieldTable[] = {{13, 40},   // Issuer
                   {56, 40},   // Subject
                   {103, 64},  // Code hash
                   {174, 64},  // Config descriptor
                   {245, 64},  // Authority hash
                   {315, 1},   // Mode
                   {336, 32},  // Public key
                   {377, 64},  // Signature
                   {9, 366}};  // Payload

static const size_t kFieldIndexIssuer = 0;
static const size_t kFieldIndexSubject = 1;
static const size_t kFieldIndexCodeHash = 2;
static const size_t kFieldIndexConfigDescriptor = 3;
static const size_t kFieldIndexAuthorityHash = 4;
static const size_t kFieldIndexMode = 5;
static const size_t kFieldIndexSubjectPublicKey = 6;
static const size_t kFieldIndexSignature = 7;
static const size_t kFieldIndexPayload = 8;

// |buffer| must point to the beginning of the template buffer and |src| must
// point to at least <field-length> bytes.
static void CopyField(const uint8_t* src, size_t index, uint8_t* buffer) {
  memcpy(&buffer[kFieldTable[index].offset], src, kFieldTable[index].length);
}

DiceResult DiceGenerateCborCertificateFromTemplateOp(
    const DiceOps* ops,
    const uint8_t subject_private_key_seed[DICE_PRIVATE_KEY_SEED_SIZE],
    const uint8_t authority_private_key_seed[DICE_PRIVATE_KEY_SEED_SIZE],
    const DiceInputValues* input_values, size_t certificate_buffer_size,
    uint8_t* certificate, size_t* certificate_actual_size) {
  DiceResult result = kDiceResultOk;

  // Variable length descriptors are not supported.
  if (input_values->code_descriptor_size > 0 ||
      input_values->config_type != kDiceConfigTypeInline ||
      input_values->authority_descriptor_size > 0) {
    return kDiceResultInvalidInput;
  }

  // We know the certificate size upfront so we can do the buffer size check.
  *certificate_actual_size = sizeof(kTemplate);
  if (certificate_buffer_size < sizeof(kTemplate)) {
    return kDiceResultBufferTooSmall;
  }

  // Declare buffers which are cleared on 'goto out'.
  uint8_t subject_private_key[DICE_PRIVATE_KEY_MAX_SIZE];
  uint8_t authority_private_key[DICE_PRIVATE_KEY_MAX_SIZE];

  // These are 'variably modified' types so need to be declared upfront.
  uint8_t tbs[kTbsSize];

  // Derive keys and IDs from the private key seeds.
  uint8_t subject_public_key[DICE_PUBLIC_KEY_MAX_SIZE];
  size_t subject_public_key_size;
  size_t subject_private_key_size;
  result = ops->keypair_from_seed(
      ops, subject_private_key_seed, subject_public_key,
      &subject_public_key_size, subject_private_key, &subject_private_key_size);
  if (result != kDiceResultOk) {
    goto out;
  }

  uint8_t subject_id[20];
  result = DiceDeriveCdiCertificateId(ops, subject_public_key,
                                      subject_public_key_size, subject_id);
  if (result != kDiceResultOk) {
    goto out;
  }
  uint8_t subject_id_hex[40];
  DiceHexEncode(subject_id, sizeof(subject_id), subject_id_hex,
                sizeof(subject_id_hex));

  uint8_t authority_public_key[DICE_PUBLIC_KEY_MAX_SIZE];
  size_t authority_public_key_size;
  size_t authority_private_key_size;
  result = ops->keypair_from_seed(
      ops, authority_private_key_seed, authority_public_key,
      &authority_public_key_size, authority_private_key,
      &authority_private_key_size);
  if (result != kDiceResultOk) {
    goto out;
  }

  uint8_t authority_id[20];
  result = DiceDeriveCdiCertificateId(ops, authority_public_key,
                                      authority_public_key_size, authority_id);
  if (result != kDiceResultOk) {
    goto out;
  }
  uint8_t authority_id_hex[40];
  DiceHexEncode(authority_id, sizeof(authority_id), authority_id_hex,
                sizeof(authority_id_hex));

  // First copy in the entire template, then fill in the fields.
  memcpy(certificate, kTemplate, sizeof(kTemplate));
  CopyField(authority_id_hex, kFieldIndexIssuer, certificate);
  CopyField(subject_id_hex, kFieldIndexSubject, certificate);
  CopyField(subject_public_key, kFieldIndexSubjectPublicKey, certificate);
  CopyField(input_values->code_hash, kFieldIndexCodeHash, certificate);
  CopyField(input_values->config_value, kFieldIndexConfigDescriptor,
            certificate);
  CopyField(input_values->authority_hash, kFieldIndexAuthorityHash,
            certificate);
  certificate[kFieldTable[kFieldIndexMode].offset] = input_values->mode;

  // Fill the TBS structure using the payload from the certificate.
  memcpy(tbs, kTbsHeader, sizeof(kTbsHeader));
  memcpy(&tbs[sizeof(kTbsHeader)],
         &certificate[kFieldTable[kFieldIndexPayload].offset],
         kFieldTable[kFieldIndexPayload].length);

  uint8_t signature[64];
  result = ops->sign(ops, tbs, kTbsSize, authority_private_key,
                     authority_private_key_size, sizeof(signature), signature);
  if (result != kDiceResultOk) {
    goto out;
  }
  if (ops->verify) {
    result = ops->verify(ops, tbs, kTbsSize, signature, sizeof(signature),
                         authority_public_key, authority_public_key_size);
    if (result != kDiceResultOk) {
      goto out;
    }
  }
  CopyField(signature, kFieldIndexSignature, certificate);

out:
  ops->clear_memory(ops, sizeof(subject_private_key), subject_private_key);
  ops->clear_memory(ops, sizeof(authority_private_key), authority_private_key);
  return result;
}
