diff options
author | Mark A. Greer <mgreer@animalcreek.com> | 2014-09-23 19:38:07 -0400 |
---|---|---|
committer | Samuel Ortiz <sameo@linux.intel.com> | 2014-11-28 06:38:47 -0500 |
commit | 485fdc9bb6f81d68aa30b399b9bc33cf27d65ba4 (patch) | |
tree | 0c57a081a707ef1768dab3fe9094707e263cd32f /net/nfc/digital_dep.c | |
parent | 3e6b0de8053ae724931799f1b5d4f009b9fc4b44 (diff) |
NFC: digital: Enforce NFC-DEP PNI sequencing
NFC-DEP DEP_REQ and DEP_RES exchanges using 'I'
and 'ACK/NACK' PDUs have a sequence number called
the Packet Number Information (PNI). The PNI
is incremented (modulo 4) after every DEP_REQ/
DEP_RES pair and should be verified by the digital
layer code. That verification isn't always done,
though, so add code to make sure that it is done.
Reviewed-by: Thierry Escande <thierry.escande@linux.intel.com>
Tested-by: Thierry Escande <thierry.escande@linux.intel.com>
Signed-off-by: Mark A. Greer <mgreer@animalcreek.com>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Diffstat (limited to 'net/nfc/digital_dep.c')
-rw-r--r-- | net/nfc/digital_dep.c | 36 |
1 files changed, 33 insertions, 3 deletions
diff --git a/net/nfc/digital_dep.c b/net/nfc/digital_dep.c index d5e669b0dedf..95a69898d5f5 100644 --- a/net/nfc/digital_dep.c +++ b/net/nfc/digital_dep.c | |||
@@ -447,8 +447,18 @@ static void digital_in_recv_dep_res(struct nfc_digital_dev *ddev, void *arg, | |||
447 | 447 | ||
448 | case DIGITAL_NFC_DEP_PFB_ACK_NACK_PDU: | 448 | case DIGITAL_NFC_DEP_PFB_ACK_NACK_PDU: |
449 | pr_err("Received a ACK/NACK PDU\n"); | 449 | pr_err("Received a ACK/NACK PDU\n"); |
450 | rc = -EIO; | 450 | |
451 | goto error; | 451 | if (DIGITAL_NFC_DEP_PFB_PNI(pfb) != ddev->curr_nfc_dep_pni) { |
452 | PROTOCOL_ERR("14.12.3.3"); | ||
453 | rc = -EIO; | ||
454 | goto exit; | ||
455 | } | ||
456 | |||
457 | ddev->curr_nfc_dep_pni = | ||
458 | DIGITAL_NFC_DEP_PFB_PNI(ddev->curr_nfc_dep_pni + 1); | ||
459 | |||
460 | rc = -EINVAL; | ||
461 | goto exit; | ||
452 | 462 | ||
453 | case DIGITAL_NFC_DEP_PFB_SUPERVISOR_PDU: | 463 | case DIGITAL_NFC_DEP_PFB_SUPERVISOR_PDU: |
454 | if (!DIGITAL_NFC_DEP_PFB_IS_TIMEOUT(pfb)) { | 464 | if (!DIGITAL_NFC_DEP_PFB_IS_TIMEOUT(pfb)) { |
@@ -592,9 +602,22 @@ static void digital_tg_recv_dep_req(struct nfc_digital_dev *ddev, void *arg, | |||
592 | switch (DIGITAL_NFC_DEP_PFB_TYPE(pfb)) { | 602 | switch (DIGITAL_NFC_DEP_PFB_TYPE(pfb)) { |
593 | case DIGITAL_NFC_DEP_PFB_I_PDU: | 603 | case DIGITAL_NFC_DEP_PFB_I_PDU: |
594 | pr_debug("DIGITAL_NFC_DEP_PFB_I_PDU\n"); | 604 | pr_debug("DIGITAL_NFC_DEP_PFB_I_PDU\n"); |
595 | ddev->curr_nfc_dep_pni = DIGITAL_NFC_DEP_PFB_PNI(pfb); | 605 | |
606 | if (DIGITAL_NFC_DEP_PFB_PNI(pfb) != ddev->curr_nfc_dep_pni) { | ||
607 | PROTOCOL_ERR("14.12.3.4"); | ||
608 | rc = -EIO; | ||
609 | goto exit; | ||
610 | } | ||
611 | |||
612 | rc = 0; | ||
596 | break; | 613 | break; |
597 | case DIGITAL_NFC_DEP_PFB_ACK_NACK_PDU: | 614 | case DIGITAL_NFC_DEP_PFB_ACK_NACK_PDU: |
615 | if (DIGITAL_NFC_DEP_PFB_PNI(pfb) != ddev->curr_nfc_dep_pni) { | ||
616 | PROTOCOL_ERR("14.12.3.4"); | ||
617 | rc = -EIO; | ||
618 | goto exit; | ||
619 | } | ||
620 | |||
598 | pr_err("Received a ACK/NACK PDU\n"); | 621 | pr_err("Received a ACK/NACK PDU\n"); |
599 | rc = -EINVAL; | 622 | rc = -EINVAL; |
600 | goto exit; | 623 | goto exit; |
@@ -629,6 +652,9 @@ int digital_tg_send_dep_res(struct nfc_digital_dev *ddev, struct sk_buff *skb) | |||
629 | sizeof(ddev->did)); | 652 | sizeof(ddev->did)); |
630 | } | 653 | } |
631 | 654 | ||
655 | ddev->curr_nfc_dep_pni = | ||
656 | DIGITAL_NFC_DEP_PFB_PNI(ddev->curr_nfc_dep_pni + 1); | ||
657 | |||
632 | digital_skb_push_dep_sod(ddev, skb); | 658 | digital_skb_push_dep_sod(ddev, skb); |
633 | 659 | ||
634 | ddev->skb_add_crc(skb); | 660 | ddev->skb_add_crc(skb); |
@@ -677,6 +703,8 @@ static int digital_tg_send_psl_res(struct nfc_digital_dev *ddev, u8 did, | |||
677 | 703 | ||
678 | ddev->skb_add_crc(skb); | 704 | ddev->skb_add_crc(skb); |
679 | 705 | ||
706 | ddev->curr_nfc_dep_pni = 0; | ||
707 | |||
680 | rc = digital_tg_send_cmd(ddev, skb, 0, digital_tg_send_psl_res_complete, | 708 | rc = digital_tg_send_cmd(ddev, skb, 0, digital_tg_send_psl_res_complete, |
681 | (void *)(unsigned long)rf_tech); | 709 | (void *)(unsigned long)rf_tech); |
682 | if (rc) | 710 | if (rc) |
@@ -800,6 +828,8 @@ static int digital_tg_send_atr_res(struct nfc_digital_dev *ddev, | |||
800 | 828 | ||
801 | ddev->skb_add_crc(skb); | 829 | ddev->skb_add_crc(skb); |
802 | 830 | ||
831 | ddev->curr_nfc_dep_pni = 0; | ||
832 | |||
803 | rc = digital_tg_send_cmd(ddev, skb, 999, | 833 | rc = digital_tg_send_cmd(ddev, skb, 999, |
804 | digital_tg_send_atr_res_complete, NULL); | 834 | digital_tg_send_atr_res_complete, NULL); |
805 | if (rc) | 835 | if (rc) |