--- old/src/java.base/share/classes/com/sun/crypto/provider/CipherCore.java 2019-07-24 00:26:53.021713910 +0000 +++ new/src/java.base/share/classes/com/sun/crypto/provider/CipherCore.java 2019-07-24 00:26:52.133684271 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -271,7 +271,9 @@ padding = null; } else if (paddingScheme.equalsIgnoreCase("ISO10126Padding")) { padding = new ISO10126Padding(blockSize); - } else if (!paddingScheme.equalsIgnoreCase("PKCS5Padding")) { + } else if (paddingScheme.equalsIgnoreCase("PKCS5Padding")) { + padding = new PKCS5Padding(blockSize); + } else { throw new NoSuchPaddingException("Padding: " + paddingScheme + " not implemented"); } --- old/src/java.base/share/classes/javax/crypto/Cipher.java 2019-07-24 00:26:55.801806698 +0000 +++ new/src/java.base/share/classes/javax/crypto/Cipher.java 2019-07-24 00:26:54.907776859 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -559,16 +559,16 @@ // does not support mode or padding we need, ignore continue; } - if (canuse == S_YES) { + // S_YES, S_MAYBE + // even when mode and padding are both supported, they + // may not be used together, try out and see if it works + try { + CipherSpi spi = (CipherSpi)s.newInstance(null); + tr.setModePadding(spi); + // specify null instead of spi for delayed provider selection return new Cipher(null, s, t, transformation, transforms); - } else { // S_MAYBE, try out if it works - try { - CipherSpi spi = (CipherSpi)s.newInstance(null); - tr.setModePadding(spi); - return new Cipher(spi, s, t, transformation, transforms); - } catch (Exception e) { - failure = e; - } + } catch (Exception e) { + failure = e; } } throw new NoSuchAlgorithmException --- old/test/jdk/com/sun/crypto/provider/Cipher/AES/Padding.java 2019-07-24 00:26:58.651901823 +0000 +++ new/test/jdk/com/sun/crypto/provider/Cipher/AES/Padding.java 2019-07-24 00:26:57.729871049 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -48,19 +48,24 @@ private static final String ALGORITHM = "AES"; private static final String PROVIDER = "SunJCE"; - private static final String[] MODES = { "ECb", "CbC", "PCBC", "OFB", + private static final String[] MODES_PKCS5PAD = { + "ECb", "CbC", "PCBC", "OFB", "OFB150", "cFB", "CFB7", "cFB8", "cFB16", "cFB24", "cFB32", "Cfb40", "cfB48", "cfB56", "cfB64", "cfB72", "cfB80", "cfB88", "cfB96", "cfb104", "cfB112", "cfB120", "OFB8", "OFB16", "OFB24", "OFB32", "OFB40", "OFB48", "OFB56", "OFB64", "OFB72", "OFB80", - "OFB88", "OFB96", "OFB104", "OFB112", "OFB120", "GCM" }; - private static final String PADDING = "PKCS5Padding"; + "OFB88", "OFB96", "OFB104", "OFB112", "OFB120" }; + private static final String[] MODES_NOPAD = { "CTR", "CTS", "GCM" }; + private static final int KEY_LENGTH = 128; public static void main(String argv[]) throws Exception { Padding test = new Padding(); - for (String mode : MODES) { - test.runTest(ALGORITHM, mode, PADDING); + for (String mode : MODES_PKCS5PAD) { + test.runTest(ALGORITHM, mode, "PKCS5Padding"); + } + for (String mode : MODES_NOPAD) { + test.runTest(ALGORITHM, mode, "NoPadding"); } } @@ -92,7 +97,6 @@ int offset = ci.update(plainText, 0, plainText.length, cipherText, 0); ci.doFinal(cipherText, offset); - if (!mo.equalsIgnoreCase("ECB")) { iv = ci.getIV(); aps = new IvParameterSpec(iv); --- old/test/jdk/com/sun/crypto/provider/Cipher/Blowfish/TestCipherBlowfish.java 2019-07-24 00:27:01.415994077 +0000 +++ new/test/jdk/com/sun/crypto/provider/Cipher/Blowfish/TestCipherBlowfish.java 2019-07-24 00:27:00.519964171 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,20 +32,20 @@ public class TestCipherBlowfish extends TestCipher { - TestCipherBlowfish() throws NoSuchAlgorithmException { - super("Blowfish", - new String[]{"CBC", "CTR", "CTS", "ECB", "PCBC", - //CFBx - "CFB", "CFB8", "CFB16", "CFB24", "CFB32", "CFB40", "CFB48", "CFB56", - "CFB64", - //OFBx - "OFB", "OFB8", "OFB16", "OFB24", "OFB32", "OFB40", "OFB48", "OFB56", - "OFB64"}, - new String[]{"NoPaDDing", "PKCS5Padding"}, - 32, 448); + TestCipherBlowfish(String[] modes, String[] paddings) throws NoSuchAlgorithmException { + super("Blowfish", modes, paddings, 32, 448); } public static void main(String[] args) throws Exception { - new TestCipherBlowfish().runAll(); + new TestCipherBlowfish(new String[]{ "CBC", "ECB", "PCBC", + //CFBx + "CFB", "CFB8", "CFB16", "CFB24", "CFB32", "CFB40", + "CFB48", "CFB56", "CFB64", + //OFBx + "OFB", "OFB8", "OFB16", "OFB24", "OFB32", "OFB40", + "OFB48", "OFB56", "OFB64"}, + new String[]{ "NoPaDDing", "PKCS5Padding"}).runAll(); + new TestCipherBlowfish(new String[]{ "CTR", "CTS" }, + new String[]{ "NoPaDDing" }).runAll(); } } --- old/test/jdk/com/sun/crypto/provider/Cipher/DES/TestCipherDES.java 2019-07-24 00:27:04.181086365 +0000 +++ new/test/jdk/com/sun/crypto/provider/Cipher/DES/TestCipherDES.java 2019-07-24 00:27:03.285056459 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,19 +30,20 @@ public class TestCipherDES extends TestCipher { - TestCipherDES() { - super("DES", - new String[]{"CBC", "CTR", "CTS", "ECB", "PCBC", - //CFBx - "CFB", "CFB8", "CFB16", "CFB24", "CFB32", "CFB40", "CFB48", "CFB56", - "CFB64", - //OFBx - "OFB", "OFB8", "OFB16", "OFB24", "OFB32", "OFB40", "OFB48", "OFB56", - "OFB64"}, - new String[]{"NoPaDDing", "PKCS5Padding"}); + TestCipherDES(String[] modes, String[] paddings) { + super("DES", modes, paddings); } public static void main(String[] args) throws Exception { - new TestCipherDES().runAll(); + new TestCipherDES(new String[]{ "CBC", "ECB", "PCBC", + //CFBx + "CFB", "CFB8", "CFB16", "CFB24", "CFB32", "CFB40", + "CFB48", "CFB56", "CFB64", + //OFBx + "OFB", "OFB8", "OFB16", "OFB24", "OFB32", "OFB40", + "OFB48", "OFB56", "OFB64" }, + new String[]{ "NoPaDDing", "PKCS5Padding" }).runAll(); + new TestCipherDES(new String[]{ "CTR", "CTS" }, + new String[]{ "NoPaDDing" }).runAll(); } } --- old/test/jdk/com/sun/crypto/provider/Cipher/DES/TestCipherDESede.java 2019-07-24 00:27:06.952178853 +0000 +++ new/test/jdk/com/sun/crypto/provider/Cipher/DES/TestCipherDESede.java 2019-07-24 00:27:06.052148813 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,19 +30,22 @@ public class TestCipherDESede extends TestCipher { - TestCipherDESede() { - super("DESede", - new String[]{"CBC", "CTR", "CTS", "ECB", "PCBC", - //CFBx - "CFB", "CFB8", "CFB16", "CFB24", "CFB32", "CFB40", "CFB48", "CFB56", - "CFB64", - //OFBx - "OFB", "OFB8", "OFB16", "OFB24", "OFB32", "OFB40", "OFB48", "OFB56", - "OFB64"}, - new String[]{"NoPaDDing", "PKCS5Padding"}); + TestCipherDESede(String[] modes, String[] paddings) { + super("DESede", modes, paddings); } public static void main(String[] args) throws Exception { - new TestCipherDESede().runAll(); + new TestCipherDESede( + new String[]{ "CBC", "ECB", "PCBC", + //CFBx + "CFB", "CFB8", "CFB16", "CFB24", "CFB32", "CFB40", + "CFB48", "CFB56", "CFB64", + //OFBx + "OFB", "OFB8", "OFB16", "OFB24", "OFB32", "OFB40", + "OFB48", "OFB56", "OFB64"}, + new String[]{ "NoPaDDing", "PKCS5Padding" }).runAll(); + new TestCipherDESede( + new String[]{ "CTR", "CTS" }, + new String[]{ "NoPaDDing" }).runAll(); } } --- old/test/jdk/javax/crypto/Cipher/CipherInputStreamExceptions.java 2019-07-24 00:27:09.728271507 +0000 +++ new/test/jdk/javax/crypto/Cipher/CipherInputStreamExceptions.java 2019-07-24 00:27:08.830241535 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -55,7 +55,7 @@ /* Full read stream, check that getMoreData() is throwing an exception * This test - * 1) Encrypt 100 bytes with AES/GCM/PKCS5Padding + * 1) Encrypt 100 bytes with AES/GCM/NoPadding * 2) Changes the last byte to invalidate the authetication tag. * 3) Fully reads CipherInputStream to decrypt the message and closes */ @@ -66,7 +66,7 @@ System.out.println("Running gcm_AEADBadTag"); - // Encrypt 100 bytes with AES/GCM/PKCS5Padding + // Encrypt 100 bytes with AES/GCM/NoPadding byte[] ct = encryptedText("GCM", 100); // Corrupt the encrypted message ct = corruptGCM(ct); @@ -92,7 +92,7 @@ /* Short read stream, * This test - * 1) Encrypt 100 bytes with AES/GCM/PKCS5Padding + * 1) Encrypt 100 bytes with AES/GCM/NoPadding * 2) Reads 100 bytes from stream to decrypt the message and closes * 3) Make sure no value is returned by read() * 4) Make sure no exception is thrown @@ -106,7 +106,7 @@ byte[] pt = new byte[600]; pt[0] = 1; - // Encrypt provided 600 bytes with AES/GCM/PKCS5Padding + // Encrypt provided 600 bytes with AES/GCM/NoPadding byte[] ct = encryptedText("GCM", pt); // Create stream for decryption CipherInputStream in = getStream("GCM", ct); @@ -134,7 +134,7 @@ * Verify doFinal() exception is suppressed when input stream is not * read before it is closed. * This test: - * 1) Encrypt 100 bytes with AES/GCM/PKCS5Padding + * 1) Encrypt 100 bytes with AES/GCM/NoPadding * 2) Changes the last byte to invalidate the authetication tag. * 3) Opens a CipherInputStream and the closes it. Never reads from it. * @@ -146,7 +146,7 @@ System.out.println("Running supressUnreadCorrupt test"); - // Encrypt 100 bytes with AES/GCM/PKCS5Padding + // Encrypt 100 bytes with AES/GCM/NoPadding byte[] ct = encryptedText("GCM", 100); // Corrupt the encrypted message ct = corruptGCM(ct); @@ -166,7 +166,7 @@ * Verify noexception thrown when 1 byte is read from a GCM stream * and then closed * This test: - * 1) Encrypt 100 bytes with AES/GCM/PKCS5Padding + * 1) Encrypt 100 bytes with AES/GCM/NoPadding * 2) Read one byte from the stream, expect no exception thrown. * 4) Close stream,expect no exception thrown. */ @@ -174,7 +174,7 @@ System.out.println("Running gcm_oneReadByte test"); - // Encrypt 100 bytes with AES/GCM/PKCS5Padding + // Encrypt 100 bytes with AES/GCM/NoPadding byte[] ct = encryptedText("GCM", 100); // Create stream for decryption CipherInputStream in = getStream("GCM", ct); @@ -192,7 +192,7 @@ * Verify exception thrown when 1 byte is read from a corrupted GCM stream * and then closed * This test: - * 1) Encrypt 100 bytes with AES/GCM/PKCS5Padding + * 1) Encrypt 100 bytes with AES/GCM/NoPadding * 2) Changes the last byte to invalidate the authetication tag. * 3) Read one byte from the stream, expect exception thrown. * 4) Close stream,expect no exception thrown. @@ -201,7 +201,7 @@ System.out.println("Running gcm_oneReadByteCorrupt test"); - // Encrypt 100 bytes with AES/GCM/PKCS5Padding + // Encrypt 100 bytes with AES/GCM/NoPadding byte[] ct = encryptedText("GCM", 100); // Corrupt the encrypted message ct = corruptGCM(ct); @@ -357,7 +357,7 @@ static byte[] encryptedText(String mode, byte[] pt) throws Exception{ Cipher c; if (mode.compareTo("GCM") == 0) { - c = Cipher.getInstance("AES/GCM/PKCS5Padding", "SunJCE"); + c = Cipher.getInstance("AES/GCM/NoPadding", "SunJCE"); c.init(Cipher.ENCRYPT_MODE, key, gcmspec); } else if (mode.compareTo("CBC") == 0) { c = Cipher.getInstance("AES/CBC/PKCS5Padding", "SunJCE"); @@ -380,7 +380,7 @@ Cipher c; if (mode.compareTo("GCM") == 0) { - c = Cipher.getInstance("AES/GCM/PKCS5Padding", "SunJCE"); + c = Cipher.getInstance("AES/GCM/NoPadding", "SunJCE"); c.init(Cipher.DECRYPT_MODE, key, gcmspec); } else if (mode.compareTo("CBC") == 0) { c = Cipher.getInstance("AES/CBC/PKCS5Padding", "SunJCE"); --- /dev/null 2019-07-16 18:46:40.604000000 +0000 +++ new/test/jdk/com/sun/crypto/provider/Cipher/AES/TestNoPaddingModes.java 2019-07-24 00:27:11.616334523 +0000 @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8180392 + * @summary Ensure SunJCE provider throws exception for unsupported modes + * and padding combinations + */ +import java.security.*; +import java.security.spec.AlgorithmParameterSpec; +import javax.crypto.*; + +public class TestNoPaddingModes { + + // SunJCE only supports NoPadding with following modes + private static final String[] MODES = { + "CTR", "CTS", "GCM" + }; + private static final String[] PADDINGS = { + "PKCS5Padding", "ISO10126Padding" + }; + + public static void main(String[] args) throws Exception { + Provider p = Security.getProvider("SunJCE"); + String transformation; + for (String mode : MODES) { + for (String padding : PADDINGS) { + transformation = "AES/" + mode + "/" + padding; + + System.out.println("Test using " + transformation); + try { + Cipher c = Cipher.getInstance(transformation, "SunJCE"); + throw new RuntimeException("=> Fail, no exception thrown"); + } catch (NoSuchAlgorithmException | NoSuchPaddingException ex) { + System.out.println("=> Expected ex: " + ex); + } + try { + Cipher c = Cipher.getInstance(transformation, p); + throw new RuntimeException("=> Fail, no exception thrown"); + } catch (NoSuchAlgorithmException | NoSuchPaddingException ex) { + System.out.println("=> Expected ex: " + ex); + } + } + } + System.out.println("Test Passed"); + } + + public static class MyCipImpl extends CipherSpi { + public MyCipImpl() { + super(); + System.out.println("MyCipImpl is created"); + } + protected void engineSetMode(String mode) + throws NoSuchAlgorithmException {}; + protected void engineSetPadding(String padding) + throws NoSuchPaddingException {}; + protected int engineGetBlockSize() { return 16; } + protected int engineGetOutputSize(int inputLen) { return 0; } + protected byte[] engineGetIV() { return null; } + protected AlgorithmParameters engineGetParameters() { return null; } + protected void engineInit(int opmode, Key key, SecureRandom random) + throws InvalidKeyException {}; + protected void engineInit(int opmode, Key key, + AlgorithmParameterSpec params, + SecureRandom random) + throws InvalidKeyException, InvalidAlgorithmParameterException {}; + protected void engineInit(int opmode, Key key, + AlgorithmParameters params, + SecureRandom random) + throws InvalidKeyException, InvalidAlgorithmParameterException {}; + protected byte[] engineUpdate(byte[] input, int inputOffset, + int inputLen) { return null; } + protected int engineUpdate(byte[] input, int inputOffset, + int inputLen, byte[] output, + int outputOffset) + throws ShortBufferException { return 0; }; + protected byte[] engineDoFinal(byte[] input, int inputOffset, + int inputLen) + throws IllegalBlockSizeException, BadPaddingException { + return null; + } + protected int engineDoFinal(byte[] input, int inputOffset, + int inputLen, byte[] output, + int outputOffset) + throws ShortBufferException, IllegalBlockSizeException, + BadPaddingException { return 0; } + } +}