weryfikacja modułu nie powiodła się podpis i / lub brak wymaganego klucza

11

Pracuję na module jądra, który działa dobrze. Jednak przeglądając dmesg, widzę komunikat dotyczący mojego modułu, że weryfikacja modułu nie powiodła się (podpis modułu nie powiódł się i / lub brak wymaganego klucza).

Jak mogę rozwiązać ten problem? Jak uzyskać podpis mojego modułu w celu weryfikacji?

Dzięki.

użytkownik2000888
źródło

Odpowiedzi:

3

Wszystko, czego potrzebujesz, opisano tutaj

OBSŁUGA MODUŁU KERNEL


ZAWARTOŚĆ

  • Przegląd.
  • Konfigurowanie podpisywania modułów.
  • Generowanie kluczy do podpisywania.
  • Klucze publiczne w jądrze.
  • Moduły podpisujące ręcznie.
  • Podpisane moduły i stripping.
  • Ładowanie podpisanych modułów.
  • Niepoprawne podpisy i niepodpisane moduły.
  • Administrowanie / ochrona klucza prywatnego.

PRZEGLĄD

Funkcja podpisywania modułów jądra podpisuje kryptograficznie moduły podczas instalacji, a następnie sprawdza podpis po załadowaniu modułu. Pozwala to na zwiększenie bezpieczeństwa jądra poprzez uniemożliwienie ładowania niepodpisanych modułów lub modułów podpisanych nieprawidłowym kluczem. Podpisywanie modułów zwiększa bezpieczeństwo, utrudniając załadowanie złośliwego modułu do jądra. Sprawdzanie podpisu modułu jest wykonywane przez jądro, więc nie ma potrzeby posiadania zaufanych bitów przestrzeni użytkownika.

Ta funkcja używa standardowych certyfikatów ITU-T X.509 do kodowania zaangażowanych kluczy publicznych. Same podpisy nie są zakodowane w żadnym typie standardu przemysłowego. Obiekt obsługuje obecnie tylko standard szyfrowania klucza publicznego RSA (chociaż można go podłączyć i umożliwia korzystanie z innych). Możliwe algorytmy mieszające, które można zastosować, to SHA-1, SHA-224, SHA-256, SHA-384 i SHA-512 (algorytm jest wybierany na podstawie danych w podpisie).


KONFIGURACJA SYGNALIZACJI MODUŁU

Funkcja podpisywania modułów jest włączana, przechodząc do sekcji „Włącz obsługę modułów ładowalnych” konfiguracji jądra i włączając

CONFIG_MODULE_SIG   "Module signature verification"

Ma wiele dostępnych opcji:

  1. „Wymagaj prawidłowego podpisania modułów” (CONFIG_MODULE_SIG_FORCE)

    Określa to, jak jądro powinno postępować z modułem, który ma sygnaturę, dla której klucz nie jest znany, lub modułem, który nie jest podpisany.

    Jeśli jest wyłączone (tzn. „Permissive”), wówczas moduły, dla których klucz nie jest dostępny, a moduły niepodpisane są dozwolone, ale jądro zostanie oznaczone jako skażone, a odnośne moduły zostaną oznaczone jako skażone, pokazane ze znakiem „E”.

    Jeśli jest włączony (tzn. „Restrykcyjny”), ładowane będą tylko moduły, które mają prawidłowy podpis, który można zweryfikować za pomocą klucza publicznego znajdującego się w posiadaniu jądra. Wszystkie pozostałe moduły wygenerują błąd.

    Niezależnie od tego ustawienia, jeśli moduł ma blok podpisu, którego nie można przeanalizować, zostanie on odrzucony z ręki.

  2. „Automatycznie podpisuj wszystkie moduły” (CONFIG_MODULE_SIG_ALL)

    Jeśli ta opcja jest włączona, moduły będą automatycznie podpisywane podczas fazy instalacji modułów. Jeśli ta opcja jest wyłączona, moduły muszą być podpisane ręcznie przy użyciu:

    scripts/sign-file
    
  3. „Którym algorytmem mieszającym należy podpisać moduły?”

    To pokazuje wybór algorytmu mieszającego, który faza instalacji podpisze moduły:

    CONFIG_MODULE_SIG_SHA1      "Sign modules with SHA-1"
    CONFIG_MODULE_SIG_SHA224    "Sign modules with SHA-224"
    CONFIG_MODULE_SIG_SHA256    "Sign modules with SHA-256"
    CONFIG_MODULE_SIG_SHA384    "Sign modules with SHA-384"
    CONFIG_MODULE_SIG_SHA512    "Sign modules with SHA-512"
    

    Wybrany tutaj algorytm zostanie również wbudowany w jądro (zamiast być modułem), aby moduły podpisane tym algorytmem mogły sprawdzać swoje podpisy bez powodowania pętli zależności.

  4. „Nazwa pliku lub identyfikator URI PKCS # 11 klucza podpisującego moduł” (CONFIG_MODULE_SIG_KEY)

    Ustawienie tej opcji na wartość inną niż domyślna „certs / signing_key.pem” spowoduje wyłączenie automatycznej generacji kluczy do podpisywania i umożliwi podpisanie modułów jądra za pomocą wybranego klucza. Podany ciąg powinien identyfikować plik zawierający zarówno klucz prywatny, jak i odpowiadający mu certyfikat X.509 w formie PEM, lub - w systemach, w których funkcjonuje OpenSSL ENGINE_pkcs11 - identyfikator URI PKCS # 11 zdefiniowany przez RFC7512. W tym drugim przypadku identyfikator URI PKCS # 11 powinien odnosić się zarówno do certyfikatu, jak i klucza prywatnego.

    Jeśli plik PEM zawierający klucz prywatny jest zaszyfrowany lub token PKCS # 11 wymaga kodu PIN, można go podać w czasie kompilacji za pomocą zmiennej KBUILD_SIGN_PIN.

  5. „Dodatkowe klucze X.509 dla domyślnego systemowego kluczy” (CONFIG_SYSTEM_TRUSTED_KEYS)

    Ta opcja może być ustawiona na nazwę pliku w pliku PEM zawierającym dodatkowe certyfikaty, które domyślnie zostaną włączone do systemowego kluczy.

