From 02fd8d816bce4ef1f59ccc05d8add0f8d6f48159 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Thu, 11 Apr 2019 23:01:51 +0300 Subject: [PATCH] Add esptest microbenchmark for ESP encryption Signed-off-by: David Woodhouse --- Makefile.am | 4 ++- configure.ac | 2 +- esp.c | 4 +-- gpst.c | 2 +- libopenconnect.map.in | 2 ++ oncp.c | 4 +-- openconnect-internal.h | 2 +- tests/Makefile.am | 5 +++ tests/esptest.c | 78 ++++++++++++++++++++++++++++++++++++++++++ 9 files changed, 95 insertions(+), 8 deletions(-) create mode 100644 tests/esptest.c diff --git a/Makefile.am b/Makefile.am index 48ca991f..02fe3da2 100644 --- a/Makefile.am +++ b/Makefile.am @@ -28,7 +28,7 @@ openconnect_CFLAGS = $(AM_CFLAGS) $(SSL_CFLAGS) $(DTLS_SSL_CFLAGS) \ $(LIBXML2_CFLAGS) $(JSON_CFLAGS) $(LIBPROXY_CFLAGS) \ $(ZLIB_CFLAGS) $(LIBSTOKEN_CFLAGS) $(LIBPSKC_CFLAGS) \ $(GSSAPI_CFLAGS) $(INTL_CFLAGS) $(ICONV_CFLAGS) \ - $(LIBPCSCLITE_CFLAGS) + $(LIBPCSCLITE_CFLAGS) $(JSON_CFLAGS) openconnect_LDADD = libopenconnect.la $(SSL_LIBS) $(LIBXML2_LIBS) \ $(LIBPROXY_LIBS) $(INTL_LIBS) $(ICONV_LIBS) @@ -132,6 +132,8 @@ libopenconnect_la_LIBADD = $(SSL_LIBS) $(DTLS_SSL_LIBS) \ $(INTL_LIBS) $(ICONV_LIBS) $(LIBPCSCLITE_LIBS) $(LIBP11_LIBS)\ $(LIBLZ4_LIBS) ${JSON_LIBS} +export libopenconnect_la_CFLAGS + if OPENBSD_LIBTOOL # OpenBSD's libtool doesn't have -version-number, but its -version-info arg # does what GNU libtool's -version-number does. Which arguably is what the diff --git a/configure.ac b/configure.ac index 4145a0b1..f2a6a5bf 100644 --- a/configure.ac +++ b/configure.ac @@ -837,7 +837,7 @@ AS_IF([test "$with_builtin_json" != "no" && test "$json" = "" ], AC_SEARCH_LIBS(pow, [m]) LIBS="$oldLIBS" AC_SUBST([JSON_LIBS], [$ac_cv_search_pow]) - AC_SUBST([JSON_CFLAGS], ['-I$(srcdir)/json']) + AC_SUBST([JSON_CFLAGS], ['-I$(abs_top_srcdir)/json']) ]) AS_IF([test "$json" = ""], diff --git a/esp.c b/esp.c index c4e9e49d..0864cb3d 100644 --- a/esp.c +++ b/esp.c @@ -95,7 +95,7 @@ int esp_setup(struct openconnect_info *vpninfo) return 0; } -int construct_esp_packet(struct openconnect_info *vpninfo, struct pkt *pkt, uint8_t next_hdr) +int openconnect_construct_esp_packet(struct openconnect_info *vpninfo, struct pkt *pkt, uint8_t next_hdr) { const int blksize = 16; int i, padlen, ret; @@ -341,7 +341,7 @@ int esp_mainloop(struct openconnect_info *vpninfo, int *timeout, int readable) if (vpninfo->dtls_tos_optname) udp_tos_update(vpninfo, this); - len = construct_esp_packet(vpninfo, this, 0); + len = openconnect_construct_esp_packet(vpninfo, this, 0); if (len < 0) { /* Should we disable ESP? */ free(this); diff --git a/gpst.c b/gpst.c index 5fb1d41b..7fdeb41d 100644 --- a/gpst.c +++ b/gpst.c @@ -1492,7 +1492,7 @@ int gpst_esp_send_probes(struct openconnect_info *vpninfo) dump_buf_hex(vpninfo, PRG_TRACE, '>', pkt->data, pkt->len); } - int pktlen = construct_esp_packet(vpninfo, pkt, vpninfo->esp_magic_af == AF_INET6 ? IPPROTO_IPV6 : IPPROTO_IPIP); + int pktlen = openconnect_construct_esp_packet(vpninfo, pkt, vpninfo->esp_magic_af == AF_INET6 ? IPPROTO_IPV6 : IPPROTO_IPIP); if (pktlen < 0 || send(vpninfo->dtls_fd, (void *)&pkt->esp, pktlen, 0) < 0) vpn_progress(vpninfo, PRG_DEBUG, _("Failed to send ESP probe\n")); diff --git a/libopenconnect.map.in b/libopenconnect.map.in index 9e47bdf4..c845bc6e 100644 --- a/libopenconnect.map.in +++ b/libopenconnect.map.in @@ -125,6 +125,8 @@ OPENCONNECT_PRIVATE { openconnect_sha1; openconnect_version_str; openconnect_read_file; + openconnect_setup_esp_keys; + openconnect_construct_esp_packet; local: *; }; diff --git a/oncp.c b/oncp.c index 1c90918d..edc6803d 100644 --- a/oncp.c +++ b/oncp.c @@ -1261,8 +1261,8 @@ int oncp_esp_send_probes(struct openconnect_info *vpninfo) for (seq=1; seq <= (vpninfo->dtls_state==DTLS_ESTABLISHED ? 1 : 2); seq++) { pkt->len = 1; pkt->data[0] = 0; - pktlen = construct_esp_packet(vpninfo, pkt, - vpninfo->dtls_addr->sa_family == AF_INET6 ? IPPROTO_IPV6 : IPPROTO_IPIP); + pktlen = openconnect_construct_esp_packet(vpninfo, pkt, + vpninfo->dtls_addr->sa_family == AF_INET6 ? IPPROTO_IPV6 : IPPROTO_IPIP); if (pktlen < 0 || send(vpninfo->dtls_fd, (void *)&pkt->esp, pktlen, 0) < 0) vpn_progress(vpninfo, PRG_DEBUG, _("Failed to send ESP probe\n")); diff --git a/openconnect-internal.h b/openconnect-internal.h index 9574e3ff..c033b4f9 100644 --- a/openconnect-internal.h +++ b/openconnect-internal.h @@ -1177,7 +1177,7 @@ void esp_close(struct openconnect_info *vpninfo); void esp_shutdown(struct openconnect_info *vpninfo); int print_esp_keys(struct openconnect_info *vpninfo, const char *name, struct esp *esp); int openconnect_setup_esp_keys(struct openconnect_info *vpninfo, int new_keys); -int construct_esp_packet(struct openconnect_info *vpninfo, struct pkt *pkt, uint8_t next_hdr); +int openconnect_construct_esp_packet(struct openconnect_info *vpninfo, struct pkt *pkt, uint8_t next_hdr); /* {gnutls,openssl}-esp.c */ int init_esp_ciphers(struct openconnect_info *vpninfo, struct esp *out, struct esp *in); diff --git a/tests/Makefile.am b/tests/Makefile.am index e79cb3a1..5ee08be3 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -145,8 +145,13 @@ TESTS_ENVIRONMENT = srcdir="$(srcdir)" \ C_TESTS = lzstest seqtest buftest +esptest_CFLAGS = $(libopenconnect_la_CFLAGS) +esptest_LDADD = ../libopenconnect.la + if OPENCONNECT_WIN32 C_TESTS += list-taps +else +C_TESTS += esptest endif if CHECK_DTLS diff --git a/tests/esptest.c b/tests/esptest.c new file mode 100644 index 00000000..4e5689be --- /dev/null +++ b/tests/esptest.c @@ -0,0 +1,78 @@ +#include + +#include "../openconnect-internal.h" +#include + +static void write_progress(void *vpninfo, int level, const char *fmt, ...) +{ + va_list args; + + va_start(args, fmt); + vprintf(fmt, args); + va_end(args); +} + +static int pkt_size = 1400; +static long count; +static int done; + +static void handle_alrm(int sig) +{ + done = 1; +} + +int main(void) +{ + openconnect_init_ssl(); + + struct openconnect_info *vpninfo = openconnect_vpninfo_new("", NULL, NULL, NULL, write_progress, NULL); + struct pkt *pkt = malloc(128 + pkt_size); + int ret; + + vpninfo->verbose = PRG_DEBUG; + + vpninfo->esp_enc = 2; /* AES128-CBC */ + vpninfo->esp_hmac = 2; /* HMAC-SHA1 */ + vpninfo->enc_key_len = 16; + vpninfo->hmac_key_len = 20; + + vpninfo->esp_out.spi = 0x12345678; + memset(vpninfo->esp_out.enc_key, 0x5a, vpninfo->enc_key_len); + memset(vpninfo->esp_out.hmac_key, 0x5a, vpninfo->hmac_key_len); + + vpninfo->esp_in[0] = vpninfo->esp_out; + + vpninfo->dtls_state = DTLS_SLEEPING; + vpninfo->dtls_addr = (void *)vpninfo; + + ret = openconnect_setup_esp_keys(vpninfo, 0); + if (ret) { + printf("setup ESP failed: %d\n", ret); + exit(1); + } + + memset(pkt->data, 0x5a, pkt_size); + + signal(SIGALRM, handle_alrm); + + alarm(5); + while (!done) { + pkt->len = pkt_size; + openconnect_construct_esp_packet(vpninfo, pkt, IPPROTO_IPV6); + count++; + } + printf("Encrypted %ld packets in 5s (%ld Mb/s)\n", count, count * pkt_size / 5 / 250000); + + done = 0; + count = 0; + alarm(5); + while (!done) { + pkt->len = pkt_size; + pkt->len = openconnect_construct_esp_packet(vpninfo, pkt, IPPROTO_IPV6); + pkt->len -= (sizeof(pkt->esp) + vpninfo->hmac_out_len); + if (vpninfo->decrypt_esp_packet(vpninfo, &vpninfo->esp_in[0], pkt)) + exit(1); + count++; + } + printf("Encrypted+decrypted %ld packets in 5s (%ld Mb/s)\n", count, count * pkt_size / 5 / 250000); +}