la verificación del módulo falló la firma y / o falta la clave requerida

9

Estoy trabajando en un módulo de kernel, que funciona bien. Sin embargo, mirando a través de dmesg, veo un mensaje con respecto a mi módulo de que la verificación del módulo ha fallado (falta la firma de verificación del módulo y / o falta la clave requerida).

¿Cómo puedo resolver este problema? ¿Cómo firmo mi módulo para la verificación?

Gracias.

user2000888
fuente

Respuestas:

2

Todo lo que necesitas se describe aquí.

INSTALACIÓN DE FIRMA DEL MÓDULO KERNEL


CONTENIDO

  • Visión general.
  • Configuración de la firma del módulo.
  • Generando claves de firma.
  • Claves públicas en el kernel.
  • Firma manual de módulos.
  • Módulos firmados y pelado.
  • Cargando módulos firmados.
  • Firmas no válidas y módulos sin firmar.
  • Administrar / proteger la clave privada.

VISIÓN GENERAL

El recurso de firma del módulo del núcleo firma criptográficamente los módulos durante la instalación y luego verifica la firma al cargar el módulo. Esto permite una mayor seguridad del núcleo al no permitir la carga de módulos sin firmar o módulos firmados con una clave no válida. La firma de módulos aumenta la seguridad al dificultar la carga de un módulo malicioso en el núcleo. La verificación de la firma del módulo la realiza el kernel para que no sea necesario tener bits de espacio de usuario de confianza.

Esta instalación utiliza certificados estándar X.509 ITU-T para codificar las claves públicas involucradas. Las firmas no están codificadas en ningún tipo de estándar industrial. Actualmente, la instalación solo admite el estándar de cifrado de clave pública RSA (aunque es conectable y permite que se usen otros). Los posibles algoritmos hash que se pueden usar son SHA-1, SHA-224, SHA-256, SHA-384 y SHA-512 (el algoritmo se selecciona mediante datos en la firma).


CONFIGURAR LA FIRMA DEL MÓDULO

La función de firma del módulo se habilita yendo a la sección "Habilitar el soporte del módulo cargable" de la configuración del kernel y activando

CONFIG_MODULE_SIG   "Module signature verification"

Esto tiene una serie de opciones disponibles:

  1. "Requerir que los módulos estén firmados de manera válida" (CONFIG_MODULE_SIG_FORCE)

    Esto especifica cómo el núcleo debe tratar con un módulo que tiene una firma para la cual no se conoce la clave o un módulo que no está firmado.

    Si esto está desactivado (es decir, "permisivo"), entonces los módulos para los que la clave no está disponible y los módulos que no están firmados están permitidos, pero el núcleo se marcará como contaminado y los módulos correspondientes se marcarán como contaminado, como se muestra con el caracter 'E'.

    Si está activado (es decir, "restrictivo"), solo se cargarán los módulos que tengan una firma válida que pueda ser verificada por una clave pública en posesión del núcleo. Todos los demás módulos generarán un error.

    Independientemente de la configuración aquí, si el módulo tiene un bloque de firma que no se puede analizar, se rechazará de inmediato.

  2. "Firmar automáticamente todos los módulos" (CONFIG_MODULE_SIG_ALL)

    Si esto está activado, los módulos se firmarán automáticamente durante la fase de instalación de módulos de una compilación. Si esto está desactivado, entonces los módulos deben firmarse manualmente usando:

    scripts/sign-file
    
  3. "¿Con qué algoritmo hash se deben firmar los módulos?"

    Esto presenta una elección de qué algoritmo hash la fase de instalación firmará los módulos con:

    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"
    

    El algoritmo seleccionado aquí también se integrará en el núcleo (en lugar de ser un módulo) para que los módulos firmados con ese algoritmo puedan verificar sus firmas sin causar un bucle de dependencia.

  4. "Nombre de archivo o URI PKCS # 11 de la clave de firma del módulo" (CONFIG_MODULE_SIG_KEY)

    Establecer esta opción en algo diferente a su valor predeterminado de "certs / Signature_key.pem" deshabilitará la generación automática de claves de firma y permitirá que los módulos del núcleo se firmen con una clave de su elección. La cadena provista debe identificar un archivo que contenga una clave privada y su correspondiente certificado X.509 en forma PEM o, en sistemas donde el OpenSSL ENGINE_pkcs11 es funcional, un URI PKCS # 11 según lo definido por RFC7512. En el último caso, el URI PKCS # 11 debe hacer referencia tanto a un certificado como a una clave privada.

    Si el archivo PEM que contiene la clave privada está encriptado, o si el token PKCS # 11 requiere un PIN, esto se puede proporcionar en el momento de la compilación mediante la variable KBUILD_SIGN_PIN.

  5. "Claves X.509 adicionales para el conjunto de claves predeterminado del sistema" (CONFIG_SYSTEM_TRUSTED_KEYS)

    Esta opción se puede establecer en el nombre de archivo de un archivo codificado por PEM que contiene certificados adicionales que se incluirán en el conjunto de claves del sistema de forma predeterminada.

Tenga en cuenta que habilitar la firma del módulo agrega una dependencia en los paquetes de desarrollo de OpenSSL a los procesos de compilación del núcleo para la herramienta que hace la firma.


GENERANDO CLAVES DE FIRMA

Se requieren pares de claves criptográficos para generar y verificar firmas. Una clave privada se usa para generar una firma y la clave pública correspondiente se usa para verificarla. La clave privada solo se necesita durante la compilación, después de lo cual se puede eliminar o almacenar de forma segura. La clave pública se integra en el kernel para que pueda usarse para verificar las firmas a medida que se cargan los módulos.

