Proteção conta leitura e Gravação do ESP32S3

A proteção contra leitura e gravação do ESP32S3 é um pouco diferente do ESP32, porém há muitos pontos para confusões e erros. O objetivo deste post é justamente te auxiliar nesse processo afim de deixar tudo um pouco mais claro.

1. Instalando Ferramentas Essenciais para o ESP32S3

Para realizar o processo de proteção do ESP32S3, será necessário instalar o ESP-IDF no seu computador. Ele oferece suporte para todos os sistemas operacionais. Para baixá-lo basta clicar aqui. Após a instalação, abra o terminal ESP-IDF.

No ESP-IDF, teremos acesso aos seguintes aplicativos:

  • esptool.py: Responsável pela leitura, consulta e gravação de dados no ESP32S3.
  • espefuse.py: Usado para modificar e proteger os eFuse (regiões de memória que armazenam as configurações de segurança do ESP32S3).
  • especure.py: Utilizado para gerar chaves de criptografia e criptografar binários.
  • idf.py: Interface de linha de comando que substitui o que uma IDE faria, mas não será necessário no processo descrito aqui.

2. Preparação para Proteger o ESP32S3: Avisos Importantes

Antes de iniciar o processo de proteção contra leitura e gravação do ESP32S3, é importante estar ciente de que erros podem ocorrer, e isso pode resultar na perda do microcontrolador. Portanto, recomendo usar um ESP32S3 que possa ser facilmente descartado, especialmente em seus primeiros testes. Se tudo ocorrer bem o processo, não haverá problemas!

Para organizar melhor o procedimento, abra três instâncias do ESP-IDF, pois precisaremos executar diferentes comandos ao longo da configuração. Isso permitirá um controle mais eficiente durante o procedimento.

3. Criptografia no ESP32S3: Métodos e Diferenças

Quando comecei a explorar a proteção do ESP32S3, confesso que fiquei um pouco confuso, pois as informações sobre a proteção no ESP32 parecem não se aplicar diretamente ao modelo ESP32S3. O que foi confirmado ao comparar a documentação do ESP32 e a documentação do ESP32S3, após a comparação tudo ficou um pouco mais claro e vou te explicar!

Basicamente o ESP32S3 oferece dois tipos de criptografia AES 128 (256-bits) e AES 256 (512-bits), porém só vamos abordar o AES 128. Além disso, há também dois métodos de criptografia que é o de desenvolvimento e o de produção.

3.1 Diferença entre os Métodos de Criptografia no ESP32S3

  • Modo de Desenvolvimento: Permite que os binários sejam enviados sem criptografia via serial, com o próprio microcontrolador criptografando-os internamente. Este método é útil para testes, mas não é recomendado para produtos finais. (Não abordaremos esse modo aqui).
  • Modo de Produção (Release): Esse é o método recomendado para ambientes de produção, aceitando apenas arquivos que foram previamente criptografados, garantindo maior segurança.

4. Proteção Contra Leitura e Gravação no ESP32S3: Passo a Passo

Agora que entendemos a diferença entre os modos de criptografia e você já configurou o ambiente corretamente, vamos seguir o passo a passo para aplicar a proteção contra leitura e gravação no ESP32S3. Esteja atento aos detalhes para garantir que tudo funcione conforme o esperado.

4.1 Gere um projeto de teste

Abra sua IDE (faça inicialmente com Arduino IDE) e gere um arquivo onde fique escrevendo valores randômicos na porta Serial a cada meio segundo, também poderá usar um LED, mas confesso que acho mais prático a Serial e além disso ela será usada para diagnosticar possíveis problemas.

4.2 Exportar binários do projeto do Arduino para uma pasta

Crie uma pasta destinada apenas para esse tutorial de criptografia, isso é altamente recomendado para todo processo em que você for fazer em seus produtos, pois a desorganização pode ser algo catastrófico nesse caso.

Imagine uma produção de um produto com ESP32S3 onde você fez todo esse processo de proteção, mas ai a chave é perdida, dos produtos que saíram da fabrica deixaram de receber novas atualizações por ter simplesmente perdido a chave.

4.3 Gerar uma chave de criptografia

Do ESP32S2 em diante já são compatíveis com chave AES 256 que é 512 bits, porém por enquanto só vamos usar a chave AES 128 que é de 256 bits. Cuidado ao gerar essa chave para não repetir o comando e subscrever uma chave já gravada no microcontrolador, o comando para AES 128 é:

espsecure.py generate_flash_encryption_key "<diretorio/nome_da_chave.bin>"

4.4 Criptografar todos os arquivos binários do projeto do Arduino IDE

Vá até o diretório aonde você colocou os binários do projeto do Arduino IDE, crie uma pasta “encrypted” para ajudar a identificar onde estão os binários criptografados.

Em seguida, vamos pegar cada binário e criptografar um a um. Vale ressaltar que esse comando a seguir tem uma ordem meio estranha, pois o destino de saída (já criptografado) do arquivo vem primeiro e o destino de entrada (não criptografado) vem

