Nozioni di base sulla sicurezza IoT - Parte 4: Mitigare le minacce all'ambiente di runtime

Di Stephen Evanczuk

Contributo di Editori nordamericani di DigiKey

Nota del redattore: nonostante la proliferazione dei dispositivi IoT, la sicurezza è una preoccupazione costante, al punto che le sfide alla sicurezza possono rappresentare un ostacolo all'adozione di dispositivi connessi all'Internet delle cose industriale (IIoT) e ad applicazioni mission-critical in cui i dati aziendali e personali possono essere compromessi in caso di un attacco portato a segno. La sicurezza delle applicazioni IoT può rivelarsi complessa, ma in realtà la sicurezza dei dispositivi IoT può basarsi su alcuni principi relativamente semplici che sono supportati dai dispositivi di sicurezza hardware. Seguendo pratiche di sicurezza consolidate si possono affrontare queste preoccupazioni. Questa serie in più parti funge da guida pratica per aiutare gli sviluppatori a seguire fin dall'inizio le best practice. Nella Parte 1 sono discussi gli algoritmi di crittografia alla base di progetti sicuri. La Parte 2 tratta il ruolo delle chiavi private, la gestione delle chiavi e lo storage sicuro in sistemi sicuri. La Parte 3 esamina i meccanismi incorporati nei processori sicuri per mitigare altri tipi di minacce ai dispositivi IoT. Questa Parte 4 identifica e mostra come applicare i meccanismi di sicurezza nei processori avanzati per garantire l'isolamento necessario al fine di mitigare gli attacchi all'ambiente di runtime dei dispositivi IoT. La Parte 5 descrive come la sicurezza IoT continua dai dispositivi IoT attraverso misure di sicurezza di alto livello utilizzate per connettere tali dispositivi alle risorse cloud IoT.

La crittografia basata su hardware con storage sicuro fornisce le basi necessarie per implementare progetti di IoT sicuri. L'avvio sicuro e l'aggiornamento sicuro del firmware via etere FOTA) utilizzano questa base per creare una radice di attendibilità per l'esecuzione del software. Tuttavia, un dispositivo per Internet delle cose (IoT) richiede la protezione continua da software che può compromettere accidentalmente o intenzionalmente le risorse sicure a cui si accede tramite un'applicazione e il codice del sistema in ambiente di runtime.

Questo articolo descrive come gli sviluppatori possono utilizzare i meccanismi di sicurezza integrati in alcuni processori di NXP Semiconductors, STMicroelectronics e di altri produttori per proteggere più efficacemente i sistemi dalle minacce che emergono durante l'esecuzione del software.

Come si può sovvertire il software di runtime

Come discusso nelle parti precedenti di questa serie, i cifrari, lo storage sicuro delle chiavi, l'avvio sicuro e l'aggiornamento sicuro del firmware sono i componenti costitutivi per la sicurezza dell'IoT. Sebbene queste capacità siano cruciali per la sicurezza complessiva dei dispositivi IoT, possono essere una soluzione incompleta contro gli attacchi studiati per sovvertire il software di runtime nei sistemi connessi. Nella migliore delle ipotesi, i tentativi di penetrare le linee di difesa di questi meccanismi dovrebbero fallire grazie all'ambiente costruito sulla radice di attendibilità creata dall'avvio sicuro. In pratica, i sistemi costruiti con queste robuste capacità di sicurezza possono essere compromessi (come è già avvenuto) da attacchi che iniettano nel sistema un pezzo di codice dannoso o malware.

Gli hacker utilizzano svariati metodi per sfruttare le vulnerabilità di sicurezza di una parte del sistema per lanciare attacchi su altre parti. Gli attacchi di riversamento del buffer, ad esempio, sfruttano applicazioni software che consentono a grandi flussi di dati in ingresso di scrivere oltre l'area di buffer prevista. Se questi dati in eccesso contengono codice, il processore potrebbe successivamente eseguirli, fornendo agli hacker un punto di accesso per ulteriori attacchi. Utilizzando questi e altri metodi, gli hacker ampliano gradualmente la loro penetrazione in parti più ampie di un sistema.

