/*
  chronyd/chronyc - Programs for keeping computer clocks accurate.

 **********************************************************************
 * Copyright (C) Miroslav Lichvar  2020
 * 
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of version 2 of the GNU General Public License as
 * published by the Free Software Foundation.
 * 
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 * 
 **********************************************************************

  =======================================================================

  NTS Authenticator and Encrypted Extension Fields extension field
  */

#include "config.h"

#include "sysincl.h"

#include "nts_ntp_auth.h"

#include "logging.h"
#include "ntp_ext.h"
#include "nts_ntp.h"
#include "siv.h"
#include "util.h"

struct AuthHeader {
  uint16_t nonce_length;
  uint16_t ciphertext_length;
};

/* ================================================== */

static int
get_padding_length(int length)
{
  return length % 4U ? 4 - length % 4U : 0;
}

/* ================================================== */

static int
get_padded_length(int length)
{
  return length + get_padding_length(length);
}

/* ================================================== */

int
NNA_GenerateAuthEF(NTP_Packet *packet, NTP_PacketInfo *info, SIV_Instance siv,
                   const unsigned char *nonce, int nonce_length,
                   const unsigned char *plaintext, int plaintext_length,
                   int min_ef_length)
{
  int auth_length, ciphertext_length, assoc_length;
  int nonce_padding, ciphertext_padding, additional_padding;
  unsigned char *ciphertext, *body;
  struct AuthHeader *header;

  assert(sizeof (*header) == 4);

  if (nonce_length <= 0 || plaintext_length < 0) {
    DEBUG_LOG("Invalid nonce/plaintext length");
    return 0;
  }

  assoc_length = info->length;
  ciphertext_length = SIV_GetTagLength(siv) + plaintext_length;
  nonce_padding = get_padding_length(nonce_length);
  ciphertext_padding = get_padding_length(ciphertext_length);
  min_ef_length = get_padded_length(min_ef_length);

  auth_length = sizeof (*header) + nonce_length + nonce_padding +
                ciphertext_length + ciphertext_padding;
  additional_padding = MAX(min_ef_length - auth_length - 4, 0);
  additional_padding = MAX(NTS_MIN_UNPADDED_NONCE_LENGTH - nonce_length - nonce_padding,
                           additional_padding);
  auth_length += additional_padding;

  if (!NEF_AddBlankField(packet, info, NTP_EF_NTS_AUTH_AND_EEF, auth_length,
                         (void **)&header)) {
    DEBUG_LOG("Could not add EF");
    return 0;
  }

  header->nonce_length = htons(nonce_length);
  header->ciphertext_length = htons(ciphertext_length);

  body = (unsigned char *)(header + 1);
  ciphertext = body + nonce_length + nonce_padding;

  if ((unsigned char *)header + auth_length !=
      ciphertext + ciphertext_length + ciphertext_padding + additional_padding)
    assert(0);

  memcpy(body, nonce, nonce_length);
  memset(body + nonce_length, 0, nonce_padding);

  if (!SIV_Encrypt(siv, nonce, nonce_length, packet, assoc_length,
                   plaintext, plaintext_length, ciphertext, ciphertext_length)) {
    DEBUG_LOG("SIV encrypt failed");
    info->length = assoc_length;
    return 0;
  }

  memset(ciphertext + ciphertext_length, 0, ciphertext_padding + additional_padding);

  return 1;
}

/* ================================================== */

int
NNA_DecryptAuthEF(NTP_Packet *packet, NTP_PacketInfo *info, SIV_Instance siv, int ef_start,
                  unsigned char *plaintext, int buffer_length, int *plaintext_length)
{
  unsigned int siv_tag_length, nonce_length, ciphertext_length;
  unsigned char *nonce, *ciphertext;
  int ef_type, ef_body_length;
  void *ef_body;
  struct AuthHeader *header;

  if (buffer_length < 0)
    return 0;

  if (!NEF_ParseField(packet, info->length, ef_start,
                      NULL, &ef_type, &ef_body, &ef_body_length))
    return 0;

  if (ef_type != NTP_EF_NTS_AUTH_AND_EEF || ef_body_length < sizeof (*header))
    return 0;

  header = ef_body;

  nonce_length = ntohs(header->nonce_length);
  ciphertext_length = ntohs(header->ciphertext_length);

  if (get_padded_length(nonce_length) +
      get_padded_length(ciphertext_length) > ef_body_length)
    return 0;

  nonce = (unsigned char *)(header + 1);
  ciphertext = nonce + get_padded_length(nonce_length);

  siv_tag_length = SIV_GetTagLength(siv);

  if (nonce_length < 1 ||
      ciphertext_length < siv_tag_length ||
      ciphertext_length - siv_tag_length > buffer_length) {
    DEBUG_LOG("Unexpected nonce/ciphertext length");
    return 0;
  }

  if (ef_body_length < sizeof (*header) +
        NTS_MIN_UNPADDED_NONCE_LENGTH + get_padded_length(ciphertext_length)) {
    DEBUG_LOG("Missing padding");
    return 0;
  }

  *plaintext_length = ciphertext_length - siv_tag_length;
  assert(*plaintext_length >= 0);

  if (!SIV_Decrypt(siv, nonce, nonce_length, packet, ef_start,
                   ciphertext, ciphertext_length, plaintext, *plaintext_length)) {
    DEBUG_LOG("SIV decrypt failed");
    return 0;
  }

  return 1;
}
