[Windows] Comment chiffrer des octets à l'aide du TPM (Trusted Platform Module)


Answers

Clés sécurisées et cryptées

Les clés sécurisées et cryptées sont deux nouveaux types de clé ajoutés au service de jeu de clés du noyau existant. Ces deux nouveaux types sont des clés symétriques de longueur variable et, dans les deux cas, toutes les clés sont créées dans le noyau et l'espace utilisateur voit, stocke et charge uniquement les blobs chiffrés. Les clés sécurisées requièrent la disponibilité d'une puce TPM (Trusted Platform Module) pour une sécurité accrue, tandis que les clés cryptées peuvent être utilisées sur n'importe quel système. Tous les blobs au niveau utilisateur sont affichés et chargés en hexa ASCII pour plus de commodité, et leur intégrité est vérifiée.

Les clés approuvées utilisent un TPM pour générer et sceller les clés. Les clés sont scellées sous une clé RSA de 2048 bits dans le TPM, et éventuellement scellées à des valeurs de PCR (mesure d'intégrité) spécifiées, et seulement non scellées par le TPM, si les PCR et les vérifications d'intégrité de blob correspondent. Une clé sécurisée chargée peut être mise à jour avec de nouvelles valeurs de PCR (futures), de sorte que les clés sont facilement migrées vers de nouvelles valeurs Pcr, par exemple lorsque le noyau et initramfs sont mis à jour. La même clé peut avoir de nombreux blobs sauvegardés sous différentes valeurs de PCR, donc plusieurs amorces sont facilement supportées.

Par défaut, les clés approuvées sont scellées sous le SRK, qui a la valeur d'autorisation par défaut (20 zéros). Cela peut être réglé au moment de la prise de possession avec l'utilitaire du pantalon: tpm_takeownership -u -z .

Usage:
    keyctl add trusted name "new keylen [options]" ring
    keyctl add trusted name "load hex_blob [pcrlock=pcrnum]" ring
    keyctl update key "update [options]"
    keyctl print keyid

    options:
    keyhandle= ascii hex value of sealing key default 0x40000000 (SRK)
    keyauth=   ascii hex auth for sealing key default 0x00...i
        (40 ascii zeros)
    blobauth=  ascii hex auth for sealed data default 0x00...
        (40 ascii zeros)
    blobauth=  ascii hex auth for sealed data default 0x00...
        (40 ascii zeros)
    pcrinfo=   ascii hex of PCR_INFO or PCR_INFO_LONG (no default)
    pcrlock=   pcr number to be extended to "lock" blob
    migratable= 0|1 indicating permission to reseal to new PCR values,
                default 1 (resealing allowed)

keyctl print renvoie une copie hexa keyctl print de la clé scellée, qui est au format TPM_STORED_DATA standard. La longueur de clé pour les nouvelles clés est toujours en octets. Les clés approuvées peuvent avoir entre 32 et 128 octets (256 à 1024 bits), la limite supérieure doit correspondre à la longueur de clé SRK (RSA) de 2048 bits, avec toute la structure / tout le remplissage nécessaire.

Les clés cryptées ne dépendent pas d'un TPM et sont plus rapides, car elles utilisent AES pour le cryptage / décryptage. Les nouvelles clés sont créées à partir de nombres aléatoires générés par le noyau et sont chiffrées / décryptées à l'aide d'une clé "maître" spécifiée. La clé 'master' peut être soit une clé de confiance, soit un type de clé d'utilisateur. Le principal inconvénient des clés cryptées est qu'elles ne sont pas aussi sûres que la clé de l'utilisateur si elles ne sont pas ancrées dans une clé sécurisée. La clé de l'utilisateur maître doit donc être chargée le plus sûrement possible, de préférence au démarrage.

La partie décryptée des clés chiffrées peut contenir soit une clé symétrique simple, soit une structure plus complexe. Le format de la structure la plus complexe est spécifique à l'application, identifié par le 'format'.

Usage:
    keyctl add encrypted name "new [format] key-type:master-key-name keylen"
        ring
    keyctl add encrypted name "load hex_blob" ring
    keyctl update keyid "update key-type:master-key-name"

format:= 'default | ecryptfs'
key-type:= 'trusted' | 'user'

Exemples d'utilisation de clé sécurisée et cryptée

Créez et enregistrez une clé approuvée nommée "kmk" de longueur 32 octets:

$ keyctl add trusted kmk "new 32" @u
440502848

$ keyctl show
Session Keyring
       -3 --alswrv    500   500  keyring: _ses
 97833714 --alswrv    500    -1   \_ keyring: _uid.500
440502848 --alswrv    500   500       \_ trusted: kmk

$ keyctl print 440502848
0101000000000000000001005d01b7e3f4a6be5709930f3b70a743cbb42e0cc95e18e915
3f60da455bbf1144ad12e4f92b452f966929f6105fd29ca28e4d4d5a031d068478bacb0b
27351119f822911b0a11ba3d3498ba6a32e50dac7f32894dd890eb9ad578e4e292c83722
a52e56a097e6a68b3f56f7a52ece0cdccba1eb62cad7d817f6dc58898b3ac15f36026fec
d568bd4a706cb60bb37be6d8f1240661199d640b66fb0fe3b079f97f450b9ef9c22c6d5d
dd379f0facd1cd020281dfa3c70ba21a3fa6fc2471dc6d13ecf8298b946f65345faa5ef0
f1f8fff03ad0acb083725535636addb08d73dedb9832da198081e5deae84bfaf0409c22b
e4a8aea2b607ec96931e6f4d4fe563ba

$ keyctl pipe 440502848 > kmk.blob

Charger une clé de confiance à partir du blob enregistré:

$ keyctl add trusted kmk "load `cat kmk.blob`" @u
268728824

$ keyctl print 268728824
0101000000000000000001005d01b7e3f4a6be5709930f3b70a743cbb42e0cc95e18e915
3f60da455bbf1144ad12e4f92b452f966929f6105fd29ca28e4d4d5a031d068478bacb0b
27351119f822911b0a11ba3d3498ba6a32e50dac7f32894dd890eb9ad578e4e292c83722
a52e56a097e6a68b3f56f7a52ece0cdccba1eb62cad7d817f6dc58898b3ac15f36026fec
d568bd4a706cb60bb37be6d8f1240661199d640b66fb0fe3b079f97f450b9ef9c22c6d5d
dd379f0facd1cd020281dfa3c70ba21a3fa6fc2471dc6d13ecf8298b946f65345faa5ef0
f1f8fff03ad0acb083725535636addb08d73dedb9832da198081e5deae84bfaf0409c22b
e4a8aea2b607ec96931e6f4d4fe563ba

Refermer une clé de confiance sous les nouvelles valeurs de Pcr:

$ keyctl update 268728824 "update pcrinfo=`cat pcr.blob`"
$ keyctl print 268728824
010100000000002c0002800093c35a09b70fff26e7a98ae786c641e678ec6ffb6b46d805
77c8a6377aed9d3219c6dfec4b23ffe3000001005d37d472ac8a44023fbb3d18583a4f73
d3a076c0858f6f1dcaa39ea0f119911ff03f5406df4f7f27f41da8d7194f45c9f4e00f2e
df449f266253aa3f52e55c53de147773e00f0f9aca86c64d94c95382265968c354c5eab4
9638c5ae99c89de1e0997242edfb0b501744e11ff9762dfd951cffd93227cc513384e7e6
e782c29435c7ec2edafaa2f4c1fe6e7a781b59549ff5296371b42133777dcc5b8b971610
94bc67ede19e43ddb9dc2baacad374a36feaf0314d700af0a65c164b7082401740e489c9
7ef6a24defe4846104209bf0c3eced7fa1a672ed5b125fc9d8cd88b476a658a4434644ef
df8ae9a178e9f83ba9f08d10fa47e4226b98b0702f06b3b8

Le consommateur initial des clés de confiance est EVM, qui au moment du démarrage a besoin d'une clé symétrique de haute qualité pour la protection HMAC des métadonnées de fichiers. L'utilisation d'une clé sécurisée garantit que la clé EVM n'a pas été compromise par un problème au niveau de l'utilisateur et, lorsqu'elle est scellée à des valeurs PCR spécifiques, elle protège contre les attaques de démarrage et hors ligne. Créez et enregistrez une clé chiffrée "evm" en utilisant la clé de confiance ci-dessus "kmk":

option 1: omettre le 'format'

$ keyctl add encrypted evm "new trusted:kmk 32" @u
159771175

option 2: définir explicitement 'format' comme 'default'

$ keyctl add encrypted evm "new default trusted:kmk 32" @u
159771175

$ keyctl print 159771175
default trusted:kmk 32 2375725ad57798846a9bbd240de8906f006e66c03af53b1b3
82dbbc55be2a44616e4959430436dc4f2a7a9659aa60bb4652aeb2120f149ed197c564e0
24717c64 5972dcb82ab2dde83376d82b2e3c09ffc

$ keyctl pipe 159771175 > evm.blob

Charger une clé chiffrée "evm" à partir du blob sauvegardé:

$ keyctl add encrypted evm "load `cat evm.blob`" @u
831684262

$ keyctl print 831684262
default trusted:kmk 32 2375725ad57798846a9bbd240de8906f006e66c03af53b1b3
82dbbc55be2a44616e4959430436dc4f2a7a9659aa60bb4652aeb2120f149ed197c564e0
24717c64 5972dcb82ab2dde83376d82b2e3c09ffc

D'autres utilisations de clés sécurisées et cryptées, telles que le cryptage de disque et de fichier sont prévues. En particulier, le nouveau format 'ecryptfs' a été défini afin d'utiliser des clés cryptées pour monter un système de fichiers eCryptfs. Plus de détails sur l'utilisation peuvent être trouvés dans le fichier 'Documentation / security / keys-ecryptfs.txt'.

Question

Comment puis-je chiffrer des octets en utilisant le module TPM d'une machine?

CryptProtectData

Windows fournit une API (relativement) simple pour chiffrer un objet blob à l'aide de l'API CryptProtectData , que nous pouvons intégrer à une fonction facile à utiliser:

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

Les détails de ProtectBytes sont moins importants que l'idée que vous pouvez l'utiliser assez facilement:

  • voici les octets que je veux crypté par une clé secrète détenue dans le System
  • rends-moi le blob chiffré

Le blob retourné est une structure de documentation non documentation qui contient tout ce qui est nécessaire pour déchiffrer et retourner les données d'origine (algorithme de hachage, algorithme de chiffrement, sel, signature HMAC, etc.).

Pour être complet, voici l'implémentation de pseudo- ProtectBytes de ProtectBytes qui utilise l' Crypt API pour protéger les octets:

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.
}

