Support for migration from 3.0 19/182719/6
authorKrzysztof Jackiewicz <k.jackiewicz@samsung.com>
Wed, 27 Jun 2018 09:08:57 +0000 (11:08 +0200)
committerJaemin Ryu <jm77.ryu@samsung.com>
Thu, 26 Jul 2018 05:12:18 +0000 (05:12 +0000)
There are products based on Tizen 3.0 using different encryption scheme and
footer format. To properly migrate their internal memory encryption key the
flag marking the beginning of an upgrade is left by ode-fota.

During the first device unlock(attempt to mount encrypted partition) after the
upgrade the flag presence is checked. The flag is removed but if it was
present, oded will try to use the product specific key storage plugin to load
the master key for internal encryption.

If it succeeds it will encrypt the master key using given password. Otherwise
it will fall back to normal operation, that is, decrypt the master key using
given password.

Any attempt to decrypt the master key using a password will result in removal
of the upgrade flag.

It is assumed that affected products verify the password prior to passing it to
ode_internal_encryption_set_mount_password().

For unaffected products that do not require the migration it's enough to remove
the flag or the master key stored for the purpose of the upgrade before calling
ode_internal_encryption_set_mount_password(). Note that it is advised to remove
the master key stored for the purpose of the upgrade as soon as possible after
the upgrade due to security reasons. Even if the flag and master key are
present, the encryption introduced in this commit won't break anything as long
as the password is correct.

Change-Id: I86c83366c432aa8ce1d4f25c9beeed98d4f672c3

fota/fota.cpp
server/internal-encryption.cpp
server/key-server.cpp
server/key-server.h
server/upgrade-support.cpp
server/upgrade-support.h

index 499ff94..7c7c46c 100644 (file)
@@ -157,6 +157,7 @@ int main(int argc, char* argv[])
 
                        // mount options are ignored by mount()
                        dmcrypt.mount(masterKey, 0);
+                       UpgradeSupport::createUpgradeFlag();
                } else if (UMOUNT == argv[1]) {
                        std::string path = INTERNAL_PATH;
                        if (argc == 3)
index bf7cc99..2791620 100644 (file)
@@ -46,6 +46,7 @@
 #include "ext4-tool.h"
 #include "internal-encryption.h"
 #include "internal-encryption-common.h"
+#include "upgrade-support.h"
 
 namespace ode {
 
@@ -395,7 +396,23 @@ InternalEncryptionServer::~InternalEncryptionServer()
 
 int InternalEncryptionServer::setMountPassword(const std::string& password)
 {
-       return keyServer.get(engine->getSource(), password, mountKey);
+       const std::string& dev = engine->getSource();
+
+       // check if upgrade flag exists
+       if(UpgradeSupport::removeUpgradeFlag()) {
+               INFO("Upgrade flag detected.");
+               // try to load the master key
+               try {
+                       mountKey = UpgradeSupport::loadMasterKey(dev);
+
+                       // encrypt the master key with given password
+                       return keyServer.changePassword2(dev, mountKey, password);
+               } catch (const runtime::Exception&) {
+                       INFO("Failed to load the master key stored during upgrade.");
+               }
+       }
+
+       return keyServer.get(dev, password, mountKey);
 }
 
 int InternalEncryptionServer::mount(const std::vector<unsigned char> &mk, unsigned int options)
index 4ab6541..2dc279b 100644 (file)
@@ -123,6 +123,8 @@ int KeyServer::changePassword(const std::string& dev,
                return error::NoSuchFile;
        }
 
+       UpgradeSupport::removeUpgradeFlag();
+
        EncryptedKey ek(FileFooter::read(dev));
 
        auto key = ek.decrypt(curPassword);
@@ -137,6 +139,20 @@ int KeyServer::changePassword(const std::string& dev,
        return error::None;
 }
 
+int KeyServer::changePassword2(const std::string& dev,
+                                                          const BinaryData& masterKey,
+                                                          const std::string& newPassword)
+{
+       if (dev.empty() || masterKey.empty() || newPassword.empty())
+               return error::InvalidParameter;
+
+       std::lock_guard<std::mutex> lock(footerLock);
+       EncryptedKey ek(masterKey, newPassword);
+
+       FileFooter::write(dev, ek.serialize());
+       return error::None;
+}
+
 int KeyServer::verifyPassword(const std::string& dev,
                                                          const std::string& password)
 {
@@ -214,6 +230,8 @@ int KeyServer::internalGet(const std::string& dev,
                return error::NoSuchFile;
        }
 
+       UpgradeSupport::removeUpgradeFlag();
+
        EncryptedKey ek(FileFooter::read(dev));
 
        key = ek.decrypt(password);
index a37f442..fbe7dde 100644 (file)
@@ -40,6 +40,9 @@ public:
        int changePassword(const std::string& dev,
                                           const std::string& curPW,
                                           const std::string& newPW);
+       int changePassword2(const std::string& dev,
+                                               const BinaryData& masterKey,
+                                               const std::string& newPW);
        int verifyPassword(const std::string& dev, const std::string& password);
        int get(const std::string& dev,
                        const std::string& password,
index 2195603..3afad93 100644 (file)
@@ -46,6 +46,8 @@ typedef int(*KeyStoragePluginLoadFn)(const unsigned char*, size_t,
 typedef int(*KeyStoragePluginRemoveFn)(const unsigned char*, size_t);
 }
 
+const std::string UPGRADE_FLAG_PATH = "/opt/etc/.ode_upgrade_started";
+
 std::mutex opGuard;
 
 // not thread-safe because of static member
@@ -248,6 +250,22 @@ void removeMasterKey(const std::string &device)
        }
 }
 
+void createUpgradeFlag()
+{
+       runtime::File file(UPGRADE_FLAG_PATH);
+       file.create(S_IRUSR | S_IWUSR); // 0600
+}
+
+bool removeUpgradeFlag()
+{
+       runtime::File file(UPGRADE_FLAG_PATH);
+       bool exists = file.exists();
+       if (exists)
+               file.remove();
+
+       return exists;
+}
+
 } // namespace UpgradeSupport
 
 } // namespace ode
index 4a029b8..2854072 100644 (file)
@@ -28,6 +28,8 @@ namespace UpgradeSupport {
 void storeMasterKey(const std::string &device, const BinaryData& key);
 BinaryData loadMasterKey(const std::string &device);
 void removeMasterKey(const std::string &device);
+void createUpgradeFlag();
+bool removeUpgradeFlag();
 
 } // namespace UpgradeSupport