Skip to content

Commit

Permalink
[core] Fixed APDU encoding cases 2E and 4E. JB#51044
Browse files Browse the repository at this point in the history
And covered all ISO 7816 cases by unit tests.
  • Loading branch information
monich committed Sep 1, 2020
1 parent 9c5cb5a commit 4feb59a
Show file tree
Hide file tree
Showing 3 changed files with 395 additions and 16 deletions.
32 changes: 18 additions & 14 deletions core/src/nfc_tag_t4.c
Expand Up @@ -120,7 +120,6 @@ static const GUtilData ndef_cc_ef_data = { ndef_cc_ef, sizeof(ndef_cc_ef) };
* Implementation
*==========================================================================*/

static
gboolean
nfc_tag_t4_build_apdu(
GByteArray* buf,
Expand All @@ -135,13 +134,13 @@ nfc_tag_t4_build_apdu(
/*
* Command APDU encoding options (ISO/IEC 7816-4):
*
* Case 1: |CLA|INS|P1|P2| n = 4
* Case 2s: |CLA|INS|P1|P2|LE | n = 5
* Case 3s: |CLA|INS|P1|P2|LC |...BODY...| n = 6..260
* Case 4s: |CLA|INS|P1|P2|LC |...BODY...|LE | n = 7..261
* Case 2e: |CLA|INS|P1|P2|00 |LE1|LE2| n = 7
* Case 3e: |CLA|INS|P1|P2|00 |LC1|LC2|...BODY...| n = 8..65542
* Case 4e: |CLA|INS|P1|P2|00 |LC1|LC2|...BODY...|LE1|LE2| n = 10..65544
* Case 1: |CLA|INS|P1|P2| n = 4
* Case 2s: |CLA|INS|P1|P2|LE| n = 5
* Case 3s: |CLA|INS|P1|P2|LC|...BODY...| n = 6..260
* Case 4s: |CLA|INS|P1|P2|LC|...BODY...|LE | n = 7..261
* Case 2e: |CLA|INS|P1|P2|00|LE1|LE2| n = 7
* Case 3e: |CLA|INS|P1|P2|00|LC1|LC2|...BODY...| n = 8..65542
* Case 4e: |CLA|INS|P1|P2|00|LC1|LC2|...BODY...|LE1|LE2| n = 10..65544
*
* LE, LE1, LE2 may be 0x00, 0x00|0x00 (means the maximum, 256 or 65536)
* LC must not be 0x00 and LC1|LC2 must not be 0x00|0x00
Expand All @@ -153,13 +152,13 @@ nfc_tag_t4_build_apdu(
buf->data[2] = p1;
buf->data[3] = p2;
if (len > 0) {
if (len < 0x100) {
/* Short Lc field */
if (len <= 0xff) {
/* Cases 3s and 4s */
guint8 lc = (guint8)len;

g_byte_array_append(buf, &lc, 1);
} else {
/* Extended Lc field */
/* Cases 3e and 4e */
guint8 lc[3];

lc[0] = 0;
Expand All @@ -170,13 +169,13 @@ nfc_tag_t4_build_apdu(
g_byte_array_append(buf, data, len);
}
if (exp > 0) {
if (exp <= 0x100) {
/* Short Le field */
if (exp <= 0x100 && len <= 0xff) {
/* Cases 2s and 4s */
guint8 le = (exp == 0x100) ? 0 : ((guint8)exp);

g_byte_array_append(buf, &le, 1);
} else {
/* Extended Le field */
/* Cases 4e and 2e */
guint8 le[2];

if (exp == 0x10000) {
Expand All @@ -185,6 +184,11 @@ nfc_tag_t4_build_apdu(
le[0] = (guint8)(exp >> 8);
le[1] = (guint8)exp;
}
if (!len) {
/* Case 2e */
g_byte_array_set_size(buf, 5);
buf->data[4] = 0;
}
g_byte_array_append(buf, le, sizeof(le));
}
}
Expand Down
13 changes: 13 additions & 0 deletions core/src/nfc_tag_t4_p.h
Expand Up @@ -64,6 +64,19 @@ nfc_tag_t4_init_base(
const NfcParamIsoDep* iso_dep)
NFCD_INTERNAL;

/* For unit tests */
gboolean
nfc_tag_t4_build_apdu(
GByteArray* buf,
guint8 cla, /* Class byte */
guint8 ins, /* Instruction byte */
guint8 p1, /* Parameter byte 1 */
guint8 p2, /* Parameter byte 2 */
guint len, /* Command data length */
const void* data, /* Command data */
guint exp) /* Expected length */
NFCD_INTERNAL;

#endif /* NFC_TAG_T4_PRIVATE_H */

/*
Expand Down

0 comments on commit 4feb59a

Please sign in to comment.