Comment faire la même chose avec le TPM?

Le code ci-dessus est utile pour chiffrer des données pour la machine locale seulement. Les données sont cryptées en utilisant le compte System comme générateur de clé (les documentation ). Le résultat final est que je peux chiffrer des données (par exemple une clé principale de chiffrement de disque dur) qui ne peuvent être décryptées que par la machine locale.

Maintenant, il est temps d'aller encore plus loin. Je veux crypter certaines données (par exemple une clé principale de cryptage de disque dur) qui ne peuvent être décryptées que par le TPM local. En d'autres termes, je souhaite remplacer l'environnement TEE (Qualcomm Trusted Execution Environment) dans le diagramme ci-dessous pour Android, avec le TPM dans Windows:

Remarque : je réalise que le TPM ne fait pas de signature de données (ou s'il le fait, cela ne garantit pas que la signature des mêmes données donnera la même sortie binaire à chaque fois). C'est pourquoi je serais prêt à remplacer "signature RSA" par "crypter un blob de 256 bits avec une clé liée au matériel" .

Alors, où est le code?

Le problème est que la programmation TPM est complètement non documentée sur MSDN . Aucune API n'est disponible pour effectuer des opérations. Au lieu de cela, vous devez trouver une copie de la pile logicielle du groupe Trusted Computing (TSS) , déterminer quelles commandes envoyer au TPM, avec les charges utiles, dans quel ordre, et appeler la fonction Tbsip_Submit_Command de Windows pour envoyer les commandes directement:

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
);

