jump to navigation

Programmare il Fritz Chip (TPM) – Parte Terza January 12, 2006

Posted by laspinanelfianco in Trusted Computing.
add a comment

Con questa terza parte della serie, siamo arrivati al momento cruciale: parlare con il TPM.

Per “parlare con il TPM” è necessario scrivere un programma che utilizzi le funzionalità offerte dal driver del TPM per parlare con il dispositivo. In questo momento, l’unico linguaggio che può essere usato a questo scopo è il C. Dato che il C è molto conosciuto e molto utilizzato, questo non dovrebbe rappresentare un problema. Comunque, è facile prevedere che nel giro di qualche tempo verranno create le librerie necessarie a pilotare il TPM da Perl, Python, Ruby, PHP, Mono (.NET), Java e Dio solo sa cos’altro.

[Esistono già alcune utility Linux che permettono di parlare con il TPM senza dover scrivere un programma in prima persona. Sono incluse nel pacchetto che contiene i driver. Vedi oltre]

Su Linux, il TPM è normalmente accessibile come “device” Unix all’indirizzo /dev/tpm. In altri termini, è accessibile in modo molto simile ad una normale stampante (che di solito è accessibile all’indirizzo /dev/lpt). Come avviene per le stampanti e per molti altri dispositivi, per parlare con il TPM è sufficiente aprire il file virtuale /dev/tpm in modalità read/write e scriverci sopra il comando come se fosse un file di testo. Eventuali risposte del TPM possono essere lette dal file virtuale /dev/tpm esattamente come se fosse un normale file di testo.

Questa elegante tecnica di accesso al TPM (ed a qualunque altro dispositivo) è resa possibile dal fatto che per Unix (e quindi per Linux) qualunque dispositivo di questo tipo può essere trattato come se fosse un normale file di solo testo (un file ASCII) presente sul disco. Per scrivere su questo file virtuale basta aprirlo come se fosse un file normale e leggere ciò che ci interessa. Per scriverci sopra, basta aprirlo il modalità “write” e scriverci sopra come se fosse un file di testo. Nulla di più semplice.

Il TPM è in grado di comprendere 73 diversi comando ma solo 14 di questi vengono abitualmente utilizzati per i compiti di routine. Tra i comandi più usati possiamo ricordare i seguenti (controllate sulla documentazione o nei sorgenti la esatta sintassi dei nomi).

TakeOwnership: l’utente assume la proprietà del TPM “firmandolo”
SealFile: sigilla (cioè cifra) un file
SignFile: firma digitalmente un file
UnsealFile: de-sigilla (cioè decifra) un file
VerifyFile: verifica la firma digitale di un file
ListKeys: elenca le chiavi disponibili
LoadKey: carica una chiave
EvictKey: cancella una chiave
GetPubKey: carica una chiave pubblica proveniente dall’esterno
DisablePubKey: disabilita una chiave pubblica
DumpKey: scarica una chiave su file o su un dispositivo esterno
CreateKey: crea una coppia di chiavi
TPMReset: resetta il TPM
BindFile: lega un file ad una chiave
UnbindFile: scollega un file dalla chiave associata

Questi comandi sono ampiamente descritti nelle specifiche tecniche emesse dal TCG ma c’è un modo più semplice di scoprire quali sono e come devono essere utilizzati: studiare il codice C messo a disposizione della IBM proprio a questo scopo. Questo codice è reperibile a questo URL:

http://www.research.ibm.com/gsal/tcpa/tpm-3.0.3.tar.gz .

Questo pacchetto tar.gz contiene i driver (per i TPM prodotti da IBM, Atmel ed Infineon) per il kernel Linux 2.6, sotto forma di loadable module, alcune utility ed alcuni programmi di esempio (vi ricordo che i kernel versione 2.6.12 e successivi contengono già questi driver per cui la loro installazione di solito non è necessaria).

Le utility sono probabilmente la fonte di informazione più utile perchè usano i comandi standard del driver per far svolgere al TPM alcune funzioni fondamentali e molto utilizzate nella realtà. Ad esempio, il frammento di codice che segue è stato preso dai sorgenti della utility sealfile e mostra come viene invocata la funzione SealCurrPCR per cifrare in modo blindato il file corrente.

ret = TPM_SealCurrPCR(parhandle, /* KEY Entity Value */
0x0000007F, /* specify PCR registers 0-6 */
passptr1, /* Key Password */
passptr2, /* new blob password */
databuff, datalen, /* data to be sealed, length */
blob, &bloblen); /* buffer to receive result, int to receive result length */

Come si può vedere, il codice è piuttosto chiaro (nonstante la pessima formattazione) e non dovrebbe rappresentare un problema per un programmatore C di medie capacità.

Ma dove si trovano questi “sorgenti”? Scompattando il file tar.gz dei driver, si ottiene questa struttura di directory:

`– tpm-3.0.3
|– COPYING
|– README
|– doc
|– libtpm
|– man
|– tcfl
|– tpm-emu
`– tpm_utils

La directory tpm_utils contiene i sorgenti delle utility:

|– Makefile
|– bindfile.c
|– chgkeyauth.c
|– chgtpmauth.c
|– clearown.c
|– createkey.c
|– disablepubek.c
|– dumpkey.c
|– evictkey.c
|– getpubek.c
|– listkeys.c
|– loadkey.c
|– quote.c
|– sealfile.c
|– signfile.c
|– takeown.c
|– tpm_demo.c
|– tpmreset.c
|– unbindfile.c
|– unsealfile.c
`– verifyfile.c

Si tratta di file C che contengono tutte le informazioni necessarie e del relativo Makefile usato per compilare questi programmi. I nomi dei file ed i commenti che trovate al loro interno dovrebbero essere più che sufficienti per capire che cosa fanno questi programmi, che funzioni usano e come. Gli esempi si trovano invece nella directory tcfl.

Nel prossimo articolo vedremo alcuni esempi di chiamate al TPM.