From 5383ad6e9aa4062f1cdad0a7302d568b14528c5a Mon Sep 17 00:00:00 2001 From: Juerg Wullschleger Date: Mon, 24 Jun 2024 23:52:10 -0700 Subject: [PATCH] Simplify calculation of n, and add unit-tests. The current implementation uses floating-points, which is unnecessary. PiperOrigin-RevId: 646353995 Change-Id: I2b32cdd12597662efc1630969cef7a347fab94d3 --- .../google/crypto/tink/subtle/PrfAesCmac.java | 10 +++++++++- .../crypto/tink/subtle/PrfAesCmacTest.java | 16 ++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/google/crypto/tink/subtle/PrfAesCmac.java b/src/main/java/com/google/crypto/tink/subtle/PrfAesCmac.java index 6a11d677b..a2f404929 100644 --- a/src/main/java/com/google/crypto/tink/subtle/PrfAesCmac.java +++ b/src/main/java/com/google/crypto/tink/subtle/PrfAesCmac.java @@ -78,6 +78,14 @@ public static Prf create(AesCmacPrfKey key) throws GeneralSecurityException { return new PrfAesCmac(key.getKeyBytes().toByteArray(InsecureSecretKeyAccess.get())); } + // Only visible for testing. + static int calcN(int dataLength) { + if (dataLength == 0) { + return 1; + } + return (dataLength - 1) / AesUtil.BLOCK_SIZE + 1; + } + // https://tools.ietf.org/html/rfc4493#section-2.4 @Override public byte[] compute(final byte[] data, int outputLength) throws GeneralSecurityException { @@ -92,7 +100,7 @@ public byte[] compute(final byte[] data, int outputLength) throws GeneralSecurit // is divided. Empty data is divided into 1 empty block. // Step 2: n = ceil(length / blocksize) // TODO(b/68969256): Adding a test that computes a CMAC of length 2**31-1. - int n = Math.max(1, (int) Math.ceil((double) data.length / AesUtil.BLOCK_SIZE)); + int n = calcN(data.length); // Step 3 boolean flag = (n * AesUtil.BLOCK_SIZE == data.length); diff --git a/src/test/java/com/google/crypto/tink/subtle/PrfAesCmacTest.java b/src/test/java/com/google/crypto/tink/subtle/PrfAesCmacTest.java index 713f0aab5..cd39b2283 100644 --- a/src/test/java/com/google/crypto/tink/subtle/PrfAesCmacTest.java +++ b/src/test/java/com/google/crypto/tink/subtle/PrfAesCmacTest.java @@ -83,6 +83,22 @@ public void testFipsCompatibility() throws Exception { () -> new PrfMac(new PrfAesCmac(CMAC_TEST_VECTORS[0].key), 16)); } + @Test + public void calcN() throws Exception { + // AesUtil.BLOCK_SIZE == 16 + assertThat(PrfAesCmac.calcN(0)).isEqualTo(1); + assertThat(PrfAesCmac.calcN(1)).isEqualTo(1); + assertThat(PrfAesCmac.calcN(16)).isEqualTo(1); + assertThat(PrfAesCmac.calcN(17)).isEqualTo(2); + assertThat(PrfAesCmac.calcN(32)).isEqualTo(2); + assertThat(PrfAesCmac.calcN(33)).isEqualTo(3); + assertThat(PrfAesCmac.calcN(48)).isEqualTo(3); + assertThat(PrfAesCmac.calcN(49)).isEqualTo(4); + assertThat(PrfAesCmac.calcN(0x7FFFFFF0)).isEqualTo(0x07FFFFFF); + assertThat(PrfAesCmac.calcN(0x7FFFFFF1)).isEqualTo(0x08000000); + assertThat(PrfAesCmac.calcN(Integer.MAX_VALUE)).isEqualTo(0x08000000); + } + @Test public void testMacTestVectors() throws Exception { Assume.assumeFalse(TinkFips.useOnlyFips());