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

// This is an implementation of the DiceGenerateCertificate that generates a
// CWT-style CBOR certificate based on a template using the ED25519-SHA512
// signature scheme.
//
// If no variable length descriptors are used in a DICE certificate, the
// certificate can be constructed from a template instead of using a CBOR /
// COSE library. This implementation includes only hashes and inline
// configuration in the certificate fields. This approach may be especially
// useful in very low level components where simplicity is paramount.
//
// This function will return kDiceResultInvalidInput if 'input_values' specifies
// any variable length descriptors. In particular:
//   * code_descriptor_size must be zero
//   * authority_descriptor_size must be zero
//   * config_type must be kDiceConfigTypeInline

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

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

#if DICE_PUBLIC_KEY_SIZE != 32
#error "Only Ed25519 is supported; 32 bytes needed to store the public key."
#endif
#if DICE_SIGNATURE_SIZE != 64
#error "Only Ed25519 is supported; 64 bytes needed to store the signature."
#endif

// 20 bytes of header, 366 bytes of payload.
#define DICE_TBS_SIZE 386

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

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 DiceGenerateCertificate(
    void* context,
    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_SIZE];
  uint8_t authority_private_key[DICE_PRIVATE_KEY_SIZE];

  // Derive keys and IDs from the private key seeds.
  uint8_t subject_public_key[DICE_PUBLIC_KEY_SIZE];
  result = DiceKeypairFromSeed(context, subject_private_key_seed,
                               subject_public_key, subject_private_key);
  if (result != kDiceResultOk) {
    goto out;
  }

  uint8_t subject_id[DICE_ID_SIZE];
  result = DiceDeriveCdiCertificateId(context, subject_public_key,
                                      DICE_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_SIZE];
  result = DiceKeypairFromSeed(context, authority_private_key_seed,
                               authority_public_key, authority_private_key);
  if (result != kDiceResultOk) {
    goto out;
  }

  uint8_t authority_id[DICE_ID_SIZE];
  result = DiceDeriveCdiCertificateId(context, authority_public_key,
                                      DICE_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.
  uint8_t tbs[DICE_TBS_SIZE];
  memcpy(tbs, kTbsHeader, sizeof(kTbsHeader));
  memcpy(&tbs[sizeof(kTbsHeader)],
         &certificate[kFieldTable[kFieldIndexPayload].offset],
         kFieldTable[kFieldIndexPayload].length);

  uint8_t signature[DICE_SIGNATURE_SIZE];
  result =
      DiceSign(context, tbs, sizeof(tbs), authority_private_key, signature);
  if (result != kDiceResultOk) {
    goto out;
  }
  result =
      DiceVerify(context, tbs, sizeof(tbs), signature, authority_public_key);
  if (result != kDiceResultOk) {
    goto out;
  }
  CopyField(signature, kFieldIndexSignature, certificate);

out:
  DiceClearMemory(context, sizeof(subject_private_key), subject_private_key);
  DiceClearMemory(context, sizeof(authority_private_key),
                  authority_private_key);
  return result;
}
