benchmark-polarssl.cc revision a98d478e
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>
9a98d478eSShuo Chen#include <stdio.h>
10a98d478eSShuo Chen#include <sys/time.h>
11a98d478eSShuo Chen
12a98d478eSShuo Chenmuduo::net::Buffer clientOut, serverOut;
13a98d478eSShuo Chen
14a98d478eSShuo Chendouble now()
15a98d478eSShuo Chen{
16a98d478eSShuo Chen  struct timeval tv;
17a98d478eSShuo Chen  gettimeofday(&tv, NULL);
18a98d478eSShuo Chen  return tv.tv_sec + tv.tv_usec / 1000000.0;
19a98d478eSShuo Chen}
20a98d478eSShuo Chen
21a98d478eSShuo Chenint net_recv(void* ctx, unsigned char* buf, size_t len)
22a98d478eSShuo Chen{
23a98d478eSShuo Chen  muduo::net::Buffer* in = static_cast<muduo::net::Buffer*>(ctx);
24a98d478eSShuo Chen  //printf("%s recv %zd\n", in == &clientOut ? "server" : "client", len);
25a98d478eSShuo Chen  if (in->readableBytes() > 0)
26a98d478eSShuo Chen  {
27a98d478eSShuo Chen    size_t n = std::min(in->readableBytes(), len);
28a98d478eSShuo Chen    memcpy(buf, in->peek(), n);
29a98d478eSShuo Chen    in->retrieve(n);
30a98d478eSShuo Chen
31a98d478eSShuo Chen    /*
32a98d478eSShuo Chen    if (n < len)
33a98d478eSShuo Chen      printf("got %zd\n", n);
34a98d478eSShuo Chen    else
35a98d478eSShuo Chen      printf("\n");
36a98d478eSShuo Chen      */
37a98d478eSShuo Chen    return n;
38a98d478eSShuo Chen  }
39a98d478eSShuo Chen  else
40a98d478eSShuo Chen  {
41a98d478eSShuo Chen    //printf("got 0\n");
42a98d478eSShuo Chen    return POLARSSL_ERR_NET_WANT_READ;
43a98d478eSShuo Chen  }
44a98d478eSShuo Chen}
45a98d478eSShuo Chen
46a98d478eSShuo Chenint net_send(void* ctx, const unsigned char* buf, size_t len)
47a98d478eSShuo Chen{
48a98d478eSShuo Chen  muduo::net::Buffer* out = static_cast<muduo::net::Buffer*>(ctx);
49a98d478eSShuo Chen  // printf("%s send %zd\n", out == &clientOut ? "client" : "server", len);
50a98d478eSShuo Chen  out->append(buf, len);
51a98d478eSShuo Chen  return len;
52a98d478eSShuo Chen}
53a98d478eSShuo Chen
54a98d478eSShuo Chenint main(int argc, char* argv[])
55a98d478eSShuo Chen{
56a98d478eSShuo Chen  unsigned char buf[16384] = { 0 };
57a98d478eSShuo Chen  entropy_context entropy;
58a98d478eSShuo Chen  entropy_init(&entropy);
59a98d478eSShuo Chen  ctr_drbg_context ctr_drbg;
60a98d478eSShuo Chen  ctr_drbg_init(&ctr_drbg, entropy_func, &entropy, NULL, 0);
61a98d478eSShuo Chen
62a98d478eSShuo Chen  ssl_context ssl;
63a98d478eSShuo Chen  bzero(&ssl, sizeof ssl);
64a98d478eSShuo Chen  ssl_init(&ssl);
65a98d478eSShuo Chen  ssl_set_rng(&ssl, ctr_drbg_random, &ctr_drbg);
66a98d478eSShuo Chen  ssl_set_bio(&ssl, &net_recv, &serverOut, &net_send, &clientOut);
67a98d478eSShuo Chen  ssl_set_endpoint(&ssl, SSL_IS_CLIENT);
68a98d478eSShuo Chen  ssl_set_authmode(&ssl, SSL_VERIFY_NONE);
69a98d478eSShuo Chen
70a98d478eSShuo Chen  const char* srv_cert = test_srv_crt_ec;
71a98d478eSShuo Chen  const char* srv_key = test_srv_key_ec;
72a98d478eSShuo Chen  bool useRSA = argc > 1;
73a98d478eSShuo Chen  if (useRSA)
74a98d478eSShuo Chen  {
75a98d478eSShuo Chen    srv_cert = test_srv_crt;
76a98d478eSShuo Chen    srv_key = test_srv_key;
77a98d478eSShuo Chen  }
78a98d478eSShuo Chen  x509_crt cert;
79a98d478eSShuo Chen  x509_crt_init(&cert);
80a98d478eSShuo Chen  // int ret = x509_crt_parse_file(&cert, argv[1]);
81a98d478eSShuo Chen  // printf("cert parse %d\n", ret);
82a98d478eSShuo Chen  x509_crt_parse(&cert, reinterpret_cast<const unsigned char*>(srv_cert), strlen(srv_cert));
83a98d478eSShuo Chen  x509_crt_parse(&cert, reinterpret_cast<const unsigned char*>(test_ca_list), strlen(test_ca_list));
84a98d478eSShuo Chen
85a98d478eSShuo Chen  pk_context pkey;
86a98d478eSShuo Chen  pk_init(&pkey);
87a98d478eSShuo Chen  pk_parse_key(&pkey, reinterpret_cast<const unsigned char*>(srv_key), strlen(srv_key), NULL, 0);
88a98d478eSShuo Chen  // ret = pk_parse_keyfile(&pkey, argv[2], NULL);
89a98d478eSShuo Chen  // printf("key parse %d\n", ret);
90a98d478eSShuo Chen
91a98d478eSShuo Chen  ssl_context ssl_server;
92a98d478eSShuo Chen  bzero(&ssl_server, sizeof ssl_server);
93a98d478eSShuo Chen  ssl_init(&ssl_server);
94a98d478eSShuo Chen  ssl_set_rng(&ssl_server, ctr_drbg_random, &ctr_drbg);
95a98d478eSShuo Chen  ssl_set_bio(&ssl_server, &net_recv, &clientOut, &net_send, &serverOut);
96a98d478eSShuo Chen  ssl_set_endpoint(&ssl_server, SSL_IS_SERVER);
97a98d478eSShuo Chen  ssl_set_authmode(&ssl_server, SSL_VERIFY_NONE);
98a98d478eSShuo Chen  //ssl_set_ca_chain(&ssl_server, cert.next, NULL, NULL);
99a98d478eSShuo Chen  ssl_set_own_cert(&ssl_server, &cert, &pkey);
100a98d478eSShuo Chen  ecp_group_id curves[] = { POLARSSL_ECP_DP_SECP256R1, POLARSSL_ECP_DP_SECP224K1, POLARSSL_ECP_DP_NONE };
101a98d478eSShuo Chen  ssl_set_curves(&ssl_server, curves);
102a98d478eSShuo Chen
103a98d478eSShuo Chen  double start = now();
104a98d478eSShuo Chen  const int N = 100;
105a98d478eSShuo Chen  for (int i = 0; i < N; ++i)
106a98d478eSShuo Chen  {
107a98d478eSShuo Chen    ssl_session_reset(&ssl);
108a98d478eSShuo Chen    ssl_session_reset(&ssl_server);
109a98d478eSShuo Chen    while (true)
110a98d478eSShuo Chen    {
111a98d478eSShuo Chen      int ret = ssl_handshake(&ssl);
112a98d478eSShuo Chen      //printf("ssl %d\n", ret);
113a98d478eSShuo Chen      if (ret < 0)
114a98d478eSShuo Chen      {
115a98d478eSShuo Chen        if (ret != POLARSSL_ERR_NET_WANT_READ)
116a98d478eSShuo Chen        {
117a98d478eSShuo Chen          char errbuf[512];
118a98d478eSShuo Chen          polarssl_strerror(ret, errbuf, sizeof errbuf);
119a98d478eSShuo Chen          printf("client error %d %s\n", ret, errbuf);
120a98d478eSShuo Chen          break;
121a98d478eSShuo Chen        }
122a98d478eSShuo Chen      }
123a98d478eSShuo Chen      else if (ret == 0 && i == 0)
124a98d478eSShuo Chen      {
125a98d478eSShuo Chen        printf("client done %s %s\n", ssl_get_version(&ssl), ssl_get_ciphersuite(&ssl));
126a98d478eSShuo Chen      }
127a98d478eSShuo Chen
128a98d478eSShuo Chen      int ret2 = ssl_handshake(&ssl_server);
129a98d478eSShuo Chen      // printf("srv %d\n", ret2);
130a98d478eSShuo Chen      if (ret2 < 0)
131a98d478eSShuo Chen      {
132a98d478eSShuo Chen        if (ret != POLARSSL_ERR_NET_WANT_READ)
133a98d478eSShuo Chen        {
134a98d478eSShuo Chen          char errbuf[512];
135a98d478eSShuo Chen          polarssl_strerror(ret2, errbuf, sizeof errbuf);
136a98d478eSShuo Chen          printf("server error %d %s\n", ret2, errbuf);
137a98d478eSShuo Chen          break;
138a98d478eSShuo Chen        }
139a98d478eSShuo Chen      }
140a98d478eSShuo Chen      else if (ret2 == 0)
141a98d478eSShuo Chen      {
142a98d478eSShuo Chen        // printf("server done %s %s\n", ssl_get_version(&ssl_server), ssl_get_ciphersuite(&ssl_server));
143a98d478eSShuo Chen      }
144a98d478eSShuo Chen
145a98d478eSShuo Chen      if (ret == 0 && ret2 == 0)
146a98d478eSShuo Chen        break;
147a98d478eSShuo Chen    }
148a98d478eSShuo Chen  }
149a98d478eSShuo Chen  double elapsed = now() - start;
150a98d478eSShuo Chen  printf("%.2fs %.1f handshakes/s\n", elapsed, N / elapsed);
151a98d478eSShuo Chen
152a98d478eSShuo Chen  double start2 = now();
153a98d478eSShuo Chen  const int M = 200;
154a98d478eSShuo Chen  for (int i = 0; i < M*1024; ++i)
155a98d478eSShuo Chen  {
156a98d478eSShuo Chen    int n = ssl_write(&ssl, buf, 1024);
157a98d478eSShuo Chen    if (n < 0)
158a98d478eSShuo Chen    {
159a98d478eSShuo Chen      char errbuf[512];
160a98d478eSShuo Chen      polarssl_strerror(n, errbuf, sizeof errbuf);
161a98d478eSShuo Chen      printf("%s\n", errbuf);
162a98d478eSShuo Chen    }
163a98d478eSShuo Chen    /*
164a98d478eSShuo Chen    n = ssl_read(&ssl_server, buf, 8192);
165a98d478eSShuo Chen    if (n != 1024)
166a98d478eSShuo Chen      break;
167a98d478eSShuo Chen    if (n < 0)
168a98d478eSShuo Chen    {
169a98d478eSShuo Chen      char errbuf[512];
170a98d478eSShuo Chen      polarssl_strerror(n, errbuf, sizeof errbuf);
171a98d478eSShuo Chen      printf("%s\n", errbuf);
172a98d478eSShuo Chen    }
173a98d478eSShuo Chen    */
174a98d478eSShuo Chen    clientOut.retrieveAll();
175a98d478eSShuo Chen  }
176a98d478eSShuo Chen  elapsed = now() - start2;
177a98d478eSShuo Chen  printf("%.2f %.1f MiB/s\n", elapsed, M / elapsed);
178a98d478eSShuo Chen
179a98d478eSShuo Chen  ssl_free(&ssl);
180a98d478eSShuo Chen  ssl_free(&ssl_server);
181a98d478eSShuo Chen  pk_free(&pkey);
182a98d478eSShuo Chen  x509_crt_free(&cert);
183a98d478eSShuo Chen  entropy_free(&entropy);
184a98d478eSShuo Chen}
185