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