TPM enabled security in Emulab
Secure Remote Node Communication via TMCC
- Background - Trusted Platform Modules (TPMs) can create RSA keypairs that are suitable for secure communications by today's standards. During this creation process,the private key never leaves the TPM in an unencrypted form. Furthermore, the created key can be 'wrapped' (encrypted) by the storage root key (aka SRK). The SRK is generated every time somebody takes ownership of a TPM.
- Because of these properties and the fact that we have no persistent storage, the following should hopefully work:
- Boss starts configuring a node for a new experiment.
- At some point when the client is ready to receive sensitive information from boss, the client asks boss to send her the following items:
- Client's X509 cert (for her public key, of course) signed by our CA (certificate authority)
- Client's corresponding private key blob (remember it is encrypted with a key in the TPM and can supposedly only be useful after it is loaded into that specific TPM using the proper TPM password)
- The client checks for consistency between the cert and the keypair after successfully unwrapping it.
- The client then uses it's received CA signed cert, the corresponding key blob that is now loaded and functional in the TPM, and a local copy of the trusted CA's cert (embedded in the Frisbee image, for now) to setup a strictly authenticated TLS tunnel.
- Everything is now happily encrypted and 100% secure - nothing bad could ever possibly happen.
Enforcing TPM Use
- We can make sure clients are using TPM keys by checking on boss that the client's cert used to establish the TLS session matches the one we have in the database for TPM usage.
- If they match, the client must have the corresponding private key which means they are using the TPM or they figured out some way to decrypt traffic encrypted with the public cert.
- TrouSerS - http://trousers.sourceforge.net/
- TrouSerS is the userspace daemon that should be the only portal to TPM usage (as per the TCG spec). Make sure you do as advised in the README if you have taken ownership of your TPM already.
- openssl-tpm-engine http://sourceforge.net/projects/trousers/files/OpenSSL%20TPM%20Engine/
- This is an OpenSSL engine that will make our lives much easier; it saves us the hassle of writing the code to load, unwrap, and convert a TPM keyfile into an OpenSSL usable key. Also, more importantly, it lets us integrate TPM use directly with OpenSSL.
- tpm-tools - http://sourceforge.net/projects/trousers/
- tpm-tools will be useful to take ownership of the tpm, but it doesn't have to be done with tpm-tools; you can even take ownership of the TPM in a different OS and it will still work.
- XXX: how to enable in the BIOS
- Use 'TPM=1' in your defs file.
- Put your SRK password into testbed/etc/gpxesrkpass or [gPXE source root]/src/gpxesrkpass before you build gPXE if you wish to compile it in. Otherwise you can use a gPXE script to configure it at runtime using the "srkpass" command.
- For GNU/Linux, you will need support for TPM devices; many distros do not have a module compiled or have a driver compiled in the kernel. You will likely need to do this yourself. The TrouSerS daemon will immediately exit if it doesn't detect a TPM device.
- Before proceeding, you need to have the TrouSerS daemon running and openssl-tpm-engine installed.
- Test to make sure TrouSerS is working properly:
# tpm_version TPM 1.2 Version Info: Chip Version: 184.108.40.206 Spec Level: 2 Errata Revision: 0 TPM Vendor ID: ATML TPM Version: 01010000 Manufacturer Info: 41544d4c
- If you haven't already taken ownership of your TPM, do so now:
# tpm_takeownership Enter owner password: Confirm password: Enter SRK password: Confirm password: #
- Next, create an endorsement key if it doesn't already have one; this key will be persistent between ownerships and will stay with the chip forever but nobody really uses them for anything yet.
- Create a TPM key, and save the blob (which will of course be wrapped by the SRK). openssl-tpm-engine comes with a small program to do this for us:
- Generate a cert request using this key; openssl-tpm-engine will again come to our rescue:
openssl req -keyform engine -engine tpm -key client.key -new -out client.req
- Send this req to whomever has access to the CA used on boss; they should then send you an X509 cert signed by the CA. The command should be something like this:
openssl x509 -req -in client.req -days 2000 -sha1 -extfile /etc/pki/tls/openssl.cnf -extensions usr_cert -CA emulab.pem -CAkey emulab.pem -CAcreateserial -out client.cert
- Now we need to import our signed cert and keyblob into the SQL database on boss - they go into tbdb/node_hostkeys. At the moment, this is all done manually. I found it easier to do it like this (obviously you will need to replace $PCID with the proper value): (sorry for the long line but there shouldn't be newlines in the tpmblob)
- This should be everything that is necessary. Now, when a node boots up in an experiment, it will run rc/rc.tpmsetup and get the cert and keyblob; they will be called tpm.cert and tpm.key.
- You can now use the -T flag with tmcc on this node. In the future, you only need the TrouSerS daemon to be running.
Trusted OS Loading in Emulab
TPM enabled nodes are capable of "measuring" or SHA1 hashing the boot sector before passing control to it (the BIOS measuring code is immutable). The hashes are stored in registers in the TPM called PCRs. Other secure boot-loaders then continue this chain of hashing (the TPM hashes the requested content in an accumulative fashion) in order to guarantee that we can verify what we have loaded. It is possible to seal data or keys to certain PCR values; the key cannot be used or the data unsealed unless the PCRs match. The PCRs are also impossible to change except through extension - when arbitrary data is hashed and then combined with the previous hash in a (supposedly) cryptographically secure fashion.
(This section is wrong - Cody will fix it). Because data cannot be sealed on behalf of other nodes and sealing keys are TPM specific (obviously), setup will require that we generate a magic blob (whether that be a key or sealed data) on every node that we wish to be able to boot securely. In order to avoid the maintenance nightmare that would ensue if we were to measure the boot all the way to the frisbee loader (the PCRs would differ if one bit anywhere in the boot chain was ever flipped thus requiring us to generate a new magic blob for _every_ trusted boot path for every individual node), we have decided to use the TPM to measure only the first bootloader which will give us access to the magic PCR-sealed blob. Our boot software will SHA1 all the next pieces of the bootchain (before passing control to the pending piece) and send the hashes to boss using the magic PCR-sealed blob (this will probably be a signing key), asking if we should boot the next piece. This way if an attacker were to compromise the very first stage, it would be noticed when we tried to use our magic PCR-sealed blob as we wouldn't be able to. If any subsequent stage were to be compromised, boss would see that the signed SHA1 hash of it was very wrong and tell the node to not boot the rubbish.
Because we want to eventually send off the correct, accumulative hash to boss which will make use of the magic PCR-sealed blob, and because GNU/Linux is the only convenient OS with TPM support, it makes the most sense to use Ryan's Linux MFS to load the final image via frisbee. We aren't aware of a bootable PXE card that is wise enough to measure what it receives with the TPM so we need to boot from a dongle; probably to gPXE which will then pull down a frisbee MFS. Then, the MFS will load on the selected OS.