GoSuda

Struktura implementacji FIPS 140-2 i FIPS 140-3 w standardowej bibliotece kryptograficznej Go

By Gosunuts views ...

FIPS 140 ( Federal Information Processing Standard Publication 140 )

FIPS 140 to standard certyfikacji bezpieczeństwa modułów kryptograficznych, ustanowiony przez amerykański NIST. Standard ten ocenia, czy dany moduł kryptograficzny lub biblioteka spełniają wymagania bezpieczeństwa zdefiniowane przez NIST. W związku z tym uzyskanie certyfikacji FIPS 140 oznacza, że dany moduł posiada oficjalnie wiarygodny poziom bezpieczeństwa, co umożliwia jego stosowanie w dziedzinach o wysokich wymaganiach dotyczących ochrony, takich jak finanse, opieka zdrowotna oraz obronność.

Od momentu swojego pierwszego ustanowienia w 1994 roku, standard FIPS 140 został znowelizowany w 2001 roku jako FIPS 140-2, a w 2019 roku jako FIPS 140-3. Do chwili obecnej wiele systemów oraz aplikacji nadal wymaga certyfikacji FIPS 140-2 lub FIPS 140-3.

FIPS 140 a języki programowania

Z tego powodu moduły kryptograficzne posiadające certyfikację FIPS 140 są powszechnie stosowane w różnych językach programowania i środowiskach jako standard de facto. Do reprezentatywnych przykładów należą OpenSSL, BoringSSL, LibreSSL oraz NSS, które są najbardziej rozpowszechnionymi modułami w aplikacjach o kluczowym znaczeniu dla bezpieczeństwa.

Większość modułów z certyfikacją FIPS 140 została napisana w języku C lub C++. Z tego względu w językach takich jak PHP, Python czy Javascript zamiast bezpośredniego używania tych modułów konfiguruje się środowisko FIPS poprzez integrowanie ich za pomocą zewnętrznych modułów dostawców (Provider). Podejście to wiąże się jednak z pewnymi ograniczeniami.

  • Problem niezgodności wersji

    Certyfikacja FIPS 140 jest przyznawana wyłącznie dla określonych wersji. W związku z tym użycie najnowszej wersji modułu wymaga ponownego przejścia procesu certyfikacji, co może prowadzić do niezgodności wersji pomiędzy modułem wykorzystywanym przez aplikację a modułem posiadającym certyfikat FIPS. Użycie nieautoryzowanej wersji skutkuje tym, że dane środowisko przestaje być uznawane za środowisko z certyfikacją FIPS.

  • Ładowanie dynamiczne a spadek wydajności

    Większość języków ładowania modułów z certyfikacją FIPS 140 dokonuje w formie bibliotek dynamicznych. Podejście to może powodować spadek wydajności podczas inicjalizacji oraz wykonywania, a w przypadku wystąpienia problemów w czasie działania (runtime) niesie ze sobą ryzyko bezpośredniego wpływu na stabilność całej aplikacji.

  • Podatności bezpieczeństwa

    Jak wspomniano powyżej, w strukturze integrującej moduły zewnętrzne, takiej jak OpenSSL Provider, istnieje ryzyko bezpośredniego przeniesienia podatności bezpieczeństwa tych modułów na aplikację. Ponadto sama warstwa komunikacji pomiędzy aplikacją a modułem zewnętrznym staje się dodatkową powierzchnią ataku, co wymaga ustanowienia osobnej warstwy zabezpieczeń w celu jej ochrony. Zwiększa to stopień złożoności i może prowadzić do powstawania nieprzewidzianych podatności.

FIPS 140 a Golang

Z tego powodu język Golang przyjął inną strategię. Go wybrał rozwiązanie polegające na bezpośrednim wspieraniu certyfikacji FIPS 140 w oficjalnej bibliotece kryptograficznej, bez polegania na zewnętrznych narzędzeniach. W rezultacie programiści nie muszą instalować ani konfigurować dodatkowych dostawców (Provider), a jedynie aktywować tryb certyfikacji FIPS (GOFIPS=1), korzystając jednocześnie ze standardowej paczki crypto. W tym procesie granica komunikacji z modułami zewnętrznymi zostaje usunięta, co podnosi poziom bezpieczeństwa, a operacyjność ulega uproszczeniu ze względu na konieczność dystrybucji wyłącznie pojedynczego, statycznie skompilowanego pliku binarnego.

FIPS 140-2 a Golang

W tym celu Golang wbudował w środowisko uruchomieniowe (runtime) języka Go moduł BoringCrypto pochodzący z BoringSSL, uzyskując certyfikację FIPS 140-2. Moduł BoringCrypto może zostać aktywowany w określonych dystrybucjach począwszy od wersji Go 1.19, dzięki czemu aplikacje napisanę w Go mogą konfigurować środowisko zgodne z certyfikacją FIPS 140-2 bez użycia dodatkowych modułów zewnętrznych.

Ponieważ jednak BoringCrypto opiera się na bibliotece OpenSSL, nadal występuje w nim zależność od języka C. W związku z tym aplikacje w Go nie były budowane jako całkowicie niezależne pliki binarne, co wiązało się z ograniczeniem polegającym na konieczności jednoczesnego dystrybuowania wymaganych bibliotek języka C.

FIPS 140-3 a Golang

Aby przezwyciężyć te ograniczenia, zespół języka Go ulepszył dotychczasową standardową bibliotekę crypto, dostosowując ją do specyfikacji FIPS 140-3. Ten udoskonalony moduł zaczął być udostępniany eksperymentalnie od wersji Go 1.21, a obecnie trwają prace nad oceną certyfikacyjną FIPS 140-3 ze strony NIST.Lista modułów w trakcie procesu oceny NIST FIPS 140-3

Świadczy to o dojrzałości biblioteki kryptograficznej języka Go, co umożliwia temu językowi oferowanie środowiska z certyfikacją FIPS 140-3 w postaci w pełni niezależnego, pojedynczego pliku binarnego.

Co więcej, zespół języka Go nie poprzestał na spełnieniu standardu FIPS 140-3, lecz samodzielnie wzmocnił jego bezpieczeństwo.

  • Fail Fast

    Tryb FIPS w języku Go wdraża model bezpieczeństwa Fail Fast, który w przypadku wywołania niezweryfikowanego algorytmu natychmiast przerywa działanie za pomocą mechanizmu panic. W przeciwieństwie do modeli opartych na dostawcach (Provider) w innych językach, które pozostawiają możliwość przejścia do trybu awaryjnego (fallback), zapewnia to bardziej rygorystyczną i jednoznaczną gwarancję w zakresie bezpieczeństwa oraz zgodności z przepisami regulacyjnymi.

  • Hedged Signature

    Standard FIPS 140-3 zaleca metodę RFC6979 podczas tworzenia podpisów ECDSA. Go wprowadza jednak dodatkowo metodę Hedged, co zapewnia silniejszą obronę przed atakami kanałów bocznych (side-channel attacks), które mogą wystąpić w procesie podpisywania.

  • Wzmocniony generator liczb pseudolosowych

    Generator liczb pseudolosowych w języku Go, korzystając z generatora DRBG (Deterministic Random Bit Generator) w przestrzeni użytkownika, wprowadza dodatkowo entropię z jądra systemu operacyjnego, generując liczby losowe o wysokiej jakości zarówno w przestrzeni użytkownika, jak i w przestrzeni jądra. Pozwala to na dalsze wzmocnienie bezpieczeństwa generatora liczb losowych.