Arranque seguro en i.MX6

Arranque seguro en i.MX6


Al desarrollar cualquier proyecto para sistemas integrados, el desarrollador debe resolver dos problemas adicionales:

  • Cómo proteger el firmware del spoofing en el producto;
  • Cómo proteger el software de la copia.

Este artículo describe cómo proteger el procesador i.MX6 de cambiar el gestor de arranque en el producto y complicar el proceso de copia de firmware.



Introducción


Para proteger la propiedad intelectual en caso de que el proyecto de metal desnudo [1] ayude principalmente a un complejo de hardware, tanto presente en el microcontrolador como externo. Se dan ejemplos en un sitio de buena reputación [2] . Se utilizan métodos de software adicionales, como [3] , sin embargo, se basan en el mecanismo de protección desconocido. Esto se debe al bajo poder de cómputo de los dispositivos y al inconveniente de implementar la generación dinámica de firmware.

Cuando SoC entra en juego con sistemas operativos como Linux, la protección debe organizarse simultáneamente en varios niveles:

  • Finalizar nivel de aplicación
  • Nivel del sistema operativo
  • Nivel de cargador de arranque

En caso de obtener acceso a cualquiera de los niveles, es bastante fácil influir en el software de otros niveles y realizar cambios en las interacciones entre niveles.
Los ejemplos más simples: su software instalado en Linux se comunica a través del protocolo UART (por ejemplo, a través de / dev / ttyACM0) con un microcontrolador. Un atacante que obtiene acceso al sistema usa el mismo recurso UART y repite los paquetes enviados al azar. O, por ejemplo, si un controlador está integrado en el núcleo, un atacante recompila el núcleo reescribiendo el código del controlador UART de otra manera. La aplicación final no sabe lo que está sucediendo.

¿Qué es el arranque seguro y por qué es necesario?


El primer nivel de protección para su software en el sistema de destino es el arranque seguro. En lo sucesivo, el arranque seguro se explica para los procesadores de la familia i.MX6.

El arranque seguro en i.MX6 se implementa a través del arranque de alta seguridad (HAB) y puede realizar dos funciones:

  • arranque seguro
  • descarga encriptada

En este artículo, describiré el proceso para garantizar la carga segura del procesador. I.MX6 también implementa un algoritmo que proporciona cifrado del cargador de arranque. Sin embargo, su uso requiere la generación de un gestor de arranque único para cada producto, ya que utiliza una función de cifrado única para cada procesador. Este es un procedimiento inconveniente en la serie, por lo que no lo describí. Si tiene algo que decir sobre este tema, me alegrará saberlo.
El arranque seguro intenta garantizar que el gestor de arranque se inicie en su producto, con el núcleo que cargó en él.

Sobre la definición que le di al arranque seguro. El arranque seguro no evita que copie el producto. Sí, esto hace que el procedimiento sea más difícil, pero no mucho. El gestor de arranque no puede firmar el FS completo, por lo tanto, no proporciona protección en el nivel del sistema operativo y en el nivel de la aplicación final. Todo funciona de manera clásica: a través del cifrado asimétrico. Describiré el proceso con los dedos, se puede leer más profundamente en [4]. El gestor de arranque indica el script para el HAB, donde se indican las áreas de memoria firmadas y dónde se encuentra la firma digital. La clave pública está ubicada previamente en la memoria del procesador programable de una sola vez (OTP). Al cargar, el script verifica el área de memoria especificada utilizando la firma digital adjunta y una clave con cable. Si la prueba falla, el procesador no inicia la descarga. La operación HAB también debe activarse configurando un bit en la región de memoria OTP.

Desventajas del arranque seguro:

  • Si el HAB no está activado, el firmware aún se iniciará. Esto significa que sin agregar. métodos de protección su firmware se ejecutará en una copia del producto. Para evitar que esto suceda, el gestor de arranque debe activar independientemente el HAB al inicio. Pero luego, al insertar una unidad flash USB en otro producto y olvidarse de flashear la clave pública, puede tirar el procesador.
  • Al acceder a la memoria del procesador, puede copiar la clave pública, esto es suficiente para copiar el producto.

Implementación


En general, hay una gran cantidad de artículos en inglés [5] [6] en Internet sobre el tema de la implementación, pero ninguno de los métodos propuestos despegó de inmediato, y los enlaces al software comenzaron a morir, así que decidí guardar esto como un artículo principalmente para mí, cuando Volveré sobre este tema en el futuro.

Primero debe descargar el siguiente software: herramienta de firma de código [7] y los scripts necesarios para generar claves y firma. En el archivo especificado, eliminé todas las utilidades y bibliotecas innecesarias, ya que hay muchas no utilizadas para nuestra tarea.

A continuación, debe generar las claves:

cd ${CST_PATH}/release/keys
echo ${serial} > serial //8 ,     
echo ${password} >  key_pass.txt //   ,     
echo ${password} >>  key_pass.txt //
./hab4_pki_tree.sh //     
Do you want to use an existing CA key (y/n)?: n 
Do you want to use Elliptic Curve Cryptography (y/n)?: n
Enter key length in bits for PKI tree: 4096
Enter PKI tree duration (years): 10
How many Super Root Keys should be generated? 4
Do you want the SRK certificates to have the CA flag set? (y/n)?: y
 ../linux64/bin/srktool -h 4 -t SRK_1_2_3_4_table.bin -e SRK_1_2_3_4_fuse.bin \
 -d sha256 -c ./SRK1_sha256_4096_65537_v3_ca_crt.pem,\
./SRK2_sha256_4096_65537_v3_ca_crt.pem,./SRK3_sha256_4096_65537_v3_ca_crt.pem,\
./SRK4_sha256_4096_65537_v3_ca_crt.pem -f 1

