Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Port AES-NI from Hotspot to IKVM #390

Open
AliveDevil opened this issue Jul 19, 2023 · 3 comments
Open

Port AES-NI from Hotspot to IKVM #390

AliveDevil opened this issue Jul 19, 2023 · 3 comments
Assignees
Labels
enhancement New feature or request

Comments

@AliveDevil
Copy link
Collaborator

There are some intrinsics in JDK, that allow runtime swapping of class implementations.
AES-NI would allow getting ikvmnet from 16 MByte/s (128 MBit/s) up to JDK-level (Gigabit, beyond) in AES-scenarios.
This heavily limits the usage in high-bandwidth encrypted data transfers (HTTP, FTP, etc.).
An IKVM-fork got more bandwidth, than ikvmnet, reasons are unclear, for now: iterate-ch/cyberduck#14909

IKVM is currently targeting x86, x64, aarch64 and arm.

Ref implementation, against jdk8u92.
x86: https://github.com/openjdk/jdk8u/blob/jdk8u92-b34/hotspot/src/cpu/x86/vm/stubGenerator_x86_32.cpp#L2189
x64: https://github.com/openjdk/jdk8u/blob/jdk8u92-b34/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp#L3031

With JDK8u312 aarch64 has been added:
arm64: https://github.com/openjdk/jdk8u/blob/jdk8u312-ga/hotspot/src/cpu/aarch64/vm/stubGenerator_aarch64.cpp#L2606

JDK8 doesn't have an implementation for AES-NI in arm, this would require sourcing the native implementation from e.g. jdk9:
https://github.com/openjdk/jdk/blob/jdk-9%2B150/hotspot/src/cpu/arm/vm/stubRoutinesCrypto_arm.cpp#L120

This could probably be replaced with regular PInvoke on IKVM-side, and simple implementations without the stub-magic in C.

Stubbing is performed in vmSymbols-file: https://github.com/openjdk/jdk8u/blob/jdk8u92-b34/hotspot/src/share/vm/classfile/vmSymbols.hpp#L819-L833

PInvoke signature could look like:

void com_sun_crypto_provider_aescrypt_encryptBlock(byte*, int, byte*, int);
void com_sun_crypto_provider_aescrypt_decryptBlock(byte*, int, byte*, int);

This would need detecting CPU-features in runtime and selecting appropriate implementation (AES-NI or Java) based on that.

As we now have native library-support, we could look at adding this to libjava/libjvm.

@AliveDevil AliveDevil self-assigned this Jul 19, 2023
@AliveDevil AliveDevil added the enhancement New feature or request label Jul 19, 2023
@AliveDevil
Copy link
Collaborator Author

Research brought up:
Slowest path in IKVM is com.sun.crypto.provider.GHASH.update(uint8[], int, int).
This lead to finding this: https://github.com/openjdk/jdk8u/blob/jdk8u312-ga/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp#L3664
Which got added as recently as 8u242.
Need to port GHash intrinsics as well then.

@AliveDevil
Copy link
Collaborator Author

Discussion around this resolved to this:

  • For FX add bcrypt PInvoke on Windows, add intrinsic wrapper to encryptBlock, decryptBlock of both aes and cbc
  • For .NET Core we can amend AESCrypt with map.xml
    to include an additional field, where we can store an Aes-instance (as obtained from Aes.Create, AesGcm.Create, AesCcm.Create)
    • This then replaces the Java implementation

@AliveDevil
Copy link
Collaborator Author

Intrinsics:
com/sun/crypto/provider/AESCrypt, methods

  • encryptBlock (impl: _aescrypt_encryptBlock)
  • decryptBlock (impl: _aescrypt_decryptBlock)

com/sun/crypto/provider/CipherBlockChaining, methods:

  • encrypt (impl: _cipherBlockChaining_encryptAESCrypt)
  • decrypt (impl: _cipherBlockChaining_decryptAESCrypt)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

1 participant