Verifica e integrità nella trasmissione dati

La trasmissione di dati, indipendentemente dal canale scelto, è sempre soggetta a problemi che possono provocare errori di ricezione. È quindi necessario predisporre una serie di strumenti che consentano di minimizzare il grado di errore o assicurare l’integrità dell’informazione. Tra i vari sistemi esistenti, analizziamo in questo articolo l’uso di IpSec per un sistema embedded.

La verifica e il controllo dell’integrità dei dati è un argomento decisamente interessante e, allo stesso tempo, molto sentito in qualsiasi applicazione, in special modo in quelle che devono condividere strutture dati. Oggi, inoltre, con la diffusione dei nuovi mezzi trasmessivi, vedi Internet e i suoi innumerevoli protocolli, diventa urgente e necessario definire nuovi sistemi di controllo o utilizzare quelli già esistenti. A questo proposito, ad esempio, esistono già applicazioni embedded che sfruttano il protocollo SSL (Secure Socket Layer). Infatti, il Secure Socket Layer è un protocollo che garantisce la privacy delle comunicazioni su Internet; esso permette infatti alle applicazioni client/server di comunicare in modo da prevenire le intrusioni, le manomissioni e le falsificazioni dei messaggi. Non solo, esistono anche protocolli proprietari che permettono di sopperire alle richieste di sicurezza e integrità dei dati. Ogni protocollo che si pone l’obiettivo di garantire queste caratteristiche deve rispettare alcuni requisiti: deve sfruttare la massima larghezza di banda che il sistema offre, permettere di introdurre un basso tasso di errore e trattare un alto contenuto informativo.

Per ridurre sensibilmente il tasso di errore, occorre aggiungere dei bit di controllo, ma questo introduce un limite: più bit di controllo sono inseriti e minore è la quantità di informazioni inviate, ma al tempo stesso maggiore è la velocità di trasferimento. Occorre a questo punto trovare un giusto compro messo. La comunicazione seriale si divide in due famiglie: sincrona e asincrona. In una comunicazione seriale di tipo asincrona non si richiede una velocità elevata del flusso dati. La sincronizzazione di questo tipo si basa sul livello di carattere e su singolo bit. In una comunicazione asincrona lo stato di idle della linea è caratterizzato dalla presenza di un livello “1” continuo. Il bit di start, inserito sempre all’inizio di ogni carattere, assume un valore “0”, mentre lo stop bit, piazzato al fine della trasmissione del carattere, è rappresentato a valore “1” e riporta la linea nello stato idle. La transizione 1-0 tra idle e start fornisce al ricevitore  il sincronismo di carattere, mentre quella di bit è garantita disponendo di un clock di ricezione prossimo a quello di trasmissione. Nelle comunicazioni seriali occorre prevedere la trasmissione di informazioni ridondanti insieme al flusso dati per permettere la predisposizione di procedure di controllo e di rilevazioni di errori. Di solito, per sopperire a questa esigenza nelle trasmissioni asincrone si utilizza un bit di parità, in pratica si aggiunge un ulteriore bit al carattere che si trasmette. In presenza di una linea eccessivamente disturbata, questa soluzione non rappresenta una buona garanzia. Infatti, in questo modo non si riesce a trovare errori su un numero pari di bit. Per questa ragione, insieme al controllo di parità sul carattere, si introduce anche un controllo di parità sul blocco, vale a dire su un insieme di caratteri che costituiscono un messaggio. Al contrario, in un sistema di trasmissione seriale su Ethernet, si utilizza una comunicazione di tipo sincrona. In una comunicazione di questo tipo si ottiene una maggiore efficienza, perché si riduce il numero di bit di ridondanza e il formato dei dati di questo protocollo risulta più libero. Infatti, in una comunicazione sincrona si eliminano  i due bit di start e stop, il bit di parità all’interno di ogni carattere e si accettano caratteri da otto bit binari; è possibile, insomma, definire delle procedure di rilevazioni più efficienti e sicure della parità longitudinali. In una trasmissione di questo tipo quindi, il carattere non è più delimitato da un bit di start e stop, ma l’intera trasmissione risulta costituita da un flusso seriale di comunicazione continuo, cioè sincrono. Per delimitare il flusso, si utilizza un meccanismo di sincronizzazione sull’intero messaggio. Ad ogni modo, in un flusso continuo non spariscono completamente le varie procedure di controllo. Infatti, in una trasmissione di questo tipo si aggiunge, nella trama di invio, oltre ai bit di controllo previsto dal singolo protocollo, anche un campo che contiene l’informazione che in maniera univoca consente di determinare la correttezza del suo contenuto. Così, in una trama Ethernet accanto ai controlli di trasmissione di tipo fisico, il protocollo provvede di inserire in ogni blocco di dati una sequenza di controllo, tipicamente un CRC a 32 bit. Tutte queste informazioni, raggruppate in un’unica trama, sono inviate insieme ai dati. La presenza di un carattere di controllo riduce inevitabilmente  il contenuto dei dati. Esistono differenti metodi per controllare e verificare l’integrità dei dati: dal famosissimo CRC rappresentato su differenti risoluzioni, al comunissimo checksum, che seppur caduto in disuso rappresenta in ogni caso ancora oggi un buon sistema di controllo. Esistono anche differenti tecniche che permettono di garantire l’integrità della trasmissione, una delle più utilizzate è senza dubbio il protocollo SSL. In realtà, in questo articolo vorremo mettere in evidenza  il protocollo IPSEC utilizzato in ambito embedded. Il protocollo IPSEC garantisce un buon grado di integrità dei dati. Oggi sempre più applicazioni richiedono connessioni di rete per condividere informazioni o per ottenere dati riservati. Per questa ragione è sempre più necessario definire nuovi sistemi di controllo e verifica: la sicurezza diventa una componente fondamentale per tutelare la transizione dei dati su sistemi condivisi. L’integrità è tutto ciò che identifica la correttezza, la coerenza e l’affidabilità delle informazioni. Di conseguenza, accanto a sistemi che tutelano l’utente sulle alterazioni dei dati dovuti a rumore o problemi insiti della rete, è necessario definire sistemi che permettono di salvaguardare la transizione dei rapporti commerciali dove una quantità di dati, non definibile a priori, viene impiegata. Com’è possibile preservare l’integrità? Accanto a sistemi che già conosciamo, quali le tecniche hashing, esistono protocolli di comunicazione elaborati a questo scopo, quali SSL o IpSec.