Windows n'a pas d'API de niveau supérieur pour effectuer des actions.

C'est l'équivalent moral d'essayer de créer un fichier texte en émettant des commandes d'E / S SATA sur votre disque dur .

Pourquoi ne pas simplement utiliser des pantalons

Le Trusted Computing Group (TCG) a défini sa propre API: TCB Software Stack (TSS) . Une implémentation de cette API a été créée par certaines personnes, et s'appelle TrouSerS . Un gars a ensuite porté ce projet sur Windows .

Le problème avec ce code est qu'il n'est pas portable dans le monde Windows. Par exemple, vous ne pouvez pas l'utiliser à partir de Delphi, vous ne pouvez pas l'utiliser à partir de C #. Cela demande:

  • OpenSSL
  • pThread

Je veux juste que le code crypte quelque chose avec mon TPM.

Le CryptProtectData ci-dessus CryptProtectData nécessite rien d'autre que ce qui se trouve dans le corps de la fonction.

Quel est le code équivalent pour chiffrer les données en utilisant le TPM? Comme d'autres l'ont noté, vous devez probablement consulter les trois manuels TPM et construire les blobs vous-même . Cela implique probablement la commande TPM_seal . Bien que je pense que je ne veux pas sceller des données, je pense que je veux le lier :

Liaison - Chiffre les données à l'aide de la clé de liaison TPM, une clé RSA unique issue d'une clé de stockage. Scellement - crypte les données de manière similaire à la liaison, mais spécifie en outre un état dans lequel TPM doit être en ordre pour que les données soient décryptées (non scellées)

