laforge has uploaded this change for review.

View Change

ccid: Handle the TPDU-length = 4 case according to CCID spec

While ISO7816-3 forbids any TPDU shorter from 5 bytes, the CCID spec
begs to differ and actually permits a host to send us 4-byte TPDUs of
Form 1, giving the responsibility of adding the P3=00h octet to the CCID
implementation.

Let's implement this accordingly. While at it, also reject TPDUs of
lengths 1, 2 and 3 bytes - just like zero-length TPDUs.

Change-Id: Ia27962bda526af3373b36d637e2b548aa01a3346
Closes: OS#6973
---
M ccid_common/ccid_device.c
1 file changed, 12 insertions(+), 3 deletions(-)

git pull ssh://gerrit.osmocom.org:29418/osmo-ccid-firmware refs/changes/17/42317/1
diff --git a/ccid_common/ccid_device.c b/ccid_common/ccid_device.c
index 8a53860..0ef85b6 100644
--- a/ccid_common/ccid_device.c
+++ b/ccid_common/ccid_device.c
@@ -457,17 +457,26 @@
/* Section 6.1.4 */
static int ccid_handle_xfr_block(struct ccid_slot *cs, struct msgb *msg)
{
- const union ccid_pc_to_rdr *u = msgb_ccid_out(msg);
+ union ccid_pc_to_rdr *u = msgb_ccid_out(msg);
const struct ccid_header *ch = (const struct ccid_header *) u;
struct msgb *resp;
int rc;

- if (u->xfr_block.hdr.dwLength == 0) {
+ /* TODO: The checks below assume TPDU-level exchange and T=0. When adding
+ * APDU-level or character level exchange or T=1 support, this needs adjustment */
+ if (u->xfr_block.hdr.dwLength < 4) {
/* CCID Rev 1.1 permits a zero-length XfrBlock on the protocol level, but what should we do
- * with a zero-length TPDU? We need to reject it as bError=1 (Bad dwLength) */
+ * with a zero-length or otherwise short TPDU? We need to reject it as bError=1 (Bad dwLength) */
resp = ccid_gen_data_block(cs, u->xfr_block.hdr.bSeq, CCID_CMD_STATUS_FAILED, 1, 0, 0);
goto out;
+ } else if (u->xfr_block.hdr.dwLength == 4) {
+ /* CCID v1.1 Section 3.2.1:
+ * Command TPDU = CLA INS P1 P2, the CCID is responsible to add P3=00h */
+ msgb_put(msg, 1);
+ u->xfr_block.hdr.dwLength = 5;
+ u->xfr_block.abData[4] = 0x00;
}
+ /* from 5 bytes upwards, we can simply transceive it */

/* handle this asynchronously */
rc = cs->ci->slot_ops->xfr_block_async(cs, msg, &u->xfr_block);

To view, visit change 42317. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-MessageType: newchange
Gerrit-Project: osmo-ccid-firmware
Gerrit-Branch: master
Gerrit-Change-Id: Ia27962bda526af3373b36d637e2b548aa01a3346
Gerrit-Change-Number: 42317
Gerrit-PatchSet: 1
Gerrit-Owner: laforge <laforge@osmocom.org>