benchmark-polarssl.cc revision 9acb42f4
1a98d478eSShuo Chen#include <polarssl/ctr_drbg.h>
2a98d478eSShuo Chen#include <polarssl/error.h>
3a98d478eSShuo Chen#include <polarssl/entropy.h>
4a98d478eSShuo Chen#include <polarssl/ssl.h>
5a98d478eSShuo Chen
6a98d478eSShuo Chen#include <polarssl/certs.h>
7a98d478eSShuo Chen
8a98d478eSShuo Chen#include <muduo/net/Buffer.h>
99acb42f4SShuo Chen#include <string>
10a98d478eSShuo Chen#include <stdio.h>
11a98d478eSShuo Chen#include <sys/time.h>
129acb42f4SShuo Chen#include "timer.h"
13a98d478eSShuo Chen
14a98d478eSShuo Chenmuduo::net::Buffer clientOut, serverOut;
15a98d478eSShuo Chen
16a98d478eSShuo Chendouble now()
17a98d478eSShuo Chen{
18a98d478eSShuo Chen  struct timeval tv;
19a98d478eSShuo Chen  gettimeofday(&tv, NULL);
20a98d478eSShuo Chen  return tv.tv_sec + tv.tv_usec / 1000000.0;
21a98d478eSShuo Chen}
22a98d478eSShuo Chen
23a98d478eSShuo Chenint net_recv(void* ctx, unsigned char* buf, size_t len)
24a98d478eSShuo Chen{
25a98d478eSShuo Chen  muduo::net::Buffer* in = static_cast<muduo::net::Buffer*>(ctx);
26a98d478eSShuo Chen  //printf("%s recv %zd\n", in == &clientOut ? "server" : "client", len);
27a98d478eSShuo Chen  if (in->readableBytes() > 0)
28a98d478eSShuo Chen  {
29a98d478eSShuo Chen    size_t n = std::min(in->readableBytes(), len);
30a98d478eSShuo Chen    memcpy(buf, in->peek(), n);
31a98d478eSShuo Chen    in->retrieve(n);
32a98d478eSShuo Chen
33a98d478eSShuo Chen    /*
34a98d478eSShuo Chen    if (n < len)
35a98d478eSShuo Chen      printf("got %zd\n", n);
36a98d478eSShuo Chen    else
37a98d478eSShuo Chen      printf("\n");
38a98d478eSShuo Chen      */
39a98d478eSShuo Chen    return n;
40a98d478eSShuo Chen  }
41a98d478eSShuo Chen  else
42a98d478eSShuo Chen  {
43a98d478eSShuo Chen    //printf("got 0\n");
44a98d478eSShuo Chen    return POLARSSL_ERR_NET_WANT_READ;
45a98d478eSShuo Chen  }
46a98d478eSShuo Chen}
47a98d478eSShuo Chen
48a98d478eSShuo Chenint net_send(void* ctx, const unsigned char* buf, size_t len)
49a98d478eSShuo Chen{
50a98d478eSShuo Chen  muduo::net::Buffer* out = static_cast<muduo::net::Buffer*>(ctx);
51a98d478eSShuo Chen  // printf("%s send %zd\n", out == &clientOut ? "client" : "server", len);
52a98d478eSShuo Chen  out->append(buf, len);
53a98d478eSShuo Chen  return len;
54a98d478eSShuo Chen}
55a98d478eSShuo Chen
56a98d478eSShuo Chenint main(int argc, char* argv[])
57a98d478eSShuo Chen{
58a98d478eSShuo Chen  entropy_context entropy;
59a98d478eSShuo Chen  entropy_init(&entropy);
60a98d478eSShuo Chen  ctr_drbg_context ctr_drbg;
61a98d478eSShuo Chen  ctr_drbg_init(&ctr_drbg, entropy_func, &entropy, NULL, 0);
62a98d478eSShuo Chen
63a98d478eSShuo Chen  ssl_context ssl;
64a98d478eSShuo Chen  bzero(&ssl, sizeof ssl);
65a98d478eSShuo Chen  ssl_init(&ssl);
66a98d478eSShuo Chen  ssl_set_rng(&ssl, ctr_drbg_random, &ctr_drbg);
67a98d478eSShuo Chen  ssl_set_bio(&ssl, &net_recv, &serverOut, &net_send, &clientOut);
68a98d478eSShuo Chen  ssl_set_endpoint(&ssl, SSL_IS_CLIENT);
69a98d478eSShuo Chen  ssl_set_authmode(&ssl, SSL_VERIFY_NONE);
70a98d478eSShuo Chen
71a98d478eSShuo Chen  const char* srv_cert = test_srv_crt_ec;
72a98d478eSShuo Chen  const char* srv_key = test_srv_key_ec;
739acb42f4SShuo Chen  std::string arg = argc > 1 ? argv[1] : "r";
749acb42f4SShuo Chen  bool useRSA = arg == "r" || arg == "er";
759acb42f4SShuo Chen  bool useECDHE = arg == "er" || arg == "ee";
76a98d478eSShuo Chen  if (useRSA)
77a98d478eSShuo Chen  {
78a98d478eSShuo Chen    srv_cert = test_srv_crt;
79a98d478eSShuo Chen    srv_key = test_srv_key;
80a98d478eSShuo Chen  }
81a98d478eSShuo Chen  x509_crt cert;
82a98d478eSShuo Chen  x509_crt_init(&cert);
83a98d478eSShuo Chen  // int ret = x509_crt_parse_file(&cert, argv[1]);
84a98d478eSShuo Chen  // printf("cert parse %d\n", ret);
85a98d478eSShuo Chen  x509_crt_parse(&cert, reinterpret_cast<const unsigned char*>(srv_cert), strlen(srv_cert));
86a98d478eSShuo Chen  x509_crt_parse(&cert, reinterpret_cast<const unsigned char*>(test_ca_list), strlen(test_ca_list));
87a98d478eSShuo Chen
88a98d478eSShuo Chen  pk_context pkey;
89a98d478eSShuo Chen  pk_init(&pkey);
90a98d478eSShuo Chen  pk_parse_key(&pkey, reinterpret_cast<const unsigned char*>(srv_key), strlen(srv_key), NULL, 0);
91a98d478eSShuo Chen  // ret = pk_parse_keyfile(&pkey, argv[2], NULL);
92a98d478eSShuo Chen  // printf("key parse %d\n", ret);
93a98d478eSShuo Chen
94a98d478eSShuo Chen  ssl_context ssl_server;
95a98d478eSShuo Chen  bzero(&ssl_server, sizeof ssl_server);
96a98d478eSShuo Chen  ssl_init(&ssl_server);
97a98d478eSShuo Chen  ssl_set_rng(&ssl_server, ctr_drbg_random, &ctr_drbg);
98a98d478eSShuo Chen  ssl_set_bio(&ssl_server, &net_recv, &clientOut, &net_send, &serverOut);
99a98d478eSShuo Chen  ssl_set_endpoint(&ssl_server, SSL_IS_SERVER);
100a98d478eSShuo Chen  ssl_set_authmode(&ssl_server, SSL_VERIFY_NONE);
101a98d478eSShuo Chen  //ssl_set_ca_chain(&ssl_server, cert.next, NULL, NULL);
102a98d478eSShuo Chen  ssl_set_own_cert(&ssl_server, &cert, &pkey);
103a98d478eSShuo Chen  ecp_group_id curves[] = { POLARSSL_ECP_DP_SECP256R1, POLARSSL_ECP_DP_SECP224K1, POLARSSL_ECP_DP_NONE };
104a98d478eSShuo Chen  ssl_set_curves(&ssl_server, curves);
1059acb42f4SShuo Chen  if (useECDHE)
1069acb42f4SShuo Chen  {
1079acb42f4SShuo Chen    int ciphersuites[] = { TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, 0 };
1089acb42f4SShuo Chen    ssl_set_ciphersuites(&ssl_server, ciphersuites);
1099acb42f4SShuo Chen  }
1109acb42f4SShuo Chen  else
1119acb42f4SShuo Chen  {
1129acb42f4SShuo Chen    int ciphersuites[] = { TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, TLS_RSA_WITH_AES_256_CBC_SHA, 0 };
1139acb42f4SShuo Chen    ssl_set_ciphersuites(&ssl_server, ciphersuites);
1149acb42f4SShuo Chen  }
115a98d478eSShuo Chen
116a98d478eSShuo Chen  double start = now();
1179acb42f4SShuo Chen  Timer tc, ts;
1189acb42f4SShuo Chen  const int N = 500;
119a98d478eSShuo Chen  for (int i = 0; i < N; ++i)
120a98d478eSShuo Chen  {
121a98d478eSShuo Chen    ssl_session_reset(&ssl);
122a98d478eSShuo Chen    ssl_session_reset(&ssl_server);
123a98d478eSShuo Chen    while (true)
124a98d478eSShuo Chen    {
1259acb42f4SShuo Chen      tc.start();
126a98d478eSShuo Chen      int ret = ssl_handshake(&ssl);
1279acb42f4SShuo Chen      tc.stop();
128a98d478eSShuo Chen      //printf("ssl %d\n", ret);
129a98d478eSShuo Chen      if (ret < 0)
130a98d478eSShuo Chen      {
131a98d478eSShuo Chen        if (ret != POLARSSL_ERR_NET_WANT_READ)
132a98d478eSShuo Chen        {
133a98d478eSShuo Chen          char errbuf[512];
134a98d478eSShuo Chen          polarssl_strerror(ret, errbuf, sizeof errbuf);
135a98d478eSShuo Chen          printf("client error %d %s\n", ret, errbuf);
136a98d478eSShuo Chen          break;
137a98d478eSShuo Chen        }
138a98d478eSShuo Chen      }
139a98d478eSShuo Chen      else if (ret == 0 && i == 0)
140a98d478eSShuo Chen      {
141a98d478eSShuo Chen        printf("client done %s %s\n", ssl_get_version(&ssl), ssl_get_ciphersuite(&ssl));
142a98d478eSShuo Chen      }
143a98d478eSShuo Chen
1449acb42f4SShuo Chen      ts.start();
145a98d478eSShuo Chen      int ret2 = ssl_handshake(&ssl_server);
1469acb42f4SShuo Chen      ts.stop();
147a98d478eSShuo Chen      // printf("srv %d\n", ret2);
148a98d478eSShuo Chen      if (ret2 < 0)
149a98d478eSShuo Chen      {
150a98d478eSShuo Chen        if (ret != POLARSSL_ERR_NET_WANT_READ)
151a98d478eSShuo Chen        {
152a98d478eSShuo Chen          char errbuf[512];
153a98d478eSShuo Chen          polarssl_strerror(ret2, errbuf, sizeof errbuf);
154a98d478eSShuo Chen          printf("server error %d %s\n", ret2, errbuf);
155a98d478eSShuo Chen          break;
156a98d478eSShuo Chen        }
157a98d478eSShuo Chen      }
158a98d478eSShuo Chen      else if (ret2 == 0)
159a98d478eSShuo Chen      {
160a98d478eSShuo Chen        // printf("server done %s %s\n", ssl_get_version(&ssl_server), ssl_get_ciphersuite(&ssl_server));
161a98d478eSShuo Chen      }
162a98d478eSShuo Chen
163a98d478eSShuo Chen      if (ret == 0 && ret2 == 0)
164a98d478eSShuo Chen        break;
165a98d478eSShuo Chen    }
166a98d478eSShuo Chen  }
167a98d478eSShuo Chen  double elapsed = now() - start;
168a98d478eSShuo Chen  printf("%.2fs %.1f handshakes/s\n", elapsed, N / elapsed);
1699acb42f4SShuo Chen  printf("client %.3f %.1f\n", tc.seconds(), N / tc.seconds());
1709acb42f4SShuo Chen  printf("server %.3f %.1f\n", ts.seconds(), N / ts.seconds());
1719acb42f4SShuo Chen  printf("server/client %.2f\n", ts.seconds() / tc.seconds());
172a98d478eSShuo Chen
173a98d478eSShuo Chen  double start2 = now();
174a98d478eSShuo Chen  const int M = 200;
1759acb42f4SShuo Chen  unsigned char buf[16384] = { 0 };
176a98d478eSShuo Chen  for (int i = 0; i < M*1024; ++i)
177a98d478eSShuo Chen  {
178a98d478eSShuo Chen    int n = ssl_write(&ssl, buf, 1024);
179a98d478eSShuo Chen    if (n < 0)
180a98d478eSShuo Chen    {
181a98d478eSShuo Chen      char errbuf[512];
182a98d478eSShuo Chen      polarssl_strerror(n, errbuf, sizeof errbuf);
183a98d478eSShuo Chen      printf("%s\n", errbuf);
184a98d478eSShuo Chen    }
185a98d478eSShuo Chen    /*
186a98d478eSShuo Chen    n = ssl_read(&ssl_server, buf, 8192);
187a98d478eSShuo Chen    if (n != 1024)
188a98d478eSShuo Chen      break;
189a98d478eSShuo Chen    if (n < 0)
190a98d478eSShuo Chen    {
191a98d478eSShuo Chen      char errbuf[512];
192a98d478eSShuo Chen      polarssl_strerror(n, errbuf, sizeof errbuf);
193a98d478eSShuo Chen      printf("%s\n", errbuf);
194a98d478eSShuo Chen    }
195a98d478eSShuo Chen    */
196a98d478eSShuo Chen    clientOut.retrieveAll();
197a98d478eSShuo Chen  }
198a98d478eSShuo Chen  elapsed = now() - start2;
199a98d478eSShuo Chen  printf("%.2f %.1f MiB/s\n", elapsed, M / elapsed);
200a98d478eSShuo Chen
201a98d478eSShuo Chen  ssl_free(&ssl);
202a98d478eSShuo Chen  ssl_free(&ssl_server);
203a98d478eSShuo Chen  pk_free(&pkey);
204a98d478eSShuo Chen  x509_crt_free(&cert);
205a98d478eSShuo Chen  entropy_free(&entropy);
206a98d478eSShuo Chen}
207