Enclaves seguros
Como proteger código e dados mesmo de quem controla a máquina.
O problema
Normalmente, quem manda no computador vê tudo. O sistema operacional consegue ler a memória de qualquer processo, o hypervisor consegue ler a memória de qualquer máquina virtual, e quem administra o servidor (ou a nuvem) consegue ler tudo isso junto.
Isso é um problema quando você quer processar algo sensível, como uma chave privada, dados médicos ou o modelo de outra empresa, numa máquina que não é sua ou em que você não confia por completo.
Em quem você confia
O enclave inverte a pilha de confiança. Em vez de confiar em todas as camadas de software abaixo do seu programa, você confia só no processador e no código que está dentro do enclave. Esse conjunto mínimo de coisas confiáveis se chama TCB (Trusted Computing Base).
As quatro peças
1. Isolamento de memória
O processador reserva uma região de memória para o enclave e bloqueia qualquer acesso vindo de fora dele, inclusive do kernel. Se o sistema operacional tentar ler esses endereços, recebe lixo ou um erro.
Esse isolamento pode ter tamanhos diferentes. Algumas tecnologias protegem só um pedaço de um processo; outras protegem uma máquina virtual inteira:
2. Memória cifrada
Dentro do processador os dados ficam em claro, porque é lá que o código trabalha. Quando eles saem do chip e vão para a RAM, um motor de criptografia cifra tudo automaticamente com uma chave que nunca deixa o processador. Na volta, decifra. Assim, mesmo alguém com acesso físico aos pentes de memória só vê bytes embaralhados.
3. Atestação remota
Como saber que o código rodando lá dentro é mesmo o que você espera, e que ele está num enclave de verdade e não num simulador? O processador calcula um hash (a medição) do código carregado no enclave e assina esse valor com uma chave que só um chip genuíno tem. Você confere a assinatura, compara o hash com o código que auditou e só então envia seus segredos.
4. Selagem (sealing)
O enclave precisa guardar coisas entre reinicializações, mas o disco é controlado pelo sistema operacional. A solução é cifrar os dados com uma chave derivada de dois ingredientes: uma chave secreta gravada no chip e a medição do próprio enclave.
A vida de um enclave
- Criar. A aplicação pede ao processador uma região protegida de memória.
- Carregar e medir. O código do enclave é copiado para dentro, página por página, e o processador vai calculando o hash de tudo que entra.
- Inicializar. A medição é congelada. A partir daqui ninguém de fora pode mudar o código.
- Atestar. Quem precisa confiar no enclave pede o relatório assinado e confere a medição.
- Executar. A aplicação chama funções do enclave, que processa os segredos lá dentro.
- Destruir. O processador apaga a região. Só o que foi selado sobrevive.
Durante a execução, o código cruza a fronteira do enclave por portas bem definidas. Entrar no enclave é uma ECALL; quando o enclave precisa de algo que só o sistema operacional faz, como ler um arquivo ou usar a rede, ele sai por uma OCALL.
Um exemplo concreto
Imagine um serviço de assinatura de transações que guarda uma chave privada num servidor alugado:
- O serviço sobe o enclave com o código de assinatura, que é open source.
- O dono da chave pede a atestação, confere que o hash bate com a versão publicada do código e só então envia a chave privada, cifrada para o enclave.
- O enclave sela a chave e guarda o blob no disco.
- A aplicação comum envia transações por ECALL; o enclave devolve assinaturas.
- Se o servidor reiniciar, o enclave abre o blob selado e continua. A chave nunca aparece em claro fora dele, nem para o administrador do servidor.
Implementações que você vai encontrar
| Tecnologia | Isola o quê | Onde aparece |
|---|---|---|
| Intel SGX | Um pedaço de um processo | Servidores Intel, Azure |
| Intel TDX | Uma máquina virtual inteira | Nuvens com Xeon recentes |
| AMD SEV-SNP | Uma máquina virtual inteira | AWS, Azure, GCP |
| Arm TrustZone / CCA | Um "mundo seguro" separado | Celulares, dispositivos embarcados |
| Apple Secure Enclave | Um coprocessador dedicado | iPhone, Mac (Face ID, chaves) |
| AWS Nitro Enclaves | Uma VM isolada sem rede nem disco | AWS EC2 |
O nome guarda-chuva para tudo isso é TEE (Trusted Execution Environment), e quando o uso é em nuvem costuma aparecer como confidential computing.
O que enclaves não resolvem
- Bugs no seu código. Se o código dentro do enclave vaza o segredo, o hardware não te salva. Por isso o código do enclave deve ser pequeno e auditável.
- Ataques de canal lateral. Tempo de execução, cache e consumo de energia já foram usados para extrair segredos de enclaves (Foreshadow, Plundervolt, SGAxe). Os fabricantes corrigem, mas é uma corrida contínua.
- Disponibilidade. O sistema operacional não lê o enclave, mas pode simplesmente não deixá-lo rodar.
- Confiança no fabricante. A raiz de tudo é a chave da Intel, AMD, Arm ou Apple. Você troca "confiar no dono da máquina" por "confiar em quem fez o chip".
Glossário rápido
- TCB (Trusted Computing Base)
- Tudo em que você precisa confiar para o sistema ser seguro. Enclaves existem para encolher a TCB.
- Medição
- Hash do código e da configuração carregados no enclave.
- Atestação
- Prova assinada pelo hardware de que uma medição específica está rodando num enclave genuíno.
- Nonce
- Número aleatório usado uma vez só, para provar que a resposta é nova e não uma gravação.
- Selagem
- Cifrar dados para que só o mesmo enclave, no mesmo chip, consiga decifrá-los depois.
- ECALL / OCALL
- Chamadas que entram no enclave e que saem dele, respectivamente.
A ideia
Um policy engine é o pedaço do sistema que responde a uma pergunta só: "quem está pedindo pode fazer isso com esse recurso?". Ele recebe o pedido, olha as regras escritas por quem é dono dos dados e devolve permite ou nega.
O problema é o mesmo da primeira parte. Se o policy engine roda num servidor que outra pessoa controla, essa pessoa pode trocar as regras, forjar um "permite" ou apagar o registro do que aconteceu. Colocando o policy engine dentro de um enclave, quem opera o servidor continua rodando o serviço, mas perde o poder de mexer nas decisões.
Quem fala com quem
Antes do primeiro pedido
A preparação usa exatamente as peças da primeira parte:
- Atestação. Quem escreve as políticas pede o relatório do enclave e confere que a medição bate com a versão auditada do policy engine. O relatório traz a chave pública de assinatura que o enclave gerou lá dentro.
- Envio das políticas. O pacote de políticas vai assinado pelo autor e cifrado para o enclave. O host repassa, mas não lê nem altera.
- Selagem. O enclave confere a assinatura do autor, guarda o pacote selado no disco e anota a versão dele.
- Publicação da chave. Os recursos protegidos passam a aceitar só decisões assinadas pela chave que apareceu no relatório atestado.
As regras
Para o exemplo, um pacote pequeno com três regras. Negação sempre ganha de permissão, e o que nenhuma regra permite fica proibido.
nega nunca-exportar-pii:
ação = "exportar" e recurso tem a etiqueta "pii"
permite ler-do-proprio-time:
ação = "ler" e recurso.time = quem_pede.time
padrão: negaO fluxo de cada pedido
Escolha um pedido para ver o caminho que ele faz dentro do enclave:
Nenhum pedido escolhido: o fluxograma mostra todos os caminhos.
O que vai na decisão
A resposta não é só "sim" ou "não". Ela amarra a decisão ao pedido e às regras usadas, para ninguém reaproveitar um "permite" antigo em outro pedido:
decisão: permite
regra: ler-do-proprio-time
pedido: sha256(ana · ler · relatorio-q3.pdf · nonce)
políticas: versão 12 (sha256 do pacote)
log anterior: sha256 da entrada 4.311
assinatura: chave do enclave (a mesma do relatório atestado)O que o enclave garante aqui
- Decisões não podem ser forjadas. Só o enclave tem a chave privada de assinatura, e o recurso só aceita decisões assinadas por ela. O admin do servidor controla o gateway, mas não consegue fabricar um "permite".
- As regras não mudam em silêncio. As políticas chegam assinadas pelo autor e ficam seladas. Cada decisão carrega a versão das políticas que usou, então trocar regras sem o autor fica visível.
- As regras podem ser sigilosas. Limites de fraude ou listas de bloqueio ficam em claro só dentro do enclave. O operador roda o serviço sem conseguir lê-las.
- O log é à prova de adulteração. Cada entrada inclui o hash da anterior e vai assinada. Apagar ou editar uma entrada quebra a corrente dali para frente.
O que ainda fica com você
- O gateway pode não perguntar. Se o recurso aceita pedidos sem decisão assinada, o enclave não adianta nada. A conferência da assinatura no recurso é obrigatória.
- Voltar uma política antiga. O host pode devolver um blob selado de uma versão anterior, que o enclave consegue abrir. Para impedir, o enclave guarda a versão num contador que só sobe, e o recurso recusa decisões com versão menor que a última que viu.
- Regras erradas continuam erradas. O enclave garante que as regras são aplicadas como foram escritas, não que estão certas.
- Disponibilidade. O operador ainda pode desligar tudo. Nesse caso nada é permitido, o que pelo menos falha do lado seguro.
Glossário desta parte
- Policy engine
- Componente que avalia regras e decide se um pedido é permitido.
- PDP (Policy Decision Point)
- Quem decide. Aqui, o policy engine dentro do enclave.
- PEP (Policy Enforcement Point)
- Quem aplica a decisão no caminho do pedido. Aqui, o gateway.
- Negação por padrão
- O que nenhuma regra permite explicitamente é proibido.
- Log encadeado
- Registro em que cada entrada inclui o hash da anterior, então qualquer alteração no meio aparece.