Support to use internal encryption prepare APIs 33/206033/9 accepted/tizen/unified/20190610.110239 submit/tizen/20190607.051013 submit/tizen/20190610.063630
authors414.kim <s414.kim@samsung.com>
Mon, 13 May 2019 10:19:57 +0000 (19:19 +0900)
committers414.kim <s414.kim@samsung.com>
Fri, 24 May 2019 07:29:03 +0000 (16:29 +0900)
- If the crypto state is prepared, does not stopSystemdUnit and unmountInternalStorage.
- Add 'internal_prepare' option to cli tool

Change-Id: I1e7d92aa93b03a6eb80312feef5d7025d16e7ed6
Signed-off-by: s414.kim <s414.kim@samsung.com>
lib/internal-encryption.h
lib/ode/internal-encryption.h
server/internal-encryption.cpp
server/internal-encryption.h
tools/cli/ode-admin-cli.cpp

index a24ec1b..3266025 100644 (file)
@@ -39,7 +39,7 @@ public:
        int prepareEncryption(unsigned int options);
        int prepareDecryption();
 
-       int encrypt(const std::string& password, unsigned int options);
+       int encrypt(const std::string& password, unsigned int options = 0);
        int decrypt(const std::string& password);
 
        int recovery();
index 5eb7499..d48ebd1 100644 (file)
@@ -161,7 +161,7 @@ ODE_API int ode_internal_encryption_prepare_decryption();
  * @pre         The password must match with what is set by
  *              ode_internal_encryption_init_password().
  * @pre         The device must be prepared to encrypt by
- *              ode_internal_encryption_prepare_encryption()
+ *              ode_internal_encryption_prepare_encryption() since tizen 5.5
  * @see         ode_internal_encryption_mount()
  * @see         ode_internal_encryption_decrypt()
  * @see         ode_internal_encryption_get_supported_options()