SSL e sistemi embedded

SSL rappresenta sicuramente il protocollo più famoso orientato alla sicurezza del collegamento. Per garantire la sicurezza, questo protocollo deve fornire tre funzionalità essenziali: autenticazione, affidabilità e privatezza del collegamento. La privatezza del collegamento è un’operazione delicata e a questo scopo si utilizza un processo crittografico. La crittografia è usata dopo un handshake iniziale per definire una chiave segreta.  Il metodo utilizzato è di tipo simmetrico, come DES o RC4. L’identità nelle connessioni può essere autenticata usando la crittografia asimmetrica, o a chiave pubblica. Il protocollo prevede la certificazione del server e del client. Infine, il livello di trasporto include un controllo dell’integrità del messaggio basato su un apposito MAC (Message Authentication Code) che utilizza funzioni hash sicure: in questo modo si garantisce che i  dati spediti tra client e server non siano stati alterati durante la trasmissione. Il protocollo SSL è aperto e non proprietario. Il protocollo è composto da due strati (vedi figura 1): a livello più basso, interfacciato su di un protocollo di trasporto affidabile come il TCP, c’è il protocollo SSL Record, usato per l’incapsulamento dei vari protocolli di livello superiore.

Figura 1: stratificazione SSL.

Figura 1: stratificazione SSL.

 

Figura 2: SSL con AVR. Figura 1: stratificazione SSL

Figura 2: SSL con AVR.

Sul protocollo SSL Record si interfaccia l’SSL Handshake Protocol, che permette al server e al client di autenticarsi a vicenda e di negoziare un algoritmo di crittografia e le relative chiavi, prima che il livello applicazione  trasmetta o riceva il suo primo byte. Esistono diverse realizzazioni embedded di questo protocollo, ad l’incapsulamento dei vari protocolli di livello superiore. Sul protocollo SSL Record si interfaccia l’SSL Handshake Protocol, che permette al server e al client di autenticarsi a vicenda e di negoziare un algoritmo di crittografia e le relative chiavi, prima che il livello applicazione  trasmetta o riceva il suo primo byte. Esistono diverse realizzazioni embedded di questo protocollo, ad l’implementazione del protocollo su AVR. Diverse applicazioni utilizzano la pila TCP/IP di LwIP o direttamente FreeRTOS (si veda figura 3).

