/*
 * Copyright (c) 2020 Siddharth Chandrasekaran <siddharth@embedjournal.com>
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr/logging/log.h>
LOG_MODULE_DECLARE(osdp, CONFIG_OSDP_LOG_LEVEL);

#include <string.h>
#include "osdp_common.h"

#define TAG "PHY: "

#define OSDP_PKT_MARK                  0xFF
#define OSDP_PKT_SOM                   0x53
#define PKT_CONTROL_SQN                0x03
#define PKT_CONTROL_CRC                0x04
#define PKT_CONTROL_SCB                0x08

struct osdp_packet_header {
	uint8_t mark;
	uint8_t som;
	uint8_t pd_address;
	uint8_t len_lsb;
	uint8_t len_msb;
	uint8_t control;
	uint8_t data[];
} __packed;

uint8_t osdp_compute_checksum(uint8_t *msg, int length)
{
	uint8_t checksum = 0;
	int i, whole_checksum;

	whole_checksum = 0;
	for (i = 0; i < length; i++) {
		whole_checksum += msg[i];
		checksum = ~(0xff & whole_checksum) + 1;
	}
	return checksum;
}

static int osdp_phy_get_seq_number(struct osdp_pd *pd, int do_inc)
{
	/* pd->seq_num is set to -1 to reset phy cmd state */
	if (do_inc) {
		pd->seq_number += 1;
		if (pd->seq_number > 3) {
			pd->seq_number = 1;
		}
	}
	return pd->seq_number & PKT_CONTROL_SQN;
}

int osdp_phy_packet_get_data_offset(struct osdp_pd *pd, const uint8_t *buf)
{
	int sb_len = 0;
	struct osdp_packet_header *pkt;

	ARG_UNUSED(pd);
	pkt = (struct osdp_packet_header *)buf;
	if (pkt->control & PKT_CONTROL_SCB) {
		sb_len = pkt->data[0];
	}
	return sizeof(struct osdp_packet_header) + sb_len;
}

uint8_t *osdp_phy_packet_get_smb(struct osdp_pd *pd, const uint8_t *buf)
{
	struct osdp_packet_header *pkt;

	ARG_UNUSED(pd);
	pkt = (struct osdp_packet_header *)buf;
	if (pkt->control & PKT_CONTROL_SCB) {
		return pkt->data;
	}
	return NULL;
}

int osdp_phy_in_sc_handshake(int is_reply, int id)
{
	if (is_reply) {
		return (id == REPLY_CCRYPT || id == REPLY_RMAC_I);
	} else {
		return (id == CMD_CHLNG || id == CMD_SCRYPT);
	}
}

int osdp_phy_packet_init(struct osdp_pd *pd, uint8_t *buf, int max_len)
{
	int exp_len, pd_mode, sb_len, id;
	struct osdp_packet_header *pkt;

	pd_mode = ISSET_FLAG(pd, PD_FLAG_PD_MODE);
	exp_len = sizeof(struct osdp_packet_header) + 64; /* 64 is estimated */
	if (max_len < exp_len) {
		LOG_INF(TAG "packet_init: out of space! CMD: %02x", pd->cmd_id);
		return OSDP_ERR_PKT_FMT;
	}

	/* Fill packet header */
	pkt = (struct osdp_packet_header *)buf;
	pkt->mark = OSDP_PKT_MARK;
	pkt->som = OSDP_PKT_SOM;
	pkt->pd_address = pd->address & 0x7F;	/* Use only the lower 7 bits */
	if (pd_mode) {
		/* PD must reply with MSB of it's address set */
		pkt->pd_address |= 0x80;
		id = pd->reply_id;
	} else {
		id = pd->cmd_id;
	}
	pkt->control = osdp_phy_get_seq_number(pd, !pd_mode);
	pkt->control |= PKT_CONTROL_CRC;

	sb_len = 0;
	if (ISSET_FLAG(pd, PD_FLAG_SC_ACTIVE)) {
		pkt->control |= PKT_CONTROL_SCB;
		pkt->data[0] = sb_len = 2;
		pkt->data[1] = SCS_15;
	} else if (osdp_phy_in_sc_handshake(pd_mode, id)) {
		pkt->control |= PKT_CONTROL_SCB;
		pkt->data[0] = sb_len = 3;
		pkt->data[1] = SCS_11;
	}

	return sizeof(struct osdp_packet_header) + sb_len;
}

