Protegendo a comunicação entre sistemas embarcados limitados

Jan 04 2021

Atualmente, estou tentando fortalecer a comunicação em um canal de comunicação físico limitado em um sistema embarcado.

O cenário

Acho que o sistema é bastante típico para pequenos aplicativos incorporados:

  • Os sistemas embarcados envolvidos são pequenos microcontroladores sem sistema operacional, que pode ser considerado em um ambiente físico seguro. O canal de conexão é fisicamente acessível aos agressores, eles podem interferir nas mensagens conforme desejado.

  • Diferentes canais de comunicação são possíveis: por exemplo, RS485 ou RS232. Existe um protocolo rudimentar que lida com coisas como endereçamento e integridade grosseira (por exemplo, CRC16 para bitflips), no qual podemos construir. Pense nisso como um TCP lento.

  • Cada parceiro de comunicação conhece um certificado raiz que pode atuar como uma CA e possui um certificado exclusivo (+ chave) assinado por ele. Os certificados são autoassinados, curva elíptica prime256v1

  • A biblioteca mbedTLS está disponível para esses sistemas (com DH, AES, ..).

  • Na maioria das vezes, não há internet disponível.

  • Os sistemas podem manter o tempo e podem criar números aleatórios suficientes

Eu quero alcançar privacidade, autenticidade e integridade.

Como pode ser resolvido

Uma regra em protocolos criptográficos é nunca implementá-los por conta própria. Infelizmente, não encontrei nada que corresponda a este caso de uso.

Também pesquisei as questões existentes, mas nada forneceu a solução completa que procurava.

Finalmente, nesta resposta, a implementação de um protocolo próprio é dada como a última opção.

É por isso que encontrei a solução descrita abaixo - mas não estou totalmente certo disso. Eu orientei esta resposta sobre como autenticar um Diffie-Hellmann Key Exchange , esta resposta sobre como verificar a integridade e esta thread me dando algumas idéias sobre como implementar tal protocolo .

Protocolo para comunicação segura

A primeira coisa a fazer é gerar aleatoriamente uma chave simétrica K. A primeira coisa a ser enviada é uma mensagem de handshake. Possui os seguintes campos:

Campo Descrição
DH A troca de chave Diffie-Hellmann msg g K
Cert O certificado (-chain) do dispositivo de envio
MsgIdNonce Um valor aleatório de 64 bits
Assinatura Uma assinatura da mensagem completa usando a chave privada do Cert

Ambos os dispositivos enviam (e recebem) tal mensagem.

Quando uma mensagem é recebida, o seguinte é feito:

  1. Verifique se o certificado está assinado pelo CA esperado (deve estar na cadeia)
  2. Verifique se a msg está devidamente assinada com o certificado e sua chave

Quando essas verificações são bem-sucedidas, as mensagens DH g K enviadas e recebidas são usadas para calcular uma chave simétrica.

A partir deste ponto, os aplicativos podem enviar mensagens criptografadas com AES-CBC. Como as mensagens podem ser perdidas com relativa frequência, o IV está sempre na mensagem.

Este é o formato da mensagem:

Campo Descrição Criptografado
IV Inicialmente aleatório IV para AES Não
MsgIdNonce Aperto de mão / Última MsgIdNonce + 1 ou + 2 sim
dados de aplicativos Os dados / comandos a serem protegidos sim
CMAC truncado para 64 bits MAC para verificação de integridade sim

Para que uma mensagem seja aceita, ela deve

  1. Ter o MsgIdNonce esperado (1 ou 2 acima do último recebido) - evitando ataques de repetição, permitindo a perda de 1 mensagem
  2. Tenha um CMAC válido - evitando ataques à integridade
  3. Ser recebido no máximo. T segundos após a última mensagem - evitando ataques retardados

Se algo não for o esperado, o handshake é enviado novamente e a mensagem é enviada novamente com os parâmetros trocados recentemente.

Questões

Estou no caminho certo ou devo tentar algo completamente diferente?

Isso fornece meus objetivos de segurança ou perco alguma vulnerabilidade óbvia aqui?

Isso pode funcionar?

Espero que você possa ajudar a mim e a outros engenheiros embarcados que enfrentam problemas semelhantes!

Respostas

2 poncho Jan 04 2021 at 23:18

Uma regra em protocolos criptográficos é nunca implementá-los por conta própria. Infelizmente, não encontrei nada que corresponda a este caso de uso.

Você considerou o DTLS ? Isso tenta resolver o mesmo problema (exceto para carimbos de hora; que podem ser adicionados inserindo o carimbo de hora no datagrama), e já tem coisas pensadas. Outra possibilidade seria o IPsec; entretanto, o DTLS parece mais perto de resolver o problema que você tem (a menos que o tráfego de dados que você está protegendo seja tráfego IP).

Dito isso, aqui estão algumas idéias sobre o protocolo que você delineou:

  • O que acontece se duas mensagens sequenciais forem descartadas (por exemplo, recebidas incorretamente)? Os dois lados perceberão o que aconteceu ou continuarão a descartar todas as mensagens subsequentes (por causa da regra 'o nonce não precisa incrementar mais do que 2')?

  • Presumindo que eles tentem uma recodificação, como isso é coordenado? Se um lado pensa que ainda não foi reinserido e o outro pensa que está, o que acontecerá com as mensagens criptografadas com a chave antiga? Em geral, achamos útil incluir uma tag 'qual chave isso está criptografado em' com o texto cifrado (em DTLS, essa é a 'época').

  • Seu canal de comunicação pode reorganizar as mensagens? Suspeito que não seja possível no seu caso, mas, se puder, você deve pensar em como lidar com isso.

  • O que acontece se alguém injetar uma mensagem de handshake anterior (válida)? Como isso vai confundir as coisas?

  • No caminho de criptografia de dados, você usa criptografia CBC e integridade CMAC. Embora seja uma solução viável, ela está sujeita a vários ataques de preenchimento se eles não forem integrados corretamente. A moda atual é usar um modo AEAD (como GCM ou Chacha20 / Poly1305) que faz as duas coisas.

  • O tráfego criptografado é unidirecional ou bidirecional? Se o tráfego for nos dois sentidos, você usa o mesmo conjunto de chaves para proteger os dois conjuntos de tráfego?

  • "Se algo não for o esperado, o handshake é enviado novamente e a mensagem é enviada novamente com os parâmetros trocados." - como isso funciona? Se o destinatário decidiu que não gostou da mensagem, como o remetente sabe que deve reenviá-la?