/*! \file class_tables.c
 * simtrace - tables determining APDU case for card emulation. */
/*
 * (C) 2016 by Harald Welte <laforge@gnumonks.org>
 *
 * SPDX-License-Identifier: GPL-2.0+
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License version 2, or
 *  any later version 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.
 */

#include <stdint.h>
#include <osmocom/core/utils.h>
#include <osmocom/sim/class_tables.h>

static const uint8_t iso7816_ins_tbl[] = {
	[0xB0]	= 2,	/* READ BIN */
	[0xD0]	= 3,	/* WRITE BIN */
	[0xD6]	= 3,	/* UPDATE BIN */
	[0x0E]	= 3,	/* ERASE BIN */
	[0xB2]	= 2,	/* READ REC */
	[0xD2]	= 3,	/* WRITE REC */
	[0xE2]	= 3,	/* APPEND REC */
	[0xDC]	= 3,	/* UPDATE REC */
	[0xCA]	= 2,	/* GET DATA */
	[0xDA]	= 3,	/* PUT DATA */
	[0xA4]	= 4,	/* SELECT FILE */
	[0x20]	= 3,	/* VERIFY */
	[0x88]	= 4,	/* INT AUTH */
	[0x82]	= 3,	/* EXT AUTH */
	[0x84]	= 2,	/* GET CHALLENGE */
	[0x70]	= 2,	/* MANAGE CHANNEL */
};

static const struct osim_cla_ins_case iso7816_4_ins_case[] = {
	{
		.cla		= 0x00,
		.cla_mask	= 0xF0,
		.ins_tbl	= iso7816_ins_tbl,
	}, {
		.cla		= 0x80,	/* 0x80/0x90 */
		.cla_mask	= 0xE0,
		.ins_tbl	= iso7816_ins_tbl,
	}, {
		.cla		= 0xB0,
		.cla_mask	= 0xF0,
		.ins_tbl	= iso7816_ins_tbl,
	}, {
		.cla		= 0xC0,
		.cla_mask	= 0xF0,
		.ins_tbl	= iso7816_ins_tbl,
	},
};

const struct osim_cla_ins_card_profile osim_iso7816_cic_profile = {
	.name		= "ISO 7816-4",
	.description	= "ISO 7816-4",
	.cic_arr	= iso7816_4_ins_case,
	.cic_arr_size	= ARRAY_SIZE(iso7816_4_ins_case),
};

static const uint8_t gsm1111_ins_tbl[256] = {
	[0xA4]	= 4,	/* SELECT FILE */
	[0xF2]	= 2,	/* STATUS */
	[0xB0]	= 2,	/* READ BINARY */
	[0xD6]	= 3,	/* UPDATE BINARY */
	[0xB2]	= 2,	/* READ RECORD */
	[0xDC]	= 3,	/* UPDATE RECORD */
	[0xA2]	= 4,	/* SEEK */
	[0x32]	= 4,	/* INCREASE */
	[0x20]	= 3,	/* VERIFY CHV */
	[0x24]	= 3,	/* CHANGE CHV */
	[0x26]	= 3,	/* DISABLE CHV */
	[0x28]	= 3,	/* ENABLE CHV */
	[0x2C]	= 3,	/* UNBLOCK CHV */
	[0x04]	= 1,	/* INVALIDATE */
	[0x44]	= 1,	/* REHABILITATE */
	[0x88]	= 4,	/* RUN GSM ALGO */
	[0xFA]	= 1,	/* SLEEP */
	[0xC0]	= 2,	/* GET RESPONSE */
	[0x10]	= 3,	/* TERMINAL PROFILE */
	[0xC2]	= 4,	/* ENVELOPE */
	[0x12]	= 2,	/* FETCH */
	[0x14]	= 3,	/* TERMINAL RESPONSE */
};

/* According to Table 9 / Section 9.2 of TS 11.11 */
static const struct osim_cla_ins_case gsm1111_ins_case[] = {
	{
		.cla		= 0xA0,
		.cla_mask	= 0xFF,
		.ins_tbl	= gsm1111_ins_tbl,
	},
};

