I dati sono oro, è risaputo. E, come oro, vanno gelosamente salvaguardati e custoditi. Rispetto ad un oggetto d’oro, però, i dati hanno una caratteristica peculiare: sono facilmente replicabili ed è decisamente più difficile dire dove, e a disposizione di chi, si trovino in un certo momento.
E però, dato che non esistono sistemi sicuri tout court, ma solo sistemi sui quali ragionare, con attenzione, allo scopo di determinare quali specifiche proprietà di sicurezza siano garantite, sotto quali specifici assunti – un concetto fondamentale è relativo a ciò che potremmo chiamare la “base fidata” del sistema, adattando dall’inglese la nozione di Trusted Computing Base (TCB).
Password, come gestirle per evitare problemi: miti da sfatare, regole da seguire
Questo aspetto è tanto più cruciale in un’epoca come quella attuale in cui, senza una chiara linea di demarcazione, le applicazioni che gestiscono i nostri dati sono distribuite tra dispositivi che abbiamo fisicamente tra le mani ed infrastrutture più o meno eteree, come il cloud.
Ma esiste un’ulteriore, fondamentale differenza. Mentre un gioiello può essere riposto in una cassaforte, della quale, tutto sommato, risultano abbastanza chiare le caratteristiche ed il funzionamento, i dati sono gestiti da macchine estremamente complesse.
Non esiste al mondo alcun esperto che conosca abbastanza bene ogni strato dell’architettura di un computer, dall’elettronica agli algoritmi, alle politiche di gestione dei dati, da poterne determinare tutte le effettive garanzie di sicurezza. E questo vale per il computer che abbiamo sulla scrivania, così come per i dispositivi che portiamo in tasca ed i server in una infrastruttura cloud.
I problemi di sicurezza nell’architettura di un dispositivo
Un dispositivo di elaborazione, qualsiasi forma esso assuma, ha un’organizzazione interna fortemente stratificata. Al livello superiore, le applicazioni utente sono gestite da un sistema operativo che, nel caso di sistemi virtualizzati, è in esecuzione come sistema guest su una Macchina Virtuale, a sua volta gestita da un hypervisor.
Ad un livello sottostante, il sistema operativo host poggia direttamente sul firmware e sull’architettura fisica della macchina e del suo processore, che rappresenta da solo un complesso universo realizzato su silicio.
Ognuno di questi strati si sostiene su quello sottostante e ne presuppone il corretto funzionamento per offrire, a sua volta, garanzie ai livelli sovrastanti.
Quanto questa stratificazione sia problematica per la sicurezza è presto detto. Per usare una metafora, si pensi a quanto sia delicato ancorare un carico sospeso ad una gru, seguendo un preciso protocollo e precise regole per evitare incidenti. Rispettare le regole ci dà la sicurezza che il carico non possa precipitare. O meglio, che non possa precipitare, con il presupposto che la gru stessa sia stata appropriatamente ancorata al suolo. In caso contrario, rischieremmo di vedere la gru crollare con tutti i suoi carichi. Ma fissare al suolo la gru a regola d’arte ci dà l’assoluta certezza di evitare incidenti?
Non del tutto: nel caso, certo raro, ma estremo e devastante, in cui abbia luogo un cedimento del suolo, a poco saranno valse le misure adottate per ancorare i carichi in sicurezza, ed anche quelle per assicurare la gru al terreno. Lo sfacelo sarà inevitabile. Ebbene, questa metafora rende appieno l’idea di quanto accade in un elaboratore. Il terreno su cui tutto poggia è rappresentato, nel nostro caso, dall’hardware della macchina, in particolare dal processore.
È importante capire che, per quanto sofisticata, qualsiasi misura di sicurezza adottata dal software, incluso il sistema operativo stesso, potrebbe essere completamente aggirata con la complicità del processore o di altri componenti hardware critici nel sistema posti ad un livello sottostante. Si pensi semplicemente all’esecuzione di un algoritmo di firma digitale. Il sistema operativo può realizzare questa funzionalità in modo da garantire che la chiave privata dell’utente, impiegata per il calcolo della firma, non sia accessibile ad altri software e che permanga nella RAM per essere manipolata dal processore lo stretto tempo necessario.
Tuttavia, anche nel caso in cui il sistema operativo, ovvero il software più potente in esecuzione sulla macchina, sia perfettamente genuino e privo di bug, una backdoor hardware inserita dal produttore del processore potrebbe, senza troppa difficoltà, esporre la chiave utilizzata per il calcolo, all’insaputa del sistema operativo, dell’utente, e di qualsiasi software antivirus in esecuzione nel sistema.
Trusted Computing: la base di fiducia del sistema
L’elemento cruciale a cui rivolgere l’attenzione nella precedente discussione è il rapporto di fiducia (o trust, in inglese) posto a fondamento delle proprietà di sicurezza del sistema. La catena di fiducia che lega le diverse parti mette in luce che la sicurezza informatica non può essere definita in termini assoluti, ma ha invece una natura intrinsecamente relativa, basata sulla creazione di rapporti di fiducia tra le parti che compongono un’infrastruttura.
Si può pensare alla TCB come al caveau dove vengono custodite le informazioni più delicate, come ad esempio delle chiavi crittografiche, ma anche la stanza dei bottoni blindata dove vengono prese le decisioni più critiche, dalla cui corretta esecuzione dipende la sicurezza dell’intero sistema.
Anche in questo caso, cosa precisamente racchiuda una TCB per un elaboratore dipende da alcuni fondamentali assunti. Presupporre che ad un soggetto malevolo risulti impossibile intervenire fisicamente sul sistema (assumere, quindi, che le misure adottate a tale scopo siano perfette) significa doversi preoccupare solo di tipi di attacco che sfruttano vulnerabilità a livello software o di rete, escludendo che si verifichino manomissioni a livello hardware, ad esempio l’installazione fisica di una sonda tra processore e RAM per intercettare i dati scambiati durante l’esecuzione di un algoritmo crittografico.
Un simile assunto ha una sottile, ma fondamentale conseguenza: poiché nell’infrastruttura di calcolo che stiamo immaginando gli operatori umani hanno accesso fisico alle macchine (e questo vale anche per chiunque abbia assemblato, distribuito, trasportato, installato, collaudato le macchine), stiamo assumendo che ognuno di questi soggetti sia parte della TCB: dobbiamo fidarci di ciascuno di loro perché si regga in piedi il castello di garanzie offerte all’utente.
Al contrario, se assumiamo che possano avvenire manomissioni fisiche e, quindi, restringiamo la nostra TCB senza doverci fidare di operatori e gestori del sistema, dobbiamo chiedere di più ai singoli componenti della nostra macchina per contenere la gamma di possibili attacchi. Ad esempio, nell’ipotesi di eventuali manomissioni, vietare al processore di fidarsi di qualsiasi cosa risieda al di fuori del proprio perimetro fisico, incluso il canale verso la RAM presente sulla scheda madre dell’elaboratore, e persino il software “privilegiato”, il sistema operativo, in esecuzione sulla macchina.
Per far ciò, il processore può, ad esempio, essere progettato per cifrare i dati prima di scriverli in RAM e decifrarli ogni volta che li carica dall’esterno, come suggerito dal lucchetto giallo nella precedente figura. Una simile misura, in buona sostanza, traccia un perimetro sicuro attorno al processore che, corredato di qualche altro accorgimento, restringe la TCB ad un’area minimale, di fatto coincidente con il solo processore.
Possiamo in tal caso resistere a scenari di attacco in cui il soggetto malevolo apra il computer, installi qualsiasi tipo di software privilegiato, come il sistema operativo ed il firmware, e possa persino manomettere la scheda madre o inserire una sonda per monitorare il traffico dati tra processore e RAM durante i calcoli. Siamo ancora vulnerabili, invece, ad attacchi che agiscano sul chip di silicio interno del processore, ma un simile scenario si può considerare sostanzialmente impraticabile, per quanto teoricamente possibile.
La differenza tra integrità e riservatezza
Tra gli accorgimenti che il processore deve adottare, in aggiunta alla cifratura delle informazioni scambiate con supporti esterni, c’è anche la verifica di integrità e l’autenticazione di dati ed istruzioni. Cifratura, da un lato, e verifica di integrità/autenticazione, dall’altro, sono funzionalità differenti ed in parte indipendenti l’una dall’altra.
Come è noto, cifrare significa rendere inintelligibile un’informazione, in modo da consentire la decifratura solo ad uno o più destinatari (ad esempio, sulla base di una chiave segreta condivisa tra le parti, o di una chiave privata a disposizione solo del destinatario). Forse inaspettatamente, la proprietà di riservatezza (o di confidenzialità, usando un calco dall’inglese) instaurata con la cifratura non necessariamente garantisce la proprietà di integrità dell’informazione.
Senza addentrarci nei dettagli, basti sapere che, in qualche caso, è possibile per un attaccante manomettere un dato cifrato in modo da causare delle modifiche mirate su quello che risulterà il dato decifrato, anche senza conoscere né l’informazione in chiaro né la chiave di cifratura. La modifica causata dall’attaccante viola la proprietà di integrità (l’assenza di qualsivoglia alterazione del dato originario), senza violare il meccanismo di cifratura, e senza che chi decifra il dato possa rilevare alcuna anomalia.
Esistono peraltro molte situazioni in cui non serve affatto garantire la riservatezza, mentre l’integrità è fondamentale. Per esempio, quando in un elaboratore carichiamo un software prelevato all’esterno del perimetro del processore (applicazioni utente, sistema operativo, o anche il firmware del sistema), ci interessa poco che il programma eseguito sia cifrato: non corriamo alcun rischio esponendo le istruzioni del software al nostro attaccante, ed anzi cifrarle causerebbe un inutile rallentamento. Ci interessa decisamente, però, che quel software sia integro, ovvero che non sia stato modificato, intenzionalmente o accidentalmente, neanche in uno dei bit che lo compongono.
Come procedere all’autenticazione del software
Fortunatamente, esistono tecniche molto efficaci per raggiungere questo scopo, essenzialmente basate sul calcolo di una sorta di codice di controllo del software, tecnicamente un hash crittografico, costituito da poche decine di byte, che è sostanzialmente impossibile ottenere da qualsiasi altro input che non sia precisamente identico, bit per bit, al software da cui l’hash è stato inizialmente derivato.
L’hash viene ricalcolato dal processore ogni volta che il software è caricato dall’esterno e confrontato con un valore di riferimento. Inoltre, allo scopo di verificare la sorgente di provenienza del software, oltre alla sua integrità, il calcolo dell’hash può includere tra gli input un elemento aggiuntivo, ad esempio una chiave segreta condivisa tra il processore e la sorgente esterna (un server remoto, ma anche il dispositivo di storage esterno al processore da cui proviene il software da eseguire, che potrebbe essere manomesso), realizzando quella che si chiama autenticazione del software.
Come alternativa all’autenticazione a chiave condivisa (“simmetrica”), l’hash del software può essere firmato digitalmente dalla sorgente. In tal caso, al processore deve essere possibile verificare l’identità della sorgente con meccanismi identici a quelli che usiamo per la firma digitale dei documenti elettronici. Che si usi l’una o l’altra soluzione, l’autenticazione rende possibile stabilire la provenienza fidata, oltre che l’integrità, del software prelevato all’esterno del perimetro del processore.
Il software più critico in esecuzione sulla macchina al momento dell’accensione, il firmware, può essere autenticato mediante un simile processo, sfruttando un meccanismo hardware offerto dal processore. Stabilita la provenienza fidata e l’integrità del firmware, possiamo demandare a tale componente il compito di condurre una simile verifica durante il passaggio successivo, il caricamento del bootloader, ed a quest’ultimo poi affidare il compito di verificare il sistema operativo: qualsiasi componente software che sia correttamente verificato dal precedente componente lungo questa catena di fiducia può essere considerato fidato, tanto quanto lo è una funzionalità realizzata direttamente all’interno del perimetro del processore. Nella precedente figura, la propagazione del rapporto di fiducia agli strati software è evidenziata dalle linee gialle che partono dal processore.
La storia del Trusted Computing
I processori odierni, da quelli utilizzati in ambito mobile fino al cloud ed il calcolo ad alte prestazioni, offrono supporto per questo tipo di meccanismi. Storicamente, la loro introduzione ed i primi tentativi di standardizzazione sono collocabili sul finire degli anni Novanta, con la costituzione della Trusted Computing Platform Alliance, poi diventata Trusted Computing Group (TCG), ad opera di aziende come Intel, AMD, IBM, Microsoft and Cisco.
In quegli anni, non era immediatamente percorribile la strada di una modifica strutturale del processore, per cui, nel quadro tracciato dal TCG, l’applicazione dei meccanismi di sicurezza era immaginata affidata ad un chip esterno al processore, il Trusted Platform Module, o TPM, di fatto lasciando il sistema vulnerabile ad attacchi fisici basati sul disassemblaggio delle parti elettroniche (per usare la nozione di TCB prima introdotta, la nostra base fidata deve includere l’intera piattaforma di calcolo e chiunque possa agire fisicamente su di essa).
Un altro fattore, però, ostacolava l’idea promossa dal Trusted Computing Group. L’idea che il TPM potesse decidere cosa ammettere e cosa escludere dall’esecuzione su un calcolatore era estremamente mal vista dalla comunità di utenti e sviluppatori.
Veniva da più parti paventato il sospetto che il TPM fosse principalmente un modo per limitare gli utenti nell’uso dei propri computer, imponendo misure di Digital Right Management (DRM). Tra queste, ad esempio, la verifica che i programmi e contenuti multimediali in uso siano di provenienza genuina e non “craccati”, effettuata tramite meccanismi hardware difficili da aggirare. In quest’ottica, la sicurezza fornita dal TPM è proiettata nella prospettiva dei produttori di software e di contenuti, più che dell’utente interessato alla privacy dei propri dati.
Un secondo aspetto, forse anche più importante, è legato alle potenziali implicazioni geopolitiche di questi meccanismi di controllo, in grado di agire così in profondità sulle tecnologie informatiche.
Non stupisce che la Cina si sia tenuta lontana dall’iniziativa del TCG, un consorzio a trazione statunitense. Anzi, in risposta al TPM, nel 2005 fu introdotto in Cina il cosiddetto chip Hengzhi, sviluppato da Lenovo e progettato sotto il controllo del governo cinese secondo specifiche non conformi a quelle del TCG (problema, per inciso, emerso recentemente con il rilascio di Microsoft Windows 11, che richiede la presenza del chip TPM 2.0, creando così difficoltà nell’accesso al mercato cinese).
Come funziona oggi il Trusted Computing
Se da un lato la piena affermazione del Trusted Computing è stata rallentata da questi problemi, con l’avvento del cloud nei primi anni Duemila è emersa l’esigenza di soluzioni tecnologiche che fornissero garanzie di sicurezza all’utente proprietario di dati in uso su piattaforme remote, piuttosto che ai produttori di software e contenuti multimediali interessati a limitare la fruizione dei propri prodotti. Questo cambio di prospettiva ha decisamente spinto l’evoluzione delle tecnologie dei processori verso la nozione odierna di Trusted Computing.
Nel 2015 Intel ha introdotto in alcuni dei suoi processori le Software Guard Extensions (SGX). Con SGX viene introdotto il concetto di enclave, intesa come una porzione dell’applicazione utente che sfrutta direttamente meccanismi di autenticazione e cifratura della RAM offerti dal processore.
Non ci addentriamo in questo articolo in tali meccanismi, se non per sottolineare che essi sono sotto il pieno controllo del processore Intel. Nulla di un’enclave che esca dal perimetro fisico del processore è intellegibile, essendo cifrato con chiavi determinate internamente dal processore, e ciò rende impossibili anche attacchi di tipo fisico che intercettino le comunicazioni tra processore e RAM (nella maniera suggerita da un lucchetto).
Inoltre, nessun componente software estraneo all’enclave ha accesso all’enclave stessa, incluso il firmware ed il sistema operativo in esecuzione sull’elaboratore. In altri termini, il rapporto di fiducia che si instaura lega tra loro solo l’applicazione utente ed il processore (Intel).
Qualsiasi altro elemento −installatori dell’hardware e del software, produttori di schede madri, assemblatori di macchine, produttori di sistemi operativi− è escluso dalla TCB: l’applicazione non deve necessariamente fidarsi di nessuno di loro per garantire la protezione dei dati utente. Ciò smarca l’approccio SGX dal modello perseguito dal Trusted Computing Group, con il TPM esterno al processore.
Per grandi linee, la stessa filosofia è stata adottata anche da altri produttori, quali ad esempio AMD con la sua Secure Memory Encryption (SME), anche se con approcci non compatibili con Intel SGX (applicazioni scritte per un modello non possono funzionare tal quali sull’altro).
Al di là degli aspetti tecnici, il punto essenziale che sottolineiamo è il rapporto di fiducia che deve instaurarsi tra l’applicazione utente da un lato e, direttamente ed unicamente, il processore dall’altro. Tale rapporto è basato su meccanismi di crittografia, inclusi quelli a chiave pubblica, non dissimili dai sistemi usati per la firma digitale, e si fondano sull’assunto essenziale di fidarci assiomaticamente del produttore, Intel nel caso SGX.
A riguardo, è interessante notare che Intel offre un servizio di attestazione dei propri prodotti. Il fornitore di un’applicazione software che richieda l’esecuzione di programmi e la condivisione di dati sensibili in un’infrastruttura di calcolo remota, ad esempio un server cloud, può interpellare tale servizio per avere conferma da Intel che la propria applicazione sia eseguita da un processore genuino, e quindi fidato, ovunque esso sia fisicamente dislocato.
Per inciso, soprattutto quando ad essere attestati da Intel sono processori posseduti da privati, questo processo di tracciamento centralizzato solleva potenziali problemi di privacy, risolti tramite un meccanismo di attestazione anonimizzata che, nella terminologia Intel, è chiamato Enhanced Privacy ID (EPID), peraltro già previsto in altra forma dal TCG.
Inoltre, sempre con il supporto di Intel (e l’implicito vincolo di fiducia che tale supporto richiede), è possibile per l’installatore di un data center sviluppare un proprio servizio di attestazione, tramite le Datacenter Attestation Primitives (DCAP) fornite da Intel.
Si noti che, in tal caso, il servizio di attestazione interpellato dall’applicazione sarà sì offerto da una parte terza indipendente da Intel (il gestore del data center), ma solo come elemento intermedio di una catena di fiducia che ha ad un capo l’applicazione utente e, all’altro capo, ancora Intel.
Un’ulteriore e molto recente evoluzione tecnologica è orientata al supporto più organico alla virtualizzazione, in particolare in ambienti cloud, con la Secure Encrypted Virtualization (SEV) di AMD e le Trust Domain Extensions (TDX) di Intel, che permettono di creare macchine virtuali isolate a livello hardware, indicate nel caso di Intel con il nome di “trust domain”.
Trusted Computing: gli interrogativi aperti
La breve sintesi delle tecnologie di Trusted Computing presentata sopra ha come messaggio di fondo il ruolo essenziale del produttore del processore all’interno della catena di fiducia. In tale scenario, è lecito porsi diversi, fondamentali interrogativi. Che effetto possono avere vulnerabilità introdotte, per errori di progetto, all’interno del processore, come nei famosi casi degli attacchi Meltdown e Spectre, rivolti proprio a processori Intel?
Peggio, come escludere che siano introdotte in maniera intenzionale delle vulnerabilità o backdoor, che consentano di aggirare in maniera silenziosa i meccanismi di protezione ufficialmente offerti dal processore, magari ad opera del produttore o, per suo tramite, di qualche ente governativo?
Non stupisce che la Cina abbia da tempo intrapreso la strada della sovranità tecnologica, incamminandosi verso la considerevole impresa di progettare e realizzare autonomamente propri processori, principalmente per il segmento del calcolo ad alte prestazioni.
Con ritardo, anche l’Europa si è mossa lungo questa strada, con la European Processor Initiative (EPI) lanciata nel 2018 e basata su tecnologie europee e/o aperte, anche a livello hardware, con attenzione ad architetture di processori non-proprietarie quali RISC-V.
Chiaramente, la strada verso questo obiettivo è lunga ed incerta, pesantemente ostacolata da divari prestazionali, forse incolmabili, e da comprensibili inerzie nell’adattamento degli ecosistemi software. Certo è, comunque, che la problematica della sicurezza dei dati e della fidatezza sono ormai considerate un elemento essenziale nell’evoluzione delle tecnologie informatiche. Ad avviso di chi scrive, è opportuno che i concetti qui discussi escano dal recinto dei tecnicismi ed entrino anzi nel vocabolario e nella forma mentis degli utenti, dei progettisti e dei decisori.
Conclusioni
Anche sul fronte della narrazione commerciale, la problematica è decisamente calda e dibattuta, spesso sotto la generica etichetta di “Confidential Computing”.
Sarebbe forse più accurato, a nostro avviso, continuare a parlare di Trusted, piuttosto che Confidential Computing, non solo e non tanto per una questione di accuratezza tecnica (“confidentiality” in senso tecnico è usato per parlare di cifratura, non di autenticazione/integrità).
Principalmente, perché la nozione di “trust” veicola il concetto fondamentale che esperti ed utenti interessati ad aspetti di sicurezza e privacy devono ben metabolizzare: progettare un’architettura sicura significa, in ultima analisi, disegnare una complessa rete di rapporti di fiducia e, nella scelta delle tecnologie, identificare chiaramente i ruoli, gli assunti ed i meccanismi che tengono in piedi le garanzie di sicurezza offerte agli utenti.