Index: /trunk/src/VBox/Main/include/ConsoleImpl.h
===================================================================
--- /trunk/src/VBox/Main/include/ConsoleImpl.h	(revision 54977)
+++ /trunk/src/VBox/Main/include/ConsoleImpl.h	(revision 54978)
@@ -595,5 +595,6 @@
                  m_pbKey(pbKey),
                  m_cbKey(cbKey),
-                 m_fRemoveOnSuspend(fRemoveOnSuspend)
+                 m_fRemoveOnSuspend(fRemoveOnSuspend),
+                 m_cDisks(0)
             { }
 
@@ -605,4 +606,5 @@
                 m_cbKey = 0;
                 m_fRemoveOnSuspend = false;
+                m_cDisks = 0;
             }
 
@@ -610,9 +612,11 @@
             volatile uint32_t m_cRefs;
             /** Key material. */
-            uint8_t *m_pbKey;
+            uint8_t          *m_pbKey;
             /** Size of the key in bytes. */
-            size_t   m_cbKey;
+            size_t            m_cbKey;
             /** Flag whether to remove the key on suspend. */
-            bool     m_fRemoveOnSuspend;
+            bool              m_fRemoveOnSuspend;
+            /** Number of disks using this key. */
+            uint32_t          m_cDisks;
     };
 
