From: Junyeon LEE Date: Wed, 28 Jun 2017 19:57:55 +0000 (+0900) Subject: examples/tls_benchmark: introduce new benchmark app X-Git-Tag: 1.1_Public_Release~318^2~78 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=84c782501d6acf645adb7aad0be96f7e7e333196;p=rtos%2Ftinyara.git examples/tls_benchmark: introduce new benchmark app This commit introduce a new crypto benchmark application. You can get a each crypto's performance with this app. MD5 : 24017 Kb/s SHA-1 : 15548 Kb/s SHA-256 : 7518 Kb/s 3DES : 1103 Kb/s DES : 2714 Kb/s AES-CBC-128 : 4202 Kb/s AES-CBC-192 : 3991 Kb/s AES-CBC-256 : 3538 Kb/s AES-GCM-128 : 1789 Kb/s .......... Change-Id: I67fd6a9139e404208a02397c7fc49f1fe4e6905b Signed-off-by: Junyeon LEE --- diff --git a/apps/examples/tls_benchmark/Kconfig b/apps/examples/tls_benchmark/Kconfig new file mode 100644 index 0000000..0135ad5 --- /dev/null +++ b/apps/examples/tls_benchmark/Kconfig @@ -0,0 +1,22 @@ +# +# For a description of the syntax of this configuration file, +# see kconfig-language at https://www.kernel.org/doc/Documentation/kbuild/kconfig-language.txt +# + +config EXAMPLES_TLS_BENCHMARK + bool "TLS benchmark program" + default n + depends on NET_SECURITY_TLS + +if EXAMPLES_TLS_BENCHMARK + +config EXAMPLES_TLS_BENCHMARK_PROGNAME + string "Program name" + default "tls_benchmark" + depends on BUILD_KERNEL + +endif # EXAMPLE_TLS_BENCHMARK + +config USER_ENTRYPOINT + string + default "tls_benchmark_main" if ENTRY_TLS_BENCHMARK diff --git a/apps/examples/tls_benchmark/Kconfig_ENTRY b/apps/examples/tls_benchmark/Kconfig_ENTRY new file mode 100644 index 0000000..ab9edb6 --- /dev/null +++ b/apps/examples/tls_benchmark/Kconfig_ENTRY @@ -0,0 +1,3 @@ +config ENTRY_TLS_BENCHMARK + bool "TLS benchmark program" + depends on EXAMPLES_TLS_BENCHMARK diff --git a/apps/examples/tls_benchmark/Make.defs b/apps/examples/tls_benchmark/Make.defs new file mode 100644 index 0000000..806cc80 --- /dev/null +++ b/apps/examples/tls_benchmark/Make.defs @@ -0,0 +1,22 @@ +########################################################################### +# +# Copyright 2017 Samsung Electronics All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +# either express or implied. See the License for the specific +# language governing permissions and limitations under the License. +# +########################################################################### + +ifeq ($(CONFIG_EXAMPLES_TLS_BENCHMARK),y) +CONFIGURED_APPS += examples/tls_benchmark +endif + diff --git a/apps/examples/tls_benchmark/Makefile b/apps/examples/tls_benchmark/Makefile new file mode 100644 index 0000000..8c28d78 --- /dev/null +++ b/apps/examples/tls_benchmark/Makefile @@ -0,0 +1,155 @@ +########################################################################### +# +# Copyright 2016 Samsung Electronics All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +# either express or implied. See the License for the specific +# language governing permissions and limitations under the License. +# +########################################################################### +############################################################################ +# apps/examples/tls_benchmark/Makefile +# +# Copyright (C) 2011-2014 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name NuttX nor the names of its contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +-include $(TOPDIR)/.config +-include $(TOPDIR)/Make.defs +include $(APPDIR)/Make.defs + +# built-in application info + +APPNAME = tls_benchmark +THREADEXEC = TASH_EXECMD_ASYNC + +ASRCS = +CSRCS = +MAINSRC = tls_benchmark_main.c + +AOBJS = $(ASRCS:.S=$(OBJEXT)) +COBJS = $(CSRCS:.c=$(OBJEXT)) +MAINOBJ = $(MAINSRC:.c=$(OBJEXT)) + +SRCS = $(ASRCS) $(CSRCS) $(MAINSRC) +OBJS = $(AOBJS) $(COBJS) + +ifneq ($(CONFIG_BUILD_KERNEL),y) + OBJS += $(MAINOBJ) +endif + +ifeq ($(CONFIG_WINDOWS_NATIVE),y) + BIN = ..\..\libapps$(LIBEXT) +else +ifeq ($(WINTOOL),y) + BIN = ..\\..\\libapps$(LIBEXT) +else + BIN = ../../libapps$(LIBEXT) +endif +endif + +ifeq ($(WINTOOL),y) + INSTALL_DIR = "${shell cygpath -w $(BIN_DIR)}" +else + INSTALL_DIR = $(BIN_DIR) +endif + +CONFIG_EXAMPLES_TLS_BENCHMARK_PROGNAME ?= tls_benchmark$(EXEEXT) +PROGNAME = $(CONFIG_EXAMPLES_TLS_BENCHMARK_PROGNAME) + +ROOTDEPPATH = --dep-path . + +# Common build + +VPATH = + +all: .built +.PHONY: clean depend distclean + +$(AOBJS): %$(OBJEXT): %.S + $(call ASSEMBLE, $<, $@) + +$(COBJS) $(MAINOBJ): %$(OBJEXT): %.c + $(call COMPILE, $<, $@) + +.built: $(OBJS) + $(call ARCHIVE, $(BIN), $(OBJS)) + @touch .built + +ifeq ($(CONFIG_BUILD_KERNEL),y) +$(BIN_DIR)$(DELIM)$(PROGNAME): $(OBJS) $(MAINOBJ) + @echo "LD: $(PROGNAME)" + $(Q) $(LD) $(LDELFFLAGS) $(LDLIBPATH) -o $(INSTALL_DIR)$(DELIM)$(PROGNAME) $(ARCHCRT0OBJ) $(MAINOBJ) $(LDLIBS) + $(Q) $(NM) -u $(INSTALL_DIR)$(DELIM)$(PROGNAME) + +install: $(BIN_DIR)$(DELIM)$(PROGNAME) + +else +install: + +endif + +ifeq ($(CONFIG_BUILTIN_APPS)$(CONFIG_EXAMPLES_TLS_BENCHMARK),yy) +$(BUILTIN_REGISTRY)$(DELIM)$(APPNAME)_main.bdat: $(DEPCONFIG) Makefile + $(call REGISTER,$(APPNAME),$(APPNAME)_main,$(THREADEXEC)) + +context: $(BUILTIN_REGISTRY)$(DELIM)$(APPNAME)_main.bdat + +else +context: + +endif + +.depend: Makefile $(SRCS) + @$(MKDEP) $(ROOTDEPPATH) "$(CC)" -- $(CFLAGS) -- $(SRCS) >Make.dep + @touch $@ + +depend: .depend + +clean: + $(call DELFILE, .built) + $(call CLEAN) + +distclean: clean + $(call DELFILE, Make.dep) + $(call DELFILE, .depend) + +-include Make.dep +.PHONY: preconfig +preconfig: diff --git a/apps/examples/tls_benchmark/README.txt b/apps/examples/tls_benchmark/README.txt new file mode 100644 index 0000000..5fa26a7 --- /dev/null +++ b/apps/examples/tls_benchmark/README.txt @@ -0,0 +1,11 @@ +examples/tls_benchmark +^^^^^^^^^^^^^^^^^^^^^ + usage: + ex) tls_benchmark + + Configs (see the details on Kconfig): + * CONFIG_EXAMPLES_TLS_BENCHMARK + + Depends on: + * CONFIG_NET_SECURITY_TLS + diff --git a/apps/examples/tls_benchmark/tls_benchmark_main.c b/apps/examples/tls_benchmark/tls_benchmark_main.c new file mode 100644 index 0000000..284a278 --- /dev/null +++ b/apps/examples/tls_benchmark/tls_benchmark_main.c @@ -0,0 +1,872 @@ +/**************************************************************************** + * + * Copyright 2017 Samsung Electronics All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the License. + * + ****************************************************************************/ +/* + * Self-test demonstration program + * + * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ + +#include + +#include +#include +#include + +#include "tls/timing.h" + +#include "tls/md4.h" +#include "tls/md5.h" +#include "tls/ripemd160.h" +#include "tls/sha1.h" +#include "tls/sha256.h" +#include "tls/sha512.h" +#include "tls/arc4.h" +#include "tls/des.h" +#include "tls/aes.h" +#include "tls/blowfish.h" +#include "tls/camellia.h" +#include "tls/gcm.h" +#include "tls/ccm.h" +#include "tls/cmac.h" +#include "tls/havege.h" +#include "tls/ctr_drbg.h" +#include "tls/hmac_drbg.h" +#include "tls/rsa.h" +#include "tls/dhm.h" +#include "tls/ecdsa.h" +#include "tls/ecdh.h" +#include "tls/error.h" + +#define mbedtls_exit exit +#define mbedtls_snprintf snprintf +#define mbedtls_printf printf +#define mbedtls_free free +#define mbedtls_calloc calloc + +/* + * Definition for handling pthread + */ +#define TLS_BENCHMARK_PRIORITY 100 +#define TLS_BENCHMARK_STACK_SIZE 51200 +#define TLS_BENCHMARK_SCHED_POLICY SCHED_RR + +/* + * For heap usage estimates, we need an estimate of the overhead per allocated + * block. ptmalloc2/3 (used in gnu libc for instance) uses 2 size_t per block, + * so use that as our baseline. + */ +#define MEM_BLOCK_OVERHEAD (2 * sizeof(size_t)) + +int sleep_time; + +int mbedtls_sleep(void *args) +{ + sleep(sleep_time); + sleep_time = 0; + return 0; +} + +void count_time(int seconds) +{ + pthread_t tid; + pthread_attr_t attr; + struct sched_param sparam; + + sleep_time = seconds; + + sparam.sched_priority = 100; + if (pthread_attr_setschedparam(&attr, &sparam)) { + return; + } + if (pthread_attr_setschedpolicy(&attr, SCHED_RR)) { + return; + } + if (pthread_attr_setstacksize(&attr, 1024)) { + return; + } + if (pthread_create(&tid, &attr, (pthread_startroutine_t)mbedtls_sleep, NULL)) { + return; + } + if (pthread_detach(tid)) { + return; + } +} + +/* + * Size to use for the alloc buffer if MEMORY_BUFFER_ALLOC_C is defined. + */ +#define HEAP_SIZE (1u << 16) // 64k + +#define BUFSIZE 1024 +#define HEADER_FORMAT " %-24s : " +#define TITLE_LEN 25 + +#define OPTIONS \ + "md4, md5, ripemd160, sha1, sha256, sha512,\n" \ + "arc4, des3, des, camellia, blowfish,\n" \ + "aes_cbc, aes_gcm, aes_ccm, aes_cmac, des3_cmac,\n" \ + "havege, ctr_drbg, hmac_drbg\n" \ + "rsa, dhm, ecdsa, ecdh.\n" + +#if defined(MBEDTLS_ERROR_C) +#define PRINT_ERROR \ + mbedtls_strerror(ret, (char *)tmp, sizeof(tmp)); \ + mbedtls_printf("FAILED: %s\n", tmp); +#else +#define PRINT_ERROR mbedtls_printf("FAILED: -0x%04x\n", -ret); +#endif + +#define TIME_AND_TSC(TITLE, CODE) \ +do { \ + unsigned long ii = 0; \ + \ + mbedtls_printf(HEADER_FORMAT, TITLE); \ + fflush(stdout); \ + \ + count_time(1); \ + for(ii = 1; sleep_time; ii++) \ + { \ + CODE; \ + } \ + mbedtls_printf("%9lu Kb/s\n", ii * BUFSIZE / 1024); \ +} while( 0 ) + +#if defined(MBEDTLS_ERROR_C) +#define PRINT_ERROR \ + mbedtls_strerror(ret, (char *)tmp, sizeof(tmp)); \ + mbedtls_printf("FAILED: %s\n", tmp); +#else +#define PRINT_ERROR mbedtls_printf("FAILED: -0x%04x\n", -ret); +#endif + +#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) && defined(MBEDTLS_MEMORY_DEBUG) + +#define MEMORY_MEASURE_INIT \ + size_t max_used, max_blocks, max_bytes; \ + size_t prv_used, prv_blocks; \ + mbedtls_memory_buffer_alloc_cur_get(&prv_used, &prv_blocks); \ + mbedtls_memory_buffer_alloc_max_reset(); + +#define MEMORY_MEASURE_PRINT(title_len) \ + mbedtls_memory_buffer_alloc_max_get(&max_used, &max_blocks); \ + for(ii = 12 - title_len; ii != 0; ii--) mbedtls_printf(""); \ + max_used -= prv_used; \ + max_blocks -= prv_blocks; \ + max_bytes = max_used + MEM_BLOCK_OVERHEAD * max_blocks; \ + mbedtls_printf("%6u heap bytes", (unsigned) max_bytes); + +#else +#define MEMORY_MEASURE_INIT +#define MEMORY_MEASURE_PRINT(title_len) +#endif + +#define TIME_PUBLIC(TITLE, TYPE, CODE) \ +do { \ + unsigned long ii; \ + int ret; \ + MEMORY_MEASURE_INIT; \ + \ + mbedtls_printf(HEADER_FORMAT, TITLE); \ + fflush(stdout); \ + count_time(3); \ + \ + ret = 0; \ + for(ii = 1; sleep_time && ! ret ; ii++) \ + { \ + CODE; \ + } \ + \ + if(ret != 0) \ + { \ + PRINT_ERROR; \ + } \ + else \ + { \ + mbedtls_printf("%6lu " TYPE "/3s", ii); \ + MEMORY_MEASURE_PRINT(sizeof(TYPE) + 1); \ + mbedtls_printf("\n"); \ + } \ +} while(0) + +struct pthread_arg { + int argc; + char **argv; +}; + +static int myrand(void *rng_state, unsigned char *output, size_t len) +{ + size_t use_len; + int rnd; + + if (rng_state != NULL) { + rng_state = NULL; + } + + while (len > 0) { + use_len = len; + if (use_len > sizeof(int)) { + use_len = sizeof(int); + } + + rnd = rand(); + memcpy(output, &rnd, use_len); + output += use_len; + len -= use_len; + } + + return (0); +} + +/* + * Clear some memory that was used to prepare the context + */ +#if defined(MBEDTLS_ECP_C) +void ecp_clear_precomputed(mbedtls_ecp_group *grp) +{ + if (grp->T != NULL) { + size_t i; + for (i = 0; i < grp->T_size; i++) { + mbedtls_ecp_point_free(&grp->T[i]); + } + mbedtls_free(grp->T); + } + grp->T = NULL; + grp->T_size = 0; +} +#else +#define ecp_clear_precomputed(g) +#endif + +unsigned char buf[BUFSIZE]; + +typedef struct { + char md4, md5, ripemd160, sha1, sha256, sha512, + arc4, des3, des, + aes_cbc, aes_gcm, aes_ccm, aes_cmac, des3_cmac, + camellia, blowfish, + havege, ctr_drbg, hmac_drbg, + rsa, dhm, ecdsa, ecdh; +} todo_list; + +pthread_addr_t tls_benchmark_cb(void *args) +{ + int i; + int argc; + char **argv; + unsigned char tmp[200]; + char title[TITLE_LEN]; + todo_list todo; +#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) + unsigned char alloc_buf[HEAP_SIZE] = { 0 }; +#endif + + argc = ((struct pthread_arg *)args)->argc; + argv = ((struct pthread_arg *)args)->argv; + + if (argc <= 1) { + memset(&todo, 1, sizeof(todo)); + } else { + memset(&todo, 0, sizeof(todo)); + + for (i = 1; i < argc; i++) { + if (strcmp(argv[i], "md4") == 0) { + todo.md4 = 1; + } else if (strcmp(argv[i], "md5") == 0) { + todo.md5 = 1; + } else if (strcmp(argv[i], "ripemd160") == 0) { + todo.ripemd160 = 1; + } else if (strcmp(argv[i], "sha1") == 0) { + todo.sha1 = 1; + } else if (strcmp(argv[i], "sha256") == 0) { + todo.sha256 = 1; + } else if (strcmp(argv[i], "sha512") == 0) { + todo.sha512 = 1; + } else if (strcmp(argv[i], "arc4") == 0) { + todo.arc4 = 1; + } else if (strcmp(argv[i], "des3") == 0) { + todo.des3 = 1; + } else if (strcmp(argv[i], "des") == 0) { + todo.des = 1; + } else if (strcmp(argv[i], "aes_cbc") == 0) { + todo.aes_cbc = 1; + } else if (strcmp(argv[i], "aes_gcm") == 0) { + todo.aes_gcm = 1; + } else if (strcmp(argv[i], "aes_ccm") == 0) { + todo.aes_ccm = 1; + } else if (strcmp(argv[i], "aes_cmac") == 0) { + todo.aes_cmac = 1; + } else if (strcmp(argv[i], "des3_cmac") == 0) { + todo.des3_cmac = 1; + } else if (strcmp(argv[i], "camellia") == 0) { + todo.camellia = 1; + } else if (strcmp(argv[i], "blowfish") == 0) { + todo.blowfish = 1; + } else if (strcmp(argv[i], "havege") == 0) { + todo.havege = 1; + } else if (strcmp(argv[i], "ctr_drbg") == 0) { + todo.ctr_drbg = 1; + } else if (strcmp(argv[i], "hmac_drbg") == 0) { + todo.hmac_drbg = 1; + } else if (strcmp(argv[i], "rsa") == 0) { + todo.rsa = 1; + } else if (strcmp(argv[i], "dhm") == 0) { + todo.dhm = 1; + } else if (strcmp(argv[i], "ecdsa") == 0) { + todo.ecdsa = 1; + } else if (strcmp(argv[i], "ecdh") == 0) { + todo.ecdh = 1; + } else { + mbedtls_printf("Unrecognized option: %s\n", argv[i]); + mbedtls_printf("Available options: " OPTIONS); + } + } + } + + mbedtls_printf("\n"); + +#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) + mbedtls_memory_buffer_alloc_init(alloc_buf, sizeof(alloc_buf)); +#endif + memset(buf, 0xAA, sizeof(buf)); + memset(tmp, 0xBB, sizeof(tmp)); + +#if defined(MBEDTLS_MD4_C) + if (todo.md4) { + TIME_AND_TSC("MD4", mbedtls_md4(buf, BUFSIZE, tmp)); + } +#endif + +#if defined(MBEDTLS_MD5_C) + if (todo.md5) { + TIME_AND_TSC("MD5", mbedtls_md5(buf, BUFSIZE, tmp)); + } +#endif + +#if defined(MBEDTLS_RIPEMD160_C) + if (todo.ripemd160) { + TIME_AND_TSC("RIPEMD160", mbedtls_ripemd160(buf, BUFSIZE, tmp)); + } +#endif + +#if defined(MBEDTLS_SHA1_C) + if (todo.sha1) { + TIME_AND_TSC("SHA-1", mbedtls_sha1(buf, BUFSIZE, tmp)); + } +#endif + +#if defined(MBEDTLS_SHA256_C) + if (todo.sha256) { + TIME_AND_TSC("SHA-256", mbedtls_sha256(buf, BUFSIZE, tmp, 0)); + } +#endif + +#if defined(MBEDTLS_SHA512_C) + if (todo.sha512) { + TIME_AND_TSC("SHA-512", mbedtls_sha512(buf, BUFSIZE, tmp, 0)); + } +#endif + +#if defined(MBEDTLS_ARC4_C) + if (todo.arc4) { + mbedtls_arc4_context arc4; + mbedtls_arc4_init(&arc4); + mbedtls_arc4_setup(&arc4, tmp, 32); + TIME_AND_TSC("ARC4", mbedtls_arc4_crypt(&arc4, BUFSIZE, buf, buf)); + mbedtls_arc4_free(&arc4); + } +#endif + +#if defined(MBEDTLS_DES_C) +#if defined(MBEDTLS_CIPHER_MODE_CBC) + if (todo.des3) { + mbedtls_des3_context des3; + mbedtls_des3_init(&des3); + mbedtls_des3_set3key_enc(&des3, tmp); + TIME_AND_TSC("3DES", + mbedtls_des3_crypt_cbc(&des3, MBEDTLS_DES_ENCRYPT, BUFSIZE, tmp, buf, buf)); + mbedtls_des3_free(&des3); + } + + if (todo.des) { + mbedtls_des_context des; + mbedtls_des_init(&des); + mbedtls_des_setkey_enc(&des, tmp); + TIME_AND_TSC("DES", + mbedtls_des_crypt_cbc(&des, MBEDTLS_DES_ENCRYPT, BUFSIZE, tmp, buf, buf)); + mbedtls_des_free(&des); + } + +#endif /* MBEDTLS_CIPHER_MODE_CBC */ +#if defined(MBEDTLS_CMAC_C) + if (todo.des3_cmac) { + unsigned char output[8]; + const mbedtls_cipher_info_t *cipher_info; + + memset(buf, 0, sizeof(buf)); + memset(tmp, 0, sizeof(tmp)); + + cipher_info = mbedtls_cipher_info_from_type(MBEDTLS_CIPHER_DES_EDE3_ECB); + + TIME_AND_TSC("3DES-CMAC", + mbedtls_cipher_cmac(cipher_info, tmp, 192, buf, + BUFSIZE, output)); + } +#endif /* MBEDTLS_CMAC_C */ +#endif /* MBEDTLS_DES_C */ + +#if defined(MBEDTLS_AES_C) +#if defined(MBEDTLS_CIPHER_MODE_CBC) + if (todo.aes_cbc) { + int keysize; + mbedtls_aes_context aes; + mbedtls_aes_init(&aes); + for (keysize = 128; keysize <= 256; keysize += 64) { + mbedtls_snprintf(title, sizeof(title), "AES-CBC-%d", keysize); + + memset(buf, 0, sizeof(buf)); + memset(tmp, 0, sizeof(tmp)); + mbedtls_aes_setkey_enc(&aes, tmp, keysize); + + TIME_AND_TSC(title, + mbedtls_aes_crypt_cbc(&aes, MBEDTLS_AES_ENCRYPT, BUFSIZE, tmp, buf, buf)); + } + mbedtls_aes_free(&aes); + } +#endif +#if defined(MBEDTLS_GCM_C) + if (todo.aes_gcm) { + int keysize; + mbedtls_gcm_context gcm; + + mbedtls_gcm_init(&gcm); + for (keysize = 128; keysize <= 256; keysize += 64) { + mbedtls_snprintf(title, sizeof(title), "AES-GCM-%d", keysize); + + memset(buf, 0, sizeof(buf)); + memset(tmp, 0, sizeof(tmp)); + mbedtls_gcm_setkey(&gcm, MBEDTLS_CIPHER_ID_AES, tmp, keysize); + + TIME_AND_TSC(title, + mbedtls_gcm_crypt_and_tag(&gcm, MBEDTLS_GCM_ENCRYPT, BUFSIZE, tmp, + 12, NULL, 0, buf, buf, 16, tmp)); + + mbedtls_gcm_free(&gcm); + } + } +#endif +#if defined(MBEDTLS_CCM_C) + if (todo.aes_ccm) { + int keysize; + mbedtls_ccm_context ccm; + + mbedtls_ccm_init(&ccm); + for (keysize = 128; keysize <= 256; keysize += 64) { + mbedtls_snprintf(title, sizeof(title), "AES-CCM-%d", keysize); + + memset(buf, 0, sizeof(buf)); + memset(tmp, 0, sizeof(tmp)); + mbedtls_ccm_setkey(&ccm, MBEDTLS_CIPHER_ID_AES, tmp, keysize); + + TIME_AND_TSC(title, + mbedtls_ccm_encrypt_and_tag(&ccm, BUFSIZE, tmp, + 12, NULL, 0, buf, buf, tmp, 16)); + + mbedtls_ccm_free(&ccm); + } + } +#endif +#if defined(MBEDTLS_CMAC_C) + if (todo.aes_cmac) { + unsigned char output[16]; + const mbedtls_cipher_info_t *cipher_info; + mbedtls_cipher_type_t cipher_type; + int keysize; + + for (keysize = 128, cipher_type = MBEDTLS_CIPHER_AES_128_ECB; + keysize <= 256; + keysize += 64, cipher_type++) { + mbedtls_snprintf(title, sizeof(title), "AES-CMAC-%d", keysize); + + memset(buf, 0, sizeof(buf)); + memset(tmp, 0, sizeof(tmp)); + + cipher_info = mbedtls_cipher_info_from_type(cipher_type); + + TIME_AND_TSC(title, + mbedtls_cipher_cmac(cipher_info, tmp, keysize, + buf, BUFSIZE, output)); + } + + memset(buf, 0, sizeof(buf)); + memset(tmp, 0, sizeof(tmp)); + TIME_AND_TSC("AES-CMAC-PRF-128", + mbedtls_aes_cmac_prf_128(tmp, 16, buf, BUFSIZE, + output)); + } +#endif /* MBEDTLS_CMAC_C */ +#endif /* MBEDTLS_AES_C */ + +#if defined(MBEDTLS_CAMELLIA_C) && defined(MBEDTLS_CIPHER_MODE_CBC) + if (todo.camellia) { + int keysize; + mbedtls_camellia_context camellia; + mbedtls_camellia_init(&camellia); + for (keysize = 128; keysize <= 256; keysize += 64) { + mbedtls_snprintf(title, sizeof(title), "CAMELLIA-CBC-%d", keysize); + + memset(buf, 0, sizeof(buf)); + memset(tmp, 0, sizeof(tmp)); + mbedtls_camellia_setkey_enc(&camellia, tmp, keysize); + + TIME_AND_TSC(title, + mbedtls_camellia_crypt_cbc(&camellia, MBEDTLS_CAMELLIA_ENCRYPT, + BUFSIZE, tmp, buf, buf)); + } + mbedtls_camellia_free(&camellia); + } +#endif + +#if defined(MBEDTLS_BLOWFISH_C) && defined(MBEDTLS_CIPHER_MODE_CBC) + if (todo.blowfish) { + int keysize; + mbedtls_blowfish_context blowfish; + mbedtls_blowfish_init(&blowfish); + + for (keysize = 128; keysize <= 256; keysize += 64) { + mbedtls_snprintf(title, sizeof(title), "BLOWFISH-CBC-%d", keysize); + + memset(buf, 0, sizeof(buf)); + memset(tmp, 0, sizeof(tmp)); + mbedtls_blowfish_setkey(&blowfish, tmp, keysize); + + TIME_AND_TSC(title, + mbedtls_blowfish_crypt_cbc(&blowfish, MBEDTLS_BLOWFISH_ENCRYPT, BUFSIZE, + tmp, buf, buf)); + } + + mbedtls_blowfish_free(&blowfish); + } +#endif + +#if defined(MBEDTLS_HAVEGE_C) + if (todo.havege) { + mbedtls_havege_state hs; + mbedtls_havege_init(&hs); + TIME_AND_TSC("HAVEGE", mbedtls_havege_random(&hs, buf, BUFSIZE)); + mbedtls_havege_free(&hs); + } +#endif + +#if defined(MBEDTLS_CTR_DRBG_C) + if (todo.ctr_drbg) { + mbedtls_ctr_drbg_context ctr_drbg; + + mbedtls_ctr_drbg_init(&ctr_drbg); + + if (mbedtls_ctr_drbg_seed(&ctr_drbg, myrand, NULL, NULL, 0) != 0) { + mbedtls_exit(1); + } + TIME_AND_TSC("CTR_DRBG (NOPR)", + if (mbedtls_ctr_drbg_random(&ctr_drbg, buf, BUFSIZE) != 0) + mbedtls_exit(1)); + + if (mbedtls_ctr_drbg_seed(&ctr_drbg, myrand, NULL, NULL, 0) != 0) { + mbedtls_exit(1); + } + mbedtls_ctr_drbg_set_prediction_resistance(&ctr_drbg, MBEDTLS_CTR_DRBG_PR_ON); + TIME_AND_TSC("CTR_DRBG (PR)", + if (mbedtls_ctr_drbg_random(&ctr_drbg, buf, BUFSIZE) != 0) + mbedtls_exit(1)); + mbedtls_ctr_drbg_free(&ctr_drbg); + } +#endif + +#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_GENPRIME) + if (todo.rsa) { + int keysize; + mbedtls_rsa_context rsa; + for (keysize = 2048; keysize <= 4096; keysize *= 2) { + mbedtls_snprintf(title, sizeof(title), "RSA-%d", keysize); + + mbedtls_rsa_init(&rsa, MBEDTLS_RSA_PKCS_V15, 0); + mbedtls_rsa_gen_key(&rsa, myrand, NULL, keysize, 65537); + + TIME_PUBLIC(title, " public", + buf[0] = 0; + ret = mbedtls_rsa_public(&rsa, buf, buf)); + + TIME_PUBLIC(title, "private", + buf[0] = 0; + ret = mbedtls_rsa_private(&rsa, myrand, NULL, buf, buf)); + + mbedtls_rsa_free(&rsa); + } + } +#endif + +#if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_BIGNUM_C) + if (todo.dhm) { + int dhm_sizes[] = { 2048 }; + const char *dhm_P[] = { + MBEDTLS_DHM_RFC3526_MODP_2048_P, + }; + const char *dhm_G[] = { + MBEDTLS_DHM_RFC3526_MODP_2048_G, + }; + + mbedtls_dhm_context dhm; + size_t olen; + for (i = 0; (size_t) i < sizeof(dhm_sizes) / sizeof(dhm_sizes[0]); i++) { + mbedtls_dhm_init(&dhm); + + if (mbedtls_mpi_read_string(&dhm.P, 16, dhm_P[i]) != 0 || + mbedtls_mpi_read_string(&dhm.G, 16, dhm_G[i]) != 0) { + mbedtls_exit(1); + } + + dhm.len = mbedtls_mpi_size(&dhm.P); + mbedtls_dhm_make_public(&dhm, (int) dhm.len, buf, dhm.len, myrand, NULL); + if (mbedtls_mpi_copy(&dhm.GY, &dhm.GX) != 0) { + mbedtls_exit(1); + } + + mbedtls_snprintf(title, sizeof(title), "DHE-%d", dhm_sizes[i]); + TIME_PUBLIC(title, "handshake", + ret |= mbedtls_dhm_make_public(&dhm, (int) dhm.len, buf, dhm.len, + myrand, NULL); + ret |= mbedtls_dhm_calc_secret(&dhm, buf, sizeof(buf), &olen, myrand, NULL)); + + mbedtls_snprintf(title, sizeof(title), "DH-%d", dhm_sizes[i]); + TIME_PUBLIC(title, "handshake", + ret |= mbedtls_dhm_calc_secret(&dhm, buf, sizeof(buf), &olen, myrand, NULL)); + + mbedtls_dhm_free(&dhm); + } + } +#endif + +#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_SHA256_C) + if (todo.ecdsa) { + mbedtls_ecdsa_context ecdsa; + const mbedtls_ecp_curve_info *curve_info; + size_t sig_len; + + memset(buf, 0x2A, sizeof(buf)); + + for (curve_info = mbedtls_ecp_curve_list(); + curve_info->grp_id != MBEDTLS_ECP_DP_NONE; + curve_info++) { + mbedtls_ecdsa_init(&ecdsa); + + if (mbedtls_ecdsa_genkey(&ecdsa, curve_info->grp_id, myrand, NULL) != 0) { + mbedtls_exit(1); + } + ecp_clear_precomputed(&ecdsa.grp); + + mbedtls_snprintf(title, sizeof(title), "ECDSA-%s", + curve_info->name); + TIME_PUBLIC(title, "sign", + ret = mbedtls_ecdsa_write_signature(&ecdsa, MBEDTLS_MD_SHA256, buf, curve_info->bit_size, + tmp, &sig_len, myrand, NULL)); + + mbedtls_ecdsa_free(&ecdsa); + } + + for (curve_info = mbedtls_ecp_curve_list(); + curve_info->grp_id != MBEDTLS_ECP_DP_NONE; + curve_info++) { + mbedtls_ecdsa_init(&ecdsa); + + if (mbedtls_ecdsa_genkey(&ecdsa, curve_info->grp_id, myrand, NULL) != 0 || + mbedtls_ecdsa_write_signature(&ecdsa, MBEDTLS_MD_SHA256, buf, curve_info->bit_size, + tmp, &sig_len, myrand, NULL) != 0) { + mbedtls_exit(1); + } + ecp_clear_precomputed(&ecdsa.grp); + + mbedtls_snprintf(title, sizeof(title), "ECDSA-%s", + curve_info->name); + TIME_PUBLIC(title, "verify", + ret = mbedtls_ecdsa_read_signature(&ecdsa, buf, curve_info->bit_size, + tmp, sig_len)); + + mbedtls_ecdsa_free(&ecdsa); + } + } +#endif + +#if defined(MBEDTLS_ECDH_C) + if (todo.ecdh) { + mbedtls_ecdh_context ecdh; +#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) + mbedtls_mpi z; +#endif + const mbedtls_ecp_curve_info *curve_info; + size_t olen; + + for (curve_info = mbedtls_ecp_curve_list(); + curve_info->grp_id != MBEDTLS_ECP_DP_NONE; + curve_info++) { + mbedtls_ecdh_init(&ecdh); + + if (mbedtls_ecp_group_load(&ecdh.grp, curve_info->grp_id) != 0 || + mbedtls_ecdh_make_public(&ecdh, &olen, buf, sizeof(buf), + myrand, NULL) != 0 || + mbedtls_ecp_copy(&ecdh.Qp, &ecdh.Q) != 0) { + mbedtls_exit(1); + } + ecp_clear_precomputed(&ecdh.grp); + + mbedtls_snprintf(title, sizeof(title), "ECDHE-%s", + curve_info->name); + TIME_PUBLIC(title, "handshake", + ret |= mbedtls_ecdh_make_public(&ecdh, &olen, buf, sizeof(buf), + myrand, NULL); + ret |= mbedtls_ecdh_calc_secret(&ecdh, &olen, buf, sizeof(buf), + myrand, NULL)); + mbedtls_ecdh_free(&ecdh); + } + + /* Curve25519 needs to be handled separately */ +#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) + mbedtls_ecdh_init(&ecdh); + mbedtls_mpi_init(&z); + + if (mbedtls_ecp_group_load(&ecdh.grp, MBEDTLS_ECP_DP_CURVE25519) != 0 || + mbedtls_ecdh_gen_public(&ecdh.grp, &ecdh.d, &ecdh.Qp, myrand, NULL) != 0) { + mbedtls_exit(1); + } + + TIME_PUBLIC("ECDHE-Curve25519", "handshake", + ret |= mbedtls_ecdh_gen_public(&ecdh.grp, &ecdh.d, &ecdh.Q, + myrand, NULL); + ret |= mbedtls_ecdh_compute_shared(&ecdh.grp, &z, &ecdh.Qp, &ecdh.d, + myrand, NULL)); + + mbedtls_ecdh_free(&ecdh); + mbedtls_mpi_free(&z); +#endif + + for (curve_info = mbedtls_ecp_curve_list(); + curve_info->grp_id != MBEDTLS_ECP_DP_NONE; + curve_info++) { + mbedtls_ecdh_init(&ecdh); + + if (mbedtls_ecp_group_load(&ecdh.grp, curve_info->grp_id) != 0 || + mbedtls_ecdh_make_public(&ecdh, &olen, buf, sizeof(buf), + myrand, NULL) != 0 || + mbedtls_ecp_copy(&ecdh.Qp, &ecdh.Q) != 0 || + mbedtls_ecdh_make_public(&ecdh, &olen, buf, sizeof(buf), + myrand, NULL) != 0) { + mbedtls_exit(1); + } + ecp_clear_precomputed(&ecdh.grp); + + mbedtls_snprintf(title, sizeof(title), "ECDH-%s", + curve_info->name); + TIME_PUBLIC(title, "handshake", + ret |= mbedtls_ecdh_calc_secret(&ecdh, &olen, buf, sizeof(buf), + myrand, NULL)); + mbedtls_ecdh_free(&ecdh); + } + + /* Curve25519 needs to be handled separately */ +#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) + mbedtls_ecdh_init(&ecdh); + mbedtls_mpi_init(&z); + + if (mbedtls_ecp_group_load(&ecdh.grp, MBEDTLS_ECP_DP_CURVE25519) != 0 || + mbedtls_ecdh_gen_public(&ecdh.grp, &ecdh.d, &ecdh.Qp, + myrand, NULL) != 0 || + mbedtls_ecdh_gen_public(&ecdh.grp, &ecdh.d, &ecdh.Q, myrand, NULL) != 0) { + mbedtls_exit(1); + } + + TIME_PUBLIC("ECDH-Curve25519", "handshake", + ret |= mbedtls_ecdh_compute_shared(&ecdh.grp, &z, &ecdh.Qp, &ecdh.d, + myrand, NULL)); + + mbedtls_ecdh_free(&ecdh); + mbedtls_mpi_free(&z); +#endif + } +#endif + + mbedtls_printf("Benchmark test finished \n"); + mbedtls_printf("\n"); + +#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) + mbedtls_memory_buffer_alloc_free(); +#endif + + return NULL; +} + +int tls_benchmark_main(int argc, char **argv) +{ + pthread_t tid; + pthread_attr_t attr; + struct sched_param sparam; + int r; + + /* Initialize the attribute variable */ + if ((r = pthread_attr_init(&attr)) != 0) { + printf("%s: pthread_attr_init failed, status=%d\n", __func__, r); + } + + /* 1. set a priority */ + sparam.sched_priority = TLS_BENCHMARK_PRIORITY; + if ((r = pthread_attr_setschedparam(&attr, &sparam)) != 0) { + printf("%s: pthread_attr_setschedparam failed, status=%d\n", __func__, r); + } + + if ((r = pthread_attr_setschedpolicy(&attr, TLS_BENCHMARK_SCHED_POLICY)) != 0) { + printf("%s: pthread_attr_setschedpolicy failed, status=%d\n", __func__, r); + } + + /* 2. set a stacksize */ + if ((r = pthread_attr_setstacksize(&attr, TLS_BENCHMARK_STACK_SIZE)) != 0) { + printf("%s: pthread_attr_setstacksize failed, status=%d\n", __func__, r); + } + + /* 3. create pthread with entry function */ + if ((r = pthread_create(&tid, &attr, tls_benchmark_cb, (void *)0)) != 0) { + printf("%s: pthread_create failed, status=%d\n", __func__, r); + } + + /* Wait for the threads to stop */ + pthread_join(tid, NULL); + + return 0; +} +