TL; DR:
Sul tuo sistema di distribuzione:
- crea una coppia di chiavi pubblica / privata
- spedisce la chiave pubblica con la prima versione del firmware
- crea un pacchetto di aggiornamento
- usa HMAC per creare un hash sicuro del pacchetto
- firma l'hash utilizzando la tua chiave privata
- distribuisci il pacchetto e la firma
Sul dispositivo:
- controlla l'hash per determinare l'integrità
- controlla la firma per determinare l'autenticità
In primo luogo, generi una coppia di chiavi sul tuo sistema di generazione. Avrai una chiave pubblica e una privata. Inserisci la chiave pubblica sul firmware originale dei dispositivi spediti. Questa è la versione iniziale. Conserva la chiave privata sullo storage sicuro, idealmente all'interno di un computer disconnesso (senza accesso alla rete).
Quando si rilascia un aggiornamento, è necessario utilizzare la chiave privata creata in precedenza per firmare il pacchetto di aggiornamento. È possibile aggiungere il pacchetto a un file zip, insieme a un file di testo contenente la firma generata in precedenza. Invia il file al microcontrollore.
Dopo aver ricevuto il file zip, il microcontrollore decomprimerà sia la firma che l'aggiornamento, eseguirà un controllo della firma e confronterà la firma risultante con la firma nel file zip. Se sono uguali, l'integrità del pacchetto è garantita e sa che tu (e non qualcun altro) hai creato il pacchetto.
Se non si dispone di memoria sufficiente per decomprimere e controllare, è necessario creare un formato di file speciale contenente sia la firma che l'aggiornamento. È persino possibile implementare SHA256HMAC su un microcontrollore.
Come ha detto Mike Scott, dopo aver inviato l'aggiornamento, deve avere qualche processo in atto per sostituire atomicamente il firmware corrente con quello nuovo. Ho visto un sistema che crea due partizioni sullo storage e ne usa uno per il firmware corrente e un altro per gli aggiornamenti. Dopo l'applicazione e il controllo dell'aggiornamento, sul bootloader viene impostato un flag per indicare quale partizione caricare. Ed è possibile modificare il bootloader per indicare quale partizione verrà caricata durante l'avvio.