14.3.4. Una nota sobre la protección de lectura de la memoria flash

De fábrica, el firmware de una OpenMV Cam ya enviada es legible por cualquiera que tenga acceso físico al dispositivo. Un atacante con la cámara en la mano puede conectar una sonda SWD al conector de depuración, comunicarse con la interfaz de depuración del MCU y volcar la memoria flash, que incluye todos los módulos Python congelados y el contenido de la partición ROMFS. El firmware estándar de OpenMV no habilita la protección de lectura de la memoria flash de forma predeterminada.

Esta página lo documenta de forma explícita para que un equipo que vaya a enviar un producto sepa dónde recae la responsabilidad.

14.3.4.1. Lo que hace la cámara de forma predeterminada

El bootloader y el entorno de ejecución de la cámara no activan ninguna función de protección de lectura del MCU subyacente. La interfaz de depuración permanece abierta, la memoria flash sigue siendo legible y la compilación se ejecuta tal como lo hace en el banco de pruebas de un desarrollador. Ese es el valor predeterminado correcto para el público de este tutorial: una cámara que se envía con la protección de lectura activada es una cámara que no se puede reprogramar a través del IDE, no se puede volver a generar la imagen tras un despliegue fallido y no la puede recuperar nadie salvo el equipo de compilación.

El equilibrio cambia cuando la cámara pasa de ser un «dispositivo de desarrollo» a un «producto». Un producto cuyo valor depende de que el código de la aplicación se mantenga privado tiene que habilitar la protección por sí mismo; el firmware de OpenMV no lo hace.

14.3.4.2. Lo que hace el equipo del producto

Todos los fabricantes de MCU ofrecen un mecanismo de protección de lectura. Los detalles varían (fusibles a nivel de bit, transiciones de ciclo de vida de un solo disparo, imágenes de flash firmadas), pero la forma común es:

  • Se graba en el silicio un bit (o conjunto de bits) específico del fabricante, normalmente mediante una herramienta del fabricante que se comunica con el puerto de depuración del MCU una última vez.

  • Tras la grabación, el puerto de depuración se niega a leer la memoria flash. La cámara sigue arrancando y ejecutando la aplicación; simplemente ya no expone su contenido a una sonda.

  • La grabación es irreversible. No hay forma de devolver la cámara a un estado depurable sin destruirla.

Configurar esto es específico del MCU, y los pasos dependen de la pieza concreta de la cámara que se está protegiendo. El manual de referencia del fabricante es la fuente de verdad; el soporte del fabricante es el canal para hacerlo bien en una línea de fabricación.

Esta es la parte fácil.

La parte difícil es cerrar todas las demás vías que tiene un atacante para ejecutar código en la cámara o leer lo que está haciendo la aplicación. La protección de lectura solo impide que una sonda de depuración vuelque la memoria flash. La cámara todavía tiene que cerrar:

  • El REPL de MicroPython. Un REPL conectado por USB acepta código Python arbitrario. La protección de lectura no cambia eso. Una sesión REPL puede leer la RAM, llamar a funciones y exfiltrar todo lo que la aplicación en ejecución pueda ver; en efecto, un REPL accesible anula todo lo que aporta la protección de lectura. Deshabilitar el acceso al REPL es un cambio en la compilación del firmware que corresponde al equipo del producto.

  • Carga de scripts desde el IDE. La vía del IDE para «ejecutar este script en la cámara» viaja por la misma superficie del protocolo USB que utiliza el REPL. Cerrar el REPL cierra esto también; dejar cualquiera de los dos abierto deja un canal de ejecución de código arbitrario hacia la cámara.

  • Secuestro del punto de entrada desde el sistema de archivos. Ya queda cerrado cuando la aplicación se envía mediante Congelar scripts en el firmware: el entorno de ejecución resuelve los boot.py y main.py congelados antes que cualquier copia del sistema de archivos, por lo que nada de lo que se coloque en la memoria flash o en la SD puede anularlos. Esta protección es gratuita una vez que la aplicación está en la compilación.

  • Memoria flash externa en las cámaras más recientes. Las cámaras que almacenan la imagen de la aplicación en memoria flash externa colocan esa imagen en un chip a la vista en la PCB; el chip puede desoldarse y leerse directamente con herramientas comerciales, o leerse en su sitio sondeando el bus. Protegerlo requiere activar el hardware integrado en el chip que descifra el contenido de la flash durante las lecturas, generar la clave de cifrado, aprovisionar esa clave en la cámara y grabarla de forma irreversible en el almacenamiento programable una sola vez (OTP) del MCU. Cada una de esas operaciones es de un solo disparo independiente, y cualquiera de ellas realizada mal en una unidad de producción inutiliza esa unidad.

Cada elemento de esta lista es su propio conjunto de trabajo de compilación de firmware, pasos en la línea de fabricación y grabaciones irreversibles. Un producto realmente blindado es una compilación de firmware personalizada, un bootloader personalizado, un flujo de fabricación que aprovisiona claves por unidad y un conjunto de pruebas que demuestran que el bloqueo está realmente cerrado antes de que la unidad salga de la línea. Eso son meses de trabajo, no días, y la irreversibilidad implica que los errores cuestan unidades.

Por qué el valor predeterminado es abierto

Esta lista es también la razón por la que el firmware estándar de OpenMV se envía sin la protección de lectura habilitada. Una cámara con el REPL cerrado, la carga de scripts del IDE deshabilitada y el firmware bloqueado es una cámara sobre la que no se puede desarrollar en absoluto: el flujo de trabajo que hace que las OpenMV Cam sean utilizables en primer lugar simplemente desaparecería. El valor predeterminado deja todo abierto; el equipo del producto elige qué piezas cerrar en el camino hacia una unidad enviada.

14.3.4.3. Lo que el acceso físico sigue aportando

Incluso con la protección de lectura activada, un atacante que tenga la cámara puede hacer bastante:

  • Reproducir el tráfico de red de la cámara espiando sus salidas.

  • Observar su comportamiento visible e inferir cómo reacciona ante las entradas.

  • En algunos casos, recuperar secretos mediante ataques de inyección de fallos o de canal lateral especializados contra el MCU protegido.

La protección de lectura aumenta el coste de acceder al código fuente de la aplicación. No elimina ese coste. «Acceso físico = compromiso» es la hipótesis de trabajo desde la que debe partir una revisión de seguridad; el mecanismo de protección solo decide cuánto cuesta ese compromiso en tiempo y equipo.

14.3.4.4. Con qué se envía el firmware de OpenMV

Un resumen, para que esto sea concreto:

  • Ninguna protección de lectura habilitada de forma predeterminada.

  • Ningún indicador de compilación en el firmware estándar que la active.

  • Ninguna API a nivel de aplicación a la que llamar desde MicroPython.

Un producto que necesite la protección se envía con firmware personalizado. Esa personalización reside en el bootloader de la placa y en el flujo de fabricación, y queda fuera de la base de código de OpenMV. Los equipos que hagan esto por primera vez deberían planificarlo dentro del cronograma de desarrollo como una pieza de trabajo concreta, no como algo que añadir al final: la irreversibilidad hace que «añadirlo más tarde» salga caro.