APDU parsing support for GlobalPlatform

This patch addes support for GlobalPlatform command. Android is using
STORE DATA commands on a logical channel.
simtrace2-cardem-pcsc is failing otherwise e.g. on an Pixel 4 with Android 12.

Change-Id: Ib734fc852e7b63b9efdc414adccbd796a572eb55
diff --git a/src/sim/class_tables.c b/src/sim/class_tables.c
index 534ef53..34f22dd 100644
--- a/src/sim/class_tables.c
+++ b/src/sim/class_tables.c
@@ -173,6 +173,24 @@
 	return 0;
 }
 
+static int gp_cla_ins_helper(const struct osim_cla_ins_case *cic,
+				  const uint8_t *hdr)
+{
+	uint8_t ins = hdr[1];
+	uint8_t p1 = hdr[2];
+
+	switch (ins) {
+	case 0xE2:	/* STORE DATA */
+		switch (p1 & 0x01) {
+		case 1:
+			return 4;
+		default:
+			return 3;
+		}
+	}
+	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 */
@@ -190,6 +208,19 @@
 	[0x14]		= 3,	/* TERMINAL RESPONSE */
 };
 
+/* Card Specification v2.3.1*/
+static const uint8_t gp_ins_tbl_8ce[256] = {
+	[0xE4]		= 4,	/* DELETE */
+	[0xE2]		= 0x80,	/* STORE DATA */
+	[0xCA]		= 4,	/* GET DATA */
+	[0xCB]		= 4,	/* GET DATA */
+	[0xF2]		= 4,	/* GET STATUS */
+	[0xE6]		= 4,	/* INSTALL */
+	[0xE8]		= 4,	/* LOAD */
+	[0xD8]		= 4,	/* PUT KEY */
+	[0xF0]		= 3,	/* SET STATUS */
+};
+
 static const struct osim_cla_ins_case uicc_ins_case[] = {
 	{
 		.cla		= 0x80,
@@ -222,6 +253,21 @@
 		.cla		= 0xE0,
 		.cla_mask	= 0xF0,
 		.ins_tbl	= uicc_ins_tbl_8ce,
+	}, {
+		.cla		= 0x80,
+		.cla_mask	= 0xF0,
+		.helper		= gp_cla_ins_helper,
+		.ins_tbl	= gp_ins_tbl_8ce,
+	}, {
+		.cla		= 0xC0,
+		.cla_mask	= 0xF0,
+		.helper		= gp_cla_ins_helper,
+		.ins_tbl	= gp_ins_tbl_8ce,
+	}, {
+		.cla		= 0xE0,
+		.cla_mask	= 0xF0,
+		.helper		= gp_cla_ins_helper,
+		.ins_tbl	= gp_ins_tbl_8ce,
 	},
 };
 
@@ -269,7 +315,23 @@
 		.cla		= 0xE0,
 		.cla_mask	= 0xF0,
 		.ins_tbl	= uicc_ins_tbl_8ce,
+	}, {
+		.cla		= 0x80,
+		.cla_mask	= 0xF0,
+		.helper		= gp_cla_ins_helper,
+		.ins_tbl	= gp_ins_tbl_8ce,
+	}, {
+		.cla		= 0xC0,
+		.cla_mask	= 0xF0,
+		.helper		= gp_cla_ins_helper,
+		.ins_tbl	= gp_ins_tbl_8ce,
+	}, {
+		.cla		= 0xE0,
+		.cla_mask	= 0xF0,
+		.helper		= gp_cla_ins_helper,
+		.ins_tbl	= gp_ins_tbl_8ce,
 	},
+
 };
 
 const struct osim_cla_ins_card_profile osim_uicc_sim_cic_profile = {
@@ -301,7 +363,7 @@
 		case 0x80:
 			return cic->helper(cic, hdr);
 		case 0x00:
-			/* continue with fruther cic, rather than abort
+			/* continue with further cic, rather than abort
 			 * now */
 			continue;
 		default: