Asynchronous initialization of PKCS#11 via cryptohomed

This CL adds asynchronous initialization of PKCS#11 to cryptohomed. MountTaskPkcs11Init handles this initialization on the mount thread.

Right now, the initialization is only enabled if cryptohomed is started with the --cryptohome-init-pkcs11 flag.

PKCS#11 initialization is predicated on 2 conditions - TPM is owned, and the mounting of cryptohome is finished. The cases are handled as follows:

1) For synchronous mounts, MountTaskPkcs11Init is immediately put on the mount thread after it mounts successfully.

2) For asynchronous mounts, the sequence id of the mount request is noted. The callback NotifyEvent() determines if the sequence id of the completed request corresponds to an earlier async mount request. If so, a MountTaskPkcs11Init is put on the mount thread.

3) If the TPM is unowned, tpminit_must_pkcs11_init_ is set to true. The InitializeTPMComplete callback for TpmInit detects this and puts a MountTaskPkcs11Init on the mount thread.

Since PIN initialization can take upto 40 seconds, it is possible that the user logs out before this initialization is complete. In that case, the initialization attempt is made again the next time the user logs in.

Known problems:
Logging out while PKCS#11 initialization is in progress will cause cryptohomed to be restarted. (crosbug.com/14292)

BUG=chromium-os:12295
TEST=manual (see below)

(With the flag disabled)
Verified from the logs that PKCS#11 initialization is skipped because of disabled flag.

(With the flag enabled)
Disable the pkcs11 and entd upstart jobs so that their operations do not interfere with our cryptohomed pkcs11 operations. Also, restart cryptohomed with the --cryptohome-init-pkcs11 flag.

With TPM being owned. Tested the following scenarios:

1) Login as a new user. Logs indicate that initialization is happening in the background. Let it finish. Try logging in again - token should already be detected as being initialized.

2) Repeat step #1 by alternating between 2 different users. Again, pkcs#11 initialization should only happen once, and not repeat.

3) Repeat steps 1 and 2 by interrupting the PIN setup. Initialization should retry on the next mount. Ensured that this happens irrespective of interrupting during the SO pin reset or the user pin reset.

4) Ran suite_Smoke on the live and VM image.

Review URL: http://codereview.chromium.org/6873028

Change-Id: I1cf7d592a86c531c55577a1fe70c36d63b573fde
6 files changed