Figura 3: SSL con FreeRTOS.

Figura 3: SSL con FreeRTOS.

La tabella 1 mostra l’occupazione di memoria richiesta dall’implementazione con AVR.

Tabella 1 – Occupazione di ram per SSL con AVR

Tabella 1 – Occupazione di ram per SSL con AVR

Il controllo  con iPsec

Per implementare la suite IPsec è necessario considerare differenti RFC, perché ognuno copre un determinato aspetto. A questo proposito, la tabella 2 pone in evidenza i differenti RFC utilizzati nella definizione di IPsec.

Tabella 2 – Relazione dei vari moduli su IPSEC

Tabella 2 – Relazione dei vari moduli su IPSEC

Dal sito della rivista è possibile scaricare un’implementazione di IPsec senza LwIP stack. Le prestazioni di questo software sono abbastanza interessanti, ad esempio si è scelto l’algoritmo MD5 perché risulta più veloce rispetto a SHA1 (tabella 5), mentre la procedura per criptare il pacchetto (1500 byte) impiega circa 1 secondo (tabella 6).

Tabella 5 – HASH-MAC confronto prestazionale

Tabella 5 – HASH-MAC confronto prestazionale

 

Tabella 6 – Stime per un C166

Tabella 6 – Stime per un C166

La figura 4 mostra l’architettura della libreria IPsec con le relative dipendenze. Per prima cosa IPsec non è un singolo protocollo, ma semmai rappresenta una suite che ha lo scopo di mettere in sicurezza il livello IP. IPsec risulta essere composto da tre strati: AH (Authentication Header), ESP (Encapsulating Security Payload) e IKE (Internet Key Exchange). Ogni strato fornisce un particolare servizio: AH fornisce servizi di autenticazione e integrità, ESP servizi di riservatezza, autenticazione e integrità e, infine, IKE gestisce lo scambio delle chiavi.  Il meccanismo di comunicazione tra i livelli AH e ESP intende garantire una security association (SA): in sostanza si definiscono i meccanismi  di sicurezza da utilizzare. Il tutto è svolto attraverso una connessione tra due moduli che, comunicando mediante IPsec, definiscono gli algoritmi e le chiavi da utilizzare per stabilire una protezione sul traffico. Il modulo IKE si preoccupa di stabilire la negoziazione e la gestione delle SA. Questi sono meccanismi unidirezionali, la comunicazione tra due dispositivi deve avvenire attraverso due SA. Inoltre, una SA non può essere assegnata ad AH e ESP. Tutte le security association attive su un host sono contenute in un database chiamato SAD (Se curity Association Database), mentre per le politiche di sicurezza ci si affida a un altro database, SPD (Security Policy Database). In base a queste informazioni,  il sistema decide se un pacchetto IP deve essere scartato, lasciato passare in chiaro, oppure elaborato tramite IPsec, basandosi su parametri come l’indirizzo IP sorgente o destinazione, la porta sorgente o destinazione,  il protocollo di trasporto. Le security association possono essere combinate tra loro, per esempio si potrebbero avere due SA in modalità trasporto tra due host (una per AH e una per ESP), oppure una SA in modalità trasporto tra due host a cui si aggiunge una SA in modalità tunnel tra due security gateway che stanno tra i  due host. Sia AH che ESP possono essere utilizzati in modalità trasporto oppure in modalità tunnel: nel primo caso (non utilizzabile tra security gateway) si aggiungono gli header dei protocolli utilizzati (AH e/o ESP) tra l’header IP e l’header del protocollo di trasporto (TCP o UDP), mentre nel secondo il  pacchetto IP originario viene interamente incapsulato in un nuovo pacchetto IP.  AH autentica l’intero pacchetto IP (figura 5), ad eccezione dei campi variabili dell’header IP (ovvero type of service, flags, fragment offset, time to live, header checksum, più alcune delle opzioni) che, essendo modificabili dai nodi intermedi, non possono essere autenticati.

Figura 5: AH.

Figura 5: AH.

La tabella 3 mostra il significato dei campi presenti nell’AH. Il processo di autenticazione, nella libreria IPsec, è garantito attraverso l’algoritmo HASH-MAC MD5 e HASH-MAC SHA1, ma per esigenze prestazionali è preferibile utilizzare MD5.

Tabella 3 – Formato pacchetto AH

Tabella 3 – Formato pacchetto AH

