>_ DevTrendspl

Język

Strona główna

Języki

Sekcje

Frontend Backend Mobilne DevOps AI / ML
PHP

Kryptografia zapałkowa: jak upchnąć ECDSA w tanim mikrokontrolerze

1419 gwiazdki

Gdy chodzi o ochronę danych w IoT lub tanim sprzęcie, programiści często napotykają ścianę. Spróbuj wdrożyć pełne OpenSSL na jakimś 8-bitowym AVR lub słabym ARM Cortex-M0. Prawdopodobnie Twoje firmware po prostu nie zmieści się w pamięci, a nawet jeśli się zmieści, nie zostanie żadnych zasobów dla głównej logiki aplikacji. Właśnie tutaj przydaje się projekt micro-ecc — robi jedną rzecz, ale robi ją porządnie.

Jaki jest cel tego projektu

micro-ecc to kompaktowa implementacja algorytmów ECDH (wymiana kluczy) i ECDSA (podpis cyfrowy) w C. Autor projektu, Ken MacKay, wyraźnie postawił sobie za cel stworzenie biblioteki, która będzie działać wszędzie tam, gdzie jest choćby jakiś procesor.

Główna sztuczka polega tutaj na całkowitym porzuceniu dynamicznej alokacji pamięci. Żadnego malloc i sterty, tylko stos i pamięć statyczna. Dla systemów wbudowanych jest to krytyczne: wiesz dokładnie, ile pamięci kryptografia będzie konsumować w czasie kompilacji, i nie obawiasz się fragmentacji ani wycieków w czasie wykonywania.

Co potrafi biblioteka

Biblioteka obsługuje pięć standardowych krzywych, w tym popularną secp256r1 (znaną również jako P-256) i "bitcoinową" secp256k1.

Główne cechy wyglądają następująco:

  • Działa na architekturach 8-, 32- i 64-bitowych.
  • Chroniona przed znanymi atakami typu side-channel.
  • Napisana w czystym C, ale są też wstawki asemblerowe dla AVR i ARM, aby wycisnąć maksymalną prędkość.
  • Dystrybuowana pod liberalną licencją BSD 2-clause.

Przy okazji, jeśli pracujesz z Arduino, projekt jest dostępny bezpośrednio w Menedżerze Bibliotek. Nie trzeba niczego pobierać ręcznie — po prostu znajdź micro-ecc i dodaj do swojego szkicu.

Mały kod do wielkich zadań

Autor twierdzi, że kod jest zoptymalizowany pod kątem rozmiaru. W świecie mikrokontrolerów jest to często ważniejsze niż surowa prędkość. Jeśli musisz tylko raz na miesiąc zweryfikować podpis aktualizacji firmware, nie ma znaczenia, czy zajmie to 100ms czy 500ms. Ważne jest, aby kod weryfikacji nie zjadał 80% pamięci flash.

To powiedziawszy, w kodzie są opcjonalne optymalizacje. Na przykład przez uECC_OPTIMIZATION_LEVEL można dostroić wydajność. Ale bądź ostrożny: przy wysokich poziomach optymalizacji dla platform ARM, GCC może wymagać określonych flag jak -fomit-frame-pointer, w przeciwnym razie wszystko może się popsuć.

Jak to wygląda w kodzie

Biblioteka ma minimalistyczny interfejs. Aby zacząć, wystarczy skopiować parę plików do projektu i dołączyć plik nagłówkowy.

#include "uECC.h"

// Создаем ключи
uint8_t public_key[64];
uint8_t private_key[32];
const struct uECC_Curve_t * curve = uECC_secp256r1();

uECC_make_key(public_key, private_key, curve);

Punkty krzywej są domyślnie reprezentowane w formie nieskompresowanej bez prefiksu 0x04. Jeśli musisz oszczędzać każdy bajt podczas transmisji przez radio, biblioteka udostępnia funkcje uECC_compress() i uECC_decompress().

Dla kogo to jest

Widzę kilka scenariuszy, gdzie micro-ecc jest po prostu niezastąpiony. Po pierwsze, uwierzytelnianie urządzeń. Na przykład gdy Twój czujnik musi udowodnić serwerowi, że jest tym, czym jest, a nie podróbką. ECDSA idealnie nadaje się do generowania takiego podpisu.

Po drugie, Secure Boot. Jeśli piszesz własny bootloader dla STM32 lub jakiegoś AVR, micro-ecc pomoże zweryfikować podpis nowego obrazu firmware przed zapisaniem go do flash.

Po trzecie, jeśli tworzysz elektronikę noszoną lub czujniki zasilane bateryjnie. Im mniej cykli CPU zużywają obliczenia, tym dłużej urządzenie działa. Wstawki asemblerowe dla ARM i AVR będą tutaj bardzo przydatne.

Kilka uwag na drogę

Mimo swojej genialności, projekt ma swoje dziwactwa. README jest dość zwięzły, więc szczegóły dotyczące każdej funkcji będziesz musiał szukać w uECC.h. Dokumentacja żyje właśnie w komentarzach w kodzie.

Jeśli planujesz zbudować projekt na Windows, nie zapomnij połączyć biblioteki systemowej advapi32.lib — jest potrzebna do pracy z entropią. A dla AVR upewnij się, że włączyłeś optymalizację kompilatora (-O1 i wyższe), w przeciwnym razie biblioteka może nie działać poprawnie ze względu na specyfikę obsługi stosu.

Ogólnie rzecz biorąc, to świetny przykład tego, jak powinna wyglądać wyspecjalizowana biblioteka: wąski fokus, minimalne zależności i przewidywalne zachowanie. Jeśli Twój sprzęt jest zbyt słaby dla TLS, ale potrzebujesz bezpieczeństwa — micro-ecc zdecydowanie zasługuje na miejsce w Twoim src/lib.