Como criptografar bytes usando o TPM (Trusted Platform Module)

Como criptografar bytes usando o módulo TPM de uma máquina?

CryptProtectData

O Windows fornece uma API (relativamente) simples para criptografar um blob usando oCryptProtectData API, que podemos incluir em uma função fácil de usar:

public Byte[] ProtectBytes(Byte[] plaintext)
{
   //...
}

Os detalhes deProtectBytes são menos importantes do que a ideia de que você pode usá-lo facilmente:

Aqui estão os bytes que eu quero criptografados por uma chave secreta mantida noSystemdevolva o blob criptografado

O retornadoblob é um indocumentadodocumentação estrutura que contém tudo o necessário para descriptografar e retornar os dados originais (algoritmo de hash, algoritmo de cifra, salt, assinatura HMAC, etc.).

Para completar, aqui está a implementação de pseudocódigo de exemplo deProtectBytes que usa oCrypt API para proteger bytes:

public Byte[] ProtectBytes(Byte[] plaintext)
{
   //Setup our n-byte plaintext blob
   DATA_BLOB dataIn;
   dataIn.cbData = plaintext.Length;
   dataIn.pbData = Addr(plaintext[0]);

   DATA_BLOB dataOut;

   //dataOut = EncryptedFormOf(dataIn)
   BOOL bRes = CryptProtectData(
         dataIn,
         null,     //data description (optional PWideChar)
         null,     //optional entropy (PDATA_BLOB)
         null,     //reserved
         null,     //prompt struct
         CRYPTPROTECT_UI_FORBIDDEN || CRYPTPROTECT_LOCAL_MACHINE,
         ref dataOut);
   if (!bRes) then
   {
      DWORD le = GetLastError();
      throw new Win32Error(le, "Error calling CryptProtectData");
   }

   //Copy ciphertext from dataOut blob into an actual array
   bytes[] result;
   SetLength(result, dataOut.cbData);
   CopyMemory(dataOut.pbData, Addr(result[0]), dataOut.cbData);

   //When you have finished using the DATA_BLOB structure, free its pbData member by calling the LocalFree function
   LocalFree(HANDLE(dataOut.pbData)); //LocalFree takes a handle, not a pointer. But that's what the SDK says.
}
Como fazer o mesmo com o TPM?

O código acima é útil para criptografar dados apenas para a máquina local. Os dados são criptografados usando oSystem conta como o gerador de chaves (detalhes, embora interessantes, não são importantes) O resultado final é que eu posso criptografar dados (por exemplo, uma chave mestra de criptografia do disco rígido) que só podem ser descriptografados pela máquina local.

Agora é hora de dar um passo adiante. Quero criptografar alguns dados (por exemplo, uma chave mestra de criptografia do disco rígido) que só podem ser descriptografados pelo TPM local. Em outras palavras, desejo substituir o Qualcomm Trusted Execution Environment (TEE) no diagrama de blocos abaixo para Android, com o TPM no Windows:

Nota: Percebo que o TPM não faz assinatura de dados (ou, se faz, não garante que a assinatura dos mesmos dados fornecerá sempre a mesma saída binária). É por isso que eu estaria disposto a substituir"Assinatura RSA" com"criptografando um blob de 256 bits com uma chave ligada ao hardware".

Então, onde está o código?

O problema é que a programação do TPM écompletamente indocumentado no MSDN. Não há API disponível para executar nenhuma operação. Em vez disso, você precisa encontrar uma cópia doPilha de software do Trusted Computing Group (também conhecida como TSS), descubra quais comandos enviar para o TPM, com cargas úteis, em que ordem e ligueJanelasTbsip_Submit_Command função para enviar comandos diretamente:

TBS_RESULT Tbsip_Submit_Command(
  _In_     TBS_HCONTEXT hContext,
  _In_     TBS_COMMAND_LOCALITY Locality,
  _In_     TBS_COMMAND_PRIORITY Priority,
  _In_     const PCBYTE *pabCommand,
  _In_     UINT32 cbCommand,
  _Out_    PBYTE *pabResult,
  _Inout_  UINT32 *pcbOutput
);

O Windows não possui API de nível superior para executar ações.

É o equivalente moral de tentar criar um arquivo de texto emitindo comandos SATA I / O para o seu disco rígido.