J'essaie de lire les trois volumes requis pour trouver les 20 lignes de code dont j'ai besoin:

Mais je n'ai aucune idée de ce que je lis. S'il y avait une sorte de tutoriel ou d'exemples, je pourrais avoir une chance. Mais je suis complètement perdu.

Nous demandons donc

De la même manière, j'ai pu fournir:

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

quelqu'un peut-il fournir l'équivalent correspondant:

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

cela fait la même chose, sauf plutôt qu'une clé enfermée dans System LSA, est enfermé dans le TPM?

Début de la recherche

Je ne sais pas exactement ce que signifie lier . Mais en regardant TPM Main - Part 3 Commands - Spécification Version 1.2, il est fait mention de bind :

10.3 TPM_UnBind

TPM_UnBind prend le blob de données qui est le résultat d'une commande Tspi_Data_Bind et le décrypte pour l'exporter vers l'utilisateur. L'appelant doit autoriser l'utilisation de la clé qui décryptera le blob entrant. TPM_UnBind fonctionne bloc par bloc et n'a aucune notion de relation entre un bloc et un autre.

Ce qui est déroutant, c'est qu'il n'y a pas de commande Tspi_Data_Bind .

Effort de recherche

C'est horrifiant de constater que personne n'a jamais pris la peine de documenter le TPM ou son fonctionnement. C'est comme s'ils passaient tout leur temps à jouer avec cette chose cool, mais ils ne voulaient pas faire face à la douloureuse mesure de la rendre utilisable pour quelque chose.

À partir du livre (maintenant) gratuit Un guide pratique de TPM 2.0: Utilisation du module de plate-forme sécurisée dans le nouvel âge de la sécurité :

Chapitre 3 - Tutoriel rapide sur TPM 2.0