En condiciones normales, cuando CONFIG_MODULE_SIG_KEY no cambia desde su valor predeterminado, la compilación del núcleo generará automáticamente un nuevo par de claves usando openssl si no existe uno en el archivo:

certs/signing_key.pem

durante la construcción de vmlinux (la parte pública de la clave debe integrarse en vmlinux) utilizando parámetros en:

certs/x509.genkey

archivo (que también se genera si aún no existe).

Se recomienda encarecidamente que proporcione su propio archivo x509.genkey.

En particular, en el archivo x509.genkey, la sección req_distinguished_name debe modificarse del valor predeterminado:

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

El tamaño de clave RSA generado también se puede configurar con:

[ req ]
default_bits = 4096

También es posible generar manualmente los archivos privados / públicos clave utilizando el archivo de configuración de generación de claves x509.genkey en el nodo raíz del árbol de fuentes del kernel de Linux y el comando openssl. El siguiente es un ejemplo para generar los archivos de clave pública / privada:

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

El nombre de ruta completo para el archivo kernel_key.pem resultante se puede especificar en la opción CONFIG_MODULE_SIG_KEY, y el certificado y la clave se utilizarán en lugar de un par de claves autogenerado.


CLAVES PÚBLICAS EN EL KERNEL

El núcleo contiene un anillo de claves públicas que puede ver la raíz. Están en un llavero llamado ".system_keyring" que puede ser visto por:

[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 []
...

Más allá de la clave pública generada específicamente para la firma del módulo, se pueden proporcionar certificados confiables adicionales en un archivo codificado por PEM al que hace referencia la opción de configuración CONFIG_SYSTEM_TRUSTED_KEYS.

Además, el código de arquitectura puede tomar claves públicas de una ferretería y agregarlas también (por ejemplo, de la base de datos de claves UEFI).

Finalmente, es posible agregar claves públicas adicionales haciendo:

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

p.ej:

keyctl padd asymmetric "" 0x223c7853 <my_public_key.x509

Sin embargo, tenga en cuenta que el núcleo solo permitirá que se agreguen claves a .system_keyring si el contenedor X.509 de la nueva clave está firmado válidamente por una clave que ya reside en .system_keyring en el momento en que se agregó la clave.


MÓDULOS DE FIRMA MANUAL

Para firmar manualmente un módulo, use la herramienta de secuencias de comandos / archivo de firma disponible en el árbol de fuentes del kernel de Linux. El script requiere 4 argumentos:

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

El siguiente es un ejemplo para firmar un módulo de kernel:

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

El algoritmo hash utilizado no tiene que coincidir con el configurado, pero si no lo hace, debe asegurarse de que el algoritmo hash esté integrado en el núcleo o se pueda cargar sin necesidad de él mismo.

Si la clave privada requiere una frase de contraseña o PIN, se puede proporcionar en la variable de entorno $ KBUILD_SIGN_PIN.


MÓDULOS Y BANDAS FIRMADAS

Un módulo firmado tiene una firma digital simplemente agregada al final. La cadena "~ Firma del módulo añadida ~". al final del archivo del módulo confirma que hay una firma, ¡pero no confirma que la firma sea válida!

Los módulos firmados son BRITTLE ya que la firma está fuera del contenedor ELF definido. Por lo tanto, NO PUEDEN quitarse una vez que la firma se calcule y se adjunte. Tenga en cuenta que todo el módulo es la carga útil firmada, incluida toda la información de depuración presente en el momento de la firma.


CARGANDO MÓDULOS FIRMADOS

Los módulos se cargan con insmod, modprobe, init_module () o finit_module (), exactamente como para los módulos sin firmar, ya que no se realiza ningún procesamiento en el espacio de usuario. La verificación de firmas se realiza dentro del núcleo.


FIRMAS NO VÁLIDAS Y MÓDULOS NO FIRMADOS

Si CONFIG_MODULE_SIG_FORCE está habilitado o se proporciona enforcemodulesig = 1 en la línea de comando del kernel, el kernel solo cargará módulos firmados válidamente para los que tiene una clave pública. De lo contrario, también cargará módulos que no estén firmados. No se permitirá cargar ningún módulo para el que el núcleo tenga una clave, pero que demuestre que no coincida con la firma.

Cualquier módulo que tenga una firma no analizable será rechazado.


ADMINISTRACIÓN / PROTECCIÓN DE LA CLAVE PRIVADA

Dado que la clave privada se usa para firmar módulos, los virus y el malware podrían usar la clave privada para firmar módulos y comprometer el sistema operativo. La clave privada debe destruirse o moverse a una ubicación segura y no mantenerse en el nodo raíz del árbol de origen del núcleo.

AB
fuente
Gracias pero, absolutamente he visto este texto antes. El problema con el que me encuentro es que aunque puedo firmar mi archivo, no puedo cargar el archivo todavía porque: "el kernel solo permitirá que se agreguen claves a .system_keyring si el contenedor X.509 de la nueva clave está firmado válidamente por una clave que ya reside en .system_keyring en el momento en que se agregó la clave ".
OmnipotentEntity
También he visto esto varias veces, pero no ayuda. Hay un error en Ubuntu que afecta a todas las placas base que no admiten uefi: bugs.launchpad.net/ubuntu/+source/linux-lts-xenial/+bug/1656670
musbach
0

Edita ./include/generated/autoconf.hy cambia la línea

define CONFIG_MODULE_SIG 1

a

define CONFIG_MODULE_SIG 0
daniel
fuente