Skip to content
This repository has been archived by the owner on Sep 2, 2022. It is now read-only.

Commit

Permalink
Browse files Browse the repository at this point in the history
8258419: RSA cipher buffer cleanup
Reviewed-by: valeriep
  • Loading branch information
wangweij committed Dec 15, 2020
1 parent 1f556d2 commit b97fe6c
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 55 deletions.
82 changes: 53 additions & 29 deletions src/java.base/share/classes/com/sun/crypto/provider/RSACipher.java
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2020, 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
Expand All @@ -25,6 +25,7 @@

package com.sun.crypto.provider;

import java.util.Arrays;
import java.util.Locale;

import java.security.*;
Expand Down Expand Up @@ -347,28 +348,40 @@ private byte[] doFinal() throws BadPaddingException,
throw new IllegalBlockSizeException("Data must not be longer "
+ "than " + buffer.length + " bytes");
}
byte[] paddingCopy = null;
byte[] result = null;
try {
byte[] data;
switch (mode) {
case MODE_SIGN:
data = padding.pad(buffer, 0, bufOfs);
return RSACore.rsa(data, privateKey, true);
paddingCopy = padding.pad(buffer, 0, bufOfs);
result = RSACore.rsa(paddingCopy, privateKey, true);
break;
case MODE_VERIFY:
byte[] verifyBuffer = RSACore.convert(buffer, 0, bufOfs);
data = RSACore.rsa(verifyBuffer, publicKey);
return padding.unpad(data);
paddingCopy = RSACore.rsa(verifyBuffer, publicKey);
result = padding.unpad(paddingCopy);
break;
case MODE_ENCRYPT:
data = padding.pad(buffer, 0, bufOfs);
return RSACore.rsa(data, publicKey);
paddingCopy = padding.pad(buffer, 0, bufOfs);
result = RSACore.rsa(paddingCopy, publicKey);
break;
case MODE_DECRYPT:
byte[] decryptBuffer = RSACore.convert(buffer, 0, bufOfs);
data = RSACore.rsa(decryptBuffer, privateKey, false);
return padding.unpad(data);
paddingCopy = RSACore.rsa(decryptBuffer, privateKey, false);
result = padding.unpad(paddingCopy);
break;
default:
throw new AssertionError("Internal error");
}
return result;
} finally {
Arrays.fill(buffer, 0, bufOfs, (byte)0);
bufOfs = 0;
if (paddingCopy != null // will not happen
&& paddingCopy != buffer // already cleaned
&& paddingCopy != result) { // DO NOT CLEAN, THIS IS RESULT!
Arrays.fill(paddingCopy, (byte)0);
}
}
}

Expand Down Expand Up @@ -404,6 +417,7 @@ protected int engineDoFinal(byte[] in, int inOfs, int inLen, byte[] out,
byte[] result = doFinal();
int n = result.length;
System.arraycopy(result, 0, out, outOfs, n);
Arrays.fill(result, (byte)0);
return n;
}

Expand All @@ -414,15 +428,19 @@ protected byte[] engineWrap(Key key) throws InvalidKeyException,
if ((encoded == null) || (encoded.length == 0)) {
throw new InvalidKeyException("Could not obtain encoded key");
}
if (encoded.length > buffer.length) {
throw new InvalidKeyException("Key is too long for wrapping");
}
update(encoded, 0, encoded.length);
try {
return doFinal();
} catch (BadPaddingException e) {
// should not occur
throw new InvalidKeyException("Wrapping failed", e);
if (encoded.length > buffer.length) {
throw new InvalidKeyException("Key is too long for wrapping");
}
update(encoded, 0, encoded.length);
try {
return doFinal();
} catch (BadPaddingException e) {
// should not occur
throw new InvalidKeyException("Wrapping failed", e);
}
} finally {
Arrays.fill(encoded, (byte)0);
}
}

Expand Down Expand Up @@ -453,20 +471,26 @@ protected Key engineUnwrap(byte[] wrappedKey, String algorithm,
throw new InvalidKeyException("Unwrapping failed", e);
}

