laforge has submitted this change. ( https://gerrit.osmocom.org/c/libosmocore/+/37118?usp=email )
Change subject: libosmosim: class_tables: Resolve conflicting CLA=8x INS=F2 definitions ......................................................................
libosmosim: class_tables: Resolve conflicting CLA=8x INS=F2 definitions
In their infinite wisdom, GlobalPlatform re-defined the CLA 8x / INS F2 command alreay specified by ETSI TS 102 221. This wouldn't be as bads if they had the same "Case". However, ETSI has case 2 while GP has case 4.
Lucikly, the P1 coding of ETSI [so far] states all the four upper bits must be 0, while GP always has one of those bits set.
Before this patch, it is possible that a Modem/Phone will send an 8xF2 command and intends it as a GlobalPlatform command (with Lc > 0 and command data portion), while this code assumes it is an ETSI UICC command with Lc=0 and hence no command data portion. This will make communication break when using simtrace2 'cardem'.
Change-Id: I8dd317ef8f942542e412b18c834a0467c51291c3 Related: SYS#6865 Related: https://lists.osmocom.org/hyperkitty/list/simtrace@lists.osmocom.org/thread/... --- M src/sim/class_tables.c M tests/sim/sim_test.c M tests/sim/sim_test.ok 3 files changed, 53 insertions(+), 6 deletions(-)
Approvals: Jenkins Builder: Verified laforge: Looks good to me, approved
diff --git a/src/sim/class_tables.c b/src/sim/class_tables.c index 9c51387..1cda9a8 100644 --- a/src/sim/class_tables.c +++ b/src/sim/class_tables.c @@ -187,6 +187,16 @@ default: return 3; } + break; + case 0xF2: + /* in their infinite wisdom, GlobalPlatform re-defined the CLA 8x / INS F2 command, so one can + * take a guess if it's GlobalPlatform or ETSI. Lucikly, the P1 coding of ETSI [so far] + * states all the four upper bits must be 0, while GP always has one of those bits set */ + if (p1 & 0xF0) + return 4; /* GlobalPlatform v2.2 11.4.2 */ + else + return 2; /* ETSI TS 102 221 V16.2.0 11.1.2 */ + break; } return 0; } @@ -217,7 +227,7 @@ [0xE2] = 0x80, /* STORE DATA */ [0xCA] = 4, /* GET DATA */ [0xCB] = 4, /* GET DATA */ - [0xF2] = 4, /* GET STATUS */ + [0xF2] = 0x80, /* GET STATUS */ [0xE6] = 4, /* INSTALL */ [0xE8] = 4, /* LOAD */ [0xD8] = 4, /* PUT KEY */ @@ -245,6 +255,12 @@ .helper = uicc046_cla_ins_helper, .ins_tbl = uicc_ins_tbl_046, }, { + /* must be before uicc_ins_tbl_8ce below with same CLA+mask */ + .cla = 0x80, + .cla_mask = 0xF0, + .helper = gp_cla_ins_helper, + .ins_tbl = gp_ins_tbl_8ce, + }, { .cla = 0x80, .cla_mask = 0xF0, .ins_tbl = uicc_ins_tbl_8ce, @@ -257,11 +273,6 @@ .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, @@ -307,6 +318,12 @@ .helper = uicc046_cla_ins_helper, .ins_tbl = uicc_ins_tbl_046, }, { + /* must be before uicc_ins_tbl_8ce below with same CLA+mask */ + .cla = 0x80, + .cla_mask = 0xF0, + .helper = gp_cla_ins_helper, + .ins_tbl = gp_ins_tbl_8ce, + }, { .cla = 0x80, .cla_mask = 0xF0, .ins_tbl = uicc_ins_tbl_8ce, diff --git a/tests/sim/sim_test.c b/tests/sim/sim_test.c index 2e2eec5..9a52af4 100644 --- a/tests/sim/sim_test.c +++ b/tests/sim/sim_test.c @@ -27,6 +27,8 @@ const uint8_t uicc_tprof_wrong_class[] = { 0x00, 0x10, 0x00, 0x00, 0x02, 0x01, 0x02 }; const uint8_t uicc_read[] = { 0x00, 0xB0, 0x00, 0x00, 0x10 }; const uint8_t uicc_upd[] = { 0x00, 0xD6, 0x00, 0x00, 0x02, 0x01, 0x02 }; +const uint8_t uicc_get_status[] = { 0x80, 0xf2, 0x00, 0x02, 0x10 }; +const uint8_t euicc_m2m_get_status[] = { 0x81, 0xf2, 0x40, 0x02, 0x02, 0x4f, 0x00 };
#define APDU_CASE_ASSERT(x, y) \ do { \ @@ -45,6 +47,8 @@ APDU_CASE_ASSERT(uicc_tprof_wrong_class, 0); APDU_CASE_ASSERT(uicc_read, 2); APDU_CASE_ASSERT(uicc_upd, 3); + APDU_CASE_ASSERT(uicc_get_status, 2); + APDU_CASE_ASSERT(euicc_m2m_get_status, 4); }
int main(int argc, char **argv) diff --git a/tests/sim/sim_test.ok b/tests/sim/sim_test.ok index 7d3f986..cac59ba 100644 --- a/tests/sim/sim_test.ok +++ b/tests/sim/sim_test.ok @@ -4,3 +4,5 @@ Testing uicc_tprof_wrong_class Testing uicc_read Testing uicc_upd +Testing uicc_get_status +Testing euicc_m2m_get_status