Le vulnerabilità possono esistere in qualsiasi componente software in qualsiasi strato dello stack software di un sistema. Mentre gli sviluppatori sono al lavoro per creare sistemi più ricchi di funzionalità, la necessità di un maggior numero di componenti software aumenta la possibilità che i loro sistemi siano soggetti a maggiori vulnerabilità. Allo stesso tempo, la varietà di vulnerabilità presenti nel software continua a crescere. Ad esempio, l'autorevole elenco Common Vulnerabilities and Exposures (CVE®) ha mostrato un aumento del 15% rispetto all'anno precedente nel primo trimestre del 2020.

Vari livelli di protezione per il software critico

L'attenuazione delle minacce è una battaglia costante tra hacker e specialisti della sicurezza. Anche se le minacce continueranno, gli sviluppatori possono rafforzare la sicurezza dei loro progetti sfruttando metodi progettati per isolare i molteplici processi software richiesti in una tipica applicazione. Per anni, i sistemi sicuri sono stati costruiti sulla base di un approccio di protezione a più livelli. In questo approccio classico, gli anelli di protezione concentrici forniscono livelli crescenti di isolamento in un sistema. Le applicazioni in esecuzione sul livello più esterno hanno accesso limitato ai driver periferici e ai servizi di sistema nei livelli interni, che a loro volta hanno accesso limitato al kernel del software nel livello più interno (Figura 1).

Schema di un approccio di protezione a più livelliFigura 1: I sistemi software sicuri proteggono applicazioni, driver e kernel del sistema operativo in anelli dalla protezione progressivamente maggiore. (Immagine per gentile concessione di Wikipedia)

I dispositivi Intel x86 che iniziano con 80286, ora disponibili presso Rochester Electronics, supportano quattro livelli, designati utilizzando un registro di selezione che include un campo a due bit del livello di privilegio richiesto (RPL). Le moderne architetture di processore, come TrustZone di Arm®, dispongono di funzionalità di sicurezza estese grazie a una serie di meccanismi progettati per isolare i processi utente durante il runtime. Gli sviluppatori possono trovare queste capacità di protezione a più livelli in una serie di processori di sistemi embedded, tra cui:

  • La famiglie di microcontroller SAM L11 di Microchip Technology, basata sulla famiglia di microcontroller Arm Cortex®-M23
  • I System-on-Chip (SoC) wireless nRF9160 di Nordic Semiconductor , basati su Arm Cortex-M33
  • Il microcontroller M2351 di Nuvoton Technology, basato su Arm Cortex-M23
  • I microcontroller LPC55 di NXP Semiconductors, basati su Arm Cortex-M33
  • La famiglia di SoC wireless EFR32BG21 di Silicon Labs, basata su Arm Cortex-M33
  • La famiglia di microcontroller STM32L5 di STMicroelectronics, basata sulla famiglia di microcontroller Arm Cortex-M33

TrustZone di Arm per Cortex-M porta capacità di sicurezza potenziate ai processori di sistema embedded Arm Cortex-M, come LPC55S69JBD100K di NXP e STM32L552VET6 di STMicroelectronics. TrustZone per Cortex-A fornisce funzionalità simili per i processori applicativi basati su Arm Cortex-A come i.MX 8M Mini MIMX8MMM6DVTLZAA di NXP e STM32MP157AAC3T di STMicroelectronics.

Per ogni serie Arm, tra le altre caratteristiche di sicurezza TrustZone offre meccanismi che supportano l'avvio sicuro e il codice sicuro, i dati e la memoria. Progettato per supportare i requisiti di bassa latenza dei sistemi embedded, TrustZone per i processori Cortex-M è dotato di miglioramenti delle prestazioni, tra cui interrupt rapidi e sicuri e transizioni veloci basate sull'hardware tra stati di sicurezza. Questo articolo descrive TrustZone per i processori Cortex-M concentrandosi su una coppia di processori rappresentativi di questa classe: LPC55S69JBD100K di NXP e STM32L552VET6 di STMicroelectronics.

Le modalità operative del processore offrono una protezione estesa

Al centro dell'architettura TrustZone, i processori possono funzionare in molteplici modalità operative che supportano l'isolamento dei processi software e delle risorse di sistema. Le modalità "sicura" e "non sicura" del processore sono un modo per isolare i processi affidabili da quelli non affidabili. Le modalità "handler" e "thread" del processore sono un meccanismo di protezione separato che offre ulteriore granularità nell'isolamento dei processi e delle risorse.

