falha na verificação do módulo e / ou falta da chave necessária

9

Estou trabalhando em um módulo do kernel, que está funcionando bem. No entanto, examinando o dmesg, vejo uma mensagem sobre o meu módulo informando que a verificação do módulo falhou (a verificação do módulo falhou na assinatura e / ou a chave necessária estava faltando).

Como posso resolver esse problema? Como assino meu módulo para verificação?

Obrigado.

user2000888
fonte

Respostas:

2

Tudo o que você precisa está descrito aqui

FACILIDADE DE ASSINATURA DO MÓDULO KERNEL


CONTEÚDO

  • Visão geral.
  • Configurando a assinatura do módulo.
  • Gerando chaves de assinatura.
  • Chaves públicas no kernel.
  • Assinando módulos manualmente.
  • Módulos assinados e decapagem.
  • Carregando módulos assinados.
  • Assinaturas não válidas e módulos não assinados.
  • Administrando / protegendo a chave privada.

VISÃO GERAL

O recurso de assinatura do módulo do kernel assina criptograficamente os módulos durante a instalação e depois verifica a assinatura ao carregar o módulo. Isso permite maior segurança do kernel, impedindo o carregamento de módulos não assinados ou módulos assinados com uma chave inválida. A assinatura do módulo aumenta a segurança, dificultando o carregamento de um módulo malicioso no kernel. A verificação da assinatura do módulo é feita pelo kernel, para que não seja necessário ter bits confiáveis ​​do espaço do usuário.

Esse recurso usa certificados padrão X.509 ITU-T para codificar as chaves públicas envolvidas. As assinaturas não são elas próprias codificadas em nenhum tipo de padrão industrial. Atualmente, o recurso suporta apenas o padrão de criptografia de chave pública RSA (embora seja conectável e permita que outros sejam usados). Os possíveis algoritmos de hash que podem ser usados ​​são SHA-1, SHA-224, SHA-256, SHA-384 e SHA-512 (o algoritmo é selecionado pelos dados na assinatura).


CONFIGURAÇÃO DA ASSINATURA DO MÓDULO

O recurso de assinatura do módulo é ativado, indo para a seção "Ativar suporte ao módulo carregável" da configuração do kernel e ativando

CONFIG_MODULE_SIG   "Module signature verification"

Isso tem várias opções disponíveis:

  1. "Requer que os módulos sejam assinados validamente" (CONFIG_MODULE_SIG_FORCE)

    Isso especifica como o kernel deve lidar com um módulo que possui uma assinatura cuja chave não é conhecida ou um módulo que não está assinado.

    Se estiver desativado (ou seja, "permissivo"), os módulos para os quais a chave não está disponível e os módulos não assinados são permitidos, mas o kernel será marcado como contaminado e os módulos em questão serão marcados como contaminado, mostrado com o caractere 'E'.

    Se estiver ativado (ou seja, "restritivo"), somente os módulos que possuem uma assinatura válida que pode ser verificada por uma chave pública em posse do kernel serão carregados. Todos os outros módulos irão gerar um erro.

    Independentemente da configuração aqui, se o módulo tiver um bloco de assinatura que não pode ser analisado, ele será rejeitado imediatamente.

  2. "Assinar automaticamente todos os módulos" (CONFIG_MODULE_SIG_ALL)

    Se estiver ativado, os módulos serão automaticamente assinados durante a fase modules_install de uma construção. Se estiver desativado, os módulos deverão ser assinados manualmente usando:

    scripts/sign-file
    
  3. "Com qual algoritmo hash os módulos devem ser assinados?"

    Isso apresenta uma escolha de qual algoritmo de hash a fase de instalação assinará os módulos com:

    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"
    

    O algoritmo selecionado aqui também será incorporado ao kernel (em vez de ser um módulo) para que os módulos assinados com esse algoritmo possam ter suas assinaturas verificadas sem causar um loop de dependência.

  4. "Nome do arquivo ou URI PKCS # 11 da chave de assinatura do módulo" (CONFIG_MODULE_SIG_KEY)

    Definir esta opção como algo diferente do padrão "certs / signature_key.pem" desabilitará a geração automática de chaves de assinatura e permitirá que os módulos do kernel sejam assinados com uma chave de sua escolha. A cadeia de caracteres fornecida deve identificar um arquivo contendo uma chave privada e seu certificado X.509 correspondente no formato PEM, ou - nos sistemas em que o OpenSSL ENGINE_pkcs11 é funcional - um URI PKCS # 11, conforme definido pelo RFC7512. Neste último caso, o URI do PKCS # 11 deve fazer referência a um certificado e a uma chave privada.

    Se o arquivo PEM que contém a chave privada estiver criptografado ou se o token PKCS # 11 solicitar um PIN, ele poderá ser fornecido no tempo de construção por meio da variável KBUILD_SIGN_PIN.

  5. "Chaves X.509 adicionais para chaveiro padrão do sistema" (CONFIG_SYSTEM_TRUSTED_KEYS)

    Essa opção pode ser definida como o nome do arquivo de um arquivo codificado em PEM contendo certificados adicionais que serão incluídos no chaveiro do sistema por padrão.

Observe que a habilitação da assinatura do módulo adiciona uma dependência dos pacotes de desenvolvimento OpenSSL aos processos de construção do kernel para a ferramenta que faz a assinatura.


GERANDO CHAVES DE ASSINATURA

Pares de chaves criptográficos são necessários para gerar e verificar assinaturas. Uma chave privada é usada para gerar uma assinatura e a chave pública correspondente é usada para verificá-la. A chave privada é necessária apenas durante a compilação, após a qual pode ser excluída ou armazenada com segurança. A chave pública é incorporada ao kernel para que possa ser usada para verificar as assinaturas à medida que os módulos são carregados.

