Comment puis-je chiffrer des octets à l'aide du module TPM d'une machine?
CryptProtectData
Windows fournit une API (relativement) simple pour chiffrer un objet blob à l'aide de l' CryptProtectData
API, que nous pouvons encapsuler dans 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 souhaite chiffrer par une clé secrète contenue dans le
System
- rendez-moi le blob chiffré
Le blob retourné est une structure de documentation non documentée qui contient tout le nécessaire pour décrypter et renvoyer les données d'origine (algorithme de hachage, algorithme de chiffrement, salt, signature HMAC, etc.).
Pour être complet, voici l'exemple d'implémentation de pseudocode de ProtectBytes
qui utilise le 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 de même avec le TPM?
Le code ci-dessus est utile pour crypter les données de la machine locale uniquement. Les données sont cryptées en utilisant le System
compte comme générateur de clé (les détails, bien qu'intéressants, ne sont pas importants ). Le résultat final est que je peux crypter des données (par exemple une clé principale de cryptage du disque dur) qui ne peuvent être décryptées que par la machine locale.
Il est maintenant temps d'aller plus loin. Je souhaite chiffrer certaines données (par exemple, une clé principale de chiffrement du disque dur) qui ne peuvent être déchiffrées que par le TPM local. En d'autres termes, je souhaite remplacer le Qualcomm Trusted Execution Environment ( TEE ) dans le diagramme ci-dessous pour Android, par le TPM sous Windows:
Remarque : je me rends compte que le TPM ne fait pas de signature de données (ou s'il le fait, il 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 «chiffrement d'un objet blob 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 vous trouver une copie de la pile logicielle du Trusted Computing Group (alias TSS) , déterminer les commandes à envoyer au TPM, avec les charges utiles, dans quel ordre, et appeler la fonction Tbsip_Submit_Command de Windows pour soumettre des 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 depuis Delphi, vous ne pouvez pas l'utiliser depuis C #. Cela demande:
- OpenSSL
- pThread
Je veux juste que le code crypte quelque chose avec mon TPM.
Ce qui précède CryptProtectData
ne nécessite rien d'autre que ce qui est dans le corps de la fonction.
Quel est le code équivalent pour crypter des données à l'aide du TPM? Comme d'autres l'ont noté, vous devez probablement consulter les trois manuels TPM et créer vous-même les objets blob . Cela implique probablement la TPM_seal
commande. Bien que je pense que je ne veux pas sceller les données, je pense que je veux les lier :
Liaison - chiffre les données à l'aide de la clé de liaison TPM, une clé RSA unique descendant d'une clé de stockage. Scellement - crypte les données de la même manière que la liaison, mais spécifie en outre un état dans lequel le TPM doit être pour que les données soient décryptées (descellées)
J'essaye de lire les trois volumes requis afin de 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 à Stackoverflow
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(...);
//...
}
qui fait la même chose, sauf plutôt qu'une clé enfermée dans System
LSA, est enfermée dans le TPM?
Début de la recherche
Je ne sais pas exactement ce que signifie bind . Mais en regardant TPM Main - Part 3 Commands - Specification Version 1.2, il y a une 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échiffre pour l'exportation vers l'utilisateur. L'appelant doit autoriser l'utilisation de la clé qui décryptera l'objet 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 Tspi_Data_Bind
commande.
Effort de recherche
Il est horrible de voir que personne ne s'est jamais donné la peine de documenter le TPM ou son fonctionnement. C'est comme s'ils passaient tout leur temps à trouver ce truc sympa avec lequel jouer, mais ne voulaient pas faire face à l'étape douloureuse de le rendre utilisable pour quelque chose.
À partir du livre (maintenant) gratuit Un guide pratique de TPM 2.0: Utilisation du module Trusted Platform 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. Il peut donc chiffrer les clés avec une clé publique, puis stocker l'objet blob résultant sur le disque dur. De cette façon, le TPM peut conserver un nombre pratiquement illimité de clés disponibles pour une utilisation sans gaspiller de précieux stockage interne. 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 devraient utiliser le TPM mais pas
Au cours des dernières années, le nombre d'applications Web a augmenté. Parmi eux, il y a la sauvegarde et le stockage sur le Web. Un grand nombre d'entreprises proposent désormais de tels services, mais à notre connaissance, aucun des clients de ces services ne permet à l'utilisateur de verrouiller la clé du service de sauvegarde sur un TPM. Si cela était fait, ce serait certainement 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é du TPM?
Chapitre 9 - Héritarchies
CAS D'UTILISATION: ENREGISTREMENT DES MOTS DE PASSE DE CONNEXION
Un fichier de mots de passe typique stocke des hachages salés de mots de passe. La vérification consiste à saler et hacher un mot de passe fourni et à le comparer à la valeur stockée. Étant donné que le calcul n'inclut pas de secret, il est soumis à une attaque hors ligne sur le fichier de mots 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 HMACing le mot de passe fourni et à le comparer à la valeur enregistrée. Étant donné qu'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 mon TPM connaît la clé HMAC, alors je pourrais remplacer «Sign (aka TPM chiffrer avec sa clé privée)» par «HMAC». Mais alors dans la ligne suivante, il se renverse complètement:
TPM2_Create, spécification d'une clé HMAC
Ce n'est pas un secret TPM si je dois spécifier la clé HMAC. Le fait que la clé HMAC ne soit pas secrète a du sens lorsque vous réalisez qu'il s'agit du chapitre sur les utilitaires cryptographiques fournis par le TPM. Plutôt que de devoir écrire vous-même SHA2, AES, HMAC ou RSA, vous pouvez réutiliser ce que le TPM a déjà en place.
Chapitre 10 - Clés
En tant que dispositif de sécurité, la capacité d'une application à utiliser des clés tout en les gardant en sécurité dans un périphérique matériel est la plus grande force du TPM. Le TPM peut à la fois générer et importer des clés générées en externe. Il prend en charge les clés asymétriques et symétriques.
Excellent! Comment faites-vous!?
Générateur de clés
On peut soutenir que la plus grande force du TPM est sa capacité à générer une clé cryptographique et à protéger son secret dans une limite matérielle. Le générateur de clés est basé sur le propre générateur de nombres aléatoires du TPM et ne repose pas sur des sources externes d'aléa. Il élimine ainsi les faiblesses basées sur des logiciels faibles avec une source d'entropie insuffisante.
Le TPM a- t -il la capacité de générer des clés cryptographiques et de protéger ses secrets dans une limite matérielle? Est-ce vrai, comment?
Chapitre 12 - Registres de configuration de plate-forme
RAP pour autorisation
CAS D'UTILISATION: SCELLER UNE CLÉ DE CRYPTION DE DISQUE DUR À L'ÉTAT DE LA PLATEFORME
Les applications de chiffrement de disque complet sont beaucoup plus sécurisées si un TPM protège la clé de chiffrement que si elle est stockée 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-marteau (voir le chapitre 8 pour une description détaillée de la protection contre les attaques par dictionnaire TPM), ce qui rend impossible une attaque par force brute sur le mot de passe. 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, doit être volée.
Le scellement 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é aux valeurs PCR (l'état du logiciel) en cours au moment du scellage. Cela suppose que l'état au premier démarrage n'est pas compromis. Tout logiciel 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 peut avoir une image disque standard et être scellée aux PCR représentant cette image. Ces valeurs PCR seraient précalculées sur une plateforme vraisemblablement plus fiable. Une entreprise encore plus sophistiquée utiliserait TPM2_PolicyAuthorize et fournirait plusieurs tickets autorisant un ensemble de valeurs PCR fiables. Voir le chapitre 14 pour une description détaillée de la politique d'autorisation et de son application pour résoudre le problème de PCRbrittleness.
Bien qu'un mot de passe puisse également protéger la clé, il existe un gain de sécurité même sans mot de passe de clé TPM. Un attaquant pourrait démarrer la plateforme 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. La sécurité du système d'exploitation protège les données. L'attaquant pourrait démarrer un système d'exploitation alternatif, par exemple à partir d'un DVD ou d'une clé USB en direct plutôt qu'à partir du disque dur, pour contourner la sécurité de connexion du système d'exploitation. Cependant, cette configuration de démarrage et ce logiciel différents modifieraient les valeurs PCR. Étant donné que ces nouveaux PCR ne correspondraient pas aux valeurs scellées, le TPM ne libérerait pas la clé de déchiffrement et le disque dur ne pouvait pas être déchiffré.
Excellent! C'est exactement le cas d'utilisation que je souhaite. C'est également le cas d'utilisation pour lequel Microsoft utilise le TPM. Comment fait-on ça!?
J'ai donc lu tout ce livre, et il n'a rien fourni d'utile. Ce qui est assez impressionnant car il fait 375 pages. Vous vous demandez ce que contient le livre - et en y repensant, je n'en ai aucune idée.
Nous abandonnons donc le guide définitif de programmation du TPM et nous nous tournons plutôt vers une documentation de Microsoft:
À partir de la boîte à outils du fournisseur de chiffrement de la plate-forme Microsoft TPM . Il mentionne exactement ce que je veux faire:
La clé d'approbation ou EK
L'EK est conçu pour fournir un identifiant cryptographique fiable pour la plateforme. Une entreprise peut maintenir une base de données des clés d'approbation appartenant aux TPM de tous les PC de son entreprise, ou un contrôleur de structure 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 dans Windows 8» pour lire la partie publique de l'EK.
Quelque part à l'intérieur du TPM se trouve 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 (c'est-à-dire le crypte avec sa clé privée).
Je veux donc l' opération la plus basique qui puisse exister:
Cryptez quelque chose avec votre clé privée. Je ne demande même pas (encore) les choses les plus compliquées:
- "sceller" il en fonction de l'état de la PCR
- créer une clé et la stocker dans une mémoire volatile ou non volatile
- créer une clé symétrique et essayer de la charger dans le TPM
Je demande l'opération la plus élémentaire qu'un TPM peut effectuer. Pourquoi est-il impossible d'obtenir des informations sur la façon de procéder?
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 élémentaire que le TPM puisse faire. La chose la plus basique que l'on puisse demander au TPM 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 fantaisie
Je me rends compte que le nombre de personnes utilisant le TPM est très faible. C'est pourquoi personne sur Stackoverflow n'a de réponse. Je ne peux donc pas vraiment devenir trop gourmand pour trouver une solution à mon problème commun. Mais ce que je voudrais vraiment faire est de «sceller» certaines données:
- présenter au TPM des données (par exemple 32 octets de matériel clé)
- faire crypter les données par le TPM, renvoyant une structure blob opaque
- demander plus tard au TPM de décrypter l'objet blob
- le décryptage ne fonctionnera que si les registres PCR du TPM sont les mêmes que lors du cryptage.
En d'autres termes:
Byte[] ProtectBytes_TPM(Byte[] plaintext, Boolean sealToPcr)
{
//...
}
Byte[] UnprotectBytes_TPM(Byte[] protectedBlob)
{
//...
}
Cryptography Next Gen (Cng, alias BCrypt) prend en charge le TPM
L'API de cryptographie d'origine de Windows était connue sous le nom d'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 , en abrégé BCrypt , à ne pas confondre avec l'algorithme de hachage de mot de passe ).
Windows est livré avec deux fournisseurs BCrypt :
- Microsoft Primitive Provider (
MS_PRIMITIVE_PROVIDER
) par défaut : implémentation logicielle par défaut de toutes les primitives (hachage, cryptage symétrique, signatures numériques, etc.) - Microsoft Platform Crypto Provider (
MS_PLATFORM_CRYPTO_PROVIDER
): fournisseur qui fournit un accès au TPM
Le fournisseur Platform Crypto n'est pas documenté sur MSDN, mais dispose de la documentation d'un site Microsoft Research 2012:
Boîte à outils du fournisseur de chiffrement de la plateforme TPM
Le fournisseur de chiffrement et la boîte à outils de la plate-forme TPM contient des exemples de code, des utilitaires et de la documentation pour l'utilisation des fonctionnalités liées au TPM dans Windows 8. Les sous-systèmes décrits incluent le fournisseur de chiffrement de la plate-forme Crypto-Next-Gen (CNG) soutenu par TPM et comment les fournisseurs de services d'attestation 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 soit de présenter la fonctionnalité de cryptage TPM avec le fournisseur de cryptage de plate-forme Microsoft de l' API Cryptography NG .
Chiffrement par clé publique à l'aide de Microsoft BCrypt
Étant donné que:
- je souhaite effectuer un cryptage asymétrique RSA (à l'aide du TPM)
- Microsoft BestCrypt prend en charge le cryptage asymétrique RSA
- Microsoft BestCrypt a un fournisseur TPM
une façon peut - être avant de savoir 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 cryptage 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 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
Avec ce code fonctionnant, je pourrai peut-être passer à l'utilisation du fournisseur TPM ( MS_PLATFORM_CRYPTO_PROVIDER
).
22/02/2016: Et avec Apple étant obligé d'aider à déchiffrer les données des utilisateurs, il y a un regain d'intérêt pour la façon dont le TPM exécute la tâche la plus simple pour laquelle il a été inventé - chiffrer quelque chose.
C'est à peu près l'équivalent du fait que tout le monde possède une voiture, mais personne ne sait comment en démarrer une. Cela peut faire des choses vraiment utiles et intéressantes, si seulement nous pouvions passer l' étape 1 .
Lecture bonus
la source
Réponses:
Apprêt
Tout ce qui suit concerne TPM 1.2. Gardez à l'esprit que Microsoft requiert un TPM 2.0 pour toutes les futures versions de Windows. La génération 2.0 est fondamentalement différente de la 1.2
Il n'y a pas de solution en une seule ligne en raison des principes de conception du TPM. Considérez le TPM comme un microcontrôleur avec des ressources limitées. Son objectif principal de conception était d'être bon marché, tout en restant sûr. Ainsi, le TPM a été déchiré de toute logique qui n'était pas nécessaire pour une opération sécurisée. Ainsi, un TPM ne fonctionne que lorsque vous avez au moins un logiciel plus ou moins gros , émettant beaucoup de commandes dans le bon ordre. Et ces séquences de commandes peuvent devenir très complexes. C'est pourquoi TCG a spécifié le TSS avec une API bien définie. Si vous souhaitez suivre la voie Java, il existe même une API Java de haut niveau . Je ne suis pas au courant d'un projet similaire pour C # / .net
Développement
Dans votre cas, je vous suggère de regarder le logiciel TPM d'IBM.
Dans le package, vous trouverez 3 composants très utiles:
Vous n'avez pas nécessairement besoin de l'émulateur logiciel TPM, vous pouvez également vous connecter au HW TPM de la machine. Cependant, vous pouvez intercepter les commandes émises et regarder les réponses, apprenant ainsi comment elles sont assemblées et comment elles correspondent à la spécification de commande.
Haut niveau
Conditions préalables:
Pour sceller un blob, vous devez effectuer les opérations suivantes:
Pour desceller, vous devez:
Vous pouvez stocker l'objet blob clé dans votre structure de données que vous utilisez pour stocker les octets protégés.
La plupart des commandes TPM dont vous avez besoin sont autorisées. Par conséquent, vous devez établir des sessions d'autorisation si nécessaire. AFAIR ce sont pour la plupart des sessions du RAFEO.
Commandes TPM
Actuellement, je ne peux pas exécuter une version de débogage, donc je ne peux pas vous fournir la séquence exacte. Considérez donc ceci comme une liste non ordonnée de commandes que vous devrez utiliser:
TPM_OSAP
TPM_CreateWrapKey
TPM_LoadKey2
TPM_Seal
Si vous souhaitez également lire les valeurs PCR actuelles:
TPM_PCRRead
la source
Clés de confiance et cryptées
Les clés approuvées et chiffrées sont deux nouveaux types de clés ajoutés au service de trousseau 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 objets blob chiffrés. Les clés de confiance nécessitent la disponibilité d'une puce TPM (Trusted Platform Module) pour une plus grande sécurité, tandis que les clés chiffrées peuvent être utilisées sur n'importe quel système. Tous les objets blob de 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 à la fois pour générer et pour sceller les clés. Les clés sont scellées sous une clé RSA de 2048 bits dans le TPM, et éventuellement scellées aux valeurs de PCR (mesure d'intégrité) spécifiées, et uniquement descellées par le TPM, si les vérifications de l'intégrité des PCR et des blob correspondent. Une clé de confiance chargée peut être mise à jour avec de nouvelles (futures) valeurs PCR, de sorte que les clés sont facilement migrées vers de nouvelles valeurs pcr, par exemple lorsque le noyau et les initramfs sont mis à jour. La même clé peut avoir de nombreux objets blob enregistrés sous différentes valeurs PCR, de sorte que plusieurs démarrages sont facilement pris en charge.
Par défaut, les clés de confiance 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 takeownership avec l'utilité du pantalon:
tpm_takeownership -u -z
.keyctl print
renvoie une copie hexadécimale ascii de la clé scellée, qui est au format standard TPM_STORED_DATA. La longueur de clé pour les nouvelles clés est toujours en octets. Les clés de confiance peuvent être de 32 à 128 octets (256 à 1024 bits), la limite supérieure est de tenir dans la longueur de clé SRK (RSA) de 2048 bits, avec toute la structure / remplissage nécessaire.Les clés chiffrées ne dépendent pas d'un TPM et sont plus rapides, car elles utilisent AES pour le chiffrement / déchiffrement. Les nouvelles clés sont créées à partir de nombres aléatoires générés par le noyau et sont chiffrées / déchiffrées à l'aide d'une clé «principale» spécifiée. La clé «principale» peut être de type clé de confiance ou clé utilisateur. Le principal inconvénient des clés cryptées est que si elles ne sont pas enracinées dans une clé de confiance, elles ne sont aussi sécurisées que la clé utilisateur qui les chiffre. La clé utilisateur principale doit donc être chargée de la manière la plus sécurisée possible, de préférence au début du démarrage.
La partie décryptée des clés crypté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, qui est identifiée par «format».
Exemples d'utilisation de clés fiables et chiffrées
Créez et enregistrez une clé de confiance nommée "kmk" d'une longueur de 32 octets:
Chargez une clé de confiance à partir de l'objet blob enregistré:
Resceller une clé de confiance sous les nouvelles valeurs pcr:
Le consommateur initial de 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 fichier. L'utilisation d'une clé de confiance offre des garanties solides que la clé EVM n'a pas été compromise par un problème de niveau utilisateur et, lorsqu'elle est scellée à des valeurs PCR de démarrage spécifiques, protège contre les attaques de démarrage et hors ligne. Créez et enregistrez une clé chiffrée "evm" à l'aide de la clé de confiance "kmk" ci-dessus:
option 1: omettre 'format'
option 2: définir explicitement le 'format' comme 'par défaut'
Chargez une clé chiffrée "evm" à partir de l'objet blob enregistré:
D'autres utilisations des clés de confiance et chiffrées, telles que le chiffrement 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'.
la source
Documentation/security/keys-ecryptfs.tx
Dépend de votre intention et des circonstances:
Chacun de ces cas d'utilisation (et il y en a d'autres) - ou une combinaison de ceux-ci - présente un chemin d'implémentation différent. Considérez le TPM comme un couteau suisse de dispositifs cryptographiques: il n'y a pas grand-chose que vous ne pouvez pas faire avec, mais la facilité d'utilisation souffre de cette polyvalence. La question continue de rebondir entre le cryptage, la signature et le verrouillage de la configuration du système, mais la partie principale de cette réponse considérera que la commande Seal couvre la plupart des besoins décrits dans la question.
C'est à cela que sert la commande Bind (remplacée par la commande Create pour TPM 2). Vous chargez une clé qui dérive d'une clé liée au TPM et la chiffrez avec elle (ou directement avec une clé liée au matériel). De cette façon, les données ne peuvent être déchiffrées qu'avec l'accès au même TPM.
Je ne sais pas si la réplication de tout ce processus est une bonne idée. D'une part, il n'est pas nécessaire d'utiliser une opération de signature n'importe où dans le processus. Il semblerait qu'à l'époque du développement d'Android 5, l' API Keystore se limitait aux opérations de signature et de vérification. Ma meilleure hypothèse est que l'équipe de chiffrement de disque a fait de son mieux pour travailler avec ce qu'elle avait et a conçu un algorithme dans lequel l'une des clés intermédiaires a été dérivée avec une opération de signature , en utilisant une clé TEE stockée, liant ainsi l'ensemble du processus à un matériel. clé liée uniquement disponible sur la plate-forme - car la signature était le seul moyen de le faire à l'époque. Cependant, il n'est pas nécessaire de vous contraindre de cette manière si vous avez accès à un TPM, ce qui vous donne plus de capacités que vous ne pensiez en avoir besoin!
Ceci est faux, les deux versions de TPM prennent en charge la signature.
Cela n'a aucun sens. La signature des mêmes données avec la même clé sera de produire la même signature. Vous pouvez confondre l'opération de signature avec l'opération de devis, qui se mélangera dans un nonce.
Cela devrait en fait être l'option préférée, bien que les deux soient possibles avec un TPM. Voir au dessus.
Malheureusement, il n'y a pas grand-chose à documenter. L'API Win est limitée à quelques fonctions TBS qui sont un niveau supprimé du pilote.
En fait, non, si vous aviez un TSS, vous n'auriez pas à l'utiliser
Tbsip_submit_Command()
. C'est tout l'intérêt d'avoir un TSS - les détails de bas niveau sont abstraits.Toujours vrai pour TPM 1, mais pour TPM 2, il y a TSS.MSR .
Correct.
Il n'est pas clair que ce soit un défi insurmontable. L'accès à TrouSerS via une interopérabilité devrait être préférable à la réécriture de tout le code de structuration des données. En outre, il y avait
doTSS
au moment de la rédaction de la question.La question contient une citation décrivant la différence entre les deux commandes, il ne devrait donc pas y avoir beaucoup de confusion. Le scellement est similaire à la liaison, avec la contrainte supplémentaire que l'état du système doit être le même pour que les données soient descellées.
Tout d'abord, il convient de souligner qu'il existe deux versions majeures de TPM, qui sont totalement incompatibles entre elles. Donc pratiquement aucun code que vous avez écrit pour TPM 1 ne fonctionnera pour TPM 2. L'API TBS est le seul code commun entre les deux et, pour être juste envers Microsoft, cela peut avoir été l'une des raisons pour lesquelles cette API n'a jamais grandi. La partie principale de la réponse présentera le code du TPM 1 pour deux raisons:
Deuxièmement, rendons la question plus précise. Je la réinterprète comme suit:
La commande Sceller est la mieux adaptée pour cela, car elle remplit la même fonction que la commande Bind lorsque la taille de la sélection PCR est définie sur zéro, mais la sélection PCR peut facilement être modifiée pour inclure les PCR que vous souhaitez. On se demande pourquoi la commande Bind a été incluse dans la spécification, et comme indiqué, elle a été supprimée dans la spécification TPM 2 et les deux ont été combinées dans une commande Create.
Voici le code C # pour utiliser la commande TPM 1.2 Seal pour crypter des données avec uniquement des fonctions TBS (note: ce code n'est pas testé et ne fonctionnera probablement pas sans débogage) :
Analyse du code:
Voici quelques-unes des rares fonctions disponibles dans Tbs.h et les seules que nous utiliserons ici. Ils vous permettent essentiellement d'ouvrir un handle vers le périphérique et de communiquer avec lui en envoyant et en recevant des octets bruts.
TPM est big endian, Windows est little endian. Ainsi, l'ordre des octets devra être inversé pour toutes les données que nous envoyons. Nous devons seulement nous soucier de l'inversion des entiers non signés 32 bits et 16 bits ici.
Ici, nous utilisons Tbsi_Context_Create () pour ouvrir un handle pour parler au TPM. Le
TBS_CONTEXT_PARAMS
paramètre est juste une structure C avec un champ int 32 bits non signé qui doit être défini sur 1 pour parler à une instance TPM 1.2, et c'est ce à quoi nous l'avons défini.Il s'agit de la taille minimale de la mémoire tampon dans les spécifications du client PC TPM . Ce sera plus que suffisant pour nos besoins ici.
TPM 1.2 Spec Part 3 dit ce qui suit:
Nous devons chiffrer XOR ce paramètre "secret" en utilisant un nonce généré lors d'une session du RAFEO. L'une des poignées d'entrée de la commande Seal est également une poignée OSAP:
Nous devons donc commencer par établir cette session du RAFEO. Le RAFEO est décrit dans TPM 1.2 Spec Part 1 . Le protocole RAFEO, ou protocole d'autorisation spécifique à un objet, a été inventé pour gérer le cas d'utilisation où vous souhaitez utiliser un objet TPM qui nécessite une autorisation plusieurs fois, mais que vous ne souhaitez pas fournir d'autorisation à chaque fois: une session RAFEO est utilisée à la place, ce qui repose sur sur le concept de "secret partagé", qui est un HMACqui mélange les données d'autorisation d'objet avec des nonces générés de chaque côté pour empêcher les attaques de réponse. Par conséquent, le "secret partagé" n'est connu que des deux côtés de cette session: le côté qui a lancé la session (utilisateur) et le côté qui l'a acceptée (TPM); aussi, les deux côtés doivent avoir les mêmes données d'autorisation d'objet pour que le «secret partagé» soit le même; de plus, le "secret partagé" utilisé dans une session sera invalide dans une autre. Ce diagramme de la spécification décrit le processus:
Nous n'utiliserons pas plusieurs sessions dans ce cas particulier (en fait, ce paramètre est ignoré avec la commande Seal!) Et la clé que nous utiliserons ne nécessite pas d'autorisation, mais malheureusement, nous sommes toujours liés par la spécification pour établir un RAFEO session.
Les opérandes de commande TPM_OSAP sont:
Chaque commande TPM 1.2 est présentée comme suit:
La balise est une valeur sur deux octets qui indique si ce qui suit est une entrée ou une sortie, et s'il existe des valeurs de données d'authentification après les paramètres de commande. Pour TPM_OSAP, la balise doit être TPM_TAG_RQU_COMMAND (0x00C1) selon la spécification, ce qui signifie «une commande sans autorisation».
La taille est une valeur de quatre octets qui spécifie la taille de la commande en octets, y compris l'étiquette et la taille elle-même. Nous définirons cette valeur plus tard, une fois que nous l'aurons calculée.
Le code de commande est une valeur de quatre octets qui sert d'ID de commande: il indique au TPM comment interpréter le reste de la commande. Notre code de commande ici est TPM_OSAP (0x0000000B).
Les deux éléments suivants à définir sont le type d'entité et la valeur d'entité. Puisque nous voulons utiliser une clé qui existe déjà dans le TPM, nous utiliserons le type d'entité "SRK" (0x0004), et puisque nous travaillons sous l'hypothèse que le TPM a déjà été possédé, il est sûr de supposer qu'il a un SRK chargé sous le handle permanent 0x40000000 selon la spécification, nous allons donc utiliser cette valeur de handle permanent pour notre valeur d'entité. (SRK signifie "Storage Root Key" et est la clé racine dont dérivent la plupart des autres clés appartenant au TPM)
Enfin, nous calculons la taille de la commande, la définissons et envoyons la commande.
Les données que nous sommes censés récupérer du TPM sur TPM_OSAP sont:
Alors on revient:
Nous extrayons ces valeurs et les stockons dans des variables.
Ensuite, nous calculons le "secret partagé". Selon les spécifications, les valeurs qui entrent dans le calcul sont les deux nonces RAFEO (un généré par l'utilisateur et l'autre généré par le TPM) et la valeur d'autorisation pour la clé que nous voulons utiliser - le SRK. Par convention, la valeur d'authentification SRK est "l'authentification bien connue": un tampon de 20 octets remis à zéro. Techniquement, on pourrait changer cette valeur en quelque chose d'autre lors de la prise en charge du TPM, mais cela n'est pas fait dans la pratique, nous pouvons donc supposer en toute sécurité que la valeur "authentification bien connue" est bonne.
Jetons ensuite un œil à ce qui se passe dans la commande TPM_Seal:
La plupart de ces paramètres sont simples à construire, à l'exception de deux d'entre eux:
encAuth
etpubAuth
. Regardons-les un par un.encAuth
est "Les AuthData cryptées pour les données scellées." Notre AuthData ici est "l'authentification bien connue" d'avant, mais oui, nous devons encore le chiffrer. Parce que nous utilisons une session RAFEO, elle est cryptée selon ADIP, ou Authorization-Data Insertion Protocol. D'après la spécification: "L'ADIP permet la création de nouvelles entités et l'insertion sécurisée de la nouvelle entité AuthData. La transmission de la nouvelle AuthData utilise un cryptage avec la clé basée sur le secret partagé d'une session OSAP." De plus: "Pour l'algorithme de chiffrement XOR obligatoire, le créateur crée une clé de chiffrement à l'aide d'un hachage SHA-1 du secret partagé du RAFEO et d'un nonce de session. Le créateur XOR crypte la nouvelle AuthData en utilisant la clé de chiffrement comme tampon unique et envoie ces données chiffrées avec la demande de création au TPM. "Le diagramme suivant explique le fonctionnement d'ADIP:
pubAuth
est "Le résumé de session d'autorisation pour les entrées et keyHandle." La partie 1 de la spécification, dans «Déclarations de paramètres pour les exemples OIAP et OSAP» explique comment interpréter la table de paramètres TPM_Seal ci-dessus: «La colonne HMAC # détaille les paramètres utilisés dans le calcul HMAC. Les paramètres 1S, 2S, etc. sont concaténés et haché en inParamDigest ou outParamDigest, appelé implicitement 1H1 et éventuellement 1H2 s'il y a deux sessions d'autorisation. Pour la première session, 1H1, 2H1, 3H1 et 4H1 sont concaténés et HMAC. Pour la deuxième session, 1H2, 2H2, 3H2, et 4H2 sont concaténés et HMAC. " Nous devrons donc hacher le texte en clair, sa taille, la taille des informations PCR,encAuth
d'en haut et l'ordinal TPM_Seal, puis HMAC avec les deux nonces et le booléen "continue session" en utilisant le OSAP "Rassembler tout cela dans un diagramme:
Remarquez comment nous définissons "Taille des informations PCR" à zéro dans ce code, car nous voulons simplement chiffrer les données sans les verrouiller dans un état système. Cependant, il est trivial de fournir une structure "info PCR" si nécessaire.
Enfin, nous construisons la commande et l'envoyons.
Nous utilisons la fonction Tbsip_Context_Close () pour fermer notre handle de communication.
Nous renvoyons la réponse telle quelle ici. Dans l'idéal, vous voudriez inverser à nouveau les octets et le valider en recalculant la
resAuth
valeur pour empêcher les attaques man-in-the-middle.En effet, Tspi_Data_Bind est une commande TSS, pas une commande TPM. La raison en est que cela ne nécessite aucun secret (seule la clé publique est utilisée), donc cela peut être fait sans impliquer le TPM. Cela a toutefois semé la confusion et même les commandes qui ne nécessitent aucun secret sont désormais incluses dans la spécification TPM 2.
Dépend de la version du TPM. Avec la commande TPM_CreateWrapKey pour TPM 1.2. Avec la commande TPM2_Create pour TPM 2.
Créez-le dans le TPM, encapsulez-le ou utilisez toute autre méthode disponible.
Le texte du livre est déroutant. Vous ne spécifiez pas la clé HMAC , vous spécifiez que vous voulez une clé HMAC .
Non, cela n'a pas de sens. La clé est secrète.
Il existe des commandes permettant de créer des clés ou de les importer pour les deux versions de TPM. Pour TPM 1, il n'y avait qu'une seule clé racine - la SRK - à partir de laquelle vous pouviez établir une hiérarchie de clés en créant des clés encapsulées. Avec TPM 2, vous pouvez avoir plusieurs clés principales ou racine.
Voir au dessus.
Dépend probablement du type de lecteur. Dans le cas de lecteurs non SED, la clé de chiffrement de lecteur est probablement encapsulée avec une clé TPM. Dans le cas des lecteurs SED, le mot de passe Admin1 (ou autre) est scellé avec le TPM.
L'EK n'est pas une clé de signature - c'est une clé de chiffrement. Cependant, ce n'est pas une clé de chiffrement à usage général: elle ne peut être utilisée que dans certains contextes .
Voir au dessus.
la source
Quand il dit
cela ne signifie PAS fournir la clé HMAC - cela signifie "pointer vers la clé HMAC que vous souhaitez utiliser" .
Les TPM peuvent utiliser un nombre pratiquement illimité de clés HMAC, comme indiqué dans le livre. Vous devez indiquer au TPM lequel utiliser.
la source