Nell'architettura TrustZone, un processore in modalità handler fa sì che il software funzioni sempre in modalità privilegiata. Pertanto è la modalità consigliata per l'esecuzione di software come un sistema operativo in tempo reale (RTOS) o per accedere all'immagine di avvio, alle chiavi di sicurezza e ad altre risorse critiche per il funzionamento del sistema. In modalità thread, il software è in modalità non privilegiata, ma i processi privilegiati possono cambiare il livello di privilegio del software in questa modalità. La modalità thread è tipicamente utilizzata per l'esecuzione del codice applicativo.

Utilizzati in modalità combinata sicura/non sicura e handler/thread forniscono lo stesso tipo di protezione a più livelli dei sistemi precedenti che supportano gli anelli di protezione. Utilizzando STM32L552VET6 di STMicroelectronics, ad esempio, gli sviluppatori possono isolare il codice attendibile con privilegi completi da quello non attendibile con privilegi minimi (Figura 2).

Schema del processore STM32L552VET6 TrustZone di STMicroelectronicsFigura 2: I processori TrustZone come la STM32L552VET6 di STMicroelectronics forniscono una combinazione di modalità che permettono agli sviluppatori di isolare il software di sistema attendibile come le immagini di avvio dal codice applicativo non attendibile come gli stack di comunicazione a radiofrequenza (RF) di produttori terzi. (Immagine per gentile concessione di Digi-Key, da materiale di STMicroelectronics)

I meccanismi di isolamento integrati in questi processori limitano la capacità di accedere a diverse aree della memoria dati del programma. Ad esempio, quando il core NXP LPC55S6x è nello stato sicuro, non può accedere alla memoria di programma non sicura, anche se può comunque raggiungere la memoria dati non sicura. Per contro, quando il core LPC55S6x funziona in stato non sicuro, può accedere solo alla memoria di programma e alla memoria dati non sicura (Figura 3).

Schema della famiglia LPC81 di NXPFigura 3: I processori come i dispositivi LPC55S6x di NXP possono assicurare che il core sia in esecuzione nello stato sicuro (stato S) per leggere la memoria di programma sicura (verde) o nello stato non sicuro (stato NS) per leggere la memoria di programma non sicura (rosso). (Immagine per gentile concessione di NXP Semiconductors)

Quando sono in stato sicuro per l'esecuzione di un software attendibile, questi processori non possono recuperare le istruzioni da una memoria di programma non sicura. Al contrario, quando sono in stato non sicuro per eseguire software non attendibili come il codice dell'applicazione, questi processori non possono accedere al codice o ai dati che si trovano in aree sicure. Tuttavia, il codice dell'applicazione richiede tipicamente la capacità di eseguire codice attendibile in librerie sicure. I processori TrustZone consentono agli sviluppatori di soddisfare questo requisito definendo regioni di memoria non sicura richiamabile (NSC) che fanno da punti di ingresso consentiti alle librerie sicure (Figura 4).

Schema delle regioni non sicure richiamabiliFigura 4: Le regioni non sicure richiamabili sono i punti di ingresso sicuri da regioni di memoria non sicure a regioni di memoria sicure, consentendo alle applicazioni non sicure di eseguire funzioni in librerie sicure. (Immagine per gentile concessione di STMicroelectronics)

Gli alias di memoria aumentano la sicurezza

I processori TrustZone come LPC55S69JBD100K di NXP e STM32L552VET6 di STMicroelectronics gestiscono l'esecuzione mediante l'aliasing della memoria fisica del programma in spazi di memoria sicuri e non sicuri. Ad esempio, STM32L552VET6 di STMicroelectronics esegue l'aliasing del codice in flash e SRAM due volte: una in un intervallo di indirizzi non sicuro (da 0x0800_000000 a 0x0BFF_FFFF) e un'altra in un intervallo di indirizzi sicuro (da 0x0C00_000000 a 0x0FFF_FFFFFF). Allo stesso modo, LPC55S69JBD100K di NXP esegue l'aliasing della memoria fisica del programma in uno spazio non sicuro a partire da 0x000000_0000 e in uno spazio sicuro a partire da 0x1000_0000. Ognuno di questi processori utilizza un approccio simile per altri tipi di memoria e periferiche, eseguendo l'aliasing due volte in regioni sicure e non sicure.

