8071726: Better RSA optimizations
Summary: Added a check when RSA signature is generated with a RSAPrivateCRTKey object.
Reviewed-by: mullan
--- a/jdk/src/java.base/share/classes/com/sun/crypto/provider/RSACipher.java Wed Jan 28 12:36:25 2015 -0800
+++ b/jdk/src/java.base/share/classes/com/sun/crypto/provider/RSACipher.java Sat Feb 14 00:27:29 2015 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2015, 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
@@ -350,7 +350,7 @@
switch (mode) {
case MODE_SIGN:
data = padding.pad(buffer, 0, bufOfs);
- return RSACore.rsa(data, privateKey);
+ return RSACore.rsa(data, privateKey, true);
case MODE_VERIFY:
byte[] verifyBuffer = RSACore.convert(buffer, 0, bufOfs);
data = RSACore.rsa(verifyBuffer, publicKey);
@@ -360,7 +360,7 @@
return RSACore.rsa(data, publicKey);
case MODE_DECRYPT:
byte[] decryptBuffer = RSACore.convert(buffer, 0, bufOfs);
- data = RSACore.rsa(decryptBuffer, privateKey);
+ data = RSACore.rsa(decryptBuffer, privateKey, false);
return padding.unpad(data);
default:
throw new AssertionError("Internal error");
--- a/jdk/src/java.base/share/classes/sun/security/rsa/RSACore.java Wed Jan 28 12:36:25 2015 -0800
+++ b/jdk/src/java.base/share/classes/sun/security/rsa/RSACore.java Sat Feb 14 00:27:29 2015 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2015, 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
@@ -102,12 +102,24 @@
/**
* Perform an RSA private key operation. Uses CRT if the key is a
- * CRT key.
+ * CRT key with additional verification check after the signature
+ * is computed.
*/
+ @Deprecated
public static byte[] rsa(byte[] msg, RSAPrivateKey key)
throws BadPaddingException {
+ return rsa(msg, key, true);
+ }
+
+ /**
+ * Perform an RSA private key operation. Uses CRT if the key is a
+ * CRT key. Set 'verify' to true if this function is used for
+ * generating a signature.
+ */
+ public static byte[] rsa(byte[] msg, RSAPrivateKey key, boolean verify)
+ throws BadPaddingException {
if (key instanceof RSAPrivateCrtKey) {
- return crtCrypt(msg, (RSAPrivateCrtKey)key);
+ return crtCrypt(msg, (RSAPrivateCrtKey)key, verify);
} else {
return priCrypt(msg, key.getModulus(), key.getPrivateExponent());
}
@@ -148,10 +160,12 @@
* RSA private key operations with CRT. Algorithm and variable naming
* are taken from PKCS#1 v2.1, section 5.1.2.
*/
- private static byte[] crtCrypt(byte[] msg, RSAPrivateCrtKey key)
- throws BadPaddingException {
+ private static byte[] crtCrypt(byte[] msg, RSAPrivateCrtKey key,
+ boolean verify) throws BadPaddingException {
+ long start = System.nanoTime();
BigInteger n = key.getModulus();
- BigInteger c = parseMsg(msg, n);
+ BigInteger c0 = parseMsg(msg, n);
+ BigInteger c = c0;
BigInteger p = key.getPrimeP();
BigInteger q = key.getPrimeQ();
BigInteger dP = key.getPrimeExponentP();
@@ -184,6 +198,9 @@
if (ENABLE_BLINDING) {
m = m.multiply(brp.v).mod(n);
}
+ if (verify && !c0.equals(m.modPow(e, n))) {
+ throw new BadPaddingException("RSA private key operation failed");
+ }
return toByteArray(m, getByteLength(n));
}
--- a/jdk/src/java.base/share/classes/sun/security/rsa/RSASignature.java Wed Jan 28 12:36:25 2015 -0800
+++ b/jdk/src/java.base/share/classes/sun/security/rsa/RSASignature.java Sat Feb 14 00:27:29 2015 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2015, 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
@@ -173,7 +173,7 @@
try {
byte[] encoded = encodeSignature(digestOID, digest);
byte[] padded = padding.pad(encoded);
- byte[] encrypted = RSACore.rsa(padded, privateKey);
+ byte[] encrypted = RSACore.rsa(padded, privateKey, true);
return encrypted;
} catch (GeneralSecurityException e) {
throw new SignatureException("Could not sign data", e);