Skip to content

Commit 45eb278

Browse files
committed
JCE: add Cipher.getInstance("AES") support, aliased to AES/ECB/PKCS5Padding, along with tests
1 parent 777a564 commit 45eb278

File tree

3 files changed

+71
-5
lines changed

3 files changed

+71
-5
lines changed

README_JCE.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ The JCE provider currently supports the following algorithms:
107107
AES/CCM/NoPadding
108108
AES/CTR/NoPadding
109109
AES/ECB/NoPadding
110-
AES/ECB/PKCS5Padding
110+
AES/ECB/PKCS5Padding (aliased also as: AES)
111111
AES/GCM/NoPadding
112112
AES/OFB/NoPadding
113113
DESede/CBC/NoPadding

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,10 @@ private void registerServices() {
281281
"com.wolfssl.provider.jce.WolfCryptCipher$wcAESECBNoPadding");
282282
put("Cipher.AES/ECB/PKCS5Padding",
283283
"com.wolfssl.provider.jce.WolfCryptCipher$wcAESECBPKCS5Padding");
284+
/* SunJCE and Bouncy Castle alias AES to AES/ECB/PKCS5Padding,
285+
* we do the same here for compatibility. */
286+
put("Cipher.AES",
287+
"com.wolfssl.provider.jce.WolfCryptCipher$wcAESECBPKCS5Padding");
284288
}
285289
if (FeatureDetect.AesCtrEnabled()) {
286290
put("Cipher.AES/CTR/NoPadding",

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

Lines changed: 66 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ public class WolfCryptCipherTest {
7777
"AES/CCM/NoPadding",
7878
"AES/CTR/NoPadding",
7979
"AES/ECB/NoPadding",
80+
"AES", /* maps to AES/ECB/PKCS5Padding */
8081
"AES/ECB/PKCS5Padding",
8182
"AES/GCM/NoPadding",
8283
"AES/OFB/NoPadding",
@@ -137,6 +138,7 @@ public static void testProviderInstallationAtRuntime()
137138
expectedBlockSizes.put("AES/CCM/NoPadding", 16);
138139
expectedBlockSizes.put("AES/CTR/NoPadding", 16);
139140
expectedBlockSizes.put("AES/ECB/NoPadding", 16);
141+
expectedBlockSizes.put("AES", 16);
140142
expectedBlockSizes.put("AES/ECB/PKCS5Padding", 16);
141143
expectedBlockSizes.put("AES/GCM/NoPadding", 16);
142144
expectedBlockSizes.put("AES/OFB/NoPadding", 16);
@@ -760,6 +762,63 @@ public void testAesCbcNoPaddingBigMessage()
760762
assertArrayEquals(plain, input);
761763
}
762764

765+
/* Cipher.getInstance("AES") is just AES/ECB/PKCS5Padding, so we
766+
* do one test that here. */
767+
@Test
768+
public void testAesGeneric()
769+
throws NoSuchProviderException, NoSuchAlgorithmException,
770+
NoSuchPaddingException, InvalidKeyException,
771+
IllegalBlockSizeException, InvalidAlgorithmParameterException,
772+
BadPaddingException {
773+
774+
if (!FeatureDetect.AesEcbEnabled()) {
775+
/* skip if AES is not enabled */
776+
return;
777+
}
778+
779+
byte key[] = new byte[] {
780+
(byte)0x2b, (byte)0x7e, (byte)0x15, (byte)0x16,
781+
(byte)0x28, (byte)0xae, (byte)0xd2, (byte)0xa6,
782+
(byte)0xab, (byte)0xf7, (byte)0x15, (byte)0x88,
783+
(byte)0x09, (byte)0xcf, (byte)0x4f, (byte)0x3c
784+
};
785+
786+
/* Test with data that needs padding.
787+
* 12 bytes, needs 4 bytes padding */
788+
byte input[] = "Hello World!".getBytes();
789+
790+
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding", jceProvider);
791+
SecretKeySpec keySpec = new SecretKeySpec(key, "AES");
792+
793+
/* Test encryption */
794+
cipher.init(Cipher.ENCRYPT_MODE, keySpec);
795+
byte[] ciphertext = cipher.doFinal(input);
796+
797+
/* Ciphertext should be block-aligned (16 bytes) */
798+
assertEquals(16, ciphertext.length);
799+
800+
/* Test decryption */
801+
cipher.init(Cipher.DECRYPT_MODE, keySpec);
802+
byte[] decrypted = cipher.doFinal(ciphertext);
803+
804+
assertArrayEquals(input, decrypted);
805+
806+
/* Test with exact block size data */
807+
byte blockSizeInput[] = new byte[16];
808+
Arrays.fill(blockSizeInput, (byte)0x41); /* Fill with 'A' */
809+
810+
cipher.init(Cipher.ENCRYPT_MODE, keySpec);
811+
byte[] blockCiphertext = cipher.doFinal(blockSizeInput);
812+
813+
/* Should be 32 bytes (original 16 + 16 bytes padding) */
814+
assertEquals(32, blockCiphertext.length);
815+
816+
cipher.init(Cipher.DECRYPT_MODE, keySpec);
817+
byte[] blockDecrypted = cipher.doFinal(blockCiphertext);
818+
819+
assertArrayEquals(blockSizeInput, blockDecrypted);
820+
}
821+
763822
@Test
764823
public void testAesCbcPKCS5Padding()
765824
throws NoSuchProviderException, NoSuchAlgorithmException,
@@ -4338,7 +4397,8 @@ public void testIVConsistencyAcrossOperations() throws Exception {
43384397
/* Test all enabled cipher modes that use IVs (exclude RSA and ECB) */
43394398
for (String mode : enabledJCEAlgos) {
43404399
/* Skip modes that don't use IVs */
4341-
if (mode.startsWith("RSA") || mode.contains("/ECB/")) {
4400+
if (mode.startsWith("RSA") || mode.contains("/ECB/") ||
4401+
mode.equals("AES")) {
43424402
continue;
43434403
}
43444404

@@ -4367,14 +4427,15 @@ private void testIVConsistencyForMode(String algorithm) throws Exception {
43674427
/* Generate test key */
43684428
if (algorithm.startsWith("AES")) {
43694429
key = new byte[16]; /* AES-128 */
4430+
keySpec = new SecretKeySpec(key, "AES");
43704431
} else if (algorithm.startsWith("DESede")) {
43714432
key = new byte[24]; /* 3DES */
4433+
keySpec = new SecretKeySpec(key, "DESede");
43724434
} else {
43734435
return; /* Unsupported algorithm */
43744436
}
43754437

43764438
secureRandom.nextBytes(key);
4377-
keySpec = new SecretKeySpec(key, algorithm.split("/")[0]);
43784439

43794440
/* Generate test data of various sizes to ensure robustness */
43804441
for (int dataSize : testSizes) {
@@ -4398,8 +4459,9 @@ private void testIVConsistencyForModeAndSize(String algorithm,
43984459
byte[] ivAfterDecryption;
43994460

44004461
/* Skip sizes that would cause issues with block ciphers */
4401-
if ((algorithm.contains("CBC") || algorithm.contains("ECB")) &&
4402-
algorithm.contains("NoPadding") && (dataSize % 16 != 0)) {
4462+
if ((algorithm.equals("AES") ||
4463+
((algorithm.contains("CBC") || algorithm.contains("ECB")) &&
4464+
algorithm.contains("NoPadding"))) && (dataSize % 16 != 0)) {
44034465
return; /* Block size must be multiple of 16 for NoPadding */
44044466
}
44054467
if (algorithm.startsWith("DESede") &&

0 commit comments

Comments
 (0)