Linux メモリ保護機能の実装 (mlock, MADV_DONTDUMP, MADV_WIPEONFORK)
セキュリティ強化のため、Linux 固有のメモリ保護機能を追加: ### 実装した保護機能 1. **mlock()** - スワップ防止 - センシティブなメモリをディスクへのスワップから保護 - 権限不足の場合は警告出力の上継続(フォールバック) 2. **MADV_DONTDUMP** - コアダンプ漏洩防止 - コアダンプ生成時にメモリ内容を除外 - プライベート鍵がダンプに含まれないようにする 3. **MADV_WIPEONFORK** - fork() 子プロセス漏洩防止 - fork() 後の子プロセスからメモリ内容を消去 - 子プロセスへの鍵漏洩を防止 ### 変更ファイル - src/se050_scp03.c - SCP03 コンテキストのメモリ保護 - src/se050_keystore.c - キーストアコンテキストのメモリ保護 ### 実装詳細 - Linux 環境でのみ有効(#ifdef __linux__) - 非 Linux プラットフォームではフォールバック - mlock 失敗時は警告のみ出力(処理継続) - madvise 失敗時はエラーログ出力(非致命的) ### 注意事項 - mlock には CAP_IPC_LOCK 権限または RLIMIT_MEMLOCK クォータが必要 - 権限不足の場合でも機能は動作(保護なしで継続) - 本番環境では適切な権限設定を推奨
This commit is contained in:
@@ -7,11 +7,20 @@
|
||||
* License: MIT (Clean-room implementation)
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE /* For MADV_DONTDUMP, MADV_WIPEONFORK */
|
||||
#define _POSIX_C_SOURCE 200809L
|
||||
|
||||
#include "se050_wireguard.h"
|
||||
#include "se050_crypto_utils.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
/* Linux memory protection */
|
||||
#ifdef __linux__
|
||||
#include <sys/mman.h>
|
||||
#endif
|
||||
|
||||
/* SCP03 constants */
|
||||
#define SCP03_KEY_SIZE 16
|
||||
@@ -24,6 +33,67 @@
|
||||
#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
|
||||
*/
|
||||
@@ -297,6 +367,7 @@ static se050_status_t scp03_derive_session_keys(se050_scp03_ctx_t *ctx)
|
||||
se050_status_t se050_scp03_init(se050_scp03_ctx_t **ctx, se050_session_ctx_t *session)
|
||||
{
|
||||
se050_scp03_ctx_t *scp03;
|
||||
size_t ctx_size;
|
||||
|
||||
if (!ctx || !session) {
|
||||
return SE050_ERR_INVALID_ARG;
|
||||
@@ -308,6 +379,14 @@ se050_status_t se050_scp03_init(se050_scp03_ctx_t **ctx, se050_session_ctx_t *se
|
||||
return SE050_ERR_FAIL;
|
||||
}
|
||||
|
||||
ctx_size = sizeof(*scp03);
|
||||
|
||||
/* Apply memory protection (Linux only) */
|
||||
if (protect_sensitive_memory(scp03, ctx_size) != SE050_OK) {
|
||||
free(scp03);
|
||||
return SE050_ERR_FAIL;
|
||||
}
|
||||
|
||||
scp03->session = session;
|
||||
scp03->cmd_counter = 0;
|
||||
scp03->rsp_counter = 0;
|
||||
@@ -339,6 +418,9 @@ void se050_scp03_free(se050_scp03_ctx_t *ctx)
|
||||
memzero_explicit(ctx->rsp_icv, sizeof(ctx->rsp_icv));
|
||||
}
|
||||
|
||||
/* Release memory protection before freeing */
|
||||
release_memory_protection(ctx, sizeof(*ctx));
|
||||
|
||||
/* Free SCP03 context */
|
||||
free(ctx);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user