src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/CipherBlockChainingSubstitutions.java
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File hotspot Sdiff src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements

src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/CipherBlockChainingSubstitutions.java

Print this page




  22  */
  23 package org.graalvm.compiler.hotspot.replacements;
  24 
  25 import static org.graalvm.compiler.hotspot.HotSpotBackend.DECRYPT;
  26 import static org.graalvm.compiler.hotspot.HotSpotBackend.DECRYPT_WITH_ORIGINAL_KEY;
  27 import static org.graalvm.compiler.hotspot.HotSpotBackend.ENCRYPT;
  28 import static org.graalvm.compiler.hotspot.replacements.UnsafeAccess.UNSAFE;
  29 import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntimeProvider.getArrayBaseOffset;
  30 
  31 import org.graalvm.compiler.api.replacements.ClassSubstitution;
  32 import org.graalvm.compiler.api.replacements.Fold;
  33 import org.graalvm.compiler.api.replacements.MethodSubstitution;
  34 import org.graalvm.compiler.core.common.LocationIdentity;
  35 import org.graalvm.compiler.core.common.spi.ForeignCallDescriptor;
  36 import org.graalvm.compiler.debug.GraalError;
  37 import org.graalvm.compiler.graph.Node.ConstantNodeParameter;
  38 import org.graalvm.compiler.graph.Node.NodeIntrinsic;
  39 import org.graalvm.compiler.hotspot.nodes.ComputeObjectAddressNode;
  40 import org.graalvm.compiler.nodes.PiNode;
  41 import org.graalvm.compiler.nodes.extended.ForeignCallNode;
  42 import org.graalvm.compiler.nodes.extended.UnsafeLoadNode;
  43 import org.graalvm.compiler.word.Pointer;
  44 import org.graalvm.compiler.word.Word;
  45 
  46 import jdk.vm.ci.meta.JavaKind;
  47 
  48 // JaCoCo Exclude
  49 
  50 /**
  51  * Substitutions for {@code com.sun.crypto.provider.CipherBlockChaining} methods.
  52  */
  53 @ClassSubstitution(className = "com.sun.crypto.provider.CipherBlockChaining", optional = true)
  54 public class CipherBlockChainingSubstitutions {
  55 
  56     private static final long embeddedCipherOffset;
  57     private static final long rOffset;
  58     private static final Class<?> cipherBlockChainingClass;
  59     private static final Class<?> feedbackCipherClass;
  60     static {
  61         try {
  62             // Need to use the system class loader as com.sun.crypto.provider.FeedbackCipher


  65             ClassLoader cl = ClassLoader.getSystemClassLoader();
  66 
  67             feedbackCipherClass = Class.forName("com.sun.crypto.provider.FeedbackCipher", true, cl);
  68             embeddedCipherOffset = UNSAFE.objectFieldOffset(feedbackCipherClass.getDeclaredField("embeddedCipher"));
  69 
  70             cipherBlockChainingClass = Class.forName("com.sun.crypto.provider.CipherBlockChaining", true, cl);
  71             rOffset = UNSAFE.objectFieldOffset(cipherBlockChainingClass.getDeclaredField("r"));
  72         } catch (Exception ex) {
  73             throw new GraalError(ex);
  74         }
  75     }
  76 
  77     @Fold
  78     static Class<?> getAESCryptClass() {
  79         return AESCryptSubstitutions.AESCryptClass;
  80     }
  81 
  82     @MethodSubstitution(isStatic = false)
  83     static int encrypt(Object rcvr, byte[] in, int inOffset, int inLength, byte[] out, int outOffset) {
  84         Object realReceiver = PiNode.piCastNonNull(rcvr, cipherBlockChainingClass);
  85         Object embeddedCipher = UnsafeLoadNode.load(realReceiver, embeddedCipherOffset, JavaKind.Object, LocationIdentity.any());
  86         if (getAESCryptClass().isInstance(embeddedCipher)) {
  87             Object aesCipher = getAESCryptClass().cast(embeddedCipher);
  88             crypt(realReceiver, in, inOffset, inLength, out, outOffset, aesCipher, true, false);
  89             return inLength;
  90         } else {
  91             return encrypt(realReceiver, in, inOffset, inLength, out, outOffset);
  92         }
  93     }
  94 
  95     @MethodSubstitution(isStatic = false, value = "implEncrypt")
  96     static int implEncrypt(Object rcvr, byte[] in, int inOffset, int inLength, byte[] out, int outOffset) {
  97         Object realReceiver = PiNode.piCastNonNull(rcvr, cipherBlockChainingClass);
  98         Object embeddedCipher = UnsafeLoadNode.load(realReceiver, embeddedCipherOffset, JavaKind.Object, LocationIdentity.any());
  99         if (getAESCryptClass().isInstance(embeddedCipher)) {
 100             Object aesCipher = getAESCryptClass().cast(embeddedCipher);
 101             crypt(realReceiver, in, inOffset, inLength, out, outOffset, aesCipher, true, false);
 102             return inLength;
 103         } else {
 104             return implEncrypt(realReceiver, in, inOffset, inLength, out, outOffset);
 105         }
 106     }
 107 
 108     @MethodSubstitution(isStatic = false)
 109     static int decrypt(Object rcvr, byte[] in, int inOffset, int inLength, byte[] out, int outOffset) {
 110         Object realReceiver = PiNode.piCastNonNull(rcvr, cipherBlockChainingClass);
 111         Object embeddedCipher = UnsafeLoadNode.load(realReceiver, embeddedCipherOffset, JavaKind.Object, LocationIdentity.any());
 112         if (in != out && getAESCryptClass().isInstance(embeddedCipher)) {
 113             Object aesCipher = getAESCryptClass().cast(embeddedCipher);
 114             crypt(realReceiver, in, inOffset, inLength, out, outOffset, aesCipher, false, false);
 115             return inLength;
 116         } else {
 117             return decrypt(realReceiver, in, inOffset, inLength, out, outOffset);
 118         }
 119     }
 120 
 121     @MethodSubstitution(isStatic = false)
 122     static int implDecrypt(Object rcvr, byte[] in, int inOffset, int inLength, byte[] out, int outOffset) {
 123         Object realReceiver = PiNode.piCastNonNull(rcvr, cipherBlockChainingClass);
 124         Object embeddedCipher = UnsafeLoadNode.load(realReceiver, embeddedCipherOffset, JavaKind.Object, LocationIdentity.any());
 125         if (in != out && getAESCryptClass().isInstance(embeddedCipher)) {
 126             Object aesCipher = getAESCryptClass().cast(embeddedCipher);
 127             crypt(realReceiver, in, inOffset, inLength, out, outOffset, aesCipher, false, false);
 128             return inLength;
 129         } else {
 130             return implDecrypt(realReceiver, in, inOffset, inLength, out, outOffset);
 131         }
 132     }
 133 
 134     /**
 135      * Variation for platforms (e.g. SPARC) that need do key expansion in stubs due to compatibility
 136      * issues between Java key expansion and hardware crypto instructions.
 137      */
 138     @MethodSubstitution(isStatic = false, value = "decrypt")
 139     static int decryptWithOriginalKey(Object rcvr, byte[] in, int inOffset, int inLength, byte[] out, int outOffset) {
 140         Object realReceiver = PiNode.piCastNonNull(rcvr, cipherBlockChainingClass);
 141         Object embeddedCipher = UnsafeLoadNode.load(realReceiver, embeddedCipherOffset, JavaKind.Object, LocationIdentity.any());
 142         if (in != out && getAESCryptClass().isInstance(embeddedCipher)) {
 143             Object aesCipher = getAESCryptClass().cast(embeddedCipher);
 144             crypt(realReceiver, in, inOffset, inLength, out, outOffset, aesCipher, false, true);
 145             return inLength;
 146         } else {
 147             return decryptWithOriginalKey(realReceiver, in, inOffset, inLength, out, outOffset);
 148         }
 149     }
 150 
 151     /**
 152      * @see #decryptWithOriginalKey(Object, byte[], int, int, byte[], int)
 153      */
 154     @MethodSubstitution(isStatic = false, value = "implDecrypt")
 155     static int implDecryptWithOriginalKey(Object rcvr, byte[] in, int inOffset, int inLength, byte[] out, int outOffset) {
 156         Object realReceiver = PiNode.piCastNonNull(rcvr, cipherBlockChainingClass);
 157         Object embeddedCipher = UnsafeLoadNode.load(realReceiver, embeddedCipherOffset, JavaKind.Object, LocationIdentity.any());
 158         if (in != out && getAESCryptClass().isInstance(embeddedCipher)) {
 159             Object aesCipher = getAESCryptClass().cast(embeddedCipher);
 160             crypt(realReceiver, in, inOffset, inLength, out, outOffset, aesCipher, false, true);
 161             return inLength;
 162         } else {
 163             return implDecryptWithOriginalKey(realReceiver, in, inOffset, inLength, out, outOffset);
 164         }
 165     }
 166 
 167     private static void crypt(Object rcvr, byte[] in, int inOffset, int inLength, byte[] out, int outOffset, Object embeddedCipher, boolean encrypt, boolean withOriginalKey) {
 168         AESCryptSubstitutions.checkArgs(in, inOffset, out, outOffset);
 169         Object realReceiver = PiNode.piCastNonNull(rcvr, cipherBlockChainingClass);
 170         Object aesCipher = getAESCryptClass().cast(embeddedCipher);
 171         Object kObject = UnsafeLoadNode.load(aesCipher, AESCryptSubstitutions.kOffset, JavaKind.Object, LocationIdentity.any());
 172         Object rObject = UnsafeLoadNode.load(realReceiver, rOffset, JavaKind.Object, LocationIdentity.any());
 173         Pointer kAddr = Word.objectToTrackedPointer(kObject).add(getArrayBaseOffset(JavaKind.Int));
 174         Pointer rAddr = Word.objectToTrackedPointer(rObject).add(getArrayBaseOffset(JavaKind.Byte));
 175         Word inAddr = Word.unsigned(ComputeObjectAddressNode.get(in, getArrayBaseOffset(JavaKind.Byte) + inOffset));
 176         Word outAddr = Word.unsigned(ComputeObjectAddressNode.get(out, getArrayBaseOffset(JavaKind.Byte) + outOffset));
 177         if (encrypt) {
 178             encryptAESCryptStub(ENCRYPT, inAddr, outAddr, kAddr, rAddr, inLength);
 179         } else {
 180             if (withOriginalKey) {
 181                 Object lastKeyObject = UnsafeLoadNode.load(aesCipher, AESCryptSubstitutions.lastKeyOffset, JavaKind.Object, LocationIdentity.any());
 182                 Pointer lastKeyAddr = Word.objectToTrackedPointer(lastKeyObject).add(getArrayBaseOffset(JavaKind.Byte));
 183                 decryptAESCryptWithOriginalKeyStub(DECRYPT_WITH_ORIGINAL_KEY, inAddr, outAddr, kAddr, rAddr, inLength, lastKeyAddr);
 184             } else {
 185                 decryptAESCryptStub(DECRYPT, inAddr, outAddr, kAddr, rAddr, inLength);
 186             }
 187         }
 188     }
 189 
 190     @NodeIntrinsic(ForeignCallNode.class)
 191     public static native void encryptAESCryptStub(@ConstantNodeParameter ForeignCallDescriptor descriptor, Word in, Word out, Pointer key, Pointer r, int inLength);
 192 
 193     @NodeIntrinsic(ForeignCallNode.class)
 194     public static native void decryptAESCryptStub(@ConstantNodeParameter ForeignCallDescriptor descriptor, Word in, Word out, Pointer key, Pointer r, int inLength);
 195 
 196     @NodeIntrinsic(ForeignCallNode.class)
 197     public static native void decryptAESCryptWithOriginalKeyStub(@ConstantNodeParameter ForeignCallDescriptor descriptor, Word in, Word out, Pointer key, Pointer r, int inLength, Pointer originalKey);
 198 }


  22  */
  23 package org.graalvm.compiler.hotspot.replacements;
  24 
  25 import static org.graalvm.compiler.hotspot.HotSpotBackend.DECRYPT;
  26 import static org.graalvm.compiler.hotspot.HotSpotBackend.DECRYPT_WITH_ORIGINAL_KEY;
  27 import static org.graalvm.compiler.hotspot.HotSpotBackend.ENCRYPT;
  28 import static org.graalvm.compiler.hotspot.replacements.UnsafeAccess.UNSAFE;
  29 import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntimeProvider.getArrayBaseOffset;
  30 
  31 import org.graalvm.compiler.api.replacements.ClassSubstitution;
  32 import org.graalvm.compiler.api.replacements.Fold;
  33 import org.graalvm.compiler.api.replacements.MethodSubstitution;
  34 import org.graalvm.compiler.core.common.LocationIdentity;
  35 import org.graalvm.compiler.core.common.spi.ForeignCallDescriptor;
  36 import org.graalvm.compiler.debug.GraalError;
  37 import org.graalvm.compiler.graph.Node.ConstantNodeParameter;
  38 import org.graalvm.compiler.graph.Node.NodeIntrinsic;
  39 import org.graalvm.compiler.hotspot.nodes.ComputeObjectAddressNode;
  40 import org.graalvm.compiler.nodes.PiNode;
  41 import org.graalvm.compiler.nodes.extended.ForeignCallNode;
  42 import org.graalvm.compiler.nodes.extended.RawLoadNode;
  43 import org.graalvm.compiler.word.Pointer;
  44 import org.graalvm.compiler.word.Word;
  45 
  46 import jdk.vm.ci.meta.JavaKind;
  47 
  48 // JaCoCo Exclude
  49 
  50 /**
  51  * Substitutions for {@code com.sun.crypto.provider.CipherBlockChaining} methods.
  52  */
  53 @ClassSubstitution(className = "com.sun.crypto.provider.CipherBlockChaining", optional = true)
  54 public class CipherBlockChainingSubstitutions {
  55 
  56     private static final long embeddedCipherOffset;
  57     private static final long rOffset;
  58     private static final Class<?> cipherBlockChainingClass;
  59     private static final Class<?> feedbackCipherClass;
  60     static {
  61         try {
  62             // Need to use the system class loader as com.sun.crypto.provider.FeedbackCipher


  65             ClassLoader cl = ClassLoader.getSystemClassLoader();
  66 
  67             feedbackCipherClass = Class.forName("com.sun.crypto.provider.FeedbackCipher", true, cl);
  68             embeddedCipherOffset = UNSAFE.objectFieldOffset(feedbackCipherClass.getDeclaredField("embeddedCipher"));
  69 
  70             cipherBlockChainingClass = Class.forName("com.sun.crypto.provider.CipherBlockChaining", true, cl);
  71             rOffset = UNSAFE.objectFieldOffset(cipherBlockChainingClass.getDeclaredField("r"));
  72         } catch (Exception ex) {
  73             throw new GraalError(ex);
  74         }
  75     }
  76 
  77     @Fold
  78     static Class<?> getAESCryptClass() {
  79         return AESCryptSubstitutions.AESCryptClass;
  80     }
  81 
  82     @MethodSubstitution(isStatic = false)
  83     static int encrypt(Object rcvr, byte[] in, int inOffset, int inLength, byte[] out, int outOffset) {
  84         Object realReceiver = PiNode.piCastNonNull(rcvr, cipherBlockChainingClass);
  85         Object embeddedCipher = RawLoadNode.load(realReceiver, embeddedCipherOffset, JavaKind.Object, LocationIdentity.any());
  86         if (getAESCryptClass().isInstance(embeddedCipher)) {
  87             Object aesCipher = getAESCryptClass().cast(embeddedCipher);
  88             crypt(realReceiver, in, inOffset, inLength, out, outOffset, aesCipher, true, false);
  89             return inLength;
  90         } else {
  91             return encrypt(realReceiver, in, inOffset, inLength, out, outOffset);
  92         }
  93     }
  94 
  95     @MethodSubstitution(isStatic = false, value = "implEncrypt")
  96     static int implEncrypt(Object rcvr, byte[] in, int inOffset, int inLength, byte[] out, int outOffset) {
  97         Object realReceiver = PiNode.piCastNonNull(rcvr, cipherBlockChainingClass);
  98         Object embeddedCipher = RawLoadNode.load(realReceiver, embeddedCipherOffset, JavaKind.Object, LocationIdentity.any());
  99         if (getAESCryptClass().isInstance(embeddedCipher)) {
 100             Object aesCipher = getAESCryptClass().cast(embeddedCipher);
 101             crypt(realReceiver, in, inOffset, inLength, out, outOffset, aesCipher, true, false);
 102             return inLength;
 103         } else {
 104             return implEncrypt(realReceiver, in, inOffset, inLength, out, outOffset);
 105         }
 106     }
 107 
 108     @MethodSubstitution(isStatic = false)
 109     static int decrypt(Object rcvr, byte[] in, int inOffset, int inLength, byte[] out, int outOffset) {
 110         Object realReceiver = PiNode.piCastNonNull(rcvr, cipherBlockChainingClass);
 111         Object embeddedCipher = RawLoadNode.load(realReceiver, embeddedCipherOffset, JavaKind.Object, LocationIdentity.any());
 112         if (in != out && getAESCryptClass().isInstance(embeddedCipher)) {
 113             Object aesCipher = getAESCryptClass().cast(embeddedCipher);
 114             crypt(realReceiver, in, inOffset, inLength, out, outOffset, aesCipher, false, false);
 115             return inLength;
 116         } else {
 117             return decrypt(realReceiver, in, inOffset, inLength, out, outOffset);
 118         }
 119     }
 120 
 121     @MethodSubstitution(isStatic = false)
 122     static int implDecrypt(Object rcvr, byte[] in, int inOffset, int inLength, byte[] out, int outOffset) {
 123         Object realReceiver = PiNode.piCastNonNull(rcvr, cipherBlockChainingClass);
 124         Object embeddedCipher = RawLoadNode.load(realReceiver, embeddedCipherOffset, JavaKind.Object, LocationIdentity.any());
 125         if (in != out && getAESCryptClass().isInstance(embeddedCipher)) {
 126             Object aesCipher = getAESCryptClass().cast(embeddedCipher);
 127             crypt(realReceiver, in, inOffset, inLength, out, outOffset, aesCipher, false, false);
 128             return inLength;
 129         } else {
 130             return implDecrypt(realReceiver, in, inOffset, inLength, out, outOffset);
 131         }
 132     }
 133 
 134     /**
 135      * Variation for platforms (e.g. SPARC) that need do key expansion in stubs due to compatibility
 136      * issues between Java key expansion and hardware crypto instructions.
 137      */
 138     @MethodSubstitution(isStatic = false, value = "decrypt")
 139     static int decryptWithOriginalKey(Object rcvr, byte[] in, int inOffset, int inLength, byte[] out, int outOffset) {
 140         Object realReceiver = PiNode.piCastNonNull(rcvr, cipherBlockChainingClass);
 141         Object embeddedCipher = RawLoadNode.load(realReceiver, embeddedCipherOffset, JavaKind.Object, LocationIdentity.any());
 142         if (in != out && getAESCryptClass().isInstance(embeddedCipher)) {
 143             Object aesCipher = getAESCryptClass().cast(embeddedCipher);
 144             crypt(realReceiver, in, inOffset, inLength, out, outOffset, aesCipher, false, true);
 145             return inLength;
 146         } else {
 147             return decryptWithOriginalKey(realReceiver, in, inOffset, inLength, out, outOffset);
 148         }
 149     }
 150 
 151     /**
 152      * @see #decryptWithOriginalKey(Object, byte[], int, int, byte[], int)
 153      */
 154     @MethodSubstitution(isStatic = false, value = "implDecrypt")
 155     static int implDecryptWithOriginalKey(Object rcvr, byte[] in, int inOffset, int inLength, byte[] out, int outOffset) {
 156         Object realReceiver = PiNode.piCastNonNull(rcvr, cipherBlockChainingClass);
 157         Object embeddedCipher = RawLoadNode.load(realReceiver, embeddedCipherOffset, JavaKind.Object, LocationIdentity.any());
 158         if (in != out && getAESCryptClass().isInstance(embeddedCipher)) {
 159             Object aesCipher = getAESCryptClass().cast(embeddedCipher);
 160             crypt(realReceiver, in, inOffset, inLength, out, outOffset, aesCipher, false, true);
 161             return inLength;
 162         } else {
 163             return implDecryptWithOriginalKey(realReceiver, in, inOffset, inLength, out, outOffset);
 164         }
 165     }
 166 
 167     private static void crypt(Object rcvr, byte[] in, int inOffset, int inLength, byte[] out, int outOffset, Object embeddedCipher, boolean encrypt, boolean withOriginalKey) {
 168         AESCryptSubstitutions.checkArgs(in, inOffset, out, outOffset);
 169         Object realReceiver = PiNode.piCastNonNull(rcvr, cipherBlockChainingClass);
 170         Object aesCipher = getAESCryptClass().cast(embeddedCipher);
 171         Object kObject = RawLoadNode.load(aesCipher, AESCryptSubstitutions.kOffset, JavaKind.Object, LocationIdentity.any());
 172         Object rObject = RawLoadNode.load(realReceiver, rOffset, JavaKind.Object, LocationIdentity.any());
 173         Pointer kAddr = Word.objectToTrackedPointer(kObject).add(getArrayBaseOffset(JavaKind.Int));
 174         Pointer rAddr = Word.objectToTrackedPointer(rObject).add(getArrayBaseOffset(JavaKind.Byte));
 175         Word inAddr = Word.unsigned(ComputeObjectAddressNode.get(in, getArrayBaseOffset(JavaKind.Byte) + inOffset));
 176         Word outAddr = Word.unsigned(ComputeObjectAddressNode.get(out, getArrayBaseOffset(JavaKind.Byte) + outOffset));
 177         if (encrypt) {
 178             encryptAESCryptStub(ENCRYPT, inAddr, outAddr, kAddr, rAddr, inLength);
 179         } else {
 180             if (withOriginalKey) {
 181                 Object lastKeyObject = RawLoadNode.load(aesCipher, AESCryptSubstitutions.lastKeyOffset, JavaKind.Object, LocationIdentity.any());
 182                 Pointer lastKeyAddr = Word.objectToTrackedPointer(lastKeyObject).add(getArrayBaseOffset(JavaKind.Byte));
 183                 decryptAESCryptWithOriginalKeyStub(DECRYPT_WITH_ORIGINAL_KEY, inAddr, outAddr, kAddr, rAddr, inLength, lastKeyAddr);
 184             } else {
 185                 decryptAESCryptStub(DECRYPT, inAddr, outAddr, kAddr, rAddr, inLength);
 186             }
 187         }
 188     }
 189 
 190     @NodeIntrinsic(ForeignCallNode.class)
 191     public static native void encryptAESCryptStub(@ConstantNodeParameter ForeignCallDescriptor descriptor, Word in, Word out, Pointer key, Pointer r, int inLength);
 192 
 193     @NodeIntrinsic(ForeignCallNode.class)
 194     public static native void decryptAESCryptStub(@ConstantNodeParameter ForeignCallDescriptor descriptor, Word in, Word out, Pointer key, Pointer r, int inLength);
 195 
 196     @NodeIntrinsic(ForeignCallNode.class)
 197     public static native void decryptAESCryptWithOriginalKeyStub(@ConstantNodeParameter ForeignCallDescriptor descriptor, Word in, Word out, Pointer key, Pointer r, int inLength, Pointer originalKey);
 198 }
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/CipherBlockChainingSubstitutions.java
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File