diff --git a/tests/api.c b/tests/api.c index d03a32080f4..70f14bfeb2c 100644 --- a/tests/api.c +++ b/tests/api.c @@ -22203,6 +22203,9 @@ static int test_wolfSSL_ERR_print_errors_cb(void) "wolfSSL error occurred, error = 275 line:100 file:asn.c", buf + 53, 55), 0); ExpectIntEQ(BIO_gets(bio, buf, sizeof(buf)), 0); + /* queue and its read cursor were reset, nothing left to pull */ + ExpectIntEQ(ERR_get_error_line(NULL, NULL), 0); + ExpectIntEQ(ERR_get_error(), 0); BIO_free(bio); #endif @@ -22230,13 +22233,43 @@ static int test_WOLFSSL_ERROR_MSG(void) */ static int test_wc_ERR_remove_state(void) { - int res = TEST_SKIPPED; + EXPECT_DECLS; #if defined(OPENSSL_EXTRA) || defined(DEBUG_WOLFSSL_VERBOSE) - wc_ERR_remove_state(); + ExpectIntEQ(wc_ERR_remove_state(), 0); - res = TEST_SUCCESS; +#if !defined(NO_ERROR_QUEUE) && defined(OPENSSL_EXTRA) && \ + defined(DEBUG_WOLFSSL) + /* the read cursor must be reset with the nodes it points into */ + ERR_clear_error(); + ERR_put_error(0, SYS_F_ACCEPT, -173, "ssl.c", 0); + ERR_put_error(0, SYS_F_BIND, -275, "asn.c", 100); + ExpectIntEQ(wc_ERR_remove_state(), 0); + ExpectIntEQ(ERR_get_error_line(NULL, NULL), 0); + ExpectIntEQ(ERR_get_error(), 0); #endif - return res; + +#if defined(WOLFSSL_HAVE_ERROR_QUEUE) && !defined(NO_ERROR_QUEUE) && \ + defined(OPENSSL_EXTRA) && defined(DEBUG_WOLFSSL) && \ + !defined(ERROR_QUEUE_PER_THREAD) + { + /* with the global queue the returned file string must not point into + * the node, which is freed when the error is removed */ + const char* file = NULL; + int line = 0; + + ERR_clear_error(); + ERR_put_error(0, SYS_F_BIND, -275, "asn.c", 100); + ExpectIntNE(ERR_peek_last_error_line(&file, &line), 0); + ExpectIntNE(ERR_get_error(), 0); + ExpectNotNull(file); + if (file != NULL) { + ExpectIntEQ(XSTRCMP(file, "asn.c"), 0); + } + ExpectIntEQ(line, 100); + } +#endif +#endif + return EXPECT_RESULT(); } /* End test_wc_ERR_remove_state */ /* * Testing wc_ERR_print_errors_fp diff --git a/wolfcrypt/src/aes.c b/wolfcrypt/src/aes.c index 8659e65f12f..4ee0fe3e103 100644 --- a/wolfcrypt/src/aes.c +++ b/wolfcrypt/src/aes.c @@ -9650,12 +9650,16 @@ static void GMULT(byte* X, byte* Y, GcmScratch* WC_RESTRICT ws) byte y = Y[i]; for (j = 0; j < 8; j++) { - if (y & 0x80) { - xorbuf(Z, V, WC_AES_BLOCK_SIZE); + byte mask; + int k; + + mask = (byte)(0U - ((y >> 7) & 0x01U)); + for (k = 0; k < WC_AES_BLOCK_SIZE; k++) { + Z[k] ^= (byte)(V[k] & mask); } RIGHTSHIFTX(V); - y = y << 1; + y = (byte)(y << 1); } } XMEMCPY(X, Z, WC_AES_BLOCK_SIZE); @@ -11023,31 +11027,18 @@ static void GMULT(word32* X, word32* Y, GcmScratch* WC_RESTRICT ws) word32 y = Y[i]; for (j = 0; j < 32; j++) { - if (y & 0x80000000) { - Z[0] ^= V[0]; - Z[1] ^= V[1]; - Z[2] ^= V[2]; - Z[3] ^= V[3]; - } + word32 mask = (word32)0U - (y >> 31); + word32 carry = (word32)0U - (V[3] & 0x00000001); - if (V[3] & 0x00000001) { - V[3] >>= 1; - V[3] |= ((V[2] & 0x00000001) ? 0x80000000 : 0); - V[2] >>= 1; - V[2] |= ((V[1] & 0x00000001) ? 0x80000000 : 0); - V[1] >>= 1; - V[1] |= ((V[0] & 0x00000001) ? 0x80000000 : 0); - V[0] >>= 1; - V[0] ^= 0xE1000000; - } else { - V[3] >>= 1; - V[3] |= ((V[2] & 0x00000001) ? 0x80000000 : 0); - V[2] >>= 1; - V[2] |= ((V[1] & 0x00000001) ? 0x80000000 : 0); - V[1] >>= 1; - V[1] |= ((V[0] & 0x00000001) ? 0x80000000 : 0); - V[0] >>= 1; - } + Z[0] ^= V[0] & mask; + Z[1] ^= V[1] & mask; + Z[2] ^= V[2] & mask; + Z[3] ^= V[3] & mask; + + V[3] = (V[3] >> 1) | (V[2] << 31); + V[2] = (V[2] >> 1) | (V[1] << 31); + V[1] = (V[1] >> 1) | (V[0] << 31); + V[0] = (V[0] >> 1) ^ (0xE1000000 & carry); y <<= 1; } } @@ -21620,8 +21611,12 @@ static void AesGcmSivGMult(AesGcmSivPolyval* poly) for (i = 0; i < WC_AES_BLOCK_SIZE; i++) { byte y = poly->h[i]; for (j = 0; j < 8; j++) { - if (y & 0x80) { - xorbuf(Z, V, WC_AES_BLOCK_SIZE); + byte mask; + int k; + + mask = (byte)(0U - ((y >> 7) & 0x01U)); + for (k = 0; k < WC_AES_BLOCK_SIZE; k++) { + Z[k] ^= (byte)(V[k] & mask); } AesGcmSivMulX(V); y = (byte)(y << 1); diff --git a/wolfcrypt/src/des3.c b/wolfcrypt/src/des3.c index 7775a5bdae6..1771d7e2aaf 100644 --- a/wolfcrypt/src/des3.c +++ b/wolfcrypt/src/des3.c @@ -571,6 +571,7 @@ static WC_INLINE void wc_Stm32_CrypDesBlock(const byte* in, byte* out) out += size; } + ForceZero(secKey, secDesc->length3); wc_UnLockMutex(&Mutex_DesSEC) ; } diff --git a/wolfcrypt/src/logging.c b/wolfcrypt/src/logging.c index 77f439727b6..8fae24ceea7 100644 --- a/wolfcrypt/src/logging.c +++ b/wolfcrypt/src/logging.c @@ -1070,6 +1070,16 @@ static struct wc_error_queue* wc_current_node; /* heap info currently used for allocation of entries */ static void* wc_error_heap; +/* Copies of the file and reason strings of the last node peeked or pulled. + * Pointers returned to the caller point here rather than into a node, so a + * remove or clear from another thread after the mutex is released can not + * leave the caller with a pointer to freed memory. The contents are only valid + * until the next peek or pull by the same thread. Only written with the mutex + * held and the last byte is never written, so the strings are always + * terminated. */ +static THREAD_LS_T char wc_errq_file[WOLFSSL_MAX_ERROR_SZ]; +static THREAD_LS_T char wc_errq_reason[WOLFSSL_MAX_ERROR_SZ]; + /* mutex for list operation protection */ static wolfSSL_Mutex wc_error_mutex WOLFSSL_MUTEX_INITIALIZER_CLAUSE(wc_error_mutex); #define ERRQ_MUTEX_INIT() wc_InitMutex(&wc_error_mutex) @@ -1109,6 +1119,21 @@ int wc_LoggingCleanup(void) return 0; } +/* Copy the node strings asked for to the static buffers and return those. + * Must be called with the mutex held. */ +static void exportErrorNodeStrings(const struct wc_error_queue* err, + const char **file, const char **reason) +{ + if (file != NULL) { + XMEMCPY(wc_errq_file, err->file, WOLFSSL_MAX_ERROR_SZ - 1); + *file = wc_errq_file; + } + if (reason != NULL) { + XMEMCPY(wc_errq_reason, err->error, WOLFSSL_MAX_ERROR_SZ - 1); + *reason = wc_errq_reason; + } +} + static int peekErrorNode(int idx, const char **file, const char **reason, int *line) { @@ -1135,12 +1160,7 @@ static int peekErrorNode(int idx, const char **file, const char **reason, return BAD_STATE_E; } - if (file != NULL) { - *file = err->file; - } - if (reason != NULL) { - *reason = err->error; - } + exportErrorNodeStrings(err, file, reason); if (line != NULL) { *line = err->line; } @@ -1153,8 +1173,10 @@ static int peekErrorNode(int idx, const char **file, const char **reason, * idx : if -1 then the most recent node is looked at, * otherwise search through queue for node at the given index starting * from the absolute head wc_errors - * file : pointer to internal file string - * reason : pointer to internal error reason + * file : pointer to a copy of the file string, valid until the next peek or + * pull + * reason : pointer to a copy of the error reason, valid until the next peek + * or pull * line : line number that error happened at * * Returns a negative value in error case, on success returns the nodes error @@ -1185,12 +1207,7 @@ static int pullErrorNode(const char **file, const char **reason, int *line) return BAD_STATE_E; } - if (file != NULL) { - *file = err->file; - } - if (reason != NULL) { - *reason = err->error; - } + exportErrorNodeStrings(err, file, reason); if (line != NULL) { *line = err->line; } @@ -1201,8 +1218,8 @@ static int pullErrorNode(const char **file, const char **reason, int *line) } /* Pulls the current node from error queue and increments current state. - * Note: this does not delete nodes because input arguments are pointing to - * node buffers. + * Note: this does not delete nodes. The file and reason pointers returned are + * to copies that are valid until the next peek or pull. * * file pointer to file that error was in. Can be NULL to return no file. * reason error string giving reason for error. Can be NULL to return no reason. @@ -1431,25 +1448,14 @@ int wc_SetLoggingHeap(void* h) */ int wc_ERR_remove_state(void) { - struct wc_error_queue* current; - struct wc_error_queue* next; - if (ERRQ_LOCK() != 0) { WOLFSSL_MSG("Lock debug mutex failed"); return BAD_MUTEX_E; } - /* free all nodes from error queue */ - current = (struct wc_error_queue*)wc_errors; - while (current != NULL) { - next = current->next; - XFREE(current, current->heap, DYNAMIC_TYPE_LOG); - current = next; - } - - wc_errors_count = 0; - wc_errors = NULL; - wc_last_node = NULL; + /* free all nodes from error queue and reset all list pointers, + * including the wc_current_node cursor */ + clearErrorNodes(); ERRQ_UNLOCK(); @@ -1584,6 +1590,7 @@ void wc_ERR_print_errors_cb(int (*cb)(const char *str, size_t len, void *u), wc_errors_count = 0; wc_errors = NULL; wc_last_node = NULL; + wc_current_node = NULL; ERRQ_UNLOCK(); }