Sob condições normais, quando CONFIG_MODULE_SIG_KEY permanecer inalterado em relação ao padrão, a compilação do kernel gerará automaticamente um novo par de chaves usando o openssl se não existir no arquivo:

certs/signing_key.pem

durante a construção do vmlinux (a parte pública da chave precisa ser incorporada ao vmlinux) usando parâmetros no:

certs/x509.genkey

arquivo (que também é gerado se ainda não existir).

É altamente recomendável que você forneça seu próprio arquivo x509.genkey.

Mais notavelmente, no arquivo x509.genkey, a seção req_distinguished_name deve ser alterada do padrão:

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

O tamanho da chave RSA gerada também pode ser definido com:

[ req ]
default_bits = 4096

Também é possível gerar manualmente os arquivos privados / públicos chave usando o arquivo de configuração de geração de chave x509.genkey no nó raiz da árvore de fontes do kernel Linux e o comando openssl. A seguir, é apresentado um exemplo para gerar os arquivos de chave 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

O nome completo do caminho para o arquivo kernel_key.pem resultante pode ser especificado na opção CONFIG_MODULE_SIG_KEY, e o certificado e a chave nele serão utilizados em vez de um par de chaves gerado automaticamente.


CHAVES PÚBLICAS NO KERNEL

O kernel contém um anel de chaves públicas que podem ser exibidas pela raiz. Eles estão em um chaveiro chamado ".system_keyring" que pode 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 []
...

Além da chave pública gerada especificamente para a assinatura do módulo, certificados confiáveis ​​adicionais podem ser fornecidos em um arquivo codificado em PEM referenciado pela opção de configuração CONFIG_SYSTEM_TRUSTED_KEYS.

Além disso, o código de arquitetura pode pegar chaves públicas de uma loja de ferragens e adicioná-las também (por exemplo, no banco de dados de chaves UEFI).

Finalmente, é possível adicionar chaves públicas adicionais fazendo:

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

por exemplo:

keyctl padd asymmetric "" 0x223c7853 <my_public_key.x509

Observe, no entanto, que o kernel somente permitirá que chaves sejam adicionadas ao .system_keyring se o wrapper X.509 da nova chave for validamente assinado por uma chave que já esteja residente no .system_keyring no momento em que a chave foi adicionada.


MÓDULOS DE ASSINATURA MANUAL

Para assinar manualmente um módulo, use a ferramenta scripts / arquivo de sinal disponível na árvore de fontes do kernel do Linux. O script requer 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

A seguir, é apresentado um exemplo para assinar um módulo do kernel:

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

O algoritmo de hash usado não precisa coincidir com o configurado, mas, se não, você deve se certificar de que o algoritmo de hash esteja incorporado no kernel ou possa ser carregado sem exigir ele próprio.

Se a chave privada exigir uma senha ou PIN, ela poderá ser fornecida na variável de ambiente $ KBUILD_SIGN_PIN.


MÓDULOS ASSINADOS E LISTRAS

Um módulo assinado possui uma assinatura digital simplesmente anexada ao final. A cadeia "~ Assinatura do módulo anexada ~." no final do arquivo do módulo, confirma que uma assinatura está presente, mas não confirma que a assinatura é válida!

Os módulos assinados são BRITTLE, pois a assinatura está fora do contêiner ELF definido. Assim, eles não podem ser retirados uma vez que a assinatura é computada e anexada. Observe que o módulo inteiro é a carga assinada, incluindo toda e qualquer informação de depuração presente no momento da assinatura.


CARREGANDO MÓDULOS ASSINADOS

Os módulos são carregados com insmod, modprobe, init_module () ou finit_module (), exatamente como para módulos não assinados, pois nenhum processamento é feito no espaço do usuário. A verificação da assinatura é feita dentro do kernel.


ASSINATURAS NÃO VÁLIDAS E MÓDULOS NÃO ASSINADOS

Se CONFIG_MODULE_SIG_FORCE estiver ativado ou enforcemodulesig = 1 for fornecido na linha de comando do kernel, o kernel carregará apenas módulos assinados validamente para os quais possui uma chave pública. Caso contrário, ele também carregará módulos sem assinatura. Qualquer módulo para o qual o kernel possua uma chave, mas que demonstre ter uma incompatibilidade de assinatura, não poderá carregar.

Qualquer módulo que tenha uma assinatura não analisável será rejeitado.


ADMINISTRAÇÃO / PROTEÇÃO DA CHAVE PRIVADA

Como a chave privada é usada para assinar módulos, vírus e malware podem usar a chave privada para assinar módulos e comprometer o sistema operacional. A chave privada deve ser destruída ou movida para um local seguro e não mantida no nó raiz da árvore de origem do kernel.

AB
fonte
Obrigado, mas eu já vi esse texto antes. O problema que eu estou enfrentando é que, embora eu possa assinar meu arquivo, não consigo carregá-lo ainda porque: "o kernel permitirá apenas que as chaves sejam adicionadas a .system_keyring se o novo invólucro X.509 da nova chave for assinado validamente por uma chave que já esteja residente no .system_keyring no momento em que a chave foi adicionada. "
usar o seguinte
Já vi isso várias vezes, mas não ajuda. Há um bug no Ubuntu que afeta todas as placas-mãe que não suportam UEFI: bugs.launchpad.net/ubuntu/+source/linux-lts-xenial/+bug/1656670
Musbach
0

Edite ./include/generated/autoconf.he altere a linha

define CONFIG_MODULE_SIG 1

para

define CONFIG_MODULE_SIG 0
daniel
fonte