[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#603104: TPM token fails to reinitialize properly on reload



Package: opencryptoki
Version: 2.2.8+dfsg-4

The TPM token code uses some global variables to track the storage
root key, root public & private keys, and leaf public & private keys
from the TPM. These variables are not properly reinitialized during
unload and reload of the module. In the case of wpasupplicant, this
results in PKCS#11 becoming unusable and one must kill the process to
start a fresh reconfiguration.

How to reproduce, given a wpasupplicant configuration that uses
opencryptoki to use the TPM for private key:
  - Connect to the network once, ensure a normal connection is possible.
  - Kill the opencryptoki pkcsslotd process (send SIGKILL; it ignores
SIGTERM while in use).
  - Start a new opencryptoki pkcsslotd process.
  - Attempt to reconnect to the same network.

Expected behavior:
  - wpasupplicant should unload the PKCS#11 openssl engine library and
reload it for the reconnection attempt.
  - The connection should succeed.

Observed behavior:
  - wpasupplicant unloads the PKCS#11 openssl engine library and
reloads it for the reconnection attempt.
  - After wpasupplicant loads the PKCS#11 openssl engine library, it
fails to load the private key.

The failure to load the private key was debugged back to failure in
the opencryptoki TPM library to load the private root key. The private
key fails to load because the session object opencryptoki uses to load
the key into the TPM is stale, left over from the first session.

A patch for this is attached and the patch has been sent upstream. See
http://sourceforge.net/tracker/?func=detail&atid=710344&aid=3073688&group_id=128009
and https://bugs.launchpad.net/ubuntu/+source/opencryptoki/+bug/645576.
Author: David Smith <dds@google.com>
Description: Reset TPM datastructures on init, not just logout.
Index: opencryptoki-2.2.8+dfsg/usr/lib/pkcs11/tpm_stdll/tpm_specific.c
===================================================================
--- opencryptoki-2.2.8+dfsg.orig/usr/lib/pkcs11/tpm_stdll/tpm_specific.c	2010-10-28 12:56:36.000000000 -0700
+++ opencryptoki-2.2.8+dfsg/usr/lib/pkcs11/tpm_stdll/tpm_specific.c	2010-10-28 15:19:41.000000000 -0700
@@ -111,6 +111,22 @@
 CK_BYTE current_so_pin_sha[SHA1_HASH_SIZE];
 
 
+static void
+clear_internal_structures()
+{
+	hSRK = NULL_HKEY;
+	hPrivateLeafKey = NULL_HKEY;
+	hPublicLeafKey = NULL_HKEY;
+	hPrivateRootKey = NULL_HKEY;
+	hPublicRootKey = NULL_HKEY;
+
+	memset(master_key_private, 0, MK_SIZE);
+	memset(current_so_pin_sha, 0, SHA1_HASH_SIZE);
+	memset(current_user_pin_sha, 0, SHA1_HASH_SIZE);
+
+	object_mgr_purge_private_token_objects();
+}
+
 CK_RV
 token_specific_session(CK_SLOT_ID  slotid)
 {
@@ -263,7 +279,7 @@
 {
 	TSS_RESULT result;
 	TSS_HPOLICY hPolicy;
-	static TSS_BOOL get_srk_pub_key = TRUE;
+	TSS_BOOL get_srk_pub_key = TRUE;
 	UINT32 key_size;
 
 	key_size = util_get_keysize_flag(size_n * 8);
@@ -1669,19 +1685,11 @@
 {
 	if (hPrivateLeafKey != NULL_HKEY) {
 		Tspi_Key_UnloadKey(hPrivateLeafKey);
-		hPrivateLeafKey = NULL_HKEY;
 	} else if (hPublicLeafKey != NULL_HKEY) {
 		Tspi_Key_UnloadKey(hPublicLeafKey);
-		hPublicLeafKey = NULL_HKEY;
 	}
 
-	memset(master_key_private, 0, MK_SIZE);
-	memset(current_so_pin_sha, 0, SHA1_HASH_SIZE);
-	memset(current_user_pin_sha, 0, SHA1_HASH_SIZE);
-
-	/* pulled from new_host.c */
-	object_mgr_purge_private_token_objects();
-
+	clear_internal_structures();
 	return CKR_OK;
 }
 
@@ -2005,6 +2013,7 @@
                 return CKR_FUNCTION_FAILED;
         }
 
+	clear_internal_structures();
 	return CKR_OK;
 }
 

Reply to: