blogy logo
login PRIHLÁS SA
BLOG deadawp
ČLÁNKY
DISKUSIE
3
SLEDUJETE BLOG
PHP, Arduino programátor
deadawp



Flash Encryption a jeho implementácia v ESP-IDF
pridal deadawp 18.7. 2021 o 11:37



Niektoré texty a pasáže použité z mojej diplomovej práce: 
Bezpečná aktualizácia firmvéru v senzorovej sieti na báze ESP32 (Košice, 2021)

Keďže funkcionalita Secure Boot V1, ktorú sme si predstavili v minulom článku nerieši ochranu firmvéru a softvérového bootloadera, ale iba bootovací proces, odporúča sa na základe dokumentácie ESP-IDF Secure Boot doplniť o Flash Encryption a využívať tieto funkcionality spolu pre vysokú úroveň bezpečnosti. Šifrovať je možné obsah celej flash pamäte, alebo jej časti, ktoré sa definujú v tabuľke partícií príznakom. Šifrovaná časť flash pamäte nie je potencionálnym útočníkom spustiteľná, keďže dokáže prevziať cez USB-UART rozhranie iba zašifrovaný firmvér (ak sa využíva produkčná verzia Flash Encryption).

Ako je z blokovej schémy vyššie patrné, OTA firmvér môže byť distribuovaný štandardne v otvorenom texte, alebo po úprave v programovej implementácie v šifrovanom texte, ktorý nie je pri zápise do flash pamäte už šifrovaný. Táto funkcionalita dokáže zároveň obsah flash pamäte dešifrovať v reálnom čase, ak sa daná partícia používa. Používa symetrický AES kľúč s dĺžkou 256 bitov pre šifrovanie a dešifrovanie obsahu flash pamäte. Kľúč je uložený v jednorazovo programovateľnej pamäti eFuse BLK1 s veľkosťou 256 bitov, ktorá je pre tento kľúč vyhradená.

V základnom nastavení Flash Encryption sú šifrované tieto sektory flash pamäte:

  • softvérový bootloader, tabuľka partícií,
  • všetky firmvérové partície – APP (aplikačné),
  • odtlačok SW bootloadera na ofsete 0x0 – (ak sa využíva MZBP).

Iné typy partícií môžu byť šifrované dodatočne pridaním príznaku encrypted do tabuľky partícií. 

 

Proces šifrovania flash pamäte

Po vytvorení buildu (firmvér, bootloader, odtlačok, tabuľka partícií) a jeho nahratí do mikrokontroléra ESP32 sú všetky dáta vo flash pamäti v otvorenom texte – nešifrované. Za predpokladu, že je spustená aj funkcionalita Secure Boot, hardvérový bootloader overí softvérový bootloader pre možnosť spustenia ďalších fáz bootovacieho procesu. Po úspešnom overení softvérový bootloader na základe príznaku zo súboru „sdkconfig“ pre príznak y (yes) pre makro prislúchajúce k zapnutiu Flash Encryption načíta hodnotu eFuse FLASH_CRYPT_CNT.

Ak je jej hodnota 0 (ešte nešifrovaná flash pamät), nastaví a aktivuje sa blok šifrovania obsahu flash pamäte. bootloader nastaví 4-bitovú eFuse FLASH_CRYPT_CONFIG na hodnotu 0xF (hexadecimálna hodnota). Operácie samotného šifrovania flash pamäte už vykonáva hardvérový bootloader, keďže softvér nemá prístup pre zápis a čítanie do už zapísaných systémových eFuses(BLK1), ktoré sú od momentu zapísania kľúča chránené voči softvérovému prepisu a čítaniu. Šifrujú sa partície a sektory vo flash pamäti označené príznakom encrypted.

Pre šifrovanie aj dešifrovanie sa využíva (symetrický) AES kľúč zapísaný do eFuse BLK1 s veľkosťou 256-bitov, ktorá je na tento účel určená. Pri väčších partíciách môže trvaťšifrovanie až minútu. Softvérový bootloader po ukončení šifrovania nastaví eFuse FLASH_CRYPT_CNT na hodnotu 0x01, čo znamená, že je obsah flash pamäte šifrovaný a opätovné šifrovanie sa pri reštarte a spúšťaní systému nevykoná. Ak je použitý režim Release, od tohto momentu je eFuse chránená aj proti opätovnému zápisu.

Secure Boot je možné prevádzkovať v dvoch režimoch:

  • development (vývojársky) režim,
  • release (produkčný) režim.

Pre režim Development nastavuje softvérový bootloader bity eFuse DISABLE_DL_DECRYPT a DISABLE_DL_CACHE na hodnotu 1, čím umožní bootloaderu cez UART opätovne nahrávať už iba šifrovaný firmvér. Pri stiahnutí firmvéru – obsahu flash pamäte je obsah dešifrovaný a vývojár tak získava výstup v otvorenom texte, čo je pre produkčné aplikácie nebezpečné, keďže sa k firmvéru môže dostať útočník a spustiť ho na svojej mikrokontrolérovej platforme.

Zároveň však v tomto režime nie je eFuse FLASH_CRYPT_CNT chránená proti opätovnému zápisu. Prepis tejto pamäte je podľa dokumentácie ESP-IDF možné vykonať maximálne tri krát, čím je možné šifrovanie flash pamäte po testovacej fáze projektu vypnúť a používať mikrokontróler ESP32 bez tejto funkcie v ďalšom vývoji / produkčnej aplikácie. V produkčnom režime Release nastavuje bootloader eFuse DISABLE_DL_ENCRYPT, DISABLE_DL_DECRYPT a DISABLE_DL_CACHE na hodnotu 1, čím zabraňuje dešifrovaniu obsahu flash pamäte pri jej čítaní cez UART.

Výstupom v tomto prípade je tak zašifrovaný text, ktorý nie je spustiteľný na inej platforme ESP32, keďže kľúč pre šifrovanie / dešifrovanie je uložený v eFuse, ktorý nie je softvérovo prečítateľná. Útočník tak bez znalosti kľúča nedokáže firmvér spustiť. Režim Release Flash Encryption taktiež zavádza ochranu proti zápisu do eFuse FLASH_CRYPT_CNT, čo znamená, že Flash Encryption už nie je možné v budúcnosti vypnúť, ani využiť 3 dostupné prepisy tejto eFuse ako v prípade Development režimu.

Po prvotnom nastavení eFuses a zašifrovaní obsahu flash pamäte sa následne mikrokontróler ESP32 reštartuje a bootuje už partície v šifrovanom texte, ktoré v reálnom čase dešifruje s využitím AES symetrického kľúča v eFuse BLK1. Dešifrovaný firmvér sa tak zavedie do RAM pamäte a spustí.

 

Algoritmus šifrovania flash pamäte

Algoritmus šifrovania flash pamäte využíva blokovú šifru AES256, ktorá pracuje na 16 B blokoch dát. Pri tomto algoritme pracuje bloková šifra na 32 B blokoch dát, teda sa používajú dva bloky AES v sérii. AES256 používa symetrický kľúč z eFuse BLK1 s dĺžkou 256 bitov v reverznej bitovej reprezentácii. Pre proces šifrovania a dešifrovania flash pamäte sa používajú kryptografické operácie AES opačne.

Proces šifrovania je tvorený funkciou AES decrypt a proces dešifrovania flash pamäte funkciou AES encrypt. Pri šifrovaní sa na každý 32 B blok (2 bloky v sérii) otvoreného textu aplikuje unikátny šifrovací kľúč, ktorý je odvodený od hlavného vykonaním operácie XOR (exkluzívny súčet) medzi AES kľúčom a ofsetom bloku otvoreného textu vo flash pamäti. XOR-ovanie konkrétnych bitov kľúča závisí od hodnoty v 4-bitovej eFuse FLASH_CRYPT_CONFIG, ktorá je štandardne nastavená na hodnotu 0xF.

To zaručuje, že sú XOR-ované všetky bity odvodeného AES kľúča s ofsetom bloku dát. Zmena hodnoty zapísanej v eFuse FLASH_CRYPT_CONFIG by mohla znížiť kryptografickú bezpečnosť šifrovania flash pamäte, keďže by sa operácia XOR nevykonala pre všetky bity AES kľúča.

Nastavenie bitov eFuse FLASH_CRYPT_CONFIG a operácia XOR pre rozsahy bitov kľúča:

  • ak je nastavený 1. bit, bity 0 až 66 sú XOR-ované,
  • ak je nastavený 2. bit, bity 67 až 131 sú XOR-ované,
  • ak je nastavený 3. bit, bity 132 až 194 sú XOR-ované,
  • ak je nastavený 4. bit, bity 195 až 256 sú XOR-ované.

 

Šifrovanie flash pamäte – implementácia v prostredí ESP-IDF

Prvým krokom pre spustenie šifrovania flash pamäte je vygenerovanie a zapísanie symetrického kľúča do príslušnej jednorazovo programovateľnej pamäte eFuse BLK1. S využitím nástroja espsecure.py a príkazom espsecure.py generate_flash_encryption_key my_flash_encryption_key.bin je možné kľúč vygenerovať. Vygenerovaný kľúč „my_flash_encryption_key.bin“ je následne potrebné zapísať do vyhradenej jednorazovo programovateľnej pamäte eFuse BLK1, ktoré je pre neho určená.

Príkazom espefuse.py - -port PORT burn_key flash_encryption my_flash_encryption_key.bin sa kľúč zapíše do eFuse BLK1. Aby Flash Encryption mohlo byť spustené pre Release režim je nutné vykompilovať build na základe zvolenej konfigurácie z Menuconfig. Makrá pre šifrovania flash pamäte sú obsiahnuté v súbore „sdkconfig“ a definujú makrá pre zvolený režim šifrovania flash pamäte. Makrá sú vložené do bootloadera v procese vytvárania buildu. Pri prvom spustení vykoná bootloader úpravy v eFuses, ktoré sú ovplyvnené navoleným režimom šifrovania flash pamäte.

Na obrázku vyššie sú definované makrá v súbore „sdkconfig“ pre funkcionality MZBP a MŠFP (obe) v Release režime, ktoré sú v procese kompilácie vložené do softvérového bootloadera. Na základe makier a nastavení sa vykoná prvotné zašifrovanie flash pamäte na požadovaných partíciách. Keďže ide o produkčný (Release) režim, nie je možné neskôr funkcionalitu šifrovania flash pamäte vypnúť. 

Nastavením eFuses v produkčnom režime šifrovania flash pamäte je zároveň zabránené aj dešifrovaniu obsahu flash pamäte, ktorá môže byť stále prečítaná cez USB-UART rozhranie. To by malo za následok, že by potencionálny útočník dokázal získať pôvodný firmvér, alebo celý obsah flash pamäte v otvorenom texte a dokázal by ho spustiť na svojom hardvéri. Po prvotnom spustení funkcionality šifrovania flash pamäte vykoná hardvérový bootloader šifrovanie obsahu flash pamäte na preddefinovaných oddieloch a partíciách vo flash pamäti s označením encrypted.

Od tohto momentu je možné zapísať cez UART iba šifrovaný firmvér. V prípade, že je firmvér nahratý do mikrokontroléru ako otvorený text, nedôjde k jeho spusteniu, keďže po jeho dešifrovaní nie je v spustiteľnej podobe, tento stav je na obrázku vyššie, ktorý je výpisom z UART monitoru po nahratí firmvéru v otvorenom texte, mikrokontróler sa reštartuje v nekonečnom cykle a indikuje v chybovom hlásení nemožnosť načítania obsahu flash pamäte, ktorá nie je šifrovaná.

Keďže využívam Secure Boot a Flash Encryption v tejto implementácii súčasne, proces nahrávania firmvéru do mikrokontroléru ESP32 cez USB-UART rozhranie je zložitejší a vyžaduje viacero krokov s presnou postupnosťou. V prvom rade je potrebné skompilovať program do binárnej podoby pre vytvorenie firmvéru aplikácie v otvorenom texte. Následne je potrebné podpísať súkromným kľúčom firmvér v otvorenom texte a zašifrovať ho s použitím symetrického AES kľúča. Ďalším krokom je nahratie firmvéru do flash pamäte mikrokontroléru na konkrétny ofset.

V tomto prípade je efektívne vytvorenie jednoduchého spustiteľného súboru .bat, ktorý dokáže všetky kroky vykonať automatizovane. Šifrovanie firmvéru (obdobne pre bootloader, jeho odtlačok a iné súbory zapísané vo flash pamäti, ktoré majú byť šifrované), sa realizuje príkazom: espsecure.py encrypt_flash_data --keyfile my_flash_encryption_key.bin --address 0x20000 -o ./build/app-encrypted.bin ./build/native_ota.bin.

Príkaz má viacero parametrov – AES symetrický kľúč „my_flash_encryption_key.bin“ pre šifrovanie, adresu (začiatočný ofset), kde bude firmvér zapísaný, keďže algoritmus využíva operáciu XOR s ofsetom blokov dát. Ďalšími parametrami je zašifrovaný súbor a pôvodný súbor. Do parametrov nie je možné dosadiť rovnaký názov súboru pre zašifrovaný a pôvodný. Výstupom algoritmu pri takomto vstupe súborov je prázdny súbor firmvéru s veľkosťou 0 B. Príkazom esptool.py write_flash 0x20000 ./build/app-encrypted.bin je možné zapísať šifrovaný firmvér na konkrétne umiestnenie do flash pamäte, aby bol korektne dešifrovaný a spustiteľný v RAM pamäti.

OTA aktualizácie je však možné naďalej distribuovať v otvorenom texte a k ich zašifrovaniu dôjde v procese uloženia do flash pamäte mikrokontroléru ESP32 automaticky. Pri zmene funkcie pre zápis OTA aktualizácie na esp_partition_write() do flash pamäte je možné zapísať už zašifrovanú aktualizáciu, ktorú musí vydavateľ zašifrovať ešte pred umiestnením na OTA úložisko.

Rozhodujúcim parametrom a obmedzením tejto implementácie je však možnosť voľby iba jedného ofsetu, kam bude zašifrovaný firmvér zapísaný, nakoľko algoritmus Flash Encryption vyžaduje zadanie ofsetu pre vykonanie XOR operácie AES kľúča a blokov dát otvoreného textu. Stiahnutý firmvér tak v tomto prípade bude možné zapísať iba na jednu OTA partíciu a prepisovať ho na nej, čo zníži počet možných aktualizácii na polovicu z pohľadu životnosti flash pamäte, keďže v prípade firmvéru v otvorenom texte sa do flash pamäte zapisuje striedavo do oboch OTA partícií.

Aktualizovaný firmvér v tomto prípade nebude v procese aktualizácie šifrovaný. Ak vydavateľ pri takejto zmene nahrá firmvér v otvorenom texte, mikrokontróler ho nedokáže spustiť, keďže ho proces dešifrovania prevedie do nespustiteľnej podoby, bootovanie zlyhá.




Prístupov 465
Kvalita článku
hlasov 0

PRÍSPEVKY
SLEDOVAŤ
Prosím prihláste sa pre možnosť pridania komentáru.
Prihláste sa, alebo použite facebook login facebook login
ĎALŠIE ČLÁNKY V BLOGU
Práca s obrázkami - MATLAB
[ 19.7.2021] (príspevkov 1)
Flash Encryption a jeho implementácia v ...
[ 18.7.2021] (príspevkov 0)
Secure Boot V1 a jeho implementácia v ES...
[ 13.7.2021] (príspevkov 0)
Senzor Bosch BME280 v prostredí ESP-IDF
[ 8.7.2021] (príspevkov 0)
Podpora ESP32 do projektu WiFi termostat
[ 1.7.2021] (príspevkov 0)
Beamforming vizualizácia - MATLAB
[ 29.6.2021] (príspevkov 0)
Výroba DPS - AISLER - RFID DOMINATOR
[ 18.6.2021] (príspevkov 0)
Podpora ESP-IDF do projektu Hladinomer
[ 4.6.2021] (príspevkov 0)
WiFi termostat - Rozšírenie o manuálny r...
[ 28.3.2021] (príspevkov 0)
RFID DOMINATOR - stopky pre Airsoft | Pa...
[ 14.3.2021] (príspevkov 0)