25 import static org.graalvm.compiler.hotspot.HotSpotBackend.DECRYPT_BLOCK;
26 import static org.graalvm.compiler.hotspot.HotSpotBackend.DECRYPT_BLOCK_WITH_ORIGINAL_KEY;
27 import static org.graalvm.compiler.hotspot.HotSpotBackend.ENCRYPT_BLOCK;
28 import static org.graalvm.compiler.nodes.extended.BranchProbabilityNode.VERY_SLOW_PATH_PROBABILITY;
29 import static org.graalvm.compiler.nodes.extended.BranchProbabilityNode.probability;
30 import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntimeProvider.getArrayBaseOffset;
31
32 import java.lang.reflect.Field;
33
34 import org.graalvm.compiler.api.replacements.ClassSubstitution;
35 import org.graalvm.compiler.api.replacements.MethodSubstitution;
36 import org.graalvm.compiler.core.common.LocationIdentity;
37 import org.graalvm.compiler.core.common.spi.ForeignCallDescriptor;
38 import org.graalvm.compiler.debug.GraalError;
39 import org.graalvm.compiler.graph.Node.ConstantNodeParameter;
40 import org.graalvm.compiler.graph.Node.NodeIntrinsic;
41 import org.graalvm.compiler.hotspot.nodes.ComputeObjectAddressNode;
42 import org.graalvm.compiler.nodes.DeoptimizeNode;
43 import org.graalvm.compiler.nodes.PiNode;
44 import org.graalvm.compiler.nodes.extended.ForeignCallNode;
45 import org.graalvm.compiler.nodes.extended.UnsafeLoadNode;
46 import org.graalvm.compiler.word.Pointer;
47 import org.graalvm.compiler.word.Word;
48
49 import jdk.vm.ci.meta.DeoptimizationAction;
50 import jdk.vm.ci.meta.DeoptimizationReason;
51 import jdk.vm.ci.meta.JavaKind;
52
53 // JaCoCo Exclude
54
55 /**
56 * Substitutions for {@code com.sun.crypto.provider.AESCrypt} methods.
57 */
58 @ClassSubstitution(className = "com.sun.crypto.provider.AESCrypt", optional = true)
59 public class AESCryptSubstitutions {
60
61 static final long kOffset;
62 static final long lastKeyOffset;
63 static final Class<?> AESCryptClass;
64 static final int AES_BLOCK_SIZE;
65
103 /**
104 * Variation for platforms (e.g. SPARC) that need do key expansion in stubs due to compatibility
105 * issues between Java key expansion and hardware crypto instructions.
106 */
107 @MethodSubstitution(value = "decryptBlock", isStatic = false)
108 static void decryptBlockWithOriginalKey(Object rcvr, byte[] in, int inOffset, byte[] out, int outOffset) {
109 crypt(rcvr, in, inOffset, out, outOffset, false, true);
110 }
111
112 /**
113 * @see #decryptBlockWithOriginalKey(Object, byte[], int, byte[], int)
114 */
115 @MethodSubstitution(value = "implDecryptBlock", isStatic = false)
116 static void implDecryptBlockWithOriginalKey(Object rcvr, byte[] in, int inOffset, byte[] out, int outOffset) {
117 crypt(rcvr, in, inOffset, out, outOffset, false, true);
118 }
119
120 private static void crypt(Object rcvr, byte[] in, int inOffset, byte[] out, int outOffset, boolean encrypt, boolean withOriginalKey) {
121 checkArgs(in, inOffset, out, outOffset);
122 Object realReceiver = PiNode.piCastNonNull(rcvr, AESCryptClass);
123 Object kObject = UnsafeLoadNode.load(realReceiver, kOffset, JavaKind.Object, LocationIdentity.any());
124 Pointer kAddr = Word.objectToTrackedPointer(kObject).add(getArrayBaseOffset(JavaKind.Int));
125 Word inAddr = Word.unsigned(ComputeObjectAddressNode.get(in, getArrayBaseOffset(JavaKind.Byte) + inOffset));
126 Word outAddr = Word.unsigned(ComputeObjectAddressNode.get(out, getArrayBaseOffset(JavaKind.Byte) + outOffset));
127 if (encrypt) {
128 encryptBlockStub(ENCRYPT_BLOCK, inAddr, outAddr, kAddr);
129 } else {
130 if (withOriginalKey) {
131 Object lastKeyObject = UnsafeLoadNode.load(realReceiver, lastKeyOffset, JavaKind.Object, LocationIdentity.any());
132 Pointer lastKeyAddr = Word.objectToTrackedPointer(lastKeyObject).add(getArrayBaseOffset(JavaKind.Byte));
133 decryptBlockWithOriginalKeyStub(DECRYPT_BLOCK_WITH_ORIGINAL_KEY, inAddr, outAddr, kAddr, lastKeyAddr);
134 } else {
135 decryptBlockStub(DECRYPT_BLOCK, inAddr, outAddr, kAddr);
136 }
137 }
138 }
139
140 /**
141 * Perform null and array bounds checks for arguments to a cipher operation.
142 */
143 static void checkArgs(byte[] in, int inOffset, byte[] out, int outOffset) {
144 if (probability(VERY_SLOW_PATH_PROBABILITY, inOffset < 0 || in.length - AES_BLOCK_SIZE < inOffset || outOffset < 0 || out.length - AES_BLOCK_SIZE < outOffset)) {
145 DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint);
146 }
147 }
148
149 @NodeIntrinsic(ForeignCallNode.class)
150 public static native void encryptBlockStub(@ConstantNodeParameter ForeignCallDescriptor descriptor, Word in, Word out, Pointer key);
151
|
25 import static org.graalvm.compiler.hotspot.HotSpotBackend.DECRYPT_BLOCK;
26 import static org.graalvm.compiler.hotspot.HotSpotBackend.DECRYPT_BLOCK_WITH_ORIGINAL_KEY;
27 import static org.graalvm.compiler.hotspot.HotSpotBackend.ENCRYPT_BLOCK;
28 import static org.graalvm.compiler.nodes.extended.BranchProbabilityNode.VERY_SLOW_PATH_PROBABILITY;
29 import static org.graalvm.compiler.nodes.extended.BranchProbabilityNode.probability;
30 import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntimeProvider.getArrayBaseOffset;
31
32 import java.lang.reflect.Field;
33
34 import org.graalvm.compiler.api.replacements.ClassSubstitution;
35 import org.graalvm.compiler.api.replacements.MethodSubstitution;
36 import org.graalvm.compiler.core.common.LocationIdentity;
37 import org.graalvm.compiler.core.common.spi.ForeignCallDescriptor;
38 import org.graalvm.compiler.debug.GraalError;
39 import org.graalvm.compiler.graph.Node.ConstantNodeParameter;
40 import org.graalvm.compiler.graph.Node.NodeIntrinsic;
41 import org.graalvm.compiler.hotspot.nodes.ComputeObjectAddressNode;
42 import org.graalvm.compiler.nodes.DeoptimizeNode;
43 import org.graalvm.compiler.nodes.PiNode;
44 import org.graalvm.compiler.nodes.extended.ForeignCallNode;
45 import org.graalvm.compiler.nodes.extended.RawLoadNode;
46 import org.graalvm.compiler.word.Pointer;
47 import org.graalvm.compiler.word.Word;
48
49 import jdk.vm.ci.meta.DeoptimizationAction;
50 import jdk.vm.ci.meta.DeoptimizationReason;
51 import jdk.vm.ci.meta.JavaKind;
52
53 // JaCoCo Exclude
54
55 /**
56 * Substitutions for {@code com.sun.crypto.provider.AESCrypt} methods.
57 */
58 @ClassSubstitution(className = "com.sun.crypto.provider.AESCrypt", optional = true)
59 public class AESCryptSubstitutions {
60
61 static final long kOffset;
62 static final long lastKeyOffset;
63 static final Class<?> AESCryptClass;
64 static final int AES_BLOCK_SIZE;
65
103 /**
104 * Variation for platforms (e.g. SPARC) that need do key expansion in stubs due to compatibility
105 * issues between Java key expansion and hardware crypto instructions.
106 */
107 @MethodSubstitution(value = "decryptBlock", isStatic = false)
108 static void decryptBlockWithOriginalKey(Object rcvr, byte[] in, int inOffset, byte[] out, int outOffset) {
109 crypt(rcvr, in, inOffset, out, outOffset, false, true);
110 }
111
112 /**
113 * @see #decryptBlockWithOriginalKey(Object, byte[], int, byte[], int)
114 */
115 @MethodSubstitution(value = "implDecryptBlock", isStatic = false)
116 static void implDecryptBlockWithOriginalKey(Object rcvr, byte[] in, int inOffset, byte[] out, int outOffset) {
117 crypt(rcvr, in, inOffset, out, outOffset, false, true);
118 }
119
120 private static void crypt(Object rcvr, byte[] in, int inOffset, byte[] out, int outOffset, boolean encrypt, boolean withOriginalKey) {
121 checkArgs(in, inOffset, out, outOffset);
122 Object realReceiver = PiNode.piCastNonNull(rcvr, AESCryptClass);
123 Object kObject = RawLoadNode.load(realReceiver, kOffset, JavaKind.Object, LocationIdentity.any());
124 Pointer kAddr = Word.objectToTrackedPointer(kObject).add(getArrayBaseOffset(JavaKind.Int));
125 Word inAddr = Word.unsigned(ComputeObjectAddressNode.get(in, getArrayBaseOffset(JavaKind.Byte) + inOffset));
126 Word outAddr = Word.unsigned(ComputeObjectAddressNode.get(out, getArrayBaseOffset(JavaKind.Byte) + outOffset));
127 if (encrypt) {
128 encryptBlockStub(ENCRYPT_BLOCK, inAddr, outAddr, kAddr);
129 } else {
130 if (withOriginalKey) {
131 Object lastKeyObject = RawLoadNode.load(realReceiver, lastKeyOffset, JavaKind.Object, LocationIdentity.any());
132 Pointer lastKeyAddr = Word.objectToTrackedPointer(lastKeyObject).add(getArrayBaseOffset(JavaKind.Byte));
133 decryptBlockWithOriginalKeyStub(DECRYPT_BLOCK_WITH_ORIGINAL_KEY, inAddr, outAddr, kAddr, lastKeyAddr);
134 } else {
135 decryptBlockStub(DECRYPT_BLOCK, inAddr, outAddr, kAddr);
136 }
137 }
138 }
139
140 /**
141 * Perform null and array bounds checks for arguments to a cipher operation.
142 */
143 static void checkArgs(byte[] in, int inOffset, byte[] out, int outOffset) {
144 if (probability(VERY_SLOW_PATH_PROBABILITY, inOffset < 0 || in.length - AES_BLOCK_SIZE < inOffset || outOffset < 0 || out.length - AES_BLOCK_SIZE < outOffset)) {
145 DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint);
146 }
147 }
148
149 @NodeIntrinsic(ForeignCallNode.class)
150 public static native void encryptBlockStub(@ConstantNodeParameter ForeignCallDescriptor descriptor, Word in, Word out, Pointer key);
151
|