14.3.4. 플래시 읽기 보호에 관한 참고 사항¶
기본 상태에서 출하된 OpenMV cam의 펌웨어는 장치에 물리적으로 접근할 수 있는 사람이라면 누구나 읽을 수 있습니다. cam을 손에 넣은 공격자는 디버그 헤더에 SWD 프로브를 연결해 MCU의 디버그 인터페이스와 통신하고 플래시를 덤프할 수 있는데, 여기에는 동결된 모든 Python 모듈과 ROMFS 파티션의 내용이 포함됩니다. 기본 OpenMV 펌웨어는 플래시 읽기 보호를 기본적으로 활성화하지 않습니다.
이 페이지는 그 점을 명시적으로 문서화하여, 제품을 출하하는 팀이 책임이 어디에 있는지 알 수 있도록 합니다.
14.3.4.1. cam이 기본적으로 하는 일¶
cam의 부트로더와 런타임은 기반 MCU의 어떠한 읽기 보호 기능도 켜지 않습니다. 디버그 인터페이스는 열려 있고, 플래시는 읽을 수 있는 상태로 유지되며, 빌드는 개발자의 작업대에서 동작하던 방식 그대로 실행됩니다. 이는 튜토리얼 대상 독자에게 올바른 기본값입니다. 읽기 보호가 켜진 채로 출하되는 cam은 IDE를 통해 재플래시할 수 없고, 잘못된 배포 후에 다시 이미지를 씌울 수 없으며, 빌드 팀이 아니면 누구도 복구할 수 없는 cam입니다.
cam이 “개발자 장치”에서 “제품”으로 넘어가면 이 트레이드오프는 달라집니다. 가치가 애플리케이션 코드의 비공개 유지에 달려 있는 제품은 보호 기능을 스스로 활성화해야 하며, OpenMV 펌웨어는 이를 대신 해주지 않습니다.
14.3.4.2. 제품 팀이 하는 일¶
모든 MCU 벤더는 읽기 보호 메커니즘을 제공합니다. 세부 사항은 다릅니다. 비트 수준 퓨즈, 단방향 라이프사이클 전환, 서명된 플래시 이미지 등 다양하지만 공통적인 형태는 다음과 같습니다:
벤더 고유의 비트(또는 비트 집합)가 실리콘에 기록되는데, 보통은 MCU의 디버그 포트와 마지막으로 한 번 통신하는 벤더 도구를 통해 이루어집니다.
기록 이후 디버그 포트는 플래시 읽기를 거부합니다. cam은 여전히 부팅되고 애플리케이션을 실행합니다. 단지 그 내용을 더 이상 프로브에 노출하지 않을 뿐입니다.
이 기록은 되돌릴 수 없습니다. cam을 파괴하지 않고 다시 디버깅 가능한 상태로 되돌릴 방법은 없습니다.
이를 설정하는 일은 MCU에 따라 다르며, 단계는 보호 대상이 되는 cam의 부품에 따라 달라집니다. 벤더의 레퍼런스 매뉴얼이 진실의 원천이며, 생산 라인에서 이를 제대로 수행하려면 벤더 지원이 그 통로입니다.
이것은 쉬운 부분입니다.
어려운 부분은 공격자가 cam에서 코드를 실행하거나 애플리케이션이 무엇을 하는지 읽어낼 수 있는 다른 모든 경로를 닫는 것입니다. 읽기 보호는 디버그 프로브가 플래시를 덤프하는 것만 막을 뿐입니다. cam은 여전히 다음을 닫아야 합니다:
MicroPython REPL. USB로 연결된 REPL은 임의의 Python을 받아들입니다. 읽기 보호는 이를 바꾸지 않습니다. REPL 세션은 RAM을 읽고, 함수를 호출하며, 실행 중인 애플리케이션이 볼 수 있는 모든 것을 유출할 수 있습니다. 사실상 도달 가능한 REPL은 읽기 보호가 가져다주는 모든 것을 우회합니다. REPL 접근을 비활성화하는 것은 제품 팀이 책임지는 펌웨어 빌드 변경입니다.
IDE 스크립트 업로드. IDE의 “이 스크립트를 cam에서 실행” 경로는 REPL과 동일한 USB 프로토콜 표면을 사용합니다. REPL을 닫으면 이것도 함께 닫힙니다. 둘 중 하나라도 열어두면 cam으로 들어오는 임의 코드 실행 채널이 남게 됩니다.
파일 시스템에서 진입점 가로채기. 애플리케이션이 스크립트를 펌웨어에 프리징하기 를 통해 출하될 때 이미 닫혀 있습니다. 런타임은 모든 파일 시스템 복사본보다 먼저 동결된
boot.py와main.py를 확인하므로, 플래시나 SD에 떨어진 어떤 것도 이를 덮어쓸 수 없습니다. 이 보호는 애플리케이션이 빌드에 포함되면 무료로 얻어집니다.최신 cam의 외부 플래시. 애플리케이션 이미지를 외부 플래시에 저장하는 cam은 그 이미지를 PCB 위에 훤히 드러나 있는 칩에 둡니다. 그 칩은 시중에서 구할 수 있는 도구로 떼어내어 직접 읽거나, 버스를 프로빙해 그 자리에서 읽을 수 있습니다. 이를 보호하려면 읽기 중에 플래시 내용을 복호화하는 온칩 하드웨어를 켜고, 암호화 키를 생성하며, 그 키를 cam에 프로비저닝하고, MCU의 일회성 프로그래밍 가능 저장소에 되돌릴 수 없게 굽는 작업이 필요합니다. 이들 각각은 별개의 단방향 작업이며, 그 중 하나라도 생산 유닛에서 잘못 수행하면 해당 유닛이 벽돌이 됩니다.
이 목록의 각 항목은 그 자체로 펌웨어 빌드 작업, 생산 라인 단계, 되돌릴 수 없는 기록의 묶음입니다. 실제로 잠긴 제품이란 맞춤형 펌웨어 빌드, 맞춤형 부트로더, 유닛마다 키를 프로비저닝하는 제조 흐름, 그리고 유닛이 라인을 떠나기 전에 잠금이 실제로 닫혔음을 증명하는 일련의 테스트입니다. 이는 며칠이 아니라 몇 달의 작업이며, 되돌릴 수 없다는 점 때문에 실수는 유닛을 희생시킵니다.
기본값이 열려 있는 이유
이 목록은 기본 OpenMV 펌웨어가 읽기 보호를 활성화하지 않은 채로 출하되는 이유이기도 합니다. REPL이 닫히고, IDE 스크립트 업로드가 비활성화되고, 펌웨어가 잠긴 cam은 아예 개발이 불가능한 cam입니다. OpenMV cam을 애초에 쓸 만하게 만들어 주는 워크플로가 그냥 사라져 버립니다. 기본값은 모든 것을 열어두며, 제품 팀이 출하 유닛으로 가는 과정에서 어떤 부분을 닫을지 선택합니다.
14.3.4.3. 물리적 접근으로 여전히 얻을 수 있는 것¶
읽기 보호가 켜져 있어도 cam을 손에 쥔 공격자는 상당히 많은 것을 할 수 있습니다:
출력을 스니핑하여 cam의 네트워크 트래픽을 재생합니다.
눈에 보이는 동작을 관찰하여 입력에 어떻게 반응하는지 추론합니다.
경우에 따라서는 보호된 MCU를 겨냥한 폴트 인젝션이나 사이드 채널 공격을 통해 비밀 정보를 복구합니다.
읽기 보호는 애플리케이션 소스에 접근하는 비용을 높입니다. 비용을 없애지는 않습니다. “물리적 접근 = 침해”는 보안 검토가 출발점으로 삼아야 하는 작동 가정입니다. 보호 메커니즘은 그 침해가 시간과 장비 면에서 얼마나 많은 비용이 드는지를 결정할 뿐입니다.
14.3.4.4. OpenMV 펌웨어가 출하될 때의 상태¶
구체적으로 정리하면 다음과 같습니다:
기본적으로 읽기 보호가 활성화되어 있지 않습니다.
기본 펌웨어에는 이를 켜는 빌드 플래그가 없습니다.
MicroPython에서 호출할 수 있는 애플리케이션 수준 API가 없습니다.
보호가 필요한 제품은 맞춤형 펌웨어를 출하합니다. 그 맞춤화는 보드의 부트로더와 제조 흐름 안에 존재하며, OpenMV 코드베이스 바깥에 있습니다. 이를 처음 수행하는 팀은 이를 개발 일정에 별개의 작업 조각으로 계획해야 하며, 마지막에 추가할 무언가로 여겨서는 안 됩니다. 되돌릴 수 없다는 점 때문에 “나중에 추가”하는 것은 비용이 많이 듭니다.