Skip to content

Commit a47e24a

Browse files
Merge pull request #107 from cconlon/cipherAesGcmNoPaddingOutputSize
JCE: fix Cipher.getOutputSize() for AES/GCM/NoPadding in DECRYPT mode
2 parents ab70102 + dbfbe28 commit a47e24a

2 files changed

Lines changed: 71 additions & 4 deletions

File tree

src/main/java/com/wolfssl/provider/jce/WolfCryptCipher.java

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -303,12 +303,19 @@ protected int engineGetOutputSize(int inputLen)
303303
if (paddingType == PaddingType.WC_NONE) {
304304
if (cipherMode == CipherMode.WC_GCM) {
305305
/* In AES-GCM mode we append the authentication tag
306-
* to the end of ciphertext */
307-
size = inputLen + this.gcmTagLen;
306+
* to the end of ciphertext, When decrypting, output
307+
* size will have it taken off. */
308+
if (this.direction == OpMode.WC_ENCRYPT) {
309+
size = inputLen + this.gcmTagLen;
310+
}
311+
else {
312+
size = inputLen - this.gcmTagLen;
313+
}
314+
size = Math.max(size, 0);
308315
}
309316
else {
310-
/* wolfCrypt expects input to be padded by application to
311-
* block size, thus output is same size as input */
317+
/* wolfCrypt expects input to be padded by application
318+
* to block size, thus output is same size as input */
312319
size = inputLen;
313320
}
314321
}

src/test/java/com/wolfssl/provider/jce/test/WolfCryptCipherTest.java

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2250,6 +2250,66 @@ public void testAesGcmNoPaddingInterop() throws NoSuchAlgorithmException,
22502250
}
22512251
}
22522252

2253+
/**
2254+
* Test Cipher("AES/GCM/NoPadding") getOutputSize() method for various
2255+
* use cases.
2256+
*/
2257+
@Test
2258+
public void testAesGcmGetOutputSize() throws Exception {
2259+
2260+
final int TAG_LENGTH_BYTES = 16; /* Default tag length */
2261+
final int KEY_LENGTH_BYTES = 16; /* 128-bit AES key */
2262+
final int IV_LENGTH_BYTES = 12;
2263+
2264+
/* Fill key and IV with non-zero values */
2265+
byte[] keyBytes = new byte[KEY_LENGTH_BYTES];
2266+
java.util.Arrays.fill(keyBytes, (byte) 0x01);
2267+
SecretKeySpec key = new SecretKeySpec(keyBytes, "AES");
2268+
2269+
byte[] iv = new byte[IV_LENGTH_BYTES];
2270+
java.util.Arrays.fill(iv, (byte) 0x02);
2271+
GCMParameterSpec spec = new GCMParameterSpec(TAG_LENGTH_BYTES * 8, iv);
2272+
2273+
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding", jceProvider);
2274+
2275+
/* Test ENCRYPT with zero-length input */
2276+
cipher.init(Cipher.ENCRYPT_MODE, key, spec);
2277+
assertEquals("Output size for zero-length input should be tag length",
2278+
TAG_LENGTH_BYTES, cipher.getOutputSize(0));
2279+
2280+
/* Test ENCRYPT with small input, re-init to reset state */
2281+
cipher.init(Cipher.ENCRYPT_MODE, key, spec);
2282+
assertEquals("Output size should be input length plus tag length",
2283+
10 + TAG_LENGTH_BYTES, cipher.getOutputSize(10));
2284+
2285+
/* Test ENCRYPT with block boundary input */
2286+
cipher.init(Cipher.ENCRYPT_MODE, key, spec);
2287+
assertEquals("Output size should be input length plus tag length " +
2288+
"at block boundary", 16 + TAG_LENGTH_BYTES,
2289+
cipher.getOutputSize(16));
2290+
2291+
/* Test DECRYPT with tag included */
2292+
cipher.init(Cipher.DECRYPT_MODE, key, spec);
2293+
assertEquals("Output size for decryption should be input length " +
2294+
"minus tag length", 10, cipher.getOutputSize(10 + TAG_LENGTH_BYTES));
2295+
2296+
/* Test ENCRYPT after partial update */
2297+
byte[] partialInput = new byte[5];
2298+
cipher.init(Cipher.ENCRYPT_MODE, key, spec);
2299+
cipher.update(partialInput); /* Process some data */
2300+
assertEquals("Output size after update should account for remaining " +
2301+
"input plus tag", 10 + TAG_LENGTH_BYTES, cipher.getOutputSize(10));
2302+
2303+
/* Test getOutputSize() before initialization, expect exception */
2304+
Cipher uninitializedCipher = Cipher.getInstance("AES/GCM/NoPadding");
2305+
try {
2306+
uninitializedCipher.getOutputSize(10);
2307+
fail("Expected IllegalStateException for uninitialized cipher");
2308+
} catch (IllegalStateException e) {
2309+
/* Expected exception */
2310+
}
2311+
}
2312+
22532313
@Test
22542314
public void testDESedeCbcNoPadding()
22552315
throws NoSuchProviderException, NoSuchAlgorithmException,

0 commit comments

Comments
 (0)