Debug authorization: 개발 때 열었던 접근을 배포 뒤에도 허용할까
debug 연결이 가능하다는 사실과 그 연결로 원하는 모든 작업을 해도 된다는 사실은 다르다. 프로세서를 멈추거나 메모리를 읽고 쓰는 기능은 개발에 유용하지만, 배포된 칩의 비밀과 실행 상태에도 접근할 수 있다. Debug authorization은 누가, 어떤 상태에서, 어떤 관측과 변경을 할 수 있는지를 정하는 문제다.
관측과 변경을 같은 권한으로 묶지 않는다
공개 상태 레지스터를 읽는 것과 내부 메모리 전체를 읽는 것은 접근하는 정보가 다르다. 실행 중인 프로세서를 멈추거나 메모리를 바꾸는 기능은 상태의 관측을 넘어 시스템 동작을 바꾼다. 개발 단계에서 편리했던 한 개의 debug enable이 배포 이후에도 적절한 정책인지 따져 봐야 한다.
OpenTitan의 life cycle 문서는 DFT_EN, NVM_DEBUG_EN, HW_DEBUG_EN을 나눠 설명한다. 특히 비휘발성 메모리의 debug 경로가 일반 보호를 우회할 수 있는 경우와 프로세서 TAP의 접근을 구분한다. 외부 연결의 존재보다 실제로 어떤 기능을 열어 주는지가 중요하다는 구현 사례다. OpenTitan Life Cycle의 debug 제어
이 신호들의 존재가 모든 제품에 같은 정책을 적용한다는 뜻은 아니다. 각 칩이 저장하는 자산과 수리·개발 요구에 맞춰 허용 상태와 경로를 정해야 한다. 기능 이름이 같더라도 우회하는 보호 범위가 다를 수 있다.
한 개의 인증 결과 대신 요청의 조건을 계산한다
가상 정책에서 내부 메모리 변경 허용을 네 조건의 AND로 정의하자. 현재 life cycle 상태가 변경을 허용하고, debug 세션이 인증됐고, 요청한 연산이 허용됐고, 대상 주소가 허용 범위여야 한다. 이 회로의 조건은 실제 OpenTitan의 신호 식이 아니라 정책을 분리해 보는 예제다.
네 조건을 [상태,세션,연산,주소]로 적으면 [1,1,1,1]만 허용한다. 다른 15개 조합은 거부한다. 예를 들어 인증된 개발자가 잘못된 주소를 쓰는 [1,1,1,0]과, 올바른 주소를 가리키지만 세션이 인증되지 않은 [1,0,1,1]은 서로 다른 이유로 거부된다. ‘인증을 통과했다’는 하나의 결과가 이후 모든 작업을 승인하지 않는다.
정책이 공개 상태 읽기를 별도로 허용한다면 그 연산에는 다른 조건을 사용할 수 있다. 그러나 그런 예외가 내부 메모리 읽기나 변경까지 넓어지지 않도록 대상과 연산을 명확히 구분해야 한다. 정상 동작의 error 응답이나 trace에 민감한 값이 포함되는지도 접근 범위의 일부다.
상태가 바뀌면 과거의 허용도 다시 읽는다
가상 장치가 개발 상태에서 debug 허용을 한 번 latch해 두고, 배포 상태로 바뀌어도 그 latch를 유지한다고 하자. 이후 요청은 이전 허용값 1을 사용할 수 있다. 현재 상태에 따라 닫혀야 하는 정책을 세션 시작 시점에만 확인한 것이다.
현재 상태를 요청마다 적용하거나 상태 변경 시 세션과 허용값을 폐기하는 방법을 설계할 수 있다. 어느 쪽이든 상태 변경의 순서, 이미 수락한 요청, reset 이후의 값까지 확인해야 한다. 새로운 상태가 확정되기 전에 민감한 접근이 열리는 구간이 없는지도 질문에 포함된다.
OpenTitan 문서는 life cycle 전이 요청 후 decoded output을 비활성화하고 재부팅을 기대하는 처리를 설명한다. 이 구체적인 설계를 모든 칩에 그대로 복사할 필요는 없지만, 상태 전이와 접근 제어를 연결해 정하는 사례로 읽을 수 있다.
수리 접근에서 이전 자산을 함께 생각한다
수리 모드에서 넓은 debug를 허용하려면 어떤 데이터가 남는지도 정책에 들어간다. 가상 정책으로 ‘이전 비밀 자산을 제거했다고 확인한 뒤 수리 접근을 연다’고 정했다면, 제거 확인과 실제 접근 허용을 함께 검증해야 한다. 표시 비트만 바뀌고 실제 저장소가 남는 경우는 그 정책을 만족하지 않는다.
접근 거부 검사도 필요하다. 허용된 개발 세션이 잘 동작하는 것만 확인하면 배포 상태나 잘못된 대상의 거부 경로를 놓칠 수 있다. 각 조건을 하나씩 거짓으로 만드는 요청, 상태 변경 전후의 요청, reset과 연결 종료 뒤의 요청을 나눠 확인할 수 있다.
Debug authorization의 핵심은 연결을 켜거나 끄는 버튼 하나가 아니다. 주체·현재 상태·연산·대상을 명시하고 실제 수행 시점까지 조건을 유지하는 것이다. 이 연결을 갖춰야 개발과 수리의 편의를 제공하면서도 배포된 장치가 어떤 경계를 지키는지 설명할 수 있다.