Por que não usar apenas calças

O Trusted Computing Group (TCG) definiu sua própria API:Pilha de software TCB (TSS). Uma implementação desta API foi criada por algumas pessoas e é chamadaCalças. Um cara entãoportou esse projeto para o Windows.

O problema com esse código é que ele não é portátil no mundo do Windows. Por exemplo, você não pode usá-lo no Delphi, nem no C #. Isso requer:

OpenSSLpThread

Eu só quero ocódigo criptografar algo com meu TPM.

O de cimaCryptProtectData requer nada além do que está no corpo da função.

Qual é o código equivalente para criptografar dados usando o TPM? Como outros observaram,você provavelmente precisará consultar os três manuais do TPM e construir os blobs por conta própria. Provavelmente envolve oTPM_seal comando. Embora eu acho que não querofoca dados, acho que queroligar isto:

Obrigatório - criptografa dados usando a chave de ligação do TPM, uma chave RSA exclusiva descendente de uma chave de armazenamento.Vedação - criptografa os dados de maneira semelhante à ligação, mas também especifica um estado em que o TPM deve estar para que os dados sejam descriptografados (sem lacre)

Tento ler os três volumes necessários para encontrar as 20 linhas de código necessárias:

Parte 1 - Princípios de DesignParte 2 - Estruturas do TPMParte 3 - Comandos

Mas eu tenhonão ideia do que estou lendo. Se houvesse algum tipo de tutorial ou exemplo, eu poderia tentar. Mas estou completamente perdido.

Então, perguntamos ao Stackoverflow

Da mesma maneira, pude fornecer:

Byte[] ProtectBytes_Crypt(Byte[] plaintext)
{
   //...
   CryptProtectData(...); 
   //...
}

alguém pode fornecer o equivalente correspondente:

Byte[] ProtectBytes_TPM(Byte[] plaintext)
{
   //...
   Tbsip_Submit_Command(...);
   Tbsip_Submit_Command(...);
   Tbsip_Submit_Command(...);
   //...snip...
   Tbsip_Submit_Command(...);
   //...
}

faz a mesma coisa, exceto em vez de uma chave trancada emSystem LSA, está trancado no TPM?

Início da Pesquisa

Não sei exatamente o queligar significa. Mas, olhando para o TPM Main - Parte 3 Comandos - Specification Versão 1.2, há uma menção deligar:

10.3 TPM_UnBind

TPM_UnBind pega o blob de dados resultante de um comando Tspi_Data_Bind e o descriptografa para exportação para o Usuário. O chamador deve autorizar o uso da chave que descriptografará o blob recebido. O TPM_UnBind opera bloco por bloco e não tem noção de nenhuma relação entre um bloco e outro.

O que é confuso está láé nãoTspi_Data_Bind comando.

Esforço de pesquisa

É horrível como ninguém nunca se incomodou em documentar o TPM ou sua operação. É como se eles passassem o tempo todo inventando esse visual legalcoisa para brincar, mas não queria lidar com o doloroso passo de fazê-loutilizável para algo.

Começando com o livro (agora) gratuitoUm guia prático para o TPM 2.0: usando o módulo Trusted Platform na nova era da segurança:

Capítulo 3 - Tutorial rápido no TPM 2.0

O TPM tem acesso a uma chave privada gerada automaticamente, para criptografar chaves com uma chave pública e, em seguida, armazenar o blob resultante no disco rígido. Dessa forma, o TPM pode manter um número praticamente ilimitado de chaves disponíveis para uso, mas não desperdiçar armazenamento interno valioso. As chaves armazenadas no disco rígido podem ser apagadas, mas também podem ser copiadas, o que pareceu aos designers uma troca aceitável.

Como criptografar uma chave com a chave pública do TPM?

Capítulo 4 - Aplicativos existentes que usam TPMsAplicativos que devem usar o TPM, mas não

Nos últimos anos, o número de aplicativos baseados na Web aumentou. Entre eles estão o backup e armazenamento na Web. Um grande número de empresas agora oferece esses serviços, mas, até onde sabemos, nenhum dos clientes desses serviços permite ao usuário bloquear a chave do serviço de backup em um TPM. Se isso fosse feito, certamente seria bom se a própria chave do TPM fosse copiada em duplicada em várias máquinas. Parece ser uma oportunidade para os desenvolvedores.