Zauważ, że włączenie podpisywania modułów dodaje zależność od pakietów deweloperskich OpenSSL do procesów kompilacji jądra dla narzędzia wykonującego podpisywanie.


WYTWARZANIE KLUCZY SYGNALIZACYJNYCH

Klucze kryptograficzne są wymagane do generowania i sprawdzania podpisów. Klucz prywatny służy do generowania podpisu, a odpowiedni klucz publiczny służy do sprawdzania go. Klucz prywatny jest potrzebny tylko podczas kompilacji, po czym można go bezpiecznie usunąć lub przechowywać. Klucz publiczny jest wbudowany w jądro, dzięki czemu można go używać do sprawdzania podpisów podczas ładowania modułów.

W normalnych warunkach, gdy CONFIG_MODULE_SIG_KEY nie ulegnie zmianie od wartości domyślnej, kompilacja jądra automatycznie wygeneruje nową parę kluczy za pomocą openssl, jeśli nie istnieje w pliku:

certs/signing_key.pem

podczas budowania vmlinux (publiczna część klucza musi być wbudowana w vmlinux) przy użyciu parametrów w:

certs/x509.genkey

plik (który jest również generowany, jeśli jeszcze nie istnieje).

Zdecydowanie zaleca się podanie własnego pliku x509.genkey.

W szczególności w pliku x509.genkey sekcja req_distinguished_name powinna zostać zmieniona z domyślnej:

[ req_distinguished_name ]
#O = Unspecified company
CN = Build time autogenerated kernel key
#emailAddress = [email protected]

Wygenerowany rozmiar klucza RSA można również ustawić za pomocą:

[ req ]
default_bits = 4096

Możliwe jest również ręczne wygenerowanie kluczy prywatnych / publicznych plików za pomocą pliku konfiguracyjnego generowania klucza x509.genkey w węźle głównym drzewa źródeł jądra Linux i polecenia openssl. Poniżej przedstawiono przykład generowania plików kluczy publicznych / prywatnych:

openssl req -new -nodes -utf8 -sha256 -days 36500 -batch -x509 \
   -config x509.genkey -outform PEM -out kernel_key.pem \
   -keyout kernel_key.pem

Pełna nazwa ścieżki wynikowego pliku kernel_key.pem może być następnie określona w opcji CONFIG_MODULE_SIG_KEY, a certyfikat i klucz w nim zostaną użyte zamiast automatycznie wygenerowanej pary kluczy.


KLUCZE PUBLICZNE W Jądrze

Jądro zawiera pierścień kluczy publicznych, które mogą być przeglądane przez root. Są w breloku o nazwie „.system_keyring”, który można zobaczyć:

[root@deneb ~]# cat /proc/keys
...
223c7853 I------     1 perm 1f030000     0     0 keyring   .system_keyring: 1
302d2d52 I------     1 perm 1f010000     0     0 asymmetri Fedora kernel signing key: d69a84e6bce3d216b979e9505b3e3ef9a7118079: X509.RSA a7118079 []
...

Oprócz klucza publicznego generowanego specjalnie do podpisywania modułów, dodatkowe zaufane certyfikaty mogą być dostarczane w pliku zakodowanym w PEM, do którego odwołuje się opcja konfiguracji CONFIG_SYSTEM_TRUSTED_KEYS.