Quando il processore deve accedere ad una posizione di memoria, la possibilità di accedere a tale posizione è determinata da un attributo di sicurezza generato da due unità hardware:

  • Implementation Defined Attribution Unit (IDAU), un'unità hardware fissa esterna al core del processore che fornisce uno stato di sicurezza fisso della mappa della memoria come definito dal produttore.
  • Secure Attribution Unit (SAU), un'unità programmabile integrata nel core del processore utilizzata per definire lo stato di sicurezza di un massimo di otto regioni di memoria.

Durante l'inizializzazione del sistema, le routine di configurazione in esecuzione in modalità sicura definiscono lo stato di sicurezza di ogni regione impostando alcuni registri SAU, tra cui:

  • Registro del numero di regione SAU (SAU_RNR) per selezionare una regione per altre operazioni
  • Registro degli indirizzi di base della regione SAU (SAU_RBAR) per definire l'indirizzo di partenza della regione
  • Registro dell'indirizzo limite della regione SAU (SAU_RLAR) per definire l'estensione della regione

Incluso nel pacchetto software MCU STM32Cube per la serie STM32L5, STMicroelectronics fornisce file di modello che dimostrano l'uso delle caratteristiche del processore, inclusa la configurazione SAU. Come mostrato nel Listato 1, gli sviluppatori possono definire queste regioni per ogni parametro di configurazione mediante una macro (SAU_INIT_REGION(n)) che imposta i valori del registro in una struttura SAU usata quando si scrivono le impostazioni di configurazione sul dispositivo.

Copy
/*
//   <e>Initialize SAU Region 0
//   <i> Setup SAU Region 0 memory attributes
*/
#define SAU_INIT_REGION0    1
 
/*
//     <o>Start Address <0-0xFFFFFFE0>
*/
#define SAU_INIT_START0     0x0C03E000      /* start address of SAU region 0 */
 
/*
//     <o>End Address <0x1F-0xFFFFFFFF>
*/
#define SAU_INIT_END0       0x0C03FFFF      /* end address of SAU region 0 */
 
/*
//     <o>Region is
//         <0=>Non-Secure
//         <1=>Secure, Non-Secure Callable
*/
#define SAU_INIT_NSC0       1
/*
//   </e>
*/
 
/*
//   <e>Initialize SAU Region 1
//   <i> Setup SAU Region 1 memory attributes
*/
#define SAU_INIT_REGION1    1
 
/*
//     <o>Start Address <0-0xFFFFFFE0>
*/
#define SAU_INIT_START1     0x08040000      /* start address of SAU region 1 */
 
/*
//     <o>End Address <0x1F-0xFFFFFFFF>
*/
#define SAU_INIT_END1       0x0807FFFF      /* end address of SAU region 1 */
 
/*
//     <o>Region is
//         <0=>Non-Secure
//         <1=>Secure, Non-Secure Callable
*/
#define SAU_INIT_NSC1       0
/*
//   </e>
*/
   .
   .
   .
**
  \brief   Setup a SAU Region
  \details Writes the region information contained in SAU_Region to the
           registers SAU_RNR, SAU_RBAR, and SAU_RLAR
 */
