diff --git a/include/se050_mem_protect.h b/include/se050_mem_protect.h new file mode 100644 index 0000000..3d53fa3 --- /dev/null +++ b/include/se050_mem_protect.h @@ -0,0 +1,92 @@ +/** + * @file se050_mem_protect.h + * @brief Memory Protection Utilities + * + * Linux-specific memory protection functions to prevent: + * - Swapping sensitive data to disk (mlock) + * - Core dump leakage (MADV_DONTDUMP) + * - Child process leakage after fork() (MADV_WIPEONFORK) + * + * License: MIT + */ + +#ifndef SE050_MEM_PROTECT_H +#define SE050_MEM_PROTECT_H + +#include +#include "se050_wireguard.h" + +#ifdef __linux__ +#include +#include +#include +#include +#endif + +/** + * @brief Protect sensitive memory from being swapped or dumped + * + * Applies multiple security measures: + * - mlock(): Prevent swapping to disk + * - MADV_DONTDUMP: Exclude from core dumps + * - MADV_WIPEONFORK: Clear in child processes after fork() + * + * @param ptr Pointer to memory region to protect + * @param size Size of memory region in bytes + * @return SE050_OK on success, SE050_ERR_FAIL on failure + * + * @note On Linux, mlock may fail due to permissions. If it fails, + * a warning is printed but the function continues (non-fatal). + * @note On non-Linux platforms, this function is a no-op. + */ +static inline se050_status_t protect_sensitive_memory(void *ptr, size_t size) +{ +#ifdef __linux__ + /* 1. Prevent swapping to disk (optional - may fail due to permissions) */ + if (mlock(ptr, size) != 0) { + /* mlock may fail due to ulimit restrictions. Log warning but continue. */ + fprintf(stderr, "Warning: mlock failed (%s). Memory may be swapped.\n", strerror(errno)); + /* Continue without mlock - better than failing entirely */ + } + + /* 2. Exclude from core dumps */ + if (madvise(ptr, size, MADV_DONTDUMP) != 0) { + perror("madvise MADV_DONTDUMP failed"); + /* Non-fatal, continue */ + } + + /* 3. Clear in child processes after fork() */ + if (madvise(ptr, size, MADV_WIPEONFORK) != 0) { + perror("madvise MADV_WIPEONFORK failed"); + /* Non-fatal, continue */ + } + + return SE050_OK; +#else + /* Non-Linux platforms: no special protection */ + (void)ptr; + (void)size; + return SE050_OK; +#endif +} + +/** + * @brief Release memory protection before freeing + * + * Must be called before freeing protected memory. + * + * @param ptr Pointer to memory region to release + * @param size Size of memory region in bytes + */ +static inline void release_memory_protection(void *ptr, size_t size) +{ +#ifdef __linux__ + /* Must unlock before freeing */ + munlock(ptr, size); +#else + (void)ptr; + (void)size; +#endif +} + +#endif /* SE050_MEM_PROTECT_H */ diff --git a/src/se050_keystore.c b/src/se050_keystore.c index 15dbe42..2875e2f 100644 --- a/src/se050_keystore.c +++ b/src/se050_keystore.c @@ -18,61 +18,7 @@ #include #include -/* Linux memory protection */ -#ifdef __linux__ -#include -#endif - -/* ============================================================================ - * Memory Protection (Linux-specific) - * ============================================================================ */ - -/** - * @brief Protect sensitive memory from being swapped or dumped - */ -#ifdef __linux__ -static se050_status_t protect_sensitive_memory(void *ptr, size_t size) -{ - /* 1. Prevent swapping to disk (optional - may fail due to permissions) */ - if (mlock(ptr, size) != 0) { - /* mlock may fail due to ulimit restrictions. Log warning but continue. */ - fprintf(stderr, "Warning: mlock failed (%s). Memory may be swapped.\n", strerror(errno)); - /* Continue without mlock - better than failing entirely */ - } - - /* 2. Exclude from core dumps */ - if (madvise(ptr, size, MADV_DONTDUMP) != 0) { - perror("madvise MADV_DONTDUMP failed"); - /* Non-fatal, continue */ - } - - /* 3. Clear in child processes after fork() */ - if (madvise(ptr, size, MADV_WIPEONFORK) != 0) { - perror("madvise MADV_WIPEONFORK failed"); - /* Non-fatal, continue */ - } - - return SE050_OK; -} - -static void release_memory_protection(void *ptr, size_t size) -{ - munlock(ptr, size); -} -#else -static se050_status_t protect_sensitive_memory(void *ptr, size_t size) -{ - (void)ptr; - (void)size; - return SE050_OK; -} - -static void release_memory_protection(void *ptr, size_t size) -{ - (void)ptr; - (void)size; -} -#endif +#include "se050_mem_protect.h" /* ============================================================================ * Key Store Management diff --git a/src/se050_keystore.o b/src/se050_keystore.o index 85b73b3..674a084 100644 Binary files a/src/se050_keystore.o and b/src/se050_keystore.o differ diff --git a/src/se050_scp03.c b/src/se050_scp03.c index fc67224..53eb917 100644 --- a/src/se050_scp03.c +++ b/src/se050_scp03.c @@ -12,15 +12,10 @@ #include "se050_wireguard.h" #include "se050_crypto_utils.h" +#include "se050_mem_protect.h" #include #include #include -#include - -/* Linux memory protection */ -#ifdef __linux__ -#include -#endif /* SCP03 constants */ #define SCP03_KEY_SIZE 16 @@ -33,67 +28,6 @@ #define SCP03_SW_SUCCESS 0x9000 #define SCP03_SW_FAIL 0x6F00 -/* ============================================================================ - * Memory Protection (Linux-specific) - * ============================================================================ */ - -/** - * @brief Protect sensitive memory from being swapped or dumped - * - * Applies multiple security measures: - * - mlock(): Prevent swapping to disk - * - MADV_DONTDUMP: Exclude from core dumps - * - MADV_WIPEONFORK: Clear in child processes after fork() - */ -#ifdef __linux__ -static se050_status_t protect_sensitive_memory(void *ptr, size_t size) -{ - /* 1. Prevent swapping to disk (optional - may fail due to permissions) */ - if (mlock(ptr, size) != 0) { - /* mlock may fail due to ulimit restrictions. Log warning but continue. */ - fprintf(stderr, "Warning: mlock failed (%s). Memory may be swapped.\n", strerror(errno)); - /* Continue without mlock - better than failing entirely */ - } - - /* 2. Exclude from core dumps */ - if (madvise(ptr, size, MADV_DONTDUMP) != 0) { - perror("madvise MADV_DONTDUMP failed"); - /* Non-fatal, continue */ - } - - /* 3. Clear in child processes after fork() */ - if (madvise(ptr, size, MADV_WIPEONFORK) != 0) { - perror("madvise MADV_WIPEONFORK failed"); - /* Non-fatal, continue */ - } - - return SE050_OK; -} - -/** - * @brief Release memory protection before freeing - */ -static void release_memory_protection(void *ptr, size_t size) -{ - /* Must unlock before freeing */ - munlock(ptr, size); -} -#else -/* Non-Linux platforms: no special protection */ -static se050_status_t protect_sensitive_memory(void *ptr, size_t size) -{ - (void)ptr; - (void)size; - return SE050_OK; -} - -static void release_memory_protection(void *ptr, size_t size) -{ - (void)ptr; - (void)size; -} -#endif - /** * @brief SCP03 session context structure */ diff --git a/src/se050_scp03.o b/src/se050_scp03.o index 26b681d..2586fa1 100644 Binary files a/src/se050_scp03.o and b/src/se050_scp03.o differ