Ponadto kod architektury może pobierać klucze publiczne ze sklepu sprzętowego i dodawać je również (np. Z bazy danych kluczy UEFI).

Wreszcie można dodać dodatkowe klucze publiczne, wykonując:

keyctl padd asymmetric "" [.system_keyring-ID] <[key-file]

na przykład:

keyctl padd asymmetric "" 0x223c7853 <my_public_key.x509

Należy jednak pamiętać, że jądro zezwoli na dodawanie kluczy tylko do .system_keyring tylko wtedy, gdy opakowanie X.509 nowego klucza jest poprawnie podpisane przez klucz, który jest już rezydentem w .system_keyring w chwili dodania klucza.


MODUŁY PODPISANIA RĘCZNIE

Aby ręcznie podpisać moduł, użyj narzędzia skryptów / pliku-pliku dostępnego w drzewie źródeł jądra Linux. Skrypt wymaga 4 argumentów:

1.  The hash algorithm (e.g., sha256)
2.  The private key filename or PKCS#11 URI
3.  The public key filename
4.  The kernel module to be signed

Oto przykład podpisania modułu jądra:

scripts/sign-file sha512 kernel-signkey.priv \
    kernel-signkey.x509 module.ko

Zastosowany algorytm skrótu nie musi być zgodny z skonfigurowanym, ale jeśli nie, należy upewnić się, że algorytm skrótu jest wbudowany w jądro lub że można go załadować bez konieczności samodzielnego działania.

Jeśli klucz prywatny wymaga hasła lub kodu PIN, można go podać w zmiennej środowiskowej $ KBUILD_SIGN_PIN.


PODPISANE MODUŁY I PASKI

Podpisany moduł ma podpis cyfrowy po prostu dołączony na końcu. Ciąg „~ Podpis modułu ~ ~”. na końcu pliku modułu potwierdza obecność podpisu, ale nie potwierdza jego poprawności!

Podpisane moduły są BRITTLE, ponieważ podpis znajduje się poza zdefiniowanym kontenerem ELF. W związku z tym NIE MOGĄ zostać usunięte po obliczeniu i załączeniu podpisu. Uwaga: cały moduł jest podpisanym ładunkiem, w tym wszelkimi informacjami debugowania obecnymi w momencie podpisywania.


ŁADOWANIE PODPISANYCH MODUŁÓW

Moduły są ładowane za pomocą insmod, modprobe, init_module () lub finit_module (), dokładnie tak jak w przypadku modułów niepodpisanych, ponieważ w przestrzeni użytkownika nie wykonuje się żadnego przetwarzania. Sprawdzanie podpisów odbywa się w jądrze.


NIEWAŻNE PODPISY I PODPISANE MODUŁY

Jeśli CONFIG_MODULE_SIG_FORCE jest włączony lub w wierszu komend jądra podano enforcemodulesig = 1, jądro załaduje tylko poprawnie podpisane moduły, dla których ma klucz publiczny. W przeciwnym razie załaduje również moduły, które nie są podpisane. Dowolny moduł, dla którego jądro ma klucz, ale który wykazuje niedopasowanie sygnatur, nie będzie mógł się ładować.

Każdy moduł, który ma nierozłączną sygnaturę, zostanie odrzucony.


ADMINISTRACJA / OCHRONA PRYWATNEGO KLUCZA

Ponieważ klucz prywatny służy do podpisywania modułów, wirusy i złośliwe oprogramowanie mogą używać klucza prywatnego do podpisywania modułów i narażania systemu operacyjnego na szwank. Klucz prywatny musi zostać zniszczony lub przeniesiony w bezpieczne miejsce i nie może być przechowywany w węźle głównym drzewa źródeł jądra.

AB
źródło
Dzięki, ale absolutnie widziałem wcześniej ten tekst. Problem, na który wpadam, polega na tym, że chociaż mogę podpisać mój plik, nadal nie mogę go załadować, ponieważ: „Jądro zezwoli na dodawanie kluczy tylko do .system_keyring tylko wtedy, gdy opakowanie X.509 nowego klucza jest poprawnie podpisane przez klucz, który jest już rezydentem w .system_keyring w chwili dodania klucza. "
OmnipotentEntity
Widziałem to także kilka razy, ale to nie pomaga. W Ubuntu występuje błąd, który wpływa na wszystkie płyty główne, które nie obsługują interfejsu uefi: bugs.launchpad.net/ubuntu/+source/linux-lts-xenial/+bug/1656670
musbach
0

Edytuj ./include/generated/autoconf.hi zmień linię

define CONFIG_MODULE_SIG 1

do

define CONFIG_MODULE_SIG 0
Daniel
źródło