Le TPM a accès à une clé privée auto-générée, ce qui lui permet de chiffrer des clés avec une clé publique, puis de stocker le blob obtenu sur le disque dur. De cette façon, le TPM peut conserver un nombre de clés pratiquement illimité, mais ne gaspille pas un stockage interne précieux. Les clés stockées sur le disque dur peuvent être effacées, mais elles peuvent également être sauvegardées, ce qui a semblé aux concepteurs comme un compromis acceptable.

Comment puis-je chiffrer une clé avec la clé publique du TPM?

Chapitre 4 - Applications existantes utilisant des TPM

Applications qui doivent utiliser le TPM mais pas

Au cours des dernières années, le nombre d'applications Web a augmenté. Parmi eux sont la sauvegarde et le stockage sur le Web. Un grand nombre d'entreprises offrent maintenant de tels services, mais pour autant que nous le sachions, aucun des clients de ces services ne permet à l'utilisateur de verrouiller la clé du service de sauvegarde à un TPM. Si cela était fait, ce serait bien si la clé TPM elle-même était sauvegardée en la dupliquant sur plusieurs machines. Cela semble être une opportunité pour les développeurs.

Comment un développeur verrouille-t-il une clé sur le TPM?

Chapitre 9 - Heirarchies

CAS D'UTILISATION: STOCKER LES MOTS DE PASSE DE CONNEXION

Un fichier de mot de passe typique stocke les hashs salés des mots de passe. La vérification consiste à saler et hacher un mot de passe fourni et à le comparer à la valeur enregistrée. Parce que le calcul n'inclut pas de secret, il est soumis à une attaque hors ligne sur le fichier de mot de passe.

Ce cas d'utilisation utilise une clé HMAC générée par TPM. Le fichier de mot de passe stocke un HMAC du mot de passe salé. La vérification consiste à saler et à HMACer le mot de passe fourni et à le comparer à la valeur enregistrée. Comme un attaquant hors ligne n'a pas la clé HMAC, l'attaquant ne peut pas monter une attaque en effectuant le calcul.

Cela pourrait fonctionner. Si le TPM a une clé HMAC secrète, et que seul TPM connaît la clé HMAC, alors je pourrais remplacer "Sign (alias chiffrer TPM avec sa clé privée)" par "HMAC". Mais alors, dans la ligne suivante, il se renverse complètement:

TPM2_Create, spécifiant une clé HMAC

Ce n'est pas un secret TPM si je dois spécifier la clé HMAC. Le fait que la clé HMAC n'est pas un secret est logique lorsque vous réalisez que c'est le chapitre sur les utilitaires cryptographiques que le TPM fournit. Plutôt que d'avoir à écrire vous-même SHA2, AES, HMAC ou RSA, vous pouvez réutiliser ce que le TPM a déjà à faire.

Chapitre 10 - Clés

En tant qu'appareil de sécurité, la capacité d'une application à utiliser des clés tout en les protégeant dans un périphérique matériel constitue la plus grande force du TPM. Le TPM peut à la fois générer et importer des clés générées de manière externe. Il prend en charge les clés asymétriques et symétriques.

Excellent! Comment faites-vous!?

Générateur de clé

On peut soutenir que la plus grande force du TPM réside dans sa capacité à générer une clé cryptographique et à protéger son secret dans une limite matérielle. Le générateur de clé est basé sur le propre générateur de nombres aléatoires du TPM et ne repose pas sur des sources externes de hasard. Il élimine ainsi les faiblesses basées sur un logiciel logiciel faible avec une source d'entropie insuffisante.

Est- ce que le TPM a la capacité de générer des clés cryptographiques et de protéger ses secrets dans une limite matérielle? Est-ce le cas, comment?

Chapitre 12 - Registres de configuration de plate-forme

PCR pour l'autorisation

CAS D'UTILISATION: SCELLER UNE CLÉ DE CRYPTAGE DE DISQUE DUR DANS UN ÉTAT DE PLATEFORME