Como um desenvolvedor bloqueia uma chave no TPM?

Capítulo 9 - HierarquiasCASO DE USO: ARMAZENAMENTO DE SENHAS DE LOGIN

Um arquivo de senha típico armazena hashes salgados de senhas. A verificação consiste em salgar e hash uma senha fornecida e compará-la com o valor armazenado. Como o cálculo não inclui um segredo, está sujeito a um ataque offline no arquivo de senha.

Este caso de uso usa uma chave HMAC gerada pelo TPM. O arquivo de senha armazena um HMAC da senha salgada. A verificação consiste em salgar e HMACing a senha fornecida e compará-la com o valor armazenado. Como um invasor offline não possui a chave HMAC, o invasor não pode montar um ataque executando o cálculo.

estepoderia trabalhos. Se o TPM tiver uma chave HMAC secreta e apenas o meu TPM conhecer a chave HMAC, eu poderia substituir "Sign (também conhecido como criptografia TPM com sua chave privada)" por "HMAC". Mas então, na linha seguinte, ele se inverte completamente:

TPM2_Create, especificando uma chave HMAC

Não é um segredo do TPM se for necessário especificar a chave HMAC. O fato de a chave HMAC não ser secreta faz sentido quando você percebe que este é o capítulo sobre utilitários criptográficos que o TPM fornece. Em vez de precisar escrever SHA2, AES, HMAC ou RSA, você pode reutilizar o que o TPM já possui.

Capítulo 10 - Chaves

Como dispositivo de segurança, a capacidade de um aplicativo parause as teclas mantendo-as seguras em um dispositivo de hardware é a maior força do TPM. O TPM pode gerar e importar chaves geradas externamente. Ele suporta chaves assimétricas e simétricas.

Excelente! Como você faz isso!?

Gerador de chaves

Indiscutivelmente, a maior força do TPM é sua capacidade de gerar uma chave criptográfica e proteger seu segredo dentro de um limite de hardware. O gerador de chaves é baseado no próprio gerador de números aleatórios do TPM e não depende de fontes externas de aleatoriedade. Assim, elimina pontos fracos baseados em softwares fracos com uma fonte insuficiente de entropia.

Faz O TPM tem a capacidade de gerar chaves criptográficas e proteger seus segredos dentro de um limite de hardware? É assim como?

Capítulo 12 - Registros de configuração da plataformaPCRs para autorizaçãoCASO DE USO: VEDANDO UMA CHAVE DE CRIPTOGRAFIA DE DISCO RÍGIDO PARA PLATAFORMA DO ESTADO

Os aplicativos de criptografia de disco completo são muito mais seguros se um TPM proteger a chave de criptografia do que se estiver armazenada no mesmo disco, protegido apenas por uma senha. Primeiro, o hardware do TPM possui proteção anti-hammering (consulte o Capítulo 8 para obter uma descrição detalhada da proteção contra ataques de dicionário do TPM), tornando impraticável um ataque de força bruta à senha. Uma chave protegida apenas por software é muito mais vulnerável a uma senha fraca. Segundo, uma chave de software armazenada no disco é muito mais fácil de roubar. Pegue o disco (ou um backup do disco) e você obterá a chave. Quando um TPM mantém a chave, toda a plataforma, ou pelo menos o disco e a placa-mãe, devem ser roubados.

A vedação permite que a chave seja protegida não apenas por uma senha, mas por uma política. Uma política típica bloqueia a chave dos valores de PCR (o estado do software) atuais no momento da vedação. Isso pressupõe que o estado na primeira inicialização não seja comprometido. Qualquer malware pré-instalado presente na primeira inicialização seria medido nas PCRs e, portanto, a chave seria selada para um estado de software comprometido. Uma empresa menos confiável pode ter uma imagem de disco padrão e selar para PCRs que representam essa imagem. Esses valores de PCR seriam pré-calculados em uma plataforma presumivelmente mais confiável. Uma empresa ainda mais sofisticada usaria TPM2_PolicyAuthorize e forneceria vários tickets autorizando um conjunto de valores de PCR confiáveis. Consulte o Capítulo 14 para obter uma descrição detalhada da política autorizada e sua aplicação para resolver o problema de fragilidade da PCR.

