From d4fa1002f97b4b64d0fb0e9585b0debb91fa83c3 Mon Sep 17 00:00:00 2001 From: Alex Jbanca Date: Tue, 9 May 2023 16:21:44 +0300 Subject: [PATCH] performance(sqlcipher): Fix burn_stack performance issue Fixing status-im/status-desktop#10572 Implements a cross-platform version of OP-TEE/optee_os#3102 Remove recursion Use memset instead of while loop A description to understand introduced changes without reading the code. zeromem weights about 50% of the total CPU time on M1 Macs and seems to be major performance offender. It is used to clear the stack when using variables with sensitive information. --- burn_stack.c | 4 +--- zeromem.c | 15 +++++++++++---- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/burn_stack.c b/burn_stack.c index 2610c06..9cc9826 100644 --- a/burn_stack.c +++ b/burn_stack.c @@ -21,10 +21,8 @@ */ void burn_stack(unsigned long len) { - unsigned char buf[32]; + unsigned char buf[len]; zeromem(buf, sizeof(buf)); - if (len > (unsigned long)sizeof(buf)) - burn_stack(len - sizeof(buf)); } diff --git a/zeromem.c b/zeromem.c index 9dff602..1182372 100644 --- a/zeromem.c +++ b/zeromem.c @@ -9,12 +9,22 @@ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" +#include /** @file zeromem.c Zero a block of memory, Tom St Denis */ +/* + * Pointer to memset is volatile so that compiler must de-reference + * the pointer and can't assume that it points to any function in + * particular (such as memset, which it then might further "optimize") + */ +typedef void *(*memset_t)(void *, int, size_t); + +static volatile memset_t memset_func = memset; + /** Zero a block of memory @param out The destination of the area to zero @@ -22,11 +32,8 @@ */ void zeromem(void *out, size_t outlen) { - unsigned char *mem = out; LTC_ARGCHKVD(out != NULL); - while (outlen-- > 0) { - *mem++ = 0; - } + memset_func((void *)out, 0, outlen); } /* $Source$ */