Les applications de chiffrement sur disque dur sont bien plus sécurisées si un TPM protège la clé de chiffrement que s'il est stocké sur le même disque, protégé uniquement par un mot de passe. Tout d'abord, le matériel TPM dispose d'une protection anti-frappe (voir le chapitre 8 pour une description détaillée de la protection d'attaque du dictionnaire TPM), ce qui rend une attaque par force brute sur le mot de passe impossible. Une clé protégée uniquement par un logiciel est beaucoup plus vulnérable à un mot de passe faible. Deuxièmement, une clé logicielle stockée sur le disque est beaucoup plus facile à voler. Prenez le disque (ou une sauvegarde du disque), et vous obtenez la clé. Lorsqu'un TPM détient la clé, la plate-forme entière, ou au moins le disque et la carte mère, doivent être volés.

L'étanchéité permet à la clé d'être protégée non seulement par un mot de passe mais par une politique. Une politique typique verrouille la clé des valeurs de PCR (l'état du logiciel) en cours au moment du scellement. Cela suppose que l'état au premier démarrage n'est pas compromis. Tout programme malveillant préinstallé présent au premier démarrage serait mesuré dans les PCR, et ainsi la clé serait scellée à un état logiciel compromis. Une entreprise moins fiable pourrait avoir une image disque standard et sceller les PCR représentant cette image. Ces valeurs de PCR seraient précalculées sur une plate-forme supposée plus fiable. Une entreprise encore plus sophistiquée utiliserait TPM2_PolicyAuthorize et fournirait plusieurs tickets autorisant un ensemble de valeurs de PCR approuvées. Voir le chapitre 14 pour une description détaillée de l'autorisation de politique et son application pour résoudre le problème de fragilité PCR.

Bien qu'un mot de passe puisse également protéger la clé, il y a un gain de sécurité même sans mot de passe de clé TPM. Un attaquant pourrait démarrer la plate-forme sans fournir de mot de passe TPMkey mais ne pourrait pas se connecter sans le nom d'utilisateur et le mot de passe du système d'exploitation. L'OSsecurity protège les données. L'attaquant pourrait amorcer un système d'exploitation alternatif, par exemple à partir d'un DVD ou d'une clé USB, plutôt qu'à partir du disque dur, afin de contourner la sécurité de connexion au système d'exploitation. Cependant, cette configuration de démarrage et ce logiciel différent changeraient les valeurs PCR. Étant donné que ces nouvelles PCR ne correspondraient pas aux valeurs scellées, le TPM ne libérerait pas la clé de déchiffrement et le disque dur ne pourrait pas être déchiffré.

Excellent! C'est exactement le cas d'utilisation que je souhaite. C'est aussi le cas d'utilisation pour lequel Microsoft utilise le TPM. Comment fait-on ça!?

J'ai donc lu tout ce livre, et cela n'a servi à rien. Ce qui est assez impressionnant parce que c'est 375 pages. Vous vous demandez ce que contenait le livre - et en y repensant, je n'en ai aucune idée.

Nous abandonnons donc le guide définitif de la programmation du TPM, et nous nous tournons plutôt vers une documentation de Microsoft:

À partir de la boîte à outils Crypto-Provider de la plate-forme Microsoft TPM . Il mentionne exactement ce que je veux faire:

La clé d'endossement ou EK

L'EK est conçu pour fournir un identifiant cryptographique fiable pour la plate-forme. Une entreprise peut gérer une base de données des clés d'endossement appartenant aux TPM de tous les PC de son entreprise ou un contrôleur de matrice de centre de données peut avoir une base de données des TPM dans toutes les lames. Sous Windows, vous pouvez utiliser le fournisseur NCrypt décrit dans la section "Platform Crypto Provider sous Windows 8" pour lire la partie publique du EK.

Quelque part à l'intérieur du TPM est une clé privée RSA. Cette clé est enfermée là-dedans - pour ne jamais être vue par le monde extérieur. Je veux que le TPM signe quelque chose avec sa clé privée (ie le crypter avec sa clé privée).

Donc, je veux l'opération la plus basique qui puisse exister:

Chiffrer quelque chose avec votre clé privée. Je ne demande même pas (encore) les choses les plus compliquées:

  • "sceller" en fonction de l'état de la PCR
  • créer une clé et la stocker dans un memroy volatile ou non volatile
  • créer une clé symétrique et essayer de le charger dans le TPM

Je demande l'opération la plus élémentaire qu'un TPM puisse faire. Pourquoi est-il impossible d'obtenir des informations sur la façon de le faire?

Je peux obtenir des données aléatoires

Je suppose que j'étais désinvolte quand j'ai dit que la signature RSA était la chose la plus fondamentale que le TPM puisse faire. La chose la plus fondamentale que le TPM peut être invité à faire est de me donner des octets aléatoires. Que j'ai compris comment faire:

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;
}