espsecure.py encrypt_flash_data --aes_xts --keyfile "<diretorio\nome_da_chave.bin>" --address 0x0 --output "<diretorio\encrypted\0x0.bin>" "<diretorio\0x0.bin>"
 
espsecure.py encrypt_flash_data --aes_xts --keyfile "<diretorio\nome_da_chave.bin>" --address 0xe000 --output "<diretorio\encrypted\nome_do_arquivo.bin>" "<diretorio\0xe000.bin>"
 
espsecure.py encrypt_flash_data --aes_xts --keyfile "<diretorio\nome_da_chave.bin>" --address 0x8000 --output "<diretorio\encrypted\nome_do_projeto.partitions.bin>" "<diretorio\nome_do_projeto.ino.partitions.bin>"
 
espsecure.py encrypt_flash_data --aes_xts --keyfile "<diretorio\nome_da_chave.bin>" --address 0x10000 --output "<diretorio\encrypted\nome_do_projeto.bin>" "<diretorio\nome_do_projeto.ino.bin>"

4.5 Analisar eFuses em um ESP32S3 sem proteção

Este processo não é um processo que vai mudar algo no ESP, apenas vai servir como um feedback para sabermos o estado de cada eFuse do ESP, para isso basta dar o seguinte comando:

espefuse.py --port COM<numero da porta> summary

Ao realizar esse comando o summary irá exibir todas as configurações dos efuses e e os marcados em verde deverão estar respectivamente como false e disable, indicando ausência de criptografia.

ESP32S3 sem proteção contra leitura e gravação

4.6 Gravar chave de criptografia no ESP

Essa ação é uma ação única, então a chave que você escolher não poderá ser modificada após a gravação da chave. Para gravar a chave no esp basta realizar o seguinte comando:

espefuse.py --port COM&lt;numero da porta>  --chip esp32s3 burn_key BLOCK_KEY0 "&lt;diretorio/nome_da_chave.bin>" XTS_AES_128_KEY

4.7 Habilitar eFuses de proteção contra leitura e gravação ESP32S3

O eFuse responsável por criptografar é o SPI_BOOT_CRYPT_CNT, porém por padrão ele tem que aceitar apenas atualizações de binários já criptografados e para garantir que de fato isso basta habilitar o efuse DIS_DOWNLOAD_MANUAL_ENCRYPT:

espefuse.py --port COM&lt;numero da porta> --chip esp32s3 burn_efuse SPI_BOOT_CRYPT_CNT 7

espefuse.py --port COM&lt;numero da porta> --chip esp32s3 burn_efuse DIS_DOWNLOAD_MANUAL_ENCRYPT

Ao realizar o comando summary mais uma vez poderá notar se de fato as gravações ocorreram e devem estar iguais a imagem a seguir:

Proteção contra leitura e gravação do ESP32S3

4.8 Gravando binários no ESP32S3 via esptool

Esse é o último passo, mas se você já fez tudo certo até aqui, quero te explicar um pequeno detalhe no qual bati bastante cabeça. Embora os binários a serem gravados no ESP32S3 já estejam previamente criptografados, ao tentar enviá-los via esptool, você ainda pode enfrentar problemas. Isso pode estar relacionado a falhas comuns, mas se você seguiu todos os passos corretamente, a maior chance é que seja um bug irritante, que pode ser resolvido ao adicionar o comando --force no final do comando de gravação. Esse parâmetro forçará a gravação no ESP32S3 e, se tudo estiver certo, o microcontrolador vai rodar o código como esperado.

Para realizar o código primeiramente você precisa saber quais configurações sua IDE está usando para gravar no seu ESP32S3 e modificar os parâmetros relacionados ao tipo e memória da versão do ESP32S3. No meu caso estou usando uma versão de 8MB então o comando ficaria assim:

esptool.py --chip esp32s3 --port COM<numero da porta> --baud 921600 --before default_reset --after hard_reset write_flash -z --flash_mode dio --flash_freq 80m --flash_size 8MB 0x0 "<diretorio\encrypted\0x0.bin>" 0x8000 "<diretorio\encrypted\nome_do_projeto.partitions.bin>" 0xe000 "<diretorio\encrypted\nome_do_arquivo.bin>" 0x10000 "<diretorio\encrypted\nome_do_projeto.bin>" --force

4.9 Verificação se deu tudo certo e de possíveis erros

Por fim, verifique se tudo ocorreu corretamente. Para isso, abra o monitor serial. Se o seu código estiver rodando, parabéns! Caso contrário, fique atento a possíveis erros. Um exemplo comum é o seguinte, que pode indicar algum problema no processo de criptografia dos binários, como chaves inválidas ou trocadas:

rst:0x3 (SW_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
invalid header: 0xb414f76b
invalid header: 0xb414f76b
invalid header: 0xb414f76b
invalid header: 0xb414f76b
invalid header: 0xb414f76b
invalid header: 0xb414f76b
invalid header: 0xb414f76b

Deixe uma resposta

Descubra mais sobre elcereza

Assine agora mesmo para continuar lendo e ter acesso ao arquivo completo.

Continue reading