Nella libreria IPsec sono presenti due funzioni. Con ipsec_ah_check si verifica l’integrità del pacchetto AH mediate l’uso di HMAC con una chiave specificata e permette controlli di tipo anti-replay. La funzione ipsec_ah_encapsulate definisce un nuovo AH e IP header calcolando il valore di integrità. La figura 6 ne mostra la struttura.

Figura 6: Header AH.

Figura 6: Header AH.

Viceversa, la tabella 4, con la figura 7, mostra il formato del pacchetto per ESP.

Tabella 4 – Formato pacchetto ESP

Tabella 4 – Formato pacchetto ESP

 

Figura 7: Header ESP.

Figura 7: Header ESP.

Con IPsec è possibile utilizzare solo alcuni dei servizi che lo strato ESP rende disponibile. L’autenticazione differisce da quella fornita dal protocollo AH, in quanto non copre l’header IP esterno. La posizione di ESP all’interno del pacchetto IP nelle modalità tunnel e trasporto è mostrata in figura 8.

Figura 8: ESP.

Figura 8: ESP.

Come si vede nella figura, ESP aggiunge sia un header sia un trailer, perché incapsula tutti i dati che protegge. Anche ESP, come AH, presuppone che esista già una security association tra i due nodi e non si preoccupa di negoziarne i parametri.  La libreria IPsec fornisce anche in questo caso due funzioni. La funzione ipsec_esp_decapsulate controlla il contenuto dell’header ESP e, in maniera opzionale, verifica la sua autenticità e lo pone in chiaro secondo la chiave ottenuta da IV (initialization vector). Con ipsec_esp_encapsulate si predispone un nuovo ESP header, cifra il pacchetto e controlla opzionalmente l’integrità. In IPsec assume un ruolo importante nel protocollo security association. La gestione delle SA è in carico al protocollo IKE (Internet Key Exchange).  Il protocollo ISAKMP (Internet Security Association and Key Management Protocol) definisce le procedure e il formato dei pacchetti per la gestione (creazione, modifica, cancellazione) delle security association e per lo scambio e l’autenticazione delle chiavi, indipendentemente dalla tecnica di generazione delle chiavi stesse, dagli algoritmi di cifratura e dai meccanismi di autenticazione.  Il significato preciso dei pacchetti ISAKMP dipende dal contesto (dominio interpretativo) utilizzato. Nell’analizzare l’elaborazione dei pacchetti IPsec si distingue il traffico in uscita (outbound, ovvero diretto verso un’interfaccia di rete) dal traffico in entrata (inbound, ovvero proveniente da un’interfaccia di rete). Si noti che un security gateway può elaborare lo stesso pacchetto due volte: prima in entrata, proveniente da un’interfaccia, e poi in uscita, diretto verso un’altra interfaccia. Introdurre un protocollo come IPSEC in un sistema embedded vuol dire considerare gli impatti che questo comporta sul sistema stesso; ad esempio, disponiamo di sufficiente memoria? In un sistema dedicato di piccole dimensioni, questa esigenza è stringente tanto da definire un’efficiente strategia di gestione della memoria. Infatti, solo introducendo una strategia sull’uso della memoria possiamo realizzare un’applicazione che non pregiudichi le prestazioni del nostro sistema. Ad ogni modo, occorre considerare questi aspetti:

» necessità di evitare la copia e lo spostamento di blocchi di memoria;

» i pacchetti devono essere passati per reference (utilizzare puntatori);

» la dimensione dei pacchetti deve essere definita in maniera dinamica.

Nella maggior parte dei casi, i  sistemi operativi e le librerie TCP/IP contengono già un gestore della memoria. Tutti i pacchetti devono essere inseriti in memoria utilizzando dei buffer contigui, in questo modo si assicura l’accesso veloce per l’algoritmo di crittografia da applicare al pacchetto. La figura 9 mostra un esempio applicativo.

Figura 9: spazio di memoria utilizzato

Figura 9: spazio di memoria utilizzato

Conclusioni

Può capitare talvolta che per specifiche applicazioni sia necessario definire un nuovo protocollo perché talune esigenze non possono essere garantite da un protocollo standard. La definizione di un protocollo deve necessariamente passare per uno corretto dimensionamento del nostro sistema. In un successivo articolo metteremo in evidenza  i criteri che occorre tenere presenti per costruire un protocollo custom.

 

Scrivi un commento

EOS-Academy