if (isTlsRsaPremasterSecret) {
if (!(spec instanceof TlsRsaPremasterSecretParameterSpec)) {
throw new IllegalStateException(
"No TlsRsaPremasterSecretParameterSpec specified");
try {
if (isTlsRsaPremasterSecret) {
if (!(spec instanceof TlsRsaPremasterSecretParameterSpec)) {
throw new IllegalStateException(
"No TlsRsaPremasterSecretParameterSpec specified");
}

// polish the TLS premaster secret
encoded = KeyUtil.checkTlsPreMasterSecretKey(
((TlsRsaPremasterSecretParameterSpec) spec).getClientVersion(),
((TlsRsaPremasterSecretParameterSpec) spec).getServerVersion(),
random, encoded, (failover != null));
}

// polish the TLS premaster secret
encoded = KeyUtil.checkTlsPreMasterSecretKey(
((TlsRsaPremasterSecretParameterSpec)spec).getClientVersion(),
((TlsRsaPremasterSecretParameterSpec)spec).getServerVersion(),
random, encoded, (failover != null));
return ConstructKeys.constructKey(encoded, algorithm, type);
} finally {
if (encoded != null) {
Arrays.fill(encoded, (byte) 0);
}
}

return ConstructKeys.constructKey(encoded, algorithm, type);
}

// see JCE spec
Expand Down
4 changes: 3 additions & 1 deletion src/java.base/share/classes/sun/security/rsa/RSACore.java
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2020, 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
Expand Down Expand Up @@ -231,12 +231,14 @@ private static byte[] toByteArray(BigInteger bi, int len) {
if ((n == len + 1) && (b[0] == 0)) {
byte[] t = new byte[len];
System.arraycopy(b, 1, t, 0, len);
Arrays.fill(b, (byte)0);
return t;
}
// must be smaller
assert (n < len);
byte[] t = new byte[len];
System.arraycopy(b, 0, t, (len - n), n);
Arrays.fill(b, (byte)0);
return t;
}

Expand Down
41 changes: 16 additions & 25 deletions src/java.base/share/classes/sun/security/rsa/RSAPadding.java
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2020, 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
Expand Down Expand Up @@ -238,41 +238,33 @@ public int getMaxDataSize() {
/**
* Pad the data and return the padded block.
*/
public byte[] pad(byte[] data, int ofs, int len)
throws BadPaddingException {
return pad(RSACore.convert(data, ofs, len));
public byte[] pad(byte[] data) throws BadPaddingException {
return pad(data, 0, data.length);
}

/**
* Pad the data and return the padded block.
*/
public byte[] pad(byte[] data) throws BadPaddingException {
if (data.length > maxDataSize) {
public byte[] pad(byte[] data, int ofs, int len)
throws BadPaddingException {
if (len > maxDataSize) {
throw new BadPaddingException("Data must be shorter than "
+ (maxDataSize + 1) + " bytes but received "
+ data.length + " bytes.");
+ len + " bytes.");
}
switch (type) {
case PAD_NONE:
return data;
return RSACore.convert(data, ofs, len);
case PAD_BLOCKTYPE_1:
case PAD_BLOCKTYPE_2:
return padV15(data);
return padV15(data, ofs, len);
case PAD_OAEP_MGF1:
return padOAEP(data);
return padOAEP(data, ofs, len);
default:
throw new AssertionError();
}
}

/**
* Unpad the padded block and return the data.
*/
public byte[] unpad(byte[] padded, int ofs, int len)
throws BadPaddingException {
return unpad(RSACore.convert(padded, ofs, len));
}

/**
* Unpad the padded block and return the data.
*/
Expand All @@ -298,11 +290,10 @@ public byte[] unpad(byte[] padded) throws BadPaddingException {
/**
* PKCS#1 v1.5 padding (blocktype 1 and 2).
*/
private byte[] padV15(byte[] data) throws BadPaddingException {
private byte[] padV15(byte[] data, int ofs, int len) throws BadPaddingException {
byte[] padded = new byte[paddedSize];
System.arraycopy(data, 0, padded, paddedSize - data.length,
data.length);
int psSize = paddedSize - 3 - data.length;
System.arraycopy(data, ofs, padded, paddedSize - len, len);
int psSize = paddedSize - 3 - len;
int k = 0;
padded[k++] = 0;
padded[k++] = (byte)type;
Expand Down Expand Up @@ -388,7 +379,7 @@ private byte[] unpadV15(byte[] padded) throws BadPaddingException {
* PKCS#1 v2.0 OAEP padding (MGF1).
* Paragraph references refer to PKCS#1 v2.1 (June 14, 2002)
*/
private byte[] padOAEP(byte[] M) throws BadPaddingException {
private byte[] padOAEP(byte[] M, int ofs, int len) throws BadPaddingException {
if (random == null) {
random = JCAUtil.getSecureRandom();
}
Expand All @@ -415,7 +406,7 @@ private byte[] padOAEP(byte[] M) throws BadPaddingException {
int dbLen = EM.length - dbStart;

// start of message M in EM
int mStart = paddedSize - M.length;
int mStart = paddedSize - len;

// build DB
// 2.b: Concatenate lHash, PS, a single octet with hexadecimal value
Expand All @@ -424,7 +415,7 @@ private byte[] padOAEP(byte[] M) throws BadPaddingException {
// (note that PS is all zeros)
System.arraycopy(lHash, 0, EM, dbStart, hLen);
EM[mStart - 1] = 1;
System.arraycopy(M, 0, EM, mStart, M.length);
System.arraycopy(M, ofs, EM, mStart, len);

// produce maskedDB
mgf.generateAndXor(EM, seedStart, seedLen, dbLen, EM, dbStart);
Expand Down

1 comment on commit b97fe6c

@openjdk-notifier
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.