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
Scarica

Architetture per la protezione dell`informazione nei sistemi embedded