test(applet): pin deriveStepUpSessionKeys to spec ASCII info strings

Adds a second regression test for AliroCrypto.deriveStepUpSessionKeys
that hard-codes the exact RFC 5869 reference computation (empty salt,
"SKDevice" / "SKReader" ASCII info) with a different IKM byte pattern
and independent expand-once helper. Complements the existing
deriveStepUpSessionKeysMatchesManualHkdf so a future spec misread in
shared helper code can't slip through.

Implementation itself was landed earlier in f94e416 ("fix: AUTH1 crypto
interop with stock X-CUBE-ALIRO + EXCHANGE compat stub"); this is the
M1A.1 task's tightened pin from the Step-Up v2 plan.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
michael
2026-06-11 10:23:44 -07:00
parent 9189b41e7f
commit cedefef70e

View File

@@ -167,6 +167,50 @@ class AliroCryptoTest {
} }
} }
/**
* Independent pin against an inline RFC 5869 reference (one HKDF-Expand
* block: T(1) = HMAC(PRK, info || 0x01)). Complements
* {@link #deriveStepUpSessionKeysMatchesManualHkdf} by anchoring on the
* exact ASCII info strings the spec specifies ("SKDevice" / "SKReader")
* with a different IKM byte pattern, so a future spec misread can't be
* masked by sharing helper code with the equivalent test above.
*/
@Test
void deriveStepUpSessionKeysMatchesRfc5869WithSpecInfoStrings() throws Exception {
AliroCrypto crypto = new AliroCrypto();
byte[] stepUpSK = new byte[32];
for (byte i = 0; i < 32; i++) stepUpSK[i] = (byte) (0x10 + i);
byte[] skDevice = new byte[32];
byte[] skReader = new byte[32];
crypto.deriveStepUpSessionKeys(
stepUpSK, (short) 0,
skDevice, (short) 0,
skReader, (short) 0);
// Reference HKDF-SHA-256 with empty salt
javax.crypto.Mac extractMac = javax.crypto.Mac.getInstance("HmacSHA256");
extractMac.init(new javax.crypto.spec.SecretKeySpec(new byte[32], "HmacSHA256"));
byte[] prk = extractMac.doFinal(stepUpSK);
byte[] expectedDevice = expandOnce(prk, "SKDevice".getBytes("US-ASCII"));
byte[] expectedReader = expandOnce(prk, "SKReader".getBytes("US-ASCII"));
assertArrayEquals(expectedDevice, skDevice,
"StepUpSKDevice = HKDF-Expand(PRK, info=ASCII(\"SKDevice\"), L=32)");
assertArrayEquals(expectedReader, skReader,
"StepUpSKReader = HKDF-Expand(PRK, info=ASCII(\"SKReader\"), L=32)");
}
private static byte[] expandOnce(byte[] prk, byte[] info) throws Exception {
// T(1) = HMAC-SHA-256(PRK, info || 0x01); first 32 bytes is the output
javax.crypto.Mac mac = javax.crypto.Mac.getInstance("HmacSHA256");
mac.init(new javax.crypto.spec.SecretKeySpec(prk, "HmacSHA256"));
mac.update(info);
mac.update((byte) 0x01);
return mac.doFinal();
}
@Test @Test
void hkdfExpandRfc5869TestCase1() { void hkdfExpandRfc5869TestCase1() {
AliroCrypto crypto = new AliroCrypto(); AliroCrypto crypto = new AliroCrypto();