@@ -185,7 +185,7 @@ ODE_API int ode_internal_encryption_encrypt(const char* password, unsigned int o
  * @pre         The password must match with what is set by
  *              ode_internal_encryption_init_password().
  * @pre         The device must be prepared to decrypt by
- *              ode_internal_encryption_prepare_decryption()
+ *              ode_internal_encryption_prepare_decryption() since tizen 5.5
  * @see         ode_internal_encryption_encrypt()
  */
 ODE_API int ode_internal_encryption_decrypt(const char* password);
index 0f29d6a..ee1c95d 100644 (file)
@@ -634,7 +634,8 @@ int InternalEncryptionServer::prepareDecryption()
 
 int InternalEncryptionServer::encrypt(const std::string& password, unsigned int options)
 {
-       if (getState() != State::Unencrypted) {
+       if (getState() != State::Unencrypted
+                       && getState() != State::PreparedEncryption) {
                ERROR(SINK, "Cannot encrypt, partition's state incorrect.");
                return error::NoSuchDevice;
        }
@@ -653,23 +654,26 @@ int InternalEncryptionServer::encrypt(const std::string& password, unsigned int
                        ::sleep(1);
 
                        runtime::File file("/opt/etc/.odeprogress");
-                       file.create(MODE_0640);
-
-                       std::string source = engine->getSource();
-                       auto mntPaths = findMountPointsByDevice(source);
-
-                       if (!mntPaths.empty()) {
-                               INFO(SINK, "Closing all processes using internal storage.");
-                               stopSystemdUnits();
-
-                               INFO(SINK, "Unmounting internal storage.");
-                               unmountInternalStorage(source);
+                       if (getState() == State::Unencrypted) {
+                               /* For backward compatibility */
+                               file.create(MODE_0640);
+                               std::string source = engine->getSource();
+                               auto mntPaths = findMountPointsByDevice(source);
+
+                               if (!mntPaths.empty()) {
+                                       INFO(SINK, "Closing all processes using internal storage.");
+                                       stopSystemdUnits();
+
+                                       INFO(SINK, "Unmounting internal storage.");
+                                       unmountInternalStorage(source);
+                               }
+                               setOptions(options & getSupportedOptions());
                        }
 
                        INFO(SINK, "Encryption started.");
                        ::vconf_set_str(VCONFKEY_ODE_CRYPTO_STATE, "error_partially_encrypted");
                        try {
-                               engine->encrypt(masterKey, options);
+                               engine->encrypt(masterKey, getOptions());
                        } catch (runtime::Exception &e) {
                                ERROR(SINK, e.what());
                                if (!engine->isStarted()) {
@@ -679,7 +683,6 @@ int InternalEncryptionServer::encrypt(const std::string& password, unsigned int
                                ::sync();
                                ::reboot(RB_AUTOBOOT);
                        }
-                       setOptions(options & getSupportedOptions());
 
                        INFO(SINK, "Encryption completed.");
                        ::vconf_set_str(VCONFKEY_ODE_CRYPTO_STATE, "encrypted");
@@ -703,7 +706,8 @@ int InternalEncryptionServer::encrypt(const std::string& password, unsigned int
 
 int InternalEncryptionServer::decrypt(const std::string& password)
 {
-       if (getState() != State::Encrypted) {
+       if (getState() != State::Encrypted
+                       && getState() != State::PreparedDecryption) {
                ERROR(SINK, "Cannot decrypt, partition's state incorrect.");
                return error::NoSuchDevice;
        }
@@ -731,15 +735,18 @@ int InternalEncryptionServer::decrypt(const std::string& password)
                        ::sleep(1);
 
                        runtime::File file("/opt/etc/.odeprogress");
-                       file.create(MODE_0640);
+                       if (getState() == State::Encrypted) {
+                               /* For backward compatibility */
+                               file.create(MODE_0640);
 
-                       if (engine->isMounted()) {
-                               INFO(SINK, "Closing all processes using internal storage.");
-                               stopSystemdUnits();
+                               if (engine->isMounted()) {
+                                       INFO(SINK, "Closing all processes using internal storage.");
+                                       stopSystemdUnits();
 
-                               INFO(SINK, "Umounting internal storage.");
-                               unmountInternalStorage("/dev/mapper/userdata");
-                               engine->umount();
+                                       INFO(SINK, "Unmounting internal storage.");
+                                       unmountInternalStorage("/dev/mapper/userdata");
+                                       engine->umount();
+                               }
                        }
 
                        INFO(SINK, "Decryption started.");
@@ -781,6 +788,16 @@ int InternalEncryptionServer::recovery()
 
        if (state == State::Unencrypted)
                return error::NoSuchDevice;
+       if (state == State::PreparedEncryption) {
+               ::vconf_set_str(VCONFKEY_ODE_CRYPTO_STATE, "unencrypted");
+               ::sync();
+               return error::None;
+       }
+       if (state == State::PreparedDecryption) {
+               ::vconf_set_str(VCONFKEY_ODE_CRYPTO_STATE, "encrypted");
+               ::sync();
+               return error::None;
+       }
 
        runtime::File file("/opt/.factoryreset");
        file.create(MODE_0640);
index 2bf5990..6507050 100644 (file)
@@ -43,7 +43,7 @@ public:
        int prepareEncryption(unsigned int options);
        int prepareDecryption();
 
-       int encrypt(const std::string& password, unsigned int options);
+       int encrypt(const std::string& password, unsigned int options = 0);
        int decrypt(const std::string& password);
 
        int recovery();
index 377a59e..87e4a8f 100644 (file)
@@ -46,27 +46,27 @@ static inline int usage(const std::string name)
        std::cout << "Usage: " << name << " [Option]" << std::endl
                          << std::endl
                          << "Options :" << std::endl
-                         << "  -m, --mount=internal|external      mount" << std::endl
-                         << "  -u, --umount=internal|external     umount" << std::endl
-                         << "  -e, --encrypt=internal|external    encrypt" << std::endl
-                         << "  -d, --decrypt=internal|external    decrypt" << std::endl
-                         << "  -l  --luks=format|open|close|wait  perform LUKS operation using asynchronous" << std::endl
-                         << "                                     API or wait for completion. May also" << std::endl
-                         << "                                     require -D and/or -M option." << std::endl
-                         << "  -L  --luks_sync=format|open|close  perform LUKS operation using synchronous" << std::endl
-                         << "                                     API. May also require -D and/or -M option." << std::endl
-                         << "  -D  --device=<device>              device path" << std::endl
-                         << "  -M  --mapping=<mapping>            mapping name required for LUKS open and" << std::endl
-                         << "                                     LUKS close operations" << std::endl
-                         << "  -k, --keys=store|remove            Store/remove the master key of given device" << std::endl
-                         << "                                     for the purpose of system upgrade. Requires" << std::endl
-                         << "                                     -D option" << std::endl
-                         << "  -p, --changepw=internal|external   change password" << std::endl
-                         << "  -s, --state=internal|external      get state" << std::endl
-                         << "  -w, --waitmnt=internal|external    wait for mount"<< std::endl
-                         << "  -c, --clean=DIRECTORY              secure-clean" << std::endl
-                         << "  -r, --recovery=internal|external   recovery" << std::endl
-                         << "  -h, --help                         show this" << std::endl
+                         << "  -m, --mount=internal|external                       mount" << std::endl
+                         << "  -u, --umount=internal|external                      umount" << std::endl
+                         << "  -e, --encrypt=internal_prepare|internal|external    encrypt" << std::endl
+                         << "  -d, --decrypt=internal_prepare|internal|external    decrypt" << std::endl
+                         << "  -l  --luks=format|open|close|wait                   perform LUKS operation using asynchronous" << std::endl
+                         << "                                                      API or wait for completion. May also" << std::endl
+                         << "                                                      require -D and/or -M option." << std::endl
+                         << "  -L  --luks_sync=format|open|close                   perform LUKS operation using synchronous" << std::endl
+                         << "                                                      API. May also require -D and/or -M option." << std::endl
+                         << "  -D  --device=<device>                               device path" << std::endl
+                         << "  -M  --mapping=<mapping>                             mapping name required for LUKS open and" << std::endl
+                         << "                                                      LUKS close operations" << std::endl
+                         << "  -k, --keys=store|remove                             Store/remove the master key of given device" << std::endl
+                         << "                                                      for the purpose of system upgrade. Requires" << std::endl
+                         << "                                                      -D option" << std::endl
+                         << "  -p, --changepw=internal|external                    change password" << std::endl
+                         << "  -s, --state=internal|external                       get state" << std::endl
+                         << "  -w, --waitmnt=internal|external                     wait for mount"<< std::endl
+                         << "  -c, --clean=DIRECTORY                               secure-clean" << std::endl
+                         << "  -r, --recovery=internal|external                    recovery" << std::endl
+                         << "  -h, --help                                          show this" << std::endl
                          << std::endl;
 
        return -1;
@@ -169,7 +169,19 @@ static inline int encrypt_storage(const std::string name)
 {
        int ret;
 
-       if (name == "internal") {
+       if (name == "internal_prepare") {
+               unsigned int options = 0;
+               ode_internal_encryption_get_supported_options(&options);
+               char answer;
+               if (options & ODE_OPTION_INTERNAL_INCLUDE_UNUSED_REGION) {
+                       std::cout << "Encrypt All (include unused region)? (y/n) ";
+                       std::cin >> answer;
+                       if (answer != 'Y' && answer != 'y') {
+                               options &= ~ODE_OPTION_INTERNAL_INCLUDE_UNUSED_REGION;
+                       }
+               }
+               ret = ode_internal_encryption_prepare_encryption(options);
+       } else if (name == "internal") {
                bool result = false;
                ode_internal_encryption_is_password_initialized(&result);
 
@@ -189,15 +201,19 @@ static inline int encrypt_storage(const std::string name)
                        return -1;
                }
 
+               int state;
                unsigned int options = 0;
-               ode_internal_encryption_get_supported_options(&options);
-
-               char answer;
-               if (options & ODE_OPTION_INTERNAL_INCLUDE_UNUSED_REGION) {
-                       std::cout << "Encrypt All (include unused region)? (y/n) ";
-                       std::cin >> answer;
-                       if (answer != 'Y' && answer != 'y') {
-                               options &= ~ODE_OPTION_INTERNAL_INCLUDE_UNUSED_REGION;
+               ode_internal_encryption_get_state(&state);
+               if (state == ODE_STATE_UNENCRYPTED) {
+                       /* For backward compatibility */
+                       ode_internal_encryption_get_supported_options(&options);
+                       char answer;
+                       if (options & ODE_OPTION_INTERNAL_INCLUDE_UNUSED_REGION) {
+                               std::cout << "Encrypt All (include unused region)? (y/n) ";
+                               std::cin >> answer;
+                               if (answer != 'Y' && answer != 'y') {
+                                       options &= ~ODE_OPTION_INTERNAL_INCLUDE_UNUSED_REGION;
+                               }
                        }
                }
                ret = ode_internal_encryption_encrypt(password.c_str(), options);
@@ -256,7 +272,9 @@ static inline int decrypt_storage(const std::string name)
 {
        int ret;
 
-       if (name == "internal") {
+       if (name == "internal_prepare") {
+               ret = ode_internal_encryption_prepare_decryption();
+       } else if (name == "internal") {
                std::string password = getPassword();
                ret = ode_internal_encryption_decrypt(password.c_str());
                if (ret == 0) {
@@ -552,6 +570,12 @@ static inline int get_state(const std::string name)
        case ODE_STATE_CORRUPTED:
                std::cout << "Corrupted";
                break;
+       case ODE_STATE_PREPARED_ENCRYPTION:
+               std::cout << "Prepared for encryption";
+               break;
+       case ODE_STATE_PREPARED_DECRYPTION:
+               std::cout << "Prepared for decryption";
+               break;
        default:
                std::cout << "Invalid";
        }