6994008: PKCS11 should support "RSA" and "RSA/ECB/NoPadding" ciphers
Summary: Add support for RSA_X_509 mechanism and aliasing of "RSA" to "RSA/ECB/PKCS1Padding".
Reviewed-by: wetmore
--- a/jdk/src/share/classes/sun/security/pkcs11/P11RSACipher.java Mon Mar 07 11:36:37 2011 -0800
+++ b/jdk/src/share/classes/sun/security/pkcs11/P11RSACipher.java Mon Mar 07 14:14:37 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2011, 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
@@ -62,6 +62,11 @@
// mode constant for public key decryption (verifying)
private final static int MODE_VERIFY = 4;
+ // padding type constant for NoPadding
+ private final static int PAD_NONE = 1;
+ // padding type constant for PKCS1Padding
+ private final static int PAD_PKCS1 = 2;
+
// token instance
private final Token token;
@@ -77,6 +82,9 @@
// mode, one of MODE_* above
private int mode;
+ // padding, one of PAD_* above
+ private int padType;
+
private byte[] buffer;
private int bufOfs;
@@ -113,8 +121,10 @@
protected void engineSetPadding(String padding)
throws NoSuchPaddingException {
String lowerPadding = padding.toLowerCase(Locale.ENGLISH);
- if (lowerPadding.equals("pkcs1Padding")) {
- // empty
+ if (lowerPadding.equals("pkcs1padding")) {
+ padType = PAD_PKCS1;
+ } else if (lowerPadding.equals("nopadding")) {
+ padType = PAD_NONE;
} else {
throw new NoSuchPaddingException("Unsupported padding " + padding);
}
@@ -209,7 +219,8 @@
int n = (p11Key.keyLength() + 7) >> 3;
outputSize = n;
buffer = new byte[n];
- maxInputSize = encrypt ? (n - PKCS1_MIN_PADDING_LENGTH) : n;
+ maxInputSize = ((padType == PAD_PKCS1 && encrypt) ?
+ (n - PKCS1_MIN_PADDING_LENGTH) : n);
try {
initialize();
} catch (PKCS11Exception e) {
--- a/jdk/src/share/classes/sun/security/pkcs11/SunPKCS11.java Mon Mar 07 11:36:37 2011 -0800
+++ b/jdk/src/share/classes/sun/security/pkcs11/SunPKCS11.java Mon Mar 07 14:14:37 2011 -0800
@@ -627,8 +627,10 @@
m(CKM_BLOWFISH_CBC));
// XXX RSA_X_509, RSA_OAEP not yet supported
- d(CIP, "RSA/ECB/PKCS1Padding", P11RSACipher,
+ d(CIP, "RSA/ECB/PKCS1Padding", P11RSACipher, s("RSA"),
m(CKM_RSA_PKCS));
+ d(CIP, "RSA/ECB/NoPadding", P11RSACipher,
+ m(CKM_RSA_X_509));
d(SIG, "RawDSA", P11Signature, s("NONEwithDSA"),
m(CKM_DSA));
--- a/jdk/test/sun/security/pkcs11/Cipher/TestRSACipher.java Mon Mar 07 11:36:37 2011 -0800
+++ b/jdk/test/sun/security/pkcs11/Cipher/TestRSACipher.java Mon Mar 07 14:14:37 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2011, 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
@@ -23,7 +23,7 @@
/**
* @test
- * @bug 4898468
+ * @bug 4898468 6994008
* @summary basic test for RSA cipher
* @author Andreas Sterbenz
* @library ..
@@ -38,9 +38,12 @@
public class TestRSACipher extends PKCS11Test {
+ private static final String[] RSA_ALGOS =
+ { "RSA/ECB/PKCS1Padding", "RSA" };
+
public void main(Provider p) throws Exception {
try {
- Cipher.getInstance("RSA/ECB/PKCS1Padding", p);
+ Cipher.getInstance(RSA_ALGOS[0], p);
} catch (GeneralSecurityException e) {
System.out.println("Not supported by provider, skipping");
return;
@@ -55,57 +58,58 @@
b = new byte[16];
random.nextBytes(b);
- Cipher c1 = Cipher.getInstance("RSA/ECB/PKCS1Padding", p);
- Cipher c2 = Cipher.getInstance("RSA/ECB/PKCS1Padding", "SunJCE");
+ for (String rsaAlgo: RSA_ALGOS) {
+ Cipher c1 = Cipher.getInstance(rsaAlgo, p);
+ Cipher c2 = Cipher.getInstance(rsaAlgo, "SunJCE");
- c1.init(Cipher.ENCRYPT_MODE, publicKey);
- e = c1.doFinal(b);
- c1.init(Cipher.DECRYPT_MODE, privateKey);
- d = c1.doFinal(e);
- match(b, d);
- c2.init(Cipher.DECRYPT_MODE, privateKey);
- d = c2.doFinal(e);
- match(b, d);
+ c1.init(Cipher.ENCRYPT_MODE, publicKey);
+ e = c1.doFinal(b);
+ c1.init(Cipher.DECRYPT_MODE, privateKey);
+ d = c1.doFinal(e);
+ match(b, d);
+ c2.init(Cipher.DECRYPT_MODE, privateKey);
+ d = c2.doFinal(e);
+ match(b, d);
- // invalid data
- c1.init(Cipher.DECRYPT_MODE, publicKey);
- try {
- d = c1.doFinal(e);
- throw new Exception("completed call");
- } catch (BadPaddingException ee) {
- ee.printStackTrace();
- }
+ // invalid data
+ c1.init(Cipher.DECRYPT_MODE, publicKey);
+ try {
+ d = c1.doFinal(e);
+ throw new Exception("completed call");
+ } catch (BadPaddingException ee) {
+ ee.printStackTrace();
+ }
- c1.init(Cipher.ENCRYPT_MODE, privateKey);
- e = c1.doFinal(b);
- c1.init(Cipher.DECRYPT_MODE, publicKey);
- d = c1.doFinal(e);
- match(b, d);
- c2.init(Cipher.DECRYPT_MODE, publicKey);
- d = c2.doFinal(e);
- match(b, d);
+ c1.init(Cipher.ENCRYPT_MODE, privateKey);
+ e = c1.doFinal(b);
+ c1.init(Cipher.DECRYPT_MODE, publicKey);
+ d = c1.doFinal(e);
+ match(b, d);
+ c2.init(Cipher.DECRYPT_MODE, publicKey);
+ d = c2.doFinal(e);
+ match(b, d);
- // reinit tests
- c1.init(Cipher.ENCRYPT_MODE, privateKey);
- c1.init(Cipher.ENCRYPT_MODE, privateKey);
- e = c1.doFinal(b);
- e = c1.doFinal(b);
- c1.update(b);
- c1.update(b);
- c1.init(Cipher.ENCRYPT_MODE, privateKey);
- e = c1.doFinal();
- e = c1.doFinal();
- c1.update(b);
- e = c1.doFinal();
+ // reinit tests
+ c1.init(Cipher.ENCRYPT_MODE, privateKey);
+ c1.init(Cipher.ENCRYPT_MODE, privateKey);
+ e = c1.doFinal(b);
+ e = c1.doFinal(b);
+ c1.update(b);
+ c1.update(b);
+ c1.init(Cipher.ENCRYPT_MODE, privateKey);
+ e = c1.doFinal();
+ e = c1.doFinal();
+ c1.update(b);
+ e = c1.doFinal();
- c1.update(new byte[256]);
- try {
- e = c1.doFinal();
- throw new Exception("completed call");
- } catch (IllegalBlockSizeException ee) {
- System.out.println(ee);
+ c1.update(new byte[256]);
+ try {
+ e = c1.doFinal();
+ throw new Exception("completed call");
+ } catch (IllegalBlockSizeException ee) {
+ System.out.println(ee);
+ }
}
-
}
private static void match(byte[] b1, byte[] b2) throws Exception {
--- a/jdk/test/sun/security/pkcs11/Cipher/TestRSACipherWrap.java Mon Mar 07 11:36:37 2011 -0800
+++ b/jdk/test/sun/security/pkcs11/Cipher/TestRSACipherWrap.java Mon Mar 07 14:14:37 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2011, 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
@@ -23,7 +23,7 @@
/**
* @test
- * @bug 6572331
+ * @bug 6572331 6994008
* @summary basic test for RSA cipher key wrapping functionality
* @author Valerie Peng
* @library ..
@@ -38,47 +38,48 @@
public class TestRSACipherWrap extends PKCS11Test {
- private static final String RSA_ALGO = "RSA/ECB/PKCS1Padding";
+ private static final String[] RSA_ALGOS =
+ { "RSA/ECB/PKCS1Padding", "RSA" };
public void main(Provider p) throws Exception {
try {
- Cipher.getInstance(RSA_ALGO, p);
+ Cipher.getInstance(RSA_ALGOS[0], p);
} catch (GeneralSecurityException e) {
- System.out.println("Not supported by provider, skipping");
+ System.out.println(RSA_ALGOS[0] + " unsupported, skipping");
return;
}
KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA", p);
kpg.initialize(1024);
KeyPair kp = kpg.generateKeyPair();
- PublicKey publicKey = kp.getPublic();
- PrivateKey privateKey = kp.getPrivate();
- Cipher cipherPKCS11 = Cipher.getInstance(RSA_ALGO, p);
- Cipher cipherJce = Cipher.getInstance(RSA_ALGO, "SunJCE");
+ for (String rsaAlgo: RSA_ALGOS) {
+ Cipher cipherPKCS11 = Cipher.getInstance(rsaAlgo, p);
+ Cipher cipherJce = Cipher.getInstance(rsaAlgo, "SunJCE");
- String algos[] = {"AES", "RC2", "Blowfish"};
- int keySizes[] = {128, 256};
+ String algos[] = {"AES", "RC2", "Blowfish"};
+ int keySizes[] = {128, 256};
- for (int j = 0; j < algos.length; j++) {
- String algorithm = algos[j];
- KeyGenerator keygen =
+ for (int j = 0; j < algos.length; j++) {
+ String algorithm = algos[j];
+ KeyGenerator keygen =
KeyGenerator.getInstance(algorithm);
- for (int i = 0; i < keySizes.length; i++) {
- SecretKey secretKey = null;
- System.out.print("Generate " + keySizes[i] + "-bit " +
+ for (int i = 0; i < keySizes.length; i++) {
+ SecretKey secretKey = null;
+ System.out.print("Generate " + keySizes[i] + "-bit " +
algorithm + " key using ");
- try {
- keygen.init(keySizes[i]);
- secretKey = keygen.generateKey();
- System.out.println(keygen.getProvider().getName());
- } catch (InvalidParameterException ipe) {
- secretKey = new SecretKeySpec(new byte[32], algorithm);
- System.out.println("SecretKeySpec class");
+ try {
+ keygen.init(keySizes[i]);
+ secretKey = keygen.generateKey();
+ System.out.println(keygen.getProvider().getName());
+ } catch (InvalidParameterException ipe) {
+ secretKey = new SecretKeySpec(new byte[32], algorithm);
+ System.out.println("SecretKeySpec class");
+ }
+ test(kp, secretKey, cipherPKCS11, cipherJce);
+ test(kp, secretKey, cipherPKCS11, cipherPKCS11);
+ test(kp, secretKey, cipherJce, cipherPKCS11);
}
- test(kp, secretKey, cipherPKCS11, cipherJce);
- test(kp, secretKey, cipherPKCS11, cipherPKCS11);
- test(kp, secretKey, cipherJce, cipherPKCS11);
}
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/pkcs11/Cipher/TestRawRSACipher.java Mon Mar 07 14:14:37 2011 -0800
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2011, 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 6994008
+ * @summary basic test for RSA/ECB/NoPadding cipher
+ * @author Valerie Peng
+ * @library ..
+ */
+
+import javax.crypto.*;
+import java.io.*;
+import javax.crypto.spec.SecretKeySpec;
+import java.security.*;
+import java.util.*;
+
+public class TestRawRSACipher extends PKCS11Test {
+
+ public void main(Provider p) throws Exception {
+ try {
+ Cipher.getInstance("RSA/ECB/NoPadding", p);
+ } catch (GeneralSecurityException e) {
+ System.out.println("Not supported by provider, skipping");
+ return;
+ }
+
+ final int KEY_LEN = 1024;
+ KeyPairGenerator kpGen = KeyPairGenerator.getInstance("RSA", p);
+ kpGen.initialize(KEY_LEN);
+ KeyPair kp = kpGen.generateKeyPair();
+ Random random = new Random();
+ byte[] plainText, cipherText, recoveredText;
+ plainText = new byte[KEY_LEN/8];
+ random.nextBytes(plainText);
+ plainText[0] = 0; // to ensure that it's less than modulus
+
+ Cipher c1 = Cipher.getInstance("RSA/ECB/NoPadding", p);
+ Cipher c2 = Cipher.getInstance("RSA/ECB/NoPadding", "SunJCE");
+
+ c1.init(Cipher.ENCRYPT_MODE, kp.getPublic());
+ c2.init(Cipher.DECRYPT_MODE, kp.getPrivate());
+
+ cipherText = c1.doFinal(plainText);
+ recoveredText = c2.doFinal(cipherText);
+ if (!Arrays.equals(plainText, recoveredText)) {
+ throw new RuntimeException("E/D Test against SunJCE Failed!");
+ }
+
+ c2.init(Cipher.ENCRYPT_MODE, kp.getPublic());
+ c1.init(Cipher.DECRYPT_MODE, kp.getPrivate());
+ cipherText = c2.doFinal(plainText);
+ recoveredText = c1.doFinal(cipherText);
+ if (!Arrays.equals(plainText, recoveredText)) {
+ throw new RuntimeException("D/E Test against SunJCE Failed!");
+ }
+
+ System.out.println("Test Passed");
+ }
+
+ public static void main(String[] args) throws Exception {
+ main(new TestRawRSACipher());
+ }
+}