document the gnutls_pcert_st
[gnutls.git] / src / benchmark-tls.c
blobb941c5cd6846b79548d3c6b08eac52ff976cc66f
1 /*
2 * Copyright (C) 2011-2012 Free Software Foundation, Inc.
4 * Author: Nikos Mavrogiannopoulos
6 * This file is part of GnuTLS.
8 * GnuTLS is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 3 of the License, or
11 * (at your option) any later version.
13 * GnuTLS is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with GnuTLS; if not, write to the Free Software Foundation,
20 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #include <errno.h>
31 #include <gnutls/gnutls.h>
32 #include <gnutls/crypto.h>
34 #define fail(...) \
35 { \
36 fprintf(stderr, __VA_ARGS__); \
37 exit(1); \
40 #include "../tests/eagain-common.h"
41 #include "benchmark.h"
43 const char* side = "";
45 #define PRIO_DH "NONE:+VERS-TLS1.0:+AES-128-CBC:+SHA1:+SIGN-ALL:+COMP-NULL:+DHE-RSA"
46 #define PRIO_ECDH "NONE:+VERS-TLS1.0:+AES-128-CBC:+SHA1:+SIGN-ALL:+COMP-NULL:+ECDHE-RSA:+CURVE-SECP192R1"
47 #define PRIO_ECDHE_ECDSA "NONE:+VERS-TLS1.0:+AES-128-CBC:+SHA1:+SIGN-ALL:+COMP-NULL:+ECDHE-ECDSA:+CURVE-SECP192R1"
48 #define PRIO_RSA "NONE:+VERS-TLS1.0:+AES-128-CBC:+SHA1:+SIGN-ALL:+COMP-NULL:+RSA"
50 #define PRIO_AES_CBC_SHA1 "NONE:+VERS-TLS1.0:+AES-128-CBC:+SHA1:+SIGN-ALL:+COMP-NULL:+ANON-DH"
51 #define PRIO_ARCFOUR_128_MD5 "NONE:+VERS-TLS1.0:+ARCFOUR-128:+MD5:+SIGN-ALL:+COMP-NULL:+ANON-DH"
52 #define PRIO_AES_GCM "NONE:+VERS-TLS1.2:+AES-128-GCM:+AEAD:+SIGN-ALL:+COMP-NULL:+ANON-DH"
53 #define PRIO_CAMELLIA_CBC_SHA1 "NONE:+VERS-TLS1.0:+CAMELLIA-128-CBC:+SHA1:+SIGN-ALL:+COMP-NULL:+ANON-DH"
55 static const int rsa_bits = 1776, ec_bits = 192;
57 /* DH of 1840 bits that is pretty close equivalent to 192 bits of ECDH.
59 const char *pkcs3 =
60 "-----BEGIN DH PARAMETERS-----\n"
61 "MIIBxgKB3gNZMD2odqYk7HGnT+kh72vcnGrDhFMad1m4VlYZoLClkRUOH05W9gKF\n"
62 "hjBzlg5zO1Pp14hpSNWdfXcd2glWE2wzkxxxztzt23gdXK1GjfupnALyPS2Q0Oj7\n"
63 "UiLDfos46vXOSzqO3vBElM2HJQ6N1TRU+EqD5t/6aTAV6iAD+yz2Fyv4Xs+rgJC2\n"
64 "IbpunLzM2IhH2u9tLUXGkBzHPW/6Q+fJRhn88OLBC9vwOHPQvw779+FB0NPue1Qs\n"
65 "vb+4HSywpOr4BtNLWST2MzhCYBApvV1dKcZLI5k5Cfmp5ryV+wKB3gEUe9uAk+5I\n"
66 "ENkTLC7XLLNGjPEKwQhBzE7Nh7RKWlZRX+B/cX5/iT7ZF9+N83O/wf2AxEV6CRWV\n"
67 "WiCjvML/wbskpGoGmrPyef7bLHI62x4/nNacGGWEichPW8Sn/qaT80FHyYM0m7Ha\n"
68 "+Q9kYUSx0u1CW//3nGvma5dh/c2iiq8r7J9w2PSYynHts4bYMrRRx2PVeGhvU8+X\n"
69 "nRkYOqptEqoB6NG5kPRL8b5jJSp7J2hN7shDjQB/s9/N8rvF8tRmMUTJpk3Fwr9F\n"
70 "LVdX3640cbukwFTKlkqZ1evymVzx0wICAL0=\n"
71 "-----END DH PARAMETERS-----\n";
73 static unsigned char server_cert_pem[] =
74 "-----BEGIN CERTIFICATE-----\n"
75 "MIIEEzCCAx6gAwIBAgIBBzANBgkqhkiG9w0BAQsFADCBuDELMAkGA1UEBhMCR1Ix\n"
76 "EjAQBgNVBAoTCUtva28gaW5jLjEXMBUGA1UECxMOc2xlZXBpbmcgZGVwdC4xDzAN\n"
77 "BgNVBAgTBkF0dGlraTEVMBMGA1UEAxMMQ2luZHkgTGF1cGVyMRcwFQYKCZImiZPy\n"
78 "LGQBARMHY2xhdXBlcjEMMAoGA1UEDBMDRHIuMQ8wDQYDVQRBEwZqYWNrYWwxHDAa\n"
79 "BgkqhkiG9w0BCQEWDW5vbmVAbm9uZS5vcmcwIhgPMjAxMjA2MDYxOTAxMjdaGA8y\n"
80 "MDE5MDcxMDE5MDEyN1owgbgxCzAJBgNVBAYTAkdSMRIwEAYDVQQKEwlLb2tvIGlu\n"
81 "Yy4xFzAVBgNVBAsTDnNsZWVwaW5nIGRlcHQuMQ8wDQYDVQQIEwZBdHRpa2kxFTAT\n"
82 "BgNVBAMTDENpbmR5IExhdXBlcjEXMBUGCgmSJomT8ixkAQETB2NsYXVwZXIxDDAK\n"
83 "BgNVBAwTA0RyLjEPMA0GA1UEQRMGamFja2FsMRwwGgYJKoZIhvcNAQkBFg1ub25l\n"
84 "QG5vbmUub3JnMIH9MA0GCSqGSIb3DQEBAQUAA4HrADCB5wKB3wC/VSBHG5adM0r0\n"
85 "E80dgVvt+oVnnDcKYcm9q2WbknTL6dFgjjcEbiHDKmnr1hgyT9jfQVE/ve2XnZqA\n"
86 "kbpYMNrQbdieclNycjoXCj3BJSJXXz3Ra6O4DLNh0/XwsxbVd/tMSQvwAK0MR60K\n"
87 "/yfruL2oxe8j7uDmS5oY8b5O9nP/EVW2u7P1KVhrNxC2rGoaK6iRpgkAX3oP2YVM\n"
88 "hLfPONpDgYGxBvrO0tlpHCYL+miWdRzIDPMYtdcU1v1zVSKAsvJ2dgEwP6FoSiWP\n"
89 "nkw3U41i4oe+T7kVEk1F9QLCnXsCAwEAAaNrMGkwDAYDVR0TAQH/BAIwADAUBgNV\n"
90 "HREEDTALgglsb2NhbGhvc3QwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDwYDVR0PAQH/\n"
91 "BAUDAwegADAdBgNVHQ4EFgQUMwvofEmn5CtM4GygipfIuebOssgwDQYJKoZIhvcN\n"
92 "AQELBQADgd8AdP87xzJGv3ddODGoCaVNipkO96HDwt1fC4Jtp1VTn1V4JRaL4e4D\n"
93 "0dlFMq30kmrLTxNSET7MJ5l2m0XZS7jhbl5UW9jLCv1GurMaVuYK4v0LGGezODoH\n"
94 "8naZkxWYGS16kssPu0SDE0V9gWF31IXs2qs0PHvvpI5WFmjrOPX3RfFeVNhmc5sv\n"
95 "1cy+hnM9wxcT2r+jpKn3mYVVcnG7ANZyLKzLwN/PGkYB+tv8sS0ojxMKZLQjr9xs\n"
96 "z1plHeDzm0/t7gsAkrL8ynSkBBJ1SLqaKMmlP1DmgU/zTlMTyKrG\n"
97 "-----END CERTIFICATE-----\n";
99 static unsigned char server_key_pem[] =
100 "-----BEGIN RSA PRIVATE KEY-----\n"
101 "MIIEBAIBAAKB3wC/VSBHG5adM0r0E80dgVvt+oVnnDcKYcm9q2WbknTL6dFgjjcE\n"
102 "biHDKmnr1hgyT9jfQVE/ve2XnZqAkbpYMNrQbdieclNycjoXCj3BJSJXXz3Ra6O4\n"
103 "DLNh0/XwsxbVd/tMSQvwAK0MR60K/yfruL2oxe8j7uDmS5oY8b5O9nP/EVW2u7P1\n"
104 "KVhrNxC2rGoaK6iRpgkAX3oP2YVMhLfPONpDgYGxBvrO0tlpHCYL+miWdRzIDPMY\n"
105 "tdcU1v1zVSKAsvJ2dgEwP6FoSiWPnkw3U41i4oe+T7kVEk1F9QLCnXsCAwEAAQKB\n"
106 "3iYR2gpMAvvkaNWH2xgz1QbVAhZLjugR7QJASEdcLMEmFPMRWQEYqL8cgVbbkpTw\n"
107 "Lka9yFzWfZ/dTBCo7lr93Yv7T063kMME12oeL4tuyBZ6bOJueHT2kfq1Igpyl+iB\n"
108 "pw7WuflXKRd4a4X0nwzYBQxYWH7bKkQRZDlViKuOXKVzgT7GqD6cbTZbc/8wUTi7\n"
109 "HoyMlz4d+YH/XL5Zt6SM7cMuJ/VOGGUcBiXqlixzulloihkPwJeg6zxx0e1dVy4q\n"
110 "jvVhb+hmypWajjBDPUwIGFih0lZJ6rqIDyls/ZK2AQJwAPFeAMubo1KWcFU+nHoK\n"
111 "Q/jdOjpuAt7fwczkqhb6uOrJtS4RUtF3x3jfESFYf6Btnt6Slj1HpNKHbud2Weyw\n"
112 "i3lIkkmQq4+8uRjZXlNtp2Sd33NFeYE1D8ll3V2wiwiCOPJxYWpOOwHs7pkcOsAD\n"
113 "ywJwAMruluGFAUhoCxXOGzbJeXOC0U+LbwU72Xgk9zhEX6chaklKgdSnJ8DlHnYe\n"
114 "R+wc2vXRfSGlT1OH0X8ezn82QV8UmYo6cNpMTNarW0rzpFir51owvYSBPnPB+DLX\n"
115 "0JausRZoI6fyZSw4Vxt9PN13EQJwANnEX2FUfcmQs68le1ZclrEdIGEBSpO9PARZ\n"
116 "tuBeu6IR9OaoeJlGwXDbiYAVcajT3oefp++ICTxtNvGchUuYiW4WvO2kmjVoJ3Q1\n"
117 "Afaxs1qDWcyNvS+HKUQjJNNX6kj1/N040JRyGqkFFMyNfLArewJwAL/KfLkJjmvT\n"
118 "QV7LW3cNNYbRRWdLXZLxvJfLQAdiv5BiiWRZUZkcnfq10HNMLSdfIiYfZocNCIrm\n"
119 "mz3sbLdYHLJy8qXsk8oNQLXGX9LXsCTJ2y6nUAZSbCbVVPEgfRhcZCvMIp7Q/YOs\n"
120 "f88QLx0UMQJvYsEnYagLe9EfC0d8fXTKJr143FMxas7j3eftxLEBnx7ZsqCbJD1o\n"
121 "UsvWkp5I3kqIABEqY1ZJV/gU41MceuWURSVADpuuRDLzv8WPdeffad9o2hX/bkI6\n"
122 "2INKeuq1nILiEHAZLloH6/fdjpWZYF0D\n"
123 "-----END RSA PRIVATE KEY-----\n";
125 static unsigned char server_ecc_key_pem[] =
126 "-----BEGIN EC PRIVATE KEY-----\n"
127 "MGACAQEEGQCovzs4UsfRncfJXO3WOZUe/Zf+usKzEcWgCgYIKoZIzj0DAQGhNAMy\n"
128 "AAREwuCcUHKNWyetsymkAaqA0GCgksI2AjewpOWsraGrfea3GPw1uuyOQRMR7kka\n"
129 "v6s=\n"
130 "-----END EC PRIVATE KEY-----\n";
132 static unsigned char server_ecc_cert_pem[] =
133 "-----BEGIN CERTIFICATE-----\n"
134 "MIIBYDCCARWgAwIBAgIETuILrDAKBggqhkjOPQQDAjAcMQswCQYDVQQGEwJCRTEN\n"
135 "MAsGA1UEChMEVGVzdDAeFw0xMTEyMDkxMzIyNTJaFw0xNzA4MTExMzIyNTlaMBwx\n"
136 "CzAJBgNVBAYTAkJFMQ0wCwYDVQQKEwRUZXN0MEkwEwYHKoZIzj0CAQYIKoZIzj0D\n"
137 "AQEDMgAERMLgnFByjVsnrbMppAGqgNBgoJLCNgI3sKTlrK2hq33mtxj8NbrsjkET\n"
138 "Ee5JGr+ro1UwUzAMBgNVHRMBAf8EAjAAMBMGA1UdJQQMMAoGCCsGAQUFBwMBMA8G\n"
139 "A1UdDwEB/wQFAwMHgAAwHQYDVR0OBBYEFKeR27mtYWFaH43U2zEvjd28Zf+CMAoG\n"
140 "CCqGSM49BAMCAzkAMDYCGQD7WWWiFV+ddI7tIyMFepKFA1dX4nlc/+ICGQCCPdHc\n"
141 "gMyHv2XyfOGHLhq0HmDTOOiwfC4=\n"
142 "-----END CERTIFICATE-----\n";
144 const gnutls_datum_t server_cert = { server_cert_pem,
145 sizeof (server_cert_pem)
148 const gnutls_datum_t server_key = { server_key_pem,
149 sizeof (server_key_pem)
152 const gnutls_datum_t server_ecc_cert = { server_ecc_cert_pem,
153 sizeof (server_ecc_cert_pem)
156 const gnutls_datum_t server_ecc_key = { server_ecc_key_pem,
157 sizeof (server_ecc_key_pem)
160 char buffer[64 * 1024];
162 static void tls_log_func(int level, const char *str)
164 fprintf(stderr, "%s|<%d>| %s", side, level, str);
167 static void test_ciphersuite(const char *cipher_prio, int size)
169 /* Server stuff. */
170 gnutls_anon_server_credentials_t s_anoncred;
171 const gnutls_datum_t p3 = { (void*) pkcs3, strlen(pkcs3) };
172 static gnutls_dh_params_t dh_params;
173 gnutls_session_t server;
174 int sret, cret;
175 const char *str;
176 /* Client stuff. */
177 gnutls_anon_client_credentials_t c_anoncred;
178 gnutls_session_t client;
179 /* Need to enable anonymous KX specifically. */
180 int ret;
181 struct benchmark_st st;
183 /* Init server */
184 gnutls_anon_allocate_server_credentials(&s_anoncred);
185 gnutls_dh_params_init(&dh_params);
186 gnutls_dh_params_import_pkcs3(dh_params, &p3, GNUTLS_X509_FMT_PEM);
187 gnutls_anon_set_server_dh_params(s_anoncred, dh_params);
188 gnutls_init(&server, GNUTLS_SERVER);
189 ret = gnutls_priority_set_direct(server, cipher_prio, &str);
190 if (ret < 0) {
191 fprintf(stderr, "Error in %s\n", str);
192 exit(1);
194 gnutls_credentials_set(server, GNUTLS_CRD_ANON, s_anoncred);
195 gnutls_dh_set_prime_bits(server, 1024);
196 gnutls_transport_set_push_function(server, server_push);
197 gnutls_transport_set_pull_function(server, server_pull);
198 gnutls_transport_set_ptr(server, (gnutls_transport_ptr_t) server);
199 reset_buffers();
201 /* Init client */
202 gnutls_anon_allocate_client_credentials(&c_anoncred);
203 gnutls_init(&client, GNUTLS_CLIENT);
205 ret = gnutls_priority_set_direct(client, cipher_prio, &str);
206 if (ret < 0) {
207 fprintf(stderr, "Error in %s\n", str);
208 exit(1);
210 gnutls_credentials_set(client, GNUTLS_CRD_ANON, c_anoncred);
211 gnutls_transport_set_push_function(client, client_push);
212 gnutls_transport_set_pull_function(client, client_pull);
213 gnutls_transport_set_ptr(client, (gnutls_transport_ptr_t) client);
215 HANDSHAKE(client, server);
217 fprintf(stdout, "Testing %s with %d packet size: ",
218 gnutls_cipher_suite_get_name(gnutls_kx_get(server),
219 gnutls_cipher_get(server),
220 gnutls_mac_get(server)), size);
221 fflush(stdout);
223 gnutls_rnd(GNUTLS_RND_NONCE, buffer, sizeof(buffer));
225 start_benchmark(&st);
227 do {
228 do {
229 ret = gnutls_record_send(client, buffer, size);
231 while (ret == GNUTLS_E_AGAIN);
233 if (ret < 0) {
234 fprintf(stderr, "Failed sending to server\n");
235 exit(1);
238 do {
239 ret = gnutls_record_recv(server, buffer, sizeof(buffer));
241 while (ret == GNUTLS_E_AGAIN);
243 if (ret < 0) {
244 fprintf(stderr, "Failed receiving from client\n");
245 exit(1);
248 st.size += size;
250 while (benchmark_must_finish == 0);
252 stop_benchmark(&st, NULL);
254 gnutls_bye(client, GNUTLS_SHUT_WR);
255 gnutls_bye(server, GNUTLS_SHUT_WR);
257 gnutls_deinit(client);
258 gnutls_deinit(server);
260 gnutls_anon_free_client_credentials(c_anoncred);
261 gnutls_anon_free_server_credentials(s_anoncred);
263 gnutls_dh_params_deinit(dh_params);
267 static void test_ciphersuite_kx(const char *cipher_prio)
269 /* Server stuff. */
270 gnutls_anon_server_credentials_t s_anoncred;
271 const gnutls_datum_t p3 = { (void*) pkcs3, strlen(pkcs3) };
272 static gnutls_dh_params_t dh_params;
273 gnutls_session_t server;
274 int sret, cret;
275 const char *str;
276 const char *suite = NULL;
277 /* Client stuff. */
278 gnutls_anon_client_credentials_t c_anoncred;
279 gnutls_certificate_credentials_t c_certcred, s_certcred;
280 gnutls_session_t client;
281 /* Need to enable anonymous KX specifically. */
282 int ret;
283 struct benchmark_st st;
285 /* Init server */
286 gnutls_certificate_allocate_credentials(&s_certcred);
287 gnutls_anon_allocate_server_credentials(&s_anoncred);
288 gnutls_dh_params_init(&dh_params);
289 if ((ret=gnutls_dh_params_import_pkcs3(dh_params, &p3, GNUTLS_X509_FMT_PEM)) < 0) {
290 fprintf(stderr, "Error importing the PKCS #3 params: %s\n", gnutls_strerror(ret));
291 exit(1);
293 gnutls_anon_set_server_dh_params(s_anoncred, dh_params);
294 gnutls_certificate_set_dh_params(s_certcred, dh_params);
296 gnutls_certificate_set_x509_key_mem (s_certcred, &server_cert, &server_key,
297 GNUTLS_X509_FMT_PEM);
298 gnutls_certificate_set_x509_key_mem (s_certcred, &server_ecc_cert, &server_ecc_key,
299 GNUTLS_X509_FMT_PEM);
301 start_benchmark(&st);
303 do {
304 gnutls_init(&server, GNUTLS_SERVER);
305 ret = gnutls_priority_set_direct(server, cipher_prio, &str);
306 if (ret < 0) {
307 fprintf(stderr, "Error in %s\n", str);
308 exit(1);
310 gnutls_credentials_set(server, GNUTLS_CRD_ANON, s_anoncred);
311 gnutls_credentials_set(server, GNUTLS_CRD_CERTIFICATE, s_certcred);
312 gnutls_transport_set_push_function(server, server_push);
313 gnutls_transport_set_pull_function(server, server_pull);
314 gnutls_transport_set_ptr(server, (gnutls_transport_ptr_t) server);
315 reset_buffers();
317 /* Init client */
318 gnutls_anon_allocate_client_credentials(&c_anoncred);
319 gnutls_certificate_allocate_credentials(&c_certcred);
321 gnutls_init(&client, GNUTLS_CLIENT);
323 ret = gnutls_priority_set_direct(client, cipher_prio, &str);
324 if (ret < 0) {
325 fprintf(stderr, "Error in %s\n", str);
326 exit(1);
328 gnutls_credentials_set(client, GNUTLS_CRD_ANON, c_anoncred);
329 gnutls_credentials_set(client, GNUTLS_CRD_CERTIFICATE, c_certcred);
331 gnutls_transport_set_push_function(client, client_push);
332 gnutls_transport_set_pull_function(client, client_pull);
333 gnutls_transport_set_ptr(client, (gnutls_transport_ptr_t) client);
335 HANDSHAKE(client, server);
337 if (suite == NULL)
338 suite = gnutls_cipher_suite_get_name(gnutls_kx_get(server),
339 gnutls_cipher_get(server),
340 gnutls_mac_get(server));
342 gnutls_deinit(client);
343 gnutls_deinit(server);
345 st.size += 1;
347 while (benchmark_must_finish == 0);
349 fprintf(stdout, "Tested %s: ", suite);
350 stop_benchmark(&st, "transactions");
352 gnutls_anon_free_client_credentials(c_anoncred);
353 gnutls_anon_free_server_credentials(s_anoncred);
355 gnutls_dh_params_deinit(dh_params);
359 void benchmark_tls(int debug_level, int ciphers)
361 gnutls_global_set_log_function(tls_log_func);
362 gnutls_global_set_log_level(debug_level);
363 gnutls_global_init();
365 if (ciphers != 0)
367 printf("Testing throughput in cipher/MAC combinations:\n");
369 test_ciphersuite(PRIO_ARCFOUR_128_MD5, 1024);
370 test_ciphersuite(PRIO_ARCFOUR_128_MD5, 4096);
371 test_ciphersuite(PRIO_ARCFOUR_128_MD5, 8 * 1024);
372 test_ciphersuite(PRIO_ARCFOUR_128_MD5, 15 * 1024);
374 test_ciphersuite(PRIO_AES_GCM, 1024);
375 test_ciphersuite(PRIO_AES_GCM, 4096);
376 test_ciphersuite(PRIO_AES_GCM, 8 * 1024);
377 test_ciphersuite(PRIO_AES_GCM, 15 * 1024);
379 test_ciphersuite(PRIO_AES_CBC_SHA1, 1024);
380 test_ciphersuite(PRIO_AES_CBC_SHA1, 4096);
381 test_ciphersuite(PRIO_AES_CBC_SHA1, 8 * 1024);
382 test_ciphersuite(PRIO_AES_CBC_SHA1, 15 * 1024);
384 test_ciphersuite(PRIO_CAMELLIA_CBC_SHA1, 1024);
385 test_ciphersuite(PRIO_CAMELLIA_CBC_SHA1, 4096);
386 test_ciphersuite(PRIO_CAMELLIA_CBC_SHA1, 8 * 1024);
387 test_ciphersuite(PRIO_CAMELLIA_CBC_SHA1, 15 * 1024);
389 else
391 printf("\nTesting key exchanges (RSA/DH bits: %d, EC bits: %d):\n", rsa_bits, ec_bits);
392 test_ciphersuite_kx(PRIO_DH);
393 test_ciphersuite_kx(PRIO_ECDH);
394 test_ciphersuite_kx(PRIO_ECDHE_ECDSA);
395 test_ciphersuite_kx(PRIO_RSA);
398 gnutls_global_deinit();