POSA_LEAKSMS/firmware/config/mbedtls_config.h
유창욱 90f121e14c chore: import codebase with security hardening
SHT30 온습도 모니터링 시스템 전체 소스(서버 PHP, STM32 펌웨어, SQL, 테스트).
전체 코드리뷰에서 도출된 보안 하드닝 10건 반영:
- 요청 서명 HMAC-SHA256 전환(펌웨어 sig.c/서버 config.php/호스트 패리티 동시)
- 재전송 방어 + 기본 API_KEY fail-closed + 디바이스 문자열 정제(api/sensor_data.php)
- 오프라인 SMS 중복 발송 경합 제거(cron_heartbeat.php, 원자적 선점)
- CSV 수식 주입 방지(monthly_report.php), 감사로그 회전 락(retention_cleanup.php)
- 브루트포스 카운터 원자화(login.php), 예시 TOTP 비밀키 무효화, 마이그레이션 멱등화

_backup/(하드코딩 실 비밀값 포함)·config.local.php·런타임 상태는 .gitignore 제외.
2026-06-20 09:37:40 +09:00

203 lines
16 KiB
C

/* =============================================================================
* mbedtls_config.h - STM32F407 (Cortex-M4F, 192KB SRAM + 64KB CCM) 용
* 최소 TLS 1.2 클라이언트 mbedTLS 설정
*
* 목표 / 제약:
* - 클라이언트 전용, TLS 1.2 ONLY (SSL3/TLS1.0/1.1 비활성).
* - 키교환: ECDHE-RSA (+ ECDHE-ECDSA 선택) — 서버 인증서 RSA/ECDSA 모두 대응.
* - 암호: AES-128/256-GCM (AEAD). CBC/RC4/3DES/ChaCha 등은 미사용.
* - 해시: SHA-256/224(주), SHA-384/512(인증서 체인 서명에 필요할 수 있음).
* - 인증서 검증: X.509 CRT 파싱 + 임베드 루트 CA(certs/server_ca.h)로 풀 검증.
* - 엔트로피: 플랫폼(파일/시스템) 엔트로피 OFF, STM32 하드웨어 RNG(ALT) 사용.
* - I/O: mbedTLS 내장 net_sockets/파일시스템 OFF — LwIP 소켓 BIO 를 직접 제공.
* - 메모리: SSL 레코드 버퍼 축소(IN 4096 / OUT 2048) + MFL 협상으로 RAM 절감.
* - 플랫폼 calloc/free → FreeRTOS heap (pvPortMalloc/vPortFree) 로 매핑.
*
* 폐쇄망(air-gapped): 모든 의존성은 third_party/mbedtls 에 벤더링되어 있으며,
* 이 설정은 빌드/런타임 모두 외부 네트워크 fetch 를 유발하지 않는다.
*
* ── RAM 사용 추정(대략) ─────────────────────────────────────────────────────
* SSL 레코드 버퍼: IN 4096 + OUT 2048 ≈ 6.1 KB
* (+ 각 버퍼당 헤더/MAC/패딩 여유 약 수십~수백 B)
* mbedtls_ssl_context (세션/핸드셰이크 트랜스폼 등): 약 1.5~2.5 KB
* 핸드셰이크 임시(ECDHE 키쌍, 인증서 파싱 시 일시적 MPI/스택): 피크 약 6~10 KB
* (핸드셰이크 종료 후 대부분 해제)
* ctr_drbg + entropy 컨텍스트: 약 0.4 KB
* 파싱된 루트 CA 체인(x509_crt, RSA-2048 기준): 약 1.5~2.5 KB (상주)
* => 연결 1개 정상 운영 시 상주 약 10~12 KB, 핸드셰이크 피크 약 18~22 KB.
* 192KB SRAM 예산 내에서 LwIP/FreeRTOS 와 공존 가능(단일 동시 TLS 연결 가정).
* 필요 시 IN_CONTENT_LEN 을 더 줄이면(서버가 MFL 또는 작은 레코드 지원 시)
* 추가 절감 가능. OUT 2048 은 우리의 HTTP POST 요청(<~1.3KB)에 충분하다.
* ===========================================================================*/
#ifndef MBEDTLS_CONFIG_H
#define MBEDTLS_CONFIG_H
/* 대상 라이브러리: mbedTLS 3.6.2 (LTS) — third_party/mbedtls.
*
* PSA 정책(중요): 이 설정은 **레거시 크립토 경로**(MBEDTLS_USE_PSA_CRYPTO 미정의,
* MBEDTLS_PSA_CRYPTO_C 미정의)를 사용한다. TLS 1.3 미사용(MBEDTLS_SSL_PROTO_TLS1_3
* 미정의)이므로 3.6 에서 psa_crypto_init() 호출이 필요 없다(코드/RAM 절감).
* → 빌드 시 -DMBEDTLS_USE_PSA_CRYPTO 등을 추가하지 말 것.
* 빌드 시 -DMBEDTLS_CONFIG_FILE='"mbedtls_config.h"' 로 이 파일을 지정한다. */
#include <stddef.h> /* size_t (아래 calloc/free 프로토타입용) */
/* ─────────────────────────────────────────────────────────────────────────
* 1) 플랫폼 계층 (베어메탈 + FreeRTOS, 표준 C 라이브러리 일부만 사용)
* ───────────────────────────────────────────────────────────────────────── */
#define MBEDTLS_PLATFORM_C
/* calloc/free 를 FreeRTOS 힙으로 매핑한다(전용 매크로 사용 → 별도 set 함수 불필요).
* pvPortMalloc 은 calloc 시그니처(nmemb,size)와 다르므로 래퍼를 tls_mbedtls.c
* 에서 제공하고 여기서는 그 래퍼를 가리킨다.
*
* 주의(gcc15/C23): 매크로는 mbedTLS 의 모든 .c 에서 텍스트 치환되므로, 해당 함수의
* 프로토타입이 그곳에서 보여야 한다(암시적 선언은 오류). 따라서 여기서 선언한다. */
#define MBEDTLS_PLATFORM_MEMORY
#define MBEDTLS_PLATFORM_CALLOC_MACRO mbedtls_platform_calloc
#define MBEDTLS_PLATFORM_FREE_MACRO mbedtls_platform_free
void *mbedtls_platform_calloc(size_t n, size_t size); /* tls_mbedtls.c 에 정의 */
void mbedtls_platform_free(void *p); /* tls_mbedtls.c 에 정의 */
/* snprintf/printf 는 표준 newlib 사용(로그/디버그용 최소). */
/* ── 시간(인증서 유효기간 검증) ─────────────────────────────────────────────
* MBEDTLS_HAVE_TIME_DATE 가 없으면 X.509 notBefore/notAfter 검증이 컴파일되지
* 않아 만료/미래 인증서도 통과한다(치명적). SNTP→RTC 로 동기한 Unix 시간을
* mbedTLS 에 공급한다. newlib 의 time()(시스템콜, nosys 에서 -1)에 의존하지
* 않도록 PLATFORM_TIME_MACRO 로 우리 함수(tls_platform_time)를 직접 가리킨다.
* 날짜 분해는 newlib 의 gmtime_r(순수 계산, 시스템콜 없음)이 처리한다.
* (time_t 타입 일치를 위해 <time.h> 포함; mbedtls_time_t 는 기본 time_t.) */
#include <time.h>
#define MBEDTLS_HAVE_TIME
#define MBEDTLS_HAVE_TIME_DATE
#define MBEDTLS_PLATFORM_TIME_MACRO tls_platform_time
time_t tls_platform_time(time_t *t); /* tls_mbedtls.c 에 정의 (timesync_now 기반) */
/* ─────────────────────────────────────────────────────────────────────────
* 2) 엔트로피 / RNG — 플랫폼 엔트로피 OFF, STM32 하드웨어 RNG(ALT) 사용
* tls_mbedtls.c 가 int mbedtls_hardware_poll(...) 를 구현한다.
* ───────────────────────────────────────────────────────────────────────── */
#define MBEDTLS_NO_PLATFORM_ENTROPY
#define MBEDTLS_ENTROPY_HARDWARE_ALT
#define MBEDTLS_ENTROPY_C
#define MBEDTLS_CTR_DRBG_C
/* SHA-512 가 빌드에 있으므로 entropy 는 SHA-512 를 기본 사용. (아래 SHA512 활성) */
/* ─────────────────────────────────────────────────────────────────────────
* 3) 프로토콜 버전: TLS 1.2 클라이언트 ONLY
* ───────────────────────────────────────────────────────────────────────── */
#define MBEDTLS_SSL_TLS_C
#define MBEDTLS_SSL_CLI_C
#define MBEDTLS_SSL_PROTO_TLS1_2
/* SSL3 / TLS1.0 / TLS1.1 / TLS1.3 / DTLS / 서버 모드는 활성하지 않는다. */
/* ─────────────────────────────────────────────────────────────────────────
* 4) 키교환: ECDHE-RSA (주) + ECDHE-ECDSA (선택, 서버가 ECDSA 인증서일 때)
* => RSA, ECDSA, ECDH, DHM(미사용) 중 ECDHE 만.
* ───────────────────────────────────────────────────────────────────────── */
#define MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED
#define MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
/* ─────────────────────────────────────────────────────────────────────────
* 5) 공개키 / 서명 알고리즘
* ───────────────────────────────────────────────────────────────────────── */
#define MBEDTLS_PK_C
#define MBEDTLS_PK_PARSE_C
#define MBEDTLS_RSA_C
#define MBEDTLS_PKCS1_V15 /* RSA PKCS#1 v1.5 서명/검증 */
#define MBEDTLS_PKCS1_V21 /* RSASSA-PSS / OAEP (v2.1) — 일부 체인에 필요 */
#define MBEDTLS_ECDSA_C
#define MBEDTLS_ECDH_C
#define MBEDTLS_ECP_C
#define MBEDTLS_BIGNUM_C
#define MBEDTLS_ASN1_PARSE_C
#define MBEDTLS_ASN1_WRITE_C /* ECDSA 서명 작성/일부 PK 경로에서 사용 */
#define MBEDTLS_OID_C
/* ECDSA 결정론적 서명(클라이언트 인증서 미사용이므로 필수는 아님). 비활성으로 RAM 절감. */
/* #define MBEDTLS_ECDSA_DETERMINISTIC */
/* 지원 타원곡선: 서버/CA 가 가장 흔히 쓰는 secp256r1, secp384r1, x25519. */
#define MBEDTLS_ECP_DP_SECP256R1_ENABLED
#define MBEDTLS_ECP_DP_SECP384R1_ENABLED
#define MBEDTLS_ECP_DP_CURVE25519_ENABLED
/* ─────────────────────────────────────────────────────────────────────────
* 6) 해시
* ───────────────────────────────────────────────────────────────────────── */
#define MBEDTLS_MD_C
#define MBEDTLS_SHA224_C
#define MBEDTLS_SHA256_C
#define MBEDTLS_SHA384_C
#define MBEDTLS_SHA512_C
/* SHA-1: 일부 구형 인증서 체인 호환을 위해 켜두되, TLS 핸드셰이크 PRF 에는 미사용.
* 보안상 불필요하면 주석 처리 가능. 기본은 호환성 위해 활성. */
#define MBEDTLS_SHA1_C
/* ─────────────────────────────────────────────────────────────────────────
* 7) 대칭 암호 (AEAD only): AES-GCM
* ───────────────────────────────────────────────────────────────────────── */
#define MBEDTLS_AES_C
#define MBEDTLS_GCM_C
#define MBEDTLS_CIPHER_C
/* CBC/CTR/ChaCha20-Poly1305/3DES/ARC4 등은 활성하지 않는다(AEAD-GCM 전용).
* → ECDHE-RSA/ECDSA-AES128/256-GCM 만 협상 가능. CBC 모드 미포함으로 코드/RAM 절감. */
/* ─────────────────────────────────────────────────────────────────────────
* 8) X.509 인증서 검증 (서버 인증서 + 임베드 루트 CA)
* ───────────────────────────────────────────────────────────────────────── */
#define MBEDTLS_X509_USE_C
#define MBEDTLS_X509_CRT_PARSE_C
/* CRL/CSR 작성은 불필요 → 비활성으로 코드/RAM 절감.
* MBEDTLS_X509_CRL_PARSE_C / MBEDTLS_X509_CSR_PARSE_C 미정의. */
/* ─────────────────────────────────────────────────────────────────────────
* 9) TLS 세부 옵션 / 확장
* ───────────────────────────────────────────────────────────────────────── */
#define MBEDTLS_SSL_SERVER_NAME_INDICATION /* SNI (mbedtls_ssl_set_hostname) */
#define MBEDTLS_SSL_MAX_FRAGMENT_LENGTH /* MFL 협상으로 레코드 버퍼 절감 */
#define MBEDTLS_SSL_ENCRYPT_THEN_MAC /* EtM 확장(GCM 엔 무영향, 켜둬도 무해) */
#define MBEDTLS_SSL_EXTENDED_MASTER_SECRET /* 보안 권장 확장 */
/* 세션 티켓/재협상/캐시: 단발 connection-close 운영이라 불필요 → 비활성. */
/* #define MBEDTLS_SSL_SESSION_TICKETS */
/* #define MBEDTLS_SSL_RENEGOTIATION */
/* ── 레코드 버퍼 크기 축소 (RAM 절감 핵심) ──────────────────────────────────
* IN 4096: 서버 인증서(중간 CA 포함) 단편이 한 레코드에 들어오도록 여유.
* OUT 2048: 우리 HTTP POST 요청은 ~1.3KB 미만 → 충분.
* (RFC 6066 MFL 과 함께 동작; 서버 미지원 시 표준 16K 대신 이 값으로 제한.) */
#define MBEDTLS_SSL_IN_CONTENT_LEN 4096
#define MBEDTLS_SSL_OUT_CONTENT_LEN 2048
/* ─────────────────────────────────────────────────────────────────────────
* 10) I/O / 파일시스템: mbedTLS 내장 비활성 (LwIP BIO 직접 제공)
* - MBEDTLS_NET_C (mbedTLS 자체 BSD 소켓): 미정의
* - MBEDTLS_FS_IO (파일에서 인증서 로드): 미정의 (PEM 은 flash 임베드)
* - MBEDTLS_TIMING_C: 미정의 (블로킹 소켓 타임아웃은 SO_RCVTIMEO 로 처리)
* ───────────────────────────────────────────────────────────────────────── */
/* ─────────────────────────────────────────────────────────────────────────
* 11) 오류 문자열 / 디버그
* - MBEDTLS_ERROR_C: mbedtls_strerror() 로 사람이 읽는 오류(로그용, 코드↑).
* 플래시 1MB 라 여유 → 운영 진단 가치가 커서 활성. 용량 부족 시 제거.
* - MBEDTLS_DEBUG_C: 핸드셰이크 상세 디버그는 기본 OFF(필요 시만 켜기).
* ───────────────────────────────────────────────────────────────────────── */
#define MBEDTLS_ERROR_C
/* #define MBEDTLS_DEBUG_C */
/* ─────────────────────────────────────────────────────────────────────────
* 12) Cortex-M4 최적화/안전 옵션
* ───────────────────────────────────────────────────────────────────────── */
/* AES/SHA 하드웨어 가속기가 없는 MCU 이므로 소프트웨어 구현 사용(기본).
* NIST 곡선 최적화(MBEDTLS_ECP_NIST_OPTIM): 속도↑(secp256/384). */
#define MBEDTLS_ECP_NIST_OPTIM
/* 사이드채널 완화 무작위화는 RNG 가용하므로 기본 동작 유지. */
/* 정수 곱셈 최적화 타깃(선택). arm-none-eabi 가 기본 처리하므로 미지정. */
/* ─────────────────────────────────────────────────────────────────────────
* 13) 설정 검증 (헤더 의존성/조합 오류를 컴파일 타임에 잡는다)
* 반드시 파일 맨 끝에 둔다.
* ───────────────────────────────────────────────────────────────────────── */
#include "mbedtls/check_config.h"
#endif /* MBEDTLS_CONFIG_H */