const struct osim_cla_ins_card_profile osim_gsm1111_cic_profile = {
	.name		= "GSM SIM",
	.description	= "GSM/3GPP TS 11.11",
	.cic_arr	= gsm1111_ins_case,
	.cic_arr_size	= ARRAY_SIZE(gsm1111_ins_case),
};

/* ETSI TS 102 221, Table 10.5, CLA = 0x0x, 0x4x or 0x6x */
static const uint8_t uicc_ins_tbl_046[256] = {
	[0xA4]	= 4,	/* SELECT FILE */
	[0xB0]	= 2,	/* READ BINARY */
	[0xD6]	= 3,	/* UPDATE BINARY */
	[0xB2]	= 2,	/* READ RECORD */
	[0xDC]	= 3,	/* UPDATE RECORD */
	[0xA2]	= 4,	/* SEEK */
	[0x20]	= 3,	/* VERIFY PIN */
	[0x24]	= 3,	/* CHANGE PIN */
	[0x26]	= 3,	/* DISABLE PIN */
	[0x28]	= 3,	/* ENABLE PIN */
	[0x2C]	= 3,	/* UNBLOCK PIN */
	[0x04]	= 1,	/* DEACTIVATE FILE */
	[0x44]	= 1,	/* ACTIVATE FILE */
	[0x88]	= 4,	/* AUTHENTICATE */
	[0x89]	= 4,	/* AUTHENTICATE */
	[0x84]	= 2,	/* GET CHALLENGE */
	[0x70]	= 2,	/* MANAGE CHANNEL */
	[0x73]	= 0x80,	/* MANAGE SECURE CHANNEL */
	[0x75]	= 0x80,	/* TRANSACT DATA */
	[0xC0]	= 2,	/* GET RESPONSE */
};

static int uicc046_cla_ins_helper(const struct osim_cla_ins_case *cic,
				  const uint8_t *hdr)
{
	uint8_t ins = hdr[1];
	uint8_t p1 = hdr[2];
	uint8_t p2 = hdr[3];
	uint8_t p2_cmd;

	switch (ins) {
	case 0x73:	/* MANAGE SECURE CHANNEL */
		if (p1 == 0x00)		/* Retrieve UICC Endpoints */
			return 2;
		switch (p1 & 0x07) {
		case 1:	/* Establish SA - Master SA */
		case 2:	/* Establish SA - Conn. SA */
		case 3:	/* Start secure channel SA */
			p2_cmd = p2 >> 5;
			if (p2 == 0x80 || p2_cmd == 0) {
				/* command data */
				return 3;
			}
			if (p2_cmd == 5 || p2_cmd == 1) {
				/* response data */
				return 2;
			}
			return 0;
			break;
		case 4:	/* Terminate secure chan SA */
			return 3;
			break;
		}
		break;
	case 0x75:	/* TRANSACT DATA */
		if (p1 & 0x04)
			return 3;
		else
			return 2;
		break;
	}

	return 0;
}

/* ETSI TS 102 221, Table 10.5, CLA = 0x8x, 0xCx or 0xEx */
static const uint8_t uicc_ins_tbl_8ce[256] = {
	[0xF2]		= 2,	/* STATUS */
	[0x32]		= 4,	/* INCREASE */
	[0xCB]		= 4,	/* RETRIEVE DATA */
	[0xDB]		= 3,	/* SET DATA */
	[0xAA]		= 3,	/* TERMINAL CAPABILITY */
};

/* ETSI TS 102 221, Table 10.5, CLA = 0x80 */
static const uint8_t uicc_ins_tbl_80[256] = {
	[0x10]		= 3,	/* TERMINAL PROFILE */
	[0xC2]		= 4,	/* ENVELOPE */
	[0x12]		= 2,	/* FETCH */
	[0x14]		= 3,	/* TERMINAL RESPONSE */
};