Embora uma senha também possa proteger a chave, há um ganho de segurança mesmo sem a senha da chave do TPM. Um invasor pode inicializar a plataforma sem fornecer uma senha do TPMkey, mas não pode efetuar login sem o nome de usuário e a senha do SO. O OSsecurity protege os dados. O invasor pode inicializar um sistema operacional alternativo, digamos, a partir de um DVD ao vivo ou pendrive ao invés do disco rígido, para ignorar a segurança de login do sistema operacional. No entanto, essa configuração e software de inicialização diferentes alterariam os valores de PCR. Como essas novas PCRs não correspondiam aos valores selados, o TPM não liberaria a chave de descriptografia e o disco rígido não pôde ser descriptografado.

Excelente! Esse é exatamente o caso de uso que eu desejo. Também é o caso de uso para o qual a Microsoft usa o TPM. Como eu faço isso!?

Então, li o livro inteiro e ele não forneceu nada de útil. O que é bastante impressionante, porque tem 375 páginas. Você quer saber o que o livro continha - e, olhando para trás, não faço ideia.

Portanto, desistimos do guia definitivo para programar o TPM e, em vez disso, recorremos a alguma documentação da Microsoft:

DeKit de ferramentas de provedor de criptografia da plataforma Microsoft TPM. Menciona exatamente o que eu quero fazer:

A chave de endosso ou EK

O EK foi projetado para fornecer um identificador criptográfico confiável para a plataforma. Uma empresa pode manter um banco de dados das Chaves de Endosso pertencentes aos TPMs de todos os PCs em sua empresa, ou um controlador de malha do datacenter pode ter um banco de dados dos TPMs em todos os blades. No Windows, você pode usar o provedor NCrypt descrito na seção “Provedor de criptografia de plataforma no Windows 8” para ler a parte pública do EK.

Em algum lugar dentro do TPM há uma chave privada RSA. Essa chave está trancada lá dentro - para nunca ser vista pelo mundo exterior. Quero que o TPM assine algo com sua chave privada (por exemplo, criptografá-lo com sua chave privada).

Então eu quero maisbásico operação que pode existir:

Criptografe algo com sua chave privada. Eu ainda nem estou pedindo coisas mais complicadas:

"vedação" com base no estado da PCRcriando uma chave e armazenando-a em memroy volátil ou não volátilcriando uma chave simétrica e tentando carregá-la no TPM

Estou solicitando a operação mais básica que um TPM pode fazer. Por que é impossível obter informações sobre como fazê-lo?

Posso obter dados aleatórios

Suponho que estava sendo simplista quando disse que a assinatura do RSA era a coisa mais básica que o TPM pode fazer. oa maioria A coisa básica que o TPM pode ser solicitado é fornecer bytes aleatórios.Naquela Eu descobri como fazer:

public Byte[] GetRandomBytesTPM(int desiredBytes)
{
   //The maximum random number size is limited to 4,096 bytes per call
   Byte[] result = new Byte[desiredBytes];

   BCRYPT_ALG_HANDLE hAlgorithm;

   BCryptOpenAlgorithmProvider(
         out hAlgorithm,
         BCRYPT_RNG_ALGORITHM, //AlgorithmID: "RNG"
         MS_PLATFORM_CRYPTO_PROVIDER, //Implementation: "Microsoft Platform Crypto Provider" i.e. the TPM
         0 //Flags
   );
   try
   {                
      BCryptGenRandom(hAlgorithm, @result[0], desiredBytes, 0);
   }
   finally
   {
      BCryptCloseAlgorithmProvider(hAlgorithm);
   }

   return result;
}
A coisa extravagante

Percebo que o volume de pessoas que usam o TPM é muito baixo. É por isso que ninguém no Stackoverflow tem uma resposta. Portanto, não posso ficar muito ganancioso ao encontrar uma solução para o meu problema comum. Mas a coisa que eurealmente quer fazer é"foca" alguns dados:

