cryptohome: reload cryptohome key after public area reading errors

If cryptohomed can't read a cryptohome key public area, it's possible
that the transient key object has been flushed after suspend-resume.

To fix that:

 - Reload cryptohome key in case of "invalid handle" errors when
   reading the public areas of the key should already be loaded.

 - Return a proper retry action for TPM 2.0 case.

 - Mark the previous handle as invalid before reloading to avoid
   flushing that old handle after loading the new cryptohome key.
   The new handle is often the same as the old one, and as a result
   we flush just loaded key. In any case, even the new and old
   handles are different, we are flushing some arbitrary handle
   that at some point belonged to cryptohome key, but we already
   know that we fail to access that key using that handle.

 - For the same reason when resetting the handle object, check
   if the tpm and handle didn't change, and do nothing in such
   case.

BUG=chrome-os-partner:62370
TEST=1) Boot, login, logout.
     2) Go through suspend to S3 and resume back, e.g.:
        echo 0 > /sys/class/rtc/rtc0/wakealarm
        echo "+3" > /sys/class/rtc/rtc0/wakealarm
        echo mem > /sys/power/state
     3) Attempt to login again. It should succeed. The log
        shouldn't contain messages "Unable to get the cryptohome
        public key from the TPM."

Change-Id: Id23a90c4ef72a21d51dfedc8ccbf8c3a09dad2b1
Reviewed-on: https://chromium-review.googlesource.com/433337
Commit-Ready: Andrey Pronin <apronin@chromium.org>
Tested-by: Andrey Pronin <apronin@chromium.org>
Reviewed-by: Darren Krahn <dkrahn@chromium.org>
(cherry picked from commit 6245eff60fb5643e6ecac06cb9e0ebed49067f40)
Reviewed-on: https://chromium-review.googlesource.com/436624
Reviewed-by: Andrey Pronin <apronin@chromium.org>
Reviewed-by: Benson Leung <bleung@chromium.org>
Commit-Queue: Benson Leung <bleung@chromium.org>
Tested-by: Benson Leung <bleung@chromium.org>
Trybot-Ready: Benson Leung <bleung@chromium.org>
4 files changed