static const struct osim_cla_ins_case uicc_ins_case[] = {
	{
		.cla		= 0x80,
		.cla_mask	= 0xFF,
		.ins_tbl	= uicc_ins_tbl_80,
	}, {
		.cla		= 0x00,
		.cla_mask	= 0xF0,
		.helper		= uicc046_cla_ins_helper,
		.ins_tbl	= uicc_ins_tbl_046,
	}, {
		.cla		= 0x40,
		.cla_mask	= 0xF0,
		.helper		= uicc046_cla_ins_helper,
		.ins_tbl	= uicc_ins_tbl_046,
	}, {
		.cla		= 0x60,
		.cla_mask	= 0xF0,
		.helper		= uicc046_cla_ins_helper,
		.ins_tbl	= uicc_ins_tbl_046,
	}, {
		.cla		= 0x80,
		.cla_mask	= 0xF0,
		.ins_tbl	= uicc_ins_tbl_8ce,
	}, {
		.cla		= 0xC0,
		.cla_mask	= 0xF0,
		.ins_tbl	= uicc_ins_tbl_8ce,
	}, {
		.cla		= 0xE0,
		.cla_mask	= 0xF0,
		.ins_tbl	= uicc_ins_tbl_8ce,
	},
};

const struct osim_cla_ins_card_profile osim_uicc_cic_profile = {
	.name		= "UICC",
	.description	= "TS 102 221 / 3GPP TS 31.102",
	.cic_arr	= uicc_ins_case,
	.cic_arr_size	= ARRAY_SIZE(uicc_ins_case),
};


static const struct osim_cla_ins_case uicc_sim_ins_case[] = {
	{
		.cla		= 0xA0,
		.cla_mask	= 0xFF,
		.ins_tbl	= gsm1111_ins_tbl,
	}, {
		.cla		= 0x80,
		.cla_mask	= 0xFF,
		.ins_tbl	= uicc_ins_tbl_80,
	}, {
		.cla		= 0x00,
		.cla_mask	= 0xF0,
		.helper		= uicc046_cla_ins_helper,
		.ins_tbl	= uicc_ins_tbl_046,
	}, {
		.cla		= 0x40,
		.cla_mask	= 0xF0,
		.helper		= uicc046_cla_ins_helper,
		.ins_tbl	= uicc_ins_tbl_046,
	}, {
		.cla		= 0x60,
		.cla_mask	= 0xF0,
		.helper		= uicc046_cla_ins_helper,
		.ins_tbl	= uicc_ins_tbl_046,
	}, {
		.cla		= 0x80,
		.cla_mask	= 0xF0,
		.ins_tbl	= uicc_ins_tbl_8ce,
	}, {
		.cla		= 0xC0,
		.cla_mask	= 0xF0,
		.ins_tbl	= uicc_ins_tbl_8ce,
	}, {
		.cla		= 0xE0,
		.cla_mask	= 0xF0,
		.ins_tbl	= uicc_ins_tbl_8ce,
	},
};

const struct osim_cla_ins_card_profile osim_uicc_sim_cic_profile = {
	.name		= "UICC+SIM",
	.description	= "TS 102 221 / 3GPP TS 31.102 + GSM TS 11.11",
	.cic_arr	= uicc_sim_ins_case,
	.cic_arr_size	= ARRAY_SIZE(uicc_sim_ins_case),
};

/* 3GPP TS 31.102 */
const uint8_t usim_ins_case[256] = {
	[0x88]		= 4,	/* AUTHENTICATE */
};

int osim_determine_apdu_case(const struct osim_cla_ins_card_profile *prof,
			     const uint8_t *hdr)
{
	uint8_t cla = hdr[0];
	uint8_t ins = hdr[1];
	int i;
	int rc;

	for (i = 0; i < prof->cic_arr_size; i++) {
		const struct osim_cla_ins_case *cic = &prof->cic_arr[i];
		if ((cla & cic->cla_mask) != cic->cla)
			continue;
		rc = cic->ins_tbl[ins];
		switch (rc) {
		case 0x80:
			return cic->helper(cic, hdr);
		case 0x00:
			/* continue with fruther cic, rather than abort
			 * now */
			continue;
		default:
			return rc;
		}
	}
	return 0;
}
