v0.5
엔터프라이즈 펌웨어 요구사항¶
1. Approval Signing Applet 요구사항¶
1.1. 개요¶
Approval Signing Applet은 개인 서명 기기(Zone 3+)의 SE 내부에서 실행되는 엔터프라이즈 전용 애플릿이다. Phase 24-03에서 정의한 NFC APDU 7개 명령(INS 0x50~0x71)을 펌웨어 수준의 요구사항으로 구체화한다.
책임 범위: - approval_sk 키 생성, 보관, 서명 실행 - ApprovalRequest 수신 및 WYSIWYS 표시 - 생체/PIN 인증 후 ECDSA secp256k1 승인 서명 생성 - 키 라이프사이클(생성/등록/폐기) 관리
1.2. NFC APDU 명령 상세¶
1.2.1. APPROVAL_REQ (INS 0x50) — 승인 요청 수신¶
| 필드 | 값 | 설명 |
|---|---|---|
| CLA | 0x80 | 독점(proprietary) 클래스 |
| INS | 0x50 | 승인 요청 수신 |
| P1 | 0x00=BTC, 0x01=EVM | 체인 유형 구분 |
| P2 | 0x00=단일 APDU, 0x01~0xFF=청크 시퀀스 번호 | 다중 청크 전송 시 사용 |
| Lc | 가변 | 입력 데이터 길이 |
| Data | ApprovalRequest CBOR 인코딩 | UR type 45050 데이터 (tx_hash + 메타데이터) |
| Le | 0x00 | 응답 없음 (상태 워드만 반환) |
입력 데이터 포맷 (ApprovalRequest CBOR):
approval-request = {
1: bytes .size 32, ; tx_hash: PSBT sighash(BTC) 또는 safeTxHash(EVM)
2: text, ; policy_id: 적용 정책 ID
3: quorum, ; quorum: 정족수 정보 (required, total)
? 4: uint, ; chain_id: EVM 전용
5: display-metadata, ; WYSIWYS 표시용 메타데이터
6: bytes .size 16, ; request_id: 승인 요청 고유 ID
7: uint, ; timestamp: 요청 생성 시간
}
display-metadata = {
1: text, ; to_address: 수신 주소 (전체 표시용)
2: bytes, ; amount: 전송 금액 (빅엔디안 정수)
3: text, ; amount_unit: 단위 ("BTC", "ETH", "USDT" 등)
4: bytes, ; fee: 수수료
5: text, ; fee_unit: 수수료 단위
? 6: uint, ; operation: EVM 전용 (0=call, 1=delegatecall)
? 7: bytes .size 4, ; function_selector: EVM 전용
? 8: text, ; function_name: 알려진 컨트랙트 함수명
9: text, ; chain_name: 체인 이름 ("Bitcoin", "Ethereum" 등)
}
응답 상태 워드 (SW1/SW2):
| SW | 의미 | 설명 |
|---|---|---|
| 0x9000 | SUCCESS | 요청 수신 완료, WYSIWYS 표시 시작 |
| 0x6A80 | WRONG_DATA | CBOR 디코딩 실패 또는 필수 필드 누락 |
| 0x6A82 | FILE_NOT_FOUND | approval_sk 미생성 상태 |
| 0x6985 | CONDITIONS_NOT_SATISFIED | 카드 타입 금액 한도 초과 (디스플레이 없는 기기) |
| 0x6986 | COMMAND_NOT_ALLOWED | delegatecall TX를 카드 타입에서 시도 |
| 0x6D00 | INS_NOT_SUPPORTED | 지원하지 않는 P1 체인 유형 |
1.2.2. APPROVAL_RESP (INS 0x51) — 승인 서명 반환¶
| 필드 | 값 | 설명 |
|---|---|---|
| CLA | 0x80 | 독점 클래스 |
| INS | 0x51 | 승인 서명 요청 |
| P1 | 0x00 | 예약 |
| P2 | 0x00 | 예약 |
| Lc | 0x00 | 입력 데이터 없음 |
| Le | 0x00 | 최대 길이 응답 요청 |
인증 필요: 예 — 생체(지문) 또는 PIN 인증 완료 후에만 서명 생성 및 반환.
응답 데이터 포맷 (ApprovalResponse CBOR):
approval-response = {
1: bytes .size 33, ; pubkey: approval_pk (compressed)
2: bytes .size (64..65), ; sig: ECDSA 서명 (BTC 64바이트 r||s, EVM 65바이트 r||s||v)
3: text, ; device_id: 기기 고유 식별자
4: uint, ; timestamp: 서명 생성 시간 (SE 내부 RTC)
5: bytes .size 16, ; request_id: 원본 승인 요청 ID (바인딩)
}
응답 상태 워드:
| SW | 의미 | 설명 |
|---|---|---|
| 0x9000 | SUCCESS | 서명 생성 및 반환 완료 |
| 0x6300 | AUTH_FAILED | 생체/PIN 인증 실패 |
| 0x6982 | SECURITY_NOT_SATISFIED | 인증 미수행 상태에서 호출 |
| 0x6985 | CONDITIONS_NOT_SATISFIED | WYSIWYS 사용자 거부(REJECT 버튼) |
| 0x6A88 | REFERENCED_DATA_NOT_FOUND | 활성 ApprovalRequest 없음 (0x50 미수신 상태) |
| 0x6983 | AUTH_BLOCKED | 인증 실패 횟수 초과로 잠금 |
1.2.3. DEVICE_REGISTER (INS 0x60) — 기기 등록¶
| 필드 | 값 | 설명 |
|---|---|---|
| CLA | 0x80 | 독점 클래스 |
| INS | 0x60 | 기기 등록 |
| P1 | 0x00 | 예약 |
| P2 | 0x00 | 예약 |
| Lc | 0x00 | 입력 없음 |
| Le | 0x00 | 최대 응답 |
인증 필요: 예 — 기기 소유자 인증 후 실행.
응답 데이터:
device-registration = {
1: bytes .size 33, ; pubkey: approval_pk (compressed)
2: text, ; device_id: 기기 고유 식별자
3: bytes, ; attestation_cert: SE attestation 인증서 체인
4: uint, ; key_index: 현재 활성 키 인덱스
5: uint, ; generated_at: 키 생성 타임스탬프
}
1.2.4. DEVICE_DEREGISTER (INS 0x61) — 기기 해제(키 폐기)¶
| 필드 | 값 | 설명 |
|---|---|---|
| CLA | 0x80 | 독점 클래스 |
| INS | 0x61 | 기기 해제 |
| P1 | 0x00=정상 폐기, 0x01=긴급 폐기 | 폐기 유형 |
| P2 | 0x00 | 예약 |
| Lc | 가변 | 폐기 인증 데이터 |
| Data | 듀얼 인증 토큰 (Admin + 기기 소유자) | |
| Le | 0x00 |
인증 필요: 예 — 듀얼 인증 (기기 소유자 생체 + Admin 승인 토큰).
응답 상태 워드:
| SW | 의미 | 설명 |
|---|---|---|
| 0x9000 | SUCCESS | 키 소거 완료, 기기 INACTIVE 상태 전환 |
| 0x6982 | SECURITY_NOT_SATISFIED | 듀얼 인증 실패 |
| 0x6A82 | FILE_NOT_FOUND | 이미 폐기된 상태 |
1.2.5. DEVICE_STATUS (INS 0x62) — 기기 상태 조회¶
| 필드 | 값 | 설명 |
|---|---|---|
| CLA | 0x80 | 독점 클래스 |
| INS | 0x62 | 상태 조회 |
| P1 | 0x00 | 예약 |
| P2 | 0x00 | 예약 |
| Lc | 0x00 | 입력 없음 |
| Le | 0x00 | 최대 응답 |
인증 필요: 아니오 — 상태 정보는 공개 가능.
응답 데이터:
device-status = {
1: text, ; device_id
2: uint, ; key_status: 0x00=미생성, 0x01=활성, 0x02=비활성, 0x03=폐기
3: uint, ; battery_percent: 배터리 잔량 (0-100, 카드 타입은 0xFF)
4: uint, ; firmware_version: 펌웨어 버전 (major.minor.patch 인코딩)
5: uint, ; approval_count: 누적 승인 횟수
6: uint, ; last_approval_at: 마지막 승인 타임스탬프
7: uint, ; auth_fail_count: 현재 연속 인증 실패 횟수
8: bool, ; is_locked: 잠금 상태 여부
}
1.2.6. KEY_GENERATE (INS 0x70) — 키 생성¶
| 필드 | 값 | 설명 |
|---|---|---|
| CLA | 0x80 | 독점 클래스 |
| INS | 0x70 | 키 생성 |
| P1 | 0x00=신규 생성, 0x01=교체 생성 | 생성 유형 |
| P2 | 0x00 | 예약 |
| Lc | 가변 | 듀얼 인증 토큰 |
| Data | Admin 승인 토큰 + 기기 소유자 인증 | |
| Le | 0x00 |
인증 필요: 예 — 듀얼 인증 (키 생성은 보안 민감 작업).
처리 흐름:
1. 듀얼 인증 검증
2. SE TRNG으로 256비트 엔트로피 생성
3. secp256k1 개인 키 유도 (approval_sk)
4. 공개 키 계산 (approval_pk = approval_sk * G)
5. 키 ID 생성: {device_id}_{key_index}_{timestamp}
6. NVM에 저장 (exportable=false)
7. P1=0x01(교체)인 경우: 기존 키 비활성화 후 신규 키 활성화
응답 상태 워드:
| SW | 의미 | 설명 |
|---|---|---|
| 0x9000 | SUCCESS | 키 생성 완료 |
| 0x6982 | SECURITY_NOT_SATISFIED | 듀얼 인증 실패 |
| 0x6A84 | NOT_ENOUGH_MEMORY | SE NVM 용량 부족 |
| 0x6985 | CONDITIONS_NOT_SATISFIED | 기존 활성 키 존재 시 P1=0x00 거부 (교체 0x01 사용 필요) |
1.2.7. KEY_EXPORT_PUB (INS 0x71) — 공개 키 내보내기¶
| 필드 | 값 | 설명 |
|---|---|---|
| CLA | 0x80 | 독점 클래스 |
| INS | 0x71 | 공개 키 내보내기 |
| P1 | 0x00=현재 활성 키, 0x01=키 인덱스 지정 | |
| P2 | 키 인덱스 (P1=0x01일 때) | |
| Lc | 0x00 | 입력 없음 |
| Le | 0x00 | 최대 응답 |
인증 필요: 아니오 — 공개 키는 공개 정보.
응답 데이터:
public-key-export = {
1: bytes .size 33, ; pubkey: approval_pk (compressed secp256k1)
2: text, ; key_id: 키 식별자
3: uint, ; key_index: 키 인덱스
4: uint, ; generated_at: 키 생성 타임스탬프
5: uint, ; key_status: 0x01=활성, 0x02=비활성
}
1.3. SE 내부 처리 흐름¶
승인 요청 수신부터 서명 반환까지의 SE 내부 처리 파이프라인:
입력: ApprovalRequest (INS 0x50)
│
▼
[1] CBOR 디코딩
│ - approval-request 스키마 유효성 검증
│ - 필수 필드(tx_hash, policy_id, quorum, display-metadata) 존재 확인
│ - P1(체인 유형)과 chain_id 일관성 확인
│
▼
[2] 기기 정책 검증
│ - 카드 타입(디스플레이 없음): 금액 한도 확인
│ - delegatecall(operation=1): 카드 타입 차단
│ - 미지 컨트랙트 고액 TX: 모든 기기 차단
│
▼
[3] WYSIWYS 디스플레이 렌더링
│ - 수신 주소, 전송 금액, 수수료, 체인 이름 표시
│ - EVM: function_name/selector, operation 경고 표시
│ - 카드 타입: WYSIWYS 단계 스킵 (저액/비금전만 도달)
│
▼
[4] 사용자 물리 확인 대기
│ - APPROVE 버튼: 다음 단계 진행
│ - REJECT 버튼: SW 0x6985 반환, 상태 IDLE 복귀
│ - 타임아웃(60초): 상태 IDLE 복귀
│
▼
[5] 생체/PIN 인증 (INS 0x51 수신 시)
│ - 지문 센서 활성화 또는 PIN 입력 대기
│ - 인증 성공: 다음 단계
│ - 인증 실패: 실패 카운터 증가, 잠금 정책 확인
│
▼
[6] ECDSA secp256k1 서명 생성
│ - sig = ECDSA_Sign(approval_sk, tx_hash)
│ - BTC: 64바이트 compact (r || s)
│ - EVM: 65바이트 (r || s || v)
│
▼
[7] 감사 로그 기록
│ - {request_id, tx_hash, timestamp, result, device_id}
│ - SE NVM에 최근 50건 순환 저장
│
▼
출력: ApprovalResponse (INS 0x51 응답)
1.4. 상태 머신¶
INS 0x50
(요청 수신 성공)
┌────────┐ ─────────────────▶ ┌──────────────────┐
│ IDLE │ │ BUNDLE_RECEIVED │
│ │ ◀──── 타임아웃 ──── │ │
└────────┘ (120초, 리셋) └────────┬─────────┘
▲ │
│ 기기 정책 검증 통과
│ │
│ ▼
│ ┌──────────────────┐
│── 타임아웃(60초) ────── │ VERIFIED │
│ 또는 REJECT │ (정책 검증 완료) │
│ └────────┬─────────┘
│ │
│ WYSIWYS 렌더링 완료
│ │
│ ▼
│ ┌──────────────────┐
│── 타임아웃(60초) ────── │ DISPLAYED │
│ 또는 REJECT │ (화면 표시 완료) │
│ └────────┬─────────┘
│ │
│ APPROVE 버튼
│ + INS 0x51 수신
│ │
│ ▼
│ ┌──────────────────┐
│── 인증 실패(잠금) ───── │ AUTHENTICATED │
│ │ (인증 완료) │
│ └────────┬─────────┘
│ │
│ 서명 생성 완료
│ │
│ ▼
│ ┌──────────────────┐
└──── 자동 복귀 ────────── │ SIGNED │
│ (서명 반환 완료) │
└──────────────────┘
1.5. 타임아웃 정책¶
| 상태 전이 | 최대 대기 시간 | 타임아웃 동작 | 근거 |
|---|---|---|---|
| IDLE → BUNDLE_RECEIVED | 120초 (APDU 청크 전송 완료 대기) | 수신 버퍼 클리어, IDLE 복귀 | 불완전 전송 방지 |
| BUNDLE_RECEIVED → VERIFIED | 5초 (내부 처리) | IDLE 복귀, SW 0x6F00 반환 | SE 처리 이상 감지 |
| VERIFIED → DISPLAYED | 2초 (렌더링) | IDLE 복귀 | 렌더링 실패 감지 |
| DISPLAYED → AUTHENTICATED | 60초 (사용자 확인 + 인증) | IDLE 복귀, 세션 폐기 | 방치된 기기 보호 |
| AUTHENTICATED → SIGNED | 3초 (서명 생성) | IDLE 복귀, 에러 로그 | 서명 연산 이상 감지 |
| 전체 세션 | 180초 (3분) | 강제 IDLE 복귀 | 단일 승인 세션 최대 수명 |
1.6. 메모리 요구사항¶
| 항목 | 크기 | 영역 | 설명 |
|---|---|---|---|
| approval_sk (개인 키) | 32 바이트 | NVM (보호) | ECDSA secp256k1 개인 키 |
| approval_pk (공개 키) | 33 바이트 | NVM | compressed 공개 키 |
| 키 메타데이터 | 64 바이트 | NVM | key_id, key_index, generated_at, status |
| 기기 설정 | 128 바이트 | NVM | 인증 정책, 금액 한도, 허용 체인 목록 |
| 감사 로그 (50건) | 2,500 바이트 | NVM | 50 x 50바이트 (순환 버퍼) |
| ApprovalRequest 버퍼 | 1,024 바이트 | RAM | 수신 중인 요청 데이터 임시 저장 |
| ECDSA 연산 작업 공간 | 512 바이트 | RAM | 서명 생성 중간 값 |
| CBOR 파서 버퍼 | 512 바이트 | RAM | CBOR 디코딩 작업 공간 |
| NVM 합계 | ~2.8 KB | NVM | 최소 4KB NVM 요구 (여유 포함) |
| RAM 합계 | ~2.0 KB | RAM | 일반 SE RAM(4~8KB) 이내 |
| ApprovalBundle 최대 크기 | 1,024 바이트 | 7-of-11 기준 최대 (11 x 서명 ~80바이트 + 헤더) |
2. 통신 프로토콜 요구사항¶
2.1. NFC APDU (필수)¶
| 항목 | 요구사항 | 등급 |
|---|---|---|
| 표준 준수 | ISO 7816-4 APDU 구조 | MUST |
| CLA 바이트 | 0x80 (독점 애플리케이션) | MUST |
| Short APDU | Lc/Le 최대 255바이트 | MUST |
| Extended APDU | Lc/Le 최대 65,535바이트 | SHOULD |
| APDU Chaining | CLA bit 5 = 1 (chaining 비트) | MUST |
| 통신 속도 | NFC ISO 14443 106~424 kbps | MUST |
| 최대 응답 시간 | 단일 APDU: < 500ms, 서명 포함: < 2,000ms | SHOULD |
| 세션 관리 | SELECT 명령(0xA4)으로 Applet 선택 후 명령 수행 | MUST |
| AID (Application ID) | D'CENT 엔터프라이즈 전용 AID 할당 | MUST |
다중 청크 전송 프로토콜 (ApprovalRequest > 255바이트 시):
전송 흐름 (3청크 예시):
Host → SE: INS 0x50, P2=0x01, Data=chunk_1 (255B) → SW 0x9000
Host → SE: INS 0x50, P2=0x02, Data=chunk_2 (255B) → SW 0x9000
Host → SE: INS 0x50, P2=0x00, Data=chunk_3 (잔여) → SW 0x9000 (수신 완료)
P2=0x00: 마지막 청크 (또는 단일 APDU)
P2=0x01~0xFF: 청크 시퀀스 번호 (순차 증가)
에러 처리:
- 청크 순서 오류: SW 0x6A86 (WRONG_P1P2)
- 전체 크기 초과(1,024B): SW 0x6A84 (NOT_ENOUGH_MEMORY)
- 청크 타임아웃(120초 내 완료 필요): 버퍼 클리어
2.2. QR UR (권장)¶
| 항목 | 요구사항 | 등급 |
|---|---|---|
| UR type 지원 | dcent-approval-request (45050), dcent-approval-response (45051), dcent-approval-bundle (45052) | SHOULD |
| UR 인코딩 | BC-UR v2 Bytewords 인코딩 | SHOULD |
| QR 생성 | UR 데이터를 QR 코드로 렌더링 (디스플레이 기기) | SHOULD |
| QR 스캔 | 카메라로 QR 코드 디코딩 (D'CENT X만 해당) | MAY |
| Animated QR | UR v2 멀티파트 시퀀스 (프레임 분할) | MAY |
| Animated QR 프레임 크기 | 최대 300바이트/프레임 (QR 밀도 최적화) | SHOULD |
| Animated QR 프레임 속도 | 4~8 FPS (카메라 디코딩 안정성) | SHOULD |
Phase 27 연계 기초 요구사항: - Animated QR 배치 전송 프레임워크는 Phase 27(MuSig2 QR 최적화)에서 상세 설계 - 본 요구사항은 기기 레벨의 QR 인코딩/디코딩 기초 역량만 정의
2.3. USB-C (선택)¶
| 항목 | 요구사항 | 등급 |
|---|---|---|
| 충전 | USB-C PD/BC 충전 지원 | SHOULD |
| 펌웨어 업데이트 | USB-C 경유 서명된 펌웨어 전송 | MAY |
| 디버그/로그 | 개발 빌드에서만 활성화, 프로덕션 비활성화 | MAY |
| 승인 데이터 전송 | USB-C로 ApprovalRequest/Response 전달 | MAY |
| USB 데이터 비활성화 | 엔터프라이즈 정책으로 USB 데이터 전송 비활성화 가능 | SHOULD |
USB-C 경유 승인 데이터 전송은 NFC 인프라가 없는 환경의 폴백 수단이다. 에어갭 엄격 모드에서는 USB 데이터를 비활성화하고 NFC/QR만 사용할 수 있다.
2.4. BLE — 비활성화 필수¶
| 항목 | 요구사항 | 등급 | 근거 |
|---|---|---|---|
| BLE 스택 비활성화 | 엔터프라이즈 펌웨어에서 BLE 프로토콜 스택 완전 비활성화 | MUST | CCSS Level 2/3 에어갭 요건 |
| BLE 하드웨어 비활성화 | BLE 라디오 모듈 전원 차단 (가능한 경우) | SHOULD | 소프트웨어 우회 공격 방어 |
| 엔터프라이즈 펌웨어 분리 | 소비자용(BLE 활성) / 엔터프라이즈용(BLE 비활성) 빌드 분리 | MUST | 동일 기기에서 BLE 재활성화 방지 |
| BLE 재활성화 차단 | 펌웨어 업데이트로 BLE 재활성화 불가 (anti-rollback) | MUST | 다운그레이드 공격으로 BLE 복원 방지 |
CCSS 에어갭 근거: - CCSS Level 2: "키 저장 시스템은 인터넷 연결이 불가능해야 한다" - CCSS Level 3: "키 저장 시스템은 네트워크 연결이 물리적으로 불가능해야 한다" - BLE는 무선 네트워크 연결로 분류되며, 활성화 시 CCSS Level 2 이상 인증 실격 사유
3. 보안 요구사항¶
3.1. SE 보안¶
| 항목 | 요구사항 | 등급 | 근거 |
|---|---|---|---|
| 키 비추출 | approval_sk의 SE 외부 읽기/전송 원천 차단 (exportable=false) | MUST | 키 유출 원천 방지 |
| DPA 방어 | Differential Power Analysis 방어 회로 | MUST | 전력 소비 패턴 분석 공격 차단 |
| SPA 방어 | Simple Power Analysis 방어 (상수 시간 연산) | MUST | 단순 전력 분석 공격 차단 |
| EMA 방어 | Electromagnetic Analysis 방어 | SHOULD | 전자기 방사 분석 공격 차단 |
| Fault injection 방어 | 전압 글리치/클럭 글리치 감지 | MUST | 의도적 오류 주입으로 키 추출 시도 방어 |
| 메모리 보호 | SE NVM 암호화, RAM 초기화 | MUST | 콜드 부트 공격, 메모리 덤프 방어 |
| 단조 카운터 | Monotonic counter (롤백 불가) | SHOULD | 재사용/롤백 공격 방어 |
| RTC (Real-Time Clock) | SE 내부 또는 외부 신뢰 시간원 | SHOULD | 타임스탬프 무결성, 타임아웃 정확성 |
3.2. 인증 보안¶
| 항목 | 요구사항 | 등급 | 근거 |
|---|---|---|---|
| 생체 인증 필수 | 서명 명령(0x51) 실행 전 지문 인증 | MUST | 비인가 서명 방지 |
| PIN 폴백 | 지문 인식 반복 실패 시 PIN 입력 허용 | SHOULD | 사용성 보장 (습기, 상처 등) |
| 인증 실패 카운터 | 연속 실패 횟수 SE 내부 관리 | MUST | 무차별 대입 감지 |
| 일시 잠금 | 연속 5회 실패 → 30초 잠금 (exponential backoff) | MUST | 자동화 무차별 대입 지연 |
| 영구 잠금 | 연속 10회 실패 → 키 소거(와이프) | MUST | 최종 방어선 — 기기 탈취 후 공격 차단 |
| 잠금 상태 조회 | DEVICE_STATUS(0x62)로 잠금 여부 확인 가능 | MUST | 사용자/관리자 상태 파악 |
| 인증 토큰 유효 시간 | 인증 성공 후 10초 이내 서명 명령 필요 | SHOULD | Relay 공격 윈도우 최소화 |
3.3. 펌웨어 무결성¶
| 항목 | 요구사항 | 등급 | 근거 |
|---|---|---|---|
| 서명된 펌웨어 | D'CENT 제조사 ECDSA/RSA 서명 검증 후에만 설치 | MUST | 악성 펌웨어 설치 방지 |
| Anti-rollback | 펌웨어 버전 단조 증가, 이전 버전 설치 차단 | MUST | 취약 버전 다운그레이드 공격 방어 |
| Secure Boot | 부트로더 → 펌웨어 서명 체인 검증 | MUST | 부트 과정 무결성 |
| 부트로더 잠금 | 프로덕션 기기 부트로더 수정 불가 | MUST | 부트로더 교체 공격 방어 |
| 펌웨어 해시 조회 | 현재 펌웨어 해시를 외부에서 조회 가능 | SHOULD | 무결성 원격 검증 |
| OTA 업데이트 비허용 | 무선 업데이트 불가 (USB-C 또는 NFC 직접 연결만) | MUST | 에어갭 원칙 유지 |
3.4. 물리적 보안¶
| 항목 | 요구사항 | 등급 | 근거 |
|---|---|---|---|
| Tamper detection | SE 접근 시도(물리적 오프닝) 감지 | MAY | 고보안 기관용. 감지 시 키 소거 |
| Tamper evidence | 기기 개봉 흔적이 외부에서 육안 확인 가능 | SHOULD | 물리적 변조 감지 |
| SE 칩 보호 | 에폭시 코팅 또는 메시 레이어 | MAY | SE 칩 직접 접근 방어 |
| 보안 라벨 | 기기 고유 시리얼 + 홀로그램 보안 라벨 | SHOULD | 위조 기기 구별 |
3.5. 감사 로깅¶
| 항목 | 요구사항 | 등급 | 근거 |
|---|---|---|---|
| 승인 이력 저장 | SE NVM에 최근 50건 순환 저장 | MUST | 감사 추적, 부인 방지 |
| 로그 포맷 | {request_id, tx_hash_prefix(8B), timestamp, result(승인/거부), device_id} | MUST | 최소 추적 정보 |
| 로그 항목 크기 | 50바이트/건 x 50건 = 2,500바이트 | MUST | NVM 용량 제약 내 |
| 로그 읽기 | 전용 APDU 명령 또는 DEVICE_STATUS 확장으로 조회 | SHOULD | 관리자 감사 수행 |
| 로그 변조 방지 | SE 내부에서만 기록, 외부 수정 불가 | MUST | 로그 무결성 |
| 로그 삭제 불가 | 로그는 순환만 가능, 명시적 삭제 불가 | MUST | 감사 증적 보존 |
설계 기준: zone3plus-security-architecture.md Approval Signing Applet NFC APDU 7개 명령 참조 참조: btc-implementation.md ApprovalBundle CBOR 스키마 및 Approval Verifier 검증 로직 보안 기준: CCSS Level 2/3 에어갭 요건, CC EAL5+ SE 보안 기준
관련 문서¶
- 개인 서명 기기 적합성 평가 및 최소 하드웨어 요구사항 -- 펌웨어 요구사항
- 개인 기기 키 5단계 라이프사이클 설계 -- 펌웨어 요구사항