19acb42f4SShuo Chen/* 29acb42f4SShuo Chen * Remember to turn off CPU frequency scaling before testing. 39acb42f4SShuo Chen */ 49acb42f4SShuo Chen 59acb42f4SShuo Chen 6a98d478eSShuo Chen#include <polarssl/ctr_drbg.h> 7a98d478eSShuo Chen#include <polarssl/error.h> 8a98d478eSShuo Chen#include <polarssl/entropy.h> 9a98d478eSShuo Chen#include <polarssl/ssl.h> 10a98d478eSShuo Chen 11a98d478eSShuo Chen#include <polarssl/certs.h> 12a98d478eSShuo Chen 13a98d478eSShuo Chen#include <muduo/base/Thread.h> 14a98d478eSShuo Chen 15a98d478eSShuo Chen#include <boost/bind.hpp> 16a98d478eSShuo Chen 17a98d478eSShuo Chen#include <stdio.h> 18a98d478eSShuo Chen#include <sys/socket.h> 199acb42f4SShuo Chen#include <sys/time.h> 20a98d478eSShuo Chen 21a98d478eSShuo Chenbool useRSA = false; 229acb42f4SShuo Chenbool useECDHE = false; 23a98d478eSShuo Chenconst int N = 500; 24a98d478eSShuo Chen 259acb42f4SShuo Chendouble now() 269acb42f4SShuo Chen{ 279acb42f4SShuo Chen struct timeval tv; 289acb42f4SShuo Chen gettimeofday(&tv, NULL); 299acb42f4SShuo Chen return tv.tv_sec + tv.tv_usec / 1000000.0; 309acb42f4SShuo Chen} 319acb42f4SShuo Chen 32a98d478eSShuo Chen// FIXME: net_recv with buffer 33a98d478eSShuo Chen 34a98d478eSShuo Chenvoid clientThread(entropy_context* entropy, int* clientFd) 35a98d478eSShuo Chen{ 36a98d478eSShuo Chen ctr_drbg_context ctr_drbg; 37a98d478eSShuo Chen ctr_drbg_init(&ctr_drbg, entropy_func, entropy, NULL, 0); 38a98d478eSShuo Chen 39a98d478eSShuo Chen ssl_context ssl; 40a98d478eSShuo Chen bzero(&ssl, sizeof ssl); 41a98d478eSShuo Chen ssl_init(&ssl); 42a98d478eSShuo Chen ssl_set_rng(&ssl, ctr_drbg_random, &ctr_drbg); 43a98d478eSShuo Chen ssl_set_bio(&ssl, &net_recv, clientFd, &net_send, clientFd); 44a98d478eSShuo Chen ssl_set_endpoint(&ssl, SSL_IS_CLIENT); 45a98d478eSShuo Chen ssl_set_authmode(&ssl, SSL_VERIFY_NONE); 46a98d478eSShuo Chen 47a98d478eSShuo Chen for (int i = 0; i < N; ++i) 48a98d478eSShuo Chen { 49a98d478eSShuo Chen ssl_session_reset( &ssl ); 50a98d478eSShuo Chen int ret = 0; 51a98d478eSShuo Chen while ( (ret = ssl_handshake(&ssl)) != 0) 52a98d478eSShuo Chen { 53a98d478eSShuo Chen if (ret != POLARSSL_ERR_NET_WANT_READ && ret != POLARSSL_ERR_NET_WANT_WRITE) 54a98d478eSShuo Chen { 55a98d478eSShuo Chen printf("client handshake failed %d\n", ret); 56a98d478eSShuo Chen break; 57a98d478eSShuo Chen } 58a98d478eSShuo Chen } 59a98d478eSShuo Chen if (i == 0) 60a98d478eSShuo Chen printf("client done %s %s\n", ssl_get_version(&ssl), ssl_get_ciphersuite(&ssl)); 61a98d478eSShuo Chen } 62a98d478eSShuo Chen 63a98d478eSShuo Chen ssl_free(&ssl); 64a98d478eSShuo Chen} 65a98d478eSShuo Chen 66a98d478eSShuo Chenvoid serverThread(entropy_context* entropy, int* serverFd) 67a98d478eSShuo Chen{ 68a98d478eSShuo Chen const char* srv_cert = test_srv_crt_ec; 69a98d478eSShuo Chen const char* srv_key = test_srv_key_ec; 70a98d478eSShuo Chen if (useRSA) 71a98d478eSShuo Chen { 72a98d478eSShuo Chen srv_cert = test_srv_crt; 73a98d478eSShuo Chen srv_key = test_srv_key; 74a98d478eSShuo Chen } 75a98d478eSShuo Chen x509_crt cert; 76a98d478eSShuo Chen x509_crt_init(&cert); 77a98d478eSShuo Chen x509_crt_parse(&cert, reinterpret_cast<const unsigned char*>(srv_cert), strlen(srv_cert)); 78a98d478eSShuo Chen x509_crt_parse(&cert, reinterpret_cast<const unsigned char*>(test_ca_list), strlen(test_ca_list)); 79a98d478eSShuo Chen 80a98d478eSShuo Chen pk_context pkey; 81a98d478eSShuo Chen pk_init(&pkey); 82a98d478eSShuo Chen pk_parse_key(&pkey, reinterpret_cast<const unsigned char*>(srv_key), strlen(srv_key), NULL, 0); 83a98d478eSShuo Chen 84a98d478eSShuo Chen ctr_drbg_context ctr_drbg; 85a98d478eSShuo Chen ctr_drbg_init(&ctr_drbg, entropy_func, entropy, NULL, 0); 86a98d478eSShuo Chen 87a98d478eSShuo Chen ssl_context ssl_server; 88a98d478eSShuo Chen bzero(&ssl_server, sizeof ssl_server); 89a98d478eSShuo Chen ssl_init(&ssl_server); 90a98d478eSShuo Chen ssl_set_rng(&ssl_server, ctr_drbg_random, &ctr_drbg); 91a98d478eSShuo Chen ssl_set_bio(&ssl_server, &net_recv, serverFd, &net_send, serverFd); 92a98d478eSShuo Chen ssl_set_endpoint(&ssl_server, SSL_IS_SERVER); 93a98d478eSShuo Chen ssl_set_authmode(&ssl_server, SSL_VERIFY_NONE); 94a98d478eSShuo Chen ssl_set_ca_chain(&ssl_server, cert.next, NULL, NULL); 95a98d478eSShuo Chen ssl_set_own_cert(&ssl_server, &cert, &pkey); 96a98d478eSShuo Chen // ssl_set_dbg(&ssl_server, my_debug, (void*)"server"); 97a98d478eSShuo Chen ecp_group_id curves[] = { POLARSSL_ECP_DP_SECP256R1, POLARSSL_ECP_DP_NONE }; 98a98d478eSShuo Chen ssl_set_curves(&ssl_server, curves); 999acb42f4SShuo Chen int ciphersuites[] = { TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, TLS_RSA_WITH_AES_256_CBC_SHA, 0 }; 1009acb42f4SShuo Chen if (!useECDHE) 1019acb42f4SShuo Chen ssl_set_ciphersuites(&ssl_server, ciphersuites); 102a98d478eSShuo Chen 103a98d478eSShuo Chen for (int i = 0; i < N; ++i) 104a98d478eSShuo Chen { 105a98d478eSShuo Chen ssl_session_reset(&ssl_server); 106a98d478eSShuo Chen int ret = 0; 107a98d478eSShuo Chen while ( (ret = ssl_handshake(&ssl_server)) != 0) 108a98d478eSShuo Chen { 109a98d478eSShuo Chen if (ret != POLARSSL_ERR_NET_WANT_READ && ret != POLARSSL_ERR_NET_WANT_WRITE) 110a98d478eSShuo Chen { 111a98d478eSShuo Chen printf("server handshake failed %d\n", ret); 112a98d478eSShuo Chen break; 113a98d478eSShuo Chen } 114a98d478eSShuo Chen } 115a98d478eSShuo Chen if (i == 0) 116a98d478eSShuo Chen printf("server done %s %s\n", ssl_get_version(&ssl_server), ssl_get_ciphersuite(&ssl_server)); 117a98d478eSShuo Chen } 118a98d478eSShuo Chen 119a98d478eSShuo Chen ssl_free(&ssl_server); 120a98d478eSShuo Chen pk_free(&pkey); 121a98d478eSShuo Chen x509_crt_free(&cert); 122a98d478eSShuo Chen} 123a98d478eSShuo Chen 124a98d478eSShuo Chenint main(int argc, char* argv[]) 125a98d478eSShuo Chen{ 126a98d478eSShuo Chen unsigned char buf[16384] = { 0 }; 127a98d478eSShuo Chen entropy_context entropy; 128a98d478eSShuo Chen entropy_init(&entropy); 129a98d478eSShuo Chen 130a98d478eSShuo Chen if (argc > 1) 131a98d478eSShuo Chen useRSA = true; 132a98d478eSShuo Chen 1339acb42f4SShuo Chen useECDHE = argc > 2; 1349acb42f4SShuo Chen 135a98d478eSShuo Chen int fds[2]; 136a98d478eSShuo Chen if (::socketpair(AF_UNIX, SOCK_STREAM, 0, fds)) 137a98d478eSShuo Chen abort(); 138a98d478eSShuo Chen 1399acb42f4SShuo Chen double start = now(); 140a98d478eSShuo Chen muduo::Thread client(boost::bind(&clientThread, &entropy, &fds[0]), "ssl client"); 141a98d478eSShuo Chen muduo::Thread server(boost::bind(&serverThread, &entropy, &fds[1]), "ssl server"); 142a98d478eSShuo Chen client.start(); 143a98d478eSShuo Chen server.start(); 144a98d478eSShuo Chen 145a98d478eSShuo Chen client.join(); 146a98d478eSShuo Chen server.join(); 1479acb42f4SShuo Chen double elapsed = now() - start; 1489acb42f4SShuo Chen printf("%.2fs %.1f handshakes/s\n", elapsed, N / elapsed); 149a98d478eSShuo Chen entropy_free(&entropy); 150a98d478eSShuo Chen} 151