El script de generación de claves plantea las preguntas anteriores. Di un ejemplo de opciones estándar. La respuesta a ellos determina cómo se llamarán las claves generadas y los parámetros de las claves generadas. Considere con más comandos. A continuación, leemos la clave pública necesaria para escribir en el procesador. Usaremos un script conveniente de [5] para esto .

cd ${CST_PATH}/release/linux64/bin
./var-u-boot_fuse_commands.sh 
fuse prog 3 0 0xFFFFFFFF //   uboot.
fuse prog 3 1 0xFFFFFFFF //     
fuse prog 3 2 0xFFFFFFFF //       .
fuse prog 3 3 0xFFFFFFFF //  -   .
fuse prog 3 4 0xFFFFFFFF //      .
fuse prog 3 5 0xFFFFFFFF //
fuse prog 3 6 0xFFFFFFFF  //
fuse prog 3 7 0xFFFFFFFF //

Esta tarea se puede aplicar a uboot con SPL integrado o con SPL y uboot separados (lanzamiento de rocko, por ejemplo). Estoy escribiendo un comunicado para que sepa dónde se usan como estándar. Si compila uboot usted mismo, lo más probable es que su SPL se integre en uboot. Un punto importante en el gestor de arranque defconfig es agregar las siguientes opciones:

CONFIG_SECURE_BOOT=y
CONFIG_SYS_FSL_HAS_SEC=y 
#define CONFIG_SYS_FSL_SEC_COMPAT    4 /* HAB version */
#define CONFIG_FSL_CAAM
#define CONFIG_CMD_DEKBLOB
#define CONFIG_SYS_FSL_SEC_LE
#define CONFIG_FAT_WRITE

Estas opciones activan los controladores para trabajar con módulos de hardware. Todo es como en menuconfig para Linux. Al compilar el gestor de arranque, use el modo detallado (elimine V = 1. El ensamblado con este parámetro está escrito en la guía. Sin embargo, lo limpié yo mismo). En este caso, la información sobre la dirección del punto de entrada y otras cosas necesarias para grabar una firma digital se agrega a los registros de compilación. Después de la compilación, necesitamos los siguientes archivos de salida:

  • u-boot-ivt.img
  • u-boot-ivt.img.log
  • SPL
  • SPL.log

cópielos a $ {CST_PATH} / release / linux64 / bin. A continuación, debe ejecutar un script bastante simple.

Descripción detallada del procedimiento de script.
(*.csf). , :

  • .

. , ( ).

:

Image Name:   U-Boot 2019 //  U-boot
Created:      XXXXXX
Image Type:   ARM U-Boot Firmware with HABv4 IVT (uncompressed)
Data Size:    339904 Bytes = 331.94 KiB = 0.32 MiB
Load Address: 17800000
Entry Point:  00000000
HAB Blocks:   0x177fffc0   0x0000   0x00051020

Image Type:   Freescale IMX Boot Image //  SPL
Image Ver:    2 (i.MX53/6/7 compatible)
Mode:         DCD
Data Size:    61440 Bytes = 60.00 KiB = 0.06 MiB
Load Address: 00907420
Entry Point:  00908000
HAB Blocks:   00907400 00000000 0000cc00
DCD Blocks:   00910000 0000002c 00000004

«HAB Blocks». ,

cd ${CST_PATH}/release/linux64/bin
./cst --o u-boot_csf.bin --i u-boot.csf
cat u-boot-ivt.img u-boot_csf.bin > u-boot_signed.img


Por lo que recuerdo en el caso de SPL integrado, lo más probable es que todo funcione de la misma manera, pero vale la pena echarle un vistazo. No recuerdo ahora y no comencé a compilar al escribir este artículo.

cd ${CST_PATH}/release/linux64/bin
SOC=mx6 ./var-som_sign_image.sh SPL u-boot-ivt.img

Según los resultados del script, obtendrá dos archivos: SPL_signed, u-boot-ivt.img_signed, que deben escribirse en el disco del sistema de destino. Aplico un ejemplo de un guión de grabación al sistema de destino. Sin sudo, para no dispararte accidentalmente en la pierna.

dd if=SPL_signed of=${DEVICE(/dev/sd*)} bs=1K seek=1; sync
dd if=u-boot-ivt.img_signed of=${DEVICE(/dev/sd*)} bs=1K seek=69; sync

Después de escribir en un medio en blanco, debe obtener un gestor de arranque sin un núcleo que se bloqueará en la consola, ya que no encontrará dtb y el núcleo. En la consola, puede verificar si lo que ha hecho o no realmente funciona. En presencia de un evento, algo salió mal. Importante: si el gestor de arranque se compila sin compatibilidad con HAB, tampoco habrá errores.

hab_status
HAB Configuration: 0xf0, HAB State: 0x66
No HAB Events Found!

El último paso es activar el HAB, la atención es un comando de una sola vez, no se puede arreglar, así que tenga cuidado

fuse prog 0 6 0x2

Conclusión


No comencé a describir el proceso de integrar todo esto en yocto, pero tengo que guardar secretos. Sin embargo, esto es factible y no requiere mucho tiempo.

referencia


[1] software incorporado de metal desnudo que se ejecuta directamente en hardware sin ninguna abstracción en forma de sistemas operativos
[2] we.easyelectronics.ru/Soft/zaschita-ustroystva-ot-vzloma-i-kopirovaniya.html
[3 ] habr.com/en/post/350602
[4] HAB4_API.pdf en github.com/BMValeev/CST_TOOL
[5] variwiki.com/index.php?title=High_Assurance_Boot
[6] boundarydevices.com/high-assurance-boot -hab-dummies
[7] github.com/BMValeev/CST_TOOL

All Articles