forked from I2P_Developers/i2p.i2p
* CPUID:
- Add hasAES() - Fix bugs in unused hasSSE3(), hasSSE41(), hasSSE42() * Crypto: Use JVM AES when faster * SystemVersion: Add isJava7() and isX86()
This commit is contained in:
@ -2,9 +2,10 @@ package freenet.support.CPUInformation;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Moved out of CPUID.java
|
* Moved out of CPUID.java
|
||||||
|
* Ref: http://en.wikipedia.org/wiki/CPUID
|
||||||
* @since 0.8.7
|
* @since 0.8.7
|
||||||
*/
|
*/
|
||||||
abstract class CPUIDCPUInfo
|
abstract class CPUIDCPUInfo implements CPUInfo
|
||||||
{
|
{
|
||||||
protected static boolean isX64 = false;
|
protected static boolean isX64 = false;
|
||||||
|
|
||||||
@ -12,33 +13,48 @@ abstract class CPUIDCPUInfo
|
|||||||
{
|
{
|
||||||
return CPUID.getCPUVendorID();
|
return CPUID.getCPUVendorID();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasMMX()
|
public boolean hasMMX()
|
||||||
{
|
{
|
||||||
return (CPUID.getEDXCPUFlags() & 0x800000) != 0; //EDX Bit 23
|
return (CPUID.getEDXCPUFlags() & 0x800000) != 0; //EDX Bit 23
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasSSE(){
|
public boolean hasSSE(){
|
||||||
return (CPUID.getEDXCPUFlags() & 0x2000000) != 0; //EDX Bit 25
|
return (CPUID.getEDXCPUFlags() & 0x2000000) != 0; //EDX Bit 25
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasSSE2()
|
public boolean hasSSE2()
|
||||||
{
|
{
|
||||||
return (CPUID.getEDXCPUFlags() & 0x4000000) != 0; //EDX Bit 26
|
return (CPUID.getEDXCPUFlags() & 0x4000000) != 0; //EDX Bit 26
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasSSE3()
|
public boolean hasSSE3()
|
||||||
{
|
{
|
||||||
return (CPUID.getEDXCPUFlags() & 0x1) != 0; //ECX Bit 0
|
return (CPUID.getECXCPUFlags() & 0x1) != 0; //ECX Bit 0
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasSSE41()
|
public boolean hasSSE41()
|
||||||
{
|
{
|
||||||
return (CPUID.getEDXCPUFlags() & 0x80000) != 0; //ECX Bit 19
|
return (CPUID.getECXCPUFlags() & 0x80000) != 0; //ECX Bit 19
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasSSE42()
|
public boolean hasSSE42()
|
||||||
{
|
{
|
||||||
return (CPUID.getEDXCPUFlags() & 0x100000) != 0; //ECX Bit 20
|
return (CPUID.getECXCPUFlags() & 0x100000) != 0; //ECX Bit 20
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasSSE4A()
|
public boolean hasSSE4A()
|
||||||
{
|
{
|
||||||
return (CPUID.getExtendedECXCPUFlags() & 0x40) != 0; //Extended ECX Bit 6
|
return (CPUID.getExtendedECXCPUFlags() & 0x40) != 0; //Extended ECX Bit 6
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return true iff the CPU supports the AES-NI instruction set.
|
||||||
|
* @since 0.9.14
|
||||||
|
*/
|
||||||
|
public boolean hasAES() {
|
||||||
|
return (CPUID.getECXCPUFlags() & 0x2000000) != 0; //ECX Bit 25
|
||||||
|
}
|
||||||
|
|
||||||
public abstract boolean hasX64();
|
public abstract boolean hasX64();
|
||||||
}
|
}
|
||||||
|
@ -62,4 +62,10 @@ public interface CPUInfo
|
|||||||
* @return true iff the CPU support the SSE4A instruction set.
|
* @return true iff the CPU support the SSE4A instruction set.
|
||||||
*/
|
*/
|
||||||
public boolean hasSSE4A();
|
public boolean hasSSE4A();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return true iff the CPU supports the AES-NI instruction set.
|
||||||
|
* @since 0.9.14
|
||||||
|
*/
|
||||||
|
public boolean hasAES();
|
||||||
}
|
}
|
||||||
|
@ -12,16 +12,21 @@ package net.i2p.crypto;
|
|||||||
import java.security.InvalidKeyException;
|
import java.security.InvalidKeyException;
|
||||||
|
|
||||||
// for using system version
|
// for using system version
|
||||||
//import java.security.GeneralSecurityException;
|
import java.security.GeneralSecurityException;
|
||||||
//import javax.crypto.Cipher;
|
import javax.crypto.Cipher;
|
||||||
//import javax.crypto.spec.IvParameterSpec;
|
import javax.crypto.spec.IvParameterSpec;
|
||||||
//import javax.crypto.spec.SecretKeySpec;
|
import javax.crypto.spec.SecretKeySpec;
|
||||||
|
|
||||||
|
import freenet.support.CPUInformation.CPUID;
|
||||||
|
import freenet.support.CPUInformation.CPUInfo;
|
||||||
|
import freenet.support.CPUInformation.UnknownCPUException;
|
||||||
|
|
||||||
import net.i2p.I2PAppContext;
|
import net.i2p.I2PAppContext;
|
||||||
import net.i2p.data.DataHelper;
|
import net.i2p.data.DataHelper;
|
||||||
import net.i2p.data.SessionKey;
|
import net.i2p.data.SessionKey;
|
||||||
import net.i2p.util.Log;
|
import net.i2p.util.Log;
|
||||||
import net.i2p.util.SimpleByteCache;
|
import net.i2p.util.SimpleByteCache;
|
||||||
|
import net.i2p.util.SystemVersion;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Wrapper for AES cypher operation using Cryptix's Rijndael implementation. Implements
|
* Wrapper for AES cypher operation using Cryptix's Rijndael implementation. Implements
|
||||||
@ -37,28 +42,47 @@ public class CryptixAESEngine extends AESEngine {
|
|||||||
// keys are now cached in the SessionKey objects
|
// keys are now cached in the SessionKey objects
|
||||||
//private CryptixAESKeyCache _cache;
|
//private CryptixAESKeyCache _cache;
|
||||||
|
|
||||||
/**** see comments for main() below
|
|
||||||
private static final boolean USE_SYSTEM_AES;
|
private static final boolean USE_SYSTEM_AES;
|
||||||
static {
|
static {
|
||||||
boolean systemOK = false;
|
boolean systemOK = false;
|
||||||
try {
|
if (hasAESNI()) {
|
||||||
systemOK = Cipher.getMaxAllowedKeyLength("AES") >= 256;
|
|
||||||
} catch (GeneralSecurityException gse) {
|
|
||||||
// a NoSuchAlgorithmException
|
|
||||||
} catch (NoSuchMethodError nsme) {
|
|
||||||
// JamVM, gij
|
|
||||||
try {
|
try {
|
||||||
Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
|
systemOK = Cipher.getMaxAllowedKeyLength("AES") >= 256;
|
||||||
SecretKeySpec key = new SecretKeySpec(new byte[32], "AES");
|
|
||||||
cipher.init(Cipher.ENCRYPT_MODE, key);
|
|
||||||
systemOK = true;
|
|
||||||
} catch (GeneralSecurityException gse) {
|
} catch (GeneralSecurityException gse) {
|
||||||
|
// a NoSuchAlgorithmException
|
||||||
|
} catch (NoSuchMethodError nsme) {
|
||||||
|
// JamVM, gij
|
||||||
|
try {
|
||||||
|
Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
|
||||||
|
SecretKeySpec key = new SecretKeySpec(new byte[32], "AES");
|
||||||
|
cipher.init(Cipher.ENCRYPT_MODE, key);
|
||||||
|
systemOK = true;
|
||||||
|
} catch (GeneralSecurityException gse) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
USE_SYSTEM_AES = systemOK;
|
USE_SYSTEM_AES = systemOK;
|
||||||
//System.out.println("Using system AES? " + systemOK);
|
//System.out.println("Using system AES? " + systemOK);
|
||||||
}
|
}
|
||||||
****/
|
|
||||||
|
/**
|
||||||
|
* Do we have AES-NI support in the processor and JVM?
|
||||||
|
* Only on 64-bit x86 Java 7 fast JVMs, with AES-NI support.
|
||||||
|
* See comments in main() below.
|
||||||
|
* @since 0.9.14
|
||||||
|
*/
|
||||||
|
private static boolean hasAESNI() {
|
||||||
|
if (SystemVersion.isX86() && SystemVersion.is64Bit() && SystemVersion.isJava7() &&
|
||||||
|
!SystemVersion.isApache() && !SystemVersion.isGNU()) {
|
||||||
|
try {
|
||||||
|
return CPUID.getInfo().hasAES();
|
||||||
|
} catch (UnknownCPUException e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
public CryptixAESEngine(I2PAppContext context) {
|
public CryptixAESEngine(I2PAppContext context) {
|
||||||
@ -104,7 +128,6 @@ public class CryptixAESEngine extends AESEngine {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/****
|
|
||||||
if (USE_SYSTEM_AES) {
|
if (USE_SYSTEM_AES) {
|
||||||
try {
|
try {
|
||||||
SecretKeySpec key = new SecretKeySpec(sessionKey.getData(), "AES");
|
SecretKeySpec key = new SecretKeySpec(sessionKey.getData(), "AES");
|
||||||
@ -118,7 +141,6 @@ public class CryptixAESEngine extends AESEngine {
|
|||||||
_log.warn("Java encrypt fail", gse);
|
_log.warn("Java encrypt fail", gse);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
****/
|
|
||||||
|
|
||||||
int numblock = length / 16;
|
int numblock = length / 16;
|
||||||
|
|
||||||
@ -159,7 +181,6 @@ public class CryptixAESEngine extends AESEngine {
|
|||||||
return ;
|
return ;
|
||||||
}
|
}
|
||||||
|
|
||||||
/****
|
|
||||||
if (USE_SYSTEM_AES) {
|
if (USE_SYSTEM_AES) {
|
||||||
try {
|
try {
|
||||||
SecretKeySpec key = new SecretKeySpec(sessionKey.getData(), "AES");
|
SecretKeySpec key = new SecretKeySpec(sessionKey.getData(), "AES");
|
||||||
@ -173,7 +194,6 @@ public class CryptixAESEngine extends AESEngine {
|
|||||||
_log.warn("Java decrypt fail", gse);
|
_log.warn("Java decrypt fail", gse);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
****/
|
|
||||||
|
|
||||||
int numblock = length / 16;
|
int numblock = length / 16;
|
||||||
if (length % 16 != 0) {
|
if (length % 16 != 0) {
|
||||||
@ -261,8 +281,8 @@ public class CryptixAESEngine extends AESEngine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/******
|
/******
|
||||||
private static final int MATCH_RUNS = 5000;
|
private static final int MATCH_RUNS = 11000;
|
||||||
private static final int TIMING_RUNS = 10000;
|
private static final int TIMING_RUNS = 100000;
|
||||||
******/
|
******/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -282,6 +302,15 @@ public class CryptixAESEngine extends AESEngine {
|
|||||||
* jrockit 9780 n/a
|
* jrockit 9780 n/a
|
||||||
*</pre>
|
*</pre>
|
||||||
*
|
*
|
||||||
|
* Speed ups with AES-NI:
|
||||||
|
* May 2014 AMD Hexcore 100K runs:
|
||||||
|
*<pre>
|
||||||
|
* JVM Cryptix (ms) System (ms)
|
||||||
|
* OpenJDK 6 3314 5030
|
||||||
|
* OpenJDK 7 3285 2476
|
||||||
|
*</pre>
|
||||||
|
*
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
/*******
|
/*******
|
||||||
public static void main(String args[]) {
|
public static void main(String args[]) {
|
||||||
|
@ -181,8 +181,7 @@ public class NativeBigInteger extends BigInteger {
|
|||||||
*/
|
*/
|
||||||
private static final boolean _is64 = SystemVersion.is64Bit();
|
private static final boolean _is64 = SystemVersion.is64Bit();
|
||||||
|
|
||||||
private static final boolean _isX86 = System.getProperty("os.arch").contains("86") ||
|
private static final boolean _isX86 = SystemVersion.isX86();
|
||||||
System.getProperty("os.arch").equals("amd64");
|
|
||||||
|
|
||||||
private static final boolean _isArm = SystemVersion.isARM();
|
private static final boolean _isArm = SystemVersion.isARM();
|
||||||
|
|
||||||
|
@ -16,6 +16,8 @@ public abstract class SystemVersion {
|
|||||||
private static final boolean _isWin = System.getProperty("os.name").startsWith("Win");
|
private static final boolean _isWin = System.getProperty("os.name").startsWith("Win");
|
||||||
private static final boolean _isMac = System.getProperty("os.name").startsWith("Mac");
|
private static final boolean _isMac = System.getProperty("os.name").startsWith("Mac");
|
||||||
private static final boolean _isArm = System.getProperty("os.arch").startsWith("arm");
|
private static final boolean _isArm = System.getProperty("os.arch").startsWith("arm");
|
||||||
|
private static final boolean _isX86 = System.getProperty("os.arch").contains("86") ||
|
||||||
|
System.getProperty("os.arch").equals("amd64");
|
||||||
private static final boolean _isAndroid;
|
private static final boolean _isAndroid;
|
||||||
private static final boolean _isApache;
|
private static final boolean _isApache;
|
||||||
private static final boolean _isGNU;
|
private static final boolean _isGNU;
|
||||||
@ -23,6 +25,7 @@ public abstract class SystemVersion {
|
|||||||
private static final boolean _hasWrapper = System.getProperty("wrapper.version") != null;
|
private static final boolean _hasWrapper = System.getProperty("wrapper.version") != null;
|
||||||
|
|
||||||
private static final boolean _oneDotSix;
|
private static final boolean _oneDotSix;
|
||||||
|
private static final boolean _oneDotSeven;
|
||||||
private static final int _androidSDK;
|
private static final int _androidSDK;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
@ -56,8 +59,10 @@ public abstract class SystemVersion {
|
|||||||
|
|
||||||
if (_isAndroid) {
|
if (_isAndroid) {
|
||||||
_oneDotSix = _androidSDK >= 9;
|
_oneDotSix = _androidSDK >= 9;
|
||||||
|
_oneDotSeven = _androidSDK >= 19;
|
||||||
} else {
|
} else {
|
||||||
_oneDotSix = VersionComparator.comp(System.getProperty("java.version"), "1.6") >= 0;
|
_oneDotSix = VersionComparator.comp(System.getProperty("java.version"), "1.6") >= 0;
|
||||||
|
_oneDotSeven = VersionComparator.comp(System.getProperty("java.version"), "1.7") >= 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -94,6 +99,13 @@ public abstract class SystemVersion {
|
|||||||
return _isArm;
|
return _isArm;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 0.9.14
|
||||||
|
*/
|
||||||
|
public static boolean isX86() {
|
||||||
|
return _isX86;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Better than (new VersionComparator()).compare(System.getProperty("java.version"), "1.6") >= 0
|
* Better than (new VersionComparator()).compare(System.getProperty("java.version"), "1.6") >= 0
|
||||||
* as it handles Android also, where java.version = "0".
|
* as it handles Android also, where java.version = "0".
|
||||||
@ -104,6 +116,17 @@ public abstract class SystemVersion {
|
|||||||
return _oneDotSix;
|
return _oneDotSix;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Better than (new VersionComparator()).compare(System.getProperty("java.version"), "1.7") >= 0
|
||||||
|
* as it handles Android also, where java.version = "0".
|
||||||
|
*
|
||||||
|
* @return true if Java 1.7 or higher, or Android API 19 or higher
|
||||||
|
* @since 0.9.14
|
||||||
|
*/
|
||||||
|
public static boolean isJava7() {
|
||||||
|
return _oneDotSeven;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This isn't always correct.
|
* This isn't always correct.
|
||||||
* http://stackoverflow.com/questions/807263/how-do-i-detect-which-kind-of-jre-is-installed-32bit-vs-64bit
|
* http://stackoverflow.com/questions/807263/how-do-i-detect-which-kind-of-jre-is-installed-32bit-vs-64bit
|
||||||
|
Reference in New Issue
Block a user