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 */ } /******************************************************************************/