__STATIC_INLINE void TZ_SAU_Setup (void)
{
 
#if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U)
 
  #if defined (SAU_INIT_REGION0) && (SAU_INIT_REGION0 == 1U)
    SAU_INIT_REGION(0);
  #endif
   .
   .
   .
#define SAU_INIT_REGION(n) \
    SAU->RNR  =  (n                                     & SAU_RNR_REGION_Msk); \
    SAU->RBAR =  (SAU_INIT_START##n                     & SAU_RBAR_BADDR_Msk); \
    SAU->RLAR =  (SAU_INIT_END##n                       & SAU_RLAR_LADDR_Msk) | \
                ((SAU_INIT_NSC##n << SAU_RLAR_NSC_Pos)  & SAU_RLAR_NSC_Msk)   | 1U
 

Listato 1: Incluso nei modelli del pacchetto software MCU STM32Cube di STMicroelectronics per la serie STM32L5, questo snippet mostra come gli sviluppatori definiscono le regioni di memoria e lo stato di sicurezza associato. (Codice per gentile concessione di STMicroelectronics)

IDAU e il SAU lavorano di concerto per determinare se la posizione di memoria è accessibile, restituendo il massimo livello di sicurezza tra i due. Poiché un processore lavora con l'alias di memoria corrispondente al suo stato operativo sicuro/non sicuro, l'attributo di sicurezza generato dalla combinazione di IDAU e SAU garantisce l'accessibilità solo alle regioni con il corrispondente livello di sicurezza (Figura 5).

Schema di IDAU e SAU in LPC55S69JBD100K di NXP (Fare clic per ingrandire)Figura 5: In LPC55S69JBD100K di NXP, IDAU e SAU si combinano per generare un attributo di sicurezza per ogni alias di memoria, eliminando di fatto il codice che non ha il permesso di uscire da ogni rispettiva regione. (Immagine per gentile concessione di NXP Semiconductors)

Ad esempio, quando LPC55S69JBD100K di NXP funziona in modalità sicura, l'attributo di sicurezza generato da IDAU e SAU impedirà l'accesso ad applicazioni non sicure contenute nell'alias sicuro di un blocco di memoria fisica, eliminando di fatto quel codice non sicuro dall'alias sicuro. Al contrario, quando il processore opera in modalità non sicura, l'attributo di sicurezza IDAU e SAU eliminerà efficacemente le applicazioni sicure dall'alias non sicuro risultante.

Impostazione del privilegio e controllo degli accessi

Mentre IDAU e SAU applicano direttamente restrizioni di accesso sicure e non sicure, lavorano con unità di protezione della memoria (MPU) sicure e non sicure per determinare i diritti di accesso associati alla risorsa target (Figura 6).

Schema del processore TrustZone LPC55S69JBD100K di NXPFigura 6: Nei processori TrustZone come LPC55S69JBD100K di NXP di questo esempio, l'attributo di sicurezza generato da SAU e IDAU si combina con le impostazioni gestite da MPU sicure e non sicure per fornire il livello di privilegio insieme al livello di sicurezza. (Immagine per gentile concessione di NXP Semiconductors)

Integrata in questi processori, l'MPU fornisce un controllo degli accessi granulare delle risorse di memoria. Ad esempio, in STM32L552VET6 di STMicroelectronics, l'MPU supporta una serie di diritti di accesso che si differenziano quando il processore funziona in modalità handler privilegiato o in modalità thread non privilegiato (Tabella 1).

Tabella di STM32L552VET6 di STMicroelectronics in modalità privilegiata e non privilegiataTabella 1: STM32L552VET6 di STMicroelectronics permette agli sviluppatori di utilizzare l'MPU per definire diversi livelli di accesso che operano in modo diverso in modalità privilegiata e non privilegiata. (Tabella per gentile concessione di STMicroelectronics)

Tra questi attributi, Execute Never (XN) consente agli sviluppatori di garantire che il processore non tenti mai di eseguire il codice dalla regione di memoria associata, fornendo un ulteriore livello di protezione di runtime. Ad esempio, nei sistemi che eseguono codice direttamente da flash, gli sviluppatori possono impostare l'attributo XN per le regioni SRAM non utilizzate ed eliminare così ogni possibilità che il sistema venga compromesso, anche se gli attacchi di malware vanno a segno in quelle aree.

Estensione della protezione a più periferiche e memoria

Le caratteristiche IDAU, SAU e MPU di questi processori fanno da base flessibile per proteggere l'esecuzione di runtime sia del software di sistema che delle applicazioni, ma queste capacità sono limitate al processore stesso. Processori come LPC55S69JBD100K di NXP e STM32L552VET6 di STMicroelectronics trasmettono le capacità sicure e privilegiate ad altri sistemi di memoria e interfacce mediante approcci diversi.

Per STM32L552VET6, STMicroelectronics completa il meccanismo TrustZone nativo con il proprio controller globale TrustZone (GTZC) progettato per proteggere le periferiche, la SRAM embedded e le memorie esterne (Figura 7).

Schema del processore STM32L552VET6 di STMicroelectronicsFigura 7: Il processore STM32L552VET6 di STMicroelectronics integra un controller TrustZone globale (GTZC) che estende la protezione di sicurezza alle periferiche e alla memoria non incluse nel framework TrustZone nativo. (Immagine per gentile concessione di STMicroelectronics)

In LPC55S69JBD100K di NXP, l'attributo privilegiato (HPRIV) e l'attributo sicuro (HNONSEC) sono trasmessi attraverso la matrice interna del bus avanzato ad alte prestazioni (AHB) per raggiungere i controlli di protezione della memoria (MPC), i controlli di protezione delle periferiche (PPC) e il wrapper di sicurezza master (MSW) per altri master di bus (Figura 8).

Schema di LPC55S69JBD100K di NXPFigura 8: In LPC55S69JBD100K di NXP, i livelli di privilegio e di sicurezza sono trasmessi a unità hardware aggiuntive che applicano questi attributi alle operazioni che coinvolgono memoria, periferiche e altri master di bus. (Immagine per gentile concessione di NXP Semiconductors)

Sebbene sia importante capire i meccanismi di base per l'isolamento del software e la protezione del sistema, gli sviluppatori possono sfruttare il supporto allo sviluppo per applicare rapidamente queste capacità ai loro progetti.

STMicroelectronics fornisce le schede di valutazione STM32L552E-EV, STM32L562E-DK e NUCLEO-L552ZE-Q come piattaforma di prototipazione rapida per costruire applicazioni basate sui suoi processori STM32L5. L'ambiente di sviluppo integrato (IDE) STM32CubeIDEdell'azienda è un ambiente completo per la programmazione di software e STM32CubeProgrammer offre sia la versione con interfaccia grafica utente (GUI) che quella con interfaccia basata sulla riga di comando (CLI) per la programmazione di memorie interne ed esterne. Con questo strumento, gli sviluppatori possono definire ad esempio regioni sicure nella memoria flash (Figura 9).

Immagine di STM32CubeProgrammer di STMicroelectronicsFigura 9: STM32CubeProgrammer di STMicroelectronics offre un approccio semplice per definire le regioni sicure nella memoria flash. (Immagine per gentile concessione di STMicroelectronics)

Per il rapido sviluppo di sistemi basati sui processori LPC55S69 di NXP, gli sviluppatori possono costruire progetti sulla scheda di valutazione LPC55S69-EVK di NXP. Per la configurazione del sistema e la programmazione del software, l'IDE MCUXpresso di NXP è una piattaforma completa per la creazione di applicazioni basate sui processori LPC55S69 di NXP.

Conclusione

La sicurezza IoT dipende da meccanismi di sicurezza fondamentali per la crittografia e lo storage sicuro, nonché dalle capacità di costruire applicazioni su una radice di attendibilità basata su meccanismi di sicurezza hardware. Sebbene siano tutti necessari per la sicurezza, raramente sono sufficienti per contrastare le minacce ricorrenti, studiate per sfruttare le vulnerabilità in ambienti di runtime del sistema. Utilizzando i meccanismi di protezione a più livelli disponibili in una gamma crescente di processori, gli sviluppatori possono costruire dispositivi IoT sicuri in grado di mitigare meglio queste minacce e ridurre o eliminare il loro impatto sulle applicazioni IoT.

DigiKey logo

Esonero della responsabilità: le opinioni, le convinzioni e i punti di vista espressi dai vari autori e/o dai partecipanti al forum su questo sito Web non riflettono necessariamente le opinioni, le convinzioni e i punti di vista di DigiKey o le sue politiche.

Informazioni su questo autore

Image of Stephen Evanczuk

Stephen Evanczuk

Stephen Evanczuk ha più di 20 anni di esperienza come autore sull'industria elettronica e ha scritto su una vasta gamma di argomenti tra cui hardware, software, sistemi e applicazioni, incluso l'IoT. Ha ricevuto un Ph.D. in neuroscienze sulle reti neuronali e ha lavorato nel settore aerospaziale su sistemi di sicurezza ampiamente distribuiti e sui metodi di accelerazione algoritmica. Attualmente, quando non scrive articoli su tecnologia e ingegneria, lavora su applicazioni di deep learning per i sistemi di riconoscimento e di raccomandazione.

Informazioni su questo editore

Editori nordamericani di DigiKey