apresentar ao TPM alguns dados (por exemplo, 32 bytes de material principal)fazer o TPM criptografar os dados, retornando alguma estrutura opaca de blobdepois peça ao TPM para descriptografar o bloba descriptografia funcionará apenas se os registros de PCR do TPM forem iguais aos da criptografia.

Em outras palavras:

Byte[] ProtectBytes_TPM(Byte[] plaintext, Boolean sealToPcr)
{
   //...
}

Byte[] UnprotectBytes_TPM(Byte[] protectedBlob)
{
   //...
}
A próxima geração de criptografia (Cng, também conhecida como BCrypt) suporta o TPM

A API de criptografia original no Windows era conhecida como API de criptografia.

A partir do Windows Vista, a API Crypto foi substituída porAPI de criptografia: próxima geração (conhecido internamente comoBestCrypt, abreviado comoBCrypt, não confunda como algoritmo de hash de senha)

O Windows é fornecido com dois BCryptfornecedores:

Provedor Microsoft Primitive (MS_PRIMITIVE_PROVIDER) padrão: Implementação de software padrão de todos osprimitivas (hash, criptografia simétrica, assinaturas digitais, etc.)Provedor de criptografia da plataforma Microsoft (MS_PLATFORM_CRYPTO_PROVIDER): Provedor que fornece acesso ao TPM

oPlatform Crypto O provedor não está documentado no MSDN, mas possui documentação de um site da Microsoft Research 2012:

Kit de ferramentas de provedor de criptografia da plataforma TPM

O provedor de criptografia da plataforma TPM e o Toolkit contêm código de amostra, utilitários e documentação para usar a funcionalidade relacionada ao TPM no Windows 8. Os subsistemas descritos incluem o provedor de criptografia da plataforma Crypto-Next-Gen (CNG) suportado pelo TPM e como provedores de serviços de atestado pode usar os novos recursos do Windows. Os sistemas baseados em TPM1.2 e TPM2.0 são suportados.

Parece que a intenção da Microsoft é apresentar a funcionalidade de criptografia TPM com oProvedor de criptografia da plataforma Microsoft doCriptografia NG API.

Criptografia de chave pública usando o Microsoft BCrypt

Dado que:

eu quero executar a criptografia assimétrica RSA (usando o TPM)MicrosoftO BestCrypt suporta criptografia assimétrica RSAO Microsoft BestCrypt possui umProvedor TPM

um caminho a seguir pode ser o de descobrir como fazer a assinatura digital usando oAPI de próxima geração de criptografia da Microsoft.

Minha próxima etapa será criar o código para criptografia no BCrypt, com uma chave pública RSA, usando o provedor padrão (MS_PRIMITIVE_PROVIDER) Por exemplo.:

modulus: 0xDC 67 FA F4 9E F2 72 1D 45 2C B4 80 79 06 A0 94 27 50 8209 DD 67 CE 57 B8 6C 4A 4F 40 9F D2 D1 69 FB 995D 85 0C 07 A1 F9 47 1B 56 16 6E F6 7F B9 CF 2A 58 36 37 99 29 AA 4F A8 12 E8 4F C7 82 2B 9D 72 2A 9C DE 6F C2 EE 12 6D CF F0 F2 B8 C4 DD 7C 5C 1A C8 17 51 A9 AC DF 08 22 04 9D 2B D7 F9 4B 09 DE 9A EB 5C 51 1A D8 F8 F9 56 9E F8 FB 37 9B 3F D3 74 65 24 0D FF 34 75 57 A4 F5 BF 55publicExponent: 65537

Com esse código funcionando, eu posso estar apto a usar o Provedor TPM (MS_PLATFORM_CRYPTO_PROVIDER)

22/02/2016: E com a Apple sendo obrigada a descriptografar dados do usuário, há um interesse renovado em como fazer o TPM executar a tarefa mais simples que foi inventada - criptografar algo.

É aproximadamente equivalente a todos os proprietários de um carro, mas ninguém sabe como começar um. Pode fazer coisas realmente úteis e legais, se pudéssemos passarPasso 1.

Leitura de bônusAndroid - Criptografia - Armazenando a chave criptografadaAndroid Explorations - Revisitando a criptografia de disco AndroidSegredos DPAPI. Análise de segurança e recuperação de dados no DPAPI (parte 1)

questionAnswers(3)

yourAnswerToTheQuestion