ESP32 보안기능 - Secure boot V2
ESP32 Secure boot V2
ESP32 Secure boot(시큐어 부트)는 Bootloader와 APP에 유져가 Sign을 하여, 보안처리를 하는 것으로, 유져가 Sign을 하지 않는 Firmware는 해당 모듈에서 동작을 하지 못하도록 막는 기능입니다. 즉, 펌웨어에 인감도장을 찍고, 도장이 원본이면 동작을 하고, 도장이 없거나 가짜이면 동작을 하지 않는 기능입니다.
Security Features Enablement Workflows - ESP32-S3 - — ESP-IDF Programming Guide latest documentation
Security Features Enablement Workflows - ESP32-S3 - — ESP-IDF Programming Guide latest documentation
Note Please update the EFUSE_NAME with the eFuse that you need to burn. Multiple eFuses can be burned at the same time by appending them to the above command (e.g., EFUSE_NAME VAL EFUSE_NAME2 VAL2). More documentation about espefuse.py can be found here Th
docs.espressif.com
Secure Boot v2는 RSA-PSS 또는 ECDSA 기반의 서명 검증을 통해 2단계 부트로더와 애플리케이션 바이너리의 무결성을 보장하는 기능입니다.
- 부트 시점에 서명되지 않은 코드 실행을 차단
- 앱만 서명하거나, 부트로더와 앱 모두 서명 가능
- idf.py secure-<command> 명령을 사용하며, 내부적으로 espsecure.py를 호출
동작 원리
- 1단계 부트로더(ROM)는 변경 불가하므로 서명 불필요 - ESP32 ROM에 내장된 Bootloader로 펌웨어가 아님
- 2단계 부트로더와 앱 이미지는 반드시 서명 검증 후 실행 (빌드시 아노는 Bootloader.bin)
- 서명 알고리즘: RSA-PSS 또는 ECDSA 중 하나 선택 (디바이스당 하나만 사용 가능)
- 공개키(Public Key)는 칩 내부 저장, 개인키(Private Key)는 외부 안전한 장소에 보관
- 최대 3개의 공개키 저장 가능, 필요 시 개별 키 영구 폐기(eFuse)
- 부트로더와 앱 동일한 이미지 포맷·검증 방식 사용
- 기기 내 비밀키 저장 없음 → 타이밍/전력 분석 등 수동 사이드채널 공격에 안전
부팅 절차
- ROM 코드가 eFuse의 Secure Boot v2 활성화 비트 확인 (ROM 코드는 칩 ROM에 내장, 펌웨어가 아님)
- 부트로더 서명 블록 검증 실패 시 부팅 중단 - 이후 펌웨어에서 기능 수행
- 부트로더 이미지 검증 실패 시 부팅 중단
- 부트로더 실행
- 앱 서명 블록 검증 실패 시 부팅 중단
- 앱 이미지 검증 실패 시 부팅 중단
- OTA 환경에서는 다른 앱 파티션 검증 시도
- 검증 성공 시 앱 실행
적용 절차 (외부 sign 방식)
이 방법은 외부 sign방식(개발자 PC에서)으로, 펌웨어 bin파일을 개발자가 sign 한 후 펌웨어 라이팅을 하는 방법이다.
내부 방식도 가능하나, 부팅 하면서 자동 sign을 하게 되어 생산 시간이 길어지는 단점이 있다.
[1] menuconfig 설정
├─ Security features → Enable hardware Secure Boot in bootloader (ON)
├─ Secure Boot Version: v2
├─ App Signing Scheme: RSA (기본값)
└─ CONFIG_SECURE_BOOT_BUILD_SIGNED_BINARIES (OFF)
→ 빌드 시 서명 없이 Secure Padding만 적용
[2] 서명 키(private키) 생성 (pem파일은 ESP32에 저장되지 않는다.)
└─ idf.py secure-generate-signing-key -v2 --scheme rsa3072 secure_boot_signing_key.pem
[3] 공개키 Digest 생성 (ESP32 efuse에 저장된다.)
└─ idf.py secure-generate-key-digest --keyfile secure_boot_signing_key.pem --output digest.bin
[4] eFuse에 Digest 굽기 (한번 Burn하면 변경 불가)
└─ idf.py --port <PORT> efuse-burn-key BLOCK_KEY0 digest.bin SECURE_BOOT_DIGEST0
[5] Secure Boot 활성화 eFuse 설정 (변경 불가)
└─ idf.py --port <PORT> efuse-burn SECURE_BOOT_EN
[6] 프로젝트 빌드 (서명 없이 패딩만 적용된 바이너리 생성)
└─ idf.py build
→ build/bootloader/bootloader.bin
→ build/<app>.bin
[7] 수동 서명 (espsecure.py 사용)
├─ 부트로더 서명:
│ espsecure.py sign_data --version 2 --keyfile secure_boot_signing_key.pem \
│ --output bootloader-signed.bin build/bootloader/bootloader.bin
└─ 앱 서명:
espsecure.py sign_data --version 2 --keyfile secure_boot_signing_key.pem \
--output app-signed.bin build/<app>.bin
[8] 서명된 바이너리 펌웨어 라이팅 (Bootloader사이즈가 커지므로 파티션 테이블 size 조종 필요 할 수도)
└─ esptool.py -p <PORT> write_flash 0x0 bootloader-signed.bin ...
esptool.py -p <PORT> write_flash <app_offset> app-signed.bin
[9] 부팅 시 검증 절차
├─ ROM 부트로더 → 2단계 부트로더 서명 검증
└─ 2단계 부트로더 → 앱 서명 검증
→ 성공 시 정상 부팅
→ 실패 시 부팅 중단
기타 보안 적용 (efuse처리)
아래 추가 보안 사항을 적용 가능하다. (주의 : 적용이후에는 되돌릴 수 없으니, 적용전 주의 필요)
적용방법 : espefuse.py burn_efuse --port <PORT> EFUSE_NAME 0x1
예 : espefuse.py burn_efuse --port <PORT> HARD_DIS_JTAG 0x1
- HARD_DIS_JTAG
- JTAG 디버그 포트를 하드웨어적으로 완전히 차단
- 개발 단계에서는 JTAG로 디버깅 가능하지만, 출하 시에는 반드시 꺼서 역공학 방지
- 이 비트를 태우면 JTAG은 절대 다시 활성화 불가
- SOFT_DIS_JTAG
- 소프트웨어적으로 JTAG 접근 차단
- 펌웨어에서 제어 가능하지만, 보안상 HARD_DIS_JTAG와 함께 쓰는 것이 안전
- DIS_DIRECT_BOOT
- Direct Boot(레거시 SPI 부트 모드) 비활성화
- 공격자가 특정 부트 모드로 진입해 보안 검증을 우회하는 것을 방지
- DIS_USB_JTAG
- USB 포트를 JTAG 모드로 전환하는 기능 차단
- USB를 통한 디버그 접근 방지
- SECURE_BOOT_AGGRESSIVE_REVOKE
- 공격적 키 폐기 모드 활성화
- 부팅 시 서명 검증이 실패하면 해당 키를 즉시 eFuse에서 폐기
- 물리적 공격 방어에 강력하지만, 모든 키가 폐기되면 기기가 영구적으로 부팅 불가(벽돌) 위험 있음
추가 : 사용하지 않는 Digest slot 폐기
ESP32는 3개의 Digest slot(공개키 HASH값 저장)이 있는데, 사용하지 않는 Disget slot를 폐기하여 영구히 사용을 못하게 한다.
반드시 사용하지 않는 Slot만 폐기 한다.
espefuse.py --port <PORT> --chip esp32s3 burn_efuse EFUSE_REVOKE_BIT
- <PORT> : 연결된 시리얼 포트 (예: /dev/ttyUSB0 또는 COM3)
- --chip esp32s3 : 칩 종류 지정 (ESP32-C6도 동일 형식 사용)
- EFUSE_REVOKE_BIT : 폐기할 Digest 슬롯에 해당하는 eFuse 비트
- SECURE_BOOT_KEY_REVOKE0 → Digest 슬롯 #0 폐기
- SECURE_BOOT_KEY_REVOKE1 → Digest 슬롯 #1 폐기
- SECURE_BOOT_KEY_REVOKE2 → Digest 슬롯 #2 폐기
메뉴컨피그에서 CONFIG_SECURE_BOOT_ALLOW_UNUSED_DIGEST_SLOTS 설정시 자동 폐기 된다.
(주) 아이디케이 테크놀러지
ESPRESSIF 한국 공식 대리점
문의메일 : INFO@IDKTECH.CO.KR
'ESPRESSIF' 카테고리의 다른 글
| Espressif SoC에서 FPU(Floating Point Unit, 부동소수점 연산 장치)에 대하여 (0) | 2025.11.11 |
|---|---|
| ESP32 - ENABLE_SECURITY_DOWNLOAD eFuse의 역할 (0) | 2025.09.19 |
| [ESP32] 3종 제품 비교, ESP32-S3, ESP32-C3, ESP32-C5 (0) | 2025.09.05 |
| ESP32 IDF 기반 펌웨어 개발을 위한 주요 강좌 소개 (0) | 2025.09.05 |
| [ESP32] 펌웨어(Firmware) 라이팅 - 하드웨어 기본 연결 (0) | 2025.09.05 |








