콘텐츠로 이동

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 펌웨어 팀이 구현에 착수할 수 있는 수준의 상세도를 제공한다.


관련 문서