From 9041e5903c3b7a1c998b78dfa58ea9d09d137761 Mon Sep 17 00:00:00 2001 From: Conor Patrick Date: Fri, 30 Aug 2019 14:34:57 +0800 Subject: [PATCH] return SW_WRONG_LENGTH for incorrect lc --- fido2/apdu.c | 18 ++++++++++++++++-- fido2/apdu.h | 2 +- targets/stm32l432/src/nfc.c | 5 +++-- 3 files changed, 20 insertions(+), 5 deletions(-) diff --git a/fido2/apdu.c b/fido2/apdu.c index 3d5bf49..ef24a25 100644 --- a/fido2/apdu.c +++ b/fido2/apdu.c @@ -9,7 +9,7 @@ #include "apdu.h" -int apdu_decode(uint8_t *data, size_t len, APDU_STRUCT *apdu) +uint16_t apdu_decode(uint8_t *data, size_t len, APDU_STRUCT *apdu) { EXT_APDU_HEADER *hapdu = (EXT_APDU_HEADER *)data; @@ -62,6 +62,11 @@ int apdu_decode(uint8_t *data, size_t len, APDU_STRUCT *apdu) if (len >= 7 && b0 == 0) { uint16_t extlen = (hapdu->lc[1] << 8) + hapdu->lc[2]; + + if (len - 7 < extlen) + { + return SW_WRONG_LENGTH; + } // case 2E (Le) - extended if (len == 7) @@ -103,9 +108,18 @@ int apdu_decode(uint8_t *data, size_t len, APDU_STRUCT *apdu) apdu->le = 0x10000; } } + else + { + if ((len > 5) && (len - 5 < hapdu->lc[0])) + { + return SW_WRONG_LENGTH; + } + } if (!apdu->case_type) - return 1; + { + return SW_COND_USE_NOT_SATISFIED; + } if (apdu->lc) { diff --git a/fido2/apdu.h b/fido2/apdu.h index 420fea6..d361c94 100644 --- a/fido2/apdu.h +++ b/fido2/apdu.h @@ -36,7 +36,7 @@ typedef struct uint8_t case_type; } __attribute__((packed)) APDU_STRUCT; -extern int apdu_decode(uint8_t *data, size_t len, APDU_STRUCT *apdu); +extern uint16_t apdu_decode(uint8_t *data, size_t len, APDU_STRUCT *apdu); #define APDU_FIDO_U2F_REGISTER 0x01 #define APDU_FIDO_U2F_AUTHENTICATE 0x02 diff --git a/targets/stm32l432/src/nfc.c b/targets/stm32l432/src/nfc.c index 6a3cab3..3a513e9 100644 --- a/targets/stm32l432/src/nfc.c +++ b/targets/stm32l432/src/nfc.c @@ -784,9 +784,10 @@ void nfc_process_iblock(uint8_t * buf, int len) } APDU_STRUCT apdu; - if (apdu_decode(buf + block_offset, len - block_offset, &apdu)) { + uint16_t ret = apdu_decode(buf + block_offset, len - block_offset, &apdu); + if (ret != 0) { printf1(TAG_NFC,"apdu decode error\r\n"); - nfc_write_response(buf[0], SW_COND_USE_NOT_SATISFIED); + nfc_write_response(buf[0], ret); return; } printf1(TAG_NFC,"apdu ok. %scase=%02x cla=%02x ins=%02x p1=%02x p2=%02x lc=%d le=%d\r\n",