int osdp_phy_packet_finalize(struct osdp_pd *pd, uint8_t *buf,
			     int len, int max_len)
{
	uint16_t crc16;
	struct osdp_packet_header *pkt;

	/* Do a sanity check only as we expect expect header to be prefilled */
	if (buf[0] != OSDP_PKT_MARK || buf[1] != OSDP_PKT_SOM) {
		LOG_ERR(TAG "packet_finalize: header validation failed! "
			"CMD: %02x", pd->cmd_id);
		return OSDP_ERR_PKT_FMT;
	}
	pkt = (struct osdp_packet_header *)buf;

	/* len: with 2 byte CRC; without 1 byte mark */
	pkt->len_lsb = BYTE_0(len - 1 + 2);
	pkt->len_msb = BYTE_1(len - 1 + 2);

#ifdef CONFIG_OSDP_SC_ENABLED
	uint8_t *data;
	int i, is_cmd, data_len;

	if (ISSET_FLAG(pd, PD_FLAG_SC_ACTIVE) &&
	    pkt->control & PKT_CONTROL_SCB &&
	    pkt->data[1] >= SCS_15) {
		is_cmd = !ISSET_FLAG(pd, PD_FLAG_PD_MODE);
		if (pkt->data[1] == SCS_17 || pkt->data[1] == SCS_18) {
			/**
			 * Only the data portion of message (after id byte)
			 * is encrypted. While (en/de)crypting, we must skip
			 * header, security block, and cmd/reply ID byte.
			 *
			 * Note: if cmd/reply has no data, we must set type to
			 * SCS_15/SCS_16 and send them.
			 */
			data = pkt->data + pkt->data[0] + 1;
			data_len = len - (sizeof(struct osdp_packet_header)
					  + pkt->data[0] + 1);
			len -= data_len;
			/**
			 * check if the passed buffer can hold the encrypted
			 * data where length may be rounded up to the nearest
			 * 16 byte block bondary.
			 */
			if (AES_PAD_LEN(data_len + 1) > max_len) {
				/* data_len + 1 for OSDP_SC_EOM_MARKER */
				goto out_of_space_error;
			}
			len += osdp_encrypt_data(pd, is_cmd, data, data_len);
		}
		/* len: with 4bytes MAC; with 2 byte CRC; without 1 byte mark */
		if (len + 4 > max_len) {
			goto out_of_space_error;
		}

		/* len: without 1 mark byte; with 2 byte CRC; with 4 byte MAC */
		pkt->len_lsb = BYTE_0(len - 1 + 2 + 4);
		pkt->len_msb = BYTE_1(len - 1 + 2 + 4);

		/* compute and extend the buf with 4 MAC bytes */
		osdp_compute_mac(pd, is_cmd, buf + 1, len - 1);
		data = is_cmd ? pd->sc.c_mac : pd->sc.r_mac;
		for (i = 0; i < 4; i++) {
			buf[len + i] = data[i];
		}
		len += 4;
	}
#endif /* CONFIG_OSDP_SC_ENABLED */

	/* fill crc16 */
	if (len + 2 > max_len) {
		goto out_of_space_error;
	}
	crc16 = osdp_compute_crc16(buf + 1, len - 1);  /* excluding mark byte */
	buf[len + 0] = BYTE_0(crc16);
	buf[len + 1] = BYTE_1(crc16);
	len += 2;

	return len;

out_of_space_error:
	LOG_ERR(TAG "packet_finalize: Out of buffer space! "
		"CMD: %02x", pd->cmd_id);
	return OSDP_ERR_PKT_FMT;
}

