build(reader): WTX cap bump 20→255 + AUTH1 wrap instrumentation

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 <noreply@anthropic.com>
This commit is contained in:
michael
2026-06-11 10:15:34 -07:00
parent 34ba616e48
commit 06c00385a4
2 changed files with 17 additions and 3 deletions

View File

@@ -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. */