aboutsummaryrefslogtreecommitdiffstats
path: root/net/nfc/digital_dep.c
diff options
context:
space:
mode:
authorMark A. Greer <mgreer@animalcreek.com>2014-09-23 19:38:07 -0400
committerSamuel Ortiz <sameo@linux.intel.com>2014-11-28 06:38:47 -0500
commit485fdc9bb6f81d68aa30b399b9bc33cf27d65ba4 (patch)
tree0c57a081a707ef1768dab3fe9094707e263cd32f /net/nfc/digital_dep.c
parent3e6b0de8053ae724931799f1b5d4f009b9fc4b44 (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.c36
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)