POSA_LEAKSMS/firmware/third_party/README.md
유창욱 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

157 lines
8.3 KiB
Markdown

# `third_party/` — 벤더링된 제3자 의존성 (폐쇄망 / air-gapped)
이 디렉터리에는 STM32F407 펌웨어가 의존하는 **모든 제3자 소스가 고정 버전으로
벤더링**된다. 폐쇄망 빌드 원칙(`~/.claude/rules/common/build-deployment.md`):
> **빌드 머신만 다운로드하고, 타깃/빌드 자체는 외부를 절대 가져오지 않는다.**
> 모든 의존성·런타임·자산은 산출물에 내장된다.
- 인터넷 fetch 는 **빌드 머신에서 단 한 번**, 아래 `vendor.ps1` / `vendor.sh`
로만 수행한다(저장소 클론).
- `CMakeLists.txt``third_party/` 안의 소스를 **그대로 참조**하며,
`FetchContent`/`ExternalProject` 로 네트워크에서 받아오지 **않는다**.
- 이 디렉터리는 용량이 크고 외부 저장소의 사본이므로 git 에 커밋하지 않는다
(`firmware/.gitignore` 에서 제외). 폐쇄망 반입 시에는 디렉터리째 오프라인
번들(USB/tar)로 전달한다.
---
## 1. 벤더링 대상 (정확한 저장소 + 고정 태그)
> 아래 태그는 검증된 조합 기준의 권장 핀(pin)이다. 실제 핀 변경 시 본 표와
> `vendor.ps1`/`vendor.sh` 의 태그, 그리고 `firmware/VERSION` 의 빌드 메모를
> 함께 갱신할 것.
| 컴포넌트 | 용도 | 저장소 (canonical) | 고정 태그 | 안착 경로 |
|----------|------|---------------------|-----------|-----------|
| **STM32CubeF4** | HAL + LL 드라이버, CMSIS-Device F4, 시동코드 | `https://github.com/STMicroelectronics/STM32CubeF4` | `v1.28.0` | `third_party/STM32CubeF4/` |
| **CMSIS_5** (선택) | CMSIS-Core(M4F). CubeF4 내장본 사용 시 불필요 | `https://github.com/ARM-software/CMSIS_5` | `5.9.0` | `third_party/CMSIS_5/` |
| **FreeRTOS-Kernel** | RTOS 커널 (네이티브 API) | `https://github.com/FreeRTOS/FreeRTOS-Kernel` | `V11.1.0` | `third_party/FreeRTOS-Kernel/` |
| **lwIP** | TCP/IP 스택 (+ SNTP app) | `https://github.com/lwip-tcpip/lwip` | `STABLE-2_2_0_RELEASE` | `third_party/lwip/` |
| **lwIP contrib** (필요 시) | 포트 예제/추가 app | `https://github.com/lwip-tcpip/lwip-contrib` | `STABLE-2_2_0_RELEASE` | `third_party/lwip-contrib/` |
| **mbedTLS** | TLS1.2 클라이언트, SHA-256(sw) | `https://github.com/Mbed-TLS/mbedtls` | `mbedtls-3.6.2` (LTS) | `third_party/mbedtls/` |
런타임/툴 메모:
- 컴파일러: **arm-none-eabi-gcc 15.2** (오프라인 툴체인 번들에 포함, `third_party` 외부).
- 빌드 시스템: **CMake + Ninja** (빌드 머신 설치본).
- mbedTLS 3.6.x 는 LTS 라인 → 보안 패치 수명이 길어 폐쇄망 장기 운용에 유리.
---
## 2. 각 컴포넌트에서 실제로 쓰는 하위 경로
CubeF4 / FreeRTOS 는 전체 트리가 크지만, CMake 는 아래 핵심 경로만 컴파일·include 한다.
### STM32CubeF4 (`third_party/STM32CubeF4/`)
- HAL/LL 드라이버:
- `Drivers/STM32F4xx_HAL_Driver/Inc/`
- `Drivers/STM32F4xx_HAL_Driver/Src/` (사용 모듈만: RCC, GPIO, CORTEX, ETH, I2C, UART, RNG, IWDG, RTC, DMA, PWR, FLASH …)
- CMSIS-Device F4:
- `Drivers/CMSIS/Device/ST/STM32F4xx/Include/` (`stm32f4xx.h`, `stm32f407xx.h`)
- `Drivers/CMSIS/Device/ST/STM32F4xx/Source/Templates/gcc/startup_stm32f407xx.s`**시동코드(GCC)**
- `Drivers/CMSIS/Device/ST/STM32F4xx/Source/Templates/system_stm32f4xx.c`**SystemInit**
- CMSIS-Core:
- `Drivers/CMSIS/Include/` (core_cm4.h 등; CMSIS_5 별도 벤더링 시 그쪽 사용)
> 링커 스크립트(`STM32F407VGTx_FLASH.ld`)는 프로젝트가 직접 보유(task stack 을
> CCM 64KB 에 배치하는 커스텀 섹션 포함). CubeF4 템플릿을 베이스로 수정한다.
### FreeRTOS-Kernel (`third_party/FreeRTOS-Kernel/`)
- 코어: 루트의 `tasks.c`, `queue.c`, `list.c`, `timers.c`, `event_groups.c`, `stream_buffer.c`
- 포트(Cortex-M4F, GCC): `portable/GCC/ARM_CM4F/` (`port.c`, `portmacro.h`)
- 힙: `portable/MemMang/heap_4.c`**heap_4 사용**
- include: `include/`
- 설정 헤더 `FreeRTOSConfig.h` 는 프로젝트(`common/` 또는 board 별)가 보유.
### lwIP (`third_party/lwip/`)
- 코어: `src/core/`, `src/core/ipv4/`, `src/api/`, `src/netif/`
- include: `src/include/`
- **SNTP app**: `src/apps/sntp/sntp.c` + `src/include/lwip/apps/sntp.h` ← 시간 동기(R4)
- 포트(이식): `lwipopts.h`, `sys_arch`(FreeRTOS 연동), LAN8720 RMII `ethernetif.c`
프로젝트가 보유(CubeF4 LwIP 미들웨어 템플릿 또는 ST 예제를 베이스로 작성).
### mbedTLS (`third_party/mbedtls/`)
- 라이브러리: `library/` (TLS/x509/PK/MD/cipher/bignum/SHA-256 등)
- include: `include/`
- 설정: `mbedtls_config.h` (TLS1.2 only, ECDHE-RSA + AES-GCM, `MBEDTLS_SSL_IN/OUT_CONTENT_LEN ≈ 4096`,
MFL extension, HW 가속 없음 → SHA-256/AES 소프트웨어)는 프로젝트(`common/`)가 보유.
- 엔트로피: STM32 HW RNG 를 `mbedtls_hardware_poll()` 로 연결(프로젝트 측 구현).
---
## 3. 벤더링 스크립트 (빌드 머신에서 1회)
`third_party/` 에 아래 스크립트를 두고, **인터넷이 되는 빌드/스테이징 머신에서만**
실행한다. 결과 디렉터리를 폐쇄망으로 반입한다.
> 두 스크립트 모두 위 표의 태그를 `--depth 1 --branch <tag>` 로 얕은 클론한다.
> 클론 후 각 저장소의 `.git/` 은 제거하여 번들 용량을 줄인다.
### Windows — `third_party/vendor.ps1` (작성 예시)
```powershell
# TODO(hw): 실제 환경에 맞게 태그 확인 후 실행. 빌드 머신 전용(폐쇄망 금지).
$ErrorActionPreference = 'Stop'
$root = $PSScriptRoot
$deps = @(
@{ url='https://github.com/STMicroelectronics/STM32CubeF4'; tag='v1.28.0'; dir='STM32CubeF4' },
@{ url='https://github.com/FreeRTOS/FreeRTOS-Kernel'; tag='V11.1.0'; dir='FreeRTOS-Kernel' },
@{ url='https://github.com/lwip-tcpip/lwip'; tag='STABLE-2_2_0_RELEASE'; dir='lwip' },
@{ url='https://github.com/Mbed-TLS/mbedtls'; tag='mbedtls-3.6.2'; dir='mbedtls' }
)
foreach ($d in $deps) {
$dst = Join-Path $root $d.dir
if (Test-Path $dst) { Write-Host "skip $($d.dir) (exists)"; continue }
git clone --depth 1 --branch $d.tag $d.url $dst
Remove-Item -Recurse -Force (Join-Path $dst '.git') # 번들 슬림화
}
Write-Host "[OK] vendored into $root"
```
### Linux/macOS — `third_party/vendor.sh` (작성 예시)
```sh
#!/usr/bin/env sh
# TODO(hw): 빌드 머신 전용(폐쇄망 금지).
set -eu
ROOT="$(cd "$(dirname "$0")" && pwd)"
clone() { # url tag dir
[ -d "$ROOT/$3" ] && { echo "skip $3 (exists)"; return; }
git clone --depth 1 --branch "$2" "$1" "$ROOT/$3"
rm -rf "$ROOT/$3/.git"
}
clone https://github.com/STMicroelectronics/STM32CubeF4 v1.28.0 STM32CubeF4
clone https://github.com/FreeRTOS/FreeRTOS-Kernel V11.1.0 FreeRTOS-Kernel
clone https://github.com/lwip-tcpip/lwip STABLE-2_2_0_RELEASE lwip
clone https://github.com/Mbed-TLS/mbedtls mbedtls-3.6.2 mbedtls
echo "[OK] vendored into $ROOT"
```
> mbedTLS 일부 버전은 `library/` 빌드에 Python 생성 스크립트가 필요할 수 있다.
> 그 산출물도 **빌드 머신에서** 생성해 함께 반입한다(타깃은 생성 금지).
---
## 4. 검증 (폐쇄망 가정)
- [ ] `vendor.*` 실행 후 위 표의 모든 경로가 존재하는지 확인.
- [ ] **네트워크를 끊고** `cmake … && ninja``sht30_fw` 타깃이
외부 fetch 없이 빌드되는지 확인.
- [ ] 결과물(`.elf/.bin/.hex`)과 `third_party/` 를 함께 오프라인 번들로 묶어
반입 절차에 첨부.
- [ ] 어떤 단계라도 네트워크가 필요하면 **명시적으로 FLAG** (조용히 가정 금지).
---
## 5. 디렉터리 레이아웃 (CMake 기대값)
```
firmware/third_party/
├─ STM32CubeF4/ # HAL + CMSIS-Device F4 + startup_stm32f407xx.s + system_stm32f4xx.c
├─ FreeRTOS-Kernel/ # tasks/queue/timers/... + portable/GCC/ARM_CM4F + portable/MemMang/heap_4.c
├─ lwip/ # src/core, src/api, src/netif, src/apps/sntp (+ src/include)
├─ mbedtls/ # library/ + include/
├─ (CMSIS_5/) # 선택: CubeF4 내장 CMSIS-Core 미사용 시
├─ (lwip-contrib/) # 선택
├─ vendor.ps1 # 빌드 머신 전용 클론 스크립트 (Windows)
├─ vendor.sh # 빌드 머신 전용 클론 스크립트 (POSIX)
└─ README.md # 이 문서
```