POLITECNICO DI TORINO III Facoltà di Ingegneria dell’Informazione Corso di Laurea in Ingegneria delle Telecomunicazioni Tesi di Laurea Magistrale Architetture per la protezione dell’informazione nei sistemi embedded Relatori: prof. Guido Masera ing. Andrea Molino ing. Fabrizio Vacca Candidato: Federico Bianco Levrin Luglio 2007 ii Sommario Negli ultimi anni l’ampliamento della gamma dei servizi e applicazioni offerti dai sistemi embedded ha dato la nascita di nuove preoccupazioni per quanto riguarda la sicurezza delle informazioni. Con il termine “sistema embedded ” si identificano dei sistemi a microprocessore progettati appositamente per una determinata applicazione, integrati nel sistema che controllano e in grado di gestirne le funzionalità. Il problema principale per quanto riguarda la sicurezza è lo scambio costante di dati e istruzioni fra la memoria esterna e la CPU. La memoria esterna presente nella maggior parte di questi dispositivi può contenere dati confidenziali, come software coperto da copyright, che per ovvie ragioni devono essere preservati. La soluzione proposta al problema si basa sull’utilizzo di un sistema crittografico che permette solamente alla CPU di conoscere il reale contenuto della memoria esterna. Il contenuto della memoria esterna è cifrato cosicché da rendere invano qualsiasi tentativo di lettura diretta della memoria. Questa soluzione considera la CPU come un’entità sicura, quindi al suo interno i dati e le istruzioni sono in chiaro mentre sono cifrati al suo esterno. La scelta della tipologia del sistema cifrante deve essere fatta in rispetto delle specifiche del sistema, e molto spesso è un compromesso fra il livello di sicurezza desiderato e la perdita di performance che ci si può permettere. Il sistema crittografico, oggetto della tesi, è stato sviluppato per poter essere inserito all’interno del microprocessore LEON3, un progetto open source di un microprocessore RISC sviluppato dalla Gaisler Research. Il microprocessore è sintetizzato con il linguaggio VHDL, può essere efficientemente implementato nelle tecnologie FPGA e ASIC ed è disponibile sotto GNU General Public License. La scelta di sviluppare un sistema crittografico specificatamente per il microprocessore LEON3 è stata dettata dal fatto che quest’ultimo, in ambito commerciale, sta riscuotendo particolare successo per lo sviluppo di SOC (System On a Chip). Il LEON3 ha un sistema cache molto flessibile che consiste in due cache separate per la gestione dei dati e delle istruzioni. Il sistema crittografico è stato posizionato fra il controllore della memoria cache per le istruzioni, e il modulo atto ad inoltrare le richieste di trasferimento dati sul bus AMBA AHB (figura 1). L’architettura sviluppata è in grado di intercettare le richieste di trasferimento di istruzioni fatte dalla iii CPU verso l’area di memoria cifrata e di eseguire le operazioni necessarie alla decifratura parallelamente alle operazioni di fetch delle istruzioni dalla memoria esterna. Le scelte progettuali sono rivolte a realizzare un’unità crittografica trasparente al microprocessore LEON3 ed in grado di ridurre al minimo la perdita di prestazioni in termini di tempo di accesso alla memoria esterna. Microprocessore LEON3 MEMORIA ESTERNA SISTEMA CRITTOGRAFICO MEMORIA CACHE CPU BUS AMBA AHB Figura 1. Collocazione del sistema crittografico La scelta dell’algoritmo di crittografia è stata orientata sull’utilizzo dell’Advanced Encryption Standard (AES). Conosciuto anche come Rijndael (benché, più propriamente, AES sia una particolare implementazione dell’algoritmo Rijndael), è un algoritmo di cifratura a blocchi utilizzato come standard dal governo degli Stati Uniti d’America. È stato adottato dalla National Institute of Standards and Technology (NIST) e dalla US FIPS PUB 197 nel novembre del 2001. La modalità di funzionamento dell’algoritmo di cifratura prescelto è la CTR (CounTeR) poiché è la modalità che meglio si adatta alle problematiche di accesso casuale ai dati come nel caso della lettura della memoria da parte della CPU che non è sequenziale (e.g. istruzione di salto). Il progetto del sistema crittografico è stato logicamente suddiviso in due parti. La prima parte prevede la progettazione di un core AES, con chiave di codifica a 128 bit, altamente prestante in termini di throughput dei dati, mentre la seconda parte prevede l’inserimento del core, precedentemente sviluppato, all’interno del microprocessore LEON3. Sono state realizzate e analizzate diverse architetture per l’implementazione dell’algoritmo AES sia per la funzionalità di codifica che di decodifica dei dati. In particolare sono state sviluppate due architetture differenti: la prima di tipo iterativo mentre la seconda di tipo fully unrolled. Entrambe le architetture sono in grado di eseguire le operazioni con un parallelismo di 128 bit (massimo per l’AES) e sono realizzate con differenti livelli di sub-pipeline (fino a due livelli). Il target tecnologico è l’FPGA poiché l’utilizzo di hardware riconfigurabile permette un’approccio decisamente più flessibile. L’FPGA utilizzata come riferimento per l’analisi delle prestazioni è la XC2V4000, un’FPGA di medie dimensioni della famiglia Virtex2 della XILINX. Le prestazioni del core AES sviluppato sono, rispetto alle altre implementazioni sia di tipo accademico che commerciale disponibili in letteratura, decisamente competitive (figura 2). Il massimo delle prestazioni, in termini di throughput, si sono ottenute con l’implementazione fully unrolled con due livelli di sub-pipeline che permette di raggiungere un bit rate (stimato) pari a 40,40 iv Gbps. L’architettura più compatta è di tipo iterativo con un livello di sub-pipeline che garantisce un throughput (stimato) di 2,89 Gbps a fronte di un’occupazione di sole 1.840 Slice. 20.000 Area [Slice] 10.000 Figura 2. Grafico riassuntivo delle prestazioni del core AES TESI, Iterativa TESI, Fully unrolled Chodowiec et al., 2001 Hodjat et al., 2004 McLoone et al., 2001 Saggese et al., 2003 Standaert et al., 2003 Wang et al., 2004 Zambreno et al., 2004 Zhang et al., 2004 1.000 1 10 Throughput [Gbps] 50 Il sistema crittografico inserito nel microprocessore LEON3 può utilizzare una qualsiasi versione del core AES precedentemente descritto. L’implementazione più adatta è quella iterativa senza sub-pipeline che ha un critical path paragonabile a quello del microprocessore LEON3. L’impatto del sistema crittografico sulle prestazioni del microprocessore LEON3 è stato valutato attraverso l’esecuzione di un programma di test. La differenza di tempo necessario alla sua esecuzione con e senza il sistema crittografico rappresenta la perdita di performance che si stimano essere del 17%. Il lavoro di tesi si conclude con lo sviluppo di un software in grado di cifrare il contenuto di un file SREC. Il formato “S-record” (SREC) è stato sviluppato dalla Motorola ed è comunemente utilizzato per l’upload del firmware nelle memorie. Grazie a questo software, sviluppato in linguaggio C++, è possibile cifrare il contenuto della memoria esterna ovvero poter proteggere la proprietà intellettiva di un qualsiasi programma già precedentemente sviluppato. Con il presente lavoro si è voluto soddisfare il bisogno di embedding security necessario alle attuali e future applicazioni mediante la realizzazione di un framework completo per lo sviluppo di applicazioni sicure in ambito SOC. Infatti, a partire da un qualsiasi file sorgente è possibile creare un eseguibile cifrato compatibile con il microprocessore LEON3 modificato, ottenendo cosı̀ la protezione del codice eseguito secondo gli standard attuali di sicurezza. Il degrado di prestazioni del sistema sviluppato rispetto a quella originale è dimostrato essere contenuto, grazie alle alte prestazioni del modulo cifrante hardware realizzato. v Indice Sommario vi 1 Introduzione alle architetture hardware 1.1 Sviluppi storici . . . . . . . . . . . . . . 1.2 Hardware crittografico . . . . . . . . . . 1.2.1 (Co-)Processore crittografico . . . 1.2.2 Smart Card e dispositivi USB . . 1.2.3 RFID tags . . . . . . . . . . . . . 1.3 Sicurezza degli apparati hardware . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 FPGA vs. ASIC 1 1 3 3 3 4 4 7 3 Metodologia per il design dell’hardware 11 3.1 L’approccio Top-Down . . . . . . . . . . . . . . . . . . . . . . . . . . 12 3.2 Progettazione congiunta FPGA e ASIC . . . . . . . . . . . . . . . . . 14 4 AES - Advanced Encryption Standard 4.1 Introduzione . . . . . . . . . . . . . . . . . . . . . 4.2 Descrizione dell’algoritmo AES . . . . . . . . . . 4.3 Analisi dettagliata dell’algoritmo Rijndael . . . . 4.3.1 Il campo GF(28 ) . . . . . . . . . . . . . . 4.3.2 Moltiplicazione per x nel campo GF(28 ) . 4.3.3 Polinomi con coefficienti nel campo GF(28 ) 4.3.4 La funzione cifrante . . . . . . . . . . . . . 4.3.5 Schedulazione della chiave . . . . . . . . . 4.3.6 La funzione cifrante inversa . . . . . . . . 4.3.7 La cifratura inversa equivalente . . . . . . 4.3.8 Criteri di progetto . . . . . . . . . . . . . 4.4 Modi di funzionamento . . . . . . . . . . . . . . . 4.4.1 Electronic Code Book (ECB) . . . . . . . 4.4.2 Cipher Block Chaining (CBC) . . . . . . . vi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 15 17 22 23 24 24 25 28 30 32 33 35 35 36 4.5 4.4.3 Cipher Feedback (CFB) . . . . . . . . . . . 4.4.4 Output Feedback (OFB) . . . . . . . . . . . 4.4.5 Confronto dei modi di funzionamento . . . . Aspetti hardware . . . . . . . . . . . . . . . . . . . 4.5.1 Pipelining, Sub-Pipelining e Loop Unrolling 5 AES: Stato dell’arte nell’implementazione 5.1 Implementazioni lightweight . . . . . . . . . 5.1.1 Principi di progettazione . . . . . . . 5.1.2 Lavori presenti in letteratura . . . . . 5.1.3 Dettagli implementativi . . . . . . . 5.1.4 Caratteristiche dell’implementazione 5.2 Architetture ottimizzate per il throughput . 5.2.1 Principi di progettazione . . . . . . . 5.2.2 Lavori presenti in letteratura . . . . . 5.2.3 Dettagli implementativi . . . . . . . 5.2.4 Caratteristiche delle implementazioni . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38 40 41 41 43 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47 47 47 50 51 56 58 59 62 64 68 6 Implementazione dell’AES128 6.1 Architettura iterativa . . . . . . . . . . . . . . . . . . 6.1.1 Macchina a stati finiti (fsm) . . . . . . . . . . 6.2 Architettura fully unrolled . . . . . . . . . . . . . . . 6.3 Architetture per la cifratura dei dati (aes128 enc) . 6.3.1 Entity roundData enc . . . . . . . . . . . . . 6.3.2 Entity roundKey enc . . . . . . . . . . . . . . 6.3.3 Inserimento dei registri di sub-pipeline . . . . 6.4 Architetture per la decifratura dei dati (aes128 dec) 6.4.1 Entity roundData dec . . . . . . . . . . . . . 6.4.2 Entity roundKey dec . . . . . . . . . . . . . . 6.4.3 Inserimento dei registri di sub-pipeline . . . . 6.5 Sintesi del core crittografico AES128 . . . . . . . . . 6.5.1 Analisi delle performance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73 73 75 77 78 78 80 81 82 85 87 88 91 95 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 Tecniche per la protezione dell’informazione nei sistemi embedded 99 7.1 Il sistema cifrante . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99 7.2 Architetture: stato dell’arte . . . . . . . . . . . . . . . . . . . . . . . 100 8 Il processore LEON3 105 8.1 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105 8.2 Cache istruzioni . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108 8.2.1 Funzionamento . . . . . . . . . . . . . . . . . . . . . . . . . . 108 vii 8.3 8.4 8.2.2 Instruction cache tag . . . . . . . . . . . . . . . 8.2.3 Funzionalità aggiuntive della cache istruzioni . . La libreria GRLIB IP . . . . . . . . . . . . . . . . . . . 8.3.1 Organizzazione della libreria . . . . . . . . . . . 8.3.2 LEON3MP: configurazione del microprocessore Analisi del codice VHDL . . . . . . . . . . . . . . . . . 8.4.1 Entity icache . . . . . . . . . . . . . . . . . . . 9 Leon3MP Crittografico 9.1 Modifiche apportate al codice VHDL . . . . . . . . . . 9.2 Principio di funzionamento dell’unità cifrante . . . . . 9.3 Entity sniffer mci . . . . . . . . . . . . . . . . . . . . 9.4 Simulazione del microprocessore Leon3MP crittografico 9.4.1 Prima simulazione . . . . . . . . . . . . . . . . 9.4.2 Seconda simulazione . . . . . . . . . . . . . . . 9.5 Conclusioni e sviluppi futuri . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109 109 115 115 116 120 122 . . . . . . . 131 . 131 . 134 . 136 . 139 . 143 . 146 . 148 A Il formato S-record 151 Bibliografia 153 viii Capitolo 1 Introduzione alle architetture hardware Tradizionalmente gli algoritmi di crittografia sono implementati in hardware allo scopo di ottenere alte prestazioni, in termini di throughput, rispetto all’alternativa software. Tuttavia il requisito delle attuali e future applicazioni richiede delle caratteristiche aggiuntive. Il basso consumo energetico e la bassa occupazione di silicio stanno diventando requisiti sempre più importanti nel campo delle smart card e RFID. Esistono numerosi algoritmi di crittografia ma solo un piccolo numero di questi è utilizzato nella pratica. RSA e DES sono prominenti esempi di algoritmi frequentemente utilizzati; sono inoltre un esempio di algoritmi che stanno gradualmente scomparendo a favore di altri più recenti e performanti. Algoritmi basati su curve ellittiche sono diventati popolari nel campo della firma digitale. L’Advanced Encryption Standard (AES) data la sua sicurezza e le sue specifiche pubbliche è stato scelto come successore del DES. Si presume che in un prossimo futuro venga utilizzato in numerose applicazioni come è successo al suo predecessore. 1.1 Sviluppi storici L’implementazione hardware degli algoritmi di crittografia ha una lunga storia. Già nel 1930 le macchine crittografiche basate su rotori erano frequentemente utilizzate in applicazioni militari allo scopo di cifrare e decifrare informazioni sensibili. Le macchine a rotori erano dei dispositivi elettromeccanici che implementavano complesse sostituzioni poli-alfabetiche in maniera veloce e semplice per l’utente; queste caratteristiche ne sancirono la loro popolarità. Con l’avvento del calcolatore elettronico (computer) vi è la possibilità di realizzare calcoli sempre più complessi in tempi ridotti. Conseguentemente la criptoanalisi 1 1 – Introduzione alle architetture hardware è divenuta molto potente e si è dovuto sviluppare nuovi algoritmi di cifratura. Lo sviluppo è da ora rivolto alla realizzazione di algoritmi in grado di essere eseguiti in maniera efficiente da un computer. Tuttavia nel 1970 quando furono inventati i moderni sistemi di crittografia come il DES e l’RSA, divenne ancora una volta interessante implementare questi algoritmi in un hardware dedicato. Infatti un computer standard di questo periodo era troppo lento per poter eseguire velocemente i nuovi algoritmi di cifratura; si rese quindi necessario sviluppare delle implementazioni in hardware dedicati. Questa situazione è cambiata più volte nel corso degli anni. In accordo con la legge di Moore, sia la potenza che la memoria di un computer sono diventate col passare del tempo incredibilmente veloci e poco costose, ed i moderni personal computer sono sufficientemente veloci per la maggior parte delle applicazioni. Tuttavia, con il sempre maggiore uso di sistemi di crittografia in differenti applicazioni, il bisogno di memorizzare in maniera sicura le chiavi di cifratura diventa prioritario e, sfortunatamente, un personal computer non è progettato per garantire questa priorità. Negli scorsi anni è stato chiaro come un personal computer è insicuro e non è una piattaforma adeguata per custodire le chiavi di cifratura. A titolo di esempio, in un’applicazione che richiede la firma elettronica il firmatario è tenuto alla memorizzazione dei dati relativi alla propria firma in maniera sicura; conseguentemente un sistema hardware di crittografia che permette l’archiviazione in modo sicuro della chiave diventa appetibile. Proprio per questo fatto vi è la necessità di creare un’area denominata hardware security module cioè un dispositivo atto a realizzare l’algoritmo crittografico, cossiché la chiave di cifratura non debba “uscire” dal dispositivo. Il bisogno di avere funzioni di crittografia e di memorizzazione sicura dei dati coinvolge sempre più applicazioni. La Smart card, utilizzata come tessera del bancomat o come scheda SIM nel telefono portatile, è un esempio della larga diffusione di questi dispositivi; recentemente hanno avuto ricevuto ampia attenzione anche i dispositivi di identificazione via radio: RFID (Radio Frequency IDentification). Il bisogno crescente di embedding security nei dispositivi portatili e non ha spinto sia le industrie che i gruppi di ricerca a ritornare alle implementazioni hardware degli algoritmi di crittografia a scapito di quelle software. Al giorno d’oggi possiamo identificare due scenari in cui l’implementazione hardware porta dei vantaggi rispetto a quella software. Per prima cosa l’hardware consente di realizzare un’applicazione ad alta velocità in cui il co-processore crittografico “alleggerisce” il resto del sistema dal costo computazionale dell’algoritmo di cifratura. In secondo luogo è possibile realizzare dispositivi ottimizzati per un basso consumo energetico e una bassa occupazione spaziale di silicio. In entrambi gli scenari l’immagazzinamento della chiave è prioritario e realizzabile in maniera sicura ed affidabile. 2 1.2 – Hardware crittografico 1.2 Hardware crittografico Si intende per hardware crittografico un qualsiasi circuito hardware in grado di eseguire un algoritmo di crittografia. Questo piuttosto ampio concetto include anche i processori standard che semplicemente eseguono l’algoritmo di crittografia. Nelle seguenti sezioni si farà un resoconto sugli hardware crittografici più diffusi analizzandone le loro peculiarità. 1.2.1 (Co-)Processore crittografico Nel caso più generale possiamo far riferimento al processore general purpose che esegue l’algoritmo di crittografia grazie l’appoggio di un dispositivo hardware esterno. Il (co-)processore crittografico è un dispositivo che è stato specificamente sviluppato per eseguire un certo tipo di algoritmo di cifratura. Tipicamente, uno o più (co-)processori crittografici affiancano un processore general purpose e ciascuno di essi è responsabile delle operazioni di cifratura. Tra i sistemi che si basano su questo approccio ci sono i moduli hardware di sicurezza (HSMs) e gli acceleratori SSL entrambi sviluppati su schede con interfaccia PCI. Esiste un numero crescente di acceleratori SSL allo stato dell’arte che utilizzano la tecnologia dell’FPGA per implementare le funzioni di cifratura. Per un sistema HSM l’archiviazione sicura delle chiavi di cifratura è di massima importanza soprattutto quando è utilizzato come dispositivo per la creazione della firma o all’interno di operazioni bancarie. Per questo tipo di applicazioni diventa prioritario la resistenza agli attacchi ([3, 18]) piuttosto che la potenza di calcolo; inoltre se queste apparecchiature sono utilizzate all’interno di una rete aperta, come ad esempio durante le fasi di autenticazione in rete internet, bisogna prestare particolare attenzione al timing attack [17]. Il processore crittografico come descritto in questa sezione necessita di essere gestito da un software che ne permetta l’interfaccia con il mondo esterno. Questi software sono denominati Application Programming Interface (API) ed è frequente che una loro errata programmazione apra una porta agli attacchi [6]. 1.2.2 Smart Card e dispositivi USB Il termine smart card è comunemente utilizzato per indicare delle schede che contengono al loro interno un circuito integrato, in alternativa sono anche chiamate Integrated Circuit Card (ICC) [15]. Al giorno d’oggi si presume che le smart card siano inviolabili e propio per questo le loro funzioni di sicurezza sono utilizzate in diverse applicazioni. Le smart card si interfacciano con il proprio lettore attraverso una contattiera elettrica che tra le altre cose fornisce alla scheda l’alimentazione e il segnale di clock. Recentemente si stanno diffondendo smart card equipaggiate con 3 1 – Introduzione alle architetture hardware un’interfaccia radio che dunque, a differenza delle tradizionali, non necessitano un contatto fisico con il lettore. Possiamo distinguere due tipi di smart card: le Memory cards e le Microprocessor cards. Le Memory cards oltre ad un Electrically Erasable Programmable Read-Only Memory (EEPROM) hanno al loro interno anche la logica di sicurezza e una memoria per la lettura/scrittura dei dati. La logica di sicurezza permette di proteggere una certa zona di memoria implementando un semplice meccanismo di autenticazione. Le Microprocessor cards contengono un microcontrollore prevalentemente costituito da una Central Processing Unit (CPU), da una memoria (ROM e RAM), da delle periferiche di Input e Output (IO) e da qualche modulo per la crittografia. Tipicamente questi moduli sono un generatore di numeri pseudo-casuali, un acceleratore DES e uno RSA. Le attuali smart card di tipo microprocessor integrano una CPU da 8, 16 o 32 bit, fino a 64 Kbyte di memoria di tipo ROM, fino a 64 Kbyte di memoria EEPROM e fino a 1 Kbyte di memoria RAM. Le microprocessor card sono tipicamente utilizzate per le svolgere applicazioni sicure. A causa del limite di spazio e di potenza di alimentazione è necessario sviluppare per questi dispositivi delle versioni ad hoc degli algoritmi di crittografia. La resistenza ad ogni tipo di attacco è la prerogativa da tenere in conto durante lo sviluppo di una smart card. Le periferiche di sicurezza basate sullo standard USB sono essenzialmente una smart card con interfaccia USB. L’implementazione degli algoritmi di crittografia è del tutto simile a quanto visto per le smart card. 1.2.3 RFID tags Le RFID tags [16] stanno avendo già tutt’oggi un largo impiego come alternativa al codice a barre. Tuttavia è possibile utilizzare questa tecnologia per applicazioni in cui è richiesta la sicurezza nel trattamento dei dati. Uno dei vantaggi delle RFID tags consiste nel fatto che non richiedo un contatto fisico con il lettore e possono essere utilizzate a qualche metro di distanza dal lettore (il limite dipende dal modello di tags utilizzato). Ciò nonostante, queste tags ricevono l’alimentazione dal lettore e quindi è fondamentale poter implementare una versione a bassissimo consumo degli algoritmi di crittografia. 1.3 Sicurezza degli apparati hardware Negli ultimi anni si é visto come le implementazioni degli algoritmi crittografici possono essere attaccate in vari modi. Gli attacchi di tipo invasivo sono fatti accedendo direttamente al circuito elettrico dell’apparato. Quelli semi-invasivi, invece, fanno 4 1.3 – Sicurezza degli apparati hardware accesso al dispositivo ma senza stabilire un contatto elettrico. Infine, quelli noninvasivi sono portati a termine accedendo solamente alle porte standard di input e output. Tutte e tre le tipologie di attacco presentate sono di tipo attivo, ovvero, l’aggressore perpetua attivamente un uso illecito del dispositivo. Sono anche noti attacchi di tipo passivo, noti anche col nome di side-channel attacks. Questi ultimi sono perpetuati monitorizzando informazioni sensibili del dispositivo. Ad esempio si può effettuare il monitoraggio di alcune grandezze fisiche come le emissioni elettromagnetiche piuttosto che il consumo energetico del dispositivo che, sono direttamente correlate con le operazioni svolte dal dispositivo. La sicurezza delle implementazioni contro gli attacchi non-invasivi è stata di recente discussa da due gruppi di ricerca del VAM3 ([5] e [4]). 5 1 – Introduzione alle architetture hardware 6 Capitolo 2 FPGA vs. ASIC Esistono due metodi convenzionalmente utilizzati per l’implementazione in hardware degli algoritmi logici. Il primo metodo si basa sull’utilizzo di una tecnologia hardwired su misura, per esempio mediante lo sviluppo di un Application Specific Integrated Circuit (ASIC). L’ASIC è specificamente sviluppata per eseguire un determinato calcolo ed è particolarmente efficiente. Per efficienza si intende che è possibile realizzare un’applicazione molto veloce, oppure che richieda una piccolo spazio su silicio o infine che richieda pochissima energia. Tuttavia non è possibile modificare il circuito dopo la produzione, questo forzerebbe un ridisegnamento del circuito e la sua successiva riproduzione. Il secondo metodo si basa invece sull’utilizzo di circuiti programmati via software ed è, per ovvie ragioni, decisamente più flessibile. Cambiando le istruzioni software è possibile cambiare le funzionalità del sistema senza modificare l’hardware utilizzato. Il rovescio della medaglia di questo approccio è il prezzo da pagare in termini di prestazioni rispetto ad un’analoga implementazione in ASIC. L’utilizzo di hardware riconfigurabile si pone a metà strada fra l’implementazione hardware e quella software, ottenendo delle potenzialità decisamente maggiori rispetto a quelle software e mantenendo un alto livello di flessibilità rispetto a quella hardware. L’hardware riconfigurabile, di cui le Field Programmable Gate Arrays (FPGAs) ne sono un esempio, contengono una matrice di celle elementari la cui funzione è programmabile. Queste celle, anche note col nome di blocchi logici, sono interconnesse attraverso una rete di collegamenti anch’essi programmabili. L’utilizzo di software di sintesi e di implementazione permette di descrivere il progetto ad alto livello per poi tradurlo a basso livello e poter cosı̀ programmare l’FPGA. La possibilità di riconfigurazione offerta da una FPGA permette di ottenere diversi vantaggi quando è utilizzata in applicazioni di crittografia: Algorithm Agility Questo definizione si riferisce alla possibilità di poter passare 7 2 – FPGA vs. ASIC da un’algoritmo all’altro in base alle richieste dell’applicazione. Si può osservare che la maggior parte dei moderni protocolli di sicurezza, come l’SSL o l’IPsec, sono algoritmi che permettono l’utilizzo di diverse tipologie di algoritmi di crittografia. L’algoritmo di crittografia utilizzato viene negoziato all’inizio della sessione e puo essere scelto fra un’ampia varietà di algoritmi. Algorithm Upload E’ utile che il dispositivo possa essere aggiornato con i più recenti algoritmi di crittografia senza doverlo sostituire e quindi di poter disporre di un’apparato sempre compatibile con le nuove applicazioni. Da un punto di vista crittografico, la possibilità di aggiornare il dispositivo può rendersi necessaria perchè gli attuali algoritmi possono essere considerati insicuri (e.g. DES), oppure non più a norma (e.g. DES), oppure infine per supportare un nuovo standard (e.g. AES). Si deve tenere in conto inoltre che l’aggiornamento di un’apparato potrebbe essere impossibile a causa della sua dislocazione, per esempio se è all’interno di un satellite artificiale. L’utilizzo di un’FPGA aggiornata a distanza, magari attraverso una rete di telecomunicazione, è sicuramente preferibile rispetto un’ASIC che per aggiornarla sarebbe necessario sostituirla. Algorithm Modification Ci sono applicazioni nelle quali è richiesto modificare in parte lo standard crittografico, per esempio usando S-Boxes (vedi standard AES) o permutazioni proprietarie. Queste modifiche possono essere facilmente fatte se si sta utilizzando un’FPGA. Un esempio in cui l’algoritmo standard è stato leggermente modificato e nella crittografia delle password in UNIX in cui l’algoritmo DES è usato 25 volte in una riga con una mappatura differente per l’espansione. E’ altrettanto interessante poter adattare il codificatore a blocco DES o AES con S-Boxes proprietarie al fine di incrementare la sicurezza. Inoltre in molte occasioni è necessario modificare le primitive o il metodo di operare di uno standard in accordo con l’applicazione che ne farà uso. Throughput Un processore general-purpose non è ottimizzato per una veloce esecuzione dell’algoritmo, specialmente nel caso di algoritmi di crittografia basati su chiave pubblica e privata. Questo è dovuto all’assenza, in questo tipo di dispositivi, di istruzioni adatte all’elaborazione aritmetiche in modulo su operandi di grandi dimensioni. L’aritmetica modulare include per esempio l’elevamento ad esponente per RSA e la moltiplicazione, l’elevamento al quadrato, l’inversione e l’addizione per i sistemi crittografici basati su curve ellittiche. Sebbene sia tipicamente più lenta di un’implementazione in ASIC, l’implementazione in FPGA ottiene una sostanziale incremento di prestazioni rispetto all’implementazione software, soprattutto nelle applicazioni sopracitate. Cost Efficiency Ci sono due fattori di costo da tenere in considerazione quando si 8 analizza l’efficienza di costo in un’FPGAs: il costo di sviluppo e il costo di ogni singola unità. Il costo di implementazione in FPGA, di un dato algoritmo, è decisamente inferiore rispetto all’alternativa ASIC, poiché è facile utilizzare le risorse messe a disposizione da una FPGA ed è possibile testare il risultato senza costi aggiuntivi. Queste caratteristiche rendono estremamente ridotto il time-to-market che oggigiorno è un’importante fattore di costo. Tuttavia, per alti volumi di produzione la soluzione basata su ASIC ha senz’altro un’efficienza di costo maggiore dato il basso costo per unità che si riesce ad avere in fase di produzione. 9 2 – FPGA vs. ASIC 10 Capitolo 3 Metodologia per il design dell’hardware Durante la realizzazione di circuiti digitali è fondamentalmente seguire una corretta strategia di progetto che permetta di ridurre la complessità del progetto. Neil Weste ha individuato quattro punti che devono essere seguiti durante lo sviluppo di un circuito digitale: gerarchia, regolarità, modularità e località [33]. In questo capitolo si discuterà delle strategie di progetto che bisogna seguire durante lo sviluppo di un circuito digitale. Organizzare in maniera gerarchica il sistema è un’importante strategia per lo sviluppo di complessi circuiti digitali. Per rafforzare la gerarchia è possibile fare delle astrazioni che permettano di maneggiare in maniera semplice le complessità del sistema senza perdersi nei dettagli. La gerarchia si può ottenere suddividendo i moduli hardware in sotto-moduli di dimensioni tali da rendere più semplice lo sviluppo del sistema. La suddivisione del circuito in sotto-moduli corrisponde all’approccio del divide et impera utilizzato in ambiente software. Questo aiuta a ridurre la complessità dei sotto-moduli e ad ottenere la possibilità di poterli riutilizzare. La regolarità è una strategia di progetto che ha l’obbiettivo di mantenere il numero di sotto-moduli derivanti dalla suddivisione gerarchica entro dei limiti. Una struttura che fa uso di piccolo numero di sotto-moduli, paragonata ad una che ne fa alto uso, garantisce di realizzare una struttura regolare che rende minimo lo sforzo nella gestione dei collegamenti fra i vari moduli (datapath); ottimizzare un singolo blocco migliora l’intero datapath. Le standard-cell utilizzate nei ICs sono un esempio di regolarità. La modularità richiede un ben definito interfacciamento fra i sotto-moduli. L’interfacciamento è definito senza ambiguità dalle proprietà del blocco che possono riguardare, tra le altre cose, l’aspetto elettrico e/o funzionale del blocco stesso. E’ chiaro che l’interfacciamento semplifica l’assemblaggio di ampi moduli a partire dall’istanza di uno o più sotto-moduli. Un buon esempio di modularità sono le standard-cell che 11 3 – Metodologia per il design dell’hardware obbediscono a rigidi schemi per il loro interfacciamento. La località è una strategia di progetto che nasconde i dettagli dei moduli: le caratteristiche costruttive del blocco dovrebbero rimanere nascoste al suo interno a garanzia dell’astrazione delle sue funzioni. Nel caso in cui la località è affrontata dai sotto-moduli, le caratteristiche del blocco possono essere predette a partire dai sotto-moduli. Un esempio di località sono i sotto-moduli con l’uscita registrata che permettono di predire la massima frequenza di clock di un blocco partendo dall’analisi dei sotto-moduli stessi. Contrariamente i moduli che hanno un cammino combinatorio impedisce questo e viola la strategia di progetto basata sulla località. 3.1 L’approccio Top-Down Al fine di sviluppare un complesso sistema digitale è necessario utilizzare una progettazione strutturata che sia capace di determinare il prima possibile i potenziali punti deboli onde evitare inutili sprechi di tempo. Per sistemi di grandi dimensioni questo è possibile solamente adottando un’approccio di tipo top-down che suddivide il problema alla ricerca dell’hardware ottimale all’interno dei vari strati di astrazione. Il più alto livello di astrazione si pone l’obbiettivo di definire le funzionalità e alcune condizioni di contorno sotto le quali il circuito deve operare. Il più basso livello, invece, ha lo scopo di individuare l’implementazione del circuito su silicio. La progettazione top-down crea l’hardware necessario partendo da una descrizione ad alto livello per poi raffinarla attraverso alcuni livelli intermedi di astrazione fino ad ottenere l’implementazione fisica. La metodologia top-down con i suoi diversi livelli di astrazione mantiene la complessità di progettazione di ciascun livello entro i propri limiti. Nello sviluppo di un complesso sistema digitale l’approccio top-down permette di suddividere il problema in un insieme di problemi di complessità inferiore. Questa suddivisione del problema segue la strategia del divide et impera, che è riconosciuta essere la più efficiente nel risolvere i problemi in campo informatico. I sotto-problemi, derivanti dalla decomposizione del problema generale, possono essere classificati all’interno dei livelli di astrazione presentati nella figura 3.1. La figura 3.1 elenca cinque livelli di astrazione che sono comunemente distinti nel campo dello sviluppo di circuiti digitali. Questi cinque livelli di astrazione sono il livello di sistema (system level), il livello algoritmico (algorithmic level), il livello architetturale (architectural level), il livello di registro (register-transfer level) e il livello di circuito (circuit level). Una breve descrizione di questi livelli è data qui di seguito: System Level Il livello di sistema definisce le funzionalità del sistema e le condizioni al contorno sotto le quali il sistema deve operare. Il livello di sistema 12 System Functionality, Constraints Algorithm Algorithm Hierarchical partitioning Cycle accuracy Architecture Registertransfer Technology mapping Circuit Details added Abstraction level 3.1 – L’approccio Top-Down Figure 5 Abstraction levels Figura 3.1. Livelli di astrazione è il livello più alto di astrazione e per questo descrive il sistema senza troppi dettagli. Essenzialmente in questo livello vengono descritti il tipo di applicazione e le funzionalità che il circuito deve implementare senza indicare come realizzarle. Algorithmic Level Il livello algoritmico esplora le differenti alternative necessarie a realizzare le funzionalità desiderate dal circuito. È un raffinamento delle indicazioni provenienti dal livello superiore. Molto spesso il modello funzionale del circuito è scritto usando un linguaggio di programmazione che permette di descrivere le funzionalità del circuito in maniera rapida. Architectural Level Il livello architetturale di un circuito definisce il circuito attraverso i suoi moduli e sotto-moduli. Questi moduli servono ad implementare le funzionalità definite nei livelli superiori. Ci sono tipicamente due tipi di approccio che permettono di ricercare la massima efficienza architetturale. Il primo prevede di ricercare l’hardware necessario ad implementare il maggior numero di funzioni del modello ad alto livello. Il secondo, invece, cerca di ottenere il massimo parallelismo dell’hardware sfruttando il fatto che molti algoritmi possono processare i dati in parallelo. L’istanza di più moduli, o sotto moduli, incrementa la capacità computazionale quando questi operano allo stesso tempo. Register-Transfer Level Il livello RTL perfeziona il livello architetturale definendo in maniera precisa la struttura dei moduli e sotto-moduli. Il livello di registro definisce, in poche parole, quali operazioni devono essere svolte in un determinato ciclo di clock, ottenendo cosı̀ una descrizione accurata a livello di clock. I circuiti digitali sono solitamente sincroni cioè sono dei circuiti in cui tutte le operazioni sono governate da un unico segnale: quello di clock. In questo livello si descrivono i segnali in maniera tale che possano essere direttamente ricondotti a segnali elettrici; ciò significa che la modellizzazione a livello di registro è accurata al bit. 13 3 – Metodologia per il design dell’hardware Circuit Level Il livello di circuito (o gate level ) rappresenta l’implementazione fisica del circuito. E’ ottenuta mappando le funzionalità desiderate su di una data tecnologia. Esistono due tipi di tecnologia prevalentemente utilizzate: la prima è basata su dispositivi a logica riconfigurabile mentre la seconda è basata sull’implementazione su misura su silicio. La prima opzione prevede tipicamente l’utilizzo di FPGA che è un dispositivo prodotto in serie e già disponibile sul mercato. Tuttavia il costo dell’FPGA e il suo considerevole consumo energetico ammette il suo utilizzo solo in piccoli lotti di produzione o in fase di prototipazione. L’implementazione su misura su silicio è indicata per grandi volumi di produzione e permette di ottimizzare il progetto per alte frequenze di clock o bassi consumi energetici. Lo stato dell’arte di questa tecnologia permette di realizzare circuiti digitali, basati sull’utilizzo di transistor CMOS, attraverso una progettazione che fa uso di standard-cell. 3.2 Progettazione congiunta FPGA e ASIC Il flusso di progetto di un circuito digitale e molto spesso identico sia per l’FPGA che per l’ASIC. I programmi di sintesi permettono di tradurre il modello HDL (VHDL o Verilog) scritto a livello di registro in una netlist, utilizzata per configurare l’FPGA, o una descrizione a livello di porte logiche (gate-level), utilizzata per lo sviluppo di un’ASIC. E’ quindi possibile ottenere, almeno in parte, un descrizione comune fra le due tecnologia ed ottenere cosı̀ dal progetto la massima versatilità. 14 Capitolo 4 AES - Advanced Encryption Standard 4.1 Introduzione Lo standard di cifratura AES, acronimo di Advanced Encryption Standard, è nato su proposta del National Institute of Standard and Technology (NIST) al fine di sostituire il DES che era stato utilizzato per vent’anni e la cui sicurezza risultava ormai praticamente nulla. Tale standard di cifratura doveva esibire caratteristiche di sicurezza superiori al DES, essere applicabile in un ampio spettro di soluzioni hardware e software (il DES era stato pensato principalmente per applicazioni hardware), essere di pubblico dominio e divulgazione e non avere licenza di utilizzo. Sarebbe stato utilizzato da strutture governative statunitensi e, su base volontaria, in organizzazioni private. L’algoritmo cifrante doveva essere un cifratore simmetrico a blocchi con chiavi a 128, 192 e 256 bit e una dimensione del blocco che al minimo doveva essere di 128 bit. Tale iniziativa fu avviata il 2 febbraio del 1997 e fu resa pubblica con un bando di concorso il 12 settembre dello stesso anno. Il 20 agosto 1998 il NIST annunciò alla prima conferenza “First AES Candidate Conference” (AES1) che i candidati erano 15 algoritmi realizzati da gruppi di crittografi provenienti da tutto il mondo. Il NIST sollecitò pubblici commenti sui candidati che furono discussi alla seconda conferenza AES2, avvenuta nel marzo del 1998. Il 15 aprile 1999 furono tratte le conclusioni di queste analisi e si creò una lista ristretta di cinque candidati che fu resa pubblica il 9 agosto 1999: MARS sviluppato da IBM, RC6 dei laboratori RSA, Rijdael sviluppato da due ricercatori belgi, Serpent di Ross Anderson, Eli Biham, Lars Knudsen e Twofish sviluppato da Bruce Schneier, John Kelsey, Doug Whiting, David Wagner, Chris Hall e Niels Ferguson. La terza conferenza AES3 tenutasi a New York nell’aprile 2000, consentı̀ una pubblica conferenza sui finalisti e il 2 ottobre 15 4 – AES - Advanced Encryption Standard 2000 fu annunciato che il vincitore era l’algoritmo Rijndael. Dopo quest’anno il NIST preparò un preliminare del Federal Information Processing Standard (FIPS) per l’AES e lo pubblicò nel febbraio del 2001, lasciando tre mesi di attesa in risposta di pubblici commenti. Nell’estate del 2001 l’AES, e quindi Rijndael, divenne lo standard di cifratura per i nuovi sviluppi. Rijndael (si pronuncia “Reign Dahl”, “Rain Doll”, o “Rhine Dahl”) è stato progettato dai due ricercatori belgi Vincent Rijmen (Catholic University of Leuven) e Joan Daemen (Proton World International). La denominazione dell’algoritmo deriva dalle iniziali del cognome di uno e dalle finali del cognome dell’altro. Al fine di consentire approfondite analisi delle prestazioni dall’algoritmo furono presentate applicazioni di riferimenti in Java e in C. I quindici algoritmi selezionati come semifinalisti furono: CAST-256 (Entrust Technology), CRYPTON (Future System), DEAL (Richard Outerbridge, Lars Knudssen), DFC (National Center of Scientific Reserch, France), E2 (NTT), FROG (TecApro International), HPC (Rich Schroeppel), LOKI97 (Lawrie Brown, Josef Pieprzyk, Jennifer Seberry), MAEGENTA (Deutsche Telekom), MARS (IBM), RC6 (RSA), Rijndael (Vincent Rijmen, Joan Daemen), Safer+ (Cylink), Serpent (Ross Anderson, Eli Biham, Lars Knudsen), Twofish (Bruce Schneier, John Kelsey, Doug Whiting, David Wagner, Chris Hall, Niels Ferguson). L’AES è adatto per piattaforme basate su processori ad 8 bit, su comuni processori a 32 bit ed è appropriato per implementazioni su hardware dedicato. Con l’implementazione hardware è possibile realizzare un’implementazione in cui il throughput è nell’ordine dei Giga-bit. L’efficienza dell’implementazione e l’assenza di licenza di utilizzo ha aperto la strada all’utilizzo dell’AES per applicazioni come le reti wireless in accordo con lo standard 802.11i e futuri standard come l’ISO 18033-3, IPSec e TLS. Sebbene l’AES sia utilizzato in molte e differenti applicazioni, l’implementazione hardware dell’algoritmo è prevalentemente rivolta all’ottimizzazione del throughput. Sono disponibili diverse pubblicazioni che riportano delle implementazioni mature dell’algoritmo AES: [7, 19, 25, 26, 29, 31]. La maggior parte di questi report mettono l’accento sull’ottimizzazione del throughput senza alcuna limitazione delle risolse utilizzate [31]. Solo alcune implementazioni provano a realizzare un’utilizzo efficiente delle risorse hardware, con prestazioni al limite, a partire da occupazioni spaziali di silicio e budget di potenza limitati. Molte pubblicazioni sono rivolte all’implementazione dell’AES su architetture riconfigurabili come le FPGA [7, 26]. Sono state pubblicate solamente poche architetture fatte su misura per l’implementazione su silicio [19, 29]. 16 4.2 – Descrizione dell’algoritmo AES 4.2 Descrizione dell’algoritmo AES Rijndael è un cifratore a blocchi iterativo con diverse opzioni per la dimensione del blocco dei dati trattati e della chiave. La dimensione del blocco d’ingresso coincide con la dimensione del blocco restituito in uscita dopo la cifratura o la decifratura, che in questo contesto viene genericamente indicata come cifratura inversa. Sono disponibili dimensioni della chiave e dei blocchi dati di 128, 192 e 256 bit. Successivamente sono state proposte altre due dimensioni: 160 e 224 bit. Lo standard AES utilizza un’unica dimensione del blocco dati, cioè un blocco da 128 bit (anche se non pregiudica l’uso di altri) e tre valori per la chiave (128, 192 e 256). In base alla dimensione della chiave si utilizzano le denominazioni indicative AES-128, AES-192 e AES-256. Più grande è tale dimensione maggiore è la sicurezza dell’algoritmo. La funzione non-lineare complessa utilizzata per cifrare o decifrare viene iterata per un numero di volte, o iterazioni (o round) che è in relazione alla dimensione della chiave: 10 iterazioni per chiavi a 128 bit, 12 iterazioni per chiavi a 192 bit e 14 iterazioni per chiavi a 256 bit. Inizialmente verrà descritto il principio di funzionamento dell’algoritmo come specificato nello standard AES [1], ovvero con dimensione del blocco dati fissa, successivamente verranno descritte le differenze quando si esegue l’estensione dei questa dimensione. Tra queste si vedrà come il numero delle iterazioni si modifichi anche al variare della dimensione del blocco dati che, come ricordato, nello standard AES resta fisso. Gli ingressi e le uscite dell’algoritmo AES (nel relativo standard FIPS PUB 197 la denominazione dell’algoritmo passa da Rijndael a AES [1]) sono sequenze di 128 bit, indicate anche come blocchi dati. Simili sequenze, ma con differenti dimensioni, si hanno per i tre tipi di chiave. I bit all’interno delle sequenze sono numerati da 0 alla dimensione del blocco, o della chiave, meno uno. Se si introduce un indice i che marca la posizione dei bit all’interno della sequenza è possibile avere un campo di variazione 0 ≤ i < 128 rispettivamente per i dati e per le chiavi dell’AES-128, 0 ≤ i < 192 per le chiavi dell’AES-192 e 0 ≤ i < 256 per le chiavi dell’AES-256. I bit delle sequenze sono accorpati in byte che risultano essere le unità elementari di elaborazione. Il blocco può quindi essere interpretato come composto da un certo numero di otto bit contigui, ovvero di 16 byte (se l’indie n indica la posizione del byte all’interno della sequenza, si ha 0 ≤ n ≤ 15), quello delle chiavi può essere di 16, 24 o 32 byte. Se indichiamo con a0 , a1 , a2 , . . . , a15 i byte del blocco d’ingresso o d’uscita e con bit0 , bit1 , bit2 , . . . , bit127 i bit ordinati di queste sequenze dati, la reciproca associazione è: 17 4 – AES - Advanced Encryption Standard a0 a1 a15 = (bit0 , bit1 , . . . , bit7 ) = (bit8 , bit9 , . . . , bit15 ) ··· = (bit120 , bit121 , . . . , bit127 ) (4.1) Per le chiavi è possibile estendere la regola utilizzando l’indice n che varia in base alla lunghezza della chiave tra 0 e 15, 23 o 31. Per cui vale la regola: an = (bit8n , bit8n+1 , . . . , bit8n+7 ) (4.2) Da notare che all’interno dei byte si usa la convenzione che il bit più a sinistra è quello con indice 7, quello più a destra con indice 0, come riportato nella figura 4.1. Input bit sequence 0 1 2 3 7 6 5 4 Byte number Bit numbers in byte 4 5 6 7 8 9 10 11 3 2 1 0 7 6 5 4 0 12 13 14 15 16 17 18 19 3 2 1 0 7 6 5 4 1 20 21 22 23 … 3 2 1 0 … 2 … Figura 4.1. Indicizzazione dei byte all’interno delle sequenze I byte sono riordinati in una struttura rettangolare che viene denominata Stato (o State). Tale matrice bidimensionale è composta da quattro righe e quattro colonne di byte, quest’ultime indicate con Nb , generalizzazione che ci consenterà l’estensione a blocchi dati di dimensione superiore. Per questo motivo, ogni un elemento dell Stato, che individua un byte, è etichettato con due indici r e c indicanti le coordinate riga e colonna, ovvero s[r,c] con 0 ≤ r < 4 e 0 ≤ c < Nb , o anche 0 ≤ c < 4, in quanto per l’AES Nb = 4. Le operazioni di cifratura e decifratura avvengono sfruttando lo Stato che è anche l’elemento di appoggio delle trasformazioni intermedie insite in questi processi. La prima operazione compiuta dall’algoritmo sia in fase di cifratura sia in fase di decifratura consiste nell’opportuna associazione dei byte d’ingresso alla matrice di Stato. Analogamente l’ultima operazione consiste nel ricostruire da questa matrice, e con legge congruente, la sequenza d’uscita. Se si indicano con in0 , in1 , in2 , . . . , in15 i byte d’ingresso ordinati per colonne e con out0 , out1 , out2 , . . . , out15 quelli d’uscita, le due associazioni sono cosı̀ rappresentabili: s[r,c] = [r + 4c] per 0 ≤ r < 4 e 0 ≤ c < Nb out[r + 4c] = s[r,c] per 0 ≤ r < 4 e 0 ≤ c < Nb (4.3) Se i byte di ogni colonna si reinterpretano come parole di 4 byte (o 32 bit), lo Stato del sistema è associabile ad un vettore monodimensionale i cui elementi sono: 18 4.2 – Descrizione dell’algoritmo AES input bytes in0 in4 in8 in12 in1 in5 in9 in13 in2 in6 in10 in14 in3 in7 in11 in15 à State array output bytes s0,0 s0,1 s0,2 s0,3 out0 out4 out8 out12 s1,0 s1,1 s1,2 s1,3 s2,0 s2,1 s2,2 s2,3 à s3,0 s3,1 s3,2 s3,3 out1 out5 out9 out13 out2 out6 out10 out14 out3 out7 out11 out15 Figure 3. State array input and output. Figura 4.2. Rappresentazione della matrici di Stato e associazione con gli ingressi e le uscite c0 c1 c2 c3 = = = = (s0,0 , (s0,1 , (s0,2 , (s0,3 , s1,0 , s1,1 , s1,2 , s1,3 , s2,0 , s2,1 , s2,2 , s2,3 , s3,0 ) s3,1 ) s3,2 ) s3,3 ) (4.4) La chiave ha una rappresentazione rettangolare simile allo stato. Le sue colonne, denotate con Nk , sono pari alla lunghezza della chiave diviso 32 (ovvero diviso i 4 byte che formano ciascuna colonna). Se si indica con Nr il numero delle iterazioni che effettua l’algoritmo, le mutue relazioni Nk , Nb e Nr sono desumibili dalla tabella 4.1. Nk Nb Nr AES-128 4 4 10 AES-192 6 4 12 AES-256 8 4 14 Tabella 4.1. Relazione tra il numero di colonne Nk della matrice della chiave, il numero di colonne Nb della matrice di Stato e il numero Nr di iterazioni. Al fine di applicare in ogni iterazione una diversa composizione della chiave, questa viene inizialmente espansa in una struttura rettangolare avente quattro righe di byte e un numero di colonne pari al prodotto del numero di iterazioni previste più una, il tutto moltiplicato per il numero di colonne dello Stato, che nell’AES è pari a quattro. In altre parole il numero di sottochiavi, o Roundkey, è pari al numero di iterazioni più una, ciascuna sottochiave sarà di Nb colonne, ovvero 128 bit, e il numero di bit totali coinvolti nel processo di espansione di espansione della chiave è pari alla lunghezza del blocco dati moltiplicato il numero di iterazioni più uno (per il blocco di 128 bit e una chiave di medesima dimensione, sono stabilite 10 iterazioni e quindi occorrono 4 · (10 + 1) = 44 colonne, o parole, e di conseguenza 44 · 32 = 1408 bit). 19 4 – AES - Advanced Encryption Standard In termini formali le parole a 4 byte componenti il vettore monodimensionale risultante saranno Nb · (Nr + 1) e verranno indicate con: w[i] con 0 ≤ i < Nb · (Nr + 1) (4.5) Le operazioni di cifratura iniziano con la creazione delle matrici di Stato e con l’espansione della chiave nell’opportuno numero di sottochiavi. Quindi viene eseguita un’addizione modulo 2 (mediante XOR bit a bit) tra gli elementi dello Stato e quelli della prima sottochiave che, a loro volta, coincidono con le prime quattro colonne della matrice rappresentativa della chiave. A questo punto viene applicata allo Stato la funzione cifrante per un certo numero di iterazioni, ad eccezione dell’ultima, dove si utilizza una funzione cifrante modificata. In ultima istanza prende forma l’uscita a partire dallo Stato. La funzione cifrante, parametrizzata dalla sottochiave, è composta da quattro differenti trasformazioni operanti sui singoli byte dello Stato. Tali trasformazioni, individualmente invertibili, sono: una sostituzione non-lineare di byte mediante S-box, o substitution table (SubBytes); uno shift circolare di alcune righe della matrice di Stato con differenti offset (ShiftRows); un’operazione di miscelazione dei dati all’interno delle colonne di Stato (MixColumns); un’aggiunta della sottochiave d’iterazione (AddRoundKey). Nell’ultima, dove si utilizza tale funzione cifrante modificata, dalle quattro trasformazioni ne viene esclusa una, che è quella responsabile della miscelazione delle colonne. Utilizzando una notazione che fa uso di uno pseudocodice è possibile indicare le operazioni di cifratura nel seguente modo: Cipher(byte in[4*Nb], byte out[4*Nb], word w[Nb*(Nr+1)]) begin byte state[4,Nb] state = in AddRoundKey(state, w[0, Nb-1]) for round = 1 step 1 to Nr{1 SubBytes(state) ShiftRows(state) MixColumns(state) AddRoundKey(state, w[round*Nb, (round+1)*Nb-1]) end for SubBytes(state) ShiftRows(state) 20 4.2 – Descrizione dell’algoritmo AES AddRoundKey(state, w[Nr*Nb, (Nr+1)*Nb-1]) out = state end Nell’ultima iterazione MixColumns non viene utilizzata. Questo non pregiudica la sicurezza del codice ma consente di realizzare una struttura cifrante inversa più simile a quella diretta. Tale tecnica è paragonabile alla rimozione dello swap nell’ultima iterazione del DES. Nell’operazione di decifratura, indicata anche come cifratura inversa, si utilizzano le inverse delle quattro trasformazioni che compongono la funzione cifrante, se ne inverte l’ordine di esecuzione all’interno della funzione e si esegue prima l’iterazione finale, quindi le altre ed infine l’addizione con la prima sottochiave. Anche in questo caso è utile una descrizione mediante pseudocodice: InvCipher(byte in[4*Nb], byte out[4*Nb], word w[Nb*(Nr+1)]) begin byte state[4,Nb] state = in AddRoundKey(state, w[Nr*Nb, (Nr+1)*Nb-1]) for round = Nr-1 step -1 downto 1 InvShiftRows(state) InvSubBytes(state) AddRoundKey(state, w[round*Nb, (round+1)*Nb-1]) InvMixColumns(state) end for InvShiftRows(state) InvSubBytes(state) AddRoundKey(state, w[0, Nb-1]) out = state end Si noti che la sequenza delle trasformazioni inverse differisce da quelle che caratterizza la cifratura ma sostanzialmente il contenuto delle sottochiavi resta invariato (non l’ordine). Allo scopo di pervenire ad una semplificazione realizzativa è possibile dimostrare che, sfruttando le proprietà delle singole trasformazioni, l’inversa della 21 4 – AES - Advanced Encryption Standard cifratura può essere realizzata con la stessa sequenza delle trasformazioni presenti nella cifratura, pur se ricorrendo alle rispettive inverse e ad un diverso contenuto delle sottochiavi. In questo caso si parla di cifratura inversa equivalente. Nella progettazione dell’algoritmo la scelta delle trasformazioni, e la conseguente ottimizzazione delle relative prestazioni, è stata principalmente focalizzata sull’aspetto cifrante. Ne consegue che le due funzioni MixColumns e InvMixColumns non esibiscono la stessa complessità computazionale. La prima viene realizzata in maniera più agevole dell’inversa. Questa asimmetria di comportamento è dovuta al fatto che le prestazioni di cifratura inversa sono ritenute meno importanti di quelle di cifratura diretta. Secondo i progettisti di Rijndael le più comuni applicazioni della cifratura a blocchi si hanno in modalità CFB e OFB o nel calcolo del checksum crittografico (MAC). Questi modi di funzionamento non fanno affatto uso della cifratura inversa ma sfruttano la modalità di esecuzione cifrante anche per la decifratura. 4.3 Analisi dettagliata dell’algoritmo Rijndael Nell’AES la lunghezza del blocco dati d’ingresso, dello Stato e del blocco dati d’uscita, misurata in multipli di 32 bit, è 4. L’algoritmo Rijndael consente maggiori flessibilità. Possibili valori sono 4, 6 e 8 e opzionalmente 5 e 7. La relazione generale tra il numero delle iterazioni (Nr ), lunghezza delle chiavi (Nk ) e la lunghezza dei blocchi dati (Nb ), è raffigurata nella tabella 4.2, dove chiavi e dati sono espressi in multipli di 32 bit. Le operazioni che avvengono all’interno delle trasformazioni agiscono utilizzando il byte come unità elementare. Riconsiderando la definizione di Stato, le relative colonne, formate da quattro byte, sono esprimibili mediante la seguente rappresentazione polinomiale: Nr = max(Nk ,Nb ) + 6 Nk = 4 Nk = 6 Nk = 8 Nb = 4 10 12 14 Nb = 6 12 12 14 Nb = 8 14 14 14 Tabella 4.2. Numero di iterazioni Nr dell’algoritmo Rijndael in funzione di Nb e Nk . c0 (x) c1 (x) c2 (x) c3 (x) = = = = s0,0 s0,1 s0,2 s0,3 x3 + s1,0 x3 + s1,1 x3 + s1,2 x3 + s1,3 22 x2 + s2,0 x2 + s2,1 x2 + s2,2 x2 + s2,3 x + s3,0 x + s3,1 x + s3,2 x + s3,3 (4.6) 4.3 – Analisi dettagliata dell’algoritmo Rijndael Le operazioni su questi polinomi possono essere di svariato tipo. La moltiplicazione tra due polinomi, ad esempio, restituisce un polinomio di grado 6. Al fine di ottenere una ridotta complessità implementativa è opportuno considerare i coefficienti dei polinomi come appartenenti ad un campo finito. In virtù di tale requisito si ricorre alla teoria dei campi finiti di Galois e si ipotizza che i coefficienti polinomiali appartengono al campo finito GF(28 ). 4.3.1 Il campo GF(28 ) In un campo finito GF(28 ) i suoi elementi, i byte, possono essere sommati o moltiplicati, ma queste operazioni sono differenti da quelle definite nel tradizionale campo numerico. Un byte, composto da una generica sequenza di 8 bit (b7 , b6 , b5 , b4 , b3 , b2 , b1 , b0 ), può essere considerato come un polinomio di grado 7 (polinomio binario) i cui coefficienti, definiti nell’insieme dei valori {0, 1}, sono proprio i valori dei bit: b(x) = b7 x7 + b6 x6 + b5 x5 + b4 x4 + b3 x3 + b2 x2 + b1 x + b0 (4.7) Nel campo GF(28 ) tra due polinomi è definibile l’operazione di somma, indicata con “⊕” e pari all’operazione di XOR tra i coefficienti di medesimo grado. La definizione dell’operazione di moltiplicazione fa uso del polinomio irriducibile m(x) = x8 + x4 + x3 + x + 1 che, in esadecimale, vale {01}{1b} (un polinomio si dice irriducibile se, oltre a se stesso ed all’unità, non ha divisori). Tale operazione, indicata con “·”, avviene come moltiplicazione polinomiale e successiva riduzione in modulo per m(x). In pratica si calcola il prodotto di due polinomi del tipo b(x), se ne effettua la divisione per il polinomio irriducibile, e se considera il resto come risultato. Lo scopo di tale operazione è quello di ottenere risultati ancora esprimibili con la rappresentazione che fa uso di un solo byte, ovvero con polinomi di grado inferiore a 8. Questa moltiplicazione è associativa ed ha come elemento neutro il byte {01}. Per ogni polinomio b(x) è possibile determinare l’inverso. A tale scopo si utilizza l’algoritmo esteso di Euclide. Tale algoritmo consente di trovare il massimo comun divisore tra due polinomi attraverso la tecnica delle divisioni successive. Per ogni polinomio binario b(x) di grado minore di 8, l’algoritmo di Euclide può essere utilizzato per calcolare i polinomi a(x) e c(x) tali che: b(x)a(x) + m(x)c(x) = 1 (4.8) Applicando quest’algoritmo ai polinomi m(x) e b(x) si ottiene: a(x) · b(x) mod m(x) = 1 e quindi: 23 (4.9) 4 – AES - Advanced Encryption Standard b−1 (x) = a(x) mod m(x) (4.10) In conclusione il campo finito GF(28 ) è definito dall’insieme dei 256 possibili valori che possono assumere i coefficienti polinomiali binari considerati complessivamente come un byte (tutte le combinazioni ottenibili da un byte) e su cui sono definite le due operazioni di addizione (⊕) e di moltiplicazione (·). 4.3.2 Moltiplicazione per x nel campo GF(28 ) Riprendendo in considerazione il polinomio b(x), il risultato della moltiplicazione per la variabile x fornisce un polinomio di grado superiore: b(x) · x = b7 x8 + b6 x7 + b5 x6 + b4 x5 + b3 x4 + b2 x3 + b1 x3 + b0 x (4.11) La moltiplicazione b(x) · x si completa riducendo in modulo m(x) il polinomio risultante dalla tradizionale moltiplicazione polinomiale. Se b7 = 0 il risultato è già in forma ridotta. Se b7 = 1 la riduzione è compiuta sottraendo il risultato al polinomio m(x) (in virtù della definizione di XOR, la somma di polinomi in GF(28 ) è identica alla sottrazione e quindi basta eseguire l’XOR bit a bit). Per cui nel campo GF(28 ) la moltiplicazione di un byte per x (che in notazione esadecimale è rappresentato con il valore {02}) si ottiene con uno shift a sinistra dei bit del byte e conseguente XOR bit a bit con la costante {1b}. La ripetuta applicazione di questa tecnica consente di realizzare con semplicità moltiplicazioni per potenze di x di grado superiore. 4.3.3 Polinomi con coefficienti nel campo GF(28 ) È possibile definire dei polinomi che hanno ciascun coefficiente appartenente al campo finito GF(28 ). I byte delle colonne della matrice di Stato possono essere interpretati come coefficienti di polinomi di quattro termini quindi di terzo grado. Dati due polinomi di questo tipo, ad esempio a(x) = a3 x3 +b2 x2 +b1 x+b0 , dove in questo caso i coefficienti a3 , a2 , a1 , a0 e b3 , b2 , b1 , b0 , sono dei byte, l’operazione di somma polinomiale si effettua sommando i corrispondenti coefficienti (con un XOR bit a bit). Se tra i polinomi a(x) e b(x) si effettuasse la classica moltiplicazione polinomiale si otterrebbe un polinomio di grado 6, non più rappresentabile come vettore di quattro byte. Per cui si definisce una nuova operazione, denominata prodotto modulare ed indicata con “⊗”, in cui il risultato del prodotto polinomiale viene ridotto ad un polinomio di grado inferiore a 4, mediante divisione con il polinomio irriducibile x4 + 1. 24 4.3 – Analisi dettagliata dell’algoritmo Rijndael Il risultato del prodotto modulare tra a(x) e b(x) ed indicato con il polinomio: d(x) = a(x) ⊗ b(x) = d3 x3 + d2 x2 + d1 x + d0 (4.12) è pari a: d0 d1 d2 d3 = = = = a0 · b0 + a3 · b1 + a2 · b2 + a1 · b3 a1 · b0 + a0 · b1 + a3 · b2 + a2 · b3 a2 · b0 + a1 · b1 + a0 · b2 + a3 · b3 a3 · b0 + a2 · b1 + a1 · b2 + a0 · b3 (4.13) Quando uno dei due, ad esempio a(x), è un polinomio fisso, la moltiplicazione modulare può essere espressa nella seguente forma matriciale: d0 d1 d2 d3 = a0 a1 a2 a3 a3 a0 a1 a2 a2 a3 a0 a1 a1 a2 a3 a0 b0 b1 b2 b3 (4.14) In virtù del fatto che x4 + 1 è un polinomio irriducibile in GF(28 ), la moltiplicazione per un polinomio fisso non è sempre invertibile. Lo diviene se si utilizzano particolari polinomi. Uno di questi è il seguente: a(x) = {03}x3 + {01}x2 + {01}x + {02} (4.15) dotato dell’inverso: a−1 (x) = {0b}x3 + {0d}x2 + {09}x + {0e} (4.16) L’uso delle parentesi per i coefficienti individua una notazione esadecimale. Il prodotto modulare x ⊗ b(x) è equivalente al prodotto del vettore b(x) con la precedente matrice che ha negli elementi individuati da a1 il valore {01} ed in tutti gli altri il valore {00}. Tale operazione equivale ad una permutazione ciclica dei byte all’interno del vettore passando da [b0 , b1 , b2 , b3 ] a [b3 , b0 , b1 , b2 ] o, in notazione polinomiale b2 x3 + b1 x2 + b0 x + b3 . 4.3.4 La funzione cifrante La funzione cifrante coinvolta nel processo iterativo agisce ripetutamente sulla matrice di Stato e si compone delle seguenti quattro trasformazioni: SubBytes, ShiftRows, MixColumns, AddRoundKey. Tra queste, MixColumns non viene utilizzata nell’ultima iterazione. La trasformazione SubBytes è una sostituzione non lineare operata a livello dei singoli byte dello Stato che fa uso della tabella di sostituzione o S-box di figura 4.3. 25 4 – AES - Advanced Encryption Standard Ciascun byte dello stato viene utilizzato come indirizzo della tabella. Da questa, e per ciascun byte dello Stato, si ottengono i valori di sostituzione che prenderanno il posto dei byte che hanno operato all’indirizzamento. Ad esempio se un byte di Stato vale in esadecimale {3e}, il nibble rappresentativo dei primi 4 bit (oppure la prima cifra esadecimale), fornisce l’indirizzo di riga all’interno dell’S-box, il secondo quello di colonna. Per cui il valore della singola trasformazione è individuato dalla quarta riga, o riga di indice ‘3’, e quindicesima colonna, o colonna di indice ‘e’, e vale {b2}. a value of {ed}. y 0 1 2 3 4 5 6 7 x 8 9 a b c d e f 0 63 ca b7 04 09 53 d0 51 cd 60 e0 e7 ba 70 e1 8c 1 7c 82 fd c7 83 d1 ef a3 0c 81 32 c8 78 3e f8 a1 2 77 c9 93 23 2c 00 aa 40 13 4f 3a 37 25 b5 98 89 3 7b 7d 26 c3 1a ed fb 8f ec dc 0a 6d 2e 66 11 0d 4 f2 fa 36 18 1b 20 43 92 5f 22 49 8d 1c 48 69 bf 5 6b 59 3f 96 6e fc 4d 9d 97 2a 06 d5 a6 03 d9 e6 6 6f 47 f7 05 5a b1 33 38 44 90 24 4e b4 f6 8e 42 7 c5 f0 cc 9a a0 5b 85 f5 17 88 5c a9 c6 0e 94 68 8 30 ad 34 07 52 6a 45 bc c4 46 c2 6c e8 61 9b 41 9 01 d4 a5 12 3b cb f9 b6 a7 ee d3 56 dd 35 1e 99 a 67 a2 e5 80 d6 be 02 da 7e b8 ac f4 74 57 87 2d b 2b af f1 e2 b3 39 7f 21 3d 14 62 ea 1f b9 e9 0f c fe 9c 71 eb 29 4a 50 10 64 de 91 65 4b 86 ce b0 d d7 a4 d8 27 e3 4c 3c ff 5d 5e 95 7a bd c1 55 54 e ab 72 31 b2 2f 58 9f f3 19 0b e4 ae 8b 1d 28 bb f 76 c0 15 75 84 cf a8 d2 73 db 79 08 8a 9e df 16 Figure 7. S-box: substitution values for the byte xy (in hexadecimal format). Figura 4.3. Tabella di sostituzione (S-box) in formato esadecimale Nella rappresentazione grafica (figura 4.4) si utilizza la convenzione di indicare con un apice gli elementi dello Stato che sono stati elaborati dalla trasformazione: sr,c → s0r,c . SubBytes() s0,0 s0,1 s0, 2 s0,3 S-Box s0' , 0 s0' ,1 s0' , 2 s0' ,3 s1' ,1' s1' , 2 s1' ,3 s1, 0 s1,1 s1, 2 s1,3 s1' ,0 s2, 0 s2,1 s2, 2 s2,3 s2' , 0 s2' ,1 s2' , 2 s2' ,3 s3, 0 s3,1 s3, 2 s3,3 s3' ,0 s3' ,1 s3' , 2 s3' ,3 sr ,c sr ,c SubBytes() Figura 4.4. Trasformazione SubBytes per Nb = 4. La successiva trasformazione è la ShiftRows che, a differenza delle altre trasformazioni, è l’unica a dipendere dalla lunghezza del blocco. Essa esegue uno shift 26 4.3 – Analisi dettagliata dell’algoritmo Rijndael circolare verso sinistra degli elementi della seconda, terza e quarta riga di opportune quantità, mentre la prima riga resta inalterata. L’ammontare dello shift per la seconda riga è di un byte, per la terza è di due (per blocchi di 256 bit è di 3 byte), per l’ultima è di 3 byte (4 per Nb = 7 e Nb = 8). ShiftRows() sr' , 0 sr' ,1 sr' , 2 sr' ,3 sr , 0 sr ,1 sr , 2 sr ,3 S S’ s0,0 s0,1 s0, 2 s0,3 s0,0 s0,1 s0, 2 s0,3 s1, 0 s1,1 s1, 2 s1,3 s1,1 s2, 0 s2,1 s2, 2 s2 ,3 s2, 2 s2,3 s2, 0 s2,1 s3, 0 s3,1 s3, 2 s3,3 s3,3 s3, 0 s3,1 s3, 2 s1, 2 s1,3 s1, 0 Figure 8. ShiftRows() cyclically shifts the last three rows in the State. Figura 4.5. Trasformazione ShiftRows per Nb = 4. La trasformazione MixColumns opera sulla matrice di Stato, colonna per colonna, considerandole ciascuna come polinomio di quattro termini definito nel campo finito GF(28 ). Ciascuno di tali polinomi viene moltiplicato per un polinomio fisso c(x) = {03}x3 +{01}x2 +{01}x+{02} e ridotto in modulo mediante il polinomio irriducibile x4 + 1. Tali moltiplicazioni modulari originano la nuova matrice di Stato indicata con: s0 (x) = c(x) ⊗ s(x) (4.17) e meglio rappresentata con la seguente notazione matriciale: s00,c s01,c s02,c s03,c = 02 01 01 03 03 02 01 01 01 03 02 01 01 01 03 02 s0,c s1,c s2,c s3,c per 0 ≤ c < Nb (4.18) In definitiva, ciascuno dei quattro byte di ogni colonna è sostituito dal risultato delle seguenti operazioni: s00,c s01,c s02,c s03,c = = = = ({02} · s0,c ) ⊕ ({03} · s1,c ) ⊕ s2,c ⊕ s3,c s0,c ⊕ ({02} · s1,c ) ⊕ ({03} · s2,c ) ⊕ s3,c s0,c ⊕ s1,c ⊕ ({02} · s2,c ) ⊕ ({03} · s3,c ) ({03} · s0,c ) ⊕ s1,c ⊕ s2,c ⊕ ({02} · s3,c ) 27 (4.19) 4 – AES - Advanced Encryption Standard MixColumns() MixColumns() s' s s0,0 s00,,1c s0, 2 s0,3 s0' , 0 s0' 0,1,c s0' , 2 s0' ,3 s s' s1, 0 s11,,1c s1, 2 s1,3 s1' ,0 s1'1,1,c s1' , 2 s1' ,3 s2, 0 ss22,,1c s2, 2 s2,3 s2' , 0 ss2'2,1,c s2' , 2 s2' ,3 s3, 0 ss33,,1c s3, 2 s3,3 s3' ,0 ss3'3,1,c s3' , 2 s3' ,3 ' ' Figure 9. MixColumns() operates on the State column-by-column. Figura 4.6. Trasformazione MixColumns per Nb = 4. L’ultima trasformazione della funzione cifrante è la AddRoundKey in cui avviene la somma tra lo stato e la sottochiave di iterazione. Tale operazione e una XOR bit a bit dei byte rappresentativi dello Stato con i byte di una parte della chiave espansa. Il numero di vettori colonna coinvolti sarà Nb . In virtù della notazione precedentemente illustrata in cui le colonne della sottochiave sono indicate con w[i] è possibile scrivere: [s00,c s01,c s02,c s03,c ] = [s0,c s1,c s2,c s3,c ] ⊕ w[round · Nb + c] per 0 ≤ c < Nb (4.20) in cui round è un valore compreso nell’intervallo 0 ≤ round < Nr . Viene utilizzato round = 0 nella prima applicazione di questa trasformazione che avviene prima di iniziare le iterazioni della funzione cifrante. l = round * Nb s0' ,c s 0 ,c s0,0 s0,1 s0, 2 s0,3 s1,c s1, 0 s1,1 s1, 2 s1,3 s2, 0 s2s,12,c s2, 2 s2 ,3 ⊕ wl+c wl wl +1 wl + 2 wl + 3 ' 0, 0 s s0' ,1' s0' , 2 s0' ,3 s1,c s1' ,0 s1' ,1 s1' , 2 s1' ,3 ' s2' , 0 ss2' ,12,c s2' , 2 s2' ,3 ' s3' ,0 s3s' ,13,c s3' , 2 s3' ,3 s3, 0 s3s,1 s3, 2 s3,3 3,c Figura 4.7. Trasformazione AddRoundKey per Nb = 4. 4.3.5 Schedulazione della chiave Le sottochiavi d’iterazione sono derivate dalla chiave di ingresso mediante la procedura di schedulazione della chiave che si compone di un processo di espansione 28 4.3 – Analisi dettagliata dell’algoritmo Rijndael della chiave e di una conseguente selezione secondo la quale iterazione per iterazione, vengono fornite alla funzione cifrante, e nell’ordine opportuno, le sottochiavi. L’espansione della chiave genera, a partire dalla chiave di cifratura (denotata con Key), un totale di Nb (Nr + 1) parole a 32 bit che vengono indicate come un unico vettore monodimensionale denotato con w[i] con indice definito nel campo di valori 0 ≤ i < Nb (Nr + 1), oppure in maniera più intuitiva con una serie di Nr + 1 matrici 4 × Nb indicate convenzionalmente RoundKey(r) per 0 ≤ r < Nr . Inizialmente il vettore w[i] è riempito nelle sue prime Nk posizioni dalla chiave di cifratura. Ogni successiva parola del vettore, e per tutto il restante campo di valori, è ottenuta come XOR tra la precedente parola, w[i − 1], e la parola di Nk posizioni prima, w[i − Nk ]. Tuttavia, sulle parole che sono in posizione multipla rispetto al numero indicante la dimensione Nk e prima dell’XOR, viene applicata una trasformazione. Tale trasformazione si differenzia se la chiave di ingresso è minore di 224 bit o maggiore (Nb ≤ 6 oppure Nb > 6). Utilizzando una notazione che fa uso di uno pseudocodice è possibile indicare le operazioni di espansione della chiave nel seguente modo: KeyExpansion(byte key[4*Nk], word w[Nb*(Nr+1)], Nk) begin word temp i = 0 while (i < Nk) w[i] = word(key[4*i], key[4*i+1], key[4*i+2], key[4*i+3]) i = i+1 end while i = Nk while (i < Nb * (Nr+1)] temp = w[i-1] if (i mod Nk = 0) temp = SubWord(RotWord(temp)) xor Rcon[i/Nk] else if (Nk > 6 and i mod Nk = 4) temp = SubWord(temp) end if w[i] = w[i-Nk] xor temp i = i + 1 end while end Nel primo caso si applica ai byte che compongono la parola corrente w[i] una 29 4 – AES - Advanced Encryption Standard permutazione ciclica, definita RotWord (se la parola in ingresso è [a0 a1 a2 a3 ] l’uscita diventa [a1 a2 a3 a0 ]). Tale trasformazione coincide con il prodotto modulare per x definito in precedenza. Quindi a ciascun byte del vettore viene applicata una sostituzione che fa uso della stessa tabella della trasformazione SubBytes. Infine, il risultato di queste due operazioni è posto in XOR con un vettore costante, indicato con Rcoin[i] e i cui valori, espressi in notazione esadecimale, sono rappresentati dal vettore [RC[i] {00} {00} {00}]. Le componenti di tale vettore sono indipendenti da Nk e sono definite come elementi nel campo GF(28 ) con un valore xi−1 , con i 6= 0. Si noti che RC[1] = x0 = 1, RC[2] = x1 = {02} e che in generale è possibile scrivere RC[i] = xi−1 = x · RC[i − 1]. Nel secondo caso (Nb > 6) alla parola corrente di w[i], il cui indice modulo Nk ha come resto della divisione 4 (in altri termini quando i − 4 è un multiplo di Nk ), e prima dell’XOR con la costante Rcoin[i], si applica solo la trasformazione SubWord escludendo la RotWord. 4.3.6 La funzione cifrante inversa La funzione cifrante può essere invertita utilizzando le inverse delle trasformazioni componenti: InvSubBytes, InvShiftRows e InvMixColumns. AddRoundKey resta la stessa in virtù dell’operazione XOR. InvShiftRows è l’inversa della trasformazione ShiftRows. La prima riga non è shiftata. I byte delle ultime tre righe sono shiftati ciclicamente, ciascuna riga del medesimo numero di byte usato in cifratura ma nella direzione contraria. InvShiftRows() sr' , 0 sr' ,1 sr' , 2 sr' ,3 sr , 0 sr ,1 sr , 2 sr ,3 S S’ s0,0 s0,1 s0, 2 s0,3 s0,0 s0,1 s0, 2 s0,3 s1, 0 s1,1 s1, 2 s1,3 s1,3 s2, 0 s2,1 s2, 2 s2 ,3 s2, 2 s2 ,3 s2, 0 s2,1 s3, 0 s3,1 s3, 2 s3,3 s3,1 s3, 2 s3,3 s3, 0 s1, 0 s1,1 s1, 2 Figure 13. InvShiftRows()cyclically shifts the last three rows in the State. Figura 4.8. Trasformazione InvShiftRows per Nb = 4. InvSubBytes è l’inversa della trasformazione SubBytes. Si esegue utilizzando come nuova tabella di sostituzione l’inversa della S-box definita in fase di cifratura. 30 4.3 – Analisi dettagliata dell’algoritmo Rijndael The inverse S-box used in the InvSubBytes() transformation is presented in Fig. 14: y 0 1 2 3 4 5 6 7 x 8 9 a b c d e f 0 52 7c 54 08 72 6c 90 d0 3a 96 47 fc 1f 60 a0 17 1 09 e3 7b 2e f8 70 d8 2c 91 ac f1 56 dd 51 e0 2b 2 6a 39 94 a1 f6 48 ab 1e 11 74 1a 3e a8 7f 3b 04 3 d5 82 32 66 64 50 00 8f 41 22 71 4b 33 a9 4d 7e 4 30 9b a6 28 86 fd 8c ca 4f e7 1d c6 88 19 ae ba 5 36 2f c2 d9 68 ed bc 3f 67 ad 29 d2 07 b5 2a 77 6 a5 ff 23 24 98 b9 d3 0f dc 35 c5 79 c7 4a f5 d6 7 38 87 3d b2 16 da 0a 02 ea 85 89 20 31 0d b0 26 8 bf 34 ee 76 d4 5e f7 c1 97 e2 6f 9a b1 2d c8 e1 9 40 8e 4c 5b a4 15 e4 af f2 f9 b7 db 12 e5 eb 69 a a3 43 95 a2 5c 46 58 bd cf 37 62 c0 10 7a bb 14 b 9e 44 0b 49 cc 57 05 03 ce e8 0e fe 59 9f 3c 63 c 81 c4 42 6d 5d a7 b8 01 f0 1c aa 78 27 93 83 55 d f3 de fa 8b 65 8d b3 13 b4 75 18 cd 80 c9 53 21 e d7 e9 c3 d1 b6 9d 45 8a e6 df be 5a ec 9c 99 0c f fb cb 4e 25 92 84 06 6b 73 6e 1b f4 5f ef 61 7d Figure 14. Inverse S-box: substitution values for the byte xy (in Figura 4.9. Tabella di sostituzione inversa (S-box) in formato esadecimale InvMixColumns è l’inversa della funzione MixColumn. Opera sulle singole colonne dello Stato considerandole ciascuna come un polinomio di quattro termini definito nel campo GF(28 ). Ciascuno di tali polinomi viene moltiplicato per un polinomio fisso c−1 (x) = {0b}x3 +{0d}x2 +{09}x+{0e}, inverso di quello utilizzato in cifratura c(x), e ridotto in modulo mediante il polinomio irriducibile x4 + 1. Tali moltiplicazioni modulari originano la nuova matrice di Stato indicata con: s0 (x) = c−1 (x) ⊗ s(x) (4.21) e meglio rappresentata con la seguente notazione matriciale: s00,c s01,c s02,c s03,c = 0e 09 0d 0b 0b 0e 09 0d 0d 0b 0e 09 09 0d 0b 0e s0,c s1,c s2,c s3,c per 0 ≤ c < Nb (4.22) In altri termini, ciascuno dei quattro byte di ogni colonna è sostituito dal risultato delle seguenti operazioni: s00,c s01,c s02,c s03,c = = = = ({0e} · s0,c ) ⊕ ({0b} · s1,c ) ⊕ ({0d} · s2,c ) ⊕ ({09} · s3,c ) ({09} · s0,c ) ⊕ ({0e} · s1,c ) ⊕ ({0b} · s2,c ) ⊕ ({0d} · s3,c ) ({0d} · s0,c ) ⊕ ({09} · s1,c ) ⊕ ({0e} · s2,c ) ⊕ ({0b} · s3,c ) ({0b} · s0,c ) ⊕ ({0d} · s1,c ) ⊕ ({09} · s2,c ) ⊕ ({0e} · s3,c ) 31 (4.23) 4 – AES - Advanced Encryption Standard 4.3.7 La cifratura inversa equivalente Nella cifratura inversa, analizzata in precedenza, la sequenza delle trasformazioni differisce da quella cifratura, mentre la schedulazione della chiave rimane invariata anche se l’ordine di utilizzo viene invertito. Sfruttando alcune proprietà algebriche delle trasformazioni e delle rispettive inverse è possibile creare una struttura cifrante inversa uguale a quella cifrante, con le singole trasformazioni sostituite dalla inverse e con un cambio della procedura di schedulazione della chiave. Le trasformazioni SubBytes e ShiftRows sono commutative, nel senso che l’ordine di esecuzione è ininfluente. Una cosa analoga avviene per le inverse. Essendo InvMixColumns una trasformazione lineare (una trasformazione lineare f gode della proprietà f (x + y) = f (x) + f (y)) questo implica che: InvMixColumns(State XOR RoundKey) = InvMixColumns(State) XOR InvMixColumns(RoundKey) (4.24) Pertanto può essere scambiato l’ordine di esecuzione di AddRoundKey e InvMixColumns. Tuttavia occorre modificare la schedulazione della chiave prevedendo l’inclusione della funzione InvMixColumns,in una funzione che viene indicata con InvRoundKey, per le iterazioni che vanno da 1 a Nr − 1, senza modificare le prima e l’ultima. Anche in questo caso è utile una descrizione mediante pseudocodice: EqInvCipher(byte in[4*Nb], byte out[4*Nb], word dw[Nb*(Nr+1)]) begin byte state[4,Nb] state = in AddRoundKey(state, dw[Nr*Nb, (Nr+1)*Nb-1]) for round = Nr-1 step -1 downto 1 InvSubBytes(state) InvShiftRows(state) InvMixColumns(state) AddRoundKey(state, dw[round*Nb, (round+1)*Nb-1]) end for InvSubBytes(state) InvShiftRows(state) AddRoundKey(state, dw[0, Nb-1]) out = state 32 4.3 – Analisi dettagliata dell’algoritmo Rijndael end /* For the Equivalent Inverse Cipher, the following pseudo code is added at the end of the Key Expansion routine. */ for i = 0 step 1 to (Nr+1)*Nb-1 dw[i] = w[i] end for for round = 1 step 1 to Nr-1 InvMixColumns(dw[round*Nb, (round+1)*Nb-1]) // note change of type end for /* Note that, since InvMixColumns operates on a two-dimensional array of bytes while the Round Keys are held in an array of words, the call to InvMixColumns in this code sequence involves a change of type (i.e. the input to InvMixColumns() is normally the State array, which is considered to be a two-dimensional array of bytes, whereas the input here is a Round Key computed as a one-dimensional array of words). */ 4.3.8 Criteri di progetto I criteri di progetto che sono stati presi in considerazione nella creazione dell’algoritmo Rijndael sono essenzialmente tre: modularità, velocità e compattezza del codice per un ampio spettro di piattaforme di calcolo, resistenza contro tutti i tipi di attacchi noti. In Rijndael l’elaborazione dei byte dello Stato è di tipo uniforme, ovvero ciascun elemento della matrice è trattato in maniera simile. La struttura dell’algoritmo non è quindi di tipo Feistel, in cui parte dei bit all’interno di un’iterazione sono trasposti senza essere elaborati mentre altri sono sottoposti all’azione della funzione cifrante. La funzione cifrante da iterare viene identificata da tre distinte trasformazioni invertibili e uniformi chiamate layer. La scelta di differenti layer discende dall’applicazione di un metodo, utilizzato per resistere alla crittoanalisi lineare e differenziale, denominato “Wide Trail Strategy”. In questo metodo ogni layer ha una propria funzione. Il primo layer, denominato layer non-lineare e associabile alla funzione SubBytes, consente di ottenere caratteristiche di non linearità e quindi di confusione, il secondo layer, denominato layer di miscelazione lineare e associabile alle trasformazioni ShiftRows e MixColumns, garantisce alta diffusione se applicato su più iterazioni, il terzo layer, denominato layer di somma della chiave e associabile alla trasformazione AddRoundKey, consente di parametrizzare il testo cifrato con la 33 4 – AES - Advanced Encryption Standard chiave. Tale layer è utilizzato anche al di fuori della funzione cifrante. Infatti prima di iniziare le iterazioni viene compiuta un’addizione con la prima sottochiave. L’aggiunta di tale addizione impedisce la rimozione in sede di crittoanalisi degli altri layer che non dipendono dalla chiave e che risulterebbero quindi ininfluenti ai fini della sicurezza complessiva (si noti come nel DES le permutazioni iniziali e finali non hanno valore crittografico). La trasformazione SubBytes, che interpreta il layer non lineare, è realizzata mediante una tabella di sostituzione, o S-box, che è invertibile e costruita componendo due trasformazioni. Nella prima di queste si genera l’inverso moltiplicativo nel campo GF(28 ) di ciascun byte d’ingresso (come caso particolare {00} è mappato in se stesso). La successiva trasformazione applicata è una trasformazione affine sul campo GF(2)1 . Il campo GF(2) è un campo finito applicato su elementi di entità pari a bit. La trasformazione utilizzata assume la seguente espressione: b0i = bi ⊕ b(i+4)mod8 ⊕ b(i+5)mod8 ⊕ b(i+6)mod8 ⊕ b(i+7)mod8 ⊕ ci per 0 ≤ i < 8 (4.25) dove b0i è i-esimo bit del byte sottoposto alla trasformazione e ci è iesimo bit di un byte che ha valore costante e pari a {63} in dotazione esadecimale. La trasformazione affine utilizzata può alternativamente essere rappresentata nella seguente forma matriciale: 0 b0 0 b1 0 b 2 b0 3 0 b4 b0 5 0 b6 b07 = 1 1 1 1 1 0 0 0 0 1 1 1 1 1 0 0 0 0 1 1 1 1 1 0 0 0 0 1 1 1 1 1 1 0 0 0 1 1 1 1 1 1 0 0 0 1 1 1 1 1 1 0 0 0 1 1 1 1 1 1 0 0 0 1 b0 b1 b2 b3 b4 b5 b6 b7 + 1 1 0 0 0 1 1 0 (4.26) Per quanto riguarda l’espansione della chiave, ovvero la creazione delle sottochiavi di iterazione a partire dalla chiave di cifratura, uno dei principali ruoli di quest’operazione è l’eliminazione della simmetria all’intero della funzione cifrante, ottenuta con l’aggiunta di una serie di costanti che variano con l’iterazione. Infine il numero delle iterazioni è stato scelto con criteri conservativi in quanto per blocchi di lunghezza pari a 128 bit si ottiene una completa diffusione in due iterazioni che diventano tre per blocchi di dimensione superiore (nella completa diffusione ogni bit di Stato dipende da tutti i bit dello Stato di due iterazioni precedenti oppure, 1 Una trasformazione affine è una trasformazione che consiste nella moltiplicazione di un vettore ad una matrice seguita da una somma con un’altro vettore. 34 4.4 – Modi di funzionamento in altri termini, il cambio in un bit è probabile che alteri al metà dei bit dello Stato dopo due iterazioni). 4.4 Modi di funzionamento L’AES, cosı̀ come ogni altro algoritmo a blocchi, può essere utilizzato in quattro modi operativi: • Electronic Code Book (ECB) • Cipher Block Chaining (CBC) • Cipher Feedback (CFB) • Output Feedback (OFB) La descrizione di questi modi è presente nella norma “Recommendation for Block Cipher Modes of Operation - Methods and Techniques” NIST SP 800-38A pubblicata nel 2001 [22]. 4.4.1 Electronic Code Book (ECB) E’ il metodo più semplice ma anche il meno affidabile, infatti con esso ogni blocco di testo è cifrato in successione sempre con la stessa chiave e indipendentemente dagli altri blocchi. Il termine code book deriva dal fatto che, per un’assegnata chiave, esiste un’unica sequenza di testo cifrato corrispondente ad un dato testo in chiaro (detto anche plaintext). La debolezza della modalità consiste nel fatto che i blocchi uguali nello stesso messaggio in chiaro danno origine sempre allo stesso blocco cifrato. Un altro limite, ovviabile con operazioni di padding, è rappresentato dal fatto che il messaggio da cifrare deve essere multiplo della dimensione del blocco. Si definisce padding l’aggiunta di bit di riempimento al blocco al fine di portare la dimensione complessiva a quella desiderata, nel caso dell’AES a 128 bit. L’operazione di padding può essere effettuata anche per irrobustire la sicurezza della modalità nel caso in cui si trasmettono blocchi simili. Il padding, in questo caso, viene utilizzato in maniera random. La presenza di uno o più errori in un blocco cifrato si ripercuote solo nel corrispettivo blocco decifrato e non nei blocchi contigui. Questo implica l’assenza del fenomeno di propagazione degli errori tra i blocchi. Da evidenziare che la presenza nel blocco cifrato anche di pochi errori introdotti dal canale di comunicazione origina un blocco decifrato notevolmente diverso da quello trasmesso (è possibile raggiungere anche il 50% di bit errati). 35 4 – AES - Advanced Encryption Standard xj n key E E −1 key n x0j = xj cj (i) encipherment (ii) decipherment Figura 4.10. Modalità di funzionamento ECB Sia X il messaggio da trasmettere e (x1 , x2 , . . . , xj ) la suddivisione in j blocchi. Nell’operazione di cifratura l’i-esimo blocco di testo on chiaro, indicato con xj , si trasforma, in seguita all’applicazione della chiave K all’algoritmo cifrante e al blocco xj , nel blocco cj , ovvero: cj = EK (xj ) (4.27) Nell’operazione di decifratura il blocco cifrato cj restituisce il blocco in chiaro xj , cioè: −1 xj = EK (cj ) 4.4.2 (4.28) Cipher Block Chaining (CBC) É un metodo simile al precedente anche se in questo caso i blocchi di testo cifrato sono concatenati ai propri predecessori nascondendo le parti che si ripetono all’interno del testo semplice e che verrebbero altrimenti ripetute nel testo cifrato. In particolare, viene sottoposto a cifratura il risultato dell’XOR compiuta sul blocco di testo cifrato precedentemente e sul blocco corrente di testo in chiaro. Oltre alla chiave segreta, bisogna introdurre come parametro del modo operativo, un vettore di inizializzazione (anche denominato IV, acronimo di Initial Vector), cioè il blocco che viene posto come cifratura fittizia all’inizio del funzionamento del sistema. La debolezza della modalità è che un eventuale errore nella fase di comunicazione dell’informazione cifrata si propaga per due blocchi successivi del messaggio cifrato. Per la cifratura si può scrivere: cj = EK (xj ⊕ cj−1 ) e come caso particolare: 36 (4.29) 4.4 – Modi di funzionamento c0 = IV cj cj−1 E −1 n xj key key cj−1 E n x0j = xj cj (i) encipherment (ii) decipherment Figura 4.11. Modalità di funzionamento CBC c0 = EK (x0 ⊕ IV) (4.30) c1 = EK (x1 ⊕ c0 ) (4.31) Inversamente per la decifratura si può scrivere: −1 xj = cj−1 ⊕ EK (xj ) (4.32) −1 x0 = IV ⊕ EK (x0 ) (4.33) −1 x1 = c0 ⊕ EK (x1 ) (4.34) e come caso particolare: Per questo metodo è possibile enunciare alcune proprietà: 1. Ad identici blocchi di testo corrispondono medesimi risultati finali se non viene alterato il vettore di inizializzazione. 2. La dipendenza dal blocco precedente è limitata ad un blocco, questo però comporta la necessità di mantenere l’ordine corretto dei blocchi in fase di decifratura. 3. La sincronizzazione è automatica nel caso di blocchi errorati, ovvero se il blocco j-esimo è errorato e quello j + 1 non lo è, il blocco j + 2 sarà decifrato correttamente. 4. Un singolo errore nel blocco cifrato si ripercuote sulla decifratura del blocco (in cui il 50% dei bit sono errati) e del successivo (in cui si verificano gli errori nella posizione in cui sono occorsi nel precedente blocco cifrato). 37 4 – AES - Advanced Encryption Standard 4.4.3 Cipher Feedback (CFB) Come per il CBC i blocchi vengono concatenati fra loro ma questa volta dopo l’operazione di cifratura. Ovvero, si esegue la cifratura del blocco cifrato precedentemente e poi l’XOR con il testo chiaro spezzettato in segmenti più piccoli. Lo scopo è quello di elaborare i dati non appena sono disponibili invece di aspettare che la cifratura di un blocco sia del tutto completata (cifratura real time). Poichè si può operare su un blocco di dimensione arbitraria tra uno e la dimensione del blocco, questa modalità consente di convertire l’AES, o il generico cifratore a blocco in esame, in un cifratore a flussi eliminando la necessità di ricorrere ad operazioni di padding quando il messaggio non è un multiplo della dimensione dei blocchi. Il messaggio in chiaro X può essere suddiviso in blocchi di dimensione pari a r bit (1 ≤ r ≤ n, dove n è la dimensione del blocco). Un registro a scorrimento di n bit viene riempito con un vettore di inizializzazione indicato con IV (inviato all’inizio della comunicazione). Gli r bit meno significativi del risultato di cifratura sul vettore di inizializzazione sono posti in XOR con la prima parte (a r bit) del messaggio da cifrare (gli altri n − r bit sono ignorati). Il risultato è trasmesso come messaggio cifrato. Lo stesso messaggio è memorizzato nelle r posizioni più significative dello shift register, che a sua volta ha preventivamente subito altrettanti spostamenti a sinistra (i bit che superano la dimensione dello shift vengono persi). Nella decifratura di adopera lo stesso schema, ovvero si continua ad usare la funzione cifrante, ma il messaggio cifrato viene posto in XOR con l’uscita della funzione cifrante applicata al precedente blocco cifrato. c) Cipher feedback (CFB), -bit characters/ -bit feedback r-bit shift r-bit shift cj−1 I1 = IV Ij Ij cj−1 n E key E r key n leftmost r bits Oj Oj r x0j = xj xj r cj (i) encipherment (ii) decipherment Figura 4.12. Modalità di funzionamento CFB Fissato r, il blocco cifrato del generico i-esimo blocco del messaggio in chiaro xj di lunghezza r bit sarà: 38 4.4 – Modi di funzionamento cj = xj ⊕ oj (4.35) oj = leftMostr (Oj ) (4.36) Oj = EK (Ij ) (4.37) Ij = leftShiftr (cj−1 ) (4.38) dove: e ancora: Ad ogni iterazione il registro esegue r shift a sinistra sostituendo il contenuto con cj−1 . La decifratura sarà: xj = cj ⊕ oj (4.39) Questa relazione ribadisce che, a differenza delle modalità ECB e CBC, la CFB si avvale esclusivamente dell’operazione di cifratura. Questo comporta che la modalità CFB non deve essere usata se la funzione cifrante è un algoritmo a chiave pubblica (l’AES non lo è). Per questo metodo è possibile enunciare alcune proprietà: 1. Ad identici blocchi di testo in chiaro corrispondono medesimi risultati cifrati se non viene alterato il vettore di inizializzazione (non necessariamente, ma auspicabilmente, da cifrare). 2. Il blocco cifrato dipende dalla cifratura precedente, questo comporta la necessità di mantenere l’ordine corretto dei blocchi in fase di decifratura. 3. La corretta decifratura avviene quando nello shift register sono presenti valori corretti. 4. Se uno o più bit del blocco di r sono errati questo si ripercuoterà sulla decifratura del blocco (con bit errati nelle stesse posizioni) e dei successivi (con una distribuzione degli errori del 50%) fino a che nello shift register il blocco errato di r bit è stato “shiftato via”. 39 4 – AES - Advanced Encryption Standard 4.4.4 Output Feedback (OFB) La struttura di questa modalità è simile alla precedente e anche in questo caso si ricorre alla funzione cifrante sia per l’operazione di cifratura sia per quella di decifratura. In questo modo di funzionamento, affinché il procedimento cifrante risulti ancora più veloce, la connessione di retroazione (detta feedback) avviene tra l’uscita del passo di cifratura precedente, che opera iterativamente sul vettore di inizializzazione, e il blocco corrente e produce un keystream. Un vantaggio di questo metodo sul precedente è che errori di trasmissione non si propagano nel processo di decifratura. Anche se n−r bit sono trascurati prima della XOR con i dati da cifrare o decifrare, il feedback può essere composto dall’intero blocco come mostrato in figura 4.13 (versione ISO 10116), o utilizzando anche qui uno shift register e porre in feedback gli r bit posti in XOR con il testo da elaborare (versione FIPS 81). In quest’ultimo caso si ripetono le operazioni di shift a sinistra prima della cifratura come illustrato nel CFB. La nascita del primo metodo è dovuta al rischio di avere, utilizzando il secondo, periodi cifranti brevi che agevolino la crittoanalisi. Infatti applicando la stessa chiave è possibile, dopo una serie di iterazioni, ottenere un’uscita pari al blocco d’ingresso di una precedente iterazione presentando pericolose ripetitività. Oj−1 Oj−1 I1 = IV Ij Ij n E key leftmost r bits E n Oj key Oj r x0j = xj xj r r cj (ii) decipherment (i) encipherment Figura 4.13. Modalità di funzionamento OFB Anche per questo metodo è possibile enunciare alcune proprietà: 1. Con questo metodo un testo in chiaro, al variare del vettore di inizializzazione, produrrà differenti risultati di cifratura. 2. Il keystream che si pone in XOR con l’ingresso è indipendente dal testo. 3. Uno o più bit errorati nel testo cifrato si presentano nel testo in chiaro decifrato nell’esatta posizione in cui sono occorsi. 40 4.5 – Aspetti hardware 4. La perdita di bit cifrati, anche se in seguito recuperati, distrugge l’allineamento in decifratura. In questo caso è necessaria un’esplicita risincronizzazione. 5. Per conferire proprietà di accesso casuali alla decifratura è possibile utilizzare l’uscita di un contatore al posto del feedback (OFB counter mode): per decifrare un blocco non occorre decifrare il precedente. 4.4.5 Confronto dei modi di funzionamento La modalità ECB è una diretta applicazione dell’algoritmo di crittografia alla cifratura o decifratura dei dati. Nel CBC si combinano blocchi di testo cifrato a quelli da cifrare. Il CFB usa il precedente blocco cifrato come ingresso all’algoritmo la cui uscita viene combinata col testo in chiaro da cifrare. Sia per CBC sia per il CFB i blocchi cifrati sono incatenati. Nell’OFB la cifratura non viene eseguita considerando anche i dati, ma solo la precedente versione cifrata che inizialmente ha come ingresso un vettore di inizializzazione. Il primo di questi quattro metodi, l’ECB, nonostante sia il meno sicuro perchè non fornisce garanzie contro i pattern di dati ripetitivi, è quello più utilizzato. È sicuro quando si effettuano trasmissioni di valori singoli (ad esempio quando si trasmette una chiave di cifratura). I crittologi consigliano il secondo, il CBC, vista anche la sua semplicità. Questo metodo è consigliato per trasmissioni generiche eseguite mediante blocchi di dati. Il CFB è adatto alle applicazioni dei Terminali in cui i codici individuali, introdotti dall’utente, devono essere inviati all’host senza che rimangano in memoria e si orienta ad applicazioni cifranti a flussi. Sia il CBC che il CFB possono anche essere utilizzati per meccanismi di autenticazione. L’OFB, generalmente orientato alla cifratura a flussi, viene spesso utilizzato nelle comunicazioni ad alta velocità su canale rumoroso come quelli satellitari. Gli ultimi due metodi fanno inoltre uso della sola operazione di cifratura anche quando devono decifrare il messaggio. 4.5 Aspetti hardware Le operazioni svolte nell’AES sono orientate al byte, in modo tale che possano essere eseguite in maniera efficiente da un processore a 8 bit. Su di un processore a 32 bit le trasformazioni dell’AES possono essere comunque effettuate in maniera efficiente in quanto, più operazioni a 8 bit possono essere combinate in un’unica operazione a 32 bit. Molte delle architetture hardware tuttavia, preferiscono adottare un’architettura a 128 bit, che offre il più alto livello di parallelismo permesso nella computazione dell’algoritmo AES. Un alto numero di operazioni svolte in concomitanza permette di ottenere un alto throughput. Alcune implementazioni adottano un completo srotolamento delle dieci, dodici e quattordici iterazioni previste rispettivamente dall’AES-128, AES-192 e AES-256. Inoltre, utilizzando dell’hardware 41 4 – AES - Advanced Encryption Standard supplementare è possibile realizzare una versione che introduce del pipeline all’architettura. L’aver srotolato l’algoritmo porta ad un costo d’implementazione di dieci, dodici e quattordici volte tanto, rispetto alla versione non srotolata e, ovviamente, ignora la simmetria presente nell’AES. Infine la struttura con pipeline non è sempre adatta perché alcuni modi di utilizzo dell’AES, presenti nella maggior parte degli apparati commerciali, non sono in grado di sfruttare il parallelismo offerto dalla struttura con pipeline. Per esempio durante la cifratura nella modalità CBC è richiesto che il risultato della precedente cifratura sia posto in ingresso all’attuale. Di conseguenza molte implementazioni hardware dell’AES realizzano in hardware un solo round che viene riutilizzato per computare tutte le iterazioni previste. Per implementazioni che richiedono un throughput dell’ordine dei megabit non è, inoltre, necessario implementare un’architettura parallela a 128 bit; architetture più piccole possono comunque soddisfare il requisito. Per esempio, in [25] è presentata una implementazione a 32 bit che raggiunge 70 Mbps con un clock di 50 MHz. Il parallelismo dell’architettura (32 bit, 128 bit) influisce, ovviamente, sulle dimensioni del circuito. Un’architettura a 32 bit necessita di quattro S-box per computare la trasformazione SubBytes di una parola a 32 bit, mentre un’architettura a 128 bit richiede ben sedici S-box. La S-box è il componente che richiede più spazio per essere realizzato in hardware, ne consegue che il numero di S-box implementate determina, in pratica, lo spazio richiesto dall’architettura. Quindi un’efficiente approccio nell’implementazione della S-box è cruciale per le dimensioni finali del circuito. Una possibile scelta per l’implementazione della S-box prevede l’utilizzo di memoria ROM per realizzare la look-up table. La ROM deve essere in grado di memorizzare 8 · 256 = 2048 bit. In alternativa, è possibile computare l’uscita della S-box attraverso il calcolo di un’inversione nel campo GF(28 ) e la successiva trasformazione affine. J. Wolkerstorfer et al. in [35] hanno messo in evidenza come sia possibile realizzare la S-box attraverso della logica combinatoria con un’efficienza pari alla memoria ROM. In particolare, l’utilizzo della logica combinatoria è più efficiente quando è richiesta dall’implementazione anche la decodifica; in questo caso la dimensione della memoria ROM raddoppia (4096 bit). La moltiplicazione nel campo finito GF(28 ) richiesta nell’operazione di MixColumns può essere combinata con la look-up table del SubBytes in nuove look-up table denominate T-boxes [9]. Tuttavia, la trasformazione prevista nel MixColumns è adatta ad essere realizzata attraverso della logica combinatoria che richiede meno spazio delle T-boxes, ha un percorso critico corto e consuma meno energia. Un’implementazione combinata delle operazioni di MixColumns e InvMixColumns può riutilizzare le molte parti in comune dei due circuiti. La memorizzazione delle variabili richieste dell’AES ha un forte impatto sulle dimensioni globali del circuito. Un’implementazione dell’AES-128 necessita la memorizzazione di almeno 256 bit: 128 bit per memorizzare lo Stato e 128 bit per 42 4.5 – Aspetti hardware memorizzare la chiave di iterazione. In alcune piattaforme risulta essere più efficiente utilizzare la memoria integrata messa a disposizione; sulle FPGA della Xilinx, N. Pramstaller et al. [26], ha mostrato come una duplicazione dello Stato può ridurre il costo complessivo dell’hardware. In un circuito che fa uso di standard-cell la memorizzazione, fatta attraverso flip-flop, è molto onerosa; perciò in questo tipo di circuito la memorizzazione dello Stato è solitamente effettuata una sola volta. Particolare attenzione va fatta anche a proposito della schedulazione della chiave. Un’implementazione software su di una piattaforma a 32 bit, elabora tutte le sottochiavi in anticipo. Questo permette di risparmiare tempo durante la cifratura di diversi blocchi e durante la decifratura quando bisogna utilizzare le sottochiavi in ordine inverso. Un’implementazione hardware che sia efficiente in termini di spazio occupato dal circuito, prevede la computazione delle sottochiavi “al volo”, riducendo cosı̀ lo spazio di memorizzazione richiesto. Generare “al volo” la sottochiave significa che in ciascuna iterazione dell’algoritmo l’attuale sottochiave è calcolata a partire dalla precedente. Se in fase di codifica la prima sottochiave coincide con la prima chiave schedulata, nell’operazione di decodifica, invece, la prima sottochiave deve essere calcolata: la prima sottochiave è l’ultima sottochiave che si ottiene effettuando una completa schedulazione della chiave. 4.5.1 Pipelining, Sub-Pipelining e Loop Unrolling In un codificatore a blocco la dimensione del testo in ingresso è fissa e, nel caso dell’AES, pari a 128 bit. Un generico messaggio viene, prima di essere elaborato, suddiviso in blocchi di dimensione pari a quella elaborabile dal codificatore (128 bit). Le modalità operative che non prevedono un feedback, come ad esempio l’ECB, offrono minor sicurezza ma permettono l’elaborazione di più blocchi in parallelo garantendo cosı̀ un’accelerazione dell’elaborazione. Le altre modalità, che invece prevedono un feedback dei dati, offrono una maggior sicurezza nella crittografia dei dati ma non permettono l’elaborazione di più blocchi in parallelo, infatti l’elaborazione del blocco successivo non può partire fino a quando non è terminata quella attuale. Esistono tre tipi di architetture che possono essere utilizzate per incrementare le prestazioni dell’architettura di riferimento (figura 4.14) del codificatore/decodificatore. Queste architetture si basano sull’utilizzo di pipeline, sub-pipeline e loop unrolling. L’architettura di riferimento oltre al blocco che esegue un’iterazione, o round, dell’algoritmo di codifica AES prevede un registro, necessario alla memorizzazione dello Stato, e un multiplexer che permette di eseguire l’iterazione dell’algoritmo. Pipelining L’utilizzo di pipeline permette un’accelerazione del processo di codifica/decodifica grazie alla possibilità di elaborare più dati simultaneamente. La struttura con pipeline si realizza inserendo una riga di registri fra la logica combinatoria che separa un round dell’algoritmo dall’altro. Ripartire delle 43 4 – AES - Advanced Encryption Standard multiplexer 1 round registers round Figura 4.14. AES: architettura di riferimento. operazioni di logica combinatoria fra due registri consecutivi crea un livello di pipeline. Durante ciascun ciclo di clock i dati, parzialmente elaborati vengono spostati nel successivo registro e sostituiti con dei nuovi. Il numero di round k in ciascun loop è solitamente scelto come divisore di Nr e il massimo valore di k e ovviamente Nr . In quest’ultimo caso la struttura prende il nome di fully pipelined architecture. Per una struttura formata da k-round quando un blocco raggiunge il k-esimo round sarà rimandato all’ingresso al primo round finché non sarà stato elaborato Nr volte. Quando la struttura si è riempita in tutta la sua profondità, (ovvero quando tutti i registri che la compongono contengono dei dati valid) essa elabora k blocchi in parallelo a scapito di una latenza iniziale che è proporzionale a k. L’area occupata da questa struttura è proporzionale al valore di k. Sub-Pipeline A differenza del pipeline, l’architettura basata su sub-pipeline, prevede inserimento di una riga di registri oltre che all’esterno anche all’interno di ciascun round dell’algoritmo. Se ciascun round dell’algoritmo è diviso in r parti con ugual ritardo di elaborazione (dovuta alla logica combinatoria), la struttura sub-pipeline composta da k-round viene accelerata approssimativamente di r volte rispetto a quella con non fa uso del sub-pipeline. Questo significativo incremento avviene con la sola aggiunta dei registri di sub-pipeline (e di logica per il controllo) che causa un esiguo incremento dell’area occupata. Tuttavia, suddividere ciascun round in un numero arbitrario numero di stadi non sempre porta ad un incremento delle prestazioni. Se la massima frequenza di clock è vincolata da un’elemento combinatorio indivisibile (che è la causa del percorso a ritardo maggiore), dividere il resto del round in più stati non porta ad un incremento delle prestazioni. Siccome molti blocchi di dati sono elaborati allo stesso tempo, l’ammontare del numero di cicli di clock necessario ad elaborare un dato è incrementato delle stesse proporzioni (tuttavia bisogna tenere in conto dell’incremento significativo della frequenza di clock). 44 4.5 – Aspetti hardware multiplexer registers k rounds round 1 registers round 2 registers round k Figura 4.15. AES: architettura con pipeline. multiplexer registers inner stage 1 r stages registers inner stage 2 round 2 registers k rounds round 1 registers registers inner stage r round k Figura 4.16. AES: architettura con sub-pipeline. Loop Unrolling L’architettura che fa uso di loop unrolling può processare solo un blocco di dati alla volta, ma vari round sono elaborati allo stesso tempo. Il fattore di unrolling, o srotolamento, k è usualmente scelto come divisore di Nr e il suo massimo valore e per l’appunto Nr . Un blocco dati viene, in ciascun ciclo di clock, processato da Nr /k iterazioni. Con questa struttura il periodo di clock incrementa di circa k volte e non si hanno fenomeni di latenza presenti 45 4 – AES - Advanced Encryption Standard negli altri due casi. L’area occupata da quest’architettura è proporzionale al numero k di round presenti in ciascun loop. multiplexer k rounds registers round 1 round 2 round k Figura 4.17. AES: architettura con loop unrolling. 46 Capitolo 5 AES: Stato dell’arte nell’implementazione In questo capitolo vengono presentati alcuni dei lavori presenti in letteratura che descrivono l’implementazione hardware dell’algoritmo AES. Le implementazioni analizzate vengono logicamente suddivise in due categorie: la prima raggruppa tutte quelle implementazioni definite lightweight mentre la seconda raggruppa le implementazioni ottimizzare per il throughput. Per ciascuna implementazione vengono descritte le peculiarità e le performance che permette di raggiungere. 5.1 Implementazioni lightweight Per “Implementazioni lightweight” si intende far riferimento alle implementazioni hardware che sono in grado di soddisfare i vincoli di basso consumo energetico e minima occupazione di risorse hardware. Il campo di applicazione di queste implementazioni sono i diffusi dispositivi per la sicurezza elettronica di tipo passivo o alimentati a batteria, come ad esempio gli RFID e le reti di sensori wireless. 5.1.1 Principi di progettazione Un’implementazione su silicio ottimizzata richiede stringenti metodologie di progetto che devono seguire fedelmente i principi di progettazione visti nel capitolo 3. Bisogna valutare attentamente le differenti opzioni di progetto tenendo presente che gli obbiettivi dell’implementazione sono il basso consumo energetico e l’utilizzo minimo di risorse hardware mentre il throughput è di secondaria importanza. È utile, a tal fine, analizzare i pro e i contro di alcune scelte architetturali e trovarne il giusto compromesso. Per esempio, una determinata architettura può diminuire le risorse 47 5 – AES: Stato dell’arte nell’implementazione hardware necessarie ma aumentare anche sensibilmente il consumo energetico. In questa sezione saranno descritti diversi criteri di progetto. Verranno prese in esame le decisioni di progetto a livello architetturale che aiuteranno a trovare il giusto compromesso fra basso consumo energetico, basso uso di risorse hardware e un’accettabile throughput. Le soluzioni pubblicate in letteratura hanno tutte come obbiettivo un throughput dell’ordine dei Giga bit, questo è un po’ in contraddizione con quanto scritto precedentemente poiché questo nuovo vincolo innalza le risorse hardware necessarie. Le dimensioni del circuito integrato influenzano direttamente il costo del dispositivo su grandi volumi di produzione. In aggiunta, il vincolo di basso consumo energetico è di vitale importanza per i dispositivi senza contatto elettrico come le smart card o le tessere RFID. Attraverso le ottimizzazioni fatte a livello architetturale è molto importante considerare vari dettagli implementativi in grado di realizzare gli obbiettivi del progetto, che come già detto sono il basso consumo energetico e il minimo utilizzo di risorse. Nella progettazione VLSI è sempre un’opzione ottimizzare le parti critiche del circuito utilizzando un’approccio completamente su misura anziché un’approccio basato su celle standard. Utilizzare un’approccio su misura può talvolta portare ad alcuni problemi come l’aumento del tempo necessario allo sviluppo che si ripercuote negativamente sul costo finale del dispositivo. Inoltre, in questo modo si rallenta la migrazione tra le diverse tecnologie CMOS. Di conseguenza tutte le ottimizzazioni sono fatte all’interno della descrizione VHDL che velocizza il flusso di progetto, compresa la sintesi e il place and route per le differenti tecnologie CMOS. Progetto per il basso utilizzo di risorse hardware La progettazione di un circuito VLSI per il basso utilizzo di risorse hardware utilizzando le celle standard richiede delle valutazioni a partire dal livello algoritmico fino al livello circuitale. Tra le valutazioni fatte per l’algoritmo AES c’è la necessità di capire quale sia il grado di parallelismo da scegliere. Nell’AES l’unità fondamentale di calcolo è il byte (8 bit), dunque un’architettura a 8 bit può essere scelta al fine di creare un’implementazione compatta capace di riutilizzare al massimo le risorse messe a disposizione. Utilizzare una RAM dedicata anziché un’approccio basato su flip-flop è una questione importante durante il progetto. Normalmente, la RAM ha un’efficienza spaziale maggiore vista la sua regolarità strutturale. L’approccio basato su flip-flop può essere vantaggioso solo se la dimensione della memoria è inferiore a 256 bit. Progetto per il basso consumo energetico L’ottimizzazione del consumo energetico è diventato al giorno d’oggi il maggior obbiettivo nella progettazione VLSI. È bene notare che esiste una precisa differenza fra il consumo energetico e consumo di potenza. Per i dispositivi alimentati a batteria il consumo 48 5.1 – Implementazioni lightweight energetico per operazione è di vitale importanza, questo significa che il powerdelay deve essere minimizzato. Viceversa, in dispositivi alimentati in maniera passiva (come le smart card contactless) il consumo medio di potenza è il parametro critico e la durata della dell’operazione non è importante. È importante che il consumo di potenza per ciclo di clock sia limitato anche se, alla fine, il consumo di energia è maggiore. Si rende necessario in questo caso porre in cascata le operazioni da effettuare poiché l’esecuzione in contemporanea di più operazioni potrebbe eccedere il budget di potenza a disposizione. Questo tipo di implementazione porta ad ottenere un dispositivo che minimizza il consumo medio di potenza. Il consumo totale di potenza di un circuito CMOS è la somma dei consumi statici e dinamici. I consumi statici causati da una corrente di leakage dipendono principalmente dalla dimensione del circuito integrato e possono in questa analisi essere trascurati essendo un contributo controllabile solamente a livello tecnologico. I consumi dinamici consistono nell’energia necessaria a caricare e scaricare la capacita totale CL di tutte le linee di interconnessione del chip. L’equazione 5.1 mostra i parametri che bisogna ottimizzare al fine di minimizzare il consumo di potenza. 2 Pdyn = CL · VDD · fCLK eff · Esw (5.1) La capacità CL da caricare è tanto più grande quante sono le porte logiche piazzate nel circuito integrato. Questo significa che diminuire la dimensione del circuito cosı̀ come diminuire la tensione di alimentazione VDD porta a una diminuzione della potenza assorbita dal circuito. Questi due coefficienti sono implicitamente predeterminati, il primo dal vincolo di ottenere un basso utilizzo di risorse hardware, il secondo dalla tecnologia utilizzata per l’implementazione. Supponendo una tensione di alimentazione fissa, la miglior scelta per un progetto a basso consumo di potenza è ridurre la frequenza di clock efficace fCLK eff del circuito. Questo diminuirà in maniera lineare il consumo di potenza del circuito. Il “Clock Gating” è un’efficiente tecnica che permette di ridurre la frequenza di clock effettiva. Questo si ottiene attivando il segnale di clock solo per i registri che hanno effettivamente del lavoro da compiere. Per esempio, nella memoria RAM soltanto un registro da 8 bit può essere scritto alla volta, quindi soltanto un registro assorbirà energia durante il fronte di clock. In aggiunta, non vi è la necessità di avere un multiplexer all’ingresso del registro per memorizzare il valore precedente che garantisce una diminuzione dell’hardware richiesto. Nell’implementazione hardware dell’AES la misura del Clock Gating è stata 49 5 – AES: Stato dell’arte nell’implementazione applicata in maniera rigorosa a tutti i sottomoduli con il risultato di abbassare significativamente il consumo di potenza. L’attivita di switching Esw del circuito può essere ridotta attraverso l’applicazione del metodo chiamato “sleep logic”. Questa tecnica si utilizza quando si nota che l’uscita di un circuito combinatorio non è sempre necessaria e che la variazione dei suoi ingressi causerà un consumo energetico inutile. Al fine di evitare questo spreco energetico si possono mascherare gli ingressi del circuito combinatorio attraverso un schiera di porte logiche AND a due ingressi, una per ogni segnale d’ingresso, pilotate da un segnale comune di enable. Cosı̀ facendo si impediranno tutte le attività di commutazione dei segnali all’interno della logica combinatoria. 5.1.2 Lavori presenti in letteratura Le prime implementazioni hardware dell’algoritmo AES furono presentate durante la fase di selezione dello standard AES. Nel frattempo un’ampia gamma di implementazioni è stata pubblicata in letteratura. La maggior parte di queste implementazioni utilizza un hardware riconfigurabile (FPGA) come obbiettivo tecnologico. Le implementazioni ottimizzate per l’FPGA possono differire in maniera sostanziale da quelle proposte per le celle standard poiché le funzioni di costo tra le due tecnologie come visto già in precedenza sono molto differenti. Conseguentemente in questa sezione verranno analizzati solo quelle realizzazioni che hanno come target le celle standard poiché sono le uniche a garantire un basso consumo energetico e basso utilizzo di risorse. L’hardware AES presentato da A. Satoh et al. [29] è basato su di un’architettura a 32 bit che divide su tre blocchi le funzionalità di cifratura, decifratura e espansione della chiave. Le quattro S-Box implementate vengono utilizzate in maniera congiunta sia dal modulo cifrante che da quello per la schedulazione della chiave. Sono presenti due grandi multiplexer, il primo è utilizzato per selezionare una parola a 32 bit dallo Stato o dal registro della chiave, il secondo per selezionare all’uscita del datapath il risultato appropriato. Data la sua struttura interna necessita di un moltiplicatore MixColumns e due moltiplicatori InvMixColumns. Questa implementazione esegue la cifratura e decifratura con una dimensione della chiave di 128 bit. La complessità dell’hardware è di 5.400 porte e raggiunge un throughput di 311 Mbps. Un’approccio molto regolare è presentato da Mangard et al. [19]. È un’architettura a 32 bit in grado di eseguire la cifratura e decifratura con differenti dimensione della chiave segreta. Vengono impiegati sedici istanze di una data cella di calcolo in grado di memorizzare 8 bit di dati ciascuna. La cella contiene il moltiplicatore MixColumns ed è in grado di eseguire tutte le trasformazione con l’eccezione del 50 5.1 – Implementazioni lightweight SubBytes. La parametrizzazione del numero di S-Box, che possono essere 4 o 16, permette di ottenere una scalabilità del throughput. In un successivo articolo [25] gli stessi autori presentano una versione minimale che prevede l’utilizzo di soli 4 moltiplicatori MixColumns. Questo approccio richiede un’area del circuito integrato pari a 8.500 porte equivalenti ed ha un throughput massimo di 70 Mbps. Da menzionare il fatto che è in grado di supportare la modalita CBC. Feldhofer et al. [10] descrivono nel loro articolo un’architettura in grado di eseguire la funzionalità di sola cifratura. La sua applicazione è rivolta alla tecnologia RFID e utilizza un’architettura a 8 bit. La descrizione dei dettagli implementativi, a cui si farà riferimento successivamente in questa sezione, sono principalmente originati dal lavoro di Feldhofer et al. [11] in cui viene descritto un circuito integrato disponibile sul mercato. 5.1.3 Dettagli implementativi Il progetto dell’implementazione hardware dell’AES è stata fatta utilizzando una metodologia flessibile che ha messo in evidenza una serie di possibili idee per l’ottimizzazione. Tutte le idee sono state valutate per quanto riguarda il loro impatto sulla dimensione del chip e sull’efficienza di potenza. Le valutazioni sono state fatte a partire dai risultati di sintesi e sulle simulazioni fatte a livello di circuito. Questa analisi assicura che il circuito realizzato sarà compatibile per i dispositivi alimentati passivamente. Qui di seguito è presentata l’architettura del modulo AES mettendo in evidenza alcuni particolari. Architettura hardware In [11] è proposta un’architettura per la cifratura e la decifratura che supporta una dimensione della chiave fissa pari a 128 bit. Questo riduce il numero di round a 10 e la memoria richiesta per la memorizzazione dello Stato e della chiave di round non eccede 256 bit. I requisiti di basso consumo di potenza del chip sono molto restrittivi da non permettere l’uso di operazioni a 128 bit e neppure un’esecuzione a 32 bit. Ne consegue che è necessario sviluppare un’architettura a 8 bit che è l’unica in grado di soddisfare i requisiti, la figura 5.1 mostra la struttura l’architettura implementata. La parte principale dell’architettura sono il controller, la memoria RAM, il datapath e il modulo di IO. Il modulo di IO è un’interfaccia verso il microcontrollore che permette di utilizzare il modulo come un coprocessore. Il controller accetta i comandi provenienti dal modulo di IO a provvede alla generazione dei segnali di controllo per la RAM e per il datapath al fine di eseguire l’algoritmo AES. Il controller è realizzato mediante la descrizione di una macchina a stati finiti implementa in hardware che permette di ottimizzare il consumo energetico e la dimensione del 51 Control 5 – AES: Stato dell’arte nell’implementazione RAM 32 x 8-bit 8 IO 1 S-Box Reg Rcon 1/4 MixColumns Datapath din Datapath Figura 5.1. Architettura a 8 bit per l’AES128 chip. Le sue parti principali sono un contatore ciclico a 4 bit e un registro per l’indirizzamento della memoria RAM. Il contatore è implementato come un shift-register utilizzando una codifica one-hot la quale assicura che il cambiamento di stato causi solo due transizioni di segnale. Inoltre la codifica one-hot riduce al minimo l’attività di glitching dei segnali di controllo. La macchina a stati finiti (fsm) sequenzia i dieci round dell’algoritmo ciascuno dei quali comprende le operazioni di AddRoundKey, ShiftRows, SubBytes, MixColumns e le loro funzioni inverse. È implementata la generazione al volo della chiave di round che aiuta a minimizzare il quantitativo di memoria necessario pari a 256 bit: 128 bit per la memorizzazione dello stato e 128 bit per la memorizzazione della chiave di round. Siccome non vi è altro quantitativo di memoria a disposizione per la computazione dell’algoritmo, il controller, assicura che nessun byte dello Stato o della chiave è sovrascritto dai risultati intermedi se questi ultimi sono ancora necessari alla computazione. La memoria è di tipo single ported al fine di facilitare l’implementazione su silicio ed è realizzata come una memoria basata su flip-flop. L’utilizzo intensivo della tecnica di clock gating ha permesso di ridurre al minimo il consumo di potenza. 52 5.1 – Implementazioni lightweight Implementazione del datapath Il datapath (figura 5.1) del modulo AES contiene la logica combinatoria necessaria al calcolo delle trasformazioni SubBytes, MixColumns, AddRoundKey e le loro inverse. Le operazioni di ShiftRows e InvShiftRows sono realizzate attraverso un’appropriato indirizzamento della memoria RAM fatto dopo l’utilizzo della S-Box. I rimanenti componenti del datapath sono il sottomodulo Rcon, qualche porta logica XOR e un registro a 8 bit per la memorizzazione del risultato intermedio della schedulazione della chiave. Rcon è un circuito che provvede a fornire la costante necessaria per la schedulazione della chiave. Le porte logiche XOR sono necessarie per la schedulazione della chiave e vengono riutilizzate nell’operazione di AddRoundKey. Inoltre le operazione di input dello Stato e della chiave sono maneggiate dal datapath. L’obbiettivo di progetto era di rendere il consumo di potenza regolare nel tempo per tutte le operazioni eseguite dal datapath che avvengono durante l’esecuzione dell’algoritmo AES. Il livellamento è molto importante per i dispositivi contactless poiché un’aumento improvviso della richiesta di potenza elettrica potrebbe causare un reset del circuito. Questo reset può essere innescato dalla caduta della tensione di alimentazione sotto il livello minimo. Conseguentemente a ciò i sottomoduli S-Box e MixColumns sono progettati in maniera tale che il loro assorbimento di potenza sia il più simile possibile. La cifratura o decifratura dei 16 byte dello stato avviene nel seguente modo. I 16 byte dello stato in input vengono scritti in memoria RAM attraverso il modulo di IO seguiti dai 16 byte della chiave di cifratura. Nella cifratura l’operazione di AddRoundKey iniziale è fatta durante l’operazione di caricamento della chiave; per la decifratura ciò non è possibile poiché è necessario schedulare in anticipo la chiave al fine di trovare l’ultima. All’arrivo del segnale di start incomincia la cifratura o decifratura dello Stato. I dieci round dell’AES128 con le funzionalità di SubBytes, ShiftRows, MixColumns per la cifratura e di InvSubBytes, InvShiftRows, InvMixColumns per la decifratura, sono effettuate in accordo con le specifiche dell’algoritmo. Durante l’operazione di AddRoundKey, che è uguale sia per la cifratura che per la decifratura, viene elaborata la successiva chiave di round utilizzando la S-Box, il modulo Rcon e le porte logiche XOR del datapath. La cifratura è fatta in 1.032 cicli di clock comprese anche le fasi di IO, mentre la decifratura necessita di 1.165 cicli di clock a causa della schedulazione iniziale della chiave. S-Box Un significativo vantaggio dell’architettura a 8 bit è la riduzione ad una sola istanza della S-Box. Ciò permette di ridurre in maniera considerevole lo spazio richiesto dal chip dato che la S-Box è il componente più grande del datapath. La singola S-Box viene utilizzata per le operazioni di SubBytes e di 53 5 – AES: Stato dell’arte nell’implementazione InvSubBytes. Ci sono diverse opzioni per implementare la S-Box tra queste la più evidente è l’utilizzo di una 512×8 bit ROM che consente di immagazzinare la lookup table sia per la cifratura che per la decifratura. Purtroppo la ROM non ha buone proprietà per quanto riguarda il basso consumo di potenza. Un’opzione particolarmente vantaggiosa per il computo delle operazioni di SubBytes e InvSubBytes è presentato nell’articolo di Xinmiao et al. [35] e propone l’utilizzo di logica combinatoria. Una caratteristica di questa S-Box è la possibilità, di inserire al suo interno dei registri di pipelining. La S-Box utilizzata nell’architettura proposta prevede un livello di pipelining che oltre ridurre il critical path riduce l’attività di glitching. Inoltre il registro di pipelining è utilizzato come unità intermedia di memoria durante le operazioni di ShiftRows e la sua inversa. Durante l’operazione di SubBytes sono due i byte che entrano nella struttura con pipelining cosicché si creano le condizioni per poter sovrascrivere alcuni byte in memoria ed eseguire contemporaneamente le operazioni di SubBytes e ShiftRows. Quest’ultima, in pratica, degenera in un indirizzamento in memoria. Allo scopo di ridurre l’attività dei segnali della S-Box viene utilizzato per i suoi ingressi una variante della tecnica del sleep logic. Quando l’uscita della S-Box non è necessaria vengono azzerati i suoi ingressi in maniera tale da renderla inattiva. Questo si realizza ponendo in ingresso alla S-Box il valore {0×52} per la cifratura e {0×63} per la decifratura il che rende l’uscita della S-Box sempre uguale a zero (vedi le tabelle 4.3 e 4.9). Grazie a questa variante della tecnica di sleep logic è possibile utilizzare delle semplici porte logiche XOR per poter multiplexare l’uscita della S-Box e degli altri componenti del datapath (MixColumns, etc.). Questo approccio consente di ottenere dei vantaggi in termini di spazio e potenza assorbita se confrontato alla soluzione con multiplexer. MixColumns Un’altra ed innovativa soluzione per realizzare un basso consumo di potenza viene dalla tecnica utilizzata per la computazione delle operazioni di MixColumns e InvMixColumns. È stato sviluppato un sottomodulo in grado di elaborare un quarto dell’operazione di moltiplicazione di colonna in un ciclo di clock e anziché utilizzarne quattro come proposto in [34] se ne utilizza solo uno ma modificato. Le colonne dello Stato sono considerati come polinomi nel campo GF(28 ) che vengono moltiplicati modulo x4 +1 per un polinomio fisso c(x) per la cifratura. Il polinomio inverso c−1 (x) viene utilizzato per la decifratura. L’equazione 5.2 mostra il risultato della combinazione dei due polinomi fissi al fine di ridurre la complessità per il calcolo congiunto della funzione di MixColumns e della sua inversa. Dopo la sottrazione del polinomio c(x) dal suo inverso c−1 (x) e dopo aver raccolto i termini comuni {08} e {0c} si nota come sono necessari 54 5.1 – Implementazioni lightweight solo due coefficienti per poter calcolare il polinomio inverso a partire da quello originario. c(x) c (x) c−1 (x) − c(x) c−1 (x) − c(x) c−1 (x) −1 = = = = = {03}x3 + {01}x2 + {01}x + {02}x {0b}x3 + {0d}x2 + {09}x + {0e}x {08}x3 + {0c}x2 + {08}x + {0c}x {08}(x3 + x) + {0c}(x2 + 1) c(x) + {08}(x3 + x) + {0c}(x2 + 1) (5.2) 8 data_in 8-bit FF i j k l 8-bit FF Multiplier 8 data_out 8-bit FF ai {01} {08} al {03} aj {01} {0C} ak {02} dec Multiplier Figura 5.2. Sottomodulo MixColumns Questo nuovo approccio ha portato a implementare un moltiplicatore particolarmente efficiente mostrato in figura 5.2. Il moltiplicatore cosı̀ configurato, dopo una fase di caricamento che dura tre cicli di clock, produce in uscita un byte valido in colpo di clock. L’elaborazione di un’intera colonna dello Stato necessita sette cicli di clock e per trasformare l’intero Stato 28 cicli di clock. Il percorso critico del moltiplicatore non è di rilievo perché più corto di quello della S-Box. 55 5 – AES: Stato dell’arte nell’implementazione 5.1.4 Caratteristiche dell’implementazione L’implementazione di Feldhofer et al. [11] utilizza una tecnologia a celle standard CMOS da 0,35 µm della Philips Semiconductors. Il circuito è stato descritto e validato in VHDL a livello di registro. Alcuni elementi del circuito sono stati modellati manualmente al fine di ottenere dal sintetizzatore i risultati voluti. Il sintetizzatore utilizzato è il PKS della Cadence e il generazione del clock tree è stata fatta con il software della CT-Gen. I test e le verifiche fatte con continuità hanno permesso di eliminare gli errori durante le fasi di progetto. Pei il placement and routing è stato utilizzato il Silicon Ensemble della Cadence. Infine sono stati eseguiti dei test per accertare la manufacturability del dispositivo. Le prove effettuate riguardano la static timing analysis, la power simulation, l’LSV e la DRC. Dopo la produzione del circuito integrato è stata eseguita la verifica del corretto funzionamento del chip attraverso l’utilizzo grazie all’ambiente di test HP82000. Die size Il die size del chip è la più piccola conosciuta in grado di eseguire la cifratura e la decifratura dell’AES128. Il core necessita di un’area di silicio pari a 0,25 mm2 su una tecnologia CMOS di 0,35 µm che può approssimativamente essere paragonata a 4.400 porte equivalenti. I risultati di sintesi indicano una complessità di 3.400 porte equivalenti. La differenza della complessità è dovuto al clock tree, alle filler cell e ad altri elementi per il layout. La figura 5.3 mostra la foto del die usando un fattore di ingrandimento di circa 40 volte. La parte più grande del circuito è quella che realizza la memoria RAM basata su flipflop e occupa circa il 60% dell’area del circuito. Il controller che include la fsm, il contatore ciclico, il registro di indirizzamento necessita di circa il 12%. La S-Box e il MixColumns richiedono rispettivamente il 12% e il 9%. L’area rimanente è occupata dal sottomodulo Rcon, dalle porte logiche XOR e dal multiplexer per l’uscita del datapath. Prestazioni Le misurazioni fatte con il chip tester indicano che il circuito è in grado di funzionare anche con tensioni di alimentazione molto basse. Il chip lavora correttamente con una tensione di alimentazione maggiore di 0,65 V. A questa tensione è possibile spingere la frequenza di clock fino a circa 2 MHz. Alla massima tensione di lavoro, pari a 3,3 V, la massima frequenza di clock ottenibile è di 80 MHz. Con questa frequenza di clock si ottiene il massimo throughput che è pari a 9,9 Mbps per la cifratura. Le performance per la decifratura sono circa simili. Consumo di potenza Un metodo comune per misurare la potenza consumata da un circuito digitale è quella di misurare la corrente assorbita e assumere la tensione di alimentazione costante. La misura di corrente viene fatta indirettamente misurando con un’oscilloscopio la caduta di tensione ai capi di un 56 5.1 – Implementazioni lightweight Figura 5.3. Foto del die del chip resistore, di basso valore ohmico, posto in ingresso al circuito. Questa tecnica è inevitabilmente affetta da errore a causa dei picchi di corrente che caratterizzano i circuiti digitali ed è difficile poter misurare piccoli valori di corrente a causa del rumore termico. Si è dunque utilizzato il metodo del charge transfer per evitare i problemi appena elencati. Questo metodo è molto diffuso per la misura di potenza assorbita da circuiti digitali a basso consumo. Questa tecnica si basa sulla misura della caduta di tensione ai capi di una condensatore che alimenta il circuito digitale durante il suo funzionamento. Il consumo di corrente misurato del chip è di 0,3 µA quando opera a una frequenza di clock di 100 KHz e la tensione di alimentazione è di 1,5 V. A confronto, il consumo di corrente simulato con il tool DIESEL della Philips Semiconductor è di 3,3 µA per la stessa frequenza di clock e di tensione di alimentazione. Questa figura di potenza non include la potenza dissipata dai piedini di IO poiché sono alimentati con una tensione differente. La potenza assorbita viene distribuita fra i vari componenti nel seguente modo: la RAM assorbe circa il 52% della potenza, segue il controller con il 18% e il datapath con la restante potenza libera. La S-Box consuma il 14% della potenza, il MixColumns l’8% come pure il restante circuito che comprende il multiplexer di uscita, il registro a 8 bit, le porte logiche XOR e il modulo Rcon. Confronto con altre implementazioni Questa sezione mette a confronto il lavoro proposto da Feldhofer et al. [11] con altre implementazioni proposte [25] e [29]. Queste due alternative proposte sono anch’esse ottimizzate per un basso consumo energetico e un basso utilizzo di risorse. La tabella 5.1 mostra 57 5 – AES: Stato dell’arte nell’implementazione come il circuito proposto da Satoh et al. necessita di 5.400 porte equivalente su di una tecnologia di 0,11 µm mentre il circuito di riferimento ne richiede solo 3.400, circa il 40% in meno. Infine, il circuito proposto da Mangard et al. necessita invece di 8.500 porte equivalenti ma include il funzionamento della modalità CBC e un’interfaccia AMBA su tecnologia 0,6 µm. Non considerando la funzionalità CBC il conteggio delle porte equivalenti necessarie scende a 7.000, circa il doppio della soluzione di riferimento. Un confronto ragionevole fra la massima frequenza di clock e il throughput è difficile da compiere. Il lavoro proposto in [29] raggiunge i 130 MHz circa il 60% più veloce della soluzione presentata. Questo risultato è pero da attribuire alla più recente tecnologia implementativa che alle scelte architetturali. Il percorso critico della soluzione [29] è molto più lungo della soluzione presentata in [11] poiché comprende una S-Box completa, due ampi multiplexer, un moltiplicatore MixColumns e delle porte logiche XOR. A confronto il percorso critico di [11] è di circa un terzo perché costituito fondamentalmente da metà della S-Box, si ricorda la presenza all’interno del registro di pipelining, e da alcuni componenti di logica simili alla soluzione proposta in [25]. Purtroppo le altre pubblicazioni non presentato i dati relativi al consumo di potenza poiché i loro progetti non sono stati fabbricati su silicio. Il consumo di potenza di [11] dovrebbe essere il più basso perché è l’unico progetto che si pone seriamente come obbiettivo la realizzazione di un dispositivo a bassissimo consumo di potenza. AES128 Version Feldhofer [11] Satoh [29] Mangard [25] Tech. [µm] 0,35 0,11 0,6 Area [GEs] 3.400 5.400 7.000 Throughput [Mbps] 9,9 311 70 Max. Freq. [MHz] 80 130 50 Power [µW ] 4,5 – – Tabella 5.1. Stima delle risorse e delle performance per diverse soluzioni lightweight 5.2 Architetture ottimizzate per il throughput Le applicazioni che richiedono un’implementazione ad alta velocità dell’AES sono svariate, ad esempio un throughput nell’ordine dei Gigabit è necessario nei protocolli di rete come l’IPsec e il TLS. Sia le tradizionali reti cablate che quelle ottiche sono tuttora in grado di garantire un data rates fino a 20 Gbps. Le reti wireless, invece, stanno attraversando un periodo di sviluppo tecnologico che le porterà nei prossimi anni a raggiungere la soglia dei Gigabit. 58 5.2 – Architetture ottimizzate per il throughput 5.2.1 Principi di progettazione La metodologia di progetto hardware per un’applicazione ad alta velocità dell’AES richiede un’attenta valutazione delle differenti opzioni di progetto. Lo scopo principale in questa sezione è quello di ottenete dall’implementazione un’alto throughput mentre è di minor importanza la minimizzazione delle risorse hardware e il consumo energetico. Le prestazioni richieste dipendo inoltre dal tipo di applicazione per la quale si sviluppa l’AES; in questa sezione si evidenzieranno diversi aspetti che bisogna tenere in conto durante la fase di progetto. La scelta dell’architettura hardware di un’implementazione determina fondamentalmente le proprietà del circuito. Al fine di conseguire l’obbiettivo prefissato oltre all’ottimizzazione del livello architetturale è importante considerare vari dettagli implementativi. Nella progettazione VLSI, che prevede lo sviluppo di un progetto completamente su misura, è comune ottimizzare le parti critiche del circuito per da ottenere alte performance a scapito di un lungo periodo di sviluppo e validazione. La decisione di sviluppare un circuito completamente su misura deve essere fatta con attenzione poiché riadattare il circuito su di un differente processo tecnologico può non essere facile. La scelta della tecnologia sulla quale implementare il circuito, come è noto, è determinata dal numero di unità che si intende produrre. I costi di produzione di un’ASIC basata su standard-cell sono spesso troppo alti per la produzione di un piccolo numero di apparati, perciò l’utilizzo di FPGA è una alternativa valida. Oltre ai vantaggio di essere un dispositivo adattabile (ad esempio, rispetto al cambiamento della dimensione della chiave o al modo di operare) il costo per dispositivo in FPGA di grandi dimensioni diminuisce. Per questa ragione il costo di sviluppo e di produzione potrebbe essere contenuto. Concetti per l’architettura del sistema La scelta del tipo di architettura determina essenzialmente le performance del circuito. Sebbene un’architettura a 32 bit riduca le risorse hardware richieste ed il rapporto tra throughput e area occupata è paragonabile a quello ottenuto con un’architettura a 128 bit, prestazioni dell’ordine dei Gigabit possono essere ottenute solamente quando il computo è fatto con operazioni a 128 bit. Le operazioni di ShiftRows e InvShiftRows se effettuate a 128 bit sono delle semplici rimappature dei byte dello Stato. SubBytes e InvSubBytes sono operazioni eseguite a livello di byte, quindi per elaborare in modo parallelo lo Stato è necessario istanziare sedici S-Box. In maniera analoga per le operazioni di MixColumns e InvMixColumns è necessario istanziare quattro moltiplicatori. Per la schedulazione della chiave sono necessarie oltre ad alcuni elementi di logica combinatoria quattro S-Box (AES-128) che opzionalmente possono essere condivise con l’unità che elabora i dati. 59 5 – AES: Stato dell’arte nell’implementazione Le tecniche di pipelining, sub-pipelining e loop unrolling dovranno essere prese in considerazione al fine di incrementare al massimo le performance. Ottimizzazione dell’hardware per i differenti modi operativi In letteratura pipelining e loop unrolling sono indicate come delle tecniche per incrementare le prestazioni di un circuito. Questo concetto non è del tutto corretto e ne chiariremo qui di seguito le motivazioni. I modi di funzionamento raccomandati per un codificatore simmetrico come l’AES sono definite dal NIST [22]. Secondo l’applicazione i modi più noti sono: Electronic Codebook (ECB), Cipher Block Chaining (CBC), Cipher Feedback (CFB), Output Feedback (OFB) e Counter (CTR). Altri modi recentemente standardizzati sono Cipher-based MAC (CMAC) e Counter with Cipher Block Chaining-message Authentication Code (CCM) [23, 24]. Due classificazioni di base possono essere fatte se la procedura di crittografia usa un modo con feedback (CBC, CFB, OFB) o senza feedback (ECB, CTR). Nella modalità che prevedono un feedback, la precedente codifica è coinvolta nel computo della successiva. Quindi non è possibile iniziare la crittografia del blocco seguente fino a che il risultato di quello precedente non è terminato. Perciò, le tecniche di loop unrolling e pipelining sono in generale inutili poiché è attivo solamente un round alla volta. Ne consegue che il guadagno di prestazioni è esiguo e lo spreco di risorse notevole. Inoltre, il tempo che intercorre tra l’inizio delle operazioni di cifratura e la fine (latenza) rimane lo stesso. Il throughput, come si vedrà i seguito, è inversamente proporzionale al tempo di latenza. Un’eccezione deriva dalla codifica o decodifica di flussi di dati indipendenti e multipli. Il numero di round che compongono il pipelining definiscono il numero di flussi dati indipendenti che possono essere elaborati parallelamente. Ciò è possibile perché il risultato di un flusso non è influenzato dagli altri. Sebbene la tecnica di sub-pipelining non porti ad un incremento delle prestazioni nella modalità con feedback ci sono dei validi motivi per i quali è bene introdurla nell’architettura. Il percorso critico, dovuto alla logica combinatoria, se troppo lungo potrebbe essere spezzato al fine di ottenere la frequenza di clock desiderata. Inserendo una riga di registri si riduce il cammino critico ottenendo cosı̀ la possibilità di incrementare la frequenza di clock e ridurre l’attività del segnale. Questo è una metodo per ridurre significativamente l’assorbimento di energia del circuito. Per i metodi che non prevedono feedback, come l’ECB oppure il CTR, è possibile sfruttare le tecniche di pipelining, sub-pipelining e loop unrolling al fine di ottenere il massimo delle performance dal circuito. Nell’AES la più veloce architettura può essere ottenuta srotolando completamente tutti i round e inserendo molti livelli di sub-pipelining. 60 5.2 – Architetture ottimizzate per il throughput Il calcolo del throughput, per una data implementazione, dipende da molti fattori. L’equazione 5.3 evidenzia come il throughput di un circuito dipende solamente dalla dimensione del blocco e dalla latenza. Nell’AES a causa di una dimensione del blocco fissa, pari a 128 bit, la latenza è minimizzata per elevati throughput come evidenziato dall’equazione 5.4. T hroughput = Latency = Block size Latency Tclk · #Rounds per block · #P ipeline stages #U tilized stages (5.3) (5.4) Il tempo Tclk è il periodo di clock del circuito e dipende dal percorso critico del circuito. Il valore #Rounds per block è il numero di round necessari al calcolo di un blocco dati. #P ipeline stages rappresenta il numero di stadi di pipelining presenti nell’architettura e #U tilized stages è il numero di stadi di pipelining usati in parallelo. Architecture Iterative Iterative Sub-unrolling Sub-unrolling Fully Fully unrolled piped piped unrolled piped Unrolled rounds 1 1 k k 10 10 Inner-round stages 0 n 0 n 0 n #P ipeline stages 1 n k k·n 10 10·n #Rounds per block 10 10 10/k 10/k 1 1 Tclk Tref Tref /n Tref Tref /n Tref Tref /n #U tilized stages 1 n k k·n 10 10·n Latency 10·Tref 10·Tref /n 10·Tref /k 10·Tref /(k·n) Tref Tref /n T hroughput ECB T href n·T href k·T href k·n·T href 10·T href 10·n·T href T hroughput CBC T href T href T href T href T href T href Resources Aref Aref +n·R k·Aref k·(Aref +n·R) 10·Aref 10·(Aref +n·R) Figura 5.4. Tabella comparativa delle performance di diverse architetture. La figura 5.4 confronta le prestazioni ottenute da diverse implementazioni ad alta velocità dell’AES. La prima colonna contiene l’implementazione di riferimento nella quale è stato adottato un’approccio iterativo senza pipelining. Le penultime due righe mostrano il throughput ottenibile dalle due architetture base, ECB e CBC, per le differenti implementazioni. Come detto precedentemente per un’architettura che non fa uso di feedback, come l’ECB, il throughput cresce con il numero di stadi di pipelining inseriti. Per le architetture di tipo feedback, come il CBC, il throughput non può incrementare se si elabora un solo flusso di dati alla volta. Per le modalità operative che prevedono 61 5 – AES: Stato dell’arte nell’implementazione l’elaborazione di più flussi dati alla volta è possibile ottenere le stesse prestazioni ottenibili dalla modalità ECB. Le risorse hardware richieste dalle diverse implementazioni sono elencate nell’ultima riga, in cui il valore R tiene conto dell’introduzione dei registri di pipelining a 128 bit. 5.2.2 Lavori presenti in letteratura Molti gruppi di ricerca hanno sviluppato diverse implementazioni ad alta velocità dell’AES. La maggior parte di queste fa uso di hardware riconfigurabile (FPGA) [7, 8, 13, 20, 26, 28, 30, 27, 32, 36, 37] mentre solo alcune convergono nell’utilizzo di celle standard CMOS [12, 14, 31]. Il flusso dati ottenuto spazia dai 150 Mbps ottenuti da un’implementazione a 32 bit fino a 68 Gbps realizzati da un’implementazione a 128 bit. Le architetture con pipelining completamente srotolate soffrono del fatto che possono essere utilizzate solo in alcuni modi operativi. Nei modi senza feedback, ECB e CTR, è possibile riempire per intero la struttura pipelinata ma in generale i modi con feedback, come il CBC, CFB e OFB, sono più utilizzati per la crittografia di flussi ad alta velocità. In molti articoli non viene affrontata la schedulazione della chiave rendendo quindi non funzionale il progetto. Le implementazioni di Chodowiec [7] e Pramstaller [26] sono implementazioni a 32 bit adatte per la cifratura e decifratura. Il loro massimo data rate è di rispettivamnete 150 Mbps e 215 Mbps. Entrambe utilizzano un’innovativa rappresentazione dello Stato in cui vengono memorizzati due Stati. Il primo Stato memorizza i valori attuali mentre l’altro memorizza quelli futuri cioè quelli in via di elaborazione. Questa rappresentazione avvantaggia l’operazione di ShiftRows che è solamente più un indirizzamento al registro corretto cosı̀ da non richiedere nessuna operazione di trasposizione fra colonne e righe. Ambedue le implementazioni eseguono la schedulazione della chiave in anticipo. Chodowiec [7] utilizza un datapath seriale in cui sono necessari quattro cicli di clock per round. Le S-Box sono implementate in blocchi dedicati di RAM. Le operazioni di MixColumns e InvMixColumns sono implementate efficientemente in LUT attraverso l’esplorazione della logica in comune. L’implementazione sull’FPGA Spartan II della XILINX richiede 222 CLB e 3 blocchi di RAM ed è capace di un throughput di 166 Mbps con un clock di 60 MHz. L’implementazione di Pramstaller [26] supporta la modalità CBC, ha un interfaccia al bus AMBA APB ed ha una datapath in cui le operazioni di SubBytes e MixColumns lavorano in parallelo. In questo modo il percorso critico è più corto ma sono necessari dieci cicli di clock per round. I circuiti che implementano la S-Box [35] e MixColumns sono basati sul lavoro di Johannes Wolkerstorfer. La memoria di stato è realizzata configurando le CLB come una memoria RAM sincrona di tipo dual-port. Questa soluzione richiede un totale di 1.125 CLB e nessun blocco di RAM. Alla frequenza di clock di 161 MHz il throughput è pari a 215 Mbps sia per il modo ECB che CBC. 62 5.2 – Architetture ottimizzate per il throughput Una delle prime implementazioni ad alta velocità dell’AES è stata presentata da McLoone [20]. L’architettura è a 128 bit e prevede, in base alla dimensione della chiave, il completo srotolamento dei 10, 12 o 14 round dell’algoritmo ciascuno dei quali prevede degli stadi di pipeline all’interno. Dopo una fase iniziale, per ciascun colpo di clock, viene elaborato uno Stato per le modalità senza feedback. La matrice di moltiplicazione dell’operazione di MixColumns è implementata direttamente e i valori delle S-Box sono memorizzati nei blocchi di RAM. Le risorse richieste dall’FPGA sono 2.222 CLB e 100 blocchi di RAM. Il data rate di 7 Gbps è ottenuto con una frequenza di clock pari a 54.35 MHz. In aggiunta è proposto un approccio che prevede sia la cifratura che la decifratura. Questa soluzione realizza un throughput di 3,238 Gbps alla frequenza di 25.3 MHz. Saggese et al. [28] propone un’architettura a 128 bit per la sola cifratura. Egli compara una struttura completamente srotolata e pipelinata a fondo rispetto ad una iterativa con il minimo ingombro. I modi di funzionamento sono indirizzati all’utilizzo in flussi dati multipli al fine di riempire completamente la struttura pipelinata. Viene implementata una schedulazione al volo della chiave e le S-Box sono implementate in blocchi di RAM. Il circuito che realizza il MixColumns è realizzato attraverso una rete di XOR. L’approccio iterativo senza pipelining ha un data rate di un 1 Gbps ad una frequenza di clock di 79 MHz. L’implementazione più veloce ha cinque livelli di pipelining per round ed è completamente srotolata. Il throughput di 20.3 Gbps alla frequenza di 158 MHz è realizzabile utilizzando 5.810 CLB e 100 blocchi di RAM. Nel 2004, Hodjat [13] ha presentato un’architettura a 128 bit completamente srotolata e con quattro livelli di pipelining per round. L’operazione di SubBytes è realizzata attraverso l’implementazione di operazioni nel GF(24 ) che utilizzano tre livelli di pipelining. Vengo utilizzati quattro moltiplicatori MixColumns per ciascun round realizzati attraverso una rete di XOR. La schedulazione della chiave non è presa in considerazione in questo articolo. Il massimo throughput è di 21,54 Gbps, alla frequenza di clock di 168 MHz, può essere ottenuto nelle sole modalità che non prevedono feedback. Le risorse necessarie sono 12.450 CLB e nessun blocco RAM. Altre interessanti pubblicazioni sull’implementazione dell’AES su FPGA possono essere trovate in [27, 30, 32, 36, 37]. Pubblicazioni riguardanti implementazioni ad alta velocità su tecnologia CMOS sono rare. La prima pubblicazione è di Verbauwhede [31] e risale al 2003, si tratta di un’implementazione a 128 bit. L’architettura proposta prevede la sola cifratura e non ha una dimensione del blocco dati fissa come prevede l’AES, ma implementa l’algoritmo Rijndael con una dimensione della chiave e del blocco dati di 128, 192 e 256 bit. L’architettura è completamente parallela senza pipelining e richiede un ciclo di clock per round. L’architettura prevede 32 S-Box per l’unità cifrante e 16 S-Box per la schedulazione della chiave sviluppate in accordo con lo standard AES [21]. L’operazione di MixColumns è realizzata con una rete di XOR e istanziata quattro volte per ciascuna colonna. La schedulazione della chiave avviene al volo e supporta tutte le dimensioni della chiave. L’implementazione è stata fatta con 63 5 – AES: Stato dell’arte nell’implementazione celle standard CMOS a 0,18 µm che permette di ottenere una frequenza massima di clock pari a 154 MHz alla tensione di alimentazione di 1.8 V. Per la dimensione del blocco dati di 128 bit il throughput è di 1.6 Gbps mentre l’occupazione del chip è di 3.96 mm2 comparato a 173K porte logiche. Gli stessi autori descrivono in [12] una nuova versione dell’architettura che è di tipo cifrante, iterativa e senza pipelining. Quest’ultima implementazione realizza un throughput di 3.83 Gbps utilizzando un’area di 0.79 mm2 sempre sulla tecnologia CMOS a celle standard di 0,18 µm. Nell’articolo di Hodjat [14] è presentata la più veloce architettura esistente per l’AES, essa è in grado di realizzare un throughput fino a 70 Gbps. L’applicazione di questo core AES è rivolta alla reti ottiche in cui la cifratura del flusso dati utilizza la modalità CTR. Sono presentate differenti idee tra cui la generazione al volo della chiave e la pre-computazione della chiave per tutti i round. L’architettura prevede lo srotolamento completo dell’algoritmo e l’inserimento di quattro livelli di pipelining per ciascun round. Le 32 S-Box per round hanno tre livelli di pipelining e sono realizzate implementando operazioni in capo finito [35]. Quattro moltiplicatori MixColumns sono utilizzati per round e sono implementati attraverso una catena di XOR. Il massimo data rate ottenuto è di 68 Gbps con un’area di 250 K porte logiche su di una tecnologi CMOS a celle standard di 0,18 µm. 5.2.3 Dettagli implementativi Le possibili implementazioni dell’AES con requisiti di alta velocità sono numerose; in accordo con quanto scritto precedentemente si considerano due implementazioni ad alta velocità. La prima implementazione può essere utilizzata sia per le modalità che richiedono un feed-back sia per quelle che non lo richiedono, utilizza un metodo iterativo per cifrare e decifrare i dati ed è sviluppata per essere pienamente compatibile con la tecnologia a celle standard. La seconda implementazione analizzata ha un’architettura che prevede il completo srotolamento dell’algoritmo per ricercare il massimo delle prestazioni nelle modalità operative che non richiedono il feed-back dei dati; il target tecnologico per questa implementazione è l’FPGA. Entrambe le architetture sono designate per l’AES128 ovvero per una dimensione della chiave di cifratura di 128 bit. Architettura AES per la cifratura e decifratura iterativa Le applicazioni target per il modulo AES ad alta velocità implementato su celle standard sono per esempio le applicazioni IPsec nelle produzioni di serie come i router. L’analisi dei requisiti dei differenti protocolli internet ha condotto ad un’architettura che fosse un compromesso fra il throughput e le dimensioni del die. Il supporto a tutte le modalità operative (con e senza feed-back) è stato l’obbiettivo principale 64 5.2 – Architetture ottimizzate per il throughput durante lo sviluppo dell’architettura mentre il supporto di più flussi di dati indipendenti è di secondaria importanza. Mentre altre implementazioni supportano la cifratura, l’architettura analizzata supporta anche la decifratura e la schedulazione al volo della chiave di codifica. Il massimo throughput è ottenuto quando l’ampiezza dei dati elaborati e massima ovvero quando vengono elaborano in parallelo 128 bit. L’approccio iterativo permette la computazione di un round AES per ogni ciclo di clock. Questo porta alla massima riutilizzazione dell’hardware mentre l’utilizzo delle risorse, confrontato all’architettura completamente srotolata, è relativamente basso. Le architetture dell’unità dati e dell’unità per la schedulazione della chiave sono rispettivamente presentate in figura 5.5 e 5.6. Qui di seguito vengono analizzate nel dettaglio le due unità. 128 enc 16xSBox ShiftRows InvShiftRows 1 enc 0 enc 4xMixCol 128 data_in 128 subkey en enc Reg Data Unit 128 data_out Figura 5.5. Unità dati con parallelismo a 128 bit per l’AES128 Unità dati L’unità dati del modulo AES contiene la logica combinatoria necessaria al calcolo delle operazioni di SubBytes, ShiftRows, MixColumns, AddRoundKey 65 5 – AES: Stato dell’arte nell’implementazione 128 32 32 1 0 32 32 enc RotWord 0 1 0 1 enc enc 0 1 enc 4xSBox Rcon 128 128 key en Reg Key Unit 128 subkey Figura 5.6. Unità di schedulazione della chiave con parallelismo a 128 per l’AES128 e le relative operazioni inverse. La figura 5.5 mostra le interconnessioni fra i diversi moduli del circuito che permetto il calcolo di un round AES in un singolo ciclo di clock. L’operazione di SubBytes opera indipendentemente su ciascun byte dello Stato utilizzando una tabella per le sostituzioni S-Box; sono necessarie sedici istanze del circuito che realizza la S-Box per poter operare contemporaneamente sullo Stato. Ciascuna S-Box, figura 5.7, è realizzata sfruttando le proprietà delle operazioni nei campi finiti in accordo con Wolkerstorfer [35]. Per la cifratura è utilizza la combinazione dell’inversione nel campo finito GF(28 ) e della trasformazione affine. La decifratura lavora in maniera analoga ma la trasformazione affine è fatta prima dell’inversione. Nell’architettura a 128 bit le operazioni di ShiftRows e InvShiftRows sono delle semplici ricablature del bus in cui un multiplexer seleziona se effettuare lo shift verso sinistra per la cifratura o verso destra per la decifratura. Allo stesso modo la sequenza delle operazioni di AddRoundKey e MixColumns è scambiata durante la cifratura e la decifratura, l’operazione di XOR con la chiave avviene per la decifratura dopo l’operazione di InvShiftRows mentre per la cifratura è l’ultima operazione da 66 5.2 – Architetture ottimizzate per il throughput effettuare. Un multiplexer è utilizzato per selezionare l’uscita del MixColumns, o per il bypass di quest’ultimo, o per leggere lo Stato in ingresso. Le operazioni di MixColumns e InvMixColumns sono implementate attraverso quattro moltiplicatori ciascuno dei quali opera su una singola colonna dello Stato. L’implementazione dei moltiplicatori è basata sul lavoro di Wolkerstorfer [34] con l’introduzione di alcuni miglioramenti che permettono la riutilizzazione dei termini comuni. Unità per la schedulazione della chiave Questa unità esegue l’algoritmo per la schedulazione della chiave e per ogni ciclo di clock è in grado di trasmettere all’unità dati la chiave di round. Durante la decifratura è possibile fornire l’ultima chiave oppure quest’ultima può essere calcolata a partire dalla chiave di cifratura in una fase di inizializzazione che dura dieci cicli di clock (AES128). In ciascun passo di espansione della chiave sulla prima parola (32 bit) della chiave viene effettuata inizialmente un’operazione di shift ciclico e successivamente applicata l’operazione di SubBytes. Perciò sono necessarie quattro istanze del modulo S-Box. La costante Rcon è inoltre aggiunta all’uscita del modulo S-Box tramite un’operazione di XOR. Questo risultato è combinato con l’ultima parola della chiave precedente tramite un’operazione di XOR. Le altre tre parole della chiave sono calcolate a partire dai valori della chiave precedente e un’operazione di XOR in accordo con l’algoritmo di espansione. La parola da porre in XOR è selezionata tramite un’opportuno multiplexer. Architettura AES completamente srotolata Per applicazioni in backend router o in server in cui più flussi dati devono essere cifrati simultaneamente è necessario un data rate dell’ordine dei Giga bit. A causa del basso numero di unità prodotte è l’FPGA la tecnologia target per l’implementazione. Il massimo throughput per la cifratura AES è ottenuto srotolando completamente tutti e dieci (AES128) i round dell’algoritmo e inserendo dei registri di pipelining tra un round e l’altro come mostrato in figura 5.8. A causa dello srotolamento dei round dell’algoritmo, solamente i modi che non prevedono un feed-back dei dati, come la modalità CTR o ECB, ottengono dei vantaggi dall’utilizzo di questo tipo di architettura. La decisione di implementare solamente il modulo cifrante, e non quello decifrante, è nata dal fatto che nella modalità CTR la decifratura è fatta con lo stesso modulo cifrante. L’architettura proposta in figura 5.8 è composta da un round iniziale in cui si effettua l’operazione di XOR fra la chiave di cifratura e i dati in ingresso seguito da nove istanze del round di trasformazione. A seguire vi è l’ultima istanza del round di trasformazione che, in accordo con l’algoritmo AES, non include il moltiplicatore MixColumns. Come conseguenza dell’implementazione in FPGA del circuito le S-Box 67 5 – AES: Stato dell’arte nell’implementazione data_in 8 inverse affine transformation 1 0 GF(28) inversion enc affine transformation 1 0 S-Box 8 data_out Figura 5.7. Circuito S-Box implementato con operazioni nel campo finito GF(28 ) vengono realizzate come lookup table in dedicati blocchi di RAM. L’operazione di ShiftRows è, come in precedenza già visto, delle semplici ricablature del bus in uscita dalla S-Box e l’ingresso del circuito successivo. L’architettura del moltiplicatore MixColumns è la stessa già presentata in precedenza ma implementata in LUT. Le dieci differenti chiavi di round sono generate in anticipo e memorizzate all’interno dell’FPGA in blocchi di RAM. 5.2.4 Caratteristiche delle implementazioni A causa del diverso target tecnologico per l’implementazione, FPGA o celle standard, non è possibile un confronto diretto per l’occupazione di risorse che nel caso dell’FPGA è misurato in LUT e blocchi di RAM mentre nel caso delle celle standard in gate equivalenti. Qui di seguito le architetture precedentemente esposte sono confrontate con altre analoghe. 68 5.2 – Architetture ottimizzate per il throughput data_in input 128 key 128 128 Initial round key 128 Initial round data_in Reg 128 128 data_out subkey 1 128 Round 1 16xSBox Reg ShiftRows data_in 4xMixCol 128 subkey 9 128 Round 9 16xSBox Reg ShiftRows Round 10 subkey 10 128 128 Round 10 Round 1-9 128 subkey 128 data_out subkey Reg 128 128 data_out output Figura 5.8. Unità dati completamente srotolata per l’AES128 Approccio basato su celle standard La stima dell’area del chip per l’architettura iterativa implementata su celle standard e mostrata in tabella 5.2. La stima è basata sui risultati della sintesi delle singole parti che formano il circuito. L’area occupata dal chip sia per l’unità dati che per l’unità di schedulazione della chiave è di circa 20.000 porte equivalenti. Come paragone si è presa la soluzione presentata da Hodjat [35] che è anch’essa di tipo iterativo, include l’hardware per l’esecuzione di differenti modi operativi ma non è in grado di eseguire da decifratura. Questa soluzione occupa 34.300 porte equivalenti ed ha un throughput maggiore poiché utilizza una tecnologia CMOS a 0.18 µm anziché quella a 0.35 µm della Austriamicrosystem. 69 5 – AES: Stato dell’arte nell’implementazione S-BOX MixColumns Flip flops Multiplexer XOR misc. AES Iretativo Hodjat [12] Area/Instance [GEs] 473 582 6 3 3 1 #Instance 20 4 256 512 384 4.000 TOTAL Area [GEs] 9.460 2.328 1.536 1.536 1.152 4.000 ≈ 20.000 34.300 Tabella 5.2. Stima dell’area occupata per l’architettura AES iterativa Approccio basato su FPGA L’architettura di un’implementazione AES determina fortemente il requisito delle risorse hardware necessarie. Tuttavia sia il software di sintesi che il modello di FPGA utilizzati possono influenzare il requisito hardware necessario. In tabella 5.3 è mostrata una veduta generale delle soluzioni esistenti basate su FPGA. A causa delle differenti FPGA utilizzate, nella maggior parte della XILINX, i valori riportati devono essere visti come un confronto relativo fra la stima delle risorse occupate e del throughput. 70 5.2 – Architetture ottimizzate per il throughput Authors Chodowiec [7] Chodowiec [8] Chodowiec [8] Chodowiec [8] Hodjat [13] Hodjat [13] McLoone [20] Pramstaller [26] Rouvroy [27] Saggese [28] Saggese [28] Saggese [28] Saggese [28] Standaert [30] Standaert [30] Wang [32] Zambreno [36] Zambreno [36] Zambreno [36] Zambreno [36] Zambreno [36] Zhang [37] Zhang [37] LUTs 222 12.600 2.057 2.507 9.446 5.177 2.222 1.125 146 446 648 2.778 5.810 1.769 15.112 1.857 387 1.254 2.206 3.766 16.938 9.406 11.022 Block RAMs 3 80 8 0 0 84 100 0 3 10 10 100 100 0 0 0 10 20 50 100 0 0 0 Throughput [Gbps] 0,166 12,16 1,265 0,414 21,64 21,54 7,0 0,215 0,358 1,0 1,82 8,9 20,3 2,085 18,560 1,604 1,41 4,44 10,88 22,93 23,57 11,965 21,556 Tabella 5.3. Stima delle risorse e delle performance per diverse soluzioni basate si FPGA 71 5 – AES: Stato dell’arte nell’implementazione 72 Capitolo 6 Implementazione dell’AES128 In questo capitolo sono descritte le scelte progettuali fatte per l’implementazione del core AES128. Tali scelte sono rivolte alla realizzazione di un core AES altamente prestante in termini di throughput dei dati; valgono quindi tutte le considerazioni fatte nel capitolo 5. Le funzionalità di cifratura e di decifratura, per garantire il massimo delle prestazioni, vengono realizzate in due entity separate denominate rispettivamente aes128 enc e aes128 dec1 . Sono state realizzate e analizzate due architetture differenti: la prima di tipo iterativo 6.1(a) mentre la seconda di tipo fully unrolled 6.1(b). Entrambe le architetture hanno un parallelismo a 128 bit e sono realizzate con differenti livelli di sub-pipeline (fino a due livelli); tale tecnica, come visto nel capitolo 4.5.1, permette di incrementare in maniera considerevole le prestazioni a fronte di un piccolo incremento delle risorse richieste. In figura 6.2 sono rappresentate rispettivamente le entity del core AES128 per l’architettura iterativa e per l’architettura fully unrolled. Le entity si differenziano per la presenza o meno dei segnali di controllo start e end conv. Questi ultimi sono presenti nell’architettura iterativa perché necessari al controllo della macchina a stati finiti che governa il funzionamento del core, mentre sono assenti nell’architettura fully unrolled poiché quest’architettura non necessita per il suo funzionamento di una macchina a stati finiti. 6.1 Architettura iterativa L’architettura del core AES128 iterativo è essenzialmente composta da tre moduli come mostrato in figura 6.3: il primo modulo è la macchina a stati finiti (fsm) che governa il funzionamento del core, il secondo è il roundData che esegue un round 1 I nomi sopracitati si riferiscono rispettivamente al prefisso del nome dell’entity che realizza il core AES128 per la codifica (encode) e per la decodifica (decode). Inoltre i suffissi “ enc” e “ dec” identificano tutti quelle entity sviluppate per le funzioni di codifica e decodifica. 73 6 – Implementazione dell’AES128 Register Multiplexer Register Round 1 Round Register Round 2 Register Round 10 (a) (b) Figura 6.1. AES128: (a) architettura iterativa, (b) architettura fully unrolled aes128 aes128 start end_conv clk clk_en rst_n key in_txt clk clk_en rst_n key in_txt out_txt out_txt (b) (a) Figura 6.2. Entity del core AES128: (a) architettura iterativa, (b) architettura fully unrolled di trasformazione della parola, il terzo modulo è il roundKey che esegue un round di schedulazione della chiave di cifratura. Oltra a questi moduli sono presenti tre multiplexer che permettono come visto nel capitolo 4.5.1 l’iterazione dell’algoritmo e un sommatore (XOR) per eseguire il primo passo dell’algoritmo AES ovvero la somma fra la parola da cifrare e la chiave di cifratura. Nella figura 6.4 è rappresentata una simulazione dell’utilizzo del core AES128 iterativo fatta grazie al tool “ModelSim SE PLUS 6.2c” della Mentor Graphics Corporation. Il suo utilizzo è molto semplice e per il suo funzionamento si avvale di due soli segnali di controllo: un segnale di start (start) e un segnale di fine elaborazione (end conv). Se il segnale di fine elaborazione è a livello logico alto il 74 6.1 – Architettura iterativa key in_txt 1 0 1 roundKey clk clk_en rst_n fsm rst_n clk clk_en rst_n start start clk clk_en lst_round load end_conv end_conv key_in rc_in enable 1 0 roundData clk clk_en rst_n key_out rc_out round_key txt_in lst_round txt_out out_txt 0 INITVALUE_ENC Figura 6.3. Architecture iterativa del core AES128 core AES128 è pronto per eseguire una nuova cifratura che inizia quando il segnale di start, per un ciclo di clock, assume il livello logico alto. Durante ques’ultimo evento vengono lette la parola da cifrare attraverso il bus in txt e la chiave di cifratura sul bus key. Il core AES risponderà dell’avvenuta cifratura ponendo a livello logico alto il segnale di fine conversione e contemporaneamente sul bus out txt la parola cifrata. Questa procedura si riferisce alla cifratura di una singola parola; nel caso in cui si debba cifrare un flusso di dati è possibile mantenere a livello logico alto il segnale di start e sincronizzare l’immissione di nuove parole e chiavi di cifratura con il segnale di fine conversione che rimarrà alto per un ciclo di clock. Infine, oltre al segnale di clock (clk) e di reset (rst n), attivo a livello logico basso, è presente un segnale di enable (clk en) che permette di bloccare il funzionamento del core AES128. Il tempo necessario per l’elaborazione dei dati è comunque determinato a priori e dipende dal numero di livelli di sub-pipeline implementati. 6.1.1 Macchina a stati finiti (fsm) La macchina a stati finiti si preoccupa di generare tutti i segnali di controllo del core AES128 iterativo. I segnali pilotati da questo modulo sono quattro: • load • enable • end conv 75 6 – Implementazione dell’AES128 clk clk_en rst_n start key in_txt {00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F} {XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX} {00 11 22 33 44 55 66 77 88 99 AA BB CC DD EE FF} {XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX} end_conv out_txt {69 C4 E0 D8 6A 7B 04 30 D8 CD B7 80 70 B4 C5 5A} {00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00} /tb/aes/load Figura 6.4. Simulazione del core AES128 • lst round Il segnale load viene posto a livello logico alto all’inizio di ogni processo di cifratura ed è utilizzato per pilotare i tre multiplexer. Due di questi multiplexer servono il modulo roundKey mentre il terzo serve il modulo roundData. I primi due permettono di caricare all’interno del modulo roundKey la chiave di cifratura key e la costante INITVALUE ENC (Rcoin[0], capitolo 4.3.5). Il terzo multiplexer permette invece di caricare all’interno del modulo roundData la parola da cifrare. Il segnale enable assume il livello logico alto quando si stanno eseguendo le operazioni di cifratura sempre se il segnale di enable clk en è a livello logico alto. Questo segnale pilota tutti i registri interni al core AES128 e permette di congelare il funzionamento del core AES128 per ottimizzare il consumo energetico. Infatti, grazie a questo segnale, durante lo stato di fine conversione (end conv = ‘1’) il modulo non assorbe energia elettrica permettendo cosı̀ un risparmio energetico non indifferente. Il segnale di fine conversione end conv come precedentemente descritto assume il livello logico alto alla fine di ogni ciclo di cifratura. Anche il segnale lst round assume il livello logico alto durante l’ultimo round di cifratura e permette di pilotare il multiplexer interno all’architecture del modulo roundData. L’architecture di questo modulo è stata sviluppata descrivendo in codice VHDL una macchina a stati finiti basata su quattro stati. Lo macchina a stati è sempre nello stato di attesa idle fin tanto che il segnale di start non assume il livello logico uno. Nel codice VHDL è stato descritto in maniera behavioral un contatore che tiene traccia del round in corso e che permette di determinare la fine dell’elaborazione dei dati. Nell’entity di questo modulo è presente la dichiarazione della variabile generic NN che permette di parametrizzare la profondità di conteggio del contatore. Questa variabile permette un’uso versatile di questo modulo, come si vedrà successivamente, in presenza di registri di sub-pipelining all’interno dell’architettura. 0 20 40 60 80 100 76 120 Entity:tb Architecture:beh Date: Fri May 11 11.59.48 ora solare Europa occidentale 2007 Row: 1 Page: 1 140 160 180 200 6.2 – Architettura fully unrolled 6.2 Architettura fully unrolled L’architettura del core AES128 fully unrolled è presentata in figura 6.5. Rispetto alla struttura iterativa non necessita dei multiplexer necessari per realizzare l’iterazione e della macchina a stati finiti fsm. in_txt key roundKey roundData_mr clk clk_en rst_n INITVALUE_ENC clk clk_en rst_n key_in rc_in key_out rc_out round_key txt_in roundKey roundData_mr clk clk_en rst_n clk clk_en rst_n key_in rc_in key_out rc_out round_key txt_in ... roundKey roundData_mr clk clk_en rst_n round_key txt_in key_out rc_out roundKey_lr txt_out roundData_lr clk clk_en rst_n key_in rc_in txt_out ... clk clk_en rst_n key_in rc_in txt_out clk clk_en rst_n key_out round_key txt_in txt_out out_txt Figura 6.5. Architecture fully unrolled del core AES128 La struttura di elaborazione dei dati pone in cascata per dieci volte i moduli di trasformazione della parola da cifrare (roundData) e di schedulazione della chiave (roundKey). L’architettura prevede che l’uscita di ciascun modulo è posta in ingresso al modulo successivo. In accordo con l’algoritmo AES l’ultimo round di trasformazione (roundData lr) differisce dai precedenti (roundData mr) per l’assenza della moltiplicazione di colonna mixColumns. Anche l’ultimo round di schedulazione della chiave (roundKey lr) differisce dai precedenti (roundKey) per l’assenza della logica di elaborazione della costante di round Rcoin[i]. 77 6 – Implementazione dell’AES128 6.3 Architetture per la cifratura dei dati (aes128 enc) In questo capitolo vengono descritte le architetture delle entity roundData enc e roundKey enc sviluppate per le funzionalità di cifratura del core AES128. 6.3.1 Entity roundData enc Questo modulo permette di eseguire un round dell’algoritmo AES128. La sua architettura è di tipo parallela a 128 bit e in un solo ciclo di clock è in grado di eseguire un passo dell’algoritmo. La sua architettura visibile in figura 6.6 è composta da un registro (reg state) a 128 bit necessario per la memorizzazione della parola da cifrare e da alcuni elementi di logica combinatoria: sBox enc, shiftRow enc, mixColumn enc, un multiplexer e un sommatore (XOR). L’architettura necessita sedici istanze del modulo che implementa la Sbox, denominato sBox enc, un’istanza per ogni byte dello Stato. Il modulo shiftRow enc esegue l’operazione di ShiftRows tramite un rewiring del bus a 128 bit. Ciascun dei quattro blocchi mixColumn enc esegue l’operazione di moltiplicazione di colonna che può essere bypassata, durante l’ultimo round, grazie all’utilizzo del multiplexer, comandato dal segnale lst round. Infine il sommatore permette di sommare la chiave di round. La Sbox, come visto nel capitoli precedenti, può essere implementata sia attraverso l’uso di logica combinatoria che attraverso l’uso di una memoria ROM contenete i 256 possibili valori della sostituzione. Nell’implementazione proposta la Sbox è stata realizzata tramite una descrizione VHDL che realizza una LUT (Look Up Table). Questa scelta si è resa necessaria per soddisfare il requisito di progetto che prevede la possibilità di poter cambiare a piacimento la Sbox per poter implementare una versione ad hoc dell’algoritmo AES. Inoltre, a favore di questa soluzione vi è il fatto che nel caso di implementazione in FPGA l’utilizzo della memoria ROM è vantaggioso in termini di area/performance ottenibili. Gli articoli in letteratura che propongono l’utilizzo della logica combinatoria confermano questo fatto, infatti, l’utilizzo di logica combinatoria introduce un lieve aumento delle prestazioni ma garantisce un risparmio in termini di risorse hardware necessarie (soprattutto di memorie necessarie). Le FPGA Virtex2 della XILINX munite di veloci memorie chiamate BlockRAM sono ideali per questo tipo di implementazione; tuttavia la scelta dell’implementazione della LUT in questo tipo di tecnologia viene lascia al tool di sintesi. In letteratura sono proposte differenti implementazioni del moltiplicatore MixColumns ma non tutte permettono di ottenere il massimo delle prestazioni ottimizzando le risorse hardware necessarie; si veda a titolo di esempio gli articoli [29], [38], [39] e [40]. La struttura proposta permette di ottenere, attraverso un’attenta condivisione 78 6.3 – Architetture per la cifratura dei dati (aes128 enc) TXT_IN 128 reg_state 128 8 8 8 sBox_enc 0 sBox_enc 1 sBox_enc 2 sBox_enc 15 ... 8 8 8 8 8 128 shiftRow_enc 128 32 32 mixColumn_enc 0 32 mixColumn_enc 1 mixColumn_enc 2 32 32 32 32 mixColumn_enc 3 32 128 lst_round 1 0 128 round_key 128 128 TXT_OUT Figura 6.6. Architecture dell’entity roundData enc delle operazioni fatte a livello di byte, un’implementazione efficiente del moltiplicatore di colonna. In particolare, l’operazione di MixColumns 6.1 può essere riscritta 79 6 – Implementazione dell’AES128 in forma 6.2 che risulta essere più appropriata per il nostro scopo. s00,c s01,c s02,c s03,c = s00,c s01,c s02,c s03,c = = = = 02 01 01 03 03 02 01 01 01 03 02 01 01 01 03 02 s0,c s1,c s2,c s3,c per 0 ≤ c < Nb {02} · (s0,c ⊕ s1,c ) ⊕ (s2,c ⊕ s3,c ) ⊕ s1,c {02} · (s1,c ⊕ s2,c ) ⊕ (s3,c ⊕ s0,c ) ⊕ s2,c {02} · (s2,c ⊕ s3,c ) ⊕ (s0,c ⊕ s1,c ) ⊕ s3,c {02} · (s3,c ⊕ s0,c ) ⊕ (s1,c ⊕ s2,c ) ⊕ s0,c (6.1) (6.2) Secondo la 6.2 l’operazione di MixColumns può essere implementata attraverso l’architettura proposta in figura 6.7. La funzione VHDL s xtime() è necessaria per il calcolo della moltiplicazione con la costante {02}. Gli elementi del GF(28 ) possono essere rappresentati nella seguente forma polinomiale: S = s7 x7 + s6 x6 + s5 x5 + s4 x4 + s3 x3 + s2 x2 + s1 x + s0 , dove s0 ,s1 , . . . ,s7 ∈ GF(2) e x è una radice del polinomio p(x). Quindi: {02}S = xS = = s7 x8 + s6 x7 + s5 x6 + s4 x5 + s3 x4 + s2 x3 + s1 x2 + s0 x1 mod p(x) = = s6 x7 + s5 x6 + s4 x5 + (s3 + s7 )x4 + (s2 + s7 )x3 + s1 x2 + (s0 + s7 )x + s7 (6.3) L’architettura della funzione s xtime() è visibile in figura 6.8 e può essere implementata attraverso l’uso di tre porte logiche XOR. Come illustrato in figura 6.7 il numero totale di porte logiche XOR necessarie al computo della moltiplicazione di colonna sono 108 e il critical path è di 3 porte logiche XOR. 6.3.2 Entity roundKey enc Questo modulo permette di eseguire un round di schedulazione della chiave di cifratura. La sua architettura è di tipo parallela a 128 bit e in un solo ciclo di clock è in grado di eseguire un passo dell’algoritmo di schedulazione della chiave. L’architecture dell’entity per la schedulazione della chiave, presentata in figura 6.8, necessita di due registri, reg byte e reg key128, rispettivamente per la memorizzazione della costante di round e della chiave di cifratura, quattro istanze della Sbox e di alcuni sommatori XOR. La generazione della chiave di round è fatta al volo, ovvero data la round key e la costante di round del passo precedente genera all’uscita la round key e la costante di round del passo attuale. La generazione al volo della chiave di round non introduce alcune penalità poiché nel caso dell’AES128 la dimensione della chiave di cifratura fissata a 128 bit permette di realizzare un modulo per la 80 6.3 – Architetture per la cifratura dei dati (aes128 enc) 8 32 MSB 8 8 c_in LSB 8 mixColun_1o2_enc s_xtime() s_xtime() 8 8 32 8 mixColun_2o2_enc 8 s_xtime() s_xtime() c_out Figura 6.7. Architecture dell’entity mixColumn enc schedulazione della chiave che ha un critical path bilanciato con quello del modulo roundData enc. Anche la generazione della costante di round RC è fatta al volo tramite l’utilizzo di tre porte logiche XOR. Questa scelta è particolarmente efficiente in quanto permette di risparmiare memoria ROM e le prestazioni sono ottimizzate. L’implementazione della Sbox è stata fatta con le stesse modalità viste nel capitolo precedente. 6.3.3 Inserimento dei registri di sub-pipeline Il tool di sintesi Synplify Pro 8.6.2 della Synplicity ha permesso di individuare il critical path delle entity precedentemente descritte. Questa caratteristica ha dato la possibilità di individuare nella struttura delle entity il punto migliore per inserire dei registri di sub-pipelining. Durante l’analisi del critical path, per una maggior accuratezza dell’analisi, la macchina a stati finiti fsm non è stata sintetizzata. Il posizionamento dei registri è avvenuto cercando di mantenere bilanciato il tempo di esecuzione della logica prima e dopo il registro. Sono state sviluppate due varianti dell’architettura, la prima che prevede un solo livello di sub-pipelining e una seconda con due livelli di sub-pipeline. Le architetture sono presentate rispettivamente in figura 6.9 e 6.10. Il critical path nel caso dell’architettura con due livelli di subpipelining è dato modulo che implementa la Sbox. 81 6 – Implementazione dell’AES128 RC_IN KEY_IN 128 128 reg_byte reg_key128 8 128 (31 downto 0) 32 128 MSB LSB 8 sBox_enc 0 8 sBox_enc 2 ... 8 8 32 MSB 8 LSB 8 8 8 32 MSB 8 LSB 8 8 8 32 s_xtime() MSB MSB LSB MSB 32 LSB 32 32 32 LSB 8 128 RC_OUT KEY_OUT Figura 6.8. Architecture dell’entity roundKey enc 6.4 Architetture per la decifratura dei dati (aes128 dec) In questo capitolo vengono descritte le architetture delle entity roundData dec e roundKey dec sviluppate per le funzionalità di decifratura del core AES128. 82 6.4 – Architetture per la decifratura dei dati (aes128 dec) RC_IN TXT_IN KEY_IN 128 128 128 reg_byte reg_state reg_key128 8 128 128 (127 downto 96) 8 8 8 8 32 128 MSB sBox_enc 0 sBox_enc 1 8 sBox_enc 2 sBox_enc 15 ... 8 8 LSB 8 8 8 sBox_enc 0 128 sBox_enc 2 ... 8 shiftRow_enc 8 32 MSB 8 128 LSB 8 8 8 32 reg_state reg_byte 128 reg_word 8 128 32 MSB 8 32 32 mixColumn_enc 0 32 mixColumn_enc 1 mixColumn_enc 2 32 32 32 reg_key128 LSB 8 8 8 32 mixColumn_enc 3 32 32 MSB 32 LSB 32 32 128 s_xtime() lst_round 1 0 128 128 128 8 TXT_OUT RC_OUT Figura 6.9. Architettura cifrante con un livello di sub-pipeline 83 128 KEY_OUT 32 6 – Implementazione dell’AES128 RC_IN TXT_IN KEY_IN 128 128 128 reg_byte reg_state reg_key128 8 128 128 (127 downto 96) 8 8 8 8 32 128 MSB sBox_enc 0 sBox_enc 1 8 sBox_enc 2 sBox_enc 15 ... 8 8 LSB 8 8 8 sBox_enc 0 sBox_enc 2 ... 8 128 8 32 MSB 8 LSB 8 8 8 32 reg_word reg_byte reg_state 128 8 128 32 MSB shiftRow_enc reg_key128 8 LSB 8 8 8 128 32 32 32 32 32 MSB 32 mixColumn_1o2_enc 0 mixColumn_1o2_enc 1 32 32 32 32 mixColumn_1o2_enc 2 32 32 s_xtime() 128 reg_state reg_state 128 128 32 128 128 reg_state 32 mixColumn_1o2_enc 3 32 32 LSB 32 reg_byte reg_key128 128 128 MSB 32 mixColumn_2o2_enc 0 32 32 32 32 mixColumn_2o2_enc 1 mixColumn_2o2_enc 2 32 32 32 32 LSB 32 32 32 32 mixColumn_2o2_enc 3 32 32 128 lst_round 1 0 128 128 128 8 RC_OUT TXT_OUT Figura 6.10. Architettura cifrante con due livelli di sub-pipeline 84 128 KEY_OUT 32 6.4 – Architetture per la decifratura dei dati (aes128 dec) 6.4.1 Entity roundData dec Questo modulo permette di eseguire un round dell’algoritmo di decifratura dello standard AES128. La sua architettura è di tipo parallela a 128 bit è in un solo ciclo di clock è in grado di eseguire un passo dell’algoritmo. La sua architettura è mostrata in figura 6.11 ed è composta da un registro (reg state) a 128 bit necessario per la memorizzazione della parola da decifrare e da alcuni elementi di logica combinatoria: shiftRow dec, sBox dec, un sommatore (XOR), mixColumn dec e un multiplexer. In analogia con l’entity roundData enc necessita di sedici istanze della Sbox, un’istanza per ogni byte dello Stato. Il modulo shifRow dec esegue l’operazione inversa dell’operazione di ShiftRows attraverso un rewiring del bus dati. Ciascuna delle quattro istanze del moltiplicatore di colonna mixColumn dec esegue l’operazione inversa di moltiplicazione di colonna che può essere bypassata attraverso l’uso del multiplexer pilotato dal segnale lst round. Infine il sommatore permette di sommare la chiave di round. Come già visto in precedenza in letteratura, sono proposte diverse implementazioni per il moltiplicatore MixColumns. Per l’implementazione del moltiplicatore inverso InvMixColumns vengono proposte diverse architetture che permettono la condivisione, almeno in parte, del moltiplicatore MixColumns per eseguire l’operazione inversa ma questo tipo di architetture non garantiscono il massimo delle performance. L’architettura sviluppata è stata sviluppata per minimizzare il tempo di elaborazione dell’operazione. La struttura proposta permette di ottenere, attraverso un’attenta condivisione delle operazioni fatte al livello di byte, un’implementazione efficiente del moltiplicatore inverso di colonna. In particolare, l’operazione di InvMixColumns 6.4 può essere riscritta in forma 6.5 che risulta essere più appropriata per il nostro scopo. s00,c s01,c s02,c s03,c = 0e 09 0d 0b 0b 0e 09 0d 0d 0b 0e 09 09 0d 0b 0e ³ s0,c s1,c s2,c s3,c per 0 ≤ c < Nb (6.4) ´ s00,c = {04} {02}(S0,c ⊕ S1,c ) ⊕ {02}(S2,c ⊕ S3,c ) ⊕ (S0,c ⊕ S2,c ) ⊕ ⊕{02}(S 0,c ⊕ S1,c ) ⊕ S1,c ⊕ (S2,c ⊕ S3,c ) ³ ´ 0 s1,c = {04} {02}(S1,c ⊕ S2,c ) ⊕ {02}(S3,c ⊕ S0,c ) ⊕ (S1,c ⊕ S3,c ) ⊕ ⊕{02}(S 1,c ⊕ S2,c ) ⊕ S2,c ⊕ (S3,c ⊕ S0,c ) ³ ´ 0 s2,c = {04} {02}(S2,c ⊕ S3,c ) ⊕ {02}(S0,c ⊕ S1,c ) ⊕ (S2,c ⊕ S0,c ) ⊕ ⊕{02}(S 2,c ⊕ S3,c ) ⊕ S3,c ⊕ (S0,c ⊕ S1,c ) ³ ´ 0 s3,c = {04} {02}(S3,c ⊕ S0,c ) ⊕ {02}(S1,c ⊕ S2,c ) ⊕ (S3,c ⊕ S1,c ) ⊕ ⊕{02}(S3,c ⊕ S0,c ) ⊕ S0,c ⊕ (S1,c ⊕ S2,c ) 85 (6.5) 6 – Implementazione dell’AES128 TXT_IN 128 reg_state 128 shiftRow_dec 128 8 sBox_dec 0 8 8 8 sBox_dec 1 8 sBox_dec 2 sBox_dec 15 ... 8 8 8 128 round_key 128 128 32 32 mixColumn_dec 0 32 mixColumn_dec 1 mixColumn_dec 2 32 32 32 32 mixColumn_dec 3 32 128 lst_round 1 0 128 TXT_OUT Figura 6.11. Architecture dell’entity roundData dec Secondo la 6.5 l’operazione di InvMixColumns può essere implementata attraverso l’architettura proposta in figura 6.12. Il numero totale di porte logiche XOR 86 6.4 – Architetture per la decifratura dei dati (aes128 dec) necessarie al computo della moltiplicazione di colonna sono 244 e il critical path è di 7 porte logiche XOR. Nell’articolo di Zhang et al. [40] è proposta un’architettura in grado di ridurre il critical path a 6 porte logiche XOR ma, da analisi fatte col tool di sintesi Synplify 8.6.2 della Synplicity, si è evidenziato il fatto che, nonostante la riduzione del critical path, la struttura non è più veloce di quella proposta. Inoltre l’architettura proposta ha il vantaggio di diminuire il numero di registri necessari per suddividere l’operazione in due stadi. 8 32 MSB 8 8 c_in s_xtime() mixColun_2o2_dec 8 LSB s_xtime() s_xtime() s_xtime() s_xtime() s_xtime() s_xtime() s_xtime() s_xtime() s_xtime() s_xtime() 8 8 8 mixColun_1o2_dec s_xtime() 8 32 c_out Figura 6.12. Architettura dell’entity mixColumn dec 6.4.2 Entity roundKey dec Questo modulo permette di eseguire un round di schedulazione inversa della chiave di cifratura. La schedulazione inversa della chiave di cifratura è fatta al volo e permette di ottenere la chiave del round n a partire dalla chiave del round n + 1. Dunque è necessario disporre, prima di iniziare con l’operazione di decodifica, dell’ultima chiave di round. Come visto nel capitolo 4, l’ultima chiave di round può essere ottenuta solamente eseguendo una schedulazione completa dalla chive di cifratura; questa operazione può essere fatta sviluppando un modulo esterno che sfrutti l’architettura, precedentemente descritta, dell’entity roundKey enc. L’architettura mostrata in figura 6.13 necessita di due registri reg byte e reg key128, rispettivamente per la memorizzazione della costante di round e della chiave di cifratura, quattro istanze della Sbox sBox enc e di alcuni sommatori XOR. La generazione al 87 6 – Implementazione dell’AES128 volo della chiave di round e della costante RC non introduce alcuna penalità perché, anche in questo caso, l’architettura risulta bilanciata con il modulo roundData dec. L’implementazione della Sbox segue le linee guida già precedentemente descritte. RC_IN KEY_IN 128 128 reg_byte reg_key128 8 128 MSB LSB 32 32 32 32 MSB LSB 8 sBox_enc 0 8 sBox_enc 2 ... 8 8 32 MSB 8 LSB 8 8 8 32 MSB 8 LSB 8 8 8 s_inv_xtime() MSB LSB MSB LSB 128 8 RC_OUT KEY_OUT Figura 6.13. Architecture dell’entity roundKey dec 6.4.3 Inserimento dei registri di sub-pipeline Il tool di sintesi Synplify Pro 8.6.2 della Synplicity ha permesso di individuare il critical path delle entity precedentemente descritte. Questa caratteristica ha dato la possibilità di individuare nella struttura delle entity il punto migliore per inserire dei registri di sub-pipelining. Durante l’analisi del critical path, per una maggior accuratezza dell’analisi, la macchina a stati finiti fsm non è stata sintetizzata. Il 88 6.4 – Architetture per la decifratura dei dati (aes128 dec) posizionamento dei registri è avvenuto cercando di mantenere bilanciato il tempo di esecuzione della logica prima e dopo il registro. Sono state sviluppate due varianti dell’architettura, la prima che prevede un solo livello di sub-pipelining e una seconda con due livelli di sub-pipeline. Le architetture sono presentate rispettivamente in figura 6.14 e 6.15. TXT_IN RC_IN 128 KEY_IN 128 reg_state 128 reg_byte 128 reg_key128 8 128 MSB 8 8 8 32 sBox_dec 0 8 sBox_dec 1 sBox_dec 2 32 32 32 sBox_dec 15 ... 128 8 8 LSB 8 8 MSB LSB 8 8 128 sBox_enc 0 shiftRow_dec sBox_enc 2 ... 8 8 128 32 MSB 8 LSB 8 8 8 reg_state 128 32 MSB 8 128 128 s_inv_xtime() 32 32 mixColumn_dec 0 32 mixColumn_dec 1 mixColumn_dec 2 32 32 32 32 mixColumn_dec 3 32 128 8 lst_round 1 128 0 reg_byte reg_key128 128 8 TXT_OUT RC_OUT 128 KEY_OUT Figura 6.14. Architettura decifrante con un livello di sub-pipeline 89 LSB 8 8 8 6 – Implementazione dell’AES128 TXT_IN RC_IN 128 KEY_IN 128 reg_state 128 reg_byte 128 reg_key128 8 128 MSB 8 8 8 LSB 8 32 sBox_dec 0 sBox_dec 1 8 sBox_dec 2 32 32 sBox_dec 15 ... 128 8 8 32 8 MSB LSB 8 8 128 sBox_enc 0 shiftRow_dec sBox_enc 2 ... 8 8 128 128 reg_state reg_byte 32 reg_word reg_key128 8 128 32 MSB LSB 128 8 8 8 8 128 32 MSB 128 8 32 32 32 32 MSB mixColumn_1o2_dec 0 mixColumn_1o2_dec 1 32 32 32 32 mixColumn_1o2_dec 2 32 32 reg_state reg_byte 8 128 32 32 32 32 mixColumn_2o2_dec 0 mixColumn_2o2_dec 2 32 32 32 32 mixColumn_2o2_dec 1 32 LSB 32 32 32 s_inv_xtime() 8 reg_state 128 128 32 32 32 128 128 reg_state mixColumn_1o2_dec 3 128 reg_key128 128 32 32 mixColumn_2o2_dec 3 32 128 lst_round 1 0 128 TXT_OUT RC_OUT KEY_OUT Figura 6.15. Architettura decifrante con due livelli di sub-pipeline 90 LSB 8 8 8 6.5 – Sintesi del core crittografico AES128 6.5 Sintesi del core crittografico AES128 La sintesi del core crittografico AES128 è stata fatta tramite il tool Synplify Pro 8.6.2 della Synplicity sull’FPGA XILINX XC2V4000. La serie XC2V4000 è un’FPGA di medie dimensione della famiglia Virtex2, contiene 5760 CLB (equivalenti a 23.040 slice) e 120 moduli di Block SelectRAM. Le impostazioni del tool di sintesi sono riassunte in tabella 6.1. PARAMETRO FPGA Fan out guide Disable I/O insertion Pipelining Update Compile Point Timing Data Verification Mode Modular Design Enable Retiming Disable Sequential Optimization Fix Gated Clock FSM Compiler FSM Explorer Frequency VALORE Xilinx, Virtex2, XC2V4000BF957-6 10.000 false true false false true true true/false 0 true true 500 MHz Tabella 6.1. Impostazioni del tool di sintesi: Synplify Pro Tra le caratteristiche del tool di sintesi utilizzato vi è la possibilità di eseguire le cosiddette “ottimizzazioni sequenziali” (Disable Sequential Optimization). Durante il processo di sintesi questa funzionalità è stata dapprima disabilitata per poi essere successivamente abilitata. Con l’abilitazione delle “ottimizzazioni sequenziali” il tool di sintesi ha utilizzato parte dei Block SelectRAM integrati nell’FPGA. Come si vedrà in seguito l’utilizzo di queste ottimizzazioni permette un’utilizzo più razionale delle risorse dell’FPGA. L’esecuzione del software di sintesi permette inoltre di verificare la sintetizzabilità del codice VHDL sviluppato. L’esame del report del processo di sintesi, è a garanzia del corretto funzionamento del core crittografico una volta implementato in FPGA. Il report di sintesi, per l’implementazione del core crittografico senza le ottimizzazioni sequenziali, è privo di errori e/o warning. Di particolare interesse vi sono due gruppi di annotazioni del report; la prima riguarda riguarda la sintesi dell’entity che realizza la Sbox (sbox enc e sbox dec) mentre la seconda riguarda l’entity fsm che realizza la macchina a stati finiti. Il sintetizzatore avverte, nel primo caso, dell’implementazione 91 6 – Implementazione dell’AES128 della Sbox attraverso l’utilizzo di memoria ROM dedicata. Questa possibilità era già stata ipotizzata in precedenza e permette di garantire il massimo delle performance al nostro circuito. Nel secondo caso, il sintetizzatore avverte dell’utilizzo della codifica sequenziale per l’enumerazione degli stati della macchina a stati. Anche questa scelta era abbastanza prevedibile visto che gli stati della macchina a stati finiti sono quattro. Il report di sintesi, con attivata la funzionalità di ottimizzazione sequenziale, è privo anch’esso di errori ma presenta alcuni warning in cui segnala l’eliminazione di alcuni registri a seguito delle ottimizzazioni effettuate. Infine, come già precedentemente detto, notifica che a seguito delle ottimizzazioni sequenziali l’implementazione delle Sbox (o di alcune di esse) nella memoria Block SelectRAM integrata nell’FPGA. Utilizzando il software di sintesi è stato possibile stimare la massima frequenza di clock (fclk ), il numero di LUT utilizzate e il numero di blocchi di RAM utilizzati. A partire dalla frequenza di clock stimata è possibile calcolare il massimo throughput e la latenza del core crittografico utilizzando le formule 5.3 e 5.4 presentate nel capitolo 5.2. L’architettura presentata ha una dimensione del blocco (Block size) di 128 bit. Il numero di round necessari al calcolo di un blocco dati (#Round per block) è pari a 10 per l’architettura iterativa e pari a 1 per l’architettura fully unrolled. Il numero di stadi di pipelining (#P ipeline stage) cosı̀ come il numero di stadi di pipelining utilizzati in parallelo (#U tilized stages) è uguale a n per l’architettura iterativa e pari a 10 · n per quella fully unrolled ; dove n è il numero di inner-round stage. Successivamente al processo di sintesi è stato eseguito un mapping con il tool ISE 9.1i della Xilinx. Quest’ultima procedura ha permesso di conteggiare le risorse hardware necessarie con maggior accuratezza. In particolare è stato di fondamentale importanza per il calcolo del numero di slice impiegate dall’FPGA per implementazione il core AES128. Architettura iterativa Le performance del core crittografico per la cifratura (Encoder AES128 UF1) e per la decifratura (Decoder AES128 UF1) con architettura iterativa sono riassunte nelle tabelle 6.2, 6.3, 6.4 e 6.5. Nelle tabelle sono riportate le performance del core crittografico per tre differenti livelli di sub-pipeline. Il valore ‘0’ si riferisce alla presenza del solo registro di pipeline all’inizio del round, i valori ‘1’ e ‘2’ invece si riferisce alla presenza, rispettivamente, di uno o due registri di sub-pipeline interni al round. Le tabelle 6.2 e 6.4 riassumono le performance del core crittografico sintetizzato senza abilitare la funzionalità di ottimizzazione sequenziale, mentre le tabelle 6.3 e 6.5 mostrano il risultato di sintesi con la funzionalità attivata. 92 6.5 – Sintesi del core crittografico AES128 Encoder AES128 UF1 (liv. sub-pipeline) 0 1 2 LUTs Slices 3.756 3.440 3.519 1.986 1.840 1.994 Block RAMs - Frequency [MHz] 173,6 226,0 220,2 Throughput [Gbps] 2,22 2,89 2,82 Latency [ns] 57,6 44,2 45,0 Tabella 6.2. Performance dell’encoder crittografico AES128 con architettura iterativa (Disable Sequential Optimization) Encoder AES128 UF1 (liv. sub-pipeline) 0 1 2 LUTs Slices 3.750 1.590 905 2.000 1.122 1.057 Block RAMs 8 10 Frequency [MHz] 175,0 187,7 208,0 Throughput [Gbps] 2,24 2,40 2,66 Latency [ns] 57,1 53,2 48,0 Tabella 6.3. Performance dell’encoder crittografico AES128 con architettura iterativa (Enable Sequential Optimization) Come studiato nel capitolo 4.5.1 l’inserimento dei registri di sub-pipeline permettono l’incremento delle prestazioni. In tabella 6.2 è mostrato, invece, come l’architettura con due livelli di sub-pipeline perda in prestazioni rispetto a quella con un solo livello di sub-pipeline. Questo è dovuto al fatto che l’analisi del critical path è stata fatta senza l’inserimento della macchina a stati finiti (fsm) che introduce un cospicuo calo delle performance. Le stesse architetture senza la fsm hanno un critical path che permetterebbe una frequenza di lavoro di circa 100 MHz maggiore. In questo particolare caso è da preferire l’utilizzo dell’architettura con un solo livello di sub-pipeline e quindi scartare quella con due livelli. Nelle tabelle 6.3 e 6.5 è possibile notare come l’utilizzo della memoria RAM integrata nell’FPGA ha permesso una drastica riduzione del numero di LUT o Slice necessarie all’implementazione dell’architettura. Nel caso della sintesi del core Encoder AES128 UF1 PP1 il tool di sintesi utilizza 8 Block SelectRAM che utilizza per implementare le 16 Sbox del roundData enc. Le Sbox del roundKey enc vengono invece implementate come memoria ROM distribuita. Similmente nella sintesi del core Encoder AES128 UF1 PP2 e Decoder AES128 UF1 PP2 il tool di sintesi implementa tutte e 20 le Sbox attraverso l’uso delle Block SelectRAM. Si noti come ciascuna delle 120 Block SelectRAM permette di implementare contemporaneamente due Sbox. 93 6 – Implementazione dell’AES128 Decoder AES128 UF1 (liv. sub-pipeline) 0 1 2 LUTs Slices 4.044 4.149 3.841 2.099 2.178 2.848 Block RAMs - Frequency [MHz] 129,9 183,2 234,3 Throughput [Gbps] 1,66 2,34 3,00 Latency [ns] 77,0 54,6 3,4 Tabella 6.4. Performance del decoder crittografico AES128 con architettura iterativa (Disable Sequential Optimization) Decoder AES128 UF1 (liv. sub-pipeline) 0 1 2 LUTs Slices 3.987 3.729 1.212 2.100 2.059 1.171 Block RAMs 10 Frequency [MHz] 144,8 203,6 220,8 Throughput [Gbps] 1,85 2,61 2,83 Latency [ns] 69,1 49,1 45,3 Tabella 6.5. Performance del decoder crittografico AES128 con architettura iterativa (Enable Sequential Optimization) Architettura fully unrolled Le performance del core crittografico per la cifratura (Encoder AES128 UF10) con architettura fully unrolled sono riassunte nelle tabelle 6.6 e 6.7. Encoder AES128 UF10 (liv. sub-pipeline) 0 1 2 LUTs Slices 30.035 29.950 30.555 15.544 16.298 17.575 Block RAMs - Frequency [MHz] 189,6 312,8 315,6 Throughput [Gbps] 24,27 40,04 40,40 Latency [ns] 5,3 3,2 3,1 Tabella 6.6. Performance dell’encoder crittografico AES128 con architettura fully unrolled (Disable Sequential Optimization) Le tabella 6.6 mostra le performance del core crittografico sintetizzato senza abilitare la funzionalità di ottimizzazione sequenziale, mentre le tabella 6.7 mostra il risultato di sintesi con la funzionalità attivata. Anche in questo caso l’utilizzo della memoria RAM integrata nell’FPGA ha permesso una drastica riduzione del numero di LUT o Slice necessarie all’implementazione dell’architettura. Il tool di sintesi, nel caso dell’architettura con uno e due livelli si sub-pipeline, utilizza 60 delle 120 Block SelectRAM messe a disposizione dall’FPGA. Quindi 120 Sbox delle 200 necessarie (20 Sbox per round) sono implementate attraverso l’uso delle Block SelectRAMs. 94 6.5 – Sintesi del core crittografico AES128 Encoder AES128 UF10 (liv. sub-pipeline) 0 1 2 LUTs Slices 29.924 14.899 15.442 15.648 10.327 12.310 Block RAMs 60 60 Frequency [MHz] 199,2 221,2 293,6 Throughput [Gbps] 25,50 28,31 37,58 Latency [ns] 5,0 4,5 3,2 Tabella 6.7. Performance dell’encoder crittografico AES128 con architettura fully unrolled (Enable Sequential Optimization) 6.5.1 Analisi delle performance Sono stati adottati tre differenti parametri per valutare le prestazioni delle architetture proposte per l’AES128. Il primo parametro è il throughput che tiene conto della velocità di cifratura o decifratura dei dati; il secondo parametro è il costo in termini di area occupata valutando il numero di slice occupate nell’FPGA Xilinx Virtex2 XC2V4000; ed infine, il terzo parametro è il rapporto fa throughput e area che tiene conto dell’efficienza dell’implementazione. Il calcolo del numero di slice occupate dall’implementazione è stata fatta in accordo con le osservazioni fatte nell’articolo di Saggese et al. [28]. Saggese et al. propone un calcolo innovativo del numero di slice occupate al fine di poter confrontare architetture che utilizzano o no le Block SelectRAMs. Questo calcolo si basa sull’osservazione che una memoria RAM dual-port 256 × 8b, contenuta in ciascuna Block SelectRAMs, può essere sostituita utilizzando una composizione di memoria distribuita composta da 256 LUTs, equivalenti a 128 slice. Con questo metodo l’area può essere valutata in termini di slice equivalenti (Eq.Slice) calcolato con la seguente formula: Area = Slices + 128 × BlockRAMs [Eq.Slice] (6.6) Nella 6.6 i termini Slices e Block RAMs sono quelli che compaiono nelle tabelle 6.2, 6.3, 6.4, 6.5, 6.6 e 6.7 rispettivamente nella terza e quarta colonna. La tabella 6.8 elenca per ciascuna architettura i tre parametri oggetto d’analisi per le performance. Dai risultati mostrati in tabella 6.8 è possibile estrapolare alcune osservazioni. Come era atteso, l’architettura fully unrolled permette di ottenere il massimo delle prestazioni, in termini di throughput, raggiungendo i 40,40 Gbps dell’architettura Encoder UF10 PP2. È interessante notare come questa performance sia ottenuta senza l’uso delle “ottimizzazioni sequenziali”. L’uso di questa caratteristica del sintetizzatore, come visibile in tabella, non introduce sostanzialmente un’aumento delle performance. Infatti se si guarda, per ogni architettura, il throughput, l’area e il T/A con e senza l’utilizzo delle “ottimizzazioni sequenziali” si nota come in quasi tutte le architetture si ha una perdita di performance. È bene ricordare che l’area è misurata in termini di slice equivalenti e che quindi tiene conto anche delle Block SelectRAMs; risultati differenti si otterrebbero se non si utilizzasse tale tecnica. Si 95 6 – Implementazione dell’AES128 Architettura AES128 Encoder UF1 PP0 (Disable Seq. Opt.) Encoder UF1 PP0 (Enable Seq. Opt.) Encoder UF1 PP1 (Disable Seq. Opt.) Encoder UF1 PP1 (Enable Seq. Opt.) Encoder UF1 PP2 (Disable Seq. Opt.) Encoder UF1 PP2 (Enable Seq. Opt.) Encoder UF10 PP0 (Disable Seq. Opt.) Encoder UF10 PP0 (Enable Seq. Opt.) Encoder UF10 PP1 (Disable Seq. Opt.) Encoder UF10 PP1 (Enable Seq. Opt.) Encoder UF10 PP2 (Disable Seq. Opt.) Encoder UF10 PP2 (Enable Seq. Opt.) Decoder UF1 PP0 (Disable Seq. Opt.) Decoder UF1 PP0 (Enable Seq. Opt.) Decoder UF1 PP1 (Disable Seq. Opt.) Decoder UF1 PP1 (Enable Seq. Opt.) Decoder UF1 PP2 (Disable Seq. Opt.) Decoder UF1 PP2 (Enable Seq. Opt.) Throughput [Gbps] 2,22 2,24 2,89 2,40 2,82 2,66 24,27 25,50 40,04 28,31 40,40 37,58 1,66 1,85 2,34 2,61 3,00 2,83 Area [Eq.Slice] 1.986 2.000 1.840 2.146 1.994 2.337 15.544 15.648 16.298 18.007 17.575 19.990 2.099 2.100 2.178 2.059 2.848 2.451 T/A [Mbps/Eq.Slice] 1,12 1,12 1,57 1,12 1,41 1,14 1,56 1,63 2,46 1,57 2,30 1,88 0,79 0,88 1,07 1,26 1,05 1,15 Tabella 6.8. Analisi delle performance osservi inoltre come sia sempre un’architettura di tipo fully unrolled ad ottenere il più alto rapporto T/A; si tratta dell’architettura Encoder UF10 PP1 implementata senza le “ottimizzazioni sequenziali”. Rispetto all’architettura più compatta (Encoder UF1 PP1 (Disable Eq. Opt.)) occupa un’area di circa 8 volte maggiore ma garantisce un throughput di circa 14 volte maggiore. Tra le architetture iterative, che quindi permettono un risparmio sia in area che in consumi, quella che ottiene il miglio rapporto T/A è l’Encoder UF1 PP1 (Disable Eq. Opt.) per la cifratura e l’Decoder UF1 PP1 (Enable Eq. Opt.) per la decifratura. Si noti come a parità di altre caratteristica l’architettura per la decifratura dei dati occupi un’area maggiore rispetto a quella per la cifratura. Questo aspetto è dovuto al maggior numero di risorse hardware necessarie al moltiplicatore di colonna mixColumn dec rispetto a quello necessario per la cifratura dei dati mixColumn enc. Se si confrontano le performance ottenute dalle architettura proposte con quelle presentate in tabella 5.3 si evince che le prestazioni raggiunte dal core AES128 presentato in questo capitolo sono estremamente competitive. Oltre alla forma tabulare esiste una metodo grafico per riassumere le performance delle varie architetture. Questa tecnica è molto più intuitiva e di facile consultazione. Nelle figure 6.16 e 6.17 sono riassunte in maniera grafica le performance delle 96 6.5 – Sintesi del core crittografico AES128 architetture precedentemente analizzate. Il grafico di figure 6.16 mostra le performance del core AES128 sintetizzato senza le “ottimizzazioni sequenziali”, mentre il grafico di figura 6.17 mostra le performance con la feature attivata. 30.000 Area [Slice] 10.000 Encoder UF1 PP0 Encoder UF1 PP1 Encoder UF1 PP2 Encoder UF10 PP0 Encoder UF10 PP1 Encoder UF10 PP2 Decoder UF1 PP0 Decoder UF1 PP1 Decoder UF1 PP2 1.000 1 10 Throughput [Gbps] Figura 6.16. Grafico performance core AES128 (Disable Sequential Optimization) 97 50 6 – Implementazione dell’AES128 Area (Slices + 128 * BlockRAMs) [Eq.Slice] 30.000 10.000 Encoder UF1 PP0 Encoder UF1 PP1 Encoder UF1 PP2 Encoder UF10 PP0 Encoder UF10 PP1 Encoder UF10 PP2 Decoder UF1 PP0 Decoder UF1 PP1 Decoder UF1 PP2 1.000 1 10 Throughput [Gbps] Figura 6.17. Grafico performance core AES128 (Enable Sequential Optimization) 98 50 Capitolo 7 Tecniche per la protezione dell’informazione nei sistemi embedded Negli ultimi anni l’allargamento della gamma dei servizi e applicazioni offerti dai dispositivi embedded ha dato la nascita di nuove preoccupazioni per quanto riguarda la sicurezza delle informazioni. La maggior parte di questi dispositivi (e.g. pay-TV, PDA, smartphone, etc.) utilizza una memoria esterna quindi il problema principale per quanto riguarda la sicurezza è lo scambio costante di dati e istruzioni, non cifrati, fra la memoria esterna e la CPU. Questa memoria può contenere dei dati confidenziali, come software coperto da copyright, che sarebbe preferibile proteggere sia per evitare delle copie illecite che per evitare qualsiasi tipo di spionaggio industriale. L’obbiettivo di questo capitolo è descrivere chiaramente il problema delle comunicazioni fra la CPU e la memoria esterna, e a questo proposito proporre delle tecniche di cifratura dei dati per assicurare un canale di comunicazione sicuro. 7.1 Il sistema cifrante La scelta della tipologia del sistema cifrante deve essere fatta in rispetto delle specifiche del sistema e molto spesso è un compromesso fra il livello di sicurezza desiderato (robustezza) e la perdita di performance che ci si può permettere. Il processo di decifratura, necessario a seguito di una richiesta di lettura/scrittura sulla memoria esterna da parte della CPU, sarà analizzato in profondità poiché è critico per le prestazioni. I sistemi di cifratura asimmetrici (e.g. RSA) spesso basati su operazioni modulari operanti su grandi numeri interi (512 ÷ 2048 bit) non sono adatti al nostro scopo poiché richiedono maggior potenza computazionale (dovuta all’elevamento a 99 7 – Tecniche per la protezione dell’informazione nei sistemi embedded potenza modulare) rispetto a sistemi di cifratura simmetrici (e.g. 3DES, AES) a parità di robustezza. È importante sottolineare che la maggior richiesta di potenza computazionale dei sistemi asimmetrici si traduce in un aumento del tempo necessario per la cifratura e decifratura delle informazioni. Inoltre, nei sistemi asimmetrici, il testo cifrato è più lungo del testo in chiaro e quindi richiedono quantitativi di memoria maggiore per memorizzare le informazioni cifrate. Gli algoritmi di cifratura simmetrica sono divisi in due: stream cipher e block cipher. Per quanto riguarda i block cipher, il testo in chiaro è suddiviso in blocchi e quindi cifrato blocco per blocco. Invece, nei sistemi stream cipher il principio di funzionamento è basato sull’operazione di XOR fatta fra il testo in chiaro e il key stream. Nel nostro contesto gli algoritmi di cifratura a flusso sono più adatti per quanto riguarda le prestazioni: la generazione del key stream può essere fatta in parallelo con le operazioni di fetch dei dati. L’imperfezione dei sistemi di cifratura a blocco deriva dal fatto che le operazioni di decifratura non posso incominciare fin tanto che non si ha a disposizione un blocco completo. Gli algoritmi di cifratura simmetrica a blocco permettono però differenti modi di funzionamento, capitolo 4.4. L’ECB (Electronic Code Book ) è il più ovvio metodo di funzionamento ma non garantisce un livello di sicurezza accettabile. Il metodo CBC (Cipher Block Chaining) permette un’alto livello di sicurezza ma la dipendenza del blocco cifrato dai sui precedenti non lo rende adatto alla lettura non sequenziale dei dati; il che lo rende inadatto per il nostro scopo. Infatti, la lettura della memoria da parte della CPU non è sequenziale (e.g. istruzioni di jump). Il metodo OFB in modalità counter mode permette di ottenere dei livelli di sicurezza molto simili alla modalità CBC e conferisce delle proprietà di accesso casuale per la cifratura è decifratura dei dati. Quest’ultima modalità di funzionamento permette di vedere il codificatore a blocco come un sistema di cifratura a flusso. In questa modalità la generazione del key stream è indipendente dalla lettura dei dati e può essere fatta in parallelo con le operazione di fetch dei dati. L’utilizzo di un codificatore a blocco in modalità counter mode rispetto a un codificatore a flusso è preferibile vista la maggior sicurezza offerta dagli algoritmi di cifratura a blocco attualmente sviluppati e standardizzati. 7.2 Architetture: stato dell’arte L’idea della cifratura del contenuto della memoria esterna è stata sviluppata circa 28 anni fa da Best [45, 46, 47]. Best ha proposto di considerare la CPU come un’entità sicura, quindi al suo interno gli indirizzi e i dati sono sono in forma chiara mentre sono in forma cifrata all’esterno del SOC (System On Chip). A tale scopo propone di implementare all’interno del SOC un’unità cifrante e di immagazzinare in un registro interno la chiave di cifratura, figura 7.1. Il cifratore a blocco scelto è 100 7.2 – Architetture: stato dell’arte basato su funzioni crittografiche basilari come mono e poli-sostituzioni alfabetiche e trasposizione dei byte. Figura 7.1. Principio di funzionamento dell’idea di Best Alcune delle regole enunciate da Best sono ancora oggi considerate come riferimento: il System On Chip è considerato sicuro, l’unità cifrante e la chiave di cifratura sono all’interno del SOC, inoltre l’unità cifrante è posizionata fra la memoria cache e il controllore della memoria esterna. In letteratura sono proposte diverse architetture basate sui principi dettati da Best e alcune di queste architetture sono diventate brevetti industriali [48, 49, 50] mentre altre sono ancora di tipo accademico [43, 51, 52]. VLSI Technology [48] propone un’architettura, mostrata in figura 7.2, in cui il trasferimento dei dati da e verso la memoria esterna sono fatti page-by-page. Tutte le richieste di dati esterne alla CPU sono gestite da un Secure DMA e le comunicazioni fra la memoria esterna e quella interna utilizzano un Encryption/Decryption Core. Questo sistema consente di utilizzare un codificatore a blocco. Il Secure DMA è controllato dal sistema operativo che obbligatoriamente deve essere considerato sicuro. Quest’ultimo aspetto è fortemente penalizzante per l’architettura perché richiede un sistema operativo sviluppato appositamente. L’architettura dalla General Instrument Corporation [49] visibile in figura 7.3 utilizza un core crittografico basato sullo standard 3-DES in modalità di funzionamento CBC. Questa architettura offre la possibilità di autenticare i dati provenienti dalla memoria esterna attraverso un’algoritmo di impronta (keyed hash algorithm). Il funzionamento in modalità CBC dell’algoritmo di cifratura offre un alto livello di sicurezza ma, come visto in precedenza, implica una degradazione inaccettabile delle prestazioni per gli accessi casuali nella memoria esterna. Tra i dispositivi di autenticazione sviluppati per differenti mercati, come quello 101 7 – Tecniche per la protezione dell’informazione nei sistemi embedded Figura 7.2. Architettura della VLSI Technology Figura 7.3. Architettura della General Instrument Corporation delle pay-TV e le carte di credito, c’è il sistema proposto dalla Dallas Semiconductors, figura 7.4. La vecchia versione del dispositivo, la DS5002FP [50], fu violata dal celebre attacco sviluppato da Markus G. Kuhn [44]. La recente DS5240 [50] implementa un cifratore basato sullo standard DES o 3-DES quindi con una chiave di cifratura a 64 bit anziché gli 8 della precedente versione. Guilmont et al. [43] utilizza un’innovativa tecnica di predizione dei dati di cui è necessario il fetch dalla memoria esterna. L’unità per la decifratura dei dati è 102 7.2 – Architetture: stato dell’arte Figura 7.4. Architettura della Dallas Semiconductors basata su una versione con pipeline dell’algoritmo 3-DES. Grazie a questa tecnica l’autore presuppone di mantenere il costo della decodifica dei dati al di sotto del 2,5% in termini di performance. Tuttavia questo risultato è stato ottenuto richiamando dalla memoria dei dati di grandezza pari alla dimensione del blocco dell’unità di decifratura. Come visto in precedenza, la maggior perdita di performance si ha nella lettura e scrittura di dati di dimensione inferiore a quella del blocco dell’unità di decifratura. Il progetto XOM sviluppato dal gruppo di ricerca VLSI dell’università di Stanford (USA) utilizza una versione con pipeline dell’algoritmo AES come unità cifrante. L’obbiettivo principale di questo progetto non è l’unità cifrante ma lo sviluppo di un’architettura robusta ai tentativi di manomissione (tamper-resistant). L’architettura proposta dal progetto AEGIS [52] prevede l’utilizzo di un motore crittografico basato su una versione con pipeline dell’algoritmo AES. La modalità di funzionamento dell’unità cifrante è la CBC ma la lunghezza dei blocchi concatenati è pari alla dimensione di una riga della memoria cache; ciascuna riga di cache è cifrata in maniera indipendente. Questa caratteristica permette un’accesso casuale alle memoria esterna garantendo un discreto livello di protezione. Tuttavia, i dati scaricati dalla memoria non possono essere utilizzati finché non si è eseguito l’algoritmo di cifratura sull’intera riga di memoria cache. La generazione del vettore di inizializzazione (IV) necessario alla modalità CBC è formato dall’indirizzo di memoria del blocco e da un vettore casuale. Per contrastare il “birthday attack” [42] è possibile sostituire il vettore casuale con un contatore. Lo svantaggio di questa architettura è ancora una volta il peso computazionale da sostenere per garantire un livello di sicurezza adeguato. Si stima che questa architettura introduca un degrado delle performance del 25%. 103 7 – Tecniche per la protezione dell’informazione nei sistemi embedded EDU Memory Controller CPU core Cache Trusted area (a) Figura 7.5. Posizione dell’unità cifrante 104 External Memory Le architetture appena descritte condivido l’utilizzo di un’algoritmo di cifratura robusto e approvato dal NIST (National Institute of Standard Technology): il 3-DES o l’attuale AES. Inoltre in tutte le architetture presentate l’unità cifrante (EDU) è posizionata fra la memoria cache e il controllore della memoria, figura 7.5. Si differenziano per le modalità con la quale propongono la cifratura dei dati provenienti dalla memoria esterna e dalle performance che permettono di raggiungere. Capitolo 8 Il processore LEON3 Il LEON3 è un progetto open source di un microprocessore RISC compatibile con l’architettura SPARC V8 sviluppato dalla Gaisler Research [53]. Il microprocessore è molto versatile ed è particolarmente adatto per il progetto di SOC (System On a Chip). La sua versatilità risiede nella caratteristica di poter essere ottimizzato su diversi aspetti, come ad esempio, le performance, il consumo di potenza, I/O throughput, occupazione di risorse ed il costo. Il microprocessore si interfaccia con il bus AMBA-2.0 AHB e supporta l’IP plug&play descritta nella libreria GRLIB (Gaisler Research ip LIBrary). Il microprocessore può essere efficientemente implementato nelle tecnologie FPGA e ASIC ed utilizza delle celle standard di RAM sincrona per implementare sia la memoria cache che i register file. Per promuovere l’architettura SPARC e semplificare la progettazione vengono forniti le descrizioni hardware in VHDL sia del processore LEON3 che della libreria IP sotto licenza GNU (General Public License). Il LEON3 è anche disponibile in versione fault tolerant per applicazioni spaziali. 8.1 Overview Il LEON3 è un microprocessore a 32 bit conforme allo standard IEEE-1754 (SPARC V8). È stato progettato per applicazioni embedded e le sue principali caratteristiche sono: • pipeline a 7 stadi • cache separate per dati e istruzioni • moltiplicatore e divisore hardware • unità per il supporto del debug on-chip 105 8 – Il processore LEON3 • compatibilità con sistemi multiprocessore L’architettura del LEON3, figura 8.1, è composta da diversi macro blocchi alcuni dei quali vengono brevemente descritti. 3-Port Register File Trace Buffer IEEE-754 FPU Co-Processor 7-Stage Integer pipeline HW MUL/DIV Local IRAM ITLB I-Cache D-Cache SRMMU Debug port Debug support unit Interrupt port Interrupt controller Local DRAM DTLB AHB I/F AMBA AHB Master (32-bit) Figura 8.1. Schema a blocchi del microprocessore LEON3 Integer Unit L’integer unit del LEON3 implementa in pieno lo standard SPARC V8 comprese le istruzioni per la moltiplicazione e divisione hardware. Il numero di registri della register windows è configurabile, entro i limiti dello standard SPARC (2÷32), e di default è pari a 8. Il pipeline è su 7 livelli con interfaccia separata per le istruzioni e i dati (architettura Harvard). Cache sub-system Il LEON3 ha una sistema cache molto flessibile che consiste in due chace separate per la gestione dei dati e delle istruzioni. Entrambe possono essere configurate in 1÷4 set, 1÷256 kByte/set, 16÷32 byte per linea. Il subblocking è implementato con un bit di validità per ciascuna parola da 32 bit. La cache istruzioni utilizza una tecnica di streaming, durante il riempimento della riga, per ridurre al minimo il tempo di attesa. La cache dati utilizza la politica di pass-through e implementa un buffer di scrittura da due parole. La cache dati può inoltre eseguire il bus-snooping sul bus AHB. A supporto di entrambi i controllori dell memoria cache può essere implementata una scratchpad RAM locale che permette di realizzare un accesso in memoria di tipo 0-waitstates senza il write back dei dati. 106 8.1 – Overview Floating point unit e co-processor L’integer unit del LEON3 fornisce un’interfaccia per la floating-point unit (FPU) e per un eventuale co-processore. Sono disponibili due FPU, una sviluppata dalla Gaisler Research (GRFPU) e l’altra sviluppata della Sun Microsystems (Meiko FPU core). La floating-point unit e l’eventuale co-processore elaborano i dati in parallelo all’integer unit finché non vi sono dei conflitti nell’utilizzo di risorse o dati in comune. Memory management unit Può essere opzionalmente abilitata una Memory Management Unit (SRMMU) compatibile con lo standard SPARC V8. La SRMMU provvede a tradurre gli indirizzi, multipli di 32 bit, della memoria virtuale nei 36 bit della memoria fisica. Sono implementati tre livelli hardware della table-walk e la MMU può essere configurata per gestire fino a 64 fully-associative TLB. On-chip debug support Il pipeline del LEON3 ha la caratteristica di permettere di effettuare un debug non intrusivo. Per aiutare il software di debug possono essere abilitati fino a quattro registri per il watch-point. Ciascun registro può causare un’evento di breakpoint su di un’istruzione arbitraria o su un determinato intervallo di indirizzamento. Quando questa unità, che è opzionale, viene abilitata i watch-point possono essere utilizzati per entrare nella modalità di debug. Attraverso l’interfaccia di supporto al debug è possibile accedere a tutti i registri del processore e alla memoria cache. L’interfaccia per il debug permette inoltre il single stepping, l’instruction tracing e il controllo dei break-point/watch-point hardware. Infine è implementato un buffer per monitorare e memorizzare le istruzioni eseguite che potranno essere lette attraverso l’interfaccia per il debug. Interrupt interface Il LEON3 supporta fino a un totale di 15 interrupt asincroni. L’interfaccia di interrupt fornisce le funzionalità per la generazione e la gestione degli interrupt. AMBA interface Il sistema cache implementa un’unità master per il bus AMBA AHB che permette la lettura e la scrittura da e verso la memoria cache. L’interfaccia è compatibile con lo standard AMBA-2.0. Durante il riempimento di una riga della memoria cache è generata una richiesta di trasferimento di tipo “incremental burst” per ottimizzare il trasferimento dei dati. Power-down mode Il processore LEON3 implementa la modalità di power-down che arresta il pipeline e la cache fino all’arrivo di un successivo interrupt. Questa è una strategia vincente per minimizzare il consumo di energia quando l’applicazione è inattiva. 107 8 – Il processore LEON3 Multi-processor support Il LEON3 è progettato per essere utilizzato in sistemi multiprocessore. Ciascun processore ha un proprio numero identificativo che permette indicizzare i processori. I meccanismi di write-through delle memorie cache e di snooping garantiscono la coerenza dei dati condivisi. Le prestazioni che il microprocessore LEON3 dipendono molto dalla sua configurazione. A titolo di esempio, utilizzando 8K+8K di memoria cache e un moltiplicatore 16×16, il resoconto del benchmark “dhrystone 2.1” è di 1.500 iterazioni/s/MHz utilizzando il compilatore “gcc-3.4.4” con l’opzione “-O2”. Questo significa che vengono eseguite 0.85 MIPS/MHz utilizzando come riferimento per un MIPS il valore di VAX 11/780. 8.2 Cache istruzioni In questo capitolo si analizzerà in dettaglio le caratteristiche della memoria cache per le istruzioni implementata dal microprocessore LEON3. Questa analisi, come si vedrà nel capitolo 9, è di fondamentale importanza per la comprensione del funzionamento della memoria cache. 8.2.1 Funzionamento La memoria cache per le istruzioni può essere configurata come direct-mapped o come multi-set con associatività da 2 a 4. L’algoritmo di rimpiazzamento dei dati per la cache multi-set da 2, 3 o 4 set, può essere scelto fra il Least Recently Used (LRU) o il Random Replacement Policy; solo per la cache multi-set a 2 set è possibile utilizzare l’algoritmo di Least Recently Replace (LRR). La dimensione del set è configurabile tra 1 e 64 kByte e diviso in linee di memoria da 16 o 32 byte. Ciascuna linea ha associato un cache tag che consiste in un registro che memorizza l’address tag, l’informazione di validità dei dati (un bit per ciascuna word) e opzionalmente un bit per l’informazione di LLR e un bit per l’informazione di lock. Al verificarsi di un cache miss, di una locazione di memoria di cui è possibile la memorizzazione in memoria cache, l’istruzione viene recuperata e vengono aggiornato il cache tag e la linea di memoria corrispondenti. In una configurazione multi-set, il set in cui memorizzare la linea viene scelto un accordo con l’algoritmo di rimpiazzamento scelto. Se è abilitata l’opzione di “instruction burst fetch”, nel cache control register (CCR), la linea della cache è riempita dalla memoria principale a partire dall’indirizzo di partenza fino alla fine della linea. Contemporaneamente, viene implementata la tecnica di streaming, in cui le istruzioni vengono inoltrate all’IU. Se l’IU non accetta il flusso di istruzioni a causa di una dipendenza interna o ad un’istruzione che 108 8.2 – Cache istruzioni dura più di un ciclo, l’IU viene messa in attesa fino a che la linea di memoria non viene riempita completamente. Se l’IU esegue un’istruzione di salto condizionato (e.g. branch, CALL, JMPL, RETT, TRAP. . . ) durante il riempimento di una riga viene interrotto lo streaming dalla memoria principale e si attende il prossimo cache miss. Se è abilitato l’“instruction burst fetch”, lo streaming delle istruzioni verso l’IU è abilitato anche quando la memoria cache è disabilitata. In questo caso le istruzioni recuperate dalla memoria vengono solamente inoltrate all’IU e non viene aggiornata la linea di cache. Durante il riempimento di una linea di cache viene richiesto al bus AMBA AHB un trasferimento in modalità “incremental burst”. Se si sono verificati degli errori nell’accesso alla memoria durante il riempimento di una linea di cache, il corrispondente bit di validità nel cache tag non viene impostato. Se l’IU richiede un’istruzione che ha associato un bit di validità non impostato, viene generato un cache miss, forzando una nuova lettura nella memoria principale. Se l’errore persiste viene generata un’istruzione trappola (tt=0×1) che permette di uscire dallo stato di errore. 8.2.2 Instruction cache tag L’“instruction cache tag” è formato da diversi campi come mostrato in figura 8.2. In funzione delle configurazione della cache saranno implementati i bit necessari al suo funzionamento. Ad esempio, una memoria cache da 4 kByte con 16 bytes per linea necessita di 4 bit di validità (uno per ogni word da 32 bit) e 12 bit per l’indirizzo di tag. 8.2.3 Funzionalità aggiuntive della cache istruzioni Vengono qui di seguito descritte alcune peculiarità della memoria cache che sono implementate nel microprocessore LEON3. Cache flushing La cache può essere svuotata eseguendo l’istruzione di FLUSH ma anche settando il bit FI nel registro di controllo della cache o attraverso la scrittura in una qualsiasi locazione di memoria con ASI=0×15. Lo svuotamento della cache richiede un ciclo di clock per ogni linea. Durante il flushing delle istruzioni l’IU non può essere arrestata e la cache è disabilitata. Quando l’operazione è terminata la cache riassume lo stato precedente (disable, enable o frozen) indicato nel registro di controllo. L’accesso diagnostico alla cache non è possibile durante l’operazione di FLUSH e causa un’eccezione (trap=0×09) se si tenta l’accesso. Accesso diagnostico alla cache Tags e dati nella cache istruzioni possono essere letti e/o scritti attraverso esecuzione delle istruzioni LDA e STA nello spazio 109 8 – Il processore LEON3 Tag for 1 Kbyte set, 32 bytes/line 31 10 ATAG 9 8 7 0 VALID LRR LOCK Tag for 4 Kbyte set, 16bytes/line 31 12 9 00 ATAG 8 LRR LOCK 3 0000 0 VALID Figure 165. Instruction cache tag layout examples Address TAG (ATAG) [31:10] Contiene l’indirizzo di tag della linea di cache corrispondente LLR [9] Utilizzato dall’algoritmo LLR per memorizzare le informazioni sul rimpiazzamento, altrimenti è impostato a ‘0’. LOCK [8] Blocca la scrittura di una linea di cache quando è impostato. È pari a ‘0’ quando la linea non è bloccata. Valid(V) [7:0] È settato quando la word della linea di cache contiene dati validi. Questo bit viene impostato al termine di una scrittura completa di una riga di memoria cache, se la lettura dalla memoria principale ha generato degli errori questo bit non viene impostato. L’istruzione di FLUSH resetta i bit di valid. V[0] corrisponde alla prima word con indirizzo 0, V[1] alla seconda con indirizzo 1 e cosi via. Figura 8.2. Instruction cache tag di indirizzo ASI 0×C e 0×D. I bit dell’indirizzo che formano l’offset della memoria cache saranno utilizzati per indirizzare il tag in cui accedere mentre i bit meno significativi dell’indirizzo di tag saranno utilizzati per indirizzare il set della cache. La lettura diagnostica del tag è possibile attraverso l’esecuzione dell’istruzione LDA con ASI=0×C. La linea di cache e il set sono indirizzati rispettivamente attraverso i bit che formano l’offset della memoria cache e dai bit meno significativi dei bit che formano l’indirizzo di tag. Analogamente il blocco dati 110 8.2 – Cache istruzioni può essere letto attraverso l’esecuzione dell’istruzione LDA con ASI=0×D. La word dati (è un’istruzione) da leggere è indirizzata dal registro A[4:2]. Il tags dell’indirizzo può essere direttamente scritto eseguendo l’istruzione STA con ASI=0×C. La linea di cache e il set sono indirizzati attraverso i bit che formano l’offset della memoria cache e i bit meno significativi dell’indirizzo di tag. Il registro D[31:10] è scritto all’interno del campo ATAG e i bit di validità sono scritti con il contenuto del registro D[7:0]. Il bit D[9] è scritto all’interno del campo LLR (se abilitato) e D[8] è scritto all’interno del campo lock (se abilitato). Il blocco dati può essere scritto attraverso l’esecuzione dell’istruzione STA con ASI=0×D. La word dati (è un’istruzione) da scrivere è indirizzata dal registro A[4:2]. Blocco di una linea di cache Nella configurazione multi-set può essere impostato nell’“instruction cache tag” il bit di ‘lock’ che informa il controllore della cache l’impossibilità di rimpiazzare la linea di cache corrispondente. Per bloccare una linea di cache è necessario eseguire una scrittura diagnostica nell’“instruction cache tag” della linea che deve essere bloccata, impostando il campo ‘Address TAG’ con l’address tag della linea che si intende bloccare, il bit di ‘lock’ con il valore logico 1 e ripulire i bit di validità. La linea di cache bloccata sarà aggiornata inseguito a un read miss. La prima linea di cache del primo set è di default bloccata. La procedura di bloccaggio su differenti linee ma con lo stesso offset viene eseguita a partire dal primo set e in ordine verso l’ultimo set. L’ultimo set non può essere bloccato ed è sempre sostituibile. La procedura di sbloccaggio è eseguita in ordine inverso, cioè a partire dal penultimo set. NOTA: Questa caratteristica deve essere abilitata durante la fase di configurazione del microprocessore LEON3. Memoria RAM locale per le istruzioni È possibile collegare al controllore della memoria cache una memoria RAM di supporto. La dimensione della memoria è configurabile e compresa fra 1 e 256 kByte. La memoria RAM locale può mappare un qualsiasi blocco da 16 Mbyte dello spazio di indirizzamento. Quando si eseguono istruzioni memorizzate nella memoria RAM locale non si causa lo stallo del pipeline dell’IU e non si generano letture sul bus AMBA AHB. Si può accedere alla memoria RAM locale attraverso delle istruzioni di lettura/scrittura (LD/ST) di integer word. È permessa la lettura/scrittura solamente di word, l’accesso alla memoria a livello di byte, half word o double causa la generazione di un’eccezione. 111 8 – Il processore LEON3 Memoria scratchpad RAM locale Può essere opzionalmente collegata una memoria scratchpad RAM locale al controllore della cache. Questa tecnica permette un’accesso in memoria di tipo 0-waistates. La memoria RAM può essere compresa fra 1 e 512 kByte e può mappare un qualsiasi blocco da 16 Mbyte dello spazio di indirizzamento. Le istruzioni lette attraverso questa tecnica non vengono memorizzato in memoria cache e non attraversano il bus AMBA AHB. La lettura e scrittura attraverso questa tecnica può essere fatta solamente dal processore, e non dalle altre periferiche collegate al bus AMBA AHB. La memoria deve essere inizializzata dal software (attraverso le istruzioni di store) prima del suo utilizzo. L’indirizzo di default della memoria RAM è 0×8e000000. NOTA: Questa tecnica può essere utilizzata solo se la MMU è disabilitata. Registro di controllo della cache Il Cache Control Register (CCR) è un registro, figura 8.3, in comune fra la cache istruzioni e quella dati e ne controlla il funzionamento. Ciascuna cache può essere in tre diverse modalità: disabilitata, abilitata e frozen. Se è disabilitata le richieste di lettura e scrittura sono direttamnete passate al memory controller. Se è abilitata, la memoria chace è abilitata ed opera come descritto in precedenza. Se è nello stato di frozen, la memoria cache è accessibile e si mantiene sincronizzata con la memoria principale (cache dati) come se fosse abilitata ma nessuna nuova linea viene allocata inseguito ad un read miss. Se DF o IF sono impostati, la corrispondente memoria cache entra nella modalità frozen a seguito di un interrupt asincrono. Questa particolarità è utile nelle applicazioni in tempo reale per permettere un calcolo accurato del segmento di codice con il tempo di esecuzione più lungo. Registro di configurazione della cache Il Cache Configuration Register, figura 8.4, è di sola lettura e indica la dimensione e la configurazione della memoria cache. Sono necessari due registri, uno per la memoria cache dei dati ed uno per la memoria cache delle istruzioni. Entrambi i registi sono accessibili attraverso le operazioni di load/store (LDA/STA) utilizzando ASI=2. La seguente tabella di figura 8.5 mostra l’indirizzo dei registri. Considerazioni software Dopo l’operazione di reset la memoria cache è disabilitata e il CCR è 0. Prima di abilitare la cache è bene eseguire l’operazione di flush per ripulire i campi ATAG e VALID. Un’appropriata sequenza assembler potrebbe essere la seguente: flush 112 8.2 – Cache istruzioni on read misses. 31 23 22 21 16 15 14 DS FD FI IB IP DP 6 5 4 3 2 DF IF DCS 1 0 ICS 167. Cache register Data cache snoop ena-Figure[23] Secontrol impostato abilita lo snooping ble (DS) della cache dati. Flus data cache (FD) [22] Se impostato svuota la memoria cache dei dati. È sempre letto come zero. Flush Instruction ca- [21] Se impostato svuota la memoria che (FI) cache delle istruzioni. È sempre letto come zero. Instruction burst fetch [16] Queta impostazione abilita la let(IB) tura delle istruzioni dalla memoria principale in modalità burst. Instruction cache flush [15] Questo bit viene impostato duapending (IP) rante l’esecuzione dell’operazione di flush della cache istruzioni. Data cache flush pen- [14] Questo bit viene impostato duading (DP) rante l’esecuzione dell’operazione di flush della cache dati. Data Cache Freeze on [5] Se impostato la meoria cache dei Interrupt (DF) dati entra nella modalità frozen a seguito di un interrupt asincrono. Instruction Cache [4] Se impostato la meoria cache delFreeze on Interrupt le istruzioni entra nella modalità (IF) frozen a seguito di un interrupt asincrono. Data Cache state [3:2] Indica lo stato della memoria (DCS) cache dei dati secondo il seguente schema: ∀0=disabilitata, 01=frozen, 11=abilitata. Instruction Cache sta- [1:0] Indica lo stato della memoria cate (ICS) che delle istruzioni secondo il seguente schema: ∀0=disabilitata, 01=frozen, 11=abilitata. Figura 8.3. Cache Control Register (CCR) set 0x81000f, %g1 sta%g1, [%g0] 2 113 8 – Il processore LEON3 31 30 29 28 27 26 25 24 23 CL REPL SN SETS Cache locking (CL) 20 19 18 SSIZE LR [31] Cache replacement policy (REPL) [29:28] Cache snooping (SN) [27] Cache associativity (SETS) [26:24] Set size (SSIZE) [23:20] Local ram (LR) [19] Line size (LSIZE) [18:16] Local ram size (LRSZ) [15:12] Local ram start address (LRSTART) [11:4] MMU (M) [3] 16 15 LSIZE 12 11 LRSIZE 4 3 LRSTART 0 M Impostato se è implementato il cache locking. 00=nessuna politica di rimpiazzamneto (direct mapped cache), 01=LRU, 10=LLR, 11=random. Impostato se è implementato lo snoopig. Numero dei set della memoria cache: 000=direct mapped, 001=2way associative, 010=3-way associative, 011=4-way associative. Indica la dimensione (KByte) di ciascun set. Size = 2SIZE . Impostato se è implementata la tecnica scratch pad. Indica la dimensione (word) di ciascuna linea. Linesize = 2LSZ . Indica la dimensione in (KByte) della memoria ram locale implementata con la tecnica scratch pad. Localramsize = 2LRSZ . Indica gli 8 MSB dell’indirizzo di partenza della memoria ram locale. Impostato a ‘1’ se è presente la MMU. Figura 8.4. Cache Configuration Register Address Register 0x00 Cache control register 0x04 Reserved 0x08 Instruction cache configuration register 0x0C Data cache configuration register Figura 8.5. Indirizzo dei registri di configurazione della cache 114 8.3 – La libreria GRLIB IP 8.3 La libreria GRLIB IP La libreria GRLIB IP è una collezione di IP (Intelligent Peripheral) espressamente sviluppate per le architetture SOC (System On Chip). Le IP sono sviluppate per condividere un bus comune e utilizzare un metodo coerente per la simulazione e la sintesi. La libreria è stata realizzata per essere pienamente compatibile con differenti strumenti CAD e differenti tecnologie implementative. Un’unico metodo plug&play viene utilizzato per configurare e connettere le IP in maniera automatica. La GRLIB è un progetto open source ed è distribuita sotto licenza GNU GPL. Questo significa che tutti i componenti della libreria, sviluppati secondo questa licenza, sono distribuiti liberamente e vengono fornite le descrizioni hardware. La libreria GRLIB è reperibile presso [53] come un file compresso gzipped tar che può essere installato in qualsiasi direttorio del computer. 8.3.1 Organizzazione della libreria La GRLIB è organizzata in differenti librerie VHDL ciascuna delle quali individua un IP (o venditore di IP) tramite un nome univoco. L’uso di differenti librerie previene il conflitto di nome fra differenti IP e permette di nascondere all’utente finale i dettagli implementativi non essenziali. Ciascuna libreria VHDL contiene parecchi package in cui vi sono le dichiarazioni per l’esportazione degli IP e la loro interfaccia. Gli script per la simulazione e la sintesi sono generati automaticamente attraverso dei makefile globali. L’aggiunta e la rimozione delle librerie e dei package possono essere fatte senza modificare alcun file globale. Alcune librerie globali provvedono a definire le strutture dati e le funzioni in comune. GRLIB fornisce gli script generator per i simulatori Modelsim, Ncsim e GHDL, e per i sintetizzatori Synopsys, Synplify, Cadence, Mentor, Actel, Altera, Lattice e Xilinx. Il supporto ad altri strumenti CAD può essere facilmente implementato. La libreria GRLIB è sviluppata per essere ‘bus-centric’, ovvero è una libreria in cui la maggior parte degli IP sono connessi a un bus comune. Il bus scelto per connettere i vari IP è l’AMBA-2.0 AHB/APB poiché è largamente utilizzato (vedi i processori della ARM), può essere utilizzato liberamente senza restrizioni d’utilizzo ed è disponibile a corredo un’ampia documentazione. La figura 8.6 mostra un’esempio di un sistema basato sul microprocessore LEON3 progettato con la libreria GRLIB. L’utilizzo della libreria GRLIB permette di creare un microcontrollore completo di tutte le periferiche necessarie. Vengono messe a disposizione componenti come il controllore AMBA AHB/APB, il microprocessore LEON3 SPARC, l’unita in virgola mobile IEEE-754, l’AHB/ABH bridge, il controllore SDRAM a 32 bit PC133, il bridge PCI a 32 bit con DMA, l’interfaccia ethernet a 10/100 Mbit, il controllore CAN-2.0, il debug link USB-2.0, il controllore PROM/SDRAM a 8/16/32 bit, il 115 8 – Il processore LEON3 USB PHY RS232 JTAG PHY LVDS CAN PCI Serial Dbg Link JTAG Dbg Link Ethernet MAC Spacewire Link CAN 2.0 Link PCI LEON3 Template Design USB LEON3 Processor AMBA AHB AHB Controller Memory Controller AMBA APB AHB/APB Bridge VGA PS/2 UART Timers Video DAC PS/2 IF RS232 WDOG IrqCtrl I/O port 8/32-bits memory bus PROM I/O SRAM SDRAM 32-bit I/O port Figura 8.6. LEON3 template design controllore SSRAM a 32 bit, il controllore DDR a 32 bit, la porta GPIO a 32 bit, la timer unit, il controllore degli interrupt, l’interfaccia PS/2 e il controllore VGA. GRLIB introduce nell’architettura del sistema delle sostanziose novità per quanto riguarda la decodifica di indirizzo distribuita, la gestione degli interrupts e la funzionalità di “plug&play”. Per “plug&play” si intende la capacità di rilevare la configurazione hardware attraverso il software. Tale possibilità permette all’applicazione software o al sistema operativo di configurarsi automaticamente al fine di adattarsi alle caratteristiche hardware. Ciò semplifica notevolmente lo sviluppo delle applicazioni software poiché diventano indipendenti dalla piattaforma hardware. La libreria GRLIB è stata sviluppata per essere facilmente implementata su tecnologia ASIC o FPGA. La portabilità prevede il supporto per componenti come le single-port RAM, le two-port RAM, le dual-port RAM, le single-port RAM, il generatore di clock e i pad. La portabilità è stata implementata per mezzo di componenti virtuali il cui codice VHDL permette di selezionare la tecnologia desiderata. Nell’architettura del componente il comando VHDL generate è utilizzato per istanziare i macro blocchi della tecnologia selezionata. 8.3.2 LEON3MP: configurazione del microprocessore La libreria GRLIB include all’interno dei progetti già pronti all’uso, tra questi vi è il LEON3MP che è un sistema di riferimento completo basato sul microprocessore LEON3. Il LEON3MP è altamente configurabile ed è composto dai seguenti IP: 116 8.3 – La libreria GRLIB IP • Da 1 a 4 microprocessori LEON3 • Unita per il supporto del debug (DSU) • Controllore PROM/SRAM a 32 bit • Controllore PROM/SRAM/SDRAM a 8/16/32/64 bit • Interfaccia PCI a 32 bit, target only o initiator/target con FIFO e DMA • Arbitro AHB round robin e controllore con supporto del plug&play • AHB/APB bridge con supporto del plug&play • Controllore degli interrupt • Modular Timer Unit a 32 bit • Da 1 a 2 UART con FIFO • Interfaccia ethernet MAC a 10/100 Mbps • Interfaccia CAN • Link per il debug via seriale • Link per il debug via ethernet • Link per il debug via JTAG Il LEON3MP è costituito da un bus AMBA AHB e APB che connette fra loro i vari IP presenti nella libreria GRLIB. Il metodo di configurazione plug&play della GRLIB da la possibilità di assegnare qualsiasi combinazione di indirizzo e interrupts ai vari IP. Tuttavia per mantenere la compatibilità software con semplici sistemi operativi come il “LEON Bare-C cross-compiler” alcuni IP essenziali devono essere assegnati a predefiniti indirizzi e interrupt. La tabella 8.1 mostra le assegnazioni di default fatte per il LEON3MP. La configurazione del LEON3MP è definita attraverso il package di configurazione situato nel file VHDL config.vhd. Questo file può essere automaticamente generato utilizzando un’interfaccia grafica, figura 8.7, basata su tkconfig. Per eseguire la GUI è necessario eseguire il comando ‘make xconfig’. Effettuata la configurazione l’applicativo genererà in automatico il file di configurazione con i parametri selezionati. Dal menù principale si possono configurare tutti gli aspetti hardware del sistema LEON3MP. Tra le varie configurazioni c’è quella che riguarda la configurazione della memoria cache, raggiungibile tramite il menù ‘Processor’, figura 8.8 117 8 – Il processore LEON3 IP Core Memory controller (separate SRAM and SDRAM controllers, or combined LEON2 controller) APB bridge UART Interrupt controller Timer unit LEON3 debug support unit (DSU) Memory area 0 × 00000000 ÷ 0 × 20000000 0 × 20000000 ÷ 0 × 40000000 0 × 40000000 ÷ 0 × 80000000 0 × 80000000 ÷ 0 × 80000100 registers (APB) 0 × 80000000 ÷ 0 × 80100000 0 × 80000100 ÷ 0 × 80000200 0 × 80000200 ÷ 0 × 80000300 0 × 80000300 ÷ 0 × 80000400 0 × 90000000 ÷ 0 × a0000000 : : : : PROM external I/O bus SRAM/SDRAM Memory controller : : : : : APB bus UART registers IRQ registers timer registers DSU registers Interrupt - 2 8, 9 - Tabella 8.1. LEON3MP: assegnazioni di default per gli indirizzi e interrupt degli IP essenziali Figura 8.7. LEON3MP Design Configuration Il menù per la configurazione della memoria cache, figura 8.9, riporta in maniera chiara e schematica tutte le impostazioni possibili per la memoria cache delle istruzioni e dei dati. Per maggior chiarezza viene brevemente illustrato il significato delle impostazioni riguardanti la memoria cache per le istruzioni; fra parentesi graffe è riportato il nome della costante presente nel file VHDL config.vhd. Enable instruction cache Abilita la cache delle istruzioni che dovrebbe essere sempre abilitata per garantire il massimo delle prestazioni. Alcuni sistemi a basse prestazioni possono risparmiare spazio disabilitando la cache e accettando un calo di prestazioni di un fattore 2÷3. {CFG ICEN} Associativity (sets) La cache delle istruzioni può essere implementata come una cache di tipo direct mapped o di tipo set associative. Per la prima tipologia è necessario impostare il parametro sul valore ‘1’, mentre per la seconda tipologia il parametro va impostato fra ‘2’ e ‘4’ in base al numero di set che si intende implementare. Un alto livello di associatività tipicamente incrementa il cache hit rate e quindi le prestazioni. L’altro lato della medaglia è l’incremento del 118 8.3 – La libreria GRLIB IP Figura 8.8. LEON3MP Design Configuration, Processor menù consumo di potenza e l’aumento di risorse hardware per l’implementazione. {CFG ISETS} Set size (kBytes/set) Permette di impostare la dimensione, espressa in kBytes, di ciascun set della memoria cache. I valori ammessi sono 1, 2, 4, 8, 16, 32, 64, 128 e 256 kBytes. Alcune tecnologie implementative permettono la scelta dei valori compresi fra 2 e 16, mentre solo per la famiglia VIRTEX2 della XILINX è possibile scegliere nell’intero range. Una dimensione ampia del set offre alte prestazioni ma limita la massima frequenza soprattutto se la tecnologia implementativa è l’ASIC. La dimensione della cache è il prodotto fra il numero di set e il set size. {CFG ISETSZ} Line size (Bytes/line) Questo parametro consente di impostare la dimensione della linea di cache. Può essere impostata solamente fra due valori: 16 e 32 byte. Tipicamente di hanno dei benefici con un’ampia dimensione di riga ma per limitare l’eviction miss rate potrebbe essere preferibile selezionare il valore più basso. {CFG ILINE} Replacement algorithm Naturalmente l’algoritmo di rimpiazzamento può essere scelto solo se stiamo implementando una cache di tipo set associative. È possibile scegliere fra tre algoritmi di rimpiazzamento: random, LRU e LRR. L’algoritmo di rimpiazzamento casuale (random) utilizza un semplice contatore a 1 o 2 bit per selezionare il set ed ha un basso impatto sulle risorse hardware. Lo schema LRR utilizza un bit extra nel instruction cache tag e 119 8 – Il processore LEON3 ha quindi anch’esso un basso impatto sulle risorse hardware. Tuttavia questo schema può essere utilizzato solo se il set size e pari a 2. Lo schema LRU ha tipicamente le migliori prestazioni ma un’impatto non trascurabile sull’overhead. Per memorizzare la cronologia di accesso il 2-set LRU utilizza 1 flip-flop per linea mentre il 3-set LRU ne utilizza 3 e il 4-set LRU ne utilizza 5. {CFG IREPL} Cache locking Impostare su ‘Y’ se si vuole abilitare il cache locking sulla memoria cache per le istruzioni. Il bloccaggio può essere fatto a livello di linea. Si incrementa di un bit la dimensione dell’instruction cache tag. È preferibile disabilitare questa opzione se non vi è nessun motivo particolare. {CFG ILOCK} Enable local instruction RAM Questa opzione permette di inserisce una memoria RAM all’interno del controllore della cache per le istruzioni. Essa opera in modo simile ad una cache di secondo livello poiché le istruzioni sono salvate in questa RAM quando vengono sostituite da altre nella cache principale. L’accesso a questa RAM avviene senza accedere al bus AHB e in un solo ciclo di clock. {CFG ILRAMEN} Local instruction RAM size (kBytes) Definisce la dimensione della memoria RAM locale che può essere impostata fra i seguenti valori: 1, 2, 4, 8, 16, 32, 64, 128 e 256 kBytes. {CFG ILRAMSZ} Local data RAM start address (8 MSB) Vengono inizializzati gli 8 MSB dell’indirizzo iniziale della RAM. Come opzione di default viene proposto l’indirizzo 0×8E000000. {CFG ILRAMADDR} 8.4 Analisi del codice VHDL In questo capitolo si analizzeranno le descrizioni hardware che realizzano il sistema cache del LEON3. Attraverso il tool di simulazione “ModelSim SE PLUS 6.2c”, della Mentor Graphics Corporation, si è analizzato il funzionamento della cache per le istruzioni dando particolare attenzione al protocollo di comunicazione fra i blocchi hardware che realizzano la memoria cache. Le descrizioni VHDL che governano il funzionamento della memoria cache sono quattro e sono raggiungibili attraverso la libreria “gaisler” disponibile nel progetto ModelSim testbench.mpf oppure all’interno del direttorio ...\lib\gaisler\leno3\. I seguenti quattro file contengono le omonime entity che realizzano la memoria cache: • cache.vhd 120 8.4 – Analisi del codice VHDL Figura 8.9. LEON3MP Design Configuration, Cache System menu 121 8 – Il processore LEON3 • acache.vhd • icache.vhd • dcache.vhd L’entity cache, raffigurata in figura 8.10, descrive la memoria cache del LEON3. Si interfaccia con l’integer unit (iu3), il bus AMBA AHB e l’entity cachemem. Quest’ultima entity si preoccupa di descrivere la tipologia di memoria (e.g. RAM) più adatta alla tecnologia su cui si implementa il microprocessore. L’entity cache funge da macroblocco ovvero la corrispondente architecture ha il compito di raggruppare le altre tre descrizioni (acache, icache e dcache) all’interno di un’unica entity. cache rst clk rst clk hclk fpu_holdn hclk fpu_holdn cachemem cramo crami iu3 ahbso ahbsi ahbo ahbi ico ici dco dci AMBA AHB Figura 8.10. Entity del file VHDL cache.vhd Le entity icache e dcache si occupano rispettivamente di implementare la memoria cache per le istruzioni e per i dati1 . Le loro architecture contengono gli algoritmi necessari a realizzare tutte le funzionalità viste nei capitoli precedenti. L’entity acache è in comune fra le due precedenti e si occupa di inoltrare le richieste di trasferimento dei dati attraverso il bus AMBA AHB. In figura 8.11 è raffigurato uno schema a blocchi della struttura interna della memoria cache in cui si mettono in evidenza le entity acache e icache. 8.4.1 Entity icache In questa sezione si analizza il funzionamento dell’entity icache attraverso l’analisi di alcune righe di codice della descrizione VHDL. L’entity icache riceve attraverso 1 Il prefisso ‘i’ e ‘d’ con il quale iniziano i vari nomi, identificano rispettivamente i segnali e le variabili della cache istruzioni e dati. 122 8.4 – Analisi del codice VHDL rst clk rst clk hclk rst clk hclk icache iu3 ici ico dci dco mcii mcio acache mcii mcio AMBA AHB ahbi ahbo ahbso mcdi mcdo cachemem fpu_hold fpu_holdn icrami icramo dcache Figura 8.11. Struttura interna della memoria cache la dichiarazione di alcuni generic le impostazioni provenienti dal file di configurazione config.vhd, nella tabella 8.2 sono riportate le impostazioni necessarie al funzionamento del controllore della cache. Grazie all’utilizzo di questi valori vengono generate tutte le costanti interne all’architecture come quelle necessarie all’individuazione dei campi “TAG”, “OFFSET” e “LINE”. Nella figura 8.12 sono riportate le costanti necessarie all’individuazione di questi campi all’interno dell’indirizzo a 32 bit. Il campo “OFFSET” individua una riga all’interno della memoria cache mentre il campo “LINE” individua una word all’interno di una riga riga. generic name’s icen irepl isets ilinesize isetsize isetlock lram lramsize lramstart default value 0 0 1 1 1 0 0 1 16#8e# reference value (config.vhd) CFG ICEN CFG IREPL CFG ISET CFG ILINE CFG ISETSZ CFG ILOCK CFG ILRAMEN CFG ILRAMSZ CFG ILRAMADDR Tabella 8.2. Impostazioni dell’entity icache Come visto in precedenza il controllore dalla memoria cache delle istruzioni è collegato all’integer unit (iu3) dalla quale riceve le richieste di una data istruzione e alla memoria cachemem nella quale ripone le istruzioni precedentemente caricate 123 8 – Il processore LEON3 INDIRIZZO A 32 BIT TAG_HIGH 31 TAG_LOW OFFSET_HIGH TAG OFFSET_HIGH OFFSET LINE_LOW 2 LINE_HIGH 1 0 LINE Figura 8.12. Disposizione dei campi “TAG”, “OFFSET” e “LINE” all’interno di un’indirizzo. dalla memoria esterna. Ogni qualvolta che l’integer unit fa richiesta di una nuova istruzione il controllore della cache si attua alla ricerca di quest’ultima all’interno della memoria cache. Se l’istruzione è presente all’interno della memoria cache saremo nella condizione di cache hit e l’evento sarà segnalato memorizzando il valore logico uno nella variabile hit. Come mostra il seguente frammento di codice il controllore della memoria cache attraverso il segnale ici.fpc riceve dall’integer unit l’indirizzo dell’istruzione e attraverso il segnale icramo ha accesso alla memoria cache. --generate cache hit and valid bit hit := ’0’; for i in ISETS-1 downto 0 loop if (icramo.tag(i)(TAG_HIGH downto TAG_LOW) = ici.fpc(TAG_HIGH downto TAG_LOW)) then hit := not r.flush; set := i; end if; validv(i) := genmux(ici.fpc(LINE_HIGH downto LINE_LOW), icramo.tag(i)(ilinesize -1 downto 0)); end loop; {omissis} valid := validv(set); Questo pezzo di codice VHDL evidenzia come la ricerca dell’istruzione è fatta in tutti i set della memoria cache confrontando il campi TAG dell’indirizzo proveniente dell’integer unit con il campo TAG dell’instruction cache tag proveniente dalla memoria cache. Se siamo in condizione di cache miss ovvero se l’istruzione richiesta non è presente all’interno della memoria cache il controllore della memoria farà richiesta di trasferimento dalla memoria principale. Il controllore della cache delle istruzioni è realizzato attraverso la descrizione di una macchina a stati finiti. Il suo funzionamento, basato sull’utilizzo di tre stati, è riassunto qui di seguito. 124 8.4 – Analisi del codice VHDL streaming state Per realizzare il trasferimento dei dati dalla memoria principale all’integer unit, il controllore della cache delle istruzioni inoltra tale esigenza all’entity acache. Questa unità funzionale ha il compito di interfacciare i controllori della memoria cache delle istruzioni e dei dati con il bus AMBA AHB attraverso la generazione degli opportuni segnali definiti dal protocollo. Entrambi i controllori necessitano del bus AMBA per effettuare sia i trasferimenti in lettura (icache e dcache) che quelli in scrittura (dcache) ed i segnali che accompagnano queste richieste sono elaborati dall’acache alfine di garantire una corretta comunicazione. Il controllore della memoria cache delle istruzioni comunica con questa unità attraverso il segnale mcii. Questo segnale è aggiornato dai segnali del registro di stato r definiti nel tipo icache control type che riceve conferma delle operazioni da effettuare attraverso il segnale mcio. I segnali mcii e mcio sono del tipo memory ic in type e memory ic out type definiti nel package libcache contenuto nel file libcache.vhd. type memory_ic_in_type is record address : std_logic_vector(31 downto 0); -- memory address burst : std_ulogic; -- burst request req : std_ulogic; -- memory cycle request su : std_ulogic; -- supervisor address space flush : std_ulogic; -- flush in progress end record; type memory_ic_out_type is record data : std_logic_vector(31 downto 0); -- memory data ready : std_ulogic; -- cycle ready grant : std_ulogic; -retry : std_ulogic; -mexc : std_ulogic; -- memory exception cache : std_ulogic; -- cacheable data par : std_logic_vector(3 downto 0); -- parity end record; Il bus AMBA permette trasferimenti di tipo single ovvero in cui viene trasferita una sola word e trasferimenti di tipo burst in cui più word vengono trasferite a partire da un dato indirizzo. I trasferimenti di tipo burst implementati dal bus AMBA sono di due tipi: • burst di tipo incrementale (incrementing burst) • burst di tipo ciclico (wrapping burst) 125 8 – Il processore LEON3 Il burst di tipo ciclico non è utilizzato dal microprocessore LEON3 il quale per trasferimenti di dati contigui utilizza la modalità incrementale di lunghezza non definita. A determinare la fine del trasferimento in corso è il controllore della cache in base anche alla lunghezza della linea di cache che come precedentemente descritto può essere di 16 o 32 byte. La strategia di utilizzare burst di lunghezza indefinita permette di utilizzare diverse configurazioni di memoria cache senza dover modificare nessun segnale di controllo inerente alle gestione del trasferimento. Senza entrare nel dettaglio implementativo sono i segnali di stato overrun e underrun a gestire quest’ultimo aspetto; infatti il primo dei due segnali permette di sincronizzare le operazioni di trasferimento in modalità burst con l’integer unit, mentre il secondo segnale interrompe il trasferimento in modalità burst quando è necessario prelevare della memoria principale un’istruzione che non è in sequenza con le altre. rst clk mcii.address 00000000 00000004 00000008 0000000C mcii.req mcii.burst mcii.su mcii.flush mcio.data FFFFFFFF 81D82000 FFFFFFFF 03000004 FFFFFFFF 821060E0 FFFFFFFF mcio.ready mcio.grant mcio.retry mcio.mexc mcio.cache mcio.par UUUU Figura 8.13. Simulazione di trasferimento dati in modalità single La figura 8.13 mostra una simulazione in cui viene richiesto da parte dell’icache un trasferimento di dati di tipo single. I segnali rappresentati sono il segnale di reset (rst), quello di clock (clk) e i segnali mcii e mcio precedentemente descritti. Si premette che il segnale mcii.flush che segnale lo stato di flushing della memoria cache viene ignorato dall’acache cosı̀ come il segnale mcio.par non è utilizzato dell’icache. Molto probabilmente questi segnali verranno impiegati in future versioni del microprocessore LEON per implementare nuove funzioni. Il protocollo per lo scambio dei dati è abbastanza semplice e si può cosı̀ riassumere: 126 8.4 – Analisi del codice VHDL • L’entity icache avverte l’acache di una richiesta di trasferimento dati ponendo a livello logico alto il segnale di request mcii.req fin tanto che l’entity acache non le concede il trasferimento dei dati ponendo a livello logico alto il segnale di grant mcio.grant. In questa simulazione il trasferimento viene concesso immediatamente ma questo è solo un caso particolare. È possibile che si verifichi la condizione in cui il segnale di request deve essere mantenuto alto per diversi cicli di clock prima di ricevere la concessione; questo evento si verifica raramente poiché l’entity icache ha la precedenza rispetto l’entity dcache e a loro volta, le due entity, hanno precedenza fra tutti i master del bus AMBA AHB. Quando il segnale di request è posto a livello logico alto l’entity acache si preoccupa di aver impostato sul bus degli indirizzi mcii.address l’indirizzo dell’istruzione da scaricare. Il segnale mcii.burst è mantenuto a livello logico basso poiché si sta effettuando un trasferimento in modalità single. Infine il segnale mcii.su è sempre posto a livello logico alto, almeno in tutte le simulazioni eseguite. • L’entity acache comunica la concessione del trasferimento impostando a livello logico alto il segnale di grant mcio.grant. In questo instante vengono generati tutti i segnali di richiesta trasferimento dati sul bus AMBA AHB. Il segnale di grant, nel caso di trasferimento single, rimane a livello logico alto per un solo ciclo di clock. Terminato il ciclo di lettura attraverso il bus AMBA AHB l’entity acache avverte la presenza del dato pronto ponendo a livello logico alto il segnale di ready mcio.ready per un ciclo di clock. Contemporaneamente a quest’evento sul bus dati mcio.data è disponibile l’istruzione e il segnale mcio.cache assume il valore logico uno o zero rispettivamente per indicare se l’istruzione e cacheable oppure no. Il segnale di retry mcio.retry viene posto a livello logico alto se il bus AMBA AHB a seguito di una richiesta di trasferimento dati comunica sul segnale di servizio ahbi.hresp la condizione di retry (HRESP RETRY) o di split (HRESP SPLIT). L’entity icache risponde a tale eventualità con una nuova richiesta di trasferimento dati sul medesimo indirizzo. Infine il segnale che indica l’evento di memory exception è posto a livello logico alto quando il segnale di servizio ahbi.hresp comunica l’evento di errore (HRESP ERROR). L’evento di memory exception può verificarsi a seguito di una lettura su un indirizzo inesistente. Per maggiori informazioni sul funzionamento del bus AMBA si veda il manuale [54]. Naturalmente se i segnali di retry o memory exception sono a livello logico alto la lettura non è andata a termine e i dati presenti sul bus mcio.data non sono validi. La figura 8.14 mostra invece la richiesta di un trasferimento dati nella modalità 127 8 – Il processore LEON3 rst clk mcii.address 00000040 0000003C 00000044 00000048 0000004C 00000050 00000054 00000058 0000005C A0100000 A2100000 A4100000 A6100000 A8100000 AA100000 AC100000 00000060 mcii.req mcii.burst mcii.su mcii.flush mcio.data 8C100000 FFFFFFFF 8E100000 FFFFFFFF mcio.ready mcio.grant mcio.retry mcio.mexc mcio.cache mcio.par UUUU Figura 8.14. Simulazione di trasferimento dati in modalità incrementing burst incrementing burst. In questo caso il protocollo per lo scambio dei dati differisce per l’utilizzo da parte dell’entity acache del segnale di burst mcii.burst. Il segnale di burst è mantenuto a livello logico alto finché si desidera inoltrare una nuova richiesta di trasferimento dati. Il vincolo è che la nuova richiesta di trasferimento dati deve avere un’indirizzo contiguo alla precedente richiesta; se la precedente richiesta aveva come obbiettivo l’istruzione con indirizzo i la nuova richiesta dovrà essere fatta sull’indirizzo i + 4 (si ricorda che sul bus AMBA vengono trasferite parole da 32 bit ovvero da 4 byte). Sul bus degli indirizzi mcii.address deve comparire il nuovo indirizzo al colpo di clock successivo alla ricezione del segnale di ready. Per terminare un trasferimento nella modalità incrementing burst è sufficiente abbassare a livello logico basso il segnale di burst. Come si nota nella figura 8.14 per semplicità vengono alzati e abbassati contemporaneamente i segnali di request e burst. L’entity acache effettua solitamente una trasferimento dati che dura un’intera linea di cache come mostrato in figura 8.14 dove vengono scaricate 8 word (i.e. 32 byte) dalla memoria principale. Ogni istruzione prelevata dalla memoria principale viene memorizzata nella memoria cache insieme al instruction cache tag, solo se la cache delle istruzioni non è disabilitata o se l’operazione di flush non è in corso. È proprio quest’istruzione a decidere quale sarà il successivo stato della macchina a stati finiti del controllore della memoria cache una volta terminato lo streaming state. Infatti se è in corso l’esecuzione di una istruzione di flush la macchina 8000000 9000000 Entity:testbench Architecture:behav Date: Wed May 09 20.03.33 ora solare Europa occidentale 2007 Row: 1 Page: 1 128 10000000 8.4 – Analisi del codice VHDL a stati tornerà al main state, altrimenti si porterà al return state. main state Una volta aggiornati i registri dei segnali di stato si decide chi dovrà fornire l’istruzione indirizzata dall’integer unit. Se tale risorsa è presente nella memoria cache, sarà quest’ultima a fornirla. Nel caso non fosse possibile prelevare l’istruzione direttamente dalla memoria cache la macchina a stati finiti dalla cache delle istruzioni si porta in streaming state, come visto in precedenza. return state Questo stato dura un solo ciclo di clock è vengono impostate alcune variabili interne all’entity. Lo stato successivo è il main state. 129 8 – Il processore LEON3 130 Capitolo 9 Leon3MP Crittografico In questo capitolo vengono illustrate le modifiche apportate al microprocessore LEON3MP (capitolo 8.3.2) affinchè possa eseguire istruzioni cifrate memorizzate su di una memoria esterna al microprocessore. Le scelte progettuali sono rivolte a realizzare un’unità cifrante trasparente al microprocessore ed in grado di ridurre al minimo la perdita di prestazioni in termini di tempo di accesso alla memoria esterna. L’architettura sviluppata è in grado di intercettare le richieste di trasferimento dati fatte dalla CPU verso l’area di memoria cifrata e di eseguire le operazioni necessarie per la decifratura parallelamente alle operazioni di fetch dei dati dalla memoria. Questo permette di minimizzare la perdita di performance del microcontrollore. Il sistema proposto segue le linee guida illustrate nel capitolo 7 e garantisce un giusto compromesso fra il livello di cifratura raggiunto e perdita di performance introdotte. 9.1 Modifiche apportate al codice VHDL Nel capitolo 8 è stata presentata l’architettura del microcontrollore LEON3 con particolare enfasi sull’architettura della memoria cache. Lo schema a blocchi della struttura della memoria cache è raffigurato in figura 9.1. Lo schema a blocchi mette in evidenzia le entity acache e icache: la prima si preoccupa di inoltrare le richieste di trasferimento dati sul bus AMBA AHB mentre la seconda implementa il controllore della memoria cache per le istruzioni. Le due entity comunicano attraverso i segnali mcii e mcio. Sinteticamente, sul primo segnale transitano le richieste di trasferimento dati mentre sul secondo segnale transitano i dati richiesti. Per maggiori informazioni sul funzionamento della memoria cache si veda il capitolo 8.4. Secondo lo schema proposto da Best, capitolo 7.2, l’unità cifrante deve essere posta fra la memoria cache ed il controllore della memoria esterna. In accordo con questo enunciato è stata modificata l’entity cache del microprocessore Leon3MP 131 9 – Leon3MP Crittografico rst clk rst clk rst clk hclk hclk icache iu3 ici ico dci dco mcii mcio acache mcii mcio AMBA AHB ahbi ahbo ahbso cachemem mcdi mcdo fpu_holdn fpu_hold icrami icramo dcache Figura 9.1. Struttura interna della memoria cache prima delle modifiche affinchè possa accogliere l’unità cifrante. In figura 9.2 è raffigurato lo schema a blocchi della struttura interna dell’entity cache dopo le modifiche. Il nuovo schema a blocchi si differenzia dal precedente per la presenza dell’entity sniffer mci. L’entity sniffer mci monitorizza costantemente le richieste di trasferimento dati che transitano sul segnale mcii e nel caso in cui venga richiesto un trasferimento dati dalla zona di memoria in cui sono contenute le istruzioni cifrate si attiva per poterle decifrare. rst clk hclk rst clk hclk acache AMBA AHB mcii mcio ahbi ahbo ahbso mcdi mcdo rst clk rst clk sniffer_mci mcii_o mcio_i icache mcii mcio mcii_i mcio_o iu3 ici ico dci dco dcache fpu_hold fpu_holdn cachemem icrami icramo Figura 9.2. Struttura interna della memoria cache dopo le modifiche L’entity sniffer mci si interfaccia con il controllore della memoria cache per le istruzioni (icache) attraverso i segnali mcii i e mcio o; mentre si interfaccia con l’entity acache attraverso i segnali mcii o e mcio i. Se il controllore della memoria cache per le istruzioni inoltra una richiesta di trasferimento di istruzioni da una zona di memoria contenente istruzioni in chiaro (non cifrate), il modulo cifrante non altera il flusso di informazioni che transitano 132 9.1 – Modifiche apportate al codice VHDL sui segnali mcii e mcio. Viceversa se il controllore della memoria per le istruzioni richiede il trasferimento di dati proveniente da una zona di memoria contenente istruzioni cifrate, il modulo cifrante si attiva e modifica il flusso di informazioni che transitano sui segnali mcii e mcio. La modifica del flusso di informazioni avviene in accordo con il protocollo di trasferimento dati analizzato nel capitolo 8.4 cosicché sia il controllore della memoria per le istruzioni (icache) che l’entity acache non si accorgano dell’attività svolta dall’unità cifrante. In altri termini l’unità cifrante è trasparente sia all’entity icache che all’entity acache. La completa trasparenza dell’unità cifrante ha permesso di ridurre al minimo gli interventi sul codice VHDL del microprocessore Leon3MP. Infatti, gli unici interventi fatti sul codice VHDL riguardano l’entity cache contenuta nell’omonimo file cache.vhd. Qui di seguito è riportato parte del codice VHDL dell’entity cache che mostra le uniche modifiche effettuate: sniffer_off : if (not SNIFFER_EN) generate begin icache0 : icache generic map ({omissis}) port map ({omissis}); dcache0 : dcache generic map ({omissis}) port map ({omissis}); a0 : acache generic map ({omissis}) port map ({omissis}); ico <= icol; dco <= dcol; end generate; sniffer_on : if SNIFFER_EN generate signal mcii_byp : memory_ic_in_type; signal mcio_byp : memory_ic_out_type; begin icache0 : icache generic map ({omissis}) port map ({omissis}); dcache0 : dcache generic map ({omissis}) port map ({omissis}); a0 : acache generic map ({omissis}) port map ({omissis}); sniffer0 : sniffer_mci port map(rst, clk, mcii, mcii_byp, mcio, mcio_byp); ico <= icol; 133 9 – Leon3MP Crittografico dco <= dcol; end generate; Attraverso l’uso di due generate è possibile inserire oppure no il modulo cifrante modificando il valore della variabile booleana SNIFFER EN. Le modifiche apportate hanno permesso di creare per il microprocessore Leon3MP una nuova feature, ovvero la possibilità da parte dell’utente finale di attivare oppure no la funzionalità di cifratura delle istruzioni. 9.2 Principio di funzionamento dell’unità cifrante L’unità cifrante sviluppata prevede l’utilizzo del core crittografico AES128 sviluppato nel capitolo 6. L’utilizzo dello standard di cifratura AES conferisce al nostro sistema il massimo in termini di sicurezza dell’algoritmo cifrante, infatti, come visto nei capitoli introduttivi l’AES è lo standard di riferimento per gli algoritmi di cifratura a chiave simmetrica. La modalità di funzionamento prescelta per la cifratura dei dati è la OFB in modalità counter mode, capitolo 4.4. Questa modalità di funzionamento è anche nota col nome CTR (CounTeR) ed è la modalità che più si adatta alle problematiche di accesso casuale ai dati. Infatti questa è l’unica modalità, fatta eccezione per l’ECB scartata per la sua bassa affidabilità, che permette di decifrare un blocco senza dover decifrare il precedente. Prima di analizzare nel dettaglio l’implementazione dell’unità cifrante è bene spendere alcune parole sulle modalità di indirizzamento e trasferimento dei dati nel microprocessore Leon3. Come nei moderni microprocessori anche il microprocessore Leon3 indirizza la memoria al byte ma esegue le operazioni a livello di word (4 byte): istruzioni e dati hanno dimensione pari a una word. Il trasferimento delle istruzioni e dei dati avviene attraverso il bus AMBA che è anch’esso a 32 bit, ne consegue che ad ogni ciclo di trasferimento dati dalla memoria principale si ha a disposizione un’istruzione o un dato. Nella figura 9.3 è raffigurata una generica memoria con ampiezza dei dati pari a una word; si noti come blocchi adiacenti di memoria hanno l’indirizzo che differisce di 4 l’uno dall’altro. La modalità CTR, utilizzata per la cifratura dei dati, si basa sulla generazione di un keystream che viene posto in XOR con i dati in chiaro. La dimensione del keystream è pari a 128 bit (standard AES) e questo implica che i dati in chiaro prima del processo di codifica debbano essere suddivisi in blocchi di pari dimensione. Questa procedura permette un’accesso casuale al flusso cifrato anche a livello di bit; ovvero è possibile accede a parte dei bit contenuti in ciascun blocco generando il keystream associato. Questa procedura naturalmente è poco efficiente poiché, nel caso più sfavorevole di accesso ad un singolo bit del blocco, è necessario generare tutti i 128 bit del keystream associato. 134 9.2 – Principio di funzionamento dell’unità cifrante 32 bit (4 byte) AES_IV + (A - CIPHER_INSTR_START) CIPHER_INSTR_START Blocco AES_KEY A Blocco #0 A+4 Blocco #1 A+8 Blocco #2 A + 12 Blocco #3 CIPHER_INSTR_END KEY DATA AES128 Keystream Blocco OUT MEMORIA ESTERNA Figura 9.3. Principio di funzionamento dell’unità cifrante Ciascun blocco AES può essere visto come il raggruppamento di quattro word. Nel caso in cui il gestore della memoria cache inoltra una richiesta di trasferimento dati di una specifica word è necessario per la sua decodifica generare il keystram associato all’intero blocco AES contenente la word desiderata. Questo introduce una perdita di efficienza da parte dell’unità cifrante. Ciò nonostante è bene tenere presente che il microprocessore Leon3MP dispone di una memoria cache e nel caso si verifica un cache miss il gestore della memoria cache inoltra il trasferimento dati di un’itera riga di memoria cache. La dimensione di una riga di cache è multiplo del blocco AES e quindi l’efficienza dell’unita cifrante, come fino ad ora intesa, è piena. In figura 9.3 è mostrato lo schema di principio utilizzato per la decodifica delle istruzioni contenute nella memoria esterna supponendo di voler decodificare una delle word, contenute nel range di indirizzi ‘A’÷‘A+4’. Il core AES128 che è impostato per funzionare in modalità CTR necessita per la generazione del keystream della chiave di cifratura AES KEY e del valore del contatore. Ciascun blocco AES è codificato con un valore del contatore differente; in linea di principio non vi è nessun vincolo sulla generazione di questo numero, quindi per motivi pratici (si veda il capitolo successivo) si è associato il valore 0 (zero) al primo blocco AES cifrato, 16 al secondo blocco, 32 al terzo e cosi via. Questi valori corrispondono all’indirizzo “virtuale” della prima word che compone il blocco AES. Per irrobustire questa modalità di codifica, in accordo con le direttive proposte per lo standard AES, viene sommato all’indirizzo “virtuale” un vettore costante AES IV che garantisce, tra le altre cose, una maggior sicurezza nel caso di attacchi di tipo “forza bruta”. 135 9 – Leon3MP Crittografico 9.3 Entity sniffer mci In questo capitolo viene descritto il funzionamento dell’entity sniffer mci attraverso l’analisi del codice VHDL che la descrive. La descrizione delle funzionalita dell’entity è avvenuta attraverso la descrizione in linguaggio VHDL di una macchina a stati finiti composta da 7 stati: • BYPASS • WAIT GRANT • REQ BURST • WAIT AES • SEND SINGLE • SEND BURST • WAIT REQ Il diagramma della macchina a stati finiti è presentato in figura 9.4. Ciascun stato della macchina a stati finiti pilota oltre che i segnali di output dell’entity (mcii o e mcio o) anche i segnali di ingresso al core AES128 (aesi) e il registro di controllo interno. Il suo funzionamento è riassunto qui di seguito: BYPASS È lo stato principale della macchina a stati finiti. In questo stato non viene alterato il flusso di informazioni che transitano sui segnali mcii e mcio. Lo stato di BYPASS analizza costantemente le informazioni che transitano sul segnale mcii e nel caso in cui si verifica la richiesta di trasferimento dati da una locazione di memoria cifrata si attiva per modificare le informazioni che transitano sui segnali sopracitati. In particolare monitorizza il livello logico del segnale flag add che assume il livello logico ‘1’ se l’indirizzo contenuto nel segnale mcii i.adress è compreso fra i valori CIPHER INSTR START e CIPHER INSTR END. Questi ultimi due valori corrispondono all’indirizzo iniziale e finale dell’area di memoria contenente istruzioni cifrate e sono inizializzati nella libreria contenuta nel file libsniffer.vhd. Se si verifica l’evento di richiesta trasferimento dati (mcii i.req = ‘1’) in un’area di memoria cifrata (flag add = ‘1’) il flusso di dati fra il controllore della memoria cache per le istruzioni (icache) e l’entity acache viene alterato. L’entity sniffer mci segnala al controllore della memoria cache per le istruzioni l’accoglimento della richiesta trasferimento dati 136 9.3 – Entity sniffer mci not rst not(mcii_i.req and aesi <= (AES_KEY, mcii_o mcio_o flag_add) ctr, '0') <= mcii_i <= mcio_i BYPASS mcii_i.req and flag_add aesi <= (AES_KEY, ctr, '1') mcii_o <= (ass, '1', '1') mcio_o <= (cmem, '0', '1', s.cac(i)) s_v.tag := add(31 downto 4) _i.grant not mcio not mcio_i.grant mcio_i.g ra not mcio_i.ready nt REQ_BURST WAIT_GRANT aesi <= (AES_KEY, ctr, '0') mcii_o <= (add, '1', '1') mcio_o <= (cmem, '0', '0', s.cac(i)) aesi <= (AES_KEY, ctr, '0') mcii_o <= (add, (not lastreq), (not lastreq)) mcio_o <= (cmem, '0', '0', s.cac(i)) mcio_i.ready s_v.mem(n) := mcio_i.data s_v.cac(n) := mcio_i.cache s_v.word := unsigned(s.word)+1 mcio_i.grant not aeso.end_conv not WAIT_AES wo last rd lastword not aeso.end_conv aesi <= (AES_KEY, ctr, '0') mcii_o <= (add, '0', '0') mcio_o <= (cmem, '0', '0', s.cac(i)) aeso.end_conv mcii_i.burst SEND_BURST SEND_SINGLE aesi <= (AES_KEY, ctr, '0') mcii_o <= (add, '0', '0') Aesi <= (AES_KEY, ctr, '0') mcii_o <= (add, '0', '0') mcio_o <= (cmem, '1', '0', scac(i)) lastsend mcio_o <= (cmem, '1', '0', s.cac(i)) not lastsend mcio_o <= (cmem, '1', mcii_i.req, s.cac(i)) mcii_i.req WAIT_REQ not fl ag_tag not mcii_i.req aesi <= (AES_KEY, ctr, '0') mcii_o <= (add, '0', '0') mcio_o <= (cmem, '0', '0', s.cac(i)) not mcii_i.burst aeso.end_conv ii mc . _i q re not mcii_i.req flag_tag aesi <= (AES_KEY, ctr, '0') mcii_o <= (add, '0', '0') mcio_o <= (cmem, '0', '1', s.cac(i)) not mcii_i.burst SEND_SINGLE mcii_i.burst SEND_BURST flag_add aesi <= mcii_o <= mcio_o <= s_v.tag (AES_KEY, ctr, '1') (add, '1', '1') (cmem, '0', '1', s.cac(i)) := add(31 downto 4); not mcio_i.grant WAIT_GRANT mcio_i.grant REQ_BURST not flag_add aesi <= (AES_KEY, ctr, '0') mcii_o <= mcii_i mcio_o <= mcio_i BYPASS NOTA: mcii_o <= (address, burst, req, su <= ‘1’, flush <= ‘0’) mcio_o <= (data, ready, grant, retry <= ‘1’, mexc <= ‘0’, cahce, par <= “0000”) Figura 9.4. Diagramma della macchina a stati finiti dell’entity sniffer mci 137 9 – Leon3MP Crittografico (mcio o.grant = ‘1’) e lo mette in attesa (mcio o.ready = ‘0’). Parallelamente a queste operazioni inoltra una richiesta di trasferimento dati all’entity acache e da il segnale di start al core AES128 per la generazione del keystream. Eseguite queste operazioni, prima di passare allo stato successivo: WAIT GRANT o REQ BURST in base alo stato del segnale mcio i.grant, salva il tag address dell’indirizzo. La memorizzazione del tag address permette alla macchina a stati finiti di capire se le future richieste di trasferimento dati possono essere soddisfatte senza inoltrare una specifica richiesta alla memoria esterna. WAIT GRANT Questo è uno stato di attesa e non vengono eseguite operazioni particolari. Viene monitorizzato il segnale di grant mcio i.grant proveniente dell’entity acache che comunica l’accettazione della richiesta di trasferimento dati (mcio i.grant = ‘1’). Il successivo stato è: REQ BURST. REQ BURST In questo stato viene eseguito il trasferimento delle 4 word che compongono il blocco AES contenente la word richiesta dal controllore della memoria cache. Il trasferimento dati dalla memoria principale avviene nella modalità incrementing burst che permette di ridurre il tempo necessario al trasferimento dati rispetto alla modalità single. Lo stato monitorizza il segnale di ready (mcio i.ready) e il segnale interno lastword per determinare la fine delle richiesta di trasferimento dati. Il segnale lastword assume il livello logico alto in occasione del trasferimento dell’ultima word. Infine, lo stato si preoccupa anche di salvare ogni word scaricata (mcio i.data) e il segnale di cacheable (mcio i.cache) in un apposito registro. Finita l’operazione di download delle istruzioni dalla memoria principale si passa allo stato successivo; se il segnale di fine conversione del core AES128 è a livello logico basso, lo stato successivo è WAIT AES in cui si attende la generazione del keystream. Viceversa, se l’operazione di generazione del keystream è più veloce del download delle 4 word si passa allo stato SEND SINGLE o SEND BURST in base alla richiesta fatta dal controllore della memoria cache (mcii i.burst). WAIT AES Il WAIT AES è uno stato di attesa e non vengono eseguite operazioni particolari. Viene monitorizzato il segnale di fine conversione aeso.end conv proveniente core AES128 che comunica la fine dell’elaborazione del keystream (aeso.end conv = ‘1’). Il successivo stato è SEND SINGLE o SEND BURST in base alla richiesta fatta dal controllore della memoria cache (mcii i.burst). SEND SINGLE Se il controllore della memoria cache per le istruzioni ha richiesto un trasferimento dati in modalità single (mcii i.burst = ‘0’) questo è lo stato che permette il trasferimento dati in questa modalità. In particolare vengono trasmessi al controllore della memoria cache l’istruzione desiderata, dopo l’opportuna decifratura, e il segale di cacheable. Per comunicare la disponibilità 138 9.4 – Simulazione del microprocessore Leon3MP crittografico al trasferimento dei dati lo stato modifica il livello logico del segnale di ready (mcii o.ready = ‘1’). Lo stato successivo è lo stato di attesa WAIT REQ. SEND BURST Questo stato permette il trasferimento dei dati in modalità incrementing burst richiesta dal controllore della memoria cache per le istruzioni attraverso il segnale mcii i.burst. Questa modalità permette il trasferimento rapido delle 4 word precedentemente scaricate verso il controllore della memoria cache. Per comunicare la disponibilità al trasferimento dei dati lo stato modifica il livello logico del segnale di ready (mcii o.ready = ‘1’). Per determinare la fine del trasferimento, ovvero per determinare la fine della disponibilità di istruzioni decifrate, lo stato monitorizza il segnale lastsend che assume il valore logico ‘1’ in corrispondenza dell’ultima word disponibile. Nel caso in cui il controllore della memoria cache richieda ulteriori istruzioni la macchina a stati si attiva per richiedere il trasferimento del blocco successivo dalla memoria principale. Durante questi ultimi tre stati: WAIT AES, SEND SINGLE e SEND BURST l’entity sniffer mci congela la comunicazione con l’entity acache comunicando l’intenzione di non procedere ad un trasferimento dati (mcii o.req = ‘0’ e mcii o.burst = ‘0’). WAIT REQ Questo stato è uno stato transitorio e la macchina a stati finiti vi rimane fin tanto che non arriva una successiva richiesta di trasferimento dati (mcii i.req = ‘1’). Lo stato successivo dipende dallo stato dei seguenti due segnali logici: flag tag e flag add. Se il segnale flag tag è livello logico alto significa che la successiva richiesta di trasferimento dati fa richiesta di un’istruzione già scaricata dalla memoria principale e dunque lo stato futuro è SEND SINGLE o SEND BURST. Se il livello logico del segnale flag tag è zero lo stato verifica se l’indirizzo della successiva istruzione fa parte dell’area di memoria cifrata. Se l’istruzione appartiene all’area di memoria cifrata lo stato futuro è WAIT GRANT o REQ BURST, altrimenti lo stato futuro è lo stato principale: BYPASS. 9.4 Simulazione del microprocessore Leon3MP crittografico In questo capitolo vengono presentati i risultati della simulazione del microprocessore Leon3MP crittografico eseguiti con il tool di simulazione “ModelSim SE PLUS 6.2c” della Mentor Graphics Corporation. La simulazione è stata eseguita utilizzando il “Demonstration design test bench” fornito all’interno della libreria GRLIB IP. Il test bench esegue una programma di 139 9 – Leon3MP Crittografico test che controlla il coretto funzionamento della CPU e delle periferiche ad essa connesse. La configurazione del microprocessore Leon3MP è ininfluente, ovvero non vi sono vincoli per i moduli che si intende implementare. In particolare l’unità cifrante sviluppata può lavorare correttamente con qualsiasi configurazione della memoria cache e anche in sua assenza. Per un’analisi più accurata dei risultati viene riassunta qui di seguito (tabella 9.1) la configurazione del microprocessore Leon3MP utilizzato per la simulazione. Tabella 9.1. Impostazioni del Leon3MP utilizzato per la simulazione PARAMETRO Synthesis: Target technologies Infer RAM Infer pads Disable asynchronous reset Clock generation: Clock generator Clock multiplication factor Clock division factor Enable Xilinx CLKDLL for PCI clock Disable external feedback for SDRAM clock Use PCI clock as system clock Processor: Enable Leon3 SPARC V8 Processor Number of processors Integer unit: SPARC register windows SPARC V8 MUL/DIV instructions Single-vector trapping Load delay Hardware break point Enable power-down mode Reset start address (addr[31:12]) Floating-point unit: Enable FPU Cache system: Enable instruction cache 140 VALORE Xilinx-Virtex2 No No No Xilinx-DCM 2 2 No No No Yes 1 8 No No 1 0 No 00000 No Yes 9.4 – Simulazione del microprocessore Leon3MP crittografico -Associativity (sets) -Set Size (kbyte/sets) -Line size (bytes/line) -Enable local instruction RAM Enable data cache -Associativity (sets) -Set Size (kbyte/sets) -Line size (bytes/line) -Enable local data RAM -AHB snooping -Fixed cacheability map MMU: Enable MMU Debug Support Unit: Enable Leon3 Debug support unit VHDL debug setting: Processor disassembly to console 32-bit program counters AMBA Configuration: Default AHB Master Round-robin arbiter AHB split-transaction support I/O area start address (haddr[31:20]) AHB/APB bridge address (haddr[31:20]) Debug Link: Serial Debug Link (RS232) JTAG Debug Link Peripherals, Memory controllers: 8/32-bit PROM/SRAM controller Enable 8/32-bit PROM/SRAM controller Leon2 memory controller Enable Leon2 memory controller 8-bit PROM/SRAM bus support 16-bit PROM/SRAM bus support 5th SRAM chip-select SDRAM controller Separate address and data buses 141 1 4 32 No Yes 1 4 32 No No 0 No No No No 0 Yes No FFF 800 Yes No No Yes No No No Yes No 9 – Leon3MP Crittografico PC133 SDRAM controller Enable PC133 SDRAM controller Peripherals, On-chip RAM/ROM: On-chip AHB ROM On-chip AHB RAM Peripherals, Ethernet: Gaisler Research 10/100/1000 Mbit Ethernet MAC Peripherals, CAN: Enable CAN interface Peripherals, Spacewire: Enable Spacewire link Peripherals, PCI: PCI interface, target-only PCI vendor ID PCI device ID PCI arbiter Enable PCI trace buffer Peripherals, UARTs (timer and irq control): Enable console UART UART1 FIFO depth Enable secondary UART UART2 FIFO depth Enable Leon3 interrupt controller Enable Timer Unit Number of timers Scaler width Timer width Timer unit interrupt Separate interrupts Watchdog enable Enable generic GPIO port VHDL Debugging: Accelerated UART tracing No No No No No No Yes 16E3 0210 No No Yes 1 Yes 1 Yes Yes 2 8 32 8 No No No Yes Al fine di validare il funzionamento del modulo crittografico sviluppato sono state eseguite due simulazioni. 142 9.4 – Simulazione del microprocessore Leon3MP crittografico 9.4.1 Prima simulazione La prima delle due simulazione è stata eseguita per validare il funzionamento della macchina a stati finiti descritta nel capitolo 9.3. Questa simulazione è molto importante perché permette di testare il funzionamento del protocollo per la trasmissione dati realizzato. Per prima cosa la simulazione prevedono il settaggio delle costanti SNIFFER EN, CIPHER INSTR START e CIPHER INSTR END contenute nella libreria libsniffer.vhd. Le impostazioni prevedono innanzitutto l’abilitazione dell’unità cifrante e la definizione del range di memoria, su cui effettuare la decifratura delle istruzioni, su tutto il range di indirizzamento delle memorie. Il range di indirizzamento delle memorie, per il Leon3MP, è deducibile dalla tabella 8.1. Le impostazioni di questa simulazione sono riassunte in tabella 9.3. PARAMETRO SNIFFER EN CIPHER INSTR START CIPHER INSTR END VALORE true 0x00000000 0x7FFFFFFF Tabella 9.2. Impostazioni per la prima simulazione del Leon3MP Crittografico Successivamente è necessaria una modifica all’entity sniffer mci. La modifica prevede l’eliminazione dell’operazione di XOR fra il keystream e l’istruzione prelevata dalla memoria esterna. Questa modifica è ininfluente per il funzionamento della macchina a stati finiti e permette di testare tutte le funzionalità dell’unità cifrante senza necessariamente cifrare le istruzioni. La modifica effettuata prevede lo scambio del segno di commento ‘--’ fra le seguenti due righe, contenute nel file sniffer mci.vhd: cmem := s.mem(i) xor out_txt_slv(32*(3-i)+31 downto 32*(3-i)); --cmem := s.mem(i); --necessario per la simulazione In figura 9.5 è mostrata una parte della simulazione in cui si mette in evidenza un trasferimento dati in modalità single, viceversa in figura 9.6 è mostrato un trasferimento in modalità incrementing burst. Come è possibile notare l’unità cifrante è sempre attiva e esegue in maniera corretta le operazioni di trasferimento dei dati e di controllo del core AES128. Grazie a questo tipo di simulazione è possibile stimare la perdita di prestazioni introdotte dall’unità cifrante. La stima della perdita delle prestazioni è stata valutata misurando il tempo necessario ad eseguire l’intero processo di benchmark con e senza l’unità cifrante. Senza l’unità cifrante il test bench ha terminato le suo operazioni dopo 44.305 cicli di clock, mentre con l’unità cifrante inserita il test bench 143 9 – Leon3MP Crittografico rst clk mcii_i mcii_i.address 00000000 00000004 00000008 0000000C 00000010 mcii_i.req mcii_i.burst mcii_i.su mcio_i mcio_i.data FFFFFFFF 81D82000 03000004 821060E0 81884000 FFFFFFFF 00000004 00000008 0000000C 00000000 00000010 81900000 mcio_i.ready mcio_i.grant mcio_i.retry mcio_i.mexc mcio_i.cache mcii_o mcii_o.address 00000000 mcii_o.req mcii_o.burst mcii_o.su mcio_o mcio_o.data FFFFFFFF 00000000 81D82000 03000004 821060E0 81884000 81D82000 wait_req wait_req wait_req wait_req mcio_o.ready mcio_o.grant mcio_o.retry mcio_o.mexc mcio_o.cache fsm r bypass req_burst r_n bypass req_burst req_burst wait_req wait_req wait_req wait_req req_burst req_burst aes aesi.key {00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F} aesi.in_txt {00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F} {00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 13} {00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 17} {00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 1B} {00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F} {00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 1F} aesi.start aeso.end_conv aeso.out_txt {00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00} {77 4D 42 80 EE 4B 07 D9 97 72 CD AB 8E B3 5B 03} reg state s.mem {00000000 00000000 00000000 00000000} s.cac 0000 {00000000 00000000 00000000 81D82000} {00000000 00000000 03000004 81D82000} {00000000 821060E0 03000004 81D82000} {81884000 821060E0 03000004 81D82000} 000U 001U 011U 111U 1 2 3 0 s.tag 0000000 0000001 s.word 0 Figura 9.5. Simulazione del Leom3MP crittografico (cifratura disabilitata): trasferimento dati in modalità single 1000000 1500000 2000000 Entity:testbench Architecture:behav Date: Fri Jun 08 12.19.49 ora solare Europa occidentale 2007 Row: 1 Page: 1 144 2500000 3000000 9.4 – Simulazione del microprocessore Leon3MP crittografico rst clk mcii_i 00000040 mcii_i.address 00000050 mcii_i.req mcii_i.burst mcii_i.su mcio_i mcio_i.data FFFFFFFF 8E100000 A0100000 A2100000 A4100000 FFFFFFFF 00000044 00000048 0000004C 00000040 A6100000 A8100000 AA100000 AC100000 FFFFFFFF 00000050 00000054 00000058 0000005C 00000050 8E100000 A6100000 mcio_i.ready mcio_i.grant mcio_i.retry mcio_i.mexc mcio_i.cache mcii_o 00000040 mcii_o.address mcii_o.req mcii_o.burst mcii_o.su mcio_o mcio_o.data 8608E01F 8E100000 mcio_o.ready mcio_o.grant mcio_o.retry mcio_o.mexc mcio_o.cache fsm r r_n wait_req wait_req req_burst send_burst req_burst req_burst send_burst req_burst send_burst req_burst req_burst send_burst aes aesi.key {00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F} aesi.in_txt {00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 4F} {00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 53} {00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 57} {00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 5B} {00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 5F} {00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 63} {00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 67} {00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 6B} aesi.start aeso.end_conv {93 CA 21 04 60 56 F8 6F 16 80 B9 16 F1 93 D4 F8} aeso.out_txt {D8 76 B4 AA 83 29 90 DD 23 5E 2A 47 68 25 93 4A} reg state s.mem {8C100000 8A100000 88100000 8608E01F} {8C100000 8A100000 88100000 8E100000} {8C100000 8A100000 A0100000 8E100000} {8C100000 A2100000 A0100000 8E100000} {A4100000 A2100000 A0100000 8E100000} 1 2 3 0 {A4100000 A2100000 A0100000 A6100000} {A4100000 A2100000 A8100000 A6100000} {A4100000 AA100000 A8100000 A6100000} 1 2 3 s.cac 1111 s.tag 0000003 s.word 0 0000004 0000005 Figura 9.6. Simulazione del Leom3MP crittografico (cifratura disabilitata): trasferimento dati in modalità incrementing burst 8000000 9000000 Entity:testbench Architecture:behav Date: Fri Jun 08 12.27.04 ora solare Europa occidentale 2007 Row: 1 Page: 1 145 10000000 0 wait_req 9 – Leon3MP Crittografico termina dopo 52.100 cicli di clock. È possibile dunque stimare la perdita percentuale delle prestazioni secondo l’equazione 9.1. η= 9.4.2 52.100 − 44.305 · 100 ≈ 17% 44.305 (9.1) Seconda simulazione La seconda simulazione prevede invece la simulazione del reale funzionamento del microprocessore Leon3MP Crittografico. Per prima cosa si è cifrata la memoria ROM il cui contenuto è scritto nel file SREC prom.srec. Per eseguire la cifratura del contenuto è stato sviluppato un programma in linguaggio C in grado di cifrare il contenuto di un file SREC. Il programma sviluppato dato in ingresso un file SREC genera in uscita la versione cifrata secondo lo standard AES e la modalità di funzionamento CTR descritta nel capitolo precedente. Successivamente sono stati settate delle costanti SNIFFER EN, CIPHER INSTR START e CIPHER INSTR END contenute nella libreria libsniffer.vhd. Le impostazioni prevedono, come nel caso precedente, l’abilitazione dell’unità cifrante ma la definizione del range di memoria, su cui effettuare la decifratura delle istruzioni, è impostato solo nel range di indirizzamento della memoria ROM. Il range di indirizzamento della memoria ROM, per il Leon3MP, è deducibile dalla tabella 8.1. Le impostazioni di questa simulazione sono riassunte in tabella 9.3. PARAMETRO SNIFFER EN CIPHER INSTR START CIPHER INSTR END VALORE true 0x00000000 0x1FFFFFFF Tabella 9.3. Impostazioni per la seconda simulazione del Leon3MP Crittografico Infine è stato modificato il codice VHDL del programma di test bench contenuto nel file testdench.vhd. La modifica prevede la modifica della costante ‘promfile’ che memorizza il nome del file SREC che descrive la memoria ROM. Come è visibile, nelle seguenti righe di codice VHDL (testdench.vhd), la versione cifrata della memoria ROM è contenuta nel file prom aes.srec. --constant promfile : string := "prom.srec"; -- rom contents constant promfile : string := "prom_aes.srec"; -- rom contents In figura 9.7 è mostrata una parte della simulazione in cui si mette in evidenza il funzionamento dell’unità cifrante. La simulazione può essere direttamente confrontata con quella di figura 9.5. In entrambe le figure è possibile osservare le stesse 146 9.4 – Simulazione del microprocessore Leon3MP crittografico rst clk mcii_i mcii_i.address 00000000 00000004 00000008 0000000C 00000010 mcii_i.req mcii_i.burst mcii_i.su mcio_i mcio_i.data FFFFFFFF F6956280 ED4B07DD 1562AD4B 0F3B1B03 FFFFFFFF 00000004 00000008 0000000C 00000000 00000010 4914EF1B mcio_i.ready mcio_i.grant mcio_i.retry mcio_i.mexc mcio_i.cache mcii_o mcii_o.address 00000000 mcii_o.req mcii_o.burst mcii_o.su mcio_o mcio_o.data FFFFFFFF 774D4280 81D82000 03000004 821060E0 81884000 wait_req wait_req wait_req mcio_o.ready mcio_o.grant mcio_o.retry mcio_o.mexc mcio_o.cache fsm r bypass req_burst r_n bypass req_burst req_burst wait_req wait_req wait_req wait_req wait_req req_burst req_burst aes aesi.key {00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F} aesi.in_txt {00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F} {00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 13} {00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 17} {00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 1B} {00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F} {00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 1F} aesi.start aeso.end_conv aeso.out_txt {00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00} {77 4D 42 80 EE 4B 07 D9 97 72 CD AB 8E B3 5B 03} reg state s.mem {00000000 00000000 00000000 00000000} s.cac 0000 {00000000 00000000 00000000 F6956280} {00000000 00000000 ED4B07DD F6956280} {00000000 1562AD4B ED4B07DD F6956280} {0F3B1B03 1562AD4B ED4B07DD F6956280} 000U 001U 011U 111U 1 2 3 0 s.tag 0000000 0000001 s.word 0 Figura 9.7. Simulazione del Leom3MP crittografico: trasferimento dati in modalità single 1000000 1500000 2000000 Entity:testbench Architecture:behav Date: Fri Jun 08 12.42.26 ora solare Europa occidentale 2007 Row: 1 Page: 1 147 2500000 3000000 9 – Leon3MP Crittografico richieste di trasferimento dati fatte dal controllore della memoria cache, ma mentre nella prima le istruzioni provenienti dalla memoria esterna sono in chiaro nella seconda figura le istruzioni sono cifrate. Questa simulazioni ha potuto confermare il coretto funzionamento delle operazioni di cifratura svolte dall’entity sniffer mci. 9.5 Conclusioni e sviluppi futuri Con l’architettura descritta in questo capitolo si è voluto soddisfare il bisogno di embedding security necessario alle attuali e future applicazioni. La scelta di sviluppare un sistema crittografico per il microprocessore LEON3 è stata dettata dal fatto che quest’ultimo, in ambito commerciale, sta riscuotendo particolare successo per lo sviluppo di SOC (System On a Chip). In conclusione vengono elencate alcune considerazioni su come migliorare le performance del sistema crittografico sviluppato e su come ampliare le funzionalità di protezione dell’informazione. Al fine di aumentare le performance del sistema crittografico è possibile procedere allo sviluppo di un’architettura composta da più core AES che eseguano le operazioni di cifratura in parallelo. Nel caso in cui la memoria cache abbia un’ampiezza di 32 byte, come è il caso delle simulazioni precedenti, per far fronte al riempimento di una riga di cache il sistema cifrante è costretto a suddividere l’operazione in due. La generazione del key stream avviene in due istanti di tempo differenti con l’introduzione di un evitabile tempo di latenza. Utilizzando due core AES è possibile risolvere il problema e generare il key stream associato all’intera riga di cache in contemporanea. Analoghi risultati si possono ottenere utilizzando una versione con pipeline del core AES. Un’altro metodo per incrementare le performance è quello di realizzare un’architettura in cui il core AES è in grado di eseguire le operazioni di cifratura con una frequenza di clock maggiore rispetto a quella del microprocessore LEON3. Utilizzando due code FIFO asincrone, una in ingresso e una in uscita al core AES, è possibile realizzare un’architettura in cui il core AES svolge le operazioni di cifratura ad un frequenza di clock maggiorata. Per esempio, si potrebbe realizzare un’implementazione in cui il microprocessore LEON3 utilizza una frequenza di clock pari a 50 MHz mentre il core AES utilizza una frequenza di clock di 300 MHz. Il sistema crittografico realizzato è già capace di garantire un’alto livello di sicurezza specialmente per quelle applicazioni in cui è di fondamentale importanza proteggere il contenuto (o parte di esso) di una memoria. La cifratura del contenuto della memoria, e quindi delle istruzioni in essa contenute, contrasta l’attività di reverse engineering. Per reverse engineering si intende l’analisi del codice oggetto (contenuto nella memoria) per risalire alle sue funzioni (nel caso queste non siano 148 9.5 – Conclusioni e sviluppi futuri note) e alle modalità con le quali queste siano realizzate. Qualsiasi tentativo di lettura diretta del contenuto della memoria risulterebbe inutile poiché le istruzioni in essa contenute sono cifrate. Per incrementare il livello di sicurezza è possibile proporre alcune migliorie al sistema crittografico proposto. Innanzi tutto si può procedere allo sviluppo di un’unità crittografica oltre che per le istruzioni anche per i dati. L’unità crittografica per i dati si posiziona tra il controllore della memoria chace per i dati e il modulo atto ad inoltrare le richieste di trasferimento dati sul bus AMBA AHB (entity acache). In questo metodo è possibile proteggere anche i risultati delle operazioni svolte dalla CPU. Successivamente si potrebbe sviluppare un’architettura in grado di poter gestire la cifratura di più processi in maniera indipendente, ovvero la possibilità di poter far eseguire alla CPU programmi differenti con chiavi di cifratura differenti magari con un’integrazione del sistema crittografico con il sistema operativo. Infine per evitare l’esecuzione di programmi creati ad hoc per eludere le funzionalità di cifratura delle informazioni sarebbe bene realizzare un sistema in grado di controllare l’integrità del contenuto della memoria esterna e quindi impedire l’esecuzione di programmi non autorizzati. 149 9 – Leon3MP Crittografico 150 Appendice A Il formato S-record Il formato “S-record” (SREC) è stato sviluppato dalla Motorola ed è comunemente utilizzato per l’upload del firmware nelle memorie. Un file S-record consiste in una sequenza di stringhe di caratteri ASCII. L’ordine delle stringe, una per ogni riga del file, è ininfluente al fine delle descrizione del contenuto della memoria. Il formato generale di un S-record è mostrato in figura A.1 ed è composto da 5 campi. TYPE COUNT ADDRESS DATA CHECKSUM Figura A.1. Formato S-record All’interno di ciascun campo, fatta eccezione per TYPE, ciascuna coppia di caratteri ASCII va interpretata come la rappresentazione esadecimale di un numero binario su 8 bit (byte). Il campo TYPE è composto da due caratteri ASCII e descrive la tipologia del record. Ci sono 8 possibili tipologie di record riassunte in tabella A.1. COUNT è composto da 2 caratteri e rappresenta il numero di coppie di caratteri ASCII (byte) rimanenti nel record (riga). Il campo ADDRESS formato da 4, 6 o 8 caratteri rappresenta l’indirizzo di memoria in cui vanno memorizzati i dati contenuti nel record. Il campo DATA è formato da massimo 64 caratteri e contiene i dati da memorizzare nella memoria o la descrizione del file SREC. Il campo CHECKSUM è formato da due caratteri e permette il controllo sui dati trasmessi. Il campo è formato dalla l’inverso della somma dei byte che formato il campo COUNT, ADDRESS e DATA. Ciascuna riga del file S-record termina con un line feed. 151 A – Il formato S-record TYPE Descrizione S0 (0x5330) È un record che permette la descrizione del contenuto del file SREC. Il campo ADDRESS è inutilizzato è posto uguale a 0x0000. Le informazioni sulla descrizione del file SREC sono contenute all’interno del campo DATA con il seguente formato: 20 caratteri per il nome del modulo, 2 caratteri per la versione e per la revisione, da 0 a 36 caratteri per commenti vari. È un record che contiene i dati da scaricare nella memoria. Il campo ADDRESS è interpretato come un indirizzo su 2 byte. Il campo DATA contiene i dati. È un record che contiene i dati da scaricare nella memoria. Il campo ADDRESS è interpretato come un indirizzo su 3 byte. Il campo DATA contiene i dati. È un record che contiene i dati da scaricare nella memoria. Il campo ADDRESS è interpretato come un indirizzo su 4 byte. Il campo DATA contiene i dati. È un record di controllo. Il campo ADDRESS è interpretato come un valore su 2 byte che rappresenta il numero di record S1, S2 e S3 precedentemente trasmessi. Il campo DATA non contiene informazioni. È un record di inizializzazione. Il campo ADDRESS contiene l’indirizzo iniziale per l’esecuzione del firmware interpretato su 4 byte. Il campo DATA non contiene informazioni. È un record di inizializzazione. Il campo ADDRESS contiene l’indirizzo iniziale per l’esecuzione del firmware interpretato su 3 byte. Il campo DATA non contiene informazioni. È un record di inizializzazione. Il campo ADDRESS contiene l’indirizzo iniziale per l’esecuzione del firmware interpretato su 2 byte. Il campo DATA non contiene informazioni. S1 (0x5331) S2 (0x5332) S3 (0x5333) S5 (0x5335) S7 (0x5337) S8 (0x5338) S9 (0x5339) Tabella A.1. Tipologie di record del formato S-record 152 Bibliografia [1] National Institute of Standards and Technology (NIST), Information Technology Laboratory (ITL), Advanced Encryption Standard (AES), Federal Information Processing Standards (FIPS) Publication 197, November 2001. [2] De Rosa, Catello Antonio. Sistemi di cifratura: storia, principi, algoritmi e tecniche di crittografia. Milano: CLUP, 2004. [3] Ross J. Anderson and Markus G. Kuhn. Tamper Resistance - a Cautionary Note. In Second Usenix Workshop on Electronic Commerce, pages 1-11, November 1996. [4] Leijla Batina, Kerstin Lemke, Elke de Mulder, Nele Mentens, Elisabeth Oswald, Eric Peeters, and François-Xavier Standaert. D.VAM.5-Side-channel attacks on FPGAs, August 2005. [5] Lejla Batina, Elke De Mulder, Kerstin Lemke, Stefan Mangard, Elisabeth Oswald, Gilles Piret, and François-Xavier Standaert. D.VAM.4-State of the art of side-channel attacks other than power and timing attacks, August 2005. [6] Mike Bond. Attacks on Cryptoprocessor Transaction Sets. In Çetin Kaya Koç and David Naccache and Christof Paar, editor, Cryptographic Hardware and Embedded Systems - CHES 2001, Third International Workshop, Paris, France, May 14-16, 2001, Proceedings, volume 2162 of Lecture Notes in Computer Science, pages 220-234. Springer, 2001. [7] Pawel Chodowiec and Kris Gaj. Very Compact FPGA Implementation of the AES Algorithm. In Colin D. Walter, Çetin Kaya Koç, and Christof Paar, editors, Cryptographic Hardware and Embedded Systems – CHES 2003, 5th International Workshop, Cologne, Germany, September 8-10, 2003, Proceedings, volume 2779 of Lecture Notes in Computer Science, pages 319-333. Springer, 2003. [8] Pawel Chodowiec, Po Khuon, and Kris Gaj. Fast implementations of secret-key block ciphers using mixed inner- and outer-round pipelining. In ACM/SIGDA ninth international symposium on Field programmable gate arrays - FPGA 2001, Montery, California, USA, 2001, Proceedings, pages 94–102. ACM Press, 2001. 153 Bibliografia [9] Joan Daemen and Vincent Rijmen. The Design of Rijndael. Information Security and Cryptography. Springer, 2002. ISBN 3-540-42580-2. [10] Martin Feldhofer, Sandra Dominikus, and Johannes Wolkerstorfer. Strong Authentication for RFID Systems using the AES Algorithm. In Marc Joye and Jean-Jacques Quisquater, editors, Cryptographic Hardware and Embedded Systems – CHES 2004, 6th International Workshop, Cambridge, MA, USA, August 11-13, 2004, Proceedings, volume 3156 of Lecture Notes in Computer Science, pages 357–370. Springer, 2004. [11] Martin Feldhofer, Johannes Wolkerstorfer, and Vincent Rijmen. AES Implementation on a Grain of Sand. IEE Proceedings on Information Security, to appear, November 2005. [12] Alireza Hodjat, David Hwang, Bo-Cheng Lai, Kris Tiri, and Ingrid Verbauwhede. A 3.84 Gbits/s AES crypto coprocessor with modes of operation in a 0.18-um CMOS Technology. In John Lach, Gang Qu, and Yehea I. Ismail, editors, Proceedings of the 15th ACM Great Lakes Symposium on VLSI 2005, Chicago, Illinois, USA, April 17-19, 2005, pages 60–63. ACM, ACM Press, April 2005. [13] Alireza Hodjat and Ingrid Verbauwhede. A 21.54 Gbits/s Fully Pipelined AES Processor on FPGA. In 12th IEEE Symposium on Field-Programmable Custom Computing Machines (FCCM 2004), 20-23 April 2003, Napa, CA, Proceedings, pages 308–309. IEEE Computer Society, 2004. [14] Alireza Hodjat and Ingrid Verbauwhede. Minimum Area Cost for a 30 to 70 Gbits/s AES Processor. In 2004 IEEE Computer Society Annual Symposium on VLSI (ISVLSI 2004), Emerging Trends in VLSI Systems Design, 19-20 February, 2004, Lafayette, LA, USA, pages 83–88. IEEE Computer Society, 2004. [15] International Organisation for Standardization (ISO). ISO/IEC 7816: Identification cards - Integrated circuit(s) cards with contacts, 1989. [16] International Organization for Standardization (ISO). ISO/IEC 18000-3: Information Technology AIDC Techniques - RFID for Item Management, March 2003. [17] Paul C. Kocher. Timing Attacks on Implementations of Diffie-Hellman, RSA, DSS, and Other Systems. In Neal Koblitz, editor, Advances in Cryptology CRYPTO ’96, 16th Annual International Cryptology Conference, Santa Barbara, California, USA, August 18-22, 1996, number 1109 in Lecture Notes in Computer Science, pages 104-113. Springer, 1996. [18] Paul C. Kocher, Joshua Jaffe, and Benjamin Jun. Differential Power Analysis. In Michael Wiener, editor, Advances in Cryptology - CRYPTO ’99, 19th Annual International Cryptology Conference, Santa Barbara, California, USA, August 15-19, 1999, Proceedings, volume 1666 of Lecture Notes in Computer Science, pages 388-397. Springer, 1999. 154 Bibliografia [19] Stefan Mangard, Manfred Aigner, and Sandra Dominikus. A Highly Regular and Scalable AES Hardware Architecture. IEEE Transactions on Computers, 52(4):483-491, April 2003. [20] Màire McLoone and John V. McCanny. High Performance Single-Chip FPGA Rijndael Algorithm Implementations. In Çetin Kaya Koç, David Naccache, and Christof Paar, editors, Cryptographic Hardware and Embedded Systems – CHES 2001, Third International Workshop, Paris, France, May 14-16, 2001, Proceedings, volume 2162 of Lecture Notes in Computer Science, pages 65–76. Springer, 2001. [21] National Institute of Standards and Technology (NIST). FIPS-197: Advanced Encryption Standard, November 2001. Available online at www.itl.nist.gov/fipspubs/. [22] National Institute of Standards and Technology (NIST). Special Publication 800-38A 2001 ED, Recommendation for Block Cipher Modes of Operation - Methods and Techniques, December 2001. Available online at csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf. [23] National Institute of Standards and Technology (NIST). Special Publication 800-38C 2004, Recommendation for Block Cipher Modes of Operation: The CCM Mode for Authentication and Confidentiality, May 2004. Available online at csrc.nist.gov/publications/nistpubs/800-38C/SP800-38C.pdf. [24] National Institute of Standards and Technology (NIST). Special Publication 800- 38B 2005, Cipher Modes of Operation: The CMAC Mode for Authentication, May 2005. Available online at csrc.nist.gov/publications/nistpubs/80038B/SP 800-38B.pdf. [25] Norbert Pramstaller, Stefan Mangard, Sandra Dominikus, and Johannes Wolkerstorfer. Efficient AES Implementations on ASICs and FPGAs. In H. Dobbertin, Vincent Rijmen, and A. Sowa, editors, Proceedings of the Fourth Workshop on the Advanced Encryption Standard, AES4 - State of the Crypto Analysis’, Bonn, Germany, May 10-12, 2005., volume 3373 of Lecture Notes in Computer Science, pages 98-112. Springer, 2004. [26] Norbert Pramstaller and Johannes Wolkerstorfer. A Universal and Efficient AES Co- Processor for Field Programmable Logic Arrays. In Jürgen Becker, Marco Platzner, and Serge Vernalde, editors, Field Programmable Logic and Application, 14th International Conference, FPL 2004, Antwerp, Belgium, August 30 - September 1, 2004, Proceedings, volume 3203 of Lecture Notes in Computer Science, pages 565-574. Springer, August 2004. [27] Gaël Rouvroy, Fran¸cois-Xavier Standaert, Jean-Didier Legat, and JeanJacques Quisquater. Compact and Efficient Encryption/Decryption Module for FPGA Implementation of the AES Rijndael Very Well Suited for Small Embedded Applications. In International Conference on Information Technology: 155 Bibliografia [28] [29] [30] [31] [32] [33] [34] [35] Coding and Computing (ITCC 2004), Special Session on Embedded Cryptographic Hardware, Washington, DC, USA, 5-7 April, 2004, Proceedings, volume 2, pages 583–587. IEEE Computer Society, 2004 Giacinto Paolo Saggese, Antonino Mazzeo, Nicola Mazzocca, and Antonio G. M. Strollo. An FPGA-Based Performance Analysis of the Unrolling, Tiling, and Pipelining of the AES Algorithm. In Peter Y. K. Cheung, George A. Constantinides, and José T. de Sousa, editors, Field Programmable Logic and Application, 13th International Conference, FPL 2003, Lisbon, Portugal, September 1-3, 2003, Proceedings, volume 2778 of Lecture Notes in Computer Science, pages 292–302. Springer, 2003. Akashi Satoh, Sumio Morioka, Kohji Takano, and Seiji Munetoh. A Compact Rijndael Hardware Architecture with S-Box Optimization. In Colin Boyd, editor, Advances in Cryptology - ASIACRYPT 2001, 7th International Conference on the Theory and Application of Cryptology and Information Security, Gold Coast, Australia, December 9-13, 2001, Proceedings, volume 2248 of Lecture Notes in Computer Science, pages 239-254. Springer, 2001. François-Xavier Standaert, Gaël Rouvroy, Jean-Jacques Quisquater, and JeanDidier Legat. Efficient Implementation of Rijndael Encryption in Reconfigurable Hardware: Improvements and Design Tradeoffs. In Colin D. Walter, Çetin Kaya Koç, and Christof Paar, editors, Cryptographic Hardware and Embedded Systems - CHES 2003, 5th International Workshop, Cologne, Germany, September 8-10, 2003, Proceedings, volume 2779 of Lecture Notes in Computer Science, pages 334–350. Springer, 2003. Ingrid Verbauwhede, Patrick Schaumont, and Henry Kuo. Design and Performance Testing of a 2.29 Gb/s Rijndael Processor. IEEE Journal of Solid-State Circuits, 38(3): 569-572, March 2003. Shuenn-Shyang Wang and Wan-Sheng Ni. An Efficient FPGA Implementation of Advanced Encryption Standard Algorithm. In International Symposium on Circuits and Systems (ISCAS 2004), Vancouver, British Columbia, Canada, May 23-26, 2004, Proceedings., volume 2, pages 597–600. IEEE Computer Society, May 2004. Neil H. E.Weste and Kamran Eshraghian. Principles of CMOS VLSI Design - A Systems Perspective. Addison-Wesley, 2nd edition, 1993. ISBN 0-201-53376-6. Johannes Wolkerstorfer. An ASIC Implementation of the AES-MixColumn operation. In Peter Rössler and Andreas Döderlein, editors, Austrochip 2001, pages 129–132, 2001. ISBN 3-9501517-0-2. Johannes Wolkerstorfer, Elisabeth Oswald, and Mario Lamberger. An ASIC implementation of the AES SBoxes. In Bart Preneel, editor, Topics in Cryptology - CT-RSA 2002, The Cryptographer’s Track at the RSA Conference 2002, San Jose, CA, USA, February 18-22, 2002, volume 2271 of Lecture Notes in Computer Science, pages 67-78. Springer, 2002. 156 Bibliografia [36] Joseph Zambreno, David Nguyen, and Alok N. Choudhary. Exploring Area/Delay Tradeoffs in an AES FPGA Implementation. In Jürgen Becker, Marco Platzner, and Serge Vernalde, editors, Field Programmable Logic and Application, 14th International Conference, FPL 2004, Leuven, Belgium, August 30-September 1, 2004, Proceedings., volume 3203 of Lecture Notes in Computer Science, pages 575–585. Springer, 2004. [37] Xinmiao Zhang and Keshab K. Parhiter. High-Speed VLSI Architectures for the AES Algorithm. IEEE Transactions on Very Large Scale Integration (VLSI) Systems, 12(9):957– 967, September 2004. [38] Viktor Fischer and Miloš Drutarovský. Two Methods of Rijndael Implementation in Reconfigurable Hardware, Ç.K. Koç, D. Naccache, and C. Paar (Eds.): CHES 2001, LNCS 2162, pp. 77–92, 2001. [39] H. Kuo and I. Verbauwhede. Architectural optimization for a 1.82 Gbits/sec VLSI implementation of the AES Rijndael algorithm, in Proc. CHES 2001, Paris, France, May 2001, pp. 51–64. [40] X. Zhang and K. K. Parhi, Implementation approaches for the advanced encryption standard algorithm, IEEE Circuits Syst. Mag., vol. 2, no. 4, pp. 24–46, 2002. [41] R. Elbaz, L. Torres, G. Sassatelli, P. Guillemin, C. Anguille, M. Bardouillet, C. Buatois, J. B. Rigaud: Hardware Engines for Bus Encryption: a Survey of Existing Techniques, IEEE Proceedings of the Design, Automation and Test in Europe Conference and Exhibition (DATE’05) 1530-1591, 2005 [42] B. Schneier, Applied Cryptography: Protocols, Algorithms and Source Code in C. John Wiley and Sons, 1996. [43] Tanguy Gilmont, Jean-Didier Legat, Jean Jacques Quisquater: Enhancing Security in the Memory Management Unit. 25th Euromicro Conference, September 1999, Vol. 1 p.1449. [44] M. G. Kuhn: Cipher Instruction Search Attack on the Bus- Encryption Security Microcontroller DS5002FP, IEEE Trans. Comput., vol. 47, pp. 1153–1157, Oct. 1998. [45] Best, R. M.: Microprocessor for Executing Enciphered programs, U.S. Patent No. 4 168 396, September 18, 1979. [46] Best, R. M.: Crypto Microprocessor for Executing Enciphered Programs, U.S. Patent No. 4 278 837, July 14, 1981. [47] Best, R. M.: Crypto Microprocessor that Executes Enciphered Programs, U.S. Patent No. 4465 901, August 14, 1984. [48] Richard Takahashi and Daniel N. Heer: Secure memory management unit for microprocessor, U.S. Patent (from VLSI Technology, Inc.) No. 5 825 878, October 20, 1998 [49] Brant Candelore and Eric Sprunk: Secure processor with external memory using 157 Bibliografia [50] [51] [52] [53] [54] block chaining and block reordering, U.S. Patent (from General Instrument Corporation) No. 6 061 449, May 9, 2000. Dallas Semiconductor (Maxim), www.maximic.com/Microcontrollers.cfm. XOM project: www-vlsi.stanford.edu/ lie/xom.htm G. E. Suh, D. Clarke, B. Gassend, M. van Dijk, and S. Devadas, AEGIS: Architecture for Tamper-Evident and Tamper-Resistant Processing, in Proc. Intl Conf. Supercomputing (ICS ’03), pp. 160–171, June 2003. GAISLER RESEARCH, www.gaisler.com ARM, AMBA (Rev 2.0) Specification, www.arm.com 158