From 4382551949e5100ba058ad4d7cd17d5d8cd23cef Mon Sep 17 00:00:00 2001 From: Chris Conlon Date: Fri, 21 Aug 2026 15:54:09 -0600 Subject: [PATCH] F-5992: throw AEADBadTagException on AES-CCM tag failure --- .../wolfssl/provider/jce/WolfCryptCipher.java | 16 ++++- .../jce/test/WolfCryptCipherTest.java | 63 +++++++++++++++++++ 2 files changed, 77 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/wolfssl/provider/jce/WolfCryptCipher.java b/src/main/java/com/wolfssl/provider/jce/WolfCryptCipher.java index a220cb0a..43faf877 100644 --- a/src/main/java/com/wolfssl/provider/jce/WolfCryptCipher.java +++ b/src/main/java/com/wolfssl/provider/jce/WolfCryptCipher.java @@ -1748,8 +1748,20 @@ public class WolfCryptCipher extends CipherSpi { tmpIn = Arrays.copyOfRange(tmpIn, 0, tmpIn.length - this.gcmTagLen); - tmpOut = this.aesCcm.decrypt(tmpIn, this.iv, tag, - aad); + try { + tmpOut = this.aesCcm.decrypt(tmpIn, this.iv, + tag, aad); + + } catch (WolfCryptException e) { + /* Convert to AEADBadTagException */ + if (e.getCode() == + WolfCryptError.AES_CCM_AUTH_E.getCode()) { + /* Authentication check fail */ + throw new AEADBadTagException( + e.getMessage()); + } + throw e; + } } } else if (cipherMode == CipherMode.WC_ECB) { diff --git a/src/test/java/com/wolfssl/provider/jce/test/WolfCryptCipherTest.java b/src/test/java/com/wolfssl/provider/jce/test/WolfCryptCipherTest.java index bce86cc0..18e7e299 100644 --- a/src/test/java/com/wolfssl/provider/jce/test/WolfCryptCipherTest.java +++ b/src/test/java/com/wolfssl/provider/jce/test/WolfCryptCipherTest.java @@ -3053,6 +3053,69 @@ public class WolfCryptCipherTest { } } + /** + * AES-CCM decrypt failure should throw AEADBadTagException. + */ + @Test + public void testAesCcmBadTagExceptionRegression() + throws NoSuchProviderException, NoSuchAlgorithmException, + NoSuchPaddingException, InvalidKeyException, + IllegalBlockSizeException, InvalidAlgorithmParameterException, + BadPaddingException { + + if (!enabledJCEAlgos.contains("AES/CCM/NoPadding")) { + /* skip if AES-CCM is not enabled */ + return; + } + + byte[] key = new byte[] { + (byte)0x2b, (byte)0x7e, (byte)0x15, (byte)0x16, + (byte)0x28, (byte)0xae, (byte)0xd2, (byte)0xa6, + (byte)0xab, (byte)0xf7, (byte)0x15, (byte)0x88, + (byte)0x09, (byte)0xcf, (byte)0x4f, (byte)0x3c + }; + + byte[] nonce = new byte[] { + (byte)0x00, (byte)0x01, (byte)0x02, (byte)0x03, + (byte)0x04, (byte)0x05, (byte)0x06, (byte)0x07, + (byte)0x08, (byte)0x09, (byte)0x0a, (byte)0x0b + }; + + byte[] plaintext = new byte[] { + (byte)0x48, (byte)0x65, (byte)0x6c, (byte)0x6c, + (byte)0x6f, (byte)0x20, (byte)0x57, (byte)0x6f, + (byte)0x72, (byte)0x6c, (byte)0x64, (byte)0x21 + }; + + Cipher cipher = Cipher.getInstance("AES/CCM/NoPadding", jceProvider); + SecretKeySpec keySpec = new SecretKeySpec(key, "AES"); + GCMParameterSpec ccmSpec = new GCMParameterSpec(128, nonce); + + /* First encrypt to get valid ciphertext */ + cipher.init(Cipher.ENCRYPT_MODE, keySpec, ccmSpec); + byte[] ciphertext = cipher.doFinal(plaintext); + + /* Corrupt the authentication tag (last 16 bytes) */ + byte[] corruptedCiphertext = ciphertext.clone(); + int tagStart = corruptedCiphertext.length - 16; + for (int i = tagStart; i < corruptedCiphertext.length; i++) { + corruptedCiphertext[i] = (byte)0xFF; + } + + /* Attempt to decrypt with corrupted tag, should throw + * AEADBadTagException */ + cipher.init(Cipher.DECRYPT_MODE, keySpec, ccmSpec); + try { + cipher.doFinal(corruptedCiphertext); + fail("Expected AEADBadTagException for corrupted CCM tag"); + } catch (AEADBadTagException e) { + /* Expected */ + } catch (Exception e) { + fail("Expected AEADBadTagException but got: " + + e.getClass().getSimpleName() + " - " + e.getMessage()); + } + } + @Test public void testAesEcbNoPadding() throws NoSuchProviderException, NoSuchAlgorithmException,