From cec6e51bd1e40afd2776d8e7a2d403a8e46de7b4 Mon Sep 17 00:00:00 2001 From: valeriep Date: Sat, 14 Feb 2015 01:18:19 +0000 Subject: 8071726: Better RSA optimizations Summary: Added a check when RSA signature is generated with a RSAPrivateCRTKey object. Reviewed-by: mullan --- .../classes/com/sun/crypto/provider/RSACipher.java | 6 ++--- src/share/classes/sun/security/rsa/RSACore.java | 28 +++++++++++++++++----- .../classes/sun/security/rsa/RSASignature.java | 4 ++-- 3 files changed, 27 insertions(+), 11 deletions(-) diff --git a/src/share/classes/com/sun/crypto/provider/RSACipher.java b/src/share/classes/com/sun/crypto/provider/RSACipher.java index d1d8cf3ef..5a83d8bf0 100644 --- a/src/share/classes/com/sun/crypto/provider/RSACipher.java +++ b/src/share/classes/com/sun/crypto/provider/RSACipher.java @@ -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 @@ -349,7 +349,7 @@ public final class RSACipher extends CipherSpi { 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); @@ -359,7 +359,7 @@ public final class RSACipher extends CipherSpi { 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"); diff --git a/src/share/classes/sun/security/rsa/RSACore.java b/src/share/classes/sun/security/rsa/RSACore.java index 81b4e3f98..7e933e5b7 100644 --- a/src/share/classes/sun/security/rsa/RSACore.java +++ b/src/share/classes/sun/security/rsa/RSACore.java @@ -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 @@ public final class RSACore { /** * 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,11 @@ public final class RSACore { * 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 { 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 +197,9 @@ public final class RSACore { 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)); } diff --git a/src/share/classes/sun/security/rsa/RSASignature.java b/src/share/classes/sun/security/rsa/RSASignature.java index 959700f22..d5ba1f826 100644 --- a/src/share/classes/sun/security/rsa/RSASignature.java +++ b/src/share/classes/sun/security/rsa/RSASignature.java @@ -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 @@ public abstract class RSASignature extends SignatureSpi { 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); -- cgit v1.2.3