Sostituzione computazionalmente semplice e leggera per SSL / TLS

24

L'hardware di destinazione è un MCU piuttosto basso (ARM Cortex-M3 @ 72 MHz, con circa 64 KB di SRAM e 256 KB di flash), quindi è sufficiente seguire la linea sottile. La mia scheda ha ethernet e alla fine avrò eseguito lwIP (leggera suite FOSS TCP / IP) su di esso (attualmente in difficoltà). Tuttavia, ho anche bisogno di una sorta di alternativa superleggera a SSL / TLS. Sono a conoscenza delle molteplici implementazioni SSL / TLS di GPL per tali MCU, ma il loro ingombro è ancora abbastanza significativo. Mentre si adattano, dato tutto il resto, non lasciare molto spazio agli altri.

Il mio traffico non è HTTP, quindi non devo preoccuparmi di HTTPS e la mia comunicazione client / server può essere completamente proprietaria, quindi la soluzione non standard va bene. Alla ricerca di suggerimenti su ciò che potrebbe essere il minimalista ma robusto (una sicurezza debole è inutile), alternativa che mi aiuta -

Encrypt my communication (C->S & S->C)
Do 2-way authentication (C->S & S->C)
Avoid man-in-middle attacks

Non sarò in grado di ottimizzare la libreria a livello di assembly ARMv7, e quindi di affidarmi interamente alle mie capacità di programmazione e all'ottimizzazione del compilatore GNU-ARM. Dato sopra, qualsiasi suggerimento su quali potrebbero essere le migliori opzioni?

C: Client, S: Server. La mia comunicazione è tutti i dati binari.

    
posta mike.dinnone 20.04.2011 - 10:09
fonte

4 risposte

31

Modifica: dopo qualche sforzo, I ha re-implementato una libreria SSL efficiente in RAM, che può essere eseguita nel tipo di RAM indicato di seguito. Ha molte più funzionalità e flessibilità delle mie precedenti creazioni, eppure è ancora molto piccolo. Ancora più importante, è anche opensource (licenza MIT). Divertiti: link

È possibile implementare un client SSL / TLS (o server) in circa 21 kB di codice ARM (pollice), che richiede meno di 20 kB di RAM durante l'esecuzione (*). So che si può fare perché l'ho fatto (mi dispiace, non open source). La maggior parte della complessità di TLS deriva dal supporto di molti tipi di algoritmi crittografici, negoziati durante l'iniziale stretta di mano; se ti concentri solo su un set di algoritmi crittografici, puoi ridurre il codice a qualcosa di abbastanza piccolo. Ti consiglio di utilizzare TLS 1.2 con la suite di crittografia TLS_RSA_WITH_AES_128_CBC_SHA256 : per quello, avrai solo bisogno di implementazioni per RSA, AES e SHA-256 (per TLS 1.1 e precedenti, occorrerebbero anche implementazioni per MD5 e SHA-1, che non è difficile ma impiegheranno alcuni kByte di codice in più). Inoltre, puoi renderlo sincrono (in chiaro TLS, client e server possono parlare simultaneamente, ma nulla li costringe a farlo) e omettere la parte "rinegoziazione handshake" (client e server eseguono una stretta di mano iniziale , ma possono rifarlo in seguito durante la connessione).

La parte più difficile nell'implementazione del protocollo riguarda i certificati. Il server e il client si autenticano a vicenda utilizzando le rispettive chiavi private - con RSA, il server esegue una decodifica RSA, mentre il client calcola una firma RSA. Ciò fornisce l'autenticazione fintanto che client e server si conoscono a vicenda le chiavi pubbliche; quindi, mandano le loro chiavi pubbliche l'una all'altra, racchiuse in certificati che sono blob firmati. Un certificato deve essere convalidato prima dell'uso, vale a dire la sua firma verificata rispetto a una chiave pubblica conosciuta a priori (spesso chiamata "root CA" o "trust anchor"). Il client non può usare ciecamente la chiave pubblica che il server ha appena inviato, perché consentirebbe attacchi man-in-the-middle.

L'analisi e la convalida del certificato X.509 è un po 'complessa (nella mia implementazione, era 6 kB di codice, fuori dai 21 kB). A seconda della configurazione, potresti avere opzioni più leggere; ad esempio, se si riesce a codificare la chiave pubblica del server nel client, il client può semplicemente usare quella chiave e gettare via il certificato del server, che è "solo un blob": nessuna necessità di analisi, nessuna certificazione, protocollo molto robusto. Si potrebbe anche definire il proprio formato "certificato". Un'altra possibilità è quella di utilizzare SRP , che è un meccanismo di scambio chiave in cui entrambe le parti si autenticano a vicenda per quanto riguarda la conoscenza di un valore segreto condiviso (la magia di SRP è che è solida anche se il segreto condiviso ha un'entropia relativamente bassa, ad esempio una password); usa TLS_SRP_SHA_WITH_AES_128_CBC_SHA .

Il punto qui è che, anche con un protocollo personalizzato, non si otterrà qualcosa di veramente più leggero di un TLS ridotto, almeno se si vuole mantenerlo robusto. E progettare un protocollo robusto non è affatto affatto ; La TLS arrivò al punto di essere considerata sufficientemente sicura attraverso anni di sangue e lacrime. Quindi è molto meglio riusare TLS che inventare il proprio protocollo. Inoltre, questo rende il codice molto più facile da testare (puoi interagire con le implementazioni SSL / TLS esistenti).

(*) Fuori dai 20 kB di RAM, c'è un buffer da 16,5 kB per i "record" in entrata, perché TLS afferma che i record possono raggiungere quella dimensione. Se si controlla sia il codice client che quello server, è possibile organizzare una dimensione massima record inferiore, risparmiando così sui requisiti di RAM. L'overhead per record non è molto meno di 50 byte in media, quindi è possibile utilizzare i record di 4 kB e avere comunque comunicazioni efficienti.

    
risposta data 20.04.2011 - 14:52
fonte
3

TLS sembra ancora lo strumento per il lavoro, basta scegliere saggiamente i cifrari e quindi definire quale dell'implementazione di cifratura funziona bene sulla piattaforma. Inoltre, le implementazioni ufficiali delle librerie crittografiche tendono ad essere orribilmente lente rispetto agli hacking, come gli algoritmi di John The Ripper , quindi forse potresti usarli. Hai già provato MatrixSSL ?

    
risposta data 20.04.2011 - 14:50
fonte
3

Qualunque cosa tu faccia, io vado con un protocollo esistente che è in circolazione da un po 'e rimuovo / hardcode alcune opzioni per renderlo più leggero, piuttosto che inventare il tuo protocollo.

Se le tue esigenze sono abbastanza semplici da poter essere utilizzate con chiavi simmetriche già condivise, aggiungere un sottoinsieme di IPSEC allo stack TCP / IP sembra essere fattibile senza un ingombro di codice enorme. Potrebbe persino essere possibile mantenere l'interoperabilità.

Analogamente, SSL o Kerberos ridotti all'essenziale sono probabilmente un'opzione, in quanto non è necessaria la maggior parte degli aspetti più importanti dell'autenticazione e della gestione delle chiavi, né la maggior parte delle cifre.

    
risposta data 20.04.2011 - 15:50
fonte
0

Potresti dare un'occhiata al MST (Minimal Secure Transport) link .

Fornisce le stesse garanzie di sicurezza di TLS, ma richiede una chiave pre-condivisa. Inoltre, è molto piccolo (meno di 1000 LoC, senza AES) e può quindi essere facilmente esaminato da un esperto.

    
risposta data 16.10.2017 - 15:21
fonte