TL;DR:
En su sistema de distribución:
- crear un par de llaves público / privado
- envíe la clave pública con la primera versión de firmware
- crear un paquete de actualización
- use HMAC para crear un hash seguro del paquete
- firma el hash usando tu clave privada
- distribuir el paquete y la firma
En el dispositivo:
- comprueba el hash para determinar la integridad
- compruebe la firma para determinar la autenticidad
Primero, generas un par de llaves en tu sistema de compilación. Tendrás claves públicas y privadas. Coloque la clave pública en el firmware original de los dispositivos enviados. Esta es la versión inicial. Mantenga la clave privada en un almacenamiento seguro, idealmente dentro de una computadora desconectada (sin acceso a la red).
Cuando lanza una actualización, debe usar la clave privada creada anteriormente para firmar el paquete de actualización. Puede agregar el paquete a un archivo zip, junto con un archivo de texto que contenga la firma que generó anteriormente. Envía el archivo al microcontrolador.
Después de recibir el archivo zip, el microcontrolador descomprimirá la firma y la actualización, ejecutará una comprobación de firma y comparará la firma resultante con la firma en el archivo zip. Si son iguales, la integridad del paquete está asegurada y te conoce (y no a otra persona) que creó el paquete.
Si no tiene suficiente memoria para descomprimir y verificar, debe crear un formato de archivo especial que contenga la firma y la actualización. Incluso puede implementar SHA256HMAC en un microcontrolador.
Como dijo Mike Scott, después de enviar la actualización, debe implementar algún proceso para reemplazar de forma automática el firmware actual por el nuevo. He visto un sistema que crea dos particiones en el almacenamiento y uso una para el firmware actual y otra para las actualizaciones. Después de aplicar y verificar la actualización, se establece un indicador en el cargador de arranque para indicar qué partición se debe cargar. Y puede cambiar el cargador de arranque para indicar qué partición cargará durante el arranque.