Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 11 additions & 4 deletions src/main/java/com/wolfssl/provider/jce/WolfCryptCipher.java
Original file line number Diff line number Diff line change
Expand Up @@ -303,12 +303,19 @@ protected int engineGetOutputSize(int inputLen)
if (paddingType == PaddingType.WC_NONE) {
if (cipherMode == CipherMode.WC_GCM) {
/* In AES-GCM mode we append the authentication tag
* to the end of ciphertext */
size = inputLen + this.gcmTagLen;
* to the end of ciphertext, When decrypting, output
* size will have it taken off. */
if (this.direction == OpMode.WC_ENCRYPT) {
size = inputLen + this.gcmTagLen;
}
else {
size = inputLen - this.gcmTagLen;
}
size = Math.max(size, 0);
}
else {
/* wolfCrypt expects input to be padded by application to
* block size, thus output is same size as input */
/* wolfCrypt expects input to be padded by application
* to block size, thus output is same size as input */
size = inputLen;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2250,6 +2250,66 @@ public void testAesGcmNoPaddingInterop() throws NoSuchAlgorithmException,
}
}

/**
* Test Cipher("AES/GCM/NoPadding") getOutputSize() method for various
* use cases.
*/
@Test
public void testAesGcmGetOutputSize() throws Exception {

final int TAG_LENGTH_BYTES = 16; /* Default tag length */
final int KEY_LENGTH_BYTES = 16; /* 128-bit AES key */
final int IV_LENGTH_BYTES = 12;

/* Fill key and IV with non-zero values */
byte[] keyBytes = new byte[KEY_LENGTH_BYTES];
java.util.Arrays.fill(keyBytes, (byte) 0x01);
SecretKeySpec key = new SecretKeySpec(keyBytes, "AES");

byte[] iv = new byte[IV_LENGTH_BYTES];
java.util.Arrays.fill(iv, (byte) 0x02);
GCMParameterSpec spec = new GCMParameterSpec(TAG_LENGTH_BYTES * 8, iv);

Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding", jceProvider);

/* Test ENCRYPT with zero-length input */
cipher.init(Cipher.ENCRYPT_MODE, key, spec);
assertEquals("Output size for zero-length input should be tag length",
TAG_LENGTH_BYTES, cipher.getOutputSize(0));

/* Test ENCRYPT with small input, re-init to reset state */
cipher.init(Cipher.ENCRYPT_MODE, key, spec);
assertEquals("Output size should be input length plus tag length",
10 + TAG_LENGTH_BYTES, cipher.getOutputSize(10));

/* Test ENCRYPT with block boundary input */
cipher.init(Cipher.ENCRYPT_MODE, key, spec);
assertEquals("Output size should be input length plus tag length " +
"at block boundary", 16 + TAG_LENGTH_BYTES,
cipher.getOutputSize(16));

/* Test DECRYPT with tag included */
cipher.init(Cipher.DECRYPT_MODE, key, spec);
assertEquals("Output size for decryption should be input length " +
"minus tag length", 10, cipher.getOutputSize(10 + TAG_LENGTH_BYTES));

/* Test ENCRYPT after partial update */
byte[] partialInput = new byte[5];
cipher.init(Cipher.ENCRYPT_MODE, key, spec);
cipher.update(partialInput); /* Process some data */
assertEquals("Output size after update should account for remaining " +
"input plus tag", 10 + TAG_LENGTH_BYTES, cipher.getOutputSize(10));

/* Test getOutputSize() before initialization, expect exception */
Cipher uninitializedCipher = Cipher.getInstance("AES/GCM/NoPadding");
try {
uninitializedCipher.getOutputSize(10);
fail("Expected IllegalStateException for uninitialized cipher");
} catch (IllegalStateException e) {
/* Expected exception */
}
}

@Test
public void testDESedeCbcNoPadding()
throws NoSuchProviderException, NoSuchAlgorithmException,
Expand Down