summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKenny Root <kroot@google.com>2013-09-30 14:45:50 -0700
committerKenny Root <kroot@google.com>2013-09-30 17:03:53 -0700
commit96b54bb1fad5cf63473f99a4155ce888f4f85d7e (patch)
treeb210c970a4b8638f4c0dd7e522a2449eda94b7e5
parent40b8d8da849f14fb455bbeca6e733239cc6f1bdc (diff)
downloadlibcore-96b54bb1fad5cf63473f99a4155ce888f4f85d7e.zip
libcore-96b54bb1fad5cf63473f99a4155ce888f4f85d7e.tar.gz
libcore-96b54bb1fad5cf63473f99a4155ce888f4f85d7e.tar.bz2
Remove unsupported Cipher modes
OpenSSL silently ignores the padding modes when specified for stream ciphers, but apparently Java does not. Change-Id: Icd92122d63b3b8e99d704e8193414dda5057146d
-rw-r--r--crypto/src/main/java/org/conscrypt/OpenSSLCipher.java80
-rw-r--r--crypto/src/main/java/org/conscrypt/OpenSSLProvider.java19
-rw-r--r--luni/src/test/java/libcore/javax/crypto/CipherTest.java75
3 files changed, 88 insertions, 86 deletions
diff --git a/crypto/src/main/java/org/conscrypt/OpenSSLCipher.java b/crypto/src/main/java/org/conscrypt/OpenSSLCipher.java
index 7acccc7..e3f76bf 100644
--- a/crypto/src/main/java/org/conscrypt/OpenSSLCipher.java
+++ b/crypto/src/main/java/org/conscrypt/OpenSSLCipher.java
@@ -543,38 +543,14 @@ public abstract class OpenSSLCipher extends CipherSpi {
}
public static class CFB extends AES {
- public CFB(Padding padding) {
- super(Mode.CFB, padding);
- }
-
- public static class NoPadding extends CFB {
- public NoPadding() {
- super(Padding.NOPADDING);
- }
- }
-
- public static class PKCS5Padding extends CFB {
- public PKCS5Padding() {
- super(Padding.PKCS5PADDING);
- }
+ public CFB() {
+ super(Mode.CFB, Padding.NOPADDING);
}
}
public static class CTR extends AES {
- public CTR(Padding padding) {
- super(Mode.CTR, padding);
- }
-
- public static class NoPadding extends CTR {
- public NoPadding() {
- super(Padding.NOPADDING);
- }
- }
-
- public static class PKCS5Padding extends CTR {
- public PKCS5Padding() {
- super(Padding.PKCS5PADDING);
- }
+ public CTR() {
+ super(Mode.CTR, Padding.NOPADDING);
}
}
@@ -597,20 +573,8 @@ public abstract class OpenSSLCipher extends CipherSpi {
}
public static class OFB extends AES {
- public OFB(Padding padding) {
- super(Mode.OFB, padding);
- }
-
- public static class NoPadding extends OFB {
- public NoPadding() {
- super(Padding.NOPADDING);
- }
- }
-
- public static class PKCS5Padding extends OFB {
- public PKCS5Padding() {
- super(Padding.PKCS5PADDING);
- }
+ public OFB() {
+ super(Mode.OFB, Padding.NOPADDING);
}
}
@@ -696,20 +660,8 @@ public abstract class OpenSSLCipher extends CipherSpi {
}
public static class CFB extends DESEDE {
- public CFB(Padding padding) {
- super(Mode.CFB, padding);
- }
-
- public static class NoPadding extends CFB {
- public NoPadding() {
- super(Padding.NOPADDING);
- }
- }
-
- public static class PKCS5Padding extends CFB {
- public PKCS5Padding() {
- super(Padding.PKCS5PADDING);
- }
+ public CFB() {
+ super(Mode.CFB, Padding.NOPADDING);
}
}
@@ -732,20 +684,8 @@ public abstract class OpenSSLCipher extends CipherSpi {
}
public static class OFB extends DESEDE {
- public OFB(Padding padding) {
- super(Mode.OFB, padding);
- }
-
- public static class NoPadding extends OFB {
- public NoPadding() {
- super(Padding.NOPADDING);
- }
- }
-
- public static class PKCS5Padding extends OFB {
- public PKCS5Padding() {
- super(Padding.PKCS5PADDING);
- }
+ public OFB() {
+ super(Mode.OFB, Padding.NOPADDING);
}
}
diff --git a/crypto/src/main/java/org/conscrypt/OpenSSLProvider.java b/crypto/src/main/java/org/conscrypt/OpenSSLProvider.java
index 371da1f..90e08a2 100644
--- a/crypto/src/main/java/org/conscrypt/OpenSSLProvider.java
+++ b/crypto/src/main/java/org/conscrypt/OpenSSLProvider.java
@@ -202,21 +202,16 @@ public final class OpenSSLProvider extends Provider {
put("Cipher.AES/ECB/PKCS5Padding", prefix + "OpenSSLCipher$AES$ECB$PKCS5Padding");
put("Cipher.AES/CBC/NoPadding", prefix + "OpenSSLCipher$AES$CBC$NoPadding");
put("Cipher.AES/CBC/PKCS5Padding", prefix + "OpenSSLCipher$AES$CBC$PKCS5Padding");
- put("Cipher.AES/CFB/NoPadding", prefix + "OpenSSLCipher$AES$CFB$NoPadding");
- put("Cipher.AES/CFB/PKCS5Padding", prefix + "OpenSSLCipher$AES$CFB$PKCS5Padding");
- put("Cipher.AES/CTR/NoPadding", prefix + "OpenSSLCipher$AES$CTR$NoPadding");
- put("Cipher.AES/CTR/PKCS5Padding", prefix + "OpenSSLCipher$AES$CTR$PKCS5Padding");
- put("Cipher.AES/OFB/NoPadding", prefix + "OpenSSLCipher$AES$OFB$NoPadding");
- put("Cipher.AES/OFB/PKCS5Padding", prefix + "OpenSSLCipher$AES$OFB$PKCS5Padding");
+ put("Cipher.AES/CFB/NoPadding", prefix + "OpenSSLCipher$AES$CFB");
+ put("Cipher.AES/CTR/NoPadding", prefix + "OpenSSLCipher$AES$CTR");
+ put("Cipher.AES/OFB/NoPadding", prefix + "OpenSSLCipher$AES$OFB");
- put("Cipher.DESEDE/CBC/NoPadding", prefix + "OpenSSLCipher$DESEDE$CBC$NoPadding");
- put("Cipher.DESEDE/CBC/PKCS5Padding", prefix + "OpenSSLCipher$DESEDE$CBC$PKCS5Padding");
- put("Cipher.DESEDE/CFB/NoPadding", prefix + "OpenSSLCipher$DESEDE$CFB$NoPadding");
- put("Cipher.DESEDE/CFB/PKCS5Padding", prefix + "OpenSSLCipher$DESEDE$CFB$PKCS5Padding");
put("Cipher.DESEDE/ECB/NoPadding", prefix + "OpenSSLCipher$DESEDE$ECB$NoPadding");
put("Cipher.DESEDE/ECB/PKCS5Padding", prefix + "OpenSSLCipher$DESEDE$ECB$PKCS5Padding");
- put("Cipher.DESEDE/OFB/NoPadding", prefix + "OpenSSLCipher$DESEDE$OFB$NoPadding");
- put("Cipher.DESEDE/OFB/PKCS5Padding", prefix + "OpenSSLCipher$DESEDE$OFB$PKCS5Padding");
+ put("Cipher.DESEDE/CBC/NoPadding", prefix + "OpenSSLCipher$DESEDE$CBC$NoPadding");
+ put("Cipher.DESEDE/CBC/PKCS5Padding", prefix + "OpenSSLCipher$DESEDE$CBC$PKCS5Padding");
+ put("Cipher.DESEDE/CFB/NoPadding", prefix + "OpenSSLCipher$DESEDE$CFB");
+ put("Cipher.DESEDE/OFB/NoPadding", prefix + "OpenSSLCipher$DESEDE$OFB");
put("Cipher.ARC4", prefix + "OpenSSLCipher$ARC4");
diff --git a/luni/src/test/java/libcore/javax/crypto/CipherTest.java b/luni/src/test/java/libcore/javax/crypto/CipherTest.java
index 7922a04..193c403 100644
--- a/luni/src/test/java/libcore/javax/crypto/CipherTest.java
+++ b/luni/src/test/java/libcore/javax/crypto/CipherTest.java
@@ -32,8 +32,6 @@ import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.Security;
import java.security.cert.Certificate;
-import java.security.interfaces.RSAPrivateKey;
-import java.security.interfaces.RSAPublicKey;
import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.RSAPrivateKeySpec;
import java.security.spec.RSAPublicKeySpec;
@@ -138,7 +136,7 @@ public final class CipherTest extends TestCase {
return false;
}
// AESWRAP should be used instead, fails with BC and SunJCE otherwise.
- if (algorithm.startsWith("AES")) {
+ if (algorithm.startsWith("AES") || algorithm.startsWith("DESEDE")) {
return false;
}
return true;
@@ -165,6 +163,9 @@ public final class CipherTest extends TestCase {
if (algorithm.startsWith("AES/")) {
return "AES";
}
+ if (algorithm.startsWith("DESEDE/")) {
+ return "DESEDE";
+ }
if (algorithm.equals("PBEWITHMD5AND128BITAES-CBC-OPENSSL")) {
return "AES";
}
@@ -240,6 +241,11 @@ public final class CipherTest extends TestCase {
return algorithm.startsWith("PBE");
}
+ private static boolean isStreamMode(String algorithm) {
+ return algorithm.contains("/CTR/") || algorithm.contains("/OFB")
+ || algorithm.contains("/CFB");
+ }
+
private static Map<String, Key> ENCRYPT_KEYS = new HashMap<String, Key>();
private synchronized static Key getEncryptKey(String algorithm) throws Exception {
Key key = ENCRYPT_KEYS.get(algorithm);
@@ -324,6 +330,18 @@ public final class CipherTest extends TestCase {
setExpectedBlockSize("PBEWITHSHA1ANDDES", 8);
setExpectedBlockSize("DESEDE", 8);
+ setExpectedBlockSize("DESEDE/CBC/PKCS5PADDING", 8);
+ setExpectedBlockSize("DESEDE/CBC/NOPADDING", 8);
+ setExpectedBlockSize("DESEDE/CFB/PKCS5PADDING", 8);
+ setExpectedBlockSize("DESEDE/CFB/NOPADDING", 8);
+ setExpectedBlockSize("DESEDE/CTR/PKCS5PADDING", 8);
+ setExpectedBlockSize("DESEDE/CTR/NOPADDING", 8);
+ setExpectedBlockSize("DESEDE/CTS/PKCS5PADDING", 8);
+ setExpectedBlockSize("DESEDE/CTS/NOPADDING", 8);
+ setExpectedBlockSize("DESEDE/ECB/PKCS5PADDING", 8);
+ setExpectedBlockSize("DESEDE/ECB/NOPADDING", 8);
+ setExpectedBlockSize("DESEDE/OFB/PKCS5PADDING", 8);
+ setExpectedBlockSize("DESEDE/OFB/NOPADDING", 8);
setExpectedBlockSize("PBEWITHSHAAND2-KEYTRIPLEDES-CBC", 8);
setExpectedBlockSize("PBEWITHSHAAND3-KEYTRIPLEDES-CBC", 8);
setExpectedBlockSize("PBEWITHMD5ANDTRIPLEDES", 8);
@@ -462,6 +480,8 @@ public final class CipherTest extends TestCase {
// AndroidOpenSSL returns the block size for the block ciphers
setExpectedOutputSize("AES/CBC/PKCS5PADDING", Cipher.DECRYPT_MODE, "AndroidOpenSSL", 16);
setExpectedOutputSize("AES/ECB/PKCS5PADDING", Cipher.DECRYPT_MODE, "AndroidOpenSSL", 16);
+ setExpectedOutputSize("DESEDE/CBC/PKCS5PADDING", Cipher.DECRYPT_MODE, "AndroidOpenSSL", 8);
+ setExpectedOutputSize("DESEDE/ECB/PKCS5PADDING", Cipher.DECRYPT_MODE, "AndroidOpenSSL", 8);
if (StandardNames.IS_RI) {
setExpectedOutputSize("AESWRAP", Cipher.WRAP_MODE, 8);
@@ -486,13 +506,32 @@ public final class CipherTest extends TestCase {
setExpectedOutputSize("PBEWITHMD5ANDDES", Cipher.DECRYPT_MODE, 0);
setExpectedOutputSize("PBEWITHSHA1ANDDES", Cipher.DECRYPT_MODE, 0);
+ setExpectedOutputSize("DESEDE/CBC/NOPADDING", 0);
+ setExpectedOutputSize("DESEDE/CFB/NOPADDING", 0);
+ setExpectedOutputSize("DESEDE/CTR/NOPADDING", 0);
+ setExpectedOutputSize("DESEDE/CTS/NOPADDING", 0);
+ setExpectedOutputSize("DESEDE/ECB/NOPADDING", 0);
+ setExpectedOutputSize("DESEDE/OFB/NOPADDING", 0);
+
setExpectedOutputSize("DESEDE", Cipher.ENCRYPT_MODE, 8);
+ setExpectedOutputSize("DESEDE/CBC/PKCS5PADDING", Cipher.ENCRYPT_MODE, 8);
+ setExpectedOutputSize("DESEDE/CFB/PKCS5PADDING", Cipher.ENCRYPT_MODE, 8);
+ setExpectedOutputSize("DESEDE/CTR/PKCS5PADDING", Cipher.ENCRYPT_MODE, 8);
+ setExpectedOutputSize("DESEDE/CTS/PKCS5PADDING", Cipher.ENCRYPT_MODE, 8);
+ setExpectedOutputSize("DESEDE/ECB/PKCS5PADDING", Cipher.ENCRYPT_MODE, 8);
+ setExpectedOutputSize("DESEDE/OFB/PKCS5PADDING", Cipher.ENCRYPT_MODE, 8);
setExpectedOutputSize("PBEWITHSHAAND2-KEYTRIPLEDES-CBC", Cipher.ENCRYPT_MODE, 8);
setExpectedOutputSize("PBEWITHSHAAND3-KEYTRIPLEDES-CBC", Cipher.ENCRYPT_MODE, 8);
setExpectedOutputSize("PBEWITHMD5ANDTRIPLEDES", Cipher.ENCRYPT_MODE, 8);
setExpectedOutputSize("PBEWITHSHA1ANDDESEDE", Cipher.ENCRYPT_MODE, 8);
setExpectedOutputSize("DESEDE", Cipher.DECRYPT_MODE, 0);
+ setExpectedOutputSize("DESEDE/CBC/PKCS5PADDING", Cipher.DECRYPT_MODE, 0);
+ setExpectedOutputSize("DESEDE/CFB/PKCS5PADDING", Cipher.DECRYPT_MODE, 0);
+ setExpectedOutputSize("DESEDE/CTR/PKCS5PADDING", Cipher.DECRYPT_MODE, 0);
+ setExpectedOutputSize("DESEDE/CTS/PKCS5PADDING", Cipher.DECRYPT_MODE, 0);
+ setExpectedOutputSize("DESEDE/ECB/PKCS5PADDING", Cipher.DECRYPT_MODE, 0);
+ setExpectedOutputSize("DESEDE/OFB/PKCS5PADDING", Cipher.DECRYPT_MODE, 0);
setExpectedOutputSize("PBEWITHSHAAND2-KEYTRIPLEDES-CBC", Cipher.DECRYPT_MODE, 0);
setExpectedOutputSize("PBEWITHSHAAND3-KEYTRIPLEDES-CBC", Cipher.DECRYPT_MODE, 0);
setExpectedOutputSize("PBEWITHMD5ANDTRIPLEDES", Cipher.DECRYPT_MODE, 0);
@@ -542,6 +581,8 @@ public final class CipherTest extends TestCase {
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00 };
+ private static byte[] EIGHT_BYTE_BLOCK_PLAIN_TEXT = new byte[] { 0x0a, 0x0b, 0x0c, 0x00,
+ 0x00, 0x00, 0x00, 0x00 };
private static byte[] PKCS1_BLOCK_TYPE_00_PADDED_PLAIN_TEXT = new byte[] {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -638,6 +679,11 @@ public final class CipherTest extends TestCase {
|| algorithm.equals("AES/ECB/NOPADDING")) {
return SIXTEEN_BYTE_BLOCK_PLAIN_TEXT;
}
+ if (algorithm.equals("DESEDE")
+ || algorithm.equals("DESEDE/CBC/NOPADDING")
+ || algorithm.equals("DESEDE/ECB/NOPADDING")) {
+ return EIGHT_BYTE_BLOCK_PLAIN_TEXT;
+ }
return ORIGINAL_PLAIN_TEXT;
}
@@ -649,6 +695,11 @@ public final class CipherTest extends TestCase {
|| algorithm.equals("AES/ECB/NOPADDING")) {
return SIXTEEN_BYTE_BLOCK_PLAIN_TEXT;
}
+ if (algorithm.equals("DESEDE")
+ || algorithm.equals("DESEDE/CBC/NOPADDING")
+ || algorithm.equals("DESEDE/ECB/NOPADDING")) {
+ return EIGHT_BYTE_BLOCK_PLAIN_TEXT;
+ }
// BC strips the leading 0 for us even when NoPadding is specified
if (!provider.equals("BC") && algorithm.equals("RSA/ECB/NOPADDING")) {
return PKCS1_BLOCK_TYPE_00_PADDED_PLAIN_TEXT;
@@ -672,6 +723,16 @@ public final class CipherTest extends TestCase {
new SecureRandom().nextBytes(iv);
return new IvParameterSpec(iv);
}
+ if (algorithm.equals("DESEDE/CBC/NOPADDING")
+ || algorithm.equals("DESEDE/CBC/PKCS5PADDING")
+ || algorithm.equals("DESEDE/CFB/NOPADDING")
+ || algorithm.equals("DESEDE/CTR/NOPADDING")
+ || algorithm.equals("DESEDE/CTS/NOPADDING")
+ || algorithm.equals("DESEDE/OFB/NOPADDING")) {
+ final byte[] iv = new byte[8];
+ new SecureRandom().nextBytes(iv);
+ return new IvParameterSpec(iv);
+ }
return null;
}
@@ -723,7 +784,9 @@ public final class CipherTest extends TestCase {
if (!seenBaseCipherNames.contains(baseCipherName)) {
seenCiphersWithModeAndPadding.add(baseCipherName);
}
- continue;
+ if (!"AndroidOpenSSL".equals(provider.getName())) {
+ continue;
+ }
}
try {
@@ -837,6 +900,10 @@ public final class CipherTest extends TestCase {
getExpectedBlockSize(algorithm, encryptMode, providerName), c.getBlockSize());
assertEquals(cipherID + " getOutputSize(0) encryptMode",
getExpectedOutputSize(algorithm, encryptMode, providerName), c.getOutputSize(0));
+ if (algorithm.endsWith("/PKCS5PADDING") && isStreamMode(algorithm)) {
+ assertEquals(getExpectedOutputSize(algorithm, encryptMode, providerName),
+ c.doFinal(new byte[1]).length);
+ }
final AlgorithmParameterSpec decryptSpec = getDecryptAlgorithmParameterSpec(encryptSpec, c);
int decryptMode = getDecryptMode(algorithm);