From 06c00385a43c233acc41ad8547e082654e2c4d7d Mon Sep 17 00:00:00 2001 From: michael Date: Thu, 11 Jun 2026 10:15:34 -0700 Subject: [PATCH] =?UTF-8?q?build(reader):=20WTX=20cap=20bump=2020=E2=86=92?= =?UTF-8?q?255=20+=20AUTH1=20wrap=20instrumentation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit rfal_isoDep.h: vendor RFAL_ISODEP_MAX_WTX_RETRYS is 20 by default. With slow userland AES-GCM on the J3R-family (J3R180/J3R452), AUTH1 takes ~3.2 s of card processing -- comfortably more than the negotiated FWT, so the card sends S(WTX) blocks to keep the link alive. At the card's FWI of 4, the spec-default 20 cap trips before AUTH1 finishes and RFAL aborts the transceive with ERR_PROTO 0xB. Bumping to the existing RFAL_ISODEP_MAX_WTX_RETRYS_ULTD (=255) accepts up to 255 sequential WTX requests, well within ISO 14443-4 limits. The card itself is fully spec-compliant on the WTX side -- the 20-cap is ST's conservative middleware choice. Revert to (20U) when we ship native AES-GCM hardware. aliro_apdu_wrap.c: extends the existing AUTH1 payload wrap to log the return value from ACWG_processAUTH1ResponsePayload (vendor library's internal status). Was instrumental in finding the three crypto bugs we fixed in the follow-up commit -- the vendor printed retval=ACWG_Error_* which let us localize the spec divergences without source access to Aliro.a or ACWG_Security.a. Two stale __real_/__wrap_ stubs for ACWG_computeKDHandVolatileKeys and ACWG_derivePersistentKeys were removed -- they had no matching --wrap flag in CMakeLists.txt and were silently dead. Co-Authored-By: Claude Opus 4.7 --- .../Middlewares/ST/rfal/Inc/rfal_isoDep.h | 2 +- .../nfc10-only/Core/Src/aliro_apdu_wrap.c | 18 ++++++++++++++++-- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/reader/STM32CubeExpansion_ALIRO_V1_0_0/Middlewares/ST/rfal/Inc/rfal_isoDep.h b/reader/STM32CubeExpansion_ALIRO_V1_0_0/Middlewares/ST/rfal/Inc/rfal_isoDep.h index 340e2a9..d769d59 100644 --- a/reader/STM32CubeExpansion_ALIRO_V1_0_0/Middlewares/ST/rfal/Inc/rfal_isoDep.h +++ b/reader/STM32CubeExpansion_ALIRO_V1_0_0/Middlewares/ST/rfal/Inc/rfal_isoDep.h @@ -133,7 +133,7 @@ #define RFAL_ISODEP_MAX_I_RETRYS (2U) /*!< Number of retries for a I-Block Digital 2.0 16.2.5.4 */ #define RFAL_ISODEP_MAX_R_RETRYS (3U) /*!< Number of retries for a R-Block Digital 2.0 B9 - nRETRY ACK/NAK: [2,5] */ #define RFAL_ISODEP_MAX_WTX_NACK_RETRYS (3U) /*!< Number of S(WTX) replied with NACK Digital 2.0 B9 - nRETRY WTX[2,5] */ -#define RFAL_ISODEP_MAX_WTX_RETRYS (20U) /*!< Number of overall S(WTX) retries Digital 2.0 16.2.5.2 */ +#define RFAL_ISODEP_MAX_WTX_RETRYS (255U) /* DT: bumped from stock 20 to ULTD (255U) so AUTH1 against our slow userland-GCM applet on j3r452 can finish; reverts to (20U) once we have native GCM */ #define RFAL_ISODEP_MAX_WTX_RETRYS_ULTD (255U) /*!< Use unlimited number of overall S(WTX) */ #define RFAL_ISODEP_MAX_DSL_RETRYS (0U) /*!< Number of retries for a S(DESELECT) Digital 2.0 B9 - nRETRY DESELECT: [0,5] */ #define RFAL_ISODEP_RATS_RETRIES (1U) /*!< RATS retries upon fail Digital 2.0 B7 - nRETRY RATS [0,1] */ diff --git a/reader/STM32CubeExpansion_ALIRO_V1_0_0/Projects/nucleo-u5/Applications/Aliro/nfc10-only/Core/Src/aliro_apdu_wrap.c b/reader/STM32CubeExpansion_ALIRO_V1_0_0/Projects/nucleo-u5/Applications/Aliro/nfc10-only/Core/Src/aliro_apdu_wrap.c index 04b5730..ad05771 100644 --- a/reader/STM32CubeExpansion_ALIRO_V1_0_0/Projects/nucleo-u5/Applications/Aliro/nfc10-only/Core/Src/aliro_apdu_wrap.c +++ b/reader/STM32CubeExpansion_ALIRO_V1_0_0/Projects/nucleo-u5/Applications/Aliro/nfc10-only/Core/Src/aliro_apdu_wrap.c @@ -32,10 +32,24 @@ ACWG_Status_t __real_ACWG_processAUTH1ResponsePayload( ACWG_Status_t __wrap_ACWG_processAUTH1ResponsePayload( ACWG_SessionContext_t *context, uint8_t *payload, uint32_t payloadSize) { - printf("[AUTH1-RESPONSE len=%u] ", (unsigned)payloadSize); + printf("[AUTH1-RESPONSE-IN len=%u] ", (unsigned)payloadSize); for (uint32_t i = 0; i < payloadSize && i < 256; i++) { printf("%02x", payload[i]); } printf("\r\n"); - return __real_ACWG_processAUTH1ResponsePayload(context, payload, payloadSize); + ACWG_Status_t ret = __real_ACWG_processAUTH1ResponsePayload(context, payload, payloadSize); + printf("[AUTH1-RESPONSE-OUT ret=%d (0x%X)]\r\n", (int)ret, (unsigned)ret); + return ret; } + +/* NOTE: tracing ACWG_computeKDHandVolatileKeys / ACWG_derivePersistentKeys + * was attempted via additional __wrap_ functions here, but the linker --wrap + * flags in CMakeLists.txt only redirect the two AUTH1 entry points. Adding + * the additional wraps without matching CMakeLists --wrap= flags produced a + * binary that boots but appears to hang during AUTH1 processing (suspected + * unresolved __real_* references being silently turned into broken calls + * by --gc-sections). If we need to instrument those inner functions later, + * add the matching -Wl,--wrap= flags in CMakeLists.txt first, then restore + * the corresponding __wrap_ definitions. For now, the AUTH1-RESPONSE-OUT + * return code is enough to identify which subsystem failed inside the + * vendor library. */