/*
 *
 *  seeld - Secure Element Manager
 *
 *  Copyright (C) 2013  Intel Corporation. All rights reserved.
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License version 2 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.
 *
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <errno.h>

#include "seel.h"

struct iso7816_apdu {
	uint8_t class;
	uint8_t instruction;
	uint8_t param1;
	uint8_t param2;
	uint8_t body[];
} __attribute__((packed));

struct iso7816_apdu_resp {
	uint8_t sw1;
	uint8_t sw2;
} __attribute__((packed));

struct seel_apdu {
	struct iso7816_apdu *apdu;
	size_t length;
} __attribute__((packed));

#define MAX_AID_LENGTH 16
#define MIN_AID_LENGTH 5

#define CLA_CHANNEL_STANDARD 0x0
#define CLA_CHANNEL_EXTENDED 0x1
#define CLA_PROPRIETARY_CMD  0x80
#define CLA_PPS_CMD          0xF0

#define INS_MANAGE_CHANNEL 0x70
#define INS_SELECT_FILE    0xA4
#define INS_GET_GP_DATA    0xCA

#define P1_SELECT_FILE_DF_NAME 0x4

#define APDU_RESP_TRAILER_LENGTH 0x2 /* SW1, SW2 */

#define CLA_CHANNEL_MASK 0xFF

static struct seel_apdu *alloc_apdu(uint8_t class, uint8_t channel,
				uint8_t instruction,
				uint8_t param1, uint8_t param2,
				uint8_t data_length, uint8_t *data,
				int resp_length)
{
	struct seel_apdu *apdu;
	struct iso7816_apdu *iso_apdu;
	size_t iso_apdu_length;
	uint32_t body_ptr;

	if (channel > 3)
		return NULL;

	apdu = g_try_malloc(sizeof(struct seel_apdu));
	if (apdu == NULL)
		return apdu;

	iso_apdu_length = sizeof(struct iso7816_apdu);
	if (data_length > 0)
		iso_apdu_length += 1 + data_length;

	if (resp_length >= 0)
		iso_apdu_length += 1;

	apdu->apdu = g_try_malloc(iso_apdu_length);
	if (apdu->apdu == NULL) {
		g_free(apdu);
		return NULL;
	}

	iso_apdu = apdu->apdu;
	iso_apdu->class = class | channel;
	iso_apdu->instruction = instruction;
	iso_apdu->param1 = param1;
	iso_apdu->param2 = param2;

	body_ptr = 0;
	if (data_length > 0) {
		iso_apdu->body[0] = data_length;
		memcpy(&iso_apdu->body[1], data, data_length);
		body_ptr += data_length + 1;
	}

	if (resp_length >= 0)
		iso_apdu->body[body_ptr] = resp_length;

	apdu->length = iso_apdu_length;

	return apdu;
}

struct seel_apdu *__seel_apdu_build(uint8_t *apdu, size_t length, uint8_t channel)
{
	struct seel_apdu *_apdu;
	struct iso7816_apdu *iso_apdu;

	_apdu = g_try_malloc(sizeof(struct seel_apdu));
	if (!_apdu)
		return NULL;

	_apdu->apdu = g_try_malloc(length);
	if (_apdu->apdu == NULL) {
		g_free(_apdu);
		return NULL;
	}

	if (channel > 3) {
		DBG("Invalid channel number %d", channel);
		channel = 0;
	}

	iso_apdu = (struct iso7816_apdu *) apdu;
	/* We add the channel iff CLA is not PPS */
	if ((iso_apdu->class & CLA_PPS_CMD) != CLA_PPS_CMD)
		iso_apdu->class |= channel;

	_apdu->length = length;
	memcpy(_apdu->apdu, apdu, length);

	return _apdu;
}

void __seel_apdu_dump(uint8_t *apdu, size_t length)
{
	size_t i;
	char *str;

	str = g_try_malloc0((3 * length) + 1);
	if (str == NULL)
		return;

	for (i = 0; i < length; i++)
		sprintf(str + (3 * i), "%02X ", apdu[i]);
	str[3 * length] = 0;

	DBG("[%zd] %s", length, str);

	g_free(str);
}

void __seel_apdu_free(struct seel_apdu *apdu)
{
	g_free(apdu->apdu);
	g_free(apdu);
}

size_t __seel_apdu_length(struct seel_apdu *apdu)
{
	return apdu->length;
}

uint8_t *__seel_apdu_data(struct seel_apdu *apdu)
{
	return (uint8_t *) apdu->apdu;
}

struct seel_apdu *__seel_apdu_open_logical_channel(void)
{
	return alloc_apdu(CLA_CHANNEL_STANDARD, 0, INS_MANAGE_CHANNEL, 0, 0,
								0, NULL, 1);
}

struct seel_apdu *__seel_apdu_close_logical_channel(uint8_t channel)
{
	DBG("%d", channel);

	return alloc_apdu(CLA_CHANNEL_STANDARD, 0, INS_MANAGE_CHANNEL, 0x80,
							channel, 0, NULL, -1);
}

struct seel_apdu *__seel_apdu_select_aid(uint8_t channel,
						uint8_t *aid, size_t aid_length)
{
	DBG("%zd", aid_length);

	if (aid_length < MIN_AID_LENGTH ||
			aid_length > MAX_AID_LENGTH)
		return NULL;

	return alloc_apdu(CLA_CHANNEL_STANDARD, channel, INS_SELECT_FILE,
					P1_SELECT_FILE_DF_NAME, 0,
					aid_length, aid, -1);
}

struct seel_apdu *__seel_apdu_get_all_gp_data(void)
{
	DBG("");

	return alloc_apdu(CLA_PROPRIETARY_CMD, 0, INS_GET_GP_DATA,
						0xFF, 0x40, 0, NULL, 0);
}

struct seel_apdu *__seel_apdu_get_next_gp_data(size_t length)
{
	DBG("");

	return alloc_apdu(CLA_PROPRIETARY_CMD, 0, INS_GET_GP_DATA,
						0xFF, 0x60, 0, NULL, length);
}

struct seel_apdu *__seel_apdu_get_refresh_gp_data(void)
{
	DBG("");

	return alloc_apdu(CLA_PROPRIETARY_CMD, 0, INS_GET_GP_DATA,
						0xDF, 0x20, 0, NULL, 0xB);
}

static int apdu_trailer_status(struct iso7816_apdu_resp *trailer)
{
	DBG("SW1 0x%x SW2 0x%x", trailer->sw1, trailer->sw2);

	switch (trailer->sw1) {
	case 0x90:
		if (trailer->sw2 == 0)
			return 0;
	default:
		return -EIO;
	}
}

int __seel_apdu_resp_status(uint8_t *apdu, size_t apdu_length)
{
	struct iso7816_apdu_resp *resp;

	if (apdu_length < APDU_RESP_TRAILER_LENGTH)
		return -EINVAL;

	__seel_apdu_dump(apdu, apdu_length);

	resp = (struct iso7816_apdu_resp *)(apdu + apdu_length - APDU_RESP_TRAILER_LENGTH);

	return apdu_trailer_status(resp);
}
