perf(applet): trim 3 over-sized transient buffers (~216 B reclaimed)

J3R452 CLEAR_ON_DESELECT pool was at ~285 B headroom post-M2G.2.
Tighten three M1/M2 conservative sizings to spec-actual values:

- AliroApplet.SALT_VOLATILE_CAPACITY: 200 -> 144
  Spec §8.3.1.13 fixes salt_volatile at 141 B. 144 = 141 + 3 B pad.
- StepUpApplet.RESPONSE_BUFFER_LEN: 512 -> 416
  Holds 388 B max (372 B canonical DeviceResponse + 16 B GCM tag).
  AD is fixed 272 B at personalization, wrapper shape is fixed.
- StepUpApplet.SCRATCH_PLAINTEXT_LEN: 256 -> 192
  M2D.1 valid DeviceRequest vector is 85 B, Reader Status request
  is 2 B; 192 leaves ~107 B headroom for larger reader requests.

No spec deviation. No security implication (sizes are upper bounds on
buffers, not crypto parameters). All 147 applet tests pass (3 documented
pre-existing GCM errors unchanged).

New pool budget: ~2,619 / ~3,120 B used, ~501 B headroom.
This commit is contained in:
michael
2026-06-17 21:01:50 -07:00
parent f9b0c1ea81
commit c85ecd2f73
2 changed files with 12 additions and 5 deletions

View File

@@ -177,7 +177,10 @@ public class AliroApplet extends Applet {
private static final short DERIVED_KEYS_LEN = 160; private static final short DERIVED_KEYS_LEN = 160;
private static final short KDH_LEN = 32; private static final short KDH_LEN = 32;
private static final short SALT_VOLATILE_CAPACITY = 200; // Spec §8.3.1.13 fixes salt_volatile at 141 B. 144 B = 141 + 3 B pad to
// keep the transient allocation arithmetic round without wasting the
// 59 B headroom the M1 conservative sizing carried.
private static final short SALT_VOLATILE_CAPACITY = 144;
/** Offsets into {@link #derivedKeys} per spec §8.3.1.13. */ /** Offsets into {@link #derivedKeys} per spec §8.3.1.13. */
private static final short OFF_EXPEDITED_SK_READER = 0; private static final short OFF_EXPEDITED_SK_READER = 0;

View File

@@ -87,8 +87,10 @@ public class StepUpApplet extends Applet {
/** Response chaining buffer for DeviceResponse outputs > {@link #CHUNK_LEN}. /** Response chaining buffer for DeviceResponse outputs > {@link #CHUNK_LEN}.
* Sized for 372 B canonical DeviceResponse + 16 B GCM tag = 388 B with * Sized for 372 B canonical DeviceResponse + 16 B GCM tag = 388 B with
* headroom for future shape tweaks. */ * 28 B headroom. AD is fixed 272 B at personalization; wrapper shape
private static final short RESPONSE_BUFFER_LEN = 512; * is fixed (see DeviceResponseBuilder). Was 512 B in M2D.4; shrunk to
* reclaim transient pool budget on J3R452. */
private static final short RESPONSE_BUFFER_LEN = 416;
/** Holds StepUpSKDevice / StepUpSKReader and the two BE32 message /** Holds StepUpSKDevice / StepUpSKReader and the two BE32 message
* counters, plus the IV-stamping math (spec §8.3.1.6/8/9 + §8.4.3). * counters, plus the IV-stamping math (spec §8.3.1.6/8/9 + §8.4.3).
@@ -108,9 +110,11 @@ public class StepUpApplet extends Applet {
/** Transient plaintext sink for ENVELOPE DeviceRequest and EXCHANGE /** Transient plaintext sink for ENVELOPE DeviceRequest and EXCHANGE
* Reader Status request decrypts. Sized for the largest reasonable * Reader Status request decrypts. Sized for the largest reasonable
* reader-supplied payload; CLEAR_ON_DESELECT so post-deselect there's * reader-supplied payload; CLEAR_ON_DESELECT so post-deselect there's
* no plaintext residue. */ * no plaintext residue. M2D.1 valid DeviceRequest vector is 85 B,
* Reader Status request is 2 B — 192 B leaves ~107 B headroom for
* larger reader requests. Was 256 B; shrunk to reclaim pool budget. */
private final byte[] scratchPlaintext; private final byte[] scratchPlaintext;
private static final short SCRATCH_PLAINTEXT_LEN = 256; private static final short SCRATCH_PLAINTEXT_LEN = 192;
/** Transient single-slot flag: 1 once {@link #select()} successfully /** Transient single-slot flag: 1 once {@link #select()} successfully
* derived the Step-Up session keys (i.e. the SELECT found * derived the Step-Up session keys (i.e. the SELECT found