@@ -864,5 +868,5 @@
      * @{ */
     HRESULT i_consoleParseDiskEncryption(const char *psz, const char **ppszEnd);
-    HRESULT i_configureEncryptionForDisk(const Utf8Str &strId);
+    HRESULT i_configureEncryptionForDisk(const Utf8Str &strId, unsigned *pcDisksConfigured);
     HRESULT i_clearDiskEncryptionKeysOnAllAttachmentsWithKeyId(const Utf8Str &strId);
     HRESULT i_initSecretKeyIfOnAllAttachments(void);
@@ -997,4 +1001,6 @@
     /** Number of disks configured for encryption. */
     unsigned             m_cDisksEncrypted;
+    /** Number of disks which have the key in the map. */
+    unsigned             m_cDisksPwProvided;
 
     /** Pointer to the key consumer -> provider (that's us) callbacks. */
Index: /trunk/src/VBox/Main/src-client/ConsoleImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/src-client/ConsoleImpl.cpp	(revision 54977)
+++ /trunk/src/VBox/Main/src-client/ConsoleImpl.cpp	(revision 54978)
@@ -3379,4 +3379,5 @@
     if (RT_SUCCESS(rc))
     {
+        unsigned cDisksConfigured = 0;
         memcpy(pbKey, aPassword.c_str(), cbKey);
 
@@ -3387,8 +3388,11 @@
         /* Add the key to the map */
         m_mapSecretKeys.insert(std::make_pair(aId, pKey));
-        hrc = i_configureEncryptionForDisk(aId);
+        hrc = i_configureEncryptionForDisk(aId, &cDisksConfigured);
         if (SUCCEEDED(hrc))
         {
-            if (   m_mapSecretKeys.size() == m_cDisksEncrypted
+            pKey->m_cDisks = cDisksConfigured;
+            m_cDisksPwProvided += cDisksConfigured;
+
+            if (   m_cDisksPwProvided == m_cDisksEncrypted
                 && mMachineState == MachineState_Paused)
             {
@@ -3445,4 +3449,5 @@
         if (RT_SUCCESS(rc))
         {
+            unsigned cDisksConfigured = 0;
             memcpy(pbKey, aPasswords[i].c_str(), cbKey);
 
@@ -3453,7 +3458,9 @@
             /* Add the key to the map */
             m_mapSecretKeys.insert(std::make_pair(aIds[i], pKey));
-            hrc = i_configureEncryptionForDisk(aIds[i]);
+            hrc = i_configureEncryptionForDisk(aIds[i], &cDisksConfigured);
             if (FAILED(hrc))
                 m_mapSecretKeys.erase(aIds[i]);
+            else
+                pKey->m_cDisks = cDisksConfigured;
         }
         else
@@ -3467,5 +3474,8 @@
              */
             for (unsigned ii = 0; ii < i; ii++)
+            {
+                i_clearDiskEncryptionKeysOnAllAttachmentsWithKeyId(aIds[ii]);
                 removeDiskEncryptionPassword(aIds[ii]);
+            }
 
             break;
@@ -3474,5 +3484,5 @@
 
     if (   SUCCEEDED(hrc)
-        && m_mapSecretKeys.size() == m_cDisksEncrypted
+        && m_cDisksPwProvided == m_cDisksEncrypted
         && mMachineState == MachineState_Paused)
     {
@@ -3508,4 +3518,5 @@
         return setError(VBOX_E_OBJECT_IN_USE, tr("The password is still in use by the VM"));
 
+    m_cDisksPwProvided -= pKey->m_cDisks;
     m_mapSecretKeys.erase(it);
     delete pKey;
@@ -3534,4 +3545,5 @@
         delete it->second;
     m_mapSecretKeys.clear();
+    m_cDisksPwProvided = 0;
 
     return S_OK;
@@ -4850,8 +4862,10 @@
  *
  * @returns COM status code.
- * @param   strId    The ID of the password.
+ * @param   strId                The ID of the password.
+ * @param   pcDisksConfigured    Where to store the number of disks configured for the given ID.
  */
-HRESULT Console::i_configureEncryptionForDisk(const com::Utf8Str &strId)
-{
+HRESULT Console::i_configureEncryptionForDisk(const com::Utf8Str &strId, unsigned *pcDisksConfigured)
+{
+    unsigned cDisksConfigured = 0;
     HRESULT hrc = S_OK;
     SafeIfaceArray<IMediumAttachment> sfaAttachments;
@@ -4959,8 +4973,17 @@
                         rc = pIMedium->pfnSetSecKeyIf(pIMedium, mpIfSecKey, mpIfSecKeyHlp);
                         if (rc == VERR_VD_PASSWORD_INCORRECT)
-                            return setError(VBOX_E_PASSWORD_INCORRECT, tr("The provided password for ID \"%s\" is not correct for at least one disk using this ID"),
-                                            strId.c_str());
+                        {
+                            hrc = setError(VBOX_E_PASSWORD_INCORRECT, tr("The provided password for ID \"%s\" is not correct for at least one disk using this ID"),
+                                           strId.c_str());
+                            break;
+                        }
                         else if (RT_FAILURE(rc))
-                            return setError(E_FAIL, tr("Failed to set the encryption key (%Rrc)"), rc);
+                        {
+                            hrc = setError(E_FAIL, tr("Failed to set the encryption key (%Rrc)"), rc);
+                            break;
+                        }
+
+                        if (RT_SUCCESS(rc))
+                           cDisksConfigured++;
                     }
                 }
@@ -4969,4 +4992,13 @@
             }
         }
+    }
+
+    if (   SUCCEEDED(hrc)
+        && pcDisksConfigured)
+        *pcDisksConfigured = cDisksConfigured;
+    else if (FAILED(hrc))
+    {
+        /* Clear disk encryption setup on successfully configured attachments. */
+        i_clearDiskEncryptionKeysOnAllAttachmentsWithKeyId(strId);
     }
 
@@ -5045,5 +5077,5 @@
                     /* Add the key to the map */
                     m_mapSecretKeys.insert(std::make_pair(Utf8Str(pszUuid), pKey));
-                    hrc = i_configureEncryptionForDisk(Utf8Str(pszUuid));
+                    hrc = i_configureEncryptionForDisk(Utf8Str(pszUuid), NULL);
                     if (FAILED(hrc))
                     {
@@ -5112,4 +5144,5 @@
 
             AssertMsg(!pKey->m_cRefs, ("No one should access the stored key at this point anymore!\n"));
+            m_cDisksPwProvided -= pKey->m_cDisks;
             delete pKey;
             m_mapSecretKeys.erase(it++);
@@ -6507,5 +6540,8 @@
     else if (   aReason == Reason_HostSuspend
              || aReason == Reason_HostBatteryLow)
+    {
+        alock.acquire();
         i_removeSecretKeysOnSuspend();
+    }
 
     LogFlowThisFunc(("hrc=%Rhrc\n", hrc));