int osdp_phy_decode_packet(struct osdp_pd *pd, uint8_t *buf, int len)
{
	uint8_t *data;
	uint16_t comp, cur;
	int pkt_len, pd_mode, pd_addr, mac_offset;
	struct osdp_packet_header *pkt;

	pd_mode = ISSET_FLAG(pd, PD_FLAG_PD_MODE);
	pkt = (struct osdp_packet_header *)buf;

	/* wait till we have the header */
	if ((unsigned long)len < sizeof(struct osdp_packet_header)) {
		/* incomplete data */
		return OSDP_ERR_PKT_WAIT;
	}

	/* validate packet header */
	if (pkt->mark != OSDP_PKT_MARK || pkt->som != OSDP_PKT_SOM) {
		LOG_ERR(TAG "invalid MARK/SOM");
		return OSDP_ERR_PKT_FMT;
	}

	if (!pd_mode && !(pkt->pd_address & 0x80)) {
		LOG_ERR(TAG "reply without MSB set 0x%02x", pkt->pd_address);
		return OSDP_ERR_PKT_FMT;
	}

	/* validate packet length */
	pkt_len = (pkt->len_msb << 8) | pkt->len_lsb;
	if (pkt_len != len - 1) {
		/* wait for more data? */
		return OSDP_ERR_PKT_WAIT;
	}

	/* validate PD address */
	pd_addr = pkt->pd_address & 0x7F;
	if (pd_addr != pd->address && pd_addr != 0x7F) {
		/* not addressed to us and was not broadcasted */
		if (!pd_mode) {
			LOG_ERR(TAG "invalid pd address %d", pd_addr);
			return OSDP_ERR_PKT_FMT;
		}
		LOG_DBG(TAG "cmd for PD[%d] discarded", pd_addr);
		return OSDP_ERR_PKT_SKIP;
	}

	/* validate sequence number */
	cur = pkt->control & PKT_CONTROL_SQN;
	if (pd_mode && cur == 0) {
		/**
		 * CP is trying to restart communication by sending a 0. The
		 * current PD implementation does not hold any state between
		 * commands so we can just set seq_number to -1 (so it gets
		 * incremented to 0 with a call to phy_get_seq_number()) and
		 * invalidate any established secure channels.
		 */
		pd->seq_number = -1;
		CLEAR_FLAG(pd, PD_FLAG_SC_ACTIVE);
	}
	if (pd_mode && cur == pd->seq_number) {
		/**
		 * TODO: PD must resend the last response if CP send the same
		 * sequence number again.
		 */
		LOG_ERR(TAG "seq-repeat reply-resend feature not supported!");
		pd->reply_id = REPLY_NAK;
		pd->cmd_data[0] = OSDP_PD_NAK_SEQ_NUM;
		return OSDP_ERR_PKT_FMT;
	}
	comp = osdp_phy_get_seq_number(pd, pd_mode);
	if (comp != cur && !ISSET_FLAG(pd, PD_FLAG_SKIP_SEQ_CHECK)) {
		LOG_ERR(TAG "packet seq mismatch %d/%d", comp, cur);
		pd->reply_id = REPLY_NAK;
		pd->cmd_data[0] = OSDP_PD_NAK_SEQ_NUM;
		return OSDP_ERR_PKT_FMT;
	}
	len -= sizeof(struct osdp_packet_header); /* consume header */

	/* validate CRC/checksum */
	if (pkt->control & PKT_CONTROL_CRC) {
		cur = (buf[pkt_len] << 8) | buf[pkt_len - 1];
		comp = osdp_compute_crc16(buf + 1, pkt_len - 2);
		if (comp != cur) {
			LOG_ERR(TAG "invalid crc 0x%04x/0x%04x", comp, cur);
			pd->reply_id = REPLY_NAK;
			pd->cmd_data[0] = OSDP_PD_NAK_MSG_CHK;
			return OSDP_ERR_PKT_FMT;
		}
		mac_offset = pkt_len - 4 - 2;
		len -= 2; /* consume CRC */
	} else {
		comp = osdp_compute_checksum(buf + 1, pkt_len - 1);
		if (comp != buf[len - 1]) {
			LOG_ERR(TAG "invalid checksum %02x/%02x", comp, cur);
			pd->reply_id = REPLY_NAK;
			pd->cmd_data[0] = OSDP_PD_NAK_MSG_CHK;
			return OSDP_ERR_PKT_FMT;
		}
		mac_offset = pkt_len - 4 - 1;
		len -= 1; /* consume checksum */
	}

	data = pkt->data;

#ifdef CONFIG_OSDP_SC_ENABLED
	uint8_t *mac;
	int is_cmd;

	if (pkt->control & PKT_CONTROL_SCB) {
		if (pd_mode && !ISSET_FLAG(pd, PD_FLAG_SC_CAPABLE)) {
			LOG_ERR(TAG "PD is not SC capable");
			pd->reply_id = REPLY_NAK;
			pd->cmd_data[0] = OSDP_PD_NAK_SC_UNSUP;
			return OSDP_ERR_PKT_FMT;
		}
		if (pkt->data[1] < SCS_11 || pkt->data[1] > SCS_18) {
			LOG_ERR(TAG "invalid SB Type");
			pd->reply_id = REPLY_NAK;
			pd->cmd_data[0] = OSDP_PD_NAK_SC_COND;
			return OSDP_ERR_PKT_FMT;
		}
		if (pkt->data[1] == SCS_11 || pkt->data[1] == SCS_13) {
			/**
			 * CP signals PD to use SCBKD by setting SB data byte
			 * to 0. In CP, PD_FLAG_SC_USE_SCBKD comes from FSM; on
			 * PD we extract it from the command itself. But this
			 * usage of SCBKD is allowed only when the PD is in
			 * install mode (indicated by PD_FLAG_INSTALL_MODE).
			 */
			if (ISSET_FLAG(pd, PD_FLAG_INSTALL_MODE) &&
			    pkt->data[2] == 0) {
				SET_FLAG(pd, PD_FLAG_SC_USE_SCBKD);
			}
		}
		data = pkt->data + pkt->data[0];
		len -= pkt->data[0]; /* consume security block */
	} else {
		if (ISSET_FLAG(pd, PD_FLAG_SC_ACTIVE)) {
			LOG_ERR(TAG "Received plain-text message in SC");
			pd->reply_id = REPLY_NAK;
			pd->cmd_data[0] = OSDP_PD_NAK_SC_COND;
			return OSDP_ERR_PKT_FMT;
		}
	}

	if (ISSET_FLAG(pd, PD_FLAG_SC_ACTIVE) &&
	    pkt->control & PKT_CONTROL_SCB &&
	    pkt->data[1] >= SCS_15) {
		/* validate MAC */
		is_cmd = ISSET_FLAG(pd, PD_FLAG_PD_MODE);
		osdp_compute_mac(pd, is_cmd, buf + 1, mac_offset);
		mac = is_cmd ? pd->sc.c_mac : pd->sc.r_mac;
		if (memcmp(buf + 1 + mac_offset, mac, 4) != 0) {
			LOG_ERR(TAG "invalid MAC");
			pd->reply_id = REPLY_NAK;
			pd->cmd_data[0] = OSDP_PD_NAK_SC_COND;
			return OSDP_ERR_PKT_FMT;
		}
		len -= 4; /* consume MAC */

		/* decrypt data block */
		if (pkt->data[1] == SCS_17 || pkt->data[1] == SCS_18) {
			/**
			 * Only the data portion of message (after id byte)
			 * is encrypted. While (en/de)crypting, we must skip
			 * header (6), security block (2) and cmd/reply id (1)
			 * bytes if cmd/reply has no data, use SCS_15/SCS_16.
			 *
			 * At this point, the header and security block is
			 * already consumed. So we can just skip the cmd/reply
			 * ID (data[0])  when calling osdp_decrypt_data().
			 */
			len = osdp_decrypt_data(pd, is_cmd, data + 1, len - 1);
			if (len <= 0) {
				LOG_ERR(TAG "failed at decrypt");
				pd->reply_id = REPLY_NAK;
				pd->cmd_data[0] = OSDP_PD_NAK_SC_COND;
				return OSDP_ERR_PKT_FMT;
			}
			len += 1; /* put back cmd/reply ID */
		}
	}
#endif /* CONFIG_OSDP_SC_ENABLED */

	memmove(buf, data, len);
	return len;
}

void osdp_phy_state_reset(struct osdp_pd *pd)
{
#ifdef CONFIG_OSDP_MODE_CP
	pd->phy_state = 0;
#endif
	pd->seq_number = -1;
	pd->rx_buf_len = 0;
}
