La libreria LibMcrypt
LibMcrypt e' una libreria thread safe (quindi adatta ad accessi simultanei di piu' processi), che fornisce un'interfaccia comune a più algoritmi e metodi di cifratura. Per la precisione essa implementa tutti gli algoritmi ed i metodi disponibili per il programma mcrypt. Licenza della libreria e' la GNU Lesser General Public License.
Tale software e' stato sviluppato come sostituto opensource del veccho programma Unix crypt. Crypt era un programma di file-encryption abbastanza diffuso in ambiente Unix, basato sull'algoritmo enigma, ormai considerato non piu' adeguato per garantire una privacy sufficiente. Originariamente lo scopo della libreria era infatti solamente quello di assistere lo sviluppo di mcrypt, fornendo un'interfaccia uniforme, in modo che il programma fosse indipendente dagli algoritmi e dai metodi usati.
La versione 2.5 della libreria supporta numerosi algoritmi, tra i quali blowfish, twofish, DES, Safer, lokI97, gost, rc2, rijndael, serpent, cast, RC4 e wake.
Tra i metodi di cifratura utilizzabili si possono invece annoverare: OFB, CBC, ECB, nOFB, nCFB, CFB, CTR. Si sottolinea inoltre, cona la libreria con CFB ed OFB intenda “8bit-CFB” e “8bit-OFB”, mentre in generale nOFB e nCFB rappresentano i metodi OFB/CFB a n-bit. Esiste inoltre un'ulteriore modalita' di cifratura supportata, STREAM, utilizzata per algoritmi di tipo stream quali RC4 e wake.
Per lo sviluppo dei due prototipi la scelta del metodo di cifratura e' caduta su CFB (Cipher-Feedback). La scelta di questo metodo e' stata giustificata dalla possibilita' di funzionare in tempo reale, cifrando ciascun carattere. Utilizzando servknock un range di 256 porte come possibili valori per gli elementi della sequenza di knock, e' stato semplice fare corrispondere i numeri di porta ai rispettivi elementi del set ASCII, per mezzo di un'operazione di casting da intero a carattere. Avendo il tipo char dimensione di 1 byte, e cifrando/decifrando il numero della porta di destinazione all'invio/ricezione del pacchetto, l'utilizzo del metodo 8bit-CFB ci e' parsa una buona soluzione. Maggiori dettagli implemntativi verranno illustrati nella sezione 4.6, relativa alla decifratura delle sequenze di knock.
Tra i diversi algoritmi disponibili servknock puo' utilizzare ed e' stato testato con:
Blowfish : cifrario sviluppato da Bruce Schneier, autore del famoso libro Applied Cryptography, opera scomponendo l'informazione in blocchi da 64 bit con chiave di lunghezza variabile, che puo' arrivare fino a 448 bit. Questo algoritmo utilizza varie tecniche tra le quali la rete Feistel, le S-box dipendenti da chiavi e funzioni non invertibili, che lo rendono, uno degli algoritmi a chiave simmetrica più sicuri tra quelli attualmente disponibili.
Esso ha inoltre i vantaggi di essere molto veloce, in grado di lavorare in maniera efficace anche su processori relativamente lenti, e di richiedere un quantitativo ridotto di memoria.
Twofish: presentato all'AES (Advanced Encryption Standard) da Bruce Schneier, John Kelsey, Doug Whiting, David Wagner, Chris Hall, e Niels Ferguson.
Questo cifrario lavora su blocchi con 128 bit di dimensione e chiavi a 128,192 e 256 bit, utilizzando "tavole" di sostituzione variabili che dipendono dalla chiave segreta. Gli autori sostengono che queste tavole in genere offrano maggiore sicurezza rispetto a tavole con valori fissati. Secondo le valutazione dall'AES l'algoritmo e' caratterizzato da performance estremamente efficienti e versatili sulla maggior parte delle piattaforme, ed anche in ambienti con scarsa quantità di memoria.
Rijndael : cifrario a blocchi sviluppato da Joan Daemen e Vincent Rijmen, vincitore del contest per l'AES, e standard USA che ha sostituito l'algoritmo DES. La sua schedulazione della chiave è veloce, e le richieste di memoria basse, per cui dovrebbe essere efficiente in hardware e in ambienti con una quantita' di memoria ridotta.
La libreria LibMcrypt, consente l'utilizzo di tre differenti versioni di questo algoritmo : Rijndael-128, Rijndael-192 e Rijndael-256, dove il numero finale indica la dimensione in bit della chiave. La versione da noi utilizzata e' stata quella a 128bit, ovvero la vincitrice dell'AES.
Serpent : cifrario con dimensione dei blocchi di 128 bit, finalista all'AES, sviluppato da Ross Anderson, Eli Biham e Lars Knudsen. Caratteristica di serpent sono una progettazione semplice e scelte implementative decisamente conservative, ricorrendo a meccanismi ben noti e sufficientemente testati.
I suoi progettisti hanno inoltre deciso di utilizzare il doppio delle iterazioni che ritenevano sicure contro gli attacchi attualmente conosciuti. Di conseguenza, le performance di Serpent sono relativamente basse comparate con quelle di altri algoritmi finalisti dell'AES, come twofish o rijndael.
xTEA : TEA e' l'acronimo per indicare Tiny Encryption Algorithm. E' un cifrario basato sulla rete di Feistel, sviluppato da David Wheeler e Roger M. Needham. L'algoritmo TEA originale era stato pensato per l'utilizzo in applicazioni dove una ridotta dimensione del codice sorgente fosse fondamentale. xTEA ne rappresenta la versione estesa (extended), carattarizzata da chiavi a 128 bit e dimensione dei blocchi di 64 bit.
Sfruttando questa libreria diventa estremamente semplice eseguire operazioni di cifratura e decifratura, che possono essere riassunte nei seguenti passi:
1. Creazione un descrittore (ovvero un puntatore ad una struttura CRYPT_STREAM) da passare alle altre funzioni utilizzate successivamente, per mezzo della funzione mcrypt_module_open, specificando l'algoritmo ed il metodo di cifratura che si desiderano utilizzare.
2. Inizializzazione dei buffer di memoria necessari, con una chimata a mcrypt_generic_init, alla quale devono essere passati il descrittore precedentemente creato, la chiave, la sua dimensione espressa in bytes e l'eventuale vettore di inizializzazione.
3. Cifratura/Decifratura effettuate per mezzo di mcrypt_generic e mdecrypt_generic, che provvedono sostituire il testo in chiaro con la versione cifrata e viceversa.
4. Deallocazione delle risorse usate : ad operazione conclusa e' buona norma liberare tutti i buffer utilizzati ed eventualmente chiudere il modulo associato al descrittore, tramite le funzioni mcrypt_generic_deinit e mcrypt_module_close.