From 6aa02da99fb078a30d05a31c5901b54d29613e86 Mon Sep 17 00:00:00 2001 From: Zexi Yu Date: Thu, 22 Feb 2024 11:23:50 +0800 Subject: [PATCH] xtest: add SM4 perf test Add perf test for SM4 algorithm Signed-off-by: Zexi Yu --- Android.mk | 2 +- host/xtest/CMakeLists.txt | 2 +- host/xtest/Makefile | 2 +- host/xtest/{aes_perf.c => symm_cipher_perf.c} | 115 +++++++++++++++--- ta/crypto_perf/include/ta_crypto_perf.h | 17 +++ ta/crypto_perf/ta_crypto_perf.c | 23 +++- 6 files changed, 138 insertions(+), 23 deletions(-) rename host/xtest/{aes_perf.c => symm_cipher_perf.c} (88%) diff --git a/Android.mk b/Android.mk index 6c3b9475f..7f2c6e126 100644 --- a/Android.mk +++ b/Android.mk @@ -42,7 +42,7 @@ srcs += adbg/src/adbg_case.c \ adbg/src/adbg_log.c \ adbg/src/adbg_run.c \ adbg/src/security_utils_hex.c \ - aes_perf.c \ + symm_cipher_perf.c \ asym_perf.c \ benchmark_1000.c \ benchmark_2000.c \ diff --git a/host/xtest/CMakeLists.txt b/host/xtest/CMakeLists.txt index df6484af0..ea435639d 100644 --- a/host/xtest/CMakeLists.txt +++ b/host/xtest/CMakeLists.txt @@ -45,7 +45,7 @@ set (SRC adbg/src/adbg_log.c adbg/src/adbg_run.c adbg/src/security_utils_hex.c - aes_perf.c + symm_cipher_perf.c asym_perf.c benchmark_1000.c benchmark_2000.c diff --git a/host/xtest/Makefile b/host/xtest/Makefile index 477ec06c0..af5252058 100644 --- a/host/xtest/Makefile +++ b/host/xtest/Makefile @@ -57,7 +57,7 @@ srcs += adbg/src/adbg_case.c \ adbg/src/adbg_log.c \ adbg/src/adbg_run.c \ adbg/src/security_utils_hex.c \ - aes_perf.c \ + symm_cipher_perf.c \ asym_perf.c \ benchmark_1000.c \ benchmark_2000.c \ diff --git a/host/xtest/aes_perf.c b/host/xtest/symm_cipher_perf.c similarity index 88% rename from host/xtest/aes_perf.c rename to host/xtest/symm_cipher_perf.c index c2f381ed2..6a620c9ab 100644 --- a/host/xtest/aes_perf.c +++ b/host/xtest/symm_cipher_perf.c @@ -162,16 +162,39 @@ static double stddev(struct statistics *s) return sqrt(s->M2/s->n); } -static const char *mode_str(uint32_t mode) +static const char *cipher_str(uint32_t algo) { - switch (mode) { + switch (algo) { case TA_AES_ECB: + case TA_AES_CBC: + case TA_AES_CTR: + case TA_AES_XTS: + case TA_AES_GCM: + return "AES"; + case TA_SM4_ECB: + case TA_SM4_CBC: + case TA_SM4_CTR: + case TA_SM4_XTS: + return "SM4"; + default: + return "???"; + } +} + +static const char *mode_str(uint32_t algo) +{ + switch (algo) { + case TA_AES_ECB: + case TA_SM4_ECB: return "ECB"; case TA_AES_CBC: + case TA_SM4_CBC: return "CBC"; case TA_AES_CTR: + case TA_SM4_CTR: return "CTR"; case TA_AES_XTS: + case TA_SM4_XTS: return "XTS"; case TA_AES_GCM: return "GCM"; @@ -183,19 +206,19 @@ static const char *mode_str(uint32_t mode) #define _TO_STR(x) #x #define TO_STR(x) _TO_STR(x) -static void usage(const char *applet_optname, int keysize, int mode, +static void usage(const char *applet_optname, int keysize, int algo, size_t size, size_t unit, int warmup, unsigned int l, unsigned int n) { fprintf(stderr, "Usage: %s %s [-h]\n", xtest_progname, applet_optname); fprintf(stderr, "Usage: %s %s [-d] [-i] [-k SIZE]", xtest_progname, applet_optname); - fprintf(stderr, " [-l LOOP] [-m MODE] [-n LOOP] [-r|--no-inited] [-s SIZE]"); + fprintf(stderr, " [-l LOOP] [-c CIPHER] [-m MODE] [-n LOOP] [-r|--no-inited] [-s SIZE]"); fprintf(stderr, " [-v [-v]] [-w SEC]"); #ifdef CFG_SECURE_DATA_PATH fprintf(stderr, " [--sdp [-Id|-Ir|-IR] [-Od|-Or|-OR]]"); #endif fprintf(stderr, "\n"); - fprintf(stderr, "AES performance testing tool for OP-TEE\n"); + fprintf(stderr, "AES/SM4 performance testing tool for OP-TEE\n"); fprintf(stderr, "\n"); fprintf(stderr, "Options:\n"); fprintf(stderr, " -d Test AES decryption instead of encryption\n"); @@ -203,7 +226,8 @@ static void usage(const char *applet_optname, int keysize, int mode, fprintf(stderr, " -i|--in-place Use same buffer for input and output (decrypt in place)\n"); fprintf(stderr, " -k SIZE Key size in bits: 128, 192 or 256 [%u]\n", keysize); fprintf(stderr, " -l LOOP Inner loop iterations [%u]\n", l); - fprintf(stderr, " -m MODE AES mode: ECB, CBC, CTR, XTS, GCM [%s]\n", mode_str(mode)); + fprintf(stderr, " -c CIPHER cipher: AES, SM4 [%s]\n", cipher_str(algo)); + fprintf(stderr, " -m MODE mode: ECB, CBC, CTR, XTS, GCM [%s]\n", mode_str(algo)); fprintf(stderr, " -n LOOP Outer test loop iterations [%u]\n", n); fprintf(stderr, " --not-inited Do not initialize input buffer content.\n"); fprintf(stderr, " -r|--random Get input data from /dev/urandom (default: all zeros)\n"); @@ -349,7 +373,7 @@ static uint64_t timespec_diff_ns(struct timespec *start, struct timespec *end) return timespec_to_ns(end) - timespec_to_ns(start); } -static void prepare_key(int decrypt, int keysize, int mode) +static void prepare_key(int decrypt, int keysize, int algo) { TEEC_Result res = TEEC_ERROR_GENERIC; uint32_t ret_origin = 0; @@ -360,7 +384,7 @@ static void prepare_key(int decrypt, int keysize, int mode) TEEC_NONE, TEEC_NONE); op.params[0].value.a = decrypt; op.params[0].value.b = keysize; - op.params[1].value.a = mode; + op.params[1].value.a = algo; res = TEEC_InvokeCommand(&sess, cmd, &op, &ret_origin); check_res(res, "TEEC_InvokeCommand", &ret_origin); @@ -423,7 +447,7 @@ static void run_feed_input(void *in, size_t size, int random) } -void aes_perf_run_test(int mode, int keysize, int decrypt, size_t size, size_t unit, +void aes_perf_run_test(int algo, int keysize, int decrypt, size_t size, size_t unit, unsigned int n, unsigned int l, int input_data_init, int in_place, int warmup, int verbosity) { @@ -456,7 +480,7 @@ void aes_perf_run_test(int mode, int keysize, int decrypt, size_t size, size_t u vverbose("output test buffer: %s\n", buf_type_str(output_buffer)); open_ta(); - prepare_key(decrypt, keysize, mode); + prepare_key(decrypt, keysize, algo); alloc_buffers(size, in_place, verbosity); if (input_data_init == CRYPTO_USE_ZEROS) @@ -474,7 +498,7 @@ void aes_perf_run_test(int mode, int keysize, int decrypt, size_t size, size_t u op.params[2].value.b = unit; verbose("Starting test: %s, %scrypt, keysize=%u bits, size=%zu bytes, ", - mode_str(mode), (decrypt ? "de" : "en"), keysize, size); + mode_str(algo), (decrypt ? "de" : "en"), keysize, size); verbose("random=%s, ", yesno(input_data_init == CRYPTO_USE_RANDOM)); verbose("in place=%s, ", yesno(in_place)); verbose("inner loops=%u, loops=%u, warm-up=%u s, ", l, n, warmup); @@ -539,7 +563,42 @@ void aes_perf_run_test(int mode, int keysize, int decrypt, size_t size, size_t u } \ } while (0); -#define USAGE() usage(argv[0], keysize, mode, size, unit, warmup, l, n) +#define USAGE() usage(argv[0], keysize, algo, size, unit, warmup, l, n) + +int get_symm_algo(int cipher, int mode) +{ + if (cipher == AES) { + switch (mode) { + case ECB: + return TA_AES_ECB; + case CBC: + return TA_AES_CBC; + case CTR: + return TA_AES_CTR; + case XTS: + return TA_AES_XTS; + case GCM: + return TA_AES_GCM; + default: + return -1; + } + } else if (cipher == SM4) { + switch (mode) { + case ECB: + return TA_SM4_ECB; + case CBC: + return TA_SM4_CBC; + case CTR: + return TA_SM4_CTR; + case XTS: + return TA_SM4_XTS; + default: + return -1; + } + } else { + return -1; + } +} int aes_perf_runner_cmd_parser(int argc, char *argv[]) { @@ -554,7 +613,9 @@ int aes_perf_runner_cmd_parser(int argc, char *argv[]) int verbosity = CRYPTO_DEF_VERBOSITY; /* Verbosity (-v) */ int decrypt = 0; /* Encrypt by default, -d to decrypt */ int keysize = AES_128; /* AES key size (-k) */ - int mode = TA_AES_ECB; /* AES mode (-m) */ + int cipher = AES; + int mode = ECB; + int algo = TA_AES_ECB; /* AES algo */ /* Get input data from /dev/urandom (-r) */ int input_data_init = CRYPTO_USE_ZEROS; /* Use same buffer for in and out (-i) */ @@ -587,18 +648,30 @@ int aes_perf_runner_cmd_parser(int argc, char *argv[]) } else if (!strcmp(argv[i], "-l")) { NEXT_ARG(i); l = atoi(argv[i]); + } else if (!strcmp(argv[i], "-c")) { + NEXT_ARG(i); + if (!strcasecmp(argv[i], "SM4")) + cipher = SM4; + else if (!strcasecmp(argv[i], "AES")) + cipher = AES; + else { + fprintf(stderr, "%s %s, invalid cipher\n", + xtest_progname, argv[0]); + USAGE(); + return 1; + } } else if (!strcmp(argv[i], "-m")) { NEXT_ARG(i); if (!strcasecmp(argv[i], "ECB")) - mode = TA_AES_ECB; + mode = ECB; else if (!strcasecmp(argv[i], "CBC")) - mode = TA_AES_CBC; + algo = CBC; else if (!strcasecmp(argv[i], "CTR")) - mode = TA_AES_CTR; + algo = CTR; else if (!strcasecmp(argv[i], "XTS")) - mode = TA_AES_XTS; + algo = XTS; else if (!strcasecmp(argv[i], "GCM")) - mode = TA_AES_GCM; + algo = GCM; else { fprintf(stderr, "%s %s, invalid mode\n", xtest_progname, argv[0]); @@ -662,6 +735,10 @@ int aes_perf_runner_cmd_parser(int argc, char *argv[]) } } + algo = get_symm_algo(cipher, mode); + if (algo == -1) + return 1; + if (size & (16 - 1)) { fprintf(stderr, "invalid buffer size argument, must be a multiple of 16\n\n"); USAGE(); @@ -669,7 +746,7 @@ int aes_perf_runner_cmd_parser(int argc, char *argv[]) } - aes_perf_run_test(mode, keysize, decrypt, size, unit, n, l, + aes_perf_run_test(algo, keysize, decrypt, size, unit, n, l, input_data_init, in_place, warmup, verbosity); return 0; diff --git a/ta/crypto_perf/include/ta_crypto_perf.h b/ta/crypto_perf/include/ta_crypto_perf.h index 1d5acc85d..4d0b6c0d4 100644 --- a/ta/crypto_perf/include/ta_crypto_perf.h +++ b/ta/crypto_perf/include/ta_crypto_perf.h @@ -36,6 +36,10 @@ #define TA_AES_CTR 2 #define TA_AES_XTS 3 #define TA_AES_GCM 4 +#define TA_SM4_ECB 5 +#define TA_SM4_CBC 6 +#define TA_SM4_CTR 7 +#define TA_SM4_XTS 8 /* * AES key sizes @@ -91,6 +95,19 @@ #define DH_MAX_SIZE 4096 #define DH_G_SIZE 1 +enum symm_cipher { + AES = 0, + SM4 = 1, +}; + +enum symm_mode { + ECB = 0, + CBC = 1, + CTR = 2, + XTS = 3, + GCM = 4, +}; + enum asym_algorithm { ALGO_DH = 1, ALGO_RSA = 2, diff --git a/ta/crypto_perf/ta_crypto_perf.c b/ta/crypto_perf/ta_crypto_perf.c index af616d301..df52d02c4 100644 --- a/ta/crypto_perf/ta_crypto_perf.c +++ b/ta/crypto_perf/ta_crypto_perf.c @@ -236,6 +236,27 @@ TEE_Result cmd_cipher_prepare_key(uint32_t param_types, TEE_Param params[4]) objectType = TEE_TYPE_AES; use_iv = 1; break; + case TA_SM4_ECB: + algo = TEE_ALG_SM4_ECB_NOPAD; + objectType = TEE_TYPE_SM4; + use_iv = 0; + break; + case TA_SM4_CBC: + algo = TEE_ALG_SM4_CBC_NOPAD; + objectType = TEE_TYPE_SM4; + use_iv = 1; + break; + case TA_SM4_CTR: + algo = TEE_ALG_SM4_CTR; + objectType = TEE_TYPE_SM4; + use_iv = 1; + break; + case TA_SM4_XTS: + algo = TEE_ALG_SM4_XTS; + objectType = TEE_TYPE_SM4; + use_iv = 1; + op_keysize *= 2; + break; default: return TEE_ERROR_BAD_PARAMETERS; } @@ -255,7 +276,7 @@ TEE_Result cmd_cipher_prepare_key(uint32_t param_types, TEE_Param params[4]) res = TEE_PopulateTransientObject(hkey, &attr, 1); CHECK(res, "TEE_PopulateTransientObject", return res;); - if (algo == TEE_ALG_AES_XTS) { + if (algo == TEE_ALG_AES_XTS || algo == TEE_ALG_SM4_XTS) { res = TEE_AllocateTransientObject(objectType, keysize, &hkey2); CHECK(res, "TEE_AllocateTransientObject", return res;);