v0.0
WYSIWYS 디스플레이 펌웨어 요구사항 명세서¶
1. Executive Summary¶
본 문서는 D'CENT X 콜드월렛의 WYSIWYS(What You See Is What You Sign) 디스플레이 기능에 대한 SE 펌웨어 구현 요구사항을 정의한다. Phase 4에서 설계한 WYSIWYS 검증 아키텍처(wysiwys-design.md)를 펌웨어 팀이 구현할 수 있는 수준의 상세 명세로 변환하며, FW-WYSIWYS- ID 체계로 요구사항을 관리한다.
핵심 기능: - 트랜잭션 파싱 엔진: PSBT, RLP/ABI, 토큰 매핑을 SE 내부에서 독립 수행 - 해시 비교 검증: SE 파싱 결과와 오프라인 앱 해시의 바이트 단위 비교 - 경고 레벨 체계: 4단계(NONE/INFO/CAUTION/CRITICAL) 화면 렌더링 - 디스플레이 렌더링: 다중 페이지 네비게이션, 주소 축약, 금액 포맷팅
설계 기반: - Phase 4 wysiwys-design.md — WYSIWYS 전체 설계 (파싱 범위, 표시 항목, 검증 플로우, 경고 체계) - Phase 5 firmware-signing-interface.md — WYSIWYS Applet 구조 - Phase 6 hardware-capability-assessment.md — 디스플레이/SE 리소스 제약
2. 트랜잭션 파싱 엔진 펌웨어 요구사항¶
2.1. PSBT 파싱 엔진¶
SE 내부에서 PSBT 바이너리를 독립적으로 파싱하여 WYSIWYS 표시용 데이터를 추출한다.
파싱 요구사항:
| 항목 | 구현 요구 | SE 리소스 | 비고 |
|---|---|---|---|
| PSBT Magic Bytes | 0x70736274FF 검증 |
5B 비교 | 무효 시 PARSE_ERROR |
| Global Map 파싱 | unsigned_tx, xpub 등 추출 | 스트리밍 | PSBTv0 |
| Input Map 파싱 (N개) | UTXO 참조, witness_utxo, BIP-32 경로 | 입력당 ~100B | 순차 파싱 후 해제 |
| Output Map 파싱 (M개) | scriptPubKey → 주소 변환, value | 출력당 ~60B | 수신자 목록 생성 |
| scriptPubKey 디코딩 | P2PKH, P2WPKH, P2TR 주소 생성 | ~200B 작업 | Bech32/Bech32m 인코딩 |
| Change Output 식별 | BIP-44/84/86 경로 매칭 | 키 파생 비교 | 자체 잔금 마킹 |
| 수수료 계산 | sum(inputs) - sum(outputs) | uint64 연산 | 비정상 수수료 감지 |
메모리 관리 (8KB 작업 메모리 내):
PSBT 스트리밍 파싱 메모리 레이아웃:
[0x0000 - 0x07FF] 파싱 버퍼 (2KB) — 현재 청크 디코딩 영역
[0x0800 - 0x0FFF] 수신자 목록 (2KB) — 최대 20명 x ~100B
[0x1000 - 0x17FF] 해시 컨텍스트 (2KB) — SHA-256 상태 + sighash 누적
[0x1800 - 0x1FFF] 메타데이터 (2KB) — UTXO 합계, 수수료, 체인 정보
대용량 PSBT 전략:
- 입력/출력을 순차 처리 후 즉시 해시 업데이트
- 전체 PSBT를 메모리에 유지하지 않음
- 수신자 20명 초과 시 → 서명 거부 + "수신자 초과" 경고
2.2. RLP/ABI 디코딩 엔진¶
EVM 트랜잭션의 RLP 인코딩과 calldata ABI를 SE 내부에서 디코딩한다.
RLP 디코딩:
| 필드 | 추출 | WYSIWYS 표시 |
|---|---|---|
| to | 20 bytes → EIP-55 체크섬 주소 | 수신 주소 |
| value | big-endian wei → ETH 변환 | 전송 금액 |
| data | calldata → ABI 디코딩 | 함수 호출 정보 |
| gasLimit | uint | 가스 한도 |
| maxFeePerGas | uint → Gwei 변환 | 최대 수수료 |
| maxPriorityFeePerGas | uint → Gwei 변환 | 우선 수수료 |
| chainId | uint → 네트워크명 매핑 | 체인 표시 |
| nonce | uint | 트랜잭션 번호 |
ABI 디코딩 (calldata):
ABI 디코딩 프로세스:
1. data 길이 확인: < 4B → 데이터 없음 (순수 전송)
2. 함수 셀렉터 추출: data[0:4]
3. SE 셀렉터 DB 조회:
- 매칭 → 파라미터 타입에 따라 디코딩
- 미매칭 → CAUTION 경고 레벨 설정
4. 파라미터 디코딩:
- 각 파라미터는 32B 경계 정렬
- address: 하위 20B 추출 + EIP-55 체크섬
- uint256: big-endian → 정수 변환
- bytes: offset 기반 동적 길이 추출
5. 중첩 인코딩 처리:
- multicall, batch 함수 등 중첩 calldata
- 최대 재귀 depth 3 제한 (SE 스택 보호)
2.3. 토큰 매핑 엔진¶
컨트랙트 주소에서 토큰 심볼과 decimals를 조회한다.
토큰 매핑 프로세스:
1. EVM 트랜잭션의 to 주소 추출
2. SE 토큰 DB에서 (chain_id, contract_address) 검색
- 발견 → {symbol, decimals} 반환
- 미발견 → {symbol: "???", decimals: 0} + "소수점 미확인" 경고
3. 금액 변환: uint256 → (amount / 10^decimals) 표시
4. 특수 처리:
- approve amount == type(uint256).max → "무제한 승인" 경고
- decimals 0 → raw uint256 표시 + 경고
2.4. Chain Parser Interface 구현¶
체인별 파서를 통합 관리하는 라우팅 레이어:
WYSIWYS Chain Router:
입력: chain_type, raw_tx_data
처리:
switch(chain_type):
case 0x00 (BTC): BTCParser.parse(raw_tx_data)
case 0x01 (EVM): EVMParser.parse(raw_tx_data)
default: RawHexDisplay(raw_tx_data) + CRITICAL 경고
출력: ParsedTransaction → DisplayPages[] 변환
3. 해시 비교 검증 펌웨어 요구사항¶
3.1. SE_PARSE_HASH 생성¶
SE가 트랜잭션을 독립 파싱한 결과에서 핵심 필드를 추출하여 해시를 생성한다.
정규화 규칙:
SE_PARSE_HASH 생성 알고리즘:
hash_input = ""
// 수신자 정규화 (Change 출력 제외)
for each recipient in parsed.recipients:
if recipient.is_change == false:
hash_input += normalize_address(recipient.address)
hash_input += uint256_to_bytes32(recipient.amount)
hash_input += asset_identifier(recipient.asset_type)
// 수수료 정규화
hash_input += uint256_to_bytes32(parsed.fee.amount)
// 체인 식별자
hash_input += uint32_to_bytes4(parsed.chain_id)
SE_PARSE_HASH = SHA-256(hash_input)
normalize_address 규칙:
BTC: scriptPubKey 바이너리 (Bech32 디코딩된 witness program)
EVM: 20 bytes 주소 (lowercase, 0x prefix 없음)
Tron: 21 bytes 주소 (hex)
asset_identifier 규칙:
네이티브 (BTC/ETH): bytes4(chain_id)
ERC-20: bytes20(contract_address)
3.2. APP_HASH 대조 로직¶
해시 비교 프로세스:
1. 오프라인 앱이 동일 정규화 규칙으로 생성한 APP_HASH(32B) 수신
2. SE 내부 SE_PARSE_HASH(32B)와 바이트 단위 비교
3. 비교 방식: constant-time comparison (타이밍 공격 방지)
- 전체 32바이트를 XOR 후 결과가 0인지 확인
- 불일치 바이트 위치를 외부에 노출하지 않음
4. 결과:
- 일치 → hash_match = true, 정상 WYSIWYS 플로우 진행
- 불일치 → hash_match = false, 해시 불일치 처리 진입
3.3. 해시 불일치 처리¶
해시 불일치는 중간자 공격(MITM) 또는 데이터 변조 가능성을 의미한다.
즉시 동작:
| 단계 | 동작 | 시간 |
|---|---|---|
| 1 | 서명 즉시 거부 — 사용자 선택 없이 자동 차단 | 즉시 |
| 2 | 보안 경고 화면 표시 — "트랜잭션 데이터 불일치 감지" | 5초 이상 (즉시 닫힘 방지) |
| 3 | 감사 이벤트 생성 — 불일치 상세를 SE 로그에 기록 | 즉시 |
| 4 | WYSIWYS_HASH_MISMATCH 에러 코드(0x30) 반환 | 경고 화면 후 |
| 5 | 불일치 카운터 증가 | 즉시 |
연속 불일치 카운터:
SE 불일치 카운터 관리:
mismatch_counter: uint8 // 연속 불일치 횟수
mismatch_lock: bool // 잠금 상태
lock_counter_start: uint32 // 잠금 시작 시 서명 카운터
서명 요청 수신 시:
if mismatch_lock == true:
if (current_counter - lock_counter_start) < LOCKOUT_THRESHOLD:
return WYSIWYS_LOCKOUT (0x32) // 24시간 잠금 근사
else:
mismatch_lock = false
mismatch_counter = 0
해시 비교 시:
if hash_mismatch:
mismatch_counter += 1
if mismatch_counter >= 3:
mismatch_lock = true
lock_counter_start = current_counter
return WYSIWYS_LOCKOUT (0x32)
else:
return WYSIWYS_HASH_MISMATCH (0x30)
else:
mismatch_counter = 0 // 성공 시 리셋
잠금 해제: 서명 카운터 기반 24시간 근사치 경과 후 자동 해제 (하루 평균 서명 수 기반 LOCKOUT_THRESHOLD 설정).
4. 경고 레벨 체계 펌웨어 요구사항¶
4.1. NONE — 일반 확인 화면¶
조건: 알려진 함수 + 정상 파싱 완료 + 이상 파라미터 없음
화면 렌더링:
┌──────────────────────────────┐
│ 트랜잭션 확인 │
│ │
│ 수신자: 0x742d35...f2bD14 │
│ 금액: 1,000.00 USDT │
│ 수수료: 0.003 ETH (~$9.50) │
│ 체인: Ethereum │
│ │
│ [거부] [승인] │
└──────────────────────────────┘
물리 버튼: 1회 — 승인 버튼 누름으로 서명 진행
4.2. INFO — 파라미터 경고¶
조건: 알려진 함수이나 비정상 파라미터 감지 (비정상 가스비, 큰 금액 등)
화면 렌더링:
┌──────────────────────────────┐
│ 트랜잭션 확인 │
│ │
│ 수신자: 0x742d35...f2bD14 │
│ 금액: 50,000.00 USDT │
│ 수수료: 0.15 ETH (~$450) │
│ 체인: Ethereum │
│ │
│ ⚠ 참고: 수수료가 높습니다 │
│ │
│ [거부] [승인] │
└──────────────────────────────┘
경고 조건 (INFO 트리거):
| 조건 | 기준 |
|---|---|
| 높은 가스비 | maxFeePerGas > 평균의 5배 (SE 내부 기준값) |
| 큰 금액 | 건당 한도의 50% 이상 |
| ERC-20 approve | 승인 금액 > 토큰 전송 금액의 10배 |
| 첫 전송 주소 | 화이트리스트에 있으나 과거 전송 이력 없음 |
물리 버튼: 1회
4.3. CAUTION — Unknown Contract Warning¶
조건: 함수 셀렉터가 SE DB에 미등록 (알 수 없는 컨트랙트 호출)
화면 렌더링:
┌──────────────────────────────┐
│ ⚠ 경고: 알 수 없는 컨트랙트 │
│ │
│ 컨트랙트: 0xAbCd...EfGh │
│ 함수: 0x12345678 │
│ 데이터: 128 bytes │
│ 금액: 0 ETH │
│ 수수료: 0.008 ETH │
│ │
│ 이 트랜잭션의 내용을 │
│ 완전히 파싱할 수 없습니다. │
│ │
│ [Raw 데이터 보기] │
│ │
│ [거부] (권장) [위험 승인] │
└──────────────────────────────┘
물리 버튼: 2회 — (1) 경고 확인 "위험 승인 버튼을 눌러 서명합니다" → (2) 최종 서명 승인
"Raw 데이터 보기" 선택 시: calldata 처음 256바이트를 Hex로 별도 페이지 표시
4.4. CRITICAL — 파싱 실패¶
조건: SE에서 트랜잭션 데이터 자체를 파싱할 수 없음 (미지원 체인, 손상된 데이터, 알 수 없는 인코딩)
화면 렌더링:
┌──────────────────────────────┐
│ ⛔ 트랜잭션 파싱 불가 │
│ │
│ 이 트랜잭션의 내용을 해석할 │
│ 수 없습니다. │
│ │
│ Raw 데이터: 0x02f901... │
│ 크기: 342 bytes │
│ │
│ 서명 시 의도치 않은 자산 │
│ 이동 위험이 있습니다. │
│ │
│ 서명을 거부할 것을 │
│ 강력히 권장합니다. │
│ │
│ [거부] (권장) [위험 승인] │
└──────────────────────────────┘
물리 버튼: 3회 순차 확인: 1. "경고를 인지하였습니까?" → 확인 2. "파싱 불가 트랜잭션 서명의 위험을 이해합니까?" → 확인 3. "최종 서명 승인" → 서명 진행
감사 로그: "파싱 불가 상태에서 사용자가 위험 승인" 기록
Admin 설정: "파싱 불가 트랜잭션 서명 금지" 옵션 → 활성화 시 CRITICAL 경고에서 위험 승인 버튼 비활성화 (거부만 가능)
4.5. 경고 레벨 판정 로직¶
경고 레벨 결정 플로우:
[1] 트랜잭션 파싱 시도
│
├─ 파싱 실패 → CRITICAL (섹션 4.4)
│
└─ 파싱 성공
│
[2] chain_type 확인
│
├─ BTC (PSBT):
│ └─ 항상 NONE (PSBT는 완전 파싱 가능)
│ 단, 비정상 수수료 시 → INFO
│
└─ EVM:
│
[3] calldata 확인
│
├─ data 없음 (순수 ETH 전송) → NONE
│
├─ 셀렉터 DB 매칭 → 파라미터 검증
│ ├─ 정상 → NONE
│ └─ 비정상 파라미터 → INFO
│
└─ 셀렉터 DB 미매칭 → CAUTION
5. 디스플레이 렌더링 펌웨어 요구사항¶
5.1. 화면 레이아웃¶
트랜잭션 확인 화면의 표준 레이아웃 (320x240px 기준):
화면 레이아웃 구조:
┌─────────────────────────────────┐
│ Title Bar (24px) │ 제목 + 페이지 표시
├─────────────────────────────────┤
│ │
│ Content Area (176px) │ 필드 목록 (label: value)
│ │
│ │
│ │
│ │
│ │
├─────────────────────────────────┤
│ Warning Area (0-24px) │ 경고 메시지 (해당 시)
├─────────────────────────────────┤
│ Button Area (16px) │ [거부] [승인] 또는 네비게이션
└─────────────────────────────────┘
5.2. 주소 축약 표시¶
체인별 축약 규칙:
| 체인 | 주소 길이 | 축약 규칙 | 예시 |
|---|---|---|---|
| BTC (Bech32) | 42-62자 | 앞 10자 + "..." + 뒤 6자 | bc1qxy2kgd...p4q0ssp |
| ETH (Hex) | 42자 | 앞 8자 + "..." + 뒤 6자 | 0x742d35...f2bD14 |
| Tron (Base58) | 34자 | 앞 8자 + "..." + 뒤 6자 | TR7NHqje...Lj6t |
"전체 보기" 모드:
전체 보기 전환:
1. 축약 표시 상태에서 네비게이션 버튼으로 "전체 보기" 선택
2. 주소 전체를 2-3줄로 줄바꿈 표시
0x742d35Cc6634C053
2925a3b844Bc9e759
5f2bD14
3. 다시 버튼 누르면 축약 표시로 복귀
5.3. 금액 표시¶
포맷 규칙:
| 규칙 | 예시 | 비고 |
|---|---|---|
| 천 단위 구분 | 1,000,000.50 USDT | 쉼표 구분자 |
| 소수점 최대 8자리 | 0.00000001 BTC (1 sat) | BTC 기준 |
| 단위 표시 | "1.5 ETH", "1,000 USDT" | 금액 뒤 자산 심볼 |
| 비정상 감지 | 수수료 > 전송액 → 경고 | INFO 레벨 |
| wei/satoshi 변환 | 자동 단위 변환 | 사용자 친화적 |
| 0 금액 | "0 ETH" (컨트랙트 호출 시) | 정상 동작 |
5.4. 다중 수신자 페이지 네비게이션¶
페이지 구성:
다중 수신자 트랜잭션 페이지 흐름:
[Page 1: 요약]
총 수신자: N명
총 금액: X.XX BTC
총 수수료: Y.YYYY BTC
◀ ▶ 네비게이션
[Page 2~N+1: 개별 수신자]
수신자 K/N:
주소: bc1qxy2...ssp
금액: Z.ZZ BTC
◀ ▶ 네비게이션
[Page N+2: 최종 확인]
총 금액: X.XX BTC + Y.YY 수수료
= 합계: Z.ZZ BTC
[거부] [승인] ← 이 페이지에서만 승인 가능
제약:
| 제약 | 값 | 동작 |
|---|---|---|
| 최대 수신자 수 | 20명 | 20명 초과 → 서명 거부 + "수신자 초과" 경고 |
| 자동 페이지 넘김 | 없음 | 사용자가 명시적으로 네비게이션 버튼 |
| 승인 가능 페이지 | 마지막 페이지만 | 모든 수신자 확인 보장 |
| 페이지 인덱스 | "K/N" 형식 | 현재 위치 표시 |
| 타임아웃 | 60초 (각 페이지 기준 아님, 전체 세션) | 타임아웃 시 CANCELLED_BY_TIMEOUT |
5.5. 폰트 요구사항¶
| 폰트 유형 | 용도 | 크기 | 메모리 |
|---|---|---|---|
| 영문/숫자 (ASCII) | 주소, 금액, 셀렉터 | 16-24px | ~2KB (비트맵) |
| 한글 (경고 메시지) | 경고 문구, 상태 메시지 | 16-20px | ~4KB (경고용 ~200자) |
| 특수 문자 | ⚠, ⛔, ◀, ▶ | 16-24px | ~0.5KB |
| Hex 폰트 | Raw 데이터 표시 | 12-16px (고정폭) | ~1KB |
폰트 저장: MCU Flash에 비트맵 폰트 저장 (SE 외부). SE는 표시 데이터만 생성하여 MCU에 전달.
6. WYSIWYS Applet 상세 요구사항 목록¶
Phase 4 wysiwys-design.md 섹션 6.1의 FW-WYSIWYS-01~10을 상세화하고, 추가 요구사항을 도출한다.
| ID | 요구사항명 | 상세 설명 | 우선순위 | SE 리소스 영향 | 테스트 기준 |
|---|---|---|---|---|---|
| FW-WYSIWYS-01 | PSBT 파싱 엔진 | BIP-174/370 PSBT 바이너리 디코딩, 입력/출력 추출, sighash 계산, 8KB 내 스트리밍 파싱 | 필수 | RAM 8KB | TC: 1/5/10 입력 PSBT 파싱 성공 |
| FW-WYSIWYS-02 | RLP/ABI 디코딩 엔진 | EVM TX RLP 디코딩(Type 0/1/2), calldata ABI 디코딩(셀렉터+파라미터), 중첩 depth 3 | 필수 | RAM 2KB | TC: ETH 전송, ERC-20 transfer, Safe execTx |
| FW-WYSIWYS-03 | 토큰 매핑 테이블 | 컨트랙트 주소 → 심볼/decimals 변환, 초기 5종, 최대 50개, 미등록 토큰 경고 | 필수 | 저장 2KB | TC: USDT/USDC 올바른 금액 표시 |
| FW-WYSIWYS-04 | 함수 셀렉터 DB | 셀렉터 4B → 함수 정보 조회, 초기 10종, 최대 256개, 위험도 분류 | 필수 | 저장 4KB | TC: transfer/approve/execTx 인식 |
| FW-WYSIWYS-05 | SHA-256 해시 비교 검증 | SE_PARSE_HASH 생성(정규화 규칙), APP_HASH 대조(constant-time), 결과 판정 | 필수 | RAM 256B | TC: 일치 → 성공, 불일치 → 0x30 에러 |
| FW-WYSIWYS-06 | 4단계 경고 레벨 렌더링 | NONE(1회)/INFO(1회)/CAUTION(2회)/CRITICAL(3회) 각 화면 레이아웃 및 버튼 입력 | 필수 | 디스플레이 | TC: 각 경고 레벨 화면 렌더링 확인 |
| FW-WYSIWYS-07 | 다중 페이지 네비게이션 | 요약→개별 수신자→최종 확인, 최대 20페이지, 마지막 페이지만 승인 | 필수 | RAM 40B (인덱스) | TC: 5 수신자 네비게이션 + 승인 |
| FW-WYSIWYS-08 | Chain Parser Interface | chain_id 기반 라우팅, parse/formatDisplay 인터페이스, 확장용 | 높음 | 인터페이스만 | TC: BTC/EVM 라우팅 동작 |
| FW-WYSIWYS-09 | 주소 축약/전체 표시 전환 | 체인별 축약 규칙(앞N+뒤M), 전체 보기 모드 전환, 줄바꿈 표시 | 높음 | RAM 64B | TC: 축약 ↔ 전체 전환 |
| FW-WYSIWYS-10 | 해시 불일치 자동 서명 거부 + 잠금 | 불일치 시 즉시 거부, 5초 경고 화면, 3회 연속 시 LOCKOUT(0x32), 카운터 기반 해제 | 필수 | 저장 8B (카운터) | TC: 3회 연속 불일치 → 잠금 |
| FW-WYSIWYS-11 | 금액 포맷팅 엔진 | 천 단위 구분, 소수점 변환(decimals), 단위 표시, wei/satoshi 자동 변환 | 필수 | RAM 128B | TC: 1000.50 USDT, 0.00001 BTC |
| FW-WYSIWYS-12 | EIP-55 체크섬 주소 생성 | EVM 주소의 mixed-case 체크섬 생성(keccak256 기반) | 필수 | RAM 64B | TC: 체크섬 일치 검증 |
| FW-WYSIWYS-13 | Bech32/Bech32m 주소 인코딩 | BTC SegWit/Taproot 주소 표시용 인코딩 | 필수 | RAM 128B | TC: bc1q.../bc1p... 정상 표시 |
| FW-WYSIWYS-14 | 경고 레벨 판정 로직 | 셀렉터 DB 조회 → 알려진 함수 NONE/INFO, 미등록 CAUTION, 파싱 실패 CRITICAL | 필수 | 로직만 | TC: 각 조건별 정확한 레벨 판정 |
| FW-WYSIWYS-15 | 세션 타임아웃 관리 | WYSIWYS 표시 후 60초 내 물리 버튼 미입력 시 CANCELLED_BY_TIMEOUT(0x11) | 필수 | 타이머 | TC: 60초 경과 → 타임아웃 |
| FW-WYSIWYS-16 | 감사 이벤트 생성 | 해시 불일치, 파싱 불가 위험 승인, 정책 위반 시 SE 로그 기록 | 높음 | 저장 ~512B (링 버퍼) | TC: 이벤트 기록 + 조회 |
| FW-WYSIWYS-17 | Raw Hex 표시 | 파싱 불가 시 처음 256바이트 Hex 표시, 고정폭 폰트, 스크롤 | 필수 | 디스플레이 | TC: 256B Hex 정상 표시 |
| FW-WYSIWYS-18 | Admin 파싱 불가 TX 금지 설정 | Admin 정책: "파싱 불가 TX 서명 금지" 활성화 시 CRITICAL 위험 승인 비활성화 | 높음 | 정책 1bit | TC: 설정 ON → 위험 승인 차단 |
| FW-WYSIWYS-19 | MuSig2 참여자 정보 표시 | BIP-373 필드에서 참여자 수, 현재 서명자 인덱스 표시 | 높음 | PSBT 확장 | TC: "다중 서명 2/3" 표시 |
| FW-WYSIWYS-20 | approve 무제한 승인 감지 | ERC-20 approve amount == MAX_UINT256 → "무제한 토큰 사용 승인 — 위험" 경고 | 필수 | 비교 로직 | TC: MAX_UINT256 → 경고 표시 |
7. 파싱 불가 트랜잭션 처리 요구사항¶
7.1. 미지원 체인¶
SE가 chain_type 필드로 인식할 수 없는 체인의 트랜잭션을 수신한 경우:
처리 흐름:
1. chain_type ∉ {0x00(BTC), 0x01(EVM)} → 파싱 불가 판정
2. CRITICAL 경고 화면 표시
3. 트랜잭션 바이너리의 처음 256바이트를 Raw Hex로 표시
4. 전체 바이트 수 표시 ("크기: XXX bytes")
5. "위험 승인" 시 물리 버튼 3회 절차
6. 감사 로그: "미지원 체인(chain_type=0x03) 위험 승인" 기록
7.2. 손상된 데이터¶
파싱 중 데이터 구조 오류(잘못된 RLP, 손상된 PSBT 등):
감지 조건:
- PSBT: magic bytes 불일치, 맵 키 순서 오류, 누락 필드
- RLP: 길이 필드 불일치, 리스트 깊이 초과, 잘린 데이터
- ABI: 파라미터 수 불일치, 오프셋 범위 초과
처리:
1. 파싱 에러 코드 생성 (PARSE_ERROR 0x41)
2. CRITICAL 경고 + 에러 상세 표시
3. "데이터 손상 가능성 — 서명 거부 권장"
4. 위험 승인 3회 절차 (Admin 설정 시 차단)
7.3. Admin 설정 — "파싱 불가 TX 서명 금지"¶
정책 설정:
SE_Policy_ParseRequired {
enabled: bool // true = 파싱 불가 TX 서명 차단
default: false // 초기값: 비활성화 (기업별 설정)
}
동작:
if parse_failed && SE_Policy_ParseRequired.enabled:
return WYSIWYS_PARSE_BLOCKED (0x33) // 위험 승인 옵션 없이 거부
else:
CRITICAL 경고 + 위험 승인 3회 절차 가능
변경:
Admin 쿼럼 서명 + 에어갭 정책 업데이트 + 물리 버튼 2회
본 문서는 Phase 6 Firmware Requirements의 두 번째 산출물(2/2)로, D'CENT X WYSIWYS 디스플레이 기능의 펌웨어 요구사항을 정의한다. Phase 4 wysiwys-design.md의 검증 아키텍처와 경고 체계를 펌웨어 구현 수준으로 변환하며, FW-WYSIWYS-01~20의 요구사항 ID 체계로 추적 가능하다. 해시 비교 검증의 정규화 규칙, 경고 레벨 판정 로직, 다중 페이지 네비게이션 등 SE 펌웨어 팀이 구현에 착수할 수 있는 수준의 상세도를 제공한다.
관련 문서¶
- D'CENT X 엔터프라이즈 펌웨어 팀 핸드오프 종합 요약서 -- 펌웨어 요구사항
- 펌웨어 업데이트 보안 메커니즘 설계서 -- 펌웨어 요구사항
- D'CENT X 하드웨어 역량 검증 및 제약사항 문서 -- 펌웨어 요구사항
- 엔터프라이즈 멀티체인 서명 펌웨어 요구사항 명세서 -- 펌웨어 요구사항