diff options
Diffstat (limited to 'src/sim/class_tables.c')
-rw-r--r-- | src/sim/class_tables.c | 94 |
1 files changed, 87 insertions, 7 deletions
diff --git a/src/sim/class_tables.c b/src/sim/class_tables.c index 6f541ee2..29c1e40e 100644 --- a/src/sim/class_tables.c +++ b/src/sim/class_tables.c @@ -13,17 +13,13 @@ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include <stdint.h> #include <osmocom/core/utils.h> #include <osmocom/sim/class_tables.h> -static const uint8_t iso7816_ins_tbl[] = { +static const uint8_t iso7816_ins_tbl[256] = { [0xB0] = 2, /* READ BIN */ [0xD0] = 3, /* WRITE BIN */ [0xD6] = 3, /* UPDATE BIN */ @@ -117,7 +113,7 @@ static const uint8_t uicc_ins_tbl_046[256] = { [0xD6] = 3, /* UPDATE BINARY */ [0xB2] = 2, /* READ RECORD */ [0xDC] = 3, /* UPDATE RECORD */ - [0xA2] = 4, /* SEEK */ + [0xA2] = 4, /* SEARCH RECORD */ [0x20] = 3, /* VERIFY PIN */ [0x24] = 3, /* CHANGE PIN */ [0x26] = 3, /* DISABLE PIN */ @@ -177,6 +173,24 @@ static int uicc046_cla_ins_helper(const struct osim_cla_ins_case *cic, 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 */ @@ -184,6 +198,7 @@ static const uint8_t uicc_ins_tbl_8ce[256] = { [0xCB] = 4, /* RETRIEVE DATA */ [0xDB] = 3, /* SET DATA */ [0xAA] = 3, /* TERMINAL CAPABILITY */ + [0x78] = 4, /* GET IDENTITY */ }; /* ETSI TS 102 221, Table 10.5, CLA = 0x80 */ @@ -192,6 +207,22 @@ static const uint8_t uicc_ins_tbl_80[256] = { [0xC2] = 4, /* ENVELOPE */ [0x12] = 2, /* FETCH */ [0x14] = 3, /* TERMINAL RESPONSE */ + [0x76] = 4, /* SUSPEND UICC */ + [0x7A] = 4, /* EXCHANGE CAPABILITIES */ +}; + +/* 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 */ + [0xC0] = 2, /* GET RESPONSE */ }; static const struct osim_cla_ins_case uicc_ins_case[] = { @@ -226,6 +257,21 @@ static const struct osim_cla_ins_case uicc_ins_case[] = { .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, }, }; @@ -273,7 +319,23 @@ static const struct osim_cla_ins_case uicc_sim_ins_case[] = { .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 = { @@ -288,6 +350,13 @@ const uint8_t usim_ins_case[256] = { [0x88] = 4, /* AUTHENTICATE */ }; +/* https://learn.microsoft.com/en-us/windows-hardware/drivers/smartcard/discovery-process */ +static const uint8_t microsoft_discovery_ins_tbl[256] = { + [0xA4] = 4, /* SELECT FILE */ + [0xCA] = 2, /* GET DATA */ + [0xC0] = 2, /* GET RESPONSE */ +}; + int osim_determine_apdu_case(const struct osim_cla_ins_card_profile *prof, const uint8_t *hdr) { @@ -305,12 +374,23 @@ int osim_determine_apdu_case(const struct osim_cla_ins_card_profile *prof, 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: return rc; } } + /* special handling for Microsoft who insists to use INS=0xCA in CLA=0x00 which is not + * really part of GSM SIM, ETSI UICC or 3GPP USIM specifications, but only ISO7816. Rather than adding + * it to each and every card profile, let's add the instructions listed at + * https://learn.microsoft.com/en-us/windows-hardware/drivers/smartcard/discovery-process explicitly + * here. They will only be used in case no more specific match was found in the actual profile above. */ + if (cla == 0x00) { + rc = microsoft_discovery_ins_tbl[ins]; + if (rc) + return rc; + } + return 0; } |