diff --git a/.github/workflows/freebsd.yml b/.github/workflows/freebsd.yml index aa106f344bf5fdd96c97c5a53ead76706e229cd9..ffd85b80d14711f4f44a98a493f1313fbc3b3020 100644 --- a/.github/workflows/freebsd.yml +++ b/.github/workflows/freebsd.yml @@ -6,6 +6,9 @@ on: pull_request: branches: [ main ] +permissions: + contents: read + jobs: # Build shared library with GMake (Clang) release-gmake-clang-shared: @@ -13,12 +16,12 @@ jobs: steps: - name: Checkout repo - uses: actions/checkout@v3 + uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0 with: repository: 'intel/intel-ipsec-mb' - name: Build - uses: vmactions/freebsd-vm@v1 + uses: vmactions/freebsd-vm@35a5b20a98476a681c7576a344775be7e7f77f06 # v1.0.6 with: usesh: true mem: 8192 @@ -33,12 +36,12 @@ jobs: steps: - name: Checkout repo - uses: actions/checkout@v3 + uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0 with: repository: 'intel/intel-ipsec-mb' - name: Build - uses: vmactions/freebsd-vm@v1 + uses: vmactions/freebsd-vm@35a5b20a98476a681c7576a344775be7e7f77f06 # v1.0.6 with: usesh: true mem: 8192 @@ -53,12 +56,12 @@ jobs: steps: - name: Checkout repo - uses: actions/checkout@v3 + uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0 with: repository: 'intel/intel-ipsec-mb' - name: Clang Release Build - uses: vmactions/freebsd-vm@v1 + uses: vmactions/freebsd-vm@35a5b20a98476a681c7576a344775be7e7f77f06 # v1.0.6 with: usesh: true mem: 8192 @@ -79,12 +82,12 @@ jobs: steps: - name: Checkout repo - uses: actions/checkout@v3 + uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0 with: repository: 'intel/intel-ipsec-mb' - name: Release build with GCC - uses: vmactions/freebsd-vm@v1 + uses: vmactions/freebsd-vm@35a5b20a98476a681c7576a344775be7e7f77f06 # v1.0.6 with: usesh: true mem: 8192 diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 6a1b159d273c7e7e0f2ad86f9e6c767e8f99603c..649998c46f8e882464dcf3560d4e317b29990abc 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -6,6 +6,9 @@ on: pull_request: branches: [ main ] +permissions: + contents: read + jobs: # Build shared library with Make (GCC) release-make-gcc-shared: @@ -16,7 +19,7 @@ jobs: run: sudo apt-get install -y nasm - name: Checkout repo - uses: actions/checkout@v3 + uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0 with: repository: intel/intel-ipsec-mb @@ -39,7 +42,7 @@ jobs: run: sudo apt-get install -y nasm - name: Checkout repo - uses: actions/checkout@v3 + uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0 with: repository: intel/intel-ipsec-mb @@ -55,7 +58,7 @@ jobs: run: sudo apt-get install -y nasm clang - name: Checkout repo - uses: actions/checkout@v3 + uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0 with: repository: intel/intel-ipsec-mb @@ -71,7 +74,7 @@ jobs: run: sudo apt-get install -y nasm clang - name: Checkout repo - uses: actions/checkout@v3 + uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0 with: repository: intel/intel-ipsec-mb @@ -87,7 +90,7 @@ jobs: run: sudo apt-get install -y nasm clang - name: Checkout repo - uses: actions/checkout@v3 + uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0 with: repository: intel/intel-ipsec-mb @@ -105,7 +108,7 @@ jobs: run: sudo apt-get install -y nasm - name: Checkout repo - uses: actions/checkout@v3 + uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0 with: repository: 'intel/intel-ipsec-mb' @@ -138,7 +141,7 @@ jobs: run: sudo apt-get install -y nasm - name: Checkout repo - uses: actions/checkout@v3 + uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0 with: repository: 'intel/intel-ipsec-mb' diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index e1032ec69464b5560d9f0303bc9a6cc8edb1ec06..727009d684082215b63d75f0a887c0f1994a98f1 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -6,6 +6,9 @@ on: pull_request: branches: [ main ] +permissions: + contents: read + jobs: # CMake release build with shared library (msbuild) release-cmake-msvc-msbuild: @@ -15,15 +18,15 @@ jobs: steps: - name: Setup NASM - uses: ilammy/setup-nasm@v1 + uses: ilammy/setup-nasm@13cbeb366c45c4379d3478cdcbadd8295feb5028 # v1.5.1 - name: Checkout repo - uses: actions/checkout@v3 + uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0 with: repository: 'intel/intel-ipsec-mb' - name: Add MSBuild to PATH - uses: microsoft/setup-msbuild@v1.0.2 + uses: microsoft/setup-msbuild@c26a08ba26249b81327e26f6ef381897b6a8754d # v1.0.2 - name: Setup environment run: | @@ -50,15 +53,15 @@ jobs: steps: - name: Setup NASM - uses: ilammy/setup-nasm@v1 + uses: ilammy/setup-nasm@13cbeb366c45c4379d3478cdcbadd8295feb5028 # v1.5.1 - name: Checkout repo - uses: actions/checkout@v3 + uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0 with: repository: 'intel/intel-ipsec-mb' - name: Add MSBuild to PATH - uses: microsoft/setup-msbuild@v1.0.2 + uses: microsoft/setup-msbuild@c26a08ba26249b81327e26f6ef381897b6a8754d # v1.0.2 - name: Setup environment run: | diff --git a/README.md b/README.md index f74bd54acafc8ffd635f98ada739467cd6c58f29..d6b3652fd76e7c3180b01fab54515e2b87f43b07 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,7 @@ ![Windows](https://github.com/intel/intel-ipsec-mb/actions/workflows/windows.yml/badge.svg) ![FreeBSD](https://github.com/intel/intel-ipsec-mb/actions/workflows/freebsd.yml/badge.svg) [![Coverity Status](https://scan.coverity.com/projects/16449/badge.svg)](https://scan.coverity.com/projects/intel-ipsec-mb) +[![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/intel/intel-ipsec-mb/badge)](https://securityscorecards.dev/viewer/?uri=github.com/intel/intel-ipsec-mb) # Multi-Buffer Crypto for IPsec Library diff --git a/ReleaseNotes.txt b/ReleaseNotes.txt index 9eb0f4a40b7ba7cd3434a3767677dbc3e8d9e07e..aac09b872207cb4afdfc7caf13536ab01b81a7bd 100644 --- a/ReleaseNotes.txt +++ b/ReleaseNotes.txt @@ -1,6 +1,11 @@ ======================================================================== Release Notes for Intel(R) Multi-Buffer Crypto for IPsec Library +Unreleased +====================================================================== +General +- YASM support removed. + v1.5 November 2023 ======================================================================= diff --git a/lib/Makefile b/lib/Makefile index 98a0986a3404eb688305d060538b6bf68bcb5cb7..c3c64b62bbba19b4bd438cc37c6e3aaa53bfdb80 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -49,8 +49,6 @@ MAN2 = libipsec-mb-dev.7 NOLDCONFIG ?= n ifeq ($(ARCH),x86_64) -USE_YASM ?= n -YASM ?= yasm NASM ?= nasm endif @@ -164,13 +162,10 @@ endif ASM_INCLUDE_DIRS := . -YASM_INCLUDES := $(foreach i,$(ASM_INCLUDE_DIRS),-I $i) NASM_INCLUDES := $(foreach i,$(ASM_INCLUDE_DIRS),-I$i/) ifneq ($(MINGW),0) -YASM_FLAGS := -f x64 -f win64 -X gnu -g dwarf2 -DWIN_ABI $(YASM_INCLUDES) NASM_FLAGS := -Werror -fwin64 -Xvc -gcv8 -DWIN_ABI $(NASM_INCLUDES) else -YASM_FLAGS := -f x64 -f elf64 -X gnu -g dwarf2 -DLINUX -D__linux__ $(YASM_INCLUDES) NASM_FLAGS := -Werror -felf64 -Xgnu -gdwarf -DLINUX -D__linux__ $(NASM_INCLUDES) endif @@ -198,25 +193,21 @@ endif ifneq ($(SAFE_DATA),n) CFLAGS += -DSAFE_DATA NASM_FLAGS += -DSAFE_DATA -YASM_FLAGS += -DSAFE_DATA endif ifneq ($(SAFE_PARAM),n) CFLAGS += -DSAFE_PARAM NASM_FLAGS += -DSAFE_PARAM -YASM_FLAGS += -DSAFE_PARAM endif ifneq ($(SAFE_LOOKUP),n) CFLAGS += -DSAFE_LOOKUP NASM_FLAGS += -DSAFE_LOOKUP -YASM_FLAGS += -DSAFE_LOOKUP endif ifeq ($(AESNI_EMU),y) CFLAGS += -DAESNI_EMU NASM_FLAGS += -DAESNI_EMU -YASM_FLAGS += -DAESNI_EMU endif # prevent SIMD optimizations for non-aesni modules @@ -995,118 +986,73 @@ $(OBJ_DIR)/%.o:x86_64/%.c $(CC) -MMD $(OPT_X86) -c $(CFLAGS) $< -o $@ $(OBJ_DIR)/%.o:x86_64/%.asm -ifeq ($(USE_YASM),y) - $(YASM) $(YASM_FLAGS) $< -o $@ -else $(NASM) -MD $(@:.o=.d) -MT $@ -o $@ $(NASM_FLAGS) $< -endif $(OBJ_DIR)/%.o:sse_t1/%.c $(CC) -MMD $(OPT_SSE) -c $(CFLAGS) $< -o $@ $(OBJ_DIR)/%.o:sse_t1/%.asm -ifeq ($(USE_YASM),y) - $(YASM) $(YASM_FLAGS) $< -o $@ -else $(NASM) -MD $(@:.o=.d) -MT $@ -o $@ $(NASM_FLAGS) $< -endif $(OBJ_DIR)/%.o:sse_t2/%.c $(CC) -MMD $(OPT_SSE) -c $(CFLAGS) $< -o $@ $(OBJ_DIR)/%.o:sse_t2/%.asm -ifeq ($(USE_YASM),y) - $(YASM) $(YASM_FLAGS) $< -o $@ -else $(NASM) -MD $(@:.o=.d) -MT $@ -o $@ $(NASM_FLAGS) $< -endif $(OBJ_DIR)/%.o:sse_t3/%.c $(CC) -MMD $(OPT_SSE) -c $(CFLAGS) $< -o $@ $(OBJ_DIR)/%.o:sse_t3/%.asm -ifeq ($(USE_YASM),y) - $(YASM) $(YASM_FLAGS) $< -o $@ -else $(NASM) -MD $(@:.o=.d) -MT $@ -o $@ $(NASM_FLAGS) $< -endif $(OBJ_DIR)/%.o:avx_t1/%.c $(CC) -MMD $(OPT_AVX) -c $(CFLAGS) $< -o $@ $(OBJ_DIR)/%.o:avx_t1/%.asm -ifeq ($(USE_YASM),y) - $(YASM) $(YASM_FLAGS) $< -o $@ -else $(NASM) -MD $(@:.o=.d) -MT $@ -o $@ $(NASM_FLAGS) $< -endif $(OBJ_DIR)/%.o:avx_t2/%.c $(CC) -MMD $(OPT_AVX) -c $(CFLAGS) $< -o $@ $(OBJ_DIR)/%.o:avx_t2/%.asm -ifeq ($(USE_YASM),y) - $(YASM) $(YASM_FLAGS) $< -o $@ -else $(NASM) -MD $(@:.o=.d) -MT $@ -o $@ $(NASM_FLAGS) $< -endif + $(OBJ_DIR)/%.o:avx2_t1/%.c $(CC) -MMD $(OPT_AVX2) -c $(CFLAGS) $< -o $@ $(OBJ_DIR)/%.o:avx2_t1/%.asm -ifeq ($(USE_YASM),y) - $(YASM) $(YASM_FLAGS) $< -o $@ -else $(NASM) -MD $(@:.o=.d) -MT $@ -o $@ $(NASM_FLAGS) $< -endif + $(OBJ_DIR)/%.o:avx2_t2/%.c $(CC) -MMD $(OPT_AVX2) -c $(CFLAGS) $< -o $@ $(OBJ_DIR)/%.o:avx2_t2/%.asm -ifeq ($(USE_YASM),y) - $(YASM) $(YASM_FLAGS) $< -o $@ -else $(NASM) -MD $(@:.o=.d) -MT $@ -o $@ $(NASM_FLAGS) $< -endif + $(OBJ_DIR)/%.o:avx2_t3/%.c $(CC) -MMD $(OPT_AVX2) -c $(CFLAGS) $< -o $@ $(OBJ_DIR)/%.o:avx2_t3/%.asm -ifeq ($(USE_YASM),y) - $(YASM) $(YASM_FLAGS) $< -o $@ -else $(NASM) -MD $(@:.o=.d) -MT $@ -o $@ $(NASM_FLAGS) $< -endif $(OBJ_DIR)/%.o:avx512_t1/%.c $(CC) -MMD $(OPT_AVX512) -c $(CFLAGS) $< -o $@ $(OBJ_DIR)/%.o:avx512_t1/%.asm -ifeq ($(USE_YASM),y) - $(YASM) $(YASM_FLAGS) $< -o $@ -else $(NASM) -MD $(@:.o=.d) -MT $@ -o $@ $(NASM_FLAGS) $< -endif $(OBJ_DIR)/%.o:avx512_t2/%.c $(CC) -MMD $(OPT_AVX512) -c $(CFLAGS) $< -o $@ $(OBJ_DIR)/%.o:avx512_t2/%.asm -ifeq ($(USE_YASM),y) - $(YASM) $(YASM_FLAGS) $< -o $@ -else $(NASM) -MD $(@:.o=.d) -MT $@ -o $@ $(NASM_FLAGS) $< -endif $(OBJ_DIR)/%.o:no-aesni/%.c $(CC) -MMD $(OPT_NOAESNI) -c $(CFLAGS_NO_SIMD) $< -o $@ $(OBJ_DIR)/%.o:no-aesni/%.asm -ifeq ($(USE_YASM),y) - $(YASM) $(YASM_FLAGS) $< -o $@ -else $(NASM) -MD $(@:.o=.d) -MT $@ -o $@ $(NASM_FLAGS) $< -endif endif # aarch64 $(OBJ_DIR): diff --git a/lib/avx2_t3/mb_mgr_avx2_t3.c b/lib/avx2_t3/mb_mgr_avx2_t3.c index 3e200dd1dbae77020287f8104079b9ff5f4ff550..826573e598f7b4bea58895bca485a70c13be0e09 100644 --- a/lib/avx2_t3/mb_mgr_avx2_t3.c +++ b/lib/avx2_t3/mb_mgr_avx2_t3.c @@ -135,9 +135,9 @@ #define AES_ECB_DEC_256 aes_ecb_dec_256_vaes_avx2 /* AES-CTR */ -#define AES_CTR_128 aes_cntr_128_avx -#define AES_CTR_192 aes_cntr_192_avx -#define AES_CTR_256 aes_cntr_256_avx +#define AES_CTR_128 aes_cntr_128_vaes_avx2 +#define AES_CTR_192 aes_cntr_192_vaes_avx2 +#define AES_CTR_256 aes_cntr_256_vaes_avx2 #define AES_CTR_128_BIT aes_cntr_bit_128_avx #define AES_CTR_192_BIT aes_cntr_bit_192_avx #define AES_CTR_256_BIT aes_cntr_bit_256_avx diff --git a/lib/x86_64/hmac_ipad_opad.c b/lib/x86_64/hmac_ipad_opad.c index 46f8283aa9e3b7f28be4e6b747d17cac73326a40..4df54d0dcb72c8fd4c4ff374e7d000e8ea17924e 100644 --- a/lib/x86_64/hmac_ipad_opad.c +++ b/lib/x86_64/hmac_ipad_opad.c @@ -33,6 +33,7 @@ #include #include "include/error.h" #include "include/sm3.h" +#include "include/memcpy.h" IMB_DLL_EXPORT void @@ -102,7 +103,7 @@ imb_hmac_ipad_opad(IMB_MGR *mb_mgr, const IMB_HASH_ALG sha_type, const void *pke /* prepare the key */ if (local_key_len == key_len) { - memcpy(key, pkey, key_len); + safe_memcpy(key, pkey, key_len); } else switch (sha_type) { case IMB_AUTH_HMAC_SHA_1: diff --git a/test/common/common.mk b/test/common/common.mk index fb32078c733c2d1c9b4610252ceab35296b7ea92..24fcf78e7ba82920f08082406f40f877ec142e4b 100644 --- a/test/common/common.mk +++ b/test/common/common.mk @@ -31,8 +31,6 @@ INSTPATH ?= /usr/include/ipsec-mb.h LIB_DIR ?= ../../lib ifeq ($(ARCH),x86_64) -USE_YASM ?= n -YASM ?= yasm NASM ?= nasm endif # x86_64 @@ -74,7 +72,6 @@ ifeq ($(CC_HAS_CET),1) CFLAGS += -fcf-protection=full endif -YASM_FLAGS := -f x64 -f elf64 -X gnu -g dwarf2 -DLINUX -D__linux__ ifeq ($(MINGW),0) CFLAGS += -DLINUX NASM_FLAGS := -Werror -felf64 -Xgnu -gdwarf -DLINUX -D__linux__ diff --git a/test/xvalid-app/Makefile b/test/xvalid-app/Makefile index 52c25bfd4dbb62c9222f1a35d434fc36d37f4c58..2c32b9a1eb4488ba414a3fbe16d7cce9b39451ce 100644 --- a/test/xvalid-app/Makefile +++ b/test/xvalid-app/Makefile @@ -38,11 +38,7 @@ OBJECTS := $(SOURCES:%.c=%.o) $(ASM:%.asm=%.o) utils.o # rule for compiling assembly code with producing dependencies %.o:%.asm -ifeq ($(USE_YASM),y) - $(YASM) $(YASM_FLAGS) $< -o $@ -else $(NASM) -MD $(@:.o=.d) -MT $@ -o $@ $(NASM_FLAGS) $< -endif else # x86_64 ASM := misc_aarch64.S diff --git a/test/xvalid-app/ipsec_xvalid.c b/test/xvalid-app/ipsec_xvalid.c index e72d1883c1fa828dd4a5de9480242a511e3057d2..5909a0368425262adbd3f5901d83ce7d29d12f99 100644 --- a/test/xvalid-app/ipsec_xvalid.c +++ b/test/xvalid-app/ipsec_xvalid.c @@ -92,6 +92,11 @@ #define MAX_SAFE_RETRIES 100 #define DEFAULT_SAFE_RETRIES 2 +/* Sensitive data search pattern definitions */ +#define FOUND_CIPHER_KEY 1 +#define FOUND_AUTH_KEY 2 +#define FOUND_TEXT 3 + static int pattern_auth_key; static int pattern_cipher_key; static int pattern_plain_text; @@ -141,6 +146,17 @@ struct data { uint8_t tag_size; }; +struct job_ctx { + uint64_t xgem_hdr; + uint16_t pli; + uint8_t *in_digest; + uint8_t *out_digest; + uint8_t tag_size_to_check; + uint8_t *test_buf; + uint8_t *src_dst_buf; + uint32_t buf_size; +}; + struct custom_job_params { IMB_CIPHER_MODE cipher_mode; /* CBC, CNTR, DES, GCM etc. */ IMB_HASH_ALG hash_alg; /* SHA-1 or others... */ @@ -709,57 +725,216 @@ generate_patterns(void) } /* - * Searches across a block of memory if a pattern is present - * (indicating there is some left over sensitive data) + * @brief Searches across a block of memory if a pattern is present + * (indicating there is some left over sensitive data) * - * Returns 0 if pattern is present or -1 if not present + * @return search status + * @retval 0 nothing found + * @retval FOUND_CIPHER_KEY fragment of CIPHER_KEY found + * @retval FOUND_AUTH_KEY fragment of AUTH_KEY found + * @retval FOUND_TEXT fragment of TEXT found */ static int -search_patterns(const void *ptr, const size_t mem_size) +search_patterns_ex(const void *ptr, const size_t mem_size, size_t *offset) { const uint8_t *ptr8 = (const uint8_t *) ptr; const size_t limit = mem_size - sizeof(uint64_t); - const char *err_str = ""; - int ret = -1; - size_t i; - if (mem_size < sizeof(uint64_t)) { - fprintf(stderr, "Invalid mem_size arg!\n"); - return -1; - } + if (mem_size < sizeof(uint64_t) || offset == NULL) + return 0; + + *offset = 0; - for (i = 0; i <= limit; i++) { + for (size_t i = 0; i <= limit; i++) { const uint64_t string = *((const uint64_t *) &ptr8[i]); if (string == pattern8_cipher_key) { - err_str = "Part of CIPHER_KEY is present"; - ret = 0; - } else if (string == pattern8_auth_key) { - err_str = "Part of AUTH_KEY is present"; - ret = 0; - } else if (string == pattern8_plain_text) { - err_str = "Part of plain/ciphertext is present"; - ret = 0; + *offset = i; + return FOUND_CIPHER_KEY; } - if (ret != -1) - break; + if (string == pattern8_auth_key) { + *offset = i; + return FOUND_AUTH_KEY; + } + + if (string == pattern8_plain_text) { + *offset = i; + return FOUND_TEXT; + } } - if (ret != -1) { - static uint8_t tb[64]; - const size_t len_to_print = (mem_size - i) > sizeof(tb) ? sizeof(tb) : mem_size - i; + return 0; +} + +struct safe_check_ctx { + int key_exp_phase; - nosimd_memcpy(tb, &ptr8[i], len_to_print); + IMB_ARCH arch; + const char *dir_name; + unsigned job_idx; + unsigned job_size; - fprintf(stderr, "%s\n", err_str); - fprintf(stderr, "Offset = %zu bytes, Addr = %p, RSP = %p\n", i, &ptr8[i], rdrsp()); + int gps_check; + size_t gps_offset; - hexdump_ex(stderr, NULL, tb, len_to_print, &ptr8[i]); - return 0; + int simd_check; + size_t simd_offset; + size_t simd_reg_size; + const char *simd_reg_name; + + int rsp_check; + size_t rsp_offset; + void *rsp_ptr; + uint8_t rsp_buf[64]; + + int mgr_check; + size_t mgr_offset; + void *mgr_ptr; + + int ooo_check; + size_t ooo_offset; + void *ooo_ptr; + const char *ooo_name; + size_t ooo_size; +}; + +static void +print_match_gp(const void *ptr, const size_t offset) +{ + const char *reg_str[] = { "rax", "rbx", "rcx", "rdx", "rdi", "rsi", "r8", + "r9", "r10", "r11", "r12", "r13", "r14", "r15" }; + const uint8_t *ptr8 = (const uint8_t *) ptr; + const size_t len_to_print = 8; + const size_t reg_idx = offset / 8; + const char *reg_name = (reg_idx < DIM(reg_str)) ? reg_str[reg_idx] : ""; + + hexdump_ex(stderr, reg_name, &ptr8[offset & ~7], len_to_print, NULL); +} + +static void +print_match_xyzmm(const void *ptr, const size_t offset, const size_t simd_size, + const char *simd_name) +{ + const uint8_t *ptr8 = (const uint8_t *) ptr; + const size_t len_to_print = simd_size; + const size_t reg_idx = offset / simd_size; + char reg_name[8]; + + nosimd_memset(reg_name, 0, sizeof(reg_name)); + snprintf(reg_name, sizeof(reg_name) - 1, "%s%zu", simd_name, reg_idx); + hexdump_ex(stderr, reg_name, &ptr8[reg_idx * simd_size], len_to_print, NULL); +} + +static void +print_match_memory(const void *ptr, const size_t mem_size, const size_t offset, + const char *mem_name) +{ + const uint8_t *ptr8 = (const uint8_t *) ptr; + static uint8_t tb[64]; + const size_t len_to_print = + (sizeof(tb) > (mem_size - offset)) ? (mem_size - offset) : sizeof(tb); + + nosimd_memcpy(tb, &ptr8[offset], len_to_print); + hexdump_ex(stderr, mem_name, tb, len_to_print, &ptr8[offset]); +} + +static void +print_match_stack(const struct safe_check_ctx *ctx) +{ + const uint8_t *ptr8 = (const uint8_t *) ctx->rsp_ptr; + const size_t len_to_print = 64; + + fprintf(stderr, "RSP = %p, offset = %zu, effective address = %p\n", ptr8, ctx->rsp_offset, + &ptr8[ctx->rsp_offset]); + + hexdump_ex(stderr, "STACK", ctx->rsp_buf, len_to_print, &ptr8[ctx->rsp_offset]); +} + +static void +print_match_type(const int check, const char *err_str) +{ + if (check == FOUND_CIPHER_KEY) + fprintf(stderr, "Part of CIPHER_KEY found when %s\n", err_str); + else if (check == FOUND_AUTH_KEY) + fprintf(stderr, "Part of AUTH_KEY found when %s\n", err_str); + else if (check == FOUND_TEXT) + fprintf(stderr, "Part of plain/cipher text found when %s\n", err_str); +} + +static void +print_match(const struct safe_check_ctx *ctx, const char *err_str) +{ + if (ctx->gps_check) { + print_match_type(ctx->gps_check, err_str); + print_match_gp(gps, ctx->gps_offset); + return; } - return -1; + if (ctx->simd_check) { + print_match_type(ctx->simd_check, err_str); + print_match_xyzmm(simd_regs, ctx->simd_offset, ctx->simd_reg_size, + ctx->simd_reg_name); + return; + } + + if (ctx->rsp_check) { + print_match_type(ctx->rsp_check, err_str); + print_match_stack(ctx); + return; + } + + if (ctx->mgr_check) { + print_match_type(ctx->mgr_check, err_str); + print_match_memory(ctx->mgr_ptr, sizeof(IMB_MGR), ctx->mgr_offset, "IMB_MGR"); + return; + } + + if (ctx->ooo_check) { + print_match_type(ctx->ooo_check, err_str); + print_match_memory(ctx->ooo_ptr, ctx->ooo_size, ctx->ooo_offset, ctx->ooo_name); + return; + } +} + +static int +compare_match(const struct safe_check_ctx *a, const struct safe_check_ctx *b) +{ + if (a->key_exp_phase != b->key_exp_phase) + return 1; + if (a->arch != b->arch) + return 1; + if (a->dir_name != b->dir_name) + return 1; + + if (a->gps_check != b->gps_check) + return 1; + if (a->gps_offset != b->gps_offset) + return 1; + + if (a->simd_check != b->simd_check) + return 1; + if (a->simd_offset != b->simd_offset) + return 1; + + if (a->rsp_check != b->rsp_check) + return 1; + if (a->rsp_offset != b->rsp_offset) + return 1; + + if (a->mgr_check != b->mgr_check) + return 1; + if (a->mgr_offset != b->mgr_offset) + return 1; + + if (a->ooo_check != b->ooo_check) + return 1; + if (a->ooo_offset != b->ooo_offset) + return 1; + if (a->ooo_ptr != b->ooo_ptr) + return 1; + + return 0; } static size_t @@ -1530,121 +1705,165 @@ modify_docsis_crc32_test_buf(uint8_t *test_buf, const IMB_JOB *job, const uint32 } /* - * Checks for sensitive information in registers, stack and MB_MGR - * (in this order, to try to minimize pollution of the data left out - * after the job completion, due to these actual checks). + * @brief Checks for sensitive information in registers, stack and MB_MGR + * (in this order, to try to minimize pollution of the data left out + * after the job completion, due to these actual checks). * - * Returns -1 if sensitive information was found or 0 if not. + * @return check status + * @retval 0 all OK + * @retval -1 sensitive data found + * @retval -2 wrong input arguments */ static int -perform_safe_checks(IMB_MGR *mgr, const IMB_ARCH arch, const char *dir) +perform_safe_checks(IMB_MGR *mgr, const IMB_ARCH arch, struct safe_check_ctx *ctx, const char *dir) { - uint8_t *rsp_ptr; - uint32_t simd_size = 0; - void **ooo_ptr; - unsigned i; + static const struct { + size_t simd_set_size; + void (*simd_dump_fn)(void); + } simd_ctx[] = { + { 0, NULL }, /* none */ +#ifndef __aarch64__ + { XMM_MEM_SIZE, dump_xmms_sse }, /* no aesni */ + { XMM_MEM_SIZE, dump_xmms_sse }, /* sse */ + { XMM_MEM_SIZE, dump_xmms_avx }, /* avx */ + { YMM_MEM_SIZE, dump_ymms }, /* avx2 */ + { ZMM_MEM_SIZE, dump_zmms } /* avx512 */ +#else /* __aarch64__ */ + { SIMD_MEM_SIZE, dump_simd_regs}, /* no aesni */ + { SIMD_MEM_SIZE, dump_simd_regs}, /* aarch64 */ + { SVE256_MEM_SIZE, dump_sve256_regs} /* sve256 */ +#endif + }; dump_gps(); - switch (arch) { + + if (ctx == NULL) + return -2; + + if (arch == IMB_ARCH_NONE || arch >= IMB_ARCH_NUM) { + fprintf(stderr, "Invalid architecture!\n"); + return -2; + } + + uint8_t *rsp_ptr = rdrsp(); + + simd_ctx[arch].simd_dump_fn(); + + nosimd_memset(ctx, 0, sizeof(*ctx)); + + ctx->rsp_ptr = rsp_ptr; + ctx->arch = arch; + ctx->dir_name = dir; + #ifndef __aarch64__ - case IMB_ARCH_SSE: - case IMB_ARCH_NOAESNI: - dump_xmms_sse(); - simd_size = XMM_MEM_SIZE; - break; - case IMB_ARCH_AVX: - dump_xmms_avx(); - simd_size = XMM_MEM_SIZE; - break; - case IMB_ARCH_AVX2: - dump_ymms(); - simd_size = YMM_MEM_SIZE; - break; - case IMB_ARCH_AVX512: - dump_zmms(); - simd_size = ZMM_MEM_SIZE; - break; + if (arch == IMB_ARCH_AVX2) { + ctx->simd_reg_size = 32; + ctx->simd_reg_name = "ymm"; + } else if (arch == IMB_ARCH_AVX512) { + ctx->simd_reg_size = 64; + ctx->simd_reg_name = "zmm"; + } else { + ctx->simd_reg_size = 16; + ctx->simd_reg_name = "xmm"; + } #else /* __aarch64__ */ - case IMB_ARCH_NOAESNI: - case IMB_ARCH_AARCH64: - dump_simd_regs(); - simd_size = SIMD_MEM_SIZE; - break; - case IMB_ARCH_SVE256: - dump_sve256_regs(); - simd_size = SVE256_MEM_SIZE; - break; -#endif - default: - fprintf(stderr, "Error getting the architecture\n"); - return -1; + if (arch == IMB_ARCH_AARCH64) { + ctx->simd_reg_size = SIMD_MEM_SIZE; + ctx->simd_reg_name = "Vn"; } - if (search_patterns(gps, GP_MEM_SIZE) == 0) { - fprintf(stderr, "Pattern found in GP registers after %s data\n", dir); - return -1; + else if (arch == IMB_ARCH_SVE256) { + ctx->simd_reg_size = SVE256_MEM_SIZE; + ctx->simd_reg_name = "Zn"; } - if (search_patterns(simd_regs, simd_size) == 0) { - fprintf(stderr, "Pattern found in SIMD registers after %s data\n", dir); +#endif + + ctx->rsp_check = search_patterns_ex((rsp_ptr - STACK_DEPTH), STACK_DEPTH, &ctx->rsp_offset); + if (ctx->rsp_check != 0) { + const uint8_t *sp = (const uint8_t *) (rsp_ptr - STACK_DEPTH); + + nosimd_memcpy(ctx->rsp_buf, &sp[ctx->rsp_offset], sizeof(ctx->rsp_buf)); return -1; } - rsp_ptr = rdrsp(); - if (search_patterns((rsp_ptr - STACK_DEPTH), STACK_DEPTH) == 0) { - fprintf(stderr, "Pattern found in stack after %s data\n", dir); + + ctx->gps_check = search_patterns_ex(gps, GP_MEM_SIZE, &ctx->gps_offset); + if (ctx->gps_check != 0) return -1; - } - if (search_patterns(mgr, sizeof(IMB_MGR)) == 0) { - fprintf(stderr, "Pattern found in MB_MGR after %s data\n", dir); + ctx->simd_check = + search_patterns_ex(simd_regs, simd_ctx[arch].simd_set_size, &ctx->simd_offset); + if (ctx->simd_check != 0) + return -1; + + ctx->mgr_check = search_patterns_ex(mgr, sizeof(*mgr), &ctx->mgr_offset); + if (ctx->mgr_check != 0) return -1; - } /* search OOO managers */ - for (ooo_ptr = &mgr->aes128_ooo, i = 0; ooo_ptr < &mgr->end_ooo; ooo_ptr++, i++) { - static const char *const ooo_names[] = { - "aes128_ooo", - "aes192_ooo", - "aes256_ooo", - "docsis128_sec_ooo", - "docsis128_crc32_sec_ooo", - "docsis256_sec_ooo", - "docsis256_crc32_sec_ooo", - "des_enc_ooo", - "des_dec_ooo", - "des3_enc_ooo", - "des3_dec_ooo", - "docsis_des_enc_ooo", - "docsis_des_dec_ooo", - "hmac_sha_1_ooo", - "hmac_sha_224_ooo", - "hmac_sha_256_ooo", - "hmac_sha_384_ooo", - "hmac_sha_512_ooo", - "hmac_md5_ooo", - "aes_xcbc_ooo", - "aes_ccm_ooo", - "aes_cmac_ooo", - "zuc_eea3_ooo", - "zuc_eia3_ooo", - "aes128_cbcs_ooo", - "zuc256_eea3_ooo", - "zuc256_eia3_ooo", - "aes256_ccm_ooo", - "aes256_cmac_ooo", - "snow3g_uea2_ooo", - "snow3g_uia2_ooo", - "sha_1_ooo", - "sha_224_ooo", - "sha_256_ooo", - "sha_384_ooo", - "sha_512_ooo", - "end_ooo" /* add new ooo manager above this line */ - }; + static const char *const ooo_names[] = { + "aes128_ooo", + "aes192_ooo", + "aes256_ooo", + "docsis128_sec_ooo", + "docsis128_crc32_sec_ooo", + "docsis256_sec_ooo", + "docsis256_crc32_sec_ooo", + "des_enc_ooo", + "des_dec_ooo", + "des3_enc_ooo", + "des3_dec_ooo", + "docsis_des_enc_ooo", + "docsis_des_dec_ooo", + "hmac_sha_1_ooo", + "hmac_sha_224_ooo", + "hmac_sha_256_ooo", + "hmac_sha_384_ooo", + "hmac_sha_512_ooo", + "hmac_md5_ooo", + "aes_xcbc_ooo", + "aes_ccm_ooo", + "aes_cmac_ooo", + "zuc_eea3_ooo", + "zuc_eia3_ooo", + "aes128_cbcs_ooo", + "zuc256_eea3_ooo", + "zuc256_eia3_ooo", + "aes256_ccm_ooo", + "aes256_cmac_ooo", + "snow3g_uea2_ooo", + "snow3g_uia2_ooo", + "sha_1_ooo", + "sha_224_ooo", + "sha_256_ooo", + "sha_384_ooo", + "sha_512_ooo", + "end_ooo" /* add new ooo manager above this line */ + }; + static size_t ooo_size[64] = { 0 }; + static int ooo_size_set = 0; + void **ooo_ptr = NULL; + + IMB_ASSERT(IMB_DIM(ooo_names) <= IMB_DIM(ooo_size)); + + if (ooo_size_set == 0) { + ooo_ptr = &mgr->aes128_ooo; + for (unsigned i = 0; ooo_ptr < &mgr->end_ooo; ooo_ptr++, i++) { + void *ooo_mgr_p = *ooo_ptr; + + ooo_size[i] = get_ooo_mgr_size(ooo_mgr_p, i); + } + + ooo_size_set = 1; + } + + ooo_ptr = &mgr->aes128_ooo; + for (unsigned i = 0; ooo_ptr < &mgr->end_ooo; ooo_ptr++, i++) { void *ooo_mgr_p = *ooo_ptr; - if (search_patterns(ooo_mgr_p, get_ooo_mgr_size(ooo_mgr_p, i)) == 0) { - fprintf(stderr, - "Pattern found in OOO MGR (index=%u,\"%s\") after %s data\n", i, - ooo_names[i], dir); + ctx->ooo_check = search_patterns_ex(ooo_mgr_p, ooo_size[i], &ctx->ooo_offset); + if (ctx->ooo_check != 0) { + ctx->ooo_ptr = ooo_mgr_p; + ctx->ooo_name = ooo_names[i]; + ctx->ooo_size = ooo_size[i]; return -1; } } @@ -1654,8 +1873,7 @@ perform_safe_checks(IMB_MGR *mgr, const IMB_ARCH arch, const char *dir) static int post_job(IMB_MGR *mgr, IMB_JOB *job, unsigned *num_processed_jobs, const struct params_s *params, - uint8_t **test_buf, const unsigned *buf_sizes, const uint16_t *pli, - const uint64_t *xgem_hdr, const IMB_CIPHER_DIRECTION dir) + struct job_ctx *job_tab, const IMB_CIPHER_DIRECTION dir) { const unsigned idx = (unsigned) ((uintptr_t) job->user_data); @@ -1681,44 +1899,270 @@ post_job(IMB_MGR *mgr, IMB_JOB *job, unsigned *num_processed_jobs, const struct /* Only need to modify the buffer after encryption */ if (dir == IMB_DIR_ENCRYPT) { if (params->hash_alg == IMB_AUTH_PON_CRC_BIP) { - if (modify_pon_test_buf(test_buf[idx], job, pli[idx], xgem_hdr[idx]) < 0) + if (modify_pon_test_buf(job_tab[idx].test_buf, job, job_tab[idx].pli, + job_tab[idx].xgem_hdr) < 0) return -1; } if (params->hash_alg == IMB_AUTH_DOCSIS_CRC32) - modify_docsis_crc32_test_buf(test_buf[idx], job, buf_sizes[idx]); + modify_docsis_crc32_test_buf(job_tab[idx].test_buf, job, + job_tab[idx].buf_size); } return 0; } -/* Performs test using AES_HMAC or DOCSIS */ +static void +set_job_ctx(struct job_ctx *ctx, const unsigned imix, const unsigned safe_check, + const struct params_s *params, uint8_t *in_digest, uint8_t *out_digest, + uint8_t tag_size, uint8_t *test_buf, uint8_t *src_dst_buf) +{ + ctx->in_digest = in_digest; + ctx->out_digest = out_digest; + ctx->tag_size_to_check = tag_size; + ctx->test_buf = test_buf; + ctx->src_dst_buf = src_dst_buf; + + /* Prepare buffer sizes */ + if (imix) { + uint32_t random_num = rand() % DEFAULT_JOB_SIZE_MAX; + + /* If random number is 0, change the size to 16 */ + if (random_num == 0) + random_num = 16; + + /* + * CBC and ECB operation modes do not support lengths + * which are non-multiple of block size + */ + if (params->cipher_mode == IMB_CIPHER_CBC || + params->cipher_mode == IMB_CIPHER_ECB || + params->cipher_mode == IMB_CIPHER_CBCS_1_9) { + random_num += (IMB_AES_BLOCK_SIZE - 1); + random_num &= (~(IMB_AES_BLOCK_SIZE - 1)); + } + + if (params->cipher_mode == IMB_CIPHER_DES || + params->cipher_mode == IMB_CIPHER_DES3) { + random_num += (IMB_DES_BLOCK_SIZE - 1); + random_num &= (~(IMB_DES_BLOCK_SIZE - 1)); + } + + if (params->cipher_mode == IMB_CIPHER_SM4_ECB || + params->cipher_mode == IMB_CIPHER_SM4_CBC) { + random_num += (IMB_SM4_BLOCK_SIZE - 1); + random_num &= (~(IMB_SM4_BLOCK_SIZE - 1)); + } + + /* + * KASUMI-UIA1 needs to be at least 9 bytes + * (IV + direction bit + '1' + 0s to align to + * byte boundary) + */ + if (params->hash_alg == IMB_AUTH_KASUMI_UIA1) + if (random_num < (IMB_KASUMI_BLOCK_SIZE + 1)) + random_num = 16; + + ctx->buf_size = random_num; + } else + ctx->buf_size = params->buf_size; + + if (params->hash_alg == IMB_AUTH_PON_CRC_BIP) { + /* Buf size is XGEM payload, including CRC, + * allocate space for XGEM header and padding */ + ctx->pli = ctx->buf_size; + ctx->buf_size += 8; + if (ctx->buf_size < 16) + ctx->buf_size = 16; + if (ctx->buf_size % 4) + ctx->buf_size = (ctx->buf_size + 3) & 0xfffffffc; + /* + * Only first 4 bytes are checked, corresponding to BIP + */ + ctx->tag_size_to_check = 4; + } + + if (params->hash_alg == IMB_AUTH_DOCSIS_CRC32) { + if (ctx->buf_size >= + (IMB_DOCSIS_CRC32_MIN_ETH_PDU_SIZE + IMB_DOCSIS_CRC32_TAG_SIZE)) + ctx->tag_size_to_check = IMB_DOCSIS_CRC32_TAG_SIZE; + else + ctx->tag_size_to_check = 0; + } + + if (safe_check) + nosimd_memset(ctx->test_buf, pattern_plain_text, ctx->buf_size); + else + generate_random_buf(ctx->test_buf, ctx->buf_size); + + /* For PON, construct the XGEM header, setting valid PLI */ + if (params->hash_alg == IMB_AUTH_PON_CRC_BIP) { + /* create XGEM header template */ + const uint16_t shifted_pli = (ctx->pli << 2) & 0xffff; + uint64_t *p_src = (uint64_t *) ctx->test_buf; + + ctx->xgem_hdr = ((shifted_pli >> 8) & 0xff) | ((shifted_pli & 0xff) << 8); + p_src[0] = ctx->xgem_hdr; + } + + /* Randomize memory for output digest */ + generate_random_buf(ctx->out_digest, ctx->tag_size_to_check); +} + +static int +process_jobs(IMB_MGR *mb_mgr, IMB_JOB *job_tab, const unsigned num_jobs, + const struct params_s *params, struct job_ctx *job_ctx_tab, + const char *avx_sse_text_submit, const char *avx_sse_text_flush, unsigned *err_idx) +{ + unsigned i; + unsigned num_processed_jobs = 0; + + *err_idx = num_jobs; + + if (burst_api) { + IMB_JOB *burst_jobs[IMB_MAX_BURST_SIZE]; + + /* num_jobs will always be lower than IMB_MAX_BURST_SIZE */ + unsigned num_rx_jobs = IMB_GET_NEXT_BURST(mb_mgr, num_jobs, burst_jobs); + + if (num_rx_jobs != num_jobs) { + fprintf(stderr, + "Number of jobs received %u is different than requested %u\n", + num_rx_jobs, num_jobs); + return -1; + } + + for (i = 0; i < num_jobs; i++) + *burst_jobs[i] = job_tab[i]; + + num_rx_jobs = IMB_SUBMIT_BURST(mb_mgr, num_jobs, burst_jobs); +#ifndef __aarch64__ + avx_sse_check(avx_sse_text_submit, (unsigned) params->hash_alg, + (unsigned) params->cipher_mode); +#endif + if (num_rx_jobs < num_jobs) { + num_rx_jobs += IMB_FLUSH_BURST(mb_mgr, (num_jobs - num_rx_jobs), + &burst_jobs[num_rx_jobs]); +#ifndef __aarch64__ + avx_sse_check(avx_sse_text_flush, (unsigned) params->hash_alg, + (unsigned) params->cipher_mode); +#endif + } + + if (num_rx_jobs != num_jobs) { + fprintf(stderr, + "Number of processed jobs %u is different than submitted %u\n", + num_rx_jobs, num_jobs); + return -1; + } + + for (i = 0; i < num_rx_jobs; i++) + if (post_job(mb_mgr, burst_jobs[i], &num_processed_jobs, params, + job_ctx_tab, IMB_DIR_ENCRYPT) < 0) { + *err_idx = i; + return -1; + } + + } else { + for (i = 0; i < num_jobs; i++) { + IMB_JOB *job = IMB_GET_NEXT_JOB(mb_mgr); + + *job = job_tab[i]; + + job = IMB_SUBMIT_JOB(mb_mgr); +#ifndef __aarch64__ + avx_sse_check(avx_sse_text_submit, (unsigned) params->hash_alg, + (unsigned) params->cipher_mode); +#endif + + if (job) + if (post_job(mb_mgr, job, &num_processed_jobs, params, job_ctx_tab, + IMB_DIR_ENCRYPT) < 0) { + *err_idx = (unsigned) ((uintptr_t) job->user_data); + return -1; + } + } + /* Flush rest of the jobs, if there are outstanding jobs */ + while (num_processed_jobs != num_jobs) { + IMB_JOB *job = IMB_FLUSH_JOB(mb_mgr); +#ifndef __aarch64__ + avx_sse_check(avx_sse_text_flush, (unsigned) params->hash_alg, + (unsigned) params->cipher_mode); +#endif + + while (job != NULL) { + if (post_job(mb_mgr, job, &num_processed_jobs, params, job_ctx_tab, + IMB_DIR_ENCRYPT) < 0) { + *err_idx = (unsigned) ((uintptr_t) job->user_data); + return -1; + } + + /* Get more completed jobs */ + job = IMB_GET_COMPLETED_JOB(mb_mgr); + } + } + } + + return 0; +} + +static void +print_fail_context(IMB_MGR *enc_mb_mgr, const IMB_ARCH enc_arch, IMB_MGR *dec_mb_mgr, + const IMB_ARCH dec_arch, const struct params_s *params, struct data *data, + const unsigned imix, const unsigned num_jobs, const unsigned idx, + const struct job_ctx *job_ctx_tab, const struct safe_check_ctx *safe_ctx) +{ + printf("Failures in\n"); + print_algo_info(params); + printf("\nEncrypting "); + print_tested_arch(enc_mb_mgr->features, enc_arch); + printf("\nDecrypting "); + print_tested_arch(dec_mb_mgr->features, dec_arch); + printf("\n"); + /* + * Print buffer size info if the failure was caused by an actual job, + * where "idx" indicates the index of the job failing + */ + if (idx < num_jobs) { + if (imix) { + if (job_ctx_tab != NULL) { + printf("Job #%u, buffer size = %u\n", idx, + job_ctx_tab[idx].buf_size); + + for (unsigned n = 0; n < num_jobs; n++) + printf("Other sizes = %u\n", job_ctx_tab[n].buf_size); + } else if (safe_ctx != NULL) { + printf("Job #%u, buffer size = %u\n", safe_ctx->job_idx, + safe_ctx->job_size); + } + } else + printf("Buffer size = %u\n", params->buf_size); + } + printf("Key size = %u\n", params->key_size); + printf("Tag size = %u\n", data->tag_size); + printf("AAD size = %u\n", (uint32_t) params->aad_size); +} + +/* + * @brief Performs test using AES_HMAC or DOCSIS + * @return Operation status + * @retval 0 success + * @retval -1 encrypt/decrypt operation error (result mismatch, unsupported algorithm etc.) + * @retval -2 safe check error + */ static int do_test(IMB_MGR *enc_mb_mgr, const IMB_ARCH enc_arch, IMB_MGR *dec_mb_mgr, const IMB_ARCH dec_arch, - const struct params_s *params, struct data *data, const unsigned safe_check, + const struct params_s *params, struct data *data, struct safe_check_ctx *p_safe_check, const unsigned imix, const unsigned num_jobs) { - IMB_JOB *job; - uint32_t i; + struct job_ctx job_ctx_tab[MAX_NUM_JOBS]; + IMB_JOB job_tab[MAX_NUM_JOBS]; + unsigned i; int ret = -1; - uint64_t xgem_hdr[MAX_NUM_JOBS] = { 0 }; - uint8_t tag_size_to_check[MAX_NUM_JOBS]; struct cipher_auth_keys *enc_keys = &data->enc_keys; struct cipher_auth_keys *dec_keys = &data->dec_keys; - uint8_t *aad = data->aad; - uint8_t *cipher_iv = data->cipher_iv; - uint8_t *auth_iv = data->auth_iv; - uint8_t *in_digest[MAX_NUM_JOBS]; - uint8_t *out_digest[MAX_NUM_JOBS]; - uint8_t *test_buf[MAX_NUM_JOBS] = { NULL }; - uint8_t *src_dst_buf[MAX_NUM_JOBS]; - uint32_t buf_sizes[MAX_NUM_JOBS] = { 0 }; - uint8_t *ciph_key = data->ciph_key; - uint8_t *auth_key = data->auth_key; - unsigned int num_processed_jobs = 0; uint8_t next_iv[IMB_AES_BLOCK_SIZE]; - uint16_t pli[MAX_NUM_JOBS] = { 0 }; - uint8_t tag_size = data->tag_size; + const unsigned safe_check = (p_safe_check != NULL); if (num_jobs == 0) return ret; @@ -1727,104 +2171,21 @@ do_test(IMB_MGR *enc_mb_mgr, const IMB_ARCH enc_arch, IMB_MGR *dec_mb_mgr, const * set keys and plaintext to known values, * so they can be searched later on in the MB_MGR structure and stack. * Otherwise, just randomize the data */ - generate_random_buf(cipher_iv, MAX_IV_SIZE); - generate_random_buf(auth_iv, MAX_IV_SIZE); - generate_random_buf(aad, MAX_AAD_SIZE); + generate_random_buf(data->cipher_iv, MAX_IV_SIZE); + generate_random_buf(data->auth_iv, MAX_IV_SIZE); + generate_random_buf(data->aad, MAX_AAD_SIZE); if (safe_check) { - nosimd_memset(ciph_key, pattern_cipher_key, MAX_KEY_SIZE); - nosimd_memset(auth_key, pattern_auth_key, MAX_KEY_SIZE); + nosimd_memset(data->ciph_key, pattern_cipher_key, MAX_KEY_SIZE); + nosimd_memset(data->auth_key, pattern_auth_key, MAX_KEY_SIZE); } else { - generate_random_buf(ciph_key, MAX_KEY_SIZE); - generate_random_buf(auth_key, MAX_KEY_SIZE); + generate_random_buf(data->ciph_key, MAX_KEY_SIZE); + generate_random_buf(data->auth_key, MAX_KEY_SIZE); } - for (i = 0; i < num_jobs; i++) { - in_digest[i] = data->in_digest[i]; - out_digest[i] = data->out_digest[i]; - tag_size_to_check[i] = tag_size; - test_buf[i] = data->test_buf[i]; - src_dst_buf[i] = data->src_dst_buf[i]; - /* Prepare buffer sizes */ - if (imix) { - uint32_t random_num = rand() % DEFAULT_JOB_SIZE_MAX; - - /* If random number is 0, change the size to 16 */ - if (random_num == 0) - random_num = 16; - - /* - * CBC and ECB operation modes do not support lengths - * which are non-multiple of block size - */ - if (params->cipher_mode == IMB_CIPHER_CBC || - params->cipher_mode == IMB_CIPHER_ECB || - params->cipher_mode == IMB_CIPHER_CBCS_1_9) { - random_num += (IMB_AES_BLOCK_SIZE - 1); - random_num &= (~(IMB_AES_BLOCK_SIZE - 1)); - } - - if (params->cipher_mode == IMB_CIPHER_DES || - params->cipher_mode == IMB_CIPHER_DES3) { - random_num += (IMB_DES_BLOCK_SIZE - 1); - random_num &= (~(IMB_DES_BLOCK_SIZE - 1)); - } - - if (params->cipher_mode == IMB_CIPHER_SM4_ECB || - params->cipher_mode == IMB_CIPHER_SM4_CBC) { - random_num += (IMB_SM4_BLOCK_SIZE - 1); - random_num &= (~(IMB_SM4_BLOCK_SIZE - 1)); - } - - /* - * KASUMI-UIA1 needs to be at least 9 bytes - * (IV + direction bit + '1' + 0s to align to - * byte boundary) - */ - if (params->hash_alg == IMB_AUTH_KASUMI_UIA1) - if (random_num < (IMB_KASUMI_BLOCK_SIZE + 1)) - random_num = 16; - - buf_sizes[i] = random_num; - } else - buf_sizes[i] = params->buf_size; - - if (params->hash_alg == IMB_AUTH_PON_CRC_BIP) { - /* Buf size is XGEM payload, including CRC, - * allocate space for XGEM header and padding */ - pli[i] = buf_sizes[i]; - buf_sizes[i] += 8; - if (buf_sizes[i] < 16) - buf_sizes[i] = 16; - if (buf_sizes[i] % 4) - buf_sizes[i] = (buf_sizes[i] + 3) & 0xfffffffc; - /* Only first 4 bytes are checked, - * corresponding to BIP */ - tag_size_to_check[i] = 4; - } - - if (params->hash_alg == IMB_AUTH_DOCSIS_CRC32) { - if (buf_sizes[i] >= - (IMB_DOCSIS_CRC32_MIN_ETH_PDU_SIZE + IMB_DOCSIS_CRC32_TAG_SIZE)) - tag_size_to_check[i] = IMB_DOCSIS_CRC32_TAG_SIZE; - else - tag_size_to_check[i] = 0; - } - - if (safe_check) - nosimd_memset(test_buf[i], pattern_plain_text, buf_sizes[i]); - else - generate_random_buf(test_buf[i], buf_sizes[i]); - - /* For PON, construct the XGEM header, setting valid PLI */ - if (params->hash_alg == IMB_AUTH_PON_CRC_BIP) { - /* create XGEM header template */ - const uint16_t shifted_pli = (pli[i] << 2) & 0xffff; - uint64_t *p_src = (uint64_t *) test_buf[i]; - - xgem_hdr[i] = ((shifted_pli >> 8) & 0xff) | ((shifted_pli & 0xff) << 8); - p_src[0] = xgem_hdr[i]; - } - } + for (i = 0; i < num_jobs; i++) + set_job_ctx(&job_ctx_tab[i], imix, safe_check, params, data->in_digest[i], + data->out_digest[i], data->tag_size, data->test_buf[i], + data->src_dst_buf[i]); /* * Expand/schedule keys. @@ -1836,28 +2197,25 @@ do_test(IMB_MGR *enc_mb_mgr, const IMB_ARCH enc_arch, IMB_MGR *dec_mb_mgr, const * expansion functions. */ if (safe_check) { - uint8_t *rsp_ptr; - - /* Clear scratch registers before expanding keys to prevent - * other functions from storing sensitive data in stack - */ - if (prepare_keys(enc_mb_mgr, enc_keys, ciph_key, auth_key, params, 0) < 0) + if (prepare_keys(enc_mb_mgr, enc_keys, data->ciph_key, data->auth_key, params, 0) < + 0) goto exit; - rsp_ptr = rdrsp(); - if (search_patterns((rsp_ptr - STACK_DEPTH), STACK_DEPTH) == 0) { - fprintf(stderr, "Pattern found in stack after " - "expanding encryption keys\n"); + if (perform_safe_checks(enc_mb_mgr, enc_arch, p_safe_check, + "expanding encryption keys") < 0) { + p_safe_check->key_exp_phase = 1; + ret = -2; goto exit; } - if (prepare_keys(dec_mb_mgr, dec_keys, ciph_key, auth_key, params, 0) < 0) + if (prepare_keys(dec_mb_mgr, dec_keys, data->ciph_key, data->auth_key, params, 0) < + 0) goto exit; - rsp_ptr = rdrsp(); - if (search_patterns((rsp_ptr - STACK_DEPTH), STACK_DEPTH) == 0) { - fprintf(stderr, "Pattern found in stack after " - "expanding decryption keys\n"); + if (perform_safe_checks(dec_mb_mgr, dec_arch, p_safe_check, + "expanding decryption keys") < 0) { + p_safe_check->key_exp_phase = 1; + ret = -2; goto exit; } @@ -1866,16 +2224,20 @@ do_test(IMB_MGR *enc_mb_mgr, const IMB_ARCH enc_arch, IMB_MGR *dec_mb_mgr, const * it is time to setup the keys and key schedules filled * with specific patterns. */ - if (prepare_keys(enc_mb_mgr, enc_keys, ciph_key, auth_key, params, 1) < 0) + if (prepare_keys(enc_mb_mgr, enc_keys, data->ciph_key, data->auth_key, params, 1) < + 0) goto exit; - if (prepare_keys(dec_mb_mgr, dec_keys, ciph_key, auth_key, params, 1) < 0) + if (prepare_keys(dec_mb_mgr, dec_keys, data->ciph_key, data->auth_key, params, 1) < + 0) goto exit; } else { - if (prepare_keys(enc_mb_mgr, enc_keys, ciph_key, auth_key, params, 0) < 0) + if (prepare_keys(enc_mb_mgr, enc_keys, data->ciph_key, data->auth_key, params, 0) < + 0) goto exit; - if (prepare_keys(dec_mb_mgr, dec_keys, ciph_key, auth_key, params, 0) < 0) + if (prepare_keys(dec_mb_mgr, dec_keys, data->ciph_key, data->auth_key, params, 0) < + 0) goto exit; } @@ -1895,125 +2257,45 @@ do_test(IMB_MGR *enc_mb_mgr, const IMB_ARCH enc_arch, IMB_MGR *dec_mb_mgr, const PinBasedCEC_MarkSecret((uintptr_t) dec_keys->k3, sizeof(dec_keys->k3)); #endif - if (burst_api) { - unsigned num_rx_jobs; - - IMB_JOB *burst_jobs[IMB_MAX_BURST_SIZE]; - /* num_jobs will always be lower than IMB_MAX_BURST_SIZE */ - num_rx_jobs = IMB_GET_NEXT_BURST(enc_mb_mgr, num_jobs, burst_jobs); + /* Build encrypt job structures */ + for (i = 0; i < num_jobs; i++) { + IMB_JOB *job = &job_tab[i]; - if (num_rx_jobs != num_jobs) { - fprintf(stderr, "Number of jobs received less than requested\n"); + /* + * Encrypt + generate digest from encrypted message + * using architecture under test + */ + nosimd_memcpy(job_ctx_tab[i].src_dst_buf, job_ctx_tab[i].test_buf, + job_ctx_tab[i].buf_size); + if (fill_job(job, params, job_ctx_tab[i].src_dst_buf, job_ctx_tab[i].in_digest, + data->aad, job_ctx_tab[i].buf_size, data->tag_size, IMB_DIR_ENCRYPT, + enc_keys, data->cipher_iv, data->auth_iv, i, next_iv) < 0) goto exit; - } - for (i = 0; i < num_jobs; i++) { - IMB_JOB *job = burst_jobs[i]; - /* - * Encrypt + generate digest from encrypted message - * using architecture under test - */ - nosimd_memcpy(src_dst_buf[i], test_buf[i], buf_sizes[i]); - if (fill_job(job, params, src_dst_buf[i], in_digest[i], aad, buf_sizes[i], - tag_size, IMB_DIR_ENCRYPT, enc_keys, cipher_iv, auth_iv, i, - next_iv) < 0) - goto exit; - /* Randomize memory for input digest */ - generate_random_buf(in_digest[i], tag_size); + /* Randomize memory for input digest */ + generate_random_buf(job_ctx_tab[i].in_digest, data->tag_size); + if (burst_api) imb_set_session(enc_mb_mgr, job); - } - - num_rx_jobs = IMB_SUBMIT_BURST(enc_mb_mgr, num_jobs, burst_jobs); -#ifndef __aarch64__ - avx_sse_check("enc-submit-burst", (unsigned) params->hash_alg, - (unsigned) params->cipher_mode); -#endif - if (num_rx_jobs < num_jobs) { - num_rx_jobs += IMB_FLUSH_BURST(enc_mb_mgr, (num_jobs - num_rx_jobs), - &burst_jobs[num_rx_jobs]); -#ifndef __aarch64__ - avx_sse_check("enc-flush-burst", (unsigned) params->hash_alg, - (unsigned) params->cipher_mode); -#endif - } - - if (num_rx_jobs != num_jobs) { - fprintf(stderr, "Number of processed jobs less than submitted\n"); - goto exit; - } - - for (i = 0; i < num_rx_jobs; i++) { - IMB_JOB *job = burst_jobs[i]; - - if (post_job(enc_mb_mgr, job, &num_processed_jobs, params, test_buf, - buf_sizes, pli, xgem_hdr, IMB_DIR_ENCRYPT) < 0) - goto exit; - } - - } else { - for (i = 0; i < num_jobs; i++) { - job = IMB_GET_NEXT_JOB(enc_mb_mgr); - /* - * Encrypt + generate digest from encrypted message - * using architecture under test - */ - nosimd_memcpy(src_dst_buf[i], test_buf[i], buf_sizes[i]); - if (fill_job(job, params, src_dst_buf[i], in_digest[i], aad, buf_sizes[i], - tag_size, IMB_DIR_ENCRYPT, enc_keys, cipher_iv, auth_iv, i, - next_iv) < 0) - goto exit; - - /* Randomize memory for input digest */ - generate_random_buf(in_digest[i], tag_size); - - /* Clear scratch registers before submitting job to prevent - * other functions from storing sensitive data in stack */ - job = IMB_SUBMIT_JOB(enc_mb_mgr); - -#ifndef __aarch64__ - avx_sse_check("enc-submit", (unsigned) params->hash_alg, - (unsigned) params->cipher_mode); -#endif - if (job) { - if (post_job(enc_mb_mgr, job, &num_processed_jobs, params, test_buf, - buf_sizes, pli, xgem_hdr, IMB_DIR_ENCRYPT) < 0) { - i = (unsigned) ((uintptr_t) job->user_data); - goto exit; - } - } - } - /* Flush rest of the jobs, if there are outstanding jobs */ - while (num_processed_jobs != num_jobs) { - job = IMB_FLUSH_JOB(enc_mb_mgr); - -#ifndef __aarch64__ - avx_sse_check("enc-flush", (unsigned) params->hash_alg, - (unsigned) params->cipher_mode); -#endif - while (job != NULL) { - if (post_job(enc_mb_mgr, job, &num_processed_jobs, params, test_buf, - buf_sizes, pli, xgem_hdr, IMB_DIR_ENCRYPT) < 0) { - i = (unsigned) ((uintptr_t) job->user_data); - goto exit; - } - - /* Get more completed jobs */ - job = IMB_GET_COMPLETED_JOB(enc_mb_mgr); - } - } } + /* Process encrypt operations */ + if (process_jobs(enc_mb_mgr, job_tab, num_jobs, params, job_ctx_tab, "enc-submit", + "enc-flush", &i) != 0) + goto exit; + #ifdef PIN_BASED_CEC PinBasedCEC_ClearSecrets(); #endif - num_processed_jobs = 0; /* Check that the registers, stack and MB_MGR do not contain any - * sensitive information after job is returned */ + * sensitive information after job is returned + */ if (safe_check) - if (perform_safe_checks(enc_mb_mgr, enc_arch, "encrypting") < 0) + if (perform_safe_checks(enc_mb_mgr, enc_arch, p_safe_check, "encrypting") < 0) { + ret = -2; goto exit; + } #ifdef PIN_BASED_CEC PinBasedCEC_MarkSecret((uintptr_t) enc_keys->enc_keys, sizeof(enc_keys->enc_keys)); @@ -2031,152 +2313,87 @@ do_test(IMB_MGR *enc_mb_mgr, const IMB_ARCH enc_arch, IMB_MGR *dec_mb_mgr, const PinBasedCEC_MarkSecret((uintptr_t) dec_keys->k3, sizeof(dec_keys->k3)); #endif - if (burst_api) { - unsigned num_rx_jobs; + /* Build decrypt job structures */ + for (i = 0; i < num_jobs; i++) { + IMB_JOB *job = &job_tab[i]; - IMB_JOB *burst_jobs[IMB_MAX_BURST_SIZE]; - /* num_jobs will always be lower than IMB_MAX_BURST_SIZE */ - num_rx_jobs = IMB_GET_NEXT_BURST(dec_mb_mgr, num_jobs, burst_jobs); + /* Randomize memory for output digest */ + generate_random_buf(job_ctx_tab[i].out_digest, data->tag_size); - if (num_rx_jobs != num_jobs) { - fprintf(stderr, "Number of jobs received less than requested\n"); + /* + * Generate digest from encrypted message and decrypt + * using reference architecture + */ + if (fill_job(job, params, job_ctx_tab[i].src_dst_buf, job_ctx_tab[i].out_digest, + data->aad, job_ctx_tab[i].buf_size, data->tag_size, IMB_DIR_DECRYPT, + dec_keys, data->cipher_iv, data->auth_iv, i, next_iv) < 0) goto exit; - } - - for (i = 0; i < num_jobs; i++) { - IMB_JOB *job = burst_jobs[i]; - - /* Randomize memory for output digest */ - generate_random_buf(out_digest[i], tag_size); - - /* - * Generate digest from encrypted message and decrypt - * using reference architecture - */ - if (fill_job(job, params, src_dst_buf[i], out_digest[i], aad, buf_sizes[i], - tag_size, IMB_DIR_DECRYPT, dec_keys, cipher_iv, auth_iv, i, - next_iv) < 0) - goto exit; + if (burst_api) imb_set_session(dec_mb_mgr, job); - } - - num_rx_jobs = IMB_SUBMIT_BURST(dec_mb_mgr, num_jobs, burst_jobs); -#ifndef __aarch64__ - avx_sse_check("dec-submit-burst", (unsigned) params->hash_alg, - (unsigned) params->cipher_mode); -#endif - - if (num_rx_jobs < num_jobs) - num_rx_jobs += IMB_FLUSH_BURST(dec_mb_mgr, (num_jobs - num_rx_jobs), - &burst_jobs[num_rx_jobs]); - - if (num_rx_jobs != num_jobs) { - fprintf(stderr, "Number of processed jobs less than submitted\n"); - goto exit; - } - - for (i = 0; i < num_rx_jobs; i++) { - IMB_JOB *job = burst_jobs[i]; - - if (post_job(dec_mb_mgr, job, &num_processed_jobs, params, test_buf, - buf_sizes, pli, xgem_hdr, IMB_DIR_DECRYPT) < 0) - goto exit; - } - } else { - for (i = 0; i < num_jobs; i++) { - job = IMB_GET_NEXT_JOB(dec_mb_mgr); - - /* Randomize memory for output digest */ - generate_random_buf(out_digest[i], tag_size); - - /* - * Generate digest from encrypted message and decrypt - * using reference architecture - */ - if (fill_job(job, params, src_dst_buf[i], out_digest[i], aad, buf_sizes[i], - tag_size, IMB_DIR_DECRYPT, dec_keys, cipher_iv, auth_iv, i, - next_iv) < 0) - goto exit; - - /* Clear scratch registers before submitting job to prevent - * other functions from storing sensitive data in stack */ - job = IMB_SUBMIT_JOB(dec_mb_mgr); - -#ifndef __aarch64__ - avx_sse_check("dec-submit", (unsigned) params->hash_alg, - (unsigned) params->cipher_mode); -#endif - - if (job != NULL) { - if (post_job(dec_mb_mgr, job, &num_processed_jobs, params, test_buf, - buf_sizes, pli, xgem_hdr, IMB_DIR_DECRYPT) < 0) { - i = (unsigned) ((uintptr_t) job->user_data); - goto exit; - } - } - } - - /* Flush rest of the jobs, if there are outstanding jobs */ - while (num_processed_jobs != num_jobs) { - job = IMB_FLUSH_JOB(dec_mb_mgr); - -#ifndef __aarch64__ - avx_sse_check("dec-flush", (unsigned) params->hash_alg, - (unsigned) params->cipher_mode); -#endif - - while (job != NULL) { - if (post_job(dec_mb_mgr, job, &num_processed_jobs, params, test_buf, - buf_sizes, pli, xgem_hdr, IMB_DIR_DECRYPT) < 0) { - i = (unsigned) ((uintptr_t) job->user_data); - goto exit; - } - /* Get more completed jobs */ - job = IMB_GET_COMPLETED_JOB(dec_mb_mgr); - } - } } + /* Process decrypt operations */ + if (process_jobs(dec_mb_mgr, job_tab, num_jobs, params, job_ctx_tab, "dec-submit", + "dec-flush", &i) != 0) + goto exit; + #ifdef PIN_BASED_CEC PinBasedCEC_ClearSecrets(); #endif /* Check that the registers, stack and MB_MGR do not contain any * sensitive information after job is returned */ if (safe_check) { - if (perform_safe_checks(dec_mb_mgr, dec_arch, "decrypting") < 0) + if (perform_safe_checks(dec_mb_mgr, dec_arch, p_safe_check, "decrypting") < 0) { + ret = -2; goto exit; + } } else { + /* + * In safe check mode results are expected not to match. + * This is due to the fact that different arch implementations + * use various key formats. This is particularly visible with + * AES-GCM and its GHASH authentication function. + */ for (i = 0; i < num_jobs; i++) { int goto_exit = 0; if (params->hash_alg != IMB_AUTH_NULL && - memcmp(in_digest[i], out_digest[i], tag_size_to_check[i]) != 0) { + memcmp(job_ctx_tab[i].in_digest, job_ctx_tab[i].out_digest, + job_ctx_tab[i].tag_size_to_check) != 0) { fprintf(stderr, "\nInput and output tags " "don't match\n"); - hexdump(stdout, "Input digest", in_digest[i], tag_size_to_check[i]); - hexdump(stdout, "Output digest", out_digest[i], - tag_size_to_check[i]); + hexdump(stdout, "Input digest", job_ctx_tab[i].in_digest, + job_ctx_tab[i].tag_size_to_check); + hexdump(stdout, "Output digest", job_ctx_tab[i].out_digest, + job_ctx_tab[i].tag_size_to_check); goto_exit = 1; } if (params->cipher_mode != IMB_CIPHER_NULL && - memcmp(src_dst_buf[i], test_buf[i], buf_sizes[i]) != 0) { + memcmp(job_ctx_tab[i].src_dst_buf, job_ctx_tab[i].test_buf, + job_ctx_tab[i].buf_size) != 0) { fprintf(stderr, "\nDecrypted text and " "plaintext don't match\n"); - hexdump(stdout, "Plaintext (orig)", test_buf[i], buf_sizes[i]); - hexdump(stdout, "Decrypted msg", src_dst_buf[i], buf_sizes[i]); + hexdump(stdout, "Plaintext (orig)", job_ctx_tab[i].test_buf, + job_ctx_tab[i].buf_size); + hexdump(stdout, "Decrypted msg", job_ctx_tab[i].src_dst_buf, + job_ctx_tab[i].buf_size); goto_exit = 1; } - if ((params->hash_alg == IMB_AUTH_PON_CRC_BIP) && (pli[i] > 4)) { - const uint64_t plen = 8 + pli[i] - 4; + if ((params->hash_alg == IMB_AUTH_PON_CRC_BIP) && + (job_ctx_tab[i].pli > 4)) { + const uint64_t plen = 8 + job_ctx_tab[i].pli - 4; - if (memcmp(src_dst_buf[i] + plen, out_digest[i] + 4, 4) != 0) { + if (memcmp(job_ctx_tab[i].src_dst_buf + plen, + job_ctx_tab[i].out_digest + 4, 4) != 0) { fprintf(stderr, "\nDecrypted CRC and " "calculated CRC don't match\n"); - hexdump(stdout, "Decrypted CRC", src_dst_buf[i] + plen, 4); - hexdump(stdout, "Calculated CRC", out_digest[i] + 4, 4); + hexdump(stdout, "Decrypted CRC", + job_ctx_tab[i].src_dst_buf + plen, 4); + hexdump(stdout, "Calculated CRC", + job_ctx_tab[i].out_digest + 4, 4); goto_exit = 1; } } @@ -2192,27 +2409,14 @@ exit: /* clear data */ clear_data(data); - if (ret < 0) { - printf("Failures in\n"); - print_algo_info(params); - printf("Encrypting "); - print_tested_arch(enc_mb_mgr->features, enc_arch); - printf("Decrypting "); - print_tested_arch(dec_mb_mgr->features, dec_arch); - /* Print buffer size info if the failure was caused by an actual job, - where "i" indicates the index of the job failing */ - if (i < num_jobs) { - if (imix) { - printf("Job #%u, buffer size = %u\n", i, buf_sizes[i]); - - for (i = 0; i < num_jobs; i++) - printf("Other sizes = %u\n", buf_sizes[i]); - } else - printf("Buffer size = %u\n", params->buf_size); - } - printf("Key size = %u\n", params->key_size); - printf("Tag size = %u\n", tag_size); - printf("AAD size = %u\n", (uint32_t) params->aad_size); + if (ret == -1) { + print_fail_context(enc_mb_mgr, enc_arch, dec_mb_mgr, dec_arch, params, data, imix, + num_jobs, i, job_ctx_tab, NULL); + } else if (ret == -2) { + if (p_safe_check != NULL) { + p_safe_check->job_idx = i; + p_safe_check->job_size = job_ctx_tab[i].buf_size; + } } return ret; @@ -2302,36 +2506,33 @@ test_single(IMB_MGR *enc_mgr, const IMB_ARCH enc_arch, IMB_MGR *dec_mgr, const I /* Check for sensitive data first, then normal cross * architecture validation */ if (safe_check) { - int result; - - result = do_test(enc_mgr, enc_arch, dec_mgr, dec_arch, params, - variant_data, 1, 0, 1); - if (result < 0) { - uint32_t j; - - for (j = 0; j < safe_retries; j++) { - printf("=== Issue found. " - "Checking again...\n"); - generate_patterns(); - result = do_test(enc_mgr, enc_arch, dec_mgr, - dec_arch, params, variant_data, 1, - 0, 1); - if (result == 0) - break; - } - if (result < 0) { + struct safe_check_ctx safe_ctx1 = { 0 }; + const int result1 = do_test(enc_mgr, enc_arch, dec_mgr, dec_arch, + params, variant_data, &safe_ctx1, 0, 1); + if (result1 == -2) { + generate_patterns(); + + struct safe_check_ctx safe_ctx2 = { 0 }; + const int result2 = + do_test(enc_mgr, enc_arch, dec_mgr, dec_arch, + params, variant_data, &safe_ctx2, 0, 1); + + if (result2 == -2 && + compare_match(&safe_ctx1, &safe_ctx2) == 0) { if (verbose) printf("FAIL\n"); - printf("=== issue confirmed\n"); + print_fail_context(enc_mgr, enc_arch, dec_mgr, + dec_arch, params, variant_data, + 0, 1, 0, NULL, &safe_ctx2); + print_match(&safe_ctx2, safe_ctx2.dir_name); exit(EXIT_FAILURE); } - printf("=== false positive\n"); } + } else { + if (do_test(enc_mgr, enc_arch, dec_mgr, dec_arch, params, + variant_data, NULL, 0, 1) < 0) + exit(EXIT_FAILURE); } - - if (do_test(enc_mgr, enc_arch, dec_mgr, dec_arch, params, variant_data, 0, - 0, 1) < 0) - exit(EXIT_FAILURE); } } }