I'm trying to do AES GCM TLS 1.2 in Java using NSS.  It works but it's very
slow.  My setup:

- Intel(R) Core(TM) i5-3210M CPU @ 2.50GHz
- Ubuntu 13.10 64 bit
- Library NSS 3.15.4
- Java(TM) SE Runtime Environment (build 1.8.0-ea-b121)

I've configured the jre/lib/security/java.security file:

...
security.provider.1=sun.security.pkcs11.SunPKCS11
${java.home}/lib/security/nss.cfg
...

This seems to be working.  I see that doing AES encryption on a buffer is
substantially faster than before.

The real thing I'm interested in is doing TLS AES GCM.  So I've written a
client and a server that transfer some data.  This is extremely slow.  I
end up transferring at a rate around 3 MB/s.

I wrote the equivalent in pure C (using OpenSSL) and I can transfer data at
a rate around 750 MB/s.

So I'm a bit at a loss.  Is this expected or not?

My test programs for AES  GCM consist of the following 3 files: A client, a
server and a shared helper file.

////////////////////////////////////////////////////////////////////////////////////////////

package aesecho;

import javax.net.ssl.*;
import java.io.*;

public class Client {

  public static void main(String[] arstring) throws IOException {
    SSLSocketFactory sslsocketfactory = (SSLSocketFactory)
SSLSocketFactory.getDefault();
    SSLSocket sslsocket = (SSLSocket)
sslsocketfactory.createSocket("localhost", 9999);
    sslsocket.setEnabledProtocols(new String[]{"TLSv1.2"});

    Helper.selectCipherSuites(sslsocket);
    long startTime = System.nanoTime();
    try (OutputStream outputstream = sslsocket.getOutputStream()) {
      final SSLSession session = sslsocket.getSession();
      System.out.println("Chosen cipher suite: " +
session.getCipherSuite());
      byte[] buffer = new byte[Helper.BUF_SIZE];

      for (int loop = 0; loop < Helper.LOOP_COUNT; ++loop) {
        outputstream.write(buffer);
        outputstream.flush();
      }
    }
    long stopTime = System.nanoTime();
    double totalTime = (stopTime - startTime) / 1e9;
    double mibs = Helper.BUF_SIZE * Helper.LOOP_COUNT / Helper.MIB;
    double bandwidth = mibs / totalTime;
    System.out.println("Bandwidth: " + bandwidth + " MiB/s");
  }
}

////////////////////////////////////////////////////////////////////////////////////////////

package aesecho;

import javax.net.ssl.*;
import java.io.*;

public class Server {

  public static void main(String[] arstring) throws IOException {
    SSLServerSocketFactory sslserversocketfactory
      = (SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
    SSLServerSocket sslserversocket
      = (SSLServerSocket) sslserversocketfactory.createServerSocket(9999);
    sslserversocket.setEnabledProtocols(new String[]{"TLSv1.2"});

    try (SSLSocket sslsocket = (SSLSocket) sslserversocket.accept()) {
      byte[] buffer = new byte[Helper.BUF_SIZE];

      for (int loop = 0; loop < Helper.LOOP_COUNT; ++loop) {
        int bytesToRead = Helper.BUF_SIZE;
        while (bytesToRead > 0) {
          InputStream inputstream = sslsocket.getInputStream();
          int bytesRead = inputstream.read(buffer);
          bytesToRead -= bytesRead;
        }
      }
    }
  }
}

////////////////////////////////////////////////////////////////////////////////////////////

package aesecho;

import java.util.*;
import java.util.regex.*;
import javax.net.ssl.SSLSocket;

public class Helper {

  static final int LOOP_COUNT = 1;
  static final int MIB = 1024 * 1024;
  static final int BUF_SIZE = MIB * 10;

  static SSLSocket selectCipherSuites(SSLSocket socket) {
    String supportedCipherSuites[] = socket.getSupportedCipherSuites();
    System.out.println("Supported cipher suites: " +
Arrays.toString(supportedCipherSuites));

    List<String> selectedCipherSuites = new ArrayList<>();

//    String patternString = ".*";
    String patternString = ".*AES.*128.*GCM.*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;
  }
}
-- 
dev-tech-crypto mailing list
dev-tech-crypto@lists.mozilla.org
https://lists.mozilla.org/listinfo/dev-tech-crypto

Reply via email to