Silly me, forgot to mention that I'm working on Ubuntu, 64 bit, 13.10. So, AES-CBC seems to be reasonably fast (100 MiB/s) but AES-GCM is slow (5.2 MiB/s). I'm particularly curious about the GCM one because I get the impression that OpenSSL should be able to reach in the GB/s for AES-GCM encryption/authentication.
Mark On Mon, Jan 27, 2014 at 3:19 PM, Xuelei Fan <xuelei....@oracle.com> wrote: > What's the platform are you using for the testing? Windows, Linux, > Solaris or Mac OS? GCM are now only implemented in SunJCE provider. I > want to make sure the crypto provider for AES-CBC, which is different > for different platforms by default, is not the major cause of the > performance impact. > > Thanks for the performance measure. > > Regards, > Xuelei > > On 1/27/2014 5:34 PM, Chris Hegarty wrote: > > Cross posting to security-dev, since the question cipher related. > > > > -Chris. > > > > On 27/01/14 09:28, Mark Christiaens wrote: > >> I wrote a little test client/server setup that transfers 100 MB of data > >> over an SSL socket configured to use TLS 1.2 AES GCM > >> (TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256). On my i7-4770 CPU @ 3.40GHz > >> with OpenJDK 1.8.0-ea-b124 I get a transfer rate of around 5.2 > >> MiB/second. I expected a higher speed. Using > >> TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 I reach 100 MiB/s. Is this to > >> be expected? > >> > >> For reference, here is my code: > >> > >> ///// Client.java > >> > >> package ssl; > >> > >> import javax.net.ssl.*; > >> import java.io.*; > >> import java.util.Arrays; > >> > >> public class Client { > >> > >> public static void main(String[] arstring) { > >> try { > >> SSLSocketFactory sslsocketfactory = (SSLSocketFactory) > >> SSLSocketFactory.getDefault(); > >> SSLSocket sslsocket = (SSLSocket) > >> sslsocketfactory.createSocket("localhost", 9999); > >> Helper.requireAESCipherSuites(sslsocket); > >> sslsocket.setEnabledProtocols(new String[]{"TLSv1.2"}); > >> > >> try (OutputStream outputstream = > >> sslsocket.getOutputStream()) { > >> byte[] buf = new byte[Helper.BUF_SIZE]; > >> Arrays.fill(buf, (byte) 1); > >> for (int i = 0; i < Helper.BUF_COUNT; ++i) { > >> outputstream.write(buf); > >> } > >> > >> System.out.println("Using cipher suite: " + > >> (sslsocket.getSession()).getCipherSuite()); > >> > >> outputstream.flush(); > >> } > >> > >> } catch (IOException exception) { > >> exception.printStackTrace(); > >> } > >> } > >> } > >> > >> ///// Server.java > >> > >> package ssl; > >> > >> import javax.net.ssl.*; > >> import java.io.*; > >> > >> public class Server { > >> > >> public static void main(String[] arstring) { > >> try { > >> SSLServerSocketFactory sslserversocketfactory = > >> (SSLServerSocketFactory) SSLServerSocketFactory.getDefault(); > >> SSLServerSocket sslserversocket = (SSLServerSocket) > >> sslserversocketfactory.createServerSocket(9999); > >> SSLSocket sslsocket = (SSLSocket) sslserversocket.accept(); > >> > >> InputStream inputstream = sslsocket.getInputStream(); > >> > >> byte[] buf = new byte[Helper.BUF_SIZE]; > >> long bytesToRead = BYTES_TO_READ; > >> > >> long startTime = System.currentTimeMillis(); > >> > >> while (bytesToRead > 0) { > >> bytesToRead -= inputstream.read(buf); > >> } > >> > >> long stopTime = System.currentTimeMillis(); > >> long totalTimeMs = stopTime - startTime; > >> double mbRead = BYTES_TO_READ / (1024.0 * 1024); > >> double totalTimeSeconds = totalTimeMs / 1000.0; > >> double mibPerSecond = mbRead / totalTimeSeconds; > >> > >> System.out.println("Using cipher suite: " + > >> (sslsocket.getSession()).getCipherSuite()); > >> System.out.println("Read " + mbRead + "MiB in " + > >> totalTimeSeconds + "s"); > >> System.out.println("Bandwidth: " + mibPerSecond + "MiB/s"); > >> > >> } catch (IOException exception) { > >> exception.printStackTrace(); > >> } > >> } > >> > >> private static final int BYTES_TO_READ = Helper.BUF_COUNT * > >> Helper.BUF_SIZE; > >> } > >> > >> ///// Helper.java > >> > >> package ssl; > >> > >> import java.util.*; > >> import java.util.regex.*; > >> import javax.net.ssl.*; > >> > >> public class Helper { > >> > >> static int BUF_SIZE = 1024 * 1024; > >> static int BUF_COUNT = 100; > >> > >> static SSLSocket requireAESCipherSuites(SSLSocket socket) { > >> String supportedCipherSuites[] = > >> socket.getSupportedCipherSuites(); > >> > >> System.out.println("Supported cipher suite: " + > >> Arrays.toString(supportedCipherSuites)); > >> > >> List<String> selectedCipherSuites = new ArrayList<>(); > >> > >> // String patternString = ".*"; > >> String patternString = > "TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256"; > >> // String patternString = > >> "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256"; > >> > >> Pattern pattern = Pattern.compile(patternString); > >> > >> for (String cipherSuite : supportedCipherSuites) { > >> Matcher matcher = pattern.matcher(cipherSuite); > >> if (matcher.find()) { > >> selectedCipherSuites.add(cipherSuite); > >> } > >> } > >> > >> System.out.println("Selected cipher suites: " + > >> selectedCipherSuites); > >> > >> socket.setEnabledCipherSuites(selectedCipherSuites.toArray(new > >> String[0])); > >> > >> return socket; > >> } > >> } > >> > > -- Mark Christiaens Ganzeplas 23 9880 Aalter 09 / 325 07 40