diff --git a/include/wolfprovider/wp_logging.h b/include/wolfprovider/wp_logging.h
index d9b0c818..c94f448e 100644
--- a/include/wolfprovider/wp_logging.h
+++ b/include/wolfprovider/wp_logging.h
@@ -110,6 +110,9 @@
* #define WOLFPROV_LOG_LEVEL_FILTER (WP_LOG_LEVEL_ALL)
* #define WOLFPROV_LOG_COMPONENTS_FILTER (WP_LOG_ECC | WP_LOG_RSA | WP_LOG_HKDF)
* // Shows level (ERROR + ENTER/LEAVE + INFO + VERBOSE + DEBUG + TRACE) for ECC, RSA, and HKDF only
+ *
+ * When modifying the enum values, ensure the corresponding strings in the
+ * wp_logging.c file are updated to match.
*/
enum wolfProv_LogType {
WP_LOG_ERROR = 0x0001, /* logs errors */
@@ -236,6 +239,8 @@ void wolfProv_Debugging_OFF(void);
int wolfProv_SetLogLevel(int levelMask);
/* Set which components are logged, bitmask of wolfProv_LogComponents */
int wolfProv_SetLogComponents(int componentMask);
+/* Initialize logging module */
+int wolfProv_LogInit(void);
#ifdef WOLFPROV_DEBUG
diff --git a/scripts/env-setup b/scripts/env-setup
index 15bae7c7..fff5c179 100755
--- a/scripts/env-setup
+++ b/scripts/env-setup
@@ -47,7 +47,7 @@ elif [ -d $REPO_ROOT/openssl-install/lib64 ]; then
export OPENSSL_LIB_PATH=$REPO_ROOT/openssl-install/lib64
else
echo "Error: Could not find OpenSSL lib directory in $REPO_ROOT/openssl-install"
- exit 1
+ return 1
fi
WOLFSSL_LIB_PATH="$REPO_ROOT/wolfssl-install/lib"
diff --git a/src/wp_logging.c b/src/wp_logging.c
index 16d21190..547c928a 100644
--- a/src/wp_logging.c
+++ b/src/wp_logging.c
@@ -49,6 +49,20 @@ static int providerLogLevel = WP_LOG_LEVEL_ALL;
* in wolfProv_LogComponents. Default components include all. */
static int providerLogComponents = WP_LOG_COMPONENTS_ALL;
+/* Callback functions to parse environment variables WOLFPROV_LOG_LEVEL and WOLFPROV_LOG_COMPONENTS */
+static void wolfProv_LogLevelToMask(const char* level, size_t len, void* ctx);
+static void wolfProv_LogComponentToMask(const char* level, size_t len, void* ctx);
+
+/* Callback receives a pointer to the token (valid only during this call),
+ * the token length (excluding the trailing '\0'), and an opaque context.
+ */
+typedef void (*token_cb)(const char *token, size_t len, void *ctx);
+/* Parse environment variables WOLFPROV_LOG_LEVEL and WOLFPROV_LOG_COMPONENTS
+ * in the form (WP_LOG_ERROR | WP_LOG_LEAVE).
+ * See wp_logging.h for valid values */
+static int wolfProv_TokenParse(const char *input, const char *delims,
+ token_cb cb, void* ctx);
+
#endif /* WOLFPROV_DEBUG */
/**
@@ -98,6 +112,46 @@ void wolfProv_Debugging_OFF(void)
#endif
}
+int wolfProv_LogInit(void)
+{
+#ifdef WOLFPROV_DEBUG
+#if defined(XGETENV) && !defined(NO_GETENV)
+ uint32_t level = 0;
+ uint32_t components = 0;
+ char* logLevelStr = XGETENV("WOLFPROV_LOG_LEVEL");
+ char* logComponentsStr = XGETENV("WOLFPROV_LOG_COMPONENTS");
+
+ if (logLevelStr != NULL) {
+ if (wolfProv_TokenParse(logLevelStr, "()| \t", wolfProv_LogLevelToMask,
+ &level) == 0) {
+ WOLFPROV_MSG(WP_LOG_PROVIDER,
+ "Setting WOLFPROV_LOG_LEVEL to 0x%X", level);
+ providerLogLevel = level;
+ }
+ else {
+ WOLFPROV_MSG(WP_LOG_PROVIDER,
+ "WOLFPROV_LOG_LEVEL environment variable too long or missing, "
+ "ignoring it");
+ }
+ }
+ if (logComponentsStr != NULL) {
+ if (wolfProv_TokenParse(logComponentsStr, "()| \t",
+ wolfProv_LogComponentToMask, &components) == 0) {
+ WOLFPROV_MSG(WP_LOG_PROVIDER,
+ "Setting WOLFPROV_LOG_COMPONENTS to 0x%X", components);
+ providerLogComponents = components;
+ }
+ else {
+ WOLFPROV_MSG(WP_LOG_PROVIDER,
+ "WOLFPROV_LOG_COMPONENTS environment variable too long or "
+ "missing, ignoring it");
+ }
+ }
+#endif
+#endif
+ return 0;
+}
+
/**
* Set wolfProv logging level.
* Default logging level for wolfProv is WP_LOG_LEVEL_DEFAULT.
@@ -182,7 +236,8 @@ static void wolfprovider_log(const int logLevel, const int component,
if (logFileHandle == NULL) {
logFileHandle = XFOPEN(WOLFPROV_LOG_FILE, "a");
if (logFileHandle) {
- XFPRINTF(stderr, "wolfProvider: Using log file %s\n", WOLFPROV_LOG_FILE);
+ XFPRINTF(stderr, "wolfProvider: Using log file %s\n",
+ WOLFPROV_LOG_FILE);
fflush(stderr);
}
else {
@@ -535,5 +590,142 @@ void WOLFPROV_BUFFER(int component, const unsigned char* buffer,
}
}
+static void wolfProv_LogLevelToMask(const char* level, size_t len, void* ctx) {
+ /* Map strings to enum values.
+ * Ensure this table is kept in sync with the enum in wp_logging.h */
+ static const struct {
+ const char* name;
+ size_t len;
+ uint32_t mask;
+ } log_levels[] = {
+ { "WP_LOG_ERROR", XSTRLEN("WP_LOG_ERROR"), WP_LOG_ERROR },
+ { "WP_LOG_ENTER", XSTRLEN("WP_LOG_ENTER"), WP_LOG_ENTER },
+ { "WP_LOG_LEAVE", XSTRLEN("WP_LOG_LEAVE"), WP_LOG_LEAVE },
+ { "WP_LOG_INFO", XSTRLEN("WP_LOG_INFO"), WP_LOG_INFO },
+ { "WP_LOG_VERBOSE", XSTRLEN("WP_LOG_VERBOSE"),WP_LOG_VERBOSE },
+ { "WP_LOG_DEBUG", XSTRLEN("WP_LOG_DEBUG"), WP_LOG_DEBUG },
+ { "WP_LOG_TRACE", XSTRLEN("WP_LOG_TRACE"), WP_LOG_TRACE },
+ { "WP_LOG_LEVEL_DEFAULT",
+ XSTRLEN("WP_LOG_LEVEL_DEFAULT"),
+ WP_LOG_LEVEL_DEFAULT },
+ { "WP_LOG_LEVEL_ALL",
+ XSTRLEN("WP_LOG_LEVEL_ALL"),
+ WP_LOG_LEVEL_ALL },
+ };
+ static const size_t num_levels = sizeof(log_levels) / sizeof(log_levels[0]);
+ uint32_t *mask = (uint32_t *)ctx;
+
+ for (size_t i = 0; i < num_levels; ++i) {
+ if (log_levels[i].len == len &&
+ XSTRNCMP(level, log_levels[i].name, len) == 0) {
+ *mask |= log_levels[i].mask;
+ break;
+ }
+ }
+}
+
+static void wolfProv_LogComponentToMask(const char* level, size_t len, void* ctx) {
+ /* Map strings to enum values.
+ * Ensure this table is kept in sync with the enum in wp_logging.h */
+ static const struct {
+ const char* name;
+ size_t len;
+ uint32_t mask;
+ } log_components[] = {
+ { "WP_LOG_RNG", XSTRLEN("WP_LOG_RNG"), WP_LOG_RNG },
+ { "WP_LOG_DIGEST", XSTRLEN("WP_LOG_DIGEST"), WP_LOG_DIGEST },
+ { "WP_LOG_MAC", XSTRLEN("WP_LOG_MAC"), WP_LOG_MAC },
+ { "WP_LOG_CIPHER", XSTRLEN("WP_LOG_CIPHER"), WP_LOG_CIPHER },
+ { "WP_LOG_PK", XSTRLEN("WP_LOG_PK"), WP_LOG_PK },
+ { "WP_LOG_KE", XSTRLEN("WP_LOG_KE"), WP_LOG_KE },
+ { "WP_LOG_KDF", XSTRLEN("WP_LOG_KDF"), WP_LOG_KDF },
+ { "WP_LOG_PROVIDER", XSTRLEN("WP_LOG_PROVIDER"), WP_LOG_PROVIDER },
+ { "WP_LOG_RSA", XSTRLEN("WP_LOG_RSA"), WP_LOG_RSA },
+ { "WP_LOG_ECC", XSTRLEN("WP_LOG_ECC"), WP_LOG_ECC },
+ { "WP_LOG_DH", XSTRLEN("WP_LOG_DH"), WP_LOG_DH },
+ { "WP_LOG_AES", XSTRLEN("WP_LOG_AES"), WP_LOG_AES },
+ { "WP_LOG_DES", XSTRLEN("WP_LOG_DES"), WP_LOG_DES },
+ { "WP_LOG_SHA", XSTRLEN("WP_LOG_SHA"), WP_LOG_SHA },
+ { "WP_LOG_MD5", XSTRLEN("WP_LOG_MD5"), WP_LOG_MD5 },
+ { "WP_LOG_HMAC", XSTRLEN("WP_LOG_HMAC"), WP_LOG_HMAC },
+ { "WP_LOG_CMAC", XSTRLEN("WP_LOG_CMAC"), WP_LOG_CMAC },
+ { "WP_LOG_HKDF", XSTRLEN("WP_LOG_HKDF"), WP_LOG_HKDF },
+ { "WP_LOG_PBKDF2", XSTRLEN("WP_LOG_PBKDF2"), WP_LOG_PBKDF2 },
+ { "WP_LOG_KRB5KDF", XSTRLEN("WP_LOG_KRB5KDF"), WP_LOG_KRB5KDF },
+ { "WP_LOG_DRBG", XSTRLEN("WP_LOG_DRBG"), WP_LOG_DRBG },
+ { "WP_LOG_ECDSA", XSTRLEN("WP_LOG_ECDSA"), WP_LOG_ECDSA },
+ { "WP_LOG_ECDH", XSTRLEN("WP_LOG_ECDH"), WP_LOG_ECDH },
+ { "WP_LOG_ED25519", XSTRLEN("WP_LOG_ED25519"), WP_LOG_ED25519 },
+ { "WP_LOG_ED448", XSTRLEN("WP_LOG_ED448"), WP_LOG_ED448 },
+ { "WP_LOG_X25519", XSTRLEN("WP_LOG_X25519"), WP_LOG_X25519 },
+ { "WP_LOG_X448", XSTRLEN("WP_LOG_X448"), WP_LOG_X448 },
+ { "WP_LOG_QUERY", XSTRLEN("WP_LOG_QUERY"), WP_LOG_QUERY },
+ { "WP_LOG_TLS1_PRF", XSTRLEN("WP_LOG_TLS1_PRF"), WP_LOG_TLS1_PRF },
+ { "WP_LOG_COMPONENTS_ALL",
+ XSTRLEN("WP_LOG_COMPONENTS_ALL"),
+ WP_LOG_COMPONENTS_ALL },
+ { "WP_LOG_COMPONENTS_DEFAULT",
+ XSTRLEN("WP_LOG_COMPONENTS_DEFAULT"),
+ WP_LOG_COMPONENTS_DEFAULT },
+ };
+ static const size_t num_components =
+ sizeof(log_components) / sizeof(log_components[0]);
+ uint32_t *mask = (uint32_t *)ctx;
+
+ for (size_t i = 0; i < num_components; ++i) {
+ if (log_components[i].len == len &&
+ XSTRNCMP(level, log_components[i].name, len) == 0) {
+ *mask |= log_components[i].mask;
+ break;
+ }
+ }
+}
+
+/* Returns number of tokens passed to cb,
+ * 0 if input is NULL or empty,
+ * -1 on allocation failure.
+ */
+static int wolfProv_TokenParse(const char *input,
+ const char *delims, /* e.g. "()| \t" */
+ token_cb cb,
+ void *ctx) /* opaque context passed to cb */
+{
+ if (!cb || !delims) return -1;
+ if (!input || !*input) return 0;
+
+ char token[256];
+ size_t n = XSTRLEN(input);
+
+ if (n < sizeof(token)) {
+ /* Copy the input string to a writable buffer, including the trailing '\0' */
+ XSTRNCPY(token, input, n + 1);
+ }
+ else {
+ return -1;
+ }
+
+ /* Overwrite delimiters with '\0' using a simple nested loop. */
+ for (size_t i = 0; i < n; ++i) {
+ for (const char *d = delims; *d; ++d) {
+ if (token[i] == *d) {
+ token[i] = '\0';
+ break;
+ }
+ }
+ }
+
+ /* Walk tokens: skip runs of NULs, emit non-empty spans. */
+ for (size_t i = 0; i <= n; i++) {
+ if (token[i] == '\0') {
+ continue; /* skip empties */
+ }
+ size_t len = strlen(&token[i]);
+ cb(&token[i], len, ctx);
+ i += len; /* hop past this token */
+ }
+
+ return 0;
+}
+
#endif /* WOLFPROV_DEBUG */
diff --git a/src/wp_wolfprov.c b/src/wp_wolfprov.c
index ac8afcd6..e3fefa32 100644
--- a/src/wp_wolfprov.c
+++ b/src/wp_wolfprov.c
@@ -1241,6 +1241,8 @@ int wolfssl_provider_init(const OSSL_CORE_HANDLE* handle,
{
int ok = 1;
+ wolfProv_LogInit();
+
WOLFPROV_ENTER(WP_LOG_PROVIDER, "wolfssl_provider_init");
#ifdef WOLFPROV_DEBUG
diff --git a/test/test_logging.c b/test/test_logging.c
index 131c7715..a1fa0858 100644
--- a/test/test_logging.c
+++ b/test/test_logging.c
@@ -18,14 +18,313 @@
* along with wolfProvider. If not, see .
*/
+#include
+#include
#include "unit.h"
/******************************************************************************/
+#ifdef WOLFPROV_DEBUG
+typedef struct TestLogState {
+ int called;
+ int lastLevel;
+ int lastComponent;
+ char lastMsg[256];
+} TestLogState;
+
+static TestLogState gLog;
+
+static void test_log_cb(const int level, const int component,
+ const char *const msg)
+{
+ gLog.called++;
+ gLog.lastLevel = level;
+ gLog.lastComponent = component;
+ XSTRNCPY(gLog.lastMsg, msg, sizeof(gLog.lastMsg) - 1);
+ gLog.lastMsg[sizeof(gLog.lastMsg) - 1] = '\0';
+}
+
+static void reset_env_and_init(const char* levelStr, const char* compStr)
+{
+ (void)setenv("WOLFPROV_LOG_LEVEL", levelStr, 1);
+ (void)setenv("WOLFPROV_LOG_COMPONENTS", compStr, 1);
+ /* Clear runtime masks so env takes effect even if parser ignores */
+ (void)wolfProv_SetLogLevel(0);
+ (void)wolfProv_SetLogComponents(0);
+ (void)wolfProv_LogInit();
+ (void)wolfProv_Debugging_ON();
+ XMEMSET(&gLog, 0, sizeof(gLog));
+}
+
+#define CHECK_LOGGED(prevCount, lvlConst, compConst, nameStr) do { \
+ /* Only assert if compile-time filters allow this level+component */ \
+ if (((WOLFPROV_LOG_COMPONENTS_FILTER & (compConst)) != 0) && \
+ ((WOLFPROV_LOG_LEVEL_FILTER & (lvlConst)) != 0)) { \
+ if (gLog.called <= (prevCount)) {\
+ PRINT_ERR_MSG("Too few logs captured for %s", (nameStr)); \
+ rc = -1; \
+ } \
+ else if (gLog.lastLevel != (lvlConst)) { \
+ PRINT_ERR_MSG("Expected %s log to be captured at level %d, got %d", (nameStr), (lvlConst), (gLog.lastLevel)); \
+ rc = -1; \
+ } \
+ else if (gLog.lastComponent != (compConst)) { \
+ PRINT_ERR_MSG("Expected %s log to be captured at component %d, got %d", (nameStr), (compConst), (gLog.lastComponent)); \
+ rc = -1; \
+ } \
+ } \
+} while (0)
+
+#define CHECK_NOT_LOGGED(prevCount, lvlConst, compConst, nameStr) do { \
+ /* Only assert if compile-time filters allow this level+component */ \
+ if (((WOLFPROV_LOG_COMPONENTS_FILTER & (compConst)) != 0) && \
+ ((WOLFPROV_LOG_LEVEL_FILTER & (lvlConst)) != 0)) { \
+ if (gLog.called != (prevCount)) { \
+ PRINT_ERR_MSG("Expected %s log to be filtered out", (nameStr)); \
+ rc = -1; \
+ } \
+ } \
+} while (0)
+#endif
+
int test_logging(void *data)
{
(void)data;
+
+#ifndef WOLFPROV_DEBUG
+ /* Logging not compiled in; treat as skipped */
+ PRINT_MSG("WOLFPROV_DEBUG not enabled; skipping logging test");
return 0;
+#else
+ int ret;
+ int rc = 0;
+
+ XMEMSET(&gLog, 0, sizeof(gLog));
+
+ ret = wolfProv_SetLoggingCb(test_log_cb);
+ if (ret != 0) {
+ PRINT_ERR_MSG("wolfProv_SetLoggingCb failed: %d", ret);
+ return -1;
+ }
+ /* Scenario A: ALL levels, provider component */
+ reset_env_and_init("WP_LOG_LEVEL_ALL", "WP_LOG_PROVIDER");
+ {
+ int prev;
+ prev = gLog.called; WOLFPROV_MSG(WP_LOG_PROVIDER, "info A");
+ CHECK_LOGGED(prev, WP_LOG_INFO, WP_LOG_PROVIDER, "INFO (A)");
+
+ prev = gLog.called; WOLFPROV_ERROR(WP_LOG_PROVIDER, -100);
+ CHECK_LOGGED(prev, WP_LOG_ERROR, WP_LOG_PROVIDER, "ERROR (A)");
+
+ prev = gLog.called; WOLFPROV_ENTER(WP_LOG_PROVIDER, "funcA");
+ CHECK_LOGGED(prev, WP_LOG_ENTER, WP_LOG_PROVIDER, "ENTER (A)");
+
+ prev = gLog.called; WOLFPROV_LEAVE(WP_LOG_PROVIDER, "funcA", 0);
+ CHECK_LOGGED(prev, WP_LOG_LEAVE, WP_LOG_PROVIDER, "LEAVE (A)");
+
+ prev = gLog.called; WOLFPROV_MSG_VERBOSE(WP_LOG_PROVIDER, "verbose A");
+ CHECK_LOGGED(prev, WP_LOG_VERBOSE, WP_LOG_PROVIDER, "VERBOSE (A)");
+
+ prev = gLog.called; WOLFPROV_MSG_DEBUG(WP_LOG_PROVIDER, "debug A");
+ CHECK_LOGGED(prev, WP_LOG_DEBUG, WP_LOG_PROVIDER, "DEBUG (A)");
+
+ prev = gLog.called; WOLFPROV_MSG_TRACE(WP_LOG_PROVIDER, "trace A");
+ CHECK_LOGGED(prev, WP_LOG_TRACE, WP_LOG_PROVIDER, "TRACE (A)");
+
+ {
+ static const unsigned char buf[] = { 0x01, 0x02 };
+ prev = gLog.called; WOLFPROV_BUFFER(WP_LOG_PROVIDER, buf, 2);
+ CHECK_LOGGED(prev, WP_LOG_VERBOSE, WP_LOG_PROVIDER, "BUFFER/VERBOSE (A)");
+ }
+ }
+
+ /* Scenario B: (ERROR | INFO), provider component */
+ reset_env_and_init("(WP_LOG_ERROR | WP_LOG_INFO)", "WP_LOG_PROVIDER");
+ {
+ int prev;
+ prev = gLog.called; WOLFPROV_MSG(WP_LOG_PROVIDER, "info B");
+ CHECK_LOGGED(prev, WP_LOG_INFO, WP_LOG_PROVIDER, "INFO (B)");
+
+ prev = gLog.called; WOLFPROV_ERROR(WP_LOG_PROVIDER, -200);
+ CHECK_LOGGED(prev, WP_LOG_ERROR, WP_LOG_PROVIDER, "ERROR (B)");
+
+ prev = gLog.called; WOLFPROV_ENTER(WP_LOG_PROVIDER, "funcB");
+ CHECK_NOT_LOGGED(prev, WP_LOG_ENTER, WP_LOG_PROVIDER, "ENTER (B)");
+
+ prev = gLog.called; WOLFPROV_LEAVE(WP_LOG_PROVIDER, "funcB", 0);
+ CHECK_NOT_LOGGED(prev, WP_LOG_LEAVE, WP_LOG_PROVIDER, "LEAVE (B)");
+
+ prev = gLog.called; WOLFPROV_MSG_VERBOSE(WP_LOG_PROVIDER, "verbose B");
+ CHECK_NOT_LOGGED(prev, WP_LOG_VERBOSE, WP_LOG_PROVIDER, "VERBOSE (B)");
+
+ prev = gLog.called; WOLFPROV_MSG_DEBUG(WP_LOG_PROVIDER, "debug B");
+ CHECK_NOT_LOGGED(prev, WP_LOG_DEBUG, WP_LOG_PROVIDER, "DEBUG (B)");
+
+ prev = gLog.called; WOLFPROV_MSG_TRACE(WP_LOG_PROVIDER, "trace B");
+ CHECK_NOT_LOGGED(prev, WP_LOG_TRACE, WP_LOG_PROVIDER, "TRACE (B)");
+ }
+
+ /* Scenario C: ERROR only */
+ reset_env_and_init("WP_LOG_ERROR", "WP_LOG_PROVIDER");
+ {
+ int prev;
+ prev = gLog.called; WOLFPROV_ERROR(WP_LOG_PROVIDER, -300);
+ CHECK_LOGGED(prev, WP_LOG_ERROR, WP_LOG_PROVIDER, "ERROR (C)");
+
+ prev = gLog.called; WOLFPROV_MSG(WP_LOG_PROVIDER, "info C");
+ CHECK_NOT_LOGGED(prev, WP_LOG_INFO, WP_LOG_PROVIDER, "INFO (C)");
+ }
+
+ /* Scenario D: VERBOSE only */
+ reset_env_and_init("WP_LOG_VERBOSE", "WP_LOG_PROVIDER");
+ {
+ int prev;
+ prev = gLog.called; WOLFPROV_MSG_VERBOSE(WP_LOG_PROVIDER, "verbose D");
+ CHECK_LOGGED(prev, WP_LOG_VERBOSE, WP_LOG_PROVIDER, "VERBOSE (D)");
+ /* BUFFER emits VERBOSE */
+ {
+ static const unsigned char buf[] = { 0xAA, 0xBB };
+ prev = gLog.called; WOLFPROV_BUFFER(WP_LOG_PROVIDER, buf, 2);
+ CHECK_LOGGED(prev, WP_LOG_VERBOSE, WP_LOG_PROVIDER, "BUFFER/VERBOSE (D)");
+ }
+ prev = gLog.called; WOLFPROV_MSG(WP_LOG_PROVIDER, "info D");
+ CHECK_NOT_LOGGED(prev, WP_LOG_INFO, WP_LOG_PROVIDER, "INFO (D)");
+ }
+
+ /* Scenario E: ALL levels, RSA component only -> provider logs blocked */
+ reset_env_and_init("WP_LOG_LEVEL_ALL", "WP_LOG_RSA");
+ {
+ int prev;
+ prev = gLog.called; WOLFPROV_MSG(WP_LOG_PROVIDER, "info E");
+ CHECK_NOT_LOGGED(prev, WP_LOG_INFO, WP_LOG_PROVIDER, "INFO (E) provider filtered");
+ prev = gLog.called; WOLFPROV_ERROR(WP_LOG_PROVIDER, -400);
+ CHECK_NOT_LOGGED(prev, WP_LOG_ERROR, WP_LOG_PROVIDER, "ERROR (E) provider filtered");
+
+ /* Now log under RSA and expect pass */
+ prev = gLog.called; WOLFPROV_MSG(WP_LOG_RSA, "info E RSA");
+ CHECK_LOGGED(prev, WP_LOG_INFO, WP_LOG_RSA, "INFO (E) RSA");
+ }
+
+ /* Scenario H: AES and SHA components with ALL levels */
+ reset_env_and_init("WP_LOG_LEVEL_ALL", "(WP_LOG_AES | WP_LOG_SHA)");
+ {
+ int prev;
+ prev = gLog.called; WOLFPROV_MSG(WP_LOG_AES, "info H AES");
+ CHECK_LOGGED(prev, WP_LOG_INFO, WP_LOG_AES, "INFO (H) AES");
+ prev = gLog.called; WOLFPROV_MSG(WP_LOG_SHA, "info H SHA");
+ CHECK_LOGGED(prev, WP_LOG_INFO, WP_LOG_SHA, "INFO (H) SHA");
+ /* Provider component should be filtered */
+ prev = gLog.called; WOLFPROV_MSG(WP_LOG_PROVIDER, "info H provider");
+ CHECK_NOT_LOGGED(prev, WP_LOG_INFO, WP_LOG_PROVIDER, "INFO (H) provider filtered");
+ }
+
+ /* Scenario I: RSA component - exercise all log types */
+ reset_env_and_init("WP_LOG_LEVEL_ALL", "WP_LOG_RSA");
+ {
+ int prev;
+ prev = gLog.called; WOLFPROV_MSG(WP_LOG_RSA, "info I RSA");
+ CHECK_LOGGED(prev, WP_LOG_INFO, WP_LOG_RSA, "INFO (I) RSA");
+ prev = gLog.called; WOLFPROV_ERROR(WP_LOG_RSA, -600);
+ CHECK_LOGGED(prev, WP_LOG_ERROR, WP_LOG_RSA, "ERROR (I) RSA");
+ prev = gLog.called; WOLFPROV_ENTER(WP_LOG_RSA, "funcI");
+ CHECK_LOGGED(prev, WP_LOG_ENTER, WP_LOG_RSA, "ENTER (I) RSA");
+ prev = gLog.called; WOLFPROV_LEAVE(WP_LOG_RSA, "funcI", 0);
+ CHECK_LOGGED(prev, WP_LOG_LEAVE, WP_LOG_RSA, "LEAVE (I) RSA");
+ prev = gLog.called; WOLFPROV_MSG_VERBOSE(WP_LOG_RSA, "verbose I RSA");
+ CHECK_LOGGED(prev, WP_LOG_VERBOSE, WP_LOG_RSA, "VERBOSE (I) RSA");
+ prev = gLog.called; WOLFPROV_MSG_DEBUG(WP_LOG_RSA, "debug I RSA");
+ CHECK_LOGGED(prev, WP_LOG_DEBUG, WP_LOG_RSA, "DEBUG (I) RSA");
+ prev = gLog.called; WOLFPROV_MSG_TRACE(WP_LOG_RSA, "trace I RSA");
+ CHECK_LOGGED(prev, WP_LOG_TRACE, WP_LOG_RSA, "TRACE (I) RSA");
+ {
+ static const unsigned char buf[] = { 0x10, 0x20 };
+ prev = gLog.called; WOLFPROV_BUFFER(WP_LOG_RSA, buf, 2);
+ CHECK_LOGGED(prev, WP_LOG_VERBOSE, WP_LOG_RSA, "BUFFER/VERBOSE (I) RSA");
+ }
+ }
+
+ /* Scenario J: AES component - exercise all log types */
+ reset_env_and_init("WP_LOG_LEVEL_ALL", "WP_LOG_AES");
+ {
+ int prev;
+ prev = gLog.called; WOLFPROV_MSG(WP_LOG_AES, "info J AES");
+ CHECK_LOGGED(prev, WP_LOG_INFO, WP_LOG_AES, "INFO (J) AES");
+ prev = gLog.called; WOLFPROV_ERROR(WP_LOG_AES, -700);
+ CHECK_LOGGED(prev, WP_LOG_ERROR, WP_LOG_AES, "ERROR (J) AES");
+ prev = gLog.called; WOLFPROV_ENTER(WP_LOG_AES, "funcJ");
+ CHECK_LOGGED(prev, WP_LOG_ENTER, WP_LOG_AES, "ENTER (J) AES");
+ prev = gLog.called; WOLFPROV_LEAVE(WP_LOG_AES, "funcJ", 0);
+ CHECK_LOGGED(prev, WP_LOG_LEAVE, WP_LOG_AES, "LEAVE (J) AES");
+ prev = gLog.called; WOLFPROV_MSG_VERBOSE(WP_LOG_AES, "verbose J AES");
+ CHECK_LOGGED(prev, WP_LOG_VERBOSE, WP_LOG_AES, "VERBOSE (J) AES");
+ prev = gLog.called; WOLFPROV_MSG_DEBUG(WP_LOG_AES, "debug J AES");
+ CHECK_LOGGED(prev, WP_LOG_DEBUG, WP_LOG_AES, "DEBUG (J) AES");
+ prev = gLog.called; WOLFPROV_MSG_TRACE(WP_LOG_AES, "trace J AES");
+ CHECK_LOGGED(prev, WP_LOG_TRACE, WP_LOG_AES, "TRACE (J) AES");
+ {
+ static const unsigned char buf[] = { 0xAB, 0xCD };
+ prev = gLog.called; WOLFPROV_BUFFER(WP_LOG_AES, buf, 2);
+ CHECK_LOGGED(prev, WP_LOG_VERBOSE, WP_LOG_AES, "BUFFER/VERBOSE (J) AES");
+ }
+ }
+
+ /* Scenario K: SHA component - exercise all log types */
+ reset_env_and_init("WP_LOG_LEVEL_ALL", "WP_LOG_SHA");
+ {
+ int prev;
+ prev = gLog.called; WOLFPROV_MSG(WP_LOG_SHA, "info K SHA");
+ CHECK_LOGGED(prev, WP_LOG_INFO, WP_LOG_SHA, "INFO (K) SHA");
+ prev = gLog.called; WOLFPROV_ERROR(WP_LOG_SHA, -800);
+ CHECK_LOGGED(prev, WP_LOG_ERROR, WP_LOG_SHA, "ERROR (K) SHA");
+ prev = gLog.called; WOLFPROV_ENTER(WP_LOG_SHA, "funcK");
+ CHECK_LOGGED(prev, WP_LOG_ENTER, WP_LOG_SHA, "ENTER (K) SHA");
+ prev = gLog.called; WOLFPROV_LEAVE(WP_LOG_SHA, "funcK", 0);
+ CHECK_LOGGED(prev, WP_LOG_LEAVE, WP_LOG_SHA, "LEAVE (K) SHA");
+ prev = gLog.called; WOLFPROV_MSG_VERBOSE(WP_LOG_SHA, "verbose K SHA");
+ CHECK_LOGGED(prev, WP_LOG_VERBOSE, WP_LOG_SHA, "VERBOSE (K) SHA");
+ prev = gLog.called; WOLFPROV_MSG_DEBUG(WP_LOG_SHA, "debug K SHA");
+ CHECK_LOGGED(prev, WP_LOG_DEBUG, WP_LOG_SHA, "DEBUG (K) SHA");
+ prev = gLog.called; WOLFPROV_MSG_TRACE(WP_LOG_SHA, "trace K SHA");
+ CHECK_LOGGED(prev, WP_LOG_TRACE, WP_LOG_SHA, "TRACE (K) SHA");
+ {
+ static const unsigned char buf[] = { 0xDE, 0xAD };
+ prev = gLog.called; WOLFPROV_BUFFER(WP_LOG_SHA, buf, 2);
+ CHECK_LOGGED(prev, WP_LOG_VERBOSE, WP_LOG_SHA, "BUFFER/VERBOSE (K) SHA");
+ }
+ }
+
+ /* Scenario F: DEFAULT level, ALL components (ERROR | LEAVE | INFO) */
+ reset_env_and_init("WP_LOG_LEVEL_DEFAULT", "WP_LOG_COMPONENTS_ALL");
+ {
+ int prev;
+ prev = gLog.called; WOLFPROV_MSG(WP_LOG_PROVIDER, "info F");
+ CHECK_LOGGED(prev, WP_LOG_INFO, WP_LOG_PROVIDER, "INFO (F)");
+
+ prev = gLog.called; WOLFPROV_LEAVE(WP_LOG_PROVIDER, "funcF", 0);
+ CHECK_LOGGED(prev, WP_LOG_LEAVE, WP_LOG_PROVIDER, "LEAVE (F)");
+
+ prev = gLog.called; WOLFPROV_ENTER(WP_LOG_PROVIDER, "funcF");
+ CHECK_NOT_LOGGED(prev, WP_LOG_ENTER, WP_LOG_PROVIDER, "ENTER (F)");
+
+ prev = gLog.called; WOLFPROV_MSG_VERBOSE(WP_LOG_PROVIDER, "verbose F");
+ CHECK_NOT_LOGGED(prev, WP_LOG_VERBOSE, WP_LOG_PROVIDER, "VERBOSE (F)");
+ }
+
+ /* Scenario G: Mixed valid + invalid tokens -> INFO only */
+ reset_env_and_init("(WP_LOG_INFO | WP_LOG_FAKE)", "WP_LOG_PROVIDER");
+ {
+ int prev;
+ prev = gLog.called; WOLFPROV_MSG(WP_LOG_PROVIDER, "info G");
+ CHECK_LOGGED(prev, WP_LOG_INFO, WP_LOG_PROVIDER, "INFO (G)");
+ prev = gLog.called; WOLFPROV_ERROR(WP_LOG_PROVIDER, -500);
+ CHECK_NOT_LOGGED(prev, WP_LOG_ERROR, WP_LOG_PROVIDER, "ERROR (G)");
+ }
+
+ /* Cleanup */
+ (void)wolfProv_SetLoggingCb(NULL);
+
+ return rc;
+#endif /* WOLFPROV_DEBUG */
}
/******************************************************************************/