mardi 30 mars 2010

trusted platforms module (TPM), openssl and ecryptfs tutorial

Trusted Platform modules (TPM) are cryptographic processors mounted on computers. Their goal is to provide an encryption and authentification service package by keeping secret keys in hardware. It makes then difficult for an attacker to retrieve these keys. With an educational purpose, when a computer is not equipped with the chip, it is possible to emulate its  behavior. This tutorial extends (french security computer researcher) Noemie Floissac article [3]. It describes the use of TPM with Linux OS and its application for openssl and ecryptfs.
Frtench version available on the site

installation

do we have a TPM?

have a look to the BIOS of our computer. If TPM exists, we activate it.

Which TPM do we have?

be root:
~$ sudo passwd root
~$ su -
~#
we install tpm tools and trousers. They will be useful later.
~# apt-get install tpm-tools trousers
have a look at ACPI table.
~# apt-get install acpidump iasl vim
~# acpidump -b -t DSDT -o dsdt.asml
~$ iasl -d dsdt.asml
~$ vim dsdt.dsl
/TPM
  Device(TPM)
  {
    Name (_HID,EisaId("IFX0102"))
  (...)
:q
Our processor type is IFX0102. It is a Infineon TPM 1.2.

If no result comes from a search of "TPM" string, that means our computer is not equipped with.

a TPM (activated in the BIOS) is present in our computer


let's list available drivers:
~# modprobe -l | grep tpm
kernel/drivers/char/tpm/tpm.ko
kernel/drivers/char/tpm/tpm_bios.ko
kernel/drivers/char/tpm/tpm_tis.ko
kernel/drivers/char/tpm/tpm_nsc.ko
kernel/drivers/char/tpm/tpm_atmel.ko
kernel/drivers/char/tpm/tpm_infineon.ko
let's load TPM module and processor driver in the kernel
~# modprobe -a tpm tpm_infineon
remark: at the end of this article, we could prefer to load these modules during boot. We will then add to /etc/modules:
~# vim /etc/modules
tpm
tpm_infineon

TPM emulation with tpmd

If our computer is not equipped with a TPM, we still can emulate it with tpmd daemon.

First, install the useful tools
~# apt-get install libgmp3c2 libgmp3-dev cmake subversion
~# exit
~$
Download tpm-emulator sources
~$ svn checkout svn://svn.berlios.de/tpm-emulator/trunk tpm-emulator
Follow the compilation how-to from the README file
~$ cd tpm-emulator
~/tpm-emulator$ mkdir build
~/tpm-emulator$ cd build
~/tpm-emulator/build$ cmake ../
~/tpm-emulator/build$ sudo make
~/tpm-emulator/build$ sudo make install
copy the generated driver to drivers directory
~/tpm-emulator/build$ sudo cp tpmd_dev/linux/tpmd_dev.ko /lib/modules/2.6.31-xxx/kernel/drivers/char/tpm/
reload the module list and load tpm module in the Linux kernel
~# depmod
~# modprobe -a tpm
~# modprobe -a tpmd_dev
verify that modules are well loaded
~# lsmod | grep tpm
tpm                    15680  0
tpm_bios                6268  1 tpm
tpmd_dev                4176  1
as before, to load them in boot sequence, we can add them to /etc/modules
~# vim /etc/modules
tpm
tpmd_dev

TPM initialization

re-initialization

If the chip is emulated, start the daemon.
Remark: we'll have to do it at each reboot. We must be root.
~$ sudo tpmd
start tpm-tools
~$ sudo tcsd
does the tpm work? From now, we don't need to be root anymore.
~$ tpm_version
  TPM 1.2 Version Info:
  Chip Version:        1.2.0.7
  Spec Level:          2
  Errata Revision:     1
  TPM Vendor ID:       ETHZ
  TPM Version:         01010000
  Manufacturer Info:   4554485a
Remark: if we work in a virtualized environment, it's time to take a snapshot. So, we won't have to redo if we meet next bug.

An emulated TPM is already enabled and active. Jump to next section.

With a physical chip (not emulated), we first initialize it:
~$ tpm_clear --force
TPM Successfuly Cleared.  You need to reboot to complete this operation.  After reboot the TPM will be in the default state: unowned, disabled and inactive.
~$ tpm_setenable --enable --force
~$ tpm_setactive --active
Action requires a reboot to take affect
remark: with an emulated tpm, the next message is printed after the clear - setenable - setactive procedure. In this case, we must start again from the beginning: install tpm and tpmd_dev modules again, then reload tpmd and tcsd processes. The kill command uses pid results form ps command.
~$ tpm_takeownership -z -y
Tspi_TPM_TakeOwnership failed: 0x00000008 - layer=tpm, code=0008 (8), The TPM target command has been disabled
~$ ps -e | grep tpm
~$ ps -e | grep tcsd
~# kill 4335
~# kill 4336
~# modprobe -r tpmd_dev~# modprobe -r tpm
~# apt-get remove tpm-tools trousers

TPM: the key master

TPM only keeps few keys. The others are stored encrypted on the disk. [8]

The Endorsment Key (EK) is the RSA keys pair of the chip. It is created by the manufacturer and can sometimes be modified by the owner of the computer.

The Storage Root Key (SRK) is the root RSA keys pair. The ower initialize it. it is used to encrypt:
- the Storage Keys (SK),
- the Attestation Identity Keys (AIK).

The Storage Keys (SK) are used to encrypt and sign the Binding Keys (BK).

The Binding Keys (BK) are used to encrypt little amounts of datas.

The Attestation Identity Keys (AIK) are used for the exchanges with the TPM. They allow the applications to authenticate the TPM.

create the SRK

have a look to the tpm_takeownership command
~$ tpm_takeownership -h
Usage: tpm_takeownership [options]
    -h, --help
        Display command usage info.
    -v, --version
        Display command version info.
    -l, --log [none|error|info|debug]
        Set logging level.
    -u, --unicode
        Use TSS UNICODE encoding for passwords to comply with applications using TSS popup boxes
    -y, --owner-well-known
        Set the owner secret to all zeros (20 bytes of zeros).
    -z, --srk-well-known
        Set the SRK secret to all zeros (20 bytes of zeros).
We create the SRK. Caution! do not fill the password. We just push ENTER on the keyboard: The SRK password's goal is to limit key generation to known users. But it is shared between them. So it is not a secret anymore. If we create a password, we must modify the source code of libengine-tpm-openssl library.
We do not create an owner password either (option -y).
~$ tpm_takeownership -u -y
Enter SRK password:
Confirm password:

tpm et openssl

We can use out TPM with openssl.

Install the packages
~$ sudo apt-get install libengine-tpm-openssl libtspi-dev
Here is the readme of the library which link the TPM and openssl: libengine-tpm-openssl

 README for the OpenSSL 0.9.8 TPM engine

 Author: Kent Yoder
 Report bugs: trousers-users@lists.sf.net


ABOUT

  This package contains 2 sets of code, a command-line utility used to
generate a TSS key blob and write it to disk and an OpenSSL engine which
interfaces with the TSS API.

BUILDING

 Requirements: OpenSSL 0.9.8

 By default, the build will assume that you have a custom openssl installed
in /usr/local/ssl.

 $ configure [--enable-debug] [--with-openssl=/path/to/custom/openssl]
 $ make
 # make install

RUNNING

create_tpm_key

        create_tpm_key: create a TPM key and write it to disk
        usage: create_tpm_key [options]

        Options:
                -e|--enc-scheme encryption scheme to use [PKCSV15] or OAEP
                -q|--sig-scheme signature scheme to use [DER] or SHA1
                -s|--key-size   key size in bits [2048]
                -a|--auth       require a password for the key [NO]
                -p|--popup      use TSS GUI popup dialogs to get the password
                for the key [NO] (implies --auth)

  Key type:  The TPM key type of the key created will be legacy, so that it can
be used for both signing and encryption.

  Padding schemes:  Choosing the encryption and signature schemes
at key creation time is mandatory because of the structure of a TPM key blob.
Once a key is created by the TPM, the encryption and signature schemes are set
in store and cannot be changed without corrupting the key (making it unloadable
into a TPM). Here are the trade-offs:

* PKCSV15 encryption scheme - all encrypted data will be padded using the
    PKCSv1.5 padding algorithm. OAEP padding is considered more secure, but
    many legacy apps will require PKCSv1.5 (most notably openssl). PKCSV15
    padding will also allow a slightly larger chunk of data to be encrypted in
    one operation.
  OAEP encryption scheme - all encrypted data will be padded using the OAEP
    padding algorithm.

* DER signature scheme - assumes data to be signed is DER encoded (although
    this is not required). Will allow signatures to be made of arbitrary
    size, up to the size the padding will allow.
  SHA1 signature scheme - assumes *all* data to be signed is a SHA1 hash.
    This restricts the data size to be signed to 20 bytes, always.

  * default

  Key sizes: Default=2048 bits. Other valid sizes are 512 and 1024 bits.

  Key auth: Default=none. if -a is specified, you will be prompted on the
command line using OpenSSL for a passphrase. This passphrase is SHA1 hashed
by the TSS and used as the key's password. At key load time, you'll be
prompted for the passphrase again by OpenSSL. If -p is specified, you'll get
a GUI  prompt for password.
  In order to make the TPM engine prompt you for your password, add the
following code to your app:

  To set the SRK password explicitly in your code, do:

  ENGINE_ctrl_cmd(e, "PIN", 0, SRK_password, NULL, 0);

  The default secret mode is TSS_SECRET_MODE_PLAIN, so the above code will
always work with a plaintext SRK secret.  If you have the hash of your secret,
do this:

  ENGINE_ctrl_cmd(e, "SECRET_MODE", TSS_SECRET_MODE_SHA1, NULL, NULL, 0);
  ENGINE_ctrl_cmd(e, "PIN", 0, SRK_password_hash, NULL, 0);

  To force the TSS to popup a dialog prompting you for your SRK password:

  ENGINE_ctrl_cmd(e, "SECRET_MODE", TSS_SECRET_MODE_POPUP, NULL, NULL, 0);


OpenSSL TPM engine

  Included in this package is a sample openssl.cnf file, which can be used
to turn on use of the TPM engine in apps where OpenSSL config support is
compiled in.


USE CASES

  If there's a use case for the TPM engine that you'd like to see it support,
please drop a line to trousers-users@lists.sf.net.

USES

Create a self-signed cert using the TPM engine:

1. Generate a TPM key and write it to a file:
 $ create_tpm_key

2. Make the openssl certificate request:
 $ openssl req -keyform engine -engine tpm -key -new -x509 -days 365 -out

3. Test using openssl:
 $ openssl s_server -cert -www -accept 4433 -keyform engine -engine tpm -key
 $ konqueror https://localhost:4433
Follow the advices:

Create the RSA keys
~$ create_tpm_key -a maclef
create the autosigned certificate
~$ openssl req -keyform engine -engine tpm -key ./maclef -new -x509 -days 365 -out moncert
test the certificate
$ openssl s_server -cert moncert -www -accept 4433 -keyform engine -engine tpm -key maclef
$ firefox https://localhost:4433


ecryptfs

installation

install ecryptfs-utils
~# apt-get install ecryptfs-utils
start ecryptfsd daemon. We need it to use public keys
~# ecryptfsd

use

create a directory. We will fill it with our encrypted files
~# mkdir /secret
mount the file system encrypted with ecrypts:
~# mount -t ecryptfs /secret /secret -o key=openssl_keyfile=~/maclef -o ecryptfs_cipher=aes -o ecryptfs_key_bytes=32 -o no_sig_cache -o ecryptfs_enable_filename_crypto=y -o ecryptfs_passthrough=n

Passphrase:

Filename Encryption Key (FNEK) Signature [72da151dc29cf399]:

Attempting to mount with the following options:
  ecryptfs_unlink_sigs
  ecryptfs_fnek_sig=72da151dc29cf399
  ecryptfs_key_bytes=32
  ecryptfs_cipher=aes
  ecryptfs_sig=72da151dc29cf399
Mounted eCryptfs
create a file in /secret
~# cd /secret
/secret# echo "bonjour" > ./essai
/secret# cat essai
bonjour
unmount /secret
/secret# cd ~
~# umount /secret
let's see now the product


The file and its name have been encrypted.

access to the encrypted directory (we use the same passphrase and FNEK)
~# mount -t ecryptfs /secret /secret -o key=openssl_keyfile=~/maclef -o ecryptfs_cipher=aes -o ecryptfs_key_bytes=32 -o no_sig_cache -o ecryptfs_enable_filename_crypto=y -o ecryptfs_passthrough=n
Passphrase:
Filename Encryption Key (FNEK) Signature [72da151dc29cf399]:
Attempting to mount with the following options:
  ecryptfs_unlink_sigs
  ecryptfs_fnek_sig=72da151dc29cf399
  ecryptfs_key_bytes=32
  ecryptfs_cipher=aes
  ecryptfs_sig=72da151dc29cf399
Mounted eCryptfs
it definitly works!# cat /secret/essai
bonjour

références:

1) tpm tools - http://sourceforge.net/projects/trousers/
2) how to use a tpm with linux - https://www.grounation.org/index.php?post/2008/07/04/8-how-to-use-a-tpm-with-linux
3) Emmanuel Fleury et Noémie Floissac - quelle confiance accorder au trusted platforms - MISC n° 45 septembre/octobre 2009
4) Noémie Floissac - quel avenir pour les trusted platforms
5) Hans Brandl - infineon technologies - Trusted computing: the TCG trusted platform module specification
6) Windows trusted platform module management step-by-step guide - http://technet.microsoft.com/en-us/library/cc749022%28WS.10%29.aspx
7) SRK - http://docs.hp.com/en/5991-7466/ch01s03.html
8) tpm keys - http://www.cs.bham.ac.uk/~mdr/teaching/modules/security/lectures/TrustedComputingTCG.html
9) installer ecryptfs - http://publib.boulder.ibm.com/infocenter/lnxinfo/v3r0m0/index.jsp?topic=/liaai/ecrypts/liaaiecryptfstroub.htm
10) IBM embedded security subsystem - http://www.thinkwiki.org/wiki/Embedded_Security_Subsystem
11) ecryptfs faq - http://ecryptfs.sourceforge.net/ecryptfs-faq.html

4 commentaires:

  1. merci beaucoup pour les info !!

    Does it mean after combining all these 3 (tpm, openssl and ecryptfs), will make the hard drive or certain folders "unuse-able" when the TPM chip does not exist or unplugged? For eg, if the encrypted hard drive is installed in another computer and all the files will be encrypted since the other computer doesnt have a TPM chip that hold the passphrase/keys needed to mount the hardrive above??

    i have tried with eCryptfs and TPM with the option of tspi with NO success, it shud be a bug or something. But if your method here is doing what i said above, that will be fantastique!

    Hope to hear from u here....

    RépondreSupprimer
  2. I have just started out on the tutorial and I really appreciate the effort you have put in to give detailed step by step information for the same. Thanks a lot. This is extremely helpful stuff.

    RépondreSupprimer
  3. dear all plz help
    i am having this error
    * Starting Trusted Computing daemon tcsd /etc/init.d/trousers: 32: [: /dev/tpm: unexpected operator
    [fail]
    invoke-rc.d: initscript trousers, action "start" failed.
    on installing trousers for emulated tpm

    RépondreSupprimer