La chose de fantaisie

Je réalise que le volume de personnes utilisant le TPM est très faible. C'est pourquoi personne sur n'a de réponse. Donc, je ne peux pas vraiment devenir trop gourmand pour trouver une solution à mon problème commun. Mais la chose que je veux vraiment faire est de "sceller" certaines données:

  • présenter au TPM certaines données (par exemple, 32 octets de données clés)
  • avoir le TPM crypter les données, renvoyant une structure de blob opaque
  • demander plus tard au TPM de déchiffrer le blob
  • le décryptage ne fonctionnera que si les registres PCR du TPM sont les mêmes que pendant le cryptage.

En d'autres termes:

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

Byte[] UnprotectBytes_TPM(Byte[] protectedBlob)
{
   //...
}

Cryptographie Next Gen (Cng, aka BCrypt) prend en charge TPM

L'API Cryptography originale dans Windows était connue comme l'API Crypto.

À partir de Windows Vista, l'API Crypto a été remplacée par l' API Cryptography: Next Generation (connue en interne sous le nom de BestCrypt , abrégé en BCrypt , à ne pas confondre avec l'algorithme de hachage par mot de passe ).

Windows est livré avec deux fournisseurs BCrypt:

Le fournisseur de cryptage de plate-forme n'est pas documenté sur MSDN, mais dispose de la documentation d'un site Microsoft Research 2012:

Boîte à outils Crypto-Provider TPM Platform

Le fournisseur de cryptage de plate-forme TPM et Toolkit contient des exemples de code, utilitaires et documentation pour l'utilisation des fonctionnalités TPM dans Windows 8. Les sous-systèmes décrits incluent le fournisseur de chiffrement de plate-forme Crypto-Next-Gen (CNG) soutenu par TPM. peut utiliser les nouvelles fonctionnalités de Windows. Les systèmes basés sur TPM1.2 et TPM2.0 sont pris en charge.

Il semble que l'intention de Microsoft est de faire apparaître la fonctionnalité de cryptage TPM avec le fournisseur de cryptage de plate-forme Microsoft de l'API Cryptography NG .

Cryptage de clé publique à l'aide de Microsoft BCrypt

Étant donné que:

Une voie à suivre pourrait être de comprendre comment faire la signature numérique en utilisant l' API Microsoft Cryptography Next Gen.

Ma prochaine étape sera de trouver le code pour faire le chiffrement dans BCrypt, avec une clé publique RSA, en utilisant le fournisseur standard ( MS_PRIMITIVE_PROVIDER ). Par exemple:

  • 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 6F 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 55
  • publicExponent : 65537

Avec ce code fonctionnant, je peux être capable d'utiliser le fournisseur TPM ( MS_PLATFORM_CRYPTO_PROVIDER ).

22/02/2016: Et avec Apple étant obligé d'aider à décrypter les données de l'utilisateur, il y a un regain d'intérêt pour la façon dont le TPM effectuer la tâche la plus simple pour laquelle il a été inventé - chiffrer quelque chose.

C'est à peu près équivalent à tout le monde possédant une voiture, mais personne ne sait comment en créer un. Il peut faire des choses vraiment utiles et cool, si seulement nous pouvions passer l' étape 1 .

Lecture bonus