diff --git a/applet/src/test/java/com/dangerousthings/aliro/AliroCryptoTest.java b/applet/src/test/java/com/dangerousthings/aliro/AliroCryptoTest.java index 5bedbfc..05cc9ec 100644 --- a/applet/src/test/java/com/dangerousthings/aliro/AliroCryptoTest.java +++ b/applet/src/test/java/com/dangerousthings/aliro/AliroCryptoTest.java @@ -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 void hkdfExpandRfc5869TestCase1() { AliroCrypto crypto = new AliroCrypto();